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