@@ -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
@@ -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);
@@ -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;
@@ -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,