diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
| -rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/mac80211.c | 22 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/sta.c | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/tx.c | 14 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-drv.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-modparams.h | 11 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 5 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 7 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac80211.c | 24 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/scan.c | 5 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/sta.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/tx.c | 91 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/utils.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/drv.c | 8 |
15 files changed, 132 insertions, 68 deletions
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)}, |
