xref: /linux/drivers/net/wireless/intel/iwlwifi/mld/sta.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3  * Copyright (C) 2024-2026 Intel Corporation
4  */
5 
6 #include <linux/ieee80211.h>
7 #include <kunit/static_stub.h>
8 
9 #include "sta.h"
10 #include "hcmd.h"
11 #include "iface.h"
12 #include "mlo.h"
13 #include "key.h"
14 #include "agg.h"
15 #include "tlc.h"
16 #include "nan.h"
17 #include "fw/api/sta.h"
18 #include "fw/api/mac.h"
19 #include "fw/api/rx.h"
20 
iwl_mld_fw_sta_id_from_link_sta(struct iwl_mld * mld,struct ieee80211_link_sta * link_sta)21 int iwl_mld_fw_sta_id_from_link_sta(struct iwl_mld *mld,
22 				    struct ieee80211_link_sta *link_sta)
23 {
24 	struct iwl_mld_link_sta *mld_link_sta;
25 
26 	/* This function should only be used with the wiphy lock held,
27 	 * In other cases, it is not guaranteed that the link_sta will exist
28 	 * in the driver too, and it is checked here.
29 	 */
30 	lockdep_assert_wiphy(mld->wiphy);
31 
32 	/* This is not meant to be called with a NULL pointer */
33 	if (WARN_ON(!link_sta))
34 		return -ENOENT;
35 
36 	mld_link_sta = iwl_mld_link_sta_from_mac80211(link_sta);
37 	if (!mld_link_sta) {
38 		WARN_ON(!iwl_mld_error_before_recovery(mld));
39 		return -ENOENT;
40 	}
41 
42 	return mld_link_sta->fw_id;
43 }
44 
45 static void
iwl_mld_fill_ampdu_size_and_dens(struct ieee80211_link_sta * link_sta,bool is_6ghz,__le32 * tx_ampdu_max_size,__le32 * tx_ampdu_spacing)46 iwl_mld_fill_ampdu_size_and_dens(struct ieee80211_link_sta *link_sta,
47 				 bool is_6ghz,
48 				 __le32 *tx_ampdu_max_size,
49 				 __le32 *tx_ampdu_spacing)
50 {
51 	u32 agg_size = 0, mpdu_dens = 0;
52 
53 	if (WARN_ON(!link_sta))
54 		return;
55 
56 	/* Note that we always use only legacy & highest supported PPDUs, so
57 	 * of Draft P802.11be D.30 Table 10-12a--Fields used for calculating
58 	 * the maximum A-MPDU size of various PPDU types in different bands,
59 	 * we only need to worry about the highest supported PPDU type here.
60 	 */
61 
62 	if (link_sta->ht_cap.ht_supported) {
63 		agg_size = link_sta->ht_cap.ampdu_factor;
64 		mpdu_dens = link_sta->ht_cap.ampdu_density;
65 	}
66 
67 	if (is_6ghz) {
68 		/* overwrite HT values on 6 GHz */
69 		mpdu_dens =
70 			le16_get_bits(link_sta->he_6ghz_capa.capa,
71 				      IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START);
72 		agg_size =
73 			le16_get_bits(link_sta->he_6ghz_capa.capa,
74 				      IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
75 	} else if (link_sta->vht_cap.vht_supported) {
76 		/* if VHT supported overwrite HT value */
77 		agg_size =
78 			u32_get_bits(link_sta->vht_cap.cap,
79 				     IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK);
80 	}
81 
82 	/* D6.0 10.12.2 A-MPDU length limit rules
83 	 * A STA indicates the maximum length of the A-MPDU preEOF padding
84 	 * that it can receive in an HE PPDU in the Maximum A-MPDU Length
85 	 * Exponent field in its HT Capabilities, VHT Capabilities,
86 	 * and HE 6 GHz Band Capabilities elements (if present) and the
87 	 * Maximum AMPDU Length Exponent Extension field in its HE
88 	 * Capabilities element
89 	 */
90 	if (link_sta->he_cap.has_he)
91 		agg_size +=
92 			u8_get_bits(link_sta->he_cap.he_cap_elem.mac_cap_info[3],
93 				    IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK);
94 
95 	if (link_sta->eht_cap.has_eht)
96 		agg_size +=
97 			u8_get_bits(link_sta->eht_cap.eht_cap_elem.mac_cap_info[1],
98 				    IEEE80211_EHT_MAC_CAP1_MAX_AMPDU_LEN_MASK);
99 
100 	/* Limit to max A-MPDU supported by FW */
101 	agg_size = min_t(u32, agg_size,
102 			 STA_FLG_MAX_AGG_SIZE_4M >> STA_FLG_MAX_AGG_SIZE_SHIFT);
103 
104 	*tx_ampdu_max_size = cpu_to_le32(agg_size);
105 	*tx_ampdu_spacing = cpu_to_le32(mpdu_dens);
106 }
107 
iwl_mld_get_uapsd_acs(struct ieee80211_sta * sta)108 static u8 iwl_mld_get_uapsd_acs(struct ieee80211_sta *sta)
109 {
110 	u8 uapsd_acs = 0;
111 
112 	if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
113 		uapsd_acs |= BIT(AC_BK);
114 	if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
115 		uapsd_acs |= BIT(AC_BE);
116 	if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
117 		uapsd_acs |= BIT(AC_VI);
118 	if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
119 		uapsd_acs |= BIT(AC_VO);
120 
121 	return uapsd_acs | uapsd_acs << 4;
122 }
123 
iwl_mld_he_get_ppe_val(u8 * ppe,u8 ppe_pos_bit)124 static u8 iwl_mld_he_get_ppe_val(u8 *ppe, u8 ppe_pos_bit)
125 {
126 	u8 byte_num = ppe_pos_bit / 8;
127 	u8 bit_num = ppe_pos_bit % 8;
128 	u8 residue_bits;
129 	u8 res;
130 
131 	if (bit_num <= 5)
132 		return (ppe[byte_num] >> bit_num) &
133 		       (BIT(IEEE80211_PPE_THRES_INFO_PPET_SIZE) - 1);
134 
135 	/* If bit_num > 5, we have to combine bits with next byte.
136 	 * Calculate how many bits we need to take from current byte (called
137 	 * here "residue_bits"), and add them to bits from next byte.
138 	 */
139 
140 	residue_bits = 8 - bit_num;
141 
142 	res = (ppe[byte_num + 1] &
143 	       (BIT(IEEE80211_PPE_THRES_INFO_PPET_SIZE - residue_bits) - 1)) <<
144 	      residue_bits;
145 	res += (ppe[byte_num] >> bit_num) & (BIT(residue_bits) - 1);
146 
147 	return res;
148 }
149 
iwl_mld_parse_ppe(struct iwl_mld * mld,struct iwl_he_pkt_ext_v2 * pkt_ext,u8 nss,u8 ru_index_bitmap,u8 * ppe,u8 ppe_pos_bit,bool inheritance)150 static void iwl_mld_parse_ppe(struct iwl_mld *mld,
151 			      struct iwl_he_pkt_ext_v2 *pkt_ext, u8 nss,
152 			      u8 ru_index_bitmap, u8 *ppe, u8 ppe_pos_bit,
153 			      bool inheritance)
154 {
155 	/* FW currently supports only nss == MAX_HE_SUPP_NSS
156 	 *
157 	 * If nss > MAX: we can ignore values we don't support
158 	 * If nss < MAX: we can set zeros in other streams
159 	 */
160 	if (nss > MAX_HE_SUPP_NSS) {
161 		IWL_DEBUG_INFO(mld, "Got NSS = %d - trimming to %d\n", nss,
162 			       MAX_HE_SUPP_NSS);
163 		nss = MAX_HE_SUPP_NSS;
164 	}
165 
166 	for (int i = 0; i < nss; i++) {
167 		u8 ru_index_tmp = ru_index_bitmap << 1;
168 		u8 low_th = IWL_HE_PKT_EXT_NONE, high_th = IWL_HE_PKT_EXT_NONE;
169 
170 		for (u8 bw = 0;
171 		     bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
172 		     bw++) {
173 			ru_index_tmp >>= 1;
174 
175 			/* According to the 11be spec, if for a specific BW the PPE Thresholds
176 			 * isn't present - it should inherit the thresholds from the last
177 			 * BW for which we had PPE Thresholds. In 11ax though, we don't have
178 			 * this inheritance - continue in this case
179 			 */
180 			if (!(ru_index_tmp & 1)) {
181 				if (inheritance)
182 					goto set_thresholds;
183 				else
184 					continue;
185 			}
186 
187 			high_th = iwl_mld_he_get_ppe_val(ppe, ppe_pos_bit);
188 			ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
189 			low_th = iwl_mld_he_get_ppe_val(ppe, ppe_pos_bit);
190 			ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
191 
192 set_thresholds:
193 			pkt_ext->pkt_ext_qam_th[i][bw][0] = low_th;
194 			pkt_ext->pkt_ext_qam_th[i][bw][1] = high_th;
195 		}
196 	}
197 }
198 
iwl_mld_set_pkt_ext_from_he_ppe(struct iwl_mld * mld,struct ieee80211_link_sta * link_sta,struct iwl_he_pkt_ext_v2 * pkt_ext,bool inheritance)199 static void iwl_mld_set_pkt_ext_from_he_ppe(struct iwl_mld *mld,
200 					    struct ieee80211_link_sta *link_sta,
201 					    struct iwl_he_pkt_ext_v2 *pkt_ext,
202 					    bool inheritance)
203 {
204 	u8 nss = (link_sta->he_cap.ppe_thres[0] &
205 		  IEEE80211_PPE_THRES_NSS_MASK) + 1;
206 	u8 *ppe = &link_sta->he_cap.ppe_thres[0];
207 	u8 ru_index_bitmap =
208 		u8_get_bits(*ppe,
209 			    IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK);
210 	/* Starting after PPE header */
211 	u8 ppe_pos_bit = IEEE80211_HE_PPE_THRES_INFO_HEADER_SIZE;
212 
213 	iwl_mld_parse_ppe(mld, pkt_ext, nss, ru_index_bitmap, ppe, ppe_pos_bit,
214 			  inheritance);
215 }
216 
217 static int
iwl_mld_set_pkt_ext_from_nominal_padding(struct iwl_he_pkt_ext_v2 * pkt_ext,u8 nominal_padding)218 iwl_mld_set_pkt_ext_from_nominal_padding(struct iwl_he_pkt_ext_v2 *pkt_ext,
219 					 u8 nominal_padding)
220 {
221 	int low_th = -1;
222 	int high_th = -1;
223 
224 	/* all the macros are the same for EHT and HE */
225 	switch (nominal_padding) {
226 	case IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_0US:
227 		low_th = IWL_HE_PKT_EXT_NONE;
228 		high_th = IWL_HE_PKT_EXT_NONE;
229 		break;
230 	case IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_8US:
231 		low_th = IWL_HE_PKT_EXT_BPSK;
232 		high_th = IWL_HE_PKT_EXT_NONE;
233 		break;
234 	case IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_16US:
235 	case IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_20US:
236 		low_th = IWL_HE_PKT_EXT_NONE;
237 		high_th = IWL_HE_PKT_EXT_BPSK;
238 		break;
239 	}
240 
241 	if (low_th < 0 || high_th < 0)
242 		return -EINVAL;
243 
244 	/* Set the PPE thresholds accordingly */
245 	for (int i = 0; i < MAX_HE_SUPP_NSS; i++) {
246 		for (u8 bw = 0;
247 			bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
248 			bw++) {
249 			pkt_ext->pkt_ext_qam_th[i][bw][0] = low_th;
250 			pkt_ext->pkt_ext_qam_th[i][bw][1] = high_th;
251 		}
252 	}
253 
254 	return 0;
255 }
256 
iwl_mld_get_optimal_ppe_info(struct iwl_he_pkt_ext_v2 * pkt_ext,u8 nominal_padding)257 static void iwl_mld_get_optimal_ppe_info(struct iwl_he_pkt_ext_v2 *pkt_ext,
258 					 u8 nominal_padding)
259 {
260 	for (int i = 0; i < MAX_HE_SUPP_NSS; i++) {
261 		for (u8 bw = 0; bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
262 		     bw++) {
263 			u8 *qam_th = &pkt_ext->pkt_ext_qam_th[i][bw][0];
264 
265 			if (nominal_padding >
266 			    IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_8US &&
267 			    qam_th[1] == IWL_HE_PKT_EXT_NONE)
268 				qam_th[1] = IWL_HE_PKT_EXT_4096QAM;
269 			else if (nominal_padding ==
270 				 IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_8US &&
271 				 qam_th[0] == IWL_HE_PKT_EXT_NONE &&
272 				 qam_th[1] == IWL_HE_PKT_EXT_NONE)
273 				qam_th[0] = IWL_HE_PKT_EXT_4096QAM;
274 		}
275 	}
276 }
277 
iwl_mld_fill_pkt_ext(struct iwl_mld * mld,struct ieee80211_link_sta * link_sta,struct iwl_he_pkt_ext_v2 * pkt_ext)278 static void iwl_mld_fill_pkt_ext(struct iwl_mld *mld,
279 				 struct ieee80211_link_sta *link_sta,
280 				 struct iwl_he_pkt_ext_v2 *pkt_ext)
281 {
282 	if (WARN_ON(!link_sta))
283 		return;
284 
285 	/* Initialize the PPE thresholds to "None" (7), as described in Table
286 	 * 9-262ac of 80211.ax/D3.0.
287 	 */
288 	memset(pkt_ext, IWL_HE_PKT_EXT_NONE, sizeof(*pkt_ext));
289 
290 	if (link_sta->eht_cap.has_eht) {
291 		u8 nominal_padding =
292 			u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5],
293 				    IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK);
294 
295 		/* If PPE Thresholds exists, parse them into a FW-familiar
296 		 * format.
297 		 */
298 		if (link_sta->eht_cap.eht_cap_elem.phy_cap_info[5] &
299 		    IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT) {
300 			u8 nss = (link_sta->eht_cap.eht_ppe_thres[0] &
301 				IEEE80211_EHT_PPE_THRES_NSS_MASK) + 1;
302 			u8 *ppe = &link_sta->eht_cap.eht_ppe_thres[0];
303 			u8 ru_index_bitmap =
304 				u16_get_bits(*ppe,
305 					     IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
306 			 /* Starting after PPE header */
307 			u8 ppe_pos_bit = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE;
308 
309 			iwl_mld_parse_ppe(mld, pkt_ext, nss, ru_index_bitmap,
310 					  ppe, ppe_pos_bit, true);
311 		/* EHT PPE Thresholds doesn't exist - set the API according to
312 		 * HE PPE Tresholds
313 		 */
314 		} else if (link_sta->he_cap.he_cap_elem.phy_cap_info[6] &
315 			   IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
316 			/* Even though HE Capabilities IE doesn't contain PPE
317 			 * Thresholds for BW 320Mhz, thresholds for this BW will
318 			 * be filled in with the same values as 160Mhz, due to
319 			 * the inheritance, as required.
320 			 */
321 			iwl_mld_set_pkt_ext_from_he_ppe(mld, link_sta, pkt_ext,
322 							true);
323 
324 			/* According to the requirements, for MCSs 12-13 the
325 			 * maximum value between HE PPE Threshold and Common
326 			 * Nominal Packet Padding needs to be taken
327 			 */
328 			iwl_mld_get_optimal_ppe_info(pkt_ext, nominal_padding);
329 
330 		/* if PPE Thresholds doesn't present in both EHT IE and HE IE -
331 		 * take the Thresholds from Common Nominal Packet Padding field
332 		 */
333 		} else {
334 			iwl_mld_set_pkt_ext_from_nominal_padding(pkt_ext,
335 								 nominal_padding);
336 		}
337 	} else if (link_sta->he_cap.has_he) {
338 		/* If PPE Thresholds exist, parse them into a FW-familiar format. */
339 		if (link_sta->he_cap.he_cap_elem.phy_cap_info[6] &
340 			IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
341 			iwl_mld_set_pkt_ext_from_he_ppe(mld, link_sta, pkt_ext,
342 							false);
343 		/* PPE Thresholds doesn't exist - set the API PPE values
344 		 * according to Common Nominal Packet Padding field.
345 		 */
346 		} else {
347 			u8 nominal_padding =
348 				u8_get_bits(link_sta->he_cap.he_cap_elem.phy_cap_info[9],
349 					    IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK);
350 			if (nominal_padding != IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED)
351 				iwl_mld_set_pkt_ext_from_nominal_padding(pkt_ext,
352 									 nominal_padding);
353 		}
354 	}
355 
356 	for (int i = 0; i < MAX_HE_SUPP_NSS; i++) {
357 		for (int bw = 0;
358 		     bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
359 		     bw++) {
360 			u8 *qam_th = pkt_ext->pkt_ext_qam_th[i][bw];
361 
362 			IWL_DEBUG_HT(mld,
363 				     "PPE table: nss[%d] bw[%d] PPET8 = %d, PPET16 = %d\n",
364 				     i, bw, qam_th[0], qam_th[1]);
365 		}
366 	}
367 }
368 
iwl_mld_get_htc_flags(struct ieee80211_link_sta * link_sta)369 static u32 iwl_mld_get_htc_flags(struct ieee80211_link_sta *link_sta)
370 {
371 	u8 *mac_cap_info =
372 		&link_sta->he_cap.he_cap_elem.mac_cap_info[0];
373 	u32 htc_flags = 0;
374 
375 	if (mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_HTC_HE)
376 		htc_flags |= IWL_HE_HTC_SUPPORT;
377 	if ((mac_cap_info[1] & IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION) ||
378 	    (mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION)) {
379 		u8 link_adap =
380 			((mac_cap_info[2] &
381 			  IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION) << 1) +
382 			 (mac_cap_info[1] &
383 			  IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION);
384 
385 		if (link_adap == 2)
386 			htc_flags |=
387 				IWL_HE_HTC_LINK_ADAP_UNSOLICITED;
388 		else if (link_adap == 3)
389 			htc_flags |= IWL_HE_HTC_LINK_ADAP_BOTH;
390 	}
391 	if (mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR)
392 		htc_flags |= IWL_HE_HTC_BSR_SUPP;
393 	if (mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL)
394 		htc_flags |= IWL_HE_HTC_OMI_SUPP;
395 	if (mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
396 		htc_flags |= IWL_HE_HTC_BQR_SUPP;
397 
398 	return htc_flags;
399 }
400 
401 /* Note: modifies the command depending on FW command version */
iwl_mld_send_sta_cmd(struct iwl_mld * mld,struct iwl_sta_cfg_cmd * cmd)402 static int iwl_mld_send_sta_cmd(struct iwl_mld *mld,
403 				struct iwl_sta_cfg_cmd *cmd)
404 {
405 	int cmd_id = WIDE_ID(MAC_CONF_GROUP, STA_CONFIG_CMD);
406 	int cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, cmd_id, 0);
407 	int len = sizeof(*cmd);
408 	int ret;
409 
410 	if (cmd_ver < 2) {
411 		IWL_ERR(mld, "Unsupported STA_CONFIG_CMD version %d\n",
412 			cmd_ver);
413 		return -EINVAL;
414 	} else if (cmd_ver == 2) {
415 		struct iwl_sta_cfg_cmd_v2 *cmd_v2 = (void *)cmd;
416 
417 		if (WARN_ON(cmd->station_type == cpu_to_le32(STATION_TYPE_NAN_PEER_NMI) ||
418 			    cmd->station_type == cpu_to_le32(STATION_TYPE_NAN_PEER_NDI) ||
419 			    hweight32(le32_to_cpu(cmd->link_mask)) != 1))
420 			return -EINVAL;
421 		/*
422 		 * These fields are located in a different place in the struct of v2.
423 		 * The assumption is that UHR won't be used with FW that has v2.
424 		 */
425 		if (WARN_ON(cmd->mic_prep_pad_delay || cmd->mic_compute_pad_delay))
426 			return -EINVAL;
427 
428 		len = sizeof(struct iwl_sta_cfg_cmd_v2);
429 		cmd_v2->link_id = cpu_to_le32(__ffs(le32_to_cpu(cmd->link_mask)));
430 	} else if (cmd->station_type ==
431 		   cpu_to_le32(STATION_TYPE_NAN_MCAST_DATA)) {
432 		if (WARN_ON(!hweight32(le32_to_cpu(cmd->link_mask))))
433 			return -EINVAL;
434 	} else if (WARN_ON(cmd->station_type != cpu_to_le32(STATION_TYPE_NAN_PEER_NMI) &&
435 			   cmd->station_type != cpu_to_le32(STATION_TYPE_NAN_PEER_NDI) &&
436 			   cmd->station_type != cpu_to_le32(STATION_TYPE_NAN_BCAST) &&
437 			   cmd->station_type != cpu_to_le32(STATION_TYPE_NAN_MGMT) &&
438 			   hweight32(le32_to_cpu(cmd->link_mask)) != 1)) {
439 		return -EINVAL;
440 	}
441 
442 	ret = iwl_mld_send_cmd_pdu(mld, cmd_id, cmd, len);
443 	if (ret)
444 		IWL_ERR(mld, "STA_CONFIG_CMD send failed, ret=0x%x\n", ret);
445 	return ret;
446 }
447 
iwl_mld_get_nan_link_mask(struct iwl_mld * mld)448 static u32 iwl_mld_get_nan_link_mask(struct iwl_mld *mld)
449 {
450 	struct iwl_mld_vif *nan_dev =
451 		iwl_mld_vif_from_mac80211(mld->nan_device_vif);
452 	struct iwl_mld_nan_link *nan_link;
453 	u32 link_mask = 0;
454 
455 	for_each_mld_nan_valid_link(nan_dev, nan_link)
456 		link_mask |= BIT(nan_link->fw_id);
457 
458 	return link_mask;
459 }
460 
iwl_mld_add_modify_sta_cmd(struct iwl_mld * mld,struct ieee80211_link_sta * link_sta)461 int iwl_mld_add_modify_sta_cmd(struct iwl_mld *mld,
462 			      struct ieee80211_link_sta *link_sta)
463 {
464 	struct ieee80211_sta *sta = link_sta->sta;
465 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
466 	struct iwl_sta_cfg_cmd cmd = {};
467 	int fw_id = iwl_mld_fw_sta_id_from_link_sta(mld, link_sta);
468 	bool is_6ghz, uora_exists;
469 	u32 link_mask;
470 
471 	lockdep_assert_wiphy(mld->wiphy);
472 
473 	if (WARN_ON(fw_id < 0))
474 		return -EINVAL;
475 
476 	if (mld_sta->sta_type == STATION_TYPE_NAN_PEER_NMI ||
477 	    mld_sta->sta_type == STATION_TYPE_NAN_PEER_NDI) {
478 		if (WARN_ON(!mld->nan_device_vif))
479 			return -EINVAL;
480 
481 		is_6ghz = false;
482 		uora_exists = false;
483 
484 		link_mask = iwl_mld_get_nan_link_mask(mld);
485 	} else {
486 		struct ieee80211_bss_conf *link;
487 		struct iwl_mld_link *mld_link;
488 
489 		link = link_conf_dereference_protected(mld_sta->vif,
490 						       link_sta->link_id);
491 		mld_link = iwl_mld_link_from_mac80211(link);
492 
493 		if (WARN_ON(!link || !mld_link))
494 			return -EINVAL;
495 
496 		link_mask = BIT(mld_link->fw_id);
497 		is_6ghz = link->chanreq.oper.chan->band == NL80211_BAND_6GHZ;
498 		uora_exists = link->uora_exists;
499 	}
500 
501 	cmd.sta_id = cpu_to_le32(fw_id);
502 	cmd.link_mask = cpu_to_le32(link_mask);
503 	cmd.station_type = cpu_to_le32(mld_sta->sta_type);
504 
505 	memcpy(&cmd.peer_mld_address, sta->addr, ETH_ALEN);
506 	memcpy(&cmd.peer_link_address, link_sta->addr, ETH_ALEN);
507 
508 	if (mld_sta->sta_state >= IEEE80211_STA_ASSOC)
509 		cmd.assoc_id = cpu_to_le32(sta->aid);
510 
511 	if (sta->mfp || mld_sta->sta_state < IEEE80211_STA_AUTHORIZED)
512 		cmd.mfp = cpu_to_le32(1);
513 
514 	switch (link_sta->rx_nss) {
515 	case 1:
516 		cmd.mimo = cpu_to_le32(0);
517 		break;
518 	case 2 ... 8:
519 		cmd.mimo = cpu_to_le32(1);
520 		break;
521 	}
522 
523 	switch (link_sta->smps_mode) {
524 	case IEEE80211_SMPS_AUTOMATIC:
525 	case IEEE80211_SMPS_NUM_MODES:
526 		WARN_ON(1);
527 		break;
528 	case IEEE80211_SMPS_STATIC:
529 		/* override NSS */
530 		cmd.mimo = cpu_to_le32(0);
531 		break;
532 	case IEEE80211_SMPS_DYNAMIC:
533 		cmd.mimo_protection = cpu_to_le32(1);
534 		break;
535 	case IEEE80211_SMPS_OFF:
536 		/* nothing */
537 		break;
538 	}
539 
540 	/* In NAN, there is no association request so no initial SMPS info */
541 	if (mld_sta->vif->type == NL80211_IFTYPE_NAN_DATA) {
542 		cmd.mimo = cpu_to_le32(1);
543 		cmd.mimo_protection = cpu_to_le32(0);
544 	}
545 
546 	iwl_mld_fill_ampdu_size_and_dens(link_sta, is_6ghz,
547 					 &cmd.tx_ampdu_max_size,
548 					 &cmd.tx_ampdu_spacing);
549 
550 	if (sta->wme) {
551 		cmd.sp_length =
552 			cpu_to_le32(sta->max_sp ? sta->max_sp * 2 : 128);
553 		cmd.uapsd_acs = cpu_to_le32(iwl_mld_get_uapsd_acs(sta));
554 	}
555 
556 	if (link_sta->he_cap.has_he) {
557 		cmd.trig_rnd_alloc =
558 			cpu_to_le32(uora_exists ? 1 : 0);
559 
560 		/* PPE Thresholds */
561 		iwl_mld_fill_pkt_ext(mld, link_sta, &cmd.pkt_ext);
562 
563 		/* HTC flags */
564 		cmd.htc_flags =
565 			cpu_to_le32(iwl_mld_get_htc_flags(link_sta));
566 
567 		if (link_sta->he_cap.he_cap_elem.mac_cap_info[2] &
568 		    IEEE80211_HE_MAC_CAP2_ACK_EN)
569 			cmd.ack_enabled = cpu_to_le32(1);
570 	}
571 
572 	if (mld_sta->sta_type == STATION_TYPE_NAN_PEER_NDI) {
573 		struct ieee80211_sta *nmi_sta =
574 			wiphy_dereference(mld->wiphy, sta->nmi);
575 		int nmi_fw_id;
576 
577 		/* copy the local NDI address */
578 		ether_addr_copy(cmd.ndi_local_addr, mld_sta->vif->addr);
579 
580 		if (WARN_ON(!nmi_sta))
581 			return -EINVAL;
582 
583 		nmi_fw_id = iwl_mld_fw_sta_id_from_link_sta(mld,
584 					&nmi_sta->deflink);
585 		if (nmi_fw_id < 0)
586 			return -EINVAL;
587 
588 		cmd.nmi_sta_id = (u8) nmi_fw_id;
589 	}
590 
591 	return iwl_mld_send_sta_cmd(mld, &cmd);
592 }
593 
IWL_MLD_ALLOC_FN_STATIC(link_sta,link_sta)594 IWL_MLD_ALLOC_FN_STATIC(link_sta, link_sta)
595 
596 static int
597 iwl_mld_add_link_sta(struct iwl_mld *mld, struct ieee80211_link_sta *link_sta)
598 {
599 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(link_sta->sta);
600 	struct iwl_mld_link_sta *mld_link_sta;
601 	int ret;
602 	u8 fw_id;
603 
604 	lockdep_assert_wiphy(mld->wiphy);
605 
606 	/* We will fail to add it to the FW anyway */
607 	if (iwl_mld_error_before_recovery(mld))
608 		return -ENODEV;
609 
610 	mld_link_sta = iwl_mld_link_sta_from_mac80211(link_sta);
611 
612 	/* We need to preserve the fw sta ids during a restart, since the fw
613 	 * will recover SN/PN for them, this is why the mld_link_sta exists.
614 	 */
615 	if (mld_link_sta) {
616 		/* But if we are not restarting, this is not OK */
617 		WARN_ON(!mld->fw_status.in_hw_restart);
618 
619 		/* Avoid adding a STA that is already in FW to avoid an assert */
620 		if (WARN_ON(mld_link_sta->in_fw))
621 			return -EINVAL;
622 
623 		fw_id = mld_link_sta->fw_id;
624 		goto add_to_fw;
625 	}
626 
627 	/* Allocate a fw id and map it to the link_sta */
628 	ret = iwl_mld_allocate_link_sta_fw_id(mld, &fw_id, link_sta);
629 	if (ret)
630 		return ret;
631 
632 	if (link_sta == &link_sta->sta->deflink) {
633 		mld_link_sta = &mld_sta->deflink;
634 	} else {
635 		mld_link_sta = kzalloc_obj(*mld_link_sta);
636 		if (!mld_link_sta)
637 			return -ENOMEM;
638 	}
639 
640 	mld_link_sta->fw_id = fw_id;
641 	rcu_assign_pointer(mld_sta->link[link_sta->link_id], mld_link_sta);
642 
643 add_to_fw:
644 	ret = iwl_mld_add_modify_sta_cmd(mld, link_sta);
645 	if (ret) {
646 		RCU_INIT_POINTER(mld->fw_id_to_link_sta[fw_id], NULL);
647 		RCU_INIT_POINTER(mld_sta->link[link_sta->link_id], NULL);
648 		if (link_sta != &link_sta->sta->deflink)
649 			kfree(mld_link_sta);
650 		return ret;
651 	}
652 	mld_link_sta->in_fw = true;
653 
654 	return 0;
655 }
656 
iwl_mld_rm_sta_from_fw(struct iwl_mld * mld,u8 fw_sta_id)657 static int iwl_mld_rm_sta_from_fw(struct iwl_mld *mld, u8 fw_sta_id)
658 {
659 	struct iwl_remove_sta_cmd cmd = {
660 		.sta_id = cpu_to_le32(fw_sta_id),
661 	};
662 	int ret;
663 
664 	ret = iwl_mld_send_cmd_pdu(mld,
665 				   WIDE_ID(MAC_CONF_GROUP, STA_REMOVE_CMD),
666 				   &cmd);
667 	if (ret)
668 		IWL_ERR(mld, "Failed to remove station. Id=%d\n", fw_sta_id);
669 
670 	return ret;
671 }
672 
673 static void
iwl_mld_remove_link_sta(struct iwl_mld * mld,struct ieee80211_link_sta * link_sta)674 iwl_mld_remove_link_sta(struct iwl_mld *mld,
675 			struct ieee80211_link_sta *link_sta)
676 {
677 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(link_sta->sta);
678 	struct iwl_mld_link_sta *mld_link_sta =
679 		iwl_mld_link_sta_from_mac80211(link_sta);
680 
681 	if (WARN_ON(!mld_link_sta))
682 		return;
683 
684 	iwl_mld_rm_sta_from_fw(mld, mld_link_sta->fw_id);
685 	mld_link_sta->in_fw = false;
686 
687 	/* Now that the STA doesn't exist in FW, we don't expect any new
688 	 * notifications for it. Cancel the ones that are already pending
689 	 */
690 	iwl_mld_cancel_notifications_of_object(mld, IWL_MLD_OBJECT_TYPE_STA,
691 					       mld_link_sta->fw_id);
692 
693 	/* This will not be done upon reconfig, so do it also when
694 	 * failed to remove from fw
695 	 */
696 	RCU_INIT_POINTER(mld->fw_id_to_link_sta[mld_link_sta->fw_id], NULL);
697 	RCU_INIT_POINTER(mld_sta->link[link_sta->link_id], NULL);
698 	if (mld_link_sta != &mld_sta->deflink)
699 		kfree_rcu(mld_link_sta, rcu_head);
700 }
701 
iwl_mld_set_max_amsdu_len(struct iwl_mld * mld,struct ieee80211_link_sta * link_sta)702 static void iwl_mld_set_max_amsdu_len(struct iwl_mld *mld,
703 				      struct ieee80211_link_sta *link_sta)
704 {
705 	const struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap;
706 
707 	/* For EHT, HE and VHT we can use the value as it was calculated by
708 	 * mac80211. For HT, mac80211 doesn't enforce to 4095, so force it
709 	 * here
710 	 */
711 	if (link_sta->eht_cap.has_eht || link_sta->he_cap.has_he ||
712 	    link_sta->vht_cap.vht_supported ||
713 	    !ht_cap->ht_supported ||
714 	    !(ht_cap->cap & IEEE80211_HT_CAP_MAX_AMSDU))
715 		return;
716 
717 	link_sta->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_BA;
718 	ieee80211_sta_recalc_aggregates(link_sta->sta);
719 }
720 
iwl_mld_update_all_link_stations(struct iwl_mld * mld,struct ieee80211_sta * sta)721 int iwl_mld_update_all_link_stations(struct iwl_mld *mld,
722 				     struct ieee80211_sta *sta)
723 {
724 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
725 	struct ieee80211_link_sta *link_sta;
726 	int link_id;
727 
728 	for_each_sta_active_link(mld_sta->vif, sta, link_sta, link_id) {
729 		int ret = iwl_mld_add_modify_sta_cmd(mld, link_sta);
730 
731 		if (ret)
732 			return ret;
733 
734 		if (mld_sta->sta_state == IEEE80211_STA_ASSOC)
735 			iwl_mld_set_max_amsdu_len(mld, link_sta);
736 	}
737 	return 0;
738 }
739 
iwl_mld_destroy_sta(struct ieee80211_sta * sta)740 static void iwl_mld_destroy_sta(struct ieee80211_sta *sta)
741 {
742 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
743 
744 	kfree(mld_sta->dup_data);
745 	kfree(mld_sta->mpdu_counters);
746 }
747 
748 static int
iwl_mld_alloc_dup_data(struct iwl_mld * mld,struct iwl_mld_sta * mld_sta)749 iwl_mld_alloc_dup_data(struct iwl_mld *mld, struct iwl_mld_sta *mld_sta)
750 {
751 	struct iwl_mld_rxq_dup_data *dup_data;
752 
753 	if (mld->fw_status.in_hw_restart)
754 		return 0;
755 
756 	dup_data = kzalloc_objs(*dup_data, mld->trans->info.num_rxqs);
757 	if (!dup_data)
758 		return -ENOMEM;
759 
760 	/* Initialize all the last_seq values to 0xffff which can never
761 	 * compare equal to the frame's seq_ctrl in the check in
762 	 * iwl_mld_is_dup() since the lower 4 bits are the fragment
763 	 * number and fragmented packets don't reach that function.
764 	 *
765 	 * This thus allows receiving a packet with seqno 0 and the
766 	 * retry bit set as the very first packet on a new TID.
767 	 */
768 	for (int q = 0; q < mld->trans->info.num_rxqs; q++)
769 		memset(dup_data[q].last_seq, 0xff,
770 		       sizeof(dup_data[q].last_seq));
771 	mld_sta->dup_data = dup_data;
772 
773 	return 0;
774 }
775 
iwl_mld_alloc_mpdu_counters(struct iwl_mld * mld,struct ieee80211_sta * sta)776 static void iwl_mld_alloc_mpdu_counters(struct iwl_mld *mld,
777 					struct ieee80211_sta *sta)
778 {
779 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
780 	struct ieee80211_vif *vif = mld_sta->vif;
781 
782 	if (mld->fw_status.in_hw_restart)
783 		return;
784 
785 	/* MPDUs are counted only when EMLSR is possible */
786 	if (ieee80211_vif_type_p2p(vif) != NL80211_IFTYPE_STATION ||
787 	    sta->tdls || !ieee80211_vif_is_mld(vif))
788 		return;
789 
790 	mld_sta->mpdu_counters = kzalloc_objs(*mld_sta->mpdu_counters,
791 				              mld->trans->info.num_rxqs);
792 	if (!mld_sta->mpdu_counters)
793 		return;
794 
795 	for (int q = 0; q < mld->trans->info.num_rxqs; q++)
796 		spin_lock_init(&mld_sta->mpdu_counters[q].lock);
797 }
798 
799 static int
iwl_mld_init_sta(struct iwl_mld * mld,struct ieee80211_sta * sta,struct ieee80211_vif * vif,enum iwl_fw_sta_type type)800 iwl_mld_init_sta(struct iwl_mld *mld, struct ieee80211_sta *sta,
801 		 struct ieee80211_vif *vif, enum iwl_fw_sta_type type)
802 {
803 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
804 
805 	mld_sta->vif = vif;
806 	mld_sta->sta_type = type;
807 	mld_sta->mld = mld;
808 
809 	if (!mld->fw_status.in_hw_restart)
810 		for (int i = 0; i < ARRAY_SIZE(sta->txq); i++)
811 			iwl_mld_init_txq(iwl_mld_txq_from_mac80211(sta->txq[i]));
812 
813 	iwl_mld_alloc_mpdu_counters(mld, sta);
814 
815 	iwl_mld_toggle_tx_ant(mld, &mld_sta->data_tx_ant);
816 
817 	return iwl_mld_alloc_dup_data(mld, mld_sta);
818 }
819 
iwl_mld_add_sta(struct iwl_mld * mld,struct ieee80211_sta * sta,struct ieee80211_vif * vif)820 int iwl_mld_add_sta(struct iwl_mld *mld, struct ieee80211_sta *sta,
821 		    struct ieee80211_vif *vif)
822 {
823 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
824 	struct ieee80211_link_sta *link_sta;
825 	enum iwl_fw_sta_type type;
826 	int link_id;
827 	int ret;
828 
829 	switch (vif->type) {
830 	case NL80211_IFTYPE_NAN:
831 		type = STATION_TYPE_NAN_PEER_NMI;
832 		break;
833 	case NL80211_IFTYPE_NAN_DATA:
834 		type = STATION_TYPE_NAN_PEER_NDI;
835 		break;
836 	default:
837 		type = STATION_TYPE_PEER;
838 		break;
839 	}
840 
841 	ret = iwl_mld_init_sta(mld, sta, vif, type);
842 	if (ret)
843 		return ret;
844 
845 	/* We could have add only the deflink link_sta, but it will not work
846 	 * in the restart case if the single link that is active during
847 	 * reconfig is not the deflink one.
848 	 */
849 	for_each_sta_active_link(mld_sta->vif, sta, link_sta, link_id) {
850 		ret = iwl_mld_add_link_sta(mld, link_sta);
851 		if (ret)
852 			goto destroy_sta;
853 	}
854 
855 	return 0;
856 
857 destroy_sta:
858 	iwl_mld_destroy_sta(sta);
859 
860 	return ret;
861 }
862 
iwl_mld_flush_sta_txqs(struct iwl_mld * mld,struct ieee80211_sta * sta)863 void iwl_mld_flush_sta_txqs(struct iwl_mld *mld, struct ieee80211_sta *sta)
864 {
865 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
866 	struct ieee80211_link_sta *link_sta;
867 	int link_id;
868 
869 	for_each_sta_active_link(mld_sta->vif, sta, link_sta, link_id) {
870 		int fw_sta_id = iwl_mld_fw_sta_id_from_link_sta(mld, link_sta);
871 
872 		if (fw_sta_id < 0)
873 			continue;
874 
875 		iwl_mld_flush_link_sta_txqs(mld, fw_sta_id);
876 	}
877 }
878 
iwl_mld_wait_sta_txqs_empty(struct iwl_mld * mld,struct ieee80211_sta * sta)879 void iwl_mld_wait_sta_txqs_empty(struct iwl_mld *mld, struct ieee80211_sta *sta)
880 {
881 	/* Avoid a warning in iwl_trans_wait_txq_empty if are anyway on the way
882 	 * to a restart.
883 	 */
884 	if (iwl_mld_error_before_recovery(mld))
885 		return;
886 
887 	for (int i = 0; i < ARRAY_SIZE(sta->txq); i++) {
888 		struct iwl_mld_txq *mld_txq =
889 			iwl_mld_txq_from_mac80211(sta->txq[i]);
890 
891 		if (!mld_txq->status.allocated)
892 			continue;
893 
894 		iwl_trans_wait_txq_empty(mld->trans, mld_txq->fw_id);
895 	}
896 }
897 
iwl_mld_remove_sta(struct iwl_mld * mld,struct ieee80211_sta * sta)898 void iwl_mld_remove_sta(struct iwl_mld *mld, struct ieee80211_sta *sta)
899 {
900 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
901 	struct ieee80211_vif *vif = mld_sta->vif;
902 	struct ieee80211_link_sta *link_sta;
903 	u8 link_id;
904 
905 	lockdep_assert_wiphy(mld->wiphy);
906 
907 	/* Tell the HW to flush the queues */
908 	iwl_mld_flush_sta_txqs(mld, sta);
909 
910 	/* Wait for trans to empty its queues */
911 	iwl_mld_wait_sta_txqs_empty(mld, sta);
912 
913 	/* Now we can remove the queues */
914 	for (int i = 0; i < ARRAY_SIZE(sta->txq); i++)
915 		iwl_mld_remove_txq(mld, sta->txq[i]);
916 
917 	for_each_sta_active_link(vif, sta, link_sta, link_id) {
918 		/* Mac8011 will remove the groupwise keys after the sta is
919 		 * removed, but FW expects all the keys to be removed before
920 		 * the STA is, so remove them all here.
921 		 */
922 		if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
923 			iwl_mld_remove_ap_keys(mld, vif, sta, link_id);
924 
925 		/* Remove the link_sta */
926 		iwl_mld_remove_link_sta(mld, link_sta);
927 	}
928 
929 	iwl_mld_destroy_sta(sta);
930 }
931 
iwl_mld_fw_sta_id_mask(struct iwl_mld * mld,struct ieee80211_sta * sta)932 u32 iwl_mld_fw_sta_id_mask(struct iwl_mld *mld, struct ieee80211_sta *sta)
933 {
934 	struct ieee80211_vif *vif = iwl_mld_sta_from_mac80211(sta)->vif;
935 	struct ieee80211_link_sta *link_sta;
936 	unsigned int link_id;
937 	u32 result = 0;
938 
939 	KUNIT_STATIC_STUB_REDIRECT(iwl_mld_fw_sta_id_mask, mld, sta);
940 
941 	/* This function should only be used with the wiphy lock held,
942 	 * In other cases, it is not guaranteed that the link_sta will exist
943 	 * in the driver too, and it is checked in
944 	 * iwl_mld_fw_sta_id_from_link_sta.
945 	 */
946 	lockdep_assert_wiphy(mld->wiphy);
947 
948 	for_each_sta_active_link(vif, sta, link_sta, link_id) {
949 		int fw_id = iwl_mld_fw_sta_id_from_link_sta(mld, link_sta);
950 
951 		if (!(fw_id < 0))
952 			result |= BIT(fw_id);
953 	}
954 
955 	return result;
956 }
957 EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_fw_sta_id_mask);
958 
iwl_mld_count_mpdu(struct ieee80211_link_sta * link_sta,int queue,u32 count,bool tx)959 static void iwl_mld_count_mpdu(struct ieee80211_link_sta *link_sta, int queue,
960 			       u32 count, bool tx)
961 {
962 	struct iwl_mld_per_q_mpdu_counter *queue_counter;
963 	struct iwl_mld_per_link_mpdu_counter *link_counter;
964 	struct iwl_mld_vif *mld_vif;
965 	struct iwl_mld_sta *mld_sta;
966 	struct iwl_mld_link *mld_link;
967 	struct iwl_mld *mld;
968 	int total_mpdus = 0;
969 
970 	if (WARN_ON(!link_sta))
971 		return;
972 
973 	mld_sta = iwl_mld_sta_from_mac80211(link_sta->sta);
974 	if (!mld_sta->mpdu_counters)
975 		return;
976 
977 	mld_vif = iwl_mld_vif_from_mac80211(mld_sta->vif);
978 	mld_link = iwl_mld_link_dereference_check(mld_vif, link_sta->link_id);
979 
980 	if (WARN_ON_ONCE(!mld_link))
981 		return;
982 
983 	queue_counter = &mld_sta->mpdu_counters[queue];
984 
985 	mld = mld_vif->mld;
986 
987 	/* If it the window is over, first clear the counters.
988 	 * When we are not blocked by TPT, the window is managed by check_tpt_wk
989 	 */
990 	if ((mld_vif->emlsr.blocked_reasons & IWL_MLD_EMLSR_BLOCKED_TPT) &&
991 	    time_is_before_jiffies(queue_counter->window_start_time +
992 					IWL_MLD_TPT_COUNT_WINDOW)) {
993 		memset(queue_counter->per_link, 0,
994 		       sizeof(queue_counter->per_link));
995 		queue_counter->window_start_time = jiffies;
996 
997 		IWL_DEBUG_EHT(mld, "MPDU counters are cleared\n");
998 	}
999 
1000 	link_counter = &queue_counter->per_link[mld_link->fw_id];
1001 
1002 	spin_lock_bh(&queue_counter->lock);
1003 
1004 	/* Update the statistics for this TPT measurement window */
1005 	if (tx)
1006 		link_counter->tx += count;
1007 	else
1008 		link_counter->rx += count;
1009 
1010 	/*
1011 	 * Next, evaluate whether we should queue an unblock,
1012 	 * skip this if we are not blocked due to low throughput.
1013 	 */
1014 	if (!(mld_vif->emlsr.blocked_reasons & IWL_MLD_EMLSR_BLOCKED_TPT))
1015 		goto unlock;
1016 
1017 	for (int i = 0; i < IWL_FW_MAX_LINKS; i++)
1018 		total_mpdus += tx ? queue_counter->per_link[i].tx :
1019 				    queue_counter->per_link[i].rx;
1020 
1021 	/* Unblock is already queued if the threshold was reached before */
1022 	if (total_mpdus - count >= IWL_MLD_ENTER_EMLSR_TPT_THRESH)
1023 		goto unlock;
1024 
1025 	if (total_mpdus >= IWL_MLD_ENTER_EMLSR_TPT_THRESH)
1026 		wiphy_work_queue(mld->wiphy, &mld_vif->emlsr.unblock_tpt_wk);
1027 
1028 unlock:
1029 	spin_unlock_bh(&queue_counter->lock);
1030 }
1031 
1032 /* must be called under rcu_read_lock() */
iwl_mld_count_mpdu_rx(struct ieee80211_link_sta * link_sta,int queue,u32 count)1033 void iwl_mld_count_mpdu_rx(struct ieee80211_link_sta *link_sta, int queue,
1034 			   u32 count)
1035 {
1036 	iwl_mld_count_mpdu(link_sta, queue, count, false);
1037 }
1038 
1039 /* must be called under rcu_read_lock() */
iwl_mld_count_mpdu_tx(struct ieee80211_link_sta * link_sta,u32 count)1040 void iwl_mld_count_mpdu_tx(struct ieee80211_link_sta *link_sta, u32 count)
1041 {
1042 	/* use queue 0 for all TX */
1043 	iwl_mld_count_mpdu(link_sta, 0, count, true);
1044 }
1045 
iwl_mld_allocate_internal_txq(struct iwl_mld * mld,struct iwl_mld_int_sta * internal_sta,u8 tid)1046 static int iwl_mld_allocate_internal_txq(struct iwl_mld *mld,
1047 					 struct iwl_mld_int_sta *internal_sta,
1048 					 u8 tid)
1049 {
1050 	u32 sta_mask = BIT(internal_sta->sta_id);
1051 	int queue, size;
1052 
1053 	size = max_t(u32, IWL_MGMT_QUEUE_SIZE,
1054 		     mld->trans->mac_cfg->base->min_txq_size);
1055 
1056 	queue = iwl_trans_txq_alloc(mld->trans, 0, sta_mask, tid, size,
1057 				    IWL_WATCHDOG_DISABLED);
1058 
1059 	if (queue >= 0)
1060 		IWL_DEBUG_TX_QUEUES(mld,
1061 				    "Enabling TXQ #%d for sta mask 0x%x tid %d\n",
1062 				    queue, sta_mask, tid);
1063 	return queue;
1064 }
1065 
iwl_mld_send_aux_sta_cmd(struct iwl_mld * mld,const struct iwl_mld_int_sta * internal_sta)1066 static int iwl_mld_send_aux_sta_cmd(struct iwl_mld *mld,
1067 				    const struct iwl_mld_int_sta *internal_sta)
1068 {
1069 	struct iwl_aux_sta_cmd cmd = {
1070 		.sta_id = cpu_to_le32(internal_sta->sta_id),
1071 		/* TODO: CDB - properly set the lmac_id */
1072 		.lmac_id = cpu_to_le32(IWL_LMAC_24G_INDEX),
1073 	};
1074 
1075 	return iwl_mld_send_cmd_pdu(mld, WIDE_ID(MAC_CONF_GROUP, AUX_STA_CMD),
1076 				    &cmd);
1077 }
1078 
1079 static int
iwl_mld_set_internal_sta_to_fw(struct iwl_mld * mld,const struct iwl_mld_int_sta * internal_sta,u32 link_mask,const u8 * addr)1080 iwl_mld_set_internal_sta_to_fw(struct iwl_mld *mld,
1081 			       const struct iwl_mld_int_sta *internal_sta,
1082 			       u32 link_mask, const u8 *addr)
1083 {
1084 	struct iwl_sta_cfg_cmd cmd = {};
1085 
1086 	if (internal_sta->sta_type == STATION_TYPE_AUX)
1087 		return iwl_mld_send_aux_sta_cmd(mld, internal_sta);
1088 
1089 	cmd.sta_id = cpu_to_le32((u8)internal_sta->sta_id);
1090 	cmd.link_mask = cpu_to_le32(link_mask);
1091 	cmd.station_type = cpu_to_le32(internal_sta->sta_type);
1092 
1093 	/* FW doesn't allow to add a IGTK/BIGTK if the sta isn't marked as MFP.
1094 	 * On the other hand, FW will never check this flag during RX since
1095 	 * an AP/GO doesn't receive protected broadcast management frames.
1096 	 * So, we can set it unconditionally.
1097 	 *
1098 	 * For NAN stations associated with a NAN Device, the MFP bit must be
1099 	 * set to 1, as otherwise the FW will assert when a key associated with
1100 	 * these stations would be added.
1101 	 */
1102 	if (internal_sta->sta_type == STATION_TYPE_BCAST_MGMT ||
1103 	    internal_sta->sta_type == STATION_TYPE_NAN_BCAST ||
1104 	    internal_sta->sta_type == STATION_TYPE_NAN_MGMT)
1105 		cmd.mfp = cpu_to_le32(1);
1106 
1107 	if (addr) {
1108 		if (internal_sta->sta_type == STATION_TYPE_NAN_MCAST_DATA) {
1109 			ether_addr_copy(cmd.ndi_local_addr, addr);
1110 		} else {
1111 			memcpy(cmd.peer_mld_address, addr, ETH_ALEN);
1112 			memcpy(cmd.peer_link_address, addr, ETH_ALEN);
1113 		}
1114 	}
1115 
1116 	return iwl_mld_send_sta_cmd(mld, &cmd);
1117 }
1118 
iwl_mld_add_internal_sta(struct iwl_mld * mld,struct iwl_mld_int_sta * internal_sta,enum iwl_fw_sta_type sta_type,u32 link_mask,const u8 * addr,u8 tid,bool add_txq)1119 static int iwl_mld_add_internal_sta(struct iwl_mld *mld,
1120 				    struct iwl_mld_int_sta *internal_sta,
1121 				    enum iwl_fw_sta_type sta_type,
1122 				    u32 link_mask, const u8 *addr,
1123 				    u8 tid, bool add_txq)
1124 {
1125 	int ret, queue_id;
1126 
1127 	ret = iwl_mld_allocate_link_sta_fw_id(mld,
1128 					      &internal_sta->sta_id,
1129 					      ERR_PTR(-EINVAL));
1130 	if (ret)
1131 		return ret;
1132 
1133 	internal_sta->sta_type = sta_type;
1134 
1135 	ret = iwl_mld_set_internal_sta_to_fw(mld, internal_sta, link_mask,
1136 					     addr);
1137 	if (ret)
1138 		goto err;
1139 
1140 	if (!add_txq)
1141 		return 0;
1142 
1143 	queue_id = iwl_mld_allocate_internal_txq(mld, internal_sta, tid);
1144 	if (queue_id < 0) {
1145 		iwl_mld_rm_sta_from_fw(mld, internal_sta->sta_id);
1146 		ret = queue_id;
1147 		goto err;
1148 	}
1149 
1150 	internal_sta->queue_id = queue_id;
1151 
1152 	return 0;
1153 err:
1154 	iwl_mld_free_internal_sta(mld, internal_sta);
1155 	return ret;
1156 }
1157 
iwl_mld_add_bcast_sta(struct iwl_mld * mld,struct ieee80211_vif * vif,struct ieee80211_bss_conf * link)1158 int iwl_mld_add_bcast_sta(struct iwl_mld *mld,
1159 			  struct ieee80211_vif *vif,
1160 			  struct ieee80211_bss_conf *link)
1161 {
1162 	struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link);
1163 	const u8 bcast_addr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1164 	const u8 *addr;
1165 
1166 	if (WARN_ON(!mld_link))
1167 		return -EINVAL;
1168 
1169 	if (WARN_ON(vif->type != NL80211_IFTYPE_AP &&
1170 		    vif->type != NL80211_IFTYPE_ADHOC))
1171 		return -EINVAL;
1172 
1173 	addr = vif->type == NL80211_IFTYPE_ADHOC ? link->bssid : bcast_addr;
1174 
1175 	return iwl_mld_add_internal_sta(mld, &mld_link->bcast_sta,
1176 					STATION_TYPE_BCAST_MGMT,
1177 					BIT(mld_link->fw_id), addr,
1178 					IWL_MGMT_TID, true);
1179 }
1180 
iwl_mld_add_mcast_sta(struct iwl_mld * mld,struct ieee80211_vif * vif,struct ieee80211_bss_conf * link)1181 int iwl_mld_add_mcast_sta(struct iwl_mld *mld,
1182 			  struct ieee80211_vif *vif,
1183 			  struct ieee80211_bss_conf *link)
1184 {
1185 	struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link);
1186 	const u8 mcast_addr[] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
1187 
1188 	if (WARN_ON(!mld_link))
1189 		return -EINVAL;
1190 
1191 	if (WARN_ON(vif->type != NL80211_IFTYPE_AP &&
1192 		    vif->type != NL80211_IFTYPE_ADHOC))
1193 		return -EINVAL;
1194 
1195 	return iwl_mld_add_internal_sta(mld, &mld_link->mcast_sta,
1196 					STATION_TYPE_MCAST,
1197 					BIT(mld_link->fw_id), mcast_addr,
1198 					0, true);
1199 }
1200 
iwl_mld_add_aux_sta(struct iwl_mld * mld,struct iwl_mld_int_sta * internal_sta)1201 int iwl_mld_add_aux_sta(struct iwl_mld *mld,
1202 			struct iwl_mld_int_sta *internal_sta)
1203 {
1204 	return iwl_mld_add_internal_sta(mld, internal_sta, STATION_TYPE_AUX,
1205 					0, NULL, IWL_MAX_TID_COUNT,
1206 					true);
1207 }
1208 
iwl_mld_add_mon_sta(struct iwl_mld * mld,struct ieee80211_vif * vif,struct ieee80211_bss_conf * link)1209 int iwl_mld_add_mon_sta(struct iwl_mld *mld,
1210 			struct ieee80211_vif *vif,
1211 			struct ieee80211_bss_conf *link)
1212 {
1213 	struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link);
1214 
1215 	if (WARN_ON(!mld_link))
1216 		return -EINVAL;
1217 
1218 	if (WARN_ON(vif->type != NL80211_IFTYPE_MONITOR))
1219 		return -EINVAL;
1220 
1221 	return iwl_mld_add_internal_sta(mld, &mld_link->mon_sta,
1222 					STATION_TYPE_BCAST_MGMT,
1223 					BIT(mld_link->fw_id), NULL,
1224 					IWL_MAX_TID_COUNT,
1225 					true);
1226 }
1227 
iwl_mld_remove_internal_sta(struct iwl_mld * mld,struct iwl_mld_int_sta * internal_sta,bool flush,u8 tid)1228 static void iwl_mld_remove_internal_sta(struct iwl_mld *mld,
1229 					struct iwl_mld_int_sta *internal_sta,
1230 					bool flush, u8 tid)
1231 {
1232 	if (WARN_ON_ONCE(internal_sta->sta_id == IWL_INVALID_STA))
1233 		return;
1234 
1235 	if (flush && !WARN_ON_ONCE(internal_sta->queue_id ==
1236 				   IWL_MLD_INVALID_QUEUE))
1237 		iwl_mld_flush_link_sta_txqs(mld, internal_sta->sta_id);
1238 
1239 	if (internal_sta->queue_id != IWL_MLD_INVALID_QUEUE)
1240 		iwl_mld_free_txq(mld, BIT(internal_sta->sta_id),
1241 				 tid, internal_sta->queue_id);
1242 
1243 	iwl_mld_rm_sta_from_fw(mld, internal_sta->sta_id);
1244 
1245 	iwl_mld_free_internal_sta(mld, internal_sta);
1246 }
1247 
iwl_mld_remove_bcast_sta(struct iwl_mld * mld,struct ieee80211_vif * vif,struct ieee80211_bss_conf * link)1248 void iwl_mld_remove_bcast_sta(struct iwl_mld *mld,
1249 			      struct ieee80211_vif *vif,
1250 			      struct ieee80211_bss_conf *link)
1251 {
1252 	struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link);
1253 
1254 	if (WARN_ON(!mld_link))
1255 		return;
1256 
1257 	if (WARN_ON(vif->type != NL80211_IFTYPE_AP &&
1258 		    vif->type != NL80211_IFTYPE_ADHOC))
1259 		return;
1260 
1261 	iwl_mld_remove_internal_sta(mld, &mld_link->bcast_sta, true,
1262 				    IWL_MGMT_TID);
1263 }
1264 
iwl_mld_remove_mcast_sta(struct iwl_mld * mld,struct ieee80211_vif * vif,struct ieee80211_bss_conf * link)1265 void iwl_mld_remove_mcast_sta(struct iwl_mld *mld,
1266 			      struct ieee80211_vif *vif,
1267 			      struct ieee80211_bss_conf *link)
1268 {
1269 	struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link);
1270 
1271 	if (WARN_ON(!mld_link))
1272 		return;
1273 
1274 	if (WARN_ON(vif->type != NL80211_IFTYPE_AP &&
1275 		    vif->type != NL80211_IFTYPE_ADHOC))
1276 		return;
1277 
1278 	iwl_mld_remove_internal_sta(mld, &mld_link->mcast_sta, true, 0);
1279 }
1280 
iwl_mld_remove_aux_sta(struct iwl_mld * mld,struct ieee80211_vif * vif)1281 void iwl_mld_remove_aux_sta(struct iwl_mld *mld,
1282 			    struct ieee80211_vif *vif)
1283 {
1284 	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
1285 
1286 	if (WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE &&
1287 		    vif->type != NL80211_IFTYPE_STATION &&
1288 		    vif->type != NL80211_IFTYPE_NAN))
1289 		return;
1290 
1291 	iwl_mld_remove_internal_sta(mld, &mld_vif->aux_sta, false,
1292 				    IWL_MAX_TID_COUNT);
1293 }
1294 
iwl_mld_remove_mon_sta(struct iwl_mld * mld,struct ieee80211_vif * vif,struct ieee80211_bss_conf * link)1295 void iwl_mld_remove_mon_sta(struct iwl_mld *mld,
1296 			    struct ieee80211_vif *vif,
1297 			    struct ieee80211_bss_conf *link)
1298 {
1299 	struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link);
1300 
1301 	if (WARN_ON(!mld_link))
1302 		return;
1303 
1304 	if (WARN_ON(vif->type != NL80211_IFTYPE_MONITOR))
1305 		return;
1306 
1307 	iwl_mld_remove_internal_sta(mld, &mld_link->mon_sta, false,
1308 				    IWL_MAX_TID_COUNT);
1309 }
1310 
iwl_mld_update_sta_resources(struct iwl_mld * mld,struct ieee80211_vif * vif,struct ieee80211_sta * sta,u32 old_sta_mask,u32 new_sta_mask)1311 static int iwl_mld_update_sta_resources(struct iwl_mld *mld,
1312 					struct ieee80211_vif *vif,
1313 					struct ieee80211_sta *sta,
1314 					u32 old_sta_mask,
1315 					u32 new_sta_mask)
1316 {
1317 	int ret;
1318 
1319 	ret = iwl_mld_update_sta_txqs(mld, sta, old_sta_mask, new_sta_mask);
1320 	if (ret)
1321 		return ret;
1322 
1323 	ret = iwl_mld_update_sta_keys(mld, vif, sta, old_sta_mask, new_sta_mask);
1324 	if (ret)
1325 		return ret;
1326 
1327 	return iwl_mld_update_sta_baids(mld, old_sta_mask, new_sta_mask);
1328 }
1329 
iwl_mld_update_link_stas(struct iwl_mld * mld,struct ieee80211_vif * vif,struct ieee80211_sta * sta,u16 old_links,u16 new_links)1330 int iwl_mld_update_link_stas(struct iwl_mld *mld,
1331 			     struct ieee80211_vif *vif,
1332 			     struct ieee80211_sta *sta,
1333 			     u16 old_links, u16 new_links)
1334 {
1335 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
1336 	struct iwl_mld_link_sta *mld_link_sta;
1337 	unsigned long links_to_add = ~old_links & new_links;
1338 	unsigned long links_to_rem = old_links & ~new_links;
1339 	unsigned long old_links_long = old_links;
1340 	unsigned long sta_mask_added = 0;
1341 	u32 current_sta_mask = 0, sta_mask_to_rem = 0;
1342 	unsigned int link_id, sta_id;
1343 	int ret;
1344 
1345 	lockdep_assert_wiphy(mld->wiphy);
1346 
1347 	for_each_set_bit(link_id, &old_links_long,
1348 			 IEEE80211_MLD_MAX_NUM_LINKS) {
1349 		mld_link_sta =
1350 			iwl_mld_link_sta_dereference_check(mld_sta, link_id);
1351 
1352 		if (WARN_ON(!mld_link_sta))
1353 			return -EINVAL;
1354 
1355 		current_sta_mask |= BIT(mld_link_sta->fw_id);
1356 		if (links_to_rem & BIT(link_id))
1357 			sta_mask_to_rem |= BIT(mld_link_sta->fw_id);
1358 	}
1359 
1360 	if (sta_mask_to_rem) {
1361 		ret = iwl_mld_update_sta_resources(mld, vif, sta,
1362 						   current_sta_mask,
1363 						   current_sta_mask &
1364 							~sta_mask_to_rem);
1365 		if (ret)
1366 			return ret;
1367 
1368 		current_sta_mask &= ~sta_mask_to_rem;
1369 	}
1370 
1371 	for_each_set_bit(link_id, &links_to_rem, IEEE80211_MLD_MAX_NUM_LINKS) {
1372 		struct ieee80211_link_sta *link_sta =
1373 			link_sta_dereference_protected(sta, link_id);
1374 
1375 		if (WARN_ON(!link_sta))
1376 			return -EINVAL;
1377 
1378 		iwl_mld_remove_link_sta(mld, link_sta);
1379 	}
1380 
1381 	for_each_set_bit(link_id, &links_to_add, IEEE80211_MLD_MAX_NUM_LINKS) {
1382 		struct ieee80211_link_sta *link_sta =
1383 			link_sta_dereference_protected(sta, link_id);
1384 		struct ieee80211_bss_conf *link;
1385 
1386 		if (WARN_ON(!link_sta))
1387 			return -EINVAL;
1388 
1389 		ret = iwl_mld_add_link_sta(mld, link_sta);
1390 		if (ret)
1391 			goto remove_added_link_stas;
1392 
1393 		mld_link_sta =
1394 			iwl_mld_link_sta_dereference_check(mld_sta,
1395 							   link_id);
1396 
1397 		link = link_conf_dereference_protected(mld_sta->vif,
1398 						       link_sta->link_id);
1399 
1400 		iwl_mld_set_max_amsdu_len(mld, link_sta);
1401 		iwl_mld_config_tlc_link(mld, vif, link, link_sta);
1402 
1403 		sta_mask_added |= BIT(mld_link_sta->fw_id);
1404 	}
1405 
1406 	if (sta_mask_added) {
1407 		ret = iwl_mld_update_sta_resources(mld, vif, sta,
1408 						   current_sta_mask,
1409 						   current_sta_mask |
1410 							sta_mask_added);
1411 		if (ret)
1412 			goto remove_added_link_stas;
1413 	}
1414 
1415 	/* We couldn't activate the links before it has a STA. Now we can */
1416 	for_each_set_bit(link_id, &links_to_add, IEEE80211_MLD_MAX_NUM_LINKS) {
1417 		struct ieee80211_bss_conf *link =
1418 			link_conf_dereference_protected(mld_sta->vif, link_id);
1419 
1420 		if (WARN_ON(!link))
1421 			continue;
1422 
1423 		iwl_mld_activate_link(mld, link);
1424 	}
1425 
1426 	return 0;
1427 
1428 remove_added_link_stas:
1429 	for_each_set_bit(sta_id, &sta_mask_added, mld->fw->ucode_capa.num_stations) {
1430 		struct ieee80211_link_sta *link_sta =
1431 			wiphy_dereference(mld->wiphy,
1432 					  mld->fw_id_to_link_sta[sta_id]);
1433 
1434 		if (WARN_ON(!link_sta))
1435 			continue;
1436 
1437 		iwl_mld_remove_link_sta(mld, link_sta);
1438 	}
1439 
1440 	return ret;
1441 }
1442 
iwl_mld_add_nan_bcast_sta(struct iwl_mld * mld,struct iwl_mld_int_sta * sta)1443 int iwl_mld_add_nan_bcast_sta(struct iwl_mld *mld,
1444 			      struct iwl_mld_int_sta *sta)
1445 {
1446 	const u8 bcast_addr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1447 
1448 	return iwl_mld_add_internal_sta(mld, sta, STATION_TYPE_NAN_BCAST,
1449 					0, bcast_addr, 0, false);
1450 }
1451 
iwl_mld_add_nan_mgmt_sta(struct iwl_mld * mld,struct iwl_mld_int_sta * sta)1452 int iwl_mld_add_nan_mgmt_sta(struct iwl_mld *mld,
1453 			     struct iwl_mld_int_sta *sta)
1454 {
1455 	return iwl_mld_add_internal_sta(mld, sta, STATION_TYPE_NAN_MGMT,
1456 					0, NULL, IWL_MAX_TID_COUNT, true);
1457 }
1458 
iwl_mld_add_nan_mcast_data_sta(struct iwl_mld * mld,const u8 * ndi_addr,struct iwl_mld_int_sta * sta)1459 int iwl_mld_add_nan_mcast_data_sta(struct iwl_mld *mld,
1460 				   const u8 *ndi_addr,
1461 				   struct iwl_mld_int_sta *sta)
1462 {
1463 	u32 link_mask = iwl_mld_get_nan_link_mask(mld);
1464 
1465 	/* In case that there are no NAN links, nothing to do */
1466 	if (!link_mask)
1467 		return 0;
1468 
1469 	return iwl_mld_add_internal_sta(mld, sta,
1470 					STATION_TYPE_NAN_MCAST_DATA,
1471 					link_mask, ndi_addr,
1472 					0, true);
1473 }
1474 
iwl_mld_update_nan_mcast_data_sta(struct iwl_mld * mld,const u8 * ndi_addr,struct iwl_mld_int_sta * sta)1475 int iwl_mld_update_nan_mcast_data_sta(struct iwl_mld *mld,
1476 				      const u8 *ndi_addr,
1477 				      struct iwl_mld_int_sta *sta)
1478 {
1479 	u32 link_mask;
1480 
1481 	if (WARN_ON(!mld->nan_device_vif))
1482 		return -EINVAL;
1483 
1484 	/* If the sta doesn't exist, add it */
1485 	if (sta->sta_id == IWL_INVALID_STA)
1486 		return iwl_mld_add_nan_mcast_data_sta(mld, ndi_addr, sta);
1487 
1488 	/* The station was already added */
1489 	if (WARN_ON(sta->sta_type != STATION_TYPE_NAN_MCAST_DATA))
1490 		return -EINVAL;
1491 
1492 	link_mask = iwl_mld_get_nan_link_mask(mld);
1493 	if (link_mask)
1494 		return iwl_mld_set_internal_sta_to_fw(mld,
1495 						      sta, link_mask,
1496 						      ndi_addr);
1497 
1498 	/* If no links are associated with NAN, remove the station */
1499 	iwl_mld_remove_nan_mcast_data_sta(mld, sta);
1500 
1501 	return 0;
1502 }
1503 
iwl_mld_remove_nan_bcast_sta(struct iwl_mld * mld,struct iwl_mld_int_sta * sta)1504 void iwl_mld_remove_nan_bcast_sta(struct iwl_mld *mld,
1505 				  struct iwl_mld_int_sta *sta)
1506 {
1507 	iwl_mld_remove_internal_sta(mld, sta, false, 0);
1508 }
1509 
iwl_mld_remove_nan_mgmt_sta(struct iwl_mld * mld,struct iwl_mld_int_sta * sta)1510 void iwl_mld_remove_nan_mgmt_sta(struct iwl_mld *mld,
1511 				 struct iwl_mld_int_sta *sta)
1512 {
1513 	iwl_mld_remove_internal_sta(mld, sta, true, IWL_MAX_TID_COUNT);
1514 }
1515 
iwl_mld_remove_nan_mcast_data_sta(struct iwl_mld * mld,struct iwl_mld_int_sta * sta)1516 void iwl_mld_remove_nan_mcast_data_sta(struct iwl_mld *mld,
1517 				       struct iwl_mld_int_sta *sta)
1518 {
1519 	iwl_mld_remove_internal_sta(mld, sta, true, 0);
1520 }
1521