blob: 9e16bc09f1fd1a7b1d45a1b6b906a78f943fe003 [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
34/*Rate tables*/
35static 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
41/*Prototypes*/
42static 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/*
123 * Check if the device is supported and initialize the needed structs
124 */
125struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
126{
127 struct ath5k_hw *ah;
128 u8 mac[ETH_ALEN];
129 int ret;
130 u32 srev;
131
132 /*If we passed the test malloc a ath5k_hw struct*/
133 ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
134 if (ah == NULL) {
135 ret = -ENOMEM;
136 ATH5K_ERR(sc, "out of memory\n");
137 goto err;
138 }
139
140 ah->ah_sc = sc;
141 ah->ah_iobase = sc->iobase;
142
143 /*
144 * HW information
145 */
146
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200147 ah->ah_op_mode = IEEE80211_IF_TYPE_STA;
148 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
149 ah->ah_turbo = false;
150 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
151 ah->ah_imr = 0;
152 ah->ah_atim_window = 0;
153 ah->ah_aifs = AR5K_TUNE_AIFS;
154 ah->ah_cw_min = AR5K_TUNE_CWMIN;
155 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
156 ah->ah_software_retry = false;
157 ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
158
159 /*
160 * Set the mac revision based on the pci id
161 */
162 ah->ah_version = mac_version;
163
164 /*Fill the ath5k_hw struct with the needed functions*/
165 if (ah->ah_version == AR5K_AR5212)
166 ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
167 else if (ah->ah_version == AR5K_AR5211)
168 ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
169
170 if (ah->ah_version == AR5K_AR5212) {
171 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
172 ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
173 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
174 } else {
175 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
176 ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
177 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
178 }
179
180 if (ah->ah_version == AR5K_AR5212)
Bruno Randolf19fd6e52008-03-05 18:35:23 +0900181 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200182 else if (ah->ah_version <= AR5K_AR5211)
Bruno Randolf19fd6e52008-03-05 18:35:23 +0900183 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200184
185 /* Bring device out of sleep and reset it's units */
186 ret = ath5k_hw_nic_wakeup(ah, AR5K_INIT_MODE, true);
187 if (ret)
188 goto err_free;
189
190 /* Get MAC, PHY and RADIO revisions */
191 srev = ath5k_hw_reg_read(ah, AR5K_SREV);
192 ah->ah_mac_srev = srev;
193 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
194 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
195 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
196 0xffffffff;
197 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
198 CHANNEL_5GHZ);
199
200 if (ah->ah_version == AR5K_AR5210)
201 ah->ah_radio_2ghz_revision = 0;
202 else
203 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
204 CHANNEL_2GHZ);
205
206 /* Return on unsuported chips (unsupported eeprom etc) */
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300207 if (srev >= AR5K_SREV_VER_AR5416) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200208 ATH5K_ERR(sc, "Device not yet supported.\n");
209 ret = -ENODEV;
210 goto err_free;
211 }
212
213 /* Identify single chip solutions */
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300214 if (((srev <= AR5K_SREV_VER_AR5414) &&
215 (srev >= AR5K_SREV_VER_AR2413)) ||
216 (srev == AR5K_SREV_VER_AR2425)) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200217 ah->ah_single_chip = true;
218 } else {
219 ah->ah_single_chip = false;
220 }
221
222 /* Single chip radio */
223 if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision)
224 ah->ah_radio_2ghz_revision = 0;
225
226 /* Identify the radio chip*/
227 if (ah->ah_version == AR5K_AR5210) {
228 ah->ah_radio = AR5K_RF5110;
229 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
230 ah->ah_radio = AR5K_RF5111;
Nick Kossifidis0af22562008-02-28 14:49:05 -0500231 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
232 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
233
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200234 ah->ah_radio = AR5K_RF5112;
Nick Kossifidis0af22562008-02-28 14:49:05 -0500235
236 if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
237 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
238 } else {
239 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
240 }
241
242 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
243 ah->ah_radio = AR5K_RF2413;
244 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300245 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
Nick Kossifidis0af22562008-02-28 14:49:05 -0500246
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200247 ah->ah_radio = AR5K_RF5413;
Nick Kossifidis0af22562008-02-28 14:49:05 -0500248
249 if (ah->ah_mac_srev <= AR5K_SREV_VER_AR5424 &&
250 ah->ah_mac_srev >= AR5K_SREV_VER_AR2424)
251 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424;
Nick Kossifidis0af22562008-02-28 14:49:05 -0500252 else
253 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
254
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300255 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
256 ah->ah_radio = AR5K_RF2425;
257 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200258 }
259
260 ah->ah_phy = AR5K_PHY(0);
261
262 /*
263 * Get card capabilities, values, ...
264 */
265
266 ret = ath5k_eeprom_init(ah);
267 if (ret) {
268 ATH5K_ERR(sc, "unable to init EEPROM\n");
269 goto err_free;
270 }
271
272 /* Get misc capabilities */
273 ret = ath5k_hw_get_capabilities(ah);
274 if (ret) {
275 ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
276 sc->pdev->device);
277 goto err_free;
278 }
279
280 /* Get MAC address */
281 ret = ath5k_eeprom_read_mac(ah, mac);
282 if (ret) {
283 ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
284 sc->pdev->device);
285 goto err_free;
286 }
287
288 ath5k_hw_set_lladdr(ah, mac);
289 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
290 memset(ah->ah_bssid, 0xff, ETH_ALEN);
291 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
292 ath5k_hw_set_opmode(ah);
293
294 ath5k_hw_set_rfgain_opt(ah);
295
296 return ah;
297err_free:
298 kfree(ah);
299err:
300 return ERR_PTR(ret);
301}
302
303/*
304 * Bring up MAC + PHY Chips
305 */
306static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
307{
Nick Kossifidis56c90542008-02-28 16:20:52 -0500308 struct pci_dev *pdev = ah->ah_sc->pdev;
309 u32 turbo, mode, clock, bus_flags;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200310 int ret;
311
312 turbo = 0;
313 mode = 0;
314 clock = 0;
315
316 ATH5K_TRACE(ah->ah_sc);
317
318 /* Wakeup the device */
319 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
320 if (ret) {
321 ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
322 return ret;
323 }
324
325 if (ah->ah_version != AR5K_AR5210) {
326 /*
327 * Get channel mode flags
328 */
329
330 if (ah->ah_radio >= AR5K_RF5112) {
331 mode = AR5K_PHY_MODE_RAD_RF5112;
332 clock = AR5K_PHY_PLL_RF5112;
333 } else {
334 mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/
335 clock = AR5K_PHY_PLL_RF5111; /*Zero*/
336 }
337
338 if (flags & CHANNEL_2GHZ) {
339 mode |= AR5K_PHY_MODE_FREQ_2GHZ;
340 clock |= AR5K_PHY_PLL_44MHZ;
341
342 if (flags & CHANNEL_CCK) {
343 mode |= AR5K_PHY_MODE_MOD_CCK;
344 } else if (flags & CHANNEL_OFDM) {
345 /* XXX Dynamic OFDM/CCK is not supported by the
346 * AR5211 so we set MOD_OFDM for plain g (no
347 * CCK headers) operation. We need to test
348 * this, 5211 might support ofdm-only g after
349 * all, there are also initial register values
350 * in the code for g mode (see initvals.c). */
351 if (ah->ah_version == AR5K_AR5211)
352 mode |= AR5K_PHY_MODE_MOD_OFDM;
353 else
354 mode |= AR5K_PHY_MODE_MOD_DYN;
355 } else {
356 ATH5K_ERR(ah->ah_sc,
357 "invalid radio modulation mode\n");
358 return -EINVAL;
359 }
360 } else if (flags & CHANNEL_5GHZ) {
361 mode |= AR5K_PHY_MODE_FREQ_5GHZ;
362 clock |= AR5K_PHY_PLL_40MHZ;
363
364 if (flags & CHANNEL_OFDM)
365 mode |= AR5K_PHY_MODE_MOD_OFDM;
366 else {
367 ATH5K_ERR(ah->ah_sc,
368 "invalid radio modulation mode\n");
369 return -EINVAL;
370 }
371 } else {
372 ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
373 return -EINVAL;
374 }
375
376 if (flags & CHANNEL_TURBO)
377 turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
378 } else { /* Reset the device */
379
380 /* ...enable Atheros turbo mode if requested */
381 if (flags & CHANNEL_TURBO)
382 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
383 AR5K_PHY_TURBO);
384 }
385
Nick Kossifidis56c90542008-02-28 16:20:52 -0500386 /* reseting PCI on PCI-E cards results card to hang
387 * and always return 0xffff... so we ingore that flag
388 * for PCI-E cards */
389 bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
390
391 /* Reset chipset */
392 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
393 AR5K_RESET_CTL_BASEBAND | bus_flags);
394 if (ret) {
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300395 ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200396 return -EIO;
397 }
398
399 if (ah->ah_version == AR5K_AR5210)
400 udelay(2300);
401
402 /* ...wakeup again!*/
403 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
404 if (ret) {
405 ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
406 return ret;
407 }
408
409 /* ...final warm reset */
410 if (ath5k_hw_nic_reset(ah, 0)) {
411 ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
412 return -EIO;
413 }
414
415 if (ah->ah_version != AR5K_AR5210) {
416 /* ...set the PHY operating mode */
417 ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
418 udelay(300);
419
420 ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
421 ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
422 }
423
424 return 0;
425}
426
427/*
428 * Get the rate table for a specific operation mode
429 */
430const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah,
431 unsigned int mode)
432{
433 ATH5K_TRACE(ah->ah_sc);
434
435 if (!test_bit(mode, ah->ah_capabilities.cap_mode))
436 return NULL;
437
438 /* Get rate tables */
439 switch (mode) {
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500440 case AR5K_MODE_11A:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200441 return &ath5k_rt_11a;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500442 case AR5K_MODE_11A_TURBO:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200443 return &ath5k_rt_turbo;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500444 case AR5K_MODE_11B:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200445 return &ath5k_rt_11b;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500446 case AR5K_MODE_11G:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200447 return &ath5k_rt_11g;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500448 case AR5K_MODE_11G_TURBO:
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200449 return &ath5k_rt_xr;
450 }
451
452 return NULL;
453}
454
455/*
456 * Free the ath5k_hw struct
457 */
458void ath5k_hw_detach(struct ath5k_hw *ah)
459{
460 ATH5K_TRACE(ah->ah_sc);
461
Pavel Roskinf50e4a82008-03-12 16:13:31 -0400462 __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
463
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200464 if (ah->ah_rf_banks != NULL)
465 kfree(ah->ah_rf_banks);
466
467 /* assume interrupts are down */
468 kfree(ah);
469}
470
471/****************************\
472 Reset function and helpers
473\****************************/
474
475/**
476 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
477 *
478 * @ah: the &struct ath5k_hw
479 * @channel: the currently set channel upon reset
480 *
481 * Write the OFDM timings for the AR5212 upon reset. This is a helper for
482 * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
483 * depending on the bandwidth of the channel.
484 *
485 */
486static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
487 struct ieee80211_channel *channel)
488{
489 /* Get exponent and mantissa and set it */
490 u32 coef_scaled, coef_exp, coef_man,
491 ds_coef_exp, ds_coef_man, clock;
492
493 if (!(ah->ah_version == AR5K_AR5212) ||
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500494 !(channel->hw_value & CHANNEL_OFDM))
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200495 BUG();
496
497 /* Seems there are two PLLs, one for baseband sampling and one
498 * for tuning. Tuning basebands are 40 MHz or 80MHz when in
499 * turbo. */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500500 clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200501 coef_scaled = ((5 * (clock << 24)) / 2) /
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500502 channel->center_freq;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200503
504 for (coef_exp = 31; coef_exp > 0; coef_exp--)
505 if ((coef_scaled >> coef_exp) & 0x1)
506 break;
507
508 if (!coef_exp)
509 return -EINVAL;
510
511 coef_exp = 14 - (coef_exp - 24);
512 coef_man = coef_scaled +
513 (1 << (24 - coef_exp - 1));
514 ds_coef_man = coef_man >> (24 - coef_exp);
515 ds_coef_exp = coef_exp - 16;
516
517 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
518 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
519 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
520 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
521
522 return 0;
523}
524
525/**
526 * ath5k_hw_write_rate_duration - set rate duration during hw resets
527 *
528 * @ah: the &struct ath5k_hw
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500529 * @mode: one of enum ath5k_driver_mode
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200530 *
531 * Write the rate duration table for the current mode upon hw reset. This
532 * is a helper for ath5k_hw_reset(). It seems all this is doing is setting
533 * an ACK timeout for the hardware for the current mode for each rate. The
534 * rates which are capable of short preamble (802.11b rates 2Mbps, 5.5Mbps,
535 * and 11Mbps) have another register for the short preamble ACK timeout
536 * calculation.
537 *
538 */
539static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500540 unsigned int mode)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200541{
542 struct ath5k_softc *sc = ah->ah_sc;
543 const struct ath5k_rate_table *rt;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500544 struct ieee80211_rate srate = {};
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200545 unsigned int i;
546
547 /* Get rate table for the current operating mode */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500548 rt = ath5k_hw_get_rate_table(ah, mode);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200549
550 /* Write rate duration table */
551 for (i = 0; i < rt->rate_count; i++) {
552 const struct ath5k_rate *rate, *control_rate;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500553
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200554 u32 reg;
555 u16 tx_time;
556
557 rate = &rt->rates[i];
558 control_rate = &rt->rates[rate->control_rate];
559
560 /* Set ACK timeout */
561 reg = AR5K_RATE_DUR(rate->rate_code);
562
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500563 srate.bitrate = control_rate->rate_kbps/100;
564
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200565 /* An ACK frame consists of 10 bytes. If you add the FCS,
566 * which ieee80211_generic_frame_duration() adds,
567 * its 14 bytes. Note we use the control rate and not the
568 * actual rate for this rate. See mac80211 tx.c
569 * ieee80211_duration() for a brief description of
570 * what rate we should choose to TX ACKs. */
Pavel Roskin38c07b42008-02-26 17:59:14 -0500571 tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
572 sc->vif, 10, &srate));
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200573
574 ath5k_hw_reg_write(ah, tx_time, reg);
575
576 if (!HAS_SHPREAMBLE(i))
577 continue;
578
579 /*
580 * We're not distinguishing short preamble here,
581 * This is true, all we'll get is a longer value here
582 * which is not necessarilly bad. We could use
583 * export ieee80211_frame_duration() but that needs to be
584 * fixed first to be properly used by mac802111 drivers:
585 *
586 * - remove erp stuff and let the routine figure ofdm
587 * erp rates
588 * - remove passing argument ieee80211_local as
589 * drivers don't have access to it
590 * - move drivers using ieee80211_generic_frame_duration()
591 * to this
592 */
593 ath5k_hw_reg_write(ah, tx_time,
594 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
595 }
596}
597
598/*
599 * Main reset function
600 */
601int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
602 struct ieee80211_channel *channel, bool change_channel)
603{
604 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
Nick Kossifidis56c90542008-02-28 16:20:52 -0500605 struct pci_dev *pdev = ah->ah_sc->pdev;
606 u32 data, s_seq, s_ant, s_led[3], dma_size;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500607 unsigned int i, mode, freq, ee_mode, ant[2];
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200608 int ret;
609
610 ATH5K_TRACE(ah->ah_sc);
611
612 s_seq = 0;
613 s_ant = 0;
614 ee_mode = 0;
615 freq = 0;
616 mode = 0;
617
618 /*
619 * Save some registers before a reset
620 */
621 /*DCU/Antenna selection not available on 5210*/
622 if (ah->ah_version != AR5K_AR5210) {
Joe Perchese9010e22008-03-07 14:21:16 -0800623 if (change_channel) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200624 /* Seq number for queue 0 -do this for all queues ? */
625 s_seq = ath5k_hw_reg_read(ah,
626 AR5K_QUEUE_DFS_SEQNUM(0));
627 /*Default antenna*/
628 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
629 }
630 }
631
632 /*GPIOs*/
633 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
634 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
635 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
636
Joe Perchese9010e22008-03-07 14:21:16 -0800637 if (change_channel && ah->ah_rf_banks != NULL)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200638 ath5k_hw_get_rf_gain(ah);
639
640
641 /*Wakeup the device*/
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500642 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200643 if (ret)
644 return ret;
645
646 /*
647 * Initialize operating mode
648 */
649 ah->ah_op_mode = op_mode;
650
651 /*
652 * 5111/5112 Settings
653 * 5210 only comes with RF5110
654 */
655 if (ah->ah_version != AR5K_AR5210) {
656 if (ah->ah_radio != AR5K_RF5111 &&
657 ah->ah_radio != AR5K_RF5112 &&
Nick Kossifidis903b4742008-02-28 14:50:50 -0500658 ah->ah_radio != AR5K_RF5413 &&
Nick Kossifidis136bfc72008-04-16 18:42:48 +0300659 ah->ah_radio != AR5K_RF2413 &&
660 ah->ah_radio != AR5K_RF2425) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200661 ATH5K_ERR(ah->ah_sc,
662 "invalid phy radio: %u\n", ah->ah_radio);
663 return -EINVAL;
664 }
665
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500666 switch (channel->hw_value & CHANNEL_MODES) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200667 case CHANNEL_A:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500668 mode = AR5K_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200669 freq = AR5K_INI_RFGAIN_5GHZ;
670 ee_mode = AR5K_EEPROM_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200671 break;
672 case CHANNEL_G:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500673 mode = AR5K_MODE_11G;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200674 freq = AR5K_INI_RFGAIN_2GHZ;
675 ee_mode = AR5K_EEPROM_MODE_11G;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200676 break;
677 case CHANNEL_B:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500678 mode = AR5K_MODE_11B;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200679 freq = AR5K_INI_RFGAIN_2GHZ;
680 ee_mode = AR5K_EEPROM_MODE_11B;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200681 break;
682 case CHANNEL_T:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500683 mode = AR5K_MODE_11A_TURBO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200684 freq = AR5K_INI_RFGAIN_5GHZ;
685 ee_mode = AR5K_EEPROM_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200686 break;
687 /*Is this ok on 5211 too ?*/
688 case CHANNEL_TG:
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500689 mode = AR5K_MODE_11G_TURBO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200690 freq = AR5K_INI_RFGAIN_2GHZ;
691 ee_mode = AR5K_EEPROM_MODE_11G;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200692 break;
693 case CHANNEL_XR:
694 if (ah->ah_version == AR5K_AR5211) {
695 ATH5K_ERR(ah->ah_sc,
696 "XR mode not available on 5211");
697 return -EINVAL;
698 }
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500699 mode = AR5K_MODE_XR;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200700 freq = AR5K_INI_RFGAIN_5GHZ;
701 ee_mode = AR5K_EEPROM_MODE_11A;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200702 break;
703 default:
704 ATH5K_ERR(ah->ah_sc,
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500705 "invalid channel: %d\n", channel->center_freq);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200706 return -EINVAL;
707 }
708
709 /* PHY access enable */
710 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
711
712 }
713
714 ret = ath5k_hw_write_initvals(ah, mode, change_channel);
715 if (ret)
716 return ret;
717
718 /*
719 * 5211/5212 Specific
720 */
721 if (ah->ah_version != AR5K_AR5210) {
722 /*
723 * Write initial RF gain settings
724 * This should work for both 5111/5112
725 */
726 ret = ath5k_hw_rfgain(ah, freq);
727 if (ret)
728 return ret;
729
730 mdelay(1);
731
732 /*
733 * Write some more initial register settings
734 */
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500735 if (ah->ah_version == AR5K_AR5212) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200736 ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11));
737
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500738 if (channel->hw_value == CHANNEL_G)
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500739 if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
740 ath5k_hw_reg_write(ah, 0x00f80d80,
741 AR5K_PHY(83));
742 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
743 ath5k_hw_reg_write(ah, 0x00380140,
744 AR5K_PHY(83));
745 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
746 ath5k_hw_reg_write(ah, 0x00fc0ec0,
747 AR5K_PHY(83));
748 else /* 2425 */
749 ath5k_hw_reg_write(ah, 0x00fc0fc0,
750 AR5K_PHY(83));
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200751 else
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -0500752 ath5k_hw_reg_write(ah, 0x00000000,
753 AR5K_PHY(83));
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200754
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200755 ath5k_hw_reg_write(ah, 0x000009b5, 0xa228);
756 ath5k_hw_reg_write(ah, 0x0000000f, 0x8060);
757 ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
758 ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
759 }
760
761 /* Fix for first revision of the RF5112 RF chipset */
762 if (ah->ah_radio >= AR5K_RF5112 &&
763 ah->ah_radio_5ghz_revision <
764 AR5K_SREV_RAD_5112A) {
765 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
766 AR5K_PHY_CCKTXCTL);
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500767 if (channel->hw_value & CHANNEL_5GHZ)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200768 data = 0xffb81020;
769 else
770 data = 0xffb80d20;
771 ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
772 }
773
774 /*
775 * Set TX power (FIXME)
776 */
777 ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER);
778 if (ret)
779 return ret;
780
Luis R. Rodriguez132127e2008-01-04 02:21:05 -0500781 /* Write rate duration table only on AR5212 and if
782 * virtual interface has already been brought up
783 * XXX: rethink this after new mode changes to
784 * mac80211 are integrated */
785 if (ah->ah_version == AR5K_AR5212 &&
786 ah->ah_sc->vif != NULL)
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500787 ath5k_hw_write_rate_duration(ah, mode);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200788
789 /*
790 * Write RF registers
791 * TODO:Does this work on 5211 (5111) ?
792 */
793 ret = ath5k_hw_rfregs(ah, channel, mode);
794 if (ret)
795 return ret;
796
797 /*
798 * Configure additional registers
799 */
800
801 /* Write OFDM timings on 5212*/
802 if (ah->ah_version == AR5K_AR5212 &&
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500803 channel->hw_value & CHANNEL_OFDM) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200804 ret = ath5k_hw_write_ofdm_timings(ah, channel);
805 if (ret)
806 return ret;
807 }
808
809 /*Enable/disable 802.11b mode on 5111
810 (enable 2111 frequency converter + CCK)*/
811 if (ah->ah_radio == AR5K_RF5111) {
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500812 if (mode == AR5K_MODE_11B)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200813 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
814 AR5K_TXCFG_B_MODE);
815 else
816 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
817 AR5K_TXCFG_B_MODE);
818 }
819
820 /*
821 * Set channel and calibrate the PHY
822 */
823 ret = ath5k_hw_channel(ah, channel);
824 if (ret)
825 return ret;
826
827 /* Set antenna mode */
828 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x44),
829 ah->ah_antenna[ee_mode][0], 0xfffffc06);
830
831 /*
832 * In case a fixed antenna was set as default
833 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
834 * registers.
835 */
836 if (s_ant != 0){
837 if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
838 ant[0] = ant[1] = AR5K_ANT_FIXED_A;
839 else /* 2 - Aux */
840 ant[0] = ant[1] = AR5K_ANT_FIXED_B;
841 } else {
842 ant[0] = AR5K_ANT_FIXED_A;
843 ant[1] = AR5K_ANT_FIXED_B;
844 }
845
846 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
847 AR5K_PHY_ANT_SWITCH_TABLE_0);
848 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
849 AR5K_PHY_ANT_SWITCH_TABLE_1);
850
851 /* Commit values from EEPROM */
852 if (ah->ah_radio == AR5K_RF5111)
853 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
854 AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
855
856 ath5k_hw_reg_write(ah,
857 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
858 AR5K_PHY(0x5a));
859
860 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x11),
861 (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
862 0xffffc07f);
863 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x12),
864 (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
865 0xfffc0fff);
866 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x14),
867 (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
868 ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
869 0xffff0000);
870
871 ath5k_hw_reg_write(ah,
872 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
873 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
874 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
875 (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY(0x0d));
876
877 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x0a),
878 ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
879 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x19),
880 (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
881 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x49), 4, 0xffffff01);
882
883 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
884 AR5K_PHY_IQ_CORR_ENABLE |
885 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
886 ee->ee_q_cal[ee_mode]);
887
888 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
889 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
890 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
891 ee->ee_margin_tx_rx[ee_mode]);
892
893 } else {
894 mdelay(1);
895 /* Disable phy and wait */
896 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
897 mdelay(1);
898 }
899
900 /*
901 * Restore saved values
902 */
903 /*DCU/Antenna selection not available on 5210*/
904 if (ah->ah_version != AR5K_AR5210) {
905 ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
906 ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
907 }
908 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
909 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
910 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
911
912 /*
913 * Misc
914 */
915 /* XXX: add ah->aid once mac80211 gives this to us */
916 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
917
918 ath5k_hw_set_opmode(ah);
919 /*PISR/SISR Not available on 5210*/
920 if (ah->ah_version != AR5K_AR5210) {
921 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
922 /* If we later allow tuning for this, store into sc structure */
923 data = AR5K_TUNE_RSSI_THRES |
924 AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
925 ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
926 }
927
928 /*
929 * Set Rx/Tx DMA Configuration
Nick Kossifidis56c90542008-02-28 16:20:52 -0500930 *
931 * Set maximum DMA size (512) except for PCI-E cards since
932 * it causes rx overruns and tx errors (tested on 5424 but since
933 * rx overruns also occur on 5416/5418 with madwifi we set 128
934 * for all PCI-E cards to be safe).
935 *
936 * In dumps this is 128 for allchips.
937 *
938 * XXX: need to check 5210 for this
939 * TODO: Check out tx triger level, it's always 64 on dumps but I
940 * guess we can tweak it and see how it goes ;-)
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200941 */
Nick Kossifidis56c90542008-02-28 16:20:52 -0500942 dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200943 if (ah->ah_version != AR5K_AR5210) {
Nick Kossifidis56c90542008-02-28 16:20:52 -0500944 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
945 AR5K_TXCFG_SDMAMR, dma_size);
946 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
947 AR5K_RXCFG_SDMAMW, dma_size);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200948 }
949
950 /*
951 * Enable the PHY and wait until completion
952 */
953 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
954
955 /*
956 * 5111/5112 Specific
957 */
958 if (ah->ah_version != AR5K_AR5210) {
959 data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
960 AR5K_PHY_RX_DELAY_M;
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500961 data = (channel->hw_value & CHANNEL_CCK) ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200962 ((data << 2) / 22) : (data / 10);
963
964 udelay(100 + data);
965 } else {
966 mdelay(1);
967 }
968
969 /*
970 * Enable calibration and wait until completion
971 */
972 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
973 AR5K_PHY_AGCCTL_CAL);
974
975 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
976 AR5K_PHY_AGCCTL_CAL, 0, false)) {
977 ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500978 channel->center_freq);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200979 return -EAGAIN;
980 }
981
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500982 ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200983 if (ret)
984 return ret;
985
986 ah->ah_calibration = false;
987
988 /* A and G modes can use QAM modulation which requires enabling
989 * I and Q calibration. Don't bother in B mode. */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -0500990 if (!(mode == AR5K_MODE_11B)) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +0200991 ah->ah_calibration = true;
992 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
993 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
994 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
995 AR5K_PHY_IQ_RUN);
996 }
997
998 /*
999 * Reset queues and start beacon timers at the end of the reset routine
1000 */
1001 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
1002 /*No QCU on 5210*/
1003 if (ah->ah_version != AR5K_AR5210)
1004 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
1005
1006 ret = ath5k_hw_reset_tx_queue(ah, i);
1007 if (ret) {
1008 ATH5K_ERR(ah->ah_sc,
1009 "failed to reset TX queue #%d\n", i);
1010 return ret;
1011 }
1012 }
1013
1014 /* Pre-enable interrupts on 5211/5212*/
1015 if (ah->ah_version != AR5K_AR5210)
1016 ath5k_hw_set_intr(ah, AR5K_INT_RX | AR5K_INT_TX |
1017 AR5K_INT_FATAL);
1018
1019 /*
1020 * Set RF kill flags if supported by the device (read from the EEPROM)
1021 * Disable gpio_intr for now since it results system hang.
1022 * TODO: Handle this in ath5k_intr
1023 */
1024#if 0
1025 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
1026 ath5k_hw_set_gpio_input(ah, 0);
1027 ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
1028 if (ah->ah_gpio[0] == 0)
1029 ath5k_hw_set_gpio_intr(ah, 0, 1);
1030 else
1031 ath5k_hw_set_gpio_intr(ah, 0, 0);
1032 }
1033#endif
1034
1035 /*
1036 * Set the 32MHz reference clock on 5212 phy clock sleep register
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05001037 *
1038 * TODO: Find out how to switch to external 32Khz clock to save power
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001039 */
1040 if (ah->ah_version == AR5K_AR5212) {
1041 ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
1042 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
1043 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
1044 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
1045 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
Nick Kossifidis903b4742008-02-28 14:50:50 -05001046 ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001047 }
1048
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05001049 if (ah->ah_version == AR5K_AR5212) {
1050 ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
1051 ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
1052 ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
1053 if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413)
1054 ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
1055 }
1056
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001057 /*
1058 * Disable beacons and reset the register
1059 */
1060 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
1061 AR5K_BEACON_RESET_TSF);
1062
1063 return 0;
1064}
1065
1066/*
1067 * Reset chipset
1068 */
1069static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
1070{
1071 int ret;
1072 u32 mask = val ? val : ~0U;
1073
1074 ATH5K_TRACE(ah->ah_sc);
1075
1076 /* Read-and-clear RX Descriptor Pointer*/
1077 ath5k_hw_reg_read(ah, AR5K_RXDP);
1078
1079 /*
1080 * Reset the device and wait until success
1081 */
1082 ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
1083
1084 /* Wait at least 128 PCI clocks */
1085 udelay(15);
1086
1087 if (ah->ah_version == AR5K_AR5210) {
1088 val &= AR5K_RESET_CTL_CHIP;
1089 mask &= AR5K_RESET_CTL_CHIP;
1090 } else {
1091 val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
1092 mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
1093 }
1094
1095 ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
1096
1097 /*
1098 * Reset configuration register (for hw byte-swap). Note that this
1099 * is only set for big endian. We do the necessary magic in
1100 * AR5K_INIT_CFG.
1101 */
1102 if ((val & AR5K_RESET_CTL_PCU) == 0)
1103 ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
1104
1105 return ret;
1106}
1107
1108/*
1109 * Power management functions
1110 */
1111
1112/*
1113 * Sleep control
1114 */
1115int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
1116 bool set_chip, u16 sleep_duration)
1117{
1118 unsigned int i;
1119 u32 staid;
1120
1121 ATH5K_TRACE(ah->ah_sc);
1122 staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
1123
1124 switch (mode) {
1125 case AR5K_PM_AUTO:
1126 staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
1127 /* fallthrough */
1128 case AR5K_PM_NETWORK_SLEEP:
Joe Perchese9010e22008-03-07 14:21:16 -08001129 if (set_chip)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001130 ath5k_hw_reg_write(ah,
1131 AR5K_SLEEP_CTL_SLE | sleep_duration,
1132 AR5K_SLEEP_CTL);
1133
1134 staid |= AR5K_STA_ID1_PWR_SV;
1135 break;
1136
1137 case AR5K_PM_FULL_SLEEP:
Joe Perchese9010e22008-03-07 14:21:16 -08001138 if (set_chip)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001139 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
1140 AR5K_SLEEP_CTL);
1141
1142 staid |= AR5K_STA_ID1_PWR_SV;
1143 break;
1144
1145 case AR5K_PM_AWAKE:
Joe Perchese9010e22008-03-07 14:21:16 -08001146 if (!set_chip)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001147 goto commit;
1148
1149 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
1150 AR5K_SLEEP_CTL);
1151
1152 for (i = 5000; i > 0; i--) {
1153 /* Check if the chip did wake up */
1154 if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
1155 AR5K_PCICFG_SPWR_DN) == 0)
1156 break;
1157
1158 /* Wait a bit and retry */
1159 udelay(200);
1160 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
1161 AR5K_SLEEP_CTL);
1162 }
1163
1164 /* Fail if the chip didn't wake up */
1165 if (i <= 0)
1166 return -EIO;
1167
1168 staid &= ~AR5K_STA_ID1_PWR_SV;
1169 break;
1170
1171 default:
1172 return -EINVAL;
1173 }
1174
1175commit:
1176 ah->ah_power_mode = mode;
1177 ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
1178
1179 return 0;
1180}
1181
1182/***********************\
1183 DMA Related Functions
1184\***********************/
1185
1186/*
1187 * Receive functions
1188 */
1189
1190/*
1191 * Start DMA receive
1192 */
1193void ath5k_hw_start_rx(struct ath5k_hw *ah)
1194{
1195 ATH5K_TRACE(ah->ah_sc);
1196 ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
1197}
1198
1199/*
1200 * Stop DMA receive
1201 */
1202int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
1203{
1204 unsigned int i;
1205
1206 ATH5K_TRACE(ah->ah_sc);
1207 ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
1208
1209 /*
1210 * It may take some time to disable the DMA receive unit
1211 */
1212 for (i = 2000; i > 0 &&
1213 (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
1214 i--)
1215 udelay(10);
1216
1217 return i ? 0 : -EBUSY;
1218}
1219
1220/*
1221 * Get the address of the RX Descriptor
1222 */
1223u32 ath5k_hw_get_rx_buf(struct ath5k_hw *ah)
1224{
1225 return ath5k_hw_reg_read(ah, AR5K_RXDP);
1226}
1227
1228/*
1229 * Set the address of the RX Descriptor
1230 */
1231void ath5k_hw_put_rx_buf(struct ath5k_hw *ah, u32 phys_addr)
1232{
1233 ATH5K_TRACE(ah->ah_sc);
1234
1235 /*TODO:Shouldn't we check if RX is enabled first ?*/
1236 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
1237}
1238
1239/*
1240 * Transmit functions
1241 */
1242
1243/*
1244 * Start DMA transmit for a specific queue
1245 * (see also QCU/DCU functions)
1246 */
1247int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue)
1248{
1249 u32 tx_queue;
1250
1251 ATH5K_TRACE(ah->ah_sc);
1252 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1253
1254 /* Return if queue is declared inactive */
1255 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
1256 return -EIO;
1257
1258 if (ah->ah_version == AR5K_AR5210) {
1259 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
1260
1261 /*
1262 * Set the queue by type on 5210
1263 */
1264 switch (ah->ah_txq[queue].tqi_type) {
1265 case AR5K_TX_QUEUE_DATA:
1266 tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
1267 break;
1268 case AR5K_TX_QUEUE_BEACON:
1269 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
1270 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
1271 AR5K_BSR);
1272 break;
1273 case AR5K_TX_QUEUE_CAB:
1274 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
1275 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |
1276 AR5K_BCR_BDMAE, AR5K_BSR);
1277 break;
1278 default:
1279 return -EINVAL;
1280 }
1281 /* Start queue */
1282 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
1283 } else {
1284 /* Return if queue is disabled */
1285 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
1286 return -EIO;
1287
1288 /* Start queue */
1289 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);
1290 }
1291
1292 return 0;
1293}
1294
1295/*
1296 * Stop DMA transmit for a specific queue
1297 * (see also QCU/DCU functions)
1298 */
1299int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
1300{
1301 unsigned int i = 100;
1302 u32 tx_queue, pending;
1303
1304 ATH5K_TRACE(ah->ah_sc);
1305 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1306
1307 /* Return if queue is declared inactive */
1308 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
1309 return -EIO;
1310
1311 if (ah->ah_version == AR5K_AR5210) {
1312 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
1313
1314 /*
1315 * Set by queue type
1316 */
1317 switch (ah->ah_txq[queue].tqi_type) {
1318 case AR5K_TX_QUEUE_DATA:
1319 tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
1320 break;
1321 case AR5K_TX_QUEUE_BEACON:
1322 case AR5K_TX_QUEUE_CAB:
1323 /* XXX Fix me... */
1324 tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;
1325 ath5k_hw_reg_write(ah, 0, AR5K_BSR);
1326 break;
1327 default:
1328 return -EINVAL;
1329 }
1330
1331 /* Stop queue */
1332 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
1333 } else {
1334 /*
1335 * Schedule TX disable and wait until queue is empty
1336 */
1337 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
1338
1339 /*Check for pending frames*/
1340 do {
1341 pending = ath5k_hw_reg_read(ah,
1342 AR5K_QUEUE_STATUS(queue)) &
1343 AR5K_QCU_STS_FRMPENDCNT;
1344 udelay(100);
1345 } while (--i && pending);
1346
1347 /* Clear register */
1348 ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
1349 }
1350
1351 /* TODO: Check for success else return error */
1352 return 0;
1353}
1354
1355/*
1356 * Get the address of the TX Descriptor for a specific queue
1357 * (see also QCU/DCU functions)
1358 */
1359u32 ath5k_hw_get_tx_buf(struct ath5k_hw *ah, unsigned int queue)
1360{
1361 u16 tx_reg;
1362
1363 ATH5K_TRACE(ah->ah_sc);
1364 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1365
1366 /*
1367 * Get the transmit queue descriptor pointer from the selected queue
1368 */
1369 /*5210 doesn't have QCU*/
1370 if (ah->ah_version == AR5K_AR5210) {
1371 switch (ah->ah_txq[queue].tqi_type) {
1372 case AR5K_TX_QUEUE_DATA:
1373 tx_reg = AR5K_NOQCU_TXDP0;
1374 break;
1375 case AR5K_TX_QUEUE_BEACON:
1376 case AR5K_TX_QUEUE_CAB:
1377 tx_reg = AR5K_NOQCU_TXDP1;
1378 break;
1379 default:
1380 return 0xffffffff;
1381 }
1382 } else {
1383 tx_reg = AR5K_QUEUE_TXDP(queue);
1384 }
1385
1386 return ath5k_hw_reg_read(ah, tx_reg);
1387}
1388
1389/*
1390 * Set the address of the TX Descriptor for a specific queue
1391 * (see also QCU/DCU functions)
1392 */
1393int ath5k_hw_put_tx_buf(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
1394{
1395 u16 tx_reg;
1396
1397 ATH5K_TRACE(ah->ah_sc);
1398 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1399
1400 /*
1401 * Set the transmit queue descriptor pointer register by type
1402 * on 5210
1403 */
1404 if (ah->ah_version == AR5K_AR5210) {
1405 switch (ah->ah_txq[queue].tqi_type) {
1406 case AR5K_TX_QUEUE_DATA:
1407 tx_reg = AR5K_NOQCU_TXDP0;
1408 break;
1409 case AR5K_TX_QUEUE_BEACON:
1410 case AR5K_TX_QUEUE_CAB:
1411 tx_reg = AR5K_NOQCU_TXDP1;
1412 break;
1413 default:
1414 return -EINVAL;
1415 }
1416 } else {
1417 /*
1418 * Set the transmit queue descriptor pointer for
1419 * the selected queue on QCU for 5211+
1420 * (this won't work if the queue is still active)
1421 */
1422 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
1423 return -EIO;
1424
1425 tx_reg = AR5K_QUEUE_TXDP(queue);
1426 }
1427
1428 /* Set descriptor pointer */
1429 ath5k_hw_reg_write(ah, phys_addr, tx_reg);
1430
1431 return 0;
1432}
1433
1434/*
1435 * Update tx trigger level
1436 */
1437int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
1438{
1439 u32 trigger_level, imr;
1440 int ret = -EIO;
1441
1442 ATH5K_TRACE(ah->ah_sc);
1443
1444 /*
1445 * Disable interrupts by setting the mask
1446 */
1447 imr = ath5k_hw_set_intr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
1448
1449 /*TODO: Boundary check on trigger_level*/
1450 trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
1451 AR5K_TXCFG_TXFULL);
1452
Joe Perchese9010e22008-03-07 14:21:16 -08001453 if (!increase) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001454 if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
1455 goto done;
1456 } else
1457 trigger_level +=
1458 ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
1459
1460 /*
1461 * Update trigger level on success
1462 */
1463 if (ah->ah_version == AR5K_AR5210)
1464 ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
1465 else
1466 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
1467 AR5K_TXCFG_TXFULL, trigger_level);
1468
1469 ret = 0;
1470
1471done:
1472 /*
1473 * Restore interrupt mask
1474 */
1475 ath5k_hw_set_intr(ah, imr);
1476
1477 return ret;
1478}
1479
1480/*
1481 * Interrupt handling
1482 */
1483
1484/*
1485 * Check if we have pending interrupts
1486 */
1487bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
1488{
1489 ATH5K_TRACE(ah->ah_sc);
1490 return ath5k_hw_reg_read(ah, AR5K_INTPEND);
1491}
1492
1493/*
1494 * Get interrupt mask (ISR)
1495 */
1496int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
1497{
1498 u32 data;
1499
1500 ATH5K_TRACE(ah->ah_sc);
1501
1502 /*
1503 * Read interrupt status from the Interrupt Status register
1504 * on 5210
1505 */
1506 if (ah->ah_version == AR5K_AR5210) {
1507 data = ath5k_hw_reg_read(ah, AR5K_ISR);
1508 if (unlikely(data == AR5K_INT_NOCARD)) {
1509 *interrupt_mask = data;
1510 return -ENODEV;
1511 }
1512 } else {
1513 /*
1514 * Read interrupt status from the Read-And-Clear shadow register
1515 * Note: PISR/SISR Not available on 5210
1516 */
1517 data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
1518 }
1519
1520 /*
1521 * Get abstract interrupt mask (driver-compatible)
1522 */
1523 *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
1524
1525 if (unlikely(data == AR5K_INT_NOCARD))
1526 return -ENODEV;
1527
1528 if (data & (AR5K_ISR_RXOK | AR5K_ISR_RXERR))
1529 *interrupt_mask |= AR5K_INT_RX;
1530
1531 if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR
1532 | AR5K_ISR_TXDESC | AR5K_ISR_TXEOL))
1533 *interrupt_mask |= AR5K_INT_TX;
1534
1535 if (ah->ah_version != AR5K_AR5210) {
1536 /*HIU = Host Interface Unit (PCI etc)*/
1537 if (unlikely(data & (AR5K_ISR_HIUERR)))
1538 *interrupt_mask |= AR5K_INT_FATAL;
1539
1540 /*Beacon Not Ready*/
1541 if (unlikely(data & (AR5K_ISR_BNR)))
1542 *interrupt_mask |= AR5K_INT_BNR;
1543 }
1544
1545 /*
1546 * XXX: BMISS interrupts may occur after association.
1547 * I found this on 5210 code but it needs testing. If this is
1548 * true we should disable them before assoc and re-enable them
1549 * after a successfull assoc + some jiffies.
1550 */
1551#if 0
1552 interrupt_mask &= ~AR5K_INT_BMISS;
1553#endif
1554
1555 /*
1556 * In case we didn't handle anything,
1557 * print the register value.
1558 */
1559 if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
1560 ATH5K_PRINTF("0x%08x\n", data);
1561
1562 return 0;
1563}
1564
1565/*
1566 * Set interrupt mask
1567 */
1568enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask)
1569{
1570 enum ath5k_int old_mask, int_mask;
1571
1572 /*
1573 * Disable card interrupts to prevent any race conditions
1574 * (they will be re-enabled afterwards).
1575 */
1576 ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
1577
1578 old_mask = ah->ah_imr;
1579
1580 /*
1581 * Add additional, chipset-dependent interrupt mask flags
1582 * and write them to the IMR (interrupt mask register).
1583 */
1584 int_mask = new_mask & AR5K_INT_COMMON;
1585
1586 if (new_mask & AR5K_INT_RX)
1587 int_mask |= AR5K_IMR_RXOK | AR5K_IMR_RXERR | AR5K_IMR_RXORN |
1588 AR5K_IMR_RXDESC;
1589
1590 if (new_mask & AR5K_INT_TX)
1591 int_mask |= AR5K_IMR_TXOK | AR5K_IMR_TXERR | AR5K_IMR_TXDESC |
1592 AR5K_IMR_TXURN;
1593
1594 if (ah->ah_version != AR5K_AR5210) {
1595 if (new_mask & AR5K_INT_FATAL) {
1596 int_mask |= AR5K_IMR_HIUERR;
1597 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_MCABT |
1598 AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR);
1599 }
1600 }
1601
1602 ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
1603
1604 /* Store new interrupt mask */
1605 ah->ah_imr = new_mask;
1606
1607 /* ..re-enable interrupts */
1608 ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
1609
1610 return old_mask;
1611}
1612
1613
1614/*************************\
1615 EEPROM access functions
1616\*************************/
1617
1618/*
1619 * Read from eeprom
1620 */
1621static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
1622{
1623 u32 status, timeout;
1624
1625 ATH5K_TRACE(ah->ah_sc);
1626 /*
1627 * Initialize EEPROM access
1628 */
1629 if (ah->ah_version == AR5K_AR5210) {
1630 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
1631 (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
1632 } else {
1633 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
1634 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1635 AR5K_EEPROM_CMD_READ);
1636 }
1637
1638 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
1639 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
1640 if (status & AR5K_EEPROM_STAT_RDDONE) {
1641 if (status & AR5K_EEPROM_STAT_RDERR)
1642 return -EIO;
1643 *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
1644 0xffff);
1645 return 0;
1646 }
1647 udelay(15);
1648 }
1649
1650 return -ETIMEDOUT;
1651}
1652
1653/*
1654 * Write to eeprom - currently disabled, use at your own risk
1655 */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001656#if 0
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001657static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data)
1658{
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001659
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001660 u32 status, timeout;
1661
1662 ATH5K_TRACE(ah->ah_sc);
1663
1664 /*
1665 * Initialize eeprom access
1666 */
1667
1668 if (ah->ah_version == AR5K_AR5210) {
1669 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
1670 } else {
1671 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1672 AR5K_EEPROM_CMD_RESET);
1673 }
1674
1675 /*
1676 * Write data to data register
1677 */
1678
1679 if (ah->ah_version == AR5K_AR5210) {
1680 ath5k_hw_reg_write(ah, data, AR5K_EEPROM_BASE + (4 * offset));
1681 } else {
1682 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
1683 ath5k_hw_reg_write(ah, data, AR5K_EEPROM_DATA);
1684 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1685 AR5K_EEPROM_CMD_WRITE);
1686 }
1687
1688 /*
1689 * Check status
1690 */
1691
1692 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
1693 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
1694 if (status & AR5K_EEPROM_STAT_WRDONE) {
1695 if (status & AR5K_EEPROM_STAT_WRERR)
1696 return EIO;
1697 return 0;
1698 }
1699 udelay(15);
1700 }
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001701
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001702 ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!");
1703 return -EIO;
1704}
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05001705#endif
Jiri Slabyfa1c1142007-08-12 17:33:16 +02001706
1707/*
1708 * Translate binary channel representation in EEPROM to frequency
1709 */
1710static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin, unsigned int mode)
1711{
1712 u16 val;
1713
1714 if (bin == AR5K_EEPROM_CHANNEL_DIS)
1715 return bin;
1716
1717 if (mode == AR5K_EEPROM_MODE_11A) {
1718 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
1719 val = (5 * bin) + 4800;
1720 else
1721 val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
1722 (bin * 10) + 5100;
1723 } else {
1724 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
1725 val = bin + 2300;
1726 else
1727 val = bin + 2400;
1728 }
1729
1730 return val;
1731}
1732
1733/*
1734 * Read antenna infos from eeprom
1735 */
1736static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
1737 unsigned int mode)
1738{
1739 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1740 u32 o = *offset;
1741 u16 val;
1742 int ret, i = 0;
1743
1744 AR5K_EEPROM_READ(o++, val);
1745 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
1746 ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f;
1747 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
1748
1749 AR5K_EEPROM_READ(o++, val);
1750 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
1751 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
1752 ee->ee_ant_control[mode][i++] = val & 0x3f;
1753
1754 AR5K_EEPROM_READ(o++, val);
1755 ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
1756 ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
1757 ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
1758
1759 AR5K_EEPROM_READ(o++, val);
1760 ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
1761 ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
1762 ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
1763 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
1764
1765 AR5K_EEPROM_READ(o++, val);
1766 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
1767 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
1768 ee->ee_ant_control[mode][i++] = val & 0x3f;
1769
1770 /* Get antenna modes */
1771 ah->ah_antenna[mode][0] =
1772 (ee->ee_ant_control[mode][0] << 4) | 0x1;
1773 ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
1774 ee->ee_ant_control[mode][1] |
1775 (ee->ee_ant_control[mode][2] << 6) |
1776 (ee->ee_ant_control[mode][3] << 12) |
1777 (ee->ee_ant_control[mode][4] << 18) |
1778 (ee->ee_ant_control[mode][5] << 24);
1779 ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
1780 ee->ee_ant_control[mode][6] |
1781 (ee->ee_ant_control[mode][7] << 6) |
1782 (ee->ee_ant_control[mode][8] << 12) |
1783 (ee->ee_ant_control[mode][9] << 18) |
1784 (ee->ee_ant_control[mode][10] << 24);
1785
1786 /* return new offset */
1787 *offset = o;
1788
1789 return 0;
1790}
1791
1792/*
1793 * Read supported modes from eeprom
1794 */
1795static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
1796 unsigned int mode)
1797{
1798 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1799 u32 o = *offset;
1800 u16 val;
1801 int ret;
1802
1803 AR5K_EEPROM_READ(o++, val);
1804 ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
1805 ee->ee_thr_62[mode] = val & 0xff;
1806
1807 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
1808 ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
1809
1810 AR5K_EEPROM_READ(o++, val);
1811 ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
1812 ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
1813
1814 AR5K_EEPROM_READ(o++, val);
1815 ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
1816
1817 if ((val & 0xff) & 0x80)
1818 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
1819 else
1820 ee->ee_noise_floor_thr[mode] = val & 0xff;
1821
1822 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
1823 ee->ee_noise_floor_thr[mode] =
1824 mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
1825
1826 AR5K_EEPROM_READ(o++, val);
1827 ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
1828 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
1829 ee->ee_xpd[mode] = val & 0x1;
1830
1831 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
1832 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
1833
1834 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
1835 AR5K_EEPROM_READ(o++, val);
1836 ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
1837
1838 if (mode == AR5K_EEPROM_MODE_11A)
1839 ee->ee_xr_power[mode] = val & 0x3f;
1840 else {
1841 ee->ee_ob[mode][0] = val & 0x7;
1842 ee->ee_db[mode][0] = (val >> 3) & 0x7;
1843 }
1844 }
1845
1846 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
1847 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
1848 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
1849 } else {
1850 ee->ee_i_gain[mode] = (val >> 13) & 0x7;
1851
1852 AR5K_EEPROM_READ(o++, val);
1853 ee->ee_i_gain[mode] |= (val << 3) & 0x38;
1854
1855 if (mode == AR5K_EEPROM_MODE_11G)
1856 ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
1857 }
1858
1859 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
1860 mode == AR5K_EEPROM_MODE_11A) {
1861 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
1862 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
1863 }
1864
1865 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 &&
1866 mode == AR5K_EEPROM_MODE_11G)
1867 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
1868
1869 /* return new offset */
1870 *offset = o;
1871
1872 return 0;
1873}
1874
1875/*
1876 * Initialize eeprom & capabilities structs
1877 */
1878static int ath5k_eeprom_init(struct ath5k_hw *ah)
1879{
1880 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1881 unsigned int mode, i;
1882 int ret;
1883 u32 offset;
1884 u16 val;
1885
1886 /* Initial TX thermal adjustment values */
1887 ee->ee_tx_clip = 4;
1888 ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
1889 ee->ee_gain_select = 1;
1890
1891 /*
1892 * Read values from EEPROM and store them in the capability structure
1893 */
1894 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
1895 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
1896 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
1897 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
1898 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
1899
1900 /* Return if we have an old EEPROM */
1901 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
1902 return 0;
1903
1904#ifdef notyet
1905 /*
1906 * Validate the checksum of the EEPROM date. There are some
1907 * devices with invalid EEPROMs.
1908 */
1909 for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
1910 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
1911 cksum ^= val;
1912 }
1913 if (cksum != AR5K_EEPROM_INFO_CKSUM) {
1914 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
1915 return -EIO;
1916 }
1917#endif
1918
1919 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
1920 ee_ant_gain);
1921
1922 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
1923 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
1924 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
1925 }
1926
1927 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
1928 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
1929 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
1930 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
1931
1932 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
1933 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
1934 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
1935 }
1936
1937 /*
1938 * Get conformance test limit values
1939 */
1940 offset = AR5K_EEPROM_CTL(ah->ah_ee_version);
1941 ee->ee_ctls = AR5K_EEPROM_N_CTLS(ah->ah_ee_version);
1942
1943 for (i = 0; i < ee->ee_ctls; i++) {
1944 AR5K_EEPROM_READ(offset++, val);
1945 ee->ee_ctl[i] = (val >> 8) & 0xff;
1946 ee->ee_ctl[i + 1] = val & 0xff;
1947 }
1948
1949 /*
1950 * Get values for 802.11a (5GHz)
1951 */
1952 mode = AR5K_EEPROM_MODE_11A;
1953
1954 ee->ee_turbo_max_power[mode] =
1955 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
1956
1957 offset = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
1958
1959 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
1960 if (ret)
1961 return ret;
1962
1963 AR5K_EEPROM_READ(offset++, val);
1964 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
1965 ee->ee_ob[mode][3] = (val >> 5) & 0x7;
1966 ee->ee_db[mode][3] = (val >> 2) & 0x7;
1967 ee->ee_ob[mode][2] = (val << 1) & 0x7;
1968
1969 AR5K_EEPROM_READ(offset++, val);
1970 ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
1971 ee->ee_db[mode][2] = (val >> 12) & 0x7;
1972 ee->ee_ob[mode][1] = (val >> 9) & 0x7;
1973 ee->ee_db[mode][1] = (val >> 6) & 0x7;
1974 ee->ee_ob[mode][0] = (val >> 3) & 0x7;
1975 ee->ee_db[mode][0] = val & 0x7;
1976
1977 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
1978 if (ret)
1979 return ret;
1980
1981 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
1982 AR5K_EEPROM_READ(offset++, val);
1983 ee->ee_margin_tx_rx[mode] = val & 0x3f;
1984 }
1985
1986 /*
1987 * Get values for 802.11b (2.4GHz)
1988 */
1989 mode = AR5K_EEPROM_MODE_11B;
1990 offset = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
1991
1992 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
1993 if (ret)
1994 return ret;
1995
1996 AR5K_EEPROM_READ(offset++, val);
1997 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
1998 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
1999 ee->ee_db[mode][1] = val & 0x7;
2000
2001 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
2002 if (ret)
2003 return ret;
2004
2005 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
2006 AR5K_EEPROM_READ(offset++, val);
2007 ee->ee_cal_pier[mode][0] =
2008 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2009 ee->ee_cal_pier[mode][1] =
2010 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
2011
2012 AR5K_EEPROM_READ(offset++, val);
2013 ee->ee_cal_pier[mode][2] =
2014 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2015 }
2016
2017 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
2018 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
2019
2020 /*
2021 * Get values for 802.11g (2.4GHz)
2022 */
2023 mode = AR5K_EEPROM_MODE_11G;
2024 offset = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
2025
2026 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
2027 if (ret)
2028 return ret;
2029
2030 AR5K_EEPROM_READ(offset++, val);
2031 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
2032 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
2033 ee->ee_db[mode][1] = val & 0x7;
2034
2035 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
2036 if (ret)
2037 return ret;
2038
2039 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
2040 AR5K_EEPROM_READ(offset++, val);
2041 ee->ee_cal_pier[mode][0] =
2042 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2043 ee->ee_cal_pier[mode][1] =
2044 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
2045
2046 AR5K_EEPROM_READ(offset++, val);
2047 ee->ee_turbo_max_power[mode] = val & 0x7f;
2048 ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
2049
2050 AR5K_EEPROM_READ(offset++, val);
2051 ee->ee_cal_pier[mode][2] =
2052 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2053
2054 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
2055 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
2056
2057 AR5K_EEPROM_READ(offset++, val);
2058 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
2059 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
2060
2061 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
2062 AR5K_EEPROM_READ(offset++, val);
2063 ee->ee_cck_ofdm_gain_delta = val & 0xff;
2064 }
2065 }
2066
2067 /*
2068 * Read 5GHz EEPROM channels
2069 */
2070
2071 return 0;
2072}
2073
2074/*
2075 * Read the MAC address from eeprom
2076 */
2077static int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
2078{
2079 u8 mac_d[ETH_ALEN];
2080 u32 total, offset;
2081 u16 data;
2082 int octet, ret;
2083
2084 memset(mac, 0, ETH_ALEN);
2085 memset(mac_d, 0, ETH_ALEN);
2086
2087 ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
2088 if (ret)
2089 return ret;
2090
2091 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
2092 ret = ath5k_hw_eeprom_read(ah, offset, &data);
2093 if (ret)
2094 return ret;
2095
2096 total += data;
2097 mac_d[octet + 1] = data & 0xff;
2098 mac_d[octet] = data >> 8;
2099 octet += 2;
2100 }
2101
2102 memcpy(mac, mac_d, ETH_ALEN);
2103
2104 if (!total || total == 3 * 0xffff)
2105 return -EINVAL;
2106
2107 return 0;
2108}
2109
2110/*
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002111 * Fill the capabilities struct
2112 */
2113static int ath5k_hw_get_capabilities(struct ath5k_hw *ah)
2114{
2115 u16 ee_header;
2116
2117 ATH5K_TRACE(ah->ah_sc);
2118 /* Capabilities stored in the EEPROM */
2119 ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
2120
2121 if (ah->ah_version == AR5K_AR5210) {
2122 /*
2123 * Set radio capabilities
2124 * (The AR5110 only supports the middle 5GHz band)
2125 */
2126 ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
2127 ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
2128 ah->ah_capabilities.cap_range.range_2ghz_min = 0;
2129 ah->ah_capabilities.cap_range.range_2ghz_max = 0;
2130
2131 /* Set supported modes */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002132 __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
2133 __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002134 } else {
2135 /*
2136 * XXX The tranceiver supports frequencies from 4920 to 6100GHz
2137 * XXX and from 2312 to 2732GHz. There are problems with the
2138 * XXX current ieee80211 implementation because the IEEE
2139 * XXX channel mapping does not support negative channel
2140 * XXX numbers (2312MHz is channel -19). Of course, this
2141 * XXX doesn't matter because these channels are out of range
2142 * XXX but some regulation domains like MKK (Japan) will
2143 * XXX support frequencies somewhere around 4.8GHz.
2144 */
2145
2146 /*
2147 * Set radio capabilities
2148 */
2149
2150 if (AR5K_EEPROM_HDR_11A(ee_header)) {
2151 ah->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
2152 ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
2153
2154 /* Set supported modes */
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002155 __set_bit(AR5K_MODE_11A,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002156 ah->ah_capabilities.cap_mode);
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002157 __set_bit(AR5K_MODE_11A_TURBO,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002158 ah->ah_capabilities.cap_mode);
2159 if (ah->ah_version == AR5K_AR5212)
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002160 __set_bit(AR5K_MODE_11G_TURBO,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002161 ah->ah_capabilities.cap_mode);
2162 }
2163
2164 /* Enable 802.11b if a 2GHz capable radio (2111/5112) is
2165 * connected */
2166 if (AR5K_EEPROM_HDR_11B(ee_header) ||
2167 AR5K_EEPROM_HDR_11G(ee_header)) {
2168 ah->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
2169 ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
2170
2171 if (AR5K_EEPROM_HDR_11B(ee_header))
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002172 __set_bit(AR5K_MODE_11B,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002173 ah->ah_capabilities.cap_mode);
2174
2175 if (AR5K_EEPROM_HDR_11G(ee_header))
Luis R. Rodriguezd8ee3982008-02-03 21:51:04 -05002176 __set_bit(AR5K_MODE_11G,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002177 ah->ah_capabilities.cap_mode);
2178 }
2179 }
2180
2181 /* GPIO */
2182 ah->ah_gpio_npins = AR5K_NUM_GPIO;
2183
2184 /* Set number of supported TX queues */
2185 if (ah->ah_version == AR5K_AR5210)
2186 ah->ah_capabilities.cap_queues.q_tx_num =
2187 AR5K_NUM_TX_QUEUES_NOQCU;
2188 else
2189 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
2190
2191 return 0;
2192}
2193
2194/*********************************\
2195 Protocol Control Unit Functions
2196\*********************************/
2197
2198/*
2199 * Set Operation mode
2200 */
2201int ath5k_hw_set_opmode(struct ath5k_hw *ah)
2202{
2203 u32 pcu_reg, beacon_reg, low_id, high_id;
2204
2205 pcu_reg = 0;
2206 beacon_reg = 0;
2207
2208 ATH5K_TRACE(ah->ah_sc);
2209
2210 switch (ah->ah_op_mode) {
2211 case IEEE80211_IF_TYPE_IBSS:
2212 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_DESC_ANTENNA |
2213 (ah->ah_version == AR5K_AR5210 ?
2214 AR5K_STA_ID1_NO_PSPOLL : 0);
2215 beacon_reg |= AR5K_BCR_ADHOC;
2216 break;
2217
2218 case IEEE80211_IF_TYPE_AP:
2219 pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_RTS_DEF_ANTENNA |
2220 (ah->ah_version == AR5K_AR5210 ?
2221 AR5K_STA_ID1_NO_PSPOLL : 0);
2222 beacon_reg |= AR5K_BCR_AP;
2223 break;
2224
2225 case IEEE80211_IF_TYPE_STA:
2226 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
2227 (ah->ah_version == AR5K_AR5210 ?
2228 AR5K_STA_ID1_PWR_SV : 0);
2229 case IEEE80211_IF_TYPE_MNTR:
2230 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
2231 (ah->ah_version == AR5K_AR5210 ?
2232 AR5K_STA_ID1_NO_PSPOLL : 0);
2233 break;
2234
2235 default:
2236 return -EINVAL;
2237 }
2238
2239 /*
2240 * Set PCU registers
2241 */
2242 low_id = AR5K_LOW_ID(ah->ah_sta_id);
2243 high_id = AR5K_HIGH_ID(ah->ah_sta_id);
2244 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
2245 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
2246
2247 /*
2248 * Set Beacon Control Register on 5210
2249 */
2250 if (ah->ah_version == AR5K_AR5210)
2251 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
2252
2253 return 0;
2254}
2255
2256/*
2257 * BSSID Functions
2258 */
2259
2260/*
2261 * Get station id
2262 */
2263void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
2264{
2265 ATH5K_TRACE(ah->ah_sc);
2266 memcpy(mac, ah->ah_sta_id, ETH_ALEN);
2267}
2268
2269/*
2270 * Set station id
2271 */
2272int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
2273{
2274 u32 low_id, high_id;
2275
2276 ATH5K_TRACE(ah->ah_sc);
2277 /* Set new station ID */
2278 memcpy(ah->ah_sta_id, mac, ETH_ALEN);
2279
2280 low_id = AR5K_LOW_ID(mac);
2281 high_id = AR5K_HIGH_ID(mac);
2282
2283 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
2284 ath5k_hw_reg_write(ah, high_id, AR5K_STA_ID1);
2285
2286 return 0;
2287}
2288
2289/*
2290 * Set BSSID
2291 */
2292void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
2293{
2294 u32 low_id, high_id;
2295 u16 tim_offset = 0;
2296
2297 /*
2298 * Set simple BSSID mask on 5212
2299 */
2300 if (ah->ah_version == AR5K_AR5212) {
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05002301 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0);
2302 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002303 }
2304
2305 /*
2306 * Set BSSID which triggers the "SME Join" operation
2307 */
2308 low_id = AR5K_LOW_ID(bssid);
2309 high_id = AR5K_HIGH_ID(bssid);
2310 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
2311 ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
2312 AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
2313
2314 if (assoc_id == 0) {
2315 ath5k_hw_disable_pspoll(ah);
2316 return;
2317 }
2318
2319 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
2320 tim_offset ? tim_offset + 4 : 0);
2321
2322 ath5k_hw_enable_pspoll(ah, NULL, 0);
2323}
2324/**
2325 * ath5k_hw_set_bssid_mask - set common bits we should listen to
2326 *
2327 * The bssid_mask is a utility used by AR5212 hardware to inform the hardware
2328 * which bits of the interface's MAC address should be looked at when trying
2329 * to decide which packets to ACK. In station mode every bit matters. In AP
2330 * mode with a single BSS every bit matters as well. In AP mode with
2331 * multiple BSSes not every bit matters.
2332 *
2333 * @ah: the &struct ath5k_hw
2334 * @mask: the bssid_mask, a u8 array of size ETH_ALEN
2335 *
2336 * Note that this is a simple filter and *does* not filter out all
2337 * relevant frames. Some non-relevant frames will get through, probability
2338 * jocks are welcomed to compute.
2339 *
2340 * When handling multiple BSSes (or VAPs) you can get the BSSID mask by
2341 * computing the set of:
2342 *
2343 * ~ ( MAC XOR BSSID )
2344 *
2345 * When you do this you are essentially computing the common bits. Later it
2346 * is assumed the harware will "and" (&) the BSSID mask with the MAC address
2347 * to obtain the relevant bits which should match on the destination frame.
2348 *
2349 * Simple example: on your card you have have two BSSes you have created with
2350 * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
2351 * There is another BSSID-03 but you are not part of it. For simplicity's sake,
2352 * assuming only 4 bits for a mac address and for BSSIDs you can then have:
2353 *
2354 * \
2355 * MAC: 0001 |
2356 * BSSID-01: 0100 | --> Belongs to us
2357 * BSSID-02: 1001 |
2358 * /
2359 * -------------------
2360 * BSSID-03: 0110 | --> External
2361 * -------------------
2362 *
2363 * Our bssid_mask would then be:
2364 *
2365 * On loop iteration for BSSID-01:
2366 * ~(0001 ^ 0100) -> ~(0101)
2367 * -> 1010
2368 * bssid_mask = 1010
2369 *
2370 * On loop iteration for BSSID-02:
2371 * bssid_mask &= ~(0001 ^ 1001)
2372 * bssid_mask = (1010) & ~(0001 ^ 1001)
2373 * bssid_mask = (1010) & ~(1001)
2374 * bssid_mask = (1010) & (0110)
2375 * bssid_mask = 0010
2376 *
2377 * A bssid_mask of 0010 means "only pay attention to the second least
2378 * significant bit". This is because its the only bit common
2379 * amongst the MAC and all BSSIDs we support. To findout what the real
2380 * common bit is we can simply "&" the bssid_mask now with any BSSID we have
2381 * or our MAC address (we assume the hardware uses the MAC address).
2382 *
2383 * Now, suppose there's an incoming frame for BSSID-03:
2384 *
2385 * IFRAME-01: 0110
2386 *
2387 * An easy eye-inspeciton of this already should tell you that this frame
2388 * will not pass our check. This is beacuse the bssid_mask tells the
2389 * hardware to only look at the second least significant bit and the
2390 * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
2391 * as 1, which does not match 0.
2392 *
2393 * So with IFRAME-01 we *assume* the hardware will do:
2394 *
2395 * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
2396 * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
2397 * --> allow = (0010) == 0000 ? 1 : 0;
2398 * --> allow = 0
2399 *
2400 * Lets now test a frame that should work:
2401 *
2402 * IFRAME-02: 0001 (we should allow)
2403 *
2404 * allow = (0001 & 1010) == 1010
2405 *
2406 * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
2407 * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0;
2408 * --> allow = (0010) == (0010)
2409 * --> allow = 1
2410 *
2411 * Other examples:
2412 *
2413 * IFRAME-03: 0100 --> allowed
2414 * IFRAME-04: 1001 --> allowed
2415 * IFRAME-05: 1101 --> allowed but its not for us!!!
2416 *
2417 */
2418int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
2419{
2420 u32 low_id, high_id;
2421 ATH5K_TRACE(ah->ah_sc);
2422
2423 if (ah->ah_version == AR5K_AR5212) {
2424 low_id = AR5K_LOW_ID(mask);
2425 high_id = AR5K_HIGH_ID(mask);
2426
2427 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
2428 ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
2429
2430 return 0;
2431 }
2432
2433 return -EIO;
2434}
2435
2436/*
2437 * Receive start/stop functions
2438 */
2439
2440/*
2441 * Start receive on PCU
2442 */
2443void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
2444{
2445 ATH5K_TRACE(ah->ah_sc);
2446 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05002447
2448 /* TODO: ANI Support */
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002449}
2450
2451/*
2452 * Stop receive on PCU
2453 */
2454void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah)
2455{
2456 ATH5K_TRACE(ah->ah_sc);
2457 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
Nick Kossifidisc87cdfd2008-03-07 11:48:21 -05002458
2459 /* TODO: ANI Support */
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002460}
2461
2462/*
2463 * RX Filter functions
2464 */
2465
2466/*
2467 * Set multicast filter
2468 */
2469void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
2470{
2471 ATH5K_TRACE(ah->ah_sc);
2472 /* Set the multicat filter */
2473 ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
2474 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
2475}
2476
2477/*
2478 * Set multicast filter by index
2479 */
2480int ath5k_hw_set_mcast_filterindex(struct ath5k_hw *ah, u32 index)
2481{
2482
2483 ATH5K_TRACE(ah->ah_sc);
2484 if (index >= 64)
2485 return -EINVAL;
2486 else if (index >= 32)
2487 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
2488 (1 << (index - 32)));
2489 else
2490 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
2491
2492 return 0;
2493}
2494
2495/*
2496 * Clear Multicast filter by index
2497 */
2498int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
2499{
2500
2501 ATH5K_TRACE(ah->ah_sc);
2502 if (index >= 64)
2503 return -EINVAL;
2504 else if (index >= 32)
2505 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
2506 (1 << (index - 32)));
2507 else
2508 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
2509
2510 return 0;
2511}
2512
2513/*
2514 * Get current rx filter
2515 */
2516u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
2517{
2518 u32 data, filter = 0;
2519
2520 ATH5K_TRACE(ah->ah_sc);
2521 filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
2522
2523 /*Radar detection for 5212*/
2524 if (ah->ah_version == AR5K_AR5212) {
2525 data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
2526
2527 if (data & AR5K_PHY_ERR_FIL_RADAR)
2528 filter |= AR5K_RX_FILTER_RADARERR;
2529 if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
2530 filter |= AR5K_RX_FILTER_PHYERR;
2531 }
2532
2533 return filter;
2534}
2535
2536/*
2537 * Set rx filter
2538 */
2539void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
2540{
2541 u32 data = 0;
2542
2543 ATH5K_TRACE(ah->ah_sc);
2544
2545 /* Set PHY error filter register on 5212*/
2546 if (ah->ah_version == AR5K_AR5212) {
2547 if (filter & AR5K_RX_FILTER_RADARERR)
2548 data |= AR5K_PHY_ERR_FIL_RADAR;
2549 if (filter & AR5K_RX_FILTER_PHYERR)
2550 data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
2551 }
2552
2553 /*
2554 * The AR5210 uses promiscous mode to detect radar activity
2555 */
2556 if (ah->ah_version == AR5K_AR5210 &&
2557 (filter & AR5K_RX_FILTER_RADARERR)) {
2558 filter &= ~AR5K_RX_FILTER_RADARERR;
2559 filter |= AR5K_RX_FILTER_PROM;
2560 }
2561
2562 /*Zero length DMA*/
2563 if (data)
2564 AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
2565 else
2566 AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
2567
2568 /*Write RX Filter register*/
2569 ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
2570
2571 /*Write PHY error filter register on 5212*/
2572 if (ah->ah_version == AR5K_AR5212)
2573 ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
2574
2575}
2576
2577/*
2578 * Beacon related functions
2579 */
2580
2581/*
2582 * Get a 32bit TSF
2583 */
2584u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
2585{
2586 ATH5K_TRACE(ah->ah_sc);
2587 return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
2588}
2589
2590/*
2591 * Get the full 64bit TSF
2592 */
2593u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
2594{
2595 u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
2596 ATH5K_TRACE(ah->ah_sc);
2597
2598 return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
2599}
2600
2601/*
2602 * Force a TSF reset
2603 */
2604void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
2605{
2606 ATH5K_TRACE(ah->ah_sc);
2607 AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_RESET_TSF);
2608}
2609
2610/*
2611 * Initialize beacon timers
2612 */
2613void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
2614{
2615 u32 timer1, timer2, timer3;
2616
2617 ATH5K_TRACE(ah->ah_sc);
2618 /*
2619 * Set the additional timers by mode
2620 */
2621 switch (ah->ah_op_mode) {
2622 case IEEE80211_IF_TYPE_STA:
2623 if (ah->ah_version == AR5K_AR5210) {
2624 timer1 = 0xffffffff;
2625 timer2 = 0xffffffff;
2626 } else {
2627 timer1 = 0x0000ffff;
2628 timer2 = 0x0007ffff;
2629 }
2630 break;
2631
2632 default:
Bruno Randolf1008e0f2008-01-18 21:51:19 +09002633 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
2634 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02002635 }
2636
2637 timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
2638
2639 /*
2640 * Set the beacon register and enable all timers.
2641 * (next beacon, DMA beacon, software beacon, ATIM window time)
2642 */
2643 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
2644 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
2645 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
2646 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
2647
2648 ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
2649 AR5K_BEACON_RESET_TSF | AR5K_BEACON_ENABLE),
2650 AR5K_BEACON);
2651}
2652
2653#if 0
2654/*
2655 * Set beacon timers
2656 */
2657int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
2658 const struct ath5k_beacon_state *state)
2659{
2660 u32 cfp_period, next_cfp, dtim, interval, next_beacon;
2661
2662 /*
2663 * TODO: should be changed through *state
2664 * review struct ath5k_beacon_state struct
2665 *
2666 * XXX: These are used for cfp period bellow, are they
2667 * ok ? Is it O.K. for tsf here to be 0 or should we use
2668 * get_tsf ?
2669 */
2670 u32 dtim_count = 0; /* XXX */
2671 u32 cfp_count = 0; /* XXX */
2672 u32 tsf = 0; /* XXX */
2673
2674 ATH5K_TRACE(ah->ah_sc);
2675 /* Return on an invalid beacon state */
2676 if (state->bs_interval < 1)
2677 return -EINVAL;
2678
2679 interval = state->bs_interval;
2680 dtim = state->bs_dtim_period;
2681
2682 /*
2683 * PCF support?
2684 */
2685 if (state->bs_cfp_period > 0) {
2686 /*
2687 * Enable PCF mode and set the CFP
2688 * (Contention Free Period) and timer registers
2689 */
2690 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
2691 state->bs_interval;
2692 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
2693 state->bs_interval;
2694
2695 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
2696 AR5K_STA_ID1_DEFAULT_ANTENNA |
2697 AR5K_STA_ID1_PCF);
2698 ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
2699 ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
2700 AR5K_CFP_DUR);
2701 ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
2702 next_cfp)) << 3, AR5K_TIMER2);
2703 } else {
2704 /* Disable PCF mode */
2705 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
2706 AR5K_STA_ID1_DEFAULT_ANTENNA |
2707 AR5K_STA_ID1_PCF);
2708 }
2709
2710 /*
2711 * Enable the beacon timer register
2712 */
2713 ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
2714
2715 /*
2716 * Start the beacon timers
2717 */
2718 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &~
2719 (AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
2720 AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
2721 AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
2722 AR5K_BEACON_PERIOD), AR5K_BEACON);
2723
2724 /*
2725 * Write new beacon miss threshold, if it appears to be valid
2726 * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
2727 * and return if its not in range. We can test this by reading value and
2728 * setting value to a largest value and seeing which values register.
2729 */
2730
2731 AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
2732 state->bs_bmiss_threshold);
2733
2734 /*
2735 * Set sleep control register
2736 * XXX: Didn't find this in 5210 code but since this register
2737 * exists also in ar5k's 5210 headers i leave it as common code.
2738 */
2739 AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
2740 (state->bs_sleep_duration - 3) << 3);
2741
2742 /*
2743 * Set enhanced sleep registers on 5212
2744 */
2745 if (ah->ah_version == AR5K_AR5212) {
2746 if (state->bs_sleep_duration > state->bs_interval &&
2747 roundup(state->bs_sleep_duration, interval) ==
2748 state->bs_sleep_duration)
2749 interval = state->bs_sleep_duration;
2750
2751 if (state->bs_sleep_duration > dtim && (dtim == 0 ||
2752 roundup(state->bs_sleep_duration, dtim) ==
2753 state->bs_sleep_duration))
2754 dtim = state->bs_sleep_duration;
2755
2756 if (interval > dtim)
2757 return -EINVAL;
2758
2759 next_beacon = interval == dtim ? state->bs_next_dtim :
2760 state->bs_next_beacon;
2761
2762 ath5k_hw_reg_write(ah,
2763 AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
2764 AR5K_SLEEP0_NEXT_DTIM) |
2765 AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
2766 AR5K_SLEEP0_ENH_SLEEP_EN |
2767 AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
2768
2769 ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
2770 AR5K_SLEEP1_NEXT_TIM) |
2771 AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
2772
2773 ath5k_hw_reg_write(ah,
2774 AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
2775 AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
2776 }
2777
2778 return 0;
2779}
2780
2781/*
2782 * Reset beacon timers
2783 */
2784void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
2785{
2786 ATH5K_TRACE(ah->ah_sc);
2787 /*
2788 * Disable beacon timer
2789 */
2790 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
2791
2792 /*
2793 * Disable some beacon register values
2794 */
2795 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
2796 AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
2797 ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
2798}
2799
2800/*
2801 * Wait for beacon queue to finish
2802 */
2803int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
2804{
2805 unsigned int i;
2806 int ret;
2807
2808 ATH5K_TRACE(ah->ah_sc);
2809
2810 /* 5210 doesn't have QCU*/
2811 if (ah->ah_version == AR5K_AR5210) {
2812 /*
2813 * Wait for beaconn queue to finish by checking
2814 * Control Register and Beacon Status Register.
2815 */
2816 for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
2817 if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
2818 ||
2819 !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
2820 break;
2821 udelay(10);
2822 }
2823
2824 /* Timeout... */
2825 if (i <= 0) {
2826 /*
2827 * Re-schedule the beacon queue
2828 */
2829 ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
2830 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
2831 AR5K_BCR);
2832
2833 return -EIO;
2834 }
2835 ret = 0;
2836 } else {
2837 /*5211/5212*/
2838 ret = ath5k_hw_register_timeout(ah,
2839 AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
2840 AR5K_QCU_STS_FRMPENDCNT, 0, false);
2841
2842 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
2843 return -EIO;
2844 }
2845
2846 return ret;
2847}
2848#endif
2849
2850/*
2851 * Update mib counters (statistics)
2852 */
2853void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
2854 struct ath5k_mib_stats *statistics)
2855{
2856 ATH5K_TRACE(ah->ah_sc);
2857 /* Read-And-Clear */
2858 statistics->ackrcv_bad += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
2859 statistics->rts_bad += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
2860 statistics->rts_good += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
2861 statistics->fcs_bad += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
2862 statistics->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
2863
2864 /* Reset profile count registers on 5212*/
2865 if (ah->ah_version == AR5K_AR5212) {
2866 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
2867 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
2868 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
2869 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
2870 }
2871}
2872
2873/** ath5k_hw_set_ack_bitrate - set bitrate for ACKs
2874 *
2875 * @ah: the &struct ath5k_hw
2876 * @high: determines if to use low bit rate or now
2877 */
2878void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
2879{
2880 if (ah->ah_version != AR5K_AR5212)
2881 return;
2882 else {
2883 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
2884 if (high)
2885 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
2886 else
2887 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
2888 }
2889}
2890
2891
2892/*
2893 * ACK/CTS Timeouts
2894 */
2895
2896/*
2897 * Set ACK timeout on PCU
2898 */
2899int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
2900{
2901 ATH5K_TRACE(ah->ah_sc);
2902 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
2903 ah->ah_turbo) <= timeout)
2904 return -EINVAL;
2905
2906 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
2907 ath5k_hw_htoclock(timeout, ah->ah_turbo));
2908
2909 return 0;
2910}
2911
2912/*
2913 * Read the ACK timeout from PCU
2914 */
2915unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
2916{
2917 ATH5K_TRACE(ah->ah_sc);
2918
2919 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
2920 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
2921}
2922
2923/*
2924 * Set CTS timeout on PCU
2925 */
2926int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
2927{
2928 ATH5K_TRACE(ah->ah_sc);
2929 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
2930 ah->ah_turbo) <= timeout)
2931 return -EINVAL;
2932
2933 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
2934 ath5k_hw_htoclock(timeout, ah->ah_turbo));
2935
2936 return 0;
2937}
2938
2939/*
2940 * Read CTS timeout from PCU
2941 */
2942unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
2943{
2944 ATH5K_TRACE(ah->ah_sc);
2945 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
2946 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
2947}
2948
2949/*
2950 * Key table (WEP) functions
2951 */
2952
2953int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
2954{
2955 unsigned int i;
2956
2957 ATH5K_TRACE(ah->ah_sc);
2958 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
2959
2960 for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
2961 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
2962
2963 /* Set NULL encryption on non-5210*/
2964 if (ah->ah_version != AR5K_AR5210)
2965 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
2966 AR5K_KEYTABLE_TYPE(entry));
2967
2968 return 0;
2969}
2970
2971int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
2972{
2973 ATH5K_TRACE(ah->ah_sc);
2974 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
2975
2976 /* Check the validation flag at the end of the entry */
2977 return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
2978 AR5K_KEYTABLE_VALID;
2979}
2980
2981int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
2982 const struct ieee80211_key_conf *key, const u8 *mac)
2983{
2984 unsigned int i;
2985 __le32 key_v[5] = {};
2986 u32 keytype;
2987
2988 ATH5K_TRACE(ah->ah_sc);
2989
2990 /* key->keylen comes in from mac80211 in bytes */
2991
2992 if (key->keylen > AR5K_KEYTABLE_SIZE / 8)
2993 return -EOPNOTSUPP;
2994
2995 switch (key->keylen) {
2996 /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */
2997 case 40 / 8:
2998 memcpy(&key_v[0], key->key, 5);
2999 keytype = AR5K_KEYTABLE_TYPE_40;
3000 break;
3001
3002 /* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */
3003 case 104 / 8:
3004 memcpy(&key_v[0], &key->key[0], 6);
3005 memcpy(&key_v[2], &key->key[6], 6);
3006 memcpy(&key_v[4], &key->key[12], 1);
3007 keytype = AR5K_KEYTABLE_TYPE_104;
3008 break;
3009 /* WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */
3010 case 128 / 8:
3011 memcpy(&key_v[0], &key->key[0], 6);
3012 memcpy(&key_v[2], &key->key[6], 6);
3013 memcpy(&key_v[4], &key->key[12], 4);
3014 keytype = AR5K_KEYTABLE_TYPE_128;
3015 break;
3016
3017 default:
3018 return -EINVAL; /* shouldn't happen */
3019 }
3020
3021 for (i = 0; i < ARRAY_SIZE(key_v); i++)
3022 ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
3023 AR5K_KEYTABLE_OFF(entry, i));
3024
3025 ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
3026
3027 return ath5k_hw_set_key_lladdr(ah, entry, mac);
3028}
3029
3030int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
3031{
3032 u32 low_id, high_id;
3033
3034 ATH5K_TRACE(ah->ah_sc);
3035 /* Invalid entry (key table overflow) */
3036 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
3037
3038 /* MAC may be NULL if it's a broadcast key. In this case no need to
3039 * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
3040 if (unlikely(mac == NULL)) {
3041 low_id = 0xffffffff;
3042 high_id = 0xffff | AR5K_KEYTABLE_VALID;
3043 } else {
3044 low_id = AR5K_LOW_ID(mac);
3045 high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
3046 }
3047
3048 ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
3049 ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
3050
3051 return 0;
3052}
3053
3054
3055/********************************************\
3056Queue Control Unit, DFS Control Unit Functions
3057\********************************************/
3058
3059/*
3060 * Initialize a transmit queue
3061 */
3062int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
3063 struct ath5k_txq_info *queue_info)
3064{
3065 unsigned int queue;
3066 int ret;
3067
3068 ATH5K_TRACE(ah->ah_sc);
3069
3070 /*
3071 * Get queue by type
3072 */
3073 /*5210 only has 2 queues*/
3074 if (ah->ah_version == AR5K_AR5210) {
3075 switch (queue_type) {
3076 case AR5K_TX_QUEUE_DATA:
3077 queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
3078 break;
3079 case AR5K_TX_QUEUE_BEACON:
3080 case AR5K_TX_QUEUE_CAB:
3081 queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
3082 break;
3083 default:
3084 return -EINVAL;
3085 }
3086 } else {
3087 switch (queue_type) {
3088 case AR5K_TX_QUEUE_DATA:
3089 for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
3090 ah->ah_txq[queue].tqi_type !=
3091 AR5K_TX_QUEUE_INACTIVE; queue++) {
3092
3093 if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
3094 return -EINVAL;
3095 }
3096 break;
3097 case AR5K_TX_QUEUE_UAPSD:
3098 queue = AR5K_TX_QUEUE_ID_UAPSD;
3099 break;
3100 case AR5K_TX_QUEUE_BEACON:
3101 queue = AR5K_TX_QUEUE_ID_BEACON;
3102 break;
3103 case AR5K_TX_QUEUE_CAB:
3104 queue = AR5K_TX_QUEUE_ID_CAB;
3105 break;
3106 case AR5K_TX_QUEUE_XR_DATA:
3107 if (ah->ah_version != AR5K_AR5212)
3108 ATH5K_ERR(ah->ah_sc,
3109 "XR data queues only supported in"
3110 " 5212!\n");
3111 queue = AR5K_TX_QUEUE_ID_XR_DATA;
3112 break;
3113 default:
3114 return -EINVAL;
3115 }
3116 }
3117
3118 /*
3119 * Setup internal queue structure
3120 */
3121 memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
3122 ah->ah_txq[queue].tqi_type = queue_type;
3123
3124 if (queue_info != NULL) {
3125 queue_info->tqi_type = queue_type;
3126 ret = ath5k_hw_setup_tx_queueprops(ah, queue, queue_info);
3127 if (ret)
3128 return ret;
3129 }
3130 /*
3131 * We use ah_txq_status to hold a temp value for
3132 * the Secondary interrupt mask registers on 5211+
3133 * check out ath5k_hw_reset_tx_queue
3134 */
3135 AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
3136
3137 return queue;
3138}
3139
3140/*
3141 * Setup a transmit queue
3142 */
3143int ath5k_hw_setup_tx_queueprops(struct ath5k_hw *ah, int queue,
3144 const struct ath5k_txq_info *queue_info)
3145{
3146 ATH5K_TRACE(ah->ah_sc);
3147 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3148
3149 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
3150 return -EIO;
3151
3152 memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
3153
3154 /*XXX: Is this supported on 5210 ?*/
3155 if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
3156 ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
3157 (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
3158 queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
3159 ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
3160
3161 return 0;
3162}
3163
3164/*
3165 * Get properties for a specific transmit queue
3166 */
3167int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
3168 struct ath5k_txq_info *queue_info)
3169{
3170 ATH5K_TRACE(ah->ah_sc);
3171 memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
3172 return 0;
3173}
3174
3175/*
3176 * Set a transmit queue inactive
3177 */
3178void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
3179{
3180 ATH5K_TRACE(ah->ah_sc);
3181 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
3182 return;
3183
3184 /* This queue will be skipped in further operations */
3185 ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
3186 /*For SIMR setup*/
3187 AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
3188}
3189
3190/*
3191 * Set DFS params for a transmit queue
3192 */
3193int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
3194{
3195 u32 cw_min, cw_max, retry_lg, retry_sh;
3196 struct ath5k_txq_info *tq = &ah->ah_txq[queue];
3197
3198 ATH5K_TRACE(ah->ah_sc);
3199 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3200
3201 tq = &ah->ah_txq[queue];
3202
3203 if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
3204 return 0;
3205
3206 if (ah->ah_version == AR5K_AR5210) {
3207 /* Only handle data queues, others will be ignored */
3208 if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
3209 return 0;
3210
3211 /* Set Slot time */
Joe Perchese9010e22008-03-07 14:21:16 -08003212 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003213 AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
3214 AR5K_SLOT_TIME);
3215 /* Set ACK_CTS timeout */
Joe Perchese9010e22008-03-07 14:21:16 -08003216 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003217 AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
3218 AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
3219 /* Set Transmit Latency */
Joe Perchese9010e22008-03-07 14:21:16 -08003220 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003221 AR5K_INIT_TRANSMIT_LATENCY_TURBO :
3222 AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
3223 /* Set IFS0 */
Joe Perchese9010e22008-03-07 14:21:16 -08003224 if (ah->ah_turbo)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003225 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
3226 (ah->ah_aifs + tq->tqi_aifs) *
3227 AR5K_INIT_SLOT_TIME_TURBO) <<
3228 AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
3229 AR5K_IFS0);
3230 else
3231 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
3232 (ah->ah_aifs + tq->tqi_aifs) *
3233 AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
3234 AR5K_INIT_SIFS, AR5K_IFS0);
3235
3236 /* Set IFS1 */
Joe Perchese9010e22008-03-07 14:21:16 -08003237 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003238 AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
3239 AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
3240 /* Set PHY register 0x9844 (??) */
Joe Perchese9010e22008-03-07 14:21:16 -08003241 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003242 (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x38 :
3243 (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x1C,
3244 AR5K_PHY(17));
3245 /* Set Frame Control Register */
Joe Perchese9010e22008-03-07 14:21:16 -08003246 ath5k_hw_reg_write(ah, ah->ah_turbo ?
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003247 (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
3248 AR5K_PHY_TURBO_SHORT | 0x2020) :
3249 (AR5K_PHY_FRAME_CTL_INI | 0x1020),
3250 AR5K_PHY_FRAME_CTL_5210);
3251 }
3252
3253 /*
3254 * Calculate cwmin/max by channel mode
3255 */
3256 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
3257 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
3258 ah->ah_aifs = AR5K_TUNE_AIFS;
3259 /*XR is only supported on 5212*/
3260 if (IS_CHAN_XR(ah->ah_current_channel) &&
3261 ah->ah_version == AR5K_AR5212) {
3262 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
3263 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
3264 ah->ah_aifs = AR5K_TUNE_AIFS_XR;
3265 /*B mode is not supported on 5210*/
3266 } else if (IS_CHAN_B(ah->ah_current_channel) &&
3267 ah->ah_version != AR5K_AR5210) {
3268 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
3269 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
3270 ah->ah_aifs = AR5K_TUNE_AIFS_11B;
3271 }
3272
3273 cw_min = 1;
3274 while (cw_min < ah->ah_cw_min)
3275 cw_min = (cw_min << 1) | 1;
3276
3277 cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
3278 ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
3279 cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
3280 ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
3281
3282 /*
3283 * Calculate and set retry limits
3284 */
Joe Perchese9010e22008-03-07 14:21:16 -08003285 if (ah->ah_software_retry) {
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003286 /* XXX Need to test this */
3287 retry_lg = ah->ah_limit_tx_retries;
3288 retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
3289 AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
3290 } else {
3291 retry_lg = AR5K_INIT_LG_RETRY;
3292 retry_sh = AR5K_INIT_SH_RETRY;
3293 }
3294
3295 /*No QCU/DCU [5210]*/
3296 if (ah->ah_version == AR5K_AR5210) {
3297 ath5k_hw_reg_write(ah,
3298 (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
3299 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
3300 AR5K_NODCU_RETRY_LMT_SLG_RETRY)
3301 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
3302 AR5K_NODCU_RETRY_LMT_SSH_RETRY)
3303 | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
3304 | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
3305 AR5K_NODCU_RETRY_LMT);
3306 } else {
3307 /*QCU/DCU [5211+]*/
3308 ath5k_hw_reg_write(ah,
3309 AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
3310 AR5K_DCU_RETRY_LMT_SLG_RETRY) |
3311 AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
3312 AR5K_DCU_RETRY_LMT_SSH_RETRY) |
3313 AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
3314 AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
3315 AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
3316
3317 /*===Rest is also for QCU/DCU only [5211+]===*/
3318
3319 /*
3320 * Set initial content window (cw_min/cw_max)
3321 * and arbitrated interframe space (aifs)...
3322 */
3323 ath5k_hw_reg_write(ah,
3324 AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
3325 AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
3326 AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
3327 AR5K_DCU_LCL_IFS_AIFS),
3328 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
3329
3330 /*
3331 * Set misc registers
3332 */
3333 ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY,
3334 AR5K_QUEUE_MISC(queue));
3335
3336 if (tq->tqi_cbr_period) {
3337 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
3338 AR5K_QCU_CBRCFG_INTVAL) |
3339 AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
3340 AR5K_QCU_CBRCFG_ORN_THRES),
3341 AR5K_QUEUE_CBRCFG(queue));
3342 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3343 AR5K_QCU_MISC_FRSHED_CBR);
3344 if (tq->tqi_cbr_overflow_limit)
3345 AR5K_REG_ENABLE_BITS(ah,
3346 AR5K_QUEUE_MISC(queue),
3347 AR5K_QCU_MISC_CBR_THRES_ENABLE);
3348 }
3349
3350 if (tq->tqi_ready_time)
3351 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
3352 AR5K_QCU_RDYTIMECFG_INTVAL) |
3353 AR5K_QCU_RDYTIMECFG_ENABLE,
3354 AR5K_QUEUE_RDYTIMECFG(queue));
3355
3356 if (tq->tqi_burst_time) {
3357 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
3358 AR5K_DCU_CHAN_TIME_DUR) |
3359 AR5K_DCU_CHAN_TIME_ENABLE,
3360 AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
3361
3362 if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
3363 AR5K_REG_ENABLE_BITS(ah,
3364 AR5K_QUEUE_MISC(queue),
3365 AR5K_QCU_MISC_TXE);
3366 }
3367
3368 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
3369 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
3370 AR5K_QUEUE_DFS_MISC(queue));
3371
3372 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
3373 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
3374 AR5K_QUEUE_DFS_MISC(queue));
3375
3376 /*
3377 * Set registers by queue type
3378 */
3379 switch (tq->tqi_type) {
3380 case AR5K_TX_QUEUE_BEACON:
3381 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3382 AR5K_QCU_MISC_FRSHED_DBA_GT |
3383 AR5K_QCU_MISC_CBREXP_BCN |
3384 AR5K_QCU_MISC_BCN_ENABLE);
3385
3386 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
3387 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
3388 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
3389 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
3390 AR5K_DCU_MISC_BCN_ENABLE);
3391
3392 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
3393 (AR5K_TUNE_SW_BEACON_RESP -
3394 AR5K_TUNE_DMA_BEACON_RESP) -
3395 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
3396 AR5K_QCU_RDYTIMECFG_ENABLE,
3397 AR5K_QUEUE_RDYTIMECFG(queue));
3398 break;
3399
3400 case AR5K_TX_QUEUE_CAB:
3401 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3402 AR5K_QCU_MISC_FRSHED_DBA_GT |
3403 AR5K_QCU_MISC_CBREXP |
3404 AR5K_QCU_MISC_CBREXP_BCN);
3405
3406 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
3407 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
3408 AR5K_DCU_MISC_ARBLOCK_CTL_S));
3409 break;
3410
3411 case AR5K_TX_QUEUE_UAPSD:
3412 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3413 AR5K_QCU_MISC_CBREXP);
3414 break;
3415
3416 case AR5K_TX_QUEUE_DATA:
3417 default:
3418 break;
3419 }
3420
3421 /*
3422 * Enable interrupts for this tx queue
3423 * in the secondary interrupt mask registers
3424 */
3425 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
3426 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
3427
3428 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
3429 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
3430
3431 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
3432 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
3433
3434 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
3435 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
3436
3437 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
3438 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
3439
3440
3441 /* Update secondary interrupt mask registers */
3442 ah->ah_txq_imr_txok &= ah->ah_txq_status;
3443 ah->ah_txq_imr_txerr &= ah->ah_txq_status;
3444 ah->ah_txq_imr_txurn &= ah->ah_txq_status;
3445 ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
3446 ah->ah_txq_imr_txeol &= ah->ah_txq_status;
3447
3448 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
3449 AR5K_SIMR0_QCU_TXOK) |
3450 AR5K_REG_SM(ah->ah_txq_imr_txdesc,
3451 AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
3452 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
3453 AR5K_SIMR1_QCU_TXERR) |
3454 AR5K_REG_SM(ah->ah_txq_imr_txeol,
3455 AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
3456 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txurn,
3457 AR5K_SIMR2_QCU_TXURN), AR5K_SIMR2);
3458 }
3459
3460 return 0;
3461}
3462
3463/*
3464 * Get number of pending frames
3465 * for a specific queue [5211+]
3466 */
3467u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) {
3468 ATH5K_TRACE(ah->ah_sc);
3469 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3470
3471 /* Return if queue is declared inactive */
3472 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
3473 return false;
3474
3475 /* XXX: How about AR5K_CFG_TXCNT ? */
3476 if (ah->ah_version == AR5K_AR5210)
3477 return false;
3478
3479 return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT;
3480}
3481
3482/*
3483 * Set slot time
3484 */
3485int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
3486{
3487 ATH5K_TRACE(ah->ah_sc);
3488 if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
3489 return -EINVAL;
3490
3491 if (ah->ah_version == AR5K_AR5210)
3492 ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
3493 ah->ah_turbo), AR5K_SLOT_TIME);
3494 else
3495 ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
3496
3497 return 0;
3498}
3499
3500/*
3501 * Get slot time
3502 */
3503unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
3504{
3505 ATH5K_TRACE(ah->ah_sc);
3506 if (ah->ah_version == AR5K_AR5210)
3507 return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
3508 AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
3509 else
3510 return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
3511}
3512
3513
3514/******************************\
3515 Hardware Descriptor Functions
3516\******************************/
3517
3518/*
3519 * TX Descriptor
3520 */
3521
3522/*
3523 * Initialize the 2-word tx descriptor on 5210/5211
3524 */
3525static int
3526ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3527 unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type,
3528 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
3529 unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
3530 unsigned int rtscts_rate, unsigned int rtscts_duration)
3531{
3532 u32 frame_type;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003533 struct ath5k_hw_2w_tx_ctl *tx_ctl;
Bruno Randolf281c56d2008-02-05 18:44:55 +09003534 unsigned int frame_len;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003535
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003536 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003537
3538 /*
3539 * Validate input
3540 * - Zero retries don't make sense.
3541 * - A zero rate will put the HW into a mode where it continously sends
3542 * noise on the channel, so it is important to avoid this.
3543 */
3544 if (unlikely(tx_tries0 == 0)) {
3545 ATH5K_ERR(ah->ah_sc, "zero retries\n");
3546 WARN_ON(1);
3547 return -EINVAL;
3548 }
3549 if (unlikely(tx_rate0 == 0)) {
3550 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3551 WARN_ON(1);
3552 return -EINVAL;
3553 }
3554
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003555 /* Clear descriptor */
3556 memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003557
3558 /* Setup control descriptor */
3559
3560 /* Verify and set frame length */
Bruno Randolf281c56d2008-02-05 18:44:55 +09003561
3562 /* remove padding we might have added before */
3563 frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
3564
3565 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003566 return -EINVAL;
3567
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003568 tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003569
3570 /* Verify and set buffer length */
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003571
3572 /* NB: beacon's BufLen must be a multiple of 4 bytes */
3573 if(type == AR5K_PKT_TYPE_BEACON)
Bruno Randolf281c56d2008-02-05 18:44:55 +09003574 pkt_len = roundup(pkt_len, 4);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003575
Bruno Randolf281c56d2008-02-05 18:44:55 +09003576 if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003577 return -EINVAL;
3578
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003579 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003580
3581 /*
3582 * Verify and set header length
3583 * XXX: I only found that on 5210 code, does it work on 5211 ?
3584 */
3585 if (ah->ah_version == AR5K_AR5210) {
3586 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
3587 return -EINVAL;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003588 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003589 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
3590 }
3591
3592 /*Diferences between 5210-5211*/
3593 if (ah->ah_version == AR5K_AR5210) {
3594 switch (type) {
3595 case AR5K_PKT_TYPE_BEACON:
3596 case AR5K_PKT_TYPE_PROBE_RESP:
3597 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
3598 case AR5K_PKT_TYPE_PIFS:
3599 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
3600 default:
3601 frame_type = type /*<< 2 ?*/;
3602 }
3603
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003604 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003605 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
3606 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3607 } else {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003608 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003609 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
3610 AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003611 tx_ctl->tx_control_1 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003612 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
3613 }
3614#define _TX_FLAGS(_c, _flag) \
3615 if (flags & AR5K_TXDESC_##_flag) \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003616 tx_ctl->tx_control_##_c |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003617 AR5K_2W_TX_DESC_CTL##_c##_##_flag
3618
3619 _TX_FLAGS(0, CLRDMASK);
3620 _TX_FLAGS(0, VEOL);
3621 _TX_FLAGS(0, INTREQ);
3622 _TX_FLAGS(0, RTSENA);
3623 _TX_FLAGS(1, NOACK);
3624
3625#undef _TX_FLAGS
3626
3627 /*
3628 * WEP crap
3629 */
3630 if (key_index != AR5K_TXKEYIX_INVALID) {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003631 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003632 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003633 tx_ctl->tx_control_1 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003634 AR5K_REG_SM(key_index,
3635 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3636 }
3637
3638 /*
3639 * RTS/CTS Duration [5210 ?]
3640 */
3641 if ((ah->ah_version == AR5K_AR5210) &&
3642 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003643 tx_ctl->tx_control_1 |= rtscts_duration &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003644 AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
3645
3646 return 0;
3647}
3648
3649/*
3650 * Initialize the 4-word tx descriptor on 5212
3651 */
3652static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
3653 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
3654 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
3655 unsigned int tx_tries0, unsigned int key_index,
3656 unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate,
3657 unsigned int rtscts_duration)
3658{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003659 struct ath5k_hw_4w_tx_ctl *tx_ctl;
Bruno Randolf281c56d2008-02-05 18:44:55 +09003660 unsigned int frame_len;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003661
3662 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003663 tx_ctl = &desc->ud.ds_tx5212.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_tx5212, 0, sizeof(struct ath5k_hw_5212_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_4W_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_4W_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_4W_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_4W_TX_DESC_CTL1_BUF_LEN;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003707
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003708 tx_ctl->tx_control_0 |=
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003709 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
3710 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003711 tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003712 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003713 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003714 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003715 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003716
3717#define _TX_FLAGS(_c, _flag) \
3718 if (flags & AR5K_TXDESC_##_flag) \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003719 tx_ctl->tx_control_##_c |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003720 AR5K_4W_TX_DESC_CTL##_c##_##_flag
3721
3722 _TX_FLAGS(0, CLRDMASK);
3723 _TX_FLAGS(0, VEOL);
3724 _TX_FLAGS(0, INTREQ);
3725 _TX_FLAGS(0, RTSENA);
3726 _TX_FLAGS(0, CTSENA);
3727 _TX_FLAGS(1, NOACK);
3728
3729#undef _TX_FLAGS
3730
3731 /*
3732 * WEP crap
3733 */
3734 if (key_index != AR5K_TXKEYIX_INVALID) {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003735 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
3736 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003737 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3738 }
3739
3740 /*
3741 * RTS/CTS
3742 */
3743 if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
3744 if ((flags & AR5K_TXDESC_RTSENA) &&
3745 (flags & AR5K_TXDESC_CTSENA))
3746 return -EINVAL;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003747 tx_ctl->tx_control_2 |= rtscts_duration &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003748 AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003749 tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003750 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
3751 }
3752
3753 return 0;
3754}
3755
3756/*
3757 * Initialize a 4-word multirate tx descriptor on 5212
3758 */
Jiri Slabyb9887632008-02-15 21:58:52 +01003759static int
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003760ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3761 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
3762 unsigned int tx_rate3, u_int tx_tries3)
3763{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003764 struct ath5k_hw_4w_tx_ctl *tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003765
3766 /*
3767 * Rates can be 0 as long as the retry count is 0 too.
3768 * A zero rate and nonzero retry count will put the HW into a mode where
3769 * it continously sends noise on the channel, so it is important to
3770 * avoid this.
3771 */
3772 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
3773 (tx_rate2 == 0 && tx_tries2 != 0) ||
3774 (tx_rate3 == 0 && tx_tries3 != 0))) {
3775 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3776 WARN_ON(1);
3777 return -EINVAL;
3778 }
3779
3780 if (ah->ah_version == AR5K_AR5212) {
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003781 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003782
3783#define _XTX_TRIES(_n) \
3784 if (tx_tries##_n) { \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003785 tx_ctl->tx_control_2 |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003786 AR5K_REG_SM(tx_tries##_n, \
3787 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003788 tx_ctl->tx_control_3 |= \
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003789 AR5K_REG_SM(tx_rate##_n, \
3790 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \
3791 }
3792
3793 _XTX_TRIES(1);
3794 _XTX_TRIES(2);
3795 _XTX_TRIES(3);
3796
3797#undef _XTX_TRIES
3798
Jiri Slabyb9887632008-02-15 21:58:52 +01003799 return 1;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003800 }
3801
Jiri Slabyb9887632008-02-15 21:58:52 +01003802 return 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003803}
3804
3805/*
3806 * Proccess the tx status descriptor on 5210/5211
3807 */
3808static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09003809 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003810{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003811 struct ath5k_hw_2w_tx_ctl *tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003812 struct ath5k_hw_tx_status *tx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003813
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003814 ATH5K_TRACE(ah->ah_sc);
3815
3816 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
3817 tx_status = &desc->ud.ds_tx5210.tx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003818
3819 /* No frame has been send or error */
3820 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
3821 return -EINPROGRESS;
3822
3823 /*
3824 * Get descriptor status
3825 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09003826 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003827 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003828 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003829 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003830 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003831 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003832 /*TODO: ts->ts_virtcol + test*/
3833 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003834 AR5K_DESC_TX_STATUS1_SEQ_NUM);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003835 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003836 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003837 ts->ts_antenna = 1;
3838 ts->ts_status = 0;
3839 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003840 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3841
3842 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
3843 if (tx_status->tx_status_0 &
3844 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003845 ts->ts_status |= AR5K_TXERR_XRETRY;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003846
3847 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003848 ts->ts_status |= AR5K_TXERR_FIFO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003849
3850 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003851 ts->ts_status |= AR5K_TXERR_FILT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003852 }
3853
3854 return 0;
3855}
3856
3857/*
3858 * Proccess a tx descriptor on 5212
3859 */
3860static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09003861 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003862{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003863 struct ath5k_hw_4w_tx_ctl *tx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003864 struct ath5k_hw_tx_status *tx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003865
3866 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003867
3868 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
3869 tx_status = &desc->ud.ds_tx5212.tx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003870
3871 /* No frame has been send or error */
3872 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
3873 return -EINPROGRESS;
3874
3875 /*
3876 * Get descriptor status
3877 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09003878 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003879 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003880 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003881 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003882 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003883 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003884 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003885 AR5K_DESC_TX_STATUS1_SEQ_NUM);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003886 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003887 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003888 ts->ts_antenna = (tx_status->tx_status_1 &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003889 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
Bruno Randolfb47f4072008-03-05 18:35:45 +09003890 ts->ts_status = 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003891
3892 switch (AR5K_REG_MS(tx_status->tx_status_1,
3893 AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
3894 case 0:
Bruno Randolfb47f4072008-03-05 18:35:45 +09003895 ts->ts_rate = tx_ctl->tx_control_3 &
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003896 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
3897 break;
3898 case 1:
Bruno Randolfb47f4072008-03-05 18:35:45 +09003899 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003900 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003901 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003902 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
3903 break;
3904 case 2:
Bruno Randolfb47f4072008-03-05 18:35:45 +09003905 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003906 AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003907 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003908 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
3909 break;
3910 case 3:
Bruno Randolfb47f4072008-03-05 18:35:45 +09003911 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003912 AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003913 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003914 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
3915 break;
3916 }
3917
3918 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
3919 if (tx_status->tx_status_0 &
3920 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003921 ts->ts_status |= AR5K_TXERR_XRETRY;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003922
3923 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003924 ts->ts_status |= AR5K_TXERR_FIFO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003925
3926 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
Bruno Randolfb47f4072008-03-05 18:35:45 +09003927 ts->ts_status |= AR5K_TXERR_FILT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003928 }
3929
3930 return 0;
3931}
3932
3933/*
3934 * RX Descriptor
3935 */
3936
3937/*
3938 * Initialize an rx descriptor
3939 */
3940int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3941 u32 size, unsigned int flags)
3942{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003943 struct ath5k_hw_rx_ctl *rx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003944
3945 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003946 rx_ctl = &desc->ud.ds_rx.rx_ctl;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003947
3948 /*
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003949 * Clear the descriptor
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003950 * If we don't clean the status descriptor,
3951 * while scanning we get too many results,
3952 * most of them virtual, after some secs
3953 * of scanning system hangs. M.F.
3954 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003955 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003956
3957 /* Setup descriptor */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003958 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
3959 if (unlikely(rx_ctl->rx_control_1 != size))
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003960 return -EINVAL;
3961
3962 if (flags & AR5K_RXDESC_INTREQ)
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003963 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003964
3965 return 0;
3966}
3967
3968/*
3969 * Proccess the rx status descriptor on 5210/5211
3970 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003971static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09003972 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003973{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003974 struct ath5k_hw_rx_status *rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003975
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003976 rx_status = &desc->ud.ds_rx.u.rx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003977
3978 /* No frame received / not ready */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003979 if (unlikely((rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_DONE)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02003980 == 0))
3981 return -EINPROGRESS;
3982
3983 /*
3984 * Frame receive status
3985 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09003986 rs->rs_datalen = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003987 AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
Bruno Randolfb47f4072008-03-05 18:35:45 +09003988 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003989 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003990 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003991 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003992 rs->rs_antenna = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003993 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA;
Bruno Randolfb47f4072008-03-05 18:35:45 +09003994 rs->rs_more = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003995 AR5K_5210_RX_DESC_STATUS0_MORE;
Bruno Randolfb47f4072008-03-05 18:35:45 +09003996 /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
3997 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09003998 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09003999 rs->rs_status = 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004000
4001 /*
4002 * Key table status
4003 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004004 if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004005 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004006 AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004007 else
Bruno Randolfb47f4072008-03-05 18:35:45 +09004008 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004009
4010 /*
4011 * Receive/descriptor errors
4012 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004013 if ((rx_status->rx_status_1 &
4014 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
4015 if (rx_status->rx_status_1 &
4016 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004017 rs->rs_status |= AR5K_RXERR_CRC;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004018
4019 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004020 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004021 rs->rs_status |= AR5K_RXERR_FIFO;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004022
4023 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004024 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
Bruno Randolfb47f4072008-03-05 18:35:45 +09004025 rs->rs_status |= AR5K_RXERR_PHY;
4026 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,
4027 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004028 }
4029
4030 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004031 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004032 rs->rs_status |= AR5K_RXERR_DECRYPT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004033 }
4034
4035 return 0;
4036}
4037
4038/*
4039 * Proccess the rx status descriptor on 5212
4040 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004041static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
Bruno Randolfb47f4072008-03-05 18:35:45 +09004042 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004043{
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004044 struct ath5k_hw_rx_status *rx_status;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004045 struct ath5k_hw_rx_error *rx_err;
4046
4047 ATH5K_TRACE(ah->ah_sc);
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004048 rx_status = &desc->ud.ds_rx.u.rx_stat;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004049
4050 /* Overlay on error */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004051 rx_err = &desc->ud.ds_rx.u.rx_err;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004052
4053 /* No frame received / not ready */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004054 if (unlikely((rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_DONE)
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004055 == 0))
4056 return -EINPROGRESS;
4057
4058 /*
4059 * Frame receive status
4060 */
Bruno Randolfb47f4072008-03-05 18:35:45 +09004061 rs->rs_datalen = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004062 AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004063 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004064 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004065 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004066 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004067 rs->rs_antenna = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004068 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004069 rs->rs_more = rx_status->rx_status_0 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004070 AR5K_5212_RX_DESC_STATUS0_MORE;
Bruno Randolfb47f4072008-03-05 18:35:45 +09004071 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004072 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
Bruno Randolfb47f4072008-03-05 18:35:45 +09004073 rs->rs_status = 0;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004074
4075 /*
4076 * Key table status
4077 */
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004078 if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004079 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004080 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004081 else
Bruno Randolfb47f4072008-03-05 18:35:45 +09004082 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004083
4084 /*
4085 * Receive/descriptor errors
4086 */
4087 if ((rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004088 AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
4089 if (rx_status->rx_status_1 &
4090 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004091 rs->rs_status |= AR5K_RXERR_CRC;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004092
4093 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004094 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
Bruno Randolfb47f4072008-03-05 18:35:45 +09004095 rs->rs_status |= AR5K_RXERR_PHY;
4096 rs->rs_phyerr = AR5K_REG_MS(rx_err->rx_error_1,
4097 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004098 }
4099
4100 if (rx_status->rx_status_1 &
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004101 AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004102 rs->rs_status |= AR5K_RXERR_DECRYPT;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004103
Bruno Randolf19fd6e52008-03-05 18:35:23 +09004104 if (rx_status->rx_status_1 &
4105 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
Bruno Randolfb47f4072008-03-05 18:35:45 +09004106 rs->rs_status |= AR5K_RXERR_MIC;
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004107 }
4108
4109 return 0;
4110}
4111
4112
4113/****************\
4114 GPIO Functions
4115\****************/
4116
4117/*
4118 * Set led state
4119 */
4120void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
4121{
4122 u32 led;
4123 /*5210 has different led mode handling*/
4124 u32 led_5210;
4125
4126 ATH5K_TRACE(ah->ah_sc);
4127
4128 /*Reset led status*/
4129 if (ah->ah_version != AR5K_AR5210)
4130 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
4131 AR5K_PCICFG_LEDMODE | AR5K_PCICFG_LED);
4132 else
4133 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED);
4134
4135 /*
4136 * Some blinking values, define at your wish
4137 */
4138 switch (state) {
4139 case AR5K_LED_SCAN:
4140 case AR5K_LED_AUTH:
4141 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND;
4142 led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL;
4143 break;
4144
4145 case AR5K_LED_INIT:
4146 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE;
4147 led_5210 = AR5K_PCICFG_LED_PEND;
4148 break;
4149
4150 case AR5K_LED_ASSOC:
4151 case AR5K_LED_RUN:
4152 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC;
4153 led_5210 = AR5K_PCICFG_LED_ASSOC;
4154 break;
4155
4156 default:
4157 led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE;
4158 led_5210 = AR5K_PCICFG_LED_PEND;
4159 break;
4160 }
4161
4162 /*Write new status to the register*/
4163 if (ah->ah_version != AR5K_AR5210)
4164 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led);
4165 else
4166 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210);
4167}
4168
4169/*
4170 * Set GPIO outputs
4171 */
4172int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
4173{
4174 ATH5K_TRACE(ah->ah_sc);
4175 if (gpio > AR5K_NUM_GPIO)
4176 return -EINVAL;
4177
4178 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~
4179 AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
4180
4181 return 0;
4182}
4183
4184/*
4185 * Set GPIO inputs
4186 */
4187int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
4188{
4189 ATH5K_TRACE(ah->ah_sc);
4190 if (gpio > AR5K_NUM_GPIO)
4191 return -EINVAL;
4192
4193 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~
4194 AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
4195
4196 return 0;
4197}
4198
4199/*
4200 * Get GPIO state
4201 */
4202u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
4203{
4204 ATH5K_TRACE(ah->ah_sc);
4205 if (gpio > AR5K_NUM_GPIO)
4206 return 0xffffffff;
4207
4208 /* GPIO input magic */
4209 return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
4210 0x1;
4211}
4212
4213/*
4214 * Set GPIO state
4215 */
4216int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
4217{
4218 u32 data;
4219 ATH5K_TRACE(ah->ah_sc);
4220
4221 if (gpio > AR5K_NUM_GPIO)
4222 return -EINVAL;
4223
4224 /* GPIO output magic */
4225 data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
4226
4227 data &= ~(1 << gpio);
4228 data |= (val & 1) << gpio;
4229
4230 ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
4231
4232 return 0;
4233}
4234
4235/*
4236 * Initialize the GPIO interrupt (RFKill switch)
4237 */
4238void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
4239 u32 interrupt_level)
4240{
4241 u32 data;
4242
4243 ATH5K_TRACE(ah->ah_sc);
4244 if (gpio > AR5K_NUM_GPIO)
4245 return;
4246
4247 /*
4248 * Set the GPIO interrupt
4249 */
4250 data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
4251 ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
4252 AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
4253 (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
4254
4255 ath5k_hw_reg_write(ah, interrupt_level ? data :
4256 (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
4257
4258 ah->ah_imr |= AR5K_IMR_GPIO;
4259
4260 /* Enable GPIO interrupts */
4261 AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
4262}
4263
4264
Jiri Slabyfa1c1142007-08-12 17:33:16 +02004265
4266
4267/****************\
4268 Misc functions
4269\****************/
4270
4271int ath5k_hw_get_capability(struct ath5k_hw *ah,
4272 enum ath5k_capability_type cap_type,
4273 u32 capability, u32 *result)
4274{
4275 ATH5K_TRACE(ah->ah_sc);
4276
4277 switch (cap_type) {
4278 case AR5K_CAP_NUM_TXQUEUES:
4279 if (result) {
4280 if (ah->ah_version == AR5K_AR5210)
4281 *result = AR5K_NUM_TX_QUEUES_NOQCU;
4282 else
4283 *result = AR5K_NUM_TX_QUEUES;
4284 goto yes;
4285 }
4286 case AR5K_CAP_VEOL:
4287 goto yes;
4288 case AR5K_CAP_COMPRESSION:
4289 if (ah->ah_version == AR5K_AR5212)
4290 goto yes;
4291 else
4292 goto no;
4293 case AR5K_CAP_BURST:
4294 goto yes;
4295 case AR5K_CAP_TPC:
4296 goto yes;
4297 case AR5K_CAP_BSSIDMASK:
4298 if (ah->ah_version == AR5K_AR5212)
4299 goto yes;
4300 else
4301 goto no;
4302 case AR5K_CAP_XR:
4303 if (ah->ah_version == AR5K_AR5212)
4304 goto yes;
4305 else
4306 goto no;
4307 default:
4308 goto no;
4309 }
4310
4311no:
4312 return -EINVAL;
4313yes:
4314 return 0;
4315}
4316
4317static int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
4318 u16 assoc_id)
4319{
4320 ATH5K_TRACE(ah->ah_sc);
4321
4322 if (ah->ah_version == AR5K_AR5210) {
4323 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
4324 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
4325 return 0;
4326 }
4327
4328 return -EIO;
4329}
4330
4331static int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
4332{
4333 ATH5K_TRACE(ah->ah_sc);
4334
4335 if (ah->ah_version == AR5K_AR5210) {
4336 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
4337 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
4338 return 0;
4339 }
4340
4341 return -EIO;
4342}