diff options
| author | David S. Miller <davem@davemloft.net> | 2010-10-29 15:23:15 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-10-29 15:23:15 -0400 |
| commit | a4765fa7bfb92d5b9de19a503674b6624f95a7ae (patch) | |
| tree | 27fa2b40b2fb4843043cc1583cd139844ee3f5fe | |
| parent | 089282fb028198169a0f62f8f833ab6d06bdbb3c (diff) | |
| parent | 9f2a0fac625bcef9c579bcf0b0c904ab1a56e7c4 (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/attach.c | 17 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/hif_usb.c | 10 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 31 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/rc.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 15 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 18 | ||||
| -rw-r--r-- | drivers/net/wireless/b43/sdio.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/libertas/if_sdio.c | 32 | ||||
| -rw-r--r-- | net/mac80211/debugfs_key.c | 6 | ||||
| -rw-r--r-- | net/mac80211/main.c | 5 |
11 files changed, 102 insertions, 38 deletions
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index cd0b14a0a93a..fbe8aca975d8 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
| @@ -139,12 +139,12 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
| 139 | /* Fill the ath5k_hw struct with the needed functions */ | 139 | /* Fill the ath5k_hw struct with the needed functions */ |
| 140 | ret = ath5k_hw_init_desc_functions(ah); | 140 | ret = ath5k_hw_init_desc_functions(ah); |
| 141 | if (ret) | 141 | if (ret) |
| 142 | goto err_free; | 142 | goto err; |
| 143 | 143 | ||
| 144 | /* Bring device out of sleep and reset its units */ | 144 | /* Bring device out of sleep and reset its units */ |
| 145 | ret = ath5k_hw_nic_wakeup(ah, 0, true); | 145 | ret = ath5k_hw_nic_wakeup(ah, 0, true); |
| 146 | if (ret) | 146 | if (ret) |
| 147 | goto err_free; | 147 | goto err; |
| 148 | 148 | ||
| 149 | /* Get MAC, PHY and RADIO revisions */ | 149 | /* Get MAC, PHY and RADIO revisions */ |
| 150 | ah->ah_mac_srev = srev; | 150 | ah->ah_mac_srev = srev; |
| @@ -234,7 +234,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
| 234 | } else { | 234 | } else { |
| 235 | ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); | 235 | ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); |
| 236 | ret = -ENODEV; | 236 | ret = -ENODEV; |
| 237 | goto err_free; | 237 | goto err; |
| 238 | } | 238 | } |
| 239 | } | 239 | } |
| 240 | 240 | ||
| @@ -244,7 +244,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
| 244 | (srev < AR5K_SREV_AR2425)) { | 244 | (srev < AR5K_SREV_AR2425)) { |
| 245 | ATH5K_ERR(sc, "Device not yet supported.\n"); | 245 | ATH5K_ERR(sc, "Device not yet supported.\n"); |
| 246 | ret = -ENODEV; | 246 | ret = -ENODEV; |
| 247 | goto err_free; | 247 | goto err; |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | /* | 250 | /* |
| @@ -252,7 +252,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
| 252 | */ | 252 | */ |
| 253 | ret = ath5k_hw_post(ah); | 253 | ret = ath5k_hw_post(ah); |
| 254 | if (ret) | 254 | if (ret) |
| 255 | goto err_free; | 255 | goto err; |
| 256 | 256 | ||
| 257 | /* Enable pci core retry fix on Hainan (5213A) and later chips */ | 257 | /* Enable pci core retry fix on Hainan (5213A) and later chips */ |
| 258 | if (srev >= AR5K_SREV_AR5213A) | 258 | if (srev >= AR5K_SREV_AR5213A) |
| @@ -265,7 +265,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
| 265 | ret = ath5k_eeprom_init(ah); | 265 | ret = ath5k_eeprom_init(ah); |
| 266 | if (ret) { | 266 | if (ret) { |
| 267 | ATH5K_ERR(sc, "unable to init EEPROM\n"); | 267 | ATH5K_ERR(sc, "unable to init EEPROM\n"); |
| 268 | goto err_free; | 268 | goto err; |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | ee = &ah->ah_capabilities.cap_eeprom; | 271 | ee = &ah->ah_capabilities.cap_eeprom; |
| @@ -307,7 +307,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
| 307 | if (ret) { | 307 | if (ret) { |
| 308 | ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n", | 308 | ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n", |
| 309 | sc->pdev->device); | 309 | sc->pdev->device); |
| 310 | goto err_free; | 310 | goto err; |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | /* Crypto settings */ | 313 | /* Crypto settings */ |
| @@ -341,8 +341,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
| 341 | ath5k_hw_set_ledstate(ah, AR5K_LED_INIT); | 341 | ath5k_hw_set_ledstate(ah, AR5K_LED_INIT); |
| 342 | 342 | ||
| 343 | return 0; | 343 | return 0; |
| 344 | err_free: | 344 | err: |
| 345 | kfree(ah); | ||
| 346 | return ret; | 345 | return ret; |
| 347 | } | 346 | } |
| 348 | 347 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 973c919fdd27..9b8e7e3fcebd 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
| @@ -310,7 +310,7 @@ struct ath_rx { | |||
| 310 | u8 rxotherant; | 310 | u8 rxotherant; |
| 311 | u32 *rxlink; | 311 | u32 *rxlink; |
| 312 | unsigned int rxfilter; | 312 | unsigned int rxfilter; |
| 313 | spinlock_t rxflushlock; | 313 | spinlock_t pcu_lock; |
| 314 | spinlock_t rxbuflock; | 314 | spinlock_t rxbuflock; |
| 315 | struct list_head rxbuf; | 315 | struct list_head rxbuf; |
| 316 | struct ath_descdma rxdma; | 316 | struct ath_descdma rxdma; |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 728d904c74d7..6576f683dba0 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
| @@ -801,10 +801,16 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) | |||
| 801 | } | 801 | } |
| 802 | kfree(buf); | 802 | kfree(buf); |
| 803 | 803 | ||
| 804 | if ((hif_dev->device_id == 0x7010) || (hif_dev->device_id == 0x7015)) | 804 | switch (hif_dev->device_id) { |
| 805 | case 0x7010: | ||
| 806 | case 0x7015: | ||
| 807 | case 0x9018: | ||
| 805 | firm_offset = AR7010_FIRMWARE_TEXT; | 808 | firm_offset = AR7010_FIRMWARE_TEXT; |
| 806 | else | 809 | break; |
| 810 | default: | ||
| 807 | firm_offset = AR9271_FIRMWARE_TEXT; | 811 | firm_offset = AR9271_FIRMWARE_TEXT; |
| 812 | break; | ||
| 813 | } | ||
| 808 | 814 | ||
| 809 | /* | 815 | /* |
| 810 | * Issue FW download complete command to firmware. | 816 | * Issue FW download complete command to firmware. |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c6ec800d7a6b..b52f1cf8a603 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -241,6 +241,9 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
| 241 | */ | 241 | */ |
| 242 | ath9k_hw_set_interrupts(ah, 0); | 242 | ath9k_hw_set_interrupts(ah, 0); |
| 243 | ath_drain_all_txq(sc, false); | 243 | ath_drain_all_txq(sc, false); |
| 244 | |||
| 245 | spin_lock_bh(&sc->rx.pcu_lock); | ||
| 246 | |||
| 244 | stopped = ath_stoprecv(sc); | 247 | stopped = ath_stoprecv(sc); |
| 245 | 248 | ||
| 246 | /* XXX: do not flush receive queue here. We don't want | 249 | /* XXX: do not flush receive queue here. We don't want |
| @@ -268,6 +271,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
| 268 | "reset status %d\n", | 271 | "reset status %d\n", |
| 269 | channel->center_freq, r); | 272 | channel->center_freq, r); |
| 270 | spin_unlock_bh(&sc->sc_resetlock); | 273 | spin_unlock_bh(&sc->sc_resetlock); |
| 274 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
| 271 | goto ps_restore; | 275 | goto ps_restore; |
| 272 | } | 276 | } |
| 273 | spin_unlock_bh(&sc->sc_resetlock); | 277 | spin_unlock_bh(&sc->sc_resetlock); |
| @@ -276,9 +280,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
| 276 | ath_print(common, ATH_DBG_FATAL, | 280 | ath_print(common, ATH_DBG_FATAL, |
| 277 | "Unable to restart recv logic\n"); | 281 | "Unable to restart recv logic\n"); |
| 278 | r = -EIO; | 282 | r = -EIO; |
| 283 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
| 279 | goto ps_restore; | 284 | goto ps_restore; |
| 280 | } | 285 | } |
| 281 | 286 | ||
| 287 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
| 288 | |||
| 282 | ath_update_txpow(sc); | 289 | ath_update_txpow(sc); |
| 283 | ath9k_hw_set_interrupts(ah, ah->imask); | 290 | ath9k_hw_set_interrupts(ah, ah->imask); |
| 284 | 291 | ||
| @@ -613,7 +620,7 @@ void ath9k_tasklet(unsigned long data) | |||
| 613 | rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); | 620 | rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); |
| 614 | 621 | ||
| 615 | if (status & rxmask) { | 622 | if (status & rxmask) { |
| 616 | spin_lock_bh(&sc->rx.rxflushlock); | 623 | spin_lock_bh(&sc->rx.pcu_lock); |
| 617 | 624 | ||
| 618 | /* Check for high priority Rx first */ | 625 | /* Check for high priority Rx first */ |
| 619 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && | 626 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && |
| @@ -621,7 +628,7 @@ void ath9k_tasklet(unsigned long data) | |||
| 621 | ath_rx_tasklet(sc, 0, true); | 628 | ath_rx_tasklet(sc, 0, true); |
| 622 | 629 | ||
| 623 | ath_rx_tasklet(sc, 0, false); | 630 | ath_rx_tasklet(sc, 0, false); |
| 624 | spin_unlock_bh(&sc->rx.rxflushlock); | 631 | spin_unlock_bh(&sc->rx.pcu_lock); |
| 625 | } | 632 | } |
| 626 | 633 | ||
| 627 | if (status & ATH9K_INT_TX) { | 634 | if (status & ATH9K_INT_TX) { |
| @@ -876,6 +883,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 876 | if (!ah->curchan) | 883 | if (!ah->curchan) |
| 877 | ah->curchan = ath_get_curchannel(sc, sc->hw); | 884 | ah->curchan = ath_get_curchannel(sc, sc->hw); |
| 878 | 885 | ||
| 886 | spin_lock_bh(&sc->rx.pcu_lock); | ||
| 879 | spin_lock_bh(&sc->sc_resetlock); | 887 | spin_lock_bh(&sc->sc_resetlock); |
| 880 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); | 888 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); |
| 881 | if (r) { | 889 | if (r) { |
| @@ -890,8 +898,10 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 890 | if (ath_startrecv(sc) != 0) { | 898 | if (ath_startrecv(sc) != 0) { |
| 891 | ath_print(common, ATH_DBG_FATAL, | 899 | ath_print(common, ATH_DBG_FATAL, |
| 892 | "Unable to restart recv logic\n"); | 900 | "Unable to restart recv logic\n"); |
| 901 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
| 893 | return; | 902 | return; |
| 894 | } | 903 | } |
| 904 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
| 895 | 905 | ||
| 896 | if (sc->sc_flags & SC_OP_BEACONS) | 906 | if (sc->sc_flags & SC_OP_BEACONS) |
| 897 | ath_beacon_config(sc, NULL); /* restart beacons */ | 907 | ath_beacon_config(sc, NULL); /* restart beacons */ |
| @@ -930,6 +940,9 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 930 | ath9k_hw_set_interrupts(ah, 0); | 940 | ath9k_hw_set_interrupts(ah, 0); |
| 931 | 941 | ||
| 932 | ath_drain_all_txq(sc, false); /* clear pending tx frames */ | 942 | ath_drain_all_txq(sc, false); /* clear pending tx frames */ |
| 943 | |||
| 944 | spin_lock_bh(&sc->rx.pcu_lock); | ||
| 945 | |||
| 933 | ath_stoprecv(sc); /* turn off frame recv */ | 946 | ath_stoprecv(sc); /* turn off frame recv */ |
| 934 | ath_flushrecv(sc); /* flush recv queue */ | 947 | ath_flushrecv(sc); /* flush recv queue */ |
| 935 | 948 | ||
| @@ -947,6 +960,9 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 947 | spin_unlock_bh(&sc->sc_resetlock); | 960 | spin_unlock_bh(&sc->sc_resetlock); |
| 948 | 961 | ||
| 949 | ath9k_hw_phy_disable(ah); | 962 | ath9k_hw_phy_disable(ah); |
| 963 | |||
| 964 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
| 965 | |||
| 950 | ath9k_hw_configpcipowersave(ah, 1, 1); | 966 | ath9k_hw_configpcipowersave(ah, 1, 1); |
| 951 | ath9k_ps_restore(sc); | 967 | ath9k_ps_restore(sc); |
| 952 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | 968 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); |
| @@ -966,6 +982,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
| 966 | 982 | ||
| 967 | ath9k_hw_set_interrupts(ah, 0); | 983 | ath9k_hw_set_interrupts(ah, 0); |
| 968 | ath_drain_all_txq(sc, retry_tx); | 984 | ath_drain_all_txq(sc, retry_tx); |
| 985 | |||
| 986 | spin_lock_bh(&sc->rx.pcu_lock); | ||
| 987 | |||
| 969 | ath_stoprecv(sc); | 988 | ath_stoprecv(sc); |
| 970 | ath_flushrecv(sc); | 989 | ath_flushrecv(sc); |
| 971 | 990 | ||
| @@ -980,6 +999,8 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
| 980 | ath_print(common, ATH_DBG_FATAL, | 999 | ath_print(common, ATH_DBG_FATAL, |
| 981 | "Unable to start recv logic\n"); | 1000 | "Unable to start recv logic\n"); |
| 982 | 1001 | ||
| 1002 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
| 1003 | |||
| 983 | /* | 1004 | /* |
| 984 | * We may be doing a reset in response to a request | 1005 | * We may be doing a reset in response to a request |
| 985 | * that changes the channel so update any state that | 1006 | * that changes the channel so update any state that |
| @@ -1142,6 +1163,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
| 1142 | * be followed by initialization of the appropriate bits | 1163 | * be followed by initialization of the appropriate bits |
| 1143 | * and then setup of the interrupt mask. | 1164 | * and then setup of the interrupt mask. |
| 1144 | */ | 1165 | */ |
| 1166 | spin_lock_bh(&sc->rx.pcu_lock); | ||
| 1145 | spin_lock_bh(&sc->sc_resetlock); | 1167 | spin_lock_bh(&sc->sc_resetlock); |
| 1146 | r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); | 1168 | r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); |
| 1147 | if (r) { | 1169 | if (r) { |
| @@ -1150,6 +1172,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
| 1150 | "(freq %u MHz)\n", r, | 1172 | "(freq %u MHz)\n", r, |
| 1151 | curchan->center_freq); | 1173 | curchan->center_freq); |
| 1152 | spin_unlock_bh(&sc->sc_resetlock); | 1174 | spin_unlock_bh(&sc->sc_resetlock); |
| 1175 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
| 1153 | goto mutex_unlock; | 1176 | goto mutex_unlock; |
| 1154 | } | 1177 | } |
| 1155 | spin_unlock_bh(&sc->sc_resetlock); | 1178 | spin_unlock_bh(&sc->sc_resetlock); |
| @@ -1171,8 +1194,10 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
| 1171 | ath_print(common, ATH_DBG_FATAL, | 1194 | ath_print(common, ATH_DBG_FATAL, |
| 1172 | "Unable to start recv logic\n"); | 1195 | "Unable to start recv logic\n"); |
| 1173 | r = -EIO; | 1196 | r = -EIO; |
| 1197 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
| 1174 | goto mutex_unlock; | 1198 | goto mutex_unlock; |
| 1175 | } | 1199 | } |
| 1200 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
| 1176 | 1201 | ||
| 1177 | /* Setup our intr mask. */ | 1202 | /* Setup our intr mask. */ |
| 1178 | ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | | 1203 | ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | |
| @@ -1371,12 +1396,14 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
| 1371 | * before setting the invalid flag. */ | 1396 | * before setting the invalid flag. */ |
| 1372 | ath9k_hw_set_interrupts(ah, 0); | 1397 | ath9k_hw_set_interrupts(ah, 0); |
| 1373 | 1398 | ||
| 1399 | spin_lock_bh(&sc->rx.pcu_lock); | ||
| 1374 | if (!(sc->sc_flags & SC_OP_INVALID)) { | 1400 | if (!(sc->sc_flags & SC_OP_INVALID)) { |
| 1375 | ath_drain_all_txq(sc, false); | 1401 | ath_drain_all_txq(sc, false); |
| 1376 | ath_stoprecv(sc); | 1402 | ath_stoprecv(sc); |
| 1377 | ath9k_hw_phy_disable(ah); | 1403 | ath9k_hw_phy_disable(ah); |
| 1378 | } else | 1404 | } else |
| 1379 | sc->rx.rxlink = NULL; | 1405 | sc->rx.rxlink = NULL; |
| 1406 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
| 1380 | 1407 | ||
| 1381 | /* disable HAL and put h/w to sleep */ | 1408 | /* disable HAL and put h/w to sleep */ |
| 1382 | ath9k_hw_disable(ah); | 1409 | ath9k_hw_disable(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 0cee90cf8dc9..89978d71617f 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
| @@ -527,7 +527,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, | |||
| 527 | for (i = 0; i < rateset->rs_nrates; i++) { | 527 | for (i = 0; i < rateset->rs_nrates; i++) { |
| 528 | for (j = 0; j < rate_table->rate_cnt; j++) { | 528 | for (j = 0; j < rate_table->rate_cnt; j++) { |
| 529 | u32 phy = rate_table->info[j].phy; | 529 | u32 phy = rate_table->info[j].phy; |
| 530 | u16 rate_flags = rate_table->info[i].rate_flags; | 530 | u16 rate_flags = rate_table->info[j].rate_flags; |
| 531 | u8 rate = rateset->rs_rates[i]; | 531 | u8 rate = rateset->rs_rates[i]; |
| 532 | u8 dot11rate = rate_table->info[j].dot11rate; | 532 | u8 dot11rate = rate_table->info[j].dot11rate; |
| 533 | 533 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index fe73fc50082a..fddb0129bb57 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
| @@ -297,19 +297,17 @@ static void ath_edma_start_recv(struct ath_softc *sc) | |||
| 297 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP, | 297 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP, |
| 298 | sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize); | 298 | sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize); |
| 299 | 299 | ||
| 300 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
| 301 | |||
| 302 | ath_opmode_init(sc); | 300 | ath_opmode_init(sc); |
| 303 | 301 | ||
| 304 | ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); | 302 | ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); |
| 303 | |||
| 304 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | static void ath_edma_stop_recv(struct ath_softc *sc) | 307 | static void ath_edma_stop_recv(struct ath_softc *sc) |
| 308 | { | 308 | { |
| 309 | spin_lock_bh(&sc->rx.rxbuflock); | ||
| 310 | ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP); | 309 | ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP); |
| 311 | ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP); | 310 | ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP); |
| 312 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
| 313 | } | 311 | } |
| 314 | 312 | ||
| 315 | int ath_rx_init(struct ath_softc *sc, int nbufs) | 313 | int ath_rx_init(struct ath_softc *sc, int nbufs) |
| @@ -319,7 +317,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
| 319 | struct ath_buf *bf; | 317 | struct ath_buf *bf; |
| 320 | int error = 0; | 318 | int error = 0; |
| 321 | 319 | ||
| 322 | spin_lock_init(&sc->rx.rxflushlock); | 320 | spin_lock_init(&sc->rx.pcu_lock); |
| 323 | sc->sc_flags &= ~SC_OP_RXFLUSH; | 321 | sc->sc_flags &= ~SC_OP_RXFLUSH; |
| 324 | spin_lock_init(&sc->rx.rxbuflock); | 322 | spin_lock_init(&sc->rx.rxbuflock); |
| 325 | 323 | ||
| @@ -506,10 +504,11 @@ int ath_startrecv(struct ath_softc *sc) | |||
| 506 | ath9k_hw_rxena(ah); | 504 | ath9k_hw_rxena(ah); |
| 507 | 505 | ||
| 508 | start_recv: | 506 | start_recv: |
| 509 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
| 510 | ath_opmode_init(sc); | 507 | ath_opmode_init(sc); |
| 511 | ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); | 508 | ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); |
| 512 | 509 | ||
| 510 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
| 511 | |||
| 513 | return 0; | 512 | return 0; |
| 514 | } | 513 | } |
| 515 | 514 | ||
| @@ -518,6 +517,7 @@ bool ath_stoprecv(struct ath_softc *sc) | |||
| 518 | struct ath_hw *ah = sc->sc_ah; | 517 | struct ath_hw *ah = sc->sc_ah; |
| 519 | bool stopped; | 518 | bool stopped; |
| 520 | 519 | ||
| 520 | spin_lock_bh(&sc->rx.rxbuflock); | ||
| 521 | ath9k_hw_stoppcurecv(ah); | 521 | ath9k_hw_stoppcurecv(ah); |
| 522 | ath9k_hw_setrxfilter(ah, 0); | 522 | ath9k_hw_setrxfilter(ah, 0); |
| 523 | stopped = ath9k_hw_stopdmarecv(ah); | 523 | stopped = ath9k_hw_stopdmarecv(ah); |
| @@ -526,19 +526,18 @@ bool ath_stoprecv(struct ath_softc *sc) | |||
| 526 | ath_edma_stop_recv(sc); | 526 | ath_edma_stop_recv(sc); |
| 527 | else | 527 | else |
| 528 | sc->rx.rxlink = NULL; | 528 | sc->rx.rxlink = NULL; |
| 529 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
| 529 | 530 | ||
| 530 | return stopped; | 531 | return stopped; |
| 531 | } | 532 | } |
| 532 | 533 | ||
| 533 | void ath_flushrecv(struct ath_softc *sc) | 534 | void ath_flushrecv(struct ath_softc *sc) |
| 534 | { | 535 | { |
| 535 | spin_lock_bh(&sc->rx.rxflushlock); | ||
| 536 | sc->sc_flags |= SC_OP_RXFLUSH; | 536 | sc->sc_flags |= SC_OP_RXFLUSH; |
| 537 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 537 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
| 538 | ath_rx_tasklet(sc, 1, true); | 538 | ath_rx_tasklet(sc, 1, true); |
| 539 | ath_rx_tasklet(sc, 1, false); | 539 | ath_rx_tasklet(sc, 1, false); |
| 540 | sc->sc_flags &= ~SC_OP_RXFLUSH; | 540 | sc->sc_flags &= ~SC_OP_RXFLUSH; |
| 541 | spin_unlock_bh(&sc->rx.rxflushlock); | ||
| 542 | } | 541 | } |
| 543 | 542 | ||
| 544 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) | 543 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 30ef2dfc1ed2..f2ade2402ce2 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -1089,15 +1089,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
| 1089 | txq->axq_tx_inprogress = false; | 1089 | txq->axq_tx_inprogress = false; |
| 1090 | spin_unlock_bh(&txq->axq_lock); | 1090 | spin_unlock_bh(&txq->axq_lock); |
| 1091 | 1091 | ||
| 1092 | /* flush any pending frames if aggregation is enabled */ | ||
| 1093 | if (sc->sc_flags & SC_OP_TXAGGR) { | ||
| 1094 | if (!retry_tx) { | ||
| 1095 | spin_lock_bh(&txq->axq_lock); | ||
| 1096 | ath_txq_drain_pending_buffers(sc, txq); | ||
| 1097 | spin_unlock_bh(&txq->axq_lock); | ||
| 1098 | } | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 1092 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
| 1102 | spin_lock_bh(&txq->axq_lock); | 1093 | spin_lock_bh(&txq->axq_lock); |
| 1103 | while (!list_empty(&txq->txq_fifo_pending)) { | 1094 | while (!list_empty(&txq->txq_fifo_pending)) { |
| @@ -1118,6 +1109,15 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
| 1118 | } | 1109 | } |
| 1119 | spin_unlock_bh(&txq->axq_lock); | 1110 | spin_unlock_bh(&txq->axq_lock); |
| 1120 | } | 1111 | } |
| 1112 | |||
| 1113 | /* flush any pending frames if aggregation is enabled */ | ||
| 1114 | if (sc->sc_flags & SC_OP_TXAGGR) { | ||
| 1115 | if (!retry_tx) { | ||
| 1116 | spin_lock_bh(&txq->axq_lock); | ||
| 1117 | ath_txq_drain_pending_buffers(sc, txq); | ||
| 1118 | spin_unlock_bh(&txq->axq_lock); | ||
| 1119 | } | ||
| 1120 | } | ||
| 1121 | } | 1121 | } |
| 1122 | 1122 | ||
| 1123 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | 1123 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) |
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index 45933cf8e8c2..9a55338d957f 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c | |||
| @@ -175,7 +175,9 @@ static void b43_sdio_remove(struct sdio_func *func) | |||
| 175 | struct b43_sdio *sdio = sdio_get_drvdata(func); | 175 | struct b43_sdio *sdio = sdio_get_drvdata(func); |
| 176 | 176 | ||
| 177 | ssb_bus_unregister(&sdio->ssb); | 177 | ssb_bus_unregister(&sdio->ssb); |
| 178 | sdio_claim_host(func); | ||
| 178 | sdio_disable_func(func); | 179 | sdio_disable_func(func); |
| 180 | sdio_release_host(func); | ||
| 179 | kfree(sdio); | 181 | kfree(sdio); |
| 180 | sdio_set_drvdata(func, NULL); | 182 | sdio_set_drvdata(func, NULL); |
| 181 | } | 183 | } |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 296fd00a5129..e5685dc317a8 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
| @@ -684,18 +684,40 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card) | |||
| 684 | 684 | ||
| 685 | lbs_deb_enter(LBS_DEB_SDIO); | 685 | lbs_deb_enter(LBS_DEB_SDIO); |
| 686 | 686 | ||
| 687 | /* | ||
| 688 | * Disable interrupts | ||
| 689 | */ | ||
| 690 | sdio_claim_host(card->func); | ||
| 691 | sdio_writeb(card->func, 0x00, IF_SDIO_H_INT_MASK, &ret); | ||
| 692 | sdio_release_host(card->func); | ||
| 693 | |||
| 687 | sdio_claim_host(card->func); | 694 | sdio_claim_host(card->func); |
| 688 | scratch = if_sdio_read_scratch(card, &ret); | 695 | scratch = if_sdio_read_scratch(card, &ret); |
| 689 | sdio_release_host(card->func); | 696 | sdio_release_host(card->func); |
| 690 | 697 | ||
| 698 | lbs_deb_sdio("firmware status = %#x\n", scratch); | ||
| 699 | lbs_deb_sdio("scratch ret = %d\n", ret); | ||
| 700 | |||
| 691 | if (ret) | 701 | if (ret) |
| 692 | goto out; | 702 | goto out; |
| 693 | 703 | ||
| 694 | lbs_deb_sdio("firmware status = %#x\n", scratch); | ||
| 695 | 704 | ||
| 705 | /* | ||
| 706 | * The manual clearly describes that FEDC is the right code to use | ||
| 707 | * to detect firmware presence, but for SD8686 it is not that simple. | ||
| 708 | * Scratch is also used to store the RX packet length, so we lose | ||
| 709 | * the FEDC value early on. So we use a non-zero check in order | ||
| 710 | * to validate firmware presence. | ||
| 711 | * Additionally, the SD8686 in the Gumstix always has the high scratch | ||
| 712 | * bit set, even when the firmware is not loaded. So we have to | ||
| 713 | * exclude that from the test. | ||
| 714 | */ | ||
| 696 | if (scratch == IF_SDIO_FIRMWARE_OK) { | 715 | if (scratch == IF_SDIO_FIRMWARE_OK) { |
| 697 | lbs_deb_sdio("firmware already loaded\n"); | 716 | lbs_deb_sdio("firmware already loaded\n"); |
| 698 | goto success; | 717 | goto success; |
| 718 | } else if ((card->model == MODEL_8686) && (scratch & 0x7fff)) { | ||
| 719 | lbs_deb_sdio("firmware may be running\n"); | ||
| 720 | goto success; | ||
| 699 | } | 721 | } |
| 700 | 722 | ||
| 701 | ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name, | 723 | ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name, |
| @@ -709,10 +731,14 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card) | |||
| 709 | if (ret) | 731 | if (ret) |
| 710 | goto out; | 732 | goto out; |
| 711 | 733 | ||
| 734 | lbs_deb_sdio("Helper firmware loaded\n"); | ||
| 735 | |||
| 712 | ret = if_sdio_prog_real(card, mainfw); | 736 | ret = if_sdio_prog_real(card, mainfw); |
| 713 | if (ret) | 737 | if (ret) |
| 714 | goto out; | 738 | goto out; |
| 715 | 739 | ||
| 740 | lbs_deb_sdio("Firmware loaded\n"); | ||
| 741 | |||
| 716 | success: | 742 | success: |
| 717 | sdio_claim_host(card->func); | 743 | sdio_claim_host(card->func); |
| 718 | sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE); | 744 | sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE); |
| @@ -1042,8 +1068,6 @@ static int if_sdio_probe(struct sdio_func *func, | |||
| 1042 | priv->exit_deep_sleep = if_sdio_exit_deep_sleep; | 1068 | priv->exit_deep_sleep = if_sdio_exit_deep_sleep; |
| 1043 | priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup; | 1069 | priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup; |
| 1044 | 1070 | ||
| 1045 | priv->fw_ready = 1; | ||
| 1046 | |||
| 1047 | sdio_claim_host(func); | 1071 | sdio_claim_host(func); |
| 1048 | 1072 | ||
| 1049 | /* | 1073 | /* |
| @@ -1064,6 +1088,8 @@ static int if_sdio_probe(struct sdio_func *func, | |||
| 1064 | if (ret) | 1088 | if (ret) |
| 1065 | goto reclaim; | 1089 | goto reclaim; |
| 1066 | 1090 | ||
| 1091 | priv->fw_ready = 1; | ||
| 1092 | |||
| 1067 | /* | 1093 | /* |
| 1068 | * FUNC_INIT is required for SD8688 WLAN/BT multiple functions | 1094 | * FUNC_INIT is required for SD8688 WLAN/BT multiple functions |
| 1069 | */ | 1095 | */ |
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 4aa47d074a79..1243d1db5c59 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
| @@ -203,9 +203,13 @@ static ssize_t key_key_read(struct file *file, char __user *userbuf, | |||
| 203 | size_t count, loff_t *ppos) | 203 | size_t count, loff_t *ppos) |
| 204 | { | 204 | { |
| 205 | struct ieee80211_key *key = file->private_data; | 205 | struct ieee80211_key *key = file->private_data; |
| 206 | int i, res, bufsize = 2 * key->conf.keylen + 2; | 206 | int i, bufsize = 2 * key->conf.keylen + 2; |
| 207 | char *buf = kmalloc(bufsize, GFP_KERNEL); | 207 | char *buf = kmalloc(bufsize, GFP_KERNEL); |
| 208 | char *p = buf; | 208 | char *p = buf; |
| 209 | ssize_t res; | ||
| 210 | |||
| 211 | if (!buf) | ||
| 212 | return -ENOMEM; | ||
| 209 | 213 | ||
| 210 | for (i = 0; i < key->conf.keylen; i++) | 214 | for (i = 0; i < key->conf.keylen; i++) |
| 211 | p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]); | 215 | p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 6b322fa681f5..107a0cbe52ac 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -677,10 +677,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 677 | /* | 677 | /* |
| 678 | * Calculate scan IE length -- we need this to alloc | 678 | * Calculate scan IE length -- we need this to alloc |
| 679 | * memory and to subtract from the driver limit. It | 679 | * memory and to subtract from the driver limit. It |
| 680 | * includes the (extended) supported rates and HT | 680 | * includes the DS Params, (extended) supported rates, and HT |
| 681 | * information -- SSID is the driver's responsibility. | 681 | * information -- SSID is the driver's responsibility. |
| 682 | */ | 682 | */ |
| 683 | local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */ | 683 | local->scan_ies_len = 4 + max_bitrates /* (ext) supp rates */ + |
| 684 | 3 /* DS Params */; | ||
| 684 | if (supp_ht) | 685 | if (supp_ht) |
| 685 | local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); | 686 | local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); |
| 686 | 687 | ||
