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: Eliad Peller <eliadx.peller@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
This commit is contained in:
parent
b800040db5
commit
b92e661b40
@ -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,
|
|||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
&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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user