Lines Matching +full:no +full:- +full:sync +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2020-2022 Realtek Corporation
84 offset = (primary_freq - center_freq - 10) / 20; in rtw89_get_primary_chan_idx()
87 offset = (center_freq - primary_freq - 10) / 20; in rtw89_get_primary_chan_idx()
106 return (prisb_cal_ofst[bw] + pri_ch - central_ch) / 4; in rtw89_get_primary_sb_idx()
116 chan->channel = center_chan; in rtw89_chan_create()
117 chan->primary_channel = primary_chan; in rtw89_chan_create()
118 chan->band_type = band; in rtw89_chan_create()
119 chan->band_width = bandwidth; in rtw89_chan_create()
124 chan->freq = center_freq; in rtw89_chan_create()
125 chan->subband_type = rtw89_get_subband_type(band, center_chan); in rtw89_chan_create()
126 chan->pri_ch_idx = rtw89_get_primary_chan_idx(bandwidth, center_freq, in rtw89_chan_create()
128 chan->pri_sb_idx = rtw89_get_primary_sb_idx(center_chan, primary_chan, in rtw89_chan_create()
138 if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION && in _rtw89_chan_update_punctured()
139 rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) in _rtw89_chan_update_punctured()
145 if (!bss_conf->eht_support) { in _rtw89_chan_update_punctured()
152 rtw89_chip_h2c_punctured_cmac_tbl(rtwdev, rtwvif_link, chandef->punctured); in _rtw89_chan_update_punctured()
165 if (!rtwvif_link->chanctx_assigned || in rtw89_chan_update_punctured()
166 rtwvif_link->chanctx_idx != idx) in rtw89_chan_update_punctured()
178 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_assign_entity_chan()
179 struct rtw89_chan *chan = &hal->chanctx[idx].chan; in rtw89_assign_entity_chan()
180 struct rtw89_chan_rcd *rcd = &hal->chanctx[idx].rcd; in rtw89_assign_entity_chan()
183 rcd->prev_primary_channel = chan->primary_channel; in rtw89_assign_entity_chan()
184 rcd->prev_band_type = chan->band_type; in rtw89_assign_entity_chan()
185 band_changed = new->band_type != chan->band_type; in rtw89_assign_entity_chan()
186 rcd->band_changed = band_changed; in rtw89_assign_entity_chan()
197 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_iterate_entity_chan()
202 lockdep_assert_wiphy(rtwdev->hw->wiphy); in rtw89_iterate_entity_chan()
204 for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) { in rtw89_iterate_entity_chan()
218 struct rtw89_hal *hal = &rtwdev->hal; in __rtw89_config_entity_chandef()
220 hal->chanctx[idx].chandef = *chandef; in __rtw89_config_entity_chandef()
227 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_config_entity_chandef()
230 clear_bit(idx, hal->entity_map); in rtw89_config_entity_chandef()
235 set_bit(idx, hal->entity_map); in rtw89_config_entity_chandef()
242 enum rtw89_chanctx_idx idx = rtwvif_link->chanctx_idx; in rtw89_config_roc_chandef()
243 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_config_roc_chandef()
247 cur = atomic_cmpxchg(&hal->roc_chanctx_idx, in rtw89_config_roc_chandef()
255 hal->roc_chandef = *chandef; in rtw89_config_roc_chandef()
256 hal->roc_link_index = rtw89_vif_link_inst_get_index(rtwvif_link); in rtw89_config_roc_chandef()
258 cur = atomic_cmpxchg(&hal->roc_chanctx_idx, idx, in rtw89_config_roc_chandef()
282 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_entity_init()
283 struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt; in rtw89_entity_init()
285 hal->entity_pause = false; in rtw89_entity_init()
286 bitmap_zero(hal->entity_map, NUM_OF_RTW89_CHANCTX); in rtw89_entity_init()
287 bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES); in rtw89_entity_init()
288 atomic_set(&hal->roc_chanctx_idx, RTW89_CHANCTX_IDLE); in rtw89_entity_init()
290 INIT_LIST_HEAD(&mgnt->active_list); in rtw89_entity_init()
301 if (rtwvif_link->chanctx_assigned) in rtw89_vif_is_active_role()
310 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_entity_calculate_weight()
315 w->registered_chanctxs = bitmap_weight(hal->entity_map, NUM_OF_RTW89_CHANCTX); in rtw89_entity_calculate_weight()
317 for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) { in rtw89_entity_calculate_weight()
318 cfg = hal->chanctx[idx].cfg; in rtw89_entity_calculate_weight()
321 w->active_chanctxs = 1; in rtw89_entity_calculate_weight()
325 if (cfg->ref_count > 0) in rtw89_entity_calculate_weight()
326 w->active_chanctxs++; in rtw89_entity_calculate_weight()
331 w->active_roles++; in rtw89_entity_calculate_weight()
338 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; in rtw89_normalize_link_chanctx()
341 if (unlikely(!rtwvif_link->chanctx_assigned)) in rtw89_normalize_link_chanctx()
345 if (!cur || !cur->chanctx_assigned) in rtw89_normalize_link_chanctx()
351 rtw89_swap_chanctx(rtwdev, rtwvif_link->chanctx_idx, cur->chanctx_idx); in rtw89_normalize_link_chanctx()
358 struct rtw89_hal *hal = &rtwdev->hal; in __rtw89_mgnt_chan_get()
359 struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt; in __rtw89_mgnt_chan_get()
362 enum rtw89_entity_mode mode; in __rtw89_mgnt_chan_get() local
365 lockdep_assert_wiphy(rtwdev->hw->wiphy); in __rtw89_mgnt_chan_get()
373 mode = rtw89_get_entity_mode(rtwdev); in __rtw89_mgnt_chan_get()
374 switch (mode) { in __rtw89_mgnt_chan_get()
383 WARN(1, "Invalid ent mode: %d\n", mode); in __rtw89_mgnt_chan_get()
387 chanctx_idx = mgnt->chanctx_tbl[role_index][link_index]; in __rtw89_mgnt_chan_get()
391 roc_idx = atomic_read(&hal->roc_chanctx_idx); in __rtw89_mgnt_chan_get()
393 /* ROC is ongoing (given ROC runs on @hal->roc_link_index). in __rtw89_mgnt_chan_get()
396 if (link_index == hal->roc_link_index) in __rtw89_mgnt_chan_get()
414 if (rtwdev->chip->chip_gen != RTW89_CHIP_BE) in rtw89_entity_sel_mlo_dbcc_mode()
431 enum rtw89_mlo_dbcc_mode mode; in rtw89_entity_recalc_mlo_dbcc_mode() local
433 mode = rtw89_entity_sel_mlo_dbcc_mode(rtwdev, active_hws); in rtw89_entity_recalc_mlo_dbcc_mode()
434 rtwdev->mlo_dbcc_mode = mode; in rtw89_entity_recalc_mlo_dbcc_mode()
436 rtw89_debug(rtwdev, RTW89_DBG_STATE, "recalc mlo dbcc mode to %d\n", mode); in rtw89_entity_recalc_mlo_dbcc_mode()
441 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_entity_recalc_mgnt_roles()
442 struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt; in rtw89_entity_recalc_mgnt_roles()
449 lockdep_assert_wiphy(rtwdev->hw->wiphy); in rtw89_entity_recalc_mgnt_roles()
452 mgnt->active_roles[i] = NULL; in rtw89_entity_recalc_mgnt_roles()
456 mgnt->chanctx_tbl[i][j] = RTW89_CHANCTX_IDLE; in rtw89_entity_recalc_mgnt_roles()
463 list_for_each_entry(role, &mgnt->active_list, mgnt_entry) { in rtw89_entity_recalc_mgnt_roles()
464 for (i = 0; i < role->links_inst_valid_num; i++) { in rtw89_entity_recalc_mgnt_roles()
466 if (!link || !link->chanctx_assigned) in rtw89_entity_recalc_mgnt_roles()
469 if (link->chanctx_idx == RTW89_CHANCTX_0) { in rtw89_entity_recalc_mgnt_roles()
472 list_del(&role->mgnt_entry); in rtw89_entity_recalc_mgnt_roles()
473 list_add(&role->mgnt_entry, &mgnt->active_list); in rtw89_entity_recalc_mgnt_roles()
480 list_for_each_entry(role, &mgnt->active_list, mgnt_entry) { in rtw89_entity_recalc_mgnt_roles()
488 for (i = 0; i < role->links_inst_valid_num; i++) { in rtw89_entity_recalc_mgnt_roles()
490 if (!link || !link->chanctx_assigned) in rtw89_entity_recalc_mgnt_roles()
493 mgnt->chanctx_tbl[pos][i] = link->chanctx_idx; in rtw89_entity_recalc_mgnt_roles()
497 mgnt->active_roles[pos++] = role; in rtw89_entity_recalc_mgnt_roles()
506 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_entity_recalc()
509 enum rtw89_entity_mode mode; in rtw89_entity_recalc() local
513 lockdep_assert_wiphy(rtwdev->hw->wiphy); in rtw89_entity_recalc()
515 bitmap_copy(recalc_map, hal->entity_map, NUM_OF_RTW89_CHANCTX); in rtw89_entity_recalc()
530 mode = RTW89_ENTITY_MODE_SCC_OR_SMLD; in rtw89_entity_recalc()
534 mode = RTW89_ENTITY_MODE_SCC_OR_SMLD; in rtw89_entity_recalc()
545 mode = rtw89_get_entity_mode(rtwdev); in rtw89_entity_recalc()
546 if (mode == RTW89_ENTITY_MODE_MCC) in rtw89_entity_recalc()
549 mode = RTW89_ENTITY_MODE_MCC_PREPARE; in rtw89_entity_recalc()
566 if (hal->entity_pause) in rtw89_entity_recalc()
569 rtw89_set_entity_mode(rtwdev, mode); in rtw89_entity_recalc()
570 return mode; in rtw89_entity_recalc()
576 const struct rtw89_chip_info *chip = rtwdev->chip; in rtw89_chanctx_notify()
577 const struct rtw89_chanctx_listener *listener = chip->chanctx_listener; in rtw89_chanctx_notify()
584 if (!listener->callbacks[i]) in rtw89_chanctx_notify()
591 listener->callbacks[i](rtwdev, state); in rtw89_chanctx_notify()
597 enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; in rtw89_concurrent_via_mrc()
606 * immediately as long as iterator returns a non-zero value.
616 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_iterate_mcc_roles()
618 &mcc->role_ref, in rtw89_iterate_mcc_roles()
619 &mcc->role_aux, in rtw89_iterate_mcc_roles()
638 struct rtw89_vif_link *rtwvif_link = role->rtwvif_link; in rtw89_mcc_get_tbtt_ofst()
639 u32 bcn_intvl_us = ieee80211_tu_to_usec(role->beacon_interval); in rtw89_mcc_get_tbtt_ofst()
640 u64 sync_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf); in rtw89_mcc_get_tbtt_ofst()
643 if (role->is_go) { in rtw89_mcc_get_tbtt_ofst()
651 div_u64_rem(tsf - sync_tsf, bcn_intvl_us, &remainder); in rtw89_mcc_get_tbtt_ofst()
658 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mcc_fw_req_tsf()
659 struct rtw89_mcc_role *ref = &mcc->role_ref; in __mcc_fw_req_tsf()
660 struct rtw89_mcc_role *aux = &mcc->role_aux; in __mcc_fw_req_tsf()
665 req.group = mcc->group; in __mcc_fw_req_tsf()
666 req.macid_x = ref->rtwvif_link->mac_id; in __mcc_fw_req_tsf()
667 req.macid_y = aux->rtwvif_link->mac_id; in __mcc_fw_req_tsf()
683 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mrc_fw_req_tsf()
684 struct rtw89_mcc_role *ref = &mcc->role_ref; in __mrc_fw_req_tsf()
685 struct rtw89_mcc_role *aux = &mcc->role_aux; in __mrc_fw_req_tsf()
693 arg.infos[0].band = ref->rtwvif_link->mac_idx; in __mrc_fw_req_tsf()
694 arg.infos[0].port = ref->rtwvif_link->port; in __mrc_fw_req_tsf()
695 arg.infos[1].band = aux->rtwvif_link->mac_idx; in __mrc_fw_req_tsf()
696 arg.infos[1].port = aux->rtwvif_link->port; in __mrc_fw_req_tsf()
713 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_get_bcn_ofst()
714 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_get_bcn_ofst()
715 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_get_bcn_ofst()
716 u32 bcn_intvl_ref_us = ieee80211_tu_to_usec(ref->beacon_interval); in rtw89_mcc_get_bcn_ofst()
735 return (tbtt_ofst_ref - tbtt_ofst_aux) / 1024; in rtw89_mcc_get_bcn_ofst()
745 if (idx >= ARRAY_SIZE(mcc_role->macid_bitmap)) in rtw89_mcc_role_fw_macid_bitmap_set_bit()
748 mcc_role->macid_bitmap[idx] |= BIT(pos); in rtw89_mcc_role_fw_macid_bitmap_set_bit()
758 for (i = 0; i < ARRAY_SIZE(mcc_role->macid_bitmap); i++) { in rtw89_mcc_role_fw_macid_bitmap_to_u32()
764 if (mcc_role->macid_bitmap[i] & BIT(j)) in rtw89_mcc_role_fw_macid_bitmap_to_u32()
776 struct rtw89_vif *target = mcc_role->rtwvif_link->rtwvif; in rtw89_mcc_role_macid_sta_iter()
778 struct rtw89_vif *rtwvif = rtwsta->rtwvif; in rtw89_mcc_role_macid_sta_iter()
791 struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link; in rtw89_mcc_fill_role_macid_bitmap()
793 rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwvif_link->mac_id); in rtw89_mcc_fill_role_macid_bitmap()
794 ieee80211_iterate_stations_atomic(rtwdev->hw, in rtw89_mcc_fill_role_macid_bitmap()
802 struct rtw89_mcc_policy *policy = &mcc_role->policy; in rtw89_mcc_fill_role_policy()
804 policy->c2h_rpt = RTW89_FW_MCC_C2H_RPT_ALL; in rtw89_mcc_fill_role_policy()
805 policy->tx_null_early = RTW89_MCC_DFLT_TX_NULL_EARLY; in rtw89_mcc_fill_role_policy()
806 policy->in_curr_ch = false; in rtw89_mcc_fill_role_policy()
807 policy->dis_sw_retry = true; in rtw89_mcc_fill_role_policy()
808 policy->sw_retry_count = false; in rtw89_mcc_fill_role_policy()
810 if (mcc_role->is_go) in rtw89_mcc_fill_role_policy()
811 policy->dis_tx_null = true; in rtw89_mcc_fill_role_policy()
813 policy->dis_tx_null = false; in rtw89_mcc_fill_role_policy()
819 struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link; in rtw89_mcc_fill_role_limit()
822 u32 bcn_intvl_us = ieee80211_tu_to_usec(mcc_role->beacon_interval); in rtw89_mcc_fill_role_limit()
829 if (!mcc_role->is_gc) in rtw89_mcc_fill_role_limit()
840 noa_desc = &bss_conf->p2p_noa_attr.desc[i]; in rtw89_mcc_fill_role_limit()
841 if (noa_desc->count == 255) in rtw89_mcc_fill_role_limit()
849 start_time = le32_to_cpu(noa_desc->start_time); in rtw89_mcc_fill_role_limit()
850 interval = le32_to_cpu(noa_desc->interval); in rtw89_mcc_fill_role_limit()
851 duration = le32_to_cpu(noa_desc->duration); in rtw89_mcc_fill_role_limit()
870 tsf_lmt += roundup_u64(tsf - tsf_lmt, interval); in rtw89_mcc_fill_role_limit()
873 max_dur_us = interval - duration; in rtw89_mcc_fill_role_limit()
874 max_tob_us = max_dur_us - max_toa_us; in rtw89_mcc_fill_role_limit()
888 mcc_role->limit.max_toa = max_toa_us / 1024; in rtw89_mcc_fill_role_limit()
889 mcc_role->limit.max_tob = max_tob_us / 1024; in rtw89_mcc_fill_role_limit()
890 mcc_role->limit.max_dur = mcc_role->limit.max_toa + mcc_role->limit.max_tob; in rtw89_mcc_fill_role_limit()
891 mcc_role->limit.enable = true; in rtw89_mcc_fill_role_limit()
895 mcc_role->limit.max_toa, mcc_role->limit.max_tob, in rtw89_mcc_fill_role_limit()
896 mcc_role->limit.max_dur); in rtw89_mcc_fill_role_limit()
907 role->rtwvif_link = rtwvif_link; in rtw89_mcc_fill_role()
912 role->beacon_interval = bss_conf->beacon_int; in rtw89_mcc_fill_role()
916 if (!role->beacon_interval) { in rtw89_mcc_fill_role()
919 return -EINVAL; in rtw89_mcc_fill_role()
922 role->duration = role->beacon_interval / 2; in rtw89_mcc_fill_role()
924 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); in rtw89_mcc_fill_role()
925 role->is_2ghz = chan->band_type == RTW89_BAND_2G; in rtw89_mcc_fill_role()
926 role->is_go = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_GO; in rtw89_mcc_fill_role()
927 role->is_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; in rtw89_mcc_fill_role()
935 role->beacon_interval, role->is_2ghz, role->is_go, role->is_gc); in rtw89_mcc_fill_role()
941 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_fill_bt_role()
942 struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role; in rtw89_mcc_fill_bt_role()
945 bt_role->duration = rtw89_coex_query_bt_req_len(rtwdev, RTW89_PHY_0); in rtw89_mcc_fill_bt_role()
948 bt_role->duration); in rtw89_mcc_fill_bt_role()
964 struct rtw89_vif_link *role_vif = sel->bind_vif[ordered_idx]; in rtw89_mcc_fill_role_iterator()
970 return -EINVAL; in rtw89_mcc_fill_role_iterator()
975 ordered_idx, role_vif->mac_id); in rtw89_mcc_fill_role_iterator()
986 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_mcc_fill_all_roles()
987 struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt; in rtw89_mcc_fill_all_roles()
995 rtwvif = mgnt->active_roles[i]; in rtw89_mcc_fill_all_roles()
1001 rtw89_err(rtwdev, "mcc fill roles: find no link on HW-0\n"); in rtw89_mcc_fill_all_roles()
1020 if (provider->is_go || receiver->is_gc) in rtw89_mcc_can_courtesy()
1029 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_assign_pattern()
1030 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_assign_pattern()
1031 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_assign_pattern()
1032 struct rtw89_mcc_config *config = &mcc->config; in rtw89_mcc_assign_pattern()
1033 struct rtw89_mcc_pattern *pattern = &config->pattern; in rtw89_mcc_assign_pattern()
1038 new->tob_ref, new->toa_ref, new->tob_aux, new->toa_aux); in rtw89_mcc_assign_pattern()
1040 rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC pattern plan: %d\n", new->plan); in rtw89_mcc_assign_pattern()
1043 memset(&pattern->courtesy, 0, sizeof(pattern->courtesy)); in rtw89_mcc_assign_pattern()
1045 if (RTW89_MCC_REQ_COURTESY(pattern, aux) && aux->is_gc) in rtw89_mcc_assign_pattern()
1046 aux->ignore_bcn = true; in rtw89_mcc_assign_pattern()
1048 aux->ignore_bcn = false; in rtw89_mcc_assign_pattern()
1051 crtz = &pattern->courtesy.ref; in rtw89_mcc_assign_pattern()
1052 ref->crtz = crtz; in rtw89_mcc_assign_pattern()
1054 crtz->macid_tgt = aux->rtwvif_link->mac_id; in rtw89_mcc_assign_pattern()
1055 crtz->slot_num = RTW89_MCC_DFLT_COURTESY_SLOT; in rtw89_mcc_assign_pattern()
1059 crtz->macid_tgt, crtz->slot_num); in rtw89_mcc_assign_pattern()
1061 ref->crtz = NULL; in rtw89_mcc_assign_pattern()
1064 if (RTW89_MCC_REQ_COURTESY(pattern, ref) && ref->is_gc) in rtw89_mcc_assign_pattern()
1065 ref->ignore_bcn = true; in rtw89_mcc_assign_pattern()
1067 ref->ignore_bcn = false; in rtw89_mcc_assign_pattern()
1070 crtz = &pattern->courtesy.aux; in rtw89_mcc_assign_pattern()
1071 aux->crtz = crtz; in rtw89_mcc_assign_pattern()
1073 crtz->macid_tgt = ref->rtwvif_link->mac_id; in rtw89_mcc_assign_pattern()
1074 crtz->slot_num = RTW89_MCC_DFLT_COURTESY_SLOT; in rtw89_mcc_assign_pattern()
1078 crtz->macid_tgt, crtz->slot_num); in rtw89_mcc_assign_pattern()
1080 aux->crtz = NULL; in rtw89_mcc_assign_pattern()
1084 /* The follow-up roughly shows the relationship between the parameters
1102 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __rtw89_mcc_calc_pattern_loose()
1103 struct rtw89_mcc_role *ref = &mcc->role_ref; in __rtw89_mcc_calc_pattern_loose()
1104 struct rtw89_mcc_role *aux = &mcc->role_aux; in __rtw89_mcc_calc_pattern_loose()
1105 struct rtw89_mcc_config *config = &mcc->config; in __rtw89_mcc_calc_pattern_loose()
1106 u16 mcc_intvl = config->mcc_interval; in __rtw89_mcc_calc_pattern_loose()
1107 u16 bcn_ofst = config->beacon_offset; in __rtw89_mcc_calc_pattern_loose()
1120 max_bcn_ofst = ref->duration + aux->duration; in __rtw89_mcc_calc_pattern_loose()
1121 if (ref->limit.enable) in __rtw89_mcc_calc_pattern_loose()
1123 ref->limit.max_toa + aux->duration); in __rtw89_mcc_calc_pattern_loose()
1124 else if (aux->limit.enable) in __rtw89_mcc_calc_pattern_loose()
1126 ref->duration + aux->limit.max_tob); in __rtw89_mcc_calc_pattern_loose()
1128 if (bcn_ofst > max_bcn_ofst && bcn_ofst >= mcc->bt_role.duration) { in __rtw89_mcc_calc_pattern_loose()
1129 bt_dur_in_mid = mcc->bt_role.duration; in __rtw89_mcc_calc_pattern_loose()
1130 ptrn->plan = RTW89_MCC_PLAN_MID_BT; in __rtw89_mcc_calc_pattern_loose()
1136 ptrn->plan, bcn_ofst); in __rtw89_mcc_calc_pattern_loose()
1138 res = bcn_ofst - bt_dur_in_mid; in __rtw89_mcc_calc_pattern_loose()
1139 upper = min_t(s16, ref->duration, res); in __rtw89_mcc_calc_pattern_loose()
1140 lower = max_t(s16, 0, ref->duration - (mcc_intvl - bcn_ofst)); in __rtw89_mcc_calc_pattern_loose()
1142 if (ref->limit.enable) { in __rtw89_mcc_calc_pattern_loose()
1143 upper = min_t(s16, upper, ref->limit.max_toa); in __rtw89_mcc_calc_pattern_loose()
1144 lower = max_t(s16, lower, ref->duration - ref->limit.max_tob); in __rtw89_mcc_calc_pattern_loose()
1145 } else if (aux->limit.enable) { in __rtw89_mcc_calc_pattern_loose()
1147 res - (aux->duration - aux->limit.max_toa)); in __rtw89_mcc_calc_pattern_loose()
1148 lower = max_t(s16, lower, res - aux->limit.max_tob); in __rtw89_mcc_calc_pattern_loose()
1152 ptrn->toa_ref = (upper + lower) / 2; in __rtw89_mcc_calc_pattern_loose()
1154 ptrn->toa_ref = lower; in __rtw89_mcc_calc_pattern_loose()
1156 ptrn->tob_ref = ref->duration - ptrn->toa_ref; in __rtw89_mcc_calc_pattern_loose()
1157 ptrn->tob_aux = res - ptrn->toa_ref; in __rtw89_mcc_calc_pattern_loose()
1158 ptrn->toa_aux = aux->duration - ptrn->tob_aux; in __rtw89_mcc_calc_pattern_loose()
1167 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __rtw89_mcc_calc_pattern_strict()
1168 struct rtw89_mcc_role *ref = &mcc->role_ref; in __rtw89_mcc_calc_pattern_strict()
1169 struct rtw89_mcc_role *aux = &mcc->role_aux; in __rtw89_mcc_calc_pattern_strict()
1170 struct rtw89_mcc_config *config = &mcc->config; in __rtw89_mcc_calc_pattern_strict()
1173 u16 bcn_ofst = config->beacon_offset; in __rtw89_mcc_calc_pattern_strict()
1181 ptrn->plan, bcn_ofst); in __rtw89_mcc_calc_pattern_strict()
1183 if (ptrn->plan == RTW89_MCC_PLAN_MID_BT) in __rtw89_mcc_calc_pattern_strict()
1184 bt_dur_in_mid = mcc->bt_role.duration; in __rtw89_mcc_calc_pattern_strict()
1188 if (ref->duration < min_tob + min_toa) { in __rtw89_mcc_calc_pattern_strict()
1191 return -EINVAL; in __rtw89_mcc_calc_pattern_strict()
1194 if (aux->duration < min_tob + min_toa) { in __rtw89_mcc_calc_pattern_strict()
1197 return -EINVAL; in __rtw89_mcc_calc_pattern_strict()
1200 res = bcn_ofst - min_toa - min_tob - bt_dur_in_mid; in __rtw89_mcc_calc_pattern_strict()
1204 return -EINVAL; in __rtw89_mcc_calc_pattern_strict()
1207 upper_toa_ref = min_t(s16, min_toa + res, ref->duration - min_tob); in __rtw89_mcc_calc_pattern_strict()
1209 upper_tob_aux = min_t(s16, min_tob + res, aux->duration - min_toa); in __rtw89_mcc_calc_pattern_strict()
1212 if (ref->limit.enable) { in __rtw89_mcc_calc_pattern_strict()
1213 if (min_tob > ref->limit.max_tob || min_toa > ref->limit.max_toa) { in __rtw89_mcc_calc_pattern_strict()
1216 return -EINVAL; in __rtw89_mcc_calc_pattern_strict()
1219 upper_toa_ref = min_t(s16, upper_toa_ref, ref->limit.max_toa); in __rtw89_mcc_calc_pattern_strict()
1221 ref->duration - ref->limit.max_tob); in __rtw89_mcc_calc_pattern_strict()
1222 } else if (aux->limit.enable) { in __rtw89_mcc_calc_pattern_strict()
1223 if (min_tob > aux->limit.max_tob || min_toa > aux->limit.max_toa) { in __rtw89_mcc_calc_pattern_strict()
1226 return -EINVAL; in __rtw89_mcc_calc_pattern_strict()
1229 upper_tob_aux = min_t(s16, upper_tob_aux, aux->limit.max_tob); in __rtw89_mcc_calc_pattern_strict()
1231 aux->duration - aux->limit.max_toa); in __rtw89_mcc_calc_pattern_strict()
1235 bcn_ofst - bt_dur_in_mid - lower_tob_aux); in __rtw89_mcc_calc_pattern_strict()
1237 bcn_ofst - bt_dur_in_mid - upper_tob_aux); in __rtw89_mcc_calc_pattern_strict()
1241 return -EINVAL; in __rtw89_mcc_calc_pattern_strict()
1244 ptrn->toa_ref = (upper_toa_ref + lower_toa_ref) / 2; in __rtw89_mcc_calc_pattern_strict()
1245 ptrn->tob_ref = ref->duration - ptrn->toa_ref; in __rtw89_mcc_calc_pattern_strict()
1246 ptrn->tob_aux = bcn_ofst - ptrn->toa_ref - bt_dur_in_mid; in __rtw89_mcc_calc_pattern_strict()
1247 ptrn->toa_aux = aux->duration - ptrn->tob_aux; in __rtw89_mcc_calc_pattern_strict()
1255 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __rtw89_mcc_fill_ptrn_anchor_ref()
1256 struct rtw89_mcc_role *ref = &mcc->role_ref; in __rtw89_mcc_fill_ptrn_anchor_ref()
1257 struct rtw89_mcc_role *aux = &mcc->role_aux; in __rtw89_mcc_fill_ptrn_anchor_ref()
1258 struct rtw89_mcc_config *config = &mcc->config; in __rtw89_mcc_fill_ptrn_anchor_ref()
1259 u16 bcn_ofst = config->beacon_offset; in __rtw89_mcc_fill_ptrn_anchor_ref()
1263 if (ref->limit.enable) { in __rtw89_mcc_fill_ptrn_anchor_ref()
1264 ref_tob = ref->limit.max_tob; in __rtw89_mcc_fill_ptrn_anchor_ref()
1265 ref_toa = ref->limit.max_toa; in __rtw89_mcc_fill_ptrn_anchor_ref()
1267 ref_tob = ref->duration / 2; in __rtw89_mcc_fill_ptrn_anchor_ref()
1268 ref_toa = ref->duration / 2; in __rtw89_mcc_fill_ptrn_anchor_ref()
1272 ptrn->toa_ref = ref_toa; in __rtw89_mcc_fill_ptrn_anchor_ref()
1273 ptrn->tob_ref = ref->duration - ptrn->toa_ref; in __rtw89_mcc_fill_ptrn_anchor_ref()
1275 ptrn->tob_ref = ref_tob; in __rtw89_mcc_fill_ptrn_anchor_ref()
1276 ptrn->toa_ref = ref->duration - ptrn->tob_ref; in __rtw89_mcc_fill_ptrn_anchor_ref()
1279 ptrn->tob_aux = bcn_ofst - ptrn->toa_ref; in __rtw89_mcc_fill_ptrn_anchor_ref()
1280 ptrn->toa_aux = aux->duration - ptrn->tob_aux; in __rtw89_mcc_fill_ptrn_anchor_ref()
1287 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __rtw89_mcc_fill_ptrn_anchor_aux()
1288 struct rtw89_mcc_role *ref = &mcc->role_ref; in __rtw89_mcc_fill_ptrn_anchor_aux()
1289 struct rtw89_mcc_role *aux = &mcc->role_aux; in __rtw89_mcc_fill_ptrn_anchor_aux()
1290 struct rtw89_mcc_config *config = &mcc->config; in __rtw89_mcc_fill_ptrn_anchor_aux()
1291 u16 bcn_ofst = config->beacon_offset; in __rtw89_mcc_fill_ptrn_anchor_aux()
1295 if (aux->limit.enable) { in __rtw89_mcc_fill_ptrn_anchor_aux()
1296 aux_tob = aux->limit.max_tob; in __rtw89_mcc_fill_ptrn_anchor_aux()
1297 aux_toa = aux->limit.max_toa; in __rtw89_mcc_fill_ptrn_anchor_aux()
1299 aux_tob = aux->duration / 2; in __rtw89_mcc_fill_ptrn_anchor_aux()
1300 aux_toa = aux->duration / 2; in __rtw89_mcc_fill_ptrn_anchor_aux()
1304 ptrn->tob_aux = aux_tob; in __rtw89_mcc_fill_ptrn_anchor_aux()
1305 ptrn->toa_aux = aux->duration - ptrn->tob_aux; in __rtw89_mcc_fill_ptrn_anchor_aux()
1307 ptrn->toa_aux = aux_toa; in __rtw89_mcc_fill_ptrn_anchor_aux()
1308 ptrn->tob_aux = aux->duration - ptrn->toa_aux; in __rtw89_mcc_fill_ptrn_anchor_aux()
1311 ptrn->toa_ref = bcn_ofst - ptrn->tob_aux; in __rtw89_mcc_fill_ptrn_anchor_aux()
1312 ptrn->tob_ref = ref->duration - ptrn->toa_ref; in __rtw89_mcc_fill_ptrn_anchor_aux()
1319 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __rtw89_mcc_calc_pattern_anchor()
1320 struct rtw89_mcc_role *ref = &mcc->role_ref; in __rtw89_mcc_calc_pattern_anchor()
1321 struct rtw89_mcc_role *aux = &mcc->role_aux; in __rtw89_mcc_calc_pattern_anchor()
1322 struct rtw89_mcc_config *config = &mcc->config; in __rtw89_mcc_calc_pattern_anchor()
1323 u16 mcc_intvl = config->mcc_interval; in __rtw89_mcc_calc_pattern_anchor()
1324 u16 bcn_ofst = config->beacon_offset; in __rtw89_mcc_calc_pattern_anchor()
1329 else if (bcn_ofst < aux->duration - aux->limit.max_toa) in __rtw89_mcc_calc_pattern_anchor()
1331 else if (mcc_intvl - bcn_ofst < RTW89_MCC_MIN_RX_BCN_WITH_SWITCH_CH_TIME) in __rtw89_mcc_calc_pattern_anchor()
1334 return -EPERM; in __rtw89_mcc_calc_pattern_anchor()
1342 ptrn->plan, bcn_ofst); in __rtw89_mcc_calc_pattern_anchor()
1344 if (ref->is_go || ref->is_gc) in __rtw89_mcc_calc_pattern_anchor()
1346 else if (aux->is_go || aux->is_gc) in __rtw89_mcc_calc_pattern_anchor()
1356 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_calc_pattern()
1357 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_calc_pattern()
1358 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_calc_pattern()
1364 if (ref->limit.enable && aux->limit.enable) { in rtw89_mcc_calc_pattern()
1367 return -EINVAL; in rtw89_mcc_calc_pattern()
1370 if (ref->limit.enable && in rtw89_mcc_calc_pattern()
1371 ref->duration > ref->limit.max_tob + ref->limit.max_toa) { in rtw89_mcc_calc_pattern()
1374 return -EINVAL; in rtw89_mcc_calc_pattern()
1377 if (aux->limit.enable && in rtw89_mcc_calc_pattern()
1378 aux->duration > aux->limit.max_tob + aux->limit.max_toa) { in rtw89_mcc_calc_pattern()
1381 return -EINVAL; in rtw89_mcc_calc_pattern()
1420 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_set_default_pattern()
1421 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_set_default_pattern()
1422 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_set_default_pattern()
1429 tmp.tob_ref = ref->duration / 2; in rtw89_mcc_set_default_pattern()
1430 tmp.toa_ref = ref->duration - tmp.tob_ref; in rtw89_mcc_set_default_pattern()
1431 tmp.tob_aux = aux->duration / 2; in rtw89_mcc_set_default_pattern()
1432 tmp.toa_aux = aux->duration - tmp.tob_aux; in rtw89_mcc_set_default_pattern()
1441 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_set_duration_go_sta()
1442 struct rtw89_mcc_config *config = &mcc->config; in rtw89_mcc_set_duration_go_sta()
1443 u16 mcc_intvl = config->mcc_interval; in rtw89_mcc_set_duration_go_sta()
1446 dur_go = clamp_t(u16, role_go->duration, RTW89_MCC_MIN_GO_DURATION, in rtw89_mcc_set_duration_go_sta()
1447 mcc_intvl - RTW89_MCC_MIN_STA_DURATION); in rtw89_mcc_set_duration_go_sta()
1448 if (role_go->limit.enable) in rtw89_mcc_set_duration_go_sta()
1449 dur_go = min(dur_go, role_go->limit.max_dur); in rtw89_mcc_set_duration_go_sta()
1450 dur_sta = mcc_intvl - dur_go; in rtw89_mcc_set_duration_go_sta()
1453 "MCC set dur: (go, sta) {%d, %d} -> {%d, %d}\n", in rtw89_mcc_set_duration_go_sta()
1454 role_go->duration, role_sta->duration, dur_go, dur_sta); in rtw89_mcc_set_duration_go_sta()
1456 role_go->duration = dur_go; in rtw89_mcc_set_duration_go_sta()
1457 role_sta->duration = dur_sta; in rtw89_mcc_set_duration_go_sta()
1462 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_set_duration_gc_sta()
1463 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_set_duration_gc_sta()
1464 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_set_duration_gc_sta()
1465 struct rtw89_mcc_config *config = &mcc->config; in rtw89_mcc_set_duration_gc_sta()
1466 u16 mcc_intvl = config->mcc_interval; in rtw89_mcc_set_duration_gc_sta()
1469 if (ref->duration < RTW89_MCC_MIN_STA_DURATION) { in rtw89_mcc_set_duration_gc_sta()
1471 dur_aux = mcc_intvl - dur_ref; in rtw89_mcc_set_duration_gc_sta()
1472 } else if (aux->duration < RTW89_MCC_MIN_STA_DURATION) { in rtw89_mcc_set_duration_gc_sta()
1474 dur_ref = mcc_intvl - dur_aux; in rtw89_mcc_set_duration_gc_sta()
1476 dur_ref = ref->duration; in rtw89_mcc_set_duration_gc_sta()
1477 dur_aux = mcc_intvl - dur_ref; in rtw89_mcc_set_duration_gc_sta()
1480 if (ref->limit.enable) { in rtw89_mcc_set_duration_gc_sta()
1481 dur_ref = min(dur_ref, ref->limit.max_dur); in rtw89_mcc_set_duration_gc_sta()
1482 dur_aux = mcc_intvl - dur_ref; in rtw89_mcc_set_duration_gc_sta()
1483 } else if (aux->limit.enable) { in rtw89_mcc_set_duration_gc_sta()
1484 dur_aux = min(dur_aux, aux->limit.max_dur); in rtw89_mcc_set_duration_gc_sta()
1485 dur_ref = mcc_intvl - dur_aux; in rtw89_mcc_set_duration_gc_sta()
1489 "MCC set dur: (ref, aux) {%d ~ %d} -> {%d ~ %d}\n", in rtw89_mcc_set_duration_gc_sta()
1490 ref->duration, aux->duration, dur_ref, dur_aux); in rtw89_mcc_set_duration_gc_sta()
1492 ref->duration = dur_ref; in rtw89_mcc_set_duration_gc_sta()
1493 aux->duration = dur_aux; in rtw89_mcc_set_duration_gc_sta()
1512 p->parm[ordered_idx].dur = mcc_role->duration; in rtw89_mcc_mod_dur_get_iterator()
1514 if (mcc_role->is_go) in rtw89_mcc_mod_dur_get_iterator()
1519 p->parm[ordered_idx].room = max_t(s32, p->parm[ordered_idx].dur - min, 0); in rtw89_mcc_mod_dur_get_iterator()
1523 ordered_idx, p->parm[ordered_idx].dur, min, in rtw89_mcc_mod_dur_get_iterator()
1524 p->parm[ordered_idx].room); in rtw89_mcc_mod_dur_get_iterator()
1526 p->available += p->parm[ordered_idx].room; in rtw89_mcc_mod_dur_get_iterator()
1537 mcc_role->duration = p->parm[ordered_idx].dur; in rtw89_mcc_mod_dur_put_iterator()
1541 ordered_idx, p->parm[ordered_idx].dur); in rtw89_mcc_mod_dur_put_iterator()
1547 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_mod_duration_dual_2ghz_with_bt()
1548 struct rtw89_mcc_config *config = &mcc->config; in rtw89_mcc_mod_duration_dual_2ghz_with_bt()
1550 u16 mcc_intvl = config->mcc_interval; in rtw89_mcc_mod_duration_dual_2ghz_with_bt()
1551 u16 bt_dur = mcc->bt_role.duration; in rtw89_mcc_mod_duration_dual_2ghz_with_bt()
1561 wifi_dur = mcc_intvl - bt_dur; in rtw89_mcc_mod_duration_dual_2ghz_with_bt()
1564 data.parm[0].dur -= min_t(u16, bt_dur / 2, data.parm[0].room); in rtw89_mcc_mod_duration_dual_2ghz_with_bt()
1565 data.parm[1].dur = wifi_dur - data.parm[0].dur; in rtw89_mcc_mod_duration_dual_2ghz_with_bt()
1567 data.parm[1].dur -= min_t(u16, bt_dur / 2, data.parm[1].room); in rtw89_mcc_mod_duration_dual_2ghz_with_bt()
1568 data.parm[0].dur = wifi_dur - data.parm[1].dur; in rtw89_mcc_mod_duration_dual_2ghz_with_bt()
1574 mcc->bt_role.duration = bt_dur; in rtw89_mcc_mod_duration_dual_2ghz_with_bt()
1582 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_mod_duration_diff_band_with_bt()
1583 struct rtw89_mcc_config *config = &mcc->config; in rtw89_mcc_mod_duration_diff_band_with_bt()
1587 dur_2ghz = role_2ghz->duration; in rtw89_mcc_mod_duration_diff_band_with_bt()
1588 dur_non_2ghz = role_non_2ghz->duration; in rtw89_mcc_mod_duration_diff_band_with_bt()
1589 mcc_intvl = config->mcc_interval; in rtw89_mcc_mod_duration_diff_band_with_bt()
1590 bt_dur = mcc->bt_role.duration; in rtw89_mcc_mod_duration_diff_band_with_bt()
1607 dur_2ghz = mcc_intvl - dur_non_2ghz; in rtw89_mcc_mod_duration_diff_band_with_bt()
1609 if (role_non_2ghz->limit.enable) { in rtw89_mcc_mod_duration_diff_band_with_bt()
1612 role_non_2ghz->limit.max_dur); in rtw89_mcc_mod_duration_diff_band_with_bt()
1614 dur_non_2ghz = min(dur_non_2ghz, role_non_2ghz->limit.max_dur); in rtw89_mcc_mod_duration_diff_band_with_bt()
1615 dur_2ghz = mcc_intvl - dur_non_2ghz; in rtw89_mcc_mod_duration_diff_band_with_bt()
1622 role_2ghz->duration = dur_2ghz; in rtw89_mcc_mod_duration_diff_band_with_bt()
1623 role_non_2ghz->duration = dur_non_2ghz; in rtw89_mcc_mod_duration_diff_band_with_bt()
1628 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_duration_decision_on_bt()
1629 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_duration_decision_on_bt()
1630 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_duration_decision_on_bt()
1631 struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role; in rtw89_mcc_duration_decision_on_bt()
1633 if (!bt_role->duration) in rtw89_mcc_duration_decision_on_bt()
1636 if (ref->is_2ghz && aux->is_2ghz) { in rtw89_mcc_duration_decision_on_bt()
1644 if (!ref->is_2ghz && !aux->is_2ghz) { in rtw89_mcc_duration_decision_on_bt()
1653 if (ref->is_2ghz) in rtw89_mcc_duration_decision_on_bt()
1668 ieee80211_wake_queues(rtwdev->hw); in rtw89_mcc_prepare_done_work()
1673 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_prepare()
1674 struct rtw89_mcc_config *config = &mcc->config; in rtw89_mcc_prepare()
1677 ieee80211_stop_queues(rtwdev->hw); in rtw89_mcc_prepare()
1679 wiphy_delayed_work_queue(rtwdev->hw->wiphy, in rtw89_mcc_prepare()
1680 &rtwdev->mcc_prepare_done_work, in rtw89_mcc_prepare()
1681 usecs_to_jiffies(config->prepare_delay)); in rtw89_mcc_prepare()
1683 wiphy_delayed_work_queue(rtwdev->hw->wiphy, in rtw89_mcc_prepare()
1684 &rtwdev->mcc_prepare_done_work, 0); in rtw89_mcc_prepare()
1685 wiphy_delayed_work_flush(rtwdev->hw->wiphy, in rtw89_mcc_prepare()
1686 &rtwdev->mcc_prepare_done_work); in rtw89_mcc_prepare()
1692 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_fill_start_tsf()
1693 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_fill_start_tsf()
1694 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_fill_start_tsf()
1695 struct rtw89_mcc_config *config = &mcc->config; in rtw89_mcc_fill_start_tsf()
1696 u32 bcn_intvl_ref_us = ieee80211_tu_to_usec(ref->beacon_interval); in rtw89_mcc_fill_start_tsf()
1697 s32 tob_ref_us = ieee80211_tu_to_usec(config->pattern.tob_ref); in rtw89_mcc_fill_start_tsf()
1713 if (ref->is_go || aux->is_go) in rtw89_mcc_fill_start_tsf()
1719 start_tsf = tsf - cur_tbtt_ofst + bcn_intvl_ref_us - tob_ref_us; in rtw89_mcc_fill_start_tsf()
1721 start_tsf += roundup_u64(min_time - start_tsf, bcn_intvl_ref_us); in rtw89_mcc_fill_start_tsf()
1723 config->start_tsf = start_tsf; in rtw89_mcc_fill_start_tsf()
1724 config->start_tsf_in_aux_domain = tsf_aux + start_tsf - tsf; in rtw89_mcc_fill_start_tsf()
1725 config->prepare_delay = start_tsf - tsf; in rtw89_mcc_fill_start_tsf()
1732 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_fill_config()
1733 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_fill_config()
1734 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_fill_config()
1735 struct rtw89_mcc_config *config = &mcc->config; in rtw89_mcc_fill_config()
1741 switch (mcc->mode) { in rtw89_mcc_fill_config()
1743 config->beacon_offset = rtw89_mcc_get_bcn_ofst(rtwdev); in rtw89_mcc_fill_config()
1744 if (ref->is_go) { in rtw89_mcc_fill_config()
1745 config->mcc_interval = ref->beacon_interval; in rtw89_mcc_fill_config()
1748 config->mcc_interval = aux->beacon_interval; in rtw89_mcc_fill_config()
1753 config->beacon_offset = rtw89_mcc_get_bcn_ofst(rtwdev); in rtw89_mcc_fill_config()
1754 config->mcc_interval = ref->beacon_interval; in rtw89_mcc_fill_config()
1758 rtw89_warn(rtwdev, "MCC unknown mode: %d\n", mcc->mode); in rtw89_mcc_fill_config()
1759 return -EFAULT; in rtw89_mcc_fill_config()
1777 const struct rtw89_mcc_courtesy_cfg *crtz = role->crtz; in __mcc_fw_add_role()
1778 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mcc_fw_add_role()
1779 struct rtw89_mcc_policy *policy = &role->policy; in __mcc_fw_add_role()
1784 chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx); in __mcc_fw_add_role()
1785 req.central_ch_seg0 = chan->channel; in __mcc_fw_add_role()
1786 req.primary_ch = chan->primary_channel; in __mcc_fw_add_role()
1787 req.bandwidth = chan->band_width; in __mcc_fw_add_role()
1788 req.ch_band_type = chan->band_type; in __mcc_fw_add_role()
1790 req.macid = role->rtwvif_link->mac_id; in __mcc_fw_add_role()
1791 req.group = mcc->group; in __mcc_fw_add_role()
1792 req.c2h_rpt = policy->c2h_rpt; in __mcc_fw_add_role()
1793 req.tx_null_early = policy->tx_null_early; in __mcc_fw_add_role()
1794 req.dis_tx_null = policy->dis_tx_null; in __mcc_fw_add_role()
1795 req.in_curr_ch = policy->in_curr_ch; in __mcc_fw_add_role()
1796 req.sw_retry_count = policy->sw_retry_count; in __mcc_fw_add_role()
1797 req.dis_sw_retry = policy->dis_sw_retry; in __mcc_fw_add_role()
1798 req.duration = role->duration; in __mcc_fw_add_role()
1802 req.courtesy_target = crtz->macid_tgt; in __mcc_fw_add_role()
1803 req.courtesy_num = crtz->slot_num; in __mcc_fw_add_role()
1814 ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group, in __mcc_fw_add_role()
1815 role->rtwvif_link->mac_id, in __mcc_fw_add_role()
1816 role->macid_bitmap); in __mcc_fw_add_role()
1830 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mrc_fw_add_role()
1831 struct rtw89_mcc_role *ref = &mcc->role_ref; in __mrc_fw_add_role()
1832 struct rtw89_mcc_policy *policy = &role->policy; in __mrc_fw_add_role()
1836 slot_arg = &arg->slots[slot_idx]; in __mrc_fw_add_role()
1837 role->slot_idx = slot_idx; in __mrc_fw_add_role()
1839 slot_arg->duration = role->duration; in __mrc_fw_add_role()
1840 slot_arg->role_num = 1; in __mrc_fw_add_role()
1842 chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx); in __mrc_fw_add_role()
1844 slot_arg->roles[0].role_type = RTW89_H2C_MRC_ROLE_WIFI; in __mrc_fw_add_role()
1845 slot_arg->roles[0].is_master = role == ref; in __mrc_fw_add_role()
1846 slot_arg->roles[0].band = chan->band_type; in __mrc_fw_add_role()
1847 slot_arg->roles[0].bw = chan->band_width; in __mrc_fw_add_role()
1848 slot_arg->roles[0].central_ch = chan->channel; in __mrc_fw_add_role()
1849 slot_arg->roles[0].primary_ch = chan->primary_channel; in __mrc_fw_add_role()
1850 slot_arg->roles[0].en_tx_null = !policy->dis_tx_null; in __mrc_fw_add_role()
1851 slot_arg->roles[0].null_early = policy->tx_null_early; in __mrc_fw_add_role()
1852 slot_arg->roles[0].macid = role->rtwvif_link->mac_id; in __mrc_fw_add_role()
1853 slot_arg->roles[0].macid_main_bitmap = in __mrc_fw_add_role()
1859 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mcc_fw_add_bt_role()
1860 struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role; in __mcc_fw_add_bt_role()
1864 req.group = mcc->group; in __mcc_fw_add_bt_role()
1865 req.duration = bt_role->duration; in __mcc_fw_add_bt_role()
1882 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mrc_fw_add_bt_role()
1883 struct rtw89_mcc_bt_role *bt_role = &mcc->bt_role; in __mrc_fw_add_bt_role()
1884 struct rtw89_fw_mrc_add_slot_arg *slot_arg = &arg->slots[slot_idx]; in __mrc_fw_add_bt_role()
1886 slot_arg->duration = bt_role->duration; in __mrc_fw_add_bt_role()
1887 slot_arg->role_num = 1; in __mrc_fw_add_bt_role()
1889 slot_arg->roles[0].role_type = RTW89_H2C_MRC_ROLE_BT; in __mrc_fw_add_bt_role()
1894 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mcc_fw_start()
1895 struct rtw89_mcc_role *ref = &mcc->role_ref; in __mcc_fw_start()
1896 struct rtw89_mcc_role *aux = &mcc->role_aux; in __mcc_fw_start()
1897 struct rtw89_mcc_config *config = &mcc->config; in __mcc_fw_start()
1898 struct rtw89_mcc_pattern *pattern = &config->pattern; in __mcc_fw_start()
1899 struct rtw89_mcc_sync *sync = &config->sync; in __mcc_fw_start() local
1904 req.old_group = mcc->group; in __mcc_fw_start()
1906 mcc->group = RTW89_MCC_NEXT_GROUP(mcc->group); in __mcc_fw_start()
1909 req.group = mcc->group; in __mcc_fw_start()
1911 switch (pattern->plan) { in __mcc_fw_start()
1949 rtw89_warn(rtwdev, "MCC unknown plan: %d\n", pattern->plan); in __mcc_fw_start()
1950 return -EFAULT; in __mcc_fw_start()
1953 if (sync->enable) { in __mcc_fw_start()
1954 ret = rtw89_fw_h2c_mcc_sync(rtwdev, req.group, sync->macid_src, in __mcc_fw_start()
1955 sync->macid_tgt, sync->offset); in __mcc_fw_start()
1958 "MCC h2c failed to trigger sync: %d\n", ret); in __mcc_fw_start()
1963 req.macid = ref->rtwvif_link->mac_id; in __mcc_fw_start()
1964 req.tsf_high = config->start_tsf >> 32; in __mcc_fw_start()
1965 req.tsf_low = config->start_tsf; in __mcc_fw_start()
1980 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mrc_fw_add_courtesy()
1981 struct rtw89_mcc_role *ref = &mcc->role_ref; in __mrc_fw_add_courtesy()
1982 struct rtw89_mcc_role *aux = &mcc->role_aux; in __mrc_fw_add_courtesy()
1985 if (ref->crtz) { in __mrc_fw_add_courtesy()
1986 slot_arg_src = &arg->slots[ref->slot_idx]; in __mrc_fw_add_courtesy()
1988 slot_arg_src->courtesy_target = aux->slot_idx; in __mrc_fw_add_courtesy()
1989 slot_arg_src->courtesy_period = ref->crtz->slot_num; in __mrc_fw_add_courtesy()
1990 slot_arg_src->courtesy_en = true; in __mrc_fw_add_courtesy()
1993 if (aux->crtz) { in __mrc_fw_add_courtesy()
1994 slot_arg_src = &arg->slots[aux->slot_idx]; in __mrc_fw_add_courtesy()
1996 slot_arg_src->courtesy_target = ref->slot_idx; in __mrc_fw_add_courtesy()
1997 slot_arg_src->courtesy_period = aux->crtz->slot_num; in __mrc_fw_add_courtesy()
1998 slot_arg_src->courtesy_en = true; in __mrc_fw_add_courtesy()
2004 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mrc_fw_start()
2005 struct rtw89_mcc_role *ref = &mcc->role_ref; in __mrc_fw_start()
2006 struct rtw89_mcc_role *aux = &mcc->role_aux; in __mrc_fw_start()
2007 struct rtw89_mcc_config *config = &mcc->config; in __mrc_fw_start()
2008 struct rtw89_mcc_pattern *pattern = &config->pattern; in __mrc_fw_start()
2009 struct rtw89_mcc_sync *sync = &config->sync; in __mrc_fw_start() local
2018 start_arg.old_sch_idx = mcc->group; in __mrc_fw_start()
2020 mcc->group = RTW89_MCC_NEXT_GROUP(mcc->group); in __mrc_fw_start()
2023 add_arg.sch_idx = mcc->group; in __mrc_fw_start()
2026 switch (pattern->plan) { in __mrc_fw_start()
2051 rtw89_warn(rtwdev, "MCC unknown plan: %d\n", pattern->plan); in __mrc_fw_start()
2052 return -EFAULT; in __mrc_fw_start()
2064 if (sync->enable) { in __mrc_fw_start()
2066 .offset = sync->offset, in __mrc_fw_start()
2068 .band = sync->band_src, in __mrc_fw_start()
2069 .port = sync->port_src, in __mrc_fw_start()
2072 .band = sync->band_tgt, in __mrc_fw_start()
2073 .port = sync->port_tgt, in __mrc_fw_start()
2080 "MRC h2c failed to trigger sync: %d\n", ret); in __mrc_fw_start()
2085 start_arg.sch_idx = mcc->group; in __mrc_fw_start()
2086 start_arg.start_tsf = config->start_tsf; in __mrc_fw_start()
2100 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mcc_fw_set_duration_no_bt()
2101 struct rtw89_mcc_config *config = &mcc->config; in __mcc_fw_set_duration_no_bt()
2102 struct rtw89_mcc_sync *sync = &config->sync; in __mcc_fw_set_duration_no_bt() local
2103 struct rtw89_mcc_role *ref = &mcc->role_ref; in __mcc_fw_set_duration_no_bt()
2104 struct rtw89_mcc_role *aux = &mcc->role_aux; in __mcc_fw_set_duration_no_bt()
2106 .group = mcc->group, in __mcc_fw_set_duration_no_bt()
2108 .start_macid = ref->rtwvif_link->mac_id, in __mcc_fw_set_duration_no_bt()
2109 .macid_x = ref->rtwvif_link->mac_id, in __mcc_fw_set_duration_no_bt()
2110 .macid_y = aux->rtwvif_link->mac_id, in __mcc_fw_set_duration_no_bt()
2111 .duration_x = ref->duration, in __mcc_fw_set_duration_no_bt()
2112 .duration_y = aux->duration, in __mcc_fw_set_duration_no_bt()
2113 .start_tsf_high = config->start_tsf >> 32, in __mcc_fw_set_duration_no_bt()
2114 .start_tsf_low = config->start_tsf, in __mcc_fw_set_duration_no_bt()
2125 if (!sync->enable || !sync_changed) in __mcc_fw_set_duration_no_bt()
2128 ret = rtw89_fw_h2c_mcc_sync(rtwdev, mcc->group, sync->macid_src, in __mcc_fw_set_duration_no_bt()
2129 sync->macid_tgt, sync->offset); in __mcc_fw_set_duration_no_bt()
2132 "MCC h2c failed to trigger sync: %d\n", ret); in __mcc_fw_set_duration_no_bt()
2141 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mrc_fw_set_duration_no_bt()
2142 struct rtw89_mcc_config *config = &mcc->config; in __mrc_fw_set_duration_no_bt()
2143 struct rtw89_mcc_sync *sync = &config->sync; in __mrc_fw_set_duration_no_bt() local
2144 struct rtw89_mcc_role *ref = &mcc->role_ref; in __mrc_fw_set_duration_no_bt()
2145 struct rtw89_mcc_role *aux = &mcc->role_aux; in __mrc_fw_set_duration_no_bt()
2147 .sch_idx = mcc->group, in __mrc_fw_set_duration_no_bt()
2148 .start_tsf = config->start_tsf, in __mrc_fw_set_duration_no_bt()
2151 .slot_idx = ref->slot_idx, in __mrc_fw_set_duration_no_bt()
2152 .duration = ref->duration, in __mrc_fw_set_duration_no_bt()
2155 .slot_idx = aux->slot_idx, in __mrc_fw_set_duration_no_bt()
2156 .duration = aux->duration, in __mrc_fw_set_duration_no_bt()
2160 .offset = sync->offset, in __mrc_fw_set_duration_no_bt()
2162 .band = sync->band_src, in __mrc_fw_set_duration_no_bt()
2163 .port = sync->port_src, in __mrc_fw_set_duration_no_bt()
2166 .band = sync->band_tgt, in __mrc_fw_set_duration_no_bt()
2167 .port = sync->port_tgt, in __mrc_fw_set_duration_no_bt()
2180 if (!sync->enable || !sync_changed) in __mrc_fw_set_duration_no_bt()
2186 "MRC h2c failed to trigger sync: %d\n", ret); in __mrc_fw_set_duration_no_bt()
2195 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_handle_beacon_noa()
2196 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_handle_beacon_noa()
2197 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_handle_beacon_noa()
2198 struct rtw89_mcc_config *config = &mcc->config; in rtw89_mcc_handle_beacon_noa()
2200 u32 interval = config->mcc_interval; in rtw89_mcc_handle_beacon_noa()
2205 if (mcc->mode != RTW89_MCC_MODE_GO_STA) in rtw89_mcc_handle_beacon_noa()
2208 if (ref->is_go) { in rtw89_mcc_handle_beacon_noa()
2209 start_time = config->start_tsf; in rtw89_mcc_handle_beacon_noa()
2210 rtwvif_go = ref->rtwvif_link; in rtw89_mcc_handle_beacon_noa()
2211 start_time += ieee80211_tu_to_usec(ref->duration); in rtw89_mcc_handle_beacon_noa()
2212 duration = config->mcc_interval - ref->duration; in rtw89_mcc_handle_beacon_noa()
2213 } else if (aux->is_go) { in rtw89_mcc_handle_beacon_noa()
2214 start_time = config->start_tsf_in_aux_domain; in rtw89_mcc_handle_beacon_noa()
2215 rtwvif_go = aux->rtwvif_link; in rtw89_mcc_handle_beacon_noa()
2216 duration = config->mcc_interval - aux->duration; in rtw89_mcc_handle_beacon_noa()
2219 "MCC find no GO: skip updating beacon NoA\n"); in rtw89_mcc_handle_beacon_noa()
2235 if (!rtwvif_go->chanctx_assigned) in rtw89_mcc_handle_beacon_noa()
2243 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_start_beacon_noa()
2244 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_start_beacon_noa()
2245 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_start_beacon_noa()
2247 if (mcc->mode != RTW89_MCC_MODE_GO_STA) in rtw89_mcc_start_beacon_noa()
2250 if (ref->is_go) in rtw89_mcc_start_beacon_noa()
2251 rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, true); in rtw89_mcc_start_beacon_noa()
2252 else if (aux->is_go) in rtw89_mcc_start_beacon_noa()
2253 rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, true); in rtw89_mcc_start_beacon_noa()
2260 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_stop_beacon_noa()
2261 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_stop_beacon_noa()
2262 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_stop_beacon_noa()
2264 if (mcc->mode != RTW89_MCC_MODE_GO_STA) in rtw89_mcc_stop_beacon_noa()
2267 if (ref->is_go) in rtw89_mcc_stop_beacon_noa()
2268 rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, false); in rtw89_mcc_stop_beacon_noa()
2269 else if (aux->is_go) in rtw89_mcc_stop_beacon_noa()
2270 rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, false); in rtw89_mcc_stop_beacon_noa()
2277 enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; in rtw89_mcc_ignore_bcn()
2279 if (role->is_go) in rtw89_mcc_ignore_bcn()
2281 else if (chip_gen == RTW89_CHIP_BE && role->is_gc) in rtw89_mcc_ignore_bcn()
2289 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_start()
2290 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_start()
2291 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_start()
2294 if (rtwdev->scanning) in rtw89_mcc_start()
2295 rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); in rtw89_mcc_start()
2305 if (ref->is_go || aux->is_go) in rtw89_mcc_start()
2306 mcc->mode = RTW89_MCC_MODE_GO_STA; in rtw89_mcc_start()
2308 mcc->mode = RTW89_MCC_MODE_GC_STA; in rtw89_mcc_start()
2310 rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC sel mode: %d\n", mcc->mode); in rtw89_mcc_start()
2312 mcc->group = RTW89_MCC_DFLT_GROUP; in rtw89_mcc_start()
2318 if (rtw89_mcc_ignore_bcn(rtwdev, ref) || aux->ignore_bcn) { in rtw89_mcc_start()
2319 rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, false); in rtw89_mcc_start()
2320 } else if (rtw89_mcc_ignore_bcn(rtwdev, aux) || ref->ignore_bcn) { in rtw89_mcc_start()
2321 rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, false); in rtw89_mcc_start()
2323 rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, true); in rtw89_mcc_start()
2324 rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, true); in rtw89_mcc_start()
2358 sel->mac_id = mcc_role->rtwvif_link->mac_id; in rtw89_mcc_stop_sel_fill()
2359 sel->slot_idx = mcc_role->slot_idx; in rtw89_mcc_stop_sel_fill()
2360 sel->filled = true; in rtw89_mcc_stop_sel_fill()
2370 if (mcc_role->rtwvif_link == sel->hint.target) { in rtw89_mcc_stop_sel_iterator()
2375 if (sel->filled) in rtw89_mcc_stop_sel_iterator()
2378 if (!mcc_role->rtwvif_link->chanctx_assigned) in rtw89_mcc_stop_sel_iterator()
2388 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_mcc_stop()
2389 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_stop()
2390 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_stop()
2391 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_stop()
2393 .hint.target = pause ? pause->trigger : NULL, in rtw89_mcc_stop()
2399 wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->chanctx_work); in rtw89_mcc_stop()
2400 bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES); in rtw89_mcc_stop()
2403 rsn_scan = pause && pause->rsn == RTW89_CHANCTX_PAUSE_REASON_HW_SCAN; in rtw89_mcc_stop()
2404 if (rsn_scan && ref->is_go) in rtw89_mcc_stop()
2405 sel.hint.target = ref->rtwvif_link; in rtw89_mcc_stop()
2406 else if (rsn_scan && aux->is_go) in rtw89_mcc_stop()
2407 sel.hint.target = aux->rtwvif_link; in rtw89_mcc_stop()
2417 ret = rtw89_fw_h2c_mrc_del(rtwdev, mcc->group, sel.slot_idx); in rtw89_mcc_stop()
2422 ret = rtw89_fw_h2c_stop_mcc(rtwdev, mcc->group, in rtw89_mcc_stop()
2428 ret = rtw89_fw_h2c_del_mcc_group(rtwdev, mcc->group, true); in rtw89_mcc_stop()
2445 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_update()
2446 bool old_ref_ignore_bcn = mcc->role_ref.ignore_bcn; in rtw89_mcc_update()
2447 bool old_aux_ignore_bcn = mcc->role_aux.ignore_bcn; in rtw89_mcc_update()
2448 struct rtw89_mcc_config *config = &mcc->config; in rtw89_mcc_update()
2449 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_update()
2450 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_update()
2456 if (rtwdev->scanning) in rtw89_mcc_update()
2457 rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); in rtw89_mcc_update()
2465 if (old_ref_ignore_bcn != ref->ignore_bcn) in rtw89_mcc_update()
2466 rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, !ref->ignore_bcn); in rtw89_mcc_update()
2467 else if (old_aux_ignore_bcn != aux->ignore_bcn) in rtw89_mcc_update()
2468 rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, !aux->ignore_bcn); in rtw89_mcc_update()
2470 if (memcmp(&old_cfg.pattern.courtesy, &config->pattern.courtesy, in rtw89_mcc_update()
2477 config->pattern.plan != RTW89_MCC_PLAN_NO_BT || in rtw89_mcc_update()
2487 if (memcmp(&old_cfg.sync, &config->sync, sizeof(old_cfg.sync)) == 0) in rtw89_mcc_update()
2512 if (mcc_role->is_gc) in rtw89_mcc_search_gc_iterator()
2520 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_get_gc_role()
2523 if (mcc->mode != RTW89_MCC_MODE_GC_STA) in rtw89_mcc_get_gc_role()
2536 enum rtw89_entity_mode mode; in rtw89_mcc_gc_detect_beacon_work() local
2541 rtwdev = rtwvif_link->rtwvif->rtwdev; in rtw89_mcc_gc_detect_beacon_work()
2543 mode = rtw89_get_entity_mode(rtwdev); in rtw89_mcc_gc_detect_beacon_work()
2544 if (mode != RTW89_ENTITY_MODE_MCC) in rtw89_mcc_gc_detect_beacon_work()
2547 if (READ_ONCE(rtwvif_link->sync_bcn_tsf) > rtwvif_link->last_sync_bcn_tsf) in rtw89_mcc_gc_detect_beacon_work()
2548 rtwvif_link->detect_bcn_count = 0; in rtw89_mcc_gc_detect_beacon_work()
2550 rtwvif_link->detect_bcn_count++; in rtw89_mcc_gc_detect_beacon_work()
2552 if (rtwvif_link->detect_bcn_count < RTW89_MCC_DETECT_BCN_MAX_TRIES) in rtw89_mcc_gc_detect_beacon_work()
2561 enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); in rtw89_mcc_detect_go_bcn() local
2570 if (mode != RTW89_ENTITY_MODE_MCC) in rtw89_mcc_detect_go_bcn()
2577 if (role->rtwvif_link != rtwvif_link) in rtw89_mcc_detect_go_bcn()
2586 bcn_int = bss_conf->beacon_int; in rtw89_mcc_detect_go_bcn()
2591 rtwvif_link->last_sync_bcn_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf); in rtw89_mcc_detect_go_bcn()
2592 wiphy_delayed_work_queue(rtwdev->hw->wiphy, in rtw89_mcc_detect_go_bcn()
2593 &rtwvif_link->mcc_gc_detect_beacon_work, in rtw89_mcc_detect_go_bcn()
2606 ret = rtw89_core_send_nullfunc(rtwdev, role->rtwvif_link, true, false, in rtw89_mcc_detect_connection()
2609 role->probe_count++; in rtw89_mcc_detect_connection()
2611 role->probe_count = 0; in rtw89_mcc_detect_connection()
2613 if (role->probe_count < RTW89_MCC_PROBE_MAX_TRIES) in rtw89_mcc_detect_connection()
2617 "MCC <macid %d> can not detect AP/GO\n", role->rtwvif_link->mac_id); in rtw89_mcc_detect_connection()
2619 start_detect = rtw89_mcc_detect_go_bcn(rtwdev, role->rtwvif_link); in rtw89_mcc_detect_connection()
2623 vif = rtwvif_link_to_vif(role->rtwvif_link); in rtw89_mcc_detect_connection()
2629 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_track()
2630 struct rtw89_mcc_config *config = &mcc->config; in rtw89_mcc_track()
2631 struct rtw89_mcc_pattern *pattern = &config->pattern; in rtw89_mcc_track()
2632 struct rtw89_mcc_role *ref = &mcc->role_ref; in rtw89_mcc_track()
2633 struct rtw89_mcc_role *aux = &mcc->role_aux; in rtw89_mcc_track()
2638 if (rtw89_mcc_ignore_bcn(rtwdev, ref) || aux->ignore_bcn) in rtw89_mcc_track()
2640 else if (rtw89_mcc_ignore_bcn(rtwdev, aux) || ref->ignore_bcn) in rtw89_mcc_track()
2643 if (mcc->mode != RTW89_MCC_MODE_GC_STA) in rtw89_mcc_track()
2647 if (bcn_ofst == config->beacon_offset) in rtw89_mcc_track()
2650 if (bcn_ofst > config->beacon_offset) { in rtw89_mcc_track()
2651 diff = bcn_ofst - config->beacon_offset; in rtw89_mcc_track()
2652 if (pattern->tob_aux < 0) in rtw89_mcc_track()
2653 tolerance = -pattern->tob_aux; in rtw89_mcc_track()
2654 else if (pattern->toa_aux > 0) in rtw89_mcc_track()
2655 tolerance = pattern->toa_aux; in rtw89_mcc_track()
2657 return; /* no chance to improve */ in rtw89_mcc_track()
2659 diff = config->beacon_offset - bcn_ofst; in rtw89_mcc_track()
2660 if (pattern->toa_aux < 0) in rtw89_mcc_track()
2661 tolerance = -pattern->toa_aux; in rtw89_mcc_track()
2662 else if (pattern->tob_aux > 0) in rtw89_mcc_track()
2663 tolerance = pattern->tob_aux; in rtw89_mcc_track()
2665 return; /* no chance to improve */ in rtw89_mcc_track()
2677 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mcc_fw_upd_macid_bitmap()
2680 ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group, in __mcc_fw_upd_macid_bitmap()
2681 upd->rtwvif_link->mac_id, in __mcc_fw_upd_macid_bitmap()
2682 upd->macid_bitmap); in __mcc_fw_upd_macid_bitmap()
2696 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in __mrc_fw_upd_macid_bitmap()
2705 arg.sch_idx = mcc->group; in __mrc_fw_upd_macid_bitmap()
2706 arg.macid = upd->rtwvif_link->mac_id; in __mrc_fw_upd_macid_bitmap()
2744 .rtwvif_link = mcc_role->rtwvif_link, in rtw89_mcc_upd_map_iterator()
2748 if (!mcc_role->is_go) in rtw89_mcc_upd_map_iterator()
2752 if (memcmp(mcc_role->macid_bitmap, upd.macid_bitmap, in rtw89_mcc_upd_map_iterator()
2753 sizeof(mcc_role->macid_bitmap)) == 0) in rtw89_mcc_upd_map_iterator()
2764 memcpy(mcc_role->macid_bitmap, upd.macid_bitmap, in rtw89_mcc_upd_map_iterator()
2765 sizeof(mcc_role->macid_bitmap)); in rtw89_mcc_upd_map_iterator()
2771 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_update_macid_bitmap()
2773 if (mcc->mode != RTW89_MCC_MODE_GO_STA) in rtw89_mcc_update_macid_bitmap()
2784 memset(&mcc_role->limit, 0, sizeof(mcc_role->limit)); in rtw89_mcc_upd_lmt_iterator()
2791 struct rtw89_mcc_info *mcc = &rtwdev->mcc; in rtw89_mcc_update_limit()
2793 if (mcc->mode != RTW89_MCC_MODE_GC_STA) in rtw89_mcc_update_limit()
2806 info->links[ordered_idx] = mcc_role->rtwvif_link; in rtw89_mcc_get_links_iterator()
2812 enum rtw89_entity_mode mode; in rtw89_mcc_get_links() local
2816 mode = rtw89_get_entity_mode(rtwdev); in rtw89_mcc_get_links()
2817 if (unlikely(mode != RTW89_ENTITY_MODE_MCC)) in rtw89_mcc_get_links()
2827 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_chanctx_work()
2829 enum rtw89_entity_mode mode; in rtw89_chanctx_work() local
2836 if (hal->entity_pause) in rtw89_chanctx_work()
2840 if (test_and_clear_bit(i, hal->changes)) in rtw89_chanctx_work()
2844 mode = rtw89_get_entity_mode(rtwdev); in rtw89_chanctx_work()
2845 switch (mode) { in rtw89_chanctx_work()
2881 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_queue_chanctx_change()
2882 enum rtw89_entity_mode mode; in rtw89_queue_chanctx_change() local
2885 mode = rtw89_get_entity_mode(rtwdev); in rtw89_queue_chanctx_change()
2886 switch (mode) { in rtw89_queue_chanctx_change()
2901 set_bit(change, hal->changes); in rtw89_queue_chanctx_change()
2905 "queue chanctx work for mode %d with delay %d us\n", in rtw89_queue_chanctx_change()
2906 mode, delay); in rtw89_queue_chanctx_change()
2907 wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->chanctx_work, in rtw89_queue_chanctx_change()
2918 struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; in __rtw89_query_mr_wtype()
2929 rtwvif = mgnt->active_roles[role_idx]; in __rtw89_query_mr_wtype()
2942 chanctx_idx = mgnt->chanctx_tbl[role_idx][idx]; in __rtw89_query_mr_wtype()
2991 struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; in __rtw89_query_mr_wmode()
3003 chanctx_idx = mgnt->chanctx_tbl[role_idx][inst_idx]; in __rtw89_query_mr_wmode()
3007 rtwvif = mgnt->active_roles[role_idx]; in __rtw89_query_mr_wmode()
3012 num[vif->type]++; in __rtw89_query_mr_wmode()
3044 struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; in __rtw89_query_mr_ctxtype()
3056 chanctx_idx = mgnt->chanctx_tbl[role_idx][inst_idx]; in __rtw89_query_mr_ctxtype()
3064 num[chan->band_type]++; in __rtw89_query_mr_ctxtype()
3104 lockdep_assert_wiphy(rtwdev->hw->wiphy); in rtw89_query_mr_chanctx_info()
3106 info->wtype = __rtw89_query_mr_wtype(rtwdev); in rtw89_query_mr_chanctx_info()
3107 info->wmode = __rtw89_query_mr_wmode(rtwdev, inst_idx); in rtw89_query_mr_chanctx_info()
3108 info->ctxtype = __rtw89_query_mr_ctxtype(rtwdev, inst_idx); in rtw89_query_mr_chanctx_info()
3113 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_chanctx_track()
3114 enum rtw89_entity_mode mode; in rtw89_chanctx_track() local
3116 lockdep_assert_wiphy(rtwdev->hw->wiphy); in rtw89_chanctx_track()
3118 if (hal->entity_pause) in rtw89_chanctx_track()
3121 mode = rtw89_get_entity_mode(rtwdev); in rtw89_chanctx_track()
3122 switch (mode) { in rtw89_chanctx_track()
3134 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_chanctx_pause()
3135 enum rtw89_entity_mode mode; in rtw89_chanctx_pause() local
3137 lockdep_assert_wiphy(rtwdev->hw->wiphy); in rtw89_chanctx_pause()
3139 if (hal->entity_pause) in rtw89_chanctx_pause()
3142 rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx pause (rsn: %d)\n", pause_parm->rsn); in rtw89_chanctx_pause()
3144 mode = rtw89_get_entity_mode(rtwdev); in rtw89_chanctx_pause()
3145 switch (mode) { in rtw89_chanctx_pause()
3153 hal->entity_pause = true; in rtw89_chanctx_pause()
3161 if (!parm || !parm->cb) in rtw89_chanctx_proceed_cb()
3164 ret = parm->cb(rtwdev, parm->data); in rtw89_chanctx_proceed_cb()
3167 parm->caller ?: "unknown", ret); in rtw89_chanctx_proceed_cb()
3170 /* pass @cb_parm if there is a @cb_parm->cb which needs to invoke right after
3171 * call rtw89_set_channel() and right before proceed entity according to mode.
3176 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_chanctx_proceed()
3177 enum rtw89_entity_mode mode; in rtw89_chanctx_proceed() local
3180 lockdep_assert_wiphy(rtwdev->hw->wiphy); in rtw89_chanctx_proceed()
3182 if (unlikely(!hal->entity_pause)) { in rtw89_chanctx_proceed()
3189 hal->entity_pause = false; in rtw89_chanctx_proceed()
3194 mode = rtw89_get_entity_mode(rtwdev); in rtw89_chanctx_proceed()
3195 switch (mode) { in rtw89_chanctx_proceed()
3216 if (!rtwvif_link->chanctx_assigned) in __rtw89_swap_chanctx()
3219 if (rtwvif_link->chanctx_idx == idx1) in __rtw89_swap_chanctx()
3220 rtwvif_link->chanctx_idx = idx2; in __rtw89_swap_chanctx()
3221 else if (rtwvif_link->chanctx_idx == idx2) in __rtw89_swap_chanctx()
3222 rtwvif_link->chanctx_idx = idx1; in __rtw89_swap_chanctx()
3230 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_swap_chanctx()
3239 * __rtw89_config_entity_chandef() might set RTW89_CHANCTX_0 but no in rtw89_swap_chanctx()
3246 * in a NULL pointer deref as hal->chanctx[idx1].cfg is NULL. in rtw89_swap_chanctx()
3250 if (hal->chanctx[idx1].cfg == NULL || hal->chanctx[idx2].cfg == NULL) { in rtw89_swap_chanctx()
3253 idx1, hal->chanctx[idx1].cfg, idx2, hal->chanctx[idx2].cfg); in rtw89_swap_chanctx()
3258 hal->chanctx[idx1].cfg->idx = idx2; in rtw89_swap_chanctx()
3259 hal->chanctx[idx2].cfg->idx = idx1; in rtw89_swap_chanctx()
3261 swap(hal->chanctx[idx1], hal->chanctx[idx2]); in rtw89_swap_chanctx()
3266 cur = atomic_read(&hal->roc_chanctx_idx); in rtw89_swap_chanctx()
3268 atomic_set(&hal->roc_chanctx_idx, idx2); in rtw89_swap_chanctx()
3270 atomic_set(&hal->roc_chanctx_idx, idx1); in rtw89_swap_chanctx()
3276 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_chanctx_ops_add()
3277 struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; in rtw89_chanctx_ops_add()
3278 const struct rtw89_chip_info *chip = rtwdev->chip; in rtw89_chanctx_ops_add()
3281 idx = find_first_zero_bit(hal->entity_map, NUM_OF_RTW89_CHANCTX); in rtw89_chanctx_ops_add()
3282 if (idx >= chip->support_chanctx_num) in rtw89_chanctx_ops_add()
3283 return -ENOENT; in rtw89_chanctx_ops_add()
3285 rtw89_config_entity_chandef(rtwdev, idx, &ctx->def); in rtw89_chanctx_ops_add()
3286 cfg->idx = idx; in rtw89_chanctx_ops_add()
3287 cfg->ref_count = 0; in rtw89_chanctx_ops_add()
3288 hal->chanctx[idx].cfg = cfg; in rtw89_chanctx_ops_add()
3295 struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; in rtw89_chanctx_ops_remove()
3297 rtw89_config_entity_chandef(rtwdev, cfg->idx, NULL); in rtw89_chanctx_ops_remove()
3304 struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; in rtw89_chanctx_ops_change()
3305 u8 idx = cfg->idx; in rtw89_chanctx_ops_change()
3308 rtw89_config_entity_chandef(rtwdev, idx, &ctx->def); in rtw89_chanctx_ops_change()
3313 rtw89_chan_update_punctured(rtwdev, idx, &ctx->def); in rtw89_chanctx_ops_change()
3320 struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; in rtw89_chanctx_ops_assign_vif()
3321 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; in rtw89_chanctx_ops_assign_vif()
3322 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_chanctx_ops_assign_vif()
3323 struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt; in rtw89_chanctx_ops_assign_vif()
3327 rtwvif_link->chanctx_idx = cfg->idx; in rtw89_chanctx_ops_assign_vif()
3328 rtwvif_link->chanctx_assigned = true; in rtw89_chanctx_ops_assign_vif()
3329 cfg->ref_count++; in rtw89_chanctx_ops_assign_vif()
3331 if (rtwdev->scanning) in rtw89_chanctx_ops_assign_vif()
3332 rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); in rtw89_chanctx_ops_assign_vif()
3334 if (list_empty(&rtwvif->mgnt_entry)) in rtw89_chanctx_ops_assign_vif()
3335 list_add_tail(&rtwvif->mgnt_entry, &mgnt->active_list); in rtw89_chanctx_ops_assign_vif()
3337 if (cfg->idx == RTW89_CHANCTX_0) in rtw89_chanctx_ops_assign_vif()
3345 rtw89_swap_chanctx(rtwdev, cfg->idx, RTW89_CHANCTX_0); in rtw89_chanctx_ops_assign_vif()
3361 struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; in rtw89_chanctx_ops_unassign_vif()
3362 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; in rtw89_chanctx_ops_unassign_vif()
3363 struct rtw89_hal *hal = &rtwdev->hal; in rtw89_chanctx_ops_unassign_vif()
3369 rtwvif_link->chanctx_idx = RTW89_CHANCTX_0; in rtw89_chanctx_ops_unassign_vif()
3370 rtwvif_link->chanctx_assigned = false; in rtw89_chanctx_ops_unassign_vif()
3371 cfg->ref_count--; in rtw89_chanctx_ops_unassign_vif()
3373 if (rtwdev->scanning) in rtw89_chanctx_ops_unassign_vif()
3374 rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); in rtw89_chanctx_ops_unassign_vif()
3377 list_del_init(&rtwvif->mgnt_entry); in rtw89_chanctx_ops_unassign_vif()
3379 if (cfg->ref_count != 0) in rtw89_chanctx_ops_unassign_vif()
3382 if (cfg->idx != RTW89_CHANCTX_0) in rtw89_chanctx_ops_unassign_vif()
3385 roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_CHANCTX, in rtw89_chanctx_ops_unassign_vif()
3386 cfg->idx + 1); in rtw89_chanctx_ops_unassign_vif()
3394 rtw89_swap_chanctx(rtwdev, cfg->idx, roll); in rtw89_chanctx_ops_unassign_vif()
3397 if (!hal->entity_pause) { in rtw89_chanctx_ops_unassign_vif()
3412 if (hal->entity_pause) in rtw89_chanctx_ops_unassign_vif()
3418 /* re-plan MCC for chanctx changes. */ in rtw89_chanctx_ops_unassign_vif()
3457 _rtw89_chan_update_punctured(rtwdev, rtwvif_link, &new_ctx->def); in rtw89_chanctx_ops_reassign_vif()