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