Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * Atheros CARL9170 driver
  3 *
  4 * Basic HW register/memory/command access functions
  5 *
  6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
  7 *
  8 * This program is free software; you can redistribute it and/or modify
  9 * it under the terms of the GNU General Public License as published by
 10 * the Free Software Foundation; either version 2 of the License, or
 11 * (at your option) any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; see the file COPYING.  If not, see
 20 * http://www.gnu.org/licenses/.
 21 *
 22 * This file incorporates work covered by the following copyright and
 23 * permission notice:
 24 *    Copyright (c) 2007-2008 Atheros Communications, Inc.
 25 *
 26 *    Permission to use, copy, modify, and/or distribute this software for any
 27 *    purpose with or without fee is hereby granted, provided that the above
 28 *    copyright notice and this permission notice appear in all copies.
 29 *
 30 *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 31 *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 32 *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 33 *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 34 *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 35 *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 36 *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 37 */
 38
 
 39#include "carl9170.h"
 40#include "cmd.h"
 41
 42int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
 43{
 44	const __le32 buf[2] = {
 45		cpu_to_le32(reg),
 46		cpu_to_le32(val),
 47	};
 48	int err;
 49
 50	err = carl9170_exec_cmd(ar, CARL9170_CMD_WREG, sizeof(buf),
 51				(u8 *) buf, 0, NULL);
 52	if (err) {
 53		if (net_ratelimit()) {
 54			wiphy_err(ar->hw->wiphy, "writing reg %#x "
 55				"(val %#x) failed (%d)\n", reg, val, err);
 56		}
 57	}
 58	return err;
 59}
 60
 61int carl9170_read_mreg(struct ar9170 *ar, const int nregs,
 62		       const u32 *regs, u32 *out)
 63{
 64	int i, err;
 65	__le32 *offs, *res;
 66
 67	/* abuse "out" for the register offsets, must be same length */
 68	offs = (__le32 *)out;
 69	for (i = 0; i < nregs; i++)
 70		offs[i] = cpu_to_le32(regs[i]);
 71
 72	/* also use the same buffer for the input */
 73	res = (__le32 *)out;
 74
 75	err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG,
 76				4 * nregs, (u8 *)offs,
 77				4 * nregs, (u8 *)res);
 78	if (err) {
 79		if (net_ratelimit()) {
 80			wiphy_err(ar->hw->wiphy, "reading regs failed (%d)\n",
 81				  err);
 82		}
 83		return err;
 84	}
 85
 86	/* convert result to cpu endian */
 87	for (i = 0; i < nregs; i++)
 88		out[i] = le32_to_cpu(res[i]);
 89
 90	return 0;
 91}
 92
 93int carl9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
 94{
 95	return carl9170_read_mreg(ar, 1, &reg, val);
 96}
 97
 98int carl9170_echo_test(struct ar9170 *ar, const u32 v)
 99{
100	u32 echores;
101	int err;
102
103	err = carl9170_exec_cmd(ar, CARL9170_CMD_ECHO,
104				4, (u8 *)&v,
105				4, (u8 *)&echores);
106	if (err)
107		return err;
108
109	if (v != echores) {
110		wiphy_info(ar->hw->wiphy, "wrong echo %x != %x", v, echores);
111		return -EINVAL;
112	}
113
114	return 0;
115}
116
117struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
118	const enum carl9170_cmd_oids cmd, const unsigned int len)
119{
120	struct carl9170_cmd *tmp;
121
122	tmp = kzalloc(sizeof(struct carl9170_cmd_head) + len, GFP_ATOMIC);
123	if (tmp) {
124		tmp->hdr.cmd = cmd;
125		tmp->hdr.len = len;
126	}
127
128	return tmp;
129}
130
131int carl9170_reboot(struct ar9170 *ar)
132{
133	struct carl9170_cmd *cmd;
134	int err;
135
136	cmd = carl9170_cmd_buf(ar, CARL9170_CMD_REBOOT_ASYNC, 0);
137	if (!cmd)
138		return -ENOMEM;
139
140	err = __carl9170_exec_cmd(ar, (struct carl9170_cmd *)cmd, true);
141	return err;
142}
143
144int carl9170_mac_reset(struct ar9170 *ar)
145{
146	return carl9170_exec_cmd(ar, CARL9170_CMD_SWRST,
147				 0, NULL, 0, NULL);
148}
149
150int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id,
151		       const u32 mode, const u32 addr, const u32 len)
152{
153	struct carl9170_cmd *cmd;
154
155	cmd = carl9170_cmd_buf(ar, CARL9170_CMD_BCN_CTRL_ASYNC,
156			       sizeof(struct carl9170_bcn_ctrl_cmd));
157	if (!cmd)
158		return -ENOMEM;
159
160	cmd->bcn_ctrl.vif_id = cpu_to_le32(vif_id);
161	cmd->bcn_ctrl.mode = cpu_to_le32(mode);
162	cmd->bcn_ctrl.bcn_addr = cpu_to_le32(addr);
163	cmd->bcn_ctrl.bcn_len = cpu_to_le32(len);
164
165	return __carl9170_exec_cmd(ar, cmd, true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166}
167
168int carl9170_powersave(struct ar9170 *ar, const bool ps)
169{
170	struct carl9170_cmd *cmd;
171	u32 state;
172
173	cmd = carl9170_cmd_buf(ar, CARL9170_CMD_PSM_ASYNC,
174			       sizeof(struct carl9170_psm));
175	if (!cmd)
176		return -ENOMEM;
177
178	if (ps) {
179		/* Sleep until next TBTT */
180		state = CARL9170_PSM_SLEEP | 1;
181	} else {
182		/* wake up immediately */
183		state = 1;
184	}
185
186	cmd->psm.state = cpu_to_le32(state);
187	return __carl9170_exec_cmd(ar, cmd, true);
188}
v6.13.7
  1/*
  2 * Atheros CARL9170 driver
  3 *
  4 * Basic HW register/memory/command access functions
  5 *
  6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
  7 *
  8 * This program is free software; you can redistribute it and/or modify
  9 * it under the terms of the GNU General Public License as published by
 10 * the Free Software Foundation; either version 2 of the License, or
 11 * (at your option) any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; see the file COPYING.  If not, see
 20 * http://www.gnu.org/licenses/.
 21 *
 22 * This file incorporates work covered by the following copyright and
 23 * permission notice:
 24 *    Copyright (c) 2007-2008 Atheros Communications, Inc.
 25 *
 26 *    Permission to use, copy, modify, and/or distribute this software for any
 27 *    purpose with or without fee is hereby granted, provided that the above
 28 *    copyright notice and this permission notice appear in all copies.
 29 *
 30 *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 31 *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 32 *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 33 *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 34 *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 35 *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 36 *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 37 */
 38
 39#include <asm/div64.h>
 40#include "carl9170.h"
 41#include "cmd.h"
 42
 43int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
 44{
 45	const __le32 buf[2] = {
 46		cpu_to_le32(reg),
 47		cpu_to_le32(val),
 48	};
 49	int err;
 50
 51	err = carl9170_exec_cmd(ar, CARL9170_CMD_WREG, sizeof(buf),
 52				(u8 *) buf, 0, NULL);
 53	if (err) {
 54		if (net_ratelimit()) {
 55			wiphy_err(ar->hw->wiphy, "writing reg %#x "
 56				"(val %#x) failed (%d)\n", reg, val, err);
 57		}
 58	}
 59	return err;
 60}
 61
 62int carl9170_read_mreg(struct ar9170 *ar, const int nregs,
 63		       const u32 *regs, u32 *out)
 64{
 65	int i, err;
 66	__le32 *offs, *res;
 67
 68	/* abuse "out" for the register offsets, must be same length */
 69	offs = (__le32 *)out;
 70	for (i = 0; i < nregs; i++)
 71		offs[i] = cpu_to_le32(regs[i]);
 72
 73	/* also use the same buffer for the input */
 74	res = (__le32 *)out;
 75
 76	err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG,
 77				4 * nregs, (u8 *)offs,
 78				4 * nregs, (u8 *)res);
 79	if (err) {
 80		if (net_ratelimit()) {
 81			wiphy_err(ar->hw->wiphy, "reading regs failed (%d)\n",
 82				  err);
 83		}
 84		return err;
 85	}
 86
 87	/* convert result to cpu endian */
 88	for (i = 0; i < nregs; i++)
 89		out[i] = le32_to_cpu(res[i]);
 90
 91	return 0;
 92}
 93
 94int carl9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
 95{
 96	return carl9170_read_mreg(ar, 1, &reg, val);
 97}
 98
 99int carl9170_echo_test(struct ar9170 *ar, const u32 v)
100{
101	u32 echores;
102	int err;
103
104	err = carl9170_exec_cmd(ar, CARL9170_CMD_ECHO,
105				4, (u8 *)&v,
106				4, (u8 *)&echores);
107	if (err)
108		return err;
109
110	if (v != echores) {
111		wiphy_info(ar->hw->wiphy, "wrong echo %x != %x", v, echores);
112		return -EINVAL;
113	}
114
115	return 0;
116}
117
118struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
119	const enum carl9170_cmd_oids cmd, const unsigned int len)
120{
121	struct carl9170_cmd *tmp;
122
123	tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
124	if (tmp) {
125		tmp->hdr.cmd = cmd;
126		tmp->hdr.len = len;
127	}
128
129	return tmp;
130}
131
132int carl9170_reboot(struct ar9170 *ar)
133{
134	struct carl9170_cmd *cmd;
135	int err;
136
137	cmd = carl9170_cmd_buf(ar, CARL9170_CMD_REBOOT_ASYNC, 0);
138	if (!cmd)
139		return -ENOMEM;
140
141	err = __carl9170_exec_cmd(ar, cmd, true);
142	return err;
143}
144
145int carl9170_mac_reset(struct ar9170 *ar)
146{
147	return carl9170_exec_cmd(ar, CARL9170_CMD_SWRST,
148				 0, NULL, 0, NULL);
149}
150
151int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id,
152		       const u32 mode, const u32 addr, const u32 len)
153{
154	struct carl9170_cmd *cmd;
155
156	cmd = carl9170_cmd_buf(ar, CARL9170_CMD_BCN_CTRL_ASYNC,
157			       sizeof(struct carl9170_bcn_ctrl_cmd));
158	if (!cmd)
159		return -ENOMEM;
160
161	cmd->bcn_ctrl.vif_id = cpu_to_le32(vif_id);
162	cmd->bcn_ctrl.mode = cpu_to_le32(mode);
163	cmd->bcn_ctrl.bcn_addr = cpu_to_le32(addr);
164	cmd->bcn_ctrl.bcn_len = cpu_to_le32(len);
165
166	return __carl9170_exec_cmd(ar, cmd, true);
167}
168
169int carl9170_collect_tally(struct ar9170 *ar)
170{
171	struct carl9170_tally_rsp tally;
172	struct survey_info *info;
173	unsigned int tick;
174	int err;
175
176	err = carl9170_exec_cmd(ar, CARL9170_CMD_TALLY, 0, NULL,
177				sizeof(tally), (u8 *)&tally);
178	if (err)
179		return err;
180
181	tick = le32_to_cpu(tally.tick);
182	if (tick) {
183		ar->tally.active += le32_to_cpu(tally.active) / tick;
184		ar->tally.cca += le32_to_cpu(tally.cca) / tick;
185		ar->tally.tx_time += le32_to_cpu(tally.tx_time) / tick;
186		ar->tally.rx_total += le32_to_cpu(tally.rx_total);
187		ar->tally.rx_overrun += le32_to_cpu(tally.rx_overrun);
188
189		if (ar->channel) {
190			info = &ar->survey[ar->channel->hw_value];
191			info->time = ar->tally.active;
192			info->time_busy = ar->tally.cca;
193			info->time_tx = ar->tally.tx_time;
194			do_div(info->time, 1000);
195			do_div(info->time_busy, 1000);
196			do_div(info->time_tx, 1000);
197		}
198	}
199	return 0;
200}
201
202int carl9170_powersave(struct ar9170 *ar, const bool ps)
203{
204	struct carl9170_cmd *cmd;
205	u32 state;
206
207	cmd = carl9170_cmd_buf(ar, CARL9170_CMD_PSM_ASYNC,
208			       sizeof(struct carl9170_psm));
209	if (!cmd)
210		return -ENOMEM;
211
212	if (ps) {
213		/* Sleep until next TBTT */
214		state = CARL9170_PSM_SLEEP | 1;
215	} else {
216		/* wake up immediately */
217		state = 1;
218	}
219
220	cmd->psm.state = cpu_to_le32(state);
221	return __carl9170_exec_cmd(ar, cmd, true);
222}