2023-06-04 09:17:40

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 00/16] cfg80211/mac80211 patches from our internal tree 2023-06-04

From: Gregory Greenman <[email protected]>

Hi,

A bunch of patches from our internal tree with mac80211 and
cfg80211 changes. It's the usual developement, cleanups and
bugfixes.

This patch set depends on the previous cfg80211/mac80211
patch set from 2023-05-04.

Thanks,
Gregory

Anjaneyulu (2):
wifi: mac80211: remove typecast in a call to ieee80211_config_bw()
wifi: mac80211: Modify type of "changed" variable.

Emmanuel Grumbach (1):
wifi: mac80211: provide a helper to fetch the medium synchronization
delay

Ilan Peer (1):
wifi: mac80211_hwsim: Fix possible NULL dereference

Johannes Berg (9):
wifi: mac80211: don't translate beacon/presp addrs
wifi: mac80211: mlme: fix non-inheritence element
wifi: cfg80211: reject bad AP MLD address
wifi: mac80211: recalc min chandef for new STA links
wifi: mac80211: move sta_info_move_state() up
wifi: mac80211: batch recalc during STA flush
wifi: mac80211: use correct iftype HE cap
wifi: mac80211: add helpers to access sband iftype data
wifi: mac80211: stop warning after reconfig failures

Mukesh Sisodiya (3):
wifi: mac80211: use u64 to hold enum ieee80211_bss_change flags
wifi: mac80211: refactor ieee80211_select_link_key()
wifi: mac80211_hwsim: check the return value of nla_put_u32

.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 +-
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 +-
.../net/wireless/intel/iwlwifi/mvm/rs-fw.c | 5 +-
drivers/net/wireless/virtual/mac80211_hwsim.c | 9 +-
include/linux/ieee80211.h | 35 +++
include/net/mac80211.h | 47 +++-
net/mac80211/cfg.c | 81 +++---
net/mac80211/chan.c | 6 +-
net/mac80211/driver-ops.h | 10 +-
net/mac80211/eht.c | 5 +-
net/mac80211/he.c | 14 +-
net/mac80211/ibss.c | 16 +-
net/mac80211/ieee80211_i.h | 19 +-
net/mac80211/iface.c | 7 +-
net/mac80211/main.c | 4 +-
net/mac80211/mesh.c | 30 +--
net/mac80211/mesh.h | 19 +-
net/mac80211/mesh_plink.c | 37 +--
net/mac80211/mesh_ps.c | 7 +-
net/mac80211/mlme.c | 55 ++--
net/mac80211/ocb.c | 4 +-
net/mac80211/rx.c | 4 +-
net/mac80211/sta_info.c | 235 ++++++++++--------
net/mac80211/tx.c | 28 +--
net/mac80211/util.c | 16 +-
net/wireless/nl80211.c | 2 +
26 files changed, 404 insertions(+), 302 deletions(-)

--
2.38.1



2023-06-04 09:17:56

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 01/16] wifi: mac80211: use u64 to hold enum ieee80211_bss_change flags

From: Mukesh Sisodiya <[email protected]>

The size of enum ieee80211_bss_change is bigger that 32,
so we need u64 to be used in a flag. Also pass u64
instead of u32 to ieee80211_reconfig_ap_links() for the same
reason.

Signed-off-by: Mukesh Sisodiya <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/mac80211/util.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index cd323fbea8df..d178dc8ab500 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2477,7 +2477,7 @@ static int ieee80211_reconfig_nan(struct ieee80211_sub_if_data *sdata)

static void ieee80211_reconfig_ap_links(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
- u32 changed)
+ u64 changed)
{
int link_id;

@@ -2654,7 +2654,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
/* Finally also reconfigure all the BSS information */
list_for_each_entry(sdata, &local->interfaces, list) {
/* common change flags for all interface types - link only */
- u32 changed = BSS_CHANGED_ERP_CTS_PROT |
+ u64 changed = BSS_CHANGED_ERP_CTS_PROT |
BSS_CHANGED_ERP_PREAMBLE |
BSS_CHANGED_ERP_SLOT |
BSS_CHANGED_HT |
--
2.38.1


2023-06-04 09:18:01

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 02/16] wifi: mac80211: refactor ieee80211_select_link_key()

From: Mukesh Sisodiya <[email protected]>

Simplify ieee80211_select_link_key(), no functional changes are made.

Signed-off-by: Mukesh Sisodiya <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/mac80211/tx.c | 28 ++++++----------------------
1 file changed, 6 insertions(+), 22 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 1a3327407552..e809c4236f78 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -581,25 +581,9 @@ ieee80211_select_link_key(struct ieee80211_tx_data *tx)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
- enum {
- USE_NONE,
- USE_MGMT_KEY,
- USE_MCAST_KEY,
- } which_key = USE_NONE;
struct ieee80211_link_data *link;
unsigned int link_id;

- if (ieee80211_is_group_privacy_action(tx->skb))
- which_key = USE_MCAST_KEY;
- else if (ieee80211_is_mgmt(hdr->frame_control) &&
- is_multicast_ether_addr(hdr->addr1) &&
- ieee80211_is_robust_mgmt_frame(tx->skb))
- which_key = USE_MGMT_KEY;
- else if (is_multicast_ether_addr(hdr->addr1))
- which_key = USE_MCAST_KEY;
- else
- return NULL;
-
link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK);
if (link_id == IEEE80211_LINK_UNSPECIFIED) {
link = &tx->sdata->deflink;
@@ -609,14 +593,14 @@ ieee80211_select_link_key(struct ieee80211_tx_data *tx)
return NULL;
}

- switch (which_key) {
- case USE_NONE:
- break;
- case USE_MGMT_KEY:
+ if (ieee80211_is_group_privacy_action(tx->skb))
+ return rcu_dereference(link->default_multicast_key);
+ else if (ieee80211_is_mgmt(hdr->frame_control) &&
+ is_multicast_ether_addr(hdr->addr1) &&
+ ieee80211_is_robust_mgmt_frame(tx->skb))
return rcu_dereference(link->default_mgmt_key);
- case USE_MCAST_KEY:
+ else if (is_multicast_ether_addr(hdr->addr1))
return rcu_dereference(link->default_multicast_key);
- }

return NULL;
}
--
2.38.1


2023-06-04 09:18:09

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 03/16] wifi: mac80211: don't translate beacon/presp addrs

From: Johannes Berg <[email protected]>

Don't do link address translation for beacons and probe responses,
this leads to reporting multiple scan list entries for the same AP
(one with the MLD address) which just breaks things.

We might need to extend this in the future for some other (action)
frames that aren't MLD addressed.

Fixes: 42fb9148c078 ("wifi: mac80211: do link->MLD address translation on RX")
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/mac80211/rx.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 58222c077898..d996aa2579df 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -4965,7 +4965,9 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
}

if (unlikely(rx->sta && rx->sta->sta.mlo) &&
- is_unicast_ether_addr(hdr->addr1)) {
+ is_unicast_ether_addr(hdr->addr1) &&
+ !ieee80211_is_probe_resp(hdr->frame_control) &&
+ !ieee80211_is_beacon(hdr->frame_control)) {
/* translate to MLD addresses */
if (ether_addr_equal(link->conf->addr, hdr->addr1))
ether_addr_copy(hdr->addr1, rx->sdata->vif.addr);
--
2.38.1


2023-06-04 09:18:46

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 04/16] wifi: mac80211: mlme: fix non-inheritence element

From: Johannes Berg <[email protected]>

There were two bugs when creating the non-inheritence
element:
1) 'at_extension' needs to be declared outside the loop,
otherwise the value resets every iteration and we
can never really switch properly
2) 'added' never got set to true, so we always cut off
the extension element again at the end of the function

This shows another issue that we might add a list but no
extension list, but we need to make the extension list a
zero-length one in that case.

Fix all these issues. While at it, add a comment explaining
the trim.

Fixes: 81151ce462e5 ("wifi: mac80211: support MLO authentication/association with one link")
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/mac80211/mlme.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4ea383aafcac..97671734427c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1217,6 +1217,7 @@ static void ieee80211_add_non_inheritance_elem(struct sk_buff *skb,
const u16 *inner)
{
unsigned int skb_len = skb->len;
+ bool at_extension = false;
bool added = false;
int i, j;
u8 *len, *list_len = NULL;
@@ -1228,7 +1229,6 @@ static void ieee80211_add_non_inheritance_elem(struct sk_buff *skb,
for (i = 0; i < PRESENT_ELEMS_MAX && outer[i]; i++) {
u16 elem = outer[i];
bool have_inner = false;
- bool at_extension = false;

/* should at least be sorted in the sense of normal -> ext */
WARN_ON(at_extension && elem < PRESENT_ELEM_EXT_OFFS);
@@ -1257,8 +1257,14 @@ static void ieee80211_add_non_inheritance_elem(struct sk_buff *skb,
}
*list_len += 1;
skb_put_u8(skb, (u8)elem);
+ added = true;
}

+ /* if we added a list but no extension list, make a zero-len one */
+ if (added && (!at_extension || !list_len))
+ skb_put_u8(skb, 0);
+
+ /* if nothing added remove extension element completely */
if (!added)
skb_trim(skb, skb_len);
else
--
2.38.1


2023-06-04 09:18:46

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 05/16] wifi: mac80211: provide a helper to fetch the medium synchronization delay

From: Emmanuel Grumbach <[email protected]>

There are drivers which need this information.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
include/linux/ieee80211.h | 35 +++++++++++++++++++++++++++++++++++
include/net/mac80211.h | 3 +++
net/mac80211/mlme.c | 5 ++++-
3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index fba4c44da832..516cd32d6196 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -4635,6 +4635,41 @@ static inline u8 ieee80211_mle_common_size(const u8 *data)
return sizeof(*mle) + common + mle->variable[0];
}

+/**
+ * ieee80211_mle_get_eml_sync_delay - returns the medium sync delay
+ * @data: pointer to the multi link EHT IE
+ *
+ * The element is assumed to be big enough. This must be checked by
+ * ieee80211_mle_size_ok().
+ * If the medium synchronization can't be found (the type is not basic, or
+ * the medium sync presence bit is clear), 0 will be returned.
+ */
+static inline u16 ieee80211_mle_get_eml_med_sync_delay(const u8 *data)
+{
+ const struct ieee80211_multi_link_elem *mle = (const void *)data;
+ u16 control = le16_to_cpu(mle->control);
+ const u8 *common = mle->variable;
+
+ if (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE) !=
+ IEEE80211_ML_CONTROL_TYPE_BASIC)
+ return 0;
+
+ /* common points now at the beginning of
+ * ieee80211_mle_basic_common_info
+ */
+ common += sizeof(struct ieee80211_mle_basic_common_info);
+
+ if (!(control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY))
+ return 0;
+
+ if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID)
+ common += 1;
+ if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT)
+ common += 1;
+
+ return get_unaligned_le16(common);
+}
+
/**
* ieee80211_mle_get_eml_cap - returns the EML capability
* @data: pointer to the multi link EHT IE
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f75d941eece8..f4516c034da2 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1791,6 +1791,8 @@ enum ieee80211_offload_flags {
* offchannel/dynamic_ps operations.
* @aid: association ID number, valid only when @assoc is true
* @eml_cap: EML capabilities as described in P802.11be_D2.2 Figure 9-1002k.
+ * @eml_med_sync_delay: Medium Synchronization delay as described in
+ * P802.11be_D2.2 Figure 9-1002j.
* @arp_addr_list: List of IPv4 addresses for hardware ARP filtering. The
* may filter ARP queries targeted for other addresses than listed here.
* The driver must allow ARP queries targeted for all address listed here
@@ -1814,6 +1816,7 @@ struct ieee80211_vif_cfg {
bool ps;
u16 aid;
u16 eml_cap;
+ u16 eml_med_sync_delay;

__be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN];
int arp_addr_cnt;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 97671734427c..a404448eb84e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4862,9 +4862,12 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
/* data + 1 / datalen - 1 since it's an extended element */
if (eht_ml_elem &&
ieee80211_mle_size_ok(eht_ml_elem->data + 1,
- eht_ml_elem->datalen - 1))
+ eht_ml_elem->datalen - 1)) {
sdata->vif.cfg.eml_cap =
ieee80211_mle_get_eml_cap(eht_ml_elem->data + 1);
+ sdata->vif.cfg.eml_med_sync_delay =
+ ieee80211_mle_get_eml_med_sync_delay(eht_ml_elem->data + 1);
+ }
}

/* Allow VHT if at least one channel on the sband supports 80 MHz */
--
2.38.1


2023-06-04 09:18:56

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 07/16] wifi: mac80211_hwsim: check the return value of nla_put_u32

From: Mukesh Sisodiya <[email protected]>

Check the return value of nla_put_u32() and handle it accordingly.

Signed-off-by: Mukesh Sisodiya <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
drivers/net/wireless/virtual/mac80211_hwsim.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
index 5ff193bcd4b9..b06a6e78169d 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
@@ -582,8 +582,9 @@ static int mac80211_hwsim_vendor_cmd_test(struct wiphy *wiphy,
*/

/* Add vendor data */
- nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_TEST, val + 1);
-
+ err = nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_TEST, val + 1);
+ if (err)
+ return err;
/* Send the event - this will call nla_nest_end() */
cfg80211_vendor_event(skb, GFP_KERNEL);
}
--
2.38.1


2023-06-04 09:18:56

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 06/16] wifi: cfg80211: reject bad AP MLD address

From: Johannes Berg <[email protected]>

When trying to authenticate, if the AP MLD address isn't
a valid address, mac80211 can throw a warning. Avoid that
by rejecting such addresses.

Fixes: d648c23024bd ("wifi: nl80211: support MLO in auth/assoc")
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/wireless/nl80211.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d95f8053020d..087d60c0f6e4 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -10723,6 +10723,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
if (!info->attrs[NL80211_ATTR_MLD_ADDR])
return -EINVAL;
req.ap_mld_addr = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
+ if (!is_valid_ether_addr(req.ap_mld_addr))
+ return -EINVAL;
}

req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
--
2.38.1


2023-06-04 09:18:57

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 08/16] wifi: mac80211: recalc min chandef for new STA links

From: Johannes Berg <[email protected]>

When adding a new link to a station, this needs to cause a
recalculation of the minimum chandef since otherwise we can
have a higher bandwidth station connected on that link than
the link is operating at. Do the appropriate recalc.

Fixes: cb71f1d136a6 ("wifi: mac80211: add sta link addition/removal")
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/mac80211/sta_info.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 1400512e0dde..a1cd5c234f47 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2913,6 +2913,8 @@ int ieee80211_sta_activate_link(struct sta_info *sta, unsigned int link_id)
if (!test_sta_flag(sta, WLAN_STA_INSERTED))
goto hash;

+ ieee80211_recalc_min_chandef(sdata, link_id);
+
/* Ensure the values are updated for the driver,
* redone by sta_remove_link on failure.
*/
--
2.38.1


2023-06-04 09:19:06

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 12/16] wifi: mac80211: add helpers to access sband iftype data

From: Johannes Berg <[email protected]>

There's quite a bit of code accessing sband iftype data
(HE, HE 6 GHz, EHT) and we always need to remember to use
the ieee80211_vif_type_p2p() helper. Add new helpers to
directly get it from the sband/vif rather than having to
call ieee80211_vif_type_p2p().

Convert most code with the following spatch:

@@
expression vif, sband;
@@
-ieee80211_get_he_iftype_cap(sband, ieee80211_vif_type_p2p(vif))
+ieee80211_get_he_iftype_cap_vif(sband, vif)

@@
expression vif, sband;
@@
-ieee80211_get_eht_iftype_cap(sband, ieee80211_vif_type_p2p(vif))
+ieee80211_get_eht_iftype_cap_vif(sband, vif)

@@
expression vif, sband;
@@
-ieee80211_get_he_6ghz_capa(sband, ieee80211_vif_type_p2p(vif))
+ieee80211_get_he_6ghz_capa_vif(sband, vif)

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 +--
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 +--
.../net/wireless/intel/iwlwifi/mvm/rs-fw.c | 5 +--
include/net/mac80211.h | 44 ++++++++++++++++++-
net/mac80211/eht.c | 5 +--
net/mac80211/he.c | 3 +-
net/mac80211/mlme.c | 30 +++++--------
net/mac80211/util.c | 11 ++---
8 files changed, 66 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 0f01b62357c6..16a36797b836 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -2285,8 +2285,7 @@ bool iwl_mvm_is_nic_ack_enabled(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
* so take it from one of them.
*/
sband = mvm->hw->wiphy->bands[NL80211_BAND_2GHZ];
- own_he_cap = ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(vif));
+ own_he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif);

return (own_he_cap && (own_he_cap->he_cap_elem.mac_cap_info[2] &
IEEE80211_HE_MAC_CAP2_ACK_EN));
@@ -3468,8 +3467,7 @@ static void iwl_mvm_reset_cca_40mhz_workaround(struct iwl_mvm *mvm,

sband->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;

- he_cap = ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(vif));
+ he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif);

if (he_cap) {
/* we know that ours is writable */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 32625bfacaae..6ba4ad6b1380 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2012-2014, 2018-2020 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2023 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -192,8 +192,7 @@ static void iwl_mvm_rx_monitor_notif(struct iwl_mvm *mvm,
WARN_ON(!(sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40));
sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;

- he_cap = ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(vif));
+ he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif);

if (he_cap) {
/* we know that ours is writable */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
index c3a00bfbeef2..f72d1ca3cfed 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
*/
#include "rs.h"
#include "fw-api.h"
@@ -94,8 +94,7 @@ static u16 rs_fw_get_config_flags(struct iwl_mvm *mvm,
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD))
flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK;

- sband_he_cap = ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(vif));
+ sband_he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif);
if (sband_he_cap &&
!(sband_he_cap->he_cap_elem.phy_cap_info[1] &
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD))
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f4516c034da2..8ea23884a583 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 - 2022 Intel Corporation
+ * Copyright (C) 2018 - 2023 Intel Corporation
*/

#ifndef MAC80211_H
@@ -6866,6 +6866,48 @@ ieee80211_vif_type_p2p(struct ieee80211_vif *vif)
return ieee80211_iftype_p2p(vif->type, vif->p2p);
}

+/**
+ * ieee80211_get_he_iftype_cap_vif - return HE capabilities for sband/vif
+ * @sband: the sband to search for the iftype on
+ * @vif: the vif to get the iftype from
+ *
+ * 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_iftype_cap_vif(const struct ieee80211_supported_band *sband,
+ struct ieee80211_vif *vif)
+{
+ return ieee80211_get_he_iftype_cap(sband, ieee80211_vif_type_p2p(vif));
+}
+
+/**
+ * ieee80211_get_he_6ghz_capa_vif - return HE 6 GHz capabilities
+ * @sband: the sband to search for the STA on
+ * @vif: the vif to get the iftype from
+ *
+ * Return: the 6GHz capabilities
+ */
+static inline __le16
+ieee80211_get_he_6ghz_capa_vif(const struct ieee80211_supported_band *sband,
+ struct ieee80211_vif *vif)
+{
+ return ieee80211_get_he_6ghz_capa(sband, ieee80211_vif_type_p2p(vif));
+}
+
+/**
+ * ieee80211_get_eht_iftype_cap_vif - return ETH capabilities for sband/vif
+ * @sband: the sband to search for the iftype on
+ * @vif: the vif to get the iftype from
+ *
+ * Return: pointer to the struct ieee80211_sta_eht_cap, or %NULL is none found
+ */
+static inline const struct ieee80211_sta_eht_cap *
+ieee80211_get_eht_iftype_cap_vif(const struct ieee80211_supported_band *sband,
+ struct ieee80211_vif *vif)
+{
+ return ieee80211_get_eht_iftype_cap(sband, ieee80211_vif_type_p2p(vif));
+}
+
/**
* ieee80211_update_mu_groups - set the VHT MU-MIMO groud data
*
diff --git a/net/mac80211/eht.c b/net/mac80211/eht.c
index 18bc6b78b267..ddc7acc68335 100644
--- a/net/mac80211/eht.c
+++ b/net/mac80211/eht.c
@@ -2,7 +2,7 @@
/*
* EHT handling
*
- * Copyright(c) 2021-2022 Intel Corporation
+ * Copyright(c) 2021-2023 Intel Corporation
*/

#include "ieee80211_i.h"
@@ -25,8 +25,7 @@ ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data *sdata,
memset(eht_cap, 0, sizeof(*eht_cap));

if (!eht_cap_ie_elem ||
- !ieee80211_get_eht_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif)))
+ !ieee80211_get_eht_iftype_cap_vif(sband, &sdata->vif))
return;

mcs_nss_size = ieee80211_eht_mcs_nss_size(he_cap_ie_elem,
diff --git a/net/mac80211/he.c b/net/mac80211/he.c
index 0322abae0825..9f5ffdc9db28 100644
--- a/net/mac80211/he.c
+++ b/net/mac80211/he.c
@@ -128,8 +128,7 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
return;

own_he_cap_ptr =
- ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif));
+ ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
if (!own_he_cap_ptr)
return;

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a404448eb84e..7d6248b8d280 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -511,16 +511,14 @@ static int ieee80211_config_bw(struct ieee80211_link_data *link,

/* don't check HE if we associated as non-HE station */
if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE ||
- !ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif))) {
+ !ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif)) {
he_oper = NULL;
eht_oper = NULL;
}

/* don't check EHT if we associated as non-EHT station */
if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_EHT ||
- !ieee80211_get_eht_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif)))
+ !ieee80211_get_eht_iftype_cap_vif(sband, &sdata->vif))
eht_oper = NULL;

/*
@@ -776,8 +774,7 @@ static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata,
const struct ieee80211_sta_he_cap *he_cap;
u8 he_cap_size;

- he_cap = ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif));
+ he_cap = ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
if (WARN_ON(!he_cap))
return;

@@ -806,10 +803,8 @@ static void ieee80211_add_eht_ie(struct ieee80211_sub_if_data *sdata,
const struct ieee80211_sta_eht_cap *eht_cap;
u8 eht_cap_size;

- he_cap = ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif));
- eht_cap = ieee80211_get_eht_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif));
+ he_cap = ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
+ eht_cap = ieee80211_get_eht_iftype_cap_vif(sband, &sdata->vif);

/*
* EHT capabilities element is only added if the HE capabilities element
@@ -3949,8 +3944,7 @@ static bool ieee80211_twt_req_supported(struct ieee80211_sub_if_data *sdata,
const struct ieee802_11_elems *elems)
{
const struct ieee80211_sta_he_cap *own_he_cap =
- ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif));
+ ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);

if (elems->ext_capab_len < 10)
return false;
@@ -3986,8 +3980,7 @@ static bool ieee80211_twt_bcast_support(struct ieee80211_sub_if_data *sdata,
struct link_sta_info *link_sta)
{
const struct ieee80211_sta_he_cap *own_he_cap =
- ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif));
+ ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);

return bss_conf->he_support &&
(link_sta->pub->he_cap.he_cap_elem.mac_cap_info[2] &
@@ -4624,8 +4617,7 @@ ieee80211_verify_sta_he_mcs_support(struct ieee80211_sub_if_data *sdata,
const struct ieee80211_he_operation *he_op)
{
const struct ieee80211_sta_he_cap *sta_he_cap =
- ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif));
+ ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
u16 ap_min_req_set;
int i;

@@ -4759,15 +4751,13 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
*conn_flags |= IEEE80211_CONN_DISABLE_EHT;
}

- if (!ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif))) {
+ if (!ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif)) {
mlme_dbg(sdata, "HE not supported, disabling HE and EHT\n");
*conn_flags |= IEEE80211_CONN_DISABLE_HE;
*conn_flags |= IEEE80211_CONN_DISABLE_EHT;
}

- if (!ieee80211_get_eht_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif))) {
+ if (!ieee80211_get_eht_iftype_cap_vif(sband, &sdata->vif)) {
mlme_dbg(sdata, "EHT not supported, disabling EHT\n");
*conn_flags |= IEEE80211_CONN_DISABLE_EHT;
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index d178dc8ab500..316a052d61bd 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-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
*
* utilities for mac80211
*/
@@ -2121,8 +2121,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
*offset = noffset;
}

- he_cap = ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif));
+ he_cap = ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
if (he_cap &&
cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band),
IEEE80211_CHAN_NO_HE)) {
@@ -2131,8 +2130,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
goto out_err;
}

- eht_cap = ieee80211_get_eht_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif));
+ eht_cap = ieee80211_get_eht_iftype_cap_vif(sband, &sdata->vif);

if (eht_cap &&
cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band),
@@ -2150,8 +2148,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
struct ieee80211_supported_band *sband6;

sband6 = local->hw.wiphy->bands[NL80211_BAND_6GHZ];
- he_cap = ieee80211_get_he_iftype_cap(sband6,
- ieee80211_vif_type_p2p(&sdata->vif));
+ he_cap = ieee80211_get_he_iftype_cap_vif(sband6, &sdata->vif);

if (he_cap) {
enum nl80211_iftype iftype =
--
2.38.1


2023-06-04 09:19:16

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 10/16] wifi: mac80211: batch recalc during STA flush

From: Johannes Berg <[email protected]>

When we flush stations, we first take them off the list
and then destroy them one by one. If we do the different
mode recalculations while destroying them, we cause the
following scenario:
- STA 1 has 80 MHz - min chanctx width is now 80 MHz
- STA 2 has 80 MHz
- empty STA list
- destroy STA 2
- recalc min chanctx width -> results in 20 MHz as
the STA list is already empty

This is broken, since as far as the driver is concerned
STA 1 still exists at this point, and this causes issues
at least with iwlwifi.

Fix - and also optimize - this by doing the recalc of
min chanctx width (and also P2P PS) only after all the
stations were removed.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/mac80211/sta_info.c | 48 +++++++++++++++++++++++++++++------------
1 file changed, 34 insertions(+), 14 deletions(-)

diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index dc76bc40350f..731b832b257c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1274,8 +1274,9 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta)
return 0;
}

-int sta_info_move_state(struct sta_info *sta,
- enum ieee80211_sta_state new_state)
+static int _sta_info_move_state(struct sta_info *sta,
+ enum ieee80211_sta_state new_state,
+ bool recalc)
{
might_sleep();

@@ -1333,18 +1334,22 @@ int sta_info_move_state(struct sta_info *sta,
set_bit(WLAN_STA_AUTH, &sta->_flags);
} else if (sta->sta_state == IEEE80211_STA_ASSOC) {
clear_bit(WLAN_STA_ASSOC, &sta->_flags);
- ieee80211_recalc_min_chandef(sta->sdata, -1);
- if (!sta->sta.support_p2p_ps)
- ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
+ if (recalc) {
+ ieee80211_recalc_min_chandef(sta->sdata, -1);
+ if (!sta->sta.support_p2p_ps)
+ ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
+ }
}
break;
case IEEE80211_STA_ASSOC:
if (sta->sta_state == IEEE80211_STA_AUTH) {
set_bit(WLAN_STA_ASSOC, &sta->_flags);
sta->assoc_at = ktime_get_boottime_ns();
- ieee80211_recalc_min_chandef(sta->sdata, -1);
- if (!sta->sta.support_p2p_ps)
- ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
+ if (recalc) {
+ ieee80211_recalc_min_chandef(sta->sdata, -1);
+ if (!sta->sta.support_p2p_ps)
+ ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
+ }
} else if (sta->sta_state == IEEE80211_STA_AUTHORIZED) {
ieee80211_vif_dec_num_mcast(sta->sdata);
clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
@@ -1373,7 +1378,13 @@ int sta_info_move_state(struct sta_info *sta,
return 0;
}

-static void __sta_info_destroy_part2(struct sta_info *sta)
+int sta_info_move_state(struct sta_info *sta,
+ enum ieee80211_sta_state new_state)
+{
+ return _sta_info_move_state(sta, new_state, true);
+}
+
+static void __sta_info_destroy_part2(struct sta_info *sta, bool recalc)
{
struct ieee80211_local *local = sta->local;
struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -1389,7 +1400,7 @@ static void __sta_info_destroy_part2(struct sta_info *sta)
lockdep_assert_held(&local->sta_mtx);

if (sta->sta_state == IEEE80211_STA_AUTHORIZED) {
- ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
+ ret = _sta_info_move_state(sta, IEEE80211_STA_ASSOC, recalc);
WARN_ON_ONCE(ret);
}

@@ -1417,7 +1428,7 @@ static void __sta_info_destroy_part2(struct sta_info *sta)
local->sta_generation++;

while (sta->sta_state > IEEE80211_STA_NONE) {
- ret = sta_info_move_state(sta, sta->sta_state - 1);
+ ret = _sta_info_move_state(sta, sta->sta_state - 1, recalc);
if (ret) {
WARN_ON_ONCE(1);
break;
@@ -1454,7 +1465,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)

synchronize_net();

- __sta_info_destroy_part2(sta);
+ __sta_info_destroy_part2(sta, true);

return 0;
}
@@ -1561,9 +1572,18 @@ int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans)
}

if (!list_empty(&free_list)) {
+ bool support_p2p_ps = true;
+
synchronize_net();
- list_for_each_entry_safe(sta, tmp, &free_list, free_list)
- __sta_info_destroy_part2(sta);
+ list_for_each_entry_safe(sta, tmp, &free_list, free_list) {
+ if (!sta->sta.support_p2p_ps)
+ support_p2p_ps = false;
+ __sta_info_destroy_part2(sta, false);
+ }
+
+ ieee80211_recalc_min_chandef(sdata, -1);
+ if (!support_p2p_ps)
+ ieee80211_recalc_p2p_go_ps_allowed(sdata);
}
mutex_unlock(&local->sta_mtx);

--
2.38.1


2023-06-04 09:19:17

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 09/16] wifi: mac80211: move sta_info_move_state() up

From: Johannes Berg <[email protected]>

To fix a sequencing issue, this code needs to be changed
a bit. Move it up in the file to prepare for that.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/mac80211/sta_info.c | 201 ++++++++++++++++++++--------------------
1 file changed, 100 insertions(+), 101 deletions(-)

diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index a1cd5c234f47..dc76bc40350f 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -4,7 +4,7 @@
* Copyright 2006-2007 Jiri Benc <[email protected]>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
*/

#include <linux/module.h>
@@ -1274,6 +1274,105 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta)
return 0;
}

+int sta_info_move_state(struct sta_info *sta,
+ enum ieee80211_sta_state new_state)
+{
+ might_sleep();
+
+ if (sta->sta_state == new_state)
+ return 0;
+
+ /* check allowed transitions first */
+
+ switch (new_state) {
+ case IEEE80211_STA_NONE:
+ if (sta->sta_state != IEEE80211_STA_AUTH)
+ return -EINVAL;
+ break;
+ case IEEE80211_STA_AUTH:
+ if (sta->sta_state != IEEE80211_STA_NONE &&
+ sta->sta_state != IEEE80211_STA_ASSOC)
+ return -EINVAL;
+ break;
+ case IEEE80211_STA_ASSOC:
+ if (sta->sta_state != IEEE80211_STA_AUTH &&
+ sta->sta_state != IEEE80211_STA_AUTHORIZED)
+ return -EINVAL;
+ break;
+ case IEEE80211_STA_AUTHORIZED:
+ if (sta->sta_state != IEEE80211_STA_ASSOC)
+ return -EINVAL;
+ break;
+ default:
+ WARN(1, "invalid state %d", new_state);
+ return -EINVAL;
+ }
+
+ sta_dbg(sta->sdata, "moving STA %pM to state %d\n",
+ sta->sta.addr, new_state);
+
+ /* notify the driver before the actual changes so it can
+ * fail the transition
+ */
+ if (test_sta_flag(sta, WLAN_STA_INSERTED)) {
+ int err = drv_sta_state(sta->local, sta->sdata, sta,
+ sta->sta_state, new_state);
+ if (err)
+ return err;
+ }
+
+ /* reflect the change in all state variables */
+
+ switch (new_state) {
+ case IEEE80211_STA_NONE:
+ if (sta->sta_state == IEEE80211_STA_AUTH)
+ clear_bit(WLAN_STA_AUTH, &sta->_flags);
+ break;
+ case IEEE80211_STA_AUTH:
+ if (sta->sta_state == IEEE80211_STA_NONE) {
+ set_bit(WLAN_STA_AUTH, &sta->_flags);
+ } else if (sta->sta_state == IEEE80211_STA_ASSOC) {
+ clear_bit(WLAN_STA_ASSOC, &sta->_flags);
+ ieee80211_recalc_min_chandef(sta->sdata, -1);
+ if (!sta->sta.support_p2p_ps)
+ ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
+ }
+ break;
+ case IEEE80211_STA_ASSOC:
+ if (sta->sta_state == IEEE80211_STA_AUTH) {
+ set_bit(WLAN_STA_ASSOC, &sta->_flags);
+ sta->assoc_at = ktime_get_boottime_ns();
+ ieee80211_recalc_min_chandef(sta->sdata, -1);
+ if (!sta->sta.support_p2p_ps)
+ ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
+ } else if (sta->sta_state == IEEE80211_STA_AUTHORIZED) {
+ ieee80211_vif_dec_num_mcast(sta->sdata);
+ clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
+ ieee80211_clear_fast_xmit(sta);
+ ieee80211_clear_fast_rx(sta);
+ }
+ break;
+ case IEEE80211_STA_AUTHORIZED:
+ if (sta->sta_state == IEEE80211_STA_ASSOC) {
+ ieee80211_vif_inc_num_mcast(sta->sdata);
+ set_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
+ ieee80211_check_fast_xmit(sta);
+ ieee80211_check_fast_rx(sta);
+ }
+ if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
+ sta->sdata->vif.type == NL80211_IFTYPE_AP)
+ cfg80211_send_layer2_update(sta->sdata->dev,
+ sta->sta.addr);
+ break;
+ default:
+ break;
+ }
+
+ sta->sta_state = new_state;
+
+ return 0;
+}
+
static void __sta_info_destroy_part2(struct sta_info *sta)
{
struct ieee80211_local *local = sta->local;
@@ -2252,106 +2351,6 @@ void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
}
}

-int sta_info_move_state(struct sta_info *sta,
- enum ieee80211_sta_state new_state)
-{
- might_sleep();
-
- if (sta->sta_state == new_state)
- return 0;
-
- /* check allowed transitions first */
-
- switch (new_state) {
- case IEEE80211_STA_NONE:
- if (sta->sta_state != IEEE80211_STA_AUTH)
- return -EINVAL;
- break;
- case IEEE80211_STA_AUTH:
- if (sta->sta_state != IEEE80211_STA_NONE &&
- sta->sta_state != IEEE80211_STA_ASSOC)
- return -EINVAL;
- break;
- case IEEE80211_STA_ASSOC:
- if (sta->sta_state != IEEE80211_STA_AUTH &&
- sta->sta_state != IEEE80211_STA_AUTHORIZED)
- return -EINVAL;
- break;
- case IEEE80211_STA_AUTHORIZED:
- if (sta->sta_state != IEEE80211_STA_ASSOC)
- return -EINVAL;
- break;
- default:
- WARN(1, "invalid state %d", new_state);
- return -EINVAL;
- }
-
- sta_dbg(sta->sdata, "moving STA %pM to state %d\n",
- sta->sta.addr, new_state);
-
- /*
- * notify the driver before the actual changes so it can
- * fail the transition
- */
- if (test_sta_flag(sta, WLAN_STA_INSERTED)) {
- int err = drv_sta_state(sta->local, sta->sdata, sta,
- sta->sta_state, new_state);
- if (err)
- return err;
- }
-
- /* reflect the change in all state variables */
-
- switch (new_state) {
- case IEEE80211_STA_NONE:
- if (sta->sta_state == IEEE80211_STA_AUTH)
- clear_bit(WLAN_STA_AUTH, &sta->_flags);
- break;
- case IEEE80211_STA_AUTH:
- if (sta->sta_state == IEEE80211_STA_NONE) {
- set_bit(WLAN_STA_AUTH, &sta->_flags);
- } else if (sta->sta_state == IEEE80211_STA_ASSOC) {
- clear_bit(WLAN_STA_ASSOC, &sta->_flags);
- ieee80211_recalc_min_chandef(sta->sdata, -1);
- if (!sta->sta.support_p2p_ps)
- ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
- }
- break;
- case IEEE80211_STA_ASSOC:
- if (sta->sta_state == IEEE80211_STA_AUTH) {
- set_bit(WLAN_STA_ASSOC, &sta->_flags);
- sta->assoc_at = ktime_get_boottime_ns();
- ieee80211_recalc_min_chandef(sta->sdata, -1);
- if (!sta->sta.support_p2p_ps)
- ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
- } else if (sta->sta_state == IEEE80211_STA_AUTHORIZED) {
- ieee80211_vif_dec_num_mcast(sta->sdata);
- clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
- ieee80211_clear_fast_xmit(sta);
- ieee80211_clear_fast_rx(sta);
- }
- break;
- case IEEE80211_STA_AUTHORIZED:
- if (sta->sta_state == IEEE80211_STA_ASSOC) {
- ieee80211_vif_inc_num_mcast(sta->sdata);
- set_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
- ieee80211_check_fast_xmit(sta);
- ieee80211_check_fast_rx(sta);
- }
- if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
- sta->sdata->vif.type == NL80211_IFTYPE_AP)
- cfg80211_send_layer2_update(sta->sdata->dev,
- sta->sta.addr);
- break;
- default:
- break;
- }
-
- sta->sta_state = new_state;
-
- return 0;
-}
-
static struct ieee80211_sta_rx_stats *
sta_get_last_rx_stats(struct sta_info *sta)
{
--
2.38.1


2023-06-04 09:19:20

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 13/16] wifi: mac80211: remove typecast in a call to ieee80211_config_bw()

From: Anjaneyulu <[email protected]>

Make "changed" to be u64 as implied by the corresponding enum size.

Fixes: 61513162aa2d ("wifi: mac80211: mlme: shift some code around")
Signed-off-by: Anjaneyulu <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/mac80211/cfg.c | 2 +-
net/mac80211/chan.c | 2 +-
net/mac80211/ieee80211_i.h | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 7317e4a5d1ff..49f5122189d3 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -5,7 +5,7 @@
* Copyright 2006-2010 Johannes Berg <[email protected]>
* Copyright 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
*/

#include <linux/ieee80211.h>
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 77c90ed8f5d7..a7e204de5d54 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* mac80211 - channel management
- * Copyright 2020 - 2022 Intel Corporation
+ * Copyright 2020 - 2023 Intel Corporation
*/

#include <linux/nl80211.h>
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e67c5c754be1..886244d42f04 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-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
*/

#ifndef IEEE80211_I_H
--
2.38.1


2023-06-04 09:19:20

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 11/16] wifi: mac80211: use correct iftype HE cap

From: Johannes Berg <[email protected]>

We already check that the right iftype capa exists,
but then don't use it. Assign it to a variable so we
can actually use it, and then do that.

Fixes: bac2fd3d7534 ("mac80211: remove use of ieee80211_get_he_sta_cap()")
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/mac80211/he.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/he.c b/net/mac80211/he.c
index 729f261520c7..0322abae0825 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 - 2022 Intel Corporation
+ * Copyright(c) 2019 - 2023 Intel Corporation
*/

#include "ieee80211_i.h"
@@ -114,6 +114,7 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
struct link_sta_info *link_sta)
{
struct ieee80211_sta_he_cap *he_cap = &link_sta->pub->he_cap;
+ const struct ieee80211_sta_he_cap *own_he_cap_ptr;
struct ieee80211_sta_he_cap own_he_cap;
struct ieee80211_he_cap_elem *he_cap_ie_elem = (void *)he_cap_ie;
u8 he_ppe_size;
@@ -123,12 +124,16 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,

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

- if (!he_cap_ie ||
- !ieee80211_get_he_iftype_cap(sband,
- ieee80211_vif_type_p2p(&sdata->vif)))
+ if (!he_cap_ie)
return;

- own_he_cap = sband->iftype_data->he_cap;
+ own_he_cap_ptr =
+ ieee80211_get_he_iftype_cap(sband,
+ ieee80211_vif_type_p2p(&sdata->vif));
+ if (!own_he_cap_ptr)
+ return;
+
+ own_he_cap = *own_he_cap_ptr;

/* Make sure size is OK */
mcs_nss_size = ieee80211_he_mcs_nss_size(he_cap_ie_elem);
--
2.38.1


2023-06-04 09:19:35

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 16/16] wifi: mac80211: stop warning after reconfig failures

From: Johannes Berg <[email protected]>

If we have a reconfig failure in the driver, then we need
to shut down the network interface(s) at the network stack
level through cfg80211, which can result in a lot of those
"Failed check-sdata-in-driver check, ..." warnings, since
interfaces are considered to not be in the driver when the
reconfiguration fails, but we still need to go through all
the shutdown flow.

Avoid many of these warnings by storing the fact that the
stack experienced a reconfiguration failure and not doing
the warning in that case.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/mac80211/driver-ops.h | 10 ++++++----
net/mac80211/ieee80211_i.h | 3 +++
net/mac80211/iface.c | 3 +++
net/mac80211/util.c | 1 +
4 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 45d3e53c7383..c4505593ba7a 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, 2021 Intel Corporation
+* Copyright (C) 2018 - 2019, 2021 - 2023 Intel Corporation
*/

#ifndef __MAC80211_DRIVER_OPS
@@ -13,9 +13,11 @@
#include "trace.h"

#define check_sdata_in_driver(sdata) ({ \
- !WARN_ONCE(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), \
- "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", \
- sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); \
+ WARN_ONCE(!sdata->local->reconfig_failure && \
+ !(sdata->flags & IEEE80211_SDATA_IN_DRIVER), \
+ "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", \
+ sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); \
+ !!(sdata->flags & IEEE80211_SDATA_IN_DRIVER); \
})

static inline struct ieee80211_sub_if_data *
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 46adb1d9a589..8358051720f8 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1394,6 +1394,9 @@ struct ieee80211_local {
/* device is during a HW reconfig */
bool in_reconfig;

+ /* reconfiguration failed ... suppress some warnings etc. */
+ bool reconfig_failure;
+
/* wowlan is enabled -- don't reconfig on resume */
bool wowlan;

diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index f1e01f7a9b2e..2e2115af38f5 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1281,6 +1281,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
}

if (local->open_count == 0) {
+ /* here we can consider everything in good order (again) */
+ local->reconfig_failure = false;
+
res = drv_start(local);
if (res)
goto err_del_bss;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 316a052d61bd..45ab533ef4f1 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2370,6 +2370,7 @@ static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
local->resuming = false;
local->suspended = false;
local->in_reconfig = false;
+ local->reconfig_failure = true;

ieee80211_flush_completed_scan(local, true);

--
2.38.1


2023-06-04 09:20:02

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 14/16] wifi: mac80211: Modify type of "changed" variable.

From: Anjaneyulu <[email protected]>

Currently, enum ieee80211_bss_change has more than 32 flags.
Change the type of the corresponding variables from u32 to u64.

Signed-off-by: Anjaneyulu <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
net/mac80211/cfg.c | 79 ++++++++++++++++++--------------------
net/mac80211/chan.c | 4 +-
net/mac80211/ibss.c | 16 ++++----
net/mac80211/ieee80211_i.h | 14 ++++---
net/mac80211/iface.c | 4 +-
net/mac80211/main.c | 4 +-
net/mac80211/mesh.c | 30 ++++++++-------
net/mac80211/mesh.h | 19 ++++-----
net/mac80211/mesh_plink.c | 37 +++++++++---------
net/mac80211/mesh_ps.c | 7 ++--
net/mac80211/mlme.c | 12 +++---
net/mac80211/ocb.c | 4 +-
12 files changed, 119 insertions(+), 111 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 49f5122189d3..c713233ee6d9 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1101,18 +1101,20 @@ ieee80211_copy_rnr_beacon(u8 *pos, struct cfg80211_rnr_elems *dst,
return offset;
}

-static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_link_data *link,
- struct cfg80211_beacon_data *params,
- const struct ieee80211_csa_settings *csa,
- const struct ieee80211_color_change_settings *cca)
+static int
+ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_link_data *link,
+ struct cfg80211_beacon_data *params,
+ const struct ieee80211_csa_settings *csa,
+ const struct ieee80211_color_change_settings *cca,
+ u64 *changed)
{
struct cfg80211_mbssid_elems *mbssid = NULL;
struct cfg80211_rnr_elems *rnr = NULL;
struct beacon_data *new, *old;
int new_head_len, new_tail_len;
int size, err;
- u32 changed = BSS_CHANGED_BEACON;
+ u64 _changed = BSS_CHANGED_BEACON;
struct ieee80211_bss_conf *link_conf = link->conf;

old = sdata_dereference(link->u.ap.beacon, sdata);
@@ -1219,7 +1221,7 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
return err;
}
if (err == 0)
- changed |= BSS_CHANGED_AP_PROBE_RESP;
+ _changed |= BSS_CHANGED_AP_PROBE_RESP;

if (params->ftm_responder != -1) {
link_conf->ftm_responder = params->ftm_responder;
@@ -1235,7 +1237,7 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
return err;
}

- changed |= BSS_CHANGED_FTM_RESPONDER;
+ _changed |= BSS_CHANGED_FTM_RESPONDER;
}

rcu_assign_pointer(link->u.ap.beacon, new);
@@ -1244,7 +1246,8 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
if (old)
kfree_rcu(old, rcu_head);

- return changed;
+ *changed |= _changed;
+ return 0;
}

static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
@@ -1446,10 +1449,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL))
link_conf->beacon_tx_rate = params->beacon_rate;

- err = ieee80211_assign_beacon(sdata, link, &params->beacon, NULL, NULL);
+ err = ieee80211_assign_beacon(sdata, link, &params->beacon, NULL, NULL,
+ &changed);
if (err < 0)
goto error;
- changed |= err;

if (params->fils_discovery.max_interval) {
err = ieee80211_set_fils_discovery(sdata,
@@ -1506,6 +1509,7 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
struct beacon_data *old;
int err;
struct ieee80211_bss_conf *link_conf;
+ u64 changed = 0;

sdata_assert_lock(sdata);

@@ -1525,17 +1529,18 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
if (!old)
return -ENOENT;

- err = ieee80211_assign_beacon(sdata, link, params, NULL, NULL);
+ err = ieee80211_assign_beacon(sdata, link, params, NULL, NULL,
+ &changed);
if (err < 0)
return err;

if (params->he_bss_color_valid &&
params->he_bss_color.enabled != link_conf->he_bss_color.enabled) {
link_conf->he_bss_color.enabled = params->he_bss_color.enabled;
- err |= BSS_CHANGED_HE_BSS_COLOR;
+ changed |= BSS_CHANGED_HE_BSS_COLOR;
}

- ieee80211_link_info_change_notify(sdata, link, err);
+ ieee80211_link_info_change_notify(sdata, link, changed);
return 0;
}

@@ -1717,7 +1722,7 @@ static void sta_apply_mesh_params(struct ieee80211_local *local,
{
#ifdef CONFIG_MAC80211_MESH
struct ieee80211_sub_if_data *sdata = sta->sdata;
- u32 changed = 0;
+ u64 changed = 0;

if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) {
switch (params->plink_state) {
@@ -2664,7 +2669,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_link_data *link;
struct ieee80211_supported_band *sband;
- u32 changed = 0;
+ u64 changed = 0;

link = ieee80211_link_or_deflink(sdata, params->link_id, true);
if (IS_ERR(link))
@@ -3589,7 +3594,7 @@ void ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif, bool block_t
EXPORT_SYMBOL(ieee80211_channel_switch_disconnect);

static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata,
- u32 *changed)
+ u64 *changed)
{
int err;

@@ -3600,25 +3605,22 @@ static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata,

err = ieee80211_assign_beacon(sdata, &sdata->deflink,
sdata->deflink.u.ap.next_beacon,
- NULL, NULL);
+ NULL, NULL, changed);
ieee80211_free_next_beacon(&sdata->deflink);

if (err < 0)
return err;
- *changed |= err;
break;
case NL80211_IFTYPE_ADHOC:
- err = ieee80211_ibss_finish_csa(sdata);
+ err = ieee80211_ibss_finish_csa(sdata, changed);
if (err < 0)
return err;
- *changed |= err;
break;
#ifdef CONFIG_MAC80211_MESH
case NL80211_IFTYPE_MESH_POINT:
- err = ieee80211_mesh_finish_csa(sdata);
+ err = ieee80211_mesh_finish_csa(sdata, changed);
if (err < 0)
return err;
- *changed |= err;
break;
#endif
default:
@@ -3632,7 +3634,7 @@ static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata,
static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
- u32 changed = 0;
+ u64 changed = 0;
int err;

sdata_assert_lock(sdata);
@@ -3729,7 +3731,7 @@ void ieee80211_csa_finalize_work(struct work_struct *work)

static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
struct cfg80211_csa_settings *params,
- u32 *changed)
+ u64 *changed)
{
struct ieee80211_csa_settings csa = {};
int err;
@@ -3776,12 +3778,11 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,

err = ieee80211_assign_beacon(sdata, &sdata->deflink,
&params->beacon_csa, &csa,
- NULL);
+ NULL, changed);
if (err < 0) {
ieee80211_free_next_beacon(&sdata->deflink);
return err;
}
- *changed |= err;

break;
case NL80211_IFTYPE_ADHOC:
@@ -3813,10 +3814,9 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,

/* see comments in the NL80211_IFTYPE_AP block */
if (params->count > 1) {
- err = ieee80211_ibss_csa_beacon(sdata, params);
+ err = ieee80211_ibss_csa_beacon(sdata, params, changed);
if (err < 0)
return err;
- *changed |= err;
}

ieee80211_send_action_csa(sdata, params);
@@ -3841,12 +3841,11 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,

/* see comments in the NL80211_IFTYPE_AP block */
if (params->count > 1) {
- err = ieee80211_mesh_csa_beacon(sdata, params);
+ err = ieee80211_mesh_csa_beacon(sdata, params, changed);
if (err < 0) {
ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
return err;
}
- *changed |= err;
}

if (ifmsh->csa_role == IEEE80211_MESH_CSA_ROLE_INIT)
@@ -3880,7 +3879,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_channel_switch ch_switch;
struct ieee80211_chanctx_conf *conf;
struct ieee80211_chanctx *chanctx;
- u32 changed = 0;
+ u64 changed = 0;
int err;

sdata_assert_lock(sdata);
@@ -4613,7 +4612,7 @@ static int ieee80211_set_sar_specs(struct wiphy *wiphy,

static int
ieee80211_set_after_color_change_beacon(struct ieee80211_sub_if_data *sdata,
- u32 *changed)
+ u64 *changed)
{
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP: {
@@ -4624,13 +4623,12 @@ ieee80211_set_after_color_change_beacon(struct ieee80211_sub_if_data *sdata,

ret = ieee80211_assign_beacon(sdata, &sdata->deflink,
sdata->deflink.u.ap.next_beacon,
- NULL, NULL);
+ NULL, NULL, changed);
ieee80211_free_next_beacon(&sdata->deflink);

if (ret < 0)
return ret;

- *changed |= ret;
break;
}
default:
@@ -4644,7 +4642,7 @@ ieee80211_set_after_color_change_beacon(struct ieee80211_sub_if_data *sdata,
static int
ieee80211_set_color_change_beacon(struct ieee80211_sub_if_data *sdata,
struct cfg80211_color_change_settings *params,
- u32 *changed)
+ u64 *changed)
{
struct ieee80211_color_change_settings color_change = {};
int err;
@@ -4667,12 +4665,11 @@ ieee80211_set_color_change_beacon(struct ieee80211_sub_if_data *sdata,

err = ieee80211_assign_beacon(sdata, &sdata->deflink,
&params->beacon_color_change,
- NULL, &color_change);
+ NULL, &color_change, changed);
if (err < 0) {
ieee80211_free_next_beacon(&sdata->deflink);
return err;
}
- *changed |= err;
break;
default:
return -EOPNOTSUPP;
@@ -4683,7 +4680,7 @@ ieee80211_set_color_change_beacon(struct ieee80211_sub_if_data *sdata,

static void
ieee80211_color_change_bss_config_notify(struct ieee80211_sub_if_data *sdata,
- u8 color, int enable, u32 changed)
+ u8 color, int enable, u64 changed)
{
sdata->vif.bss_conf.he_bss_color.color = color;
sdata->vif.bss_conf.he_bss_color.enabled = enable;
@@ -4711,7 +4708,7 @@ ieee80211_color_change_bss_config_notify(struct ieee80211_sub_if_data *sdata,
static int ieee80211_color_change_finalize(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
- u32 changed = 0;
+ u64 changed = 0;
int err;

sdata_assert_lock(sdata);
@@ -4808,7 +4805,7 @@ ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev,
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
- u32 changed = 0;
+ u64 changed = 0;
int err;

sdata_assert_lock(sdata);
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index a7e204de5d54..97b944b97d17 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -1257,7 +1257,7 @@ ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link)
struct ieee80211_vif_chanctx_switch vif_chsw[1] = {};
struct ieee80211_chanctx *old_ctx, *new_ctx;
const struct cfg80211_chan_def *chandef;
- u32 changed = 0;
+ u64 changed = 0;
int err;

lockdep_assert_held(&local->mtx);
@@ -1653,7 +1653,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
reserved_chanctx_list) {
struct ieee80211_sub_if_data *sdata = link->sdata;
struct ieee80211_bss_conf *link_conf = link->conf;
- u32 changed = 0;
+ u64 changed = 0;

if (!ieee80211_link_has_in_place_reservation(link))
continue;
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 9dffc3079588..faa01ee11d32 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -9,7 +9,7 @@
* Copyright 2009, Johannes Berg <[email protected]>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright(c) 2016 Intel Deutschland GmbH
- * Copyright(c) 2018-2022 Intel Corporation
+ * Copyright(c) 2018-2023 Intel Corporation
*/

#include <linux/delay.h>
@@ -226,7 +226,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct ieee80211_mgmt *mgmt;
struct cfg80211_bss *bss;
- u32 bss_change;
+ u64 bss_change;
struct cfg80211_chan_def chandef;
struct ieee80211_channel *chan;
struct beacon_data *presp;
@@ -478,7 +478,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
}

int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
- struct cfg80211_csa_settings *csa_settings)
+ struct cfg80211_csa_settings *csa_settings,
+ u64 *changed)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct beacon_data *presp, *old_presp;
@@ -520,10 +521,11 @@ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
if (old_presp)
kfree_rcu(old_presp, rcu_head);

- return BSS_CHANGED_BEACON;
+ *changed |= BSS_CHANGED_BEACON;
+ return 0;
}

-int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata)
+int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata, u64 *changed)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct cfg80211_bss *cbss;
@@ -552,7 +554,7 @@ int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata)
ifibss->chandef = sdata->deflink.csa_chandef;

/* generate the beacon */
- return ieee80211_ibss_csa_beacon(sdata, NULL);
+ return ieee80211_ibss_csa_beacon(sdata, NULL, changed);
}

void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata)
@@ -1754,7 +1756,7 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
struct cfg80211_ibss_params *params)
{
- u32 changed = 0;
+ u64 changed = 0;
u32 rate_flags;
struct ieee80211_supported_band *sband;
enum ieee80211_chanctx_mode chanmode;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 886244d42f04..46adb1d9a589 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1827,7 +1827,7 @@ void ieee80211_link_info_change_notify(struct ieee80211_sub_if_data *sdata,
struct ieee80211_link_data *link,
u64 changed);
void ieee80211_configure_filter(struct ieee80211_local *local);
-u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
+u64 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);

u64 ieee80211_mgmt_tx_cookie(struct ieee80211_local *local);
int ieee80211_attach_ack_skb(struct ieee80211_local *local, struct sk_buff *skb,
@@ -1887,8 +1887,10 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata);
void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb);
int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
- struct cfg80211_csa_settings *csa_settings);
-int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata);
+ struct cfg80211_csa_settings *csa_settings,
+ u64 *changed);
+int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata,
+ u64 *changed);
void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata);

/* OCB code */
@@ -1905,8 +1907,10 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata);
void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb);
int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata,
- struct cfg80211_csa_settings *csa_settings);
-int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata);
+ struct cfg80211_csa_settings *csa_settings,
+ u64 *changed);
+int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata,
+ u64 *changed);

/* scan/BSS handling */
void ieee80211_scan_work(struct work_struct *work);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index bd2c48870add..f1e01f7a9b2e 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -8,7 +8,7 @@
* Copyright 2008, Johannes Berg <[email protected]>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (c) 2016 Intel Deutschland GmbH
- * Copyright (C) 2018-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
*/
#include <linux/slab.h>
#include <linux/kernel.h>
@@ -1221,7 +1221,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct net_device *dev = wdev->netdev;
struct ieee80211_local *local = sdata->local;
- u32 changed = 0;
+ u64 changed = 0;
int res;
u32 hw_reconf_flags = 0;

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 55cdfaef0f5d..3db178b1d50c 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -5,7 +5,7 @@
* Copyright 2006-2007 Jiri Benc <[email protected]>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
*/

#include <net/mac80211.h>
@@ -291,7 +291,7 @@ void ieee80211_link_info_change_notify(struct ieee80211_sub_if_data *sdata,
drv_link_info_changed(local, sdata, link->conf, link->link_id, changed);
}

-u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
+u64 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
{
sdata->vif.bss_conf.use_cts_prot = false;
sdata->vif.bss_conf.use_short_preamble = false;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index f72333201903..a4d8764073bf 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2008, 2009 open80211s Ltd.
- * Copyright (C) 2018 - 2022 Intel Corporation
+ * Copyright (C) 2018 - 2023 Intel Corporation
* Authors: Luis Carlos Cobo <[email protected]>
* Javier Cardona <[email protected]>
*/
@@ -133,10 +133,10 @@ bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
*
* Returns: beacon changed flag if the beacon content changed.
*/
-u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
+u64 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
{
bool free_plinks;
- u32 changed = 0;
+ u64 changed = 0;

/* In case mesh_plink_free_count > 0 and mesh_plinktbl_capacity == 0,
* the mesh interface might be able to establish plinks with peers that
@@ -162,7 +162,7 @@ u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
void mesh_sta_cleanup(struct sta_info *sta)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
- u32 changed = mesh_plink_deactivate(sta);
+ u64 changed = mesh_plink_deactivate(sta);

if (changed)
ieee80211_mbss_info_change_notify(sdata, changed);
@@ -923,7 +923,7 @@ unsigned int ieee80211_new_mesh_header(struct ieee80211_sub_if_data *sdata,
static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
- u32 changed;
+ u64 changed;

if (ifmsh->mshcfg.plink_timeout > 0)
ieee80211_sta_expire(sdata, ifmsh->mshcfg.plink_timeout * HZ);
@@ -1164,7 +1164,7 @@ ieee80211_mesh_rebuild_beacon(struct ieee80211_sub_if_data *sdata)
}

void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
- u32 changed)
+ u64 changed)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
unsigned long bits = changed;
@@ -1184,7 +1184,7 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_local *local = sdata->local;
- u32 changed = BSS_CHANGED_BEACON |
+ u64 changed = BSS_CHANGED_BEACON |
BSS_CHANGED_BEACON_ENABLED |
BSS_CHANGED_HT |
BSS_CHANGED_BASIC_RATES |
@@ -1525,12 +1525,11 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
kfree(elems);
}

-int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
+int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata, u64 *changed)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct mesh_csa_settings *tmp_csa_settings;
int ret = 0;
- int changed = 0;

/* Reset the TTL value and Initiator flag */
ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
@@ -1545,15 +1544,16 @@ int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
if (ret)
return -EINVAL;

- changed |= BSS_CHANGED_BEACON;
+ *changed |= BSS_CHANGED_BEACON;

mcsa_dbg(sdata, "complete switching to center freq %d MHz",
sdata->vif.bss_conf.chandef.chan->center_freq);
- return changed;
+ return 0;
}

int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata,
- struct cfg80211_csa_settings *csa_settings)
+ struct cfg80211_csa_settings *csa_settings,
+ u64 *changed)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct mesh_csa_settings *tmp_csa_settings;
@@ -1579,7 +1579,8 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata,
return ret;
}

- return BSS_CHANGED_BEACON;
+ *changed |= BSS_CHANGED_BEACON;
+ return 0;
}

static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
@@ -1720,7 +1721,8 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
static void mesh_bss_info_changed(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
- u32 bit, changed = 0;
+ u32 bit;
+ u64 changed = 0;

for_each_set_bit(bit, &ifmsh->mbss_changed,
sizeof(changed) * BITS_PER_BYTE) {
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 022f41292a05..6c94222a9df5 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2008, 2009 open80211s Ltd.
+ * Copyright (C) 2023 Intel Corporation
* Authors: Luis Carlos Cobo <[email protected]>
* Javier Cardona <[email protected]>
*/
@@ -252,11 +253,11 @@ void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh);
const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method);
/* wrapper for ieee80211_bss_info_change_notify() */
void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
- u32 changed);
+ u64 changed);

/* mesh power save */
-u32 ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata);
-u32 ieee80211_mps_set_sta_local_pm(struct sta_info *sta,
+u64 ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata);
+u64 ieee80211_mps_set_sta_local_pm(struct sta_info *sta,
enum nl80211_mesh_power_mode pm);
void ieee80211_mps_set_frame_flags(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta,
@@ -303,12 +304,12 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
u8 *hw_addr, struct ieee802_11_elems *ie,
struct ieee80211_rx_status *rx_status);
bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
-u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
+u64 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
void mesh_plink_timer(struct timer_list *t);
void mesh_plink_broken(struct sta_info *sta);
-u32 mesh_plink_deactivate(struct sta_info *sta);
-u32 mesh_plink_open(struct sta_info *sta);
-u32 mesh_plink_block(struct sta_info *sta);
+u64 mesh_plink_deactivate(struct sta_info *sta);
+u64 mesh_plink_open(struct sta_info *sta);
+u64 mesh_plink_block(struct sta_info *sta);
void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len,
struct ieee80211_rx_status *rx_status);
@@ -349,14 +350,14 @@ void mesh_path_refresh(struct ieee80211_sub_if_data *sdata,

#ifdef CONFIG_MAC80211_MESH
static inline
-u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
+u64 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
{
atomic_inc(&sdata->u.mesh.estab_plinks);
return mesh_accept_plinks_update(sdata) | BSS_CHANGED_BEACON;
}

static inline
-u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
+u64 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
{
atomic_dec(&sdata->u.mesh.estab_plinks);
return mesh_accept_plinks_update(sdata) | BSS_CHANGED_BEACON;
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 8f168bc4e4b8..f3d5bb0a59f1 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2008, 2009 open80211s Ltd.
- * Copyright (C) 2019, 2021-2022 Intel Corporation
+ * Copyright (C) 2019, 2021-2023 Intel Corporation
* Author: Luis Carlos Cobo <[email protected]>
*/
#include <linux/gfp.h>
@@ -90,12 +90,13 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta)
*
* Returns BSS_CHANGED_ERP_SLOT or 0 for no change.
*/
-static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
+static u64 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_supported_band *sband;
struct sta_info *sta;
- u32 erp_rates = 0, changed = 0;
+ u32 erp_rates = 0;
+ u64 changed = 0;
int i;
bool short_slot = false;

@@ -153,7 +154,7 @@ static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
* is selected if all peers in our 20/40MHz MBSS support HT and at least one
* HT20 peer is present. Otherwise no-protection mode is selected.
*/
-static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
+static u64 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
@@ -365,10 +366,10 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
*
* Locking: the caller must hold sta->mesh->plink_lock
*/
-static u32 __mesh_plink_deactivate(struct sta_info *sta)
+static u64 __mesh_plink_deactivate(struct sta_info *sta)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
- u32 changed = 0;
+ u64 changed = 0;

lockdep_assert_held(&sta->mesh->plink_lock);

@@ -390,10 +391,10 @@ static u32 __mesh_plink_deactivate(struct sta_info *sta)
*
* All mesh paths with this peer as next hop will be flushed
*/
-u32 mesh_plink_deactivate(struct sta_info *sta)
+u64 mesh_plink_deactivate(struct sta_info *sta)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
- u32 changed;
+ u64 changed;

spin_lock_bh(&sta->mesh->plink_lock);
changed = __mesh_plink_deactivate(sta);
@@ -622,7 +623,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
struct ieee80211_rx_status *rx_status)
{
struct sta_info *sta;
- u32 changed = 0;
+ u64 changed = 0;

sta = mesh_sta_info_get(sdata, hw_addr, elems, rx_status);
if (!sta)
@@ -775,10 +776,10 @@ static u16 mesh_get_new_llid(struct ieee80211_sub_if_data *sdata)
return llid;
}

-u32 mesh_plink_open(struct sta_info *sta)
+u64 mesh_plink_open(struct sta_info *sta)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
- u32 changed;
+ u64 changed;

if (!test_sta_flag(sta, WLAN_STA_AUTH))
return 0;
@@ -805,9 +806,9 @@ u32 mesh_plink_open(struct sta_info *sta)
return changed;
}

-u32 mesh_plink_block(struct sta_info *sta)
+u64 mesh_plink_block(struct sta_info *sta)
{
- u32 changed;
+ u64 changed;

spin_lock_bh(&sta->mesh->plink_lock);
changed = __mesh_plink_deactivate(sta);
@@ -831,11 +832,11 @@ static void mesh_plink_close(struct ieee80211_sub_if_data *sdata,
mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
}

-static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
+static u64 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta)
{
struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
- u32 changed = 0;
+ u64 changed = 0;

del_timer(&sta->mesh->plink_timer);
sta->mesh->plink_state = NL80211_PLINK_ESTAB;
@@ -857,12 +858,12 @@ static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
*
* Return: changed MBSS flags
*/
-static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
+static u64 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta, enum plink_event event)
{
struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
enum ieee80211_self_protected_actioncode action = 0;
- u32 changed = 0;
+ u64 changed = 0;
bool flush = false;

mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr,
@@ -1117,7 +1118,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta;
enum plink_event event;
enum ieee80211_self_protected_actioncode ftype;
- u32 changed = 0;
+ u64 changed = 0;
u8 ie_len = elems->peering_len;
u16 plid, llid = 0;

diff --git a/net/mac80211/mesh_ps.c b/net/mac80211/mesh_ps.c
index 3fbd0b9ff913..35eacca43e49 100644
--- a/net/mac80211/mesh_ps.c
+++ b/net/mac80211/mesh_ps.c
@@ -3,6 +3,7 @@
* Copyright 2012-2013, Marco Porsch <[email protected]>
* Copyright 2012-2013, cozybit Inc.
* Copyright (C) 2021 Intel Corporation
+ * Copyright (C) 2023 Intel Corporation
*/

#include "mesh.h"
@@ -77,14 +78,14 @@ static void mps_qos_null_tx(struct sta_info *sta)
* sets the non-peer power mode and triggers the driver PS (re-)configuration
* Return BSS_CHANGED_BEACON if a beacon update is necessary.
*/
-u32 ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata)
+u64 ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct sta_info *sta;
bool peering = false;
int light_sleep_cnt = 0;
int deep_sleep_cnt = 0;
- u32 changed = 0;
+ u64 changed = 0;
enum nl80211_mesh_power_mode nonpeer_pm;

rcu_read_lock();
@@ -148,7 +149,7 @@ u32 ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata)
* @pm: the power mode to set
* Return BSS_CHANGED_BEACON if a beacon update is in order.
*/
-u32 ieee80211_mps_set_sta_local_pm(struct sta_info *sta,
+u64 ieee80211_mps_set_sta_local_pm(struct sta_info *sta,
enum nl80211_mesh_power_mode pm)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 7d6248b8d280..68ee837cbbef 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2110,7 +2110,7 @@ static void ieee80211_find_cisco_dtpc(struct ieee80211_sub_if_data *sdata,
*pwr_level = (__s8)cisco_dtpc_ie[4];
}

-static u32 ieee80211_handle_pwr_constr(struct ieee80211_link_data *link,
+static u64 ieee80211_handle_pwr_constr(struct ieee80211_link_data *link,
struct ieee80211_channel *channel,
struct ieee80211_mgmt *mgmt,
const u8 *country_ie, u8 country_ie_len,
@@ -2700,12 +2700,12 @@ static void ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
mutex_unlock(&sdata->local->mtx);
}

-static u32 ieee80211_handle_bss_capability(struct ieee80211_link_data *link,
+static u64 ieee80211_handle_bss_capability(struct ieee80211_link_data *link,
u16 capab, bool erp_valid, u8 erp)
{
struct ieee80211_bss_conf *bss_conf = link->conf;
struct ieee80211_supported_band *sband;
- u32 changed = 0;
+ u64 changed = 0;
bool use_protection;
bool use_short_preamble;
bool use_short_slot;
@@ -2751,7 +2751,7 @@ static u64 ieee80211_link_set_associated(struct ieee80211_link_data *link,
struct ieee80211_sub_if_data *sdata = link->sdata;
struct ieee80211_bss_conf *bss_conf = link->conf;
struct ieee80211_bss *bss = (void *)cbss->priv;
- u32 changed = BSS_CHANGED_QOS;
+ u64 changed = BSS_CHANGED_QOS;

/* not really used in MLO */
sdata->u.mgd.beacon_timeout =
@@ -2889,7 +2889,7 @@ 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;
unsigned int link_id;
- u32 changed = 0;
+ u64 changed = 0;
struct ieee80211_prep_tx_info info = {
.subtype = stype,
};
@@ -3959,7 +3959,7 @@ static bool ieee80211_twt_req_supported(struct ieee80211_sub_if_data *sdata,
IEEE80211_HE_MAC_CAP0_TWT_REQ);
}

-static int ieee80211_recalc_twt_req(struct ieee80211_sub_if_data *sdata,
+static u64 ieee80211_recalc_twt_req(struct ieee80211_sub_if_data *sdata,
struct ieee80211_supported_band *sband,
struct ieee80211_link_data *link,
struct link_sta_info *link_sta,
diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c
index a57dcbe99a0d..cf205762ab96 100644
--- a/net/mac80211/ocb.c
+++ b/net/mac80211/ocb.c
@@ -4,7 +4,7 @@
*
* Copyright: (c) 2014 Czech Technical University in Prague
* (c) 2014 Volkswagen Group Research
- * Copyright (C) 2022 Intel Corporation
+ * Copyright (C) 2022 - 2023 Intel Corporation
* Author: Rostislav Lisovy <[email protected]>
* Funded by: Volkswagen Group Research
*/
@@ -175,7 +175,7 @@ int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
- u32 changed = BSS_CHANGED_OCB | BSS_CHANGED_BSSID;
+ u64 changed = BSS_CHANGED_OCB | BSS_CHANGED_BSSID;
int err;

if (ifocb->joined == true)
--
2.38.1


2023-06-04 09:20:25

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 15/16] wifi: mac80211_hwsim: Fix possible NULL dereference

From: Ilan Peer <[email protected]>

In a call to mac80211_hwsim_select_tx_link() the sta pointer might
be NULL, thus need to check that it is not NULL before accessing it.

Signed-off-by: Ilan Peer <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
drivers/net/wireless/virtual/mac80211_hwsim.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
index b06a6e78169d..c706abbdaa17 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
@@ -4,7 +4,7 @@
* Copyright (c) 2008, Jouni Malinen <[email protected]>
* Copyright (c) 2011, Javier Lopez <[email protected]>
* Copyright (c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright (C) 2018 - 2022 Intel Corporation
+ * Copyright (C) 2018 - 2023 Intel Corporation
*/

/*
@@ -1865,7 +1865,7 @@ mac80211_hwsim_select_tx_link(struct mac80211_hwsim_data *data,

WARN_ON(is_multicast_ether_addr(hdr->addr1));

- if (WARN_ON_ONCE(!sta->valid_links))
+ if (WARN_ON_ONCE(!sta || !sta->valid_links))
return &vif->bss_conf;

for (i = 0; i < ARRAY_SIZE(vif->link_conf); i++) {
--
2.38.1


2023-06-06 13:26:13

by Nicolas Escande

[permalink] [raw]
Subject: Re: [PATCH 13/16] wifi: mac80211: remove typecast in a call to ieee80211_config_bw()

On Sun Jun 4, 2023 at 11:11 AM CEST, wrote:
> From: Anjaneyulu <[email protected]>
>
> Make "changed" to be u64 as implied by the corresponding enum size.
>
> Fixes: 61513162aa2d ("wifi: mac80211: mlme: shift some code around")
> Signed-off-by: Anjaneyulu <[email protected]>
> Signed-off-by: Gregory Greenman <[email protected]>
> ---
> net/mac80211/cfg.c | 2 +-
> net/mac80211/chan.c | 2 +-
> net/mac80211/ieee80211_i.h | 2 +-
> 3 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
> index 7317e4a5d1ff..49f5122189d3 100644
> --- a/net/mac80211/cfg.c
> +++ b/net/mac80211/cfg.c
> @@ -5,7 +5,7 @@
> * Copyright 2006-2010 Johannes Berg <[email protected]>
> * Copyright 2013-2015 Intel Mobile Communications GmbH
> * Copyright (C) 2015-2017 Intel Deutschland GmbH
> - * Copyright (C) 2018-2022 Intel Corporation
> + * Copyright (C) 2018-2023 Intel Corporation
> */
>
> #include <linux/ieee80211.h>
> diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
> index 77c90ed8f5d7..a7e204de5d54 100644
> --- a/net/mac80211/chan.c
> +++ b/net/mac80211/chan.c
> @@ -1,7 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /*
> * mac80211 - channel management
> - * Copyright 2020 - 2022 Intel Corporation
> + * Copyright 2020 - 2023 Intel Corporation
> */
>
> #include <linux/nl80211.h>
> diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
> index e67c5c754be1..886244d42f04 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-2022 Intel Corporation
> + * Copyright (C) 2018-2023 Intel Corporation
> */
>
> #ifndef IEEE80211_I_H

Hi there,

Did I miss something or there's no code in this one but just copyright updates ?

---
Nicolas E.

2023-06-06 13:39:08

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 13/16] wifi: mac80211: remove typecast in a call to ieee80211_config_bw()

On Tue, 2023-06-06 at 15:18 +0200, Nicolas Escande wrote:
>
> Did I miss something or there's no code in this one but just copyright updates ?
>

Yeah ... I already dropped the patch. Apparently Gregory missed, when
transferring from our tree to upstream, that these changes had already
been rolled up or done elsewhere.

johannes

2023-12-02 17:57:10

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 14/16] wifi: mac80211: Modify type of "changed" variable.

On 6/4/2023 2:11 AM, [email protected] wrote:
> From: Anjaneyulu <[email protected]>
>
> Currently, enum ieee80211_bss_change has more than 32 flags.
> Change the type of the corresponding variables from u32 to u64.
>
> Signed-off-by: Anjaneyulu <[email protected]>
> Signed-off-by: Gregory Greenman <[email protected]>
> ---
> net/mac80211/cfg.c | 79 ++++++++++++++++++--------------------
> net/mac80211/chan.c | 4 +-
> net/mac80211/ibss.c | 16 ++++----
> net/mac80211/ieee80211_i.h | 14 ++++---
> net/mac80211/iface.c | 4 +-
> net/mac80211/main.c | 4 +-
> net/mac80211/mesh.c | 30 ++++++++-------
> net/mac80211/mesh.h | 19 ++++-----
> net/mac80211/mesh_plink.c | 37 +++++++++---------
> net/mac80211/mesh_ps.c | 7 ++--
> net/mac80211/mlme.c | 12 +++---
> net/mac80211/ocb.c | 4 +-
> 12 files changed, 119 insertions(+), 111 deletions(-)

We are finally at the point where we are testing mesh and this patch is
breaking mesh on 32-bit systems. There seems to be a fundamental issue
with both the original code and the revised code where bitop operations
are being used on bitmaps which have not been defined and sized with
DECLARE_BITMAP.

Note the bitops all use unsigned long * for the bitmap pointer, and
hence it seems important that all the bitmaps being used with these
operations use that same underlying type.

The specific code that is causing us issues is in
ieee80211_mbss_info_change_notify():
for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE)
set_bit(bit, ifmsh->mbss_changed);

Here in the current code changed is u64 and ifmsh->mbss_changed is
unsigned long and hence processing a bit > 32 writes outside
ifmsh->mbss_changed on a 32-bit system.

At a minimum struct ieee80211_if_mesh::mbss_changed needs to be properly
sized.

We have validated what I consider to be a quick and dirty change which
modifies struct ieee80211_if_mesh::mbss_changed from unsigned long to u64.

Do you want that change?

Or do you want to propose an encompassing solution that correctly uses
unsigned long * and DECLARE_BOTMAP


/jeff


2023-12-03 16:48:37

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 14/16] wifi: mac80211: Modify type of "changed" variable.

On 12/2/2023 9:56 AM, Jeff Johnson wrote:
> On 6/4/2023 2:11 AM, [email protected] wrote:
>> From: Anjaneyulu <[email protected]>
>>
>> Currently, enum ieee80211_bss_change has more than 32 flags.
>> Change the type of the corresponding variables from u32 to u64.
>>
>> Signed-off-by: Anjaneyulu <[email protected]>
>> Signed-off-by: Gregory Greenman <[email protected]>
>> ---
>> net/mac80211/cfg.c | 79 ++++++++++++++++++--------------------
>> net/mac80211/chan.c | 4 +-
>> net/mac80211/ibss.c | 16 ++++----
>> net/mac80211/ieee80211_i.h | 14 ++++---
>> net/mac80211/iface.c | 4 +-
>> net/mac80211/main.c | 4 +-
>> net/mac80211/mesh.c | 30 ++++++++-------
>> net/mac80211/mesh.h | 19 ++++-----
>> net/mac80211/mesh_plink.c | 37 +++++++++---------
>> net/mac80211/mesh_ps.c | 7 ++--
>> net/mac80211/mlme.c | 12 +++---
>> net/mac80211/ocb.c | 4 +-
>> 12 files changed, 119 insertions(+), 111 deletions(-)
>
> We are finally at the point where we are testing mesh and this patch is
> breaking mesh on 32-bit systems. There seems to be a fundamental issue
> with both the original code and the revised code where bitop operations
> are being used on bitmaps which have not been defined and sized with
> DECLARE_BITMAP.
>
> Note the bitops all use unsigned long * for the bitmap pointer, and
> hence it seems important that all the bitmaps being used with these
> operations use that same underlying type.
>
> The specific code that is causing us issues is in
> ieee80211_mbss_info_change_notify():
> for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE)
> set_bit(bit, ifmsh->mbss_changed);
>
> Here in the current code changed is u64 and ifmsh->mbss_changed is
> unsigned long and hence processing a bit > 32 writes outside
> ifmsh->mbss_changed on a 32-bit system.
>
> At a minimum struct ieee80211_if_mesh::mbss_changed needs to be properly
> sized.
>
> We have validated what I consider to be a quick and dirty change which
> modifies struct ieee80211_if_mesh::mbss_changed from unsigned long to u64.
>
> Do you want that change?
>
> Or do you want to propose an encompassing solution that correctly uses
> unsigned long * and DECLARE_BOTMAP
>
>
> /jeff
>
>

Apologies for reporting an issue that has already been (somewhat) fixed
by 6e48ebffc2db ("wifi: mac80211: fix mesh id corruption on 32 bit
systems"). Issue was found internally in a backported kernel and that
fix was not present.

But note that fix did not use DECLARE_BITMAP which I still think is the
right thing to do everywhere we are using bitops.

/jeff

2023-12-03 18:42:27

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 14/16] wifi: mac80211: Modify type of "changed" variable.

On Sun, 2023-12-03 at 08:48 -0800, Jeff Johnson wrote:
> Apologies for reporting an issue that has already been (somewhat) fixed
> by 6e48ebffc2db ("wifi: mac80211: fix mesh id corruption on 32 bit
> systems"). Issue was found internally in a backported kernel and that
> fix was not present.
>
> But note that fix did not use DECLARE_BITMAP which I still think is the
> right thing to do everywhere we are using bitops.
>

The mesh use here is a bit weird with the atomic ops on it, everything
else just uses plain ops (|= etc.). I think that there could be done
with cmpxchg64(), but you can't assume that on 32-bit machines ...

However, I think the whole trick is really no longer needed? A quick
look at the callers of ieee80211_mbss_info_change_notify() suggests that
they all can sleep and also already hold wiphy mutex, so there's not
even any need to bounce through the workqueue *again*? IOW, we can
remove that whole thing? Do you see anything to the contrary?

So realistically I think rather than paper over it again with
DECLARE_BITMAP() and all the right thing here to do is actually try to
understand the code again and make some cleanups, since it's grown and
(mostly?) survived two major locking restructurings, but has not been
adjusted to any of that.

johannes