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