xref: /openbmc/linux/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c (revision 9df839a711aee437390b16ee39cf0b5c1620be6a)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3  * Copyright (C) 2022 Intel Corporation
4  */
5 #include "mvm.h"
6 #include "time-sync.h"
7 
8 static int iwl_mvm_mld_send_sta_cmd(struct iwl_mvm *mvm,
9 				    struct iwl_mvm_sta_cfg_cmd *cmd)
10 {
11 	int ret = iwl_mvm_send_cmd_pdu(mvm,
12 				       WIDE_ID(MAC_CONF_GROUP, STA_CONFIG_CMD),
13 				       0, sizeof(*cmd), cmd);
14 	if (ret)
15 		IWL_ERR(mvm, "STA_CONFIG_CMD send failed, ret=0x%x\n", ret);
16 	return ret;
17 }
18 
19 /*
20  * Add an internal station to the FW table
21  */
22 static int iwl_mvm_mld_add_int_sta_to_fw(struct iwl_mvm *mvm,
23 					 struct iwl_mvm_int_sta *sta,
24 					 const u8 *addr, int link_id)
25 {
26 	struct iwl_mvm_sta_cfg_cmd cmd;
27 
28 	lockdep_assert_held(&mvm->mutex);
29 
30 	memset(&cmd, 0, sizeof(cmd));
31 	cmd.sta_id = cpu_to_le32((u8)sta->sta_id);
32 
33 	cmd.link_id = cpu_to_le32(link_id);
34 
35 	cmd.station_type = cpu_to_le32(sta->type);
36 
37 	if (addr) {
38 		memcpy(cmd.peer_mld_address, addr, ETH_ALEN);
39 		memcpy(cmd.peer_link_address, addr, ETH_ALEN);
40 	}
41 
42 	return iwl_mvm_mld_send_sta_cmd(mvm, &cmd);
43 }
44 
45 /*
46  * Remove a station from the FW table. Before sending the command to remove
47  * the station validate that the station is indeed known to the driver (sanity
48  * only).
49  */
50 static int iwl_mvm_mld_rm_sta_from_fw(struct iwl_mvm *mvm, u32 sta_id)
51 {
52 	struct iwl_mvm_remove_sta_cmd rm_sta_cmd = {
53 		.sta_id = cpu_to_le32(sta_id),
54 	};
55 	int ret;
56 
57 	/* Note: internal stations are marked as error values */
58 	if (!rcu_access_pointer(mvm->fw_id_to_mac_id[sta_id])) {
59 		IWL_ERR(mvm, "Invalid station id %d\n", sta_id);
60 		return -EINVAL;
61 	}
62 
63 	ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(MAC_CONF_GROUP, STA_REMOVE_CMD),
64 				   0, sizeof(rm_sta_cmd), &rm_sta_cmd);
65 	if (ret) {
66 		IWL_ERR(mvm, "Failed to remove station. Id=%d\n", sta_id);
67 		return ret;
68 	}
69 
70 	return 0;
71 }
72 
73 static int iwl_mvm_add_aux_sta_to_fw(struct iwl_mvm *mvm,
74 				     struct iwl_mvm_int_sta *sta,
75 				     u32 lmac_id)
76 {
77 	int ret;
78 
79 	struct iwl_mvm_aux_sta_cmd cmd = {
80 		.sta_id = cpu_to_le32(sta->sta_id),
81 		.lmac_id = cpu_to_le32(lmac_id),
82 	};
83 
84 	ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(MAC_CONF_GROUP, AUX_STA_CMD),
85 				   0, sizeof(cmd), &cmd);
86 	if (ret)
87 		IWL_ERR(mvm, "Failed to send AUX_STA_CMD\n");
88 	return ret;
89 }
90 
91 /*
92  * Adds an internal sta to the FW table with its queues
93  */
94 static int iwl_mvm_mld_add_int_sta_with_queue(struct iwl_mvm *mvm,
95 					      struct iwl_mvm_int_sta *sta,
96 					      const u8 *addr, int link_id,
97 					      u16 *queue, u8 tid,
98 					      unsigned int *_wdg_timeout)
99 {
100 	int ret, txq;
101 	unsigned int wdg_timeout = _wdg_timeout ? *_wdg_timeout :
102 		mvm->trans->trans_cfg->base_params->wd_timeout;
103 
104 	if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_INVALID_STA))
105 		return -ENOSPC;
106 
107 	if (sta->type == STATION_TYPE_AUX)
108 		ret = iwl_mvm_add_aux_sta_to_fw(mvm, sta, link_id);
109 	else
110 		ret = iwl_mvm_mld_add_int_sta_to_fw(mvm, sta, addr, link_id);
111 	if (ret)
112 		return ret;
113 
114 	/*
115 	 * For 22000 firmware and on we cannot add queue to a station unknown
116 	 * to firmware so enable queue here - after the station was added
117 	 */
118 	txq = iwl_mvm_tvqm_enable_txq(mvm, NULL, sta->sta_id, tid,
119 				      wdg_timeout);
120 	if (txq < 0) {
121 		iwl_mvm_mld_rm_sta_from_fw(mvm, sta->sta_id);
122 		return txq;
123 	}
124 	*queue = txq;
125 
126 	return 0;
127 }
128 
129 /*
130  * Adds a new int sta: allocate it in the driver, add it to the FW table,
131  * and add its queues.
132  */
133 static int iwl_mvm_mld_add_int_sta(struct iwl_mvm *mvm,
134 				   struct iwl_mvm_int_sta *int_sta, u16 *queue,
135 				   enum nl80211_iftype iftype,
136 				   enum iwl_fw_sta_type sta_type,
137 				   int link_id, const u8 *addr, u8 tid,
138 				   unsigned int *wdg_timeout)
139 {
140 	int ret;
141 
142 	lockdep_assert_held(&mvm->mutex);
143 
144 	/* qmask argument is not used in the new tx api, send a don't care */
145 	ret = iwl_mvm_allocate_int_sta(mvm, int_sta, 0, iftype,
146 				       sta_type);
147 	if (ret)
148 		return ret;
149 
150 	ret = iwl_mvm_mld_add_int_sta_with_queue(mvm, int_sta, addr, link_id,
151 						 queue, tid, wdg_timeout);
152 	if (ret) {
153 		iwl_mvm_dealloc_int_sta(mvm, int_sta);
154 		return ret;
155 	}
156 
157 	return 0;
158 }
159 
160 /* Allocate a new station entry for the broadcast station to the given vif,
161  * and send it to the FW.
162  * Note that each P2P mac should have its own broadcast station.
163  */
164 int iwl_mvm_mld_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
165 			      struct ieee80211_bss_conf *link_conf)
166 {
167 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
168 	struct iwl_mvm_vif_link_info *mvm_link =
169 		mvmvif->link[link_conf->link_id];
170 	struct iwl_mvm_int_sta *bsta = &mvm_link->bcast_sta;
171 	static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
172 	const u8 *baddr = _baddr;
173 	unsigned int wdg_timeout =
174 		iwl_mvm_get_wd_timeout(mvm, vif, false, false);
175 	u16 *queue;
176 
177 	lockdep_assert_held(&mvm->mutex);
178 
179 	if (vif->type == NL80211_IFTYPE_ADHOC)
180 		baddr = link_conf->bssid;
181 
182 	if (vif->type == NL80211_IFTYPE_AP ||
183 	    vif->type == NL80211_IFTYPE_ADHOC) {
184 		queue = &mvm_link->mgmt_queue;
185 	} else if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
186 		queue = &mvm->p2p_dev_queue;
187 	} else {
188 		WARN(1, "Missing required TXQ for adding bcast STA\n");
189 		return -EINVAL;
190 	}
191 
192 	return iwl_mvm_mld_add_int_sta(mvm, bsta, queue,
193 				       ieee80211_vif_type_p2p(vif),
194 				       STATION_TYPE_BCAST_MGMT,
195 				       mvm_link->fw_link_id, baddr,
196 				       IWL_MAX_TID_COUNT, &wdg_timeout);
197 }
198 
199 /* Allocate a new station entry for the broadcast station to the given vif,
200  * and send it to the FW.
201  * Note that each AP/GO mac should have its own multicast station.
202  */
203 int iwl_mvm_mld_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
204 			      struct ieee80211_bss_conf *link_conf)
205 {
206 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
207 	struct iwl_mvm_vif_link_info *mvm_link =
208 		mvmvif->link[link_conf->link_id];
209 	struct iwl_mvm_int_sta *msta = &mvm_link->mcast_sta;
210 	static const u8 _maddr[] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
211 	const u8 *maddr = _maddr;
212 	unsigned int timeout = iwl_mvm_get_wd_timeout(mvm, vif, false, false);
213 
214 	lockdep_assert_held(&mvm->mutex);
215 
216 	if (WARN_ON(vif->type != NL80211_IFTYPE_AP &&
217 		    vif->type != NL80211_IFTYPE_ADHOC))
218 		return -EOPNOTSUPP;
219 
220 	/* In IBSS, ieee80211_check_queues() sets the cab_queue to be
221 	 * invalid, so make sure we use the queue we want.
222 	 * Note that this is done here as we want to avoid making DQA
223 	 * changes in mac80211 layer.
224 	 */
225 	if (vif->type == NL80211_IFTYPE_ADHOC)
226 		mvm_link->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
227 
228 	return iwl_mvm_mld_add_int_sta(mvm, msta, &mvm_link->cab_queue,
229 				       vif->type, STATION_TYPE_MCAST,
230 				       mvm_link->fw_link_id, maddr, 0,
231 				       &timeout);
232 }
233 
234 /* Allocate a new station entry for the sniffer station to the given vif,
235  * and send it to the FW.
236  */
237 int iwl_mvm_mld_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
238 			     struct ieee80211_bss_conf *link_conf)
239 {
240 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
241 	struct iwl_mvm_vif_link_info *mvm_link =
242 		mvmvif->link[link_conf->link_id];
243 
244 	lockdep_assert_held(&mvm->mutex);
245 
246 	return iwl_mvm_mld_add_int_sta(mvm, &mvm->snif_sta, &mvm->snif_queue,
247 				       vif->type, STATION_TYPE_BCAST_MGMT,
248 				       mvm_link->fw_link_id, NULL,
249 				       IWL_MAX_TID_COUNT, NULL);
250 }
251 
252 int iwl_mvm_mld_add_aux_sta(struct iwl_mvm *mvm, u32 lmac_id)
253 {
254 	lockdep_assert_held(&mvm->mutex);
255 
256 	/* In CDB NICs we need to specify which lmac to use for aux activity;
257 	 * use the link_id argument place to send lmac_id to the function.
258 	 */
259 	return iwl_mvm_mld_add_int_sta(mvm, &mvm->aux_sta, &mvm->aux_queue,
260 				       NL80211_IFTYPE_UNSPECIFIED,
261 				       STATION_TYPE_AUX, lmac_id, NULL,
262 				       IWL_MAX_TID_COUNT, NULL);
263 }
264 
265 static int iwl_mvm_mld_disable_txq(struct iwl_mvm *mvm, int sta_id,
266 				   u16 *queueptr, u8 tid)
267 {
268 	int queue = *queueptr;
269 	int ret = 0;
270 
271 	if (mvm->sta_remove_requires_queue_remove) {
272 		u32 cmd_id = WIDE_ID(DATA_PATH_GROUP,
273 				     SCD_QUEUE_CONFIG_CMD);
274 		struct iwl_scd_queue_cfg_cmd remove_cmd = {
275 			.operation = cpu_to_le32(IWL_SCD_QUEUE_REMOVE),
276 			.u.remove.tid = cpu_to_le32(tid),
277 			.u.remove.sta_mask = cpu_to_le32(BIT(sta_id)),
278 		};
279 
280 		ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0,
281 					   sizeof(remove_cmd),
282 					   &remove_cmd);
283 	}
284 
285 	iwl_trans_txq_free(mvm->trans, queue);
286 	*queueptr = IWL_MVM_INVALID_QUEUE;
287 
288 	return ret;
289 }
290 
291 /* Removes a sta from the FW table, disable its queues, and dealloc it
292  */
293 static int iwl_mvm_mld_rm_int_sta(struct iwl_mvm *mvm,
294 				  struct iwl_mvm_int_sta *int_sta,
295 				  bool flush, u8 tid, u16 *queuptr)
296 {
297 	int ret;
298 
299 	lockdep_assert_held(&mvm->mutex);
300 
301 	if (WARN_ON_ONCE(int_sta->sta_id == IWL_MVM_INVALID_STA))
302 		return -EINVAL;
303 
304 	if (flush)
305 		iwl_mvm_flush_sta(mvm, int_sta, true);
306 
307 	iwl_mvm_mld_disable_txq(mvm, int_sta->sta_id, queuptr, tid);
308 
309 	ret = iwl_mvm_mld_rm_sta_from_fw(mvm, int_sta->sta_id);
310 	if (ret)
311 		IWL_WARN(mvm, "Failed sending remove station\n");
312 
313 	iwl_mvm_dealloc_int_sta(mvm, int_sta);
314 
315 	return ret;
316 }
317 
318 int iwl_mvm_mld_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
319 			     struct ieee80211_bss_conf *link_conf)
320 {
321 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
322 	struct iwl_mvm_vif_link_info *link = mvmvif->link[link_conf->link_id];
323 	u16 *queueptr;
324 
325 	lockdep_assert_held(&mvm->mutex);
326 
327 	switch (vif->type) {
328 	case NL80211_IFTYPE_AP:
329 	case NL80211_IFTYPE_ADHOC:
330 		queueptr = &link->mgmt_queue;
331 		break;
332 	case NL80211_IFTYPE_P2P_DEVICE:
333 		queueptr = &mvm->p2p_dev_queue;
334 		break;
335 	default:
336 		WARN(1, "Can't free bcast queue on vif type %d\n",
337 		     vif->type);
338 		return -EINVAL;
339 	}
340 
341 	return iwl_mvm_mld_rm_int_sta(mvm, &link->bcast_sta,
342 				      true, IWL_MAX_TID_COUNT, queueptr);
343 }
344 
345 /* Send the FW a request to remove the station from it's internal data
346  * structures, and in addition remove it from the local data structure.
347  */
348 int iwl_mvm_mld_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
349 			     struct ieee80211_bss_conf *link_conf)
350 {
351 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
352 	struct iwl_mvm_vif_link_info *link = mvmvif->link[link_conf->link_id];
353 
354 	lockdep_assert_held(&mvm->mutex);
355 
356 	return iwl_mvm_mld_rm_int_sta(mvm, &link->mcast_sta, true, 0,
357 				      &link->cab_queue);
358 }
359 
360 int iwl_mvm_mld_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
361 {
362 	lockdep_assert_held(&mvm->mutex);
363 
364 	return iwl_mvm_mld_rm_int_sta(mvm, &mvm->snif_sta, false,
365 				      IWL_MAX_TID_COUNT, &mvm->snif_queue);
366 }
367 
368 int iwl_mvm_mld_rm_aux_sta(struct iwl_mvm *mvm)
369 {
370 	lockdep_assert_held(&mvm->mutex);
371 
372 	return iwl_mvm_mld_rm_int_sta(mvm, &mvm->aux_sta, false,
373 				      IWL_MAX_TID_COUNT, &mvm->aux_queue);
374 }
375 
376 /* send a cfg sta command to add/update a sta in firmware */
377 static int iwl_mvm_mld_cfg_sta(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
378 			       struct ieee80211_vif *vif,
379 			       struct ieee80211_link_sta *link_sta,
380 			       struct ieee80211_bss_conf *link_conf,
381 			       struct iwl_mvm_link_sta *mvm_link_sta)
382 {
383 	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
384 	struct iwl_mvm_vif *mvm_vif = iwl_mvm_vif_from_mac80211(vif);
385 	struct iwl_mvm_vif_link_info *link_info =
386 					mvm_vif->link[link_conf->link_id];
387 	struct iwl_mvm_sta_cfg_cmd cmd = {
388 		.sta_id = cpu_to_le32(mvm_link_sta->sta_id),
389 		.station_type = cpu_to_le32(mvm_sta->sta_type),
390 		.mfp = cpu_to_le32(sta->mfp),
391 	};
392 	u32 agg_size = 0, mpdu_dens = 0;
393 
394 	/* when adding sta, link should exist in FW */
395 	if (WARN_ON(link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID))
396 		return -EINVAL;
397 
398 	cmd.link_id = cpu_to_le32(link_info->fw_link_id);
399 
400 	memcpy(&cmd.peer_mld_address, sta->addr, ETH_ALEN);
401 	memcpy(&cmd.peer_link_address, link_sta->addr, ETH_ALEN);
402 
403 	if (mvm_sta->sta_state >= IEEE80211_STA_ASSOC)
404 		cmd.assoc_id = cpu_to_le32(sta->aid);
405 
406 	switch (link_sta->rx_nss) {
407 	case 1:
408 		cmd.mimo = cpu_to_le32(0);
409 		break;
410 	case 2 ... 8:
411 		cmd.mimo = cpu_to_le32(1);
412 		break;
413 	}
414 
415 	switch (sta->deflink.smps_mode) {
416 	case IEEE80211_SMPS_AUTOMATIC:
417 	case IEEE80211_SMPS_NUM_MODES:
418 		WARN_ON(1);
419 		break;
420 	case IEEE80211_SMPS_STATIC:
421 		/* override NSS */
422 		cmd.mimo = cpu_to_le32(0);
423 		break;
424 	case IEEE80211_SMPS_DYNAMIC:
425 		cmd.mimo_protection = cpu_to_le32(1);
426 		break;
427 	case IEEE80211_SMPS_OFF:
428 		/* nothing */
429 		break;
430 	}
431 
432 	mpdu_dens = iwl_mvm_get_sta_ampdu_dens(link_sta, link_conf, &agg_size);
433 	cmd.tx_ampdu_spacing = cpu_to_le32(mpdu_dens);
434 	cmd.tx_ampdu_max_size = cpu_to_le32(agg_size);
435 
436 	if (sta->wme) {
437 		cmd.sp_length =
438 			cpu_to_le32(sta->max_sp ? sta->max_sp * 2 : 128);
439 		cmd.uapsd_acs = cpu_to_le32(iwl_mvm_get_sta_uapsd_acs(sta));
440 	}
441 
442 	if (link_sta->he_cap.has_he) {
443 		cmd.trig_rnd_alloc =
444 			cpu_to_le32(link_conf->uora_exists ? 1 : 0);
445 
446 		/* PPE Thresholds */
447 		iwl_mvm_set_sta_pkt_ext(mvm, link_sta, &cmd.pkt_ext);
448 
449 		/* HTC flags */
450 		cmd.htc_flags = iwl_mvm_get_sta_htc_flags(sta, link_sta);
451 
452 		if (link_sta->he_cap.he_cap_elem.mac_cap_info[2] &
453 		    IEEE80211_HE_MAC_CAP2_ACK_EN)
454 			cmd.ack_enabled = cpu_to_le32(1);
455 	}
456 
457 	return iwl_mvm_mld_send_sta_cmd(mvm, &cmd);
458 }
459 
460 static void iwl_mvm_mld_free_sta_link(struct iwl_mvm *mvm,
461 				      struct iwl_mvm_sta *mvm_sta,
462 				      struct iwl_mvm_link_sta *mvm_sta_link,
463 				      unsigned int link_id,
464 				      bool is_in_fw)
465 {
466 	RCU_INIT_POINTER(mvm->fw_id_to_mac_id[mvm_sta_link->sta_id],
467 			 is_in_fw ? ERR_PTR(-EINVAL) : NULL);
468 	RCU_INIT_POINTER(mvm->fw_id_to_link_sta[mvm_sta_link->sta_id], NULL);
469 	RCU_INIT_POINTER(mvm_sta->link[link_id], NULL);
470 
471 	if (mvm_sta_link != &mvm_sta->deflink)
472 		kfree_rcu(mvm_sta_link, rcu_head);
473 }
474 
475 static void iwl_mvm_mld_sta_rm_all_sta_links(struct iwl_mvm *mvm,
476 					     struct iwl_mvm_sta *mvm_sta)
477 {
478 	unsigned int link_id;
479 
480 	for (link_id = 0; link_id < ARRAY_SIZE(mvm_sta->link); link_id++) {
481 		struct iwl_mvm_link_sta *link =
482 			rcu_dereference_protected(mvm_sta->link[link_id],
483 						  lockdep_is_held(&mvm->mutex));
484 
485 		if (!link)
486 			continue;
487 
488 		iwl_mvm_mld_free_sta_link(mvm, mvm_sta, link, link_id, false);
489 	}
490 }
491 
492 static int iwl_mvm_mld_alloc_sta_link(struct iwl_mvm *mvm,
493 				      struct ieee80211_vif *vif,
494 				      struct ieee80211_sta *sta,
495 				      unsigned int link_id)
496 {
497 	struct ieee80211_link_sta *link_sta =
498 		link_sta_dereference_protected(sta, link_id);
499 	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
500 	struct iwl_mvm_link_sta *link;
501 	u32 sta_id = iwl_mvm_find_free_sta_id(mvm,
502 					  ieee80211_vif_type_p2p(vif));
503 
504 	if (sta_id == IWL_MVM_INVALID_STA)
505 		return -ENOSPC;
506 
507 	if (rcu_access_pointer(sta->link[link_id]) == &sta->deflink) {
508 		link = &mvm_sta->deflink;
509 	} else {
510 		link = kzalloc(sizeof(*link), GFP_KERNEL);
511 		if (!link)
512 			return -ENOMEM;
513 	}
514 
515 	link->sta_id = sta_id;
516 	rcu_assign_pointer(mvm_sta->link[link_id], link);
517 	rcu_assign_pointer(mvm->fw_id_to_mac_id[link->sta_id], sta);
518 	rcu_assign_pointer(mvm->fw_id_to_link_sta[link->sta_id],
519 			   link_sta);
520 
521 	return 0;
522 }
523 
524 /* allocate all the links of a sta, called when the station is first added */
525 static int iwl_mvm_mld_alloc_sta_links(struct iwl_mvm *mvm,
526 				       struct ieee80211_vif *vif,
527 				       struct ieee80211_sta *sta)
528 {
529 	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
530 	unsigned int link_id;
531 	int ret;
532 
533 	lockdep_assert_held(&mvm->mutex);
534 
535 	for (link_id = 0; link_id < ARRAY_SIZE(sta->link); link_id++) {
536 		if (!rcu_access_pointer(sta->link[link_id]) ||
537 		    mvm_sta->link[link_id])
538 			continue;
539 
540 		ret = iwl_mvm_mld_alloc_sta_link(mvm, vif, sta, link_id);
541 		if (ret)
542 			goto err;
543 	}
544 
545 	return 0;
546 
547 err:
548 	iwl_mvm_mld_sta_rm_all_sta_links(mvm, mvm_sta);
549 	return ret;
550 }
551 
552 static void iwl_mvm_mld_set_ap_sta_id(struct ieee80211_sta *sta,
553 				      struct iwl_mvm_vif_link_info *vif_link,
554 				      struct iwl_mvm_link_sta *sta_link)
555 {
556 	if (!sta->tdls) {
557 		WARN_ON(vif_link->ap_sta_id != IWL_MVM_INVALID_STA);
558 		vif_link->ap_sta_id = sta_link->sta_id;
559 	} else {
560 		WARN_ON(vif_link->ap_sta_id == IWL_MVM_INVALID_STA);
561 	}
562 }
563 
564 /* FIXME: consider waiting for mac80211 to add the STA instead of allocating
565  * queues here
566  */
567 static int iwl_mvm_alloc_sta_after_restart(struct iwl_mvm *mvm,
568 					   struct ieee80211_vif *vif,
569 					   struct ieee80211_sta *sta)
570 {
571 	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
572 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
573 	struct ieee80211_link_sta *link_sta;
574 	unsigned int link_id;
575 	/* no active link found */
576 	int ret = -EINVAL;
577 	int sta_id;
578 
579 	/* First add an empty station since allocating a queue requires
580 	 * a valid station. Since we need a link_id to allocate a station,
581 	 * pick up the first valid one.
582 	 */
583 	for_each_sta_active_link(vif, sta, link_sta, link_id) {
584 		struct iwl_mvm_vif_link_info *mvm_link;
585 		struct ieee80211_bss_conf *link_conf =
586 			link_conf_dereference_protected(vif, link_id);
587 		struct iwl_mvm_link_sta *mvm_link_sta =
588 			rcu_dereference_protected(mvm_sta->link[link_id],
589 						  lockdep_is_held(&mvm->mutex));
590 
591 		if (!link_conf)
592 			continue;
593 
594 		mvm_link = mvmvif->link[link_conf->link_id];
595 
596 		if (!mvm_link || !mvm_link_sta)
597 			continue;
598 
599 		sta_id = mvm_link_sta->sta_id;
600 		ret = iwl_mvm_mld_cfg_sta(mvm, sta, vif, link_sta,
601 					  link_conf, mvm_link_sta);
602 		if (ret)
603 			return ret;
604 
605 		rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta);
606 		rcu_assign_pointer(mvm->fw_id_to_link_sta[sta_id], link_sta);
607 		ret = 0;
608 	}
609 
610 	iwl_mvm_realloc_queues_after_restart(mvm, sta);
611 
612 	return ret;
613 }
614 
615 int iwl_mvm_mld_add_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
616 			struct ieee80211_sta *sta)
617 {
618 	struct iwl_mvm_vif *mvm_vif = iwl_mvm_vif_from_mac80211(vif);
619 	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
620 	unsigned long link_sta_added_to_fw = 0;
621 	struct ieee80211_link_sta *link_sta;
622 	int ret = 0;
623 	unsigned int link_id;
624 
625 	lockdep_assert_held(&mvm->mutex);
626 
627 	if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
628 		ret = iwl_mvm_mld_alloc_sta_links(mvm, vif, sta);
629 		if (ret)
630 			return ret;
631 	}
632 
633 	spin_lock_init(&mvm_sta->lock);
634 
635 	if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
636 		ret = iwl_mvm_alloc_sta_after_restart(mvm, vif, sta);
637 	else
638 		ret = iwl_mvm_sta_init(mvm, vif, sta, IWL_MVM_INVALID_STA,
639 				       STATION_TYPE_PEER);
640 	if (ret)
641 		goto err;
642 
643 	/* at this stage sta link pointers are already allocated */
644 	ret = iwl_mvm_mld_update_sta(mvm, vif, sta);
645 
646 	for_each_sta_active_link(vif, sta, link_sta, link_id) {
647 		struct ieee80211_bss_conf *link_conf =
648 			link_conf_dereference_protected(vif, link_id);
649 		struct iwl_mvm_link_sta *mvm_link_sta =
650 			rcu_dereference_protected(mvm_sta->link[link_id],
651 						  lockdep_is_held(&mvm->mutex));
652 
653 		if (WARN_ON(!link_conf || !mvm_link_sta))
654 			goto err;
655 
656 		ret = iwl_mvm_mld_cfg_sta(mvm, sta, vif, link_sta, link_conf,
657 					  mvm_link_sta);
658 		if (ret)
659 			goto err;
660 
661 		link_sta_added_to_fw |= BIT(link_id);
662 
663 		if (vif->type == NL80211_IFTYPE_STATION)
664 			iwl_mvm_mld_set_ap_sta_id(sta, mvm_vif->link[link_id],
665 						  mvm_link_sta);
666 	}
667 
668 	return 0;
669 
670 err:
671 	/* remove all already allocated stations in FW */
672 	for_each_set_bit(link_id, &link_sta_added_to_fw,
673 			 IEEE80211_MLD_MAX_NUM_LINKS) {
674 		struct iwl_mvm_link_sta *mvm_link_sta =
675 			rcu_dereference_protected(mvm_sta->link[link_id],
676 						  lockdep_is_held(&mvm->mutex));
677 
678 		iwl_mvm_mld_rm_sta_from_fw(mvm, mvm_link_sta->sta_id);
679 	}
680 
681 	/* free all sta resources in the driver */
682 	iwl_mvm_mld_sta_rm_all_sta_links(mvm, mvm_sta);
683 	return ret;
684 }
685 
686 int iwl_mvm_mld_update_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
687 			   struct ieee80211_sta *sta)
688 {
689 	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
690 	struct ieee80211_link_sta *link_sta;
691 	unsigned int link_id;
692 	int ret = 0;
693 
694 	lockdep_assert_held(&mvm->mutex);
695 
696 	for_each_sta_active_link(vif, sta, link_sta, link_id) {
697 		struct ieee80211_bss_conf *link_conf =
698 			link_conf_dereference_protected(vif, link_id);
699 		struct iwl_mvm_link_sta *mvm_link_sta =
700 			rcu_dereference_protected(mvm_sta->link[link_id],
701 						  lockdep_is_held(&mvm->mutex));
702 
703 		if (WARN_ON(!link_conf || !mvm_link_sta))
704 			return -EINVAL;
705 
706 		ret = iwl_mvm_mld_cfg_sta(mvm, sta, vif, link_sta, link_conf,
707 					  mvm_link_sta);
708 
709 		if (ret) {
710 			IWL_ERR(mvm, "Failed to update sta link %d\n", link_id);
711 			break;
712 		}
713 	}
714 
715 	return ret;
716 }
717 
718 static void iwl_mvm_mld_disable_sta_queues(struct iwl_mvm *mvm,
719 					   struct ieee80211_vif *vif,
720 					   struct ieee80211_sta *sta)
721 {
722 	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
723 	int i;
724 
725 	lockdep_assert_held(&mvm->mutex);
726 
727 	for (i = 0; i < ARRAY_SIZE(mvm_sta->tid_data); i++) {
728 		if (mvm_sta->tid_data[i].txq_id == IWL_MVM_INVALID_QUEUE)
729 			continue;
730 
731 		iwl_mvm_mld_disable_txq(mvm, mvm_sta->deflink.sta_id,
732 					&mvm_sta->tid_data[i].txq_id, i);
733 		mvm_sta->tid_data[i].txq_id = IWL_MVM_INVALID_QUEUE;
734 	}
735 
736 	for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
737 		struct iwl_mvm_txq *mvmtxq =
738 			iwl_mvm_txq_from_mac80211(sta->txq[i]);
739 
740 		mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;
741 	}
742 }
743 
744 int iwl_mvm_mld_rm_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
745 		       struct ieee80211_sta *sta)
746 {
747 	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
748 	struct ieee80211_link_sta *link_sta;
749 	unsigned int link_id;
750 	int ret;
751 
752 	lockdep_assert_held(&mvm->mutex);
753 
754 	kfree(mvm_sta->dup_data);
755 
756 	/* flush its queues here since we are freeing mvm_sta */
757 	for_each_sta_active_link(vif, sta, link_sta, link_id) {
758 		struct iwl_mvm_link_sta *mvm_link_sta =
759 			rcu_dereference_protected(mvm_sta->link[link_id],
760 						  lockdep_is_held(&mvm->mutex));
761 
762 		if (WARN_ON(!mvm_link_sta))
763 			return -EINVAL;
764 
765 		ret = iwl_mvm_flush_sta_tids(mvm, mvm_link_sta->sta_id,
766 					     0xffff);
767 		if (ret)
768 			return ret;
769 	}
770 
771 	ret = iwl_mvm_wait_sta_queues_empty(mvm, mvm_sta);
772 	if (ret)
773 		return ret;
774 
775 	iwl_mvm_mld_disable_sta_queues(mvm, vif, sta);
776 
777 	for_each_sta_active_link(vif, sta, link_sta, link_id) {
778 		struct iwl_mvm_link_sta *mvm_link_sta =
779 			rcu_dereference_protected(mvm_sta->link[link_id],
780 						  lockdep_is_held(&mvm->mutex));
781 		bool stay_in_fw;
782 
783 		stay_in_fw = iwl_mvm_sta_del(mvm, vif, sta, link_sta, &ret);
784 		if (ret)
785 			break;
786 
787 		if (!stay_in_fw)
788 			ret = iwl_mvm_mld_rm_sta_from_fw(mvm,
789 							 mvm_link_sta->sta_id);
790 
791 		iwl_mvm_mld_free_sta_link(mvm, mvm_sta, mvm_link_sta,
792 					  link_id, stay_in_fw);
793 	}
794 
795 	return ret;
796 }
797 
798 int iwl_mvm_mld_rm_sta_id(struct iwl_mvm *mvm, u8 sta_id)
799 {
800 	int ret = iwl_mvm_mld_rm_sta_from_fw(mvm, sta_id);
801 
802 	lockdep_assert_held(&mvm->mutex);
803 
804 	RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta_id], NULL);
805 	RCU_INIT_POINTER(mvm->fw_id_to_link_sta[sta_id], NULL);
806 	return ret;
807 }
808 
809 void iwl_mvm_mld_sta_modify_disable_tx(struct iwl_mvm *mvm,
810 				       struct iwl_mvm_sta *mvmsta,
811 				       bool disable)
812 {
813 	struct iwl_mvm_sta_disable_tx_cmd cmd;
814 	int ret;
815 
816 	cmd.sta_id = cpu_to_le32(mvmsta->deflink.sta_id);
817 	cmd.disable = cpu_to_le32(disable);
818 
819 	ret = iwl_mvm_send_cmd_pdu(mvm,
820 				   WIDE_ID(MAC_CONF_GROUP, STA_DISABLE_TX_CMD),
821 				   CMD_ASYNC, sizeof(cmd), &cmd);
822 	if (ret)
823 		IWL_ERR(mvm,
824 			"Failed to send STA_DISABLE_TX_CMD command (%d)\n",
825 			ret);
826 }
827 
828 void iwl_mvm_mld_sta_modify_disable_tx_ap(struct iwl_mvm *mvm,
829 					  struct ieee80211_sta *sta,
830 					  bool disable)
831 {
832 	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
833 
834 	spin_lock_bh(&mvm_sta->lock);
835 
836 	if (mvm_sta->disable_tx == disable) {
837 		spin_unlock_bh(&mvm_sta->lock);
838 		return;
839 	}
840 
841 	iwl_mvm_mld_sta_modify_disable_tx(mvm, mvm_sta, disable);
842 
843 	spin_unlock_bh(&mvm_sta->lock);
844 }
845 
846 void iwl_mvm_mld_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
847 					   struct iwl_mvm_vif *mvmvif,
848 					   bool disable)
849 {
850 	struct ieee80211_sta *sta;
851 	struct iwl_mvm_sta *mvm_sta;
852 	int i;
853 
854 	rcu_read_lock();
855 
856 	/* Block/unblock all the stations of the given mvmvif */
857 	for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
858 		sta = rcu_dereference(mvm->fw_id_to_mac_id[i]);
859 		if (IS_ERR_OR_NULL(sta))
860 			continue;
861 
862 		mvm_sta = iwl_mvm_sta_from_mac80211(sta);
863 		if (mvm_sta->mac_id_n_color !=
864 		    FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color))
865 			continue;
866 
867 		iwl_mvm_mld_sta_modify_disable_tx(mvm, mvm_sta, disable);
868 	}
869 
870 	rcu_read_unlock();
871 }
872 
873 static int iwl_mvm_mld_update_sta_queue(struct iwl_mvm *mvm,
874 					struct iwl_mvm_sta *mvm_sta,
875 					u32 old_sta_mask,
876 					u32 new_sta_mask)
877 {
878 	struct iwl_scd_queue_cfg_cmd cmd = {
879 		.operation = cpu_to_le32(IWL_SCD_QUEUE_MODIFY),
880 		.u.modify.old_sta_mask = cpu_to_le32(old_sta_mask),
881 		.u.modify.new_sta_mask = cpu_to_le32(new_sta_mask),
882 	};
883 	struct iwl_host_cmd hcmd = {
884 		.id = WIDE_ID(DATA_PATH_GROUP, SCD_QUEUE_CONFIG_CMD),
885 		.len[0] = sizeof(cmd),
886 		.data[0] = &cmd
887 	};
888 	int tid;
889 	int ret;
890 
891 	lockdep_assert_held(&mvm->mutex);
892 
893 	for (tid = 0; tid <= IWL_MAX_TID_COUNT; tid++) {
894 		struct iwl_mvm_tid_data *tid_data = &mvm_sta->tid_data[tid];
895 		int txq_id = tid_data->txq_id;
896 
897 		if (txq_id == IWL_MVM_INVALID_QUEUE)
898 			continue;
899 
900 		if (tid == IWL_MAX_TID_COUNT)
901 			cmd.u.modify.tid = cpu_to_le32(IWL_MGMT_TID);
902 		else
903 			cmd.u.modify.tid = cpu_to_le32(tid);
904 
905 		ret = iwl_mvm_send_cmd(mvm, &hcmd);
906 		if (ret)
907 			return ret;
908 	}
909 
910 	return 0;
911 }
912 
913 int iwl_mvm_mld_update_sta_links(struct iwl_mvm *mvm,
914 				 struct ieee80211_vif *vif,
915 				 struct ieee80211_sta *sta,
916 				 u16 old_links, u16 new_links)
917 {
918 	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
919 	struct iwl_mvm_vif *mvm_vif = iwl_mvm_vif_from_mac80211(vif);
920 	struct iwl_mvm_link_sta *mvm_sta_link;
921 	struct iwl_mvm_vif_link_info *mvm_vif_link;
922 	unsigned long links_to_add = ~old_links & new_links;
923 	unsigned long links_to_rem = old_links & ~new_links;
924 	unsigned long old_links_long = old_links;
925 	u32 current_sta_mask = 0, sta_mask_added = 0, sta_mask_to_rem = 0;
926 	unsigned long link_sta_added_to_fw = 0, link_sta_allocated = 0;
927 	unsigned int link_id;
928 	int ret;
929 
930 	lockdep_assert_held(&mvm->mutex);
931 
932 	for_each_set_bit(link_id, &old_links_long,
933 			 IEEE80211_MLD_MAX_NUM_LINKS) {
934 		mvm_sta_link =
935 			rcu_dereference_protected(mvm_sta->link[link_id],
936 						  lockdep_is_held(&mvm->mutex));
937 
938 		if (WARN_ON(!mvm_sta_link)) {
939 			ret = -EINVAL;
940 			goto err;
941 		}
942 
943 		current_sta_mask |= BIT(mvm_sta_link->sta_id);
944 		if (links_to_rem & BIT(link_id))
945 			sta_mask_to_rem |= BIT(mvm_sta_link->sta_id);
946 	}
947 
948 	if (sta_mask_to_rem) {
949 		ret = iwl_mvm_mld_update_sta_queue(mvm, mvm_sta,
950 						   current_sta_mask,
951 						   current_sta_mask & ~sta_mask_to_rem);
952 		if (WARN_ON(ret))
953 			goto err;
954 
955 		current_sta_mask &= ~sta_mask_to_rem;
956 	}
957 
958 	for_each_set_bit(link_id, &links_to_rem, IEEE80211_MLD_MAX_NUM_LINKS) {
959 		mvm_sta_link =
960 			rcu_dereference_protected(mvm_sta->link[link_id],
961 						  lockdep_is_held(&mvm->mutex));
962 		mvm_vif_link = mvm_vif->link[link_id];
963 
964 		if (WARN_ON(!mvm_sta_link || !mvm_vif_link)) {
965 			ret = -EINVAL;
966 			goto err;
967 		}
968 
969 		ret = iwl_mvm_mld_rm_sta_from_fw(mvm, mvm_sta_link->sta_id);
970 		if (WARN_ON(ret))
971 			goto err;
972 
973 		if (vif->type == NL80211_IFTYPE_STATION)
974 			mvm_vif_link->ap_sta_id = IWL_MVM_INVALID_STA;
975 
976 		iwl_mvm_mld_free_sta_link(mvm, mvm_sta, mvm_sta_link, link_id,
977 					  false);
978 	}
979 
980 	for_each_set_bit(link_id, &links_to_add, IEEE80211_MLD_MAX_NUM_LINKS) {
981 		struct ieee80211_bss_conf *link_conf =
982 			link_conf_dereference_protected(vif, link_id);
983 		struct ieee80211_link_sta *link_sta =
984 			link_sta_dereference_protected(sta, link_id);
985 		mvm_vif_link = mvm_vif->link[link_id];
986 
987 		if (WARN_ON(!mvm_vif_link || !link_conf || !link_sta ||
988 			    mvm_sta->link[link_id])) {
989 			ret = -EINVAL;
990 			goto err;
991 		}
992 
993 		ret = iwl_mvm_mld_alloc_sta_link(mvm, vif, sta, link_id);
994 		if (WARN_ON(ret))
995 			goto err;
996 
997 		link_sta->agg.max_rc_amsdu_len = 1;
998 		ieee80211_sta_recalc_aggregates(sta);
999 
1000 		mvm_sta_link =
1001 			rcu_dereference_protected(mvm_sta->link[link_id],
1002 						  lockdep_is_held(&mvm->mutex));
1003 
1004 		if (WARN_ON(!mvm_sta_link)) {
1005 			ret = -EINVAL;
1006 			goto err;
1007 		}
1008 
1009 		if (vif->type == NL80211_IFTYPE_STATION)
1010 			iwl_mvm_mld_set_ap_sta_id(sta, mvm_vif_link,
1011 						  mvm_sta_link);
1012 
1013 		link_sta_allocated |= BIT(link_id);
1014 
1015 		sta_mask_added |= BIT(mvm_sta_link->sta_id);
1016 
1017 		ret = iwl_mvm_mld_cfg_sta(mvm, sta, vif, link_sta, link_conf,
1018 					  mvm_sta_link);
1019 		if (WARN_ON(ret))
1020 			goto err;
1021 
1022 		link_sta_added_to_fw |= BIT(link_id);
1023 	}
1024 
1025 	if (sta_mask_added) {
1026 		ret = iwl_mvm_mld_update_sta_queue(mvm, mvm_sta,
1027 						   current_sta_mask,
1028 						   current_sta_mask | sta_mask_added);
1029 		if (WARN_ON(ret))
1030 			goto err;
1031 	}
1032 
1033 	return 0;
1034 
1035 err:
1036 	/* remove all already allocated stations in FW */
1037 	for_each_set_bit(link_id, &link_sta_added_to_fw,
1038 			 IEEE80211_MLD_MAX_NUM_LINKS) {
1039 		mvm_sta_link =
1040 			rcu_dereference_protected(mvm_sta->link[link_id],
1041 						  lockdep_is_held(&mvm->mutex));
1042 
1043 		iwl_mvm_mld_rm_sta_from_fw(mvm, mvm_sta_link->sta_id);
1044 	}
1045 
1046 	/* remove all already allocated station links in driver */
1047 	for_each_set_bit(link_id, &link_sta_allocated,
1048 			 IEEE80211_MLD_MAX_NUM_LINKS) {
1049 		mvm_sta_link =
1050 			rcu_dereference_protected(mvm_sta->link[link_id],
1051 						  lockdep_is_held(&mvm->mutex));
1052 
1053 		iwl_mvm_mld_free_sta_link(mvm, mvm_sta, mvm_sta_link, link_id,
1054 					  false);
1055 	}
1056 
1057 	return ret;
1058 }
1059