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