diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 14:47:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 14:47:02 -0400 |
commit | 5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0 (patch) | |
tree | 7851ef1c93aa1aba7ef327ca4b75fd35e6d10f29 /drivers/net/wireless/ath/ath5k | |
parent | 02f36038c568111ad4fc433f6fa760ff5e38fab4 (diff) | |
parent | ec37a48d1d16c30b655ac5280209edf52a6775d4 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1699 commits)
bnx2/bnx2x: Unsupported Ethtool operations should return -EINVAL.
vlan: Calling vlan_hwaccel_do_receive() is always valid.
tproxy: use the interface primary IP address as a default value for --on-ip
tproxy: added IPv6 support to the socket match
cxgb3: function namespace cleanup
tproxy: added IPv6 support to the TPROXY target
tproxy: added IPv6 socket lookup function to nf_tproxy_core
be2net: Changes to use only priority codes allowed by f/w
tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled
tproxy: added tproxy sockopt interface in the IPV6 layer
tproxy: added udp6_lib_lookup function
tproxy: added const specifiers to udp lookup functions
tproxy: split off ipv6 defragmentation to a separate module
l2tp: small cleanup
nf_nat: restrict ICMP translation for embedded header
can: mcp251x: fix generation of error frames
can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set
can-raw: add msg_flags to distinguish local traffic
9p: client code cleanup
rds: make local functions/variables static
...
Fix up conflicts in net/core/dev.c, drivers/net/pcmcia/smc91c92_cs.c and
drivers/net/wireless/ath/ath9k/debug.c as per David
Diffstat (limited to 'drivers/net/wireless/ath/ath5k')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ani.c | 47 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ani.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ath5k.h | 31 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/attach.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 2373 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.h | 33 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/debug.c | 121 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/debug.h | 15 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/dma.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/eeprom.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/pcu.c | 297 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/phy.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/qcu.c | 99 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/reg.h | 73 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/reset.c | 34 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/rfbuffer.h | 4 |
16 files changed, 1651 insertions, 1542 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index 26dbe65fedb0..f1419198a479 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c | |||
@@ -355,41 +355,28 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as) | |||
355 | 355 | ||
356 | 356 | ||
357 | /** | 357 | /** |
358 | * ath5k_hw_ani_get_listen_time() - Calculate time spent listening | 358 | * ath5k_hw_ani_get_listen_time() - Update counters and return listening time |
359 | * | 359 | * |
360 | * Return an approximation of the time spent "listening" in milliseconds (ms) | 360 | * Return an approximation of the time spent "listening" in milliseconds (ms) |
361 | * since the last call of this function by deducting the cycles spent | 361 | * since the last call of this function. |
362 | * transmitting and receiving from the total cycle count. | 362 | * Save a snapshot of the counter values for debugging/statistics. |
363 | * Save profile count values for debugging/statistics and because we might want | ||
364 | * to use them later. | ||
365 | * | ||
366 | * We assume no one else clears these registers! | ||
367 | */ | 363 | */ |
368 | static int | 364 | static int |
369 | ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as) | 365 | ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as) |
370 | { | 366 | { |
367 | struct ath_common *common = ath5k_hw_common(ah); | ||
371 | int listen; | 368 | int listen; |
372 | 369 | ||
373 | /* freeze */ | 370 | spin_lock_bh(&common->cc_lock); |
374 | ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC); | 371 | |
375 | /* read */ | 372 | ath_hw_cycle_counters_update(common); |
376 | as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE); | 373 | memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc)); |
377 | as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR); | 374 | |
378 | as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX); | 375 | /* clears common->cc_ani */ |
379 | as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX); | 376 | listen = ath_hw_get_listen_time(common); |
380 | /* clear */ | 377 | |
381 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX); | 378 | spin_unlock_bh(&common->cc_lock); |
382 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX); | 379 | |
383 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR); | ||
384 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE); | ||
385 | /* un-freeze */ | ||
386 | ath5k_hw_reg_write(ah, 0, AR5K_MIBC); | ||
387 | |||
388 | /* TODO: where does 44000 come from? (11g clock rate?) */ | ||
389 | listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000; | ||
390 | |||
391 | if (as->pfc_cycles == 0 || listen < 0) | ||
392 | return 0; | ||
393 | return listen; | 380 | return listen; |
394 | } | 381 | } |
395 | 382 | ||
@@ -552,9 +539,9 @@ ath5k_ani_mib_intr(struct ath5k_hw *ah) | |||
552 | if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO) | 539 | if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO) |
553 | return; | 540 | return; |
554 | 541 | ||
555 | /* if one of the errors triggered, we can get a superfluous second | 542 | /* If one of the errors triggered, we can get a superfluous second |
556 | * interrupt, even though we have already reset the register. the | 543 | * interrupt, even though we have already reset the register. The |
557 | * function detects that so we can return early */ | 544 | * function detects that so we can return early. */ |
558 | if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0) | 545 | if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0) |
559 | return; | 546 | return; |
560 | 547 | ||
diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h index 55cf26d8522c..d0a664039c87 100644 --- a/drivers/net/wireless/ath/ath5k/ani.h +++ b/drivers/net/wireless/ath/ath5k/ani.h | |||
@@ -75,10 +75,7 @@ struct ath5k_ani_state { | |||
75 | unsigned int cck_errors; | 75 | unsigned int cck_errors; |
76 | 76 | ||
77 | /* debug/statistics only: numbers from last ANI calibration */ | 77 | /* debug/statistics only: numbers from last ANI calibration */ |
78 | unsigned int pfc_tx; | 78 | struct ath_cycle_counters last_cc; |
79 | unsigned int pfc_rx; | ||
80 | unsigned int pfc_busy; | ||
81 | unsigned int pfc_cycles; | ||
82 | unsigned int last_listen; | 79 | unsigned int last_listen; |
83 | unsigned int last_ofdm_errors; | 80 | unsigned int last_ofdm_errors; |
84 | unsigned int last_cck_errors; | 81 | unsigned int last_cck_errors; |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index ea6362a8988d..4a367cdb3eb9 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -175,7 +175,7 @@ | |||
175 | #define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0 | 175 | #define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0 |
176 | #define AR5K_TUNE_RADAR_ALERT false | 176 | #define AR5K_TUNE_RADAR_ALERT false |
177 | #define AR5K_TUNE_MIN_TX_FIFO_THRES 1 | 177 | #define AR5K_TUNE_MIN_TX_FIFO_THRES 1 |
178 | #define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_LEN / 64) + 1) | 178 | #define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_FRAME_LEN / 64) + 1) |
179 | #define AR5K_TUNE_REGISTER_TIMEOUT 20000 | 179 | #define AR5K_TUNE_REGISTER_TIMEOUT 20000 |
180 | /* Register for RSSI threshold has a mask of 0xff, so 255 seems to | 180 | /* Register for RSSI threshold has a mask of 0xff, so 255 seems to |
181 | * be the max value. */ | 181 | * be the max value. */ |
@@ -206,6 +206,8 @@ | |||
206 | #define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */ | 206 | #define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */ |
207 | #define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */ | 207 | #define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */ |
208 | 208 | ||
209 | #define ATH5K_TX_COMPLETE_POLL_INT 3000 /* 3 sec */ | ||
210 | |||
209 | #define AR5K_INIT_CARR_SENSE_EN 1 | 211 | #define AR5K_INIT_CARR_SENSE_EN 1 |
210 | 212 | ||
211 | /*Swap RX/TX Descriptor for big endian archs*/ | 213 | /*Swap RX/TX Descriptor for big endian archs*/ |
@@ -256,8 +258,6 @@ | |||
256 | (AR5K_INIT_PROG_IFS_TURBO) \ | 258 | (AR5K_INIT_PROG_IFS_TURBO) \ |
257 | ) | 259 | ) |
258 | 260 | ||
259 | /* token to use for aifs, cwmin, cwmax in MadWiFi */ | ||
260 | #define AR5K_TXQ_USEDEFAULT ((u32) -1) | ||
261 | 261 | ||
262 | /* GENERIC CHIPSET DEFINITIONS */ | 262 | /* GENERIC CHIPSET DEFINITIONS */ |
263 | 263 | ||
@@ -343,9 +343,6 @@ struct ath5k_srev_name { | |||
343 | #define AR5K_SREV_PHY_5413 0x61 | 343 | #define AR5K_SREV_PHY_5413 0x61 |
344 | #define AR5K_SREV_PHY_2425 0x70 | 344 | #define AR5K_SREV_PHY_2425 0x70 |
345 | 345 | ||
346 | /* IEEE defs */ | ||
347 | #define IEEE80211_MAX_LEN 2500 | ||
348 | |||
349 | /* TODO add support to mac80211 for vendor-specific rates and modes */ | 346 | /* TODO add support to mac80211 for vendor-specific rates and modes */ |
350 | 347 | ||
351 | /* | 348 | /* |
@@ -531,9 +528,9 @@ struct ath5k_txq_info { | |||
531 | enum ath5k_tx_queue tqi_type; | 528 | enum ath5k_tx_queue tqi_type; |
532 | enum ath5k_tx_queue_subtype tqi_subtype; | 529 | enum ath5k_tx_queue_subtype tqi_subtype; |
533 | u16 tqi_flags; /* Tx queue flags (see above) */ | 530 | u16 tqi_flags; /* Tx queue flags (see above) */ |
534 | u32 tqi_aifs; /* Arbitrated Interframe Space */ | 531 | u8 tqi_aifs; /* Arbitrated Interframe Space */ |
535 | s32 tqi_cw_min; /* Minimum Contention Window */ | 532 | u16 tqi_cw_min; /* Minimum Contention Window */ |
536 | s32 tqi_cw_max; /* Maximum Contention Window */ | 533 | u16 tqi_cw_max; /* Maximum Contention Window */ |
537 | u32 tqi_cbr_period; /* Constant bit rate period */ | 534 | u32 tqi_cbr_period; /* Constant bit rate period */ |
538 | u32 tqi_cbr_overflow_limit; | 535 | u32 tqi_cbr_overflow_limit; |
539 | u32 tqi_burst_time; | 536 | u32 tqi_burst_time; |
@@ -1031,8 +1028,6 @@ struct ath5k_hw { | |||
1031 | bool ah_turbo; | 1028 | bool ah_turbo; |
1032 | bool ah_calibration; | 1029 | bool ah_calibration; |
1033 | bool ah_single_chip; | 1030 | bool ah_single_chip; |
1034 | bool ah_aes_support; | ||
1035 | bool ah_combined_mic; | ||
1036 | 1031 | ||
1037 | enum ath5k_version ah_version; | 1032 | enum ath5k_version ah_version; |
1038 | enum ath5k_radio ah_radio; | 1033 | enum ath5k_radio ah_radio; |
@@ -1046,10 +1041,6 @@ struct ath5k_hw { | |||
1046 | #define ah_modes ah_capabilities.cap_mode | 1041 | #define ah_modes ah_capabilities.cap_mode |
1047 | #define ah_ee_version ah_capabilities.cap_eeprom.ee_version | 1042 | #define ah_ee_version ah_capabilities.cap_eeprom.ee_version |
1048 | 1043 | ||
1049 | u32 ah_atim_window; | ||
1050 | u32 ah_aifs; | ||
1051 | u32 ah_cw_min; | ||
1052 | u32 ah_cw_max; | ||
1053 | u32 ah_limit_tx_retries; | 1044 | u32 ah_limit_tx_retries; |
1054 | u8 ah_coverage_class; | 1045 | u8 ah_coverage_class; |
1055 | 1046 | ||
@@ -1190,7 +1181,7 @@ extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); | |||
1190 | void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); | 1181 | void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); |
1191 | /* BSSID Functions */ | 1182 | /* BSSID Functions */ |
1192 | int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); | 1183 | int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); |
1193 | void ath5k_hw_set_associd(struct ath5k_hw *ah); | 1184 | void ath5k_hw_set_bssid(struct ath5k_hw *ah); |
1194 | void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); | 1185 | void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); |
1195 | /* Receive start/stop functions */ | 1186 | /* Receive start/stop functions */ |
1196 | void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); | 1187 | void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); |
@@ -1204,17 +1195,13 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); | |||
1204 | void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); | 1195 | void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); |
1205 | void ath5k_hw_reset_tsf(struct ath5k_hw *ah); | 1196 | void ath5k_hw_reset_tsf(struct ath5k_hw *ah); |
1206 | void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); | 1197 | void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); |
1198 | bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval); | ||
1207 | /* ACK bit rate */ | 1199 | /* ACK bit rate */ |
1208 | void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); | 1200 | void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); |
1209 | /* Clock rate related functions */ | 1201 | /* Clock rate related functions */ |
1210 | unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); | 1202 | unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); |
1211 | unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); | 1203 | unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); |
1212 | unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); | 1204 | void ath5k_hw_set_clockrate(struct ath5k_hw *ah); |
1213 | /* Key table (WEP) functions */ | ||
1214 | int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); | ||
1215 | int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, | ||
1216 | const struct ieee80211_key_conf *key, const u8 *mac); | ||
1217 | int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); | ||
1218 | 1205 | ||
1219 | /* Queue Control Unit, DFS Control Unit Functions */ | 1206 | /* Queue Control Unit, DFS Control Unit Functions */ |
1220 | int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, | 1207 | int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index b32e28caeee2..cd0b14a0a93a 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -118,9 +118,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
118 | ah->ah_turbo = false; | 118 | ah->ah_turbo = false; |
119 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; | 119 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; |
120 | ah->ah_imr = 0; | 120 | ah->ah_imr = 0; |
121 | ah->ah_atim_window = 0; | ||
122 | ah->ah_aifs = AR5K_TUNE_AIFS; | ||
123 | ah->ah_cw_min = AR5K_TUNE_CWMIN; | ||
124 | ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; | 121 | ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; |
125 | ah->ah_software_retry = false; | 122 | ah->ah_software_retry = false; |
126 | ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; | 123 | ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; |
@@ -139,12 +136,12 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
139 | else | 136 | else |
140 | ah->ah_version = AR5K_AR5212; | 137 | ah->ah_version = AR5K_AR5212; |
141 | 138 | ||
142 | /*Fill the ath5k_hw struct with the needed functions*/ | 139 | /* Fill the ath5k_hw struct with the needed functions */ |
143 | ret = ath5k_hw_init_desc_functions(ah); | 140 | ret = ath5k_hw_init_desc_functions(ah); |
144 | if (ret) | 141 | if (ret) |
145 | goto err_free; | 142 | goto err_free; |
146 | 143 | ||
147 | /* Bring device out of sleep and reset it's units */ | 144 | /* Bring device out of sleep and reset its units */ |
148 | ret = ath5k_hw_nic_wakeup(ah, 0, true); | 145 | ret = ath5k_hw_nic_wakeup(ah, 0, true); |
149 | if (ret) | 146 | if (ret) |
150 | goto err_free; | 147 | goto err_free; |
@@ -158,7 +155,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
158 | CHANNEL_5GHZ); | 155 | CHANNEL_5GHZ); |
159 | ah->ah_phy = AR5K_PHY(0); | 156 | ah->ah_phy = AR5K_PHY(0); |
160 | 157 | ||
161 | /* Try to identify radio chip based on it's srev */ | 158 | /* Try to identify radio chip based on its srev */ |
162 | switch (ah->ah_radio_5ghz_revision & 0xf0) { | 159 | switch (ah->ah_radio_5ghz_revision & 0xf0) { |
163 | case AR5K_SREV_RAD_5111: | 160 | case AR5K_SREV_RAD_5111: |
164 | ah->ah_radio = AR5K_RF5111; | 161 | ah->ah_radio = AR5K_RF5111; |
@@ -314,12 +311,16 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
314 | } | 311 | } |
315 | 312 | ||
316 | /* Crypto settings */ | 313 | /* Crypto settings */ |
317 | ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 && | 314 | common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? |
318 | (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && | 315 | AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); |
319 | !AR5K_EEPROM_AES_DIS(ee->ee_misc5)); | 316 | |
317 | if (srev >= AR5K_SREV_AR5212_V4 && | ||
318 | (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && | ||
319 | !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) | ||
320 | common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; | ||
320 | 321 | ||
321 | if (srev >= AR5K_SREV_AR2414) { | 322 | if (srev >= AR5K_SREV_AR2414) { |
322 | ah->ah_combined_mic = true; | 323 | common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; |
323 | AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE, | 324 | AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE, |
324 | AR5K_MISC_MODE_COMBINED_MIC); | 325 | AR5K_MISC_MODE_COMBINED_MIC); |
325 | } | 326 | } |
@@ -329,7 +330,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
329 | 330 | ||
330 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ | 331 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ |
331 | memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); | 332 | memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); |
332 | ath5k_hw_set_associd(ah); | 333 | ath5k_hw_set_bssid(ah); |
333 | ath5k_hw_set_opmode(ah, sc->opmode); | 334 | ath5k_hw_set_opmode(ah, sc->opmode); |
334 | 335 | ||
335 | ath5k_hw_rfgain_opt_init(ah); | 336 | ath5k_hw_rfgain_opt_init(ah); |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index d77ce9906b6c..f1ae75d35d5d 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/ethtool.h> | 52 | #include <linux/ethtool.h> |
53 | #include <linux/uaccess.h> | 53 | #include <linux/uaccess.h> |
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/etherdevice.h> | ||
55 | 56 | ||
56 | #include <net/ieee80211_radiotap.h> | 57 | #include <net/ieee80211_radiotap.h> |
57 | 58 | ||
@@ -61,6 +62,7 @@ | |||
61 | #include "reg.h" | 62 | #include "reg.h" |
62 | #include "debug.h" | 63 | #include "debug.h" |
63 | #include "ani.h" | 64 | #include "ani.h" |
65 | #include "../debug.h" | ||
64 | 66 | ||
65 | static int modparam_nohwcrypt; | 67 | static int modparam_nohwcrypt; |
66 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 68 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); |
@@ -70,11 +72,6 @@ static int modparam_all_channels; | |||
70 | module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); | 72 | module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); |
71 | MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); | 73 | MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); |
72 | 74 | ||
73 | |||
74 | /******************\ | ||
75 | * Internal defines * | ||
76 | \******************/ | ||
77 | |||
78 | /* Module info */ | 75 | /* Module info */ |
79 | MODULE_AUTHOR("Jiri Slaby"); | 76 | MODULE_AUTHOR("Jiri Slaby"); |
80 | MODULE_AUTHOR("Nick Kossifidis"); | 77 | MODULE_AUTHOR("Nick Kossifidis"); |
@@ -83,6 +80,10 @@ MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); | |||
83 | MODULE_LICENSE("Dual BSD/GPL"); | 80 | MODULE_LICENSE("Dual BSD/GPL"); |
84 | MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); | 81 | MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); |
85 | 82 | ||
83 | static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); | ||
84 | static int ath5k_beacon_update(struct ieee80211_hw *hw, | ||
85 | struct ieee80211_vif *vif); | ||
86 | static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); | ||
86 | 87 | ||
87 | /* Known PCI ids */ | 88 | /* Known PCI ids */ |
88 | static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { | 89 | static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { |
@@ -190,129 +191,6 @@ static const struct ieee80211_rate ath5k_rates[] = { | |||
190 | /* XR missing */ | 191 | /* XR missing */ |
191 | }; | 192 | }; |
192 | 193 | ||
193 | /* | ||
194 | * Prototypes - PCI stack related functions | ||
195 | */ | ||
196 | static int __devinit ath5k_pci_probe(struct pci_dev *pdev, | ||
197 | const struct pci_device_id *id); | ||
198 | static void __devexit ath5k_pci_remove(struct pci_dev *pdev); | ||
199 | #ifdef CONFIG_PM_SLEEP | ||
200 | static int ath5k_pci_suspend(struct device *dev); | ||
201 | static int ath5k_pci_resume(struct device *dev); | ||
202 | |||
203 | static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); | ||
204 | #define ATH5K_PM_OPS (&ath5k_pm_ops) | ||
205 | #else | ||
206 | #define ATH5K_PM_OPS NULL | ||
207 | #endif /* CONFIG_PM_SLEEP */ | ||
208 | |||
209 | static struct pci_driver ath5k_pci_driver = { | ||
210 | .name = KBUILD_MODNAME, | ||
211 | .id_table = ath5k_pci_id_table, | ||
212 | .probe = ath5k_pci_probe, | ||
213 | .remove = __devexit_p(ath5k_pci_remove), | ||
214 | .driver.pm = ATH5K_PM_OPS, | ||
215 | }; | ||
216 | |||
217 | |||
218 | |||
219 | /* | ||
220 | * Prototypes - MAC 802.11 stack related functions | ||
221 | */ | ||
222 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
223 | static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
224 | struct ath5k_txq *txq); | ||
225 | static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); | ||
226 | static int ath5k_start(struct ieee80211_hw *hw); | ||
227 | static void ath5k_stop(struct ieee80211_hw *hw); | ||
228 | static int ath5k_add_interface(struct ieee80211_hw *hw, | ||
229 | struct ieee80211_vif *vif); | ||
230 | static void ath5k_remove_interface(struct ieee80211_hw *hw, | ||
231 | struct ieee80211_vif *vif); | ||
232 | static int ath5k_config(struct ieee80211_hw *hw, u32 changed); | ||
233 | static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, | ||
234 | struct netdev_hw_addr_list *mc_list); | ||
235 | static void ath5k_configure_filter(struct ieee80211_hw *hw, | ||
236 | unsigned int changed_flags, | ||
237 | unsigned int *new_flags, | ||
238 | u64 multicast); | ||
239 | static int ath5k_set_key(struct ieee80211_hw *hw, | ||
240 | enum set_key_cmd cmd, | ||
241 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, | ||
242 | struct ieee80211_key_conf *key); | ||
243 | static int ath5k_get_stats(struct ieee80211_hw *hw, | ||
244 | struct ieee80211_low_level_stats *stats); | ||
245 | static int ath5k_get_survey(struct ieee80211_hw *hw, | ||
246 | int idx, struct survey_info *survey); | ||
247 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); | ||
248 | static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); | ||
249 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); | ||
250 | static int ath5k_beacon_update(struct ieee80211_hw *hw, | ||
251 | struct ieee80211_vif *vif); | ||
252 | static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | ||
253 | struct ieee80211_vif *vif, | ||
254 | struct ieee80211_bss_conf *bss_conf, | ||
255 | u32 changes); | ||
256 | static void ath5k_sw_scan_start(struct ieee80211_hw *hw); | ||
257 | static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); | ||
258 | static void ath5k_set_coverage_class(struct ieee80211_hw *hw, | ||
259 | u8 coverage_class); | ||
260 | |||
261 | static const struct ieee80211_ops ath5k_hw_ops = { | ||
262 | .tx = ath5k_tx, | ||
263 | .start = ath5k_start, | ||
264 | .stop = ath5k_stop, | ||
265 | .add_interface = ath5k_add_interface, | ||
266 | .remove_interface = ath5k_remove_interface, | ||
267 | .config = ath5k_config, | ||
268 | .prepare_multicast = ath5k_prepare_multicast, | ||
269 | .configure_filter = ath5k_configure_filter, | ||
270 | .set_key = ath5k_set_key, | ||
271 | .get_stats = ath5k_get_stats, | ||
272 | .get_survey = ath5k_get_survey, | ||
273 | .conf_tx = NULL, | ||
274 | .get_tsf = ath5k_get_tsf, | ||
275 | .set_tsf = ath5k_set_tsf, | ||
276 | .reset_tsf = ath5k_reset_tsf, | ||
277 | .bss_info_changed = ath5k_bss_info_changed, | ||
278 | .sw_scan_start = ath5k_sw_scan_start, | ||
279 | .sw_scan_complete = ath5k_sw_scan_complete, | ||
280 | .set_coverage_class = ath5k_set_coverage_class, | ||
281 | }; | ||
282 | |||
283 | /* | ||
284 | * Prototypes - Internal functions | ||
285 | */ | ||
286 | /* Attach detach */ | ||
287 | static int ath5k_attach(struct pci_dev *pdev, | ||
288 | struct ieee80211_hw *hw); | ||
289 | static void ath5k_detach(struct pci_dev *pdev, | ||
290 | struct ieee80211_hw *hw); | ||
291 | /* Channel/mode setup */ | ||
292 | static inline short ath5k_ieee2mhz(short chan); | ||
293 | static unsigned int ath5k_copy_channels(struct ath5k_hw *ah, | ||
294 | struct ieee80211_channel *channels, | ||
295 | unsigned int mode, | ||
296 | unsigned int max); | ||
297 | static int ath5k_setup_bands(struct ieee80211_hw *hw); | ||
298 | static int ath5k_chan_set(struct ath5k_softc *sc, | ||
299 | struct ieee80211_channel *chan); | ||
300 | static void ath5k_setcurmode(struct ath5k_softc *sc, | ||
301 | unsigned int mode); | ||
302 | static void ath5k_mode_setup(struct ath5k_softc *sc); | ||
303 | |||
304 | /* Descriptor setup */ | ||
305 | static int ath5k_desc_alloc(struct ath5k_softc *sc, | ||
306 | struct pci_dev *pdev); | ||
307 | static void ath5k_desc_free(struct ath5k_softc *sc, | ||
308 | struct pci_dev *pdev); | ||
309 | /* Buffers setup */ | ||
310 | static int ath5k_rxbuf_setup(struct ath5k_softc *sc, | ||
311 | struct ath5k_buf *bf); | ||
312 | static int ath5k_txbuf_setup(struct ath5k_softc *sc, | ||
313 | struct ath5k_buf *bf, | ||
314 | struct ath5k_txq *txq, int padsize); | ||
315 | |||
316 | static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, | 194 | static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, |
317 | struct ath5k_buf *bf) | 195 | struct ath5k_buf *bf) |
318 | { | 196 | { |
@@ -345,35 +223,6 @@ static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, | |||
345 | } | 223 | } |
346 | 224 | ||
347 | 225 | ||
348 | /* Queues setup */ | ||
349 | static struct ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc, | ||
350 | int qtype, int subtype); | ||
351 | static int ath5k_beaconq_setup(struct ath5k_hw *ah); | ||
352 | static int ath5k_beaconq_config(struct ath5k_softc *sc); | ||
353 | static void ath5k_txq_drainq(struct ath5k_softc *sc, | ||
354 | struct ath5k_txq *txq); | ||
355 | static void ath5k_txq_cleanup(struct ath5k_softc *sc); | ||
356 | static void ath5k_txq_release(struct ath5k_softc *sc); | ||
357 | /* Rx handling */ | ||
358 | static int ath5k_rx_start(struct ath5k_softc *sc); | ||
359 | static void ath5k_rx_stop(struct ath5k_softc *sc); | ||
360 | static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc, | ||
361 | struct sk_buff *skb, | ||
362 | struct ath5k_rx_status *rs); | ||
363 | static void ath5k_tasklet_rx(unsigned long data); | ||
364 | /* Tx handling */ | ||
365 | static void ath5k_tx_processq(struct ath5k_softc *sc, | ||
366 | struct ath5k_txq *txq); | ||
367 | static void ath5k_tasklet_tx(unsigned long data); | ||
368 | /* Beacon handling */ | ||
369 | static int ath5k_beacon_setup(struct ath5k_softc *sc, | ||
370 | struct ath5k_buf *bf); | ||
371 | static void ath5k_beacon_send(struct ath5k_softc *sc); | ||
372 | static void ath5k_beacon_config(struct ath5k_softc *sc); | ||
373 | static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); | ||
374 | static void ath5k_tasklet_beacon(unsigned long data); | ||
375 | static void ath5k_tasklet_ani(unsigned long data); | ||
376 | |||
377 | static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) | 226 | static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) |
378 | { | 227 | { |
379 | u64 tsf = ath5k_hw_get_tsf64(ah); | 228 | u64 tsf = ath5k_hw_get_tsf64(ah); |
@@ -384,50 +233,6 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) | |||
384 | return (tsf & ~0x7fff) | rstamp; | 233 | return (tsf & ~0x7fff) | rstamp; |
385 | } | 234 | } |
386 | 235 | ||
387 | /* Interrupt handling */ | ||
388 | static int ath5k_init(struct ath5k_softc *sc); | ||
389 | static int ath5k_stop_locked(struct ath5k_softc *sc); | ||
390 | static int ath5k_stop_hw(struct ath5k_softc *sc); | ||
391 | static irqreturn_t ath5k_intr(int irq, void *dev_id); | ||
392 | static void ath5k_reset_work(struct work_struct *work); | ||
393 | |||
394 | static void ath5k_tasklet_calibrate(unsigned long data); | ||
395 | |||
396 | /* | ||
397 | * Module init/exit functions | ||
398 | */ | ||
399 | static int __init | ||
400 | init_ath5k_pci(void) | ||
401 | { | ||
402 | int ret; | ||
403 | |||
404 | ath5k_debug_init(); | ||
405 | |||
406 | ret = pci_register_driver(&ath5k_pci_driver); | ||
407 | if (ret) { | ||
408 | printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); | ||
409 | return ret; | ||
410 | } | ||
411 | |||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static void __exit | ||
416 | exit_ath5k_pci(void) | ||
417 | { | ||
418 | pci_unregister_driver(&ath5k_pci_driver); | ||
419 | |||
420 | ath5k_debug_finish(); | ||
421 | } | ||
422 | |||
423 | module_init(init_ath5k_pci); | ||
424 | module_exit(exit_ath5k_pci); | ||
425 | |||
426 | |||
427 | /********************\ | ||
428 | * PCI Initialization * | ||
429 | \********************/ | ||
430 | |||
431 | static const char * | 236 | static const char * |
432 | ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) | 237 | ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) |
433 | { | 238 | { |
@@ -466,299 +271,6 @@ static const struct ath_ops ath5k_common_ops = { | |||
466 | .write = ath5k_iowrite32, | 271 | .write = ath5k_iowrite32, |
467 | }; | 272 | }; |
468 | 273 | ||
469 | static int __devinit | ||
470 | ath5k_pci_probe(struct pci_dev *pdev, | ||
471 | const struct pci_device_id *id) | ||
472 | { | ||
473 | void __iomem *mem; | ||
474 | struct ath5k_softc *sc; | ||
475 | struct ath_common *common; | ||
476 | struct ieee80211_hw *hw; | ||
477 | int ret; | ||
478 | u8 csz; | ||
479 | |||
480 | /* | ||
481 | * L0s needs to be disabled on all ath5k cards. | ||
482 | * | ||
483 | * For distributions shipping with CONFIG_PCIEASPM (this will be enabled | ||
484 | * by default in the future in 2.6.36) this will also mean both L1 and | ||
485 | * L0s will be disabled when a pre 1.1 PCIe device is detected. We do | ||
486 | * know L1 works correctly even for all ath5k pre 1.1 PCIe devices | ||
487 | * though but cannot currently undue the effect of a blacklist, for | ||
488 | * details you can read pcie_aspm_sanity_check() and see how it adjusts | ||
489 | * the device link capability. | ||
490 | * | ||
491 | * It may be possible in the future to implement some PCI API to allow | ||
492 | * drivers to override blacklists for pre 1.1 PCIe but for now it is | ||
493 | * best to accept that both L0s and L1 will be disabled completely for | ||
494 | * distributions shipping with CONFIG_PCIEASPM rather than having this | ||
495 | * issue present. Motivation for adding this new API will be to help | ||
496 | * with power consumption for some of these devices. | ||
497 | */ | ||
498 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); | ||
499 | |||
500 | ret = pci_enable_device(pdev); | ||
501 | if (ret) { | ||
502 | dev_err(&pdev->dev, "can't enable device\n"); | ||
503 | goto err; | ||
504 | } | ||
505 | |||
506 | /* XXX 32-bit addressing only */ | ||
507 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
508 | if (ret) { | ||
509 | dev_err(&pdev->dev, "32-bit DMA not available\n"); | ||
510 | goto err_dis; | ||
511 | } | ||
512 | |||
513 | /* | ||
514 | * Cache line size is used to size and align various | ||
515 | * structures used to communicate with the hardware. | ||
516 | */ | ||
517 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); | ||
518 | if (csz == 0) { | ||
519 | /* | ||
520 | * Linux 2.4.18 (at least) writes the cache line size | ||
521 | * register as a 16-bit wide register which is wrong. | ||
522 | * We must have this setup properly for rx buffer | ||
523 | * DMA to work so force a reasonable value here if it | ||
524 | * comes up zero. | ||
525 | */ | ||
526 | csz = L1_CACHE_BYTES >> 2; | ||
527 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); | ||
528 | } | ||
529 | /* | ||
530 | * The default setting of latency timer yields poor results, | ||
531 | * set it to the value used by other systems. It may be worth | ||
532 | * tweaking this setting more. | ||
533 | */ | ||
534 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); | ||
535 | |||
536 | /* Enable bus mastering */ | ||
537 | pci_set_master(pdev); | ||
538 | |||
539 | /* | ||
540 | * Disable the RETRY_TIMEOUT register (0x41) to keep | ||
541 | * PCI Tx retries from interfering with C3 CPU state. | ||
542 | */ | ||
543 | pci_write_config_byte(pdev, 0x41, 0); | ||
544 | |||
545 | ret = pci_request_region(pdev, 0, "ath5k"); | ||
546 | if (ret) { | ||
547 | dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); | ||
548 | goto err_dis; | ||
549 | } | ||
550 | |||
551 | mem = pci_iomap(pdev, 0, 0); | ||
552 | if (!mem) { | ||
553 | dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; | ||
554 | ret = -EIO; | ||
555 | goto err_reg; | ||
556 | } | ||
557 | |||
558 | /* | ||
559 | * Allocate hw (mac80211 main struct) | ||
560 | * and hw->priv (driver private data) | ||
561 | */ | ||
562 | hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops); | ||
563 | if (hw == NULL) { | ||
564 | dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); | ||
565 | ret = -ENOMEM; | ||
566 | goto err_map; | ||
567 | } | ||
568 | |||
569 | dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); | ||
570 | |||
571 | /* Initialize driver private data */ | ||
572 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
573 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
574 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
575 | IEEE80211_HW_SIGNAL_DBM; | ||
576 | |||
577 | hw->wiphy->interface_modes = | ||
578 | BIT(NL80211_IFTYPE_AP) | | ||
579 | BIT(NL80211_IFTYPE_STATION) | | ||
580 | BIT(NL80211_IFTYPE_ADHOC) | | ||
581 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
582 | |||
583 | hw->extra_tx_headroom = 2; | ||
584 | hw->channel_change_time = 5000; | ||
585 | sc = hw->priv; | ||
586 | sc->hw = hw; | ||
587 | sc->pdev = pdev; | ||
588 | |||
589 | ath5k_debug_init_device(sc); | ||
590 | |||
591 | /* | ||
592 | * Mark the device as detached to avoid processing | ||
593 | * interrupts until setup is complete. | ||
594 | */ | ||
595 | __set_bit(ATH_STAT_INVALID, sc->status); | ||
596 | |||
597 | sc->iobase = mem; /* So we can unmap it on detach */ | ||
598 | sc->opmode = NL80211_IFTYPE_STATION; | ||
599 | sc->bintval = 1000; | ||
600 | mutex_init(&sc->lock); | ||
601 | spin_lock_init(&sc->rxbuflock); | ||
602 | spin_lock_init(&sc->txbuflock); | ||
603 | spin_lock_init(&sc->block); | ||
604 | |||
605 | /* Set private data */ | ||
606 | pci_set_drvdata(pdev, sc); | ||
607 | |||
608 | /* Setup interrupt handler */ | ||
609 | ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); | ||
610 | if (ret) { | ||
611 | ATH5K_ERR(sc, "request_irq failed\n"); | ||
612 | goto err_free; | ||
613 | } | ||
614 | |||
615 | /*If we passed the test malloc a ath5k_hw struct*/ | ||
616 | sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); | ||
617 | if (!sc->ah) { | ||
618 | ret = -ENOMEM; | ||
619 | ATH5K_ERR(sc, "out of memory\n"); | ||
620 | goto err_irq; | ||
621 | } | ||
622 | |||
623 | sc->ah->ah_sc = sc; | ||
624 | sc->ah->ah_iobase = sc->iobase; | ||
625 | common = ath5k_hw_common(sc->ah); | ||
626 | common->ops = &ath5k_common_ops; | ||
627 | common->ah = sc->ah; | ||
628 | common->hw = hw; | ||
629 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
630 | |||
631 | /* Initialize device */ | ||
632 | ret = ath5k_hw_attach(sc); | ||
633 | if (ret) { | ||
634 | goto err_free_ah; | ||
635 | } | ||
636 | |||
637 | /* set up multi-rate retry capabilities */ | ||
638 | if (sc->ah->ah_version == AR5K_AR5212) { | ||
639 | hw->max_rates = 4; | ||
640 | hw->max_rate_tries = 11; | ||
641 | } | ||
642 | |||
643 | /* Finish private driver data initialization */ | ||
644 | ret = ath5k_attach(pdev, hw); | ||
645 | if (ret) | ||
646 | goto err_ah; | ||
647 | |||
648 | ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", | ||
649 | ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), | ||
650 | sc->ah->ah_mac_srev, | ||
651 | sc->ah->ah_phy_revision); | ||
652 | |||
653 | if (!sc->ah->ah_single_chip) { | ||
654 | /* Single chip radio (!RF5111) */ | ||
655 | if (sc->ah->ah_radio_5ghz_revision && | ||
656 | !sc->ah->ah_radio_2ghz_revision) { | ||
657 | /* No 5GHz support -> report 2GHz radio */ | ||
658 | if (!test_bit(AR5K_MODE_11A, | ||
659 | sc->ah->ah_capabilities.cap_mode)) { | ||
660 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
661 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
662 | sc->ah->ah_radio_5ghz_revision), | ||
663 | sc->ah->ah_radio_5ghz_revision); | ||
664 | /* No 2GHz support (5110 and some | ||
665 | * 5Ghz only cards) -> report 5Ghz radio */ | ||
666 | } else if (!test_bit(AR5K_MODE_11B, | ||
667 | sc->ah->ah_capabilities.cap_mode)) { | ||
668 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
669 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
670 | sc->ah->ah_radio_5ghz_revision), | ||
671 | sc->ah->ah_radio_5ghz_revision); | ||
672 | /* Multiband radio */ | ||
673 | } else { | ||
674 | ATH5K_INFO(sc, "RF%s multiband radio found" | ||
675 | " (0x%x)\n", | ||
676 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
677 | sc->ah->ah_radio_5ghz_revision), | ||
678 | sc->ah->ah_radio_5ghz_revision); | ||
679 | } | ||
680 | } | ||
681 | /* Multi chip radio (RF5111 - RF2111) -> | ||
682 | * report both 2GHz/5GHz radios */ | ||
683 | else if (sc->ah->ah_radio_5ghz_revision && | ||
684 | sc->ah->ah_radio_2ghz_revision){ | ||
685 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
686 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
687 | sc->ah->ah_radio_5ghz_revision), | ||
688 | sc->ah->ah_radio_5ghz_revision); | ||
689 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
690 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
691 | sc->ah->ah_radio_2ghz_revision), | ||
692 | sc->ah->ah_radio_2ghz_revision); | ||
693 | } | ||
694 | } | ||
695 | |||
696 | |||
697 | /* ready to process interrupts */ | ||
698 | __clear_bit(ATH_STAT_INVALID, sc->status); | ||
699 | |||
700 | return 0; | ||
701 | err_ah: | ||
702 | ath5k_hw_detach(sc->ah); | ||
703 | err_irq: | ||
704 | free_irq(pdev->irq, sc); | ||
705 | err_free_ah: | ||
706 | kfree(sc->ah); | ||
707 | err_free: | ||
708 | ieee80211_free_hw(hw); | ||
709 | err_map: | ||
710 | pci_iounmap(pdev, mem); | ||
711 | err_reg: | ||
712 | pci_release_region(pdev, 0); | ||
713 | err_dis: | ||
714 | pci_disable_device(pdev); | ||
715 | err: | ||
716 | return ret; | ||
717 | } | ||
718 | |||
719 | static void __devexit | ||
720 | ath5k_pci_remove(struct pci_dev *pdev) | ||
721 | { | ||
722 | struct ath5k_softc *sc = pci_get_drvdata(pdev); | ||
723 | |||
724 | ath5k_debug_finish_device(sc); | ||
725 | ath5k_detach(pdev, sc->hw); | ||
726 | ath5k_hw_detach(sc->ah); | ||
727 | kfree(sc->ah); | ||
728 | free_irq(pdev->irq, sc); | ||
729 | pci_iounmap(pdev, sc->iobase); | ||
730 | pci_release_region(pdev, 0); | ||
731 | pci_disable_device(pdev); | ||
732 | ieee80211_free_hw(sc->hw); | ||
733 | } | ||
734 | |||
735 | #ifdef CONFIG_PM_SLEEP | ||
736 | static int ath5k_pci_suspend(struct device *dev) | ||
737 | { | ||
738 | struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); | ||
739 | |||
740 | ath5k_led_off(sc); | ||
741 | return 0; | ||
742 | } | ||
743 | |||
744 | static int ath5k_pci_resume(struct device *dev) | ||
745 | { | ||
746 | struct pci_dev *pdev = to_pci_dev(dev); | ||
747 | struct ath5k_softc *sc = pci_get_drvdata(pdev); | ||
748 | |||
749 | /* | ||
750 | * Suspend/Resume resets the PCI configuration space, so we have to | ||
751 | * re-disable the RETRY_TIMEOUT register (0x41) to keep | ||
752 | * PCI Tx retries from interfering with C3 CPU state | ||
753 | */ | ||
754 | pci_write_config_byte(pdev, 0x41, 0); | ||
755 | |||
756 | ath5k_led_enable(sc); | ||
757 | return 0; | ||
758 | } | ||
759 | #endif /* CONFIG_PM_SLEEP */ | ||
760 | |||
761 | |||
762 | /***********************\ | 274 | /***********************\ |
763 | * Driver Initialization * | 275 | * Driver Initialization * |
764 | \***********************/ | 276 | \***********************/ |
@@ -772,170 +284,6 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re | |||
772 | return ath_reg_notifier_apply(wiphy, request, regulatory); | 284 | return ath_reg_notifier_apply(wiphy, request, regulatory); |
773 | } | 285 | } |
774 | 286 | ||
775 | static int | ||
776 | ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | ||
777 | { | ||
778 | struct ath5k_softc *sc = hw->priv; | ||
779 | struct ath5k_hw *ah = sc->ah; | ||
780 | struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); | ||
781 | u8 mac[ETH_ALEN] = {}; | ||
782 | int ret; | ||
783 | |||
784 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); | ||
785 | |||
786 | /* | ||
787 | * Check if the MAC has multi-rate retry support. | ||
788 | * We do this by trying to setup a fake extended | ||
789 | * descriptor. MAC's that don't have support will | ||
790 | * return false w/o doing anything. MAC's that do | ||
791 | * support it will return true w/o doing anything. | ||
792 | */ | ||
793 | ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); | ||
794 | |||
795 | if (ret < 0) | ||
796 | goto err; | ||
797 | if (ret > 0) | ||
798 | __set_bit(ATH_STAT_MRRETRY, sc->status); | ||
799 | |||
800 | /* | ||
801 | * Collect the channel list. The 802.11 layer | ||
802 | * is resposible for filtering this list based | ||
803 | * on settings like the phy mode and regulatory | ||
804 | * domain restrictions. | ||
805 | */ | ||
806 | ret = ath5k_setup_bands(hw); | ||
807 | if (ret) { | ||
808 | ATH5K_ERR(sc, "can't get channels\n"); | ||
809 | goto err; | ||
810 | } | ||
811 | |||
812 | /* NB: setup here so ath5k_rate_update is happy */ | ||
813 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) | ||
814 | ath5k_setcurmode(sc, AR5K_MODE_11A); | ||
815 | else | ||
816 | ath5k_setcurmode(sc, AR5K_MODE_11B); | ||
817 | |||
818 | /* | ||
819 | * Allocate tx+rx descriptors and populate the lists. | ||
820 | */ | ||
821 | ret = ath5k_desc_alloc(sc, pdev); | ||
822 | if (ret) { | ||
823 | ATH5K_ERR(sc, "can't allocate descriptors\n"); | ||
824 | goto err; | ||
825 | } | ||
826 | |||
827 | /* | ||
828 | * Allocate hardware transmit queues: one queue for | ||
829 | * beacon frames and one data queue for each QoS | ||
830 | * priority. Note that hw functions handle reseting | ||
831 | * these queues at the needed time. | ||
832 | */ | ||
833 | ret = ath5k_beaconq_setup(ah); | ||
834 | if (ret < 0) { | ||
835 | ATH5K_ERR(sc, "can't setup a beacon xmit queue\n"); | ||
836 | goto err_desc; | ||
837 | } | ||
838 | sc->bhalq = ret; | ||
839 | sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0); | ||
840 | if (IS_ERR(sc->cabq)) { | ||
841 | ATH5K_ERR(sc, "can't setup cab queue\n"); | ||
842 | ret = PTR_ERR(sc->cabq); | ||
843 | goto err_bhal; | ||
844 | } | ||
845 | |||
846 | sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); | ||
847 | if (IS_ERR(sc->txq)) { | ||
848 | ATH5K_ERR(sc, "can't setup xmit queue\n"); | ||
849 | ret = PTR_ERR(sc->txq); | ||
850 | goto err_queues; | ||
851 | } | ||
852 | |||
853 | tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); | ||
854 | tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); | ||
855 | tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); | ||
856 | tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); | ||
857 | tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); | ||
858 | |||
859 | INIT_WORK(&sc->reset_work, ath5k_reset_work); | ||
860 | |||
861 | ret = ath5k_eeprom_read_mac(ah, mac); | ||
862 | if (ret) { | ||
863 | ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", | ||
864 | sc->pdev->device); | ||
865 | goto err_queues; | ||
866 | } | ||
867 | |||
868 | SET_IEEE80211_PERM_ADDR(hw, mac); | ||
869 | /* All MAC address bits matter for ACKs */ | ||
870 | memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); | ||
871 | ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); | ||
872 | |||
873 | regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; | ||
874 | ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); | ||
875 | if (ret) { | ||
876 | ATH5K_ERR(sc, "can't initialize regulatory system\n"); | ||
877 | goto err_queues; | ||
878 | } | ||
879 | |||
880 | ret = ieee80211_register_hw(hw); | ||
881 | if (ret) { | ||
882 | ATH5K_ERR(sc, "can't register ieee80211 hw\n"); | ||
883 | goto err_queues; | ||
884 | } | ||
885 | |||
886 | if (!ath_is_world_regd(regulatory)) | ||
887 | regulatory_hint(hw->wiphy, regulatory->alpha2); | ||
888 | |||
889 | ath5k_init_leds(sc); | ||
890 | |||
891 | ath5k_sysfs_register(sc); | ||
892 | |||
893 | return 0; | ||
894 | err_queues: | ||
895 | ath5k_txq_release(sc); | ||
896 | err_bhal: | ||
897 | ath5k_hw_release_tx_queue(ah, sc->bhalq); | ||
898 | err_desc: | ||
899 | ath5k_desc_free(sc, pdev); | ||
900 | err: | ||
901 | return ret; | ||
902 | } | ||
903 | |||
904 | static void | ||
905 | ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) | ||
906 | { | ||
907 | struct ath5k_softc *sc = hw->priv; | ||
908 | |||
909 | /* | ||
910 | * NB: the order of these is important: | ||
911 | * o call the 802.11 layer before detaching ath5k_hw to | ||
912 | * insure callbacks into the driver to delete global | ||
913 | * key cache entries can be handled | ||
914 | * o reclaim the tx queue data structures after calling | ||
915 | * the 802.11 layer as we'll get called back to reclaim | ||
916 | * node state and potentially want to use them | ||
917 | * o to cleanup the tx queues the hal is called, so detach | ||
918 | * it last | ||
919 | * XXX: ??? detach ath5k_hw ??? | ||
920 | * Other than that, it's straightforward... | ||
921 | */ | ||
922 | ieee80211_unregister_hw(hw); | ||
923 | ath5k_desc_free(sc, pdev); | ||
924 | ath5k_txq_release(sc); | ||
925 | ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); | ||
926 | ath5k_unregister_leds(sc); | ||
927 | |||
928 | ath5k_sysfs_unregister(sc); | ||
929 | /* | ||
930 | * NB: can't reclaim these until after ieee80211_ifdetach | ||
931 | * returns because we'll get called back to reclaim node | ||
932 | * state and potentially want to use them. | ||
933 | */ | ||
934 | } | ||
935 | |||
936 | |||
937 | |||
938 | |||
939 | /********************\ | 287 | /********************\ |
940 | * Channel/mode setup * | 288 | * Channel/mode setup * |
941 | \********************/ | 289 | \********************/ |
@@ -1163,8 +511,101 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) | |||
1163 | } | 511 | } |
1164 | } | 512 | } |
1165 | 513 | ||
514 | struct ath_vif_iter_data { | ||
515 | const u8 *hw_macaddr; | ||
516 | u8 mask[ETH_ALEN]; | ||
517 | u8 active_mac[ETH_ALEN]; /* first active MAC */ | ||
518 | bool need_set_hw_addr; | ||
519 | bool found_active; | ||
520 | bool any_assoc; | ||
521 | enum nl80211_iftype opmode; | ||
522 | }; | ||
523 | |||
524 | static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
525 | { | ||
526 | struct ath_vif_iter_data *iter_data = data; | ||
527 | int i; | ||
528 | struct ath5k_vif *avf = (void *)vif->drv_priv; | ||
529 | |||
530 | if (iter_data->hw_macaddr) | ||
531 | for (i = 0; i < ETH_ALEN; i++) | ||
532 | iter_data->mask[i] &= | ||
533 | ~(iter_data->hw_macaddr[i] ^ mac[i]); | ||
534 | |||
535 | if (!iter_data->found_active) { | ||
536 | iter_data->found_active = true; | ||
537 | memcpy(iter_data->active_mac, mac, ETH_ALEN); | ||
538 | } | ||
539 | |||
540 | if (iter_data->need_set_hw_addr && iter_data->hw_macaddr) | ||
541 | if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0) | ||
542 | iter_data->need_set_hw_addr = false; | ||
543 | |||
544 | if (!iter_data->any_assoc) { | ||
545 | if (avf->assoc) | ||
546 | iter_data->any_assoc = true; | ||
547 | } | ||
548 | |||
549 | /* Calculate combined mode - when APs are active, operate in AP mode. | ||
550 | * Otherwise use the mode of the new interface. This can currently | ||
551 | * only deal with combinations of APs and STAs. Only one ad-hoc | ||
552 | * interfaces is allowed above. | ||
553 | */ | ||
554 | if (avf->opmode == NL80211_IFTYPE_AP) | ||
555 | iter_data->opmode = NL80211_IFTYPE_AP; | ||
556 | else | ||
557 | if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED) | ||
558 | iter_data->opmode = avf->opmode; | ||
559 | } | ||
560 | |||
561 | static void ath_do_set_opmode(struct ath5k_softc *sc) | ||
562 | { | ||
563 | struct ath5k_hw *ah = sc->ah; | ||
564 | ath5k_hw_set_opmode(ah, sc->opmode); | ||
565 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n", | ||
566 | sc->opmode, ath_opmode_to_string(sc->opmode)); | ||
567 | } | ||
568 | |||
569 | void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, | ||
570 | struct ieee80211_vif *vif) | ||
571 | { | ||
572 | struct ath_common *common = ath5k_hw_common(sc->ah); | ||
573 | struct ath_vif_iter_data iter_data; | ||
574 | |||
575 | /* | ||
576 | * Use the hardware MAC address as reference, the hardware uses it | ||
577 | * together with the BSSID mask when matching addresses. | ||
578 | */ | ||
579 | iter_data.hw_macaddr = common->macaddr; | ||
580 | memset(&iter_data.mask, 0xff, ETH_ALEN); | ||
581 | iter_data.found_active = false; | ||
582 | iter_data.need_set_hw_addr = true; | ||
583 | iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED; | ||
584 | |||
585 | if (vif) | ||
586 | ath_vif_iter(&iter_data, vif->addr, vif); | ||
587 | |||
588 | /* Get list of all active MAC addresses */ | ||
589 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, | ||
590 | &iter_data); | ||
591 | memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); | ||
592 | |||
593 | sc->opmode = iter_data.opmode; | ||
594 | if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED) | ||
595 | /* Nothing active, default to station mode */ | ||
596 | sc->opmode = NL80211_IFTYPE_STATION; | ||
597 | |||
598 | ath_do_set_opmode(sc); | ||
599 | |||
600 | if (iter_data.need_set_hw_addr && iter_data.found_active) | ||
601 | ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac); | ||
602 | |||
603 | if (ath5k_hw_hasbssidmask(sc->ah)) | ||
604 | ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); | ||
605 | } | ||
606 | |||
1166 | static void | 607 | static void |
1167 | ath5k_mode_setup(struct ath5k_softc *sc) | 608 | ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif) |
1168 | { | 609 | { |
1169 | struct ath5k_hw *ah = sc->ah; | 610 | struct ath5k_hw *ah = sc->ah; |
1170 | u32 rfilt; | 611 | u32 rfilt; |
@@ -1172,15 +613,9 @@ ath5k_mode_setup(struct ath5k_softc *sc) | |||
1172 | /* configure rx filter */ | 613 | /* configure rx filter */ |
1173 | rfilt = sc->filter_flags; | 614 | rfilt = sc->filter_flags; |
1174 | ath5k_hw_set_rx_filter(ah, rfilt); | 615 | ath5k_hw_set_rx_filter(ah, rfilt); |
1175 | |||
1176 | if (ath5k_hw_hasbssidmask(ah)) | ||
1177 | ath5k_hw_set_bssid_mask(ah, sc->bssidmask); | ||
1178 | |||
1179 | /* configure operational mode */ | ||
1180 | ath5k_hw_set_opmode(ah, sc->opmode); | ||
1181 | |||
1182 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode); | ||
1183 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); | 616 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); |
617 | |||
618 | ath5k_update_bssid_mask_and_opmode(sc, vif); | ||
1184 | } | 619 | } |
1185 | 620 | ||
1186 | static inline int | 621 | static inline int |
@@ -1352,13 +787,13 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1352 | flags |= AR5K_TXDESC_RTSENA; | 787 | flags |= AR5K_TXDESC_RTSENA; |
1353 | cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; | 788 | cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; |
1354 | duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, | 789 | duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, |
1355 | sc->vif, pktlen, info)); | 790 | info->control.vif, pktlen, info)); |
1356 | } | 791 | } |
1357 | if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { | 792 | if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
1358 | flags |= AR5K_TXDESC_CTSENA; | 793 | flags |= AR5K_TXDESC_CTSENA; |
1359 | cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; | 794 | cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; |
1360 | duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, | 795 | duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, |
1361 | sc->vif, pktlen, info)); | 796 | info->control.vif, pktlen, info)); |
1362 | } | 797 | } |
1363 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | 798 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, |
1364 | ieee80211_get_hdrlen_from_skb(skb), padsize, | 799 | ieee80211_get_hdrlen_from_skb(skb), padsize, |
@@ -1391,6 +826,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1391 | 826 | ||
1392 | spin_lock_bh(&txq->lock); | 827 | spin_lock_bh(&txq->lock); |
1393 | list_add_tail(&bf->list, &txq->q); | 828 | list_add_tail(&bf->list, &txq->q); |
829 | txq->txq_len++; | ||
1394 | if (txq->link == NULL) /* is this first packet? */ | 830 | if (txq->link == NULL) /* is this first packet? */ |
1395 | ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); | 831 | ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); |
1396 | else /* no, so only link it */ | 832 | else /* no, so only link it */ |
@@ -1459,10 +895,13 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) | |||
1459 | list_add_tail(&bf->list, &sc->txbuf); | 895 | list_add_tail(&bf->list, &sc->txbuf); |
1460 | } | 896 | } |
1461 | 897 | ||
1462 | /* beacon buffer */ | 898 | /* beacon buffers */ |
1463 | bf->desc = ds; | 899 | INIT_LIST_HEAD(&sc->bcbuf); |
1464 | bf->daddr = da; | 900 | for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) { |
1465 | sc->bbuf = bf; | 901 | bf->desc = ds; |
902 | bf->daddr = da; | ||
903 | list_add_tail(&bf->list, &sc->bcbuf); | ||
904 | } | ||
1466 | 905 | ||
1467 | return 0; | 906 | return 0; |
1468 | err_free: | 907 | err_free: |
@@ -1477,11 +916,12 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) | |||
1477 | { | 916 | { |
1478 | struct ath5k_buf *bf; | 917 | struct ath5k_buf *bf; |
1479 | 918 | ||
1480 | ath5k_txbuf_free_skb(sc, sc->bbuf); | ||
1481 | list_for_each_entry(bf, &sc->txbuf, list) | 919 | list_for_each_entry(bf, &sc->txbuf, list) |
1482 | ath5k_txbuf_free_skb(sc, bf); | 920 | ath5k_txbuf_free_skb(sc, bf); |
1483 | list_for_each_entry(bf, &sc->rxbuf, list) | 921 | list_for_each_entry(bf, &sc->rxbuf, list) |
1484 | ath5k_rxbuf_free_skb(sc, bf); | 922 | ath5k_rxbuf_free_skb(sc, bf); |
923 | list_for_each_entry(bf, &sc->bcbuf, list) | ||
924 | ath5k_txbuf_free_skb(sc, bf); | ||
1485 | 925 | ||
1486 | /* Free memory associated with all descriptors */ | 926 | /* Free memory associated with all descriptors */ |
1487 | pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); | 927 | pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); |
@@ -1490,13 +930,9 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) | |||
1490 | 930 | ||
1491 | kfree(sc->bufptr); | 931 | kfree(sc->bufptr); |
1492 | sc->bufptr = NULL; | 932 | sc->bufptr = NULL; |
1493 | sc->bbuf = NULL; | ||
1494 | } | 933 | } |
1495 | 934 | ||
1496 | 935 | ||
1497 | |||
1498 | |||
1499 | |||
1500 | /**************\ | 936 | /**************\ |
1501 | * Queues setup * | 937 | * Queues setup * |
1502 | \**************/ | 938 | \**************/ |
@@ -1509,16 +945,18 @@ ath5k_txq_setup(struct ath5k_softc *sc, | |||
1509 | struct ath5k_txq *txq; | 945 | struct ath5k_txq *txq; |
1510 | struct ath5k_txq_info qi = { | 946 | struct ath5k_txq_info qi = { |
1511 | .tqi_subtype = subtype, | 947 | .tqi_subtype = subtype, |
1512 | .tqi_aifs = AR5K_TXQ_USEDEFAULT, | 948 | /* XXX: default values not correct for B and XR channels, |
1513 | .tqi_cw_min = AR5K_TXQ_USEDEFAULT, | 949 | * but who cares? */ |
1514 | .tqi_cw_max = AR5K_TXQ_USEDEFAULT | 950 | .tqi_aifs = AR5K_TUNE_AIFS, |
951 | .tqi_cw_min = AR5K_TUNE_CWMIN, | ||
952 | .tqi_cw_max = AR5K_TUNE_CWMAX | ||
1515 | }; | 953 | }; |
1516 | int qnum; | 954 | int qnum; |
1517 | 955 | ||
1518 | /* | 956 | /* |
1519 | * Enable interrupts only for EOL and DESC conditions. | 957 | * Enable interrupts only for EOL and DESC conditions. |
1520 | * We mark tx descriptors to receive a DESC interrupt | 958 | * We mark tx descriptors to receive a DESC interrupt |
1521 | * when a tx queue gets deep; otherwise waiting for the | 959 | * when a tx queue gets deep; otherwise we wait for the |
1522 | * EOL to reap descriptors. Note that this is done to | 960 | * EOL to reap descriptors. Note that this is done to |
1523 | * reduce interrupt load and this only defers reaping | 961 | * reduce interrupt load and this only defers reaping |
1524 | * descriptors, never transmitting frames. Aside from | 962 | * descriptors, never transmitting frames. Aside from |
@@ -1550,6 +988,9 @@ ath5k_txq_setup(struct ath5k_softc *sc, | |||
1550 | INIT_LIST_HEAD(&txq->q); | 988 | INIT_LIST_HEAD(&txq->q); |
1551 | spin_lock_init(&txq->lock); | 989 | spin_lock_init(&txq->lock); |
1552 | txq->setup = true; | 990 | txq->setup = true; |
991 | txq->txq_len = 0; | ||
992 | txq->txq_poll_mark = false; | ||
993 | txq->txq_stuck = 0; | ||
1553 | } | 994 | } |
1554 | return &sc->txqs[qnum]; | 995 | return &sc->txqs[qnum]; |
1555 | } | 996 | } |
@@ -1558,9 +999,11 @@ static int | |||
1558 | ath5k_beaconq_setup(struct ath5k_hw *ah) | 999 | ath5k_beaconq_setup(struct ath5k_hw *ah) |
1559 | { | 1000 | { |
1560 | struct ath5k_txq_info qi = { | 1001 | struct ath5k_txq_info qi = { |
1561 | .tqi_aifs = AR5K_TXQ_USEDEFAULT, | 1002 | /* XXX: default values not correct for B and XR channels, |
1562 | .tqi_cw_min = AR5K_TXQ_USEDEFAULT, | 1003 | * but who cares? */ |
1563 | .tqi_cw_max = AR5K_TXQ_USEDEFAULT, | 1004 | .tqi_aifs = AR5K_TUNE_AIFS, |
1005 | .tqi_cw_min = AR5K_TUNE_CWMIN, | ||
1006 | .tqi_cw_max = AR5K_TUNE_CWMAX, | ||
1564 | /* NB: for dynamic turbo, don't enable any other interrupts */ | 1007 | /* NB: for dynamic turbo, don't enable any other interrupts */ |
1565 | .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE | 1008 | .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE |
1566 | }; | 1009 | }; |
@@ -1594,7 +1037,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1594 | */ | 1037 | */ |
1595 | qi.tqi_aifs = 0; | 1038 | qi.tqi_aifs = 0; |
1596 | qi.tqi_cw_min = 0; | 1039 | qi.tqi_cw_min = 0; |
1597 | qi.tqi_cw_max = 2 * ah->ah_cw_min; | 1040 | qi.tqi_cw_max = 2 * AR5K_TUNE_CWMIN; |
1598 | } | 1041 | } |
1599 | 1042 | ||
1600 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, | 1043 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, |
@@ -1644,9 +1087,11 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1644 | spin_lock_bh(&sc->txbuflock); | 1087 | spin_lock_bh(&sc->txbuflock); |
1645 | list_move_tail(&bf->list, &sc->txbuf); | 1088 | list_move_tail(&bf->list, &sc->txbuf); |
1646 | sc->txbuf_len++; | 1089 | sc->txbuf_len++; |
1090 | txq->txq_len--; | ||
1647 | spin_unlock_bh(&sc->txbuflock); | 1091 | spin_unlock_bh(&sc->txbuflock); |
1648 | } | 1092 | } |
1649 | txq->link = NULL; | 1093 | txq->link = NULL; |
1094 | txq->txq_poll_mark = false; | ||
1650 | spin_unlock_bh(&txq->lock); | 1095 | spin_unlock_bh(&txq->lock); |
1651 | } | 1096 | } |
1652 | 1097 | ||
@@ -1696,8 +1141,6 @@ ath5k_txq_release(struct ath5k_softc *sc) | |||
1696 | } | 1141 | } |
1697 | 1142 | ||
1698 | 1143 | ||
1699 | |||
1700 | |||
1701 | /*************\ | 1144 | /*************\ |
1702 | * RX Handling * | 1145 | * RX Handling * |
1703 | \*************/ | 1146 | \*************/ |
@@ -1713,7 +1156,7 @@ ath5k_rx_start(struct ath5k_softc *sc) | |||
1713 | struct ath5k_buf *bf; | 1156 | struct ath5k_buf *bf; |
1714 | int ret; | 1157 | int ret; |
1715 | 1158 | ||
1716 | common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz); | 1159 | common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz); |
1717 | 1160 | ||
1718 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", | 1161 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", |
1719 | common->cachelsz, common->rx_bufsize); | 1162 | common->cachelsz, common->rx_bufsize); |
@@ -1732,7 +1175,7 @@ ath5k_rx_start(struct ath5k_softc *sc) | |||
1732 | spin_unlock_bh(&sc->rxbuflock); | 1175 | spin_unlock_bh(&sc->rxbuflock); |
1733 | 1176 | ||
1734 | ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ | 1177 | ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ |
1735 | ath5k_mode_setup(sc); /* set filters, etc. */ | 1178 | ath5k_mode_setup(sc, NULL); /* set filters, etc. */ |
1736 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ | 1179 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ |
1737 | 1180 | ||
1738 | return 0; | 1181 | return 0; |
@@ -1840,6 +1283,15 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1840 | */ | 1283 | */ |
1841 | if (hw_tu >= sc->nexttbtt) | 1284 | if (hw_tu >= sc->nexttbtt) |
1842 | ath5k_beacon_update_timers(sc, bc_tstamp); | 1285 | ath5k_beacon_update_timers(sc, bc_tstamp); |
1286 | |||
1287 | /* Check if the beacon timers are still correct, because a TSF | ||
1288 | * update might have created a window between them - for a | ||
1289 | * longer description see the comment of this function: */ | ||
1290 | if (!ath5k_hw_check_beacon_timers(sc->ah, sc->bintval)) { | ||
1291 | ath5k_beacon_update_timers(sc, bc_tstamp); | ||
1292 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, | ||
1293 | "fixed beacon timers after beacon receive\n"); | ||
1294 | } | ||
1843 | } | 1295 | } |
1844 | } | 1296 | } |
1845 | 1297 | ||
@@ -1863,7 +1315,7 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi) | |||
1863 | } | 1315 | } |
1864 | 1316 | ||
1865 | /* | 1317 | /* |
1866 | * Compute padding position. skb must contains an IEEE 802.11 frame | 1318 | * Compute padding position. skb must contain an IEEE 802.11 frame |
1867 | */ | 1319 | */ |
1868 | static int ath5k_common_padpos(struct sk_buff *skb) | 1320 | static int ath5k_common_padpos(struct sk_buff *skb) |
1869 | { | 1321 | { |
@@ -1882,10 +1334,9 @@ static int ath5k_common_padpos(struct sk_buff *skb) | |||
1882 | } | 1334 | } |
1883 | 1335 | ||
1884 | /* | 1336 | /* |
1885 | * This function expects a 802.11 frame and returns the number of | 1337 | * This function expects an 802.11 frame and returns the number of |
1886 | * bytes added, or -1 if we don't have enought header room. | 1338 | * bytes added, or -1 if we don't have enough header room. |
1887 | */ | 1339 | */ |
1888 | |||
1889 | static int ath5k_add_padding(struct sk_buff *skb) | 1340 | static int ath5k_add_padding(struct sk_buff *skb) |
1890 | { | 1341 | { |
1891 | int padpos = ath5k_common_padpos(skb); | 1342 | int padpos = ath5k_common_padpos(skb); |
@@ -1905,10 +1356,18 @@ static int ath5k_add_padding(struct sk_buff *skb) | |||
1905 | } | 1356 | } |
1906 | 1357 | ||
1907 | /* | 1358 | /* |
1908 | * This function expects a 802.11 frame and returns the number of | 1359 | * The MAC header is padded to have 32-bit boundary if the |
1909 | * bytes removed | 1360 | * packet payload is non-zero. The general calculation for |
1361 | * padsize would take into account odd header lengths: | ||
1362 | * padsize = 4 - (hdrlen & 3); however, since only | ||
1363 | * even-length headers are used, padding can only be 0 or 2 | ||
1364 | * bytes and we can optimize this a bit. We must not try to | ||
1365 | * remove padding from short control frames that do not have a | ||
1366 | * payload. | ||
1367 | * | ||
1368 | * This function expects an 802.11 frame and returns the number of | ||
1369 | * bytes removed. | ||
1910 | */ | 1370 | */ |
1911 | |||
1912 | static int ath5k_remove_padding(struct sk_buff *skb) | 1371 | static int ath5k_remove_padding(struct sk_buff *skb) |
1913 | { | 1372 | { |
1914 | int padpos = ath5k_common_padpos(skb); | 1373 | int padpos = ath5k_common_padpos(skb); |
@@ -1929,14 +1388,6 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1929 | { | 1388 | { |
1930 | struct ieee80211_rx_status *rxs; | 1389 | struct ieee80211_rx_status *rxs; |
1931 | 1390 | ||
1932 | /* The MAC header is padded to have 32-bit boundary if the | ||
1933 | * packet payload is non-zero. The general calculation for | ||
1934 | * padsize would take into account odd header lengths: | ||
1935 | * padsize = (4 - hdrlen % 4) % 4; However, since only | ||
1936 | * even-length headers are used, padding can only be 0 or 2 | ||
1937 | * bytes and we can optimize this a bit. In addition, we must | ||
1938 | * not try to remove padding from short control frames that do | ||
1939 | * not have payload. */ | ||
1940 | ath5k_remove_padding(skb); | 1391 | ath5k_remove_padding(skb); |
1941 | 1392 | ||
1942 | rxs = IEEE80211_SKB_RXCB(skb); | 1393 | rxs = IEEE80211_SKB_RXCB(skb); |
@@ -2007,6 +1458,7 @@ static bool | |||
2007 | ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) | 1458 | ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) |
2008 | { | 1459 | { |
2009 | sc->stats.rx_all_count++; | 1460 | sc->stats.rx_all_count++; |
1461 | sc->stats.rx_bytes_count += rs->rs_datalen; | ||
2010 | 1462 | ||
2011 | if (unlikely(rs->rs_status)) { | 1463 | if (unlikely(rs->rs_status)) { |
2012 | if (rs->rs_status & AR5K_RXERR_CRC) | 1464 | if (rs->rs_status & AR5K_RXERR_CRC) |
@@ -2040,9 +1492,8 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) | |||
2040 | return true; | 1492 | return true; |
2041 | } | 1493 | } |
2042 | 1494 | ||
2043 | /* let crypto-error packets fall through in MNTR */ | 1495 | /* reject any frames with non-crypto errors */ |
2044 | if ((rs->rs_status & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || | 1496 | if (rs->rs_status & ~(AR5K_RXERR_DECRYPT)) |
2045 | sc->opmode != NL80211_IFTYPE_MONITOR) | ||
2046 | return false; | 1497 | return false; |
2047 | } | 1498 | } |
2048 | 1499 | ||
@@ -2123,6 +1574,118 @@ unlock: | |||
2123 | * TX Handling * | 1574 | * TX Handling * |
2124 | \*************/ | 1575 | \*************/ |
2125 | 1576 | ||
1577 | static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
1578 | struct ath5k_txq *txq) | ||
1579 | { | ||
1580 | struct ath5k_softc *sc = hw->priv; | ||
1581 | struct ath5k_buf *bf; | ||
1582 | unsigned long flags; | ||
1583 | int padsize; | ||
1584 | |||
1585 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); | ||
1586 | |||
1587 | /* | ||
1588 | * The hardware expects the header padded to 4 byte boundaries. | ||
1589 | * If this is not the case, we add the padding after the header. | ||
1590 | */ | ||
1591 | padsize = ath5k_add_padding(skb); | ||
1592 | if (padsize < 0) { | ||
1593 | ATH5K_ERR(sc, "tx hdrlen not %%4: not enough" | ||
1594 | " headroom to pad"); | ||
1595 | goto drop_packet; | ||
1596 | } | ||
1597 | |||
1598 | if (txq->txq_len >= ATH5K_TXQ_LEN_MAX) | ||
1599 | ieee80211_stop_queue(hw, txq->qnum); | ||
1600 | |||
1601 | spin_lock_irqsave(&sc->txbuflock, flags); | ||
1602 | if (list_empty(&sc->txbuf)) { | ||
1603 | ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); | ||
1604 | spin_unlock_irqrestore(&sc->txbuflock, flags); | ||
1605 | ieee80211_stop_queues(hw); | ||
1606 | goto drop_packet; | ||
1607 | } | ||
1608 | bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); | ||
1609 | list_del(&bf->list); | ||
1610 | sc->txbuf_len--; | ||
1611 | if (list_empty(&sc->txbuf)) | ||
1612 | ieee80211_stop_queues(hw); | ||
1613 | spin_unlock_irqrestore(&sc->txbuflock, flags); | ||
1614 | |||
1615 | bf->skb = skb; | ||
1616 | |||
1617 | if (ath5k_txbuf_setup(sc, bf, txq, padsize)) { | ||
1618 | bf->skb = NULL; | ||
1619 | spin_lock_irqsave(&sc->txbuflock, flags); | ||
1620 | list_add_tail(&bf->list, &sc->txbuf); | ||
1621 | sc->txbuf_len++; | ||
1622 | spin_unlock_irqrestore(&sc->txbuflock, flags); | ||
1623 | goto drop_packet; | ||
1624 | } | ||
1625 | return NETDEV_TX_OK; | ||
1626 | |||
1627 | drop_packet: | ||
1628 | dev_kfree_skb_any(skb); | ||
1629 | return NETDEV_TX_OK; | ||
1630 | } | ||
1631 | |||
1632 | static void | ||
1633 | ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, | ||
1634 | struct ath5k_tx_status *ts) | ||
1635 | { | ||
1636 | struct ieee80211_tx_info *info; | ||
1637 | int i; | ||
1638 | |||
1639 | sc->stats.tx_all_count++; | ||
1640 | sc->stats.tx_bytes_count += skb->len; | ||
1641 | info = IEEE80211_SKB_CB(skb); | ||
1642 | |||
1643 | ieee80211_tx_info_clear_status(info); | ||
1644 | for (i = 0; i < 4; i++) { | ||
1645 | struct ieee80211_tx_rate *r = | ||
1646 | &info->status.rates[i]; | ||
1647 | |||
1648 | if (ts->ts_rate[i]) { | ||
1649 | r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]); | ||
1650 | r->count = ts->ts_retry[i]; | ||
1651 | } else { | ||
1652 | r->idx = -1; | ||
1653 | r->count = 0; | ||
1654 | } | ||
1655 | } | ||
1656 | |||
1657 | /* count the successful attempt as well */ | ||
1658 | info->status.rates[ts->ts_final_idx].count++; | ||
1659 | |||
1660 | if (unlikely(ts->ts_status)) { | ||
1661 | sc->stats.ack_fail++; | ||
1662 | if (ts->ts_status & AR5K_TXERR_FILT) { | ||
1663 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
1664 | sc->stats.txerr_filt++; | ||
1665 | } | ||
1666 | if (ts->ts_status & AR5K_TXERR_XRETRY) | ||
1667 | sc->stats.txerr_retry++; | ||
1668 | if (ts->ts_status & AR5K_TXERR_FIFO) | ||
1669 | sc->stats.txerr_fifo++; | ||
1670 | } else { | ||
1671 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
1672 | info->status.ack_signal = ts->ts_rssi; | ||
1673 | } | ||
1674 | |||
1675 | /* | ||
1676 | * Remove MAC header padding before giving the frame | ||
1677 | * back to mac80211. | ||
1678 | */ | ||
1679 | ath5k_remove_padding(skb); | ||
1680 | |||
1681 | if (ts->ts_antenna > 0 && ts->ts_antenna < 5) | ||
1682 | sc->stats.antenna_tx[ts->ts_antenna]++; | ||
1683 | else | ||
1684 | sc->stats.antenna_tx[0]++; /* invalid */ | ||
1685 | |||
1686 | ieee80211_tx_status(sc->hw, skb); | ||
1687 | } | ||
1688 | |||
2126 | static void | 1689 | static void |
2127 | ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | 1690 | ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) |
2128 | { | 1691 | { |
@@ -2130,96 +1693,51 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
2130 | struct ath5k_buf *bf, *bf0; | 1693 | struct ath5k_buf *bf, *bf0; |
2131 | struct ath5k_desc *ds; | 1694 | struct ath5k_desc *ds; |
2132 | struct sk_buff *skb; | 1695 | struct sk_buff *skb; |
2133 | struct ieee80211_tx_info *info; | 1696 | int ret; |
2134 | int i, ret; | ||
2135 | 1697 | ||
2136 | spin_lock(&txq->lock); | 1698 | spin_lock(&txq->lock); |
2137 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { | 1699 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { |
2138 | ds = bf->desc; | ||
2139 | 1700 | ||
2140 | /* | 1701 | txq->txq_poll_mark = false; |
2141 | * It's possible that the hardware can say the buffer is | ||
2142 | * completed when it hasn't yet loaded the ds_link from | ||
2143 | * host memory and moved on. If there are more TX | ||
2144 | * descriptors in the queue, wait for TXDP to change | ||
2145 | * before processing this one. | ||
2146 | */ | ||
2147 | if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr && | ||
2148 | !list_is_last(&bf->list, &txq->q)) | ||
2149 | break; | ||
2150 | 1702 | ||
2151 | ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); | 1703 | /* skb might already have been processed last time. */ |
2152 | if (unlikely(ret == -EINPROGRESS)) | 1704 | if (bf->skb != NULL) { |
2153 | break; | 1705 | ds = bf->desc; |
2154 | else if (unlikely(ret)) { | ||
2155 | ATH5K_ERR(sc, "error %d while processing queue %u\n", | ||
2156 | ret, txq->qnum); | ||
2157 | break; | ||
2158 | } | ||
2159 | |||
2160 | sc->stats.tx_all_count++; | ||
2161 | skb = bf->skb; | ||
2162 | info = IEEE80211_SKB_CB(skb); | ||
2163 | bf->skb = NULL; | ||
2164 | |||
2165 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, | ||
2166 | PCI_DMA_TODEVICE); | ||
2167 | 1706 | ||
2168 | ieee80211_tx_info_clear_status(info); | 1707 | ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); |
2169 | for (i = 0; i < 4; i++) { | 1708 | if (unlikely(ret == -EINPROGRESS)) |
2170 | struct ieee80211_tx_rate *r = | 1709 | break; |
2171 | &info->status.rates[i]; | 1710 | else if (unlikely(ret)) { |
2172 | 1711 | ATH5K_ERR(sc, | |
2173 | if (ts.ts_rate[i]) { | 1712 | "error %d while processing " |
2174 | r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]); | 1713 | "queue %u\n", ret, txq->qnum); |
2175 | r->count = ts.ts_retry[i]; | 1714 | break; |
2176 | } else { | ||
2177 | r->idx = -1; | ||
2178 | r->count = 0; | ||
2179 | } | 1715 | } |
2180 | } | ||
2181 | 1716 | ||
2182 | /* count the successful attempt as well */ | 1717 | skb = bf->skb; |
2183 | info->status.rates[ts.ts_final_idx].count++; | 1718 | bf->skb = NULL; |
2184 | 1719 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, | |
2185 | if (unlikely(ts.ts_status)) { | 1720 | PCI_DMA_TODEVICE); |
2186 | sc->stats.ack_fail++; | 1721 | ath5k_tx_frame_completed(sc, skb, &ts); |
2187 | if (ts.ts_status & AR5K_TXERR_FILT) { | ||
2188 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
2189 | sc->stats.txerr_filt++; | ||
2190 | } | ||
2191 | if (ts.ts_status & AR5K_TXERR_XRETRY) | ||
2192 | sc->stats.txerr_retry++; | ||
2193 | if (ts.ts_status & AR5K_TXERR_FIFO) | ||
2194 | sc->stats.txerr_fifo++; | ||
2195 | } else { | ||
2196 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
2197 | info->status.ack_signal = ts.ts_rssi; | ||
2198 | } | 1722 | } |
2199 | 1723 | ||
2200 | /* | 1724 | /* |
2201 | * Remove MAC header padding before giving the frame | 1725 | * It's possible that the hardware can say the buffer is |
2202 | * back to mac80211. | 1726 | * completed when it hasn't yet loaded the ds_link from |
1727 | * host memory and moved on. | ||
1728 | * Always keep the last descriptor to avoid HW races... | ||
2203 | */ | 1729 | */ |
2204 | ath5k_remove_padding(skb); | 1730 | if (ath5k_hw_get_txdp(sc->ah, txq->qnum) != bf->daddr) { |
2205 | 1731 | spin_lock(&sc->txbuflock); | |
2206 | if (ts.ts_antenna > 0 && ts.ts_antenna < 5) | 1732 | list_move_tail(&bf->list, &sc->txbuf); |
2207 | sc->stats.antenna_tx[ts.ts_antenna]++; | 1733 | sc->txbuf_len++; |
2208 | else | 1734 | txq->txq_len--; |
2209 | sc->stats.antenna_tx[0]++; /* invalid */ | 1735 | spin_unlock(&sc->txbuflock); |
2210 | 1736 | } | |
2211 | ieee80211_tx_status(sc->hw, skb); | ||
2212 | |||
2213 | spin_lock(&sc->txbuflock); | ||
2214 | list_move_tail(&bf->list, &sc->txbuf); | ||
2215 | sc->txbuf_len++; | ||
2216 | spin_unlock(&sc->txbuflock); | ||
2217 | } | 1737 | } |
2218 | if (likely(list_empty(&txq->q))) | ||
2219 | txq->link = NULL; | ||
2220 | spin_unlock(&txq->lock); | 1738 | spin_unlock(&txq->lock); |
2221 | if (sc->txbuf_len > ATH_TXBUF / 5) | 1739 | if (txq->txq_len < ATH5K_TXQ_LEN_LOW && txq->qnum < 4) |
2222 | ieee80211_wake_queues(sc->hw); | 1740 | ieee80211_wake_queue(sc->hw, txq->qnum); |
2223 | } | 1741 | } |
2224 | 1742 | ||
2225 | static void | 1743 | static void |
@@ -2285,10 +1803,11 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
2285 | * default antenna which is supposed to be an omni. | 1803 | * default antenna which is supposed to be an omni. |
2286 | * | 1804 | * |
2287 | * Note2: On sectored scenarios it's possible to have | 1805 | * Note2: On sectored scenarios it's possible to have |
2288 | * multiple antennas (1omni -the default- and 14 sectors) | 1806 | * multiple antennas (1 omni -- the default -- and 14 |
2289 | * so if we choose to actually support this mode we need | 1807 | * sectors), so if we choose to actually support this |
2290 | * to allow user to set how many antennas we have and tweak | 1808 | * mode, we need to allow the user to set how many antennas |
2291 | * the code below to send beacons on all of them. | 1809 | * we have and tweak the code below to send beacons |
1810 | * on all of them. | ||
2292 | */ | 1811 | */ |
2293 | if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP) | 1812 | if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP) |
2294 | antenna = sc->bsent & 4 ? 2 : 1; | 1813 | antenna = sc->bsent & 4 ? 2 : 1; |
@@ -2314,6 +1833,44 @@ err_unmap: | |||
2314 | } | 1833 | } |
2315 | 1834 | ||
2316 | /* | 1835 | /* |
1836 | * Updates the beacon that is sent by ath5k_beacon_send. For adhoc, | ||
1837 | * this is called only once at config_bss time, for AP we do it every | ||
1838 | * SWBA interrupt so that the TIM will reflect buffered frames. | ||
1839 | * | ||
1840 | * Called with the beacon lock. | ||
1841 | */ | ||
1842 | static int | ||
1843 | ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | ||
1844 | { | ||
1845 | int ret; | ||
1846 | struct ath5k_softc *sc = hw->priv; | ||
1847 | struct ath5k_vif *avf = (void *)vif->drv_priv; | ||
1848 | struct sk_buff *skb; | ||
1849 | |||
1850 | if (WARN_ON(!vif)) { | ||
1851 | ret = -EINVAL; | ||
1852 | goto out; | ||
1853 | } | ||
1854 | |||
1855 | skb = ieee80211_beacon_get(hw, vif); | ||
1856 | |||
1857 | if (!skb) { | ||
1858 | ret = -ENOMEM; | ||
1859 | goto out; | ||
1860 | } | ||
1861 | |||
1862 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); | ||
1863 | |||
1864 | ath5k_txbuf_free_skb(sc, avf->bbuf); | ||
1865 | avf->bbuf->skb = skb; | ||
1866 | ret = ath5k_beacon_setup(sc, avf->bbuf); | ||
1867 | if (ret) | ||
1868 | avf->bbuf->skb = NULL; | ||
1869 | out: | ||
1870 | return ret; | ||
1871 | } | ||
1872 | |||
1873 | /* | ||
2317 | * Transmit a beacon frame at SWBA. Dynamic updates to the | 1874 | * Transmit a beacon frame at SWBA. Dynamic updates to the |
2318 | * frame contents are done as needed and the slot time is | 1875 | * frame contents are done as needed and the slot time is |
2319 | * also adjusted based on current state. | 1876 | * also adjusted based on current state. |
@@ -2324,20 +1881,17 @@ err_unmap: | |||
2324 | static void | 1881 | static void |
2325 | ath5k_beacon_send(struct ath5k_softc *sc) | 1882 | ath5k_beacon_send(struct ath5k_softc *sc) |
2326 | { | 1883 | { |
2327 | struct ath5k_buf *bf = sc->bbuf; | ||
2328 | struct ath5k_hw *ah = sc->ah; | 1884 | struct ath5k_hw *ah = sc->ah; |
1885 | struct ieee80211_vif *vif; | ||
1886 | struct ath5k_vif *avf; | ||
1887 | struct ath5k_buf *bf; | ||
2329 | struct sk_buff *skb; | 1888 | struct sk_buff *skb; |
2330 | 1889 | ||
2331 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); | 1890 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); |
2332 | 1891 | ||
2333 | if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || | ||
2334 | sc->opmode == NL80211_IFTYPE_MONITOR)) { | ||
2335 | ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); | ||
2336 | return; | ||
2337 | } | ||
2338 | /* | 1892 | /* |
2339 | * Check if the previous beacon has gone out. If | 1893 | * Check if the previous beacon has gone out. If |
2340 | * not don't don't try to post another, skip this | 1894 | * not, don't don't try to post another: skip this |
2341 | * period and wait for the next. Missed beacons | 1895 | * period and wait for the next. Missed beacons |
2342 | * indicate a problem and should not occur. If we | 1896 | * indicate a problem and should not occur. If we |
2343 | * miss too many consecutive beacons reset the device. | 1897 | * miss too many consecutive beacons reset the device. |
@@ -2363,6 +1917,28 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
2363 | sc->bmisscount = 0; | 1917 | sc->bmisscount = 0; |
2364 | } | 1918 | } |
2365 | 1919 | ||
1920 | if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { | ||
1921 | u64 tsf = ath5k_hw_get_tsf64(ah); | ||
1922 | u32 tsftu = TSF_TO_TU(tsf); | ||
1923 | int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; | ||
1924 | vif = sc->bslot[(slot + 1) % ATH_BCBUF]; | ||
1925 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, | ||
1926 | "tsf %llx tsftu %x intval %u slot %u vif %p\n", | ||
1927 | (unsigned long long)tsf, tsftu, sc->bintval, slot, vif); | ||
1928 | } else /* only one interface */ | ||
1929 | vif = sc->bslot[0]; | ||
1930 | |||
1931 | if (!vif) | ||
1932 | return; | ||
1933 | |||
1934 | avf = (void *)vif->drv_priv; | ||
1935 | bf = avf->bbuf; | ||
1936 | if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || | ||
1937 | sc->opmode == NL80211_IFTYPE_MONITOR)) { | ||
1938 | ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); | ||
1939 | return; | ||
1940 | } | ||
1941 | |||
2366 | /* | 1942 | /* |
2367 | * Stop any current dma and put the new frame on the queue. | 1943 | * Stop any current dma and put the new frame on the queue. |
2368 | * This should never fail since we check above that no frames | 1944 | * This should never fail since we check above that no frames |
@@ -2375,23 +1951,22 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
2375 | 1951 | ||
2376 | /* refresh the beacon for AP mode */ | 1952 | /* refresh the beacon for AP mode */ |
2377 | if (sc->opmode == NL80211_IFTYPE_AP) | 1953 | if (sc->opmode == NL80211_IFTYPE_AP) |
2378 | ath5k_beacon_update(sc->hw, sc->vif); | 1954 | ath5k_beacon_update(sc->hw, vif); |
2379 | 1955 | ||
2380 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); | 1956 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); |
2381 | ath5k_hw_start_tx_dma(ah, sc->bhalq); | 1957 | ath5k_hw_start_tx_dma(ah, sc->bhalq); |
2382 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", | 1958 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", |
2383 | sc->bhalq, (unsigned long long)bf->daddr, bf->desc); | 1959 | sc->bhalq, (unsigned long long)bf->daddr, bf->desc); |
2384 | 1960 | ||
2385 | skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); | 1961 | skb = ieee80211_get_buffered_bc(sc->hw, vif); |
2386 | while (skb) { | 1962 | while (skb) { |
2387 | ath5k_tx_queue(sc->hw, skb, sc->cabq); | 1963 | ath5k_tx_queue(sc->hw, skb, sc->cabq); |
2388 | skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); | 1964 | skb = ieee80211_get_buffered_bc(sc->hw, vif); |
2389 | } | 1965 | } |
2390 | 1966 | ||
2391 | sc->bsent++; | 1967 | sc->bsent++; |
2392 | } | 1968 | } |
2393 | 1969 | ||
2394 | |||
2395 | /** | 1970 | /** |
2396 | * ath5k_beacon_update_timers - update beacon timers | 1971 | * ath5k_beacon_update_timers - update beacon timers |
2397 | * | 1972 | * |
@@ -2416,6 +1991,12 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) | |||
2416 | u64 hw_tsf; | 1991 | u64 hw_tsf; |
2417 | 1992 | ||
2418 | intval = sc->bintval & AR5K_BEACON_PERIOD; | 1993 | intval = sc->bintval & AR5K_BEACON_PERIOD; |
1994 | if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { | ||
1995 | intval /= ATH_BCBUF; /* staggered multi-bss beacons */ | ||
1996 | if (intval < 15) | ||
1997 | ATH5K_WARN(sc, "intval %u is too low, min 15\n", | ||
1998 | intval); | ||
1999 | } | ||
2419 | if (WARN_ON(!intval)) | 2000 | if (WARN_ON(!intval)) |
2420 | return; | 2001 | return; |
2421 | 2002 | ||
@@ -2426,8 +2007,11 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) | |||
2426 | hw_tsf = ath5k_hw_get_tsf64(ah); | 2007 | hw_tsf = ath5k_hw_get_tsf64(ah); |
2427 | hw_tu = TSF_TO_TU(hw_tsf); | 2008 | hw_tu = TSF_TO_TU(hw_tsf); |
2428 | 2009 | ||
2429 | #define FUDGE 3 | 2010 | #define FUDGE AR5K_TUNE_SW_BEACON_RESP + 3 |
2430 | /* we use FUDGE to make sure the next TBTT is ahead of the current TU */ | 2011 | /* We use FUDGE to make sure the next TBTT is ahead of the current TU. |
2012 | * Since we later substract AR5K_TUNE_SW_BEACON_RESP (10) in the timer | ||
2013 | * configuration we need to make sure it is bigger than that. */ | ||
2014 | |||
2431 | if (bc_tsf == -1) { | 2015 | if (bc_tsf == -1) { |
2432 | /* | 2016 | /* |
2433 | * no beacons received, called internally. | 2017 | * no beacons received, called internally. |
@@ -2493,7 +2077,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) | |||
2493 | intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : ""); | 2077 | intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : ""); |
2494 | } | 2078 | } |
2495 | 2079 | ||
2496 | |||
2497 | /** | 2080 | /** |
2498 | * ath5k_beacon_config - Configure the beacon queues and interrupts | 2081 | * ath5k_beacon_config - Configure the beacon queues and interrupts |
2499 | * | 2082 | * |
@@ -2572,155 +2155,6 @@ static void ath5k_tasklet_beacon(unsigned long data) | |||
2572 | * Interrupt handling * | 2155 | * Interrupt handling * |
2573 | \********************/ | 2156 | \********************/ |
2574 | 2157 | ||
2575 | static int | ||
2576 | ath5k_init(struct ath5k_softc *sc) | ||
2577 | { | ||
2578 | struct ath5k_hw *ah = sc->ah; | ||
2579 | int ret, i; | ||
2580 | |||
2581 | mutex_lock(&sc->lock); | ||
2582 | |||
2583 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); | ||
2584 | |||
2585 | /* | ||
2586 | * Stop anything previously setup. This is safe | ||
2587 | * no matter this is the first time through or not. | ||
2588 | */ | ||
2589 | ath5k_stop_locked(sc); | ||
2590 | |||
2591 | /* | ||
2592 | * The basic interface to setting the hardware in a good | ||
2593 | * state is ``reset''. On return the hardware is known to | ||
2594 | * be powered up and with interrupts disabled. This must | ||
2595 | * be followed by initialization of the appropriate bits | ||
2596 | * and then setup of the interrupt mask. | ||
2597 | */ | ||
2598 | sc->curchan = sc->hw->conf.channel; | ||
2599 | sc->curband = &sc->sbands[sc->curchan->band]; | ||
2600 | sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | | ||
2601 | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | | ||
2602 | AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; | ||
2603 | |||
2604 | ret = ath5k_reset(sc, NULL); | ||
2605 | if (ret) | ||
2606 | goto done; | ||
2607 | |||
2608 | ath5k_rfkill_hw_start(ah); | ||
2609 | |||
2610 | /* | ||
2611 | * Reset the key cache since some parts do not reset the | ||
2612 | * contents on initial power up or resume from suspend. | ||
2613 | */ | ||
2614 | for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) | ||
2615 | ath5k_hw_reset_key(ah, i); | ||
2616 | |||
2617 | ath5k_hw_set_ack_bitrate_high(ah, true); | ||
2618 | ret = 0; | ||
2619 | done: | ||
2620 | mmiowb(); | ||
2621 | mutex_unlock(&sc->lock); | ||
2622 | return ret; | ||
2623 | } | ||
2624 | |||
2625 | static int | ||
2626 | ath5k_stop_locked(struct ath5k_softc *sc) | ||
2627 | { | ||
2628 | struct ath5k_hw *ah = sc->ah; | ||
2629 | |||
2630 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n", | ||
2631 | test_bit(ATH_STAT_INVALID, sc->status)); | ||
2632 | |||
2633 | /* | ||
2634 | * Shutdown the hardware and driver: | ||
2635 | * stop output from above | ||
2636 | * disable interrupts | ||
2637 | * turn off timers | ||
2638 | * turn off the radio | ||
2639 | * clear transmit machinery | ||
2640 | * clear receive machinery | ||
2641 | * drain and release tx queues | ||
2642 | * reclaim beacon resources | ||
2643 | * power down hardware | ||
2644 | * | ||
2645 | * Note that some of this work is not possible if the | ||
2646 | * hardware is gone (invalid). | ||
2647 | */ | ||
2648 | ieee80211_stop_queues(sc->hw); | ||
2649 | |||
2650 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { | ||
2651 | ath5k_led_off(sc); | ||
2652 | ath5k_hw_set_imr(ah, 0); | ||
2653 | synchronize_irq(sc->pdev->irq); | ||
2654 | } | ||
2655 | ath5k_txq_cleanup(sc); | ||
2656 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { | ||
2657 | ath5k_rx_stop(sc); | ||
2658 | ath5k_hw_phy_disable(ah); | ||
2659 | } | ||
2660 | |||
2661 | return 0; | ||
2662 | } | ||
2663 | |||
2664 | static void stop_tasklets(struct ath5k_softc *sc) | ||
2665 | { | ||
2666 | tasklet_kill(&sc->rxtq); | ||
2667 | tasklet_kill(&sc->txtq); | ||
2668 | tasklet_kill(&sc->calib); | ||
2669 | tasklet_kill(&sc->beacontq); | ||
2670 | tasklet_kill(&sc->ani_tasklet); | ||
2671 | } | ||
2672 | |||
2673 | /* | ||
2674 | * Stop the device, grabbing the top-level lock to protect | ||
2675 | * against concurrent entry through ath5k_init (which can happen | ||
2676 | * if another thread does a system call and the thread doing the | ||
2677 | * stop is preempted). | ||
2678 | */ | ||
2679 | static int | ||
2680 | ath5k_stop_hw(struct ath5k_softc *sc) | ||
2681 | { | ||
2682 | int ret; | ||
2683 | |||
2684 | mutex_lock(&sc->lock); | ||
2685 | ret = ath5k_stop_locked(sc); | ||
2686 | if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) { | ||
2687 | /* | ||
2688 | * Don't set the card in full sleep mode! | ||
2689 | * | ||
2690 | * a) When the device is in this state it must be carefully | ||
2691 | * woken up or references to registers in the PCI clock | ||
2692 | * domain may freeze the bus (and system). This varies | ||
2693 | * by chip and is mostly an issue with newer parts | ||
2694 | * (madwifi sources mentioned srev >= 0x78) that go to | ||
2695 | * sleep more quickly. | ||
2696 | * | ||
2697 | * b) On older chips full sleep results a weird behaviour | ||
2698 | * during wakeup. I tested various cards with srev < 0x78 | ||
2699 | * and they don't wake up after module reload, a second | ||
2700 | * module reload is needed to bring the card up again. | ||
2701 | * | ||
2702 | * Until we figure out what's going on don't enable | ||
2703 | * full chip reset on any chip (this is what Legacy HAL | ||
2704 | * and Sam's HAL do anyway). Instead Perform a full reset | ||
2705 | * on the device (same as initial state after attach) and | ||
2706 | * leave it idle (keep MAC/BB on warm reset) */ | ||
2707 | ret = ath5k_hw_on_hold(sc->ah); | ||
2708 | |||
2709 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, | ||
2710 | "putting device to sleep\n"); | ||
2711 | } | ||
2712 | ath5k_txbuf_free_skb(sc, sc->bbuf); | ||
2713 | |||
2714 | mmiowb(); | ||
2715 | mutex_unlock(&sc->lock); | ||
2716 | |||
2717 | stop_tasklets(sc); | ||
2718 | |||
2719 | ath5k_rfkill_hw_stop(sc->ah); | ||
2720 | |||
2721 | return ret; | ||
2722 | } | ||
2723 | |||
2724 | static void | 2158 | static void |
2725 | ath5k_intr_calibration_poll(struct ath5k_hw *ah) | 2159 | ath5k_intr_calibration_poll(struct ath5k_hw *ah) |
2726 | { | 2160 | { |
@@ -2857,14 +2291,13 @@ ath5k_tasklet_calibrate(unsigned long data) | |||
2857 | sc->curchan->center_freq)); | 2291 | sc->curchan->center_freq)); |
2858 | 2292 | ||
2859 | /* Noise floor calibration interrupts rx/tx path while I/Q calibration | 2293 | /* Noise floor calibration interrupts rx/tx path while I/Q calibration |
2860 | * doesn't. We stop the queues so that calibration doesn't interfere | 2294 | * doesn't. |
2861 | * with TX and don't run it as often */ | 2295 | * TODO: We should stop TX here, so that it doesn't interfere. |
2296 | * Note that stopping the queues is not enough to stop TX! */ | ||
2862 | if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) { | 2297 | if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) { |
2863 | ah->ah_cal_next_nf = jiffies + | 2298 | ah->ah_cal_next_nf = jiffies + |
2864 | msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF); | 2299 | msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF); |
2865 | ieee80211_stop_queues(sc->hw); | ||
2866 | ath5k_hw_update_noise_floor(ah); | 2300 | ath5k_hw_update_noise_floor(ah); |
2867 | ieee80211_wake_queues(sc->hw); | ||
2868 | } | 2301 | } |
2869 | 2302 | ||
2870 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; | 2303 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; |
@@ -2883,71 +2316,208 @@ ath5k_tasklet_ani(unsigned long data) | |||
2883 | } | 2316 | } |
2884 | 2317 | ||
2885 | 2318 | ||
2886 | /********************\ | 2319 | static void |
2887 | * Mac80211 functions * | 2320 | ath5k_tx_complete_poll_work(struct work_struct *work) |
2888 | \********************/ | 2321 | { |
2322 | struct ath5k_softc *sc = container_of(work, struct ath5k_softc, | ||
2323 | tx_complete_work.work); | ||
2324 | struct ath5k_txq *txq; | ||
2325 | int i; | ||
2326 | bool needreset = false; | ||
2327 | |||
2328 | for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) { | ||
2329 | if (sc->txqs[i].setup) { | ||
2330 | txq = &sc->txqs[i]; | ||
2331 | spin_lock_bh(&txq->lock); | ||
2332 | if (txq->txq_len > 1) { | ||
2333 | if (txq->txq_poll_mark) { | ||
2334 | ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, | ||
2335 | "TX queue stuck %d\n", | ||
2336 | txq->qnum); | ||
2337 | needreset = true; | ||
2338 | txq->txq_stuck++; | ||
2339 | spin_unlock_bh(&txq->lock); | ||
2340 | break; | ||
2341 | } else { | ||
2342 | txq->txq_poll_mark = true; | ||
2343 | } | ||
2344 | } | ||
2345 | spin_unlock_bh(&txq->lock); | ||
2346 | } | ||
2347 | } | ||
2348 | |||
2349 | if (needreset) { | ||
2350 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, | ||
2351 | "TX queues stuck, resetting\n"); | ||
2352 | ath5k_reset(sc, sc->curchan); | ||
2353 | } | ||
2354 | |||
2355 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, | ||
2356 | msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); | ||
2357 | } | ||
2358 | |||
2359 | |||
2360 | /*************************\ | ||
2361 | * Initialization routines * | ||
2362 | \*************************/ | ||
2889 | 2363 | ||
2890 | static int | 2364 | static int |
2891 | ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 2365 | ath5k_stop_locked(struct ath5k_softc *sc) |
2892 | { | 2366 | { |
2893 | struct ath5k_softc *sc = hw->priv; | 2367 | struct ath5k_hw *ah = sc->ah; |
2368 | |||
2369 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n", | ||
2370 | test_bit(ATH_STAT_INVALID, sc->status)); | ||
2371 | |||
2372 | /* | ||
2373 | * Shutdown the hardware and driver: | ||
2374 | * stop output from above | ||
2375 | * disable interrupts | ||
2376 | * turn off timers | ||
2377 | * turn off the radio | ||
2378 | * clear transmit machinery | ||
2379 | * clear receive machinery | ||
2380 | * drain and release tx queues | ||
2381 | * reclaim beacon resources | ||
2382 | * power down hardware | ||
2383 | * | ||
2384 | * Note that some of this work is not possible if the | ||
2385 | * hardware is gone (invalid). | ||
2386 | */ | ||
2387 | ieee80211_stop_queues(sc->hw); | ||
2894 | 2388 | ||
2895 | return ath5k_tx_queue(hw, skb, sc->txq); | 2389 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { |
2390 | ath5k_led_off(sc); | ||
2391 | ath5k_hw_set_imr(ah, 0); | ||
2392 | synchronize_irq(sc->pdev->irq); | ||
2393 | } | ||
2394 | ath5k_txq_cleanup(sc); | ||
2395 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { | ||
2396 | ath5k_rx_stop(sc); | ||
2397 | ath5k_hw_phy_disable(ah); | ||
2398 | } | ||
2399 | |||
2400 | return 0; | ||
2896 | } | 2401 | } |
2897 | 2402 | ||
2898 | static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | 2403 | static int |
2899 | struct ath5k_txq *txq) | 2404 | ath5k_init(struct ath5k_softc *sc) |
2900 | { | 2405 | { |
2901 | struct ath5k_softc *sc = hw->priv; | 2406 | struct ath5k_hw *ah = sc->ah; |
2902 | struct ath5k_buf *bf; | 2407 | struct ath_common *common = ath5k_hw_common(ah); |
2903 | unsigned long flags; | 2408 | int ret, i; |
2904 | int padsize; | ||
2905 | 2409 | ||
2906 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); | 2410 | mutex_lock(&sc->lock); |
2907 | 2411 | ||
2908 | if (sc->opmode == NL80211_IFTYPE_MONITOR) | 2412 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); |
2909 | ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n"); | ||
2910 | 2413 | ||
2911 | /* | 2414 | /* |
2912 | * the hardware expects the header padded to 4 byte boundaries | 2415 | * Stop anything previously setup. This is safe |
2913 | * if this is not the case we add the padding after the header | 2416 | * no matter this is the first time through or not. |
2914 | */ | 2417 | */ |
2915 | padsize = ath5k_add_padding(skb); | 2418 | ath5k_stop_locked(sc); |
2916 | if (padsize < 0) { | ||
2917 | ATH5K_ERR(sc, "tx hdrlen not %%4: not enough" | ||
2918 | " headroom to pad"); | ||
2919 | goto drop_packet; | ||
2920 | } | ||
2921 | 2419 | ||
2922 | spin_lock_irqsave(&sc->txbuflock, flags); | 2420 | /* |
2923 | if (list_empty(&sc->txbuf)) { | 2421 | * The basic interface to setting the hardware in a good |
2924 | ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); | 2422 | * state is ``reset''. On return the hardware is known to |
2925 | spin_unlock_irqrestore(&sc->txbuflock, flags); | 2423 | * be powered up and with interrupts disabled. This must |
2926 | ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); | 2424 | * be followed by initialization of the appropriate bits |
2927 | goto drop_packet; | 2425 | * and then setup of the interrupt mask. |
2928 | } | 2426 | */ |
2929 | bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); | 2427 | sc->curchan = sc->hw->conf.channel; |
2930 | list_del(&bf->list); | 2428 | sc->curband = &sc->sbands[sc->curchan->band]; |
2931 | sc->txbuf_len--; | 2429 | sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | |
2932 | if (list_empty(&sc->txbuf)) | 2430 | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | |
2933 | ieee80211_stop_queues(hw); | 2431 | AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; |
2934 | spin_unlock_irqrestore(&sc->txbuflock, flags); | ||
2935 | 2432 | ||
2936 | bf->skb = skb; | 2433 | ret = ath5k_reset(sc, NULL); |
2434 | if (ret) | ||
2435 | goto done; | ||
2937 | 2436 | ||
2938 | if (ath5k_txbuf_setup(sc, bf, txq, padsize)) { | 2437 | ath5k_rfkill_hw_start(ah); |
2939 | bf->skb = NULL; | 2438 | |
2940 | spin_lock_irqsave(&sc->txbuflock, flags); | 2439 | /* |
2941 | list_add_tail(&bf->list, &sc->txbuf); | 2440 | * Reset the key cache since some parts do not reset the |
2942 | sc->txbuf_len++; | 2441 | * contents on initial power up or resume from suspend. |
2943 | spin_unlock_irqrestore(&sc->txbuflock, flags); | 2442 | */ |
2944 | goto drop_packet; | 2443 | for (i = 0; i < common->keymax; i++) |
2444 | ath_hw_keyreset(common, (u16) i); | ||
2445 | |||
2446 | ath5k_hw_set_ack_bitrate_high(ah, true); | ||
2447 | |||
2448 | for (i = 0; i < ARRAY_SIZE(sc->bslot); i++) | ||
2449 | sc->bslot[i] = NULL; | ||
2450 | |||
2451 | ret = 0; | ||
2452 | done: | ||
2453 | mmiowb(); | ||
2454 | mutex_unlock(&sc->lock); | ||
2455 | |||
2456 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, | ||
2457 | msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); | ||
2458 | |||
2459 | return ret; | ||
2460 | } | ||
2461 | |||
2462 | static void stop_tasklets(struct ath5k_softc *sc) | ||
2463 | { | ||
2464 | tasklet_kill(&sc->rxtq); | ||
2465 | tasklet_kill(&sc->txtq); | ||
2466 | tasklet_kill(&sc->calib); | ||
2467 | tasklet_kill(&sc->beacontq); | ||
2468 | tasklet_kill(&sc->ani_tasklet); | ||
2469 | } | ||
2470 | |||
2471 | /* | ||
2472 | * Stop the device, grabbing the top-level lock to protect | ||
2473 | * against concurrent entry through ath5k_init (which can happen | ||
2474 | * if another thread does a system call and the thread doing the | ||
2475 | * stop is preempted). | ||
2476 | */ | ||
2477 | static int | ||
2478 | ath5k_stop_hw(struct ath5k_softc *sc) | ||
2479 | { | ||
2480 | int ret; | ||
2481 | |||
2482 | mutex_lock(&sc->lock); | ||
2483 | ret = ath5k_stop_locked(sc); | ||
2484 | if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) { | ||
2485 | /* | ||
2486 | * Don't set the card in full sleep mode! | ||
2487 | * | ||
2488 | * a) When the device is in this state it must be carefully | ||
2489 | * woken up or references to registers in the PCI clock | ||
2490 | * domain may freeze the bus (and system). This varies | ||
2491 | * by chip and is mostly an issue with newer parts | ||
2492 | * (madwifi sources mentioned srev >= 0x78) that go to | ||
2493 | * sleep more quickly. | ||
2494 | * | ||
2495 | * b) On older chips full sleep results a weird behaviour | ||
2496 | * during wakeup. I tested various cards with srev < 0x78 | ||
2497 | * and they don't wake up after module reload, a second | ||
2498 | * module reload is needed to bring the card up again. | ||
2499 | * | ||
2500 | * Until we figure out what's going on don't enable | ||
2501 | * full chip reset on any chip (this is what Legacy HAL | ||
2502 | * and Sam's HAL do anyway). Instead Perform a full reset | ||
2503 | * on the device (same as initial state after attach) and | ||
2504 | * leave it idle (keep MAC/BB on warm reset) */ | ||
2505 | ret = ath5k_hw_on_hold(sc->ah); | ||
2506 | |||
2507 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, | ||
2508 | "putting device to sleep\n"); | ||
2945 | } | 2509 | } |
2946 | return NETDEV_TX_OK; | ||
2947 | 2510 | ||
2948 | drop_packet: | 2511 | mmiowb(); |
2949 | dev_kfree_skb_any(skb); | 2512 | mutex_unlock(&sc->lock); |
2950 | return NETDEV_TX_OK; | 2513 | |
2514 | stop_tasklets(sc); | ||
2515 | |||
2516 | cancel_delayed_work_sync(&sc->tx_complete_work); | ||
2517 | |||
2518 | ath5k_rfkill_hw_stop(sc->ah); | ||
2519 | |||
2520 | return ret; | ||
2951 | } | 2521 | } |
2952 | 2522 | ||
2953 | /* | 2523 | /* |
@@ -3024,6 +2594,208 @@ static void ath5k_reset_work(struct work_struct *work) | |||
3024 | mutex_unlock(&sc->lock); | 2594 | mutex_unlock(&sc->lock); |
3025 | } | 2595 | } |
3026 | 2596 | ||
2597 | static int | ||
2598 | ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | ||
2599 | { | ||
2600 | struct ath5k_softc *sc = hw->priv; | ||
2601 | struct ath5k_hw *ah = sc->ah; | ||
2602 | struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); | ||
2603 | struct ath5k_txq *txq; | ||
2604 | u8 mac[ETH_ALEN] = {}; | ||
2605 | int ret; | ||
2606 | |||
2607 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); | ||
2608 | |||
2609 | /* | ||
2610 | * Check if the MAC has multi-rate retry support. | ||
2611 | * We do this by trying to setup a fake extended | ||
2612 | * descriptor. MACs that don't have support will | ||
2613 | * return false w/o doing anything. MACs that do | ||
2614 | * support it will return true w/o doing anything. | ||
2615 | */ | ||
2616 | ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); | ||
2617 | |||
2618 | if (ret < 0) | ||
2619 | goto err; | ||
2620 | if (ret > 0) | ||
2621 | __set_bit(ATH_STAT_MRRETRY, sc->status); | ||
2622 | |||
2623 | /* | ||
2624 | * Collect the channel list. The 802.11 layer | ||
2625 | * is resposible for filtering this list based | ||
2626 | * on settings like the phy mode and regulatory | ||
2627 | * domain restrictions. | ||
2628 | */ | ||
2629 | ret = ath5k_setup_bands(hw); | ||
2630 | if (ret) { | ||
2631 | ATH5K_ERR(sc, "can't get channels\n"); | ||
2632 | goto err; | ||
2633 | } | ||
2634 | |||
2635 | /* NB: setup here so ath5k_rate_update is happy */ | ||
2636 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) | ||
2637 | ath5k_setcurmode(sc, AR5K_MODE_11A); | ||
2638 | else | ||
2639 | ath5k_setcurmode(sc, AR5K_MODE_11B); | ||
2640 | |||
2641 | /* | ||
2642 | * Allocate tx+rx descriptors and populate the lists. | ||
2643 | */ | ||
2644 | ret = ath5k_desc_alloc(sc, pdev); | ||
2645 | if (ret) { | ||
2646 | ATH5K_ERR(sc, "can't allocate descriptors\n"); | ||
2647 | goto err; | ||
2648 | } | ||
2649 | |||
2650 | /* | ||
2651 | * Allocate hardware transmit queues: one queue for | ||
2652 | * beacon frames and one data queue for each QoS | ||
2653 | * priority. Note that hw functions handle resetting | ||
2654 | * these queues at the needed time. | ||
2655 | */ | ||
2656 | ret = ath5k_beaconq_setup(ah); | ||
2657 | if (ret < 0) { | ||
2658 | ATH5K_ERR(sc, "can't setup a beacon xmit queue\n"); | ||
2659 | goto err_desc; | ||
2660 | } | ||
2661 | sc->bhalq = ret; | ||
2662 | sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0); | ||
2663 | if (IS_ERR(sc->cabq)) { | ||
2664 | ATH5K_ERR(sc, "can't setup cab queue\n"); | ||
2665 | ret = PTR_ERR(sc->cabq); | ||
2666 | goto err_bhal; | ||
2667 | } | ||
2668 | |||
2669 | /* This order matches mac80211's queue priority, so we can | ||
2670 | * directly use the mac80211 queue number without any mapping */ | ||
2671 | txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO); | ||
2672 | if (IS_ERR(txq)) { | ||
2673 | ATH5K_ERR(sc, "can't setup xmit queue\n"); | ||
2674 | ret = PTR_ERR(txq); | ||
2675 | goto err_queues; | ||
2676 | } | ||
2677 | txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI); | ||
2678 | if (IS_ERR(txq)) { | ||
2679 | ATH5K_ERR(sc, "can't setup xmit queue\n"); | ||
2680 | ret = PTR_ERR(txq); | ||
2681 | goto err_queues; | ||
2682 | } | ||
2683 | txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE); | ||
2684 | if (IS_ERR(txq)) { | ||
2685 | ATH5K_ERR(sc, "can't setup xmit queue\n"); | ||
2686 | ret = PTR_ERR(txq); | ||
2687 | goto err_queues; | ||
2688 | } | ||
2689 | txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); | ||
2690 | if (IS_ERR(txq)) { | ||
2691 | ATH5K_ERR(sc, "can't setup xmit queue\n"); | ||
2692 | ret = PTR_ERR(txq); | ||
2693 | goto err_queues; | ||
2694 | } | ||
2695 | hw->queues = 4; | ||
2696 | |||
2697 | tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); | ||
2698 | tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); | ||
2699 | tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); | ||
2700 | tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); | ||
2701 | tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); | ||
2702 | |||
2703 | INIT_WORK(&sc->reset_work, ath5k_reset_work); | ||
2704 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); | ||
2705 | |||
2706 | ret = ath5k_eeprom_read_mac(ah, mac); | ||
2707 | if (ret) { | ||
2708 | ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", | ||
2709 | sc->pdev->device); | ||
2710 | goto err_queues; | ||
2711 | } | ||
2712 | |||
2713 | SET_IEEE80211_PERM_ADDR(hw, mac); | ||
2714 | memcpy(&sc->lladdr, mac, ETH_ALEN); | ||
2715 | /* All MAC address bits matter for ACKs */ | ||
2716 | ath5k_update_bssid_mask_and_opmode(sc, NULL); | ||
2717 | |||
2718 | regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; | ||
2719 | ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); | ||
2720 | if (ret) { | ||
2721 | ATH5K_ERR(sc, "can't initialize regulatory system\n"); | ||
2722 | goto err_queues; | ||
2723 | } | ||
2724 | |||
2725 | ret = ieee80211_register_hw(hw); | ||
2726 | if (ret) { | ||
2727 | ATH5K_ERR(sc, "can't register ieee80211 hw\n"); | ||
2728 | goto err_queues; | ||
2729 | } | ||
2730 | |||
2731 | if (!ath_is_world_regd(regulatory)) | ||
2732 | regulatory_hint(hw->wiphy, regulatory->alpha2); | ||
2733 | |||
2734 | ath5k_init_leds(sc); | ||
2735 | |||
2736 | ath5k_sysfs_register(sc); | ||
2737 | |||
2738 | return 0; | ||
2739 | err_queues: | ||
2740 | ath5k_txq_release(sc); | ||
2741 | err_bhal: | ||
2742 | ath5k_hw_release_tx_queue(ah, sc->bhalq); | ||
2743 | err_desc: | ||
2744 | ath5k_desc_free(sc, pdev); | ||
2745 | err: | ||
2746 | return ret; | ||
2747 | } | ||
2748 | |||
2749 | static void | ||
2750 | ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) | ||
2751 | { | ||
2752 | struct ath5k_softc *sc = hw->priv; | ||
2753 | |||
2754 | /* | ||
2755 | * NB: the order of these is important: | ||
2756 | * o call the 802.11 layer before detaching ath5k_hw to | ||
2757 | * ensure callbacks into the driver to delete global | ||
2758 | * key cache entries can be handled | ||
2759 | * o reclaim the tx queue data structures after calling | ||
2760 | * the 802.11 layer as we'll get called back to reclaim | ||
2761 | * node state and potentially want to use them | ||
2762 | * o to cleanup the tx queues the hal is called, so detach | ||
2763 | * it last | ||
2764 | * XXX: ??? detach ath5k_hw ??? | ||
2765 | * Other than that, it's straightforward... | ||
2766 | */ | ||
2767 | ieee80211_unregister_hw(hw); | ||
2768 | ath5k_desc_free(sc, pdev); | ||
2769 | ath5k_txq_release(sc); | ||
2770 | ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); | ||
2771 | ath5k_unregister_leds(sc); | ||
2772 | |||
2773 | ath5k_sysfs_unregister(sc); | ||
2774 | /* | ||
2775 | * NB: can't reclaim these until after ieee80211_ifdetach | ||
2776 | * returns because we'll get called back to reclaim node | ||
2777 | * state and potentially want to use them. | ||
2778 | */ | ||
2779 | } | ||
2780 | |||
2781 | /********************\ | ||
2782 | * Mac80211 functions * | ||
2783 | \********************/ | ||
2784 | |||
2785 | static int | ||
2786 | ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
2787 | { | ||
2788 | struct ath5k_softc *sc = hw->priv; | ||
2789 | u16 qnum = skb_get_queue_mapping(skb); | ||
2790 | |||
2791 | if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) { | ||
2792 | dev_kfree_skb_any(skb); | ||
2793 | return 0; | ||
2794 | } | ||
2795 | |||
2796 | return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]); | ||
2797 | } | ||
2798 | |||
3027 | static int ath5k_start(struct ieee80211_hw *hw) | 2799 | static int ath5k_start(struct ieee80211_hw *hw) |
3028 | { | 2800 | { |
3029 | return ath5k_init(hw->priv); | 2801 | return ath5k_init(hw->priv); |
@@ -3039,32 +2811,78 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
3039 | { | 2811 | { |
3040 | struct ath5k_softc *sc = hw->priv; | 2812 | struct ath5k_softc *sc = hw->priv; |
3041 | int ret; | 2813 | int ret; |
2814 | struct ath5k_vif *avf = (void *)vif->drv_priv; | ||
3042 | 2815 | ||
3043 | mutex_lock(&sc->lock); | 2816 | mutex_lock(&sc->lock); |
3044 | if (sc->vif) { | 2817 | |
3045 | ret = 0; | 2818 | if ((vif->type == NL80211_IFTYPE_AP || |
2819 | vif->type == NL80211_IFTYPE_ADHOC) | ||
2820 | && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) { | ||
2821 | ret = -ELNRNG; | ||
3046 | goto end; | 2822 | goto end; |
3047 | } | 2823 | } |
3048 | 2824 | ||
3049 | sc->vif = vif; | 2825 | /* Don't allow other interfaces if one ad-hoc is configured. |
2826 | * TODO: Fix the problems with ad-hoc and multiple other interfaces. | ||
2827 | * We would need to operate the HW in ad-hoc mode to allow TSF updates | ||
2828 | * for the IBSS, but this breaks with additional AP or STA interfaces | ||
2829 | * at the moment. */ | ||
2830 | if (sc->num_adhoc_vifs || | ||
2831 | (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { | ||
2832 | ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n"); | ||
2833 | ret = -ELNRNG; | ||
2834 | goto end; | ||
2835 | } | ||
3050 | 2836 | ||
3051 | switch (vif->type) { | 2837 | switch (vif->type) { |
3052 | case NL80211_IFTYPE_AP: | 2838 | case NL80211_IFTYPE_AP: |
3053 | case NL80211_IFTYPE_STATION: | 2839 | case NL80211_IFTYPE_STATION: |
3054 | case NL80211_IFTYPE_ADHOC: | 2840 | case NL80211_IFTYPE_ADHOC: |
3055 | case NL80211_IFTYPE_MESH_POINT: | 2841 | case NL80211_IFTYPE_MESH_POINT: |
3056 | case NL80211_IFTYPE_MONITOR: | 2842 | avf->opmode = vif->type; |
3057 | sc->opmode = vif->type; | ||
3058 | break; | 2843 | break; |
3059 | default: | 2844 | default: |
3060 | ret = -EOPNOTSUPP; | 2845 | ret = -EOPNOTSUPP; |
3061 | goto end; | 2846 | goto end; |
3062 | } | 2847 | } |
3063 | 2848 | ||
3064 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode); | 2849 | sc->nvifs++; |
2850 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode); | ||
2851 | |||
2852 | /* Assign the vap/adhoc to a beacon xmit slot. */ | ||
2853 | if ((avf->opmode == NL80211_IFTYPE_AP) || | ||
2854 | (avf->opmode == NL80211_IFTYPE_ADHOC)) { | ||
2855 | int slot; | ||
3065 | 2856 | ||
2857 | WARN_ON(list_empty(&sc->bcbuf)); | ||
2858 | avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf, | ||
2859 | list); | ||
2860 | list_del(&avf->bbuf->list); | ||
2861 | |||
2862 | avf->bslot = 0; | ||
2863 | for (slot = 0; slot < ATH_BCBUF; slot++) { | ||
2864 | if (!sc->bslot[slot]) { | ||
2865 | avf->bslot = slot; | ||
2866 | break; | ||
2867 | } | ||
2868 | } | ||
2869 | BUG_ON(sc->bslot[avf->bslot] != NULL); | ||
2870 | sc->bslot[avf->bslot] = vif; | ||
2871 | if (avf->opmode == NL80211_IFTYPE_AP) | ||
2872 | sc->num_ap_vifs++; | ||
2873 | else | ||
2874 | sc->num_adhoc_vifs++; | ||
2875 | } | ||
2876 | |||
2877 | /* Any MAC address is fine, all others are included through the | ||
2878 | * filter. | ||
2879 | */ | ||
2880 | memcpy(&sc->lladdr, vif->addr, ETH_ALEN); | ||
3066 | ath5k_hw_set_lladdr(sc->ah, vif->addr); | 2881 | ath5k_hw_set_lladdr(sc->ah, vif->addr); |
3067 | ath5k_mode_setup(sc); | 2882 | |
2883 | memcpy(&avf->lladdr, vif->addr, ETH_ALEN); | ||
2884 | |||
2885 | ath5k_mode_setup(sc, vif); | ||
3068 | 2886 | ||
3069 | ret = 0; | 2887 | ret = 0; |
3070 | end: | 2888 | end: |
@@ -3077,15 +2895,29 @@ ath5k_remove_interface(struct ieee80211_hw *hw, | |||
3077 | struct ieee80211_vif *vif) | 2895 | struct ieee80211_vif *vif) |
3078 | { | 2896 | { |
3079 | struct ath5k_softc *sc = hw->priv; | 2897 | struct ath5k_softc *sc = hw->priv; |
3080 | u8 mac[ETH_ALEN] = {}; | 2898 | struct ath5k_vif *avf = (void *)vif->drv_priv; |
2899 | unsigned int i; | ||
3081 | 2900 | ||
3082 | mutex_lock(&sc->lock); | 2901 | mutex_lock(&sc->lock); |
3083 | if (sc->vif != vif) | 2902 | sc->nvifs--; |
3084 | goto end; | 2903 | |
2904 | if (avf->bbuf) { | ||
2905 | ath5k_txbuf_free_skb(sc, avf->bbuf); | ||
2906 | list_add_tail(&avf->bbuf->list, &sc->bcbuf); | ||
2907 | for (i = 0; i < ATH_BCBUF; i++) { | ||
2908 | if (sc->bslot[i] == vif) { | ||
2909 | sc->bslot[i] = NULL; | ||
2910 | break; | ||
2911 | } | ||
2912 | } | ||
2913 | avf->bbuf = NULL; | ||
2914 | } | ||
2915 | if (avf->opmode == NL80211_IFTYPE_AP) | ||
2916 | sc->num_ap_vifs--; | ||
2917 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) | ||
2918 | sc->num_adhoc_vifs--; | ||
3085 | 2919 | ||
3086 | ath5k_hw_set_lladdr(sc->ah, mac); | 2920 | ath5k_update_bssid_mask_and_opmode(sc, NULL); |
3087 | sc->vif = NULL; | ||
3088 | end: | ||
3089 | mutex_unlock(&sc->lock); | 2921 | mutex_unlock(&sc->lock); |
3090 | } | 2922 | } |
3091 | 2923 | ||
@@ -3168,6 +3000,19 @@ static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, | |||
3168 | return ((u64)(mfilt[1]) << 32) | mfilt[0]; | 3000 | return ((u64)(mfilt[1]) << 32) | mfilt[0]; |
3169 | } | 3001 | } |
3170 | 3002 | ||
3003 | static bool ath_any_vif_assoc(struct ath5k_softc *sc) | ||
3004 | { | ||
3005 | struct ath_vif_iter_data iter_data; | ||
3006 | iter_data.hw_macaddr = NULL; | ||
3007 | iter_data.any_assoc = false; | ||
3008 | iter_data.need_set_hw_addr = false; | ||
3009 | iter_data.found_active = true; | ||
3010 | |||
3011 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, | ||
3012 | &iter_data); | ||
3013 | return iter_data.any_assoc; | ||
3014 | } | ||
3015 | |||
3171 | #define SUPPORTED_FIF_FLAGS \ | 3016 | #define SUPPORTED_FIF_FLAGS \ |
3172 | FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ | 3017 | FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ |
3173 | FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ | 3018 | FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ |
@@ -3237,9 +3082,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
3237 | rfilt |= AR5K_RX_FILTER_PHYERR; | 3082 | rfilt |= AR5K_RX_FILTER_PHYERR; |
3238 | 3083 | ||
3239 | /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons | 3084 | /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons |
3240 | * and probes for any BSSID, this needs testing */ | 3085 | * and probes for any BSSID */ |
3241 | if (*new_flags & FIF_BCN_PRBRESP_PROMISC) | 3086 | if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1)) |
3242 | rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ; | 3087 | rfilt |= AR5K_RX_FILTER_BEACON; |
3243 | 3088 | ||
3244 | /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not | 3089 | /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not |
3245 | * set we should only pass on control frames for this | 3090 | * set we should only pass on control frames for this |
@@ -3255,7 +3100,6 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
3255 | 3100 | ||
3256 | switch (sc->opmode) { | 3101 | switch (sc->opmode) { |
3257 | case NL80211_IFTYPE_MESH_POINT: | 3102 | case NL80211_IFTYPE_MESH_POINT: |
3258 | case NL80211_IFTYPE_MONITOR: | ||
3259 | rfilt |= AR5K_RX_FILTER_CONTROL | | 3103 | rfilt |= AR5K_RX_FILTER_CONTROL | |
3260 | AR5K_RX_FILTER_BEACON | | 3104 | AR5K_RX_FILTER_BEACON | |
3261 | AR5K_RX_FILTER_PROBEREQ | | 3105 | AR5K_RX_FILTER_PROBEREQ | |
@@ -3278,7 +3122,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
3278 | 3122 | ||
3279 | /* Set multicast bits */ | 3123 | /* Set multicast bits */ |
3280 | ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); | 3124 | ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); |
3281 | /* Set the cached hw filter flags, this will alter actually | 3125 | /* Set the cached hw filter flags, this will later actually |
3282 | * be set in HW */ | 3126 | * be set in HW */ |
3283 | sc->filter_flags = rfilt; | 3127 | sc->filter_flags = rfilt; |
3284 | 3128 | ||
@@ -3298,17 +3142,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3298 | if (modparam_nohwcrypt) | 3142 | if (modparam_nohwcrypt) |
3299 | return -EOPNOTSUPP; | 3143 | return -EOPNOTSUPP; |
3300 | 3144 | ||
3301 | if (sc->opmode == NL80211_IFTYPE_AP) | 3145 | switch (key->cipher) { |
3302 | return -EOPNOTSUPP; | 3146 | case WLAN_CIPHER_SUITE_WEP40: |
3303 | 3147 | case WLAN_CIPHER_SUITE_WEP104: | |
3304 | switch (key->alg) { | 3148 | case WLAN_CIPHER_SUITE_TKIP: |
3305 | case ALG_WEP: | ||
3306 | case ALG_TKIP: | ||
3307 | break; | 3149 | break; |
3308 | case ALG_CCMP: | 3150 | case WLAN_CIPHER_SUITE_CCMP: |
3309 | if (sc->ah->ah_aes_support) | 3151 | if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM) |
3310 | break; | 3152 | break; |
3311 | |||
3312 | return -EOPNOTSUPP; | 3153 | return -EOPNOTSUPP; |
3313 | default: | 3154 | default: |
3314 | WARN_ON(1); | 3155 | WARN_ON(1); |
@@ -3319,27 +3160,25 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3319 | 3160 | ||
3320 | switch (cmd) { | 3161 | switch (cmd) { |
3321 | case SET_KEY: | 3162 | case SET_KEY: |
3322 | ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, | 3163 | ret = ath_key_config(common, vif, sta, key); |
3323 | sta ? sta->addr : NULL); | 3164 | if (ret >= 0) { |
3324 | if (ret) { | 3165 | key->hw_key_idx = ret; |
3325 | ATH5K_ERR(sc, "can't set the key\n"); | 3166 | /* push IV and Michael MIC generation to stack */ |
3326 | goto unlock; | 3167 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
3168 | if (key->cipher == WLAN_CIPHER_SUITE_TKIP) | ||
3169 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
3170 | if (key->cipher == WLAN_CIPHER_SUITE_CCMP) | ||
3171 | key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; | ||
3172 | ret = 0; | ||
3327 | } | 3173 | } |
3328 | __set_bit(key->keyidx, common->keymap); | ||
3329 | key->hw_key_idx = key->keyidx; | ||
3330 | key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV | | ||
3331 | IEEE80211_KEY_FLAG_GENERATE_MMIC); | ||
3332 | break; | 3174 | break; |
3333 | case DISABLE_KEY: | 3175 | case DISABLE_KEY: |
3334 | ath5k_hw_reset_key(sc->ah, key->keyidx); | 3176 | ath_key_delete(common, key); |
3335 | __clear_bit(key->keyidx, common->keymap); | ||
3336 | break; | 3177 | break; |
3337 | default: | 3178 | default: |
3338 | ret = -EINVAL; | 3179 | ret = -EINVAL; |
3339 | goto unlock; | ||
3340 | } | 3180 | } |
3341 | 3181 | ||
3342 | unlock: | ||
3343 | mmiowb(); | 3182 | mmiowb(); |
3344 | mutex_unlock(&sc->lock); | 3183 | mutex_unlock(&sc->lock); |
3345 | return ret; | 3184 | return ret; |
@@ -3409,43 +3248,6 @@ ath5k_reset_tsf(struct ieee80211_hw *hw) | |||
3409 | ath5k_hw_reset_tsf(sc->ah); | 3248 | ath5k_hw_reset_tsf(sc->ah); |
3410 | } | 3249 | } |
3411 | 3250 | ||
3412 | /* | ||
3413 | * Updates the beacon that is sent by ath5k_beacon_send. For adhoc, | ||
3414 | * this is called only once at config_bss time, for AP we do it every | ||
3415 | * SWBA interrupt so that the TIM will reflect buffered frames. | ||
3416 | * | ||
3417 | * Called with the beacon lock. | ||
3418 | */ | ||
3419 | static int | ||
3420 | ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | ||
3421 | { | ||
3422 | int ret; | ||
3423 | struct ath5k_softc *sc = hw->priv; | ||
3424 | struct sk_buff *skb; | ||
3425 | |||
3426 | if (WARN_ON(!vif)) { | ||
3427 | ret = -EINVAL; | ||
3428 | goto out; | ||
3429 | } | ||
3430 | |||
3431 | skb = ieee80211_beacon_get(hw, vif); | ||
3432 | |||
3433 | if (!skb) { | ||
3434 | ret = -ENOMEM; | ||
3435 | goto out; | ||
3436 | } | ||
3437 | |||
3438 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); | ||
3439 | |||
3440 | ath5k_txbuf_free_skb(sc, sc->bbuf); | ||
3441 | sc->bbuf->skb = skb; | ||
3442 | ret = ath5k_beacon_setup(sc, sc->bbuf); | ||
3443 | if (ret) | ||
3444 | sc->bbuf->skb = NULL; | ||
3445 | out: | ||
3446 | return ret; | ||
3447 | } | ||
3448 | |||
3449 | static void | 3251 | static void |
3450 | set_beacon_filter(struct ieee80211_hw *hw, bool enable) | 3252 | set_beacon_filter(struct ieee80211_hw *hw, bool enable) |
3451 | { | 3253 | { |
@@ -3466,20 +3268,19 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | |||
3466 | struct ieee80211_bss_conf *bss_conf, | 3268 | struct ieee80211_bss_conf *bss_conf, |
3467 | u32 changes) | 3269 | u32 changes) |
3468 | { | 3270 | { |
3271 | struct ath5k_vif *avf = (void *)vif->drv_priv; | ||
3469 | struct ath5k_softc *sc = hw->priv; | 3272 | struct ath5k_softc *sc = hw->priv; |
3470 | struct ath5k_hw *ah = sc->ah; | 3273 | struct ath5k_hw *ah = sc->ah; |
3471 | struct ath_common *common = ath5k_hw_common(ah); | 3274 | struct ath_common *common = ath5k_hw_common(ah); |
3472 | unsigned long flags; | 3275 | unsigned long flags; |
3473 | 3276 | ||
3474 | mutex_lock(&sc->lock); | 3277 | mutex_lock(&sc->lock); |
3475 | if (WARN_ON(sc->vif != vif)) | ||
3476 | goto unlock; | ||
3477 | 3278 | ||
3478 | if (changes & BSS_CHANGED_BSSID) { | 3279 | if (changes & BSS_CHANGED_BSSID) { |
3479 | /* Cache for later use during resets */ | 3280 | /* Cache for later use during resets */ |
3480 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | 3281 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
3481 | common->curaid = 0; | 3282 | common->curaid = 0; |
3482 | ath5k_hw_set_associd(ah); | 3283 | ath5k_hw_set_bssid(ah); |
3483 | mmiowb(); | 3284 | mmiowb(); |
3484 | } | 3285 | } |
3485 | 3286 | ||
@@ -3487,7 +3288,12 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | |||
3487 | sc->bintval = bss_conf->beacon_int; | 3288 | sc->bintval = bss_conf->beacon_int; |
3488 | 3289 | ||
3489 | if (changes & BSS_CHANGED_ASSOC) { | 3290 | if (changes & BSS_CHANGED_ASSOC) { |
3490 | sc->assoc = bss_conf->assoc; | 3291 | avf->assoc = bss_conf->assoc; |
3292 | if (bss_conf->assoc) | ||
3293 | sc->assoc = bss_conf->assoc; | ||
3294 | else | ||
3295 | sc->assoc = ath_any_vif_assoc(sc); | ||
3296 | |||
3491 | if (sc->opmode == NL80211_IFTYPE_STATION) | 3297 | if (sc->opmode == NL80211_IFTYPE_STATION) |
3492 | set_beacon_filter(hw, sc->assoc); | 3298 | set_beacon_filter(hw, sc->assoc); |
3493 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? | 3299 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? |
@@ -3497,7 +3303,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | |||
3497 | "Bss Info ASSOC %d, bssid: %pM\n", | 3303 | "Bss Info ASSOC %d, bssid: %pM\n", |
3498 | bss_conf->aid, common->curbssid); | 3304 | bss_conf->aid, common->curbssid); |
3499 | common->curaid = bss_conf->aid; | 3305 | common->curaid = bss_conf->aid; |
3500 | ath5k_hw_set_associd(ah); | 3306 | ath5k_hw_set_bssid(ah); |
3501 | /* Once ANI is available you would start it here */ | 3307 | /* Once ANI is available you would start it here */ |
3502 | } | 3308 | } |
3503 | } | 3309 | } |
@@ -3515,7 +3321,6 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | |||
3515 | BSS_CHANGED_BEACON_INT)) | 3321 | BSS_CHANGED_BEACON_INT)) |
3516 | ath5k_beacon_config(sc); | 3322 | ath5k_beacon_config(sc); |
3517 | 3323 | ||
3518 | unlock: | ||
3519 | mutex_unlock(&sc->lock); | 3324 | mutex_unlock(&sc->lock); |
3520 | } | 3325 | } |
3521 | 3326 | ||
@@ -3551,3 +3356,399 @@ static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | |||
3551 | ath5k_hw_set_coverage_class(sc->ah, coverage_class); | 3356 | ath5k_hw_set_coverage_class(sc->ah, coverage_class); |
3552 | mutex_unlock(&sc->lock); | 3357 | mutex_unlock(&sc->lock); |
3553 | } | 3358 | } |
3359 | |||
3360 | static int ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue, | ||
3361 | const struct ieee80211_tx_queue_params *params) | ||
3362 | { | ||
3363 | struct ath5k_softc *sc = hw->priv; | ||
3364 | struct ath5k_hw *ah = sc->ah; | ||
3365 | struct ath5k_txq_info qi; | ||
3366 | int ret = 0; | ||
3367 | |||
3368 | if (queue >= ah->ah_capabilities.cap_queues.q_tx_num) | ||
3369 | return 0; | ||
3370 | |||
3371 | mutex_lock(&sc->lock); | ||
3372 | |||
3373 | ath5k_hw_get_tx_queueprops(ah, queue, &qi); | ||
3374 | |||
3375 | qi.tqi_aifs = params->aifs; | ||
3376 | qi.tqi_cw_min = params->cw_min; | ||
3377 | qi.tqi_cw_max = params->cw_max; | ||
3378 | qi.tqi_burst_time = params->txop; | ||
3379 | |||
3380 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, | ||
3381 | "Configure tx [queue %d], " | ||
3382 | "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", | ||
3383 | queue, params->aifs, params->cw_min, | ||
3384 | params->cw_max, params->txop); | ||
3385 | |||
3386 | if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) { | ||
3387 | ATH5K_ERR(sc, | ||
3388 | "Unable to update hardware queue %u!\n", queue); | ||
3389 | ret = -EIO; | ||
3390 | } else | ||
3391 | ath5k_hw_reset_tx_queue(ah, queue); | ||
3392 | |||
3393 | mutex_unlock(&sc->lock); | ||
3394 | |||
3395 | return ret; | ||
3396 | } | ||
3397 | |||
3398 | static const struct ieee80211_ops ath5k_hw_ops = { | ||
3399 | .tx = ath5k_tx, | ||
3400 | .start = ath5k_start, | ||
3401 | .stop = ath5k_stop, | ||
3402 | .add_interface = ath5k_add_interface, | ||
3403 | .remove_interface = ath5k_remove_interface, | ||
3404 | .config = ath5k_config, | ||
3405 | .prepare_multicast = ath5k_prepare_multicast, | ||
3406 | .configure_filter = ath5k_configure_filter, | ||
3407 | .set_key = ath5k_set_key, | ||
3408 | .get_stats = ath5k_get_stats, | ||
3409 | .get_survey = ath5k_get_survey, | ||
3410 | .conf_tx = ath5k_conf_tx, | ||
3411 | .get_tsf = ath5k_get_tsf, | ||
3412 | .set_tsf = ath5k_set_tsf, | ||
3413 | .reset_tsf = ath5k_reset_tsf, | ||
3414 | .bss_info_changed = ath5k_bss_info_changed, | ||
3415 | .sw_scan_start = ath5k_sw_scan_start, | ||
3416 | .sw_scan_complete = ath5k_sw_scan_complete, | ||
3417 | .set_coverage_class = ath5k_set_coverage_class, | ||
3418 | }; | ||
3419 | |||
3420 | /********************\ | ||
3421 | * PCI Initialization * | ||
3422 | \********************/ | ||
3423 | |||
3424 | static int __devinit | ||
3425 | ath5k_pci_probe(struct pci_dev *pdev, | ||
3426 | const struct pci_device_id *id) | ||
3427 | { | ||
3428 | void __iomem *mem; | ||
3429 | struct ath5k_softc *sc; | ||
3430 | struct ath_common *common; | ||
3431 | struct ieee80211_hw *hw; | ||
3432 | int ret; | ||
3433 | u8 csz; | ||
3434 | |||
3435 | /* | ||
3436 | * L0s needs to be disabled on all ath5k cards. | ||
3437 | * | ||
3438 | * For distributions shipping with CONFIG_PCIEASPM (this will be enabled | ||
3439 | * by default in the future in 2.6.36) this will also mean both L1 and | ||
3440 | * L0s will be disabled when a pre 1.1 PCIe device is detected. We do | ||
3441 | * know L1 works correctly even for all ath5k pre 1.1 PCIe devices | ||
3442 | * though but cannot currently undue the effect of a blacklist, for | ||
3443 | * details you can read pcie_aspm_sanity_check() and see how it adjusts | ||
3444 | * the device link capability. | ||
3445 | * | ||
3446 | * It may be possible in the future to implement some PCI API to allow | ||
3447 | * drivers to override blacklists for pre 1.1 PCIe but for now it is | ||
3448 | * best to accept that both L0s and L1 will be disabled completely for | ||
3449 | * distributions shipping with CONFIG_PCIEASPM rather than having this | ||
3450 | * issue present. Motivation for adding this new API will be to help | ||
3451 | * with power consumption for some of these devices. | ||
3452 | */ | ||
3453 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); | ||
3454 | |||
3455 | ret = pci_enable_device(pdev); | ||
3456 | if (ret) { | ||
3457 | dev_err(&pdev->dev, "can't enable device\n"); | ||
3458 | goto err; | ||
3459 | } | ||
3460 | |||
3461 | /* XXX 32-bit addressing only */ | ||
3462 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
3463 | if (ret) { | ||
3464 | dev_err(&pdev->dev, "32-bit DMA not available\n"); | ||
3465 | goto err_dis; | ||
3466 | } | ||
3467 | |||
3468 | /* | ||
3469 | * Cache line size is used to size and align various | ||
3470 | * structures used to communicate with the hardware. | ||
3471 | */ | ||
3472 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); | ||
3473 | if (csz == 0) { | ||
3474 | /* | ||
3475 | * Linux 2.4.18 (at least) writes the cache line size | ||
3476 | * register as a 16-bit wide register which is wrong. | ||
3477 | * We must have this setup properly for rx buffer | ||
3478 | * DMA to work so force a reasonable value here if it | ||
3479 | * comes up zero. | ||
3480 | */ | ||
3481 | csz = L1_CACHE_BYTES >> 2; | ||
3482 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); | ||
3483 | } | ||
3484 | /* | ||
3485 | * The default setting of latency timer yields poor results, | ||
3486 | * set it to the value used by other systems. It may be worth | ||
3487 | * tweaking this setting more. | ||
3488 | */ | ||
3489 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); | ||
3490 | |||
3491 | /* Enable bus mastering */ | ||
3492 | pci_set_master(pdev); | ||
3493 | |||
3494 | /* | ||
3495 | * Disable the RETRY_TIMEOUT register (0x41) to keep | ||
3496 | * PCI Tx retries from interfering with C3 CPU state. | ||
3497 | */ | ||
3498 | pci_write_config_byte(pdev, 0x41, 0); | ||
3499 | |||
3500 | ret = pci_request_region(pdev, 0, "ath5k"); | ||
3501 | if (ret) { | ||
3502 | dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); | ||
3503 | goto err_dis; | ||
3504 | } | ||
3505 | |||
3506 | mem = pci_iomap(pdev, 0, 0); | ||
3507 | if (!mem) { | ||
3508 | dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; | ||
3509 | ret = -EIO; | ||
3510 | goto err_reg; | ||
3511 | } | ||
3512 | |||
3513 | /* | ||
3514 | * Allocate hw (mac80211 main struct) | ||
3515 | * and hw->priv (driver private data) | ||
3516 | */ | ||
3517 | hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops); | ||
3518 | if (hw == NULL) { | ||
3519 | dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); | ||
3520 | ret = -ENOMEM; | ||
3521 | goto err_map; | ||
3522 | } | ||
3523 | |||
3524 | dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); | ||
3525 | |||
3526 | /* Initialize driver private data */ | ||
3527 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
3528 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
3529 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
3530 | IEEE80211_HW_SIGNAL_DBM; | ||
3531 | |||
3532 | hw->wiphy->interface_modes = | ||
3533 | BIT(NL80211_IFTYPE_AP) | | ||
3534 | BIT(NL80211_IFTYPE_STATION) | | ||
3535 | BIT(NL80211_IFTYPE_ADHOC) | | ||
3536 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
3537 | |||
3538 | hw->extra_tx_headroom = 2; | ||
3539 | hw->channel_change_time = 5000; | ||
3540 | sc = hw->priv; | ||
3541 | sc->hw = hw; | ||
3542 | sc->pdev = pdev; | ||
3543 | |||
3544 | /* | ||
3545 | * Mark the device as detached to avoid processing | ||
3546 | * interrupts until setup is complete. | ||
3547 | */ | ||
3548 | __set_bit(ATH_STAT_INVALID, sc->status); | ||
3549 | |||
3550 | sc->iobase = mem; /* So we can unmap it on detach */ | ||
3551 | sc->opmode = NL80211_IFTYPE_STATION; | ||
3552 | sc->bintval = 1000; | ||
3553 | mutex_init(&sc->lock); | ||
3554 | spin_lock_init(&sc->rxbuflock); | ||
3555 | spin_lock_init(&sc->txbuflock); | ||
3556 | spin_lock_init(&sc->block); | ||
3557 | |||
3558 | /* Set private data */ | ||
3559 | pci_set_drvdata(pdev, sc); | ||
3560 | |||
3561 | /* Setup interrupt handler */ | ||
3562 | ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); | ||
3563 | if (ret) { | ||
3564 | ATH5K_ERR(sc, "request_irq failed\n"); | ||
3565 | goto err_free; | ||
3566 | } | ||
3567 | |||
3568 | /* If we passed the test, malloc an ath5k_hw struct */ | ||
3569 | sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); | ||
3570 | if (!sc->ah) { | ||
3571 | ret = -ENOMEM; | ||
3572 | ATH5K_ERR(sc, "out of memory\n"); | ||
3573 | goto err_irq; | ||
3574 | } | ||
3575 | |||
3576 | sc->ah->ah_sc = sc; | ||
3577 | sc->ah->ah_iobase = sc->iobase; | ||
3578 | common = ath5k_hw_common(sc->ah); | ||
3579 | common->ops = &ath5k_common_ops; | ||
3580 | common->ah = sc->ah; | ||
3581 | common->hw = hw; | ||
3582 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
3583 | |||
3584 | /* Initialize device */ | ||
3585 | ret = ath5k_hw_attach(sc); | ||
3586 | if (ret) { | ||
3587 | goto err_free_ah; | ||
3588 | } | ||
3589 | |||
3590 | /* set up multi-rate retry capabilities */ | ||
3591 | if (sc->ah->ah_version == AR5K_AR5212) { | ||
3592 | hw->max_rates = 4; | ||
3593 | hw->max_rate_tries = 11; | ||
3594 | } | ||
3595 | |||
3596 | hw->vif_data_size = sizeof(struct ath5k_vif); | ||
3597 | |||
3598 | /* Finish private driver data initialization */ | ||
3599 | ret = ath5k_attach(pdev, hw); | ||
3600 | if (ret) | ||
3601 | goto err_ah; | ||
3602 | |||
3603 | ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", | ||
3604 | ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), | ||
3605 | sc->ah->ah_mac_srev, | ||
3606 | sc->ah->ah_phy_revision); | ||
3607 | |||
3608 | if (!sc->ah->ah_single_chip) { | ||
3609 | /* Single chip radio (!RF5111) */ | ||
3610 | if (sc->ah->ah_radio_5ghz_revision && | ||
3611 | !sc->ah->ah_radio_2ghz_revision) { | ||
3612 | /* No 5GHz support -> report 2GHz radio */ | ||
3613 | if (!test_bit(AR5K_MODE_11A, | ||
3614 | sc->ah->ah_capabilities.cap_mode)) { | ||
3615 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
3616 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
3617 | sc->ah->ah_radio_5ghz_revision), | ||
3618 | sc->ah->ah_radio_5ghz_revision); | ||
3619 | /* No 2GHz support (5110 and some | ||
3620 | * 5Ghz only cards) -> report 5Ghz radio */ | ||
3621 | } else if (!test_bit(AR5K_MODE_11B, | ||
3622 | sc->ah->ah_capabilities.cap_mode)) { | ||
3623 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
3624 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
3625 | sc->ah->ah_radio_5ghz_revision), | ||
3626 | sc->ah->ah_radio_5ghz_revision); | ||
3627 | /* Multiband radio */ | ||
3628 | } else { | ||
3629 | ATH5K_INFO(sc, "RF%s multiband radio found" | ||
3630 | " (0x%x)\n", | ||
3631 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
3632 | sc->ah->ah_radio_5ghz_revision), | ||
3633 | sc->ah->ah_radio_5ghz_revision); | ||
3634 | } | ||
3635 | } | ||
3636 | /* Multi chip radio (RF5111 - RF2111) -> | ||
3637 | * report both 2GHz/5GHz radios */ | ||
3638 | else if (sc->ah->ah_radio_5ghz_revision && | ||
3639 | sc->ah->ah_radio_2ghz_revision){ | ||
3640 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
3641 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
3642 | sc->ah->ah_radio_5ghz_revision), | ||
3643 | sc->ah->ah_radio_5ghz_revision); | ||
3644 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
3645 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
3646 | sc->ah->ah_radio_2ghz_revision), | ||
3647 | sc->ah->ah_radio_2ghz_revision); | ||
3648 | } | ||
3649 | } | ||
3650 | |||
3651 | ath5k_debug_init_device(sc); | ||
3652 | |||
3653 | /* ready to process interrupts */ | ||
3654 | __clear_bit(ATH_STAT_INVALID, sc->status); | ||
3655 | |||
3656 | return 0; | ||
3657 | err_ah: | ||
3658 | ath5k_hw_detach(sc->ah); | ||
3659 | err_free_ah: | ||
3660 | kfree(sc->ah); | ||
3661 | err_irq: | ||
3662 | free_irq(pdev->irq, sc); | ||
3663 | err_free: | ||
3664 | ieee80211_free_hw(hw); | ||
3665 | err_map: | ||
3666 | pci_iounmap(pdev, mem); | ||
3667 | err_reg: | ||
3668 | pci_release_region(pdev, 0); | ||
3669 | err_dis: | ||
3670 | pci_disable_device(pdev); | ||
3671 | err: | ||
3672 | return ret; | ||
3673 | } | ||
3674 | |||
3675 | static void __devexit | ||
3676 | ath5k_pci_remove(struct pci_dev *pdev) | ||
3677 | { | ||
3678 | struct ath5k_softc *sc = pci_get_drvdata(pdev); | ||
3679 | |||
3680 | ath5k_debug_finish_device(sc); | ||
3681 | ath5k_detach(pdev, sc->hw); | ||
3682 | ath5k_hw_detach(sc->ah); | ||
3683 | kfree(sc->ah); | ||
3684 | free_irq(pdev->irq, sc); | ||
3685 | pci_iounmap(pdev, sc->iobase); | ||
3686 | pci_release_region(pdev, 0); | ||
3687 | pci_disable_device(pdev); | ||
3688 | ieee80211_free_hw(sc->hw); | ||
3689 | } | ||
3690 | |||
3691 | #ifdef CONFIG_PM_SLEEP | ||
3692 | static int ath5k_pci_suspend(struct device *dev) | ||
3693 | { | ||
3694 | struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); | ||
3695 | |||
3696 | ath5k_led_off(sc); | ||
3697 | return 0; | ||
3698 | } | ||
3699 | |||
3700 | static int ath5k_pci_resume(struct device *dev) | ||
3701 | { | ||
3702 | struct pci_dev *pdev = to_pci_dev(dev); | ||
3703 | struct ath5k_softc *sc = pci_get_drvdata(pdev); | ||
3704 | |||
3705 | /* | ||
3706 | * Suspend/Resume resets the PCI configuration space, so we have to | ||
3707 | * re-disable the RETRY_TIMEOUT register (0x41) to keep | ||
3708 | * PCI Tx retries from interfering with C3 CPU state | ||
3709 | */ | ||
3710 | pci_write_config_byte(pdev, 0x41, 0); | ||
3711 | |||
3712 | ath5k_led_enable(sc); | ||
3713 | return 0; | ||
3714 | } | ||
3715 | |||
3716 | static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); | ||
3717 | #define ATH5K_PM_OPS (&ath5k_pm_ops) | ||
3718 | #else | ||
3719 | #define ATH5K_PM_OPS NULL | ||
3720 | #endif /* CONFIG_PM_SLEEP */ | ||
3721 | |||
3722 | static struct pci_driver ath5k_pci_driver = { | ||
3723 | .name = KBUILD_MODNAME, | ||
3724 | .id_table = ath5k_pci_id_table, | ||
3725 | .probe = ath5k_pci_probe, | ||
3726 | .remove = __devexit_p(ath5k_pci_remove), | ||
3727 | .driver.pm = ATH5K_PM_OPS, | ||
3728 | }; | ||
3729 | |||
3730 | /* | ||
3731 | * Module init/exit functions | ||
3732 | */ | ||
3733 | static int __init | ||
3734 | init_ath5k_pci(void) | ||
3735 | { | ||
3736 | int ret; | ||
3737 | |||
3738 | ret = pci_register_driver(&ath5k_pci_driver); | ||
3739 | if (ret) { | ||
3740 | printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); | ||
3741 | return ret; | ||
3742 | } | ||
3743 | |||
3744 | return 0; | ||
3745 | } | ||
3746 | |||
3747 | static void __exit | ||
3748 | exit_ath5k_pci(void) | ||
3749 | { | ||
3750 | pci_unregister_driver(&ath5k_pci_driver); | ||
3751 | } | ||
3752 | |||
3753 | module_init(init_ath5k_pci); | ||
3754 | module_exit(exit_ath5k_pci); | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index dc1241f9c4e8..9a79773cdc2a 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -58,7 +58,9 @@ | |||
58 | 58 | ||
59 | #define ATH_RXBUF 40 /* number of RX buffers */ | 59 | #define ATH_RXBUF 40 /* number of RX buffers */ |
60 | #define ATH_TXBUF 200 /* number of TX buffers */ | 60 | #define ATH_TXBUF 200 /* number of TX buffers */ |
61 | #define ATH_BCBUF 1 /* number of beacon buffers */ | 61 | #define ATH_BCBUF 4 /* number of beacon buffers */ |
62 | #define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */ | ||
63 | #define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */ | ||
62 | 64 | ||
63 | struct ath5k_buf { | 65 | struct ath5k_buf { |
64 | struct list_head list; | 66 | struct list_head list; |
@@ -83,6 +85,9 @@ struct ath5k_txq { | |||
83 | struct list_head q; /* transmit queue */ | 85 | struct list_head q; /* transmit queue */ |
84 | spinlock_t lock; /* lock on q and link */ | 86 | spinlock_t lock; /* lock on q and link */ |
85 | bool setup; | 87 | bool setup; |
88 | int txq_len; /* number of queued buffers */ | ||
89 | bool txq_poll_mark; | ||
90 | unsigned int txq_stuck; /* informational counter */ | ||
86 | }; | 91 | }; |
87 | 92 | ||
88 | #define ATH5K_LED_MAX_NAME_LEN 31 | 93 | #define ATH5K_LED_MAX_NAME_LEN 31 |
@@ -116,6 +121,13 @@ struct ath5k_statistics { | |||
116 | /* frame errors */ | 121 | /* frame errors */ |
117 | unsigned int rx_all_count; /* all RX frames, including errors */ | 122 | unsigned int rx_all_count; /* all RX frames, including errors */ |
118 | unsigned int tx_all_count; /* all TX frames, including errors */ | 123 | unsigned int tx_all_count; /* all TX frames, including errors */ |
124 | unsigned int rx_bytes_count; /* all RX bytes, including errored pks | ||
125 | * and the MAC headers for each packet | ||
126 | */ | ||
127 | unsigned int tx_bytes_count; /* all TX bytes, including errored pkts | ||
128 | * and the MAC headers and padding for | ||
129 | * each packet. | ||
130 | */ | ||
119 | unsigned int rxerr_crc; | 131 | unsigned int rxerr_crc; |
120 | unsigned int rxerr_phy; | 132 | unsigned int rxerr_phy; |
121 | unsigned int rxerr_phy_code[32]; | 133 | unsigned int rxerr_phy_code[32]; |
@@ -146,6 +158,14 @@ struct ath5k_statistics { | |||
146 | #define ATH_CHAN_MAX (14+14+14+252+20) | 158 | #define ATH_CHAN_MAX (14+14+14+252+20) |
147 | #endif | 159 | #endif |
148 | 160 | ||
161 | struct ath5k_vif { | ||
162 | bool assoc; /* are we associated or not */ | ||
163 | enum nl80211_iftype opmode; | ||
164 | int bslot; | ||
165 | struct ath5k_buf *bbuf; /* beacon buffer */ | ||
166 | u8 lladdr[ETH_ALEN]; | ||
167 | }; | ||
168 | |||
149 | /* Software Carrier, keeps track of the driver state | 169 | /* Software Carrier, keeps track of the driver state |
150 | * associated with an instance of a device */ | 170 | * associated with an instance of a device */ |
151 | struct ath5k_softc { | 171 | struct ath5k_softc { |
@@ -182,10 +202,11 @@ struct ath5k_softc { | |||
182 | unsigned int curmode; /* current phy mode */ | 202 | unsigned int curmode; /* current phy mode */ |
183 | struct ieee80211_channel *curchan; /* current h/w channel */ | 203 | struct ieee80211_channel *curchan; /* current h/w channel */ |
184 | 204 | ||
185 | struct ieee80211_vif *vif; | 205 | u16 nvifs; |
186 | 206 | ||
187 | enum ath5k_int imask; /* interrupt mask copy */ | 207 | enum ath5k_int imask; /* interrupt mask copy */ |
188 | 208 | ||
209 | u8 lladdr[ETH_ALEN]; | ||
189 | u8 bssidmask[ETH_ALEN]; | 210 | u8 bssidmask[ETH_ALEN]; |
190 | 211 | ||
191 | unsigned int led_pin, /* GPIO pin for driving LED */ | 212 | unsigned int led_pin, /* GPIO pin for driving LED */ |
@@ -204,7 +225,6 @@ struct ath5k_softc { | |||
204 | spinlock_t txbuflock; | 225 | spinlock_t txbuflock; |
205 | unsigned int txbuf_len; /* buf count in txbuf list */ | 226 | unsigned int txbuf_len; /* buf count in txbuf list */ |
206 | struct ath5k_txq txqs[AR5K_NUM_TX_QUEUES]; /* tx queues */ | 227 | struct ath5k_txq txqs[AR5K_NUM_TX_QUEUES]; /* tx queues */ |
207 | struct ath5k_txq *txq; /* main tx queue */ | ||
208 | struct tasklet_struct txtq; /* tx intr tasklet */ | 228 | struct tasklet_struct txtq; /* tx intr tasklet */ |
209 | struct ath5k_led tx_led; /* tx led */ | 229 | struct ath5k_led tx_led; /* tx led */ |
210 | 230 | ||
@@ -214,7 +234,10 @@ struct ath5k_softc { | |||
214 | 234 | ||
215 | spinlock_t block; /* protects beacon */ | 235 | spinlock_t block; /* protects beacon */ |
216 | struct tasklet_struct beacontq; /* beacon intr tasklet */ | 236 | struct tasklet_struct beacontq; /* beacon intr tasklet */ |
217 | struct ath5k_buf *bbuf; /* beacon buffer */ | 237 | struct list_head bcbuf; /* beacon buffer */ |
238 | struct ieee80211_vif *bslot[ATH_BCBUF]; | ||
239 | u16 num_ap_vifs; | ||
240 | u16 num_adhoc_vifs; | ||
218 | unsigned int bhalq, /* SW q for outgoing beacons */ | 241 | unsigned int bhalq, /* SW q for outgoing beacons */ |
219 | bmisscount, /* missed beacon transmits */ | 242 | bmisscount, /* missed beacon transmits */ |
220 | bintval, /* beacon interval in TU */ | 243 | bintval, /* beacon interval in TU */ |
@@ -230,6 +253,8 @@ struct ath5k_softc { | |||
230 | 253 | ||
231 | struct ath5k_ani_state ani_state; | 254 | struct ath5k_ani_state ani_state; |
232 | struct tasklet_struct ani_tasklet; /* ANI calibration */ | 255 | struct tasklet_struct ani_tasklet; /* ANI calibration */ |
256 | |||
257 | struct delayed_work tx_complete_work; | ||
233 | }; | 258 | }; |
234 | 259 | ||
235 | #define ath5k_hw_hasbssidmask(_ah) \ | 260 | #define ath5k_hw_hasbssidmask(_ah) \ |
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index fb339c3852ee..acda56ee521b 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c | |||
@@ -60,6 +60,7 @@ | |||
60 | 60 | ||
61 | #include "base.h" | 61 | #include "base.h" |
62 | #include "debug.h" | 62 | #include "debug.h" |
63 | #include "../debug.h" | ||
63 | 64 | ||
64 | static unsigned int ath5k_debug; | 65 | static unsigned int ath5k_debug; |
65 | module_param_named(debug, ath5k_debug, uint, 0); | 66 | module_param_named(debug, ath5k_debug, uint, 0); |
@@ -71,8 +72,6 @@ module_param_named(debug, ath5k_debug, uint, 0); | |||
71 | #include "reg.h" | 72 | #include "reg.h" |
72 | #include "ani.h" | 73 | #include "ani.h" |
73 | 74 | ||
74 | static struct dentry *ath5k_global_debugfs; | ||
75 | |||
76 | static int ath5k_debugfs_open(struct inode *inode, struct file *file) | 75 | static int ath5k_debugfs_open(struct inode *inode, struct file *file) |
77 | { | 76 | { |
78 | file->private_data = inode->i_private; | 77 | file->private_data = inode->i_private; |
@@ -314,6 +313,7 @@ static const struct { | |||
314 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, | 313 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, |
315 | { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, | 314 | { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, |
316 | { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, | 315 | { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, |
316 | { ATH5K_DEBUG_DESC, "desc", "descriptor chains" }, | ||
317 | { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, | 317 | { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, |
318 | }; | 318 | }; |
319 | 319 | ||
@@ -486,6 +486,60 @@ static const struct file_operations fops_antenna = { | |||
486 | .llseek = default_llseek, | 486 | .llseek = default_llseek, |
487 | }; | 487 | }; |
488 | 488 | ||
489 | /* debugfs: misc */ | ||
490 | |||
491 | static ssize_t read_file_misc(struct file *file, char __user *user_buf, | ||
492 | size_t count, loff_t *ppos) | ||
493 | { | ||
494 | struct ath5k_softc *sc = file->private_data; | ||
495 | char buf[700]; | ||
496 | unsigned int len = 0; | ||
497 | u32 filt = ath5k_hw_get_rx_filter(sc->ah); | ||
498 | |||
499 | len += snprintf(buf+len, sizeof(buf)-len, "bssid-mask: %pM\n", | ||
500 | sc->bssidmask); | ||
501 | len += snprintf(buf+len, sizeof(buf)-len, "filter-flags: 0x%x ", | ||
502 | filt); | ||
503 | if (filt & AR5K_RX_FILTER_UCAST) | ||
504 | len += snprintf(buf+len, sizeof(buf)-len, " UCAST"); | ||
505 | if (filt & AR5K_RX_FILTER_MCAST) | ||
506 | len += snprintf(buf+len, sizeof(buf)-len, " MCAST"); | ||
507 | if (filt & AR5K_RX_FILTER_BCAST) | ||
508 | len += snprintf(buf+len, sizeof(buf)-len, " BCAST"); | ||
509 | if (filt & AR5K_RX_FILTER_CONTROL) | ||
510 | len += snprintf(buf+len, sizeof(buf)-len, " CONTROL"); | ||
511 | if (filt & AR5K_RX_FILTER_BEACON) | ||
512 | len += snprintf(buf+len, sizeof(buf)-len, " BEACON"); | ||
513 | if (filt & AR5K_RX_FILTER_PROM) | ||
514 | len += snprintf(buf+len, sizeof(buf)-len, " PROM"); | ||
515 | if (filt & AR5K_RX_FILTER_XRPOLL) | ||
516 | len += snprintf(buf+len, sizeof(buf)-len, " XRPOLL"); | ||
517 | if (filt & AR5K_RX_FILTER_PROBEREQ) | ||
518 | len += snprintf(buf+len, sizeof(buf)-len, " PROBEREQ"); | ||
519 | if (filt & AR5K_RX_FILTER_PHYERR_5212) | ||
520 | len += snprintf(buf+len, sizeof(buf)-len, " PHYERR-5212"); | ||
521 | if (filt & AR5K_RX_FILTER_RADARERR_5212) | ||
522 | len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5212"); | ||
523 | if (filt & AR5K_RX_FILTER_PHYERR_5211) | ||
524 | snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211"); | ||
525 | if (filt & AR5K_RX_FILTER_RADARERR_5211) | ||
526 | len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211"); | ||
527 | |||
528 | len += snprintf(buf+len, sizeof(buf)-len, "\nopmode: %s (%d)\n", | ||
529 | ath_opmode_to_string(sc->opmode), sc->opmode); | ||
530 | |||
531 | if (len > sizeof(buf)) | ||
532 | len = sizeof(buf); | ||
533 | |||
534 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
535 | } | ||
536 | |||
537 | static const struct file_operations fops_misc = { | ||
538 | .read = read_file_misc, | ||
539 | .open = ath5k_debugfs_open, | ||
540 | .owner = THIS_MODULE, | ||
541 | }; | ||
542 | |||
489 | 543 | ||
490 | /* debugfs: frameerrors */ | 544 | /* debugfs: frameerrors */ |
491 | 545 | ||
@@ -537,6 +591,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, | |||
537 | st->rxerr_jumbo*100/st->rx_all_count : 0); | 591 | st->rxerr_jumbo*100/st->rx_all_count : 0); |
538 | len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n", | 592 | len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n", |
539 | st->rx_all_count); | 593 | st->rx_all_count); |
594 | len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%d\n", | ||
595 | st->rx_bytes_count); | ||
540 | 596 | ||
541 | len += snprintf(buf+len, sizeof(buf)-len, | 597 | len += snprintf(buf+len, sizeof(buf)-len, |
542 | "\nTX\n---------------------\n"); | 598 | "\nTX\n---------------------\n"); |
@@ -554,6 +610,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, | |||
554 | st->txerr_filt*100/st->tx_all_count : 0); | 610 | st->txerr_filt*100/st->tx_all_count : 0); |
555 | len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", | 611 | len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", |
556 | st->tx_all_count); | 612 | st->tx_all_count); |
613 | len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%d\n", | ||
614 | st->tx_bytes_count); | ||
557 | 615 | ||
558 | if (len > sizeof(buf)) | 616 | if (len > sizeof(buf)) |
559 | len = sizeof(buf); | 617 | len = sizeof(buf); |
@@ -662,20 +720,21 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf, | |||
662 | len += snprintf(buf+len, sizeof(buf)-len, | 720 | len += snprintf(buf+len, sizeof(buf)-len, |
663 | "beacon RSSI average:\t%d\n", | 721 | "beacon RSSI average:\t%d\n", |
664 | sc->ah->ah_beacon_rssi_avg.avg); | 722 | sc->ah->ah_beacon_rssi_avg.avg); |
723 | |||
724 | #define CC_PRINT(_struct, _field) \ | ||
725 | _struct._field, \ | ||
726 | _struct.cycles > 0 ? \ | ||
727 | _struct._field*100/_struct.cycles : 0 | ||
728 | |||
665 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n", | 729 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n", |
666 | as->pfc_tx, | 730 | CC_PRINT(as->last_cc, tx_frame)); |
667 | as->pfc_cycles > 0 ? | ||
668 | as->pfc_tx*100/as->pfc_cycles : 0); | ||
669 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n", | 731 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n", |
670 | as->pfc_rx, | 732 | CC_PRINT(as->last_cc, rx_frame)); |
671 | as->pfc_cycles > 0 ? | ||
672 | as->pfc_rx*100/as->pfc_cycles : 0); | ||
673 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n", | 733 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n", |
674 | as->pfc_busy, | 734 | CC_PRINT(as->last_cc, rx_busy)); |
675 | as->pfc_cycles > 0 ? | 735 | #undef CC_PRINT |
676 | as->pfc_busy*100/as->pfc_cycles : 0); | ||
677 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n", | 736 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n", |
678 | as->pfc_cycles); | 737 | as->last_cc.cycles); |
679 | len += snprintf(buf+len, sizeof(buf)-len, | 738 | len += snprintf(buf+len, sizeof(buf)-len, |
680 | "listen time\t\t%d\tlast: %d\n", | 739 | "listen time\t\t%d\tlast: %d\n", |
681 | as->listen_time, as->last_listen); | 740 | as->listen_time, as->last_listen); |
@@ -768,7 +827,7 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, | |||
768 | 827 | ||
769 | struct ath5k_txq *txq; | 828 | struct ath5k_txq *txq; |
770 | struct ath5k_buf *bf, *bf0; | 829 | struct ath5k_buf *bf, *bf0; |
771 | int i, n = 0; | 830 | int i, n; |
772 | 831 | ||
773 | len += snprintf(buf+len, sizeof(buf)-len, | 832 | len += snprintf(buf+len, sizeof(buf)-len, |
774 | "available txbuffers: %d\n", sc->txbuf_len); | 833 | "available txbuffers: %d\n", sc->txbuf_len); |
@@ -782,9 +841,16 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, | |||
782 | if (!txq->setup) | 841 | if (!txq->setup) |
783 | continue; | 842 | continue; |
784 | 843 | ||
844 | n = 0; | ||
845 | spin_lock_bh(&txq->lock); | ||
785 | list_for_each_entry_safe(bf, bf0, &txq->q, list) | 846 | list_for_each_entry_safe(bf, bf0, &txq->q, list) |
786 | n++; | 847 | n++; |
787 | len += snprintf(buf+len, sizeof(buf)-len, " len: %d\n", n); | 848 | spin_unlock_bh(&txq->lock); |
849 | |||
850 | len += snprintf(buf+len, sizeof(buf)-len, | ||
851 | " len: %d bufs: %d\n", txq->txq_len, n); | ||
852 | len += snprintf(buf+len, sizeof(buf)-len, | ||
853 | " stuck: %d\n", txq->txq_stuck); | ||
788 | } | 854 | } |
789 | 855 | ||
790 | if (len > sizeof(buf)) | 856 | if (len > sizeof(buf)) |
@@ -821,21 +887,13 @@ static const struct file_operations fops_queue = { | |||
821 | }; | 887 | }; |
822 | 888 | ||
823 | 889 | ||
824 | /* init */ | ||
825 | |||
826 | void | ||
827 | ath5k_debug_init(void) | ||
828 | { | ||
829 | ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL); | ||
830 | } | ||
831 | |||
832 | void | 890 | void |
833 | ath5k_debug_init_device(struct ath5k_softc *sc) | 891 | ath5k_debug_init_device(struct ath5k_softc *sc) |
834 | { | 892 | { |
835 | sc->debug.level = ath5k_debug; | 893 | sc->debug.level = ath5k_debug; |
836 | 894 | ||
837 | sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy), | 895 | sc->debug.debugfs_phydir = debugfs_create_dir("ath5k", |
838 | ath5k_global_debugfs); | 896 | sc->hw->wiphy->debugfsdir); |
839 | 897 | ||
840 | sc->debug.debugfs_debug = debugfs_create_file("debug", | 898 | sc->debug.debugfs_debug = debugfs_create_file("debug", |
841 | S_IWUSR | S_IRUSR, | 899 | S_IWUSR | S_IRUSR, |
@@ -855,6 +913,10 @@ ath5k_debug_init_device(struct ath5k_softc *sc) | |||
855 | S_IWUSR | S_IRUSR, | 913 | S_IWUSR | S_IRUSR, |
856 | sc->debug.debugfs_phydir, sc, &fops_antenna); | 914 | sc->debug.debugfs_phydir, sc, &fops_antenna); |
857 | 915 | ||
916 | sc->debug.debugfs_misc = debugfs_create_file("misc", | ||
917 | S_IRUSR, | ||
918 | sc->debug.debugfs_phydir, sc, &fops_misc); | ||
919 | |||
858 | sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", | 920 | sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", |
859 | S_IWUSR | S_IRUSR, | 921 | S_IWUSR | S_IRUSR, |
860 | sc->debug.debugfs_phydir, sc, | 922 | sc->debug.debugfs_phydir, sc, |
@@ -872,12 +934,6 @@ ath5k_debug_init_device(struct ath5k_softc *sc) | |||
872 | } | 934 | } |
873 | 935 | ||
874 | void | 936 | void |
875 | ath5k_debug_finish(void) | ||
876 | { | ||
877 | debugfs_remove(ath5k_global_debugfs); | ||
878 | } | ||
879 | |||
880 | void | ||
881 | ath5k_debug_finish_device(struct ath5k_softc *sc) | 937 | ath5k_debug_finish_device(struct ath5k_softc *sc) |
882 | { | 938 | { |
883 | debugfs_remove(sc->debug.debugfs_debug); | 939 | debugfs_remove(sc->debug.debugfs_debug); |
@@ -885,6 +941,7 @@ ath5k_debug_finish_device(struct ath5k_softc *sc) | |||
885 | debugfs_remove(sc->debug.debugfs_beacon); | 941 | debugfs_remove(sc->debug.debugfs_beacon); |
886 | debugfs_remove(sc->debug.debugfs_reset); | 942 | debugfs_remove(sc->debug.debugfs_reset); |
887 | debugfs_remove(sc->debug.debugfs_antenna); | 943 | debugfs_remove(sc->debug.debugfs_antenna); |
944 | debugfs_remove(sc->debug.debugfs_misc); | ||
888 | debugfs_remove(sc->debug.debugfs_frameerrors); | 945 | debugfs_remove(sc->debug.debugfs_frameerrors); |
889 | debugfs_remove(sc->debug.debugfs_ani); | 946 | debugfs_remove(sc->debug.debugfs_ani); |
890 | debugfs_remove(sc->debug.debugfs_queue); | 947 | debugfs_remove(sc->debug.debugfs_queue); |
@@ -962,7 +1019,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) | |||
962 | struct ath5k_rx_status rs = {}; | 1019 | struct ath5k_rx_status rs = {}; |
963 | int status; | 1020 | int status; |
964 | 1021 | ||
965 | if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) | 1022 | if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC))) |
966 | return; | 1023 | return; |
967 | 1024 | ||
968 | printk(KERN_DEBUG "rxdp %x, rxlink %p\n", | 1025 | printk(KERN_DEBUG "rxdp %x, rxlink %p\n", |
@@ -1004,7 +1061,7 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1004 | struct ath5k_tx_status ts = {}; | 1061 | struct ath5k_tx_status ts = {}; |
1005 | int done; | 1062 | int done; |
1006 | 1063 | ||
1007 | if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) | 1064 | if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC))) |
1008 | return; | 1065 | return; |
1009 | 1066 | ||
1010 | done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts); | 1067 | done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts); |
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 606ae94a9157..236edbd2507d 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h | |||
@@ -75,6 +75,7 @@ struct ath5k_dbg_info { | |||
75 | struct dentry *debugfs_beacon; | 75 | struct dentry *debugfs_beacon; |
76 | struct dentry *debugfs_reset; | 76 | struct dentry *debugfs_reset; |
77 | struct dentry *debugfs_antenna; | 77 | struct dentry *debugfs_antenna; |
78 | struct dentry *debugfs_misc; | ||
78 | struct dentry *debugfs_frameerrors; | 79 | struct dentry *debugfs_frameerrors; |
79 | struct dentry *debugfs_ani; | 80 | struct dentry *debugfs_ani; |
80 | struct dentry *debugfs_queue; | 81 | struct dentry *debugfs_queue; |
@@ -95,6 +96,7 @@ struct ath5k_dbg_info { | |||
95 | * @ATH5K_DEBUG_DUMP_TX: print transmit skb content | 96 | * @ATH5K_DEBUG_DUMP_TX: print transmit skb content |
96 | * @ATH5K_DEBUG_DUMPBANDS: dump bands | 97 | * @ATH5K_DEBUG_DUMPBANDS: dump bands |
97 | * @ATH5K_DEBUG_TRACE: trace function calls | 98 | * @ATH5K_DEBUG_TRACE: trace function calls |
99 | * @ATH5K_DEBUG_DESC: descriptor setup | ||
98 | * @ATH5K_DEBUG_ANY: show at any debug level | 100 | * @ATH5K_DEBUG_ANY: show at any debug level |
99 | * | 101 | * |
100 | * The debug level is used to control the amount and type of debugging output | 102 | * The debug level is used to control the amount and type of debugging output |
@@ -117,6 +119,7 @@ enum ath5k_debug_level { | |||
117 | ATH5K_DEBUG_DUMP_TX = 0x00000200, | 119 | ATH5K_DEBUG_DUMP_TX = 0x00000200, |
118 | ATH5K_DEBUG_DUMPBANDS = 0x00000400, | 120 | ATH5K_DEBUG_DUMPBANDS = 0x00000400, |
119 | ATH5K_DEBUG_ANI = 0x00002000, | 121 | ATH5K_DEBUG_ANI = 0x00002000, |
122 | ATH5K_DEBUG_DESC = 0x00004000, | ||
120 | ATH5K_DEBUG_ANY = 0xffffffff | 123 | ATH5K_DEBUG_ANY = 0xffffffff |
121 | }; | 124 | }; |
122 | 125 | ||
@@ -135,15 +138,9 @@ enum ath5k_debug_level { | |||
135 | } while (0) | 138 | } while (0) |
136 | 139 | ||
137 | void | 140 | void |
138 | ath5k_debug_init(void); | ||
139 | |||
140 | void | ||
141 | ath5k_debug_init_device(struct ath5k_softc *sc); | 141 | ath5k_debug_init_device(struct ath5k_softc *sc); |
142 | 142 | ||
143 | void | 143 | void |
144 | ath5k_debug_finish(void); | ||
145 | |||
146 | void | ||
147 | ath5k_debug_finish_device(struct ath5k_softc *sc); | 144 | ath5k_debug_finish_device(struct ath5k_softc *sc); |
148 | 145 | ||
149 | void | 146 | void |
@@ -171,15 +168,9 @@ ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) | |||
171 | {} | 168 | {} |
172 | 169 | ||
173 | static inline void | 170 | static inline void |
174 | ath5k_debug_init(void) {} | ||
175 | |||
176 | static inline void | ||
177 | ath5k_debug_init_device(struct ath5k_softc *sc) {} | 171 | ath5k_debug_init_device(struct ath5k_softc *sc) {} |
178 | 172 | ||
179 | static inline void | 173 | static inline void |
180 | ath5k_debug_finish(void) {} | ||
181 | |||
182 | static inline void | ||
183 | ath5k_debug_finish_device(struct ath5k_softc *sc) {} | 174 | ath5k_debug_finish_device(struct ath5k_softc *sc) {} |
184 | 175 | ||
185 | static inline void | 176 | static inline void |
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 484f31870ba8..923c9ca5c4f0 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c | |||
@@ -244,7 +244,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) | |||
244 | 244 | ||
245 | /* Force channel idle high */ | 245 | /* Force channel idle high */ |
246 | AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, | 246 | AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, |
247 | AR5K_DIAG_SW_CHANEL_IDLE_HIGH); | 247 | AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); |
248 | 248 | ||
249 | /* Wait a while and disable mechanism */ | 249 | /* Wait a while and disable mechanism */ |
250 | udelay(200); | 250 | udelay(200); |
@@ -261,7 +261,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) | |||
261 | } while (--i && pending); | 261 | } while (--i && pending); |
262 | 262 | ||
263 | AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, | 263 | AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, |
264 | AR5K_DIAG_SW_CHANEL_IDLE_HIGH); | 264 | AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); |
265 | } | 265 | } |
266 | 266 | ||
267 | /* Clear register */ | 267 | /* Clear register */ |
@@ -377,11 +377,11 @@ int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr) | |||
377 | * | 377 | * |
378 | * This function increases/decreases the tx trigger level for the tx fifo | 378 | * This function increases/decreases the tx trigger level for the tx fifo |
379 | * buffer (aka FIFO threshold) that is used to indicate when PCU flushes | 379 | * buffer (aka FIFO threshold) that is used to indicate when PCU flushes |
380 | * the buffer and transmits it's data. Lowering this results sending small | 380 | * the buffer and transmits its data. Lowering this results sending small |
381 | * frames more quickly but can lead to tx underruns, raising it a lot can | 381 | * frames more quickly but can lead to tx underruns, raising it a lot can |
382 | * result other problems (i think bmiss is related). Right now we start with | 382 | * result other problems (i think bmiss is related). Right now we start with |
383 | * the lowest possible (64Bytes) and if we get tx underrun we increase it using | 383 | * the lowest possible (64Bytes) and if we get tx underrun we increase it using |
384 | * the increase flag. Returns -EIO if we have have reached maximum/minimum. | 384 | * the increase flag. Returns -EIO if we have reached maximum/minimum. |
385 | * | 385 | * |
386 | * XXX: Link this with tx DMA size ? | 386 | * XXX: Link this with tx DMA size ? |
387 | * XXX: Use it to save interrupts ? | 387 | * XXX: Use it to save interrupts ? |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index ae316fec4a6a..39722dd73e43 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -661,7 +661,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) | |||
661 | * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC | 661 | * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC |
662 | * steps that match with the power values we read from eeprom. On | 662 | * steps that match with the power values we read from eeprom. On |
663 | * older eeprom versions (< 3.2) these steps are equaly spaced at | 663 | * older eeprom versions (< 3.2) these steps are equaly spaced at |
664 | * 10% of the pcdac curve -until the curve reaches it's maximum- | 664 | * 10% of the pcdac curve -until the curve reaches its maximum- |
665 | * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) | 665 | * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) |
666 | * these 11 steps are spaced in a different way. This function returns | 666 | * these 11 steps are spaced in a different way. This function returns |
667 | * the pcdac steps based on eeprom version and curve min/max so that we | 667 | * the pcdac steps based on eeprom version and curve min/max so that we |
@@ -1113,7 +1113,7 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) | |||
1113 | */ | 1113 | */ |
1114 | 1114 | ||
1115 | /* For RF2413 power calibration data doesn't start on a fixed location and | 1115 | /* For RF2413 power calibration data doesn't start on a fixed location and |
1116 | * if a mode is not supported, it's section is missing -not zeroed-. | 1116 | * if a mode is not supported, its section is missing -not zeroed-. |
1117 | * So we need to calculate the starting offset for each section by using | 1117 | * So we need to calculate the starting offset for each section by using |
1118 | * these two functions */ | 1118 | * these two functions */ |
1119 | 1119 | ||
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 86fdb6ddfaaa..074b4c644399 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -137,11 +137,11 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah) | |||
137 | * ath5k_hw_set_ack_bitrate - set bitrate for ACKs | 137 | * ath5k_hw_set_ack_bitrate - set bitrate for ACKs |
138 | * | 138 | * |
139 | * @ah: The &struct ath5k_hw | 139 | * @ah: The &struct ath5k_hw |
140 | * @high: Flag to determine if we want to use high transmition rate | 140 | * @high: Flag to determine if we want to use high transmission rate |
141 | * for ACKs or not | 141 | * for ACKs or not |
142 | * | 142 | * |
143 | * If high flag is set, we tell hw to use a set of control rates based on | 143 | * If high flag is set, we tell hw to use a set of control rates based on |
144 | * the current transmition rate (check out control_rates array inside reset.c). | 144 | * the current transmission rate (check out control_rates array inside reset.c). |
145 | * If not hw just uses the lowest rate available for the current modulation | 145 | * If not hw just uses the lowest rate available for the current modulation |
146 | * scheme being used (1Mbit for CCK and 6Mbits for OFDM). | 146 | * scheme being used (1Mbit for CCK and 6Mbits for OFDM). |
147 | */ | 147 | */ |
@@ -207,7 +207,8 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) | |||
207 | */ | 207 | */ |
208 | unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) | 208 | unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) |
209 | { | 209 | { |
210 | return usec * ath5k_hw_get_clockrate(ah); | 210 | struct ath_common *common = ath5k_hw_common(ah); |
211 | return usec * common->clockrate; | ||
211 | } | 212 | } |
212 | 213 | ||
213 | /** | 214 | /** |
@@ -216,17 +217,19 @@ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) | |||
216 | */ | 217 | */ |
217 | unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock) | 218 | unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock) |
218 | { | 219 | { |
219 | return clock / ath5k_hw_get_clockrate(ah); | 220 | struct ath_common *common = ath5k_hw_common(ah); |
221 | return clock / common->clockrate; | ||
220 | } | 222 | } |
221 | 223 | ||
222 | /** | 224 | /** |
223 | * ath5k_hw_get_clockrate - Get the clock rate for current mode | 225 | * ath5k_hw_set_clockrate - Set common->clockrate for the current channel |
224 | * | 226 | * |
225 | * @ah: The &struct ath5k_hw | 227 | * @ah: The &struct ath5k_hw |
226 | */ | 228 | */ |
227 | unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah) | 229 | void ath5k_hw_set_clockrate(struct ath5k_hw *ah) |
228 | { | 230 | { |
229 | struct ieee80211_channel *channel = ah->ah_current_channel; | 231 | struct ieee80211_channel *channel = ah->ah_current_channel; |
232 | struct ath_common *common = ath5k_hw_common(ah); | ||
230 | int clock; | 233 | int clock; |
231 | 234 | ||
232 | if (channel->hw_value & CHANNEL_5GHZ) | 235 | if (channel->hw_value & CHANNEL_5GHZ) |
@@ -240,7 +243,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah) | |||
240 | if (channel->hw_value & CHANNEL_TURBO) | 243 | if (channel->hw_value & CHANNEL_TURBO) |
241 | clock *= 2; | 244 | clock *= 2; |
242 | 245 | ||
243 | return clock; | 246 | common->clockrate = clock; |
244 | } | 247 | } |
245 | 248 | ||
246 | /** | 249 | /** |
@@ -308,27 +311,26 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) | |||
308 | } | 311 | } |
309 | 312 | ||
310 | /** | 313 | /** |
311 | * ath5k_hw_set_associd - Set BSSID for association | 314 | * ath5k_hw_set_bssid - Set current BSSID on hw |
312 | * | 315 | * |
313 | * @ah: The &struct ath5k_hw | 316 | * @ah: The &struct ath5k_hw |
314 | * @bssid: BSSID | ||
315 | * @assoc_id: Assoc id | ||
316 | * | 317 | * |
317 | * Sets the BSSID which trigers the "SME Join" operation | 318 | * Sets the current BSSID and BSSID mask we have from the |
319 | * common struct into the hardware | ||
318 | */ | 320 | */ |
319 | void ath5k_hw_set_associd(struct ath5k_hw *ah) | 321 | void ath5k_hw_set_bssid(struct ath5k_hw *ah) |
320 | { | 322 | { |
321 | struct ath_common *common = ath5k_hw_common(ah); | 323 | struct ath_common *common = ath5k_hw_common(ah); |
322 | u16 tim_offset = 0; | 324 | u16 tim_offset = 0; |
323 | 325 | ||
324 | /* | 326 | /* |
325 | * Set simple BSSID mask on 5212 | 327 | * Set BSSID mask on 5212 |
326 | */ | 328 | */ |
327 | if (ah->ah_version == AR5K_AR5212) | 329 | if (ah->ah_version == AR5K_AR5212) |
328 | ath_hw_setbssidmask(common); | 330 | ath_hw_setbssidmask(common); |
329 | 331 | ||
330 | /* | 332 | /* |
331 | * Set BSSID which triggers the "SME Join" operation | 333 | * Set BSSID |
332 | */ | 334 | */ |
333 | ath5k_hw_reg_write(ah, | 335 | ath5k_hw_reg_write(ah, |
334 | get_unaligned_le32(common->curbssid), | 336 | get_unaligned_le32(common->curbssid), |
@@ -496,6 +498,10 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) | |||
496 | { | 498 | { |
497 | u32 tsf_lower, tsf_upper1, tsf_upper2; | 499 | u32 tsf_lower, tsf_upper1, tsf_upper2; |
498 | int i; | 500 | int i; |
501 | unsigned long flags; | ||
502 | |||
503 | /* This code is time critical - we don't want to be interrupted here */ | ||
504 | local_irq_save(flags); | ||
499 | 505 | ||
500 | /* | 506 | /* |
501 | * While reading TSF upper and then lower part, the clock is still | 507 | * While reading TSF upper and then lower part, the clock is still |
@@ -518,6 +524,8 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) | |||
518 | tsf_upper1 = tsf_upper2; | 524 | tsf_upper1 = tsf_upper2; |
519 | } | 525 | } |
520 | 526 | ||
527 | local_irq_restore(flags); | ||
528 | |||
521 | WARN_ON( i == ATH5K_MAX_TSF_READ ); | 529 | WARN_ON( i == ATH5K_MAX_TSF_READ ); |
522 | 530 | ||
523 | return (((u64)tsf_upper1 << 32) | tsf_lower); | 531 | return (((u64)tsf_upper1 << 32) | tsf_lower); |
@@ -601,7 +609,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) | |||
601 | /* Timer3 marks the end of our ATIM window | 609 | /* Timer3 marks the end of our ATIM window |
602 | * a zero length window is not allowed because | 610 | * a zero length window is not allowed because |
603 | * we 'll get no beacons */ | 611 | * we 'll get no beacons */ |
604 | timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1); | 612 | timer3 = next_beacon + 1; |
605 | 613 | ||
606 | /* | 614 | /* |
607 | * Set the beacon register and enable all timers. | 615 | * Set the beacon register and enable all timers. |
@@ -641,198 +649,95 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) | |||
641 | 649 | ||
642 | } | 650 | } |
643 | 651 | ||
644 | 652 | /** | |
645 | /*********************\ | 653 | * ath5k_check_timer_win - Check if timer B is timer A + window |
646 | * Key table functions * | 654 | * |
647 | \*********************/ | 655 | * @a: timer a (before b) |
648 | 656 | * @b: timer b (after a) | |
649 | /* | 657 | * @window: difference between a and b |
650 | * Reset a key entry on the table | 658 | * @intval: timers are increased by this interval |
659 | * | ||
660 | * This helper function checks if timer B is timer A + window and covers | ||
661 | * cases where timer A or B might have already been updated or wrapped | ||
662 | * around (Timers are 16 bit). | ||
663 | * | ||
664 | * Returns true if O.K. | ||
651 | */ | 665 | */ |
652 | int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) | 666 | static inline bool |
667 | ath5k_check_timer_win(int a, int b, int window, int intval) | ||
653 | { | 668 | { |
654 | unsigned int i, type; | ||
655 | u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; | ||
656 | |||
657 | AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); | ||
658 | |||
659 | type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry)); | ||
660 | |||
661 | for (i = 0; i < AR5K_KEYCACHE_SIZE; i++) | ||
662 | ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i)); | ||
663 | |||
664 | /* Reset associated MIC entry if TKIP | ||
665 | * is enabled located at offset (entry + 64) */ | ||
666 | if (type == AR5K_KEYTABLE_TYPE_TKIP) { | ||
667 | AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE); | ||
668 | for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++) | ||
669 | ath5k_hw_reg_write(ah, 0, | ||
670 | AR5K_KEYTABLE_OFF(micentry, i)); | ||
671 | } | ||
672 | |||
673 | /* | 669 | /* |
674 | * Set NULL encryption on AR5212+ | 670 | * 1.) usually B should be A + window |
675 | * | 671 | * 2.) A already updated, B not updated yet |
676 | * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5) | 672 | * 3.) A already updated and has wrapped around |
677 | * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007 | 673 | * 4.) B has wrapped around |
678 | * | ||
679 | * Note2: Windows driver (ndiswrapper) sets this to | ||
680 | * 0x00000714 instead of 0x00000007 | ||
681 | */ | 674 | */ |
682 | if (ah->ah_version >= AR5K_AR5211) { | 675 | if ((b - a == window) || /* 1.) */ |
683 | ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, | 676 | (a - b == intval - window) || /* 2.) */ |
684 | AR5K_KEYTABLE_TYPE(entry)); | 677 | ((a | 0x10000) - b == intval - window) || /* 3.) */ |
685 | 678 | ((b | 0x10000) - a == window)) /* 4.) */ | |
686 | if (type == AR5K_KEYTABLE_TYPE_TKIP) { | 679 | return true; /* O.K. */ |
687 | ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, | 680 | return false; |
688 | AR5K_KEYTABLE_TYPE(micentry)); | ||
689 | } | ||
690 | } | ||
691 | |||
692 | return 0; | ||
693 | } | 681 | } |
694 | 682 | ||
695 | static | 683 | /** |
696 | int ath5k_keycache_type(const struct ieee80211_key_conf *key) | 684 | * ath5k_hw_check_beacon_timers - Check if the beacon timers are correct |
697 | { | 685 | * |
698 | switch (key->alg) { | 686 | * @ah: The &struct ath5k_hw |
699 | case ALG_TKIP: | 687 | * @intval: beacon interval |
700 | return AR5K_KEYTABLE_TYPE_TKIP; | 688 | * |
701 | case ALG_CCMP: | 689 | * This is a workaround for IBSS mode: |
702 | return AR5K_KEYTABLE_TYPE_CCM; | 690 | * |
703 | case ALG_WEP: | 691 | * The need for this function arises from the fact that we have 4 separate |
704 | if (key->keylen == WLAN_KEY_LEN_WEP40) | 692 | * HW timer registers (TIMER0 - TIMER3), which are closely related to the |
705 | return AR5K_KEYTABLE_TYPE_40; | 693 | * next beacon target time (NBTT), and that the HW updates these timers |
706 | else if (key->keylen == WLAN_KEY_LEN_WEP104) | 694 | * seperately based on the current TSF value. The hardware increments each |
707 | return AR5K_KEYTABLE_TYPE_104; | 695 | * timer by the beacon interval, when the local TSF coverted to TU is equal |
708 | return -EINVAL; | 696 | * to the value stored in the timer. |
709 | default: | 697 | * |
710 | return -EINVAL; | 698 | * The reception of a beacon with the same BSSID can update the local HW TSF |
711 | } | 699 | * at any time - this is something we can't avoid. If the TSF jumps to a |
712 | return -EINVAL; | 700 | * time which is later than the time stored in a timer, this timer will not |
713 | } | 701 | * be updated until the TSF in TU wraps around at 16 bit (the size of the |
714 | 702 | * timers) and reaches the time which is stored in the timer. | |
715 | /* | 703 | * |
716 | * Set a key entry on the table | 704 | * The problem is that these timers are closely related to TIMER0 (NBTT) and |
705 | * that they define a time "window". When the TSF jumps between two timers | ||
706 | * (e.g. ATIM and NBTT), the one in the past will be left behind (not | ||
707 | * updated), while the one in the future will be updated every beacon | ||
708 | * interval. This causes the window to get larger, until the TSF wraps | ||
709 | * around as described above and the timer which was left behind gets | ||
710 | * updated again. But - because the beacon interval is usually not an exact | ||
711 | * divisor of the size of the timers (16 bit), an unwanted "window" between | ||
712 | * these timers has developed! | ||
713 | * | ||
714 | * This is especially important with the ATIM window, because during | ||
715 | * the ATIM window only ATIM frames and no data frames are allowed to be | ||
716 | * sent, which creates transmission pauses after each beacon. This symptom | ||
717 | * has been described as "ramping ping" because ping times increase linearly | ||
718 | * for some time and then drop down again. A wrong window on the DMA beacon | ||
719 | * timer has the same effect, so we check for these two conditions. | ||
720 | * | ||
721 | * Returns true if O.K. | ||
717 | */ | 722 | */ |
718 | int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, | 723 | bool |
719 | const struct ieee80211_key_conf *key, const u8 *mac) | 724 | ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval) |
720 | { | ||
721 | unsigned int i; | ||
722 | int keylen; | ||
723 | __le32 key_v[5] = {}; | ||
724 | __le32 key0 = 0, key1 = 0; | ||
725 | __le32 *rxmic, *txmic; | ||
726 | int keytype; | ||
727 | u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; | ||
728 | bool is_tkip; | ||
729 | const u8 *key_ptr; | ||
730 | |||
731 | is_tkip = (key->alg == ALG_TKIP); | ||
732 | |||
733 | /* | ||
734 | * key->keylen comes in from mac80211 in bytes. | ||
735 | * TKIP is 128 bit + 128 bit mic | ||
736 | */ | ||
737 | keylen = (is_tkip) ? (128 / 8) : key->keylen; | ||
738 | |||
739 | if (entry > AR5K_KEYTABLE_SIZE || | ||
740 | (is_tkip && micentry > AR5K_KEYTABLE_SIZE)) | ||
741 | return -EOPNOTSUPP; | ||
742 | |||
743 | if (unlikely(keylen > 16)) | ||
744 | return -EOPNOTSUPP; | ||
745 | |||
746 | keytype = ath5k_keycache_type(key); | ||
747 | if (keytype < 0) | ||
748 | return keytype; | ||
749 | |||
750 | /* | ||
751 | * each key block is 6 bytes wide, written as pairs of | ||
752 | * alternating 32 and 16 bit le values. | ||
753 | */ | ||
754 | key_ptr = key->key; | ||
755 | for (i = 0; keylen >= 6; keylen -= 6) { | ||
756 | memcpy(&key_v[i], key_ptr, 6); | ||
757 | i += 2; | ||
758 | key_ptr += 6; | ||
759 | } | ||
760 | if (keylen) | ||
761 | memcpy(&key_v[i], key_ptr, keylen); | ||
762 | |||
763 | /* intentionally corrupt key until mic is installed */ | ||
764 | if (is_tkip) { | ||
765 | key0 = key_v[0] = ~key_v[0]; | ||
766 | key1 = key_v[1] = ~key_v[1]; | ||
767 | } | ||
768 | |||
769 | for (i = 0; i < ARRAY_SIZE(key_v); i++) | ||
770 | ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), | ||
771 | AR5K_KEYTABLE_OFF(entry, i)); | ||
772 | |||
773 | ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry)); | ||
774 | |||
775 | if (is_tkip) { | ||
776 | /* Install rx/tx MIC */ | ||
777 | rxmic = (__le32 *) &key->key[16]; | ||
778 | txmic = (__le32 *) &key->key[24]; | ||
779 | |||
780 | if (ah->ah_combined_mic) { | ||
781 | key_v[0] = rxmic[0]; | ||
782 | key_v[1] = cpu_to_le32(le32_to_cpu(txmic[0]) >> 16); | ||
783 | key_v[2] = rxmic[1]; | ||
784 | key_v[3] = cpu_to_le32(le32_to_cpu(txmic[0]) & 0xffff); | ||
785 | key_v[4] = txmic[1]; | ||
786 | } else { | ||
787 | key_v[0] = rxmic[0]; | ||
788 | key_v[1] = 0; | ||
789 | key_v[2] = rxmic[1]; | ||
790 | key_v[3] = 0; | ||
791 | key_v[4] = 0; | ||
792 | } | ||
793 | for (i = 0; i < ARRAY_SIZE(key_v); i++) | ||
794 | ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), | ||
795 | AR5K_KEYTABLE_OFF(micentry, i)); | ||
796 | |||
797 | ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, | ||
798 | AR5K_KEYTABLE_TYPE(micentry)); | ||
799 | ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC0(micentry)); | ||
800 | ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC1(micentry)); | ||
801 | |||
802 | /* restore first 2 words of key */ | ||
803 | ath5k_hw_reg_write(ah, le32_to_cpu(~key0), | ||
804 | AR5K_KEYTABLE_OFF(entry, 0)); | ||
805 | ath5k_hw_reg_write(ah, le32_to_cpu(~key1), | ||
806 | AR5K_KEYTABLE_OFF(entry, 1)); | ||
807 | } | ||
808 | |||
809 | return ath5k_hw_set_key_lladdr(ah, entry, mac); | ||
810 | } | ||
811 | |||
812 | int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) | ||
813 | { | 725 | { |
814 | u32 low_id, high_id; | 726 | unsigned int nbtt, atim, dma; |
815 | |||
816 | /* Invalid entry (key table overflow) */ | ||
817 | AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); | ||
818 | 727 | ||
819 | /* | 728 | nbtt = ath5k_hw_reg_read(ah, AR5K_TIMER0); |
820 | * MAC may be NULL if it's a broadcast key. In this case no need to | 729 | atim = ath5k_hw_reg_read(ah, AR5K_TIMER3); |
821 | * to compute get_unaligned_le32 and get_unaligned_le16 as we | 730 | dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3; |
822 | * already know it. | ||
823 | */ | ||
824 | if (!mac) { | ||
825 | low_id = 0xffffffff; | ||
826 | high_id = 0xffff | AR5K_KEYTABLE_VALID; | ||
827 | } else { | ||
828 | low_id = get_unaligned_le32(mac); | ||
829 | high_id = get_unaligned_le16(mac + 4) | AR5K_KEYTABLE_VALID; | ||
830 | } | ||
831 | 731 | ||
832 | ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry)); | 732 | /* NOTE: SWBA is different. Having a wrong window there does not |
833 | ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry)); | 733 | * stop us from sending data and this condition is catched thru |
734 | * other means (SWBA interrupt) */ | ||
834 | 735 | ||
835 | return 0; | 736 | if (ath5k_check_timer_win(nbtt, atim, 1, intval) && |
737 | ath5k_check_timer_win(dma, nbtt, AR5K_TUNE_DMA_BEACON_RESP, | ||
738 | intval)) | ||
739 | return true; /* O.K. */ | ||
740 | return false; | ||
836 | } | 741 | } |
837 | 742 | ||
838 | /** | 743 | /** |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 6284c389ba18..219367884e64 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -115,7 +115,7 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, | |||
115 | \**********************/ | 115 | \**********************/ |
116 | 116 | ||
117 | /* | 117 | /* |
118 | * This code is used to optimize rf gain on different environments | 118 | * This code is used to optimize RF gain on different environments |
119 | * (temperature mostly) based on feedback from a power detector. | 119 | * (temperature mostly) based on feedback from a power detector. |
120 | * | 120 | * |
121 | * It's only used on RF5111 and RF5112, later RF chips seem to have | 121 | * It's only used on RF5111 and RF5112, later RF chips seem to have |
@@ -302,7 +302,7 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah) | |||
302 | } | 302 | } |
303 | 303 | ||
304 | /* Perform gain_F adjustment by choosing the right set | 304 | /* Perform gain_F adjustment by choosing the right set |
305 | * of parameters from rf gain optimization ladder */ | 305 | * of parameters from RF gain optimization ladder */ |
306 | static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah) | 306 | static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah) |
307 | { | 307 | { |
308 | const struct ath5k_gain_opt *go; | 308 | const struct ath5k_gain_opt *go; |
@@ -367,7 +367,7 @@ done: | |||
367 | return ret; | 367 | return ret; |
368 | } | 368 | } |
369 | 369 | ||
370 | /* Main callback for thermal rf gain calibration engine | 370 | /* Main callback for thermal RF gain calibration engine |
371 | * Check for a new gain reading and schedule an adjustment | 371 | * Check for a new gain reading and schedule an adjustment |
372 | * if needed. | 372 | * if needed. |
373 | * | 373 | * |
@@ -433,7 +433,7 @@ done: | |||
433 | return ah->ah_gain.g_state; | 433 | return ah->ah_gain.g_state; |
434 | } | 434 | } |
435 | 435 | ||
436 | /* Write initial rf gain table to set the RF sensitivity | 436 | /* Write initial RF gain table to set the RF sensitivity |
437 | * this one works on all RF chips and has nothing to do | 437 | * this one works on all RF chips and has nothing to do |
438 | * with gain_F calibration */ | 438 | * with gain_F calibration */ |
439 | int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) | 439 | int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) |
@@ -496,7 +496,7 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) | |||
496 | 496 | ||
497 | 497 | ||
498 | /* | 498 | /* |
499 | * Setup RF registers by writing rf buffer on hw | 499 | * Setup RF registers by writing RF buffer on hw |
500 | */ | 500 | */ |
501 | int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | 501 | int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, |
502 | unsigned int mode) | 502 | unsigned int mode) |
@@ -571,7 +571,7 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
571 | return -EINVAL; | 571 | return -EINVAL; |
572 | } | 572 | } |
573 | 573 | ||
574 | /* If it's the first time we set rf buffer, allocate | 574 | /* If it's the first time we set RF buffer, allocate |
575 | * ah->ah_rf_banks based on ah->ah_rf_banks_size | 575 | * ah->ah_rf_banks based on ah->ah_rf_banks_size |
576 | * we set above */ | 576 | * we set above */ |
577 | if (ah->ah_rf_banks == NULL) { | 577 | if (ah->ah_rf_banks == NULL) { |
@@ -1093,6 +1093,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) | |||
1093 | 1093 | ||
1094 | ah->ah_current_channel = channel; | 1094 | ah->ah_current_channel = channel; |
1095 | ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false; | 1095 | ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false; |
1096 | ath5k_hw_set_clockrate(ah); | ||
1096 | 1097 | ||
1097 | return 0; | 1098 | return 0; |
1098 | } | 1099 | } |
@@ -1257,7 +1258,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, | |||
1257 | * Disable beacons and RX/TX queues, wait | 1258 | * Disable beacons and RX/TX queues, wait |
1258 | */ | 1259 | */ |
1259 | AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210, | 1260 | AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210, |
1260 | AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210); | 1261 | AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210); |
1261 | beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210); | 1262 | beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210); |
1262 | ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210); | 1263 | ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210); |
1263 | 1264 | ||
@@ -1336,7 +1337,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, | |||
1336 | * Re-enable RX/TX and beacons | 1337 | * Re-enable RX/TX and beacons |
1337 | */ | 1338 | */ |
1338 | AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210, | 1339 | AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210, |
1339 | AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210); | 1340 | AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210); |
1340 | ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210); | 1341 | ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210); |
1341 | 1342 | ||
1342 | return 0; | 1343 | return 0; |
@@ -1377,7 +1378,7 @@ ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah) | |||
1377 | 1378 | ||
1378 | /* protect against divide by 0 and loss of sign bits */ | 1379 | /* protect against divide by 0 and loss of sign bits */ |
1379 | if (i_coffd == 0 || q_coffd < 2) | 1380 | if (i_coffd == 0 || q_coffd < 2) |
1380 | return -1; | 1381 | return 0; |
1381 | 1382 | ||
1382 | i_coff = (-iq_corr) / i_coffd; | 1383 | i_coff = (-iq_corr) / i_coffd; |
1383 | i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ | 1384 | i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ |
@@ -1582,7 +1583,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, | |||
1582 | else if (curr_sym_off >= 31 && curr_sym_off <= 46) | 1583 | else if (curr_sym_off >= 31 && curr_sym_off <= 46) |
1583 | mag_mask[2] |= | 1584 | mag_mask[2] |= |
1584 | plt_mag_map << (curr_sym_off - 31) * 2; | 1585 | plt_mag_map << (curr_sym_off - 31) * 2; |
1585 | else if (curr_sym_off >= 46 && curr_sym_off <= 53) | 1586 | else if (curr_sym_off >= 47 && curr_sym_off <= 53) |
1586 | mag_mask[3] |= | 1587 | mag_mask[3] |= |
1587 | plt_mag_map << (curr_sym_off - 47) * 2; | 1588 | plt_mag_map << (curr_sym_off - 47) * 2; |
1588 | 1589 | ||
@@ -2987,7 +2988,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, | |||
2987 | 2988 | ||
2988 | 2989 | ||
2989 | /* | 2990 | /* |
2990 | * Set transmition power | 2991 | * Set transmission power |
2991 | */ | 2992 | */ |
2992 | int | 2993 | int |
2993 | ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, | 2994 | ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, |
@@ -3035,9 +3036,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
3035 | /* Limit max power if we have a CTL available */ | 3036 | /* Limit max power if we have a CTL available */ |
3036 | ath5k_get_max_ctl_power(ah, channel); | 3037 | ath5k_get_max_ctl_power(ah, channel); |
3037 | 3038 | ||
3038 | /* FIXME: Tx power limit for this regdomain | ||
3039 | * XXX: Mac80211/CRDA will do that anyway ? */ | ||
3040 | |||
3041 | /* FIXME: Antenna reduction stuff */ | 3039 | /* FIXME: Antenna reduction stuff */ |
3042 | 3040 | ||
3043 | /* FIXME: Limit power on turbo modes */ | 3041 | /* FIXME: Limit power on turbo modes */ |
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 4186ff4c6e9c..84c717ded1c5 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c | |||
@@ -36,24 +36,58 @@ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, | |||
36 | } | 36 | } |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * Make sure cw is a power of 2 minus 1 and smaller than 1024 | ||
40 | */ | ||
41 | static u16 ath5k_cw_validate(u16 cw_req) | ||
42 | { | ||
43 | u32 cw = 1; | ||
44 | cw_req = min(cw_req, (u16)1023); | ||
45 | |||
46 | while (cw < cw_req) | ||
47 | cw = (cw << 1) | 1; | ||
48 | |||
49 | return cw; | ||
50 | } | ||
51 | |||
52 | /* | ||
39 | * Set properties for a transmit queue | 53 | * Set properties for a transmit queue |
40 | */ | 54 | */ |
41 | int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, | 55 | int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, |
42 | const struct ath5k_txq_info *queue_info) | 56 | const struct ath5k_txq_info *qinfo) |
43 | { | 57 | { |
58 | struct ath5k_txq_info *qi; | ||
59 | |||
44 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | 60 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); |
45 | 61 | ||
46 | if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) | 62 | qi = &ah->ah_txq[queue]; |
63 | |||
64 | if (qi->tqi_type == AR5K_TX_QUEUE_INACTIVE) | ||
47 | return -EIO; | 65 | return -EIO; |
48 | 66 | ||
49 | memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info)); | 67 | /* copy and validate values */ |
68 | qi->tqi_type = qinfo->tqi_type; | ||
69 | qi->tqi_subtype = qinfo->tqi_subtype; | ||
70 | qi->tqi_flags = qinfo->tqi_flags; | ||
71 | /* | ||
72 | * According to the docs: Although the AIFS field is 8 bit wide, | ||
73 | * the maximum supported value is 0xFC. Setting it higher than that | ||
74 | * will cause the DCU to hang. | ||
75 | */ | ||
76 | qi->tqi_aifs = min(qinfo->tqi_aifs, (u8)0xFC); | ||
77 | qi->tqi_cw_min = ath5k_cw_validate(qinfo->tqi_cw_min); | ||
78 | qi->tqi_cw_max = ath5k_cw_validate(qinfo->tqi_cw_max); | ||
79 | qi->tqi_cbr_period = qinfo->tqi_cbr_period; | ||
80 | qi->tqi_cbr_overflow_limit = qinfo->tqi_cbr_overflow_limit; | ||
81 | qi->tqi_burst_time = qinfo->tqi_burst_time; | ||
82 | qi->tqi_ready_time = qinfo->tqi_ready_time; | ||
50 | 83 | ||
51 | /*XXX: Is this supported on 5210 ?*/ | 84 | /*XXX: Is this supported on 5210 ?*/ |
52 | if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA && | 85 | /*XXX: Is this correct for AR5K_WME_AC_VI,VO ???*/ |
53 | ((queue_info->tqi_subtype == AR5K_WME_AC_VI) || | 86 | if ((qinfo->tqi_type == AR5K_TX_QUEUE_DATA && |
54 | (queue_info->tqi_subtype == AR5K_WME_AC_VO))) || | 87 | ((qinfo->tqi_subtype == AR5K_WME_AC_VI) || |
55 | queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD) | 88 | (qinfo->tqi_subtype == AR5K_WME_AC_VO))) || |
56 | ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; | 89 | qinfo->tqi_type == AR5K_TX_QUEUE_UAPSD) |
90 | qi->tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; | ||
57 | 91 | ||
58 | return 0; | 92 | return 0; |
59 | } | 93 | } |
@@ -186,7 +220,7 @@ void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
186 | */ | 220 | */ |
187 | int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | 221 | int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) |
188 | { | 222 | { |
189 | u32 cw_min, cw_max, retry_lg, retry_sh; | 223 | u32 retry_lg, retry_sh; |
190 | struct ath5k_txq_info *tq = &ah->ah_txq[queue]; | 224 | struct ath5k_txq_info *tq = &ah->ah_txq[queue]; |
191 | 225 | ||
192 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | 226 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); |
@@ -217,14 +251,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
217 | /* Set IFS0 */ | 251 | /* Set IFS0 */ |
218 | if (ah->ah_turbo) { | 252 | if (ah->ah_turbo) { |
219 | ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO + | 253 | ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO + |
220 | (ah->ah_aifs + tq->tqi_aifs) * | 254 | tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO) << |
221 | AR5K_INIT_SLOT_TIME_TURBO) << | ||
222 | AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO, | 255 | AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO, |
223 | AR5K_IFS0); | 256 | AR5K_IFS0); |
224 | } else { | 257 | } else { |
225 | ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS + | 258 | ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS + |
226 | (ah->ah_aifs + tq->tqi_aifs) * | 259 | tq->tqi_aifs * AR5K_INIT_SLOT_TIME) << |
227 | AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) | | 260 | AR5K_IFS0_DIFS_S) | |
228 | AR5K_INIT_SIFS, AR5K_IFS0); | 261 | AR5K_INIT_SIFS, AR5K_IFS0); |
229 | } | 262 | } |
230 | 263 | ||
@@ -248,35 +281,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
248 | } | 281 | } |
249 | 282 | ||
250 | /* | 283 | /* |
251 | * Calculate cwmin/max by channel mode | ||
252 | */ | ||
253 | cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN; | ||
254 | cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX; | ||
255 | ah->ah_aifs = AR5K_TUNE_AIFS; | ||
256 | /*XR is only supported on 5212*/ | ||
257 | if (IS_CHAN_XR(ah->ah_current_channel) && | ||
258 | ah->ah_version == AR5K_AR5212) { | ||
259 | cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR; | ||
260 | cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR; | ||
261 | ah->ah_aifs = AR5K_TUNE_AIFS_XR; | ||
262 | /*B mode is not supported on 5210*/ | ||
263 | } else if (IS_CHAN_B(ah->ah_current_channel) && | ||
264 | ah->ah_version != AR5K_AR5210) { | ||
265 | cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B; | ||
266 | cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B; | ||
267 | ah->ah_aifs = AR5K_TUNE_AIFS_11B; | ||
268 | } | ||
269 | |||
270 | cw_min = 1; | ||
271 | while (cw_min < ah->ah_cw_min) | ||
272 | cw_min = (cw_min << 1) | 1; | ||
273 | |||
274 | cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) : | ||
275 | ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1); | ||
276 | cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) : | ||
277 | ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1); | ||
278 | |||
279 | /* | ||
280 | * Calculate and set retry limits | 284 | * Calculate and set retry limits |
281 | */ | 285 | */ |
282 | if (ah->ah_software_retry) { | 286 | if (ah->ah_software_retry) { |
@@ -292,7 +296,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
292 | /*No QCU/DCU [5210]*/ | 296 | /*No QCU/DCU [5210]*/ |
293 | if (ah->ah_version == AR5K_AR5210) { | 297 | if (ah->ah_version == AR5K_AR5210) { |
294 | ath5k_hw_reg_write(ah, | 298 | ath5k_hw_reg_write(ah, |
295 | (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) | 299 | (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) |
296 | | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, | 300 | | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, |
297 | AR5K_NODCU_RETRY_LMT_SLG_RETRY) | 301 | AR5K_NODCU_RETRY_LMT_SLG_RETRY) |
298 | | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, | 302 | | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, |
@@ -314,14 +318,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
314 | /*===Rest is also for QCU/DCU only [5211+]===*/ | 318 | /*===Rest is also for QCU/DCU only [5211+]===*/ |
315 | 319 | ||
316 | /* | 320 | /* |
317 | * Set initial content window (cw_min/cw_max) | 321 | * Set contention window (cw_min/cw_max) |
318 | * and arbitrated interframe space (aifs)... | 322 | * and arbitrated interframe space (aifs)... |
319 | */ | 323 | */ |
320 | ath5k_hw_reg_write(ah, | 324 | ath5k_hw_reg_write(ah, |
321 | AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | | 325 | AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | |
322 | AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | | 326 | AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | |
323 | AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs, | 327 | AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS), |
324 | AR5K_DCU_LCL_IFS_AIFS), | ||
325 | AR5K_QUEUE_DFS_LOCAL_IFS(queue)); | 328 | AR5K_QUEUE_DFS_LOCAL_IFS(queue)); |
326 | 329 | ||
327 | /* | 330 | /* |
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 55b4ac6d236f..a34929f06533 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h | |||
@@ -1387,10 +1387,9 @@ | |||
1387 | 1387 | ||
1388 | 1388 | ||
1389 | /* | 1389 | /* |
1390 | * PCU control register | 1390 | * PCU Diagnostic register |
1391 | * | 1391 | * |
1392 | * Only DIS_RX is used in the code, the rest i guess are | 1392 | * Used for tweaking/diagnostics. |
1393 | * for tweaking/diagnostics. | ||
1394 | */ | 1393 | */ |
1395 | #define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */ | 1394 | #define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */ |
1396 | #define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */ | 1395 | #define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */ |
@@ -1399,22 +1398,22 @@ | |||
1399 | #define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001 /* Disable ACKs if WEP key is invalid */ | 1398 | #define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001 /* Disable ACKs if WEP key is invalid */ |
1400 | #define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs */ | 1399 | #define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs */ |
1401 | #define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs */ | 1400 | #define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs */ |
1402 | #define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable encryption */ | 1401 | #define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable HW encryption */ |
1403 | #define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable decryption */ | 1402 | #define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable HW decryption */ |
1404 | #define AR5K_DIAG_SW_DIS_TX 0x00000020 /* Disable transmit [5210] */ | 1403 | #define AR5K_DIAG_SW_DIS_TX_5210 0x00000020 /* Disable transmit [5210] */ |
1405 | #define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable recieve */ | 1404 | #define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable receive */ |
1406 | #define AR5K_DIAG_SW_DIS_RX_5211 0x00000020 | 1405 | #define AR5K_DIAG_SW_DIS_RX_5211 0x00000020 |
1407 | #define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \ | 1406 | #define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \ |
1408 | AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211) | 1407 | AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211) |
1409 | #define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* Loopback (i guess it goes with DIS_TX) [5210] */ | 1408 | #define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* TX Data Loopback (i guess it goes with DIS_TX) [5210] */ |
1410 | #define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040 | 1409 | #define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040 |
1411 | #define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \ | 1410 | #define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \ |
1412 | AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211) | 1411 | AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211) |
1413 | #define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Corrupted FCS */ | 1412 | #define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Generate invalid TX FCS */ |
1414 | #define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080 | 1413 | #define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080 |
1415 | #define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \ | 1414 | #define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \ |
1416 | AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211) | 1415 | AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211) |
1417 | #define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Dump channel info */ | 1416 | #define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Add 56 bytes of channel info before the frame data in the RX buffer */ |
1418 | #define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100 | 1417 | #define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100 |
1419 | #define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \ | 1418 | #define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \ |
1420 | AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211) | 1419 | AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211) |
@@ -1426,17 +1425,17 @@ | |||
1426 | #define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */ | 1425 | #define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */ |
1427 | #define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask */ | 1426 | #define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask */ |
1428 | #define AR5K_DIAG_SW_SCRAM_SEED_S 10 | 1427 | #define AR5K_DIAG_SW_SCRAM_SEED_S 10 |
1429 | #define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */ | 1428 | #define AR5K_DIAG_SW_DIS_SEQ_INC_5210 0x00040000 /* Disable seqnum increment (?)[5210] */ |
1430 | #define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000 | 1429 | #define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000 |
1431 | #define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */ | 1430 | #define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */ |
1432 | #define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \ | 1431 | #define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \ |
1433 | AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211) | 1432 | AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211) |
1434 | #define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */ | 1433 | #define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */ |
1435 | #define AR5K_DIAG_SW_OBSPT_S 18 | 1434 | #define AR5K_DIAG_SW_OBSPT_S 18 |
1436 | #define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x0010000 /* Force RX Clear high */ | 1435 | #define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x00100000 /* Ignore carrier sense */ |
1437 | #define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000 /* Ignore virtual carrier sense */ | 1436 | #define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x00200000 /* Ignore virtual carrier sense */ |
1438 | #define AR5K_DIAG_SW_CHANEL_IDLE_HIGH 0x0040000 /* Force channel idle high */ | 1437 | #define AR5K_DIAG_SW_CHANNEL_IDLE_HIGH 0x00400000 /* Force channel idle high */ |
1439 | #define AR5K_DIAG_SW_PHEAR_ME 0x0080000 /* ??? */ | 1438 | #define AR5K_DIAG_SW_PHEAR_ME 0x00800000 /* ??? */ |
1440 | 1439 | ||
1441 | /* | 1440 | /* |
1442 | * TSF (clock) register (lower 32 bits) | 1441 | * TSF (clock) register (lower 32 bits) |
@@ -1822,50 +1821,8 @@ | |||
1822 | 1821 | ||
1823 | /*===5212 end===*/ | 1822 | /*===5212 end===*/ |
1824 | 1823 | ||
1825 | /* | ||
1826 | * Key table (WEP) register | ||
1827 | */ | ||
1828 | #define AR5K_KEYTABLE_0_5210 0x9000 | ||
1829 | #define AR5K_KEYTABLE_0_5211 0x8800 | ||
1830 | #define AR5K_KEYTABLE_5210(_n) (AR5K_KEYTABLE_0_5210 + ((_n) << 5)) | ||
1831 | #define AR5K_KEYTABLE_5211(_n) (AR5K_KEYTABLE_0_5211 + ((_n) << 5)) | ||
1832 | #define AR5K_KEYTABLE(_n) (ah->ah_version == AR5K_AR5210 ? \ | ||
1833 | AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n)) | ||
1834 | #define AR5K_KEYTABLE_OFF(_n, x) (AR5K_KEYTABLE(_n) + (x << 2)) | ||
1835 | #define AR5K_KEYTABLE_TYPE(_n) AR5K_KEYTABLE_OFF(_n, 5) | ||
1836 | #define AR5K_KEYTABLE_TYPE_40 0x00000000 | ||
1837 | #define AR5K_KEYTABLE_TYPE_104 0x00000001 | ||
1838 | #define AR5K_KEYTABLE_TYPE_128 0x00000003 | ||
1839 | #define AR5K_KEYTABLE_TYPE_TKIP 0x00000004 /* [5212+] */ | ||
1840 | #define AR5K_KEYTABLE_TYPE_AES 0x00000005 /* [5211+] */ | ||
1841 | #define AR5K_KEYTABLE_TYPE_CCM 0x00000006 /* [5212+] */ | ||
1842 | #define AR5K_KEYTABLE_TYPE_NULL 0x00000007 /* [5211+] */ | ||
1843 | #define AR5K_KEYTABLE_ANTENNA 0x00000008 /* [5212+] */ | ||
1844 | #define AR5K_KEYTABLE_MAC0(_n) AR5K_KEYTABLE_OFF(_n, 6) | ||
1845 | #define AR5K_KEYTABLE_MAC1(_n) AR5K_KEYTABLE_OFF(_n, 7) | ||
1846 | #define AR5K_KEYTABLE_VALID 0x00008000 | ||
1847 | |||
1848 | /* If key type is TKIP and MIC is enabled | ||
1849 | * MIC key goes in offset entry + 64 */ | ||
1850 | #define AR5K_KEYTABLE_MIC_OFFSET 64 | ||
1851 | |||
1852 | /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit | ||
1853 | * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit | ||
1854 | * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit | ||
1855 | * | ||
1856 | * Some vendors have introduced bigger WEP keys to address | ||
1857 | * security vulnerabilities in WEP. This includes: | ||
1858 | * | ||
1859 | * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit | ||
1860 | * | ||
1861 | * We can expand this if we find ar5k Atheros cards with a larger | ||
1862 | * key table size. | ||
1863 | */ | ||
1864 | #define AR5K_KEYTABLE_SIZE_5210 64 | 1824 | #define AR5K_KEYTABLE_SIZE_5210 64 |
1865 | #define AR5K_KEYTABLE_SIZE_5211 128 | 1825 | #define AR5K_KEYTABLE_SIZE_5211 128 |
1866 | #define AR5K_KEYTABLE_SIZE (ah->ah_version == AR5K_AR5210 ? \ | ||
1867 | AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211) | ||
1868 | |||
1869 | 1826 | ||
1870 | /*===PHY REGISTERS===*/ | 1827 | /*===PHY REGISTERS===*/ |
1871 | 1828 | ||
@@ -1911,7 +1868,7 @@ | |||
1911 | #define AR5K_PHY_TURBO 0x9804 /* Register Address */ | 1868 | #define AR5K_PHY_TURBO 0x9804 /* Register Address */ |
1912 | #define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */ | 1869 | #define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */ |
1913 | #define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */ | 1870 | #define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */ |
1914 | #define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo mimo */ | 1871 | #define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo */ |
1915 | 1872 | ||
1916 | /* | 1873 | /* |
1917 | * PHY agility command register | 1874 | * PHY agility command register |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 498aa28ea9e6..5b179d01f97d 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -167,7 +167,7 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | |||
167 | * ieee80211_duration() for a brief description of | 167 | * ieee80211_duration() for a brief description of |
168 | * what rate we should choose to TX ACKs. */ | 168 | * what rate we should choose to TX ACKs. */ |
169 | tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, | 169 | tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, |
170 | sc->vif, 10, rate)); | 170 | NULL, 10, rate)); |
171 | 171 | ||
172 | ath5k_hw_reg_write(ah, tx_time, reg); | 172 | ath5k_hw_reg_write(ah, tx_time, reg); |
173 | 173 | ||
@@ -326,7 +326,7 @@ commit: | |||
326 | * register). After this MAC and Baseband are | 326 | * register). After this MAC and Baseband are |
327 | * disabled and a full reset is needed to come | 327 | * disabled and a full reset is needed to come |
328 | * back. This way we save as much power as possible | 328 | * back. This way we save as much power as possible |
329 | * without puting the card on full sleep. | 329 | * without putting the card on full sleep. |
330 | */ | 330 | */ |
331 | int ath5k_hw_on_hold(struct ath5k_hw *ah) | 331 | int ath5k_hw_on_hold(struct ath5k_hw *ah) |
332 | { | 332 | { |
@@ -344,7 +344,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah) | |||
344 | /* | 344 | /* |
345 | * Put chipset on warm reset... | 345 | * Put chipset on warm reset... |
346 | * | 346 | * |
347 | * Note: puting PCI core on warm reset on PCI-E cards | 347 | * Note: putting PCI core on warm reset on PCI-E cards |
348 | * results card to hang and always return 0xffff... so | 348 | * results card to hang and always return 0xffff... so |
349 | * we ingore that flag for PCI-E cards. On PCI cards | 349 | * we ingore that flag for PCI-E cards. On PCI cards |
350 | * this flag gets cleared after 64 PCI clocks. | 350 | * this flag gets cleared after 64 PCI clocks. |
@@ -400,7 +400,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) | |||
400 | /* | 400 | /* |
401 | * Put chipset on warm reset... | 401 | * Put chipset on warm reset... |
402 | * | 402 | * |
403 | * Note: puting PCI core on warm reset on PCI-E cards | 403 | * Note: putting PCI core on warm reset on PCI-E cards |
404 | * results card to hang and always return 0xffff... so | 404 | * results card to hang and always return 0xffff... so |
405 | * we ingore that flag for PCI-E cards. On PCI cards | 405 | * we ingore that flag for PCI-E cards. On PCI cards |
406 | * this flag gets cleared after 64 PCI clocks. | 406 | * this flag gets cleared after 64 PCI clocks. |
@@ -959,7 +959,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
959 | AR5K_QUEUE_DCU_SEQNUM(0)); | 959 | AR5K_QUEUE_DCU_SEQNUM(0)); |
960 | } | 960 | } |
961 | 961 | ||
962 | /* TSF accelerates on AR5211 durring reset | 962 | /* TSF accelerates on AR5211 during reset |
963 | * As a workaround save it here and restore | 963 | * As a workaround save it here and restore |
964 | * it later so that it's back in time after | 964 | * it later so that it's back in time after |
965 | * reset. This way it'll get re-synced on the | 965 | * reset. This way it'll get re-synced on the |
@@ -1060,7 +1060,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1060 | * XXX: rethink this after new mode changes to | 1060 | * XXX: rethink this after new mode changes to |
1061 | * mac80211 are integrated */ | 1061 | * mac80211 are integrated */ |
1062 | if (ah->ah_version == AR5K_AR5212 && | 1062 | if (ah->ah_version == AR5K_AR5212 && |
1063 | ah->ah_sc->vif != NULL) | 1063 | ah->ah_sc->nvifs) |
1064 | ath5k_hw_write_rate_duration(ah, mode); | 1064 | ath5k_hw_write_rate_duration(ah, mode); |
1065 | 1065 | ||
1066 | /* | 1066 | /* |
@@ -1080,7 +1080,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1080 | return ret; | 1080 | return ret; |
1081 | 1081 | ||
1082 | /* Spur info is available only from EEPROM versions | 1082 | /* Spur info is available only from EEPROM versions |
1083 | * bigger than 5.3 but but the EEPOM routines will use | 1083 | * greater than 5.3, but the EEPROM routines will use |
1084 | * static values for older versions */ | 1084 | * static values for older versions */ |
1085 | if (ah->ah_mac_srev >= AR5K_SREV_AR5424) | 1085 | if (ah->ah_mac_srev >= AR5K_SREV_AR5424) |
1086 | ath5k_hw_set_spur_mitigation_filter(ah, | 1086 | ath5k_hw_set_spur_mitigation_filter(ah, |
@@ -1160,7 +1160,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1160 | */ | 1160 | */ |
1161 | 1161 | ||
1162 | /* Restore bssid and bssid mask */ | 1162 | /* Restore bssid and bssid mask */ |
1163 | ath5k_hw_set_associd(ah); | 1163 | ath5k_hw_set_bssid(ah); |
1164 | 1164 | ||
1165 | /* Set PCU config */ | 1165 | /* Set PCU config */ |
1166 | ath5k_hw_set_opmode(ah, op_mode); | 1166 | ath5k_hw_set_opmode(ah, op_mode); |
@@ -1173,11 +1173,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1173 | /* Set RSSI/BRSSI thresholds | 1173 | /* Set RSSI/BRSSI thresholds |
1174 | * | 1174 | * |
1175 | * Note: If we decide to set this value | 1175 | * Note: If we decide to set this value |
1176 | * dynamicaly, have in mind that when AR5K_RSSI_THR | 1176 | * dynamically, keep in mind that when AR5K_RSSI_THR |
1177 | * register is read it might return 0x40 if we haven't | 1177 | * register is read, it might return 0x40 if we haven't |
1178 | * wrote anything to it plus BMISS RSSI threshold is zeroed. | 1178 | * written anything to it. Also, BMISS RSSI threshold is zeroed. |
1179 | * So doing a save/restore procedure here isn't the right | 1179 | * So doing a save/restore procedure here isn't the right |
1180 | * choice. Instead store it on ath5k_hw */ | 1180 | * choice. Instead, store it in ath5k_hw */ |
1181 | ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES | | 1181 | ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES | |
1182 | AR5K_TUNE_BMISS_THRES << | 1182 | AR5K_TUNE_BMISS_THRES << |
1183 | AR5K_RSSI_THR_BMISS_S), | 1183 | AR5K_RSSI_THR_BMISS_S), |
@@ -1235,7 +1235,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1235 | 1235 | ||
1236 | /* | 1236 | /* |
1237 | * Perform ADC test to see if baseband is ready | 1237 | * Perform ADC test to see if baseband is ready |
1238 | * Set tx hold and check adc test register | 1238 | * Set TX hold and check ADC test register |
1239 | */ | 1239 | */ |
1240 | phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); | 1240 | phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); |
1241 | ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); | 1241 | ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); |
@@ -1254,15 +1254,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1254 | * | 1254 | * |
1255 | * This method is used to calibrate some static offsets | 1255 | * This method is used to calibrate some static offsets |
1256 | * used together with on-the fly I/Q calibration (the | 1256 | * used together with on-the fly I/Q calibration (the |
1257 | * one performed via ath5k_hw_phy_calibrate), that doesn't | 1257 | * one performed via ath5k_hw_phy_calibrate), which doesn't |
1258 | * interrupt rx path. | 1258 | * interrupt rx path. |
1259 | * | 1259 | * |
1260 | * While rx path is re-routed to the power detector we also | 1260 | * While rx path is re-routed to the power detector we also |
1261 | * start a noise floor calibration, to measure the | 1261 | * start a noise floor calibration to measure the |
1262 | * card's noise floor (the noise we measure when we are not | 1262 | * card's noise floor (the noise we measure when we are not |
1263 | * transmiting or receiving anything). | 1263 | * transmitting or receiving anything). |
1264 | * | 1264 | * |
1265 | * If we are in a noisy environment AGC calibration may time | 1265 | * If we are in a noisy environment, AGC calibration may time |
1266 | * out and/or noise floor calibration might timeout. | 1266 | * out and/or noise floor calibration might timeout. |
1267 | */ | 1267 | */ |
1268 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | 1268 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, |
diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h index e50baff66175..3ac4cff4239d 100644 --- a/drivers/net/wireless/ath/ath5k/rfbuffer.h +++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h | |||
@@ -25,10 +25,10 @@ | |||
25 | * | 25 | * |
26 | * We don't write on those registers directly but | 26 | * We don't write on those registers directly but |
27 | * we send a data packet on the chip, using a special register, | 27 | * we send a data packet on the chip, using a special register, |
28 | * that holds all the settings we need. After we 've sent the | 28 | * that holds all the settings we need. After we've sent the |
29 | * data packet, we write on another special register to notify hw | 29 | * data packet, we write on another special register to notify hw |
30 | * to apply the settings. This is done so that control registers | 30 | * to apply the settings. This is done so that control registers |
31 | * can be dynamicaly programmed during operation and the settings | 31 | * can be dynamically programmed during operation and the settings |
32 | * are applied faster on the hw. | 32 | * are applied faster on the hw. |
33 | * | 33 | * |
34 | * We call each data packet an "RF Bank" and all the data we write | 34 | * We call each data packet an "RF Bank" and all the data we write |