drivers/net/wireless/intel/iwlwifi/mld/phy.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/intel/iwlwifi/mld/phy.c
Extension
.c
Size
5929 bytes
Lines
217
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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_mld_chanctx_usage_data {
	struct iwl_mld *mld;
	struct ieee80211_chanctx_conf *ctx;
	bool use_def;
};

static bool iwl_mld_chanctx_fils_enabled(struct ieee80211_vif *vif,
					 struct ieee80211_chanctx_conf *ctx)
{
	if (vif->type != NL80211_IFTYPE_AP)
		return false;

	return cfg80211_channel_is_psc(ctx->def.chan) ||
		(ctx->def.chan->band == NL80211_BAND_6GHZ &&
		 ctx->def.width >= NL80211_CHAN_WIDTH_80);
}

static void iwl_mld_chanctx_usage_iter(void *_data, u8 *mac,
				       struct ieee80211_vif *vif)
{
	struct iwl_mld_chanctx_usage_data *data = _data;
	struct ieee80211_bss_conf *link_conf;
	int link_id;

	for_each_vif_active_link(vif, link_conf, link_id) {
		if (rcu_access_pointer(link_conf->chanctx_conf) != data->ctx)
			continue;

		if (vif->type == NL80211_IFTYPE_AP && link_conf->ftm_responder)
			data->use_def = true;

		if (iwl_mld_chanctx_fils_enabled(vif, data->ctx))
			data->use_def = true;
	}
}

struct cfg80211_chan_def *
iwl_mld_get_chandef_from_chanctx(struct iwl_mld *mld,
				 struct ieee80211_chanctx_conf *ctx)
{
	struct iwl_mld_chanctx_usage_data data = {
		.mld = mld,
		.ctx = ctx,
	};

	ieee80211_iterate_active_interfaces_mtx(mld->hw,
						IEEE80211_IFACE_ITER_NORMAL,
						iwl_mld_chanctx_usage_iter,
						&data);

	return data.use_def ? &ctx->def : &ctx->min_def;
}

static u8
iwl_mld_nl80211_width_to_fw(enum nl80211_chan_width width)
{
	switch (width) {
	case NL80211_CHAN_WIDTH_20_NOHT:
	case NL80211_CHAN_WIDTH_20:
		return IWL_PHY_CHANNEL_MODE20;
	case NL80211_CHAN_WIDTH_40:
		return IWL_PHY_CHANNEL_MODE40;
	case NL80211_CHAN_WIDTH_80:
		return IWL_PHY_CHANNEL_MODE80;
	case NL80211_CHAN_WIDTH_160:
		return IWL_PHY_CHANNEL_MODE160;
	case NL80211_CHAN_WIDTH_320:
		return IWL_PHY_CHANNEL_MODE320;
	default:
		WARN(1, "Invalid channel width=%u", width);
		return IWL_PHY_CHANNEL_MODE20;
	}
}

/* Maps the driver specific control channel position (relative to the center
 * freq) definitions to the fw values
 */
static u8 _iwl_mld_get_fw_ctrl_pos(u32 control, u32 cf1)
{
	int offs = control - cf1;
	int abs_offs = abs(offs);
	u8 ret;

	if (offs == 0) {
		/* The FW is expected to check the control channel position only
		 * when in HT/VHT and the channel width is not 20MHz. Return
		 * this value as the default one.
		 */
		return 0;
	}

Annotation

Implementation Notes