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