diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-07-22 16:02:10 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-07-22 16:02:10 -0400 |
commit | 0597a7a130533eae2e357373a487ebcc6dd01d34 (patch) | |
tree | 34066274c7e81c7d84c231e564d34dfe728b2453 | |
parent | 22f64bd30366417f6f0648fcf45f8aa409e2ba25 (diff) | |
parent | a590ad411891de551e6de1b51ea635c0484148d6 (diff) |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/debugfs.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac80211.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/scan.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/sta.c | 23 |
6 files changed, 56 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 3952ddf2ddb2..1531a4fc0960 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
@@ -758,7 +758,7 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
758 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 758 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
759 | if (ret) | 759 | if (ret) |
760 | return ret; | 760 | return ret; |
761 | } else { | 761 | } else if (priv->lib->bt_params) { |
762 | /* | 762 | /* |
763 | * default is 2-wire BT coexexistence support | 763 | * default is 2-wire BT coexexistence support |
764 | */ | 764 | */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index e56ed2a84888..c24a744910ac 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
@@ -988,7 +988,11 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
988 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 988 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
989 | char buf[100]; | 989 | char buf[100]; |
990 | 990 | ||
991 | if (!dbgfs_dir) | 991 | /* |
992 | * Check if debugfs directory already exist before creating it. | ||
993 | * This may happen when, for example, resetting hw or suspend-resume | ||
994 | */ | ||
995 | if (!dbgfs_dir || mvmvif->dbgfs_dir) | ||
992 | return; | 996 | return; |
993 | 997 | ||
994 | mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); | 998 | mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index e08683b20531..1eedc424051c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -257,7 +257,11 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
257 | if (ret) | 257 | if (ret) |
258 | return ret; | 258 | return ret; |
259 | 259 | ||
260 | return ieee80211_register_hw(mvm->hw); | 260 | ret = ieee80211_register_hw(mvm->hw); |
261 | if (ret) | ||
262 | iwl_mvm_leds_exit(mvm); | ||
263 | |||
264 | return ret; | ||
261 | } | 265 | } |
262 | 266 | ||
263 | static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, | 267 | static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, |
@@ -385,6 +389,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) | |||
385 | ieee80211_wake_queues(mvm->hw); | 389 | ieee80211_wake_queues(mvm->hw); |
386 | 390 | ||
387 | mvm->vif_count = 0; | 391 | mvm->vif_count = 0; |
392 | mvm->rx_ba_sessions = 0; | ||
388 | } | 393 | } |
389 | 394 | ||
390 | static int iwl_mvm_mac_start(struct ieee80211_hw *hw) | 395 | static int iwl_mvm_mac_start(struct ieee80211_hw *hw) |
@@ -1006,6 +1011,21 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, | |||
1006 | mutex_lock(&mvm->mutex); | 1011 | mutex_lock(&mvm->mutex); |
1007 | if (old_state == IEEE80211_STA_NOTEXIST && | 1012 | if (old_state == IEEE80211_STA_NOTEXIST && |
1008 | new_state == IEEE80211_STA_NONE) { | 1013 | new_state == IEEE80211_STA_NONE) { |
1014 | /* | ||
1015 | * Firmware bug - it'll crash if the beacon interval is less | ||
1016 | * than 16. We can't avoid connecting at all, so refuse the | ||
1017 | * station state change, this will cause mac80211 to abandon | ||
1018 | * attempts to connect to this AP, and eventually wpa_s will | ||
1019 | * blacklist the AP... | ||
1020 | */ | ||
1021 | if (vif->type == NL80211_IFTYPE_STATION && | ||
1022 | vif->bss_conf.beacon_int < 16) { | ||
1023 | IWL_ERR(mvm, | ||
1024 | "AP %pM beacon interval is %d, refusing due to firmware bug!\n", | ||
1025 | sta->addr, vif->bss_conf.beacon_int); | ||
1026 | ret = -EINVAL; | ||
1027 | goto out_unlock; | ||
1028 | } | ||
1009 | ret = iwl_mvm_add_sta(mvm, vif, sta); | 1029 | ret = iwl_mvm_add_sta(mvm, vif, sta); |
1010 | } else if (old_state == IEEE80211_STA_NONE && | 1030 | } else if (old_state == IEEE80211_STA_NONE && |
1011 | new_state == IEEE80211_STA_AUTH) { | 1031 | new_state == IEEE80211_STA_AUTH) { |
@@ -1038,6 +1058,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, | |||
1038 | } else { | 1058 | } else { |
1039 | ret = -EIO; | 1059 | ret = -EIO; |
1040 | } | 1060 | } |
1061 | out_unlock: | ||
1041 | mutex_unlock(&mvm->mutex); | 1062 | mutex_unlock(&mvm->mutex); |
1042 | 1063 | ||
1043 | return ret; | 1064 | return ret; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index d40d7db185d6..420e82d379d9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -419,6 +419,7 @@ struct iwl_mvm { | |||
419 | struct work_struct sta_drained_wk; | 419 | struct work_struct sta_drained_wk; |
420 | unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; | 420 | unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; |
421 | atomic_t pending_frames[IWL_MVM_STATION_COUNT]; | 421 | atomic_t pending_frames[IWL_MVM_STATION_COUNT]; |
422 | u8 rx_ba_sessions; | ||
422 | 423 | ||
423 | /* configured by mac80211 */ | 424 | /* configured by mac80211 */ |
424 | u32 rts_threshold; | 425 | u32 rts_threshold; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 2157b0f8ced5..268f027b45b0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -137,8 +137,8 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, | |||
137 | { | 137 | { |
138 | int fw_idx, req_idx; | 138 | int fw_idx, req_idx; |
139 | 139 | ||
140 | fw_idx = 0; | 140 | for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx > 0; |
141 | for (req_idx = req->n_ssids - 1; req_idx > 0; req_idx--) { | 141 | req_idx--, fw_idx++) { |
142 | cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; | 142 | cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; |
143 | cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; | 143 | cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; |
144 | memcpy(cmd->direct_scan[fw_idx].ssid, | 144 | memcpy(cmd->direct_scan[fw_idx].ssid, |
@@ -153,7 +153,9 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, | |||
153 | * just to notify that this scan is active and not passive. | 153 | * just to notify that this scan is active and not passive. |
154 | * In order to notify the FW of the number of SSIDs we wish to scan (including | 154 | * In order to notify the FW of the number of SSIDs we wish to scan (including |
155 | * the zero-length one), we need to set the corresponding bits in chan->type, | 155 | * the zero-length one), we need to set the corresponding bits in chan->type, |
156 | * one for each SSID, and set the active bit (first). | 156 | * one for each SSID, and set the active bit (first). The first SSID is already |
157 | * included in the probe template, so we need to set only req->n_ssids - 1 bits | ||
158 | * in addition to the first bit. | ||
157 | */ | 159 | */ |
158 | static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) | 160 | static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) |
159 | { | 161 | { |
@@ -179,7 +181,7 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, | |||
179 | __le32 chan_type_value; | 181 | __le32 chan_type_value; |
180 | 182 | ||
181 | if (req->n_ssids > 0) | 183 | if (req->n_ssids > 0) |
182 | chan_type_value = cpu_to_le32(BIT(req->n_ssids + 1) - 1); | 184 | chan_type_value = cpu_to_le32(BIT(req->n_ssids) - 1); |
183 | else | 185 | else |
184 | chan_type_value = SCAN_CHANNEL_TYPE_PASSIVE; | 186 | chan_type_value = SCAN_CHANNEL_TYPE_PASSIVE; |
185 | 187 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 62fe5209093b..85d4bbe52157 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
@@ -608,6 +608,8 @@ int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta) | |||
608 | return ret; | 608 | return ret; |
609 | } | 609 | } |
610 | 610 | ||
611 | #define IWL_MAX_RX_BA_SESSIONS 16 | ||
612 | |||
611 | int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | 613 | int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, |
612 | int tid, u16 ssn, bool start) | 614 | int tid, u16 ssn, bool start) |
613 | { | 615 | { |
@@ -618,11 +620,20 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
618 | 620 | ||
619 | lockdep_assert_held(&mvm->mutex); | 621 | lockdep_assert_held(&mvm->mutex); |
620 | 622 | ||
623 | if (start && mvm->rx_ba_sessions >= IWL_MAX_RX_BA_SESSIONS) { | ||
624 | IWL_WARN(mvm, "Not enough RX BA SESSIONS\n"); | ||
625 | return -ENOSPC; | ||
626 | } | ||
627 | |||
621 | cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); | 628 | cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); |
622 | cmd.sta_id = mvm_sta->sta_id; | 629 | cmd.sta_id = mvm_sta->sta_id; |
623 | cmd.add_modify = STA_MODE_MODIFY; | 630 | cmd.add_modify = STA_MODE_MODIFY; |
624 | cmd.add_immediate_ba_tid = (u8) tid; | 631 | if (start) { |
625 | cmd.add_immediate_ba_ssn = cpu_to_le16(ssn); | 632 | cmd.add_immediate_ba_tid = (u8) tid; |
633 | cmd.add_immediate_ba_ssn = cpu_to_le16(ssn); | ||
634 | } else { | ||
635 | cmd.remove_immediate_ba_tid = (u8) tid; | ||
636 | } | ||
626 | cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID : | 637 | cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID : |
627 | STA_MODIFY_REMOVE_BA_TID; | 638 | STA_MODIFY_REMOVE_BA_TID; |
628 | 639 | ||
@@ -648,6 +659,14 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
648 | break; | 659 | break; |
649 | } | 660 | } |
650 | 661 | ||
662 | if (!ret) { | ||
663 | if (start) | ||
664 | mvm->rx_ba_sessions++; | ||
665 | else if (mvm->rx_ba_sessions > 0) | ||
666 | /* check that restart flow didn't zero the counter */ | ||
667 | mvm->rx_ba_sessions--; | ||
668 | } | ||
669 | |||
651 | return ret; | 670 | return ret; |
652 | } | 671 | } |
653 | 672 | ||