Commit 0597a7a1 authored by John W. Linville's avatar John W. Linville
parents 22f64bd3 a590ad41
...@@ -758,7 +758,7 @@ int iwl_alive_start(struct iwl_priv *priv) ...@@ -758,7 +758,7 @@ int iwl_alive_start(struct iwl_priv *priv)
BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
if (ret) if (ret)
return ret; return ret;
} else { } else if (priv->lib->bt_params) {
/* /*
* default is 2-wire BT coexexistence support * default is 2-wire BT coexexistence support
*/ */
......
...@@ -988,7 +988,11 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) ...@@ -988,7 +988,11 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
char buf[100]; char buf[100];
if (!dbgfs_dir) /*
* Check if debugfs directory already exist before creating it.
* This may happen when, for example, resetting hw or suspend-resume
*/
if (!dbgfs_dir || mvmvif->dbgfs_dir)
return; return;
mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
......
...@@ -257,7 +257,11 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) ...@@ -257,7 +257,11 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
if (ret) if (ret)
return ret; return ret;
return ieee80211_register_hw(mvm->hw); ret = ieee80211_register_hw(mvm->hw);
if (ret)
iwl_mvm_leds_exit(mvm);
return ret;
} }
static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, 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,6 +389,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
ieee80211_wake_queues(mvm->hw); ieee80211_wake_queues(mvm->hw);
mvm->vif_count = 0; mvm->vif_count = 0;
mvm->rx_ba_sessions = 0;
} }
static int iwl_mvm_mac_start(struct ieee80211_hw *hw) 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,6 +1011,21 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
if (old_state == IEEE80211_STA_NOTEXIST && if (old_state == IEEE80211_STA_NOTEXIST &&
new_state == IEEE80211_STA_NONE) { new_state == IEEE80211_STA_NONE) {
/*
* Firmware bug - it'll crash if the beacon interval is less
* than 16. We can't avoid connecting at all, so refuse the
* station state change, this will cause mac80211 to abandon
* attempts to connect to this AP, and eventually wpa_s will
* blacklist the AP...
*/
if (vif->type == NL80211_IFTYPE_STATION &&
vif->bss_conf.beacon_int < 16) {
IWL_ERR(mvm,
"AP %pM beacon interval is %d, refusing due to firmware bug!\n",
sta->addr, vif->bss_conf.beacon_int);
ret = -EINVAL;
goto out_unlock;
}
ret = iwl_mvm_add_sta(mvm, vif, sta); ret = iwl_mvm_add_sta(mvm, vif, sta);
} else if (old_state == IEEE80211_STA_NONE && } else if (old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_AUTH) { new_state == IEEE80211_STA_AUTH) {
...@@ -1038,6 +1058,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, ...@@ -1038,6 +1058,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
} else { } else {
ret = -EIO; ret = -EIO;
} }
out_unlock:
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
return ret; return ret;
......
...@@ -419,6 +419,7 @@ struct iwl_mvm { ...@@ -419,6 +419,7 @@ struct iwl_mvm {
struct work_struct sta_drained_wk; struct work_struct sta_drained_wk;
unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)];
atomic_t pending_frames[IWL_MVM_STATION_COUNT]; atomic_t pending_frames[IWL_MVM_STATION_COUNT];
u8 rx_ba_sessions;
/* configured by mac80211 */ /* configured by mac80211 */
u32 rts_threshold; u32 rts_threshold;
......
...@@ -137,8 +137,8 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, ...@@ -137,8 +137,8 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
{ {
int fw_idx, req_idx; int fw_idx, req_idx;
fw_idx = 0; for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx > 0;
for (req_idx = req->n_ssids - 1; req_idx > 0; req_idx--) { req_idx--, fw_idx++) {
cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; cmd->direct_scan[fw_idx].id = WLAN_EID_SSID;
cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len;
memcpy(cmd->direct_scan[fw_idx].ssid, memcpy(cmd->direct_scan[fw_idx].ssid,
...@@ -153,7 +153,9 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, ...@@ -153,7 +153,9 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
* just to notify that this scan is active and not passive. * just to notify that this scan is active and not passive.
* In order to notify the FW of the number of SSIDs we wish to scan (including * In order to notify the FW of the number of SSIDs we wish to scan (including
* the zero-length one), we need to set the corresponding bits in chan->type, * the zero-length one), we need to set the corresponding bits in chan->type,
* one for each SSID, and set the active bit (first). * one for each SSID, and set the active bit (first). The first SSID is already
* included in the probe template, so we need to set only req->n_ssids - 1 bits
* in addition to the first bit.
*/ */
static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids)
{ {
...@@ -179,7 +181,7 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, ...@@ -179,7 +181,7 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
__le32 chan_type_value; __le32 chan_type_value;
if (req->n_ssids > 0) if (req->n_ssids > 0)
chan_type_value = cpu_to_le32(BIT(req->n_ssids + 1) - 1); chan_type_value = cpu_to_le32(BIT(req->n_ssids) - 1);
else else
chan_type_value = SCAN_CHANNEL_TYPE_PASSIVE; chan_type_value = SCAN_CHANNEL_TYPE_PASSIVE;
......
...@@ -608,6 +608,8 @@ int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta) ...@@ -608,6 +608,8 @@ int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta)
return ret; return ret;
} }
#define IWL_MAX_RX_BA_SESSIONS 16
int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
int tid, u16 ssn, bool start) int tid, u16 ssn, bool start)
{ {
...@@ -618,11 +620,20 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -618,11 +620,20 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
if (start && mvm->rx_ba_sessions >= IWL_MAX_RX_BA_SESSIONS) {
IWL_WARN(mvm, "Not enough RX BA SESSIONS\n");
return -ENOSPC;
}
cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
cmd.sta_id = mvm_sta->sta_id; cmd.sta_id = mvm_sta->sta_id;
cmd.add_modify = STA_MODE_MODIFY; cmd.add_modify = STA_MODE_MODIFY;
if (start) {
cmd.add_immediate_ba_tid = (u8) tid; cmd.add_immediate_ba_tid = (u8) tid;
cmd.add_immediate_ba_ssn = cpu_to_le16(ssn); cmd.add_immediate_ba_ssn = cpu_to_le16(ssn);
} else {
cmd.remove_immediate_ba_tid = (u8) tid;
}
cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID : cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID :
STA_MODIFY_REMOVE_BA_TID; STA_MODIFY_REMOVE_BA_TID;
...@@ -648,6 +659,14 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -648,6 +659,14 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
break; break;
} }
if (!ret) {
if (start)
mvm->rx_ba_sessions++;
else if (mvm->rx_ba_sessions > 0)
/* check that restart flow didn't zero the counter */
mvm->rx_ba_sessions--;
}
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment