Commit ef11a931 authored by John Crispin's avatar John Crispin Committed by Johannes Berg

mac80211: HE: add Spatial Reuse element parsing support

Add support to mac80211 for parsing SPR elements as per
P802.11ax_D4.0 section 9.4.2.241.
Signed-off-by: default avatarShashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: default avatarJohn Crispin <john@phrozen.org>
Link: https://lore.kernel.org/r/20190618061915.7102-2-john@phrozen.orgSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 3d07ffca
...@@ -1633,6 +1633,18 @@ struct ieee80211_he_operation { ...@@ -1633,6 +1633,18 @@ struct ieee80211_he_operation {
u8 optional[0]; u8 optional[0];
} __packed; } __packed;
/**
* struct ieee80211_he_spr - HE spatial reuse element
*
* This structure is the "HE spatial reuse element" element as
* described in P802.11ax_D4.0 section 9.4.2.241
*/
struct ieee80211_he_spr {
u8 he_sr_control;
/* Optional 0 to 19 bytes: depends on @he_sr_control */
u8 optional[0];
} __packed;
/** /**
* struct ieee80211_he_mu_edca_param_ac_rec - MU AC Parameter Record field * struct ieee80211_he_mu_edca_param_ac_rec - MU AC Parameter Record field
* *
...@@ -2071,6 +2083,42 @@ ieee80211_he_oper_size(const u8 *he_oper_ie) ...@@ -2071,6 +2083,42 @@ ieee80211_he_oper_size(const u8 *he_oper_ie)
return oper_len; return oper_len;
} }
/* HE Spatial Reuse defines */
#define IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT 0x4
#define IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT 0x8
/*
* ieee80211_he_spr_size - calculate 802.11ax HE Spatial Reuse IE size
* @he_spr_ie: byte data of the He Spatial Reuse IE, stating from the the byte
* after the ext ID byte. It is assumed that he_spr_ie has at least
* sizeof(struct ieee80211_he_spr) bytes, the caller must have validated
* this
* @return the actual size of the IE data (not including header), or 0 on error
*/
static inline u8
ieee80211_he_spr_size(const u8 *he_spr_ie)
{
struct ieee80211_he_spr *he_spr = (void *)he_spr_ie;
u8 spr_len = sizeof(struct ieee80211_he_spr);
u32 he_spr_params;
/* Make sure the input is not NULL */
if (!he_spr_ie)
return 0;
/* Calc required length */
he_spr_params = le32_to_cpu(he_spr->he_sr_control);
if (he_spr_params & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT)
spr_len++;
if (he_spr_params & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT)
spr_len += 18;
/* Add the first byte (extension ID) to the total length */
spr_len++;
return spr_len;
}
/* Authentication algorithms */ /* Authentication algorithms */
#define WLAN_AUTH_OPEN 0 #define WLAN_AUTH_OPEN 0
#define WLAN_AUTH_SHARED_KEY 1 #define WLAN_AUTH_SHARED_KEY 1
...@@ -2493,6 +2541,7 @@ enum ieee80211_eid_ext { ...@@ -2493,6 +2541,7 @@ enum ieee80211_eid_ext {
WLAN_EID_EXT_HE_OPERATION = 36, WLAN_EID_EXT_HE_OPERATION = 36,
WLAN_EID_EXT_UORA = 37, WLAN_EID_EXT_UORA = 37,
WLAN_EID_EXT_HE_MU_EDCA = 38, WLAN_EID_EXT_HE_MU_EDCA = 38,
WLAN_EID_EXT_HE_SPR = 39,
WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME = 52, WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME = 52,
WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION = 55, WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION = 55,
WLAN_EID_EXT_NON_INHERITANCE = 56, WLAN_EID_EXT_NON_INHERITANCE = 56,
......
...@@ -1480,6 +1480,7 @@ struct ieee802_11_elems { ...@@ -1480,6 +1480,7 @@ struct ieee802_11_elems {
const struct ieee80211_meshconf_ie *mesh_config; const struct ieee80211_meshconf_ie *mesh_config;
const u8 *he_cap; const u8 *he_cap;
const struct ieee80211_he_operation *he_operation; const struct ieee80211_he_operation *he_operation;
const struct ieee80211_he_spr *he_spr;
const struct ieee80211_mu_edca_param_set *mu_edca_param_set; const struct ieee80211_mu_edca_param_set *mu_edca_param_set;
const u8 *uora_element; const u8 *uora_element;
const u8 *mesh_id; const u8 *mesh_id;
......
...@@ -1240,6 +1240,10 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, ...@@ -1240,6 +1240,10 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION && WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION &&
elen == 3) { elen == 3) {
elems->mbssid_config_ie = (void *)&pos[1]; elems->mbssid_config_ie = (void *)&pos[1];
} else if (pos[0] == WLAN_EID_EXT_HE_SPR &&
elen >= sizeof(*elems->he_spr) &&
elen >= ieee80211_he_spr_size(&pos[1])) {
elems->he_spr = (void *)&pos[1];
} }
break; break;
default: default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment