brintos

brintos / linux-shallow public Read only

0
0
Text · 8.9 KiB · bb78510 Raw
325 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause2/*3 * Copyright (C) 2022 - 2024 Intel Corporation4 */5#include "mvm.h"6 7static void iwl_mvm_mld_set_he_support(struct iwl_mvm *mvm,8				       struct ieee80211_vif *vif,9				       struct iwl_mac_config_cmd *cmd)10{11	if (vif->type == NL80211_IFTYPE_AP)12		cmd->he_ap_support = cpu_to_le16(1);13	else14		cmd->he_support = cpu_to_le16(1);15}16 17static void iwl_mvm_mld_mac_ctxt_cmd_common(struct iwl_mvm *mvm,18					    struct ieee80211_vif *vif,19					    struct iwl_mac_config_cmd *cmd,20					    u32 action)21{22	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);23	struct ieee80211_bss_conf *link_conf;24	unsigned int link_id;25 26	cmd->id_and_color = cpu_to_le32(mvmvif->id);27	cmd->action = cpu_to_le32(action);28 29	cmd->mac_type = cpu_to_le32(iwl_mvm_get_mac_type(vif));30 31	memcpy(cmd->local_mld_addr, vif->addr, ETH_ALEN);32 33	cmd->he_support = 0;34	cmd->eht_support = 0;35 36	/* should be set by specific context type handler */37	cmd->filter_flags = 0;38 39	cmd->nic_not_ack_enabled =40		cpu_to_le32(!iwl_mvm_is_nic_ack_enabled(mvm, vif));41 42	if (iwlwifi_mod_params.disable_11ax)43		return;44 45	/* If we have MLO enabled, then the firmware needs to enable46	 * address translation for the station(s) we add. That depends47	 * on having EHT enabled in firmware, which in turn depends on48	 * mac80211 in the code below.49	 * However, mac80211 doesn't enable HE/EHT until it has parsed50	 * the association response successfully, so just skip all that51	 * and enable both when we have MLO.52	 */53	if (ieee80211_vif_is_mld(vif)) {54		iwl_mvm_mld_set_he_support(mvm, vif, cmd);55		cmd->eht_support = cpu_to_le32(1);56		return;57	}58 59	rcu_read_lock();60	for (link_id = 0; link_id < ARRAY_SIZE((vif)->link_conf); link_id++) {61		link_conf = rcu_dereference(vif->link_conf[link_id]);62		if (!link_conf)63			continue;64 65		if (link_conf->he_support)66			iwl_mvm_mld_set_he_support(mvm, vif, cmd);67 68		/* it's not reasonable to have EHT without HE and FW API doesn't69		 * support it. Ignore EHT in this case.70		 */71		if (!link_conf->he_support && link_conf->eht_support)72			continue;73 74		if (link_conf->eht_support) {75			cmd->eht_support = cpu_to_le32(1);76			break;77		}78	}79	rcu_read_unlock();80}81 82static int iwl_mvm_mld_mac_ctxt_send_cmd(struct iwl_mvm *mvm,83					 struct iwl_mac_config_cmd *cmd)84{85	int ret = iwl_mvm_send_cmd_pdu(mvm,86				       WIDE_ID(MAC_CONF_GROUP, MAC_CONFIG_CMD),87				       0, sizeof(*cmd), cmd);88	if (ret)89		IWL_ERR(mvm, "Failed to send MAC_CONFIG_CMD (action:%d): %d\n",90			le32_to_cpu(cmd->action), ret);91	return ret;92}93 94static int iwl_mvm_mld_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,95					struct ieee80211_vif *vif,96					u32 action, bool force_assoc_off)97{98	struct iwl_mac_config_cmd cmd = {};99	u16 esr_transition_timeout;100 101	WARN_ON(vif->type != NL80211_IFTYPE_STATION);102 103	/* Fill the common data for all mac context types */104	iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action);105 106	/*107	 * We always want to hear MCAST frames, if we're not authorized yet,108	 * we'll drop them.109	 */110	cmd.filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_GRP);111 112	if (vif->p2p)113		cmd.client.ctwin =114			iwl_mvm_mac_ctxt_cmd_p2p_sta_get_oppps_ctwin(mvm, vif);115 116	if (vif->cfg.assoc && !force_assoc_off) {117		struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);118 119		cmd.client.is_assoc = 1;120 121		if (!mvmvif->authorized &&122		    fw_has_capa(&mvm->fw->ucode_capa,123				IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO))124			cmd.client.data_policy |=125				cpu_to_le16(COEX_HIGH_PRIORITY_ENABLE);126 127	} else {128		cmd.client.is_assoc = 0;129 130		/* Allow beacons to pass through as long as we are not131		 * associated, or we do not have dtim period information.132		 */133		cmd.filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_BEACON);134	}135 136	cmd.client.assoc_id = cpu_to_le16(vif->cfg.aid);137	if (ieee80211_vif_is_mld(vif)) {138		esr_transition_timeout =139			u16_get_bits(vif->cfg.eml_cap,140				     IEEE80211_EML_CAP_TRANSITION_TIMEOUT);141 142		cmd.client.esr_transition_timeout =143			min_t(u16, IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU,144			      esr_transition_timeout);145		cmd.client.medium_sync_delay =146			cpu_to_le16(vif->cfg.eml_med_sync_delay);147	}148 149	if (vif->probe_req_reg && vif->cfg.assoc && vif->p2p)150		cmd.filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_PROBE_REQ);151 152	if (vif->bss_conf.he_support && !iwlwifi_mod_params.disable_11ax)153		cmd.client.data_policy |=154			cpu_to_le16(iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(mvm, vif));155 156	return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);157}158 159static int iwl_mvm_mld_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,160					     struct ieee80211_vif *vif,161					     u32 action)162{163	struct iwl_mac_config_cmd cmd = {};164 165	WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);166 167	iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action);168 169	cmd.filter_flags = cpu_to_le32(MAC_CFG_FILTER_PROMISC |170				       MAC_CFG_FILTER_ACCEPT_CONTROL_AND_MGMT |171				       MAC_CFG_FILTER_ACCEPT_BEACON |172				       MAC_CFG_FILTER_ACCEPT_PROBE_REQ |173				       MAC_CFG_FILTER_ACCEPT_GRP);174 175	return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);176}177 178static int iwl_mvm_mld_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm,179					 struct ieee80211_vif *vif,180					 u32 action)181{182	struct iwl_mac_config_cmd cmd = {};183 184	WARN_ON(vif->type != NL80211_IFTYPE_ADHOC);185 186	iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action);187 188	cmd.filter_flags = cpu_to_le32(MAC_CFG_FILTER_ACCEPT_BEACON |189				       MAC_CFG_FILTER_ACCEPT_PROBE_REQ |190				       MAC_CFG_FILTER_ACCEPT_GRP);191 192	return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);193}194 195static int iwl_mvm_mld_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm,196					       struct ieee80211_vif *vif,197					       u32 action)198{199	struct iwl_mac_config_cmd cmd = {};200 201	WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE);202 203	iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action);204 205	cmd.p2p_dev.is_disc_extended =206		iwl_mac_ctxt_p2p_dev_has_extended_disc(mvm, vif);207 208	/* Override the filter flags to accept all management frames. This is209	 * needed to support both P2P device discovery using probe requests and210	 * P2P service discovery using action frames211	 */212	cmd.filter_flags = cpu_to_le32(MAC_CFG_FILTER_ACCEPT_CONTROL_AND_MGMT);213 214	return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);215}216 217static int iwl_mvm_mld_mac_ctxt_cmd_ap_go(struct iwl_mvm *mvm,218					  struct ieee80211_vif *vif,219					  u32 action)220{221	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);222	struct iwl_mac_config_cmd cmd = {};223 224	WARN_ON(vif->type != NL80211_IFTYPE_AP);225 226	/* Fill the common data for all mac context types */227	iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action);228 229	iwl_mvm_mac_ctxt_cmd_ap_set_filter_flags(mvm, mvmvif,230						 &cmd.filter_flags,231						 MAC_CFG_FILTER_ACCEPT_PROBE_REQ,232						 MAC_CFG_FILTER_ACCEPT_BEACON);233 234	return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);235}236 237static int iwl_mvm_mld_mac_ctx_send(struct iwl_mvm *mvm,238				    struct ieee80211_vif *vif,239				    u32 action, bool force_assoc_off)240{241	switch (vif->type) {242	case NL80211_IFTYPE_STATION:243		return iwl_mvm_mld_mac_ctxt_cmd_sta(mvm, vif, action,244						    force_assoc_off);245	case NL80211_IFTYPE_AP:246		return iwl_mvm_mld_mac_ctxt_cmd_ap_go(mvm, vif, action);247	case NL80211_IFTYPE_MONITOR:248		return iwl_mvm_mld_mac_ctxt_cmd_listener(mvm, vif, action);249	case NL80211_IFTYPE_P2P_DEVICE:250		return iwl_mvm_mld_mac_ctxt_cmd_p2p_device(mvm, vif, action);251	case NL80211_IFTYPE_ADHOC:252		return iwl_mvm_mld_mac_ctxt_cmd_ibss(mvm, vif, action);253	default:254		break;255	}256 257	return -EOPNOTSUPP;258}259 260int iwl_mvm_mld_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif)261{262	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);263	int ret;264 265	if (WARN_ON_ONCE(vif->type == NL80211_IFTYPE_NAN))266		return -EOPNOTSUPP;267 268	if (WARN_ONCE(mvmvif->uploaded, "Adding active MAC %pM/%d\n",269		      vif->addr, ieee80211_vif_type_p2p(vif)))270		return -EIO;271 272	ret = iwl_mvm_mld_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD,273				       true);274	if (ret)275		return ret;276 277	/* will only do anything at resume from D3 time */278	iwl_mvm_set_last_nonqos_seq(mvm, vif);279 280	mvmvif->uploaded = true;281	return 0;282}283 284int iwl_mvm_mld_mac_ctxt_changed(struct iwl_mvm *mvm,285				 struct ieee80211_vif *vif,286				 bool force_assoc_off)287{288	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);289 290	if (WARN_ON_ONCE(vif->type == NL80211_IFTYPE_NAN))291		return -EOPNOTSUPP;292 293	if (WARN_ONCE(!mvmvif->uploaded, "Changing inactive MAC %pM/%d\n",294		      vif->addr, ieee80211_vif_type_p2p(vif)))295		return -EIO;296 297	return iwl_mvm_mld_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY,298					force_assoc_off);299}300 301int iwl_mvm_mld_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)302{303	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);304	struct iwl_mac_config_cmd cmd = {305		.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),306		.id_and_color = cpu_to_le32(mvmvif->id),307	};308	int ret;309 310	if (WARN_ON_ONCE(vif->type == NL80211_IFTYPE_NAN))311		return -EOPNOTSUPP;312 313	if (WARN_ONCE(!mvmvif->uploaded, "Removing inactive MAC %pM/%d\n",314		      vif->addr, ieee80211_vif_type_p2p(vif)))315		return -EIO;316 317	ret = iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);318	if (ret)319		return ret;320 321	mvmvif->uploaded = false;322 323	return 0;324}325