diff options
Diffstat (limited to 'drivers/net/wireless/ath')
| -rw-r--r-- | drivers/net/wireless/ath/ar5523/ar5523.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/phy.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/htc.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_init.c | 8 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_main.c | 63 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 12 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 8 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 70 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 15 |
11 files changed, 116 insertions, 74 deletions
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 8aa20df55e50..507d9a9ee69a 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c | |||
| @@ -1764,7 +1764,7 @@ static struct usb_device_id ar5523_id_table[] = { | |||
| 1764 | AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */ | 1764 | AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */ |
| 1765 | AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ | 1765 | AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ |
| 1766 | AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ | 1766 | AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ |
| 1767 | AR5523_DEVICE_UG(0x129b, 0x160c), /* Gigaset / USB stick 108 | 1767 | AR5523_DEVICE_UG(0x129b, 0x160b), /* Gigaset / USB stick 108 |
| 1768 | (CyberTAN Technology) */ | 1768 | (CyberTAN Technology) */ |
| 1769 | AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */ | 1769 | AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */ |
| 1770 | AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */ | 1770 | AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */ |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index d6bc7cb61bfb..1a2973b7acf2 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
| @@ -110,7 +110,7 @@ ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band) | |||
| 110 | ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); | 110 | ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); |
| 111 | 111 | ||
| 112 | if (ah->ah_version == AR5K_AR5210) { | 112 | if (ah->ah_version == AR5K_AR5210) { |
| 113 | srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf; | 113 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(256)) >> 28) & 0xf; |
| 114 | ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; | 114 | ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; |
| 115 | } else { | 115 | } else { |
| 116 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; | 116 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 25243cbc07f0..b8daff78b9d1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
| @@ -5065,6 +5065,10 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep, | |||
| 5065 | break; | 5065 | break; |
| 5066 | } | 5066 | } |
| 5067 | } | 5067 | } |
| 5068 | |||
| 5069 | if (is2GHz && !twiceMaxEdgePower) | ||
| 5070 | twiceMaxEdgePower = 60; | ||
| 5071 | |||
| 5068 | return twiceMaxEdgePower; | 5072 | return twiceMaxEdgePower; |
| 5069 | } | 5073 | } |
| 5070 | 5074 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 1cc13569b17b..1b6b4d0cfa97 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | |||
| @@ -57,7 +57,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
| 57 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, | 57 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, |
| 58 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 58 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 59 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | 59 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, |
| 60 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | 60 | {0x00009e20, 0x000003a5, 0x000003a5, 0x000003a5, 0x000003a5}, |
| 61 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | 61 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, |
| 62 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, | 62 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, |
| 63 | {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, | 63 | {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, |
| @@ -96,7 +96,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
| 96 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, | 96 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, |
| 97 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 97 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 98 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | 98 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, |
| 99 | {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, | 99 | {0x0000ae20, 0x000001a6, 0x000001a6, 0x000001aa, 0x000001aa}, |
| 100 | {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, | 100 | {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, |
| 101 | }; | 101 | }; |
| 102 | 102 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 58da3468d1f0..99a203174f45 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
| @@ -262,6 +262,8 @@ enum tid_aggr_state { | |||
| 262 | struct ath9k_htc_sta { | 262 | struct ath9k_htc_sta { |
| 263 | u8 index; | 263 | u8 index; |
| 264 | enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID]; | 264 | enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID]; |
| 265 | struct work_struct rc_update_work; | ||
| 266 | struct ath9k_htc_priv *htc_priv; | ||
| 265 | }; | 267 | }; |
| 266 | 268 | ||
| 267 | #define ATH9K_HTC_RXBUF 256 | 269 | #define ATH9K_HTC_RXBUF 256 |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index f4e1de20d99c..c57d6b859c04 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
| @@ -34,6 +34,10 @@ static int ath9k_htc_btcoex_enable; | |||
| 34 | module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444); | 34 | module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444); |
| 35 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); | 35 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); |
| 36 | 36 | ||
| 37 | static int ath9k_ps_enable; | ||
| 38 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | ||
| 39 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | ||
| 40 | |||
| 37 | #define CHAN2G(_freq, _idx) { \ | 41 | #define CHAN2G(_freq, _idx) { \ |
| 38 | .center_freq = (_freq), \ | 42 | .center_freq = (_freq), \ |
| 39 | .hw_value = (_idx), \ | 43 | .hw_value = (_idx), \ |
| @@ -725,12 +729,14 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
| 725 | IEEE80211_HW_SPECTRUM_MGMT | | 729 | IEEE80211_HW_SPECTRUM_MGMT | |
| 726 | IEEE80211_HW_HAS_RATE_CONTROL | | 730 | IEEE80211_HW_HAS_RATE_CONTROL | |
| 727 | IEEE80211_HW_RX_INCLUDES_FCS | | 731 | IEEE80211_HW_RX_INCLUDES_FCS | |
| 728 | IEEE80211_HW_SUPPORTS_PS | | ||
| 729 | IEEE80211_HW_PS_NULLFUNC_STACK | | 732 | IEEE80211_HW_PS_NULLFUNC_STACK | |
| 730 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 733 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
| 731 | IEEE80211_HW_MFP_CAPABLE | | 734 | IEEE80211_HW_MFP_CAPABLE | |
| 732 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | 735 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; |
| 733 | 736 | ||
| 737 | if (ath9k_ps_enable) | ||
| 738 | hw->flags |= IEEE80211_HW_SUPPORTS_PS; | ||
| 739 | |||
| 734 | hw->wiphy->interface_modes = | 740 | hw->wiphy->interface_modes = |
| 735 | BIT(NL80211_IFTYPE_STATION) | | 741 | BIT(NL80211_IFTYPE_STATION) | |
| 736 | BIT(NL80211_IFTYPE_ADHOC) | | 742 | BIT(NL80211_IFTYPE_ADHOC) | |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 608d739d1378..c9254a61ca52 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
| @@ -1270,18 +1270,50 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, | |||
| 1270 | mutex_unlock(&priv->mutex); | 1270 | mutex_unlock(&priv->mutex); |
| 1271 | } | 1271 | } |
| 1272 | 1272 | ||
| 1273 | static void ath9k_htc_sta_rc_update_work(struct work_struct *work) | ||
| 1274 | { | ||
| 1275 | struct ath9k_htc_sta *ista = | ||
| 1276 | container_of(work, struct ath9k_htc_sta, rc_update_work); | ||
| 1277 | struct ieee80211_sta *sta = | ||
| 1278 | container_of((void *)ista, struct ieee80211_sta, drv_priv); | ||
| 1279 | struct ath9k_htc_priv *priv = ista->htc_priv; | ||
| 1280 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
| 1281 | struct ath9k_htc_target_rate trate; | ||
| 1282 | |||
| 1283 | mutex_lock(&priv->mutex); | ||
| 1284 | ath9k_htc_ps_wakeup(priv); | ||
| 1285 | |||
| 1286 | memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); | ||
| 1287 | ath9k_htc_setup_rate(priv, sta, &trate); | ||
| 1288 | if (!ath9k_htc_send_rate_cmd(priv, &trate)) | ||
| 1289 | ath_dbg(common, CONFIG, | ||
| 1290 | "Supported rates for sta: %pM updated, rate caps: 0x%X\n", | ||
| 1291 | sta->addr, be32_to_cpu(trate.capflags)); | ||
| 1292 | else | ||
| 1293 | ath_dbg(common, CONFIG, | ||
| 1294 | "Unable to update supported rates for sta: %pM\n", | ||
| 1295 | sta->addr); | ||
| 1296 | |||
| 1297 | ath9k_htc_ps_restore(priv); | ||
| 1298 | mutex_unlock(&priv->mutex); | ||
| 1299 | } | ||
| 1300 | |||
| 1273 | static int ath9k_htc_sta_add(struct ieee80211_hw *hw, | 1301 | static int ath9k_htc_sta_add(struct ieee80211_hw *hw, |
| 1274 | struct ieee80211_vif *vif, | 1302 | struct ieee80211_vif *vif, |
| 1275 | struct ieee80211_sta *sta) | 1303 | struct ieee80211_sta *sta) |
| 1276 | { | 1304 | { |
| 1277 | struct ath9k_htc_priv *priv = hw->priv; | 1305 | struct ath9k_htc_priv *priv = hw->priv; |
| 1306 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
| 1278 | int ret; | 1307 | int ret; |
| 1279 | 1308 | ||
| 1280 | mutex_lock(&priv->mutex); | 1309 | mutex_lock(&priv->mutex); |
| 1281 | ath9k_htc_ps_wakeup(priv); | 1310 | ath9k_htc_ps_wakeup(priv); |
| 1282 | ret = ath9k_htc_add_station(priv, vif, sta); | 1311 | ret = ath9k_htc_add_station(priv, vif, sta); |
| 1283 | if (!ret) | 1312 | if (!ret) { |
| 1313 | INIT_WORK(&ista->rc_update_work, ath9k_htc_sta_rc_update_work); | ||
| 1314 | ista->htc_priv = priv; | ||
| 1284 | ath9k_htc_init_rate(priv, sta); | 1315 | ath9k_htc_init_rate(priv, sta); |
| 1316 | } | ||
| 1285 | ath9k_htc_ps_restore(priv); | 1317 | ath9k_htc_ps_restore(priv); |
| 1286 | mutex_unlock(&priv->mutex); | 1318 | mutex_unlock(&priv->mutex); |
| 1287 | 1319 | ||
| @@ -1293,12 +1325,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, | |||
| 1293 | struct ieee80211_sta *sta) | 1325 | struct ieee80211_sta *sta) |
| 1294 | { | 1326 | { |
| 1295 | struct ath9k_htc_priv *priv = hw->priv; | 1327 | struct ath9k_htc_priv *priv = hw->priv; |
| 1296 | struct ath9k_htc_sta *ista; | 1328 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; |
| 1297 | int ret; | 1329 | int ret; |
| 1298 | 1330 | ||
| 1331 | cancel_work_sync(&ista->rc_update_work); | ||
| 1332 | |||
| 1299 | mutex_lock(&priv->mutex); | 1333 | mutex_lock(&priv->mutex); |
| 1300 | ath9k_htc_ps_wakeup(priv); | 1334 | ath9k_htc_ps_wakeup(priv); |
| 1301 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
| 1302 | htc_sta_drain(priv->htc, ista->index); | 1335 | htc_sta_drain(priv->htc, ista->index); |
| 1303 | ret = ath9k_htc_remove_station(priv, vif, sta); | 1336 | ret = ath9k_htc_remove_station(priv, vif, sta); |
| 1304 | ath9k_htc_ps_restore(priv); | 1337 | ath9k_htc_ps_restore(priv); |
| @@ -1311,28 +1344,12 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw, | |||
| 1311 | struct ieee80211_vif *vif, | 1344 | struct ieee80211_vif *vif, |
| 1312 | struct ieee80211_sta *sta, u32 changed) | 1345 | struct ieee80211_sta *sta, u32 changed) |
| 1313 | { | 1346 | { |
| 1314 | struct ath9k_htc_priv *priv = hw->priv; | 1347 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; |
| 1315 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
| 1316 | struct ath9k_htc_target_rate trate; | ||
| 1317 | |||
| 1318 | mutex_lock(&priv->mutex); | ||
| 1319 | ath9k_htc_ps_wakeup(priv); | ||
| 1320 | 1348 | ||
| 1321 | if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { | 1349 | if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED)) |
| 1322 | memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); | 1350 | return; |
| 1323 | ath9k_htc_setup_rate(priv, sta, &trate); | ||
| 1324 | if (!ath9k_htc_send_rate_cmd(priv, &trate)) | ||
| 1325 | ath_dbg(common, CONFIG, | ||
| 1326 | "Supported rates for sta: %pM updated, rate caps: 0x%X\n", | ||
| 1327 | sta->addr, be32_to_cpu(trate.capflags)); | ||
| 1328 | else | ||
| 1329 | ath_dbg(common, CONFIG, | ||
| 1330 | "Unable to update supported rates for sta: %pM\n", | ||
| 1331 | sta->addr); | ||
| 1332 | } | ||
| 1333 | 1351 | ||
| 1334 | ath9k_htc_ps_restore(priv); | 1352 | schedule_work(&ista->rc_update_work); |
| 1335 | mutex_unlock(&priv->mutex); | ||
| 1336 | } | 1353 | } |
| 1337 | 1354 | ||
| 1338 | static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, | 1355 | static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index fbf43c05713f..9078a6c5a74e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -1316,7 +1316,7 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
| 1316 | if (AR_SREV_9300_20_OR_LATER(ah)) | 1316 | if (AR_SREV_9300_20_OR_LATER(ah)) |
| 1317 | udelay(50); | 1317 | udelay(50); |
| 1318 | else if (AR_SREV_9100(ah)) | 1318 | else if (AR_SREV_9100(ah)) |
| 1319 | udelay(10000); | 1319 | mdelay(10); |
| 1320 | else | 1320 | else |
| 1321 | udelay(100); | 1321 | udelay(100); |
| 1322 | 1322 | ||
| @@ -1534,7 +1534,7 @@ EXPORT_SYMBOL(ath9k_hw_check_nav); | |||
| 1534 | bool ath9k_hw_check_alive(struct ath_hw *ah) | 1534 | bool ath9k_hw_check_alive(struct ath_hw *ah) |
| 1535 | { | 1535 | { |
| 1536 | int count = 50; | 1536 | int count = 50; |
| 1537 | u32 reg; | 1537 | u32 reg, last_val; |
| 1538 | 1538 | ||
| 1539 | if (AR_SREV_9300(ah)) | 1539 | if (AR_SREV_9300(ah)) |
| 1540 | return !ath9k_hw_detect_mac_hang(ah); | 1540 | return !ath9k_hw_detect_mac_hang(ah); |
| @@ -1542,9 +1542,14 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) | |||
| 1542 | if (AR_SREV_9285_12_OR_LATER(ah)) | 1542 | if (AR_SREV_9285_12_OR_LATER(ah)) |
| 1543 | return true; | 1543 | return true; |
| 1544 | 1544 | ||
| 1545 | last_val = REG_READ(ah, AR_OBS_BUS_1); | ||
| 1545 | do { | 1546 | do { |
| 1546 | reg = REG_READ(ah, AR_OBS_BUS_1); | 1547 | reg = REG_READ(ah, AR_OBS_BUS_1); |
| 1548 | if (reg != last_val) | ||
| 1549 | return true; | ||
| 1547 | 1550 | ||
| 1551 | udelay(1); | ||
| 1552 | last_val = reg; | ||
| 1548 | if ((reg & 0x7E7FFFEF) == 0x00702400) | 1553 | if ((reg & 0x7E7FFFEF) == 0x00702400) |
| 1549 | continue; | 1554 | continue; |
| 1550 | 1555 | ||
| @@ -2051,9 +2056,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) | |||
| 2051 | 2056 | ||
| 2052 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | 2057 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, |
| 2053 | AR_RTC_FORCE_WAKE_EN); | 2058 | AR_RTC_FORCE_WAKE_EN); |
| 2054 | |||
| 2055 | if (AR_SREV_9100(ah)) | 2059 | if (AR_SREV_9100(ah)) |
| 2056 | udelay(10000); | 2060 | mdelay(10); |
| 2057 | else | 2061 | else |
| 2058 | udelay(50); | 2062 | udelay(50); |
| 2059 | 2063 | ||
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index c36de303c8f3..1fc2e5a26b52 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
| @@ -57,6 +57,10 @@ static int ath9k_bt_ant_diversity; | |||
| 57 | module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444); | 57 | module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444); |
| 58 | MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity"); | 58 | MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity"); |
| 59 | 59 | ||
| 60 | static int ath9k_ps_enable; | ||
| 61 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | ||
| 62 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | ||
| 63 | |||
| 60 | bool is_ath9k_unloaded; | 64 | bool is_ath9k_unloaded; |
| 61 | /* We use the hw_value as an index into our private channel structure */ | 65 | /* We use the hw_value as an index into our private channel structure */ |
| 62 | 66 | ||
| @@ -903,13 +907,15 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 903 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 907 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
| 904 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 908 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
| 905 | IEEE80211_HW_SIGNAL_DBM | | 909 | IEEE80211_HW_SIGNAL_DBM | |
| 906 | IEEE80211_HW_SUPPORTS_PS | | ||
| 907 | IEEE80211_HW_PS_NULLFUNC_STACK | | 910 | IEEE80211_HW_PS_NULLFUNC_STACK | |
| 908 | IEEE80211_HW_SPECTRUM_MGMT | | 911 | IEEE80211_HW_SPECTRUM_MGMT | |
| 909 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 912 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
| 910 | IEEE80211_HW_SUPPORTS_RC_TABLE | | 913 | IEEE80211_HW_SUPPORTS_RC_TABLE | |
| 911 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; | 914 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; |
| 912 | 915 | ||
| 916 | if (ath9k_ps_enable) | ||
| 917 | hw->flags |= IEEE80211_HW_SUPPORTS_PS; | ||
| 918 | |||
| 913 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | 919 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { |
| 914 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | 920 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; |
| 915 | 921 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index a0ebdd000fc2..82e340d3ec60 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
| @@ -732,11 +732,18 @@ static struct ath_rxbuf *ath_get_next_rx_buf(struct ath_softc *sc, | |||
| 732 | return NULL; | 732 | return NULL; |
| 733 | 733 | ||
| 734 | /* | 734 | /* |
| 735 | * mark descriptor as zero-length and set the 'more' | 735 | * Re-check previous descriptor, in case it has been filled |
| 736 | * flag to ensure that both buffers get discarded | 736 | * in the mean time. |
| 737 | */ | 737 | */ |
| 738 | rs->rs_datalen = 0; | 738 | ret = ath9k_hw_rxprocdesc(ah, ds, rs); |
| 739 | rs->rs_more = true; | 739 | if (ret == -EINPROGRESS) { |
| 740 | /* | ||
| 741 | * mark descriptor as zero-length and set the 'more' | ||
| 742 | * flag to ensure that both buffers get discarded | ||
| 743 | */ | ||
| 744 | rs->rs_datalen = 0; | ||
| 745 | rs->rs_more = true; | ||
| 746 | } | ||
| 740 | } | 747 | } |
| 741 | 748 | ||
| 742 | list_del(&bf->list); | 749 | list_del(&bf->list); |
| @@ -985,32 +992,32 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 985 | struct ath_common *common = ath9k_hw_common(ah); | 992 | struct ath_common *common = ath9k_hw_common(ah); |
| 986 | struct ieee80211_hdr *hdr; | 993 | struct ieee80211_hdr *hdr; |
| 987 | bool discard_current = sc->rx.discard_next; | 994 | bool discard_current = sc->rx.discard_next; |
| 988 | int ret = 0; | ||
| 989 | 995 | ||
| 990 | /* | 996 | /* |
| 991 | * Discard corrupt descriptors which are marked in | 997 | * Discard corrupt descriptors which are marked in |
| 992 | * ath_get_next_rx_buf(). | 998 | * ath_get_next_rx_buf(). |
| 993 | */ | 999 | */ |
| 994 | sc->rx.discard_next = rx_stats->rs_more; | ||
| 995 | if (discard_current) | 1000 | if (discard_current) |
| 996 | return -EINVAL; | 1001 | goto corrupt; |
| 1002 | |||
| 1003 | sc->rx.discard_next = false; | ||
| 997 | 1004 | ||
| 998 | /* | 1005 | /* |
| 999 | * Discard zero-length packets. | 1006 | * Discard zero-length packets. |
| 1000 | */ | 1007 | */ |
| 1001 | if (!rx_stats->rs_datalen) { | 1008 | if (!rx_stats->rs_datalen) { |
| 1002 | RX_STAT_INC(rx_len_err); | 1009 | RX_STAT_INC(rx_len_err); |
| 1003 | return -EINVAL; | 1010 | goto corrupt; |
| 1004 | } | 1011 | } |
| 1005 | 1012 | ||
| 1006 | /* | 1013 | /* |
| 1007 | * rs_status follows rs_datalen so if rs_datalen is too large | 1014 | * rs_status follows rs_datalen so if rs_datalen is too large |
| 1008 | * we can take a hint that hardware corrupted it, so ignore | 1015 | * we can take a hint that hardware corrupted it, so ignore |
| 1009 | * those frames. | 1016 | * those frames. |
| 1010 | */ | 1017 | */ |
| 1011 | if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) { | 1018 | if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) { |
| 1012 | RX_STAT_INC(rx_len_err); | 1019 | RX_STAT_INC(rx_len_err); |
| 1013 | return -EINVAL; | 1020 | goto corrupt; |
| 1014 | } | 1021 | } |
| 1015 | 1022 | ||
| 1016 | /* Only use status info from the last fragment */ | 1023 | /* Only use status info from the last fragment */ |
| @@ -1024,10 +1031,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1024 | * This is different from the other corrupt descriptor | 1031 | * This is different from the other corrupt descriptor |
| 1025 | * condition handled above. | 1032 | * condition handled above. |
| 1026 | */ | 1033 | */ |
| 1027 | if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) { | 1034 | if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) |
| 1028 | ret = -EINVAL; | 1035 | goto corrupt; |
| 1029 | goto exit; | ||
| 1030 | } | ||
| 1031 | 1036 | ||
| 1032 | hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len); | 1037 | hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len); |
| 1033 | 1038 | ||
| @@ -1043,18 +1048,15 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1043 | if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) | 1048 | if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) |
| 1044 | RX_STAT_INC(rx_spectral); | 1049 | RX_STAT_INC(rx_spectral); |
| 1045 | 1050 | ||
| 1046 | ret = -EINVAL; | 1051 | return -EINVAL; |
| 1047 | goto exit; | ||
| 1048 | } | 1052 | } |
| 1049 | 1053 | ||
| 1050 | /* | 1054 | /* |
| 1051 | * everything but the rate is checked here, the rate check is done | 1055 | * everything but the rate is checked here, the rate check is done |
| 1052 | * separately to avoid doing two lookups for a rate for each frame. | 1056 | * separately to avoid doing two lookups for a rate for each frame. |
| 1053 | */ | 1057 | */ |
| 1054 | if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) { | 1058 | if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) |
| 1055 | ret = -EINVAL; | 1059 | return -EINVAL; |
| 1056 | goto exit; | ||
| 1057 | } | ||
| 1058 | 1060 | ||
| 1059 | if (ath_is_mybeacon(common, hdr)) { | 1061 | if (ath_is_mybeacon(common, hdr)) { |
| 1060 | RX_STAT_INC(rx_beacons); | 1062 | RX_STAT_INC(rx_beacons); |
| @@ -1064,15 +1066,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1064 | /* | 1066 | /* |
| 1065 | * This shouldn't happen, but have a safety check anyway. | 1067 | * This shouldn't happen, but have a safety check anyway. |
| 1066 | */ | 1068 | */ |
| 1067 | if (WARN_ON(!ah->curchan)) { | 1069 | if (WARN_ON(!ah->curchan)) |
| 1068 | ret = -EINVAL; | 1070 | return -EINVAL; |
| 1069 | goto exit; | ||
| 1070 | } | ||
| 1071 | 1071 | ||
| 1072 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { | 1072 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) |
| 1073 | ret =-EINVAL; | 1073 | return -EINVAL; |
| 1074 | goto exit; | ||
| 1075 | } | ||
| 1076 | 1074 | ||
| 1077 | ath9k_process_rssi(common, hw, rx_stats, rx_status); | 1075 | ath9k_process_rssi(common, hw, rx_stats, rx_status); |
| 1078 | 1076 | ||
| @@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1087 | sc->rx.num_pkts++; | 1085 | sc->rx.num_pkts++; |
| 1088 | #endif | 1086 | #endif |
| 1089 | 1087 | ||
| 1090 | exit: | 1088 | return 0; |
| 1091 | sc->rx.discard_next = false; | 1089 | |
| 1092 | return ret; | 1090 | corrupt: |
| 1091 | sc->rx.discard_next = rx_stats->rs_more; | ||
| 1092 | return -EINVAL; | ||
| 1093 | } | 1093 | } |
| 1094 | 1094 | ||
| 1095 | static void ath9k_rx_skb_postprocess(struct ath_common *common, | 1095 | static void ath9k_rx_skb_postprocess(struct ath_common *common, |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 0a75e2f68c9d..55897d508a76 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -1444,14 +1444,16 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | |||
| 1444 | for (tidno = 0, tid = &an->tid[tidno]; | 1444 | for (tidno = 0, tid = &an->tid[tidno]; |
| 1445 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | 1445 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { |
| 1446 | 1446 | ||
| 1447 | if (!tid->sched) | ||
| 1448 | continue; | ||
| 1449 | |||
| 1450 | ac = tid->ac; | 1447 | ac = tid->ac; |
| 1451 | txq = ac->txq; | 1448 | txq = ac->txq; |
| 1452 | 1449 | ||
| 1453 | ath_txq_lock(sc, txq); | 1450 | ath_txq_lock(sc, txq); |
| 1454 | 1451 | ||
| 1452 | if (!tid->sched) { | ||
| 1453 | ath_txq_unlock(sc, txq); | ||
| 1454 | continue; | ||
| 1455 | } | ||
| 1456 | |||
| 1455 | buffered = ath_tid_has_buffered(tid); | 1457 | buffered = ath_tid_has_buffered(tid); |
| 1456 | 1458 | ||
| 1457 | tid->sched = false; | 1459 | tid->sched = false; |
| @@ -2061,7 +2063,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | |||
| 2061 | 2063 | ||
| 2062 | ATH_TXBUF_RESET(bf); | 2064 | ATH_TXBUF_RESET(bf); |
| 2063 | 2065 | ||
| 2064 | if (tid) { | 2066 | if (tid && ieee80211_is_data_present(hdr->frame_control)) { |
| 2065 | fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; | 2067 | fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; |
| 2066 | seqno = tid->seq_next; | 2068 | seqno = tid->seq_next; |
| 2067 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); | 2069 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); |
| @@ -2184,14 +2186,15 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 2184 | txq->stopped = true; | 2186 | txq->stopped = true; |
| 2185 | } | 2187 | } |
| 2186 | 2188 | ||
| 2189 | if (txctl->an && ieee80211_is_data_present(hdr->frame_control)) | ||
| 2190 | tid = ath_get_skb_tid(sc, txctl->an, skb); | ||
| 2191 | |||
| 2187 | if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) { | 2192 | if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) { |
| 2188 | ath_txq_unlock(sc, txq); | 2193 | ath_txq_unlock(sc, txq); |
| 2189 | txq = sc->tx.uapsdq; | 2194 | txq = sc->tx.uapsdq; |
| 2190 | ath_txq_lock(sc, txq); | 2195 | ath_txq_lock(sc, txq); |
| 2191 | } else if (txctl->an && | 2196 | } else if (txctl->an && |
| 2192 | ieee80211_is_data_present(hdr->frame_control)) { | 2197 | ieee80211_is_data_present(hdr->frame_control)) { |
| 2193 | tid = ath_get_skb_tid(sc, txctl->an, skb); | ||
| 2194 | |||
| 2195 | WARN_ON(tid->ac->txq != txctl->txq); | 2198 | WARN_ON(tid->ac->txq != txctl->txq); |
| 2196 | 2199 | ||
| 2197 | if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) | 2200 | if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) |
