blob: 42ef41ed5d18938d3637de04f073f59ece305729 [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];
142 init_val = ath5k_hw_reg_read(ah, cur_reg);
143
144 for (i = 0; i < 256; i++) {
145 var_pattern = i << 16 | i;
146 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
147 cur_val = ath5k_hw_reg_read(ah, cur_reg);
148
149 if (cur_val != var_pattern) {
150 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
151 return -EAGAIN;
152 }
153
154 /* Found on ndiswrapper dumps */
155 var_pattern = 0x0039080f;
156 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
157 }
158
159 for (i = 0; i < 4; i++) {
160 var_pattern = static_pattern[i];
161 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
162 cur_val = ath5k_hw_reg_read(ah, cur_reg);
163
164 if (cur_val != var_pattern) {
165 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
166 return -EAGAIN;
167 }
168
169 /* Found on ndiswrapper dumps */
170 var_pattern = 0x003b080f;
171 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
172 }
173 }
174
175 return 0;
176
177}
178
179/*
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200180 * Check if the device is supported and initialize the needed structs
181 */
182struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
183{
184 struct ath5k_hw *ah;
Nick Kossifidis194828a2008-04-16 18:49:02 +0300185 struct pci_dev *pdev = sc->pdev;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200186 u8 mac[ETH_ALEN];
187 int ret;
188 u32 srev;
189
190 /*If we passed the test malloc a ath5k_hw struct*/
191 ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
192 if (ah == NULL) {
193 ret = -ENOMEM;
194 ATH5K_ERR(sc, "out of memory\n");
195 goto err;
196 }
197
198 ah->ah_sc = sc;
199 ah->ah_iobase = sc->iobase;
200
201 /*
202 * HW information
203 */
204
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200205 ah->ah_op_mode = IEEE80211_IF_TYPE_STA;
206 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
207 ah->ah_turbo = false;
208 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
209 ah->ah_imr = 0;
210 ah->ah_atim_window = 0;
211 ah->ah_aifs = AR5K_TUNE_AIFS;
212 ah->ah_cw_min = AR5K_TUNE_CWMIN;
213 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
214 ah->ah_software_retry = false;
215 ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
216
217 /*
218 * Set the mac revision based on the pci id
219 */
220 ah->ah_version = mac_version;
221
222 /*Fill the ath5k_hw struct with the needed functions*/
223 if (ah->ah_version == AR5K_AR5212)
224 ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
225 else if (ah->ah_version == AR5K_AR5211)
226 ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
227
228 if (ah->ah_version == AR5K_AR5212) {
229 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
230 ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
231 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
232 } else {
233 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
234 ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
235 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
236 }
237
238 if (ah->ah_version == AR5K_AR5212)
Bruno Randolf19fd6e52008-03-05 18:35:23 +0900239 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200240 else if (ah->ah_version <= AR5K_AR5211)
Bruno Randolf19fd6e52008-03-05 18:35:23 +0900241 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200242
243 /* Bring device out of sleep and reset it's units */
244 ret = ath5k_hw_nic_wakeup(ah, AR5K_INIT_MODE, true);
245 if (ret)
246 goto err_free;
247
248 /* Get MAC, PHY and RADIO revisions */
249 srev = ath5k_hw_reg_read(ah, AR5K_SREV);
250 ah->ah_mac_srev = srev;
251 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
252 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
253 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
254 0xffffffff;
255 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
256 CHANNEL_5GHZ);
257
258 if (ah->ah_version == AR5K_AR5210)
259 ah->ah_radio_2ghz_revision = 0;
260 else
261 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
262 CHANNEL_2GHZ);
263
264 /* Return on unsuported chips (unsupported eeprom etc) */
Nick Kossifidis194828a2008-04-16 18:49:02 +0300265 if ((srev >= AR5K_SREV_VER_AR5416) &&
266 (srev < AR5K_SREV_VER_AR2425)) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200267 ATH5K_ERR(sc, "Device not yet supported.\n");
268 ret = -ENODEV;
269 goto err_free;
Nick Kossifidis194828a2008-04-16 18:49:02 +0300270 } else if (srev == AR5K_SREV_VER_AR2425) {
271 ATH5K_WARN(sc, "Support for RF2425 is under development.\n");
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200272 }
273
274 /* Identify single chip solutions */
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300275 if (((srev <= AR5K_SREV_VER_AR5414) &&
276 (srev >= AR5K_SREV_VER_AR2413)) ||
277 (srev == AR5K_SREV_VER_AR2425)) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200278 ah->ah_single_chip = true;
279 } else {
280 ah->ah_single_chip = false;
281 }
282
283 /* Single chip radio */
284 if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision)
285 ah->ah_radio_2ghz_revision = 0;
286
287 /* Identify the radio chip*/
288 if (ah->ah_version == AR5K_AR5210) {
289 ah->ah_radio = AR5K_RF5110;
290 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
291 ah->ah_radio = AR5K_RF5111;
Nick Kossifidis0af22562008-02-28 14:49:05 -0500292 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
293 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
294
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200295 ah->ah_radio = AR5K_RF5112;
Nick Kossifidis0af22562008-02-28 14:49:05 -0500296
297 if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
298 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
299 } else {
300 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
301 }
302
303 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
304 ah->ah_radio = AR5K_RF2413;
305 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300306 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200307 ah->ah_radio = AR5K_RF5413;
Nick Kossifidisd1d8f442008-04-21 21:28:24 +0300308 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
309 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
Nick Kossifidis0af22562008-02-28 14:49:05 -0500310
Nick Kossifidisd1d8f442008-04-21 21:28:24 +0300311 /* AR5424 */
312 if (srev >= AR5K_SREV_VER_AR5424) {
313 ah->ah_radio = AR5K_RF5413;
Nick Kossifidis0af22562008-02-28 14:49:05 -0500314 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424;
Nick Kossifidisd1d8f442008-04-21 21:28:24 +0300315 /* AR2424 */
316 } else {
317 ah->ah_radio = AR5K_RF2413; /* For testing */
Nick Kossifidis0af22562008-02-28 14:49:05 -0500318 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
Nick Kossifidisd1d8f442008-04-21 21:28:24 +0300319 }
320
Nick Kossifidis194828a2008-04-16 18:49:02 +0300321 /*
322 * Register returns 0x4 for radio revision
323 * so ath5k_hw_radio_revision doesn't parse the value
324 * correctly. For now we are based on mac's srev to
325 * identify RF2425 radio.
326 */
327 } else if (srev == AR5K_SREV_VER_AR2425) {
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300328 ah->ah_radio = AR5K_RF2425;
329 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200330 }
331
332 ah->ah_phy = AR5K_PHY(0);
333
334 /*
Nick Kossifidis194828a2008-04-16 18:49:02 +0300335 * Identify AR5212-based PCI-E cards
336 * And write some initial settings.
337 *
338 * (doing a "strings" on ndis driver
339 * -ar5211.sys- reveals the following
340 * pci-e related functions:
341 *
342 * pcieClockReq
343 * pcieRxErrNotify
344 * pcieL1SKPEnable
345 * pcieAspm
346 * pcieDisableAspmOnRfWake
347 * pciePowerSaveEnable
348 *
349 * I guess these point to ClockReq but
350 * i'm not sure.)
351 */
352 if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
353 ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
354 ath5k_hw_reg_write(ah, 0x24924924, 0x4080);
355 ath5k_hw_reg_write(ah, 0x28000039, 0x4080);
356 ath5k_hw_reg_write(ah, 0x53160824, 0x4080);
357 ath5k_hw_reg_write(ah, 0xe5980579, 0x4080);
358 ath5k_hw_reg_write(ah, 0x001defff, 0x4080);
359 ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080);
360 ath5k_hw_reg_write(ah, 0xbe105554, 0x4080);
361 ath5k_hw_reg_write(ah, 0x000e3007, 0x4080);
362 ath5k_hw_reg_write(ah, 0x00000000, 0x4084);
363 }
364
365 /*
366 * POST
367 */
368 ret = ath5k_hw_post(ah);
369 if (ret)
370 goto err_free;
371
372 /*
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200373 * Get card capabilities, values, ...
374 */
375
376 ret = ath5k_eeprom_init(ah);
377 if (ret) {
378 ATH5K_ERR(sc, "unable to init EEPROM\n");
379 goto err_free;
380 }
381
382 /* Get misc capabilities */
383 ret = ath5k_hw_get_capabilities(ah);
384 if (ret) {
385 ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
386 sc->pdev->device);
387 goto err_free;
388 }
389
390 /* Get MAC address */
391 ret = ath5k_eeprom_read_mac(ah, mac);
392 if (ret) {
393 ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
394 sc->pdev->device);
395 goto err_free;
396 }
397
398 ath5k_hw_set_lladdr(ah, mac);
399 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
400 memset(ah->ah_bssid, 0xff, ETH_ALEN);
401 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
402 ath5k_hw_set_opmode(ah);
403
404 ath5k_hw_set_rfgain_opt(ah);
405
406 return ah;
407err_free:
408 kfree(ah);
409err:
410 return ERR_PTR(ret);
411}
412
413/*
414 * Bring up MAC + PHY Chips
415 */
416static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
417{
Nick Kossifidis56c90542008-02-28 16:20:52 -0500418 struct pci_dev *pdev = ah->ah_sc->pdev;
419 u32 turbo, mode, clock, bus_flags;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200420 int ret;
421
422 turbo = 0;
423 mode = 0;
424 clock = 0;
425
426 ATH5K_TRACE(ah->ah_sc);
427
428 /* Wakeup the device */
429 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
430 if (ret) {
431 ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
432 return ret;
433 }
434
435 if (ah->ah_version != AR5K_AR5210) {
436 /*
437 * Get channel mode flags
438 */
439
440 if (ah->ah_radio >= AR5K_RF5112) {
441 mode = AR5K_PHY_MODE_RAD_RF5112;
442 clock = AR5K_PHY_PLL_RF5112;
443 } else {
444 mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/
445 clock = AR5K_PHY_PLL_RF5111; /*Zero*/
446 }
447
448 if (flags & CHANNEL_2GHZ) {
449 mode |= AR5K_PHY_MODE_FREQ_2GHZ;
450 clock |= AR5K_PHY_PLL_44MHZ;
451
452 if (flags & CHANNEL_CCK) {
453 mode |= AR5K_PHY_MODE_MOD_CCK;
454 } else if (flags & CHANNEL_OFDM) {
455 /* XXX Dynamic OFDM/CCK is not supported by the
456 * AR5211 so we set MOD_OFDM for plain g (no
457 * CCK headers) operation. We need to test
458 * this, 5211 might support ofdm-only g after
459 * all, there are also initial register values
460 * in the code for g mode (see initvals.c). */
461 if (ah->ah_version == AR5K_AR5211)
462 mode |= AR5K_PHY_MODE_MOD_OFDM;
463 else
464 mode |= AR5K_PHY_MODE_MOD_DYN;
465 } else {
466 ATH5K_ERR(ah->ah_sc,
467 "invalid radio modulation mode\n");
468 return -EINVAL;
469 }
470 } else if (flags & CHANNEL_5GHZ) {
471 mode |= AR5K_PHY_MODE_FREQ_5GHZ;
472 clock |= AR5K_PHY_PLL_40MHZ;
473
474 if (flags & CHANNEL_OFDM)
475 mode |= AR5K_PHY_MODE_MOD_OFDM;
476 else {
477 ATH5K_ERR(ah->ah_sc,
478 "invalid radio modulation mode\n");
479 return -EINVAL;
480 }
481 } else {
482 ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
483 return -EINVAL;
484 }
485
486 if (flags & CHANNEL_TURBO)
487 turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
488 } else { /* Reset the device */
489
490 /* ...enable Atheros turbo mode if requested */
491 if (flags & CHANNEL_TURBO)
492 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
493 AR5K_PHY_TURBO);
494 }
495
Nick Kossifidis56c90542008-02-28 16:20:52 -0500496 /* reseting PCI on PCI-E cards results card to hang
497 * and always return 0xffff... so we ingore that flag
498 * for PCI-E cards */
499 bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
500
501 /* Reset chipset */
502 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
503 AR5K_RESET_CTL_BASEBAND | bus_flags);
504 if (ret) {
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300505 ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200506 return -EIO;
507 }
508
509 if (ah->ah_version == AR5K_AR5210)
510 udelay(2300);
511
512 /* ...wakeup again!*/
513 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
514 if (ret) {
515 ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
516 return ret;
517 }
518
519 /* ...final warm reset */
520 if (ath5k_hw_nic_reset(ah, 0)) {
521 ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
522 return -EIO;
523 }
524
525 if (ah->ah_version != AR5K_AR5210) {
526 /* ...set the PHY operating mode */
527 ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
528 udelay(300);
529
530 ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
531 ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
532 }
533
534 return 0;
535}
536
537/*
538 * Get the rate table for a specific operation mode
539 */
540const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah,
541 unsigned int mode)
542{
543 ATH5K_TRACE(ah->ah_sc);
544
545 if (!test_bit(mode, ah->ah_capabilities.cap_mode))
546 return NULL;
547
548 /* Get rate tables */
549 switch (mode) {
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500550 case AR5K_MODE_11A:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200551 return &ath5k_rt_11a;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500552 case AR5K_MODE_11A_TURBO:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200553 return &ath5k_rt_turbo;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500554 case AR5K_MODE_11B:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200555 return &ath5k_rt_11b;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500556 case AR5K_MODE_11G:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200557 return &ath5k_rt_11g;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500558 case AR5K_MODE_11G_TURBO:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200559 return &ath5k_rt_xr;
560 }
561
562 return NULL;
563}
564
565/*
566 * Free the ath5k_hw struct
567 */
568void ath5k_hw_detach(struct ath5k_hw *ah)
569{
570 ATH5K_TRACE(ah->ah_sc);
571
Pavel Roskinf50e4a82008-03-12 16:13:31 -0400572 __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
573
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200574 if (ah->ah_rf_banks != NULL)
575 kfree(ah->ah_rf_banks);
576
577 /* assume interrupts are down */
578 kfree(ah);
579}
580
581/****************************\
582 Reset function and helpers
583\****************************/
584
585/**
586 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
587 *
588 * @ah: the &struct ath5k_hw
589 * @channel: the currently set channel upon reset
590 *
591 * Write the OFDM timings for the AR5212 upon reset. This is a helper for
592 * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
593 * depending on the bandwidth of the channel.
594 *
595 */
596static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
597 struct ieee80211_channel *channel)
598{
599 /* Get exponent and mantissa and set it */
600 u32 coef_scaled, coef_exp, coef_man,
601 ds_coef_exp, ds_coef_man, clock;
602
603 if (!(ah->ah_version == AR5K_AR5212) ||
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500604 !(channel->hw_value & CHANNEL_OFDM))
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200605 BUG();
606
607 /* Seems there are two PLLs, one for baseband sampling and one
608 * for tuning. Tuning basebands are 40 MHz or 80MHz when in
609 * turbo. */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500610 clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200611 coef_scaled = ((5 * (clock << 24)) / 2) /
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500612 channel->center_freq;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200613
614 for (coef_exp = 31; coef_exp > 0; coef_exp--)
615 if ((coef_scaled >> coef_exp) & 0x1)
616 break;
617
618 if (!coef_exp)
619 return -EINVAL;
620
621 coef_exp = 14 - (coef_exp - 24);
622 coef_man = coef_scaled +
623 (1 << (24 - coef_exp - 1));
624 ds_coef_man = coef_man >> (24 - coef_exp);
625 ds_coef_exp = coef_exp - 16;
626
627 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
628 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
629 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
630 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
631
632 return 0;
633}
634
635/**
636 * ath5k_hw_write_rate_duration - set rate duration during hw resets
637 *
638 * @ah: the &struct ath5k_hw
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500639 * @mode: one of enum ath5k_driver_mode
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200640 *
641 * Write the rate duration table for the current mode upon hw reset. This
642 * is a helper for ath5k_hw_reset(). It seems all this is doing is setting
643 * an ACK timeout for the hardware for the current mode for each rate. The
644 * rates which are capable of short preamble (802.11b rates 2Mbps, 5.5Mbps,
645 * and 11Mbps) have another register for the short preamble ACK timeout
646 * calculation.
647 *
648 */
649static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500650 unsigned int mode)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200651{
652 struct ath5k_softc *sc = ah->ah_sc;
653 const struct ath5k_rate_table *rt;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500654 struct ieee80211_rate srate = {};
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200655 unsigned int i;
656
657 /* Get rate table for the current operating mode */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500658 rt = ath5k_hw_get_rate_table(ah, mode);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200659
660 /* Write rate duration table */
661 for (i = 0; i < rt->rate_count; i++) {
662 const struct ath5k_rate *rate, *control_rate;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500663
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200664 u32 reg;
665 u16 tx_time;
666
667 rate = &rt->rates[i];
668 control_rate = &rt->rates[rate->control_rate];
669
670 /* Set ACK timeout */
671 reg = AR5K_RATE_DUR(rate->rate_code);
672
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500673 srate.bitrate = control_rate->rate_kbps/100;
674
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200675 /* An ACK frame consists of 10 bytes. If you add the FCS,
676 * which ieee80211_generic_frame_duration() adds,
677 * its 14 bytes. Note we use the control rate and not the
678 * actual rate for this rate. See mac80211 tx.c
679 * ieee80211_duration() for a brief description of
680 * what rate we should choose to TX ACKs. */
Pavel Roskin38c07b42008-02-26 17:59:14 -0500681 tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
682 sc->vif, 10, &srate));
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200683
684 ath5k_hw_reg_write(ah, tx_time, reg);
685
686 if (!HAS_SHPREAMBLE(i))
687 continue;
688
689 /*
690 * We're not distinguishing short preamble here,
691 * This is true, all we'll get is a longer value here
692 * which is not necessarilly bad. We could use
693 * export ieee80211_frame_duration() but that needs to be
694 * fixed first to be properly used by mac802111 drivers:
695 *
696 * - remove erp stuff and let the routine figure ofdm
697 * erp rates
698 * - remove passing argument ieee80211_local as
699 * drivers don't have access to it
700 * - move drivers using ieee80211_generic_frame_duration()
701 * to this
702 */
703 ath5k_hw_reg_write(ah, tx_time,
704 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
705 }
706}
707
708/*
709 * Main reset function
710 */
711int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
712 struct ieee80211_channel *channel, bool change_channel)
713{
714 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
Nick Kossifidis56c90542008-02-28 16:20:52 -0500715 struct pci_dev *pdev = ah->ah_sc->pdev;
716 u32 data, s_seq, s_ant, s_led[3], dma_size;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500717 unsigned int i, mode, freq, ee_mode, ant[2];
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200718 int ret;
719
720 ATH5K_TRACE(ah->ah_sc);
721
722 s_seq = 0;
723 s_ant = 0;
724 ee_mode = 0;
725 freq = 0;
726 mode = 0;
727
728 /*
729 * Save some registers before a reset
730 */
731 /*DCU/Antenna selection not available on 5210*/
732 if (ah->ah_version != AR5K_AR5210) {
Joe Perchese9010e22008-03-07 14:21:16 -0800733 if (change_channel) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200734 /* Seq number for queue 0 -do this for all queues ? */
735 s_seq = ath5k_hw_reg_read(ah,
736 AR5K_QUEUE_DFS_SEQNUM(0));
737 /*Default antenna*/
738 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
739 }
740 }
741
742 /*GPIOs*/
743 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
744 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
745 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
746
Joe Perchese9010e22008-03-07 14:21:16 -0800747 if (change_channel && ah->ah_rf_banks != NULL)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200748 ath5k_hw_get_rf_gain(ah);
749
750
751 /*Wakeup the device*/
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500752 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200753 if (ret)
754 return ret;
755
756 /*
757 * Initialize operating mode
758 */
759 ah->ah_op_mode = op_mode;
760
761 /*
762 * 5111/5112 Settings
763 * 5210 only comes with RF5110
764 */
765 if (ah->ah_version != AR5K_AR5210) {
766 if (ah->ah_radio != AR5K_RF5111 &&
767 ah->ah_radio != AR5K_RF5112 &&
Nick Kossifidis903b4742008-02-28 14:50:50 -0500768 ah->ah_radio != AR5K_RF5413 &&
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300769 ah->ah_radio != AR5K_RF2413 &&
770 ah->ah_radio != AR5K_RF2425) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200771 ATH5K_ERR(ah->ah_sc,
772 "invalid phy radio: %u\n", ah->ah_radio);
773 return -EINVAL;
774 }
775
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500776 switch (channel->hw_value & CHANNEL_MODES) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200777 case CHANNEL_A:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500778 mode = AR5K_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200779 freq = AR5K_INI_RFGAIN_5GHZ;
780 ee_mode = AR5K_EEPROM_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200781 break;
782 case CHANNEL_G:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500783 mode = AR5K_MODE_11G;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200784 freq = AR5K_INI_RFGAIN_2GHZ;
785 ee_mode = AR5K_EEPROM_MODE_11G;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200786 break;
787 case CHANNEL_B:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500788 mode = AR5K_MODE_11B;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200789 freq = AR5K_INI_RFGAIN_2GHZ;
790 ee_mode = AR5K_EEPROM_MODE_11B;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200791 break;
792 case CHANNEL_T:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500793 mode = AR5K_MODE_11A_TURBO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200794 freq = AR5K_INI_RFGAIN_5GHZ;
795 ee_mode = AR5K_EEPROM_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200796 break;
797 /*Is this ok on 5211 too ?*/
798 case CHANNEL_TG:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500799 mode = AR5K_MODE_11G_TURBO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200800 freq = AR5K_INI_RFGAIN_2GHZ;
801 ee_mode = AR5K_EEPROM_MODE_11G;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200802 break;
803 case CHANNEL_XR:
804 if (ah->ah_version == AR5K_AR5211) {
805 ATH5K_ERR(ah->ah_sc,
806 "XR mode not available on 5211");
807 return -EINVAL;
808 }
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500809 mode = AR5K_MODE_XR;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200810 freq = AR5K_INI_RFGAIN_5GHZ;
811 ee_mode = AR5K_EEPROM_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200812 break;
813 default:
814 ATH5K_ERR(ah->ah_sc,
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500815 "invalid channel: %d\n", channel->center_freq);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200816 return -EINVAL;
817 }
818
819 /* PHY access enable */
820 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
821
822 }
823
824 ret = ath5k_hw_write_initvals(ah, mode, change_channel);
825 if (ret)
826 return ret;
827
828 /*
829 * 5211/5212 Specific
830 */
831 if (ah->ah_version != AR5K_AR5210) {
832 /*
833 * Write initial RF gain settings
834 * This should work for both 5111/5112
835 */
836 ret = ath5k_hw_rfgain(ah, freq);
837 if (ret)
838 return ret;
839
840 mdelay(1);
841
842 /*
843 * Write some more initial register settings
844 */
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500845 if (ah->ah_version == AR5K_AR5212) {
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300846 ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200847
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500848 if (channel->hw_value == CHANNEL_G)
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500849 if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
850 ath5k_hw_reg_write(ah, 0x00f80d80,
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300851 0x994c);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500852 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
853 ath5k_hw_reg_write(ah, 0x00380140,
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300854 0x994c);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500855 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
856 ath5k_hw_reg_write(ah, 0x00fc0ec0,
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300857 0x994c);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500858 else /* 2425 */
859 ath5k_hw_reg_write(ah, 0x00fc0fc0,
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300860 0x994c);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200861 else
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300862 ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200863
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200864 ath5k_hw_reg_write(ah, 0x000009b5, 0xa228);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300865 ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200866 ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
867 ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
868 }
869
870 /* Fix for first revision of the RF5112 RF chipset */
871 if (ah->ah_radio >= AR5K_RF5112 &&
872 ah->ah_radio_5ghz_revision <
873 AR5K_SREV_RAD_5112A) {
874 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
875 AR5K_PHY_CCKTXCTL);
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500876 if (channel->hw_value & CHANNEL_5GHZ)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200877 data = 0xffb81020;
878 else
879 data = 0xffb80d20;
880 ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
881 }
882
883 /*
884 * Set TX power (FIXME)
885 */
886 ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER);
887 if (ret)
888 return ret;
889
Luis R. Rodriguez132127e2008-01-04 02:21:05 -0500890 /* Write rate duration table only on AR5212 and if
891 * virtual interface has already been brought up
892 * XXX: rethink this after new mode changes to
893 * mac80211 are integrated */
894 if (ah->ah_version == AR5K_AR5212 &&
895 ah->ah_sc->vif != NULL)
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500896 ath5k_hw_write_rate_duration(ah, mode);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200897
898 /*
899 * Write RF registers
900 * TODO:Does this work on 5211 (5111) ?
901 */
902 ret = ath5k_hw_rfregs(ah, channel, mode);
903 if (ret)
904 return ret;
905
906 /*
907 * Configure additional registers
908 */
909
910 /* Write OFDM timings on 5212*/
911 if (ah->ah_version == AR5K_AR5212 &&
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500912 channel->hw_value & CHANNEL_OFDM) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200913 ret = ath5k_hw_write_ofdm_timings(ah, channel);
914 if (ret)
915 return ret;
916 }
917
918 /*Enable/disable 802.11b mode on 5111
919 (enable 2111 frequency converter + CCK)*/
920 if (ah->ah_radio == AR5K_RF5111) {
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500921 if (mode == AR5K_MODE_11B)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200922 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
923 AR5K_TXCFG_B_MODE);
924 else
925 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
926 AR5K_TXCFG_B_MODE);
927 }
928
929 /*
930 * Set channel and calibrate the PHY
931 */
932 ret = ath5k_hw_channel(ah, channel);
933 if (ret)
934 return ret;
935
936 /* Set antenna mode */
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300937 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200938 ah->ah_antenna[ee_mode][0], 0xfffffc06);
939
940 /*
941 * In case a fixed antenna was set as default
942 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
943 * registers.
944 */
945 if (s_ant != 0){
946 if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
947 ant[0] = ant[1] = AR5K_ANT_FIXED_A;
948 else /* 2 - Aux */
949 ant[0] = ant[1] = AR5K_ANT_FIXED_B;
950 } else {
951 ant[0] = AR5K_ANT_FIXED_A;
952 ant[1] = AR5K_ANT_FIXED_B;
953 }
954
955 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
956 AR5K_PHY_ANT_SWITCH_TABLE_0);
957 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
958 AR5K_PHY_ANT_SWITCH_TABLE_1);
959
960 /* Commit values from EEPROM */
961 if (ah->ah_radio == AR5K_RF5111)
962 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
963 AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
964
965 ath5k_hw_reg_write(ah,
966 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300967 AR5K_PHY_NFTHRES);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200968
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300969 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200970 (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
971 0xffffc07f);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300972 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200973 (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
974 0xfffc0fff);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300975 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200976 (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
977 ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
978 0xffff0000);
979
980 ath5k_hw_reg_write(ah,
981 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
982 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
983 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300984 (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200985
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300986 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200987 ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300988 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200989 (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +0300990 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200991
992 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
993 AR5K_PHY_IQ_CORR_ENABLE |
994 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
995 ee->ee_q_cal[ee_mode]);
996
997 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
998 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
999 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
1000 ee->ee_margin_tx_rx[ee_mode]);
1001
1002 } else {
1003 mdelay(1);
1004 /* Disable phy and wait */
1005 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
1006 mdelay(1);
1007 }
1008
1009 /*
1010 * Restore saved values
1011 */
1012 /*DCU/Antenna selection not available on 5210*/
1013 if (ah->ah_version != AR5K_AR5210) {
1014 ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
1015 ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
1016 }
1017 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
1018 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
1019 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
1020
1021 /*
1022 * Misc
1023 */
1024 /* XXX: add ah->aid once mac80211 gives this to us */
1025 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
1026
1027 ath5k_hw_set_opmode(ah);
1028 /*PISR/SISR Not available on 5210*/
1029 if (ah->ah_version != AR5K_AR5210) {
1030 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
1031 /* If we later allow tuning for this, store into sc structure */
1032 data = AR5K_TUNE_RSSI_THRES |
1033 AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
1034 ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
1035 }
1036
1037 /*
1038 * Set Rx/Tx DMA Configuration
Nick Kossifidis56c90542008-02-28 16:20:52 -05001039 *
1040 * Set maximum DMA size (512) except for PCI-E cards since
1041 * it causes rx overruns and tx errors (tested on 5424 but since
1042 * rx overruns also occur on 5416/5418 with madwifi we set 128
1043 * for all PCI-E cards to be safe).
1044 *
1045 * In dumps this is 128 for allchips.
1046 *
1047 * XXX: need to check 5210 for this
1048 * TODO: Check out tx triger level, it's always 64 on dumps but I
1049 * guess we can tweak it and see how it goes ;-)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001050 */
Nick Kossifidis56c90542008-02-28 16:20:52 -05001051 dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001052 if (ah->ah_version != AR5K_AR5210) {
Nick Kossifidis56c90542008-02-28 16:20:52 -05001053 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
1054 AR5K_TXCFG_SDMAMR, dma_size);
1055 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
1056 AR5K_RXCFG_SDMAMW, dma_size);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001057 }
1058
1059 /*
1060 * Enable the PHY and wait until completion
1061 */
1062 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
1063
1064 /*
1065 * 5111/5112 Specific
1066 */
1067 if (ah->ah_version != AR5K_AR5210) {
1068 data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
1069 AR5K_PHY_RX_DELAY_M;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001070 data = (channel->hw_value & CHANNEL_CCK) ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001071 ((data << 2) / 22) : (data / 10);
1072
1073 udelay(100 + data);
1074 } else {
1075 mdelay(1);
1076 }
1077
1078 /*
1079 * Enable calibration and wait until completion
1080 */
1081 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1082 AR5K_PHY_AGCCTL_CAL);
1083
1084 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1085 AR5K_PHY_AGCCTL_CAL, 0, false)) {
1086 ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001087 channel->center_freq);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001088 return -EAGAIN;
1089 }
1090
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001091 ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001092 if (ret)
1093 return ret;
1094
1095 ah->ah_calibration = false;
1096
1097 /* A and G modes can use QAM modulation which requires enabling
1098 * I and Q calibration. Don't bother in B mode. */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001099 if (!(mode == AR5K_MODE_11B)) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001100 ah->ah_calibration = true;
1101 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
1102 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
1103 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
1104 AR5K_PHY_IQ_RUN);
1105 }
1106
1107 /*
1108 * Reset queues and start beacon timers at the end of the reset routine
1109 */
1110 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
1111 /*No QCU on 5210*/
1112 if (ah->ah_version != AR5K_AR5210)
1113 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
1114
1115 ret = ath5k_hw_reset_tx_queue(ah, i);
1116 if (ret) {
1117 ATH5K_ERR(ah->ah_sc,
1118 "failed to reset TX queue #%d\n", i);
1119 return ret;
1120 }
1121 }
1122
1123 /* Pre-enable interrupts on 5211/5212*/
1124 if (ah->ah_version != AR5K_AR5210)
1125 ath5k_hw_set_intr(ah, AR5K_INT_RX | AR5K_INT_TX |
1126 AR5K_INT_FATAL);
1127
1128 /*
1129 * Set RF kill flags if supported by the device (read from the EEPROM)
1130 * Disable gpio_intr for now since it results system hang.
1131 * TODO: Handle this in ath5k_intr
1132 */
1133#if 0
1134 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
1135 ath5k_hw_set_gpio_input(ah, 0);
1136 ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
1137 if (ah->ah_gpio[0] == 0)
1138 ath5k_hw_set_gpio_intr(ah, 0, 1);
1139 else
1140 ath5k_hw_set_gpio_intr(ah, 0, 0);
1141 }
1142#endif
1143
1144 /*
1145 * Set the 32MHz reference clock on 5212 phy clock sleep register
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05001146 *
1147 * TODO: Find out how to switch to external 32Khz clock to save power
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001148 */
1149 if (ah->ah_version == AR5K_AR5212) {
1150 ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
1151 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
1152 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
1153 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
1154 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
Nick Kossifidis903b4742008-02-28 14:50:50 -05001155 ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001156 }
1157
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05001158 if (ah->ah_version == AR5K_AR5212) {
1159 ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
1160 ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
1161 ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
1162 if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413)
1163 ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
1164 }
1165
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001166 /*
1167 * Disable beacons and reset the register
1168 */
1169 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
1170 AR5K_BEACON_RESET_TSF);
1171
1172 return 0;
1173}
1174
1175/*
1176 * Reset chipset
1177 */
1178static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
1179{
1180 int ret;
1181 u32 mask = val ? val : ~0U;
1182
1183 ATH5K_TRACE(ah->ah_sc);
1184
1185 /* Read-and-clear RX Descriptor Pointer*/
1186 ath5k_hw_reg_read(ah, AR5K_RXDP);
1187
1188 /*
1189 * Reset the device and wait until success
1190 */
1191 ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
1192
1193 /* Wait at least 128 PCI clocks */
1194 udelay(15);
1195
1196 if (ah->ah_version == AR5K_AR5210) {
1197 val &= AR5K_RESET_CTL_CHIP;
1198 mask &= AR5K_RESET_CTL_CHIP;
1199 } else {
1200 val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
1201 mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
1202 }
1203
1204 ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
1205
1206 /*
1207 * Reset configuration register (for hw byte-swap). Note that this
1208 * is only set for big endian. We do the necessary magic in
1209 * AR5K_INIT_CFG.
1210 */
1211 if ((val & AR5K_RESET_CTL_PCU) == 0)
1212 ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
1213
1214 return ret;
1215}
1216
1217/*
1218 * Power management functions
1219 */
1220
1221/*
1222 * Sleep control
1223 */
1224int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
1225 bool set_chip, u16 sleep_duration)
1226{
1227 unsigned int i;
1228 u32 staid;
1229
1230 ATH5K_TRACE(ah->ah_sc);
1231 staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
1232
1233 switch (mode) {
1234 case AR5K_PM_AUTO:
1235 staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
1236 /* fallthrough */
1237 case AR5K_PM_NETWORK_SLEEP:
Joe Perchese9010e22008-03-07 14:21:16 -08001238 if (set_chip)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001239 ath5k_hw_reg_write(ah,
1240 AR5K_SLEEP_CTL_SLE | sleep_duration,
1241 AR5K_SLEEP_CTL);
1242
1243 staid |= AR5K_STA_ID1_PWR_SV;
1244 break;
1245
1246 case AR5K_PM_FULL_SLEEP:
Joe Perchese9010e22008-03-07 14:21:16 -08001247 if (set_chip)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001248 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
1249 AR5K_SLEEP_CTL);
1250
1251 staid |= AR5K_STA_ID1_PWR_SV;
1252 break;
1253
1254 case AR5K_PM_AWAKE:
Joe Perchese9010e22008-03-07 14:21:16 -08001255 if (!set_chip)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001256 goto commit;
1257
1258 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
1259 AR5K_SLEEP_CTL);
1260
1261 for (i = 5000; i > 0; i--) {
1262 /* Check if the chip did wake up */
1263 if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
1264 AR5K_PCICFG_SPWR_DN) == 0)
1265 break;
1266
1267 /* Wait a bit and retry */
1268 udelay(200);
1269 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
1270 AR5K_SLEEP_CTL);
1271 }
1272
1273 /* Fail if the chip didn't wake up */
1274 if (i <= 0)
1275 return -EIO;
1276
1277 staid &= ~AR5K_STA_ID1_PWR_SV;
1278 break;
1279
1280 default:
1281 return -EINVAL;
1282 }
1283
1284commit:
1285 ah->ah_power_mode = mode;
1286 ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
1287
1288 return 0;
1289}
1290
1291/***********************\
1292 DMA Related Functions
1293\***********************/
1294
1295/*
1296 * Receive functions
1297 */
1298
1299/*
1300 * Start DMA receive
1301 */
1302void ath5k_hw_start_rx(struct ath5k_hw *ah)
1303{
1304 ATH5K_TRACE(ah->ah_sc);
1305 ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
1306}
1307
1308/*
1309 * Stop DMA receive
1310 */
1311int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
1312{
1313 unsigned int i;
1314
1315 ATH5K_TRACE(ah->ah_sc);
1316 ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
1317
1318 /*
1319 * It may take some time to disable the DMA receive unit
1320 */
1321 for (i = 2000; i > 0 &&
1322 (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
1323 i--)
1324 udelay(10);
1325
1326 return i ? 0 : -EBUSY;
1327}
1328
1329/*
1330 * Get the address of the RX Descriptor
1331 */
1332u32 ath5k_hw_get_rx_buf(struct ath5k_hw *ah)
1333{
1334 return ath5k_hw_reg_read(ah, AR5K_RXDP);
1335}
1336
1337/*
1338 * Set the address of the RX Descriptor
1339 */
1340void ath5k_hw_put_rx_buf(struct ath5k_hw *ah, u32 phys_addr)
1341{
1342 ATH5K_TRACE(ah->ah_sc);
1343
1344 /*TODO:Shouldn't we check if RX is enabled first ?*/
1345 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
1346}
1347
1348/*
1349 * Transmit functions
1350 */
1351
1352/*
1353 * Start DMA transmit for a specific queue
1354 * (see also QCU/DCU functions)
1355 */
1356int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue)
1357{
1358 u32 tx_queue;
1359
1360 ATH5K_TRACE(ah->ah_sc);
1361 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1362
1363 /* Return if queue is declared inactive */
1364 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
1365 return -EIO;
1366
1367 if (ah->ah_version == AR5K_AR5210) {
1368 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
1369
1370 /*
1371 * Set the queue by type on 5210
1372 */
1373 switch (ah->ah_txq[queue].tqi_type) {
1374 case AR5K_TX_QUEUE_DATA:
1375 tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
1376 break;
1377 case AR5K_TX_QUEUE_BEACON:
1378 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
1379 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
1380 AR5K_BSR);
1381 break;
1382 case AR5K_TX_QUEUE_CAB:
1383 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
1384 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |
1385 AR5K_BCR_BDMAE, AR5K_BSR);
1386 break;
1387 default:
1388 return -EINVAL;
1389 }
1390 /* Start queue */
1391 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
1392 } else {
1393 /* Return if queue is disabled */
1394 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
1395 return -EIO;
1396
1397 /* Start queue */
1398 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);
1399 }
1400
1401 return 0;
1402}
1403
1404/*
1405 * Stop DMA transmit for a specific queue
1406 * (see also QCU/DCU functions)
1407 */
1408int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
1409{
1410 unsigned int i = 100;
1411 u32 tx_queue, pending;
1412
1413 ATH5K_TRACE(ah->ah_sc);
1414 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1415
1416 /* Return if queue is declared inactive */
1417 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
1418 return -EIO;
1419
1420 if (ah->ah_version == AR5K_AR5210) {
1421 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
1422
1423 /*
1424 * Set by queue type
1425 */
1426 switch (ah->ah_txq[queue].tqi_type) {
1427 case AR5K_TX_QUEUE_DATA:
1428 tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
1429 break;
1430 case AR5K_TX_QUEUE_BEACON:
1431 case AR5K_TX_QUEUE_CAB:
1432 /* XXX Fix me... */
1433 tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;
1434 ath5k_hw_reg_write(ah, 0, AR5K_BSR);
1435 break;
1436 default:
1437 return -EINVAL;
1438 }
1439
1440 /* Stop queue */
1441 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
Jiri Slaby274c7c32008-07-15 17:44:20 +02001442 ath5k_hw_reg_read(ah, AR5K_CR);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001443 } else {
1444 /*
1445 * Schedule TX disable and wait until queue is empty
1446 */
1447 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
1448
1449 /*Check for pending frames*/
1450 do {
1451 pending = ath5k_hw_reg_read(ah,
1452 AR5K_QUEUE_STATUS(queue)) &
1453 AR5K_QCU_STS_FRMPENDCNT;
1454 udelay(100);
1455 } while (--i && pending);
1456
1457 /* Clear register */
1458 ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
Jiri Slaby274c7c32008-07-15 17:44:20 +02001459 if (pending)
1460 return -EBUSY;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001461 }
1462
1463 /* TODO: Check for success else return error */
1464 return 0;
1465}
1466
1467/*
1468 * Get the address of the TX Descriptor for a specific queue
1469 * (see also QCU/DCU functions)
1470 */
1471u32 ath5k_hw_get_tx_buf(struct ath5k_hw *ah, unsigned int queue)
1472{
1473 u16 tx_reg;
1474
1475 ATH5K_TRACE(ah->ah_sc);
1476 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1477
1478 /*
1479 * Get the transmit queue descriptor pointer from the selected queue
1480 */
1481 /*5210 doesn't have QCU*/
1482 if (ah->ah_version == AR5K_AR5210) {
1483 switch (ah->ah_txq[queue].tqi_type) {
1484 case AR5K_TX_QUEUE_DATA:
1485 tx_reg = AR5K_NOQCU_TXDP0;
1486 break;
1487 case AR5K_TX_QUEUE_BEACON:
1488 case AR5K_TX_QUEUE_CAB:
1489 tx_reg = AR5K_NOQCU_TXDP1;
1490 break;
1491 default:
1492 return 0xffffffff;
1493 }
1494 } else {
1495 tx_reg = AR5K_QUEUE_TXDP(queue);
1496 }
1497
1498 return ath5k_hw_reg_read(ah, tx_reg);
1499}
1500
1501/*
1502 * Set the address of the TX Descriptor for a specific queue
1503 * (see also QCU/DCU functions)
1504 */
1505int ath5k_hw_put_tx_buf(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
1506{
1507 u16 tx_reg;
1508
1509 ATH5K_TRACE(ah->ah_sc);
1510 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1511
1512 /*
1513 * Set the transmit queue descriptor pointer register by type
1514 * on 5210
1515 */
1516 if (ah->ah_version == AR5K_AR5210) {
1517 switch (ah->ah_txq[queue].tqi_type) {
1518 case AR5K_TX_QUEUE_DATA:
1519 tx_reg = AR5K_NOQCU_TXDP0;
1520 break;
1521 case AR5K_TX_QUEUE_BEACON:
1522 case AR5K_TX_QUEUE_CAB:
1523 tx_reg = AR5K_NOQCU_TXDP1;
1524 break;
1525 default:
1526 return -EINVAL;
1527 }
1528 } else {
1529 /*
1530 * Set the transmit queue descriptor pointer for
1531 * the selected queue on QCU for 5211+
1532 * (this won't work if the queue is still active)
1533 */
1534 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
1535 return -EIO;
1536
1537 tx_reg = AR5K_QUEUE_TXDP(queue);
1538 }
1539
1540 /* Set descriptor pointer */
1541 ath5k_hw_reg_write(ah, phys_addr, tx_reg);
1542
1543 return 0;
1544}
1545
1546/*
1547 * Update tx trigger level
1548 */
1549int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
1550{
1551 u32 trigger_level, imr;
1552 int ret = -EIO;
1553
1554 ATH5K_TRACE(ah->ah_sc);
1555
1556 /*
1557 * Disable interrupts by setting the mask
1558 */
1559 imr = ath5k_hw_set_intr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
1560
1561 /*TODO: Boundary check on trigger_level*/
1562 trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
1563 AR5K_TXCFG_TXFULL);
1564
Joe Perchese9010e22008-03-07 14:21:16 -08001565 if (!increase) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001566 if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
1567 goto done;
1568 } else
1569 trigger_level +=
1570 ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
1571
1572 /*
1573 * Update trigger level on success
1574 */
1575 if (ah->ah_version == AR5K_AR5210)
1576 ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
1577 else
1578 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
1579 AR5K_TXCFG_TXFULL, trigger_level);
1580
1581 ret = 0;
1582
1583done:
1584 /*
1585 * Restore interrupt mask
1586 */
1587 ath5k_hw_set_intr(ah, imr);
1588
1589 return ret;
1590}
1591
1592/*
1593 * Interrupt handling
1594 */
1595
1596/*
1597 * Check if we have pending interrupts
1598 */
1599bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
1600{
1601 ATH5K_TRACE(ah->ah_sc);
1602 return ath5k_hw_reg_read(ah, AR5K_INTPEND);
1603}
1604
1605/*
1606 * Get interrupt mask (ISR)
1607 */
1608int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
1609{
1610 u32 data;
1611
1612 ATH5K_TRACE(ah->ah_sc);
1613
1614 /*
1615 * Read interrupt status from the Interrupt Status register
1616 * on 5210
1617 */
1618 if (ah->ah_version == AR5K_AR5210) {
1619 data = ath5k_hw_reg_read(ah, AR5K_ISR);
1620 if (unlikely(data == AR5K_INT_NOCARD)) {
1621 *interrupt_mask = data;
1622 return -ENODEV;
1623 }
1624 } else {
1625 /*
1626 * Read interrupt status from the Read-And-Clear shadow register
1627 * Note: PISR/SISR Not available on 5210
1628 */
1629 data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
1630 }
1631
1632 /*
1633 * Get abstract interrupt mask (driver-compatible)
1634 */
1635 *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
1636
1637 if (unlikely(data == AR5K_INT_NOCARD))
1638 return -ENODEV;
1639
1640 if (data & (AR5K_ISR_RXOK | AR5K_ISR_RXERR))
1641 *interrupt_mask |= AR5K_INT_RX;
1642
1643 if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR
1644 | AR5K_ISR_TXDESC | AR5K_ISR_TXEOL))
1645 *interrupt_mask |= AR5K_INT_TX;
1646
1647 if (ah->ah_version != AR5K_AR5210) {
1648 /*HIU = Host Interface Unit (PCI etc)*/
1649 if (unlikely(data & (AR5K_ISR_HIUERR)))
1650 *interrupt_mask |= AR5K_INT_FATAL;
1651
1652 /*Beacon Not Ready*/
1653 if (unlikely(data & (AR5K_ISR_BNR)))
1654 *interrupt_mask |= AR5K_INT_BNR;
1655 }
1656
1657 /*
1658 * XXX: BMISS interrupts may occur after association.
1659 * I found this on 5210 code but it needs testing. If this is
1660 * true we should disable them before assoc and re-enable them
1661 * after a successfull assoc + some jiffies.
1662 */
1663#if 0
1664 interrupt_mask &= ~AR5K_INT_BMISS;
1665#endif
1666
1667 /*
1668 * In case we didn't handle anything,
1669 * print the register value.
1670 */
1671 if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
1672 ATH5K_PRINTF("0x%08x\n", data);
1673
1674 return 0;
1675}
1676
1677/*
1678 * Set interrupt mask
1679 */
1680enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask)
1681{
1682 enum ath5k_int old_mask, int_mask;
1683
1684 /*
1685 * Disable card interrupts to prevent any race conditions
1686 * (they will be re-enabled afterwards).
1687 */
1688 ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
1689
1690 old_mask = ah->ah_imr;
1691
1692 /*
1693 * Add additional, chipset-dependent interrupt mask flags
1694 * and write them to the IMR (interrupt mask register).
1695 */
1696 int_mask = new_mask & AR5K_INT_COMMON;
1697
1698 if (new_mask & AR5K_INT_RX)
1699 int_mask |= AR5K_IMR_RXOK | AR5K_IMR_RXERR | AR5K_IMR_RXORN |
1700 AR5K_IMR_RXDESC;
1701
1702 if (new_mask & AR5K_INT_TX)
1703 int_mask |= AR5K_IMR_TXOK | AR5K_IMR_TXERR | AR5K_IMR_TXDESC |
1704 AR5K_IMR_TXURN;
1705
1706 if (ah->ah_version != AR5K_AR5210) {
1707 if (new_mask & AR5K_INT_FATAL) {
1708 int_mask |= AR5K_IMR_HIUERR;
1709 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_MCABT |
1710 AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR);
1711 }
1712 }
1713
1714 ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
1715
1716 /* Store new interrupt mask */
1717 ah->ah_imr = new_mask;
1718
1719 /* ..re-enable interrupts */
1720 ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
Jiri Slaby274c7c32008-07-15 17:44:20 +02001721 ath5k_hw_reg_read(ah, AR5K_IER);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001722
1723 return old_mask;
1724}
1725
1726
1727/*************************\
1728 EEPROM access functions
1729\*************************/
1730
1731/*
1732 * Read from eeprom
1733 */
1734static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
1735{
1736 u32 status, timeout;
1737
1738 ATH5K_TRACE(ah->ah_sc);
1739 /*
1740 * Initialize EEPROM access
1741 */
1742 if (ah->ah_version == AR5K_AR5210) {
1743 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
1744 (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
1745 } else {
1746 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
1747 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1748 AR5K_EEPROM_CMD_READ);
1749 }
1750
1751 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
1752 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
1753 if (status & AR5K_EEPROM_STAT_RDDONE) {
1754 if (status & AR5K_EEPROM_STAT_RDERR)
1755 return -EIO;
1756 *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
1757 0xffff);
1758 return 0;
1759 }
1760 udelay(15);
1761 }
1762
1763 return -ETIMEDOUT;
1764}
1765
1766/*
1767 * Write to eeprom - currently disabled, use at your own risk
1768 */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001769#if 0
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001770static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data)
1771{
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001772
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001773 u32 status, timeout;
1774
1775 ATH5K_TRACE(ah->ah_sc);
1776
1777 /*
1778 * Initialize eeprom access
1779 */
1780
1781 if (ah->ah_version == AR5K_AR5210) {
1782 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
1783 } else {
1784 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1785 AR5K_EEPROM_CMD_RESET);
1786 }
1787
1788 /*
1789 * Write data to data register
1790 */
1791
1792 if (ah->ah_version == AR5K_AR5210) {
1793 ath5k_hw_reg_write(ah, data, AR5K_EEPROM_BASE + (4 * offset));
1794 } else {
1795 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
1796 ath5k_hw_reg_write(ah, data, AR5K_EEPROM_DATA);
1797 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1798 AR5K_EEPROM_CMD_WRITE);
1799 }
1800
1801 /*
1802 * Check status
1803 */
1804
1805 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
1806 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
1807 if (status & AR5K_EEPROM_STAT_WRDONE) {
1808 if (status & AR5K_EEPROM_STAT_WRERR)
1809 return EIO;
1810 return 0;
1811 }
1812 udelay(15);
1813 }
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001814
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001815 ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!");
1816 return -EIO;
1817}
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001818#endif
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001819
1820/*
1821 * Translate binary channel representation in EEPROM to frequency
1822 */
1823static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin, unsigned int mode)
1824{
1825 u16 val;
1826
1827 if (bin == AR5K_EEPROM_CHANNEL_DIS)
1828 return bin;
1829
1830 if (mode == AR5K_EEPROM_MODE_11A) {
1831 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
1832 val = (5 * bin) + 4800;
1833 else
1834 val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
1835 (bin * 10) + 5100;
1836 } else {
1837 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
1838 val = bin + 2300;
1839 else
1840 val = bin + 2400;
1841 }
1842
1843 return val;
1844}
1845
1846/*
1847 * Read antenna infos from eeprom
1848 */
1849static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
1850 unsigned int mode)
1851{
1852 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1853 u32 o = *offset;
1854 u16 val;
1855 int ret, i = 0;
1856
1857 AR5K_EEPROM_READ(o++, val);
1858 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
1859 ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f;
1860 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
1861
1862 AR5K_EEPROM_READ(o++, val);
1863 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
1864 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
1865 ee->ee_ant_control[mode][i++] = val & 0x3f;
1866
1867 AR5K_EEPROM_READ(o++, val);
1868 ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
1869 ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
1870 ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
1871
1872 AR5K_EEPROM_READ(o++, val);
1873 ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
1874 ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
1875 ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
1876 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
1877
1878 AR5K_EEPROM_READ(o++, val);
1879 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
1880 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
1881 ee->ee_ant_control[mode][i++] = val & 0x3f;
1882
1883 /* Get antenna modes */
1884 ah->ah_antenna[mode][0] =
1885 (ee->ee_ant_control[mode][0] << 4) | 0x1;
1886 ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
1887 ee->ee_ant_control[mode][1] |
1888 (ee->ee_ant_control[mode][2] << 6) |
1889 (ee->ee_ant_control[mode][3] << 12) |
1890 (ee->ee_ant_control[mode][4] << 18) |
1891 (ee->ee_ant_control[mode][5] << 24);
1892 ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
1893 ee->ee_ant_control[mode][6] |
1894 (ee->ee_ant_control[mode][7] << 6) |
1895 (ee->ee_ant_control[mode][8] << 12) |
1896 (ee->ee_ant_control[mode][9] << 18) |
1897 (ee->ee_ant_control[mode][10] << 24);
1898
1899 /* return new offset */
1900 *offset = o;
1901
1902 return 0;
1903}
1904
1905/*
1906 * Read supported modes from eeprom
1907 */
1908static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
1909 unsigned int mode)
1910{
1911 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1912 u32 o = *offset;
1913 u16 val;
1914 int ret;
1915
1916 AR5K_EEPROM_READ(o++, val);
1917 ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
1918 ee->ee_thr_62[mode] = val & 0xff;
1919
1920 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
1921 ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
1922
1923 AR5K_EEPROM_READ(o++, val);
1924 ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
1925 ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
1926
1927 AR5K_EEPROM_READ(o++, val);
1928 ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
1929
1930 if ((val & 0xff) & 0x80)
1931 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
1932 else
1933 ee->ee_noise_floor_thr[mode] = val & 0xff;
1934
1935 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
1936 ee->ee_noise_floor_thr[mode] =
1937 mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
1938
1939 AR5K_EEPROM_READ(o++, val);
1940 ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
1941 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
1942 ee->ee_xpd[mode] = val & 0x1;
1943
1944 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
1945 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
1946
1947 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
1948 AR5K_EEPROM_READ(o++, val);
1949 ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
1950
1951 if (mode == AR5K_EEPROM_MODE_11A)
1952 ee->ee_xr_power[mode] = val & 0x3f;
1953 else {
1954 ee->ee_ob[mode][0] = val & 0x7;
1955 ee->ee_db[mode][0] = (val >> 3) & 0x7;
1956 }
1957 }
1958
1959 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
1960 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
1961 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
1962 } else {
1963 ee->ee_i_gain[mode] = (val >> 13) & 0x7;
1964
1965 AR5K_EEPROM_READ(o++, val);
1966 ee->ee_i_gain[mode] |= (val << 3) & 0x38;
1967
1968 if (mode == AR5K_EEPROM_MODE_11G)
1969 ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
1970 }
1971
1972 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
1973 mode == AR5K_EEPROM_MODE_11A) {
1974 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
1975 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
1976 }
1977
1978 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 &&
1979 mode == AR5K_EEPROM_MODE_11G)
1980 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
1981
1982 /* return new offset */
1983 *offset = o;
1984
1985 return 0;
1986}
1987
1988/*
1989 * Initialize eeprom & capabilities structs
1990 */
1991static int ath5k_eeprom_init(struct ath5k_hw *ah)
1992{
1993 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1994 unsigned int mode, i;
1995 int ret;
1996 u32 offset;
1997 u16 val;
1998
1999 /* Initial TX thermal adjustment values */
2000 ee->ee_tx_clip = 4;
2001 ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
2002 ee->ee_gain_select = 1;
2003
2004 /*
2005 * Read values from EEPROM and store them in the capability structure
2006 */
2007 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
2008 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
2009 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
2010 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
2011 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
2012
2013 /* Return if we have an old EEPROM */
2014 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
2015 return 0;
2016
2017#ifdef notyet
2018 /*
2019 * Validate the checksum of the EEPROM date. There are some
2020 * devices with invalid EEPROMs.
2021 */
2022 for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
2023 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
2024 cksum ^= val;
2025 }
2026 if (cksum != AR5K_EEPROM_INFO_CKSUM) {
2027 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
2028 return -EIO;
2029 }
2030#endif
2031
2032 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
2033 ee_ant_gain);
2034
2035 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
2036 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
2037 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
2038 }
2039
2040 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
2041 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
2042 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
2043 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
2044
2045 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
2046 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
2047 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
2048 }
2049
2050 /*
2051 * Get conformance test limit values
2052 */
2053 offset = AR5K_EEPROM_CTL(ah->ah_ee_version);
2054 ee->ee_ctls = AR5K_EEPROM_N_CTLS(ah->ah_ee_version);
2055
2056 for (i = 0; i < ee->ee_ctls; i++) {
2057 AR5K_EEPROM_READ(offset++, val);
2058 ee->ee_ctl[i] = (val >> 8) & 0xff;
2059 ee->ee_ctl[i + 1] = val & 0xff;
2060 }
2061
2062 /*
2063 * Get values for 802.11a (5GHz)
2064 */
2065 mode = AR5K_EEPROM_MODE_11A;
2066
2067 ee->ee_turbo_max_power[mode] =
2068 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
2069
2070 offset = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
2071
2072 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
2073 if (ret)
2074 return ret;
2075
2076 AR5K_EEPROM_READ(offset++, val);
2077 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
2078 ee->ee_ob[mode][3] = (val >> 5) & 0x7;
2079 ee->ee_db[mode][3] = (val >> 2) & 0x7;
2080 ee->ee_ob[mode][2] = (val << 1) & 0x7;
2081
2082 AR5K_EEPROM_READ(offset++, val);
2083 ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
2084 ee->ee_db[mode][2] = (val >> 12) & 0x7;
2085 ee->ee_ob[mode][1] = (val >> 9) & 0x7;
2086 ee->ee_db[mode][1] = (val >> 6) & 0x7;
2087 ee->ee_ob[mode][0] = (val >> 3) & 0x7;
2088 ee->ee_db[mode][0] = val & 0x7;
2089
2090 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
2091 if (ret)
2092 return ret;
2093
2094 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
2095 AR5K_EEPROM_READ(offset++, val);
2096 ee->ee_margin_tx_rx[mode] = val & 0x3f;
2097 }
2098
2099 /*
2100 * Get values for 802.11b (2.4GHz)
2101 */
2102 mode = AR5K_EEPROM_MODE_11B;
2103 offset = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
2104
2105 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
2106 if (ret)
2107 return ret;
2108
2109 AR5K_EEPROM_READ(offset++, val);
2110 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
2111 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
2112 ee->ee_db[mode][1] = val & 0x7;
2113
2114 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
2115 if (ret)
2116 return ret;
2117
2118 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
2119 AR5K_EEPROM_READ(offset++, val);
2120 ee->ee_cal_pier[mode][0] =
2121 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2122 ee->ee_cal_pier[mode][1] =
2123 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
2124
2125 AR5K_EEPROM_READ(offset++, val);
2126 ee->ee_cal_pier[mode][2] =
2127 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2128 }
2129
2130 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
2131 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
2132
2133 /*
2134 * Get values for 802.11g (2.4GHz)
2135 */
2136 mode = AR5K_EEPROM_MODE_11G;
2137 offset = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
2138
2139 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
2140 if (ret)
2141 return ret;
2142
2143 AR5K_EEPROM_READ(offset++, val);
2144 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
2145 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
2146 ee->ee_db[mode][1] = val & 0x7;
2147
2148 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
2149 if (ret)
2150 return ret;
2151
2152 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
2153 AR5K_EEPROM_READ(offset++, val);
2154 ee->ee_cal_pier[mode][0] =
2155 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2156 ee->ee_cal_pier[mode][1] =
2157 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
2158
2159 AR5K_EEPROM_READ(offset++, val);
2160 ee->ee_turbo_max_power[mode] = val & 0x7f;
2161 ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
2162
2163 AR5K_EEPROM_READ(offset++, val);
2164 ee->ee_cal_pier[mode][2] =
2165 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2166
2167 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
2168 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
2169
2170 AR5K_EEPROM_READ(offset++, val);
2171 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
2172 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
2173
2174 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
2175 AR5K_EEPROM_READ(offset++, val);
2176 ee->ee_cck_ofdm_gain_delta = val & 0xff;
2177 }
2178 }
2179
2180 /*
2181 * Read 5GHz EEPROM channels
2182 */
2183
2184 return 0;
2185}
2186
2187/*
2188 * Read the MAC address from eeprom
2189 */
2190static int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
2191{
2192 u8 mac_d[ETH_ALEN];
2193 u32 total, offset;
2194 u16 data;
2195 int octet, ret;
2196
2197 memset(mac, 0, ETH_ALEN);
2198 memset(mac_d, 0, ETH_ALEN);
2199
2200 ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
2201 if (ret)
2202 return ret;
2203
2204 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
2205 ret = ath5k_hw_eeprom_read(ah, offset, &data);
2206 if (ret)
2207 return ret;
2208
2209 total += data;
2210 mac_d[octet + 1] = data & 0xff;
2211 mac_d[octet] = data >> 8;
2212 octet += 2;
2213 }
2214
2215 memcpy(mac, mac_d, ETH_ALEN);
2216
2217 if (!total || total == 3 * 0xffff)
2218 return -EINVAL;
2219
2220 return 0;
2221}
2222
2223/*
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002224 * Fill the capabilities struct
2225 */
2226static int ath5k_hw_get_capabilities(struct ath5k_hw *ah)
2227{
2228 u16 ee_header;
2229
2230 ATH5K_TRACE(ah->ah_sc);
2231 /* Capabilities stored in the EEPROM */
2232 ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
2233
2234 if (ah->ah_version == AR5K_AR5210) {
2235 /*
2236 * Set radio capabilities
2237 * (The AR5110 only supports the middle 5GHz band)
2238 */
2239 ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
2240 ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
2241 ah->ah_capabilities.cap_range.range_2ghz_min = 0;
2242 ah->ah_capabilities.cap_range.range_2ghz_max = 0;
2243
2244 /* Set supported modes */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002245 __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
2246 __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002247 } else {
2248 /*
2249 * XXX The tranceiver supports frequencies from 4920 to 6100GHz
2250 * XXX and from 2312 to 2732GHz. There are problems with the
2251 * XXX current ieee80211 implementation because the IEEE
2252 * XXX channel mapping does not support negative channel
2253 * XXX numbers (2312MHz is channel -19). Of course, this
2254 * XXX doesn't matter because these channels are out of range
2255 * XXX but some regulation domains like MKK (Japan) will
2256 * XXX support frequencies somewhere around 4.8GHz.
2257 */
2258
2259 /*
2260 * Set radio capabilities
2261 */
2262
2263 if (AR5K_EEPROM_HDR_11A(ee_header)) {
2264 ah->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
2265 ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
2266
2267 /* Set supported modes */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002268 __set_bit(AR5K_MODE_11A,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002269 ah->ah_capabilities.cap_mode);
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002270 __set_bit(AR5K_MODE_11A_TURBO,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002271 ah->ah_capabilities.cap_mode);
2272 if (ah->ah_version == AR5K_AR5212)
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002273 __set_bit(AR5K_MODE_11G_TURBO,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002274 ah->ah_capabilities.cap_mode);
2275 }
2276
2277 /* Enable 802.11b if a 2GHz capable radio (2111/5112) is
2278 * connected */
2279 if (AR5K_EEPROM_HDR_11B(ee_header) ||
2280 AR5K_EEPROM_HDR_11G(ee_header)) {
2281 ah->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
2282 ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
2283
2284 if (AR5K_EEPROM_HDR_11B(ee_header))
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002285 __set_bit(AR5K_MODE_11B,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002286 ah->ah_capabilities.cap_mode);
2287
2288 if (AR5K_EEPROM_HDR_11G(ee_header))
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002289 __set_bit(AR5K_MODE_11G,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002290 ah->ah_capabilities.cap_mode);
2291 }
2292 }
2293
2294 /* GPIO */
2295 ah->ah_gpio_npins = AR5K_NUM_GPIO;
2296
2297 /* Set number of supported TX queues */
2298 if (ah->ah_version == AR5K_AR5210)
2299 ah->ah_capabilities.cap_queues.q_tx_num =
2300 AR5K_NUM_TX_QUEUES_NOQCU;
2301 else
2302 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
2303
2304 return 0;
2305}
2306
2307/*********************************\
2308 Protocol Control Unit Functions
2309\*********************************/
2310
2311/*
2312 * Set Operation mode
2313 */
2314int ath5k_hw_set_opmode(struct ath5k_hw *ah)
2315{
2316 u32 pcu_reg, beacon_reg, low_id, high_id;
2317
2318 pcu_reg = 0;
2319 beacon_reg = 0;
2320
2321 ATH5K_TRACE(ah->ah_sc);
2322
2323 switch (ah->ah_op_mode) {
2324 case IEEE80211_IF_TYPE_IBSS:
2325 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_DESC_ANTENNA |
2326 (ah->ah_version == AR5K_AR5210 ?
2327 AR5K_STA_ID1_NO_PSPOLL : 0);
2328 beacon_reg |= AR5K_BCR_ADHOC;
2329 break;
2330
2331 case IEEE80211_IF_TYPE_AP:
2332 pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_RTS_DEF_ANTENNA |
2333 (ah->ah_version == AR5K_AR5210 ?
2334 AR5K_STA_ID1_NO_PSPOLL : 0);
2335 beacon_reg |= AR5K_BCR_AP;
2336 break;
2337
2338 case IEEE80211_IF_TYPE_STA:
2339 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
2340 (ah->ah_version == AR5K_AR5210 ?
2341 AR5K_STA_ID1_PWR_SV : 0);
2342 case IEEE80211_IF_TYPE_MNTR:
2343 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
2344 (ah->ah_version == AR5K_AR5210 ?
2345 AR5K_STA_ID1_NO_PSPOLL : 0);
2346 break;
2347
2348 default:
2349 return -EINVAL;
2350 }
2351
2352 /*
2353 * Set PCU registers
2354 */
2355 low_id = AR5K_LOW_ID(ah->ah_sta_id);
2356 high_id = AR5K_HIGH_ID(ah->ah_sta_id);
2357 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
2358 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
2359
2360 /*
2361 * Set Beacon Control Register on 5210
2362 */
2363 if (ah->ah_version == AR5K_AR5210)
2364 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
2365
2366 return 0;
2367}
2368
2369/*
2370 * BSSID Functions
2371 */
2372
2373/*
2374 * Get station id
2375 */
2376void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
2377{
2378 ATH5K_TRACE(ah->ah_sc);
2379 memcpy(mac, ah->ah_sta_id, ETH_ALEN);
2380}
2381
2382/*
2383 * Set station id
2384 */
2385int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
2386{
2387 u32 low_id, high_id;
2388
2389 ATH5K_TRACE(ah->ah_sc);
2390 /* Set new station ID */
2391 memcpy(ah->ah_sta_id, mac, ETH_ALEN);
2392
2393 low_id = AR5K_LOW_ID(mac);
2394 high_id = AR5K_HIGH_ID(mac);
2395
2396 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
2397 ath5k_hw_reg_write(ah, high_id, AR5K_STA_ID1);
2398
2399 return 0;
2400}
2401
2402/*
2403 * Set BSSID
2404 */
2405void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
2406{
2407 u32 low_id, high_id;
2408 u16 tim_offset = 0;
2409
2410 /*
2411 * Set simple BSSID mask on 5212
2412 */
2413 if (ah->ah_version == AR5K_AR5212) {
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05002414 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0);
2415 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002416 }
2417
2418 /*
2419 * Set BSSID which triggers the "SME Join" operation
2420 */
2421 low_id = AR5K_LOW_ID(bssid);
2422 high_id = AR5K_HIGH_ID(bssid);
2423 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
2424 ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
2425 AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
2426
2427 if (assoc_id == 0) {
2428 ath5k_hw_disable_pspoll(ah);
2429 return;
2430 }
2431
2432 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
2433 tim_offset ? tim_offset + 4 : 0);
2434
2435 ath5k_hw_enable_pspoll(ah, NULL, 0);
2436}
2437/**
2438 * ath5k_hw_set_bssid_mask - set common bits we should listen to
2439 *
2440 * The bssid_mask is a utility used by AR5212 hardware to inform the hardware
2441 * which bits of the interface's MAC address should be looked at when trying
2442 * to decide which packets to ACK. In station mode every bit matters. In AP
2443 * mode with a single BSS every bit matters as well. In AP mode with
2444 * multiple BSSes not every bit matters.
2445 *
2446 * @ah: the &struct ath5k_hw
2447 * @mask: the bssid_mask, a u8 array of size ETH_ALEN
2448 *
2449 * Note that this is a simple filter and *does* not filter out all
2450 * relevant frames. Some non-relevant frames will get through, probability
2451 * jocks are welcomed to compute.
2452 *
2453 * When handling multiple BSSes (or VAPs) you can get the BSSID mask by
2454 * computing the set of:
2455 *
2456 * ~ ( MAC XOR BSSID )
2457 *
2458 * When you do this you are essentially computing the common bits. Later it
2459 * is assumed the harware will "and" (&) the BSSID mask with the MAC address
2460 * to obtain the relevant bits which should match on the destination frame.
2461 *
2462 * Simple example: on your card you have have two BSSes you have created with
2463 * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
2464 * There is another BSSID-03 but you are not part of it. For simplicity's sake,
2465 * assuming only 4 bits for a mac address and for BSSIDs you can then have:
2466 *
2467 * \
2468 * MAC: 0001 |
2469 * BSSID-01: 0100 | --> Belongs to us
2470 * BSSID-02: 1001 |
2471 * /
2472 * -------------------
2473 * BSSID-03: 0110 | --> External
2474 * -------------------
2475 *
2476 * Our bssid_mask would then be:
2477 *
2478 * On loop iteration for BSSID-01:
2479 * ~(0001 ^ 0100) -> ~(0101)
2480 * -> 1010
2481 * bssid_mask = 1010
2482 *
2483 * On loop iteration for BSSID-02:
2484 * bssid_mask &= ~(0001 ^ 1001)
2485 * bssid_mask = (1010) & ~(0001 ^ 1001)
2486 * bssid_mask = (1010) & ~(1001)
2487 * bssid_mask = (1010) & (0110)
2488 * bssid_mask = 0010
2489 *
2490 * A bssid_mask of 0010 means "only pay attention to the second least
2491 * significant bit". This is because its the only bit common
2492 * amongst the MAC and all BSSIDs we support. To findout what the real
2493 * common bit is we can simply "&" the bssid_mask now with any BSSID we have
2494 * or our MAC address (we assume the hardware uses the MAC address).
2495 *
2496 * Now, suppose there's an incoming frame for BSSID-03:
2497 *
2498 * IFRAME-01: 0110
2499 *
2500 * An easy eye-inspeciton of this already should tell you that this frame
2501 * will not pass our check. This is beacuse the bssid_mask tells the
2502 * hardware to only look at the second least significant bit and the
2503 * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
2504 * as 1, which does not match 0.
2505 *
2506 * So with IFRAME-01 we *assume* the hardware will do:
2507 *
2508 * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
2509 * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
2510 * --> allow = (0010) == 0000 ? 1 : 0;
2511 * --> allow = 0
2512 *
2513 * Lets now test a frame that should work:
2514 *
2515 * IFRAME-02: 0001 (we should allow)
2516 *
2517 * allow = (0001 & 1010) == 1010
2518 *
2519 * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
2520 * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0;
2521 * --> allow = (0010) == (0010)
2522 * --> allow = 1
2523 *
2524 * Other examples:
2525 *
2526 * IFRAME-03: 0100 --> allowed
2527 * IFRAME-04: 1001 --> allowed
2528 * IFRAME-05: 1101 --> allowed but its not for us!!!
2529 *
2530 */
2531int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
2532{
2533 u32 low_id, high_id;
2534 ATH5K_TRACE(ah->ah_sc);
2535
2536 if (ah->ah_version == AR5K_AR5212) {
2537 low_id = AR5K_LOW_ID(mask);
2538 high_id = AR5K_HIGH_ID(mask);
2539
2540 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
2541 ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
2542
2543 return 0;
2544 }
2545
2546 return -EIO;
2547}
2548
2549/*
2550 * Receive start/stop functions
2551 */
2552
2553/*
2554 * Start receive on PCU
2555 */
2556void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
2557{
2558 ATH5K_TRACE(ah->ah_sc);
2559 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05002560
2561 /* TODO: ANI Support */
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002562}
2563
2564/*
2565 * Stop receive on PCU
2566 */
2567void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah)
2568{
2569 ATH5K_TRACE(ah->ah_sc);
2570 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05002571
2572 /* TODO: ANI Support */
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002573}
2574
2575/*
2576 * RX Filter functions
2577 */
2578
2579/*
2580 * Set multicast filter
2581 */
2582void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
2583{
2584 ATH5K_TRACE(ah->ah_sc);
2585 /* Set the multicat filter */
2586 ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
2587 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
2588}
2589
2590/*
2591 * Set multicast filter by index
2592 */
2593int ath5k_hw_set_mcast_filterindex(struct ath5k_hw *ah, u32 index)
2594{
2595
2596 ATH5K_TRACE(ah->ah_sc);
2597 if (index >= 64)
2598 return -EINVAL;
2599 else if (index >= 32)
2600 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
2601 (1 << (index - 32)));
2602 else
2603 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
2604
2605 return 0;
2606}
2607
2608/*
2609 * Clear Multicast filter by index
2610 */
2611int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
2612{
2613
2614 ATH5K_TRACE(ah->ah_sc);
2615 if (index >= 64)
2616 return -EINVAL;
2617 else if (index >= 32)
2618 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
2619 (1 << (index - 32)));
2620 else
2621 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
2622
2623 return 0;
2624}
2625
2626/*
2627 * Get current rx filter
2628 */
2629u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
2630{
2631 u32 data, filter = 0;
2632
2633 ATH5K_TRACE(ah->ah_sc);
2634 filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
2635
2636 /*Radar detection for 5212*/
2637 if (ah->ah_version == AR5K_AR5212) {
2638 data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
2639
2640 if (data & AR5K_PHY_ERR_FIL_RADAR)
2641 filter |= AR5K_RX_FILTER_RADARERR;
2642 if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
2643 filter |= AR5K_RX_FILTER_PHYERR;
2644 }
2645
2646 return filter;
2647}
2648
2649/*
2650 * Set rx filter
2651 */
2652void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
2653{
2654 u32 data = 0;
2655
2656 ATH5K_TRACE(ah->ah_sc);
2657
2658 /* Set PHY error filter register on 5212*/
2659 if (ah->ah_version == AR5K_AR5212) {
2660 if (filter & AR5K_RX_FILTER_RADARERR)
2661 data |= AR5K_PHY_ERR_FIL_RADAR;
2662 if (filter & AR5K_RX_FILTER_PHYERR)
2663 data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
2664 }
2665
2666 /*
2667 * The AR5210 uses promiscous mode to detect radar activity
2668 */
2669 if (ah->ah_version == AR5K_AR5210 &&
2670 (filter & AR5K_RX_FILTER_RADARERR)) {
2671 filter &= ~AR5K_RX_FILTER_RADARERR;
2672 filter |= AR5K_RX_FILTER_PROM;
2673 }
2674
2675 /*Zero length DMA*/
2676 if (data)
2677 AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
2678 else
2679 AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
2680
2681 /*Write RX Filter register*/
2682 ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
2683
2684 /*Write PHY error filter register on 5212*/
2685 if (ah->ah_version == AR5K_AR5212)
2686 ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
2687
2688}
2689
2690/*
2691 * Beacon related functions
2692 */
2693
2694/*
2695 * Get a 32bit TSF
2696 */
2697u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
2698{
2699 ATH5K_TRACE(ah->ah_sc);
2700 return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
2701}
2702
2703/*
2704 * Get the full 64bit TSF
2705 */
2706u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
2707{
2708 u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
2709 ATH5K_TRACE(ah->ah_sc);
2710
2711 return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
2712}
2713
2714/*
2715 * Force a TSF reset
2716 */
2717void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
2718{
2719 ATH5K_TRACE(ah->ah_sc);
2720 AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_RESET_TSF);
2721}
2722
2723/*
2724 * Initialize beacon timers
2725 */
2726void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
2727{
2728 u32 timer1, timer2, timer3;
2729
2730 ATH5K_TRACE(ah->ah_sc);
2731 /*
2732 * Set the additional timers by mode
2733 */
2734 switch (ah->ah_op_mode) {
2735 case IEEE80211_IF_TYPE_STA:
2736 if (ah->ah_version == AR5K_AR5210) {
2737 timer1 = 0xffffffff;
2738 timer2 = 0xffffffff;
2739 } else {
2740 timer1 = 0x0000ffff;
2741 timer2 = 0x0007ffff;
2742 }
2743 break;
2744
2745 default:
Bruno Randolf1008e0f2008-01-18 21:51:19 +09002746 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
2747 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002748 }
2749
2750 timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
2751
2752 /*
2753 * Set the beacon register and enable all timers.
2754 * (next beacon, DMA beacon, software beacon, ATIM window time)
2755 */
2756 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
2757 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
2758 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
2759 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
2760
2761 ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
2762 AR5K_BEACON_RESET_TSF | AR5K_BEACON_ENABLE),
2763 AR5K_BEACON);
2764}
2765
2766#if 0
2767/*
2768 * Set beacon timers
2769 */
2770int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
2771 const struct ath5k_beacon_state *state)
2772{
2773 u32 cfp_period, next_cfp, dtim, interval, next_beacon;
2774
2775 /*
2776 * TODO: should be changed through *state
2777 * review struct ath5k_beacon_state struct
2778 *
2779 * XXX: These are used for cfp period bellow, are they
2780 * ok ? Is it O.K. for tsf here to be 0 or should we use
2781 * get_tsf ?
2782 */
2783 u32 dtim_count = 0; /* XXX */
2784 u32 cfp_count = 0; /* XXX */
2785 u32 tsf = 0; /* XXX */
2786
2787 ATH5K_TRACE(ah->ah_sc);
2788 /* Return on an invalid beacon state */
2789 if (state->bs_interval < 1)
2790 return -EINVAL;
2791
2792 interval = state->bs_interval;
2793 dtim = state->bs_dtim_period;
2794
2795 /*
2796 * PCF support?
2797 */
2798 if (state->bs_cfp_period > 0) {
2799 /*
2800 * Enable PCF mode and set the CFP
2801 * (Contention Free Period) and timer registers
2802 */
2803 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
2804 state->bs_interval;
2805 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
2806 state->bs_interval;
2807
2808 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
2809 AR5K_STA_ID1_DEFAULT_ANTENNA |
2810 AR5K_STA_ID1_PCF);
2811 ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
2812 ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
2813 AR5K_CFP_DUR);
2814 ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
2815 next_cfp)) << 3, AR5K_TIMER2);
2816 } else {
2817 /* Disable PCF mode */
2818 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
2819 AR5K_STA_ID1_DEFAULT_ANTENNA |
2820 AR5K_STA_ID1_PCF);
2821 }
2822
2823 /*
2824 * Enable the beacon timer register
2825 */
2826 ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
2827
2828 /*
2829 * Start the beacon timers
2830 */
2831 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &~
2832 (AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
2833 AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
2834 AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
2835 AR5K_BEACON_PERIOD), AR5K_BEACON);
2836
2837 /*
2838 * Write new beacon miss threshold, if it appears to be valid
2839 * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
2840 * and return if its not in range. We can test this by reading value and
2841 * setting value to a largest value and seeing which values register.
2842 */
2843
2844 AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
2845 state->bs_bmiss_threshold);
2846
2847 /*
2848 * Set sleep control register
2849 * XXX: Didn't find this in 5210 code but since this register
2850 * exists also in ar5k's 5210 headers i leave it as common code.
2851 */
2852 AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
2853 (state->bs_sleep_duration - 3) << 3);
2854
2855 /*
2856 * Set enhanced sleep registers on 5212
2857 */
2858 if (ah->ah_version == AR5K_AR5212) {
2859 if (state->bs_sleep_duration > state->bs_interval &&
2860 roundup(state->bs_sleep_duration, interval) ==
2861 state->bs_sleep_duration)
2862 interval = state->bs_sleep_duration;
2863
2864 if (state->bs_sleep_duration > dtim && (dtim == 0 ||
2865 roundup(state->bs_sleep_duration, dtim) ==
2866 state->bs_sleep_duration))
2867 dtim = state->bs_sleep_duration;
2868
2869 if (interval > dtim)
2870 return -EINVAL;
2871
2872 next_beacon = interval == dtim ? state->bs_next_dtim :
2873 state->bs_next_beacon;
2874
2875 ath5k_hw_reg_write(ah,
2876 AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
2877 AR5K_SLEEP0_NEXT_DTIM) |
2878 AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
2879 AR5K_SLEEP0_ENH_SLEEP_EN |
2880 AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
2881
2882 ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
2883 AR5K_SLEEP1_NEXT_TIM) |
2884 AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
2885
2886 ath5k_hw_reg_write(ah,
2887 AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
2888 AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
2889 }
2890
2891 return 0;
2892}
2893
2894/*
2895 * Reset beacon timers
2896 */
2897void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
2898{
2899 ATH5K_TRACE(ah->ah_sc);
2900 /*
2901 * Disable beacon timer
2902 */
2903 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
2904
2905 /*
2906 * Disable some beacon register values
2907 */
2908 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
2909 AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
2910 ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
2911}
2912
2913/*
2914 * Wait for beacon queue to finish
2915 */
2916int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
2917{
2918 unsigned int i;
2919 int ret;
2920
2921 ATH5K_TRACE(ah->ah_sc);
2922
2923 /* 5210 doesn't have QCU*/
2924 if (ah->ah_version == AR5K_AR5210) {
2925 /*
2926 * Wait for beaconn queue to finish by checking
2927 * Control Register and Beacon Status Register.
2928 */
2929 for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
2930 if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
2931 ||
2932 !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
2933 break;
2934 udelay(10);
2935 }
2936
2937 /* Timeout... */
2938 if (i <= 0) {
2939 /*
2940 * Re-schedule the beacon queue
2941 */
2942 ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
2943 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
2944 AR5K_BCR);
2945
2946 return -EIO;
2947 }
2948 ret = 0;
2949 } else {
2950 /*5211/5212*/
2951 ret = ath5k_hw_register_timeout(ah,
2952 AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
2953 AR5K_QCU_STS_FRMPENDCNT, 0, false);
2954
2955 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
2956 return -EIO;
2957 }
2958
2959 return ret;
2960}
2961#endif
2962
2963/*
2964 * Update mib counters (statistics)
2965 */
2966void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
Nick Kossifidis194828a2008-04-16 18:49:02 +03002967 struct ieee80211_low_level_stats *stats)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002968{
2969 ATH5K_TRACE(ah->ah_sc);
Nick Kossifidis194828a2008-04-16 18:49:02 +03002970
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002971 /* Read-And-Clear */
Nick Kossifidis194828a2008-04-16 18:49:02 +03002972 stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
2973 stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
2974 stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
2975 stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
2976
2977 /* XXX: Should we use this to track beacon count ?
2978 * -we read it anyway to clear the register */
2979 ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002980
2981 /* Reset profile count registers on 5212*/
2982 if (ah->ah_version == AR5K_AR5212) {
2983 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
2984 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
2985 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
2986 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
2987 }
2988}
2989
2990/** ath5k_hw_set_ack_bitrate - set bitrate for ACKs
2991 *
2992 * @ah: the &struct ath5k_hw
2993 * @high: determines if to use low bit rate or now
2994 */
2995void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
2996{
2997 if (ah->ah_version != AR5K_AR5212)
2998 return;
2999 else {
3000 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
3001 if (high)
3002 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
3003 else
3004 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
3005 }
3006}
3007
3008
3009/*
3010 * ACK/CTS Timeouts
3011 */
3012
3013/*
3014 * Set ACK timeout on PCU
3015 */
3016int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
3017{
3018 ATH5K_TRACE(ah->ah_sc);
3019 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
3020 ah->ah_turbo) <= timeout)
3021 return -EINVAL;
3022
3023 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
3024 ath5k_hw_htoclock(timeout, ah->ah_turbo));
3025
3026 return 0;
3027}
3028
3029/*
3030 * Read the ACK timeout from PCU
3031 */
3032unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
3033{
3034 ATH5K_TRACE(ah->ah_sc);
3035
3036 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
3037 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
3038}
3039
3040/*
3041 * Set CTS timeout on PCU
3042 */
3043int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
3044{
3045 ATH5K_TRACE(ah->ah_sc);
3046 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
3047 ah->ah_turbo) <= timeout)
3048 return -EINVAL;
3049
3050 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
3051 ath5k_hw_htoclock(timeout, ah->ah_turbo));
3052
3053 return 0;
3054}
3055
3056/*
3057 * Read CTS timeout from PCU
3058 */
3059unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
3060{
3061 ATH5K_TRACE(ah->ah_sc);
3062 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
3063 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
3064}
3065
3066/*
3067 * Key table (WEP) functions
3068 */
3069
3070int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
3071{
3072 unsigned int i;
3073
3074 ATH5K_TRACE(ah->ah_sc);
3075 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
3076
3077 for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
3078 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
3079
Nick Kossifidis194828a2008-04-16 18:49:02 +03003080 /*
3081 * Set NULL encryption on AR5212+
3082 *
3083 * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
3084 * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
3085 *
3086 * Note2: Windows driver (ndiswrapper) sets this to
3087 * 0x00000714 instead of 0x00000007
3088 */
3089 if (ah->ah_version > AR5K_AR5211)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003090 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
3091 AR5K_KEYTABLE_TYPE(entry));
3092
3093 return 0;
3094}
3095
3096int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
3097{
3098 ATH5K_TRACE(ah->ah_sc);
3099 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
3100
3101 /* Check the validation flag at the end of the entry */
3102 return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
3103 AR5K_KEYTABLE_VALID;
3104}
3105
3106int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
3107 const struct ieee80211_key_conf *key, const u8 *mac)
3108{
3109 unsigned int i;
3110 __le32 key_v[5] = {};
3111 u32 keytype;
3112
3113 ATH5K_TRACE(ah->ah_sc);
3114
3115 /* key->keylen comes in from mac80211 in bytes */
3116
3117 if (key->keylen > AR5K_KEYTABLE_SIZE / 8)
3118 return -EOPNOTSUPP;
3119
3120 switch (key->keylen) {
3121 /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */
3122 case 40 / 8:
3123 memcpy(&key_v[0], key->key, 5);
3124 keytype = AR5K_KEYTABLE_TYPE_40;
3125 break;
3126
3127 /* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */
3128 case 104 / 8:
3129 memcpy(&key_v[0], &key->key[0], 6);
3130 memcpy(&key_v[2], &key->key[6], 6);
3131 memcpy(&key_v[4], &key->key[12], 1);
3132 keytype = AR5K_KEYTABLE_TYPE_104;
3133 break;
3134 /* WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */
3135 case 128 / 8:
3136 memcpy(&key_v[0], &key->key[0], 6);
3137 memcpy(&key_v[2], &key->key[6], 6);
3138 memcpy(&key_v[4], &key->key[12], 4);
3139 keytype = AR5K_KEYTABLE_TYPE_128;
3140 break;
3141
3142 default:
3143 return -EINVAL; /* shouldn't happen */
3144 }
3145
3146 for (i = 0; i < ARRAY_SIZE(key_v); i++)
3147 ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
3148 AR5K_KEYTABLE_OFF(entry, i));
3149
3150 ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
3151
3152 return ath5k_hw_set_key_lladdr(ah, entry, mac);
3153}
3154
3155int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
3156{
3157 u32 low_id, high_id;
3158
3159 ATH5K_TRACE(ah->ah_sc);
3160 /* Invalid entry (key table overflow) */
3161 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
3162
3163 /* MAC may be NULL if it's a broadcast key. In this case no need to
3164 * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
3165 if (unlikely(mac == NULL)) {
3166 low_id = 0xffffffff;
3167 high_id = 0xffff | AR5K_KEYTABLE_VALID;
3168 } else {
3169 low_id = AR5K_LOW_ID(mac);
3170 high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
3171 }
3172
3173 ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
3174 ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
3175
3176 return 0;
3177}
3178
3179
3180/********************************************\
3181Queue Control Unit, DFS Control Unit Functions
3182\********************************************/
3183
3184/*
3185 * Initialize a transmit queue
3186 */
3187int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
3188 struct ath5k_txq_info *queue_info)
3189{
3190 unsigned int queue;
3191 int ret;
3192
3193 ATH5K_TRACE(ah->ah_sc);
3194
3195 /*
3196 * Get queue by type
3197 */
3198 /*5210 only has 2 queues*/
3199 if (ah->ah_version == AR5K_AR5210) {
3200 switch (queue_type) {
3201 case AR5K_TX_QUEUE_DATA:
3202 queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
3203 break;
3204 case AR5K_TX_QUEUE_BEACON:
3205 case AR5K_TX_QUEUE_CAB:
3206 queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
3207 break;
3208 default:
3209 return -EINVAL;
3210 }
3211 } else {
3212 switch (queue_type) {
3213 case AR5K_TX_QUEUE_DATA:
3214 for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
3215 ah->ah_txq[queue].tqi_type !=
3216 AR5K_TX_QUEUE_INACTIVE; queue++) {
3217
3218 if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
3219 return -EINVAL;
3220 }
3221 break;
3222 case AR5K_TX_QUEUE_UAPSD:
3223 queue = AR5K_TX_QUEUE_ID_UAPSD;
3224 break;
3225 case AR5K_TX_QUEUE_BEACON:
3226 queue = AR5K_TX_QUEUE_ID_BEACON;
3227 break;
3228 case AR5K_TX_QUEUE_CAB:
3229 queue = AR5K_TX_QUEUE_ID_CAB;
3230 break;
3231 case AR5K_TX_QUEUE_XR_DATA:
3232 if (ah->ah_version != AR5K_AR5212)
3233 ATH5K_ERR(ah->ah_sc,
3234 "XR data queues only supported in"
3235 " 5212!\n");
3236 queue = AR5K_TX_QUEUE_ID_XR_DATA;
3237 break;
3238 default:
3239 return -EINVAL;
3240 }
3241 }
3242
3243 /*
3244 * Setup internal queue structure
3245 */
3246 memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
3247 ah->ah_txq[queue].tqi_type = queue_type;
3248
3249 if (queue_info != NULL) {
3250 queue_info->tqi_type = queue_type;
3251 ret = ath5k_hw_setup_tx_queueprops(ah, queue, queue_info);
3252 if (ret)
3253 return ret;
3254 }
3255 /*
3256 * We use ah_txq_status to hold a temp value for
3257 * the Secondary interrupt mask registers on 5211+
3258 * check out ath5k_hw_reset_tx_queue
3259 */
3260 AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
3261
3262 return queue;
3263}
3264
3265/*
3266 * Setup a transmit queue
3267 */
3268int ath5k_hw_setup_tx_queueprops(struct ath5k_hw *ah, int queue,
3269 const struct ath5k_txq_info *queue_info)
3270{
3271 ATH5K_TRACE(ah->ah_sc);
3272 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3273
3274 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
3275 return -EIO;
3276
3277 memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
3278
3279 /*XXX: Is this supported on 5210 ?*/
3280 if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
3281 ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
3282 (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
3283 queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
3284 ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
3285
3286 return 0;
3287}
3288
3289/*
3290 * Get properties for a specific transmit queue
3291 */
3292int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
3293 struct ath5k_txq_info *queue_info)
3294{
3295 ATH5K_TRACE(ah->ah_sc);
3296 memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
3297 return 0;
3298}
3299
3300/*
3301 * Set a transmit queue inactive
3302 */
3303void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
3304{
3305 ATH5K_TRACE(ah->ah_sc);
3306 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
3307 return;
3308
3309 /* This queue will be skipped in further operations */
3310 ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
3311 /*For SIMR setup*/
3312 AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
3313}
3314
3315/*
3316 * Set DFS params for a transmit queue
3317 */
3318int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
3319{
3320 u32 cw_min, cw_max, retry_lg, retry_sh;
3321 struct ath5k_txq_info *tq = &ah->ah_txq[queue];
3322
3323 ATH5K_TRACE(ah->ah_sc);
3324 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3325
3326 tq = &ah->ah_txq[queue];
3327
3328 if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
3329 return 0;
3330
3331 if (ah->ah_version == AR5K_AR5210) {
3332 /* Only handle data queues, others will be ignored */
3333 if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
3334 return 0;
3335
3336 /* Set Slot time */
Joe Perchese9010e22008-03-07 14:21:16 -08003337 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003338 AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
3339 AR5K_SLOT_TIME);
3340 /* Set ACK_CTS timeout */
Joe Perchese9010e22008-03-07 14:21:16 -08003341 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003342 AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
3343 AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
3344 /* Set Transmit Latency */
Joe Perchese9010e22008-03-07 14:21:16 -08003345 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003346 AR5K_INIT_TRANSMIT_LATENCY_TURBO :
3347 AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
3348 /* Set IFS0 */
Joe Perchese9010e22008-03-07 14:21:16 -08003349 if (ah->ah_turbo)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003350 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
3351 (ah->ah_aifs + tq->tqi_aifs) *
3352 AR5K_INIT_SLOT_TIME_TURBO) <<
3353 AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
3354 AR5K_IFS0);
3355 else
3356 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
3357 (ah->ah_aifs + tq->tqi_aifs) *
3358 AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
3359 AR5K_INIT_SIFS, AR5K_IFS0);
3360
3361 /* Set IFS1 */
Joe Perchese9010e22008-03-07 14:21:16 -08003362 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003363 AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
3364 AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
Nick Kossifidis0bacdf32008-07-30 13:18:59 +03003365 /* Set AR5K_PHY_SETTLING */
Joe Perchese9010e22008-03-07 14:21:16 -08003366 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Nick Kossifidis0bacdf32008-07-30 13:18:59 +03003367 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
3368 | 0x38 :
3369 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
3370 | 0x1C,
3371 AR5K_PHY_SETTLING);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003372 /* Set Frame Control Register */
Joe Perchese9010e22008-03-07 14:21:16 -08003373 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003374 (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
3375 AR5K_PHY_TURBO_SHORT | 0x2020) :
3376 (AR5K_PHY_FRAME_CTL_INI | 0x1020),
3377 AR5K_PHY_FRAME_CTL_5210);
3378 }
3379
3380 /*
3381 * Calculate cwmin/max by channel mode
3382 */
3383 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
3384 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
3385 ah->ah_aifs = AR5K_TUNE_AIFS;
3386 /*XR is only supported on 5212*/
3387 if (IS_CHAN_XR(ah->ah_current_channel) &&
3388 ah->ah_version == AR5K_AR5212) {
3389 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
3390 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
3391 ah->ah_aifs = AR5K_TUNE_AIFS_XR;
3392 /*B mode is not supported on 5210*/
3393 } else if (IS_CHAN_B(ah->ah_current_channel) &&
3394 ah->ah_version != AR5K_AR5210) {
3395 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
3396 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
3397 ah->ah_aifs = AR5K_TUNE_AIFS_11B;
3398 }
3399
3400 cw_min = 1;
3401 while (cw_min < ah->ah_cw_min)
3402 cw_min = (cw_min << 1) | 1;
3403
3404 cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
3405 ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
3406 cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
3407 ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
3408
3409 /*
3410 * Calculate and set retry limits
3411 */
Joe Perchese9010e22008-03-07 14:21:16 -08003412 if (ah->ah_software_retry) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003413 /* XXX Need to test this */
3414 retry_lg = ah->ah_limit_tx_retries;
3415 retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
3416 AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
3417 } else {
3418 retry_lg = AR5K_INIT_LG_RETRY;
3419 retry_sh = AR5K_INIT_SH_RETRY;
3420 }
3421
3422 /*No QCU/DCU [5210]*/
3423 if (ah->ah_version == AR5K_AR5210) {
3424 ath5k_hw_reg_write(ah,
3425 (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
3426 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
3427 AR5K_NODCU_RETRY_LMT_SLG_RETRY)
3428 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
3429 AR5K_NODCU_RETRY_LMT_SSH_RETRY)
3430 | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
3431 | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
3432 AR5K_NODCU_RETRY_LMT);
3433 } else {
3434 /*QCU/DCU [5211+]*/
3435 ath5k_hw_reg_write(ah,
3436 AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
3437 AR5K_DCU_RETRY_LMT_SLG_RETRY) |
3438 AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
3439 AR5K_DCU_RETRY_LMT_SSH_RETRY) |
3440 AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
3441 AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
3442 AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
3443
3444 /*===Rest is also for QCU/DCU only [5211+]===*/
3445
3446 /*
3447 * Set initial content window (cw_min/cw_max)
3448 * and arbitrated interframe space (aifs)...
3449 */
3450 ath5k_hw_reg_write(ah,
3451 AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
3452 AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
3453 AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
3454 AR5K_DCU_LCL_IFS_AIFS),
3455 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
3456
3457 /*
3458 * Set misc registers
3459 */
3460 ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY,
3461 AR5K_QUEUE_MISC(queue));
3462
3463 if (tq->tqi_cbr_period) {
3464 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
3465 AR5K_QCU_CBRCFG_INTVAL) |
3466 AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
3467 AR5K_QCU_CBRCFG_ORN_THRES),
3468 AR5K_QUEUE_CBRCFG(queue));
3469 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3470 AR5K_QCU_MISC_FRSHED_CBR);
3471 if (tq->tqi_cbr_overflow_limit)
3472 AR5K_REG_ENABLE_BITS(ah,
3473 AR5K_QUEUE_MISC(queue),
3474 AR5K_QCU_MISC_CBR_THRES_ENABLE);
3475 }
3476
3477 if (tq->tqi_ready_time)
3478 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
3479 AR5K_QCU_RDYTIMECFG_INTVAL) |
3480 AR5K_QCU_RDYTIMECFG_ENABLE,
3481 AR5K_QUEUE_RDYTIMECFG(queue));
3482
3483 if (tq->tqi_burst_time) {
3484 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
3485 AR5K_DCU_CHAN_TIME_DUR) |
3486 AR5K_DCU_CHAN_TIME_ENABLE,
3487 AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
3488
3489 if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
3490 AR5K_REG_ENABLE_BITS(ah,
3491 AR5K_QUEUE_MISC(queue),
3492 AR5K_QCU_MISC_TXE);
3493 }
3494
3495 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
3496 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
3497 AR5K_QUEUE_DFS_MISC(queue));
3498
3499 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
3500 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
3501 AR5K_QUEUE_DFS_MISC(queue));
3502
3503 /*
3504 * Set registers by queue type
3505 */
3506 switch (tq->tqi_type) {
3507 case AR5K_TX_QUEUE_BEACON:
3508 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3509 AR5K_QCU_MISC_FRSHED_DBA_GT |
3510 AR5K_QCU_MISC_CBREXP_BCN |
3511 AR5K_QCU_MISC_BCN_ENABLE);
3512
3513 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
3514 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
3515 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
3516 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
3517 AR5K_DCU_MISC_BCN_ENABLE);
3518
3519 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
3520 (AR5K_TUNE_SW_BEACON_RESP -
3521 AR5K_TUNE_DMA_BEACON_RESP) -
3522 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
3523 AR5K_QCU_RDYTIMECFG_ENABLE,
3524 AR5K_QUEUE_RDYTIMECFG(queue));
3525 break;
3526
3527 case AR5K_TX_QUEUE_CAB:
3528 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3529 AR5K_QCU_MISC_FRSHED_DBA_GT |
3530 AR5K_QCU_MISC_CBREXP |
3531 AR5K_QCU_MISC_CBREXP_BCN);
3532
3533 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
3534 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
3535 AR5K_DCU_MISC_ARBLOCK_CTL_S));
3536 break;
3537
3538 case AR5K_TX_QUEUE_UAPSD:
3539 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3540 AR5K_QCU_MISC_CBREXP);
3541 break;
3542
3543 case AR5K_TX_QUEUE_DATA:
3544 default:
3545 break;
3546 }
3547
3548 /*
3549 * Enable interrupts for this tx queue
3550 * in the secondary interrupt mask registers
3551 */
3552 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
3553 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
3554
3555 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
3556 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
3557
3558 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
3559 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
3560
3561 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
3562 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
3563
3564 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
3565 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
3566
3567
3568 /* Update secondary interrupt mask registers */
3569 ah->ah_txq_imr_txok &= ah->ah_txq_status;
3570 ah->ah_txq_imr_txerr &= ah->ah_txq_status;
3571 ah->ah_txq_imr_txurn &= ah->ah_txq_status;
3572 ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
3573 ah->ah_txq_imr_txeol &= ah->ah_txq_status;
3574
3575 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
3576 AR5K_SIMR0_QCU_TXOK) |
3577 AR5K_REG_SM(ah->ah_txq_imr_txdesc,
3578 AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
3579 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
3580 AR5K_SIMR1_QCU_TXERR) |
3581 AR5K_REG_SM(ah->ah_txq_imr_txeol,
3582 AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
3583 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txurn,
3584 AR5K_SIMR2_QCU_TXURN), AR5K_SIMR2);
3585 }
3586
3587 return 0;
3588}
3589
3590/*
3591 * Get number of pending frames
3592 * for a specific queue [5211+]
3593 */
3594u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) {
3595 ATH5K_TRACE(ah->ah_sc);
3596 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3597
3598 /* Return if queue is declared inactive */
3599 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
3600 return false;
3601
3602 /* XXX: How about AR5K_CFG_TXCNT ? */
3603 if (ah->ah_version == AR5K_AR5210)
3604 return false;
3605
3606 return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT;
3607}
3608
3609/*
3610 * Set slot time
3611 */
3612int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
3613{
3614 ATH5K_TRACE(ah->ah_sc);
3615 if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
3616 return -EINVAL;
3617
3618 if (ah->ah_version == AR5K_AR5210)
3619 ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
3620 ah->ah_turbo), AR5K_SLOT_TIME);
3621 else
3622 ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
3623
3624 return 0;
3625}
3626
3627/*
3628 * Get slot time
3629 */
3630unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
3631{
3632 ATH5K_TRACE(ah->ah_sc);
3633 if (ah->ah_version == AR5K_AR5210)
3634 return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
3635 AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
3636 else
3637 return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
3638}
3639
3640
3641/******************************\
3642 Hardware Descriptor Functions
3643\******************************/
3644
3645/*
3646 * TX Descriptor
3647 */
3648
3649/*
3650 * Initialize the 2-word tx descriptor on 5210/5211
3651 */
3652static int
3653ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3654 unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type,
3655 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
3656 unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
3657 unsigned int rtscts_rate, unsigned int rtscts_duration)
3658{
3659 u32 frame_type;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003660 struct ath5k_hw_2w_tx_ctl *tx_ctl;
Bruno Randolf281c56d2008-02-05 18:44:55 +09003661 unsigned int frame_len;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003662
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003663 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003664
3665 /*
3666 * Validate input
3667 * - Zero retries don't make sense.
3668 * - A zero rate will put the HW into a mode where it continously sends
3669 * noise on the channel, so it is important to avoid this.
3670 */
3671 if (unlikely(tx_tries0 == 0)) {
3672 ATH5K_ERR(ah->ah_sc, "zero retries\n");
3673 WARN_ON(1);
3674 return -EINVAL;
3675 }
3676 if (unlikely(tx_rate0 == 0)) {
3677 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3678 WARN_ON(1);
3679 return -EINVAL;
3680 }
3681
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003682 /* Clear descriptor */
3683 memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003684
3685 /* Setup control descriptor */
3686
3687 /* Verify and set frame length */
Bruno Randolf281c56d2008-02-05 18:44:55 +09003688
3689 /* remove padding we might have added before */
3690 frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
3691
3692 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003693 return -EINVAL;
3694
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003695 tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003696
3697 /* Verify and set buffer length */
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003698
3699 /* NB: beacon's BufLen must be a multiple of 4 bytes */
3700 if(type == AR5K_PKT_TYPE_BEACON)
Bruno Randolf281c56d2008-02-05 18:44:55 +09003701 pkt_len = roundup(pkt_len, 4);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003702
Bruno Randolf281c56d2008-02-05 18:44:55 +09003703 if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003704 return -EINVAL;
3705
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003706 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003707
3708 /*
3709 * Verify and set header length
3710 * XXX: I only found that on 5210 code, does it work on 5211 ?
3711 */
3712 if (ah->ah_version == AR5K_AR5210) {
3713 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
3714 return -EINVAL;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003715 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003716 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
3717 }
3718
3719 /*Diferences between 5210-5211*/
3720 if (ah->ah_version == AR5K_AR5210) {
3721 switch (type) {
3722 case AR5K_PKT_TYPE_BEACON:
3723 case AR5K_PKT_TYPE_PROBE_RESP:
3724 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
3725 case AR5K_PKT_TYPE_PIFS:
3726 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
3727 default:
3728 frame_type = type /*<< 2 ?*/;
3729 }
3730
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003731 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003732 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
3733 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3734 } else {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003735 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003736 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
3737 AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003738 tx_ctl->tx_control_1 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003739 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
3740 }
3741#define _TX_FLAGS(_c, _flag) \
3742 if (flags & AR5K_TXDESC_##_flag) \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003743 tx_ctl->tx_control_##_c |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003744 AR5K_2W_TX_DESC_CTL##_c##_##_flag
3745
3746 _TX_FLAGS(0, CLRDMASK);
3747 _TX_FLAGS(0, VEOL);
3748 _TX_FLAGS(0, INTREQ);
3749 _TX_FLAGS(0, RTSENA);
3750 _TX_FLAGS(1, NOACK);
3751
3752#undef _TX_FLAGS
3753
3754 /*
3755 * WEP crap
3756 */
3757 if (key_index != AR5K_TXKEYIX_INVALID) {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003758 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003759 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003760 tx_ctl->tx_control_1 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003761 AR5K_REG_SM(key_index,
3762 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3763 }
3764
3765 /*
3766 * RTS/CTS Duration [5210 ?]
3767 */
3768 if ((ah->ah_version == AR5K_AR5210) &&
3769 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003770 tx_ctl->tx_control_1 |= rtscts_duration &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003771 AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
3772
3773 return 0;
3774}
3775
3776/*
3777 * Initialize the 4-word tx descriptor on 5212
3778 */
3779static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
3780 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
3781 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
3782 unsigned int tx_tries0, unsigned int key_index,
3783 unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate,
3784 unsigned int rtscts_duration)
3785{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003786 struct ath5k_hw_4w_tx_ctl *tx_ctl;
Bruno Randolf281c56d2008-02-05 18:44:55 +09003787 unsigned int frame_len;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003788
3789 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003790 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003791
3792 /*
3793 * Validate input
3794 * - Zero retries don't make sense.
3795 * - A zero rate will put the HW into a mode where it continously sends
3796 * noise on the channel, so it is important to avoid this.
3797 */
3798 if (unlikely(tx_tries0 == 0)) {
3799 ATH5K_ERR(ah->ah_sc, "zero retries\n");
3800 WARN_ON(1);
3801 return -EINVAL;
3802 }
3803 if (unlikely(tx_rate0 == 0)) {
3804 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3805 WARN_ON(1);
3806 return -EINVAL;
3807 }
3808
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003809 /* Clear descriptor */
3810 memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003811
3812 /* Setup control descriptor */
3813
3814 /* Verify and set frame length */
Bruno Randolf281c56d2008-02-05 18:44:55 +09003815
3816 /* remove padding we might have added before */
3817 frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
3818
3819 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003820 return -EINVAL;
3821
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003822 tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003823
3824 /* Verify and set buffer length */
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003825
3826 /* NB: beacon's BufLen must be a multiple of 4 bytes */
3827 if(type == AR5K_PKT_TYPE_BEACON)
Bruno Randolf281c56d2008-02-05 18:44:55 +09003828 pkt_len = roundup(pkt_len, 4);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003829
Bruno Randolf281c56d2008-02-05 18:44:55 +09003830 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003831 return -EINVAL;
3832
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003833 tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003834
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003835 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003836 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
3837 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003838 tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003839 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003840 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003841 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003842 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003843
3844#define _TX_FLAGS(_c, _flag) \
3845 if (flags & AR5K_TXDESC_##_flag) \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003846 tx_ctl->tx_control_##_c |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003847 AR5K_4W_TX_DESC_CTL##_c##_##_flag
3848
3849 _TX_FLAGS(0, CLRDMASK);
3850 _TX_FLAGS(0, VEOL);
3851 _TX_FLAGS(0, INTREQ);
3852 _TX_FLAGS(0, RTSENA);
3853 _TX_FLAGS(0, CTSENA);
3854 _TX_FLAGS(1, NOACK);
3855
3856#undef _TX_FLAGS
3857
3858 /*
3859 * WEP crap
3860 */
3861 if (key_index != AR5K_TXKEYIX_INVALID) {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003862 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
3863 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003864 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3865 }
3866
3867 /*
3868 * RTS/CTS
3869 */
3870 if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
3871 if ((flags & AR5K_TXDESC_RTSENA) &&
3872 (flags & AR5K_TXDESC_CTSENA))
3873 return -EINVAL;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003874 tx_ctl->tx_control_2 |= rtscts_duration &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003875 AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003876 tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003877 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
3878 }
3879
3880 return 0;
3881}
3882
3883/*
3884 * Initialize a 4-word multirate tx descriptor on 5212
3885 */
Jiri Slabyb9887632008-02-15 21:58:52 +01003886static int
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003887ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3888 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
3889 unsigned int tx_rate3, u_int tx_tries3)
3890{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003891 struct ath5k_hw_4w_tx_ctl *tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003892
3893 /*
3894 * Rates can be 0 as long as the retry count is 0 too.
3895 * A zero rate and nonzero retry count will put the HW into a mode where
3896 * it continously sends noise on the channel, so it is important to
3897 * avoid this.
3898 */
3899 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
3900 (tx_rate2 == 0 && tx_tries2 != 0) ||
3901 (tx_rate3 == 0 && tx_tries3 != 0))) {
3902 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3903 WARN_ON(1);
3904 return -EINVAL;
3905 }
3906
3907 if (ah->ah_version == AR5K_AR5212) {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003908 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003909
3910#define _XTX_TRIES(_n) \
3911 if (tx_tries##_n) { \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003912 tx_ctl->tx_control_2 |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003913 AR5K_REG_SM(tx_tries##_n, \
3914 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003915 tx_ctl->tx_control_3 |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003916 AR5K_REG_SM(tx_rate##_n, \
3917 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \
3918 }
3919
3920 _XTX_TRIES(1);
3921 _XTX_TRIES(2);
3922 _XTX_TRIES(3);
3923
3924#undef _XTX_TRIES
3925
Jiri Slabyb9887632008-02-15 21:58:52 +01003926 return 1;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003927 }
3928
Jiri Slabyb9887632008-02-15 21:58:52 +01003929 return 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003930}
3931
3932/*
3933 * Proccess the tx status descriptor on 5210/5211
3934 */
3935static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09003936 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003937{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003938 struct ath5k_hw_2w_tx_ctl *tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003939 struct ath5k_hw_tx_status *tx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003940
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003941 ATH5K_TRACE(ah->ah_sc);
3942
3943 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
3944 tx_status = &desc->ud.ds_tx5210.tx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003945
3946 /* No frame has been send or error */
3947 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
3948 return -EINPROGRESS;
3949
3950 /*
3951 * Get descriptor status
3952 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09003953 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003954 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003955 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003956 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003957 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003958 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003959 /*TODO: ts->ts_virtcol + test*/
3960 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003961 AR5K_DESC_TX_STATUS1_SEQ_NUM);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003962 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003963 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003964 ts->ts_antenna = 1;
3965 ts->ts_status = 0;
3966 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003967 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3968
3969 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
3970 if (tx_status->tx_status_0 &
3971 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003972 ts->ts_status |= AR5K_TXERR_XRETRY;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003973
3974 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003975 ts->ts_status |= AR5K_TXERR_FIFO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003976
3977 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003978 ts->ts_status |= AR5K_TXERR_FILT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003979 }
3980
3981 return 0;
3982}
3983
3984/*
3985 * Proccess a tx descriptor on 5212
3986 */
3987static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09003988 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003989{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003990 struct ath5k_hw_4w_tx_ctl *tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003991 struct ath5k_hw_tx_status *tx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003992
3993 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003994
3995 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
3996 tx_status = &desc->ud.ds_tx5212.tx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003997
3998 /* No frame has been send or error */
3999 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
4000 return -EINPROGRESS;
4001
4002 /*
4003 * Get descriptor status
4004 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09004005 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004006 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004007 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004008 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004009 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004010 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004011 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004012 AR5K_DESC_TX_STATUS1_SEQ_NUM);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004013 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004014 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004015 ts->ts_antenna = (tx_status->tx_status_1 &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004016 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004017 ts->ts_status = 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004018
4019 switch (AR5K_REG_MS(tx_status->tx_status_1,
4020 AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
4021 case 0:
Bruno Randolfb47f4072008-03-05 18:35:45 +09004022 ts->ts_rate = tx_ctl->tx_control_3 &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004023 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
4024 break;
4025 case 1:
Bruno Randolfb47f4072008-03-05 18:35:45 +09004026 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004027 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004028 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004029 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
4030 break;
4031 case 2:
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_RATE2);
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_TRIES2);
4036 break;
4037 case 3:
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_RATE3);
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_TRIES3);
4042 break;
4043 }
4044
4045 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
4046 if (tx_status->tx_status_0 &
4047 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004048 ts->ts_status |= AR5K_TXERR_XRETRY;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004049
4050 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004051 ts->ts_status |= AR5K_TXERR_FIFO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004052
4053 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004054 ts->ts_status |= AR5K_TXERR_FILT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004055 }
4056
4057 return 0;
4058}
4059
4060/*
4061 * RX Descriptor
4062 */
4063
4064/*
4065 * Initialize an rx descriptor
4066 */
4067int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
4068 u32 size, unsigned int flags)
4069{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004070 struct ath5k_hw_rx_ctl *rx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004071
4072 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004073 rx_ctl = &desc->ud.ds_rx.rx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004074
4075 /*
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004076 * Clear the descriptor
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004077 * If we don't clean the status descriptor,
4078 * while scanning we get too many results,
4079 * most of them virtual, after some secs
4080 * of scanning system hangs. M.F.
4081 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004082 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004083
4084 /* Setup descriptor */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004085 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
4086 if (unlikely(rx_ctl->rx_control_1 != size))
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004087 return -EINVAL;
4088
4089 if (flags & AR5K_RXDESC_INTREQ)
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004090 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004091
4092 return 0;
4093}
4094
4095/*
4096 * Proccess the rx status descriptor on 5210/5211
4097 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004098static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09004099 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004100{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004101 struct ath5k_hw_rx_status *rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004102
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004103 rx_status = &desc->ud.ds_rx.u.rx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004104
4105 /* No frame received / not ready */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004106 if (unlikely((rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_DONE)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004107 == 0))
4108 return -EINPROGRESS;
4109
4110 /*
4111 * Frame receive status
4112 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09004113 rs->rs_datalen = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004114 AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004115 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004116 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004117 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004118 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004119 rs->rs_antenna = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004120 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004121 rs->rs_more = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004122 AR5K_5210_RX_DESC_STATUS0_MORE;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004123 /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
4124 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004125 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004126 rs->rs_status = 0;
Bob Copelandd6894b52008-05-12 21:16:44 -04004127 rs->rs_phyerr = 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004128
4129 /*
4130 * Key table status
4131 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004132 if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004133 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004134 AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004135 else
Bruno Randolfb47f4072008-03-05 18:35:45 +09004136 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004137
4138 /*
4139 * Receive/descriptor errors
4140 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004141 if ((rx_status->rx_status_1 &
4142 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
4143 if (rx_status->rx_status_1 &
4144 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004145 rs->rs_status |= AR5K_RXERR_CRC;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004146
4147 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004148 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004149 rs->rs_status |= AR5K_RXERR_FIFO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004150
4151 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004152 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
Bruno Randolfb47f4072008-03-05 18:35:45 +09004153 rs->rs_status |= AR5K_RXERR_PHY;
Bob Copelandd6894b52008-05-12 21:16:44 -04004154 rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolfb47f4072008-03-05 18:35:45 +09004155 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004156 }
4157
4158 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004159 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004160 rs->rs_status |= AR5K_RXERR_DECRYPT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004161 }
4162
4163 return 0;
4164}
4165
4166/*
4167 * Proccess the rx status descriptor on 5212
4168 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004169static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09004170 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004171{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004172 struct ath5k_hw_rx_status *rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004173 struct ath5k_hw_rx_error *rx_err;
4174
4175 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004176 rx_status = &desc->ud.ds_rx.u.rx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004177
4178 /* Overlay on error */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004179 rx_err = &desc->ud.ds_rx.u.rx_err;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004180
4181 /* No frame received / not ready */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004182 if (unlikely((rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_DONE)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004183 == 0))
4184 return -EINPROGRESS;
4185
4186 /*
4187 * Frame receive status
4188 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09004189 rs->rs_datalen = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004190 AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004191 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004192 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004193 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004194 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004195 rs->rs_antenna = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004196 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004197 rs->rs_more = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004198 AR5K_5212_RX_DESC_STATUS0_MORE;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004199 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004200 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004201 rs->rs_status = 0;
Bob Copelandd6894b52008-05-12 21:16:44 -04004202 rs->rs_phyerr = 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004203
4204 /*
4205 * Key table status
4206 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004207 if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004208 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004209 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004210 else
Bruno Randolfb47f4072008-03-05 18:35:45 +09004211 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004212
4213 /*
4214 * Receive/descriptor errors
4215 */
4216 if ((rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004217 AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
4218 if (rx_status->rx_status_1 &
4219 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004220 rs->rs_status |= AR5K_RXERR_CRC;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004221
4222 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004223 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
Bruno Randolfb47f4072008-03-05 18:35:45 +09004224 rs->rs_status |= AR5K_RXERR_PHY;
Bob Copelandd6894b52008-05-12 21:16:44 -04004225 rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
Bruno Randolfb47f4072008-03-05 18:35:45 +09004226 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004227 }
4228
4229 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004230 AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004231 rs->rs_status |= AR5K_RXERR_DECRYPT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004232
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004233 if (rx_status->rx_status_1 &
4234 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004235 rs->rs_status |= AR5K_RXERR_MIC;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004236 }
4237
4238 return 0;
4239}
4240
4241
4242/****************\
4243 GPIO Functions
4244\****************/
4245
4246/*
4247 * Set led state
4248 */
4249void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
4250{
4251 u32 led;
4252 /*5210 has different led mode handling*/
4253 u32 led_5210;
4254
4255 ATH5K_TRACE(ah->ah_sc);
4256
4257 /*Reset led status*/
4258 if (ah->ah_version != AR5K_AR5210)
4259 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
4260 AR5K_PCICFG_LEDMODE | AR5K_PCICFG_LED);
4261 else
4262 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED);
4263
4264 /*
4265 * Some blinking values, define at your wish
4266 */
4267 switch (state) {
4268 case AR5K_LED_SCAN:
4269 case AR5K_LED_AUTH:
4270 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND;
4271 led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL;
4272 break;
4273
4274 case AR5K_LED_INIT:
4275 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE;
4276 led_5210 = AR5K_PCICFG_LED_PEND;
4277 break;
4278
4279 case AR5K_LED_ASSOC:
4280 case AR5K_LED_RUN:
4281 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC;
4282 led_5210 = AR5K_PCICFG_LED_ASSOC;
4283 break;
4284
4285 default:
4286 led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE;
4287 led_5210 = AR5K_PCICFG_LED_PEND;
4288 break;
4289 }
4290
4291 /*Write new status to the register*/
4292 if (ah->ah_version != AR5K_AR5210)
4293 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led);
4294 else
4295 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210);
4296}
4297
4298/*
4299 * Set GPIO outputs
4300 */
4301int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
4302{
4303 ATH5K_TRACE(ah->ah_sc);
4304 if (gpio > AR5K_NUM_GPIO)
4305 return -EINVAL;
4306
4307 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~
4308 AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
4309
4310 return 0;
4311}
4312
4313/*
4314 * Set GPIO inputs
4315 */
4316int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
4317{
4318 ATH5K_TRACE(ah->ah_sc);
4319 if (gpio > AR5K_NUM_GPIO)
4320 return -EINVAL;
4321
4322 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~
4323 AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
4324
4325 return 0;
4326}
4327
4328/*
4329 * Get GPIO state
4330 */
4331u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
4332{
4333 ATH5K_TRACE(ah->ah_sc);
4334 if (gpio > AR5K_NUM_GPIO)
4335 return 0xffffffff;
4336
4337 /* GPIO input magic */
4338 return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
4339 0x1;
4340}
4341
4342/*
4343 * Set GPIO state
4344 */
4345int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
4346{
4347 u32 data;
4348 ATH5K_TRACE(ah->ah_sc);
4349
4350 if (gpio > AR5K_NUM_GPIO)
4351 return -EINVAL;
4352
4353 /* GPIO output magic */
4354 data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
4355
4356 data &= ~(1 << gpio);
4357 data |= (val & 1) << gpio;
4358
4359 ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
4360
4361 return 0;
4362}
4363
4364/*
4365 * Initialize the GPIO interrupt (RFKill switch)
4366 */
4367void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
4368 u32 interrupt_level)
4369{
4370 u32 data;
4371
4372 ATH5K_TRACE(ah->ah_sc);
4373 if (gpio > AR5K_NUM_GPIO)
4374 return;
4375
4376 /*
4377 * Set the GPIO interrupt
4378 */
4379 data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
4380 ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
4381 AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
4382 (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
4383
4384 ath5k_hw_reg_write(ah, interrupt_level ? data :
4385 (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
4386
4387 ah->ah_imr |= AR5K_IMR_GPIO;
4388
4389 /* Enable GPIO interrupts */
4390 AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
4391}
4392
4393
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004394
4395
4396/****************\
4397 Misc functions
4398\****************/
4399
4400int ath5k_hw_get_capability(struct ath5k_hw *ah,
4401 enum ath5k_capability_type cap_type,
4402 u32 capability, u32 *result)
4403{
4404 ATH5K_TRACE(ah->ah_sc);
4405
4406 switch (cap_type) {
4407 case AR5K_CAP_NUM_TXQUEUES:
4408 if (result) {
4409 if (ah->ah_version == AR5K_AR5210)
4410 *result = AR5K_NUM_TX_QUEUES_NOQCU;
4411 else
4412 *result = AR5K_NUM_TX_QUEUES;
4413 goto yes;
4414 }
4415 case AR5K_CAP_VEOL:
4416 goto yes;
4417 case AR5K_CAP_COMPRESSION:
4418 if (ah->ah_version == AR5K_AR5212)
4419 goto yes;
4420 else
4421 goto no;
4422 case AR5K_CAP_BURST:
4423 goto yes;
4424 case AR5K_CAP_TPC:
4425 goto yes;
4426 case AR5K_CAP_BSSIDMASK:
4427 if (ah->ah_version == AR5K_AR5212)
4428 goto yes;
4429 else
4430 goto no;
4431 case AR5K_CAP_XR:
4432 if (ah->ah_version == AR5K_AR5212)
4433 goto yes;
4434 else
4435 goto no;
4436 default:
4437 goto no;
4438 }
4439
4440no:
4441 return -EINVAL;
4442yes:
4443 return 0;
4444}
4445
4446static int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
4447 u16 assoc_id)
4448{
4449 ATH5K_TRACE(ah->ah_sc);
4450
4451 if (ah->ah_version == AR5K_AR5210) {
4452 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
4453 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
4454 return 0;
4455 }
4456
4457 return -EIO;
4458}
4459
4460static int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
4461{
4462 ATH5K_TRACE(ah->ah_sc);
4463
4464 if (ah->ah_version == AR5K_AR5210) {
4465 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
4466 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
4467 return 0;
4468 }
4469
4470 return -EIO;
4471}