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