diff options
Diffstat (limited to 'drivers/net/wireless')
45 files changed, 346 insertions, 209 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) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 3e991897d7ca..ddaa9efd053d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
| @@ -457,7 +457,6 @@ struct brcmf_sdio { | |||
| 457 | 457 | ||
| 458 | u8 tx_hdrlen; /* sdio bus header length for tx packet */ | 458 | u8 tx_hdrlen; /* sdio bus header length for tx packet */ |
| 459 | bool txglom; /* host tx glomming enable flag */ | 459 | bool txglom; /* host tx glomming enable flag */ |
| 460 | struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */ | ||
| 461 | u16 head_align; /* buffer pointer alignment */ | 460 | u16 head_align; /* buffer pointer alignment */ |
| 462 | u16 sgentry_align; /* scatter-gather buffer alignment */ | 461 | u16 sgentry_align; /* scatter-gather buffer alignment */ |
| 463 | }; | 462 | }; |
| @@ -1944,19 +1943,21 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus, | |||
| 1944 | if (lastfrm && chain_pad) | 1943 | if (lastfrm && chain_pad) |
| 1945 | tail_pad += blksize - chain_pad; | 1944 | tail_pad += blksize - chain_pad; |
| 1946 | if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { | 1945 | if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { |
| 1947 | pkt_pad = bus->txglom_sgpad; | 1946 | pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop + |
| 1948 | if (pkt_pad == NULL) | 1947 | bus->head_align); |
| 1949 | brcmu_pkt_buf_get_skb(tail_pad + tail_chop); | ||
| 1950 | if (pkt_pad == NULL) | 1948 | if (pkt_pad == NULL) |
| 1951 | return -ENOMEM; | 1949 | return -ENOMEM; |
| 1952 | ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad); | 1950 | ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad); |
| 1953 | if (unlikely(ret < 0)) | 1951 | if (unlikely(ret < 0)) { |
| 1952 | kfree_skb(pkt_pad); | ||
| 1954 | return ret; | 1953 | return ret; |
| 1954 | } | ||
| 1955 | memcpy(pkt_pad->data, | 1955 | memcpy(pkt_pad->data, |
| 1956 | pkt->data + pkt->len - tail_chop, | 1956 | pkt->data + pkt->len - tail_chop, |
| 1957 | tail_chop); | 1957 | tail_chop); |
| 1958 | *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; | 1958 | *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; |
| 1959 | skb_trim(pkt, pkt->len - tail_chop); | 1959 | skb_trim(pkt, pkt->len - tail_chop); |
| 1960 | skb_trim(pkt_pad, tail_pad + tail_chop); | ||
| 1960 | __skb_queue_after(pktq, pkt, pkt_pad); | 1961 | __skb_queue_after(pktq, pkt, pkt_pad); |
| 1961 | } else { | 1962 | } else { |
| 1962 | ntail = pkt->data_len + tail_pad - | 1963 | ntail = pkt->data_len + tail_pad - |
| @@ -2011,7 +2012,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, | |||
| 2011 | return ret; | 2012 | return ret; |
| 2012 | head_pad = (u16)ret; | 2013 | head_pad = (u16)ret; |
| 2013 | if (head_pad) | 2014 | if (head_pad) |
| 2014 | memset(pkt_next->data, 0, head_pad + bus->tx_hdrlen); | 2015 | memset(pkt_next->data + bus->tx_hdrlen, 0, head_pad); |
| 2015 | 2016 | ||
| 2016 | total_len += pkt_next->len; | 2017 | total_len += pkt_next->len; |
| 2017 | 2018 | ||
| @@ -3486,10 +3487,6 @@ static int brcmf_sdio_bus_preinit(struct device *dev) | |||
| 3486 | bus->txglom = false; | 3487 | bus->txglom = false; |
| 3487 | value = 1; | 3488 | value = 1; |
| 3488 | pad_size = bus->sdiodev->func[2]->cur_blksize << 1; | 3489 | pad_size = bus->sdiodev->func[2]->cur_blksize << 1; |
| 3489 | bus->txglom_sgpad = brcmu_pkt_buf_get_skb(pad_size); | ||
| 3490 | if (!bus->txglom_sgpad) | ||
| 3491 | brcmf_err("allocating txglom padding skb failed, reduced performance\n"); | ||
| 3492 | |||
| 3493 | err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", | 3490 | err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", |
| 3494 | &value, sizeof(u32)); | 3491 | &value, sizeof(u32)); |
| 3495 | if (err < 0) { | 3492 | if (err < 0) { |
| @@ -4053,7 +4050,6 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) | |||
| 4053 | brcmf_sdio_chip_detach(&bus->ci); | 4050 | brcmf_sdio_chip_detach(&bus->ci); |
| 4054 | } | 4051 | } |
| 4055 | 4052 | ||
| 4056 | brcmu_pkt_buf_free_skb(bus->txglom_sgpad); | ||
| 4057 | kfree(bus->rxbuf); | 4053 | kfree(bus->rxbuf); |
| 4058 | kfree(bus->hdrbuf); | 4054 | kfree(bus->hdrbuf); |
| 4059 | kfree(bus); | 4055 | kfree(bus); |
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index d36e252d2ccb..596525528f50 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c | |||
| @@ -147,7 +147,7 @@ static void ap_free_sta(struct ap_data *ap, struct sta_info *sta) | |||
| 147 | 147 | ||
| 148 | if (!sta->ap && sta->u.sta.challenge) | 148 | if (!sta->ap && sta->u.sta.challenge) |
| 149 | kfree(sta->u.sta.challenge); | 149 | kfree(sta->u.sta.challenge); |
| 150 | del_timer(&sta->timer); | 150 | del_timer_sync(&sta->timer); |
| 151 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ | 151 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ |
| 152 | 152 | ||
| 153 | kfree(sta); | 153 | kfree(sta); |
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index aa7ad3a7a69b..4e5c0f8c9496 100644 --- a/drivers/net/wireless/hostap/hostap_proc.c +++ b/drivers/net/wireless/hostap/hostap_proc.c | |||
| @@ -496,7 +496,7 @@ void hostap_init_proc(local_info_t *local) | |||
| 496 | 496 | ||
| 497 | void hostap_remove_proc(local_info_t *local) | 497 | void hostap_remove_proc(local_info_t *local) |
| 498 | { | 498 | { |
| 499 | remove_proc_subtree(local->ddev->name, hostap_proc); | 499 | proc_remove(local->proc); |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | 502 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index c24d1d3d55f6..73086c1629ca 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
| @@ -696,6 +696,24 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
| 696 | return ret; | 696 | return ret; |
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg) | ||
| 700 | { | ||
| 701 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | ||
| 702 | return false; | ||
| 703 | return true; | ||
| 704 | } | ||
| 705 | |||
| 706 | static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg) | ||
| 707 | { | ||
| 708 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | ||
| 709 | return false; | ||
| 710 | if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG) | ||
| 711 | return true; | ||
| 712 | |||
| 713 | /* disabled by default */ | ||
| 714 | return false; | ||
| 715 | } | ||
| 716 | |||
| 699 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | 717 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, |
| 700 | struct ieee80211_vif *vif, | 718 | struct ieee80211_vif *vif, |
| 701 | enum ieee80211_ampdu_mlme_action action, | 719 | enum ieee80211_ampdu_mlme_action action, |
| @@ -717,7 +735,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 717 | 735 | ||
| 718 | switch (action) { | 736 | switch (action) { |
| 719 | case IEEE80211_AMPDU_RX_START: | 737 | case IEEE80211_AMPDU_RX_START: |
| 720 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | 738 | if (!iwl_enable_rx_ampdu(priv->cfg)) |
| 721 | break; | 739 | break; |
| 722 | IWL_DEBUG_HT(priv, "start Rx\n"); | 740 | IWL_DEBUG_HT(priv, "start Rx\n"); |
| 723 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); | 741 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); |
| @@ -729,7 +747,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 729 | case IEEE80211_AMPDU_TX_START: | 747 | case IEEE80211_AMPDU_TX_START: |
| 730 | if (!priv->trans->ops->txq_enable) | 748 | if (!priv->trans->ops->txq_enable) |
| 731 | break; | 749 | break; |
| 732 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | 750 | if (!iwl_enable_tx_ampdu(priv->cfg)) |
| 733 | break; | 751 | break; |
| 734 | IWL_DEBUG_HT(priv, "start Tx\n"); | 752 | IWL_DEBUG_HT(priv, "start Tx\n"); |
| 735 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | 753 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index c0d070c5df5e..9cdd91cdf661 100644 --- a/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c | |||
| @@ -590,6 +590,7 @@ void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, | |||
| 590 | sizeof(priv->tid_data[sta_id][tid])); | 590 | sizeof(priv->tid_data[sta_id][tid])); |
| 591 | 591 | ||
| 592 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | 592 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; |
| 593 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; | ||
| 593 | 594 | ||
| 594 | priv->num_stations--; | 595 | priv->num_stations--; |
| 595 | 596 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index a6839dfcb82d..398dd096674c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
| @@ -1291,8 +1291,6 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
| 1291 | struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data; | 1291 | struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data; |
| 1292 | struct iwl_ht_agg *agg; | 1292 | struct iwl_ht_agg *agg; |
| 1293 | struct sk_buff_head reclaimed_skbs; | 1293 | struct sk_buff_head reclaimed_skbs; |
| 1294 | struct ieee80211_tx_info *info; | ||
| 1295 | struct ieee80211_hdr *hdr; | ||
| 1296 | struct sk_buff *skb; | 1294 | struct sk_buff *skb; |
| 1297 | int sta_id; | 1295 | int sta_id; |
| 1298 | int tid; | 1296 | int tid; |
| @@ -1379,22 +1377,28 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
| 1379 | freed = 0; | 1377 | freed = 0; |
| 1380 | 1378 | ||
| 1381 | skb_queue_walk(&reclaimed_skbs, skb) { | 1379 | skb_queue_walk(&reclaimed_skbs, skb) { |
| 1382 | hdr = (struct ieee80211_hdr *)skb->data; | 1380 | struct ieee80211_hdr *hdr = (void *)skb->data; |
| 1381 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 1383 | 1382 | ||
| 1384 | if (ieee80211_is_data_qos(hdr->frame_control)) | 1383 | if (ieee80211_is_data_qos(hdr->frame_control)) |
| 1385 | freed++; | 1384 | freed++; |
| 1386 | else | 1385 | else |
| 1387 | WARN_ON_ONCE(1); | 1386 | WARN_ON_ONCE(1); |
| 1388 | 1387 | ||
| 1389 | info = IEEE80211_SKB_CB(skb); | ||
| 1390 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); | 1388 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); |
| 1391 | 1389 | ||
| 1390 | memset(&info->status, 0, sizeof(info->status)); | ||
| 1391 | /* Packet was transmitted successfully, failures come as single | ||
| 1392 | * frames because before failing a frame the firmware transmits | ||
| 1393 | * it without aggregation at least once. | ||
| 1394 | */ | ||
| 1395 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
| 1396 | |||
| 1392 | if (freed == 1) { | 1397 | if (freed == 1) { |
| 1393 | /* this is the first skb we deliver in this batch */ | 1398 | /* this is the first skb we deliver in this batch */ |
| 1394 | /* put the rate scaling data there */ | 1399 | /* put the rate scaling data there */ |
| 1395 | info = IEEE80211_SKB_CB(skb); | 1400 | info = IEEE80211_SKB_CB(skb); |
| 1396 | memset(&info->status, 0, sizeof(info->status)); | 1401 | memset(&info->status, 0, sizeof(info->status)); |
| 1397 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
| 1398 | info->flags |= IEEE80211_TX_STAT_AMPDU; | 1402 | info->flags |= IEEE80211_TX_STAT_AMPDU; |
| 1399 | info->status.ampdu_ack_len = ba_resp->txed_2_done; | 1403 | info->status.ampdu_ack_len = ba_resp->txed_2_done; |
| 1400 | info->status.ampdu_len = ba_resp->txed; | 1404 | info->status.ampdu_len = ba_resp->txed; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index c3728163be46..75103554cd63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
| @@ -1286,7 +1286,7 @@ module_param_named(swcrypto, iwlwifi_mod_params.sw_crypto, int, S_IRUGO); | |||
| 1286 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); | 1286 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); |
| 1287 | module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); | 1287 | module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); |
| 1288 | MODULE_PARM_DESC(11n_disable, | 1288 | MODULE_PARM_DESC(11n_disable, |
| 1289 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); | 1289 | "disable 11n functionality, bitmap: 1: full, 2: disable agg TX, 4: disable agg RX, 8 enable agg TX"); |
| 1290 | module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, | 1290 | module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, |
| 1291 | int, S_IRUGO); | 1291 | int, S_IRUGO); |
| 1292 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); | 1292 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index 0a84ade7edac..b29075c3da8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h | |||
| @@ -79,9 +79,12 @@ enum iwl_power_level { | |||
| 79 | IWL_POWER_NUM | 79 | IWL_POWER_NUM |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | #define IWL_DISABLE_HT_ALL BIT(0) | 82 | enum iwl_disable_11n { |
| 83 | #define IWL_DISABLE_HT_TXAGG BIT(1) | 83 | IWL_DISABLE_HT_ALL = BIT(0), |
| 84 | #define IWL_DISABLE_HT_RXAGG BIT(2) | 84 | IWL_DISABLE_HT_TXAGG = BIT(1), |
| 85 | IWL_DISABLE_HT_RXAGG = BIT(2), | ||
| 86 | IWL_ENABLE_HT_TXAGG = BIT(3), | ||
| 87 | }; | ||
| 85 | 88 | ||
| 86 | /** | 89 | /** |
| 87 | * struct iwl_mod_params | 90 | * struct iwl_mod_params |
| @@ -90,7 +93,7 @@ enum iwl_power_level { | |||
| 90 | * | 93 | * |
| 91 | * @sw_crypto: using hardware encryption, default = 0 | 94 | * @sw_crypto: using hardware encryption, default = 0 |
| 92 | * @disable_11n: disable 11n capabilities, default = 0, | 95 | * @disable_11n: disable 11n capabilities, default = 0, |
| 93 | * use IWL_DISABLE_HT_* constants | 96 | * use IWL_[DIS,EN]ABLE_HT_* constants |
| 94 | * @amsdu_size_8K: enable 8K amsdu size, default = 0 | 97 | * @amsdu_size_8K: enable 8K amsdu size, default = 0 |
| 95 | * @restart_fw: restart firmware, default = 1 | 98 | * @restart_fw: restart firmware, default = 1 |
| 96 | * @wd_disable: enable stuck queue check, default = 0 | 99 | * @wd_disable: enable stuck queue check, default = 0 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index f06f4cbe1317..725e954d8475 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
| @@ -182,6 +182,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
| 182 | 182 | ||
| 183 | for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) { | 183 | for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) { |
| 184 | ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); | 184 | ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); |
| 185 | |||
| 186 | if (ch_idx >= NUM_2GHZ_CHANNELS && | ||
| 187 | !data->sku_cap_band_52GHz_enable) | ||
| 188 | ch_flags &= ~NVM_CHANNEL_VALID; | ||
| 189 | |||
| 185 | if (!(ch_flags & NVM_CHANNEL_VALID)) { | 190 | if (!(ch_flags & NVM_CHANNEL_VALID)) { |
| 186 | IWL_DEBUG_EEPROM(dev, | 191 | IWL_DEBUG_EEPROM(dev, |
| 187 | "Ch. %d Flags %x [%sGHz] - No traffic\n", | 192 | "Ch. %d Flags %x [%sGHz] - No traffic\n", |
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 76cde6ce6551..18a895a949d4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c | |||
| @@ -872,8 +872,11 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 872 | 872 | ||
| 873 | lockdep_assert_held(&mvm->mutex); | 873 | lockdep_assert_held(&mvm->mutex); |
| 874 | 874 | ||
| 875 | /* Rssi update while not associated ?! */ | 875 | /* |
| 876 | if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)) | 876 | * Rssi update while not associated - can happen since the statistics |
| 877 | * are handled asynchronously | ||
| 878 | */ | ||
| 879 | if (mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) | ||
| 877 | return; | 880 | return; |
| 878 | 881 | ||
| 879 | /* No BT - reports should be disabled */ | 882 | /* No BT - reports should be disabled */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 73cbba7424f2..9426905de6b2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
| @@ -504,6 +504,7 @@ struct iwl_scan_offload_profile { | |||
| 504 | * @match_notify: clients waiting for match found notification | 504 | * @match_notify: clients waiting for match found notification |
| 505 | * @pass_match: clients waiting for the results | 505 | * @pass_match: clients waiting for the results |
| 506 | * @active_clients: active clients bitmap - enum scan_framework_client | 506 | * @active_clients: active clients bitmap - enum scan_framework_client |
| 507 | * @any_beacon_notify: clients waiting for match notification without match | ||
| 507 | */ | 508 | */ |
| 508 | struct iwl_scan_offload_profile_cfg { | 509 | struct iwl_scan_offload_profile_cfg { |
| 509 | struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; | 510 | struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; |
| @@ -512,7 +513,8 @@ struct iwl_scan_offload_profile_cfg { | |||
| 512 | u8 match_notify; | 513 | u8 match_notify; |
| 513 | u8 pass_match; | 514 | u8 pass_match; |
| 514 | u8 active_clients; | 515 | u8 active_clients; |
| 515 | u8 reserved[3]; | 516 | u8 any_beacon_notify; |
| 517 | u8 reserved[2]; | ||
| 516 | } __packed; | 518 | } __packed; |
| 517 | 519 | ||
| 518 | /** | 520 | /** |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index c49b5073c251..c35b8661b395 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -246,7 +246,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
| 246 | else | 246 | else |
| 247 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 247 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
| 248 | 248 | ||
| 249 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) { | 249 | if (0 && mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) { |
| 250 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | 250 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; |
| 251 | hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; | 251 | hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; |
| 252 | hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES; | 252 | hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES; |
| @@ -328,6 +328,24 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, | |||
| 328 | ieee80211_free_txskb(hw, skb); | 328 | ieee80211_free_txskb(hw, skb); |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg) | ||
| 332 | { | ||
| 333 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | ||
| 334 | return false; | ||
| 335 | return true; | ||
| 336 | } | ||
| 337 | |||
| 338 | static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg) | ||
| 339 | { | ||
| 340 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | ||
| 341 | return false; | ||
| 342 | if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG) | ||
| 343 | return true; | ||
| 344 | |||
| 345 | /* enabled by default */ | ||
| 346 | return true; | ||
| 347 | } | ||
| 348 | |||
| 331 | static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | 349 | static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, |
| 332 | struct ieee80211_vif *vif, | 350 | struct ieee80211_vif *vif, |
| 333 | enum ieee80211_ampdu_mlme_action action, | 351 | enum ieee80211_ampdu_mlme_action action, |
| @@ -347,7 +365,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 347 | 365 | ||
| 348 | switch (action) { | 366 | switch (action) { |
| 349 | case IEEE80211_AMPDU_RX_START: | 367 | case IEEE80211_AMPDU_RX_START: |
| 350 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) { | 368 | if (!iwl_enable_rx_ampdu(mvm->cfg)) { |
| 351 | ret = -EINVAL; | 369 | ret = -EINVAL; |
| 352 | break; | 370 | break; |
| 353 | } | 371 | } |
| @@ -357,7 +375,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 357 | ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); | 375 | ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); |
| 358 | break; | 376 | break; |
| 359 | case IEEE80211_AMPDU_TX_START: | 377 | case IEEE80211_AMPDU_TX_START: |
| 360 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) { | 378 | if (!iwl_enable_tx_ampdu(mvm->cfg)) { |
| 361 | ret = -EINVAL; | 379 | ret = -EINVAL; |
| 362 | break; | 380 | break; |
| 363 | } | 381 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index e4ead86f06d6..2b0ba1fc3c82 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
| @@ -152,7 +152,7 @@ enum iwl_power_scheme { | |||
| 152 | IWL_POWER_SCHEME_LP | 152 | IWL_POWER_SCHEME_LP |
| 153 | }; | 153 | }; |
| 154 | 154 | ||
| 155 | #define IWL_CONN_MAX_LISTEN_INTERVAL 70 | 155 | #define IWL_CONN_MAX_LISTEN_INTERVAL 10 |
| 156 | #define IWL_UAPSD_AC_INFO (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\ | 156 | #define IWL_UAPSD_AC_INFO (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\ |
| 157 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\ | 157 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\ |
| 158 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\ | 158 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 0e0007960612..742afc429c94 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
| @@ -344,7 +344,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, | |||
| 344 | 344 | ||
| 345 | iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0); | 345 | iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0); |
| 346 | 346 | ||
| 347 | cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL); | 347 | cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL | |
| 348 | TX_CMD_FLG_BT_DIS); | ||
| 348 | cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; | 349 | cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; |
| 349 | cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); | 350 | cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); |
| 350 | cmd->tx_cmd.rate_n_flags = | 351 | cmd->tx_cmd.rate_n_flags = |
| @@ -807,6 +808,8 @@ int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, | |||
| 807 | profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN; | 808 | profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN; |
| 808 | profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN; | 809 | profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN; |
| 809 | profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN; | 810 | profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN; |
| 811 | if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len) | ||
| 812 | profile_cfg->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN; | ||
| 810 | 813 | ||
| 811 | for (i = 0; i < req->n_match_sets; i++) { | 814 | for (i = 0; i < req->n_match_sets; i++) { |
| 812 | profile = &profile_cfg->profiles[i]; | 815 | profile = &profile_cfg->profiles[i]; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index ec1812133235..3397f59cd4e4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
| @@ -652,7 +652,7 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 652 | { | 652 | { |
| 653 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 653 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| 654 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 654 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
| 655 | static const u8 *baddr = _baddr; | 655 | const u8 *baddr = _baddr; |
| 656 | 656 | ||
| 657 | lockdep_assert_held(&mvm->mutex); | 657 | lockdep_assert_held(&mvm->mutex); |
| 658 | 658 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 90378c217bc7..76ee486039d7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
| @@ -659,8 +659,14 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
| 659 | rcu_read_lock(); | 659 | rcu_read_lock(); |
| 660 | 660 | ||
| 661 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | 661 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); |
| 662 | /* | ||
| 663 | * sta can't be NULL otherwise it'd mean that the sta has been freed in | ||
| 664 | * the firmware while we still have packets for it in the Tx queues. | ||
| 665 | */ | ||
| 666 | if (WARN_ON_ONCE(!sta)) | ||
| 667 | goto out; | ||
| 662 | 668 | ||
| 663 | if (!IS_ERR_OR_NULL(sta)) { | 669 | if (!IS_ERR(sta)) { |
| 664 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | 670 | mvmsta = iwl_mvm_sta_from_mac80211(sta); |
| 665 | 671 | ||
| 666 | if (tid != IWL_TID_NON_QOS) { | 672 | if (tid != IWL_TID_NON_QOS) { |
| @@ -675,7 +681,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
| 675 | spin_unlock_bh(&mvmsta->lock); | 681 | spin_unlock_bh(&mvmsta->lock); |
| 676 | } | 682 | } |
| 677 | } else { | 683 | } else { |
| 678 | sta = NULL; | ||
| 679 | mvmsta = NULL; | 684 | mvmsta = NULL; |
| 680 | } | 685 | } |
| 681 | 686 | ||
| @@ -683,42 +688,38 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
| 683 | * If the txq is not an AMPDU queue, there is no chance we freed | 688 | * If the txq is not an AMPDU queue, there is no chance we freed |
| 684 | * several skbs. Check that out... | 689 | * several skbs. Check that out... |
| 685 | */ | 690 | */ |
| 686 | if (txq_id < mvm->first_agg_queue && !WARN_ON(skb_freed > 1) && | 691 | if (txq_id >= mvm->first_agg_queue) |
| 687 | atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) { | 692 | goto out; |
| 688 | if (mvmsta) { | 693 | |
| 689 | /* | 694 | /* We can't free more than one frame at once on a shared queue */ |
| 690 | * If there are no pending frames for this STA, notify | 695 | WARN_ON(skb_freed > 1); |
| 691 | * mac80211 that this station can go to sleep in its | 696 | |
| 692 | * STA table. | 697 | /* If we have still frames from this STA nothing to do here */ |
| 693 | */ | 698 | if (!atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) |
| 694 | if (mvmsta->vif->type == NL80211_IFTYPE_AP) | 699 | goto out; |
| 695 | ieee80211_sta_block_awake(mvm->hw, sta, false); | 700 | |
| 696 | /* | 701 | if (mvmsta && mvmsta->vif->type == NL80211_IFTYPE_AP) { |
| 697 | * We might very well have taken mvmsta pointer while | 702 | /* |
| 698 | * the station was being removed. The remove flow might | 703 | * If there are no pending frames for this STA, notify |
| 699 | * have seen a pending_frame (because we didn't take | 704 | * mac80211 that this station can go to sleep in its |
| 700 | * the lock) even if now the queues are drained. So make | 705 | * STA table. |
| 701 | * really sure now that this the station is not being | 706 | * If mvmsta is not NULL, sta is valid. |
| 702 | * removed. If it is, run the drain worker to remove it. | 707 | */ |
| 703 | */ | 708 | ieee80211_sta_block_awake(mvm->hw, sta, false); |
| 704 | spin_lock_bh(&mvmsta->lock); | ||
| 705 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | ||
| 706 | if (!sta || PTR_ERR(sta) == -EBUSY) { | ||
| 707 | /* | ||
| 708 | * Station disappeared in the meantime: | ||
| 709 | * so we are draining. | ||
| 710 | */ | ||
| 711 | set_bit(sta_id, mvm->sta_drained); | ||
| 712 | schedule_work(&mvm->sta_drained_wk); | ||
| 713 | } | ||
| 714 | spin_unlock_bh(&mvmsta->lock); | ||
| 715 | } else if (!mvmsta && PTR_ERR(sta) == -EBUSY) { | ||
| 716 | /* Tx response without STA, so we are draining */ | ||
| 717 | set_bit(sta_id, mvm->sta_drained); | ||
| 718 | schedule_work(&mvm->sta_drained_wk); | ||
| 719 | } | ||
| 720 | } | 709 | } |
| 721 | 710 | ||
| 711 | if (PTR_ERR(sta) == -EBUSY || PTR_ERR(sta) == -ENOENT) { | ||
| 712 | /* | ||
| 713 | * We are draining and this was the last packet - pre_rcu_remove | ||
| 714 | * has been called already. We might be after the | ||
| 715 | * synchronize_net already. | ||
| 716 | * Don't rely on iwl_mvm_rm_sta to see the empty Tx queues. | ||
| 717 | */ | ||
| 718 | set_bit(sta_id, mvm->sta_drained); | ||
| 719 | schedule_work(&mvm->sta_drained_wk); | ||
| 720 | } | ||
| 721 | |||
| 722 | out: | ||
| 722 | rcu_read_unlock(); | 723 | rcu_read_unlock(); |
| 723 | } | 724 | } |
| 724 | 725 | ||
| @@ -821,16 +822,12 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
| 821 | struct iwl_mvm_ba_notif *ba_notif = (void *)pkt->data; | 822 | struct iwl_mvm_ba_notif *ba_notif = (void *)pkt->data; |
| 822 | struct sk_buff_head reclaimed_skbs; | 823 | struct sk_buff_head reclaimed_skbs; |
| 823 | struct iwl_mvm_tid_data *tid_data; | 824 | struct iwl_mvm_tid_data *tid_data; |
| 824 | struct ieee80211_tx_info *info; | ||
| 825 | struct ieee80211_sta *sta; | 825 | struct ieee80211_sta *sta; |
| 826 | struct iwl_mvm_sta *mvmsta; | 826 | struct iwl_mvm_sta *mvmsta; |
| 827 | struct ieee80211_hdr *hdr; | ||
| 828 | struct sk_buff *skb; | 827 | struct sk_buff *skb; |
| 829 | int sta_id, tid, freed; | 828 | int sta_id, tid, freed; |
| 830 | |||
| 831 | /* "flow" corresponds to Tx queue */ | 829 | /* "flow" corresponds to Tx queue */ |
| 832 | u16 scd_flow = le16_to_cpu(ba_notif->scd_flow); | 830 | u16 scd_flow = le16_to_cpu(ba_notif->scd_flow); |
| 833 | |||
| 834 | /* "ssn" is start of block-ack Tx window, corresponds to index | 831 | /* "ssn" is start of block-ack Tx window, corresponds to index |
| 835 | * (in Tx queue's circular buffer) of first TFD/frame in window */ | 832 | * (in Tx queue's circular buffer) of first TFD/frame in window */ |
| 836 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_notif->scd_ssn); | 833 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_notif->scd_ssn); |
| @@ -887,22 +884,26 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
| 887 | freed = 0; | 884 | freed = 0; |
| 888 | 885 | ||
| 889 | skb_queue_walk(&reclaimed_skbs, skb) { | 886 | skb_queue_walk(&reclaimed_skbs, skb) { |
| 890 | hdr = (struct ieee80211_hdr *)skb->data; | 887 | struct ieee80211_hdr *hdr = (void *)skb->data; |
| 888 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 891 | 889 | ||
| 892 | if (ieee80211_is_data_qos(hdr->frame_control)) | 890 | if (ieee80211_is_data_qos(hdr->frame_control)) |
| 893 | freed++; | 891 | freed++; |
| 894 | else | 892 | else |
| 895 | WARN_ON_ONCE(1); | 893 | WARN_ON_ONCE(1); |
| 896 | 894 | ||
| 897 | info = IEEE80211_SKB_CB(skb); | ||
| 898 | iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); | 895 | iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); |
| 899 | 896 | ||
| 897 | memset(&info->status, 0, sizeof(info->status)); | ||
| 898 | /* Packet was transmitted successfully, failures come as single | ||
| 899 | * frames because before failing a frame the firmware transmits | ||
| 900 | * it without aggregation at least once. | ||
| 901 | */ | ||
| 902 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
| 903 | |||
| 900 | if (freed == 1) { | 904 | if (freed == 1) { |
| 901 | /* this is the first skb we deliver in this batch */ | 905 | /* this is the first skb we deliver in this batch */ |
| 902 | /* put the rate scaling data there */ | 906 | /* put the rate scaling data there */ |
| 903 | info = IEEE80211_SKB_CB(skb); | ||
| 904 | memset(&info->status, 0, sizeof(info->status)); | ||
| 905 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
| 906 | info->flags |= IEEE80211_TX_STAT_AMPDU; | 907 | info->flags |= IEEE80211_TX_STAT_AMPDU; |
| 907 | info->status.ampdu_ack_len = ba_notif->txed_2_done; | 908 | info->status.ampdu_ack_len = ba_notif->txed_2_done; |
| 908 | info->status.ampdu_len = ba_notif->txed; | 909 | info->status.ampdu_len = ba_notif->txed; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index a4a5e25623c3..86989df69356 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
| @@ -411,6 +411,8 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) | |||
| 411 | mvm->status, table.valid); | 411 | mvm->status, table.valid); |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version); | ||
| 415 | |||
| 414 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, | 416 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, |
| 415 | table.data1, table.data2, table.data3, | 417 | table.data1, table.data2, table.data3, |
| 416 | table.blink1, table.blink2, table.ilink1, | 418 | table.blink1, table.blink2, table.ilink1, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 3040924f5f3c..3872ead75488 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
| @@ -359,20 +359,24 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
| 359 | /* 7265 Series */ | 359 | /* 7265 Series */ |
| 360 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, | 360 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, |
| 361 | {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)}, | 361 | {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)}, |
| 362 | {IWL_PCI_DEVICE(0x095A, 0x5100, iwl7265_2ac_cfg)}, | ||
| 362 | {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)}, | 363 | {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)}, |
| 363 | {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)}, | 364 | {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_n_cfg)}, |
| 364 | {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)}, | 365 | {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)}, |
| 365 | {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)}, | 366 | {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)}, |
| 366 | {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2ac_cfg)}, | 367 | {IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)}, |
| 367 | {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, | 368 | {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, |
| 368 | {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)}, | 369 | {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)}, |
| 369 | {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, | 370 | {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, |
| 370 | {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)}, | 371 | {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)}, |
| 372 | {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)}, | ||
| 371 | {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, | 373 | {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, |
| 372 | {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, | 374 | {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, |
| 373 | {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, | 375 | {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, |
| 374 | {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, | 376 | {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, |
| 377 | {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)}, | ||
| 375 | {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, | 378 | {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, |
| 379 | {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)}, | ||
| 376 | {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, | 380 | {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, |
| 377 | {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, | 381 | {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, |
| 378 | {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, | 382 | {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 32f75007a825..cb6d189bc3e6 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
| @@ -621,7 +621,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
| 621 | id = *pos++; | 621 | id = *pos++; |
| 622 | elen = *pos++; | 622 | elen = *pos++; |
| 623 | left -= 2; | 623 | left -= 2; |
| 624 | if (elen > left || elen == 0) { | 624 | if (elen > left) { |
| 625 | lbs_deb_scan("scan response: invalid IE fmt\n"); | 625 | lbs_deb_scan("scan response: invalid IE fmt\n"); |
| 626 | goto done; | 626 | goto done; |
| 627 | } | 627 | } |
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c index 5e0eec4d71c7..5d9a8084665d 100644 --- a/drivers/net/wireless/mwifiex/11ac.c +++ b/drivers/net/wireless/mwifiex/11ac.c | |||
| @@ -189,8 +189,7 @@ int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv, | |||
| 189 | vht_cap->header.len = | 189 | vht_cap->header.len = |
| 190 | cpu_to_le16(sizeof(struct ieee80211_vht_cap)); | 190 | cpu_to_le16(sizeof(struct ieee80211_vht_cap)); |
| 191 | memcpy((u8 *)vht_cap + sizeof(struct mwifiex_ie_types_header), | 191 | memcpy((u8 *)vht_cap + sizeof(struct mwifiex_ie_types_header), |
| 192 | (u8 *)bss_desc->bcn_vht_cap + | 192 | (u8 *)bss_desc->bcn_vht_cap, |
| 193 | sizeof(struct ieee_types_header), | ||
| 194 | le16_to_cpu(vht_cap->header.len)); | 193 | le16_to_cpu(vht_cap->header.len)); |
| 195 | 194 | ||
| 196 | mwifiex_fill_vht_cap_tlv(priv, vht_cap, bss_desc->bss_band); | 195 | mwifiex_fill_vht_cap_tlv(priv, vht_cap, bss_desc->bss_band); |
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 6261f8c53d44..7db1a89fdd95 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c | |||
| @@ -308,8 +308,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | |||
| 308 | ht_cap->header.len = | 308 | ht_cap->header.len = |
| 309 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); | 309 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); |
| 310 | memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header), | 310 | memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header), |
| 311 | (u8 *) bss_desc->bcn_ht_cap + | 311 | (u8 *)bss_desc->bcn_ht_cap, |
| 312 | sizeof(struct ieee_types_header), | ||
| 313 | le16_to_cpu(ht_cap->header.len)); | 312 | le16_to_cpu(ht_cap->header.len)); |
| 314 | 313 | ||
| 315 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); | 314 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 4d79761b9c87..9d3d2758ec35 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
| @@ -748,7 +748,7 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev) | |||
| 748 | 748 | ||
| 749 | static u16 | 749 | static u16 |
| 750 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb, | 750 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb, |
| 751 | void *accel_priv) | 751 | void *accel_priv, select_queue_fallback_t fallback) |
| 752 | { | 752 | { |
| 753 | skb->priority = cfg80211_classify8021d(skb, NULL); | 753 | skb->priority = cfg80211_classify8021d(skb, NULL); |
| 754 | return mwifiex_1d_to_wmm_queue[skb->priority]; | 754 | return mwifiex_1d_to_wmm_queue[skb->priority]; |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 03688aa14e8a..7fe7b53fb17a 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
| @@ -1211,6 +1211,12 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
| 1211 | rd_index = card->rxbd_rdptr & reg->rx_mask; | 1211 | rd_index = card->rxbd_rdptr & reg->rx_mask; |
| 1212 | skb_data = card->rx_buf_list[rd_index]; | 1212 | skb_data = card->rx_buf_list[rd_index]; |
| 1213 | 1213 | ||
| 1214 | /* If skb allocation was failed earlier for Rx packet, | ||
| 1215 | * rx_buf_list[rd_index] would have been left with a NULL. | ||
| 1216 | */ | ||
| 1217 | if (!skb_data) | ||
| 1218 | return -ENOMEM; | ||
| 1219 | |||
| 1214 | MWIFIEX_SKB_PACB(skb_data, &buf_pa); | 1220 | MWIFIEX_SKB_PACB(skb_data, &buf_pa); |
| 1215 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE, | 1221 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE, |
| 1216 | PCI_DMA_FROMDEVICE); | 1222 | PCI_DMA_FROMDEVICE); |
| @@ -1525,6 +1531,14 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) | |||
| 1525 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { | 1531 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { |
| 1526 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, | 1532 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, |
| 1527 | skb->len); | 1533 | skb->len); |
| 1534 | mwifiex_pcie_enable_host_int(adapter); | ||
| 1535 | if (mwifiex_write_reg(adapter, | ||
| 1536 | PCIE_CPU_INT_EVENT, | ||
| 1537 | CPU_INTR_SLEEP_CFM_DONE)) { | ||
| 1538 | dev_warn(adapter->dev, | ||
| 1539 | "Write register failed\n"); | ||
| 1540 | return -1; | ||
| 1541 | } | ||
| 1528 | while (reg->sleep_cookie && (count++ < 10) && | 1542 | while (reg->sleep_cookie && (count++ < 10) && |
| 1529 | mwifiex_pcie_ok_to_access_hw(adapter)) | 1543 | mwifiex_pcie_ok_to_access_hw(adapter)) |
| 1530 | usleep_range(50, 60); | 1544 | usleep_range(50, 60); |
| @@ -1993,23 +2007,9 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
| 1993 | adapter->int_status |= pcie_ireg; | 2007 | adapter->int_status |= pcie_ireg; |
| 1994 | spin_unlock_irqrestore(&adapter->int_lock, flags); | 2008 | spin_unlock_irqrestore(&adapter->int_lock, flags); |
| 1995 | 2009 | ||
| 1996 | if (pcie_ireg & HOST_INTR_CMD_DONE) { | 2010 | if (!adapter->pps_uapsd_mode && |
| 1997 | if ((adapter->ps_state == PS_STATE_SLEEP_CFM) || | 2011 | adapter->ps_state == PS_STATE_SLEEP && |
| 1998 | (adapter->ps_state == PS_STATE_SLEEP)) { | 2012 | mwifiex_pcie_ok_to_access_hw(adapter)) { |
| 1999 | mwifiex_pcie_enable_host_int(adapter); | ||
| 2000 | if (mwifiex_write_reg(adapter, | ||
| 2001 | PCIE_CPU_INT_EVENT, | ||
| 2002 | CPU_INTR_SLEEP_CFM_DONE) | ||
| 2003 | ) { | ||
| 2004 | dev_warn(adapter->dev, | ||
| 2005 | "Write register failed\n"); | ||
| 2006 | return; | ||
| 2007 | |||
| 2008 | } | ||
| 2009 | } | ||
| 2010 | } else if (!adapter->pps_uapsd_mode && | ||
| 2011 | adapter->ps_state == PS_STATE_SLEEP && | ||
| 2012 | mwifiex_pcie_ok_to_access_hw(adapter)) { | ||
| 2013 | /* Potentially for PCIe we could get other | 2013 | /* Potentially for PCIe we could get other |
| 2014 | * interrupts like shared. Don't change power | 2014 | * interrupts like shared. Don't change power |
| 2015 | * state until cookie is set */ | 2015 | * state until cookie is set */ |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 0a8a26e10f01..668547c2de84 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
| @@ -2101,12 +2101,12 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) | |||
| 2101 | curr_bss->ht_info_offset); | 2101 | curr_bss->ht_info_offset); |
| 2102 | 2102 | ||
| 2103 | if (curr_bss->bcn_vht_cap) | 2103 | if (curr_bss->bcn_vht_cap) |
| 2104 | curr_bss->bcn_ht_cap = (void *)(curr_bss->beacon_buf + | 2104 | curr_bss->bcn_vht_cap = (void *)(curr_bss->beacon_buf + |
| 2105 | curr_bss->vht_cap_offset); | 2105 | curr_bss->vht_cap_offset); |
| 2106 | 2106 | ||
| 2107 | if (curr_bss->bcn_vht_oper) | 2107 | if (curr_bss->bcn_vht_oper) |
| 2108 | curr_bss->bcn_ht_oper = (void *)(curr_bss->beacon_buf + | 2108 | curr_bss->bcn_vht_oper = (void *)(curr_bss->beacon_buf + |
| 2109 | curr_bss->vht_info_offset); | 2109 | curr_bss->vht_info_offset); |
| 2110 | 2110 | ||
| 2111 | if (curr_bss->bcn_bss_co_2040) | 2111 | if (curr_bss->bcn_bss_co_2040) |
| 2112 | curr_bss->bcn_bss_co_2040 = | 2112 | curr_bss->bcn_bss_co_2040 = |
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index e8ebbd4bc3cd..208748804a55 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c | |||
| @@ -22,8 +22,6 @@ | |||
| 22 | 22 | ||
| 23 | #define USB_VERSION "1.0" | 23 | #define USB_VERSION "1.0" |
| 24 | 24 | ||
| 25 | static const char usbdriver_name[] = "usb8xxx"; | ||
| 26 | |||
| 27 | static struct mwifiex_if_ops usb_ops; | 25 | static struct mwifiex_if_ops usb_ops; |
| 28 | static struct semaphore add_remove_card_sem; | 26 | static struct semaphore add_remove_card_sem; |
| 29 | static struct usb_card_rec *usb_card; | 27 | static struct usb_card_rec *usb_card; |
| @@ -527,13 +525,6 @@ static int mwifiex_usb_resume(struct usb_interface *intf) | |||
| 527 | MWIFIEX_BSS_ROLE_ANY), | 525 | MWIFIEX_BSS_ROLE_ANY), |
| 528 | MWIFIEX_ASYNC_CMD); | 526 | MWIFIEX_ASYNC_CMD); |
| 529 | 527 | ||
| 530 | #ifdef CONFIG_PM | ||
| 531 | /* Resume handler may be called due to remote wakeup, | ||
| 532 | * force to exit suspend anyway | ||
| 533 | */ | ||
| 534 | usb_disable_autosuspend(card->udev); | ||
| 535 | #endif /* CONFIG_PM */ | ||
| 536 | |||
| 537 | return 0; | 528 | return 0; |
| 538 | } | 529 | } |
| 539 | 530 | ||
| @@ -567,13 +558,12 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf) | |||
| 567 | } | 558 | } |
| 568 | 559 | ||
| 569 | static struct usb_driver mwifiex_usb_driver = { | 560 | static struct usb_driver mwifiex_usb_driver = { |
| 570 | .name = usbdriver_name, | 561 | .name = "mwifiex_usb", |
| 571 | .probe = mwifiex_usb_probe, | 562 | .probe = mwifiex_usb_probe, |
| 572 | .disconnect = mwifiex_usb_disconnect, | 563 | .disconnect = mwifiex_usb_disconnect, |
| 573 | .id_table = mwifiex_usb_table, | 564 | .id_table = mwifiex_usb_table, |
| 574 | .suspend = mwifiex_usb_suspend, | 565 | .suspend = mwifiex_usb_suspend, |
| 575 | .resume = mwifiex_usb_resume, | 566 | .resume = mwifiex_usb_resume, |
| 576 | .supports_autosuspend = 1, | ||
| 577 | }; | 567 | }; |
| 578 | 568 | ||
| 579 | static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) | 569 | static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) |
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 13eaeed03898..981cf6e7c73b 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
| @@ -559,7 +559,8 @@ mwifiex_clean_txrx(struct mwifiex_private *priv) | |||
| 559 | mwifiex_wmm_delete_all_ralist(priv); | 559 | mwifiex_wmm_delete_all_ralist(priv); |
| 560 | memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); | 560 | memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); |
| 561 | 561 | ||
| 562 | if (priv->adapter->if_ops.clean_pcie_ring) | 562 | if (priv->adapter->if_ops.clean_pcie_ring && |
| 563 | !priv->adapter->surprise_removed) | ||
| 563 | priv->adapter->if_ops.clean_pcie_ring(priv->adapter); | 564 | priv->adapter->if_ops.clean_pcie_ring(priv->adapter); |
| 564 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); | 565 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
| 565 | } | 566 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index abc5f56f29fe..2f1cd929c6f6 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
| @@ -1877,6 +1877,11 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 1877 | EEPROM_MAC_ADDR_0)); | 1877 | EEPROM_MAC_ADDR_0)); |
| 1878 | 1878 | ||
| 1879 | /* | 1879 | /* |
| 1880 | * Disable powersaving as default. | ||
| 1881 | */ | ||
| 1882 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
| 1883 | |||
| 1884 | /* | ||
| 1880 | * Initialize hw_mode information. | 1885 | * Initialize hw_mode information. |
| 1881 | */ | 1886 | */ |
| 1882 | spec->supported_bands = SUPPORT_BAND_2GHZ; | 1887 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9f16824cd1bc..d849d590de25 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
| @@ -1706,6 +1706,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 1706 | IEEE80211_HW_SUPPORTS_PS | | 1706 | IEEE80211_HW_SUPPORTS_PS | |
| 1707 | IEEE80211_HW_PS_NULLFUNC_STACK; | 1707 | IEEE80211_HW_PS_NULLFUNC_STACK; |
| 1708 | 1708 | ||
| 1709 | /* | ||
| 1710 | * Disable powersaving as default. | ||
| 1711 | */ | ||
| 1712 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
| 1713 | |||
| 1709 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | 1714 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
| 1710 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1715 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
| 1711 | rt2x00_eeprom_addr(rt2x00dev, | 1716 | rt2x00_eeprom_addr(rt2x00dev, |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b8f5b06006c4..41d4a8167dc3 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
| @@ -5460,14 +5460,15 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) | |||
| 5460 | 5460 | ||
| 5461 | rt2800_bbp_write(rt2x00dev, 68, 0x0b); | 5461 | rt2800_bbp_write(rt2x00dev, 68, 0x0b); |
| 5462 | 5462 | ||
| 5463 | rt2800_bbp_write(rt2x00dev, 69, 0x0d); | 5463 | rt2800_bbp_write(rt2x00dev, 69, 0x12); |
| 5464 | rt2800_bbp_write(rt2x00dev, 70, 0x06); | ||
| 5465 | rt2800_bbp_write(rt2x00dev, 73, 0x13); | 5464 | rt2800_bbp_write(rt2x00dev, 73, 0x13); |
| 5466 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | 5465 | rt2800_bbp_write(rt2x00dev, 75, 0x46); |
| 5467 | rt2800_bbp_write(rt2x00dev, 76, 0x28); | 5466 | rt2800_bbp_write(rt2x00dev, 76, 0x28); |
| 5468 | 5467 | ||
| 5469 | rt2800_bbp_write(rt2x00dev, 77, 0x59); | 5468 | rt2800_bbp_write(rt2x00dev, 77, 0x59); |
| 5470 | 5469 | ||
| 5470 | rt2800_bbp_write(rt2x00dev, 70, 0x0a); | ||
| 5471 | |||
| 5471 | rt2800_bbp_write(rt2x00dev, 79, 0x13); | 5472 | rt2800_bbp_write(rt2x00dev, 79, 0x13); |
| 5472 | rt2800_bbp_write(rt2x00dev, 80, 0x05); | 5473 | rt2800_bbp_write(rt2x00dev, 80, 0x05); |
| 5473 | rt2800_bbp_write(rt2x00dev, 81, 0x33); | 5474 | rt2800_bbp_write(rt2x00dev, 81, 0x33); |
| @@ -5510,7 +5511,6 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) | |||
| 5510 | if (rt2x00_rt(rt2x00dev, RT5392)) { | 5511 | if (rt2x00_rt(rt2x00dev, RT5392)) { |
| 5511 | rt2800_bbp_write(rt2x00dev, 134, 0xd0); | 5512 | rt2800_bbp_write(rt2x00dev, 134, 0xd0); |
| 5512 | rt2800_bbp_write(rt2x00dev, 135, 0xf6); | 5513 | rt2800_bbp_write(rt2x00dev, 135, 0xf6); |
| 5513 | rt2800_bbp_write(rt2x00dev, 148, 0x84); | ||
| 5514 | } | 5514 | } |
| 5515 | 5515 | ||
| 5516 | rt2800_disable_unused_dac_adc(rt2x00dev); | 5516 | rt2800_disable_unused_dac_adc(rt2x00dev); |
| @@ -7458,10 +7458,9 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 7458 | u32 reg; | 7458 | u32 reg; |
| 7459 | 7459 | ||
| 7460 | /* | 7460 | /* |
| 7461 | * Disable powersaving as default on PCI devices. | 7461 | * Disable powersaving as default. |
| 7462 | */ | 7462 | */ |
| 7463 | if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) | 7463 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
| 7464 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
| 7465 | 7464 | ||
| 7466 | /* | 7465 | /* |
| 7467 | * Initialize all hw fields. | 7466 | * Initialize all hw fields. |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index 8ec17aad0e52..3867d1470b36 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c | |||
| @@ -107,6 +107,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 107 | struct rtl8180_priv *priv = dev->priv; | 107 | struct rtl8180_priv *priv = dev->priv; |
| 108 | unsigned int count = 32; | 108 | unsigned int count = 32; |
| 109 | u8 signal, agc, sq; | 109 | u8 signal, agc, sq; |
| 110 | dma_addr_t mapping; | ||
| 110 | 111 | ||
| 111 | while (count--) { | 112 | while (count--) { |
| 112 | struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; | 113 | struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; |
| @@ -128,6 +129,17 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 128 | if (unlikely(!new_skb)) | 129 | if (unlikely(!new_skb)) |
| 129 | goto done; | 130 | goto done; |
| 130 | 131 | ||
| 132 | mapping = pci_map_single(priv->pdev, | ||
| 133 | skb_tail_pointer(new_skb), | ||
| 134 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | ||
| 135 | |||
| 136 | if (pci_dma_mapping_error(priv->pdev, mapping)) { | ||
| 137 | kfree_skb(new_skb); | ||
| 138 | dev_err(&priv->pdev->dev, "RX DMA map error\n"); | ||
| 139 | |||
| 140 | goto done; | ||
| 141 | } | ||
| 142 | |||
| 131 | pci_unmap_single(priv->pdev, | 143 | pci_unmap_single(priv->pdev, |
| 132 | *((dma_addr_t *)skb->cb), | 144 | *((dma_addr_t *)skb->cb), |
| 133 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | 145 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); |
| @@ -158,9 +170,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 158 | 170 | ||
| 159 | skb = new_skb; | 171 | skb = new_skb; |
| 160 | priv->rx_buf[priv->rx_idx] = skb; | 172 | priv->rx_buf[priv->rx_idx] = skb; |
| 161 | *((dma_addr_t *) skb->cb) = | 173 | *((dma_addr_t *) skb->cb) = mapping; |
| 162 | pci_map_single(priv->pdev, skb_tail_pointer(skb), | ||
| 163 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | ||
| 164 | } | 174 | } |
| 165 | 175 | ||
| 166 | done: | 176 | done: |
| @@ -266,6 +276,13 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
| 266 | mapping = pci_map_single(priv->pdev, skb->data, | 276 | mapping = pci_map_single(priv->pdev, skb->data, |
| 267 | skb->len, PCI_DMA_TODEVICE); | 277 | skb->len, PCI_DMA_TODEVICE); |
| 268 | 278 | ||
| 279 | if (pci_dma_mapping_error(priv->pdev, mapping)) { | ||
| 280 | kfree_skb(skb); | ||
| 281 | dev_err(&priv->pdev->dev, "TX DMA mapping error\n"); | ||
| 282 | return; | ||
| 283 | |||
| 284 | } | ||
| 285 | |||
| 269 | tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | | 286 | tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | |
| 270 | RTL818X_TX_DESC_FLAG_LS | | 287 | RTL818X_TX_DESC_FLAG_LS | |
| 271 | (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | | 288 | (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h index 56aee067f324..a6ad79f61bf9 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #ifndef RTL8187_H | 15 | #ifndef RTL8187_H |
| 16 | #define RTL8187_H | 16 | #define RTL8187_H |
| 17 | 17 | ||
| 18 | #include <linux/cache.h> | ||
| 19 | |||
| 18 | #include "rtl818x.h" | 20 | #include "rtl818x.h" |
| 19 | #include "leds.h" | 21 | #include "leds.h" |
| 20 | 22 | ||
| @@ -139,7 +141,10 @@ struct rtl8187_priv { | |||
| 139 | u8 aifsn[4]; | 141 | u8 aifsn[4]; |
| 140 | u8 rfkill_mask; | 142 | u8 rfkill_mask; |
| 141 | struct { | 143 | struct { |
| 142 | __le64 buf; | 144 | union { |
| 145 | __le64 buf; | ||
| 146 | u8 dummy1[L1_CACHE_BYTES]; | ||
| 147 | } ____cacheline_aligned; | ||
| 143 | struct sk_buff_head queue; | 148 | struct sk_buff_head queue; |
| 144 | } b_tx_status; /* This queue is used by both -b and non-b devices */ | 149 | } b_tx_status; /* This queue is used by both -b and non-b devices */ |
| 145 | struct mutex io_mutex; | 150 | struct mutex io_mutex; |
| @@ -147,7 +152,8 @@ struct rtl8187_priv { | |||
| 147 | u8 bits8; | 152 | u8 bits8; |
| 148 | __le16 bits16; | 153 | __le16 bits16; |
| 149 | __le32 bits32; | 154 | __le32 bits32; |
| 150 | } *io_dmabuf; | 155 | u8 dummy2[L1_CACHE_BYTES]; |
| 156 | } *io_dmabuf ____cacheline_aligned; | ||
| 151 | bool rfkill_off; | 157 | bool rfkill_off; |
| 152 | u16 seqno; | 158 | u16 seqno; |
| 153 | }; | 159 | }; |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index deedae3c5449..d1c0191a195b 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
| @@ -48,7 +48,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) | |||
| 48 | 48 | ||
| 49 | /*<2> Enable Adapter */ | 49 | /*<2> Enable Adapter */ |
| 50 | if (rtlpriv->cfg->ops->hw_init(hw)) | 50 | if (rtlpriv->cfg->ops->hw_init(hw)) |
| 51 | return 1; | 51 | return false; |
| 52 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | 52 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); |
| 53 | 53 | ||
| 54 | /*<3> Enable Interrupt */ | 54 | /*<3> Enable Interrupt */ |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index a82b30a1996c..2eb0b38384dd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
| @@ -937,14 +937,26 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
| 937 | bool is92c; | 937 | bool is92c; |
| 938 | int err; | 938 | int err; |
| 939 | u8 tmp_u1b; | 939 | u8 tmp_u1b; |
| 940 | unsigned long flags; | ||
| 940 | 941 | ||
| 941 | rtlpci->being_init_adapter = true; | 942 | rtlpci->being_init_adapter = true; |
| 943 | |||
| 944 | /* Since this function can take a very long time (up to 350 ms) | ||
| 945 | * and can be called with irqs disabled, reenable the irqs | ||
| 946 | * to let the other devices continue being serviced. | ||
| 947 | * | ||
| 948 | * It is safe doing so since our own interrupts will only be enabled | ||
| 949 | * in a subsequent step. | ||
| 950 | */ | ||
| 951 | local_save_flags(flags); | ||
| 952 | local_irq_enable(); | ||
| 953 | |||
| 942 | rtlpriv->intf_ops->disable_aspm(hw); | 954 | rtlpriv->intf_ops->disable_aspm(hw); |
| 943 | rtstatus = _rtl92ce_init_mac(hw); | 955 | rtstatus = _rtl92ce_init_mac(hw); |
| 944 | if (!rtstatus) { | 956 | if (!rtstatus) { |
| 945 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); | 957 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); |
| 946 | err = 1; | 958 | err = 1; |
| 947 | return err; | 959 | goto exit; |
| 948 | } | 960 | } |
| 949 | 961 | ||
| 950 | err = rtl92c_download_fw(hw); | 962 | err = rtl92c_download_fw(hw); |
| @@ -952,7 +964,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
| 952 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 964 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
| 953 | "Failed to download FW. Init HW without FW now..\n"); | 965 | "Failed to download FW. Init HW without FW now..\n"); |
| 954 | err = 1; | 966 | err = 1; |
| 955 | return err; | 967 | goto exit; |
| 956 | } | 968 | } |
| 957 | 969 | ||
| 958 | rtlhal->last_hmeboxnum = 0; | 970 | rtlhal->last_hmeboxnum = 0; |
| @@ -1032,6 +1044,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
| 1032 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); | 1044 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); |
| 1033 | } | 1045 | } |
| 1034 | rtl92c_dm_init(hw); | 1046 | rtl92c_dm_init(hw); |
| 1047 | exit: | ||
| 1048 | local_irq_restore(flags); | ||
| 1035 | rtlpci->being_init_adapter = false; | 1049 | rtlpci->being_init_adapter = false; |
| 1036 | return err; | 1050 | return err; |
| 1037 | } | 1051 | } |
diff --git a/drivers/net/wireless/ti/wl1251/rx.c b/drivers/net/wireless/ti/wl1251/rx.c index 123c4bb50e0a..cde0eaf99714 100644 --- a/drivers/net/wireless/ti/wl1251/rx.c +++ b/drivers/net/wireless/ti/wl1251/rx.c | |||
| @@ -180,7 +180,7 @@ static void wl1251_rx_body(struct wl1251 *wl, | |||
| 180 | wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length); | 180 | wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length); |
| 181 | 181 | ||
| 182 | /* The actual length doesn't include the target's alignment */ | 182 | /* The actual length doesn't include the target's alignment */ |
| 183 | skb->len = desc->length - PLCP_HEADER_LENGTH; | 183 | skb_trim(skb, desc->length - PLCP_HEADER_LENGTH); |
| 184 | 184 | ||
| 185 | fc = (u16 *)skb->data; | 185 | fc = (u16 *)skb->data; |
| 186 | 186 | ||
