iwlwifi: mvm: don't change band on bound PHY contexts
[ Upstream commit 8835a64f74c46baebfc946cd5a2c861b866ebcee ] When we have a P2P Device active, we attempt to only change the PHY context it uses when we get a new remain-on-channel, if the P2P Device is the only user of the PHY context. This is fine if we're switching within a band, but if we're switching bands then the switch implies a removal and re-add of the PHY context, which isn't permitted by the firmware while it's bound to an interface. Fix the code to skip the unbind/release/... cycle only if the band doesn't change (or we have old devices that can switch the band on the fly as well.) Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Link: https://lore.kernel.org/r/iwlwifi.20210612142637.e9ac313f70f3.I713b9d109957df7e7d9ed0861d5377ce3f8fccd3@changeid Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
1df3603039
commit
1e1bb1efd6
@@ -3794,6 +3794,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
|
|||||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||||
struct cfg80211_chan_def chandef;
|
struct cfg80211_chan_def chandef;
|
||||||
struct iwl_mvm_phy_ctxt *phy_ctxt;
|
struct iwl_mvm_phy_ctxt *phy_ctxt;
|
||||||
|
bool band_change_removal;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
|
IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
|
||||||
@@ -3874,19 +3875,30 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
|
|||||||
cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
|
cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change the PHY context configuration as it is currently referenced
|
* Check if the remain-on-channel is on a different band and that
|
||||||
* only by the P2P Device MAC
|
* requires context removal, see iwl_mvm_phy_ctxt_changed(). If
|
||||||
|
* so, we'll need to release and then re-configure here, since we
|
||||||
|
* must not remove a PHY context that's part of a binding.
|
||||||
|
*/
|
||||||
|
band_change_removal =
|
||||||
|
fw_has_capa(&mvm->fw->ucode_capa,
|
||||||
|
IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) &&
|
||||||
|
mvmvif->phy_ctxt->channel->band != chandef.chan->band;
|
||||||
|
|
||||||
|
if (mvmvif->phy_ctxt->ref == 1 && !band_change_removal) {
|
||||||
|
/*
|
||||||
|
* Change the PHY context configuration as it is currently
|
||||||
|
* referenced only by the P2P Device MAC (and we can modify it)
|
||||||
*/
|
*/
|
||||||
if (mvmvif->phy_ctxt->ref == 1) {
|
|
||||||
ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
|
ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
|
||||||
&chandef, 1, 1);
|
&chandef, 1, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* The PHY context is shared with other MACs. Need to remove the
|
* The PHY context is shared with other MACs (or we're trying to
|
||||||
* P2P Device from the binding, allocate an new PHY context and
|
* switch bands), so remove the P2P Device from the binding,
|
||||||
* create a new binding
|
* allocate an new PHY context and create a new binding.
|
||||||
*/
|
*/
|
||||||
phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
|
phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
|
||||||
if (!phy_ctxt) {
|
if (!phy_ctxt) {
|
||||||
|
Reference in New Issue
Block a user