xref: /linux/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac.c (revision 79790b6818e96c58fe2bffee1b418c16e64e7b80)
19be162a7SMiri Korenblit // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
29be162a7SMiri Korenblit /*
359214747SIlan Peer  * Copyright (C) 2022 - 2024 Intel Corporation
49be162a7SMiri Korenblit  */
59be162a7SMiri Korenblit #include "mvm.h"
69be162a7SMiri Korenblit 
iwl_mvm_mld_set_he_support(struct iwl_mvm * mvm,struct ieee80211_vif * vif,struct iwl_mac_config_cmd * cmd)7bb7fcb37SJohannes Berg static void iwl_mvm_mld_set_he_support(struct iwl_mvm *mvm,
8bb7fcb37SJohannes Berg 				       struct ieee80211_vif *vif,
9bb7fcb37SJohannes Berg 				       struct iwl_mac_config_cmd *cmd)
10bb7fcb37SJohannes Berg {
11bb7fcb37SJohannes Berg 	if (vif->type == NL80211_IFTYPE_AP)
12bb7fcb37SJohannes Berg 		cmd->he_ap_support = cpu_to_le16(1);
13bb7fcb37SJohannes Berg 	else
14bb7fcb37SJohannes Berg 		cmd->he_support = cpu_to_le16(1);
15bb7fcb37SJohannes Berg }
16bb7fcb37SJohannes Berg 
iwl_mvm_mld_mac_ctxt_cmd_common(struct iwl_mvm * mvm,struct ieee80211_vif * vif,struct iwl_mac_config_cmd * cmd,u32 action)179be162a7SMiri Korenblit static void iwl_mvm_mld_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
189be162a7SMiri Korenblit 					    struct ieee80211_vif *vif,
199be162a7SMiri Korenblit 					    struct iwl_mac_config_cmd *cmd,
209be162a7SMiri Korenblit 					    u32 action)
219be162a7SMiri Korenblit {
229be162a7SMiri Korenblit 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2336cf5377SGregory Greenman 	struct ieee80211_bss_conf *link_conf;
2436cf5377SGregory Greenman 	unsigned int link_id;
259be162a7SMiri Korenblit 
269be162a7SMiri Korenblit 	cmd->id_and_color = cpu_to_le32(mvmvif->id);
279be162a7SMiri Korenblit 	cmd->action = cpu_to_le32(action);
289be162a7SMiri Korenblit 
299be162a7SMiri Korenblit 	cmd->mac_type = cpu_to_le32(iwl_mvm_get_mac_type(vif));
309be162a7SMiri Korenblit 
319be162a7SMiri Korenblit 	memcpy(cmd->local_mld_addr, vif->addr, ETH_ALEN);
329be162a7SMiri Korenblit 
3336cf5377SGregory Greenman 	cmd->he_support = 0;
3436cf5377SGregory Greenman 	cmd->eht_support = 0;
3536cf5377SGregory Greenman 
3636cf5377SGregory Greenman 	/* should be set by specific context type handler */
3736cf5377SGregory Greenman 	cmd->filter_flags = 0;
389be162a7SMiri Korenblit 
399be162a7SMiri Korenblit 	cmd->nic_not_ack_enabled =
409be162a7SMiri Korenblit 		cpu_to_le32(!iwl_mvm_is_nic_ack_enabled(mvm, vif));
419be162a7SMiri Korenblit 
429be162a7SMiri Korenblit 	if (iwlwifi_mod_params.disable_11ax)
439be162a7SMiri Korenblit 		return;
449be162a7SMiri Korenblit 
4536cf5377SGregory Greenman 	/* If we have MLO enabled, then the firmware needs to enable
4636cf5377SGregory Greenman 	 * address translation for the station(s) we add. That depends
4736cf5377SGregory Greenman 	 * on having EHT enabled in firmware, which in turn depends on
4836cf5377SGregory Greenman 	 * mac80211 in the code below.
4936cf5377SGregory Greenman 	 * However, mac80211 doesn't enable HE/EHT until it has parsed
5036cf5377SGregory Greenman 	 * the association response successfully, so just skip all that
5136cf5377SGregory Greenman 	 * and enable both when we have MLO.
5236cf5377SGregory Greenman 	 */
5398d8a003SIlan Peer 	if (ieee80211_vif_is_mld(vif)) {
54bb7fcb37SJohannes Berg 		iwl_mvm_mld_set_he_support(mvm, vif, cmd);
5536cf5377SGregory Greenman 		cmd->eht_support = cpu_to_le32(1);
5636cf5377SGregory Greenman 		return;
5736cf5377SGregory Greenman 	}
5836cf5377SGregory Greenman 
5936cf5377SGregory Greenman 	rcu_read_lock();
6036cf5377SGregory Greenman 	for (link_id = 0; link_id < ARRAY_SIZE((vif)->link_conf); link_id++) {
6136cf5377SGregory Greenman 		link_conf = rcu_dereference(vif->link_conf[link_id]);
6236cf5377SGregory Greenman 		if (!link_conf)
6336cf5377SGregory Greenman 			continue;
6436cf5377SGregory Greenman 
6536cf5377SGregory Greenman 		if (link_conf->he_support)
66bb7fcb37SJohannes Berg 			iwl_mvm_mld_set_he_support(mvm, vif, cmd);
6736cf5377SGregory Greenman 
6836cf5377SGregory Greenman 		/* it's not reasonable to have EHT without HE and FW API doesn't
6936cf5377SGregory Greenman 		 * support it. Ignore EHT in this case.
7036cf5377SGregory Greenman 		 */
7136cf5377SGregory Greenman 		if (!link_conf->he_support && link_conf->eht_support)
7236cf5377SGregory Greenman 			continue;
7336cf5377SGregory Greenman 
7436cf5377SGregory Greenman 		if (link_conf->eht_support) {
7536cf5377SGregory Greenman 			cmd->eht_support = cpu_to_le32(1);
7636cf5377SGregory Greenman 			break;
7736cf5377SGregory Greenman 		}
7836cf5377SGregory Greenman 	}
7936cf5377SGregory Greenman 	rcu_read_unlock();
809be162a7SMiri Korenblit }
819be162a7SMiri Korenblit 
iwl_mvm_mld_mac_ctxt_send_cmd(struct iwl_mvm * mvm,struct iwl_mac_config_cmd * cmd)829be162a7SMiri Korenblit static int iwl_mvm_mld_mac_ctxt_send_cmd(struct iwl_mvm *mvm,
839be162a7SMiri Korenblit 					 struct iwl_mac_config_cmd *cmd)
849be162a7SMiri Korenblit {
859be162a7SMiri Korenblit 	int ret = iwl_mvm_send_cmd_pdu(mvm,
869be162a7SMiri Korenblit 				       WIDE_ID(MAC_CONF_GROUP, MAC_CONFIG_CMD),
879be162a7SMiri Korenblit 				       0, sizeof(*cmd), cmd);
889be162a7SMiri Korenblit 	if (ret)
899be162a7SMiri Korenblit 		IWL_ERR(mvm, "Failed to send MAC_CONFIG_CMD (action:%d): %d\n",
909be162a7SMiri Korenblit 			le32_to_cpu(cmd->action), ret);
919be162a7SMiri Korenblit 	return ret;
929be162a7SMiri Korenblit }
939be162a7SMiri Korenblit 
iwl_mvm_mld_mac_ctxt_cmd_sta(struct iwl_mvm * mvm,struct ieee80211_vif * vif,u32 action,bool force_assoc_off)949be162a7SMiri Korenblit static int iwl_mvm_mld_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
959be162a7SMiri Korenblit 					struct ieee80211_vif *vif,
969be162a7SMiri Korenblit 					u32 action, bool force_assoc_off)
979be162a7SMiri Korenblit {
989be162a7SMiri Korenblit 	struct iwl_mac_config_cmd cmd = {};
996107f300SEmmanuel Grumbach 	u16 esr_transition_timeout;
1009be162a7SMiri Korenblit 
1019be162a7SMiri Korenblit 	WARN_ON(vif->type != NL80211_IFTYPE_STATION);
1029be162a7SMiri Korenblit 
1039be162a7SMiri Korenblit 	/* Fill the common data for all mac context types */
1049be162a7SMiri Korenblit 	iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
1059be162a7SMiri Korenblit 
1069be162a7SMiri Korenblit 	/*
1079be162a7SMiri Korenblit 	 * We always want to hear MCAST frames, if we're not authorized yet,
1089be162a7SMiri Korenblit 	 * we'll drop them.
1099be162a7SMiri Korenblit 	 */
1109be162a7SMiri Korenblit 	cmd.filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_GRP);
1119be162a7SMiri Korenblit 
1129be162a7SMiri Korenblit 	if (vif->p2p)
1139be162a7SMiri Korenblit 		cmd.client.ctwin =
1149be162a7SMiri Korenblit 			iwl_mvm_mac_ctxt_cmd_p2p_sta_get_oppps_ctwin(mvm, vif);
1159be162a7SMiri Korenblit 
116ac251da9SJohannes Berg 	if (vif->cfg.assoc && !force_assoc_off) {
1179be162a7SMiri Korenblit 		struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1189be162a7SMiri Korenblit 
1193f302269SEmmanuel Grumbach 		cmd.client.is_assoc = 1;
1209be162a7SMiri Korenblit 
1219be162a7SMiri Korenblit 		if (!mvmvif->authorized &&
1229be162a7SMiri Korenblit 		    fw_has_capa(&mvm->fw->ucode_capa,
1239be162a7SMiri Korenblit 				IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO))
1249be162a7SMiri Korenblit 			cmd.client.data_policy |=
1253f302269SEmmanuel Grumbach 				cpu_to_le16(COEX_HIGH_PRIORITY_ENABLE);
1269be162a7SMiri Korenblit 
1279be162a7SMiri Korenblit 	} else {
1283f302269SEmmanuel Grumbach 		cmd.client.is_assoc = 0;
1299be162a7SMiri Korenblit 
1309be162a7SMiri Korenblit 		/* Allow beacons to pass through as long as we are not
1319be162a7SMiri Korenblit 		 * associated, or we do not have dtim period information.
1329be162a7SMiri Korenblit 		 */
1339be162a7SMiri Korenblit 		cmd.filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_BEACON);
1349be162a7SMiri Korenblit 	}
1359be162a7SMiri Korenblit 
1363f302269SEmmanuel Grumbach 	cmd.client.assoc_id = cpu_to_le16(vif->cfg.aid);
1376107f300SEmmanuel Grumbach 	if (ieee80211_vif_is_mld(vif)) {
1386107f300SEmmanuel Grumbach 		esr_transition_timeout =
1396107f300SEmmanuel Grumbach 			u16_get_bits(vif->cfg.eml_cap,
1406107f300SEmmanuel Grumbach 				     IEEE80211_EML_CAP_TRANSITION_TIMEOUT);
1416107f300SEmmanuel Grumbach 
1426107f300SEmmanuel Grumbach 		cmd.client.esr_transition_timeout =
1436107f300SEmmanuel Grumbach 			min_t(u16, IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU,
1446107f300SEmmanuel Grumbach 			      esr_transition_timeout);
1456107f300SEmmanuel Grumbach 		cmd.client.medium_sync_delay =
1466107f300SEmmanuel Grumbach 			cpu_to_le16(vif->cfg.eml_med_sync_delay);
1476107f300SEmmanuel Grumbach 	}
1489be162a7SMiri Korenblit 
1499be162a7SMiri Korenblit 	if (vif->probe_req_reg && vif->cfg.assoc && vif->p2p)
1509be162a7SMiri Korenblit 		cmd.filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_PROBE_REQ);
1519be162a7SMiri Korenblit 
1529be162a7SMiri Korenblit 	if (vif->bss_conf.he_support && !iwlwifi_mod_params.disable_11ax)
1539be162a7SMiri Korenblit 		cmd.client.data_policy |=
1543f302269SEmmanuel Grumbach 			cpu_to_le16(iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(mvm, vif));
1559be162a7SMiri Korenblit 
1569be162a7SMiri Korenblit 	return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);
1579be162a7SMiri Korenblit }
1589be162a7SMiri Korenblit 
iwl_mvm_mld_mac_ctxt_cmd_listener(struct iwl_mvm * mvm,struct ieee80211_vif * vif,u32 action)1599be162a7SMiri Korenblit static int iwl_mvm_mld_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
1609be162a7SMiri Korenblit 					     struct ieee80211_vif *vif,
1619be162a7SMiri Korenblit 					     u32 action)
1629be162a7SMiri Korenblit {
1639be162a7SMiri Korenblit 	struct iwl_mac_config_cmd cmd = {};
1649be162a7SMiri Korenblit 
1659be162a7SMiri Korenblit 	WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
1669be162a7SMiri Korenblit 
1679be162a7SMiri Korenblit 	iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
1689be162a7SMiri Korenblit 
1699be162a7SMiri Korenblit 	cmd.filter_flags = cpu_to_le32(MAC_CFG_FILTER_PROMISC |
170*4cdb8648SIlan Peer 				       MAC_CFG_FILTER_ACCEPT_CONTROL_AND_MGMT |
1719be162a7SMiri Korenblit 				       MAC_CFG_FILTER_ACCEPT_BEACON |
1729be162a7SMiri Korenblit 				       MAC_CFG_FILTER_ACCEPT_PROBE_REQ |
1739be162a7SMiri Korenblit 				       MAC_CFG_FILTER_ACCEPT_GRP);
1749be162a7SMiri Korenblit 
1759be162a7SMiri Korenblit 	return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);
1769be162a7SMiri Korenblit }
1779be162a7SMiri Korenblit 
iwl_mvm_mld_mac_ctxt_cmd_ibss(struct iwl_mvm * mvm,struct ieee80211_vif * vif,u32 action)1789be162a7SMiri Korenblit static int iwl_mvm_mld_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm,
1799be162a7SMiri Korenblit 					 struct ieee80211_vif *vif,
1809be162a7SMiri Korenblit 					 u32 action)
1819be162a7SMiri Korenblit {
1829be162a7SMiri Korenblit 	struct iwl_mac_config_cmd cmd = {};
1839be162a7SMiri Korenblit 
1849be162a7SMiri Korenblit 	WARN_ON(vif->type != NL80211_IFTYPE_ADHOC);
1859be162a7SMiri Korenblit 
1869be162a7SMiri Korenblit 	iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
1879be162a7SMiri Korenblit 
1889be162a7SMiri Korenblit 	cmd.filter_flags = cpu_to_le32(MAC_CFG_FILTER_ACCEPT_BEACON |
1899be162a7SMiri Korenblit 				       MAC_CFG_FILTER_ACCEPT_PROBE_REQ |
1909be162a7SMiri Korenblit 				       MAC_CFG_FILTER_ACCEPT_GRP);
1919be162a7SMiri Korenblit 
1929be162a7SMiri Korenblit 	return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);
1939be162a7SMiri Korenblit }
1949be162a7SMiri Korenblit 
iwl_mvm_mld_mac_ctxt_cmd_p2p_device(struct iwl_mvm * mvm,struct ieee80211_vif * vif,u32 action)1959be162a7SMiri Korenblit static int iwl_mvm_mld_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm,
1969be162a7SMiri Korenblit 					       struct ieee80211_vif *vif,
1979be162a7SMiri Korenblit 					       u32 action)
1989be162a7SMiri Korenblit {
1999be162a7SMiri Korenblit 	struct iwl_mac_config_cmd cmd = {};
2009be162a7SMiri Korenblit 
2019be162a7SMiri Korenblit 	WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE);
2029be162a7SMiri Korenblit 
2039be162a7SMiri Korenblit 	iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
2049be162a7SMiri Korenblit 
2059be162a7SMiri Korenblit 	cmd.p2p_dev.is_disc_extended =
2069be162a7SMiri Korenblit 		iwl_mac_ctxt_p2p_dev_has_extended_disc(mvm, vif);
2079be162a7SMiri Korenblit 
20859214747SIlan Peer 	/* Override the filter flags to accept all management frames. This is
20959214747SIlan Peer 	 * needed to support both P2P device discovery using probe requests and
21059214747SIlan Peer 	 * P2P service discovery using action frames
21159214747SIlan Peer 	 */
21259214747SIlan Peer 	cmd.filter_flags = cpu_to_le32(MAC_CFG_FILTER_ACCEPT_CONTROL_AND_MGMT);
2139be162a7SMiri Korenblit 
2149be162a7SMiri Korenblit 	return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);
2159be162a7SMiri Korenblit }
2169be162a7SMiri Korenblit 
iwl_mvm_mld_mac_ctxt_cmd_ap_go(struct iwl_mvm * mvm,struct ieee80211_vif * vif,u32 action)2179be162a7SMiri Korenblit static int iwl_mvm_mld_mac_ctxt_cmd_ap_go(struct iwl_mvm *mvm,
2189be162a7SMiri Korenblit 					  struct ieee80211_vif *vif,
2199be162a7SMiri Korenblit 					  u32 action)
2209be162a7SMiri Korenblit {
2219be162a7SMiri Korenblit 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2229be162a7SMiri Korenblit 	struct iwl_mac_config_cmd cmd = {};
2239be162a7SMiri Korenblit 
2249be162a7SMiri Korenblit 	WARN_ON(vif->type != NL80211_IFTYPE_AP);
2259be162a7SMiri Korenblit 
2269be162a7SMiri Korenblit 	/* Fill the common data for all mac context types */
2279be162a7SMiri Korenblit 	iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
2289be162a7SMiri Korenblit 
2299be162a7SMiri Korenblit 	iwl_mvm_mac_ctxt_cmd_ap_set_filter_flags(mvm, mvmvif,
2309be162a7SMiri Korenblit 						 &cmd.filter_flags,
2319be162a7SMiri Korenblit 						 MAC_CFG_FILTER_ACCEPT_PROBE_REQ,
2329be162a7SMiri Korenblit 						 MAC_CFG_FILTER_ACCEPT_BEACON);
2339be162a7SMiri Korenblit 
2349be162a7SMiri Korenblit 	return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);
2359be162a7SMiri Korenblit }
2369be162a7SMiri Korenblit 
iwl_mvm_mld_mac_ctx_send(struct iwl_mvm * mvm,struct ieee80211_vif * vif,u32 action,bool force_assoc_off)2379be162a7SMiri Korenblit static int iwl_mvm_mld_mac_ctx_send(struct iwl_mvm *mvm,
2389be162a7SMiri Korenblit 				    struct ieee80211_vif *vif,
2399be162a7SMiri Korenblit 				    u32 action, bool force_assoc_off)
2409be162a7SMiri Korenblit {
2419be162a7SMiri Korenblit 	switch (vif->type) {
2429be162a7SMiri Korenblit 	case NL80211_IFTYPE_STATION:
2439be162a7SMiri Korenblit 		return iwl_mvm_mld_mac_ctxt_cmd_sta(mvm, vif, action,
2449be162a7SMiri Korenblit 						    force_assoc_off);
2459be162a7SMiri Korenblit 	case NL80211_IFTYPE_AP:
2469be162a7SMiri Korenblit 		return iwl_mvm_mld_mac_ctxt_cmd_ap_go(mvm, vif, action);
2479be162a7SMiri Korenblit 	case NL80211_IFTYPE_MONITOR:
2489be162a7SMiri Korenblit 		return iwl_mvm_mld_mac_ctxt_cmd_listener(mvm, vif, action);
2499be162a7SMiri Korenblit 	case NL80211_IFTYPE_P2P_DEVICE:
2509be162a7SMiri Korenblit 		return iwl_mvm_mld_mac_ctxt_cmd_p2p_device(mvm, vif, action);
2519be162a7SMiri Korenblit 	case NL80211_IFTYPE_ADHOC:
2529be162a7SMiri Korenblit 		return iwl_mvm_mld_mac_ctxt_cmd_ibss(mvm, vif, action);
2539be162a7SMiri Korenblit 	default:
2549be162a7SMiri Korenblit 		break;
2559be162a7SMiri Korenblit 	}
2569be162a7SMiri Korenblit 
2579be162a7SMiri Korenblit 	return -EOPNOTSUPP;
2589be162a7SMiri Korenblit }
2599be162a7SMiri Korenblit 
iwl_mvm_mld_mac_ctxt_add(struct iwl_mvm * mvm,struct ieee80211_vif * vif)2609be162a7SMiri Korenblit int iwl_mvm_mld_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2619be162a7SMiri Korenblit {
2629be162a7SMiri Korenblit 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2639be162a7SMiri Korenblit 	int ret;
2649be162a7SMiri Korenblit 
2659be162a7SMiri Korenblit 	if (WARN_ON_ONCE(vif->type == NL80211_IFTYPE_NAN))
2669be162a7SMiri Korenblit 		return -EOPNOTSUPP;
2679be162a7SMiri Korenblit 
2689be162a7SMiri Korenblit 	if (WARN_ONCE(mvmvif->uploaded, "Adding active MAC %pM/%d\n",
2699be162a7SMiri Korenblit 		      vif->addr, ieee80211_vif_type_p2p(vif)))
2709be162a7SMiri Korenblit 		return -EIO;
2719be162a7SMiri Korenblit 
2729be162a7SMiri Korenblit 	ret = iwl_mvm_mld_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD,
2739be162a7SMiri Korenblit 				       true);
2749be162a7SMiri Korenblit 	if (ret)
2759be162a7SMiri Korenblit 		return ret;
2769be162a7SMiri Korenblit 
2779be162a7SMiri Korenblit 	/* will only do anything at resume from D3 time */
2789be162a7SMiri Korenblit 	iwl_mvm_set_last_nonqos_seq(mvm, vif);
2799be162a7SMiri Korenblit 
2809be162a7SMiri Korenblit 	mvmvif->uploaded = true;
2819be162a7SMiri Korenblit 	return 0;
2829be162a7SMiri Korenblit }
2839be162a7SMiri Korenblit 
iwl_mvm_mld_mac_ctxt_changed(struct iwl_mvm * mvm,struct ieee80211_vif * vif,bool force_assoc_off)2849be162a7SMiri Korenblit int iwl_mvm_mld_mac_ctxt_changed(struct iwl_mvm *mvm,
2859be162a7SMiri Korenblit 				 struct ieee80211_vif *vif,
2869be162a7SMiri Korenblit 				 bool force_assoc_off)
2879be162a7SMiri Korenblit {
2889be162a7SMiri Korenblit 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2899be162a7SMiri Korenblit 
2909be162a7SMiri Korenblit 	if (WARN_ON_ONCE(vif->type == NL80211_IFTYPE_NAN))
2919be162a7SMiri Korenblit 		return -EOPNOTSUPP;
2929be162a7SMiri Korenblit 
2939be162a7SMiri Korenblit 	if (WARN_ONCE(!mvmvif->uploaded, "Changing inactive MAC %pM/%d\n",
2949be162a7SMiri Korenblit 		      vif->addr, ieee80211_vif_type_p2p(vif)))
2959be162a7SMiri Korenblit 		return -EIO;
2969be162a7SMiri Korenblit 
2979be162a7SMiri Korenblit 	return iwl_mvm_mld_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY,
2989be162a7SMiri Korenblit 					force_assoc_off);
2999be162a7SMiri Korenblit }
3009be162a7SMiri Korenblit 
iwl_mvm_mld_mac_ctxt_remove(struct iwl_mvm * mvm,struct ieee80211_vif * vif)3019be162a7SMiri Korenblit int iwl_mvm_mld_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
3029be162a7SMiri Korenblit {
3039be162a7SMiri Korenblit 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3049be162a7SMiri Korenblit 	struct iwl_mac_config_cmd cmd = {
3059be162a7SMiri Korenblit 		.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
3069be162a7SMiri Korenblit 		.id_and_color = cpu_to_le32(mvmvif->id),
3079be162a7SMiri Korenblit 	};
3089be162a7SMiri Korenblit 	int ret;
3099be162a7SMiri Korenblit 
3109be162a7SMiri Korenblit 	if (WARN_ON_ONCE(vif->type == NL80211_IFTYPE_NAN))
3119be162a7SMiri Korenblit 		return -EOPNOTSUPP;
3129be162a7SMiri Korenblit 
3139be162a7SMiri Korenblit 	if (WARN_ONCE(!mvmvif->uploaded, "Removing inactive MAC %pM/%d\n",
3149be162a7SMiri Korenblit 		      vif->addr, ieee80211_vif_type_p2p(vif)))
3159be162a7SMiri Korenblit 		return -EIO;
3169be162a7SMiri Korenblit 
3179be162a7SMiri Korenblit 	ret = iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);
3189be162a7SMiri Korenblit 	if (ret)
3199be162a7SMiri Korenblit 		return ret;
3209be162a7SMiri Korenblit 
3219be162a7SMiri Korenblit 	mvmvif->uploaded = false;
3229be162a7SMiri Korenblit 
3239be162a7SMiri Korenblit 	return 0;
3249be162a7SMiri Korenblit }
325