Commit 6f71e90e authored by Miri Korenblit's avatar Miri Korenblit Committed by Johannes Berg
Browse files

wifi: iwlwifi: mvm: add an unassign_vif_chanctx() callback for MLD mode



This is another patch in the series adding all the ops
for the new MLD ieee80211_ops.
The callback added here uses the new MLD FW API

Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230314194113.5d4bcd384425.I263eef3aad8efe23a597843fe7c56924038c8fdc@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent daddfae5
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -4551,7 +4551,7 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
 * Returns if chanctx unassign chanctx is done
 * (either on failure or success)
 */
static bool __iwl_mvm_unassign_vif_chanctx_common(struct iwl_mvm *mvm,
bool __iwl_mvm_unassign_vif_chanctx_common(struct iwl_mvm *mvm,
					   struct ieee80211_vif *vif,
					   bool switching_chanctx)
{
+41 −0
Original line number Diff line number Diff line
@@ -205,8 +205,49 @@ static int iwl_mvm_mld_assign_vif_chanctx(struct ieee80211_hw *hw,

	return ret;
}

static void __iwl_mvm_mld_unassign_vif_chanctx(struct iwl_mvm *mvm,
					       struct ieee80211_vif *vif,
					       struct ieee80211_chanctx_conf *ctx,
					       bool switching_chanctx)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);

	if (__iwl_mvm_unassign_vif_chanctx_common(mvm, vif, switching_chanctx))
		goto out;

	if (vif->type == NL80211_IFTYPE_MONITOR)
		iwl_mvm_mld_rm_snif_sta(mvm, vif);

	if (vif->type == NL80211_IFTYPE_AP)
		/* Set CS bit on all the stations */
		iwl_mvm_mld_modify_all_sta_disable_tx(mvm, mvmvif, true);

	/* Link needs to be deactivated before removal */
	iwl_mvm_link_changed(mvm, vif, LINK_CONTEXT_MODIFY_ACTIVE, false);
	iwl_mvm_remove_link(mvm, vif);

out:
	if (switching_chanctx)
		return;
	mvmvif->phy_ctxt = NULL;
	iwl_mvm_power_update_mac(mvm);
}

static void iwl_mvm_mld_unassign_vif_chanctx(struct ieee80211_hw *hw,
					     struct ieee80211_vif *vif,
					     struct ieee80211_bss_conf *link_conf,
					     struct ieee80211_chanctx_conf *ctx)
{
	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);

	mutex_lock(&mvm->mutex);
	__iwl_mvm_mld_unassign_vif_chanctx(mvm, vif, ctx, false);
	mutex_unlock(&mvm->mutex);
}
const struct ieee80211_ops iwl_mvm_mld_hw_ops = {
	.add_interface = iwl_mvm_mld_mac_add_interface,
	.remove_interface = iwl_mvm_mld_mac_remove_interface,
	.assign_vif_chanctx = iwl_mvm_mld_assign_vif_chanctx,
	.unassign_vif_chanctx = iwl_mvm_mld_unassign_vif_chanctx,
};
+58 −0
Original line number Diff line number Diff line
@@ -279,3 +279,61 @@ int iwl_mvm_mld_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
	return iwl_mvm_mld_rm_int_sta(mvm, &mvm->snif_sta, false,
				      IWL_MAX_TID_COUNT, &mvm->snif_queue);
}

static void iwl_mvm_mld_sta_modify_disable_tx(struct iwl_mvm *mvm,
					      struct ieee80211_sta *sta,
					      bool disable)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	struct iwl_mvm_sta_disable_tx_cmd cmd;
	int ret;

	spin_lock_bh(&mvm_sta->lock);

	if (mvm_sta->disable_tx == disable) {
		spin_unlock_bh(&mvm_sta->lock);
		return;
	}

	mvm_sta->disable_tx = disable;

	cmd.sta_id = cpu_to_le32(mvm_sta->sta_id);
	cmd.disable = cpu_to_le32(disable);

	ret = iwl_mvm_send_cmd_pdu(mvm,
				   WIDE_ID(MAC_CONF_GROUP, STA_DISABLE_TX_CMD),
				   CMD_ASYNC, sizeof(cmd), &cmd);
	if (ret)
		IWL_ERR(mvm,
			"Failed to send STA_DISABLE_TX_CMD command (%d)\n",
			ret);

	spin_unlock_bh(&mvm_sta->lock);
}

void iwl_mvm_mld_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
					   struct iwl_mvm_vif *mvmvif,
					   bool disable)
{
	struct ieee80211_sta *sta;
	struct iwl_mvm_sta *mvm_sta;
	int i;

	rcu_read_lock();

	/* Block/unblock all the stations of the given mvmvif */
	for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
		sta = rcu_dereference(mvm->fw_id_to_mac_id[i]);
		if (IS_ERR_OR_NULL(sta))
			continue;

		mvm_sta = iwl_mvm_sta_from_mac80211(sta);
		if (mvm_sta->mac_id_n_color !=
		    FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color))
			continue;

		iwl_mvm_mld_sta_modify_disable_tx(mvm, sta, disable);
	}

	rcu_read_unlock();
}
+3 −0
Original line number Diff line number Diff line
@@ -2173,6 +2173,9 @@ bool __iwl_mvm_assign_vif_chanctx_common(struct iwl_mvm *mvm,
					 struct ieee80211_vif *vif,
					 struct ieee80211_chanctx_conf *ctx,
					 bool switching_chanctx, int *ret);
bool __iwl_mvm_unassign_vif_chanctx_common(struct iwl_mvm *mvm,
					   struct ieee80211_vif *vif,
					   bool switching_chanctx);

/* Channel info utils */
static inline bool iwl_mvm_has_ultra_hb_channel(struct iwl_mvm *mvm)
+7 −0
Original line number Diff line number Diff line
@@ -545,6 +545,7 @@ void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm,
void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
				       struct iwl_mvm_vif *mvmvif,
				       bool disable);

void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk);
int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
@@ -559,8 +560,14 @@ int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm,
			    u8 sta_id, u8 tid, unsigned int timeout);

/* New MLD STA related APIs */
/* STA */
int iwl_mvm_mld_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_mld_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_mld_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_mld_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);

/* Queues */
void iwl_mvm_mld_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
					   struct iwl_mvm_vif *mvmvif,
					   bool disable);
#endif /* __sta_h__ */