xref: /linux/drivers/net/wireless/realtek/rtw89/chan.c (revision 0ad9617c78acbc71373fb341a6f75d4012b01d69)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2020-2022  Realtek Corporation
3  */
4 
5 #include "chan.h"
6 #include "coex.h"
7 #include "debug.h"
8 #include "fw.h"
9 #include "mac.h"
10 #include "ps.h"
11 #include "util.h"
12 
13 static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
14 			       enum rtw89_chanctx_idx idx1,
15 			       enum rtw89_chanctx_idx idx2);
16 
17 static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
18 						 u8 center_chan)
19 {
20 	switch (band) {
21 	default:
22 	case RTW89_BAND_2G:
23 		switch (center_chan) {
24 		default:
25 		case 1 ... 14:
26 			return RTW89_CH_2G;
27 		}
28 	case RTW89_BAND_5G:
29 		switch (center_chan) {
30 		default:
31 		case 36 ... 64:
32 			return RTW89_CH_5G_BAND_1;
33 		case 100 ... 144:
34 			return RTW89_CH_5G_BAND_3;
35 		case 149 ... 177:
36 			return RTW89_CH_5G_BAND_4;
37 		}
38 	case RTW89_BAND_6G:
39 		switch (center_chan) {
40 		default:
41 		case 1 ... 29:
42 			return RTW89_CH_6G_BAND_IDX0;
43 		case 33 ... 61:
44 			return RTW89_CH_6G_BAND_IDX1;
45 		case 65 ... 93:
46 			return RTW89_CH_6G_BAND_IDX2;
47 		case 97 ... 125:
48 			return RTW89_CH_6G_BAND_IDX3;
49 		case 129 ... 157:
50 			return RTW89_CH_6G_BAND_IDX4;
51 		case 161 ... 189:
52 			return RTW89_CH_6G_BAND_IDX5;
53 		case 193 ... 221:
54 			return RTW89_CH_6G_BAND_IDX6;
55 		case 225 ... 253:
56 			return RTW89_CH_6G_BAND_IDX7;
57 		}
58 	}
59 }
60 
61 static enum rtw89_sc_offset rtw89_get_primary_chan_idx(enum rtw89_bandwidth bw,
62 						       u32 center_freq,
63 						       u32 primary_freq)
64 {
65 	u8 primary_chan_idx;
66 	u32 offset;
67 
68 	switch (bw) {
69 	default:
70 	case RTW89_CHANNEL_WIDTH_20:
71 		primary_chan_idx = RTW89_SC_DONT_CARE;
72 		break;
73 	case RTW89_CHANNEL_WIDTH_40:
74 		if (primary_freq > center_freq)
75 			primary_chan_idx = RTW89_SC_20_UPPER;
76 		else
77 			primary_chan_idx = RTW89_SC_20_LOWER;
78 		break;
79 	case RTW89_CHANNEL_WIDTH_80:
80 	case RTW89_CHANNEL_WIDTH_160:
81 		if (primary_freq > center_freq) {
82 			offset = (primary_freq - center_freq - 10) / 20;
83 			primary_chan_idx = RTW89_SC_20_UPPER + offset * 2;
84 		} else {
85 			offset = (center_freq - primary_freq - 10) / 20;
86 			primary_chan_idx = RTW89_SC_20_LOWER + offset * 2;
87 		}
88 		break;
89 	}
90 
91 	return primary_chan_idx;
92 }
93 
94 static u8 rtw89_get_primary_sb_idx(u8 central_ch, u8 pri_ch,
95 				   enum rtw89_bandwidth bw)
96 {
97 	static const u8 prisb_cal_ofst[RTW89_CHANNEL_WIDTH_ORDINARY_NUM] = {
98 		0, 2, 6, 14, 30
99 	};
100 
101 	if (bw >= RTW89_CHANNEL_WIDTH_ORDINARY_NUM)
102 		return 0;
103 
104 	return (prisb_cal_ofst[bw] + pri_ch - central_ch) / 4;
105 }
106 
107 void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan,
108 		       enum rtw89_band band, enum rtw89_bandwidth bandwidth)
109 {
110 	enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
111 	u32 center_freq, primary_freq;
112 
113 	memset(chan, 0, sizeof(*chan));
114 	chan->channel = center_chan;
115 	chan->primary_channel = primary_chan;
116 	chan->band_type = band;
117 	chan->band_width = bandwidth;
118 
119 	center_freq = ieee80211_channel_to_frequency(center_chan, nl_band);
120 	primary_freq = ieee80211_channel_to_frequency(primary_chan, nl_band);
121 
122 	chan->freq = center_freq;
123 	chan->subband_type = rtw89_get_subband_type(band, center_chan);
124 	chan->pri_ch_idx = rtw89_get_primary_chan_idx(bandwidth, center_freq,
125 						      primary_freq);
126 	chan->pri_sb_idx = rtw89_get_primary_sb_idx(center_chan, primary_chan,
127 						    bandwidth);
128 }
129 
130 bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
131 			      enum rtw89_chanctx_idx idx,
132 			      const struct rtw89_chan *new)
133 {
134 	struct rtw89_hal *hal = &rtwdev->hal;
135 	struct rtw89_chan *chan = &hal->chanctx[idx].chan;
136 	struct rtw89_chan_rcd *rcd = &hal->chanctx[idx].rcd;
137 	bool band_changed;
138 
139 	rcd->prev_primary_channel = chan->primary_channel;
140 	rcd->prev_band_type = chan->band_type;
141 	band_changed = new->band_type != chan->band_type;
142 	rcd->band_changed = band_changed;
143 
144 	*chan = *new;
145 	return band_changed;
146 }
147 
148 int rtw89_iterate_entity_chan(struct rtw89_dev *rtwdev,
149 			      int (*iterator)(const struct rtw89_chan *chan,
150 					      void *data),
151 			      void *data)
152 {
153 	struct rtw89_hal *hal = &rtwdev->hal;
154 	const struct rtw89_chan *chan;
155 	int ret;
156 	u8 idx;
157 
158 	lockdep_assert_held(&rtwdev->mutex);
159 
160 	for_each_set_bit(idx,  hal->entity_map, NUM_OF_RTW89_CHANCTX) {
161 		chan = rtw89_chan_get(rtwdev, idx);
162 		ret = iterator(chan, data);
163 		if (ret)
164 			return ret;
165 	}
166 
167 	return 0;
168 }
169 
170 static void __rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
171 					  enum rtw89_chanctx_idx idx,
172 					  const struct cfg80211_chan_def *chandef,
173 					  bool from_stack)
174 {
175 	struct rtw89_hal *hal = &rtwdev->hal;
176 
177 	hal->chanctx[idx].chandef = *chandef;
178 
179 	if (from_stack)
180 		set_bit(idx, hal->entity_map);
181 }
182 
183 void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
184 				 enum rtw89_chanctx_idx idx,
185 				 const struct cfg80211_chan_def *chandef)
186 {
187 	__rtw89_config_entity_chandef(rtwdev, idx, chandef, true);
188 }
189 
190 void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
191 			      enum rtw89_chanctx_idx idx,
192 			      const struct cfg80211_chan_def *chandef)
193 {
194 	struct rtw89_hal *hal = &rtwdev->hal;
195 	enum rtw89_chanctx_idx cur;
196 
197 	if (chandef) {
198 		cur = atomic_cmpxchg(&hal->roc_chanctx_idx,
199 				     RTW89_CHANCTX_IDLE, idx);
200 		if (cur != RTW89_CHANCTX_IDLE) {
201 			rtw89_debug(rtwdev, RTW89_DBG_TXRX,
202 				    "ROC still processing on entity %d\n", idx);
203 			return;
204 		}
205 
206 		hal->roc_chandef = *chandef;
207 	} else {
208 		cur = atomic_cmpxchg(&hal->roc_chanctx_idx, idx,
209 				     RTW89_CHANCTX_IDLE);
210 		if (cur == idx)
211 			return;
212 
213 		if (cur == RTW89_CHANCTX_IDLE)
214 			rtw89_debug(rtwdev, RTW89_DBG_TXRX,
215 				    "ROC already finished on entity %d\n", idx);
216 		else
217 			rtw89_debug(rtwdev, RTW89_DBG_TXRX,
218 				    "ROC is processing on entity %d\n", cur);
219 	}
220 }
221 
222 static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
223 {
224 	struct cfg80211_chan_def chandef = {0};
225 
226 	rtw89_get_default_chandef(&chandef);
227 	__rtw89_config_entity_chandef(rtwdev, RTW89_CHANCTX_0, &chandef, false);
228 }
229 
230 void rtw89_entity_init(struct rtw89_dev *rtwdev)
231 {
232 	struct rtw89_hal *hal = &rtwdev->hal;
233 	struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
234 
235 	hal->entity_pause = false;
236 	bitmap_zero(hal->entity_map, NUM_OF_RTW89_CHANCTX);
237 	bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES);
238 	atomic_set(&hal->roc_chanctx_idx, RTW89_CHANCTX_IDLE);
239 
240 	INIT_LIST_HEAD(&mgnt->active_list);
241 
242 	rtw89_config_default_chandef(rtwdev);
243 }
244 
245 static bool rtw89_vif_is_active_role(struct rtw89_vif *rtwvif)
246 {
247 	struct rtw89_vif_link *rtwvif_link;
248 	unsigned int link_id;
249 
250 	rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
251 		if (rtwvif_link->chanctx_assigned)
252 			return true;
253 
254 	return false;
255 }
256 
257 static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
258 					  struct rtw89_entity_weight *w)
259 {
260 	struct rtw89_hal *hal = &rtwdev->hal;
261 	const struct rtw89_chanctx_cfg *cfg;
262 	struct rtw89_vif *rtwvif;
263 	int idx;
264 
265 	for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) {
266 		cfg = hal->chanctx[idx].cfg;
267 		if (!cfg) {
268 			/* doesn't run with chanctx ops; one channel at most */
269 			w->active_chanctxs = 1;
270 			break;
271 		}
272 
273 		if (cfg->ref_count > 0)
274 			w->active_chanctxs++;
275 	}
276 
277 	rtw89_for_each_rtwvif(rtwdev, rtwvif) {
278 		if (rtw89_vif_is_active_role(rtwvif))
279 			w->active_roles++;
280 	}
281 }
282 
283 static void rtw89_normalize_link_chanctx(struct rtw89_dev *rtwdev,
284 					 struct rtw89_vif_link *rtwvif_link)
285 {
286 	struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
287 	struct rtw89_vif_link *cur;
288 
289 	if (unlikely(!rtwvif_link->chanctx_assigned))
290 		return;
291 
292 	cur = rtw89_vif_get_link_inst(rtwvif, 0);
293 	if (!cur || !cur->chanctx_assigned)
294 		return;
295 
296 	if (cur == rtwvif_link)
297 		return;
298 
299 	rtw89_swap_chanctx(rtwdev, rtwvif_link->chanctx_idx, cur->chanctx_idx);
300 }
301 
302 const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
303 					       const char *caller_message,
304 					       u8 link_index)
305 {
306 	struct rtw89_hal *hal = &rtwdev->hal;
307 	struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
308 	enum rtw89_chanctx_idx chanctx_idx;
309 	enum rtw89_chanctx_idx roc_idx;
310 	enum rtw89_entity_mode mode;
311 	u8 role_index;
312 
313 	lockdep_assert_held(&rtwdev->mutex);
314 
315 	if (unlikely(link_index >= __RTW89_MLD_MAX_LINK_NUM)) {
316 		WARN(1, "link index %u is invalid (max link inst num: %d)\n",
317 		     link_index, __RTW89_MLD_MAX_LINK_NUM);
318 		goto dflt;
319 	}
320 
321 	mode = rtw89_get_entity_mode(rtwdev);
322 	switch (mode) {
323 	case RTW89_ENTITY_MODE_SCC_OR_SMLD:
324 	case RTW89_ENTITY_MODE_MCC:
325 		role_index = 0;
326 		break;
327 	case RTW89_ENTITY_MODE_MCC_PREPARE:
328 		role_index = 1;
329 		break;
330 	default:
331 		WARN(1, "Invalid ent mode: %d\n", mode);
332 		goto dflt;
333 	}
334 
335 	chanctx_idx = mgnt->chanctx_tbl[role_index][link_index];
336 	if (chanctx_idx == RTW89_CHANCTX_IDLE)
337 		goto dflt;
338 
339 	roc_idx = atomic_read(&hal->roc_chanctx_idx);
340 	if (roc_idx != RTW89_CHANCTX_IDLE) {
341 		/* ROC is ongoing (given ROC runs on RTW89_ROC_BY_LINK_INDEX).
342 		 * If @link_index is the same as RTW89_ROC_BY_LINK_INDEX, get
343 		 * the ongoing ROC chanctx.
344 		 */
345 		if (link_index == RTW89_ROC_BY_LINK_INDEX)
346 			chanctx_idx = roc_idx;
347 	}
348 
349 	return rtw89_chan_get(rtwdev, chanctx_idx);
350 
351 dflt:
352 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
353 		    "%s (%s): prefetch NULL on link index %u\n",
354 		    __func__, caller_message ?: "", link_index);
355 
356 	return rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
357 }
358 EXPORT_SYMBOL(__rtw89_mgnt_chan_get);
359 
360 static void rtw89_entity_recalc_mgnt_roles(struct rtw89_dev *rtwdev)
361 {
362 	struct rtw89_hal *hal = &rtwdev->hal;
363 	struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
364 	struct rtw89_vif_link *link;
365 	struct rtw89_vif *role;
366 	u8 pos = 0;
367 	int i, j;
368 
369 	lockdep_assert_held(&rtwdev->mutex);
370 
371 	for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++)
372 		mgnt->active_roles[i] = NULL;
373 
374 	for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++) {
375 		for (j = 0; j < __RTW89_MLD_MAX_LINK_NUM; j++)
376 			mgnt->chanctx_tbl[i][j] = RTW89_CHANCTX_IDLE;
377 	}
378 
379 	/* To be consistent with legacy behavior, expect the first active role
380 	 * which uses RTW89_CHANCTX_0 to put at position 0, and make its first
381 	 * link instance take RTW89_CHANCTX_0. (normalizing)
382 	 */
383 	list_for_each_entry(role, &mgnt->active_list, mgnt_entry) {
384 		for (i = 0; i < role->links_inst_valid_num; i++) {
385 			link = rtw89_vif_get_link_inst(role, i);
386 			if (!link || !link->chanctx_assigned)
387 				continue;
388 
389 			if (link->chanctx_idx == RTW89_CHANCTX_0) {
390 				rtw89_normalize_link_chanctx(rtwdev, link);
391 
392 				list_del(&role->mgnt_entry);
393 				list_add(&role->mgnt_entry, &mgnt->active_list);
394 				goto fill;
395 			}
396 		}
397 	}
398 
399 fill:
400 	list_for_each_entry(role, &mgnt->active_list, mgnt_entry) {
401 		if (unlikely(pos >= RTW89_MAX_INTERFACE_NUM)) {
402 			rtw89_warn(rtwdev,
403 				   "%s: active roles are over max iface num\n",
404 				   __func__);
405 			break;
406 		}
407 
408 		for (i = 0; i < role->links_inst_valid_num; i++) {
409 			link = rtw89_vif_get_link_inst(role, i);
410 			if (!link || !link->chanctx_assigned)
411 				continue;
412 
413 			mgnt->chanctx_tbl[pos][i] = link->chanctx_idx;
414 		}
415 
416 		mgnt->active_roles[pos++] = role;
417 	}
418 }
419 
420 enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
421 {
422 	DECLARE_BITMAP(recalc_map, NUM_OF_RTW89_CHANCTX) = {};
423 	struct rtw89_hal *hal = &rtwdev->hal;
424 	const struct cfg80211_chan_def *chandef;
425 	struct rtw89_entity_weight w = {};
426 	enum rtw89_entity_mode mode;
427 	struct rtw89_chan chan;
428 	u8 idx;
429 
430 	lockdep_assert_held(&rtwdev->mutex);
431 
432 	bitmap_copy(recalc_map, hal->entity_map, NUM_OF_RTW89_CHANCTX);
433 
434 	rtw89_entity_calculate_weight(rtwdev, &w);
435 	switch (w.active_chanctxs) {
436 	default:
437 		rtw89_warn(rtwdev, "unknown ent chanctxs weight: %d\n",
438 			   w.active_chanctxs);
439 		bitmap_zero(recalc_map, NUM_OF_RTW89_CHANCTX);
440 		fallthrough;
441 	case 0:
442 		rtw89_config_default_chandef(rtwdev);
443 		set_bit(RTW89_CHANCTX_0, recalc_map);
444 		fallthrough;
445 	case 1:
446 		mode = RTW89_ENTITY_MODE_SCC_OR_SMLD;
447 		break;
448 	case 2 ... NUM_OF_RTW89_CHANCTX:
449 		if (w.active_roles == 1) {
450 			mode = RTW89_ENTITY_MODE_SCC_OR_SMLD;
451 			break;
452 		}
453 
454 		if (w.active_roles != NUM_OF_RTW89_MCC_ROLES) {
455 			rtw89_debug(rtwdev, RTW89_DBG_CHAN,
456 				    "unhandled ent: %d chanctxs %d roles\n",
457 				    w.active_chanctxs, w.active_roles);
458 			return RTW89_ENTITY_MODE_UNHANDLED;
459 		}
460 
461 		mode = rtw89_get_entity_mode(rtwdev);
462 		if (mode == RTW89_ENTITY_MODE_MCC)
463 			break;
464 
465 		mode = RTW89_ENTITY_MODE_MCC_PREPARE;
466 		break;
467 	}
468 
469 	for_each_set_bit(idx, recalc_map, NUM_OF_RTW89_CHANCTX) {
470 		chandef = rtw89_chandef_get(rtwdev, idx);
471 		rtw89_get_channel_params(chandef, &chan);
472 		if (chan.channel == 0) {
473 			WARN(1, "Invalid channel on chanctx %d\n", idx);
474 			return RTW89_ENTITY_MODE_INVALID;
475 		}
476 
477 		rtw89_assign_entity_chan(rtwdev, idx, &chan);
478 	}
479 
480 	rtw89_entity_recalc_mgnt_roles(rtwdev);
481 
482 	if (hal->entity_pause)
483 		return rtw89_get_entity_mode(rtwdev);
484 
485 	rtw89_set_entity_mode(rtwdev, mode);
486 	return mode;
487 }
488 
489 static void rtw89_chanctx_notify(struct rtw89_dev *rtwdev,
490 				 enum rtw89_chanctx_state state)
491 {
492 	const struct rtw89_chip_info *chip = rtwdev->chip;
493 	const struct rtw89_chanctx_listener *listener = chip->chanctx_listener;
494 	int i;
495 
496 	if (!listener)
497 		return;
498 
499 	for (i = 0; i < NUM_OF_RTW89_CHANCTX_CALLBACKS; i++) {
500 		if (!listener->callbacks[i])
501 			continue;
502 
503 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
504 			    "chanctx notify listener: cb %d, state %d\n",
505 			    i, state);
506 
507 		listener->callbacks[i](rtwdev, state);
508 	}
509 }
510 
511 static bool rtw89_concurrent_via_mrc(struct rtw89_dev *rtwdev)
512 {
513 	enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
514 
515 	return chip_gen == RTW89_CHIP_BE;
516 }
517 
518 /* This function centrally manages how MCC roles are sorted and iterated.
519  * And, it guarantees that ordered_idx is less than NUM_OF_RTW89_MCC_ROLES.
520  * So, if data needs to pass an array for ordered_idx, the array can declare
521  * with NUM_OF_RTW89_MCC_ROLES. Besides, the entire iteration will stop
522  * immediately as long as iterator returns a non-zero value.
523  */
524 static
525 int rtw89_iterate_mcc_roles(struct rtw89_dev *rtwdev,
526 			    int (*iterator)(struct rtw89_dev *rtwdev,
527 					    struct rtw89_mcc_role *mcc_role,
528 					    unsigned int ordered_idx,
529 					    void *data),
530 			    void *data)
531 {
532 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
533 	struct rtw89_mcc_role * const roles[] = {
534 		&mcc->role_ref,
535 		&mcc->role_aux,
536 	};
537 	unsigned int idx;
538 	int ret;
539 
540 	BUILD_BUG_ON(ARRAY_SIZE(roles) != NUM_OF_RTW89_MCC_ROLES);
541 
542 	for (idx = 0; idx < NUM_OF_RTW89_MCC_ROLES; idx++) {
543 		ret = iterator(rtwdev, roles[idx], idx, data);
544 		if (ret)
545 			return ret;
546 	}
547 
548 	return 0;
549 }
550 
551 static u32 rtw89_mcc_get_tbtt_ofst(struct rtw89_dev *rtwdev,
552 				   struct rtw89_mcc_role *role, u64 tsf)
553 {
554 	struct rtw89_vif_link *rtwvif_link = role->rtwvif_link;
555 	u32 bcn_intvl_us = ieee80211_tu_to_usec(role->beacon_interval);
556 	u64 sync_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf);
557 	u32 remainder;
558 
559 	if (tsf < sync_tsf) {
560 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
561 			    "MCC get tbtt ofst: tsf might not update yet\n");
562 		sync_tsf = 0;
563 	}
564 
565 	div_u64_rem(tsf - sync_tsf, bcn_intvl_us, &remainder);
566 
567 	return remainder;
568 }
569 
570 static int __mcc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux)
571 {
572 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
573 	struct rtw89_mcc_role *ref = &mcc->role_ref;
574 	struct rtw89_mcc_role *aux = &mcc->role_aux;
575 	struct rtw89_mac_mcc_tsf_rpt rpt = {};
576 	struct rtw89_fw_mcc_tsf_req req = {};
577 	int ret;
578 
579 	req.group = mcc->group;
580 	req.macid_x = ref->rtwvif_link->mac_id;
581 	req.macid_y = aux->rtwvif_link->mac_id;
582 	ret = rtw89_fw_h2c_mcc_req_tsf(rtwdev, &req, &rpt);
583 	if (ret) {
584 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
585 			    "MCC h2c failed to request tsf: %d\n", ret);
586 		return ret;
587 	}
588 
589 	*tsf_ref = (u64)rpt.tsf_x_high << 32 | rpt.tsf_x_low;
590 	*tsf_aux = (u64)rpt.tsf_y_high << 32 | rpt.tsf_y_low;
591 
592 	return 0;
593 }
594 
595 static int __mrc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux)
596 {
597 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
598 	struct rtw89_mcc_role *ref = &mcc->role_ref;
599 	struct rtw89_mcc_role *aux = &mcc->role_aux;
600 	struct rtw89_fw_mrc_req_tsf_arg arg = {};
601 	struct rtw89_mac_mrc_tsf_rpt rpt = {};
602 	int ret;
603 
604 	BUILD_BUG_ON(RTW89_MAC_MRC_MAX_REQ_TSF_NUM < NUM_OF_RTW89_MCC_ROLES);
605 
606 	arg.num = 2;
607 	arg.infos[0].band = ref->rtwvif_link->mac_idx;
608 	arg.infos[0].port = ref->rtwvif_link->port;
609 	arg.infos[1].band = aux->rtwvif_link->mac_idx;
610 	arg.infos[1].port = aux->rtwvif_link->port;
611 
612 	ret = rtw89_fw_h2c_mrc_req_tsf(rtwdev, &arg, &rpt);
613 	if (ret) {
614 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
615 			    "MRC h2c failed to request tsf: %d\n", ret);
616 		return ret;
617 	}
618 
619 	*tsf_ref = rpt.tsfs[0];
620 	*tsf_aux = rpt.tsfs[1];
621 
622 	return 0;
623 }
624 
625 static u16 rtw89_mcc_get_bcn_ofst(struct rtw89_dev *rtwdev)
626 {
627 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
628 	struct rtw89_mcc_role *ref = &mcc->role_ref;
629 	struct rtw89_mcc_role *aux = &mcc->role_aux;
630 	u32 bcn_intvl_ref_us = ieee80211_tu_to_usec(ref->beacon_interval);
631 	u32 tbtt_ofst_ref, tbtt_ofst_aux;
632 	u64 tsf_ref, tsf_aux;
633 	int ret;
634 
635 	if (rtw89_concurrent_via_mrc(rtwdev))
636 		ret = __mrc_fw_req_tsf(rtwdev, &tsf_ref, &tsf_aux);
637 	else
638 		ret = __mcc_fw_req_tsf(rtwdev, &tsf_ref, &tsf_aux);
639 
640 	if (ret)
641 		return RTW89_MCC_DFLT_BCN_OFST_TIME;
642 
643 	tbtt_ofst_ref = rtw89_mcc_get_tbtt_ofst(rtwdev, ref, tsf_ref);
644 	tbtt_ofst_aux = rtw89_mcc_get_tbtt_ofst(rtwdev, aux, tsf_aux);
645 
646 	while (tbtt_ofst_ref < tbtt_ofst_aux)
647 		tbtt_ofst_ref += bcn_intvl_ref_us;
648 
649 	return (tbtt_ofst_ref - tbtt_ofst_aux) / 1024;
650 }
651 
652 static
653 void rtw89_mcc_role_fw_macid_bitmap_set_bit(struct rtw89_mcc_role *mcc_role,
654 					    unsigned int bit)
655 {
656 	unsigned int idx = bit / 8;
657 	unsigned int pos = bit % 8;
658 
659 	if (idx >= ARRAY_SIZE(mcc_role->macid_bitmap))
660 		return;
661 
662 	mcc_role->macid_bitmap[idx] |= BIT(pos);
663 }
664 
665 static
666 u32 rtw89_mcc_role_fw_macid_bitmap_to_u32(struct rtw89_mcc_role *mcc_role)
667 {
668 	unsigned int macid;
669 	unsigned int i, j;
670 	u32 bitmap = 0;
671 
672 	for (i = 0; i < ARRAY_SIZE(mcc_role->macid_bitmap); i++) {
673 		for (j = 0; j < 8; j++) {
674 			macid = i * 8 + j;
675 			if (macid >= 32)
676 				goto out;
677 
678 			if (mcc_role->macid_bitmap[i] & BIT(j))
679 				bitmap |= BIT(macid);
680 		}
681 	}
682 
683 out:
684 	return bitmap;
685 }
686 
687 static void rtw89_mcc_role_macid_sta_iter(void *data, struct ieee80211_sta *sta)
688 {
689 	struct rtw89_mcc_role *mcc_role = data;
690 	struct rtw89_vif *target = mcc_role->rtwvif_link->rtwvif;
691 	struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
692 	struct rtw89_vif *rtwvif = rtwsta->rtwvif;
693 	struct rtw89_dev *rtwdev = rtwsta->rtwdev;
694 	struct rtw89_sta_link *rtwsta_link;
695 
696 	if (rtwvif != target)
697 		return;
698 
699 	rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
700 	if (unlikely(!rtwsta_link)) {
701 		rtw89_err(rtwdev, "mcc sta macid: find no link on HW-0\n");
702 		return;
703 	}
704 
705 	rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwsta_link->mac_id);
706 }
707 
708 static void rtw89_mcc_fill_role_macid_bitmap(struct rtw89_dev *rtwdev,
709 					     struct rtw89_mcc_role *mcc_role)
710 {
711 	struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link;
712 
713 	rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwvif_link->mac_id);
714 	ieee80211_iterate_stations_atomic(rtwdev->hw,
715 					  rtw89_mcc_role_macid_sta_iter,
716 					  mcc_role);
717 }
718 
719 static void rtw89_mcc_fill_role_policy(struct rtw89_dev *rtwdev,
720 				       struct rtw89_mcc_role *mcc_role)
721 {
722 	struct rtw89_mcc_policy *policy = &mcc_role->policy;
723 
724 	policy->c2h_rpt = RTW89_FW_MCC_C2H_RPT_ALL;
725 	policy->tx_null_early = RTW89_MCC_DFLT_TX_NULL_EARLY;
726 	policy->in_curr_ch = false;
727 	policy->dis_sw_retry = true;
728 	policy->sw_retry_count = false;
729 
730 	if (mcc_role->is_go)
731 		policy->dis_tx_null = true;
732 	else
733 		policy->dis_tx_null = false;
734 }
735 
736 static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev,
737 				      struct rtw89_mcc_role *mcc_role)
738 {
739 	struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link;
740 	struct ieee80211_p2p_noa_desc *noa_desc;
741 	struct ieee80211_bss_conf *bss_conf;
742 	u32 bcn_intvl_us = ieee80211_tu_to_usec(mcc_role->beacon_interval);
743 	u32 max_toa_us, max_tob_us, max_dur_us;
744 	u32 start_time, interval, duration;
745 	u64 tsf, tsf_lmt;
746 	int ret;
747 	int i;
748 
749 	if (!mcc_role->is_go && !mcc_role->is_gc)
750 		return;
751 
752 	rcu_read_lock();
753 
754 	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
755 
756 	/* find the first periodic NoA */
757 	for (i = 0; i < RTW89_P2P_MAX_NOA_NUM; i++) {
758 		noa_desc = &bss_conf->p2p_noa_attr.desc[i];
759 		if (noa_desc->count == 255)
760 			goto fill;
761 	}
762 
763 	rcu_read_unlock();
764 	return;
765 
766 fill:
767 	start_time = le32_to_cpu(noa_desc->start_time);
768 	interval = le32_to_cpu(noa_desc->interval);
769 	duration = le32_to_cpu(noa_desc->duration);
770 
771 	rcu_read_unlock();
772 
773 	if (interval != bcn_intvl_us) {
774 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
775 			    "MCC role limit: mismatch interval: %d vs. %d\n",
776 			    interval, bcn_intvl_us);
777 		return;
778 	}
779 
780 	ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
781 	if (ret) {
782 		rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
783 		return;
784 	}
785 
786 	tsf_lmt = (tsf & GENMASK_ULL(63, 32)) | start_time;
787 	max_toa_us = rtw89_mcc_get_tbtt_ofst(rtwdev, mcc_role, tsf_lmt);
788 	max_dur_us = interval - duration;
789 	max_tob_us = max_dur_us - max_toa_us;
790 
791 	if (!max_toa_us || !max_tob_us) {
792 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
793 			    "MCC role limit: hit boundary\n");
794 		return;
795 	}
796 
797 	if (max_dur_us < max_toa_us) {
798 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
799 			    "MCC role limit: insufficient duration\n");
800 		return;
801 	}
802 
803 	mcc_role->limit.max_toa = max_toa_us / 1024;
804 	mcc_role->limit.max_tob = max_tob_us / 1024;
805 	mcc_role->limit.max_dur = mcc_role->limit.max_toa + mcc_role->limit.max_tob;
806 	mcc_role->limit.enable = true;
807 
808 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
809 		    "MCC role limit: max_toa %d, max_tob %d, max_dur %d\n",
810 		    mcc_role->limit.max_toa, mcc_role->limit.max_tob,
811 		    mcc_role->limit.max_dur);
812 }
813 
814 static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev,
815 			       struct rtw89_vif_link *rtwvif_link,
816 			       struct rtw89_mcc_role *role)
817 {
818 	struct ieee80211_bss_conf *bss_conf;
819 	const struct rtw89_chan *chan;
820 
821 	memset(role, 0, sizeof(*role));
822 	role->rtwvif_link = rtwvif_link;
823 
824 	rcu_read_lock();
825 
826 	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
827 	role->beacon_interval = bss_conf->beacon_int;
828 
829 	rcu_read_unlock();
830 
831 	if (!role->beacon_interval) {
832 		rtw89_warn(rtwdev,
833 			   "cannot handle MCC role without beacon interval\n");
834 		return -EINVAL;
835 	}
836 
837 	role->duration = role->beacon_interval / 2;
838 
839 	chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
840 	role->is_2ghz = chan->band_type == RTW89_BAND_2G;
841 	role->is_go = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_GO;
842 	role->is_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
843 
844 	rtw89_mcc_fill_role_macid_bitmap(rtwdev, role);
845 	rtw89_mcc_fill_role_policy(rtwdev, role);
846 	rtw89_mcc_fill_role_limit(rtwdev, role);
847 
848 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
849 		    "MCC role: bcn_intvl %d, is_2ghz %d, is_go %d, is_gc %d\n",
850 		    role->beacon_interval, role->is_2ghz, role->is_go, role->is_gc);
851 	return 0;
852 }
853 
854 static void rtw89_mcc_fill_bt_role(struct rtw89_dev *rtwdev)
855 {
856 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
857 	struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role;
858 
859 	memset(bt_role, 0, sizeof(*bt_role));
860 	bt_role->duration = rtw89_coex_query_bt_req_len(rtwdev, RTW89_PHY_0);
861 
862 	rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC bt role: dur %d\n",
863 		    bt_role->duration);
864 }
865 
866 struct rtw89_mcc_fill_role_selector {
867 	struct rtw89_vif_link *bind_vif[NUM_OF_RTW89_CHANCTX];
868 };
869 
870 static_assert((u8)NUM_OF_RTW89_CHANCTX >= NUM_OF_RTW89_MCC_ROLES);
871 static_assert(RTW89_MAX_INTERFACE_NUM >= NUM_OF_RTW89_MCC_ROLES);
872 
873 static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
874 					struct rtw89_mcc_role *mcc_role,
875 					unsigned int ordered_idx,
876 					void *data)
877 {
878 	struct rtw89_mcc_fill_role_selector *sel = data;
879 	struct rtw89_vif_link *role_vif = sel->bind_vif[ordered_idx];
880 	int ret;
881 
882 	if (!role_vif) {
883 		rtw89_warn(rtwdev, "cannot handle MCC without role[%d]\n",
884 			   ordered_idx);
885 		return -EINVAL;
886 	}
887 
888 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
889 		    "MCC fill role[%d] with vif <macid %d>\n",
890 		    ordered_idx, role_vif->mac_id);
891 
892 	ret = rtw89_mcc_fill_role(rtwdev, role_vif, mcc_role);
893 	if (ret)
894 		return ret;
895 
896 	return 0;
897 }
898 
899 static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
900 {
901 	struct rtw89_hal *hal = &rtwdev->hal;
902 	struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
903 	struct rtw89_mcc_fill_role_selector sel = {};
904 	struct rtw89_vif_link *rtwvif_link;
905 	struct rtw89_vif *rtwvif;
906 	int ret;
907 	int i;
908 
909 	for (i = 0; i < NUM_OF_RTW89_MCC_ROLES; i++) {
910 		rtwvif = mgnt->active_roles[i];
911 		if (!rtwvif)
912 			break;
913 
914 		rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
915 		if (unlikely(!rtwvif_link)) {
916 			rtw89_err(rtwdev, "mcc fill roles: find no link on HW-0\n");
917 			continue;
918 		}
919 
920 		sel.bind_vif[i] = rtwvif_link;
921 	}
922 
923 	ret = rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_fill_role_iterator, &sel);
924 	if (ret)
925 		return ret;
926 
927 	rtw89_mcc_fill_bt_role(rtwdev);
928 	return 0;
929 }
930 
931 static void rtw89_mcc_assign_pattern(struct rtw89_dev *rtwdev,
932 				     const struct rtw89_mcc_pattern *new)
933 {
934 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
935 	struct rtw89_mcc_role *ref = &mcc->role_ref;
936 	struct rtw89_mcc_role *aux = &mcc->role_aux;
937 	struct rtw89_mcc_config *config = &mcc->config;
938 	struct rtw89_mcc_pattern *pattern = &config->pattern;
939 
940 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
941 		    "MCC assign pattern: ref {%d | %d}, aux {%d | %d}\n",
942 		    new->tob_ref, new->toa_ref, new->tob_aux, new->toa_aux);
943 
944 	*pattern = *new;
945 	memset(&pattern->courtesy, 0, sizeof(pattern->courtesy));
946 
947 	if (pattern->tob_aux <= 0 || pattern->toa_aux <= 0) {
948 		pattern->courtesy.macid_tgt = aux->rtwvif_link->mac_id;
949 		pattern->courtesy.macid_src = ref->rtwvif_link->mac_id;
950 		pattern->courtesy.slot_num = RTW89_MCC_DFLT_COURTESY_SLOT;
951 		pattern->courtesy.enable = true;
952 	} else if (pattern->tob_ref <= 0 || pattern->toa_ref <= 0) {
953 		pattern->courtesy.macid_tgt = ref->rtwvif_link->mac_id;
954 		pattern->courtesy.macid_src = aux->rtwvif_link->mac_id;
955 		pattern->courtesy.slot_num = RTW89_MCC_DFLT_COURTESY_SLOT;
956 		pattern->courtesy.enable = true;
957 	}
958 
959 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
960 		    "MCC pattern flags: plan %d, courtesy_en %d\n",
961 		    pattern->plan, pattern->courtesy.enable);
962 
963 	if (!pattern->courtesy.enable)
964 		return;
965 
966 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
967 		    "MCC pattern courtesy: tgt %d, src %d, slot %d\n",
968 		    pattern->courtesy.macid_tgt, pattern->courtesy.macid_src,
969 		    pattern->courtesy.slot_num);
970 }
971 
972 /* The follow-up roughly shows the relationship between the parameters
973  * for pattern calculation.
974  *
975  * |<    duration ref     >| (if mid bt) |<    duration aux     >|
976  * |< tob ref >|< toa ref >|     ...     |< tob aux >|< toa aux >|
977  *             V                                     V
978  *         tbtt ref                              tbtt aux
979  *             |<           beacon offset           >|
980  *
981  * In loose pattern calculation, we only ensure at least tob_ref and
982  * toa_ref have positive results. If tob_aux or toa_aux is negative
983  * unfortunately, FW will be notified to handle it with courtesy
984  * mechanism.
985  */
986 static void __rtw89_mcc_calc_pattern_loose(struct rtw89_dev *rtwdev,
987 					   struct rtw89_mcc_pattern *ptrn,
988 					   bool hdl_bt)
989 {
990 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
991 	struct rtw89_mcc_role *ref = &mcc->role_ref;
992 	struct rtw89_mcc_role *aux = &mcc->role_aux;
993 	struct rtw89_mcc_config *config = &mcc->config;
994 	u16 bcn_ofst = config->beacon_offset;
995 	u16 bt_dur_in_mid = 0;
996 	u16 max_bcn_ofst;
997 	s16 upper, lower;
998 	u16 res;
999 
1000 	*ptrn = (typeof(*ptrn)){
1001 		.plan = hdl_bt ? RTW89_MCC_PLAN_TAIL_BT : RTW89_MCC_PLAN_NO_BT,
1002 	};
1003 
1004 	if (!hdl_bt)
1005 		goto calc;
1006 
1007 	max_bcn_ofst = ref->duration + aux->duration;
1008 	if (ref->limit.enable)
1009 		max_bcn_ofst = min_t(u16, max_bcn_ofst,
1010 				     ref->limit.max_toa + aux->duration);
1011 	else if (aux->limit.enable)
1012 		max_bcn_ofst = min_t(u16, max_bcn_ofst,
1013 				     ref->duration + aux->limit.max_tob);
1014 
1015 	if (bcn_ofst > max_bcn_ofst && bcn_ofst >= mcc->bt_role.duration) {
1016 		bt_dur_in_mid = mcc->bt_role.duration;
1017 		ptrn->plan = RTW89_MCC_PLAN_MID_BT;
1018 	}
1019 
1020 calc:
1021 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1022 		    "MCC calc ptrn_ls: plan %d, bcn_ofst %d\n",
1023 		    ptrn->plan, bcn_ofst);
1024 
1025 	res = bcn_ofst - bt_dur_in_mid;
1026 	upper = min_t(s16, ref->duration, res);
1027 	lower = 0;
1028 
1029 	if (ref->limit.enable) {
1030 		upper = min_t(s16, upper, ref->limit.max_toa);
1031 		lower = max_t(s16, lower, ref->duration - ref->limit.max_tob);
1032 	} else if (aux->limit.enable) {
1033 		upper = min_t(s16, upper,
1034 			      res - (aux->duration - aux->limit.max_toa));
1035 		lower = max_t(s16, lower, res - aux->limit.max_tob);
1036 	}
1037 
1038 	if (lower < upper)
1039 		ptrn->toa_ref = (upper + lower) / 2;
1040 	else
1041 		ptrn->toa_ref = lower;
1042 
1043 	ptrn->tob_ref = ref->duration - ptrn->toa_ref;
1044 	ptrn->tob_aux = res - ptrn->toa_ref;
1045 	ptrn->toa_aux = aux->duration - ptrn->tob_aux;
1046 }
1047 
1048 /* In strict pattern calculation, we consider timing that might need
1049  * for HW stuffs, i.e. min_tob and min_toa.
1050  */
1051 static int __rtw89_mcc_calc_pattern_strict(struct rtw89_dev *rtwdev,
1052 					   struct rtw89_mcc_pattern *ptrn)
1053 {
1054 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1055 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1056 	struct rtw89_mcc_role *aux = &mcc->role_aux;
1057 	struct rtw89_mcc_config *config = &mcc->config;
1058 	u16 min_tob = RTW89_MCC_EARLY_RX_BCN_TIME;
1059 	u16 min_toa = RTW89_MCC_MIN_RX_BCN_TIME;
1060 	u16 bcn_ofst = config->beacon_offset;
1061 	s16 upper_toa_ref, lower_toa_ref;
1062 	s16 upper_tob_aux, lower_tob_aux;
1063 	u16 bt_dur_in_mid;
1064 	s16 res;
1065 
1066 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1067 		    "MCC calc ptrn_st: plan %d, bcn_ofst %d\n",
1068 		    ptrn->plan, bcn_ofst);
1069 
1070 	if (ptrn->plan == RTW89_MCC_PLAN_MID_BT)
1071 		bt_dur_in_mid = mcc->bt_role.duration;
1072 	else
1073 		bt_dur_in_mid = 0;
1074 
1075 	if (ref->duration < min_tob + min_toa) {
1076 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1077 			    "MCC calc ptrn_st: not meet ref dur cond\n");
1078 		return -EINVAL;
1079 	}
1080 
1081 	if (aux->duration < min_tob + min_toa) {
1082 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1083 			    "MCC calc ptrn_st: not meet aux dur cond\n");
1084 		return -EINVAL;
1085 	}
1086 
1087 	res = bcn_ofst - min_toa - min_tob - bt_dur_in_mid;
1088 	if (res < 0) {
1089 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1090 			    "MCC calc ptrn_st: not meet bcn_ofst cond\n");
1091 		return -EINVAL;
1092 	}
1093 
1094 	upper_toa_ref = min_t(s16, min_toa + res, ref->duration - min_tob);
1095 	lower_toa_ref = min_toa;
1096 	upper_tob_aux = min_t(s16, min_tob + res, aux->duration - min_toa);
1097 	lower_tob_aux = min_tob;
1098 
1099 	if (ref->limit.enable) {
1100 		if (min_tob > ref->limit.max_tob || min_toa > ref->limit.max_toa) {
1101 			rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1102 				    "MCC calc ptrn_st: conflict ref limit\n");
1103 			return -EINVAL;
1104 		}
1105 
1106 		upper_toa_ref = min_t(s16, upper_toa_ref, ref->limit.max_toa);
1107 		lower_toa_ref = max_t(s16, lower_toa_ref,
1108 				      ref->duration - ref->limit.max_tob);
1109 	} else if (aux->limit.enable) {
1110 		if (min_tob > aux->limit.max_tob || min_toa > aux->limit.max_toa) {
1111 			rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1112 				    "MCC calc ptrn_st: conflict aux limit\n");
1113 			return -EINVAL;
1114 		}
1115 
1116 		upper_tob_aux = min_t(s16, upper_tob_aux, aux->limit.max_tob);
1117 		lower_tob_aux = max_t(s16, lower_tob_aux,
1118 				      aux->duration - aux->limit.max_toa);
1119 	}
1120 
1121 	upper_toa_ref = min_t(s16, upper_toa_ref,
1122 			      bcn_ofst - bt_dur_in_mid - lower_tob_aux);
1123 	lower_toa_ref = max_t(s16, lower_toa_ref,
1124 			      bcn_ofst - bt_dur_in_mid - upper_tob_aux);
1125 	if (lower_toa_ref > upper_toa_ref) {
1126 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1127 			    "MCC calc ptrn_st: conflict boundary\n");
1128 		return -EINVAL;
1129 	}
1130 
1131 	ptrn->toa_ref = (upper_toa_ref + lower_toa_ref) / 2;
1132 	ptrn->tob_ref = ref->duration - ptrn->toa_ref;
1133 	ptrn->tob_aux = bcn_ofst - ptrn->toa_ref - bt_dur_in_mid;
1134 	ptrn->toa_aux = aux->duration - ptrn->tob_aux;
1135 	return 0;
1136 }
1137 
1138 static int rtw89_mcc_calc_pattern(struct rtw89_dev *rtwdev, bool hdl_bt)
1139 {
1140 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1141 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1142 	struct rtw89_mcc_role *aux = &mcc->role_aux;
1143 	bool sel_plan[NUM_OF_RTW89_MCC_PLAN] = {};
1144 	struct rtw89_mcc_pattern ptrn;
1145 	int ret;
1146 	int i;
1147 
1148 	if (ref->limit.enable && aux->limit.enable) {
1149 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1150 			    "MCC calc ptrn: not support dual limited roles\n");
1151 		return -EINVAL;
1152 	}
1153 
1154 	if (ref->limit.enable &&
1155 	    ref->duration > ref->limit.max_tob + ref->limit.max_toa) {
1156 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1157 			    "MCC calc ptrn: not fit ref limit\n");
1158 		return -EINVAL;
1159 	}
1160 
1161 	if (aux->limit.enable &&
1162 	    aux->duration > aux->limit.max_tob + aux->limit.max_toa) {
1163 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1164 			    "MCC calc ptrn: not fit aux limit\n");
1165 		return -EINVAL;
1166 	}
1167 
1168 	if (hdl_bt) {
1169 		sel_plan[RTW89_MCC_PLAN_TAIL_BT] = true;
1170 		sel_plan[RTW89_MCC_PLAN_MID_BT] = true;
1171 	} else {
1172 		sel_plan[RTW89_MCC_PLAN_NO_BT] = true;
1173 	}
1174 
1175 	for (i = 0; i < NUM_OF_RTW89_MCC_PLAN; i++) {
1176 		if (!sel_plan[i])
1177 			continue;
1178 
1179 		ptrn = (typeof(ptrn)){
1180 			.plan = i,
1181 		};
1182 
1183 		ret = __rtw89_mcc_calc_pattern_strict(rtwdev, &ptrn);
1184 		if (ret)
1185 			rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1186 				    "MCC calc ptrn_st with plan %d: fail\n", i);
1187 		else
1188 			goto done;
1189 	}
1190 
1191 	__rtw89_mcc_calc_pattern_loose(rtwdev, &ptrn, hdl_bt);
1192 
1193 done:
1194 	rtw89_mcc_assign_pattern(rtwdev, &ptrn);
1195 	return 0;
1196 }
1197 
1198 static void rtw89_mcc_set_default_pattern(struct rtw89_dev *rtwdev)
1199 {
1200 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1201 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1202 	struct rtw89_mcc_role *aux = &mcc->role_aux;
1203 	struct rtw89_mcc_pattern tmp = {};
1204 
1205 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1206 		    "MCC use default pattern unexpectedly\n");
1207 
1208 	tmp.plan = RTW89_MCC_PLAN_NO_BT;
1209 	tmp.tob_ref = ref->duration / 2;
1210 	tmp.toa_ref = ref->duration - tmp.tob_ref;
1211 	tmp.tob_aux = aux->duration / 2;
1212 	tmp.toa_aux = aux->duration - tmp.tob_aux;
1213 
1214 	rtw89_mcc_assign_pattern(rtwdev, &tmp);
1215 }
1216 
1217 static void rtw89_mcc_set_duration_go_sta(struct rtw89_dev *rtwdev,
1218 					  struct rtw89_mcc_role *role_go,
1219 					  struct rtw89_mcc_role *role_sta)
1220 {
1221 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1222 	struct rtw89_mcc_config *config = &mcc->config;
1223 	u16 mcc_intvl = config->mcc_interval;
1224 	u16 dur_go, dur_sta;
1225 
1226 	dur_go = clamp_t(u16, role_go->duration, RTW89_MCC_MIN_GO_DURATION,
1227 			 mcc_intvl - RTW89_MCC_MIN_STA_DURATION);
1228 	if (role_go->limit.enable)
1229 		dur_go = min(dur_go, role_go->limit.max_dur);
1230 	dur_sta = mcc_intvl - dur_go;
1231 
1232 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1233 		    "MCC set dur: (go, sta) {%d, %d} -> {%d, %d}\n",
1234 		    role_go->duration, role_sta->duration, dur_go, dur_sta);
1235 
1236 	role_go->duration = dur_go;
1237 	role_sta->duration = dur_sta;
1238 }
1239 
1240 static void rtw89_mcc_set_duration_gc_sta(struct rtw89_dev *rtwdev)
1241 {
1242 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1243 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1244 	struct rtw89_mcc_role *aux = &mcc->role_aux;
1245 	struct rtw89_mcc_config *config = &mcc->config;
1246 	u16 mcc_intvl = config->mcc_interval;
1247 	u16 dur_ref, dur_aux;
1248 
1249 	if (ref->duration < RTW89_MCC_MIN_STA_DURATION) {
1250 		dur_ref = RTW89_MCC_MIN_STA_DURATION;
1251 		dur_aux = mcc_intvl - dur_ref;
1252 	} else if (aux->duration < RTW89_MCC_MIN_STA_DURATION) {
1253 		dur_aux = RTW89_MCC_MIN_STA_DURATION;
1254 		dur_ref = mcc_intvl - dur_aux;
1255 	} else {
1256 		dur_ref = ref->duration;
1257 		dur_aux = mcc_intvl - dur_ref;
1258 	}
1259 
1260 	if (ref->limit.enable) {
1261 		dur_ref = min(dur_ref, ref->limit.max_dur);
1262 		dur_aux = mcc_intvl - dur_ref;
1263 	} else if (aux->limit.enable) {
1264 		dur_aux = min(dur_aux, aux->limit.max_dur);
1265 		dur_ref = mcc_intvl - dur_aux;
1266 	}
1267 
1268 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1269 		    "MCC set dur: (ref, aux) {%d ~ %d} -> {%d ~ %d}\n",
1270 		    ref->duration, aux->duration, dur_ref, dur_aux);
1271 
1272 	ref->duration = dur_ref;
1273 	aux->duration = dur_aux;
1274 }
1275 
1276 struct rtw89_mcc_mod_dur_data {
1277 	u16 available;
1278 	struct {
1279 		u16 dur;
1280 		u16 room;
1281 	} parm[NUM_OF_RTW89_MCC_ROLES];
1282 };
1283 
1284 static int rtw89_mcc_mod_dur_get_iterator(struct rtw89_dev *rtwdev,
1285 					  struct rtw89_mcc_role *mcc_role,
1286 					  unsigned int ordered_idx,
1287 					  void *data)
1288 {
1289 	struct rtw89_mcc_mod_dur_data *p = data;
1290 	u16 min;
1291 
1292 	p->parm[ordered_idx].dur = mcc_role->duration;
1293 
1294 	if (mcc_role->is_go)
1295 		min = RTW89_MCC_MIN_GO_DURATION;
1296 	else
1297 		min = RTW89_MCC_MIN_STA_DURATION;
1298 
1299 	p->parm[ordered_idx].room = max_t(s32, p->parm[ordered_idx].dur - min, 0);
1300 
1301 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1302 		    "MCC mod dur: chk role[%u]: dur %u, min %u, room %u\n",
1303 		    ordered_idx, p->parm[ordered_idx].dur, min,
1304 		    p->parm[ordered_idx].room);
1305 
1306 	p->available += p->parm[ordered_idx].room;
1307 	return 0;
1308 }
1309 
1310 static int rtw89_mcc_mod_dur_put_iterator(struct rtw89_dev *rtwdev,
1311 					  struct rtw89_mcc_role *mcc_role,
1312 					  unsigned int ordered_idx,
1313 					  void *data)
1314 {
1315 	struct rtw89_mcc_mod_dur_data *p = data;
1316 
1317 	mcc_role->duration = p->parm[ordered_idx].dur;
1318 
1319 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1320 		    "MCC mod dur: set role[%u]: dur %u\n",
1321 		    ordered_idx, p->parm[ordered_idx].dur);
1322 	return 0;
1323 }
1324 
1325 static void rtw89_mcc_mod_duration_dual_2ghz_with_bt(struct rtw89_dev *rtwdev)
1326 {
1327 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1328 	struct rtw89_mcc_config *config = &mcc->config;
1329 	struct rtw89_mcc_mod_dur_data data = {};
1330 	u16 mcc_intvl = config->mcc_interval;
1331 	u16 bt_dur = mcc->bt_role.duration;
1332 	u16 wifi_dur;
1333 
1334 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1335 		    "MCC mod dur (dual 2ghz): mcc_intvl %u, raw bt_dur %u\n",
1336 		    mcc_intvl, bt_dur);
1337 
1338 	rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_mod_dur_get_iterator, &data);
1339 
1340 	bt_dur = clamp_t(u16, bt_dur, 1, data.available / 3);
1341 	wifi_dur = mcc_intvl - bt_dur;
1342 
1343 	if (data.parm[0].room <= data.parm[1].room) {
1344 		data.parm[0].dur -= min_t(u16, bt_dur / 2, data.parm[0].room);
1345 		data.parm[1].dur = wifi_dur - data.parm[0].dur;
1346 	} else {
1347 		data.parm[1].dur -= min_t(u16, bt_dur / 2, data.parm[1].room);
1348 		data.parm[0].dur = wifi_dur - data.parm[1].dur;
1349 	}
1350 
1351 	rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_mod_dur_put_iterator, &data);
1352 
1353 	rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC mod dur: set bt: dur %u\n", bt_dur);
1354 	mcc->bt_role.duration = bt_dur;
1355 }
1356 
1357 static
1358 void rtw89_mcc_mod_duration_diff_band_with_bt(struct rtw89_dev *rtwdev,
1359 					      struct rtw89_mcc_role *role_2ghz,
1360 					      struct rtw89_mcc_role *role_non_2ghz)
1361 {
1362 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1363 	struct rtw89_mcc_config *config = &mcc->config;
1364 	u16 dur_2ghz, dur_non_2ghz;
1365 	u16 bt_dur, mcc_intvl;
1366 
1367 	dur_2ghz = role_2ghz->duration;
1368 	dur_non_2ghz = role_non_2ghz->duration;
1369 	mcc_intvl = config->mcc_interval;
1370 	bt_dur = mcc->bt_role.duration;
1371 
1372 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1373 		    "MCC mod dur (diff band): mcc_intvl %u, bt_dur %u\n",
1374 		    mcc_intvl, bt_dur);
1375 
1376 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1377 		    "MCC mod dur: check dur_2ghz %u, dur_non_2ghz %u\n",
1378 		    dur_2ghz, dur_non_2ghz);
1379 
1380 	if (dur_non_2ghz >= bt_dur) {
1381 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1382 			    "MCC mod dur: dur_non_2ghz is enough for bt\n");
1383 		return;
1384 	}
1385 
1386 	dur_non_2ghz = bt_dur;
1387 	dur_2ghz = mcc_intvl - dur_non_2ghz;
1388 
1389 	if (role_non_2ghz->limit.enable) {
1390 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1391 			    "MCC mod dur: dur_non_2ghz is limited with max %u\n",
1392 			    role_non_2ghz->limit.max_dur);
1393 
1394 		dur_non_2ghz = min(dur_non_2ghz, role_non_2ghz->limit.max_dur);
1395 		dur_2ghz = mcc_intvl - dur_non_2ghz;
1396 	}
1397 
1398 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1399 		    "MCC mod dur: set dur_2ghz %u, dur_non_2ghz %u\n",
1400 		    dur_2ghz, dur_non_2ghz);
1401 
1402 	role_2ghz->duration = dur_2ghz;
1403 	role_non_2ghz->duration = dur_non_2ghz;
1404 }
1405 
1406 static bool rtw89_mcc_duration_decision_on_bt(struct rtw89_dev *rtwdev)
1407 {
1408 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1409 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1410 	struct rtw89_mcc_role *aux = &mcc->role_aux;
1411 	struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role;
1412 
1413 	if (!bt_role->duration)
1414 		return false;
1415 
1416 	if (ref->is_2ghz && aux->is_2ghz) {
1417 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1418 			    "MCC dual roles are on 2GHz; consider BT duration\n");
1419 
1420 		rtw89_mcc_mod_duration_dual_2ghz_with_bt(rtwdev);
1421 		return true;
1422 	}
1423 
1424 	if (!ref->is_2ghz && !aux->is_2ghz) {
1425 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1426 			    "MCC dual roles are not on 2GHz; ignore BT duration\n");
1427 		return false;
1428 	}
1429 
1430 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1431 		    "MCC one role is on 2GHz; modify another for BT duration\n");
1432 
1433 	if (ref->is_2ghz)
1434 		rtw89_mcc_mod_duration_diff_band_with_bt(rtwdev, ref, aux);
1435 	else
1436 		rtw89_mcc_mod_duration_diff_band_with_bt(rtwdev, aux, ref);
1437 
1438 	return false;
1439 }
1440 
1441 static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev,
1442 				struct rtw89_mcc_role *tgt,
1443 				struct rtw89_mcc_role *src,
1444 				bool ref_is_src)
1445 {
1446 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1447 	struct rtw89_mcc_config *config = &mcc->config;
1448 	u16 beacon_offset_us = ieee80211_tu_to_usec(config->beacon_offset);
1449 	u32 bcn_intvl_src_us = ieee80211_tu_to_usec(src->beacon_interval);
1450 	u32 cur_tbtt_ofst_src;
1451 	u32 tsf_ofst_tgt;
1452 	u32 remainder;
1453 	u64 tbtt_tgt;
1454 	u64 tsf_src;
1455 	int ret;
1456 
1457 	ret = rtw89_mac_port_get_tsf(rtwdev, src->rtwvif_link, &tsf_src);
1458 	if (ret) {
1459 		rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
1460 		return;
1461 	}
1462 
1463 	cur_tbtt_ofst_src = rtw89_mcc_get_tbtt_ofst(rtwdev, src, tsf_src);
1464 
1465 	if (ref_is_src)
1466 		tbtt_tgt = tsf_src - cur_tbtt_ofst_src + beacon_offset_us;
1467 	else
1468 		tbtt_tgt = tsf_src - cur_tbtt_ofst_src +
1469 			   (bcn_intvl_src_us - beacon_offset_us);
1470 
1471 	div_u64_rem(tbtt_tgt, bcn_intvl_src_us, &remainder);
1472 	tsf_ofst_tgt = bcn_intvl_src_us - remainder;
1473 
1474 	config->sync.macid_tgt = tgt->rtwvif_link->mac_id;
1475 	config->sync.band_tgt = tgt->rtwvif_link->mac_idx;
1476 	config->sync.port_tgt = tgt->rtwvif_link->port;
1477 	config->sync.macid_src = src->rtwvif_link->mac_id;
1478 	config->sync.band_src = src->rtwvif_link->mac_idx;
1479 	config->sync.port_src = src->rtwvif_link->port;
1480 	config->sync.offset = tsf_ofst_tgt / 1024;
1481 	config->sync.enable = true;
1482 
1483 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1484 		    "MCC sync tbtt: tgt %d, src %d, offset %d\n",
1485 		    config->sync.macid_tgt, config->sync.macid_src,
1486 		    config->sync.offset);
1487 
1488 	rtw89_mac_port_tsf_sync(rtwdev, tgt->rtwvif_link, src->rtwvif_link,
1489 				config->sync.offset);
1490 }
1491 
1492 static int rtw89_mcc_fill_start_tsf(struct rtw89_dev *rtwdev)
1493 {
1494 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1495 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1496 	struct rtw89_mcc_config *config = &mcc->config;
1497 	u32 bcn_intvl_ref_us = ieee80211_tu_to_usec(ref->beacon_interval);
1498 	u32 tob_ref_us = ieee80211_tu_to_usec(config->pattern.tob_ref);
1499 	struct rtw89_vif_link *rtwvif_link = ref->rtwvif_link;
1500 	u64 tsf, start_tsf;
1501 	u32 cur_tbtt_ofst;
1502 	u64 min_time;
1503 	int ret;
1504 
1505 	ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
1506 	if (ret) {
1507 		rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
1508 		return ret;
1509 	}
1510 
1511 	min_time = tsf;
1512 	if (ref->is_go)
1513 		min_time += ieee80211_tu_to_usec(RTW89_MCC_SHORT_TRIGGER_TIME);
1514 	else
1515 		min_time += ieee80211_tu_to_usec(RTW89_MCC_LONG_TRIGGER_TIME);
1516 
1517 	cur_tbtt_ofst = rtw89_mcc_get_tbtt_ofst(rtwdev, ref, tsf);
1518 	start_tsf = tsf - cur_tbtt_ofst + bcn_intvl_ref_us - tob_ref_us;
1519 	while (start_tsf < min_time)
1520 		start_tsf += bcn_intvl_ref_us;
1521 
1522 	config->start_tsf = start_tsf;
1523 	return 0;
1524 }
1525 
1526 static int rtw89_mcc_fill_config(struct rtw89_dev *rtwdev)
1527 {
1528 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1529 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1530 	struct rtw89_mcc_role *aux = &mcc->role_aux;
1531 	struct rtw89_mcc_config *config = &mcc->config;
1532 	bool hdl_bt;
1533 	int ret;
1534 
1535 	memset(config, 0, sizeof(*config));
1536 
1537 	switch (mcc->mode) {
1538 	case RTW89_MCC_MODE_GO_STA:
1539 		config->beacon_offset = RTW89_MCC_DFLT_BCN_OFST_TIME;
1540 		if (ref->is_go) {
1541 			rtw89_mcc_sync_tbtt(rtwdev, ref, aux, false);
1542 			config->mcc_interval = ref->beacon_interval;
1543 			rtw89_mcc_set_duration_go_sta(rtwdev, ref, aux);
1544 		} else {
1545 			rtw89_mcc_sync_tbtt(rtwdev, aux, ref, true);
1546 			config->mcc_interval = aux->beacon_interval;
1547 			rtw89_mcc_set_duration_go_sta(rtwdev, aux, ref);
1548 		}
1549 		break;
1550 	case RTW89_MCC_MODE_GC_STA:
1551 		config->beacon_offset = rtw89_mcc_get_bcn_ofst(rtwdev);
1552 		config->mcc_interval = ref->beacon_interval;
1553 		rtw89_mcc_set_duration_gc_sta(rtwdev);
1554 		break;
1555 	default:
1556 		rtw89_warn(rtwdev, "MCC unknown mode: %d\n", mcc->mode);
1557 		return -EFAULT;
1558 	}
1559 
1560 	hdl_bt = rtw89_mcc_duration_decision_on_bt(rtwdev);
1561 	rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC handle bt: %d\n", hdl_bt);
1562 
1563 	ret = rtw89_mcc_calc_pattern(rtwdev, hdl_bt);
1564 	if (!ret)
1565 		goto bottom;
1566 
1567 	rtw89_mcc_set_default_pattern(rtwdev);
1568 
1569 bottom:
1570 	return rtw89_mcc_fill_start_tsf(rtwdev);
1571 }
1572 
1573 static int __mcc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role)
1574 {
1575 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1576 	struct rtw89_mcc_config *config = &mcc->config;
1577 	struct rtw89_mcc_pattern *pattern = &config->pattern;
1578 	struct rtw89_mcc_courtesy *courtesy = &pattern->courtesy;
1579 	struct rtw89_mcc_policy *policy = &role->policy;
1580 	struct rtw89_fw_mcc_add_req req = {};
1581 	const struct rtw89_chan *chan;
1582 	int ret;
1583 
1584 	chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx);
1585 	req.central_ch_seg0 = chan->channel;
1586 	req.primary_ch = chan->primary_channel;
1587 	req.bandwidth = chan->band_width;
1588 	req.ch_band_type = chan->band_type;
1589 
1590 	req.macid = role->rtwvif_link->mac_id;
1591 	req.group = mcc->group;
1592 	req.c2h_rpt = policy->c2h_rpt;
1593 	req.tx_null_early = policy->tx_null_early;
1594 	req.dis_tx_null = policy->dis_tx_null;
1595 	req.in_curr_ch = policy->in_curr_ch;
1596 	req.sw_retry_count = policy->sw_retry_count;
1597 	req.dis_sw_retry = policy->dis_sw_retry;
1598 	req.duration = role->duration;
1599 	req.btc_in_2g = false;
1600 
1601 	if (courtesy->enable && courtesy->macid_src == req.macid) {
1602 		req.courtesy_target = courtesy->macid_tgt;
1603 		req.courtesy_num = courtesy->slot_num;
1604 		req.courtesy_en = true;
1605 	}
1606 
1607 	ret = rtw89_fw_h2c_add_mcc(rtwdev, &req);
1608 	if (ret) {
1609 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1610 			    "MCC h2c failed to add wifi role: %d\n", ret);
1611 		return ret;
1612 	}
1613 
1614 	ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group,
1615 					    role->rtwvif_link->mac_id,
1616 					    role->macid_bitmap);
1617 	if (ret) {
1618 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1619 			    "MCC h2c failed to set macid bitmap: %d\n", ret);
1620 		return ret;
1621 	}
1622 
1623 	return 0;
1624 }
1625 
1626 static
1627 void __mrc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role,
1628 		       struct rtw89_fw_mrc_add_arg *arg, u8 slot_idx)
1629 {
1630 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1631 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1632 	struct rtw89_mcc_policy *policy = &role->policy;
1633 	struct rtw89_fw_mrc_add_slot_arg *slot_arg;
1634 	const struct rtw89_chan *chan;
1635 
1636 	slot_arg = &arg->slots[slot_idx];
1637 	role->slot_idx = slot_idx;
1638 
1639 	slot_arg->duration = role->duration;
1640 	slot_arg->role_num = 1;
1641 
1642 	chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx);
1643 
1644 	slot_arg->roles[0].role_type = RTW89_H2C_MRC_ROLE_WIFI;
1645 	slot_arg->roles[0].is_master = role == ref;
1646 	slot_arg->roles[0].band = chan->band_type;
1647 	slot_arg->roles[0].bw = chan->band_width;
1648 	slot_arg->roles[0].central_ch = chan->channel;
1649 	slot_arg->roles[0].primary_ch = chan->primary_channel;
1650 	slot_arg->roles[0].en_tx_null = !policy->dis_tx_null;
1651 	slot_arg->roles[0].null_early = policy->tx_null_early;
1652 	slot_arg->roles[0].macid = role->rtwvif_link->mac_id;
1653 	slot_arg->roles[0].macid_main_bitmap =
1654 		rtw89_mcc_role_fw_macid_bitmap_to_u32(role);
1655 }
1656 
1657 static int __mcc_fw_add_bt_role(struct rtw89_dev *rtwdev)
1658 {
1659 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1660 	struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role;
1661 	struct rtw89_fw_mcc_add_req req = {};
1662 	int ret;
1663 
1664 	req.group = mcc->group;
1665 	req.duration = bt_role->duration;
1666 	req.btc_in_2g = true;
1667 
1668 	ret = rtw89_fw_h2c_add_mcc(rtwdev, &req);
1669 	if (ret) {
1670 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1671 			    "MCC h2c failed to add bt role: %d\n", ret);
1672 		return ret;
1673 	}
1674 
1675 	return 0;
1676 }
1677 
1678 static
1679 void __mrc_fw_add_bt_role(struct rtw89_dev *rtwdev,
1680 			  struct rtw89_fw_mrc_add_arg *arg, u8 slot_idx)
1681 {
1682 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1683 	struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role;
1684 	struct rtw89_fw_mrc_add_slot_arg *slot_arg = &arg->slots[slot_idx];
1685 
1686 	slot_arg->duration = bt_role->duration;
1687 	slot_arg->role_num = 1;
1688 
1689 	slot_arg->roles[0].role_type = RTW89_H2C_MRC_ROLE_BT;
1690 }
1691 
1692 static int __mcc_fw_start(struct rtw89_dev *rtwdev, bool replace)
1693 {
1694 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1695 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1696 	struct rtw89_mcc_role *aux = &mcc->role_aux;
1697 	struct rtw89_mcc_config *config = &mcc->config;
1698 	struct rtw89_mcc_pattern *pattern = &config->pattern;
1699 	struct rtw89_mcc_sync *sync = &config->sync;
1700 	struct rtw89_fw_mcc_start_req req = {};
1701 	int ret;
1702 
1703 	if (replace) {
1704 		req.old_group = mcc->group;
1705 		req.old_group_action = RTW89_FW_MCC_OLD_GROUP_ACT_REPLACE;
1706 		mcc->group = RTW89_MCC_NEXT_GROUP(mcc->group);
1707 	}
1708 
1709 	req.group = mcc->group;
1710 
1711 	switch (pattern->plan) {
1712 	case RTW89_MCC_PLAN_TAIL_BT:
1713 		ret = __mcc_fw_add_role(rtwdev, ref);
1714 		if (ret)
1715 			return ret;
1716 		ret = __mcc_fw_add_role(rtwdev, aux);
1717 		if (ret)
1718 			return ret;
1719 		ret = __mcc_fw_add_bt_role(rtwdev);
1720 		if (ret)
1721 			return ret;
1722 
1723 		req.btc_in_group = true;
1724 		break;
1725 	case RTW89_MCC_PLAN_MID_BT:
1726 		ret = __mcc_fw_add_role(rtwdev, ref);
1727 		if (ret)
1728 			return ret;
1729 		ret = __mcc_fw_add_bt_role(rtwdev);
1730 		if (ret)
1731 			return ret;
1732 		ret = __mcc_fw_add_role(rtwdev, aux);
1733 		if (ret)
1734 			return ret;
1735 
1736 		req.btc_in_group = true;
1737 		break;
1738 	case RTW89_MCC_PLAN_NO_BT:
1739 		ret = __mcc_fw_add_role(rtwdev, ref);
1740 		if (ret)
1741 			return ret;
1742 		ret = __mcc_fw_add_role(rtwdev, aux);
1743 		if (ret)
1744 			return ret;
1745 
1746 		req.btc_in_group = false;
1747 		break;
1748 	default:
1749 		rtw89_warn(rtwdev, "MCC unknown plan: %d\n", pattern->plan);
1750 		return -EFAULT;
1751 	}
1752 
1753 	if (sync->enable) {
1754 		ret = rtw89_fw_h2c_mcc_sync(rtwdev, req.group, sync->macid_src,
1755 					    sync->macid_tgt, sync->offset);
1756 		if (ret) {
1757 			rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1758 				    "MCC h2c failed to trigger sync: %d\n", ret);
1759 			return ret;
1760 		}
1761 	}
1762 
1763 	req.macid = ref->rtwvif_link->mac_id;
1764 	req.tsf_high = config->start_tsf >> 32;
1765 	req.tsf_low = config->start_tsf;
1766 
1767 	ret = rtw89_fw_h2c_start_mcc(rtwdev, &req);
1768 	if (ret) {
1769 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1770 			    "MCC h2c failed to trigger start: %d\n", ret);
1771 		return ret;
1772 	}
1773 
1774 	return 0;
1775 }
1776 
1777 static void __mrc_fw_add_courtesy(struct rtw89_dev *rtwdev,
1778 				  struct rtw89_fw_mrc_add_arg *arg)
1779 {
1780 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1781 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1782 	struct rtw89_mcc_role *aux = &mcc->role_aux;
1783 	struct rtw89_mcc_config *config = &mcc->config;
1784 	struct rtw89_mcc_pattern *pattern = &config->pattern;
1785 	struct rtw89_mcc_courtesy *courtesy = &pattern->courtesy;
1786 	struct rtw89_fw_mrc_add_slot_arg *slot_arg_src;
1787 	u8 slot_idx_tgt;
1788 
1789 	if (!courtesy->enable)
1790 		return;
1791 
1792 	if (courtesy->macid_src == ref->rtwvif_link->mac_id) {
1793 		slot_arg_src = &arg->slots[ref->slot_idx];
1794 		slot_idx_tgt = aux->slot_idx;
1795 	} else {
1796 		slot_arg_src = &arg->slots[aux->slot_idx];
1797 		slot_idx_tgt = ref->slot_idx;
1798 	}
1799 
1800 	slot_arg_src->courtesy_target = slot_idx_tgt;
1801 	slot_arg_src->courtesy_period = courtesy->slot_num;
1802 	slot_arg_src->courtesy_en = true;
1803 }
1804 
1805 static int __mrc_fw_start(struct rtw89_dev *rtwdev, bool replace)
1806 {
1807 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1808 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1809 	struct rtw89_mcc_role *aux = &mcc->role_aux;
1810 	struct rtw89_mcc_config *config = &mcc->config;
1811 	struct rtw89_mcc_pattern *pattern = &config->pattern;
1812 	struct rtw89_mcc_sync *sync = &config->sync;
1813 	struct rtw89_fw_mrc_start_arg start_arg = {};
1814 	struct rtw89_fw_mrc_add_arg add_arg = {};
1815 	int ret;
1816 
1817 	BUILD_BUG_ON(RTW89_MAC_MRC_MAX_ADD_SLOT_NUM <
1818 		     NUM_OF_RTW89_MCC_ROLES + 1 /* bt role */);
1819 
1820 	if (replace) {
1821 		start_arg.old_sch_idx = mcc->group;
1822 		start_arg.action = RTW89_H2C_MRC_START_ACTION_REPLACE_OLD;
1823 		mcc->group = RTW89_MCC_NEXT_GROUP(mcc->group);
1824 	}
1825 
1826 	add_arg.sch_idx = mcc->group;
1827 	add_arg.sch_type = RTW89_H2C_MRC_SCH_BAND0_ONLY;
1828 
1829 	switch (pattern->plan) {
1830 	case RTW89_MCC_PLAN_TAIL_BT:
1831 		__mrc_fw_add_role(rtwdev, ref, &add_arg, 0);
1832 		__mrc_fw_add_role(rtwdev, aux, &add_arg, 1);
1833 		__mrc_fw_add_bt_role(rtwdev, &add_arg, 2);
1834 
1835 		add_arg.slot_num = 3;
1836 		add_arg.btc_in_sch = true;
1837 		break;
1838 	case RTW89_MCC_PLAN_MID_BT:
1839 		__mrc_fw_add_role(rtwdev, ref, &add_arg, 0);
1840 		__mrc_fw_add_bt_role(rtwdev, &add_arg, 1);
1841 		__mrc_fw_add_role(rtwdev, aux, &add_arg, 2);
1842 
1843 		add_arg.slot_num = 3;
1844 		add_arg.btc_in_sch = true;
1845 		break;
1846 	case RTW89_MCC_PLAN_NO_BT:
1847 		__mrc_fw_add_role(rtwdev, ref, &add_arg, 0);
1848 		__mrc_fw_add_role(rtwdev, aux, &add_arg, 1);
1849 
1850 		add_arg.slot_num = 2;
1851 		add_arg.btc_in_sch = false;
1852 		break;
1853 	default:
1854 		rtw89_warn(rtwdev, "MCC unknown plan: %d\n", pattern->plan);
1855 		return -EFAULT;
1856 	}
1857 
1858 	__mrc_fw_add_courtesy(rtwdev, &add_arg);
1859 
1860 	ret = rtw89_fw_h2c_mrc_add(rtwdev, &add_arg);
1861 	if (ret) {
1862 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1863 			    "MRC h2c failed to trigger add: %d\n", ret);
1864 		return ret;
1865 	}
1866 
1867 	if (sync->enable) {
1868 		struct rtw89_fw_mrc_sync_arg sync_arg = {
1869 			.offset = sync->offset,
1870 			.src = {
1871 				.band = sync->band_src,
1872 				.port = sync->port_src,
1873 			},
1874 			.dest = {
1875 				.band = sync->band_tgt,
1876 				.port = sync->port_tgt,
1877 			},
1878 		};
1879 
1880 		ret = rtw89_fw_h2c_mrc_sync(rtwdev, &sync_arg);
1881 		if (ret) {
1882 			rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1883 				    "MRC h2c failed to trigger sync: %d\n", ret);
1884 			return ret;
1885 		}
1886 	}
1887 
1888 	start_arg.sch_idx = mcc->group;
1889 	start_arg.start_tsf = config->start_tsf;
1890 
1891 	ret = rtw89_fw_h2c_mrc_start(rtwdev, &start_arg);
1892 	if (ret) {
1893 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1894 			    "MRC h2c failed to trigger start: %d\n", ret);
1895 		return ret;
1896 	}
1897 
1898 	return 0;
1899 }
1900 
1901 static int __mcc_fw_set_duration_no_bt(struct rtw89_dev *rtwdev, bool sync_changed)
1902 {
1903 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1904 	struct rtw89_mcc_config *config = &mcc->config;
1905 	struct rtw89_mcc_sync *sync = &config->sync;
1906 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1907 	struct rtw89_mcc_role *aux = &mcc->role_aux;
1908 	struct rtw89_fw_mcc_duration req = {
1909 		.group = mcc->group,
1910 		.btc_in_group = false,
1911 		.start_macid = ref->rtwvif_link->mac_id,
1912 		.macid_x = ref->rtwvif_link->mac_id,
1913 		.macid_y = aux->rtwvif_link->mac_id,
1914 		.duration_x = ref->duration,
1915 		.duration_y = aux->duration,
1916 		.start_tsf_high = config->start_tsf >> 32,
1917 		.start_tsf_low = config->start_tsf,
1918 	};
1919 	int ret;
1920 
1921 	ret = rtw89_fw_h2c_mcc_set_duration(rtwdev, &req);
1922 	if (ret) {
1923 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1924 			    "MCC h2c failed to set duration: %d\n", ret);
1925 		return ret;
1926 	}
1927 
1928 	if (!sync->enable || !sync_changed)
1929 		return 0;
1930 
1931 	ret = rtw89_fw_h2c_mcc_sync(rtwdev, mcc->group, sync->macid_src,
1932 				    sync->macid_tgt, sync->offset);
1933 	if (ret) {
1934 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1935 			    "MCC h2c failed to trigger sync: %d\n", ret);
1936 		return ret;
1937 	}
1938 
1939 	return 0;
1940 }
1941 
1942 static int __mrc_fw_set_duration_no_bt(struct rtw89_dev *rtwdev, bool sync_changed)
1943 {
1944 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1945 	struct rtw89_mcc_config *config = &mcc->config;
1946 	struct rtw89_mcc_sync *sync = &config->sync;
1947 	struct rtw89_mcc_role *ref = &mcc->role_ref;
1948 	struct rtw89_mcc_role *aux = &mcc->role_aux;
1949 	struct rtw89_fw_mrc_upd_duration_arg dur_arg = {
1950 		.sch_idx = mcc->group,
1951 		.start_tsf = config->start_tsf,
1952 		.slot_num = 2,
1953 		.slots[0] = {
1954 			.slot_idx = ref->slot_idx,
1955 			.duration = ref->duration,
1956 		},
1957 		.slots[1] = {
1958 			.slot_idx = aux->slot_idx,
1959 			.duration = aux->duration,
1960 		},
1961 	};
1962 	struct rtw89_fw_mrc_sync_arg sync_arg = {
1963 		.offset = sync->offset,
1964 		.src = {
1965 			.band = sync->band_src,
1966 			.port = sync->port_src,
1967 		},
1968 		.dest = {
1969 			.band = sync->band_tgt,
1970 			.port = sync->port_tgt,
1971 		},
1972 
1973 	};
1974 	int ret;
1975 
1976 	ret = rtw89_fw_h2c_mrc_upd_duration(rtwdev, &dur_arg);
1977 	if (ret) {
1978 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1979 			    "MRC h2c failed to update duration: %d\n", ret);
1980 		return ret;
1981 	}
1982 
1983 	if (!sync->enable || !sync_changed)
1984 		return 0;
1985 
1986 	ret = rtw89_fw_h2c_mrc_sync(rtwdev, &sync_arg);
1987 	if (ret) {
1988 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
1989 			    "MRC h2c failed to trigger sync: %d\n", ret);
1990 		return ret;
1991 	}
1992 
1993 	return 0;
1994 }
1995 
1996 static void rtw89_mcc_handle_beacon_noa(struct rtw89_dev *rtwdev, bool enable)
1997 {
1998 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
1999 	struct rtw89_mcc_role *ref = &mcc->role_ref;
2000 	struct rtw89_mcc_role *aux = &mcc->role_aux;
2001 	struct rtw89_mcc_config *config = &mcc->config;
2002 	struct rtw89_mcc_pattern *pattern = &config->pattern;
2003 	struct rtw89_mcc_sync *sync = &config->sync;
2004 	struct ieee80211_p2p_noa_desc noa_desc = {};
2005 	u64 start_time = config->start_tsf;
2006 	u32 interval = config->mcc_interval;
2007 	struct rtw89_vif_link *rtwvif_go;
2008 	u32 duration;
2009 
2010 	if (mcc->mode != RTW89_MCC_MODE_GO_STA)
2011 		return;
2012 
2013 	if (ref->is_go) {
2014 		rtwvif_go = ref->rtwvif_link;
2015 		start_time += ieee80211_tu_to_usec(ref->duration);
2016 		duration = config->mcc_interval - ref->duration;
2017 	} else if (aux->is_go) {
2018 		rtwvif_go = aux->rtwvif_link;
2019 		start_time += ieee80211_tu_to_usec(pattern->tob_ref) +
2020 			      ieee80211_tu_to_usec(config->beacon_offset) +
2021 			      ieee80211_tu_to_usec(pattern->toa_aux);
2022 		duration = config->mcc_interval - aux->duration;
2023 
2024 		/* convert time domain from sta(ref) to GO(aux) */
2025 		start_time += ieee80211_tu_to_usec(sync->offset);
2026 	} else {
2027 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
2028 			    "MCC find no GO: skip updating beacon NoA\n");
2029 		return;
2030 	}
2031 
2032 	rtw89_p2p_noa_renew(rtwvif_go);
2033 
2034 	if (enable) {
2035 		noa_desc.start_time = cpu_to_le32(start_time);
2036 		noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(interval));
2037 		noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(duration));
2038 		noa_desc.count = 255;
2039 		rtw89_p2p_noa_append(rtwvif_go, &noa_desc);
2040 	}
2041 
2042 	/* without chanctx, we cannot get beacon from mac80211 stack */
2043 	if (!rtwvif_go->chanctx_assigned)
2044 		return;
2045 
2046 	rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_go);
2047 }
2048 
2049 static void rtw89_mcc_start_beacon_noa(struct rtw89_dev *rtwdev)
2050 {
2051 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
2052 	struct rtw89_mcc_role *ref = &mcc->role_ref;
2053 	struct rtw89_mcc_role *aux = &mcc->role_aux;
2054 
2055 	if (mcc->mode != RTW89_MCC_MODE_GO_STA)
2056 		return;
2057 
2058 	if (ref->is_go)
2059 		rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, true);
2060 	else if (aux->is_go)
2061 		rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, true);
2062 
2063 	rtw89_mcc_handle_beacon_noa(rtwdev, true);
2064 }
2065 
2066 static void rtw89_mcc_stop_beacon_noa(struct rtw89_dev *rtwdev)
2067 {
2068 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
2069 	struct rtw89_mcc_role *ref = &mcc->role_ref;
2070 	struct rtw89_mcc_role *aux = &mcc->role_aux;
2071 
2072 	if (mcc->mode != RTW89_MCC_MODE_GO_STA)
2073 		return;
2074 
2075 	if (ref->is_go)
2076 		rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, false);
2077 	else if (aux->is_go)
2078 		rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, false);
2079 
2080 	rtw89_mcc_handle_beacon_noa(rtwdev, false);
2081 }
2082 
2083 static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
2084 {
2085 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
2086 	struct rtw89_mcc_role *ref = &mcc->role_ref;
2087 	struct rtw89_mcc_role *aux = &mcc->role_aux;
2088 	int ret;
2089 
2090 	if (rtwdev->scanning)
2091 		rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
2092 
2093 	rtw89_leave_lps(rtwdev);
2094 
2095 	rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC start\n");
2096 
2097 	ret = rtw89_mcc_fill_all_roles(rtwdev);
2098 	if (ret)
2099 		return ret;
2100 
2101 	if (ref->is_go || aux->is_go)
2102 		mcc->mode = RTW89_MCC_MODE_GO_STA;
2103 	else
2104 		mcc->mode = RTW89_MCC_MODE_GC_STA;
2105 
2106 	rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC sel mode: %d\n", mcc->mode);
2107 
2108 	mcc->group = RTW89_MCC_DFLT_GROUP;
2109 
2110 	ret = rtw89_mcc_fill_config(rtwdev);
2111 	if (ret)
2112 		return ret;
2113 
2114 	if (rtw89_concurrent_via_mrc(rtwdev))
2115 		ret = __mrc_fw_start(rtwdev, false);
2116 	else
2117 		ret = __mcc_fw_start(rtwdev, false);
2118 
2119 	if (ret)
2120 		return ret;
2121 
2122 	rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_START);
2123 
2124 	rtw89_mcc_start_beacon_noa(rtwdev);
2125 	return 0;
2126 }
2127 
2128 struct rtw89_mcc_stop_sel {
2129 	u8 mac_id;
2130 	u8 slot_idx;
2131 };
2132 
2133 static void rtw89_mcc_stop_sel_fill(struct rtw89_mcc_stop_sel *sel,
2134 				    const struct rtw89_mcc_role *mcc_role)
2135 {
2136 	sel->mac_id = mcc_role->rtwvif_link->mac_id;
2137 	sel->slot_idx = mcc_role->slot_idx;
2138 }
2139 
2140 static int rtw89_mcc_stop_sel_iterator(struct rtw89_dev *rtwdev,
2141 				       struct rtw89_mcc_role *mcc_role,
2142 				       unsigned int ordered_idx,
2143 				       void *data)
2144 {
2145 	struct rtw89_mcc_stop_sel *sel = data;
2146 
2147 	if (!mcc_role->rtwvif_link->chanctx_assigned)
2148 		return 0;
2149 
2150 	rtw89_mcc_stop_sel_fill(sel, mcc_role);
2151 	return 1; /* break iteration */
2152 }
2153 
2154 static void rtw89_mcc_stop(struct rtw89_dev *rtwdev)
2155 {
2156 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
2157 	struct rtw89_mcc_role *ref = &mcc->role_ref;
2158 	struct rtw89_mcc_stop_sel sel;
2159 	int ret;
2160 
2161 	/* by default, stop at ref */
2162 	rtw89_mcc_stop_sel_fill(&sel, ref);
2163 	rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_stop_sel_iterator, &sel);
2164 
2165 	rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC stop at <macid %d>\n", sel.mac_id);
2166 
2167 	if (rtw89_concurrent_via_mrc(rtwdev)) {
2168 		ret = rtw89_fw_h2c_mrc_del(rtwdev, mcc->group, sel.slot_idx);
2169 		if (ret)
2170 			rtw89_debug(rtwdev, RTW89_DBG_CHAN,
2171 				    "MRC h2c failed to trigger del: %d\n", ret);
2172 	} else {
2173 		ret = rtw89_fw_h2c_stop_mcc(rtwdev, mcc->group,
2174 					    sel.mac_id, true);
2175 		if (ret)
2176 			rtw89_debug(rtwdev, RTW89_DBG_CHAN,
2177 				    "MCC h2c failed to trigger stop: %d\n", ret);
2178 
2179 		ret = rtw89_fw_h2c_del_mcc_group(rtwdev, mcc->group, true);
2180 		if (ret)
2181 			rtw89_debug(rtwdev, RTW89_DBG_CHAN,
2182 				    "MCC h2c failed to delete group: %d\n", ret);
2183 	}
2184 
2185 	rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_STOP);
2186 
2187 	rtw89_mcc_stop_beacon_noa(rtwdev);
2188 }
2189 
2190 static int rtw89_mcc_update(struct rtw89_dev *rtwdev)
2191 {
2192 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
2193 	struct rtw89_mcc_config *config = &mcc->config;
2194 	struct rtw89_mcc_config old_cfg = *config;
2195 	bool sync_changed;
2196 	int ret;
2197 
2198 	if (rtwdev->scanning)
2199 		rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
2200 
2201 	rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC update\n");
2202 
2203 	ret = rtw89_mcc_fill_config(rtwdev);
2204 	if (ret)
2205 		return ret;
2206 
2207 	if (old_cfg.pattern.plan != RTW89_MCC_PLAN_NO_BT ||
2208 	    config->pattern.plan != RTW89_MCC_PLAN_NO_BT) {
2209 		if (rtw89_concurrent_via_mrc(rtwdev))
2210 			ret = __mrc_fw_start(rtwdev, true);
2211 		else
2212 			ret = __mcc_fw_start(rtwdev, true);
2213 
2214 		if (ret)
2215 			return ret;
2216 	} else {
2217 		if (memcmp(&old_cfg.sync, &config->sync, sizeof(old_cfg.sync)) == 0)
2218 			sync_changed = false;
2219 		else
2220 			sync_changed = true;
2221 
2222 		if (rtw89_concurrent_via_mrc(rtwdev))
2223 			ret = __mrc_fw_set_duration_no_bt(rtwdev, sync_changed);
2224 		else
2225 			ret = __mcc_fw_set_duration_no_bt(rtwdev, sync_changed);
2226 
2227 		if (ret)
2228 			return ret;
2229 	}
2230 
2231 	rtw89_mcc_handle_beacon_noa(rtwdev, true);
2232 	return 0;
2233 }
2234 
2235 static void rtw89_mcc_track(struct rtw89_dev *rtwdev)
2236 {
2237 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
2238 	struct rtw89_mcc_config *config = &mcc->config;
2239 	struct rtw89_mcc_pattern *pattern = &config->pattern;
2240 	s16 tolerance;
2241 	u16 bcn_ofst;
2242 	u16 diff;
2243 
2244 	if (mcc->mode != RTW89_MCC_MODE_GC_STA)
2245 		return;
2246 
2247 	bcn_ofst = rtw89_mcc_get_bcn_ofst(rtwdev);
2248 	if (bcn_ofst > config->beacon_offset) {
2249 		diff = bcn_ofst - config->beacon_offset;
2250 		if (pattern->tob_aux < 0)
2251 			tolerance = -pattern->tob_aux;
2252 		else
2253 			tolerance = pattern->toa_aux;
2254 	} else {
2255 		diff = config->beacon_offset - bcn_ofst;
2256 		if (pattern->toa_aux < 0)
2257 			tolerance = -pattern->toa_aux;
2258 		else
2259 			tolerance = pattern->tob_aux;
2260 	}
2261 
2262 	if (diff <= tolerance)
2263 		return;
2264 
2265 	rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_BCN_OFFSET_CHANGE);
2266 }
2267 
2268 static int __mcc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev,
2269 				     struct rtw89_mcc_role *upd)
2270 {
2271 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
2272 	int ret;
2273 
2274 	ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group,
2275 					    upd->rtwvif_link->mac_id,
2276 					    upd->macid_bitmap);
2277 	if (ret) {
2278 		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
2279 			    "MCC h2c failed to update macid bitmap: %d\n", ret);
2280 		return ret;
2281 	}
2282 
2283 	return 0;
2284 }
2285 
2286 static int __mrc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev,
2287 				     struct rtw89_mcc_role *cur,
2288 				     struct rtw89_mcc_role *upd)
2289 {
2290 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
2291 	struct rtw89_fw_mrc_upd_bitmap_arg arg = {};
2292 	u32 old = rtw89_mcc_role_fw_macid_bitmap_to_u32(cur);
2293 	u32 new = rtw89_mcc_role_fw_macid_bitmap_to_u32(upd);
2294 	u32 add = new & ~old;
2295 	u32 del = old & ~new;
2296 	int ret;
2297 	int i;
2298 
2299 	arg.sch_idx = mcc->group;
2300 	arg.macid = upd->rtwvif_link->mac_id;
2301 
2302 	for (i = 0; i < 32; i++) {
2303 		if (add & BIT(i)) {
2304 			arg.client_macid = i;
2305 			arg.action = RTW89_H2C_MRC_UPD_BITMAP_ACTION_ADD;
2306 
2307 			ret = rtw89_fw_h2c_mrc_upd_bitmap(rtwdev, &arg);
2308 			if (ret)
2309 				goto err;
2310 		}
2311 	}
2312 
2313 	for (i = 0; i < 32; i++) {
2314 		if (del & BIT(i)) {
2315 			arg.client_macid = i;
2316 			arg.action = RTW89_H2C_MRC_UPD_BITMAP_ACTION_DEL;
2317 
2318 			ret = rtw89_fw_h2c_mrc_upd_bitmap(rtwdev, &arg);
2319 			if (ret)
2320 				goto err;
2321 		}
2322 	}
2323 
2324 	return 0;
2325 
2326 err:
2327 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
2328 		    "MRC h2c failed to update bitmap: %d\n", ret);
2329 	return ret;
2330 }
2331 
2332 static int rtw89_mcc_upd_map_iterator(struct rtw89_dev *rtwdev,
2333 				      struct rtw89_mcc_role *mcc_role,
2334 				      unsigned int ordered_idx,
2335 				      void *data)
2336 {
2337 	struct rtw89_mcc_role upd = {
2338 		.rtwvif_link = mcc_role->rtwvif_link,
2339 	};
2340 	int ret;
2341 
2342 	if (!mcc_role->is_go)
2343 		return 0;
2344 
2345 	rtw89_mcc_fill_role_macid_bitmap(rtwdev, &upd);
2346 	if (memcmp(mcc_role->macid_bitmap, upd.macid_bitmap,
2347 		   sizeof(mcc_role->macid_bitmap)) == 0)
2348 		return 0;
2349 
2350 	if (rtw89_concurrent_via_mrc(rtwdev))
2351 		ret = __mrc_fw_upd_macid_bitmap(rtwdev, mcc_role, &upd);
2352 	else
2353 		ret = __mcc_fw_upd_macid_bitmap(rtwdev, &upd);
2354 
2355 	if (ret)
2356 		return ret;
2357 
2358 	memcpy(mcc_role->macid_bitmap, upd.macid_bitmap,
2359 	       sizeof(mcc_role->macid_bitmap));
2360 	return 0;
2361 }
2362 
2363 static void rtw89_mcc_update_macid_bitmap(struct rtw89_dev *rtwdev)
2364 {
2365 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
2366 
2367 	if (mcc->mode != RTW89_MCC_MODE_GO_STA)
2368 		return;
2369 
2370 	rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_upd_map_iterator, NULL);
2371 }
2372 
2373 static int rtw89_mcc_upd_lmt_iterator(struct rtw89_dev *rtwdev,
2374 				      struct rtw89_mcc_role *mcc_role,
2375 				      unsigned int ordered_idx,
2376 				      void *data)
2377 {
2378 	memset(&mcc_role->limit, 0, sizeof(mcc_role->limit));
2379 	rtw89_mcc_fill_role_limit(rtwdev, mcc_role);
2380 	return 0;
2381 }
2382 
2383 static void rtw89_mcc_update_limit(struct rtw89_dev *rtwdev)
2384 {
2385 	struct rtw89_mcc_info *mcc = &rtwdev->mcc;
2386 
2387 	if (mcc->mode != RTW89_MCC_MODE_GC_STA)
2388 		return;
2389 
2390 	rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_upd_lmt_iterator, NULL);
2391 }
2392 
2393 void rtw89_chanctx_work(struct work_struct *work)
2394 {
2395 	struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
2396 						chanctx_work.work);
2397 	struct rtw89_hal *hal = &rtwdev->hal;
2398 	bool update_mcc_pattern = false;
2399 	enum rtw89_entity_mode mode;
2400 	u32 changed = 0;
2401 	int ret;
2402 	int i;
2403 
2404 	mutex_lock(&rtwdev->mutex);
2405 
2406 	if (hal->entity_pause) {
2407 		mutex_unlock(&rtwdev->mutex);
2408 		return;
2409 	}
2410 
2411 	for (i = 0; i < NUM_OF_RTW89_CHANCTX_CHANGES; i++) {
2412 		if (test_and_clear_bit(i, hal->changes))
2413 			changed |= BIT(i);
2414 	}
2415 
2416 	mode = rtw89_get_entity_mode(rtwdev);
2417 	switch (mode) {
2418 	case RTW89_ENTITY_MODE_MCC_PREPARE:
2419 		rtw89_set_entity_mode(rtwdev, RTW89_ENTITY_MODE_MCC);
2420 		rtw89_set_channel(rtwdev);
2421 
2422 		ret = rtw89_mcc_start(rtwdev);
2423 		if (ret)
2424 			rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret);
2425 		break;
2426 	case RTW89_ENTITY_MODE_MCC:
2427 		if (changed & BIT(RTW89_CHANCTX_BCN_OFFSET_CHANGE) ||
2428 		    changed & BIT(RTW89_CHANCTX_P2P_PS_CHANGE) ||
2429 		    changed & BIT(RTW89_CHANCTX_BT_SLOT_CHANGE) ||
2430 		    changed & BIT(RTW89_CHANCTX_TSF32_TOGGLE_CHANGE))
2431 			update_mcc_pattern = true;
2432 		if (changed & BIT(RTW89_CHANCTX_REMOTE_STA_CHANGE))
2433 			rtw89_mcc_update_macid_bitmap(rtwdev);
2434 		if (changed & BIT(RTW89_CHANCTX_P2P_PS_CHANGE))
2435 			rtw89_mcc_update_limit(rtwdev);
2436 		if (changed & BIT(RTW89_CHANCTX_BT_SLOT_CHANGE))
2437 			rtw89_mcc_fill_bt_role(rtwdev);
2438 		if (update_mcc_pattern) {
2439 			ret = rtw89_mcc_update(rtwdev);
2440 			if (ret)
2441 				rtw89_warn(rtwdev, "failed to update MCC: %d\n",
2442 					   ret);
2443 		}
2444 		break;
2445 	default:
2446 		break;
2447 	}
2448 
2449 	mutex_unlock(&rtwdev->mutex);
2450 }
2451 
2452 void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
2453 				enum rtw89_chanctx_changes change)
2454 {
2455 	struct rtw89_hal *hal = &rtwdev->hal;
2456 	enum rtw89_entity_mode mode;
2457 	u32 delay;
2458 
2459 	mode = rtw89_get_entity_mode(rtwdev);
2460 	switch (mode) {
2461 	default:
2462 		return;
2463 	case RTW89_ENTITY_MODE_MCC_PREPARE:
2464 		delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC_PREPARE);
2465 		break;
2466 	case RTW89_ENTITY_MODE_MCC:
2467 		delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC);
2468 		break;
2469 	}
2470 
2471 	if (change != RTW89_CHANCTX_CHANGE_DFLT) {
2472 		rtw89_debug(rtwdev, RTW89_DBG_CHAN, "set chanctx change %d\n",
2473 			    change);
2474 		set_bit(change, hal->changes);
2475 	}
2476 
2477 	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
2478 		    "queue chanctx work for mode %d with delay %d us\n",
2479 		    mode, delay);
2480 	ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->chanctx_work,
2481 				     usecs_to_jiffies(delay));
2482 }
2483 
2484 void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev)
2485 {
2486 	rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_CHANGE_DFLT);
2487 }
2488 
2489 void rtw89_chanctx_track(struct rtw89_dev *rtwdev)
2490 {
2491 	struct rtw89_hal *hal = &rtwdev->hal;
2492 	enum rtw89_entity_mode mode;
2493 
2494 	lockdep_assert_held(&rtwdev->mutex);
2495 
2496 	if (hal->entity_pause)
2497 		return;
2498 
2499 	mode = rtw89_get_entity_mode(rtwdev);
2500 	switch (mode) {
2501 	case RTW89_ENTITY_MODE_MCC:
2502 		rtw89_mcc_track(rtwdev);
2503 		break;
2504 	default:
2505 		break;
2506 	}
2507 }
2508 
2509 void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
2510 			 enum rtw89_chanctx_pause_reasons rsn)
2511 {
2512 	struct rtw89_hal *hal = &rtwdev->hal;
2513 	enum rtw89_entity_mode mode;
2514 
2515 	lockdep_assert_held(&rtwdev->mutex);
2516 
2517 	if (hal->entity_pause)
2518 		return;
2519 
2520 	rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx pause (rsn: %d)\n", rsn);
2521 
2522 	mode = rtw89_get_entity_mode(rtwdev);
2523 	switch (mode) {
2524 	case RTW89_ENTITY_MODE_MCC:
2525 		rtw89_mcc_stop(rtwdev);
2526 		break;
2527 	default:
2528 		break;
2529 	}
2530 
2531 	hal->entity_pause = true;
2532 }
2533 
2534 static void rtw89_chanctx_proceed_cb(struct rtw89_dev *rtwdev,
2535 				     const struct rtw89_chanctx_cb_parm *parm)
2536 {
2537 	int ret;
2538 
2539 	if (!parm || !parm->cb)
2540 		return;
2541 
2542 	ret = parm->cb(rtwdev, parm->data);
2543 	if (ret)
2544 		rtw89_warn(rtwdev, "%s (%s): cb failed: %d\n", __func__,
2545 			   parm->caller ?: "unknown", ret);
2546 }
2547 
2548 /* pass @cb_parm if there is a @cb_parm->cb which needs to invoke right after
2549  * call rtw89_set_channel() and right before proceed entity according to mode.
2550  */
2551 void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev,
2552 			   const struct rtw89_chanctx_cb_parm *cb_parm)
2553 {
2554 	struct rtw89_hal *hal = &rtwdev->hal;
2555 	enum rtw89_entity_mode mode;
2556 	int ret;
2557 
2558 	lockdep_assert_held(&rtwdev->mutex);
2559 
2560 	if (unlikely(!hal->entity_pause)) {
2561 		rtw89_chanctx_proceed_cb(rtwdev, cb_parm);
2562 		return;
2563 	}
2564 
2565 	rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx proceed\n");
2566 
2567 	hal->entity_pause = false;
2568 	rtw89_set_channel(rtwdev);
2569 
2570 	rtw89_chanctx_proceed_cb(rtwdev, cb_parm);
2571 
2572 	mode = rtw89_get_entity_mode(rtwdev);
2573 	switch (mode) {
2574 	case RTW89_ENTITY_MODE_MCC:
2575 		ret = rtw89_mcc_start(rtwdev);
2576 		if (ret)
2577 			rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret);
2578 		break;
2579 	default:
2580 		break;
2581 	}
2582 
2583 	rtw89_queue_chanctx_work(rtwdev);
2584 }
2585 
2586 static void __rtw89_swap_chanctx(struct rtw89_vif *rtwvif,
2587 				 enum rtw89_chanctx_idx idx1,
2588 				 enum rtw89_chanctx_idx idx2)
2589 {
2590 	struct rtw89_vif_link *rtwvif_link;
2591 	unsigned int link_id;
2592 
2593 	rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
2594 		if (!rtwvif_link->chanctx_assigned)
2595 			continue;
2596 
2597 		if (rtwvif_link->chanctx_idx == idx1)
2598 			rtwvif_link->chanctx_idx = idx2;
2599 		else if (rtwvif_link->chanctx_idx == idx2)
2600 			rtwvif_link->chanctx_idx = idx1;
2601 	}
2602 }
2603 
2604 static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
2605 			       enum rtw89_chanctx_idx idx1,
2606 			       enum rtw89_chanctx_idx idx2)
2607 {
2608 	struct rtw89_hal *hal = &rtwdev->hal;
2609 	struct rtw89_vif *rtwvif;
2610 	u8 cur;
2611 
2612 	if (idx1 == idx2)
2613 		return;
2614 
2615 	hal->chanctx[idx1].cfg->idx = idx2;
2616 	hal->chanctx[idx2].cfg->idx = idx1;
2617 
2618 	swap(hal->chanctx[idx1], hal->chanctx[idx2]);
2619 
2620 	rtw89_for_each_rtwvif(rtwdev, rtwvif)
2621 		__rtw89_swap_chanctx(rtwvif, idx1, idx2);
2622 
2623 	cur = atomic_read(&hal->roc_chanctx_idx);
2624 	if (cur == idx1)
2625 		atomic_set(&hal->roc_chanctx_idx, idx2);
2626 	else if (cur == idx2)
2627 		atomic_set(&hal->roc_chanctx_idx, idx1);
2628 }
2629 
2630 int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
2631 			  struct ieee80211_chanctx_conf *ctx)
2632 {
2633 	struct rtw89_hal *hal = &rtwdev->hal;
2634 	struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
2635 	const struct rtw89_chip_info *chip = rtwdev->chip;
2636 	u8 idx;
2637 
2638 	idx = find_first_zero_bit(hal->entity_map, NUM_OF_RTW89_CHANCTX);
2639 	if (idx >= chip->support_chanctx_num)
2640 		return -ENOENT;
2641 
2642 	rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
2643 	cfg->idx = idx;
2644 	cfg->ref_count = 0;
2645 	hal->chanctx[idx].cfg = cfg;
2646 	return 0;
2647 }
2648 
2649 void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
2650 			      struct ieee80211_chanctx_conf *ctx)
2651 {
2652 	struct rtw89_hal *hal = &rtwdev->hal;
2653 	struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
2654 
2655 	clear_bit(cfg->idx, hal->entity_map);
2656 }
2657 
2658 void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
2659 			      struct ieee80211_chanctx_conf *ctx,
2660 			      u32 changed)
2661 {
2662 	struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
2663 	u8 idx = cfg->idx;
2664 
2665 	if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
2666 		rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
2667 		rtw89_set_channel(rtwdev);
2668 	}
2669 }
2670 
2671 int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
2672 				 struct rtw89_vif_link *rtwvif_link,
2673 				 struct ieee80211_chanctx_conf *ctx)
2674 {
2675 	struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
2676 	struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
2677 	struct rtw89_hal *hal = &rtwdev->hal;
2678 	struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
2679 	struct rtw89_entity_weight w = {};
2680 
2681 	rtwvif_link->chanctx_idx = cfg->idx;
2682 	rtwvif_link->chanctx_assigned = true;
2683 	cfg->ref_count++;
2684 
2685 	if (list_empty(&rtwvif->mgnt_entry))
2686 		list_add_tail(&rtwvif->mgnt_entry, &mgnt->active_list);
2687 
2688 	if (cfg->idx == RTW89_CHANCTX_0)
2689 		goto out;
2690 
2691 	rtw89_entity_calculate_weight(rtwdev, &w);
2692 	if (w.active_chanctxs != 1)
2693 		goto out;
2694 
2695 	/* put the first active chanctx at RTW89_CHANCTX_0 */
2696 	rtw89_swap_chanctx(rtwdev, cfg->idx, RTW89_CHANCTX_0);
2697 
2698 out:
2699 	return rtw89_set_channel(rtwdev);
2700 }
2701 
2702 void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
2703 				    struct rtw89_vif_link *rtwvif_link,
2704 				    struct ieee80211_chanctx_conf *ctx)
2705 {
2706 	struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
2707 	struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
2708 	struct rtw89_hal *hal = &rtwdev->hal;
2709 	enum rtw89_chanctx_idx roll;
2710 	enum rtw89_entity_mode cur;
2711 	enum rtw89_entity_mode new;
2712 	int ret;
2713 
2714 	rtwvif_link->chanctx_idx = RTW89_CHANCTX_0;
2715 	rtwvif_link->chanctx_assigned = false;
2716 	cfg->ref_count--;
2717 
2718 	if (!rtw89_vif_is_active_role(rtwvif))
2719 		list_del_init(&rtwvif->mgnt_entry);
2720 
2721 	if (cfg->ref_count != 0)
2722 		goto out;
2723 
2724 	if (cfg->idx != RTW89_CHANCTX_0)
2725 		goto out;
2726 
2727 	roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_CHANCTX,
2728 			     cfg->idx + 1);
2729 	/* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */
2730 	if (roll == NUM_OF_RTW89_CHANCTX)
2731 		goto out;
2732 
2733 	/* RTW89_CHANCTX_0 is going to release, and another exists.
2734 	 * Make another roll down to RTW89_CHANCTX_0 to replace.
2735 	 */
2736 	rtw89_swap_chanctx(rtwdev, cfg->idx, roll);
2737 
2738 out:
2739 	if (!hal->entity_pause) {
2740 		cur = rtw89_get_entity_mode(rtwdev);
2741 		switch (cur) {
2742 		case RTW89_ENTITY_MODE_MCC:
2743 			rtw89_mcc_stop(rtwdev);
2744 			break;
2745 		default:
2746 			break;
2747 		}
2748 	}
2749 
2750 	ret = rtw89_set_channel(rtwdev);
2751 	if (ret)
2752 		return;
2753 
2754 	if (hal->entity_pause)
2755 		return;
2756 
2757 	new = rtw89_get_entity_mode(rtwdev);
2758 	switch (new) {
2759 	case RTW89_ENTITY_MODE_MCC:
2760 		/* re-plan MCC for chanctx changes. */
2761 		ret = rtw89_mcc_start(rtwdev);
2762 		if (ret)
2763 			rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret);
2764 		break;
2765 	default:
2766 		break;
2767 	}
2768 }
2769