Lines Matching +full:link +full:- +full:loss +full:- +full:low
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2013-2014, 2018-2020, 2022-2024 Intel Corporation
4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
11 #include "iwl-modparams.h"
13 #include "iwl-debug.h"
100 * Checking that we hold mvm->mutex is a good idea, but the rate in iwl_get_coex_type()
109 chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf); in iwl_get_coex_type()
112 chanctx_conf->def.chan->band != NL80211_BAND_2GHZ) { in iwl_get_coex_type()
119 phy_ctx_id = *((u16 *)chanctx_conf->drv_priv); in iwl_get_coex_type()
120 primary_ch_phy_id = le32_to_cpu(mvm->last_bt_ci_cmd.primary_ch_phy_id); in iwl_get_coex_type()
122 le32_to_cpu(mvm->last_bt_ci_cmd.secondary_ch_phy_id); in iwl_get_coex_type()
125 ret = le32_to_cpu(mvm->last_bt_notif.primary_ch_lut); in iwl_get_coex_type()
127 ret = le32_to_cpu(mvm->last_bt_notif.secondary_ch_lut); in iwl_get_coex_type()
128 /* else - default = TX TX disallowed */ in iwl_get_coex_type()
140 lockdep_assert_held(&mvm->mutex); in iwl_mvm_send_bt_init_conf()
142 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS)) { in iwl_mvm_send_bt_init_conf()
143 switch (mvm->bt_force_ant_mode) { in iwl_mvm_send_bt_init_conf()
171 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); in iwl_mvm_send_bt_init_conf()
172 memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd)); in iwl_mvm_send_bt_init_conf()
184 if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) in iwl_mvm_bt_coex_reduced_txp()
192 if (mvmsta->bt_reduced_txpower == enable) in iwl_mvm_bt_coex_reduced_txp()
195 value = mvmsta->deflink.sta_id; in iwl_mvm_bt_coex_reduced_txp()
204 mvmsta->bt_reduced_txpower = enable; in iwl_mvm_bt_coex_reduced_txp()
225 link_info->bf_data.last_bt_coex_event = rssi; in iwl_mvm_bt_coex_enable_rssi_event()
226 link_info->bf_data.bt_coex_max_thold = in iwl_mvm_bt_coex_enable_rssi_event()
227 enable ? -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH : 0; in iwl_mvm_bt_coex_enable_rssi_event()
228 link_info->bf_data.bt_coex_min_thold = in iwl_mvm_bt_coex_enable_rssi_event()
229 enable ? -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH : 0; in iwl_mvm_bt_coex_enable_rssi_event()
239 if (!time_after(now, mvm->bt_coex_last_tcm_ts + MVM_COEX_TCM_PERIOD)) in iwl_mvm_bt_coex_tcm_based_ci()
242 mvm->bt_coex_last_tcm_ts = now; in iwl_mvm_bt_coex_tcm_based_ci()
246 /* if the primary is low latency, it will stay primary */ in iwl_mvm_bt_coex_tcm_based_ci()
247 if (data->primary_ll) in iwl_mvm_bt_coex_tcm_based_ci()
250 if (data->primary_load >= data->secondary_load) in iwl_mvm_bt_coex_tcm_based_ci()
253 swap(data->primary, data->secondary); in iwl_mvm_bt_coex_tcm_based_ci()
257 * This function receives the LB link id and checks if eSR should be
268 iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, in iwl_mvm_bt_coex_calculate_esr_mode()
270 iwl_fw_lookup_notif_ver(mvm->fw, BT_COEX_GROUP, in iwl_mvm_bt_coex_calculate_esr_mode()
276 if (iwl_fw_lookup_notif_ver(mvm->fw, BT_COEX_GROUP, in iwl_mvm_bt_coex_calculate_esr_mode()
280 mvm->last_bt_wifi_loss.wifi_loss_mid_high_rssi[PHY_BAND_24][0]; in iwl_mvm_bt_coex_calculate_esr_mode()
282 mvm->last_bt_wifi_loss.wifi_loss_low_rssi[PHY_BAND_24][0]; in iwl_mvm_bt_coex_calculate_esr_mode()
284 wifi_loss_mid_high_rssi = mvm->last_bt_notif.wifi_loss_mid_high_rssi; in iwl_mvm_bt_coex_calculate_esr_mode()
285 wifi_loss_low_rssi = mvm->last_bt_notif.wifi_loss_low_rssi; in iwl_mvm_bt_coex_calculate_esr_mode()
300 * In case we don't know the RSSI - take the lower wifi loss, in iwl_mvm_bt_coex_calculate_esr_mode()
301 * so we will more likely enter eSR, and if RSSI is low - in iwl_mvm_bt_coex_calculate_esr_mode()
307 else if (mvmvif->esr_active) in iwl_mvm_bt_coex_calculate_esr_mode()
308 /* RSSI needs to get really low to disable eSR... */ in iwl_mvm_bt_coex_calculate_esr_mode()
310 link_rssi <= -IWL_MVM_BT_COEX_DISABLE_ESR_THRESH ? in iwl_mvm_bt_coex_calculate_esr_mode()
316 link_rssi <= -IWL_MVM_BT_COEX_ENABLE_ESR_THRESH ? in iwl_mvm_bt_coex_calculate_esr_mode()
328 struct iwl_mvm_vif_link_info *link = mvmvif->link[link_id]; in iwl_mvm_bt_coex_update_link_esr() local
331 !iwl_mvm_vif_from_mac80211(vif)->authorized || in iwl_mvm_bt_coex_update_link_esr()
332 WARN_ON(!link)) in iwl_mvm_bt_coex_update_link_esr()
336 (s8)link->beacon_stats.avg_signal, in iwl_mvm_bt_coex_update_link_esr()
338 /* In case we decided to exit eSR - stay with the primary */ in iwl_mvm_bt_coex_update_link_esr()
348 /* default smps_mode is AUTOMATIC - only used for client modes */ in iwl_mvm_bt_notif_per_link()
357 lockdep_assert_held(&mvm->mutex); in iwl_mvm_bt_notif_per_link()
359 link_info = mvmvif->link[link_id]; in iwl_mvm_bt_notif_per_link()
363 link_conf = rcu_dereference(vif->link_conf[link_id]); in iwl_mvm_bt_notif_per_link()
366 * in the middle of removing the link. in iwl_mvm_bt_notif_per_link()
371 chanctx_conf = rcu_dereference(link_conf->chanctx_conf); in iwl_mvm_bt_notif_per_link()
375 chanctx_conf->def.chan->band != NL80211_BAND_2GHZ)) { in iwl_mvm_bt_notif_per_link()
376 if (vif->type == NL80211_IFTYPE_STATION) { in iwl_mvm_bt_notif_per_link()
380 iwl_mvm_bt_coex_reduced_txp(mvm, link_info->ap_sta_id, in iwl_mvm_bt_notif_per_link()
390 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2)) in iwl_mvm_bt_notif_per_link()
395 bt_activity_grading = le32_to_cpu(data->notif->bt_activity_grading); in iwl_mvm_bt_notif_per_link()
402 if (!vif->cfg.assoc) in iwl_mvm_bt_notif_per_link()
405 if (link_info->phy_ctxt && in iwl_mvm_bt_notif_per_link()
406 (mvm->last_bt_notif.rrc_status & BIT(link_info->phy_ctxt->id))) in iwl_mvm_bt_notif_per_link()
409 IWL_DEBUG_COEX(data->mvm, in iwl_mvm_bt_notif_per_link()
410 "mac %d link %d: bt_activity_grading %d smps_req %d\n", in iwl_mvm_bt_notif_per_link()
411 mvmvif->id, link_info->fw_link_id, in iwl_mvm_bt_notif_per_link()
414 if (vif->type == NL80211_IFTYPE_STATION) in iwl_mvm_bt_notif_per_link()
418 /* low latency is always primary */ in iwl_mvm_bt_notif_per_link()
420 data->primary_ll = true; in iwl_mvm_bt_notif_per_link()
422 data->secondary = data->primary; in iwl_mvm_bt_notif_per_link()
423 data->primary = chanctx_conf; in iwl_mvm_bt_notif_per_link()
426 if (vif->type == NL80211_IFTYPE_AP) { in iwl_mvm_bt_notif_per_link()
427 if (!mvmvif->ap_ibss_active) in iwl_mvm_bt_notif_per_link()
430 if (chanctx_conf == data->primary) in iwl_mvm_bt_notif_per_link()
433 if (!data->primary_ll) { in iwl_mvm_bt_notif_per_link()
438 data->secondary = data->primary; in iwl_mvm_bt_notif_per_link()
439 data->primary = chanctx_conf; in iwl_mvm_bt_notif_per_link()
441 /* there is low latency vif - we will be secondary */ in iwl_mvm_bt_notif_per_link()
442 data->secondary = chanctx_conf; in iwl_mvm_bt_notif_per_link()
445 /* FIXME: TCM load per interface? or need something per link? */ in iwl_mvm_bt_notif_per_link()
446 if (data->primary == chanctx_conf) in iwl_mvm_bt_notif_per_link()
447 data->primary_load = mvm->tcm.result.load[mvmvif->id]; in iwl_mvm_bt_notif_per_link()
448 else if (data->secondary == chanctx_conf) in iwl_mvm_bt_notif_per_link()
449 data->secondary_load = mvm->tcm.result.load[mvmvif->id]; in iwl_mvm_bt_notif_per_link()
454 * STA / P2P Client, try to be primary if first vif. If we are in low in iwl_mvm_bt_notif_per_link()
457 if (!data->primary || data->primary == chanctx_conf) in iwl_mvm_bt_notif_per_link()
458 data->primary = chanctx_conf; in iwl_mvm_bt_notif_per_link()
459 else if (!data->secondary) in iwl_mvm_bt_notif_per_link()
461 data->secondary = chanctx_conf; in iwl_mvm_bt_notif_per_link()
463 /* FIXME: TCM load per interface? or need something per link? */ in iwl_mvm_bt_notif_per_link()
464 if (data->primary == chanctx_conf) in iwl_mvm_bt_notif_per_link()
465 data->primary_load = mvm->tcm.result.load[mvmvif->id]; in iwl_mvm_bt_notif_per_link()
466 else if (data->secondary == chanctx_conf) in iwl_mvm_bt_notif_per_link()
467 data->secondary_load = mvm->tcm.result.load[mvmvif->id]; in iwl_mvm_bt_notif_per_link()
475 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF || in iwl_mvm_bt_notif_per_link()
476 !vif->cfg.assoc) { in iwl_mvm_bt_notif_per_link()
477 iwl_mvm_bt_coex_reduced_txp(mvm, link_info->ap_sta_id, false); in iwl_mvm_bt_notif_per_link()
483 ave_rssi = link_info->bf_data.ave_beacon_signal; in iwl_mvm_bt_notif_per_link()
485 /* if the RSSI isn't valid, fake it is very low */ in iwl_mvm_bt_notif_per_link()
487 ave_rssi = -100; in iwl_mvm_bt_notif_per_link()
488 if (ave_rssi > -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH) { in iwl_mvm_bt_notif_per_link()
489 if (iwl_mvm_bt_coex_reduced_txp(mvm, link_info->ap_sta_id, in iwl_mvm_bt_notif_per_link()
492 } else if (ave_rssi < -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH) { in iwl_mvm_bt_notif_per_link()
493 if (iwl_mvm_bt_coex_reduced_txp(mvm, link_info->ap_sta_id, in iwl_mvm_bt_notif_per_link()
508 struct iwl_mvm *mvm = data->mvm; in iwl_mvm_bt_notif_iterator()
511 lockdep_assert_held(&mvm->mutex); in iwl_mvm_bt_notif_iterator()
513 switch (vif->type) { in iwl_mvm_bt_notif_iterator()
517 if (!mvmvif->ap_ibss_active) in iwl_mvm_bt_notif_iterator()
534 lockdep_assert_held(&mvm->mutex); in iwl_mvm_bt_coex_notif_iterator()
536 if (vif->type != NL80211_IFTYPE_STATION) in iwl_mvm_bt_coex_notif_iterator()
543 rcu_dereference_check(vif->link_conf[link_id], in iwl_mvm_bt_coex_notif_iterator()
544 lockdep_is_held(&mvm->mutex)); in iwl_mvm_bt_coex_notif_iterator()
546 rcu_dereference_check(link_conf->chanctx_conf, in iwl_mvm_bt_coex_notif_iterator()
547 lockdep_is_held(&mvm->mutex)); in iwl_mvm_bt_coex_notif_iterator()
550 chanctx_conf->def.chan->band != NL80211_BAND_2GHZ)) in iwl_mvm_bt_coex_notif_iterator()
561 .notif = &mvm->last_bt_notif, in iwl_mvm_bt_coex_notif_handle()
567 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS)) in iwl_mvm_bt_coex_notif_handle()
572 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, in iwl_mvm_bt_coex_notif_handle()
575 if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { in iwl_mvm_bt_coex_notif_handle()
584 if (WARN_ON(!chan->def.chan)) { in iwl_mvm_bt_coex_notif_handle()
589 if (chan->def.width < NL80211_CHAN_WIDTH_40) { in iwl_mvm_bt_coex_notif_handle()
592 if (chan->def.center_freq1 > in iwl_mvm_bt_coex_notif_handle()
593 chan->def.chan->center_freq) in iwl_mvm_bt_coex_notif_handle()
600 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx]; in iwl_mvm_bt_coex_notif_handle()
602 cpu_to_le32(*((u16 *)data.primary->drv_priv)); in iwl_mvm_bt_coex_notif_handle()
607 if (WARN_ON(!data.secondary->def.chan)) { in iwl_mvm_bt_coex_notif_handle()
612 if (chan->def.width < NL80211_CHAN_WIDTH_40) { in iwl_mvm_bt_coex_notif_handle()
615 if (chan->def.center_freq1 > in iwl_mvm_bt_coex_notif_handle()
616 chan->def.chan->center_freq) in iwl_mvm_bt_coex_notif_handle()
623 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx]; in iwl_mvm_bt_coex_notif_handle()
625 cpu_to_le32(*((u16 *)data.secondary->drv_priv)); in iwl_mvm_bt_coex_notif_handle()
631 if (memcmp(&cmd, &mvm->last_bt_ci_cmd, sizeof(cmd))) { in iwl_mvm_bt_coex_notif_handle()
635 memcpy(&mvm->last_bt_ci_cmd, &cmd, sizeof(cmd)); in iwl_mvm_bt_coex_notif_handle()
643 struct iwl_bt_coex_prof_old_notif *notif = (void *)pkt->data; in iwl_mvm_rx_bt_coex_old_notif()
646 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); in iwl_mvm_rx_bt_coex_old_notif()
648 le32_to_cpu(notif->primary_ch_lut)); in iwl_mvm_rx_bt_coex_old_notif()
650 le32_to_cpu(notif->secondary_ch_lut)); in iwl_mvm_rx_bt_coex_old_notif()
652 le32_to_cpu(notif->bt_activity_grading)); in iwl_mvm_rx_bt_coex_old_notif()
655 memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); in iwl_mvm_rx_bt_coex_old_notif()
664 const struct iwl_bt_coex_profile_notif *notif = (const void *)pkt->data; in iwl_mvm_rx_bt_coex_notif()
666 lockdep_assert_held(&mvm->mutex); in iwl_mvm_rx_bt_coex_notif()
668 mvm->last_bt_wifi_loss = *notif; in iwl_mvm_rx_bt_coex_notif()
670 ieee80211_iterate_active_interfaces(mvm->hw, in iwl_mvm_rx_bt_coex_notif()
682 lockdep_assert_held(&mvm->mutex); in iwl_mvm_bt_rssi_event()
685 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS)) in iwl_mvm_bt_rssi_event()
689 * Rssi update while not associated - can happen since the statistics in iwl_mvm_bt_rssi_event()
692 if (mvmvif->deflink.ap_sta_id == IWL_MVM_INVALID_STA) in iwl_mvm_bt_rssi_event()
695 /* No BT - reports should be disabled */ in iwl_mvm_bt_rssi_event()
696 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF) in iwl_mvm_bt_rssi_event()
699 IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid, in iwl_mvm_bt_rssi_event()
700 rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW"); in iwl_mvm_bt_rssi_event()
709 mvmvif->deflink.ap_sta_id, in iwl_mvm_bt_rssi_event()
713 mvmvif->deflink.ap_sta_id, in iwl_mvm_bt_rssi_event()
727 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); in iwl_mvm_coex_agg_time_limit()
728 struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->deflink.phy_ctxt; in iwl_mvm_coex_agg_time_limit()
731 if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id)) in iwl_mvm_coex_agg_time_limit()
734 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < in iwl_mvm_coex_agg_time_limit()
738 lut_type = iwl_get_coex_type(mvm, mvmsta->vif); in iwl_mvm_coex_agg_time_limit()
751 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); in iwl_mvm_bt_coex_is_mimo_allowed()
752 struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->deflink.phy_ctxt; in iwl_mvm_bt_coex_is_mimo_allowed()
755 if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id)) in iwl_mvm_bt_coex_is_mimo_allowed()
758 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < in iwl_mvm_bt_coex_is_mimo_allowed()
769 lut_type = iwl_get_coex_type(mvm, mvmsta->vif); in iwl_mvm_bt_coex_is_mimo_allowed()
775 if (ant & mvm->cfg->non_shared_ant) in iwl_mvm_bt_coex_is_ant_avail()
778 return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < in iwl_mvm_bt_coex_is_ant_avail()
784 return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < BT_HIGH_TRAFFIC; in iwl_mvm_bt_coex_is_shared_ant_avail()
790 u32 bt_activity = le32_to_cpu(mvm->last_bt_notif.bt_activity_grading); in iwl_mvm_bt_coex_is_tpc_allowed()
800 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2) && in iwl_mvm_bt_coex_get_single_ant_msk()
801 (mvm->cfg->non_shared_ant & enabled_ants)) in iwl_mvm_bt_coex_get_single_ant_msk()
802 return mvm->cfg->non_shared_ant; in iwl_mvm_bt_coex_get_single_ant_msk()
810 __le16 fc = hdr->frame_control; in iwl_mvm_bt_coex_tx_prio()
813 if (info->band != NL80211_BAND_2GHZ) in iwl_mvm_bt_coex_tx_prio()
816 if (unlikely(mvm->bt_tx_prio)) in iwl_mvm_bt_coex_tx_prio()
817 return mvm->bt_tx_prio - 1; in iwl_mvm_bt_coex_tx_prio()
831 } else if (is_multicast_ether_addr(hdr->addr1)) { in iwl_mvm_bt_coex_tx_prio()