Commit b92e661b authored by Eliad Peller's avatar Eliad Peller Committed by Emmanuel Grumbach

iwlwifi: mvm: reserve sta_id 0 to station

The d3/d0i3 fw code requires the sta_id to be 0
(this is used to determine the rates and keys
to use in arp offloading).

Reserve sta_id 0 to station interface in order
to comply with this requirement.

Change some functions prototypes in order to
make the allocation function know about
the interface type.
Signed-off-by: default avatarEliad Peller <eliadx.peller@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent b800040d
...@@ -963,7 +963,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, ...@@ -963,7 +963,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
}; };
int ret, i; int ret, i;
int len __maybe_unused; int len __maybe_unused;
u8 old_aux_sta_id, old_ap_sta_id = IWL_MVM_STATION_COUNT;
if (!wowlan) { if (!wowlan) {
/* /*
...@@ -980,8 +979,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, ...@@ -980,8 +979,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
old_aux_sta_id = mvm->aux_sta.sta_id;
/* see if there's only a single BSS vif and it's associated */ /* see if there's only a single BSS vif and it's associated */
ieee80211_iterate_active_interfaces_atomic( ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_NORMAL, mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
...@@ -1066,16 +1063,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, ...@@ -1066,16 +1063,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
iwl_trans_stop_device(mvm->trans); iwl_trans_stop_device(mvm->trans);
/*
* The D3 firmware still hardcodes the AP station ID for the
* BSS we're associated with as 0. Store the real STA ID here
* and assign 0. When we leave this function, we'll restore
* the original value for the resume code.
*/
old_ap_sta_id = mvm_ap_sta->sta_id;
mvm_ap_sta->sta_id = 0;
mvmvif->ap_sta_id = 0;
/* /*
* Set the HW restart bit -- this is mostly true as we're * Set the HW restart bit -- this is mostly true as we're
* going to load new firmware and reprogram that, though * going to load new firmware and reprogram that, though
...@@ -1096,16 +1083,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, ...@@ -1096,16 +1083,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
mvm->ptk_ivlen = 0; mvm->ptk_ivlen = 0;
mvm->ptk_icvlen = 0; mvm->ptk_icvlen = 0;
/*
* The D3 firmware still hardcodes the AP station ID for the
* BSS we're associated with as 0. As a result, we have to move
* the auxiliary station to ID 1 so the ID 0 remains free for
* the AP station for later.
* We set the sta_id to 1 here, and reset it to its previous
* value (that we stored above) later.
*/
mvm->aux_sta.sta_id = 1;
ret = iwl_mvm_load_d3_fw(mvm); ret = iwl_mvm_load_d3_fw(mvm);
if (ret) if (ret)
goto out; goto out;
...@@ -1222,10 +1199,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, ...@@ -1222,10 +1199,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
iwl_trans_d3_suspend(mvm->trans, test); iwl_trans_d3_suspend(mvm->trans, test);
out: out:
mvm->aux_sta.sta_id = old_aux_sta_id;
mvm_ap_sta->sta_id = old_ap_sta_id;
mvmvif->ap_sta_id = old_ap_sta_id;
if (ret < 0) if (ret < 0)
ieee80211_restart_hw(mvm->hw); ieee80211_restart_hw(mvm->hw);
out_noreset: out_noreset:
......
...@@ -703,7 +703,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, ...@@ -703,7 +703,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
vif->type == NL80211_IFTYPE_ADHOC) { vif->type == NL80211_IFTYPE_ADHOC) {
u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
qmask); qmask,
ieee80211_vif_type_p2p(vif));
if (ret) { if (ret) {
IWL_ERR(mvm, "Failed to allocate bcast sta\n"); IWL_ERR(mvm, "Failed to allocate bcast sta\n");
goto out_release; goto out_release;
......
...@@ -175,19 +175,30 @@ static int iwl_mvm_send_add_sta_key_cmd(struct iwl_mvm *mvm, ...@@ -175,19 +175,30 @@ static int iwl_mvm_send_add_sta_key_cmd(struct iwl_mvm *mvm,
&sta_cmd); &sta_cmd);
} }
static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm) static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm,
enum nl80211_iftype iftype)
{ {
int sta_id; int sta_id;
u32 reserved_ids = 0;
BUILD_BUG_ON(IWL_MVM_STATION_COUNT > 32);
WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)); WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status));
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
/* d0i3/d3 assumes the AP's sta_id (of sta vif) is 0. reserve it. */
if (iftype != NL80211_IFTYPE_STATION)
reserved_ids = BIT(0);
/* Don't take rcu_read_lock() since we are protected by mvm->mutex */ /* Don't take rcu_read_lock() since we are protected by mvm->mutex */
for (sta_id = 0; sta_id < IWL_MVM_STATION_COUNT; sta_id++) for (sta_id = 0; sta_id < IWL_MVM_STATION_COUNT; sta_id++) {
if (BIT(sta_id) & reserved_ids)
continue;
if (!rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], if (!rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
lockdep_is_held(&mvm->mutex))) lockdep_is_held(&mvm->mutex)))
return sta_id; return sta_id;
}
return IWL_MVM_STATION_COUNT; return IWL_MVM_STATION_COUNT;
} }
...@@ -312,7 +323,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, ...@@ -312,7 +323,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
sta_id = iwl_mvm_find_free_sta_id(mvm); sta_id = iwl_mvm_find_free_sta_id(mvm,
ieee80211_vif_type_p2p(vif));
else else
sta_id = mvm_sta->sta_id; sta_id = mvm_sta->sta_id;
...@@ -564,10 +576,10 @@ int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm, ...@@ -564,10 +576,10 @@ int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm,
} }
int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
u32 qmask) u32 qmask, enum nl80211_iftype iftype)
{ {
if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
sta->sta_id = iwl_mvm_find_free_sta_id(mvm); sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype);
if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_STATION_COUNT)) if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_STATION_COUNT))
return -ENOSPC; return -ENOSPC;
} }
...@@ -631,7 +643,8 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) ...@@ -631,7 +643,8 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
/* Add the aux station, but without any queues */ /* Add the aux station, but without any queues */
ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, 0); ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, 0,
NL80211_IFTYPE_UNSPECIFIED);
if (ret) if (ret)
return ret; return ret;
...@@ -703,7 +716,8 @@ int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -703,7 +716,8 @@ int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask); ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask,
ieee80211_vif_type_p2p(vif));
if (ret) if (ret)
return ret; return ret;
......
...@@ -384,7 +384,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -384,7 +384,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
u32 qmask); u32 qmask, enum nl80211_iftype iftype);
void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm,
struct iwl_mvm_int_sta *sta); struct iwl_mvm_int_sta *sta);
int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
......
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