2021-06-18 12:33:07

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 00/31] cfg80211/mac80211 patches from our internal tree 2021-06-18

From: Luca Coelho <[email protected]>

Hi,

A bunch of patches with mac80211 and cfg80211 changes from our
internal tree.

Please review, though you have already reviewed (or even written!)
most if not all of them. ;)

Thanks!

Cheers,


Avraham Stern (2):
cfg80211: avoid double free of PMSR request
nl80211/cfg80211: add BSS color to NDP ranging parameters

Ilan Peer (3):
mac80211: Properly WARN on HW scan before restart
cfg80211: Support hidden AP discovery over 6GHz band
mac8021: Allow probe request injection on passive non radar channels

Johannes Berg (19):
cfg80211: make certificate generation more robust
mac80211: allow SMPS requests only in client mode
mac80211: free skb in WEP error case
ieee80211: add defines for HE PHY cap byte 10
cfg80211: add cfg80211_any_usable_channels()
mac80211: conditionally advertise HE in probe requests
mac80211: always include HE 6GHz capability in probe request
mac80211: always include HE 6GHz capability in assoc request
mac80211: rearrange struct txq_info for fewer holes
mac80211: handle various extensible elements correctly
mac80211: improve AP disconnect message
cfg80211: trace more information in assoc trace event
mac80211: reset profile_periodicity/ema_ap
mac80211: remove use of ieee80211_get_he_sta_cap()
cfg80211: remove ieee80211_get_he_sta_cap()
cfg80211: allow advertising vendor-specific capabilities
mac80211: add vendor-specific capabilities to assoc request
mac80211: notify driver on mgd TX completion
cfg80211: reg: improve bad regulatory warning

Krishnanand Prabhu (1):
ieee80211: define timing measurement in extended capabilities IE

Miri Korenblit (1):
cfg80211: set custom regdomain after wiphy registration

Mordechay Goodstein (1):
mac80211: handle rate control (RC) racing with chanctx definition

Shaul Triebitz (4):
mac80211: add HE 6GHz cap IE in 6GHz band only
mac80211: do not add twice the HE 6GHz cap IE
mac80211: move SMPS mode setting after ieee80211_prep_connection
mac80211: add to bss_conf if broadcast TWT is supported

drivers/net/wireless/ath/ath9k/main.c | 2 +-
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 +-
drivers/net/wireless/realtek/rtw88/mac80211.c | 2 +-
include/linux/ieee80211.h | 9 +-
include/net/cfg80211.h | 38 ++-
include/net/mac80211.h | 32 ++-
include/uapi/linux/nl80211.h | 9 +-
net/mac80211/chan.c | 108 +++++---
net/mac80211/driver-ops.h | 26 +-
net/mac80211/he.c | 5 +-
net/mac80211/ht.c | 18 +-
net/mac80211/ieee80211_i.h | 9 +-
net/mac80211/main.c | 16 +-
net/mac80211/mlme.c | 240 +++++++++---------
net/mac80211/trace.h | 33 ++-
net/mac80211/tx.c | 27 +-
net/mac80211/util.c | 59 +++--
net/wireless/Makefile | 2 +-
net/wireless/chan.c | 33 ++-
net/wireless/core.c | 8 +-
net/wireless/nl80211.c | 5 +
net/wireless/pmsr.c | 28 +-
net/wireless/rdev-ops.h | 12 +-
net/wireless/reg.c | 5 +-
net/wireless/scan.c | 16 +-
net/wireless/trace.h | 36 ++-
26 files changed, 528 insertions(+), 256 deletions(-)

--
2.32.0


2021-06-18 12:33:12

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 02/31] mac80211: do not add twice the HE 6GHz cap IE

From: Shaul Triebitz <[email protected]>

The HE 6GHz capability IE is already added before:
ieee80211_add_he_ie -> ieee80211_ie_build_he_6ghz_cap

Signed-off-by: Shaul Triebitz <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/mlme.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 2480bd0577bb..310cfd02fda4 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -8,7 +8,7 @@
* Copyright 2007, Michael Wu <[email protected]>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
- * Copyright (C) 2018 - 2020 Intel Corporation
+ * Copyright (C) 2018 - 2021 Intel Corporation
*/

#include <linux/delay.h>
--
2.32.0

2021-06-18 12:33:12

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 01/31] mac80211: add HE 6GHz cap IE in 6GHz band only

From: Shaul Triebitz <[email protected]>

The HE 6GHz capability IE should be added to the
association request only when operating in the 6GHz band.

Signed-off-by: Shaul Triebitz <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/util.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 0a0481f5af48..a0ff27487686 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -6,7 +6,7 @@
* Copyright 2007 Johannes Berg <[email protected]>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2020 Intel Corporation
+ * Copyright (C) 2018-2021 Intel Corporation
*
* utilities for mac80211
*/
@@ -2950,6 +2950,9 @@ void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata,
if (!sband)
return;

+ if (sband->band != NL80211_BAND_6GHZ)
+ return;
+
iftd = ieee80211_get_sband_iftype_data(sband, iftype);
if (WARN_ON(!iftd))
return;
--
2.32.0

2021-06-18 12:33:13

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 03/31] ieee80211: define timing measurement in extended capabilities IE

From: Krishnanand Prabhu <[email protected]>

Define the bit used for timing measurement support in extended
capabilities IE, used for time synchronization.

Signed-off-by: Krishnanand Prabhu <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
include/linux/ieee80211.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 2967437f1b11..16a3a133cd20 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -9,7 +9,7 @@
* Copyright (c) 2006, Michael Wu <[email protected]>
* Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright (c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright (c) 2018 - 2020 Intel Corporation
+ * Copyright (c) 2018 - 2021 Intel Corporation
*/

#ifndef LINUX_IEEE80211_H
@@ -3110,6 +3110,11 @@ enum ieee80211_tdls_actioncode {
*/
#define WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT BIT(6)

+/* Timing Measurement protocol for time sync is set in the 7th bit of 3rd byte
+ * of the @WLAN_EID_EXT_CAPABILITY information element
+ */
+#define WLAN_EXT_CAPA3_TIMING_MEASUREMENT_SUPPORT BIT(7)
+
/* TDLS capabilities in the 4th byte of @WLAN_EID_EXT_CAPABILITY */
#define WLAN_EXT_CAPA4_TDLS_BUFFER_STA BIT(4)
#define WLAN_EXT_CAPA4_TDLS_PEER_PSM BIT(5)
--
2.32.0

2021-06-18 12:33:21

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 05/31] mac80211: handle rate control (RC) racing with chanctx definition

From: Mordechay Goodstein <[email protected]>

chanctx represents the current phy configuration and rate scale uses
it for achieving max throughput, so if phy changes bandwidth to narrow
bandwidth, RC should be _first_ updated to avoid using the wider bandwidth
before updating the phy, and vice versa.

We assume in the patch that station interface is always updated before
updating phy context by calling ieee80211_vif_update_chandef.

Signed-off-by: Mordechay Goodstein <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/chan.c | 108 ++++++++++++++++++++++++++++----------------
net/mac80211/mlme.c | 89 +-----------------------------------
2 files changed, 71 insertions(+), 126 deletions(-)

diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 907bb1f748a1..76fc36a68750 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* mac80211 - channel management
+ * Copyright 2020 - 2021 Intel Corporation
*/

#include <linux/nl80211.h>
@@ -308,8 +309,8 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
* the max of min required widths of all the interfaces bound to this
* channel context.
*/
-void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
- struct ieee80211_chanctx *ctx)
+static u32 _ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
+ struct ieee80211_chanctx *ctx)
{
enum nl80211_chan_width max_bw;
struct cfg80211_chan_def min_def;
@@ -326,7 +327,7 @@ void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
ctx->conf.def.width == NL80211_CHAN_WIDTH_16 ||
ctx->conf.radar_enabled) {
ctx->conf.min_def = ctx->conf.def;
- return;
+ return 0;
}

max_bw = ieee80211_get_chanctx_max_required_bw(local, &ctx->conf);
@@ -337,17 +338,21 @@ void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
ieee80211_chandef_downgrade(&min_def);

if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def))
- return;
+ return 0;

ctx->conf.min_def = min_def;
if (!ctx->driver_present)
- return;
+ return 0;

- drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH);
+ return IEEE80211_CHANCTX_CHANGE_MIN_WIDTH;
}

+/* calling this function is assuming that station vif is updated to
+ * lates changes by calling ieee80211_vif_update_chandef
+ */
static void ieee80211_chan_bw_change(struct ieee80211_local *local,
- struct ieee80211_chanctx *ctx)
+ struct ieee80211_chanctx *ctx,
+ bool narrowed)
{
struct sta_info *sta;
struct ieee80211_supported_band *sband =
@@ -366,9 +371,16 @@ static void ieee80211_chan_bw_change(struct ieee80211_local *local,
continue;

new_sta_bw = ieee80211_sta_cur_vht_bw(sta);
+
+ /* nothing change */
if (new_sta_bw == sta->sta.bandwidth)
continue;

+ /* vif changed to narrow BW and narrow BW for station wasn't
+ * requested or vise versa */
+ if ((new_sta_bw < sta->sta.bandwidth) == !narrowed)
+ continue;
+
sta->sta.bandwidth = new_sta_bw;
rate_control_rate_update(local, sband, sta,
IEEE80211_RC_BW_CHANGED);
@@ -376,21 +388,34 @@ static void ieee80211_chan_bw_change(struct ieee80211_local *local,
rcu_read_unlock();
}

-static void ieee80211_change_chanctx(struct ieee80211_local *local,
- struct ieee80211_chanctx *ctx,
- const struct cfg80211_chan_def *chandef)
+/*
+ * recalc the min required chan width of the channel context, which is
+ * the max of min required widths of all the interfaces bound to this
+ * channel context.
+ */
+void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
+ struct ieee80211_chanctx *ctx)
{
- enum nl80211_chan_width width;
+ u32 changed = _ieee80211_recalc_chanctx_min_def(local, ctx);

- if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) {
- ieee80211_recalc_chanctx_min_def(local, ctx);
+ if (!changed)
return;
- }

- WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
+ /* check is BW narrowed */
+ ieee80211_chan_bw_change(local, ctx, true);

- width = ctx->conf.def.width;
- ctx->conf.def = *chandef;
+ drv_change_chanctx(local, ctx, changed);
+
+ /* check is BW wider */
+ ieee80211_chan_bw_change(local, ctx, false);
+}
+
+static void ieee80211_change_chanctx(struct ieee80211_local *local,
+ struct ieee80211_chanctx *ctx,
+ struct ieee80211_chanctx *old_ctx,
+ const struct cfg80211_chan_def *chandef)
+{
+ u32 changed;

/* expected to handle only 20/40/80/160 channel widths */
switch (chandef->width) {
@@ -405,19 +430,33 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
WARN_ON(1);
}

- if (chandef->width < width)
- ieee80211_chan_bw_change(local, ctx);
+ /* Check maybe BW narrowed - we do this _before_ calling recalc_chanctx_min_def
+ * due to maybe not returning from it, e.g in case new context was added
+ * first time with all parameters up to date.
+ */
+ ieee80211_chan_bw_change(local, old_ctx, true);
+
+ if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) {
+ ieee80211_recalc_chanctx_min_def(local, ctx);
+ return;
+ }

- drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH);
- ieee80211_recalc_chanctx_min_def(local, ctx);
+ WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
+
+ ctx->conf.def = *chandef;
+
+ /* check if min chanctx also changed */
+ changed = IEEE80211_CHANCTX_CHANGE_WIDTH |
+ _ieee80211_recalc_chanctx_min_def(local, ctx);
+ drv_change_chanctx(local, ctx, changed);

if (!local->use_chanctx) {
local->_oper_chandef = *chandef;
ieee80211_hw_config(local, 0);
}

- if (chandef->width > width)
- ieee80211_chan_bw_change(local, ctx);
+ /* check is BW wider */
+ ieee80211_chan_bw_change(local, old_ctx, false);
}

static struct ieee80211_chanctx *
@@ -450,7 +489,7 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
if (!compat)
continue;

- ieee80211_change_chanctx(local, ctx, compat);
+ ieee80211_change_chanctx(local, ctx, ctx, compat);

return ctx;
}
@@ -679,7 +718,7 @@ void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
if (!compat)
return;

- ieee80211_change_chanctx(local, ctx, compat);
+ ieee80211_change_chanctx(local, ctx, ctx, compat);
}

static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local,
@@ -1107,13 +1146,12 @@ ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
if (WARN_ON(!chandef))
return -EINVAL;

- if (old_ctx->conf.def.width > new_ctx->conf.def.width)
- ieee80211_chan_bw_change(local, new_ctx);
+ if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width)
+ changed = BSS_CHANGED_BANDWIDTH;

- ieee80211_change_chanctx(local, new_ctx, chandef);
+ ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);

- if (old_ctx->conf.def.width < new_ctx->conf.def.width)
- ieee80211_chan_bw_change(local, new_ctx);
+ ieee80211_change_chanctx(local, new_ctx, old_ctx, chandef);

vif_chsw[0].vif = &sdata->vif;
vif_chsw[0].old_ctx = &old_ctx->conf;
@@ -1142,14 +1180,9 @@ ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
if (ieee80211_chanctx_refcount(local, old_ctx) == 0)
ieee80211_free_chanctx(local, old_ctx);

- if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width)
- changed = BSS_CHANGED_BANDWIDTH;
-
- ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
-
+ ieee80211_recalc_chanctx_min_def(local, new_ctx);
ieee80211_recalc_smps_chanctx(local, new_ctx);
ieee80211_recalc_radar_chanctx(local, new_ctx);
- ieee80211_recalc_chanctx_min_def(local, new_ctx);

if (changed)
ieee80211_bss_info_change_notify(sdata, changed);
@@ -1188,7 +1221,7 @@ ieee80211_vif_use_reserved_assign(struct ieee80211_sub_if_data *sdata)
if (WARN_ON(!chandef))
return -EINVAL;

- ieee80211_change_chanctx(local, new_ctx, chandef);
+ ieee80211_change_chanctx(local, new_ctx, new_ctx, chandef);

list_del(&sdata->reserved_chanctx_list);
sdata->reserved_chanctx = NULL;
@@ -1505,7 +1538,6 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
ieee80211_recalc_smps_chanctx(local, ctx);
ieee80211_recalc_radar_chanctx(local, ctx);
ieee80211_recalc_chanctx_min_def(local, ctx);
- ieee80211_chan_bw_change(local, ctx);

list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
reserved_chanctx_list) {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 310cfd02fda4..fe7120f3b2ba 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -371,7 +371,6 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
struct cfg80211_chan_def chandef;
u16 ht_opmode;
u32 flags;
- enum ieee80211_sta_rx_bandwidth new_sta_bw;
u32 vht_cap_info = 0;
int ret;

@@ -450,35 +449,8 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
return -EINVAL;
}

- switch (chandef.width) {
- case NL80211_CHAN_WIDTH_20_NOHT:
- case NL80211_CHAN_WIDTH_20:
- new_sta_bw = IEEE80211_STA_RX_BW_20;
- break;
- case NL80211_CHAN_WIDTH_40:
- new_sta_bw = IEEE80211_STA_RX_BW_40;
- break;
- case NL80211_CHAN_WIDTH_80:
- new_sta_bw = IEEE80211_STA_RX_BW_80;
- break;
- case NL80211_CHAN_WIDTH_80P80:
- case NL80211_CHAN_WIDTH_160:
- new_sta_bw = IEEE80211_STA_RX_BW_160;
- break;
- default:
- return -EINVAL;
- }
-
- if (new_sta_bw > sta->cur_max_bandwidth)
- new_sta_bw = sta->cur_max_bandwidth;
-
- if (new_sta_bw < sta->sta.bandwidth) {
- sta->sta.bandwidth = new_sta_bw;
- rate_control_rate_update(local, sband, sta,
- IEEE80211_RC_BW_CHANGED);
- }
-
ret = ieee80211_vif_change_bandwidth(sdata, &chandef, changed);
+
if (ret) {
sdata_info(sdata,
"AP %pM changed bandwidth to incompatible one - disconnect\n",
@@ -486,12 +458,6 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
return ret;
}

- if (new_sta_bw > sta->sta.bandwidth) {
- sta->sta.bandwidth = new_sta_bw;
- rate_control_rate_update(local, sband, sta,
- IEEE80211_RC_BW_CHANGED);
- }
-
return 0;
}

@@ -1183,10 +1149,6 @@ static void ieee80211_chswitch_work(struct work_struct *work)
*/

if (sdata->reserved_chanctx) {
- struct ieee80211_supported_band *sband = NULL;
- struct sta_info *mgd_sta = NULL;
- enum ieee80211_sta_rx_bandwidth bw = IEEE80211_STA_RX_BW_20;
-
/*
* with multi-vif csa driver may call ieee80211_csa_finish()
* many times while waiting for other interfaces to use their
@@ -1195,48 +1157,6 @@ static void ieee80211_chswitch_work(struct work_struct *work)
if (sdata->reserved_ready)
goto out;

- if (sdata->vif.bss_conf.chandef.width !=
- sdata->csa_chandef.width) {
- /*
- * For managed interface, we need to also update the AP
- * station bandwidth and align the rate scale algorithm
- * on the bandwidth change. Here we only consider the
- * bandwidth of the new channel definition (as channel
- * switch flow does not have the full HT/VHT/HE
- * information), assuming that if additional changes are
- * required they would be done as part of the processing
- * of the next beacon from the AP.
- */
- switch (sdata->csa_chandef.width) {
- case NL80211_CHAN_WIDTH_20_NOHT:
- case NL80211_CHAN_WIDTH_20:
- default:
- bw = IEEE80211_STA_RX_BW_20;
- break;
- case NL80211_CHAN_WIDTH_40:
- bw = IEEE80211_STA_RX_BW_40;
- break;
- case NL80211_CHAN_WIDTH_80:
- bw = IEEE80211_STA_RX_BW_80;
- break;
- case NL80211_CHAN_WIDTH_80P80:
- case NL80211_CHAN_WIDTH_160:
- bw = IEEE80211_STA_RX_BW_160;
- break;
- }
-
- mgd_sta = sta_info_get(sdata, ifmgd->bssid);
- sband =
- local->hw.wiphy->bands[sdata->csa_chandef.chan->band];
- }
-
- if (sdata->vif.bss_conf.chandef.width >
- sdata->csa_chandef.width) {
- mgd_sta->sta.bandwidth = bw;
- rate_control_rate_update(local, sband, mgd_sta,
- IEEE80211_RC_BW_CHANGED);
- }
-
ret = ieee80211_vif_use_reserved_context(sdata);
if (ret) {
sdata_info(sdata,
@@ -1247,13 +1167,6 @@ static void ieee80211_chswitch_work(struct work_struct *work)
goto out;
}

- if (sdata->vif.bss_conf.chandef.width <
- sdata->csa_chandef.width) {
- mgd_sta->sta.bandwidth = bw;
- rate_control_rate_update(local, sband, mgd_sta,
- IEEE80211_RC_BW_CHANGED);
- }
-
goto out;
}

--
2.32.0

2021-06-18 12:33:24

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 06/31] cfg80211: avoid double free of PMSR request

From: Avraham Stern <[email protected]>

If cfg80211_pmsr_process_abort() moves all the PMSR requests that
need to be freed into a local list before aborting and freeing them.
As a result, it is possible that cfg80211_pmsr_complete() will run in
parallel and free the same PMSR request.

Fix it by freeing the request in cfg80211_pmsr_complete() only if it
is still in the original pmsr list.

Signed-off-by: Avraham Stern <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/wireless/pmsr.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
index 6bdd96408022..d245968b74cb 100644
--- a/net/wireless/pmsr.c
+++ b/net/wireless/pmsr.c
@@ -334,6 +334,7 @@ void cfg80211_pmsr_complete(struct wireless_dev *wdev,
gfp_t gfp)
{
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+ struct cfg80211_pmsr_request *tmp, *prev, *to_free = NULL;
struct sk_buff *msg;
void *hdr;

@@ -364,9 +365,20 @@ void cfg80211_pmsr_complete(struct wireless_dev *wdev,
nlmsg_free(msg);
free_request:
spin_lock_bh(&wdev->pmsr_lock);
- list_del(&req->list);
+ /*
+ * cfg80211_pmsr_process_abort() may have already moved this request
+ * to the free list, and will free it later. In this case, don't free
+ * it here.
+ */
+ list_for_each_entry_safe(tmp, prev, &wdev->pmsr_list, list) {
+ if (tmp == req) {
+ list_del(&req->list);
+ to_free = req;
+ break;
+ }
+ }
spin_unlock_bh(&wdev->pmsr_lock);
- kfree(req);
+ kfree(to_free);
}
EXPORT_SYMBOL_GPL(cfg80211_pmsr_complete);

--
2.32.0

2021-06-18 12:33:24

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 07/31] mac80211: allow SMPS requests only in client mode

From: Johannes Berg <[email protected]>

The code currently allows this for AP mode, but then ignores
it. Clarify that since the spec doesn't allow it in AP mode.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/ht.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 3d62a80b5790..2eb7641f5556 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -9,7 +9,7 @@
* Copyright 2007, Michael Wu <[email protected]>
* Copyright 2007-2010, Intel Corporation
* Copyright 2017 Intel Deutschland GmbH
- * Copyright(c) 2020 Intel Corporation
+ * Copyright(c) 2020-2021 Intel Corporation
*/

#include <linux/ieee80211.h>
@@ -555,17 +555,15 @@ void ieee80211_request_smps(struct ieee80211_vif *vif,
{
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);

- if (WARN_ON_ONCE(vif->type != NL80211_IFTYPE_STATION &&
- vif->type != NL80211_IFTYPE_AP))
+ if (WARN_ON_ONCE(vif->type != NL80211_IFTYPE_STATION))
return;

- if (vif->type == NL80211_IFTYPE_STATION) {
- if (sdata->u.mgd.driver_smps_mode == smps_mode)
- return;
- sdata->u.mgd.driver_smps_mode = smps_mode;
- ieee80211_queue_work(&sdata->local->hw,
- &sdata->u.mgd.request_smps_work);
- }
+ if (sdata->u.mgd.driver_smps_mode == smps_mode)
+ return;
+
+ sdata->u.mgd.driver_smps_mode = smps_mode;
+ ieee80211_queue_work(&sdata->local->hw,
+ &sdata->u.mgd.request_smps_work);
}
/* this might change ... don't want non-open drivers using it */
EXPORT_SYMBOL_GPL(ieee80211_request_smps);
--
2.32.0

2021-06-18 12:33:24

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 08/31] mac80211: free skb in WEP error case

From: Johannes Berg <[email protected]>

If, for some strange reason, ieee80211_wep_encrypt() fails in
ieee80211_send_auth() free the SKB instead of sending out the
useless frame, in addition to the warning. This can't really
happen since the SKB was freshly allocated.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/util.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index a0ff27487686..0f6fd90f6696 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1693,7 +1693,10 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
- WARN_ON(err);
+ if (WARN_ON(err)) {
+ kfree_skb(skb);
+ return;
+ }
}

IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
--
2.32.0

2021-06-18 12:33:27

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 09/31] mac80211: move SMPS mode setting after ieee80211_prep_connection

From: Shaul Triebitz <[email protected]>

ieee80211_mgd_assoc calls ieee80211_prep_connection which
might call ieee80211_prep_channel and set smps_mode to OFF.
That will override the previous setting of smps_mode in
ieee80211_mgd_assoc and HT SMPS will be set to "disabled"
in the association request frame.

Move the setting of smps_mode in ieee80211_mgd_assoc to
after the call to ieee80211_prep_connection.

Signed-off-by: Shaul Triebitz <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/mlme.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index fe7120f3b2ba..cc9bb4b9f8dc 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -5564,15 +5564,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2 * FILS_NONCE_LEN);

assoc_data->bss = req->bss;
-
- if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
- if (ifmgd->powersave)
- sdata->smps_mode = IEEE80211_SMPS_DYNAMIC;
- else
- sdata->smps_mode = IEEE80211_SMPS_OFF;
- } else
- sdata->smps_mode = ifmgd->req_smps;
-
assoc_data->capability = req->bss->capability;
assoc_data->supp_rates = bss->supp_rates;
assoc_data->supp_rates_len = bss->supp_rates_len;
@@ -5679,6 +5670,15 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
if (err)
goto err_clear;

+ if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
+ if (ifmgd->powersave)
+ sdata->smps_mode = IEEE80211_SMPS_DYNAMIC;
+ else
+ sdata->smps_mode = IEEE80211_SMPS_OFF;
+ } else {
+ sdata->smps_mode = ifmgd->req_smps;
+ }
+
rcu_read_lock();
beacon_ies = rcu_dereference(req->bss->beacon_ies);

--
2.32.0

2021-06-18 12:33:30

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 10/31] mac80211: add to bss_conf if broadcast TWT is supported

From: Shaul Triebitz <[email protected]>

Add to struct ieee80211_bss_conf a twt_broadcast field.
Set it to true if both STA and AP support broadcast TWT.

Signed-off-by: Shaul Triebitz <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
include/net/mac80211.h | 4 +++-
net/mac80211/mlme.c | 18 ++++++++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 445b66c6eb7e..c575240b02c8 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -7,7 +7,7 @@
* Copyright 2007-2010 Johannes Berg <[email protected]>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
- * Copyright (C) 2018 - 2020 Intel Corporation
+ * Copyright (C) 2018 - 2021 Intel Corporation
*/

#ifndef MAC80211_H
@@ -526,6 +526,7 @@ struct ieee80211_fils_discovery {
* @twt_responder: does this BSS support TWT requester (relevant for managed
* mode only, set if the AP advertises TWT responder role)
* @twt_protected: does this BSS support protected TWT frames
+ * @twt_broadcast: does this BSS support broadcast TWT
* @assoc: association status
* @ibss_joined: indicates whether this station is part of an IBSS
* or not
@@ -642,6 +643,7 @@ struct ieee80211_bss_conf {
bool twt_requester;
bool twt_responder;
bool twt_protected;
+ bool twt_broadcast;
/* association related data */
bool assoc, ibss_joined;
bool ibss_creator;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index cc9bb4b9f8dc..6457415e4797 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3227,6 +3227,21 @@ static int ieee80211_recalc_twt_req(struct ieee80211_sub_if_data *sdata,
return 0;
}

+static bool ieee80211_twt_bcast_support(struct ieee80211_bss_conf *bss_conf,
+ struct ieee80211_supported_band *sband,
+ struct sta_info *sta)
+{
+ const struct ieee80211_sta_he_cap *own_he_cap =
+ ieee80211_get_he_sta_cap(sband);
+
+ return bss_conf->he_support &&
+ (sta->sta.he_cap.he_cap_elem.mac_cap_info[2] &
+ IEEE80211_HE_MAC_CAP2_BCAST_TWT) &&
+ own_he_cap &&
+ (own_he_cap->he_cap_elem.mac_cap_info[2] &
+ IEEE80211_HE_MAC_CAP2_BCAST_TWT);
+}
+
static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
struct cfg80211_bss *cbss,
struct ieee80211_mgmt *mgmt, size_t len,
@@ -3442,6 +3457,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
bss_conf->twt_protected = false;
}

+ bss_conf->twt_broadcast =
+ ieee80211_twt_bcast_support(bss_conf, sband, sta);
+
if (bss_conf->he_support) {
bss_conf->he_bss_color.color =
le32_get_bits(elems->he_operation->he_oper_params,
--
2.32.0

2021-06-18 12:33:55

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 04/31] cfg80211: make certificate generation more robust

From: Johannes Berg <[email protected]>

If all net/wireless/certs/*.hex files are deleted, the build
will hang at this point since the 'cat' command will have no
arguments. Do "echo | cat - ..." so that even if the "..."
part is empty, the whole thing won't hang.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/wireless/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index 2eee93985ab0..af590ae606b6 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -28,7 +28,7 @@ $(obj)/shipped-certs.c: $(wildcard $(srctree)/$(src)/certs/*.hex)
@$(kecho) " GEN [email protected]"
@(echo '#include "reg.h"'; \
echo 'const u8 shipped_regdb_certs[] = {'; \
- cat $^ ; \
+ echo | cat - $^ ; \
echo '};'; \
echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);'; \
) > [email protected]
--
2.32.0

2021-06-18 12:34:22

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 13/31] ieee80211: add defines for HE PHY cap byte 10

From: Johannes Berg <[email protected]>

One bit out of the previously completely reserved byte 10 in
the PHY capabilities is used since 802.11ax D7.0, add a new
define for it.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
include/linux/ieee80211.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 16a3a133cd20..ab6bc225cf5d 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2179,6 +2179,8 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_RESERVED 0xc0
#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_MASK 0xc0

+#define IEEE80211_HE_PHY_CAP10_HE_MU_M1RU_MAX_LTF 0x01
+
/* 802.11ax HE TX/RX MCS NSS Support */
#define IEEE80211_TX_RX_MCS_NSS_SUPP_HIGHEST_MCS_POS (3)
#define IEEE80211_TX_RX_MCS_NSS_SUPP_TX_BITMAP_POS (6)
--
2.32.0

2021-06-18 12:34:33

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 15/31] mac80211: conditionally advertise HE in probe requests

From: Johannes Berg <[email protected]>

While building probe requests, only enable HE capability if
there are actually any channels in the band with HE enabled,
otherwise we're not really capable. We're doing the same in
association requests, so doing it here makes it consistent.

This also makes HE not appear available if it isn't due to
regulatory constraints.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/util.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 0f6fd90f6696..22cab76a9c2f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1938,7 +1938,9 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
}

he_cap = ieee80211_get_he_sta_cap(sband);
- if (he_cap) {
+ if (he_cap &&
+ cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band),
+ IEEE80211_CHAN_NO_HE)) {
pos = ieee80211_ie_build_he_cap(pos, he_cap, end);
if (!pos)
goto out_err;
--
2.32.0

2021-06-18 12:35:06

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 16/31] cfg80211: Support hidden AP discovery over 6GHz band

From: Ilan Peer <[email protected]>

To discover a hidden AP on the 6GHz band, the probe request
sent to the AP needs to include the AP's SSID, as some APs
would not respond with a probe response based only on short
SSID match.

To support hidden AP discovery over the 6GHz band,
when constructing the specific 6GHz band scan also include
SSIDs that were part of the original scan request, so these
can be used in the probe requests transmitted during scan.

Signed-off-by: Ilan Peer <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/wireless/scan.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 4f06c1825029..86cd66952131 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -5,7 +5,7 @@
* Copyright 2008 Johannes Berg <[email protected]>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright 2016 Intel Deutschland GmbH
- * Copyright (C) 2018-2020 Intel Corporation
+ * Copyright (C) 2018-2021 Intel Corporation
*/
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -757,7 +757,8 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev)
}

request = kzalloc(struct_size(request, channels, n_channels) +
- sizeof(*request->scan_6ghz_params) * count,
+ sizeof(*request->scan_6ghz_params) * count +
+ sizeof(*request->ssids) * rdev_req->n_ssids,
GFP_KERNEL);
if (!request) {
cfg80211_free_coloc_ap_list(&coloc_ap_list);
@@ -848,9 +849,18 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev)

if (request->n_channels) {
struct cfg80211_scan_request *old = rdev->int_scan_req;
-
rdev->int_scan_req = request;

+ /*
+ * Add the ssids from the parent scan request to the new scan
+ * request, so the driver would be able to use them in its
+ * probe requests to discover hidden APs on PSC channels.
+ */
+ request->ssids = (void *)&request->channels[request->n_channels];
+ request->n_ssids = rdev_req->n_ssids;
+ memcpy(request->ssids, rdev_req->ssids, sizeof(*request->ssids) *
+ request->n_ssids);
+
/*
* If this scan follows a previous scan, save the scan start
* info from the first part of the scan
--
2.32.0

2021-06-18 12:35:19

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 11/31] nl80211/cfg80211: add BSS color to NDP ranging parameters

From: Avraham Stern <[email protected]>

In NDP ranging, the initiator need to set the BSS color in the NDP
to the BSS color of the responder. Add the BSS color as a parameter
for NDP ranging.

Signed-off-by: Avraham Stern <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
include/net/cfg80211.h | 8 ++++++--
include/uapi/linux/nl80211.h | 6 +++++-
net/wireless/pmsr.c | 12 ++++++++++++
3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 5224f885a99a..6a54caa6fa16 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -7,7 +7,7 @@
* Copyright 2006-2010 Johannes Berg <[email protected]>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2020 Intel Corporation
+ * Copyright (C) 2018-2021 Intel Corporation
*/

#include <linux/ethtool.h>
@@ -3522,7 +3522,10 @@ struct cfg80211_pmsr_result {
* If neither @trigger_based nor @non_trigger_based is set,
* EDCA based ranging will be used.
* @lmr_feedback: negotiate for I2R LMR feedback. Only valid if either
- * @trigger_based or @non_trigger_based is set.
+ * @trigger_based or @non_trigger_based is set.
+ * @bss_color: the bss color of the responder. Optional. Set to zero to
+ * indicate the driver should set the BSS color. Only valid if
+ * @non_trigger_based or @trigger_based is set.
*
* See also nl80211 for the respective attribute documentation.
*/
@@ -3540,6 +3543,7 @@ struct cfg80211_pmsr_ftm_request_peer {
u8 burst_duration;
u8 ftms_per_burst;
u8 ftmr_retries;
+ u8 bss_color;
};

/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f962c06e9818..771f238ccff1 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -11,7 +11,7 @@
* Copyright 2008 Jouni Malinen <[email protected]>
* Copyright 2008 Colin McCabe <[email protected]>
* Copyright 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2020 Intel Corporation
+ * Copyright (C) 2018-2021 Intel Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -6912,6 +6912,9 @@ enum nl80211_peer_measurement_ftm_capa {
* @NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK: negotiate for LMR feedback. Only
* valid if either %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED or
* %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set.
+ * @NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR: optional. The BSS color of the
+ * responder. Only valid if %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED
+ * or %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED is set.
*
* @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal
* @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number
@@ -6931,6 +6934,7 @@ enum nl80211_peer_measurement_ftm_req {
NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED,
NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED,
NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK,
+ NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR,

/* keep last */
NUM_NL80211_PMSR_FTM_REQ_ATTR,
diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
index d245968b74cb..328cf54bda82 100644
--- a/net/wireless/pmsr.c
+++ b/net/wireless/pmsr.c
@@ -168,6 +168,18 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
return -EINVAL;
}

+ if (tb[NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR]) {
+ if (!out->ftm.non_trigger_based && !out->ftm.trigger_based) {
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR],
+ "FTM: BSS color set for EDCA based ranging");
+ return -EINVAL;
+ }
+
+ out->ftm.bss_color =
+ nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR]);
+ }
+
return 0;
}

--
2.32.0

2021-06-18 12:35:58

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 21/31] cfg80211: set custom regdomain after wiphy registration

From: Miri Korenblit <[email protected]>

We used to set regulatory info before the registration of
the device and then the regulatory info didn't get set, because
the device isn't registered so there isn't a device to set the
regulatory info for. So set the regulatory info after the device
registration.
Call reg_process_self_managed_hints() once again after the device
registration because it does nothing before it.

Signed-off-by: Miri Korenblit <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/wireless/core.c | 8 ++++----
net/wireless/reg.c | 1 +
2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/net/wireless/core.c b/net/wireless/core.c
index 6fbf7537faf5..6bc074f18a24 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -5,7 +5,7 @@
* Copyright 2006-2010 Johannes Berg <[email protected]>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2020 Intel Corporation
+ * Copyright (C) 2018-2021 Intel Corporation
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -936,9 +936,6 @@ int wiphy_register(struct wiphy *wiphy)
return res;
}

- /* set up regulatory info */
- wiphy_regulatory_register(wiphy);
-
list_add_rcu(&rdev->list, &cfg80211_rdev_list);
cfg80211_rdev_list_generation++;

@@ -949,6 +946,9 @@ int wiphy_register(struct wiphy *wiphy)
cfg80211_debugfs_rdev_add(rdev);
nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);

+ /* set up regulatory info */
+ wiphy_regulatory_register(wiphy);
+
if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) {
struct regulatory_request request;

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 0406ce7334fa..0df048bd4b84 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -4049,6 +4049,7 @@ void wiphy_regulatory_register(struct wiphy *wiphy)

wiphy_update_regulatory(wiphy, lr->initiator);
wiphy_all_share_dfs_chan_state(wiphy);
+ reg_process_self_managed_hints();
}

void wiphy_regulatory_deregister(struct wiphy *wiphy)
--
2.32.0

2021-06-18 12:35:58

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 27/31] cfg80211: allow advertising vendor-specific capabilities

From: Johannes Berg <[email protected]>

There may be cases where vendor-specific elements need to be
used over the air. Rather than have driver or firmware add
them and possibly cause problems that way, add them to the
iftype-data band capabilities. This way we can advertise to
userspace first, and use them in mac80211 next.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
include/net/cfg80211.h | 7 +++++++
include/uapi/linux/nl80211.h | 3 +++
net/wireless/nl80211.c | 5 +++++
3 files changed, 15 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 6c851fa312ac..f8c24da15d29 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -370,11 +370,18 @@ struct ieee80211_sta_he_cap {
* @he_cap: holds the HE capabilities
* @he_6ghz_capa: HE 6 GHz capabilities, must be filled in for a
* 6 GHz band channel (and 0 may be valid value).
+ * @vendor_elems: vendor element(s) to advertise
+ * @vendor_elems.data: vendor element(s) data
+ * @vendor_elems.len: vendor element(s) length
*/
struct ieee80211_sband_iftype_data {
u16 types_mask;
struct ieee80211_sta_he_cap he_cap;
struct ieee80211_he_6ghz_capa he_6ghz_capa;
+ struct {
+ const u8 *data;
+ unsigned int len;
+ } vendor_elems;
};

/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 771f238ccff1..db474994fa73 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3654,6 +3654,8 @@ enum nl80211_mpath_info {
* defined
* @NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA: HE 6GHz band capabilities (__le16),
* given for all 6 GHz band channels
+ * @NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS: vendor element capabilities that are
+ * advertised on this band/for this iftype (binary)
* @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use
*/
enum nl80211_band_iftype_attr {
@@ -3665,6 +3667,7 @@ enum nl80211_band_iftype_attr {
NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
+ NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS,

/* keep last */
__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index fc9286afe3c9..23c59d43a8dd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1731,6 +1731,11 @@ nl80211_send_iftype_data(struct sk_buff *msg,
&iftdata->he_6ghz_capa))
return -ENOBUFS;

+ if (iftdata->vendor_elems.data && iftdata->vendor_elems.len &&
+ nla_put(msg, NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS,
+ iftdata->vendor_elems.len, iftdata->vendor_elems.data))
+ return -ENOBUFS;
+
return 0;
}

--
2.32.0

2021-06-18 12:36:50

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 17/31] mac80211: always include HE 6GHz capability in probe request

From: Johannes Berg <[email protected]>

If HE/6GHz is available (thus we consider dot11HE6GOptionImplemented
to be true), then always include the corresponding capability in the
probe request as required by the spec.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/he.c | 5 +++--
net/mac80211/mlme.c | 3 ++-
net/mac80211/util.c | 17 +++++++++++++----
3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/net/mac80211/he.c b/net/mac80211/he.c
index 0c0b970835ce..94d85b3f295b 100644
--- a/net/mac80211/he.c
+++ b/net/mac80211/he.c
@@ -3,7 +3,7 @@
* HE handling
*
* Copyright(c) 2017 Intel Deutschland GmbH
- * Copyright(c) 2019 - 2020 Intel Corporation
+ * Copyright(c) 2019 - 2021 Intel Corporation
*/

#include "ieee80211_i.h"
@@ -117,10 +117,11 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
u8 mcs_nss_size;
u8 he_total_size;
bool own_160, peer_160, own_80p80, peer_80p80;
+ enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);

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

- if (!he_cap_ie || !ieee80211_get_he_sta_cap(sband))
+ if (!he_cap_ie || !ieee80211_get_he_iftype_cap(sband, iftype))
return;

/* Make sure size is OK */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6457415e4797..5c58eae7ef4b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4954,7 +4954,8 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
}

- if (!ieee80211_get_he_sta_cap(sband))
+ if (!ieee80211_get_he_iftype_cap(sband,
+ ieee80211_vif_type_p2p(&sdata->vif)))
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;

rcu_read_lock();
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 22cab76a9c2f..fb3b7bbfb1dc 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1776,6 +1776,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
int shift;
u32 rate_flags;
bool have_80mhz = false;
+ enum nl80211_iftype iftype;

*offset = 0;

@@ -1937,17 +1938,25 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
*offset = noffset;
}

- he_cap = ieee80211_get_he_sta_cap(sband);
+ iftype = ieee80211_vif_type_p2p(&sdata->vif);
+ he_cap = ieee80211_get_he_iftype_cap(sband, iftype);
if (he_cap &&
cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band),
IEEE80211_CHAN_NO_HE)) {
pos = ieee80211_ie_build_he_cap(pos, he_cap, end);
if (!pos)
goto out_err;
+ }
+
+ if (cfg80211_any_usable_channels(local->hw.wiphy,
+ BIT(NL80211_BAND_6GHZ),
+ IEEE80211_CHAN_NO_HE)) {
+ struct ieee80211_supported_band *sband6;
+
+ sband6 = local->hw.wiphy->bands[NL80211_BAND_6GHZ];
+ he_cap = ieee80211_get_he_iftype_cap(sband6, iftype);

- if (sband->band == NL80211_BAND_6GHZ) {
- enum nl80211_iftype iftype =
- ieee80211_vif_type_p2p(&sdata->vif);
+ if (he_cap) {
__le16 cap = ieee80211_get_he_6ghz_capa(sband, iftype);

pos = ieee80211_write_he_6ghz_cap(pos, cap, end);
--
2.32.0

2021-06-18 12:36:52

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 23/31] cfg80211: trace more information in assoc trace event

From: Johannes Berg <[email protected]>

Add more information to the assoc trace event so we can see
more precisely what's going on and what options were used.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/wireless/rdev-ops.h | 12 +++++++++++-
net/wireless/trace.h | 36 ++++++++++++++++++++++++++++++++++--
2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 8b1358d04ca2..b1d37f582dc6 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -464,8 +464,18 @@ static inline int rdev_assoc(struct cfg80211_registered_device *rdev,
struct net_device *dev,
struct cfg80211_assoc_request *req)
{
+ const struct cfg80211_bss_ies *bss_ies;
int ret;
- trace_rdev_assoc(&rdev->wiphy, dev, req);
+
+ /*
+ * Note: we might trace not exactly the data that's processed,
+ * due to races and the driver/mac80211 getting a newer copy.
+ */
+ rcu_read_lock();
+ bss_ies = rcu_dereference(req->bss->ies);
+ trace_rdev_assoc(&rdev->wiphy, dev, req, bss_ies);
+ rcu_read_unlock();
+
ret = rdev->ops->assoc(&rdev->wiphy, dev, req);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 76b777d5903f..440bce5f0274 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1195,8 +1195,9 @@ TRACE_EVENT(rdev_auth,

TRACE_EVENT(rdev_assoc,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
- struct cfg80211_assoc_request *req),
- TP_ARGS(wiphy, netdev, req),
+ struct cfg80211_assoc_request *req,
+ const struct cfg80211_bss_ies *bss_ies),
+ TP_ARGS(wiphy, netdev, req, bss_ies),
TP_STRUCT__entry(
WIPHY_ENTRY
NETDEV_ENTRY
@@ -1204,6 +1205,17 @@ TRACE_EVENT(rdev_assoc,
MAC_ENTRY(prev_bssid)
__field(bool, use_mfp)
__field(u32, flags)
+ __dynamic_array(u8, bss_elements, bss_ies->len)
+ __field(bool, bss_elements_bcon)
+ __field(u64, bss_elements_tsf)
+ __dynamic_array(u8, elements, req->ie_len)
+ __array(u8, ht_capa, sizeof(struct ieee80211_ht_cap))
+ __array(u8, ht_capa_mask, sizeof(struct ieee80211_ht_cap))
+ __array(u8, vht_capa, sizeof(struct ieee80211_vht_cap))
+ __array(u8, vht_capa_mask, sizeof(struct ieee80211_vht_cap))
+ __dynamic_array(u8, fils_kek, req->fils_kek_len)
+ __dynamic_array(u8, fils_nonces,
+ req->fils_nonces ? 2 * FILS_NONCE_LEN : 0)
),
TP_fast_assign(
WIPHY_ASSIGN;
@@ -1215,6 +1227,26 @@ TRACE_EVENT(rdev_assoc,
MAC_ASSIGN(prev_bssid, req->prev_bssid);
__entry->use_mfp = req->use_mfp;
__entry->flags = req->flags;
+ if (bss_ies->len)
+ memcpy(__get_dynamic_array(bss_elements),
+ bss_ies->data, bss_ies->len);
+ __entry->bss_elements_bcon = bss_ies->from_beacon;
+ __entry->bss_elements_tsf = bss_ies->tsf;
+ if (req->ie)
+ memcpy(__get_dynamic_array(elements),
+ req->ie, req->ie_len);
+ memcpy(__entry->ht_capa, &req->ht_capa, sizeof(req->ht_capa));
+ memcpy(__entry->ht_capa_mask, &req->ht_capa_mask,
+ sizeof(req->ht_capa_mask));
+ memcpy(__entry->vht_capa, &req->vht_capa, sizeof(req->vht_capa));
+ memcpy(__entry->vht_capa_mask, &req->vht_capa_mask,
+ sizeof(req->vht_capa_mask));
+ if (req->fils_kek)
+ memcpy(__get_dynamic_array(fils_kek),
+ req->fils_kek, req->fils_kek_len);
+ if (req->fils_nonces)
+ memcpy(__get_dynamic_array(fils_nonces),
+ req->fils_nonces, 2 * FILS_NONCE_LEN);
),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
", previous bssid: " MAC_PR_FMT ", use mfp: %s, flags: %u",
--
2.32.0

2021-06-18 12:36:58

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 22/31] mac80211: improve AP disconnect message

From: Johannes Berg <[email protected]>

If the AP changes capability/bandwidth in some fashion, the
message might be somewhat misleading and we don't know what
really changed. Modify the message to speak about "caps/bw"
instead of just "bandwidth", and print out the flags.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/mlme.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 5c58eae7ef4b..3eee75571650 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -444,8 +444,8 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
IEEE80211_STA_DISABLE_160MHZ)) ||
!cfg80211_chandef_valid(&chandef)) {
sdata_info(sdata,
- "AP %pM changed bandwidth in a way we can't support - disconnect\n",
- ifmgd->bssid);
+ "AP %pM changed caps/bw in a way we can't support (0x%x/0x%x) - disconnect\n",
+ ifmgd->bssid, flags, ifmgd->flags);
return -EINVAL;
}

--
2.32.0

2021-06-18 12:36:58

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 14/31] cfg80211: add cfg80211_any_usable_channels()

From: Johannes Berg <[email protected]>

This helper function checks if there are any usable channels on
any of the given bands with the given properties (as expressed
by disallowed channel flags).

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
include/net/cfg80211.h | 11 +++++++++++
net/wireless/chan.c | 33 ++++++++++++++++++++++++++++++++-
2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 6a54caa6fa16..5a0c4fd2ec5a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -905,6 +905,17 @@ ieee80211_chandef_max_power(struct cfg80211_chan_def *chandef)
return chandef->chan->max_power;
}

+/**
+ * cfg80211_any_usable_channels - check for usable channels
+ * @wiphy: the wiphy to check for
+ * @band_mask: which bands to check on
+ * @prohibited_flags: which channels to not consider usable,
+ * %IEEE80211_CHAN_DISABLED is always taken into account
+ */
+bool cfg80211_any_usable_channels(struct wiphy *wiphy,
+ unsigned long band_mask,
+ u32 prohibited_flags);
+
/**
* enum survey_info_flags - survey information flags
*
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 285b8076054b..0c349c7819dc 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -6,7 +6,7 @@
*
* Copyright 2009 Johannes Berg <[email protected]>
* Copyright 2013-2014 Intel Mobile Communications GmbH
- * Copyright 2018-2020 Intel Corporation
+ * Copyright 2018-2021 Intel Corporation
*/

#include <linux/export.h>
@@ -1335,3 +1335,34 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
WARN_ON(1);
}
}
+
+bool cfg80211_any_usable_channels(struct wiphy *wiphy,
+ unsigned long sband_mask,
+ u32 prohibited_flags)
+{
+ int idx;
+
+ prohibited_flags |= IEEE80211_CHAN_DISABLED;
+
+ for_each_set_bit(idx, &sband_mask, NUM_NL80211_BANDS) {
+ struct ieee80211_supported_band *sband = wiphy->bands[idx];
+ int chanidx;
+
+ if (!sband)
+ continue;
+
+ for (chanidx = 0; chanidx < sband->n_channels; chanidx++) {
+ struct ieee80211_channel *chan;
+
+ chan = &sband->channels[chanidx];
+
+ if (chan->flags & prohibited_flags)
+ continue;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(cfg80211_any_usable_channels);
--
2.32.0

2021-06-18 12:36:58

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 25/31] mac80211: remove use of ieee80211_get_he_sta_cap()

From: Johannes Berg <[email protected]>

All uses of ieee80211_get_he_sta_cap() were actually wrong,
in net/mac80211/mlme.c they were wrong because that code is
also used for P2P (which is a different interface type), in
net/mac80211/main.c that should check all interface types.
Fix all that.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/main.c | 9 +++++++--
net/mac80211/mlme.c | 23 +++++++++++++++--------
2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index da3e0ca6aa31..2e3f8a479f83 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1008,8 +1008,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
supp_ht = supp_ht || sband->ht_cap.ht_supported;
supp_vht = supp_vht || sband->vht_cap.vht_supported;

- if (!supp_he)
- supp_he = !!ieee80211_get_he_sta_cap(sband);
+ for (i = 0; i < sband->n_iftype_data; i++) {
+ const struct ieee80211_sband_iftype_data *iftd;
+
+ iftd = &sband->iftype_data[i];
+
+ supp_he = supp_he || (iftd && iftd->he_cap.has_he);
+ }

/* HT, VHT, HE require QoS, thus >= 4 queues */
if (WARN_ON(local->hw.queues < IEEE80211_NUM_ACS &&
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a0d77539d1d9..a5d0f62de5c3 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -384,7 +384,9 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,

/* don't check HE if we associated as non-HE station */
if (ifmgd->flags & IEEE80211_STA_DISABLE_HE ||
- !ieee80211_get_he_sta_cap(sband))
+ !ieee80211_get_he_iftype_cap(sband,
+ ieee80211_vif_type_p2p(&sdata->vif)))
+
he_oper = NULL;

if (WARN_ON_ONCE(!sta))
@@ -642,7 +644,8 @@ static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata,

rcu_read_unlock();

- he_cap = ieee80211_get_he_sta_cap(sband);
+ he_cap = ieee80211_get_he_iftype_cap(sband,
+ ieee80211_vif_type_p2p(&sdata->vif));
if (!he_cap || !reg_cap)
return;

@@ -3227,12 +3230,14 @@ static int ieee80211_recalc_twt_req(struct ieee80211_sub_if_data *sdata,
return 0;
}

-static bool ieee80211_twt_bcast_support(struct ieee80211_bss_conf *bss_conf,
+static bool ieee80211_twt_bcast_support(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_bss_conf *bss_conf,
struct ieee80211_supported_band *sband,
struct sta_info *sta)
{
const struct ieee80211_sta_he_cap *own_he_cap =
- ieee80211_get_he_sta_cap(sband);
+ ieee80211_get_he_iftype_cap(sband,
+ ieee80211_vif_type_p2p(&sdata->vif));

return bss_conf->he_support &&
(sta->sta.he_cap.he_cap_elem.mac_cap_info[2] &
@@ -3458,7 +3463,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
}

bss_conf->twt_broadcast =
- ieee80211_twt_bcast_support(bss_conf, sband, sta);
+ ieee80211_twt_bcast_support(sdata, bss_conf, sband, sta);

if (bss_conf->he_support) {
bss_conf->he_bss_color.color =
@@ -4860,11 +4865,13 @@ static u8 ieee80211_ht_vht_rx_chains(struct ieee80211_sub_if_data *sdata,
}

static bool
-ieee80211_verify_sta_he_mcs_support(struct ieee80211_supported_band *sband,
+ieee80211_verify_sta_he_mcs_support(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_supported_band *sband,
const struct ieee80211_he_operation *he_op)
{
const struct ieee80211_sta_he_cap *sta_he_cap =
- ieee80211_get_he_sta_cap(sband);
+ ieee80211_get_he_iftype_cap(sband,
+ ieee80211_vif_type_p2p(&sdata->vif));
u16 ap_min_req_set;
int i;

@@ -5017,7 +5024,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
else
he_oper = NULL;

- if (!ieee80211_verify_sta_he_mcs_support(sband, he_oper))
+ if (!ieee80211_verify_sta_he_mcs_support(sdata, sband, he_oper))
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
}

--
2.32.0

2021-06-18 12:37:06

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 31/31] cfg80211: reg: improve bad regulatory warning

From: Johannes Berg <[email protected]>

There's a WARN_ON here but it says nothing, and the later
dump of the regdomain aren't usually printed. As a first
step, include the regdomain code in the WARN_ON message,
just like in other similar instances.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/wireless/reg.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 0df048bd4b84..c2d0ff7f089f 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -3975,7 +3975,9 @@ static int __regulatory_set_wiphy_regd(struct wiphy *wiphy,
"wiphy should have REGULATORY_WIPHY_SELF_MANAGED\n"))
return -EPERM;

- if (WARN(!is_valid_rd(rd), "Invalid regulatory domain detected\n")) {
+ if (WARN(!is_valid_rd(rd),
+ "Invalid regulatory domain detected: %c%c\n",
+ rd->alpha2[0], rd->alpha2[1])) {
print_regdomain_info(rd);
return -EINVAL;
}
--
2.32.0

2021-06-18 12:38:36

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 19/31] mac80211: rearrange struct txq_info for fewer holes

From: Johannes Berg <[email protected]>

We can slightly decrease the size of struct txq_info by
rearranging some fields for fewer holes, so do that.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/ieee80211_i.h | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8fcbaa1eedf3..0553e68b2047 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -5,7 +5,7 @@
* Copyright 2006-2007 Jiri Benc <[email protected]>
* Copyright 2007-2010 Johannes Berg <[email protected]>
* Copyright 2013-2015 Intel Mobile Communications GmbH
- * Copyright (C) 2018-2020 Intel Corporation
+ * Copyright (C) 2018-2021 Intel Corporation
*/

#ifndef IEEE80211_I_H
@@ -850,9 +850,12 @@ struct txq_info {
struct fq_tin tin;
struct codel_vars def_cvars;
struct codel_stats cstats;
- struct sk_buff_head frags;
- struct list_head schedule_order;
+
u16 schedule_round;
+ struct list_head schedule_order;
+
+ struct sk_buff_head frags;
+
unsigned long flags;

/* keep last! */
--
2.32.0

2021-06-18 12:38:38

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 30/31] mac80211: notify driver on mgd TX completion

From: Johannes Berg <[email protected]>

We have mgd_prepare_tx(), but sometimes drivers may want/need
to take action when the exchange finishes, whether successfully
or not.

Add a notification to the driver on completion, i.e. call the
new method mgd_complete_tx().

To unify the two scenarios, and to add more information, make
both of them take a struct that has the duration (prepare only),
subtype (both) and success (complete only).

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/ath/ath9k/main.c | 2 +-
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 +-
drivers/net/wireless/realtek/rtw88/mac80211.c | 2 +-
include/net/mac80211.h | 28 +++++++-
net/mac80211/driver-ops.h | 26 +++++--
net/mac80211/mlme.c | 71 ++++++++++++++-----
net/mac80211/trace.h | 33 +++++++--
7 files changed, 133 insertions(+), 35 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 45f6402478b5..85d6d47bdece 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2649,7 +2649,7 @@ static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw,

static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- u16 duration)
+ struct ieee80211_prep_tx_info *info)
{
struct ath_softc *sc = hw->priv;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 607d5d564928..cc78f306ac1a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -3306,14 +3306,14 @@ static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,

static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- u16 req_duration)
+ struct ieee80211_prep_tx_info *info)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS;

- if (req_duration > duration)
- duration = req_duration;
+ if (info->duration > duration)
+ duration = info->duration;

mutex_lock(&mvm->mutex);
/* Try really hard to protect the session and hear a beacon
diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index 333df6b38113..d8718b253f0b 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -629,7 +629,7 @@ static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw,

static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- u16 duration)
+ struct ieee80211_prep_tx_info *info)
{
struct rtw_dev *rtwdev = hw->priv;

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index c575240b02c8..78dde1846dab 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3346,6 +3346,21 @@ enum ieee80211_reconfig_type {
IEEE80211_RECONFIG_TYPE_SUSPEND,
};

+/**
+ * struct ieee80211_prep_tx_info - prepare TX information
+ * @duration: if non-zero, hint about the required duration,
+ * only used with the mgd_prepare_tx() method.
+ * @subtype: frame subtype (auth, (re)assoc, deauth, disassoc)
+ * @success: whether the frame exchange was successful, only
+ * used with the mgd_complete_tx() method, and then only
+ * valid for auth and (re)assoc.
+ */
+struct ieee80211_prep_tx_info {
+ u16 duration;
+ u16 subtype;
+ u8 success:1;
+};
+
/**
* struct ieee80211_ops - callbacks from mac80211 to the driver
*
@@ -3758,9 +3773,13 @@ enum ieee80211_reconfig_type {
* frame in case that no beacon was heard from the AP/P2P GO.
* The callback will be called before each transmission and upon return
* mac80211 will transmit the frame right away.
- * If duration is greater than zero, mac80211 hints to the driver the
- * duration for which the operation is requested.
+ * Additional information is passed in the &struct ieee80211_prep_tx_info
+ * data. If duration there is greater than zero, mac80211 hints to the
+ * driver the duration for which the operation is requested.
* The callback is optional and can (should!) sleep.
+ * @mgd_complete_tx: Notify the driver that the response frame for a previously
+ * transmitted frame announced with @mgd_prepare_tx was received, the data
+ * is filled similarly to @mgd_prepare_tx though the duration is not used.
*
* @mgd_protect_tdls_discover: Protect a TDLS discovery session. After sending
* a TDLS discovery-request, we expect a reply to arrive on the AP's
@@ -4111,7 +4130,10 @@ struct ieee80211_ops {

void (*mgd_prepare_tx)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- u16 duration);
+ struct ieee80211_prep_tx_info *info);
+ void (*mgd_complete_tx)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_prep_tx_info *info);

void (*mgd_protect_tdls_discover)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 604ca59937f0..bcb7cc06db3d 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -2,7 +2,7 @@
/*
* Portions of this file
* Copyright(c) 2016 Intel Deutschland GmbH
-* Copyright (C) 2018 - 2019 Intel Corporation
+* Copyright (C) 2018 - 2019, 2021 Intel Corporation
*/

#ifndef __MAC80211_DRIVER_OPS
@@ -821,7 +821,7 @@ drv_allow_buffered_frames(struct ieee80211_local *local,

static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
- u16 duration)
+ struct ieee80211_prep_tx_info *info)
{
might_sleep();

@@ -829,9 +829,27 @@ static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
return;
WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);

- trace_drv_mgd_prepare_tx(local, sdata, duration);
+ trace_drv_mgd_prepare_tx(local, sdata, info->duration,
+ info->subtype, info->success);
if (local->ops->mgd_prepare_tx)
- local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, duration);
+ local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, info);
+ trace_drv_return_void(local);
+}
+
+static inline void drv_mgd_complete_tx(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_prep_tx_info *info)
+{
+ might_sleep();
+
+ if (!check_sdata_in_driver(sdata))
+ return;
+ WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
+
+ trace_drv_mgd_complete_tx(local, sdata, info->duration,
+ info->subtype, info->success);
+ if (local->ops->mgd_complete_tx)
+ local->ops->mgd_complete_tx(&local->hw, &sdata->vif, info);
trace_drv_return_void(local);
}

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9af6fac56429..6b1020ca728d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -683,6 +683,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
struct element *ext_capa = NULL;
enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
const struct ieee80211_sband_iftype_data *iftd;
+ struct ieee80211_prep_tx_info info = {};

/* we know it's writable, cast away the const */
if (assoc_data->ie_len)
@@ -784,12 +785,14 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
mgmt->u.reassoc_req.listen_interval = listen_int;
memcpy(mgmt->u.reassoc_req.current_ap, assoc_data->prev_bssid,
ETH_ALEN);
+ info.subtype = IEEE80211_STYPE_REASSOC_REQ;
} else {
skb_put(skb, 4);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ASSOC_REQ);
mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
mgmt->u.assoc_req.listen_interval = listen_int;
+ info.subtype = IEEE80211_STYPE_ASSOC_REQ;
}

/* SSID */
@@ -1037,7 +1040,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
ifmgd->assoc_req_ies = kmemdup(ie_start, pos - ie_start, GFP_ATOMIC);
ifmgd->assoc_req_ies_len = pos - ie_start;

- drv_mgd_prepare_tx(local, sdata, 0);
+ drv_mgd_prepare_tx(local, sdata, &info);

IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
@@ -2265,6 +2268,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_local *local = sdata->local;
u32 changed = 0;
+ struct ieee80211_prep_tx_info info = {
+ .subtype = stype,
+ };

sdata_assert_lock(sdata);

@@ -2314,8 +2320,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
* driver requested so.
*/
if (ieee80211_hw_check(&local->hw, DEAUTH_NEED_MGD_TX_PREP) &&
- !ifmgd->have_beacon)
- drv_mgd_prepare_tx(sdata->local, sdata, 0);
+ !ifmgd->have_beacon) {
+ drv_mgd_prepare_tx(sdata->local, sdata, &info);
+ }

ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid,
ifmgd->bssid, stype, reason,
@@ -2326,6 +2333,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
if (tx)
ieee80211_flush_queues(local, sdata, false);

+ drv_mgd_complete_tx(sdata->local, sdata, &info);
+
/* clear bssid only after building the needed mgmt frames */
eth_zero_addr(ifmgd->bssid);

@@ -2876,6 +2885,9 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
u8 *pos;
struct ieee802_11_elems elems;
u32 tx_flags = 0;
+ struct ieee80211_prep_tx_info info = {
+ .subtype = IEEE80211_STYPE_AUTH,
+ };

pos = mgmt->u.auth.variable;
ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems,
@@ -2883,7 +2895,7 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
if (!elems.challenge)
return;
auth_data->expected_transaction = 4;
- drv_mgd_prepare_tx(sdata->local, sdata, 0);
+ drv_mgd_prepare_tx(sdata->local, sdata, &info);
if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
IEEE80211_TX_INTFL_MLME_CONN_TX;
@@ -2936,6 +2948,9 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
.type = MLME_EVENT,
.u.mlme.data = AUTH_EVENT,
};
+ struct ieee80211_prep_tx_info info = {
+ .subtype = IEEE80211_STYPE_AUTH,
+ };

sdata_assert_lock(sdata);

@@ -2964,7 +2979,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
mgmt->sa, auth_alg, ifmgd->auth_data->algorithm,
auth_transaction,
ifmgd->auth_data->expected_transaction);
- return;
+ goto notify_driver;
}

if (status_code != WLAN_STATUS_SUCCESS) {
@@ -2975,7 +2990,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
(auth_transaction == 1 &&
(status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
status_code == WLAN_STATUS_SAE_PK))))
- return;
+ goto notify_driver;

sdata_info(sdata, "%pM denied authentication (status %d)\n",
mgmt->sa, status_code);
@@ -2983,7 +2998,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
event.u.mlme.status = MLME_DENIED;
event.u.mlme.reason = status_code;
drv_event_callback(sdata->local, sdata, &event);
- return;
+ goto notify_driver;
}

switch (ifmgd->auth_data->algorithm) {
@@ -3005,10 +3020,11 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
default:
WARN_ONCE(1, "invalid auth alg %d",
ifmgd->auth_data->algorithm);
- return;
+ goto notify_driver;
}

event.u.mlme.status = MLME_SUCCESS;
+ info.success = 1;
drv_event_callback(sdata->local, sdata, &event);
if (ifmgd->auth_data->algorithm != WLAN_AUTH_SAE ||
(auth_transaction == 2 &&
@@ -3022,6 +3038,8 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
}

cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
+notify_driver:
+ drv_mgd_complete_tx(sdata->local, sdata, &info);
}

#define case_WLAN(type) \
@@ -3643,6 +3661,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
.type = MLME_EVENT,
.u.mlme.data = ASSOC_EVENT,
};
+ struct ieee80211_prep_tx_info info = {};

sdata_assert_lock(sdata);

@@ -3672,6 +3691,15 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
aid = 0; /* TODO */
}

+ /*
+ * Note: this may not be perfect, AP might misbehave - if
+ * anyone needs to rely on perfect complete notification
+ * with the exact right subtype, then we need to track what
+ * we actually transmitted.
+ */
+ info.subtype = reassoc ? IEEE80211_STYPE_REASSOC_REQ :
+ IEEE80211_STYPE_ASSOC_REQ;
+
sdata_info(sdata,
"RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n",
reassoc ? "Rea" : "A", mgmt->sa,
@@ -3697,7 +3725,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
assoc_data->timeout_started = true;
if (ms > IEEE80211_ASSOC_TIMEOUT)
run_again(sdata, assoc_data->timeout);
- return;
+ goto notify_driver;
}

if (status_code != WLAN_STATUS_SUCCESS) {
@@ -3712,7 +3740,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
/* oops -- internal error -- send timeout for now */
ieee80211_destroy_assoc_data(sdata, false, false);
cfg80211_assoc_timeout(sdata->dev, cbss);
- return;
+ goto notify_driver;
}
event.u.mlme.status = MLME_SUCCESS;
drv_event_callback(sdata->local, sdata, &event);
@@ -3730,10 +3758,14 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
if (sdata->tx_conf[ac].uapsd)
uapsd_queues |= ieee80211_ac_to_qos_mask[ac];
+
+ info.success = 1;
}

cfg80211_rx_assoc_resp(sdata->dev, cbss, (u8 *)mgmt, len, uapsd_queues,
ifmgd->assoc_req_ies, ifmgd->assoc_req_ies_len);
+notify_driver:
+ drv_mgd_complete_tx(sdata->local, sdata, &info);
}

static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -4352,7 +4384,9 @@ static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
u32 tx_flags = 0;
u16 trans = 1;
u16 status = 0;
- u16 prepare_tx_duration = 0;
+ struct ieee80211_prep_tx_info info = {
+ .subtype = IEEE80211_STYPE_AUTH,
+ };

sdata_assert_lock(sdata);

@@ -4375,10 +4409,9 @@ static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
}

if (auth_data->algorithm == WLAN_AUTH_SAE)
- prepare_tx_duration =
- jiffies_to_msecs(IEEE80211_AUTH_TIMEOUT_SAE);
+ info.duration = jiffies_to_msecs(IEEE80211_AUTH_TIMEOUT_SAE);

- drv_mgd_prepare_tx(local, sdata, prepare_tx_duration);
+ drv_mgd_prepare_tx(local, sdata, &info);

sdata_info(sdata, "send auth to %pM (try %d/%d)\n",
auth_data->bss->bssid, auth_data->tries,
@@ -5801,6 +5834,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
bool tx = !req->local_state_change;
+ struct ieee80211_prep_tx_info info = {
+ .subtype = IEEE80211_STYPE_DEAUTH,
+ };

if (ifmgd->auth_data &&
ether_addr_equal(ifmgd->auth_data->bss->bssid, req->bssid)) {
@@ -5809,7 +5845,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
req->bssid, req->reason_code,
ieee80211_get_reason_code_string(req->reason_code));

- drv_mgd_prepare_tx(sdata->local, sdata, 0);
+ drv_mgd_prepare_tx(sdata->local, sdata, &info);
ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
IEEE80211_STYPE_DEAUTH,
req->reason_code, tx,
@@ -5818,7 +5854,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
ieee80211_report_disconnect(sdata, frame_buf,
sizeof(frame_buf), true,
req->reason_code, false);
-
+ drv_mgd_complete_tx(sdata->local, sdata, &info);
return 0;
}

@@ -5829,7 +5865,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
req->bssid, req->reason_code,
ieee80211_get_reason_code_string(req->reason_code));

- drv_mgd_prepare_tx(sdata->local, sdata, 0);
+ drv_mgd_prepare_tx(sdata->local, sdata, &info);
ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
IEEE80211_STYPE_DEAUTH,
req->reason_code, tx,
@@ -5838,6 +5874,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
ieee80211_report_disconnect(sdata, frame_buf,
sizeof(frame_buf), true,
req->reason_code, false);
+ drv_mgd_complete_tx(sdata->local, sdata, &info);
return 0;
}

diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 8fcc39056402..f6ef15366938 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -2,7 +2,7 @@
/*
* Portions of this file
* Copyright(c) 2016-2017 Intel Deutschland GmbH
-* Copyright (C) 2018 - 2020 Intel Corporation
+* Copyright (C) 2018 - 2021 Intel Corporation
*/

#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
@@ -1461,31 +1461,52 @@ DEFINE_EVENT(release_evt, drv_allow_buffered_frames,
TP_ARGS(local, sta, tids, num_frames, reason, more_data)
);

-TRACE_EVENT(drv_mgd_prepare_tx,
+DECLARE_EVENT_CLASS(mgd_prepare_complete_tx_evt,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
- u16 duration),
+ u16 duration, u16 subtype, bool success),

- TP_ARGS(local, sdata, duration),
+ TP_ARGS(local, sdata, duration, subtype, success),

TP_STRUCT__entry(
LOCAL_ENTRY
VIF_ENTRY
__field(u32, duration)
+ __field(u16, subtype)
+ __field(u8, success)
),

TP_fast_assign(
LOCAL_ASSIGN;
VIF_ASSIGN;
__entry->duration = duration;
+ __entry->subtype = subtype;
+ __entry->success = success;
),

TP_printk(
- LOCAL_PR_FMT VIF_PR_FMT " duration: %u",
- LOCAL_PR_ARG, VIF_PR_ARG, __entry->duration
+ LOCAL_PR_FMT VIF_PR_FMT " duration: %u, subtype:0x%x, success:%d",
+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->duration,
+ __entry->subtype, __entry->success
)
);

+DEFINE_EVENT(mgd_prepare_complete_tx_evt, drv_mgd_prepare_tx,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ u16 duration, u16 subtype, bool success),
+
+ TP_ARGS(local, sdata, duration, subtype, success)
+);
+
+DEFINE_EVENT(mgd_prepare_complete_tx_evt, drv_mgd_complete_tx,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ u16 duration, u16 subtype, bool success),
+
+ TP_ARGS(local, sdata, duration, subtype, success)
+);
+
DEFINE_EVENT(local_sdata_evt, drv_mgd_protect_tdls_discover,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata),
--
2.32.0

2021-06-18 12:38:45

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 24/31] mac80211: reset profile_periodicity/ema_ap

From: Johannes Berg <[email protected]>

Apparently we never clear these values, so they'll remain set
since the setting of them is conditional. Clear the values in
the relevant other cases.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/mlme.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 3eee75571650..a0d77539d1d9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3993,10 +3993,14 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
if (elems.mbssid_config_ie)
bss_conf->profile_periodicity =
elems.mbssid_config_ie->profile_periodicity;
+ else
+ bss_conf->profile_periodicity = 0;

if (elems.ext_capab_len >= 11 &&
(elems.ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
bss_conf->ema_ap = true;
+ else
+ bss_conf->ema_ap = false;

/* continue assoc process */
ifmgd->assoc_data->timeout = jiffies;
@@ -5734,12 +5738,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
beacon_ies->data, beacon_ies->len);
if (elem && elem->datalen >= 3)
sdata->vif.bss_conf.profile_periodicity = elem->data[2];
+ else
+ sdata->vif.bss_conf.profile_periodicity = 0;

elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY,
beacon_ies->data, beacon_ies->len);
if (elem && elem->datalen >= 11 &&
(elem->data[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
sdata->vif.bss_conf.ema_ap = true;
+ else
+ sdata->vif.bss_conf.ema_ap = false;
} else {
assoc_data->timeout = jiffies;
assoc_data->timeout_started = true;
--
2.32.0

2021-06-18 12:38:47

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 12/31] mac80211: Properly WARN on HW scan before restart

From: Ilan Peer <[email protected]>

The following race was possible:

1. The device driver requests HW restart.
2. A scan is requested from user space and is propagated
to the driver. During this flow HW_SCANNING flag is set.
3. The thread that handles the HW restart is scheduled,
and before starting the actual reconfiguration it
checks that HW_SCANNING is not set. The flow does so
without acquiring any lock, and thus the WARN fires.

Fix this by checking that HW_SCANNING is on only after RTNL is
acquired, i.e., user space scan request handling is no longer
in transit.

Signed-off-by: Ilan Peer <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/main.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 62145e5f9628..da3e0ca6aa31 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -256,14 +256,13 @@ static void ieee80211_restart_work(struct work_struct *work)
/* wait for scan work complete */
flush_workqueue(local->workqueue);
flush_work(&local->sched_scan_stopped_work);
+ flush_work(&local->radar_detected_work);
+
+ rtnl_lock();

WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
"%s called with hardware scan in progress\n", __func__);

- flush_work(&local->radar_detected_work);
- /* we might do interface manipulations, so need both */
- rtnl_lock();
- wiphy_lock(local->hw.wiphy);
list_for_each_entry(sdata, &local->interfaces, list) {
/*
* XXX: there may be more work for other vif types and even
--
2.32.0

2021-06-18 12:38:48

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 28/31] mac80211: add vendor-specific capabilities to assoc request

From: Johannes Berg <[email protected]>

When sending an association request, add any vendor specific
capabilities at the end of the frame. This way, mac80211 is
still completely in charge of building the frame, but drivers
can determine what should be added depending on the band and
interface type.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/mlme.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a5d0f62de5c3..9af6fac56429 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -681,6 +681,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
u32 rates = 0;
__le16 listen_int;
struct element *ext_capa = NULL;
+ enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
+ const struct ieee80211_sband_iftype_data *iftd;

/* we know it's writable, cast away the const */
if (assoc_data->ie_len)
@@ -725,6 +727,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
}
}

+ iftd = ieee80211_get_sband_iftype_data(sband, iftype);
+
skb = alloc_skb(local->hw.extra_tx_headroom +
sizeof(*mgmt) + /* bit too much but doesn't matter */
2 + assoc_data->ssid_len + /* SSID */
@@ -739,7 +743,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) +
assoc_data->ie_len + /* extra IEs */
(assoc_data->fils_kek_len ? 16 /* AES-SIV */ : 0) +
- 9, /* WMM */
+ 9 + /* WMM */
+ (iftd ? iftd->vendor_elems.len : 0),
GFP_KERNEL);
if (!skb)
return;
@@ -1012,6 +1017,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
ieee80211_add_s1g_capab_ie(sdata, &sband->s1g_cap, skb);
}

+ if (iftd && iftd->vendor_elems.data && iftd->vendor_elems.len)
+ skb_put_data(skb, iftd->vendor_elems.data, iftd->vendor_elems.len);
+
/* add any remaining custom (i.e. vendor specific here) IEs */
if (assoc_data->ie_len) {
noffset = assoc_data->ie_len;
--
2.32.0

2021-06-18 12:38:48

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 29/31] mac8021: Allow probe request injection on passive non radar channels

From: Ilan Peer <[email protected]>

Based on section 11.1.4.3.8 (Non-scanning probe request transmission)
in Draft P802.11REVmd_D5.0 transmission of a probe request to an AP
known to be in range is allowed. Thus, allow probe request injection on
monitor interface in case the target AP is found in range and the
channel is not a radar channel.

Signed-off-by: Ilan Peer <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/tx.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 0b719f3d2dec..663c2fb99b11 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2337,8 +2337,31 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
* monitor flag interfaces used for AP support.
*/
if (!cfg80211_reg_can_beacon(local->hw.wiphy, chandef,
- sdata->vif.type))
- goto fail_rcu;
+ sdata->vif.type)) {
+ /*
+ * Allow probe request transmissions on non radar channels
+ * in case the AP is known to be in range. This is in accordance
+ * to section 11.1.4.3.8 (Non-scanning probe request
+ * transmission) in Draft P802.11REVmd_D5.0 specification.
+ */
+ if (!ieee80211_is_probe_req(hdr->frame_control) ||
+ chandef->chan->flags & IEEE80211_CHAN_RADAR) {
+ goto fail_rcu;
+ } else {
+ struct cfg80211_bss *tmp =
+ cfg80211_get_bss(local->hw.wiphy,
+ chandef->chan,
+ hdr->addr1,
+ NULL, 0,
+ IEEE80211_BSS_TYPE_ANY,
+ IEEE80211_PRIVACY_ANY);
+
+ if (!tmp)
+ goto fail_rcu;
+ else
+ cfg80211_put_bss(local->hw.wiphy, tmp);
+ }
+ }

info->band = chandef->chan->band;

--
2.32.0

2021-06-18 12:38:58

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 18/31] mac80211: always include HE 6GHz capability in assoc request

From: Johannes Berg <[email protected]>

If HE/6GHz is available (thus we consider dot11HE6GOptionImplemented
to be true), then always include the corresponding capability in the
association request as required by the spec.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/util.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index fb3b7bbfb1dc..08530da5ac05 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2960,15 +2960,15 @@ void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata,
u8 *pos;
u16 cap;

- sband = ieee80211_get_sband(sdata);
- if (!sband)
+ if (!cfg80211_any_usable_channels(sdata->local->hw.wiphy,
+ BIT(NL80211_BAND_6GHZ),
+ IEEE80211_CHAN_NO_HE))
return;

- if (sband->band != NL80211_BAND_6GHZ)
- return;
+ sband = sdata->local->hw.wiphy->bands[NL80211_BAND_6GHZ];

iftd = ieee80211_get_sband_iftype_data(sband, iftype);
- if (WARN_ON(!iftd))
+ if (!iftd)
return;

/* Check for device HE 6 GHz capability before adding element */
--
2.32.0

2021-06-18 12:40:27

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 26/31] cfg80211: remove ieee80211_get_he_sta_cap()

From: Johannes Berg <[email protected]>

This function turned out to be too easy to misuse since it
doesn't consider the interface type. Remove it now that we
no longer use it in mac80211.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
include/net/cfg80211.h | 12 ------------
1 file changed, 12 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 5a0c4fd2ec5a..6c851fa312ac 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -533,18 +533,6 @@ ieee80211_get_he_iftype_cap(const struct ieee80211_supported_band *sband,
return NULL;
}

-/**
- * ieee80211_get_he_sta_cap - return HE capabilities for an sband's STA
- * @sband: the sband to search for the STA on
- *
- * Return: pointer to the struct ieee80211_sta_he_cap, or NULL is none found
- */
-static inline const struct ieee80211_sta_he_cap *
-ieee80211_get_he_sta_cap(const struct ieee80211_supported_band *sband)
-{
- return ieee80211_get_he_iftype_cap(sband, NL80211_IFTYPE_STATION);
-}
-
/**
* ieee80211_get_he_6ghz_capa - return HE 6 GHz capabilities
* @sband: the sband to search for the STA on
--
2.32.0

2021-06-18 12:40:37

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 20/31] mac80211: handle various extensible elements correctly

From: Johannes Berg <[email protected]>

Various elements are parsed with a requirement to have an
exact size, when really we should only check that they have
the minimum size that we need. Check only that and therefore
ignore any additional data that they might carry.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/util.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 08530da5ac05..c4aff6743552 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -947,7 +947,7 @@ static void ieee80211_parse_extension_element(u32 *crc,

switch (elem->data[0]) {
case WLAN_EID_EXT_HE_MU_EDCA:
- if (len == sizeof(*elems->mu_edca_param_set)) {
+ if (len >= sizeof(*elems->mu_edca_param_set)) {
elems->mu_edca_param_set = data;
if (crc)
*crc = crc32_be(*crc, (void *)elem,
@@ -968,7 +968,7 @@ static void ieee80211_parse_extension_element(u32 *crc,
}
break;
case WLAN_EID_EXT_UORA:
- if (len == 1)
+ if (len >= 1)
elems->uora_element = data;
break;
case WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME:
@@ -976,7 +976,7 @@ static void ieee80211_parse_extension_element(u32 *crc,
elems->max_channel_switch_time = data;
break;
case WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION:
- if (len == sizeof(*elems->mbssid_config_ie))
+ if (len >= sizeof(*elems->mbssid_config_ie))
elems->mbssid_config_ie = data;
break;
case WLAN_EID_EXT_HE_SPR:
@@ -985,7 +985,7 @@ static void ieee80211_parse_extension_element(u32 *crc,
elems->he_spr = data;
break;
case WLAN_EID_EXT_HE_6GHZ_CAPA:
- if (len == sizeof(*elems->he_6ghz_capa))
+ if (len >= sizeof(*elems->he_6ghz_capa))
elems->he_6ghz_capa = data;
break;
}
@@ -1074,14 +1074,14 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,

switch (id) {
case WLAN_EID_LINK_ID:
- if (elen + 2 != sizeof(struct ieee80211_tdls_lnkie)) {
+ if (elen + 2 < sizeof(struct ieee80211_tdls_lnkie)) {
elem_parse_failed = true;
break;
}
elems->lnk_id = (void *)(pos - 2);
break;
case WLAN_EID_CHAN_SWITCH_TIMING:
- if (elen != sizeof(struct ieee80211_ch_switch_timing)) {
+ if (elen < sizeof(struct ieee80211_ch_switch_timing)) {
elem_parse_failed = true;
break;
}
@@ -1244,7 +1244,7 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
elems->sec_chan_offs = (void *)pos;
break;
case WLAN_EID_CHAN_SWITCH_PARAM:
- if (elen !=
+ if (elen <
sizeof(*elems->mesh_chansw_params_ie)) {
elem_parse_failed = true;
break;
@@ -1253,7 +1253,7 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
break;
case WLAN_EID_WIDE_BW_CHANNEL_SWITCH:
if (!action ||
- elen != sizeof(*elems->wide_bw_chansw_ie)) {
+ elen < sizeof(*elems->wide_bw_chansw_ie)) {
elem_parse_failed = true;
break;
}
@@ -1272,7 +1272,7 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
ie = cfg80211_find_ie(WLAN_EID_WIDE_BW_CHANNEL_SWITCH,
pos, elen);
if (ie) {
- if (ie[1] == sizeof(*elems->wide_bw_chansw_ie))
+ if (ie[1] >= sizeof(*elems->wide_bw_chansw_ie))
elems->wide_bw_chansw_ie =
(void *)(ie + 2);
else
@@ -1316,7 +1316,7 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
elems->cisco_dtpc_elem = pos;
break;
case WLAN_EID_ADDBA_EXT:
- if (elen != sizeof(struct ieee80211_addba_ext_ie)) {
+ if (elen < sizeof(struct ieee80211_addba_ext_ie)) {
elem_parse_failed = true;
break;
}
@@ -1342,7 +1342,7 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
elem, elems);
break;
case WLAN_EID_S1G_CAPABILITIES:
- if (elen == sizeof(*elems->s1g_capab))
+ if (elen >= sizeof(*elems->s1g_capab))
elems->s1g_capab = (void *)pos;
else
elem_parse_failed = true;
--
2.32.0

2021-06-18 19:25:06

by Florian Fainelli

[permalink] [raw]
Subject: Re: [PATCH 02/31] mac80211: do not add twice the HE 6GHz cap IE



On 6/18/2021 3:41 AM, Luca Coelho wrote:
> From: Shaul Triebitz <[email protected]>
>
> The HE 6GHz capability IE is already added before:
> ieee80211_add_he_ie -> ieee80211_ie_build_he_6ghz_cap
>
> Signed-off-by: Shaul Triebitz <[email protected]>
> Signed-off-by: Luca Coelho <[email protected]>
> ---
> net/mac80211/mlme.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
> index 2480bd0577bb..310cfd02fda4 100644
> --- a/net/mac80211/mlme.c
> +++ b/net/mac80211/mlme.c
> @@ -8,7 +8,7 @@
> * Copyright 2007, Michael Wu <[email protected]>
> * Copyright 2013-2014 Intel Mobile Communications GmbH
> * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
> - * Copyright (C) 2018 - 2020 Intel Corporation
> + * Copyright (C) 2018 - 2021 Intel Corporation

This change only bumps the copyright year...
--
Florian

2021-06-18 20:19:38

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH 02/31] mac80211: do not add twice the HE 6GHz cap IE

On Fri, 2021-06-18 at 10:14 -0700, Florian Fainelli wrote:
>
> On 6/18/2021 3:41 AM, Luca Coelho wrote:
> > From: Shaul Triebitz <[email protected]>
> >
> > The HE 6GHz capability IE is already added before:
> > ieee80211_add_he_ie -> ieee80211_ie_build_he_6ghz_cap
> >
> > Signed-off-by: Shaul Triebitz <[email protected]>
> > Signed-off-by: Luca Coelho <[email protected]>
> > ---
> >  net/mac80211/mlme.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
> > index 2480bd0577bb..310cfd02fda4 100644
> > --- a/net/mac80211/mlme.c
> > +++ b/net/mac80211/mlme.c
> > @@ -8,7 +8,7 @@
> >   * Copyright 2007, Michael Wu <[email protected]>
> >   * Copyright 2013-2014 Intel Mobile Communications GmbH
> >   * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
> > - * Copyright (C) 2018 - 2020 Intel Corporation
> > + * Copyright (C) 2018 - 2021 Intel Corporation
>
> This change only bumps the copyright year...

Oops, something went wrong when I applied it. I'll check and either
resend or drop it.

--
Cheers,
Luca.

2021-06-23 11:04:40

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH 02/31] mac80211: do not add twice the HE 6GHz cap IE

On Fri, 2021-06-18 at 23:17 +0300, Luca Coelho wrote:
> On Fri, 2021-06-18 at 10:14 -0700, Florian Fainelli wrote:
> >
> > On 6/18/2021 3:41 AM, Luca Coelho wrote:
> > > From: Shaul Triebitz <[email protected]>
> > >
> > > The HE 6GHz capability IE is already added before:
> > > ieee80211_add_he_ie -> ieee80211_ie_build_he_6ghz_cap
> > >
> > > Signed-off-by: Shaul Triebitz <[email protected]>
> > > Signed-off-by: Luca Coelho <[email protected]>
> > > ---
> > >  net/mac80211/mlme.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
> > > index 2480bd0577bb..310cfd02fda4 100644
> > > --- a/net/mac80211/mlme.c
> > > +++ b/net/mac80211/mlme.c
> > > @@ -8,7 +8,7 @@
> > >   * Copyright 2007, Michael Wu <[email protected]>
> > >   * Copyright 2013-2014 Intel Mobile Communications GmbH
> > >   * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
> > > - * Copyright (C) 2018 - 2020 Intel Corporation
> > > + * Copyright (C) 2018 - 2021 Intel Corporation
> >
> > This change only bumps the copyright year...
>
> Oops, something went wrong when I applied it. I'll check and either
> resend or drop it.

Please drop this patch. It was an internal fixed to a merge damage and
should not have been sent out (obviously because it resulted in no
code).

--
Cheers,
Luca.