summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2023-10-11 13:07:26 +0300
committerJohannes Berg <johannes.berg@intel.com>2023-10-23 12:26:28 +0200
commit34cc3a4a49a6908790234e87cde14cde1a1c5f91 (patch)
tree136659626a55ccd6e1096a39813ea93f81359ceb /drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
parenta32a84948e3b1bb9d76bb198e20c616c4b7810d7 (diff)
wifi: iwlwifi: mvm: fix the PHY context resolution for p2p device
We seem to have an issue in case we had a BSS and a P2P device on channel 1 and then, the P2P device gets an ROC on channel 6. We would change the channel of the PHY context to channel 6 even if the BSS was using that same PHY context. Revamp that code and don't try to change a PHY context, it doesn't mean much for the firmware anyway. Just remove it and allocate a new one. This makes the logic easier to follow. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Link: https://lore.kernel.org/r/20231011130030.4bc8b90d7be0.I1232dca3fe007362ec0ae0cf1d96217f2544e0d2@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c101
1 files changed, 49 insertions, 52 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index d161e2ea1ac5..7d96725da176 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -4634,6 +4634,52 @@ static int iwl_mvm_roc_station(struct iwl_mvm *mvm,
return ret;
}
+static int iwl_mvm_p2p_find_phy_ctxt(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ struct ieee80211_channel *channel)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct cfg80211_chan_def chandef;
+ int i;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ if (mvmvif->deflink.phy_ctxt &&
+ channel == mvmvif->deflink.phy_ctxt->channel)
+ return 0;
+
+ /* Try using a PHY context that is already in use */
+ for (i = 0; i < NUM_PHY_CTX; i++) {
+ struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[i];
+
+ if (!phy_ctxt->ref || mvmvif->deflink.phy_ctxt == phy_ctxt)
+ continue;
+
+ if (channel == phy_ctxt->channel) {
+ if (mvmvif->deflink.phy_ctxt)
+ iwl_mvm_phy_ctxt_unref(mvm,
+ mvmvif->deflink.phy_ctxt);
+
+ mvmvif->deflink.phy_ctxt = phy_ctxt;
+ iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt);
+ return 0;
+ }
+ }
+
+ /* We already have a phy_ctxt, but it's not on the right channel */
+ if (mvmvif->deflink.phy_ctxt)
+ iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt);
+
+ mvmvif->deflink.phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
+ if (!mvmvif->deflink.phy_ctxt)
+ return -ENOSPC;
+
+ cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
+
+ return iwl_mvm_phy_ctxt_add(mvm, mvmvif->deflink.phy_ctxt,
+ &chandef, 1, 1);
+}
+
/* Execute the common part for MLD and non-MLD modes */
int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_channel *channel, int duration,
@@ -4641,11 +4687,8 @@ int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const struct iwl_mvm_roc_ops *ops)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- struct cfg80211_chan_def chandef;
- struct iwl_mvm_phy_ctxt *phy_ctxt;
- int ret, i;
u32 lmac_id;
+ int ret;
IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
duration, type);
@@ -4676,57 +4719,11 @@ int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
goto out_unlock;
}
- /* Try using a PHY context that is already in use */
- for (i = 0; i < NUM_PHY_CTX; i++) {
- phy_ctxt = &mvm->phy_ctxts[i];
- if (!phy_ctxt->ref || mvmvif->deflink.phy_ctxt == phy_ctxt)
- continue;
-
- if (channel == phy_ctxt->channel) {
- if (mvmvif->deflink.phy_ctxt)
- iwl_mvm_phy_ctxt_unref(mvm,
- mvmvif->deflink.phy_ctxt);
-
- mvmvif->deflink.phy_ctxt = phy_ctxt;
- iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt);
- goto link_and_start_p2p_roc;
- }
- }
- /* Configure the PHY context */
- cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
-
- /* If the currently used PHY context is configured with a matching
- * channel use it
- */
- if (mvmvif->deflink.phy_ctxt) {
- if (channel == mvmvif->deflink.phy_ctxt->channel)
- goto link_and_start_p2p_roc;
- } else {
- phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
- if (!phy_ctxt) {
- ret = -ENOSPC;
- goto out_unlock;
- }
-
- mvmvif->deflink.phy_ctxt = phy_ctxt;
- ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, &chandef, 1, 1);
- if (ret) {
- IWL_ERR(mvm, "Failed to change PHY context\n");
- goto out_unlock;
- }
-
- goto link_and_start_p2p_roc;
- }
-
- ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chandef,
- 1, 1);
- if (ret) {
- IWL_ERR(mvm, "Failed to change PHY context\n");
+ ret = iwl_mvm_p2p_find_phy_ctxt(mvm, vif, channel);
+ if (ret)
goto out_unlock;
- }
-link_and_start_p2p_roc:
ret = ops->link(mvm, vif);
if (ret)
goto out_unlock;