net/mac80211/mlme.c

Source file repositories/reference/linux-study-clean/net/mac80211/mlme.c

File Facts

System
Linux kernel
Corpus path
net/mac80211/mlme.c
Extension
.c
Size
348689 bytes
Lines
11924
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ieee80211_determine_ap_chan_data {
	/* input data */
	struct ieee80211_channel *channel;
	const struct ieee802_11_elems *elems;
	const struct ieee80211_conn_settings *conn;
	u32 vht_cap_info;
	bool ignore_ht_channel_mismatch;
	const struct cfg80211_chan_def *cur_chandef;
	bool cur_dbe_used;

	/* target chandef is filled in */
	struct cfg80211_chan_def *chandef;
};

struct ieee80211_determine_ap_chan_output {
	/* filled to indicate UHR DBE was used */
	bool dbe_used;
	/* and need to know non-DBE width */
	enum nl80211_chan_width non_dbe_width;
};

static enum ieee80211_conn_mode
ieee80211_determine_ap_chan(struct ieee80211_sub_if_data *sdata,
			    const struct ieee80211_determine_ap_chan_data *data,
			    struct ieee80211_determine_ap_chan_output *out)
{
	bool ignore_ht_channel_mismatch = data->ignore_ht_channel_mismatch;
	const struct ieee802_11_elems *elems = data->elems;
	const struct ieee80211_ht_operation *ht_oper = elems->ht_operation;
	const struct ieee80211_vht_operation *vht_oper = elems->vht_operation;
	const struct ieee80211_he_operation *he_oper = elems->he_operation;
	const struct ieee80211_eht_operation *eht_oper = elems->eht_operation;
	const struct ieee80211_uhr_operation *uhr_oper = elems->uhr_operation;
	const struct ieee80211_conn_settings *conn = data->conn;
	struct ieee80211_channel *channel = data->channel;
	struct cfg80211_chan_def *chandef = data->chandef;
	struct ieee80211_supported_band *sband =
		sdata->local->hw.wiphy->bands[channel->band];
	struct cfg80211_chan_def vht_chandef;
	bool no_vht = false;
	u32 ht_cfreq;

	memset(out, 0, sizeof(*out));

	if (ieee80211_hw_check(&sdata->local->hw, STRICT))
		ignore_ht_channel_mismatch = false;

	*chandef = (struct cfg80211_chan_def) {
		.chan = channel,
		.width = NL80211_CHAN_WIDTH_20_NOHT,
		.center_freq1 = channel->center_freq,
		.freq1_offset = channel->freq_offset,
	};

	/* get special S1G case out of the way */
	if (sband->band == NL80211_BAND_S1GHZ) {
		if (!ieee80211_chandef_s1g_oper(sdata->local, elems->s1g_oper,
						chandef)) {
			/* Fallback to default 1MHz */
			chandef->width = NL80211_CHAN_WIDTH_1;
			chandef->s1g_primary_2mhz = false;
		}

		return IEEE80211_CONN_MODE_S1G;
	}

	/* get special 6 GHz case out of the way */
	if (sband->band == NL80211_BAND_6GHZ) {
		enum ieee80211_conn_mode mode = IEEE80211_CONN_MODE_HIGHEST;

		/* this is an error */
		if (conn->mode < IEEE80211_CONN_MODE_HE)
			return IEEE80211_CONN_MODE_LEGACY;

		if (!elems->he_6ghz_capa || !elems->he_cap) {
			sdata_info(sdata,
				   "HE 6 GHz AP is missing HE/HE 6 GHz band capability\n");
			return IEEE80211_CONN_MODE_LEGACY;
		}

		if (!eht_oper || !elems->eht_cap) {
			eht_oper = NULL;
			mode = IEEE80211_CONN_MODE_HE;
		}

		if (!ieee80211_chandef_he_6ghz_oper(sdata->local, he_oper,
						    eht_oper, chandef)) {
			sdata_info(sdata, "bad HE/EHT 6 GHz operation\n");
			return IEEE80211_CONN_MODE_LEGACY;
		}

Annotation

Implementation Notes