diff options
Diffstat (limited to 'sys/contrib/dev/iwlwifi/mvm/coex.c')
| -rw-r--r-- | sys/contrib/dev/iwlwifi/mvm/coex.c | 88 | 
1 files changed, 73 insertions, 15 deletions
| diff --git a/sys/contrib/dev/iwlwifi/mvm/coex.c b/sys/contrib/dev/iwlwifi/mvm/coex.c index ad3e14a0d043..13cdc077d8d3 100644 --- a/sys/contrib/dev/iwlwifi/mvm/coex.c +++ b/sys/contrib/dev/iwlwifi/mvm/coex.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2013-2014, 2018-2020, 2022-2024 Intel Corporation + * Copyright (C) 2013-2014, 2018-2020, 2022-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   */  #include <linux/ieee80211.h> @@ -181,7 +181,7 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,  	struct iwl_mvm_sta *mvmsta;  	u32 value; -	if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) +	if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)  		return 0;  	mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id); @@ -208,7 +208,7 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,  }  struct iwl_bt_iterator_data { -	struct iwl_bt_coex_profile_notif *notif; +	struct iwl_bt_coex_prof_old_notif *notif;  	struct iwl_mvm *mvm;  	struct ieee80211_chanctx_conf *primary;  	struct ieee80211_chanctx_conf *secondary; @@ -266,10 +266,26 @@ iwl_mvm_bt_coex_calculate_esr_mode(struct iwl_mvm *mvm,  	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);  	bool have_wifi_loss_rate =  		iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, -					BT_PROFILE_NOTIFICATION, 0) > 4; +					BT_PROFILE_NOTIFICATION, 0) > 4 || +		iwl_fw_lookup_notif_ver(mvm->fw, BT_COEX_GROUP, +					PROFILE_NOTIF, 0) >= 1; +	u8 wifi_loss_mid_high_rssi; +	u8 wifi_loss_low_rssi;  	u8 wifi_loss_rate; -	if (mvm->last_bt_notif.wifi_loss_low_rssi == BT_OFF) +	if (iwl_fw_lookup_notif_ver(mvm->fw, BT_COEX_GROUP, +				    PROFILE_NOTIF, 0) >= 1) { +		/* For now, we consider 2.4 GHz band / ANT_A only */ +		wifi_loss_mid_high_rssi = +			mvm->last_bt_wifi_loss.wifi_loss_mid_high_rssi[PHY_BAND_24][0]; +		wifi_loss_low_rssi = +			mvm->last_bt_wifi_loss.wifi_loss_low_rssi[PHY_BAND_24][0]; +	} else { +		wifi_loss_mid_high_rssi = mvm->last_bt_notif.wifi_loss_mid_high_rssi; +		wifi_loss_low_rssi = mvm->last_bt_notif.wifi_loss_low_rssi; +	} + +	if (wifi_loss_low_rssi == BT_OFF)  		return true;  	if (primary) @@ -286,20 +302,20 @@ iwl_mvm_bt_coex_calculate_esr_mode(struct iwl_mvm *mvm,  	 * we will get an update on this and exit eSR.  	 */  	if (!link_rssi) -		wifi_loss_rate = mvm->last_bt_notif.wifi_loss_mid_high_rssi; +		wifi_loss_rate = wifi_loss_mid_high_rssi;  	else if (mvmvif->esr_active)  		 /* RSSI needs to get really low to disable eSR... */  		wifi_loss_rate =  			link_rssi <= -IWL_MVM_BT_COEX_DISABLE_ESR_THRESH ? -				mvm->last_bt_notif.wifi_loss_low_rssi : -				mvm->last_bt_notif.wifi_loss_mid_high_rssi; +				wifi_loss_low_rssi : +				wifi_loss_mid_high_rssi;  	else  		/* ...And really high before we enable it back */  		wifi_loss_rate =  			link_rssi <= -IWL_MVM_BT_COEX_ENABLE_ESR_THRESH ? -				mvm->last_bt_notif.wifi_loss_low_rssi : -				mvm->last_bt_notif.wifi_loss_mid_high_rssi; +				wifi_loss_low_rssi : +				wifi_loss_mid_high_rssi;  	return wifi_loss_rate <= IWL_MVM_BT_COEX_WIFI_LOSS_THRESH;  } @@ -509,6 +525,32 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,  		iwl_mvm_bt_notif_per_link(mvm, vif, data, link_id);  } +/* must be called under rcu_read_lock */ +static void iwl_mvm_bt_coex_notif_iterator(void *_data, u8 *mac, +					   struct ieee80211_vif *vif) +{ +	struct iwl_mvm *mvm = _data; +	struct ieee80211_bss_conf *link_conf; +	unsigned int link_id; + +	lockdep_assert_held(&mvm->mutex); + +	if (vif->type != NL80211_IFTYPE_STATION) +		return; + +	for_each_vif_active_link(vif, link_conf, link_id) { +		struct ieee80211_chanctx_conf *chanctx_conf = +			rcu_dereference_check(link_conf->chanctx_conf, +					      lockdep_is_held(&mvm->mutex)); + +		if ((!chanctx_conf || +		     chanctx_conf->def.chan->band != NL80211_BAND_2GHZ)) +			continue; + +		iwl_mvm_bt_coex_update_link_esr(mvm, vif, link_id); +	} +} +  static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)  {  	struct iwl_bt_iterator_data data = { @@ -527,7 +569,7 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)  					mvm->hw, IEEE80211_IFACE_ITER_NORMAL,  					iwl_mvm_bt_notif_iterator, &data); -	if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { +	if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {  		rcu_read_unlock();  		return;  	} @@ -591,11 +633,11 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)  	}  } -void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, -			      struct iwl_rx_cmd_buffer *rxb) +void iwl_mvm_rx_bt_coex_old_notif(struct iwl_mvm *mvm, +				  struct iwl_rx_cmd_buffer *rxb)  {  	struct iwl_rx_packet *pkt = rxb_addr(rxb); -	struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; +	struct iwl_bt_coex_prof_old_notif *notif = (void *)pkt->data;  	IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");  	IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); @@ -612,6 +654,22 @@ void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,  	iwl_mvm_bt_coex_notif_handle(mvm);  } +void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, +			      struct iwl_rx_cmd_buffer *rxb) +{ +	const struct iwl_rx_packet *pkt = rxb_addr(rxb); +	const struct iwl_bt_coex_profile_notif *notif = (const void *)pkt->data; + +	lockdep_assert_held(&mvm->mutex); + +	mvm->last_bt_wifi_loss = *notif; + +	ieee80211_iterate_active_interfaces(mvm->hw, +					    IEEE80211_IFACE_ITER_NORMAL, +					    iwl_mvm_bt_coex_notif_iterator, +					    mvm); +} +  void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  			   enum ieee80211_rssi_event_data rssi_event)  { @@ -628,7 +686,7 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  	 * Rssi update while not associated - can happen since the statistics  	 * are handled asynchronously  	 */ -	if (mvmvif->deflink.ap_sta_id == IWL_MVM_INVALID_STA) +	if (mvmvif->deflink.ap_sta_id == IWL_INVALID_STA)  		return;  	/* No BT - reports should be disabled */ | 
