aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-07-22 16:02:10 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-07-22 16:02:10 -0400
commit0597a7a130533eae2e357373a487ebcc6dd01d34 (patch)
tree34066274c7e81c7d84c231e564d34dfe728b2453
parent22f64bd30366417f6f0648fcf45f8aa409e2ba25 (diff)
parenta590ad411891de551e6de1b51ea635c0484148d6 (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.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c23
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c23
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
263static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, 267static 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
390static int iwl_mvm_mac_start(struct ieee80211_hw *hw) 395static 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 */
158static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) 160static 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
611int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 613int 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