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