mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
iwlwifi: mvm: Change PHY context handling
1. All the phy contexts are added immediately after the firmware is loaded and up. 2. Whenever a PHY context needs to be used, its reference counter is incremented and the PHY context is being configured to the appropriate configuration. 3. When a PHY context is no longer needed, its reference count is decremented. 4. PHY contexts are never removed. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
fe0f2de30c
commit
53a9d61eb7
@ -388,6 +388,8 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
|||||||
int iwl_mvm_up(struct iwl_mvm *mvm)
|
int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||||
{
|
{
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
struct ieee80211_channel *chan;
|
||||||
|
struct cfg80211_chan_def chandef;
|
||||||
|
|
||||||
lockdep_assert_held(&mvm->mutex);
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
@ -443,8 +445,22 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
|
/* Add all the PHY contexts */
|
||||||
|
chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->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;
|
||||||
|
}
|
||||||
|
|
||||||
|
IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
iwl_trans_stop_device(mvm->trans);
|
iwl_trans_stop_device(mvm->trans);
|
||||||
|
@ -576,8 +576,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
|||||||
* MAC context is bound to it at this stage.
|
* MAC context is bound to it at this stage.
|
||||||
*/
|
*/
|
||||||
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
||||||
struct ieee80211_channel *chan;
|
|
||||||
struct cfg80211_chan_def chandef;
|
|
||||||
|
|
||||||
mvmvif->phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
|
mvmvif->phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
|
||||||
if (!mvmvif->phy_ctxt) {
|
if (!mvmvif->phy_ctxt) {
|
||||||
@ -585,21 +583,10 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
|||||||
goto out_remove_mac;
|
goto out_remove_mac;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
|
||||||
* The channel used here isn't relevant as it's
|
|
||||||
* going to be overwritten as part of the ROC flow.
|
|
||||||
* For now use the first channel we have.
|
|
||||||
*/
|
|
||||||
chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
|
|
||||||
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
|
|
||||||
ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt,
|
|
||||||
&chandef, 1, 1);
|
|
||||||
if (ret)
|
|
||||||
goto out_remove_mac;
|
|
||||||
|
|
||||||
ret = iwl_mvm_binding_add_vif(mvm, vif);
|
ret = iwl_mvm_binding_add_vif(mvm, vif);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_remove_phy;
|
goto out_unref_phy;
|
||||||
|
|
||||||
ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
|
ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -615,7 +602,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
|||||||
|
|
||||||
out_unbind:
|
out_unbind:
|
||||||
iwl_mvm_binding_remove_vif(mvm, vif);
|
iwl_mvm_binding_remove_vif(mvm, vif);
|
||||||
out_remove_phy:
|
out_unref_phy:
|
||||||
iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
|
iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
|
||||||
out_remove_mac:
|
out_remove_mac:
|
||||||
mvmvif->phy_ctxt = NULL;
|
mvmvif->phy_ctxt = NULL;
|
||||||
@ -1254,7 +1241,7 @@ static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
|
|||||||
struct iwl_mvm_phy_ctxt *phy_ctxt;
|
struct iwl_mvm_phy_ctxt *phy_ctxt;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
IWL_DEBUG_MAC80211(mvm, "Add PHY context\n");
|
IWL_DEBUG_MAC80211(mvm, "Add channel context\n");
|
||||||
|
|
||||||
mutex_lock(&mvm->mutex);
|
mutex_lock(&mvm->mutex);
|
||||||
phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
|
phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
|
||||||
@ -1263,14 +1250,15 @@ static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, &ctx->def,
|
ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
|
||||||
ctx->rx_chains_static,
|
ctx->rx_chains_static,
|
||||||
ctx->rx_chains_dynamic);
|
ctx->rx_chains_dynamic);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
IWL_ERR(mvm, "Failed to add PHY context\n");
|
IWL_ERR(mvm, "Failed to add PHY context\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iwl_mvm_phy_ctxt_ref(mvm, phy_ctxt);
|
||||||
*phy_ctxt_id = phy_ctxt->id;
|
*phy_ctxt_id = phy_ctxt->id;
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&mvm->mutex);
|
mutex_unlock(&mvm->mutex);
|
||||||
|
@ -212,8 +212,6 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
|
|||||||
chains_static, chains_dynamic,
|
chains_static, chains_dynamic,
|
||||||
FW_CTXT_ACTION_ADD, 0);
|
FW_CTXT_ACTION_ADD, 0);
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
ctxt->ref = 1;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,9 +221,7 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
|
|||||||
*/
|
*/
|
||||||
void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
|
void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
|
||||||
{
|
{
|
||||||
WARN_ON(!ctxt->ref);
|
|
||||||
lockdep_assert_held(&mvm->mutex);
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
ctxt->ref++;
|
ctxt->ref++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,36 +242,8 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
|
|||||||
FW_CTXT_ACTION_MODIFY, 0);
|
FW_CTXT_ACTION_MODIFY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Send a command to the FW to remove the given phy context.
|
|
||||||
* Once the command is sent, regardless of success or failure, the context is
|
|
||||||
* marked as invalid
|
|
||||||
*/
|
|
||||||
static void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm,
|
|
||||||
struct iwl_mvm_phy_ctxt *ctxt)
|
|
||||||
{
|
|
||||||
struct iwl_phy_context_cmd cmd;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
lockdep_assert_held(&mvm->mutex);
|
|
||||||
|
|
||||||
iwl_mvm_phy_ctxt_cmd_hdr(ctxt, &cmd, FW_CTXT_ACTION_REMOVE, 0);
|
|
||||||
ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, CMD_SYNC,
|
|
||||||
sizeof(struct iwl_phy_context_cmd),
|
|
||||||
&cmd);
|
|
||||||
ctxt->channel = NULL;
|
|
||||||
if (ret)
|
|
||||||
IWL_ERR(mvm, "Failed to send PHY remove: ctxt id=%d\n",
|
|
||||||
ctxt->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iwl_mvm_phy_ctxt_unref(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)
|
||||||
{
|
{
|
||||||
lockdep_assert_held(&mvm->mutex);
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
ctxt->ref--;
|
ctxt->ref--;
|
||||||
if (ctxt->ref != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
return iwl_mvm_phy_ctxt_remove(mvm, ctxt);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user