mac80211: Update to version 5.15-rc6-1
authorHauke Mehrtens <hauke@hauke-m.de>
Mon, 18 Oct 2021 22:44:43 +0000 (00:44 +0200)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 23 Oct 2021 22:08:38 +0000 (00:08 +0200)
The removed patches were applied upstream.
The Cisco Aironet 802.11b driver was removed from backports, remove
it also from OpenWrt.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
16 files changed:
package/kernel/mac80211/Makefile
package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch
package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch
package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch
package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch
package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch
package/kernel/mac80211/patches/brcm/998-survey.patch
package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch
package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch
package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch
package/kernel/mac80211/patches/subsys/210-ap_scan.patch
package/kernel/mac80211/patches/subsys/387-nl80211-add-support-for-BSS-coloring.patch [deleted file]
package/kernel/mac80211/patches/subsys/388-mac80211-add-support-for-BSS-color-change.patch [deleted file]
package/kernel/mac80211/patches/subsys/389-ieee80211-add-TWT-element-definitions.patch [deleted file]
package/kernel/mac80211/patches/subsys/390-mac80211-introduce-individual-TWT-support-in-AP-mode.patch [deleted file]
package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch

index 1fc9dc4c486d9bfa20a78e616f138016ab70e89c..89e078b0c38e081df99be5c526a38d4e0b6308fa 100644 (file)
@@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=5.14.13-1
+PKG_VERSION:=5.15-rc6-1
 PKG_RELEASE:=1
-PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.14.13/
-PKG_HASH:=042aef20caf17ef649502d5f2e744a7676abe7faed18de83c96f37bc029635fe
+PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15-rc6/
+PKG_HASH:=9282612c4c02ef9fc9d74405303033f6b53914cd63d631eef0f43155fcd38932
 
 PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
@@ -23,7 +23,6 @@ PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
 
 PKG_DRIVERS = \
        adm8211 \
-       airo \
        hermes hermes-pci hermes-pcmcia hermes-plx\
        lib80211 \
        mac80211-hwsim \
@@ -174,18 +173,6 @@ define KernelPackage/adm8211
   AUTOLOAD:=$(call AutoProbe,adm8211)
 endef
 
-define KernelPackage/airo
-  $(call KernelPackage/mac80211/Default)
-  TITLE:=Cisco Aironet driver
-  DEPENDS+=@PCI_SUPPORT +@DRIVER_WEXT_SUPPORT +kmod-cfg80211 @TARGET_x86 @BROKEN
-  FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/cisco/airo.ko
-  AUTOLOAD:=$(call AutoProbe,airo)
-endef
-
-define KernelPackage/airo/description
- Kernel support for Cisco Aironet cards
-endef
-
 define KernelPackage/hermes
   $(call KernelPackage/mac80211/Default)
   TITLE:=Hermes 802.11b chipset support
@@ -406,8 +393,6 @@ endif
 
 config-$(call config_package,lib80211) += LIB80211 LIB80211_CRYPT_WEP LIB80211_CRYPT_CCMP LIB80211_CRYPT_TKIP
 
-config-$(call config_package,airo) += AIRO
-
 config-$(call config_package,mac80211-hwsim) += MAC80211_HWSIM
 config-$(call config_package,mt7601u) += MT7601U
 config-y += WL_MEDIATEK
index bda710d5c0430e95bd795a8f5bd57766f4cae18f..833e2411c485e7152fef51a3788dd3b573734a57 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/wireless/reg.c
 +++ b/net/wireless/reg.c
-@@ -3292,6 +3292,8 @@ void regulatory_hint_country_ie(struct w
+@@ -3299,6 +3299,8 @@ void regulatory_hint_country_ie(struct w
        enum environment_cap env = ENVIRON_ANY;
        struct regulatory_request *request = NULL, *lr;
  
@@ -9,7 +9,7 @@
        /* IE len must be evenly divisible by 2 */
        if (country_ie_len & 0x01)
                return;
-@@ -3543,6 +3545,7 @@ static bool is_wiphy_all_set_reg_flag(en
+@@ -3550,6 +3552,7 @@ static bool is_wiphy_all_set_reg_flag(en
  
  void regulatory_hint_disconnect(void)
  {
index c17001eecbbacce4be44fc6b2dbb1a94679f99c1..0886fd688ac59c2533861c1db0d837be24b504f4 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath10k/Kconfig
 +++ b/drivers/net/wireless/ath/ath10k/Kconfig
-@@ -85,6 +85,12 @@ config ATH10K_TRACING
+@@ -86,6 +86,12 @@ config ATH10K_TRACING
        help
          Select this to ath10k use tracing infrastructure.
  
index c8d76329002f3d0e4a22cc3c4ecf7c5415da4be6..d815ba2742e3a05ef1cf5d3c33871fce94af7cf9 100644 (file)
@@ -85,7 +85,7 @@ v13:
  create mode 100644 drivers/net/wireless/ath/ath10k/leds.h
 --- a/drivers/net/wireless/ath/ath10k/Kconfig
 +++ b/drivers/net/wireless/ath/ath10k/Kconfig
-@@ -70,6 +70,16 @@ config ATH10K_DEBUGFS
+@@ -71,6 +71,16 @@ config ATH10K_DEBUGFS
  
          If unsure, say Y to make it easier to debug problems.
  
index 7c76699c4456f97e1a2a1c5306f60d46895a1777..aa890ce0f3a144020c882ad77ced8e5beb111b16 100644 (file)
@@ -20,8 +20,8 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 +      struct completion *completion;
  };
  
- static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
-@@ -636,6 +637,8 @@ static void brcmf_fw_request_done(const
+ #ifdef CONFIG_EFI
+@@ -653,6 +654,8 @@ static void brcmf_fw_request_done(const
                fwctx->req = NULL;
        }
        fwctx->done(fwctx->dev, ret, fwctx->req);
@@ -30,16 +30,16 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
        kfree(fwctx);
  }
  
-@@ -660,6 +663,8 @@ int brcmf_fw_get_firmwares(struct device
+@@ -693,6 +696,8 @@ int brcmf_fw_get_firmwares(struct device
  {
        struct brcmf_fw_item *first = &req->items[0];
        struct brcmf_fw *fwctx;
 +      struct completion completion;
 +      unsigned long time_left;
+       char *alt_path;
        int ret;
  
-       brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
-@@ -676,6 +681,9 @@ int brcmf_fw_get_firmwares(struct device
+@@ -710,6 +715,9 @@ int brcmf_fw_get_firmwares(struct device
        fwctx->dev = dev;
        fwctx->req = req;
        fwctx->done = fw_cb;
@@ -47,9 +47,9 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 +      init_completion(&completion);
 +      fwctx->completion = &completion;
  
-       ret = request_firmware_nowait(THIS_MODULE, true, first->path,
-                                     fwctx->dev, GFP_KERNEL, fwctx,
-@@ -683,6 +691,12 @@ int brcmf_fw_get_firmwares(struct device
+       /* First try alternative board-specific path if any */
+       alt_path = brcm_alt_fw_path(first->path, fwctx->req->board_type);
+@@ -726,6 +734,12 @@ int brcmf_fw_get_firmwares(struct device
        if (ret < 0)
                brcmf_fw_request_done(NULL, fwctx);
  
index 2e22ec793b0ad79fdbc1ab26f21eae9a2ba39d4e..88465f256be5f1b6a2d8d48afdd59949584e079e 100644 (file)
@@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -2966,6 +2966,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
+@@ -2974,6 +2974,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
         * preference in cfg struct to apply this to
         * FW later while initializing the dongle
         */
index 1479c671561a597515d8753291c67f1725858a02..a5efc08015fa6737353eace295757ae287667d75 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -2913,6 +2913,63 @@ done:
+@@ -2921,6 +2921,63 @@ done:
  }
  
  static int
@@ -64,7 +64,7 @@
  brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
                            int idx, u8 *mac, struct station_info *sinfo)
  {
-@@ -3013,6 +3070,7 @@ static s32 brcmf_inform_single_bss(struc
+@@ -3021,6 +3078,7 @@ static s32 brcmf_inform_single_bss(struc
        struct brcmu_chan ch;
        u16 channel;
        u32 freq;
@@ -72,7 +72,7 @@
        u16 notify_capability;
        u16 notify_interval;
        u8 *notify_ie;
-@@ -3037,6 +3095,17 @@ static s32 brcmf_inform_single_bss(struc
+@@ -3045,6 +3103,17 @@ static s32 brcmf_inform_single_bss(struc
                band = NL80211_BAND_5GHZ;
  
        freq = ieee80211_channel_to_frequency(channel, band);
@@ -90,7 +90,7 @@
        bss_data.chan = ieee80211_get_channel(wiphy, freq);
        bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20;
        bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime());
-@@ -5565,6 +5634,7 @@ static struct cfg80211_ops brcmf_cfg8021
+@@ -5573,6 +5642,7 @@ static struct cfg80211_ops brcmf_cfg8021
        .leave_ibss = brcmf_cfg80211_leave_ibss,
        .get_station = brcmf_cfg80211_get_station,
        .dump_station = brcmf_cfg80211_dump_station,
index 0bfc2860f13f7fa8a7830410367265b7257ecf26..3967d73fad3cfab0fb8b3ccc2f8d256a8472dd03 100644 (file)
@@ -1,6 +1,6 @@
 --- a/local-symbols
 +++ b/local-symbols
-@@ -431,43 +431,6 @@ USB_VL600=
+@@ -421,43 +421,6 @@ USB_VL600=
  USB_NET_CH9200=
  USB_NET_AQC111=
  USB_RTL8153_ECM=
        select BRCMUTIL
 --- a/Kconfig.local
 +++ b/Kconfig.local
-@@ -1297,117 +1297,6 @@ config BACKPORTED_USB_NET_AQC111
+@@ -1267,117 +1267,6 @@ config BACKPORTED_USB_NET_AQC111
  config BACKPORTED_USB_RTL8153_ECM
        tristate
        default USB_RTL8153_ECM
index 5cbbf12462f3ac39b4294e494a1e66c2ee077cfb..5bc55cc90b3906c11c92f2a57de3509e63304943 100644 (file)
@@ -1,6 +1,6 @@
 --- a/local-symbols
 +++ b/local-symbols
-@@ -325,6 +325,7 @@ RT2X00_LIB_FIRMWARE=
+@@ -315,6 +315,7 @@ RT2X00_LIB_FIRMWARE=
  RT2X00_LIB_CRYPTO=
  RT2X00_LIB_LEDS=
  RT2X00_LIB_DEBUGFS=
index 227eacf49aea88dc97b32d03338c9d082053fab4..02b2947ebf2dae23d71f1164483fdbf5b3dffd2c 100644 (file)
@@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
 
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1306,7 +1306,6 @@ static int ieee80211_stop_ap(struct wiph
+@@ -1314,7 +1314,6 @@ static int ieee80211_stop_ap(struct wiph
        sdata->vif.bss_conf.ftmr_params = NULL;
  
        __sta_info_flush(sdata, true);
index 1efa336d0c29302ee03011ada76c613af7bd51dd..5d1823e5c6cc9d65f9e6f69438681cbc9e2a8b56 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2487,7 +2487,7 @@ static int ieee80211_scan(struct wiphy *
+@@ -2495,7 +2495,7 @@ static int ieee80211_scan(struct wiphy *
                 * the  frames sent while scanning on other channel will be
                 * lost)
                 */
diff --git a/package/kernel/mac80211/patches/subsys/387-nl80211-add-support-for-BSS-coloring.patch b/package/kernel/mac80211/patches/subsys/387-nl80211-add-support-for-BSS-coloring.patch
deleted file mode 100644 (file)
index f2ebede..0000000
+++ /dev/null
@@ -1,492 +0,0 @@
-From 0d2ab3aea50bb02ff0c9c3d53c7b2b4b21cdd59d Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 2 Jul 2021 19:44:07 +0200
-Subject: [PATCH] nl80211: add support for BSS coloring
-
-This patch adds support for BSS color collisions to the wireless subsystem.
-Add the required functionality to nl80211 that will notify about color
-collisions, triggering the color change and notifying when it is completed.
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: John Crispin <john@phrozen.org>
-Link: https://lore.kernel.org/r/500b3582aec8fe2c42ef46f3117b148cb7cbceb5.1625247619.git.lorenzo@kernel.org
-[remove unnecessary NULL initialisation]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/net/cfg80211.h       |  92 ++++++++++++++++++++
- include/uapi/linux/nl80211.h |  43 ++++++++++
- net/wireless/nl80211.c       | 157 +++++++++++++++++++++++++++++++++++
- net/wireless/rdev-ops.h      |  13 +++
- net/wireless/trace.h         |  46 ++++++++++
- 5 files changed, 351 insertions(+)
-
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -1258,6 +1258,27 @@ struct cfg80211_csa_settings {
- };
- /**
-+ * struct cfg80211_color_change_settings - color change settings
-+ *
-+ * Used for bss color change
-+ *
-+ * @beacon_color_change: beacon data while performing the color countdown
-+ * @counter_offsets_beacon: offsets of the counters within the beacon (tail)
-+ * @counter_offsets_presp: offsets of the counters within the probe response
-+ * @beacon_next: beacon data to be used after the color change
-+ * @count: number of beacons until the color change
-+ * @color: the color used after the change
-+ */
-+struct cfg80211_color_change_settings {
-+      struct cfg80211_beacon_data beacon_color_change;
-+      u16 counter_offset_beacon;
-+      u16 counter_offset_presp;
-+      struct cfg80211_beacon_data beacon_next;
-+      u8 count;
-+      u8 color;
-+};
-+
-+/**
-  * struct iface_combination_params - input parameters for interface combinations
-  *
-  * Used to pass interface combination parameters
-@@ -4000,6 +4021,8 @@ struct mgmt_frame_regs {
-  *    given TIDs. This callback may sleep.
-  *
-  * @set_sar_specs: Update the SAR (TX power) settings.
-+ *
-+ * @color_change: Initiate a color change.
-  */
- struct cfg80211_ops {
-       int     (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
-@@ -4327,6 +4350,9 @@ struct cfg80211_ops {
-                                   const u8 *peer, u8 tids);
-       int     (*set_sar_specs)(struct wiphy *wiphy,
-                                struct cfg80211_sar_specs *sar);
-+      int     (*color_change)(struct wiphy *wiphy,
-+                              struct net_device *dev,
-+                              struct cfg80211_color_change_settings *params);
- };
- /*
-@@ -8226,4 +8252,70 @@ void cfg80211_update_owe_info_event(stru
-  */
- void cfg80211_bss_flush(struct wiphy *wiphy);
-+/**
-+ * cfg80211_bss_color_notify - notify about bss color event
-+ * @dev: network device
-+ * @gfp: allocation flags
-+ * @cmd: the actual event we want to notify
-+ * @count: the number of TBTTs until the color change happens
-+ * @color_bitmap: representations of the colors that the local BSS is aware of
-+ */
-+int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp,
-+                            enum nl80211_commands cmd, u8 count,
-+                            u64 color_bitmap);
-+
-+/**
-+ * cfg80211_obss_color_collision_notify - notify about bss color collision
-+ * @dev: network device
-+ * @color_bitmap: representations of the colors that the local BSS is aware of
-+ */
-+static inline int cfg80211_obss_color_collision_notify(struct net_device *dev,
-+                                                     u64 color_bitmap)
-+{
-+      return cfg80211_bss_color_notify(dev, GFP_KERNEL,
-+                                       NL80211_CMD_OBSS_COLOR_COLLISION,
-+                                       0, color_bitmap);
-+}
-+
-+/**
-+ * cfg80211_color_change_started_notify - notify color change start
-+ * @dev: the device on which the color is switched
-+ * @count: the number of TBTTs until the color change happens
-+ *
-+ * Inform the userspace about the color change that has started.
-+ */
-+static inline int cfg80211_color_change_started_notify(struct net_device *dev,
-+                                                     u8 count)
-+{
-+      return cfg80211_bss_color_notify(dev, GFP_KERNEL,
-+                                       NL80211_CMD_COLOR_CHANGE_STARTED,
-+                                       count, 0);
-+}
-+
-+/**
-+ * cfg80211_color_change_aborted_notify - notify color change abort
-+ * @dev: the device on which the color is switched
-+ *
-+ * Inform the userspace about the color change that has aborted.
-+ */
-+static inline int cfg80211_color_change_aborted_notify(struct net_device *dev)
-+{
-+      return cfg80211_bss_color_notify(dev, GFP_KERNEL,
-+                                       NL80211_CMD_COLOR_CHANGE_ABORTED,
-+                                       0, 0);
-+}
-+
-+/**
-+ * cfg80211_color_change_notify - notify color change completion
-+ * @dev: the device on which the color was switched
-+ *
-+ * Inform the userspace about the color change that has completed.
-+ */
-+static inline int cfg80211_color_change_notify(struct net_device *dev)
-+{
-+      return cfg80211_bss_color_notify(dev, GFP_KERNEL,
-+                                       NL80211_CMD_COLOR_CHANGE_COMPLETED,
-+                                       0, 0);
-+}
-+
- #endif /* __NET_CFG80211_H */
---- a/include/uapi/linux/nl80211.h
-+++ b/include/uapi/linux/nl80211.h
-@@ -1185,6 +1185,21 @@
-  *    passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to
-  *    specify the wiphy index to be applied to.
-  *
-+ * @NL80211_CMD_OBSS_COLOR_COLLISION: This notification is sent out whenever
-+ *    mac80211/drv detects a bss color collision.
-+ *
-+ * @NL80211_CMD_COLOR_CHANGE_REQUEST: This command is used to indicate that
-+ *    userspace wants to change the BSS color.
-+ *
-+ * @NL80211_CMD_COLOR_CHANGE_STARTED: Notify userland, that a color change has
-+ *    started
-+ *
-+ * @NL80211_CMD_COLOR_CHANGE_ABORTED: Notify userland, that the color change has
-+ *    been aborted
-+ *
-+ * @NL80211_CMD_COLOR_CHANGE_COMPLETED: Notify userland that the color change
-+ *    has completed
-+ *
-  * @NL80211_CMD_MAX: highest used command number
-  * @__NL80211_CMD_AFTER_LAST: internal use
-  */
-@@ -1417,6 +1432,14 @@ enum nl80211_commands {
-       NL80211_CMD_SET_SAR_SPECS,
-+      NL80211_CMD_OBSS_COLOR_COLLISION,
-+
-+      NL80211_CMD_COLOR_CHANGE_REQUEST,
-+
-+      NL80211_CMD_COLOR_CHANGE_STARTED,
-+      NL80211_CMD_COLOR_CHANGE_ABORTED,
-+      NL80211_CMD_COLOR_CHANGE_COMPLETED,
-+
-       /* add new commands above here */
-       /* used to define NL80211_CMD_MAX below */
-@@ -2560,6 +2583,16 @@ enum nl80211_commands {
-  *    disassoc events to indicate that an immediate reconnect to the AP
-  *    is desired.
-  *
-+ * @NL80211_ATTR_OBSS_COLOR_BITMAP: bitmap of the u64 BSS colors for the
-+ *    %NL80211_CMD_OBSS_COLOR_COLLISION event.
-+ *
-+ * @NL80211_ATTR_COLOR_CHANGE_COUNT: u8 attribute specifying the number of TBTT's
-+ *    until the color switch event.
-+ * @NL80211_ATTR_COLOR_CHANGE_COLOR: u8 attribute specifying the color that we are
-+ *    switching to
-+ * @NL80211_ATTR_COLOR_CHANGE_ELEMS: Nested set of attributes containing the IE
-+ *    information for the time while performing a color switch.
-+ *
-  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
-  * @NL80211_ATTR_MAX: highest attribute number currently defined
-  * @__NL80211_ATTR_AFTER_LAST: internal use
-@@ -3057,6 +3090,12 @@ enum nl80211_attrs {
-       NL80211_ATTR_DISABLE_HE,
-+      NL80211_ATTR_OBSS_COLOR_BITMAP,
-+
-+      NL80211_ATTR_COLOR_CHANGE_COUNT,
-+      NL80211_ATTR_COLOR_CHANGE_COLOR,
-+      NL80211_ATTR_COLOR_CHANGE_ELEMS,
-+
-       /* add attributes here, update the policy in nl80211.c */
-       __NL80211_ATTR_AFTER_LAST,
-@@ -5953,6 +5992,9 @@ enum nl80211_feature_flags {
-  *      frame protection for all management frames exchanged during the
-  *      negotiation and range measurement procedure.
-  *
-+ * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision
-+ *    detection and change announcemnts.
-+ *
-  * @NUM_NL80211_EXT_FEATURES: number of extended features.
-  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
-  */
-@@ -6017,6 +6059,7 @@ enum nl80211_ext_feature_index {
-       NL80211_EXT_FEATURE_SECURE_LTF,
-       NL80211_EXT_FEATURE_SECURE_RTT,
-       NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
-+      NL80211_EXT_FEATURE_BSS_COLOR,
-       /* add new features before the definition below */
-       NUM_NL80211_EXT_FEATURES,
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -776,6 +776,10 @@ static const struct nla_policy nl80211_p
-       [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
-       [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
-       [NL80211_ATTR_DISABLE_HE] = { .type = NLA_FLAG },
-+      [NL80211_ATTR_OBSS_COLOR_BITMAP] = { .type = NLA_U64 },
-+      [NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 },
-+      [NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 },
-+      [NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy),
- };
- /* policy for the key attributes */
-@@ -14823,6 +14827,106 @@ bad_tid_conf:
-       return ret;
- }
-+static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info)
-+{
-+      struct cfg80211_registered_device *rdev = info->user_ptr[0];
-+      struct cfg80211_color_change_settings params = {};
-+      struct net_device *dev = info->user_ptr[1];
-+      struct wireless_dev *wdev = dev->ieee80211_ptr;
-+      struct nlattr **tb;
-+      u16 offset;
-+      int err;
-+
-+      if (!rdev->ops->color_change)
-+              return -EOPNOTSUPP;
-+
-+      if (!wiphy_ext_feature_isset(&rdev->wiphy,
-+                                   NL80211_EXT_FEATURE_BSS_COLOR))
-+              return -EOPNOTSUPP;
-+
-+      if (wdev->iftype != NL80211_IFTYPE_AP)
-+              return -EOPNOTSUPP;
-+
-+      if (!info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT] ||
-+          !info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR] ||
-+          !info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS])
-+              return -EINVAL;
-+
-+      params.count = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT]);
-+      params.color = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR]);
-+
-+      err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_next);
-+      if (err)
-+              return err;
-+
-+      tb = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*tb), GFP_KERNEL);
-+      if (!tb)
-+              return -ENOMEM;
-+
-+      err = nla_parse_nested(tb, NL80211_ATTR_MAX,
-+                             info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS],
-+                             nl80211_policy, info->extack);
-+      if (err)
-+              goto out;
-+
-+      err = nl80211_parse_beacon(rdev, tb, &params.beacon_color_change);
-+      if (err)
-+              goto out;
-+
-+      if (!tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) {
-+              err = -EINVAL;
-+              goto out;
-+      }
-+
-+      if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) != sizeof(u16)) {
-+              err = -EINVAL;
-+              goto out;
-+      }
-+
-+      offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
-+      if (offset >= params.beacon_color_change.tail_len) {
-+              err = -EINVAL;
-+              goto out;
-+      }
-+
-+      if (params.beacon_color_change.tail[offset] != params.count) {
-+              err = -EINVAL;
-+              goto out;
-+      }
-+
-+      params.counter_offset_beacon = offset;
-+
-+      if (tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) {
-+              if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) !=
-+                  sizeof(u16)) {
-+                      err = -EINVAL;
-+                      goto out;
-+              }
-+
-+              offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
-+              if (offset >= params.beacon_color_change.probe_resp_len) {
-+                      err = -EINVAL;
-+                      goto out;
-+              }
-+
-+              if (params.beacon_color_change.probe_resp[offset] !=
-+                  params.count) {
-+                      err = -EINVAL;
-+                      goto out;
-+              }
-+
-+              params.counter_offset_presp = offset;
-+      }
-+
-+      wdev_lock(wdev);
-+      err = rdev_color_change(rdev, dev, &params);
-+      wdev_unlock(wdev);
-+
-+out:
-+      kfree(tb);
-+      return err;
-+}
-+
- #define NL80211_FLAG_NEED_WIPHY               0x01
- #define NL80211_FLAG_NEED_NETDEV      0x02
- #define NL80211_FLAG_NEED_RTNL                0x04
-@@ -15823,6 +15927,14 @@ static const struct genl_small_ops nl802
-               .internal_flags = NL80211_FLAG_NEED_WIPHY |
-                                 NL80211_FLAG_NEED_RTNL,
-       },
-+      {
-+              .cmd = NL80211_CMD_COLOR_CHANGE_REQUEST,
-+              .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
-+              .doit = nl80211_color_change,
-+              .flags = GENL_UNS_ADMIN_PERM,
-+              .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
-+                                NL80211_FLAG_NEED_RTNL,
-+      },
- };
- static struct genl_family nl80211_fam __genl_ro_after_init = {
-@@ -17454,6 +17566,51 @@ void cfg80211_ch_switch_started_notify(s
- }
- EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
-+int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp,
-+                            enum nl80211_commands cmd, u8 count,
-+                            u64 color_bitmap)
-+{
-+      struct wireless_dev *wdev = dev->ieee80211_ptr;
-+      struct wiphy *wiphy = wdev->wiphy;
-+      struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
-+      struct sk_buff *msg;
-+      void *hdr;
-+
-+      ASSERT_WDEV_LOCK(wdev);
-+
-+      trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap);
-+
-+      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
-+      if (!msg)
-+              return -ENOMEM;
-+
-+      hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
-+      if (!hdr)
-+              goto nla_put_failure;
-+
-+      if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
-+              goto nla_put_failure;
-+
-+      if (cmd == NL80211_CMD_COLOR_CHANGE_STARTED &&
-+          nla_put_u32(msg, NL80211_ATTR_COLOR_CHANGE_COUNT, count))
-+              goto nla_put_failure;
-+
-+      if (cmd == NL80211_CMD_OBSS_COLOR_COLLISION &&
-+          nla_put_u64_64bit(msg, NL80211_ATTR_OBSS_COLOR_BITMAP,
-+                            color_bitmap, NL80211_ATTR_PAD))
-+              goto nla_put_failure;
-+
-+      genlmsg_end(msg, hdr);
-+
-+      return genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
-+                                     msg, 0, NL80211_MCGRP_MLME, gfp);
-+
-+nla_put_failure:
-+      nlmsg_free(msg);
-+      return -EINVAL;
-+}
-+EXPORT_SYMBOL(cfg80211_bss_color_notify);
-+
- void
- nl80211_radar_notify(struct cfg80211_registered_device *rdev,
-                    const struct cfg80211_chan_def *chandef,
---- a/net/wireless/rdev-ops.h
-+++ b/net/wireless/rdev-ops.h
-@@ -1368,4 +1368,17 @@ static inline int rdev_set_sar_specs(str
-       return ret;
- }
-+static inline int rdev_color_change(struct cfg80211_registered_device *rdev,
-+                                  struct net_device *dev,
-+                                  struct cfg80211_color_change_settings *params)
-+{
-+      int ret;
-+
-+      trace_rdev_color_change(&rdev->wiphy, dev, params);
-+      ret = rdev->ops->color_change(&rdev->wiphy, dev, params);
-+      trace_rdev_return_int(&rdev->wiphy, ret);
-+
-+      return ret;
-+}
-+
- #endif /* __CFG80211_RDEV_OPS */
---- a/net/wireless/trace.h
-+++ b/net/wireless/trace.h
-@@ -3597,6 +3597,52 @@ TRACE_EVENT(rdev_set_sar_specs,
-                 WIPHY_PR_ARG, __entry->type, __entry->num)
- );
-+TRACE_EVENT(rdev_color_change,
-+      TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
-+               struct cfg80211_color_change_settings *params),
-+      TP_ARGS(wiphy, netdev, params),
-+      TP_STRUCT__entry(
-+              WIPHY_ENTRY
-+              NETDEV_ENTRY
-+              __field(u8, count)
-+              __field(u16, bcn_ofs)
-+              __field(u16, pres_ofs)
-+      ),
-+      TP_fast_assign(
-+              WIPHY_ASSIGN;
-+              NETDEV_ASSIGN;
-+              __entry->count = params->count;
-+              __entry->bcn_ofs = params->counter_offset_beacon;
-+              __entry->pres_ofs = params->counter_offset_presp;
-+      ),
-+      TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT
-+                ", count: %u",
-+                WIPHY_PR_ARG, NETDEV_PR_ARG,
-+                __entry->count)
-+);
-+
-+TRACE_EVENT(cfg80211_bss_color_notify,
-+      TP_PROTO(struct net_device *netdev,
-+               enum nl80211_commands cmd,
-+               u8 count, u64 color_bitmap),
-+      TP_ARGS(netdev, cmd, count, color_bitmap),
-+      TP_STRUCT__entry(
-+              NETDEV_ENTRY
-+              __field(enum nl80211_bss_scan_width, cmd)
-+              __field(u8, count)
-+              __field(u64, color_bitmap)
-+      ),
-+      TP_fast_assign(
-+              NETDEV_ASSIGN;
-+              __entry->cmd = cmd;
-+              __entry->count = count;
-+              __entry->color_bitmap = color_bitmap;
-+      ),
-+      TP_printk(NETDEV_PR_FMT ", cmd: %x, count: %u, bitmap: %llx",
-+                NETDEV_PR_ARG, __entry->cmd, __entry->count,
-+                __entry->color_bitmap)
-+);
-+
- #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
- #undef TRACE_INCLUDE_PATH
diff --git a/package/kernel/mac80211/patches/subsys/388-mac80211-add-support-for-BSS-color-change.patch b/package/kernel/mac80211/patches/subsys/388-mac80211-add-support-for-BSS-color-change.patch
deleted file mode 100644 (file)
index 196c8e1..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-From: John Crispin <john@phrozen.org>
-Date: Fri, 2 Jul 2021 19:44:08 +0200
-Subject: [PATCH] mac80211: add support for BSS color change
-
-The color change announcement is very similar to how CSA works where
-we have an IE that includes a counter. When the counter hits 0, the new
-color is applied via an updated beacon.
-
-This patch makes the CSA counter functionality reusable, rather than
-implementing it again. This also allows for future reuse incase support
-for other counter IEs gets added.
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: John Crispin <john@phrozen.org>
-Link: https://lore.kernel.org/r/057c1e67b82bee561ea44ce6a45a8462d3da6995.1625247619.git.lorenzo@kernel.org
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -1715,6 +1715,10 @@ enum ieee80211_offload_flags {
-  *    protected by fq->lock.
-  * @offload_flags: 802.3 -> 802.11 enapsulation offload flags, see
-  *    &enum ieee80211_offload_flags.
-+ * @color_change_active: marks whether a color change is ongoing. Internally it is
-+ *    write-protected by sdata_lock and local->mtx so holding either is fine
-+ *    for read access.
-+ * @color_change_color: the bss color that will be used after the change.
-  */
- struct ieee80211_vif {
-       enum nl80211_iftype type;
-@@ -1743,6 +1747,9 @@ struct ieee80211_vif {
-       bool txqs_stopped[IEEE80211_NUM_ACS];
-+      bool color_change_active;
-+      u8 color_change_color;
-+
-       /* must be last */
-       u8 drv_priv[] __aligned(sizeof(void *));
- };
-@@ -5016,6 +5023,16 @@ void ieee80211_csa_finish(struct ieee802
- bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif);
- /**
-+ * ieee80211_color_change_finish - notify mac80211 about color change
-+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
-+ *
-+ * After a color change announcement was scheduled and the counter in this
-+ * announcement hits 1, this function must be called by the driver to
-+ * notify mac80211 that the color can be changed
-+ */
-+void ieee80211_color_change_finish(struct ieee80211_vif *vif);
-+
-+/**
-  * ieee80211_proberesp_get - retrieve a Probe Response template
-  * @hw: pointer obtained from ieee80211_alloc_hw().
-  * @vif: &struct ieee80211_vif pointer from the add_interface callback.
-@@ -6780,6 +6797,18 @@ ieee80211_get_unsol_bcast_probe_resp_tmp
-                                         struct ieee80211_vif *vif);
- /**
-+ * ieeee80211_obss_color_collision_notify - notify userland about a BSS color
-+ * collision.
-+ *
-+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
-+ * @color_bitmap: a 64 bit bitmap representing the colors that the local BSS is
-+ *    aware of.
-+ */
-+void
-+ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
-+                                     u64 color_bitmap);
-+
-+/**
-  * ieee80211_is_tx_data - check if frame is a data frame
-  *
-  * The function is used to check if a frame is a data frame. Frames with
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -828,9 +828,11 @@ static int ieee80211_set_monitor_channel
-       return ret;
- }
--static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
--                                  const u8 *resp, size_t resp_len,
--                                  const struct ieee80211_csa_settings *csa)
-+static int
-+ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
-+                       const u8 *resp, size_t resp_len,
-+                       const struct ieee80211_csa_settings *csa,
-+                       const struct ieee80211_color_change_settings *cca)
- {
-       struct probe_resp *new, *old;
-@@ -850,6 +852,8 @@ static int ieee80211_set_probe_resp(stru
-               memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_presp,
-                      csa->n_counter_offsets_presp *
-                      sizeof(new->cntdwn_counter_offsets[0]));
-+      else if (cca)
-+              new->cntdwn_counter_offsets[0] = cca->counter_offset_presp;
-       rcu_assign_pointer(sdata->u.ap.probe_resp, new);
-       if (old)
-@@ -955,7 +959,8 @@ static int ieee80211_set_ftm_responder_p
- static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
-                                  struct cfg80211_beacon_data *params,
--                                 const struct ieee80211_csa_settings *csa)
-+                                 const struct ieee80211_csa_settings *csa,
-+                                 const struct ieee80211_color_change_settings *cca)
- {
-       struct beacon_data *new, *old;
-       int new_head_len, new_tail_len;
-@@ -1004,6 +1009,9 @@ static int ieee80211_assign_beacon(struc
-               memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_beacon,
-                      csa->n_counter_offsets_beacon *
-                      sizeof(new->cntdwn_counter_offsets[0]));
-+      } else if (cca) {
-+              new->cntdwn_current_counter = cca->count;
-+              new->cntdwn_counter_offsets[0] = cca->counter_offset_beacon;
-       }
-       /* copy in head */
-@@ -1020,7 +1028,7 @@ static int ieee80211_assign_beacon(struc
-                       memcpy(new->tail, old->tail, new_tail_len);
-       err = ieee80211_set_probe_resp(sdata, params->probe_resp,
--                                     params->probe_resp_len, csa);
-+                                     params->probe_resp_len, csa, cca);
-       if (err < 0) {
-               kfree(new);
-               return err;
-@@ -1175,7 +1183,7 @@ static int ieee80211_start_ap(struct wip
-       if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL))
-               sdata->vif.bss_conf.beacon_tx_rate = params->beacon_rate;
--      err = ieee80211_assign_beacon(sdata, &params->beacon, NULL);
-+      err = ieee80211_assign_beacon(sdata, &params->beacon, NULL, NULL);
-       if (err < 0)
-               goto error;
-       changed |= err;
-@@ -1230,17 +1238,17 @@ static int ieee80211_change_beacon(struc
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       sdata_assert_lock(sdata);
--      /* don't allow changing the beacon while CSA is in place - offset
-+      /* don't allow changing the beacon while a countdown is in place - offset
-        * of channel switch counter may change
-        */
--      if (sdata->vif.csa_active)
-+      if (sdata->vif.csa_active || sdata->vif.color_change_active)
-               return -EBUSY;
-       old = sdata_dereference(sdata->u.ap.beacon, sdata);
-       if (!old)
-               return -ENOENT;
--      err = ieee80211_assign_beacon(sdata, params, NULL);
-+      err = ieee80211_assign_beacon(sdata, params, NULL, NULL);
-       if (err < 0)
-               return err;
-       ieee80211_bss_info_change_notify(sdata, err);
-@@ -3155,7 +3163,7 @@ static int ieee80211_set_after_csa_beaco
-       switch (sdata->vif.type) {
-       case NL80211_IFTYPE_AP:
-               err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
--                                            NULL);
-+                                            NULL, NULL);
-               kfree(sdata->u.ap.next_beacon);
-               sdata->u.ap.next_beacon = NULL;
-@@ -3321,7 +3329,7 @@ static int ieee80211_set_csa_beacon(stru
-               csa.n_counter_offsets_presp = params->n_counter_offsets_presp;
-               csa.count = params->count;
--              err = ieee80211_assign_beacon(sdata, &params->beacon_csa, &csa);
-+              err = ieee80211_assign_beacon(sdata, &params->beacon_csa, &csa, NULL);
-               if (err < 0) {
-                       kfree(sdata->u.ap.next_beacon);
-                       return err;
-@@ -3410,6 +3418,15 @@ static int ieee80211_set_csa_beacon(stru
-       return 0;
- }
-+static void ieee80211_color_change_abort(struct ieee80211_sub_if_data  *sdata)
-+{
-+      sdata->vif.color_change_active = false;
-+      kfree(sdata->u.ap.next_beacon);
-+      sdata->u.ap.next_beacon = NULL;
-+
-+      cfg80211_color_change_aborted_notify(sdata->dev);
-+}
-+
- static int
- __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
-                          struct cfg80211_csa_settings *params)
-@@ -3478,6 +3495,10 @@ __ieee80211_channel_switch(struct wiphy
-               goto out;
-       }
-+      /* if there is a color change in progress, abort it */
-+      if (sdata->vif.color_change_active)
-+              ieee80211_color_change_abort(sdata);
-+
-       err = ieee80211_set_csa_beacon(sdata, params, &changed);
-       if (err) {
-               ieee80211_vif_unreserve_chanctx(sdata);
-@@ -4129,6 +4150,196 @@ static int ieee80211_set_sar_specs(struc
-       return local->ops->set_sar_specs(&local->hw, sar);
- }
-+static int
-+ieee80211_set_after_color_change_beacon(struct ieee80211_sub_if_data *sdata,
-+                                      u32 *changed)
-+{
-+      switch (sdata->vif.type) {
-+      case NL80211_IFTYPE_AP: {
-+              int ret;
-+
-+              ret = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
-+                                            NULL, NULL);
-+              kfree(sdata->u.ap.next_beacon);
-+              sdata->u.ap.next_beacon = NULL;
-+
-+              if (ret < 0)
-+                      return ret;
-+
-+              *changed |= ret;
-+              break;
-+      }
-+      default:
-+              WARN_ON_ONCE(1);
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static int
-+ieee80211_set_color_change_beacon(struct ieee80211_sub_if_data *sdata,
-+                                struct cfg80211_color_change_settings *params,
-+                                u32 *changed)
-+{
-+      struct ieee80211_color_change_settings color_change = {};
-+      int err;
-+
-+      switch (sdata->vif.type) {
-+      case NL80211_IFTYPE_AP:
-+              sdata->u.ap.next_beacon =
-+                      cfg80211_beacon_dup(&params->beacon_next);
-+              if (!sdata->u.ap.next_beacon)
-+                      return -ENOMEM;
-+
-+              if (params->count <= 1)
-+                      break;
-+
-+              color_change.counter_offset_beacon =
-+                      params->counter_offset_beacon;
-+              color_change.counter_offset_presp =
-+                      params->counter_offset_presp;
-+              color_change.count = params->count;
-+
-+              err = ieee80211_assign_beacon(sdata, &params->beacon_color_change,
-+                                            NULL, &color_change);
-+              if (err < 0) {
-+                      kfree(sdata->u.ap.next_beacon);
-+                      return err;
-+              }
-+              *changed |= err;
-+              break;
-+      default:
-+              return -EOPNOTSUPP;
-+      }
-+
-+      return 0;
-+}
-+
-+static void
-+ieee80211_color_change_bss_config_notify(struct ieee80211_sub_if_data *sdata,
-+                                       u8 color, int enable, u32 changed)
-+{
-+      sdata->vif.bss_conf.he_bss_color.color = color;
-+      sdata->vif.bss_conf.he_bss_color.enabled = enable;
-+      changed |= BSS_CHANGED_HE_BSS_COLOR;
-+
-+      ieee80211_bss_info_change_notify(sdata, changed);
-+}
-+
-+static int ieee80211_color_change_finalize(struct ieee80211_sub_if_data *sdata)
-+{
-+      struct ieee80211_local *local = sdata->local;
-+      u32 changed = 0;
-+      int err;
-+
-+      sdata_assert_lock(sdata);
-+      lockdep_assert_held(&local->mtx);
-+
-+      sdata->vif.color_change_active = false;
-+
-+      err = ieee80211_set_after_color_change_beacon(sdata, &changed);
-+      if (err) {
-+              cfg80211_color_change_aborted_notify(sdata->dev);
-+              return err;
-+      }
-+
-+      ieee80211_color_change_bss_config_notify(sdata,
-+                                               sdata->vif.color_change_color,
-+                                               1, changed);
-+      cfg80211_color_change_notify(sdata->dev);
-+
-+      return 0;
-+}
-+
-+void ieee80211_color_change_finalize_work(struct work_struct *work)
-+{
-+      struct ieee80211_sub_if_data *sdata =
-+              container_of(work, struct ieee80211_sub_if_data,
-+                           color_change_finalize_work);
-+      struct ieee80211_local *local = sdata->local;
-+
-+      sdata_lock(sdata);
-+      mutex_lock(&local->mtx);
-+
-+      /* AP might have been stopped while waiting for the lock. */
-+      if (!sdata->vif.color_change_active)
-+              goto unlock;
-+
-+      if (!ieee80211_sdata_running(sdata))
-+              goto unlock;
-+
-+      ieee80211_color_change_finalize(sdata);
-+
-+unlock:
-+      mutex_unlock(&local->mtx);
-+      sdata_unlock(sdata);
-+}
-+
-+void ieee80211_color_change_finish(struct ieee80211_vif *vif)
-+{
-+      struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
-+
-+      ieee80211_queue_work(&sdata->local->hw,
-+                           &sdata->color_change_finalize_work);
-+}
-+EXPORT_SYMBOL_GPL(ieee80211_color_change_finish);
-+
-+void
-+ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
-+                                     u64 color_bitmap)
-+{
-+      struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
-+
-+      if (sdata->vif.color_change_active || sdata->vif.csa_active)
-+              return;
-+
-+      cfg80211_obss_color_collision_notify(sdata->dev, color_bitmap);
-+}
-+EXPORT_SYMBOL_GPL(ieeee80211_obss_color_collision_notify);
-+
-+static int
-+ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev,
-+                     struct cfg80211_color_change_settings *params)
-+{
-+      struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+      struct ieee80211_local *local = sdata->local;
-+      u32 changed = 0;
-+      int err;
-+
-+      sdata_assert_lock(sdata);
-+
-+      mutex_lock(&local->mtx);
-+
-+      /* don't allow another color change if one is already active or if csa
-+       * is active
-+       */
-+      if (sdata->vif.color_change_active || sdata->vif.csa_active) {
-+              err = -EBUSY;
-+              goto out;
-+      }
-+
-+      err = ieee80211_set_color_change_beacon(sdata, params, &changed);
-+      if (err)
-+              goto out;
-+
-+      sdata->vif.color_change_active = true;
-+      sdata->vif.color_change_color = params->color;
-+
-+      cfg80211_color_change_started_notify(sdata->dev, params->count);
-+
-+      if (changed)
-+              ieee80211_color_change_bss_config_notify(sdata, 0, 0, changed);
-+      else
-+              /* if the beacon didn't change, we can finalize immediately */
-+              ieee80211_color_change_finalize(sdata);
-+
-+out:
-+      mutex_unlock(&local->mtx);
-+
-+      return err;
-+}
-+
- const struct cfg80211_ops mac80211_config_ops = {
-       .add_virtual_intf = ieee80211_add_iface,
-       .del_virtual_intf = ieee80211_del_iface,
-@@ -4232,4 +4443,5 @@ const struct cfg80211_ops mac80211_confi
-       .set_tid_config = ieee80211_set_tid_config,
-       .reset_tid_config = ieee80211_reset_tid_config,
-       .set_sar_specs = ieee80211_set_sar_specs,
-+      .color_change = ieee80211_color_change,
- };
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -248,6 +248,12 @@ struct ieee80211_csa_settings {
-       u8 count;
- };
-+struct ieee80211_color_change_settings {
-+      u16 counter_offset_beacon;
-+      u16 counter_offset_presp;
-+      u8 count;
-+};
-+
- struct beacon_data {
-       u8 *head, *tail;
-       int head_len, tail_len;
-@@ -927,6 +933,8 @@ struct ieee80211_sub_if_data {
-       bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */
-       struct cfg80211_chan_def csa_chandef;
-+      struct work_struct color_change_finalize_work;
-+
-       struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */
-       struct list_head reserved_chanctx_list; /* protected by chanctx_mtx */
-@@ -1891,6 +1899,9 @@ void ieee80211_csa_finalize_work(struct
- int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
-                            struct cfg80211_csa_settings *params);
-+/* color change handling */
-+void ieee80211_color_change_finalize_work(struct work_struct *work);
-+
- /* interface handling */
- #define MAC80211_SUPPORTED_FEATURES_TX        (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
-                                        NETIF_F_HW_CSUM | NETIF_F_SG | \
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -462,6 +462,7 @@ static void ieee80211_do_stop(struct iee
-       sdata_unlock(sdata);
-       cancel_work_sync(&sdata->csa_finalize_work);
-+      cancel_work_sync(&sdata->color_change_finalize_work);
-       cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
-@@ -1608,6 +1609,7 @@ static void ieee80211_setup_sdata(struct
-       INIT_WORK(&sdata->work, ieee80211_iface_work);
-       INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
-       INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
-+      INIT_WORK(&sdata->color_change_finalize_work, ieee80211_color_change_finalize_work);
-       INIT_LIST_HEAD(&sdata->assigned_chanctx_list);
-       INIT_LIST_HEAD(&sdata->reserved_chanctx_list);
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -4796,11 +4796,11 @@ static int ieee80211_beacon_add_tim(stru
- static void ieee80211_set_beacon_cntdwn(struct ieee80211_sub_if_data *sdata,
-                                       struct beacon_data *beacon)
- {
-+      u8 *beacon_data, count, max_count = 1;
-       struct probe_resp *resp;
--      u8 *beacon_data;
-       size_t beacon_data_len;
-+      u16 *bcn_offsets;
-       int i;
--      u8 count = beacon->cntdwn_current_counter;
-       switch (sdata->vif.type) {
-       case NL80211_IFTYPE_AP:
-@@ -4820,21 +4820,27 @@ static void ieee80211_set_beacon_cntdwn(
-       }
-       rcu_read_lock();
--      for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; ++i) {
--              resp = rcu_dereference(sdata->u.ap.probe_resp);
-+      resp = rcu_dereference(sdata->u.ap.probe_resp);
--              if (beacon->cntdwn_counter_offsets[i]) {
--                      if (WARN_ON_ONCE(beacon->cntdwn_counter_offsets[i] >=
--                                       beacon_data_len)) {
-+      bcn_offsets = beacon->cntdwn_counter_offsets;
-+      count = beacon->cntdwn_current_counter;
-+      if (sdata->vif.csa_active)
-+              max_count = IEEE80211_MAX_CNTDWN_COUNTERS_NUM;
-+
-+      for (i = 0; i < max_count; ++i) {
-+              if (bcn_offsets[i]) {
-+                      if (WARN_ON_ONCE(bcn_offsets[i] >= beacon_data_len)) {
-                               rcu_read_unlock();
-                               return;
-                       }
--
--                      beacon_data[beacon->cntdwn_counter_offsets[i]] = count;
-+                      beacon_data[bcn_offsets[i]] = count;
-               }
--              if (sdata->vif.type == NL80211_IFTYPE_AP && resp)
--                      resp->data[resp->cntdwn_counter_offsets[i]] = count;
-+              if (sdata->vif.type == NL80211_IFTYPE_AP && resp) {
-+                      u16 *resp_offsets = resp->cntdwn_counter_offsets;
-+
-+                      resp->data[resp_offsets[i]] = count;
-+              }
-       }
-       rcu_read_unlock();
- }
-@@ -5044,6 +5050,7 @@ __ieee80211_beacon_get(struct ieee80211_
-                       if (offs) {
-                               offs->tim_offset = beacon->head_len;
-                               offs->tim_length = skb->len - beacon->head_len;
-+                              offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
-                               /* for AP the csa offsets are from tail */
-                               csa_off_base = skb->len;
diff --git a/package/kernel/mac80211/patches/subsys/389-ieee80211-add-TWT-element-definitions.patch b/package/kernel/mac80211/patches/subsys/389-ieee80211-add-TWT-element-definitions.patch
deleted file mode 100644 (file)
index 6bb7dd7..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 23 Aug 2021 20:02:38 +0200
-Subject: [PATCH] ieee80211: add TWT element definitions
-
-Introduce TWT definitions and TWT Information element structure
-in ieee80211.h
-
-Tested-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/71d8b581fe4b5abc5b92f8d77ac2de3e2f7591b6.1629741512.git.lorenzo@kernel.org
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/linux/ieee80211.h
-+++ b/include/linux/ieee80211.h
-@@ -1088,6 +1088,48 @@ struct ieee80211_ext {
-       } u;
- } __packed __aligned(2);
-+#define IEEE80211_TWT_CONTROL_NDP                     BIT(0)
-+#define IEEE80211_TWT_CONTROL_RESP_MODE                       BIT(1)
-+#define IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST      BIT(3)
-+#define IEEE80211_TWT_CONTROL_RX_DISABLED             BIT(4)
-+#define IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT           BIT(5)
-+
-+#define IEEE80211_TWT_REQTYPE_REQUEST                 BIT(0)
-+#define IEEE80211_TWT_REQTYPE_SETUP_CMD                       GENMASK(3, 1)
-+#define IEEE80211_TWT_REQTYPE_TRIGGER                 BIT(4)
-+#define IEEE80211_TWT_REQTYPE_IMPLICIT                        BIT(5)
-+#define IEEE80211_TWT_REQTYPE_FLOWTYPE                        BIT(6)
-+#define IEEE80211_TWT_REQTYPE_FLOWID                  GENMASK(9, 7)
-+#define IEEE80211_TWT_REQTYPE_WAKE_INT_EXP            GENMASK(14, 10)
-+#define IEEE80211_TWT_REQTYPE_PROTECTION              BIT(15)
-+
-+enum ieee80211_twt_setup_cmd {
-+      TWT_SETUP_CMD_REQUEST,
-+      TWT_SETUP_CMD_SUGGEST,
-+      TWT_SETUP_CMD_DEMAND,
-+      TWT_SETUP_CMD_GROUPING,
-+      TWT_SETUP_CMD_ACCEPT,
-+      TWT_SETUP_CMD_ALTERNATE,
-+      TWT_SETUP_CMD_DICTATE,
-+      TWT_SETUP_CMD_REJECT,
-+};
-+
-+struct ieee80211_twt_params {
-+      __le16 req_type;
-+      __le64 twt;
-+      u8 min_twt_dur;
-+      __le16 mantissa;
-+      u8 channel;
-+} __packed;
-+
-+struct ieee80211_twt_setup {
-+      u8 dialog_token;
-+      u8 element_id;
-+      u8 length;
-+      u8 control;
-+      u8 params[];
-+} __packed;
-+
- struct ieee80211_mgmt {
-       __le16 frame_control;
-       __le16 duration;
-@@ -1252,6 +1294,10 @@ struct ieee80211_mgmt {
-                                       __le16 toa_error;
-                                       u8 variable[0];
-                               } __packed ftm;
-+                              struct {
-+                                      u8 action_code;
-+                                      u8 variable[];
-+                              } __packed s1g;
-                       } u;
-               } __packed action;
-       } u;
-@@ -2881,6 +2927,7 @@ enum ieee80211_eid {
-       WLAN_EID_AID_RESPONSE = 211,
-       WLAN_EID_S1G_BCN_COMPAT = 213,
-       WLAN_EID_S1G_SHORT_BCN_INTERVAL = 214,
-+      WLAN_EID_S1G_TWT = 216,
-       WLAN_EID_S1G_CAPABILITIES = 217,
-       WLAN_EID_VENDOR_SPECIFIC = 221,
-       WLAN_EID_QOS_PARAMETER = 222,
-@@ -2950,6 +2997,7 @@ enum ieee80211_category {
-       WLAN_CATEGORY_FST = 18,
-       WLAN_CATEGORY_UNPROT_DMG = 20,
-       WLAN_CATEGORY_VHT = 21,
-+      WLAN_CATEGORY_S1G = 22,
-       WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
-       WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
- };
-@@ -3023,6 +3071,20 @@ enum ieee80211_key_len {
-       WLAN_KEY_LEN_BIP_GMAC_256 = 32,
- };
-+enum ieee80211_s1g_actioncode {
-+      WLAN_S1G_AID_SWITCH_REQUEST,
-+      WLAN_S1G_AID_SWITCH_RESPONSE,
-+      WLAN_S1G_SYNC_CONTROL,
-+      WLAN_S1G_STA_INFO_ANNOUNCE,
-+      WLAN_S1G_EDCA_PARAM_SET,
-+      WLAN_S1G_EL_OPERATION,
-+      WLAN_S1G_TWT_SETUP,
-+      WLAN_S1G_TWT_TEARDOWN,
-+      WLAN_S1G_SECT_GROUP_ID_LIST,
-+      WLAN_S1G_SECT_ID_FEEDBACK,
-+      WLAN_S1G_TWT_INFORMATION = 11,
-+};
-+
- #define IEEE80211_WEP_IV_LEN          4
- #define IEEE80211_WEP_ICV_LEN         4
- #define IEEE80211_CCMP_HDR_LEN                8
diff --git a/package/kernel/mac80211/patches/subsys/390-mac80211-introduce-individual-TWT-support-in-AP-mode.patch b/package/kernel/mac80211/patches/subsys/390-mac80211-introduce-individual-TWT-support-in-AP-mode.patch
deleted file mode 100644 (file)
index f0f864c..0000000
+++ /dev/null
@@ -1,604 +0,0 @@
-From f5a4c24e689f54e66201f04d343bdd2e8a1d7923 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 23 Aug 2021 20:02:39 +0200
-Subject: [PATCH] mac80211: introduce individual TWT support in AP mode
-
-Introduce TWT action frames parsing support to mac80211.
-Currently just individual TWT agreement are support in AP mode.
-Whenever the AP receives a TWT action frame from an associated client,
-after performing sanity checks, it will notify the underlay driver with
-requested parameters in order to check if they are supported and if there
-is enough room for a new agreement. The driver is expected to set the
-agreement result and report it to mac80211.
-
-Drivers supporting this have two new callbacks:
- - add_twt_setup (mandatory)
- - twt_teardown_request (optional)
-
-mac80211 will send an action frame reply according to the result
-reported by the driver.
-
-Tested-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://lore.kernel.org/r/257512f2e22ba42b9f2624942a128dd8f141de4b.1629741512.git.lorenzo@kernel.org
-[use le16p_replace_bits(), minor cleanups, use (void *) casts,
- fix to use ieee80211_get_he_iftype_cap() correctly]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/net/mac80211.h     |  12 +++
- net/mac80211/driver-ops.h  |  36 ++++++++
- net/mac80211/ieee80211_i.h |   6 ++
- net/mac80211/iface.c       |  41 +++++++++
- net/mac80211/rx.c          |  73 +++++++++++++++
- net/mac80211/s1g.c         | 180 +++++++++++++++++++++++++++++++++++++
- net/mac80211/status.c      |  17 +++-
- net/mac80211/trace.h       |  67 ++++++++++++++
- 8 files changed, 430 insertions(+), 2 deletions(-)
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -3930,6 +3930,13 @@ struct ieee80211_prep_tx_info {
-  * @set_sar_specs: Update the SAR (TX power) settings.
-  * @sta_set_decap_offload: Called to notify the driver when a station is allowed
-  *    to use rx decapsulation offload
-+ * @add_twt_setup: Update hw with TWT agreement parameters received from the peer.
-+ *    This callback allows the hw to check if requested parameters
-+ *    are supported and if there is enough room for a new agreement.
-+ *    The hw is expected to set agreement result in the req_type field of
-+ *    twt structure.
-+ * @twt_teardown_request: Update the hw with TWT teardown request received
-+ *    from the peer.
-  */
- struct ieee80211_ops {
-       void (*tx)(struct ieee80211_hw *hw,
-@@ -4253,6 +4260,11 @@ struct ieee80211_ops {
-       void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
-                                     struct ieee80211_vif *vif,
-                                     struct ieee80211_sta *sta, bool enabled);
-+      void (*add_twt_setup)(struct ieee80211_hw *hw,
-+                            struct ieee80211_sta *sta,
-+                            struct ieee80211_twt_setup *twt);
-+      void (*twt_teardown_request)(struct ieee80211_hw *hw,
-+                                   struct ieee80211_sta *sta, u8 flowid);
- };
- /**
---- a/net/mac80211/driver-ops.h
-+++ b/net/mac80211/driver-ops.h
-@@ -1447,4 +1447,40 @@ static inline void drv_sta_set_decap_off
-       trace_drv_return_void(local);
- }
-+static inline void drv_add_twt_setup(struct ieee80211_local *local,
-+                                   struct ieee80211_sub_if_data *sdata,
-+                                   struct ieee80211_sta *sta,
-+                                   struct ieee80211_twt_setup *twt)
-+{
-+      struct ieee80211_twt_params *twt_agrt;
-+
-+      might_sleep();
-+
-+      if (!check_sdata_in_driver(sdata))
-+              return;
-+
-+      twt_agrt = (void *)twt->params;
-+
-+      trace_drv_add_twt_setup(local, sta, twt, twt_agrt);
-+      local->ops->add_twt_setup(&local->hw, sta, twt);
-+      trace_drv_return_void(local);
-+}
-+
-+static inline void drv_twt_teardown_request(struct ieee80211_local *local,
-+                                          struct ieee80211_sub_if_data *sdata,
-+                                          struct ieee80211_sta *sta,
-+                                          u8 flowid)
-+{
-+      might_sleep();
-+      if (!check_sdata_in_driver(sdata))
-+              return;
-+
-+      if (!local->ops->twt_teardown_request)
-+              return;
-+
-+      trace_drv_twt_teardown_request(local, sta, flowid);
-+      local->ops->twt_teardown_request(&local->hw, sta, flowid);
-+      trace_drv_return_void(local);
-+}
-+
- #endif /* __MAC80211_DRIVER_OPS */
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -949,6 +949,7 @@ struct ieee80211_sub_if_data {
-       struct work_struct work;
-       struct sk_buff_head skb_queue;
-+      struct sk_buff_head status_queue;
-       u8 needed_rx_chains;
-       enum ieee80211_smps_mode smps_mode;
-@@ -2083,6 +2084,11 @@ ieee80211_he_op_ie_to_bss_conf(struct ie
- /* S1G */
- void ieee80211_s1g_sta_rate_init(struct sta_info *sta);
-+bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb);
-+void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
-+                               struct sk_buff *skb);
-+void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
-+                                   struct sk_buff *skb);
- /* Spectrum management */
- void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -552,6 +552,7 @@ static void ieee80211_do_stop(struct iee
-                */
-               ieee80211_free_keys(sdata, true);
-               skb_queue_purge(&sdata->skb_queue);
-+              skb_queue_purge(&sdata->status_queue);
-       }
-       spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
-@@ -1055,6 +1056,7 @@ int ieee80211_add_virtual_monitor(struct
-       }
-       skb_queue_head_init(&sdata->skb_queue);
-+      skb_queue_head_init(&sdata->status_queue);
-       INIT_WORK(&sdata->work, ieee80211_iface_work);
-       return 0;
-@@ -1459,6 +1461,16 @@ static void ieee80211_iface_process_skb(
-                       WARN_ON(1);
-                       break;
-               }
-+      } else if (ieee80211_is_action(mgmt->frame_control) &&
-+                 mgmt->u.action.category == WLAN_CATEGORY_S1G) {
-+              switch (mgmt->u.action.u.s1g.action_code) {
-+              case WLAN_S1G_TWT_TEARDOWN:
-+              case WLAN_S1G_TWT_SETUP:
-+                      ieee80211_s1g_rx_twt_action(sdata, skb);
-+                      break;
-+              default:
-+                      break;
-+              }
-       } else if (ieee80211_is_ext(mgmt->frame_control)) {
-               if (sdata->vif.type == NL80211_IFTYPE_STATION)
-                       ieee80211_sta_rx_queued_ext(sdata, skb);
-@@ -1514,6 +1526,24 @@ static void ieee80211_iface_process_skb(
-       }
- }
-+static void ieee80211_iface_process_status(struct ieee80211_sub_if_data *sdata,
-+                                         struct sk_buff *skb)
-+{
-+      struct ieee80211_mgmt *mgmt = (void *)skb->data;
-+
-+      if (ieee80211_is_action(mgmt->frame_control) &&
-+          mgmt->u.action.category == WLAN_CATEGORY_S1G) {
-+              switch (mgmt->u.action.u.s1g.action_code) {
-+              case WLAN_S1G_TWT_TEARDOWN:
-+              case WLAN_S1G_TWT_SETUP:
-+                      ieee80211_s1g_status_twt_action(sdata, skb);
-+                      break;
-+              default:
-+                      break;
-+              }
-+      }
-+}
-+
- static void ieee80211_iface_work(struct work_struct *work)
- {
-       struct ieee80211_sub_if_data *sdata =
-@@ -1543,6 +1573,16 @@ static void ieee80211_iface_work(struct
-               kcov_remote_stop();
-       }
-+      /* process status queue */
-+      while ((skb = skb_dequeue(&sdata->status_queue))) {
-+              kcov_remote_start_common(skb_get_kcov_handle(skb));
-+
-+              ieee80211_iface_process_status(sdata, skb);
-+              kfree_skb(skb);
-+
-+              kcov_remote_stop();
-+      }
-+
-       /* then other type-dependent work */
-       switch (sdata->vif.type) {
-       case NL80211_IFTYPE_STATION:
-@@ -1606,6 +1646,7 @@ static void ieee80211_setup_sdata(struct
-       }
-       skb_queue_head_init(&sdata->skb_queue);
-+      skb_queue_head_init(&sdata->status_queue);
-       INIT_WORK(&sdata->work, ieee80211_iface_work);
-       INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
-       INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -3211,6 +3211,68 @@ ieee80211_rx_h_mgmt_check(struct ieee802
-       return RX_CONTINUE;
- }
-+static bool
-+ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
-+{
-+      struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)rx->skb->data;
-+      struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
-+      struct ieee80211_sub_if_data *sdata = rx->sdata;
-+      const struct ieee80211_sta_he_cap *hecap;
-+      struct ieee80211_supported_band *sband;
-+
-+      /* TWT actions are only supported in AP for the moment */
-+      if (sdata->vif.type != NL80211_IFTYPE_AP)
-+              return false;
-+
-+      if (!rx->local->ops->add_twt_setup)
-+              return false;
-+
-+      sband = rx->local->hw.wiphy->bands[status->band];
-+      hecap = ieee80211_get_he_iftype_cap(sband,
-+                                          ieee80211_vif_type_p2p(&sdata->vif));
-+      if (!hecap)
-+              return false;
-+
-+      if (!(hecap->he_cap_elem.mac_cap_info[0] &
-+            IEEE80211_HE_MAC_CAP0_TWT_RES))
-+              return false;
-+
-+      if (!rx->sta)
-+              return false;
-+
-+      switch (mgmt->u.action.u.s1g.action_code) {
-+      case WLAN_S1G_TWT_SETUP: {
-+              struct ieee80211_twt_setup *twt;
-+
-+              if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
-+                                 1 + /* action code */
-+                                 sizeof(struct ieee80211_twt_setup) +
-+                                 2 /* TWT req_type agrt */)
-+                      break;
-+
-+              twt = (void *)mgmt->u.action.u.s1g.variable;
-+              if (twt->element_id != WLAN_EID_S1G_TWT)
-+                      break;
-+
-+              if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
-+                                 4 + /* action code + token + tlv */
-+                                 twt->length)
-+                      break;
-+
-+              return true; /* queue the frame */
-+      }
-+      case WLAN_S1G_TWT_TEARDOWN:
-+              if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 2)
-+                      break;
-+
-+              return true; /* queue the frame */
-+      default:
-+              break;
-+      }
-+
-+      return false;
-+}
-+
- static ieee80211_rx_result debug_noinline
- ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
- {
-@@ -3490,6 +3552,17 @@ ieee80211_rx_h_action(struct ieee80211_r
-                   !mesh_path_sel_is_hwmp(sdata))
-                       break;
-               goto queue;
-+      case WLAN_CATEGORY_S1G:
-+              switch (mgmt->u.action.u.s1g.action_code) {
-+              case WLAN_S1G_TWT_SETUP:
-+              case WLAN_S1G_TWT_TEARDOWN:
-+                      if (ieee80211_process_rx_twt_action(rx))
-+                              goto queue;
-+                      break;
-+              default:
-+                      break;
-+              }
-+              break;
-       }
-       return RX_CONTINUE;
---- a/net/mac80211/s1g.c
-+++ b/net/mac80211/s1g.c
-@@ -6,6 +6,7 @@
- #include <linux/ieee80211.h>
- #include <net/mac80211.h>
- #include "ieee80211_i.h"
-+#include "driver-ops.h"
- void ieee80211_s1g_sta_rate_init(struct sta_info *sta)
- {
-@@ -14,3 +15,182 @@ void ieee80211_s1g_sta_rate_init(struct
-       sta->rx_stats.last_rate =
-                       STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_S1G);
- }
-+
-+bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb)
-+{
-+      struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
-+
-+      if (likely(!ieee80211_is_action(mgmt->frame_control)))
-+              return false;
-+
-+      if (likely(mgmt->u.action.category != WLAN_CATEGORY_S1G))
-+              return false;
-+
-+      return mgmt->u.action.u.s1g.action_code == WLAN_S1G_TWT_SETUP;
-+}
-+
-+static void
-+ieee80211_s1g_send_twt_setup(struct ieee80211_sub_if_data *sdata, const u8 *da,
-+                           const u8 *bssid, struct ieee80211_twt_setup *twt)
-+{
-+      int len = IEEE80211_MIN_ACTION_SIZE + 4 + twt->length;
-+      struct ieee80211_local *local = sdata->local;
-+      struct ieee80211_mgmt *mgmt;
-+      struct sk_buff *skb;
-+
-+      skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
-+      if (!skb)
-+              return;
-+
-+      skb_reserve(skb, local->hw.extra_tx_headroom);
-+      mgmt = skb_put_zero(skb, len);
-+      mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-+                                        IEEE80211_STYPE_ACTION);
-+      memcpy(mgmt->da, da, ETH_ALEN);
-+      memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
-+      memcpy(mgmt->bssid, bssid, ETH_ALEN);
-+
-+      mgmt->u.action.category = WLAN_CATEGORY_S1G;
-+      mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_SETUP;
-+      memcpy(mgmt->u.action.u.s1g.variable, twt, 3 + twt->length);
-+
-+      IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
-+                                      IEEE80211_TX_INTFL_MLME_CONN_TX |
-+                                      IEEE80211_TX_CTL_REQ_TX_STATUS;
-+      ieee80211_tx_skb(sdata, skb);
-+}
-+
-+static void
-+ieee80211_s1g_send_twt_teardown(struct ieee80211_sub_if_data *sdata,
-+                              const u8 *da, const u8 *bssid, u8 flowid)
-+{
-+      struct ieee80211_local *local = sdata->local;
-+      struct ieee80211_mgmt *mgmt;
-+      struct sk_buff *skb;
-+      u8 *id;
-+
-+      skb = dev_alloc_skb(local->hw.extra_tx_headroom +
-+                          IEEE80211_MIN_ACTION_SIZE + 2);
-+      if (!skb)
-+              return;
-+
-+      skb_reserve(skb, local->hw.extra_tx_headroom);
-+      mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE + 2);
-+      mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-+                                        IEEE80211_STYPE_ACTION);
-+      memcpy(mgmt->da, da, ETH_ALEN);
-+      memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
-+      memcpy(mgmt->bssid, bssid, ETH_ALEN);
-+
-+      mgmt->u.action.category = WLAN_CATEGORY_S1G;
-+      mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_TEARDOWN;
-+      id = (u8 *)mgmt->u.action.u.s1g.variable;
-+      *id = flowid;
-+
-+      IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
-+                                      IEEE80211_TX_CTL_REQ_TX_STATUS;
-+      ieee80211_tx_skb(sdata, skb);
-+}
-+
-+static void
-+ieee80211_s1g_rx_twt_setup(struct ieee80211_sub_if_data *sdata,
-+                         struct sta_info *sta, struct sk_buff *skb)
-+{
-+      struct ieee80211_mgmt *mgmt = (void *)skb->data;
-+      struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
-+      struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
-+
-+      twt_agrt->req_type &= cpu_to_le16(~IEEE80211_TWT_REQTYPE_REQUEST);
-+
-+      /* broadcast TWT not supported yet */
-+      if (twt->control & IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST) {
-+              le16p_replace_bits(&twt_agrt->req_type,
-+                                 TWT_SETUP_CMD_REJECT,
-+                                 IEEE80211_TWT_REQTYPE_SETUP_CMD);
-+              goto out;
-+      }
-+
-+      drv_add_twt_setup(sdata->local, sdata, &sta->sta, twt);
-+out:
-+      ieee80211_s1g_send_twt_setup(sdata, mgmt->sa, sdata->vif.addr, twt);
-+}
-+
-+static void
-+ieee80211_s1g_rx_twt_teardown(struct ieee80211_sub_if_data *sdata,
-+                            struct sta_info *sta, struct sk_buff *skb)
-+{
-+      struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
-+
-+      drv_twt_teardown_request(sdata->local, sdata, &sta->sta,
-+                               mgmt->u.action.u.s1g.variable[0]);
-+}
-+
-+static void
-+ieee80211_s1g_tx_twt_setup_fail(struct ieee80211_sub_if_data *sdata,
-+                              struct sta_info *sta, struct sk_buff *skb)
-+{
-+      struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
-+      struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
-+      struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
-+      u8 flowid = le16_get_bits(twt_agrt->req_type,
-+                                IEEE80211_TWT_REQTYPE_FLOWID);
-+
-+      drv_twt_teardown_request(sdata->local, sdata, &sta->sta, flowid);
-+
-+      ieee80211_s1g_send_twt_teardown(sdata, mgmt->sa, sdata->vif.addr,
-+                                      flowid);
-+}
-+
-+void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
-+                               struct sk_buff *skb)
-+{
-+      struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
-+      struct ieee80211_local *local = sdata->local;
-+      struct sta_info *sta;
-+
-+      mutex_lock(&local->sta_mtx);
-+
-+      sta = sta_info_get_bss(sdata, mgmt->sa);
-+      if (!sta)
-+              goto out;
-+
-+      switch (mgmt->u.action.u.s1g.action_code) {
-+      case WLAN_S1G_TWT_SETUP:
-+              ieee80211_s1g_rx_twt_setup(sdata, sta, skb);
-+              break;
-+      case WLAN_S1G_TWT_TEARDOWN:
-+              ieee80211_s1g_rx_twt_teardown(sdata, sta, skb);
-+              break;
-+      default:
-+              break;
-+      }
-+
-+out:
-+      mutex_unlock(&local->sta_mtx);
-+}
-+
-+void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
-+                                   struct sk_buff *skb)
-+{
-+      struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
-+      struct ieee80211_local *local = sdata->local;
-+      struct sta_info *sta;
-+
-+      mutex_lock(&local->sta_mtx);
-+
-+      sta = sta_info_get_bss(sdata, mgmt->da);
-+      if (!sta)
-+              goto out;
-+
-+      switch (mgmt->u.action.u.s1g.action_code) {
-+      case WLAN_S1G_TWT_SETUP:
-+              /* process failed twt setup frames */
-+              ieee80211_s1g_tx_twt_setup_fail(sdata, sta, skb);
-+              break;
-+      default:
-+              break;
-+      }
-+
-+out:
-+      mutex_unlock(&local->sta_mtx);
-+}
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -705,13 +705,26 @@ static void ieee80211_report_used_skb(st
-                       /* Check to see if packet is a TDLS teardown packet */
-                       if (ieee80211_is_data(hdr->frame_control) &&
-                           (ieee80211_get_tdls_action(skb, hdr_size) ==
--                           WLAN_TDLS_TEARDOWN))
-+                           WLAN_TDLS_TEARDOWN)) {
-                               ieee80211_tdls_td_tx_handle(local, sdata, skb,
-                                                           info->flags);
--                      else
-+                      } else if (ieee80211_s1g_is_twt_setup(skb)) {
-+                              if (!acked) {
-+                                      struct sk_buff *qskb;
-+
-+                                      qskb = skb_clone(skb, GFP_ATOMIC);
-+                                      if (qskb) {
-+                                              skb_queue_tail(&sdata->status_queue,
-+                                                             qskb);
-+                                              ieee80211_queue_work(&local->hw,
-+                                                                   &sdata->work);
-+                                      }
-+                              }
-+                      } else {
-                               ieee80211_mgd_conn_tx_status(sdata,
-                                                            hdr->frame_control,
-                                                            acked);
-+                      }
-               }
-               rcu_read_unlock();
---- a/net/mac80211/trace.h
-+++ b/net/mac80211/trace.h
-@@ -2825,6 +2825,73 @@ DEFINE_EVENT(sta_flag_evt, drv_sta_set_d
-       TP_ARGS(local, sdata, sta, enabled)
- );
-+TRACE_EVENT(drv_add_twt_setup,
-+      TP_PROTO(struct ieee80211_local *local,
-+               struct ieee80211_sta *sta,
-+               struct ieee80211_twt_setup *twt,
-+               struct ieee80211_twt_params *twt_agrt),
-+
-+      TP_ARGS(local, sta, twt, twt_agrt),
-+
-+      TP_STRUCT__entry(
-+              LOCAL_ENTRY
-+              STA_ENTRY
-+              __field(u8, dialog_token)
-+              __field(u8, control)
-+              __field(__le16, req_type)
-+              __field(__le64, twt)
-+              __field(u8, duration)
-+              __field(__le16, mantissa)
-+              __field(u8, channel)
-+      ),
-+
-+      TP_fast_assign(
-+              LOCAL_ASSIGN;
-+              STA_ASSIGN;
-+              __entry->dialog_token = twt->dialog_token;
-+              __entry->control = twt->control;
-+              __entry->req_type = twt_agrt->req_type;
-+              __entry->twt = twt_agrt->twt;
-+              __entry->duration = twt_agrt->min_twt_dur;
-+              __entry->mantissa = twt_agrt->mantissa;
-+              __entry->channel = twt_agrt->channel;
-+      ),
-+
-+      TP_printk(
-+              LOCAL_PR_FMT STA_PR_FMT
-+              " token:%d control:0x%02x req_type:0x%04x"
-+              " twt:%llu duration:%d mantissa:%d channel:%d",
-+              LOCAL_PR_ARG, STA_PR_ARG, __entry->dialog_token,
-+              __entry->control, le16_to_cpu(__entry->req_type),
-+              le64_to_cpu(__entry->twt), __entry->duration,
-+              le16_to_cpu(__entry->mantissa), __entry->channel
-+      )
-+);
-+
-+TRACE_EVENT(drv_twt_teardown_request,
-+      TP_PROTO(struct ieee80211_local *local,
-+               struct ieee80211_sta *sta, u8 flowid),
-+
-+      TP_ARGS(local, sta, flowid),
-+
-+      TP_STRUCT__entry(
-+              LOCAL_ENTRY
-+              STA_ENTRY
-+              __field(u8, flowid)
-+      ),
-+
-+      TP_fast_assign(
-+              LOCAL_ASSIGN;
-+              STA_ASSIGN;
-+              __entry->flowid = flowid;
-+      ),
-+
-+      TP_printk(
-+              LOCAL_PR_FMT STA_PR_FMT " flowid:%d",
-+              LOCAL_PR_ARG, STA_PR_ARG, __entry->flowid
-+      )
-+);
-+
- #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
- #undef TRACE_INCLUDE_PATH
index 1775dc44b161c6bbf3268c4ebe8fe727755b67d9..3f2cc182530adfaf9dc81ecd29d2b1762cce1fc2 100644 (file)
@@ -87,7 +87,7 @@
        CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump)
 --- a/net/mac80211/ieee80211_i.h
 +++ b/net/mac80211/ieee80211_i.h
-@@ -1428,6 +1428,7 @@ struct ieee80211_local {
+@@ -1429,6 +1429,7 @@ struct ieee80211_local {
        int dynamic_ps_forced_timeout;
  
        int user_power_level; /* in dBm, for all interfaces */