mac80211: implement HE support for mesh
Implement the basics required for supporting high efficiency with mesh: include HE information elements in beacons, probe responses, and peering action frames, and check for compatible HE configurations when peering. Signed-off-by: Sven Eckelmann <seckelmann@datto.com> Forwarded: https://patchwork.kernel.org/patch/11029299/ Link: https://lore.kernel.org/r/20190724163359.3507-2-sven@narfation.org Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:

committed by
Johannes Berg

parent
a0b4496a43
commit
60ad72da55
@@ -532,6 +532,61 @@ int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mesh_add_he_cap_ie(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb, u8 ie_len)
|
||||
{
|
||||
const struct ieee80211_sta_he_cap *he_cap;
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 *pos;
|
||||
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return -EINVAL;
|
||||
|
||||
he_cap = ieee80211_get_he_iftype_cap(sband, NL80211_IFTYPE_MESH_POINT);
|
||||
|
||||
if (!he_cap ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
|
||||
return 0;
|
||||
|
||||
if (skb_tailroom(skb) < ie_len)
|
||||
return -ENOMEM;
|
||||
|
||||
pos = skb_put(skb, ie_len);
|
||||
ieee80211_ie_build_he_cap(pos, he_cap, pos + ie_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct ieee80211_sta_he_cap *he_cap;
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 *pos;
|
||||
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return -EINVAL;
|
||||
|
||||
he_cap = ieee80211_get_he_iftype_cap(sband, NL80211_IFTYPE_MESH_POINT);
|
||||
if (!he_cap ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
|
||||
return 0;
|
||||
|
||||
if (skb_tailroom(skb) < 2 + 1 + sizeof(struct ieee80211_he_operation))
|
||||
return -ENOMEM;
|
||||
|
||||
pos = skb_put(skb, 2 + 1 + sizeof(struct ieee80211_he_operation));
|
||||
ieee80211_ie_build_he_oper(pos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ieee80211_mesh_path_timer(struct timer_list *t)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata =
|
||||
@@ -677,6 +732,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
struct mesh_csa_settings *csa;
|
||||
enum nl80211_band band;
|
||||
u8 ie_len_he_cap;
|
||||
u8 *pos;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
int hdr_len = offsetofend(struct ieee80211_mgmt, u.beacon);
|
||||
@@ -687,6 +743,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
|
||||
band = chanctx_conf->def.chan->band;
|
||||
rcu_read_unlock();
|
||||
|
||||
ie_len_he_cap = ieee80211_ie_len_he_cap(sdata,
|
||||
NL80211_IFTYPE_MESH_POINT);
|
||||
head_len = hdr_len +
|
||||
2 + /* NULL SSID */
|
||||
/* Channel Switch Announcement */
|
||||
@@ -706,6 +764,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
|
||||
2 + sizeof(__le16) + /* awake window */
|
||||
2 + sizeof(struct ieee80211_vht_cap) +
|
||||
2 + sizeof(struct ieee80211_vht_operation) +
|
||||
ie_len_he_cap +
|
||||
2 + 1 + sizeof(struct ieee80211_he_operation) +
|
||||
ifmsh->ie_len;
|
||||
|
||||
bcn = kzalloc(sizeof(*bcn) + head_len + tail_len, GFP_KERNEL);
|
||||
@@ -823,6 +883,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
|
||||
mesh_add_awake_window_ie(sdata, skb) ||
|
||||
mesh_add_vht_cap_ie(sdata, skb) ||
|
||||
mesh_add_vht_oper_ie(sdata, skb) ||
|
||||
mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) ||
|
||||
mesh_add_he_oper_ie(sdata, skb) ||
|
||||
mesh_add_vendor_ies(sdata, skb))
|
||||
goto out_free;
|
||||
|
||||
|
Reference in New Issue
Block a user