Commit 650cadb7 authored by Gregory Greenman's avatar Gregory Greenman Committed by Johannes Berg
Browse files

wifi: iwlwifi: mvm: vif preparation for MLO



In MLO, some fields of iwl_mvm_vif should be defined in the
context of a link. Define a separate structure for these fields and
add a deflink object to hold it as part of iwl_mvm_vif. Non-MLO legacy
code will use only deflink object while MLO related code will use the
corresponding link from the link array.

It follows the strategy applied in mac80211 for introducing MLO
changes.

The below spatch takes care of updating all driver code to access
fields separated into MLD specific data structure via deflink (need
to convert all references to the fields listed in var to deflink.var
and also to take care of calls like iwl_mvm_vif_from_mac80211(vif)->field).

  @iwl_mld_vif@
  struct iwl_mvm_vif *v;
  struct ieee80211_vif *vv;
  identifier fn;
  identifier var = {bssid, ap_sta_id, bcast_sta, mcast_sta,
                    beacon_stats, smps_requests, probe_resp_data,
		    he_ru_2mhz_block, cab_queue, phy_ctxt,
                    queue_params};
  @@

  (
    v->
  -    var
  +    deflink.var
  |
    fn(vv)->
  -    var
  +    deflink.var
  )

Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230328104948.4896576f0a9f.Ifaf0187c96b9fe52b24bd629331165831a877691@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 9a8aac92
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
/*
 * Copyright (C) 2012-2014, 2020 Intel Corporation
 * Copyright (C) 2016 Intel Deutschland GmbH
 * Copyright (C) 2022 Intel Corporation
 */
#include <net/mac80211.h>
#include "fw-api.h"
@@ -75,7 +76,7 @@ static void iwl_mvm_iface_iterator(void *_data, u8 *mac,
	if (vif == data->ignore_vif)
		return;

	if (mvmvif->phy_ctxt != data->phyctxt)
	if (mvmvif->deflink.phy_ctxt != data->phyctxt)
		return;

	if (WARN_ON_ONCE(data->idx >= MAX_MACS_IN_BINDING))
@@ -132,7 +133,7 @@ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);

	if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
	if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt))
		return -EINVAL;

	/*
@@ -142,7 +143,8 @@ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
	if (iwl_mvm_sf_update(mvm, vif, false))
		return -EINVAL;

	return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, true);
	return iwl_mvm_binding_update(mvm, vif, mvmvif->deflink.phy_ctxt,
				      true);
}

int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
@@ -150,10 +152,11 @@ int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	int ret;

	if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
	if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt))
		return -EINVAL;

	ret = iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, false);
	ret = iwl_mvm_binding_update(mvm, vif, mvmvif->deflink.phy_ctxt,
				     false);

	if (!ret)
		if (iwl_mvm_sf_update(mvm, vif, true))
+18 −11
Original line number Diff line number Diff line
@@ -292,7 +292,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
			/* ... relax constraints and disable rssi events */
			iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
					    smps_mode);
			iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
			iwl_mvm_bt_coex_reduced_txp(mvm,
						    mvmvif->deflink.ap_sta_id,
						    false);
			iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
		}
@@ -314,8 +315,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
	if (!vif->cfg.assoc)
		smps_mode = IEEE80211_SMPS_AUTOMATIC;

	if (mvmvif->phy_ctxt &&
	    (mvm->last_bt_notif.rrc_status & BIT(mvmvif->phy_ctxt->id)))
	if (mvmvif->deflink.phy_ctxt &&
	    (mvm->last_bt_notif.rrc_status & BIT(mvmvif->deflink.phy_ctxt->id)))
		smps_mode = IEEE80211_SMPS_AUTOMATIC;

	IWL_DEBUG_COEX(data->mvm,
@@ -384,7 +385,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
	if (iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT ||
	    mvm->cfg->bt_shared_single_ant || !vif->cfg.assoc ||
	    le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF) {
		iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false);
		iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->deflink.ap_sta_id,
					    false);
		iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
		return;
	}
@@ -396,10 +398,12 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
	if (!ave_rssi)
		ave_rssi = -100;
	if (ave_rssi > -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH) {
		if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true))
		if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->deflink.ap_sta_id,
						true))
			IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
	} else if (ave_rssi < -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH) {
		if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false))
		if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->deflink.ap_sta_id,
						false))
			IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
	}

@@ -521,7 +525,7 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
	 * Rssi update while not associated - can happen since the statistics
	 * are handled asynchronously
	 */
	if (mvmvif->ap_sta_id == IWL_MVM_INVALID_STA)
	if (mvmvif->deflink.ap_sta_id == IWL_MVM_INVALID_STA)
		return;

	/* No BT - reports should be disabled */
@@ -537,10 +541,13 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
	 */
	if (rssi_event == RSSI_EVENT_LOW || mvm->cfg->bt_shared_single_ant ||
	    iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT)
		ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
		ret = iwl_mvm_bt_coex_reduced_txp(mvm,
						  mvmvif->deflink.ap_sta_id,
						  false);
	else
		ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true);
		ret = iwl_mvm_bt_coex_reduced_txp(mvm,
						  mvmvif->deflink.ap_sta_id,
						  true);

	if (ret)
		IWL_ERR(mvm, "couldn't send BT_CONFIG HCMD upon RSSI event\n");
@@ -554,7 +561,7 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
{
	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
	struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
	struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->deflink.phy_ctxt;
	enum iwl_bt_coex_lut_type lut_type;

	if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id))
@@ -578,7 +585,7 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
{
	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
	struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
	struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->deflink.phy_ctxt;
	enum iwl_bt_coex_lut_type lut_type;

	if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id))
+21 −18
Original line number Diff line number Diff line
@@ -470,7 +470,7 @@ static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm,
		for (i = 0; i < ARRAY_SIZE(data.rsc->mcast_key_id_map); i++)
			data.rsc->mcast_key_id_map[i] =
				IWL_MCAST_KEY_MAP_INVALID;
		data.rsc->sta_id = cpu_to_le32(mvmvif->ap_sta_id);
		data.rsc->sta_id = cpu_to_le32(mvmvif->deflink.ap_sta_id);

		ieee80211_iter_keys(mvm->hw, vif,
				    iwl_mvm_wowlan_get_rsc_v5_data,
@@ -493,7 +493,8 @@ static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm,

		if (ver == 4) {
			size = sizeof(*data.rsc_tsc);
			data.rsc_tsc->sta_id = cpu_to_le32(mvmvif->ap_sta_id);
			data.rsc_tsc->sta_id =
				cpu_to_le32(mvmvif->deflink.ap_sta_id);
		} else {
			/* ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN */
			size = sizeof(data.rsc_tsc->params);
@@ -691,7 +692,7 @@ static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,

	pattern_cmd->n_patterns = wowlan->n_patterns;
	if (ver >= 3)
		pattern_cmd->sta_id = mvmvif->ap_sta_id;
		pattern_cmd->sta_id = mvmvif->deflink.ap_sta_id;

	for (i = 0; i < wowlan->n_patterns; i++) {
		int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
@@ -732,7 +733,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
		return -EINVAL;

	/* add back the PHY */
	if (WARN_ON(!mvmvif->phy_ctxt))
	if (WARN_ON(!mvmvif->deflink.phy_ctxt))
		return -EINVAL;

	rcu_read_lock();
@@ -746,7 +747,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
	chains_dynamic = ctx->rx_chains_dynamic;
	rcu_read_unlock();

	ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt, &chandef,
	ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->deflink.phy_ctxt, &chandef,
				   chains_static, chains_dynamic);
	if (ret)
		return ret;
@@ -763,12 +764,12 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,

	/* add back binding - XXX refactor? */
	binding_cmd.id_and_color =
		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
						mvmvif->phy_ctxt->color));
		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id,
						mvmvif->deflink.phy_ctxt->color));
	binding_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
	binding_cmd.phy =
		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
						mvmvif->phy_ctxt->color));
		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id,
						mvmvif->deflink.phy_ctxt->color));
	binding_cmd.macs[0] = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
							      mvmvif->color));
	for (i = 1; i < MAX_MACS_IN_BINDING; i++)
@@ -791,7 +792,8 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
	ret = iwl_mvm_sta_send_to_fw(mvm, ap_sta, false, 0);
	if (ret)
		return ret;
	rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);
	rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id],
			   ap_sta);

	ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
	if (ret)
@@ -800,8 +802,8 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
	/* and some quota */
	quota = iwl_mvm_quota_cmd_get_quota(mvm, &quota_cmd, 0);
	quota->id_and_color =
		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
						mvmvif->phy_ctxt->color));
		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id,
						mvmvif->deflink.phy_ctxt->color));
	quota->quota = cpu_to_le32(IWL_MVM_MAX_QUOTA);
	quota->max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);

@@ -1027,7 +1029,7 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
		if (ver == 2) {
			size = sizeof(tkip_data.tkip);
			tkip_data.tkip.sta_id =
				cpu_to_le32(mvmvif->ap_sta_id);
				cpu_to_le32(mvmvif->deflink.ap_sta_id);
		} else if (ver == 1 || ver == IWL_FW_CMD_VER_UNKNOWN) {
			size = sizeof(struct iwl_wowlan_tkip_params_cmd_ver_1);
		} else {
@@ -1076,7 +1078,7 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
		kek_kck_cmd.kek_len = cpu_to_le16(mvmvif->rekey_data.kek_len);
		kek_kck_cmd.replay_ctr = mvmvif->rekey_data.replay_ctr;
		kek_kck_cmd.akm = cpu_to_le32(mvmvif->rekey_data.akm);
		kek_kck_cmd.sta_id = cpu_to_le32(mvmvif->ap_sta_id);
		kek_kck_cmd.sta_id = cpu_to_le32(mvmvif->deflink.ap_sta_id);

		if (cmd_ver == 4) {
			cmd_size = sizeof(struct iwl_wowlan_kek_kck_material_cmd_v4);
@@ -1269,7 +1271,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,

	mvmvif = iwl_mvm_vif_from_mac80211(vif);

	if (mvmvif->ap_sta_id == IWL_MVM_INVALID_STA) {
	if (mvmvif->deflink.ap_sta_id == IWL_MVM_INVALID_STA) {
		/* if we're not associated, this must be netdetect */
		if (!wowlan->nd_config) {
			ret = 1;
@@ -1285,10 +1287,10 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
	} else {
		struct iwl_wowlan_config_cmd wowlan_config_cmd = {};

		wowlan_config_cmd.sta_id = mvmvif->ap_sta_id;
		wowlan_config_cmd.sta_id = mvmvif->deflink.ap_sta_id;

		ap_sta = rcu_dereference_protected(
			mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
			mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id],
			lockdep_is_held(&mvm->mutex));
		if (IS_ERR_OR_NULL(ap_sta)) {
			ret = -EINVAL;
@@ -2575,7 +2577,8 @@ iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm *mvm,
	/* if FW uses status notification, status shouldn't be NULL here */
	if (!d3_data->status) {
		struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
		u8 sta_id = mvm->net_detect ? IWL_MVM_INVALID_STA : mvmvif->ap_sta_id;
		u8 sta_id = mvm->net_detect ? IWL_MVM_INVALID_STA :
					      mvmvif->deflink.ap_sta_id;

		d3_data->status = iwl_mvm_send_wowlan_get_status(mvm, sta_id);
	}
+7 −7
Original line number Diff line number Diff line
@@ -179,7 +179,7 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file,

	mutex_lock(&mvm->mutex);

	ap_sta_id = mvmvif->ap_sta_id;
	ap_sta_id = mvmvif->deflink.ap_sta_id;

	switch (ieee80211_vif_type_p2p(vif)) {
	case NL80211_IFTYPE_ADHOC:
@@ -211,14 +211,14 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
	pos += scnprintf(buf+pos, bufsz-pos, "Load: %d\n",
			 mvm->tcm.result.load[mvmvif->id]);
	pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
	for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++)
	for (i = 0; i < ARRAY_SIZE(mvmvif->deflink.queue_params); i++)
		pos += scnprintf(buf+pos, bufsz-pos,
				 "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
				 i, mvmvif->queue_params[i].txop,
				 mvmvif->queue_params[i].cw_min,
				 mvmvif->queue_params[i].cw_max,
				 mvmvif->queue_params[i].aifs,
				 mvmvif->queue_params[i].uapsd);
				 i, mvmvif->deflink.queue_params[i].txop,
				 mvmvif->deflink.queue_params[i].cw_min,
				 mvmvif->deflink.queue_params[i].cw_max,
				 mvmvif->deflink.queue_params[i].aifs,
				 mvmvif->deflink.queue_params[i].uapsd);

	if (vif->type == NL80211_IFTYPE_STATION &&
	    ap_sta_id != IWL_MVM_INVALID_STA) {
+3 −3
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ int iwl_mvm_ftm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
		struct ieee80211_sta *sta;

		rcu_read_lock();
		sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id]);
		sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id]);
		if (!IS_ERR_OR_NULL(sta) && sta->mfp)
			expected_tk_len = 0;
		rcu_read_unlock();
@@ -510,13 +510,13 @@ iwl_mvm_ftm_put_target(struct iwl_mvm *mvm, struct ieee80211_vif *vif,

		rcu_read_lock();

		sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id]);
		sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id]);
		if (sta->mfp && (peer->ftm.trigger_based || peer->ftm.non_trigger_based))
			FTM_PUT_FLAG(PMF);

		rcu_read_unlock();

		target->sta_id = mvmvif->ap_sta_id;
		target->sta_id = mvmvif->deflink.ap_sta_id;
	} else {
		target->sta_id = IWL_MVM_INVALID_STA;
	}
Loading