Commit ba323e29 authored by Johannes Berg's avatar Johannes Berg
Browse files

wifi: mac80211: separate out connection downgrade flags



Separate out the connection downgrade flags from the ifmgd->flags
and put them into the link information instead. While at it, make
them a separate sparse type so we don't get confused about where
they belong and have static checking on correct handling.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 062e8e02
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -770,20 +770,21 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
	struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
	enum nl80211_channel_type ch_type;
	int err;
	u32 sta_flags;
	ieee80211_conn_flags_t conn_flags;
	u32 vht_cap_info = 0;

	sdata_assert_lock(sdata);

	sta_flags = IEEE80211_STA_DISABLE_VHT;
	conn_flags = IEEE80211_CONN_DISABLE_VHT;

	switch (ifibss->chandef.width) {
	case NL80211_CHAN_WIDTH_5:
	case NL80211_CHAN_WIDTH_10:
	case NL80211_CHAN_WIDTH_20_NOHT:
		sta_flags |= IEEE80211_STA_DISABLE_HT;
		conn_flags |= IEEE80211_CONN_DISABLE_HT;
		fallthrough;
	case NL80211_CHAN_WIDTH_20:
		sta_flags |= IEEE80211_STA_DISABLE_40MHZ;
		conn_flags |= IEEE80211_CONN_DISABLE_40MHZ;
		break;
	default:
		break;
@@ -796,7 +797,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
	err = ieee80211_parse_ch_switch_ie(sdata, elems,
					   ifibss->chandef.chan->band,
					   vht_cap_info,
					   sta_flags, ifibss->bssid, &csa_ie);
					   conn_flags, ifibss->bssid, &csa_ie);
	/* can't switch to destination channel, fail */
	if (err < 0)
		goto disconnect;
@@ -839,7 +840,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
		}
		break;
	default:
		/* should not happen, sta_flags should prevent VHT modes. */
		/* should not happen, conn_flags should prevent VHT modes. */
		WARN_ON(1);
		goto disconnect;
	}
+21 −17
Original line number Diff line number Diff line
@@ -358,20 +358,25 @@ struct ieee80211_roc_work {
enum ieee80211_sta_flags {
	IEEE80211_STA_CONNECTION_POLL	= BIT(1),
	IEEE80211_STA_CONTROL_PORT	= BIT(2),
	IEEE80211_STA_DISABLE_HT	= BIT(4),
	IEEE80211_STA_MFP_ENABLED	= BIT(6),
	IEEE80211_STA_UAPSD_ENABLED	= BIT(7),
	IEEE80211_STA_NULLFUNC_ACKED	= BIT(8),
	IEEE80211_STA_RESET_SIGNAL_AVE	= BIT(9),
	IEEE80211_STA_DISABLE_40MHZ	= BIT(10),
	IEEE80211_STA_DISABLE_VHT	= BIT(11),
	IEEE80211_STA_DISABLE_80P80MHZ	= BIT(12),
	IEEE80211_STA_DISABLE_160MHZ	= BIT(13),
	IEEE80211_STA_DISABLE_WMM	= BIT(14),
	IEEE80211_STA_ENABLE_RRM	= BIT(15),
	IEEE80211_STA_DISABLE_HE	= BIT(16),
	IEEE80211_STA_DISABLE_EHT	= BIT(17),
	IEEE80211_STA_DISABLE_320MHZ	= BIT(18),
};

typedef u32 __bitwise ieee80211_conn_flags_t;

enum ieee80211_conn_flags {
	IEEE80211_CONN_DISABLE_HT	= (__force ieee80211_conn_flags_t)BIT(0),
	IEEE80211_CONN_DISABLE_40MHZ	= (__force ieee80211_conn_flags_t)BIT(1),
	IEEE80211_CONN_DISABLE_VHT	= (__force ieee80211_conn_flags_t)BIT(2),
	IEEE80211_CONN_DISABLE_80P80MHZ	= (__force ieee80211_conn_flags_t)BIT(3),
	IEEE80211_CONN_DISABLE_160MHZ	= (__force ieee80211_conn_flags_t)BIT(4),
	IEEE80211_CONN_DISABLE_HE	= (__force ieee80211_conn_flags_t)BIT(5),
	IEEE80211_CONN_DISABLE_EHT	= (__force ieee80211_conn_flags_t)BIT(6),
	IEEE80211_CONN_DISABLE_320MHZ	= (__force ieee80211_conn_flags_t)BIT(7),
};

struct ieee80211_mgd_auth_data {
@@ -875,6 +880,8 @@ struct ieee80211_link_data_managed {
	enum ieee80211_smps_mode req_smps, /* requested smps mode */
				 driver_smps_mode; /* smps mode request */

	ieee80211_conn_flags_t conn_flags;

	s16 p2p_noa_index;

	bool have_beacon;
@@ -2051,12 +2058,9 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
 * @elems: parsed 802.11 elements received with the frame
 * @current_band: indicates the current band
 * @vht_cap_info: VHT capabilities of the transmitter
 * @sta_flags: contains information about own capabilities and restrictions
 *	to decide which channel switch announcements can be accepted. Only the
 *	following subset of &enum ieee80211_sta_flags are evaluated:
 *	%IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT,
 *	%IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ,
 *	%IEEE80211_STA_DISABLE_160MHZ.
 * @conn_flags: contains information about own capabilities and restrictions
 *	to decide which channel switch announcements can be accepted, using
 *	flags from &enum ieee80211_conn_flags.
 * @bssid: the currently connected bssid (for reporting)
 * @csa_ie: parsed 802.11 csa elements on count, mode, chandef and mesh ttl.
	All of them will be filled with if success only.
@@ -2066,7 +2070,7 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
				 struct ieee802_11_elems *elems,
				 enum nl80211_band current_band,
				 u32 vht_cap_info,
				 u32 sta_flags, u8 *bssid,
				 ieee80211_conn_flags_t conn_flags, u8 *bssid,
				 struct ieee80211_csa_ie *csa_ie);

/* Suspend/resume and hw reconfiguration */
@@ -2297,7 +2301,7 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
				const struct cfg80211_chan_def *chandef);
u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata, u8 iftype);
u8 *ieee80211_ie_build_he_cap(u32 disable_flags, u8 *pos,
u8 *ieee80211_ie_build_he_cap(ieee80211_conn_flags_t disable_flags, u8 *pos,
			      const struct ieee80211_sta_he_cap *he_cap,
			      u8 *end);
void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata,
@@ -2336,7 +2340,7 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
				    struct cfg80211_chan_def *chandef);
bool ieee80211_chandef_s1g_oper(const struct ieee80211_s1g_oper_ie *oper,
				struct cfg80211_chan_def *chandef);
u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c);
ieee80211_conn_flags_t ieee80211_chandef_downgrade(struct cfg80211_chan_def *c);

int __must_check
ieee80211_link_use_channel(struct ieee80211_link_data *link,
+6 −6
Original line number Diff line number Diff line
@@ -1129,7 +1129,8 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
	struct ieee80211_supported_band *sband;
	int err;
	u32 sta_flags, vht_cap_info = 0;
	ieee80211_conn_flags_t conn_flags = 0;
	u32 vht_cap_info = 0;

	sdata_assert_lock(sdata);

@@ -1137,16 +1138,15 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
	if (!sband)
		return false;

	sta_flags = 0;
	switch (sdata->vif.bss_conf.chandef.width) {
	case NL80211_CHAN_WIDTH_20_NOHT:
		sta_flags |= IEEE80211_STA_DISABLE_HT;
		conn_flags |= IEEE80211_CONN_DISABLE_HT;
		fallthrough;
	case NL80211_CHAN_WIDTH_20:
		sta_flags |= IEEE80211_STA_DISABLE_40MHZ;
		conn_flags |= IEEE80211_CONN_DISABLE_40MHZ;
		fallthrough;
	case NL80211_CHAN_WIDTH_40:
		sta_flags |= IEEE80211_STA_DISABLE_VHT;
		conn_flags |= IEEE80211_CONN_DISABLE_VHT;
		break;
	default:
		break;
@@ -1159,7 +1159,7 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
	memset(&params, 0, sizeof(params));
	err = ieee80211_parse_ch_switch_ie(sdata, elems, sband->band,
					   vht_cap_info,
					   sta_flags, sdata->vif.addr,
					   conn_flags, sdata->vif.addr,
					   &csa_ie);
	if (err < 0)
		return false;
+161 −153

File changed.

Preview size limit exceeded, changes collapsed.

+8 −8
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
 * Copyright 2007-2008, Intel Corporation
 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
 * Copyright (C) 2018, 2020 Intel Corporation
 * Copyright (C) 2018, 2020, 2022 Intel Corporation
 */

#include <linux/ieee80211.h>
@@ -23,7 +23,7 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
				 struct ieee802_11_elems *elems,
				 enum nl80211_band current_band,
				 u32 vht_cap_info,
				 u32 sta_flags, u8 *bssid,
				 ieee80211_conn_flags_t conn_flags, u8 *bssid,
				 struct ieee80211_csa_ie *csa_ie)
{
	enum nl80211_band new_band = current_band;
@@ -40,13 +40,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
	sec_chan_offs = elems->sec_chan_offs;
	wide_bw_chansw_ie = elems->wide_bw_chansw_ie;

	if (sta_flags & (IEEE80211_STA_DISABLE_HT |
			 IEEE80211_STA_DISABLE_40MHZ)) {
	if (conn_flags & (IEEE80211_CONN_DISABLE_HT |
			  IEEE80211_CONN_DISABLE_40MHZ)) {
		sec_chan_offs = NULL;
		wide_bw_chansw_ie = NULL;
	}

	if (sta_flags & IEEE80211_STA_DISABLE_VHT)
	if (conn_flags & IEEE80211_CONN_DISABLE_VHT)
		wide_bw_chansw_ie = NULL;

	if (elems->ext_chansw_ie) {
@@ -93,7 +93,7 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,

	if (sec_chan_offs) {
		secondary_channel_offset = sec_chan_offs->sec_chan_offs;
	} else if (!(sta_flags & IEEE80211_STA_DISABLE_HT)) {
	} else if (!(conn_flags & IEEE80211_CONN_DISABLE_HT)) {
		/* If the secondary channel offset IE is not present,
		 * we can't know what's the post-CSA offset, so the
		 * best we can do is use 20MHz.
@@ -160,10 +160,10 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
						&new_vht_chandef))
			new_vht_chandef.chan = NULL;

		if (sta_flags & IEEE80211_STA_DISABLE_80P80MHZ &&
		if (conn_flags & IEEE80211_CONN_DISABLE_80P80MHZ &&
		    new_vht_chandef.width == NL80211_CHAN_WIDTH_80P80)
			ieee80211_chandef_downgrade(&new_vht_chandef);
		if (sta_flags & IEEE80211_STA_DISABLE_160MHZ &&
		if (conn_flags & IEEE80211_CONN_DISABLE_160MHZ &&
		    new_vht_chandef.width == NL80211_CHAN_WIDTH_160)
			ieee80211_chandef_downgrade(&new_vht_chandef);
	}
Loading