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