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