wifi: iwlwifi: mvm: don't add dummy phy context
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Wed, 11 Oct 2023 10:07:24 +0000 (13:07 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 23 Oct 2023 10:26:27 +0000 (12:26 +0200)
From its very first stages of development, iwlmvm added all the PHY
context immediately upon firmware boot. Then, all we needed to do is to
modify the contexts. This was fine if the addition of a PHY context that
we don't need is free. This was true until now. Newer devices will run
calibrations upon the addition of a PHY context.

Change the way we work with PHY context in iwlmvm. Fortunately, we
already have all the ref counting in place so that it is not very hard
to do.

Also, since we now remove the PHY context before the link is removed
(but after it has been de-activated of course), it'll confuse the
firmware if we put the late phy_id into the LINK command that removes
the link. Change this to put an invalid phy_id just like we do when we
add a link that has no PHY context yet.

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.55a1a78719be.I2032a7d227b57f4fc4370a2793476d47538404fd@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/link.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c

index 233c839de502a6416bd234e186d9b08cb0334146..d791132b3a33d96c6b0b57933c63ebb87fbcb0db 100644 (file)
@@ -1535,8 +1535,6 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
 int iwl_mvm_up(struct iwl_mvm *mvm)
 {
        int ret, i;
-       struct ieee80211_channel *chan;
-       struct cfg80211_chan_def chandef;
        struct ieee80211_supported_band *sband = NULL;
 
        lockdep_assert_held(&mvm->mutex);
@@ -1661,21 +1659,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
                goto error;
        }
 
-       chan = &sband->channels[0];
-
-       cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
-       for (i = 0; i < NUM_PHY_CTX; i++) {
-               /*
-                * The channel used here isn't relevant as it's
-                * going to be overwritten in the other flows.
-                * For now use the first channel we have.
-                */
-               ret = iwl_mvm_phy_ctxt_add(mvm, &mvm->phy_ctxts[i],
-                                          &chandef, 1, 1);
-               if (ret)
-                       goto error;
-       }
-
        if (iwl_mvm_is_tt_in_fw(mvm)) {
                /* in order to give the responsibility of ct-kill and
                 * TX backoff to FW we need to send empty temperature reporting
index 6e1ad65527d128eb97b78629ed4d06b0ff16a5ad..d0d5ebc03d53d83dc1c80102bb06628ae27aa613 100644 (file)
@@ -252,6 +252,7 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
        iwl_mvm_release_fw_link_id(mvm, link_info->fw_link_id);
        link_info->fw_link_id = IWL_MVM_FW_LINK_ID_INVALID;
        cmd.spec_link_id = link_conf->link_id;
+       cmd.phy_id = cpu_to_le32(FW_CTXT_INVALID);
 
        ret = iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_REMOVE);
 
index ce65d74413fbf05c7a2f0f5e634812d9814a49f2..0d78a9efbe2fb7a85b60391109488d8bc511dd14 100644 (file)
@@ -4693,6 +4693,9 @@ int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                }
        }
 
+       /* 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
         */
@@ -4707,12 +4710,16 @@ int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                }
 
                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;
+               }
+
                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);
-
        ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chandef,
                                       1, 1);
        if (ret) {
@@ -4797,9 +4804,9 @@ static int __iwl_mvm_add_chanctx(struct iwl_mvm *mvm,
                goto out;
        }
 
-       ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, def,
-                                      ctx->rx_chains_static,
-                                      ctx->rx_chains_dynamic);
+       ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, def,
+                                  ctx->rx_chains_static,
+                                  ctx->rx_chains_dynamic);
        if (ret) {
                IWL_ERR(mvm, "Failed to add PHY context\n");
                goto out;
index a5b432bc9e2f82e3394c9b1b5761f6c4d3e5857b..c3c1b57a05ce139767c3673ead688197281a2f9a 100644 (file)
@@ -301,7 +301,11 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
 
        lockdep_assert_held(&mvm->mutex);
 
-       if (iwl_fw_lookup_cmd_ver(mvm->fw, WIDE_ID(DATA_PATH_GROUP, RLC_CONFIG_CMD), 0) >= 2 &&
+       if (WARN_ON_ONCE(!ctxt->ref))
+               return -EINVAL;
+
+       if (iwl_fw_lookup_cmd_ver(mvm->fw, WIDE_ID(DATA_PATH_GROUP,
+                                                  RLC_CONFIG_CMD), 0) >= 2 &&
            ctxt->channel == chandef->chan &&
            ctxt->width == chandef->width &&
            ctxt->center_freq1 == chandef->center_freq1)
@@ -335,6 +339,7 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
 
 void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
 {
+       struct cfg80211_chan_def chandef;
        lockdep_assert_held(&mvm->mutex);
 
        if (WARN_ON_ONCE(!ctxt))
@@ -342,41 +347,13 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
 
        ctxt->ref--;
 
-       /*
-        * Move unused phy's to a default channel. When the phy is moved the,
-        * fw will cleanup immediate quiet bit if it was previously set,
-        * otherwise we might not be able to reuse this phy.
-        */
-       if (ctxt->ref == 0) {
-               struct ieee80211_channel *chan = NULL;
-               struct cfg80211_chan_def chandef;
-               struct ieee80211_supported_band *sband;
-               enum nl80211_band band;
-               int channel;
-
-               for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
-                       sband = mvm->hw->wiphy->bands[band];
-
-                       if (!sband)
-                               continue;
-
-                       for (channel = 0; channel < sband->n_channels; channel++)
-                               if (!(sband->channels[channel].flags &
-                                               IEEE80211_CHAN_DISABLED)) {
-                                       chan = &sband->channels[channel];
-                                       break;
-                               }
-
-                       if (chan)
-                               break;
-               }
-
-               if (WARN_ON(!chan))
-                       return;
-
-               cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
-               iwl_mvm_phy_ctxt_changed(mvm, ctxt, &chandef, 1, 1);
-       }
+       if (ctxt->ref)
+               return;
+
+       cfg80211_chandef_create(&chandef, ctxt->channel, NL80211_CHAN_NO_HT);
+
+       iwl_mvm_phy_ctxt_apply(mvm, ctxt, &chandef, 1, 1,
+                              FW_CTXT_ACTION_REMOVE);
 }
 
 static void iwl_mvm_binding_iterator(void *_data, u8 *mac,