blob: b3b9baa551bc4b94aa537a4afb6f4750ff0f1f13 [file] [log] [blame]
Joe Perchese9010e22008-03-07 14:21:16 -08001/*
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007 Matthew W. S. Bell <mentor@madwifi.org>
5 * Copyright (c) 2007 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
6 * Copyright (c) 2007 Pavel Roskin <proski@gnu.org>
7 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *
21 */
22
23/*
24 * HW related functions for Atheros Wireless LAN devices.
25 */
26
27#include <linux/pci.h>
28#include <linux/delay.h>
29
30#include "reg.h"
31#include "base.h"
32#include "debug.h"
33
Pavel Macheke292c732008-06-25 12:25:53 +020034/* Rate tables */
Jiri Slabyfa1c1142007-08-12 17:33:16 +020035static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A;
36static const struct ath5k_rate_table ath5k_rt_11b = AR5K_RATES_11B;
37static const struct ath5k_rate_table ath5k_rt_11g = AR5K_RATES_11G;
38static const struct ath5k_rate_table ath5k_rt_turbo = AR5K_RATES_TURBO;
39static const struct ath5k_rate_table ath5k_rt_xr = AR5K_RATES_XR;
40
Pavel Macheke292c732008-06-25 12:25:53 +020041/* Prototypes */
Jiri Slabyfa1c1142007-08-12 17:33:16 +020042static int ath5k_hw_nic_reset(struct ath5k_hw *, u32);
43static int ath5k_hw_nic_wakeup(struct ath5k_hw *, int, bool);
44static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
45 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
46 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
47 unsigned int, unsigned int);
Jiri Slabyb9887632008-02-15 21:58:52 +010048static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
Jiri Slabyfa1c1142007-08-12 17:33:16 +020049 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
50 unsigned int);
Bruno Randolfb47f4072008-03-05 18:35:45 +090051static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *,
52 struct ath5k_tx_status *);
Jiri Slabyfa1c1142007-08-12 17:33:16 +020053static int ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
54 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
55 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
56 unsigned int, unsigned int);
Bruno Randolfb47f4072008-03-05 18:35:45 +090057static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *, struct ath5k_desc *,
58 struct ath5k_tx_status *);
59static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *, struct ath5k_desc *,
60 struct ath5k_rx_status *);
61static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *, struct ath5k_desc *,
62 struct ath5k_rx_status *);
Jiri Slabyfa1c1142007-08-12 17:33:16 +020063static int ath5k_hw_get_capabilities(struct ath5k_hw *);
64
65static int ath5k_eeprom_init(struct ath5k_hw *);
66static int ath5k_eeprom_read_mac(struct ath5k_hw *, u8 *);
67
68static int ath5k_hw_enable_pspoll(struct ath5k_hw *, u8 *, u16);
69static int ath5k_hw_disable_pspoll(struct ath5k_hw *);
70
71/*
72 * Enable to overwrite the country code (use "00" for debug)
73 */
74#if 0
75#define COUNTRYCODE "00"
76#endif
77
78/*******************\
79 General Functions
80\*******************/
81
82/*
83 * Functions used internaly
84 */
85
86static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
87{
Joe Perchese9010e22008-03-07 14:21:16 -080088 return turbo ? (usec * 80) : (usec * 40);
Jiri Slabyfa1c1142007-08-12 17:33:16 +020089}
90
91static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
92{
Joe Perchese9010e22008-03-07 14:21:16 -080093 return turbo ? (clock / 80) : (clock / 40);
Jiri Slabyfa1c1142007-08-12 17:33:16 +020094}
95
96/*
97 * Check if a register write has been completed
98 */
99int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
100 bool is_set)
101{
102 int i;
103 u32 data;
104
105 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
106 data = ath5k_hw_reg_read(ah, reg);
Joe Perchese9010e22008-03-07 14:21:16 -0800107 if (is_set && (data & flag))
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200108 break;
109 else if ((data & flag) == val)
110 break;
111 udelay(15);
112 }
113
114 return (i <= 0) ? -EAGAIN : 0;
115}
116
117
118/***************************************\
119 Attach/Detach Functions
120\***************************************/
121
122/*
Nick Kossifidis194828a2008-04-16 18:49:02 +0300123 * Power On Self Test helper function
124 */
125static int ath5k_hw_post(struct ath5k_hw *ah)
126{
127
128 int i, c;
129 u16 cur_reg;
130 u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)};
131 u32 var_pattern;
132 u32 static_pattern[4] = {
133 0x55555555, 0xaaaaaaaa,
134 0x66666666, 0x99999999
135 };
136 u32 init_val;
137 u32 cur_val;
138
139 for (c = 0; c < 2; c++) {
140
141 cur_reg = regs[c];
Nick Kossifidisba377462008-07-20 06:32:32 +0300142
143 /* Save previous value */
Nick Kossifidis194828a2008-04-16 18:49:02 +0300144 init_val = ath5k_hw_reg_read(ah, cur_reg);
145
146 for (i = 0; i < 256; i++) {
147 var_pattern = i << 16 | i;
148 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
149 cur_val = ath5k_hw_reg_read(ah, cur_reg);
150
151 if (cur_val != var_pattern) {
152 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
153 return -EAGAIN;
154 }
155
156 /* Found on ndiswrapper dumps */
157 var_pattern = 0x0039080f;
158 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
159 }
160
161 for (i = 0; i < 4; i++) {
162 var_pattern = static_pattern[i];
163 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
164 cur_val = ath5k_hw_reg_read(ah, cur_reg);
165
166 if (cur_val != var_pattern) {
167 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
168 return -EAGAIN;
169 }
170
171 /* Found on ndiswrapper dumps */
172 var_pattern = 0x003b080f;
173 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
174 }
Nick Kossifidisba377462008-07-20 06:32:32 +0300175
176 /* Restore previous value */
177 ath5k_hw_reg_write(ah, init_val, cur_reg);
178
Nick Kossifidis194828a2008-04-16 18:49:02 +0300179 }
180
181 return 0;
182
183}
184
185/*
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200186 * Check if the device is supported and initialize the needed structs
187 */
188struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
189{
190 struct ath5k_hw *ah;
Nick Kossifidis194828a2008-04-16 18:49:02 +0300191 struct pci_dev *pdev = sc->pdev;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200192 u8 mac[ETH_ALEN];
193 int ret;
194 u32 srev;
195
196 /*If we passed the test malloc a ath5k_hw struct*/
197 ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
198 if (ah == NULL) {
199 ret = -ENOMEM;
200 ATH5K_ERR(sc, "out of memory\n");
201 goto err;
202 }
203
204 ah->ah_sc = sc;
205 ah->ah_iobase = sc->iobase;
206
207 /*
208 * HW information
209 */
210
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200211 ah->ah_op_mode = IEEE80211_IF_TYPE_STA;
212 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
213 ah->ah_turbo = false;
214 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
215 ah->ah_imr = 0;
216 ah->ah_atim_window = 0;
217 ah->ah_aifs = AR5K_TUNE_AIFS;
218 ah->ah_cw_min = AR5K_TUNE_CWMIN;
219 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
220 ah->ah_software_retry = false;
221 ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
222
223 /*
224 * Set the mac revision based on the pci id
225 */
226 ah->ah_version = mac_version;
227
228 /*Fill the ath5k_hw struct with the needed functions*/
229 if (ah->ah_version == AR5K_AR5212)
230 ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
231 else if (ah->ah_version == AR5K_AR5211)
232 ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
233
234 if (ah->ah_version == AR5K_AR5212) {
235 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
236 ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
237 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
238 } else {
239 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
240 ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
241 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
242 }
243
244 if (ah->ah_version == AR5K_AR5212)
Bruno Randolf19fd6e52008-03-05 18:35:23 +0900245 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200246 else if (ah->ah_version <= AR5K_AR5211)
Bruno Randolf19fd6e52008-03-05 18:35:23 +0900247 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200248
249 /* Bring device out of sleep and reset it's units */
250 ret = ath5k_hw_nic_wakeup(ah, AR5K_INIT_MODE, true);
251 if (ret)
252 goto err_free;
253
254 /* Get MAC, PHY and RADIO revisions */
255 srev = ath5k_hw_reg_read(ah, AR5K_SREV);
256 ah->ah_mac_srev = srev;
257 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
258 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
259 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
260 0xffffffff;
261 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
262 CHANNEL_5GHZ);
263
264 if (ah->ah_version == AR5K_AR5210)
265 ah->ah_radio_2ghz_revision = 0;
266 else
267 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
268 CHANNEL_2GHZ);
269
270 /* Return on unsuported chips (unsupported eeprom etc) */
Nick Kossifidis194828a2008-04-16 18:49:02 +0300271 if ((srev >= AR5K_SREV_VER_AR5416) &&
272 (srev < AR5K_SREV_VER_AR2425)) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200273 ATH5K_ERR(sc, "Device not yet supported.\n");
274 ret = -ENODEV;
275 goto err_free;
Nick Kossifidis194828a2008-04-16 18:49:02 +0300276 } else if (srev == AR5K_SREV_VER_AR2425) {
277 ATH5K_WARN(sc, "Support for RF2425 is under development.\n");
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200278 }
279
280 /* Identify single chip solutions */
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300281 if (((srev <= AR5K_SREV_VER_AR5414) &&
282 (srev >= AR5K_SREV_VER_AR2413)) ||
283 (srev == AR5K_SREV_VER_AR2425)) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200284 ah->ah_single_chip = true;
285 } else {
286 ah->ah_single_chip = false;
287 }
288
289 /* Single chip radio */
290 if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision)
291 ah->ah_radio_2ghz_revision = 0;
292
293 /* Identify the radio chip*/
294 if (ah->ah_version == AR5K_AR5210) {
295 ah->ah_radio = AR5K_RF5110;
296 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
297 ah->ah_radio = AR5K_RF5111;
Nick Kossifidis0af22562008-02-28 14:49:05 -0500298 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
299 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
300
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200301 ah->ah_radio = AR5K_RF5112;
Nick Kossifidis0af22562008-02-28 14:49:05 -0500302
303 if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
304 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
305 } else {
306 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
307 }
308
309 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
310 ah->ah_radio = AR5K_RF2413;
311 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300312 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200313 ah->ah_radio = AR5K_RF5413;
Nick Kossifidisd1d8f442008-04-21 21:28:24 +0300314 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
315 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
Nick Kossifidis0af22562008-02-28 14:49:05 -0500316
Nick Kossifidisd1d8f442008-04-21 21:28:24 +0300317 /* AR5424 */
318 if (srev >= AR5K_SREV_VER_AR5424) {
319 ah->ah_radio = AR5K_RF5413;
Nick Kossifidis0af22562008-02-28 14:49:05 -0500320 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424;
Nick Kossifidisd1d8f442008-04-21 21:28:24 +0300321 /* AR2424 */
322 } else {
323 ah->ah_radio = AR5K_RF2413; /* For testing */
Nick Kossifidis0af22562008-02-28 14:49:05 -0500324 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
Nick Kossifidisd1d8f442008-04-21 21:28:24 +0300325 }
326
Nick Kossifidis194828a2008-04-16 18:49:02 +0300327 /*
328 * Register returns 0x4 for radio revision
329 * so ath5k_hw_radio_revision doesn't parse the value
330 * correctly. For now we are based on mac's srev to
331 * identify RF2425 radio.
332 */
333 } else if (srev == AR5K_SREV_VER_AR2425) {
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300334 ah->ah_radio = AR5K_RF2425;
335 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200336 }
337
338 ah->ah_phy = AR5K_PHY(0);
339
340 /*
Nick Kossifidis194828a2008-04-16 18:49:02 +0300341 * Identify AR5212-based PCI-E cards
342 * And write some initial settings.
343 *
344 * (doing a "strings" on ndis driver
345 * -ar5211.sys- reveals the following
346 * pci-e related functions:
347 *
348 * pcieClockReq
349 * pcieRxErrNotify
350 * pcieL1SKPEnable
351 * pcieAspm
352 * pcieDisableAspmOnRfWake
353 * pciePowerSaveEnable
354 *
355 * I guess these point to ClockReq but
356 * i'm not sure.)
357 */
358 if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
359 ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
360 ath5k_hw_reg_write(ah, 0x24924924, 0x4080);
361 ath5k_hw_reg_write(ah, 0x28000039, 0x4080);
362 ath5k_hw_reg_write(ah, 0x53160824, 0x4080);
363 ath5k_hw_reg_write(ah, 0xe5980579, 0x4080);
364 ath5k_hw_reg_write(ah, 0x001defff, 0x4080);
365 ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080);
366 ath5k_hw_reg_write(ah, 0xbe105554, 0x4080);
367 ath5k_hw_reg_write(ah, 0x000e3007, 0x4080);
368 ath5k_hw_reg_write(ah, 0x00000000, 0x4084);
369 }
370
371 /*
372 * POST
373 */
374 ret = ath5k_hw_post(ah);
375 if (ret)
376 goto err_free;
377
378 /*
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200379 * Get card capabilities, values, ...
380 */
381
382 ret = ath5k_eeprom_init(ah);
383 if (ret) {
384 ATH5K_ERR(sc, "unable to init EEPROM\n");
385 goto err_free;
386 }
387
388 /* Get misc capabilities */
389 ret = ath5k_hw_get_capabilities(ah);
390 if (ret) {
391 ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
392 sc->pdev->device);
393 goto err_free;
394 }
395
396 /* Get MAC address */
397 ret = ath5k_eeprom_read_mac(ah, mac);
398 if (ret) {
399 ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
400 sc->pdev->device);
401 goto err_free;
402 }
403
404 ath5k_hw_set_lladdr(ah, mac);
405 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
406 memset(ah->ah_bssid, 0xff, ETH_ALEN);
407 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
408 ath5k_hw_set_opmode(ah);
409
410 ath5k_hw_set_rfgain_opt(ah);
411
412 return ah;
413err_free:
414 kfree(ah);
415err:
416 return ERR_PTR(ret);
417}
418
419/*
420 * Bring up MAC + PHY Chips
421 */
422static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
423{
Nick Kossifidis56c90542008-02-28 16:20:52 -0500424 struct pci_dev *pdev = ah->ah_sc->pdev;
425 u32 turbo, mode, clock, bus_flags;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200426 int ret;
427
428 turbo = 0;
429 mode = 0;
430 clock = 0;
431
432 ATH5K_TRACE(ah->ah_sc);
433
434 /* Wakeup the device */
435 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
436 if (ret) {
437 ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
438 return ret;
439 }
440
441 if (ah->ah_version != AR5K_AR5210) {
442 /*
443 * Get channel mode flags
444 */
445
446 if (ah->ah_radio >= AR5K_RF5112) {
447 mode = AR5K_PHY_MODE_RAD_RF5112;
448 clock = AR5K_PHY_PLL_RF5112;
449 } else {
450 mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/
451 clock = AR5K_PHY_PLL_RF5111; /*Zero*/
452 }
453
454 if (flags & CHANNEL_2GHZ) {
455 mode |= AR5K_PHY_MODE_FREQ_2GHZ;
456 clock |= AR5K_PHY_PLL_44MHZ;
457
458 if (flags & CHANNEL_CCK) {
459 mode |= AR5K_PHY_MODE_MOD_CCK;
460 } else if (flags & CHANNEL_OFDM) {
461 /* XXX Dynamic OFDM/CCK is not supported by the
462 * AR5211 so we set MOD_OFDM for plain g (no
463 * CCK headers) operation. We need to test
464 * this, 5211 might support ofdm-only g after
465 * all, there are also initial register values
466 * in the code for g mode (see initvals.c). */
467 if (ah->ah_version == AR5K_AR5211)
468 mode |= AR5K_PHY_MODE_MOD_OFDM;
469 else
470 mode |= AR5K_PHY_MODE_MOD_DYN;
471 } else {
472 ATH5K_ERR(ah->ah_sc,
473 "invalid radio modulation mode\n");
474 return -EINVAL;
475 }
476 } else if (flags & CHANNEL_5GHZ) {
477 mode |= AR5K_PHY_MODE_FREQ_5GHZ;
478 clock |= AR5K_PHY_PLL_40MHZ;
479
480 if (flags & CHANNEL_OFDM)
481 mode |= AR5K_PHY_MODE_MOD_OFDM;
482 else {
483 ATH5K_ERR(ah->ah_sc,
484 "invalid radio modulation mode\n");
485 return -EINVAL;
486 }
487 } else {
488 ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
489 return -EINVAL;
490 }
491
492 if (flags & CHANNEL_TURBO)
493 turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
494 } else { /* Reset the device */
495
496 /* ...enable Atheros turbo mode if requested */
497 if (flags & CHANNEL_TURBO)
498 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
499 AR5K_PHY_TURBO);
500 }
501
Nick Kossifidis56c90542008-02-28 16:20:52 -0500502 /* reseting PCI on PCI-E cards results card to hang
503 * and always return 0xffff... so we ingore that flag
504 * for PCI-E cards */
505 bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
506
507 /* Reset chipset */
508 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
509 AR5K_RESET_CTL_BASEBAND | bus_flags);
510 if (ret) {
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300511 ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200512 return -EIO;
513 }
514
515 if (ah->ah_version == AR5K_AR5210)
516 udelay(2300);
517
518 /* ...wakeup again!*/
519 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
520 if (ret) {
521 ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
522 return ret;
523 }
524
525 /* ...final warm reset */
526 if (ath5k_hw_nic_reset(ah, 0)) {
527 ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
528 return -EIO;
529 }
530
531 if (ah->ah_version != AR5K_AR5210) {
532 /* ...set the PHY operating mode */
533 ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
534 udelay(300);
535
536 ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
537 ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
538 }
539
540 return 0;
541}
542
543/*
544 * Get the rate table for a specific operation mode
545 */
546const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah,
547 unsigned int mode)
548{
549 ATH5K_TRACE(ah->ah_sc);
550
551 if (!test_bit(mode, ah->ah_capabilities.cap_mode))
552 return NULL;
553
554 /* Get rate tables */
555 switch (mode) {
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500556 case AR5K_MODE_11A:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200557 return &ath5k_rt_11a;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500558 case AR5K_MODE_11A_TURBO:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200559 return &ath5k_rt_turbo;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500560 case AR5K_MODE_11B:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200561 return &ath5k_rt_11b;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500562 case AR5K_MODE_11G:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200563 return &ath5k_rt_11g;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500564 case AR5K_MODE_11G_TURBO:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200565 return &ath5k_rt_xr;
566 }
567
568 return NULL;
569}
570
571/*
572 * Free the ath5k_hw struct
573 */
574void ath5k_hw_detach(struct ath5k_hw *ah)
575{
576 ATH5K_TRACE(ah->ah_sc);
577
Pavel Roskinf50e4a82008-03-12 16:13:31 -0400578 __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
579
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200580 if (ah->ah_rf_banks != NULL)
581 kfree(ah->ah_rf_banks);
582
583 /* assume interrupts are down */
584 kfree(ah);
585}
586
587/****************************\
588 Reset function and helpers
589\****************************/
590
591/**
592 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
593 *
594 * @ah: the &struct ath5k_hw
595 * @channel: the currently set channel upon reset
596 *
597 * Write the OFDM timings for the AR5212 upon reset. This is a helper for
598 * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
599 * depending on the bandwidth of the channel.
600 *
601 */
602static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
603 struct ieee80211_channel *channel)
604{
605 /* Get exponent and mantissa and set it */
606 u32 coef_scaled, coef_exp, coef_man,
607 ds_coef_exp, ds_coef_man, clock;
608
609 if (!(ah->ah_version == AR5K_AR5212) ||
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500610 !(channel->hw_value & CHANNEL_OFDM))
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200611 BUG();
612
613 /* Seems there are two PLLs, one for baseband sampling and one
614 * for tuning. Tuning basebands are 40 MHz or 80MHz when in
615 * turbo. */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500616 clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200617 coef_scaled = ((5 * (clock << 24)) / 2) /
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500618 channel->center_freq;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200619
620 for (coef_exp = 31; coef_exp > 0; coef_exp--)
621 if ((coef_scaled >> coef_exp) & 0x1)
622 break;
623
624 if (!coef_exp)
625 return -EINVAL;
626
627 coef_exp = 14 - (coef_exp - 24);
628 coef_man = coef_scaled +
629 (1 << (24 - coef_exp - 1));
630 ds_coef_man = coef_man >> (24 - coef_exp);
631 ds_coef_exp = coef_exp - 16;
632
633 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
634 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
635 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
636 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
637
638 return 0;
639}
640
641/**
642 * ath5k_hw_write_rate_duration - set rate duration during hw resets
643 *
644 * @ah: the &struct ath5k_hw
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500645 * @mode: one of enum ath5k_driver_mode
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200646 *
647 * Write the rate duration table for the current mode upon hw reset. This
648 * is a helper for ath5k_hw_reset(). It seems all this is doing is setting
649 * an ACK timeout for the hardware for the current mode for each rate. The
650 * rates which are capable of short preamble (802.11b rates 2Mbps, 5.5Mbps,
651 * and 11Mbps) have another register for the short preamble ACK timeout
652 * calculation.
653 *
654 */
655static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500656 unsigned int mode)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200657{
658 struct ath5k_softc *sc = ah->ah_sc;
659 const struct ath5k_rate_table *rt;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500660 struct ieee80211_rate srate = {};
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200661 unsigned int i;
662
663 /* Get rate table for the current operating mode */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500664 rt = ath5k_hw_get_rate_table(ah, mode);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200665
666 /* Write rate duration table */
667 for (i = 0; i < rt->rate_count; i++) {
668 const struct ath5k_rate *rate, *control_rate;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500669
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200670 u32 reg;
671 u16 tx_time;
672
673 rate = &rt->rates[i];
674 control_rate = &rt->rates[rate->control_rate];
675
676 /* Set ACK timeout */
677 reg = AR5K_RATE_DUR(rate->rate_code);
678
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500679 srate.bitrate = control_rate->rate_kbps/100;
680
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200681 /* An ACK frame consists of 10 bytes. If you add the FCS,
682 * which ieee80211_generic_frame_duration() adds,
683 * its 14 bytes. Note we use the control rate and not the
684 * actual rate for this rate. See mac80211 tx.c
685 * ieee80211_duration() for a brief description of
686 * what rate we should choose to TX ACKs. */
Pavel Roskin38c07b42008-02-26 17:59:14 -0500687 tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
688 sc->vif, 10, &srate));
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200689
690 ath5k_hw_reg_write(ah, tx_time, reg);
691
692 if (!HAS_SHPREAMBLE(i))
693 continue;
694
695 /*
696 * We're not distinguishing short preamble here,
697 * This is true, all we'll get is a longer value here
698 * which is not necessarilly bad. We could use
699 * export ieee80211_frame_duration() but that needs to be
700 * fixed first to be properly used by mac802111 drivers:
701 *
702 * - remove erp stuff and let the routine figure ofdm
703 * erp rates
704 * - remove passing argument ieee80211_local as
705 * drivers don't have access to it
706 * - move drivers using ieee80211_generic_frame_duration()
707 * to this
708 */
709 ath5k_hw_reg_write(ah, tx_time,
710 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
711 }
712}
713
714/*
715 * Main reset function
716 */
717int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
718 struct ieee80211_channel *channel, bool change_channel)
719{
720 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
Nick Kossifidis56c90542008-02-28 16:20:52 -0500721 struct pci_dev *pdev = ah->ah_sc->pdev;
722 u32 data, s_seq, s_ant, s_led[3], dma_size;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500723 unsigned int i, mode, freq, ee_mode, ant[2];
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200724 int ret;
725
726 ATH5K_TRACE(ah->ah_sc);
727
728 s_seq = 0;
729 s_ant = 0;
730 ee_mode = 0;
731 freq = 0;
732 mode = 0;
733
734 /*
735 * Save some registers before a reset
736 */
737 /*DCU/Antenna selection not available on 5210*/
738 if (ah->ah_version != AR5K_AR5210) {
Joe Perchese9010e22008-03-07 14:21:16 -0800739 if (change_channel) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200740 /* Seq number for queue 0 -do this for all queues ? */
741 s_seq = ath5k_hw_reg_read(ah,
742 AR5K_QUEUE_DFS_SEQNUM(0));
743 /*Default antenna*/
744 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
745 }
746 }
747
748 /*GPIOs*/
749 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
750 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
751 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
752
Joe Perchese9010e22008-03-07 14:21:16 -0800753 if (change_channel && ah->ah_rf_banks != NULL)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200754 ath5k_hw_get_rf_gain(ah);
755
756
757 /*Wakeup the device*/
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500758 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200759 if (ret)
760 return ret;
761
762 /*
763 * Initialize operating mode
764 */
765 ah->ah_op_mode = op_mode;
766
767 /*
768 * 5111/5112 Settings
769 * 5210 only comes with RF5110
770 */
771 if (ah->ah_version != AR5K_AR5210) {
772 if (ah->ah_radio != AR5K_RF5111 &&
773 ah->ah_radio != AR5K_RF5112 &&
Nick Kossifidis903b4742008-02-28 14:50:50 -0500774 ah->ah_radio != AR5K_RF5413 &&
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300775 ah->ah_radio != AR5K_RF2413 &&
776 ah->ah_radio != AR5K_RF2425) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200777 ATH5K_ERR(ah->ah_sc,
778 "invalid phy radio: %u\n", ah->ah_radio);
779 return -EINVAL;
780 }
781
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500782 switch (channel->hw_value & CHANNEL_MODES) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200783 case CHANNEL_A:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500784 mode = AR5K_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200785 freq = AR5K_INI_RFGAIN_5GHZ;
786 ee_mode = AR5K_EEPROM_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200787 break;
788 case CHANNEL_G:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500789 mode = AR5K_MODE_11G;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200790 freq = AR5K_INI_RFGAIN_2GHZ;
791 ee_mode = AR5K_EEPROM_MODE_11G;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200792 break;
793 case CHANNEL_B:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500794 mode = AR5K_MODE_11B;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200795 freq = AR5K_INI_RFGAIN_2GHZ;
796 ee_mode = AR5K_EEPROM_MODE_11B;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200797 break;
798 case CHANNEL_T:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500799 mode = AR5K_MODE_11A_TURBO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200800 freq = AR5K_INI_RFGAIN_5GHZ;
801 ee_mode = AR5K_EEPROM_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200802 break;
803 /*Is this ok on 5211 too ?*/
804 case CHANNEL_TG:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500805 mode = AR5K_MODE_11G_TURBO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200806 freq = AR5K_INI_RFGAIN_2GHZ;
807 ee_mode = AR5K_EEPROM_MODE_11G;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200808 break;
809 case CHANNEL_XR:
810 if (ah->ah_version == AR5K_AR5211) {
811 ATH5K_ERR(ah->ah_sc,
812 "XR mode not available on 5211");
813 return -EINVAL;
814 }
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500815 mode = AR5K_MODE_XR;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200816 freq = AR5K_INI_RFGAIN_5GHZ;
817 ee_mode = AR5K_EEPROM_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200818 break;
819 default:
820 ATH5K_ERR(ah->ah_sc,
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500821 "invalid channel: %d\n", channel->center_freq);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200822 return -EINVAL;
823 }
824
825 /* PHY access enable */
826 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
827
828 }
829
830 ret = ath5k_hw_write_initvals(ah, mode, change_channel);
831 if (ret)
832 return ret;
833
834 /*
835 * 5211/5212 Specific
836 */
837 if (ah->ah_version != AR5K_AR5210) {
838 /*
839 * Write initial RF gain settings
840 * This should work for both 5111/5112
841 */
842 ret = ath5k_hw_rfgain(ah, freq);
843 if (ret)
844 return ret;
845
846 mdelay(1);
847
848 /*
849 * Write some more initial register settings
850 */
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500851 if (ah->ah_version == AR5K_AR5212) {
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300852 ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200853
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500854 if (channel->hw_value == CHANNEL_G)
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500855 if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
856 ath5k_hw_reg_write(ah, 0x00f80d80,
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300857 0x994c);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500858 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
859 ath5k_hw_reg_write(ah, 0x00380140,
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300860 0x994c);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500861 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
862 ath5k_hw_reg_write(ah, 0x00fc0ec0,
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300863 0x994c);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500864 else /* 2425 */
865 ath5k_hw_reg_write(ah, 0x00fc0fc0,
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300866 0x994c);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200867 else
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300868 ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200869
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200870 ath5k_hw_reg_write(ah, 0x000009b5, 0xa228);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300871 ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200872 ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
873 ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
874 }
875
876 /* Fix for first revision of the RF5112 RF chipset */
877 if (ah->ah_radio >= AR5K_RF5112 &&
878 ah->ah_radio_5ghz_revision <
879 AR5K_SREV_RAD_5112A) {
880 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
881 AR5K_PHY_CCKTXCTL);
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500882 if (channel->hw_value & CHANNEL_5GHZ)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200883 data = 0xffb81020;
884 else
885 data = 0xffb80d20;
886 ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
887 }
888
889 /*
890 * Set TX power (FIXME)
891 */
892 ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER);
893 if (ret)
894 return ret;
895
Luis R. Rodriguez132127e2008-01-04 02:21:05 -0500896 /* Write rate duration table only on AR5212 and if
897 * virtual interface has already been brought up
898 * XXX: rethink this after new mode changes to
899 * mac80211 are integrated */
900 if (ah->ah_version == AR5K_AR5212 &&
901 ah->ah_sc->vif != NULL)
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500902 ath5k_hw_write_rate_duration(ah, mode);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200903
904 /*
905 * Write RF registers
906 * TODO:Does this work on 5211 (5111) ?
907 */
908 ret = ath5k_hw_rfregs(ah, channel, mode);
909 if (ret)
910 return ret;
911
912 /*
913 * Configure additional registers
914 */
915
916 /* Write OFDM timings on 5212*/
917 if (ah->ah_version == AR5K_AR5212 &&
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500918 channel->hw_value & CHANNEL_OFDM) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200919 ret = ath5k_hw_write_ofdm_timings(ah, channel);
920 if (ret)
921 return ret;
922 }
923
924 /*Enable/disable 802.11b mode on 5111
925 (enable 2111 frequency converter + CCK)*/
926 if (ah->ah_radio == AR5K_RF5111) {
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500927 if (mode == AR5K_MODE_11B)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200928 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
929 AR5K_TXCFG_B_MODE);
930 else
931 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
932 AR5K_TXCFG_B_MODE);
933 }
934
935 /*
936 * Set channel and calibrate the PHY
937 */
938 ret = ath5k_hw_channel(ah, channel);
939 if (ret)
940 return ret;
941
942 /* Set antenna mode */
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300943 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200944 ah->ah_antenna[ee_mode][0], 0xfffffc06);
945
946 /*
947 * In case a fixed antenna was set as default
948 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
949 * registers.
950 */
951 if (s_ant != 0){
952 if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
953 ant[0] = ant[1] = AR5K_ANT_FIXED_A;
954 else /* 2 - Aux */
955 ant[0] = ant[1] = AR5K_ANT_FIXED_B;
956 } else {
957 ant[0] = AR5K_ANT_FIXED_A;
958 ant[1] = AR5K_ANT_FIXED_B;
959 }
960
961 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
962 AR5K_PHY_ANT_SWITCH_TABLE_0);
963 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
964 AR5K_PHY_ANT_SWITCH_TABLE_1);
965
966 /* Commit values from EEPROM */
967 if (ah->ah_radio == AR5K_RF5111)
968 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
969 AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
970
971 ath5k_hw_reg_write(ah,
972 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300973 AR5K_PHY_NFTHRES);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200974
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300975 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200976 (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
977 0xffffc07f);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300978 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200979 (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
980 0xfffc0fff);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300981 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200982 (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
983 ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
984 0xffff0000);
985
986 ath5k_hw_reg_write(ah,
987 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
988 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
989 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300990 (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200991
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300992 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200993 ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300994 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200995 (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300996 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200997
998 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
999 AR5K_PHY_IQ_CORR_ENABLE |
1000 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
1001 ee->ee_q_cal[ee_mode]);
1002
1003 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
1004 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
1005 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
1006 ee->ee_margin_tx_rx[ee_mode]);
1007
1008 } else {
1009 mdelay(1);
1010 /* Disable phy and wait */
1011 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
1012 mdelay(1);
1013 }
1014
1015 /*
1016 * Restore saved values
1017 */
1018 /*DCU/Antenna selection not available on 5210*/
1019 if (ah->ah_version != AR5K_AR5210) {
1020 ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
1021 ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
1022 }
1023 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
1024 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
1025 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
1026
1027 /*
1028 * Misc
1029 */
1030 /* XXX: add ah->aid once mac80211 gives this to us */
1031 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
1032
1033 ath5k_hw_set_opmode(ah);
1034 /*PISR/SISR Not available on 5210*/
1035 if (ah->ah_version != AR5K_AR5210) {
1036 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
1037 /* If we later allow tuning for this, store into sc structure */
1038 data = AR5K_TUNE_RSSI_THRES |
1039 AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
1040 ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
1041 }
1042
1043 /*
1044 * Set Rx/Tx DMA Configuration
Nick Kossifidis56c90542008-02-28 16:20:52 -05001045 *
1046 * Set maximum DMA size (512) except for PCI-E cards since
1047 * it causes rx overruns and tx errors (tested on 5424 but since
1048 * rx overruns also occur on 5416/5418 with madwifi we set 128
1049 * for all PCI-E cards to be safe).
1050 *
1051 * In dumps this is 128 for allchips.
1052 *
1053 * XXX: need to check 5210 for this
1054 * TODO: Check out tx triger level, it's always 64 on dumps but I
1055 * guess we can tweak it and see how it goes ;-)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001056 */
Nick Kossifidis56c90542008-02-28 16:20:52 -05001057 dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001058 if (ah->ah_version != AR5K_AR5210) {
Nick Kossifidis56c90542008-02-28 16:20:52 -05001059 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
1060 AR5K_TXCFG_SDMAMR, dma_size);
1061 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
1062 AR5K_RXCFG_SDMAMW, dma_size);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001063 }
1064
1065 /*
1066 * Enable the PHY and wait until completion
1067 */
1068 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
1069
1070 /*
1071 * 5111/5112 Specific
1072 */
1073 if (ah->ah_version != AR5K_AR5210) {
1074 data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
1075 AR5K_PHY_RX_DELAY_M;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001076 data = (channel->hw_value & CHANNEL_CCK) ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001077 ((data << 2) / 22) : (data / 10);
1078
1079 udelay(100 + data);
1080 } else {
1081 mdelay(1);
1082 }
1083
1084 /*
1085 * Enable calibration and wait until completion
1086 */
1087 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1088 AR5K_PHY_AGCCTL_CAL);
1089
1090 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1091 AR5K_PHY_AGCCTL_CAL, 0, false)) {
1092 ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001093 channel->center_freq);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001094 return -EAGAIN;
1095 }
1096
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001097 ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001098 if (ret)
1099 return ret;
1100
1101 ah->ah_calibration = false;
1102
1103 /* A and G modes can use QAM modulation which requires enabling
1104 * I and Q calibration. Don't bother in B mode. */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001105 if (!(mode == AR5K_MODE_11B)) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001106 ah->ah_calibration = true;
1107 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
1108 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
1109 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
1110 AR5K_PHY_IQ_RUN);
1111 }
1112
1113 /*
1114 * Reset queues and start beacon timers at the end of the reset routine
1115 */
1116 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
1117 /*No QCU on 5210*/
1118 if (ah->ah_version != AR5K_AR5210)
1119 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
1120
1121 ret = ath5k_hw_reset_tx_queue(ah, i);
1122 if (ret) {
1123 ATH5K_ERR(ah->ah_sc,
1124 "failed to reset TX queue #%d\n", i);
1125 return ret;
1126 }
1127 }
1128
1129 /* Pre-enable interrupts on 5211/5212*/
1130 if (ah->ah_version != AR5K_AR5210)
1131 ath5k_hw_set_intr(ah, AR5K_INT_RX | AR5K_INT_TX |
1132 AR5K_INT_FATAL);
1133
1134 /*
1135 * Set RF kill flags if supported by the device (read from the EEPROM)
1136 * Disable gpio_intr for now since it results system hang.
1137 * TODO: Handle this in ath5k_intr
1138 */
1139#if 0
1140 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
1141 ath5k_hw_set_gpio_input(ah, 0);
1142 ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
1143 if (ah->ah_gpio[0] == 0)
1144 ath5k_hw_set_gpio_intr(ah, 0, 1);
1145 else
1146 ath5k_hw_set_gpio_intr(ah, 0, 0);
1147 }
1148#endif
1149
1150 /*
1151 * Set the 32MHz reference clock on 5212 phy clock sleep register
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05001152 *
1153 * TODO: Find out how to switch to external 32Khz clock to save power
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001154 */
1155 if (ah->ah_version == AR5K_AR5212) {
1156 ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
1157 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
1158 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
1159 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
1160 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
Nick Kossifidis903b4742008-02-28 14:50:50 -05001161 ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001162 }
1163
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05001164 if (ah->ah_version == AR5K_AR5212) {
1165 ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
1166 ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
1167 ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
1168 if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413)
1169 ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
1170 }
1171
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001172 /*
1173 * Disable beacons and reset the register
1174 */
1175 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
1176 AR5K_BEACON_RESET_TSF);
1177
1178 return 0;
1179}
1180
1181/*
1182 * Reset chipset
1183 */
1184static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
1185{
1186 int ret;
1187 u32 mask = val ? val : ~0U;
1188
1189 ATH5K_TRACE(ah->ah_sc);
1190
1191 /* Read-and-clear RX Descriptor Pointer*/
1192 ath5k_hw_reg_read(ah, AR5K_RXDP);
1193
1194 /*
1195 * Reset the device and wait until success
1196 */
1197 ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
1198
1199 /* Wait at least 128 PCI clocks */
1200 udelay(15);
1201
1202 if (ah->ah_version == AR5K_AR5210) {
1203 val &= AR5K_RESET_CTL_CHIP;
1204 mask &= AR5K_RESET_CTL_CHIP;
1205 } else {
1206 val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
1207 mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
1208 }
1209
1210 ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
1211
1212 /*
1213 * Reset configuration register (for hw byte-swap). Note that this
1214 * is only set for big endian. We do the necessary magic in
1215 * AR5K_INIT_CFG.
1216 */
1217 if ((val & AR5K_RESET_CTL_PCU) == 0)
1218 ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
1219
1220 return ret;
1221}
1222
1223/*
1224 * Power management functions
1225 */
1226
1227/*
1228 * Sleep control
1229 */
1230int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
1231 bool set_chip, u16 sleep_duration)
1232{
1233 unsigned int i;
1234 u32 staid;
1235
1236 ATH5K_TRACE(ah->ah_sc);
1237 staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
1238
1239 switch (mode) {
1240 case AR5K_PM_AUTO:
1241 staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
1242 /* fallthrough */
1243 case AR5K_PM_NETWORK_SLEEP:
Joe Perchese9010e22008-03-07 14:21:16 -08001244 if (set_chip)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001245 ath5k_hw_reg_write(ah,
1246 AR5K_SLEEP_CTL_SLE | sleep_duration,
1247 AR5K_SLEEP_CTL);
1248
1249 staid |= AR5K_STA_ID1_PWR_SV;
1250 break;
1251
1252 case AR5K_PM_FULL_SLEEP:
Joe Perchese9010e22008-03-07 14:21:16 -08001253 if (set_chip)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001254 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
1255 AR5K_SLEEP_CTL);
1256
1257 staid |= AR5K_STA_ID1_PWR_SV;
1258 break;
1259
1260 case AR5K_PM_AWAKE:
Joe Perchese9010e22008-03-07 14:21:16 -08001261 if (!set_chip)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001262 goto commit;
1263
1264 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
1265 AR5K_SLEEP_CTL);
1266
1267 for (i = 5000; i > 0; i--) {
1268 /* Check if the chip did wake up */
1269 if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
1270 AR5K_PCICFG_SPWR_DN) == 0)
1271 break;
1272
1273 /* Wait a bit and retry */
1274 udelay(200);
1275 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
1276 AR5K_SLEEP_CTL);
1277 }
1278
1279 /* Fail if the chip didn't wake up */
1280 if (i <= 0)
1281 return -EIO;
1282
1283 staid &= ~AR5K_STA_ID1_PWR_SV;
1284 break;
1285
1286 default:
1287 return -EINVAL;
1288 }
1289
1290commit:
1291 ah->ah_power_mode = mode;
1292 ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
1293
1294 return 0;
1295}
1296
1297/***********************\
1298 DMA Related Functions
1299\***********************/
1300
1301/*
1302 * Receive functions
1303 */
1304
1305/*
1306 * Start DMA receive
1307 */
1308void ath5k_hw_start_rx(struct ath5k_hw *ah)
1309{
1310 ATH5K_TRACE(ah->ah_sc);
1311 ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
1312}
1313
1314/*
1315 * Stop DMA receive
1316 */
1317int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
1318{
1319 unsigned int i;
1320
1321 ATH5K_TRACE(ah->ah_sc);
1322 ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
1323
1324 /*
1325 * It may take some time to disable the DMA receive unit
1326 */
1327 for (i = 2000; i > 0 &&
1328 (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
1329 i--)
1330 udelay(10);
1331
1332 return i ? 0 : -EBUSY;
1333}
1334
1335/*
1336 * Get the address of the RX Descriptor
1337 */
1338u32 ath5k_hw_get_rx_buf(struct ath5k_hw *ah)
1339{
1340 return ath5k_hw_reg_read(ah, AR5K_RXDP);
1341}
1342
1343/*
1344 * Set the address of the RX Descriptor
1345 */
1346void ath5k_hw_put_rx_buf(struct ath5k_hw *ah, u32 phys_addr)
1347{
1348 ATH5K_TRACE(ah->ah_sc);
1349
1350 /*TODO:Shouldn't we check if RX is enabled first ?*/
1351 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
1352}
1353
1354/*
1355 * Transmit functions
1356 */
1357
1358/*
1359 * Start DMA transmit for a specific queue
1360 * (see also QCU/DCU functions)
1361 */
1362int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue)
1363{
1364 u32 tx_queue;
1365
1366 ATH5K_TRACE(ah->ah_sc);
1367 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1368
1369 /* Return if queue is declared inactive */
1370 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
1371 return -EIO;
1372
1373 if (ah->ah_version == AR5K_AR5210) {
1374 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
1375
1376 /*
1377 * Set the queue by type on 5210
1378 */
1379 switch (ah->ah_txq[queue].tqi_type) {
1380 case AR5K_TX_QUEUE_DATA:
1381 tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
1382 break;
1383 case AR5K_TX_QUEUE_BEACON:
1384 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
1385 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
1386 AR5K_BSR);
1387 break;
1388 case AR5K_TX_QUEUE_CAB:
1389 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
1390 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |
1391 AR5K_BCR_BDMAE, AR5K_BSR);
1392 break;
1393 default:
1394 return -EINVAL;
1395 }
1396 /* Start queue */
1397 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
1398 } else {
1399 /* Return if queue is disabled */
1400 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
1401 return -EIO;
1402
1403 /* Start queue */
1404 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);
1405 }
1406
1407 return 0;
1408}
1409
1410/*
1411 * Stop DMA transmit for a specific queue
1412 * (see also QCU/DCU functions)
1413 */
1414int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
1415{
1416 unsigned int i = 100;
1417 u32 tx_queue, pending;
1418
1419 ATH5K_TRACE(ah->ah_sc);
1420 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1421
1422 /* Return if queue is declared inactive */
1423 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
1424 return -EIO;
1425
1426 if (ah->ah_version == AR5K_AR5210) {
1427 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
1428
1429 /*
1430 * Set by queue type
1431 */
1432 switch (ah->ah_txq[queue].tqi_type) {
1433 case AR5K_TX_QUEUE_DATA:
1434 tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
1435 break;
1436 case AR5K_TX_QUEUE_BEACON:
1437 case AR5K_TX_QUEUE_CAB:
1438 /* XXX Fix me... */
1439 tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;
1440 ath5k_hw_reg_write(ah, 0, AR5K_BSR);
1441 break;
1442 default:
1443 return -EINVAL;
1444 }
1445
1446 /* Stop queue */
1447 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
Jiri Slaby274c7c32008-07-15 17:44:20 +02001448 ath5k_hw_reg_read(ah, AR5K_CR);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001449 } else {
1450 /*
1451 * Schedule TX disable and wait until queue is empty
1452 */
1453 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
1454
1455 /*Check for pending frames*/
1456 do {
1457 pending = ath5k_hw_reg_read(ah,
1458 AR5K_QUEUE_STATUS(queue)) &
1459 AR5K_QCU_STS_FRMPENDCNT;
1460 udelay(100);
1461 } while (--i && pending);
1462
1463 /* Clear register */
1464 ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
Jiri Slaby274c7c32008-07-15 17:44:20 +02001465 if (pending)
1466 return -EBUSY;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001467 }
1468
1469 /* TODO: Check for success else return error */
1470 return 0;
1471}
1472
1473/*
1474 * Get the address of the TX Descriptor for a specific queue
1475 * (see also QCU/DCU functions)
1476 */
1477u32 ath5k_hw_get_tx_buf(struct ath5k_hw *ah, unsigned int queue)
1478{
1479 u16 tx_reg;
1480
1481 ATH5K_TRACE(ah->ah_sc);
1482 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1483
1484 /*
1485 * Get the transmit queue descriptor pointer from the selected queue
1486 */
1487 /*5210 doesn't have QCU*/
1488 if (ah->ah_version == AR5K_AR5210) {
1489 switch (ah->ah_txq[queue].tqi_type) {
1490 case AR5K_TX_QUEUE_DATA:
1491 tx_reg = AR5K_NOQCU_TXDP0;
1492 break;
1493 case AR5K_TX_QUEUE_BEACON:
1494 case AR5K_TX_QUEUE_CAB:
1495 tx_reg = AR5K_NOQCU_TXDP1;
1496 break;
1497 default:
1498 return 0xffffffff;
1499 }
1500 } else {
1501 tx_reg = AR5K_QUEUE_TXDP(queue);
1502 }
1503
1504 return ath5k_hw_reg_read(ah, tx_reg);
1505}
1506
1507/*
1508 * Set the address of the TX Descriptor for a specific queue
1509 * (see also QCU/DCU functions)
1510 */
1511int ath5k_hw_put_tx_buf(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
1512{
1513 u16 tx_reg;
1514
1515 ATH5K_TRACE(ah->ah_sc);
1516 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1517
1518 /*
1519 * Set the transmit queue descriptor pointer register by type
1520 * on 5210
1521 */
1522 if (ah->ah_version == AR5K_AR5210) {
1523 switch (ah->ah_txq[queue].tqi_type) {
1524 case AR5K_TX_QUEUE_DATA:
1525 tx_reg = AR5K_NOQCU_TXDP0;
1526 break;
1527 case AR5K_TX_QUEUE_BEACON:
1528 case AR5K_TX_QUEUE_CAB:
1529 tx_reg = AR5K_NOQCU_TXDP1;
1530 break;
1531 default:
1532 return -EINVAL;
1533 }
1534 } else {
1535 /*
1536 * Set the transmit queue descriptor pointer for
1537 * the selected queue on QCU for 5211+
1538 * (this won't work if the queue is still active)
1539 */
1540 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
1541 return -EIO;
1542
1543 tx_reg = AR5K_QUEUE_TXDP(queue);
1544 }
1545
1546 /* Set descriptor pointer */
1547 ath5k_hw_reg_write(ah, phys_addr, tx_reg);
1548
1549 return 0;
1550}
1551
1552/*
1553 * Update tx trigger level
1554 */
1555int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
1556{
1557 u32 trigger_level, imr;
1558 int ret = -EIO;
1559
1560 ATH5K_TRACE(ah->ah_sc);
1561
1562 /*
1563 * Disable interrupts by setting the mask
1564 */
1565 imr = ath5k_hw_set_intr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
1566
1567 /*TODO: Boundary check on trigger_level*/
1568 trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
1569 AR5K_TXCFG_TXFULL);
1570
Joe Perchese9010e22008-03-07 14:21:16 -08001571 if (!increase) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001572 if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
1573 goto done;
1574 } else
1575 trigger_level +=
1576 ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
1577
1578 /*
1579 * Update trigger level on success
1580 */
1581 if (ah->ah_version == AR5K_AR5210)
1582 ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
1583 else
1584 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
1585 AR5K_TXCFG_TXFULL, trigger_level);
1586
1587 ret = 0;
1588
1589done:
1590 /*
1591 * Restore interrupt mask
1592 */
1593 ath5k_hw_set_intr(ah, imr);
1594
1595 return ret;
1596}
1597
1598/*
1599 * Interrupt handling
1600 */
1601
1602/*
1603 * Check if we have pending interrupts
1604 */
1605bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
1606{
1607 ATH5K_TRACE(ah->ah_sc);
1608 return ath5k_hw_reg_read(ah, AR5K_INTPEND);
1609}
1610
1611/*
1612 * Get interrupt mask (ISR)
1613 */
1614int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
1615{
1616 u32 data;
1617
1618 ATH5K_TRACE(ah->ah_sc);
1619
1620 /*
1621 * Read interrupt status from the Interrupt Status register
1622 * on 5210
1623 */
1624 if (ah->ah_version == AR5K_AR5210) {
1625 data = ath5k_hw_reg_read(ah, AR5K_ISR);
1626 if (unlikely(data == AR5K_INT_NOCARD)) {
1627 *interrupt_mask = data;
1628 return -ENODEV;
1629 }
1630 } else {
1631 /*
1632 * Read interrupt status from the Read-And-Clear shadow register
1633 * Note: PISR/SISR Not available on 5210
1634 */
1635 data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
1636 }
1637
1638 /*
1639 * Get abstract interrupt mask (driver-compatible)
1640 */
1641 *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
1642
1643 if (unlikely(data == AR5K_INT_NOCARD))
1644 return -ENODEV;
1645
1646 if (data & (AR5K_ISR_RXOK | AR5K_ISR_RXERR))
1647 *interrupt_mask |= AR5K_INT_RX;
1648
1649 if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR
1650 | AR5K_ISR_TXDESC | AR5K_ISR_TXEOL))
1651 *interrupt_mask |= AR5K_INT_TX;
1652
1653 if (ah->ah_version != AR5K_AR5210) {
1654 /*HIU = Host Interface Unit (PCI etc)*/
1655 if (unlikely(data & (AR5K_ISR_HIUERR)))
1656 *interrupt_mask |= AR5K_INT_FATAL;
1657
1658 /*Beacon Not Ready*/
1659 if (unlikely(data & (AR5K_ISR_BNR)))
1660 *interrupt_mask |= AR5K_INT_BNR;
1661 }
1662
1663 /*
1664 * XXX: BMISS interrupts may occur after association.
1665 * I found this on 5210 code but it needs testing. If this is
1666 * true we should disable them before assoc and re-enable them
1667 * after a successfull assoc + some jiffies.
1668 */
1669#if 0
1670 interrupt_mask &= ~AR5K_INT_BMISS;
1671#endif
1672
1673 /*
1674 * In case we didn't handle anything,
1675 * print the register value.
1676 */
1677 if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
1678 ATH5K_PRINTF("0x%08x\n", data);
1679
1680 return 0;
1681}
1682
1683/*
1684 * Set interrupt mask
1685 */
1686enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask)
1687{
1688 enum ath5k_int old_mask, int_mask;
1689
1690 /*
1691 * Disable card interrupts to prevent any race conditions
1692 * (they will be re-enabled afterwards).
1693 */
1694 ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
1695
1696 old_mask = ah->ah_imr;
1697
1698 /*
1699 * Add additional, chipset-dependent interrupt mask flags
1700 * and write them to the IMR (interrupt mask register).
1701 */
1702 int_mask = new_mask & AR5K_INT_COMMON;
1703
1704 if (new_mask & AR5K_INT_RX)
1705 int_mask |= AR5K_IMR_RXOK | AR5K_IMR_RXERR | AR5K_IMR_RXORN |
1706 AR5K_IMR_RXDESC;
1707
1708 if (new_mask & AR5K_INT_TX)
1709 int_mask |= AR5K_IMR_TXOK | AR5K_IMR_TXERR | AR5K_IMR_TXDESC |
1710 AR5K_IMR_TXURN;
1711
1712 if (ah->ah_version != AR5K_AR5210) {
1713 if (new_mask & AR5K_INT_FATAL) {
1714 int_mask |= AR5K_IMR_HIUERR;
1715 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_MCABT |
1716 AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR);
1717 }
1718 }
1719
1720 ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
1721
1722 /* Store new interrupt mask */
1723 ah->ah_imr = new_mask;
1724
1725 /* ..re-enable interrupts */
1726 ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
Jiri Slaby274c7c32008-07-15 17:44:20 +02001727 ath5k_hw_reg_read(ah, AR5K_IER);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001728
1729 return old_mask;
1730}
1731
1732
1733/*************************\
1734 EEPROM access functions
1735\*************************/
1736
1737/*
1738 * Read from eeprom
1739 */
1740static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
1741{
1742 u32 status, timeout;
1743
1744 ATH5K_TRACE(ah->ah_sc);
1745 /*
1746 * Initialize EEPROM access
1747 */
1748 if (ah->ah_version == AR5K_AR5210) {
1749 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
1750 (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
1751 } else {
1752 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
1753 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1754 AR5K_EEPROM_CMD_READ);
1755 }
1756
1757 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
1758 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
1759 if (status & AR5K_EEPROM_STAT_RDDONE) {
1760 if (status & AR5K_EEPROM_STAT_RDERR)
1761 return -EIO;
1762 *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
1763 0xffff);
1764 return 0;
1765 }
1766 udelay(15);
1767 }
1768
1769 return -ETIMEDOUT;
1770}
1771
1772/*
1773 * Write to eeprom - currently disabled, use at your own risk
1774 */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001775#if 0
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001776static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data)
1777{
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001778
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001779 u32 status, timeout;
1780
1781 ATH5K_TRACE(ah->ah_sc);
1782
1783 /*
1784 * Initialize eeprom access
1785 */
1786
1787 if (ah->ah_version == AR5K_AR5210) {
1788 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
1789 } else {
1790 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1791 AR5K_EEPROM_CMD_RESET);
1792 }
1793
1794 /*
1795 * Write data to data register
1796 */
1797
1798 if (ah->ah_version == AR5K_AR5210) {
1799 ath5k_hw_reg_write(ah, data, AR5K_EEPROM_BASE + (4 * offset));
1800 } else {
1801 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
1802 ath5k_hw_reg_write(ah, data, AR5K_EEPROM_DATA);
1803 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1804 AR5K_EEPROM_CMD_WRITE);
1805 }
1806
1807 /*
1808 * Check status
1809 */
1810
1811 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
1812 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
1813 if (status & AR5K_EEPROM_STAT_WRDONE) {
1814 if (status & AR5K_EEPROM_STAT_WRERR)
1815 return EIO;
1816 return 0;
1817 }
1818 udelay(15);
1819 }
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001820
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001821 ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!");
1822 return -EIO;
1823}
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001824#endif
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001825
1826/*
1827 * Translate binary channel representation in EEPROM to frequency
1828 */
1829static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin, unsigned int mode)
1830{
1831 u16 val;
1832
1833 if (bin == AR5K_EEPROM_CHANNEL_DIS)
1834 return bin;
1835
1836 if (mode == AR5K_EEPROM_MODE_11A) {
1837 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
1838 val = (5 * bin) + 4800;
1839 else
1840 val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
1841 (bin * 10) + 5100;
1842 } else {
1843 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
1844 val = bin + 2300;
1845 else
1846 val = bin + 2400;
1847 }
1848
1849 return val;
1850}
1851
1852/*
1853 * Read antenna infos from eeprom
1854 */
1855static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
1856 unsigned int mode)
1857{
1858 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1859 u32 o = *offset;
1860 u16 val;
1861 int ret, i = 0;
1862
1863 AR5K_EEPROM_READ(o++, val);
1864 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
1865 ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f;
1866 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
1867
1868 AR5K_EEPROM_READ(o++, val);
1869 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
1870 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
1871 ee->ee_ant_control[mode][i++] = val & 0x3f;
1872
1873 AR5K_EEPROM_READ(o++, val);
1874 ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
1875 ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
1876 ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
1877
1878 AR5K_EEPROM_READ(o++, val);
1879 ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
1880 ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
1881 ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
1882 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
1883
1884 AR5K_EEPROM_READ(o++, val);
1885 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
1886 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
1887 ee->ee_ant_control[mode][i++] = val & 0x3f;
1888
1889 /* Get antenna modes */
1890 ah->ah_antenna[mode][0] =
1891 (ee->ee_ant_control[mode][0] << 4) | 0x1;
1892 ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
1893 ee->ee_ant_control[mode][1] |
1894 (ee->ee_ant_control[mode][2] << 6) |
1895 (ee->ee_ant_control[mode][3] << 12) |
1896 (ee->ee_ant_control[mode][4] << 18) |
1897 (ee->ee_ant_control[mode][5] << 24);
1898 ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
1899 ee->ee_ant_control[mode][6] |
1900 (ee->ee_ant_control[mode][7] << 6) |
1901 (ee->ee_ant_control[mode][8] << 12) |
1902 (ee->ee_ant_control[mode][9] << 18) |
1903 (ee->ee_ant_control[mode][10] << 24);
1904
1905 /* return new offset */
1906 *offset = o;
1907
1908 return 0;
1909}
1910
1911/*
1912 * Read supported modes from eeprom
1913 */
1914static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
1915 unsigned int mode)
1916{
1917 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1918 u32 o = *offset;
1919 u16 val;
1920 int ret;
1921
1922 AR5K_EEPROM_READ(o++, val);
1923 ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
1924 ee->ee_thr_62[mode] = val & 0xff;
1925
1926 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
1927 ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
1928
1929 AR5K_EEPROM_READ(o++, val);
1930 ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
1931 ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
1932
1933 AR5K_EEPROM_READ(o++, val);
1934 ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
1935
1936 if ((val & 0xff) & 0x80)
1937 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
1938 else
1939 ee->ee_noise_floor_thr[mode] = val & 0xff;
1940
1941 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
1942 ee->ee_noise_floor_thr[mode] =
1943 mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
1944
1945 AR5K_EEPROM_READ(o++, val);
1946 ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
1947 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
1948 ee->ee_xpd[mode] = val & 0x1;
1949
1950 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
1951 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
1952
1953 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
1954 AR5K_EEPROM_READ(o++, val);
1955 ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
1956
1957 if (mode == AR5K_EEPROM_MODE_11A)
1958 ee->ee_xr_power[mode] = val & 0x3f;
1959 else {
1960 ee->ee_ob[mode][0] = val & 0x7;
1961 ee->ee_db[mode][0] = (val >> 3) & 0x7;
1962 }
1963 }
1964
1965 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
1966 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
1967 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
1968 } else {
1969 ee->ee_i_gain[mode] = (val >> 13) & 0x7;
1970
1971 AR5K_EEPROM_READ(o++, val);
1972 ee->ee_i_gain[mode] |= (val << 3) & 0x38;
1973
1974 if (mode == AR5K_EEPROM_MODE_11G)
1975 ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
1976 }
1977
1978 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
1979 mode == AR5K_EEPROM_MODE_11A) {
1980 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
1981 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
1982 }
1983
1984 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 &&
1985 mode == AR5K_EEPROM_MODE_11G)
1986 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
1987
1988 /* return new offset */
1989 *offset = o;
1990
1991 return 0;
1992}
1993
1994/*
1995 * Initialize eeprom & capabilities structs
1996 */
1997static int ath5k_eeprom_init(struct ath5k_hw *ah)
1998{
1999 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2000 unsigned int mode, i;
2001 int ret;
2002 u32 offset;
2003 u16 val;
2004
2005 /* Initial TX thermal adjustment values */
2006 ee->ee_tx_clip = 4;
2007 ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
2008 ee->ee_gain_select = 1;
2009
2010 /*
2011 * Read values from EEPROM and store them in the capability structure
2012 */
2013 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
2014 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
2015 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
2016 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
2017 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
2018
2019 /* Return if we have an old EEPROM */
2020 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
2021 return 0;
2022
2023#ifdef notyet
2024 /*
2025 * Validate the checksum of the EEPROM date. There are some
2026 * devices with invalid EEPROMs.
2027 */
2028 for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
2029 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
2030 cksum ^= val;
2031 }
2032 if (cksum != AR5K_EEPROM_INFO_CKSUM) {
2033 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
2034 return -EIO;
2035 }
2036#endif
2037
2038 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
2039 ee_ant_gain);
2040
2041 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
2042 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
2043 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
2044 }
2045
2046 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
2047 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
2048 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
2049 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
2050
2051 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
2052 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
2053 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
2054 }
2055
2056 /*
2057 * Get conformance test limit values
2058 */
2059 offset = AR5K_EEPROM_CTL(ah->ah_ee_version);
2060 ee->ee_ctls = AR5K_EEPROM_N_CTLS(ah->ah_ee_version);
2061
2062 for (i = 0; i < ee->ee_ctls; i++) {
2063 AR5K_EEPROM_READ(offset++, val);
2064 ee->ee_ctl[i] = (val >> 8) & 0xff;
2065 ee->ee_ctl[i + 1] = val & 0xff;
2066 }
2067
2068 /*
2069 * Get values for 802.11a (5GHz)
2070 */
2071 mode = AR5K_EEPROM_MODE_11A;
2072
2073 ee->ee_turbo_max_power[mode] =
2074 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
2075
2076 offset = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
2077
2078 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
2079 if (ret)
2080 return ret;
2081
2082 AR5K_EEPROM_READ(offset++, val);
2083 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
2084 ee->ee_ob[mode][3] = (val >> 5) & 0x7;
2085 ee->ee_db[mode][3] = (val >> 2) & 0x7;
2086 ee->ee_ob[mode][2] = (val << 1) & 0x7;
2087
2088 AR5K_EEPROM_READ(offset++, val);
2089 ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
2090 ee->ee_db[mode][2] = (val >> 12) & 0x7;
2091 ee->ee_ob[mode][1] = (val >> 9) & 0x7;
2092 ee->ee_db[mode][1] = (val >> 6) & 0x7;
2093 ee->ee_ob[mode][0] = (val >> 3) & 0x7;
2094 ee->ee_db[mode][0] = val & 0x7;
2095
2096 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
2097 if (ret)
2098 return ret;
2099
2100 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
2101 AR5K_EEPROM_READ(offset++, val);
2102 ee->ee_margin_tx_rx[mode] = val & 0x3f;
2103 }
2104
2105 /*
2106 * Get values for 802.11b (2.4GHz)
2107 */
2108 mode = AR5K_EEPROM_MODE_11B;
2109 offset = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
2110
2111 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
2112 if (ret)
2113 return ret;
2114
2115 AR5K_EEPROM_READ(offset++, val);
2116 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
2117 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
2118 ee->ee_db[mode][1] = val & 0x7;
2119
2120 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
2121 if (ret)
2122 return ret;
2123
2124 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
2125 AR5K_EEPROM_READ(offset++, val);
2126 ee->ee_cal_pier[mode][0] =
2127 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2128 ee->ee_cal_pier[mode][1] =
2129 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
2130
2131 AR5K_EEPROM_READ(offset++, val);
2132 ee->ee_cal_pier[mode][2] =
2133 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2134 }
2135
2136 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
2137 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
2138
2139 /*
2140 * Get values for 802.11g (2.4GHz)
2141 */
2142 mode = AR5K_EEPROM_MODE_11G;
2143 offset = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
2144
2145 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
2146 if (ret)
2147 return ret;
2148
2149 AR5K_EEPROM_READ(offset++, val);
2150 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
2151 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
2152 ee->ee_db[mode][1] = val & 0x7;
2153
2154 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
2155 if (ret)
2156 return ret;
2157
2158 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
2159 AR5K_EEPROM_READ(offset++, val);
2160 ee->ee_cal_pier[mode][0] =
2161 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2162 ee->ee_cal_pier[mode][1] =
2163 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
2164
2165 AR5K_EEPROM_READ(offset++, val);
2166 ee->ee_turbo_max_power[mode] = val & 0x7f;
2167 ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
2168
2169 AR5K_EEPROM_READ(offset++, val);
2170 ee->ee_cal_pier[mode][2] =
2171 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2172
2173 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
2174 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
2175
2176 AR5K_EEPROM_READ(offset++, val);
2177 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
2178 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
2179
2180 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
2181 AR5K_EEPROM_READ(offset++, val);
2182 ee->ee_cck_ofdm_gain_delta = val & 0xff;
2183 }
2184 }
2185
2186 /*
2187 * Read 5GHz EEPROM channels
2188 */
2189
2190 return 0;
2191}
2192
2193/*
2194 * Read the MAC address from eeprom
2195 */
2196static int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
2197{
2198 u8 mac_d[ETH_ALEN];
2199 u32 total, offset;
2200 u16 data;
2201 int octet, ret;
2202
2203 memset(mac, 0, ETH_ALEN);
2204 memset(mac_d, 0, ETH_ALEN);
2205
2206 ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
2207 if (ret)
2208 return ret;
2209
2210 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
2211 ret = ath5k_hw_eeprom_read(ah, offset, &data);
2212 if (ret)
2213 return ret;
2214
2215 total += data;
2216 mac_d[octet + 1] = data & 0xff;
2217 mac_d[octet] = data >> 8;
2218 octet += 2;
2219 }
2220
2221 memcpy(mac, mac_d, ETH_ALEN);
2222
2223 if (!total || total == 3 * 0xffff)
2224 return -EINVAL;
2225
2226 return 0;
2227}
2228
2229/*
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002230 * Fill the capabilities struct
2231 */
2232static int ath5k_hw_get_capabilities(struct ath5k_hw *ah)
2233{
2234 u16 ee_header;
2235
2236 ATH5K_TRACE(ah->ah_sc);
2237 /* Capabilities stored in the EEPROM */
2238 ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
2239
2240 if (ah->ah_version == AR5K_AR5210) {
2241 /*
2242 * Set radio capabilities
2243 * (The AR5110 only supports the middle 5GHz band)
2244 */
2245 ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
2246 ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
2247 ah->ah_capabilities.cap_range.range_2ghz_min = 0;
2248 ah->ah_capabilities.cap_range.range_2ghz_max = 0;
2249
2250 /* Set supported modes */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002251 __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
2252 __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002253 } else {
2254 /*
2255 * XXX The tranceiver supports frequencies from 4920 to 6100GHz
2256 * XXX and from 2312 to 2732GHz. There are problems with the
2257 * XXX current ieee80211 implementation because the IEEE
2258 * XXX channel mapping does not support negative channel
2259 * XXX numbers (2312MHz is channel -19). Of course, this
2260 * XXX doesn't matter because these channels are out of range
2261 * XXX but some regulation domains like MKK (Japan) will
2262 * XXX support frequencies somewhere around 4.8GHz.
2263 */
2264
2265 /*
2266 * Set radio capabilities
2267 */
2268
2269 if (AR5K_EEPROM_HDR_11A(ee_header)) {
2270 ah->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
2271 ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
2272
2273 /* Set supported modes */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002274 __set_bit(AR5K_MODE_11A,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002275 ah->ah_capabilities.cap_mode);
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002276 __set_bit(AR5K_MODE_11A_TURBO,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002277 ah->ah_capabilities.cap_mode);
2278 if (ah->ah_version == AR5K_AR5212)
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002279 __set_bit(AR5K_MODE_11G_TURBO,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002280 ah->ah_capabilities.cap_mode);
2281 }
2282
2283 /* Enable 802.11b if a 2GHz capable radio (2111/5112) is
2284 * connected */
2285 if (AR5K_EEPROM_HDR_11B(ee_header) ||
2286 AR5K_EEPROM_HDR_11G(ee_header)) {
2287 ah->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
2288 ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
2289
2290 if (AR5K_EEPROM_HDR_11B(ee_header))
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002291 __set_bit(AR5K_MODE_11B,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002292 ah->ah_capabilities.cap_mode);
2293
2294 if (AR5K_EEPROM_HDR_11G(ee_header))
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002295 __set_bit(AR5K_MODE_11G,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002296 ah->ah_capabilities.cap_mode);
2297 }
2298 }
2299
2300 /* GPIO */
2301 ah->ah_gpio_npins = AR5K_NUM_GPIO;
2302
2303 /* Set number of supported TX queues */
2304 if (ah->ah_version == AR5K_AR5210)
2305 ah->ah_capabilities.cap_queues.q_tx_num =
2306 AR5K_NUM_TX_QUEUES_NOQCU;
2307 else
2308 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
2309
2310 return 0;
2311}
2312
2313/*********************************\
2314 Protocol Control Unit Functions
2315\*********************************/
2316
2317/*
2318 * Set Operation mode
2319 */
2320int ath5k_hw_set_opmode(struct ath5k_hw *ah)
2321{
2322 u32 pcu_reg, beacon_reg, low_id, high_id;
2323
2324 pcu_reg = 0;
2325 beacon_reg = 0;
2326
2327 ATH5K_TRACE(ah->ah_sc);
2328
2329 switch (ah->ah_op_mode) {
2330 case IEEE80211_IF_TYPE_IBSS:
2331 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_DESC_ANTENNA |
2332 (ah->ah_version == AR5K_AR5210 ?
2333 AR5K_STA_ID1_NO_PSPOLL : 0);
2334 beacon_reg |= AR5K_BCR_ADHOC;
2335 break;
2336
2337 case IEEE80211_IF_TYPE_AP:
2338 pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_RTS_DEF_ANTENNA |
2339 (ah->ah_version == AR5K_AR5210 ?
2340 AR5K_STA_ID1_NO_PSPOLL : 0);
2341 beacon_reg |= AR5K_BCR_AP;
2342 break;
2343
2344 case IEEE80211_IF_TYPE_STA:
2345 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
2346 (ah->ah_version == AR5K_AR5210 ?
2347 AR5K_STA_ID1_PWR_SV : 0);
2348 case IEEE80211_IF_TYPE_MNTR:
2349 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
2350 (ah->ah_version == AR5K_AR5210 ?
2351 AR5K_STA_ID1_NO_PSPOLL : 0);
2352 break;
2353
2354 default:
2355 return -EINVAL;
2356 }
2357
2358 /*
2359 * Set PCU registers
2360 */
2361 low_id = AR5K_LOW_ID(ah->ah_sta_id);
2362 high_id = AR5K_HIGH_ID(ah->ah_sta_id);
2363 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
2364 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
2365
2366 /*
2367 * Set Beacon Control Register on 5210
2368 */
2369 if (ah->ah_version == AR5K_AR5210)
2370 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
2371
2372 return 0;
2373}
2374
2375/*
2376 * BSSID Functions
2377 */
2378
2379/*
2380 * Get station id
2381 */
2382void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
2383{
2384 ATH5K_TRACE(ah->ah_sc);
2385 memcpy(mac, ah->ah_sta_id, ETH_ALEN);
2386}
2387
2388/*
2389 * Set station id
2390 */
2391int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
2392{
2393 u32 low_id, high_id;
2394
2395 ATH5K_TRACE(ah->ah_sc);
2396 /* Set new station ID */
2397 memcpy(ah->ah_sta_id, mac, ETH_ALEN);
2398
2399 low_id = AR5K_LOW_ID(mac);
2400 high_id = AR5K_HIGH_ID(mac);
2401
2402 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
2403 ath5k_hw_reg_write(ah, high_id, AR5K_STA_ID1);
2404
2405 return 0;
2406}
2407
2408/*
2409 * Set BSSID
2410 */
2411void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
2412{
2413 u32 low_id, high_id;
2414 u16 tim_offset = 0;
2415
2416 /*
2417 * Set simple BSSID mask on 5212
2418 */
2419 if (ah->ah_version == AR5K_AR5212) {
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05002420 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0);
2421 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002422 }
2423
2424 /*
2425 * Set BSSID which triggers the "SME Join" operation
2426 */
2427 low_id = AR5K_LOW_ID(bssid);
2428 high_id = AR5K_HIGH_ID(bssid);
2429 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
2430 ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
2431 AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
2432
2433 if (assoc_id == 0) {
2434 ath5k_hw_disable_pspoll(ah);
2435 return;
2436 }
2437
2438 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
2439 tim_offset ? tim_offset + 4 : 0);
2440
2441 ath5k_hw_enable_pspoll(ah, NULL, 0);
2442}
2443/**
2444 * ath5k_hw_set_bssid_mask - set common bits we should listen to
2445 *
2446 * The bssid_mask is a utility used by AR5212 hardware to inform the hardware
2447 * which bits of the interface's MAC address should be looked at when trying
2448 * to decide which packets to ACK. In station mode every bit matters. In AP
2449 * mode with a single BSS every bit matters as well. In AP mode with
2450 * multiple BSSes not every bit matters.
2451 *
2452 * @ah: the &struct ath5k_hw
2453 * @mask: the bssid_mask, a u8 array of size ETH_ALEN
2454 *
2455 * Note that this is a simple filter and *does* not filter out all
2456 * relevant frames. Some non-relevant frames will get through, probability
2457 * jocks are welcomed to compute.
2458 *
2459 * When handling multiple BSSes (or VAPs) you can get the BSSID mask by
2460 * computing the set of:
2461 *
2462 * ~ ( MAC XOR BSSID )
2463 *
2464 * When you do this you are essentially computing the common bits. Later it
2465 * is assumed the harware will "and" (&) the BSSID mask with the MAC address
2466 * to obtain the relevant bits which should match on the destination frame.
2467 *
2468 * Simple example: on your card you have have two BSSes you have created with
2469 * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
2470 * There is another BSSID-03 but you are not part of it. For simplicity's sake,
2471 * assuming only 4 bits for a mac address and for BSSIDs you can then have:
2472 *
2473 * \
2474 * MAC: 0001 |
2475 * BSSID-01: 0100 | --> Belongs to us
2476 * BSSID-02: 1001 |
2477 * /
2478 * -------------------
2479 * BSSID-03: 0110 | --> External
2480 * -------------------
2481 *
2482 * Our bssid_mask would then be:
2483 *
2484 * On loop iteration for BSSID-01:
2485 * ~(0001 ^ 0100) -> ~(0101)
2486 * -> 1010
2487 * bssid_mask = 1010
2488 *
2489 * On loop iteration for BSSID-02:
2490 * bssid_mask &= ~(0001 ^ 1001)
2491 * bssid_mask = (1010) & ~(0001 ^ 1001)
2492 * bssid_mask = (1010) & ~(1001)
2493 * bssid_mask = (1010) & (0110)
2494 * bssid_mask = 0010
2495 *
2496 * A bssid_mask of 0010 means "only pay attention to the second least
2497 * significant bit". This is because its the only bit common
2498 * amongst the MAC and all BSSIDs we support. To findout what the real
2499 * common bit is we can simply "&" the bssid_mask now with any BSSID we have
2500 * or our MAC address (we assume the hardware uses the MAC address).
2501 *
2502 * Now, suppose there's an incoming frame for BSSID-03:
2503 *
2504 * IFRAME-01: 0110
2505 *
2506 * An easy eye-inspeciton of this already should tell you that this frame
2507 * will not pass our check. This is beacuse the bssid_mask tells the
2508 * hardware to only look at the second least significant bit and the
2509 * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
2510 * as 1, which does not match 0.
2511 *
2512 * So with IFRAME-01 we *assume* the hardware will do:
2513 *
2514 * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
2515 * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
2516 * --> allow = (0010) == 0000 ? 1 : 0;
2517 * --> allow = 0
2518 *
2519 * Lets now test a frame that should work:
2520 *
2521 * IFRAME-02: 0001 (we should allow)
2522 *
2523 * allow = (0001 & 1010) == 1010
2524 *
2525 * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
2526 * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0;
2527 * --> allow = (0010) == (0010)
2528 * --> allow = 1
2529 *
2530 * Other examples:
2531 *
2532 * IFRAME-03: 0100 --> allowed
2533 * IFRAME-04: 1001 --> allowed
2534 * IFRAME-05: 1101 --> allowed but its not for us!!!
2535 *
2536 */
2537int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
2538{
2539 u32 low_id, high_id;
2540 ATH5K_TRACE(ah->ah_sc);
2541
2542 if (ah->ah_version == AR5K_AR5212) {
2543 low_id = AR5K_LOW_ID(mask);
2544 high_id = AR5K_HIGH_ID(mask);
2545
2546 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
2547 ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
2548
2549 return 0;
2550 }
2551
2552 return -EIO;
2553}
2554
2555/*
2556 * Receive start/stop functions
2557 */
2558
2559/*
2560 * Start receive on PCU
2561 */
2562void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
2563{
2564 ATH5K_TRACE(ah->ah_sc);
2565 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05002566
2567 /* TODO: ANI Support */
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002568}
2569
2570/*
2571 * Stop receive on PCU
2572 */
2573void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah)
2574{
2575 ATH5K_TRACE(ah->ah_sc);
2576 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05002577
2578 /* TODO: ANI Support */
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002579}
2580
2581/*
2582 * RX Filter functions
2583 */
2584
2585/*
2586 * Set multicast filter
2587 */
2588void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
2589{
2590 ATH5K_TRACE(ah->ah_sc);
2591 /* Set the multicat filter */
2592 ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
2593 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
2594}
2595
2596/*
2597 * Set multicast filter by index
2598 */
2599int ath5k_hw_set_mcast_filterindex(struct ath5k_hw *ah, u32 index)
2600{
2601
2602 ATH5K_TRACE(ah->ah_sc);
2603 if (index >= 64)
2604 return -EINVAL;
2605 else if (index >= 32)
2606 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
2607 (1 << (index - 32)));
2608 else
2609 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
2610
2611 return 0;
2612}
2613
2614/*
2615 * Clear Multicast filter by index
2616 */
2617int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
2618{
2619
2620 ATH5K_TRACE(ah->ah_sc);
2621 if (index >= 64)
2622 return -EINVAL;
2623 else if (index >= 32)
2624 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
2625 (1 << (index - 32)));
2626 else
2627 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
2628
2629 return 0;
2630}
2631
2632/*
2633 * Get current rx filter
2634 */
2635u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
2636{
2637 u32 data, filter = 0;
2638
2639 ATH5K_TRACE(ah->ah_sc);
2640 filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
2641
2642 /*Radar detection for 5212*/
2643 if (ah->ah_version == AR5K_AR5212) {
2644 data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
2645
2646 if (data & AR5K_PHY_ERR_FIL_RADAR)
2647 filter |= AR5K_RX_FILTER_RADARERR;
2648 if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
2649 filter |= AR5K_RX_FILTER_PHYERR;
2650 }
2651
2652 return filter;
2653}
2654
2655/*
2656 * Set rx filter
2657 */
2658void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
2659{
2660 u32 data = 0;
2661
2662 ATH5K_TRACE(ah->ah_sc);
2663
2664 /* Set PHY error filter register on 5212*/
2665 if (ah->ah_version == AR5K_AR5212) {
2666 if (filter & AR5K_RX_FILTER_RADARERR)
2667 data |= AR5K_PHY_ERR_FIL_RADAR;
2668 if (filter & AR5K_RX_FILTER_PHYERR)
2669 data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
2670 }
2671
2672 /*
2673 * The AR5210 uses promiscous mode to detect radar activity
2674 */
2675 if (ah->ah_version == AR5K_AR5210 &&
2676 (filter & AR5K_RX_FILTER_RADARERR)) {
2677 filter &= ~AR5K_RX_FILTER_RADARERR;
2678 filter |= AR5K_RX_FILTER_PROM;
2679 }
2680
2681 /*Zero length DMA*/
2682 if (data)
2683 AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
2684 else
2685 AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
2686
2687 /*Write RX Filter register*/
2688 ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
2689
2690 /*Write PHY error filter register on 5212*/
2691 if (ah->ah_version == AR5K_AR5212)
2692 ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
2693
2694}
2695
2696/*
2697 * Beacon related functions
2698 */
2699
2700/*
2701 * Get a 32bit TSF
2702 */
2703u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
2704{
2705 ATH5K_TRACE(ah->ah_sc);
2706 return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
2707}
2708
2709/*
2710 * Get the full 64bit TSF
2711 */
2712u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
2713{
2714 u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
2715 ATH5K_TRACE(ah->ah_sc);
2716
2717 return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
2718}
2719
2720/*
2721 * Force a TSF reset
2722 */
2723void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
2724{
2725 ATH5K_TRACE(ah->ah_sc);
2726 AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_RESET_TSF);
2727}
2728
2729/*
2730 * Initialize beacon timers
2731 */
2732void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
2733{
2734 u32 timer1, timer2, timer3;
2735
2736 ATH5K_TRACE(ah->ah_sc);
2737 /*
2738 * Set the additional timers by mode
2739 */
2740 switch (ah->ah_op_mode) {
2741 case IEEE80211_IF_TYPE_STA:
2742 if (ah->ah_version == AR5K_AR5210) {
2743 timer1 = 0xffffffff;
2744 timer2 = 0xffffffff;
2745 } else {
2746 timer1 = 0x0000ffff;
2747 timer2 = 0x0007ffff;
2748 }
2749 break;
2750
2751 default:
Bruno Randolf1008e0f2008-01-18 21:51:19 +09002752 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
2753 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002754 }
2755
2756 timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
2757
2758 /*
2759 * Set the beacon register and enable all timers.
2760 * (next beacon, DMA beacon, software beacon, ATIM window time)
2761 */
2762 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
2763 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
2764 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
2765 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
2766
2767 ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
2768 AR5K_BEACON_RESET_TSF | AR5K_BEACON_ENABLE),
2769 AR5K_BEACON);
2770}
2771
2772#if 0
2773/*
2774 * Set beacon timers
2775 */
2776int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
2777 const struct ath5k_beacon_state *state)
2778{
2779 u32 cfp_period, next_cfp, dtim, interval, next_beacon;
2780
2781 /*
2782 * TODO: should be changed through *state
2783 * review struct ath5k_beacon_state struct
2784 *
2785 * XXX: These are used for cfp period bellow, are they
2786 * ok ? Is it O.K. for tsf here to be 0 or should we use
2787 * get_tsf ?
2788 */
2789 u32 dtim_count = 0; /* XXX */
2790 u32 cfp_count = 0; /* XXX */
2791 u32 tsf = 0; /* XXX */
2792
2793 ATH5K_TRACE(ah->ah_sc);
2794 /* Return on an invalid beacon state */
2795 if (state->bs_interval < 1)
2796 return -EINVAL;
2797
2798 interval = state->bs_interval;
2799 dtim = state->bs_dtim_period;
2800
2801 /*
2802 * PCF support?
2803 */
2804 if (state->bs_cfp_period > 0) {
2805 /*
2806 * Enable PCF mode and set the CFP
2807 * (Contention Free Period) and timer registers
2808 */
2809 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
2810 state->bs_interval;
2811 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
2812 state->bs_interval;
2813
2814 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
2815 AR5K_STA_ID1_DEFAULT_ANTENNA |
2816 AR5K_STA_ID1_PCF);
2817 ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
2818 ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
2819 AR5K_CFP_DUR);
2820 ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
2821 next_cfp)) << 3, AR5K_TIMER2);
2822 } else {
2823 /* Disable PCF mode */
2824 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
2825 AR5K_STA_ID1_DEFAULT_ANTENNA |
2826 AR5K_STA_ID1_PCF);
2827 }
2828
2829 /*
2830 * Enable the beacon timer register
2831 */
2832 ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
2833
2834 /*
2835 * Start the beacon timers
2836 */
2837 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &~
2838 (AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
2839 AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
2840 AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
2841 AR5K_BEACON_PERIOD), AR5K_BEACON);
2842
2843 /*
2844 * Write new beacon miss threshold, if it appears to be valid
2845 * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
2846 * and return if its not in range. We can test this by reading value and
2847 * setting value to a largest value and seeing which values register.
2848 */
2849
2850 AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
2851 state->bs_bmiss_threshold);
2852
2853 /*
2854 * Set sleep control register
2855 * XXX: Didn't find this in 5210 code but since this register
2856 * exists also in ar5k's 5210 headers i leave it as common code.
2857 */
2858 AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
2859 (state->bs_sleep_duration - 3) << 3);
2860
2861 /*
2862 * Set enhanced sleep registers on 5212
2863 */
2864 if (ah->ah_version == AR5K_AR5212) {
2865 if (state->bs_sleep_duration > state->bs_interval &&
2866 roundup(state->bs_sleep_duration, interval) ==
2867 state->bs_sleep_duration)
2868 interval = state->bs_sleep_duration;
2869
2870 if (state->bs_sleep_duration > dtim && (dtim == 0 ||
2871 roundup(state->bs_sleep_duration, dtim) ==
2872 state->bs_sleep_duration))
2873 dtim = state->bs_sleep_duration;
2874
2875 if (interval > dtim)
2876 return -EINVAL;
2877
2878 next_beacon = interval == dtim ? state->bs_next_dtim :
2879 state->bs_next_beacon;
2880
2881 ath5k_hw_reg_write(ah,
2882 AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
2883 AR5K_SLEEP0_NEXT_DTIM) |
2884 AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
2885 AR5K_SLEEP0_ENH_SLEEP_EN |
2886 AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
2887
2888 ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
2889 AR5K_SLEEP1_NEXT_TIM) |
2890 AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
2891
2892 ath5k_hw_reg_write(ah,
2893 AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
2894 AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
2895 }
2896
2897 return 0;
2898}
2899
2900/*
2901 * Reset beacon timers
2902 */
2903void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
2904{
2905 ATH5K_TRACE(ah->ah_sc);
2906 /*
2907 * Disable beacon timer
2908 */
2909 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
2910
2911 /*
2912 * Disable some beacon register values
2913 */
2914 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
2915 AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
2916 ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
2917}
2918
2919/*
2920 * Wait for beacon queue to finish
2921 */
2922int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
2923{
2924 unsigned int i;
2925 int ret;
2926
2927 ATH5K_TRACE(ah->ah_sc);
2928
2929 /* 5210 doesn't have QCU*/
2930 if (ah->ah_version == AR5K_AR5210) {
2931 /*
2932 * Wait for beaconn queue to finish by checking
2933 * Control Register and Beacon Status Register.
2934 */
2935 for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
2936 if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
2937 ||
2938 !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
2939 break;
2940 udelay(10);
2941 }
2942
2943 /* Timeout... */
2944 if (i <= 0) {
2945 /*
2946 * Re-schedule the beacon queue
2947 */
2948 ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
2949 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
2950 AR5K_BCR);
2951
2952 return -EIO;
2953 }
2954 ret = 0;
2955 } else {
2956 /*5211/5212*/
2957 ret = ath5k_hw_register_timeout(ah,
2958 AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
2959 AR5K_QCU_STS_FRMPENDCNT, 0, false);
2960
2961 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
2962 return -EIO;
2963 }
2964
2965 return ret;
2966}
2967#endif
2968
2969/*
2970 * Update mib counters (statistics)
2971 */
2972void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
Nick Kossifidis194828a2008-04-16 18:49:02 +03002973 struct ieee80211_low_level_stats *stats)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002974{
2975 ATH5K_TRACE(ah->ah_sc);
Nick Kossifidis194828a2008-04-16 18:49:02 +03002976
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002977 /* Read-And-Clear */
Nick Kossifidis194828a2008-04-16 18:49:02 +03002978 stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
2979 stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
2980 stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
2981 stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
2982
2983 /* XXX: Should we use this to track beacon count ?
2984 * -we read it anyway to clear the register */
2985 ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002986
2987 /* Reset profile count registers on 5212*/
2988 if (ah->ah_version == AR5K_AR5212) {
2989 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
2990 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
2991 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
2992 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
2993 }
2994}
2995
2996/** ath5k_hw_set_ack_bitrate - set bitrate for ACKs
2997 *
2998 * @ah: the &struct ath5k_hw
2999 * @high: determines if to use low bit rate or now
3000 */
3001void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
3002{
3003 if (ah->ah_version != AR5K_AR5212)
3004 return;
3005 else {
3006 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
3007 if (high)
3008 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
3009 else
3010 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
3011 }
3012}
3013
3014
3015/*
3016 * ACK/CTS Timeouts
3017 */
3018
3019/*
3020 * Set ACK timeout on PCU
3021 */
3022int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
3023{
3024 ATH5K_TRACE(ah->ah_sc);
3025 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
3026 ah->ah_turbo) <= timeout)
3027 return -EINVAL;
3028
3029 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
3030 ath5k_hw_htoclock(timeout, ah->ah_turbo));
3031
3032 return 0;
3033}
3034
3035/*
3036 * Read the ACK timeout from PCU
3037 */
3038unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
3039{
3040 ATH5K_TRACE(ah->ah_sc);
3041
3042 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
3043 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
3044}
3045
3046/*
3047 * Set CTS timeout on PCU
3048 */
3049int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
3050{
3051 ATH5K_TRACE(ah->ah_sc);
3052 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
3053 ah->ah_turbo) <= timeout)
3054 return -EINVAL;
3055
3056 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
3057 ath5k_hw_htoclock(timeout, ah->ah_turbo));
3058
3059 return 0;
3060}
3061
3062/*
3063 * Read CTS timeout from PCU
3064 */
3065unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
3066{
3067 ATH5K_TRACE(ah->ah_sc);
3068 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
3069 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
3070}
3071
3072/*
3073 * Key table (WEP) functions
3074 */
3075
3076int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
3077{
3078 unsigned int i;
3079
3080 ATH5K_TRACE(ah->ah_sc);
3081 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
3082
3083 for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
3084 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
3085
Nick Kossifidis194828a2008-04-16 18:49:02 +03003086 /*
3087 * Set NULL encryption on AR5212+
3088 *
3089 * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
3090 * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
3091 *
3092 * Note2: Windows driver (ndiswrapper) sets this to
3093 * 0x00000714 instead of 0x00000007
3094 */
3095 if (ah->ah_version > AR5K_AR5211)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003096 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
3097 AR5K_KEYTABLE_TYPE(entry));
3098
3099 return 0;
3100}
3101
3102int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
3103{
3104 ATH5K_TRACE(ah->ah_sc);
3105 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
3106
3107 /* Check the validation flag at the end of the entry */
3108 return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
3109 AR5K_KEYTABLE_VALID;
3110}
3111
3112int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
3113 const struct ieee80211_key_conf *key, const u8 *mac)
3114{
3115 unsigned int i;
3116 __le32 key_v[5] = {};
3117 u32 keytype;
3118
3119 ATH5K_TRACE(ah->ah_sc);
3120
3121 /* key->keylen comes in from mac80211 in bytes */
3122
3123 if (key->keylen > AR5K_KEYTABLE_SIZE / 8)
3124 return -EOPNOTSUPP;
3125
3126 switch (key->keylen) {
3127 /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */
3128 case 40 / 8:
3129 memcpy(&key_v[0], key->key, 5);
3130 keytype = AR5K_KEYTABLE_TYPE_40;
3131 break;
3132
3133 /* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */
3134 case 104 / 8:
3135 memcpy(&key_v[0], &key->key[0], 6);
3136 memcpy(&key_v[2], &key->key[6], 6);
3137 memcpy(&key_v[4], &key->key[12], 1);
3138 keytype = AR5K_KEYTABLE_TYPE_104;
3139 break;
3140 /* WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */
3141 case 128 / 8:
3142 memcpy(&key_v[0], &key->key[0], 6);
3143 memcpy(&key_v[2], &key->key[6], 6);
3144 memcpy(&key_v[4], &key->key[12], 4);
3145 keytype = AR5K_KEYTABLE_TYPE_128;
3146 break;
3147
3148 default:
3149 return -EINVAL; /* shouldn't happen */
3150 }
3151
3152 for (i = 0; i < ARRAY_SIZE(key_v); i++)
3153 ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
3154 AR5K_KEYTABLE_OFF(entry, i));
3155
3156 ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
3157
3158 return ath5k_hw_set_key_lladdr(ah, entry, mac);
3159}
3160
3161int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
3162{
3163 u32 low_id, high_id;
3164
3165 ATH5K_TRACE(ah->ah_sc);
3166 /* Invalid entry (key table overflow) */
3167 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
3168
3169 /* MAC may be NULL if it's a broadcast key. In this case no need to
3170 * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
3171 if (unlikely(mac == NULL)) {
3172 low_id = 0xffffffff;
3173 high_id = 0xffff | AR5K_KEYTABLE_VALID;
3174 } else {
3175 low_id = AR5K_LOW_ID(mac);
3176 high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
3177 }
3178
3179 ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
3180 ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
3181
3182 return 0;
3183}
3184
3185
3186/********************************************\
3187Queue Control Unit, DFS Control Unit Functions
3188\********************************************/
3189
3190/*
3191 * Initialize a transmit queue
3192 */
3193int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
3194 struct ath5k_txq_info *queue_info)
3195{
3196 unsigned int queue;
3197 int ret;
3198
3199 ATH5K_TRACE(ah->ah_sc);
3200
3201 /*
3202 * Get queue by type
3203 */
3204 /*5210 only has 2 queues*/
3205 if (ah->ah_version == AR5K_AR5210) {
3206 switch (queue_type) {
3207 case AR5K_TX_QUEUE_DATA:
3208 queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
3209 break;
3210 case AR5K_TX_QUEUE_BEACON:
3211 case AR5K_TX_QUEUE_CAB:
3212 queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
3213 break;
3214 default:
3215 return -EINVAL;
3216 }
3217 } else {
3218 switch (queue_type) {
3219 case AR5K_TX_QUEUE_DATA:
3220 for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
3221 ah->ah_txq[queue].tqi_type !=
3222 AR5K_TX_QUEUE_INACTIVE; queue++) {
3223
3224 if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
3225 return -EINVAL;
3226 }
3227 break;
3228 case AR5K_TX_QUEUE_UAPSD:
3229 queue = AR5K_TX_QUEUE_ID_UAPSD;
3230 break;
3231 case AR5K_TX_QUEUE_BEACON:
3232 queue = AR5K_TX_QUEUE_ID_BEACON;
3233 break;
3234 case AR5K_TX_QUEUE_CAB:
3235 queue = AR5K_TX_QUEUE_ID_CAB;
3236 break;
3237 case AR5K_TX_QUEUE_XR_DATA:
3238 if (ah->ah_version != AR5K_AR5212)
3239 ATH5K_ERR(ah->ah_sc,
3240 "XR data queues only supported in"
3241 " 5212!\n");
3242 queue = AR5K_TX_QUEUE_ID_XR_DATA;
3243 break;
3244 default:
3245 return -EINVAL;
3246 }
3247 }
3248
3249 /*
3250 * Setup internal queue structure
3251 */
3252 memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
3253 ah->ah_txq[queue].tqi_type = queue_type;
3254
3255 if (queue_info != NULL) {
3256 queue_info->tqi_type = queue_type;
3257 ret = ath5k_hw_setup_tx_queueprops(ah, queue, queue_info);
3258 if (ret)
3259 return ret;
3260 }
3261 /*
3262 * We use ah_txq_status to hold a temp value for
3263 * the Secondary interrupt mask registers on 5211+
3264 * check out ath5k_hw_reset_tx_queue
3265 */
3266 AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
3267
3268 return queue;
3269}
3270
3271/*
3272 * Setup a transmit queue
3273 */
3274int ath5k_hw_setup_tx_queueprops(struct ath5k_hw *ah, int queue,
3275 const struct ath5k_txq_info *queue_info)
3276{
3277 ATH5K_TRACE(ah->ah_sc);
3278 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3279
3280 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
3281 return -EIO;
3282
3283 memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
3284
3285 /*XXX: Is this supported on 5210 ?*/
3286 if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
3287 ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
3288 (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
3289 queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
3290 ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
3291
3292 return 0;
3293}
3294
3295/*
3296 * Get properties for a specific transmit queue
3297 */
3298int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
3299 struct ath5k_txq_info *queue_info)
3300{
3301 ATH5K_TRACE(ah->ah_sc);
3302 memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
3303 return 0;
3304}
3305
3306/*
3307 * Set a transmit queue inactive
3308 */
3309void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
3310{
3311 ATH5K_TRACE(ah->ah_sc);
3312 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
3313 return;
3314
3315 /* This queue will be skipped in further operations */
3316 ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
3317 /*For SIMR setup*/
3318 AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
3319}
3320
3321/*
3322 * Set DFS params for a transmit queue
3323 */
3324int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
3325{
3326 u32 cw_min, cw_max, retry_lg, retry_sh;
3327 struct ath5k_txq_info *tq = &ah->ah_txq[queue];
3328
3329 ATH5K_TRACE(ah->ah_sc);
3330 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3331
3332 tq = &ah->ah_txq[queue];
3333
3334 if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
3335 return 0;
3336
3337 if (ah->ah_version == AR5K_AR5210) {
3338 /* Only handle data queues, others will be ignored */
3339 if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
3340 return 0;
3341
3342 /* Set Slot time */
Joe Perchese9010e22008-03-07 14:21:16 -08003343 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003344 AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
3345 AR5K_SLOT_TIME);
3346 /* Set ACK_CTS timeout */
Joe Perchese9010e22008-03-07 14:21:16 -08003347 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003348 AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
3349 AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
3350 /* Set Transmit Latency */
Joe Perchese9010e22008-03-07 14:21:16 -08003351 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003352 AR5K_INIT_TRANSMIT_LATENCY_TURBO :
3353 AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
3354 /* Set IFS0 */
Joe Perchese9010e22008-03-07 14:21:16 -08003355 if (ah->ah_turbo)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003356 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
3357 (ah->ah_aifs + tq->tqi_aifs) *
3358 AR5K_INIT_SLOT_TIME_TURBO) <<
3359 AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
3360 AR5K_IFS0);
3361 else
3362 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
3363 (ah->ah_aifs + tq->tqi_aifs) *
3364 AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
3365 AR5K_INIT_SIFS, AR5K_IFS0);
3366
3367 /* Set IFS1 */
Joe Perchese9010e22008-03-07 14:21:16 -08003368 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003369 AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
3370 AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +03003371 /* Set AR5K_PHY_SETTLING */
Joe Perchese9010e22008-03-07 14:21:16 -08003372 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Nick Kossifidis0bacdf32008-07-30 13:18:59 +03003373 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
3374 | 0x38 :
3375 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
3376 | 0x1C,
3377 AR5K_PHY_SETTLING);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003378 /* Set Frame Control Register */
Joe Perchese9010e22008-03-07 14:21:16 -08003379 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003380 (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
3381 AR5K_PHY_TURBO_SHORT | 0x2020) :
3382 (AR5K_PHY_FRAME_CTL_INI | 0x1020),
3383 AR5K_PHY_FRAME_CTL_5210);
3384 }
3385
3386 /*
3387 * Calculate cwmin/max by channel mode
3388 */
3389 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
3390 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
3391 ah->ah_aifs = AR5K_TUNE_AIFS;
3392 /*XR is only supported on 5212*/
3393 if (IS_CHAN_XR(ah->ah_current_channel) &&
3394 ah->ah_version == AR5K_AR5212) {
3395 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
3396 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
3397 ah->ah_aifs = AR5K_TUNE_AIFS_XR;
3398 /*B mode is not supported on 5210*/
3399 } else if (IS_CHAN_B(ah->ah_current_channel) &&
3400 ah->ah_version != AR5K_AR5210) {
3401 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
3402 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
3403 ah->ah_aifs = AR5K_TUNE_AIFS_11B;
3404 }
3405
3406 cw_min = 1;
3407 while (cw_min < ah->ah_cw_min)
3408 cw_min = (cw_min << 1) | 1;
3409
3410 cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
3411 ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
3412 cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
3413 ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
3414
3415 /*
3416 * Calculate and set retry limits
3417 */
Joe Perchese9010e22008-03-07 14:21:16 -08003418 if (ah->ah_software_retry) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003419 /* XXX Need to test this */
3420 retry_lg = ah->ah_limit_tx_retries;
3421 retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
3422 AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
3423 } else {
3424 retry_lg = AR5K_INIT_LG_RETRY;
3425 retry_sh = AR5K_INIT_SH_RETRY;
3426 }
3427
3428 /*No QCU/DCU [5210]*/
3429 if (ah->ah_version == AR5K_AR5210) {
3430 ath5k_hw_reg_write(ah,
3431 (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
3432 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
3433 AR5K_NODCU_RETRY_LMT_SLG_RETRY)
3434 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
3435 AR5K_NODCU_RETRY_LMT_SSH_RETRY)
3436 | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
3437 | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
3438 AR5K_NODCU_RETRY_LMT);
3439 } else {
3440 /*QCU/DCU [5211+]*/
3441 ath5k_hw_reg_write(ah,
3442 AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
3443 AR5K_DCU_RETRY_LMT_SLG_RETRY) |
3444 AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
3445 AR5K_DCU_RETRY_LMT_SSH_RETRY) |
3446 AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
3447 AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
3448 AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
3449
3450 /*===Rest is also for QCU/DCU only [5211+]===*/
3451
3452 /*
3453 * Set initial content window (cw_min/cw_max)
3454 * and arbitrated interframe space (aifs)...
3455 */
3456 ath5k_hw_reg_write(ah,
3457 AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
3458 AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
3459 AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
3460 AR5K_DCU_LCL_IFS_AIFS),
3461 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
3462
3463 /*
3464 * Set misc registers
3465 */
3466 ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY,
3467 AR5K_QUEUE_MISC(queue));
3468
3469 if (tq->tqi_cbr_period) {
3470 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
3471 AR5K_QCU_CBRCFG_INTVAL) |
3472 AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
3473 AR5K_QCU_CBRCFG_ORN_THRES),
3474 AR5K_QUEUE_CBRCFG(queue));
3475 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3476 AR5K_QCU_MISC_FRSHED_CBR);
3477 if (tq->tqi_cbr_overflow_limit)
3478 AR5K_REG_ENABLE_BITS(ah,
3479 AR5K_QUEUE_MISC(queue),
3480 AR5K_QCU_MISC_CBR_THRES_ENABLE);
3481 }
3482
3483 if (tq->tqi_ready_time)
3484 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
3485 AR5K_QCU_RDYTIMECFG_INTVAL) |
3486 AR5K_QCU_RDYTIMECFG_ENABLE,
3487 AR5K_QUEUE_RDYTIMECFG(queue));
3488
3489 if (tq->tqi_burst_time) {
3490 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
3491 AR5K_DCU_CHAN_TIME_DUR) |
3492 AR5K_DCU_CHAN_TIME_ENABLE,
3493 AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
3494
3495 if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
3496 AR5K_REG_ENABLE_BITS(ah,
3497 AR5K_QUEUE_MISC(queue),
3498 AR5K_QCU_MISC_TXE);
3499 }
3500
3501 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
3502 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
3503 AR5K_QUEUE_DFS_MISC(queue));
3504
3505 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
3506 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
3507 AR5K_QUEUE_DFS_MISC(queue));
3508
3509 /*
3510 * Set registers by queue type
3511 */
3512 switch (tq->tqi_type) {
3513 case AR5K_TX_QUEUE_BEACON:
3514 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3515 AR5K_QCU_MISC_FRSHED_DBA_GT |
3516 AR5K_QCU_MISC_CBREXP_BCN |
3517 AR5K_QCU_MISC_BCN_ENABLE);
3518
3519 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
3520 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
3521 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
3522 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
3523 AR5K_DCU_MISC_BCN_ENABLE);
3524
3525 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
3526 (AR5K_TUNE_SW_BEACON_RESP -
3527 AR5K_TUNE_DMA_BEACON_RESP) -
3528 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
3529 AR5K_QCU_RDYTIMECFG_ENABLE,
3530 AR5K_QUEUE_RDYTIMECFG(queue));
3531 break;
3532
3533 case AR5K_TX_QUEUE_CAB:
3534 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3535 AR5K_QCU_MISC_FRSHED_DBA_GT |
3536 AR5K_QCU_MISC_CBREXP |
3537 AR5K_QCU_MISC_CBREXP_BCN);
3538
3539 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
3540 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
3541 AR5K_DCU_MISC_ARBLOCK_CTL_S));
3542 break;
3543
3544 case AR5K_TX_QUEUE_UAPSD:
3545 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3546 AR5K_QCU_MISC_CBREXP);
3547 break;
3548
3549 case AR5K_TX_QUEUE_DATA:
3550 default:
3551 break;
3552 }
3553
3554 /*
3555 * Enable interrupts for this tx queue
3556 * in the secondary interrupt mask registers
3557 */
3558 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
3559 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
3560
3561 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
3562 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
3563
3564 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
3565 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
3566
3567 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
3568 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
3569
3570 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
3571 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
3572
3573
3574 /* Update secondary interrupt mask registers */
3575 ah->ah_txq_imr_txok &= ah->ah_txq_status;
3576 ah->ah_txq_imr_txerr &= ah->ah_txq_status;
3577 ah->ah_txq_imr_txurn &= ah->ah_txq_status;
3578 ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
3579 ah->ah_txq_imr_txeol &= ah->ah_txq_status;
3580
3581 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
3582 AR5K_SIMR0_QCU_TXOK) |
3583 AR5K_REG_SM(ah->ah_txq_imr_txdesc,
3584 AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
3585 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
3586 AR5K_SIMR1_QCU_TXERR) |
3587 AR5K_REG_SM(ah->ah_txq_imr_txeol,
3588 AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
3589 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txurn,
3590 AR5K_SIMR2_QCU_TXURN), AR5K_SIMR2);
3591 }
3592
3593 return 0;
3594}
3595
3596/*
3597 * Get number of pending frames
3598 * for a specific queue [5211+]
3599 */
3600u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) {
3601 ATH5K_TRACE(ah->ah_sc);
3602 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3603
3604 /* Return if queue is declared inactive */
3605 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
3606 return false;
3607
3608 /* XXX: How about AR5K_CFG_TXCNT ? */
3609 if (ah->ah_version == AR5K_AR5210)
3610 return false;
3611
3612 return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT;
3613}
3614
3615/*
3616 * Set slot time
3617 */
3618int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
3619{
3620 ATH5K_TRACE(ah->ah_sc);
3621 if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
3622 return -EINVAL;
3623
3624 if (ah->ah_version == AR5K_AR5210)
3625 ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
3626 ah->ah_turbo), AR5K_SLOT_TIME);
3627 else
3628 ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
3629
3630 return 0;
3631}
3632
3633/*
3634 * Get slot time
3635 */
3636unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
3637{
3638 ATH5K_TRACE(ah->ah_sc);
3639 if (ah->ah_version == AR5K_AR5210)
3640 return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
3641 AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
3642 else
3643 return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
3644}
3645
3646
3647/******************************\
3648 Hardware Descriptor Functions
3649\******************************/
3650
3651/*
3652 * TX Descriptor
3653 */
3654
3655/*
3656 * Initialize the 2-word tx descriptor on 5210/5211
3657 */
3658static int
3659ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3660 unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type,
3661 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
3662 unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
3663 unsigned int rtscts_rate, unsigned int rtscts_duration)
3664{
3665 u32 frame_type;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003666 struct ath5k_hw_2w_tx_ctl *tx_ctl;
Bruno Randolf281c56d2008-02-05 18:44:55 +09003667 unsigned int frame_len;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003668
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003669 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003670
3671 /*
3672 * Validate input
3673 * - Zero retries don't make sense.
3674 * - A zero rate will put the HW into a mode where it continously sends
3675 * noise on the channel, so it is important to avoid this.
3676 */
3677 if (unlikely(tx_tries0 == 0)) {
3678 ATH5K_ERR(ah->ah_sc, "zero retries\n");
3679 WARN_ON(1);
3680 return -EINVAL;
3681 }
3682 if (unlikely(tx_rate0 == 0)) {
3683 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3684 WARN_ON(1);
3685 return -EINVAL;
3686 }
3687
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003688 /* Clear descriptor */
3689 memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003690
3691 /* Setup control descriptor */
3692
3693 /* Verify and set frame length */
Bruno Randolf281c56d2008-02-05 18:44:55 +09003694
3695 /* remove padding we might have added before */
3696 frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
3697
3698 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003699 return -EINVAL;
3700
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003701 tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003702
3703 /* Verify and set buffer length */
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003704
3705 /* NB: beacon's BufLen must be a multiple of 4 bytes */
3706 if(type == AR5K_PKT_TYPE_BEACON)
Bruno Randolf281c56d2008-02-05 18:44:55 +09003707 pkt_len = roundup(pkt_len, 4);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003708
Bruno Randolf281c56d2008-02-05 18:44:55 +09003709 if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003710 return -EINVAL;
3711
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003712 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003713
3714 /*
3715 * Verify and set header length
3716 * XXX: I only found that on 5210 code, does it work on 5211 ?
3717 */
3718 if (ah->ah_version == AR5K_AR5210) {
3719 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
3720 return -EINVAL;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003721 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003722 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
3723 }
3724
3725 /*Diferences between 5210-5211*/
3726 if (ah->ah_version == AR5K_AR5210) {
3727 switch (type) {
3728 case AR5K_PKT_TYPE_BEACON:
3729 case AR5K_PKT_TYPE_PROBE_RESP:
3730 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
3731 case AR5K_PKT_TYPE_PIFS:
3732 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
3733 default:
3734 frame_type = type /*<< 2 ?*/;
3735 }
3736
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003737 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003738 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
3739 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3740 } else {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003741 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003742 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
3743 AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003744 tx_ctl->tx_control_1 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003745 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
3746 }
3747#define _TX_FLAGS(_c, _flag) \
3748 if (flags & AR5K_TXDESC_##_flag) \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003749 tx_ctl->tx_control_##_c |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003750 AR5K_2W_TX_DESC_CTL##_c##_##_flag
3751
3752 _TX_FLAGS(0, CLRDMASK);
3753 _TX_FLAGS(0, VEOL);
3754 _TX_FLAGS(0, INTREQ);
3755 _TX_FLAGS(0, RTSENA);
3756 _TX_FLAGS(1, NOACK);
3757
3758#undef _TX_FLAGS
3759
3760 /*
3761 * WEP crap
3762 */
3763 if (key_index != AR5K_TXKEYIX_INVALID) {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003764 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003765 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003766 tx_ctl->tx_control_1 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003767 AR5K_REG_SM(key_index,
3768 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3769 }
3770
3771 /*
3772 * RTS/CTS Duration [5210 ?]
3773 */
3774 if ((ah->ah_version == AR5K_AR5210) &&
3775 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003776 tx_ctl->tx_control_1 |= rtscts_duration &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003777 AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
3778
3779 return 0;
3780}
3781
3782/*
3783 * Initialize the 4-word tx descriptor on 5212
3784 */
3785static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
3786 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
3787 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
3788 unsigned int tx_tries0, unsigned int key_index,
3789 unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate,
3790 unsigned int rtscts_duration)
3791{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003792 struct ath5k_hw_4w_tx_ctl *tx_ctl;
Bruno Randolf281c56d2008-02-05 18:44:55 +09003793 unsigned int frame_len;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003794
3795 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003796 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003797
3798 /*
3799 * Validate input
3800 * - Zero retries don't make sense.
3801 * - A zero rate will put the HW into a mode where it continously sends
3802 * noise on the channel, so it is important to avoid this.
3803 */
3804 if (unlikely(tx_tries0 == 0)) {
3805 ATH5K_ERR(ah->ah_sc, "zero retries\n");
3806 WARN_ON(1);
3807 return -EINVAL;
3808 }
3809 if (unlikely(tx_rate0 == 0)) {
3810 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3811 WARN_ON(1);
3812 return -EINVAL;
3813 }
3814
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003815 /* Clear descriptor */
3816 memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003817
3818 /* Setup control descriptor */
3819
3820 /* Verify and set frame length */
Bruno Randolf281c56d2008-02-05 18:44:55 +09003821
3822 /* remove padding we might have added before */
3823 frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
3824
3825 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003826 return -EINVAL;
3827
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003828 tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003829
3830 /* Verify and set buffer length */
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003831
3832 /* NB: beacon's BufLen must be a multiple of 4 bytes */
3833 if(type == AR5K_PKT_TYPE_BEACON)
Bruno Randolf281c56d2008-02-05 18:44:55 +09003834 pkt_len = roundup(pkt_len, 4);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003835
Bruno Randolf281c56d2008-02-05 18:44:55 +09003836 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003837 return -EINVAL;
3838
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003839 tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003840
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003841 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003842 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
3843 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003844 tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003845 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003846 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003847 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003848 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003849
3850#define _TX_FLAGS(_c, _flag) \
3851 if (flags & AR5K_TXDESC_##_flag) \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003852 tx_ctl->tx_control_##_c |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003853 AR5K_4W_TX_DESC_CTL##_c##_##_flag
3854
3855 _TX_FLAGS(0, CLRDMASK);
3856 _TX_FLAGS(0, VEOL);
3857 _TX_FLAGS(0, INTREQ);
3858 _TX_FLAGS(0, RTSENA);
3859 _TX_FLAGS(0, CTSENA);
3860 _TX_FLAGS(1, NOACK);
3861
3862#undef _TX_FLAGS
3863
3864 /*
3865 * WEP crap
3866 */
3867 if (key_index != AR5K_TXKEYIX_INVALID) {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003868 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
3869 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003870 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3871 }
3872
3873 /*
3874 * RTS/CTS
3875 */
3876 if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
3877 if ((flags & AR5K_TXDESC_RTSENA) &&
3878 (flags & AR5K_TXDESC_CTSENA))
3879 return -EINVAL;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003880 tx_ctl->tx_control_2 |= rtscts_duration &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003881 AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003882 tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003883 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
3884 }
3885
3886 return 0;
3887}
3888
3889/*
3890 * Initialize a 4-word multirate tx descriptor on 5212
3891 */
Jiri Slabyb9887632008-02-15 21:58:52 +01003892static int
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003893ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3894 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
3895 unsigned int tx_rate3, u_int tx_tries3)
3896{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003897 struct ath5k_hw_4w_tx_ctl *tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003898
3899 /*
3900 * Rates can be 0 as long as the retry count is 0 too.
3901 * A zero rate and nonzero retry count will put the HW into a mode where
3902 * it continously sends noise on the channel, so it is important to
3903 * avoid this.
3904 */
3905 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
3906 (tx_rate2 == 0 && tx_tries2 != 0) ||
3907 (tx_rate3 == 0 && tx_tries3 != 0))) {
3908 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3909 WARN_ON(1);
3910 return -EINVAL;
3911 }
3912
3913 if (ah->ah_version == AR5K_AR5212) {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003914 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003915
3916#define _XTX_TRIES(_n) \
3917 if (tx_tries##_n) { \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003918 tx_ctl->tx_control_2 |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003919 AR5K_REG_SM(tx_tries##_n, \
3920 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003921 tx_ctl->tx_control_3 |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003922 AR5K_REG_SM(tx_rate##_n, \
3923 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \
3924 }
3925
3926 _XTX_TRIES(1);
3927 _XTX_TRIES(2);
3928 _XTX_TRIES(3);
3929
3930#undef _XTX_TRIES
3931
Jiri Slabyb9887632008-02-15 21:58:52 +01003932 return 1;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003933 }
3934
Jiri Slabyb9887632008-02-15 21:58:52 +01003935 return 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003936}
3937
3938/*
3939 * Proccess the tx status descriptor on 5210/5211
3940 */
3941static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09003942 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003943{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003944 struct ath5k_hw_2w_tx_ctl *tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003945 struct ath5k_hw_tx_status *tx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003946
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003947 ATH5K_TRACE(ah->ah_sc);
3948
3949 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
3950 tx_status = &desc->ud.ds_tx5210.tx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003951
3952 /* No frame has been send or error */
3953 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
3954 return -EINPROGRESS;
3955
3956 /*
3957 * Get descriptor status
3958 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09003959 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003960 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003961 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003962 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003963 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003964 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003965 /*TODO: ts->ts_virtcol + test*/
3966 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003967 AR5K_DESC_TX_STATUS1_SEQ_NUM);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003968 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003969 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003970 ts->ts_antenna = 1;
3971 ts->ts_status = 0;
3972 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003973 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3974
3975 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
3976 if (tx_status->tx_status_0 &
3977 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003978 ts->ts_status |= AR5K_TXERR_XRETRY;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003979
3980 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003981 ts->ts_status |= AR5K_TXERR_FIFO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003982
3983 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003984 ts->ts_status |= AR5K_TXERR_FILT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003985 }
3986
3987 return 0;
3988}
3989
3990/*
3991 * Proccess a tx descriptor on 5212
3992 */
3993static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09003994 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003995{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003996 struct ath5k_hw_4w_tx_ctl *tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003997 struct ath5k_hw_tx_status *tx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003998
3999 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004000
4001 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
4002 tx_status = &desc->ud.ds_tx5212.tx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004003
4004 /* No frame has been send or error */
4005 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
4006 return -EINPROGRESS;
4007
4008 /*
4009 * Get descriptor status
4010 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09004011 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004012 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004013 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004014 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004015 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004016 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004017 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004018 AR5K_DESC_TX_STATUS1_SEQ_NUM);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004019 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004020 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004021 ts->ts_antenna = (tx_status->tx_status_1 &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004022 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004023 ts->ts_status = 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004024
4025 switch (AR5K_REG_MS(tx_status->tx_status_1,
4026 AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
4027 case 0:
Bruno Randolfb47f4072008-03-05 18:35:45 +09004028 ts->ts_rate = tx_ctl->tx_control_3 &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004029 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
4030 break;
4031 case 1:
Bruno Randolfb47f4072008-03-05 18:35:45 +09004032 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004033 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004034 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004035 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
4036 break;
4037 case 2:
Bruno Randolfb47f4072008-03-05 18:35:45 +09004038 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004039 AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004040 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004041 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
4042 break;
4043 case 3:
Bruno Randolfb47f4072008-03-05 18:35:45 +09004044 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004045 AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004046 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004047 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
4048 break;
4049 }
4050
4051 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
4052 if (tx_status->tx_status_0 &
4053 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004054 ts->ts_status |= AR5K_TXERR_XRETRY;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004055
4056 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004057 ts->ts_status |= AR5K_TXERR_FIFO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004058
4059 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004060 ts->ts_status |= AR5K_TXERR_FILT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004061 }
4062
4063 return 0;
4064}
4065
4066/*
4067 * RX Descriptor
4068 */
4069
4070/*
4071 * Initialize an rx descriptor
4072 */
4073int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
4074 u32 size, unsigned int flags)
4075{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004076 struct ath5k_hw_rx_ctl *rx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004077
4078 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004079 rx_ctl = &desc->ud.ds_rx.rx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004080
4081 /*
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004082 * Clear the descriptor
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004083 * If we don't clean the status descriptor,
4084 * while scanning we get too many results,
4085 * most of them virtual, after some secs
4086 * of scanning system hangs. M.F.
4087 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004088 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004089
4090 /* Setup descriptor */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004091 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
4092 if (unlikely(rx_ctl->rx_control_1 != size))
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004093 return -EINVAL;
4094
4095 if (flags & AR5K_RXDESC_INTREQ)
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004096 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004097
4098 return 0;
4099}
4100
4101/*
4102 * Proccess the rx status descriptor on 5210/5211
4103 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004104static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09004105 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004106{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004107 struct ath5k_hw_rx_status *rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004108
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004109 rx_status = &desc->ud.ds_rx.u.rx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004110
4111 /* No frame received / not ready */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004112 if (unlikely((rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_DONE)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004113 == 0))
4114 return -EINPROGRESS;
4115
4116 /*
4117 * Frame receive status
4118 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09004119 rs->rs_datalen = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004120 AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004121 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004122 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004123 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004124 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004125 rs->rs_antenna = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004126 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004127 rs->rs_more = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004128 AR5K_5210_RX_DESC_STATUS0_MORE;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004129 /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
4130 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004131 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004132 rs->rs_status = 0;
Bob Copelandd6894b52008-05-12 21:16:44 -04004133 rs->rs_phyerr = 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004134
4135 /*
4136 * Key table status
4137 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004138 if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004139 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004140 AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004141 else
Bruno Randolfb47f4072008-03-05 18:35:45 +09004142 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004143
4144 /*
4145 * Receive/descriptor errors
4146 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004147 if ((rx_status->rx_status_1 &
4148 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
4149 if (rx_status->rx_status_1 &
4150 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004151 rs->rs_status |= AR5K_RXERR_CRC;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004152
4153 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004154 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004155 rs->rs_status |= AR5K_RXERR_FIFO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004156
4157 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004158 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
Bruno Randolfb47f4072008-03-05 18:35:45 +09004159 rs->rs_status |= AR5K_RXERR_PHY;
Bob Copelandd6894b52008-05-12 21:16:44 -04004160 rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolfb47f4072008-03-05 18:35:45 +09004161 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004162 }
4163
4164 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004165 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004166 rs->rs_status |= AR5K_RXERR_DECRYPT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004167 }
4168
4169 return 0;
4170}
4171
4172/*
4173 * Proccess the rx status descriptor on 5212
4174 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004175static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09004176 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004177{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004178 struct ath5k_hw_rx_status *rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004179 struct ath5k_hw_rx_error *rx_err;
4180
4181 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004182 rx_status = &desc->ud.ds_rx.u.rx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004183
4184 /* Overlay on error */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004185 rx_err = &desc->ud.ds_rx.u.rx_err;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004186
4187 /* No frame received / not ready */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004188 if (unlikely((rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_DONE)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004189 == 0))
4190 return -EINPROGRESS;
4191
4192 /*
4193 * Frame receive status
4194 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09004195 rs->rs_datalen = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004196 AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004197 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004198 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004199 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004200 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004201 rs->rs_antenna = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004202 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004203 rs->rs_more = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004204 AR5K_5212_RX_DESC_STATUS0_MORE;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004205 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004206 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004207 rs->rs_status = 0;
Bob Copelandd6894b52008-05-12 21:16:44 -04004208 rs->rs_phyerr = 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004209
4210 /*
4211 * Key table status
4212 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004213 if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004214 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004215 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004216 else
Bruno Randolfb47f4072008-03-05 18:35:45 +09004217 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004218
4219 /*
4220 * Receive/descriptor errors
4221 */
4222 if ((rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004223 AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
4224 if (rx_status->rx_status_1 &
4225 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004226 rs->rs_status |= AR5K_RXERR_CRC;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004227
4228 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004229 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
Bruno Randolfb47f4072008-03-05 18:35:45 +09004230 rs->rs_status |= AR5K_RXERR_PHY;
Bob Copelandd6894b52008-05-12 21:16:44 -04004231 rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
Bruno Randolfb47f4072008-03-05 18:35:45 +09004232 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004233 }
4234
4235 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004236 AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004237 rs->rs_status |= AR5K_RXERR_DECRYPT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004238
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004239 if (rx_status->rx_status_1 &
4240 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004241 rs->rs_status |= AR5K_RXERR_MIC;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004242 }
4243
4244 return 0;
4245}
4246
4247
4248/****************\
4249 GPIO Functions
4250\****************/
4251
4252/*
4253 * Set led state
4254 */
4255void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
4256{
4257 u32 led;
4258 /*5210 has different led mode handling*/
4259 u32 led_5210;
4260
4261 ATH5K_TRACE(ah->ah_sc);
4262
4263 /*Reset led status*/
4264 if (ah->ah_version != AR5K_AR5210)
4265 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
4266 AR5K_PCICFG_LEDMODE | AR5K_PCICFG_LED);
4267 else
4268 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED);
4269
4270 /*
4271 * Some blinking values, define at your wish
4272 */
4273 switch (state) {
4274 case AR5K_LED_SCAN:
4275 case AR5K_LED_AUTH:
4276 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND;
4277 led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL;
4278 break;
4279
4280 case AR5K_LED_INIT:
4281 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE;
4282 led_5210 = AR5K_PCICFG_LED_PEND;
4283 break;
4284
4285 case AR5K_LED_ASSOC:
4286 case AR5K_LED_RUN:
4287 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC;
4288 led_5210 = AR5K_PCICFG_LED_ASSOC;
4289 break;
4290
4291 default:
4292 led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE;
4293 led_5210 = AR5K_PCICFG_LED_PEND;
4294 break;
4295 }
4296
4297 /*Write new status to the register*/
4298 if (ah->ah_version != AR5K_AR5210)
4299 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led);
4300 else
4301 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210);
4302}
4303
4304/*
4305 * Set GPIO outputs
4306 */
4307int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
4308{
4309 ATH5K_TRACE(ah->ah_sc);
4310 if (gpio > AR5K_NUM_GPIO)
4311 return -EINVAL;
4312
4313 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~
4314 AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
4315
4316 return 0;
4317}
4318
4319/*
4320 * Set GPIO inputs
4321 */
4322int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
4323{
4324 ATH5K_TRACE(ah->ah_sc);
4325 if (gpio > AR5K_NUM_GPIO)
4326 return -EINVAL;
4327
4328 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~
4329 AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
4330
4331 return 0;
4332}
4333
4334/*
4335 * Get GPIO state
4336 */
4337u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
4338{
4339 ATH5K_TRACE(ah->ah_sc);
4340 if (gpio > AR5K_NUM_GPIO)
4341 return 0xffffffff;
4342
4343 /* GPIO input magic */
4344 return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
4345 0x1;
4346}
4347
4348/*
4349 * Set GPIO state
4350 */
4351int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
4352{
4353 u32 data;
4354 ATH5K_TRACE(ah->ah_sc);
4355
4356 if (gpio > AR5K_NUM_GPIO)
4357 return -EINVAL;
4358
4359 /* GPIO output magic */
4360 data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
4361
4362 data &= ~(1 << gpio);
4363 data |= (val & 1) << gpio;
4364
4365 ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
4366
4367 return 0;
4368}
4369
4370/*
4371 * Initialize the GPIO interrupt (RFKill switch)
4372 */
4373void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
4374 u32 interrupt_level)
4375{
4376 u32 data;
4377
4378 ATH5K_TRACE(ah->ah_sc);
4379 if (gpio > AR5K_NUM_GPIO)
4380 return;
4381
4382 /*
4383 * Set the GPIO interrupt
4384 */
4385 data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
4386 ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
4387 AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
4388 (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
4389
4390 ath5k_hw_reg_write(ah, interrupt_level ? data :
4391 (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
4392
4393 ah->ah_imr |= AR5K_IMR_GPIO;
4394
4395 /* Enable GPIO interrupts */
4396 AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
4397}
4398
4399
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004400
4401
4402/****************\
4403 Misc functions
4404\****************/
4405
4406int ath5k_hw_get_capability(struct ath5k_hw *ah,
4407 enum ath5k_capability_type cap_type,
4408 u32 capability, u32 *result)
4409{
4410 ATH5K_TRACE(ah->ah_sc);
4411
4412 switch (cap_type) {
4413 case AR5K_CAP_NUM_TXQUEUES:
4414 if (result) {
4415 if (ah->ah_version == AR5K_AR5210)
4416 *result = AR5K_NUM_TX_QUEUES_NOQCU;
4417 else
4418 *result = AR5K_NUM_TX_QUEUES;
4419 goto yes;
4420 }
4421 case AR5K_CAP_VEOL:
4422 goto yes;
4423 case AR5K_CAP_COMPRESSION:
4424 if (ah->ah_version == AR5K_AR5212)
4425 goto yes;
4426 else
4427 goto no;
4428 case AR5K_CAP_BURST:
4429 goto yes;
4430 case AR5K_CAP_TPC:
4431 goto yes;
4432 case AR5K_CAP_BSSIDMASK:
4433 if (ah->ah_version == AR5K_AR5212)
4434 goto yes;
4435 else
4436 goto no;
4437 case AR5K_CAP_XR:
4438 if (ah->ah_version == AR5K_AR5212)
4439 goto yes;
4440 else
4441 goto no;
4442 default:
4443 goto no;
4444 }
4445
4446no:
4447 return -EINVAL;
4448yes:
4449 return 0;
4450}
4451
4452static int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
4453 u16 assoc_id)
4454{
4455 ATH5K_TRACE(ah->ah_sc);
4456
4457 if (ah->ah_version == AR5K_AR5210) {
4458 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
4459 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
4460 return 0;
4461 }
4462
4463 return -EIO;
4464}
4465
4466static int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
4467{
4468 ATH5K_TRACE(ah->ah_sc);
4469
4470 if (ah->ah_version == AR5K_AR5210) {
4471 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
4472 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
4473 return 0;
4474 }
4475
4476 return -EIO;
4477}