drivers/net/wireless/intel/iwlwifi/mvm/coex.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/intel/iwlwifi/mvm/coex.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/intel/iwlwifi/mvm/coex.c
Extension
.c
Size
19376 bytes
Lines
715
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct iwl_bt_iterator_data {
	struct iwl_bt_coex_prof_old_notif *notif;
	struct iwl_mvm *mvm;
	struct ieee80211_chanctx_conf *primary;
	struct ieee80211_chanctx_conf *secondary;
	bool primary_ll;
	u8 primary_load;
	u8 secondary_load;
};

static inline
void iwl_mvm_bt_coex_enable_rssi_event(struct iwl_mvm *mvm,
				       struct iwl_mvm_vif_link_info *link_info,
				       bool enable, int rssi)
{
	link_info->bf_data.last_bt_coex_event = rssi;
	link_info->bf_data.bt_coex_max_thold =
		enable ? -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH : 0;
	link_info->bf_data.bt_coex_min_thold =
		enable ? -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH : 0;
}

#define MVM_COEX_TCM_PERIOD (HZ * 10)

static void iwl_mvm_bt_coex_tcm_based_ci(struct iwl_mvm *mvm,
					 struct iwl_bt_iterator_data *data)
{
	unsigned long now = jiffies;

	if (!time_after(now, mvm->bt_coex_last_tcm_ts + MVM_COEX_TCM_PERIOD))
		return;

	mvm->bt_coex_last_tcm_ts = now;

	/* We assume here that we don't have more than 2 vifs on 2.4GHz */

	/* if the primary is low latency, it will stay primary */
	if (data->primary_ll)
		return;

	if (data->primary_load >= data->secondary_load)
		return;

	swap(data->primary, data->secondary);
}

static void iwl_mvm_bt_notif_per_link(struct iwl_mvm *mvm,
				      struct ieee80211_vif *vif,
				      struct iwl_bt_iterator_data *data,
				      unsigned int link_id)
{
	/* default smps_mode is AUTOMATIC - only used for client modes */
	enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_AUTOMATIC;
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	u32 bt_activity_grading, min_ag_for_static_smps;
	struct ieee80211_chanctx_conf *chanctx_conf;
	struct iwl_mvm_vif_link_info *link_info;
	struct ieee80211_bss_conf *link_conf;
	int ave_rssi;

	lockdep_assert_held(&mvm->mutex);

	link_info = mvmvif->link[link_id];
	if (!link_info)
		return;

	link_conf = rcu_dereference(vif->link_conf[link_id]);
	/* This can happen due to races: if we receive the notification
	 * and have the mutex held, while mac80211 is stuck on our mutex
	 * in the middle of removing the link.
	 */
	if (!link_conf)
		return;

	chanctx_conf = rcu_dereference(link_conf->chanctx_conf);

	/* If channel context is invalid or not on 2.4GHz .. */
	if ((!chanctx_conf ||
	     chanctx_conf->def.chan->band != NL80211_BAND_2GHZ)) {
		if (vif->type == NL80211_IFTYPE_STATION) {
			/* ... relax constraints and disable rssi events */
			iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
					    smps_mode, link_id);
			iwl_mvm_bt_coex_reduced_txp(mvm, link_info->ap_sta_id,
						    false);
			iwl_mvm_bt_coex_enable_rssi_event(mvm, link_info, false,
							  0);
		}
		return;
	}

Annotation

Implementation Notes