From 19128346aecc61b5995abc3e40b02d316532fa29 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 2 Jan 2022 15:17:32 +0100 Subject: [PATCH] openwrt-21.02: update to latest upstream commit Signed-off-by: John Crispin --- config.yml | 5 +- feeds/ucentral/ratelimit/Makefile | 2 +- feeds/ucentral/usteer/Makefile | 1 + ...8-realtek-update-to-latest-owrt-HEAD.patch | 341 +- .../0009-include-set-kernel-version.mk.patch | 10 +- .../0017-netifd-update-to-latest-HEAD.patch | 66 +- .../0018-mac80211-update-to-latest-HEAD.patch | 4841 ----- .../0028-mt76-update-to-latest-HEAD.patch | 247 - ...ute2-m_xt.so-depends-on-dynsyms.list.patch | 47 - ...rnel-backport-napi-threading-patches.patch | 18 +- ...03-pending-scripts-add-gen_config.py.patch | 17 +- ...on-hotplug-convert-to-gpio-descripto.patch | 286 + ...t-ipq40xx-revert-usage-of-VLAN-S-TAG.patch | 18 +- ...-add-EdgeCore-SPW2AC1200-support-lan.patch | 148 + ...x-add-the-Qualcomm-AX-target-support.patch | 139 +- ...-ability-to-persistently-store-certi.patch | 33 - .../0030-ath10k-ct-update-the-driver.patch | 30 - ...mac80211-fix-builds-on-ath79-targets.patch | 60 - ...stapd-under-ujail-to-communicate-wit.patch | 91 - .../0002-rtkmipsel-add-kernel-version.patch | 10 +- .../0006-rtkmipsel-kernel-module-fixes.patch | 4 +- .../0001-mac80211-backport-latest-HEAD.patch | 16557 ++++++++++++++++ .../wifi/0002-mac80211-pending-fixes.patch | 106 + .../0003-hostapd-backport-latest-HEAD.patch} | 2645 +-- patches/wifi/0004-hostapd-pending-fixes.patch | 170 + ...5-hostapd-add-wispr-bandwidth-patch.patch} | 0 26 files changed, 19035 insertions(+), 6857 deletions(-) delete mode 100644 patches/backports/0018-mac80211-update-to-latest-HEAD.patch delete mode 100644 patches/backports/0028-mt76-update-to-latest-HEAD.patch delete mode 100644 patches/backports/0030-iproute2-m_xt.so-depends-on-dynsyms.list.patch create mode 100644 patches/base/0018-Revert-gpio-button-hotplug-convert-to-gpio-descripto.patch create mode 100644 patches/ipq40xx/0011-ipq4018-add-EdgeCore-SPW2AC1200-support-lan.patch delete mode 100644 patches/rest/0030-ath10k-ct-update-the-driver.patch delete mode 100644 patches/rest/0044-mac80211-fix-builds-on-ath79-targets.patch delete mode 100644 patches/rest/0052-hostapd-allow-hostapd-under-ujail-to-communicate-wit.patch create mode 100644 patches/wifi/0001-mac80211-backport-latest-HEAD.patch create mode 100644 patches/wifi/0002-mac80211-pending-fixes.patch rename patches/{backports/0019-hostapd-update-to-latest-HEAD.patch => wifi/0003-hostapd-backport-latest-HEAD.patch} (75%) create mode 100644 patches/wifi/0004-hostapd-pending-fixes.patch rename patches/{rest/0049-hostapd-add-wispr-bandwidth-patch.patch => wifi/0005-hostapd-add-wispr-bandwidth-patch.patch} (100%) diff --git a/config.yml b/config.yml index 9d250bf74..cd8532ea5 100644 --- a/config.yml +++ b/config.yml @@ -1,12 +1,13 @@ repo: https://github.com/openwrt/openwrt.git branch: openwrt-21.02 -revision: 378769b5551714ccaa821b481bfeecbf362f351e +revision: c67509efd7d0c43eb3f622f06c8a31aa28d22f6e output_dir: ./output patch_folders: - patches/backports/ - - patches/ath79 - patches/base + - patches/wifi + - patches/ath79 - patches/ramips - patches/ipq40xx - patches/ipq806x diff --git a/feeds/ucentral/ratelimit/Makefile b/feeds/ucentral/ratelimit/Makefile index 700f5d398..829130d8c 100644 --- a/feeds/ucentral/ratelimit/Makefile +++ b/feeds/ucentral/ratelimit/Makefile @@ -11,7 +11,7 @@ define Package/ratelimit SECTION:=net CATEGORY:=Network TITLE:=Wireless ratelimiting - DEPENDS:=+hostapd-utils +tc +kmod-ifb + DEPENDS:=+tc +kmod-ifb endef define Package/ratelimit/description diff --git a/feeds/ucentral/usteer/Makefile b/feeds/ucentral/usteer/Makefile index 23d3de2b8..14030d46e 100644 --- a/feeds/ucentral/usteer/Makefile +++ b/feeds/ucentral/usteer/Makefile @@ -7,6 +7,7 @@ PKG_SOURCE_URL=https://git.openwrt.org/project/usteer.git PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2021-04-19 PKG_SOURCE_VERSION:=ab4d89e7429df19fb7af862213bc5f09ca964948 +PKG_MIRROR_HASH:=84f6143fea887aca896337756d393494a4cfb698f5e48da760c38723ceaca226 PKG_BUILD_PARALLEL:=1 diff --git a/patches/backports/0008-realtek-update-to-latest-owrt-HEAD.patch b/patches/backports/0008-realtek-update-to-latest-owrt-HEAD.patch index 87dc95035..e9a00418a 100644 --- a/patches/backports/0008-realtek-update-to-latest-owrt-HEAD.patch +++ b/patches/backports/0008-realtek-update-to-latest-owrt-HEAD.patch @@ -1,7 +1,7 @@ -From b3305eb14bf4daabee1e49eafcb04a856744db99 Mon Sep 17 00:00:00 2001 +From 9baf9f77dbc5129bd0f8f655e9ccf9fab93cd7e6 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sat, 4 Sep 2021 05:42:30 +0200 -Subject: [PATCH 01/66] realtek: update to latest owrt HEAD +Subject: [PATCH 01/88] realtek: update to latest owrt HEAD Signed-off-by: John Crispin --- @@ -24,7 +24,7 @@ Signed-off-by: John Crispin .../files-5.4/drivers/net/dsa/rtl83xx/Kconfig | 2 +- .../drivers/net/dsa/rtl83xx/Makefile | 2 +- .../drivers/net/dsa/rtl83xx/common.c | 1065 +++++- - .../drivers/net/dsa/rtl83xx/debugfs.c | 392 ++- + .../drivers/net/dsa/rtl83xx/debugfs.c | 392 +- .../files-5.4/drivers/net/dsa/rtl83xx/dsa.c | 1363 +++++-- .../drivers/net/dsa/rtl83xx/rtl838x.c | 1749 ++++++++- .../drivers/net/dsa/rtl83xx/rtl838x.h | 472 --- @@ -39,9 +39,10 @@ Signed-off-by: John Crispin .../realtek/files-5.4/include/linux/rtl838x.h | 1072 ++++++ .../realtek/files-5.4/net/dsa/tag_rtl83xx.c | 119 + target/linux/realtek/image/Makefile | 44 +- - .../realtek/patches-5.4/100-dsa-lag.patch | 3123 +++++++++++++++++ + .../realtek/patches-5.4/100-dsa-lag.patch | 3145 +++++++++++++++++ .../realtek/patches-5.4/101-brflood-api.patch | 817 +++++ ...0-gpio-Add-Realtek-Otto-GPIO-support.patch | 405 +++ + ...net-add-support-for-rtl838x-ethernet.patch | 2 +- ...nclude-linux-add-phy-ops-for-rtl838x.patch | 2 +- ...04-include-linux-add-phy-hsgmii-mode.patch | 19 + .../realtek/patches-5.4/706-sysled.patch | 288 ++ @@ -51,7 +52,7 @@ Signed-off-by: John Crispin .../realtek/patches-5.4/710-adt7470.patch | 20 + .../realtek/patches-5.4/711-ec4100.patch | 150 + .../linux/realtek/patches-5.4/712-fixes.patch | 23 + - 46 files changed, 16263 insertions(+), 1623 deletions(-) + 47 files changed, 16286 insertions(+), 1624 deletions(-) delete mode 100644 target/linux/realtek/base-files/lib/preinit/05_set_preinit_iface_realtek delete mode 100644 target/linux/realtek/base-files/lib/preinit/98_remove_preinit_realtek delete mode 100644 target/linux/realtek/dts/rtl8380_zyxel_gs1900-8.dts @@ -15346,13 +15347,14 @@ index 18e5fedb9b..a4b2ea892c 100644 $(eval $(call BuildImage)) diff --git a/target/linux/realtek/patches-5.4/100-dsa-lag.patch b/target/linux/realtek/patches-5.4/100-dsa-lag.patch new file mode 100644 -index 0000000000..3d1992e4cb +index 0000000000..5a28760ba9 --- /dev/null +++ b/target/linux/realtek/patches-5.4/100-dsa-lag.patch -@@ -0,0 +1,3123 @@ -+diff -urpN linux-5.4.137.old/drivers/net/bonding/bond_main.c linux-5.4.137/drivers/net/bonding/bond_main.c -+--- linux-5.4.137.old/drivers/net/bonding/bond_main.c 2021-08-04 14:05:38.055697349 +0700 -++++ linux-5.4.137/drivers/net/bonding/bond_main.c 2021-08-04 14:05:53.887713713 +0700 +@@ -0,0 +1,3145 @@ ++Index: linux-5.4.158/drivers/net/bonding/bond_main.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/bonding/bond_main.c +++++ linux-5.4.158/drivers/net/bonding/bond_main.c +@@ -1753,6 +1753,8 @@ int bond_enslave(struct net_device *bond + goto err_unregister; + } @@ -15362,9 +15364,10 @@ index 0000000000..3d1992e4cb + res = bond_sysfs_slave_add(new_slave); + if (res) { + slave_dbg(bond_dev, slave_dev, "Error %d calling bond_sysfs_slave_add\n", res); -+diff -urpN linux-5.4.137.old/drivers/net/dsa/b53/b53_common.c linux-5.4.137/drivers/net/dsa/b53/b53_common.c -+--- linux-5.4.137.old/drivers/net/dsa/b53/b53_common.c 2021-08-04 14:05:38.055697349 +0700 -++++ linux-5.4.137/drivers/net/dsa/b53/b53_common.c 2021-08-04 14:05:53.887713713 +0700 ++Index: linux-5.4.158/drivers/net/dsa/b53/b53_common.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/b53/b53_common.c +++++ linux-5.4.158/drivers/net/dsa/b53/b53_common.c +@@ -537,7 +537,7 @@ int b53_enable_port(struct dsa_switch *d + if (!dsa_is_user_port(ds, port)) + return 0; @@ -15392,7 +15395,7 @@ index 0000000000..3d1992e4cb + unsigned int i; + u16 pvlan, reg, pvid; + -+@@ -2396,10 +2396,13 @@ struct b53_device *b53_switch_alloc(stru ++@@ -2395,10 +2395,13 @@ struct b53_device *b53_switch_alloc(stru + struct dsa_switch *ds; + struct b53_device *dev; + @@ -15407,9 +15410,10 @@ index 0000000000..3d1992e4cb + dev = devm_kzalloc(base, sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; -+diff -urpN linux-5.4.137.old/drivers/net/dsa/bcm_sf2.c linux-5.4.137/drivers/net/dsa/bcm_sf2.c -+--- linux-5.4.137.old/drivers/net/dsa/bcm_sf2.c 2021-08-04 14:05:38.055697349 +0700 -++++ linux-5.4.137/drivers/net/dsa/bcm_sf2.c 2021-08-04 14:05:53.887713713 +0700 ++Index: linux-5.4.158/drivers/net/dsa/bcm_sf2.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/bcm_sf2.c +++++ linux-5.4.158/drivers/net/dsa/bcm_sf2.c +@@ -670,7 +670,7 @@ static void bcm_sf2_sw_fixed_state(struc + * state machine and make it go in PHY_FORCING state instead. + */ @@ -15440,9 +15444,10 @@ index 0000000000..3d1992e4cb + struct ethtool_wolinfo pwol = { }; + + if (p->ethtool_ops->get_wol) -+diff -urpN linux-5.4.137.old/drivers/net/dsa/bcm_sf2_cfp.c linux-5.4.137/drivers/net/dsa/bcm_sf2_cfp.c -+--- linux-5.4.137.old/drivers/net/dsa/bcm_sf2_cfp.c 2021-08-04 14:05:38.055697349 +0700 -++++ linux-5.4.137/drivers/net/dsa/bcm_sf2_cfp.c 2021-08-04 14:05:53.887713713 +0700 ++Index: linux-5.4.158/drivers/net/dsa/bcm_sf2_cfp.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/bcm_sf2_cfp.c +++++ linux-5.4.158/drivers/net/dsa/bcm_sf2_cfp.c +@@ -821,7 +821,7 @@ static int bcm_sf2_cfp_rule_insert(struc + struct ethtool_rx_flow_spec *fs) + { @@ -15470,9 +15475,10 @@ index 0000000000..3d1992e4cb + struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); + int ret = 0; + -+diff -urpN linux-5.4.137.old/drivers/net/dsa/dsa_loop.c linux-5.4.137/drivers/net/dsa/dsa_loop.c -+--- linux-5.4.137.old/drivers/net/dsa/dsa_loop.c 2021-08-04 14:05:38.055697349 +0700 -++++ linux-5.4.137/drivers/net/dsa/dsa_loop.c 2021-08-04 14:05:53.887713713 +0700 ++Index: linux-5.4.158/drivers/net/dsa/dsa_loop.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/dsa_loop.c +++++ linux-5.4.158/drivers/net/dsa/dsa_loop.c +@@ -286,10 +286,13 @@ static int dsa_loop_drv_probe(struct mdi + dev_info(&mdiodev->dev, "%s: 0x%0x\n", + pdata->name, pdata->enabled_ports); @@ -15488,10 +15494,11 @@ index 0000000000..3d1992e4cb + ps = devm_kzalloc(&mdiodev->dev, sizeof(*ps), GFP_KERNEL); + if (!ps) + return -ENOMEM; -+diff -urpN linux-5.4.137.old/drivers/net/dsa/lan9303-core.c linux-5.4.137/drivers/net/dsa/lan9303-core.c -+--- linux-5.4.137.old/drivers/net/dsa/lan9303-core.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/lan9303-core.c 2021-08-04 14:05:53.887713713 +0700 -+@@ -1283,10 +1283,12 @@ static int lan9303_register_switch(struc ++Index: linux-5.4.158/drivers/net/dsa/lan9303-core.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/lan9303-core.c +++++ linux-5.4.158/drivers/net/dsa/lan9303-core.c ++@@ -1287,10 +1287,12 @@ static int lan9303_register_switch(struc + { + int base; + @@ -15505,10 +15512,11 @@ index 0000000000..3d1992e4cb + chip->ds->priv = chip; + chip->ds->ops = &lan9303_switch_ops; + base = chip->phy_addr_base; -+diff -urpN linux-5.4.137.old/drivers/net/dsa/lantiq_gswip.c linux-5.4.137/drivers/net/dsa/lantiq_gswip.c -+--- linux-5.4.137.old/drivers/net/dsa/lantiq_gswip.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/lantiq_gswip.c 2021-08-04 14:05:53.887713713 +0700 -+@@ -2006,10 +2006,12 @@ static int gswip_probe(struct platform_d ++Index: linux-5.4.158/drivers/net/dsa/lantiq_gswip.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/lantiq_gswip.c +++++ linux-5.4.158/drivers/net/dsa/lantiq_gswip.c ++@@ -2013,10 +2013,12 @@ static int gswip_probe(struct platform_d + if (!priv->hw_info) + return -EINVAL; + @@ -15522,9 +15530,10 @@ index 0000000000..3d1992e4cb + priv->ds->priv = priv; + priv->ds->ops = &gswip_switch_ops; + priv->dev = dev; -+diff -urpN linux-5.4.137.old/drivers/net/dsa/microchip/ksz_common.c linux-5.4.137/drivers/net/dsa/microchip/ksz_common.c -+--- linux-5.4.137.old/drivers/net/dsa/microchip/ksz_common.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/microchip/ksz_common.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/drivers/net/dsa/microchip/ksz_common.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/microchip/ksz_common.c +++++ linux-5.4.158/drivers/net/dsa/microchip/ksz_common.c +@@ -396,10 +396,13 @@ struct ksz_device *ksz_switch_alloc(stru + struct dsa_switch *ds; + struct ksz_device *swdev; @@ -15540,10 +15549,11 @@ index 0000000000..3d1992e4cb + swdev = devm_kzalloc(base, sizeof(*swdev), GFP_KERNEL); + if (!swdev) + return NULL; -+diff -urpN linux-5.4.137.old/drivers/net/dsa/mt7530.c linux-5.4.137/drivers/net/dsa/mt7530.c -+--- linux-5.4.137.old/drivers/net/dsa/mt7530.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/mt7530.c 2021-08-04 14:05:53.891713717 +0700 -+@@ -785,7 +785,7 @@ mt7530_port_set_vlan_unaware(struct dsa_ ++Index: linux-5.4.158/drivers/net/dsa/mt7530.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/mt7530.c +++++ linux-5.4.158/drivers/net/dsa/mt7530.c ++@@ -786,7 +786,7 @@ mt7530_port_set_vlan_unaware(struct dsa_ + + for (i = 0; i < MT7530_NUM_PORTS; i++) { + if (dsa_is_user_port(ds, i) && @@ -15552,16 +15562,7 @@ index 0000000000..3d1992e4cb + all_user_ports_removed = false; + break; + } -+@@ -843,7 +843,7 @@ mt7530_port_bridge_leave(struct dsa_swit -+ * other port is still a VLAN-aware port. -+ */ -+ if (dsa_is_user_port(ds, i) && i != port && -+- !dsa_port_is_vlan_filtering(&ds->ports[i])) { -++ !dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) { -+ if (dsa_to_port(ds, i)->bridge_dev != bridge) -+ continue; -+ if (priv->ports[i].enable) -+@@ -1219,7 +1219,7 @@ mt7530_setup(struct dsa_switch *ds) ++@@ -1217,7 +1217,7 @@ mt7530_setup(struct dsa_switch *ds) + * controller also is the container for two GMACs nodes representing + * as two netdev instances. + */ @@ -15570,7 +15571,7 @@ index 0000000000..3d1992e4cb + ds->configure_vlan_while_not_filtering = true; + + if (priv->id == ID_MT7530) { -+@@ -1306,7 +1306,7 @@ mt7530_setup(struct dsa_switch *ds) ++@@ -1304,7 +1304,7 @@ mt7530_setup(struct dsa_switch *ds) + + if (!dsa_is_unused_port(ds, 5)) { + priv->p5_intf_sel = P5_INTF_SEL_GMAC5; @@ -15579,7 +15580,7 @@ index 0000000000..3d1992e4cb + } else { + /* Scan the ethernet nodes. look for GMAC1, lookup used phy */ + for_each_child_of_node(dn, mac_np) { -+@@ -1649,10 +1649,13 @@ mt7530_probe(struct mdio_device *mdiodev ++@@ -1647,10 +1647,13 @@ mt7530_probe(struct mdio_device *mdiodev + if (!priv) + return -ENOMEM; + @@ -15594,9 +15595,10 @@ index 0000000000..3d1992e4cb + /* Use medatek,mcm property to distinguish hardware type that would + * casues a little bit differences on power-on sequence. + */ -+diff -urpN linux-5.4.137.old/drivers/net/dsa/mv88e6060.c linux-5.4.137/drivers/net/dsa/mv88e6060.c -+--- linux-5.4.137.old/drivers/net/dsa/mv88e6060.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/mv88e6060.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/drivers/net/dsa/mv88e6060.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/mv88e6060.c +++++ linux-5.4.158/drivers/net/dsa/mv88e6060.c +@@ -270,10 +270,12 @@ static int mv88e6060_probe(struct mdio_d + + dev_info(dev, "switch %s detected\n", name); @@ -15611,9 +15613,10 @@ index 0000000000..3d1992e4cb + ds->priv = priv; + ds->dev = dev; + ds->ops = &mv88e6060_switch_ops; -+diff -urpN linux-5.4.137.old/drivers/net/dsa/mv88e6xxx/chip.c linux-5.4.137/drivers/net/dsa/mv88e6xxx/chip.c -+--- linux-5.4.137.old/drivers/net/dsa/mv88e6xxx/chip.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/mv88e6xxx/chip.c 2021-08-04 14:05:57.643717592 +0700 ++Index: linux-5.4.158/drivers/net/dsa/mv88e6xxx/chip.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/mv88e6xxx/chip.c +++++ linux-5.4.158/drivers/net/dsa/mv88e6xxx/chip.c +@@ -1075,7 +1075,7 @@ static u16 mv88e6xxx_port_vlan(struct mv + if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) + return mv88e6xxx_port_mask(chip); @@ -16025,9 +16028,10 @@ index 0000000000..3d1992e4cb + dev_set_drvdata(dev, ds); + + return dsa_register_switch(ds); -+diff -urpN linux-5.4.137.old/drivers/net/dsa/mv88e6xxx/global2.c linux-5.4.137/drivers/net/dsa/mv88e6xxx/global2.c -+--- linux-5.4.137.old/drivers/net/dsa/mv88e6xxx/global2.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/mv88e6xxx/global2.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/drivers/net/dsa/mv88e6xxx/global2.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/mv88e6xxx/global2.c +++++ linux-5.4.158/drivers/net/dsa/mv88e6xxx/global2.c +@@ -126,8 +126,8 @@ int mv88e6xxx_g2_device_mapping_write(st + + /* Offset 0x07: Trunk Mask Table register */ @@ -16050,9 +16054,10 @@ index 0000000000..3d1992e4cb + { + const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1; + u16 val = (id << 11) | (map & port_mask); -+diff -urpN linux-5.4.137.old/drivers/net/dsa/mv88e6xxx/global2.h linux-5.4.137/drivers/net/dsa/mv88e6xxx/global2.h -+--- linux-5.4.137.old/drivers/net/dsa/mv88e6xxx/global2.h 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/mv88e6xxx/global2.h 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/drivers/net/dsa/mv88e6xxx/global2.h ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/mv88e6xxx/global2.h +++++ linux-5.4.158/drivers/net/dsa/mv88e6xxx/global2.h +@@ -101,6 +101,7 @@ + #define MV88E6XXX_G2_PVT_ADDR_OP_WRITE_PVLAN 0x3000 + #define MV88E6XXX_G2_PVT_ADDR_OP_READ 0x4000 @@ -16072,9 +16077,10 @@ index 0000000000..3d1992e4cb + int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip); + + int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target, -+diff -urpN linux-5.4.137.old/drivers/net/dsa/mv88e6xxx/port.c linux-5.4.137/drivers/net/dsa/mv88e6xxx/port.c -+--- linux-5.4.137.old/drivers/net/dsa/mv88e6xxx/port.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/mv88e6xxx/port.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/drivers/net/dsa/mv88e6xxx/port.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/mv88e6xxx/port.c +++++ linux-5.4.158/drivers/net/dsa/mv88e6xxx/port.c +@@ -994,6 +994,27 @@ int mv88e6xxx_port_set_message_port(stru + return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val); + } @@ -16103,9 +16109,10 @@ index 0000000000..3d1992e4cb + /* Offset 0x06: Port Based VLAN Map */ + + int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map) -+diff -urpN linux-5.4.137.old/drivers/net/dsa/mv88e6xxx/port.h linux-5.4.137/drivers/net/dsa/mv88e6xxx/port.h -+--- linux-5.4.137.old/drivers/net/dsa/mv88e6xxx/port.h 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/mv88e6xxx/port.h 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/drivers/net/dsa/mv88e6xxx/port.h ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/mv88e6xxx/port.h +++++ linux-5.4.158/drivers/net/dsa/mv88e6xxx/port.h +@@ -168,6 +168,9 @@ + /* Offset 0x05: Port Control 1 */ + #define MV88E6XXX_PORT_CTL1 0x05 @@ -16125,9 +16132,10 @@ index 0000000000..3d1992e4cb + int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port, + size_t size); + int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port); -+diff -urpN linux-5.4.137.old/drivers/net/dsa/qca8k.c linux-5.4.137/drivers/net/dsa/qca8k.c -+--- linux-5.4.137.old/drivers/net/dsa/qca8k.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/qca8k.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/drivers/net/dsa/qca8k.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/qca8k.c +++++ linux-5.4.158/drivers/net/dsa/qca8k.c +@@ -661,7 +661,7 @@ qca8k_setup(struct dsa_switch *ds) + return ret; + @@ -16152,9 +16160,10 @@ index 0000000000..3d1992e4cb + priv->ds->priv = priv; + priv->ops = qca8k_switch_ops; + priv->ds->ops = &priv->ops; -+diff -urpN linux-5.4.137.old/drivers/net/dsa/realtek-smi-core.c linux-5.4.137/drivers/net/dsa/realtek-smi-core.c -+--- linux-5.4.137.old/drivers/net/dsa/realtek-smi-core.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/realtek-smi-core.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/drivers/net/dsa/realtek-smi-core.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/realtek-smi-core.c +++++ linux-5.4.158/drivers/net/dsa/realtek-smi-core.c +@@ -444,9 +444,12 @@ static int realtek_smi_probe(struct plat + return ret; + } @@ -16169,10 +16178,11 @@ index 0000000000..3d1992e4cb + smi->ds->priv = smi; + + smi->ds->ops = var->ds_ops; -+diff -urpN linux-5.4.137.old/drivers/net/dsa/sja1105/sja1105_main.c linux-5.4.137/drivers/net/dsa/sja1105/sja1105_main.c -+--- linux-5.4.137.old/drivers/net/dsa/sja1105/sja1105_main.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/sja1105/sja1105_main.c 2021-08-04 14:05:53.891713717 +0700 -+@@ -1096,7 +1096,7 @@ int sja1105pqrs_fdb_add(struct dsa_switc ++Index: linux-5.4.158/drivers/net/dsa/sja1105/sja1105_main.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/sja1105/sja1105_main.c +++++ linux-5.4.158/drivers/net/dsa/sja1105/sja1105_main.c ++@@ -1121,7 +1121,7 @@ int sja1105pqrs_fdb_add(struct dsa_switc + l2_lookup.vlanid = vid; + l2_lookup.iotag = SJA1105_S_TAG; + l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0); @@ -16181,7 +16191,7 @@ index 0000000000..3d1992e4cb + l2_lookup.mask_vlanid = VLAN_VID_MASK; + l2_lookup.mask_iotag = BIT(0); + } else { -+@@ -1159,7 +1159,7 @@ int sja1105pqrs_fdb_del(struct dsa_switc ++@@ -1214,7 +1214,7 @@ int sja1105pqrs_fdb_del(struct dsa_switc + l2_lookup.vlanid = vid; + l2_lookup.iotag = SJA1105_S_TAG; + l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0); @@ -16190,7 +16200,7 @@ index 0000000000..3d1992e4cb + l2_lookup.mask_vlanid = VLAN_VID_MASK; + l2_lookup.mask_iotag = BIT(0); + } else { -+@@ -1205,7 +1205,7 @@ static int sja1105_fdb_add(struct dsa_sw ++@@ -1260,7 +1260,7 @@ static int sja1105_fdb_add(struct dsa_sw + * for what gets printed in 'bridge fdb show'. In the case of zero, + * no VID gets printed at all. + */ @@ -16199,7 +16209,7 @@ index 0000000000..3d1992e4cb + vid = 0; + + return priv->info->fdb_add_cmd(ds, port, addr, vid); -+@@ -1216,7 +1216,7 @@ static int sja1105_fdb_del(struct dsa_sw ++@@ -1271,7 +1271,7 @@ static int sja1105_fdb_del(struct dsa_sw + { + struct sja1105_private *priv = ds->priv; + @@ -16208,16 +16218,16 @@ index 0000000000..3d1992e4cb + vid = 0; + + return priv->info->fdb_del_cmd(ds, port, addr, vid); -+@@ -1255,7 +1255,7 @@ static int sja1105_fdb_dump(struct dsa_s ++@@ -1310,7 +1310,7 @@ static int sja1105_fdb_dump(struct dsa_s + u64_to_ether_addr(l2_lookup.macaddr, macaddr); + + /* We need to hide the dsa_8021q VLANs from the user. */ +- if (!dsa_port_is_vlan_filtering(&ds->ports[port])) ++ if (!dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) + l2_lookup.vlanid = 0; -+ cb(macaddr, l2_lookup.vlanid, l2_lookup.lockeds, data); -+ } -+@@ -1748,7 +1748,7 @@ static int sja1105_port_enable(struct ds ++ rc = cb(macaddr, l2_lookup.vlanid, l2_lookup.lockeds, data); ++ if (rc) ++@@ -1805,7 +1805,7 @@ static int sja1105_port_enable(struct ds + if (!dsa_is_user_port(ds, port)) + return 0; + @@ -16226,7 +16236,7 @@ index 0000000000..3d1992e4cb + + slave->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; + -+@@ -1780,7 +1780,7 @@ static int sja1105_mgmt_xmit(struct dsa_ ++@@ -1837,7 +1837,7 @@ static int sja1105_mgmt_xmit(struct dsa_ + } + + /* Transfer skb to the host port. */ @@ -16235,7 +16245,7 @@ index 0000000000..3d1992e4cb + + /* Wait until the switch has processed the frame */ + do { -+@@ -2198,10 +2198,12 @@ static int sja1105_probe(struct spi_devi ++@@ -2255,10 +2255,12 @@ static int sja1105_probe(struct spi_devi + + dev_info(dev, "Probed switch chip: %s\n", priv->info->name); + @@ -16249,7 +16259,7 @@ index 0000000000..3d1992e4cb + ds->ops = &sja1105_switch_ops; + ds->priv = priv; + priv->ds = ds; -+@@ -2215,8 +2217,8 @@ static int sja1105_probe(struct spi_devi ++@@ -2272,8 +2274,8 @@ static int sja1105_probe(struct spi_devi + for (i = 0; i < SJA1105_NUM_PORTS; i++) { + struct sja1105_port *sp = &priv->ports[i]; + @@ -16260,9 +16270,10 @@ index 0000000000..3d1992e4cb + sp->data = tagger_data; + } + mutex_init(&priv->mgmt_lock); -+diff -urpN linux-5.4.137.old/drivers/net/dsa/vitesse-vsc73xx-core.c linux-5.4.137/drivers/net/dsa/vitesse-vsc73xx-core.c -+--- linux-5.4.137.old/drivers/net/dsa/vitesse-vsc73xx-core.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/drivers/net/dsa/vitesse-vsc73xx-core.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/drivers/net/dsa/vitesse-vsc73xx-core.c ++=================================================================== ++--- linux-5.4.158.orig/drivers/net/dsa/vitesse-vsc73xx-core.c +++++ linux-5.4.158/drivers/net/dsa/vitesse-vsc73xx-core.c +@@ -1178,9 +1178,12 @@ int vsc73xx_probe(struct vsc73xx *vsc) + * We allocate 8 ports and avoid access to the nonexistant + * ports. @@ -16277,9 +16288,10 @@ index 0000000000..3d1992e4cb + vsc->ds->priv = vsc; + + vsc->ds->ops = &vsc73xx_ds_ops; -+diff -urpN linux-5.4.137.old/include/net/dsa.h linux-5.4.137/include/net/dsa.h -+--- linux-5.4.137.old/include/net/dsa.h 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/include/net/dsa.h 2021-08-04 14:05:57.643717592 +0700 ++Index: linux-5.4.158/include/net/dsa.h ++=================================================================== ++--- linux-5.4.158.orig/include/net/dsa.h +++++ linux-5.4.158/include/net/dsa.h +@@ -124,17 +124,46 @@ struct dsa_switch_tree { + */ + struct dsa_platform_data *pd; @@ -16508,9 +16520,10 @@ index 0000000000..3d1992e4cb + #endif + + /* Broadcom tag specific helpers to insert and extract queue/port number */ -+diff -urpN linux-5.4.137.old/net/dsa/Kconfig linux-5.4.137/net/dsa/Kconfig -+--- linux-5.4.137.old/net/dsa/Kconfig 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/net/dsa/Kconfig 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/net/dsa/Kconfig ++=================================================================== ++--- linux-5.4.158.orig/net/dsa/Kconfig +++++ linux-5.4.158/net/dsa/Kconfig +@@ -56,14 +56,19 @@ config NET_DSA_TAG_GSWIP + Say Y or M if you want to enable support for tagging frames for the + Lantiq / Intel GSWIP switches. @@ -16531,9 +16544,10 @@ index 0000000000..3d1992e4cb + help + Say Y or M if you want to enable support for tagging frames for the + Marvell switches which use EtherType DSA headers. -+diff -urpN linux-5.4.137.old/net/dsa/Makefile linux-5.4.137/net/dsa/Makefile -+--- linux-5.4.137.old/net/dsa/Makefile 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/net/dsa/Makefile 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/net/dsa/Makefile ++=================================================================== ++--- linux-5.4.158.orig/net/dsa/Makefile +++++ linux-5.4.158/net/dsa/Makefile +@@ -6,8 +6,7 @@ dsa_core-y += dsa.o dsa2.o master.o port + # tagging formats + obj-$(CONFIG_NET_DSA_TAG_8021Q) += tag_8021q.o @@ -16544,9 +16558,10 @@ index 0000000000..3d1992e4cb + obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o + obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o + obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o -+diff -urpN linux-5.4.137.old/net/dsa/dsa.c linux-5.4.137/net/dsa/dsa.c -+--- linux-5.4.137.old/net/dsa/dsa.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/net/dsa/dsa.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/net/dsa/dsa.c ++=================================================================== ++--- linux-5.4.158.orig/net/dsa/dsa.c +++++ linux-5.4.158/net/dsa/dsa.c +@@ -224,11 +224,21 @@ static int dsa_switch_rcv(struct sk_buff + } + @@ -16599,10 +16614,11 @@ index 0000000000..3d1992e4cb + if (ret) + return ret; + } -+diff -urpN linux-5.4.137.old/net/dsa/dsa2.c linux-5.4.137/net/dsa/dsa2.c -+--- linux-5.4.137.old/net/dsa/dsa2.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/net/dsa/dsa2.c 2021-08-04 14:05:57.643717592 +0700 -+@@ -25,6 +25,65 @@ static DEFINE_MUTEX(dsa2_mutex); ++Index: linux-5.4.158/net/dsa/dsa2.c ++=================================================================== ++--- linux-5.4.158.orig/net/dsa/dsa2.c +++++ linux-5.4.158/net/dsa/dsa2.c ++@@ -24,6 +24,65 @@ static DEFINE_MUTEX(dsa2_mutex); + static const struct devlink_ops dsa_devlink_ops = { + }; + @@ -16668,7 +16684,7 @@ index 0000000000..3d1992e4cb + static struct dsa_switch_tree *dsa_tree_find(int index) + { + struct dsa_switch_tree *dst; -+@@ -46,6 +105,10 @@ static struct dsa_switch_tree *dsa_tree_ ++@@ -45,6 +104,10 @@ static struct dsa_switch_tree *dsa_tree_ + + dst->index = index; + @@ -16679,7 +16695,7 @@ index 0000000000..3d1992e4cb + INIT_LIST_HEAD(&dst->list); + list_add_tail(&dst->list, &dsa_tree_list); + -+@@ -112,24 +175,38 @@ static bool dsa_port_is_user(struct dsa_ ++@@ -111,24 +174,38 @@ static bool dsa_port_is_user(struct dsa_ + static struct dsa_port *dsa_tree_find_port_by_node(struct dsa_switch_tree *dst, + struct device_node *dn) + { @@ -16731,7 +16747,7 @@ index 0000000000..3d1992e4cb + } + + static bool dsa_port_setup_routing_table(struct dsa_port *dp) -+@@ -139,6 +216,7 @@ static bool dsa_port_setup_routing_table ++@@ -138,6 +215,7 @@ static bool dsa_port_setup_routing_table + struct device_node *dn = dp->dn; + struct of_phandle_iterator it; + struct dsa_port *link_dp; @@ -16739,7 +16755,7 @@ index 0000000000..3d1992e4cb + int err; + + of_for_each_phandle(&it, err, dn, "link", NULL, 0) { -+@@ -148,24 +226,22 @@ static bool dsa_port_setup_routing_table ++@@ -147,24 +225,22 @@ static bool dsa_port_setup_routing_table + return false; + } + @@ -16771,7 +16787,7 @@ index 0000000000..3d1992e4cb + if (dsa_port_is_dsa(dp)) { + complete = dsa_port_setup_routing_table(dp); + if (!complete) -+@@ -176,81 +252,42 @@ static bool dsa_switch_setup_routing_tab ++@@ -175,81 +251,42 @@ static bool dsa_switch_setup_routing_tab + return complete; + } + @@ -16868,7 +16884,7 @@ index 0000000000..3d1992e4cb + } + + static int dsa_port_setup(struct dsa_port *dp) -+@@ -266,6 +303,9 @@ static int dsa_port_setup(struct dsa_por ++@@ -265,6 +302,9 @@ static int dsa_port_setup(struct dsa_por + bool dsa_port_enabled = false; + int err = 0; + @@ -16878,7 +16894,7 @@ index 0000000000..3d1992e4cb + switch (dp->type) { + case DSA_PORT_TYPE_UNUSED: + dsa_port_disable(dp); -+@@ -335,14 +375,21 @@ static int dsa_port_setup(struct dsa_por ++@@ -333,14 +373,21 @@ static int dsa_port_setup(struct dsa_por + dsa_port_link_unregister_of(dp); + if (err && devlink_port_registered) + devlink_port_unregister(dlp); @@ -16901,7 +16917,7 @@ index 0000000000..3d1992e4cb + switch (dp->type) { + case DSA_PORT_TYPE_UNUSED: + break; -+@@ -365,11 +412,16 @@ static void dsa_port_teardown(struct dsa ++@@ -363,11 +410,16 @@ static void dsa_port_teardown(struct dsa + } + break; + } @@ -16919,7 +16935,7 @@ index 0000000000..3d1992e4cb + + /* Initialize ds->phys_mii_mask before registering the slave MDIO bus + * driver and before ops->setup() has run, since the switch drivers and -+@@ -411,6 +463,8 @@ static int dsa_switch_setup(struct dsa_s ++@@ -409,6 +461,8 @@ static int dsa_switch_setup(struct dsa_s + goto teardown; + } + @@ -16928,7 +16944,7 @@ index 0000000000..3d1992e4cb + return 0; + + teardown: -+@@ -429,6 +483,9 @@ free_devlink: ++@@ -427,6 +481,9 @@ free_devlink: + + static void dsa_switch_teardown(struct dsa_switch *ds) + { @@ -16938,7 +16954,7 @@ index 0000000000..3d1992e4cb + if (ds->slave_mii_bus && ds->ops->phy_read) + mdiobus_unregister(ds->slave_mii_bus); + -+@@ -443,89 +500,98 @@ static void dsa_switch_teardown(struct d ++@@ -441,89 +498,98 @@ static void dsa_switch_teardown(struct d + ds->devlink = NULL; + } + @@ -17089,7 +17105,7 @@ index 0000000000..3d1992e4cb + } + + static int dsa_tree_setup(struct dsa_switch_tree *dst) -+@@ -555,12 +621,18 @@ static int dsa_tree_setup(struct dsa_swi ++@@ -553,12 +619,18 @@ static int dsa_tree_setup(struct dsa_swi + if (err) + goto teardown_switches; + @@ -17108,7 +17124,7 @@ index 0000000000..3d1992e4cb + teardown_switches: + dsa_tree_teardown_switches(dst); + teardown_default_cpu: -+@@ -571,48 +643,49 @@ teardown_default_cpu: ++@@ -569,48 +641,49 @@ teardown_default_cpu: + + static void dsa_tree_teardown(struct dsa_switch_tree *dst) + { @@ -17180,7 +17196,7 @@ index 0000000000..3d1992e4cb + } + + static int dsa_port_parse_user(struct dsa_port *dp, const char *name) -+@@ -707,7 +780,7 @@ static int dsa_switch_parse_ports_of(str ++@@ -705,7 +778,7 @@ static int dsa_switch_parse_ports_of(str + goto out_put_node; + } + @@ -17189,7 +17205,7 @@ index 0000000000..3d1992e4cb + + err = dsa_port_parse_of(dp, port); + if (err) -+@@ -731,8 +804,6 @@ static int dsa_switch_parse_member_of(st ++@@ -729,8 +802,6 @@ static int dsa_switch_parse_member_of(st + return sz; + + ds->index = m[1]; @@ -17198,7 +17214,7 @@ index 0000000000..3d1992e4cb + + ds->dst = dsa_tree_touch(m[0]); + if (!ds->dst) -+@@ -741,6 +812,20 @@ static int dsa_switch_parse_member_of(st ++@@ -739,6 +810,20 @@ static int dsa_switch_parse_member_of(st + return 0; + } + @@ -17219,7 +17235,7 @@ index 0000000000..3d1992e4cb + static int dsa_switch_parse_of(struct dsa_switch *ds, struct device_node *dn) + { + int err; -+@@ -749,6 +834,10 @@ static int dsa_switch_parse_of(struct ds ++@@ -747,6 +832,10 @@ static int dsa_switch_parse_of(struct ds + if (err) + return err; + @@ -17230,7 +17246,7 @@ index 0000000000..3d1992e4cb + return dsa_switch_parse_ports_of(ds, dn); + } + -+@@ -786,7 +875,7 @@ static int dsa_switch_parse_ports(struct ++@@ -784,7 +873,7 @@ static int dsa_switch_parse_ports(struct + for (i = 0; i < DSA_MAX_PORTS; i++) { + name = cd->port_names[i]; + dev = cd->netdev[i]; @@ -17239,7 +17255,7 @@ index 0000000000..3d1992e4cb + + if (!name) + continue; -+@@ -806,6 +895,8 @@ static int dsa_switch_parse_ports(struct ++@@ -804,6 +893,8 @@ static int dsa_switch_parse_ports(struct + + static int dsa_switch_parse(struct dsa_switch *ds, struct dsa_chip_data *cd) + { @@ -17248,7 +17264,7 @@ index 0000000000..3d1992e4cb + ds->cd = cd; + + /* We don't support interconnected switches nor multiple trees via -+@@ -816,22 +907,26 @@ static int dsa_switch_parse(struct dsa_s ++@@ -814,22 +905,26 @@ static int dsa_switch_parse(struct dsa_s + if (!ds->dst) + return -ENOMEM; + @@ -17282,7 +17298,7 @@ index 0000000000..3d1992e4cb + if (np) + err = dsa_switch_parse_of(ds, np); + else if (pdata) -+@@ -842,29 +937,14 @@ static int dsa_switch_probe(struct dsa_s ++@@ -840,29 +935,14 @@ static int dsa_switch_probe(struct dsa_s + if (err) + return err; + @@ -17318,7 +17334,7 @@ index 0000000000..3d1992e4cb + + int dsa_register_switch(struct dsa_switch *ds) + { -+@@ -882,9 +962,15 @@ EXPORT_SYMBOL_GPL(dsa_register_switch); ++@@ -880,9 +960,15 @@ EXPORT_SYMBOL_GPL(dsa_register_switch); + static void dsa_switch_remove(struct dsa_switch *ds) + { + struct dsa_switch_tree *dst = ds->dst; @@ -17336,9 +17352,10 @@ index 0000000000..3d1992e4cb + } + + void dsa_unregister_switch(struct dsa_switch *ds) -+diff -urpN linux-5.4.137.old/net/dsa/dsa_priv.h linux-5.4.137/net/dsa/dsa_priv.h -+--- linux-5.4.137.old/net/dsa/dsa_priv.h 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/net/dsa/dsa_priv.h 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/net/dsa/dsa_priv.h ++=================================================================== ++--- linux-5.4.158.orig/net/dsa/dsa_priv.h +++++ linux-5.4.158/net/dsa/dsa_priv.h +@@ -19,6 +19,9 @@ enum { + DSA_NOTIFIER_BRIDGE_LEAVE, + DSA_NOTIFIER_FDB_ADD, @@ -17442,9 +17459,10 @@ index 0000000000..3d1992e4cb ++void dsa_lag_unmap(struct dsa_switch_tree *dst, struct net_device *lag); ++ + #endif -+diff -urpN linux-5.4.137.old/net/dsa/port.c linux-5.4.137/net/dsa/port.c -+--- linux-5.4.137.old/net/dsa/port.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/net/dsa/port.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/net/dsa/port.c ++=================================================================== ++--- linux-5.4.158.orig/net/dsa/port.c +++++ linux-5.4.158/net/dsa/port.c +@@ -174,6 +174,85 @@ void dsa_port_bridge_leave(struct dsa_po + dsa_port_set_state_now(dp, BR_STATE_FORWARDING); + } @@ -17531,9 +17549,10 @@ index 0000000000..3d1992e4cb + static bool dsa_port_can_apply_vlan_filtering(struct dsa_port *dp, + bool vlan_filtering) + { -+diff -urpN linux-5.4.137.old/net/dsa/slave.c linux-5.4.137/net/dsa/slave.c -+--- linux-5.4.137.old/net/dsa/slave.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/net/dsa/slave.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/net/dsa/slave.c ++=================================================================== ++--- linux-5.4.158.orig/net/dsa/slave.c +++++ linux-5.4.158/net/dsa/slave.c +@@ -26,8 +26,6 @@ + + #include "dsa_priv.h" @@ -17589,7 +17608,7 @@ index 0000000000..3d1992e4cb + return -EOPNOTSUPP; + err = dsa_port_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj)); + break; -+@@ -1527,10 +1528,11 @@ void dsa_slave_destroy(struct net_device ++@@ -1525,10 +1526,11 @@ void dsa_slave_destroy(struct net_device + free_netdev(slave_dev); + } + @@ -17602,7 +17621,7 @@ index 0000000000..3d1992e4cb + + static int dsa_slave_changeupper(struct net_device *dev, + struct netdev_notifier_changeupper_info *info) -+@@ -1546,6 +1548,46 @@ static int dsa_slave_changeupper(struct ++@@ -1544,6 +1546,46 @@ static int dsa_slave_changeupper(struct + dsa_port_bridge_leave(dp, info->upper_dev); + err = NOTIFY_OK; + } @@ -17649,7 +17668,7 @@ index 0000000000..3d1992e4cb + } + + return err; -+@@ -1588,11 +1630,33 @@ static int dsa_slave_netdevice_event(str ++@@ -1586,11 +1628,33 @@ static int dsa_slave_netdevice_event(str + { + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + @@ -17685,9 +17704,10 @@ index 0000000000..3d1992e4cb + } + + return NOTIFY_DONE; -+diff -urpN linux-5.4.137.old/net/dsa/switch.c linux-5.4.137/net/dsa/switch.c -+--- linux-5.4.137.old/net/dsa/switch.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/net/dsa/switch.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/net/dsa/switch.c ++=================================================================== ++--- linux-5.4.158.orig/net/dsa/switch.c +++++ linux-5.4.158/net/dsa/switch.c +@@ -20,7 +20,7 @@ static unsigned int dsa_switch_fastest_a + int i; + @@ -17770,9 +17790,10 @@ index 0000000000..3d1992e4cb + case DSA_NOTIFIER_MDB_ADD: + err = dsa_switch_mdb_add(ds, info); + break; -+diff -urpN linux-5.4.137.old/net/dsa/tag_8021q.c linux-5.4.137/net/dsa/tag_8021q.c -+--- linux-5.4.137.old/net/dsa/tag_8021q.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/net/dsa/tag_8021q.c 2021-08-04 14:05:57.643717592 +0700 ++Index: linux-5.4.158/net/dsa/tag_8021q.c ++=================================================================== ++--- linux-5.4.158.orig/net/dsa/tag_8021q.c +++++ linux-5.4.158/net/dsa/tag_8021q.c +@@ -31,15 +31,14 @@ + * Must be transmitted as zero and ignored on receive. + * @@ -17818,9 +17839,10 @@ index 0000000000..3d1992e4cb + struct bridge_vlan_info vinfo; + int err; + -+diff -urpN linux-5.4.137.old/net/dsa/tag_dsa.c linux-5.4.137/net/dsa/tag_dsa.c -+--- linux-5.4.137.old/net/dsa/tag_dsa.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/net/dsa/tag_dsa.c 2021-08-04 14:05:53.891713717 +0700 ++Index: linux-5.4.158/net/dsa/tag_dsa.c ++=================================================================== ++--- linux-5.4.158.orig/net/dsa/tag_dsa.c +++++ linux-5.4.158/net/dsa/tag_dsa.c +@@ -1,7 +1,48 @@ + // SPDX-License-Identifier: GPL-2.0+ + /* @@ -18254,9 +18276,10 @@ index 0000000000..3d1992e4cb ++module_dsa_tag_drivers(dsa_tag_drivers); ++ ++MODULE_LICENSE("GPL"); -+diff -urpN linux-5.4.137.old/net/dsa/tag_edsa.c linux-5.4.137/net/dsa/tag_edsa.c -+--- linux-5.4.137.old/net/dsa/tag_edsa.c 2021-08-04 14:05:38.059697353 +0700 -++++ linux-5.4.137/net/dsa/tag_edsa.c 1970-01-01 07:00:00.000000000 +0700 ++Index: linux-5.4.158/net/dsa/tag_edsa.c ++=================================================================== ++--- linux-5.4.158.orig/net/dsa/tag_edsa.c +++++ /dev/null +@@ -1,215 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ +-/* @@ -19707,6 +19730,18 @@ index 0000000000..8b43f07e8a ++MODULE_DESCRIPTION("Realtek Otto GPIO support"); ++MODULE_AUTHOR("Sander Vanheule "); ++MODULE_LICENSE("GPL v2"); +diff --git a/target/linux/realtek/patches-5.4/702-net-ethernet-add-support-for-rtl838x-ethernet.patch b/target/linux/realtek/patches-5.4/702-net-ethernet-add-support-for-rtl838x-ethernet.patch +index 952384ac89..11e62450d5 100644 +--- a/target/linux/realtek/patches-5.4/702-net-ethernet-add-support-for-rtl838x-ethernet.patch ++++ b/target/linux/realtek/patches-5.4/702-net-ethernet-add-support-for-rtl838x-ethernet.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/ethernet/Kconfig + +++ b/drivers/net/ethernet/Kconfig +-@@ -164,6 +164,13 @@ source "drivers/net/ethernet/rdc/Kconfig ++@@ -163,6 +163,13 @@ source "drivers/net/ethernet/rdc/Kconfig + source "drivers/net/ethernet/realtek/Kconfig" + source "drivers/net/ethernet/renesas/Kconfig" + source "drivers/net/ethernet/rocker/Kconfig" diff --git a/target/linux/realtek/patches-5.4/703-include-linux-add-phy-ops-for-rtl838x.patch b/target/linux/realtek/patches-5.4/703-include-linux-add-phy-ops-for-rtl838x.patch index 03accd1e07..3682eb30a3 100644 --- a/target/linux/realtek/patches-5.4/703-include-linux-add-phy-ops-for-rtl838x.patch diff --git a/patches/backports/0009-include-set-kernel-version.mk.patch b/patches/backports/0009-include-set-kernel-version.mk.patch index 510d11f19..a318df86d 100644 --- a/patches/backports/0009-include-set-kernel-version.mk.patch +++ b/patches/backports/0009-include-set-kernel-version.mk.patch @@ -1,7 +1,7 @@ -From 4ed9b7d04405d5109681643f3ceebbd25f3f28e2 Mon Sep 17 00:00:00 2001 +From d28712edcc0e57b5c0e5d79125a5517ced252e18 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 7 Apr 2021 10:46:26 +0200 -Subject: [PATCH 09/27] include: set kernel-version.mk +Subject: [PATCH] include: set kernel-version.mk Signed-off-by: John Crispin --- @@ -9,7 +9,7 @@ Signed-off-by: John Crispin 1 file changed, 6 insertions(+) diff --git a/include/kernel-version.mk b/include/kernel-version.mk -index fe81dbf603..3c109c13c8 100644 +index 688660cbbd..c7aba61cd7 100644 --- a/include/kernel-version.mk +++ b/include/kernel-version.mk @@ -6,9 +6,15 @@ ifdef CONFIG_TESTING_KERNEL @@ -18,12 +18,12 @@ index fe81dbf603..3c109c13c8 100644 +LINUX_VERSION-4.4 = .60 +LINUX_VERSION-4.14 = .193 - LINUX_VERSION-5.4 = .142 + LINUX_VERSION-5.4 = .158 +LINUX_VERSION-5.10 = .27 +LINUX_KERNEL_HASH-4.4.60 = 2cd8df6f1ac6a5329c5a286ec9b5956215977221a1b731597ed169fff74a9659 +LINUX_KERNEL_HASH-4.14.193 = 0b0fb41d4430e1a42738b341cbfd2f41951aa5cd02acabbd53f076119c8b9f03 - LINUX_KERNEL_HASH-5.4.142 = 99785728968564ba27c7e552d024b560072dcbc885540912eabb5c021e231451 + LINUX_KERNEL_HASH-5.4.158 = 6e018fecdc8fc24553756e582d83b82d65b10a6b03ef36262a24911f839b8d59 +LINUX_KERNEL_HASH-5.10.27 = d99dc9662951299c53a0a8d8c8d0a72a16ff861d20e927c0f9b14f63282d69d9 remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) diff --git a/patches/backports/0017-netifd-update-to-latest-HEAD.patch b/patches/backports/0017-netifd-update-to-latest-HEAD.patch index b8693dc44..c34500ced 100644 --- a/patches/backports/0017-netifd-update-to-latest-HEAD.patch +++ b/patches/backports/0017-netifd-update-to-latest-HEAD.patch @@ -1,33 +1,22 @@ -From 1496ca5ceb941ba725311c6c0366193092035f32 Mon Sep 17 00:00:00 2001 +From 23f5618453b232b9ebc5b61b7a560cd4abc09957 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 27 May 2021 13:24:47 +0200 -Subject: [PATCH 01/60] netifd: update to latest HEAD +Subject: [PATCH] netifd: update to latest HEAD Signed-off-by: John Crispin --- - package/network/config/netifd/Makefile | 8 ++-- + package/network/config/netifd/Makefile | 2 - .../config/netifd/patches/100-script.patch | 21 +++++++++++ .../config/netifd/patches/hairpin.patch | 37 +++++++++++++++++++ - 3 files changed, 61 insertions(+), 5 deletions(-) + 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 package/network/config/netifd/patches/100-script.patch create mode 100644 package/network/config/netifd/patches/hairpin.patch diff --git a/package/network/config/netifd/Makefile b/package/network/config/netifd/Makefile -index 4b5f110da2..d41bddfd56 100644 +index cd4f8f423d..e4399b2473 100644 --- a/package/network/config/netifd/Makefile +++ b/package/network/config/netifd/Makefile -@@ -5,16 +5,14 @@ PKG_RELEASE:=1 - - PKG_SOURCE_PROTO:=git - PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git --PKG_SOURCE_DATE:=2021-07-26 --PKG_SOURCE_VERSION:=440eb0647708274cc8d7d9e7c2bb0cfdfba90023 --PKG_MIRROR_HASH:=eed957036ab608fdc49bdf801fc5b4405fcd2a3a5e5d3343ec39898e156c10e9 -+PKG_SOURCE_DATE:=2021-10-20 -+PKG_SOURCE_VERSION:=c61a1d432b34babe230e49a82712608b07410fc3 -+PKG_MIRROR_HASH:=2b040d039c560cbc04dfe1e496aa81f714a032db88986803728dd6b724c11cd2 - PKG_MAINTAINER:=Felix Fietkau - +@@ -13,8 +13,6 @@ PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:= @@ -63,49 +52,6 @@ index 0000000000..e7ba83f4bb + psk3-mixed*|sae-mixed*) + auth_type=psk-sae + ;; -diff --git a/package/network/config/netifd/patches/hairpin.patch b/package/network/config/netifd/patches/hairpin.patch -new file mode 100644 -index 0000000000..25515d75d4 ---- /dev/null -+++ b/package/network/config/netifd/patches/hairpin.patch -@@ -0,0 +1,37 @@ -+diff --git a/wireless.c b/wireless.c -+index b26c4e8c8f0b..bd847e72ab40 100644 -+--- a/wireless.c -++++ b/wireless.c -+@@ -804,20 +804,13 @@ wireless_interface_init_config(struct wireless_interface *vif) -+ vif->network = cur; -+ -+ cur = tb[VIF_ATTR_MODE]; -+- if (cur) -+- vif->ap_mode = !strcmp(blobmsg_get_string(cur), "ap"); -+- -+- if (!vif->ap_mode) -+- return; -++ vif->ap_mode = cur && !strcmp(blobmsg_get_string(cur), "ap"); -+ -+ cur = tb[VIF_ATTR_ISOLATE]; -+- if (cur) -+- vif->isolate = blobmsg_get_bool(cur); -++ vif->isolate = vif->ap_mode && cur && blobmsg_get_bool(cur); -+ -+ cur = tb[VIF_ATTR_PROXYARP]; -+- if (cur) -+- vif->proxyarp = blobmsg_get_bool(cur); -+- -++ vif->proxyarp = vif->ap_mode && cur && blobmsg_get_bool(cur); -+ } -+ -+ /* vlist update call for wireless interface list */ -+@@ -846,8 +839,6 @@ vif_update(struct vlist_tree *tree, struct vlist_node *node_new, -+ wireless_interface_handle_link(vif_old, NULL, false); -+ free(vif_old->config); -+ vif_old->config = blob_memdup(vif_new->config); -+- vif_old->isolate = vif_new->isolate; -+- vif_old->ap_mode = vif_new->ap_mode; -+ wireless_interface_init_config(vif_old); -+ free(vif_new); -+ } else if (vif_new) { -- 2.25.1 diff --git a/patches/backports/0018-mac80211-update-to-latest-HEAD.patch b/patches/backports/0018-mac80211-update-to-latest-HEAD.patch deleted file mode 100644 index 0a57e4a60..000000000 --- a/patches/backports/0018-mac80211-update-to-latest-HEAD.patch +++ /dev/null @@ -1,4841 +0,0 @@ -From 3feca6da7b0571cf17afc9f0e40d0ede9059c271 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sat, 4 Sep 2021 05:47:27 +0200 -Subject: [PATCH 01/72] mac80211: update to latest HEAD - -Signed-off-by: John Crispin ---- - package/kernel/mac80211/Makefile | 15 +- - package/kernel/mac80211/ath.mk | 5 +- - package/kernel/mac80211/broadcom.mk | 4 +- - .../mac80211/files/lib/netifd/mac80211.sh | 36 - - .../files/lib/netifd/wireless/mac80211.sh | 214 ++- - .../mac80211/files/lib/wifi/mac80211.sh | 110 +- - .../patches/ath/120-owl-loader-compat.patch | 53 - - .../patches/ath/402-ath_regd_optional.patch | 2 +- - .../080-ath10k_thermal_config.patch | 2 +- - ...21-ath10k_init_devices_synchronously.patch | 0 - ...h10k-increase-rx-buffer-size-to-2048.patch | 0 - .../930-ath10k_add_tpt_led_trigger.patch | 0 - ...rolling-support-for-various-chipsets.patch | 2 +- - ...75-ath10k-use-tpt-trigger-by-default.patch | 0 - ...980-ath10k-fix-max-antenna-gain-unit.patch | 0 - ...-power-reduction-for-US-regulatory-d.patch | 0 - ...h10k-Try-to-get-mac-address-from-dts.patch | 42 + - .../201-ath5k-WAR-for-AR71xx-PCI-bug.patch | 0 - .../411-ath5k_allow_adhoc_and_ap.patch | 0 - .../420-ath5k_disable_fast_cc.patch | 0 - .../430-add_ath5k_platform.patch | 0 - .../{ath => ath5k}/432-ath5k_add_pciids.patch | 0 - .../440-ath5k_channel_bw_debugfs.patch | 0 - ...w-reset-AHB-WMAC-interface-on-AR91xx.patch | 0 - ..._hw-issue-external-reset-for-QCA955x.patch | 0 - ...h9k-force-rx_clear-when-disabling-rx.patch | 0 - ...erpret-requested-txpower-in-EIRP-dom.patch | 0 - ...power-reduction-for-US-regulatory-do.patch | 0 - .../401-ath9k_blink_default.patch | 0 - .../410-ath9k_allow_adhoc_and_ap.patch | 0 - ...abled-MFP-capability-unconditionally.patch | 0 - .../500-ath9k_eeprom_debugfs.patch | 0 - .../{ath => ath9k}/501-ath9k_ahb_init.patch | 0 - .../510-ath9k_intr_mitigation_tweak.patch | 0 - .../511-ath9k_reduce_rxbuf.patch | 0 - .../512-ath9k_channelbw_debugfs.patch | 0 - .../513-ath9k_add_pci_ids.patch | 0 - .../{ath => ath9k}/530-ath9k_extra_leds.patch | 0 - .../531-ath9k_extra_platform_leds.patch | 0 - .../540-ath9k_reduce_ani_interval.patch | 0 - .../542-ath9k_debugfs_diag.patch | 0 - .../543-ath9k_entropy_from_adc.patch | 0 - ...544-ath9k-ar933x-usb-hang-workaround.patch | 0 - .../545-ath9k_ani_ws_detect.patch | 0 - .../547-ath9k_led_defstate_fix.patch | 0 - .../548-ath9k_enable_gpio_chip.patch | 0 - .../549-ath9k_enable_gpio_buttons.patch | 0 - .../550-ath9k-disable-bands-via-dt.patch | 0 - .../551-ath9k_ubnt_uap_plus_hsr.patch | 2 +- - .../552-ath9k-ahb_of.patch} | 0 - .../553-ath9k_of_gpio_mask.patch | 0 - .../602-rt2x00-introduce-rt2x00eeprom.patch | 2 +- - ...07-rt2x00-add_platform_data_mac_addr.patch | 11 +- - .../100-remove-cryptoapi-dependencies.patch | 699 --------- - .../patches/subsys/130-disable-fils.patch | 32 - - ...aes-cmac-switch-to-shash-CMAC-driver.patch | 230 --- - .../132-mac80211-remove-cmac-dependency.patch | 10 - - ...320-mac80211_hwsim-add-6GHz-channels.patch | 123 ++ - ...211_hwsim-make-6-GHz-channels-usable.patch | 74 + - ...-remove-legacy-minstrel-rate-control.patch | 2 +- - ...te-control-support-for-encap-offload.patch | 43 +- - ...introduce-aql_enable-node-in-debugfs.patch | 111 ++ - ...ange-struct-txq_info-for-fewer-holes.patch | 39 + - ...to-a-virtual-time-based-airtime-sche.patch | 1277 +++++++++++++++++ - ...bling-4-address-mode-on-a-sta-vif-af.patch | 72 + - ...on-API-to-configure-SAR-power-limita.patch | 398 +++++ - ...mac80211-add-ieee80211_set_sar_specs.patch | 51 + - ...eck-per-vif-offload_flags-in-Tx-path.patch | 26 + - .../500-mac80211_configure_antenna_gain.patch | 16 +- - ...the-dst-buffer-to-of_get_mac_address.patch | 237 +++ - 70 files changed, 2777 insertions(+), 1163 deletions(-) - delete mode 100644 package/kernel/mac80211/files/lib/netifd/mac80211.sh - delete mode 100644 package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch - rename package/kernel/mac80211/patches/{ath => ath10k}/080-ath10k_thermal_config.patch (97%) - rename package/kernel/mac80211/patches/{ath => ath10k}/921-ath10k_init_devices_synchronously.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath10k}/922-ath10k-increase-rx-buffer-size-to-2048.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath10k}/930-ath10k_add_tpt_led_trigger.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath10k}/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch (99%) - rename package/kernel/mac80211/patches/{ath => ath10k}/975-ath10k-use-tpt-trigger-by-default.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath10k}/980-ath10k-fix-max-antenna-gain-unit.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath10k}/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch (100%) - create mode 100644 package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch - rename package/kernel/mac80211/patches/{ath => ath5k}/201-ath5k-WAR-for-AR71xx-PCI-bug.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath5k}/411-ath5k_allow_adhoc_and_ap.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath5k}/420-ath5k_disable_fast_cc.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath5k}/430-add_ath5k_platform.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath5k}/432-ath5k_add_pciids.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath5k}/440-ath5k_channel_bw_debugfs.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/351-ath9k_hw-issue-external-reset-for-QCA955x.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/354-ath9k-force-rx_clear-when-disabling-rx.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/401-ath9k_blink_default.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/410-ath9k_allow_adhoc_and_ap.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/450-ath9k-enabled-MFP-capability-unconditionally.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/500-ath9k_eeprom_debugfs.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/501-ath9k_ahb_init.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/510-ath9k_intr_mitigation_tweak.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/511-ath9k_reduce_rxbuf.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/512-ath9k_channelbw_debugfs.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/513-ath9k_add_pci_ids.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/530-ath9k_extra_leds.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/531-ath9k_extra_platform_leds.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/540-ath9k_reduce_ani_interval.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/542-ath9k_debugfs_diag.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/543-ath9k_entropy_from_adc.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/544-ath9k-ar933x-usb-hang-workaround.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/545-ath9k_ani_ws_detect.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/547-ath9k_led_defstate_fix.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/548-ath9k_enable_gpio_chip.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/549-ath9k_enable_gpio_buttons.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/550-ath9k-disable-bands-via-dt.patch (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/551-ath9k_ubnt_uap_plus_hsr.patch (99%) - rename package/kernel/mac80211/patches/{ath/552-ahb_of.patch => ath9k/552-ath9k-ahb_of.patch} (100%) - rename package/kernel/mac80211/patches/{ath => ath9k}/553-ath9k_of_gpio_mask.patch (100%) - delete mode 100644 package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/130-disable-fils.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch - create mode 100644 package/kernel/mac80211/patches/subsys/320-mac80211_hwsim-add-6GHz-channels.patch - create mode 100644 package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch - create mode 100644 package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch - create mode 100644 package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch - create mode 100644 package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch - create mode 100644 package/kernel/mac80211/patches/subsys/383-mac80211-fix-enabling-4-address-mode-on-a-sta-vif-af.patch - create mode 100644 package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch - create mode 100644 package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch - create mode 100644 package/kernel/mac80211/patches/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch - create mode 100644 package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch - -diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile -index dd9ec172ca..dd39c2d069 100644 ---- a/package/kernel/mac80211/Makefile -+++ b/package/kernel/mac80211/Makefile -@@ -98,7 +98,7 @@ PKG_CONFIG_DEPENDS += \ - define KernelPackage/cfg80211 - $(call KernelPackage/mac80211/Default) - TITLE:=cfg80211 - wireless configuration API -- DEPENDS+= +iw +wireless-regdb -+ DEPENDS+= +iw +iwinfo +wireless-regdb - ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) - FILES:= \ - $(PKG_BUILD_DIR)/compat/compat.ko \ -@@ -127,7 +127,7 @@ define KernelPackage/mac80211 - $(call KernelPackage/mac80211/Default) - TITLE:=Linux 802.11 Wireless Networking Stack - # +kmod-crypto-cmac is a runtime only dependency of net/mac80211/aes_cmac.c -- DEPENDS+= +kmod-cfg80211 +hostapd-common -+ DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm +hostapd-common - KCONFIG:=\ - CONFIG_AVERAGE=y - FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko -@@ -501,9 +501,14 @@ define Build/Patch - $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) - $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) - $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) - $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) - $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) - $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/) - $(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used) - endef - -@@ -511,9 +516,14 @@ define Quilt/Refresh/Package - $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) - $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) - $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) - $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) - $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) - $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/) - endef - - define Build/Compile -@@ -539,7 +549,6 @@ endef - define KernelPackage/cfg80211/install - $(INSTALL_DIR) $(1)/lib/wifi $(1)/lib/netifd/wireless - $(INSTALL_DATA) ./files/lib/wifi/mac80211.sh $(1)/lib/wifi -- $(INSTALL_DATA) ./files/lib/netifd/mac80211.sh $(1)/lib/netifd - $(INSTALL_BIN) ./files/lib/netifd/wireless/mac80211.sh $(1)/lib/netifd/wireless - $(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211 - $(INSTALL_DATA) ./files/mac80211.hotplug $(1)/etc/hotplug.d/ieee80211/10-wifi-detect -diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk -index 24abb910ff..ad2860a98e 100644 ---- a/package/kernel/mac80211/ath.mk -+++ b/package/kernel/mac80211/ath.mk -@@ -34,7 +34,7 @@ ifdef CONFIG_PACKAGE_MAC80211_TRACING - WIL6210_TRACING - endif - --config-$(call config_package,ath) += ATH_CARDS ATH_COMMON ATH_REG_DYNAMIC_USER_REG_HINTS -+config-$(call config_package,ath) += ATH_CARDS ATH_COMMON - config-$(CONFIG_PACKAGE_ATH_DEBUG) += ATH_DEBUG ATH10K_DEBUG ATH9K_STATION_STATISTICS - config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED - config-$(CONFIG_PACKAGE_ATH_SPECTRAL) += ATH9K_COMMON_SPECTRAL ATH10K_SPECTRAL -@@ -43,9 +43,10 @@ config-$(call config_package,ath9k) += ATH9K - config-$(call config_package,ath9k-common) += ATH9K_COMMON - config-$(call config_package,owl-loader) += ATH9K_PCI_NO_EEPROM - config-$(CONFIG_TARGET_ath79) += ATH9K_AHB -+config-$(CONFIG_TARGET_ar71xx) += ATH9K_AHB - config-$(CONFIG_TARGET_ipq40xx) += ATH10K_AHB - config-$(CONFIG_PCI) += ATH9K_PCI --config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD -+config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD ATH_REG_DYNAMIC_USER_REG_HINTS - config-$(CONFIG_ATH9K_HWRNG) += ATH9K_HWRNG - config-$(CONFIG_ATH9K_SUPPORT_PCOEM) += ATH9K_PCOEM - config-$(CONFIG_ATH9K_TX99) += ATH9K_TX99 -diff --git a/package/kernel/mac80211/broadcom.mk b/package/kernel/mac80211/broadcom.mk -index fb576c5809..473bbf597c 100644 ---- a/package/kernel/mac80211/broadcom.mk -+++ b/package/kernel/mac80211/broadcom.mk -@@ -209,7 +209,7 @@ config PACKAGE_B43_USE_BCMA - default "16,28,29,30" if TARGET_bcm47xx_mips74k - default "5,6,7,8,9,10,11,13,15,16,28,29,30" - help -- This is a comma seperated list of core revision numbers. -+ This is a comma separated list of core revision numbers. - - Example (keep files for rev5 only): - 5 -@@ -224,7 +224,7 @@ config PACKAGE_B43_USE_BCMA - default "N,HT" if TARGET_bcm47xx_mips74k - default "G,N,LP,HT" - help -- This is a comma seperated list of PHY types: -+ This is a comma separated list of PHY types: - A => A-PHY - AG => Dual A-PHY G-PHY - G => G-PHY -diff --git a/package/kernel/mac80211/files/lib/netifd/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/mac80211.sh -deleted file mode 100644 -index 92e5c0e395..0000000000 ---- a/package/kernel/mac80211/files/lib/netifd/mac80211.sh -+++ /dev/null -@@ -1,36 +0,0 @@ --mac80211_phy_to_path() { -- local phy="$1" -- -- [ -x /usr/bin/readlink -a -h /sys/class/ieee80211/${phy} ] || return -- -- local path="$(readlink -f /sys/class/ieee80211/${phy}/device)" -- [ -n "$path" ] || return -- -- path="${path##/sys/devices/}" -- case "$path" in -- platform*/pci*) path="${path##platform/}";; -- esac -- -- local p -- local seq="" -- for p in $(ls /sys/class/ieee80211/$phy/device/ieee80211); do -- [ "$p" = "$phy" ] && { -- echo "$path${seq:++$seq}" -- break -- } -- -- seq=$((${seq:-0} + 1)) -- done --} -- --mac80211_path_to_phy() { -- local path="$1" -- -- local p -- for p in $(ls /sys/class/ieee80211); do -- local cur="$(mac80211_phy_to_path "$p")" -- case "$cur" in -- *$path) echo "$p"; return;; -- esac -- done --} -diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -index 9a9c35fb5f..97c567031e 100644 ---- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -+++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -@@ -1,7 +1,6 @@ - #!/bin/sh - . /lib/netifd/netifd-wireless.sh - . /lib/netifd/hostapd.sh --. /lib/netifd/mac80211.sh - - init_wireless_driver "$@" - -@@ -26,11 +25,11 @@ drv_mac80211_init_device_config() { - hostapd_common_add_device_config - - config_add_string path phy 'macaddr:macaddr' -- config_add_string hwmode - config_add_string tx_burst - config_add_string distance - config_add_int beacon_int chanbw frag rts - config_add_int rxantenna txantenna antenna_gain txpower -+ config_add_int num_global_macaddr - config_add_boolean noscan ht_coex acs_exclude_dfs - config_add_array ht_capab - config_add_array channels -@@ -44,11 +43,26 @@ drv_mac80211_init_device_config() { - su_beamformee \ - mu_beamformer \ - mu_beamformee \ -+ he_su_beamformer \ -+ he_su_beamformee \ -+ he_mu_beamformer \ - vht_txop_ps \ - htc_vht \ - rx_antenna_pattern \ -- tx_antenna_pattern -- config_add_int vht_max_a_mpdu_len_exp vht_max_mpdu vht_link_adapt vht160 rx_stbc tx_stbc -+ tx_antenna_pattern \ -+ he_spr_sr_control \ -+ he_twt_required -+ config_add_int \ -+ beamformer_antennas \ -+ beamformee_antennas \ -+ vht_max_a_mpdu_len_exp \ -+ vht_max_mpdu \ -+ vht_link_adapt \ -+ vht160 \ -+ rx_stbc \ -+ tx_stbc \ -+ he_bss_color \ -+ he_spr_non_srg_obss_pd_max_offset - config_add_boolean \ - ldpc \ - greenfield \ -@@ -96,6 +110,23 @@ mac80211_add_capabilities() { - export -n -- "$__var=$__out" - } - -+mac80211_add_he_capabilities() { -+ local __out= oifs -+ -+ oifs="$IFS" -+ IFS=: -+ for capab in "$@"; do -+ set -- $capab -+ [ "$(($4))" -gt 0 ] || continue -+ [ "$(((0x$2) & $3))" -gt 0 ] || { -+ eval "$1=0" -+ continue -+ } -+ append base_cfg "$1=1" "$N" -+ done -+ IFS="$oifs" -+} -+ - mac80211_hostapd_setup_base() { - local phy="$1" - -@@ -119,6 +150,9 @@ mac80211_hostapd_setup_base() { - [ "$noscan" -gt 0 ] && hostapd_noscan=1 - [ "$tx_burst" = 0 ] && tx_burst= - -+ chan_ofs=0 -+ [ "$band" = "6g" ] && chan_ofs=1 -+ - ieee80211n=1 - ht_capab= - case "$htmode" in -@@ -126,7 +160,7 @@ mac80211_hostapd_setup_base() { - HT40*|VHT40|VHT80|VHT160|HE40|HE80|HE160) - case "$hwmode" in - a) -- case "$(( ($channel / 4) % 2 ))" in -+ case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in - 1) ht_capab="[HT40+]";; - 0) ht_capab="[HT40-]";; - esac -@@ -200,7 +234,7 @@ mac80211_hostapd_setup_base() { - case "$htmode" in - VHT20|HE20) enable_ac=1;; - VHT40|HE40) -- case "$(( ($channel / 4) % 2 ))" in -+ case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in - 1) idx=$(($channel + 2));; - 0) idx=$(($channel - 2));; - esac -@@ -208,7 +242,7 @@ mac80211_hostapd_setup_base() { - vht_center_seg0=$idx - ;; - VHT80|HE80) -- case "$(( ($channel / 4) % 4 ))" in -+ case "$(( (($channel / 4) + $chan_ofs) % 4 ))" in - 1) idx=$(($channel + 6));; - 2) idx=$(($channel + 2));; - 3) idx=$(($channel - 2));; -@@ -219,15 +253,35 @@ mac80211_hostapd_setup_base() { - vht_center_seg0=$idx - ;; - VHT160|HE160) -- case "$channel" in -- 36|40|44|48|52|56|60|64) idx=50;; -- 100|104|108|112|116|120|124|128) idx=114;; -- esac -+ if [ "$band" = "6g" ]; then -+ case "$channel" in -+ 1|5|9|13|17|21|25|29) idx=15;; -+ 33|37|41|45|49|53|57|61) idx=47;; -+ 65|69|73|77|81|85|89|93) idx=79;; -+ 97|101|105|109|113|117|121|125) idx=111;; -+ 129|133|137|141|145|149|153|157) idx=143;; -+ 161|165|169|173|177|181|185|189) idx=175;; -+ 193|197|201|205|209|213|217|221) idx=207;; -+ esac -+ else -+ case "$channel" in -+ 36|40|44|48|52|56|60|64) idx=50;; -+ 100|104|108|112|116|120|124|128) idx=114;; -+ esac -+ fi - enable_ac=1 - vht_oper_chwidth=2 - vht_center_seg0=$idx - ;; - esac -+ [ "$band" = "6g" ] && { -+ op_class= -+ case "$htmode" in -+ HE20) op_class=131;; -+ HE*) op_class=$((132 + $vht_oper_chwidth)) -+ esac -+ [ -n "$op_class" ] && append base_cfg "op_class=$op_class" "$N" -+ } - [ "$hwmode" = "a" ] || enable_ac=0 - - if [ "$enable_ac" != "0" ]; then -@@ -242,6 +296,8 @@ mac80211_hostapd_setup_base() { - mu_beamformee:1 \ - vht_txop_ps:1 \ - htc_vht:1 \ -+ beamformee_antennas:4 \ -+ beamformer_antennas:4 \ - rx_antenna_pattern:1 \ - tx_antenna_pattern:1 \ - vht_max_a_mpdu_len_exp:7 \ -@@ -282,6 +338,18 @@ mac80211_hostapd_setup_base() { - RX-STBC-123:0x700:0x300:1 \ - RX-STBC-1234:0x700:0x400:1 \ - -+ [ "$(($vht_cap & 0x800))" -gt 0 -a "$su_beamformer" -gt 0 ] && { -+ cap_ant="$(( ( ($vht_cap >> 16) & 3 ) + 1 ))" -+ [ "$cap_ant" -gt "$beamformer_antennas" ] && cap_ant="$beamformer_antennas" -+ [ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[SOUNDING-DIMENSION-$cap_ant]" -+ } -+ -+ [ "$(($vht_cap & 0x1000))" -gt 0 -a "$su_beamformee" -gt 0 ] && { -+ cap_ant="$(( ( ($vht_cap >> 13) & 3 ) + 1 ))" -+ [ "$cap_ant" -gt "$beamformee_antennas" ] && cap_ant="$beamformee_antennas" -+ [ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[BF-ANTENNA-$cap_ant]" -+ } -+ - # supported Channel widths - vht160_hw=0 - [ "$(($vht_cap & 12))" -eq 4 -a 1 -le "$vht160" ] && \ -@@ -337,16 +405,62 @@ mac80211_hostapd_setup_base() { - esac - - if [ "$enable_ax" != "0" ]; then -+ json_get_vars \ -+ he_su_beamformer:1 \ -+ he_su_beamformee:0 \ -+ he_mu_beamformer:1 \ -+ he_twt_required:0 \ -+ he_spr_sr_control:0 \ -+ he_spr_non_srg_obss_pd_max_offset:1 \ -+ he_bss_color -+ -+ he_phy_cap=$(iw phy "$phy" info | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1) -+ he_phy_cap=${he_phy_cap:2} -+ he_mac_cap=$(iw phy "$phy" info | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1) -+ he_mac_cap=${he_mac_cap:2} -+ - append base_cfg "ieee80211ax=1" "$N" -+ [ -n "$he_bss_color" ] && append base_cfg "he_bss_color=$he_bss_color" "$N" - [ "$hwmode" = "a" ] && { - append base_cfg "he_oper_chwidth=$vht_oper_chwidth" "$N" - append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" - } -+ -+ mac80211_add_he_capabilities \ -+ he_su_beamformer:${he_phy_cap:6:2}:0x80:$he_su_beamformer \ -+ he_su_beamformee:${he_phy_cap:8:2}:0x1:$he_su_beamformee \ -+ he_mu_beamformer:${he_phy_cap:8:2}:0x2:$he_mu_beamformer \ -+ he_spr_sr_control:${he_phy_cap:14:2}:0x1:$he_spr_sr_control \ -+ he_twt_required:${he_mac_cap:0:2}:0x6:$he_twt_required -+ -+ [ "$he_spr_sr_control" -gt 0 ] && append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N" -+ - append base_cfg "he_default_pe_duration=4" "$N" - append base_cfg "he_rts_threshold=1023" "$N" -- append base_cfg "he_su_beamformer=1" "$N" -- append base_cfg "he_su_beamformee=1" "$N" -- append base_cfg "he_mu_beamformer=1" "$N" -+ append base_cfg "he_mu_edca_qos_info_param_count=0" "$N" -+ append base_cfg "he_mu_edca_qos_info_q_ack=0" "$N" -+ append base_cfg "he_mu_edca_qos_info_queue_request=0" "$N" -+ append base_cfg "he_mu_edca_qos_info_txop_request=0" "$N" -+ append base_cfg "he_mu_edca_ac_be_aifsn=8" "$N" -+ append base_cfg "he_mu_edca_ac_be_aci=0" "$N" -+ append base_cfg "he_mu_edca_ac_be_ecwmin=9" "$N" -+ append base_cfg "he_mu_edca_ac_be_ecwmax=10" "$N" -+ append base_cfg "he_mu_edca_ac_be_timer=255" "$N" -+ append base_cfg "he_mu_edca_ac_bk_aifsn=15" "$N" -+ append base_cfg "he_mu_edca_ac_bk_aci=1" "$N" -+ append base_cfg "he_mu_edca_ac_bk_ecwmin=9" "$N" -+ append base_cfg "he_mu_edca_ac_bk_ecwmax=10" "$N" -+ append base_cfg "he_mu_edca_ac_bk_timer=255" "$N" -+ append base_cfg "he_mu_edca_ac_vi_ecwmin=5" "$N" -+ append base_cfg "he_mu_edca_ac_vi_ecwmax=7" "$N" -+ append base_cfg "he_mu_edca_ac_vi_aifsn=5" "$N" -+ append base_cfg "he_mu_edca_ac_vi_aci=2" "$N" -+ append base_cfg "he_mu_edca_ac_vi_timer=255" "$N" -+ append base_cfg "he_mu_edca_ac_vo_aifsn=5" "$N" -+ append base_cfg "he_mu_edca_ac_vo_aci=3" "$N" -+ append base_cfg "he_mu_edca_ac_vo_ecwmin=5" "$N" -+ append base_cfg "he_mu_edca_ac_vo_ecwmax=7" "$N" -+ append base_cfg "he_mu_edca_ac_vo_timer=255" "$N" - fi - - hostapd_prepare_device_config "$hostapd_conf_file" nl80211 -@@ -401,6 +515,7 @@ mac80211_get_addr() { - - mac80211_generate_mac() { - local phy="$1" -+ local multiple_bssid="$2" - local id="${macidx:-0}" - - local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)" -@@ -424,9 +539,16 @@ mac80211_generate_mac() { - local mask6=$6 - - local oIFS="$IFS"; IFS=":"; set -- $ref; IFS="$oIFS" -- -+ [ "$multiple_bssid" -eq 1 ] && { -+ printf "02:%s:%s:%s:%s:%02x" $b1 $2 $3 $4 $5 $macidx -+ return -+ } - macidx=$(($id + 1)) -- [ "$((0x$mask1))" -gt 0 ] && { -+ -+ local use_global=0 -+ [ "$id" -gt 0 -a "$macidx" -le "$num_global_macaddr" ] && use_global=1 -+ -+ [ "$((0x$mask1))" -gt 0 -a "$use_global" -lt 1 ] && { - b1="0x$1" - [ "$id" -gt 0 ] && \ - b1=$(($b1 ^ ((($id - !($b1 & 2)) << 2)) | 0x2)) -@@ -434,7 +556,7 @@ mac80211_generate_mac() { - return - } - -- [ "$((0x$mask6))" -lt 255 ] && { -+ [ "$((0x$mask6))" -lt 255 -a "$use_global" -gt 0 ] && { - printf "%s:%s:%s:%s:%s:%02x" $1 $2 $3 $4 $5 $(( 0x$6 ^ $id )) - return - } -@@ -449,7 +571,7 @@ mac80211_generate_mac() { - find_phy() { - [ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0 - [ -n "$path" ] && { -- phy="$(mac80211_path_to_phy "$path")" -+ phy="$(iwinfo nl80211 phyname "path=$path")" - [ -n "$phy" ] && return 0 - } - [ -n "$macaddr" ] && { -@@ -528,11 +650,12 @@ mac80211_iw_interface_add() { - rc="$?" - } - -- [ "$rc" != 0 ] && wireless_setup_failed INTERFACE_CREATION_FAILED -+ [ "$rc" != 0 ] && echo "Failed to create interface $ifname" - return $rc - } - - mac80211_prepare_vif() { -+ local multiple_bssid=$1 - json_select config - - json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file -@@ -546,7 +669,7 @@ mac80211_prepare_vif() { - json_select .. - - [ -n "$macaddr" ] || { -- macaddr="$(mac80211_generate_mac $phy)" -+ macaddr="$(mac80211_generate_mac $phy $multiple_bssid)" - macidx="$(($macidx + 1))" - } - -@@ -689,14 +812,8 @@ mac80211_prepare_iw_htmode() { - case "$htmode" in - VHT20|HT20) iw_htmode=HT20;; - HT40*|VHT40|VHT160) -- case "$hwmode" in -- a) -- case "$(( ($channel / 4) % 2 ))" in -- 1) iw_htmode="HT40+" ;; -- 0) iw_htmode="HT40-";; -- esac -- ;; -- *) -+ case "$band" in -+ 2g) - case "$htmode" in - HT40+) iw_htmode="HT40+";; - HT40-) iw_htmode="HT40-";; -@@ -709,6 +826,12 @@ mac80211_prepare_iw_htmode() { - ;; - esac - ;; -+ *) -+ case "$(( ($channel / 4) % 2 ))" in -+ 1) iw_htmode="HT40+" ;; -+ 0) iw_htmode="HT40-";; -+ esac -+ ;; - esac - [ "$auto_channel" -gt 0 ] && iw_htmode="HT40+" - ;; -@@ -818,7 +941,6 @@ mac80211_setup_vif() { - mesh) - wireless_vif_parse_encryption - [ -z "$htmode" ] && htmode="NOHT"; -- freq="$(get_freq "$phy" "$channel")" - if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ] || chan_is_dfs "$phy" "$channel"; then - mac80211_setup_supplicant $vif_enable || failed=1 - else -@@ -832,7 +954,6 @@ mac80211_setup_vif() { - adhoc) - wireless_vif_parse_encryption - if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then -- freq="$(get_freq "$phy" "$channel")" - mac80211_setup_supplicant_noctl $vif_enable || failed=1 - else - mac80211_setup_adhoc $vif_enable -@@ -849,10 +970,30 @@ mac80211_setup_vif() { - - get_freq() { - local phy="$1" -- local chan="$2" -- iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep MHz | awk '{print $2}' -+ local channel="$2" -+ local band="$3" -+ -+ case "$band" in -+ 2g) band="1:";; -+ 5g) band="2:";; -+ 60g) band="3:";; -+ 6g) band="4:";; -+ esac -+ -+ iw "$phy" info | awk -v band="$band" -v channel="[$channel]" ' -+ -+$1 ~ /Band/ { -+ band_match = band == $2 -+} -+ -+band_match && $3 == "MHz" && $4 == channel { -+ print $2 -+ exit -+} -+' - } - -+ - chan_is_dfs() { - local phy="$1" - local chan="$2" -@@ -896,7 +1037,9 @@ drv_mac80211_setup() { - country chanbw distance \ - txpower antenna_gain \ - rxantenna txantenna \ -- frag rts beacon_int:100 htmode -+ frag rts beacon_int:100 htmode \ -+ multiple_bssid:0 \ -+ num_global_macaddr - json_get_values basic_rate_list basic_rate - json_get_values scan_list scan_list - json_select .. -@@ -933,7 +1076,7 @@ drv_mac80211_setup() { - done - - # convert channel to frequency -- [ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel")" -+ [ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel" "$band")" - - [ -n "$country" ] && { - iw reg get | grep -q "^country $country:" || { -@@ -958,6 +1101,7 @@ drv_mac80211_setup() { - set_default txantenna 0xffffffff - set_default distance 0 - set_default antenna_gain 0 -+ set_default num_global_macaddr 1 - - [ "$txantenna" = "all" ] && txantenna=0xffffffff - [ "$rxantenna" = "all" ] && rxantenna=0xffffffff -@@ -989,7 +1133,7 @@ drv_mac80211_setup() { - mac80211_prepare_iw_htmode - for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif - NEWAPLIST= -- for_each_interface "ap" mac80211_prepare_vif -+ for_each_interface "ap" mac80211_prepare_vif ${multiple_bssid} - NEW_MD5=$(test -e "${hostapd_conf_file}" && md5sum ${hostapd_conf_file}) - OLD_MD5=$(uci -q -P /var/state get wireless._${phy}.md5) - if [ "${NEWAPLIST}" != "${OLDAPLIST}" ]; then -diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh -index 3e99f06693..6aa46b0c74 100644 ---- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh -+++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh -@@ -1,5 +1,4 @@ - #!/bin/sh --. /lib/netifd/mac80211.sh - - append DRIVERS "mac80211" - -@@ -11,7 +10,7 @@ lookup_phy() { - local devpath - config_get devpath "$device" path - [ -n "$devpath" ] && { -- phy="$(mac80211_path_to_phy "$devpath")" -+ phy="$(iwinfo nl80211 phyname "path=$devpath")" - [ -n "$phy" ] && return - } - -@@ -57,6 +56,85 @@ check_mac80211_device() { - [ "$phy" = "$dev" ] && found=1 - } - -+ -+__get_band_defaults() { -+ local phy="$1" -+ -+ ( iw phy "$phy" info; echo ) | awk ' -+BEGIN { -+ bands = "" -+} -+ -+($1 == "Band" || $1 == "") && band { -+ if (channel) { -+ mode="NOHT" -+ if (ht) mode="HT20" -+ if (vht && band != "1:") mode="VHT80" -+ if (he) mode="HE80" -+ if (he && band == "1:") mode="HE20" -+ sub("\\[", "", channel) -+ sub("\\]", "", channel) -+ bands = bands band channel ":" mode " " -+ } -+ band="" -+} -+ -+$1 == "Band" { -+ band = $2 -+ channel = "" -+ vht = "" -+ ht = "" -+ he = "" -+} -+ -+$0 ~ "Capabilities:" { -+ ht=1 -+} -+ -+$0 ~ "VHT Capabilities" { -+ vht=1 -+} -+ -+$0 ~ "HE Iftypes" { -+ he=1 -+} -+ -+$1 == "*" && $3 == "MHz" && $0 !~ /disabled/ && band && !channel { -+ channel = $4 -+} -+ -+END { -+ print bands -+}' -+} -+ -+get_band_defaults() { -+ local phy="$1" -+ -+ for c in $(__get_band_defaults "$phy"); do -+ local band="${c%%:*}" -+ c="${c#*:}" -+ local chan="${c%%:*}" -+ c="${c#*:}" -+ local mode="${c%%:*}" -+ -+ case "$band" in -+ 1) band=2g;; -+ 2) band=5g;; -+ 3) band=60g;; -+ 4) band=6g;; -+ *) band="";; -+ esac -+ -+ [ -n "$band" ] || continue -+ [ -n "$mode_band" -a "$band" = "6g" ] && return -+ -+ mode_band="$band" -+ channel="$chan" -+ htmode="$mode" -+ done -+} -+ - detect_mac80211() { - devidx=0 - config_load wireless -@@ -75,28 +153,14 @@ detect_mac80211() { - config_foreach check_mac80211_device wifi-device - [ "$found" -gt 0 ] && continue - -- mode_band="g" -- channel="11" -+ mode_band="" -+ channel="" - htmode="" - ht_capab="" - -- iw phy "$dev" info | grep -q 'Capabilities:' && htmode=HT20 -- -- iw phy "$dev" info | grep -q '\* 5... MHz \[' && { -- mode_band="a" -- channel=$(iw phy "$dev" info | grep '\* 5... MHz \[' | grep '(disabled)' -v -m 1 | sed 's/[^[]*\[\|\].*//g') -- iw phy "$dev" info | grep -q 'VHT Capabilities' && htmode="VHT80" -- } -- -- iw phy "$dev" info | grep -q '\* 5.... MHz \[' && { -- mode_band="ad" -- channel=$(iw phy "$dev" info | grep '\* 5.... MHz \[' | grep '(disabled)' -v -m 1 | sed 's/[^[]*\[\|\|\].*//g') -- iw phy "$dev" info | grep -q 'Capabilities:' && htmode="HT20" -- } -+ get_band_defaults "$dev" - -- [ -n "$htmode" ] && ht_capab="set wireless.radio${devidx}.htmode=$htmode" -- -- path="$(mac80211_phy_to_path "$dev")" -+ path="$(iwinfo nl80211 path "$dev")" - if [ -n "$path" ]; then - dev_id="set wireless.radio${devidx}.path='$path'" - else -@@ -106,10 +170,10 @@ detect_mac80211() { - uci -q batch <<-EOF - set wireless.radio${devidx}=wifi-device - set wireless.radio${devidx}.type=mac80211 -- set wireless.radio${devidx}.channel=${channel} -- set wireless.radio${devidx}.hwmode=11${mode_band} - ${dev_id} -- ${ht_capab} -+ set wireless.radio${devidx}.channel=${channel} -+ set wireless.radio${devidx}.band=${mode_band} -+ set wireless.radio${devidx}.htmode=$htmode - set wireless.radio${devidx}.disabled=1 - - set wireless.default_radio${devidx}=wifi-iface -diff --git a/package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch b/package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch -deleted file mode 100644 -index d1d6c9e2e3..0000000000 ---- a/package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch -+++ /dev/null -@@ -1,53 +0,0 @@ --From: Christian Lamparter --Date: Sat, 16 Nov 2019 19:25:24 +0100 --Subject: [PATCH] owl_loader: compatibility patch -- --This patch includes OpenWrt specific changes that are --not included in the upstream owl-loader. -- --This includes a platform data handling changes for ar71xx. -- --Signed-off-by: Christian Lamparter -- ----- a/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c --+++ b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c --@@ -103,6 +103,7 @@ static void owl_fw_cb(const struct firmw -- { -- struct pci_dev *pdev = (struct pci_dev *)context; -- struct owl_ctx *ctx = (struct owl_ctx *)pci_get_drvdata(pdev); --+ struct ath9k_platform_data *pdata = dev_get_platdata(&pdev->dev); -- struct pci_bus *bus; -- -- complete(&ctx->eeprom_load); --@@ -118,6 +119,16 @@ static void owl_fw_cb(const struct firmw -- goto release; -- } -- --+ if (pdata) { --+ memcpy(pdata->eeprom_data, fw->data, fw->size); --+ --+ /* --+ * eeprom has been successfully loaded - pass the data to ath9k --+ * but remove the eeprom_name, so it doesn't try to load it too. --+ */ --+ pdata->eeprom_name = NULL; --+ } --+ -- if (ath9k_pci_fixup(pdev, (const u16 *)fw->data, fw->size)) -- goto release; -- --@@ -137,8 +148,14 @@ release: -- static const char *owl_get_eeprom_name(struct pci_dev *pdev) -- { -- struct device *dev = &pdev->dev; --+ struct ath9k_platform_data *pdata; -- char *eeprom_name; -- --+ /* try the existing platform data first */ --+ pdata = dev_get_platdata(dev); --+ if (pdata && pdata->eeprom_name) --+ return pdata->eeprom_name; --+ -- dev_dbg(dev, "using auto-generated eeprom filename\n"); -- -- eeprom_name = devm_kzalloc(dev, EEPROM_FILENAME_LEN, GFP_KERNEL); -diff --git a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch -index bf87d3551a..3c9180b113 100644 ---- a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch -+++ b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch -@@ -82,7 +82,7 @@ - help - --- a/local-symbols - +++ b/local-symbols --@@ -85,6 +85,7 @@ ADM8211= -+@@ -86,6 +86,7 @@ ADM8211= - ATH_COMMON= - WLAN_VENDOR_ATH= - ATH_DEBUG= -diff --git a/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch b/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch -similarity index 97% -rename from package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch -rename to package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch -index de6f9d9bb0..9ce44fd288 100644 ---- a/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch -+++ b/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch -@@ -37,7 +37,7 @@ - void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); - --- a/local-symbols - +++ b/local-symbols --@@ -142,6 +142,7 @@ ATH10K_SNOC= -+@@ -145,6 +145,7 @@ ATH10K_SNOC= - ATH10K_DEBUG= - ATH10K_DEBUGFS= - ATH10K_SPECTRAL= -diff --git a/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch -rename to package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch -diff --git a/package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch b/package/kernel/mac80211/patches/ath10k/922-ath10k-increase-rx-buffer-size-to-2048.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch -rename to package/kernel/mac80211/patches/ath10k/922-ath10k-increase-rx-buffer-size-to-2048.patch -diff --git a/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch -rename to package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch -diff --git a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch -similarity index 99% -rename from package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch -rename to package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch -index ce8effe3c3..fa007e73a1 100644 ---- a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch -+++ b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch -@@ -114,7 +114,7 @@ v13: - ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o - --- a/local-symbols - +++ b/local-symbols --@@ -145,6 +145,7 @@ ATH10K_DEBUG= -+@@ -146,6 +146,7 @@ ATH10K_DEBUG= - ATH10K_DEBUGFS= - ATH10K_SPECTRAL= - ATH10K_THERMAL= -diff --git a/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch -rename to package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch -diff --git a/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch b/package/kernel/mac80211/patches/ath10k/980-ath10k-fix-max-antenna-gain-unit.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch -rename to package/kernel/mac80211/patches/ath10k/980-ath10k-fix-max-antenna-gain-unit.patch -diff --git a/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch b/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch -rename to package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch -diff --git a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch -new file mode 100644 -index 0000000000..5f427f6b8f ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch -@@ -0,0 +1,42 @@ -+From 22fb5991a44c78ff18ec0082dc90c809356eb893 Mon Sep 17 00:00:00 2001 -+From: Ansuel Smith -+Date: Sun, 27 Sep 2020 19:23:35 +0200 -+Subject: [PATCH 1/2] ath10k: Try to get mac-address from dts -+ -+Most of embedded device that have the ath10k wifi integrated store the -+mac-address in nvmem partitions. Try to fetch the mac-address using the -+standard 'of_get_mac_address' than in all the check also try to fetch the -+address using the nvmem api searching for a defined 'mac-address' cell. -+Mac-address defined in the dts have priority than any other address found. -+ -+Tested-on: QCA9984 hw1.0 PCI 10.4 -+ -+Signed-off-by: Ansuel Smith -+--- -+ drivers/net/wireless/ath/ath10k/core.c | 10 ++++++++++ -+ 1 file changed, 10 insertions(+) -+ -+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c -+index 5f4e12196..9ed7b9883 100644 -+--- a/drivers/net/wireless/ath/ath10k/core.c -++++ b/drivers/net/wireless/ath/ath10k/core.c -+@@ -8,6 +8,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -3062,6 +3068,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar) -+ -+ device_get_mac_address(ar->dev, ar->mac_addr, sizeof(ar->mac_addr)); -+ -++ of_get_mac_address(ar->dev->of_node, ar->mac_addr); -++ -+ ret = ath10k_core_init_firmware_features(ar); -+ if (ret) { -+ ath10k_err(ar, "fatal problem with firmware features: %d\n", -+-- -+2.27.0 -+ -diff --git a/package/kernel/mac80211/patches/ath/201-ath5k-WAR-for-AR71xx-PCI-bug.patch b/package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/201-ath5k-WAR-for-AR71xx-PCI-bug.patch -rename to package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch -diff --git a/package/kernel/mac80211/patches/ath/411-ath5k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/411-ath5k_allow_adhoc_and_ap.patch -rename to package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch -diff --git a/package/kernel/mac80211/patches/ath/420-ath5k_disable_fast_cc.patch b/package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/420-ath5k_disable_fast_cc.patch -rename to package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch -diff --git a/package/kernel/mac80211/patches/ath/430-add_ath5k_platform.patch b/package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/430-add_ath5k_platform.patch -rename to package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch -diff --git a/package/kernel/mac80211/patches/ath/432-ath5k_add_pciids.patch b/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/432-ath5k_add_pciids.patch -rename to package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch -diff --git a/package/kernel/mac80211/patches/ath/440-ath5k_channel_bw_debugfs.patch b/package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/440-ath5k_channel_bw_debugfs.patch -rename to package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch -diff --git a/package/kernel/mac80211/patches/ath/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch -rename to package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch -diff --git a/package/kernel/mac80211/patches/ath/351-ath9k_hw-issue-external-reset-for-QCA955x.patch b/package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/351-ath9k_hw-issue-external-reset-for-QCA955x.patch -rename to package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch -diff --git a/package/kernel/mac80211/patches/ath/354-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/354-ath9k-force-rx_clear-when-disabling-rx.patch -rename to package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch -diff --git a/package/kernel/mac80211/patches/ath/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch -rename to package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch -diff --git a/package/kernel/mac80211/patches/ath/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch b/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch -rename to package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch -diff --git a/package/kernel/mac80211/patches/ath/401-ath9k_blink_default.patch b/package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/401-ath9k_blink_default.patch -rename to package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch -diff --git a/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch -rename to package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch -diff --git a/package/kernel/mac80211/patches/ath/450-ath9k-enabled-MFP-capability-unconditionally.patch b/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/450-ath9k-enabled-MFP-capability-unconditionally.patch -rename to package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch -diff --git a/package/kernel/mac80211/patches/ath/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/500-ath9k_eeprom_debugfs.patch -rename to package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch -diff --git a/package/kernel/mac80211/patches/ath/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/501-ath9k_ahb_init.patch -rename to package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch -diff --git a/package/kernel/mac80211/patches/ath/510-ath9k_intr_mitigation_tweak.patch b/package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/510-ath9k_intr_mitigation_tweak.patch -rename to package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch -diff --git a/package/kernel/mac80211/patches/ath/511-ath9k_reduce_rxbuf.patch b/package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/511-ath9k_reduce_rxbuf.patch -rename to package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch -diff --git a/package/kernel/mac80211/patches/ath/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/512-ath9k_channelbw_debugfs.patch -rename to package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch -diff --git a/package/kernel/mac80211/patches/ath/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/513-ath9k_add_pci_ids.patch -rename to package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch -diff --git a/package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch -rename to package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch -diff --git a/package/kernel/mac80211/patches/ath/531-ath9k_extra_platform_leds.patch b/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/531-ath9k_extra_platform_leds.patch -rename to package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch -diff --git a/package/kernel/mac80211/patches/ath/540-ath9k_reduce_ani_interval.patch b/package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/540-ath9k_reduce_ani_interval.patch -rename to package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch -diff --git a/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch -rename to package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch -diff --git a/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch -rename to package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch -diff --git a/package/kernel/mac80211/patches/ath/544-ath9k-ar933x-usb-hang-workaround.patch b/package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/544-ath9k-ar933x-usb-hang-workaround.patch -rename to package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch -diff --git a/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch b/package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch -rename to package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch -diff --git a/package/kernel/mac80211/patches/ath/547-ath9k_led_defstate_fix.patch b/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/547-ath9k_led_defstate_fix.patch -rename to package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch -diff --git a/package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch -rename to package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch -diff --git a/package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch -rename to package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch -diff --git a/package/kernel/mac80211/patches/ath/550-ath9k-disable-bands-via-dt.patch b/package/kernel/mac80211/patches/ath9k/550-ath9k-disable-bands-via-dt.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/550-ath9k-disable-bands-via-dt.patch -rename to package/kernel/mac80211/patches/ath9k/550-ath9k-disable-bands-via-dt.patch -diff --git a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch b/package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch -similarity index 99% -rename from package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch -rename to package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch -index acb9ad443c..cd2bdbf1a0 100644 ---- a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch -+++ b/package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch -@@ -371,7 +371,7 @@ - - --- a/local-symbols - +++ b/local-symbols --@@ -112,6 +112,7 @@ ATH9K_WOW= -+@@ -113,6 +113,7 @@ ATH9K_WOW= - ATH9K_RFKILL= - ATH9K_CHANNEL_CONTEXT= - ATH9K_PCOEM= -diff --git a/package/kernel/mac80211/patches/ath/552-ahb_of.patch b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/552-ahb_of.patch -rename to package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch -diff --git a/package/kernel/mac80211/patches/ath/553-ath9k_of_gpio_mask.patch b/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/553-ath9k_of_gpio_mask.patch -rename to package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch -diff --git a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch -index e74d9a9aa0..1c52132da6 100644 ---- a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch -+++ b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch -@@ -1,6 +1,6 @@ - --- a/local-symbols - +++ b/local-symbols --@@ -332,6 +332,7 @@ RT2X00_LIB_FIRMWARE= -+@@ -333,6 +333,7 @@ RT2X00_LIB_FIRMWARE= - RT2X00_LIB_CRYPTO= - RT2X00_LIB_LEDS= - RT2X00_LIB_DEBUGFS= -diff --git a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch -index b5b2c61037..79f99ffdf4 100644 ---- a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch -+++ b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch -@@ -1,19 +1,18 @@ - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -990,8 +990,13 @@ static void rt2x00lib_rate(struct ieee80 -+@@ -990,6 +990,12 @@ static void rt2x00lib_rate(struct ieee80 - - void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) - { - + struct rt2x00_platform_data *pdata; -- const char *mac_addr; -- -++ - + pdata = rt2x00dev->dev->platform_data; - + if (pdata && pdata->mac_address) - + ether_addr_copy(eeprom_mac_addr, pdata->mac_address); - + -- mac_addr = of_get_mac_address(rt2x00dev->dev->of_node); -- if (!IS_ERR(mac_addr)) -- ether_addr_copy(eeprom_mac_addr, mac_addr); -+ of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr); -+ -+ if (!is_valid_ether_addr(eeprom_mac_addr)) { - --- a/include/linux/rt2x00_platform.h - +++ b/include/linux/rt2x00_platform.h - @@ -14,6 +14,7 @@ -diff --git a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch b/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch -deleted file mode 100644 -index ca02dfb06f..0000000000 ---- a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch -+++ /dev/null -@@ -1,699 +0,0 @@ ----- a/net/mac80211/Makefile --+++ b/net/mac80211/Makefile --@@ -7,7 +7,6 @@ mac80211-y := \ -- driver-ops.o \ -- sta_info.o \ -- wep.o \ --- aead_api.o \ -- wpa.o \ -- scan.o offchannel.o \ -- ht.o agg-tx.o agg-rx.o \ --@@ -19,8 +18,8 @@ mac80211-y := \ -- rate.o \ -- michael.o \ -- tkip.o \ --+ aes_ccm.o \ -- aes_cmac.o \ --- aes_gmac.o \ -- fils_aead.o \ -- cfg.o \ -- ethtool.o \ ----- a/net/mac80211/aead_api.c --+++ /dev/null --@@ -1,113 +0,0 @@ ---// SPDX-License-Identifier: GPL-2.0-only ---/* --- * Copyright 2003-2004, Instant802 Networks, Inc. --- * Copyright 2005-2006, Devicescape Software, Inc. --- * Copyright 2014-2015, Qualcomm Atheros, Inc. --- * --- * Rewrite: Copyright (C) 2013 Linaro Ltd --- */ --- ---#include ---#include ---#include ---#include ---#include --- ---#include "aead_api.h" --- ---int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, --- u8 *data, size_t data_len, u8 *mic) ---{ --- size_t mic_len = crypto_aead_authsize(tfm); --- struct scatterlist sg[3]; --- struct aead_request *aead_req; --- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); --- u8 *__aad; --- int ret; --- --- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); --- if (!aead_req) --- return -ENOMEM; --- --- __aad = (u8 *)aead_req + reqsize; --- memcpy(__aad, aad, aad_len); --- --- sg_init_table(sg, 3); --- sg_set_buf(&sg[0], __aad, aad_len); --- sg_set_buf(&sg[1], data, data_len); --- sg_set_buf(&sg[2], mic, mic_len); --- --- aead_request_set_tfm(aead_req, tfm); --- aead_request_set_crypt(aead_req, sg, sg, data_len, b_0); --- aead_request_set_ad(aead_req, sg[0].length); --- --- ret = crypto_aead_encrypt(aead_req); --- kfree_sensitive(aead_req); --- --- return ret; ---} --- ---int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, --- u8 *data, size_t data_len, u8 *mic) ---{ --- size_t mic_len = crypto_aead_authsize(tfm); --- struct scatterlist sg[3]; --- struct aead_request *aead_req; --- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); --- u8 *__aad; --- int err; --- --- if (data_len == 0) --- return -EINVAL; --- --- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); --- if (!aead_req) --- return -ENOMEM; --- --- __aad = (u8 *)aead_req + reqsize; --- memcpy(__aad, aad, aad_len); --- --- sg_init_table(sg, 3); --- sg_set_buf(&sg[0], __aad, aad_len); --- sg_set_buf(&sg[1], data, data_len); --- sg_set_buf(&sg[2], mic, mic_len); --- --- aead_request_set_tfm(aead_req, tfm); --- aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0); --- aead_request_set_ad(aead_req, sg[0].length); --- --- err = crypto_aead_decrypt(aead_req); --- kfree_sensitive(aead_req); --- --- return err; ---} --- ---struct crypto_aead * ---aead_key_setup_encrypt(const char *alg, const u8 key[], --- size_t key_len, size_t mic_len) ---{ --- struct crypto_aead *tfm; --- int err; --- --- tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC); --- if (IS_ERR(tfm)) --- return tfm; --- --- err = crypto_aead_setkey(tfm, key, key_len); --- if (err) --- goto free_aead; --- err = crypto_aead_setauthsize(tfm, mic_len); --- if (err) --- goto free_aead; --- --- return tfm; --- ---free_aead: --- crypto_free_aead(tfm); --- return ERR_PTR(err); ---} --- ---void aead_key_free(struct crypto_aead *tfm) ---{ --- crypto_free_aead(tfm); ---} ----- a/net/mac80211/aead_api.h --+++ /dev/null --@@ -1,23 +0,0 @@ ---/* SPDX-License-Identifier: GPL-2.0-only */ --- ---#ifndef _AEAD_API_H ---#define _AEAD_API_H --- ---#include ---#include --- ---struct crypto_aead * ---aead_key_setup_encrypt(const char *alg, const u8 key[], --- size_t key_len, size_t mic_len); --- ---int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, --- size_t aad_len, u8 *data, --- size_t data_len, u8 *mic); --- ---int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, --- size_t aad_len, u8 *data, --- size_t data_len, u8 *mic); --- ---void aead_key_free(struct crypto_aead *tfm); --- ---#endif /* _AEAD_API_H */ ----- a/net/mac80211/aes_ccm.h --+++ b/net/mac80211/aes_ccm.h --@@ -7,39 +7,17 @@ -- #ifndef AES_CCM_H -- #define AES_CCM_H -- ---#include "aead_api.h" --+#include -- ---#define CCM_AAD_LEN 32 --- ---static inline struct crypto_aead * ---ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len) ---{ --- return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len); ---} --- ---static inline int ---ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, --- u8 *b_0, u8 *aad, u8 *data, --- size_t data_len, u8 *mic) ---{ --- return aead_encrypt(tfm, b_0, aad + 2, --- be16_to_cpup((__be16 *)aad), --- data, data_len, mic); ---} --- ---static inline int ---ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, --- u8 *b_0, u8 *aad, u8 *data, --- size_t data_len, u8 *mic) ---{ --- return aead_decrypt(tfm, b_0, aad + 2, --- be16_to_cpup((__be16 *)aad), --- data, data_len, mic); ---} --- ---static inline void ieee80211_aes_key_free(struct crypto_aead *tfm) ---{ --- return aead_key_free(tfm); ---} --+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], --+ size_t key_len, --+ size_t mic_len); --+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, --+ u8 *data, size_t data_len, u8 *mic, --+ size_t mic_len); --+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, --+ u8 *data, size_t data_len, u8 *mic, --+ size_t mic_len); --+void ieee80211_aes_key_free(struct crypto_cipher *tfm); -- -- #endif /* AES_CCM_H */ ----- /dev/null --+++ b/net/mac80211/aes_gcm.c --@@ -0,0 +1,109 @@ --+/* --+ * Copyright 2014-2015, Qualcomm Atheros, Inc. --+ * --+ * This program is free software; you can redistribute it and/or modify --+ * it under the terms of the GNU General Public License version 2 as --+ * published by the Free Software Foundation. --+ */ --+ --+#include --+#include --+#include --+#include --+ --+#include --+#include "key.h" --+#include "aes_gcm.h" --+ --+int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, --+ u8 *data, size_t data_len, u8 *mic) --+{ --+ struct scatterlist sg[3]; --+ struct aead_request *aead_req; --+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); --+ u8 *__aad; --+ --+ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); --+ if (!aead_req) --+ return -ENOMEM; --+ --+ __aad = (u8 *)aead_req + reqsize; --+ memcpy(__aad, aad, GCM_AAD_LEN); --+ --+ sg_init_table(sg, 3); --+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); --+ sg_set_buf(&sg[1], data, data_len); --+ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); --+ --+ aead_request_set_tfm(aead_req, tfm); --+ aead_request_set_crypt(aead_req, sg, sg, data_len, j_0); --+ aead_request_set_ad(aead_req, sg[0].length); --+ --+ crypto_aead_encrypt(aead_req); --+ kzfree(aead_req); --+ return 0; --+} --+ --+int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, --+ u8 *data, size_t data_len, u8 *mic) --+{ --+ struct scatterlist sg[3]; --+ struct aead_request *aead_req; --+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); --+ u8 *__aad; --+ int err; --+ --+ if (data_len == 0) --+ return -EINVAL; --+ --+ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); --+ if (!aead_req) --+ return -ENOMEM; --+ --+ __aad = (u8 *)aead_req + reqsize; --+ memcpy(__aad, aad, GCM_AAD_LEN); --+ --+ sg_init_table(sg, 3); --+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); --+ sg_set_buf(&sg[1], data, data_len); --+ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); --+ --+ aead_request_set_tfm(aead_req, tfm); --+ aead_request_set_crypt(aead_req, sg, sg, --+ data_len + IEEE80211_GCMP_MIC_LEN, j_0); --+ aead_request_set_ad(aead_req, sg[0].length); --+ --+ err = crypto_aead_decrypt(aead_req); --+ kzfree(aead_req); --+ --+ return err; --+} --+ --+struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], --+ size_t key_len) --+{ --+ struct crypto_aead *tfm; --+ int err; --+ --+ tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); --+ if (IS_ERR(tfm)) --+ return tfm; --+ --+ err = crypto_aead_setkey(tfm, key, key_len); --+ if (err) --+ goto free_aead; --+ err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN); --+ if (err) --+ goto free_aead; --+ --+ return tfm; --+ --+free_aead: --+ crypto_free_aead(tfm); --+ return ERR_PTR(err); --+} --+ --+void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) --+{ --+ crypto_free_aead(tfm); --+} ----- a/net/mac80211/aes_gcm.h --+++ b/net/mac80211/aes_gcm.h --@@ -6,38 +6,30 @@ -- #ifndef AES_GCM_H -- #define AES_GCM_H -- ---#include "aead_api.h" --+#include -- ---#define GCM_AAD_LEN 32 --- ---static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, --- u8 *j_0, u8 *aad, u8 *data, --- size_t data_len, u8 *mic) --+static inline void --+ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, --+ u8 *data, size_t data_len, u8 *mic) -- { --- return aead_encrypt(tfm, j_0, aad + 2, --- be16_to_cpup((__be16 *)aad), --- data, data_len, mic); -- } -- ---static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, --- u8 *j_0, u8 *aad, u8 *data, --- size_t data_len, u8 *mic) --+static inline int --+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, --+ u8 *data, size_t data_len, u8 *mic) -- { --- return aead_decrypt(tfm, j_0, aad + 2, --- be16_to_cpup((__be16 *)aad), --- data, data_len, mic); --+ return -EOPNOTSUPP; -- } -- -- static inline struct crypto_aead * -- ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len) -- { --- return aead_key_setup_encrypt("gcm(aes)", key, --- key_len, IEEE80211_GCMP_MIC_LEN); --+ return NULL; -- } -- ---static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) --+static inline void --+ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) -- { --- return aead_key_free(tfm); -- } -- -- #endif /* AES_GCM_H */ ----- a/net/mac80211/wpa.c --+++ b/net/mac80211/wpa.c --@@ -312,7 +312,8 @@ ieee80211_crypto_tkip_decrypt(struct iee -- } -- -- ---static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad) --+static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, --+ u16 data_len) -- { -- __le16 mask_fc; -- int a4_included, mgmt; --@@ -342,14 +343,8 @@ static void ccmp_special_blocks(struct s -- else -- qos_tid = 0; -- --- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC --- * mode authentication are not allowed to collide, yet both are derived --- * from this vector b_0. We only set L := 1 here to indicate that the --- * data size can be represented in (L+1) bytes. The CCM layer will take --- * care of storing the data length in the top (L+1) bytes and setting --- * and clearing the other bits as is required to derive the two IVs. --- */ --- b_0[0] = 0x1; --+ /* First block, b_0 */ --+ b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ -- -- /* Nonce: Nonce Flags | A2 | PN -- * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) --@@ -357,6 +352,8 @@ static void ccmp_special_blocks(struct s -- b_0[1] = qos_tid | (mgmt << 4); -- memcpy(&b_0[2], hdr->addr2, ETH_ALEN); -- memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); --+ /* l(m) */ --+ put_unaligned_be16(data_len, &b_0[14]); -- -- /* AAD (extra authenticate-only data) / masked 802.11 header -- * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ --@@ -413,7 +410,7 @@ static int ccmp_encrypt_skb(struct ieee8 -- u8 *pos; -- u8 pn[6]; -- u64 pn64; --- u8 aad[CCM_AAD_LEN]; --+ u8 aad[2 * AES_BLOCK_SIZE]; -- u8 b_0[AES_BLOCK_SIZE]; -- -- if (info->control.hw_key && --@@ -468,9 +465,11 @@ static int ccmp_encrypt_skb(struct ieee8 -- return 0; -- -- pos += IEEE80211_CCMP_HDR_LEN; --- ccmp_special_blocks(skb, pn, b_0, aad); --- return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, --- skb_put(skb, mic_len)); --+ ccmp_special_blocks(skb, pn, b_0, aad, len); --+ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, --+ skb_put(skb, mic_len), mic_len); --+ --+ return 0; -- } -- -- --@@ -543,13 +542,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee -- u8 aad[2 * AES_BLOCK_SIZE]; -- u8 b_0[AES_BLOCK_SIZE]; -- /* hardware didn't decrypt/verify MIC */ --- ccmp_special_blocks(skb, pn, b_0, aad); --+ ccmp_special_blocks(skb, pn, b_0, aad, data_len); -- -- if (ieee80211_aes_ccm_decrypt( -- key->u.ccmp.tfm, b_0, aad, -- skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, -- data_len, --- skb->data + skb->len - mic_len)) --+ skb->data + skb->len - mic_len, mic_len)) -- return RX_DROP_UNUSABLE; -- } -- --@@ -646,7 +645,7 @@ static int gcmp_encrypt_skb(struct ieee8 -- u8 *pos; -- u8 pn[6]; -- u64 pn64; --- u8 aad[GCM_AAD_LEN]; --+ u8 aad[2 * AES_BLOCK_SIZE]; -- u8 j_0[AES_BLOCK_SIZE]; -- -- if (info->control.hw_key && --@@ -703,8 +702,10 @@ static int gcmp_encrypt_skb(struct ieee8 -- -- pos += IEEE80211_GCMP_HDR_LEN; -- gcmp_special_blocks(skb, pn, j_0, aad); --- return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, --- skb_put(skb, IEEE80211_GCMP_MIC_LEN)); --+ ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, --+ skb_put(skb, IEEE80211_GCMP_MIC_LEN)); --+ --+ return 0; -- } -- -- ieee80211_tx_result --@@ -1133,9 +1134,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct -- struct ieee80211_key *key = tx->key; -- struct ieee80211_mmie_16 *mmie; -- struct ieee80211_hdr *hdr; --- u8 aad[GMAC_AAD_LEN]; --+ u8 aad[20]; -- u64 pn64; --- u8 nonce[GMAC_NONCE_LEN]; --+ u8 nonce[12]; -- -- if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) -- return TX_DROP; --@@ -1181,7 +1182,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct -- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); -- struct ieee80211_key *key = rx->key; -- struct ieee80211_mmie_16 *mmie; --- u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN]; --+ u8 aad[20], *mic, ipn[6], nonce[12]; -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -- -- if (!ieee80211_is_mgmt(hdr->frame_control)) ----- /dev/null --+++ b/net/mac80211/aes_ccm.c --@@ -0,0 +1,144 @@ --+/* --+ * Copyright 2003-2004, Instant802 Networks, Inc. --+ * Copyright 2005-2006, Devicescape Software, Inc. --+ * --+ * Rewrite: Copyright (C) 2013 Linaro Ltd --+ * --+ * This program is free software; you can redistribute it and/or modify --+ * it under the terms of the GNU General Public License version 2 as --+ * published by the Free Software Foundation. --+ */ --+ --+#include --+#include --+#include --+#include --+#include --+ --+#include --+#include "key.h" --+#include "aes_ccm.h" --+ --+static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0, --+ u8 *a, u8 *b) --+{ --+ int i; --+ --+ crypto_cipher_encrypt_one(tfm, b, b_0); --+ --+ /* Extra Authenticate-only data (always two AES blocks) */ --+ for (i = 0; i < AES_BLOCK_SIZE; i++) --+ aad[i] ^= b[i]; --+ crypto_cipher_encrypt_one(tfm, b, aad); --+ --+ aad += AES_BLOCK_SIZE; --+ --+ for (i = 0; i < AES_BLOCK_SIZE; i++) --+ aad[i] ^= b[i]; --+ crypto_cipher_encrypt_one(tfm, a, aad); --+ --+ /* Mask out bits from auth-only-b_0 */ --+ b_0[0] &= 0x07; --+ --+ /* S_0 is used to encrypt T (= MIC) */ --+ b_0[14] = 0; --+ b_0[15] = 0; --+ crypto_cipher_encrypt_one(tfm, s_0, b_0); --+} --+ --+ --+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, --+ u8 *data, size_t data_len, u8 *mic, --+ size_t mic_len) --+{ --+ int i, j, last_len, num_blocks; --+ u8 b[AES_BLOCK_SIZE]; --+ u8 s_0[AES_BLOCK_SIZE]; --+ u8 e[AES_BLOCK_SIZE]; --+ u8 *pos, *cpos; --+ --+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); --+ last_len = data_len % AES_BLOCK_SIZE; --+ aes_ccm_prepare(tfm, b_0, aad, s_0, b, b); --+ --+ /* Process payload blocks */ --+ pos = data; --+ cpos = data; --+ for (j = 1; j <= num_blocks; j++) { --+ int blen = (j == num_blocks && last_len) ? --+ last_len : AES_BLOCK_SIZE; --+ --+ /* Authentication followed by encryption */ --+ for (i = 0; i < blen; i++) --+ b[i] ^= pos[i]; --+ crypto_cipher_encrypt_one(tfm, b, b); --+ --+ b_0[14] = (j >> 8) & 0xff; --+ b_0[15] = j & 0xff; --+ crypto_cipher_encrypt_one(tfm, e, b_0); --+ for (i = 0; i < blen; i++) --+ *cpos++ = *pos++ ^ e[i]; --+ } --+ --+ for (i = 0; i < mic_len; i++) --+ mic[i] = b[i] ^ s_0[i]; --+} --+ --+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, --+ u8 *data, size_t data_len, u8 *mic, --+ size_t mic_len) --+{ --+ int i, j, last_len, num_blocks; --+ u8 *pos, *cpos; --+ u8 a[AES_BLOCK_SIZE]; --+ u8 b[AES_BLOCK_SIZE]; --+ u8 s_0[AES_BLOCK_SIZE]; --+ --+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); --+ last_len = data_len % AES_BLOCK_SIZE; --+ aes_ccm_prepare(tfm, b_0, aad, s_0, a, b); --+ --+ /* Process payload blocks */ --+ cpos = data; --+ pos = data; --+ for (j = 1; j <= num_blocks; j++) { --+ int blen = (j == num_blocks && last_len) ? --+ last_len : AES_BLOCK_SIZE; --+ --+ /* Decryption followed by authentication */ --+ b_0[14] = (j >> 8) & 0xff; --+ b_0[15] = j & 0xff; --+ crypto_cipher_encrypt_one(tfm, b, b_0); --+ for (i = 0; i < blen; i++) { --+ *pos = *cpos++ ^ b[i]; --+ a[i] ^= *pos++; --+ } --+ crypto_cipher_encrypt_one(tfm, a, a); --+ } --+ --+ for (i = 0; i < mic_len; i++) { --+ if ((mic[i] ^ s_0[i]) != a[i]) --+ return -1; --+ } --+ --+ return 0; --+} --+ --+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], --+ size_t key_len, --+ size_t mic_len) --+{ --+ struct crypto_cipher *tfm; --+ --+ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); --+ if (!IS_ERR(tfm)) --+ crypto_cipher_setkey(tfm, key, key_len); --+ --+ return tfm; --+} --+ --+ --+void ieee80211_aes_key_free(struct crypto_cipher *tfm) --+{ --+ crypto_free_cipher(tfm); --+} ----- a/net/mac80211/Kconfig --+++ b/net/mac80211/Kconfig --@@ -6,8 +6,6 @@ config MAC80211 -- depends on CRYPTO -- select BPAUTO_CRYPTO_LIB_ARC4 -- depends on CRYPTO_AES --- depends on CRYPTO_CCM --- depends on CRYPTO_GCM -- depends on CRYPTO_CMAC -- depends on CRC32 -- help ----- a/net/mac80211/aes_gmac.h --+++ b/net/mac80211/aes_gmac.h --@@ -12,10 +12,22 @@ -- #define GMAC_MIC_LEN 16 -- #define GMAC_NONCE_LEN 12 -- ---struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[], --- size_t key_len); ---int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, --- const u8 *data, size_t data_len, u8 *mic); ---void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm); --+static inline struct crypto_aead * --+ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len) --+{ --+ return NULL; --+} --+ --+static inline int --+ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, --+ const u8 *data, size_t data_len, u8 *mic) --+{ --+ return -EOPNOTSUPP; --+} --+ --+static inline void --+ieee80211_aes_gmac_key_free(struct crypto_aead *tfm) --+{ --+} -- -- #endif /* AES_GMAC_H */ ----- a/net/mac80211/key.h --+++ b/net/mac80211/key.h --@@ -89,7 +89,7 @@ struct ieee80211_key { -- * Management frames. -- */ -- u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; --- struct crypto_aead *tfm; --+ struct crypto_cipher *tfm; -- u32 replays; /* dot11RSNAStatsCCMPReplays */ -- } ccmp; -- struct { -diff --git a/package/kernel/mac80211/patches/subsys/130-disable-fils.patch b/package/kernel/mac80211/patches/subsys/130-disable-fils.patch -deleted file mode 100644 -index 9c6e971f9d..0000000000 ---- a/package/kernel/mac80211/patches/subsys/130-disable-fils.patch -+++ /dev/null -@@ -1,32 +0,0 @@ --Disable FILS support, since it pulls in crypto hash support -- ----- a/net/mac80211/fils_aead.h --+++ b/net/mac80211/fils_aead.h --@@ -7,7 +7,7 @@ -- #ifndef FILS_AEAD_H -- #define FILS_AEAD_H -- ---#if LINUX_VERSION_IS_GEQ(4,3,0) --+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ -- int fils_encrypt_assoc_req(struct sk_buff *skb, -- struct ieee80211_mgd_assoc_data *assoc_data); -- int fils_decrypt_assoc_resp(struct ieee80211_sub_if_data *sdata, ----- a/net/mac80211/fils_aead.c --+++ b/net/mac80211/fils_aead.c --@@ -1,4 +1,4 @@ ---#if LINUX_VERSION_IS_GEQ(4,3,0) --+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ -- // SPDX-License-Identifier: GPL-2.0-only -- /* -- * FILS AEAD for (Re)Association Request/Response frames ----- a/net/mac80211/main.c --+++ b/net/mac80211/main.c --@@ -591,7 +591,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ -- NL80211_FEATURE_MAC_ON_CREATE | -- NL80211_FEATURE_USERSPACE_MPM | -- NL80211_FEATURE_FULL_AP_CLIENT_STATE; ---#if LINUX_VERSION_IS_GEQ(4,3,0) --+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ -- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA); -- #endif -- wiphy_ext_feature_set(wiphy, -diff --git a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch b/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch -deleted file mode 100644 -index c3bf7ccc7a..0000000000 ---- a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch -+++ /dev/null -@@ -1,230 +0,0 @@ --From: Felix Fietkau --Date: Sat, 7 Oct 2017 09:37:28 +0200 --Subject: [PATCH] Revert "mac80211: aes-cmac: switch to shash CMAC -- driver" -- --This reverts commit 26717828b75dd5c46e97f7f4a9b937d038bb2852. --Reduces mac80211 dependencies for LEDE -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/aes_cmac.c --+++ b/net/mac80211/aes_cmac.c --@@ -19,67 +19,151 @@ -- #define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */ -- #define AAD_LEN 20 -- ---static const u8 zero[CMAC_TLEN_256]; -- ---void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, --+void gf_mulx(u8 *pad) --+{ --+ int i, carry; --+ --+ carry = pad[0] & 0x80; --+ for (i = 0; i < AES_BLOCK_SIZE - 1; i++) --+ pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); --+ pad[AES_BLOCK_SIZE - 1] <<= 1; --+ if (carry) --+ pad[AES_BLOCK_SIZE - 1] ^= 0x87; --+} --+ --+void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem, --+ const u8 *addr[], const size_t *len, u8 *mac, --+ size_t mac_len) --+{ --+ u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; --+ const u8 *pos, *end; --+ size_t i, e, left, total_len; --+ --+ memset(cbc, 0, AES_BLOCK_SIZE); --+ --+ total_len = 0; --+ for (e = 0; e < num_elem; e++) --+ total_len += len[e]; --+ left = total_len; --+ --+ e = 0; --+ pos = addr[0]; --+ end = pos + len[0]; --+ --+ while (left >= AES_BLOCK_SIZE) { --+ for (i = 0; i < AES_BLOCK_SIZE; i++) { --+ cbc[i] ^= *pos++; --+ if (pos >= end) { --+ e++; --+ pos = addr[e]; --+ end = pos + len[e]; --+ } --+ } --+ if (left > AES_BLOCK_SIZE) --+ crypto_cipher_encrypt_one(tfm, cbc, cbc); --+ left -= AES_BLOCK_SIZE; --+ } --+ --+ memset(pad, 0, AES_BLOCK_SIZE); --+ crypto_cipher_encrypt_one(tfm, pad, pad); --+ gf_mulx(pad); --+ --+ if (left || total_len == 0) { --+ for (i = 0; i < left; i++) { --+ cbc[i] ^= *pos++; --+ if (pos >= end) { --+ e++; --+ pos = addr[e]; --+ end = pos + len[e]; --+ } --+ } --+ cbc[left] ^= 0x80; --+ gf_mulx(pad); --+ } --+ --+ for (i = 0; i < AES_BLOCK_SIZE; i++) --+ pad[i] ^= cbc[i]; --+ crypto_cipher_encrypt_one(tfm, pad, pad); --+ memcpy(mac, pad, mac_len); --+} --+ --+ --+void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, -- const u8 *data, size_t data_len, u8 *mic) -- { --- SHASH_DESC_ON_STACK(desc, tfm); --- u8 out[AES_BLOCK_SIZE]; --+ const u8 *addr[4]; --+ size_t len[4]; --+ u8 zero[CMAC_TLEN]; -- const __le16 *fc; -- --- desc->tfm = tfm; --- --- crypto_shash_init(desc); --- crypto_shash_update(desc, aad, AAD_LEN); --+ memset(zero, 0, CMAC_TLEN); --+ addr[0] = aad; --+ len[0] = AAD_LEN; -- fc = (const __le16 *)aad; -- if (ieee80211_is_beacon(*fc)) { -- /* mask Timestamp field to zero */ --- crypto_shash_update(desc, zero, 8); --- crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN); --+ addr[1] = zero; --+ len[1] = 8; --+ addr[2] = data + 8; --+ len[2] = data_len - 8 - CMAC_TLEN; --+ addr[3] = zero; --+ len[3] = CMAC_TLEN; --+ aes_cmac_vector(tfm, 4, addr, len, mic, CMAC_TLEN); -- } else { --- crypto_shash_update(desc, data, data_len - CMAC_TLEN); --+ addr[1] = data; --+ len[1] = data_len - CMAC_TLEN; --+ addr[2] = zero; --+ len[2] = CMAC_TLEN; --+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN); -- } --- crypto_shash_finup(desc, zero, CMAC_TLEN, out); --- --- memcpy(mic, out, CMAC_TLEN); -- } -- ---void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, --+void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, -- const u8 *data, size_t data_len, u8 *mic) -- { --- SHASH_DESC_ON_STACK(desc, tfm); --+ const u8 *addr[4]; --+ size_t len[4]; --+ u8 zero[CMAC_TLEN_256]; -- const __le16 *fc; -- --- desc->tfm = tfm; --- --- crypto_shash_init(desc); --- crypto_shash_update(desc, aad, AAD_LEN); --+ memset(zero, 0, CMAC_TLEN_256); --+ addr[0] = aad; --+ len[0] = AAD_LEN; --+ addr[1] = data; -- fc = (const __le16 *)aad; -- if (ieee80211_is_beacon(*fc)) { -- /* mask Timestamp field to zero */ --- crypto_shash_update(desc, zero, 8); --- crypto_shash_update(desc, data + 8, --- data_len - 8 - CMAC_TLEN_256); --+ addr[1] = zero; --+ len[1] = 8; --+ addr[2] = data + 8; --+ len[2] = data_len - 8 - CMAC_TLEN_256; --+ addr[3] = zero; --+ len[3] = CMAC_TLEN_256; --+ aes_cmac_vector(tfm, 4, addr, len, mic, CMAC_TLEN_256); -- } else { --- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); --+ addr[1] = data; --+ len[1] = data_len - CMAC_TLEN_256; --+ addr[2] = zero; --+ len[2] = CMAC_TLEN_256; --+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256); -- } --- crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); -- } -- ---struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], --- size_t key_len) --+struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], --+ size_t key_len) -- { --- struct crypto_shash *tfm; --+ struct crypto_cipher *tfm; -- --- tfm = crypto_alloc_shash("cmac(aes)", 0, 0); --+ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); -- if (!IS_ERR(tfm)) --- crypto_shash_setkey(tfm, key, key_len); --+ crypto_cipher_setkey(tfm, key, key_len); -- -- return tfm; -- } -- ---void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm) --+ --+void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) -- { --- crypto_free_shash(tfm); --+ crypto_free_cipher(tfm); -- } ----- a/net/mac80211/aes_cmac.h --+++ b/net/mac80211/aes_cmac.h --@@ -7,14 +7,13 @@ -- #define AES_CMAC_H -- -- #include ---#include -- ---struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], --- size_t key_len); ---void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, --+struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], --+ size_t key_len); --+void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, -- const u8 *data, size_t data_len, u8 *mic); ---void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, --+void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, -- const u8 *data, size_t data_len, u8 *mic); ---void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); --+void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); -- -- #endif /* AES_CMAC_H */ ----- a/net/mac80211/key.h --+++ b/net/mac80211/key.h --@@ -94,7 +94,7 @@ struct ieee80211_key { -- } ccmp; -- struct { -- u8 rx_pn[IEEE80211_CMAC_PN_LEN]; --- struct crypto_shash *tfm; --+ struct crypto_cipher *tfm; -- u32 replays; /* dot11RSNAStatsCMACReplays */ -- u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ -- } aes_cmac; -diff --git a/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch b/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch -deleted file mode 100644 -index df67d2f101..0000000000 ---- a/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch -+++ /dev/null -@@ -1,10 +0,0 @@ ----- a/net/mac80211/Kconfig --+++ b/net/mac80211/Kconfig --@@ -6,7 +6,6 @@ config MAC80211 -- depends on CRYPTO -- select BPAUTO_CRYPTO_LIB_ARC4 -- depends on CRYPTO_AES --- depends on CRYPTO_CMAC -- depends on CRC32 -- help -- This option enables the hardware independent IEEE 802.11 -diff --git a/package/kernel/mac80211/patches/subsys/320-mac80211_hwsim-add-6GHz-channels.patch b/package/kernel/mac80211/patches/subsys/320-mac80211_hwsim-add-6GHz-channels.patch -new file mode 100644 -index 0000000000..a7c09f00bc ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/320-mac80211_hwsim-add-6GHz-channels.patch -@@ -0,0 +1,123 @@ -+From: Ramon Fontes -+Date: Sun, 27 Dec 2020 00:11:55 -0300 -+Subject: [PATCH] mac80211_hwsim: add 6GHz channels -+ -+Advertise 6GHz channels to mac80211. -+ -+Signed-off-by: Ramon Fontes -+Link: https://lore.kernel.org/r/20201227031155.81161-1-ramonreisfontes@gmail.com -+[reword commit message] -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/drivers/net/wireless/mac80211_hwsim.c -++++ b/drivers/net/wireless/mac80211_hwsim.c -+@@ -311,6 +311,12 @@ static struct net_device *hwsim_mon; /* -+ .hw_value = (_freq), \ -+ } -+ -++#define CHAN6G(_freq) { \ -++ .band = NL80211_BAND_6GHZ, \ -++ .center_freq = (_freq), \ -++ .hw_value = (_freq), \ -++} -++ -+ static const struct ieee80211_channel hwsim_channels_2ghz[] = { -+ CHAN2G(2412), /* Channel 1 */ -+ CHAN2G(2417), /* Channel 2 */ -+@@ -377,6 +383,68 @@ static const struct ieee80211_channel hw -+ CHAN5G(5925), /* Channel 185 */ -+ }; -+ -++static const struct ieee80211_channel hwsim_channels_6ghz[] = { -++ CHAN6G(5955), /* Channel 1 */ -++ CHAN6G(5975), /* Channel 5 */ -++ CHAN6G(5995), /* Channel 9 */ -++ CHAN6G(6015), /* Channel 13 */ -++ CHAN6G(6035), /* Channel 17 */ -++ CHAN6G(6055), /* Channel 21 */ -++ CHAN6G(6075), /* Channel 25 */ -++ CHAN6G(6095), /* Channel 29 */ -++ CHAN6G(6115), /* Channel 33 */ -++ CHAN6G(6135), /* Channel 37 */ -++ CHAN6G(6155), /* Channel 41 */ -++ CHAN6G(6175), /* Channel 45 */ -++ CHAN6G(6195), /* Channel 49 */ -++ CHAN6G(6215), /* Channel 53 */ -++ CHAN6G(6235), /* Channel 57 */ -++ CHAN6G(6255), /* Channel 61 */ -++ CHAN6G(6275), /* Channel 65 */ -++ CHAN6G(6295), /* Channel 69 */ -++ CHAN6G(6315), /* Channel 73 */ -++ CHAN6G(6335), /* Channel 77 */ -++ CHAN6G(6355), /* Channel 81 */ -++ CHAN6G(6375), /* Channel 85 */ -++ CHAN6G(6395), /* Channel 89 */ -++ CHAN6G(6415), /* Channel 93 */ -++ CHAN6G(6435), /* Channel 97 */ -++ CHAN6G(6455), /* Channel 181 */ -++ CHAN6G(6475), /* Channel 105 */ -++ CHAN6G(6495), /* Channel 109 */ -++ CHAN6G(6515), /* Channel 113 */ -++ CHAN6G(6535), /* Channel 117 */ -++ CHAN6G(6555), /* Channel 121 */ -++ CHAN6G(6575), /* Channel 125 */ -++ CHAN6G(6595), /* Channel 129 */ -++ CHAN6G(6615), /* Channel 133 */ -++ CHAN6G(6635), /* Channel 137 */ -++ CHAN6G(6655), /* Channel 141 */ -++ CHAN6G(6675), /* Channel 145 */ -++ CHAN6G(6695), /* Channel 149 */ -++ CHAN6G(6715), /* Channel 153 */ -++ CHAN6G(6735), /* Channel 157 */ -++ CHAN6G(6755), /* Channel 161 */ -++ CHAN6G(6775), /* Channel 165 */ -++ CHAN6G(6795), /* Channel 169 */ -++ CHAN6G(6815), /* Channel 173 */ -++ CHAN6G(6835), /* Channel 177 */ -++ CHAN6G(6855), /* Channel 181 */ -++ CHAN6G(6875), /* Channel 185 */ -++ CHAN6G(6895), /* Channel 189 */ -++ CHAN6G(6915), /* Channel 193 */ -++ CHAN6G(6935), /* Channel 197 */ -++ CHAN6G(6955), /* Channel 201 */ -++ CHAN6G(6975), /* Channel 205 */ -++ CHAN6G(6995), /* Channel 209 */ -++ CHAN6G(7015), /* Channel 213 */ -++ CHAN6G(7035), /* Channel 217 */ -++ CHAN6G(7055), /* Channel 221 */ -++ CHAN6G(7075), /* Channel 225 */ -++ CHAN6G(7095), /* Channel 229 */ -++ CHAN6G(7115), /* Channel 233 */ -++}; -++ -+ #define NUM_S1G_CHANS_US 51 -+ static struct ieee80211_channel hwsim_channels_s1g[NUM_S1G_CHANS_US]; -+ -+@@ -548,6 +616,7 @@ struct mac80211_hwsim_data { -+ struct ieee80211_supported_band bands[NUM_NL80211_BANDS]; -+ struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)]; -+ struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)]; -++ struct ieee80211_channel channels_6ghz[ARRAY_SIZE(hwsim_channels_6ghz)]; -+ struct ieee80211_channel channels_s1g[ARRAY_SIZE(hwsim_channels_s1g)]; -+ struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; -+ struct ieee80211_iface_combination if_combination; -+@@ -578,7 +647,8 @@ struct mac80211_hwsim_data { -+ struct ieee80211_channel *channel; -+ unsigned long next_start, start, end; -+ } survey_data[ARRAY_SIZE(hwsim_channels_2ghz) + -+- ARRAY_SIZE(hwsim_channels_5ghz)]; -++ ARRAY_SIZE(hwsim_channels_5ghz) + -++ ARRAY_SIZE(hwsim_channels_6ghz)]; -+ -+ struct ieee80211_channel *channel; -+ u64 beacon_int /* beacon interval in us */; -+@@ -3149,6 +3219,8 @@ static int mac80211_hwsim_new_radio(stru -+ sizeof(hwsim_channels_2ghz)); -+ memcpy(data->channels_5ghz, hwsim_channels_5ghz, -+ sizeof(hwsim_channels_5ghz)); -++ memcpy(data->channels_6ghz, hwsim_channels_6ghz, -++ sizeof(hwsim_channels_6ghz)); -+ memcpy(data->channels_s1g, hwsim_channels_s1g, -+ sizeof(hwsim_channels_s1g)); -+ memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates)); -diff --git a/package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch b/package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch -new file mode 100644 -index 0000000000..4bac10eefe ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch -@@ -0,0 +1,74 @@ -+From: Felix Fietkau -+Date: Mon, 24 May 2021 11:46:09 +0200 -+Subject: [PATCH] mac80211_hwsim: make 6 GHz channels usable -+ -+The previous commit that claimed to add 6 GHz channels didn't actually make -+them usable, since the 6 GHz band was not registered with mac80211. -+ -+Fixes: 28881922abd7 ("mac80211_hwsim: add 6GHz channels") -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/mac80211_hwsim.c -++++ b/drivers/net/wireless/mac80211_hwsim.c -+@@ -2968,15 +2968,19 @@ static void mac80211_hwsim_he_capab(stru -+ { -+ u16 n_iftype_data; -+ -+- if (sband->band == NL80211_BAND_2GHZ) { -++ switch (sband->band) { -++ case NL80211_BAND_2GHZ: -+ n_iftype_data = ARRAY_SIZE(he_capa_2ghz); -+ sband->iftype_data = -+ (struct ieee80211_sband_iftype_data *)he_capa_2ghz; -+- } else if (sband->band == NL80211_BAND_5GHZ) { -++ break; -++ case NL80211_BAND_5GHZ: -++ case NL80211_BAND_6GHZ: -+ n_iftype_data = ARRAY_SIZE(he_capa_5ghz); -+ sband->iftype_data = -+ (struct ieee80211_sband_iftype_data *)he_capa_5ghz; -+- } else { -++ break; -++ default: -+ return; -+ } -+ -+@@ -3265,6 +3269,12 @@ static int mac80211_hwsim_new_radio(stru -+ sband->vht_cap.vht_mcs.tx_mcs_map = -+ sband->vht_cap.vht_mcs.rx_mcs_map; -+ break; -++ case NL80211_BAND_6GHZ: -++ sband->channels = data->channels_6ghz; -++ sband->n_channels = ARRAY_SIZE(hwsim_channels_6ghz); -++ sband->bitrates = data->rates + 4; -++ sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4; -++ break; -+ case NL80211_BAND_S1GHZ: -+ memcpy(&sband->s1g_cap, &hwsim_s1g_cap, -+ sizeof(sband->s1g_cap)); -+@@ -3275,6 +3285,13 @@ static int mac80211_hwsim_new_radio(stru -+ continue; -+ } -+ -++ mac80211_hwsim_he_capab(sband); -++ -++ hw->wiphy->bands[band] = sband; -++ -++ if (band == NL80211_BAND_6GHZ) -++ continue; -++ -+ sband->ht_cap.ht_supported = true; -+ sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | -+ IEEE80211_HT_CAP_GRN_FLD | -+@@ -3288,10 +3305,6 @@ static int mac80211_hwsim_new_radio(stru -+ sband->ht_cap.mcs.rx_mask[0] = 0xff; -+ sband->ht_cap.mcs.rx_mask[1] = 0xff; -+ sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; -+- -+- mac80211_hwsim_he_capab(sband); -+- -+- hw->wiphy->bands[band] = sband; -+ } -+ -+ /* By default all radios belong to the first group */ -diff --git a/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch b/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch -index 96ee595ac1..1cab2eb194 100644 ---- a/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch -+++ b/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch -@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau - - --- a/net/mac80211/Makefile - +++ b/net/mac80211/Makefile --@@ -55,11 +55,9 @@ mac80211-$(CONFIG_PM) += pm.o -+@@ -56,11 +56,9 @@ mac80211-$(CONFIG_PM) += pm.o - CFLAGS_trace.o := -I$(src) - - rc80211_minstrel-y := \ -diff --git a/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch b/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch -index 43a4a1334d..f22b0d9849 100644 ---- a/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch -+++ b/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch -@@ -7,24 +7,6 @@ The software rate control cannot deal with encap offload, so fix it. - Signed-off-by: Ryder Lee - --- - ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -2024,6 +2024,15 @@ static inline void ieee80211_tx_skb(stru -- ieee80211_tx_skb_tid(sdata, skb, 7); -- } -- --+static inline bool ieee80211_is_tx_data(struct sk_buff *skb) --+{ --+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; --+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); --+ --+ return info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP || --+ ieee80211_is_data(hdr->frame_control); --+} --+ -- u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, -- struct ieee802_11_elems *elems, -- u64 filter, u32 crc, u8 *transmitter_bssid, - --- a/net/mac80211/rate.c - +++ b/net/mac80211/rate.c - @@ -297,15 +297,11 @@ void ieee80211_check_rate_mask(struct ie -@@ -117,3 +99,28 @@ Signed-off-by: Ryder Lee - - if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) { - struct sta_info *sta = container_of(txq->sta, struct sta_info, -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -6728,4 +6728,22 @@ struct sk_buff *ieee80211_get_fils_disco -+ struct sk_buff * -+ ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif); -++ -++/** -++ * 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 -++ * hardware encapsulation enabled are data frames. -++ * -++ * @skb: the frame to be transmitted. -++ */ -++static inline bool ieee80211_is_tx_data(struct sk_buff *skb) -++{ -++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -++ struct ieee80211_hdr *hdr = (void *) skb->data; -++ -++ return info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP || -++ ieee80211_is_data(hdr->frame_control); -++} -++ -+ #endif /* MAC80211_H */ -diff --git a/package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch b/package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch -new file mode 100644 -index 0000000000..b21b671c10 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch -@@ -0,0 +1,111 @@ -+From: Lorenzo Bianconi -+Date: Sat, 9 Jan 2021 18:57:51 +0100 -+Subject: [PATCH] mac80211: introduce aql_enable node in debugfs -+ -+Introduce aql_enable node in debugfs in order to enable/disable aql. -+This is useful for debugging purpose. -+ -+Signed-off-by: Lorenzo Bianconi -+Link: https://lore.kernel.org/r/e7a934d5d84e4796c4f97ea5de4e66c824296b07.1610214851.git.lorenzo@kernel.org -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/net/mac80211/debugfs.c -++++ b/net/mac80211/debugfs.c -+@@ -281,6 +281,56 @@ static const struct file_operations aql_ -+ .llseek = default_llseek, -+ }; -+ -++static ssize_t aql_enable_read(struct file *file, char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ char buf[3]; -++ int len; -++ -++ len = scnprintf(buf, sizeof(buf), "%d\n", -++ !static_key_false(&aql_disable.key)); -++ -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++} -++ -++static ssize_t aql_enable_write(struct file *file, const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ bool aql_disabled = static_key_false(&aql_disable.key); -++ char buf[3]; -++ size_t len; -++ -++ if (count > sizeof(buf)) -++ return -EINVAL; -++ -++ if (copy_from_user(buf, user_buf, count)) -++ return -EFAULT; -++ -++ buf[sizeof(buf) - 1] = '\0'; -++ len = strlen(buf); -++ if (len > 0 && buf[len - 1] == '\n') -++ buf[len - 1] = 0; -++ -++ if (buf[0] == '0' && buf[1] == '\0') { -++ if (!aql_disabled) -++ static_branch_inc(&aql_disable); -++ } else if (buf[0] == '1' && buf[1] == '\0') { -++ if (aql_disabled) -++ static_branch_dec(&aql_disable); -++ } else { -++ return -EINVAL; -++ } -++ -++ return count; -++} -++ -++static const struct file_operations aql_enable_ops = { -++ .write = aql_enable_write, -++ .read = aql_enable_read, -++ .open = simple_open, -++ .llseek = default_llseek, -++}; -++ -+ static ssize_t force_tx_status_read(struct file *file, -+ char __user *user_buf, -+ size_t count, -+@@ -569,6 +619,7 @@ void debugfs_hw_add(struct ieee80211_loc -+ DEBUGFS_ADD(power); -+ DEBUGFS_ADD(hw_conf); -+ DEBUGFS_ADD_MODE(force_tx_status, 0600); -++ DEBUGFS_ADD_MODE(aql_enable, 0600); -+ -+ if (local->ops->wake_tx_queue) -+ DEBUGFS_ADD_MODE(aqm, 0600); -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -1140,6 +1140,8 @@ enum mac80211_scan_state { -+ SCAN_ABORT, -+ }; -+ -++DECLARE_STATIC_KEY_FALSE(aql_disable); -++ -+ struct ieee80211_local { -+ /* embed the driver visible part. -+ * don't cast (use the static inlines below), but we keep -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -3887,6 +3887,8 @@ void __ieee80211_schedule_txq(struct iee -+ } -+ EXPORT_SYMBOL(__ieee80211_schedule_txq); -+ -++DEFINE_STATIC_KEY_FALSE(aql_disable); -++ -+ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, -+ struct ieee80211_txq *txq) -+ { -+@@ -3896,6 +3898,9 @@ bool ieee80211_txq_airtime_check(struct -+ if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) -+ return true; -+ -++ if (static_branch_unlikely(&aql_disable)) -++ return true; -++ -+ if (!txq->sta) -+ return true; -+ -diff --git a/package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch b/package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch -new file mode 100644 -index 0000000000..708ad6f460 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch -@@ -0,0 +1,39 @@ -+From: Johannes Berg -+Date: Fri, 18 Jun 2021 13:41:44 +0300 -+Subject: [PATCH] mac80211: rearrange struct txq_info for fewer holes -+ -+We can slightly decrease the size of struct txq_info by -+rearranging some fields for fewer holes, so do that. -+ -+Signed-off-by: Johannes Berg -+Signed-off-by: Luca Coelho -+Link: https://lore.kernel.org/r/iwlwifi.20210618133832.1bf019a1fe2e.Ib54622b8d6dc1a9a7dc484e573c073119450538b@changeid -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -5,7 +5,7 @@ -+ * Copyright 2006-2007 Jiri Benc -+ * Copyright 2007-2010 Johannes Berg -+ * Copyright 2013-2015 Intel Mobile Communications GmbH -+- * Copyright (C) 2018-2020 Intel Corporation -++ * Copyright (C) 2018-2021 Intel Corporation -+ */ -+ -+ #ifndef IEEE80211_I_H -+@@ -848,9 +848,12 @@ struct txq_info { -+ struct fq_tin tin; -+ struct codel_vars def_cvars; -+ struct codel_stats cstats; -+- struct sk_buff_head frags; -+- struct list_head schedule_order; -++ -+ u16 schedule_round; -++ struct list_head schedule_order; -++ -++ struct sk_buff_head frags; -++ -+ unsigned long flags; -+ -+ /* keep last! */ -diff --git a/package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch b/package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch -new file mode 100644 -index 0000000000..ba78f7a142 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch -@@ -0,0 +1,1277 @@ -+From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= -+Date: Wed, 23 Jun 2021 15:47:55 +0200 -+Subject: [PATCH] mac80211: Switch to a virtual time-based airtime scheduler -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This switches the airtime scheduler in mac80211 to use a virtual -+time-based scheduler instead of the round-robin scheduler used before. -+This has a couple of advantages: -+ -+- No need to sync up the round-robin scheduler in firmware/hardware with -+ the round-robin airtime scheduler. -+ -+- If several stations are eligible for transmission we can schedule both -+ of them; no need to hard-block the scheduling rotation until the head -+ of the queue has used up its quantum. -+ -+- The check of whether a station is eligible for transmission becomes -+ simpler (in ieee80211_txq_may_transmit()). -+ -+The drawback is that scheduling becomes slightly more expensive, as we -+need to maintain an rbtree of TXQs sorted by virtual time. This means -+that ieee80211_register_airtime() becomes O(logN) in the number of -+currently scheduled TXQs because it can change the order of the -+scheduled stations. We mitigate this overhead by only resorting when a -+station changes position in the tree, and hopefully N rarely grows too -+big (it's only TXQs currently backlogged, not all associated stations), -+so it shouldn't be too big of an issue. -+ -+To prevent divisions in the fast path, we maintain both station sums and -+pre-computed reciprocals of the sums. This turns the fast-path operation -+into a multiplication, with divisions only happening as the number of -+active stations change (to re-compute the current sum of all active -+station weights). To prevent this re-computation of the reciprocal from -+happening too frequently, we use a time-based notion of station -+activity, instead of updating the weight every time a station gets -+scheduled or de-scheduled. As queues can oscillate between empty and -+occupied quite frequently, this can significantly cut down on the number -+of re-computations. It also has the added benefit of making the station -+airtime calculation independent on whether the queue happened to have -+drained at the time an airtime value was accounted. -+ -+Co-developed-by: Yibo Zhao -+Signed-off-by: Yibo Zhao -+Signed-off-by: Toke Høiland-Jørgensen -+Link: https://lore.kernel.org/r/20210623134755.235545-1-toke@redhat.com -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -6552,9 +6552,6 @@ static inline void ieee80211_txq_schedul -+ { -+ } -+ -+-void __ieee80211_schedule_txq(struct ieee80211_hw *hw, -+- struct ieee80211_txq *txq, bool force); -+- -+ /** -+ * ieee80211_schedule_txq - schedule a TXQ for transmission -+ * -+@@ -6567,11 +6564,7 @@ void __ieee80211_schedule_txq(struct iee -+ * The driver may call this function if it has buffered packets for -+ * this TXQ internally. -+ */ -+-static inline void -+-ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq) -+-{ -+- __ieee80211_schedule_txq(hw, txq, true); -+-} -++void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq); -+ -+ /** -+ * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq() -+@@ -6583,12 +6576,8 @@ ieee80211_schedule_txq(struct ieee80211_ -+ * The driver may set force=true if it has buffered packets for this TXQ -+ * internally. -+ */ -+-static inline void -+-ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, -+- bool force) -+-{ -+- __ieee80211_schedule_txq(hw, txq, force); -+-} -++void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, -++ bool force); -+ -+ /** -+ * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -1442,6 +1442,38 @@ static void sta_apply_mesh_params(struct -+ #endif -+ } -+ -++static void sta_apply_airtime_params(struct ieee80211_local *local, -++ struct sta_info *sta, -++ struct station_parameters *params) -++{ -++ u8 ac; -++ -++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -++ struct airtime_sched_info *air_sched = &local->airtime[ac]; -++ struct airtime_info *air_info = &sta->airtime[ac]; -++ struct txq_info *txqi; -++ u8 tid; -++ -++ spin_lock_bh(&air_sched->lock); -++ for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) { -++ if (air_info->weight == params->airtime_weight || -++ !sta->sta.txq[tid] || -++ ac != ieee80211_ac_from_tid(tid)) -++ continue; -++ -++ airtime_weight_set(air_info, params->airtime_weight); -++ -++ txqi = to_txq_info(sta->sta.txq[tid]); -++ if (RB_EMPTY_NODE(&txqi->schedule_order)) -++ continue; -++ -++ ieee80211_update_airtime_weight(local, air_sched, -++ 0, true); -++ } -++ spin_unlock_bh(&air_sched->lock); -++ } -++} -++ -+ static int sta_apply_parameters(struct ieee80211_local *local, -+ struct sta_info *sta, -+ struct station_parameters *params) -+@@ -1629,7 +1661,8 @@ static int sta_apply_parameters(struct i -+ sta_apply_mesh_params(local, sta, params); -+ -+ if (params->airtime_weight) -+- sta->airtime_weight = params->airtime_weight; -++ sta_apply_airtime_params(local, sta, params); -++ -+ -+ /* set the STA state after all sta info from usermode has been set */ -+ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) || -+--- a/net/mac80211/debugfs.c -++++ b/net/mac80211/debugfs.c -+@@ -216,14 +216,14 @@ static ssize_t aql_txq_limit_read(struct -+ "VI %u %u\n" -+ "BE %u %u\n" -+ "BK %u %u\n", -+- local->aql_txq_limit_low[IEEE80211_AC_VO], -+- local->aql_txq_limit_high[IEEE80211_AC_VO], -+- local->aql_txq_limit_low[IEEE80211_AC_VI], -+- local->aql_txq_limit_high[IEEE80211_AC_VI], -+- local->aql_txq_limit_low[IEEE80211_AC_BE], -+- local->aql_txq_limit_high[IEEE80211_AC_BE], -+- local->aql_txq_limit_low[IEEE80211_AC_BK], -+- local->aql_txq_limit_high[IEEE80211_AC_BK]); -++ local->airtime[IEEE80211_AC_VO].aql_txq_limit_low, -++ local->airtime[IEEE80211_AC_VO].aql_txq_limit_high, -++ local->airtime[IEEE80211_AC_VI].aql_txq_limit_low, -++ local->airtime[IEEE80211_AC_VI].aql_txq_limit_high, -++ local->airtime[IEEE80211_AC_BE].aql_txq_limit_low, -++ local->airtime[IEEE80211_AC_BE].aql_txq_limit_high, -++ local->airtime[IEEE80211_AC_BK].aql_txq_limit_low, -++ local->airtime[IEEE80211_AC_BK].aql_txq_limit_high); -+ return simple_read_from_buffer(user_buf, count, ppos, -+ buf, len); -+ } -+@@ -255,11 +255,11 @@ static ssize_t aql_txq_limit_write(struc -+ if (ac >= IEEE80211_NUM_ACS) -+ return -EINVAL; -+ -+- q_limit_low_old = local->aql_txq_limit_low[ac]; -+- q_limit_high_old = local->aql_txq_limit_high[ac]; -++ q_limit_low_old = local->airtime[ac].aql_txq_limit_low; -++ q_limit_high_old = local->airtime[ac].aql_txq_limit_high; -+ -+- local->aql_txq_limit_low[ac] = q_limit_low; -+- local->aql_txq_limit_high[ac] = q_limit_high; -++ local->airtime[ac].aql_txq_limit_low = q_limit_low; -++ local->airtime[ac].aql_txq_limit_high = q_limit_high; -+ -+ mutex_lock(&local->sta_mtx); -+ list_for_each_entry(sta, &local->sta_list, list) { -+@@ -382,6 +382,46 @@ static const struct file_operations forc -+ .llseek = default_llseek, -+ }; -+ -++static ssize_t airtime_read(struct file *file, -++ char __user *user_buf, -++ size_t count, -++ loff_t *ppos) -++{ -++ struct ieee80211_local *local = file->private_data; -++ char buf[200]; -++ u64 v_t[IEEE80211_NUM_ACS]; -++ u64 wt[IEEE80211_NUM_ACS]; -++ int len = 0, ac; -++ -++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -++ spin_lock_bh(&local->airtime[ac].lock); -++ v_t[ac] = local->airtime[ac].v_t; -++ wt[ac] = local->airtime[ac].weight_sum; -++ spin_unlock_bh(&local->airtime[ac].lock); -++ } -++ len = scnprintf(buf, sizeof(buf), -++ "\tVO VI BE BK\n" -++ "Virt-t\t%-10llu %-10llu %-10llu %-10llu\n" -++ "Weight\t%-10llu %-10llu %-10llu %-10llu\n", -++ v_t[0], -++ v_t[1], -++ v_t[2], -++ v_t[3], -++ wt[0], -++ wt[1], -++ wt[2], -++ wt[3]); -++ -++ return simple_read_from_buffer(user_buf, count, ppos, -++ buf, len); -++} -++ -++static const struct file_operations airtime_ops = { -++ .read = airtime_read, -++ .open = simple_open, -++ .llseek = default_llseek, -++}; -++ -+ #ifdef CONFIG_PM -+ static ssize_t reset_write(struct file *file, const char __user *user_buf, -+ size_t count, loff_t *ppos) -+@@ -624,7 +664,11 @@ void debugfs_hw_add(struct ieee80211_loc -+ if (local->ops->wake_tx_queue) -+ DEBUGFS_ADD_MODE(aqm, 0600); -+ -+- DEBUGFS_ADD_MODE(airtime_flags, 0600); -++ if (wiphy_ext_feature_isset(local->hw.wiphy, -++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) { -++ DEBUGFS_ADD_MODE(airtime, 0600); -++ DEBUGFS_ADD_MODE(airtime_flags, 0600); -++ } -+ -+ DEBUGFS_ADD(aql_txq_limit); -+ debugfs_create_u32("aql_threshold", 0600, -+--- a/net/mac80211/debugfs_netdev.c -++++ b/net/mac80211/debugfs_netdev.c -+@@ -513,6 +513,34 @@ static ssize_t ieee80211_if_fmt_aqm( -+ } -+ IEEE80211_IF_FILE_R(aqm); -+ -++static ssize_t ieee80211_if_fmt_airtime( -++ const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) -++{ -++ struct ieee80211_local *local = sdata->local; -++ struct ieee80211_txq *txq = sdata->vif.txq; -++ struct airtime_info *air_info; -++ int len; -++ -++ if (!txq) -++ return 0; -++ -++ spin_lock_bh(&local->airtime[txq->ac].lock); -++ air_info = to_airtime_info(txq); -++ len = scnprintf(buf, -++ buflen, -++ "RX: %llu us\nTX: %llu us\nWeight: %u\n" -++ "Virt-T: %lld us\n", -++ air_info->rx_airtime, -++ air_info->tx_airtime, -++ air_info->weight, -++ air_info->v_t); -++ spin_unlock_bh(&local->airtime[txq->ac].lock); -++ -++ return len; -++} -++ -++IEEE80211_IF_FILE_R(airtime); -++ -+ IEEE80211_IF_FILE(multicast_to_unicast, u.ap.multicast_to_unicast, HEX); -+ -+ /* IBSS attributes */ -+@@ -661,8 +689,10 @@ static void add_common_files(struct ieee -+ -+ if (sdata->local->ops->wake_tx_queue && -+ sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && -+- sdata->vif.type != NL80211_IFTYPE_NAN) -++ sdata->vif.type != NL80211_IFTYPE_NAN) { -+ DEBUGFS_ADD(aqm); -++ DEBUGFS_ADD(airtime); -++ } -+ } -+ -+ static void add_sta_files(struct ieee80211_sub_if_data *sdata) -+--- a/net/mac80211/debugfs_sta.c -++++ b/net/mac80211/debugfs_sta.c -+@@ -202,7 +202,7 @@ static ssize_t sta_airtime_read(struct f -+ size_t bufsz = 400; -+ char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf; -+ u64 rx_airtime = 0, tx_airtime = 0; -+- s64 deficit[IEEE80211_NUM_ACS]; -++ u64 v_t[IEEE80211_NUM_ACS]; -+ ssize_t rv; -+ int ac; -+ -+@@ -210,18 +210,18 @@ static ssize_t sta_airtime_read(struct f -+ return -ENOMEM; -+ -+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -+- spin_lock_bh(&local->active_txq_lock[ac]); -++ spin_lock_bh(&local->airtime[ac].lock); -+ rx_airtime += sta->airtime[ac].rx_airtime; -+ tx_airtime += sta->airtime[ac].tx_airtime; -+- deficit[ac] = sta->airtime[ac].deficit; -+- spin_unlock_bh(&local->active_txq_lock[ac]); -++ v_t[ac] = sta->airtime[ac].v_t; -++ spin_unlock_bh(&local->airtime[ac].lock); -+ } -+ -+ p += scnprintf(p, bufsz + buf - p, -+ "RX: %llu us\nTX: %llu us\nWeight: %u\n" -+- "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", -+- rx_airtime, tx_airtime, sta->airtime_weight, -+- deficit[0], deficit[1], deficit[2], deficit[3]); -++ "Virt-T: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", -++ rx_airtime, tx_airtime, sta->airtime[0].weight, -++ v_t[0], v_t[1], v_t[2], v_t[3]); -+ -+ rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); -+ kfree(buf); -+@@ -236,11 +236,11 @@ static ssize_t sta_airtime_write(struct -+ int ac; -+ -+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -+- spin_lock_bh(&local->active_txq_lock[ac]); -++ spin_lock_bh(&local->airtime[ac].lock); -+ sta->airtime[ac].rx_airtime = 0; -+ sta->airtime[ac].tx_airtime = 0; -+- sta->airtime[ac].deficit = sta->airtime_weight; -+- spin_unlock_bh(&local->active_txq_lock[ac]); -++ sta->airtime[ac].v_t = 0; -++ spin_unlock_bh(&local->airtime[ac].lock); -+ } -+ -+ return count; -+@@ -263,10 +263,10 @@ static ssize_t sta_aql_read(struct file -+ return -ENOMEM; -+ -+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -+- spin_lock_bh(&local->active_txq_lock[ac]); -++ spin_lock_bh(&local->airtime[ac].lock); -+ q_limit_l[ac] = sta->airtime[ac].aql_limit_low; -+ q_limit_h[ac] = sta->airtime[ac].aql_limit_high; -+- spin_unlock_bh(&local->active_txq_lock[ac]); -++ spin_unlock_bh(&local->airtime[ac].lock); -+ q_depth[ac] = atomic_read(&sta->airtime[ac].aql_tx_pending); -+ } -+ -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -840,20 +840,16 @@ enum txq_info_flags { -+ * @def_flow: used as a fallback flow when a packet destined to @tin hashes to -+ * a fq_flow which is already owned by a different tin -+ * @def_cvars: codel vars for @def_flow -+- * @frags: used to keep fragments created after dequeue -+ * @schedule_order: used with ieee80211_local->active_txqs -+- * @schedule_round: counter to prevent infinite loops on TXQ scheduling -++ * @frags: used to keep fragments created after dequeue -+ */ -+ struct txq_info { -+ struct fq_tin tin; -+ struct codel_vars def_cvars; -+ struct codel_stats cstats; -+- -+- u16 schedule_round; -+- struct list_head schedule_order; -++ struct rb_node schedule_order; -+ -+ struct sk_buff_head frags; -+- -+ unsigned long flags; -+ -+ /* keep last! */ -+@@ -930,6 +926,8 @@ struct ieee80211_sub_if_data { -+ struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; -+ struct mac80211_qos_map __rcu *qos_map; -+ -++ struct airtime_info airtime[IEEE80211_NUM_ACS]; -++ -+ struct work_struct csa_finalize_work; -+ bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */ -+ struct cfg80211_chan_def csa_chandef; -+@@ -1143,6 +1141,44 @@ enum mac80211_scan_state { -+ SCAN_ABORT, -+ }; -+ -++/** -++ * struct airtime_sched_info - state used for airtime scheduling and AQL -++ * -++ * @lock: spinlock that protects all the fields in this struct -++ * @active_txqs: rbtree of currently backlogged queues, sorted by virtual time -++ * @schedule_pos: the current position maintained while a driver walks the tree -++ * with ieee80211_next_txq() -++ * @active_list: list of struct airtime_info structs that were active within -++ * the last AIRTIME_ACTIVE_DURATION (100 ms), used to compute -++ * weight_sum -++ * @last_weight_update: used for rate limiting walking active_list -++ * @last_schedule_time: tracks the last time a transmission was scheduled; used -++ * for catching up v_t if no stations are eligible for -++ * transmission. -++ * @v_t: global virtual time; queues with v_t < this are eligible for -++ * transmission -++ * @weight_sum: total sum of all active stations used for dividing airtime -++ * @weight_sum_reciprocal: reciprocal of weight_sum (to avoid divisions in fast -++ * path - see comment above -++ * IEEE80211_RECIPROCAL_DIVISOR_64) -++ * @aql_txq_limit_low: AQL limit when total outstanding airtime -++ * is < IEEE80211_AQL_THRESHOLD -++ * @aql_txq_limit_high: AQL limit when total outstanding airtime -++ * is > IEEE80211_AQL_THRESHOLD -++ */ -++struct airtime_sched_info { -++ spinlock_t lock; -++ struct rb_root_cached active_txqs; -++ struct rb_node *schedule_pos; -++ struct list_head active_list; -++ u64 last_weight_update; -++ u64 last_schedule_activity; -++ u64 v_t; -++ u64 weight_sum; -++ u64 weight_sum_reciprocal; -++ u32 aql_txq_limit_low; -++ u32 aql_txq_limit_high; -++}; -+ DECLARE_STATIC_KEY_FALSE(aql_disable); -+ -+ struct ieee80211_local { -+@@ -1156,13 +1192,8 @@ struct ieee80211_local { -+ struct codel_params cparams; -+ -+ /* protects active_txqs and txqi->schedule_order */ -+- spinlock_t active_txq_lock[IEEE80211_NUM_ACS]; -+- struct list_head active_txqs[IEEE80211_NUM_ACS]; -+- u16 schedule_round[IEEE80211_NUM_ACS]; -+- -++ struct airtime_sched_info airtime[IEEE80211_NUM_ACS]; -+ u16 airtime_flags; -+- u32 aql_txq_limit_low[IEEE80211_NUM_ACS]; -+- u32 aql_txq_limit_high[IEEE80211_NUM_ACS]; -+ u32 aql_threshold; -+ atomic_t aql_total_pending_airtime; -+ -+@@ -1581,6 +1612,125 @@ static inline bool txq_has_queue(struct -+ return !(skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets); -+ } -+ -++static inline struct airtime_info *to_airtime_info(struct ieee80211_txq *txq) -++{ -++ struct ieee80211_sub_if_data *sdata; -++ struct sta_info *sta; -++ -++ if (txq->sta) { -++ sta = container_of(txq->sta, struct sta_info, sta); -++ return &sta->airtime[txq->ac]; -++ } -++ -++ sdata = vif_to_sdata(txq->vif); -++ return &sdata->airtime[txq->ac]; -++} -++ -++/* To avoid divisions in the fast path, we keep pre-computed reciprocals for -++ * airtime weight calculations. There are two different weights to keep track -++ * of: The per-station weight and the sum of weights per phy. -++ * -++ * For the per-station weights (kept in airtime_info below), we use 32-bit -++ * reciprocals with a devisor of 2^19. This lets us keep the multiplications and -++ * divisions for the station weights as 32-bit operations at the cost of a bit -++ * of rounding error for high weights; but the choice of divisor keeps rounding -++ * errors <10% for weights <2^15, assuming no more than 8ms of airtime is -++ * reported at a time. -++ * -++ * For the per-phy sum of weights the values can get higher, so we use 64-bit -++ * operations for those with a 32-bit divisor, which should avoid any -++ * significant rounding errors. -++ */ -++#define IEEE80211_RECIPROCAL_DIVISOR_64 0x100000000ULL -++#define IEEE80211_RECIPROCAL_SHIFT_64 32 -++#define IEEE80211_RECIPROCAL_DIVISOR_32 0x80000U -++#define IEEE80211_RECIPROCAL_SHIFT_32 19 -++ -++static inline void airtime_weight_set(struct airtime_info *air_info, u16 weight) -++{ -++ if (air_info->weight == weight) -++ return; -++ -++ air_info->weight = weight; -++ if (weight) { -++ air_info->weight_reciprocal = -++ IEEE80211_RECIPROCAL_DIVISOR_32 / weight; -++ } else { -++ air_info->weight_reciprocal = 0; -++ } -++} -++ -++static inline void airtime_weight_sum_set(struct airtime_sched_info *air_sched, -++ int weight_sum) -++{ -++ if (air_sched->weight_sum == weight_sum) -++ return; -++ -++ air_sched->weight_sum = weight_sum; -++ if (air_sched->weight_sum) { -++ air_sched->weight_sum_reciprocal = IEEE80211_RECIPROCAL_DIVISOR_64; -++ do_div(air_sched->weight_sum_reciprocal, air_sched->weight_sum); -++ } else { -++ air_sched->weight_sum_reciprocal = 0; -++ } -++} -++ -++/* A problem when trying to enforce airtime fairness is that we want to divide -++ * the airtime between the currently *active* stations. However, basing this on -++ * the instantaneous queue state of stations doesn't work, as queues tend to -++ * oscillate very quickly between empty and occupied, leading to the scheduler -++ * thinking only a single station is active when deciding whether to allow -++ * transmission (and thus not throttling correctly). -++ * -++ * To fix this we use a timer-based notion of activity: a station is considered -++ * active if it has been scheduled within the last 100 ms; we keep a separate -++ * list of all the stations considered active in this manner, and lazily update -++ * the total weight of active stations from this list (filtering the stations in -++ * the list by their 'last active' time). -++ * -++ * We add one additional safeguard to guard against stations that manage to get -++ * scheduled every 100 ms but don't transmit a lot of data, and thus don't use -++ * up any airtime. Such stations would be able to get priority for an extended -++ * period of time if they do start transmitting at full capacity again, and so -++ * we add an explicit maximum for how far behind a station is allowed to fall in -++ * the virtual airtime domain. This limit is set to a relatively high value of -++ * 20 ms because the main mechanism for catching up idle stations is the active -++ * state as described above; i.e., the hard limit should only be hit in -++ * pathological cases. -++ */ -++#define AIRTIME_ACTIVE_DURATION (100 * NSEC_PER_MSEC) -++#define AIRTIME_MAX_BEHIND 20000 /* 20 ms */ -++ -++static inline bool airtime_is_active(struct airtime_info *air_info, u64 now) -++{ -++ return air_info->last_scheduled >= now - AIRTIME_ACTIVE_DURATION; -++} -++ -++static inline void airtime_set_active(struct airtime_sched_info *air_sched, -++ struct airtime_info *air_info, u64 now) -++{ -++ air_info->last_scheduled = now; -++ air_sched->last_schedule_activity = now; -++ list_move_tail(&air_info->list, &air_sched->active_list); -++} -++ -++static inline bool airtime_catchup_v_t(struct airtime_sched_info *air_sched, -++ u64 v_t, u64 now) -++{ -++ air_sched->v_t = v_t; -++ return true; -++} -++ -++static inline void init_airtime_info(struct airtime_info *air_info, -++ struct airtime_sched_info *air_sched) -++{ -++ atomic_set(&air_info->aql_tx_pending, 0); -++ air_info->aql_limit_low = air_sched->aql_txq_limit_low; -++ air_info->aql_limit_high = air_sched->aql_txq_limit_high; -++ airtime_weight_set(air_info, IEEE80211_DEFAULT_AIRTIME_WEIGHT); -++ INIT_LIST_HEAD(&air_info->list); -++} -++ -+ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) -+ { -+ return ether_addr_equal(raddr, addr) || -+@@ -1821,6 +1971,14 @@ int ieee80211_tx_control_port(struct wip -+ u64 *cookie); -+ int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *buf, size_t len); -++void ieee80211_resort_txq(struct ieee80211_hw *hw, -++ struct ieee80211_txq *txq); -++void ieee80211_unschedule_txq(struct ieee80211_hw *hw, -++ struct ieee80211_txq *txq, -++ bool purge); -++void ieee80211_update_airtime_weight(struct ieee80211_local *local, -++ struct airtime_sched_info *air_sched, -++ u64 now, bool force); -+ -+ /* HT */ -+ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, -+--- a/net/mac80211/iface.c -++++ b/net/mac80211/iface.c -+@@ -2067,6 +2067,9 @@ int ieee80211_if_add(struct ieee80211_lo -+ } -+ } -+ -++ for (i = 0; i < IEEE80211_NUM_ACS; i++) -++ init_airtime_info(&sdata->airtime[i], &local->airtime[i]); -++ -+ ieee80211_set_default_queues(sdata); -+ -+ sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; -+--- a/net/mac80211/main.c -++++ b/net/mac80211/main.c -+@@ -693,10 +693,13 @@ struct ieee80211_hw *ieee80211_alloc_hw_ -+ spin_lock_init(&local->queue_stop_reason_lock); -+ -+ for (i = 0; i < IEEE80211_NUM_ACS; i++) { -+- INIT_LIST_HEAD(&local->active_txqs[i]); -+- spin_lock_init(&local->active_txq_lock[i]); -+- local->aql_txq_limit_low[i] = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; -+- local->aql_txq_limit_high[i] = -++ struct airtime_sched_info *air_sched = &local->airtime[i]; -++ -++ air_sched->active_txqs = RB_ROOT_CACHED; -++ INIT_LIST_HEAD(&air_sched->active_list); -++ spin_lock_init(&air_sched->lock); -++ air_sched->aql_txq_limit_low = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; -++ air_sched->aql_txq_limit_high = -+ IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H; -+ } -+ -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -1573,12 +1573,8 @@ static void sta_ps_start(struct sta_info -+ -+ for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { -+ struct ieee80211_txq *txq = sta->sta.txq[tid]; -+- struct txq_info *txqi = to_txq_info(txq); -+ -+- spin_lock(&local->active_txq_lock[txq->ac]); -+- if (!list_empty(&txqi->schedule_order)) -+- list_del_init(&txqi->schedule_order); -+- spin_unlock(&local->active_txq_lock[txq->ac]); -++ ieee80211_unschedule_txq(&local->hw, txq, false); -+ -+ if (txq_has_queue(txq)) -+ set_bit(tid, &sta->txq_buffered_tids); -+--- a/net/mac80211/sta_info.c -++++ b/net/mac80211/sta_info.c -+@@ -426,15 +426,11 @@ struct sta_info *sta_info_alloc(struct i -+ if (sta_prepare_rate_control(local, sta, gfp)) -+ goto free_txq; -+ -+- sta->airtime_weight = IEEE80211_DEFAULT_AIRTIME_WEIGHT; -+ -+ for (i = 0; i < IEEE80211_NUM_ACS; i++) { -+ skb_queue_head_init(&sta->ps_tx_buf[i]); -+ skb_queue_head_init(&sta->tx_filtered[i]); -+- sta->airtime[i].deficit = sta->airtime_weight; -+- atomic_set(&sta->airtime[i].aql_tx_pending, 0); -+- sta->airtime[i].aql_limit_low = local->aql_txq_limit_low[i]; -+- sta->airtime[i].aql_limit_high = local->aql_txq_limit_high[i]; -++ init_airtime_info(&sta->airtime[i], &local->airtime[i]); -+ } -+ -+ for (i = 0; i < IEEE80211_NUM_TIDS; i++) -+@@ -1898,24 +1894,59 @@ void ieee80211_sta_set_buffered(struct i -+ } -+ EXPORT_SYMBOL(ieee80211_sta_set_buffered); -+ -+-void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, -+- u32 tx_airtime, u32 rx_airtime) -++void ieee80211_register_airtime(struct ieee80211_txq *txq, -++ u32 tx_airtime, u32 rx_airtime) -+ { -+- struct sta_info *sta = container_of(pubsta, struct sta_info, sta); -+- struct ieee80211_local *local = sta->sdata->local; -+- u8 ac = ieee80211_ac_from_tid(tid); -++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif); -++ struct ieee80211_local *local = sdata->local; -++ u64 weight_sum, weight_sum_reciprocal; -++ struct airtime_sched_info *air_sched; -++ struct airtime_info *air_info; -+ u32 airtime = 0; -+ -+- if (sta->local->airtime_flags & AIRTIME_USE_TX) -++ air_sched = &local->airtime[txq->ac]; -++ air_info = to_airtime_info(txq); -++ -++ if (local->airtime_flags & AIRTIME_USE_TX) -+ airtime += tx_airtime; -+- if (sta->local->airtime_flags & AIRTIME_USE_RX) -++ if (local->airtime_flags & AIRTIME_USE_RX) -+ airtime += rx_airtime; -+ -+- spin_lock_bh(&local->active_txq_lock[ac]); -+- sta->airtime[ac].tx_airtime += tx_airtime; -+- sta->airtime[ac].rx_airtime += rx_airtime; -+- sta->airtime[ac].deficit -= airtime; -+- spin_unlock_bh(&local->active_txq_lock[ac]); -++ /* Weights scale so the unit weight is 256 */ -++ airtime <<= 8; -++ -++ spin_lock_bh(&air_sched->lock); -++ -++ air_info->tx_airtime += tx_airtime; -++ air_info->rx_airtime += rx_airtime; -++ -++ if (air_sched->weight_sum) { -++ weight_sum = air_sched->weight_sum; -++ weight_sum_reciprocal = air_sched->weight_sum_reciprocal; -++ } else { -++ weight_sum = air_info->weight; -++ weight_sum_reciprocal = air_info->weight_reciprocal; -++ } -++ -++ /* Round the calculation of global vt */ -++ air_sched->v_t += (u64)((airtime + (weight_sum >> 1)) * -++ weight_sum_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_64; -++ air_info->v_t += (u32)((airtime + (air_info->weight >> 1)) * -++ air_info->weight_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_32; -++ ieee80211_resort_txq(&local->hw, txq); -++ -++ spin_unlock_bh(&air_sched->lock); -++} -++ -++void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, -++ u32 tx_airtime, u32 rx_airtime) -++{ -++ struct ieee80211_txq *txq = pubsta->txq[tid]; -++ -++ if (!txq) -++ return; -++ -++ ieee80211_register_airtime(txq, tx_airtime, rx_airtime); -+ } -+ EXPORT_SYMBOL(ieee80211_sta_register_airtime); -+ -+@@ -2364,7 +2395,7 @@ void sta_set_sinfo(struct sta_info *sta, -+ } -+ -+ if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { -+- sinfo->airtime_weight = sta->airtime_weight; -++ sinfo->airtime_weight = sta->airtime[0].weight; -+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); -+ } -+ -+--- a/net/mac80211/sta_info.h -++++ b/net/mac80211/sta_info.h -+@@ -135,18 +135,25 @@ enum ieee80211_agg_stop_reason { -+ #define AIRTIME_USE_TX BIT(0) -+ #define AIRTIME_USE_RX BIT(1) -+ -++ -+ struct airtime_info { -+ u64 rx_airtime; -+ u64 tx_airtime; -+- s64 deficit; -++ u64 v_t; -++ u64 last_scheduled; -++ struct list_head list; -+ atomic_t aql_tx_pending; /* Estimated airtime for frames pending */ -+ u32 aql_limit_low; -+ u32 aql_limit_high; -++ u32 weight_reciprocal; -++ u16 weight; -+ }; -+ -+ void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, -+ struct sta_info *sta, u8 ac, -+ u16 tx_airtime, bool tx_completed); -++void ieee80211_register_airtime(struct ieee80211_txq *txq, -++ u32 tx_airtime, u32 rx_airtime); -+ -+ struct sta_info; -+ -+@@ -515,7 +522,6 @@ struct ieee80211_fragment_cache { -+ * @tid_seq: per-TID sequence numbers for sending to this STA -+ * @airtime: per-AC struct airtime_info describing airtime statistics for this -+ * station -+- * @airtime_weight: station weight for airtime fairness calculation purposes -+ * @ampdu_mlme: A-MPDU state machine state -+ * @mesh: mesh STA information -+ * @debugfs_dir: debug filesystem directory dentry -+@@ -646,7 +652,6 @@ struct sta_info { -+ u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; -+ -+ struct airtime_info airtime[IEEE80211_NUM_ACS]; -+- u16 airtime_weight; -+ -+ /* -+ * Aggregation information, locked with lock. -+--- a/net/mac80211/status.c -++++ b/net/mac80211/status.c -+@@ -972,6 +972,25 @@ static void __ieee80211_tx_status(struct -+ if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked) -+ ieee80211_frame_acked(sta, skb); -+ -++ } else if (wiphy_ext_feature_isset(local->hw.wiphy, -++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) { -++ struct ieee80211_sub_if_data *sdata; -++ struct ieee80211_txq *txq; -++ u32 airtime; -++ -++ /* Account airtime to multicast queue */ -++ sdata = ieee80211_sdata_from_skb(local, skb); -++ -++ if (sdata && (txq = sdata->vif.txq)) { -++ airtime = info->status.tx_time ?: -++ ieee80211_calc_expected_tx_airtime(hw, -++ &sdata->vif, -++ NULL, -++ skb->len, -++ false); -++ -++ ieee80211_register_airtime(txq, airtime, 0); -++ } -+ } -+ -+ /* SNMP counters -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -18,6 +18,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -1489,7 +1490,7 @@ void ieee80211_txq_init(struct ieee80211 -+ codel_vars_init(&txqi->def_cvars); -+ codel_stats_init(&txqi->cstats); -+ __skb_queue_head_init(&txqi->frags); -+- INIT_LIST_HEAD(&txqi->schedule_order); -++ RB_CLEAR_NODE(&txqi->schedule_order); -+ -+ txqi->txq.vif = &sdata->vif; -+ -+@@ -1533,9 +1534,7 @@ void ieee80211_txq_purge(struct ieee8021 -+ ieee80211_purge_tx_queue(&local->hw, &txqi->frags); -+ spin_unlock_bh(&fq->lock); -+ -+- spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]); -+- list_del_init(&txqi->schedule_order); -+- spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]); -++ ieee80211_unschedule_txq(&local->hw, &txqi->txq, true); -+ } -+ -+ void ieee80211_txq_set_params(struct ieee80211_local *local) -+@@ -3797,102 +3796,259 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue); -+ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) -+ { -+ struct ieee80211_local *local = hw_to_local(hw); -++ struct airtime_sched_info *air_sched; -++ u64 now = ktime_get_boottime_ns(); -+ struct ieee80211_txq *ret = NULL; -+- struct txq_info *txqi = NULL, *head = NULL; -+- bool found_eligible_txq = false; -++ struct airtime_info *air_info; -++ struct txq_info *txqi = NULL; -++ struct rb_node *node; -++ bool first = false; -+ -+- spin_lock_bh(&local->active_txq_lock[ac]); -++ air_sched = &local->airtime[ac]; -++ spin_lock_bh(&air_sched->lock); -+ -+- begin: -+- txqi = list_first_entry_or_null(&local->active_txqs[ac], -+- struct txq_info, -+- schedule_order); -+- if (!txqi) -++ node = air_sched->schedule_pos; -++ -++begin: -++ if (!node) { -++ node = rb_first_cached(&air_sched->active_txqs); -++ first = true; -++ } else { -++ node = rb_next(node); -++ } -++ -++ if (!node) -+ goto out; -+ -+- if (txqi == head) { -+- if (!found_eligible_txq) -+- goto out; -+- else -+- found_eligible_txq = false; -++ txqi = container_of(node, struct txq_info, schedule_order); -++ air_info = to_airtime_info(&txqi->txq); -++ -++ if (air_info->v_t > air_sched->v_t && -++ (!first || !airtime_catchup_v_t(air_sched, air_info->v_t, now))) -++ goto out; -++ -++ if (!ieee80211_txq_airtime_check(hw, &txqi->txq)) { -++ first = false; -++ goto begin; -+ } -+ -+- if (!head) -+- head = txqi; -++ air_sched->schedule_pos = node; -++ air_sched->last_schedule_activity = now; -++ ret = &txqi->txq; -++out: -++ spin_unlock_bh(&air_sched->lock); -++ return ret; -++} -++EXPORT_SYMBOL(ieee80211_next_txq); -+ -+- if (txqi->txq.sta) { -+- struct sta_info *sta = container_of(txqi->txq.sta, -+- struct sta_info, sta); -+- bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq); -+- s64 deficit = sta->airtime[txqi->txq.ac].deficit; -++static void __ieee80211_insert_txq(struct rb_root_cached *root, -++ struct txq_info *txqi) -++{ -++ struct rb_node **new = &root->rb_root.rb_node; -++ struct airtime_info *old_air, *new_air; -++ struct rb_node *parent = NULL; -++ struct txq_info *__txqi; -++ bool leftmost = true; -++ -++ while (*new) { -++ parent = *new; -++ __txqi = rb_entry(parent, struct txq_info, schedule_order); -++ old_air = to_airtime_info(&__txqi->txq); -++ new_air = to_airtime_info(&txqi->txq); -+ -+- if (aql_check) -+- found_eligible_txq = true; -++ if (new_air->v_t <= old_air->v_t) { -++ new = &parent->rb_left; -++ } else { -++ new = &parent->rb_right; -++ leftmost = false; -++ } -++ } -+ -+- if (deficit < 0) -+- sta->airtime[txqi->txq.ac].deficit += -+- sta->airtime_weight; -+- -+- if (deficit < 0 || !aql_check) { -+- list_move_tail(&txqi->schedule_order, -+- &local->active_txqs[txqi->txq.ac]); -+- goto begin; -++ rb_link_node(&txqi->schedule_order, parent, new); -++ rb_insert_color_cached(&txqi->schedule_order, root, leftmost); -++} -++ -++void ieee80211_resort_txq(struct ieee80211_hw *hw, -++ struct ieee80211_txq *txq) -++{ -++ struct airtime_info *air_info = to_airtime_info(txq); -++ struct ieee80211_local *local = hw_to_local(hw); -++ struct txq_info *txqi = to_txq_info(txq); -++ struct airtime_sched_info *air_sched; -++ -++ air_sched = &local->airtime[txq->ac]; -++ -++ lockdep_assert_held(&air_sched->lock); -++ -++ if (!RB_EMPTY_NODE(&txqi->schedule_order)) { -++ struct airtime_info *a_prev = NULL, *a_next = NULL; -++ struct txq_info *t_prev, *t_next; -++ struct rb_node *n_prev, *n_next; -++ -++ /* Erasing a node can cause an expensive rebalancing operation, -++ * so we check the previous and next nodes first and only remove -++ * and re-insert if the current node is not already in the -++ * correct position. -++ */ -++ if ((n_prev = rb_prev(&txqi->schedule_order)) != NULL) { -++ t_prev = container_of(n_prev, struct txq_info, -++ schedule_order); -++ a_prev = to_airtime_info(&t_prev->txq); -++ } -++ -++ if ((n_next = rb_next(&txqi->schedule_order)) != NULL) { -++ t_next = container_of(n_next, struct txq_info, -++ schedule_order); -++ a_next = to_airtime_info(&t_next->txq); -+ } -++ -++ if ((!a_prev || a_prev->v_t <= air_info->v_t) && -++ (!a_next || a_next->v_t > air_info->v_t)) -++ return; -++ -++ if (air_sched->schedule_pos == &txqi->schedule_order) -++ air_sched->schedule_pos = n_prev; -++ -++ rb_erase_cached(&txqi->schedule_order, -++ &air_sched->active_txqs); -++ RB_CLEAR_NODE(&txqi->schedule_order); -++ __ieee80211_insert_txq(&air_sched->active_txqs, txqi); -+ } -++} -++ -++void ieee80211_update_airtime_weight(struct ieee80211_local *local, -++ struct airtime_sched_info *air_sched, -++ u64 now, bool force) -++{ -++ struct airtime_info *air_info, *tmp; -++ u64 weight_sum = 0; -++ -++ if (unlikely(!now)) -++ now = ktime_get_boottime_ns(); -++ -++ lockdep_assert_held(&air_sched->lock); -++ -++ if (!force && (air_sched->last_weight_update < -++ now - AIRTIME_ACTIVE_DURATION)) -++ return; -++ -++ list_for_each_entry_safe(air_info, tmp, -++ &air_sched->active_list, list) { -++ if (airtime_is_active(air_info, now)) -++ weight_sum += air_info->weight; -++ else -++ list_del_init(&air_info->list); -++ } -++ airtime_weight_sum_set(air_sched, weight_sum); -++ air_sched->last_weight_update = now; -++} -+ -++void ieee80211_schedule_txq(struct ieee80211_hw *hw, -++ struct ieee80211_txq *txq) -++ __acquires(txq_lock) __releases(txq_lock) -++{ -++ struct ieee80211_local *local = hw_to_local(hw); -++ struct txq_info *txqi = to_txq_info(txq); -++ struct airtime_sched_info *air_sched; -++ u64 now = ktime_get_boottime_ns(); -++ struct airtime_info *air_info; -++ u8 ac = txq->ac; -++ bool was_active; -+ -+- if (txqi->schedule_round == local->schedule_round[ac]) -++ air_sched = &local->airtime[ac]; -++ air_info = to_airtime_info(txq); -++ -++ spin_lock_bh(&air_sched->lock); -++ was_active = airtime_is_active(air_info, now); -++ airtime_set_active(air_sched, air_info, now); -++ -++ if (!RB_EMPTY_NODE(&txqi->schedule_order)) -+ goto out; -+ -+- list_del_init(&txqi->schedule_order); -+- txqi->schedule_round = local->schedule_round[ac]; -+- ret = &txqi->txq; -++ /* If the station has been inactive for a while, catch up its v_t so it -++ * doesn't get indefinite priority; see comment above the definition of -++ * AIRTIME_MAX_BEHIND. -++ */ -++ if ((!was_active && air_info->v_t < air_sched->v_t) || -++ air_info->v_t < air_sched->v_t - AIRTIME_MAX_BEHIND) -++ air_info->v_t = air_sched->v_t; -++ -++ ieee80211_update_airtime_weight(local, air_sched, now, !was_active); -++ __ieee80211_insert_txq(&air_sched->active_txqs, txqi); -+ -+ out: -+- spin_unlock_bh(&local->active_txq_lock[ac]); -+- return ret; -++ spin_unlock_bh(&air_sched->lock); -+ } -+-EXPORT_SYMBOL(ieee80211_next_txq); -++EXPORT_SYMBOL(ieee80211_schedule_txq); -+ -+-void __ieee80211_schedule_txq(struct ieee80211_hw *hw, -+- struct ieee80211_txq *txq, -+- bool force) -++static void __ieee80211_unschedule_txq(struct ieee80211_hw *hw, -++ struct ieee80211_txq *txq, -++ bool purge) -+ { -+ struct ieee80211_local *local = hw_to_local(hw); -+ struct txq_info *txqi = to_txq_info(txq); -++ struct airtime_sched_info *air_sched; -++ struct airtime_info *air_info; -+ -+- spin_lock_bh(&local->active_txq_lock[txq->ac]); -++ air_sched = &local->airtime[txq->ac]; -++ air_info = to_airtime_info(&txqi->txq); -+ -+- if (list_empty(&txqi->schedule_order) && -+- (force || !skb_queue_empty(&txqi->frags) || -+- txqi->tin.backlog_packets)) { -+- /* If airtime accounting is active, always enqueue STAs at the -+- * head of the list to ensure that they only get moved to the -+- * back by the airtime DRR scheduler once they have a negative -+- * deficit. A station that already has a negative deficit will -+- * get immediately moved to the back of the list on the next -+- * call to ieee80211_next_txq(). -+- */ -+- if (txqi->txq.sta && local->airtime_flags && -+- wiphy_ext_feature_isset(local->hw.wiphy, -+- NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) -+- list_add(&txqi->schedule_order, -+- &local->active_txqs[txq->ac]); -+- else -+- list_add_tail(&txqi->schedule_order, -+- &local->active_txqs[txq->ac]); -++ lockdep_assert_held(&air_sched->lock); -++ -++ if (purge) { -++ list_del_init(&air_info->list); -++ ieee80211_update_airtime_weight(local, air_sched, 0, true); -+ } -+ -+- spin_unlock_bh(&local->active_txq_lock[txq->ac]); -++ if (RB_EMPTY_NODE(&txqi->schedule_order)) -++ return; -++ -++ if (air_sched->schedule_pos == &txqi->schedule_order) -++ air_sched->schedule_pos = rb_prev(&txqi->schedule_order); -++ -++ if (!purge) -++ airtime_set_active(air_sched, air_info, -++ ktime_get_boottime_ns()); -++ -++ rb_erase_cached(&txqi->schedule_order, -++ &air_sched->active_txqs); -++ RB_CLEAR_NODE(&txqi->schedule_order); -++} -++ -++void ieee80211_unschedule_txq(struct ieee80211_hw *hw, -++ struct ieee80211_txq *txq, -++ bool purge) -++ __acquires(txq_lock) __releases(txq_lock) -++{ -++ struct ieee80211_local *local = hw_to_local(hw); -++ -++ spin_lock_bh(&local->airtime[txq->ac].lock); -++ __ieee80211_unschedule_txq(hw, txq, purge); -++ spin_unlock_bh(&local->airtime[txq->ac].lock); -++} -++ -++void ieee80211_return_txq(struct ieee80211_hw *hw, -++ struct ieee80211_txq *txq, bool force) -++{ -++ struct ieee80211_local *local = hw_to_local(hw); -++ struct txq_info *txqi = to_txq_info(txq); -++ -++ spin_lock_bh(&local->airtime[txq->ac].lock); -++ -++ if (!RB_EMPTY_NODE(&txqi->schedule_order) && !force && -++ !txq_has_queue(txq)) -++ __ieee80211_unschedule_txq(hw, txq, false); -++ -++ spin_unlock_bh(&local->airtime[txq->ac].lock); -+ } -+-EXPORT_SYMBOL(__ieee80211_schedule_txq); -++EXPORT_SYMBOL(ieee80211_return_txq); -+ -+ DEFINE_STATIC_KEY_FALSE(aql_disable); -+ -+ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, -+ struct ieee80211_txq *txq) -+ { -+- struct sta_info *sta; -++ struct airtime_info *air_info = to_airtime_info(txq); -+ struct ieee80211_local *local = hw_to_local(hw); -+ -+ if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) -+@@ -3907,15 +4063,12 @@ bool ieee80211_txq_airtime_check(struct -+ if (unlikely(txq->tid == IEEE80211_NUM_TIDS)) -+ return true; -+ -+- sta = container_of(txq->sta, struct sta_info, sta); -+- if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) < -+- sta->airtime[txq->ac].aql_limit_low) -++ if (atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_low) -+ return true; -+ -+ if (atomic_read(&local->aql_total_pending_airtime) < -+ local->aql_threshold && -+- atomic_read(&sta->airtime[txq->ac].aql_tx_pending) < -+- sta->airtime[txq->ac].aql_limit_high) -++ atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_high) -+ return true; -+ -+ return false; -+@@ -3925,60 +4078,59 @@ EXPORT_SYMBOL(ieee80211_txq_airtime_chec -+ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, -+ struct ieee80211_txq *txq) -+ { -++ struct txq_info *first_txqi = NULL, *txqi = to_txq_info(txq); -+ struct ieee80211_local *local = hw_to_local(hw); -+- struct txq_info *iter, *tmp, *txqi = to_txq_info(txq); -+- struct sta_info *sta; -+- u8 ac = txq->ac; -++ struct airtime_sched_info *air_sched; -++ struct airtime_info *air_info; -++ struct rb_node *node = NULL; -++ bool ret = false; -++ u64 now; -+ -+- spin_lock_bh(&local->active_txq_lock[ac]); -+ -+- if (!txqi->txq.sta) -+- goto out; -++ if (!ieee80211_txq_airtime_check(hw, txq)) -++ return false; -++ -++ air_sched = &local->airtime[txq->ac]; -++ spin_lock_bh(&air_sched->lock); -+ -+- if (list_empty(&txqi->schedule_order)) -++ if (RB_EMPTY_NODE(&txqi->schedule_order)) -+ goto out; -+ -+- list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac], -+- schedule_order) { -+- if (iter == txqi) -+- break; -++ now = ktime_get_boottime_ns(); -+ -+- if (!iter->txq.sta) { -+- list_move_tail(&iter->schedule_order, -+- &local->active_txqs[ac]); -+- continue; -+- } -+- sta = container_of(iter->txq.sta, struct sta_info, sta); -+- if (sta->airtime[ac].deficit < 0) -+- sta->airtime[ac].deficit += sta->airtime_weight; -+- list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); -++ /* Like in ieee80211_next_txq(), make sure the first station in the -++ * scheduling order is eligible for transmission to avoid starvation. -++ */ -++ node = rb_first_cached(&air_sched->active_txqs); -++ if (node) { -++ first_txqi = container_of(node, struct txq_info, -++ schedule_order); -++ air_info = to_airtime_info(&first_txqi->txq); -++ -++ if (air_sched->v_t < air_info->v_t) -++ airtime_catchup_v_t(air_sched, air_info->v_t, now); -+ } -+ -+- sta = container_of(txqi->txq.sta, struct sta_info, sta); -+- if (sta->airtime[ac].deficit >= 0) -+- goto out; -+- -+- sta->airtime[ac].deficit += sta->airtime_weight; -+- list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); -+- spin_unlock_bh(&local->active_txq_lock[ac]); -++ air_info = to_airtime_info(&txqi->txq); -++ if (air_info->v_t <= air_sched->v_t) { -++ air_sched->last_schedule_activity = now; -++ ret = true; -++ } -+ -+- return false; -+ out: -+- if (!list_empty(&txqi->schedule_order)) -+- list_del_init(&txqi->schedule_order); -+- spin_unlock_bh(&local->active_txq_lock[ac]); -+- -+- return true; -++ spin_unlock_bh(&air_sched->lock); -++ return ret; -+ } -+ EXPORT_SYMBOL(ieee80211_txq_may_transmit); -+ -+ void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) -+ { -+ struct ieee80211_local *local = hw_to_local(hw); -++ struct airtime_sched_info *air_sched = &local->airtime[ac]; -+ -+- spin_lock_bh(&local->active_txq_lock[ac]); -+- local->schedule_round[ac]++; -+- spin_unlock_bh(&local->active_txq_lock[ac]); -++ spin_lock_bh(&air_sched->lock); -++ air_sched->schedule_pos = NULL; -++ spin_unlock_bh(&air_sched->lock); -+ } -+ EXPORT_SYMBOL(ieee80211_txq_schedule_start); -+ -diff --git a/package/kernel/mac80211/patches/subsys/383-mac80211-fix-enabling-4-address-mode-on-a-sta-vif-af.patch b/package/kernel/mac80211/patches/subsys/383-mac80211-fix-enabling-4-address-mode-on-a-sta-vif-af.patch -new file mode 100644 -index 0000000000..c1f77ff5d9 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/383-mac80211-fix-enabling-4-address-mode-on-a-sta-vif-af.patch -@@ -0,0 +1,72 @@ -+From: Felix Fietkau -+Date: Fri, 2 Jul 2021 06:57:53 +0200 -+Subject: [PATCH] mac80211: fix enabling 4-address mode on a sta vif after -+ assoc -+ -+Notify the driver about the 4-address mode change and also send a nulldata -+packet to the AP to notify it about the change -+ -+Fixes: 1ff4e8f2dec8 ("mac80211: notify the driver when a sta uses 4-address mode") -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -152,6 +152,8 @@ static int ieee80211_change_iface(struct -+ struct vif_params *params) -+ { -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -++ struct ieee80211_local *local = sdata->local; -++ struct sta_info *sta; -+ int ret; -+ -+ ret = ieee80211_if_change_type(sdata, type); -+@@ -162,7 +164,24 @@ static int ieee80211_change_iface(struct -+ RCU_INIT_POINTER(sdata->u.vlan.sta, NULL); -+ ieee80211_check_fast_rx_iface(sdata); -+ } else if (type == NL80211_IFTYPE_STATION && params->use_4addr >= 0) { -++ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; -++ -++ if (params->use_4addr == ifmgd->use_4addr) -++ return 0; -++ -+ sdata->u.mgd.use_4addr = params->use_4addr; -++ if (!ifmgd->associated) -++ return 0; -++ -++ mutex_lock(&local->sta_mtx); -++ sta = sta_info_get(sdata, ifmgd->bssid); -++ if (sta) -++ drv_sta_set_4addr(local, sdata, &sta->sta, -++ params->use_4addr); -++ mutex_unlock(&local->sta_mtx); -++ -++ if (params->use_4addr) -++ ieee80211_send_4addr_nullfunc(local, sdata); -+ } -+ -+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -2215,6 +2215,8 @@ void ieee80211_dynamic_ps_timer(struct t -+ void ieee80211_send_nullfunc(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -+ bool powersave); -++void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local, -++ struct ieee80211_sub_if_data *sdata); -+ void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, -+ struct ieee80211_hdr *hdr, bool ack, u16 tx_time); -+ -+--- a/net/mac80211/mlme.c -++++ b/net/mac80211/mlme.c -+@@ -1115,8 +1115,8 @@ void ieee80211_send_nullfunc(struct ieee -+ ieee80211_tx_skb(sdata, skb); -+ } -+ -+-static void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local, -+- struct ieee80211_sub_if_data *sdata) -++void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local, -++ struct ieee80211_sub_if_data *sdata) -+ { -+ struct sk_buff *skb; -+ struct ieee80211_hdr *nullfunc; -diff --git a/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch b/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch -new file mode 100644 -index 0000000000..0c9ae3595d ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch -@@ -0,0 +1,398 @@ -+From: Carl Huang -+Date: Thu, 3 Dec 2020 05:37:26 -0500 -+Subject: [PATCH] nl80211: add common API to configure SAR power limitations -+ -+NL80211_CMD_SET_SAR_SPECS is added to configure SAR from -+user space. NL80211_ATTR_SAR_SPEC is used to pass the SAR -+power specification when used with NL80211_CMD_SET_SAR_SPECS. -+ -+Wireless driver needs to register SAR type, supported frequency -+ranges to wiphy, so user space can query it. The index in -+frequency range is used to specify which sub band the power -+limitation applies to. The SAR type is for compatibility, so later -+other SAR mechanism can be implemented without breaking the user -+space SAR applications. -+ -+Normal process is user space queries the SAR capability, and -+gets the index of supported frequency ranges and associates the -+power limitation with this index and sends to kernel. -+ -+Here is an example of message send to kernel: -+8c 00 00 00 08 00 01 00 00 00 00 00 38 00 2b 81 -+08 00 01 00 00 00 00 00 2c 00 02 80 14 00 00 80 -+08 00 02 00 00 00 00 00 08 00 01 00 38 00 00 00 -+14 00 01 80 08 00 02 00 01 00 00 00 08 00 01 00 -+48 00 00 00 -+ -+NL80211_CMD_SET_SAR_SPECS: 0x8c -+NL80211_ATTR_WIPHY: 0x01(phy idx is 0) -+NL80211_ATTR_SAR_SPEC: 0x812b (NLA_NESTED) -+NL80211_SAR_ATTR_TYPE: 0x00 (NL80211_SAR_TYPE_POWER) -+NL80211_SAR_ATTR_SPECS: 0x8002 (NLA_NESTED) -+freq range 0 power: 0x38 in 0.25dbm unit (14dbm) -+freq range 1 power: 0x48 in 0.25dbm unit (18dbm) -+ -+Signed-off-by: Carl Huang -+Reviewed-by: Brian Norris -+Reviewed-by: Abhishek Kumar -+Link: https://lore.kernel.org/r/20201203103728.3034-2-cjhuang@codeaurora.org -+[minor edits, NLA parse cleanups] -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/include/net/cfg80211.h -++++ b/include/net/cfg80211.h -+@@ -1737,6 +1737,54 @@ struct station_info { -+ u8 connected_to_as; -+ }; -+ -++/** -++ * struct cfg80211_sar_sub_specs - sub specs limit -++ * @power: power limitation in 0.25dbm -++ * @freq_range_index: index the power limitation applies to -++ */ -++struct cfg80211_sar_sub_specs { -++ s32 power; -++ u32 freq_range_index; -++}; -++ -++/** -++ * struct cfg80211_sar_specs - sar limit specs -++ * @type: it's set with power in 0.25dbm or other types -++ * @num_sub_specs: number of sar sub specs -++ * @sub_specs: memory to hold the sar sub specs -++ */ -++struct cfg80211_sar_specs { -++ enum nl80211_sar_type type; -++ u32 num_sub_specs; -++ struct cfg80211_sar_sub_specs sub_specs[]; -++}; -++ -++ -++/** -++ * @struct cfg80211_sar_chan_ranges - sar frequency ranges -++ * @start_freq: start range edge frequency -++ * @end_freq: end range edge frequency -++ */ -++struct cfg80211_sar_freq_ranges { -++ u32 start_freq; -++ u32 end_freq; -++}; -++ -++/** -++ * struct cfg80211_sar_capa - sar limit capability -++ * @type: it's set via power in 0.25dbm or other types -++ * @num_freq_ranges: number of frequency ranges -++ * @freq_ranges: memory to hold the freq ranges. -++ * -++ * Note: WLAN driver may append new ranges or split an existing -++ * range to small ones and then append them. -++ */ -++struct cfg80211_sar_capa { -++ enum nl80211_sar_type type; -++ u32 num_freq_ranges; -++ const struct cfg80211_sar_freq_ranges *freq_ranges; -++}; -++ -+ #if IS_ENABLED(CPTCFG_CFG80211) -+ /** -+ * cfg80211_get_station - retrieve information about a given station -+@@ -4259,6 +4307,8 @@ struct cfg80211_ops { -+ struct cfg80211_tid_config *tid_conf); -+ int (*reset_tid_config)(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, u8 tids); -++ int (*set_sar_specs)(struct wiphy *wiphy, -++ struct cfg80211_sar_specs *sar); -+ }; -+ -+ /* -+@@ -5030,6 +5080,8 @@ struct wiphy { -+ -+ u8 max_data_retry_count; -+ -++ const struct cfg80211_sar_capa *sar_capa; -++ -+ char priv[] __aligned(NETDEV_ALIGN); -+ }; -+ -+--- a/net/wireless/nl80211.c -++++ b/net/wireless/nl80211.c -+@@ -405,6 +405,18 @@ nl80211_unsol_bcast_probe_resp_policy[NL -+ .len = IEEE80211_MAX_DATA_LEN } -+ }; -+ -++static const struct nla_policy -++sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = { -++ [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_S32 }, -++ [NL80211_SAR_ATTR_SPECS_RANGE_INDEX] = {.type = NLA_U32 }, -++}; -++ -++static const struct nla_policy -++sar_policy[NL80211_SAR_ATTR_MAX + 1] = { -++ [NL80211_SAR_ATTR_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_SAR_TYPE), -++ [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy), -++}; -++ -+ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { -+ [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD }, -+ [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, -+@@ -739,6 +751,7 @@ static const struct nla_policy nl80211_p -+ [NL80211_ATTR_SAE_PWE] = -+ NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK, -+ NL80211_SAE_PWE_BOTH), -++ [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy), -+ [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT }, -+ }; -+ -+@@ -2117,6 +2130,56 @@ fail: -+ return -ENOBUFS; -+ } -+ -++static int -++nl80211_put_sar_specs(struct cfg80211_registered_device *rdev, -++ struct sk_buff *msg) -++{ -++ struct nlattr *sar_capa, *specs, *sub_freq_range; -++ u8 num_freq_ranges; -++ int i; -++ -++ if (!rdev->wiphy.sar_capa) -++ return 0; -++ -++ num_freq_ranges = rdev->wiphy.sar_capa->num_freq_ranges; -++ -++ sar_capa = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC); -++ if (!sar_capa) -++ return -ENOSPC; -++ -++ if (nla_put_u32(msg, NL80211_SAR_ATTR_TYPE, rdev->wiphy.sar_capa->type)) -++ goto fail; -++ -++ specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS); -++ if (!specs) -++ goto fail; -++ -++ /* report supported freq_ranges */ -++ for (i = 0; i < num_freq_ranges; i++) { -++ sub_freq_range = nla_nest_start(msg, i + 1); -++ if (!sub_freq_range) -++ goto fail; -++ -++ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ, -++ rdev->wiphy.sar_capa->freq_ranges[i].start_freq)) -++ goto fail; -++ -++ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ, -++ rdev->wiphy.sar_capa->freq_ranges[i].end_freq)) -++ goto fail; -++ -++ nla_nest_end(msg, sub_freq_range); -++ } -++ -++ nla_nest_end(msg, specs); -++ nla_nest_end(msg, sar_capa); -++ -++ return 0; -++fail: -++ nla_nest_cancel(msg, sar_capa); -++ return -ENOBUFS; -++} -++ -+ struct nl80211_dump_wiphy_state { -+ s64 filter_wiphy; -+ long start; -+@@ -2366,6 +2429,8 @@ static int nl80211_send_wiphy(struct cfg -+ CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST); -+ CMD(update_connect_params, UPDATE_CONNECT_PARAMS); -+ CMD(update_ft_ies, UPDATE_FT_IES); -++ if (rdev->wiphy.sar_capa) -++ CMD(set_sar_specs, SET_SAR_SPECS); -+ } -+ #undef CMD -+ -+@@ -2691,6 +2756,11 @@ static int nl80211_send_wiphy(struct cfg -+ -+ if (nl80211_put_tid_config_support(rdev, msg)) -+ goto nla_put_failure; -++ state->split_start++; -++ break; -++ case 16: -++ if (nl80211_put_sar_specs(rdev, msg)) -++ goto nla_put_failure; -+ -+ /* done */ -+ state->split_start = 0; -+@@ -14713,6 +14783,111 @@ static void nl80211_post_doit(__genl_con -+ } -+ } -+ -++static int nl80211_set_sar_sub_specs(struct cfg80211_registered_device *rdev, -++ struct cfg80211_sar_specs *sar_specs, -++ struct nlattr *spec[], int index) -++{ -++ u32 range_index, i; -++ -++ if (!sar_specs || !spec) -++ return -EINVAL; -++ -++ if (!spec[NL80211_SAR_ATTR_SPECS_POWER] || -++ !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]) -++ return -EINVAL; -++ -++ range_index = nla_get_u32(spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]); -++ -++ /* check if range_index exceeds num_freq_ranges */ -++ if (range_index >= rdev->wiphy.sar_capa->num_freq_ranges) -++ return -EINVAL; -++ -++ /* check if range_index duplicates */ -++ for (i = 0; i < index; i++) { -++ if (sar_specs->sub_specs[i].freq_range_index == range_index) -++ return -EINVAL; -++ } -++ -++ sar_specs->sub_specs[index].power = -++ nla_get_s32(spec[NL80211_SAR_ATTR_SPECS_POWER]); -++ -++ sar_specs->sub_specs[index].freq_range_index = range_index; -++ -++ return 0; -++} -++ -++static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info) -++{ -++ struct cfg80211_registered_device *rdev = info->user_ptr[0]; -++ struct nlattr *spec[NL80211_SAR_ATTR_SPECS_MAX + 1]; -++ struct nlattr *tb[NL80211_SAR_ATTR_MAX + 1]; -++ struct cfg80211_sar_specs *sar_spec; -++ enum nl80211_sar_type type; -++ struct nlattr *spec_list; -++ u32 specs; -++ int rem, err; -++ -++ if (!rdev->wiphy.sar_capa || !rdev->ops->set_sar_specs) -++ return -EOPNOTSUPP; -++ -++ if (!info->attrs[NL80211_ATTR_SAR_SPEC]) -++ return -EINVAL; -++ -++ nla_parse_nested(tb, NL80211_SAR_ATTR_MAX, -++ info->attrs[NL80211_ATTR_SAR_SPEC], -++ NULL, NULL); -++ -++ if (!tb[NL80211_SAR_ATTR_TYPE] || !tb[NL80211_SAR_ATTR_SPECS]) -++ return -EINVAL; -++ -++ type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]); -++ if (type != rdev->wiphy.sar_capa->type) -++ return -EINVAL; -++ -++ specs = 0; -++ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) -++ specs++; -++ -++ if (specs > rdev->wiphy.sar_capa->num_freq_ranges) -++ return -EINVAL; -++ -++ sar_spec = kzalloc(sizeof(*sar_spec) + -++ specs * sizeof(struct cfg80211_sar_sub_specs), -++ GFP_KERNEL); -++ if (!sar_spec) -++ return -ENOMEM; -++ -++ sar_spec->type = type; -++ specs = 0; -++ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) { -++ nla_parse_nested(spec, NL80211_SAR_ATTR_SPECS_MAX, -++ spec_list, NULL, NULL); -++ -++ switch (type) { -++ case NL80211_SAR_TYPE_POWER: -++ if (nl80211_set_sar_sub_specs(rdev, sar_spec, -++ spec, specs)) { -++ err = -EINVAL; -++ goto error; -++ } -++ break; -++ default: -++ err = -EINVAL; -++ goto error; -++ } -++ specs++; -++ } -++ -++ sar_spec->num_sub_specs = specs; -++ -++ rdev->cur_cmd_info = info; -++ err = rdev_set_sar_specs(rdev, sar_spec); -++ rdev->cur_cmd_info = NULL; -++error: -++ kfree(sar_spec); -++ return err; -++} -++ -+ static __genl_const struct genl_ops nl80211_ops[] = { -+ { -+ .cmd = NL80211_CMD_GET_WIPHY, -+@@ -15576,6 +15751,14 @@ static const struct genl_small_ops nl802 -+ .internal_flags = NL80211_FLAG_NEED_NETDEV | -+ NL80211_FLAG_NEED_RTNL, -+ }, -++ { -++ .cmd = NL80211_CMD_SET_SAR_SPECS, -++ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -++ .doit = nl80211_set_sar_specs, -++ .flags = GENL_UNS_ADMIN_PERM, -++ .internal_flags = NL80211_FLAG_NEED_WIPHY | -++ NL80211_FLAG_NEED_RTNL, -++ }, -+ }; -+ -+ static struct genl_family nl80211_fam __genl_ro_after_init = { -+--- a/net/wireless/rdev-ops.h -++++ b/net/wireless/rdev-ops.h -+@@ -1356,4 +1356,16 @@ static inline int rdev_reset_tid_config( -+ return ret; -+ } -+ -++static inline int rdev_set_sar_specs(struct cfg80211_registered_device *rdev, -++ struct cfg80211_sar_specs *sar) -++{ -++ int ret; -++ -++ trace_rdev_set_sar_specs(&rdev->wiphy, sar); -++ ret = rdev->ops->set_sar_specs(&rdev->wiphy, sar); -++ trace_rdev_return_int(&rdev->wiphy, ret); -++ -++ return ret; -++} -++ -+ #endif /* __CFG80211_RDEV_OPS */ -+--- a/net/wireless/trace.h -++++ b/net/wireless/trace.h -+@@ -3551,6 +3551,25 @@ TRACE_EVENT(rdev_reset_tid_config, -+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", tids: 0x%x", -+ WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->tids) -+ ); -++ -++TRACE_EVENT(rdev_set_sar_specs, -++ TP_PROTO(struct wiphy *wiphy, struct cfg80211_sar_specs *sar), -++ TP_ARGS(wiphy, sar), -++ TP_STRUCT__entry( -++ WIPHY_ENTRY -++ __field(u16, type) -++ __field(u16, num) -++ ), -++ TP_fast_assign( -++ WIPHY_ASSIGN; -++ __entry->type = sar->type; -++ __entry->num = sar->num_sub_specs; -++ -++ ), -++ TP_printk(WIPHY_PR_FMT ", Set type:%d, num_specs:%d", -++ WIPHY_PR_ARG, __entry->type, __entry->num) -++); -++ -+ #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ -+ -+ #undef TRACE_INCLUDE_PATH -diff --git a/package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch b/package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch -new file mode 100644 -index 0000000000..c351bc812a ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch -@@ -0,0 +1,51 @@ -+From: Carl Huang -+Date: Thu, 3 Dec 2020 05:37:27 -0500 -+Subject: [PATCH] mac80211: add ieee80211_set_sar_specs -+ -+This change registers ieee80211_set_sar_specs to -+mac80211_config_ops, so cfg80211 can call it. -+ -+Signed-off-by: Carl Huang -+Reviewed-by: Brian Norris -+Reviewed-by: Abhishek Kumar -+Link: https://lore.kernel.org/r/20201203103728.3034-3-cjhuang@codeaurora.org -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -4207,6 +4207,8 @@ struct ieee80211_ops { -+ struct ieee80211_vif *vif); -+ void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, bool enabled); -++ int (*set_sar_specs)(struct ieee80211_hw *hw, -++ const struct cfg80211_sar_specs *sar); -+ void (*sta_set_decap_offload)(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, bool enabled); -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -4136,6 +4136,17 @@ static int ieee80211_reset_tid_config(st -+ return ret; -+ } -+ -++static int ieee80211_set_sar_specs(struct wiphy *wiphy, -++ struct cfg80211_sar_specs *sar) -++{ -++ struct ieee80211_local *local = wiphy_priv(wiphy); -++ -++ if (!local->ops->set_sar_specs) -++ return -EOPNOTSUPP; -++ -++ return local->ops->set_sar_specs(&local->hw, sar); -++} -++ -+ const struct cfg80211_ops mac80211_config_ops = { -+ .add_virtual_intf = ieee80211_add_iface, -+ .del_virtual_intf = ieee80211_del_iface, -+@@ -4239,4 +4250,5 @@ const struct cfg80211_ops mac80211_confi -+ .probe_mesh_link = ieee80211_probe_mesh_link, -+ .set_tid_config = ieee80211_set_tid_config, -+ .reset_tid_config = ieee80211_reset_tid_config, -++ .set_sar_specs = ieee80211_set_sar_specs, -+ }; -diff --git a/package/kernel/mac80211/patches/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch b/package/kernel/mac80211/patches/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch -new file mode 100644 -index 0000000000..cfad1c3927 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch -@@ -0,0 +1,26 @@ -+From: Ryder Lee -+Date: Fri, 18 Jun 2021 04:38:59 +0800 -+Subject: [PATCH] mac80211: check per vif offload_flags in Tx path -+ -+offload_flags has been introduced to indicate encap status of each interface. -+An interface can encap offload at runtime, or if it has some extra limitations -+it can simply override the flags, so it's more flexible to check offload_flags -+in Tx path. -+ -+Signed-off-by: Ryder Lee -+Link: https://lore.kernel.org/r/177785418cf407808bf3a44760302d0647076990.1623961575.git.ryder.lee@mediatek.com -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -3309,6 +3309,9 @@ static bool ieee80211_amsdu_aggregate(st -+ if (!ieee80211_hw_check(&local->hw, TX_AMSDU)) -+ return false; -+ -++ if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) -++ return false; -++ -+ if (skb_is_gso(skb)) -+ return false; -+ -diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch -index febe42eb9d..b2ee61a6dc 100644 ---- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch -+++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch -@@ -1,6 +1,6 @@ - --- a/include/net/cfg80211.h - +++ b/include/net/cfg80211.h --@@ -3745,6 +3745,7 @@ struct mgmt_frame_regs { -+@@ -3793,6 +3793,7 @@ struct mgmt_frame_regs { - * (as advertised by the nl80211 feature flag.) - * @get_tx_power: store the current TX power into the dbm variable; - * return 0 if successful -@@ -8,7 +8,7 @@ - * - * @set_wds_peer: set the WDS peer for a WDS interface - * --@@ -4067,6 +4068,7 @@ struct cfg80211_ops { -+@@ -4115,6 +4116,7 @@ struct cfg80211_ops { - enum nl80211_tx_power_setting type, int mbm); - int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, - int *dbm); -@@ -57,7 +57,7 @@ - __NL80211_ATTR_AFTER_LAST, - --- a/net/mac80211/cfg.c - +++ b/net/mac80211/cfg.c --@@ -2709,6 +2709,19 @@ static int ieee80211_get_tx_power(struct -+@@ -2761,6 +2761,19 @@ static int ieee80211_get_tx_power(struct - return 0; - } - -@@ -77,7 +77,7 @@ - static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, - const u8 *addr) - { --@@ -4139,6 +4152,7 @@ const struct cfg80211_ops mac80211_confi -+@@ -4202,6 +4215,7 @@ const struct cfg80211_ops mac80211_confi - .set_wiphy_params = ieee80211_set_wiphy_params, - .set_tx_power = ieee80211_set_tx_power, - .get_tx_power = ieee80211_get_tx_power, -@@ -87,7 +87,7 @@ - CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) - --- a/net/mac80211/ieee80211_i.h - +++ b/net/mac80211/ieee80211_i.h --@@ -1390,6 +1390,7 @@ struct ieee80211_local { -+@@ -1426,6 +1426,7 @@ struct ieee80211_local { - int dynamic_ps_forced_timeout; - - int user_power_level; /* in dBm, for all interfaces */ -@@ -129,15 +129,15 @@ - local->hw.max_mtu = IEEE80211_MAX_DATA_LEN; - --- a/net/wireless/nl80211.c - +++ b/net/wireless/nl80211.c --@@ -740,6 +740,7 @@ static const struct nla_policy nl80211_p -- NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK, -+@@ -753,6 +753,7 @@ static const struct nla_policy nl80211_p - NL80211_SAE_PWE_BOTH), -+ [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy), - [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT }, - + [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, - }; - - /* policy for the key attributes */ --@@ -3248,6 +3249,20 @@ static int nl80211_set_wiphy(struct sk_b -+@@ -3318,6 +3319,20 @@ static int nl80211_set_wiphy(struct sk_b - if (result) - return result; - } -diff --git a/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch -new file mode 100644 -index 0000000000..5d94362155 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch -@@ -0,0 +1,237 @@ -+From 83216e3988cd196183542937c9bd58b279f946af Mon Sep 17 00:00:00 2001 -+From: Michael Walle -+Date: Mon, 12 Apr 2021 19:47:17 +0200 -+Subject: of: net: pass the dst buffer to of_get_mac_address() -+ -+of_get_mac_address() returns a "const void*" pointer to a MAC address. -+Lately, support to fetch the MAC address by an NVMEM provider was added. -+But this will only work with platform devices. It will not work with -+PCI devices (e.g. of an integrated root complex) and esp. not with DSA -+ports. -+ -+There is an of_* variant of the nvmem binding which works without -+devices. The returned data of a nvmem_cell_read() has to be freed after -+use. On the other hand the return of_get_mac_address() points to some -+static data without a lifetime. The trick for now, was to allocate a -+device resource managed buffer which is then returned. This will only -+work if we have an actual device. -+ -+Change it, so that the caller of of_get_mac_address() has to supply a -+buffer where the MAC address is written to. Unfortunately, this will -+touch all drivers which use the of_get_mac_address(). -+ -+Usually the code looks like: -+ -+ const char *addr; -+ addr = of_get_mac_address(np); -+ if (!IS_ERR(addr)) -+ ether_addr_copy(ndev->dev_addr, addr); -+ -+This can then be simply rewritten as: -+ -+ of_get_mac_address(np, ndev->dev_addr); -+ -+Sometimes is_valid_ether_addr() is used to test the MAC address. -+of_get_mac_address() already makes sure, it just returns a valid MAC -+address. Thus we can just test its return code. But we have to be -+careful if there are still other sources for the MAC address before the -+of_get_mac_address(). In this case we have to keep the -+is_valid_ether_addr() call. -+ -+The following coccinelle patch was used to convert common cases to the -+new style. Afterwards, I've manually gone over the drivers and fixed the -+return code variable: either used a new one or if one was already -+available use that. Mansour Moufid, thanks for that coccinelle patch! -+ -+ -+@a@ -+identifier x; -+expression y, z; -+@@ -+- x = of_get_mac_address(y); -++ x = of_get_mac_address(y, z); -+ <... -+- ether_addr_copy(z, x); -+ ...> -+ -+@@ -+identifier a.x; -+@@ -+- if (<+... x ...+>) {} -+ -+@@ -+identifier a.x; -+@@ -+ if (<+... x ...+>) { -+ ... -+ } -+- else {} -+ -+@@ -+identifier a.x; -+expression e; -+@@ -+- if (<+... x ...+>@e) -+- {} -+- else -++ if (!(e)) -+ {...} -+ -+@@ -+expression x, y, z; -+@@ -+- x = of_get_mac_address(y, z); -++ of_get_mac_address(y, z); -+ ... when != x -+ -+ -+All drivers, except drivers/net/ethernet/aeroflex/greth.c, were -+compile-time tested. -+ -+Suggested-by: Andrew Lunn -+Signed-off-by: Michael Walle -+Reviewed-by: Andrew Lunn -+Signed-off-by: David S. Miller -+--- -+ arch/arm/mach-mvebu/kirkwood.c | 3 +- -+ arch/powerpc/sysdev/tsi108_dev.c | 5 +- -+ drivers/net/ethernet/aeroflex/greth.c | 6 +-- -+ drivers/net/ethernet/allwinner/sun4i-emac.c | 10 ++-- -+ drivers/net/ethernet/altera/altera_tse_main.c | 7 +-- -+ drivers/net/ethernet/arc/emac_main.c | 8 +-- -+ drivers/net/ethernet/atheros/ag71xx.c | 7 +-- -+ drivers/net/ethernet/broadcom/bcm4908_enet.c | 7 +-- -+ drivers/net/ethernet/broadcom/bcmsysport.c | 7 +-- -+ drivers/net/ethernet/broadcom/bgmac-bcma.c | 10 ++-- -+ drivers/net/ethernet/broadcom/bgmac-platform.c | 11 ++-- -+ drivers/net/ethernet/cadence/macb_main.c | 11 ++-- -+ drivers/net/ethernet/cavium/octeon/octeon_mgmt.c | 8 +-- -+ drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 5 +- -+ drivers/net/ethernet/davicom/dm9000.c | 10 ++-- -+ drivers/net/ethernet/ethoc.c | 6 +-- -+ drivers/net/ethernet/ezchip/nps_enet.c | 7 +-- -+ drivers/net/ethernet/freescale/fec_main.c | 7 +-- -+ drivers/net/ethernet/freescale/fec_mpc52xx.c | 7 +-- -+ drivers/net/ethernet/freescale/fman/mac.c | 9 ++-- -+ .../net/ethernet/freescale/fs_enet/fs_enet-main.c | 5 +- -+ drivers/net/ethernet/freescale/gianfar.c | 8 +-- -+ drivers/net/ethernet/freescale/ucc_geth.c | 5 +- -+ drivers/net/ethernet/hisilicon/hisi_femac.c | 7 +-- -+ drivers/net/ethernet/hisilicon/hix5hd2_gmac.c | 7 +-- -+ drivers/net/ethernet/lantiq_xrx200.c | 7 +-- -+ drivers/net/ethernet/marvell/mv643xx_eth.c | 5 +- -+ drivers/net/ethernet/marvell/mvneta.c | 6 +-- -+ .../net/ethernet/marvell/prestera/prestera_main.c | 11 ++-- -+ drivers/net/ethernet/marvell/pxa168_eth.c | 9 +--- -+ drivers/net/ethernet/marvell/sky2.c | 8 ++- -+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 ++-- -+ drivers/net/ethernet/micrel/ks8851_common.c | 7 ++- -+ drivers/net/ethernet/microchip/lan743x_main.c | 5 +- -+ drivers/net/ethernet/nxp/lpc_eth.c | 4 +- -+ drivers/net/ethernet/qualcomm/qca_spi.c | 10 ++-- -+ drivers/net/ethernet/qualcomm/qca_uart.c | 9 +--- -+ drivers/net/ethernet/renesas/ravb_main.c | 12 +++-- -+ drivers/net/ethernet/renesas/sh_eth.c | 5 +- -+ .../net/ethernet/samsung/sxgbe/sxgbe_platform.c | 13 ++--- -+ drivers/net/ethernet/socionext/sni_ave.c | 10 ++-- -+ .../net/ethernet/stmicro/stmmac/dwmac-anarion.c | 2 +- -+ .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-generic.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 2 +- -+ .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-visconti.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 14 ++--- -+ .../net/ethernet/stmicro/stmmac/stmmac_platform.h | 2 +- -+ drivers/net/ethernet/ti/am65-cpsw-nuss.c | 19 ++++--- -+ drivers/net/ethernet/ti/cpsw.c | 7 +-- -+ drivers/net/ethernet/ti/cpsw_new.c | 7 +-- -+ drivers/net/ethernet/ti/davinci_emac.c | 8 +-- -+ drivers/net/ethernet/ti/netcp_core.c | 7 +-- -+ drivers/net/ethernet/wiznet/w5100-spi.c | 8 ++- -+ drivers/net/ethernet/wiznet/w5100.c | 2 +- -+ drivers/net/ethernet/xilinx/ll_temac_main.c | 8 +-- -+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 15 +++--- -+ drivers/net/ethernet/xilinx/xilinx_emaclite.c | 8 +-- -+ drivers/net/wireless/ath/ath9k/init.c | 5 +- -+ drivers/net/wireless/mediatek/mt76/eeprom.c | 9 +--- -+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 6 +-- -+ drivers/of/of_net.c | 60 ++++++++++------------ -+ drivers/staging/octeon/ethernet.c | 10 ++-- -+ drivers/staging/wfx/main.c | 7 ++- -+ include/linux/of_net.h | 6 +-- -+ include/net/dsa.h | 2 +- -+ net/dsa/dsa2.c | 2 +- -+ net/dsa/slave.c | 2 +- -+ net/ethernet/eth.c | 11 ++-- -+ 85 files changed, 218 insertions(+), 364 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -618,7 +618,6 @@ static int ath9k_of_init(struct ath_soft -+ struct ath_hw *ah = sc->sc_ah; -+ struct ath_common *common = ath9k_hw_common(ah); -+ enum ath_bus_type bus_type = common->bus_ops->ath_bus_type; -+- const char *mac; -+ char eeprom_name[100]; -+ int ret; -+ -+@@ -641,9 +640,7 @@ static int ath9k_of_init(struct ath_soft -+ ah->ah_flags |= AH_NO_EEP_SWAP; -+ } -+ -+- mac = of_get_mac_address(np); -+- if (!IS_ERR(mac)) -+- ether_addr_copy(common->macaddr, mac); -++ of_get_mac_address(np, common->macaddr); -+ -+ return 0; -+ } -+--- a/drivers/net/wireless/mediatek/mt76/eeprom.c -++++ b/drivers/net/wireless/mediatek/mt76/eeprom.c -+@@ -90,15 +90,9 @@ out_put_node: -+ void -+ mt76_eeprom_override(struct mt76_dev *dev) -+ { -+-#ifdef CONFIG_OF -+ struct device_node *np = dev->dev->of_node; -+- const u8 *mac = NULL; -+ -+- if (np) -+- mac = of_get_mac_address(np); -+- if (!IS_ERR_OR_NULL(mac)) -+- ether_addr_copy(dev->macaddr, mac); -+-#endif -++ of_get_mac_address(np, dev->macaddr); -+ -+ if (!is_valid_ether_addr(dev->macaddr)) { -+ eth_random_addr(dev->macaddr); -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+@@ -990,11 +990,7 @@ static void rt2x00lib_rate(struct ieee80 -+ -+ void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) -+ { -+- const char *mac_addr; -+- -+- mac_addr = of_get_mac_address(rt2x00dev->dev->of_node); -+- if (!IS_ERR(mac_addr)) -+- ether_addr_copy(eeprom_mac_addr, mac_addr); -++ of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr); -+ -+ if (!is_valid_ether_addr(eeprom_mac_addr)) { -+ eth_random_addr(eeprom_mac_addr); --- -2.25.1 - diff --git a/patches/backports/0028-mt76-update-to-latest-HEAD.patch b/patches/backports/0028-mt76-update-to-latest-HEAD.patch deleted file mode 100644 index 7ab049f0c..000000000 --- a/patches/backports/0028-mt76-update-to-latest-HEAD.patch +++ /dev/null @@ -1,247 +0,0 @@ -From 99b9f524e94b98ce8fd3e141bf7e07bfa96bbea0 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 14 Sep 2021 09:19:08 +0200 -Subject: [PATCH] mt76: update to latest HEAD - -Signed-off-by: John Crispin ---- - package/kernel/mt76/Makefile | 7 +- - ...the-dst-buffer-to-of_get_mac_address.patch | 206 ++++++++++++++++++ - 2 files changed, 210 insertions(+), 3 deletions(-) - create mode 100644 package/kernel/mt76/patches/001-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch - -diff --git a/package/kernel/mt76/Makefile b/package/kernel/mt76/Makefile -index e4051d8347..431c57a240 100644 ---- a/package/kernel/mt76/Makefile -+++ b/package/kernel/mt76/Makefile -@@ -8,11 +8,12 @@ PKG_LICENSE_FILES:= - - PKG_SOURCE_URL:=https://github.com/openwrt/mt76 - PKG_SOURCE_PROTO:=git --PKG_SOURCE_DATE:=2021-06-06 --PKG_SOURCE_VERSION:=22b690334c0f49b11534cc2e331c9d5e17c4a0bc --PKG_MIRROR_HASH:=ff5e563935919d2e40c1e7254ef3bc06f7ecc5e69f8ddd12903e8f5de942d630 -+PKG_SOURCE_DATE:=2021-07-15 -+PKG_SOURCE_VERSION:=bbebea7d6dc64313132226adc3f7369d36e9359d -+PKG_MIRROR_HASH:=17cd74e72c1f6c8742b698bf6772afacc6fba71b233af8c4d59530600cf44d5b - - PKG_MAINTAINER:=Felix Fietkau -+PKG_USE_NINJA:=0 - PKG_BUILD_PARALLEL:=1 - - PKG_CONFIG_DEPENDS += \ -diff --git a/package/kernel/mt76/patches/001-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/package/kernel/mt76/patches/001-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch -new file mode 100644 -index 0000000000..66075f2771 ---- /dev/null -+++ b/package/kernel/mt76/patches/001-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch -@@ -0,0 +1,206 @@ -+From 83216e3988cd196183542937c9bd58b279f946af Mon Sep 17 00:00:00 2001 -+From: Michael Walle -+Date: Mon, 12 Apr 2021 19:47:17 +0200 -+Subject: of: net: pass the dst buffer to of_get_mac_address() -+ -+of_get_mac_address() returns a "const void*" pointer to a MAC address. -+Lately, support to fetch the MAC address by an NVMEM provider was added. -+But this will only work with platform devices. It will not work with -+PCI devices (e.g. of an integrated root complex) and esp. not with DSA -+ports. -+ -+There is an of_* variant of the nvmem binding which works without -+devices. The returned data of a nvmem_cell_read() has to be freed after -+use. On the other hand the return of_get_mac_address() points to some -+static data without a lifetime. The trick for now, was to allocate a -+device resource managed buffer which is then returned. This will only -+work if we have an actual device. -+ -+Change it, so that the caller of of_get_mac_address() has to supply a -+buffer where the MAC address is written to. Unfortunately, this will -+touch all drivers which use the of_get_mac_address(). -+ -+Usually the code looks like: -+ -+ const char *addr; -+ addr = of_get_mac_address(np); -+ if (!IS_ERR(addr)) -+ ether_addr_copy(ndev->dev_addr, addr); -+ -+This can then be simply rewritten as: -+ -+ of_get_mac_address(np, ndev->dev_addr); -+ -+Sometimes is_valid_ether_addr() is used to test the MAC address. -+of_get_mac_address() already makes sure, it just returns a valid MAC -+address. Thus we can just test its return code. But we have to be -+careful if there are still other sources for the MAC address before the -+of_get_mac_address(). In this case we have to keep the -+is_valid_ether_addr() call. -+ -+The following coccinelle patch was used to convert common cases to the -+new style. Afterwards, I've manually gone over the drivers and fixed the -+return code variable: either used a new one or if one was already -+available use that. Mansour Moufid, thanks for that coccinelle patch! -+ -+ -+@a@ -+identifier x; -+expression y, z; -+@@ -+- x = of_get_mac_address(y); -++ x = of_get_mac_address(y, z); -+ <... -+- ether_addr_copy(z, x); -+ ...> -+ -+@@ -+identifier a.x; -+@@ -+- if (<+... x ...+>) {} -+ -+@@ -+identifier a.x; -+@@ -+ if (<+... x ...+>) { -+ ... -+ } -+- else {} -+ -+@@ -+identifier a.x; -+expression e; -+@@ -+- if (<+... x ...+>@e) -+- {} -+- else -++ if (!(e)) -+ {...} -+ -+@@ -+expression x, y, z; -+@@ -+- x = of_get_mac_address(y, z); -++ of_get_mac_address(y, z); -+ ... when != x -+ -+ -+All drivers, except drivers/net/ethernet/aeroflex/greth.c, were -+compile-time tested. -+ -+Suggested-by: Andrew Lunn -+Signed-off-by: Michael Walle -+Reviewed-by: Andrew Lunn -+Signed-off-by: David S. Miller -+--- -+ arch/arm/mach-mvebu/kirkwood.c | 3 +- -+ arch/powerpc/sysdev/tsi108_dev.c | 5 +- -+ drivers/net/ethernet/aeroflex/greth.c | 6 +-- -+ drivers/net/ethernet/allwinner/sun4i-emac.c | 10 ++-- -+ drivers/net/ethernet/altera/altera_tse_main.c | 7 +-- -+ drivers/net/ethernet/arc/emac_main.c | 8 +-- -+ drivers/net/ethernet/atheros/ag71xx.c | 7 +-- -+ drivers/net/ethernet/broadcom/bcm4908_enet.c | 7 +-- -+ drivers/net/ethernet/broadcom/bcmsysport.c | 7 +-- -+ drivers/net/ethernet/broadcom/bgmac-bcma.c | 10 ++-- -+ drivers/net/ethernet/broadcom/bgmac-platform.c | 11 ++-- -+ drivers/net/ethernet/cadence/macb_main.c | 11 ++-- -+ drivers/net/ethernet/cavium/octeon/octeon_mgmt.c | 8 +-- -+ drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 5 +- -+ drivers/net/ethernet/davicom/dm9000.c | 10 ++-- -+ drivers/net/ethernet/ethoc.c | 6 +-- -+ drivers/net/ethernet/ezchip/nps_enet.c | 7 +-- -+ drivers/net/ethernet/freescale/fec_main.c | 7 +-- -+ drivers/net/ethernet/freescale/fec_mpc52xx.c | 7 +-- -+ drivers/net/ethernet/freescale/fman/mac.c | 9 ++-- -+ .../net/ethernet/freescale/fs_enet/fs_enet-main.c | 5 +- -+ drivers/net/ethernet/freescale/gianfar.c | 8 +-- -+ drivers/net/ethernet/freescale/ucc_geth.c | 5 +- -+ drivers/net/ethernet/hisilicon/hisi_femac.c | 7 +-- -+ drivers/net/ethernet/hisilicon/hix5hd2_gmac.c | 7 +-- -+ drivers/net/ethernet/lantiq_xrx200.c | 7 +-- -+ drivers/net/ethernet/marvell/mv643xx_eth.c | 5 +- -+ drivers/net/ethernet/marvell/mvneta.c | 6 +-- -+ .../net/ethernet/marvell/prestera/prestera_main.c | 11 ++-- -+ drivers/net/ethernet/marvell/pxa168_eth.c | 9 +--- -+ drivers/net/ethernet/marvell/sky2.c | 8 ++- -+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 ++-- -+ drivers/net/ethernet/micrel/ks8851_common.c | 7 ++- -+ drivers/net/ethernet/microchip/lan743x_main.c | 5 +- -+ drivers/net/ethernet/nxp/lpc_eth.c | 4 +- -+ drivers/net/ethernet/qualcomm/qca_spi.c | 10 ++-- -+ drivers/net/ethernet/qualcomm/qca_uart.c | 9 +--- -+ drivers/net/ethernet/renesas/ravb_main.c | 12 +++-- -+ drivers/net/ethernet/renesas/sh_eth.c | 5 +- -+ .../net/ethernet/samsung/sxgbe/sxgbe_platform.c | 13 ++--- -+ drivers/net/ethernet/socionext/sni_ave.c | 10 ++-- -+ .../net/ethernet/stmicro/stmmac/dwmac-anarion.c | 2 +- -+ .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-generic.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 2 +- -+ .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/dwmac-visconti.c | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +- -+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- -+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 14 ++--- -+ .../net/ethernet/stmicro/stmmac/stmmac_platform.h | 2 +- -+ drivers/net/ethernet/ti/am65-cpsw-nuss.c | 19 ++++--- -+ drivers/net/ethernet/ti/cpsw.c | 7 +-- -+ drivers/net/ethernet/ti/cpsw_new.c | 7 +-- -+ drivers/net/ethernet/ti/davinci_emac.c | 8 +-- -+ drivers/net/ethernet/ti/netcp_core.c | 7 +-- -+ drivers/net/ethernet/wiznet/w5100-spi.c | 8 ++- -+ drivers/net/ethernet/wiznet/w5100.c | 2 +- -+ drivers/net/ethernet/xilinx/ll_temac_main.c | 8 +-- -+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 15 +++--- -+ drivers/net/ethernet/xilinx/xilinx_emaclite.c | 8 +-- -+ drivers/net/wireless/ath/ath9k/init.c | 5 +- -+ drivers/net/wireless/mediatek/mt76/eeprom.c | 9 +--- -+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 6 +-- -+ drivers/of/of_net.c | 60 ++++++++++------------ -+ drivers/staging/octeon/ethernet.c | 10 ++-- -+ drivers/staging/wfx/main.c | 7 ++- -+ include/linux/of_net.h | 6 +-- -+ include/net/dsa.h | 2 +- -+ net/dsa/dsa2.c | 2 +- -+ net/dsa/slave.c | 2 +- -+ net/ethernet/eth.c | 11 ++-- -+ 85 files changed, 218 insertions(+), 364 deletions(-) -+ -+diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c -+index 665b54c5c8ae5..6d895738222ad 100644 -+--- a/eeprom.c -++++ b/eeprom.c -+@@ -91,15 +91,9 @@ void -+ { -+ struct mt76_dev *dev = phy->dev; -+ -+-#ifdef CONFIG_OF -+ struct device_node *np = dev->dev->of_node; -+- const u8 *mac = NULL; -+ -+- if (np) -+- mac = of_get_mac_address(np); -+- if (!IS_ERR_OR_NULL(mac)) -+- ether_addr_copy(phy->macaddr, mac); -+-#endif -++ of_get_mac_address(np, phy->macaddr); -+ -+ if (!is_valid_ether_addr(phy->macaddr)) { -+ eth_random_addr(phy->macaddr); -+-- -+cgit 1.2.3-1.el7 -+ --- -2.25.1 - diff --git a/patches/backports/0030-iproute2-m_xt.so-depends-on-dynsyms.list.patch b/patches/backports/0030-iproute2-m_xt.so-depends-on-dynsyms.list.patch deleted file mode 100644 index 2f0fc57ea..000000000 --- a/patches/backports/0030-iproute2-m_xt.so-depends-on-dynsyms.list.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 4b2e6bb352b400e244646a7bc59bc5ca3ca6f5df Mon Sep 17 00:00:00 2001 -From: Roman Yeryomin -Date: Fri, 3 Sep 2021 17:31:11 +0300 -Subject: [PATCH 32/32] iproute2: m_xt.so depends on dynsyms.list - -When doing parallel build on a fast machine with bottleneck in i/o, -m_xt.so may start linking faster than dynsyms.list gets populated, -resulting in error: - -ld:dynsyms.list:0: syntax error in dynamic list - -Fix this by adding dynsyms.list as make dependency to m_xt.so -Described also here: -https://bugs.openwrt.org/index.php?do=details&task_id=3353 - -Change from v1: -- add dynsysms.list dependancy only when shared libs are enabled - -Signed-off-by: Roman Yeryomin -Fixes: FS#3353 ---- - .../utils/iproute2/patches/175-reduce-dynamic-syms.patch | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/package/network/utils/iproute2/patches/175-reduce-dynamic-syms.patch b/package/network/utils/iproute2/patches/175-reduce-dynamic-syms.patch -index da961a183b..c3892e5a0e 100644 ---- a/package/network/utils/iproute2/patches/175-reduce-dynamic-syms.patch -+++ b/package/network/utils/iproute2/patches/175-reduce-dynamic-syms.patch -@@ -26,13 +26,14 @@ - - q_atm.so: q_atm.c - $(QUIET_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -shared -fpic -o q_atm.so q_atm.c -latm --@@ -205,4 +206,15 @@ static-syms.h: $(wildcard *.c) -+@@ -205,4 +206,16 @@ static-syms.h: $(wildcard *.c) - sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \ - done > $@ - - +else - + - +tc: dynsyms.list -++m_xt.so: dynsyms.list - +dynsyms.list: $(wildcard *.c) - + files="$(filter-out $(patsubst %.so,%.c,$(TCSO)), $^)" ; \ - + echo "{" > $@ ; \ --- -2.25.1 - diff --git a/patches/backports/0058-kernel-backport-napi-threading-patches.patch b/patches/backports/0058-kernel-backport-napi-threading-patches.patch index c8b273e3f..58dd6d74e 100644 --- a/patches/backports/0058-kernel-backport-napi-threading-patches.patch +++ b/patches/backports/0058-kernel-backport-napi-threading-patches.patch @@ -1,4 +1,4 @@ -From 9e48f3b55c4a379ad36974097fadc6bd034a8ce5 Mon Sep 17 00:00:00 2001 +From e2bb75821cd023b62bf69bc40d5187ba63237cc2 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 14 Dec 2021 09:39:42 +0100 Subject: [PATCH] kernel: backport napi threading patches @@ -723,7 +723,7 @@ index 0000000000..108cf809f8 + diff --git a/target/linux/generic/pending-5.4/690-net-add-support-for-threaded-NAPI-polling.patch b/target/linux/generic/pending-5.4/690-net-add-support-for-threaded-NAPI-polling.patch deleted file mode 100644 -index f45efdf12b..0000000000 +index febec868f4..0000000000 --- a/target/linux/generic/pending-5.4/690-net-add-support-for-threaded-NAPI-polling.patch +++ /dev/null @@ -1,356 +0,0 @@ @@ -824,7 +824,7 @@ index f45efdf12b..0000000000 - - static int netif_rx_internal(struct sk_buff *skb); - static int call_netdevice_notifiers_info(unsigned long val, --@@ -5931,6 +5932,11 @@ void __napi_schedule(struct napi_struct +-@@ -5937,6 +5938,11 @@ void __napi_schedule(struct napi_struct - { - unsigned long flags; - @@ -836,7 +836,7 @@ index f45efdf12b..0000000000 - local_irq_save(flags); - ____napi_schedule(this_cpu_ptr(&softnet_data), n); - local_irq_restore(flags); --@@ -5982,6 +5988,11 @@ EXPORT_SYMBOL(napi_schedule_prep); +-@@ -5988,6 +5994,11 @@ EXPORT_SYMBOL(napi_schedule_prep); - */ - void __napi_schedule_irqoff(struct napi_struct *n) - { @@ -848,7 +848,7 @@ index f45efdf12b..0000000000 - if (!IS_ENABLED(CONFIG_PREEMPT_RT)) - ____napi_schedule(this_cpu_ptr(&softnet_data), n); - else --@@ -6246,9 +6257,89 @@ static void init_gro_hash(struct napi_st +-@@ -6252,9 +6263,89 @@ static void init_gro_hash(struct napi_st - napi->gro_bitmask = 0; - } - @@ -938,7 +938,7 @@ index f45efdf12b..0000000000 - INIT_LIST_HEAD(&napi->poll_list); - hrtimer_init(&napi->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED); - napi->timer.function = napi_watchdog; --@@ -6265,6 +6356,7 @@ void netif_napi_add(struct net_device *d +-@@ -6271,6 +6362,7 @@ void netif_napi_add(struct net_device *d - #ifdef CONFIG_NETPOLL - napi->poll_owner = -1; - #endif @@ -946,7 +946,7 @@ index f45efdf12b..0000000000 - set_bit(NAPI_STATE_SCHED, &napi->state); - set_bit(NAPI_STATE_NPSVC, &napi->state); - list_add_rcu(&napi->dev_list, &dev->napi_list); --@@ -6305,6 +6397,7 @@ static void flush_gro_hash(struct napi_s +-@@ -6311,6 +6403,7 @@ static void flush_gro_hash(struct napi_s - void netif_napi_del(struct napi_struct *napi) - { - might_sleep(); @@ -954,7 +954,7 @@ index f45efdf12b..0000000000 - if (napi_hash_del(napi)) - synchronize_net(); - list_del_init(&napi->dev_list); --@@ -6317,50 +6410,18 @@ EXPORT_SYMBOL(netif_napi_del); +-@@ -6323,50 +6416,18 @@ EXPORT_SYMBOL(netif_napi_del); - - static int napi_poll(struct napi_struct *n, struct list_head *repoll) - { @@ -1009,7 +1009,7 @@ index f45efdf12b..0000000000 - - /* Some drivers may have called napi_schedule - * prior to exhausting their budget. --@@ -10340,6 +10401,10 @@ static int __init net_dev_init(void) +-@@ -10346,6 +10407,10 @@ static int __init net_dev_init(void) - sd->backlog.weight = weight_p; - } - diff --git a/patches/base/0003-pending-scripts-add-gen_config.py.patch b/patches/base/0003-pending-scripts-add-gen_config.py.patch index a050c010e..04d83355b 100644 --- a/patches/base/0003-pending-scripts-add-gen_config.py.patch +++ b/patches/base/0003-pending-scripts-add-gen_config.py.patch @@ -1,22 +1,22 @@ -From 3b8b9898226f49379e34356fd8d2b0abc8947994 Mon Sep 17 00:00:00 2001 +From 9279389d2759af6bfa21bfe7a80dd5c96c67df9e Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 19 Jun 2020 10:45:22 +0200 -Subject: [PATCH] pending: scripts: add gen_config.py +Subject: [PATCH 01/61] pending: scripts: add gen_config.py This script is used to setup the tree based on the profiles/. Signed-off-by: John Crispin --- - scripts/gen_config.py | 236 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 236 insertions(+) + scripts/gen_config.py | 237 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 237 insertions(+) create mode 100755 scripts/gen_config.py diff --git a/scripts/gen_config.py b/scripts/gen_config.py new file mode 100755 -index 0000000000..d39066f44d +index 0000000000..01c3f4050d --- /dev/null +++ b/scripts/gen_config.py -@@ -0,0 +1,236 @@ +@@ -0,0 +1,237 @@ +#!/usr/bin/env python3 + +from os import getenv @@ -244,11 +244,12 @@ index 0000000000..d39066f44d + clean_tree() + setup_feeds(profile) + generate_config(profile) -+ if profile["image"]: -+ Path("tmp/image-file").write_text(profile["image"]) ++ run(["rm", "-rf", "tmp/"]) + print("Running make defconfig") + if run(["make", "defconfig"]).returncode: + die(f"Error running make defconfig") ++ if profile["image"]: ++ Path("tmp/image-file").write_text(profile["image"]) + + print("#########################\n" * 3) + print("\n".join(warnings)) diff --git a/patches/base/0018-Revert-gpio-button-hotplug-convert-to-gpio-descripto.patch b/patches/base/0018-Revert-gpio-button-hotplug-convert-to-gpio-descripto.patch new file mode 100644 index 000000000..581f81dd4 --- /dev/null +++ b/patches/base/0018-Revert-gpio-button-hotplug-convert-to-gpio-descripto.patch @@ -0,0 +1,286 @@ +From be7c703e5078abb5f39b9ad435c47db2f9c1f0ec Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Tue, 4 Jan 2022 05:22:04 +0100 +Subject: [PATCH] Revert "gpio-button-hotplug: convert to gpio descriptor + (gpiod_) API" + +This reverts commit 6fe4b7aa2b00b4e93871454e6a6fc41eb192c784. +--- + .../src/gpio-button-hotplug.c | 142 ++++++++++-------- + 1 file changed, 79 insertions(+), 63 deletions(-) + +diff --git a/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c +index fcaf7f59de..9575c6245b 100644 +--- a/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c ++++ b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c +@@ -242,11 +242,11 @@ static int gpio_button_get_value(struct gpio_keys_button_data *bdata) + int val; + + if (bdata->can_sleep) +- val = !!gpiod_get_value_cansleep(bdata->gpiod); ++ val = !!gpio_get_value_cansleep(bdata->b->gpio); + else +- val = !!gpiod_get_value(bdata->gpiod); ++ val = !!gpio_get_value(bdata->b->gpio); + +- return val; ++ return val ^ bdata->b->active_low; + } + + static void gpio_keys_handle_button(struct gpio_keys_button_data *bdata) +@@ -365,6 +365,7 @@ gpio_keys_get_devtree_pdata(struct device *dev) + struct device_node *node, *pp; + struct gpio_keys_platform_data *pdata; + struct gpio_keys_button *button; ++ int error; + int nbuttons; + int i = 0; + +@@ -374,12 +375,14 @@ gpio_keys_get_devtree_pdata(struct device *dev) + + nbuttons = of_get_child_count(node); + if (nbuttons == 0) +- return ERR_PTR(-EINVAL); ++ return NULL; + + pdata = devm_kzalloc(dev, sizeof(*pdata) + nbuttons * (sizeof *button), + GFP_KERNEL); +- if (!pdata) +- return ERR_PTR(-ENOMEM); ++ if (!pdata) { ++ error = -ENOMEM; ++ goto err_out; ++ } + + pdata->buttons = (struct gpio_keys_button *)(pdata + 1); + pdata->nbuttons = nbuttons; +@@ -388,13 +391,37 @@ gpio_keys_get_devtree_pdata(struct device *dev) + of_property_read_u32(node, "poll-interval", &pdata->poll_interval); + + for_each_child_of_node(node, pp) { ++ enum of_gpio_flags flags; ++ ++ if (!of_find_property(pp, "gpios", NULL)) { ++ pdata->nbuttons--; ++ dev_warn(dev, "Found button without gpios\n"); ++ continue; ++ } ++ + button = (struct gpio_keys_button *)(&pdata->buttons[i++]); + ++ button->irq = irq_of_parse_and_map(pp, 0); ++ ++ button->gpio = of_get_gpio_flags(pp, 0, &flags); ++ if (button->gpio < 0) { ++ error = button->gpio; ++ if (error != -ENOENT) { ++ if (error != -EPROBE_DEFER) ++ dev_err(dev, ++ "Failed to get gpio flags, error: %d\n", ++ error); ++ return ERR_PTR(error); ++ } ++ } else { ++ button->active_low = !!(flags & OF_GPIO_ACTIVE_LOW); ++ } ++ + if (of_property_read_u32(pp, "linux,code", &button->code)) { +- dev_err(dev, "Button node '%s' without keycode\n", +- pp->full_name); +- of_node_put(pp); +- return ERR_PTR(-EINVAL); ++ dev_err(dev, "Button without keycode: 0x%x\n", ++ button->gpio); ++ error = -EINVAL; ++ goto err_out; + } + + button->desc = of_get_property(pp, "label", NULL); +@@ -407,12 +434,17 @@ gpio_keys_get_devtree_pdata(struct device *dev) + if (of_property_read_u32(pp, "debounce-interval", + &button->debounce_interval)) + button->debounce_interval = 5; ++ } + +- button->irq = irq_of_parse_and_map(pp, 0); +- button->gpio = -ENOENT; /* mark this as device-tree */ ++ if (pdata->nbuttons == 0) { ++ error = -EINVAL; ++ goto err_out; + } + + return pdata; ++ ++err_out: ++ return ERR_PTR(error); + } + + static struct of_device_id gpio_keys_of_match[] = { +@@ -439,12 +471,11 @@ gpio_keys_get_devtree_pdata(struct device *dev) + static int gpio_keys_button_probe(struct platform_device *pdev, + struct gpio_keys_button_dev **_bdev, int polled) + { ++ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; +- struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); + struct gpio_keys_button_dev *bdev; + struct gpio_keys_button *buttons; +- struct device_node *prev = NULL; +- int error = 0; ++ int error; + int i; + + if (!pdata) { +@@ -483,67 +514,46 @@ static int gpio_keys_button_probe(struct platform_device *pdev, + for (i = 0; i < pdata->nbuttons; i++) { + struct gpio_keys_button *button = &buttons[i]; + struct gpio_keys_button_data *bdata = &bdev->data[i]; +- const char *desc = button->desc ? button->desc : DRV_NAME; ++ unsigned int gpio = button->gpio; + + if (button->wakeup) { + dev_err(dev, "does not support wakeup\n"); +- error = -EINVAL; +- goto out; ++ return -EINVAL; + } + + bdata->map_entry = button_get_index(button->code); + if (bdata->map_entry < 0) { +- dev_err(dev, "does not support key code:%u\n", ++ dev_warn(dev, "does not support key code:%u\n", + button->code); +- error = -EINVAL; +- goto out; ++ continue; + } + + if (!(button->type == 0 || button->type == EV_KEY || + button->type == EV_SW)) { +- dev_err(dev, "only supports buttons or switches\n"); +- error = -EINVAL; +- goto out; ++ dev_warn(dev, "only supports buttons or switches\n"); ++ continue; + } + +- if (gpio_is_valid(button->gpio)) { +- /* legacy platform data... but is it the lookup table? */ +- bdata->gpiod = devm_gpiod_get_index(dev, desc, i, +- GPIOD_IN); +- if (IS_ERR(bdata->gpiod)) { +- /* or the legacy (button->gpio is good) way? */ +- error = devm_gpio_request_one(dev, +- button->gpio, GPIOF_IN | ( +- button->active_low ? GPIOF_ACTIVE_LOW : +- 0), desc); +- if (error) { +- if (error != -EPROBE_DEFER) { +- dev_err(dev, "unable to claim gpio %d, err=%d\n", +- button->gpio, error); +- } +- goto out; +- } +- +- bdata->gpiod = gpio_to_desc(button->gpio); +- } +- } else { +- /* Device-tree */ +- struct device_node *child = +- of_get_next_child(dev->of_node, prev); +- +- bdata->gpiod = devm_gpiod_get_from_of_node(dev, +- child, "gpios", 0, GPIOD_IN, desc); +- +- prev = child; ++ error = devm_gpio_request(dev, gpio, ++ button->desc ? button->desc : DRV_NAME); ++ if (error) { ++ dev_err(dev, "unable to claim gpio %u, err=%d\n", ++ gpio, error); ++ return error; + } ++ bdata->gpiod = gpio_to_desc(gpio); ++ if (!bdata->gpiod) ++ return -EINVAL; + +- if (IS_ERR_OR_NULL(bdata->gpiod)) { +- error = IS_ERR(bdata->gpiod) ? PTR_ERR(bdata->gpiod) : +- -EINVAL; +- goto out; ++ error = gpio_direction_input(gpio); ++ if (error) { ++ dev_err(dev, ++ "unable to set direction on gpio %u, err=%d\n", ++ gpio, error); ++ return error; + } + +- bdata->can_sleep = gpiod_cansleep(bdata->gpiod); ++ bdata->can_sleep = gpio_cansleep(gpio); + bdata->last_state = -1; /* Unknown state on boot */ + + if (bdev->polled) { +@@ -574,11 +584,8 @@ static int gpio_keys_button_probe(struct platform_device *pdev, + platform_set_drvdata(pdev, bdev); + + *_bdev = bdev; +- error = 0; + +-out: +- of_node_put(prev); +- return error; ++ return 0; + } + + static int gpio_keys_probe(struct platform_device *pdev) +@@ -587,7 +594,9 @@ static int gpio_keys_probe(struct platform_device *pdev) + struct gpio_keys_button_dev *bdev; + int ret, i; + ++ + ret = gpio_keys_button_probe(pdev, &bdev, 0); ++ + if (ret) + return ret; + +@@ -599,8 +608,12 @@ static int gpio_keys_probe(struct platform_device *pdev) + + INIT_DELAYED_WORK(&bdata->work, gpio_keys_irq_work_func); + ++ if (!bdata->gpiod) ++ continue; ++ + if (!button->irq) { +- bdata->irq = gpiod_to_irq(bdata->gpiod); ++ bdata->irq = gpio_to_irq(button->gpio); ++ + if (bdata->irq < 0) { + dev_err(&pdev->dev, "failed to get irq for gpio:%d\n", + button->gpio); +@@ -618,6 +631,7 @@ static int gpio_keys_probe(struct platform_device *pdev) + ret = devm_request_threaded_irq(&pdev->dev, + bdata->irq, NULL, button_handle_irq, + irqflags, dev_name(&pdev->dev), bdata); ++ + if (ret < 0) { + bdata->irq = 0; + dev_err(&pdev->dev, "failed to request irq:%d for gpio:%d\n", +@@ -639,12 +653,14 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) + int ret; + + ret = gpio_keys_button_probe(pdev, &bdev, 1); ++ + if (ret) + return ret; + + INIT_DELAYED_WORK(&bdev->work, gpio_keys_polled_poll); + + pdata = bdev->pdata; ++ + if (pdata->enable) + pdata->enable(bdev->dev); + +-- +2.25.1 + diff --git a/patches/ipq40xx/0001-Revert-ipq40xx-revert-usage-of-VLAN-S-TAG.patch b/patches/ipq40xx/0001-Revert-ipq40xx-revert-usage-of-VLAN-S-TAG.patch index 62c4fae54..c0de8a9b4 100644 --- a/patches/ipq40xx/0001-Revert-ipq40xx-revert-usage-of-VLAN-S-TAG.patch +++ b/patches/ipq40xx/0001-Revert-ipq40xx-revert-usage-of-VLAN-S-TAG.patch @@ -1,7 +1,7 @@ -From 687576be91062e5ab25e8ff4e2d990799a34210f Mon Sep 17 00:00:00 2001 +From f42a338de65dc32684d26cca106853eb3e888fde Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 8 Apr 2021 10:46:29 +0200 -Subject: [PATCH 22/43] Revert "ipq40xx: revert usage of VLAN S-TAG" +Subject: [PATCH 52/83] Revert "ipq40xx: revert usage of VLAN S-TAG" This reverts commit cdc8d4b46f0811292fffc6094acd81e854b5f4a5. @@ -50,12 +50,12 @@ index af55ee4dd5..9dc38bcfcc 100644 edma_set_ethtool_ops(edma_netdev[i]); diff --git a/target/linux/ipq40xx/files/drivers/net/phy/ar40xx.c b/target/linux/ipq40xx/files/drivers/net/phy/ar40xx.c -index c35ba2799f..9758f013f0 100644 +index ca7f0ca350..8b3ae53bd9 100644 --- a/target/linux/ipq40xx/files/drivers/net/phy/ar40xx.c +++ b/target/linux/ipq40xx/files/drivers/net/phy/ar40xx.c -@@ -1201,7 +1201,11 @@ ar40xx_init_port(struct ar40xx_priv *priv, int port) - ar40xx_rmw(priv, AR40XX_REG_PORT_STATUS(port), - AR40XX_PORT_AUTO_LINK_EN, 0); +@@ -1200,7 +1200,11 @@ ar40xx_init_port(struct ar40xx_priv *priv, int port) + + ar40xx_write(priv, AR40XX_REG_PORT_STATUS(port), 0); - ar40xx_write(priv, AR40XX_REG_PORT_HEADER(port), 0); + /* CPU port is setting headers to limit output ports */ @@ -66,7 +66,7 @@ index c35ba2799f..9758f013f0 100644 ar40xx_write(priv, AR40XX_REG_PORT_VLAN0(port), 0); -@@ -1244,6 +1248,10 @@ ar40xx_init_globals(struct ar40xx_priv *priv) +@@ -1243,6 +1247,10 @@ ar40xx_init_globals(struct ar40xx_priv *priv) t = (AR40XX_PORT0_FC_THRESH_ON_DFLT << 16) | AR40XX_PORT0_FC_THRESH_OFF_DFLT; ar40xx_write(priv, AR40XX_REG_PORT_FLOWCTRL_THRESH(0), t); @@ -77,7 +77,7 @@ index c35ba2799f..9758f013f0 100644 } static int -@@ -1531,7 +1539,10 @@ ar40xx_setup_port(struct ar40xx_priv *priv, int port, u32 members) +@@ -1530,7 +1538,10 @@ ar40xx_setup_port(struct ar40xx_priv *priv, int port, u32 members) u32 pvid = priv->vlan_id[priv->pvid[port]]; if (priv->vlan) { @@ -89,7 +89,7 @@ index c35ba2799f..9758f013f0 100644 ingress = AR40XX_IN_SECURE; } else { -@@ -1543,8 +1554,16 @@ ar40xx_setup_port(struct ar40xx_priv *priv, int port, u32 members) +@@ -1542,8 +1553,16 @@ ar40xx_setup_port(struct ar40xx_priv *priv, int port, u32 members) t |= pvid << AR40XX_PORT_VLAN0_DEF_CVID_S; ar40xx_write(priv, AR40XX_REG_PORT_VLAN0(port), t); diff --git a/patches/ipq40xx/0011-ipq4018-add-EdgeCore-SPW2AC1200-support-lan.patch b/patches/ipq40xx/0011-ipq4018-add-EdgeCore-SPW2AC1200-support-lan.patch new file mode 100644 index 000000000..90514c02b --- /dev/null +++ b/patches/ipq40xx/0011-ipq4018-add-EdgeCore-SPW2AC1200-support-lan.patch @@ -0,0 +1,148 @@ +From a0eb587ea9e4d905e1796c4f0d64fff9cd8a88f3 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 14 Oct 2021 15:13:56 +0200 +Subject: [PATCH] spwlanpoe + +Signed-off-by: John Crispin +--- + package/boot/uboot-envtools/files/ipq40xx | 1 + + target/linux/ipq40xx/base-files/etc/board.d/01_leds | 1 + + .../linux/ipq40xx/base-files/etc/board.d/02_network | 1 + + .../etc/hotplug.d/firmware/11-ath10k-caldata | 2 ++ + .../ipq40xx/base-files/lib/upgrade/platform.sh | 3 ++- + .../boot/dts/qcom-ipq4018-spw2ac1200-lan-poe.dts | 6 ++++++ + target/linux/ipq40xx/image/generic.mk | 13 +++++++++++++ + .../patches-5.4/901-arm-boot-add-dts-files.patch | 3 ++- + 8 files changed, 28 insertions(+), 2 deletions(-) + create mode 100644 target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-spw2ac1200-lan-poe.dts + +diff --git a/package/boot/uboot-envtools/files/ipq40xx b/package/boot/uboot-envtools/files/ipq40xx +index fd7ad69eff..c51b40ab12 100644 +--- a/package/boot/uboot-envtools/files/ipq40xx ++++ b/package/boot/uboot-envtools/files/ipq40xx +@@ -35,6 +35,7 @@ alfa-network,ap120c-ac |\ + devolo,magic-2-wifi-next |\ + edgecore,ecw5211 |\ + edgecore,spw2ac1200 |\ ++edgecore,spw2ac1200-lan-poe |\ + glinet,gl-ap1300 |\ + glinet,gl-b1300 |\ + luma,wrtq-329acn |\ +diff --git a/target/linux/ipq40xx/base-files/etc/board.d/01_leds b/target/linux/ipq40xx/base-files/etc/board.d/01_leds +index d944d72184..5476dd5df6 100755 +--- a/target/linux/ipq40xx/base-files/etc/board.d/01_leds ++++ b/target/linux/ipq40xx/base-files/etc/board.d/01_leds +@@ -72,6 +72,7 @@ qxwlan,e2600ac-c2) + ;; + edgecore,ecw5211 |\ + edgecore,spw2ac1200 |\ ++edgecore,spw2ac1200-lan-poe |\ + cig,wf610d |\ + zyxel,nbg6617 |\ + zyxel,wre6606) +diff --git a/target/linux/ipq40xx/base-files/etc/board.d/02_network b/target/linux/ipq40xx/base-files/etc/board.d/02_network +index e4b009bf93..f533c39179 100755 +--- a/target/linux/ipq40xx/base-files/etc/board.d/02_network ++++ b/target/linux/ipq40xx/base-files/etc/board.d/02_network +@@ -15,6 +15,7 @@ ipq40xx_setup_interfaces() + 8dev,habanero-dvk|\ + 8dev,jalapeno|\ + alfa-network,ap120c-ac|\ ++ edgecore,spw2ac1200-lan-poe |\ + engenius,emr3500|\ + engenius,ens620ext|\ + luma,wrtq-329acn|\ +diff --git a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata +index 97dd1b4039..e36821a596 100644 +--- a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata ++++ b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata +@@ -105,6 +105,7 @@ case "$FIRMWARE" in + compex,wpj428 |\ + edgecore,ecw5211 |\ + edgecore,spw2ac1200 |\ ++ edgecore,spw2ac1200-lan-poe |\ + edgecore,oap100 |\ + engenius,eap1300 |\ + engenius,eap2200 |\ +@@ -226,6 +227,7 @@ case "$FIRMWARE" in + compex,wpj428 |\ + edgecore,ecw5211 |\ + edgecore,spw2ac1200 |\ ++ edgecore,spw2ac1200-lan-poe |\ + edgecore,oap100 |\ + engenius,eap1300 |\ + engenius,eap2200 |\ +diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh +index 806b3edb66..d44a57c62a 100644 +--- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh ++++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh +@@ -90,7 +90,8 @@ platform_do_upgrade() { + fi + nand_do_upgrade "$1" + ;; +- edgecore,spw2ac1200) ++ edgecore,spw2ac1200|\ ++ edgecore,spw2ac1200-lan-poe) + CI_UBIPART="$(awk -F 'ubi.mtd=' '{printf $2}' /proc/cmdline | sed -e 's/ .*$//')" + nand_do_upgrade "$1" + ;; +diff --git a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-spw2ac1200-lan-poe.dts b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-spw2ac1200-lan-poe.dts +new file mode 100644 +index 0000000000..1c2a2a8621 +--- /dev/null ++++ b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-spw2ac1200-lan-poe.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT ++ ++#include "qcom-ipq4018-spw2ac1200.dts" ++/ { ++ compatible = "edgecore,spw2ac1200-lan-poe"; ++}; +diff --git a/target/linux/ipq40xx/image/generic.mk b/target/linux/ipq40xx/image/generic.mk +index ae1e2e49cf..7e6118e61c 100644 +--- a/target/linux/ipq40xx/image/generic.mk ++++ b/target/linux/ipq40xx/image/generic.mk +@@ -387,6 +387,19 @@ define Device/edgecore_spw2ac1200 + endef + TARGET_DEVICES += edgecore_spw2ac1200 + ++define Device/edgecore_spw2ac1200-lan-poe ++ $(call Device/FitImage) ++ $(call Device/UbiFit) ++ DEVICE_VENDOR := Edgecore ++ DEVICE_MODEL := SPW2AC1200 ++ SOC := qcom-ipq4018 ++ BLOCKSIZE := 128k ++ PAGESIZE := 2048 ++ DEVICE_DTS_CONFIG := config@ap.dk01.1-c2 ++ DEVICE_PACKAGES := kmod-tpm-i2c-atmel kmod-usb-acm uboot-envtools kmod-usb-net kmod-usb-net-cdc-qmi uqmi ++endef ++TARGET_DEVICES += edgecore_spw2ac1200-lan-poe ++ + define Device/edgecore_oap100 + $(call Device/FitImage) + $(call Device/UbiFit) +diff --git a/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch b/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch +index 826e17b0e9..c4ecf62313 100644 +--- a/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch ++++ b/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch +@@ -10,7 +10,7 @@ Signed-off-by: John Crispin + + --- a/arch/arm/boot/dts/Makefile + +++ b/arch/arm/boot/dts/Makefile +-@@ -837,11 +837,63 @@ dtb-$(CONFIG_ARCH_QCOM) += \ ++@@ -837,11 +837,64 @@ dtb-$(CONFIG_ARCH_QCOM) += \ + qcom-apq8074-dragonboard.dtb \ + qcom-apq8084-ifc6540.dtb \ + qcom-apq8084-mtp.dtb \ +@@ -23,6 +23,7 @@ Signed-off-by: John Crispin + + qcom-ipq4018-eap1300.dtb \ + + qcom-ipq4018-ecw5211.dtb \ + + qcom-ipq4018-spw2ac1200.dtb \ +++ qcom-ipq4018-spw2ac1200-lan-poe.dtb \ + + qcom-ipq4018-emd1.dtb \ + + qcom-ipq4018-emr3500.dtb \ + + qcom-ipq4018-ens620ext.dtb \ +-- +2.25.1 + diff --git a/patches/ipq807x/0004-ipq807x-add-the-Qualcomm-AX-target-support.patch b/patches/ipq807x/0004-ipq807x-add-the-Qualcomm-AX-target-support.patch index 19bd55e51..f0c312eb9 100644 --- a/patches/ipq807x/0004-ipq807x-add-the-Qualcomm-AX-target-support.patch +++ b/patches/ipq807x/0004-ipq807x-add-the-Qualcomm-AX-target-support.patch @@ -1,135 +1,20 @@ -From c1670dcdda1ab0f5310f76e5ae6e710bd16892c7 Mon Sep 17 00:00:00 2001 +From 1749748819caa03e249e8a5df1311498550cbd3b Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sat, 18 Jul 2020 08:53:44 +0200 -Subject: [PATCH 01/38] ipq807x: add the Qualcomm AX target support +Subject: [PATCH 68/83] ipq807x: add the Qualcomm AX target support Signed-off-by: John Crispin --- - config/Config-kernel.in | 9 + - include/image.mk | 6 +- - include/kernel-version.mk | 2 +- - package/boot/uboot-envtools/files/ipq807x | 37 + - .../etc/hotplug.d/firmware/11-ath10k-caldata | 5 + - target/linux/ipq807x/109-logspam.patch | 24 + - target/linux/ipq807x/Makefile | 22 + - .../ipq807x/base-files/etc/board.d/01_leds | 38 + - .../ipq807x/base-files/etc/board.d/02_network | 81 + - .../ipq807x/base-files/etc/board.d/03_wifi | 17 + - .../etc/hotplug.d/firmware/10-ath11k-caldata | 111 + - .../etc/hotplug.d/firmware/11-ath10k-caldata | 16 + - .../ipq807x/base-files/etc/hotplug.d/net/macs | 3 + - .../ipq807x/base-files/etc/init.d/aq_phy | 21 + - .../ipq807x/base-files/etc/init.d/bootcount | 12 + - .../linux/ipq807x/base-files/etc/init.d/wdt | 14 + - ...G4_v5.4.B-AQR_CIG_WIFI_ID44715_VER1673.cld | Bin 0 -> 391170 bytes - .../base-files/lib/upgrade/platform.sh | 73 + - target/linux/ipq807x/config-4.4 | 828 + - .../arm/boot/dts/qcom-ipq6018-cig-wf188.dts | 18 + - .../arm/boot/dts/qcom-ipq6018-cig-wf188n.dts | 18 + - .../boot/dts/qcom-ipq6018-edgecore-eap101.dts | 18 + - .../boot/dts/qcom-ipq6018-miwifi-ax1800.dts | 18 + - .../boot/dts/qcom-ipq6018-wallys-dr6018.dts | 18 + - .../arch/arm/boot/dts/qcom-ipq807x-eap102.dts | 26 + - .../arch/arm/boot/dts/qcom-ipq807x-eap106.dts | 26 + - .../arch/arm/boot/dts/qcom-ipq807x-ex227.dts | 26 + - .../arch/arm/boot/dts/qcom-ipq807x-ex447.dts | 26 + - .../boot/dts/qcom-ipq807x-sercomm-wallaby.dts | 26 + - .../arch/arm/boot/dts/qcom-ipq807x-wf194c.dts | 26 + - .../arm/boot/dts/qcom-ipq807x-wf194c4.dts | 26 + - .../dts/qcom/qcom-ipq6018-miwifi-ax1800.dts | 419 + - .../dts/qcom/qcom-ipq6018-wallys-dr6018.dts | 441 + - .../boot/dts/qcom/qcom-ipq807x-eap102.dts | 918 + - .../boot/dts/qcom/qcom-ipq807x-wf194c4.dts | 942 + - target/linux/ipq807x/image/Makefile | 26 + - target/linux/ipq807x/image/ipq50xx.mk | 10 + - target/linux/ipq807x/image/ipq60xx.mk | 56 + - target/linux/ipq807x/image/ipq807x.mk | 90 + - target/linux/ipq807x/ipq50xx/config-default | 84 + - target/linux/ipq807x/ipq50xx/config-lowmem | 73 + - target/linux/ipq807x/ipq50xx/target.mk | 10 + - target/linux/ipq807x/ipq60xx/config-default | 122 + - .../linux/ipq807x/ipq60xx/profiles/default.mk | 9 + - target/linux/ipq807x/ipq60xx/target.mk | 8 + - target/linux/ipq807x/ipq807x/config-default | 78 + - .../linux/ipq807x/ipq807x/profiles/default.mk | 9 + - target/linux/ipq807x/ipq807x/target.mk | 7 + - target/linux/ipq807x/modules.mk | 61 + - .../linux/ipq807x/patches/100-qrtr-ns.patch | 976 + - .../linux/ipq807x/patches/101-squashfs.patch | 16 + - .../linux/ipq807x/patches/102-cig-wf188.patch | 869 + - .../ipq807x/patches/103-sercomm-wallaby.patch | 816 + - target/linux/ipq807x/patches/104-wf194c.patch | 816 + - .../patches/105-fix-dtc-gcc10-build.patch | 11 + - target/linux/ipq807x/patches/106-eap101.patch | 993 + - .../linux/ipq807x/patches/108-log-spam.patch | 37 + - target/linux/ipq807x/patches/109-tplink.patch | 1518 + - .../ipq807x/patches/110-add-esmt-nand.patch | 37 + - target/linux/ipq807x/patches/111-eap106.patch | 765 + - target/linux/ipq807x/patches/112-pstore.patch | 147 + - .../ipq807x/patches/200-bpf_backport.patch | 44780 ++++++++++++++++ - toolchain/kernel-headers/Makefile | 8 + - 63 files changed, 56741 insertions(+), 2 deletions(-) + config/Config-kernel.in | 9 ++++++ + include/image.mk | 6 +++- + include/kernel-version.mk | 2 +- + package/boot/uboot-envtools/files/ipq807x | 37 +++++++++++++++++++++++ + toolchain/kernel-headers/Makefile | 8 +++++ + 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 package/boot/uboot-envtools/files/ipq807x - create mode 100644 target/linux/ipq807x/109-logspam.patch - create mode 100644 target/linux/ipq807x/Makefile - create mode 100755 target/linux/ipq807x/base-files/etc/board.d/01_leds - create mode 100755 target/linux/ipq807x/base-files/etc/board.d/02_network - create mode 100755 target/linux/ipq807x/base-files/etc/board.d/03_wifi - create mode 100755 target/linux/ipq807x/base-files/etc/hotplug.d/firmware/10-ath11k-caldata - create mode 100644 target/linux/ipq807x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata - create mode 100644 target/linux/ipq807x/base-files/etc/hotplug.d/net/macs - create mode 100755 target/linux/ipq807x/base-files/etc/init.d/aq_phy - create mode 100755 target/linux/ipq807x/base-files/etc/init.d/bootcount - create mode 100755 target/linux/ipq807x/base-files/etc/init.d/wdt - create mode 100644 target/linux/ipq807x/base-files/lib/firmware/AQR-G4_v5.4.B-AQR_CIG_WIFI_ID44715_VER1673.cld - create mode 100755 target/linux/ipq807x/base-files/lib/upgrade/platform.sh - create mode 100644 target/linux/ipq807x/config-4.4 - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq6018-cig-wf188.dts - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq6018-cig-wf188n.dts - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq6018-edgecore-eap101.dts - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq6018-miwifi-ax1800.dts - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq6018-wallys-dr6018.dts - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq807x-eap102.dts - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq807x-eap106.dts - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq807x-ex227.dts - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq807x-ex447.dts - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq807x-sercomm-wallaby.dts - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq807x-wf194c.dts - create mode 100644 target/linux/ipq807x/files/arch/arm/boot/dts/qcom-ipq807x-wf194c4.dts - create mode 100755 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/qcom-ipq6018-miwifi-ax1800.dts - create mode 100755 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/qcom-ipq6018-wallys-dr6018.dts - create mode 100755 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/qcom-ipq807x-eap102.dts - create mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/qcom-ipq807x-wf194c4.dts - create mode 100644 target/linux/ipq807x/image/Makefile - create mode 100644 target/linux/ipq807x/image/ipq50xx.mk - create mode 100644 target/linux/ipq807x/image/ipq60xx.mk - create mode 100644 target/linux/ipq807x/image/ipq807x.mk - create mode 100644 target/linux/ipq807x/ipq50xx/config-default - create mode 100644 target/linux/ipq807x/ipq50xx/config-lowmem - create mode 100644 target/linux/ipq807x/ipq50xx/target.mk - create mode 100644 target/linux/ipq807x/ipq60xx/config-default - create mode 100644 target/linux/ipq807x/ipq60xx/profiles/default.mk - create mode 100644 target/linux/ipq807x/ipq60xx/target.mk - create mode 100644 target/linux/ipq807x/ipq807x/config-default - create mode 100644 target/linux/ipq807x/ipq807x/profiles/default.mk - create mode 100644 target/linux/ipq807x/ipq807x/target.mk - create mode 100644 target/linux/ipq807x/modules.mk - create mode 100644 target/linux/ipq807x/patches/100-qrtr-ns.patch - create mode 100644 target/linux/ipq807x/patches/101-squashfs.patch - create mode 100644 target/linux/ipq807x/patches/102-cig-wf188.patch - create mode 100644 target/linux/ipq807x/patches/103-sercomm-wallaby.patch - create mode 100644 target/linux/ipq807x/patches/104-wf194c.patch - create mode 100644 target/linux/ipq807x/patches/105-fix-dtc-gcc10-build.patch - create mode 100644 target/linux/ipq807x/patches/106-eap101.patch - create mode 100644 target/linux/ipq807x/patches/108-log-spam.patch - create mode 100644 target/linux/ipq807x/patches/109-tplink.patch - create mode 100644 target/linux/ipq807x/patches/110-add-esmt-nand.patch - create mode 100644 target/linux/ipq807x/patches/111-eap106.patch - create mode 100644 target/linux/ipq807x/patches/112-pstore.patch - create mode 100644 target/linux/ipq807x/patches/200-bpf_backport.patch diff --git a/config/Config-kernel.in b/config/Config-kernel.in -index f71114b5da..4a85d83118 100644 +index d4648a5064..2d5c9f1437 100644 --- a/config/Config-kernel.in +++ b/config/Config-kernel.in @@ -2,6 +2,15 @@ @@ -173,17 +58,17 @@ index 6fc02a3f6b..92b23321b1 100644 $(LINUX_DIR)/scripts/dtc/dtc -O dtb \ -i$(dir $(1)) $(DTC_FLAGS) $(4) \ diff --git a/include/kernel-version.mk b/include/kernel-version.mk -index 3c109c13c8..dff01895be 100644 +index c7aba61cd7..efecf2f919 100644 --- a/include/kernel-version.mk +++ b/include/kernel-version.mk @@ -11,7 +11,7 @@ LINUX_VERSION-4.14 = .193 - LINUX_VERSION-5.4 = .142 + LINUX_VERSION-5.4 = .158 LINUX_VERSION-5.10 = .27 -LINUX_KERNEL_HASH-4.4.60 = 2cd8df6f1ac6a5329c5a286ec9b5956215977221a1b731597ed169fff74a9659 +LINUX_KERNEL_HASH-4.4.60 = e7f2f47acf17497d6ffd713eda65c025b3df0bce09faa8c04712bf1b3cfc9fdb LINUX_KERNEL_HASH-4.14.193 = 0b0fb41d4430e1a42738b341cbfd2f41951aa5cd02acabbd53f076119c8b9f03 - LINUX_KERNEL_HASH-5.4.142 = 99785728968564ba27c7e552d024b560072dcbc885540912eabb5c021e231451 + LINUX_KERNEL_HASH-5.4.158 = 6e018fecdc8fc24553756e582d83b82d65b10a6b03ef36262a24911f839b8d59 LINUX_KERNEL_HASH-5.10.27 = d99dc9662951299c53a0a8d8c8d0a72a16ff861d20e927c0f9b14f63282d69d9 diff --git a/package/boot/uboot-envtools/files/ipq807x b/package/boot/uboot-envtools/files/ipq807x new file mode 100644 diff --git a/patches/ramips/0004-certificates-add-ability-to-persistently-store-certi.patch b/patches/ramips/0004-certificates-add-ability-to-persistently-store-certi.patch index 300234437..9713a4122 100644 --- a/patches/ramips/0004-certificates-add-ability-to-persistently-store-certi.patch +++ b/patches/ramips/0004-certificates-add-ability-to-persistently-store-certi.patch @@ -11,39 +11,6 @@ Signed-off-by: John Crispin .../linux/ramips/dts/mt7628an_tplink_8m-split-uboot.dtsi | 7 ++++++- 3 files changed, 13 insertions(+), 4 deletions(-) -diff --git a/target/linux/ath79/dts/qca9563_tplink_cpe710-v1.dts b/target/linux/ath79/dts/qca9563_tplink_cpe710-v1.dts -index 830c3d30b8..71c6381f86 100644 ---- a/target/linux/ath79/dts/qca9563_tplink_cpe710-v1.dts -+++ b/target/linux/ath79/dts/qca9563_tplink_cpe710-v1.dts -@@ -86,7 +86,12 @@ - partition@70000 { - compatible = "denx,uimage"; - label = "firmware"; -- reg = <0x070000 0xf50000>; -+ reg = <0x070000 0xf40000>; -+ }; -+ -+ partition@fb0000 { -+ label = "certificates"; -+ reg = <0xfb0000 0x10000>; - }; - - partition@fc0000 { -diff --git a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-xx8300.dtsi b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-xx8300.dtsi -index 8f971e505c..0f1f083a5b 100644 ---- a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-xx8300.dtsi -+++ b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-xx8300.dtsi -@@ -229,9 +229,8 @@ - }; - - partition@b880000 { -- label = "syscfg"; -+ label = "certificates"; - reg = <0xb880000 0x4680000>; -- read-only; - }; - }; - }; diff --git a/target/linux/ramips/dts/mt7628an_tplink_8m-split-uboot.dtsi b/target/linux/ramips/dts/mt7628an_tplink_8m-split-uboot.dtsi index b6ce7b1f56..471be72001 100644 --- a/target/linux/ramips/dts/mt7628an_tplink_8m-split-uboot.dtsi diff --git a/patches/rest/0030-ath10k-ct-update-the-driver.patch b/patches/rest/0030-ath10k-ct-update-the-driver.patch deleted file mode 100644 index 283ebe9c8..000000000 --- a/patches/rest/0030-ath10k-ct-update-the-driver.patch +++ /dev/null @@ -1,30 +0,0 @@ -From ed5a8958378d84bba92a70f2a56a962be73c4b3b Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 23 Apr 2021 16:16:31 +0200 -Subject: [PATCH 30/43] ath10k-ct: update the driver - -Signed-off-by: John Crispin ---- - package/kernel/ath10k-ct/Makefile | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/package/kernel/ath10k-ct/Makefile b/package/kernel/ath10k-ct/Makefile -index 5681c5c2cd..24e0702e2c 100644 ---- a/package/kernel/ath10k-ct/Makefile -+++ b/package/kernel/ath10k-ct/Makefile -@@ -8,9 +8,9 @@ PKG_LICENSE_FILES:= - - PKG_SOURCE_URL:=https://github.com/greearb/ath10k-ct.git - PKG_SOURCE_PROTO:=git --PKG_SOURCE_DATE:=2021-06-03 --PKG_SOURCE_VERSION:=b44cd7b2e7b0df5995ece18f358d4dfc40834ba1 --PKG_MIRROR_HASH:=59f961ad425eb1a48fa9c391a325cc0f23845daec9d12673445d3077f9756cf0 -+PKG_SOURCE_DATE:=2021-04-23 -+PKG_SOURCE_VERSION:=8eca56d1514042b4af34004e0bbf69e40351d499 -+PKG_MIRROR_HASH:=4ce22470b0cd15cc3cb04478678407e976c48010baab517fa1ac37685b791d95 - - # Build the 5.10 ath10k-ct driver version. - # Probably this should match as closely as --- -2.25.1 - diff --git a/patches/rest/0044-mac80211-fix-builds-on-ath79-targets.patch b/patches/rest/0044-mac80211-fix-builds-on-ath79-targets.patch deleted file mode 100644 index 32ceb2806..000000000 --- a/patches/rest/0044-mac80211-fix-builds-on-ath79-targets.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 7d1503f1fb878bf27aa1bfa15d81394eaf8888d0 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 13 Sep 2021 13:42:00 +0200 -Subject: [PATCH] mac80211: fix builds on ath79 targets - -Signed-off-by: John Crispin ---- - .../100-backport_of_get_mac_address.patch | 40 +++++++++++++++++++ - 1 file changed, 40 insertions(+) - create mode 100644 package/kernel/mac80211/patches/build/100-backport_of_get_mac_address.patch - -diff --git a/package/kernel/mac80211/patches/build/100-backport_of_get_mac_address.patch b/package/kernel/mac80211/patches/build/100-backport_of_get_mac_address.patch -new file mode 100644 -index 0000000000..79c2343522 ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/100-backport_of_get_mac_address.patch -@@ -0,0 +1,40 @@ -+--- a/backport-include/linux/of_net.h -++++ b/backport-include/linux/of_net.h -+@@ -2,6 +2,7 @@ -+ #define _BP_OF_NET_H -+ #include_next -+ #include -++#include -+ -+ #ifndef CONFIG_OF -+ #if LINUX_VERSION_IS_LESS(3,10,0) -+@@ -12,18 +13,23 @@ static inline const void *of_get_mac_add -+ #endif -+ #endif -+ -+-/* The behavior of of_get_mac_address() changed in kernel 5.2, it now -+- * returns an error code and not NULL in case of an error. -++/* The behavior of of_get_mac_address() changed in kernel 5.15, it now -++ * accepts an argument with the destination buffer to copy the address to -+ */ -+-#if LINUX_VERSION_IS_LESS(5,2,0) -+-static inline const void *backport_of_get_mac_address(struct device_node *np) -++#if LINUX_VERSION_IS_LESS(5,15,0) -++static inline int backport_of_get_mac_address(struct device_node *np, u8 *addr) -+ { -+ const void *mac = of_get_mac_address(np); -+ -++ if (IS_ERR(mac)) -++ return PTR_ERR(mac); -++ -+ if (!mac) -+- return ERR_PTR(-ENODEV); -++ return -ENODEV; -++ -++ memcpy(addr, mac, ETH_ALEN); -+ -+- return mac; -++ return 0; -+ } -+ #define of_get_mac_address LINUX_BACKPORT(of_get_mac_address) -+ #endif /* < 5.2 */ --- -2.25.1 - diff --git a/patches/rest/0052-hostapd-allow-hostapd-under-ujail-to-communicate-wit.patch b/patches/rest/0052-hostapd-allow-hostapd-under-ujail-to-communicate-wit.patch deleted file mode 100644 index 1a6f3e95c..000000000 --- a/patches/rest/0052-hostapd-allow-hostapd-under-ujail-to-communicate-wit.patch +++ /dev/null @@ -1,91 +0,0 @@ -From bbd31470429134c23f593a49c02d5413dcba352f Mon Sep 17 00:00:00 2001 -From: Mark Mentovai -Date: Tue, 23 Nov 2021 12:28:55 -0500 -Subject: [PATCH] hostapd: allow hostapd under ujail to communicate with - hostapd_cli - -When procd-ujail is available, 1f785383875a runs hostapd as user -"network", with only limited additional capabilities (CAP_NET_ADMIN and -CAP_NET_RAW). - -hostapd_cli (CONFIG_PACKAGE_hostapd-utils) communicates with hostapd -over a named UNIX-domain socket. hostapd_cli is responsible for creating -this socket at /tmp/wpa_ctrl_$pid_$counter. Since it typically runs as -root, this endpoint is normally created with uid root, gid root, mode -0755. As a result, hostapd running as uid network is able to receive -control messages sent through this interface, but is not able to respond -to them. If debug-level logging is enabled (CONFIG_WPA_MSG_MIN_PRIORITY -<= 2 at build, and log_level <= 2 in /etc/config/wireless wifi-device), -this message will appear from hostapd: - -CTRL: sendto failed: Permission denied - -As a fix, hostapd_cli should create the socket node in the filesystem -with uid network, gid network, mode 0770. This borrows the presently -Android-only strategy already in hostapd intended to solve the same -problem on Android. - -If procd-ujail is not available and hostapd falls back to running as -root, it will still be able to read from and write to the socket even if -the node in the filesystem has been restricted to the network user and -group. This matches the logic in -package/network/services/hostapd/files/wpad.init, which sets the uid and -gid of /var/run/hostapd to network regardless of whether procd-ujail is -available. - -As it appears that the "network" user and group are statically allocated -uid 101 and gid 101, respectively, per -package/base-files/files/etc/passwd and USERID in -package/network/services/hostapd/Makefile, this patch also uses a -constant 101 for the uid and gid. - -Signed-off-by: Mark Mentovai -[refreshed patch] -Signed-off-by: Daniel Golle ---- - .../610-hostapd_cli_ujail_permission.patch | 33 +++++++++++++++++++ - 1 file changed, 33 insertions(+) - create mode 100644 package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch - -diff --git a/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch b/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch -new file mode 100644 -index 0000000000..a03fcc9f92 ---- /dev/null -+++ b/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch -@@ -0,0 +1,33 @@ -+--- a/src/common/wpa_ctrl.c -++++ b/src/common/wpa_ctrl.c -+@@ -135,7 +135,7 @@ try_again: -+ return NULL; -+ } -+ tries++; -+-#ifdef ANDROID -++ -+ /* Set client socket file permissions so that bind() creates the client -+ * socket with these permissions and there is no need to try to change -+ * them with chmod() after bind() which would have potential issues with -+@@ -147,7 +147,7 @@ try_again: -+ * operations to allow the response to go through. Those are using the -+ * no-deference-symlinks version to avoid races. */ -+ fchmod(ctrl->s, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -+-#endif /* ANDROID */ -++ -+ if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, -+ sizeof(ctrl->local)) < 0) { -+ if (errno == EADDRINUSE && tries < 2) { -+@@ -165,7 +165,11 @@ try_again: -+ return NULL; -+ } -+ -+-#ifdef ANDROID -++#ifndef ANDROID -++ /* Set group even if we do not have privileges to change owner */ -++ lchown(ctrl->local.sun_path, -1, 101); -++ lchown(ctrl->local.sun_path, 101, 101); -++#else -+ /* Set group even if we do not have privileges to change owner */ -+ lchown(ctrl->local.sun_path, -1, AID_WIFI); -+ lchown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI); --- -2.25.1 - diff --git a/patches/rtkmipsel/0002-rtkmipsel-add-kernel-version.patch b/patches/rtkmipsel/0002-rtkmipsel-add-kernel-version.patch index 53f2ca2e8..839f1c685 100644 --- a/patches/rtkmipsel/0002-rtkmipsel-add-kernel-version.patch +++ b/patches/rtkmipsel/0002-rtkmipsel-add-kernel-version.patch @@ -1,7 +1,7 @@ -From 07b199d0759992a17a2ef42b75776635c7e57d21 Mon Sep 17 00:00:00 2001 +From d692bfd33a8169b47dcf200fcfd238cdbc4a4084 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 2 Jan 2022 09:56:17 +0100 -Subject: [PATCH] rtkmipsel: add kernel-version +Subject: [PATCH 70/83] rtkmipsel: add kernel-version Signed-off-by: John Crispin --- @@ -10,7 +10,7 @@ Signed-off-by: John Crispin 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/kernel-version.mk b/include/kernel-version.mk -index dff01895be..f5a95af201 100644 +index efecf2f919..787abfca14 100644 --- a/include/kernel-version.mk +++ b/include/kernel-version.mk @@ -6,11 +6,13 @@ ifdef CONFIG_TESTING_KERNEL @@ -20,13 +20,13 @@ index dff01895be..f5a95af201 100644 +LINUX_VERSION-3.18 = .29 LINUX_VERSION-4.4 = .60 LINUX_VERSION-4.14 = .193 - LINUX_VERSION-5.4 = .142 + LINUX_VERSION-5.4 = .158 LINUX_VERSION-5.10 = .27 +LINUX_KERNEL_HASH-3.18.29 = d099072fcbd6aefea8c787c0325eaa56c65b35b15c52579c8a613349bcba425f LINUX_KERNEL_HASH-4.4.60 = e7f2f47acf17497d6ffd713eda65c025b3df0bce09faa8c04712bf1b3cfc9fdb LINUX_KERNEL_HASH-4.14.193 = 0b0fb41d4430e1a42738b341cbfd2f41951aa5cd02acabbd53f076119c8b9f03 - LINUX_KERNEL_HASH-5.4.142 = 99785728968564ba27c7e552d024b560072dcbc885540912eabb5c021e231451 + LINUX_KERNEL_HASH-5.4.158 = 6e018fecdc8fc24553756e582d83b82d65b10a6b03ef36262a24911f839b8d59 diff --git a/include/target.mk b/include/target.mk index 691f8fb186..d198d59262 100644 --- a/include/target.mk diff --git a/patches/rtkmipsel/0006-rtkmipsel-kernel-module-fixes.patch b/patches/rtkmipsel/0006-rtkmipsel-kernel-module-fixes.patch index bb1b0a153..2b4d08758 100644 --- a/patches/rtkmipsel/0006-rtkmipsel-kernel-module-fixes.patch +++ b/patches/rtkmipsel/0006-rtkmipsel-kernel-module-fixes.patch @@ -1,7 +1,7 @@ -From 10c568bd0a619a7f497d1450195f5650695cefff Mon Sep 17 00:00:00 2001 +From 4c86f99b3a97a8f0a9d0c803c322362f7866a620 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 2 Jan 2022 10:10:13 +0100 -Subject: [PATCH 2/2] rtkmipsel: kernel module fixes +Subject: [PATCH 74/83] rtkmipsel: kernel module fixes Signed-off-by: John Crispin --- diff --git a/patches/wifi/0001-mac80211-backport-latest-HEAD.patch b/patches/wifi/0001-mac80211-backport-latest-HEAD.patch new file mode 100644 index 000000000..f684a80bf --- /dev/null +++ b/patches/wifi/0001-mac80211-backport-latest-HEAD.patch @@ -0,0 +1,16557 @@ +From 1ee96e877b2e1ce30774dcde5391e96d5211407f Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Tue, 4 Jan 2022 06:22:29 +0100 +Subject: [PATCH 1/4] mac80211: backport latest HEAD + +Signed-off-by: John Crispin +--- + package/kernel/mac80211/Makefile | 46 +- + package/kernel/mac80211/ath.mk | 18 +- + package/kernel/mac80211/broadcom.mk | 4 +- + .../mac80211/files/lib/netifd/mac80211.sh | 36 - + .../files/lib/netifd/wireless/mac80211.sh | 3 +- + .../mac80211/files/lib/wifi/mac80211.sh | 5 +- + .../patches/ath/120-owl-loader-compat.patch | 53 - + .../patches/ath/402-ath_regd_optional.patch | 8 +- + .../patches/ath/404-regd_no_assoc_hints.patch | 4 +- + .../ath/406-ath_relax_default_regd.patch | 2 +- + .../ath/550-ath9k-disable-bands-via-dt.patch | 15 - + ...h10k-increase-rx-buffer-size-to-2048.patch | 37 - + ...980-ath10k-fix-max-antenna-gain-unit.patch | 49 - + .../080-ath10k_thermal_config.patch | 2 +- + ...calibration-data-via-nvmem-subsystem.patch | 162 ++ + ...21-ath10k_init_devices_synchronously.patch | 2 +- + .../930-ath10k_add_tpt_led_trigger.patch | 4 +- + ...rolling-support-for-various-chipsets.patch | 38 +- + ...75-ath10k-use-tpt-trigger-by-default.patch | 8 +- + ...-power-reduction-for-US-regulatory-d.patch | 8 +- + ...h10k-Try-to-get-mac-address-from-dts.patch | 37 + + .../ath10k/990-ath10k-small-buffers.patch | 64 + + .../201-ath5k-WAR-for-AR71xx-PCI-bug.patch | 0 + .../411-ath5k_allow_adhoc_and_ap.patch | 6 +- + .../420-ath5k_disable_fast_cc.patch | 0 + .../430-add_ath5k_platform.patch | 0 + .../{ath => ath5k}/432-ath5k_add_pciids.patch | 0 + .../440-ath5k_channel_bw_debugfs.patch | 2 +- + ...-ieee80211-freq-limit-property-to-li.patch | 28 + + ...w-reset-AHB-WMAC-interface-on-AR91xx.patch | 2 +- + ..._hw-issue-external-reset-for-QCA955x.patch | 4 +- + ...h9k-force-rx_clear-when-disabling-rx.patch | 0 + ...erpret-requested-txpower-in-EIRP-dom.patch | 4 +- + ...power-reduction-for-US-regulatory-do.patch | 2 +- + .../401-ath9k_blink_default.patch | 2 +- + .../410-ath9k_allow_adhoc_and_ap.patch | 4 +- + ...abled-MFP-capability-unconditionally.patch | 4 +- + .../500-ath9k_eeprom_debugfs.patch | 0 + .../{ath => ath9k}/501-ath9k_ahb_init.patch | 2 +- + .../510-ath9k_intr_mitigation_tweak.patch | 2 +- + .../511-ath9k_reduce_rxbuf.patch | 0 + .../512-ath9k_channelbw_debugfs.patch | 0 + .../513-ath9k_add_pci_ids.patch | 2 +- + .../{ath => ath9k}/530-ath9k_extra_leds.patch | 8 +- + .../531-ath9k_extra_platform_leds.patch | 0 + .../540-ath9k_reduce_ani_interval.patch | 0 + .../542-ath9k_debugfs_diag.patch | 8 +- + .../543-ath9k_entropy_from_adc.patch | 14 +- + ...544-ath9k-ar933x-usb-hang-workaround.patch | 10 +- + .../545-ath9k_ani_ws_detect.patch | 2 +- + .../547-ath9k_led_defstate_fix.patch | 0 + .../548-ath9k_enable_gpio_chip.patch | 4 +- + .../549-ath9k_enable_gpio_buttons.patch | 2 +- + .../551-ath9k_ubnt_uap_plus_hsr.patch | 6 +- + .../552-ath9k-ahb_of.patch} | 18 +- + .../553-ath9k_of_gpio_mask.patch | 4 +- + ...calibration-data-via-nvmem-subsystem.patch | 154 ++ + ...-fetch-pci-init-values-through-nvmem.patch | 181 +++ + .../brcm/812-b43-add-antenna-control.patch | 8 +- + ...-register-wiphy-s-during-module_init.patch | 18 +- + ...62-brcmfmac-Disable-power-management.patch | 2 +- + ...-in-driver-tables-with-country-codes.patch | 12 +- + .../mac80211/patches/brcm/998-survey.patch | 12 +- + .../build/003-remove_bogus_modparams.patch | 2 +- + .../build/004-kconfig_backport_fix.patch | 28 - + .../patches/build/010-disable_rfkill.patch | 15 - + .../patches/build/060-no_local_ssb_bcma.patch | 10 +- + ...700-mwl8k-missing-pci-id-for-WNR854T.patch | 2 +- + ...940-mwl8k_init_devices_synchronously.patch | 4 +- + ...define-RF5592-in-init_eeprom-routine.patch | 2 +- + .../602-rt2x00-introduce-rt2x00eeprom.patch | 10 +- + ...isabling_bands_through_platform_data.patch | 4 +- + ...07-rt2x00-add_platform_data_mac_addr.patch | 11 +- + ...00-allow_disabling_bands_through_dts.patch | 2 +- + ...0-rt2x00-change-led-polarity-from-OF.patch | 2 +- + .../611-rt2x00-add-AP+STA-support.patch | 2 +- + .../612-rt2x00-led-tpt-trigger-support.patch | 4 +- + ...dd-support-for-external-PA-on-MT7620.patch | 6 +- + ...-rt2x00-add-rf-self-txdc-calibration.patch | 4 +- + .../rt2x00/983-rt2x00-add-r-calibration.patch | 4 +- + .../984-rt2x00-add-rxdcoc-calibration.patch | 4 +- + .../985-rt2x00-add-rxiq-calibration.patch | 4 +- + .../986-rt2x00-add-TX-LOFT-calibration.patch | 4 +- + ...-differentiate-based-on-SoC-CHIP_VER.patch | 16 +- + ...ave-survey-for-every-channel-visited.patch | 183 --- + ...ent-set_tim-by-update-beacon-content.patch | 118 -- + .../patches/subsys/010-sync-nl80211_h.patch | 297 ---- + .../100-remove-cryptoapi-dependencies.patch | 699 --------- + .../110-mac80211_keep_keys_on_stop_ap.patch | 2 +- + .../120-cfg80211_allow_perm_addr_change.patch | 2 +- + .../patches/subsys/130-disable-fils.patch | 32 - + ...aes-cmac-switch-to-shash-CMAC-driver.patch | 230 --- + .../132-mac80211-remove-cmac-dependency.patch | 10 - + .../subsys/150-disable_addr_notifier.patch | 12 +- + .../mac80211/patches/subsys/210-ap_scan.patch | 2 +- + ...ort-immediate-reconnect-request-hint.patch | 279 ---- + ...te-control-for-retransmitted-frames.patch} | 2 +- + ...-driver-based-disconnect-with-reconn.patch | 271 ---- + ...port-to-configure-SAE-PWE-value-to-d.patch | 74 - + ...gression-in-SSN-handling-of-addba-tx.patch | 2 +- + ...-the-fwd_skb-dev-for-mesh-forwarding.patch | 2 +- + ...t-access-the-IV-when-it-was-stripped.patch | 26 - + ...BA-requests-using-the-tid-queue-of-.patch} | 0 + ...on-t-schedule_and_wake_txq-under-st.patch} | 0 + ...-free-packets-from-a-flow-on-overmem.patch | 95 -- + ...rse-boottime-for-airtime-fairness-co.patch | 60 + + ...-get_default_func-move-default-flow-.patch | 144 -- + ...ot-maintain-a-backlog-sorted-list-of.patch | 317 ---- + ...add-rx-decapsulation-offload-support.patch | 570 ------- + ...le-QoS-support-for-nl80211-ctrl-port.patch | 116 -- + ...211_hwsim-make-6-GHz-channels-usable.patch | 74 + + ...c80211-minstrel_ht-clean-up-CCK-code.patch | 166 --- + ...l_ht-add-support-for-OFDM-rates-on-n.patch | 762 ---------- + ...-remove-legacy-minstrel-rate-control.patch | 1328 ----------------- + ...l_ht-remove-old-ewma-based-rate-aver.patch | 96 -- + ...l_ht-improve-ampdu-length-estimation.patch | 67 - + ...rel_ht-improve-sample-rate-selection.patch | 31 - + ...l_ht-fix-max-probability-rate-select.patch | 124 -- + ...el_ht-increase-stats-update-interval.patch | 20 - + ...l_ht-fix-rounding-error-in-throughpu.patch | 34 - + ...l_ht-use-bitfields-to-encode-rate-in.patch | 412 ----- + ...l_ht-update-total-packets-counter-in.patch | 54 - + ...l_ht-reduce-the-need-to-sample-slowe.patch | 102 -- + ...l_ht-significantly-redesign-the-rate.patch | 767 ---------- + ...el_ht-show-sampling-rates-in-debugfs.patch | 58 - + ...l_ht-remove-sample-rate-switching-co.patch | 279 ---- + ...l_ht-fix-regression-in-the-max_prob_.patch | 23 - + ...l_ht-rework-rate-downgrade-code-and-.patch | 10 +- + ...pply-flow-control-on-management-fram.patch | 60 - + ...set-sk_pacing_shift-for-802.3-txpath.patch | 21 - + ...-Rx-timestamp-calculation-for-all-pr.patch | 134 -- + ...MPDU-session-check-from-minstrel_ht-.patch | 126 -- + ...eee80211_tx_h_rate_ctrl-when-dequeue.patch | 114 -- + ...te-control-support-for-encap-offload.patch | 126 -- + ...11-minstrel_ht-fix-sample-time-check.patch | 23 - + ...rting-aggregation-sessions-on-mesh-i.patch | 112 -- + ...introduce-aql_enable-node-in-debugfs.patch | 111 -- + ...ange-struct-txq_info-for-fewer-holes.patch | 39 - + ...to-a-virtual-time-based-airtime-sche.patch | 1277 ---------------- + ...on-API-to-configure-SAR-power-limita.patch | 398 ----- + ...mac80211-add-ieee80211_set_sar_specs.patch | 51 - + ...eck-per-vif-offload_flags-in-Tx-path.patch | 26 - + ...nl80211-add-support-for-BSS-coloring.patch | 485 ------ + ...211-add-support-for-BSS-color-change.patch | 524 ------- + ...eee80211-add-TWT-element-definitions.patch | 112 -- + ...ce-individual-TWT-support-in-AP-mode.patch | 576 ------- + ...n-some-HE-capabilities-with-the-spec.patch | 196 --- + ...pelling-of-A-MSDU-in-HE-capabilities.patch | 113 -- + ...E-capabilities-A-MPDU-Length-Exponen.patch | 148 -- + .../patches/subsys/400-allow-ibss-mixed.patch | 2 +- + .../500-mac80211_configure_antenna_gain.patch | 48 +- + ...the-dst-buffer-to-of_get_mac_address.patch | 29 + + 152 files changed, 1038 insertions(+), 13037 deletions(-) + delete mode 100644 package/kernel/mac80211/files/lib/netifd/mac80211.sh + delete mode 100644 package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch + delete mode 100644 package/kernel/mac80211/patches/ath/550-ath9k-disable-bands-via-dt.patch + delete mode 100644 package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch + delete mode 100644 package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch + rename package/kernel/mac80211/patches/{ath => ath10k}/080-ath10k_thermal_config.patch (97%) + create mode 100644 package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch + rename package/kernel/mac80211/patches/{ath => ath10k}/921-ath10k_init_devices_synchronously.patch (94%) + rename package/kernel/mac80211/patches/{ath => ath10k}/930-ath10k_add_tpt_led_trigger.patch (89%) + rename package/kernel/mac80211/patches/{ath => ath10k}/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch (94%) + rename package/kernel/mac80211/patches/{ath => ath10k}/975-ath10k-use-tpt-trigger-by-default.patch (92%) + rename package/kernel/mac80211/patches/{ath => ath10k}/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch (93%) + create mode 100644 package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch + create mode 100644 package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch + rename package/kernel/mac80211/patches/{ath => ath5k}/201-ath5k-WAR-for-AR71xx-PCI-bug.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath5k}/411-ath5k_allow_adhoc_and_ap.patch (89%) + rename package/kernel/mac80211/patches/{ath => ath5k}/420-ath5k_disable_fast_cc.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath5k}/430-add_ath5k_platform.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath5k}/432-ath5k_add_pciids.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath5k}/440-ath5k_channel_bw_debugfs.patch (98%) + create mode 100644 package/kernel/mac80211/patches/ath9k/040-ath9k-support-DT-ieee80211-freq-limit-property-to-li.patch + rename package/kernel/mac80211/patches/{ath => ath9k}/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch (89%) + rename package/kernel/mac80211/patches/{ath => ath9k}/351-ath9k_hw-issue-external-reset-for-QCA955x.patch (95%) + rename package/kernel/mac80211/patches/{ath => ath9k}/354-ath9k-force-rx_clear-when-disabling-rx.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath9k}/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch (89%) + rename package/kernel/mac80211/patches/{ath => ath9k}/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch (91%) + rename package/kernel/mac80211/patches/{ath => ath9k}/401-ath9k_blink_default.patch (88%) + rename package/kernel/mac80211/patches/{ath => ath9k}/410-ath9k_allow_adhoc_and_ap.patch (73%) + rename package/kernel/mac80211/patches/{ath => ath9k}/450-ath9k-enabled-MFP-capability-unconditionally.patch (90%) + rename package/kernel/mac80211/patches/{ath => ath9k}/500-ath9k_eeprom_debugfs.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath9k}/501-ath9k_ahb_init.patch (91%) + rename package/kernel/mac80211/patches/{ath => ath9k}/510-ath9k_intr_mitigation_tweak.patch (87%) + rename package/kernel/mac80211/patches/{ath => ath9k}/511-ath9k_reduce_rxbuf.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath9k}/512-ath9k_channelbw_debugfs.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath9k}/513-ath9k_add_pci_ids.patch (93%) + rename package/kernel/mac80211/patches/{ath => ath9k}/530-ath9k_extra_leds.patch (96%) + rename package/kernel/mac80211/patches/{ath => ath9k}/531-ath9k_extra_platform_leds.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath9k}/540-ath9k_reduce_ani_interval.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath9k}/542-ath9k_debugfs_diag.patch (93%) + rename package/kernel/mac80211/patches/{ath => ath9k}/543-ath9k_entropy_from_adc.patch (94%) + rename package/kernel/mac80211/patches/{ath => ath9k}/544-ath9k-ar933x-usb-hang-workaround.patch (84%) + rename package/kernel/mac80211/patches/{ath => ath9k}/545-ath9k_ani_ws_detect.patch (98%) + rename package/kernel/mac80211/patches/{ath => ath9k}/547-ath9k_led_defstate_fix.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath9k}/548-ath9k_enable_gpio_chip.patch (98%) + rename package/kernel/mac80211/patches/{ath => ath9k}/549-ath9k_enable_gpio_buttons.patch (98%) + rename package/kernel/mac80211/patches/{ath => ath9k}/551-ath9k_ubnt_uap_plus_hsr.patch (98%) + rename package/kernel/mac80211/patches/{ath/552-ahb_of.patch => ath9k/552-ath9k-ahb_of.patch} (93%) + rename package/kernel/mac80211/patches/{ath => ath9k}/553-ath9k_of_gpio_mask.patch (80%) + create mode 100644 package/kernel/mac80211/patches/ath9k/600-v5.16-ath9k-fetch-calibration-data-via-nvmem-subsystem.patch + create mode 100644 package/kernel/mac80211/patches/ath9k/601-v5.16-ath9k-owl-loader-fetch-pci-init-values-through-nvmem.patch + delete mode 100644 package/kernel/mac80211/patches/build/004-kconfig_backport_fix.patch + delete mode 100644 package/kernel/mac80211/patches/build/010-disable_rfkill.patch + delete mode 100644 package/kernel/mac80211/patches/rt2x00/992-rt2x00-save-survey-for-every-channel-visited.patch + delete mode 100644 package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/010-sync-nl80211_h.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/130-disable-fils.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/300-cfg80211-support-immediate-reconnect-request-hint.patch + rename package/kernel/mac80211/patches/subsys/{394-mac80211-fix-rate-control-for-retransmitted-frames.patch => 301-mac80211-fix-rate-control-for-retransmitted-frames.patch} (94%) + delete mode 100644 package/kernel/mac80211/patches/subsys/301-mac80211-support-driver-based-disconnect-with-reconn.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/302-cfg80211-Add-support-to-configure-SAE-PWE-value-to-d.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/307-mac80211-do-not-access-the-IV-when-it-was-stripped.patch + rename package/kernel/mac80211/patches/subsys/{308-mac80211-send-ADDBA-requests-using-the-tid-queue-of-.patch => 309-mac80211-send-ADDBA-requests-using-the-tid-queue-of-.patch} (100%) + rename package/kernel/mac80211/patches/subsys/{309-mac80211-agg-tx-don-t-schedule_and_wake_txq-under-st.patch => 310-mac80211-agg-tx-don-t-schedule_and_wake_txq-under-st.patch} (100%) + delete mode 100644 package/kernel/mac80211/patches/subsys/310-net-fq_impl-bulk-free-packets-from-a-flow-on-overmem.patch + create mode 100644 package/kernel/mac80211/patches/subsys/311-mac80211-use-coarse-boottime-for-airtime-fairness-co.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/311-net-fq_impl-drop-get_default_func-move-default-flow-.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/312-net-fq_impl-do-not-maintain-a-backlog-sorted-list-of.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/315-mac80211-add-rx-decapsulation-offload-support.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch + create mode 100644 package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/338-mac80211-minstrel_ht-add-support-for-OFDM-rates-on-n.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/340-mac80211-minstrel_ht-remove-old-ewma-based-rate-aver.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/345-mac80211-minstrel_ht-fix-rounding-error-in-throughpu.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/346-mac80211-minstrel_ht-use-bitfields-to-encode-rate-in.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/347-mac80211-minstrel_ht-update-total-packets-counter-in.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/348-mac80211-minstrel_ht-reduce-the-need-to-sample-slowe.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/349-mac80211-minstrel_ht-significantly-redesign-the-rate.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/350-mac80211-minstrel_ht-show-sampling-rates-in-debugfs.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/351-mac80211-minstrel_ht-remove-sample-rate-switching-co.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/352-mac80211-minstrel_ht-fix-regression-in-the-max_prob_.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/373-mac80211-support-Rx-timestamp-calculation-for-all-pr.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/377-mac80211-minstrel_ht-fix-sample-time-check.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/387-nl80211-add-support-for-BSS-coloring.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/388-mac80211-add-support-for-BSS-color-change.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/389-ieee80211-add-TWT-element-definitions.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/390-mac80211-introduce-individual-TWT-support-in-AP-mode.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/391-wireless-align-some-HE-capabilities-with-the-spec.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/392-wireless-fix-spelling-of-A-MSDU-in-HE-capabilities.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/393-wireless-align-HE-capabilities-A-MPDU-Length-Exponen.patch + create mode 100644 package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch + +diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile +index 211bb346f3..2f9fd11f10 100644 +--- a/package/kernel/mac80211/Makefile ++++ b/package/kernel/mac80211/Makefile +@@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk + + PKG_NAME:=mac80211 + +-PKG_VERSION:=5.10.68-1 +-PKG_RELEASE:=3 +-PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.10.68/ +-PKG_HASH:=bba161b0084590c677a84b80993709e388a3c478f29ed0c475d4fce1b9162968 ++PKG_VERSION:=5.15.8-1 ++PKG_RELEASE:=1 ++PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.8/ ++PKG_HASH:=9f71b659c034f19d156532ec780fcb606cee3c4ccc42e2f8ef18dd3e9f1b6820 + + PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz + PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) +@@ -23,7 +23,6 @@ PKG_MAINTAINER:=Felix Fietkau + + PKG_DRIVERS = \ + adm8211 \ +- airo \ + hermes hermes-pci hermes-pcmcia hermes-plx\ + lib80211 \ + mac80211-hwsim \ +@@ -98,7 +97,7 @@ PKG_CONFIG_DEPENDS += \ + define KernelPackage/cfg80211 + $(call KernelPackage/mac80211/Default) + TITLE:=cfg80211 - wireless configuration API +- DEPENDS+= +iw +wireless-regdb ++ DEPENDS+= +iw +iwinfo +wireless-regdb +USE_RFKILL:kmod-rfkill + ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) + FILES:= \ + $(PKG_BUILD_DIR)/compat/compat.ko \ +@@ -127,7 +126,7 @@ define KernelPackage/mac80211 + $(call KernelPackage/mac80211/Default) + TITLE:=Linux 802.11 Wireless Networking Stack + # +kmod-crypto-cmac is a runtime only dependency of net/mac80211/aes_cmac.c +- DEPENDS+= +kmod-cfg80211 +hostapd-common ++ DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm +hostapd-common + KCONFIG:=\ + CONFIG_AVERAGE=y + FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko +@@ -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 +@@ -434,9 +419,15 @@ config-$(call config_package,rsi91x-sdio) += RSI_SDIO + + config-$(CONFIG_LEDS_TRIGGERS) += MAC80211_LEDS + ++C_DEFINES= ++ ++ifeq ($(BUILD_VARIANT),smallbuffers) ++ C_DEFINES+= -DCONFIG_ATH10K_SMALLBUFFERS ++endif ++ + MAKE_OPTS:= -C "$(PKG_BUILD_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ +- EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS)" \ ++ EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) $(C_DEFINES)" \ + KLIB_BUILD="$(LINUX_DIR)" \ + MODPROBE=true \ + KLIB=$(TARGET_MODULES_DIR) \ +@@ -501,9 +492,14 @@ define Build/Patch + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) ++ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/) ++ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) ++ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) ++ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) ++ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/) + $(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used) + endef + +@@ -511,9 +507,14 @@ define Quilt/Refresh/Package + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) ++ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/) ++ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) ++ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) ++ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) ++ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/) + endef + + define Build/Compile +@@ -539,7 +540,6 @@ endef + define KernelPackage/cfg80211/install + $(INSTALL_DIR) $(1)/lib/wifi $(1)/lib/netifd/wireless + $(INSTALL_DATA) ./files/lib/wifi/mac80211.sh $(1)/lib/wifi +- $(INSTALL_DATA) ./files/lib/netifd/mac80211.sh $(1)/lib/netifd + $(INSTALL_BIN) ./files/lib/netifd/wireless/mac80211.sh $(1)/lib/netifd/wireless + $(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211 + $(INSTALL_DATA) ./files/mac80211.hotplug $(1)/etc/hotplug.d/ieee80211/10-wifi-detect +diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk +index 24abb910ff..50b1eed9c8 100644 +--- a/package/kernel/mac80211/ath.mk ++++ b/package/kernel/mac80211/ath.mk +@@ -1,5 +1,5 @@ + PKG_DRIVERS += \ +- ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k \ ++ ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k ath10k-smallbuffers \ + carl9170 owl-loader ar5523 wil6210 + + PKG_CONFIG_DEPENDS += \ +@@ -34,7 +34,7 @@ ifdef CONFIG_PACKAGE_MAC80211_TRACING + WIL6210_TRACING + endif + +-config-$(call config_package,ath) += ATH_CARDS ATH_COMMON ATH_REG_DYNAMIC_USER_REG_HINTS ++config-$(call config_package,ath) += ATH_CARDS ATH_COMMON + config-$(CONFIG_PACKAGE_ATH_DEBUG) += ATH_DEBUG ATH10K_DEBUG ATH9K_STATION_STATISTICS + config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED + config-$(CONFIG_PACKAGE_ATH_SPECTRAL) += ATH9K_COMMON_SPECTRAL ATH10K_SPECTRAL +@@ -45,7 +45,7 @@ config-$(call config_package,owl-loader) += ATH9K_PCI_NO_EEPROM + config-$(CONFIG_TARGET_ath79) += ATH9K_AHB + config-$(CONFIG_TARGET_ipq40xx) += ATH10K_AHB + config-$(CONFIG_PCI) += ATH9K_PCI +-config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD ++config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD ATH_REG_DYNAMIC_USER_REG_HINTS + config-$(CONFIG_ATH9K_HWRNG) += ATH9K_HWRNG + config-$(CONFIG_ATH9K_SUPPORT_PCOEM) += ATH9K_PCOEM + config-$(CONFIG_ATH9K_TX99) += ATH9K_TX99 +@@ -55,6 +55,7 @@ config-$(CONFIG_ATH10K_THERMAL) += ATH10K_THERMAL + + config-$(call config_package,ath9k-htc) += ATH9K_HTC + config-$(call config_package,ath10k) += ATH10K ATH10K_PCI ++config-$(call config_package,ath10k-smallbuffers) += ATH10K ATH10K_PCI ATH10K_SMALLBUFFERS + + config-$(call config_package,ath5k) += ATH5K + ifdef CONFIG_TARGET_ath25 +@@ -260,6 +261,7 @@ define KernelPackage/ath10k + $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_core.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_pci.ko + AUTOLOAD:=$(call AutoProbe,ath10k_pci) ++ VARIANT:=regular + endef + + define KernelPackage/ath10k/description +@@ -273,14 +275,20 @@ define KernelPackage/ath10k/config + config ATH10K_LEDS + bool "Enable LED support" + default y +- depends on PACKAGE_kmod-ath10k ++ depends on PACKAGE_kmod-ath10k || PACKAGE_kmod-ath10k-smallbuffers + + config ATH10K_THERMAL + bool "Enable thermal sensors and throttling support" +- depends on PACKAGE_kmod-ath10k ++ depends on PACKAGE_kmod-ath10k || PACKAGE_kmod-ath10k-smallbuffers + + endef + ++define KernelPackage/ath10k-smallbuffers ++ $(call KernelPackage/ath10k) ++ TITLE+= (small buffers for low-RAM devices) ++ VARIANT:=smallbuffers ++endef ++ + define KernelPackage/carl9170 + $(call KernelPackage/mac80211/Default) + TITLE:=Driver for Atheros AR9170 USB sticks +diff --git a/package/kernel/mac80211/broadcom.mk b/package/kernel/mac80211/broadcom.mk +index fb576c5809..473bbf597c 100644 +--- a/package/kernel/mac80211/broadcom.mk ++++ b/package/kernel/mac80211/broadcom.mk +@@ -209,7 +209,7 @@ config PACKAGE_B43_USE_BCMA + default "16,28,29,30" if TARGET_bcm47xx_mips74k + default "5,6,7,8,9,10,11,13,15,16,28,29,30" + help +- This is a comma seperated list of core revision numbers. ++ This is a comma separated list of core revision numbers. + + Example (keep files for rev5 only): + 5 +@@ -224,7 +224,7 @@ config PACKAGE_B43_USE_BCMA + default "N,HT" if TARGET_bcm47xx_mips74k + default "G,N,LP,HT" + help +- This is a comma seperated list of PHY types: ++ This is a comma separated list of PHY types: + A => A-PHY + AG => Dual A-PHY G-PHY + G => G-PHY +diff --git a/package/kernel/mac80211/files/lib/netifd/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/mac80211.sh +deleted file mode 100644 +index 92e5c0e395..0000000000 +--- a/package/kernel/mac80211/files/lib/netifd/mac80211.sh ++++ /dev/null +@@ -1,36 +0,0 @@ +-mac80211_phy_to_path() { +- local phy="$1" +- +- [ -x /usr/bin/readlink -a -h /sys/class/ieee80211/${phy} ] || return +- +- local path="$(readlink -f /sys/class/ieee80211/${phy}/device)" +- [ -n "$path" ] || return +- +- path="${path##/sys/devices/}" +- case "$path" in +- platform*/pci*) path="${path##platform/}";; +- esac +- +- local p +- local seq="" +- for p in $(ls /sys/class/ieee80211/$phy/device/ieee80211); do +- [ "$p" = "$phy" ] && { +- echo "$path${seq:++$seq}" +- break +- } +- +- seq=$((${seq:-0} + 1)) +- done +-} +- +-mac80211_path_to_phy() { +- local path="$1" +- +- local p +- for p in $(ls /sys/class/ieee80211); do +- local cur="$(mac80211_phy_to_path "$p")" +- case "$cur" in +- *$path) echo "$p"; return;; +- esac +- done +-} +diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +index d69667bf8c..27eecf3a7f 100644 +--- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh ++++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +@@ -1,7 +1,6 @@ + #!/bin/sh + . /lib/netifd/netifd-wireless.sh + . /lib/netifd/hostapd.sh +-. /lib/netifd/mac80211.sh + + init_wireless_driver "$@" + +@@ -563,7 +562,7 @@ mac80211_generate_mac() { + find_phy() { + [ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0 + [ -n "$path" ] && { +- phy="$(mac80211_path_to_phy "$path")" ++ phy="$(iwinfo nl80211 phyname "path=$path")" + [ -n "$phy" ] && return 0 + } + [ -n "$macaddr" ] && { +diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh +index 5eb7cc4c61..6aa46b0c74 100644 +--- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh ++++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh +@@ -1,5 +1,4 @@ + #!/bin/sh +-. /lib/netifd/mac80211.sh + + append DRIVERS "mac80211" + +@@ -11,7 +10,7 @@ lookup_phy() { + local devpath + config_get devpath "$device" path + [ -n "$devpath" ] && { +- phy="$(mac80211_path_to_phy "$devpath")" ++ phy="$(iwinfo nl80211 phyname "path=$devpath")" + [ -n "$phy" ] && return + } + +@@ -161,7 +160,7 @@ detect_mac80211() { + + get_band_defaults "$dev" + +- path="$(mac80211_phy_to_path "$dev")" ++ path="$(iwinfo nl80211 path "$dev")" + if [ -n "$path" ]; then + dev_id="set wireless.radio${devidx}.path='$path'" + else +diff --git a/package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch b/package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch +deleted file mode 100644 +index d1d6c9e2e3..0000000000 +--- a/package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch ++++ /dev/null +@@ -1,53 +0,0 @@ +-From: Christian Lamparter +-Date: Sat, 16 Nov 2019 19:25:24 +0100 +-Subject: [PATCH] owl_loader: compatibility patch +- +-This patch includes OpenWrt specific changes that are +-not included in the upstream owl-loader. +- +-This includes a platform data handling changes for ar71xx. +- +-Signed-off-by: Christian Lamparter +- +---- a/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c +-+++ b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c +-@@ -103,6 +103,7 @@ static void owl_fw_cb(const struct firmw +- { +- struct pci_dev *pdev = (struct pci_dev *)context; +- struct owl_ctx *ctx = (struct owl_ctx *)pci_get_drvdata(pdev); +-+ struct ath9k_platform_data *pdata = dev_get_platdata(&pdev->dev); +- struct pci_bus *bus; +- +- complete(&ctx->eeprom_load); +-@@ -118,6 +119,16 @@ static void owl_fw_cb(const struct firmw +- goto release; +- } +- +-+ if (pdata) { +-+ memcpy(pdata->eeprom_data, fw->data, fw->size); +-+ +-+ /* +-+ * eeprom has been successfully loaded - pass the data to ath9k +-+ * but remove the eeprom_name, so it doesn't try to load it too. +-+ */ +-+ pdata->eeprom_name = NULL; +-+ } +-+ +- if (ath9k_pci_fixup(pdev, (const u16 *)fw->data, fw->size)) +- goto release; +- +-@@ -137,8 +148,14 @@ release: +- static const char *owl_get_eeprom_name(struct pci_dev *pdev) +- { +- struct device *dev = &pdev->dev; +-+ struct ath9k_platform_data *pdata; +- char *eeprom_name; +- +-+ /* try the existing platform data first */ +-+ pdata = dev_get_platdata(dev); +-+ if (pdata && pdata->eeprom_name) +-+ return pdata->eeprom_name; +-+ +- dev_dbg(dev, "using auto-generated eeprom filename\n"); +- +- eeprom_name = devm_kzalloc(dev, EEPROM_FILENAME_LEN, GFP_KERNEL); +diff --git a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch +index bf87d3551a..506beb79c3 100644 +--- a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch ++++ b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch +@@ -37,7 +37,7 @@ + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if (!wiphy->bands[band]) + continue; +-@@ -378,6 +387,9 @@ ath_reg_apply_ir_flags(struct wiphy *wip ++@@ -379,6 +388,9 @@ ath_reg_apply_ir_flags(struct wiphy *wip + { + struct ieee80211_supported_band *sband; + +@@ -47,7 +47,7 @@ + sband = wiphy->bands[NL80211_BAND_2GHZ]; + if (!sband) + return; +-@@ -407,6 +419,9 @@ static void ath_reg_apply_radar_flags(st ++@@ -408,6 +420,9 @@ static void ath_reg_apply_radar_flags(st + struct ieee80211_channel *ch; + unsigned int i; + +@@ -57,7 +57,7 @@ + if (!wiphy->bands[NL80211_BAND_5GHZ]) + return; + +-@@ -639,6 +654,10 @@ ath_regd_init_wiphy(struct ath_regulator ++@@ -640,6 +655,10 @@ ath_regd_init_wiphy(struct ath_regulator + const struct ieee80211_regdomain *regd; + + wiphy->reg_notifier = reg_notifier; +@@ -82,7 +82,7 @@ + help + --- a/local-symbols + +++ b/local-symbols +-@@ -85,6 +85,7 @@ ADM8211= ++@@ -76,6 +76,7 @@ ADM8211= + ATH_COMMON= + WLAN_VENDOR_ATH= + ATH_DEBUG= +diff --git a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch +index c6dc184e28..833e2411c4 100644 +--- a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch ++++ b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch +@@ -1,6 +1,6 @@ + --- a/net/wireless/reg.c + +++ b/net/wireless/reg.c +-@@ -3252,6 +3252,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; +-@@ -3503,6 +3505,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) + { +diff --git a/package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch b/package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch +index 35b0f2b76e..ee4e461342 100644 +--- a/package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch ++++ b/package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch +@@ -39,7 +39,7 @@ + bool ath_is_world_regd(struct ath_regulatory *reg) + { + return is_wwr_sku(ath_regd_get_eepromRD(reg)); +-@@ -658,6 +666,9 @@ ath_regd_init_wiphy(struct ath_regulator ++@@ -659,6 +667,9 @@ ath_regd_init_wiphy(struct ath_regulator + if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) + return 0; + +diff --git a/package/kernel/mac80211/patches/ath/550-ath9k-disable-bands-via-dt.patch b/package/kernel/mac80211/patches/ath/550-ath9k-disable-bands-via-dt.patch +deleted file mode 100644 +index 7d3a334c42..0000000000 +--- a/package/kernel/mac80211/patches/ath/550-ath9k-disable-bands-via-dt.patch ++++ /dev/null +@@ -1,15 +0,0 @@ +---- a/drivers/net/wireless/ath/ath9k/init.c +-+++ b/drivers/net/wireless/ath/ath9k/init.c +-@@ -627,6 +627,12 @@ static int ath9k_of_init(struct ath_soft +- +- ath_dbg(common, CONFIG, "parsing configuration from OF node\n"); +- +-+ if (of_property_read_bool(np, "qca,disable-2ghz")) +-+ ah->disable_2ghz = true; +-+ +-+ if (of_property_read_bool(np, "qca,disable-5ghz")) +-+ ah->disable_5ghz = true; +-+ +- if (of_property_read_bool(np, "qca,no-eeprom")) { +- /* ath9k-eeprom--.bin */ +- scnprintf(eeprom_name, sizeof(eeprom_name), +diff --git a/package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch b/package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch +deleted file mode 100644 +index 8f7a60eec8..0000000000 +--- a/package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch ++++ /dev/null +@@ -1,37 +0,0 @@ +-From: Linus Lüssing +-Date: Wed, 5 Feb 2020 20:10:43 +0100 +-Subject: ath10k: increase rx buffer size to 2048 +- +-Before, only frames with a maximum size of 1528 bytes could be +-transmitted between two 802.11s nodes. +- +-For batman-adv for instance, which adds its own header to each frame, +-we typically need an MTU of at least 1532 bytes to be able to transmit +-without fragmentation. +- +-This patch now increases the maxmimum frame size from 1528 to 1656 +-bytes. +- +-Tested with two ath10k devices in 802.11s mode, as well as with +-batman-adv on top of 802.11s with forwarding disabled. +- +-Fix originally found and developed by Ben Greear. +- +-Link: https://github.com/greearb/ath10k-ct/issues/89 +-Link: https://github.com/greearb/ath10k-ct/commit/9e5ab25027e0971fa24ccf93373324c08c4e992d +-Cc: Ben Greear +-Signed-off-by: Linus Lüssing +- +-Forwarded: https://patchwork.kernel.org/patch/11367055/ +- +---- a/drivers/net/wireless/ath/ath10k/htt.h +-+++ b/drivers/net/wireless/ath/ath10k/htt.h +-@@ -2243,7 +2243,7 @@ struct htt_rx_chan_info { +- * Should be: sizeof(struct htt_host_rx_desc) + max rx MSDU size, +- * rounded up to a cache line size. +- */ +--#define HTT_RX_BUF_SIZE 1920 +-+#define HTT_RX_BUF_SIZE 2048 +- #define HTT_RX_MSDU_SIZE (HTT_RX_BUF_SIZE - (int)sizeof(struct htt_rx_desc)) +- +- /* Refill a bunch of RX buffers for each refill round so that FW/HW can handle +diff --git a/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch b/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch +deleted file mode 100644 +index e951e011e6..0000000000 +--- a/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch ++++ /dev/null +@@ -1,49 +0,0 @@ +-From: Sven Eckelmann +-Date: Tue, 11 Jun 2019 13:58:35 +0200 +-Subject: ath10k: fix max antenna gain unit +- +-Most of the txpower for the ath10k firmware is stored as twicepower (0.5 dB +-steps). This isn't the case for max_antenna_gain - which is still expected +-by the firmware as dB. +- +-The firmware is converting it from dB to the internal (twicepower) +-representation when it calculates the limits of a channel. This can be seen +-in tpc_stats when configuring "12" as max_antenna_gain. Instead of the +-expected 12 (6 dB), the tpc_stats shows 24 (12 dB). +- +-Tested on QCA9888 and IPQ4019 with firmware 10.4-3.5.3-00057. +- +-Fixes: 02256930d9b8 ("ath10k: use proper tx power unit") +-Signed-off-by: Sven Eckelmann +- +-Forwarded: https://patchwork.kernel.org/patch/10986723/ +- +---- a/drivers/net/wireless/ath/ath10k/mac.c +-+++ b/drivers/net/wireless/ath/ath10k/mac.c +-@@ -1038,7 +1038,7 @@ static int ath10k_monitor_vdev_start(str +- arg.channel.min_power = 0; +- arg.channel.max_power = channel->max_power * 2; +- arg.channel.max_reg_power = channel->max_reg_power * 2; +-- arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; +-+ arg.channel.max_antenna_gain = channel->max_antenna_gain; +- +- reinit_completion(&ar->vdev_setup_done); +- reinit_completion(&ar->vdev_delete_done); +-@@ -1484,7 +1484,7 @@ static int ath10k_vdev_start_restart(str +- arg.channel.min_power = 0; +- arg.channel.max_power = chandef->chan->max_power * 2; +- arg.channel.max_reg_power = chandef->chan->max_reg_power * 2; +-- arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2; +-+ arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain; +- +- if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { +- arg.ssid = arvif->u.ap.ssid; +-@@ -3255,7 +3255,7 @@ static int ath10k_update_channel_list(st +- ch->min_power = 0; +- ch->max_power = channel->max_power * 2; +- ch->max_reg_power = channel->max_reg_power * 2; +-- ch->max_antenna_gain = channel->max_antenna_gain * 2; +-+ ch->max_antenna_gain = channel->max_antenna_gain; +- ch->reg_class_id = 0; /* FIXME */ +- +- /* FIXME: why use only legacy modes, why not any +diff --git a/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch b/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch +similarity index 97% +rename from package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch +rename to package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch +index de6f9d9bb0..0886fd688a 100644 +--- a/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch ++++ b/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch +@@ -37,7 +37,7 @@ + void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); + --- a/local-symbols + +++ b/local-symbols +-@@ -142,6 +142,7 @@ ATH10K_SNOC= ++@@ -135,6 +135,7 @@ ATH10K_SNOC= + ATH10K_DEBUG= + ATH10K_DEBUGFS= + ATH10K_SPECTRAL= +diff --git a/package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch b/package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch +new file mode 100644 +index 0000000000..6728a69efe +--- /dev/null ++++ b/package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch +@@ -0,0 +1,162 @@ ++From e2333703373e8b81294da5d1c73c30154f75b082 Mon Sep 17 00:00:00 2001 ++From: Christian Lamparter ++Date: Fri, 15 Oct 2021 18:56:33 +0200 ++Subject: [PATCH] ath10k: fetch (pre-)calibration data via nvmem subsystem ++ ++On most embedded ath10k devices (like range extenders, ++routers, accesspoints, ...) the calibration data is ++stored in a easily accessible MTD partitions named ++"ART", "caldata", "calibration", etc... ++ ++Since commit 4b361cfa8624 ("mtd: core: add OTP nvmem provider support"): ++MTD partitions and portions of them can be specified ++as potential nvmem-cells which are accessible through ++the nvmem subsystem. ++ ++This feature - together with an nvmem cell definition either ++in the platform data or via device-tree allows drivers to get ++the (pre-)calibration data which is required for initializing ++the WIFI. ++ ++Tested with Netgear EX6150v2 (IPQ4018) ++ ++Cc: Robert Marko ++Cc: Thibaut Varene ++Signed-off-by: Christian Lamparter ++--- ++--- a/drivers/net/wireless/ath/ath10k/core.c +++++ b/drivers/net/wireless/ath/ath10k/core.c ++@@ -12,6 +12,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ ++ #include "core.h" ++@@ -935,7 +936,8 @@ static int ath10k_core_get_board_id_from ++ } ++ ++ if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT || ++- ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE) +++ ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE || +++ ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM) ++ bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID; ++ else ++ bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID; ++@@ -1726,7 +1728,8 @@ static int ath10k_download_and_run_otp(s ++ ++ /* As of now pre-cal is valid for 10_4 variants */ ++ if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT || ++- ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE) +++ ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE || +++ ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM) ++ bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL; ++ ++ ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result); ++@@ -1853,6 +1856,39 @@ out_free: ++ return ret; ++ } ++ +++static int ath10k_download_cal_nvmem(struct ath10k *ar, const char *cell_name) +++{ +++ struct nvmem_cell *cell; +++ void *buf; +++ size_t len; +++ int ret; +++ +++ cell = devm_nvmem_cell_get(ar->dev, cell_name); +++ if (IS_ERR(cell)) { +++ ret = PTR_ERR(cell); +++ return ret; +++ } +++ +++ buf = nvmem_cell_read(cell, &len); +++ if (IS_ERR(buf)) +++ return PTR_ERR(buf); +++ +++ if (ar->hw_params.cal_data_len != len) { +++ kfree(buf); +++ ath10k_warn(ar, "invalid calibration data length in nvmem-cell '%s': %zu != %u\n", +++ cell_name, len, ar->hw_params.cal_data_len); +++ return -EMSGSIZE; +++ } +++ +++ ret = ath10k_download_board_data(ar, buf, len); +++ kfree(buf); +++ if (ret) +++ ath10k_warn(ar, "failed to download calibration data from nvmem-cell '%s': %d\n", +++ cell_name, ret); +++ +++ return ret; +++} +++ ++ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name, ++ struct ath10k_fw_file *fw_file) ++ { ++@@ -2087,6 +2123,18 @@ static int ath10k_core_pre_cal_download( ++ { ++ int ret; ++ +++ ret = ath10k_download_cal_nvmem(ar, "pre-calibration"); +++ if (ret == 0) { +++ ar->cal_mode = ATH10K_PRE_CAL_MODE_NVMEM; +++ goto success; +++ } else if (ret == -EPROBE_DEFER) { +++ return ret; +++ } +++ +++ ath10k_dbg(ar, ATH10K_DBG_BOOT, +++ "boot did not find a pre-calibration nvmem-cell, try file next: %d\n", +++ ret); +++ ++ ret = ath10k_download_cal_file(ar, ar->pre_cal_file); ++ if (ret == 0) { ++ ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE; ++@@ -2153,6 +2201,18 @@ static int ath10k_download_cal_data(stru ++ "pre cal download procedure failed, try cal file: %d\n", ++ ret); ++ +++ ret = ath10k_download_cal_nvmem(ar, "calibration"); +++ if (ret == 0) { +++ ar->cal_mode = ATH10K_CAL_MODE_NVMEM; +++ goto done; +++ } else if (ret == -EPROBE_DEFER) { +++ return ret; +++ } +++ +++ ath10k_dbg(ar, ATH10K_DBG_BOOT, +++ "boot did not find a calibration nvmem-cell, try file next: %d\n", +++ ret); +++ ++ ret = ath10k_download_cal_file(ar, ar->cal_file); ++ if (ret == 0) { ++ ar->cal_mode = ATH10K_CAL_MODE_FILE; ++--- a/drivers/net/wireless/ath/ath10k/core.h +++++ b/drivers/net/wireless/ath/ath10k/core.h ++@@ -877,8 +877,10 @@ enum ath10k_cal_mode { ++ ATH10K_CAL_MODE_FILE, ++ ATH10K_CAL_MODE_OTP, ++ ATH10K_CAL_MODE_DT, +++ ATH10K_CAL_MODE_NVMEM, ++ ATH10K_PRE_CAL_MODE_FILE, ++ ATH10K_PRE_CAL_MODE_DT, +++ ATH10K_PRE_CAL_MODE_NVMEM, ++ ATH10K_CAL_MODE_EEPROM, ++ }; ++ ++@@ -898,10 +900,14 @@ static inline const char *ath10k_cal_mod ++ return "otp"; ++ case ATH10K_CAL_MODE_DT: ++ return "dt"; +++ case ATH10K_CAL_MODE_NVMEM: +++ return "nvmem"; ++ case ATH10K_PRE_CAL_MODE_FILE: ++ return "pre-cal-file"; ++ case ATH10K_PRE_CAL_MODE_DT: ++ return "pre-cal-dt"; +++ case ATH10K_PRE_CAL_MODE_NVMEM: +++ return "pre-cal-nvmem"; ++ case ATH10K_CAL_MODE_EEPROM: ++ return "eeprom"; ++ } +diff --git a/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch +similarity index 94% +rename from package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch +rename to package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch +index e004acc340..710cd45269 100644 +--- a/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch ++++ b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch +@@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann + + --- a/drivers/net/wireless/ath/ath10k/core.c + +++ b/drivers/net/wireless/ath/ath10k/core.c +-@@ -3189,6 +3189,16 @@ int ath10k_core_register(struct ath10k * ++@@ -3412,6 +3412,16 @@ int ath10k_core_register(struct ath10k * + + queue_work(ar->workqueue, &ar->register_work); + +diff --git a/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch +similarity index 89% +rename from package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch +rename to package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch +index 517a98206d..b60db19464 100644 +--- a/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch ++++ b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ath/ath10k/mac.c + +++ b/drivers/net/wireless/ath/ath10k/mac.c +-@@ -9709,6 +9709,21 @@ static int ath10k_mac_init_rd(struct ath ++@@ -9843,6 +9843,21 @@ static int ath10k_mac_init_rd(struct ath + return 0; + } + +@@ -22,7 +22,7 @@ + int ath10k_mac_register(struct ath10k *ar) + { + static const u32 cipher_suites[] = { +-@@ -10058,6 +10073,12 @@ int ath10k_mac_register(struct ath10k *a ++@@ -10195,6 +10210,12 @@ int ath10k_mac_register(struct ath10k *a + + ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; + +diff --git a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch +similarity index 94% +rename from package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch +rename to package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch +index ce8effe3c3..65d67b2e03 100644 +--- a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch ++++ b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch +@@ -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. + +@@ -114,7 +114,7 @@ v13: + ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o + --- a/local-symbols + +++ b/local-symbols +-@@ -145,6 +145,7 @@ ATH10K_DEBUG= ++@@ -136,6 +136,7 @@ ATH10K_DEBUG= + ATH10K_DEBUGFS= + ATH10K_SPECTRAL= + ATH10K_THERMAL= +@@ -124,7 +124,7 @@ v13: + WCN36XX= + --- a/drivers/net/wireless/ath/ath10k/core.c + +++ b/drivers/net/wireless/ath/ath10k/core.c +-@@ -25,6 +25,7 @@ ++@@ -26,6 +26,7 @@ + #include "testmode.h" + #include "wmi-ops.h" + #include "coredump.h" +@@ -132,7 +132,7 @@ v13: + + unsigned int ath10k_debug_mask; + EXPORT_SYMBOL(ath10k_debug_mask); +-@@ -61,6 +62,7 @@ static const struct ath10k_hw_params ath ++@@ -62,6 +63,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA988X_2_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca988x hw2.0", +@@ -140,7 +140,7 @@ v13: + .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, +-@@ -130,6 +132,7 @@ static const struct ath10k_hw_params ath ++@@ -133,6 +135,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA9887_1_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca9887 hw1.0", +@@ -148,7 +148,7 @@ v13: + .patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, +-@@ -335,6 +338,7 @@ static const struct ath10k_hw_params ath ++@@ -344,6 +347,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA99X0_2_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca99x0 hw2.0", +@@ -156,7 +156,7 @@ v13: + .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .otp_exe_param = 0x00000700, +-@@ -375,6 +379,7 @@ static const struct ath10k_hw_params ath ++@@ -385,6 +389,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA9984_1_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca9984/qca9994 hw1.0", +@@ -164,7 +164,7 @@ v13: + .patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, +-@@ -422,6 +427,7 @@ static const struct ath10k_hw_params ath ++@@ -433,6 +438,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA9888_2_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca9888 hw2.0", +@@ -172,7 +172,7 @@ v13: + .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, +-@@ -2904,6 +2910,10 @@ int ath10k_core_start(struct ath10k *ar, ++@@ -3127,6 +3133,10 @@ int ath10k_core_start(struct ath10k *ar, + goto err_hif_stop; + } + +@@ -183,7 +183,7 @@ v13: + return 0; + + err_hif_stop: +-@@ -3162,9 +3172,18 @@ static void ath10k_core_register_work(st ++@@ -3385,9 +3395,18 @@ static void ath10k_core_register_work(st + goto err_spectral_destroy; + } + +@@ -202,7 +202,7 @@ v13: + err_spectral_destroy: + ath10k_spectral_destroy(ar); + err_debug_destroy: +-@@ -3210,6 +3229,8 @@ void ath10k_core_unregister(struct ath10 ++@@ -3433,6 +3452,8 @@ void ath10k_core_unregister(struct ath10 + if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) + return; + +@@ -221,7 +221,7 @@ v13: + + #include "htt.h" + #include "htc.h" +-@@ -1237,6 +1238,13 @@ struct ath10k { ++@@ -1256,6 +1257,13 @@ struct ath10k { + } testmode; + + struct { +@@ -467,7 +467,7 @@ v13: + static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { + --- a/drivers/net/wireless/ath/ath10k/wmi.c + +++ b/drivers/net/wireless/ath/ath10k/wmi.c +-@@ -7468,6 +7468,49 @@ ath10k_wmi_op_gen_peer_set_param(struct ++@@ -7472,6 +7472,49 @@ ath10k_wmi_op_gen_peer_set_param(struct + return skb; + } + +@@ -517,7 +517,7 @@ v13: + static struct sk_buff * + ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, + enum wmi_sta_ps_mode psmode) +-@@ -9156,6 +9199,9 @@ static const struct wmi_ops wmi_ops = { ++@@ -9160,6 +9203,9 @@ static const struct wmi_ops wmi_ops = { + .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, + .gen_echo = ath10k_wmi_op_gen_echo, +@@ -527,7 +527,7 @@ v13: + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +-@@ -9226,6 +9272,8 @@ static const struct wmi_ops wmi_10_1_ops ++@@ -9230,6 +9276,8 @@ static const struct wmi_ops wmi_10_1_ops + .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, + .gen_echo = ath10k_wmi_op_gen_echo, +@@ -536,7 +536,7 @@ v13: + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +-@@ -9298,6 +9346,8 @@ static const struct wmi_ops wmi_10_2_ops ++@@ -9302,6 +9350,8 @@ static const struct wmi_ops wmi_10_2_ops + .gen_delba_send = ath10k_wmi_op_gen_delba_send, + .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, +@@ -545,7 +545,7 @@ v13: + /* .gen_pdev_enable_adaptive_cca not implemented */ + }; + +-@@ -9369,6 +9419,8 @@ static const struct wmi_ops wmi_10_2_4_o ++@@ -9373,6 +9423,8 @@ static const struct wmi_ops wmi_10_2_4_o + ath10k_wmi_op_gen_pdev_enable_adaptive_cca, + .get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype, + .gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing, +@@ -554,7 +554,7 @@ v13: + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +-@@ -9450,6 +9502,8 @@ static const struct wmi_ops wmi_10_4_ops ++@@ -9454,6 +9506,8 @@ static const struct wmi_ops wmi_10_4_ops + .gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info, + .gen_echo = ath10k_wmi_op_gen_echo, + .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config, +@@ -565,7 +565,7 @@ v13: + int ath10k_wmi_attach(struct ath10k *ar) + --- a/drivers/net/wireless/ath/ath10k/wmi.h + +++ b/drivers/net/wireless/ath/ath10k/wmi.h +-@@ -3027,6 +3027,41 @@ enum wmi_10_4_feature_mask { ++@@ -3030,6 +3030,41 @@ enum wmi_10_4_feature_mask { + + }; + +diff --git a/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch +similarity index 92% +rename from package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch +rename to package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch +index 975d9a88a8..da31ad578a 100644 +--- a/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch ++++ b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch +@@ -16,9 +16,9 @@ Signed-off-by: Mathias Kresin + + --- a/drivers/net/wireless/ath/ath10k/core.h + +++ b/drivers/net/wireless/ath/ath10k/core.h +-@@ -1290,6 +1290,10 @@ struct ath10k { +- bool coex_support; +- int coex_gpio_pin; ++@@ -1312,6 +1312,10 @@ struct ath10k { ++ s32 tx_power_2g_limit; ++ s32 tx_power_5g_limit; + + +#ifdef CPTCFG_MAC80211_LEDS + + const char *led_default_trigger; +@@ -42,7 +42,7 @@ Signed-off-by: Mathias Kresin + if (ret) + --- a/drivers/net/wireless/ath/ath10k/mac.c + +++ b/drivers/net/wireless/ath/ath10k/mac.c +-@@ -10075,7 +10075,7 @@ int ath10k_mac_register(struct ath10k *a ++@@ -10212,7 +10212,7 @@ int ath10k_mac_register(struct ath10k *a + ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; + + #ifdef CPTCFG_MAC80211_LEDS +diff --git a/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch b/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch +similarity index 93% +rename from package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch +rename to package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch +index a149ce1216..a45addf119 100644 +--- a/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch ++++ b/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch +@@ -28,7 +28,7 @@ Forwarded: no + + --- a/drivers/net/wireless/ath/ath10k/mac.c + +++ b/drivers/net/wireless/ath/ath10k/mac.c +-@@ -1006,6 +1006,40 @@ static inline int ath10k_vdev_setup_sync ++@@ -1021,6 +1021,40 @@ static inline int ath10k_vdev_setup_sync + return ar->last_wmi_vdev_start_status; + } + +@@ -69,7 +69,7 @@ Forwarded: no + static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) + { + struct cfg80211_chan_def *chandef = NULL; +-@@ -1038,7 +1072,8 @@ static int ath10k_monitor_vdev_start(str ++@@ -1053,7 +1087,8 @@ static int ath10k_monitor_vdev_start(str + arg.channel.min_power = 0; + arg.channel.max_power = channel->max_power * 2; + arg.channel.max_reg_power = channel->max_reg_power * 2; +@@ -79,7 +79,7 @@ Forwarded: no + + reinit_completion(&ar->vdev_setup_done); + reinit_completion(&ar->vdev_delete_done); +-@@ -1484,7 +1519,8 @@ static int ath10k_vdev_start_restart(str ++@@ -1499,7 +1534,8 @@ static int ath10k_vdev_start_restart(str + arg.channel.min_power = 0; + arg.channel.max_power = chandef->chan->max_power * 2; + arg.channel.max_reg_power = chandef->chan->max_reg_power * 2; +@@ -89,7 +89,7 @@ Forwarded: no + + if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { + arg.ssid = arvif->u.ap.ssid; +-@@ -3255,7 +3291,8 @@ static int ath10k_update_channel_list(st ++@@ -3427,7 +3463,8 @@ static int ath10k_update_channel_list(st + ch->min_power = 0; + ch->max_power = channel->max_power * 2; + ch->max_reg_power = channel->max_reg_power * 2; +diff --git a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch +new file mode 100644 +index 0000000000..e14329cce8 +--- /dev/null ++++ b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch +@@ -0,0 +1,37 @@ ++From 22fb5991a44c78ff18ec0082dc90c809356eb893 Mon Sep 17 00:00:00 2001 ++From: Ansuel Smith ++Date: Sun, 27 Sep 2020 19:23:35 +0200 ++Subject: [PATCH 1/2] ath10k: Try to get mac-address from dts ++ ++Most of embedded device that have the ath10k wifi integrated store the ++mac-address in nvmem partitions. Try to fetch the mac-address using the ++standard 'of_get_mac_address' than in all the check also try to fetch the ++address using the nvmem api searching for a defined 'mac-address' cell. ++Mac-address defined in the dts have priority than any other address found. ++ ++Tested-on: QCA9984 hw1.0 PCI 10.4 ++ ++Signed-off-by: Ansuel Smith ++--- ++ drivers/net/wireless/ath/ath10k/core.c | 10 ++++++++++ ++ 1 file changed, 10 insertions(+) ++ ++--- a/drivers/net/wireless/ath/ath10k/core.c +++++ b/drivers/net/wireless/ath/ath10k/core.c ++@@ -8,6 +8,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ #include ++ #include ++@@ -3303,6 +3304,8 @@ static int ath10k_core_probe_fw(struct a ++ ++ device_get_mac_address(ar->dev, ar->mac_addr, sizeof(ar->mac_addr)); ++ +++ of_get_mac_address(ar->dev->of_node, ar->mac_addr); +++ ++ ret = ath10k_core_init_firmware_features(ar); ++ if (ret) { ++ ath10k_err(ar, "fatal problem with firmware features: %d\n", +diff --git a/package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch b/package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch +new file mode 100644 +index 0000000000..2f560c70a0 +--- /dev/null ++++ b/package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch +@@ -0,0 +1,64 @@ ++--- a/drivers/net/wireless/ath/ath10k/htt.h +++++ b/drivers/net/wireless/ath/ath10k/htt.h ++@@ -235,7 +235,11 @@ enum htt_rx_ring_flags { ++ }; ++ ++ #define HTT_RX_RING_SIZE_MIN 128 +++#ifndef CONFIG_ATH10K_SMALLBUFFERS ++ #define HTT_RX_RING_SIZE_MAX 2048 +++#else +++#define HTT_RX_RING_SIZE_MAX 512 +++#endif ++ #define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX ++ #define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1) ++ #define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1) ++--- a/drivers/net/wireless/ath/ath10k/pci.c +++++ b/drivers/net/wireless/ath/ath10k/pci.c ++@@ -131,7 +131,11 @@ static const struct ce_attr pci_host_ce_ ++ .flags = CE_ATTR_FLAGS, ++ .src_nentries = 0, ++ .src_sz_max = 2048, +++#ifndef CONFIG_ATH10K_SMALLBUFFERS ++ .dest_nentries = 512, +++#else +++ .dest_nentries = 128, +++#endif ++ .recv_cb = ath10k_pci_htt_htc_rx_cb, ++ }, ++ ++@@ -140,7 +144,11 @@ static const struct ce_attr pci_host_ce_ ++ .flags = CE_ATTR_FLAGS, ++ .src_nentries = 0, ++ .src_sz_max = 2048, +++#ifndef CONFIG_ATH10K_SMALLBUFFERS ++ .dest_nentries = 128, +++#else +++ .dest_nentries = 64, +++#endif ++ .recv_cb = ath10k_pci_htc_rx_cb, ++ }, ++ ++@@ -167,7 +175,11 @@ static const struct ce_attr pci_host_ce_ ++ .flags = CE_ATTR_FLAGS, ++ .src_nentries = 0, ++ .src_sz_max = 512, +++#ifndef CONFIG_ATH10K_SMALLBUFFERS ++ .dest_nentries = 512, +++#else +++ .dest_nentries = 128, +++#endif ++ .recv_cb = ath10k_pci_htt_rx_cb, ++ }, ++ ++@@ -192,7 +204,11 @@ static const struct ce_attr pci_host_ce_ ++ .flags = CE_ATTR_FLAGS, ++ .src_nentries = 0, ++ .src_sz_max = 2048, +++#ifndef CONFIG_ATH10K_SMALLBUFFERS ++ .dest_nentries = 128, +++#else +++ .dest_nentries = 96, +++#endif ++ .recv_cb = ath10k_pci_pktlog_rx_cb, ++ }, ++ +diff --git a/package/kernel/mac80211/patches/ath/201-ath5k-WAR-for-AR71xx-PCI-bug.patch b/package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch +similarity index 100% +rename from package/kernel/mac80211/patches/ath/201-ath5k-WAR-for-AR71xx-PCI-bug.patch +rename to package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch +diff --git a/package/kernel/mac80211/patches/ath/411-ath5k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch +similarity index 89% +rename from package/kernel/mac80211/patches/ath/411-ath5k_allow_adhoc_and_ap.patch +rename to package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch +index 9dbe047c9a..35ed6ea555 100644 +--- a/package/kernel/mac80211/patches/ath/411-ath5k_allow_adhoc_and_ap.patch ++++ b/package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch +@@ -18,7 +18,7 @@ + goto end; + --- a/drivers/net/wireless/ath/ath5k/base.c + +++ b/drivers/net/wireless/ath/ath5k/base.c +-@@ -1964,7 +1964,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) ++@@ -1963,7 +1963,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) + } + + if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + +@@ -27,7 +27,7 @@ + ah->opmode == NL80211_IFTYPE_MESH_POINT) { + u64 tsf = ath5k_hw_get_tsf64(ah); + u32 tsftu = TSF_TO_TU(tsf); +-@@ -2050,7 +2050,7 @@ ath5k_beacon_update_timers(struct ath5k_ ++@@ -2049,7 +2049,7 @@ ath5k_beacon_update_timers(struct ath5k_ + + intval = ah->bintval & AR5K_BEACON_PERIOD; + if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +@@ -36,7 +36,7 @@ + intval /= ATH_BCBUF; /* staggered multi-bss beacons */ + if (intval < 15) + ATH5K_WARN(ah, "intval %u is too low, min 15\n", +-@@ -2516,6 +2516,7 @@ static const struct ieee80211_iface_limi ++@@ -2515,6 +2515,7 @@ static const struct ieee80211_iface_limi + BIT(NL80211_IFTYPE_MESH_POINT) | + #endif + BIT(NL80211_IFTYPE_AP) }, +diff --git a/package/kernel/mac80211/patches/ath/420-ath5k_disable_fast_cc.patch b/package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch +similarity index 100% +rename from package/kernel/mac80211/patches/ath/420-ath5k_disable_fast_cc.patch +rename to package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch +diff --git a/package/kernel/mac80211/patches/ath/430-add_ath5k_platform.patch b/package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch +similarity index 100% +rename from package/kernel/mac80211/patches/ath/430-add_ath5k_platform.patch +rename to package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch +diff --git a/package/kernel/mac80211/patches/ath/432-ath5k_add_pciids.patch b/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch +similarity index 100% +rename from package/kernel/mac80211/patches/ath/432-ath5k_add_pciids.patch +rename to package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch +diff --git a/package/kernel/mac80211/patches/ath/440-ath5k_channel_bw_debugfs.patch b/package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch +similarity index 98% +rename from package/kernel/mac80211/patches/ath/440-ath5k_channel_bw_debugfs.patch +rename to package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch +index 92fb90c165..a63f0c881b 100644 +--- a/package/kernel/mac80211/patches/ath/440-ath5k_channel_bw_debugfs.patch ++++ b/package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch +@@ -130,7 +130,7 @@ drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++ + /* Antenna Control */ + --- a/drivers/net/wireless/ath/ath5k/base.c + +++ b/drivers/net/wireless/ath/ath5k/base.c +-@@ -466,6 +466,9 @@ ath5k_chan_set(struct ath5k_hw *ah, stru ++@@ -465,6 +465,9 @@ ath5k_chan_set(struct ath5k_hw *ah, stru + return -EINVAL; + } + +diff --git a/package/kernel/mac80211/patches/ath9k/040-ath9k-support-DT-ieee80211-freq-limit-property-to-li.patch b/package/kernel/mac80211/patches/ath9k/040-ath9k-support-DT-ieee80211-freq-limit-property-to-li.patch +new file mode 100644 +index 0000000000..7d44681760 +--- /dev/null ++++ b/package/kernel/mac80211/patches/ath9k/040-ath9k-support-DT-ieee80211-freq-limit-property-to-li.patch +@@ -0,0 +1,28 @@ ++From 03469e79fee9e8e908dae3bd1a80bcd9a66f2a88 Mon Sep 17 00:00:00 2001 ++From: Christian Lamparter ++Date: Mon, 11 Oct 2021 18:18:00 +0300 ++Subject: ath9k: support DT ieee80211-freq-limit property to limit channels ++ ++The common DT property can be used to limit the available channels ++but ath9k has to manually call wiphy_read_of_freq_limits(). ++ ++I would have put this into ath9k_of_init(). But it didn't work there. ++The reason is that in ath9k_of_init() the channels and bands are not yet ++registered in the wiphy struct. So there isn't any channel to flag as ++disabled. ++ ++Signed-off-by: Christian Lamparter ++Signed-off-by: Kalle Valo ++Link: https://lore.kernel.org/r/20211009212847.1781986-1-chunkeey@gmail.com ++--- ++--- a/drivers/net/wireless/ath/ath9k/init.c +++++ b/drivers/net/wireless/ath/ath9k/init.c ++@@ -1038,6 +1038,8 @@ int ath9k_init_device(u16 devid, struct ++ ARRAY_SIZE(ath9k_tpt_blink)); ++ #endif ++ +++ wiphy_read_of_freq_limits(hw->wiphy); +++ ++ /* Register with mac80211 */ ++ error = ieee80211_register_hw(hw); ++ if (error) +diff --git a/package/kernel/mac80211/patches/ath/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch +similarity index 89% +rename from package/kernel/mac80211/patches/ath/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch +rename to package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch +index d648a3a3e5..3a0171d4a2 100644 +--- a/package/kernel/mac80211/patches/ath/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch ++++ b/package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch +@@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau + + --- a/drivers/net/wireless/ath/ath9k/hw.c + +++ b/drivers/net/wireless/ath/ath9k/hw.c +-@@ -1435,8 +1435,12 @@ static bool ath9k_hw_set_reset(struct at ++@@ -1434,8 +1434,12 @@ static bool ath9k_hw_set_reset(struct at + if (!AR_SREV_9100(ah)) + REG_WRITE(ah, AR_RC, 0); + +diff --git a/package/kernel/mac80211/patches/ath/351-ath9k_hw-issue-external-reset-for-QCA955x.patch b/package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch +similarity index 95% +rename from package/kernel/mac80211/patches/ath/351-ath9k_hw-issue-external-reset-for-QCA955x.patch +rename to package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch +index 5f265b84c2..53b7ba08bc 100644 +--- a/package/kernel/mac80211/patches/ath/351-ath9k_hw-issue-external-reset-for-QCA955x.patch ++++ b/package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch +@@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau + + --- a/drivers/net/wireless/ath/ath9k/hw.c + +++ b/drivers/net/wireless/ath/ath9k/hw.c +-@@ -1312,39 +1312,56 @@ void ath9k_hw_get_delta_slope_vals(struc ++@@ -1311,39 +1311,56 @@ void ath9k_hw_get_delta_slope_vals(struc + *coef_exponent = coef_exp - 16; + } + +@@ -94,7 +94,7 @@ Signed-off-by: Felix Fietkau + return true; + } + +-@@ -1397,24 +1414,24 @@ static bool ath9k_hw_set_reset(struct at ++@@ -1396,24 +1413,24 @@ static bool ath9k_hw_set_reset(struct at + rst_flags |= AR_RTC_RC_MAC_COLD; + } + +diff --git a/package/kernel/mac80211/patches/ath/354-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch +similarity index 100% +rename from package/kernel/mac80211/patches/ath/354-ath9k-force-rx_clear-when-disabling-rx.patch +rename to package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch +diff --git a/package/kernel/mac80211/patches/ath/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch +similarity index 89% +rename from package/kernel/mac80211/patches/ath/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch +rename to package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch +index 406d03e2fe..385eea0116 100644 +--- a/package/kernel/mac80211/patches/ath/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch ++++ b/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch +@@ -8,7 +8,7 @@ This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. + + --- a/drivers/net/wireless/ath/ath9k/hw.c + +++ b/drivers/net/wireless/ath/ath9k/hw.c +-@@ -2979,7 +2979,8 @@ void ath9k_hw_apply_txpower(struct ath_h ++@@ -2977,7 +2977,8 @@ void ath9k_hw_apply_txpower(struct ath_h + { + struct ath_regulatory *reg = ath9k_hw_regulatory(ah); + struct ieee80211_channel *channel; +@@ -18,7 +18,7 @@ This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. + u16 ctl = NO_CTL; + + if (!chan) +-@@ -2991,9 +2992,14 @@ void ath9k_hw_apply_txpower(struct ath_h ++@@ -2989,9 +2990,14 @@ void ath9k_hw_apply_txpower(struct ath_h + channel = chan->chan; + chan_pwr = min_t(int, channel->max_power * 2, MAX_COMBINED_POWER); + new_pwr = min_t(int, chan_pwr, reg->power_limit); +diff --git a/package/kernel/mac80211/patches/ath/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch b/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch +similarity index 91% +rename from package/kernel/mac80211/patches/ath/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch +rename to package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch +index 12cbd27e1a..0c3edc1260 100644 +--- a/package/kernel/mac80211/patches/ath/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch ++++ b/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch +@@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau + + --- a/drivers/net/wireless/ath/ath9k/hw.c + +++ b/drivers/net/wireless/ath/ath9k/hw.c +-@@ -2998,6 +2998,10 @@ void ath9k_hw_apply_txpower(struct ath_h ++@@ -2996,6 +2996,10 @@ void ath9k_hw_apply_txpower(struct ath_h + if (ant_gain > max_gain) + ant_reduction = ant_gain - max_gain; + +diff --git a/package/kernel/mac80211/patches/ath/401-ath9k_blink_default.patch b/package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch +similarity index 88% +rename from package/kernel/mac80211/patches/ath/401-ath9k_blink_default.patch +rename to package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch +index 3eb57bb1cf..7405e594fe 100644 +--- a/package/kernel/mac80211/patches/ath/401-ath9k_blink_default.patch ++++ b/package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ath/ath9k/init.c + +++ b/drivers/net/wireless/ath/ath9k/init.c +-@@ -48,7 +48,7 @@ int ath9k_modparam_nohwcrypt; ++@@ -47,7 +47,7 @@ int ath9k_modparam_nohwcrypt; + module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444); + MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); + +diff --git a/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch +similarity index 73% +rename from package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch +rename to package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch +index 17dd8f6597..b355e8372f 100644 +--- a/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch ++++ b/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch +@@ -1,10 +1,10 @@ + --- a/drivers/net/wireless/ath/ath9k/init.c + +++ b/drivers/net/wireless/ath/ath9k/init.c +-@@ -830,6 +830,7 @@ static const struct ieee80211_iface_limi ++@@ -826,6 +826,7 @@ static const struct ieee80211_iface_limi + BIT(NL80211_IFTYPE_AP) }, + { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) }, + + { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, + }; + +- #ifdef CPTCFG_WIRELESS_WDS ++ #ifdef CPTCFG_ATH9K_CHANNEL_CONTEXT +diff --git a/package/kernel/mac80211/patches/ath/450-ath9k-enabled-MFP-capability-unconditionally.patch b/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch +similarity index 90% +rename from package/kernel/mac80211/patches/ath/450-ath9k-enabled-MFP-capability-unconditionally.patch +rename to package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch +index ea94b52385..284c88ff49 100644 +--- a/package/kernel/mac80211/patches/ath/450-ath9k-enabled-MFP-capability-unconditionally.patch ++++ b/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch +@@ -14,7 +14,7 @@ Signed-off-by: David Bauer + + --- a/drivers/net/wireless/ath/ath9k/init.c + +++ b/drivers/net/wireless/ath/ath9k/init.c +-@@ -927,6 +927,7 @@ static void ath9k_set_hw_capab(struct at ++@@ -907,6 +907,7 @@ static void ath9k_set_hw_capab(struct at + ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING); + ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); + ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); +@@ -22,7 +22,7 @@ Signed-off-by: David Bauer + + if (ath9k_ps_enable) + ieee80211_hw_set(hw, SUPPORTS_PS); +-@@ -939,9 +940,6 @@ static void ath9k_set_hw_capab(struct at ++@@ -919,9 +920,6 @@ static void ath9k_set_hw_capab(struct at + IEEE80211_RADIOTAP_MCS_HAVE_STBC; + } + +diff --git a/package/kernel/mac80211/patches/ath/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch +similarity index 100% +rename from package/kernel/mac80211/patches/ath/500-ath9k_eeprom_debugfs.patch +rename to package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch +diff --git a/package/kernel/mac80211/patches/ath/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch +similarity index 91% +rename from package/kernel/mac80211/patches/ath/501-ath9k_ahb_init.patch +rename to package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch +index b9c784eb25..6ab7972b55 100644 +--- a/package/kernel/mac80211/patches/ath/501-ath9k_ahb_init.patch ++++ b/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ath/ath9k/init.c + +++ b/drivers/net/wireless/ath/ath9k/init.c +-@@ -1143,25 +1143,25 @@ static int __init ath9k_init(void) ++@@ -1122,25 +1122,25 @@ static int __init ath9k_init(void) + { + int error; + +diff --git a/package/kernel/mac80211/patches/ath/510-ath9k_intr_mitigation_tweak.patch b/package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch +similarity index 87% +rename from package/kernel/mac80211/patches/ath/510-ath9k_intr_mitigation_tweak.patch +rename to package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch +index 75b48b480e..fda050a8f2 100644 +--- a/package/kernel/mac80211/patches/ath/510-ath9k_intr_mitigation_tweak.patch ++++ b/package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ath/ath9k/hw.c + +++ b/drivers/net/wireless/ath/ath9k/hw.c +-@@ -403,13 +403,8 @@ static void ath9k_hw_init_config(struct ++@@ -402,13 +402,8 @@ static void ath9k_hw_init_config(struct + + ah->config.rx_intr_mitigation = true; + +diff --git a/package/kernel/mac80211/patches/ath/511-ath9k_reduce_rxbuf.patch b/package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch +similarity index 100% +rename from package/kernel/mac80211/patches/ath/511-ath9k_reduce_rxbuf.patch +rename to package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch +diff --git a/package/kernel/mac80211/patches/ath/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch +similarity index 100% +rename from package/kernel/mac80211/patches/ath/512-ath9k_channelbw_debugfs.patch +rename to package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch +diff --git a/package/kernel/mac80211/patches/ath/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch +similarity index 93% +rename from package/kernel/mac80211/patches/ath/513-ath9k_add_pci_ids.patch +rename to package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch +index 113c35625f..a085e3a1fb 100644 +--- a/package/kernel/mac80211/patches/ath/513-ath9k_add_pci_ids.patch ++++ b/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ath/ath9k/hw.c + +++ b/drivers/net/wireless/ath/ath9k/hw.c +-@@ -663,6 +663,7 @@ int ath9k_hw_init(struct ath_hw *ah) ++@@ -662,6 +662,7 @@ int ath9k_hw_init(struct ath_hw *ah) + + /* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */ + switch (ah->hw_version.devid) { +diff --git a/package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch +similarity index 96% +rename from package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch +rename to package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch +index 5fd5c73a2f..c161237827 100644 +--- a/package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch ++++ b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ath/ath9k/ath9k.h + +++ b/drivers/net/wireless/ath/ath9k/ath9k.h +-@@ -844,6 +844,9 @@ static inline int ath9k_dump_btcoex(stru ++@@ -843,6 +843,9 @@ static inline int ath9k_dump_btcoex(stru + #ifdef CPTCFG_MAC80211_LEDS + void ath_init_leds(struct ath_softc *sc); + void ath_deinit_leds(struct ath_softc *sc); +@@ -10,7 +10,7 @@ + #else + static inline void ath_init_leds(struct ath_softc *sc) + { +-@@ -980,6 +983,13 @@ void ath_ant_comb_scan(struct ath_softc ++@@ -979,6 +982,13 @@ void ath_ant_comb_scan(struct ath_softc + + #define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */ + +@@ -24,7 +24,7 @@ + struct ath_softc { + struct ieee80211_hw *hw; + struct device *dev; +-@@ -1033,9 +1043,8 @@ struct ath_softc { ++@@ -1032,9 +1042,8 @@ struct ath_softc { + spinlock_t chan_lock; + + #ifdef CPTCFG_MAC80211_LEDS +@@ -181,7 +181,7 @@ + + --- a/drivers/net/wireless/ath/ath9k/init.c + +++ b/drivers/net/wireless/ath/ath9k/init.c +-@@ -1055,7 +1055,7 @@ int ath9k_init_device(u16 devid, struct ++@@ -1032,7 +1032,7 @@ int ath9k_init_device(u16 devid, struct + + #ifdef CPTCFG_MAC80211_LEDS + /* must be initialized before ieee80211_register_hw */ +diff --git a/package/kernel/mac80211/patches/ath/531-ath9k_extra_platform_leds.patch b/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch +similarity index 100% +rename from package/kernel/mac80211/patches/ath/531-ath9k_extra_platform_leds.patch +rename to package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch +diff --git a/package/kernel/mac80211/patches/ath/540-ath9k_reduce_ani_interval.patch b/package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch +similarity index 100% +rename from package/kernel/mac80211/patches/ath/540-ath9k_reduce_ani_interval.patch +rename to package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch +diff --git a/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch +similarity index 93% +rename from package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch +rename to package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch +index 0e75b86cbf..5b64f560fd 100644 +--- a/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch ++++ b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch +@@ -94,7 +94,7 @@ + struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, + --- a/drivers/net/wireless/ath/ath9k/hw.c + +++ b/drivers/net/wireless/ath/ath9k/hw.c +-@@ -1882,6 +1882,20 @@ u32 ath9k_hw_get_tsf_offset(struct times ++@@ -1881,6 +1881,20 @@ u32 ath9k_hw_get_tsf_offset(struct times + } + EXPORT_SYMBOL(ath9k_hw_get_tsf_offset); + +@@ -115,7 +115,7 @@ + int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, + struct ath9k_hw_cal_data *caldata, bool fastcc) + { +-@@ -2090,6 +2104,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st ++@@ -2089,6 +2103,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st + ar9003_hw_disable_phy_restart(ah); + + ath9k_hw_apply_gpio_override(ah); +@@ -125,9 +125,9 @@ + REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); + --- a/drivers/net/wireless/ath/ath9k/main.c + +++ b/drivers/net/wireless/ath/ath9k/main.c +-@@ -536,6 +536,11 @@ irqreturn_t ath_isr(int irq, void *dev) +- if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) ++@@ -538,6 +538,11 @@ irqreturn_t ath_isr(int irq, void *dev) + return IRQ_HANDLED; ++ } + + + if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) { + + status |= ATH9K_INT_FATAL; +diff --git a/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch +similarity index 94% +rename from package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch +rename to package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch +index 0d938a3730..ef4e659870 100644 +--- a/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch ++++ b/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch +@@ -55,7 +55,7 @@ + ops->spectral_scan_config = ar9003_hw_spectral_scan_config; + --- a/drivers/net/wireless/ath/ath9k/init.c + +++ b/drivers/net/wireless/ath/ath9k/init.c +-@@ -818,7 +818,8 @@ static void ath9k_init_txpower_limits(st ++@@ -814,7 +814,8 @@ static void ath9k_init_txpower_limits(st + if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) + ath9k_init_band_txpower(sc, NL80211_BAND_5GHZ); + +@@ -65,7 +65,7 @@ + } + + static const struct ieee80211_iface_limit if_limits[] = { +-@@ -1015,6 +1016,18 @@ static void ath9k_set_hw_capab(struct at ++@@ -992,6 +993,18 @@ static void ath9k_set_hw_capab(struct at + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); + } + +@@ -84,9 +84,9 @@ + int ath9k_init_device(u16 devid, struct ath_softc *sc, + const struct ath_bus_ops *bus_ops) + { +-@@ -1060,6 +1073,8 @@ int ath9k_init_device(u16 devid, struct +- ARRAY_SIZE(ath9k_tpt_blink)); +- #endif ++@@ -1039,6 +1052,8 @@ int ath9k_init_device(u16 devid, struct ++ ++ wiphy_read_of_freq_limits(hw->wiphy); + + + ath_get_initial_entropy(sc); + + +@@ -110,7 +110,7 @@ + static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) + --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c + +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c +-@@ -1349,9 +1349,30 @@ void ar5008_hw_init_rate_txpower(struct ++@@ -1340,9 +1340,30 @@ void ar5008_hw_init_rate_txpower(struct + } + } + +@@ -141,7 +141,7 @@ + static const u32 ar5416_cca_regs[6] = { + AR_PHY_CCA, + AR_PHY_CH1_CCA, +-@@ -1366,6 +1387,8 @@ int ar5008_hw_attach_phy_ops(struct ath_ ++@@ -1357,6 +1378,8 @@ int ar5008_hw_attach_phy_ops(struct ath_ + if (ret) + return ret; + +diff --git a/package/kernel/mac80211/patches/ath/544-ath9k-ar933x-usb-hang-workaround.patch b/package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch +similarity index 84% +rename from package/kernel/mac80211/patches/ath/544-ath9k-ar933x-usb-hang-workaround.patch +rename to package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch +index 2d2b837072..23a81864fa 100644 +--- a/package/kernel/mac80211/patches/ath/544-ath9k-ar933x-usb-hang-workaround.patch ++++ b/package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ath/ath9k/hw.c + +++ b/drivers/net/wireless/ath/ath9k/hw.c +-@@ -248,6 +248,19 @@ void ath9k_hw_get_channel_centers(struct ++@@ -247,6 +247,19 @@ void ath9k_hw_get_channel_centers(struct + centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT); + } + +@@ -20,7 +20,7 @@ + /******************/ + /* Chip Revisions */ + /******************/ +-@@ -1455,6 +1468,9 @@ static bool ath9k_hw_set_reset(struct at ++@@ -1454,6 +1467,9 @@ static bool ath9k_hw_set_reset(struct at + udelay(50); + } + +@@ -30,7 +30,7 @@ + return true; + } + +-@@ -1554,6 +1570,9 @@ static bool ath9k_hw_chip_reset(struct a ++@@ -1553,6 +1569,9 @@ static bool ath9k_hw_chip_reset(struct a + ar9003_hw_internal_regulator_apply(ah); + ath9k_hw_init_pll(ah, chan); + +@@ -40,7 +40,7 @@ + return true; + } + +-@@ -1860,8 +1879,14 @@ static int ath9k_hw_do_fastcc(struct ath ++@@ -1859,8 +1878,14 @@ static int ath9k_hw_do_fastcc(struct ath + if (AR_SREV_9271(ah)) + ar9002_hw_load_ani_reg(ah, chan); + +@@ -55,7 +55,7 @@ + return -EINVAL; + } + +-@@ -2115,6 +2140,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st ++@@ -2114,6 +2139,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st + ath9k_hw_set_radar_params(ah); + } + +diff --git a/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch b/package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch +similarity index 98% +rename from package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch +rename to package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch +index 466767adb9..854bb3659a 100644 +--- a/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch ++++ b/package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c + +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c +-@@ -978,55 +978,6 @@ static bool ar5008_hw_ani_control_new(st ++@@ -969,55 +969,6 @@ static bool ar5008_hw_ani_control_new(st + * on == 0 means more noise imm + */ + u32 on = param ? 1 : 0; +diff --git a/package/kernel/mac80211/patches/ath/547-ath9k_led_defstate_fix.patch b/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch +similarity index 100% +rename from package/kernel/mac80211/patches/ath/547-ath9k_led_defstate_fix.patch +rename to package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch +diff --git a/package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch +similarity index 98% +rename from package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch +rename to package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch +index 88198a4562..78206d2860 100644 +--- a/package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch ++++ b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch +@@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau + + #include "common.h" + #include "debug.h" +-@@ -990,6 +991,14 @@ struct ath_led { ++@@ -989,6 +990,14 @@ struct ath_led { + struct led_classdev cdev; + }; + +@@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau + struct ath_softc { + struct ieee80211_hw *hw; + struct device *dev; +-@@ -1045,6 +1054,9 @@ struct ath_softc { ++@@ -1044,6 +1053,9 @@ struct ath_softc { + #ifdef CPTCFG_MAC80211_LEDS + const char *led_default_trigger; + struct list_head leds; +diff --git a/package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch +similarity index 98% +rename from package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch +rename to package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch +index 83076b8ae4..716e09f351 100644 +--- a/package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch ++++ b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch +@@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau + --- + --- a/drivers/net/wireless/ath/ath9k/ath9k.h + +++ b/drivers/net/wireless/ath/ath9k/ath9k.h +-@@ -1056,6 +1056,7 @@ struct ath_softc { ++@@ -1055,6 +1055,7 @@ struct ath_softc { + struct list_head leds; + #ifdef CONFIG_GPIOLIB + struct ath9k_gpio_chip *gpiochip; +diff --git a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch b/package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch +similarity index 98% +rename from package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch +rename to package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch +index c98222781d..cb6374feb0 100644 +--- a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch ++++ b/package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch +@@ -339,7 +339,7 @@ + + static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop); +-@@ -657,6 +658,7 @@ void ath_reset_work(struct work_struct * ++@@ -659,6 +660,7 @@ void ath_reset_work(struct work_struct * + static int ath9k_start(struct ieee80211_hw *hw) + { + struct ath_softc *sc = hw->priv; +@@ -347,7 +347,7 @@ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan; +-@@ -735,6 +737,11 @@ static int ath9k_start(struct ieee80211_ ++@@ -737,6 +739,11 @@ static int ath9k_start(struct ieee80211_ + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + } + +@@ -371,7 +371,7 @@ + + --- a/local-symbols + +++ b/local-symbols +-@@ -112,6 +112,7 @@ ATH9K_WOW= ++@@ -103,6 +103,7 @@ ATH9K_WOW= + ATH9K_RFKILL= + ATH9K_CHANNEL_CONTEXT= + ATH9K_PCOEM= +diff --git a/package/kernel/mac80211/patches/ath/552-ahb_of.patch b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch +similarity index 93% +rename from package/kernel/mac80211/patches/ath/552-ahb_of.patch +rename to package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch +index 8fd6e4409b..7ce8bc5b82 100644 +--- a/package/kernel/mac80211/patches/ath/552-ahb_of.patch ++++ b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch +@@ -16,7 +16,7 @@ + + static const struct platform_device_id ath9k_platform_id_table[] = { + { +-@@ -69,6 +77,242 @@ static const struct ath_bus_ops ath_ahb_ ++@@ -69,6 +77,236 @@ static const struct ath_bus_ops ath_ahb_ + .eeprom_read = ath_ahb_eeprom_read, + }; + +@@ -218,12 +218,6 @@ + + else + + pdata->led_pin = -1; + + +-+ if (of_property_read_bool(pdev->dev.of_node, "qca,disable-2ghz")) +-+ pdata->disable_2ghz = true; +-+ +-+ if (of_property_read_bool(pdev->dev.of_node, "qca,disable-5ghz")) +-+ pdata->disable_5ghz = true; +-+ + + if (of_property_read_bool(pdev->dev.of_node, "qca,tx-gain-buffalo")) + + pdata->tx_gain_buffalo = true; + + +@@ -259,7 +253,7 @@ + static int ath_ahb_probe(struct platform_device *pdev) + { + void __iomem *mem; +-@@ -80,6 +324,17 @@ static int ath_ahb_probe(struct platform ++@@ -80,6 +318,17 @@ static int ath_ahb_probe(struct platform + int ret = 0; + struct ath_hw *ah; + char hw_name[64]; +@@ -277,7 +271,7 @@ + + if (!dev_get_platdata(&pdev->dev)) { + dev_err(&pdev->dev, "no platform data specified\n"); +-@@ -122,13 +377,16 @@ static int ath_ahb_probe(struct platform ++@@ -122,13 +371,16 @@ static int ath_ahb_probe(struct platform + sc->mem = mem; + sc->irq = irq; + +@@ -295,7 +289,7 @@ + if (ret) { + dev_err(&pdev->dev, "failed to initialize device\n"); + goto err_irq; +-@@ -159,6 +417,9 @@ static int ath_ahb_remove(struct platfor ++@@ -159,6 +411,9 @@ static int ath_ahb_remove(struct platfor + free_irq(sc->irq, sc); + ieee80211_free_hw(sc->hw); + } +@@ -305,7 +299,7 @@ + + return 0; + } +-@@ -168,6 +429,9 @@ static struct platform_driver ath_ahb_dr ++@@ -168,6 +423,9 @@ static struct platform_driver ath_ahb_dr + .remove = ath_ahb_remove, + .driver = { + .name = "ath9k", +@@ -325,7 +319,7 @@ + + #include "common.h" + #include "debug.h" +-@@ -1012,6 +1013,9 @@ struct ath_softc { ++@@ -1011,6 +1012,9 @@ struct ath_softc { + struct ath_hw *sc_ah; + void __iomem *mem; + int irq; +diff --git a/package/kernel/mac80211/patches/ath/553-ath9k_of_gpio_mask.patch b/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch +similarity index 80% +rename from package/kernel/mac80211/patches/ath/553-ath9k_of_gpio_mask.patch +rename to package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch +index 8e0041e3ef..80e0dc4c5e 100644 +--- a/package/kernel/mac80211/patches/ath/553-ath9k_of_gpio_mask.patch ++++ b/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ath/ath9k/init.c + +++ b/drivers/net/wireless/ath/ath9k/init.c +-@@ -654,6 +654,12 @@ static int ath9k_of_init(struct ath_soft ++@@ -644,6 +644,12 @@ static int ath9k_of_init(struct ath_soft + return 0; + } + +@@ -13,7 +13,7 @@ + static int ath9k_init_softc(u16 devid, struct ath_softc *sc, + const struct ath_bus_ops *bus_ops) + { +-@@ -757,6 +763,9 @@ static int ath9k_init_softc(u16 devid, s ++@@ -747,6 +753,9 @@ static int ath9k_init_softc(u16 devid, s + if (ret) + goto err_hw; + +diff --git a/package/kernel/mac80211/patches/ath9k/600-v5.16-ath9k-fetch-calibration-data-via-nvmem-subsystem.patch b/package/kernel/mac80211/patches/ath9k/600-v5.16-ath9k-fetch-calibration-data-via-nvmem-subsystem.patch +new file mode 100644 +index 0000000000..a250d2318e +--- /dev/null ++++ b/package/kernel/mac80211/patches/ath9k/600-v5.16-ath9k-fetch-calibration-data-via-nvmem-subsystem.patch +@@ -0,0 +1,154 @@ ++From dab16ef495dbb3cabb355b6c80f0771a4a25e35d Mon Sep 17 00:00:00 2001 ++From: Christian Lamparter ++Date: Fri, 20 Aug 2021 22:44:52 +0200 ++Subject: [PATCH] ath9k: fetch calibration data via nvmem subsystem ++ ++On most embedded ath9k devices (like range extenders, ++routers, accesspoints, ...) the calibration data is ++stored in a MTD partitions named "ART", or "caldata"/ ++"calibration". ++ ++Ever since commit ++4b361cfa8624 ("mtd: core: add OTP nvmem provider support") ++all MTD partitions are all automatically available through ++the nvmem subsystem. This allows drivers like ath9k to read ++the necessary data without needing any userspace helpers ++that would do this extraction. ++ ++Signed-off-by: Christian Lamparter ++--- ++ ++includes: ++ ++From 57671351379b2051cfb07fc14e0bead9916a0880 Mon Sep 17 00:00:00 2001 ++From: Dan Carpenter ++Date: Mon, 11 Oct 2021 18:18:01 +0300 ++Subject: ath9k: fix an IS_ERR() vs NULL check ++ ++The devm_kmemdup() function doesn't return error pointers, it returns ++NULL on error. ++ ++Fixes: eb3a97a69be8 ("ath9k: fetch calibration data via nvmem subsystem") ++Signed-off-by: Dan Carpenter ++Signed-off-by: Kalle Valo ++Link: https://lore.kernel.org/r/20211011123533.GA15188@kili ++ ++--- ++ ++--- a/drivers/net/wireless/ath/ath9k/eeprom.c +++++ b/drivers/net/wireless/ath/ath9k/eeprom.c ++@@ -135,13 +135,23 @@ static bool ath9k_hw_nvram_read_firmware ++ offset, data); ++ } ++ +++static bool ath9k_hw_nvram_read_nvmem(struct ath_hw *ah, off_t offset, +++ u16 *data) +++{ +++ return ath9k_hw_nvram_read_array(ah->nvmem_blob, +++ ah->nvmem_blob_len / sizeof(u16), +++ offset, data); +++} +++ ++ bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data) ++ { ++ struct ath_common *common = ath9k_hw_common(ah); ++ struct ath9k_platform_data *pdata = ah->dev->platform_data; ++ bool ret; ++ ++- if (ah->eeprom_blob) +++ if (ah->nvmem_blob) +++ ret = ath9k_hw_nvram_read_nvmem(ah, off, data); +++ else if (ah->eeprom_blob) ++ ret = ath9k_hw_nvram_read_firmware(ah->eeprom_blob, off, data); ++ else if (pdata && !pdata->use_eeprom) ++ ret = ath9k_hw_nvram_read_pdata(pdata, off, data); ++--- a/drivers/net/wireless/ath/ath9k/hw.h +++++ b/drivers/net/wireless/ath/ath9k/hw.h ++@@ -988,6 +988,8 @@ struct ath_hw { ++ bool disable_5ghz; ++ ++ const struct firmware *eeprom_blob; +++ u16 *nvmem_blob; /* devres managed */ +++ size_t nvmem_blob_len; ++ ++ struct ath_dynack dynack; ++ ++--- a/drivers/net/wireless/ath/ath9k/init.c +++++ b/drivers/net/wireless/ath/ath9k/init.c ++@@ -22,6 +22,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ #include ++ #include ++@@ -568,6 +569,57 @@ static void ath9k_eeprom_release(struct ++ release_firmware(sc->sc_ah->eeprom_blob); ++ } ++ +++static int ath9k_nvmem_request_eeprom(struct ath_softc *sc) +++{ +++ struct ath_hw *ah = sc->sc_ah; +++ struct nvmem_cell *cell; +++ void *buf; +++ size_t len; +++ int err; +++ +++ cell = devm_nvmem_cell_get(sc->dev, "calibration"); +++ if (IS_ERR(cell)) { +++ err = PTR_ERR(cell); +++ +++ /* nvmem cell might not be defined, or the nvmem +++ * subsystem isn't included. In this case, follow +++ * the established "just return 0;" convention of +++ * ath9k_init_platform to say: +++ * "All good. Nothing to see here. Please go on." +++ */ +++ if (err == -ENOENT || err == -EOPNOTSUPP) +++ return 0; +++ +++ return err; +++ } +++ +++ buf = nvmem_cell_read(cell, &len); +++ if (IS_ERR(buf)) +++ return PTR_ERR(buf); +++ +++ /* run basic sanity checks on the returned nvram cell length. +++ * That length has to be a multiple of a "u16" (i.e.: & 1). +++ * Furthermore, it has to be more than "let's say" 512 bytes +++ * but less than the maximum of AR9300_EEPROM_SIZE (16kb). +++ */ +++ if (((len & 1) == 1) || (len < 512) || (len >= AR9300_EEPROM_SIZE)) { +++ kfree(buf); +++ return -EINVAL; +++ } +++ +++ /* devres manages the calibration values release on shutdown */ +++ ah->nvmem_blob = (u16 *)devm_kmemdup(sc->dev, buf, len, GFP_KERNEL); +++ kfree(buf); +++ if (!ah->nvmem_blob) +++ return -ENOMEM; +++ +++ ah->nvmem_blob_len = len; +++ ah->ah_flags &= ~AH_USE_EEPROM; +++ ah->ah_flags |= AH_NO_EEP_SWAP; +++ +++ return 0; +++} +++ ++ static int ath9k_init_platform(struct ath_softc *sc) ++ { ++ struct ath9k_platform_data *pdata = sc->dev->platform_data; ++@@ -710,6 +762,10 @@ static int ath9k_init_softc(u16 devid, s ++ if (ret) ++ return ret; ++ +++ ret = ath9k_nvmem_request_eeprom(sc); +++ if (ret) +++ return ret; +++ ++ if (ath9k_led_active_high != -1) ++ ah->config.led_active_high = ath9k_led_active_high == 1; ++ +diff --git a/package/kernel/mac80211/patches/ath9k/601-v5.16-ath9k-owl-loader-fetch-pci-init-values-through-nvmem.patch b/package/kernel/mac80211/patches/ath9k/601-v5.16-ath9k-owl-loader-fetch-pci-init-values-through-nvmem.patch +new file mode 100644 +index 0000000000..62c561d619 +--- /dev/null ++++ b/package/kernel/mac80211/patches/ath9k/601-v5.16-ath9k-owl-loader-fetch-pci-init-values-through-nvmem.patch +@@ -0,0 +1,181 @@ ++From 9bf31835f11aa3c4fe5a9c1f7462c199c5d8e7ca Mon Sep 17 00:00:00 2001 ++From: Christian Lamparter ++Date: Sat, 21 Aug 2021 00:22:39 +0200 ++Subject: [PATCH] ath9k: owl-loader: fetch pci init values through nvmem ++ ++extends the owl loader to fetch important pci initialization ++values - which are stored together with the calibration data - ++through the nvmem subsystem. ++ ++This allows for much faster WIFI/ath9k initializations on devices ++that do not require to perform any post-processing (like XOR'ing/ ++reversal or unpacking) since no userspace helper is required. ++ ++Signed-off-by: Christian Lamparter ++--- ++ .../wireless/ath/ath9k/ath9k_pci_owl_loader.c | 105 +++++++++++++----- ++ 1 file changed, 76 insertions(+), 29 deletions(-) ++ ++--- a/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c +++++ b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c ++@@ -19,9 +19,14 @@ ++ #include ++ #include ++ #include +++#include +++#include ++ ++ struct owl_ctx { +++ struct pci_dev *pdev; ++ struct completion eeprom_load; +++ struct work_struct work; +++ struct nvmem_cell *cell; ++ }; ++ ++ #define EEPROM_FILENAME_LEN 100 ++@@ -42,6 +47,12 @@ static int ath9k_pci_fixup(struct pci_de ++ u32 bar0; ++ bool swap_needed = false; ++ +++ /* also note that we are doing *u16 operations on the file */ +++ if (cal_len > 4096 || cal_len < 0x200 || (cal_len & 1) == 1) { +++ dev_err(&pdev->dev, "eeprom has an invalid size.\n"); +++ return -EINVAL; +++ } +++ ++ if (*cal_data != AR5416_EEPROM_MAGIC) { ++ if (*cal_data != swab16(AR5416_EEPROM_MAGIC)) { ++ dev_err(&pdev->dev, "invalid calibration data\n"); ++@@ -99,38 +110,31 @@ static int ath9k_pci_fixup(struct pci_de ++ return 0; ++ } ++ ++-static void owl_fw_cb(const struct firmware *fw, void *context) +++static void owl_rescan(struct pci_dev *pdev) ++ { ++- struct pci_dev *pdev = (struct pci_dev *)context; ++- struct owl_ctx *ctx = (struct owl_ctx *)pci_get_drvdata(pdev); ++- struct pci_bus *bus; ++- ++- complete(&ctx->eeprom_load); ++- ++- if (!fw) { ++- dev_err(&pdev->dev, "no eeprom data received.\n"); ++- goto release; ++- } ++- ++- /* also note that we are doing *u16 operations on the file */ ++- if (fw->size > 4096 || fw->size < 0x200 || (fw->size & 1) == 1) { ++- dev_err(&pdev->dev, "eeprom file has an invalid size.\n"); ++- goto release; ++- } ++- ++- if (ath9k_pci_fixup(pdev, (const u16 *)fw->data, fw->size)) ++- goto release; +++ struct pci_bus *bus = pdev->bus; ++ ++ pci_lock_rescan_remove(); ++- bus = pdev->bus; ++ pci_stop_and_remove_bus_device(pdev); ++ /* the device should come back with the proper ++ * ProductId. But we have to initiate a rescan. ++ */ ++ pci_rescan_bus(bus); ++ pci_unlock_rescan_remove(); +++} +++ +++static void owl_fw_cb(const struct firmware *fw, void *context) +++{ +++ struct owl_ctx *ctx = (struct owl_ctx *)context; +++ +++ complete(&ctx->eeprom_load); ++ ++-release: +++ if (fw) { +++ ath9k_pci_fixup(ctx->pdev, (const u16 *)fw->data, fw->size); +++ owl_rescan(ctx->pdev); +++ } else { +++ dev_err(&ctx->pdev->dev, "no eeprom data received.\n"); +++ } ++ release_firmware(fw); ++ } ++ ++@@ -152,6 +156,43 @@ static const char *owl_get_eeprom_name(s ++ return eeprom_name; ++ } ++ +++static void owl_nvmem_work(struct work_struct *work) +++{ +++ struct owl_ctx *ctx = container_of(work, struct owl_ctx, work); +++ void *buf; +++ size_t len; +++ +++ complete(&ctx->eeprom_load); +++ +++ buf = nvmem_cell_read(ctx->cell, &len); +++ if (!IS_ERR(buf)) { +++ ath9k_pci_fixup(ctx->pdev, buf, len); +++ kfree(buf); +++ owl_rescan(ctx->pdev); +++ } else { +++ dev_err(&ctx->pdev->dev, "no nvmem data received.\n"); +++ } +++} +++ +++static int owl_nvmem_probe(struct owl_ctx *ctx) +++{ +++ int err; +++ +++ ctx->cell = devm_nvmem_cell_get(&ctx->pdev->dev, "calibration"); +++ if (IS_ERR(ctx->cell)) { +++ err = PTR_ERR(ctx->cell); +++ if (err == -ENOENT || err == -EOPNOTSUPP) +++ return 1; /* not present, try firmware_request */ +++ +++ return err; +++ } +++ +++ INIT_WORK(&ctx->work, owl_nvmem_work); +++ schedule_work(&ctx->work); +++ +++ return 0; +++} +++ ++ static int owl_probe(struct pci_dev *pdev, ++ const struct pci_device_id *id) ++ { ++@@ -164,21 +205,27 @@ static int owl_probe(struct pci_dev *pde ++ ++ pcim_pin_device(pdev); ++ ++- eeprom_name = owl_get_eeprom_name(pdev); ++- if (!eeprom_name) { ++- dev_err(&pdev->dev, "no eeprom filename found.\n"); ++- return -ENODEV; ++- } ++- ++ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); ++ if (!ctx) ++ return -ENOMEM; ++ ++ init_completion(&ctx->eeprom_load); +++ ctx->pdev = pdev; ++ ++ pci_set_drvdata(pdev, ctx); +++ +++ err = owl_nvmem_probe(ctx); +++ if (err <= 0) +++ return err; +++ +++ eeprom_name = owl_get_eeprom_name(pdev); +++ if (!eeprom_name) { +++ dev_err(&pdev->dev, "no eeprom filename found.\n"); +++ return -ENODEV; +++ } +++ ++ err = request_firmware_nowait(THIS_MODULE, true, eeprom_name, ++- &pdev->dev, GFP_KERNEL, pdev, owl_fw_cb); +++ &pdev->dev, GFP_KERNEL, ctx, owl_fw_cb); ++ if (err) ++ dev_err(&pdev->dev, "failed to request caldata (%d).\n", err); ++ +diff --git a/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch b/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch +index 52ae7a8eba..5dc04ecc88 100644 +--- a/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch ++++ b/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch +@@ -42,7 +42,7 @@ + + if (wl->radio_enabled != phy->radio_on) { + if (wl->radio_enabled) { +-@@ -5176,6 +5173,47 @@ static int b43_op_get_survey(struct ieee ++@@ -5175,6 +5172,47 @@ static int b43_op_get_survey(struct ieee + return 0; + } + +@@ -90,7 +90,7 @@ + static const struct ieee80211_ops b43_hw_ops = { + .tx = b43_op_tx, + .conf_tx = b43_op_conf_tx, +-@@ -5197,6 +5235,8 @@ static const struct ieee80211_ops b43_hw ++@@ -5196,6 +5234,8 @@ static const struct ieee80211_ops b43_hw + .sw_scan_complete = b43_op_sw_scan_complete_notifier, + .get_survey = b43_op_get_survey, + .rfkill_poll = b43_rfkill_poll, +@@ -99,7 +99,7 @@ + }; + + /* Hard-reset the chip. Do not call this directly. +-@@ -5498,6 +5538,8 @@ static int b43_one_core_attach(struct b4 ++@@ -5497,6 +5537,8 @@ static int b43_one_core_attach(struct b4 + if (!wldev) + goto out; + +@@ -108,7 +108,7 @@ + wldev->use_pio = b43_modparam_pio; + wldev->dev = dev; + wldev->wl = wl; +-@@ -5592,6 +5634,9 @@ static struct b43_wl *b43_wireless_init( ++@@ -5588,6 +5630,9 @@ static struct b43_wl *b43_wireless_init( + + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + +diff --git a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch +index c9730e29fd..aa890ce0f3 100644 +--- a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch ++++ b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch +@@ -13,15 +13,15 @@ Signed-off-by: RafaÅ‚ MiÅ‚ecki + + --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c + +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +-@@ -431,6 +431,7 @@ struct brcmf_fw { ++@@ -429,6 +429,7 @@ struct brcmf_fw { + struct brcmf_fw_request *req; + u32 curpos; + void (*done)(struct device *dev, int err, struct brcmf_fw_request *req); + + struct completion *completion; + }; + +- static void brcmf_fw_request_done(const struct firmware *fw, void *ctx); +-@@ -638,6 +639,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 + kfree(fwctx); + } + +-@@ -662,6 +665,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)); +-@@ -678,6 +683,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 + + init_completion(&completion); + + fwctx->completion = &completion; + +- ret = request_firmware_nowait(THIS_MODULE, true, first->path, +- fwctx->dev, GFP_KERNEL, fwctx, +-@@ -685,6 +693,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); + +diff --git a/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch +index 774656f1fd..88465f256b 100644 +--- a/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch ++++ b/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch +@@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell + + --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c + +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +-@@ -2961,6 +2961,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 + */ +diff --git a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch +index 9658bda1c1..835c870a65 100644 +--- a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch ++++ b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch +@@ -12,9 +12,9 @@ Signed-off-by: RafaÅ‚ MiÅ‚ecki + + --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c + +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +-@@ -12,6 +12,36 @@ +- #include "common.h" +- #include "of.h" ++@@ -58,6 +58,36 @@ static int brcmf_of_get_country_codes(st ++ return 0; ++ } + + +/* TODO: FIXME: Use DT */ + +static void brcmf_of_probe_cc(struct device *dev, +@@ -49,12 +49,12 @@ Signed-off-by: RafaÅ‚ MiÅ‚ecki + void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + struct brcmf_mp_device *settings) + { +-@@ -43,6 +73,8 @@ void brcmf_of_probe(struct device *dev, ++@@ -90,6 +120,8 @@ void brcmf_of_probe(struct device *dev, + of_node_put(root); + } + + + brcmf_of_probe_cc(dev, settings); + + +- if (!np || bus_type != BRCMF_BUSTYPE_SDIO || +- !of_device_is_compatible(np, "brcm,bcm4329-fmac")) ++ if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) + return; ++ +diff --git a/package/kernel/mac80211/patches/brcm/998-survey.patch b/package/kernel/mac80211/patches/brcm/998-survey.patch +index 25a12c783e..a5efc08015 100644 +--- a/package/kernel/mac80211/patches/brcm/998-survey.patch ++++ b/package/kernel/mac80211/patches/brcm/998-survey.patch +@@ -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) + { +-@@ -3008,6 +3065,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; +-@@ -3032,6 +3090,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()); +-@@ -5518,6 +5587,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, +@@ -100,7 +100,7 @@ + .add_key = brcmf_cfg80211_add_key, + --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c + +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +-@@ -1356,6 +1356,8 @@ int brcmf_attach(struct device *dev) ++@@ -1361,6 +1361,8 @@ int brcmf_attach(struct device *dev) + + /* Link to bus module */ + drvr->hdrlen = 0; +@@ -109,7 +109,7 @@ + + /* Attach and link in the protocol */ + ret = brcmf_proto_attach(drvr); +-@@ -1438,6 +1440,12 @@ void brcmf_detach(struct device *dev) ++@@ -1443,6 +1445,12 @@ void brcmf_detach(struct device *dev) + if (drvr == NULL) + return; + +diff --git a/package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch b/package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch +index 8fa465a7e1..aa26c8cb2a 100644 +--- a/package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch ++++ b/package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch +@@ -1,6 +1,6 @@ + --- a/compat/main.c + +++ b/compat/main.c +-@@ -20,31 +20,6 @@ MODULE_LICENSE("GPL"); ++@@ -19,31 +19,6 @@ MODULE_LICENSE("GPL"); + #error "You need a CPTCFG_VERSION" + #endif + +diff --git a/package/kernel/mac80211/patches/build/004-kconfig_backport_fix.patch b/package/kernel/mac80211/patches/build/004-kconfig_backport_fix.patch +deleted file mode 100644 +index 2c9572ec93..0000000000 +--- a/package/kernel/mac80211/patches/build/004-kconfig_backport_fix.patch ++++ /dev/null +@@ -1,28 +0,0 @@ +---- a/backport-include/linux/kconfig.h +-+++ b/backport-include/linux/kconfig.h +-@@ -5,6 +5,8 @@ +- #include_next +- #endif +- +-+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) +-+ +- #ifndef __ARG_PLACEHOLDER_1 +- #define __ARG_PLACEHOLDER_1 0, +- #define config_enabled(cfg) _config_enabled(cfg) +-@@ -16,6 +18,7 @@ +- * 3.1 - 3.3 had a broken version of this, so undef +- * (they didn't have __ARG_PLACEHOLDER_1) +- */ +-+ +- #undef IS_ENABLED +- #define IS_ENABLED(option) \ +- (config_enabled(option) || config_enabled(option##_MODULE)) +-@@ -31,6 +34,8 @@ +- #undef IS_BUILTIN +- #define IS_BUILTIN(option) config_enabled(option) +- +-+#endif +-+ +- #ifndef IS_REACHABLE +- /* +- * IS_REACHABLE(CONFIG_FOO) evaluates to 1 if the currently compiled +diff --git a/package/kernel/mac80211/patches/build/010-disable_rfkill.patch b/package/kernel/mac80211/patches/build/010-disable_rfkill.patch +deleted file mode 100644 +index d5253063ce..0000000000 +--- a/package/kernel/mac80211/patches/build/010-disable_rfkill.patch ++++ /dev/null +@@ -1,15 +0,0 @@ +---- a/backport-include/linux/rfkill.h +-+++ b/backport-include/linux/rfkill.h +-@@ -2,6 +2,12 @@ +- #define __COMPAT_RFKILL_H +- #include +- +-+#undef CONFIG_RFKILL +-+#undef CONFIG_RFKILL_FULL +-+#undef CONFIG_RFKILL_LEDS +-+#undef CONFIG_RFKILL_MODULE +-+#undef CONFIG_RFKILL_FULL_MODULE +-+ +- #if LINUX_VERSION_IS_GEQ(3,10,0) +- #include_next +- #else +diff --git a/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch +index ff2ce2071f..3967d73fad 100644 +--- a/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch ++++ b/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch +@@ -1,9 +1,9 @@ + --- a/local-symbols + +++ b/local-symbols +-@@ -437,43 +437,6 @@ USB_SIERRA_NET= +- USB_VL600= ++@@ -421,43 +421,6 @@ USB_VL600= + USB_NET_CH9200= + USB_NET_AQC111= ++ USB_RTL8153_ECM= + -SSB_POSSIBLE= + -SSB= + -SSB_SPROM= +@@ -192,10 +192,10 @@ + select BRCMUTIL + --- a/Kconfig.local + +++ b/Kconfig.local +-@@ -1315,117 +1315,6 @@ config BACKPORTED_USB_NET_CH9200 +- config BACKPORTED_USB_NET_AQC111 ++@@ -1267,117 +1267,6 @@ config BACKPORTED_USB_NET_AQC111 ++ config BACKPORTED_USB_RTL8153_ECM + tristate +- default USB_NET_AQC111 ++ default USB_RTL8153_ECM + -config BACKPORTED_SSB_POSSIBLE + - tristate + - default SSB_POSSIBLE +diff --git a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch +index d358cfe367..140949f9a8 100644 +--- a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch ++++ b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/marvell/mwl8k.c + +++ b/drivers/net/wireless/marvell/mwl8k.c +-@@ -5695,6 +5695,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") ++@@ -5699,6 +5699,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") + MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); + + static const struct pci_device_id mwl8k_pci_id_table[] = { +diff --git a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch +index a35cf1875a..96b1ce77e9 100644 +--- a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch ++++ b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/marvell/mwl8k.c + +++ b/drivers/net/wireless/marvell/mwl8k.c +-@@ -6280,6 +6280,8 @@ static int mwl8k_probe(struct pci_dev *p ++@@ -6285,6 +6285,8 @@ static int mwl8k_probe(struct pci_dev *p + + priv->running_bsses = 0; + +@@ -9,7 +9,7 @@ + return rc; + + err_stop_firmware: +-@@ -6313,8 +6315,6 @@ static void mwl8k_remove(struct pci_dev ++@@ -6318,8 +6320,6 @@ static void mwl8k_remove(struct pci_dev + return; + priv = hw->priv; + +diff --git a/package/kernel/mac80211/patches/rt2x00/002-rt2x00-define-RF5592-in-init_eeprom-routine.patch b/package/kernel/mac80211/patches/rt2x00/002-rt2x00-define-RF5592-in-init_eeprom-routine.patch +index a50a195285..96eeb37dc6 100644 +--- a/package/kernel/mac80211/patches/rt2x00/002-rt2x00-define-RF5592-in-init_eeprom-routine.patch ++++ b/package/kernel/mac80211/patches/rt2x00/002-rt2x00-define-RF5592-in-init_eeprom-routine.patch +@@ -40,7 +40,7 @@ Signed-off-by: Tomislav Požega + + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -9416,6 +9416,8 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -9435,6 +9435,8 @@ static int rt2800_init_eeprom(struct rt2 + rf = RF3853; + else if (rt2x00_rt(rt2x00dev, RT5350)) + rf = RF5350; +diff --git a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch +index e74d9a9aa0..5bc55cc90b 100644 +--- a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch ++++ b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch +@@ -1,6 +1,6 @@ + --- a/local-symbols + +++ b/local-symbols +-@@ -332,6 +332,7 @@ RT2X00_LIB_FIRMWARE= ++@@ -315,6 +315,7 @@ RT2X00_LIB_FIRMWARE= + RT2X00_LIB_CRYPTO= + RT2X00_LIB_LEDS= + RT2X00_LIB_DEBUGFS= +@@ -105,7 +105,7 @@ + .drv_init_registers = rt2800mmio_init_registers, + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +-@@ -694,6 +694,7 @@ enum rt2x00_capability_flags { ++@@ -703,6 +703,7 @@ enum rt2x00_capability_flags { + REQUIRE_HT_TX_DESC, + REQUIRE_PS_AUTOWAKE, + REQUIRE_DELAYED_RFKILL, +@@ -113,7 +113,7 @@ + + /* + * Capabilities +-@@ -970,6 +971,11 @@ struct rt2x00_dev { ++@@ -980,6 +981,11 @@ struct rt2x00_dev { + const struct firmware *fw; + + /* +@@ -127,7 +127,7 @@ + DECLARE_KFIFO_PTR(txstatus_fifo, u32); + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1406,6 +1406,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de ++@@ -1401,6 +1401,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de + INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); + INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); + +@@ -138,7 +138,7 @@ + /* + * Let the driver probe the device to detect the capabilities. + */ +-@@ -1549,6 +1553,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ ++@@ -1541,6 +1545,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ + * Free the driver data. + */ + kfree(rt2x00dev->drv_data); +diff --git a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch +index 6a8e594d5e..ffee2189d2 100644 +--- a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch ++++ b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch +@@ -12,7 +12,7 @@ + #endif /* _RT2X00_PLATFORM_H */ + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1012,6 +1012,22 @@ static int rt2x00lib_probe_hw_modes(stru ++@@ -1007,6 +1007,22 @@ static int rt2x00lib_probe_hw_modes(stru + unsigned int num_rates; + unsigned int i; + +@@ -37,7 +37,7 @@ + num_rates += 4; + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +-@@ -399,6 +399,7 @@ struct hw_mode_spec { ++@@ -408,6 +408,7 @@ struct hw_mode_spec { + unsigned int supported_bands; + #define SUPPORT_BAND_2GHZ 0x00000001 + #define SUPPORT_BAND_5GHZ 0x00000002 +diff --git a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch +index b5b2c61037..37553bb80a 100644 +--- a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch ++++ b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch +@@ -1,19 +1,18 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -990,8 +990,13 @@ static void rt2x00lib_rate(struct ieee80 ++@@ -989,6 +989,12 @@ static void rt2x00lib_rate(struct ieee80 + + void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) + { + + struct rt2x00_platform_data *pdata; +- const char *mac_addr; +- +++ + + pdata = rt2x00dev->dev->platform_data; + + if (pdata && pdata->mac_address) + + ether_addr_copy(eeprom_mac_addr, pdata->mac_address); + + +- mac_addr = of_get_mac_address(rt2x00dev->dev->of_node); +- if (!IS_ERR(mac_addr)) +- ether_addr_copy(eeprom_mac_addr, mac_addr); ++ of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr); ++ ++ if (!is_valid_ether_addr(eeprom_mac_addr)) { + --- a/include/linux/rt2x00_platform.h + +++ b/include/linux/rt2x00_platform.h + @@ -14,6 +14,7 @@ +diff --git a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch +index ff8b2c947b..6211809c0a 100644 +--- a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch ++++ b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1016,6 +1016,16 @@ static int rt2x00lib_probe_hw_modes(stru ++@@ -1012,6 +1012,16 @@ static int rt2x00lib_probe_hw_modes(stru + struct ieee80211_rate *rates; + unsigned int num_rates; + unsigned int i; +diff --git a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch +index 039c6f6afc..d78b76d7f5 100644 +--- a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch ++++ b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch +@@ -8,7 +8,7 @@ + + #include "rt2x00.h" + #include "rt2800lib.h" +-@@ -9530,6 +9531,17 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -9549,6 +9550,17 @@ static int rt2800_init_eeprom(struct rt2 + rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); + rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); + +diff --git a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch +index 88d6dd559b..0da9356e0c 100644 +--- a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch ++++ b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1344,7 +1344,7 @@ static inline void rt2x00lib_set_if_comb ++@@ -1340,7 +1340,7 @@ static inline void rt2x00lib_set_if_comb + */ + if_limit = &rt2x00dev->if_limits_ap; + if_limit->max = rt2x00dev->ops->max_ap_intf; +diff --git a/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch b/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch +index fca1fb2cd4..6e6564f870 100644 +--- a/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch ++++ b/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch +@@ -11,7 +11,7 @@ Tested-by: Christoph Krapp + + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1129,6 +1129,19 @@ static void rt2x00lib_remove_hw(struct r ++@@ -1125,6 +1125,19 @@ static void rt2x00lib_remove_hw(struct r + kfree(rt2x00dev->spec.channels_info); + } + +@@ -31,7 +31,7 @@ Tested-by: Christoph Krapp + static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) + { + struct hw_mode_spec *spec = &rt2x00dev->spec; +-@@ -1210,6 +1223,10 @@ static int rt2x00lib_probe_hw(struct rt2 ++@@ -1206,6 +1219,10 @@ static int rt2x00lib_probe_hw(struct rt2 + + #undef RT2X00_TASKLET_INIT + +diff --git a/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch +index 20452cd8a7..8814c02532 100644 +--- a/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch ++++ b/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch +@@ -30,7 +30,7 @@ Signed-off-by: Tomislav Po=C5=BEega + * EEPROM LNA + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -4356,6 +4356,45 @@ static void rt2800_config_channel(struct ++@@ -4369,6 +4369,45 @@ static void rt2800_config_channel(struct + rt2800_iq_calibrate(rt2x00dev, rf->channel); + } + +@@ -76,7 +76,7 @@ Signed-off-by: Tomislav Po=C5=BEega + bbp = rt2800_bbp_read(rt2x00dev, 4); + rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf)); + rt2800_bbp_write(rt2x00dev, 4, bbp); +-@@ -9559,7 +9598,8 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -9578,7 +9617,8 @@ static int rt2800_init_eeprom(struct rt2 + */ + eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1); + +@@ -86,7 +86,7 @@ Signed-off-by: Tomislav Po=C5=BEega + if (rt2x00_get_field16(eeprom, + EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352)) + __set_bit(CAPABILITY_EXTERNAL_PA_TX0, +-@@ -9570,6 +9610,18 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -9589,6 +9629,18 @@ static int rt2800_init_eeprom(struct rt2 + &rt2x00dev->cap_flags); + } + +diff --git a/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch b/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch +index 6be847478e..b798dcc6d8 100644 +--- a/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch ++++ b/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -8419,6 +8419,56 @@ static void rt2800_init_rfcsr_5592(struc ++@@ -8438,6 +8438,56 @@ static void rt2800_init_rfcsr_5592(struc + rt2800_led_open_drain_enable(rt2x00dev); + } + +@@ -57,7 +57,7 @@ + static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, + bool set_bw, bool is_ht40) + { +-@@ -9026,6 +9076,7 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -9045,6 +9095,7 @@ static void rt2800_init_rfcsr_6352(struc + rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); + rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); + +diff --git a/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch b/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch +index 3ed0ff7ef5..cf21c39a6c 100644 +--- a/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch ++++ b/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -8469,6 +8469,155 @@ static void rt2800_rf_self_txdc_cal(stru ++@@ -8488,6 +8488,155 @@ static void rt2800_rf_self_txdc_cal(stru + rt2x00_info(rt2x00dev, "RF Tx self calibration end\n"); + } + +@@ -156,7 +156,7 @@ + static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, + bool set_bw, bool is_ht40) + { +-@@ -9076,6 +9225,7 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -9095,6 +9244,7 @@ static void rt2800_init_rfcsr_6352(struc + rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); + rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); + +diff --git a/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch b/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch +index 77be986d18..1f8684b0bf 100644 +--- a/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch ++++ b/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -8618,6 +8618,70 @@ static void rt2800_r_calibration(struct ++@@ -8637,6 +8637,70 @@ static void rt2800_r_calibration(struct + rt2800_register_write(rt2x00dev, PWR_PIN_CFG, MAC_PWR_PIN_CFG); + } + +@@ -71,7 +71,7 @@ + static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, + bool set_bw, bool is_ht40) + { +-@@ -9227,6 +9291,7 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -9246,6 +9310,7 @@ static void rt2800_init_rfcsr_6352(struc + + rt2800_r_calibration(rt2x00dev); + rt2800_rf_self_txdc_cal(rt2x00dev); +diff --git a/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch b/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch +index 7352ad036c..98f2e245ce 100644 +--- a/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch ++++ b/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -8682,6 +8682,384 @@ static void rt2800_rxdcoc_calibration(st ++@@ -8701,6 +8701,384 @@ static void rt2800_rxdcoc_calibration(st + rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2); + } + +@@ -385,7 +385,7 @@ + static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, + bool set_bw, bool is_ht40) + { +-@@ -9294,6 +9672,7 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -9313,6 +9691,7 @@ static void rt2800_init_rfcsr_6352(struc + rt2800_rxdcoc_calibration(rt2x00dev); + rt2800_bw_filter_calibration(rt2x00dev, true); + rt2800_bw_filter_calibration(rt2x00dev, false); +diff --git a/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch b/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch +index fe0961baa7..6a685f80ab 100644 +--- a/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch ++++ b/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -9060,6 +9060,943 @@ restore_value: ++@@ -9079,6 +9079,943 @@ restore_value: + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl); + } + +@@ -944,7 +944,7 @@ + static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, + bool set_bw, bool is_ht40) + { +-@@ -9672,6 +10609,7 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -9691,6 +10628,7 @@ static void rt2800_init_rfcsr_6352(struc + rt2800_rxdcoc_calibration(rt2x00dev); + rt2800_bw_filter_calibration(rt2x00dev, true); + rt2800_bw_filter_calibration(rt2x00dev, false); +diff --git a/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch b/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch +index 3de00b2267..40b20ec594 100644 +--- a/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch ++++ b/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch +@@ -14,7 +14,7 @@ + */ + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -3685,14 +3685,16 @@ static void rt2800_config_channel_rf7620 ++@@ -3698,14 +3698,16 @@ static void rt2800_config_channel_rf7620 + rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4); + rt2800_rfcsr_write(rt2x00dev, 19, rfcsr); + +@@ -39,7 +39,7 @@ + + rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620, +-@@ -3726,18 +3728,23 @@ static void rt2800_config_channel_rf7620 ++@@ -3739,18 +3741,23 @@ static void rt2800_config_channel_rf7620 + rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20); + } + +@@ -73,7 +73,7 @@ + + if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) { + if (conf_is_ht40(conf)) { +-@@ -3837,25 +3844,29 @@ static void rt2800_config_alc(struct rt2 ++@@ -3850,25 +3857,29 @@ static void rt2800_config_alc(struct rt2 + if (i == 10000) + rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n"); + +@@ -121,7 +121,7 @@ + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl); + + rt2800_vco_calibration(rt2x00dev); +-@@ -5887,18 +5898,33 @@ static int rt2800_init_registers(struct ++@@ -5906,18 +5917,33 @@ static int rt2800_init_registers(struct + } else if (rt2x00_rt(rt2x00dev, RT5350)) { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); + } else if (rt2x00_rt(rt2x00dev, RT6352)) { +@@ -167,7 +167,7 @@ + reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1); + rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0); + rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); +-@@ -7042,14 +7068,16 @@ static void rt2800_init_bbp_6352(struct ++@@ -7061,14 +7087,16 @@ static void rt2800_init_bbp_6352(struct + rt2800_bbp_write(rt2x00dev, 188, 0x00); + rt2800_bbp_write(rt2x00dev, 189, 0x00); + +@@ -192,7 +192,7 @@ + + /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */ + rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00); +-@@ -10388,31 +10416,36 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -10407,31 +10435,36 @@ static void rt2800_init_rfcsr_6352(struc + rt2800_rfcsr_write(rt2x00dev, 42, 0x5B); + rt2800_rfcsr_write(rt2x00dev, 43, 0x00); + +@@ -254,7 +254,7 @@ + + /* Initialize RF channel register to default value */ + rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03); +-@@ -10478,63 +10511,71 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -10497,63 +10530,71 @@ static void rt2800_init_rfcsr_6352(struc + + rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5); + +@@ -383,7 +383,7 @@ + + /* Initialize RF DC calibration register to default value */ + rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47); +-@@ -10597,12 +10638,17 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -10616,12 +10657,17 @@ static void rt2800_init_rfcsr_6352(struc + rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00); + rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00); + +diff --git a/package/kernel/mac80211/patches/rt2x00/992-rt2x00-save-survey-for-every-channel-visited.patch b/package/kernel/mac80211/patches/rt2x00/992-rt2x00-save-survey-for-every-channel-visited.patch +deleted file mode 100644 +index 31a7baeee7..0000000000 +--- a/package/kernel/mac80211/patches/rt2x00/992-rt2x00-save-survey-for-every-channel-visited.patch ++++ /dev/null +@@ -1,183 +0,0 @@ +---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -1238,6 +1238,8 @@ void rt2800_watchdog(struct rt2x00_dev * +- if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) +- return; +- +-+ rt2800_update_survey(rt2x00dev); +-+ +- queue_for_each(rt2x00dev, queue) { +- switch (queue->qid) { +- case QID_AC_VO: +-@@ -1274,6 +1276,18 @@ void rt2800_watchdog(struct rt2x00_dev * +- } +- EXPORT_SYMBOL_GPL(rt2800_watchdog); +- +-+void rt2800_update_survey(struct rt2x00_dev *rt2x00dev) +-+{ +-+ struct ieee80211_channel *chan = rt2x00dev->hw->conf.chandef.chan; +-+ struct rt2x00_chan_survey *chan_survey = +-+ &rt2x00dev->chan_survey[chan->hw_value]; +-+ +-+ chan_survey->time_idle += rt2800_register_read(rt2x00dev, CH_IDLE_STA); +-+ chan_survey->time_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA); +-+ chan_survey->time_ext_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC); +-+} +-+EXPORT_SYMBOL_GPL(rt2800_update_survey); +-+ +- static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev, +- unsigned int index) +- { +-@@ -12199,26 +12213,30 @@ int rt2800_get_survey(struct ieee80211_h +- { +- struct rt2x00_dev *rt2x00dev = hw->priv; +- struct ieee80211_conf *conf = &hw->conf; +-- u32 idle, busy, busy_ext; +-+ struct rt2x00_chan_survey *chan_survey = +-+ &rt2x00dev->chan_survey[idx]; +-+ enum nl80211_band band = NL80211_BAND_2GHZ; +- +-- if (idx != 0) +-+ if (idx >= rt2x00dev->bands[band].n_channels) { +-+ idx -= rt2x00dev->bands[band].n_channels; +-+ band = NL80211_BAND_5GHZ; +-+ } +-+ +-+ if (idx >= rt2x00dev->bands[band].n_channels) +- return -ENOENT; +- +-- survey->channel = conf->chandef.chan; +-+ if (idx == 0) +-+ rt2800_update_survey(rt2x00dev); +- +-- idle = rt2800_register_read(rt2x00dev, CH_IDLE_STA); +-- busy = rt2800_register_read(rt2x00dev, CH_BUSY_STA); +-- busy_ext = rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC); +-- +-- if (idle || busy) { +-- survey->filled = SURVEY_INFO_TIME | +-- SURVEY_INFO_TIME_BUSY | +-- SURVEY_INFO_TIME_EXT_BUSY; +-- +-- survey->time = (idle + busy) / 1000; +-- survey->time_busy = busy / 1000; +-- survey->time_ext_busy = busy_ext / 1000; +-- } +-+ survey->channel = &rt2x00dev->bands[band].channels[idx]; +-+ +-+ survey->filled = SURVEY_INFO_TIME | +-+ SURVEY_INFO_TIME_BUSY | +-+ SURVEY_INFO_TIME_EXT_BUSY; +-+ +-+ survey->time = div_u64(chan_survey->time_idle + chan_survey->time_busy, 1000); +-+ survey->time_busy = div_u64(chan_survey->time_busy, 1000); +-+ survey->time_ext_busy = div_u64(chan_survey->time_ext_busy, 1000); +- +- if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) +- survey->filled |= SURVEY_INFO_IN_USE; +---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +-@@ -243,6 +243,7 @@ bool rt2800_txstatus_timeout(struct rt2x +- bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev); +- +- void rt2800_watchdog(struct rt2x00_dev *rt2x00dev); +-+void rt2800_update_survey(struct rt2x00_dev *rt2x00dev); +- +- void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); +- void rt2800_clear_beacon(struct queue_entry *entry); +---- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c +-@@ -360,6 +360,7 @@ static const struct rt2x00lib_ops rt2800 +- .gain_calibration = rt2800_gain_calibration, +- .vco_calibration = rt2800_vco_calibration, +- .watchdog = rt2800_watchdog, +-+ .update_survey = rt2800_update_survey, +- .start_queue = rt2800mmio_start_queue, +- .kick_queue = rt2800mmio_kick_queue, +- .stop_queue = rt2800mmio_stop_queue, +---- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +-@@ -214,6 +214,7 @@ static const struct rt2x00lib_ops rt2800 +- .gain_calibration = rt2800_gain_calibration, +- .vco_calibration = rt2800_vco_calibration, +- .watchdog = rt2800_watchdog, +-+ .update_survey = rt2800_update_survey, +- .start_queue = rt2800mmio_start_queue, +- .kick_queue = rt2800mmio_kick_queue, +- .stop_queue = rt2800mmio_stop_queue, +---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +-@@ -183,6 +183,15 @@ struct rf_channel { +- }; +- +- /* +-+ * Information structure for channel survey. +-+ */ +-+struct rt2x00_chan_survey { +-+ u64 time_idle; +-+ u64 time_busy; +-+ u64 time_ext_busy; +-+}; +-+ +-+/* +- * Channel information structure +- */ +- struct channel_info { +-@@ -567,6 +576,7 @@ struct rt2x00lib_ops { +- * Data queue handlers. +- */ +- void (*watchdog) (struct rt2x00_dev *rt2x00dev); +-+ void (*update_survey) (struct rt2x00_dev *rt2x00dev); +- void (*start_queue) (struct data_queue *queue); +- void (*kick_queue) (struct data_queue *queue); +- void (*stop_queue) (struct data_queue *queue); +-@@ -755,6 +765,7 @@ struct rt2x00_dev { +- */ +- struct ieee80211_hw *hw; +- struct ieee80211_supported_band bands[NUM_NL80211_BANDS]; +-+ struct rt2x00_chan_survey *chan_survey; +- enum nl80211_band curr_band; +- int curr_freq; +- +---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1057,6 +1057,12 @@ static int rt2x00lib_probe_hw_modes(stru +- if (!rates) +- goto exit_free_channels; +- +-+ rt2x00dev->chan_survey = +-+ kcalloc(spec->num_channels, sizeof(struct rt2x00_chan_survey), +-+ GFP_KERNEL); +-+ if (!rt2x00dev->chan_survey) +-+ goto exit_free_rates; +-+ +- /* +- * Initialize Rate list. +- */ +-@@ -1108,6 +1114,8 @@ static int rt2x00lib_probe_hw_modes(stru +- +- return 0; +- +-+ exit_free_rates: +-+ kfree(rates); +- exit_free_channels: +- kfree(channels); +- rt2x00_err(rt2x00dev, "Allocation ieee80211 modes failed\n"); +---- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +-@@ -317,6 +317,15 @@ int rt2x00mac_config(struct ieee80211_hw +- return 0; +- +- /* +-+ * To provide correct survey data for survey-based ACS algorithm +-+ * we have to save survey data for current channel before switching. +-+ */ +-+ if (rt2x00dev->ops->lib->update_survey && +-+ (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { +-+ rt2x00dev->ops->lib->update_survey(rt2x00dev); +-+ } +-+ +-+ /* +- * Some configuration parameters (e.g. channel and antenna values) can +- * only be set when the radio is enabled, but do require the RX to +- * be off. During this period we should keep link tuning enabled, +diff --git a/package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch b/package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch +deleted file mode 100644 +index 3daf65e967..0000000000 +--- a/package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch ++++ /dev/null +@@ -1,118 +0,0 @@ +-Date: Mon, 19 Apr 2021 14:59:56 +0800 +-From: Ping-Ke Shih +-To: +-CC: , , +- +-Subject: [PATCH] rtlwifi: implement set_tim by update beacon content +- +-Once beacon content is changed, we update the content to wifi card by +-send_beacon_frame(). Then, STA with PS can wake up properly to receive its +-packets. +- +-Since we update beacon content to PCI wifi devices every beacon interval, +-the only one usb device, 8192CU, needs to update beacon content when +-mac80211 calling set_tim. +- +-Reported-by: Maciej S. Szmigiero +-Signed-off-by: Ping-Ke Shih +-Tested-by: Maciej S. Szmigiero +---- +- drivers/net/wireless/realtek/rtlwifi/core.c | 32 +++++++++++++++++++++ +- drivers/net/wireless/realtek/rtlwifi/core.h | 1 + +- drivers/net/wireless/realtek/rtlwifi/usb.c | 3 ++ +- drivers/net/wireless/realtek/rtlwifi/wifi.h | 1 + +- 4 files changed, 37 insertions(+) +- +---- a/drivers/net/wireless/realtek/rtlwifi/core.c +-+++ b/drivers/net/wireless/realtek/rtlwifi/core.c +-@@ -1018,6 +1018,25 @@ static void send_beacon_frame(struct iee +- } +- } +- +-+void rtl_update_beacon_work_callback(struct work_struct *work) +-+{ +-+ struct rtl_works *rtlworks = +-+ container_of(work, struct rtl_works, update_beacon_work); +-+ struct ieee80211_hw *hw = rtlworks->hw; +-+ struct rtl_priv *rtlpriv = rtl_priv(hw); +-+ struct ieee80211_vif *vif = rtlpriv->mac80211.vif; +-+ +-+ if (!vif) { +-+ WARN_ONCE(true, "no vif to update beacon\n"); +-+ return; +-+ } +-+ +-+ mutex_lock(&rtlpriv->locks.conf_mutex); +-+ send_beacon_frame(hw, vif); +-+ mutex_unlock(&rtlpriv->locks.conf_mutex); +-+} +-+EXPORT_SYMBOL_GPL(rtl_update_beacon_work_callback); +-+ +- static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, +- struct ieee80211_vif *vif, +- struct ieee80211_bss_conf *bss_conf, +-@@ -1747,6 +1766,18 @@ static void rtl_op_flush(struct ieee8021 +- rtlpriv->intf_ops->flush(hw, queues, drop); +- } +- +-+static int rtl_op_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, +-+ bool set) +-+{ +-+ struct rtl_priv *rtlpriv = rtl_priv(hw); +-+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +-+ +-+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) +-+ schedule_work(&rtlpriv->works.update_beacon_work); +-+ +-+ return 0; +-+} +-+ +- /* Description: +- * This routine deals with the Power Configuration CMD +- * parsing for RTL8723/RTL8188E Series IC. +-@@ -1903,6 +1934,7 @@ const struct ieee80211_ops rtl_ops = { +- .sta_add = rtl_op_sta_add, +- .sta_remove = rtl_op_sta_remove, +- .flush = rtl_op_flush, +-+ .set_tim = rtl_op_set_tim, +- }; +- EXPORT_SYMBOL_GPL(rtl_ops); +- +---- a/drivers/net/wireless/realtek/rtlwifi/core.h +-+++ b/drivers/net/wireless/realtek/rtlwifi/core.h +-@@ -60,5 +60,6 @@ void rtl_bb_delay(struct ieee80211_hw *h +- bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); +- bool rtl_btc_status_false(void); +- void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igval); +-+void rtl_update_beacon_work_callback(struct work_struct *work); +- +- #endif +---- a/drivers/net/wireless/realtek/rtlwifi/usb.c +-+++ b/drivers/net/wireless/realtek/rtlwifi/usb.c +-@@ -807,6 +807,7 @@ static void rtl_usb_stop(struct ieee8021 +- +- tasklet_kill(&rtlusb->rx_work_tasklet); +- cancel_work_sync(&rtlpriv->works.lps_change_work); +-+ cancel_work_sync(&rtlpriv->works.update_beacon_work); +- +- flush_workqueue(rtlpriv->works.rtl_wq); +- +-@@ -1033,6 +1034,8 @@ int rtl_usb_probe(struct usb_interface * +- rtl_fill_h2c_cmd_work_callback); +- INIT_WORK(&rtlpriv->works.lps_change_work, +- rtl_lps_change_work_callback); +-+ INIT_WORK(&rtlpriv->works.update_beacon_work, +-+ rtl_update_beacon_work_callback); +- +- rtlpriv->usb_data_index = 0; +- init_completion(&rtlpriv->firmware_loading_complete); +---- a/drivers/net/wireless/realtek/rtlwifi/wifi.h +-+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h +-@@ -2487,6 +2487,7 @@ struct rtl_works { +- +- struct work_struct lps_change_work; +- struct work_struct fill_h2c_cmd; +-+ struct work_struct update_beacon_work; +- }; +- +- struct rtl_debug { +diff --git a/package/kernel/mac80211/patches/subsys/010-sync-nl80211_h.patch b/package/kernel/mac80211/patches/subsys/010-sync-nl80211_h.patch +deleted file mode 100644 +index e1f66ac1c3..0000000000 +--- a/package/kernel/mac80211/patches/subsys/010-sync-nl80211_h.patch ++++ /dev/null +@@ -1,297 +0,0 @@ +---- a/include/uapi/linux/nl80211.h +-+++ b/include/uapi/linux/nl80211.h +-@@ -655,6 +655,9 @@ +- * When a security association was established on an 802.1X network using +- * fast transition, this event should be followed by an +- * %NL80211_CMD_PORT_AUTHORIZED event. +-+ * Following a %NL80211_CMD_ROAM event userspace can issue +-+ * %NL80211_CMD_GET_SCAN in order to obtain the scan information for the +-+ * new BSS the card/driver roamed to. +- * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify +- * userspace that a connection was dropped by the AP or due to other +- * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and +-@@ -757,7 +760,8 @@ +- * of any other interfaces, and other interfaces will again take +- * precedence when they are used. +- * +-- * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface. +-+ * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface +-+ * (no longer supported). +- * +- * @NL80211_CMD_SET_MULTICAST_TO_UNICAST: Configure if this AP should perform +- * multicast to unicast conversion. When enabled, all multicast packets +-@@ -1177,6 +1181,10 @@ +- * includes the contents of the frame. %NL80211_ATTR_ACK flag is included +- * if the recipient acknowledged the frame. +- * +-+ * @NL80211_CMD_SET_SAR_SPECS: SAR power limitation configuration is +-+ * passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to +-+ * specify the wiphy index to be applied to. +-+ * +- * @NL80211_CMD_MAX: highest used command number +- * @__NL80211_CMD_AFTER_LAST: internal use +- */ +-@@ -1407,6 +1415,8 @@ enum nl80211_commands { +- +- NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS, +- +-+ NL80211_CMD_SET_SAR_SPECS, +-+ +- /* add new commands above here */ +- +- /* used to define NL80211_CMD_MAX below */ +-@@ -1750,8 +1760,9 @@ enum nl80211_commands { +- * specify just a single bitrate, which is to be used for the beacon. +- * The driver must also specify support for this with the extended +- * features NL80211_EXT_FEATURE_BEACON_RATE_LEGACY, +-- * NL80211_EXT_FEATURE_BEACON_RATE_HT and +-- * NL80211_EXT_FEATURE_BEACON_RATE_VHT. +-+ * NL80211_EXT_FEATURE_BEACON_RATE_HT, +-+ * NL80211_EXT_FEATURE_BEACON_RATE_VHT and +-+ * NL80211_EXT_FEATURE_BEACON_RATE_HE. +- * +- * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain +- * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME. +-@@ -1955,8 +1966,15 @@ enum nl80211_commands { +- * @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire +- * probe-response frame. The DA field in the 802.11 header is zero-ed out, +- * to be filled by the FW. +-- * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable +-- * this feature. Currently, only supported in mac80211 drivers. +-+ * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable +-+ * this feature during association. This is a flag attribute. +-+ * Currently only supported in mac80211 drivers. +-+ * @NL80211_ATTR_DISABLE_VHT: Force VHT capable interfaces to disable +-+ * this feature during association. This is a flag attribute. +-+ * Currently only supported in mac80211 drivers. +-+ * @NL80211_ATTR_DISABLE_HE: Force HE capable interfaces to disable +-+ * this feature during association. This is a flag attribute. +-+ * Currently only supported in mac80211 drivers. +- * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the +- * ATTR_HT_CAPABILITY to which attention should be paid. +- * Currently, only mac80211 NICs support this feature. +-@@ -2077,7 +2095,8 @@ enum nl80211_commands { +- * until the channel switch event. +- * @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission +- * must be blocked on the current channel (before the channel switch +-- * operation). +-+ * operation). Also included in the channel switch started event if quiet +-+ * was requested by the AP. +- * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information +- * for the time while performing a channel switch. +- * @NL80211_ATTR_CNTDWN_OFFS_BEACON: An array of offsets (u16) to the channel +-@@ -2527,6 +2546,20 @@ enum nl80211_commands { +- * override mask. Used with NL80211_ATTR_S1G_CAPABILITY in +- * NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT. +- * +-+ * @NL80211_ATTR_SAE_PWE: Indicates the mechanism(s) allowed for SAE PWE +-+ * derivation in WPA3-Personal networks which are using SAE authentication. +-+ * This is a u8 attribute that encapsulates one of the values from +-+ * &enum nl80211_sae_pwe_mechanism. +-+ * +-+ * @NL80211_ATTR_SAR_SPEC: SAR power limitation specification when +-+ * used with %NL80211_CMD_SET_SAR_SPECS. The message contains fields +-+ * of %nl80211_sar_attrs which specifies the sar type and related +-+ * sar specs. Sar specs contains array of %nl80211_sar_specs_attrs. +-+ * +-+ * @NL80211_ATTR_RECONNECT_REQUESTED: flag attribute, used with deauth and +-+ * disassoc events to indicate that an immediate reconnect to the AP +-+ * is desired. +-+ * +- * @NUM_NL80211_ATTR: total number of nl80211_attrs available +- * @NL80211_ATTR_MAX: highest attribute number currently defined +- * @__NL80211_ATTR_AFTER_LAST: internal use +-@@ -3016,6 +3049,14 @@ enum nl80211_attrs { +- NL80211_ATTR_S1G_CAPABILITY, +- NL80211_ATTR_S1G_CAPABILITY_MASK, +- +-+ NL80211_ATTR_SAE_PWE, +-+ +-+ NL80211_ATTR_RECONNECT_REQUESTED, +-+ +-+ NL80211_ATTR_SAR_SPEC, +-+ +-+ NL80211_ATTR_DISABLE_HE, +-+ +- /* add attributes here, update the policy in nl80211.c */ +- +- __NL80211_ATTR_AFTER_LAST, +-@@ -5896,6 +5937,19 @@ enum nl80211_feature_flags { +- * @NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP: Driver/device supports +- * unsolicited broadcast probe response transmission +- * +-+ * @NL80211_EXT_FEATURE_BEACON_RATE_HE: Driver supports beacon rate +-+ * configuration (AP/mesh) with HE rates. +-+ * +-+ * @NL80211_EXT_FEATURE_SECURE_LTF: Device supports secure LTF measurement +-+ * exchange protocol. +-+ * +-+ * @NL80211_EXT_FEATURE_SECURE_RTT: Device supports secure RTT measurement +-+ * exchange protocol. +-+ * +-+ * @NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE: Device supports management +-+ * frame protection for all management frames exchanged during the +-+ * negotiation and range measurement procedure. +-+ * +- * @NUM_NL80211_EXT_FEATURES: number of extended features. +- * @MAX_NL80211_EXT_FEATURES: highest extended feature index. +- */ +-@@ -5956,6 +6010,10 @@ enum nl80211_ext_feature_index { +- NL80211_EXT_FEATURE_SAE_OFFLOAD_AP, +- NL80211_EXT_FEATURE_FILS_DISCOVERY, +- NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP, +-+ NL80211_EXT_FEATURE_BEACON_RATE_HE, +-+ NL80211_EXT_FEATURE_SECURE_LTF, +-+ NL80211_EXT_FEATURE_SECURE_RTT, +-+ NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, +- +- /* add new features before the definition below */ +- NUM_NL80211_EXT_FEATURES, +-@@ -6253,11 +6311,13 @@ struct nl80211_vendor_cmd_info { +- * @NL80211_TDLS_PEER_HT: TDLS peer is HT capable. +- * @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable. +- * @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable. +-+ * @NL80211_TDLS_PEER_HE: TDLS peer is HE capable. +- */ +- enum nl80211_tdls_peer_capability { +- NL80211_TDLS_PEER_HT = 1<<0, +- NL80211_TDLS_PEER_VHT = 1<<1, +- NL80211_TDLS_PEER_WMM = 1<<2, +-+ NL80211_TDLS_PEER_HE = 1<<3, +- }; +- +- /** +-@@ -6849,6 +6909,9 @@ enum nl80211_peer_measurement_ftm_capa { +- * if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor +- * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based +- * ranging will be used. +-+ * @NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK: negotiate for LMR feedback. Only +-+ * valid if either %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED or +-+ * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set. +- * +- * @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal +- * @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number +-@@ -6867,6 +6930,7 @@ enum nl80211_peer_measurement_ftm_req { +- NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC, +- NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED, +- NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED, +-+ NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK, +- +- /* keep last */ +- NUM_NL80211_PMSR_FTM_REQ_ATTR, +-@@ -7124,4 +7188,115 @@ enum nl80211_unsol_bcast_probe_resp_attr +- NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX = +- __NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_LAST - 1 +- }; +-+ +-+/** +-+ * enum nl80211_sae_pwe_mechanism - The mechanism(s) allowed for SAE PWE +-+ * derivation. Applicable only when WPA3-Personal SAE authentication is +-+ * used. +-+ * +-+ * @NL80211_SAE_PWE_UNSPECIFIED: not specified, used internally to indicate that +-+ * attribute is not present from userspace. +-+ * @NL80211_SAE_PWE_HUNT_AND_PECK: hunting-and-pecking loop only +-+ * @NL80211_SAE_PWE_HASH_TO_ELEMENT: hash-to-element only +-+ * @NL80211_SAE_PWE_BOTH: both hunting-and-pecking loop and hash-to-element +-+ * can be used. +-+ */ +-+enum nl80211_sae_pwe_mechanism { +-+ NL80211_SAE_PWE_UNSPECIFIED, +-+ NL80211_SAE_PWE_HUNT_AND_PECK, +-+ NL80211_SAE_PWE_HASH_TO_ELEMENT, +-+ NL80211_SAE_PWE_BOTH, +-+}; +-+ +-+/** +-+ * enum nl80211_sar_type - type of SAR specs +-+ * +-+ * @NL80211_SAR_TYPE_POWER: power limitation specified in 0.25dBm unit +-+ * +-+ */ +-+enum nl80211_sar_type { +-+ NL80211_SAR_TYPE_POWER, +-+ +-+ /* add new type here */ +-+ +-+ /* Keep last */ +-+ NUM_NL80211_SAR_TYPE, +-+}; +-+ +-+/** +-+ * enum nl80211_sar_attrs - Attributes for SAR spec +-+ * +-+ * @NL80211_SAR_ATTR_TYPE: the SAR type as defined in &enum nl80211_sar_type. +-+ * +-+ * @NL80211_SAR_ATTR_SPECS: Nested array of SAR power +-+ * limit specifications. Each specification contains a set +-+ * of %nl80211_sar_specs_attrs. +-+ * +-+ * For SET operation, it contains array of %NL80211_SAR_ATTR_SPECS_POWER +-+ * and %NL80211_SAR_ATTR_SPECS_RANGE_INDEX. +-+ * +-+ * For sar_capa dump, it contains array of +-+ * %NL80211_SAR_ATTR_SPECS_START_FREQ +-+ * and %NL80211_SAR_ATTR_SPECS_END_FREQ. +-+ * +-+ * @__NL80211_SAR_ATTR_LAST: Internal +-+ * @NL80211_SAR_ATTR_MAX: highest sar attribute +-+ * +-+ * These attributes are used with %NL80211_CMD_SET_SAR_SPEC +-+ */ +-+enum nl80211_sar_attrs { +-+ __NL80211_SAR_ATTR_INVALID, +-+ +-+ NL80211_SAR_ATTR_TYPE, +-+ NL80211_SAR_ATTR_SPECS, +-+ +-+ __NL80211_SAR_ATTR_LAST, +-+ NL80211_SAR_ATTR_MAX = __NL80211_SAR_ATTR_LAST - 1, +-+}; +-+ +-+/** +-+ * enum nl80211_sar_specs_attrs - Attributes for SAR power limit specs +-+ * +-+ * @NL80211_SAR_ATTR_SPECS_POWER: Required (s32)value to specify the actual +-+ * power limit value in units of 0.25 dBm if type is +-+ * NL80211_SAR_TYPE_POWER. (i.e., a value of 44 represents 11 dBm). +-+ * 0 means userspace doesn't have SAR limitation on this associated range. +-+ * +-+ * @NL80211_SAR_ATTR_SPECS_RANGE_INDEX: Required (u32) value to specify the +-+ * index of exported freq range table and the associated power limitation +-+ * is applied to this range. +-+ * +-+ * Userspace isn't required to set all the ranges advertised by WLAN driver, +-+ * and userspace can skip some certain ranges. These skipped ranges don't +-+ * have SAR limitations, and they are same as setting the +-+ * %NL80211_SAR_ATTR_SPECS_POWER to any unreasonable high value because any +-+ * value higher than regulatory allowed value just means SAR power +-+ * limitation is removed, but it's required to set at least one range. +-+ * It's not allowed to set duplicated range in one SET operation. +-+ * +-+ * Every SET operation overwrites previous SET operation. +-+ * +-+ * @NL80211_SAR_ATTR_SPECS_START_FREQ: Required (u32) value to specify the start +-+ * frequency of this range edge when registering SAR capability to wiphy. +-+ * It's not a channel center frequency. The unit is kHz. +-+ * +-+ * @NL80211_SAR_ATTR_SPECS_END_FREQ: Required (u32) value to specify the end +-+ * frequency of this range edge when registering SAR capability to wiphy. +-+ * It's not a channel center frequency. The unit is kHz. +-+ * +-+ * @__NL80211_SAR_ATTR_SPECS_LAST: Internal +-+ * @NL80211_SAR_ATTR_SPECS_MAX: highest sar specs attribute +-+ */ +-+enum nl80211_sar_specs_attrs { +-+ __NL80211_SAR_ATTR_SPECS_INVALID, +-+ +-+ NL80211_SAR_ATTR_SPECS_POWER, +-+ NL80211_SAR_ATTR_SPECS_RANGE_INDEX, +-+ NL80211_SAR_ATTR_SPECS_START_FREQ, +-+ NL80211_SAR_ATTR_SPECS_END_FREQ, +-+ +-+ __NL80211_SAR_ATTR_SPECS_LAST, +-+ NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1, +-+}; +-+ +- #endif /* __LINUX_NL80211_H */ +diff --git a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch b/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch +deleted file mode 100644 +index ca02dfb06f..0000000000 +--- a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch ++++ /dev/null +@@ -1,699 +0,0 @@ +---- a/net/mac80211/Makefile +-+++ b/net/mac80211/Makefile +-@@ -7,7 +7,6 @@ mac80211-y := \ +- driver-ops.o \ +- sta_info.o \ +- wep.o \ +-- aead_api.o \ +- wpa.o \ +- scan.o offchannel.o \ +- ht.o agg-tx.o agg-rx.o \ +-@@ -19,8 +18,8 @@ mac80211-y := \ +- rate.o \ +- michael.o \ +- tkip.o \ +-+ aes_ccm.o \ +- aes_cmac.o \ +-- aes_gmac.o \ +- fils_aead.o \ +- cfg.o \ +- ethtool.o \ +---- a/net/mac80211/aead_api.c +-+++ /dev/null +-@@ -1,113 +0,0 @@ +--// SPDX-License-Identifier: GPL-2.0-only +--/* +-- * Copyright 2003-2004, Instant802 Networks, Inc. +-- * Copyright 2005-2006, Devicescape Software, Inc. +-- * Copyright 2014-2015, Qualcomm Atheros, Inc. +-- * +-- * Rewrite: Copyright (C) 2013 Linaro Ltd +-- */ +-- +--#include +--#include +--#include +--#include +--#include +-- +--#include "aead_api.h" +-- +--int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, +-- u8 *data, size_t data_len, u8 *mic) +--{ +-- size_t mic_len = crypto_aead_authsize(tfm); +-- struct scatterlist sg[3]; +-- struct aead_request *aead_req; +-- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); +-- u8 *__aad; +-- int ret; +-- +-- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); +-- if (!aead_req) +-- return -ENOMEM; +-- +-- __aad = (u8 *)aead_req + reqsize; +-- memcpy(__aad, aad, aad_len); +-- +-- sg_init_table(sg, 3); +-- sg_set_buf(&sg[0], __aad, aad_len); +-- sg_set_buf(&sg[1], data, data_len); +-- sg_set_buf(&sg[2], mic, mic_len); +-- +-- aead_request_set_tfm(aead_req, tfm); +-- aead_request_set_crypt(aead_req, sg, sg, data_len, b_0); +-- aead_request_set_ad(aead_req, sg[0].length); +-- +-- ret = crypto_aead_encrypt(aead_req); +-- kfree_sensitive(aead_req); +-- +-- return ret; +--} +-- +--int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, +-- u8 *data, size_t data_len, u8 *mic) +--{ +-- size_t mic_len = crypto_aead_authsize(tfm); +-- struct scatterlist sg[3]; +-- struct aead_request *aead_req; +-- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); +-- u8 *__aad; +-- int err; +-- +-- if (data_len == 0) +-- return -EINVAL; +-- +-- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); +-- if (!aead_req) +-- return -ENOMEM; +-- +-- __aad = (u8 *)aead_req + reqsize; +-- memcpy(__aad, aad, aad_len); +-- +-- sg_init_table(sg, 3); +-- sg_set_buf(&sg[0], __aad, aad_len); +-- sg_set_buf(&sg[1], data, data_len); +-- sg_set_buf(&sg[2], mic, mic_len); +-- +-- aead_request_set_tfm(aead_req, tfm); +-- aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0); +-- aead_request_set_ad(aead_req, sg[0].length); +-- +-- err = crypto_aead_decrypt(aead_req); +-- kfree_sensitive(aead_req); +-- +-- return err; +--} +-- +--struct crypto_aead * +--aead_key_setup_encrypt(const char *alg, const u8 key[], +-- size_t key_len, size_t mic_len) +--{ +-- struct crypto_aead *tfm; +-- int err; +-- +-- tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC); +-- if (IS_ERR(tfm)) +-- return tfm; +-- +-- err = crypto_aead_setkey(tfm, key, key_len); +-- if (err) +-- goto free_aead; +-- err = crypto_aead_setauthsize(tfm, mic_len); +-- if (err) +-- goto free_aead; +-- +-- return tfm; +-- +--free_aead: +-- crypto_free_aead(tfm); +-- return ERR_PTR(err); +--} +-- +--void aead_key_free(struct crypto_aead *tfm) +--{ +-- crypto_free_aead(tfm); +--} +---- a/net/mac80211/aead_api.h +-+++ /dev/null +-@@ -1,23 +0,0 @@ +--/* SPDX-License-Identifier: GPL-2.0-only */ +-- +--#ifndef _AEAD_API_H +--#define _AEAD_API_H +-- +--#include +--#include +-- +--struct crypto_aead * +--aead_key_setup_encrypt(const char *alg, const u8 key[], +-- size_t key_len, size_t mic_len); +-- +--int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, +-- size_t aad_len, u8 *data, +-- size_t data_len, u8 *mic); +-- +--int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, +-- size_t aad_len, u8 *data, +-- size_t data_len, u8 *mic); +-- +--void aead_key_free(struct crypto_aead *tfm); +-- +--#endif /* _AEAD_API_H */ +---- a/net/mac80211/aes_ccm.h +-+++ b/net/mac80211/aes_ccm.h +-@@ -7,39 +7,17 @@ +- #ifndef AES_CCM_H +- #define AES_CCM_H +- +--#include "aead_api.h" +-+#include +- +--#define CCM_AAD_LEN 32 +-- +--static inline struct crypto_aead * +--ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len) +--{ +-- return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len); +--} +-- +--static inline int +--ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, +-- u8 *b_0, u8 *aad, u8 *data, +-- size_t data_len, u8 *mic) +--{ +-- return aead_encrypt(tfm, b_0, aad + 2, +-- be16_to_cpup((__be16 *)aad), +-- data, data_len, mic); +--} +-- +--static inline int +--ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, +-- u8 *b_0, u8 *aad, u8 *data, +-- size_t data_len, u8 *mic) +--{ +-- return aead_decrypt(tfm, b_0, aad + 2, +-- be16_to_cpup((__be16 *)aad), +-- data, data_len, mic); +--} +-- +--static inline void ieee80211_aes_key_free(struct crypto_aead *tfm) +--{ +-- return aead_key_free(tfm); +--} +-+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], +-+ size_t key_len, +-+ size_t mic_len); +-+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, +-+ u8 *data, size_t data_len, u8 *mic, +-+ size_t mic_len); +-+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, +-+ u8 *data, size_t data_len, u8 *mic, +-+ size_t mic_len); +-+void ieee80211_aes_key_free(struct crypto_cipher *tfm); +- +- #endif /* AES_CCM_H */ +---- /dev/null +-+++ b/net/mac80211/aes_gcm.c +-@@ -0,0 +1,109 @@ +-+/* +-+ * Copyright 2014-2015, Qualcomm Atheros, Inc. +-+ * +-+ * This program is free software; you can redistribute it and/or modify +-+ * it under the terms of the GNU General Public License version 2 as +-+ * published by the Free Software Foundation. +-+ */ +-+ +-+#include +-+#include +-+#include +-+#include +-+ +-+#include +-+#include "key.h" +-+#include "aes_gcm.h" +-+ +-+int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, +-+ u8 *data, size_t data_len, u8 *mic) +-+{ +-+ struct scatterlist sg[3]; +-+ struct aead_request *aead_req; +-+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); +-+ u8 *__aad; +-+ +-+ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); +-+ if (!aead_req) +-+ return -ENOMEM; +-+ +-+ __aad = (u8 *)aead_req + reqsize; +-+ memcpy(__aad, aad, GCM_AAD_LEN); +-+ +-+ sg_init_table(sg, 3); +-+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); +-+ sg_set_buf(&sg[1], data, data_len); +-+ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); +-+ +-+ aead_request_set_tfm(aead_req, tfm); +-+ aead_request_set_crypt(aead_req, sg, sg, data_len, j_0); +-+ aead_request_set_ad(aead_req, sg[0].length); +-+ +-+ crypto_aead_encrypt(aead_req); +-+ kzfree(aead_req); +-+ return 0; +-+} +-+ +-+int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, +-+ u8 *data, size_t data_len, u8 *mic) +-+{ +-+ struct scatterlist sg[3]; +-+ struct aead_request *aead_req; +-+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); +-+ u8 *__aad; +-+ int err; +-+ +-+ if (data_len == 0) +-+ return -EINVAL; +-+ +-+ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); +-+ if (!aead_req) +-+ return -ENOMEM; +-+ +-+ __aad = (u8 *)aead_req + reqsize; +-+ memcpy(__aad, aad, GCM_AAD_LEN); +-+ +-+ sg_init_table(sg, 3); +-+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); +-+ sg_set_buf(&sg[1], data, data_len); +-+ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); +-+ +-+ aead_request_set_tfm(aead_req, tfm); +-+ aead_request_set_crypt(aead_req, sg, sg, +-+ data_len + IEEE80211_GCMP_MIC_LEN, j_0); +-+ aead_request_set_ad(aead_req, sg[0].length); +-+ +-+ err = crypto_aead_decrypt(aead_req); +-+ kzfree(aead_req); +-+ +-+ return err; +-+} +-+ +-+struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], +-+ size_t key_len) +-+{ +-+ struct crypto_aead *tfm; +-+ int err; +-+ +-+ tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); +-+ if (IS_ERR(tfm)) +-+ return tfm; +-+ +-+ err = crypto_aead_setkey(tfm, key, key_len); +-+ if (err) +-+ goto free_aead; +-+ err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN); +-+ if (err) +-+ goto free_aead; +-+ +-+ return tfm; +-+ +-+free_aead: +-+ crypto_free_aead(tfm); +-+ return ERR_PTR(err); +-+} +-+ +-+void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) +-+{ +-+ crypto_free_aead(tfm); +-+} +---- a/net/mac80211/aes_gcm.h +-+++ b/net/mac80211/aes_gcm.h +-@@ -6,38 +6,30 @@ +- #ifndef AES_GCM_H +- #define AES_GCM_H +- +--#include "aead_api.h" +-+#include +- +--#define GCM_AAD_LEN 32 +-- +--static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, +-- u8 *j_0, u8 *aad, u8 *data, +-- size_t data_len, u8 *mic) +-+static inline void +-+ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, +-+ u8 *data, size_t data_len, u8 *mic) +- { +-- return aead_encrypt(tfm, j_0, aad + 2, +-- be16_to_cpup((__be16 *)aad), +-- data, data_len, mic); +- } +- +--static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, +-- u8 *j_0, u8 *aad, u8 *data, +-- size_t data_len, u8 *mic) +-+static inline int +-+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, +-+ u8 *data, size_t data_len, u8 *mic) +- { +-- return aead_decrypt(tfm, j_0, aad + 2, +-- be16_to_cpup((__be16 *)aad), +-- data, data_len, mic); +-+ return -EOPNOTSUPP; +- } +- +- static inline struct crypto_aead * +- ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len) +- { +-- return aead_key_setup_encrypt("gcm(aes)", key, +-- key_len, IEEE80211_GCMP_MIC_LEN); +-+ return NULL; +- } +- +--static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) +-+static inline void +-+ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) +- { +-- return aead_key_free(tfm); +- } +- +- #endif /* AES_GCM_H */ +---- a/net/mac80211/wpa.c +-+++ b/net/mac80211/wpa.c +-@@ -312,7 +312,8 @@ ieee80211_crypto_tkip_decrypt(struct iee +- } +- +- +--static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad) +-+static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, +-+ u16 data_len) +- { +- __le16 mask_fc; +- int a4_included, mgmt; +-@@ -342,14 +343,8 @@ static void ccmp_special_blocks(struct s +- else +- qos_tid = 0; +- +-- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC +-- * mode authentication are not allowed to collide, yet both are derived +-- * from this vector b_0. We only set L := 1 here to indicate that the +-- * data size can be represented in (L+1) bytes. The CCM layer will take +-- * care of storing the data length in the top (L+1) bytes and setting +-- * and clearing the other bits as is required to derive the two IVs. +-- */ +-- b_0[0] = 0x1; +-+ /* First block, b_0 */ +-+ b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ +- +- /* Nonce: Nonce Flags | A2 | PN +- * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) +-@@ -357,6 +352,8 @@ static void ccmp_special_blocks(struct s +- b_0[1] = qos_tid | (mgmt << 4); +- memcpy(&b_0[2], hdr->addr2, ETH_ALEN); +- memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); +-+ /* l(m) */ +-+ put_unaligned_be16(data_len, &b_0[14]); +- +- /* AAD (extra authenticate-only data) / masked 802.11 header +- * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ +-@@ -413,7 +410,7 @@ static int ccmp_encrypt_skb(struct ieee8 +- u8 *pos; +- u8 pn[6]; +- u64 pn64; +-- u8 aad[CCM_AAD_LEN]; +-+ u8 aad[2 * AES_BLOCK_SIZE]; +- u8 b_0[AES_BLOCK_SIZE]; +- +- if (info->control.hw_key && +-@@ -468,9 +465,11 @@ static int ccmp_encrypt_skb(struct ieee8 +- return 0; +- +- pos += IEEE80211_CCMP_HDR_LEN; +-- ccmp_special_blocks(skb, pn, b_0, aad); +-- return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, +-- skb_put(skb, mic_len)); +-+ ccmp_special_blocks(skb, pn, b_0, aad, len); +-+ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, +-+ skb_put(skb, mic_len), mic_len); +-+ +-+ return 0; +- } +- +- +-@@ -543,13 +542,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee +- u8 aad[2 * AES_BLOCK_SIZE]; +- u8 b_0[AES_BLOCK_SIZE]; +- /* hardware didn't decrypt/verify MIC */ +-- ccmp_special_blocks(skb, pn, b_0, aad); +-+ ccmp_special_blocks(skb, pn, b_0, aad, data_len); +- +- if (ieee80211_aes_ccm_decrypt( +- key->u.ccmp.tfm, b_0, aad, +- skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, +- data_len, +-- skb->data + skb->len - mic_len)) +-+ skb->data + skb->len - mic_len, mic_len)) +- return RX_DROP_UNUSABLE; +- } +- +-@@ -646,7 +645,7 @@ static int gcmp_encrypt_skb(struct ieee8 +- u8 *pos; +- u8 pn[6]; +- u64 pn64; +-- u8 aad[GCM_AAD_LEN]; +-+ u8 aad[2 * AES_BLOCK_SIZE]; +- u8 j_0[AES_BLOCK_SIZE]; +- +- if (info->control.hw_key && +-@@ -703,8 +702,10 @@ static int gcmp_encrypt_skb(struct ieee8 +- +- pos += IEEE80211_GCMP_HDR_LEN; +- gcmp_special_blocks(skb, pn, j_0, aad); +-- return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, +-- skb_put(skb, IEEE80211_GCMP_MIC_LEN)); +-+ ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, +-+ skb_put(skb, IEEE80211_GCMP_MIC_LEN)); +-+ +-+ return 0; +- } +- +- ieee80211_tx_result +-@@ -1133,9 +1134,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct +- struct ieee80211_key *key = tx->key; +- struct ieee80211_mmie_16 *mmie; +- struct ieee80211_hdr *hdr; +-- u8 aad[GMAC_AAD_LEN]; +-+ u8 aad[20]; +- u64 pn64; +-- u8 nonce[GMAC_NONCE_LEN]; +-+ u8 nonce[12]; +- +- if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) +- return TX_DROP; +-@@ -1181,7 +1182,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct +- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); +- struct ieee80211_key *key = rx->key; +- struct ieee80211_mmie_16 *mmie; +-- u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN]; +-+ u8 aad[20], *mic, ipn[6], nonce[12]; +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +- +- if (!ieee80211_is_mgmt(hdr->frame_control)) +---- /dev/null +-+++ b/net/mac80211/aes_ccm.c +-@@ -0,0 +1,144 @@ +-+/* +-+ * Copyright 2003-2004, Instant802 Networks, Inc. +-+ * Copyright 2005-2006, Devicescape Software, Inc. +-+ * +-+ * Rewrite: Copyright (C) 2013 Linaro Ltd +-+ * +-+ * This program is free software; you can redistribute it and/or modify +-+ * it under the terms of the GNU General Public License version 2 as +-+ * published by the Free Software Foundation. +-+ */ +-+ +-+#include +-+#include +-+#include +-+#include +-+#include +-+ +-+#include +-+#include "key.h" +-+#include "aes_ccm.h" +-+ +-+static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0, +-+ u8 *a, u8 *b) +-+{ +-+ int i; +-+ +-+ crypto_cipher_encrypt_one(tfm, b, b_0); +-+ +-+ /* Extra Authenticate-only data (always two AES blocks) */ +-+ for (i = 0; i < AES_BLOCK_SIZE; i++) +-+ aad[i] ^= b[i]; +-+ crypto_cipher_encrypt_one(tfm, b, aad); +-+ +-+ aad += AES_BLOCK_SIZE; +-+ +-+ for (i = 0; i < AES_BLOCK_SIZE; i++) +-+ aad[i] ^= b[i]; +-+ crypto_cipher_encrypt_one(tfm, a, aad); +-+ +-+ /* Mask out bits from auth-only-b_0 */ +-+ b_0[0] &= 0x07; +-+ +-+ /* S_0 is used to encrypt T (= MIC) */ +-+ b_0[14] = 0; +-+ b_0[15] = 0; +-+ crypto_cipher_encrypt_one(tfm, s_0, b_0); +-+} +-+ +-+ +-+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, +-+ u8 *data, size_t data_len, u8 *mic, +-+ size_t mic_len) +-+{ +-+ int i, j, last_len, num_blocks; +-+ u8 b[AES_BLOCK_SIZE]; +-+ u8 s_0[AES_BLOCK_SIZE]; +-+ u8 e[AES_BLOCK_SIZE]; +-+ u8 *pos, *cpos; +-+ +-+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); +-+ last_len = data_len % AES_BLOCK_SIZE; +-+ aes_ccm_prepare(tfm, b_0, aad, s_0, b, b); +-+ +-+ /* Process payload blocks */ +-+ pos = data; +-+ cpos = data; +-+ for (j = 1; j <= num_blocks; j++) { +-+ int blen = (j == num_blocks && last_len) ? +-+ last_len : AES_BLOCK_SIZE; +-+ +-+ /* Authentication followed by encryption */ +-+ for (i = 0; i < blen; i++) +-+ b[i] ^= pos[i]; +-+ crypto_cipher_encrypt_one(tfm, b, b); +-+ +-+ b_0[14] = (j >> 8) & 0xff; +-+ b_0[15] = j & 0xff; +-+ crypto_cipher_encrypt_one(tfm, e, b_0); +-+ for (i = 0; i < blen; i++) +-+ *cpos++ = *pos++ ^ e[i]; +-+ } +-+ +-+ for (i = 0; i < mic_len; i++) +-+ mic[i] = b[i] ^ s_0[i]; +-+} +-+ +-+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, +-+ u8 *data, size_t data_len, u8 *mic, +-+ size_t mic_len) +-+{ +-+ int i, j, last_len, num_blocks; +-+ u8 *pos, *cpos; +-+ u8 a[AES_BLOCK_SIZE]; +-+ u8 b[AES_BLOCK_SIZE]; +-+ u8 s_0[AES_BLOCK_SIZE]; +-+ +-+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); +-+ last_len = data_len % AES_BLOCK_SIZE; +-+ aes_ccm_prepare(tfm, b_0, aad, s_0, a, b); +-+ +-+ /* Process payload blocks */ +-+ cpos = data; +-+ pos = data; +-+ for (j = 1; j <= num_blocks; j++) { +-+ int blen = (j == num_blocks && last_len) ? +-+ last_len : AES_BLOCK_SIZE; +-+ +-+ /* Decryption followed by authentication */ +-+ b_0[14] = (j >> 8) & 0xff; +-+ b_0[15] = j & 0xff; +-+ crypto_cipher_encrypt_one(tfm, b, b_0); +-+ for (i = 0; i < blen; i++) { +-+ *pos = *cpos++ ^ b[i]; +-+ a[i] ^= *pos++; +-+ } +-+ crypto_cipher_encrypt_one(tfm, a, a); +-+ } +-+ +-+ for (i = 0; i < mic_len; i++) { +-+ if ((mic[i] ^ s_0[i]) != a[i]) +-+ return -1; +-+ } +-+ +-+ return 0; +-+} +-+ +-+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], +-+ size_t key_len, +-+ size_t mic_len) +-+{ +-+ struct crypto_cipher *tfm; +-+ +-+ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); +-+ if (!IS_ERR(tfm)) +-+ crypto_cipher_setkey(tfm, key, key_len); +-+ +-+ return tfm; +-+} +-+ +-+ +-+void ieee80211_aes_key_free(struct crypto_cipher *tfm) +-+{ +-+ crypto_free_cipher(tfm); +-+} +---- a/net/mac80211/Kconfig +-+++ b/net/mac80211/Kconfig +-@@ -6,8 +6,6 @@ config MAC80211 +- depends on CRYPTO +- select BPAUTO_CRYPTO_LIB_ARC4 +- depends on CRYPTO_AES +-- depends on CRYPTO_CCM +-- depends on CRYPTO_GCM +- depends on CRYPTO_CMAC +- depends on CRC32 +- help +---- a/net/mac80211/aes_gmac.h +-+++ b/net/mac80211/aes_gmac.h +-@@ -12,10 +12,22 @@ +- #define GMAC_MIC_LEN 16 +- #define GMAC_NONCE_LEN 12 +- +--struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[], +-- size_t key_len); +--int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, +-- const u8 *data, size_t data_len, u8 *mic); +--void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm); +-+static inline struct crypto_aead * +-+ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len) +-+{ +-+ return NULL; +-+} +-+ +-+static inline int +-+ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, +-+ const u8 *data, size_t data_len, u8 *mic) +-+{ +-+ return -EOPNOTSUPP; +-+} +-+ +-+static inline void +-+ieee80211_aes_gmac_key_free(struct crypto_aead *tfm) +-+{ +-+} +- +- #endif /* AES_GMAC_H */ +---- a/net/mac80211/key.h +-+++ b/net/mac80211/key.h +-@@ -89,7 +89,7 @@ struct ieee80211_key { +- * Management frames. +- */ +- u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; +-- struct crypto_aead *tfm; +-+ struct crypto_cipher *tfm; +- u32 replays; /* dot11RSNAStatsCCMPReplays */ +- } ccmp; +- struct { +diff --git a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch +index c6fafb77b1..638da14346 100644 +--- a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch ++++ b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch +@@ -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 +-@@ -1307,7 +1307,6 @@ static int ieee80211_stop_ap(struct wiph ++@@ -1316,7 +1316,6 @@ static int ieee80211_stop_ap(struct wiph + sdata->vif.bss_conf.ftmr_params = NULL; + + __sta_info_flush(sdata, true); +diff --git a/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch b/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch +index 172e5b04fd..ffd8807ccc 100644 +--- a/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch ++++ b/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch +@@ -1,6 +1,6 @@ + --- a/net/wireless/sysfs.c + +++ b/net/wireless/sysfs.c +-@@ -23,18 +23,35 @@ static inline struct cfg80211_registered ++@@ -24,18 +24,35 @@ static inline struct cfg80211_registered + return container_of(dev, struct cfg80211_registered_device, wiphy.dev); + } + +diff --git a/package/kernel/mac80211/patches/subsys/130-disable-fils.patch b/package/kernel/mac80211/patches/subsys/130-disable-fils.patch +deleted file mode 100644 +index 9c6e971f9d..0000000000 +--- a/package/kernel/mac80211/patches/subsys/130-disable-fils.patch ++++ /dev/null +@@ -1,32 +0,0 @@ +-Disable FILS support, since it pulls in crypto hash support +- +---- a/net/mac80211/fils_aead.h +-+++ b/net/mac80211/fils_aead.h +-@@ -7,7 +7,7 @@ +- #ifndef FILS_AEAD_H +- #define FILS_AEAD_H +- +--#if LINUX_VERSION_IS_GEQ(4,3,0) +-+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ +- int fils_encrypt_assoc_req(struct sk_buff *skb, +- struct ieee80211_mgd_assoc_data *assoc_data); +- int fils_decrypt_assoc_resp(struct ieee80211_sub_if_data *sdata, +---- a/net/mac80211/fils_aead.c +-+++ b/net/mac80211/fils_aead.c +-@@ -1,4 +1,4 @@ +--#if LINUX_VERSION_IS_GEQ(4,3,0) +-+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ +- // SPDX-License-Identifier: GPL-2.0-only +- /* +- * FILS AEAD for (Re)Association Request/Response frames +---- a/net/mac80211/main.c +-+++ b/net/mac80211/main.c +-@@ -591,7 +591,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ +- NL80211_FEATURE_MAC_ON_CREATE | +- NL80211_FEATURE_USERSPACE_MPM | +- NL80211_FEATURE_FULL_AP_CLIENT_STATE; +--#if LINUX_VERSION_IS_GEQ(4,3,0) +-+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ +- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA); +- #endif +- wiphy_ext_feature_set(wiphy, +diff --git a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch b/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch +deleted file mode 100644 +index c3bf7ccc7a..0000000000 +--- a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch ++++ /dev/null +@@ -1,230 +0,0 @@ +-From: Felix Fietkau +-Date: Sat, 7 Oct 2017 09:37:28 +0200 +-Subject: [PATCH] Revert "mac80211: aes-cmac: switch to shash CMAC +- driver" +- +-This reverts commit 26717828b75dd5c46e97f7f4a9b937d038bb2852. +-Reduces mac80211 dependencies for LEDE +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/aes_cmac.c +-+++ b/net/mac80211/aes_cmac.c +-@@ -19,67 +19,151 @@ +- #define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */ +- #define AAD_LEN 20 +- +--static const u8 zero[CMAC_TLEN_256]; +- +--void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, +-+void gf_mulx(u8 *pad) +-+{ +-+ int i, carry; +-+ +-+ carry = pad[0] & 0x80; +-+ for (i = 0; i < AES_BLOCK_SIZE - 1; i++) +-+ pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); +-+ pad[AES_BLOCK_SIZE - 1] <<= 1; +-+ if (carry) +-+ pad[AES_BLOCK_SIZE - 1] ^= 0x87; +-+} +-+ +-+void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem, +-+ const u8 *addr[], const size_t *len, u8 *mac, +-+ size_t mac_len) +-+{ +-+ u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; +-+ const u8 *pos, *end; +-+ size_t i, e, left, total_len; +-+ +-+ memset(cbc, 0, AES_BLOCK_SIZE); +-+ +-+ total_len = 0; +-+ for (e = 0; e < num_elem; e++) +-+ total_len += len[e]; +-+ left = total_len; +-+ +-+ e = 0; +-+ pos = addr[0]; +-+ end = pos + len[0]; +-+ +-+ while (left >= AES_BLOCK_SIZE) { +-+ for (i = 0; i < AES_BLOCK_SIZE; i++) { +-+ cbc[i] ^= *pos++; +-+ if (pos >= end) { +-+ e++; +-+ pos = addr[e]; +-+ end = pos + len[e]; +-+ } +-+ } +-+ if (left > AES_BLOCK_SIZE) +-+ crypto_cipher_encrypt_one(tfm, cbc, cbc); +-+ left -= AES_BLOCK_SIZE; +-+ } +-+ +-+ memset(pad, 0, AES_BLOCK_SIZE); +-+ crypto_cipher_encrypt_one(tfm, pad, pad); +-+ gf_mulx(pad); +-+ +-+ if (left || total_len == 0) { +-+ for (i = 0; i < left; i++) { +-+ cbc[i] ^= *pos++; +-+ if (pos >= end) { +-+ e++; +-+ pos = addr[e]; +-+ end = pos + len[e]; +-+ } +-+ } +-+ cbc[left] ^= 0x80; +-+ gf_mulx(pad); +-+ } +-+ +-+ for (i = 0; i < AES_BLOCK_SIZE; i++) +-+ pad[i] ^= cbc[i]; +-+ crypto_cipher_encrypt_one(tfm, pad, pad); +-+ memcpy(mac, pad, mac_len); +-+} +-+ +-+ +-+void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic) +- { +-- SHASH_DESC_ON_STACK(desc, tfm); +-- u8 out[AES_BLOCK_SIZE]; +-+ const u8 *addr[4]; +-+ size_t len[4]; +-+ u8 zero[CMAC_TLEN]; +- const __le16 *fc; +- +-- desc->tfm = tfm; +-- +-- crypto_shash_init(desc); +-- crypto_shash_update(desc, aad, AAD_LEN); +-+ memset(zero, 0, CMAC_TLEN); +-+ addr[0] = aad; +-+ len[0] = AAD_LEN; +- fc = (const __le16 *)aad; +- if (ieee80211_is_beacon(*fc)) { +- /* mask Timestamp field to zero */ +-- crypto_shash_update(desc, zero, 8); +-- crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN); +-+ addr[1] = zero; +-+ len[1] = 8; +-+ addr[2] = data + 8; +-+ len[2] = data_len - 8 - CMAC_TLEN; +-+ addr[3] = zero; +-+ len[3] = CMAC_TLEN; +-+ aes_cmac_vector(tfm, 4, addr, len, mic, CMAC_TLEN); +- } else { +-- crypto_shash_update(desc, data, data_len - CMAC_TLEN); +-+ addr[1] = data; +-+ len[1] = data_len - CMAC_TLEN; +-+ addr[2] = zero; +-+ len[2] = CMAC_TLEN; +-+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN); +- } +-- crypto_shash_finup(desc, zero, CMAC_TLEN, out); +-- +-- memcpy(mic, out, CMAC_TLEN); +- } +- +--void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, +-+void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic) +- { +-- SHASH_DESC_ON_STACK(desc, tfm); +-+ const u8 *addr[4]; +-+ size_t len[4]; +-+ u8 zero[CMAC_TLEN_256]; +- const __le16 *fc; +- +-- desc->tfm = tfm; +-- +-- crypto_shash_init(desc); +-- crypto_shash_update(desc, aad, AAD_LEN); +-+ memset(zero, 0, CMAC_TLEN_256); +-+ addr[0] = aad; +-+ len[0] = AAD_LEN; +-+ addr[1] = data; +- fc = (const __le16 *)aad; +- if (ieee80211_is_beacon(*fc)) { +- /* mask Timestamp field to zero */ +-- crypto_shash_update(desc, zero, 8); +-- crypto_shash_update(desc, data + 8, +-- data_len - 8 - CMAC_TLEN_256); +-+ addr[1] = zero; +-+ len[1] = 8; +-+ addr[2] = data + 8; +-+ len[2] = data_len - 8 - CMAC_TLEN_256; +-+ addr[3] = zero; +-+ len[3] = CMAC_TLEN_256; +-+ aes_cmac_vector(tfm, 4, addr, len, mic, CMAC_TLEN_256); +- } else { +-- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); +-+ addr[1] = data; +-+ len[1] = data_len - CMAC_TLEN_256; +-+ addr[2] = zero; +-+ len[2] = CMAC_TLEN_256; +-+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256); +- } +-- crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); +- } +- +--struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], +-- size_t key_len) +-+struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], +-+ size_t key_len) +- { +-- struct crypto_shash *tfm; +-+ struct crypto_cipher *tfm; +- +-- tfm = crypto_alloc_shash("cmac(aes)", 0, 0); +-+ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); +- if (!IS_ERR(tfm)) +-- crypto_shash_setkey(tfm, key, key_len); +-+ crypto_cipher_setkey(tfm, key, key_len); +- +- return tfm; +- } +- +--void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm) +-+ +-+void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) +- { +-- crypto_free_shash(tfm); +-+ crypto_free_cipher(tfm); +- } +---- a/net/mac80211/aes_cmac.h +-+++ b/net/mac80211/aes_cmac.h +-@@ -7,14 +7,13 @@ +- #define AES_CMAC_H +- +- #include +--#include +- +--struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], +-- size_t key_len); +--void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, +-+struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], +-+ size_t key_len); +-+void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic); +--void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, +-+void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic); +--void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); +-+void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); +- +- #endif /* AES_CMAC_H */ +---- a/net/mac80211/key.h +-+++ b/net/mac80211/key.h +-@@ -94,7 +94,7 @@ struct ieee80211_key { +- } ccmp; +- struct { +- u8 rx_pn[IEEE80211_CMAC_PN_LEN]; +-- struct crypto_shash *tfm; +-+ struct crypto_cipher *tfm; +- u32 replays; /* dot11RSNAStatsCMACReplays */ +- u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ +- } aes_cmac; +diff --git a/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch b/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch +deleted file mode 100644 +index df67d2f101..0000000000 +--- a/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch ++++ /dev/null +@@ -1,10 +0,0 @@ +---- a/net/mac80211/Kconfig +-+++ b/net/mac80211/Kconfig +-@@ -6,7 +6,6 @@ config MAC80211 +- depends on CRYPTO +- select BPAUTO_CRYPTO_LIB_ARC4 +- depends on CRYPTO_AES +-- depends on CRYPTO_CMAC +- depends on CRC32 +- help +- This option enables the hardware independent IEEE 802.11 +diff --git a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch b/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch +index 8d086625e4..e93efa4429 100644 +--- a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch ++++ b/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch +@@ -1,6 +1,6 @@ + --- a/net/mac80211/main.c + +++ b/net/mac80211/main.c +-@@ -321,7 +321,7 @@ void ieee80211_restart_hw(struct ieee802 ++@@ -337,7 +337,7 @@ void ieee80211_restart_hw(struct ieee802 + } + EXPORT_SYMBOL(ieee80211_restart_hw); + +@@ -9,7 +9,7 @@ + static int ieee80211_ifa_changed(struct notifier_block *nb, + unsigned long data, void *arg) + { +-@@ -380,7 +380,7 @@ static int ieee80211_ifa_changed(struct ++@@ -396,7 +396,7 @@ static int ieee80211_ifa_changed(struct + } + #endif + +@@ -18,8 +18,8 @@ + static int ieee80211_ifa6_changed(struct notifier_block *nb, + unsigned long data, void *arg) + { +-@@ -1315,14 +1315,14 @@ int ieee80211_register_hw(struct ieee802 +- ++@@ -1324,14 +1324,14 @@ int ieee80211_register_hw(struct ieee802 ++ wiphy_unlock(hw->wiphy); + rtnl_unlock(); + + -#ifdef CONFIG_INET +@@ -35,7 +35,7 @@ + local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; + result = register_inet6addr_notifier(&local->ifa6_notifier); + if (result) +-@@ -1331,13 +1331,13 @@ int ieee80211_register_hw(struct ieee802 ++@@ -1340,13 +1340,13 @@ int ieee80211_register_hw(struct ieee802 + + return 0; + +@@ -52,7 +52,7 @@ + fail_ifa: + #endif + wiphy_unregister(local->hw.wiphy); +-@@ -1365,10 +1365,10 @@ void ieee80211_unregister_hw(struct ieee ++@@ -1374,10 +1374,10 @@ void ieee80211_unregister_hw(struct ieee + tasklet_kill(&local->tx_pending_tasklet); + tasklet_kill(&local->tasklet); + +diff --git a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch +index f8c3821c51..0c06829ce4 100644 +--- a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch ++++ b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch +@@ -1,6 +1,6 @@ + --- a/net/mac80211/cfg.c + +++ b/net/mac80211/cfg.c +-@@ -2463,7 +2463,7 @@ static int ieee80211_scan(struct wiphy * ++@@ -2497,7 +2497,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/300-cfg80211-support-immediate-reconnect-request-hint.patch b/package/kernel/mac80211/patches/subsys/300-cfg80211-support-immediate-reconnect-request-hint.patch +deleted file mode 100644 +index 425b6895b1..0000000000 +--- a/package/kernel/mac80211/patches/subsys/300-cfg80211-support-immediate-reconnect-request-hint.patch ++++ /dev/null +@@ -1,279 +0,0 @@ +-From: Johannes Berg +-Date: Sun, 6 Dec 2020 14:54:42 +0200 +-Subject: [PATCH] cfg80211: support immediate reconnect request hint +- +-There are cases where it's necessary to disconnect, but an +-immediate reconnection is desired. Support a hint to userspace +-that this is the case, by including a new attribute in the +-deauth or disassoc event. +- +-Signed-off-by: Luca Coelho +-Link: https://lore.kernel.org/r/iwlwifi.20201206145305.58d33941fb9d.I0e7168c205c7949529c8e3b86f3c9b12c01a7017@changeid +-Signed-off-by: Johannes Berg +---- +- +---- a/include/net/cfg80211.h +-+++ b/include/net/cfg80211.h +-@@ -6410,13 +6410,15 @@ void cfg80211_abandon_assoc(struct net_d +- * @dev: network device +- * @buf: 802.11 frame (header + body) +- * @len: length of the frame data +-+ * @reconnect: immediate reconnect is desired (include the nl80211 attribute) +- * +- * This function is called whenever deauthentication has been processed in +- * station mode. This includes both received deauthentication frames and +- * locally generated ones. This function may sleep. The caller must hold the +- * corresponding wdev's mutex. +- */ +--void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len); +-+void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len, +-+ bool reconnect); +- +- /** +- * cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame +---- a/net/mac80211/mlme.c +-+++ b/net/mac80211/mlme.c +-@@ -2725,7 +2725,7 @@ static void ieee80211_report_disconnect( +- }; +- +- if (tx) +-- cfg80211_tx_mlme_mgmt(sdata->dev, buf, len); +-+ cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, false); +- else +- cfg80211_rx_mlme_mgmt(sdata->dev, buf, len); +- +-@@ -4719,7 +4719,8 @@ void ieee80211_mgd_quiesce(struct ieee80 +- if (ifmgd->auth_data) +- ieee80211_destroy_auth_data(sdata, false); +- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, +-- IEEE80211_DEAUTH_FRAME_LEN); +-+ IEEE80211_DEAUTH_FRAME_LEN, +-+ false); +- } +- +- /* This is a bit of a hack - we should find a better and more generic +---- a/net/wireless/mlme.c +-+++ b/net/wireless/mlme.c +-@@ -4,7 +4,7 @@ +- * +- * Copyright (c) 2009, Jouni Malinen +- * Copyright (c) 2015 Intel Deutschland GmbH +-- * Copyright (C) 2019 Intel Corporation +-+ * Copyright (C) 2019-2020 Intel Corporation +- */ +- +- #include +-@@ -81,7 +81,8 @@ static void cfg80211_process_auth(struct +- } +- +- static void cfg80211_process_deauth(struct wireless_dev *wdev, +-- const u8 *buf, size_t len) +-+ const u8 *buf, size_t len, +-+ bool reconnect) +- { +- struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); +- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; +-@@ -89,7 +90,7 @@ static void cfg80211_process_deauth(stru +- u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); +- bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr); +- +-- nl80211_send_deauth(rdev, wdev->netdev, buf, len, GFP_KERNEL); +-+ nl80211_send_deauth(rdev, wdev->netdev, buf, len, reconnect, GFP_KERNEL); +- +- if (!wdev->current_bss || +- !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) +-@@ -100,7 +101,8 @@ static void cfg80211_process_deauth(stru +- } +- +- static void cfg80211_process_disassoc(struct wireless_dev *wdev, +-- const u8 *buf, size_t len) +-+ const u8 *buf, size_t len, +-+ bool reconnect) +- { +- struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); +- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; +-@@ -108,7 +110,8 @@ static void cfg80211_process_disassoc(st +- u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); +- bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr); +- +-- nl80211_send_disassoc(rdev, wdev->netdev, buf, len, GFP_KERNEL); +-+ nl80211_send_disassoc(rdev, wdev->netdev, buf, len, reconnect, +-+ GFP_KERNEL); +- +- if (WARN_ON(!wdev->current_bss || +- !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) +-@@ -133,9 +136,9 @@ void cfg80211_rx_mlme_mgmt(struct net_de +- if (ieee80211_is_auth(mgmt->frame_control)) +- cfg80211_process_auth(wdev, buf, len); +- else if (ieee80211_is_deauth(mgmt->frame_control)) +-- cfg80211_process_deauth(wdev, buf, len); +-+ cfg80211_process_deauth(wdev, buf, len, false); +- else if (ieee80211_is_disassoc(mgmt->frame_control)) +-- cfg80211_process_disassoc(wdev, buf, len); +-+ cfg80211_process_disassoc(wdev, buf, len, false); +- } +- EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt); +- +-@@ -180,22 +183,23 @@ void cfg80211_abandon_assoc(struct net_d +- } +- EXPORT_SYMBOL(cfg80211_abandon_assoc); +- +--void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len) +-+void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len, +-+ bool reconnect) +- { +- struct wireless_dev *wdev = dev->ieee80211_ptr; +- struct ieee80211_mgmt *mgmt = (void *)buf; +- +- ASSERT_WDEV_LOCK(wdev); +- +-- trace_cfg80211_tx_mlme_mgmt(dev, buf, len); +-+ trace_cfg80211_tx_mlme_mgmt(dev, buf, len, reconnect); +- +- if (WARN_ON(len < 2)) +- return; +- +- if (ieee80211_is_deauth(mgmt->frame_control)) +-- cfg80211_process_deauth(wdev, buf, len); +-+ cfg80211_process_deauth(wdev, buf, len, reconnect); +- else +-- cfg80211_process_disassoc(wdev, buf, len); +-+ cfg80211_process_disassoc(wdev, buf, len, reconnect); +- } +- EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt); +- +---- a/net/wireless/nl80211.c +-+++ b/net/wireless/nl80211.c +-@@ -736,6 +736,7 @@ static const struct nla_policy nl80211_p +- NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN), +- [NL80211_ATTR_S1G_CAPABILITY_MASK] = +- NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN), +-+ [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT }, +- }; +- +- /* policy for the key attributes */ +-@@ -15902,7 +15903,7 @@ static void nl80211_send_mlme_event(stru +- const u8 *buf, size_t len, +- enum nl80211_commands cmd, gfp_t gfp, +- int uapsd_queues, const u8 *req_ies, +-- size_t req_ies_len) +-+ size_t req_ies_len, bool reconnect) +- { +- struct sk_buff *msg; +- void *hdr; +-@@ -15924,6 +15925,9 @@ static void nl80211_send_mlme_event(stru +- nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies))) +- goto nla_put_failure; +- +-+ if (reconnect && nla_put_flag(msg, NL80211_ATTR_RECONNECT_REQUESTED)) +-+ goto nla_put_failure; +-+ +- if (uapsd_queues >= 0) { +- struct nlattr *nla_wmm = +- nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME); +-@@ -15952,7 +15956,8 @@ void nl80211_send_rx_auth(struct cfg8021 +- size_t len, gfp_t gfp) +- { +- nl80211_send_mlme_event(rdev, netdev, buf, len, +-- NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0); +-+ NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0, +-+ false); +- } +- +- void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, +-@@ -15962,23 +15967,25 @@ void nl80211_send_rx_assoc(struct cfg802 +- { +- nl80211_send_mlme_event(rdev, netdev, buf, len, +- NL80211_CMD_ASSOCIATE, gfp, uapsd_queues, +-- req_ies, req_ies_len); +-+ req_ies, req_ies_len, false); +- } +- +- void nl80211_send_deauth(struct cfg80211_registered_device *rdev, +- struct net_device *netdev, const u8 *buf, +-- size_t len, gfp_t gfp) +-+ size_t len, bool reconnect, gfp_t gfp) +- { +- nl80211_send_mlme_event(rdev, netdev, buf, len, +-- NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0); +-+ NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0, +-+ reconnect); +- } +- +- void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, +- struct net_device *netdev, const u8 *buf, +-- size_t len, gfp_t gfp) +-+ size_t len, bool reconnect, gfp_t gfp) +- { +- nl80211_send_mlme_event(rdev, netdev, buf, len, +-- NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0); +-+ NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0, +-+ reconnect); +- } +- +- void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, +-@@ -16009,7 +16016,7 @@ void cfg80211_rx_unprot_mlme_mgmt(struct +- +- trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); +- nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1, +-- NULL, 0); +-+ NULL, 0, false); +- } +- EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt); +- +---- a/net/wireless/nl80211.h +-+++ b/net/wireless/nl80211.h +-@@ -1,7 +1,7 @@ +- /* SPDX-License-Identifier: GPL-2.0 */ +- /* +- * Portions of this file +-- * Copyright (C) 2018 Intel Corporation +-+ * Copyright (C) 2018, 2020 Intel Corporation +- */ +- #ifndef __NET_WIRELESS_NL80211_H +- #define __NET_WIRELESS_NL80211_H +-@@ -69,10 +69,12 @@ void nl80211_send_rx_assoc(struct cfg802 +- const u8 *req_ies, size_t req_ies_len); +- void nl80211_send_deauth(struct cfg80211_registered_device *rdev, +- struct net_device *netdev, +-- const u8 *buf, size_t len, gfp_t gfp); +-+ const u8 *buf, size_t len, +-+ bool reconnect, gfp_t gfp); +- void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, +- struct net_device *netdev, +-- const u8 *buf, size_t len, gfp_t gfp); +-+ const u8 *buf, size_t len, +-+ bool reconnect, gfp_t gfp); +- void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, +- struct net_device *netdev, +- const u8 *addr, gfp_t gfp); +---- a/net/wireless/trace.h +-+++ b/net/wireless/trace.h +-@@ -2684,19 +2684,23 @@ DEFINE_EVENT(netdev_frame_event, cfg8021 +- ); +- +- TRACE_EVENT(cfg80211_tx_mlme_mgmt, +-- TP_PROTO(struct net_device *netdev, const u8 *buf, int len), +-- TP_ARGS(netdev, buf, len), +-+ TP_PROTO(struct net_device *netdev, const u8 *buf, int len, +-+ bool reconnect), +-+ TP_ARGS(netdev, buf, len, reconnect), +- TP_STRUCT__entry( +- NETDEV_ENTRY +- __dynamic_array(u8, frame, len) +-+ __field(int, reconnect) +- ), +- TP_fast_assign( +- NETDEV_ASSIGN; +- memcpy(__get_dynamic_array(frame), buf, len); +-+ __entry->reconnect = reconnect; +- ), +-- TP_printk(NETDEV_PR_FMT ", ftype:0x%.2x", +-+ TP_printk(NETDEV_PR_FMT ", ftype:0x%.2x reconnect:%d", +- NETDEV_PR_ARG, +-- le16_to_cpup((__le16 *)__get_dynamic_array(frame))) +-+ le16_to_cpup((__le16 *)__get_dynamic_array(frame)), +-+ __entry->reconnect) +- ); +- +- DECLARE_EVENT_CLASS(netdev_mac_evt, +diff --git a/package/kernel/mac80211/patches/subsys/394-mac80211-fix-rate-control-for-retransmitted-frames.patch b/package/kernel/mac80211/patches/subsys/301-mac80211-fix-rate-control-for-retransmitted-frames.patch +similarity index 94% +rename from package/kernel/mac80211/patches/subsys/394-mac80211-fix-rate-control-for-retransmitted-frames.patch +rename to package/kernel/mac80211/patches/subsys/301-mac80211-fix-rate-control-for-retransmitted-frames.patch +index cd91a925f3..98dfe88cbd 100644 +--- a/package/kernel/mac80211/patches/subsys/394-mac80211-fix-rate-control-for-retransmitted-frames.patch ++++ b/package/kernel/mac80211/patches/subsys/301-mac80211-fix-rate-control-for-retransmitted-frames.patch +@@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau + + --- a/net/mac80211/tx.c + +++ b/net/mac80211/tx.c +-@@ -1835,15 +1835,15 @@ static int invoke_tx_handlers_late(struc ++@@ -1821,15 +1821,15 @@ static int invoke_tx_handlers_late(struc + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); + ieee80211_tx_result res = TX_CONTINUE; + +diff --git a/package/kernel/mac80211/patches/subsys/301-mac80211-support-driver-based-disconnect-with-reconn.patch b/package/kernel/mac80211/patches/subsys/301-mac80211-support-driver-based-disconnect-with-reconn.patch +deleted file mode 100644 +index cc9602df71..0000000000 +--- a/package/kernel/mac80211/patches/subsys/301-mac80211-support-driver-based-disconnect-with-reconn.patch ++++ /dev/null +@@ -1,271 +0,0 @@ +-From: Johannes Berg +-Date: Sun, 6 Dec 2020 14:54:43 +0200 +-Subject: [PATCH] mac80211: support driver-based disconnect with reconnect hint +- +-Support the driver indicating that a disconnection needs +-to be performed, and pass through the reconnect hint in +-this case. +- +-Signed-off-by: Johannes Berg +-Signed-off-by: Luca Coelho +-Link: https://lore.kernel.org/r/iwlwifi.20201206145305.5c8dab7a22a0.I58459fdf6968b16c90cab9c574f0f04ca22b0c79@changeid +-Signed-off-by: Johannes Berg +---- +- +---- a/include/net/mac80211.h +-+++ b/include/net/mac80211.h +-@@ -5885,6 +5885,17 @@ void ieee80211_beacon_loss(struct ieee80 +- void ieee80211_connection_loss(struct ieee80211_vif *vif); +- +- /** +-+ * ieee80211_disconnect - request disconnection +-+ * +-+ * @vif: &struct ieee80211_vif pointer from the add_interface callback. +-+ * @reconnect: immediate reconnect is desired +-+ * +-+ * Request disconnection from the current network and, if enabled, send a +-+ * hint to the higher layers that immediate reconnect is desired. +-+ */ +-+void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect); +-+ +-+/** +- * ieee80211_resume_disconnect - disconnect from AP after resume +- * +- * @vif: &struct ieee80211_vif pointer from the add_interface callback. +---- a/net/mac80211/ieee80211_i.h +-+++ b/net/mac80211/ieee80211_i.h +-@@ -450,7 +450,9 @@ struct ieee80211_if_managed { +- unsigned long probe_timeout; +- int probe_send_count; +- bool nullfunc_failed; +-- bool connection_loss; +-+ u8 connection_loss:1, +-+ driver_disconnect:1, +-+ reconnect:1; +- +- struct cfg80211_bss *associated; +- struct ieee80211_mgd_auth_data *auth_data; +---- a/net/mac80211/mlme.c +-+++ b/net/mac80211/mlme.c +-@@ -2716,7 +2716,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get) +- +- static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata, +- const u8 *buf, size_t len, bool tx, +-- u16 reason) +-+ u16 reason, bool reconnect) +- { +- struct ieee80211_event event = { +- .type = MLME_EVENT, +-@@ -2725,7 +2725,7 @@ static void ieee80211_report_disconnect( +- }; +- +- if (tx) +-- cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, false); +-+ cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, reconnect); +- else +- cfg80211_rx_mlme_mgmt(sdata->dev, buf, len); +- +-@@ -2747,13 +2747,18 @@ static void __ieee80211_disconnect(struc +- +- tx = !sdata->csa_block_tx; +- +-- /* AP is probably out of range (or not reachable for another reason) so +-- * remove the bss struct for that AP. +-- */ +-- cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated); +-+ if (!ifmgd->driver_disconnect) { +-+ /* +-+ * AP is probably out of range (or not reachable for another +-+ * reason) so remove the bss struct for that AP. +-+ */ +-+ cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated); +-+ } +- +- ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, +-- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, +-+ ifmgd->driver_disconnect ? +-+ WLAN_REASON_DEAUTH_LEAVING : +-+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, +- tx, frame_buf); +- mutex_lock(&local->mtx); +- sdata->vif.csa_active = false; +-@@ -2766,7 +2771,9 @@ static void __ieee80211_disconnect(struc +- mutex_unlock(&local->mtx); +- +- ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx, +-- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); +-+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, +-+ ifmgd->reconnect); +-+ ifmgd->reconnect = false; +- +- sdata_unlock(sdata); +- } +-@@ -2785,6 +2792,13 @@ static void ieee80211_beacon_connection_ +- sdata_info(sdata, "Connection to AP %pM lost\n", +- ifmgd->bssid); +- __ieee80211_disconnect(sdata); +-+ ifmgd->connection_loss = false; +-+ } else if (ifmgd->driver_disconnect) { +-+ sdata_info(sdata, +-+ "Driver requested disconnection from AP %pM\n", +-+ ifmgd->bssid); +-+ __ieee80211_disconnect(sdata); +-+ ifmgd->driver_disconnect = false; +- } else { +- ieee80211_mgd_probe_ap(sdata, true); +- } +-@@ -2823,6 +2837,21 @@ void ieee80211_connection_loss(struct ie +- } +- EXPORT_SYMBOL(ieee80211_connection_loss); +- +-+void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect) +-+{ +-+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); +-+ struct ieee80211_hw *hw = &sdata->local->hw; +-+ +-+ trace_api_disconnect(sdata, reconnect); +-+ +-+ if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) +-+ return; +-+ +-+ sdata->u.mgd.driver_disconnect = true; +-+ sdata->u.mgd.reconnect = reconnect; +-+ ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work); +-+} +-+EXPORT_SYMBOL(ieee80211_disconnect); +- +- static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, +- bool assoc) +-@@ -3126,7 +3155,7 @@ static void ieee80211_rx_mgmt_deauth(str +- ieee80211_set_disassoc(sdata, 0, 0, false, NULL); +- +- ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, +-- reason_code); +-+ reason_code, false); +- return; +- } +- +-@@ -3175,7 +3204,8 @@ static void ieee80211_rx_mgmt_disassoc(s +- +- ieee80211_set_disassoc(sdata, 0, 0, false, NULL); +- +-- ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code); +-+ ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code, +-+ false); +- } +- +- static void ieee80211_get_rates(struct ieee80211_supported_band *sband, +-@@ -4199,7 +4229,8 @@ static void ieee80211_rx_mgmt_beacon(str +- true, deauth_buf); +- ieee80211_report_disconnect(sdata, deauth_buf, +- sizeof(deauth_buf), true, +-- WLAN_REASON_DEAUTH_LEAVING); +-+ WLAN_REASON_DEAUTH_LEAVING, +-+ false); +- return; +- } +- +-@@ -4344,7 +4375,7 @@ static void ieee80211_sta_connection_los +- tx, frame_buf); +- +- ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, +-- reason); +-+ reason, false); +- } +- +- static int ieee80211_auth(struct ieee80211_sub_if_data *sdata) +-@@ -5434,7 +5465,8 @@ int ieee80211_mgd_auth(struct ieee80211_ +- +- ieee80211_report_disconnect(sdata, frame_buf, +- sizeof(frame_buf), true, +-- WLAN_REASON_UNSPECIFIED); +-+ WLAN_REASON_UNSPECIFIED, +-+ false); +- } +- +- sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); +-@@ -5506,7 +5538,8 @@ int ieee80211_mgd_assoc(struct ieee80211 +- +- ieee80211_report_disconnect(sdata, frame_buf, +- sizeof(frame_buf), true, +-- WLAN_REASON_UNSPECIFIED); +-+ WLAN_REASON_UNSPECIFIED, +-+ false); +- } +- +- if (ifmgd->auth_data && !ifmgd->auth_data->done) { +-@@ -5809,7 +5842,7 @@ int ieee80211_mgd_deauth(struct ieee8021 +- ieee80211_destroy_auth_data(sdata, false); +- ieee80211_report_disconnect(sdata, frame_buf, +- sizeof(frame_buf), true, +-- req->reason_code); +-+ req->reason_code, false); +- +- return 0; +- } +-@@ -5829,7 +5862,7 @@ int ieee80211_mgd_deauth(struct ieee8021 +- ieee80211_destroy_assoc_data(sdata, false, true); +- ieee80211_report_disconnect(sdata, frame_buf, +- sizeof(frame_buf), true, +-- req->reason_code); +-+ req->reason_code, false); +- return 0; +- } +- +-@@ -5844,7 +5877,7 @@ int ieee80211_mgd_deauth(struct ieee8021 +- req->reason_code, tx, frame_buf); +- ieee80211_report_disconnect(sdata, frame_buf, +- sizeof(frame_buf), true, +-- req->reason_code); +-+ req->reason_code, false); +- return 0; +- } +- +-@@ -5877,7 +5910,7 @@ int ieee80211_mgd_disassoc(struct ieee80 +- frame_buf); +- +- ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, +-- req->reason_code); +-+ req->reason_code, false); +- +- return 0; +- } +---- a/net/mac80211/trace.h +-+++ b/net/mac80211/trace.h +-@@ -2,7 +2,7 @@ +- /* +- * Portions of this file +- * Copyright(c) 2016-2017 Intel Deutschland GmbH +--* Copyright (C) 2018 - 2019 Intel Corporation +-+* Copyright (C) 2018 - 2020 Intel Corporation +- */ +- +- #if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ) +-@@ -2086,6 +2086,27 @@ TRACE_EVENT(api_connection_loss, +- ) +- ); +- +-+TRACE_EVENT(api_disconnect, +-+ TP_PROTO(struct ieee80211_sub_if_data *sdata, bool reconnect), +-+ +-+ TP_ARGS(sdata, reconnect), +-+ +-+ TP_STRUCT__entry( +-+ VIF_ENTRY +-+ __field(int, reconnect) +-+ ), +-+ +-+ TP_fast_assign( +-+ VIF_ASSIGN; +-+ __entry->reconnect = reconnect; +-+ ), +-+ +-+ TP_printk( +-+ VIF_PR_FMT " reconnect:%d", +-+ VIF_PR_ARG, __entry->reconnect +-+ ) +-+); +-+ +- TRACE_EVENT(api_cqm_rssi_notify, +- TP_PROTO(struct ieee80211_sub_if_data *sdata, +- enum nl80211_cqm_rssi_threshold_event rssi_event, +diff --git a/package/kernel/mac80211/patches/subsys/302-cfg80211-Add-support-to-configure-SAE-PWE-value-to-d.patch b/package/kernel/mac80211/patches/subsys/302-cfg80211-Add-support-to-configure-SAE-PWE-value-to-d.patch +deleted file mode 100644 +index da88d1413d..0000000000 +--- a/package/kernel/mac80211/patches/subsys/302-cfg80211-Add-support-to-configure-SAE-PWE-value-to-d.patch ++++ /dev/null +@@ -1,74 +0,0 @@ +-From: Rohan Dutta +-Date: Tue, 27 Oct 2020 12:09:10 +0200 +-Subject: [PATCH] cfg80211: Add support to configure SAE PWE value to drivers +- +-Add support to configure SAE PWE preference from userspace to drivers in +-both AP and STA modes. This is needed for cases where the driver takes +-care of Authentication frame processing (SME in the driver) so that +-correct enforcement of the acceptable PWE derivation mechanism can be +-performed. +- +-The userspace applications can pass the sae_pwe value using the +-NL80211_ATTR_SAE_PWE attribute in the NL80211_CMD_CONNECT and +-NL80211_CMD_START_AP commands to the driver. This allows selection +-between the hunting-and-pecking loop and hash-to-element options for PWE +-derivation. For backwards compatibility, this new attribute is optional +-and if not included, the driver is notified of the value being +-unspecified. +- +-Signed-off-by: Rohan Dutta +-Signed-off-by: Jouni Malinen +-Link: https://lore.kernel.org/r/20201027100910.22283-1-jouni@codeaurora.org +-Signed-off-by: Johannes Berg +---- +- +---- a/include/net/cfg80211.h +-+++ b/include/net/cfg80211.h +-@@ -1009,6 +1009,14 @@ struct survey_info { +- * @sae_pwd: password for SAE authentication (for devices supporting SAE +- * offload) +- * @sae_pwd_len: length of SAE password (for devices supporting SAE offload) +-+ * @sae_pwe: The mechanisms allowed for SAE PWE derivation +-+ * NL80211_SAE_PWE_UNSPECIFIED: Not-specified, used to indicate userspace +-+ * did not specify any preference. The driver should follow its +-+ * internal policy in such a scenario. +-+ * NL80211_SAE_PWE_HUNT_AND_PECK: Allow hunting-and-pecking loop only +-+ * NL80211_SAE_PWE_HASH_TO_ELEMENT: Allow hash-to-element only +-+ * NL80211_SAE_PWE_BOTH: Allow either hunting-and-pecking loop +-+ * or hash-to-element +- */ +- struct cfg80211_crypto_settings { +- u32 wpa_versions; +-@@ -1027,6 +1035,7 @@ struct cfg80211_crypto_settings { +- const u8 *psk; +- const u8 *sae_pwd; +- u8 sae_pwd_len; +-+ enum nl80211_sae_pwe_mechanism sae_pwe; +- }; +- +- /** +---- a/net/wireless/nl80211.c +-+++ b/net/wireless/nl80211.c +-@@ -736,6 +736,9 @@ static const struct nla_policy nl80211_p +- NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN), +- [NL80211_ATTR_S1G_CAPABILITY_MASK] = +- NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN), +-+ [NL80211_ATTR_SAE_PWE] = +-+ NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK, +-+ NL80211_SAE_PWE_BOTH), +- [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT }, +- }; +- +-@@ -9763,6 +9766,12 @@ static int nl80211_crypto_settings(struc +- nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]); +- } +- +-+ if (info->attrs[NL80211_ATTR_SAE_PWE]) +-+ settings->sae_pwe = +-+ nla_get_u8(info->attrs[NL80211_ATTR_SAE_PWE]); +-+ else +-+ settings->sae_pwe = NL80211_SAE_PWE_UNSPECIFIED; +-+ +- return 0; +- } +- +diff --git a/package/kernel/mac80211/patches/subsys/305-mac80211-fix-regression-in-SSN-handling-of-addba-tx.patch b/package/kernel/mac80211/patches/subsys/305-mac80211-fix-regression-in-SSN-handling-of-addba-tx.patch +index 6ffdffc562..dc8afb9186 100644 +--- a/package/kernel/mac80211/patches/subsys/305-mac80211-fix-regression-in-SSN-handling-of-addba-tx.patch ++++ b/package/kernel/mac80211/patches/subsys/305-mac80211-fix-regression-in-SSN-handling-of-addba-tx.patch +@@ -34,7 +34,7 @@ Signed-off-by: Felix Fietkau + } else if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) { + --- a/net/mac80211/sta_info.h + +++ b/net/mac80211/sta_info.h +-@@ -190,6 +190,7 @@ struct tid_ampdu_tx { ++@@ -199,6 +199,7 @@ struct tid_ampdu_tx { + u8 stop_initiator; + bool tx_stop; + u16 buf_size; +diff --git a/package/kernel/mac80211/patches/subsys/306-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch b/package/kernel/mac80211/patches/subsys/306-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch +index c8cac93354..1ceb2be25c 100644 +--- a/package/kernel/mac80211/patches/subsys/306-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch ++++ b/package/kernel/mac80211/patches/subsys/306-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch +@@ -52,7 +52,7 @@ Signed-off-by: Xing Song + + --- a/net/mac80211/rx.c + +++ b/net/mac80211/rx.c +-@@ -2940,6 +2940,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 ++@@ -2948,6 +2948,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 + if (!fwd_skb) + goto out; + +diff --git a/package/kernel/mac80211/patches/subsys/307-mac80211-do-not-access-the-IV-when-it-was-stripped.patch b/package/kernel/mac80211/patches/subsys/307-mac80211-do-not-access-the-IV-when-it-was-stripped.patch +deleted file mode 100644 +index b50499d58a..0000000000 +--- a/package/kernel/mac80211/patches/subsys/307-mac80211-do-not-access-the-IV-when-it-was-stripped.patch ++++ /dev/null +@@ -1,26 +0,0 @@ +-From: Xing Song +-Date: Mon, 1 Nov 2021 10:46:57 +0800 +-Subject: [PATCH] mac80211: do not access the IV when it was stripped +- +-ieee80211_get_keyid() will return false value if IV has been stripped, +-such as return 0 for IP/ARP frames due to LLC header, and return -EINVAL +-for disassociation frames due to its length... etc. Don't try to access +-it if it's not present. +- +-Signed-off-by: Xing Song +-Link: https://lore.kernel.org/r/20211101024657.143026-1-xing.song@mediatek.com +-Signed-off-by: Johannes Berg +---- +- +---- a/net/mac80211/rx.c +-+++ b/net/mac80211/rx.c +-@@ -1945,7 +1945,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_ +- int keyid = rx->sta->ptk_idx; +- sta_ptk = rcu_dereference(rx->sta->ptk[keyid]); +- +-- if (ieee80211_has_protected(fc)) { +-+ if (ieee80211_has_protected(fc) && +-+ !(status->flag & RX_FLAG_IV_STRIPPED)) { +- cs = rx->sta->cipher_scheme; +- keyid = ieee80211_get_keyid(rx->skb, cs); +- +diff --git a/package/kernel/mac80211/patches/subsys/308-mac80211-send-ADDBA-requests-using-the-tid-queue-of-.patch b/package/kernel/mac80211/patches/subsys/309-mac80211-send-ADDBA-requests-using-the-tid-queue-of-.patch +similarity index 100% +rename from package/kernel/mac80211/patches/subsys/308-mac80211-send-ADDBA-requests-using-the-tid-queue-of-.patch +rename to package/kernel/mac80211/patches/subsys/309-mac80211-send-ADDBA-requests-using-the-tid-queue-of-.patch +diff --git a/package/kernel/mac80211/patches/subsys/309-mac80211-agg-tx-don-t-schedule_and_wake_txq-under-st.patch b/package/kernel/mac80211/patches/subsys/310-mac80211-agg-tx-don-t-schedule_and_wake_txq-under-st.patch +similarity index 100% +rename from package/kernel/mac80211/patches/subsys/309-mac80211-agg-tx-don-t-schedule_and_wake_txq-under-st.patch +rename to package/kernel/mac80211/patches/subsys/310-mac80211-agg-tx-don-t-schedule_and_wake_txq-under-st.patch +diff --git a/package/kernel/mac80211/patches/subsys/310-net-fq_impl-bulk-free-packets-from-a-flow-on-overmem.patch b/package/kernel/mac80211/patches/subsys/310-net-fq_impl-bulk-free-packets-from-a-flow-on-overmem.patch +deleted file mode 100644 +index 05a888006e..0000000000 +--- a/package/kernel/mac80211/patches/subsys/310-net-fq_impl-bulk-free-packets-from-a-flow-on-overmem.patch ++++ /dev/null +@@ -1,95 +0,0 @@ +-From: Felix Fietkau +-Date: Wed, 25 Nov 2020 18:03:46 +0100 +-Subject: [PATCH] net/fq_impl: bulk-free packets from a flow on overmemory +- +-This is similar to what sch_fq_codel does. It also amortizes the worst +-case cost of a follow-up patch that changes the selection of the biggest +-flow for dropping packets +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/include/net/fq_impl.h +-+++ b/include/net/fq_impl.h +-@@ -11,17 +11,25 @@ +- +- /* functions that are embedded into includer */ +- +-+ +-+static void +-+__fq_adjust_removal(struct fq *fq, struct fq_flow *flow, unsigned int packets, +-+ unsigned int bytes, unsigned int truesize) +-+{ +-+ struct fq_tin *tin = flow->tin; +-+ +-+ tin->backlog_bytes -= bytes; +-+ tin->backlog_packets -= packets; +-+ flow->backlog -= bytes; +-+ fq->backlog -= packets; +-+ fq->memory_usage -= truesize; +-+} +-+ +- static void fq_adjust_removal(struct fq *fq, +- struct fq_flow *flow, +- struct sk_buff *skb) +- { +-- struct fq_tin *tin = flow->tin; +-- +-- tin->backlog_bytes -= skb->len; +-- tin->backlog_packets--; +-- flow->backlog -= skb->len; +-- fq->backlog--; +-- fq->memory_usage -= skb->truesize; +-+ __fq_adjust_removal(fq, flow, 1, skb->len, skb->truesize); +- } +- +- static void fq_rejigger_backlog(struct fq *fq, struct fq_flow *flow) +-@@ -59,6 +67,34 @@ static struct sk_buff *fq_flow_dequeue(s +- return skb; +- } +- +-+static int fq_flow_drop(struct fq *fq, struct fq_flow *flow, +-+ fq_skb_free_t free_func) +-+{ +-+ unsigned int packets = 0, bytes = 0, truesize = 0; +-+ struct fq_tin *tin = flow->tin; +-+ struct sk_buff *skb; +-+ int pending; +-+ +-+ lockdep_assert_held(&fq->lock); +-+ +-+ pending = min_t(int, 32, skb_queue_len(&flow->queue) / 2); +-+ do { +-+ skb = __skb_dequeue(&flow->queue); +-+ if (!skb) +-+ break; +-+ +-+ packets++; +-+ bytes += skb->len; +-+ truesize += skb->truesize; +-+ free_func(fq, tin, flow, skb); +-+ } while (packets < pending); +-+ +-+ __fq_adjust_removal(fq, flow, packets, bytes, truesize); +-+ fq_rejigger_backlog(fq, flow); +-+ +-+ return packets; +-+} +-+ +- static struct sk_buff *fq_tin_dequeue(struct fq *fq, +- struct fq_tin *tin, +- fq_tin_dequeue_t dequeue_func) +-@@ -190,12 +226,9 @@ static void fq_tin_enqueue(struct fq *fq +- if (!flow) +- return; +- +-- skb = fq_flow_dequeue(fq, flow); +-- if (!skb) +-+ if (!fq_flow_drop(fq, flow, free_func)) +- return; +- +-- free_func(fq, flow->tin, flow, skb); +-- +- flow->tin->overlimit++; +- fq->overlimit++; +- if (oom) { +diff --git a/package/kernel/mac80211/patches/subsys/311-mac80211-use-coarse-boottime-for-airtime-fairness-co.patch b/package/kernel/mac80211/patches/subsys/311-mac80211-use-coarse-boottime-for-airtime-fairness-co.patch +new file mode 100644 +index 0000000000..c43cd3acb9 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/311-mac80211-use-coarse-boottime-for-airtime-fairness-co.patch +@@ -0,0 +1,60 @@ ++From: Felix Fietkau ++Date: Tue, 14 Dec 2021 17:53:12 +0100 ++Subject: [PATCH] mac80211: use coarse boottime for airtime fairness code ++ ++The time values used by the airtime fairness code only need to be accurate ++enough to cover station activity detection. ++Using ktime_get_coarse_boottime_ns instead of ktime_get_boottime_ns will ++drop the accuracy down to jiffies intervals, but at the same time saves ++a lot of CPU cycles in a hot path ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/net/mac80211/tx.c +++++ b/net/mac80211/tx.c ++@@ -3820,7 +3820,7 @@ struct ieee80211_txq *ieee80211_next_txq ++ { ++ struct ieee80211_local *local = hw_to_local(hw); ++ struct airtime_sched_info *air_sched; ++- u64 now = ktime_get_boottime_ns(); +++ u64 now = ktime_get_coarse_boottime_ns(); ++ struct ieee80211_txq *ret = NULL; ++ struct airtime_info *air_info; ++ struct txq_info *txqi = NULL; ++@@ -3947,7 +3947,7 @@ void ieee80211_update_airtime_weight(str ++ u64 weight_sum = 0; ++ ++ if (unlikely(!now)) ++- now = ktime_get_boottime_ns(); +++ now = ktime_get_coarse_boottime_ns(); ++ ++ lockdep_assert_held(&air_sched->lock); ++ ++@@ -3973,7 +3973,7 @@ void ieee80211_schedule_txq(struct ieee8 ++ struct ieee80211_local *local = hw_to_local(hw); ++ struct txq_info *txqi = to_txq_info(txq); ++ struct airtime_sched_info *air_sched; ++- u64 now = ktime_get_boottime_ns(); +++ u64 now = ktime_get_coarse_boottime_ns(); ++ struct airtime_info *air_info; ++ u8 ac = txq->ac; ++ bool was_active; ++@@ -4031,7 +4031,7 @@ static void __ieee80211_unschedule_txq(s ++ ++ if (!purge) ++ airtime_set_active(air_sched, air_info, ++- ktime_get_boottime_ns()); +++ ktime_get_coarse_boottime_ns()); ++ ++ rb_erase_cached(&txqi->schedule_order, ++ &air_sched->active_txqs); ++@@ -4119,7 +4119,7 @@ bool ieee80211_txq_may_transmit(struct i ++ if (RB_EMPTY_NODE(&txqi->schedule_order)) ++ goto out; ++ ++- now = ktime_get_boottime_ns(); +++ now = ktime_get_coarse_boottime_ns(); ++ ++ /* Like in ieee80211_next_txq(), make sure the first station in the ++ * scheduling order is eligible for transmission to avoid starvation. +diff --git a/package/kernel/mac80211/patches/subsys/311-net-fq_impl-drop-get_default_func-move-default-flow-.patch b/package/kernel/mac80211/patches/subsys/311-net-fq_impl-drop-get_default_func-move-default-flow-.patch +deleted file mode 100644 +index 6adca7d70d..0000000000 +--- a/package/kernel/mac80211/patches/subsys/311-net-fq_impl-drop-get_default_func-move-default-flow-.patch ++++ /dev/null +@@ -1,144 +0,0 @@ +-From: Felix Fietkau +-Date: Wed, 25 Nov 2020 18:09:10 +0100 +-Subject: [PATCH] net/fq_impl: drop get_default_func, move default flow to +- fq_tin +- +-Simplifies the code and prepares for a rework of scanning for flows on +-overmemory drop. +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/include/net/fq.h +-+++ b/include/net/fq.h +-@@ -47,6 +47,7 @@ struct fq_flow { +- struct fq_tin { +- struct list_head new_flows; +- struct list_head old_flows; +-+ struct fq_flow default_flow; +- u32 backlog_bytes; +- u32 backlog_packets; +- u32 overlimit; +---- a/include/net/fq_impl.h +-+++ b/include/net/fq_impl.h +-@@ -151,8 +151,7 @@ static u32 fq_flow_idx(struct fq *fq, st +- +- static struct fq_flow *fq_flow_classify(struct fq *fq, +- struct fq_tin *tin, u32 idx, +-- struct sk_buff *skb, +-- fq_flow_get_default_t get_default_func) +-+ struct sk_buff *skb) +- { +- struct fq_flow *flow; +- +-@@ -160,7 +159,7 @@ static struct fq_flow *fq_flow_classify( +- +- flow = &fq->flows[idx]; +- if (flow->tin && flow->tin != tin) { +-- flow = get_default_func(fq, tin, idx, skb); +-+ flow = &tin->default_flow; +- tin->collisions++; +- fq->collisions++; +- } +-@@ -192,15 +191,14 @@ static void fq_recalc_backlog(struct fq +- static void fq_tin_enqueue(struct fq *fq, +- struct fq_tin *tin, u32 idx, +- struct sk_buff *skb, +-- fq_skb_free_t free_func, +-- fq_flow_get_default_t get_default_func) +-+ fq_skb_free_t free_func) +- { +- struct fq_flow *flow; +- bool oom; +- +- lockdep_assert_held(&fq->lock); +- +-- flow = fq_flow_classify(fq, tin, idx, skb, get_default_func); +-+ flow = fq_flow_classify(fq, tin, idx, skb); +- +- flow->tin = tin; +- flow->backlog += skb->len; +-@@ -331,6 +329,7 @@ static void fq_tin_init(struct fq_tin *t +- { +- INIT_LIST_HEAD(&tin->new_flows); +- INIT_LIST_HEAD(&tin->old_flows); +-+ fq_flow_init(&tin->default_flow); +- } +- +- static int fq_init(struct fq *fq, int flows_cnt) +---- a/net/mac80211/ieee80211_i.h +-+++ b/net/mac80211/ieee80211_i.h +-@@ -846,7 +846,6 @@ enum txq_info_flags { +- */ +- struct txq_info { +- struct fq_tin tin; +-- struct fq_flow def_flow; +- struct codel_vars def_cvars; +- struct codel_stats cstats; +- struct sk_buff_head frags; +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -1322,7 +1322,7 @@ static struct sk_buff *codel_dequeue_fun +- fq = &local->fq; +- +- if (cvars == &txqi->def_cvars) +-- flow = &txqi->def_flow; +-+ flow = &txqi->tin.default_flow; +- else +- flow = &fq->flows[cvars - local->cvars]; +- +-@@ -1365,7 +1365,7 @@ static struct sk_buff *fq_tin_dequeue_fu +- cparams = &local->cparams; +- } +- +-- if (flow == &txqi->def_flow) +-+ if (flow == &tin->default_flow) +- cvars = &txqi->def_cvars; +- else +- cvars = &local->cvars[flow - fq->flows]; +-@@ -1392,17 +1392,6 @@ static void fq_skb_free_func(struct fq * +- ieee80211_free_txskb(&local->hw, skb); +- } +- +--static struct fq_flow *fq_flow_get_default_func(struct fq *fq, +-- struct fq_tin *tin, +-- int idx, +-- struct sk_buff *skb) +--{ +-- struct txq_info *txqi; +-- +-- txqi = container_of(tin, struct txq_info, tin); +-- return &txqi->def_flow; +--} +-- +- static void ieee80211_txq_enqueue(struct ieee80211_local *local, +- struct txq_info *txqi, +- struct sk_buff *skb) +-@@ -1415,8 +1404,7 @@ static void ieee80211_txq_enqueue(struct +- +- spin_lock_bh(&fq->lock); +- fq_tin_enqueue(fq, tin, flow_idx, skb, +-- fq_skb_free_func, +-- fq_flow_get_default_func); +-+ fq_skb_free_func); +- spin_unlock_bh(&fq->lock); +- } +- +-@@ -1459,7 +1447,6 @@ void ieee80211_txq_init(struct ieee80211 +- struct txq_info *txqi, int tid) +- { +- fq_tin_init(&txqi->tin); +-- fq_flow_init(&txqi->def_flow); +- codel_vars_init(&txqi->def_cvars); +- codel_stats_init(&txqi->cstats); +- __skb_queue_head_init(&txqi->frags); +-@@ -3332,8 +3319,7 @@ static bool ieee80211_amsdu_aggregate(st +- */ +- +- tin = &txqi->tin; +-- flow = fq_flow_classify(fq, tin, flow_idx, skb, +-- fq_flow_get_default_func); +-+ flow = fq_flow_classify(fq, tin, flow_idx, skb); +- head = skb_peek_tail(&flow->queue); +- if (!head || skb_is_gso(head)) +- goto out; +diff --git a/package/kernel/mac80211/patches/subsys/312-net-fq_impl-do-not-maintain-a-backlog-sorted-list-of.patch b/package/kernel/mac80211/patches/subsys/312-net-fq_impl-do-not-maintain-a-backlog-sorted-list-of.patch +deleted file mode 100644 +index 793c76abec..0000000000 +--- a/package/kernel/mac80211/patches/subsys/312-net-fq_impl-do-not-maintain-a-backlog-sorted-list-of.patch ++++ /dev/null +@@ -1,317 +0,0 @@ +-From: Felix Fietkau +-Date: Wed, 25 Nov 2020 18:10:34 +0100 +-Subject: [PATCH] net/fq_impl: do not maintain a backlog-sorted list of +- flows +- +-A sorted flow list is only needed to drop packets in the biggest flow when +-hitting the overmemory condition. +-By scanning flows only when needed, we can avoid paying the cost of +-maintaining the list under normal conditions +-In order to avoid scanning lots of empty flows and touching too many cold +-cache lines, a bitmap of flows with backlog is maintained +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/include/net/fq.h +-+++ b/include/net/fq.h +-@@ -19,8 +19,6 @@ struct fq_tin; +- * @flowchain: can be linked to fq_tin's new_flows or old_flows. Used for DRR++ +- * (deficit round robin) based round robin queuing similar to the one +- * found in net/sched/sch_fq_codel.c +-- * @backlogchain: can be linked to other fq_flow and fq. Used to keep track of +-- * fat flows and efficient head-dropping if packet limit is reached +- * @queue: sk_buff queue to hold packets +- * @backlog: number of bytes pending in the queue. The number of packets can be +- * found in @queue.qlen +-@@ -29,7 +27,6 @@ struct fq_tin; +- struct fq_flow { +- struct fq_tin *tin; +- struct list_head flowchain; +-- struct list_head backlogchain; +- struct sk_buff_head queue; +- u32 backlog; +- int deficit; +-@@ -47,6 +44,7 @@ struct fq_flow { +- struct fq_tin { +- struct list_head new_flows; +- struct list_head old_flows; +-+ struct list_head tin_list; +- struct fq_flow default_flow; +- u32 backlog_bytes; +- u32 backlog_packets; +-@@ -60,14 +58,14 @@ struct fq_tin { +- /** +- * struct fq - main container for fair queuing purposes +- * +-- * @backlogs: linked to fq_flows. Used to maintain fat flows for efficient +-- * head-dropping when @backlog reaches @limit +- * @limit: max number of packets that can be queued across all flows +- * @backlog: number of packets queued across all flows +- */ +- struct fq { +- struct fq_flow *flows; +-- struct list_head backlogs; +-+ unsigned long *flows_bitmap; +-+ +-+ struct list_head tin_backlog; +- spinlock_t lock; +- u32 flows_cnt; +- u32 limit; +---- a/include/net/fq_impl.h +-+++ b/include/net/fq_impl.h +-@@ -17,12 +17,24 @@ __fq_adjust_removal(struct fq *fq, struc +- unsigned int bytes, unsigned int truesize) +- { +- struct fq_tin *tin = flow->tin; +-+ int idx; +- +- tin->backlog_bytes -= bytes; +- tin->backlog_packets -= packets; +- flow->backlog -= bytes; +- fq->backlog -= packets; +- fq->memory_usage -= truesize; +-+ +-+ if (flow->backlog) +-+ return; +-+ +-+ if (flow == &tin->default_flow) { +-+ list_del_init(&tin->tin_list); +-+ return; +-+ } +-+ +-+ idx = flow - fq->flows; +-+ __clear_bit(idx, fq->flows_bitmap); +- } +- +- static void fq_adjust_removal(struct fq *fq, +-@@ -32,24 +44,6 @@ static void fq_adjust_removal(struct fq +- __fq_adjust_removal(fq, flow, 1, skb->len, skb->truesize); +- } +- +--static void fq_rejigger_backlog(struct fq *fq, struct fq_flow *flow) +--{ +-- struct fq_flow *i; +-- +-- if (flow->backlog == 0) { +-- list_del_init(&flow->backlogchain); +-- } else { +-- i = flow; +-- +-- list_for_each_entry_continue(i, &fq->backlogs, backlogchain) +-- if (i->backlog < flow->backlog) +-- break; +-- +-- list_move_tail(&flow->backlogchain, +-- &i->backlogchain); +-- } +--} +-- +- static struct sk_buff *fq_flow_dequeue(struct fq *fq, +- struct fq_flow *flow) +- { +-@@ -62,7 +56,6 @@ static struct sk_buff *fq_flow_dequeue(s +- return NULL; +- +- fq_adjust_removal(fq, flow, skb); +-- fq_rejigger_backlog(fq, flow); +- +- return skb; +- } +-@@ -90,7 +83,6 @@ static int fq_flow_drop(struct fq *fq, s +- } while (packets < pending); +- +- __fq_adjust_removal(fq, flow, packets, bytes, truesize); +-- fq_rejigger_backlog(fq, flow); +- +- return packets; +- } +-@@ -170,22 +162,36 @@ static struct fq_flow *fq_flow_classify( +- return flow; +- } +- +--static void fq_recalc_backlog(struct fq *fq, +-- struct fq_tin *tin, +-- struct fq_flow *flow) +--{ +-- struct fq_flow *i; +-- +-- if (list_empty(&flow->backlogchain)) +-- list_add_tail(&flow->backlogchain, &fq->backlogs); +-- +-- i = flow; +-- list_for_each_entry_continue_reverse(i, &fq->backlogs, +-- backlogchain) +-- if (i->backlog > flow->backlog) +-- break; +-+static struct fq_flow *fq_find_fattest_flow(struct fq *fq) +-+{ +-+ struct fq_tin *tin; +-+ struct fq_flow *flow = NULL; +-+ u32 len = 0; +-+ int i; +-+ +-+ for_each_set_bit(i, fq->flows_bitmap, fq->flows_cnt) { +-+ struct fq_flow *cur = &fq->flows[i]; +-+ unsigned int cur_len; +-+ +-+ cur_len = cur->backlog; +-+ if (cur_len <= len) +-+ continue; +-+ +-+ flow = cur; +-+ len = cur_len; +-+ } +- +-- list_move(&flow->backlogchain, &i->backlogchain); +-+ list_for_each_entry(tin, &fq->tin_backlog, tin_list) { +-+ unsigned int cur_len = tin->default_flow.backlog; +-+ +-+ if (cur_len <= len) +-+ continue; +-+ +-+ flow = &tin->default_flow; +-+ len = cur_len; +-+ } +-+ +-+ return flow; +- } +- +- static void fq_tin_enqueue(struct fq *fq, +-@@ -200,6 +206,13 @@ static void fq_tin_enqueue(struct fq *fq +- +- flow = fq_flow_classify(fq, tin, idx, skb); +- +-+ if (!flow->backlog) { +-+ if (flow != &tin->default_flow) +-+ __set_bit(idx, fq->flows_bitmap); +-+ else if (list_empty(&tin->tin_list)) +-+ list_add(&tin->tin_list, &fq->tin_backlog); +-+ } +-+ +- flow->tin = tin; +- flow->backlog += skb->len; +- tin->backlog_bytes += skb->len; +-@@ -207,8 +220,6 @@ static void fq_tin_enqueue(struct fq *fq +- fq->memory_usage += skb->truesize; +- fq->backlog++; +- +-- fq_recalc_backlog(fq, tin, flow); +-- +- if (list_empty(&flow->flowchain)) { +- flow->deficit = fq->quantum; +- list_add_tail(&flow->flowchain, +-@@ -218,9 +229,7 @@ static void fq_tin_enqueue(struct fq *fq +- __skb_queue_tail(&flow->queue, skb); +- oom = (fq->memory_usage > fq->memory_limit); +- while (fq->backlog > fq->limit || oom) { +-- flow = list_first_entry_or_null(&fq->backlogs, +-- struct fq_flow, +-- backlogchain); +-+ flow = fq_find_fattest_flow(fq); +- if (!flow) +- return; +- +-@@ -255,8 +264,6 @@ static void fq_flow_filter(struct fq *fq +- fq_adjust_removal(fq, flow, skb); +- free_func(fq, tin, flow, skb); +- } +-- +-- fq_rejigger_backlog(fq, flow); +- } +- +- static void fq_tin_filter(struct fq *fq, +-@@ -279,16 +286,18 @@ static void fq_flow_reset(struct fq *fq, +- struct fq_flow *flow, +- fq_skb_free_t free_func) +- { +-+ struct fq_tin *tin = flow->tin; +- struct sk_buff *skb; +- +- while ((skb = fq_flow_dequeue(fq, flow))) +-- free_func(fq, flow->tin, flow, skb); +-+ free_func(fq, tin, flow, skb); +- +-- if (!list_empty(&flow->flowchain)) +-+ if (!list_empty(&flow->flowchain)) { +- list_del_init(&flow->flowchain); +-- +-- if (!list_empty(&flow->backlogchain)) +-- list_del_init(&flow->backlogchain); +-+ if (list_empty(&tin->new_flows) && +-+ list_empty(&tin->old_flows)) +-+ list_del_init(&tin->tin_list); +-+ } +- +- flow->tin = NULL; +- +-@@ -314,6 +323,7 @@ static void fq_tin_reset(struct fq *fq, +- fq_flow_reset(fq, flow, free_func); +- } +- +-+ WARN_ON_ONCE(!list_empty(&tin->tin_list)); +- WARN_ON_ONCE(tin->backlog_bytes); +- WARN_ON_ONCE(tin->backlog_packets); +- } +-@@ -321,7 +331,6 @@ static void fq_tin_reset(struct fq *fq, +- static void fq_flow_init(struct fq_flow *flow) +- { +- INIT_LIST_HEAD(&flow->flowchain); +-- INIT_LIST_HEAD(&flow->backlogchain); +- __skb_queue_head_init(&flow->queue); +- } +- +-@@ -329,6 +338,7 @@ static void fq_tin_init(struct fq_tin *t +- { +- INIT_LIST_HEAD(&tin->new_flows); +- INIT_LIST_HEAD(&tin->old_flows); +-+ INIT_LIST_HEAD(&tin->tin_list); +- fq_flow_init(&tin->default_flow); +- } +- +-@@ -337,8 +347,8 @@ static int fq_init(struct fq *fq, int fl +- int i; +- +- memset(fq, 0, sizeof(fq[0])); +-- INIT_LIST_HEAD(&fq->backlogs); +- spin_lock_init(&fq->lock); +-+ INIT_LIST_HEAD(&fq->tin_backlog); +- fq->flows_cnt = max_t(u32, flows_cnt, 1); +- fq->quantum = 300; +- fq->limit = 8192; +-@@ -348,6 +358,14 @@ static int fq_init(struct fq *fq, int fl +- if (!fq->flows) +- return -ENOMEM; +- +-+ fq->flows_bitmap = kcalloc(BITS_TO_LONGS(fq->flows_cnt), sizeof(long), +-+ GFP_KERNEL); +-+ if (!fq->flows_bitmap) { +-+ kvfree(fq->flows); +-+ fq->flows = NULL; +-+ return -ENOMEM; +-+ } +-+ +- for (i = 0; i < fq->flows_cnt; i++) +- fq_flow_init(&fq->flows[i]); +- +-@@ -364,6 +382,9 @@ static void fq_reset(struct fq *fq, +- +- kvfree(fq->flows); +- fq->flows = NULL; +-+ +-+ kfree(fq->flows_bitmap); +-+ fq->flows_bitmap = NULL; +- } +- +- #endif +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -3386,8 +3386,6 @@ out_recalc: +- if (head->len != orig_len) { +- flow->backlog += head->len - orig_len; +- tin->backlog_bytes += head->len - orig_len; +-- +-- fq_recalc_backlog(fq, tin, flow); +- } +- out: +- spin_unlock_bh(&fq->lock); +diff --git a/package/kernel/mac80211/patches/subsys/315-mac80211-add-rx-decapsulation-offload-support.patch b/package/kernel/mac80211/patches/subsys/315-mac80211-add-rx-decapsulation-offload-support.patch +deleted file mode 100644 +index 518bc582ae..0000000000 +--- a/package/kernel/mac80211/patches/subsys/315-mac80211-add-rx-decapsulation-offload-support.patch ++++ /dev/null +@@ -1,570 +0,0 @@ +-From: Felix Fietkau +-Date: Wed, 16 Dec 2020 21:34:03 +0100 +-Subject: [PATCH] mac80211: add rx decapsulation offload support +- +-This allows drivers to pass 802.3 frames to mac80211, with some restrictions: +- +-- the skb must be passed with a valid sta +-- fast-rx needs to be active for the sta +-- monitor mode needs to be disabled +- +-mac80211 will tell the driver when it is safe to enable rx decap offload for +-a particular station. +- +-In order to implement support, a driver must: +- +-- call ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD) +-- implement ops->sta_set_decap_offload +-- mark 802.3 frames with RX_FLAG_8023 +- +-If it doesn't want to enable offload for some vif types, it can mask out +-IEEE80211_OFFLOAD_DECAP_ENABLED in vif->offload_flags from within the +-.add_interface or .update_vif_offload driver ops +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/include/net/mac80211.h +-+++ b/include/net/mac80211.h +-@@ -1297,6 +1297,8 @@ ieee80211_tx_info_clear_status(struct ie +- * the "0-length PSDU" field included there. The value for it is +- * in &struct ieee80211_rx_status. Note that if this value isn't +- * known the frame shouldn't be reported. +-+ * @RX_FLAG_8023: the frame has an 802.3 header (decap offload performed by +-+ * hardware or driver) +- */ +- enum mac80211_rx_flags { +- RX_FLAG_MMIC_ERROR = BIT(0), +-@@ -1329,6 +1331,7 @@ enum mac80211_rx_flags { +- RX_FLAG_RADIOTAP_HE_MU = BIT(27), +- RX_FLAG_RADIOTAP_LSIG = BIT(28), +- RX_FLAG_NO_PSDU = BIT(29), +-+ RX_FLAG_8023 = BIT(30), +- }; +- +- /** +-@@ -1650,11 +1653,15 @@ enum ieee80211_vif_flags { +- * The driver supports sending frames passed as 802.3 frames by mac80211. +- * It must also support sending 802.11 packets for the same interface. +- * @IEEE80211_OFFLOAD_ENCAP_4ADDR: support 4-address mode encapsulation offload +-+ * @IEEE80211_OFFLOAD_DECAP_ENABLED: rx encapsulation offload is enabled +-+ * The driver supports passing received 802.11 frames as 802.3 frames to +-+ * mac80211. +- */ +- +- enum ieee80211_offload_flags { +- IEEE80211_OFFLOAD_ENCAP_ENABLED = BIT(0), +- IEEE80211_OFFLOAD_ENCAP_4ADDR = BIT(1), +-+ IEEE80211_OFFLOAD_DECAP_ENABLED = BIT(2), +- }; +- +- /** +-@@ -2390,6 +2397,9 @@ struct ieee80211_txq { +- * @IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD: Hardware supports tx encapsulation +- * offload +- * +-+ * @IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD: Hardware supports rx decapsulation +-+ * offload +-+ * +- * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays +- */ +- enum ieee80211_hw_flags { +-@@ -2443,6 +2453,7 @@ enum ieee80211_hw_flags { +- IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID, +- IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT, +- IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD, +-+ IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD, +- +- /* keep last, obviously */ +- NUM_IEEE80211_HW_FLAGS +-@@ -4196,6 +4207,9 @@ struct ieee80211_ops { +- struct ieee80211_vif *vif); +- void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +- struct ieee80211_sta *sta, bool enabled); +-+ void (*sta_set_decap_offload)(struct ieee80211_hw *hw, +-+ struct ieee80211_vif *vif, +-+ struct ieee80211_sta *sta, bool enabled); +- }; +- +- /** +---- a/net/mac80211/debugfs.c +-+++ b/net/mac80211/debugfs.c +-@@ -405,6 +405,7 @@ static const char *hw_flag_names[] = { +- FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID), +- FLAG(AMPDU_KEYBORDER_SUPPORT), +- FLAG(SUPPORTS_TX_ENCAP_OFFLOAD), +-+ FLAG(SUPPORTS_RX_DECAP_OFFLOAD), +- #undef FLAG +- }; +- +---- a/net/mac80211/debugfs_sta.c +-+++ b/net/mac80211/debugfs_sta.c +-@@ -79,6 +79,7 @@ static const char * const sta_flag_names +- FLAG(MPSP_RECIPIENT), +- FLAG(PS_DELIVER), +- FLAG(USES_ENCRYPTION), +-+ FLAG(DECAP_OFFLOAD), +- #undef FLAG +- }; +- +---- a/net/mac80211/driver-ops.h +-+++ b/net/mac80211/driver-ops.h +-@@ -1413,4 +1413,20 @@ static inline void drv_sta_set_4addr(str +- trace_drv_return_void(local); +- } +- +-+static inline void drv_sta_set_decap_offload(struct ieee80211_local *local, +-+ struct ieee80211_sub_if_data *sdata, +-+ struct ieee80211_sta *sta, +-+ bool enabled) +-+{ +-+ sdata = get_bss_sdata(sdata); +-+ if (!check_sdata_in_driver(sdata)) +-+ return; +-+ +-+ trace_drv_sta_set_decap_offload(local, sdata, sta, enabled); +-+ if (local->ops->sta_set_decap_offload) +-+ local->ops->sta_set_decap_offload(&local->hw, &sdata->vif, sta, +-+ enabled); +-+ trace_drv_return_void(local); +-+} +-+ +- #endif /* __MAC80211_DRIVER_OPS */ +---- a/net/mac80211/iface.c +-+++ b/net/mac80211/iface.c +-@@ -856,7 +856,7 @@ static const struct net_device_ops ieee8 +- +- }; +- +--static bool ieee80211_iftype_supports_encap_offload(enum nl80211_iftype iftype) +-+static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype) +- { +- switch (iftype) { +- /* P2P GO and client are mapped to AP/STATION types */ +-@@ -876,7 +876,7 @@ static bool ieee80211_set_sdata_offload_ +- flags = sdata->vif.offload_flags; +- +- if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) && +-- ieee80211_iftype_supports_encap_offload(sdata->vif.type)) { +-+ ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) { +- flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED; +- +- if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) && +-@@ -889,10 +889,21 @@ static bool ieee80211_set_sdata_offload_ +- flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; +- } +- +-+ if (ieee80211_hw_check(&local->hw, SUPPORTS_RX_DECAP_OFFLOAD) && +-+ ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) { +-+ flags |= IEEE80211_OFFLOAD_DECAP_ENABLED; +-+ +-+ if (local->monitors) +-+ flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; +-+ } else { +-+ flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; +-+ } +-+ +- if (sdata->vif.offload_flags == flags) +- return false; +- +- sdata->vif.offload_flags = flags; +-+ ieee80211_check_fast_rx_iface(sdata); +- return true; +- } +- +-@@ -910,7 +921,7 @@ static void ieee80211_set_vif_encap_ops( +- } +- +- if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) || +-- !ieee80211_iftype_supports_encap_offload(bss->vif.type)) +-+ !ieee80211_iftype_supports_hdr_offload(bss->vif.type)) +- return; +- +- enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED; +---- a/net/mac80211/rx.c +-+++ b/net/mac80211/rx.c +-@@ -4197,7 +4197,9 @@ void ieee80211_check_fast_rx(struct sta_ +- .vif_type = sdata->vif.type, +- .control_port_protocol = sdata->control_port_protocol, +- }, *old, *new = NULL; +-+ bool set_offload = false; +- bool assign = false; +-+ bool offload; +- +- /* use sparse to check that we don't return without updating */ +- __acquire(check_fast_rx); +-@@ -4310,6 +4312,17 @@ void ieee80211_check_fast_rx(struct sta_ +- if (assign) +- new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL); +- +-+ offload = assign && +-+ (sdata->vif.offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED); +-+ +-+ if (offload) +-+ set_offload = !test_and_set_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD); +-+ else +-+ set_offload = test_and_clear_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD); +-+ +-+ if (set_offload) +-+ drv_sta_set_decap_offload(local, sdata, &sta->sta, assign); +-+ +- spin_lock_bh(&sta->lock); +- old = rcu_dereference_protected(sta->fast_rx, true); +- rcu_assign_pointer(sta->fast_rx, new); +-@@ -4356,6 +4369,108 @@ void ieee80211_check_fast_rx_iface(struc +- mutex_unlock(&local->sta_mtx); +- } +- +-+static void ieee80211_rx_8023(struct ieee80211_rx_data *rx, +-+ struct ieee80211_fast_rx *fast_rx, +-+ int orig_len) +-+{ +-+ struct ieee80211_sta_rx_stats *stats; +-+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); +-+ struct sta_info *sta = rx->sta; +-+ struct sk_buff *skb = rx->skb; +-+ void *sa = skb->data + ETH_ALEN; +-+ void *da = skb->data; +-+ +-+ stats = &sta->rx_stats; +-+ if (fast_rx->uses_rss) +-+ stats = this_cpu_ptr(sta->pcpu_rx_stats); +-+ +-+ /* statistics part of ieee80211_rx_h_sta_process() */ +-+ if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { +-+ stats->last_signal = status->signal; +-+ if (!fast_rx->uses_rss) +-+ ewma_signal_add(&sta->rx_stats_avg.signal, +-+ -status->signal); +-+ } +-+ +-+ if (status->chains) { +-+ int i; +-+ +-+ stats->chains = status->chains; +-+ for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) { +-+ int signal = status->chain_signal[i]; +-+ +-+ if (!(status->chains & BIT(i))) +-+ continue; +-+ +-+ stats->chain_signal_last[i] = signal; +-+ if (!fast_rx->uses_rss) +-+ ewma_signal_add(&sta->rx_stats_avg.chain_signal[i], +-+ -signal); +-+ } +-+ } +-+ /* end of statistics */ +-+ +-+ stats->last_rx = jiffies; +-+ stats->last_rate = sta_stats_encode_rate(status); +-+ +-+ stats->fragments++; +-+ stats->packets++; +-+ +-+ skb->dev = fast_rx->dev; +-+ +-+ ieee80211_rx_stats(fast_rx->dev, skb->len); +-+ +-+ /* The seqno index has the same property as needed +-+ * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS +-+ * for non-QoS-data frames. Here we know it's a data +-+ * frame, so count MSDUs. +-+ */ +-+ u64_stats_update_begin(&stats->syncp); +-+ stats->msdu[rx->seqno_idx]++; +-+ stats->bytes += orig_len; +-+ u64_stats_update_end(&stats->syncp); +-+ +-+ if (fast_rx->internal_forward) { +-+ struct sk_buff *xmit_skb = NULL; +-+ if (is_multicast_ether_addr(da)) { +-+ xmit_skb = skb_copy(skb, GFP_ATOMIC); +-+ } else if (!ether_addr_equal(da, sa) && +-+ sta_info_get(rx->sdata, da)) { +-+ xmit_skb = skb; +-+ skb = NULL; +-+ } +-+ +-+ if (xmit_skb) { +-+ /* +-+ * Send to wireless media and increase priority by 256 +-+ * to keep the received priority instead of +-+ * reclassifying the frame (see cfg80211_classify8021d). +-+ */ +-+ xmit_skb->priority += 256; +-+ xmit_skb->protocol = htons(ETH_P_802_3); +-+ skb_reset_network_header(xmit_skb); +-+ skb_reset_mac_header(xmit_skb); +-+ dev_queue_xmit(xmit_skb); +-+ } +-+ +-+ if (!skb) +-+ return; +-+ } +-+ +-+ /* deliver to local stack */ +-+ skb->protocol = eth_type_trans(skb, fast_rx->dev); +-+ memset(skb->cb, 0, sizeof(skb->cb)); +-+ if (rx->list) +-+#if LINUX_VERSION_IS_GEQ(4,19,0) +-+ list_add_tail(&skb->list, rx->list); +-+#else +-+ __skb_queue_tail(rx->list, skb); +-+#endif +-+ else +-+ netif_receive_skb(skb); +-+ +-+} +-+ +- static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx, +- struct ieee80211_fast_rx *fast_rx) +- { +-@@ -4376,9 +4491,6 @@ static bool ieee80211_invoke_fast_rx(str +- } addrs __aligned(2); +- struct ieee80211_sta_rx_stats *stats = &sta->rx_stats; +- +-- if (fast_rx->uses_rss) +-- stats = this_cpu_ptr(sta->pcpu_rx_stats); +-- +- /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write +- * to a common data structure; drivers can implement that per queue +- * but we don't have that information in mac80211 +-@@ -4452,32 +4564,6 @@ static bool ieee80211_invoke_fast_rx(str +- pskb_trim(skb, skb->len - fast_rx->icv_len)) +- goto drop; +- +-- /* statistics part of ieee80211_rx_h_sta_process() */ +-- if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { +-- stats->last_signal = status->signal; +-- if (!fast_rx->uses_rss) +-- ewma_signal_add(&sta->rx_stats_avg.signal, +-- -status->signal); +-- } +-- +-- if (status->chains) { +-- int i; +-- +-- stats->chains = status->chains; +-- for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) { +-- int signal = status->chain_signal[i]; +-- +-- if (!(status->chains & BIT(i))) +-- continue; +-- +-- stats->chain_signal_last[i] = signal; +-- if (!fast_rx->uses_rss) +-- ewma_signal_add(&sta->rx_stats_avg.chain_signal[i], +-- -signal); +-- } +-- } +-- /* end of statistics */ +-- +- if (rx->key && !ieee80211_has_protected(hdr->frame_control)) +- goto drop; +- +-@@ -4489,12 +4575,6 @@ static bool ieee80211_invoke_fast_rx(str +- return true; +- } +- +-- stats->last_rx = jiffies; +-- stats->last_rate = sta_stats_encode_rate(status); +-- +-- stats->fragments++; +-- stats->packets++; +-- +- /* do the header conversion - first grab the addresses */ +- ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs); +- ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs); +-@@ -4503,62 +4583,14 @@ static bool ieee80211_invoke_fast_rx(str +- /* push the addresses in front */ +- memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs)); +- +-- skb->dev = fast_rx->dev; +-- +-- ieee80211_rx_stats(fast_rx->dev, skb->len); +-- +-- /* The seqno index has the same property as needed +-- * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS +-- * for non-QoS-data frames. Here we know it's a data +-- * frame, so count MSDUs. +-- */ +-- u64_stats_update_begin(&stats->syncp); +-- stats->msdu[rx->seqno_idx]++; +-- stats->bytes += orig_len; +-- u64_stats_update_end(&stats->syncp); +-- +-- if (fast_rx->internal_forward) { +-- struct sk_buff *xmit_skb = NULL; +-- if (is_multicast_ether_addr(addrs.da)) { +-- xmit_skb = skb_copy(skb, GFP_ATOMIC); +-- } else if (!ether_addr_equal(addrs.da, addrs.sa) && +-- sta_info_get(rx->sdata, addrs.da)) { +-- xmit_skb = skb; +-- skb = NULL; +-- } +-- +-- if (xmit_skb) { +-- /* +-- * Send to wireless media and increase priority by 256 +-- * to keep the received priority instead of +-- * reclassifying the frame (see cfg80211_classify8021d). +-- */ +-- xmit_skb->priority += 256; +-- xmit_skb->protocol = htons(ETH_P_802_3); +-- skb_reset_network_header(xmit_skb); +-- skb_reset_mac_header(xmit_skb); +-- dev_queue_xmit(xmit_skb); +-- } +-- +-- if (!skb) +-- return true; +-- } +-- +-- /* deliver to local stack */ +-- skb->protocol = eth_type_trans(skb, fast_rx->dev); +-- memset(skb->cb, 0, sizeof(skb->cb)); +-- if (rx->list) +--#if LINUX_VERSION_IS_GEQ(4,19,0) +-- list_add_tail(&skb->list, rx->list); +--#else +-- __skb_queue_tail(rx->list, skb); +--#endif +-- else +-- netif_receive_skb(skb); +-+ ieee80211_rx_8023(rx, fast_rx, orig_len); +- +- return true; +- drop: +- dev_kfree_skb(skb); +-+ if (fast_rx->uses_rss) +-+ stats = this_cpu_ptr(sta->pcpu_rx_stats); +-+ +- stats->dropped++; +- return true; +- } +-@@ -4612,6 +4644,47 @@ static bool ieee80211_prepare_and_rx_han +- return true; +- } +- +-+static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw, +-+ struct ieee80211_sta *pubsta, +-+ struct sk_buff *skb, +-+#if LINUX_VERSION_IS_GEQ(4,19,0) +-+ struct list_head *list) +-+#else +-+ struct sk_buff_head *list) +-+#endif +-+{ +-+ struct ieee80211_local *local = hw_to_local(hw); +-+ struct ieee80211_fast_rx *fast_rx; +-+ struct ieee80211_rx_data rx; +-+ +-+ memset(&rx, 0, sizeof(rx)); +-+ rx.skb = skb; +-+ rx.local = local; +-+ rx.list = list; +-+ +-+ I802_DEBUG_INC(local->dot11ReceivedFragmentCount); +-+ +-+ /* drop frame if too short for header */ +-+ if (skb->len < sizeof(struct ethhdr)) +-+ goto drop; +-+ +-+ if (!pubsta) +-+ goto drop; +-+ +-+ rx.sta = container_of(pubsta, struct sta_info, sta); +-+ rx.sdata = rx.sta->sdata; +-+ +-+ fast_rx = rcu_dereference(rx.sta->fast_rx); +-+ if (!fast_rx) +-+ goto drop; +-+ +-+ ieee80211_rx_8023(&rx, fast_rx, skb->len); +-+ return; +-+ +-+drop: +-+ dev_kfree_skb(skb); +-+} +-+ +- /* +- * This is the actual Rx frames handler. as it belongs to Rx path it must +- * be called with rcu_read_lock protection. +-@@ -4849,15 +4922,20 @@ void ieee80211_rx_list(struct ieee80211_ +- * if it was previously present. +- * Also, frames with less than 16 bytes are dropped. +- */ +-- skb = ieee80211_rx_monitor(local, skb, rate); +-- if (!skb) +-- return; +-+ if (!(status->flag & RX_FLAG_8023)) { +-+ skb = ieee80211_rx_monitor(local, skb, rate); +-+ if (!skb) +-+ return; +-+ } +- +- ieee80211_tpt_led_trig_rx(local, +- ((struct ieee80211_hdr *)skb->data)->frame_control, +- skb->len); +- +-- __ieee80211_rx_handle_packet(hw, pubsta, skb, list); +-+ if (status->flag & RX_FLAG_8023) +-+ __ieee80211_rx_handle_8023(hw, pubsta, skb, list); +-+ else +-+ __ieee80211_rx_handle_packet(hw, pubsta, skb, list); +- +- return; +- drop: +---- a/net/mac80211/sta_info.h +-+++ b/net/mac80211/sta_info.h +-@@ -71,6 +71,7 @@ +- * until pending frames are delivered +- * @WLAN_STA_USES_ENCRYPTION: This station was configured for encryption, +- * so drop all packets without a key later. +-+ * @WLAN_STA_DECAP_OFFLOAD: This station uses rx decap offload +- * +- * @NUM_WLAN_STA_FLAGS: number of defined flags +- */ +-@@ -102,6 +103,7 @@ enum ieee80211_sta_info_flags { +- WLAN_STA_MPSP_RECIPIENT, +- WLAN_STA_PS_DELIVER, +- WLAN_STA_USES_ENCRYPTION, +-+ WLAN_STA_DECAP_OFFLOAD, +- +- NUM_WLAN_STA_FLAGS, +- }; +---- a/net/mac80211/trace.h +-+++ b/net/mac80211/trace.h +-@@ -2761,7 +2761,7 @@ DEFINE_EVENT(local_sdata_addr_evt, drv_u +- TP_ARGS(local, sdata) +- ); +- +--TRACE_EVENT(drv_sta_set_4addr, +-+DECLARE_EVENT_CLASS(sta_flag_evt, +- TP_PROTO(struct ieee80211_local *local, +- struct ieee80211_sub_if_data *sdata, +- struct ieee80211_sta *sta, bool enabled), +-@@ -2788,6 +2788,22 @@ TRACE_EVENT(drv_sta_set_4addr, +- ) +- ); +- +-+DEFINE_EVENT(sta_flag_evt, drv_sta_set_4addr, +-+ TP_PROTO(struct ieee80211_local *local, +-+ struct ieee80211_sub_if_data *sdata, +-+ struct ieee80211_sta *sta, bool enabled), +-+ +-+ TP_ARGS(local, sdata, sta, enabled) +-+); +-+ +-+DEFINE_EVENT(sta_flag_evt, drv_sta_set_decap_offload, +-+ TP_PROTO(struct ieee80211_local *local, +-+ struct ieee80211_sub_if_data *sdata, +-+ struct ieee80211_sta *sta, bool enabled), +-+ +-+ TP_ARGS(local, sdata, sta, enabled) +-+); +-+ +- #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ +- +- #undef TRACE_INCLUDE_PATH +diff --git a/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch b/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch +deleted file mode 100644 +index 43ac9a0cef..0000000000 +--- a/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch ++++ /dev/null +@@ -1,116 +0,0 @@ +-From: Markus Theil +-Date: Sat, 6 Feb 2021 12:51:12 +0100 +-Subject: [PATCH] mac80211: enable QoS support for nl80211 ctrl port +- +-This patch unifies sending control port frames +-over nl80211 and AF_PACKET sockets a little more. +- +-Before this patch, EAPOL frames got QoS prioritization +-only when using AF_PACKET sockets. +- +-__ieee80211_select_queue only selects a QoS-enabled queue +-for control port frames, when the control port protocol +-is set correctly on the skb. For the AF_PACKET path this +-works, but the nl80211 path used ETH_P_802_3. +- +-Another check for injected frames in wme.c then prevented +-the QoS TID to be copied in the frame. +- +-In order to fix this, get rid of the frame injection marking +-for nl80211 ctrl port and set the correct ethernet protocol. +- +-Please note: +-An erlier version of this path tried to prevent +-frame aggregation for control port frames in order to speed up +-the initial connection setup a little. This seemed to cause +-issues on my older Intel dvm-based hardware, and was therefore +-removed again. Future commits which try to reintroduce this +-have to check carefully how hw behaves with aggregated and +-non-aggregated traffic for the same TID. +-My NIC: Intel(R) Centrino(R) Ultimate-N 6300 AGN, REV=0x74 +- +-Reported-by: kernel test robot +-Signed-off-by: Markus Theil +-Link: https://lore.kernel.org/r/20210206115112.567881-1-markus.theil@tu-ilmenau.de +-Signed-off-by: Johannes Berg +---- +- +---- a/net/mac80211/status.c +-+++ b/net/mac80211/status.c +-@@ -628,16 +628,12 @@ static void ieee80211_report_ack_skb(str +- u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie; +- struct ieee80211_sub_if_data *sdata; +- struct ieee80211_hdr *hdr = (void *)skb->data; +-- __be16 ethertype = 0; +-- +-- if (skb->len >= ETH_HLEN && skb->protocol == cpu_to_be16(ETH_P_802_3)) +-- skb_copy_bits(skb, 2 * ETH_ALEN, ðertype, ETH_TLEN); +- +- rcu_read_lock(); +- sdata = ieee80211_sdata_from_skb(local, skb); +- if (sdata) { +-- if (ethertype == sdata->control_port_protocol || +-- ethertype == cpu_to_be16(ETH_P_PREAUTH)) +-+ if (skb->protocol == sdata->control_port_protocol || +-+ skb->protocol == cpu_to_be16(ETH_P_PREAUTH)) +- cfg80211_control_port_tx_status(&sdata->wdev, +- cookie, +- skb->data, +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -1195,9 +1195,7 @@ ieee80211_tx_prepare(struct ieee80211_su +- tx->sta = rcu_dereference(sdata->u.vlan.sta); +- if (!tx->sta && sdata->wdev.use_4addr) +- return TX_DROP; +-- } else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX | +-- IEEE80211_TX_CTL_INJECTED) || +-- tx->sdata->control_port_protocol == tx->skb->protocol) { +-+ } else if (tx->sdata->control_port_protocol == tx->skb->protocol) { +- tx->sta = sta_info_get_bss(sdata, hdr->addr1); +- } +- if (!tx->sta && !is_multicast_ether_addr(hdr->addr1)) +-@@ -5443,6 +5441,7 @@ int ieee80211_tx_control_port(struct wip +- { +- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); +- struct ieee80211_local *local = sdata->local; +-+ struct sta_info *sta; +- struct sk_buff *skb; +- struct ethhdr *ehdr; +- u32 ctrl_flags = 0; +-@@ -5465,8 +5464,7 @@ int ieee80211_tx_control_port(struct wip +- if (cookie) +- ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; +- +-- flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX | +-- IEEE80211_TX_CTL_INJECTED; +-+ flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX; +- +- skb = dev_alloc_skb(local->hw.extra_tx_headroom + +- sizeof(struct ethhdr) + len); +-@@ -5483,10 +5481,25 @@ int ieee80211_tx_control_port(struct wip +- ehdr->h_proto = proto; +- +- skb->dev = dev; +-- skb->protocol = htons(ETH_P_802_3); +-+ skb->protocol = proto; +- skb_reset_network_header(skb); +- skb_reset_mac_header(skb); +- +-+ /* update QoS header to prioritize control port frames if possible, +-+ * priorization also happens for control port frames send over +-+ * AF_PACKET +-+ */ +-+ rcu_read_lock(); +-+ +-+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta) == 0 && !IS_ERR(sta)) { +-+ u16 queue = __ieee80211_select_queue(sdata, sta, skb); +-+ +-+ skb_set_queue_mapping(skb, queue); +-+ skb_get_hash(skb); +-+ } +-+ +-+ rcu_read_unlock(); +-+ +- /* mutex lock is only needed for incrementing the cookie counter */ +- mutex_lock(&local->mtx); +- +diff --git a/package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch b/package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch +new file mode 100644 +index 0000000000..9c7417e5fc +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch +@@ -0,0 +1,74 @@ ++From: Felix Fietkau ++Date: Mon, 24 May 2021 11:46:09 +0200 ++Subject: [PATCH] mac80211_hwsim: make 6 GHz channels usable ++ ++The previous commit that claimed to add 6 GHz channels didn't actually make ++them usable, since the 6 GHz band was not registered with mac80211. ++ ++Fixes: 28881922abd7 ("mac80211_hwsim: add 6GHz channels") ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/wireless/mac80211_hwsim.c +++++ b/drivers/net/wireless/mac80211_hwsim.c ++@@ -2992,15 +2992,19 @@ static void mac80211_hwsim_he_capab(stru ++ { ++ u16 n_iftype_data; ++ ++- if (sband->band == NL80211_BAND_2GHZ) { +++ switch (sband->band) { +++ case NL80211_BAND_2GHZ: ++ n_iftype_data = ARRAY_SIZE(he_capa_2ghz); ++ sband->iftype_data = ++ (struct ieee80211_sband_iftype_data *)he_capa_2ghz; ++- } else if (sband->band == NL80211_BAND_5GHZ) { +++ break; +++ case NL80211_BAND_5GHZ: +++ case NL80211_BAND_6GHZ: ++ n_iftype_data = ARRAY_SIZE(he_capa_5ghz); ++ sband->iftype_data = ++ (struct ieee80211_sband_iftype_data *)he_capa_5ghz; ++- } else { +++ break; +++ default: ++ return; ++ } ++ ++@@ -3290,6 +3294,12 @@ static int mac80211_hwsim_new_radio(stru ++ sband->vht_cap.vht_mcs.tx_mcs_map = ++ sband->vht_cap.vht_mcs.rx_mcs_map; ++ break; +++ case NL80211_BAND_6GHZ: +++ sband->channels = data->channels_6ghz; +++ sband->n_channels = ARRAY_SIZE(hwsim_channels_6ghz); +++ sband->bitrates = data->rates + 4; +++ sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4; +++ break; ++ case NL80211_BAND_S1GHZ: ++ memcpy(&sband->s1g_cap, &hwsim_s1g_cap, ++ sizeof(sband->s1g_cap)); ++@@ -3300,6 +3310,13 @@ static int mac80211_hwsim_new_radio(stru ++ continue; ++ } ++ +++ mac80211_hwsim_he_capab(sband); +++ +++ hw->wiphy->bands[band] = sband; +++ +++ if (band == NL80211_BAND_6GHZ) +++ continue; +++ ++ sband->ht_cap.ht_supported = true; ++ sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | ++ IEEE80211_HT_CAP_GRN_FLD | ++@@ -3313,10 +3330,6 @@ static int mac80211_hwsim_new_radio(stru ++ sband->ht_cap.mcs.rx_mask[0] = 0xff; ++ sband->ht_cap.mcs.rx_mask[1] = 0xff; ++ sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; ++- ++- mac80211_hwsim_he_capab(sband); ++- ++- hw->wiphy->bands[band] = sband; ++ } ++ ++ /* By default all radios belong to the first group */ +diff --git a/package/kernel/mac80211/patches/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch b/package/kernel/mac80211/patches/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch +deleted file mode 100644 +index f667d2c94e..0000000000 +--- a/package/kernel/mac80211/patches/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch ++++ /dev/null +@@ -1,166 +0,0 @@ +-From: Felix Fietkau +-Date: Fri, 25 Dec 2020 16:22:52 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: clean up CCK code +- +-- move ack overhead out of rate duration table +-- remove cck_supported, cck_supported_short +- +-Preparation for adding OFDM legacy rates support +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -136,20 +136,16 @@ +- __VHT_GROUP(_streams, _sgi, _bw, \ +- VHT_GROUP_SHIFT(_streams, _sgi, _bw)) +- +--#define CCK_DURATION(_bitrate, _short, _len) \ +-+#define CCK_DURATION(_bitrate, _short) \ +- (1000 * (10 /* SIFS */ + \ +- (_short ? 72 + 24 : 144 + 48) + \ +-- (8 * (_len + 4) * 10) / (_bitrate))) +-- +--#define CCK_ACK_DURATION(_bitrate, _short) \ +-- (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \ +-- CCK_DURATION(_bitrate, _short, AVG_PKT_SIZE)) +-+ (8 * (AVG_PKT_SIZE + 4) * 10) / (_bitrate))) +- +- #define CCK_DURATION_LIST(_short, _s) \ +-- CCK_ACK_DURATION(10, _short) >> _s, \ +-- CCK_ACK_DURATION(20, _short) >> _s, \ +-- CCK_ACK_DURATION(55, _short) >> _s, \ +-- CCK_ACK_DURATION(110, _short) >> _s +-+ CCK_DURATION(10, _short) >> _s, \ +-+ CCK_DURATION(20, _short) >> _s, \ +-+ CCK_DURATION(55, _short) >> _s, \ +-+ CCK_DURATION(110, _short) >> _s +- +- #define __CCK_GROUP(_s) \ +- [MINSTREL_CCK_GROUP] = { \ +-@@ -163,7 +159,7 @@ +- } +- +- #define CCK_GROUP_SHIFT \ +-- GROUP_SHIFT(CCK_ACK_DURATION(10, false)) +-+ GROUP_SHIFT(CCK_DURATION(10, false)) +- +- #define CCK_GROUP __CCK_GROUP(CCK_GROUP_SHIFT) +- +-@@ -349,15 +345,19 @@ int +- minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate, +- int prob_avg) +- { +-- unsigned int nsecs = 0; +-+ unsigned int nsecs = 0, overhead = mi->overhead; +-+ unsigned int ampdu_len = 1; +- +- /* do not account throughput if sucess prob is below 10% */ +- if (prob_avg < MINSTREL_FRAC(10, 100)) +- return 0; +- +-- if (group != MINSTREL_CCK_GROUP) +-- nsecs = 1000 * mi->overhead / minstrel_ht_avg_ampdu_len(mi); +-+ if (group == MINSTREL_CCK_GROUP) +-+ overhead = mi->overhead_legacy; +-+ else +-+ ampdu_len = minstrel_ht_avg_ampdu_len(mi); +- +-+ nsecs = 1000 * overhead / ampdu_len; +- nsecs += minstrel_mcs_groups[group].duration[rate] << +- minstrel_mcs_groups[group].shift; +- +-@@ -1031,7 +1031,10 @@ minstrel_calc_retransmit(struct minstrel +- ctime += (t_slot * cw) >> 1; +- cw = min((cw << 1) | 1, mp->cw_max); +- +-- if (index / MCS_GROUP_RATES != MINSTREL_CCK_GROUP) { +-+ if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { +-+ overhead = mi->overhead_legacy; +-+ overhead_rtscts = mi->overhead_legacy_rtscts; +-+ } else { +- overhead = mi->overhead; +- overhead_rtscts = mi->overhead_rtscts; +- } +-@@ -1369,18 +1372,14 @@ minstrel_ht_update_cck(struct minstrel_p +- if (!ieee80211_hw_check(mp->hw, SUPPORTS_HT_CCK_RATES)) +- return; +- +-- mi->cck_supported = 0; +-- mi->cck_supported_short = 0; +- for (i = 0; i < 4; i++) { +- if (!rate_supported(sta, sband->band, mp->cck_rates[i])) +- continue; +- +-- mi->cck_supported |= BIT(i); +-+ mi->supported[MINSTREL_CCK_GROUP] |= BIT(i); +- if (sband->bitrates[i].flags & IEEE80211_RATE_SHORT_PREAMBLE) +-- mi->cck_supported_short |= BIT(i); +-+ mi->supported[MINSTREL_CCK_GROUP] |= BIT(i + 4); +- } +-- +-- mi->supported[MINSTREL_CCK_GROUP] = mi->cck_supported; +- } +- +- static void +-@@ -1394,12 +1393,13 @@ minstrel_ht_update_caps(void *priv, stru +- struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; +- u16 ht_cap = sta->ht_cap.cap; +- struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; +-+ const struct ieee80211_rate *ctl_rate; +-+ bool ldpc, erp; +- int use_vht; +- int n_supported = 0; +- int ack_dur; +- int stbc; +- int i; +-- bool ldpc; +- +- /* fall back to the old minstrel for legacy stations */ +- if (!sta->ht_cap.ht_supported) +-@@ -1423,6 +1423,14 @@ minstrel_ht_update_caps(void *priv, stru +- mi->overhead += ack_dur; +- mi->overhead_rtscts = mi->overhead + 2 * ack_dur; +- +-+ ctl_rate = &sband->bitrates[rate_lowest_index(sband, sta)]; +-+ erp = ctl_rate->flags & IEEE80211_RATE_ERP_G; +-+ ack_dur = ieee80211_frame_duration(sband->band, 10, +-+ ctl_rate->bitrate, erp, 1, +-+ ieee80211_chandef_get_shift(chandef)); +-+ mi->overhead_legacy = ack_dur; +-+ mi->overhead_legacy_rtscts = mi->overhead_legacy + 2 * ack_dur; +-+ +- mi->avg_ampdu_len = MINSTREL_FRAC(1, 1); +- +- /* When using MRR, sample more on the first attempt, without delay */ +-@@ -1523,8 +1531,6 @@ minstrel_ht_update_caps(void *priv, stru +- if (!n_supported) +- goto use_legacy; +- +-- mi->supported[MINSTREL_CCK_GROUP] |= mi->cck_supported_short << 4; +-- +- /* create an initial rate table with the lowest supported rates */ +- minstrel_ht_update_stats(mp, mi, true); +- minstrel_ht_update_rates(mp, mi); +---- a/net/mac80211/rc80211_minstrel_ht.h +-+++ b/net/mac80211/rc80211_minstrel_ht.h +-@@ -77,6 +77,8 @@ struct minstrel_ht_sta { +- /* overhead time in usec for each frame */ +- unsigned int overhead; +- unsigned int overhead_rtscts; +-+ unsigned int overhead_legacy; +-+ unsigned int overhead_legacy_rtscts; +- +- unsigned int total_packets_last; +- unsigned int total_packets_cur; +-@@ -97,9 +99,6 @@ struct minstrel_ht_sta { +- /* current MCS group to be sampled */ +- u8 sample_group; +- +-- u8 cck_supported; +-- u8 cck_supported_short; +-- +- /* Bitfield of supported MCS rates of all groups */ +- u16 supported[MINSTREL_GROUPS_NB]; +- +diff --git a/package/kernel/mac80211/patches/subsys/338-mac80211-minstrel_ht-add-support-for-OFDM-rates-on-n.patch b/package/kernel/mac80211/patches/subsys/338-mac80211-minstrel_ht-add-support-for-OFDM-rates-on-n.patch +deleted file mode 100644 +index abefde7109..0000000000 +--- a/package/kernel/mac80211/patches/subsys/338-mac80211-minstrel_ht-add-support-for-OFDM-rates-on-n.patch ++++ /dev/null +@@ -1,762 +0,0 @@ +-From: Felix Fietkau +-Date: Sat, 26 Dec 2020 13:56:42 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: add support for OFDM rates on +- non-HT clients +- +-The legacy minstrel code is essentially unmaintained and receives only very +-little testing. In order to bring the significant algorithm improvements from +-minstrel_ht to legacy clients, this patch adds support for OFDM rates to +-minstrel_ht and removes the fallback to the legacy codepath. +-This also makes it work much better on hardware with rate selection constraints, +-e.g. mt76. +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel.h +-+++ b/net/mac80211/rc80211_minstrel.h +-@@ -152,6 +152,7 @@ struct minstrel_priv { +- unsigned int lookaround_rate_mrr; +- +- u8 cck_rates[4]; +-+ u8 ofdm_rates[NUM_NL80211_BANDS][8]; +- +- #ifdef CPTCFG_MAC80211_DEBUGFS +- /* +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -163,6 +163,38 @@ +- +- #define CCK_GROUP __CCK_GROUP(CCK_GROUP_SHIFT) +- +-+#define OFDM_DURATION(_bitrate) \ +-+ (1000 * (16 /* SIFS + signal ext */ + \ +-+ 16 /* T_PREAMBLE */ + \ +-+ 4 /* T_SIGNAL */ + \ +-+ 4 * (((16 + 80 * (AVG_PKT_SIZE + 4) + 6) / \ +-+ ((_bitrate) * 4))))) +-+ +-+#define OFDM_DURATION_LIST(_s) \ +-+ OFDM_DURATION(60) >> _s, \ +-+ OFDM_DURATION(90) >> _s, \ +-+ OFDM_DURATION(120) >> _s, \ +-+ OFDM_DURATION(180) >> _s, \ +-+ OFDM_DURATION(240) >> _s, \ +-+ OFDM_DURATION(360) >> _s, \ +-+ OFDM_DURATION(480) >> _s, \ +-+ OFDM_DURATION(540) >> _s +-+ +-+#define __OFDM_GROUP(_s) \ +-+ [MINSTREL_OFDM_GROUP] = { \ +-+ .streams = 1, \ +-+ .flags = 0, \ +-+ .shift = _s, \ +-+ .duration = { \ +-+ OFDM_DURATION_LIST(_s), \ +-+ } \ +-+ } +-+ +-+#define OFDM_GROUP_SHIFT \ +-+ GROUP_SHIFT(OFDM_DURATION(60)) +-+ +-+#define OFDM_GROUP __OFDM_GROUP(OFDM_GROUP_SHIFT) +-+ +- +- static bool minstrel_vht_only = true; +- module_param(minstrel_vht_only, bool, 0644); +-@@ -199,6 +231,7 @@ const struct mcs_group minstrel_mcs_grou +- MCS_GROUP(4, 1, BW_40), +- +- CCK_GROUP, +-+ OFDM_GROUP, +- +- VHT_GROUP(1, 0, BW_20), +- VHT_GROUP(2, 0, BW_20), +-@@ -231,6 +264,8 @@ const struct mcs_group minstrel_mcs_grou +- VHT_GROUP(4, 1, BW_80), +- }; +- +-+const s16 minstrel_cck_bitrates[4] = { 10, 20, 55, 110 }; +-+const s16 minstrel_ofdm_bitrates[8] = { 60, 90, 120, 180, 240, 360, 480, 540 }; +- static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; +- +- static void +-@@ -275,6 +310,13 @@ minstrel_get_valid_vht_rates(int bw, int +- return 0x3ff & ~mask; +- } +- +-+static bool +-+minstrel_ht_is_legacy_group(int group) +-+{ +-+ return group == MINSTREL_CCK_GROUP || +-+ group == MINSTREL_OFDM_GROUP; +-+} +-+ +- /* +- * Look up an MCS group index based on mac80211 rate information +- */ +-@@ -304,21 +346,34 @@ minstrel_ht_get_stats(struct minstrel_pr +- if (rate->flags & IEEE80211_TX_RC_MCS) { +- group = minstrel_ht_get_group_idx(rate); +- idx = rate->idx % 8; +-- } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { +-+ goto out; +-+ } +-+ +-+ if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { +- group = minstrel_vht_get_group_idx(rate); +- idx = ieee80211_rate_get_vht_mcs(rate); +-- } else { +-- group = MINSTREL_CCK_GROUP; +-+ goto out; +-+ } +- +-- for (idx = 0; idx < ARRAY_SIZE(mp->cck_rates); idx++) +-- if (rate->idx == mp->cck_rates[idx]) +-- break; +-+ group = MINSTREL_CCK_GROUP; +-+ for (idx = 0; idx < ARRAY_SIZE(mp->cck_rates); idx++) { +-+ if (rate->idx != mp->cck_rates[idx]) +-+ continue; +- +- /* short preamble */ +- if ((mi->supported[group] & BIT(idx + 4)) && +- (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) +-- idx += 4; +-+ idx += 4; +-+ goto out; +- } +-+ +-+ group = MINSTREL_OFDM_GROUP; +-+ for (idx = 0; idx < ARRAY_SIZE(mp->ofdm_rates[0]); idx++) +-+ if (rate->idx == mp->ofdm_rates[mi->band][idx]) +-+ goto out; +-+ +-+ idx = 0; +-+out: +- return &mi->groups[group].rates[idx]; +- } +- +-@@ -352,7 +407,7 @@ minstrel_ht_get_tp_avg(struct minstrel_h +- if (prob_avg < MINSTREL_FRAC(10, 100)) +- return 0; +- +-- if (group == MINSTREL_CCK_GROUP) +-+ if (minstrel_ht_is_legacy_group(group)) +- overhead = mi->overhead_legacy; +- else +- ampdu_len = minstrel_ht_avg_ampdu_len(mi); +-@@ -439,8 +494,8 @@ minstrel_ht_set_best_prob_rate(struct mi +- /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from +- * MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */ +- max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES; +-- if((index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) && +-- (max_tp_group != MINSTREL_CCK_GROUP)) +-+ if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) && +-+ !minstrel_ht_is_legacy_group(max_tp_group)) +- return; +- +- max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES; +-@@ -476,13 +531,13 @@ minstrel_ht_set_best_prob_rate(struct mi +- static void +- minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi, +- u16 tmp_mcs_tp_rate[MAX_THR_RATES], +-- u16 tmp_cck_tp_rate[MAX_THR_RATES]) +-+ u16 tmp_legacy_tp_rate[MAX_THR_RATES]) +- { +- unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp, tmp_prob; +- int i; +- +-- tmp_group = tmp_cck_tp_rate[0] / MCS_GROUP_RATES; +-- tmp_idx = tmp_cck_tp_rate[0] % MCS_GROUP_RATES; +-+ tmp_group = tmp_legacy_tp_rate[0] / MCS_GROUP_RATES; +-+ tmp_idx = tmp_legacy_tp_rate[0] % MCS_GROUP_RATES; +- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; +- tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); +- +-@@ -493,7 +548,7 @@ minstrel_ht_assign_best_tp_rates(struct +- +- if (tmp_cck_tp > tmp_mcs_tp) { +- for(i = 0; i < MAX_THR_RATES; i++) { +-- minstrel_ht_sort_best_tp_rates(mi, tmp_cck_tp_rate[i], +-+ minstrel_ht_sort_best_tp_rates(mi, tmp_legacy_tp_rate[i], +- tmp_mcs_tp_rate); +- } +- } +-@@ -511,6 +566,9 @@ minstrel_ht_prob_rate_reduce_streams(str +- int tmp_max_streams, group, tmp_idx, tmp_prob; +- int tmp_tp = 0; +- +-+ if (!mi->sta->ht_cap.ht_supported) +-+ return; +-+ +- tmp_max_streams = minstrel_mcs_groups[mi->max_tp_rate[0] / +- MCS_GROUP_RATES].streams; +- for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { +-@@ -675,7 +733,8 @@ minstrel_ht_update_stats(struct minstrel +- struct minstrel_rate_stats *mrs; +- int group, i, j, cur_prob; +- u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; +-- u16 tmp_cck_tp_rate[MAX_THR_RATES], index; +-+ u16 tmp_legacy_tp_rate[MAX_THR_RATES], index; +-+ bool ht_supported = mi->sta->ht_cap.ht_supported; +- +- mi->sample_mode = MINSTREL_SAMPLE_IDLE; +- +-@@ -704,21 +763,29 @@ minstrel_ht_update_stats(struct minstrel +- mi->sample_count = 0; +- +- memset(tmp_mcs_tp_rate, 0, sizeof(tmp_mcs_tp_rate)); +-- memset(tmp_cck_tp_rate, 0, sizeof(tmp_cck_tp_rate)); +-+ memset(tmp_legacy_tp_rate, 0, sizeof(tmp_legacy_tp_rate)); +- if (mi->supported[MINSTREL_CCK_GROUP]) +-- for (j = 0; j < ARRAY_SIZE(tmp_cck_tp_rate); j++) +-- tmp_cck_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; +-+ for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++) +-+ tmp_legacy_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; +-+ else if (mi->supported[MINSTREL_OFDM_GROUP]) +-+ for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++) +-+ tmp_legacy_tp_rate[j] = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES; +- +- if (mi->supported[MINSTREL_VHT_GROUP_0]) +- index = MINSTREL_VHT_GROUP_0 * MCS_GROUP_RATES; +-- else +-+ else if (ht_supported) +- index = MINSTREL_HT_GROUP_0 * MCS_GROUP_RATES; +-+ else if (mi->supported[MINSTREL_CCK_GROUP]) +-+ index = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; +-+ else +-+ index = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES; +- +- for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++) +- tmp_mcs_tp_rate[j] = index; +- +- /* Find best rate sets within all MCS groups*/ +- for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { +-+ u16 *tp_rate = tmp_mcs_tp_rate; +- +- mg = &mi->groups[group]; +- if (!mi->supported[group]) +-@@ -730,6 +797,9 @@ minstrel_ht_update_stats(struct minstrel +- for(j = 0; j < MAX_THR_RATES; j++) +- tmp_group_tp_rate[j] = MCS_GROUP_RATES * group; +- +-+ if (group == MINSTREL_CCK_GROUP && ht_supported) +-+ tp_rate = tmp_legacy_tp_rate; +-+ +- for (i = 0; i < MCS_GROUP_RATES; i++) { +- if (!(mi->supported[group] & BIT(i))) +- continue; +-@@ -745,13 +815,7 @@ minstrel_ht_update_stats(struct minstrel +- continue; +- +- /* Find max throughput rate set */ +-- if (group != MINSTREL_CCK_GROUP) { +-- minstrel_ht_sort_best_tp_rates(mi, index, +-- tmp_mcs_tp_rate); +-- } else if (group == MINSTREL_CCK_GROUP) { +-- minstrel_ht_sort_best_tp_rates(mi, index, +-- tmp_cck_tp_rate); +-- } +-+ minstrel_ht_sort_best_tp_rates(mi, index, tp_rate); +- +- /* Find max throughput rate set within a group */ +- minstrel_ht_sort_best_tp_rates(mi, index, +-@@ -766,7 +830,8 @@ minstrel_ht_update_stats(struct minstrel +- } +- +- /* Assign new rate set per sta */ +-- minstrel_ht_assign_best_tp_rates(mi, tmp_mcs_tp_rate, tmp_cck_tp_rate); +-+ minstrel_ht_assign_best_tp_rates(mi, tmp_mcs_tp_rate, +-+ tmp_legacy_tp_rate); +- memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate)); +- +- /* Try to increase robustness of max_prob_rate*/ +-@@ -795,8 +860,11 @@ minstrel_ht_update_stats(struct minstrel +- } +- +- static bool +--minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct ieee80211_tx_rate *rate) +-+minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, +-+ struct ieee80211_tx_rate *rate) +- { +-+ int i; +-+ +- if (rate->idx < 0) +- return false; +- +-@@ -807,10 +875,15 @@ minstrel_ht_txstat_valid(struct minstrel +- rate->flags & IEEE80211_TX_RC_VHT_MCS) +- return true; +- +-- return rate->idx == mp->cck_rates[0] || +-- rate->idx == mp->cck_rates[1] || +-- rate->idx == mp->cck_rates[2] || +-- rate->idx == mp->cck_rates[3]; +-+ for (i = 0; i < ARRAY_SIZE(mp->cck_rates); i++) +-+ if (rate->idx == mp->cck_rates[i]) +-+ return true; +-+ +-+ for (i = 0; i < ARRAY_SIZE(mp->ofdm_rates[0]); i++) +-+ if (rate->idx == mp->ofdm_rates[mi->band][i]) +-+ return true; +-+ +-+ return false; +- } +- +- static void +-@@ -897,11 +970,6 @@ minstrel_ht_tx_status(void *priv, struct +- bool sample_status = false; +- int i; +- +-- if (!msp->is_ht) +-- return mac80211_minstrel.tx_status_ext(priv, sband, +-- &msp->legacy, st); +-- +-- +- /* This packet was aggregated but doesn't carry status info */ +- if ((info->flags & IEEE80211_TX_CTL_AMPDU) && +- !(info->flags & IEEE80211_TX_STAT_AMPDU)) +-@@ -930,10 +998,10 @@ minstrel_ht_tx_status(void *priv, struct +- if (mi->sample_mode != MINSTREL_SAMPLE_IDLE) +- rate_sample = minstrel_get_ratestats(mi, mi->sample_rate); +- +-- last = !minstrel_ht_txstat_valid(mp, &ar[0]); +-+ last = !minstrel_ht_txstat_valid(mp, mi, &ar[0]); +- for (i = 0; !last; i++) { +- last = (i == IEEE80211_TX_MAX_RATES - 1) || +-- !minstrel_ht_txstat_valid(mp, &ar[i + 1]); +-+ !minstrel_ht_txstat_valid(mp, mi, &ar[i + 1]); +- +- rate = minstrel_ht_get_stats(mp, mi, &ar[i]); +- if (rate == rate_sample) +-@@ -1031,7 +1099,7 @@ minstrel_calc_retransmit(struct minstrel +- ctime += (t_slot * cw) >> 1; +- cw = min((cw << 1) | 1, mp->cw_max); +- +-- if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { +-+ if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES)) { +- overhead = mi->overhead_legacy; +- overhead_rtscts = mi->overhead_legacy_rtscts; +- } else { +-@@ -1064,7 +1132,8 @@ static void +- minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, +- struct ieee80211_sta_rates *ratetbl, int offset, int index) +- { +-- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +-+ int group_idx = index / MCS_GROUP_RATES; +-+ const struct mcs_group *group = &minstrel_mcs_groups[group_idx]; +- struct minstrel_rate_stats *mrs; +- u8 idx; +- u16 flags = group->flags; +-@@ -1083,13 +1152,17 @@ minstrel_ht_set_rate(struct minstrel_pri +- ratetbl->rate[offset].count_rts = mrs->retry_count_rtscts; +- } +- +-- if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) +-+ index %= MCS_GROUP_RATES; +-+ if (group_idx == MINSTREL_CCK_GROUP) +- idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; +-+ else if (group_idx == MINSTREL_OFDM_GROUP) +-+ idx = mp->ofdm_rates[mi->band][index % +-+ ARRAY_SIZE(mp->ofdm_rates[0])]; +- else if (flags & IEEE80211_TX_RC_VHT_MCS) +- idx = ((group->streams - 1) << 4) | +-- ((index % MCS_GROUP_RATES) & 0xF); +-+ (index & 0xF); +- else +-- idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; +-+ idx = index + (group->streams - 1) * 8; +- +- /* enable RTS/CTS if needed: +- * - if station is in dynamic SMPS (and streams > 1) +-@@ -1304,11 +1377,8 @@ minstrel_ht_get_rate(void *priv, struct +- struct minstrel_priv *mp = priv; +- int sample_idx; +- +-- if (!msp->is_ht) +-- return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc); +-- +- if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && +-- mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP) +-+ !minstrel_ht_is_legacy_group(mi->max_prob_rate / MCS_GROUP_RATES)) +- minstrel_aggr_check(sta, txrc->skb); +- +- info->flags |= mi->tx_flags; +-@@ -1349,6 +1419,9 @@ minstrel_ht_get_rate(void *priv, struct +- if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP]) { +- int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); +- rate->idx = mp->cck_rates[idx]; +-+ } else if (sample_group == &minstrel_mcs_groups[MINSTREL_OFDM_GROUP]) { +-+ int idx = sample_idx % ARRAY_SIZE(mp->ofdm_rates[0]); +-+ rate->idx = mp->ofdm_rates[mi->band][idx]; +- } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { +- ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, +- sample_group->streams); +-@@ -1369,11 +1442,13 @@ minstrel_ht_update_cck(struct minstrel_p +- if (sband->band != NL80211_BAND_2GHZ) +- return; +- +-- if (!ieee80211_hw_check(mp->hw, SUPPORTS_HT_CCK_RATES)) +-+ if (sta->ht_cap.ht_supported && +-+ !ieee80211_hw_check(mp->hw, SUPPORTS_HT_CCK_RATES)) +- return; +- +- for (i = 0; i < 4; i++) { +-- if (!rate_supported(sta, sband->band, mp->cck_rates[i])) +-+ if (mp->cck_rates[i] == 0xff || +-+ !rate_supported(sta, sband->band, mp->cck_rates[i])) +- continue; +- +- mi->supported[MINSTREL_CCK_GROUP] |= BIT(i); +-@@ -1383,9 +1458,30 @@ minstrel_ht_update_cck(struct minstrel_p +- } +- +- static void +-+minstrel_ht_update_ofdm(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, +-+ struct ieee80211_supported_band *sband, +-+ struct ieee80211_sta *sta) +-+{ +-+ const u8 *rates; +-+ int i; +-+ +-+ if (sta->ht_cap.ht_supported) +-+ return; +-+ +-+ rates = mp->ofdm_rates[sband->band]; +-+ for (i = 0; i < ARRAY_SIZE(mp->ofdm_rates[0]); i++) { +-+ if (rates[i] == 0xff || +-+ !rate_supported(sta, sband->band, rates[i])) +-+ continue; +-+ +-+ mi->supported[MINSTREL_OFDM_GROUP] |= BIT(i); +-+ } +-+} +-+ +-+static void +- minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, +- struct cfg80211_chan_def *chandef, +-- struct ieee80211_sta *sta, void *priv_sta) +-+ struct ieee80211_sta *sta, void *priv_sta) +- { +- struct minstrel_priv *mp = priv; +- struct minstrel_ht_sta_priv *msp = priv_sta; +-@@ -1401,10 +1497,6 @@ minstrel_ht_update_caps(void *priv, stru +- int stbc; +- int i; +- +-- /* fall back to the old minstrel for legacy stations */ +-- if (!sta->ht_cap.ht_supported) +-- goto use_legacy; +-- +- BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB); +- +- if (vht_cap->vht_supported) +-@@ -1412,10 +1504,10 @@ minstrel_ht_update_caps(void *priv, stru +- else +- use_vht = 0; +- +-- msp->is_ht = true; +- memset(mi, 0, sizeof(*mi)); +- +- mi->sta = sta; +-+ mi->band = sband->band; +- mi->last_stats_update = jiffies; +- +- ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1, 0); +-@@ -1464,10 +1556,8 @@ minstrel_ht_update_caps(void *priv, stru +- int bw, nss; +- +- mi->supported[i] = 0; +-- if (i == MINSTREL_CCK_GROUP) { +-- minstrel_ht_update_cck(mp, mi, sband, sta); +-+ if (minstrel_ht_is_legacy_group(i)) +- continue; +-- } +- +- if (gflags & IEEE80211_TX_RC_SHORT_GI) { +- if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) { +-@@ -1528,22 +1618,12 @@ minstrel_ht_update_caps(void *priv, stru +- n_supported++; +- } +- +-- if (!n_supported) +-- goto use_legacy; +-+ minstrel_ht_update_cck(mp, mi, sband, sta); +-+ minstrel_ht_update_ofdm(mp, mi, sband, sta); +- +- /* create an initial rate table with the lowest supported rates */ +- minstrel_ht_update_stats(mp, mi, true); +- minstrel_ht_update_rates(mp, mi); +-- +-- return; +-- +--use_legacy: +-- msp->is_ht = false; +-- memset(&msp->legacy, 0, sizeof(msp->legacy)); +-- msp->legacy.r = msp->ratelist; +-- msp->legacy.sample_table = msp->sample_table; +-- return mac80211_minstrel.rate_init(priv, sband, chandef, sta, +-- &msp->legacy); +- } +- +- static void +-@@ -1611,40 +1691,70 @@ minstrel_ht_free_sta(void *priv, struct +- } +- +- static void +--minstrel_ht_init_cck_rates(struct minstrel_priv *mp) +-+minstrel_ht_fill_rate_array(u8 *dest, struct ieee80211_supported_band *sband, +-+ const s16 *bitrates, int n_rates, u32 rate_flags) +- { +-- static const int bitrates[4] = { 10, 20, 55, 110 }; +-- struct ieee80211_supported_band *sband; +-- u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); +- int i, j; +- +-- sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ]; +-- if (!sband) +-- return; +-- +- for (i = 0; i < sband->n_bitrates; i++) { +- struct ieee80211_rate *rate = &sband->bitrates[i]; +- +-- if (rate->flags & IEEE80211_RATE_ERP_G) +-- continue; +-- +- if ((rate_flags & sband->bitrates[i].flags) != rate_flags) +- continue; +- +-- for (j = 0; j < ARRAY_SIZE(bitrates); j++) { +-+ for (j = 0; j < n_rates; j++) { +- if (rate->bitrate != bitrates[j]) +- continue; +- +-- mp->cck_rates[j] = i; +-+ dest[j] = i; +- break; +- } +- } +- } +- +-+static void +-+minstrel_ht_init_cck_rates(struct minstrel_priv *mp) +-+{ +-+ static const s16 bitrates[4] = { 10, 20, 55, 110 }; +-+ struct ieee80211_supported_band *sband; +-+ u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); +-+ +-+ memset(mp->cck_rates, 0xff, sizeof(mp->cck_rates)); +-+ sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ]; +-+ if (!sband) +-+ return; +-+ +-+ BUILD_BUG_ON(ARRAY_SIZE(mp->cck_rates) != ARRAY_SIZE(bitrates)); +-+ minstrel_ht_fill_rate_array(mp->cck_rates, sband, +-+ minstrel_cck_bitrates, +-+ ARRAY_SIZE(minstrel_cck_bitrates), +-+ rate_flags); +-+} +-+ +-+static void +-+minstrel_ht_init_ofdm_rates(struct minstrel_priv *mp, enum nl80211_band band) +-+{ +-+ static const s16 bitrates[8] = { 60, 90, 120, 180, 240, 360, 480, 540 }; +-+ struct ieee80211_supported_band *sband; +-+ u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); +-+ +-+ memset(mp->ofdm_rates[band], 0xff, sizeof(mp->ofdm_rates[band])); +-+ sband = mp->hw->wiphy->bands[band]; +-+ if (!sband) +-+ return; +-+ +-+ BUILD_BUG_ON(ARRAY_SIZE(mp->ofdm_rates[band]) != ARRAY_SIZE(bitrates)); +-+ minstrel_ht_fill_rate_array(mp->ofdm_rates[band], sband, +-+ minstrel_ofdm_bitrates, +-+ ARRAY_SIZE(minstrel_ofdm_bitrates), +-+ rate_flags); +-+} +-+ +- static void * +- minstrel_ht_alloc(struct ieee80211_hw *hw) +- { +- struct minstrel_priv *mp; +-+ int i; +- +- mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC); +- if (!mp) +-@@ -1681,6 +1791,8 @@ minstrel_ht_alloc(struct ieee80211_hw *h +- mp->new_avg = true; +- +- minstrel_ht_init_cck_rates(mp); +-+ for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++) +-+ minstrel_ht_init_ofdm_rates(mp, i); +- +- return mp; +- } +-@@ -1713,9 +1825,6 @@ static u32 minstrel_ht_get_expected_thro +- struct minstrel_ht_sta *mi = &msp->ht; +- int i, j, prob, tp_avg; +- +-- if (!msp->is_ht) +-- return mac80211_minstrel.get_expected_throughput(priv_sta); +-- +- i = mi->max_tp_rate[0] / MCS_GROUP_RATES; +- j = mi->max_tp_rate[0] % MCS_GROUP_RATES; +- prob = mi->groups[i].rates[j].prob_avg; +---- a/net/mac80211/rc80211_minstrel_ht.h +-+++ b/net/mac80211/rc80211_minstrel_ht.h +-@@ -18,14 +18,15 @@ +- MINSTREL_HT_STREAM_GROUPS) +- #define MINSTREL_VHT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ +- MINSTREL_VHT_STREAM_GROUPS) +--#define MINSTREL_CCK_GROUPS_NB 1 +-+#define MINSTREL_LEGACY_GROUPS_NB 2 +- #define MINSTREL_GROUPS_NB (MINSTREL_HT_GROUPS_NB + \ +- MINSTREL_VHT_GROUPS_NB + \ +-- MINSTREL_CCK_GROUPS_NB) +-+ MINSTREL_LEGACY_GROUPS_NB) +- +- #define MINSTREL_HT_GROUP_0 0 +- #define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) +--#define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1) +-+#define MINSTREL_OFDM_GROUP (MINSTREL_CCK_GROUP + 1) +-+#define MINSTREL_VHT_GROUP_0 (MINSTREL_OFDM_GROUP + 1) +- +- #define MCS_GROUP_RATES 10 +- +-@@ -37,6 +38,8 @@ struct mcs_group { +- u16 duration[MCS_GROUP_RATES]; +- }; +- +-+extern const s16 minstrel_cck_bitrates[4]; +-+extern const s16 minstrel_ofdm_bitrates[8]; +- extern const struct mcs_group minstrel_mcs_groups[]; +- +- struct minstrel_mcs_group_data { +-@@ -99,6 +102,8 @@ struct minstrel_ht_sta { +- /* current MCS group to be sampled */ +- u8 sample_group; +- +-+ u8 band; +-+ +- /* Bitfield of supported MCS rates of all groups */ +- u16 supported[MINSTREL_GROUPS_NB]; +- +-@@ -107,13 +112,9 @@ struct minstrel_ht_sta { +- }; +- +- struct minstrel_ht_sta_priv { +-- union { +-- struct minstrel_ht_sta ht; +-- struct minstrel_sta_info legacy; +-- }; +-+ struct minstrel_ht_sta ht; +- void *ratelist; +- void *sample_table; +-- bool is_ht; +- }; +- +- void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); +---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +-+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +-@@ -52,7 +52,6 @@ minstrel_ht_stats_dump(struct minstrel_h +- +- for (j = 0; j < MCS_GROUP_RATES; j++) { +- struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; +-- static const int bitrates[4] = { 10, 20, 55, 110 }; +- int idx = i * MCS_GROUP_RATES + j; +- unsigned int duration; +- +-@@ -67,6 +66,9 @@ minstrel_ht_stats_dump(struct minstrel_h +- p += sprintf(p, "VHT%c0 ", htmode); +- p += sprintf(p, "%cGI ", gimode); +- p += sprintf(p, "%d ", mg->streams); +-+ } else if (i == MINSTREL_OFDM_GROUP) { +-+ p += sprintf(p, "OFDM "); +-+ p += sprintf(p, "1 "); +- } else { +- p += sprintf(p, "CCK "); +- p += sprintf(p, "%cP ", j < 4 ? 'L' : 'S'); +-@@ -84,7 +86,12 @@ minstrel_ht_stats_dump(struct minstrel_h +- } else if (gflags & IEEE80211_TX_RC_VHT_MCS) { +- p += sprintf(p, " MCS%-1u/%1u", j, mg->streams); +- } else { +-- int r = bitrates[j % 4]; +-+ int r; +-+ +-+ if (i == MINSTREL_OFDM_GROUP) +-+ r = minstrel_ofdm_bitrates[j % 8]; +-+ else +-+ r = minstrel_cck_bitrates[j % 4]; +- +- p += sprintf(p, " %2u.%1uM", r / 10, r % 10); +- } +-@@ -124,16 +131,8 @@ minstrel_ht_stats_open(struct inode *ino +- struct minstrel_ht_sta *mi = &msp->ht; +- struct minstrel_debugfs_info *ms; +- unsigned int i; +-- int ret; +- char *p; +- +-- if (!msp->is_ht) { +-- inode->i_private = &msp->legacy; +-- ret = minstrel_stats_open(inode, file); +-- inode->i_private = msp; +-- return ret; +-- } +-- +- ms = kmalloc(32768, GFP_KERNEL); +- if (!ms) +- return -ENOMEM; +-@@ -199,7 +198,6 @@ minstrel_ht_stats_csv_dump(struct minstr +- +- for (j = 0; j < MCS_GROUP_RATES; j++) { +- struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; +-- static const int bitrates[4] = { 10, 20, 55, 110 }; +- int idx = i * MCS_GROUP_RATES + j; +- unsigned int duration; +- +-@@ -214,6 +212,8 @@ minstrel_ht_stats_csv_dump(struct minstr +- p += sprintf(p, "VHT%c0,", htmode); +- p += sprintf(p, "%cGI,", gimode); +- p += sprintf(p, "%d,", mg->streams); +-+ } else if (i == MINSTREL_OFDM_GROUP) { +-+ p += sprintf(p, "OFDM,,1,"); +- } else { +- p += sprintf(p, "CCK,"); +- p += sprintf(p, "%cP,", j < 4 ? 'L' : 'S'); +-@@ -231,7 +231,13 @@ minstrel_ht_stats_csv_dump(struct minstr +- } else if (gflags & IEEE80211_TX_RC_VHT_MCS) { +- p += sprintf(p, ",MCS%-1u/%1u,", j, mg->streams); +- } else { +-- int r = bitrates[j % 4]; +-+ int r; +-+ +-+ if (i == MINSTREL_OFDM_GROUP) +-+ r = minstrel_ofdm_bitrates[j % 8]; +-+ else +-+ r = minstrel_cck_bitrates[j % 4]; +-+ +- p += sprintf(p, ",%2u.%1uM,", r / 10, r % 10); +- } +- +-@@ -274,18 +280,9 @@ minstrel_ht_stats_csv_open(struct inode +- struct minstrel_ht_sta *mi = &msp->ht; +- struct minstrel_debugfs_info *ms; +- unsigned int i; +-- int ret; +- char *p; +- +-- if (!msp->is_ht) { +-- inode->i_private = &msp->legacy; +-- ret = minstrel_stats_csv_open(inode, file); +-- inode->i_private = msp; +-- return ret; +-- } +-- +- ms = kmalloc(32768, GFP_KERNEL); +-- +- if (!ms) +- return -ENOMEM; +- +diff --git a/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch b/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch +deleted file mode 100644 +index 96ee595ac1..0000000000 +--- a/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch ++++ /dev/null +@@ -1,1328 +0,0 @@ +-From: Felix Fietkau +-Date: Sat, 26 Dec 2020 14:23:47 +0100 +-Subject: [PATCH] mac80211: remove legacy minstrel rate control +- +-Now that minstrel_ht supports legacy rates, it is no longer needed +- +-Signed-off-by: Felix Fietkau +---- +- delete mode 100644 net/mac80211/rc80211_minstrel.c +- delete mode 100644 net/mac80211/rc80211_minstrel.h +- delete mode 100644 net/mac80211/rc80211_minstrel_debugfs.c +- +---- a/net/mac80211/Makefile +-+++ b/net/mac80211/Makefile +-@@ -55,11 +55,9 @@ mac80211-$(CONFIG_PM) += pm.o +- CFLAGS_trace.o := -I$(src) +- +- rc80211_minstrel-y := \ +-- rc80211_minstrel.o \ +- rc80211_minstrel_ht.o +- +- rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += \ +-- rc80211_minstrel_debugfs.o \ +- rc80211_minstrel_ht_debugfs.o +- +- mac80211-$(CPTCFG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) +---- a/net/mac80211/rc80211_minstrel.c +-+++ /dev/null +-@@ -1,574 +0,0 @@ +--/* +-- * Copyright (C) 2008 Felix Fietkau +-- * +-- * This program is free software; you can redistribute it and/or modify +-- * it under the terms of the GNU General Public License version 2 as +-- * published by the Free Software Foundation. +-- * +-- * Based on minstrel.c: +-- * Copyright (C) 2005-2007 Derek Smithies +-- * Sponsored by Indranet Technologies Ltd +-- * +-- * Based on sample.c: +-- * Copyright (c) 2005 John Bicket +-- * All rights reserved. +-- * +-- * Redistribution and use in source and binary forms, with or without +-- * modification, are permitted provided that the following conditions +-- * are met: +-- * 1. Redistributions of source code must retain the above copyright +-- * notice, this list of conditions and the following disclaimer, +-- * without modification. +-- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +-- * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any +-- * redistribution must be conditioned upon including a substantially +-- * similar Disclaimer requirement for further binary redistribution. +-- * 3. Neither the names of the above-listed copyright holders nor the names +-- * of any contributors may be used to endorse or promote products derived +-- * from this software without specific prior written permission. +-- * +-- * Alternatively, this software may be distributed under the terms of the +-- * GNU General Public License ("GPL") version 2 as published by the Free +-- * Software Foundation. +-- * +-- * NO WARRANTY +-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY +-- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +-- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, +-- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +-- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +-- * THE POSSIBILITY OF SUCH DAMAGES. +-- */ +--#include +--#include +--#include +--#include +--#include +--#include +--#include +--#include +--#include "rate.h" +--#include "rc80211_minstrel.h" +-- +--#define SAMPLE_TBL(_mi, _idx, _col) \ +-- _mi->sample_table[(_idx * SAMPLE_COLUMNS) + _col] +-- +--/* convert mac80211 rate index to local array index */ +--static inline int +--rix_to_ndx(struct minstrel_sta_info *mi, int rix) +--{ +-- int i = rix; +-- for (i = rix; i >= 0; i--) +-- if (mi->r[i].rix == rix) +-- break; +-- return i; +--} +-- +--/* return current EMWA throughput */ +--int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg) +--{ +-- int usecs; +-- +-- usecs = mr->perfect_tx_time; +-- if (!usecs) +-- usecs = 1000000; +-- +-- /* reset thr. below 10% success */ +-- if (mr->stats.prob_avg < MINSTREL_FRAC(10, 100)) +-- return 0; +-- +-- if (prob_avg > MINSTREL_FRAC(90, 100)) +-- return MINSTREL_TRUNC(100000 * (MINSTREL_FRAC(90, 100) / usecs)); +-- else +-- return MINSTREL_TRUNC(100000 * (prob_avg / usecs)); +--} +-- +--/* find & sort topmost throughput rates */ +--static inline void +--minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list) +--{ +-- int j; +-- struct minstrel_rate_stats *tmp_mrs; +-- struct minstrel_rate_stats *cur_mrs = &mi->r[i].stats; +-- +-- for (j = MAX_THR_RATES; j > 0; --j) { +-- tmp_mrs = &mi->r[tp_list[j - 1]].stats; +-- if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_avg) <= +-- minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_avg)) +-- break; +-- } +-- +-- if (j < MAX_THR_RATES - 1) +-- memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1)); +-- if (j < MAX_THR_RATES) +-- tp_list[j] = i; +--} +-- +--static void +--minstrel_set_rate(struct minstrel_sta_info *mi, struct ieee80211_sta_rates *ratetbl, +-- int offset, int idx) +--{ +-- struct minstrel_rate *r = &mi->r[idx]; +-- +-- ratetbl->rate[offset].idx = r->rix; +-- ratetbl->rate[offset].count = r->adjusted_retry_count; +-- ratetbl->rate[offset].count_cts = r->retry_count_cts; +-- ratetbl->rate[offset].count_rts = r->stats.retry_count_rtscts; +--} +-- +--static void +--minstrel_update_rates(struct minstrel_priv *mp, struct minstrel_sta_info *mi) +--{ +-- struct ieee80211_sta_rates *ratetbl; +-- int i = 0; +-- +-- ratetbl = kzalloc(sizeof(*ratetbl), GFP_ATOMIC); +-- if (!ratetbl) +-- return; +-- +-- /* Start with max_tp_rate */ +-- minstrel_set_rate(mi, ratetbl, i++, mi->max_tp_rate[0]); +-- +-- if (mp->hw->max_rates >= 3) { +-- /* At least 3 tx rates supported, use max_tp_rate2 next */ +-- minstrel_set_rate(mi, ratetbl, i++, mi->max_tp_rate[1]); +-- } +-- +-- if (mp->hw->max_rates >= 2) { +-- /* At least 2 tx rates supported, use max_prob_rate next */ +-- minstrel_set_rate(mi, ratetbl, i++, mi->max_prob_rate); +-- } +-- +-- /* Use lowest rate last */ +-- ratetbl->rate[i].idx = mi->lowest_rix; +-- ratetbl->rate[i].count = mp->max_retry; +-- ratetbl->rate[i].count_cts = mp->max_retry; +-- ratetbl->rate[i].count_rts = mp->max_retry; +-- +-- rate_control_set_rates(mp->hw, mi->sta, ratetbl); +--} +-- +--/* +--* Recalculate statistics and counters of a given rate +--*/ +--void +--minstrel_calc_rate_stats(struct minstrel_priv *mp, +-- struct minstrel_rate_stats *mrs) +--{ +-- unsigned int cur_prob; +-- +-- if (unlikely(mrs->attempts > 0)) { +-- mrs->sample_skipped = 0; +-- cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); +-- if (mp->new_avg) { +-- minstrel_filter_avg_add(&mrs->prob_avg, +-- &mrs->prob_avg_1, cur_prob); +-- } else if (unlikely(!mrs->att_hist)) { +-- mrs->prob_avg = cur_prob; +-- } else { +-- /*update exponential weighted moving avarage */ +-- mrs->prob_avg = minstrel_ewma(mrs->prob_avg, +-- cur_prob, +-- EWMA_LEVEL); +-- } +-- mrs->att_hist += mrs->attempts; +-- mrs->succ_hist += mrs->success; +-- } else { +-- mrs->sample_skipped++; +-- } +-- +-- mrs->last_success = mrs->success; +-- mrs->last_attempts = mrs->attempts; +-- mrs->success = 0; +-- mrs->attempts = 0; +--} +-- +--static void +--minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) +--{ +-- u8 tmp_tp_rate[MAX_THR_RATES]; +-- u8 tmp_prob_rate = 0; +-- int i, tmp_cur_tp, tmp_prob_tp; +-- +-- for (i = 0; i < MAX_THR_RATES; i++) +-- tmp_tp_rate[i] = 0; +-- +-- for (i = 0; i < mi->n_rates; i++) { +-- struct minstrel_rate *mr = &mi->r[i]; +-- struct minstrel_rate_stats *mrs = &mi->r[i].stats; +-- struct minstrel_rate_stats *tmp_mrs = &mi->r[tmp_prob_rate].stats; +-- +-- /* Update statistics of success probability per rate */ +-- minstrel_calc_rate_stats(mp, mrs); +-- +-- /* Sample less often below the 10% chance of success. +-- * Sample less often above the 95% chance of success. */ +-- if (mrs->prob_avg > MINSTREL_FRAC(95, 100) || +-- mrs->prob_avg < MINSTREL_FRAC(10, 100)) { +-- mr->adjusted_retry_count = mrs->retry_count >> 1; +-- if (mr->adjusted_retry_count > 2) +-- mr->adjusted_retry_count = 2; +-- mr->sample_limit = 4; +-- } else { +-- mr->sample_limit = -1; +-- mr->adjusted_retry_count = mrs->retry_count; +-- } +-- if (!mr->adjusted_retry_count) +-- mr->adjusted_retry_count = 2; +-- +-- minstrel_sort_best_tp_rates(mi, i, tmp_tp_rate); +-- +-- /* To determine the most robust rate (max_prob_rate) used at +-- * 3rd mmr stage we distinct between two cases: +-- * (1) if any success probabilitiy >= 95%, out of those rates +-- * choose the maximum throughput rate as max_prob_rate +-- * (2) if all success probabilities < 95%, the rate with +-- * highest success probability is chosen as max_prob_rate */ +-- if (mrs->prob_avg >= MINSTREL_FRAC(95, 100)) { +-- tmp_cur_tp = minstrel_get_tp_avg(mr, mrs->prob_avg); +-- tmp_prob_tp = minstrel_get_tp_avg(&mi->r[tmp_prob_rate], +-- tmp_mrs->prob_avg); +-- if (tmp_cur_tp >= tmp_prob_tp) +-- tmp_prob_rate = i; +-- } else { +-- if (mrs->prob_avg >= tmp_mrs->prob_avg) +-- tmp_prob_rate = i; +-- } +-- } +-- +-- /* Assign the new rate set */ +-- memcpy(mi->max_tp_rate, tmp_tp_rate, sizeof(mi->max_tp_rate)); +-- mi->max_prob_rate = tmp_prob_rate; +-- +--#ifdef CPTCFG_MAC80211_DEBUGFS +-- /* use fixed index if set */ +-- if (mp->fixed_rate_idx != -1) { +-- mi->max_tp_rate[0] = mp->fixed_rate_idx; +-- mi->max_tp_rate[1] = mp->fixed_rate_idx; +-- mi->max_prob_rate = mp->fixed_rate_idx; +-- } +--#endif +-- +-- /* Reset update timer */ +-- mi->last_stats_update = jiffies; +-- +-- minstrel_update_rates(mp, mi); +--} +-- +--static void +--minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, +-- void *priv_sta, struct ieee80211_tx_status *st) +--{ +-- struct ieee80211_tx_info *info = st->info; +-- struct minstrel_priv *mp = priv; +-- struct minstrel_sta_info *mi = priv_sta; +-- struct ieee80211_tx_rate *ar = info->status.rates; +-- int i, ndx; +-- int success; +-- +-- success = !!(info->flags & IEEE80211_TX_STAT_ACK); +-- +-- for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { +-- if (ar[i].idx < 0 || !ar[i].count) +-- break; +-- +-- ndx = rix_to_ndx(mi, ar[i].idx); +-- if (ndx < 0) +-- continue; +-- +-- mi->r[ndx].stats.attempts += ar[i].count; +-- +-- if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) +-- mi->r[ndx].stats.success += success; +-- } +-- +-- if (time_after(jiffies, mi->last_stats_update + +-- mp->update_interval / (mp->new_avg ? 2 : 1))) +-- minstrel_update_stats(mp, mi); +--} +-- +-- +--static inline unsigned int +--minstrel_get_retry_count(struct minstrel_rate *mr, +-- struct ieee80211_tx_info *info) +--{ +-- u8 retry = mr->adjusted_retry_count; +-- +-- if (info->control.use_rts) +-- retry = max_t(u8, 2, min(mr->stats.retry_count_rtscts, retry)); +-- else if (info->control.use_cts_prot) +-- retry = max_t(u8, 2, min(mr->retry_count_cts, retry)); +-- return retry; +--} +-- +-- +--static int +--minstrel_get_next_sample(struct minstrel_sta_info *mi) +--{ +-- unsigned int sample_ndx; +-- sample_ndx = SAMPLE_TBL(mi, mi->sample_row, mi->sample_column); +-- mi->sample_row++; +-- if ((int) mi->sample_row >= mi->n_rates) { +-- mi->sample_row = 0; +-- mi->sample_column++; +-- if (mi->sample_column >= SAMPLE_COLUMNS) +-- mi->sample_column = 0; +-- } +-- return sample_ndx; +--} +-- +--static void +--minstrel_get_rate(void *priv, struct ieee80211_sta *sta, +-- void *priv_sta, struct ieee80211_tx_rate_control *txrc) +--{ +-- struct sk_buff *skb = txrc->skb; +-- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +-- struct minstrel_sta_info *mi = priv_sta; +-- struct minstrel_priv *mp = priv; +-- struct ieee80211_tx_rate *rate = &info->control.rates[0]; +-- struct minstrel_rate *msr, *mr; +-- unsigned int ndx; +-- bool mrr_capable; +-- bool prev_sample; +-- int delta; +-- int sampling_ratio; +-- +-- /* check multi-rate-retry capabilities & adjust lookaround_rate */ +-- mrr_capable = mp->has_mrr && +-- !txrc->rts && +-- !txrc->bss_conf->use_cts_prot; +-- if (mrr_capable) +-- sampling_ratio = mp->lookaround_rate_mrr; +-- else +-- sampling_ratio = mp->lookaround_rate; +-- +-- /* increase sum packet counter */ +-- mi->total_packets++; +-- +--#ifdef CPTCFG_MAC80211_DEBUGFS +-- if (mp->fixed_rate_idx != -1) +-- return; +--#endif +-- +-- /* Don't use EAPOL frames for sampling on non-mrr hw */ +-- if (mp->hw->max_rates == 1 && +-- (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) +-- return; +-- +-- delta = (mi->total_packets * sampling_ratio / 100) - +-- mi->sample_packets; +-- +-- /* delta < 0: no sampling required */ +-- prev_sample = mi->prev_sample; +-- mi->prev_sample = false; +-- if (delta < 0 || (!mrr_capable && prev_sample)) +-- return; +-- +-- if (mi->total_packets >= 10000) { +-- mi->sample_packets = 0; +-- mi->total_packets = 0; +-- } else if (delta > mi->n_rates * 2) { +-- /* With multi-rate retry, not every planned sample +-- * attempt actually gets used, due to the way the retry +-- * chain is set up - [max_tp,sample,prob,lowest] for +-- * sample_rate < max_tp. +-- * +-- * If there's too much sampling backlog and the link +-- * starts getting worse, minstrel would start bursting +-- * out lots of sampling frames, which would result +-- * in a large throughput loss. */ +-- mi->sample_packets += (delta - mi->n_rates * 2); +-- } +-- +-- /* get next random rate sample */ +-- ndx = minstrel_get_next_sample(mi); +-- msr = &mi->r[ndx]; +-- mr = &mi->r[mi->max_tp_rate[0]]; +-- +-- /* Decide if direct ( 1st mrr stage) or indirect (2nd mrr stage) +-- * rate sampling method should be used. +-- * Respect such rates that are not sampled for 20 interations. +-- */ +-- if (msr->perfect_tx_time < mr->perfect_tx_time || +-- msr->stats.sample_skipped >= 20) { +-- if (!msr->sample_limit) +-- return; +-- +-- mi->sample_packets++; +-- if (msr->sample_limit > 0) +-- msr->sample_limit--; +-- } +-- +-- /* If we're not using MRR and the sampling rate already +-- * has a probability of >95%, we shouldn't be attempting +-- * to use it, as this only wastes precious airtime */ +-- if (!mrr_capable && +-- (mi->r[ndx].stats.prob_avg > MINSTREL_FRAC(95, 100))) +-- return; +-- +-- mi->prev_sample = true; +-- +-- rate->idx = mi->r[ndx].rix; +-- rate->count = minstrel_get_retry_count(&mi->r[ndx], info); +-- info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; +--} +-- +-- +--static void +--calc_rate_durations(enum nl80211_band band, +-- struct minstrel_rate *d, +-- struct ieee80211_rate *rate, +-- struct cfg80211_chan_def *chandef) +--{ +-- int erp = !!(rate->flags & IEEE80211_RATE_ERP_G); +-- int shift = ieee80211_chandef_get_shift(chandef); +-- +-- d->perfect_tx_time = ieee80211_frame_duration(band, 1200, +-- DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1, +-- shift); +-- d->ack_time = ieee80211_frame_duration(band, 10, +-- DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1, +-- shift); +--} +-- +--static void +--init_sample_table(struct minstrel_sta_info *mi) +--{ +-- unsigned int i, col, new_idx; +-- u8 rnd[8]; +-- +-- mi->sample_column = 0; +-- mi->sample_row = 0; +-- memset(mi->sample_table, 0xff, SAMPLE_COLUMNS * mi->n_rates); +-- +-- for (col = 0; col < SAMPLE_COLUMNS; col++) { +-- prandom_bytes(rnd, sizeof(rnd)); +-- for (i = 0; i < mi->n_rates; i++) { +-- new_idx = (i + rnd[i & 7]) % mi->n_rates; +-- while (SAMPLE_TBL(mi, new_idx, col) != 0xff) +-- new_idx = (new_idx + 1) % mi->n_rates; +-- +-- SAMPLE_TBL(mi, new_idx, col) = i; +-- } +-- } +--} +-- +--static void +--minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, +-- struct cfg80211_chan_def *chandef, +-- struct ieee80211_sta *sta, void *priv_sta) +--{ +-- struct minstrel_sta_info *mi = priv_sta; +-- struct minstrel_priv *mp = priv; +-- struct ieee80211_rate *ctl_rate; +-- unsigned int i, n = 0; +-- unsigned int t_slot = 9; /* FIXME: get real slot time */ +-- u32 rate_flags; +-- +-- mi->sta = sta; +-- mi->lowest_rix = rate_lowest_index(sband, sta); +-- ctl_rate = &sband->bitrates[mi->lowest_rix]; +-- mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10, +-- ctl_rate->bitrate, +-- !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1, +-- ieee80211_chandef_get_shift(chandef)); +-- +-- rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); +-- memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate)); +-- mi->max_prob_rate = 0; +-- +-- for (i = 0; i < sband->n_bitrates; i++) { +-- struct minstrel_rate *mr = &mi->r[n]; +-- struct minstrel_rate_stats *mrs = &mi->r[n].stats; +-- unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; +-- unsigned int tx_time_single; +-- unsigned int cw = mp->cw_min; +-- int shift; +-- +-- if (!rate_supported(sta, sband->band, i)) +-- continue; +-- if ((rate_flags & sband->bitrates[i].flags) != rate_flags) +-- continue; +-- +-- n++; +-- memset(mr, 0, sizeof(*mr)); +-- memset(mrs, 0, sizeof(*mrs)); +-- +-- mr->rix = i; +-- shift = ieee80211_chandef_get_shift(chandef); +-- mr->bitrate = DIV_ROUND_UP(sband->bitrates[i].bitrate, +-- (1 << shift) * 5); +-- calc_rate_durations(sband->band, mr, &sband->bitrates[i], +-- chandef); +-- +-- /* calculate maximum number of retransmissions before +-- * fallback (based on maximum segment size) */ +-- mr->sample_limit = -1; +-- mrs->retry_count = 1; +-- mr->retry_count_cts = 1; +-- mrs->retry_count_rtscts = 1; +-- tx_time = mr->perfect_tx_time + mi->sp_ack_dur; +-- do { +-- /* add one retransmission */ +-- tx_time_single = mr->ack_time + mr->perfect_tx_time; +-- +-- /* contention window */ +-- tx_time_single += (t_slot * cw) >> 1; +-- cw = min((cw << 1) | 1, mp->cw_max); +-- +-- tx_time += tx_time_single; +-- tx_time_cts += tx_time_single + mi->sp_ack_dur; +-- tx_time_rtscts += tx_time_single + 2 * mi->sp_ack_dur; +-- if ((tx_time_cts < mp->segment_size) && +-- (mr->retry_count_cts < mp->max_retry)) +-- mr->retry_count_cts++; +-- if ((tx_time_rtscts < mp->segment_size) && +-- (mrs->retry_count_rtscts < mp->max_retry)) +-- mrs->retry_count_rtscts++; +-- } while ((tx_time < mp->segment_size) && +-- (++mr->stats.retry_count < mp->max_retry)); +-- mr->adjusted_retry_count = mrs->retry_count; +-- if (!(sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)) +-- mr->retry_count_cts = mrs->retry_count; +-- } +-- +-- for (i = n; i < sband->n_bitrates; i++) { +-- struct minstrel_rate *mr = &mi->r[i]; +-- mr->rix = -1; +-- } +-- +-- mi->n_rates = n; +-- mi->last_stats_update = jiffies; +-- +-- init_sample_table(mi); +-- minstrel_update_rates(mp, mi); +--} +-- +--static u32 minstrel_get_expected_throughput(void *priv_sta) +--{ +-- struct minstrel_sta_info *mi = priv_sta; +-- struct minstrel_rate_stats *tmp_mrs; +-- int idx = mi->max_tp_rate[0]; +-- int tmp_cur_tp; +-- +-- /* convert pkt per sec in kbps (1200 is the average pkt size used for +-- * computing cur_tp +-- */ +-- tmp_mrs = &mi->r[idx].stats; +-- tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_avg) * 10; +-- tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024; +-- +-- return tmp_cur_tp; +--} +-- +--const struct rate_control_ops mac80211_minstrel = { +-- .tx_status_ext = minstrel_tx_status, +-- .get_rate = minstrel_get_rate, +-- .rate_init = minstrel_rate_init, +-- .get_expected_throughput = minstrel_get_expected_throughput, +--}; +---- a/net/mac80211/rc80211_minstrel.h +-+++ /dev/null +-@@ -1,185 +0,0 @@ +--/* SPDX-License-Identifier: GPL-2.0-only */ +--/* +-- * Copyright (C) 2008 Felix Fietkau +-- */ +-- +--#ifndef __RC_MINSTREL_H +--#define __RC_MINSTREL_H +-- +--#define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */ +--#define EWMA_DIV 128 +--#define SAMPLE_COLUMNS 10 /* number of columns in sample table */ +-- +--/* scaled fraction values */ +--#define MINSTREL_SCALE 12 +--#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) +--#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) +-- +--/* number of highest throughput rates to consider*/ +--#define MAX_THR_RATES 4 +-- +--/* +-- * Coefficients for moving average with noise filter (period=16), +-- * scaled by 10 bits +-- * +-- * a1 = exp(-pi * sqrt(2) / period) +-- * coeff2 = 2 * a1 * cos(sqrt(2) * 2 * pi / period) +-- * coeff3 = -sqr(a1) +-- * coeff1 = 1 - coeff2 - coeff3 +-- */ +--#define MINSTREL_AVG_COEFF1 (MINSTREL_FRAC(1, 1) - \ +-- MINSTREL_AVG_COEFF2 - \ +-- MINSTREL_AVG_COEFF3) +--#define MINSTREL_AVG_COEFF2 0x00001499 +--#define MINSTREL_AVG_COEFF3 -0x0000092e +-- +--/* +-- * Perform EWMA (Exponentially Weighted Moving Average) calculation +-- */ +--static inline int +--minstrel_ewma(int old, int new, int weight) +--{ +-- int diff, incr; +-- +-- diff = new - old; +-- incr = (EWMA_DIV - weight) * diff / EWMA_DIV; +-- +-- return old + incr; +--} +-- +--static inline int minstrel_filter_avg_add(u16 *prev_1, u16 *prev_2, s32 in) +--{ +-- s32 out_1 = *prev_1; +-- s32 out_2 = *prev_2; +-- s32 val; +-- +-- if (!in) +-- in += 1; +-- +-- if (!out_1) { +-- val = out_1 = in; +-- goto out; +-- } +-- +-- val = MINSTREL_AVG_COEFF1 * in; +-- val += MINSTREL_AVG_COEFF2 * out_1; +-- val += MINSTREL_AVG_COEFF3 * out_2; +-- val >>= MINSTREL_SCALE; +-- +-- if (val > 1 << MINSTREL_SCALE) +-- val = 1 << MINSTREL_SCALE; +-- if (val < 0) +-- val = 1; +-- +--out: +-- *prev_2 = out_1; +-- *prev_1 = val; +-- +-- return val; +--} +-- +--struct minstrel_rate_stats { +-- /* current / last sampling period attempts/success counters */ +-- u16 attempts, last_attempts; +-- u16 success, last_success; +-- +-- /* total attempts/success counters */ +-- u32 att_hist, succ_hist; +-- +-- /* prob_avg - moving average of prob */ +-- u16 prob_avg; +-- u16 prob_avg_1; +-- +-- /* maximum retry counts */ +-- u8 retry_count; +-- u8 retry_count_rtscts; +-- +-- u8 sample_skipped; +-- bool retry_updated; +--}; +-- +--struct minstrel_rate { +-- int bitrate; +-- +-- s8 rix; +-- u8 retry_count_cts; +-- u8 adjusted_retry_count; +-- +-- unsigned int perfect_tx_time; +-- unsigned int ack_time; +-- +-- int sample_limit; +-- +-- struct minstrel_rate_stats stats; +--}; +-- +--struct minstrel_sta_info { +-- struct ieee80211_sta *sta; +-- +-- unsigned long last_stats_update; +-- unsigned int sp_ack_dur; +-- unsigned int rate_avg; +-- +-- unsigned int lowest_rix; +-- +-- u8 max_tp_rate[MAX_THR_RATES]; +-- u8 max_prob_rate; +-- unsigned int total_packets; +-- unsigned int sample_packets; +-- +-- unsigned int sample_row; +-- unsigned int sample_column; +-- +-- int n_rates; +-- struct minstrel_rate *r; +-- bool prev_sample; +-- +-- /* sampling table */ +-- u8 *sample_table; +--}; +-- +--struct minstrel_priv { +-- struct ieee80211_hw *hw; +-- bool has_mrr; +-- bool new_avg; +-- u32 sample_switch; +-- unsigned int cw_min; +-- unsigned int cw_max; +-- unsigned int max_retry; +-- unsigned int segment_size; +-- unsigned int update_interval; +-- unsigned int lookaround_rate; +-- unsigned int lookaround_rate_mrr; +-- +-- u8 cck_rates[4]; +-- u8 ofdm_rates[NUM_NL80211_BANDS][8]; +-- +--#ifdef CPTCFG_MAC80211_DEBUGFS +-- /* +-- * enable fixed rate processing per RC +-- * - write static index to debugfs:ieee80211/phyX/rc/fixed_rate_idx +-- * - write -1 to enable RC processing again +-- * - setting will be applied on next update +-- */ +-- u32 fixed_rate_idx; +--#endif +--}; +-- +--struct minstrel_debugfs_info { +-- size_t len; +-- char buf[]; +--}; +-- +--extern const struct rate_control_ops mac80211_minstrel; +--void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); +-- +--/* Recalculate success probabilities and counters for a given rate using EWMA */ +--void minstrel_calc_rate_stats(struct minstrel_priv *mp, +-- struct minstrel_rate_stats *mrs); +--int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg); +-- +--/* debugfs */ +--int minstrel_stats_open(struct inode *inode, struct file *file); +--int minstrel_stats_csv_open(struct inode *inode, struct file *file); +-- +--#endif +---- a/net/mac80211/rc80211_minstrel_debugfs.c +-+++ /dev/null +-@@ -1,172 +0,0 @@ +--/* +-- * Copyright (C) 2008 Felix Fietkau +-- * +-- * This program is free software; you can redistribute it and/or modify +-- * it under the terms of the GNU General Public License version 2 as +-- * published by the Free Software Foundation. +-- * +-- * Based on minstrel.c: +-- * Copyright (C) 2005-2007 Derek Smithies +-- * Sponsored by Indranet Technologies Ltd +-- * +-- * Based on sample.c: +-- * Copyright (c) 2005 John Bicket +-- * All rights reserved. +-- * +-- * Redistribution and use in source and binary forms, with or without +-- * modification, are permitted provided that the following conditions +-- * are met: +-- * 1. Redistributions of source code must retain the above copyright +-- * notice, this list of conditions and the following disclaimer, +-- * without modification. +-- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +-- * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any +-- * redistribution must be conditioned upon including a substantially +-- * similar Disclaimer requirement for further binary redistribution. +-- * 3. Neither the names of the above-listed copyright holders nor the names +-- * of any contributors may be used to endorse or promote products derived +-- * from this software without specific prior written permission. +-- * +-- * Alternatively, this software may be distributed under the terms of the +-- * GNU General Public License ("GPL") version 2 as published by the Free +-- * Software Foundation. +-- * +-- * NO WARRANTY +-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY +-- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +-- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, +-- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +-- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +-- * THE POSSIBILITY OF SUCH DAMAGES. +-- */ +--#include +--#include +--#include +--#include +--#include +--#include +--#include +--#include +--#include "rc80211_minstrel.h" +-- +--int +--minstrel_stats_open(struct inode *inode, struct file *file) +--{ +-- struct minstrel_sta_info *mi = inode->i_private; +-- struct minstrel_debugfs_info *ms; +-- unsigned int i, tp_max, tp_avg, eprob; +-- char *p; +-- +-- ms = kmalloc(2048, GFP_KERNEL); +-- if (!ms) +-- return -ENOMEM; +-- +-- file->private_data = ms; +-- p = ms->buf; +-- p += sprintf(p, "\n"); +-- p += sprintf(p, +-- "best __________rate_________ ____statistics___ ____last_____ ______sum-of________\n"); +-- p += sprintf(p, +-- "rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n"); +-- +-- for (i = 0; i < mi->n_rates; i++) { +-- struct minstrel_rate *mr = &mi->r[i]; +-- struct minstrel_rate_stats *mrs = &mi->r[i].stats; +-- +-- *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' '; +-- *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' '; +-- *(p++) = (i == mi->max_tp_rate[2]) ? 'C' : ' '; +-- *(p++) = (i == mi->max_tp_rate[3]) ? 'D' : ' '; +-- *(p++) = (i == mi->max_prob_rate) ? 'P' : ' '; +-- +-- p += sprintf(p, " %3u%s ", mr->bitrate / 2, +-- (mr->bitrate & 1 ? ".5" : " ")); +-- p += sprintf(p, "%3u ", i); +-- p += sprintf(p, "%6u ", mr->perfect_tx_time); +-- +-- tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); +-- tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg); +-- eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000); +-- +-- p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u" +-- " %3u %3u %-3u " +-- "%9llu %-9llu\n", +-- tp_max / 10, tp_max % 10, +-- tp_avg / 10, tp_avg % 10, +-- eprob / 10, eprob % 10, +-- mrs->retry_count, +-- mrs->last_success, +-- mrs->last_attempts, +-- (unsigned long long)mrs->succ_hist, +-- (unsigned long long)mrs->att_hist); +-- } +-- p += sprintf(p, "\nTotal packet count:: ideal %d " +-- "lookaround %d\n\n", +-- mi->total_packets - mi->sample_packets, +-- mi->sample_packets); +-- ms->len = p - ms->buf; +-- +-- WARN_ON(ms->len + sizeof(*ms) > 2048); +-- +-- return 0; +--} +-- +--int +--minstrel_stats_csv_open(struct inode *inode, struct file *file) +--{ +-- struct minstrel_sta_info *mi = inode->i_private; +-- struct minstrel_debugfs_info *ms; +-- unsigned int i, tp_max, tp_avg, eprob; +-- char *p; +-- +-- ms = kmalloc(2048, GFP_KERNEL); +-- if (!ms) +-- return -ENOMEM; +-- +-- file->private_data = ms; +-- p = ms->buf; +-- +-- for (i = 0; i < mi->n_rates; i++) { +-- struct minstrel_rate *mr = &mi->r[i]; +-- struct minstrel_rate_stats *mrs = &mi->r[i].stats; +-- +-- p += sprintf(p, "%s" ,((i == mi->max_tp_rate[0]) ? "A" : "")); +-- p += sprintf(p, "%s" ,((i == mi->max_tp_rate[1]) ? "B" : "")); +-- p += sprintf(p, "%s" ,((i == mi->max_tp_rate[2]) ? "C" : "")); +-- p += sprintf(p, "%s" ,((i == mi->max_tp_rate[3]) ? "D" : "")); +-- p += sprintf(p, "%s" ,((i == mi->max_prob_rate) ? "P" : "")); +-- +-- p += sprintf(p, ",%u%s", mr->bitrate / 2, +-- (mr->bitrate & 1 ? ".5," : ",")); +-- p += sprintf(p, "%u,", i); +-- p += sprintf(p, "%u,",mr->perfect_tx_time); +-- +-- tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); +-- tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg); +-- eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000); +-- +-- p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,%u," +-- "%llu,%llu,%d,%d\n", +-- tp_max / 10, tp_max % 10, +-- tp_avg / 10, tp_avg % 10, +-- eprob / 10, eprob % 10, +-- mrs->retry_count, +-- mrs->last_success, +-- mrs->last_attempts, +-- (unsigned long long)mrs->succ_hist, +-- (unsigned long long)mrs->att_hist, +-- mi->total_packets - mi->sample_packets, +-- mi->sample_packets); +-- +-- } +-- ms->len = p - ms->buf; +-- +-- WARN_ON(ms->len + sizeof(*ms) > 2048); +-- +-- return 0; +--} +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -13,7 +13,6 @@ +- #include +- #include "rate.h" +- #include "sta_info.h" +--#include "rc80211_minstrel.h" +- #include "rc80211_minstrel_ht.h" +- +- #define AVG_AMPDU_SIZE 16 +-@@ -716,6 +715,83 @@ out: +- mi->sample_mode = MINSTREL_SAMPLE_ACTIVE; +- } +- +-+static inline int +-+minstrel_ewma(int old, int new, int weight) +-+{ +-+ int diff, incr; +-+ +-+ diff = new - old; +-+ incr = (EWMA_DIV - weight) * diff / EWMA_DIV; +-+ +-+ return old + incr; +-+} +-+ +-+static inline int minstrel_filter_avg_add(u16 *prev_1, u16 *prev_2, s32 in) +-+{ +-+ s32 out_1 = *prev_1; +-+ s32 out_2 = *prev_2; +-+ s32 val; +-+ +-+ if (!in) +-+ in += 1; +-+ +-+ if (!out_1) { +-+ val = out_1 = in; +-+ goto out; +-+ } +-+ +-+ val = MINSTREL_AVG_COEFF1 * in; +-+ val += MINSTREL_AVG_COEFF2 * out_1; +-+ val += MINSTREL_AVG_COEFF3 * out_2; +-+ val >>= MINSTREL_SCALE; +-+ +-+ if (val > 1 << MINSTREL_SCALE) +-+ val = 1 << MINSTREL_SCALE; +-+ if (val < 0) +-+ val = 1; +-+ +-+out: +-+ *prev_2 = out_1; +-+ *prev_1 = val; +-+ +-+ return val; +-+} +-+ +-+/* +-+* Recalculate statistics and counters of a given rate +-+*/ +-+static void +-+minstrel_ht_calc_rate_stats(struct minstrel_priv *mp, +-+ struct minstrel_rate_stats *mrs) +-+{ +-+ unsigned int cur_prob; +-+ +-+ if (unlikely(mrs->attempts > 0)) { +-+ mrs->sample_skipped = 0; +-+ cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); +-+ if (mp->new_avg) { +-+ minstrel_filter_avg_add(&mrs->prob_avg, +-+ &mrs->prob_avg_1, cur_prob); +-+ } else if (unlikely(!mrs->att_hist)) { +-+ mrs->prob_avg = cur_prob; +-+ } else { +-+ /*update exponential weighted moving avarage */ +-+ mrs->prob_avg = minstrel_ewma(mrs->prob_avg, +-+ cur_prob, +-+ EWMA_LEVEL); +-+ } +-+ mrs->att_hist += mrs->attempts; +-+ mrs->succ_hist += mrs->success; +-+ } else { +-+ mrs->sample_skipped++; +-+ } +-+ +-+ mrs->last_success = mrs->success; +-+ mrs->last_attempts = mrs->attempts; +-+ mrs->success = 0; +-+ mrs->attempts = 0; +-+} +-+ +- /* +- * Update rate statistics and select new primary rates +- * +-@@ -808,7 +884,7 @@ minstrel_ht_update_stats(struct minstrel +- +- mrs = &mg->rates[i]; +- mrs->retry_updated = false; +-- minstrel_calc_rate_stats(mp, mrs); +-+ minstrel_ht_calc_rate_stats(mp, mrs); +- cur_prob = mrs->prob_avg; +- +- if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0) +-@@ -960,8 +1036,7 @@ minstrel_ht_tx_status(void *priv, struct +- void *priv_sta, struct ieee80211_tx_status *st) +- { +- struct ieee80211_tx_info *info = st->info; +-- struct minstrel_ht_sta_priv *msp = priv_sta; +-- struct minstrel_ht_sta *mi = &msp->ht; +-+ struct minstrel_ht_sta *mi = priv_sta; +- struct ieee80211_tx_rate *ar = info->status.rates; +- struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL; +- struct minstrel_priv *mp = priv; +-@@ -1372,8 +1447,7 @@ minstrel_ht_get_rate(void *priv, struct +- const struct mcs_group *sample_group; +- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); +- struct ieee80211_tx_rate *rate = &info->status.rates[0]; +-- struct minstrel_ht_sta_priv *msp = priv_sta; +-- struct minstrel_ht_sta *mi = &msp->ht; +-+ struct minstrel_ht_sta *mi = priv_sta; +- struct minstrel_priv *mp = priv; +- int sample_idx; +- +-@@ -1484,8 +1558,7 @@ minstrel_ht_update_caps(void *priv, stru +- struct ieee80211_sta *sta, void *priv_sta) +- { +- struct minstrel_priv *mp = priv; +-- struct minstrel_ht_sta_priv *msp = priv_sta; +-- struct minstrel_ht_sta *mi = &msp->ht; +-+ struct minstrel_ht_sta *mi = priv_sta; +- struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; +- u16 ht_cap = sta->ht_cap.cap; +- struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; +-@@ -1647,7 +1720,7 @@ static void * +- minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) +- { +- struct ieee80211_supported_band *sband; +-- struct minstrel_ht_sta_priv *msp; +-+ struct minstrel_ht_sta *mi; +- struct minstrel_priv *mp = priv; +- struct ieee80211_hw *hw = mp->hw; +- int max_rates = 0; +-@@ -1659,35 +1732,13 @@ minstrel_ht_alloc_sta(void *priv, struct +- max_rates = sband->n_bitrates; +- } +- +-- msp = kzalloc(sizeof(*msp), gfp); +-- if (!msp) +-- return NULL; +-- +-- msp->ratelist = kcalloc(max_rates, sizeof(struct minstrel_rate), gfp); +-- if (!msp->ratelist) +-- goto error; +-- +-- msp->sample_table = kmalloc_array(max_rates, SAMPLE_COLUMNS, gfp); +-- if (!msp->sample_table) +-- goto error1; +-- +-- return msp; +-- +--error1: +-- kfree(msp->ratelist); +--error: +-- kfree(msp); +-- return NULL; +-+ return kzalloc(sizeof(*mi), gfp); +- } +- +- static void +- minstrel_ht_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta) +- { +-- struct minstrel_ht_sta_priv *msp = priv_sta; +-- +-- kfree(msp->sample_table); +-- kfree(msp->ratelist); +-- kfree(msp); +-+ kfree(priv_sta); +- } +- +- static void +-@@ -1768,12 +1819,6 @@ minstrel_ht_alloc(struct ieee80211_hw *h +- mp->cw_min = 15; +- mp->cw_max = 1023; +- +-- /* number of packets (in %) to use for sampling other rates +-- * sample less often for non-mrr packets, because the overhead +-- * is much higher than with mrr */ +-- mp->lookaround_rate = 5; +-- mp->lookaround_rate_mrr = 10; +-- +- /* maximum time that the hw is allowed to stay in one MRR segment */ +- mp->segment_size = 6000; +- +-@@ -1821,8 +1866,7 @@ minstrel_ht_free(void *priv) +- +- static u32 minstrel_ht_get_expected_throughput(void *priv_sta) +- { +-- struct minstrel_ht_sta_priv *msp = priv_sta; +-- struct minstrel_ht_sta *mi = &msp->ht; +-+ struct minstrel_ht_sta *mi = priv_sta; +- int i, j, prob, tp_avg; +- +- i = mi->max_tp_rate[0] / MCS_GROUP_RATES; +---- a/net/mac80211/rc80211_minstrel_ht.h +-+++ b/net/mac80211/rc80211_minstrel_ht.h +-@@ -6,6 +6,33 @@ +- #ifndef __RC_MINSTREL_HT_H +- #define __RC_MINSTREL_HT_H +- +-+/* number of highest throughput rates to consider*/ +-+#define MAX_THR_RATES 4 +-+#define SAMPLE_COLUMNS 10 /* number of columns in sample table */ +-+ +-+/* scaled fraction values */ +-+#define MINSTREL_SCALE 12 +-+#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) +-+#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) +-+ +-+#define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */ +-+#define EWMA_DIV 128 +-+ +-+/* +-+ * Coefficients for moving average with noise filter (period=16), +-+ * scaled by 10 bits +-+ * +-+ * a1 = exp(-pi * sqrt(2) / period) +-+ * coeff2 = 2 * a1 * cos(sqrt(2) * 2 * pi / period) +-+ * coeff3 = -sqr(a1) +-+ * coeff1 = 1 - coeff2 - coeff3 +-+ */ +-+#define MINSTREL_AVG_COEFF1 (MINSTREL_FRAC(1, 1) - \ +-+ MINSTREL_AVG_COEFF2 - \ +-+ MINSTREL_AVG_COEFF3) +-+#define MINSTREL_AVG_COEFF2 0x00001499 +-+#define MINSTREL_AVG_COEFF3 -0x0000092e +-+ +- /* +- * The number of streams can be changed to 2 to reduce code +- * size and memory footprint. +-@@ -30,6 +57,32 @@ +- +- #define MCS_GROUP_RATES 10 +- +-+struct minstrel_priv { +-+ struct ieee80211_hw *hw; +-+ bool has_mrr; +-+ bool new_avg; +-+ u32 sample_switch; +-+ unsigned int cw_min; +-+ unsigned int cw_max; +-+ unsigned int max_retry; +-+ unsigned int segment_size; +-+ unsigned int update_interval; +-+ +-+ u8 cck_rates[4]; +-+ u8 ofdm_rates[NUM_NL80211_BANDS][8]; +-+ +-+#ifdef CPTCFG_MAC80211_DEBUGFS +-+ /* +-+ * enable fixed rate processing per RC +-+ * - write static index to debugfs:ieee80211/phyX/rc/fixed_rate_idx +-+ * - write -1 to enable RC processing again +-+ * - setting will be applied on next update +-+ */ +-+ u32 fixed_rate_idx; +-+#endif +-+}; +-+ +-+ +- struct mcs_group { +- u16 flags; +- u8 streams; +-@@ -42,6 +95,26 @@ extern const s16 minstrel_cck_bitrates[4 +- extern const s16 minstrel_ofdm_bitrates[8]; +- extern const struct mcs_group minstrel_mcs_groups[]; +- +-+struct minstrel_rate_stats { +-+ /* current / last sampling period attempts/success counters */ +-+ u16 attempts, last_attempts; +-+ u16 success, last_success; +-+ +-+ /* total attempts/success counters */ +-+ u32 att_hist, succ_hist; +-+ +-+ /* prob_avg - moving average of prob */ +-+ u16 prob_avg; +-+ u16 prob_avg_1; +-+ +-+ /* maximum retry counts */ +-+ u8 retry_count; +-+ u8 retry_count_rtscts; +-+ +-+ u8 sample_skipped; +-+ bool retry_updated; +-+}; +-+ +- struct minstrel_mcs_group_data { +- u8 index; +- u8 column; +-@@ -111,12 +184,6 @@ struct minstrel_ht_sta { +- struct minstrel_mcs_group_data groups[MINSTREL_GROUPS_NB]; +- }; +- +--struct minstrel_ht_sta_priv { +-- struct minstrel_ht_sta ht; +-- void *ratelist; +-- void *sample_table; +--}; +-- +- void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); +- int minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate, +- int prob_avg); +---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +-+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +-@@ -9,9 +9,13 @@ +- #include +- #include +- #include +--#include "rc80211_minstrel.h" +- #include "rc80211_minstrel_ht.h" +- +-+struct minstrel_debugfs_info { +-+ size_t len; +-+ char buf[]; +-+}; +-+ +- static ssize_t +- minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) +- { +-@@ -127,8 +131,7 @@ minstrel_ht_stats_dump(struct minstrel_h +- static int +- minstrel_ht_stats_open(struct inode *inode, struct file *file) +- { +-- struct minstrel_ht_sta_priv *msp = inode->i_private; +-- struct minstrel_ht_sta *mi = &msp->ht; +-+ struct minstrel_ht_sta *mi = inode->i_private; +- struct minstrel_debugfs_info *ms; +- unsigned int i; +- char *p; +-@@ -276,8 +279,7 @@ minstrel_ht_stats_csv_dump(struct minstr +- static int +- minstrel_ht_stats_csv_open(struct inode *inode, struct file *file) +- { +-- struct minstrel_ht_sta_priv *msp = inode->i_private; +-- struct minstrel_ht_sta *mi = &msp->ht; +-+ struct minstrel_ht_sta *mi = inode->i_private; +- struct minstrel_debugfs_info *ms; +- unsigned int i; +- char *p; +-@@ -313,10 +315,8 @@ static const struct file_operations mins +- void +- minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir) +- { +-- struct minstrel_ht_sta_priv *msp = priv_sta; +-- +-- debugfs_create_file("rc_stats", 0444, dir, msp, +-+ debugfs_create_file("rc_stats", 0444, dir, priv_sta, +- &minstrel_ht_stat_fops); +-- debugfs_create_file("rc_stats_csv", 0444, dir, msp, +-+ debugfs_create_file("rc_stats_csv", 0444, dir, priv_sta, +- &minstrel_ht_stat_csv_fops); +- } +diff --git a/package/kernel/mac80211/patches/subsys/340-mac80211-minstrel_ht-remove-old-ewma-based-rate-aver.patch b/package/kernel/mac80211/patches/subsys/340-mac80211-minstrel_ht-remove-old-ewma-based-rate-aver.patch +deleted file mode 100644 +index 9b6a614aa8..0000000000 +--- a/package/kernel/mac80211/patches/subsys/340-mac80211-minstrel_ht-remove-old-ewma-based-rate-aver.patch ++++ /dev/null +@@ -1,96 +0,0 @@ +-From: Felix Fietkau +-Date: Sat, 26 Dec 2020 14:34:30 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: remove old ewma based rate average +- code +- +-The new noise filter has been the default for a while now with no reported +-downside and significant improvement compared to the old code. +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -769,17 +769,8 @@ minstrel_ht_calc_rate_stats(struct minst +- if (unlikely(mrs->attempts > 0)) { +- mrs->sample_skipped = 0; +- cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); +-- if (mp->new_avg) { +-- minstrel_filter_avg_add(&mrs->prob_avg, +-- &mrs->prob_avg_1, cur_prob); +-- } else if (unlikely(!mrs->att_hist)) { +-- mrs->prob_avg = cur_prob; +-- } else { +-- /*update exponential weighted moving avarage */ +-- mrs->prob_avg = minstrel_ewma(mrs->prob_avg, +-- cur_prob, +-- EWMA_LEVEL); +-- } +-+ minstrel_filter_avg_add(&mrs->prob_avg, +-+ &mrs->prob_avg_1, cur_prob); +- mrs->att_hist += mrs->attempts; +- mrs->succ_hist += mrs->success; +- } else { +-@@ -913,10 +904,8 @@ minstrel_ht_update_stats(struct minstrel +- /* Try to increase robustness of max_prob_rate*/ +- minstrel_ht_prob_rate_reduce_streams(mi); +- +-- /* try to sample all available rates during each interval */ +-- mi->sample_count *= 8; +-- if (mp->new_avg) +-- mi->sample_count /= 2; +-+ /* try to sample half of all available rates during each interval */ +-+ mi->sample_count *= 4; +- +- if (sample) +- minstrel_ht_rate_sample_switch(mp, mi); +-@@ -1040,7 +1029,7 @@ minstrel_ht_tx_status(void *priv, struct +- struct ieee80211_tx_rate *ar = info->status.rates; +- struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL; +- struct minstrel_priv *mp = priv; +-- u32 update_interval = mp->update_interval / 2; +-+ u32 update_interval = mp->update_interval; +- bool last, update = false; +- bool sample_status = false; +- int i; +-@@ -1090,9 +1079,8 @@ minstrel_ht_tx_status(void *priv, struct +- +- switch (mi->sample_mode) { +- case MINSTREL_SAMPLE_IDLE: +-- if (mp->new_avg && +-- (mp->hw->max_rates > 1 || +-- mi->total_packets_cur < SAMPLE_SWITCH_THR)) +-+ if (mp->hw->max_rates > 1 || +-+ mi->total_packets_cur < SAMPLE_SWITCH_THR) +- update_interval /= 2; +- break; +- +-@@ -1832,8 +1820,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h +- mp->has_mrr = true; +- +- mp->hw = hw; +-- mp->update_interval = HZ / 10; +-- mp->new_avg = true; +-+ mp->update_interval = HZ / 20; +- +- minstrel_ht_init_cck_rates(mp); +- for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++) +-@@ -1853,8 +1840,6 @@ static void minstrel_ht_add_debugfs(stru +- &mp->fixed_rate_idx); +- debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir, +- &mp->sample_switch); +-- debugfs_create_bool("new_avg", S_IRUGO | S_IWUSR, debugfsdir, +-- &mp->new_avg); +- } +- #endif +- +---- a/net/mac80211/rc80211_minstrel_ht.h +-+++ b/net/mac80211/rc80211_minstrel_ht.h +-@@ -60,7 +60,6 @@ +- struct minstrel_priv { +- struct ieee80211_hw *hw; +- bool has_mrr; +-- bool new_avg; +- u32 sample_switch; +- unsigned int cw_min; +- unsigned int cw_max; +diff --git a/package/kernel/mac80211/patches/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch b/package/kernel/mac80211/patches/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch +deleted file mode 100644 +index a8e6e89954..0000000000 +--- a/package/kernel/mac80211/patches/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch ++++ /dev/null +@@ -1,67 +0,0 @@ +-From: Felix Fietkau +-Date: Sat, 26 Dec 2020 19:08:19 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: improve ampdu length estimation +- +-If the driver does not report A-MPDU length, estimate it based on the rate. +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -382,13 +382,37 @@ minstrel_get_ratestats(struct minstrel_h +- return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES]; +- } +- +-+static inline int +-+minstrel_get_duration(int index) +-+{ +-+ const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +-+ unsigned int duration = group->duration[index % MCS_GROUP_RATES]; +-+ return duration << group->shift; +-+} +-+ +- static unsigned int +- minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi) +- { +-- if (!mi->avg_ampdu_len) +-- return AVG_AMPDU_SIZE; +-+ int duration; +-+ +-+ if (mi->avg_ampdu_len) +-+ return MINSTREL_TRUNC(mi->avg_ampdu_len); +-+ +-+ if (minstrel_ht_is_legacy_group(mi->max_tp_rate[0] / MCS_GROUP_RATES)) +-+ return 1; +-+ +-+ duration = minstrel_get_duration(mi->max_tp_rate[0]); +- +-- return MINSTREL_TRUNC(mi->avg_ampdu_len); +-+ if (duration > 400 * 1000) +-+ return 2; +-+ +-+ if (duration > 250 * 1000) +-+ return 4; +-+ +-+ if (duration > 150 * 1000) +-+ return 8; +-+ +-+ return 16; +- } +- +- /* +-@@ -588,14 +612,6 @@ minstrel_ht_prob_rate_reduce_streams(str +- } +- } +- +--static inline int +--minstrel_get_duration(int index) +--{ +-- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +-- unsigned int duration = group->duration[index % MCS_GROUP_RATES]; +-- return duration << group->shift; +--} +-- +- static bool +- minstrel_ht_probe_group(struct minstrel_ht_sta *mi, const struct mcs_group *tp_group, +- int tp_idx, const struct mcs_group *group) +diff --git a/package/kernel/mac80211/patches/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch b/package/kernel/mac80211/patches/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch +deleted file mode 100644 +index e084525235..0000000000 +--- a/package/kernel/mac80211/patches/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch ++++ /dev/null +@@ -1,31 +0,0 @@ +-From: Felix Fietkau +-Date: Sat, 26 Dec 2020 19:12:22 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: improve sample rate selection +- +-Always allow sampling of rates faster than the primary max throughput rate. +-When the second max_tp_rate is higher than the first one, sample attempts were +-previously skipped, potentially causing rate control to get stuck at a slightly +-lower rate +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -1379,13 +1379,13 @@ minstrel_get_sample_rate(struct minstrel +- mrs = &mg->rates[sample_idx]; +- sample_idx += sample_group * MCS_GROUP_RATES; +- +-- /* Set tp_rate1, tp_rate2 to the highest / second highest max_tp_rate */ +-+ tp_rate1 = mi->max_tp_rate[0]; +-+ +-+ /* Set tp_rate2 to the second highest max_tp_rate */ +- if (minstrel_get_duration(mi->max_tp_rate[0]) > +- minstrel_get_duration(mi->max_tp_rate[1])) { +-- tp_rate1 = mi->max_tp_rate[1]; +- tp_rate2 = mi->max_tp_rate[0]; +- } else { +-- tp_rate1 = mi->max_tp_rate[0]; +- tp_rate2 = mi->max_tp_rate[1]; +- } +- +diff --git a/package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch b/package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch +deleted file mode 100644 +index 0dbfa9d4fb..0000000000 +--- a/package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch ++++ /dev/null +@@ -1,124 +0,0 @@ +-From: Felix Fietkau +-Date: Sat, 26 Dec 2020 19:09:08 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: fix max probability rate selection +- +-- do not select rates faster than the max throughput rate if probability is lower +-- reset previous rate before sorting again +- +-This ensures that the max prob rate gets set to a more reliable rate +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -495,12 +495,13 @@ minstrel_ht_sort_best_tp_rates(struct mi +- * Find and set the topmost probability rate per sta and per group +- */ +- static void +--minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index) +-+minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index) +- { +- struct minstrel_mcs_group_data *mg; +- struct minstrel_rate_stats *mrs; +- int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob; +-- int max_tp_group, cur_tp_avg, cur_group, cur_idx; +-+ int max_tp_group, max_tp_idx, max_tp_prob; +-+ int cur_tp_avg, cur_group, cur_idx; +- int max_gpr_group, max_gpr_idx; +- int max_gpr_tp_avg, max_gpr_prob; +- +-@@ -509,18 +510,26 @@ minstrel_ht_set_best_prob_rate(struct mi +- mg = &mi->groups[index / MCS_GROUP_RATES]; +- mrs = &mg->rates[index % MCS_GROUP_RATES]; +- +-- tmp_group = mi->max_prob_rate / MCS_GROUP_RATES; +-- tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES; +-+ tmp_group = *dest / MCS_GROUP_RATES; +-+ tmp_idx = *dest % MCS_GROUP_RATES; +- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; +- tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); +- +- /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from +- * MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */ +- max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES; +-+ max_tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES; +-+ max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg; +-+ +- if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) && +- !minstrel_ht_is_legacy_group(max_tp_group)) +- return; +- +-+ /* skip rates faster than max tp rate with lower prob */ +-+ if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) && +-+ mrs->prob_avg < max_tp_prob) +-+ return; +-+ +- max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES; +- max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; +- max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; +-@@ -538,7 +547,7 @@ minstrel_ht_set_best_prob_rate(struct mi +- mg->max_group_prob_rate = index; +- } else { +- if (mrs->prob_avg > tmp_prob) +-- mi->max_prob_rate = index; +-+ *dest = index; +- if (mrs->prob_avg > max_gpr_prob) +- mg->max_group_prob_rate = index; +- } +-@@ -816,7 +825,8 @@ minstrel_ht_update_stats(struct minstrel +- struct minstrel_rate_stats *mrs; +- int group, i, j, cur_prob; +- u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; +-- u16 tmp_legacy_tp_rate[MAX_THR_RATES], index; +-+ u16 tmp_legacy_tp_rate[MAX_THR_RATES], tmp_max_prob_rate; +-+ u16 index; +- bool ht_supported = mi->sta->ht_cap.ht_supported; +- +- mi->sample_mode = MINSTREL_SAMPLE_IDLE; +-@@ -863,6 +873,7 @@ minstrel_ht_update_stats(struct minstrel +- else +- index = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES; +- +-+ tmp_max_prob_rate = index; +- for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++) +- tmp_mcs_tp_rate[j] = index; +- +-@@ -903,9 +914,6 @@ minstrel_ht_update_stats(struct minstrel +- /* Find max throughput rate set within a group */ +- minstrel_ht_sort_best_tp_rates(mi, index, +- tmp_group_tp_rate); +-- +-- /* Find max probability rate per group and global */ +-- minstrel_ht_set_best_prob_rate(mi, index); +- } +- +- memcpy(mg->max_group_tp_rate, tmp_group_tp_rate, +-@@ -917,6 +925,27 @@ minstrel_ht_update_stats(struct minstrel +- tmp_legacy_tp_rate); +- memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate)); +- +-+ for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { +-+ if (!mi->supported[group]) +-+ continue; +-+ +-+ mg = &mi->groups[group]; +-+ mg->max_group_prob_rate = MCS_GROUP_RATES * group; +-+ +-+ for (i = 0; i < MCS_GROUP_RATES; i++) { +-+ if (!(mi->supported[group] & BIT(i))) +-+ continue; +-+ +-+ index = MCS_GROUP_RATES * group + i; +-+ +-+ /* Find max probability rate per group and global */ +-+ minstrel_ht_set_best_prob_rate(mi, &tmp_max_prob_rate, +-+ index); +-+ } +-+ } +-+ +-+ mi->max_prob_rate = tmp_max_prob_rate; +-+ +- /* Try to increase robustness of max_prob_rate*/ +- minstrel_ht_prob_rate_reduce_streams(mi); +- +diff --git a/package/kernel/mac80211/patches/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch b/package/kernel/mac80211/patches/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch +deleted file mode 100644 +index 9972a9414e..0000000000 +--- a/package/kernel/mac80211/patches/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch ++++ /dev/null +@@ -1,20 +0,0 @@ +-From: Felix Fietkau +-Date: Sat, 26 Dec 2020 19:14:58 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: increase stats update interval +- +-The shorter interval was leading to too many frames being used for probing +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -1865,7 +1865,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h +- mp->has_mrr = true; +- +- mp->hw = hw; +-- mp->update_interval = HZ / 20; +-+ mp->update_interval = HZ / 10; +- +- minstrel_ht_init_cck_rates(mp); +- for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++) +diff --git a/package/kernel/mac80211/patches/subsys/345-mac80211-minstrel_ht-fix-rounding-error-in-throughpu.patch b/package/kernel/mac80211/patches/subsys/345-mac80211-minstrel_ht-fix-rounding-error-in-throughpu.patch +deleted file mode 100644 +index 1df5dec039..0000000000 +--- a/package/kernel/mac80211/patches/subsys/345-mac80211-minstrel_ht-fix-rounding-error-in-throughpu.patch ++++ /dev/null +@@ -1,34 +0,0 @@ +-From: Felix Fietkau +-Date: Fri, 15 Jan 2021 12:15:06 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: fix rounding error in throughput +- calculation +- +-On lower data rates, the throughput calculation has a significant rounding +-error, causing rates like 48M and 54M OFDM to share the same throughput +-value with >= 90% success probablity. +- +-This is because the result of the division (prob_avg * 1000) / nsecs +-is really small (8 in this example). +- +-Improve accuracy by moving over some zeroes, making better use of the full +-range of u32 before the division. +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -445,10 +445,9 @@ minstrel_ht_get_tp_avg(struct minstrel_h +- * (prob is scaled - see MINSTREL_FRAC above) +- */ +- if (prob_avg > MINSTREL_FRAC(90, 100)) +-- return MINSTREL_TRUNC(100000 * ((MINSTREL_FRAC(90, 100) * 1000) +-- / nsecs)); +-- else +-- return MINSTREL_TRUNC(100000 * ((prob_avg * 1000) / nsecs)); +-+ prob_avg = MINSTREL_FRAC(90, 100); +-+ +-+ return MINSTREL_TRUNC(100 * ((prob_avg * 1000000) / nsecs)); +- } +- +- /* +diff --git a/package/kernel/mac80211/patches/subsys/346-mac80211-minstrel_ht-use-bitfields-to-encode-rate-in.patch b/package/kernel/mac80211/patches/subsys/346-mac80211-minstrel_ht-use-bitfields-to-encode-rate-in.patch +deleted file mode 100644 +index 6aa6f0ed93..0000000000 +--- a/package/kernel/mac80211/patches/subsys/346-mac80211-minstrel_ht-use-bitfields-to-encode-rate-in.patch ++++ /dev/null +@@ -1,412 +0,0 @@ +-From: Felix Fietkau +-Date: Thu, 21 Jan 2021 18:29:30 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: use bitfields to encode rate +- indexes +- +-Get rid of a lot of divisions and modulo operations +-Reduces code size and improves performance +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -379,14 +379,14 @@ out: +- static inline struct minstrel_rate_stats * +- minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index) +- { +-- return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES]; +-+ return &mi->groups[MI_RATE_GROUP(index)].rates[MI_RATE_IDX(index)]; +- } +- +--static inline int +--minstrel_get_duration(int index) +-+static inline int minstrel_get_duration(int index) +- { +-- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +-- unsigned int duration = group->duration[index % MCS_GROUP_RATES]; +-+ const struct mcs_group *group = &minstrel_mcs_groups[MI_RATE_GROUP(index)]; +-+ unsigned int duration = group->duration[MI_RATE_IDX(index)]; +-+ +- return duration << group->shift; +- } +- +-@@ -398,7 +398,7 @@ minstrel_ht_avg_ampdu_len(struct minstre +- if (mi->avg_ampdu_len) +- return MINSTREL_TRUNC(mi->avg_ampdu_len); +- +-- if (minstrel_ht_is_legacy_group(mi->max_tp_rate[0] / MCS_GROUP_RATES)) +-+ if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_tp_rate[0]))) +- return 1; +- +- duration = minstrel_get_duration(mi->max_tp_rate[0]); +-@@ -465,14 +465,14 @@ minstrel_ht_sort_best_tp_rates(struct mi +- int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob; +- int j = MAX_THR_RATES; +- +-- cur_group = index / MCS_GROUP_RATES; +-- cur_idx = index % MCS_GROUP_RATES; +-+ cur_group = MI_RATE_GROUP(index); +-+ cur_idx = MI_RATE_IDX(index); +- cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg; +- cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob); +- +- do { +-- tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; +-- tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES; +-+ tmp_group = MI_RATE_GROUP(tp_list[j - 1]); +-+ tmp_idx = MI_RATE_IDX(tp_list[j - 1]); +- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; +- tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, +- tmp_prob); +-@@ -504,23 +504,23 @@ minstrel_ht_set_best_prob_rate(struct mi +- int max_gpr_group, max_gpr_idx; +- int max_gpr_tp_avg, max_gpr_prob; +- +-- cur_group = index / MCS_GROUP_RATES; +-- cur_idx = index % MCS_GROUP_RATES; +-- mg = &mi->groups[index / MCS_GROUP_RATES]; +-- mrs = &mg->rates[index % MCS_GROUP_RATES]; +-+ cur_group = MI_RATE_GROUP(index); +-+ cur_idx = MI_RATE_IDX(index); +-+ mg = &mi->groups[cur_group]; +-+ mrs = &mg->rates[cur_idx]; +- +-- tmp_group = *dest / MCS_GROUP_RATES; +-- tmp_idx = *dest % MCS_GROUP_RATES; +-+ tmp_group = MI_RATE_GROUP(*dest); +-+ tmp_idx = MI_RATE_IDX(*dest); +- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; +- tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); +- +- /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from +- * MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */ +-- max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES; +-- max_tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES; +-+ max_tp_group = MI_RATE_GROUP(mi->max_tp_rate[0]); +-+ max_tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]); +- max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg; +- +-- if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) && +-+ if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(index)) && +- !minstrel_ht_is_legacy_group(max_tp_group)) +- return; +- +-@@ -529,8 +529,8 @@ minstrel_ht_set_best_prob_rate(struct mi +- mrs->prob_avg < max_tp_prob) +- return; +- +-- max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES; +-- max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; +-+ max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate); +-+ max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate); +- max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; +- +- if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) { +-@@ -567,13 +567,13 @@ minstrel_ht_assign_best_tp_rates(struct +- unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp, tmp_prob; +- int i; +- +-- tmp_group = tmp_legacy_tp_rate[0] / MCS_GROUP_RATES; +-- tmp_idx = tmp_legacy_tp_rate[0] % MCS_GROUP_RATES; +-+ tmp_group = MI_RATE_GROUP(tmp_legacy_tp_rate[0]); +-+ tmp_idx = MI_RATE_IDX(tmp_legacy_tp_rate[0]); +- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; +- tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); +- +-- tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES; +-- tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES; +-+ tmp_group = MI_RATE_GROUP(tmp_mcs_tp_rate[0]); +-+ tmp_idx = MI_RATE_IDX(tmp_mcs_tp_rate[0]); +- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; +- tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); +- +-@@ -600,14 +600,14 @@ minstrel_ht_prob_rate_reduce_streams(str +- if (!mi->sta->ht_cap.ht_supported) +- return; +- +-- tmp_max_streams = minstrel_mcs_groups[mi->max_tp_rate[0] / +-- MCS_GROUP_RATES].streams; +-+ group = MI_RATE_GROUP(mi->max_tp_rate[0]); +-+ tmp_max_streams = minstrel_mcs_groups[group].streams; +- for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { +- mg = &mi->groups[group]; +- if (!mi->supported[group] || group == MINSTREL_CCK_GROUP) +- continue; +- +-- tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; +-+ tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate); +- tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg; +- +- if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) && +-@@ -644,8 +644,8 @@ minstrel_ht_find_probe_rates(struct mins +- int i, g, max_dur; +- int tp_idx; +- +-- tp_group = &minstrel_mcs_groups[mi->max_tp_rate[0] / MCS_GROUP_RATES]; +-- tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES; +-+ tp_group = &minstrel_mcs_groups[MI_RATE_GROUP(mi->max_tp_rate[0])]; +-+ tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]); +- +- max_dur = minstrel_get_duration(mi->max_tp_rate[0]); +- if (faster_rate) +-@@ -670,7 +670,7 @@ minstrel_ht_find_probe_rates(struct mins +- if ((group->duration[i] << group->shift) > max_dur) +- continue; +- +-- idx = g * MCS_GROUP_RATES + i; +-+ idx = MI_RATE(g, i); +- if (idx == mi->max_tp_rate[0]) +- continue; +- +-@@ -712,10 +712,10 @@ minstrel_ht_rate_sample_switch(struct mi +- +- /* If no suitable rate was found, try to pick the next one in the group */ +- if (!n_rates) { +-- int g_idx = mi->max_tp_rate[0] / MCS_GROUP_RATES; +-+ int g_idx = MI_RATE_GROUP(mi->max_tp_rate[0]); +- u16 supported = mi->supported[g_idx]; +- +-- supported >>= mi->max_tp_rate[0] % MCS_GROUP_RATES; +-+ supported >>= MI_RATE_IDX(mi->max_tp_rate[0]); +- for (i = 0; supported; supported >>= 1, i++) { +- if (!(supported & 1)) +- continue; +-@@ -854,24 +854,27 @@ minstrel_ht_update_stats(struct minstrel +- mi->sample_slow = 0; +- mi->sample_count = 0; +- +-- memset(tmp_mcs_tp_rate, 0, sizeof(tmp_mcs_tp_rate)); +-- memset(tmp_legacy_tp_rate, 0, sizeof(tmp_legacy_tp_rate)); +- if (mi->supported[MINSTREL_CCK_GROUP]) +-- for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++) +-- tmp_legacy_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; +-+ group = MINSTREL_CCK_GROUP; +- else if (mi->supported[MINSTREL_OFDM_GROUP]) +-- for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++) +-- tmp_legacy_tp_rate[j] = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES; +-+ group = MINSTREL_OFDM_GROUP; +-+ else +-+ group = 0; +-+ +-+ index = MI_RATE(group, 0); +-+ for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++) +-+ tmp_legacy_tp_rate[j] = index; +- +- if (mi->supported[MINSTREL_VHT_GROUP_0]) +-- index = MINSTREL_VHT_GROUP_0 * MCS_GROUP_RATES; +-+ group = MINSTREL_VHT_GROUP_0; +- else if (ht_supported) +-- index = MINSTREL_HT_GROUP_0 * MCS_GROUP_RATES; +-+ group = MINSTREL_HT_GROUP_0; +- else if (mi->supported[MINSTREL_CCK_GROUP]) +-- index = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; +-+ group = MINSTREL_CCK_GROUP; +- else +-- index = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES; +-+ group = MINSTREL_OFDM_GROUP; +- +-+ index = MI_RATE(group, 0); +- tmp_max_prob_rate = index; +- for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++) +- tmp_mcs_tp_rate[j] = index; +-@@ -888,7 +891,7 @@ minstrel_ht_update_stats(struct minstrel +- +- /* (re)Initialize group rate indexes */ +- for(j = 0; j < MAX_THR_RATES; j++) +-- tmp_group_tp_rate[j] = MCS_GROUP_RATES * group; +-+ tmp_group_tp_rate[j] = MI_RATE(group, 0); +- +- if (group == MINSTREL_CCK_GROUP && ht_supported) +- tp_rate = tmp_legacy_tp_rate; +-@@ -897,7 +900,7 @@ minstrel_ht_update_stats(struct minstrel +- if (!(mi->supported[group] & BIT(i))) +- continue; +- +-- index = MCS_GROUP_RATES * group + i; +-+ index = MI_RATE(group, i); +- +- mrs = &mg->rates[i]; +- mrs->retry_updated = false; +-@@ -929,13 +932,13 @@ minstrel_ht_update_stats(struct minstrel +- continue; +- +- mg = &mi->groups[group]; +-- mg->max_group_prob_rate = MCS_GROUP_RATES * group; +-+ mg->max_group_prob_rate = MI_RATE(group, 0); +- +- for (i = 0; i < MCS_GROUP_RATES; i++) { +- if (!(mi->supported[group] & BIT(i))) +- continue; +- +-- index = MCS_GROUP_RATES * group + i; +-+ index = MI_RATE(group, i); +- +- /* Find max probability rate per group and global */ +- minstrel_ht_set_best_prob_rate(mi, &tmp_max_prob_rate, +-@@ -1022,7 +1025,7 @@ minstrel_downgrade_rate(struct minstrel_ +- { +- int group, orig_group; +- +-- orig_group = group = *idx / MCS_GROUP_RATES; +-+ orig_group = group = MI_RATE_GROUP(*idx); +- while (group > 0) { +- group--; +- +-@@ -1206,7 +1209,7 @@ minstrel_calc_retransmit(struct minstrel +- ctime += (t_slot * cw) >> 1; +- cw = min((cw << 1) | 1, mp->cw_max); +- +-- if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES)) { +-+ if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(index))) { +- overhead = mi->overhead_legacy; +- overhead_rtscts = mi->overhead_legacy_rtscts; +- } else { +-@@ -1239,7 +1242,7 @@ static void +- minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, +- struct ieee80211_sta_rates *ratetbl, int offset, int index) +- { +-- int group_idx = index / MCS_GROUP_RATES; +-+ int group_idx = MI_RATE_GROUP(index); +- const struct mcs_group *group = &minstrel_mcs_groups[group_idx]; +- struct minstrel_rate_stats *mrs; +- u8 idx; +-@@ -1259,7 +1262,7 @@ minstrel_ht_set_rate(struct minstrel_pri +- ratetbl->rate[offset].count_rts = mrs->retry_count_rtscts; +- } +- +-- index %= MCS_GROUP_RATES; +-+ index = MI_RATE_IDX(index); +- if (group_idx == MINSTREL_CCK_GROUP) +- idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; +- else if (group_idx == MINSTREL_OFDM_GROUP) +-@@ -1289,17 +1292,17 @@ minstrel_ht_set_rate(struct minstrel_pri +- static inline int +- minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate) +- { +-- int group = rate / MCS_GROUP_RATES; +-- rate %= MCS_GROUP_RATES; +-+ int group = MI_RATE_GROUP(rate); +-+ rate = MI_RATE_IDX(rate); +- return mi->groups[group].rates[rate].prob_avg; +- } +- +- static int +- minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi) +- { +-- int group = mi->max_prob_rate / MCS_GROUP_RATES; +-+ int group = MI_RATE_GROUP(mi->max_prob_rate); +- const struct mcs_group *g = &minstrel_mcs_groups[group]; +-- int rate = mi->max_prob_rate % MCS_GROUP_RATES; +-+ int rate = MI_RATE_IDX(mi->max_prob_rate); +- unsigned int duration; +- +- /* Disable A-MSDU if max_prob_rate is bad */ +-@@ -1405,7 +1408,7 @@ minstrel_get_sample_rate(struct minstrel +- return -1; +- +- mrs = &mg->rates[sample_idx]; +-- sample_idx += sample_group * MCS_GROUP_RATES; +-+ sample_idx += MI_RATE(sample_group, 0); +- +- tp_rate1 = mi->max_tp_rate[0]; +- +-@@ -1455,8 +1458,7 @@ minstrel_get_sample_rate(struct minstrel +- * if the link is working perfectly. +- */ +- +-- cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 / +-- MCS_GROUP_RATES].streams; +-+ cur_max_tp_streams = minstrel_mcs_groups[MI_RATE_GROUP(tp_rate1)].streams; +- if (sample_dur >= minstrel_get_duration(tp_rate2) && +- (cur_max_tp_streams - 1 < +- minstrel_mcs_groups[sample_group].streams || +-@@ -1484,7 +1486,7 @@ minstrel_ht_get_rate(void *priv, struct +- int sample_idx; +- +- if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && +-- !minstrel_ht_is_legacy_group(mi->max_prob_rate / MCS_GROUP_RATES)) +-+ !minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_prob_rate))) +- minstrel_aggr_check(sta, txrc->skb); +- +- info->flags |= mi->tx_flags; +-@@ -1512,8 +1514,8 @@ minstrel_ht_get_rate(void *priv, struct +- if (sample_idx < 0) +- return; +- +-- sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES]; +-- sample_idx %= MCS_GROUP_RATES; +-+ sample_group = &minstrel_mcs_groups[MI_RATE_GROUP(sample_idx)]; +-+ sample_idx = MI_RATE_IDX(sample_idx); +- +- if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP] && +- (sample_idx >= 4) != txrc->short_preamble) +-@@ -1529,7 +1531,7 @@ minstrel_ht_get_rate(void *priv, struct +- int idx = sample_idx % ARRAY_SIZE(mp->ofdm_rates[0]); +- rate->idx = mp->ofdm_rates[mi->band][idx]; +- } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { +-- ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, +-+ ieee80211_rate_set_vht(rate, MI_RATE_IDX(sample_idx), +- sample_group->streams); +- } else { +- rate->idx = sample_idx + (sample_group->streams - 1) * 8; +-@@ -1898,8 +1900,8 @@ static u32 minstrel_ht_get_expected_thro +- struct minstrel_ht_sta *mi = priv_sta; +- int i, j, prob, tp_avg; +- +-- i = mi->max_tp_rate[0] / MCS_GROUP_RATES; +-- j = mi->max_tp_rate[0] % MCS_GROUP_RATES; +-+ i = MI_RATE_GROUP(mi->max_tp_rate[0]); +-+ j = MI_RATE_IDX(mi->max_tp_rate[0]); +- prob = mi->groups[i].rates[j].prob_avg; +- +- /* convert tp_avg from pkt per second in kbps */ +---- a/net/mac80211/rc80211_minstrel_ht.h +-+++ b/net/mac80211/rc80211_minstrel_ht.h +-@@ -6,6 +6,8 @@ +- #ifndef __RC_MINSTREL_HT_H +- #define __RC_MINSTREL_HT_H +- +-+#include +-+ +- /* number of highest throughput rates to consider*/ +- #define MAX_THR_RATES 4 +- #define SAMPLE_COLUMNS 10 /* number of columns in sample table */ +-@@ -57,6 +59,17 @@ +- +- #define MCS_GROUP_RATES 10 +- +-+#define MI_RATE_IDX_MASK GENMASK(3, 0) +-+#define MI_RATE_GROUP_MASK GENMASK(15, 4) +-+ +-+#define MI_RATE(_group, _idx) \ +-+ (FIELD_PREP(MI_RATE_GROUP_MASK, _group) | \ +-+ FIELD_PREP(MI_RATE_IDX_MASK, _idx)) +-+ +-+#define MI_RATE_IDX(_rate) FIELD_GET(MI_RATE_IDX_MASK, _rate) +-+#define MI_RATE_GROUP(_rate) FIELD_GET(MI_RATE_GROUP_MASK, _rate) +-+ +-+ +- struct minstrel_priv { +- struct ieee80211_hw *hw; +- bool has_mrr; +---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +-+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +-@@ -56,7 +56,7 @@ minstrel_ht_stats_dump(struct minstrel_h +- +- for (j = 0; j < MCS_GROUP_RATES; j++) { +- struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; +-- int idx = i * MCS_GROUP_RATES + j; +-+ int idx = MI_RATE(i, j); +- unsigned int duration; +- +- if (!(mi->supported[i] & BIT(j))) +-@@ -201,7 +201,7 @@ minstrel_ht_stats_csv_dump(struct minstr +- +- for (j = 0; j < MCS_GROUP_RATES; j++) { +- struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; +-- int idx = i * MCS_GROUP_RATES + j; +-+ int idx = MI_RATE(i, j); +- unsigned int duration; +- +- if (!(mi->supported[i] & BIT(j))) +diff --git a/package/kernel/mac80211/patches/subsys/347-mac80211-minstrel_ht-update-total-packets-counter-in.patch b/package/kernel/mac80211/patches/subsys/347-mac80211-minstrel_ht-update-total-packets-counter-in.patch +deleted file mode 100644 +index dce8104934..0000000000 +--- a/package/kernel/mac80211/patches/subsys/347-mac80211-minstrel_ht-update-total-packets-counter-in.patch ++++ /dev/null +@@ -1,54 +0,0 @@ +-From: Felix Fietkau +-Date: Fri, 22 Jan 2021 18:21:13 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: update total packets counter in tx +- status path +- +-Keep the update in one place and prepare for further rework +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -1092,6 +1092,16 @@ minstrel_ht_tx_status(void *priv, struct +- info->status.ampdu_len = 1; +- } +- +-+ /* wraparound */ +-+ if (mi->total_packets >= ~0 - info->status.ampdu_len) { +-+ mi->total_packets = 0; +-+ mi->sample_packets = 0; +-+ } +-+ +-+ mi->total_packets += info->status.ampdu_len; +-+ if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) +-+ mi->sample_packets += info->status.ampdu_len; +-+ +- mi->ampdu_packets++; +- mi->ampdu_len += info->status.ampdu_len; +- +-@@ -1103,9 +1113,6 @@ minstrel_ht_tx_status(void *priv, struct +- mi->sample_count--; +- } +- +-- if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) +-- mi->sample_packets += info->status.ampdu_len; +-- +- if (mi->sample_mode != MINSTREL_SAMPLE_IDLE) +- rate_sample = minstrel_get_ratestats(mi, mi->sample_rate); +- +-@@ -1503,14 +1510,6 @@ minstrel_ht_get_rate(void *priv, struct +- else +- sample_idx = minstrel_get_sample_rate(mp, mi); +- +-- mi->total_packets++; +-- +-- /* wraparound */ +-- if (mi->total_packets == ~0) { +-- mi->total_packets = 0; +-- mi->sample_packets = 0; +-- } +-- +- if (sample_idx < 0) +- return; +- +diff --git a/package/kernel/mac80211/patches/subsys/348-mac80211-minstrel_ht-reduce-the-need-to-sample-slowe.patch b/package/kernel/mac80211/patches/subsys/348-mac80211-minstrel_ht-reduce-the-need-to-sample-slowe.patch +deleted file mode 100644 +index dc6f11e4b9..0000000000 +--- a/package/kernel/mac80211/patches/subsys/348-mac80211-minstrel_ht-reduce-the-need-to-sample-slowe.patch ++++ /dev/null +@@ -1,102 +0,0 @@ +-From: Felix Fietkau +-Date: Fri, 22 Jan 2021 19:24:59 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: reduce the need to sample slower +- rates +- +-In order to more gracefully be able to fall back to lower rates without too +-much throughput fluctuations, initialize all untested rates below tested ones +-to the maximum probabilty of higher rates. +-Usually this leads to untested lower rates getting initialized with a +-probability value of 100%, making them better candidates for fallback without +-having to rely on random probing +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -791,14 +791,11 @@ minstrel_ht_calc_rate_stats(struct minst +- unsigned int cur_prob; +- +- if (unlikely(mrs->attempts > 0)) { +-- mrs->sample_skipped = 0; +- cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); +- minstrel_filter_avg_add(&mrs->prob_avg, +- &mrs->prob_avg_1, cur_prob); +- mrs->att_hist += mrs->attempts; +- mrs->succ_hist += mrs->success; +-- } else { +-- mrs->sample_skipped++; +- } +- +- mrs->last_success = mrs->success; +-@@ -851,7 +848,6 @@ minstrel_ht_update_stats(struct minstrel +- mi->ampdu_packets = 0; +- } +- +-- mi->sample_slow = 0; +- mi->sample_count = 0; +- +- if (mi->supported[MINSTREL_CCK_GROUP]) +-@@ -882,6 +878,7 @@ minstrel_ht_update_stats(struct minstrel +- /* Find best rate sets within all MCS groups*/ +- for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { +- u16 *tp_rate = tmp_mcs_tp_rate; +-+ u16 last_prob = 0; +- +- mg = &mi->groups[group]; +- if (!mi->supported[group]) +-@@ -896,7 +893,7 @@ minstrel_ht_update_stats(struct minstrel +- if (group == MINSTREL_CCK_GROUP && ht_supported) +- tp_rate = tmp_legacy_tp_rate; +- +-- for (i = 0; i < MCS_GROUP_RATES; i++) { +-+ for (i = MCS_GROUP_RATES - 1; i >= 0; i--) { +- if (!(mi->supported[group] & BIT(i))) +- continue; +- +-@@ -905,6 +902,11 @@ minstrel_ht_update_stats(struct minstrel +- mrs = &mg->rates[i]; +- mrs->retry_updated = false; +- minstrel_ht_calc_rate_stats(mp, mrs); +-+ +-+ if (mrs->att_hist) +-+ last_prob = max(last_prob, mrs->prob_avg); +-+ else +-+ mrs->prob_avg = max(last_prob, mrs->prob_avg); +- cur_prob = mrs->prob_avg; +- +- if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0) +-@@ -1469,13 +1471,9 @@ minstrel_get_sample_rate(struct minstrel +- if (sample_dur >= minstrel_get_duration(tp_rate2) && +- (cur_max_tp_streams - 1 < +- minstrel_mcs_groups[sample_group].streams || +-- sample_dur >= minstrel_get_duration(mi->max_prob_rate))) { +-- if (mrs->sample_skipped < 20) +-+ sample_dur >= minstrel_get_duration(mi->max_prob_rate))) +- return -1; +- +-- if (mi->sample_slow++ > 2) +-- return -1; +-- } +- mi->sample_tries--; +- +- return sample_idx; +---- a/net/mac80211/rc80211_minstrel_ht.h +-+++ b/net/mac80211/rc80211_minstrel_ht.h +-@@ -123,7 +123,6 @@ struct minstrel_rate_stats { +- u8 retry_count; +- u8 retry_count_rtscts; +- +-- u8 sample_skipped; +- bool retry_updated; +- }; +- +-@@ -179,7 +178,6 @@ struct minstrel_ht_sta { +- u8 sample_wait; +- u8 sample_tries; +- u8 sample_count; +-- u8 sample_slow; +- +- enum minstrel_sample_mode sample_mode; +- u16 sample_rate; +diff --git a/package/kernel/mac80211/patches/subsys/349-mac80211-minstrel_ht-significantly-redesign-the-rate.patch b/package/kernel/mac80211/patches/subsys/349-mac80211-minstrel_ht-significantly-redesign-the-rate.patch +deleted file mode 100644 +index 09f6fd2214..0000000000 +--- a/package/kernel/mac80211/patches/subsys/349-mac80211-minstrel_ht-significantly-redesign-the-rate.patch ++++ /dev/null +@@ -1,767 +0,0 @@ +-From: Felix Fietkau +-Date: Fri, 22 Jan 2021 23:57:50 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: significantly redesign the rate +- probing strategy +- +-The biggest flaw in current minstrel_ht is the fact that it needs way too +-many probing packets to be able to quickly find the best rate. +-Depending on the wifi hardware and operating mode, this can significantly +-reduce throughput when not operating at the highest available data rate. +- +-In order to be able to significantly reduce the amount of rate sampling, +-we need a much smarter selection of probing rates. +- +-The new approach introduced by this patch maintains a limited set of +-available rates to be tested during a statistics window. +- +-They are split into distinct categories: +-- MINSTREL_SAMPLE_TYPE_INC - incremental rate upgrade: +- Pick the next rate group and find the first rate that is faster than +- the current max. throughput rate +-- MINSTREL_SAMPLE_TYPE_JUMP - random testing of higher rates: +- Pick a random rate from the next group that is faster than the current +- max throughput rate. This allows faster adaptation when the link changes +- significantly +-- MINSTREL_SAMPLE_TYPE_SLOW - test a rate between max_prob, max_tp2 and +- max_tp in order to reduce the gap between them +- +-In order to prioritize sampling, every 6 attempts are split into 3x INC, +-2x JUMP, 1x SLOW. +- +-Available rates are checked and refilled on every stats window update. +- +-With this approach, we finally get a very small delta in throughput when +-comparing setting the optimal data rate as a fixed rate vs normal rate +-control operation. +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -266,6 +266,14 @@ const struct mcs_group minstrel_mcs_grou +- const s16 minstrel_cck_bitrates[4] = { 10, 20, 55, 110 }; +- const s16 minstrel_ofdm_bitrates[8] = { 60, 90, 120, 180, 240, 360, 480, 540 }; +- static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; +-+static const u8 minstrel_sample_seq[] = { +-+ MINSTREL_SAMPLE_TYPE_INC, +-+ MINSTREL_SAMPLE_TYPE_JUMP, +-+ MINSTREL_SAMPLE_TYPE_INC, +-+ MINSTREL_SAMPLE_TYPE_JUMP, +-+ MINSTREL_SAMPLE_TYPE_INC, +-+ MINSTREL_SAMPLE_TYPE_SLOW, +-+}; +- +- static void +- minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi); +-@@ -620,77 +628,31 @@ minstrel_ht_prob_rate_reduce_streams(str +- } +- } +- +--static bool +--minstrel_ht_probe_group(struct minstrel_ht_sta *mi, const struct mcs_group *tp_group, +-- int tp_idx, const struct mcs_group *group) +--{ +-- if (group->bw < tp_group->bw) +-- return false; +-- +-- if (group->streams == tp_group->streams) +-- return true; +-- +-- if (tp_idx < 4 && group->streams == tp_group->streams - 1) +-- return true; +-- +-- return group->streams == tp_group->streams + 1; +--} +-- +--static void +--minstrel_ht_find_probe_rates(struct minstrel_ht_sta *mi, u16 *rates, int *n_rates, +-- bool faster_rate) +-+static u16 +-+__minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi, +-+ enum minstrel_sample_type type) +- { +-- const struct mcs_group *group, *tp_group; +-- int i, g, max_dur; +-- int tp_idx; +-- +-- tp_group = &minstrel_mcs_groups[MI_RATE_GROUP(mi->max_tp_rate[0])]; +-- tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]); +-- +-- max_dur = minstrel_get_duration(mi->max_tp_rate[0]); +-- if (faster_rate) +-- max_dur -= max_dur / 16; +-- +-- for (g = 0; g < MINSTREL_GROUPS_NB; g++) { +-- u16 supported = mi->supported[g]; +-- +-- if (!supported) +-- continue; +-+ u16 *rates = mi->sample[type].sample_rates; +-+ u16 cur; +-+ int i; +- +-- group = &minstrel_mcs_groups[g]; +-- if (!minstrel_ht_probe_group(mi, tp_group, tp_idx, group)) +-+ for (i = 0; i < MINSTREL_SAMPLE_RATES; i++) { +-+ if (!rates[i]) +- continue; +- +-- for (i = 0; supported; supported >>= 1, i++) { +-- int idx; +-- +-- if (!(supported & 1)) +-- continue; +-- +-- if ((group->duration[i] << group->shift) > max_dur) +-- continue; +-- +-- idx = MI_RATE(g, i); +-- if (idx == mi->max_tp_rate[0]) +-- continue; +-- +-- rates[(*n_rates)++] = idx; +-- break; +-- } +-+ cur = rates[i]; +-+ rates[i] = 0; +-+ return cur; +- } +-+ +-+ return 0; +- } +- +- static void +- minstrel_ht_rate_sample_switch(struct minstrel_priv *mp, +- struct minstrel_ht_sta *mi) +- { +-- struct minstrel_rate_stats *mrs; +-- u16 rates[MINSTREL_GROUPS_NB]; +-- int n_rates = 0; +-- int probe_rate = 0; +-- bool faster_rate; +-- int i; +-- u8 random; +-+ u16 rate; +- +- /* +- * Use rate switching instead of probing packets for devices with +-@@ -699,43 +661,11 @@ minstrel_ht_rate_sample_switch(struct mi +- if (mp->hw->max_rates > 1) +- return; +- +-- /* +-- * If the current EWMA prob is >75%, look for a rate that's 6.25% +-- * faster than the max tp rate. +-- * If that fails, look again for a rate that is at least as fast +-- */ +-- mrs = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); +-- faster_rate = mrs->prob_avg > MINSTREL_FRAC(75, 100); +-- minstrel_ht_find_probe_rates(mi, rates, &n_rates, faster_rate); +-- if (!n_rates && faster_rate) +-- minstrel_ht_find_probe_rates(mi, rates, &n_rates, false); +-- +-- /* If no suitable rate was found, try to pick the next one in the group */ +-- if (!n_rates) { +-- int g_idx = MI_RATE_GROUP(mi->max_tp_rate[0]); +-- u16 supported = mi->supported[g_idx]; +-- +-- supported >>= MI_RATE_IDX(mi->max_tp_rate[0]); +-- for (i = 0; supported; supported >>= 1, i++) { +-- if (!(supported & 1)) +-- continue; +-- +-- probe_rate = mi->max_tp_rate[0] + i; +-- goto out; +-- } +-- +-+ rate = __minstrel_ht_get_sample_rate(mi, MINSTREL_SAMPLE_TYPE_INC); +-+ if (!rate) +- return; +-- } +-- +-- i = 0; +-- if (n_rates > 1) { +-- random = prandom_u32(); +-- i = random % n_rates; +-- } +-- probe_rate = rates[i]; +- +--out: +-- mi->sample_rate = probe_rate; +-+ mi->sample_rate = rate; +- mi->sample_mode = MINSTREL_SAMPLE_ACTIVE; +- } +- +-@@ -804,6 +734,274 @@ minstrel_ht_calc_rate_stats(struct minst +- mrs->attempts = 0; +- } +- +-+static bool +-+minstrel_ht_find_sample_rate(struct minstrel_ht_sta *mi, int type, int idx) +-+{ +-+ int i; +-+ +-+ for (i = 0; i < MINSTREL_SAMPLE_RATES; i++) { +-+ u16 cur = mi->sample[type].sample_rates[i]; +-+ +-+ if (cur == idx) +-+ return true; +-+ +-+ if (!cur) +-+ break; +-+ } +-+ +-+ return false; +-+} +-+ +-+static int +-+minstrel_ht_move_sample_rates(struct minstrel_ht_sta *mi, int type, +-+ u32 fast_rate_dur, u32 slow_rate_dur) +-+{ +-+ u16 *rates = mi->sample[type].sample_rates; +-+ int i, j; +-+ +-+ for (i = 0, j = 0; i < MINSTREL_SAMPLE_RATES; i++) { +-+ u32 duration; +-+ bool valid = false; +-+ u16 cur; +-+ +-+ cur = rates[i]; +-+ if (!cur) +-+ continue; +-+ +-+ duration = minstrel_get_duration(cur); +-+ switch (type) { +-+ case MINSTREL_SAMPLE_TYPE_SLOW: +-+ valid = duration > fast_rate_dur && +-+ duration < slow_rate_dur; +-+ break; +-+ case MINSTREL_SAMPLE_TYPE_INC: +-+ case MINSTREL_SAMPLE_TYPE_JUMP: +-+ valid = duration < fast_rate_dur; +-+ break; +-+ default: +-+ valid = false; +-+ break; +-+ } +-+ +-+ if (!valid) { +-+ rates[i] = 0; +-+ continue; +-+ } +-+ +-+ if (i == j) +-+ continue; +-+ +-+ rates[j++] = cur; +-+ rates[i] = 0; +-+ } +-+ +-+ return j; +-+} +-+ +-+static int +-+minstrel_ht_group_min_rate_offset(struct minstrel_ht_sta *mi, int group, +-+ u32 max_duration) +-+{ +-+ u16 supported = mi->supported[group]; +-+ int i; +-+ +-+ for (i = 0; i < MCS_GROUP_RATES && supported; i++, supported >>= 1) { +-+ if (!(supported & BIT(0))) +-+ continue; +-+ +-+ if (minstrel_get_duration(MI_RATE(group, i)) >= max_duration) +-+ continue; +-+ +-+ return i; +-+ } +-+ +-+ return -1; +-+} +-+ +-+/* +-+ * Incremental update rates: +-+ * Flip through groups and pick the first group rate that is faster than the +-+ * highest currently selected rate +-+ */ +-+static u16 +-+minstrel_ht_next_inc_rate(struct minstrel_ht_sta *mi, u32 fast_rate_dur) +-+{ +-+ struct minstrel_mcs_group_data *mg; +-+ u8 type = MINSTREL_SAMPLE_TYPE_INC; +-+ int i, index = 0; +-+ u8 group; +-+ +-+ group = mi->sample[type].sample_group; +-+ for (i = 0; i < ARRAY_SIZE(minstrel_mcs_groups); i++) { +-+ group = (group + 1) % ARRAY_SIZE(minstrel_mcs_groups); +-+ mg = &mi->groups[group]; +-+ +-+ index = minstrel_ht_group_min_rate_offset(mi, group, +-+ fast_rate_dur); +-+ if (index < 0) +-+ continue; +-+ +-+ index = MI_RATE(group, index & 0xf); +-+ if (!minstrel_ht_find_sample_rate(mi, type, index)) +-+ goto out; +-+ } +-+ index = 0; +-+ +-+out: +-+ mi->sample[type].sample_group = group; +-+ +-+ return index; +-+} +-+ +-+static int +-+minstrel_ht_next_group_sample_rate(struct minstrel_ht_sta *mi, int group, +-+ u16 supported, int offset) +-+{ +-+ struct minstrel_mcs_group_data *mg = &mi->groups[group]; +-+ u16 idx; +-+ int i; +-+ +-+ for (i = 0; i < MCS_GROUP_RATES; i++) { +-+ idx = sample_table[mg->column][mg->index]; +-+ if (++mg->index >= MCS_GROUP_RATES) { +-+ mg->index = 0; +-+ if (++mg->column >= ARRAY_SIZE(sample_table)) +-+ mg->column = 0; +-+ } +-+ +-+ if (idx < offset) +-+ continue; +-+ +-+ if (!(supported & BIT(idx))) +-+ continue; +-+ +-+ return MI_RATE(group, idx); +-+ } +-+ +-+ return -1; +-+} +-+ +-+/* +-+ * Jump rates: +-+ * Sample random rates, use those that are faster than the highest +-+ * currently selected rate. Rates between the fastest and the slowest +-+ * get sorted into the slow sample bucket, but only if it has room +-+ */ +-+static u16 +-+minstrel_ht_next_jump_rate(struct minstrel_ht_sta *mi, u32 fast_rate_dur, +-+ u32 slow_rate_dur, int *slow_rate_ofs) +-+{ +-+ struct minstrel_mcs_group_data *mg; +-+ struct minstrel_rate_stats *mrs; +-+ u32 max_duration = slow_rate_dur; +-+ int i, index, offset; +-+ u16 *slow_rates; +-+ u16 supported; +-+ u32 duration; +-+ u8 group; +-+ +-+ if (*slow_rate_ofs >= MINSTREL_SAMPLE_RATES) +-+ max_duration = fast_rate_dur; +-+ +-+ slow_rates = mi->sample[MINSTREL_SAMPLE_TYPE_SLOW].sample_rates; +-+ group = mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_group; +-+ for (i = 0; i < ARRAY_SIZE(minstrel_mcs_groups); i++) { +-+ u8 type; +-+ +-+ group = (group + 1) % ARRAY_SIZE(minstrel_mcs_groups); +-+ mg = &mi->groups[group]; +-+ +-+ supported = mi->supported[group]; +-+ if (!supported) +-+ continue; +-+ +-+ offset = minstrel_ht_group_min_rate_offset(mi, group, +-+ max_duration); +-+ if (offset < 0) +-+ continue; +-+ +-+ index = minstrel_ht_next_group_sample_rate(mi, group, supported, +-+ offset); +-+ if (index < 0) +-+ continue; +-+ +-+ duration = minstrel_get_duration(index); +-+ if (duration < fast_rate_dur) +-+ type = MINSTREL_SAMPLE_TYPE_JUMP; +-+ else +-+ type = MINSTREL_SAMPLE_TYPE_SLOW; +-+ +-+ if (minstrel_ht_find_sample_rate(mi, type, index)) +-+ continue; +-+ +-+ if (type == MINSTREL_SAMPLE_TYPE_JUMP) +-+ goto found; +-+ +-+ if (*slow_rate_ofs >= MINSTREL_SAMPLE_RATES) +-+ continue; +-+ +-+ if (duration >= slow_rate_dur) +-+ continue; +-+ +-+ /* skip slow rates with high success probability */ +-+ mrs = minstrel_get_ratestats(mi, index); +-+ if (mrs->prob_avg > MINSTREL_FRAC(95, 100)) +-+ continue; +-+ +-+ slow_rates[(*slow_rate_ofs)++] = index; +-+ if (*slow_rate_ofs >= MINSTREL_SAMPLE_RATES) +-+ max_duration = fast_rate_dur; +-+ } +-+ index = 0; +-+ +-+found: +-+ mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_group = group; +-+ +-+ return index; +-+} +-+ +-+static void +-+minstrel_ht_refill_sample_rates(struct minstrel_ht_sta *mi) +-+{ +-+ u32 prob_dur = minstrel_get_duration(mi->max_prob_rate); +-+ u32 tp_dur = minstrel_get_duration(mi->max_tp_rate[0]); +-+ u32 tp2_dur = minstrel_get_duration(mi->max_tp_rate[1]); +-+ u32 fast_rate_dur = min(min(tp_dur, tp2_dur), prob_dur); +-+ u32 slow_rate_dur = max(max(tp_dur, tp2_dur), prob_dur); +-+ u16 *rates; +-+ int i, j; +-+ +-+ rates = mi->sample[MINSTREL_SAMPLE_TYPE_INC].sample_rates; +-+ i = minstrel_ht_move_sample_rates(mi, MINSTREL_SAMPLE_TYPE_INC, +-+ fast_rate_dur, slow_rate_dur); +-+ while (i < MINSTREL_SAMPLE_RATES) { +-+ rates[i] = minstrel_ht_next_inc_rate(mi, tp_dur); +-+ if (!rates[i]) +-+ break; +-+ +-+ i++; +-+ } +-+ +-+ rates = mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_rates; +-+ i = minstrel_ht_move_sample_rates(mi, MINSTREL_SAMPLE_TYPE_JUMP, +-+ fast_rate_dur, slow_rate_dur); +-+ j = minstrel_ht_move_sample_rates(mi, MINSTREL_SAMPLE_TYPE_SLOW, +-+ fast_rate_dur, slow_rate_dur); +-+ while (i < MINSTREL_SAMPLE_RATES) { +-+ rates[i] = minstrel_ht_next_jump_rate(mi, fast_rate_dur, +-+ slow_rate_dur, &j); +-+ if (!rates[i]) +-+ break; +-+ +-+ i++; +-+ } +-+ +-+ for (i = 0; i < ARRAY_SIZE(mi->sample); i++) +-+ memcpy(mi->sample[i].cur_sample_rates, mi->sample[i].sample_rates, +-+ sizeof(mi->sample[i].cur_sample_rates)); +-+} +-+ +-+ +- /* +- * Update rate statistics and select new primary rates +- * +-@@ -848,8 +1046,6 @@ minstrel_ht_update_stats(struct minstrel +- mi->ampdu_packets = 0; +- } +- +-- mi->sample_count = 0; +-- +- if (mi->supported[MINSTREL_CCK_GROUP]) +- group = MINSTREL_CCK_GROUP; +- else if (mi->supported[MINSTREL_OFDM_GROUP]) +-@@ -884,8 +1080,6 @@ minstrel_ht_update_stats(struct minstrel +- if (!mi->supported[group]) +- continue; +- +-- mi->sample_count++; +-- +- /* (re)Initialize group rate indexes */ +- for(j = 0; j < MAX_THR_RATES; j++) +- tmp_group_tp_rate[j] = MI_RATE(group, 0); +-@@ -952,9 +1146,7 @@ minstrel_ht_update_stats(struct minstrel +- +- /* Try to increase robustness of max_prob_rate*/ +- minstrel_ht_prob_rate_reduce_streams(mi); +-- +-- /* try to sample half of all available rates during each interval */ +-- mi->sample_count *= 4; +-+ minstrel_ht_refill_sample_rates(mi); +- +- if (sample) +- minstrel_ht_rate_sample_switch(mp, mi); +-@@ -971,6 +1163,7 @@ minstrel_ht_update_stats(struct minstrel +- +- /* Reset update timer */ +- mi->last_stats_update = jiffies; +-+ mi->sample_time = jiffies; +- } +- +- static bool +-@@ -1001,28 +1194,6 @@ minstrel_ht_txstat_valid(struct minstrel +- } +- +- static void +--minstrel_set_next_sample_idx(struct minstrel_ht_sta *mi) +--{ +-- struct minstrel_mcs_group_data *mg; +-- +-- for (;;) { +-- mi->sample_group++; +-- mi->sample_group %= ARRAY_SIZE(minstrel_mcs_groups); +-- mg = &mi->groups[mi->sample_group]; +-- +-- if (!mi->supported[mi->sample_group]) +-- continue; +-- +-- if (++mg->index >= MCS_GROUP_RATES) { +-- mg->index = 0; +-- if (++mg->column >= ARRAY_SIZE(sample_table)) +-- mg->column = 0; +-- } +-- break; +-- } +--} +-- +--static void +- minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary) +- { +- int group, orig_group; +-@@ -1107,14 +1278,6 @@ minstrel_ht_tx_status(void *priv, struct +- mi->ampdu_packets++; +- mi->ampdu_len += info->status.ampdu_len; +- +-- if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { +-- int avg_ampdu_len = minstrel_ht_avg_ampdu_len(mi); +-- +-- mi->sample_wait = 16 + 2 * avg_ampdu_len; +-- mi->sample_tries = 1; +-- mi->sample_count--; +-- } +-- +- if (mi->sample_mode != MINSTREL_SAMPLE_IDLE) +- rate_sample = minstrel_get_ratestats(mi, mi->sample_rate); +- +-@@ -1386,97 +1549,20 @@ minstrel_ht_update_rates(struct minstrel +- rate_control_set_rates(mp->hw, mi->sta, rates); +- } +- +--static int +--minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) +-+static u16 +-+minstrel_ht_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) +- { +-- struct minstrel_rate_stats *mrs; +-- struct minstrel_mcs_group_data *mg; +-- unsigned int sample_dur, sample_group, cur_max_tp_streams; +-- int tp_rate1, tp_rate2; +-- int sample_idx = 0; +-- +-- if (mp->hw->max_rates == 1 && mp->sample_switch && +-- (mi->total_packets_cur >= SAMPLE_SWITCH_THR || +-- mp->sample_switch == 1)) +-- return -1; +-- +-- if (mi->sample_wait > 0) { +-- mi->sample_wait--; +-- return -1; +-- } +-- +-- if (!mi->sample_tries) +-- return -1; +-- +-- sample_group = mi->sample_group; +-- mg = &mi->groups[sample_group]; +-- sample_idx = sample_table[mg->column][mg->index]; +-- minstrel_set_next_sample_idx(mi); +-- +-- if (!(mi->supported[sample_group] & BIT(sample_idx))) +-- return -1; +-+ u8 seq; +- +-- mrs = &mg->rates[sample_idx]; +-- sample_idx += MI_RATE(sample_group, 0); +-- +-- tp_rate1 = mi->max_tp_rate[0]; +-- +-- /* Set tp_rate2 to the second highest max_tp_rate */ +-- if (minstrel_get_duration(mi->max_tp_rate[0]) > +-- minstrel_get_duration(mi->max_tp_rate[1])) { +-- tp_rate2 = mi->max_tp_rate[0]; +-+ if (mp->hw->max_rates > 1) { +-+ seq = mi->sample_seq; +-+ mi->sample_seq = (seq + 1) % ARRAY_SIZE(minstrel_sample_seq); +-+ seq = minstrel_sample_seq[seq]; +- } else { +-- tp_rate2 = mi->max_tp_rate[1]; +-+ seq = MINSTREL_SAMPLE_TYPE_INC; +- } +- +-- /* +-- * Sampling might add some overhead (RTS, no aggregation) +-- * to the frame. Hence, don't use sampling for the highest currently +-- * used highest throughput or probability rate. +-- */ +-- if (sample_idx == mi->max_tp_rate[0] || sample_idx == mi->max_prob_rate) +-- return -1; +-- +-- /* +-- * Do not sample if the probability is already higher than 95%, +-- * or if the rate is 3 times slower than the current max probability +-- * rate, to avoid wasting airtime. +-- */ +-- sample_dur = minstrel_get_duration(sample_idx); +-- if (mrs->prob_avg > MINSTREL_FRAC(95, 100) || +-- minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur) +-- return -1; +-- +-- +-- /* +-- * For devices with no configurable multi-rate retry, skip sampling +-- * below the per-group max throughput rate, and only use one sampling +-- * attempt per rate +-- */ +-- if (mp->hw->max_rates == 1 && +-- (minstrel_get_duration(mg->max_group_tp_rate[0]) < sample_dur || +-- mrs->attempts)) +-- return -1; +-- +-- /* Skip already sampled slow rates */ +-- if (sample_dur >= minstrel_get_duration(tp_rate1) && mrs->attempts) +-- return -1; +-- +-- /* +-- * Make sure that lower rates get sampled only occasionally, +-- * if the link is working perfectly. +-- */ +-- +-- cur_max_tp_streams = minstrel_mcs_groups[MI_RATE_GROUP(tp_rate1)].streams; +-- if (sample_dur >= minstrel_get_duration(tp_rate2) && +-- (cur_max_tp_streams - 1 < +-- minstrel_mcs_groups[sample_group].streams || +-- sample_dur >= minstrel_get_duration(mi->max_prob_rate))) +-- return -1; +-- +-- mi->sample_tries--; +-- +-- return sample_idx; +-+ return __minstrel_ht_get_sample_rate(mi, seq); +- } +- +- static void +-@@ -1488,7 +1574,7 @@ minstrel_ht_get_rate(void *priv, struct +- struct ieee80211_tx_rate *rate = &info->status.rates[0]; +- struct minstrel_ht_sta *mi = priv_sta; +- struct minstrel_priv *mp = priv; +-- int sample_idx; +-+ u16 sample_idx; +- +- if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && +- !minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_prob_rate))) +-@@ -1504,11 +1590,19 @@ minstrel_ht_get_rate(void *priv, struct +- /* Don't use EAPOL frames for sampling on non-mrr hw */ +- if (mp->hw->max_rates == 1 && +- (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) +-- sample_idx = -1; +-- else +-- sample_idx = minstrel_get_sample_rate(mp, mi); +-+ return; +-+ +-+ if (mp->hw->max_rates == 1 && mp->sample_switch && +-+ (mi->total_packets_cur >= SAMPLE_SWITCH_THR || +-+ mp->sample_switch == 1)) +-+ return; +-+ +-+ if (time_is_before_jiffies(mi->sample_time)) +-+ return; +- +-- if (sample_idx < 0) +-+ mi->sample_time = jiffies + MINSTREL_SAMPLE_INTERVAL; +-+ sample_idx = minstrel_ht_get_sample_rate(mp, mi); +-+ if (!sample_idx) +- return; +- +- sample_group = &minstrel_mcs_groups[MI_RATE_GROUP(sample_idx)]; +-@@ -1629,16 +1723,6 @@ minstrel_ht_update_caps(void *priv, stru +- +- mi->avg_ampdu_len = MINSTREL_FRAC(1, 1); +- +-- /* When using MRR, sample more on the first attempt, without delay */ +-- if (mp->has_mrr) { +-- mi->sample_count = 16; +-- mi->sample_wait = 0; +-- } else { +-- mi->sample_count = 8; +-- mi->sample_wait = 8; +-- } +-- mi->sample_tries = 4; +-- +- if (!use_vht) { +- stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >> +- IEEE80211_HT_CAP_RX_STBC_SHIFT; +---- a/net/mac80211/rc80211_minstrel_ht.h +-+++ b/net/mac80211/rc80211_minstrel_ht.h +-@@ -69,6 +69,8 @@ +- #define MI_RATE_IDX(_rate) FIELD_GET(MI_RATE_IDX_MASK, _rate) +- #define MI_RATE_GROUP(_rate) FIELD_GET(MI_RATE_GROUP_MASK, _rate) +- +-+#define MINSTREL_SAMPLE_RATES 5 /* rates per sample type */ +-+#define MINSTREL_SAMPLE_INTERVAL (HZ / 50) +- +- struct minstrel_priv { +- struct ieee80211_hw *hw; +-@@ -126,6 +128,13 @@ struct minstrel_rate_stats { +- bool retry_updated; +- }; +- +-+enum minstrel_sample_type { +-+ MINSTREL_SAMPLE_TYPE_INC, +-+ MINSTREL_SAMPLE_TYPE_JUMP, +-+ MINSTREL_SAMPLE_TYPE_SLOW, +-+ __MINSTREL_SAMPLE_TYPE_MAX +-+}; +-+ +- struct minstrel_mcs_group_data { +- u8 index; +- u8 column; +-@@ -144,6 +153,12 @@ enum minstrel_sample_mode { +- MINSTREL_SAMPLE_PENDING, +- }; +- +-+struct minstrel_sample_category { +-+ u8 sample_group; +-+ u16 sample_rates[MINSTREL_SAMPLE_RATES]; +-+ u16 cur_sample_rates[MINSTREL_SAMPLE_RATES]; +-+}; +-+ +- struct minstrel_ht_sta { +- struct ieee80211_sta *sta; +- +-@@ -175,16 +190,14 @@ struct minstrel_ht_sta { +- /* tx flags to add for frames for this sta */ +- u32 tx_flags; +- +-- u8 sample_wait; +-- u8 sample_tries; +-- u8 sample_count; +-+ unsigned long sample_time; +-+ struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX]; +-+ +-+ u8 sample_seq; +- +- enum minstrel_sample_mode sample_mode; +- u16 sample_rate; +- +-- /* current MCS group to be sampled */ +-- u8 sample_group; +-- +- u8 band; +- +- /* Bitfield of supported MCS rates of all groups */ +diff --git a/package/kernel/mac80211/patches/subsys/350-mac80211-minstrel_ht-show-sampling-rates-in-debugfs.patch b/package/kernel/mac80211/patches/subsys/350-mac80211-minstrel_ht-show-sampling-rates-in-debugfs.patch +deleted file mode 100644 +index 041ba31a37..0000000000 +--- a/package/kernel/mac80211/patches/subsys/350-mac80211-minstrel_ht-show-sampling-rates-in-debugfs.patch ++++ /dev/null +@@ -1,58 +0,0 @@ +-From: Felix Fietkau +-Date: Sat, 23 Jan 2021 00:10:34 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: show sampling rates in debugfs +- +-This makes it easier to see what rates are going to be tested next +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +-+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +-@@ -32,6 +32,18 @@ minstrel_stats_release(struct inode *ino +- return 0; +- } +- +-+static bool +-+minstrel_ht_is_sample_rate(struct minstrel_ht_sta *mi, int idx) +-+{ +-+ int type, i; +-+ +-+ for (type = 0; type < ARRAY_SIZE(mi->sample); type++) +-+ for (i = 0; i < MINSTREL_SAMPLE_RATES; i++) +-+ if (mi->sample[type].cur_sample_rates[i] == idx) +-+ return true; +-+ return false; +-+} +-+ +- static char * +- minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) +- { +-@@ -84,6 +96,7 @@ minstrel_ht_stats_dump(struct minstrel_h +- *(p++) = (idx == mi->max_tp_rate[2]) ? 'C' : ' '; +- *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' '; +- *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; +-+ *(p++) = minstrel_ht_is_sample_rate(mi, idx) ? 'S' : ' '; +- +- if (gflags & IEEE80211_TX_RC_MCS) { +- p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j); +-@@ -145,9 +158,9 @@ minstrel_ht_stats_open(struct inode *ino +- +- p += sprintf(p, "\n"); +- p += sprintf(p, +-- " best ____________rate__________ ____statistics___ _____last____ ______sum-of________\n"); +-+ " best ____________rate__________ ____statistics___ _____last____ ______sum-of________\n"); +- p += sprintf(p, +-- "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n"); +-+ "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n"); +- +- p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); +- for (i = 0; i < MINSTREL_CCK_GROUP; i++) +-@@ -228,6 +241,7 @@ minstrel_ht_stats_csv_dump(struct minstr +- p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[2]) ? "C" : "")); +- p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[3]) ? "D" : "")); +- p += sprintf(p, "%s" ,((idx == mi->max_prob_rate) ? "P" : "")); +-+ p += sprintf(p, "%s", (minstrel_ht_is_sample_rate(mi, idx) ? "S" : "")); +- +- if (gflags & IEEE80211_TX_RC_MCS) { +- p += sprintf(p, ",MCS%-2u,", (mg->streams - 1) * 8 + j); +diff --git a/package/kernel/mac80211/patches/subsys/351-mac80211-minstrel_ht-remove-sample-rate-switching-co.patch b/package/kernel/mac80211/patches/subsys/351-mac80211-minstrel_ht-remove-sample-rate-switching-co.patch +deleted file mode 100644 +index 8170ff85f8..0000000000 +--- a/package/kernel/mac80211/patches/subsys/351-mac80211-minstrel_ht-remove-sample-rate-switching-co.patch ++++ /dev/null +@@ -1,279 +0,0 @@ +-From: Felix Fietkau +-Date: Sat, 23 Jan 2021 07:18:26 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: remove sample rate switching code for +- constrained devices +- +-This was added to mitigate the effects of too much sampling on devices that +-use a static global fallback table instead of configurable multi-rate retry. +-Now that the sampling algorithm is improved, this code path no longer performs +-any better than the standard probing on affected devices. +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -648,27 +648,6 @@ __minstrel_ht_get_sample_rate(struct min +- return 0; +- } +- +--static void +--minstrel_ht_rate_sample_switch(struct minstrel_priv *mp, +-- struct minstrel_ht_sta *mi) +--{ +-- u16 rate; +-- +-- /* +-- * Use rate switching instead of probing packets for devices with +-- * little control over retry fallback behavior +-- */ +-- if (mp->hw->max_rates > 1) +-- return; +-- +-- rate = __minstrel_ht_get_sample_rate(mi, MINSTREL_SAMPLE_TYPE_INC); +-- if (!rate) +-- return; +-- +-- mi->sample_rate = rate; +-- mi->sample_mode = MINSTREL_SAMPLE_ACTIVE; +--} +-- +- static inline int +- minstrel_ewma(int old, int new, int weight) +- { +-@@ -1012,8 +991,7 @@ minstrel_ht_refill_sample_rates(struct m +- * higher throughput rates, even if the probablity is a bit lower +- */ +- static void +--minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, +-- bool sample) +-+minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) +- { +- struct minstrel_mcs_group_data *mg; +- struct minstrel_rate_stats *mrs; +-@@ -1023,18 +1001,6 @@ minstrel_ht_update_stats(struct minstrel +- u16 index; +- bool ht_supported = mi->sta->ht_cap.ht_supported; +- +-- mi->sample_mode = MINSTREL_SAMPLE_IDLE; +-- +-- if (sample) { +-- mi->total_packets_cur = mi->total_packets - +-- mi->total_packets_last; +-- mi->total_packets_last = mi->total_packets; +-- } +-- if (!mp->sample_switch) +-- sample = false; +-- if (mi->total_packets_cur < SAMPLE_SWITCH_THR && mp->sample_switch != 1) +-- sample = false; +-- +- if (mi->ampdu_packets > 0) { +- if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN)) +- mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, +-@@ -1148,16 +1114,12 @@ minstrel_ht_update_stats(struct minstrel +- minstrel_ht_prob_rate_reduce_streams(mi); +- minstrel_ht_refill_sample_rates(mi); +- +-- if (sample) +-- minstrel_ht_rate_sample_switch(mp, mi); +-- +- #ifdef CPTCFG_MAC80211_DEBUGFS +- /* use fixed index if set */ +- if (mp->fixed_rate_idx != -1) { +- for (i = 0; i < 4; i++) +- mi->max_tp_rate[i] = mp->fixed_rate_idx; +- mi->max_prob_rate = mp->fixed_rate_idx; +-- mi->sample_mode = MINSTREL_SAMPLE_IDLE; +- } +- #endif +- +-@@ -1247,11 +1209,10 @@ minstrel_ht_tx_status(void *priv, struct +- struct ieee80211_tx_info *info = st->info; +- struct minstrel_ht_sta *mi = priv_sta; +- struct ieee80211_tx_rate *ar = info->status.rates; +-- struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL; +-+ struct minstrel_rate_stats *rate, *rate2; +- struct minstrel_priv *mp = priv; +- u32 update_interval = mp->update_interval; +- bool last, update = false; +-- bool sample_status = false; +- int i; +- +- /* This packet was aggregated but doesn't carry status info */ +-@@ -1278,49 +1239,18 @@ minstrel_ht_tx_status(void *priv, struct +- mi->ampdu_packets++; +- mi->ampdu_len += info->status.ampdu_len; +- +-- if (mi->sample_mode != MINSTREL_SAMPLE_IDLE) +-- rate_sample = minstrel_get_ratestats(mi, mi->sample_rate); +-- +- last = !minstrel_ht_txstat_valid(mp, mi, &ar[0]); +- for (i = 0; !last; i++) { +- last = (i == IEEE80211_TX_MAX_RATES - 1) || +- !minstrel_ht_txstat_valid(mp, mi, &ar[i + 1]); +- +- rate = minstrel_ht_get_stats(mp, mi, &ar[i]); +-- if (rate == rate_sample) +-- sample_status = true; +-- +- if (last) +- rate->success += info->status.ampdu_ack_len; +- +- rate->attempts += ar[i].count * info->status.ampdu_len; +- } +- +-- switch (mi->sample_mode) { +-- case MINSTREL_SAMPLE_IDLE: +-- if (mp->hw->max_rates > 1 || +-- mi->total_packets_cur < SAMPLE_SWITCH_THR) +-- update_interval /= 2; +-- break; +-- +-- case MINSTREL_SAMPLE_ACTIVE: +-- if (!sample_status) +-- break; +-- +-- mi->sample_mode = MINSTREL_SAMPLE_PENDING; +-- update = true; +-- break; +-- +-- case MINSTREL_SAMPLE_PENDING: +-- if (sample_status) +-- break; +-- +-- update = true; +-- minstrel_ht_update_stats(mp, mi, false); +-- break; +-- } +-- +-- +- if (mp->hw->max_rates > 1) { +- /* +- * check for sudden death of spatial multiplexing, +-@@ -1343,7 +1273,7 @@ minstrel_ht_tx_status(void *priv, struct +- +- if (time_after(jiffies, mi->last_stats_update + update_interval)) { +- update = true; +-- minstrel_ht_update_stats(mp, mi, true); +-+ minstrel_ht_update_stats(mp, mi); +- } +- +- if (update) +-@@ -1522,18 +1452,14 @@ static void +- minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) +- { +- struct ieee80211_sta_rates *rates; +-- u16 first_rate = mi->max_tp_rate[0]; +- int i = 0; +- +-- if (mi->sample_mode == MINSTREL_SAMPLE_ACTIVE) +-- first_rate = mi->sample_rate; +-- +- rates = kzalloc(sizeof(*rates), GFP_ATOMIC); +- if (!rates) +- return; +- +- /* Start with max_tp_rate[0] */ +-- minstrel_ht_set_rate(mp, mi, rates, i++, first_rate); +-+ minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]); +- +- if (mp->hw->max_rates >= 3) { +- /* At least 3 tx rates supported, use max_tp_rate[1] next */ +-@@ -1592,11 +1518,6 @@ minstrel_ht_get_rate(void *priv, struct +- (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) +- return; +- +-- if (mp->hw->max_rates == 1 && mp->sample_switch && +-- (mi->total_packets_cur >= SAMPLE_SWITCH_THR || +-- mp->sample_switch == 1)) +-- return; +-- +- if (time_is_before_jiffies(mi->sample_time)) +- return; +- +-@@ -1810,7 +1731,7 @@ minstrel_ht_update_caps(void *priv, stru +- minstrel_ht_update_ofdm(mp, mi, sband, sta); +- +- /* create an initial rate table with the lowest supported rates */ +-- minstrel_ht_update_stats(mp, mi, true); +-+ minstrel_ht_update_stats(mp, mi); +- minstrel_ht_update_rates(mp, mi); +- } +- +-@@ -1926,8 +1847,6 @@ minstrel_ht_alloc(struct ieee80211_hw *h +- if (!mp) +- return NULL; +- +-- mp->sample_switch = -1; +-- +- /* contention window settings +- * Just an approximation. Using the per-queue values would complicate +- * the calculations and is probably unnecessary */ +-@@ -1947,7 +1866,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h +- mp->has_mrr = true; +- +- mp->hw = hw; +-- mp->update_interval = HZ / 10; +-+ mp->update_interval = HZ / 20; +- +- minstrel_ht_init_cck_rates(mp); +- for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++) +-@@ -1965,8 +1884,6 @@ static void minstrel_ht_add_debugfs(stru +- mp->fixed_rate_idx = (u32) -1; +- debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, +- &mp->fixed_rate_idx); +-- debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir, +-- &mp->sample_switch); +- } +- #endif +- +---- a/net/mac80211/rc80211_minstrel_ht.h +-+++ b/net/mac80211/rc80211_minstrel_ht.h +-@@ -75,7 +75,6 @@ +- struct minstrel_priv { +- struct ieee80211_hw *hw; +- bool has_mrr; +-- u32 sample_switch; +- unsigned int cw_min; +- unsigned int cw_max; +- unsigned int max_retry; +-@@ -147,12 +146,6 @@ struct minstrel_mcs_group_data { +- struct minstrel_rate_stats rates[MCS_GROUP_RATES]; +- }; +- +--enum minstrel_sample_mode { +-- MINSTREL_SAMPLE_IDLE, +-- MINSTREL_SAMPLE_ACTIVE, +-- MINSTREL_SAMPLE_PENDING, +--}; +-- +- struct minstrel_sample_category { +- u8 sample_group; +- u16 sample_rates[MINSTREL_SAMPLE_RATES]; +-@@ -182,23 +175,19 @@ struct minstrel_ht_sta { +- unsigned int overhead_legacy; +- unsigned int overhead_legacy_rtscts; +- +-- unsigned int total_packets_last; +-- unsigned int total_packets_cur; +- unsigned int total_packets; +- unsigned int sample_packets; +- +- /* tx flags to add for frames for this sta */ +- u32 tx_flags; +- +-- unsigned long sample_time; +-- struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX]; +-+ u8 band; +- +- u8 sample_seq; +-- +-- enum minstrel_sample_mode sample_mode; +- u16 sample_rate; +- +-- u8 band; +-+ unsigned long sample_time; +-+ struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX]; +- +- /* Bitfield of supported MCS rates of all groups */ +- u16 supported[MINSTREL_GROUPS_NB]; +diff --git a/package/kernel/mac80211/patches/subsys/352-mac80211-minstrel_ht-fix-regression-in-the-max_prob_.patch b/package/kernel/mac80211/patches/subsys/352-mac80211-minstrel_ht-fix-regression-in-the-max_prob_.patch +deleted file mode 100644 +index a366a921d4..0000000000 +--- a/package/kernel/mac80211/patches/subsys/352-mac80211-minstrel_ht-fix-regression-in-the-max_prob_.patch ++++ /dev/null +@@ -1,23 +0,0 @@ +-From: Felix Fietkau +-Date: Tue, 26 Jan 2021 16:40:52 +0100 +-Subject: [PATCH] mac80211: minstrel_ht: fix regression in the max_prob_rate +- fix +- +-Since mi->max_prob_rate is overwritten after the loop that calls +-minstrel_ht_set_best_prob_rate, the new best rate needs to be written to *dest +- +-Fixes: a7fca4e4037f ("mac80211: minstrel_ht: fix max probability rate selection") +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -545,7 +545,7 @@ minstrel_ht_set_best_prob_rate(struct mi +- cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, +- mrs->prob_avg); +- if (cur_tp_avg > tmp_tp_avg) +-- mi->max_prob_rate = index; +-+ *dest = index; +- +- max_gpr_tp_avg = minstrel_ht_get_tp_avg(mi, max_gpr_group, +- max_gpr_idx, +diff --git a/package/kernel/mac80211/patches/subsys/355-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch b/package/kernel/mac80211/patches/subsys/355-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch +index aec2e07781..a6817bd4a6 100644 +--- a/package/kernel/mac80211/patches/subsys/355-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch ++++ b/package/kernel/mac80211/patches/subsys/355-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch +@@ -86,7 +86,7 @@ Signed-off-by: Felix Fietkau + static u16 + __minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi, + enum minstrel_sample_type type) +-@@ -1111,8 +1080,6 @@ minstrel_ht_update_stats(struct minstrel ++@@ -1107,8 +1076,6 @@ minstrel_ht_update_stats(struct minstrel + + mi->max_prob_rate = tmp_max_prob_rate; + +@@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau + minstrel_ht_refill_sample_rates(mi); + + #ifdef CPTCFG_MAC80211_DEBUGFS +-@@ -1157,7 +1124,7 @@ minstrel_ht_txstat_valid(struct minstrel ++@@ -1153,7 +1120,7 @@ minstrel_ht_txstat_valid(struct minstrel + } + + static void +@@ -104,7 +104,7 @@ Signed-off-by: Felix Fietkau + { + int group, orig_group; + +-@@ -1172,11 +1139,7 @@ minstrel_downgrade_rate(struct minstrel_ ++@@ -1168,11 +1135,7 @@ minstrel_downgrade_rate(struct minstrel_ + minstrel_mcs_groups[orig_group].streams) + continue; + +@@ -117,7 +117,7 @@ Signed-off-by: Felix Fietkau + } + } + +-@@ -1210,7 +1173,7 @@ minstrel_ht_tx_status(void *priv, struct ++@@ -1183,7 +1146,7 @@ minstrel_ht_tx_status(void *priv, struct + struct ieee80211_tx_info *info = st->info; + struct minstrel_ht_sta *mi = priv_sta; + struct ieee80211_tx_rate *ar = info->status.rates; +@@ -126,7 +126,7 @@ Signed-off-by: Felix Fietkau + struct minstrel_priv *mp = priv; + u32 update_interval = mp->update_interval; + bool last, update = false; +-@@ -1256,18 +1219,13 @@ minstrel_ht_tx_status(void *priv, struct ++@@ -1233,18 +1196,13 @@ minstrel_ht_tx_status(void *priv, struct + /* + * check for sudden death of spatial multiplexing, + * downgrade to a lower number of streams if necessary. +diff --git a/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch b/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch +deleted file mode 100644 +index 3ce6ceacd5..0000000000 +--- a/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch ++++ /dev/null +@@ -1,60 +0,0 @@ +-From: Johannes Berg +-Date: Fri, 19 Mar 2021 23:28:01 +0100 +-Subject: [PATCH] mac80211: don't apply flow control on management frames +- +-In some cases (depending on the driver, but it's true e.g. for +-iwlwifi) we're using an internal TXQ for management packets, +-mostly to simplify the code and to have a place to queue them. +-However, it appears that in certain cases we can confuse the +-code and management frames are dropped, which is certainly not +-what we want. +- +-Short-circuit the processing of management frames. To keep the +-impact minimal, only put them on the frags queue and check the +-tid == management only for doing that and to skip the airtime +-fairness checks, if applicable. +- +-Signed-off-by: Johannes Berg +---- +- +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -5,7 +5,7 @@ +- * Copyright 2006-2007 Jiri Benc +- * Copyright 2007 Johannes Berg +- * Copyright 2013-2014 Intel Mobile Communications GmbH +-- * Copyright (C) 2018-2020 Intel Corporation +-+ * Copyright (C) 2018-2021 Intel Corporation +- * +- * Transmit and frame generation functions. +- */ +-@@ -1401,8 +1401,17 @@ static void ieee80211_txq_enqueue(struct +- ieee80211_set_skb_enqueue_time(skb); +- +- spin_lock_bh(&fq->lock); +-- fq_tin_enqueue(fq, tin, flow_idx, skb, +-- fq_skb_free_func); +-+ /* +-+ * For management frames, don't really apply codel etc., +-+ * we don't want to apply any shaping or anything we just +-+ * want to simplify the driver API by having them on the +-+ * txqi. +-+ */ +-+ if (unlikely(txqi->txq.tid == IEEE80211_NUM_TIDS)) +-+ __skb_queue_tail(&txqi->frags, skb); +-+ else +-+ fq_tin_enqueue(fq, tin, flow_idx, skb, +-+ fq_skb_free_func); +- spin_unlock_bh(&fq->lock); +- } +- +-@@ -3866,6 +3875,9 @@ bool ieee80211_txq_airtime_check(struct +- if (!txq->sta) +- return true; +- +-+ if (unlikely(txq->tid == IEEE80211_NUM_TIDS)) +-+ return true; +-+ +- sta = container_of(txq->sta, struct sta_info, sta); +- if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) < +- sta->airtime[txq->ac].aql_limit_low) +diff --git a/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch b/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch +deleted file mode 100644 +index c8f3047a34..0000000000 +--- a/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch ++++ /dev/null +@@ -1,21 +0,0 @@ +-From: Lorenzo Bianconi +-Date: Mon, 8 Mar 2021 23:01:49 +0100 +-Subject: [PATCH] mac80211: set sk_pacing_shift for 802.3 txpath +- +-Similar to 802.11 txpath, set socket sk_pacing_shift for 802.3 tx path. +- +-Signed-off-by: Lorenzo Bianconi +---- +- +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -4193,6 +4193,9 @@ static bool ieee80211_tx_8023(struct iee +- unsigned long flags; +- int q = info->hw_queue; +- +-+ if (sta) +-+ sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift); +-+ +- if (ieee80211_queue_skb(local, sdata, sta, skb)) +- return true; +- +diff --git a/package/kernel/mac80211/patches/subsys/373-mac80211-support-Rx-timestamp-calculation-for-all-pr.patch b/package/kernel/mac80211/patches/subsys/373-mac80211-support-Rx-timestamp-calculation-for-all-pr.patch +deleted file mode 100644 +index 117fb35fcf..0000000000 +--- a/package/kernel/mac80211/patches/subsys/373-mac80211-support-Rx-timestamp-calculation-for-all-pr.patch ++++ /dev/null +@@ -1,134 +0,0 @@ +-From: Avraham Stern +-Date: Sun, 6 Dec 2020 14:54:45 +0200 +-Subject: [PATCH] mac80211: support Rx timestamp calculation for all preamble +- types +- +-Add support for calculating the Rx timestamp for HE frames. +-Since now all frame types are supported, allow setting the Rx +-timestamp regardless of the frame type. +- +-Signed-off-by: Avraham Stern +-Signed-off-by: Luca Coelho +-Link: https://lore.kernel.org/r/iwlwifi.20201206145305.4786559af475.Ia54486bb0a12e5351f9d5c60ef6fcda7c9e7141c@changeid +-Signed-off-by: Johannes Berg +---- +- +---- a/net/mac80211/ieee80211_i.h +-+++ b/net/mac80211/ieee80211_i.h +-@@ -1587,13 +1587,8 @@ ieee80211_have_rx_timestamp(struct ieee8 +- { +- WARN_ON_ONCE(status->flag & RX_FLAG_MACTIME_START && +- status->flag & RX_FLAG_MACTIME_END); +-- if (status->flag & (RX_FLAG_MACTIME_START | RX_FLAG_MACTIME_END)) +-- return true; +-- /* can't handle non-legacy preamble yet */ +-- if (status->flag & RX_FLAG_MACTIME_PLCP_START && +-- status->encoding == RX_ENC_LEGACY) +-- return true; +-- return false; +-+ return !!(status->flag & (RX_FLAG_MACTIME_START | RX_FLAG_MACTIME_END | +-+ RX_FLAG_MACTIME_PLCP_START)); +- } +- +- void ieee80211_vif_inc_num_mcast(struct ieee80211_sub_if_data *sdata); +---- a/net/mac80211/util.c +-+++ b/net/mac80211/util.c +-@@ -3665,6 +3665,7 @@ u64 ieee80211_calculate_rx_timestamp(str +- u64 ts = status->mactime; +- struct rate_info ri; +- u16 rate; +-+ u8 n_ltf; +- +- if (WARN_ON(!ieee80211_have_rx_timestamp(status))) +- return 0; +-@@ -3675,11 +3676,58 @@ u64 ieee80211_calculate_rx_timestamp(str +- +- /* Fill cfg80211 rate info */ +- switch (status->encoding) { +-+ case RX_ENC_HE: +-+ ri.flags |= RATE_INFO_FLAGS_HE_MCS; +-+ ri.mcs = status->rate_idx; +-+ ri.nss = status->nss; +-+ ri.he_ru_alloc = status->he_ru; +-+ if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) +-+ ri.flags |= RATE_INFO_FLAGS_SHORT_GI; +-+ +-+ /* +-+ * See P802.11ax_D6.0, section 27.3.4 for +-+ * VHT PPDU format. +-+ */ +-+ if (status->flag & RX_FLAG_MACTIME_PLCP_START) { +-+ mpdu_offset += 2; +-+ ts += 36; +-+ +-+ /* +-+ * TODO: +-+ * For HE MU PPDU, add the HE-SIG-B. +-+ * For HE ER PPDU, add 8us for the HE-SIG-A. +-+ * For HE TB PPDU, add 4us for the HE-STF. +-+ * Add the HE-LTF durations - variable. +-+ */ +-+ } +-+ +-+ break; +- case RX_ENC_HT: +- ri.mcs = status->rate_idx; +- ri.flags |= RATE_INFO_FLAGS_MCS; +- if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) +- ri.flags |= RATE_INFO_FLAGS_SHORT_GI; +-+ +-+ /* +-+ * See P802.11REVmd_D3.0, section 19.3.2 for +-+ * HT PPDU format. +-+ */ +-+ if (status->flag & RX_FLAG_MACTIME_PLCP_START) { +-+ mpdu_offset += 2; +-+ if (status->enc_flags & RX_ENC_FLAG_HT_GF) +-+ ts += 24; +-+ else +-+ ts += 32; +-+ +-+ /* +-+ * Add Data HT-LTFs per streams +-+ * TODO: add Extension HT-LTFs, 4us per LTF +-+ */ +-+ n_ltf = ((ri.mcs >> 3) & 3) + 1; +-+ n_ltf = n_ltf == 3 ? 4 : n_ltf; +-+ ts += n_ltf * 4; +-+ } +-+ +- break; +- case RX_ENC_VHT: +- ri.flags |= RATE_INFO_FLAGS_VHT_MCS; +-@@ -3687,6 +3735,23 @@ u64 ieee80211_calculate_rx_timestamp(str +- ri.nss = status->nss; +- if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) +- ri.flags |= RATE_INFO_FLAGS_SHORT_GI; +-+ +-+ /* +-+ * See P802.11REVmd_D3.0, section 21.3.2 for +-+ * VHT PPDU format. +-+ */ +-+ if (status->flag & RX_FLAG_MACTIME_PLCP_START) { +-+ mpdu_offset += 2; +-+ ts += 36; +-+ +-+ /* +-+ * Add VHT-LTFs per streams +-+ */ +-+ n_ltf = (ri.nss != 1) && (ri.nss % 2) ? +-+ ri.nss + 1 : ri.nss; +-+ ts += 4 * n_ltf; +-+ } +-+ +- break; +- default: +- WARN_ON(1); +-@@ -3710,7 +3775,6 @@ u64 ieee80211_calculate_rx_timestamp(str +- ri.legacy = DIV_ROUND_UP(bitrate, (1 << shift)); +- +- if (status->flag & RX_FLAG_MACTIME_PLCP_START) { +-- /* TODO: handle HT/VHT preambles */ +- if (status->band == NL80211_BAND_5GHZ) { +- ts += 20 << shift; +- mpdu_offset += 2; +diff --git a/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch b/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch +deleted file mode 100644 +index 07f5bb5263..0000000000 +--- a/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch ++++ /dev/null +@@ -1,126 +0,0 @@ +-From: Felix Fietkau +-Date: Thu, 17 Jun 2021 17:56:54 +0200 +-Subject: [PATCH] mac80211: move A-MPDU session check from minstrel_ht to +- mac80211 +- +-This avoids calling back into tx handlers from within the rate control module. +-Preparation for deferring rate control until tx dequeue +- +-Signed-off-by: Felix Fietkau +---- +- +---- a/include/net/mac80211.h +-+++ b/include/net/mac80211.h +-@@ -6160,6 +6160,11 @@ enum rate_control_capabilities { +- * otherwise the NSS difference doesn't bother us. +- */ +- RATE_CTRL_CAPA_VHT_EXT_NSS_BW = BIT(0), +-+ /** +-+ * @RATE_CTRL_CAPA_AMPDU_TRIGGER: +-+ * mac80211 should start A-MPDU sessions on tx +-+ */ +-+ RATE_CTRL_CAPA_AMPDU_TRIGGER = BIT(1), +- }; +- +- struct rate_control_ops { +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -1144,29 +1144,6 @@ minstrel_downgrade_prob_rate(struct mins +- } +- +- static void +--minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb) +--{ +-- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; +-- struct sta_info *sta = container_of(pubsta, struct sta_info, sta); +-- u16 tid; +-- +-- if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) +-- return; +-- +-- if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) +-- return; +-- +-- if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) +-- return; +-- +-- tid = ieee80211_get_tid(hdr); +-- if (likely(sta->ampdu_mlme.tid_tx[tid])) +-- return; +-- +-- ieee80211_start_tx_ba_session(pubsta, tid, 0); +--} +-- +--static void +- minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, +- void *priv_sta, struct ieee80211_tx_status *st) +- { +-@@ -1461,10 +1438,6 @@ minstrel_ht_get_rate(void *priv, struct +- struct minstrel_priv *mp = priv; +- u16 sample_idx; +- +-- if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && +-- !minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_prob_rate))) +-- minstrel_aggr_check(sta, txrc->skb); +-- +- info->flags |= mi->tx_flags; +- +- #ifdef CPTCFG_MAC80211_DEBUGFS +-@@ -1870,6 +1843,7 @@ static u32 minstrel_ht_get_expected_thro +- +- static const struct rate_control_ops mac80211_minstrel_ht = { +- .name = "minstrel_ht", +-+ .capa = RATE_CTRL_CAPA_AMPDU_TRIGGER, +- .tx_status_ext = minstrel_ht_tx_status, +- .get_rate = minstrel_ht_get_rate, +- .rate_init = minstrel_ht_rate_init, +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -3953,6 +3953,29 @@ void ieee80211_txq_schedule_start(struct +- } +- EXPORT_SYMBOL(ieee80211_txq_schedule_start); +- +-+static void +-+ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, +-+ struct sta_info *sta, +-+ struct sk_buff *skb) +-+{ +-+ struct rate_control_ref *ref = sdata->local->rate_ctrl; +-+ u16 tid; +-+ +-+ if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER)) +-+ return; +-+ +-+ if (!sta || !sta->sta.ht_cap.ht_supported || +-+ !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO || +-+ skb->protocol == sdata->control_port_protocol) +-+ return; +-+ +-+ tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; +-+ if (likely(sta->ampdu_mlme.tid_tx[tid])) +-+ return; +-+ +-+ ieee80211_start_tx_ba_session(&sta->sta, tid, 0); +-+} +-+ +- void __ieee80211_subif_start_xmit(struct sk_buff *skb, +- struct net_device *dev, +- u32 info_flags, +-@@ -3983,6 +4006,8 @@ void __ieee80211_subif_start_xmit(struct +- skb_get_hash(skb); +- } +- +-+ ieee80211_aggr_check(sdata, sta, skb); +-+ +- if (sta) { +- struct ieee80211_fast_tx *fast_tx; +- +-@@ -4246,6 +4271,8 @@ static void ieee80211_8023_xmit(struct i +- +- memset(info, 0, sizeof(*info)); +- +-+ ieee80211_aggr_check(sdata, sta, skb); +-+ +- tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; +- tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); +- if (tid_tx) { +diff --git a/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch b/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch +deleted file mode 100644 +index 26f7f59296..0000000000 +--- a/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch ++++ /dev/null +@@ -1,114 +0,0 @@ +-From: Ryder Lee +-Date: Fri, 28 May 2021 14:05:41 +0800 +-Subject: [PATCH] mac80211: call ieee80211_tx_h_rate_ctrl() when dequeue +- +-Make ieee80211_tx_h_rate_ctrl() get called on dequeue to improve +-performance since it reduces the turnaround time for rate control. +- +-Signed-off-by: Ryder Lee +---- +- +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -1778,8 +1778,6 @@ static int invoke_tx_handlers_early(stru +- CALL_TXH(ieee80211_tx_h_ps_buf); +- CALL_TXH(ieee80211_tx_h_check_control_port_protocol); +- CALL_TXH(ieee80211_tx_h_select_key); +-- if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL)) +-- CALL_TXH(ieee80211_tx_h_rate_ctrl); +- +- txh_done: +- if (unlikely(res == TX_DROP)) { +-@@ -1812,6 +1810,9 @@ static int invoke_tx_handlers_late(struc +- goto txh_done; +- } +- +-+ if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL)) +-+ CALL_TXH(ieee80211_tx_h_rate_ctrl); +-+ +- CALL_TXH(ieee80211_tx_h_michael_mic_add); +- CALL_TXH(ieee80211_tx_h_sequence); +- CALL_TXH(ieee80211_tx_h_fragment); +-@@ -3404,15 +3405,21 @@ out: +- * Can be called while the sta lock is held. Anything that can cause packets to +- * be generated will cause deadlock! +- */ +--static void ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata, +-- struct sta_info *sta, u8 pn_offs, +-- struct ieee80211_key *key, +-- struct sk_buff *skb) +-+static ieee80211_tx_result +-+ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata, +-+ struct sta_info *sta, u8 pn_offs, +-+ struct ieee80211_key *key, +-+ struct ieee80211_tx_data *tx) +- { +-+ struct sk_buff *skb = tx->skb; +- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +- struct ieee80211_hdr *hdr = (void *)skb->data; +- u8 tid = IEEE80211_NUM_TIDS; +- +-+ if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL) && +-+ ieee80211_tx_h_rate_ctrl(tx) != TX_CONTINUE) +-+ return TX_DROP; +-+ +- if (key) +- info->control.hw_key = &key->conf; +- +-@@ -3461,6 +3468,8 @@ static void ieee80211_xmit_fast_finish(s +- break; +- } +- } +-+ +-+ return TX_CONTINUE; +- } +- +- static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, +-@@ -3564,24 +3573,17 @@ static bool ieee80211_xmit_fast(struct i +- tx.sta = sta; +- tx.key = fast_tx->key; +- +-- if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) { +-- tx.skb = skb; +-- r = ieee80211_tx_h_rate_ctrl(&tx); +-- skb = tx.skb; +-- tx.skb = NULL; +-- +-- if (r != TX_CONTINUE) { +-- if (r != TX_QUEUED) +-- kfree_skb(skb); +-- return true; +-- } +-- } +-- +- if (ieee80211_queue_skb(local, sdata, sta, skb)) +- return true; +- +-- ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs, +-- fast_tx->key, skb); +-+ tx.skb = skb; +-+ r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs, +-+ fast_tx->key, &tx); +-+ tx.skb = NULL; +-+ if (r == TX_DROP) { +-+ kfree_skb(skb); +-+ return true; +-+ } +- +- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) +- sdata = container_of(sdata->bss, +-@@ -3692,8 +3694,12 @@ begin: +- (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) +- pn_offs = ieee80211_hdrlen(hdr->frame_control); +- +-- ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs, +-- tx.key, skb); +-+ r = ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs, +-+ tx.key, &tx); +-+ if (r != TX_CONTINUE) { +-+ ieee80211_free_txskb(&local->hw, skb); +-+ goto begin; +-+ } +- } else { +- if (invoke_tx_handlers_late(&tx)) +- goto begin; +diff --git a/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch b/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch +deleted file mode 100644 +index 5d390990cd..0000000000 +--- a/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch ++++ /dev/null +@@ -1,126 +0,0 @@ +-From: Ryder Lee +-Date: Fri, 28 May 2021 14:05:43 +0800 +-Subject: [PATCH] mac80211: add rate control support for encap offload +- +-The software rate control cannot deal with encap offload, so fix it. +- +-Signed-off-by: Ryder Lee +---- +- +---- a/net/mac80211/rate.c +-+++ b/net/mac80211/rate.c +-@@ -297,15 +297,11 @@ void ieee80211_check_rate_mask(struct ie +- static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc) +- { +- struct sk_buff *skb = txrc->skb; +-- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; +- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +-- __le16 fc; +-- +-- fc = hdr->frame_control; +- +- return (info->flags & (IEEE80211_TX_CTL_NO_ACK | +- IEEE80211_TX_CTL_USE_MINRATE)) || +-- !ieee80211_is_data(fc); +-+ !ieee80211_is_tx_data(skb); +- } +- +- static void rc_send_low_basicrate(struct ieee80211_tx_rate *rate, +-@@ -870,7 +866,6 @@ void ieee80211_get_tx_rates(struct ieee8 +- int max_rates) +- { +- struct ieee80211_sub_if_data *sdata; +-- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; +- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +- struct ieee80211_supported_band *sband; +- +-@@ -882,7 +877,7 @@ void ieee80211_get_tx_rates(struct ieee8 +- sdata = vif_to_sdata(vif); +- sband = sdata->local->hw.wiphy->bands[info->band]; +- +-- if (ieee80211_is_data(hdr->frame_control)) +-+ if (ieee80211_is_tx_data(skb)) +- rate_control_apply_mask(sdata, sta, sband, dest, max_rates); +- +- if (dest[0].idx < 0) +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -679,6 +679,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021 +- u32 len; +- struct ieee80211_tx_rate_control txrc; +- struct ieee80211_sta_rates *ratetbl = NULL; +-+ bool encap = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; +- bool assoc = false; +- +- memset(&txrc, 0, sizeof(txrc)); +-@@ -720,7 +721,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021 +- * just wants a probe response. +- */ +- if (tx->sdata->vif.bss_conf.use_short_preamble && +-- (ieee80211_is_data(hdr->frame_control) || +-+ (ieee80211_is_tx_data(tx->skb) || +- (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) +- txrc.short_preamble = true; +- +-@@ -742,7 +743,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021 +- "%s: Dropped data frame as no usable bitrate found while " +- "scanning and associated. Target station: " +- "%pM on %d GHz band\n", +-- tx->sdata->name, hdr->addr1, +-+ tx->sdata->name, +-+ encap ? ((struct ethhdr *)hdr)->h_dest : hdr->addr1, +- info->band ? 5 : 2)) +- return TX_DROP; +- +-@@ -776,7 +778,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021 +- +- if (txrc.reported_rate.idx < 0) { +- txrc.reported_rate = tx->rate; +-- if (tx->sta && ieee80211_is_data(hdr->frame_control)) +-+ if (tx->sta && ieee80211_is_tx_data(tx->skb)) +- tx->sta->tx_stats.last_rate = txrc.reported_rate; +- } else if (tx->sta) +- tx->sta->tx_stats.last_rate = txrc.reported_rate; +-@@ -3682,8 +3684,16 @@ begin: +- else +- info->flags &= ~IEEE80211_TX_CTL_AMPDU; +- +-- if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) +-+ if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { +-+ if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) { +-+ r = ieee80211_tx_h_rate_ctrl(&tx); +-+ if (r != TX_CONTINUE) { +-+ ieee80211_free_txskb(&local->hw, skb); +-+ goto begin; +-+ } +-+ } +- goto encap_out; +-+ } +- +- if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) { +- struct sta_info *sta = container_of(txq->sta, struct sta_info, +---- a/include/net/mac80211.h +-+++ b/include/net/mac80211.h +-@@ -6733,4 +6733,22 @@ struct sk_buff *ieee80211_get_fils_disco +- struct sk_buff * +- ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw, +- struct ieee80211_vif *vif); +-+ +-+/** +-+ * 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 +-+ * hardware encapsulation enabled are data frames. +-+ * +-+ * @skb: the frame to be transmitted. +-+ */ +-+static inline bool ieee80211_is_tx_data(struct sk_buff *skb) +-+{ +-+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +-+ struct ieee80211_hdr *hdr = (void *) skb->data; +-+ +-+ return info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP || +-+ ieee80211_is_data(hdr->frame_control); +-+} +-+ +- #endif /* MAC80211_H */ +diff --git a/package/kernel/mac80211/patches/subsys/377-mac80211-minstrel_ht-fix-sample-time-check.patch b/package/kernel/mac80211/patches/subsys/377-mac80211-minstrel_ht-fix-sample-time-check.patch +deleted file mode 100644 +index 054662f3ef..0000000000 +--- a/package/kernel/mac80211/patches/subsys/377-mac80211-minstrel_ht-fix-sample-time-check.patch ++++ /dev/null +@@ -1,23 +0,0 @@ +-From: Felix Fietkau +-Date: Thu, 17 Jun 2021 12:05:54 +0200 +-Subject: [PATCH] mac80211: minstrel_ht: fix sample time check +- +-We need to skip sampling if the next sample time is after jiffies, not before. +-This patch fixes an issue where in some cases only very little sampling (or none +-at all) is performed, leading to really bad data rates +- +-Fixes: 80d55154b2f8 ("mac80211: minstrel_ht: significantly redesign the rate probing strategy") +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/rc80211_minstrel_ht.c +-+++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -1450,7 +1450,7 @@ minstrel_ht_get_rate(void *priv, struct +- (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) +- return; +- +-- if (time_is_before_jiffies(mi->sample_time)) +-+ if (time_is_after_jiffies(mi->sample_time)) +- return; +- +- mi->sample_time = jiffies + MINSTREL_SAMPLE_INTERVAL; +diff --git a/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch b/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch +deleted file mode 100644 +index c7902d6542..0000000000 +--- a/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch ++++ /dev/null +@@ -1,112 +0,0 @@ +-From: Felix Fietkau +-Date: Tue, 29 Jun 2021 13:25:09 +0200 +-Subject: [PATCH] mac80211: fix starting aggregation sessions on mesh +- interfaces +- +-The logic for starting aggregation sessions was recently moved from minstrel_ht +-to mac80211, into the subif tx handler just after the sta lookup. +-Unfortunately this didn't work for mesh interfaces, since the sta lookup is +-deferred until a much later point in time on those. +-Fix this by also calling the aggregation check right after the deferred sta +-lookup. +- +-Fixes: 08a46c642001 ("mac80211: move A-MPDU session check from minstrel_ht to mac80211") +-Signed-off-by: Felix Fietkau +---- +- +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -1159,6 +1159,29 @@ static bool ieee80211_tx_prep_agg(struct +- return queued; +- } +- +-+static void +-+ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, +-+ struct sta_info *sta, +-+ struct sk_buff *skb) +-+{ +-+ struct rate_control_ref *ref = sdata->local->rate_ctrl; +-+ u16 tid; +-+ +-+ if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER)) +-+ return; +-+ +-+ if (!sta || !sta->sta.ht_cap.ht_supported || +-+ !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO || +-+ skb->protocol == sdata->control_port_protocol) +-+ return; +-+ +-+ tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; +-+ if (likely(sta->ampdu_mlme.tid_tx[tid])) +-+ return; +-+ +-+ ieee80211_start_tx_ba_session(&sta->sta, tid, 0); +-+} +-+ +- /* +- * initialises @tx +- * pass %NULL for the station if unknown, a valid pointer if known +-@@ -1172,6 +1195,7 @@ ieee80211_tx_prepare(struct ieee80211_su +- struct ieee80211_local *local = sdata->local; +- struct ieee80211_hdr *hdr; +- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +-+ bool aggr_check = false; +- int tid; +- +- memset(tx, 0, sizeof(*tx)); +-@@ -1200,8 +1224,10 @@ ieee80211_tx_prepare(struct ieee80211_su +- } else if (tx->sdata->control_port_protocol == tx->skb->protocol) { +- tx->sta = sta_info_get_bss(sdata, hdr->addr1); +- } +-- if (!tx->sta && !is_multicast_ether_addr(hdr->addr1)) +-+ if (!tx->sta && !is_multicast_ether_addr(hdr->addr1)) { +- tx->sta = sta_info_get(sdata, hdr->addr1); +-+ aggr_check = true; +-+ } +- } +- +- if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && +-@@ -1211,8 +1237,12 @@ ieee80211_tx_prepare(struct ieee80211_su +- struct tid_ampdu_tx *tid_tx; +- +- tid = ieee80211_get_tid(hdr); +-- +- tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]); +-+ if (!tid_tx && aggr_check) { +-+ ieee80211_aggr_check(sdata, tx->sta, skb); +-+ tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]); +-+ } +-+ +- if (tid_tx) { +- bool queued; +- +-@@ -3969,29 +3999,6 @@ void ieee80211_txq_schedule_start(struct +- } +- EXPORT_SYMBOL(ieee80211_txq_schedule_start); +- +--static void +--ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, +-- struct sta_info *sta, +-- struct sk_buff *skb) +--{ +-- struct rate_control_ref *ref = sdata->local->rate_ctrl; +-- u16 tid; +-- +-- if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER)) +-- return; +-- +-- if (!sta || !sta->sta.ht_cap.ht_supported || +-- !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO || +-- skb->protocol == sdata->control_port_protocol) +-- return; +-- +-- tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; +-- if (likely(sta->ampdu_mlme.tid_tx[tid])) +-- return; +-- +-- ieee80211_start_tx_ba_session(&sta->sta, tid, 0); +--} +-- +- void __ieee80211_subif_start_xmit(struct sk_buff *skb, +- struct net_device *dev, +- u32 info_flags, +diff --git a/package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch b/package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch +deleted file mode 100644 +index 073782188a..0000000000 +--- a/package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch ++++ /dev/null +@@ -1,111 +0,0 @@ +-From: Lorenzo Bianconi +-Date: Sat, 9 Jan 2021 18:57:51 +0100 +-Subject: [PATCH] mac80211: introduce aql_enable node in debugfs +- +-Introduce aql_enable node in debugfs in order to enable/disable aql. +-This is useful for debugging purpose. +- +-Signed-off-by: Lorenzo Bianconi +-Link: https://lore.kernel.org/r/e7a934d5d84e4796c4f97ea5de4e66c824296b07.1610214851.git.lorenzo@kernel.org +-Signed-off-by: Johannes Berg +---- +- +---- a/net/mac80211/debugfs.c +-+++ b/net/mac80211/debugfs.c +-@@ -281,6 +281,56 @@ static const struct file_operations aql_ +- .llseek = default_llseek, +- }; +- +-+static ssize_t aql_enable_read(struct file *file, char __user *user_buf, +-+ size_t count, loff_t *ppos) +-+{ +-+ char buf[3]; +-+ int len; +-+ +-+ len = scnprintf(buf, sizeof(buf), "%d\n", +-+ !static_key_false(&aql_disable.key)); +-+ +-+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); +-+} +-+ +-+static ssize_t aql_enable_write(struct file *file, const char __user *user_buf, +-+ size_t count, loff_t *ppos) +-+{ +-+ bool aql_disabled = static_key_false(&aql_disable.key); +-+ char buf[3]; +-+ size_t len; +-+ +-+ if (count > sizeof(buf)) +-+ return -EINVAL; +-+ +-+ if (copy_from_user(buf, user_buf, count)) +-+ return -EFAULT; +-+ +-+ buf[sizeof(buf) - 1] = '\0'; +-+ len = strlen(buf); +-+ if (len > 0 && buf[len - 1] == '\n') +-+ buf[len - 1] = 0; +-+ +-+ if (buf[0] == '0' && buf[1] == '\0') { +-+ if (!aql_disabled) +-+ static_branch_inc(&aql_disable); +-+ } else if (buf[0] == '1' && buf[1] == '\0') { +-+ if (aql_disabled) +-+ static_branch_dec(&aql_disable); +-+ } else { +-+ return -EINVAL; +-+ } +-+ +-+ return count; +-+} +-+ +-+static const struct file_operations aql_enable_ops = { +-+ .write = aql_enable_write, +-+ .read = aql_enable_read, +-+ .open = simple_open, +-+ .llseek = default_llseek, +-+}; +-+ +- static ssize_t force_tx_status_read(struct file *file, +- char __user *user_buf, +- size_t count, +-@@ -569,6 +619,7 @@ void debugfs_hw_add(struct ieee80211_loc +- DEBUGFS_ADD(power); +- DEBUGFS_ADD(hw_conf); +- DEBUGFS_ADD_MODE(force_tx_status, 0600); +-+ DEBUGFS_ADD_MODE(aql_enable, 0600); +- +- if (local->ops->wake_tx_queue) +- DEBUGFS_ADD_MODE(aqm, 0600); +---- a/net/mac80211/ieee80211_i.h +-+++ b/net/mac80211/ieee80211_i.h +-@@ -1140,6 +1140,8 @@ enum mac80211_scan_state { +- SCAN_ABORT, +- }; +- +-+DECLARE_STATIC_KEY_FALSE(aql_disable); +-+ +- struct ieee80211_local { +- /* embed the driver visible part. +- * don't cast (use the static inlines below), but we keep +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -3909,6 +3909,8 @@ void __ieee80211_schedule_txq(struct iee +- } +- EXPORT_SYMBOL(__ieee80211_schedule_txq); +- +-+DEFINE_STATIC_KEY_FALSE(aql_disable); +-+ +- bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, +- struct ieee80211_txq *txq) +- { +-@@ -3918,6 +3920,9 @@ bool ieee80211_txq_airtime_check(struct +- if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) +- return true; +- +-+ if (static_branch_unlikely(&aql_disable)) +-+ return true; +-+ +- if (!txq->sta) +- return true; +- +diff --git a/package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch b/package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch +deleted file mode 100644 +index 708ad6f460..0000000000 +--- a/package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch ++++ /dev/null +@@ -1,39 +0,0 @@ +-From: Johannes Berg +-Date: Fri, 18 Jun 2021 13:41:44 +0300 +-Subject: [PATCH] mac80211: rearrange struct txq_info for fewer holes +- +-We can slightly decrease the size of struct txq_info by +-rearranging some fields for fewer holes, so do that. +- +-Signed-off-by: Johannes Berg +-Signed-off-by: Luca Coelho +-Link: https://lore.kernel.org/r/iwlwifi.20210618133832.1bf019a1fe2e.Ib54622b8d6dc1a9a7dc484e573c073119450538b@changeid +-Signed-off-by: Johannes Berg +---- +- +---- a/net/mac80211/ieee80211_i.h +-+++ b/net/mac80211/ieee80211_i.h +-@@ -5,7 +5,7 @@ +- * Copyright 2006-2007 Jiri Benc +- * Copyright 2007-2010 Johannes Berg +- * Copyright 2013-2015 Intel Mobile Communications GmbH +-- * Copyright (C) 2018-2020 Intel Corporation +-+ * Copyright (C) 2018-2021 Intel Corporation +- */ +- +- #ifndef IEEE80211_I_H +-@@ -848,9 +848,12 @@ struct txq_info { +- struct fq_tin tin; +- struct codel_vars def_cvars; +- struct codel_stats cstats; +-- struct sk_buff_head frags; +-- struct list_head schedule_order; +-+ +- u16 schedule_round; +-+ struct list_head schedule_order; +-+ +-+ struct sk_buff_head frags; +-+ +- unsigned long flags; +- +- /* keep last! */ +diff --git a/package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch b/package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch +deleted file mode 100644 +index 8b3d743b2f..0000000000 +--- a/package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch ++++ /dev/null +@@ -1,1277 +0,0 @@ +-From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +-Date: Wed, 23 Jun 2021 15:47:55 +0200 +-Subject: [PATCH] mac80211: Switch to a virtual time-based airtime scheduler +-MIME-Version: 1.0 +-Content-Type: text/plain; charset=UTF-8 +-Content-Transfer-Encoding: 8bit +- +-This switches the airtime scheduler in mac80211 to use a virtual +-time-based scheduler instead of the round-robin scheduler used before. +-This has a couple of advantages: +- +-- No need to sync up the round-robin scheduler in firmware/hardware with +- the round-robin airtime scheduler. +- +-- If several stations are eligible for transmission we can schedule both +- of them; no need to hard-block the scheduling rotation until the head +- of the queue has used up its quantum. +- +-- The check of whether a station is eligible for transmission becomes +- simpler (in ieee80211_txq_may_transmit()). +- +-The drawback is that scheduling becomes slightly more expensive, as we +-need to maintain an rbtree of TXQs sorted by virtual time. This means +-that ieee80211_register_airtime() becomes O(logN) in the number of +-currently scheduled TXQs because it can change the order of the +-scheduled stations. We mitigate this overhead by only resorting when a +-station changes position in the tree, and hopefully N rarely grows too +-big (it's only TXQs currently backlogged, not all associated stations), +-so it shouldn't be too big of an issue. +- +-To prevent divisions in the fast path, we maintain both station sums and +-pre-computed reciprocals of the sums. This turns the fast-path operation +-into a multiplication, with divisions only happening as the number of +-active stations change (to re-compute the current sum of all active +-station weights). To prevent this re-computation of the reciprocal from +-happening too frequently, we use a time-based notion of station +-activity, instead of updating the weight every time a station gets +-scheduled or de-scheduled. As queues can oscillate between empty and +-occupied quite frequently, this can significantly cut down on the number +-of re-computations. It also has the added benefit of making the station +-airtime calculation independent on whether the queue happened to have +-drained at the time an airtime value was accounted. +- +-Co-developed-by: Yibo Zhao +-Signed-off-by: Yibo Zhao +-Signed-off-by: Toke Høiland-Jørgensen +-Link: https://lore.kernel.org/r/20210623134755.235545-1-toke@redhat.com +-Signed-off-by: Johannes Berg +---- +- +---- a/include/net/mac80211.h +-+++ b/include/net/mac80211.h +-@@ -6557,9 +6557,6 @@ static inline void ieee80211_txq_schedul +- { +- } +- +--void __ieee80211_schedule_txq(struct ieee80211_hw *hw, +-- struct ieee80211_txq *txq, bool force); +-- +- /** +- * ieee80211_schedule_txq - schedule a TXQ for transmission +- * +-@@ -6572,11 +6569,7 @@ void __ieee80211_schedule_txq(struct iee +- * The driver may call this function if it has buffered packets for +- * this TXQ internally. +- */ +--static inline void +--ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq) +--{ +-- __ieee80211_schedule_txq(hw, txq, true); +--} +-+void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq); +- +- /** +- * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq() +-@@ -6588,12 +6581,8 @@ ieee80211_schedule_txq(struct ieee80211_ +- * The driver may set force=true if it has buffered packets for this TXQ +- * internally. +- */ +--static inline void +--ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, +-- bool force) +--{ +-- __ieee80211_schedule_txq(hw, txq, force); +--} +-+void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, +-+ bool force); +- +- /** +- * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit +---- a/net/mac80211/cfg.c +-+++ b/net/mac80211/cfg.c +-@@ -1461,6 +1461,38 @@ static void sta_apply_mesh_params(struct +- #endif +- } +- +-+static void sta_apply_airtime_params(struct ieee80211_local *local, +-+ struct sta_info *sta, +-+ struct station_parameters *params) +-+{ +-+ u8 ac; +-+ +-+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { +-+ struct airtime_sched_info *air_sched = &local->airtime[ac]; +-+ struct airtime_info *air_info = &sta->airtime[ac]; +-+ struct txq_info *txqi; +-+ u8 tid; +-+ +-+ spin_lock_bh(&air_sched->lock); +-+ for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) { +-+ if (air_info->weight == params->airtime_weight || +-+ !sta->sta.txq[tid] || +-+ ac != ieee80211_ac_from_tid(tid)) +-+ continue; +-+ +-+ airtime_weight_set(air_info, params->airtime_weight); +-+ +-+ txqi = to_txq_info(sta->sta.txq[tid]); +-+ if (RB_EMPTY_NODE(&txqi->schedule_order)) +-+ continue; +-+ +-+ ieee80211_update_airtime_weight(local, air_sched, +-+ 0, true); +-+ } +-+ spin_unlock_bh(&air_sched->lock); +-+ } +-+} +-+ +- static int sta_apply_parameters(struct ieee80211_local *local, +- struct sta_info *sta, +- struct station_parameters *params) +-@@ -1648,7 +1680,8 @@ static int sta_apply_parameters(struct i +- sta_apply_mesh_params(local, sta, params); +- +- if (params->airtime_weight) +-- sta->airtime_weight = params->airtime_weight; +-+ sta_apply_airtime_params(local, sta, params); +-+ +- +- /* set the STA state after all sta info from usermode has been set */ +- if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) || +---- a/net/mac80211/debugfs.c +-+++ b/net/mac80211/debugfs.c +-@@ -216,14 +216,14 @@ static ssize_t aql_txq_limit_read(struct +- "VI %u %u\n" +- "BE %u %u\n" +- "BK %u %u\n", +-- local->aql_txq_limit_low[IEEE80211_AC_VO], +-- local->aql_txq_limit_high[IEEE80211_AC_VO], +-- local->aql_txq_limit_low[IEEE80211_AC_VI], +-- local->aql_txq_limit_high[IEEE80211_AC_VI], +-- local->aql_txq_limit_low[IEEE80211_AC_BE], +-- local->aql_txq_limit_high[IEEE80211_AC_BE], +-- local->aql_txq_limit_low[IEEE80211_AC_BK], +-- local->aql_txq_limit_high[IEEE80211_AC_BK]); +-+ local->airtime[IEEE80211_AC_VO].aql_txq_limit_low, +-+ local->airtime[IEEE80211_AC_VO].aql_txq_limit_high, +-+ local->airtime[IEEE80211_AC_VI].aql_txq_limit_low, +-+ local->airtime[IEEE80211_AC_VI].aql_txq_limit_high, +-+ local->airtime[IEEE80211_AC_BE].aql_txq_limit_low, +-+ local->airtime[IEEE80211_AC_BE].aql_txq_limit_high, +-+ local->airtime[IEEE80211_AC_BK].aql_txq_limit_low, +-+ local->airtime[IEEE80211_AC_BK].aql_txq_limit_high); +- return simple_read_from_buffer(user_buf, count, ppos, +- buf, len); +- } +-@@ -255,11 +255,11 @@ static ssize_t aql_txq_limit_write(struc +- if (ac >= IEEE80211_NUM_ACS) +- return -EINVAL; +- +-- q_limit_low_old = local->aql_txq_limit_low[ac]; +-- q_limit_high_old = local->aql_txq_limit_high[ac]; +-+ q_limit_low_old = local->airtime[ac].aql_txq_limit_low; +-+ q_limit_high_old = local->airtime[ac].aql_txq_limit_high; +- +-- local->aql_txq_limit_low[ac] = q_limit_low; +-- local->aql_txq_limit_high[ac] = q_limit_high; +-+ local->airtime[ac].aql_txq_limit_low = q_limit_low; +-+ local->airtime[ac].aql_txq_limit_high = q_limit_high; +- +- mutex_lock(&local->sta_mtx); +- list_for_each_entry(sta, &local->sta_list, list) { +-@@ -382,6 +382,46 @@ static const struct file_operations forc +- .llseek = default_llseek, +- }; +- +-+static ssize_t airtime_read(struct file *file, +-+ char __user *user_buf, +-+ size_t count, +-+ loff_t *ppos) +-+{ +-+ struct ieee80211_local *local = file->private_data; +-+ char buf[200]; +-+ u64 v_t[IEEE80211_NUM_ACS]; +-+ u64 wt[IEEE80211_NUM_ACS]; +-+ int len = 0, ac; +-+ +-+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { +-+ spin_lock_bh(&local->airtime[ac].lock); +-+ v_t[ac] = local->airtime[ac].v_t; +-+ wt[ac] = local->airtime[ac].weight_sum; +-+ spin_unlock_bh(&local->airtime[ac].lock); +-+ } +-+ len = scnprintf(buf, sizeof(buf), +-+ "\tVO VI BE BK\n" +-+ "Virt-t\t%-10llu %-10llu %-10llu %-10llu\n" +-+ "Weight\t%-10llu %-10llu %-10llu %-10llu\n", +-+ v_t[0], +-+ v_t[1], +-+ v_t[2], +-+ v_t[3], +-+ wt[0], +-+ wt[1], +-+ wt[2], +-+ wt[3]); +-+ +-+ return simple_read_from_buffer(user_buf, count, ppos, +-+ buf, len); +-+} +-+ +-+static const struct file_operations airtime_ops = { +-+ .read = airtime_read, +-+ .open = simple_open, +-+ .llseek = default_llseek, +-+}; +-+ +- #ifdef CONFIG_PM +- static ssize_t reset_write(struct file *file, const char __user *user_buf, +- size_t count, loff_t *ppos) +-@@ -624,7 +664,11 @@ void debugfs_hw_add(struct ieee80211_loc +- if (local->ops->wake_tx_queue) +- DEBUGFS_ADD_MODE(aqm, 0600); +- +-- DEBUGFS_ADD_MODE(airtime_flags, 0600); +-+ if (wiphy_ext_feature_isset(local->hw.wiphy, +-+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) { +-+ DEBUGFS_ADD_MODE(airtime, 0600); +-+ DEBUGFS_ADD_MODE(airtime_flags, 0600); +-+ } +- +- DEBUGFS_ADD(aql_txq_limit); +- debugfs_create_u32("aql_threshold", 0600, +---- a/net/mac80211/debugfs_netdev.c +-+++ b/net/mac80211/debugfs_netdev.c +-@@ -513,6 +513,34 @@ static ssize_t ieee80211_if_fmt_aqm( +- } +- IEEE80211_IF_FILE_R(aqm); +- +-+static ssize_t ieee80211_if_fmt_airtime( +-+ const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) +-+{ +-+ struct ieee80211_local *local = sdata->local; +-+ struct ieee80211_txq *txq = sdata->vif.txq; +-+ struct airtime_info *air_info; +-+ int len; +-+ +-+ if (!txq) +-+ return 0; +-+ +-+ spin_lock_bh(&local->airtime[txq->ac].lock); +-+ air_info = to_airtime_info(txq); +-+ len = scnprintf(buf, +-+ buflen, +-+ "RX: %llu us\nTX: %llu us\nWeight: %u\n" +-+ "Virt-T: %lld us\n", +-+ air_info->rx_airtime, +-+ air_info->tx_airtime, +-+ air_info->weight, +-+ air_info->v_t); +-+ spin_unlock_bh(&local->airtime[txq->ac].lock); +-+ +-+ return len; +-+} +-+ +-+IEEE80211_IF_FILE_R(airtime); +-+ +- IEEE80211_IF_FILE(multicast_to_unicast, u.ap.multicast_to_unicast, HEX); +- +- /* IBSS attributes */ +-@@ -661,8 +689,10 @@ static void add_common_files(struct ieee +- +- if (sdata->local->ops->wake_tx_queue && +- sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && +-- sdata->vif.type != NL80211_IFTYPE_NAN) +-+ sdata->vif.type != NL80211_IFTYPE_NAN) { +- DEBUGFS_ADD(aqm); +-+ DEBUGFS_ADD(airtime); +-+ } +- } +- +- static void add_sta_files(struct ieee80211_sub_if_data *sdata) +---- a/net/mac80211/debugfs_sta.c +-+++ b/net/mac80211/debugfs_sta.c +-@@ -202,7 +202,7 @@ static ssize_t sta_airtime_read(struct f +- size_t bufsz = 400; +- char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf; +- u64 rx_airtime = 0, tx_airtime = 0; +-- s64 deficit[IEEE80211_NUM_ACS]; +-+ u64 v_t[IEEE80211_NUM_ACS]; +- ssize_t rv; +- int ac; +- +-@@ -210,18 +210,18 @@ static ssize_t sta_airtime_read(struct f +- return -ENOMEM; +- +- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { +-- spin_lock_bh(&local->active_txq_lock[ac]); +-+ spin_lock_bh(&local->airtime[ac].lock); +- rx_airtime += sta->airtime[ac].rx_airtime; +- tx_airtime += sta->airtime[ac].tx_airtime; +-- deficit[ac] = sta->airtime[ac].deficit; +-- spin_unlock_bh(&local->active_txq_lock[ac]); +-+ v_t[ac] = sta->airtime[ac].v_t; +-+ spin_unlock_bh(&local->airtime[ac].lock); +- } +- +- p += scnprintf(p, bufsz + buf - p, +- "RX: %llu us\nTX: %llu us\nWeight: %u\n" +-- "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", +-- rx_airtime, tx_airtime, sta->airtime_weight, +-- deficit[0], deficit[1], deficit[2], deficit[3]); +-+ "Virt-T: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", +-+ rx_airtime, tx_airtime, sta->airtime[0].weight, +-+ v_t[0], v_t[1], v_t[2], v_t[3]); +- +- rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); +- kfree(buf); +-@@ -236,11 +236,11 @@ static ssize_t sta_airtime_write(struct +- int ac; +- +- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { +-- spin_lock_bh(&local->active_txq_lock[ac]); +-+ spin_lock_bh(&local->airtime[ac].lock); +- sta->airtime[ac].rx_airtime = 0; +- sta->airtime[ac].tx_airtime = 0; +-- sta->airtime[ac].deficit = sta->airtime_weight; +-- spin_unlock_bh(&local->active_txq_lock[ac]); +-+ sta->airtime[ac].v_t = 0; +-+ spin_unlock_bh(&local->airtime[ac].lock); +- } +- +- return count; +-@@ -263,10 +263,10 @@ static ssize_t sta_aql_read(struct file +- return -ENOMEM; +- +- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { +-- spin_lock_bh(&local->active_txq_lock[ac]); +-+ spin_lock_bh(&local->airtime[ac].lock); +- q_limit_l[ac] = sta->airtime[ac].aql_limit_low; +- q_limit_h[ac] = sta->airtime[ac].aql_limit_high; +-- spin_unlock_bh(&local->active_txq_lock[ac]); +-+ spin_unlock_bh(&local->airtime[ac].lock); +- q_depth[ac] = atomic_read(&sta->airtime[ac].aql_tx_pending); +- } +- +---- a/net/mac80211/ieee80211_i.h +-+++ b/net/mac80211/ieee80211_i.h +-@@ -840,20 +840,16 @@ enum txq_info_flags { +- * @def_flow: used as a fallback flow when a packet destined to @tin hashes to +- * a fq_flow which is already owned by a different tin +- * @def_cvars: codel vars for @def_flow +-- * @frags: used to keep fragments created after dequeue +- * @schedule_order: used with ieee80211_local->active_txqs +-- * @schedule_round: counter to prevent infinite loops on TXQ scheduling +-+ * @frags: used to keep fragments created after dequeue +- */ +- struct txq_info { +- struct fq_tin tin; +- struct codel_vars def_cvars; +- struct codel_stats cstats; +-- +-- u16 schedule_round; +-- struct list_head schedule_order; +-+ struct rb_node schedule_order; +- +- struct sk_buff_head frags; +-- +- unsigned long flags; +- +- /* keep last! */ +-@@ -930,6 +926,8 @@ struct ieee80211_sub_if_data { +- struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; +- struct mac80211_qos_map __rcu *qos_map; +- +-+ struct airtime_info airtime[IEEE80211_NUM_ACS]; +-+ +- struct work_struct csa_finalize_work; +- bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */ +- struct cfg80211_chan_def csa_chandef; +-@@ -1143,6 +1141,44 @@ enum mac80211_scan_state { +- SCAN_ABORT, +- }; +- +-+/** +-+ * struct airtime_sched_info - state used for airtime scheduling and AQL +-+ * +-+ * @lock: spinlock that protects all the fields in this struct +-+ * @active_txqs: rbtree of currently backlogged queues, sorted by virtual time +-+ * @schedule_pos: the current position maintained while a driver walks the tree +-+ * with ieee80211_next_txq() +-+ * @active_list: list of struct airtime_info structs that were active within +-+ * the last AIRTIME_ACTIVE_DURATION (100 ms), used to compute +-+ * weight_sum +-+ * @last_weight_update: used for rate limiting walking active_list +-+ * @last_schedule_time: tracks the last time a transmission was scheduled; used +-+ * for catching up v_t if no stations are eligible for +-+ * transmission. +-+ * @v_t: global virtual time; queues with v_t < this are eligible for +-+ * transmission +-+ * @weight_sum: total sum of all active stations used for dividing airtime +-+ * @weight_sum_reciprocal: reciprocal of weight_sum (to avoid divisions in fast +-+ * path - see comment above +-+ * IEEE80211_RECIPROCAL_DIVISOR_64) +-+ * @aql_txq_limit_low: AQL limit when total outstanding airtime +-+ * is < IEEE80211_AQL_THRESHOLD +-+ * @aql_txq_limit_high: AQL limit when total outstanding airtime +-+ * is > IEEE80211_AQL_THRESHOLD +-+ */ +-+struct airtime_sched_info { +-+ spinlock_t lock; +-+ struct rb_root_cached active_txqs; +-+ struct rb_node *schedule_pos; +-+ struct list_head active_list; +-+ u64 last_weight_update; +-+ u64 last_schedule_activity; +-+ u64 v_t; +-+ u64 weight_sum; +-+ u64 weight_sum_reciprocal; +-+ u32 aql_txq_limit_low; +-+ u32 aql_txq_limit_high; +-+}; +- DECLARE_STATIC_KEY_FALSE(aql_disable); +- +- struct ieee80211_local { +-@@ -1156,13 +1192,8 @@ struct ieee80211_local { +- struct codel_params cparams; +- +- /* protects active_txqs and txqi->schedule_order */ +-- spinlock_t active_txq_lock[IEEE80211_NUM_ACS]; +-- struct list_head active_txqs[IEEE80211_NUM_ACS]; +-- u16 schedule_round[IEEE80211_NUM_ACS]; +-- +-+ struct airtime_sched_info airtime[IEEE80211_NUM_ACS]; +- u16 airtime_flags; +-- u32 aql_txq_limit_low[IEEE80211_NUM_ACS]; +-- u32 aql_txq_limit_high[IEEE80211_NUM_ACS]; +- u32 aql_threshold; +- atomic_t aql_total_pending_airtime; +- +-@@ -1581,6 +1612,125 @@ static inline bool txq_has_queue(struct +- return !(skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets); +- } +- +-+static inline struct airtime_info *to_airtime_info(struct ieee80211_txq *txq) +-+{ +-+ struct ieee80211_sub_if_data *sdata; +-+ struct sta_info *sta; +-+ +-+ if (txq->sta) { +-+ sta = container_of(txq->sta, struct sta_info, sta); +-+ return &sta->airtime[txq->ac]; +-+ } +-+ +-+ sdata = vif_to_sdata(txq->vif); +-+ return &sdata->airtime[txq->ac]; +-+} +-+ +-+/* To avoid divisions in the fast path, we keep pre-computed reciprocals for +-+ * airtime weight calculations. There are two different weights to keep track +-+ * of: The per-station weight and the sum of weights per phy. +-+ * +-+ * For the per-station weights (kept in airtime_info below), we use 32-bit +-+ * reciprocals with a devisor of 2^19. This lets us keep the multiplications and +-+ * divisions for the station weights as 32-bit operations at the cost of a bit +-+ * of rounding error for high weights; but the choice of divisor keeps rounding +-+ * errors <10% for weights <2^15, assuming no more than 8ms of airtime is +-+ * reported at a time. +-+ * +-+ * For the per-phy sum of weights the values can get higher, so we use 64-bit +-+ * operations for those with a 32-bit divisor, which should avoid any +-+ * significant rounding errors. +-+ */ +-+#define IEEE80211_RECIPROCAL_DIVISOR_64 0x100000000ULL +-+#define IEEE80211_RECIPROCAL_SHIFT_64 32 +-+#define IEEE80211_RECIPROCAL_DIVISOR_32 0x80000U +-+#define IEEE80211_RECIPROCAL_SHIFT_32 19 +-+ +-+static inline void airtime_weight_set(struct airtime_info *air_info, u16 weight) +-+{ +-+ if (air_info->weight == weight) +-+ return; +-+ +-+ air_info->weight = weight; +-+ if (weight) { +-+ air_info->weight_reciprocal = +-+ IEEE80211_RECIPROCAL_DIVISOR_32 / weight; +-+ } else { +-+ air_info->weight_reciprocal = 0; +-+ } +-+} +-+ +-+static inline void airtime_weight_sum_set(struct airtime_sched_info *air_sched, +-+ int weight_sum) +-+{ +-+ if (air_sched->weight_sum == weight_sum) +-+ return; +-+ +-+ air_sched->weight_sum = weight_sum; +-+ if (air_sched->weight_sum) { +-+ air_sched->weight_sum_reciprocal = IEEE80211_RECIPROCAL_DIVISOR_64; +-+ do_div(air_sched->weight_sum_reciprocal, air_sched->weight_sum); +-+ } else { +-+ air_sched->weight_sum_reciprocal = 0; +-+ } +-+} +-+ +-+/* A problem when trying to enforce airtime fairness is that we want to divide +-+ * the airtime between the currently *active* stations. However, basing this on +-+ * the instantaneous queue state of stations doesn't work, as queues tend to +-+ * oscillate very quickly between empty and occupied, leading to the scheduler +-+ * thinking only a single station is active when deciding whether to allow +-+ * transmission (and thus not throttling correctly). +-+ * +-+ * To fix this we use a timer-based notion of activity: a station is considered +-+ * active if it has been scheduled within the last 100 ms; we keep a separate +-+ * list of all the stations considered active in this manner, and lazily update +-+ * the total weight of active stations from this list (filtering the stations in +-+ * the list by their 'last active' time). +-+ * +-+ * We add one additional safeguard to guard against stations that manage to get +-+ * scheduled every 100 ms but don't transmit a lot of data, and thus don't use +-+ * up any airtime. Such stations would be able to get priority for an extended +-+ * period of time if they do start transmitting at full capacity again, and so +-+ * we add an explicit maximum for how far behind a station is allowed to fall in +-+ * the virtual airtime domain. This limit is set to a relatively high value of +-+ * 20 ms because the main mechanism for catching up idle stations is the active +-+ * state as described above; i.e., the hard limit should only be hit in +-+ * pathological cases. +-+ */ +-+#define AIRTIME_ACTIVE_DURATION (100 * NSEC_PER_MSEC) +-+#define AIRTIME_MAX_BEHIND 20000 /* 20 ms */ +-+ +-+static inline bool airtime_is_active(struct airtime_info *air_info, u64 now) +-+{ +-+ return air_info->last_scheduled >= now - AIRTIME_ACTIVE_DURATION; +-+} +-+ +-+static inline void airtime_set_active(struct airtime_sched_info *air_sched, +-+ struct airtime_info *air_info, u64 now) +-+{ +-+ air_info->last_scheduled = now; +-+ air_sched->last_schedule_activity = now; +-+ list_move_tail(&air_info->list, &air_sched->active_list); +-+} +-+ +-+static inline bool airtime_catchup_v_t(struct airtime_sched_info *air_sched, +-+ u64 v_t, u64 now) +-+{ +-+ air_sched->v_t = v_t; +-+ return true; +-+} +-+ +-+static inline void init_airtime_info(struct airtime_info *air_info, +-+ struct airtime_sched_info *air_sched) +-+{ +-+ atomic_set(&air_info->aql_tx_pending, 0); +-+ air_info->aql_limit_low = air_sched->aql_txq_limit_low; +-+ air_info->aql_limit_high = air_sched->aql_txq_limit_high; +-+ airtime_weight_set(air_info, IEEE80211_DEFAULT_AIRTIME_WEIGHT); +-+ INIT_LIST_HEAD(&air_info->list); +-+} +-+ +- static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) +- { +- return ether_addr_equal(raddr, addr) || +-@@ -1821,6 +1971,14 @@ int ieee80211_tx_control_port(struct wip +- u64 *cookie); +- int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, +- const u8 *buf, size_t len); +-+void ieee80211_resort_txq(struct ieee80211_hw *hw, +-+ struct ieee80211_txq *txq); +-+void ieee80211_unschedule_txq(struct ieee80211_hw *hw, +-+ struct ieee80211_txq *txq, +-+ bool purge); +-+void ieee80211_update_airtime_weight(struct ieee80211_local *local, +-+ struct airtime_sched_info *air_sched, +-+ u64 now, bool force); +- +- /* HT */ +- void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, +---- a/net/mac80211/iface.c +-+++ b/net/mac80211/iface.c +-@@ -2088,6 +2088,9 @@ int ieee80211_if_add(struct ieee80211_lo +- } +- } +- +-+ for (i = 0; i < IEEE80211_NUM_ACS; i++) +-+ init_airtime_info(&sdata->airtime[i], &local->airtime[i]); +-+ +- ieee80211_set_default_queues(sdata); +- +- sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; +---- a/net/mac80211/main.c +-+++ b/net/mac80211/main.c +-@@ -693,10 +693,13 @@ struct ieee80211_hw *ieee80211_alloc_hw_ +- spin_lock_init(&local->queue_stop_reason_lock); +- +- for (i = 0; i < IEEE80211_NUM_ACS; i++) { +-- INIT_LIST_HEAD(&local->active_txqs[i]); +-- spin_lock_init(&local->active_txq_lock[i]); +-- local->aql_txq_limit_low[i] = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; +-- local->aql_txq_limit_high[i] = +-+ struct airtime_sched_info *air_sched = &local->airtime[i]; +-+ +-+ air_sched->active_txqs = RB_ROOT_CACHED; +-+ INIT_LIST_HEAD(&air_sched->active_list); +-+ spin_lock_init(&air_sched->lock); +-+ air_sched->aql_txq_limit_low = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; +-+ air_sched->aql_txq_limit_high = +- IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H; +- } +- +---- a/net/mac80211/rx.c +-+++ b/net/mac80211/rx.c +-@@ -1573,12 +1573,8 @@ static void sta_ps_start(struct sta_info +- +- for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { +- struct ieee80211_txq *txq = sta->sta.txq[tid]; +-- struct txq_info *txqi = to_txq_info(txq); +- +-- spin_lock(&local->active_txq_lock[txq->ac]); +-- if (!list_empty(&txqi->schedule_order)) +-- list_del_init(&txqi->schedule_order); +-- spin_unlock(&local->active_txq_lock[txq->ac]); +-+ ieee80211_unschedule_txq(&local->hw, txq, false); +- +- if (txq_has_queue(txq)) +- set_bit(tid, &sta->txq_buffered_tids); +---- a/net/mac80211/sta_info.c +-+++ b/net/mac80211/sta_info.c +-@@ -426,15 +426,11 @@ struct sta_info *sta_info_alloc(struct i +- if (sta_prepare_rate_control(local, sta, gfp)) +- goto free_txq; +- +-- sta->airtime_weight = IEEE80211_DEFAULT_AIRTIME_WEIGHT; +- +- for (i = 0; i < IEEE80211_NUM_ACS; i++) { +- skb_queue_head_init(&sta->ps_tx_buf[i]); +- skb_queue_head_init(&sta->tx_filtered[i]); +-- sta->airtime[i].deficit = sta->airtime_weight; +-- atomic_set(&sta->airtime[i].aql_tx_pending, 0); +-- sta->airtime[i].aql_limit_low = local->aql_txq_limit_low[i]; +-- sta->airtime[i].aql_limit_high = local->aql_txq_limit_high[i]; +-+ init_airtime_info(&sta->airtime[i], &local->airtime[i]); +- } +- +- for (i = 0; i < IEEE80211_NUM_TIDS; i++) +-@@ -1893,24 +1889,59 @@ void ieee80211_sta_set_buffered(struct i +- } +- EXPORT_SYMBOL(ieee80211_sta_set_buffered); +- +--void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, +-- u32 tx_airtime, u32 rx_airtime) +-+void ieee80211_register_airtime(struct ieee80211_txq *txq, +-+ u32 tx_airtime, u32 rx_airtime) +- { +-- struct sta_info *sta = container_of(pubsta, struct sta_info, sta); +-- struct ieee80211_local *local = sta->sdata->local; +-- u8 ac = ieee80211_ac_from_tid(tid); +-+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif); +-+ struct ieee80211_local *local = sdata->local; +-+ u64 weight_sum, weight_sum_reciprocal; +-+ struct airtime_sched_info *air_sched; +-+ struct airtime_info *air_info; +- u32 airtime = 0; +- +-- if (sta->local->airtime_flags & AIRTIME_USE_TX) +-+ air_sched = &local->airtime[txq->ac]; +-+ air_info = to_airtime_info(txq); +-+ +-+ if (local->airtime_flags & AIRTIME_USE_TX) +- airtime += tx_airtime; +-- if (sta->local->airtime_flags & AIRTIME_USE_RX) +-+ if (local->airtime_flags & AIRTIME_USE_RX) +- airtime += rx_airtime; +- +-- spin_lock_bh(&local->active_txq_lock[ac]); +-- sta->airtime[ac].tx_airtime += tx_airtime; +-- sta->airtime[ac].rx_airtime += rx_airtime; +-- sta->airtime[ac].deficit -= airtime; +-- spin_unlock_bh(&local->active_txq_lock[ac]); +-+ /* Weights scale so the unit weight is 256 */ +-+ airtime <<= 8; +-+ +-+ spin_lock_bh(&air_sched->lock); +-+ +-+ air_info->tx_airtime += tx_airtime; +-+ air_info->rx_airtime += rx_airtime; +-+ +-+ if (air_sched->weight_sum) { +-+ weight_sum = air_sched->weight_sum; +-+ weight_sum_reciprocal = air_sched->weight_sum_reciprocal; +-+ } else { +-+ weight_sum = air_info->weight; +-+ weight_sum_reciprocal = air_info->weight_reciprocal; +-+ } +-+ +-+ /* Round the calculation of global vt */ +-+ air_sched->v_t += (u64)((airtime + (weight_sum >> 1)) * +-+ weight_sum_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_64; +-+ air_info->v_t += (u32)((airtime + (air_info->weight >> 1)) * +-+ air_info->weight_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_32; +-+ ieee80211_resort_txq(&local->hw, txq); +-+ +-+ spin_unlock_bh(&air_sched->lock); +-+} +-+ +-+void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, +-+ u32 tx_airtime, u32 rx_airtime) +-+{ +-+ struct ieee80211_txq *txq = pubsta->txq[tid]; +-+ +-+ if (!txq) +-+ return; +-+ +-+ ieee80211_register_airtime(txq, tx_airtime, rx_airtime); +- } +- EXPORT_SYMBOL(ieee80211_sta_register_airtime); +- +-@@ -2354,7 +2385,7 @@ void sta_set_sinfo(struct sta_info *sta, +- } +- +- if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { +-- sinfo->airtime_weight = sta->airtime_weight; +-+ sinfo->airtime_weight = sta->airtime[0].weight; +- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); +- } +- +---- a/net/mac80211/sta_info.h +-+++ b/net/mac80211/sta_info.h +-@@ -135,18 +135,25 @@ enum ieee80211_agg_stop_reason { +- #define AIRTIME_USE_TX BIT(0) +- #define AIRTIME_USE_RX BIT(1) +- +-+ +- struct airtime_info { +- u64 rx_airtime; +- u64 tx_airtime; +-- s64 deficit; +-+ u64 v_t; +-+ u64 last_scheduled; +-+ struct list_head list; +- atomic_t aql_tx_pending; /* Estimated airtime for frames pending */ +- u32 aql_limit_low; +- u32 aql_limit_high; +-+ u32 weight_reciprocal; +-+ u16 weight; +- }; +- +- void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, +- struct sta_info *sta, u8 ac, +- u16 tx_airtime, bool tx_completed); +-+void ieee80211_register_airtime(struct ieee80211_txq *txq, +-+ u32 tx_airtime, u32 rx_airtime); +- +- struct sta_info; +- +-@@ -516,7 +523,6 @@ struct ieee80211_fragment_cache { +- * @tid_seq: per-TID sequence numbers for sending to this STA +- * @airtime: per-AC struct airtime_info describing airtime statistics for this +- * station +-- * @airtime_weight: station weight for airtime fairness calculation purposes +- * @ampdu_mlme: A-MPDU state machine state +- * @mesh: mesh STA information +- * @debugfs_dir: debug filesystem directory dentry +-@@ -647,7 +653,6 @@ struct sta_info { +- u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; +- +- struct airtime_info airtime[IEEE80211_NUM_ACS]; +-- u16 airtime_weight; +- +- /* +- * Aggregation information, locked with lock. +---- a/net/mac80211/status.c +-+++ b/net/mac80211/status.c +-@@ -972,6 +972,25 @@ static void __ieee80211_tx_status(struct +- if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked) +- ieee80211_frame_acked(sta, skb); +- +-+ } else if (wiphy_ext_feature_isset(local->hw.wiphy, +-+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) { +-+ struct ieee80211_sub_if_data *sdata; +-+ struct ieee80211_txq *txq; +-+ u32 airtime; +-+ +-+ /* Account airtime to multicast queue */ +-+ sdata = ieee80211_sdata_from_skb(local, skb); +-+ +-+ if (sdata && (txq = sdata->vif.txq)) { +-+ airtime = info->status.tx_time ?: +-+ ieee80211_calc_expected_tx_airtime(hw, +-+ &sdata->vif, +-+ NULL, +-+ skb->len, +-+ false); +-+ +-+ ieee80211_register_airtime(txq, airtime, 0); +-+ } +- } +- +- /* SNMP counters +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -18,6 +18,7 @@ +- #include +- #include +- #include +-+#include +- #include +- #include +- #include +-@@ -1489,7 +1490,7 @@ void ieee80211_txq_init(struct ieee80211 +- codel_vars_init(&txqi->def_cvars); +- codel_stats_init(&txqi->cstats); +- __skb_queue_head_init(&txqi->frags); +-- INIT_LIST_HEAD(&txqi->schedule_order); +-+ RB_CLEAR_NODE(&txqi->schedule_order); +- +- txqi->txq.vif = &sdata->vif; +- +-@@ -1533,9 +1534,7 @@ void ieee80211_txq_purge(struct ieee8021 +- ieee80211_purge_tx_queue(&local->hw, &txqi->frags); +- spin_unlock_bh(&fq->lock); +- +-- spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]); +-- list_del_init(&txqi->schedule_order); +-- spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]); +-+ ieee80211_unschedule_txq(&local->hw, &txqi->txq, true); +- } +- +- void ieee80211_txq_set_params(struct ieee80211_local *local) +-@@ -3819,102 +3818,259 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue); +- struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) +- { +- struct ieee80211_local *local = hw_to_local(hw); +-+ struct airtime_sched_info *air_sched; +-+ u64 now = ktime_get_boottime_ns(); +- struct ieee80211_txq *ret = NULL; +-- struct txq_info *txqi = NULL, *head = NULL; +-- bool found_eligible_txq = false; +-+ struct airtime_info *air_info; +-+ struct txq_info *txqi = NULL; +-+ struct rb_node *node; +-+ bool first = false; +- +-- spin_lock_bh(&local->active_txq_lock[ac]); +-+ air_sched = &local->airtime[ac]; +-+ spin_lock_bh(&air_sched->lock); +- +-- begin: +-- txqi = list_first_entry_or_null(&local->active_txqs[ac], +-- struct txq_info, +-- schedule_order); +-- if (!txqi) +-+ node = air_sched->schedule_pos; +-+ +-+begin: +-+ if (!node) { +-+ node = rb_first_cached(&air_sched->active_txqs); +-+ first = true; +-+ } else { +-+ node = rb_next(node); +-+ } +-+ +-+ if (!node) +- goto out; +- +-- if (txqi == head) { +-- if (!found_eligible_txq) +-- goto out; +-- else +-- found_eligible_txq = false; +-+ txqi = container_of(node, struct txq_info, schedule_order); +-+ air_info = to_airtime_info(&txqi->txq); +-+ +-+ if (air_info->v_t > air_sched->v_t && +-+ (!first || !airtime_catchup_v_t(air_sched, air_info->v_t, now))) +-+ goto out; +-+ +-+ if (!ieee80211_txq_airtime_check(hw, &txqi->txq)) { +-+ first = false; +-+ goto begin; +- } +- +-- if (!head) +-- head = txqi; +-+ air_sched->schedule_pos = node; +-+ air_sched->last_schedule_activity = now; +-+ ret = &txqi->txq; +-+out: +-+ spin_unlock_bh(&air_sched->lock); +-+ return ret; +-+} +-+EXPORT_SYMBOL(ieee80211_next_txq); +- +-- if (txqi->txq.sta) { +-- struct sta_info *sta = container_of(txqi->txq.sta, +-- struct sta_info, sta); +-- bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq); +-- s64 deficit = sta->airtime[txqi->txq.ac].deficit; +-+static void __ieee80211_insert_txq(struct rb_root_cached *root, +-+ struct txq_info *txqi) +-+{ +-+ struct rb_node **new = &root->rb_root.rb_node; +-+ struct airtime_info *old_air, *new_air; +-+ struct rb_node *parent = NULL; +-+ struct txq_info *__txqi; +-+ bool leftmost = true; +-+ +-+ while (*new) { +-+ parent = *new; +-+ __txqi = rb_entry(parent, struct txq_info, schedule_order); +-+ old_air = to_airtime_info(&__txqi->txq); +-+ new_air = to_airtime_info(&txqi->txq); +- +-- if (aql_check) +-- found_eligible_txq = true; +-+ if (new_air->v_t <= old_air->v_t) { +-+ new = &parent->rb_left; +-+ } else { +-+ new = &parent->rb_right; +-+ leftmost = false; +-+ } +-+ } +- +-- if (deficit < 0) +-- sta->airtime[txqi->txq.ac].deficit += +-- sta->airtime_weight; +-- +-- if (deficit < 0 || !aql_check) { +-- list_move_tail(&txqi->schedule_order, +-- &local->active_txqs[txqi->txq.ac]); +-- goto begin; +-+ rb_link_node(&txqi->schedule_order, parent, new); +-+ rb_insert_color_cached(&txqi->schedule_order, root, leftmost); +-+} +-+ +-+void ieee80211_resort_txq(struct ieee80211_hw *hw, +-+ struct ieee80211_txq *txq) +-+{ +-+ struct airtime_info *air_info = to_airtime_info(txq); +-+ struct ieee80211_local *local = hw_to_local(hw); +-+ struct txq_info *txqi = to_txq_info(txq); +-+ struct airtime_sched_info *air_sched; +-+ +-+ air_sched = &local->airtime[txq->ac]; +-+ +-+ lockdep_assert_held(&air_sched->lock); +-+ +-+ if (!RB_EMPTY_NODE(&txqi->schedule_order)) { +-+ struct airtime_info *a_prev = NULL, *a_next = NULL; +-+ struct txq_info *t_prev, *t_next; +-+ struct rb_node *n_prev, *n_next; +-+ +-+ /* Erasing a node can cause an expensive rebalancing operation, +-+ * so we check the previous and next nodes first and only remove +-+ * and re-insert if the current node is not already in the +-+ * correct position. +-+ */ +-+ if ((n_prev = rb_prev(&txqi->schedule_order)) != NULL) { +-+ t_prev = container_of(n_prev, struct txq_info, +-+ schedule_order); +-+ a_prev = to_airtime_info(&t_prev->txq); +-+ } +-+ +-+ if ((n_next = rb_next(&txqi->schedule_order)) != NULL) { +-+ t_next = container_of(n_next, struct txq_info, +-+ schedule_order); +-+ a_next = to_airtime_info(&t_next->txq); +- } +-+ +-+ if ((!a_prev || a_prev->v_t <= air_info->v_t) && +-+ (!a_next || a_next->v_t > air_info->v_t)) +-+ return; +-+ +-+ if (air_sched->schedule_pos == &txqi->schedule_order) +-+ air_sched->schedule_pos = n_prev; +-+ +-+ rb_erase_cached(&txqi->schedule_order, +-+ &air_sched->active_txqs); +-+ RB_CLEAR_NODE(&txqi->schedule_order); +-+ __ieee80211_insert_txq(&air_sched->active_txqs, txqi); +- } +-+} +-+ +-+void ieee80211_update_airtime_weight(struct ieee80211_local *local, +-+ struct airtime_sched_info *air_sched, +-+ u64 now, bool force) +-+{ +-+ struct airtime_info *air_info, *tmp; +-+ u64 weight_sum = 0; +-+ +-+ if (unlikely(!now)) +-+ now = ktime_get_boottime_ns(); +-+ +-+ lockdep_assert_held(&air_sched->lock); +-+ +-+ if (!force && (air_sched->last_weight_update < +-+ now - AIRTIME_ACTIVE_DURATION)) +-+ return; +-+ +-+ list_for_each_entry_safe(air_info, tmp, +-+ &air_sched->active_list, list) { +-+ if (airtime_is_active(air_info, now)) +-+ weight_sum += air_info->weight; +-+ else +-+ list_del_init(&air_info->list); +-+ } +-+ airtime_weight_sum_set(air_sched, weight_sum); +-+ air_sched->last_weight_update = now; +-+} +- +-+void ieee80211_schedule_txq(struct ieee80211_hw *hw, +-+ struct ieee80211_txq *txq) +-+ __acquires(txq_lock) __releases(txq_lock) +-+{ +-+ struct ieee80211_local *local = hw_to_local(hw); +-+ struct txq_info *txqi = to_txq_info(txq); +-+ struct airtime_sched_info *air_sched; +-+ u64 now = ktime_get_boottime_ns(); +-+ struct airtime_info *air_info; +-+ u8 ac = txq->ac; +-+ bool was_active; +- +-- if (txqi->schedule_round == local->schedule_round[ac]) +-+ air_sched = &local->airtime[ac]; +-+ air_info = to_airtime_info(txq); +-+ +-+ spin_lock_bh(&air_sched->lock); +-+ was_active = airtime_is_active(air_info, now); +-+ airtime_set_active(air_sched, air_info, now); +-+ +-+ if (!RB_EMPTY_NODE(&txqi->schedule_order)) +- goto out; +- +-- list_del_init(&txqi->schedule_order); +-- txqi->schedule_round = local->schedule_round[ac]; +-- ret = &txqi->txq; +-+ /* If the station has been inactive for a while, catch up its v_t so it +-+ * doesn't get indefinite priority; see comment above the definition of +-+ * AIRTIME_MAX_BEHIND. +-+ */ +-+ if ((!was_active && air_info->v_t < air_sched->v_t) || +-+ air_info->v_t < air_sched->v_t - AIRTIME_MAX_BEHIND) +-+ air_info->v_t = air_sched->v_t; +-+ +-+ ieee80211_update_airtime_weight(local, air_sched, now, !was_active); +-+ __ieee80211_insert_txq(&air_sched->active_txqs, txqi); +- +- out: +-- spin_unlock_bh(&local->active_txq_lock[ac]); +-- return ret; +-+ spin_unlock_bh(&air_sched->lock); +- } +--EXPORT_SYMBOL(ieee80211_next_txq); +-+EXPORT_SYMBOL(ieee80211_schedule_txq); +- +--void __ieee80211_schedule_txq(struct ieee80211_hw *hw, +-- struct ieee80211_txq *txq, +-- bool force) +-+static void __ieee80211_unschedule_txq(struct ieee80211_hw *hw, +-+ struct ieee80211_txq *txq, +-+ bool purge) +- { +- struct ieee80211_local *local = hw_to_local(hw); +- struct txq_info *txqi = to_txq_info(txq); +-+ struct airtime_sched_info *air_sched; +-+ struct airtime_info *air_info; +- +-- spin_lock_bh(&local->active_txq_lock[txq->ac]); +-+ air_sched = &local->airtime[txq->ac]; +-+ air_info = to_airtime_info(&txqi->txq); +- +-- if (list_empty(&txqi->schedule_order) && +-- (force || !skb_queue_empty(&txqi->frags) || +-- txqi->tin.backlog_packets)) { +-- /* If airtime accounting is active, always enqueue STAs at the +-- * head of the list to ensure that they only get moved to the +-- * back by the airtime DRR scheduler once they have a negative +-- * deficit. A station that already has a negative deficit will +-- * get immediately moved to the back of the list on the next +-- * call to ieee80211_next_txq(). +-- */ +-- if (txqi->txq.sta && local->airtime_flags && +-- wiphy_ext_feature_isset(local->hw.wiphy, +-- NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) +-- list_add(&txqi->schedule_order, +-- &local->active_txqs[txq->ac]); +-- else +-- list_add_tail(&txqi->schedule_order, +-- &local->active_txqs[txq->ac]); +-+ lockdep_assert_held(&air_sched->lock); +-+ +-+ if (purge) { +-+ list_del_init(&air_info->list); +-+ ieee80211_update_airtime_weight(local, air_sched, 0, true); +- } +- +-- spin_unlock_bh(&local->active_txq_lock[txq->ac]); +-+ if (RB_EMPTY_NODE(&txqi->schedule_order)) +-+ return; +-+ +-+ if (air_sched->schedule_pos == &txqi->schedule_order) +-+ air_sched->schedule_pos = rb_prev(&txqi->schedule_order); +-+ +-+ if (!purge) +-+ airtime_set_active(air_sched, air_info, +-+ ktime_get_boottime_ns()); +-+ +-+ rb_erase_cached(&txqi->schedule_order, +-+ &air_sched->active_txqs); +-+ RB_CLEAR_NODE(&txqi->schedule_order); +-+} +-+ +-+void ieee80211_unschedule_txq(struct ieee80211_hw *hw, +-+ struct ieee80211_txq *txq, +-+ bool purge) +-+ __acquires(txq_lock) __releases(txq_lock) +-+{ +-+ struct ieee80211_local *local = hw_to_local(hw); +-+ +-+ spin_lock_bh(&local->airtime[txq->ac].lock); +-+ __ieee80211_unschedule_txq(hw, txq, purge); +-+ spin_unlock_bh(&local->airtime[txq->ac].lock); +-+} +-+ +-+void ieee80211_return_txq(struct ieee80211_hw *hw, +-+ struct ieee80211_txq *txq, bool force) +-+{ +-+ struct ieee80211_local *local = hw_to_local(hw); +-+ struct txq_info *txqi = to_txq_info(txq); +-+ +-+ spin_lock_bh(&local->airtime[txq->ac].lock); +-+ +-+ if (!RB_EMPTY_NODE(&txqi->schedule_order) && !force && +-+ !txq_has_queue(txq)) +-+ __ieee80211_unschedule_txq(hw, txq, false); +-+ +-+ spin_unlock_bh(&local->airtime[txq->ac].lock); +- } +--EXPORT_SYMBOL(__ieee80211_schedule_txq); +-+EXPORT_SYMBOL(ieee80211_return_txq); +- +- DEFINE_STATIC_KEY_FALSE(aql_disable); +- +- bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, +- struct ieee80211_txq *txq) +- { +-- struct sta_info *sta; +-+ struct airtime_info *air_info = to_airtime_info(txq); +- struct ieee80211_local *local = hw_to_local(hw); +- +- if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) +-@@ -3929,15 +4085,12 @@ bool ieee80211_txq_airtime_check(struct +- if (unlikely(txq->tid == IEEE80211_NUM_TIDS)) +- return true; +- +-- sta = container_of(txq->sta, struct sta_info, sta); +-- if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) < +-- sta->airtime[txq->ac].aql_limit_low) +-+ if (atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_low) +- return true; +- +- if (atomic_read(&local->aql_total_pending_airtime) < +- local->aql_threshold && +-- atomic_read(&sta->airtime[txq->ac].aql_tx_pending) < +-- sta->airtime[txq->ac].aql_limit_high) +-+ atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_high) +- return true; +- +- return false; +-@@ -3947,60 +4100,59 @@ EXPORT_SYMBOL(ieee80211_txq_airtime_chec +- bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, +- struct ieee80211_txq *txq) +- { +-+ struct txq_info *first_txqi = NULL, *txqi = to_txq_info(txq); +- struct ieee80211_local *local = hw_to_local(hw); +-- struct txq_info *iter, *tmp, *txqi = to_txq_info(txq); +-- struct sta_info *sta; +-- u8 ac = txq->ac; +-+ struct airtime_sched_info *air_sched; +-+ struct airtime_info *air_info; +-+ struct rb_node *node = NULL; +-+ bool ret = false; +-+ u64 now; +- +-- spin_lock_bh(&local->active_txq_lock[ac]); +- +-- if (!txqi->txq.sta) +-- goto out; +-+ if (!ieee80211_txq_airtime_check(hw, txq)) +-+ return false; +-+ +-+ air_sched = &local->airtime[txq->ac]; +-+ spin_lock_bh(&air_sched->lock); +- +-- if (list_empty(&txqi->schedule_order)) +-+ if (RB_EMPTY_NODE(&txqi->schedule_order)) +- goto out; +- +-- list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac], +-- schedule_order) { +-- if (iter == txqi) +-- break; +-+ now = ktime_get_boottime_ns(); +- +-- if (!iter->txq.sta) { +-- list_move_tail(&iter->schedule_order, +-- &local->active_txqs[ac]); +-- continue; +-- } +-- sta = container_of(iter->txq.sta, struct sta_info, sta); +-- if (sta->airtime[ac].deficit < 0) +-- sta->airtime[ac].deficit += sta->airtime_weight; +-- list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); +-+ /* Like in ieee80211_next_txq(), make sure the first station in the +-+ * scheduling order is eligible for transmission to avoid starvation. +-+ */ +-+ node = rb_first_cached(&air_sched->active_txqs); +-+ if (node) { +-+ first_txqi = container_of(node, struct txq_info, +-+ schedule_order); +-+ air_info = to_airtime_info(&first_txqi->txq); +-+ +-+ if (air_sched->v_t < air_info->v_t) +-+ airtime_catchup_v_t(air_sched, air_info->v_t, now); +- } +- +-- sta = container_of(txqi->txq.sta, struct sta_info, sta); +-- if (sta->airtime[ac].deficit >= 0) +-- goto out; +-- +-- sta->airtime[ac].deficit += sta->airtime_weight; +-- list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); +-- spin_unlock_bh(&local->active_txq_lock[ac]); +-+ air_info = to_airtime_info(&txqi->txq); +-+ if (air_info->v_t <= air_sched->v_t) { +-+ air_sched->last_schedule_activity = now; +-+ ret = true; +-+ } +- +-- return false; +- out: +-- if (!list_empty(&txqi->schedule_order)) +-- list_del_init(&txqi->schedule_order); +-- spin_unlock_bh(&local->active_txq_lock[ac]); +-- +-- return true; +-+ spin_unlock_bh(&air_sched->lock); +-+ return ret; +- } +- EXPORT_SYMBOL(ieee80211_txq_may_transmit); +- +- void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) +- { +- struct ieee80211_local *local = hw_to_local(hw); +-+ struct airtime_sched_info *air_sched = &local->airtime[ac]; +- +-- spin_lock_bh(&local->active_txq_lock[ac]); +-- local->schedule_round[ac]++; +-- spin_unlock_bh(&local->active_txq_lock[ac]); +-+ spin_lock_bh(&air_sched->lock); +-+ air_sched->schedule_pos = NULL; +-+ spin_unlock_bh(&air_sched->lock); +- } +- EXPORT_SYMBOL(ieee80211_txq_schedule_start); +- +diff --git a/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch b/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch +deleted file mode 100644 +index a47e29794c..0000000000 +--- a/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch ++++ /dev/null +@@ -1,398 +0,0 @@ +-From: Carl Huang +-Date: Thu, 3 Dec 2020 05:37:26 -0500 +-Subject: [PATCH] nl80211: add common API to configure SAR power limitations +- +-NL80211_CMD_SET_SAR_SPECS is added to configure SAR from +-user space. NL80211_ATTR_SAR_SPEC is used to pass the SAR +-power specification when used with NL80211_CMD_SET_SAR_SPECS. +- +-Wireless driver needs to register SAR type, supported frequency +-ranges to wiphy, so user space can query it. The index in +-frequency range is used to specify which sub band the power +-limitation applies to. The SAR type is for compatibility, so later +-other SAR mechanism can be implemented without breaking the user +-space SAR applications. +- +-Normal process is user space queries the SAR capability, and +-gets the index of supported frequency ranges and associates the +-power limitation with this index and sends to kernel. +- +-Here is an example of message send to kernel: +-8c 00 00 00 08 00 01 00 00 00 00 00 38 00 2b 81 +-08 00 01 00 00 00 00 00 2c 00 02 80 14 00 00 80 +-08 00 02 00 00 00 00 00 08 00 01 00 38 00 00 00 +-14 00 01 80 08 00 02 00 01 00 00 00 08 00 01 00 +-48 00 00 00 +- +-NL80211_CMD_SET_SAR_SPECS: 0x8c +-NL80211_ATTR_WIPHY: 0x01(phy idx is 0) +-NL80211_ATTR_SAR_SPEC: 0x812b (NLA_NESTED) +-NL80211_SAR_ATTR_TYPE: 0x00 (NL80211_SAR_TYPE_POWER) +-NL80211_SAR_ATTR_SPECS: 0x8002 (NLA_NESTED) +-freq range 0 power: 0x38 in 0.25dbm unit (14dbm) +-freq range 1 power: 0x48 in 0.25dbm unit (18dbm) +- +-Signed-off-by: Carl Huang +-Reviewed-by: Brian Norris +-Reviewed-by: Abhishek Kumar +-Link: https://lore.kernel.org/r/20201203103728.3034-2-cjhuang@codeaurora.org +-[minor edits, NLA parse cleanups] +-Signed-off-by: Johannes Berg +---- +- +---- a/include/net/cfg80211.h +-+++ b/include/net/cfg80211.h +-@@ -1737,6 +1737,54 @@ struct station_info { +- u8 connected_to_as; +- }; +- +-+/** +-+ * struct cfg80211_sar_sub_specs - sub specs limit +-+ * @power: power limitation in 0.25dbm +-+ * @freq_range_index: index the power limitation applies to +-+ */ +-+struct cfg80211_sar_sub_specs { +-+ s32 power; +-+ u32 freq_range_index; +-+}; +-+ +-+/** +-+ * struct cfg80211_sar_specs - sar limit specs +-+ * @type: it's set with power in 0.25dbm or other types +-+ * @num_sub_specs: number of sar sub specs +-+ * @sub_specs: memory to hold the sar sub specs +-+ */ +-+struct cfg80211_sar_specs { +-+ enum nl80211_sar_type type; +-+ u32 num_sub_specs; +-+ struct cfg80211_sar_sub_specs sub_specs[]; +-+}; +-+ +-+ +-+/** +-+ * @struct cfg80211_sar_chan_ranges - sar frequency ranges +-+ * @start_freq: start range edge frequency +-+ * @end_freq: end range edge frequency +-+ */ +-+struct cfg80211_sar_freq_ranges { +-+ u32 start_freq; +-+ u32 end_freq; +-+}; +-+ +-+/** +-+ * struct cfg80211_sar_capa - sar limit capability +-+ * @type: it's set via power in 0.25dbm or other types +-+ * @num_freq_ranges: number of frequency ranges +-+ * @freq_ranges: memory to hold the freq ranges. +-+ * +-+ * Note: WLAN driver may append new ranges or split an existing +-+ * range to small ones and then append them. +-+ */ +-+struct cfg80211_sar_capa { +-+ enum nl80211_sar_type type; +-+ u32 num_freq_ranges; +-+ const struct cfg80211_sar_freq_ranges *freq_ranges; +-+}; +-+ +- #if IS_ENABLED(CPTCFG_CFG80211) +- /** +- * cfg80211_get_station - retrieve information about a given station +-@@ -4259,6 +4307,8 @@ struct cfg80211_ops { +- struct cfg80211_tid_config *tid_conf); +- int (*reset_tid_config)(struct wiphy *wiphy, struct net_device *dev, +- const u8 *peer, u8 tids); +-+ int (*set_sar_specs)(struct wiphy *wiphy, +-+ struct cfg80211_sar_specs *sar); +- }; +- +- /* +-@@ -5030,6 +5080,8 @@ struct wiphy { +- +- u8 max_data_retry_count; +- +-+ const struct cfg80211_sar_capa *sar_capa; +-+ +- char priv[] __aligned(NETDEV_ALIGN); +- }; +- +---- a/net/wireless/nl80211.c +-+++ b/net/wireless/nl80211.c +-@@ -405,6 +405,18 @@ nl80211_unsol_bcast_probe_resp_policy[NL +- .len = IEEE80211_MAX_DATA_LEN } +- }; +- +-+static const struct nla_policy +-+sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = { +-+ [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_S32 }, +-+ [NL80211_SAR_ATTR_SPECS_RANGE_INDEX] = {.type = NLA_U32 }, +-+}; +-+ +-+static const struct nla_policy +-+sar_policy[NL80211_SAR_ATTR_MAX + 1] = { +-+ [NL80211_SAR_ATTR_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_SAR_TYPE), +-+ [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy), +-+}; +-+ +- static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { +- [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD }, +- [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, +-@@ -739,6 +751,7 @@ static const struct nla_policy nl80211_p +- [NL80211_ATTR_SAE_PWE] = +- NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK, +- NL80211_SAE_PWE_BOTH), +-+ [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy), +- [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT }, +- }; +- +-@@ -2117,6 +2130,56 @@ fail: +- return -ENOBUFS; +- } +- +-+static int +-+nl80211_put_sar_specs(struct cfg80211_registered_device *rdev, +-+ struct sk_buff *msg) +-+{ +-+ struct nlattr *sar_capa, *specs, *sub_freq_range; +-+ u8 num_freq_ranges; +-+ int i; +-+ +-+ if (!rdev->wiphy.sar_capa) +-+ return 0; +-+ +-+ num_freq_ranges = rdev->wiphy.sar_capa->num_freq_ranges; +-+ +-+ sar_capa = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC); +-+ if (!sar_capa) +-+ return -ENOSPC; +-+ +-+ if (nla_put_u32(msg, NL80211_SAR_ATTR_TYPE, rdev->wiphy.sar_capa->type)) +-+ goto fail; +-+ +-+ specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS); +-+ if (!specs) +-+ goto fail; +-+ +-+ /* report supported freq_ranges */ +-+ for (i = 0; i < num_freq_ranges; i++) { +-+ sub_freq_range = nla_nest_start(msg, i + 1); +-+ if (!sub_freq_range) +-+ goto fail; +-+ +-+ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ, +-+ rdev->wiphy.sar_capa->freq_ranges[i].start_freq)) +-+ goto fail; +-+ +-+ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ, +-+ rdev->wiphy.sar_capa->freq_ranges[i].end_freq)) +-+ goto fail; +-+ +-+ nla_nest_end(msg, sub_freq_range); +-+ } +-+ +-+ nla_nest_end(msg, specs); +-+ nla_nest_end(msg, sar_capa); +-+ +-+ return 0; +-+fail: +-+ nla_nest_cancel(msg, sar_capa); +-+ return -ENOBUFS; +-+} +-+ +- struct nl80211_dump_wiphy_state { +- s64 filter_wiphy; +- long start; +-@@ -2366,6 +2429,8 @@ static int nl80211_send_wiphy(struct cfg +- CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST); +- CMD(update_connect_params, UPDATE_CONNECT_PARAMS); +- CMD(update_ft_ies, UPDATE_FT_IES); +-+ if (rdev->wiphy.sar_capa) +-+ CMD(set_sar_specs, SET_SAR_SPECS); +- } +- #undef CMD +- +-@@ -2691,6 +2756,11 @@ static int nl80211_send_wiphy(struct cfg +- +- if (nl80211_put_tid_config_support(rdev, msg)) +- goto nla_put_failure; +-+ state->split_start++; +-+ break; +-+ case 16: +-+ if (nl80211_put_sar_specs(rdev, msg)) +-+ goto nla_put_failure; +- +- /* done */ +- state->split_start = 0; +-@@ -14712,6 +14782,111 @@ static void nl80211_post_doit(__genl_con +- } +- } +- +-+static int nl80211_set_sar_sub_specs(struct cfg80211_registered_device *rdev, +-+ struct cfg80211_sar_specs *sar_specs, +-+ struct nlattr *spec[], int index) +-+{ +-+ u32 range_index, i; +-+ +-+ if (!sar_specs || !spec) +-+ return -EINVAL; +-+ +-+ if (!spec[NL80211_SAR_ATTR_SPECS_POWER] || +-+ !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]) +-+ return -EINVAL; +-+ +-+ range_index = nla_get_u32(spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]); +-+ +-+ /* check if range_index exceeds num_freq_ranges */ +-+ if (range_index >= rdev->wiphy.sar_capa->num_freq_ranges) +-+ return -EINVAL; +-+ +-+ /* check if range_index duplicates */ +-+ for (i = 0; i < index; i++) { +-+ if (sar_specs->sub_specs[i].freq_range_index == range_index) +-+ return -EINVAL; +-+ } +-+ +-+ sar_specs->sub_specs[index].power = +-+ nla_get_s32(spec[NL80211_SAR_ATTR_SPECS_POWER]); +-+ +-+ sar_specs->sub_specs[index].freq_range_index = range_index; +-+ +-+ return 0; +-+} +-+ +-+static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info) +-+{ +-+ struct cfg80211_registered_device *rdev = info->user_ptr[0]; +-+ struct nlattr *spec[NL80211_SAR_ATTR_SPECS_MAX + 1]; +-+ struct nlattr *tb[NL80211_SAR_ATTR_MAX + 1]; +-+ struct cfg80211_sar_specs *sar_spec; +-+ enum nl80211_sar_type type; +-+ struct nlattr *spec_list; +-+ u32 specs; +-+ int rem, err; +-+ +-+ if (!rdev->wiphy.sar_capa || !rdev->ops->set_sar_specs) +-+ return -EOPNOTSUPP; +-+ +-+ if (!info->attrs[NL80211_ATTR_SAR_SPEC]) +-+ return -EINVAL; +-+ +-+ nla_parse_nested(tb, NL80211_SAR_ATTR_MAX, +-+ info->attrs[NL80211_ATTR_SAR_SPEC], +-+ NULL, NULL); +-+ +-+ if (!tb[NL80211_SAR_ATTR_TYPE] || !tb[NL80211_SAR_ATTR_SPECS]) +-+ return -EINVAL; +-+ +-+ type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]); +-+ if (type != rdev->wiphy.sar_capa->type) +-+ return -EINVAL; +-+ +-+ specs = 0; +-+ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) +-+ specs++; +-+ +-+ if (specs > rdev->wiphy.sar_capa->num_freq_ranges) +-+ return -EINVAL; +-+ +-+ sar_spec = kzalloc(sizeof(*sar_spec) + +-+ specs * sizeof(struct cfg80211_sar_sub_specs), +-+ GFP_KERNEL); +-+ if (!sar_spec) +-+ return -ENOMEM; +-+ +-+ sar_spec->type = type; +-+ specs = 0; +-+ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) { +-+ nla_parse_nested(spec, NL80211_SAR_ATTR_SPECS_MAX, +-+ spec_list, NULL, NULL); +-+ +-+ switch (type) { +-+ case NL80211_SAR_TYPE_POWER: +-+ if (nl80211_set_sar_sub_specs(rdev, sar_spec, +-+ spec, specs)) { +-+ err = -EINVAL; +-+ goto error; +-+ } +-+ break; +-+ default: +-+ err = -EINVAL; +-+ goto error; +-+ } +-+ specs++; +-+ } +-+ +-+ sar_spec->num_sub_specs = specs; +-+ +-+ rdev->cur_cmd_info = info; +-+ err = rdev_set_sar_specs(rdev, sar_spec); +-+ rdev->cur_cmd_info = NULL; +-+error: +-+ kfree(sar_spec); +-+ return err; +-+} +-+ +- static __genl_const struct genl_ops nl80211_ops[] = { +- { +- .cmd = NL80211_CMD_GET_WIPHY, +-@@ -15575,6 +15750,14 @@ static const struct genl_small_ops nl802 +- .internal_flags = NL80211_FLAG_NEED_NETDEV | +- NL80211_FLAG_NEED_RTNL, +- }, +-+ { +-+ .cmd = NL80211_CMD_SET_SAR_SPECS, +-+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, +-+ .doit = nl80211_set_sar_specs, +-+ .flags = GENL_UNS_ADMIN_PERM, +-+ .internal_flags = NL80211_FLAG_NEED_WIPHY | +-+ NL80211_FLAG_NEED_RTNL, +-+ }, +- }; +- +- static struct genl_family nl80211_fam __genl_ro_after_init = { +---- a/net/wireless/rdev-ops.h +-+++ b/net/wireless/rdev-ops.h +-@@ -1356,4 +1356,16 @@ static inline int rdev_reset_tid_config( +- return ret; +- } +- +-+static inline int rdev_set_sar_specs(struct cfg80211_registered_device *rdev, +-+ struct cfg80211_sar_specs *sar) +-+{ +-+ int ret; +-+ +-+ trace_rdev_set_sar_specs(&rdev->wiphy, sar); +-+ ret = rdev->ops->set_sar_specs(&rdev->wiphy, sar); +-+ trace_rdev_return_int(&rdev->wiphy, ret); +-+ +-+ return ret; +-+} +-+ +- #endif /* __CFG80211_RDEV_OPS */ +---- a/net/wireless/trace.h +-+++ b/net/wireless/trace.h +-@@ -3551,6 +3551,25 @@ TRACE_EVENT(rdev_reset_tid_config, +- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", tids: 0x%x", +- WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->tids) +- ); +-+ +-+TRACE_EVENT(rdev_set_sar_specs, +-+ TP_PROTO(struct wiphy *wiphy, struct cfg80211_sar_specs *sar), +-+ TP_ARGS(wiphy, sar), +-+ TP_STRUCT__entry( +-+ WIPHY_ENTRY +-+ __field(u16, type) +-+ __field(u16, num) +-+ ), +-+ TP_fast_assign( +-+ WIPHY_ASSIGN; +-+ __entry->type = sar->type; +-+ __entry->num = sar->num_sub_specs; +-+ +-+ ), +-+ TP_printk(WIPHY_PR_FMT ", Set type:%d, num_specs:%d", +-+ WIPHY_PR_ARG, __entry->type, __entry->num) +-+); +-+ +- #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ +- +- #undef TRACE_INCLUDE_PATH +diff --git a/package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch b/package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch +deleted file mode 100644 +index c351bc812a..0000000000 +--- a/package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch ++++ /dev/null +@@ -1,51 +0,0 @@ +-From: Carl Huang +-Date: Thu, 3 Dec 2020 05:37:27 -0500 +-Subject: [PATCH] mac80211: add ieee80211_set_sar_specs +- +-This change registers ieee80211_set_sar_specs to +-mac80211_config_ops, so cfg80211 can call it. +- +-Signed-off-by: Carl Huang +-Reviewed-by: Brian Norris +-Reviewed-by: Abhishek Kumar +-Link: https://lore.kernel.org/r/20201203103728.3034-3-cjhuang@codeaurora.org +-Signed-off-by: Johannes Berg +---- +- +---- a/include/net/mac80211.h +-+++ b/include/net/mac80211.h +-@@ -4207,6 +4207,8 @@ struct ieee80211_ops { +- struct ieee80211_vif *vif); +- void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +- struct ieee80211_sta *sta, bool enabled); +-+ int (*set_sar_specs)(struct ieee80211_hw *hw, +-+ const struct cfg80211_sar_specs *sar); +- void (*sta_set_decap_offload)(struct ieee80211_hw *hw, +- struct ieee80211_vif *vif, +- struct ieee80211_sta *sta, bool enabled); +---- a/net/mac80211/cfg.c +-+++ b/net/mac80211/cfg.c +-@@ -4136,6 +4136,17 @@ static int ieee80211_reset_tid_config(st +- return ret; +- } +- +-+static int ieee80211_set_sar_specs(struct wiphy *wiphy, +-+ struct cfg80211_sar_specs *sar) +-+{ +-+ struct ieee80211_local *local = wiphy_priv(wiphy); +-+ +-+ if (!local->ops->set_sar_specs) +-+ return -EOPNOTSUPP; +-+ +-+ return local->ops->set_sar_specs(&local->hw, sar); +-+} +-+ +- const struct cfg80211_ops mac80211_config_ops = { +- .add_virtual_intf = ieee80211_add_iface, +- .del_virtual_intf = ieee80211_del_iface, +-@@ -4239,4 +4250,5 @@ const struct cfg80211_ops mac80211_confi +- .probe_mesh_link = ieee80211_probe_mesh_link, +- .set_tid_config = ieee80211_set_tid_config, +- .reset_tid_config = ieee80211_reset_tid_config, +-+ .set_sar_specs = ieee80211_set_sar_specs, +- }; +diff --git a/package/kernel/mac80211/patches/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch b/package/kernel/mac80211/patches/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch +deleted file mode 100644 +index c2cc16cd48..0000000000 +--- a/package/kernel/mac80211/patches/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch ++++ /dev/null +@@ -1,26 +0,0 @@ +-From: Ryder Lee +-Date: Fri, 18 Jun 2021 04:38:59 +0800 +-Subject: [PATCH] mac80211: check per vif offload_flags in Tx path +- +-offload_flags has been introduced to indicate encap status of each interface. +-An interface can encap offload at runtime, or if it has some extra limitations +-it can simply override the flags, so it's more flexible to check offload_flags +-in Tx path. +- +-Signed-off-by: Ryder Lee +-Link: https://lore.kernel.org/r/177785418cf407808bf3a44760302d0647076990.1623961575.git.ryder.lee@mediatek.com +-Signed-off-by: Johannes Berg +---- +- +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -3331,6 +3331,9 @@ static bool ieee80211_amsdu_aggregate(st +- if (!ieee80211_hw_check(&local->hw, TX_AMSDU)) +- return false; +- +-+ if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) +-+ return false; +-+ +- if (skb_is_gso(skb)) +- return false; +- +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 +index 36b705de12..0000000000 +--- a/package/kernel/mac80211/patches/subsys/387-nl80211-add-support-for-BSS-coloring.patch ++++ /dev/null +@@ -1,485 +0,0 @@ +-From: John Crispin +-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 +-Signed-off-by: Lorenzo Bianconi +-Signed-off-by: John Crispin +-Link: https://lore.kernel.org/r/500b3582aec8fe2c42ef46f3117b148cb7cbceb5.1625247619.git.lorenzo@kernel.org +-[remove unnecessary NULL initialisation] +-Signed-off-by: Johannes Berg +---- +- +---- a/include/net/cfg80211.h +-+++ b/include/net/cfg80211.h +-@@ -1252,6 +1252,27 @@ struct cfg80211_csa_settings { +- #define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 +- +- /** +-+ * 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 +-@@ -3979,6 +4000,8 @@ struct mgmt_frame_regs { +- * This callback may sleep. +- * @reset_tid_config: Reset TID specific configuration for the peer, for the +- * given TIDs. This callback may sleep. +-+ * +-+ * @color_change: Initiate a color change. +- */ +- struct cfg80211_ops { +- int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); +-@@ -4309,6 +4332,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); +- }; +- +- /* +-@@ -8094,4 +8120,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, +-@@ -5950,6 +5989,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. +- */ +-@@ -6014,6 +6056,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 +-@@ -753,6 +753,10 @@ static const struct nla_policy nl80211_p +- NL80211_SAE_PWE_BOTH), +- [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy), +- [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT }, +-+ [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 */ +-@@ -14677,6 +14681,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, ¶ms.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, ¶ms.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, ¶ms); +-+ 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 +-@@ -15758,6 +15862,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 = { +-@@ -17384,6 +17496,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 +-@@ -3570,6 +3570,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 +index 0a3118545f..0000000000 +--- a/package/kernel/mac80211/patches/subsys/388-mac80211-add-support-for-BSS-color-change.patch ++++ /dev/null +@@ -1,524 +0,0 @@ +-From: John Crispin +-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 +-Signed-off-by: Lorenzo Bianconi +-Signed-off-by: John Crispin +-Link: https://lore.kernel.org/r/057c1e67b82bee561ea44ce6a45a8462d3da6995.1625247619.git.lorenzo@kernel.org +-Signed-off-by: Johannes Berg +---- +- +---- a/include/net/mac80211.h +-+++ b/include/net/mac80211.h +-@@ -1710,6 +1710,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; +-@@ -1738,6 +1742,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 *)); +- }; +-@@ -4982,6 +4989,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. +-@@ -6726,6 +6743,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 +-@@ -827,9 +827,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; +- +-@@ -849,6 +851,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) +-@@ -954,7 +958,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; +-@@ -1003,6 +1008,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 */ +-@@ -1019,7 +1027,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; +-@@ -1176,7 +1184,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, ¶ms->beacon, NULL); +-+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon, NULL, NULL); +- if (err < 0) +- goto error; +- changed |= err; +-@@ -1231,17 +1239,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); +-@@ -3174,7 +3182,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; +- +-@@ -3340,7 +3348,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, ¶ms->beacon_csa, &csa); +-+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa, &csa, NULL); +- if (err < 0) { +- kfree(sdata->u.ap.next_beacon); +- return err; +-@@ -3428,6 +3436,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) +-@@ -3496,6 +3513,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); +-@@ -4147,6 +4168,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(¶ms->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, ¶ms->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, +-@@ -4251,4 +4462,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; +-@@ -932,6 +938,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 */ +- +-@@ -1900,6 +1908,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 +-@@ -465,6 +465,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); +- +-@@ -1639,6 +1640,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 +-@@ -4790,11 +4790,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: +-@@ -4814,21 +4814,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(); +- } +-@@ -5038,6 +5044,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 +index 369619938e..0000000000 +--- a/package/kernel/mac80211/patches/subsys/389-ieee80211-add-TWT-element-definitions.patch ++++ /dev/null +@@ -1,112 +0,0 @@ +-From: Lorenzo Bianconi +-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 +-Signed-off-by: Lorenzo Bianconi +-Link: https://lore.kernel.org/r/71d8b581fe4b5abc5b92f8d77ac2de3e2f7591b6.1629741512.git.lorenzo@kernel.org +-Signed-off-by: Johannes Berg +---- +- +---- 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; +-@@ -2880,6 +2926,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, +-@@ -2948,6 +2995,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, +- }; +-@@ -3021,6 +3069,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 +index c32861a78f..0000000000 +--- a/package/kernel/mac80211/patches/subsys/390-mac80211-introduce-individual-TWT-support-in-AP-mode.patch ++++ /dev/null +@@ -1,576 +0,0 @@ +-From: Lorenzo Bianconi +-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 +-Signed-off-by: Lorenzo Bianconi +-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 +---- +- +---- a/include/net/mac80211.h +-+++ b/include/net/mac80211.h +-@@ -4219,6 +4219,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 +-@@ -1429,4 +1429,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 +-@@ -954,6 +954,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; +-@@ -2093,6 +2094,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 +-@@ -563,6 +563,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); +-@@ -1070,6 +1071,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; +-@@ -1442,6 +1444,24 @@ static void ieee80211_if_setup_no_queue( +- #endif +- } +- +-+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 = +-@@ -1519,6 +1539,16 @@ static void ieee80211_iface_work(struct +- 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); +-@@ -1574,6 +1604,12 @@ static void ieee80211_iface_work(struct +- kfree_skb(skb); +- } +- +-+ /* process status queue */ +-+ while ((skb = skb_dequeue(&sdata->status_queue))) { +-+ ieee80211_iface_process_status(sdata, skb); +-+ kfree_skb(skb); +-+ } +-+ +- /* then other type-dependent work */ +- switch (sdata->vif.type) { +- case NL80211_IFTYPE_STATION: +-@@ -1637,6 +1673,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 +-@@ -3210,6 +3210,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) +- { +-@@ -3489,6 +3551,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 +- #include +- #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 +-@@ -2804,6 +2804,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 +diff --git a/package/kernel/mac80211/patches/subsys/391-wireless-align-some-HE-capabilities-with-the-spec.patch b/package/kernel/mac80211/patches/subsys/391-wireless-align-some-HE-capabilities-with-the-spec.patch +deleted file mode 100644 +index eb32c49890..0000000000 +--- a/package/kernel/mac80211/patches/subsys/391-wireless-align-some-HE-capabilities-with-the-spec.patch ++++ /dev/null +@@ -1,196 +0,0 @@ +-From: Johannes Berg +-Date: Fri, 9 Apr 2021 12:40:17 +0300 +-Subject: [PATCH] wireless: align some HE capabilities with the spec +- +-Some names were changed, align that with the spec as of +-802.11ax-D6.1. +- +-Signed-off-by: Luca Coelho +-Link: https://lore.kernel.org/r/iwlwifi.20210409123755.b1e5fbab0d8c.I3eb6076cb0714ec6aec6b8f9dee613ce4a05d825@changeid +-Signed-off-by: Johannes Berg +---- +- +---- a/drivers/net/wireless/ath/ath11k/mac.c +-+++ b/drivers/net/wireless/ath/ath11k/mac.c +-@@ -3627,7 +3627,7 @@ ath11k_mac_filter_he_cap_mesh(struct iee +- IEEE80211_HE_MAC_CAP4_BQR; +- he_cap_elem->mac_cap_info[4] &= ~m; +- +-- m = IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION | +-+ m = IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION | +- IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU | +- IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING | +- IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX; +-@@ -3637,7 +3637,7 @@ ath11k_mac_filter_he_cap_mesh(struct iee +- IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO; +- he_cap_elem->phy_cap_info[2] &= ~m; +- +-- m = IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA | +-+ m = IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU | +- IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK | +- IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK; +- he_cap_elem->phy_cap_info[3] &= ~m; +-@@ -3649,13 +3649,13 @@ ath11k_mac_filter_he_cap_mesh(struct iee +- he_cap_elem->phy_cap_info[5] &= ~m; +- +- m = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | +-- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB | +-+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB | +- IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB | +- IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO; +- he_cap_elem->phy_cap_info[6] &= ~m; +- +-- m = IEEE80211_HE_PHY_CAP7_SRP_BASED_SR | +-- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR | +-+ m = IEEE80211_HE_PHY_CAP7_PSR_BASED_SR | +-+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP | +- IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ | +- IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ; +- he_cap_elem->phy_cap_info[7] &= ~m; +---- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +-+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c +-@@ -307,8 +307,8 @@ mt7915_set_stream_he_txbf_caps(struct ie +- IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK; +- elem->phy_cap_info[5] &= ~c; +- +-- c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB | +-- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB; +-+ c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | +-+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB; +- elem->phy_cap_info[6] &= ~c; +- +- elem->phy_cap_info[7] &= ~IEEE80211_HE_PHY_CAP7_MAX_NC_MASK; +-@@ -348,8 +348,8 @@ mt7915_set_stream_he_txbf_caps(struct ie +- c = (nss - 1) | (max_t(int, mcs->tx_mcs_160, 1) << 3); +- elem->phy_cap_info[5] |= c; +- +-- c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB | +-- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB; +-+ c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | +-+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB; +- elem->phy_cap_info[6] |= c; +- } +- +-@@ -484,7 +484,7 @@ mt7915_init_he_caps(struct mt7915_phy *p +- IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE | +- IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT; +- he_cap_elem->phy_cap_info[7] |= +-- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR | +-+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP | +- IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; +- he_cap_elem->phy_cap_info[8] |= +- IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G | +---- a/include/linux/ieee80211.h +-+++ b/include/linux/ieee80211.h +-@@ -2065,7 +2065,7 @@ int ieee80211_get_vht_max_nss(struct iee +- #define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG 0x01 +- #define IEEE80211_HE_MAC_CAP4_QTP 0x02 +- #define IEEE80211_HE_MAC_CAP4_BQR 0x04 +--#define IEEE80211_HE_MAC_CAP4_SRP_RESP 0x08 +-+#define IEEE80211_HE_MAC_CAP4_PSR_RESP 0x08 +- #define IEEE80211_HE_MAC_CAP4_NDP_FB_REP 0x10 +- #define IEEE80211_HE_MAC_CAP4_OPS 0x20 +- #define IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU 0x40 +-@@ -2076,7 +2076,7 @@ int ieee80211_get_vht_max_nss(struct iee +- +- #define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 0x01 +- #define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B41 0x02 +--#define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION 0x04 +-+#define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION 0x04 +- #define IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU 0x08 +- #define IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX 0x10 +- #define IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS 0x20 +-@@ -2134,7 +2134,7 @@ int ieee80211_get_vht_max_nss(struct iee +- #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK 0x18 +- #define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 0x00 +- #define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_2 0x20 +--#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40 +-+#define IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU 0x40 +- #define IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER 0x80 +- +- #define IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE 0x01 +-@@ -2181,15 +2181,15 @@ int ieee80211_get_vht_max_nss(struct iee +- +- #define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU 0x01 +- #define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU 0x02 +--#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB 0x04 +--#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB 0x08 +-+#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB 0x04 +-+#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB 0x08 +- #define IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB 0x10 +- #define IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE 0x20 +- #define IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO 0x40 +- #define IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT 0x80 +- +--#define IEEE80211_HE_PHY_CAP7_SRP_BASED_SR 0x01 +--#define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR 0x02 +-+#define IEEE80211_HE_PHY_CAP7_PSR_BASED_SR 0x01 +-+#define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP 0x02 +- #define IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI 0x04 +- #define IEEE80211_HE_PHY_CAP7_MAX_NC_1 0x08 +- #define IEEE80211_HE_PHY_CAP7_MAX_NC_2 0x10 +---- a/net/mac80211/debugfs_sta.c +-+++ b/net/mac80211/debugfs_sta.c +-@@ -732,15 +732,15 @@ static ssize_t sta_he_capa_read(struct f +- PFLAG(MAC, 4, BSRP_BQRP_A_MPDU_AGG, "BSRP-BQRP-A-MPDU-AGG"); +- PFLAG(MAC, 4, QTP, "QTP"); +- PFLAG(MAC, 4, BQR, "BQR"); +-- PFLAG(MAC, 4, SRP_RESP, "SRP-RESP"); +-+ PFLAG(MAC, 4, PSR_RESP, "PSR-RESP"); +- PFLAG(MAC, 4, NDP_FB_REP, "NDP-FB-REP"); +- PFLAG(MAC, 4, OPS, "OPS"); +- PFLAG(MAC, 4, AMDSU_IN_AMPDU, "AMSDU-IN-AMPDU"); +- +- PRINT("MULTI-TID-AGG-TX-QOS-%d", ((cap[5] << 1) | (cap[4] >> 7)) & 0x7); +- +-- PFLAG(MAC, 5, SUBCHAN_SELECVITE_TRANSMISSION, +-- "SUBCHAN-SELECVITE-TRANSMISSION"); +-+ PFLAG(MAC, 5, SUBCHAN_SELECTIVE_TRANSMISSION, +-+ "SUBCHAN-SELECTIVE-TRANSMISSION"); +- PFLAG(MAC, 5, UL_2x996_TONE_RU, "UL-2x996-TONE-RU"); +- PFLAG(MAC, 5, OM_CTRL_UL_MU_DATA_DIS_RX, "OM-CTRL-UL-MU-DATA-DIS-RX"); +- PFLAG(MAC, 5, HE_DYNAMIC_SM_PS, "HE-DYNAMIC-SM-PS"); +-@@ -832,8 +832,8 @@ static ssize_t sta_he_capa_read(struct f +- +- PFLAG(PHY, 3, DCM_MAX_RX_NSS_1, "DCM-MAX-RX-NSS-1"); +- PFLAG(PHY, 3, DCM_MAX_RX_NSS_2, "DCM-MAX-RX-NSS-2"); +-- PFLAG(PHY, 3, RX_HE_MU_PPDU_FROM_NON_AP_STA, +-- "RX-HE-MU-PPDU-FROM-NON-AP-STA"); +-+ PFLAG(PHY, 3, RX_PARTIAL_BW_SU_IN_20MHZ_MU, +-+ "RX-PARTIAL-BW-SU-IN-20MHZ-MU"); +- PFLAG(PHY, 3, SU_BEAMFORMER, "SU-BEAMFORMER"); +- +- PFLAG(PHY, 4, SU_BEAMFORMEE, "SU-BEAMFORMEE"); +-@@ -853,16 +853,17 @@ static ssize_t sta_he_capa_read(struct f +- +- PFLAG(PHY, 6, CODEBOOK_SIZE_42_SU, "CODEBOOK-SIZE-42-SU"); +- PFLAG(PHY, 6, CODEBOOK_SIZE_75_MU, "CODEBOOK-SIZE-75-MU"); +-- PFLAG(PHY, 6, TRIG_SU_BEAMFORMER_FB, "TRIG-SU-BEAMFORMER-FB"); +-- PFLAG(PHY, 6, TRIG_MU_BEAMFORMER_FB, "TRIG-MU-BEAMFORMER-FB"); +-+ PFLAG(PHY, 6, TRIG_SU_BEAMFORMING_FB, "TRIG-SU-BEAMFORMING-FB"); +-+ PFLAG(PHY, 6, TRIG_MU_BEAMFORMING_PARTIAL_BW_FB, +-+ "MU-BEAMFORMING-PARTIAL-BW-FB"); +- PFLAG(PHY, 6, TRIG_CQI_FB, "TRIG-CQI-FB"); +- PFLAG(PHY, 6, PARTIAL_BW_EXT_RANGE, "PARTIAL-BW-EXT-RANGE"); +- PFLAG(PHY, 6, PARTIAL_BANDWIDTH_DL_MUMIMO, +- "PARTIAL-BANDWIDTH-DL-MUMIMO"); +- PFLAG(PHY, 6, PPE_THRESHOLD_PRESENT, "PPE-THRESHOLD-PRESENT"); +- +-- PFLAG(PHY, 7, SRP_BASED_SR, "SRP-BASED-SR"); +-- PFLAG(PHY, 7, POWER_BOOST_FACTOR_AR, "POWER-BOOST-FACTOR-AR"); +-+ PFLAG(PHY, 7, PSR_BASED_SR, "PSR-BASED-SR"); +-+ PFLAG(PHY, 7, POWER_BOOST_FACTOR_SUPP, "POWER-BOOST-FACTOR-SUPP"); +- PFLAG(PHY, 7, HE_SU_MU_PPDU_4XLTF_AND_08_US_GI, +- "HE-SU-MU-PPDU-4XLTF-AND-08-US-GI"); +- PFLAG_RANGE(PHY, 7, MAX_NC, 0, 1, 1, "MAX-NC-%d"); +---- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +-+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +-@@ -631,7 +631,7 @@ static struct ieee80211_sband_iftype_dat +- .phy_cap_info[6] = +- IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, +- .phy_cap_info[7] = +-- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR | +-+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP | +- IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI | +- IEEE80211_HE_PHY_CAP7_MAX_NC_1, +- .phy_cap_info[8] = +diff --git a/package/kernel/mac80211/patches/subsys/392-wireless-fix-spelling-of-A-MSDU-in-HE-capabilities.patch b/package/kernel/mac80211/patches/subsys/392-wireless-fix-spelling-of-A-MSDU-in-HE-capabilities.patch +deleted file mode 100644 +index 0bd01126f7..0000000000 +--- a/package/kernel/mac80211/patches/subsys/392-wireless-fix-spelling-of-A-MSDU-in-HE-capabilities.patch ++++ /dev/null +@@ -1,113 +0,0 @@ +-From: Johannes Berg +-Date: Fri, 9 Apr 2021 12:40:24 +0300 +-Subject: [PATCH] wireless: fix spelling of A-MSDU in HE capabilities +- +-In the HE capabilities, spell A-MSDU correctly, not "A-MDSU". +- +-Signed-off-by: Luca Coelho +-Link: https://lore.kernel.org/r/iwlwifi.20210409123755.9e6ff1af1181.If6868bc6902ccd9a95c74c78f716c4b41473ef14@changeid +-Signed-off-by: Johannes Berg +---- +- +---- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +-+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +-@@ -598,7 +598,7 @@ static struct ieee80211_sband_iftype_dat +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +- .mac_cap_info[4] = +-- IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU | +-+ IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU | +- IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39, +- .mac_cap_info[5] = +- IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 | +-@@ -682,7 +682,7 @@ static struct ieee80211_sband_iftype_dat +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +- .mac_cap_info[4] = +-- IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU, +-+ IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU, +- .mac_cap_info[5] = +- IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU, +- .phy_cap_info[0] = +---- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +-+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c +-@@ -427,7 +427,7 @@ mt7915_init_he_caps(struct mt7915_phy *p +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED; +- he_cap_elem->mac_cap_info[4] = +-- IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU; +-+ IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU; +- +- if (band == NL80211_BAND_2GHZ) +- he_cap_elem->phy_cap_info[0] = +---- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +-+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +-@@ -1353,7 +1353,7 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *sk +- if (elem->mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL) +- cap |= STA_REC_HE_CAP_OM; +- +-- if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU) +-+ if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU) +- cap |= STA_REC_HE_CAP_AMSDU_IN_AMPDU; +- +- if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR) +---- a/include/linux/ieee80211.h +-+++ b/include/linux/ieee80211.h +-@@ -2068,7 +2068,7 @@ int ieee80211_get_vht_max_nss(struct iee +- #define IEEE80211_HE_MAC_CAP4_PSR_RESP 0x08 +- #define IEEE80211_HE_MAC_CAP4_NDP_FB_REP 0x10 +- #define IEEE80211_HE_MAC_CAP4_OPS 0x20 +--#define IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU 0x40 +-+#define IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU 0x40 +- /* Multi TID agg TX is split between byte #4 and #5 +- * The value is a combination of B39,B40,B41 +- */ +---- a/net/mac80211/debugfs_sta.c +-+++ b/net/mac80211/debugfs_sta.c +-@@ -735,7 +735,7 @@ static ssize_t sta_he_capa_read(struct f +- PFLAG(MAC, 4, PSR_RESP, "PSR-RESP"); +- PFLAG(MAC, 4, NDP_FB_REP, "NDP-FB-REP"); +- PFLAG(MAC, 4, OPS, "OPS"); +-- PFLAG(MAC, 4, AMDSU_IN_AMPDU, "AMSDU-IN-AMPDU"); +-+ PFLAG(MAC, 4, AMSDU_IN_AMPDU, "AMSDU-IN-AMPDU"); +- +- PRINT("MULTI-TID-AGG-TX-QOS-%d", ((cap[5] << 1) | (cap[4] >> 7)) & 0x7); +- +---- a/drivers/net/wireless/mac80211_hwsim.c +-+++ b/drivers/net/wireless/mac80211_hwsim.c +-@@ -2748,7 +2748,7 @@ static const struct ieee80211_sband_ifty +- .mac_cap_info[3] = +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +-- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU, +-+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU, +- .phy_cap_info[1] = +- IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK | +- IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A | +-@@ -2792,7 +2792,7 @@ static const struct ieee80211_sband_ifty +- .mac_cap_info[3] = +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +-- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU, +-+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU, +- .phy_cap_info[1] = +- IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK | +- IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A | +-@@ -2838,7 +2838,7 @@ static const struct ieee80211_sband_ifty +- .mac_cap_info[3] = +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +-- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU, +-+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU, +- .phy_cap_info[0] = +- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | +- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G | +-@@ -2886,7 +2886,7 @@ static const struct ieee80211_sband_ifty +- .mac_cap_info[3] = +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +-- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU, +-+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU, +- .phy_cap_info[0] = +- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | +- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G | +diff --git a/package/kernel/mac80211/patches/subsys/393-wireless-align-HE-capabilities-A-MPDU-Length-Exponen.patch b/package/kernel/mac80211/patches/subsys/393-wireless-align-HE-capabilities-A-MPDU-Length-Exponen.patch +deleted file mode 100644 +index 42b71df9d1..0000000000 +--- a/package/kernel/mac80211/patches/subsys/393-wireless-align-HE-capabilities-A-MPDU-Length-Exponen.patch ++++ /dev/null +@@ -1,148 +0,0 @@ +-From: Johannes Berg +-Date: Fri, 9 Apr 2021 12:40:20 +0300 +-Subject: [PATCH] wireless: align HE capabilities A-MPDU Length Exponent +- Extension +- +-The A-MPDU length exponent extension is defined differently in +-802.11ax D6.1, align with that. +- +-Signed-off-by: Luca Coelho +-Link: https://lore.kernel.org/r/iwlwifi.20210409123755.c2a257d3e2df.I3455245d388c52c61dace7e7958dbed7e807cfb6@changeid +-Signed-off-by: Johannes Berg +---- +- +---- a/drivers/net/wireless/ath/ath11k/mac.c +-+++ b/drivers/net/wireless/ath/ath11k/mac.c +-@@ -1290,9 +1290,8 @@ static void ath11k_peer_assoc_h_he(struc +- * request, then use MAX_AMPDU_LEN_FACTOR as 16 to calculate max_ampdu +- * length. +- */ +-- ampdu_factor = (he_cap->he_cap_elem.mac_cap_info[3] & +-- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) >> +-- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHIFT; +-+ ampdu_factor = u8_get_bits(he_cap->he_cap_elem.mac_cap_info[3], +-+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK); +- +- if (ampdu_factor) { +- if (sta->vht_cap.vht_supported) +---- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +-+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +-@@ -596,7 +596,7 @@ static struct ieee80211_sband_iftype_dat +- IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP, +- .mac_cap_info[3] = +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +-- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +-+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2, +- .mac_cap_info[4] = +- IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU | +- IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39, +-@@ -680,7 +680,7 @@ static struct ieee80211_sband_iftype_dat +- IEEE80211_HE_MAC_CAP2_BSR, +- .mac_cap_info[3] = +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +-- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +-+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2, +- .mac_cap_info[4] = +- IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU, +- .mac_cap_info[5] = +---- a/drivers/net/wireless/mac80211_hwsim.c +-+++ b/drivers/net/wireless/mac80211_hwsim.c +-@@ -2747,7 +2747,7 @@ static const struct ieee80211_sband_ifty +- IEEE80211_HE_MAC_CAP2_ACK_EN, +- .mac_cap_info[3] = +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +-- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +-+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3, +- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU, +- .phy_cap_info[1] = +- IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK | +-@@ -2791,7 +2791,7 @@ static const struct ieee80211_sband_ifty +- IEEE80211_HE_MAC_CAP2_ACK_EN, +- .mac_cap_info[3] = +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +-- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +-+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3, +- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU, +- .phy_cap_info[1] = +- IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK | +-@@ -2837,7 +2837,7 @@ static const struct ieee80211_sband_ifty +- IEEE80211_HE_MAC_CAP2_ACK_EN, +- .mac_cap_info[3] = +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +-- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +-+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3, +- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU, +- .phy_cap_info[0] = +- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | +-@@ -2885,7 +2885,7 @@ static const struct ieee80211_sband_ifty +- IEEE80211_HE_MAC_CAP2_ACK_EN, +- .mac_cap_info[3] = +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +-- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, +-+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3, +- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU, +- .phy_cap_info[0] = +- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | +---- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +-+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c +-@@ -425,7 +425,7 @@ mt7915_init_he_caps(struct mt7915_phy *p +- IEEE80211_HE_MAC_CAP0_HTC_HE; +- he_cap_elem->mac_cap_info[3] = +- IEEE80211_HE_MAC_CAP3_OMI_CONTROL | +-- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED; +-+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3; +- he_cap_elem->mac_cap_info[4] = +- IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU; +- +---- a/include/linux/ieee80211.h +-+++ b/include/linux/ieee80211.h +-@@ -2051,17 +2051,15 @@ int ieee80211_get_vht_max_nss(struct iee +- * A-MDPU Length Exponent field in the HT capabilities, VHT capabilities and the +- * same field in the HE capabilities. +- */ +--#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_USE_VHT 0x00 +--#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_1 0x08 +--#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2 0x10 +--#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED 0x18 +-+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_0 0x00 +-+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1 0x08 +-+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2 0x10 +-+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3 0x18 +- #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK 0x18 +- #define IEEE80211_HE_MAC_CAP3_AMSDU_FRAG 0x20 +- #define IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED 0x40 +- #define IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS 0x80 +- +--#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHIFT 3 +-- +- #define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG 0x01 +- #define IEEE80211_HE_MAC_CAP4_QTP 0x02 +- #define IEEE80211_HE_MAC_CAP4_BQR 0x04 +---- a/net/mac80211/debugfs_sta.c +-+++ b/net/mac80211/debugfs_sta.c +-@@ -711,17 +711,17 @@ static ssize_t sta_he_capa_read(struct f +- PFLAG(MAC, 3, OFDMA_RA, "OFDMA-RA"); +- +- switch (cap[3] & IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) { +-- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_USE_VHT: +-- PRINT("MAX-AMPDU-LEN-EXP-USE-VHT"); +-+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_0: +-+ PRINT("MAX-AMPDU-LEN-EXP-USE-EXT-0"); +- break; +-- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_1: +-- PRINT("MAX-AMPDU-LEN-EXP-VHT-1"); +-+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1: +-+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-1"); +- break; +-- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2: +-- PRINT("MAX-AMPDU-LEN-EXP-VHT-2"); +-+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2: +-+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-2"); +- break; +-- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED: +-- PRINT("MAX-AMPDU-LEN-EXP-RESERVED"); +-+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3: +-+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-3"); +- break; +- } +- +diff --git a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch +index f9c4caa51c..3df4062ec5 100644 +--- a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch ++++ b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch +@@ -5,7 +5,7 @@ and we should ignore this. + + --- a/net/wireless/core.c + +++ b/net/wireless/core.c +-@@ -614,21 +614,6 @@ static int wiphy_verify_combinations(str ++@@ -630,21 +630,6 @@ static int wiphy_verify_combinations(str + c->limits[j].max > 1)) + return -EINVAL; + +diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +index 6f13f64208..e0a259cde5 100644 +--- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch ++++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +@@ -1,24 +1,24 @@ + --- a/include/net/cfg80211.h + +++ b/include/net/cfg80211.h +-@@ -3814,6 +3814,7 @@ struct mgmt_frame_regs { ++@@ -3835,6 +3835,7 @@ struct mgmt_frame_regs { + * (as advertised by the nl80211 feature flag.) + * @get_tx_power: store the current TX power into the dbm variable; + * return 0 if successful + + * @set_antenna_gain: set antenna gain to reduce maximum tx power if necessary + * +- * @set_wds_peer: set the WDS peer for a WDS interface +- * +-@@ -4138,6 +4139,7 @@ struct cfg80211_ops { ++ * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting ++ * functions to adjust rfkill hw state ++@@ -4159,6 +4160,7 @@ struct cfg80211_ops { + enum nl80211_tx_power_setting type, int mbm); + int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, + int *dbm); + + int (*set_antenna_gain)(struct wiphy *wiphy, int dbi); + +- int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, +- const u8 *addr); ++ void (*rfkill_poll)(struct wiphy *wiphy); ++ + --- a/include/net/mac80211.h + +++ b/include/net/mac80211.h +-@@ -1561,6 +1561,7 @@ enum ieee80211_smps_mode { ++@@ -1566,6 +1566,7 @@ enum ieee80211_smps_mode { + * + * @power_level: requested transmit power (in dBm), backward compatibility + * value only that is set to the minimum of all interfaces +@@ -26,7 +26,7 @@ + * + * @chandef: the channel definition to tune to + * @radar_enabled: whether radar detection is enabled +-@@ -1581,6 +1582,7 @@ enum ieee80211_smps_mode { ++@@ -1586,6 +1587,7 @@ enum ieee80211_smps_mode { + struct ieee80211_conf { + u32 flags; + int power_level, dynamic_ps_timeout; +@@ -57,7 +57,7 @@ + __NL80211_ATTR_AFTER_LAST, + --- a/net/mac80211/cfg.c + +++ b/net/mac80211/cfg.c +-@@ -2769,6 +2769,19 @@ static int ieee80211_get_tx_power(struct ++@@ -2764,6 +2764,19 @@ static int ieee80211_get_tx_power(struct + return 0; + } + +@@ -74,20 +74,20 @@ + + return 0; + +} + + +- static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, +- const u8 *addr) ++ static void ieee80211_rfkill_poll(struct wiphy *wiphy) + { +-@@ -4413,6 +4426,7 @@ const struct cfg80211_ops mac80211_confi ++ struct ieee80211_local *local = wiphy_priv(wiphy); ++@@ -4399,6 +4412,7 @@ const struct cfg80211_ops mac80211_confi + .set_wiphy_params = ieee80211_set_wiphy_params, + .set_tx_power = ieee80211_set_tx_power, + .get_tx_power = ieee80211_get_tx_power, + + .set_antenna_gain = ieee80211_set_antenna_gain, +- .set_wds_peer = ieee80211_set_wds_peer, + .rfkill_poll = ieee80211_rfkill_poll, + CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) ++ CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump) + --- a/net/mac80211/ieee80211_i.h + +++ b/net/mac80211/ieee80211_i.h +-@@ -1435,6 +1435,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 */ +@@ -119,7 +119,7 @@ + if (local->hw.conf.power_level != power) { + changed |= IEEE80211_CONF_CHANGE_POWER; + local->hw.conf.power_level = power; +-@@ -665,6 +671,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ ++@@ -679,6 +685,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ + IEEE80211_RADIOTAP_MCS_HAVE_BW; + local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | + IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; +@@ -129,7 +129,7 @@ + local->hw.max_mtu = IEEE80211_MAX_DATA_LEN; + --- a/net/wireless/nl80211.c + +++ b/net/wireless/nl80211.c +-@@ -757,6 +757,7 @@ static const struct nla_policy nl80211_p ++@@ -780,6 +780,7 @@ static const struct nla_policy nl80211_p + [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), +@@ -137,24 +137,26 @@ + }; + + /* policy for the key attributes */ +-@@ -3322,6 +3323,20 @@ static int nl80211_set_wiphy(struct sk_b ++@@ -3328,6 +3329,22 @@ static int nl80211_set_wiphy(struct sk_b + if (result) +- return result; ++ goto out; + } + + + + if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) { + + int idx, dbi = 0; + + +-+ if (!rdev->ops->set_antenna_gain) +-+ return -EOPNOTSUPP; +++ if (!rdev->ops->set_antenna_gain) { +++ result = -EOPNOTSUPP; +++ goto out; +++ } + + + + idx = NL80211_ATTR_WIPHY_ANTENNA_GAIN; + + dbi = nla_get_u32(info->attrs[idx]); + + + + result = rdev->ops->set_antenna_gain(&rdev->wiphy, dbi); + + if (result) +-+ return result; +++ goto out; + + } + +- if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && +- info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { ++ if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) { ++ struct wireless_dev *txp_wdev = wdev; +diff --git a/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch +new file mode 100644 +index 0000000000..26af6a2fb9 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch +@@ -0,0 +1,29 @@ ++--- a/backport-include/linux/of_net.h +++++ /dev/null ++@@ -1,26 +0,0 @@ ++-#ifndef _BP_OF_NET_H ++-#define _BP_OF_NET_H ++-#include_next ++-#include ++-#include ++- ++-/* The behavior of of_get_mac_address() changed in kernel 5.2, it now ++- * returns an error code and not NULL in case of an error. ++- */ ++-#if LINUX_VERSION_IS_LESS(5,13,0) ++-static inline int backport_of_get_mac_address(struct device_node *np, u8 *mac_out) ++-{ ++- const void *mac = of_get_mac_address(np); ++- ++- if (!mac) ++- return -ENODEV; ++- if (IS_ERR(mac)) ++- return PTR_ERR(mac); ++- ether_addr_copy(mac_out, mac); ++- ++- return 0; ++-} ++-#define of_get_mac_address LINUX_BACKPORT(of_get_mac_address) ++-#endif /* < 5.2 */ ++- ++-#endif /* _BP_OF_NET_H */ +-- +2.25.1 + diff --git a/patches/wifi/0002-mac80211-pending-fixes.patch b/patches/wifi/0002-mac80211-pending-fixes.patch new file mode 100644 index 000000000..3e0e36881 --- /dev/null +++ b/patches/wifi/0002-mac80211-pending-fixes.patch @@ -0,0 +1,106 @@ +From 1f1de369b842e8dbf3577d6e8380e57e7810007a Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Tue, 4 Jan 2022 06:22:59 +0100 +Subject: [PATCH 2/4] mac80211: pending fixes + +Signed-off-by: John Crispin +--- + .../files/lib/netifd/wireless/mac80211.sh | 25 ++++++++++++++----- + 1 file changed, 19 insertions(+), 6 deletions(-) + +diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +index 27eecf3a7f..823cb0180c 100644 +--- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh ++++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +@@ -29,6 +29,7 @@ drv_mac80211_init_device_config() { + config_add_string distance + config_add_int beacon_int chanbw frag rts + config_add_int rxantenna txantenna antenna_gain txpower ++ config_add_int num_global_macaddr + config_add_boolean noscan ht_coex acs_exclude_dfs + config_add_array ht_capab + config_add_array channels +@@ -514,6 +515,7 @@ mac80211_get_addr() { + + mac80211_generate_mac() { + local phy="$1" ++ local multiple_bssid="$2" + local id="${macidx:-0}" + + local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)" +@@ -537,9 +539,16 @@ mac80211_generate_mac() { + local mask6=$6 + + local oIFS="$IFS"; IFS=":"; set -- $ref; IFS="$oIFS" +- ++ [ "$multiple_bssid" -eq 1 ] && { ++ printf "02:%s:%s:%s:%s:%02x" $b1 $2 $3 $4 $5 $macidx ++ return ++ } + macidx=$(($id + 1)) +- [ "$((0x$mask1))" -gt 0 ] && { ++ ++ local use_global=0 ++ [ "$id" -gt 0 -a "$macidx" -le "$num_global_macaddr" ] && use_global=1 ++ ++ [ "$((0x$mask1))" -gt 0 -a "$use_global" -lt 1 ] && { + b1="0x$1" + [ "$id" -gt 0 ] && \ + b1=$(($b1 ^ ((($id - !($b1 & 2)) << 2)) | 0x2)) +@@ -547,7 +556,7 @@ mac80211_generate_mac() { + return + } + +- [ "$((0x$mask6))" -lt 255 ] && { ++ [ "$((0x$mask6))" -lt 255 -a "$use_global" -gt 0 ] && { + printf "%s:%s:%s:%s:%s:%02x" $1 $2 $3 $4 $5 $(( 0x$6 ^ $id )) + return + } +@@ -646,6 +655,7 @@ mac80211_iw_interface_add() { + } + + mac80211_prepare_vif() { ++ local multiple_bssid=$1 + json_select config + + json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file +@@ -659,7 +669,7 @@ mac80211_prepare_vif() { + json_select .. + + [ -n "$macaddr" ] || { +- macaddr="$(mac80211_generate_mac $phy)" ++ macaddr="$(mac80211_generate_mac $phy $multiple_bssid)" + macidx="$(($macidx + 1))" + } + +@@ -1028,7 +1038,9 @@ drv_mac80211_setup() { + country chanbw distance \ + txpower antenna_gain \ + rxantenna txantenna \ +- frag rts beacon_int:100 htmode ++ frag rts beacon_int:100 htmode \ ++ multiple_bssid:0 \ ++ num_global_macaddr + json_get_values basic_rate_list basic_rate + json_get_values scan_list scan_list + json_select .. +@@ -1090,6 +1102,7 @@ drv_mac80211_setup() { + set_default txantenna 0xffffffff + set_default distance 0 + set_default antenna_gain 0 ++ set_default num_global_macaddr 1 + + [ "$txantenna" = "all" ] && txantenna=0xffffffff + [ "$rxantenna" = "all" ] && rxantenna=0xffffffff +@@ -1121,7 +1134,7 @@ drv_mac80211_setup() { + mac80211_prepare_iw_htmode + for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif + NEWAPLIST= +- for_each_interface "ap" mac80211_prepare_vif ++ for_each_interface "ap" mac80211_prepare_vif ${multiple_bssid} + NEW_MD5=$(test -e "${hostapd_conf_file}" && md5sum ${hostapd_conf_file}) + OLD_MD5=$(uci -q -P /var/state get wireless._${phy}.md5) + if [ "${NEWAPLIST}" != "${OLDAPLIST}" ]; then +-- +2.25.1 + diff --git a/patches/backports/0019-hostapd-update-to-latest-HEAD.patch b/patches/wifi/0003-hostapd-backport-latest-HEAD.patch similarity index 75% rename from patches/backports/0019-hostapd-update-to-latest-HEAD.patch rename to patches/wifi/0003-hostapd-backport-latest-HEAD.patch index 89e4fbddd..5b4a16f63 100644 --- a/patches/backports/0019-hostapd-update-to-latest-HEAD.patch +++ b/patches/wifi/0003-hostapd-backport-latest-HEAD.patch @@ -1,45 +1,51 @@ -From 6e3370a4c785c2c245b77832960f1dbed2736192 Mon Sep 17 00:00:00 2001 +From 7004c861a5f8cbe52a47e5888cdd8d555206e033 Mon Sep 17 00:00:00 2001 From: John Crispin -Date: Sat, 4 Sep 2021 05:48:27 +0200 -Subject: [PATCH 01/70] hostapd: update to latest HEAD +Date: Tue, 4 Jan 2022 06:56:05 +0100 +Subject: [PATCH 3/4] hostapd: backport latest HEAD Signed-off-by: John Crispin --- - package/network/services/hostapd/Makefile | 15 +- - .../hostapd/files/hostapd-basic.config | 2 +- - .../hostapd/files/hostapd-full.config | 4 +- - .../network/services/hostapd/files/hostapd.sh | 188 +++++++++--- - ...-fix-frequency-setup-with-HE-enabled.patch | 196 ------------- - ...> 001-wolfssl-init-RNG-with-ECC-key.patch} | 11 +- - ...-init-order-disable-pri-sec-channel-.patch | 126 -------- - ...andle-HT40-and-mode-downgrade-in-AP-.patch | 102 ------- - ...ix-frequency-config-for-non-p2p-vht-.patch | 63 ---- - ...nable-vht-and-he-in-default-config-p.patch | 25 -- - ...er-debug-messages-for-some-error-cas.patch | 83 ------ - ...lper-functions-for-vht-he-parameters.patch | 27 -- - ...ompletion-callback-to-complete-mesh-.patch | 108 ------- - ...-frequency-as-pri-sec-channel-switch.patch | 26 -- + package/network/services/hostapd/Makefile | 25 +- + .../services/hostapd/files/dhcp-get-server.sh | 2 + + .../hostapd/files/hostapd-basic.config | 3 + + .../hostapd/files/hostapd-full.config | 5 +- + .../hostapd/files/hostapd-mini.config | 3 + + .../network/services/hostapd/files/hostapd.sh | 89 +++- + .../hostapd/files/wpa_supplicant-full.config | 2 +- + .../hostapd/files/wpa_supplicant-p2p.config | 2 +- + .../services/hostapd/files/wps-hotplug.sh | 21 +- + ...-fix-frequency-setup-with-HE-enabled.patch | 196 -------- + ...> 001-wolfssl-init-RNG-with-ECC-key.patch} | 0 + ...-init-order-disable-pri-sec-channel-.patch | 126 ----- + ...andle-HT40-and-mode-downgrade-in-AP-.patch | 102 ---- + ...ix-frequency-config-for-non-p2p-vht-.patch | 63 --- + ...nable-vht-and-he-in-default-config-p.patch | 25 - + ...er-debug-messages-for-some-error-cas.patch | 83 --- + ...lper-functions-for-vht-he-parameters.patch | 27 - + ...ompletion-callback-to-complete-mesh-.patch | 108 ---- + ...-frequency-as-pri-sec-channel-switch.patch | 26 - ...hannels-to-be-selected-if-dfs-is-ena.patch | 10 +- - ...offchanok-on-DFS-channels-in-non-ETS.patch | 53 ---- + ...offchanok-on-DFS-channels-in-non-ETS.patch | 53 -- ...rministic-channel-on-channel-switch.patch} | 2 +- - ...-fix-channel-switch-error-during-CAC.patch | 66 ----- - ...rnel-driver-DFS-handler-in-userspace.patch | 48 --- - .../014-mesh-fixes-for-mesh-init-deinit.patch | 158 ---------- - .../015-mesh-fix-DFS-deinit-init.patch | 262 ----------------- - ...sts-DFS-test-for-wpa_supplicant-mesh.patch | 94 ------ - .../patches/017-mesh-fix-mesh_oom-test.patch | 24 -- - ...ve-mesh-freq-setting-to-own-function.patch | 93 ------ - ...020-ignore-4addr-mode-enabling-error.patch | 78 ----- + ...-fix-channel-switch-error-during-CAC.patch | 66 --- + ...rnel-driver-DFS-handler-in-userspace.patch | 48 -- + .../014-mesh-fixes-for-mesh-init-deinit.patch | 158 ------ + .../015-mesh-fix-DFS-deinit-init.patch | 262 ---------- + ...sts-DFS-test-for-wpa_supplicant-mesh.patch | 94 ---- + .../patches/017-mesh-fix-mesh_oom-test.patch | 24 - + ...ve-mesh-freq-setting-to-own-function.patch | 93 ---- + ...020-ignore-4addr-mode-enabling-error.patch | 73 --- ...0-mesh-make-forwarding-configurable.patch} | 28 +- - ...ix-sta-add-after-previous-connection.patch | 26 ++ - ...use-of-uninitialized-stack-variables.patch | 25 ++ - ...-dl_list_del-before-freeing-ipv6-add.patch | 19 ++ - ...ewrite-neigh-code-to-not-depend-on-l.patch | 275 ++++++++++++++++++ - ...-case-in-peer-addition-based-on-PD-R.patch | 45 --- - .../patches/110-notify-mgmt-frames.patch | 116 -------- + ...ix-sta-add-after-previous-connection.patch | 26 + + ...use-of-uninitialized-stack-variables.patch | 25 + + ...ewrite-neigh-code-to-not-depend-on-l.patch | 14 +- + ...ssing-authentication-frames-in-block.patch | 8 +- + .../hostapd/patches/050-build_fix.patch | 20 + + ...-case-in-peer-addition-based-on-PD-R.patch | 45 -- + .../patches/110-notify-mgmt-frames.patch | 116 ----- .../patches/110-wolfssl-compile-fix.patch | 10 - - .../120-reconfigure-wps-credentials.patch | 178 ------------ - .../hostapd/patches/200-multicall.patch | 80 ++--- + .../120-reconfigure-wps-credentials.patch | 178 ------- + .../hostapd/patches/200-multicall.patch | 80 +-- .../services/hostapd/patches/300-noscan.patch | 6 +- .../hostapd/patches/301-mesh-noscan.patch | 10 +- .../patches/310-rescan_immediately.patch | 2 +- @@ -49,8 +55,8 @@ Signed-off-by: John Crispin .../341-mesh-ctrl-iface-channel-switch.patch | 2 +- .../patches/350-nl80211_del_beacon_bss.patch | 12 +- .../patches/360-ctrl_iface_reload.patch | 10 +- - .../hostapd/patches/370-ap_sta_support.patch | 67 ++--- - .../patches/380-disable_ctrl_iface_mib.patch | 34 +-- + .../hostapd/patches/370-ap_sta_support.patch | 68 ++- + .../patches/380-disable_ctrl_iface_mib.patch | 34 +- .../patches/390-wpa_ie_cap_workaround.patch | 4 +- .../patches/420-indicate-features.patch | 4 +- .../patches/430-hostapd_cli_ifdef.patch | 4 +- @@ -60,22 +66,29 @@ Signed-off-by: John Crispin .../patches/464-fix-mesh-obss-check.patch | 2 +- .../patches/470-survey_data_fallback.patch | 2 +- .../patches/500-lto-jobserver-support.patch | 19 +- - .../hostapd/patches/600-ubus_support.patch | 166 ++++++++--- - .../hostapd/patches/700-wifi-reload.patch | 51 ++-- - .../hostapd/patches/710-vlan_no_bridge.patch | 41 +++ - .../patches/711-wds_bridge_force.patch | 26 ++ + ...50-WNM-allow-specifying-dialog-token.patch | 99 ++++ + .../patches/590-rrm-wnm-statistics.patch | 92 ++++ + .../hostapd/patches/600-ubus_support.patch | 207 ++++++-- + .../610-hostapd_cli_ujail_permission.patch | 33 ++ + .../hostapd/patches/700-wifi-reload.patch | 53 +- + .../hostapd/patches/710-vlan_no_bridge.patch | 24 +- + .../patches/711-wds_bridge_force.patch | 2 +- .../720-ACS-fix-channel-100-frequency.patch | 30 ++ - .../patches/720-iface_max_num_sta.patch | 82 ++++++ - .../hostapd/patches/730-ft_iface.patch | 38 +++ - .../hostapd/patches/740-snoop_iface.patch | 72 +++++ - ...ate-if-no-available-channel-is-found.patch | 37 --- - ...of-secondary-device-types-for-P2P-gr.patch | 33 --- - .../services/hostapd/src/src/ap/ubus.c | 214 +++++++++++++- - .../services/hostapd/src/src/ap/ubus.h | 16 + - .../hostapd/src/src/utils/build_features.h | 2 - - 68 files changed, 1343 insertions(+), 2347 deletions(-) + .../patches/720-iface_max_num_sta.patch | 82 +++ + .../hostapd/patches/730-ft_iface.patch | 6 +- + .../hostapd/patches/740-snoop_iface.patch | 4 +- + ...ompilation-with-Hotspot-2.0-disabled.patch | 51 ++ + ...750-qos_map_set_without_interworking.patch | 20 +- + .../751-qos_map_ignore_when_unsupported.patch | 12 + + ...ate-if-no-available-channel-is-found.patch | 37 -- + ...of-secondary-device-types-for-P2P-gr.patch | 33 -- + .../services/hostapd/src/src/ap/ubus.c | 472 ++++++++++++++++-- + .../services/hostapd/src/src/ap/ubus.h | 37 ++ + .../hostapd/src/src/utils/build_features.h | 6 +- + 80 files changed, 1462 insertions(+), 2396 deletions(-) + create mode 100644 package/network/services/hostapd/files/dhcp-get-server.sh delete mode 100644 package/network/services/hostapd/patches/001-HE-VHT-fix-frequency-setup-with-HE-enabled.patch - rename package/network/services/hostapd/patches/{802-wolfssl-init-RNG-with-ECC-key.patch => 001-wolfssl-init-RNG-with-ECC-key.patch} (76%) + rename package/network/services/hostapd/patches/{802-wolfssl-init-RNG-with-ECC-key.patch => 001-wolfssl-init-RNG-with-ECC-key.patch} (100%) delete mode 100644 package/network/services/hostapd/patches/002-mesh-fix-channel-init-order-disable-pri-sec-channel-.patch delete mode 100644 package/network/services/hostapd/patches/003-wpa_supplicant-handle-HT40-and-mode-downgrade-in-AP-.patch delete mode 100644 package/network/services/hostapd/patches/004-wpa_supplicant-fix-frequency-config-for-non-p2p-vht-.patch @@ -97,23 +110,23 @@ Signed-off-by: John Crispin rename package/network/services/hostapd/patches/{050-mesh-make-forwarding-configurable.patch => 020-mesh-make-forwarding-configurable.patch} (89%) create mode 100644 package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch create mode 100644 package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch - create mode 100644 package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch - create mode 100644 package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch + create mode 100644 package/network/services/hostapd/patches/050-build_fix.patch delete mode 100644 package/network/services/hostapd/patches/060-P2P-Fix-a-corner-case-in-peer-addition-based-on-PD-R.patch delete mode 100644 package/network/services/hostapd/patches/110-notify-mgmt-frames.patch delete mode 100644 package/network/services/hostapd/patches/110-wolfssl-compile-fix.patch delete mode 100644 package/network/services/hostapd/patches/120-reconfigure-wps-credentials.patch - create mode 100644 package/network/services/hostapd/patches/710-vlan_no_bridge.patch - create mode 100644 package/network/services/hostapd/patches/711-wds_bridge_force.patch + create mode 100644 package/network/services/hostapd/patches/550-WNM-allow-specifying-dialog-token.patch + create mode 100644 package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch + create mode 100644 package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch create mode 100644 package/network/services/hostapd/patches/720-ACS-fix-channel-100-frequency.patch create mode 100644 package/network/services/hostapd/patches/720-iface_max_num_sta.patch - create mode 100644 package/network/services/hostapd/patches/730-ft_iface.patch - create mode 100644 package/network/services/hostapd/patches/740-snoop_iface.patch + create mode 100644 package/network/services/hostapd/patches/741-proxyarp-fix-compilation-with-Hotspot-2.0-disabled.patch + create mode 100644 package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch delete mode 100644 package/network/services/hostapd/patches/800-dfs-enter-DFS-state-if-no-available-channel-is-found.patch delete mode 100644 package/network/services/hostapd/patches/801-P2P-Fix-copying-of-secondary-device-types-for-P2P-gr.patch diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile -index 67ea89c339..fee6889b40 100644 +index 783c10d587..7e4056bb18 100644 --- a/package/network/services/hostapd/Makefile +++ b/package/network/services/hostapd/Makefile @@ -1,19 +1,17 @@ @@ -128,7 +141,7 @@ index 67ea89c339..fee6889b40 100644 include $(TOPDIR)/rules.mk PKG_NAME:=hostapd --PKG_RELEASE:=35 +-PKG_RELEASE:=37 +PKG_RELEASE:=$(AUTORELEASE) PKG_SOURCE_URL:=http://w1.fi/hostap.git @@ -142,7 +155,47 @@ index 67ea89c339..fee6889b40 100644 PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=BSD-3-Clause -@@ -524,6 +522,7 @@ define Build/RunMake +@@ -145,6 +143,7 @@ define Package/hostapd/Default + TITLE:=IEEE 802.1x Authenticator + URL:=http://hostap.epitest.fi/ + DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus ++ EXTRA_DEPENDS:=hostapd-common (=$(PKG_VERSION)-$(PKG_RELEASE)) + USERID:=network=101:network=101 + PROVIDES:=hostapd + CONFLICTS:=$(HOSTAPD_PROVIDERS) +@@ -229,6 +228,7 @@ define Package/wpad/Default + SUBMENU:=WirelessAPD + TITLE:=IEEE 802.1x Auth/Supplicant + DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus ++ EXTRA_DEPENDS:=hostapd-common (=$(PKG_VERSION)-$(PKG_RELEASE)) + USERID:=network=101:network=101 + URL:=http://hostap.epitest.fi/ + PROVIDES:=hostapd wpa-supplicant +@@ -344,6 +344,7 @@ define Package/wpa-supplicant/Default + TITLE:=WPA Supplicant + URL:=http://hostap.epitest.fi/wpa_supplicant/ + DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus ++ EXTRA_DEPENDS:=hostapd-common (=$(PKG_VERSION)-$(PKG_RELEASE)) + USERID:=network=101:network=101 + PROVIDES:=wpa-supplicant + CONFLICTS:=$(SUPPLICANT_PROVIDERS) +@@ -428,6 +429,7 @@ define Package/hostapd-utils + TITLE:=IEEE 802.1x Authenticator (utils) + URL:=http://hostap.epitest.fi/ + DEPENDS:=@$(subst $(space),||,$(foreach pkg,$(HOSTAPD_PROVIDERS),PACKAGE_$(pkg))) ++ VARIANT:=* + endef + + define Package/hostapd-utils/description +@@ -441,6 +443,7 @@ define Package/wpa-cli + SUBMENU:=WirelessAPD + DEPENDS:=@$(subst $(space),||,$(foreach pkg,$(SUPPLICANT_PROVIDERS),PACKAGE_$(pkg))) + TITLE:=WPA Supplicant command line control utility ++ VARIANT:=* + endef + + define Package/eapol-test/Default +@@ -524,6 +527,7 @@ define Build/RunMake LIBS_c="$(TARGET_LDFLAGS_C)" \ AR="$(TARGET_CROSS)gcc-ar" \ BCHECK= \ @@ -150,125 +203,148 @@ index 67ea89c339..fee6889b40 100644 $(2) endef +@@ -597,6 +601,7 @@ endef + + define Package/hostapd-common/install + $(INSTALL_DIR) $(1)/etc/capabilities $(1)/etc/rc.button $(1)/etc/hotplug.d/ieee80211 $(1)/etc/init.d $(1)/lib/netifd $(1)/usr/share/acl.d ++ $(INSTALL_BIN) ./files/dhcp-get-server.sh $(1)/lib/netifd/dhcp-get-server.sh + $(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/netifd/hostapd.sh + $(INSTALL_BIN) ./files/wpad.init $(1)/etc/init.d/wpad + $(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps +@@ -678,6 +683,9 @@ ifeq ($(BUILD_VARIANT),supplicant-full-wolfssl) + endef + endif + ++# Build hostapd-common before its dependents, to avoid ++# spurious rebuilds when building multiple variants. ++$(eval $(call BuildPackage,hostapd-common)) + $(eval $(call BuildPackage,hostapd)) + $(eval $(call BuildPackage,hostapd-basic)) + $(eval $(call BuildPackage,hostapd-basic-openssl)) +@@ -704,7 +712,6 @@ $(eval $(call BuildPackage,wpa-supplicant-openssl)) + $(eval $(call BuildPackage,wpa-supplicant-wolfssl)) + $(eval $(call BuildPackage,wpa-cli)) + $(eval $(call BuildPackage,hostapd-utils)) +-$(eval $(call BuildPackage,hostapd-common)) + $(eval $(call BuildPackage,eapol-test)) + $(eval $(call BuildPackage,eapol-test-openssl)) + $(eval $(call BuildPackage,eapol-test-wolfssl)) +diff --git a/package/network/services/hostapd/files/dhcp-get-server.sh b/package/network/services/hostapd/files/dhcp-get-server.sh +new file mode 100644 +index 0000000000..a1509ace2f +--- /dev/null ++++ b/package/network/services/hostapd/files/dhcp-get-server.sh +@@ -0,0 +1,2 @@ ++#!/bin/sh ++[ "$1" = bound ] && echo "$serverid" diff --git a/package/network/services/hostapd/files/hostapd-basic.config b/package/network/services/hostapd/files/hostapd-basic.config -index 947e2fa200..33c38192b1 100644 +index 33c38192b1..1f52546d57 100644 --- a/package/network/services/hostapd/files/hostapd-basic.config +++ b/package/network/services/hostapd/files/hostapd-basic.config -@@ -384,7 +384,7 @@ CONFIG_TLS=internal - #CONFIG_OWE=y - +@@ -386,6 +386,9 @@ CONFIG_TLS=internal # Airtime policy support --#CONFIG_AIRTIME_POLICY=y -+CONFIG_AIRTIME_POLICY=y + CONFIG_AIRTIME_POLICY=y ++# Proxy ARP support ++#CONFIG_PROXYARP=y ++ # Override default value for the wpa_disable_eapol_key_retries configuration # parameter. See that parameter in hostapd.conf for more details. + #CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1 diff --git a/package/network/services/hostapd/files/hostapd-full.config b/package/network/services/hostapd/files/hostapd-full.config -index df272e443a..61b6daf861 100644 +index df272e443a..dbc2022550 100644 --- a/package/network/services/hostapd/files/hostapd-full.config +++ b/package/network/services/hostapd/files/hostapd-full.config -@@ -94,10 +94,10 @@ CONFIG_EAP_TTLS=y - #CONFIG_EAP_PAX=y +@@ -60,7 +60,7 @@ CONFIG_RSN_PREAUTH=y + CONFIG_EAP=y - # EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) --#CONFIG_EAP_PSK=y -+CONFIG_EAP_PSK=y + # EAP Re-authentication Protocol (ERP) in integrated EAP server +-#CONFIG_ERP=y ++CONFIG_ERP=y - # EAP-pwd for the integrated EAP server (secure authentication with a password) --#CONFIG_EAP_PWD=y -+CONFIG_EAP_PWD=y + # EAP-MD5 for the integrated EAP server + CONFIG_EAP_MD5=y +@@ -386,6 +386,9 @@ CONFIG_TAXONOMY=y + # Airtime policy support + CONFIG_AIRTIME_POLICY=y - # EAP-SAKE for the integrated EAP server - #CONFIG_EAP_SAKE=y ++# Proxy ARP support ++CONFIG_PROXYARP=y ++ + # Override default value for the wpa_disable_eapol_key_retries configuration + # parameter. See that parameter in hostapd.conf for more details. + #CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1 +diff --git a/package/network/services/hostapd/files/hostapd-mini.config b/package/network/services/hostapd/files/hostapd-mini.config +index b3050f7bbc..f2ed071ec0 100644 +--- a/package/network/services/hostapd/files/hostapd-mini.config ++++ b/package/network/services/hostapd/files/hostapd-mini.config +@@ -386,6 +386,9 @@ CONFIG_TLS=internal + # Airtime policy support + #CONFIG_AIRTIME_POLICY=y + ++# Proxy ARP support ++#CONFIG_PROXYARP=y ++ + # Override default value for the wpa_disable_eapol_key_retries configuration + # parameter. See that parameter in hostapd.conf for more details. + #CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1 diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh -index aa72e09eba..fe6af98f4d 100644 +index b52667d09a..d9d5f34877 100644 --- a/package/network/services/hostapd/files/hostapd.sh +++ b/package/network/services/hostapd/files/hostapd.sh -@@ -48,13 +48,17 @@ hostapd_append_wpa_key_mgmt() { +@@ -72,6 +72,15 @@ hostapd_append_wpa_key_mgmt() { ;; - eap192) - append wpa_key_mgmt "WPA-EAP-SUITE-B-192" -+ append wpa_key_mgmt "WPA-EAP-SHA256" - [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP" - ;; -- eap-eap192) -- append wpa_key_mgmt "WPA-EAP-SUITE-B-192" -+ eap-eap256) - append wpa_key_mgmt "WPA-EAP" -+ append wpa_key_mgmt "WPA-EAP-SHA256" -+ [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP" -+ ;; -+ eap256) -+ append wpa_key_mgmt "WPA-EAP-SHA256" - [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP" -- [ "${ieee80211w:-0}" -gt 0 ] && append wpa_key_mgmt "WPA-EAP-SHA256" - ;; - sae) - append wpa_key_mgmt "SAE" -@@ -91,6 +95,7 @@ hostapd_add_log_config() { - hostapd_common_add_device_config() { - config_add_array basic_rate - config_add_array supported_rates -+ config_add_string beacon_rate + esac - config_add_string country country3 - config_add_boolean country_ie doth -@@ -99,6 +104,10 @@ hostapd_common_add_device_config() { - config_add_string require_mode ++ [ "$fils" -gt 0 ] && { ++ case "$auth_type" in ++ eap*) ++ append wpa_key_mgmt FILS-SHA256 ++ [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt FT-FILS-SHA256 ++ ;; ++ esac ++ } ++ + [ "$auth_osen" = "1" ] && append wpa_key_mgmt "OSEN" + } + +@@ -101,6 +110,9 @@ hostapd_common_add_device_config() { config_add_boolean legacy_rates config_add_int cell_density -+ config_add_int rts_threshold + config_add_int rts_threshold + config_add_int rssi_reject_assoc_rssi + config_add_int rssi_ignore_probe_request + config_add_int maxassoc config_add_string acs_chan_bias config_add_array hostapd_options -@@ -115,7 +124,8 @@ hostapd_prepare_device_config() { - local base_cfg= +@@ -118,7 +130,7 @@ hostapd_prepare_device_config() { json_get_vars country country3 country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \ -- acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density -+ acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \ + acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \ +- rts_threshold beacon_rate + rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc hostapd_set_log_options base_cfg -@@ -207,11 +217,16 @@ hostapd_prepare_device_config() { +@@ -210,6 +222,8 @@ hostapd_prepare_device_config() { hostapd_add_rate brlist "$br" done + [ -n "$rssi_reject_assoc_rssi" ] && append base_cfg "rssi_reject_assoc_rssi=$rssi_reject_assoc_rssi" "$N" + [ -n "$rssi_ignore_probe_request" ] && append base_cfg "rssi_ignore_probe_request=$rssi_ignore_probe_request" "$N" -+ [ -n "$beacon_rate" ] && append base_cfg "beacon_rate=$beacon_rate" "$N" + [ -n "$beacon_rate" ] && append base_cfg "beacon_rate=$beacon_rate" "$N" [ -n "$rlist" ] && append base_cfg "supported_rates=$rlist" "$N" [ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N" - append base_cfg "beacon_int=$beacon_int" "$N" -+ [ -n "$rts_threshold" ] && append base_cfg "rts_threshold=$rts_threshold" "$N" +@@ -217,6 +231,7 @@ hostapd_prepare_device_config() { + [ -n "$rts_threshold" ] && append base_cfg "rts_threshold=$rts_threshold" "$N" append base_cfg "dtim_period=$dtim_period" "$N" [ "$airtime_mode" -gt 0 ] && append base_cfg "airtime_mode=$airtime_mode" "$N" + [ -n "$maxassoc" ] && append base_cfg "iface_max_num_sta=$maxassoc" "$N" json_get_values opts hostapd_options for val in $opts; do -@@ -269,7 +284,7 @@ hostapd_common_add_bss_config() { - config_add_array domain_match domain_match2 domain_suffix_match domain_suffix_match2 - config_add_string ieee80211w_mgmt_cipher - -- config_add_int dynamic_vlan vlan_naming -+ config_add_int dynamic_vlan vlan_naming vlan_no_bridge - config_add_string vlan_tagged_interface vlan_bridge - config_add_string vlan_file - -@@ -287,6 +302,7 @@ hostapd_common_add_bss_config() { - config_add_boolean wnm_sleep_mode wnm_sleep_mode_no_keys bss_transition - config_add_int time_advertisement - config_add_string time_zone -+ config_add_string vendor_elements - - config_add_boolean ieee80211k rrm_neighbor_report rrm_beacon_report - -@@ -311,6 +327,7 @@ hostapd_common_add_bss_config() { +@@ -317,6 +332,7 @@ hostapd_common_add_bss_config() { config_add_array supported_rates config_add_boolean sae_require_mfp @@ -276,25 +352,7 @@ index aa72e09eba..fe6af98f4d 100644 config_add_string 'owe_transition_bssid:macaddr' 'owe_transition_ssid:string' -@@ -319,23 +336,35 @@ hostapd_common_add_bss_config() { - config_add_int iw_ipaddr_type_availability iw_gas_address3 - config_add_string iw_hessid iw_network_auth_type iw_qos_map_set - config_add_array iw_roaming_consortium iw_domain_name iw_anqp_3gpp_cell_net iw_nai_realm -- config_add_array iw_anqp_elem -+ config_add_array iw_anqp_elem iw_venue_name iw_venue_url - - config_add_boolean hs20 disable_dgaf osen - config_add_int anqp_domain_id -- config_add_int hs20_deauth_req_timeout -+ config_add_int hs20_deauth_req_timeout hs20_release - config_add_array hs20_oper_friendly_name - config_add_array osu_provider - config_add_array operator_icon - config_add_array hs20_conn_capab - config_add_string osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp - -+ config_add_string hs20_t_c_server_url -+ +@@ -341,9 +357,10 @@ hostapd_common_add_bss_config() { config_add_array airtime_sta_weight config_add_int airtime_bss_weight airtime_bss_limit @@ -303,74 +361,34 @@ index aa72e09eba..fe6af98f4d 100644 config_add_array hostapd_bss_options + config_add_boolean default_disabled + + config_add_boolean request_cui + config_add_array radius_auth_req_attr +@@ -351,6 +368,9 @@ hostapd_common_add_bss_config() { + + config_add_int eap_server + config_add_string eap_user_file ca_cert server_cert private_key private_key_passwd server_id + -+ config_add_boolean request_cui -+ config_add_array radius_auth_req_attr -+ config_add_array radius_acct_req_attr -+ -+ config_add_int eap_server -+ config_add_string eap_user_file ca_cert server_cert private_key private_key_passwd server_id -+ -+ config_add_boolean ratelimit ++ config_add_boolean fils ++ config_add_string fils_dhcp } hostapd_set_vlan_file() { -@@ -387,7 +416,7 @@ append_iw_anqp_3gpp_cell_net() { - if [ -z "$iw_anqp_3gpp_cell_net_conf" ]; then - iw_anqp_3gpp_cell_net_conf="$1" - else -- iw_anqp_3gpp_cell_net_conf="$iw_anqp_3gpp_cell_net_conf:$1" -+ iw_anqp_3gpp_cell_net_conf="$iw_anqp_3gpp_cell_net_conf;$1" - fi +@@ -488,11 +508,11 @@ append_hs20_conn_capab() { } -@@ -399,10 +428,22 @@ append_iw_nai_realm() { - [ -n "$1" ] && append bss_conf "nai_realm=$1" "$N" - } - -+append_iw_venue_name() { -+ append bss_conf "venue_name=$1" "$N" -+} -+ -+append_iw_venue_url() { -+ append bss_conf "venue_url=$1" "$N" -+} -+ - append_hs20_oper_friendly_name() { - append bss_conf "hs20_oper_friendly_name=$1" "$N" - } - -+append_osu_provider_friendly_name() { -+ append bss_conf "osu_friendly_name=$1" "$N" -+} -+ - append_osu_provider_service_desc() { - append bss_conf "osu_service_desc=$1" "$N" - } -@@ -450,6 +491,7 @@ append_osu_provider() { - append bss_conf "osu_method_list=$osu_method_list" "$N" - - config_list_foreach "$1" osu_service_desc append_osu_provider_service_desc -+ config_list_foreach "$1" osu_friendly_name append_osu_friendly_name - config_list_foreach "$1" osu_icon append_osu_icon - - append bss_conf "$N" -@@ -459,6 +501,14 @@ append_hs20_conn_capab() { - [ -n "$1" ] && append bss_conf "hs20_conn_capab=$1" "$N" - } - -+append_radius_acct_req_attr() { + append_radius_acct_req_attr() { +- append bss_conf "radius_acct_req_attr=$1" "$N" + [ -n "$1" ] && append bss_conf "radius_acct_req_attr=$1" "$N" -+} -+ -+append_radius_auth_req_attr() { -+ [ -n "$1" ] && append bss_conf "radius_auth_req_attr=$1" "$N" -+} -+ - append_airtime_sta_weight() { - [ -n "$1" ] && append bss_conf "airtime_sta_weight=$1" "$N" } -@@ -482,10 +532,12 @@ hostapd_set_bss_options() { + + append_radius_auth_req_attr() { +- append bss_conf "radius_auth_req_attr=$1" "$N" ++ [ -n "$1" ] && append bss_conf "radius_auth_req_attr=$1" "$N" + } + + append_airtime_sta_weight() { +@@ -518,13 +538,14 @@ hostapd_set_bss_options() { macfilter ssid utf8_ssid wmm uapsd hidden short_preamble rsn_preauth \ iapp_interface eapol_version dynamic_vlan ieee80211w nasid \ acct_server acct_secret acct_port acct_interval \ @@ -378,46 +396,26 @@ index aa72e09eba..fe6af98f4d 100644 + bss_load_update_period chan_util_avg_period sae_require_mfp sae_pwe \ multi_ap multi_ap_backhaul_ssid multi_ap_backhaul_key skip_inactivity_poll \ airtime_bss_weight airtime_bss_limit airtime_sta_weight \ -- multicast_to_unicast per_sta_vif +- multicast_to_unicast per_sta_vif \ + multicast_to_unicast proxy_arp per_sta_vif \ -+ eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id \ -+ vendor_elements + eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id \ +- vendor_elements ++ vendor_elements fils ++ set_default fils 0 set_default isolate 0 set_default maxassoc 0 -@@ -506,6 +558,7 @@ hostapd_set_bss_options() { - set_default multi_ap 0 - set_default airtime_bss_weight 0 + set_default max_inactivity 0 +@@ -546,6 +567,8 @@ hostapd_set_bss_options() { set_default airtime_bss_limit 0 -+ set_default eap_server 0 + set_default eap_server 0 ++ /usr/sbin/hostapd -vfils || fils=0 ++ append bss_conf "ctrl_interface=/var/run/hostapd" if [ "$isolate" -gt 0 ]; then -@@ -532,6 +585,7 @@ hostapd_set_bss_options() { - append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N" - append bss_conf "utf8_ssid=$utf8_ssid" "$N" - append bss_conf "multi_ap=$multi_ap" "$N" -+ [ -n "$vendor_elements" ] && append bss_conf "vendor_elements=$vendor_elements" "$N" - - [ "$tdls_prohibit" -gt 0 ] && append bss_conf "tdls_prohibit=$tdls_prohibit" "$N" - -@@ -550,19 +604,21 @@ hostapd_set_bss_options() { - append bss_conf "acct_server_shared_secret=$acct_secret" "$N" - [ -n "$acct_interval" ] && \ - append bss_conf "radius_acct_interim_interval=$acct_interval" "$N" -+ json_for_each_item append_radius_acct_req_attr radius_acct_req_attr - } - - case "$auth_type" in -- sae|owe|eap192|eap-eap192) -+ sae|owe|eap192|eap256) - set_default ieee80211w 2 - set_default sae_require_mfp 1 - ;; -- psk-sae) -+ psk-sae|eap-eap256) - set_default ieee80211w 1 - set_default sae_require_mfp 1 + append bss_conf "ap_isolate=$isolate" "$N" +@@ -604,6 +627,7 @@ hostapd_set_bss_options() { ;; esac [ -n "$sae_require_mfp" ] && append bss_conf "sae_require_mfp=$sae_require_mfp" "$N" @@ -425,205 +423,77 @@ index aa72e09eba..fe6af98f4d 100644 local vlan_possible="" -@@ -599,12 +655,12 @@ hostapd_set_bss_options() { - vlan_possible=1 - wps_possible=1 - ;; -- eap|eap192|eap-eap192) -+ eap|eap192|eap-eap256|eap256) - json_get_vars \ +@@ -645,7 +669,9 @@ hostapd_set_bss_options() { auth_server auth_secret auth_port \ dae_client dae_secret dae_port \ ownip radius_client_addr \ -- eap_reauth_period -+ eap_reauth_period request_cui +- eap_reauth_period request_cui ++ eap_reauth_period request_cui \ ++ erp_domain mobility_domain \ ++ fils_realm fils_dhcp # radius can provide VLAN ID for clients vlan_possible=1 -@@ -616,18 +672,22 @@ hostapd_set_bss_options() { +@@ -655,6 +681,30 @@ hostapd_set_bss_options() { + [ -n "$auth_port" ] || json_get_var auth_port port + [ -n "$auth_secret" ] || json_get_var auth_secret key ++ [ "$fils" -gt 0 ] && { ++ set_default erp_domain "$mobility_domain" ++ set_default erp_domain "$(echo "$ssid" | md5sum | head -c 8)" ++ set_default fils_realm "$erp_domain" ++ ++ append bss_conf "erp_send_reauth_start=1" "$N" ++ append bss_conf "erp_domain=$erp_domain" "$N" ++ append bss_conf "fils_realm=$fils_realm" "$N" ++ append bss_conf "fils_cache_id=$(echo "$fils_realm" | md5sum | head -c 4)" "$N" ++ ++ [ "$fils_dhcp" = "*" ] && { ++ json_get_values network network ++ fils_dhcp= ++ for net in $network; do ++ fils_dhcp="$(ifstatus "$net" | jsonfilter -e '@.data.dhcpserver')" ++ [ -n "$fils_dhcp" ] && break ++ done ++ ++ [ -z "$fils_dhcp" -a -n "$network_bridge" -a -n "$network_ifname" ] && \ ++ fils_dhcp="$(udhcpc -B -n -q -s /lib/netifd/dhcp-get-server.sh -t 1 -i "$network_ifname" 2>/dev/null)" ++ } ++ [ -n "$fils_dhcp" ] && append bss_conf "dhcp_server=$fils_dhcp" "$N" ++ } ++ set_default auth_port 1812 set_default dae_port 3799 -+ set_default request_cui 0 - -+ [ "$eap_server" -eq 0 ] && { -+ append bss_conf "auth_server_addr=$auth_server" "$N" -+ append bss_conf "auth_server_port=$auth_port" "$N" -+ append bss_conf "auth_server_shared_secret=$auth_secret" "$N" -+ } - -- append bss_conf "auth_server_addr=$auth_server" "$N" -- append bss_conf "auth_server_port=$auth_port" "$N" -- append bss_conf "auth_server_shared_secret=$auth_secret" "$N" -- -+ [ "$request_cui" -gt 0 ] && append bss_conf "radius_request_cui=$request_cui" "$N" - [ -n "$eap_reauth_period" ] && append bss_conf "eap_reauth_period=$eap_reauth_period" "$N" - - [ -n "$dae_client" -a -n "$dae_secret" ] && { - append bss_conf "radius_das_port=$dae_port" "$N" - append bss_conf "radius_das_client=$dae_client $dae_secret" "$N" - } -+ json_for_each_item append_radius_auth_req_attr radius_auth_req_attr - - [ -n "$ownip" ] && append bss_conf "own_ip_addr=$ownip" "$N" - [ -n "$radius_client_addr" ] && append bss_conf "radius_client_addr=$radius_client_addr" "$N" -@@ -699,7 +759,8 @@ hostapd_set_bss_options() { - } - - append bss_conf "ssid=$ssid" "$N" -- [ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge" "$N" -+ [ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge${N}wds_bridge=" "$N" -+ [ -n "$network_ifname" ] && append bss_conf "snoop_iface=$network_ifname" "$N" - [ -n "$iapp_interface" ] && { - local ifname - network_get_device ifname "$iapp_interface" || ifname="$iapp_interface" -@@ -740,7 +801,7 @@ hostapd_set_bss_options() { - append bss_conf "ftm_responder=1" "$N" - [ "$stationary_ap" -eq "1" ] && append bss_conf "stationary_ap=1" "$N" - [ -n "$lci" ] && append bss_conf "lci=$lci" "$N" -- [ -n "$civic" ] && append bss_conf "lci=$civic" "$N" -+ [ -n "$civic" ] && append bss_conf "civic=$civic" "$N" - } - fi - -@@ -764,6 +825,7 @@ hostapd_set_bss_options() { - ;; - esac - -+ [ -n "$network_ifname" ] && append bss_conf "ft_iface=$network_ifname" "$N" - append bss_conf "mobility_domain=$mobility_domain" "$N" - append bss_conf "ft_psk_generate_local=$ft_psk_generate_local" "$N" - append bss_conf "ft_over_ds=$ft_over_ds" "$N" -@@ -778,6 +840,13 @@ hostapd_set_bss_options() { - set_default r0_key_lifetime 10000 - set_default pmk_r1_push 0 - -+ [ -n "$r0kh" -a -n "$r1kh" ] || { -+ key=`echo -n "$mobility_domain/$auth_secret" | md5sum | awk '{print $1}'` -+ -+ set_default r0kh "ff:ff:ff:ff:ff:ff,*,$key" -+ set_default r1kh "00:00:00:00:00:00,00:00:00:00:00:00,$key" -+ } -+ - [ -n "$r1_key_holder" ] && append bss_conf "r1_key_holder=$r1_key_holder" "$N" - append bss_conf "r0_key_lifetime=$r0_key_lifetime" "$N" - append bss_conf "pmk_r1_push=$pmk_r1_push" "$N" -@@ -822,7 +891,16 @@ hostapd_set_bss_options() { - json_get_vars ieee80211w_mgmt_cipher ieee80211w_max_timeout ieee80211w_retry_timeout - append bss_conf "ieee80211w=$ieee80211w" "$N" - [ "$ieee80211w" -gt "0" ] && { -- append bss_conf "group_mgmt_cipher=${ieee80211w_mgmt_cipher:-AES-128-CMAC}" "$N" -+ case "$auth_type" in -+ eap192) -+ append bss_conf "group_mgmt_cipher=BIP-GMAC-256" "$N" -+ append bss_conf "group_cipher=GCMP-256" "$N" -+ ;; -+ *) -+ append bss_conf "group_mgmt_cipher=${ieee80211w_mgmt_cipher:-AES-128-CMAC}" "$N" -+ ;; -+ esac -+ - [ -n "$ieee80211w_max_timeout" ] && \ - append bss_conf "assoc_sa_query_max_timeout=$ieee80211w_max_timeout" "$N" - [ -n "$ieee80211w_retry_timeout" ] && \ -@@ -863,13 +941,17 @@ hostapd_set_bss_options() { - } - - [ -n "$vlan_possible" -a -n "$dynamic_vlan" ] && { -- json_get_vars vlan_naming vlan_tagged_interface vlan_bridge vlan_file -+ json_get_vars vlan_naming vlan_tagged_interface vlan_bridge vlan_file vlan_no_bridge - set_default vlan_naming 1 - [ -z "$vlan_file" ] && set_default vlan_file /var/run/hostapd-$ifname.vlan - append bss_conf "dynamic_vlan=$dynamic_vlan" "$N" - append bss_conf "vlan_naming=$vlan_naming" "$N" -- [ -n "$vlan_bridge" ] && \ -+ if [ -n "$vlan_bridge" ]; then - append bss_conf "vlan_bridge=$vlan_bridge" "$N" -+ else -+ set_default vlan_no_bridge 1 + set_default request_cui 0 +@@ -844,6 +894,10 @@ hostapd_set_bss_options() { + done + fi + fi ++ if [ "$fils" -gt 0 ]; then ++ json_get_vars fils_realm ++ set_default fils_realm "$(echo "$ssid" | md5sum | head -c 8)" + fi -+ append bss_conf "vlan_no_bridge=$vlan_no_bridge" "$N" - [ -n "$vlan_tagged_interface" ] && \ - append bss_conf "vlan_tagged_interface=$vlan_tagged_interface" "$N" - [ -n "$vlan_file" ] && { -@@ -882,6 +964,7 @@ hostapd_set_bss_options() { - json_get_vars iw_hessid iw_venue_group iw_venue_type iw_network_auth_type - json_get_vars iw_roaming_consortium iw_domain_name iw_anqp_3gpp_cell_net iw_nai_realm - json_get_vars iw_anqp_elem iw_qos_map_set iw_ipaddr_type_availability iw_gas_address3 -+ json_get_vars iw_venue_name iw_venue_url - set_default iw_enabled 0 - if [ "$iw_enabled" = "1" ]; then -@@ -905,11 +988,12 @@ hostapd_set_bss_options() { - [ -n "$iw_network_auth_type" ] && \ - append bss_conf "network_auth_type=$iw_network_auth_type" "$N" - [ -n "$iw_gas_address3" ] && append bss_conf "gas_address3=$iw_gas_address3" "$N" -- [ -n "$iw_qos_map_set" ] && append bss_conf "qos_map_set=$iw_qos_map_set" "$N" + append bss_conf "wpa_disable_eapol_key_retries=$wpa_disable_eapol_key_retries" "$N" - json_for_each_item append_iw_roaming_consortium iw_roaming_consortium - json_for_each_item append_iw_anqp_elem iw_anqp_elem - json_for_each_item append_iw_nai_realm iw_nai_realm -+ json_for_each_item append_iw_venue_name iw_venue_name -+ json_for_each_item append_iw_venue_url iw_venue_url +@@ -868,7 +922,7 @@ hostapd_set_bss_options() { + fi - iw_domain_name_conf= - json_for_each_item append_iw_domain_name iw_domain_name -@@ -922,13 +1006,22 @@ hostapd_set_bss_options() { - append bss_conf "anqp_3gpp_cell_net=$iw_anqp_3gpp_cell_net_conf" "$N" - fi + append bss_conf "okc=$auth_cache" "$N" +- [ "$auth_cache" = 0 ] && append bss_conf "disable_pmksa_caching=1" "$N" ++ [ "$auth_cache" = 0 -a "$fils" = 0 ] && append bss_conf "disable_pmksa_caching=1" "$N" -+ set_default iw_qos_map_set 0,0,2,16,1,1,255,255,18,22,24,38,40,40,44,46,48,56 -+ case "$iw_qos_map_set" in -+ *,*);; -+ *) iw_qos_map_set="";; -+ esac -+ [ -n "$iw_qos_map_set" ] && append bss_conf "qos_map_set=$iw_qos_map_set" "$N" + # RSN -> allow management frame protection + case "$ieee80211w" in +@@ -1022,6 +1076,7 @@ hostapd_set_bss_options() { - local hs20 disable_dgaf osen anqp_domain_id hs20_deauth_req_timeout \ -- osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp -+ osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp \ -+ hs20_t_c_server_url hs20_release - json_get_vars hs20 disable_dgaf osen anqp_domain_id hs20_deauth_req_timeout \ -- osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp -+ osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp \ -+ hs20_t_c_server_url hs20_release - - set_default hs20 0 -+ set_default hs20_release 1 - set_default disable_dgaf $hs20 - set_default osen 0 - set_default anqp_domain_id 0 -@@ -936,6 +1029,7 @@ hostapd_set_bss_options() { - if [ "$hs20" = "1" ]; then - append bss_conf "hs20=1" "$N" - append_hs20_icons -+ append bss_conf "hs20_release=$hs20_release" "$N" - append bss_conf "disable_dgaf=$disable_dgaf" "$N" - append bss_conf "osen=$osen" "$N" - append bss_conf "anqp_domain_id=$anqp_domain_id" "$N" -@@ -945,16 +1039,31 @@ hostapd_set_bss_options() { - [ -n "$hs20_operating_class" ] && append bss_conf "hs20_operating_class=$hs20_operating_class" "$N" - [ -n "$hs20_t_c_filename" ] && append bss_conf "hs20_t_c_filename=$hs20_t_c_filename" "$N" - [ -n "$hs20_t_c_timestamp" ] && append bss_conf "hs20_t_c_timestamp=$hs20_t_c_timestamp" "$N" -- json_for_each_item append_hs20_conn_capab hs20_conn_capab -+ [ -n "$hs20_t_c_server_url" ] && append bss_conf "hs20_t_c_server_url=$hs20_t_c_server_url" "$N" - json_for_each_item append_hs20_oper_friendly_name hs20_oper_friendly_name -+ json_for_each_item append_hs20_conn_capab hs20_conn_capab - json_for_each_item append_osu_provider osu_provider - json_for_each_item append_operator_icon operator_icon - fi - -+ if [ "$eap_server" = "1" ]; then -+ append bss_conf "eap_server=1" "$N" -+ [ -n "$eap_user_file" ] && append bss_conf "eap_user_file=$eap_user_file" "$N" -+ [ -n "$ca_cert" ] && append bss_conf "ca_cert=$ca_cert" "$N" -+ [ -n "$server_cert" ] && append bss_conf "server_cert=$server_cert" "$N" -+ [ -n "$private_key" ] && append bss_conf "private_key=$private_key" "$N" -+ [ -n "$private_key_passwd" ] && append bss_conf "private_key_passwd=$private_key_passwd" "$N" -+ [ -n "$server_id" ] && append bss_conf "server_id=$server_id" "$N" -+ fi -+ - set_default multicast_to_unicast 0 + if [ "$eap_server" = "1" ]; then + append bss_conf "eap_server=1" "$N" ++ append bss_conf "eap_server_erp=1" "$N" + [ -n "$eap_user_file" ] && append bss_conf "eap_user_file=$eap_user_file" "$N" + [ -n "$ca_cert" ] && append bss_conf "ca_cert=$ca_cert" "$N" + [ -n "$server_cert" ] && append bss_conf "server_cert=$server_cert" "$N" +@@ -1034,6 +1089,10 @@ hostapd_set_bss_options() { if [ "$multicast_to_unicast" -gt 0 ]; then append bss_conf "multicast_to_unicast=$multicast_to_unicast" "$N" fi @@ -634,45 +504,19 @@ index aa72e09eba..fe6af98f4d 100644 set_default per_sta_vif 0 if [ "$per_sta_vif" -gt 0 ]; then -@@ -1079,16 +1188,16 @@ wpa_supplicant_set_fixed_freq() { - append network_data "frequency=$freq" "$N$T" - case "$htmode" in - NOHT) append network_data "disable_ht=1" "$N$T";; -- HT20|VHT20) append network_data "disable_ht40=1" "$N$T";; -+ HT20|VHT20|HE20) append network_data "disable_ht40=1" "$N$T";; - HT40*|VHT40*|VHT80*|VHT160*) append network_data "ht40=1" "$N$T";; - esac - case "$htmode" in - VHT*) append network_data "vht=1" "$N$T";; - esac - case "$htmode" in -- VHT80) append network_data "max_oper_chwidth=1" "$N$T";; -- VHT160) append network_data "max_oper_chwidth=2" "$N$T";; -- VHT20|VHT40) append network_data "max_oper_chwidth=0" "$N$T";; -+ HE80|VHT80) append network_data "max_oper_chwidth=1" "$N$T";; -+ HE160|VHT160) append network_data "max_oper_chwidth=2" "$N$T";; -+ HE20|HE40|VHT20|VHT40) append network_data "max_oper_chwidth=0" "$N$T";; - *) append network_data "disable_vht=1" "$N$T";; - esac - } -@@ -1106,19 +1215,21 @@ wpa_supplicant_add_network() { +@@ -1184,8 +1243,9 @@ wpa_supplicant_add_network() { + json_get_vars \ ssid bssid key \ basic_rate mcast_rate \ - ieee80211w ieee80211r \ +- ieee80211w ieee80211r \ - multi_ap ++ ieee80211w ieee80211r fils \ + multi_ap \ + default_disabled case "$auth_type" in -- sae|owe|eap192|eap-eap192) -+ sae|owe|eap-eap256) - set_default ieee80211w 2 - ;; -- psk-sae) -+ psk-sae|eap192|eap256) - set_default ieee80211w 1 - ;; - esac + sae|owe|eap192|eap-eap192) +@@ -1198,6 +1258,7 @@ wpa_supplicant_add_network() { set_default ieee80211r 0 set_default multi_ap 0 @@ -680,7 +524,7 @@ index aa72e09eba..fe6af98f4d 100644 local key_mgmt='NONE' local network_data= -@@ -1150,7 +1261,10 @@ wpa_supplicant_add_network() { +@@ -1229,7 +1290,10 @@ wpa_supplicant_add_network() { scan_ssid="" } @@ -692,15 +536,72 @@ index aa72e09eba..fe6af98f4d 100644 case "$auth_type" in none) ;; -@@ -1186,7 +1300,7 @@ wpa_supplicant_add_network() { - fi - append network_data "$passphrase" "$N$T" - ;; -- eap|eap192|eap-eap192) -+ eap|eap192|eap-eap256|eap256) - hostapd_append_wpa_key_mgmt - key_mgmt="$wpa_key_mgmt" +@@ -1271,6 +1335,7 @@ wpa_supplicant_add_network() { + json_get_vars eap_type identity anonymous_identity ca_cert ca_cert_usesystem + ++ [ "$fils" -gt 0 ] && append network_data "erp=1" "$N$T" + if [ "$ca_cert_usesystem" -eq "1" -a -f "/etc/ssl/certs/ca-certificates.crt" ]; then + append network_data "ca_cert=\"/etc/ssl/certs/ca-certificates.crt\"" "$N$T" + else +diff --git a/package/network/services/hostapd/files/wpa_supplicant-full.config b/package/network/services/hostapd/files/wpa_supplicant-full.config +index b3e85d073d..de3302c875 100644 +--- a/package/network/services/hostapd/files/wpa_supplicant-full.config ++++ b/package/network/services/hostapd/files/wpa_supplicant-full.config +@@ -578,7 +578,7 @@ CONFIG_HS20=y + #CONFIG_MBO=y + + # Fast Initial Link Setup (FILS) (IEEE 802.11ai) +-#CONFIG_FILS=y ++CONFIG_FILS=y + # FILS shared key authentication with PFS + #CONFIG_FILS_SK_PFS=y + +diff --git a/package/network/services/hostapd/files/wpa_supplicant-p2p.config b/package/network/services/hostapd/files/wpa_supplicant-p2p.config +index b00847a256..48302bb4c3 100644 +--- a/package/network/services/hostapd/files/wpa_supplicant-p2p.config ++++ b/package/network/services/hostapd/files/wpa_supplicant-p2p.config +@@ -578,7 +578,7 @@ CONFIG_P2P=y + #CONFIG_MBO=y + + # Fast Initial Link Setup (FILS) (IEEE 802.11ai) +-#CONFIG_FILS=y ++CONFIG_FILS=y + # FILS shared key authentication with PFS + #CONFIG_FILS_SK_PFS=y + +diff --git a/package/network/services/hostapd/files/wps-hotplug.sh b/package/network/services/hostapd/files/wps-hotplug.sh +index d00939d769..073bdd1868 100644 +--- a/package/network/services/hostapd/files/wps-hotplug.sh ++++ b/package/network/services/hostapd/files/wps-hotplug.sh +@@ -38,13 +38,20 @@ wps_catch_credentials() { + done + } + +-if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" ]; then +- wps_done=0 +- ubusobjs="$( ubus -S list hostapd.* )" +- for ubusobj in $ubusobjs; do +- ubus -S call $ubusobj wps_start && wps_done=1 +- done +- [ $wps_done = 0 ] || return 0 ++if [ "$ACTION" = "released" ] && [ "$BUTTON" = "wps" ]; then ++ # If the button was pressed for 3 seconds or more, trigger WPS on ++ # wpa_supplicant only, no matter if hostapd is running or not. If ++ # was pressed for less than 3 seconds, try triggering on ++ # hostapd. If there is no hostapd instance to trigger it on or WPS ++ # is not enabled on them, trigger it on wpa_supplicant. ++ if [ "$SEEN" -lt 3 ] ; then ++ wps_done=0 ++ ubusobjs="$( ubus -S list hostapd.* )" ++ for ubusobj in $ubusobjs; do ++ ubus -S call $ubusobj wps_start && wps_done=1 ++ done ++ [ $wps_done = 0 ] || return 0 ++ fi + wps_done=0 + ubusobjs="$( ubus -S list wpa_supplicant.* )" + for ubusobj in $ubusobjs; do diff --git a/package/network/services/hostapd/patches/001-HE-VHT-fix-frequency-setup-with-HE-enabled.patch b/package/network/services/hostapd/patches/001-HE-VHT-fix-frequency-setup-with-HE-enabled.patch deleted file mode 100644 index 37c17c50af..0000000000 @@ -904,50 +805,9 @@ index 37c17c50af..0000000000 - if (ssid->mesh_basic_rates == NULL) { - /* diff --git a/package/network/services/hostapd/patches/802-wolfssl-init-RNG-with-ECC-key.patch b/package/network/services/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch -similarity index 76% +similarity index 100% rename from package/network/services/hostapd/patches/802-wolfssl-init-RNG-with-ECC-key.patch rename to package/network/services/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch -index 89d111e991..84fc1c9351 100644 ---- a/package/network/services/hostapd/patches/802-wolfssl-init-RNG-with-ECC-key.patch -+++ b/package/network/services/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch -@@ -14,11 +14,9 @@ Signed-off-by: David Bauer - src/crypto/crypto_wolfssl.c | 4 ++++ - 1 file changed, 4 insertions(+) - --diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c --index 2e4bf8962..ed2528159 100644 - --- a/src/crypto/crypto_wolfssl.c - +++ b/src/crypto/crypto_wolfssl.c --@@ -1303,6 +1303,7 @@ int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, -+@@ -1303,6 +1303,7 @@ int ecc_projective_add_point(ecc_point * - - struct crypto_ec { - ecc_key key; -@@ -26,7 +24,7 @@ index 2e4bf8962..ed2528159 100644 - mp_int a; - mp_int prime; - mp_int order; --@@ -1357,6 +1358,8 @@ struct crypto_ec * crypto_ec_init(int group) -+@@ -1357,6 +1358,8 @@ struct crypto_ec * crypto_ec_init(int gr - return NULL; - - if (wc_ecc_init(&e->key) != 0 || -@@ -35,7 +33,7 @@ index 2e4bf8962..ed2528159 100644 - wc_ecc_set_curve(&e->key, 0, curve_id) != 0 || - mp_init(&e->a) != MP_OKAY || - mp_init(&e->prime) != MP_OKAY || --@@ -1388,6 +1391,7 @@ void crypto_ec_deinit(struct crypto_ec* e) -+@@ -1388,6 +1391,7 @@ void crypto_ec_deinit(struct crypto_ec* - mp_clear(&e->order); - mp_clear(&e->prime); - mp_clear(&e->a); -@@ -43,6 +41,3 @@ index 2e4bf8962..ed2528159 100644 - wc_ecc_free(&e->key); - os_free(e); - } ---- --2.31.1 -- diff --git a/package/network/services/hostapd/patches/002-mesh-fix-channel-init-order-disable-pri-sec-channel-.patch b/package/network/services/hostapd/patches/002-mesh-fix-channel-init-order-disable-pri-sec-channel-.patch deleted file mode 100644 index c7101b1dbc..0000000000 @@ -2469,10 +2329,10 @@ index 1dd7d37411..0000000000 - return -ENOMEM; diff --git a/package/network/services/hostapd/patches/020-ignore-4addr-mode-enabling-error.patch b/package/network/services/hostapd/patches/020-ignore-4addr-mode-enabling-error.patch deleted file mode 100644 -index 3431ac0949..0000000000 +index f6751829a5..0000000000 --- a/package/network/services/hostapd/patches/020-ignore-4addr-mode-enabling-error.patch +++ /dev/null -@@ -1,78 +0,0 @@ +@@ -1,73 +0,0 @@ -From c7cca9b08f3e1e49c4a4a59ec66c47d91448e6ae Mon Sep 17 00:00:00 2001 -From: Jouni Malinen -Date: Sat, 13 Feb 2021 23:59:28 +0200 @@ -2493,8 +2353,6 @@ index 3431ac0949..0000000000 - src/drivers/driver_nl80211.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - --diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c --index 72189da24..011a15e68 100644 ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -617,6 +617,7 @@ struct wiphy_idx_data { @@ -2505,7 +2363,7 @@ index 3431ac0949..0000000000 - }; - - --@@ -639,6 +640,9 @@ static int netdev_info_handler(struct nl_msg *msg, void *arg) +-@@ -639,6 +640,9 @@ static int netdev_info_handler(struct nl - os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]), - ETH_ALEN); - @@ -2515,7 +2373,7 @@ index 3431ac0949..0000000000 - return NL_SKIP; - } - --@@ -691,6 +695,20 @@ static int nl80211_get_macaddr(struct i802_bss *bss) +-@@ -691,6 +695,20 @@ static int nl80211_get_macaddr(struct i8 - } - - @@ -2536,7 +2394,7 @@ index 3431ac0949..0000000000 - static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv, - struct nl80211_wiphy_data *w) - { --@@ -11482,6 +11500,11 @@ static int nl80211_set_4addr_mode(void *priv, const char *bridge_ifname, +-@@ -11508,6 +11526,11 @@ static int nl80211_set_4addr_mode(void * - - ret = send_and_recv_msgs(drv, msg, NULL, NULL); - msg = NULL; @@ -2548,14 +2406,11 @@ index 3431ac0949..0000000000 - if (!ret) { - if (bridge_ifname[0] && val && - i802_check_bridge(drv, bss, bridge_ifname, bss->ifname) < 0) ---- --2.29.2 -- diff --git a/package/network/services/hostapd/patches/050-mesh-make-forwarding-configurable.patch b/package/network/services/hostapd/patches/020-mesh-make-forwarding-configurable.patch similarity index 89% rename from package/network/services/hostapd/patches/050-mesh-make-forwarding-configurable.patch rename to package/network/services/hostapd/patches/020-mesh-make-forwarding-configurable.patch -index 0ecb9ba078..75726a6750 100644 +index 4d64ec8287..75726a6750 100644 --- a/package/network/services/hostapd/patches/050-mesh-make-forwarding-configurable.patch +++ b/package/network/services/hostapd/patches/020-mesh-make-forwarding-configurable.patch @@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle @@ -2589,7 +2444,7 @@ index 0ecb9ba078..75726a6750 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c --@@ -10023,6 +10023,9 @@ static int nl80211_put_mesh_config(struc +-@@ -10038,6 +10038,9 @@ static int nl80211_put_mesh_config(struc +@@ -10456,6 +10456,9 @@ static int nl80211_put_mesh_config(struc if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) && nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, @@ -2747,312 +2602,122 @@ index 0000000000..c7da33f029 + struct hostapd_hw_modes *mode; + + if (!params->channel) { -diff --git a/package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch b/package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch -new file mode 100644 -index 0000000000..9ff9b2398d ---- /dev/null -+++ b/package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch -@@ -0,0 +1,19 @@ -+From: Felix Fietkau -+Date: Wed, 28 Jul 2021 05:43:29 +0200 -+Subject: [PATCH] ndisc_snoop: call dl_list_del before freeing ipv6 addresses -+ -+Fixes a segmentation fault on sta disconnect -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/src/ap/ndisc_snoop.c -++++ b/src/ap/ndisc_snoop.c -+@@ -61,6 +61,7 @@ void sta_ip6addr_del(struct hostapd_data -+ dl_list_for_each_safe(ip6addr, prev, &sta->ip6addr, struct ip6addr, -+ list) { -+ hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) &ip6addr->addr); -++ dl_list_del(&ip6addr->list); -+ os_free(ip6addr); -+ } -+ } diff --git a/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch b/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch -new file mode 100644 -index 0000000000..e8a78e355e ---- /dev/null +index f65362fe96..e8a78e355e 100644 +--- a/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch +++ b/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch -@@ -0,0 +1,275 @@ -+From: Felix Fietkau -+Date: Wed, 28 Jul 2021 05:49:46 +0200 -+Subject: [PATCH] driver_nl80211: rewrite neigh code to not depend on -+ libnl3-route -+ -+Removes an unnecessary dependency and also makes the code smaller -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/src/drivers/driver_nl80211.c -++++ b/src/drivers/driver_nl80211.c -+@@ -16,9 +16,6 @@ -+ #include -+ #include -+ #include -+-#ifdef CONFIG_LIBNL3_ROUTE -+-#include -+-#endif /* CONFIG_LIBNL3_ROUTE */ -+ #include -+ #include -+ #include +@@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau + #include + #include + #include +-@@ -4965,26 +4962,29 @@ fail: +@@ -5284,26 +5281,29 @@ fail: -+ -+ static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) -+ { -+-#ifdef CONFIG_LIBNL3_ROUTE -+ struct wpa_driver_nl80211_data *drv = bss->drv; -+- struct rtnl_neigh *rn; -+- struct nl_addr *nl_addr; -++ struct ndmsg nhdr = { -++ .ndm_state = NUD_PERMANENT, -++ .ndm_ifindex = bss->ifindex, -++ .ndm_family = AF_BRIDGE, -++ }; -++ struct nl_msg *msg; -+ int err; -+ -+- rn = rtnl_neigh_alloc(); -+- if (!rn) -++ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE); -++ if (!msg) -+ return; -+ -+- rtnl_neigh_set_family(rn, AF_BRIDGE); -+- rtnl_neigh_set_ifindex(rn, bss->ifindex); -+- nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN); -+- if (!nl_addr) { -+- rtnl_neigh_put(rn); -+- return; -+- } -+- rtnl_neigh_set_lladdr(rn, nl_addr); -++ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) -++ goto errout; -++ -++ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr)) -++ goto errout; -++ -++ if (nl_send_auto_complete(drv->rtnl_sk, msg) < 0) -++ goto errout; -+ -+- err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0); -++ err = nl_wait_for_ack(drv->rtnl_sk); -+ if (err < 0) { -+ wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for " -+ MACSTR " ifindex=%d failed: %s", MAC2STR(addr), + + static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) + { +@@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau + if (err < 0) { + wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for " + MACSTR " ifindex=%d failed: %s", MAC2STR(addr), +-@@ -4994,9 +4994,8 @@ static void rtnl_neigh_delete_fdb_entry( +@@ -5313,9 +5313,8 @@ static void rtnl_neigh_delete_fdb_entry( -+ MACSTR, MAC2STR(addr)); -+ } -+ -+- nl_addr_put(nl_addr); -+- rtnl_neigh_put(rn); -+-#endif /* CONFIG_LIBNL3_ROUTE */ -++errout: -++ nlmsg_free(msg); -+ } -+ -+ + MACSTR, MAC2STR(addr)); + } + +@@ -76,7 +76,7 @@ Signed-off-by: Felix Fietkau + } + + +-@@ -7337,7 +7336,6 @@ static void *i802_init(struct hostapd_da +@@ -7691,7 +7690,6 @@ static void *i802_init(struct hostapd_da -+ (params->num_bridge == 0 || !params->bridge[0])) -+ add_ifidx(drv, br_ifindex, drv->ifindex); -+ -+-#ifdef CONFIG_LIBNL3_ROUTE -+ if (bss->added_if_into_bridge || bss->already_in_bridge) { -+ int err; -+ + (params->num_bridge == 0 || !params->bridge[0])) + add_ifidx(drv, br_ifindex, drv->ifindex); + +@@ -84,7 +84,7 @@ Signed-off-by: Felix Fietkau + if (bss->added_if_into_bridge || bss->already_in_bridge) { + int err; + +-@@ -7354,7 +7352,6 @@ static void *i802_init(struct hostapd_da +@@ -7708,7 +7706,6 @@ static void *i802_init(struct hostapd_da -+ goto failed; -+ } -+ } -+-#endif /* CONFIG_LIBNL3_ROUTE */ -+ -+ if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { -+ wpa_printf(MSG_DEBUG, + goto failed; + } + } +@@ -92,7 +92,7 @@ Signed-off-by: Felix Fietkau + + if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { + wpa_printf(MSG_DEBUG, +-@@ -10238,13 +10235,14 @@ static int wpa_driver_br_add_ip_neigh(vo +@@ -10655,13 +10652,14 @@ static int wpa_driver_br_add_ip_neigh(vo -+ const u8 *ipaddr, int prefixlen, -+ const u8 *addr) -+ { -+-#ifdef CONFIG_LIBNL3_ROUTE -+ struct i802_bss *bss = priv; -+ struct wpa_driver_nl80211_data *drv = bss->drv; -+- struct rtnl_neigh *rn; -+- struct nl_addr *nl_ipaddr = NULL; -+- struct nl_addr *nl_lladdr = NULL; -+- int family, addrsize; -++ struct ndmsg nhdr = { -++ .ndm_state = NUD_PERMANENT, -++ .ndm_ifindex = bss->br_ifindex, -++ }; -++ struct nl_msg *msg; -++ int addrsize; -+ int res; -+ -+ if (!ipaddr || prefixlen == 0 || !addr) + const u8 *ipaddr, int prefixlen, + const u8 *addr) + { +@@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau + int res; + + if (!ipaddr || prefixlen == 0 || !addr) +-@@ -10263,85 +10261,66 @@ static int wpa_driver_br_add_ip_neigh(vo +@@ -10680,85 +10678,66 @@ static int wpa_driver_br_add_ip_neigh(vo -+ } -+ -+ if (version == 4) { -+- family = AF_INET; -++ nhdr.ndm_family = AF_INET; -+ addrsize = 4; -+ } else if (version == 6) { -+- family = AF_INET6; -++ nhdr.ndm_family = AF_INET6; -+ addrsize = 16; -+ } else { -+ return -EINVAL; -+ } -+ -+- rn = rtnl_neigh_alloc(); -+- if (rn == NULL) -++ msg = nlmsg_alloc_simple(RTM_NEWNEIGH, NLM_F_CREATE); -++ if (!msg) -+ return -ENOMEM; -+ -+- /* set the destination ip address for neigh */ -+- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize); -+- if (nl_ipaddr == NULL) { -+- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed"); -+- res = -ENOMEM; -++ res = -ENOMEM; -++ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) -+ goto errout; -+- } -+- nl_addr_set_prefixlen(nl_ipaddr, prefixlen); -+- res = rtnl_neigh_set_dst(rn, nl_ipaddr); -+- if (res) { -+- wpa_printf(MSG_DEBUG, -+- "nl80211: neigh set destination addr failed"); -++ -++ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr)) -+ goto errout; -+- } -+ -+- /* set the corresponding lladdr for neigh */ -+- nl_lladdr = nl_addr_build(AF_BRIDGE, (u8 *) addr, ETH_ALEN); -+- if (nl_lladdr == NULL) { -+- wpa_printf(MSG_DEBUG, "nl80211: neigh set lladdr failed"); -+- res = -ENOMEM; -++ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr)) -+ goto errout; -+- } -+- rtnl_neigh_set_lladdr(rn, nl_lladdr); -+ -+- rtnl_neigh_set_ifindex(rn, bss->br_ifindex); -+- rtnl_neigh_set_state(rn, NUD_PERMANENT); -++ res = nl_send_auto_complete(drv->rtnl_sk, msg); -++ if (res < 0) -++ goto errout; -+ -+- res = rtnl_neigh_add(drv->rtnl_sk, rn, NLM_F_CREATE); -++ res = nl_wait_for_ack(drv->rtnl_sk); -+ if (res) { -+ wpa_printf(MSG_DEBUG, -+ "nl80211: Adding bridge ip neigh failed: %s", -+ nl_geterror(res)); -+ } -+ errout: -+- if (nl_lladdr) -+- nl_addr_put(nl_lladdr); -+- if (nl_ipaddr) -+- nl_addr_put(nl_ipaddr); -+- if (rn) -+- rtnl_neigh_put(rn); -++ nlmsg_free(msg); -+ return res; -+-#else /* CONFIG_LIBNL3_ROUTE */ -+- return -1; -+-#endif /* CONFIG_LIBNL3_ROUTE */ -+ } -+ -+ -+ static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version, -+ const u8 *ipaddr) -+ { -+-#ifdef CONFIG_LIBNL3_ROUTE -+ struct i802_bss *bss = priv; -+ struct wpa_driver_nl80211_data *drv = bss->drv; -+- struct rtnl_neigh *rn; -+- struct nl_addr *nl_ipaddr; -+- int family, addrsize; -++ struct ndmsg nhdr = { -++ .ndm_state = NUD_PERMANENT, -++ .ndm_ifindex = bss->br_ifindex, -++ }; -++ struct nl_msg *msg; -++ int addrsize; -+ int res; -+ -+ if (!ipaddr) -+ return -EINVAL; -+ -+ if (version == 4) { -+- family = AF_INET; -++ nhdr.ndm_family = AF_INET; -+ addrsize = 4; -+ } else if (version == 6) { -+- family = AF_INET6; -++ nhdr.ndm_family = AF_INET6; -+ addrsize = 16; -+ } else { -+ return -EINVAL; + } + + if (version == 4) { +@@ -220,7 +220,7 @@ Signed-off-by: Felix Fietkau + addrsize = 16; + } else { + return -EINVAL; +-@@ -10359,41 +10338,30 @@ static int wpa_driver_br_delete_ip_neigh +@@ -10776,41 +10755,30 @@ static int wpa_driver_br_delete_ip_neigh -+ return -1; -+ } -+ -+- rn = rtnl_neigh_alloc(); -+- if (rn == NULL) -++ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE); -++ if (!msg) -+ return -ENOMEM; -+ -+- /* set the destination ip address for neigh */ -+- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize); -+- if (nl_ipaddr == NULL) { -+- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed"); -+- res = -ENOMEM; -++ res = -ENOMEM; -++ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) -+ goto errout; -+- } -+- res = rtnl_neigh_set_dst(rn, nl_ipaddr); -+- if (res) { -+- wpa_printf(MSG_DEBUG, -+- "nl80211: neigh set destination addr failed"); -++ -++ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr)) -+ goto errout; -+- } -+ -+- rtnl_neigh_set_ifindex(rn, bss->br_ifindex); -++ res = nl_send_auto_complete(drv->rtnl_sk, msg); -++ if (res < 0) -++ goto errout; -+ -+- res = rtnl_neigh_delete(drv->rtnl_sk, rn, 0); -++ res = nl_wait_for_ack(drv->rtnl_sk); -+ if (res) { -+ wpa_printf(MSG_DEBUG, -+ "nl80211: Deleting bridge ip neigh failed: %s", -+ nl_geterror(res)); -+ } -+ errout: -+- if (nl_ipaddr) -+- nl_addr_put(nl_ipaddr); -+- if (rn) -+- rtnl_neigh_put(rn); -++ nlmsg_free(msg); -+ return res; -+-#else /* CONFIG_LIBNL3_ROUTE */ -+- return -1; -+-#endif /* CONFIG_LIBNL3_ROUTE */ -+ } -+ -+ + return -1; + } + +diff --git a/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch b/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch +index 55dd980cd7..6d9fd81acf 100644 +--- a/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch ++++ b/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch +@@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau + + --- a/src/ap/ieee802_11.c + +++ b/src/ap/ieee802_11.c +-@@ -2527,15 +2527,6 @@ static void handle_auth(struct hostapd_d ++@@ -3761,15 +3761,6 @@ static void handle_auth(struct hostapd_d + seq_ctrl); + return; + } +@@ -29,6 +29,6 @@ Signed-off-by: Felix Fietkau + - return; + - } + -#endif /* CONFIG_MESH */ +- } else { +- #ifdef CONFIG_MESH +- if (hapd->conf->mesh & MESH_ENABLED) { ++ #ifdef CONFIG_PASN ++ if (auth_alg == WLAN_AUTH_PASN && ++ (sta->flags & WLAN_STA_ASSOC)) { +diff --git a/package/network/services/hostapd/patches/050-build_fix.patch b/package/network/services/hostapd/patches/050-build_fix.patch +new file mode 100644 +index 0000000000..3da88fe290 +--- /dev/null ++++ b/package/network/services/hostapd/patches/050-build_fix.patch +@@ -0,0 +1,20 @@ ++--- a/hostapd/Makefile +++++ b/hostapd/Makefile ++@@ -323,6 +323,7 @@ ifdef CONFIG_FILS ++ CFLAGS += -DCONFIG_FILS ++ OBJS += ../src/ap/fils_hlp.o ++ NEED_SHA384=y +++NEED_HMAC_SHA384_KDF=y ++ NEED_AES_SIV=y ++ ifdef CONFIG_FILS_SK_PFS ++ CFLAGS += -DCONFIG_FILS_SK_PFS ++--- a/wpa_supplicant/Makefile +++++ b/wpa_supplicant/Makefile ++@@ -309,6 +309,7 @@ endif ++ ifdef CONFIG_FILS ++ CFLAGS += -DCONFIG_FILS ++ NEED_SHA384=y +++NEED_HMAC_SHA384_KDF=y ++ NEED_AES_SIV=y ++ ifdef CONFIG_FILS_SK_PFS ++ CFLAGS += -DCONFIG_FILS_SK_PFS diff --git a/package/network/services/hostapd/patches/060-P2P-Fix-a-corner-case-in-peer-addition-based-on-PD-R.patch b/package/network/services/hostapd/patches/060-P2P-Fix-a-corner-case-in-peer-addition-based-on-PD-R.patch deleted file mode 100644 index 1202ff3725..0000000000 @@ -3106,7 +2771,7 @@ index 1202ff3725..0000000000 - wpabuf_free(dev->info.wfd_subelems); diff --git a/package/network/services/hostapd/patches/110-notify-mgmt-frames.patch b/package/network/services/hostapd/patches/110-notify-mgmt-frames.patch deleted file mode 100644 -index 9e187253d4..0000000000 +index c3a66a7115..0000000000 --- a/package/network/services/hostapd/patches/110-notify-mgmt-frames.patch +++ /dev/null @@ -1,116 +0,0 @@ @@ -3175,7 +2840,7 @@ index 9e187253d4..0000000000 - ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c --@@ -4878,6 +4878,28 @@ static int handle_action(struct hostapd_ +-@@ -4869,6 +4869,28 @@ static int handle_action(struct hostapd_ - return 1; - } - @@ -3204,7 +2869,7 @@ index 9e187253d4..0000000000 - - /** - * ieee802_11_mgmt - process incoming IEEE 802.11 management frames --@@ -4969,6 +4991,9 @@ int ieee802_11_mgmt(struct hostapd_data +-@@ -4960,6 +4982,9 @@ int ieee802_11_mgmt(struct hostapd_data - if (hapd->iconf->track_sta_max_num) - sta_track_add(hapd->iface, mgmt->sa, ssi_signal); - @@ -3427,7 +3092,7 @@ index 1826b6685b..0000000000 - - int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg, diff --git a/package/network/services/hostapd/patches/200-multicall.patch b/package/network/services/hostapd/patches/200-multicall.patch -index 4f3e3decfe..8dce260871 100644 +index 9119a24c55..ceeaf5169b 100644 --- a/package/network/services/hostapd/patches/200-multicall.patch +++ b/package/network/services/hostapd/patches/200-multicall.patch @@ -1,14 +1,14 @@ @@ -3456,7 +3121,7 @@ index 4f3e3decfe..8dce260871 100644 OBJS += ../src/ap/vlan_ifconfig.o OBJS += ../src/ap/vlan.o -@@ -354,10 +356,14 @@ CFLAGS += -DCONFIG_MBO -+@@ -349,10 +351,14 @@ CFLAGS += -DCONFIG_MBO ++@@ -350,10 +352,14 @@ CFLAGS += -DCONFIG_MBO OBJS += ../src/ap/mbo_ap.o endif @@ -3467,7 +3132,7 @@ index 4f3e3decfe..8dce260871 100644 -@@ -1311,6 +1317,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR) - - BCHECK=../src/drivers/build.hostapd -+@@ -1277,6 +1283,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR) ++@@ -1278,6 +1284,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR) + _OBJS_VAR := OBJS + include ../src/objs.mk @@ -3484,7 +3149,7 @@ index 4f3e3decfe..8dce260871 100644 -@@ -1374,6 +1386,12 @@ SOBJS += ../src/crypto/sha256-kdf.o - SOBJS += ../src/crypto/sha384-kdf.o - SOBJS += ../src/crypto/sha512-kdf.o -+@@ -1351,6 +1363,12 @@ include ../src/objs.mk ++@@ -1352,6 +1364,12 @@ include ../src/objs.mk + _OBJS_VAR := SOBJS + include ../src/objs.mk @@ -3508,7 +3173,7 @@ index 4f3e3decfe..8dce260871 100644 - # Add VERSION_STR postfix for builds from a git repository -@@ -369,7 +370,9 @@ endif + ifdef LIBS -+@@ -359,7 +360,9 @@ endif ++@@ -360,7 +361,9 @@ endif ifdef CONFIG_IBSS_RSN NEED_RSN_AUTHENTICATOR=y CFLAGS += -DCONFIG_IBSS_RSN @@ -3517,7 +3182,7 @@ index 4f3e3decfe..8dce260871 100644 endif -@@ -890,6 +893,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS -+@@ -897,6 +900,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS ++@@ -898,6 +901,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS LIBS += -ldl -rdynamic endif @@ -3526,7 +3191,7 @@ index 4f3e3decfe..8dce260871 100644 ifdef CONFIG_AP -@@ -897,9 +904,11 @@ NEED_EAP_COMMON=y -+@@ -904,9 +911,11 @@ NEED_EAP_COMMON=y ++@@ -905,9 +912,11 @@ NEED_EAP_COMMON=y NEED_RSN_AUTHENTICATOR=y CFLAGS += -DCONFIG_AP OBJS += ap.o @@ -3535,7 +3200,7 @@ index 4f3e3decfe..8dce260871 100644 OBJS += ../src/ap/wpa_auth_glue.o OBJS += ../src/ap/utils.o -@@ -979,6 +988,12 @@ endif -+@@ -986,6 +995,12 @@ endif ++@@ -987,6 +996,12 @@ endif ifdef CONFIG_HS20 OBJS += ../src/ap/hs20.o endif @@ -3544,7 +3209,7 @@ index 4f3e3decfe..8dce260871 100644 ifdef CONFIG_MBO -@@ -987,7 +1002,9 @@ CFLAGS += -DCONFIG_MBO -+@@ -994,7 +1009,9 @@ CFLAGS += -DCONFIG_MBO ++@@ -995,7 +1010,9 @@ CFLAGS += -DCONFIG_MBO endif ifdef NEED_RSN_AUTHENTICATOR @@ -3555,7 +3220,7 @@ index 4f3e3decfe..8dce260871 100644 -@@ -1897,6 +1914,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) - - $(OBJS_c) $(OBJS_t) $(OBJS_t2) $(OBJS) $(BCHECK) $(EXTRA_progs): .config -+@@ -1889,6 +1906,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) ++@@ -1890,6 +1907,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) + _OBJS_VAR := OBJS + include ../src/objs.mk @@ -3567,7 +3232,7 @@ index 4f3e3decfe..8dce260871 100644 $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) @$(E) " LD " $@ -@@ -1997,6 +2020,12 @@ endif -+@@ -2021,6 +2044,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK) ++@@ -2022,6 +2045,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK) $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ @$(E) " sed" $< @@ -3611,7 +3276,7 @@ index 4f3e3decfe..8dce260871 100644 os_memset(&global, 0, sizeof(global)); --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c --@@ -4581,8 +4581,8 @@ static void wpas_event_unprot_beacon(str +-@@ -4579,8 +4579,8 @@ static void wpas_event_unprot_beacon(str +@@ -4665,8 +4665,8 @@ static void wpas_event_unprot_beacon(str } @@ -3620,7 +3285,7 @@ index 4f3e3decfe..8dce260871 100644 { struct wpa_supplicant *wpa_s = ctx; int resched; --@@ -5400,7 +5400,7 @@ void wpa_supplicant_event(void *ctx, enu +-@@ -5398,7 +5398,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -5511,7 +5511,7 @@ void wpa_supplicant_event(void *ctx, enu } @@ -3809,14 +3474,14 @@ index a703c7e132..01537790e0 100644 ifdef NEED_RFKILL DRV_OBJS += ../src/drivers/rfkill.o diff --git a/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch -index 9e2551ce60..9ced08801e 100644 +index ccd8589728..ca586d862c 100644 --- a/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch +++ b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch @@ -1,6 +1,6 @@ --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c --@@ -4646,7 +4646,7 @@ static int nl80211_set_channel(struct i8 -+@@ -4973,7 +4973,7 @@ static int nl80211_set_channel(struct i8 +-@@ -4661,7 +4661,7 @@ static int nl80211_set_channel(struct i8 ++@@ -4970,7 +4970,7 @@ static int nl80211_set_channel(struct i8 freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled, freq->bandwidth, freq->center_freq1, freq->center_freq2); @@ -3863,14 +3528,14 @@ index 90fa5eff5d..73f81f65e6 100644 #ifdef CONFIG_CTRL_IFACE diff --git a/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch -index a2a03c04f7..1f9b74e97e 100644 +index 076950fe35..656b744aa7 100644 --- a/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch +++ b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch @@ -1,6 +1,6 @@ --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c --@@ -2788,10 +2788,15 @@ static int wpa_driver_nl80211_del_beacon -+@@ -2918,10 +2918,15 @@ static int wpa_driver_nl80211_del_beacon +-@@ -2803,10 +2803,15 @@ static int wpa_driver_nl80211_del_beacon ++@@ -2915,10 +2915,15 @@ static int wpa_driver_nl80211_del_beacon struct nl_msg *msg; struct wpa_driver_nl80211_data *drv = bss->drv; @@ -3882,8 +3547,8 @@ index a2a03c04f7..1f9b74e97e 100644 + return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); } --@@ -5261,7 +5266,7 @@ static void nl80211_teardown_ap(struct i -+@@ -5602,7 +5607,7 @@ static void nl80211_teardown_ap(struct i +-@@ -5278,7 +5283,7 @@ static void nl80211_teardown_ap(struct i ++@@ -5601,7 +5606,7 @@ static void nl80211_teardown_ap(struct i nl80211_mgmt_unsubscribe(bss, "AP teardown"); nl80211_put_wiphy_data_ap(bss); @@ -3891,8 +3556,8 @@ index a2a03c04f7..1f9b74e97e 100644 } --@@ -7679,8 +7684,6 @@ static int wpa_driver_nl80211_if_remove( -+@@ -8051,8 +8056,6 @@ static int wpa_driver_nl80211_if_remove( +-@@ -7694,8 +7699,6 @@ static int wpa_driver_nl80211_if_remove( ++@@ -8048,8 +8053,6 @@ static int wpa_driver_nl80211_if_remove( } else { wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context"); nl80211_teardown_ap(bss); @@ -3900,8 +3565,8 @@ index a2a03c04f7..1f9b74e97e 100644 nl80211_destroy_bss(bss); if (!bss->added_if) i802_set_iface_flags(bss, 0); --@@ -8074,7 +8077,6 @@ static int wpa_driver_nl80211_deinit_ap( -+@@ -8449,7 +8452,6 @@ static int wpa_driver_nl80211_deinit_ap( +-@@ -8089,7 +8092,6 @@ static int wpa_driver_nl80211_deinit_ap( ++@@ -8446,7 +8449,6 @@ static int wpa_driver_nl80211_deinit_ap( if (!is_ap_interface(drv->nlmode)) return -1; wpa_driver_nl80211_del_beacon(bss); @@ -3909,8 +3574,8 @@ index a2a03c04f7..1f9b74e97e 100644 /* * If the P2P GO interface was dynamically added, then it is --@@ -8094,7 +8096,6 @@ static int wpa_driver_nl80211_stop_ap(vo -+@@ -8469,7 +8471,6 @@ static int wpa_driver_nl80211_stop_ap(vo +-@@ -8109,7 +8111,6 @@ static int wpa_driver_nl80211_stop_ap(vo ++@@ -8466,7 +8468,6 @@ static int wpa_driver_nl80211_stop_ap(vo if (!is_ap_interface(drv->nlmode)) return -1; wpa_driver_nl80211_del_beacon(bss); @@ -3963,7 +3628,7 @@ index 31c5102cb1..349522e06a 100644 int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd) { diff --git a/package/network/services/hostapd/patches/370-ap_sta_support.patch b/package/network/services/hostapd/patches/370-ap_sta_support.patch -index a7a646d2d1..c5cad3bb8d 100644 +index 1c5f72ddc0..535164d802 100644 --- a/package/network/services/hostapd/patches/370-ap_sta_support.patch +++ b/package/network/services/hostapd/patches/370-ap_sta_support.patch @@ -1,17 +1,6 @@ @@ -4092,16 +3757,20 @@ index a7a646d2d1..c5cad3bb8d 100644 #endif /* CONFIG_CTRL_IFACE_BINDER */ char bridge_ifname[16]; -@@ -246,7 +235,7 @@ +@@ -246,23 +235,24 @@ --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c -@@ -2712,6 +2712,11 @@ static int hostapd_ctrl_iface_chan_switc -+@@ -2883,6 +2883,11 @@ static int hostapd_ctrl_iface_chan_switc ++@@ -2883,6 +2883,12 @@ static int hostapd_ctrl_iface_chan_switc return 0; } -@@ -257,12 +246,12 @@ + + if (os_strstr(pos, " auto-ht")) { + + settings.freq_params.ht_enabled = iface->conf->ieee80211n; + + settings.freq_params.vht_enabled = iface->conf->ieee80211ac; +++ settings.freq_params.he_enabled = iface->conf->ieee80211ax; + + } + for (i = 0; i < iface->num_bss; i++) { @@ -4118,25 +3787,25 @@ index a7a646d2d1..c5cad3bb8d 100644 - if (hapd->csa_in_progress) { - wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period"); -@@ -274,7 +263,7 @@ +@@ -274,7 +264,7 @@ if (ieee802_11_build_ap_params(hapd, ¶ms) < 0) --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c --@@ -4581,6 +4581,60 @@ static void wpas_event_unprot_beacon(str +-@@ -4579,6 +4579,60 @@ static void wpas_event_unprot_beacon(str +@@ -4665,6 +4665,60 @@ static void wpas_event_unprot_beacon(str } -@@ -335,7 +324,7 @@ +@@ -335,7 +325,7 @@ void supplicant_event(void *ctx, enum wpa_event_type event, union wpa_event_data *data) { --@@ -4883,8 +4937,10 @@ void supplicant_event(void *ctx, enum wp +-@@ -4881,8 +4935,10 @@ void supplicant_event(void *ctx, enum wp +@@ -4980,8 +5034,10 @@ void supplicant_event(void *ctx, enum wp channel_width_to_string(data->ch_switch.ch_width), data->ch_switch.cf1, data->ch_switch.cf2); -@@ -349,7 +338,7 @@ +@@ -349,7 +339,7 @@ wpa_s->current_ssid->frequency = data->ch_switch.freq; --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -4145,7 +3814,7 @@ index a7a646d2d1..c5cad3bb8d 100644 /** * struct ch_switch -@@ -357,7 +346,7 @@ +@@ -357,7 +347,7 @@ * @freq: Frequency of new channel in MHz * @ht_enabled: Whether this is an HT channel * @ch_offset: Secondary channel offset @@ -4154,7 +3823,7 @@ index a7a646d2d1..c5cad3bb8d 100644 * @cf2: Center frequency 2 */ struct ch_switch { -@@ -367,7 +356,7 @@ +@@ -367,7 +357,7 @@ int ch_offset; --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -4163,7 +3832,7 @@ index a7a646d2d1..c5cad3bb8d 100644 struct nlattr *ifindex, struct nlattr *freq, struct nlattr *type, struct nlattr *bw, struct nlattr *cf1, struct nlattr *cf2, -@@ -376,7 +365,7 @@ +@@ -376,7 +366,7 @@ { struct i802_bss *bss; union wpa_event_data data; @@ -4172,7 +3841,7 @@ index a7a646d2d1..c5cad3bb8d 100644 data.ch_switch.cf1 = nla_get_u32(cf1); if (cf2) data.ch_switch.cf2 = nla_get_u32(cf2); -@@ -385,7 +374,7 @@ +@@ -385,7 +375,7 @@ if (finished) bss->freq = data.ch_switch.freq; @@ -4181,7 +3850,7 @@ index a7a646d2d1..c5cad3bb8d 100644 tb[NL80211_ATTR_CHANNEL_WIDTH], tb[NL80211_ATTR_CENTER_FREQ1], tb[NL80211_ATTR_CENTER_FREQ2], -@@ -393,7 +382,7 @@ +@@ -393,7 +383,7 @@ 0); break; case NL80211_CMD_CH_SWITCH_NOTIFY: @@ -4191,7 +3860,7 @@ index a7a646d2d1..c5cad3bb8d 100644 tb[NL80211_ATTR_CENTER_FREQ1], tb[NL80211_ATTR_CENTER_FREQ2], diff --git a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch -index b98b2d0cba..ca634077b7 100644 +index b98b2d0cba..81f7aa4952 100644 --- a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch +++ b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch @@ -1,6 +1,6 @@ @@ -4207,7 +3876,7 @@ index b98b2d0cba..ca634077b7 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c -@@ -3370,6 +3370,7 @@ static int hostapd_ctrl_iface_receive_pr -+@@ -3569,6 +3569,7 @@ static int hostapd_ctrl_iface_receive_pr ++@@ -3570,6 +3570,7 @@ static int hostapd_ctrl_iface_receive_pr reply_size); } else if (os_strcmp(buf, "STATUS-DRIVER") == 0) { reply_len = hostapd_drv_status(hapd, reply, reply_size); @@ -4216,7 +3885,7 @@ index b98b2d0cba..ca634077b7 100644 reply_len = ieee802_11_get_mib(hapd, reply, reply_size); if (reply_len >= 0) { -@@ -3411,6 +3412,7 @@ static int hostapd_ctrl_iface_receive_pr -+@@ -3610,6 +3611,7 @@ static int hostapd_ctrl_iface_receive_pr ++@@ -3611,6 +3612,7 @@ static int hostapd_ctrl_iface_receive_pr } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, reply_size); @@ -4225,7 +3894,7 @@ index b98b2d0cba..ca634077b7 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -952,6 +952,9 @@ ifdef CONFIG_FILS -+@@ -955,6 +955,9 @@ ifdef CONFIG_FILS ++@@ -956,6 +956,9 @@ ifdef CONFIG_FILS OBJS += ../src/ap/fils_hlp.o endif ifdef CONFIG_CTRL_IFACE @@ -4452,15 +4121,15 @@ index 99c552821b..e0e687e161 100644 else params.beacon_int = wpa_s->conf->beacon_int; diff --git a/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch b/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch -index 61d2089bc8..1d2a053faa 100644 +index b5dec991d0..b3c8b26461 100644 --- a/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch +++ b/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch @@ -10,7 +10,7 @@ Signed-hostap: Antonio Quartulli --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c --@@ -5584,7 +5584,7 @@ static int wpa_driver_nl80211_ibss(struc -+@@ -5951,7 +5951,7 @@ static int wpa_driver_nl80211_ibss(struc +-@@ -5601,7 +5601,7 @@ static int wpa_driver_nl80211_ibss(struc ++@@ -5950,7 +5950,7 @@ static int wpa_driver_nl80211_ibss(struc struct wpa_driver_associate_params *params) { struct nl_msg *msg; @@ -4468,13 +4137,13 @@ index 61d2089bc8..1d2a053faa 100644 int count = 0; wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex); --@@ -5611,6 +5611,37 @@ retry: -+@@ -5978,6 +5978,37 @@ retry: +-@@ -5628,6 +5628,37 @@ retry: ++@@ -5977,6 +5977,37 @@ retry: nl80211_put_beacon_int(msg, params->beacon_int)) goto fail; diff --git a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch -index 33ef097e75..1794befe95 100644 +index 7e21da263d..d9a6e74140 100644 --- a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch +++ b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch @@ -19,17 +19,17 @@ Tested-by: Simon Wunderlich @@ -4493,8 +4162,8 @@ index 33ef097e75..1794befe95 100644 struct wpa_driver_set_key_params { --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c --@@ -10043,6 +10043,18 @@ static int nl80211_put_mesh_id(struct nl -+@@ -10476,6 +10476,18 @@ static int nl80211_put_mesh_id(struct nl +-@@ -10058,6 +10058,18 @@ static int nl80211_put_mesh_id(struct nl ++@@ -10473,6 +10473,18 @@ static int nl80211_put_mesh_id(struct nl } @@ -4502,8 +4171,8 @@ index 33ef097e75..1794befe95 100644 static int nl80211_put_mesh_config(struct nl_msg *msg, struct wpa_driver_mesh_bss_params *params) { --@@ -10104,6 +10116,7 @@ static int nl80211_join_mesh(struct i802 -+@@ -10537,6 +10549,7 @@ static int nl80211_join_mesh(struct i802 +-@@ -10119,6 +10131,7 @@ static int nl80211_join_mesh(struct i802 ++@@ -10534,6 +10546,7 @@ static int nl80211_join_mesh(struct i802 nl80211_put_basic_rates(msg, params->basic_rates) || nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || nl80211_put_beacon_int(msg, params->beacon_int) || @@ -4542,14 +4211,14 @@ index 57a78ee865..efd82599d3 100644 { if (!(survey->filled & SURVEY_HAS_NF)) { diff --git a/package/network/services/hostapd/patches/500-lto-jobserver-support.patch b/package/network/services/hostapd/patches/500-lto-jobserver-support.patch -index 46030859de..1475590d06 100644 +index 46030859de..3f741cdf34 100644 --- a/package/network/services/hostapd/patches/500-lto-jobserver-support.patch +++ b/package/network/services/hostapd/patches/500-lto-jobserver-support.patch @@ -1,16 +1,17 @@ --- a/hostapd/Makefile +++ b/hostapd/Makefile -@@ -1327,14 +1327,14 @@ hostapd_multi.a: $(BCHECK) $(OBJS) -+@@ -1293,7 +1293,7 @@ hostapd_multi.a: $(BCHECK) $(OBJS) ++@@ -1294,7 +1294,7 @@ hostapd_multi.a: $(BCHECK) $(OBJS) @$(AR) cr $@ hostapd_multi.o $(OBJS) - hostapd: $(BCHECK) $(OBJS) @@ -4561,7 +4230,7 @@ index 46030859de..1475590d06 100644 ifdef CONFIG_WPA_TRACE - OBJS_c += ../src/utils/trace.o - endif -+@@ -1304,7 +1304,7 @@ _OBJS_VAR := OBJS_c ++@@ -1305,7 +1305,7 @@ _OBJS_VAR := OBJS_c + include ../src/objs.mk + hostapd_cli: $(OBJS_c) @@ -4572,7 +4241,7 @@ index 46030859de..1475590d06 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -1930,23 +1930,23 @@ wpa_supplicant_multi.a: .config $(BCHECK -+@@ -1918,31 +1918,31 @@ wpa_supplicant_multi.a: .config $(BCHECK ++@@ -1919,31 +1919,31 @@ wpa_supplicant_multi.a: .config $(BCHECK @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) @@ -4606,8 +4275,211 @@ index 46030859de..1475590d06 100644 wpa_cli: $(OBJS_c) - $(Q)$(LDO) $(LDFLAGS) -o wpa_cli $(OBJS_c) $(LIBS_c) + +$(Q)$(LDO) $(LDFLAGS) -o wpa_cli $(OBJS_c) $(LIBS_c) +diff --git a/package/network/services/hostapd/patches/550-WNM-allow-specifying-dialog-token.patch b/package/network/services/hostapd/patches/550-WNM-allow-specifying-dialog-token.patch +new file mode 100644 +index 0000000000..6c080adc0e +--- /dev/null ++++ b/package/network/services/hostapd/patches/550-WNM-allow-specifying-dialog-token.patch +@@ -0,0 +1,99 @@ ++From 1b26807938815d0b0b266caf31d8ef0019607e64 Mon Sep 17 00:00:00 2001 ++From: David Bauer ++Date: Mon, 27 Sep 2021 15:41:48 +0200 ++Subject: [PATCH] WNM: allow specifying dialog-token ++ ++This commit adds the ability to specify the dialog token of a WNM BSS ++Transition request frame via the hostapd control socket. ++ ++FOr this, the new 'dialog_token' option can be used. It accepts values ++as a 8 bit unsigned integer. If not specified, the dialog token is set ++to 1 like before. ++ ++Signed-off-by: David Bauer ++--- ++ hostapd/ctrl_iface.c | 10 ++++++++-- ++ src/ap/wnm_ap.c | 11 ++++++----- ++ src/ap/wnm_ap.h | 4 ++-- ++ 3 files changed, 16 insertions(+), 9 deletions(-) ++ ++--- a/hostapd/ctrl_iface.c +++++ b/hostapd/ctrl_iface.c ++@@ -897,7 +897,7 @@ static int hostapd_ctrl_iface_bss_tm_req ++ const char *pos, *end; ++ int disassoc_timer = 0; ++ struct sta_info *sta; ++- u8 req_mode = 0, valid_int = 0x01; +++ u8 req_mode = 0, valid_int = 0x01, dialog_token = 0x01; ++ u8 bss_term_dur[12]; ++ char *url = NULL; ++ int ret; ++@@ -935,6 +935,12 @@ static int hostapd_ctrl_iface_bss_tm_req ++ valid_int = atoi(pos); ++ } ++ +++ pos = os_strstr(cmd, " dialog_token="); +++ if (pos) { +++ pos += 14; +++ dialog_token = atoi(pos); +++ } +++ ++ pos = os_strstr(cmd, " bss_term="); ++ if (pos) { ++ pos += 10; ++@@ -1041,7 +1047,7 @@ static int hostapd_ctrl_iface_bss_tm_req ++ #endif /* CONFIG_MBO */ ++ ++ ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, ++- valid_int, bss_term_dur, url, +++ valid_int, bss_term_dur, dialog_token, url, ++ nei_len ? nei_rep : NULL, nei_len, ++ mbo_len ? mbo : NULL, mbo_len); ++ #ifdef CONFIG_MBO ++--- a/src/ap/wnm_ap.c +++++ b/src/ap/wnm_ap.c ++@@ -788,8 +788,8 @@ int wnm_send_ess_disassoc_imminent(struc ++ ++ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta, ++ u8 req_mode, int disassoc_timer, u8 valid_int, ++- const u8 *bss_term_dur, const char *url, ++- const u8 *nei_rep, size_t nei_rep_len, +++ const u8 *bss_term_dur, u8 dialog_token, +++ const char *url, const u8 *nei_rep, size_t nei_rep_len, ++ const u8 *mbo_attrs, size_t mbo_len) ++ { ++ u8 *buf, *pos; ++@@ -797,8 +797,9 @@ int wnm_send_bss_tm_req(struct hostapd_d ++ size_t url_len; ++ ++ wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to " ++- MACSTR " req_mode=0x%x disassoc_timer=%d valid_int=0x%x", ++- MAC2STR(sta->addr), req_mode, disassoc_timer, valid_int); +++ MACSTR " req_mode=0x%x disassoc_timer=%d valid_int=0x%x " +++ "dialog_token=%x", +++ MAC2STR(sta->addr), req_mode, disassoc_timer, valid_int, dialog_token); ++ buf = os_zalloc(1000 + nei_rep_len + mbo_len); ++ if (buf == NULL) ++ return -1; ++@@ -810,7 +811,7 @@ int wnm_send_bss_tm_req(struct hostapd_d ++ os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN); ++ mgmt->u.action.category = WLAN_ACTION_WNM; ++ mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ; ++- mgmt->u.action.u.bss_tm_req.dialog_token = 1; +++ mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token; ++ mgmt->u.action.u.bss_tm_req.req_mode = req_mode; ++ mgmt->u.action.u.bss_tm_req.disassoc_timer = ++ host_to_le16(disassoc_timer); ++--- a/src/ap/wnm_ap.h +++++ b/src/ap/wnm_ap.h ++@@ -20,8 +20,8 @@ int wnm_send_ess_disassoc_imminent(struc ++ int disassoc_timer); ++ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta, ++ u8 req_mode, int disassoc_timer, u8 valid_int, ++- const u8 *bss_term_dur, const char *url, ++- const u8 *nei_rep, size_t nei_rep_len, +++ const u8 *bss_term_dur, u8 dialog_token, +++ const char *url, const u8 *nei_rep, size_t nei_rep_len, ++ const u8 *mbo_attrs, size_t mbo_len); ++ void ap_sta_reset_steer_flag_timer(void *eloop_ctx, void *timeout_ctx); ++ int wnm_send_coloc_intf_req(struct hostapd_data *hapd, struct sta_info *sta, +diff --git a/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch b/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch +new file mode 100644 +index 0000000000..737fdbb5d0 +--- /dev/null ++++ b/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch +@@ -0,0 +1,92 @@ ++--- a/src/ap/hostapd.h +++++ b/src/ap/hostapd.h ++@@ -148,6 +148,21 @@ struct hostapd_sae_commit_queue { ++ }; ++ ++ /** +++ * struct hostapd_openwrt_stats - OpenWrt custom STA/AP statistics +++ */ +++struct hostapd_openwrt_stats { +++ struct { +++ u64 neighbor_report_tx; +++ } rrm; +++ +++ struct { +++ u64 bss_transition_query_rx; +++ u64 bss_transition_request_tx; +++ u64 bss_transition_response_rx; +++ } wnm; +++}; +++ +++/** ++ * struct hostapd_data - hostapd per-BSS data structure ++ */ ++ struct hostapd_data { ++@@ -161,6 +176,9 @@ struct hostapd_data { ++ ++ u8 own_addr[ETH_ALEN]; ++ +++ /* OpenWrt specific statistics */ +++ struct hostapd_openwrt_stats openwrt_stats; +++ ++ int num_sta; /* number of entries in sta_list */ ++ struct sta_info *sta_list; /* STA info list head */ ++ #define STA_HASH_SIZE 256 ++--- a/src/ap/wnm_ap.c +++++ b/src/ap/wnm_ap.c ++@@ -386,6 +386,7 @@ static int ieee802_11_send_bss_trans_mgm ++ mgmt->u.action.u.bss_tm_req.validity_interval = 1; ++ pos = mgmt->u.action.u.bss_tm_req.variable; ++ +++ hapd->openwrt_stats.wnm.bss_transition_request_tx++; ++ wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to " ++ MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u " ++ "validity_interval=%u", ++@@ -646,10 +647,12 @@ int ieee802_11_rx_wnm_action_ap(struct h ++ ++ switch (action) { ++ case WNM_BSS_TRANS_MGMT_QUERY: +++ hapd->openwrt_stats.wnm.bss_transition_query_rx++; ++ ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload, ++ plen); ++ return 0; ++ case WNM_BSS_TRANS_MGMT_RESP: +++ hapd->openwrt_stats.wnm.bss_transition_response_rx++; ++ ieee802_11_rx_bss_trans_mgmt_resp(hapd, mgmt->sa, payload, ++ plen); ++ return 0; ++@@ -696,6 +699,7 @@ int wnm_send_disassoc_imminent(struct ho ++ ++ pos = mgmt->u.action.u.bss_tm_req.variable; ++ +++ hapd->openwrt_stats.wnm.bss_transition_request_tx++; ++ wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request frame to indicate imminent disassociation (disassoc_timer=%d) to " ++ MACSTR, disassoc_timer, MAC2STR(sta->addr)); ++ if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) { ++@@ -777,6 +781,7 @@ int wnm_send_ess_disassoc_imminent(struc ++ return -1; ++ } ++ +++ hapd->openwrt_stats.wnm.bss_transition_request_tx++; ++ if (disassoc_timer) { ++ /* send disassociation frame after time-out */ ++ set_disassoc_timer(hapd, sta, disassoc_timer); ++@@ -856,6 +861,7 @@ int wnm_send_bss_tm_req(struct hostapd_d ++ } ++ os_free(buf); ++ +++ hapd->openwrt_stats.wnm.bss_transition_request_tx++; ++ if (disassoc_timer) { ++ /* send disassociation frame after time-out */ ++ set_disassoc_timer(hapd, sta, disassoc_timer); ++--- a/src/ap/rrm.c +++++ b/src/ap/rrm.c ++@@ -269,6 +269,8 @@ static void hostapd_send_nei_report_resp ++ } ++ } ++ +++ hapd->openwrt_stats.rrm.neighbor_report_tx++; +++ ++ hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, ++ wpabuf_head(buf), wpabuf_len(buf)); ++ wpabuf_free(buf); diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch -index 938840755a..005ed54e0c 100644 +index 53f521e649..b33fe8cda5 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -1,6 +1,6 @@ @@ -4618,12 +4490,21 @@ index 938840755a..005ed54e0c 100644 OBJS += ../src/eapol_auth/eapol_auth_sm.o +@@ -31,7 +31,7 @@ + }; + + enum hostapd_chan_status { +-@@ -154,6 +155,7 @@ struct hostapd_data { ++@@ -169,6 +170,7 @@ struct hostapd_data { + struct hostapd_iface *iface; + struct hostapd_config *iconf; + struct hostapd_bss_config *conf; @@ -39,7 +39,7 @@ int interface_added; /* virtual interface added for this BSS */ unsigned int started:1; unsigned int disabled:1; -@@ -606,6 +608,7 @@ hostapd_alloc_bss_data(struct hostapd_if -+@@ -610,6 +612,7 @@ hostapd_alloc_bss_data(struct hostapd_if ++@@ -628,6 +630,7 @@ hostapd_alloc_bss_data(struct hostapd_if struct hostapd_bss_config *bss); int hostapd_setup_interface(struct hostapd_iface *iface); int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); @@ -4694,8 +4575,8 @@ index 938840755a..005ed54e0c 100644 if (res == HOSTAPD_ACL_PENDING) return; --@@ -4166,7 +4178,7 @@ static void handle_assoc(struct hostapd_ -+@@ -5454,7 +5466,7 @@ static void handle_assoc(struct hostapd_ +-@@ -4157,7 +4169,7 @@ static void handle_assoc(struct hostapd_ ++@@ -5445,7 +5457,7 @@ static void handle_assoc(struct hostapd_ int resp = WLAN_STATUS_SUCCESS; - u16 reply_res; + u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; @@ -4705,8 +4586,8 @@ index 938840755a..005ed54e0c 100644 struct sta_info *sta; u8 *tmp = NULL; #ifdef CONFIG_FILS --@@ -4379,6 +4391,11 @@ static void handle_assoc(struct hostapd_ -+@@ -5667,6 +5679,11 @@ static void handle_assoc(struct hostapd_ +-@@ -4370,6 +4382,11 @@ static void handle_assoc(struct hostapd_ ++@@ -5658,6 +5670,11 @@ static void handle_assoc(struct hostapd_ left = res; } #endif /* CONFIG_FILS */ @@ -4714,37 +4595,38 @@ index 938840755a..005ed54e0c 100644 /* followed by SSID and Supported rates; and HT capabilities if 802.11n * is used */ --@@ -4543,6 +4560,14 @@ static void handle_assoc(struct hostapd_ -+@@ -5831,6 +5848,14 @@ static void handle_assoc(struct hostapd_ - pos, left, rssi, omit_rsnxe); - os_free(tmp); +-@@ -4468,6 +4485,14 @@ static void handle_assoc(struct hostapd_ ++@@ -5756,6 +5773,13 @@ static void handle_assoc(struct hostapd_ + } + #endif /* CONFIG_FILS */ -@@ -160,9 +160,9 @@ +@@ -158,11 +158,10 @@ + + resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE; + + goto fail; + } - + +-+ + fail: + /* -- * Remove the station in case tranmission of a success response fails -+ * Remove the station in case transmission of a success response fails - * (the STA was added associated to the driver) or if the station was --@@ -4570,6 +4595,7 @@ static void handle_disassoc(struct hosta -+@@ -5858,6 +5883,7 @@ static void handle_disassoc(struct hosta +-@@ -4561,6 +4586,7 @@ static void handle_disassoc(struct hosta ++@@ -5849,6 +5873,7 @@ static void handle_disassoc(struct hosta wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d", MAC2STR(mgmt->sa), le_to_host16(mgmt->u.disassoc.reason_code)); -@@ -170,9 +170,9 @@ +@@ -170,9 +169,9 @@ sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { --@@ -4636,6 +4662,8 @@ static void handle_deauth(struct hostapd +-@@ -4627,6 +4653,8 @@ static void handle_deauth(struct hostapd - " reason_code=%d", - MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code)); -+@@ -5927,6 +5953,8 @@ static void handle_deauth(struct hostapd ++@@ -5918,6 +5943,8 @@ static void handle_deauth(struct hostapd + /* Clear the PTKSA cache entries for PASN */ + ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE); + hostapd_ubus_notify(hapd, "deauth", mgmt->sa); + -@@ -181,7 +181,7 @@ +@@ -181,7 +180,7 @@ wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying " --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -4753,7 +4635,7 @@ index 938840755a..005ed54e0c 100644 u16 csa_offs[2]; size_t csa_offs_len; struct radius_sta rad_info; -@@ -192,9 +192,9 @@ +@@ -192,9 +191,9 @@ + .elems = &elems, + }; @@ -4766,7 +4648,7 @@ index 938840755a..005ed54e0c 100644 } #endif /* CONFIG_P2P */ -@@ -209,7 +209,7 @@ +@@ -209,7 +208,7 @@ --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -4775,7 +4657,7 @@ index 938840755a..005ed54e0c 100644 u16 reason = WLAN_REASON_UNSPECIFIED; int status = WLAN_STATUS_SUCCESS; const u8 *p2p_dev_addr = NULL; -@@ -220,7 +220,7 @@ +@@ -220,7 +219,7 @@ if (addr == NULL) { /* @@ -4784,34 +4666,34 @@ index 938840755a..005ed54e0c 100644 goto fail; } -@@ -235,7 +235,7 @@ +@@ -235,7 +234,7 @@ wpabuf_free(sta->p2p_ie); --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c --@@ -424,6 +424,7 @@ void ap_handle_timer(void *eloop_ctx, vo -+@@ -459,6 +459,7 @@ void ap_handle_timer(void *eloop_ctx, vo +-@@ -423,6 +423,7 @@ void ap_handle_timer(void *eloop_ctx, vo ++@@ -458,6 +458,7 @@ void ap_handle_timer(void *eloop_ctx, vo + hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "local deauth request"); +@@ -243,7 +242,7 @@ ap_free_sta(hapd, sta); -@@ -243,7 +243,7 @@ return; } - --@@ -579,6 +580,7 @@ skip_poll: -+@@ -614,6 +615,7 @@ skip_poll: +-@@ -578,6 +579,7 @@ skip_poll: ++@@ -613,6 +614,7 @@ skip_poll: + mlme_deauthenticate_indication( hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); +@@ -251,7 +250,7 @@ ap_free_sta(hapd, sta); -@@ -251,7 +251,7 @@ break; } - } -@@ -1294,6 +1296,7 @@ void ap_sta_set_authorized(struct hostap +@@ -1329,6 +1331,7 @@ void ap_sta_set_authorized(struct hostap buf, ip_addr, keyid_buf); } else { wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); -@@ -261,7 +261,7 @@ +@@ -261,7 +260,7 @@ hapd->msg_ctx_parent != hapd->msg_ctx) --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -4820,7 +4702,7 @@ index 938840755a..005ed54e0c 100644 struct hostapd_data *hapd = ctx; wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, MAC2STR(addr)); -@@ -271,7 +271,7 @@ +@@ -271,7 +270,7 @@ --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -4829,16 +4711,16 @@ index 938840755a..005ed54e0c 100644 CFLAGS += -Werror -DEAPOL_TEST endif -@@ -284,7 +284,7 @@ +@@ -284,7 +283,7 @@ ifdef CONFIG_CODE_COVERAGE CFLAGS += -O0 -fprofile-arcs -ftest-coverage LIBS += -lgcov -@@ -956,6 +962,9 @@ ifdef CONFIG_CTRL_IFACE_MIB -+@@ -959,6 +965,9 @@ ifdef CONFIG_CTRL_IFACE_MIB ++@@ -960,6 +966,9 @@ ifdef CONFIG_CTRL_IFACE_MIB CFLAGS += -DCONFIG_CTRL_IFACE_MIB endif OBJS += ../src/ap/ctrl_iface_ap.o -@@ -296,7 +296,7 @@ +@@ -296,7 +295,7 @@ CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -4847,7 +4729,7 @@ index 938840755a..005ed54e0c 100644 } #endif /* CONFIG_P2P */ -@@ -305,7 +305,7 @@ +@@ -305,7 +304,7 @@ return wpa_s; } @@ -4856,7 +4738,7 @@ index 938840755a..005ed54e0c 100644 struct wpa_supplicant *parent = wpa_s->parent; #endif /* CONFIG_MESH */ -@@ -314,7 +314,7 @@ +@@ -314,7 +313,7 @@ /* Remove interface from the global list of interfaces */ prev = global->ifaces; if (prev == wpa_s) { @@ -4865,7 +4747,7 @@ index 938840755a..005ed54e0c 100644 eloop_register_signal_terminate(wpa_supplicant_terminate, global); eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); -@@ -329,7 +329,7 @@ +@@ -329,7 +328,7 @@ --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -4874,7 +4756,7 @@ index 938840755a..005ed54e0c 100644 #include "wps/wps_defs.h" #include "config_ssid.h" #include "wmm_ac.h" -@@ -337,7 +337,7 @@ +@@ -337,7 +336,7 @@ extern const char *const wpa_supplicant_version; extern const char *const wpa_supplicant_license; @@ -4883,7 +4765,7 @@ index 938840755a..005ed54e0c 100644 #endif /* CONFIG_WIFI_DISPLAY */ struct psk_list_entry *add_psk; /* From group formation */ -@@ -346,7 +346,7 @@ +@@ -346,7 +345,7 @@ }; @@ -4892,7 +4774,7 @@ index 938840755a..005ed54e0c 100644 unsigned char own_addr[ETH_ALEN]; unsigned char perm_addr[ETH_ALEN]; char ifname[100]; -@@ -375,7 +375,7 @@ +@@ -375,7 +374,7 @@ --- a/hostapd/main.c +++ b/hostapd/main.c @@ -4901,7 +4783,7 @@ index 938840755a..005ed54e0c 100644 } hostapd_global_ctrl_iface_init(&interfaces); -@@ -383,7 +383,7 @@ +@@ -383,7 +382,7 @@ if (hostapd_global_run(&interfaces, daemonize, pid_file)) { wpa_printf(MSG_ERROR, "Failed to start eloop"); @@ -4910,7 +4792,7 @@ index 938840755a..005ed54e0c 100644 ret = 0; out: -@@ -424,3 +424,93 @@ +@@ -424,3 +423,133 @@ } @@ -5004,8 +4886,87 @@ index 938840755a..005ed54e0c 100644 + struct os_reltime backlogged_until; + #endif /* CONFIG_AIRTIME_POLICY */ + ++--- a/src/ap/wnm_ap.c +++++ b/src/ap/wnm_ap.c ++@@ -442,7 +442,8 @@ static void ieee802_11_rx_bss_trans_mgmt ++ wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", ++ pos, end - pos); ++ ++- ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); +++ if (!hostapd_ubus_notify_bss_transition_query(hapd, addr, dialog_token, reason, pos, end - pos)) +++ ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); ++ } ++ ++ ++@@ -464,7 +465,7 @@ static void ieee802_11_rx_bss_trans_mgmt ++ size_t len) ++ { ++ u8 dialog_token, status_code, bss_termination_delay; ++- const u8 *pos, *end; +++ const u8 *pos, *end, *target_bssid = NULL; ++ int enabled = hapd->conf->bss_transition; ++ struct sta_info *sta; ++ ++@@ -511,6 +512,7 @@ static void ieee802_11_rx_bss_trans_mgmt ++ wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field"); ++ return; ++ } +++ target_bssid = pos; ++ sta->agreed_to_steer = 1; ++ eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta); ++ eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer, ++@@ -530,6 +532,10 @@ static void ieee802_11_rx_bss_trans_mgmt ++ MAC2STR(addr), status_code, bss_termination_delay); ++ } ++ +++ hostapd_ubus_notify_bss_transition_response(hapd, sta->addr, dialog_token, +++ status_code, bss_termination_delay, +++ target_bssid, pos, end - pos); +++ ++ wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", ++ pos, end - pos); ++ } +diff --git a/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch b/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch +new file mode 100644 +index 0000000000..a03fcc9f92 +--- /dev/null ++++ b/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch +@@ -0,0 +1,33 @@ ++--- a/src/common/wpa_ctrl.c +++++ b/src/common/wpa_ctrl.c ++@@ -135,7 +135,7 @@ try_again: ++ return NULL; ++ } ++ tries++; ++-#ifdef ANDROID +++ ++ /* Set client socket file permissions so that bind() creates the client ++ * socket with these permissions and there is no need to try to change ++ * them with chmod() after bind() which would have potential issues with ++@@ -147,7 +147,7 @@ try_again: ++ * operations to allow the response to go through. Those are using the ++ * no-deference-symlinks version to avoid races. */ ++ fchmod(ctrl->s, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); ++-#endif /* ANDROID */ +++ ++ if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, ++ sizeof(ctrl->local)) < 0) { ++ if (errno == EADDRINUSE && tries < 2) { ++@@ -165,7 +165,11 @@ try_again: ++ return NULL; ++ } ++ ++-#ifdef ANDROID +++#ifndef ANDROID +++ /* Set group even if we do not have privileges to change owner */ +++ lchown(ctrl->local.sun_path, -1, 101); +++ lchown(ctrl->local.sun_path, 101, 101); +++#else ++ /* Set group even if we do not have privileges to change owner */ ++ lchown(ctrl->local.sun_path, -1, AID_WIFI); ++ lchown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI); diff --git a/package/network/services/hostapd/patches/700-wifi-reload.patch b/package/network/services/hostapd/patches/700-wifi-reload.patch -index d5520d0b77..5993b0d445 100644 +index ceb92265dd..29ac5923df 100644 --- a/package/network/services/hostapd/patches/700-wifi-reload.patch +++ b/package/network/services/hostapd/patches/700-wifi-reload.patch @@ -1,6 +1,6 @@ @@ -5128,12 +5089,21 @@ index d5520d0b77..5993b0d445 100644 hapd->iconf = conf; hapd->conf = bss; hapd->iface = hapd_iface; +@@ -155,7 +156,7 @@ + struct hostapd_config * (*config_read_cb)(const char *config_fname); + int (*ctrl_iface_init)(struct hostapd_data *hapd); + void (*ctrl_iface_deinit)(struct hostapd_data *hapd); +-@@ -156,6 +156,7 @@ struct hostapd_data { ++@@ -171,6 +171,7 @@ struct hostapd_data { + struct hostapd_config *iconf; + struct hostapd_bss_config *conf; + struct hostapd_ubus_bss ubus; @@ -163,7 +164,7 @@ int interface_added; /* virtual interface added for this BSS */ unsigned int started:1; unsigned int disabled:1; -@@ -600,7 +601,7 @@ struct hostapd_iface { -+@@ -604,7 +605,7 @@ struct hostapd_iface { ++@@ -622,7 +623,7 @@ struct hostapd_iface { int hostapd_for_each_interface(struct hapd_interfaces *interfaces, int (*cb)(struct hostapd_iface *iface, void *ctx), void *ctx); @@ -5141,8 +5111,8 @@ index d5520d0b77..5993b0d445 100644 hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c --@@ -4493,6 +4493,9 @@ static int wpa_driver_nl80211_set_ap(voi -+@@ -4820,6 +4820,9 @@ static int wpa_driver_nl80211_set_ap(voi +-@@ -4508,6 +4508,9 @@ static int wpa_driver_nl80211_set_ap(voi ++@@ -4817,6 +4817,9 @@ static int wpa_driver_nl80211_set_ap(voi if (ret) { wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)", ret, strerror(-ret)); @@ -5156,30 +5126,27 @@ index d5520d0b77..5993b0d445 100644 reload_opts = txt; diff --git a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch -new file mode 100644 -index 0000000000..73db32e54a ---- /dev/null +index 7de4e2c1d4..73db32e54a 100644 +--- a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch +++ b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch -@@ -0,0 +1,41 @@ -+--- a/src/ap/ap_config.h -++++ b/src/ap/ap_config.h -+@@ -115,6 +115,7 @@ struct hostapd_ssid { -+ #define DYNAMIC_VLAN_OPTIONAL 1 -+ #define DYNAMIC_VLAN_REQUIRED 2 -+ int dynamic_vlan; -++ int vlan_no_bridge; -+ #define DYNAMIC_VLAN_NAMING_WITHOUT_DEVICE 0 -+ #define DYNAMIC_VLAN_NAMING_WITH_DEVICE 1 -+ #define DYNAMIC_VLAN_NAMING_END 2 -+--- a/src/ap/vlan_full.c -++++ b/src/ap/vlan_full.c +@@ -10,19 +10,27 @@ + #define DYNAMIC_VLAN_NAMING_END 2 + --- a/src/ap/vlan_full.c + +++ b/src/ap/vlan_full.c +-@@ -466,6 +466,9 @@ void vlan_newlink(const char *ifname, st +- +- wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname); +@@ -475,6 +475,9 @@ void vlan_newlink(const char *ifname, st + if (!vlan) + return; -+ -++ if (hapd->conf->ssid.vlan_no_bridge) + + + if (hapd->conf->ssid.vlan_no_bridge) +-+ return; ++ goto out; -++ + + +- for (vlan = hapd->conf->vlan; vlan; vlan = vlan->next) { +- if (vlan->configured || +- os_strcmp(ifname, vlan->ifname) != 0) + vlan->configured = 1; + + notempty = vlan->vlan_desc.notempty; @@ -5191,49 +5158,25 @@ index 0000000000..73db32e54a + ifconfig_up(ifname); + } + -+--- a/hostapd/config_file.c -++++ b/hostapd/config_file.c + --- a/hostapd/config_file.c + +++ b/hostapd/config_file.c +-@@ -3400,6 +3400,8 @@ static int hostapd_config_fill(struct ho +@@ -3366,6 +3366,8 @@ static int hostapd_config_fill(struct ho -+ #ifndef CONFIG_NO_VLAN -+ } else if (os_strcmp(buf, "dynamic_vlan") == 0) { -+ bss->ssid.dynamic_vlan = atoi(pos); -++ } else if (os_strcmp(buf, "vlan_no_bridge") == 0) { -++ bss->ssid.vlan_no_bridge = atoi(pos); -+ } else if (os_strcmp(buf, "per_sta_vif") == 0) { -+ bss->ssid.per_sta_vif = atoi(pos); -+ } else if (os_strcmp(buf, "vlan_file") == 0) { + #ifndef CONFIG_NO_VLAN + } else if (os_strcmp(buf, "dynamic_vlan") == 0) { + bss->ssid.dynamic_vlan = atoi(pos); diff --git a/package/network/services/hostapd/patches/711-wds_bridge_force.patch b/package/network/services/hostapd/patches/711-wds_bridge_force.patch -new file mode 100644 -index 0000000000..76a3547805 ---- /dev/null +index 01507b6d36..d3f8864a74 100644 +--- a/package/network/services/hostapd/patches/711-wds_bridge_force.patch +++ b/package/network/services/hostapd/patches/711-wds_bridge_force.patch -@@ -0,0 +1,26 @@ -+Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c -+=================================================================== -+--- hostapd-2021-05-22-b102f19b.orig/hostapd/config_file.c -++++ hostapd-2021-05-22-b102f19b/hostapd/config_file.c +@@ -1,6 +1,6 @@ + --- a/hostapd/config_file.c + +++ b/hostapd/config_file.c +-@@ -2405,6 +2405,8 @@ static int hostapd_config_fill(struct ho +@@ -2357,6 +2357,8 @@ static int hostapd_config_fill(struct ho -+ sizeof(conf->bss[0]->iface)); -+ } else if (os_strcmp(buf, "bridge") == 0) { -+ os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); -++ if (!bss->wds_bridge[0]) -++ os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); -+ } else if (os_strcmp(buf, "vlan_bridge") == 0) { -+ os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); -+ } else if (os_strcmp(buf, "wds_bridge") == 0) { -+Index: hostapd-2021-05-22-b102f19b/src/ap/ap_drv_ops.c -+=================================================================== -+--- hostapd-2021-05-22-b102f19b.orig/src/ap/ap_drv_ops.c -++++ hostapd-2021-05-22-b102f19b/src/ap/ap_drv_ops.c -+@@ -340,8 +340,6 @@ int hostapd_set_wds_sta(struct hostapd_d -+ return -1; -+ if (hapd->conf->wds_bridge[0]) -+ bridge = hapd->conf->wds_bridge; -+- else if (hapd->conf->bridge[0]) -+- bridge = hapd->conf->bridge; -+ return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val, -+ bridge, ifname_wds); -+ } + sizeof(conf->bss[0]->iface)); + } else if (os_strcmp(buf, "bridge") == 0) { + os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); diff --git a/package/network/services/hostapd/patches/720-ACS-fix-channel-100-frequency.patch b/package/network/services/hostapd/patches/720-ACS-fix-channel-100-frequency.patch new file mode 100644 index 0000000000..3ef19e5298 @@ -5272,13 +5215,13 @@ index 0000000000..3ef19e5298 + unsigned int i; diff --git a/package/network/services/hostapd/patches/720-iface_max_num_sta.patch b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch new file mode 100644 -index 0000000000..b93a0bcbef +index 0000000000..3778357ac6 --- /dev/null +++ b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch @@ -0,0 +1,82 @@ +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c -+@@ -2873,6 +2873,14 @@ static int hostapd_config_fill(struct ho ++@@ -2875,6 +2875,14 @@ static int hostapd_config_fill(struct ho + line, bss->max_num_sta, MAX_STA_COUNT); + return 1; + } @@ -5295,7 +5238,7 @@ index 0000000000..b93a0bcbef + } else if (os_strcmp(buf, "extended_key_id") == 0) { +--- a/src/ap/hostapd.h ++++ b/src/ap/hostapd.h -+@@ -648,6 +648,7 @@ void hostapd_cleanup_cs_params(struct ho ++@@ -666,6 +666,7 @@ void hostapd_cleanup_cs_params(struct ho + void hostapd_periodic_iface(struct hostapd_iface *iface); + int hostapd_owe_trans_get_info(struct hostapd_data *hapd); + void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); @@ -5359,127 +5302,224 @@ index 0000000000..b93a0bcbef + * ISO/IEC 3166-1. Third octet: + * ' ' (ascii 32): all environments diff --git a/package/network/services/hostapd/patches/730-ft_iface.patch b/package/network/services/hostapd/patches/730-ft_iface.patch -new file mode 100644 -index 0000000000..793e8e0194 ---- /dev/null +index c1adf1ffcf..0a1a16d6e3 100644 +--- a/package/network/services/hostapd/patches/730-ft_iface.patch +++ b/package/network/services/hostapd/patches/730-ft_iface.patch -@@ -0,0 +1,38 @@ -+--- a/hostapd/config_file.c -++++ b/hostapd/config_file.c -+@@ -3031,6 +3031,8 @@ static int hostapd_config_fill(struct ho -+ wpa_printf(MSG_INFO, -+ "Line %d: Obsolete peerkey parameter ignored", line); -+ #ifdef CONFIG_IEEE80211R_AP -++ } else if (os_strcmp(buf, "ft_iface") == 0) { -++ os_strlcpy(bss->ft_iface, pos, sizeof(bss->ft_iface)); -+ } else if (os_strcmp(buf, "mobility_domain") == 0) { -+ if (os_strlen(pos) != 2 * MOBILITY_DOMAIN_ID_LEN || -+ hexstr2bin(pos, bss->mobility_domain, -+--- a/src/ap/ap_config.h -++++ b/src/ap/ap_config.h +@@ -1,6 +1,6 @@ + --- a/hostapd/config_file.c + +++ b/hostapd/config_file.c +-@@ -3069,6 +3069,8 @@ static int hostapd_config_fill(struct ho ++@@ -3033,6 +3033,8 @@ static int hostapd_config_fill(struct ho + wpa_printf(MSG_INFO, + "Line %d: Obsolete peerkey parameter ignored", line); + #ifdef CONFIG_IEEE80211R_AP +@@ -11,7 +11,7 @@ + hexstr2bin(pos, bss->mobility_domain, + --- a/src/ap/ap_config.h + +++ b/src/ap/ap_config.h +-@@ -284,6 +284,7 @@ struct airtime_sta_weight { +@@ -277,6 +277,7 @@ struct airtime_sta_weight { -+ struct hostapd_bss_config { -+ char iface[IFNAMSIZ + 1]; -+ char bridge[IFNAMSIZ + 1]; -++ char ft_iface[IFNAMSIZ + 1]; -+ char vlan_bridge[IFNAMSIZ + 1]; -+ char wds_bridge[IFNAMSIZ + 1]; -+ -+--- a/src/ap/wpa_auth_glue.c -++++ b/src/ap/wpa_auth_glue.c + struct hostapd_bss_config { + char iface[IFNAMSIZ + 1]; + char bridge[IFNAMSIZ + 1]; +@@ -21,7 +21,7 @@ + + --- a/src/ap/wpa_auth_glue.c + +++ b/src/ap/wpa_auth_glue.c +-@@ -1511,8 +1511,12 @@ int hostapd_setup_wpa(struct hostapd_dat +@@ -1565,8 +1565,12 @@ int hostapd_setup_wpa(struct hostapd_dat -+ wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { -+ const char *ft_iface; -+ -+- ft_iface = hapd->conf->bridge[0] ? hapd->conf->bridge : -+- hapd->conf->iface; -++ if (hapd->conf->ft_iface[0]) -++ ft_iface = hapd->conf->ft_iface; -++ else if (hapd->conf->bridge[0]) -++ ft_iface = hapd->conf->bridge; -++ else -++ ft_iface = hapd->conf->iface; -+ hapd->l2 = l2_packet_init(ft_iface, NULL, ETH_P_RRB, -+ hostapd_rrb_receive, hapd, 1); -+ if (!hapd->l2) { + wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { + const char *ft_iface; + diff --git a/package/network/services/hostapd/patches/740-snoop_iface.patch b/package/network/services/hostapd/patches/740-snoop_iface.patch -new file mode 100644 -index 0000000000..6e60cde844 ---- /dev/null +index 15aaf4b8e4..d206ed7322 100644 +--- a/package/network/services/hostapd/patches/740-snoop_iface.patch +++ b/package/network/services/hostapd/patches/740-snoop_iface.patch -@@ -0,0 +1,72 @@ -+Index: hostapd-2021-05-22-b102f19b/src/ap/ap_config.h -+=================================================================== -+--- hostapd-2021-05-22-b102f19b.orig/src/ap/ap_config.h -++++ hostapd-2021-05-22-b102f19b/src/ap/ap_config.h +@@ -1,6 +1,6 @@ + --- a/src/ap/ap_config.h + +++ b/src/ap/ap_config.h +-@@ -285,6 +285,7 @@ struct hostapd_bss_config { +@@ -278,6 +278,7 @@ struct hostapd_bss_config { -+ char iface[IFNAMSIZ + 1]; -+ char bridge[IFNAMSIZ + 1]; -+ char ft_iface[IFNAMSIZ + 1]; -++ char snoop_iface[IFNAMSIZ + 1]; -+ char vlan_bridge[IFNAMSIZ + 1]; -+ char wds_bridge[IFNAMSIZ + 1]; -+ -+Index: hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c -+=================================================================== -+--- hostapd-2021-05-22-b102f19b.orig/src/ap/x_snoop.c -++++ hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c -+@@ -31,14 +31,16 @@ int x_snoop_init(struct hostapd_data *ha -+ return -1; -+ } -+ -+- if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, -++ if (!conf->snoop_iface[0] && -++ hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, -+ 1)) { -+ wpa_printf(MSG_DEBUG, -+ "x_snoop: Failed to enable hairpin_mode on the bridge port"); -+ return -1; -+ } -+ -+- if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { -++ if (!conf->snoop_iface[0] && -++ hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { -+ wpa_printf(MSG_DEBUG, -+ "x_snoop: Failed to enable proxyarp on the bridge port"); -+ return -1; -+@@ -52,7 +54,8 @@ int x_snoop_init(struct hostapd_data *ha -+ } -+ -+ #ifdef CONFIG_IPV6 -+- if (hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) { -++ if (!conf->snoop_iface[0] && -++ hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) { -+ wpa_printf(MSG_DEBUG, -+ "x_snoop: Failed to enable multicast snooping on the bridge"); -+ return -1; -+@@ -71,8 +74,12 @@ x_snoop_get_l2_packet(struct hostapd_dat -+ { -+ struct hostapd_bss_config *conf = hapd->conf; -+ struct l2_packet_data *l2; -++ const char *ifname = conf->bridge; -+ -+- l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1); -++ if (conf->snoop_iface[0]) -++ ifname = conf->snoop_iface; -++ -++ l2 = l2_packet_init(ifname, NULL, ETH_P_ALL, handler, hapd, 1); -+ if (l2 == NULL) { -+ wpa_printf(MSG_DEBUG, -+ "x_snoop: Failed to initialize L2 packet processing %s", -+Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c -+=================================================================== -+--- hostapd-2021-05-22-b102f19b.orig/hostapd/config_file.c -++++ hostapd-2021-05-22-b102f19b/hostapd/config_file.c + char iface[IFNAMSIZ + 1]; + char bridge[IFNAMSIZ + 1]; + char ft_iface[IFNAMSIZ + 1]; +@@ -55,7 +55,7 @@ + "x_snoop: Failed to initialize L2 packet processing %s", + --- a/hostapd/config_file.c + +++ b/hostapd/config_file.c +-@@ -2407,6 +2407,8 @@ static int hostapd_config_fill(struct ho +@@ -2359,6 +2359,8 @@ static int hostapd_config_fill(struct ho -+ os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); -+ if (!bss->wds_bridge[0]) -+ os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); -++ } else if (os_strcmp(buf, "snoop_iface") == 0) { -++ os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface)); -+ } else if (os_strcmp(buf, "vlan_bridge") == 0) { -+ os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); -+ } else if (os_strcmp(buf, "wds_bridge") == 0) { + os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); + if (!bss->wds_bridge[0]) + os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); +diff --git a/package/network/services/hostapd/patches/741-proxyarp-fix-compilation-with-Hotspot-2.0-disabled.patch b/package/network/services/hostapd/patches/741-proxyarp-fix-compilation-with-Hotspot-2.0-disabled.patch +new file mode 100644 +index 0000000000..657ef5f2ed +--- /dev/null ++++ b/package/network/services/hostapd/patches/741-proxyarp-fix-compilation-with-Hotspot-2.0-disabled.patch +@@ -0,0 +1,51 @@ ++From ad694836b2ded6b97b426bf331627537cdbff591 Mon Sep 17 00:00:00 2001 ++From: David Bauer ++Date: Thu, 19 Aug 2021 00:52:04 +0200 ++Subject: [PATCH] proxyarp: fix compilation with Hotspot 2.0 disabled ++ ++The disable_dgaf config fiels is only available in case Hostapd is ++compiled with Hotspot 2.0 support, however Proxy-ARP does not depend on ++Hotspot 2.0. ++ ++Only add the code related to this config field when Hotspot 2.0 is ++enabled to fix compilation with the aformentioned preconditions. ++ ++Signed-off-by: David Bauer ++--- ++ src/ap/dhcp_snoop.c | 2 ++ ++ src/ap/ndisc_snoop.c | 2 ++ ++ 2 files changed, 4 insertions(+) ++ ++--- a/src/ap/dhcp_snoop.c +++++ b/src/ap/dhcp_snoop.c ++@@ -88,6 +88,7 @@ static void handle_dhcp(void *ctx, const ++ } ++ } ++ +++#ifdef CONFIG_HS20 ++ if (hapd->conf->disable_dgaf && is_broadcast_ether_addr(buf)) { ++ for (sta = hapd->sta_list; sta; sta = sta->next) { ++ if (!(sta->flags & WLAN_STA_AUTHORIZED)) ++@@ -96,6 +97,7 @@ static void handle_dhcp(void *ctx, const ++ (u8 *) buf, len); ++ } ++ } +++#endif ++ ++ if (msgtype == DHCPACK) { ++ if (b->your_ip == 0) ++--- a/src/ap/ndisc_snoop.c +++++ b/src/ap/ndisc_snoop.c ++@@ -151,10 +151,12 @@ static void handle_ndisc(void *ctx, cons ++ return; ++ } ++ break; +++#ifdef CONFIG_HS20 ++ case ROUTER_ADVERTISEMENT: ++ if (hapd->conf->disable_dgaf) ++ ucast_to_stas(hapd, buf, len); ++ break; +++#endif ++ case NEIGHBOR_ADVERTISEMENT: ++ if (hapd->conf->na_mcast_to_ucast) ++ ucast_to_stas(hapd, buf, len); +diff --git a/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch b/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch +index 94f4a2b297..a7a221352f 100644 +--- a/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch ++++ b/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch +@@ -1,6 +1,6 @@ + --- a/hostapd/config_file.c + +++ b/hostapd/config_file.c +-@@ -1711,6 +1711,8 @@ static int parse_anqp_elem(struct hostap ++@@ -1643,6 +1643,8 @@ static int parse_anqp_elem(struct hostap + return 0; + } + +@@ -9,7 +9,7 @@ + + static int parse_qos_map_set(struct hostapd_bss_config *bss, + char *buf, int line) +-@@ -1752,8 +1754,6 @@ static int parse_qos_map_set(struct host ++@@ -1684,8 +1686,6 @@ static int parse_qos_map_set(struct host + return 0; + } + +@@ -18,7 +18,7 @@ + + #ifdef CONFIG_HS20 + static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf, +-@@ -4050,10 +4050,10 @@ static int hostapd_config_fill(struct ho ++@@ -4058,10 +4058,10 @@ static int hostapd_config_fill(struct ho + bss->gas_frag_limit = val; + } else if (os_strcmp(buf, "gas_comeback_delay") == 0) { + bss->gas_comeback_delay = atoi(pos); +@@ -32,7 +32,7 @@ + os_free(bss->dump_msk_file); + --- a/src/ap/hostapd.c + +++ b/src/ap/hostapd.c +-@@ -1386,6 +1386,7 @@ static int hostapd_setup_bss(struct host ++@@ -1415,6 +1415,7 @@ static int hostapd_setup_bss(struct host + wpa_printf(MSG_ERROR, "GAS server initialization failed"); + return -1; + } +@@ -40,7 +40,7 @@ + + if (conf->qos_map_set_len && + hostapd_drv_set_qos_map(hapd, conf->qos_map_set, +-@@ -1393,7 +1394,6 @@ static int hostapd_setup_bss(struct host ++@@ -1422,7 +1423,6 @@ static int hostapd_setup_bss(struct host + wpa_printf(MSG_ERROR, "Failed to initialize QoS Map"); + return -1; + } +@@ -50,7 +50,7 @@ + wpa_printf(MSG_ERROR, "BSS Load initialization failed"); + --- a/src/ap/drv_callbacks.c + +++ b/src/ap/drv_callbacks.c +-@@ -245,12 +245,10 @@ int hostapd_notif_assoc(struct hostapd_d ++@@ -271,12 +271,10 @@ int hostapd_notif_assoc(struct hostapd_d + } + #endif /* NEED_AP_MLME */ + +@@ -65,7 +65,7 @@ + wpabuf_free(sta->hs20_ie); + --- a/src/ap/ieee802_11.c + +++ b/src/ap/ieee802_11.c +-@@ -2875,13 +2875,11 @@ static u16 copy_supp_rates(struct hostap ++@@ -4127,13 +4127,11 @@ static u16 copy_supp_rates(struct hostap + static u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta, + const u8 *ext_capab_ie, size_t ext_capab_ie_len) + { +@@ -81,7 +81,7 @@ + sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2)); + --- a/wpa_supplicant/events.c + +++ b/wpa_supplicant/events.c +-@@ -2500,8 +2500,6 @@ void wnm_bss_keep_alive_deinit(struct wp ++@@ -2535,8 +2535,6 @@ void wnm_bss_keep_alive_deinit(struct wp + } + + +@@ -90,7 +90,7 @@ + static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map, + size_t len) + { +-@@ -2534,8 +2532,6 @@ static void interworking_process_assoc_r ++@@ -2569,8 +2567,6 @@ static void interworking_process_assoc_r + } + } + +@@ -99,7 +99,7 @@ + + static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s, + const u8 *ies, size_t ies_len) +-@@ -2669,10 +2665,8 @@ static int wpa_supplicant_event_associnf ++@@ -2704,10 +2700,8 @@ static int wpa_supplicant_event_associnf + wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len); + #endif /* CONFIG_WNM */ +diff --git a/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch b/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch +new file mode 100644 +index 0000000000..8af5a0a046 +--- /dev/null ++++ b/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch +@@ -0,0 +1,12 @@ ++--- a/src/ap/ap_drv_ops.c +++++ b/src/ap/ap_drv_ops.c ++@@ -850,7 +850,8 @@ int hostapd_start_dfs_cac(struct hostapd ++ int hostapd_drv_set_qos_map(struct hostapd_data *hapd, ++ const u8 *qos_map_set, u8 qos_map_set_len) ++ { ++- if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv) +++ if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv || +++ !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_QOS_MAPPING)) ++ return 0; ++ return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set, ++ qos_map_set_len); diff --git a/package/network/services/hostapd/patches/800-dfs-enter-DFS-state-if-no-available-channel-is-found.patch b/package/network/services/hostapd/patches/800-dfs-enter-DFS-state-if-no-available-channel-is-found.patch deleted file mode 100644 index 3e4638d7ff..0000000000 @@ -5563,7 +5603,7 @@ index 944f7d71c9..0000000000 - dev->info.wps_sec_dev_type_list_len); - } diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c -index d03b848f94..09b25a29e5 100644 +index 0575fe2572..bcb80f4a33 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -21,6 +21,7 @@ @@ -5582,7 +5622,7 @@ index d03b848f94..09b25a29e5 100644 { "wps", WLAN_STA_WPS }, { "mfp", WLAN_STA_MFP }, }; -@@ -372,6 +374,32 @@ hostapd_bss_get_features(struct ubus_context *ctx, struct ubus_object *obj, +@@ -372,24 +374,74 @@ hostapd_bss_get_features(struct ubus_context *ctx, struct ubus_object *obj, return 0; } @@ -5615,9 +5655,11 @@ index d03b848f94..09b25a29e5 100644 static int hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, -@@ -380,12 +408,23 @@ hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, + struct blob_attr *msg) + { struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - void *airtime_table, *dfs_table; +- void *airtime_table, *dfs_table; ++ void *airtime_table, *dfs_table, *rrm_table, *wnm_table; struct os_reltime now; + char ssid[SSID_MAX_LEN + 1]; char phy_name[17]; @@ -5637,10 +5679,27 @@ index d03b848f94..09b25a29e5 100644 + blobmsg_add_u32(&b, "freq", hapd->iface->freq); + blobmsg_add_u32(&b, "channel", ieee80211_frequency_to_channel(hapd->iface->freq)); ++ blobmsg_add_u32(&b, "beacon_interval", hapd->iconf->beacon_int); snprintf(phy_name, 17, "%s", hapd->iface->phy); blobmsg_add_string(&b, "phy", phy_name); -@@ -703,7 +742,9 @@ enum { + ++ /* RRM */ ++ rrm_table = blobmsg_open_table(&b, "rrm"); ++ blobmsg_add_u64(&b, "neighbor_report_tx", hapd->openwrt_stats.rrm.neighbor_report_tx); ++ blobmsg_close_table(&b, rrm_table); ++ ++ /* WNM */ ++ wnm_table = blobmsg_open_table(&b, "wnm"); ++ blobmsg_add_u64(&b, "bss_transition_query_rx", hapd->openwrt_stats.wnm.bss_transition_query_rx); ++ blobmsg_add_u64(&b, "bss_transition_request_tx", hapd->openwrt_stats.wnm.bss_transition_request_tx); ++ blobmsg_add_u64(&b, "bss_transition_response_rx", hapd->openwrt_stats.wnm.bss_transition_response_rx); ++ blobmsg_close_table(&b, wnm_table); ++ + /* Airtime */ + airtime_table = blobmsg_open_table(&b, "airtime"); + blobmsg_add_u64(&b, "time", hapd->iface->last_channel_time); +@@ -703,7 +755,9 @@ enum { CSA_SEC_CHANNEL_OFFSET, CSA_HT, CSA_VHT, @@ -5650,7 +5709,7 @@ index d03b848f94..09b25a29e5 100644 __CSA_MAX }; -@@ -716,9 +757,20 @@ static const struct blobmsg_policy csa_policy[__CSA_MAX] = { +@@ -716,9 +770,20 @@ static const struct blobmsg_policy csa_policy[__CSA_MAX] = { [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, @@ -5671,7 +5730,7 @@ index d03b848f94..09b25a29e5 100644 #ifdef NEED_AP_MLME static int hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, -@@ -727,14 +779,39 @@ hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, +@@ -727,14 +792,39 @@ hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, { struct blob_attr *tb[__CSA_MAX]; struct hostapd_data *hapd = get_hapd_from_object(obj); @@ -5713,7 +5772,7 @@ index d03b848f94..09b25a29e5 100644 css.freq_params.freq = blobmsg_get_u32(tb[CSA_FREQ]); #define SET_CSA_SETTING(name, field, type) \ -@@ -750,12 +827,25 @@ hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, +@@ -750,12 +840,25 @@ hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, SET_CSA_SETTING(CSA_SEC_CHANNEL_OFFSET, freq_params.sec_channel_offset, u32); SET_CSA_SETTING(CSA_HT, freq_params.ht_enabled, bool); SET_CSA_SETTING(CSA_VHT, freq_params.vht_enabled, bool); @@ -5742,10 +5801,209 @@ index d03b848f94..09b25a29e5 100644 #undef SET_CSA_SETTING } #endif -@@ -1282,11 +1372,68 @@ hostapd_wnm_disassoc_imminent(struct ubus_context *ctx, struct ubus_object *obj, - } - #endif +@@ -1185,60 +1288,31 @@ hostapd_rrm_beacon_req(struct ubus_context *ctx, struct ubus_object *obj, + + #ifdef CONFIG_WNM_AP +-enum { +- WNM_DISASSOC_ADDR, +- WNM_DISASSOC_DURATION, +- WNM_DISASSOC_NEIGHBORS, +- WNM_DISASSOC_ABRIDGED, +- __WNM_DISASSOC_MAX, +-}; +- +-static const struct blobmsg_policy wnm_disassoc_policy[__WNM_DISASSOC_MAX] = { +- [WNM_DISASSOC_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, +- [WNM_DISASSOC_DURATION] { "duration", BLOBMSG_TYPE_INT32 }, +- [WNM_DISASSOC_NEIGHBORS] { "neighbors", BLOBMSG_TYPE_ARRAY }, +- [WNM_DISASSOC_ABRIDGED] { "abridged", BLOBMSG_TYPE_BOOL }, +-}; + + static int +-hostapd_wnm_disassoc_imminent(struct ubus_context *ctx, struct ubus_object *obj, +- struct ubus_request_data *ureq, const char *method, +- struct blob_attr *msg) ++hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, bool abridged, ++ u16 disassoc_timer, u8 validity_period, u8 dialog_token, ++ struct blob_attr *neighbors) + { +- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); +- struct blob_attr *tb[__WNM_DISASSOC_MAX]; + struct blob_attr *cur; + struct sta_info *sta; +- int duration = 10; +- int rem; + int nr_len = 0; ++ int rem; + u8 *nr = NULL; +- u8 req_mode = WNM_BSS_TM_REQ_DISASSOC_IMMINENT; +- u8 addr[ETH_ALEN]; +- +- blobmsg_parse(wnm_disassoc_policy, __WNM_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); +- +- if (!tb[WNM_DISASSOC_ADDR]) +- return UBUS_STATUS_INVALID_ARGUMENT; +- +- if (hwaddr_aton(blobmsg_data(tb[WNM_DISASSOC_ADDR]), addr)) +- return UBUS_STATUS_INVALID_ARGUMENT; +- +- if ((cur = tb[WNM_DISASSOC_DURATION]) != NULL) +- duration = blobmsg_get_u32(cur); ++ u8 req_mode = 0; + + sta = ap_get_sta(hapd, addr); + if (!sta) + return UBUS_STATUS_NOT_FOUND; + +- if (tb[WNM_DISASSOC_NEIGHBORS]) { ++ if (neighbors) { + u8 *nr_cur; + +- if (blobmsg_check_array(tb[WNM_DISASSOC_NEIGHBORS], ++ if (blobmsg_check_array(neighbors, + BLOBMSG_TYPE_STRING) < 0) + return UBUS_STATUS_INVALID_ARGUMENT; + +- blobmsg_for_each_attr(cur, tb[WNM_DISASSOC_NEIGHBORS], rem) { ++ blobmsg_for_each_attr(cur, neighbors, rem) { + int len = strlen(blobmsg_get_string(cur)); + + if (len % 2) +@@ -1254,7 +1328,7 @@ hostapd_wnm_disassoc_imminent(struct ubus_context *ctx, struct ubus_object *obj, + } + + nr_cur = nr; +- blobmsg_for_each_attr(cur, tb[WNM_DISASSOC_NEIGHBORS], rem) { ++ blobmsg_for_each_attr(cur, neighbors, rem) { + int len = strlen(blobmsg_get_string(cur)) / 2; + + *nr_cur++ = WLAN_EID_NEIGHBOR_REPORT; +@@ -1271,22 +1345,186 @@ hostapd_wnm_disassoc_imminent(struct ubus_context *ctx, struct ubus_object *obj, + if (nr) + req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED; + +- if (tb[WNM_DISASSOC_ABRIDGED] && blobmsg_get_bool(tb[WNM_DISASSOC_ABRIDGED])) ++ if (abridged) + req_mode |= WNM_BSS_TM_REQ_ABRIDGED; + +- if (wnm_send_bss_tm_req(hapd, sta, req_mode, duration, duration, NULL, +- NULL, nr, nr_len, NULL, 0)) ++ if (disassoc_imminent) ++ req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT; ++ ++ if (wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, validity_period, NULL, ++ dialog_token, NULL, nr, nr_len, NULL, 0)) + return UBUS_STATUS_UNKNOWN_ERROR; + + return 0; + } ++ ++enum { ++ BSS_TR_ADDR, ++ BSS_TR_DA_IMMINENT, ++ BSS_TR_DA_TIMER, ++ BSS_TR_VALID_PERIOD, ++ BSS_TR_NEIGHBORS, ++ BSS_TR_ABRIDGED, ++ BSS_TR_DIALOG_TOKEN, ++ __BSS_TR_DISASSOC_MAX ++}; ++ ++static const struct blobmsg_policy bss_tr_policy[__BSS_TR_DISASSOC_MAX] = { ++ [BSS_TR_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, ++ [BSS_TR_DA_IMMINENT] = { "disassociation_imminent", BLOBMSG_TYPE_BOOL }, ++ [BSS_TR_DA_TIMER] = { "disassociation_timer", BLOBMSG_TYPE_INT32 }, ++ [BSS_TR_VALID_PERIOD] = { "validity_period", BLOBMSG_TYPE_INT32 }, ++ [BSS_TR_NEIGHBORS] = { "neighbors", BLOBMSG_TYPE_ARRAY }, ++ [BSS_TR_ABRIDGED] = { "abridged", BLOBMSG_TYPE_BOOL }, ++ [BSS_TR_DIALOG_TOKEN] = { "dialog_token", BLOBMSG_TYPE_INT32 }, ++}; ++ ++static int ++hostapd_bss_transition_request(struct ubus_context *ctx, struct ubus_object *obj, ++ struct ubus_request_data *ureq, const char *method, ++ struct blob_attr *msg) ++{ ++ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); ++ struct blob_attr *tb[__BSS_TR_DISASSOC_MAX]; ++ struct sta_info *sta; ++ u32 da_timer = 0; ++ u32 valid_period = 0; ++ u8 addr[ETH_ALEN]; ++ u32 dialog_token = 1; ++ bool abridged; ++ bool da_imminent; ++ ++ blobmsg_parse(bss_tr_policy, __BSS_TR_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); ++ ++ if (!tb[BSS_TR_ADDR]) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ if (hwaddr_aton(blobmsg_data(tb[BSS_TR_ADDR]), addr)) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ if (tb[BSS_TR_DA_TIMER]) ++ da_timer = blobmsg_get_u32(tb[BSS_TR_DA_TIMER]); ++ ++ if (tb[BSS_TR_VALID_PERIOD]) ++ valid_period = blobmsg_get_u32(tb[BSS_TR_VALID_PERIOD]); ++ ++ if (tb[BSS_TR_DIALOG_TOKEN]) ++ dialog_token = blobmsg_get_u32(tb[BSS_TR_DIALOG_TOKEN]); ++ ++ da_imminent = !!(tb[BSS_TR_DA_IMMINENT] && blobmsg_get_bool(tb[BSS_TR_DA_IMMINENT])); ++ abridged = !!(tb[BSS_TR_ABRIDGED] && blobmsg_get_bool(tb[BSS_TR_ABRIDGED])); ++ ++ return hostapd_bss_tr_send(hapd, addr, da_imminent, abridged, da_timer, valid_period, ++ dialog_token, tb[BSS_TR_NEIGHBORS]); ++} ++ ++enum { ++ WNM_DISASSOC_ADDR, ++ WNM_DISASSOC_DURATION, ++ WNM_DISASSOC_NEIGHBORS, ++ WNM_DISASSOC_ABRIDGED, ++ __WNM_DISASSOC_MAX, ++}; ++ ++static const struct blobmsg_policy wnm_disassoc_policy[__WNM_DISASSOC_MAX] = { ++ [WNM_DISASSOC_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, ++ [WNM_DISASSOC_DURATION] { "duration", BLOBMSG_TYPE_INT32 }, ++ [WNM_DISASSOC_NEIGHBORS] { "neighbors", BLOBMSG_TYPE_ARRAY }, ++ [WNM_DISASSOC_ABRIDGED] { "abridged", BLOBMSG_TYPE_BOOL }, ++}; ++ ++static int ++hostapd_wnm_disassoc_imminent(struct ubus_context *ctx, struct ubus_object *obj, ++ struct ubus_request_data *ureq, const char *method, ++ struct blob_attr *msg) ++{ ++ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); ++ struct blob_attr *tb[__WNM_DISASSOC_MAX]; ++ struct sta_info *sta; ++ int duration = 10; ++ u8 addr[ETH_ALEN]; ++ bool abridged; ++ ++ blobmsg_parse(wnm_disassoc_policy, __WNM_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); ++ ++ if (!tb[WNM_DISASSOC_ADDR]) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ if (hwaddr_aton(blobmsg_data(tb[WNM_DISASSOC_ADDR]), addr)) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ if (tb[WNM_DISASSOC_DURATION]) ++ duration = blobmsg_get_u32(tb[WNM_DISASSOC_DURATION]); ++ ++ abridged = !!(tb[WNM_DISASSOC_ABRIDGED] && blobmsg_get_bool(tb[WNM_DISASSOC_ABRIDGED])); ++ ++ return hostapd_bss_tr_send(hapd, addr, true, abridged, duration, duration, ++ 1, tb[WNM_DISASSOC_NEIGHBORS]); ++} ++#endif ++ +#ifdef CONFIG_AIRTIME_POLICY +enum { + UPDATE_AIRTIME_STA, @@ -5797,8 +6055,8 @@ index d03b848f94..09b25a29e5 100644 + + return 0; +} -+#endif -+ + #endif + + static const struct ubus_method bss_methods[] = { UBUS_METHOD_NOARG("reload", hostapd_bss_reload), @@ -5811,7 +6069,15 @@ index d03b848f94..09b25a29e5 100644 UBUS_METHOD_NOARG("list_bans", hostapd_bss_list_bans), #ifdef CONFIG_WPS UBUS_METHOD_NOARG("wps_start", hostapd_bss_wps_start), -@@ -1364,6 +1511,43 @@ void hostapd_ubus_free_bss(struct hostapd_data *hapd) +@@ -1307,6 +1545,7 @@ static const struct ubus_method bss_methods[] = { + UBUS_METHOD("rrm_beacon_req", hostapd_rrm_beacon_req, beacon_req_policy), + #ifdef CONFIG_WNM_AP + UBUS_METHOD("wnm_disassoc_imminent", hostapd_wnm_disassoc_imminent, wnm_disassoc_policy), ++ UBUS_METHOD("bss_transition_request", hostapd_bss_transition_request, bss_tr_policy), + #endif + }; + +@@ -1369,6 +1608,43 @@ void hostapd_ubus_free_bss(struct hostapd_data *hapd) free(name); } @@ -5855,7 +6121,7 @@ index d03b848f94..09b25a29e5 100644 static const struct ubus_method daemon_methods[] = { UBUS_METHOD("config_add", hostapd_config_add, config_add_policy), UBUS_METHOD("config_remove", hostapd_config_remove, config_remove_policy), -@@ -1550,3 +1734,21 @@ void hostapd_ubus_notify_beacon_report( +@@ -1555,3 +1831,103 @@ void hostapd_ubus_notify_beacon_report( ubus_notify(ctx, &hapd->ubus.obj, "beacon-report", b.head, -1); } @@ -5877,8 +6143,91 @@ index d03b848f94..09b25a29e5 100644 + ubus_notify(ctx, &hapd->ubus.obj, "radar-detected", b.head, -1); + } +} ++ ++#ifdef CONFIG_WNM_AP ++static void hostapd_ubus_notify_bss_transition_add_candidate_list( ++ const u8 *candidate_list, u16 candidate_list_len) ++{ ++ char *cl_str; ++ int i; ++ ++ if (candidate_list_len == 0) ++ return; ++ ++ cl_str = blobmsg_alloc_string_buffer(&b, "candidate-list", candidate_list_len * 2 + 1); ++ for (i = 0; i < candidate_list_len; i++) ++ snprintf(&cl_str[i*2], 3, "%02X", candidate_list[i]); ++ blobmsg_add_string_buffer(&b); ++ ++} ++#endif ++ ++void hostapd_ubus_notify_bss_transition_response( ++ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code, ++ u8 bss_termination_delay, const u8 *target_bssid, ++ const u8 *candidate_list, u16 candidate_list_len) ++{ ++#ifdef CONFIG_WNM_AP ++ u16 i; ++ ++ if (!hapd->ubus.obj.has_subscribers) ++ return; ++ ++ if (!addr) ++ return; ++ ++ blob_buf_init(&b, 0); ++ blobmsg_add_macaddr(&b, "address", addr); ++ blobmsg_add_u8(&b, "dialog-token", dialog_token); ++ blobmsg_add_u8(&b, "status-code", status_code); ++ blobmsg_add_u8(&b, "bss-termination-delay", bss_termination_delay); ++ if (target_bssid) ++ blobmsg_add_macaddr(&b, "target-bssid", target_bssid); ++ ++ hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len); ++ ++ ubus_notify(ctx, &hapd->ubus.obj, "bss-transition-response", b.head, -1); ++#endif ++} ++ ++int hostapd_ubus_notify_bss_transition_query( ++ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, ++ const u8 *candidate_list, u16 candidate_list_len) ++{ ++#ifdef CONFIG_WNM_AP ++ struct ubus_event_req ureq = {}; ++ char *cl_str; ++ u16 i; ++ ++ if (!hapd->ubus.obj.has_subscribers) ++ return 0; ++ ++ if (!addr) ++ return 0; ++ ++ blob_buf_init(&b, 0); ++ blobmsg_add_macaddr(&b, "address", addr); ++ blobmsg_add_u8(&b, "dialog-token", dialog_token); ++ blobmsg_add_u8(&b, "reason", reason); ++ hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len); ++ ++ if (!hapd->ubus.notify_response) { ++ ubus_notify(ctx, &hapd->ubus.obj, "bss-transition-query", b.head, -1); ++ return 0; ++ } ++ ++ if (ubus_notify_async(ctx, &hapd->ubus.obj, "bss-transition-query", b.head, &ureq.nreq)) ++ return 0; ++ ++ ureq.nreq.status_cb = ubus_event_cb; ++ ubus_complete_request(ctx, &ureq.nreq.req, 100); ++ ++ return ureq.resp; ++#endif ++} +\ No newline at end of file diff --git a/package/network/services/hostapd/src/src/ap/ubus.h b/package/network/services/hostapd/src/src/ap/ubus.h -index e16017394f..acdac74360 100644 +index e16017394f..f1bc093e57 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.h +++ b/package/network/services/hostapd/src/src/ap/ubus.h @@ -43,6 +43,8 @@ void hostapd_ubus_add_iface(struct hostapd_iface *iface); @@ -5890,16 +6239,26 @@ index e16017394f..acdac74360 100644 int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req); void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac); -@@ -50,6 +52,8 @@ void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd, +@@ -50,9 +52,18 @@ void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd, const u8 *addr, u8 token, u8 rep_mode, struct rrm_measurement_beacon_report *rep, size_t len); +void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency, + int chan_width, int cf1, int cf2); ++void hostapd_ubus_notify_bss_transition_response( ++ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code, ++ u8 bss_termination_delay, const u8 *target_bssid, ++ const u8 *candidate_list, u16 candidate_list_len); void hostapd_ubus_add(struct hapd_interfaces *interfaces); void hostapd_ubus_free(struct hapd_interfaces *interfaces); -@@ -74,6 +78,14 @@ static inline void hostapd_ubus_free_bss(struct hostapd_data *hapd) ++int hostapd_ubus_notify_bss_transition_query( ++ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, ++ const u8 *candidate_list, u16 candidate_list_len); + + #else + +@@ -74,6 +85,14 @@ static inline void hostapd_ubus_free_bss(struct hostapd_data *hapd) { } @@ -5914,19 +6273,40 @@ index e16017394f..acdac74360 100644 static inline int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) { return 0; -@@ -90,6 +102,10 @@ static inline void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd, +@@ -90,6 +109,17 @@ static inline void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd, size_t len) { } +static inline void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency, + int chan_width, int cf1, int cf2) +{ ++} ++ ++static inline void hostapd_ubus_notify_bss_transition_response( ++ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code, ++ u8 bss_termination_delay, const u8 *target_bssid, ++ const u8 *candidate_list, u16 candidate_list_len) ++{ +} static inline void hostapd_ubus_add(struct hapd_interfaces *interfaces) { +@@ -98,6 +128,13 @@ static inline void hostapd_ubus_add(struct hapd_interfaces *interfaces) + static inline void hostapd_ubus_free(struct hapd_interfaces *interfaces) + { + } ++ ++static inline int hostapd_ubus_notify_bss_transition_query( ++ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, ++ const u8 *candidate_list, u16 candidate_list_len) ++{ ++ return 0; ++} + #endif + + #endif diff --git a/package/network/services/hostapd/src/src/utils/build_features.h b/package/network/services/hostapd/src/src/utils/build_features.h -index c7fccad413..3ab5246c78 100644 +index c7fccad413..cb7cb72731 100644 --- a/package/network/services/hostapd/src/src/utils/build_features.h +++ b/package/network/services/hostapd/src/src/utils/build_features.h @@ -23,8 +23,6 @@ static inline int has_feature(const char *feat) @@ -5938,6 +6318,17 @@ index c7fccad413..3ab5246c78 100644 #ifdef CONFIG_ACS if (!strcmp(feat, "acs")) return 1; +@@ -52,6 +50,10 @@ static inline int has_feature(const char *feat) + #ifdef CONFIG_WPS + if (!strcmp(feat, "wps")) + return 1; ++#endif ++#ifdef CONFIG_FILS ++ if (!strcmp(feat, "fils")) ++ return 1; + #endif + return 0; + } -- 2.25.1 diff --git a/patches/wifi/0004-hostapd-pending-fixes.patch b/patches/wifi/0004-hostapd-pending-fixes.patch new file mode 100644 index 000000000..149e55533 --- /dev/null +++ b/patches/wifi/0004-hostapd-pending-fixes.patch @@ -0,0 +1,170 @@ +From 83e8509388c5648dc8217b8f86d0461fade6a8d1 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Tue, 4 Jan 2022 07:01:41 +0100 +Subject: [PATCH 4/4] hostapd: pending fixes + +Signed-off-by: John Crispin +--- + .../hostapd/files/hostapd-full.config | 4 +- + .../network/services/hostapd/files/hostapd.sh | 45 +++++++++++++------ + 2 files changed, 33 insertions(+), 16 deletions(-) + +diff --git a/package/network/services/hostapd/files/hostapd-full.config b/package/network/services/hostapd/files/hostapd-full.config +index dbc2022550..38a29143d5 100644 +--- a/package/network/services/hostapd/files/hostapd-full.config ++++ b/package/network/services/hostapd/files/hostapd-full.config +@@ -94,10 +94,10 @@ CONFIG_EAP_TTLS=y + #CONFIG_EAP_PAX=y + + # EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) +-#CONFIG_EAP_PSK=y ++CONFIG_EAP_PSK=y + + # EAP-pwd for the integrated EAP server (secure authentication with a password) +-#CONFIG_EAP_PWD=y ++CONFIG_EAP_PWD=y + + # EAP-SAKE for the integrated EAP server + #CONFIG_EAP_SAKE=y +diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh +index d9d5f34877..a56bc69562 100644 +--- a/package/network/services/hostapd/files/hostapd.sh ++++ b/package/network/services/hostapd/files/hostapd.sh +@@ -48,13 +48,17 @@ hostapd_append_wpa_key_mgmt() { + ;; + eap192) + append wpa_key_mgmt "WPA-EAP-SUITE-B-192" ++ append wpa_key_mgmt "WPA-EAP-SHA256" + [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP" + ;; +- eap-eap192) +- append wpa_key_mgmt "WPA-EAP-SUITE-B-192" ++ eap-eap256) + append wpa_key_mgmt "WPA-EAP" ++ append wpa_key_mgmt "WPA-EAP-SHA256" ++ [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP" ++ ;; ++ eap256) ++ append wpa_key_mgmt "WPA-EAP-SHA256" + [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP" +- [ "${ieee80211w:-0}" -gt 0 ] && append wpa_key_mgmt "WPA-EAP-SHA256" + ;; + sae) + append wpa_key_mgmt "SAE" +@@ -345,7 +349,7 @@ hostapd_common_add_bss_config() { + + config_add_boolean hs20 disable_dgaf osen + config_add_int anqp_domain_id +- config_add_int hs20_deauth_req_timeout ++ config_add_int hs20_deauth_req_timeout hs20_release + config_add_array hs20_oper_friendly_name + config_add_array osu_provider + config_add_array operator_icon +@@ -371,6 +375,8 @@ hostapd_common_add_bss_config() { + + config_add_boolean fils + config_add_string fils_dhcp ++ ++ config_add_boolean ratelimit + } + + hostapd_set_vlan_file() { +@@ -422,7 +428,7 @@ append_iw_anqp_3gpp_cell_net() { + if [ -z "$iw_anqp_3gpp_cell_net_conf" ]; then + iw_anqp_3gpp_cell_net_conf="$1" + else +- iw_anqp_3gpp_cell_net_conf="$iw_anqp_3gpp_cell_net_conf:$1" ++ iw_anqp_3gpp_cell_net_conf="$iw_anqp_3gpp_cell_net_conf;$1" + fi + } + +@@ -617,11 +623,11 @@ hostapd_set_bss_options() { + } + + case "$auth_type" in +- sae|owe|eap192|eap-eap192) ++ sae|owe|eap192|eap256) + set_default ieee80211w 2 + set_default sae_require_mfp 1 + ;; +- psk-sae) ++ psk-sae|eap-eap256) + set_default ieee80211w 1 + set_default sae_require_mfp 1 + ;; +@@ -664,7 +670,7 @@ hostapd_set_bss_options() { + vlan_possible=1 + wps_possible=1 + ;; +- eap|eap192|eap-eap192) ++ eap|eap192|eap-eap256|eap256) + json_get_vars \ + auth_server auth_secret auth_port \ + dae_client dae_secret dae_port \ +@@ -930,7 +936,16 @@ hostapd_set_bss_options() { + json_get_vars ieee80211w_mgmt_cipher ieee80211w_max_timeout ieee80211w_retry_timeout + append bss_conf "ieee80211w=$ieee80211w" "$N" + [ "$ieee80211w" -gt "0" ] && { +- append bss_conf "group_mgmt_cipher=${ieee80211w_mgmt_cipher:-AES-128-CMAC}" "$N" ++ case "$auth_type" in ++ eap192) ++ append bss_conf "group_mgmt_cipher=BIP-GMAC-256" "$N" ++ append bss_conf "group_cipher=GCMP-256" "$N" ++ ;; ++ *) ++ append bss_conf "group_mgmt_cipher=${ieee80211w_mgmt_cipher:-AES-128-CMAC}" "$N" ++ ;; ++ esac ++ + [ -n "$ieee80211w_max_timeout" ] && \ + append bss_conf "assoc_sa_query_max_timeout=$ieee80211w_max_timeout" "$N" + [ -n "$ieee80211w_retry_timeout" ] && \ +@@ -1045,12 +1060,13 @@ hostapd_set_bss_options() { + + local hs20 disable_dgaf osen anqp_domain_id hs20_deauth_req_timeout \ + osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp \ +- hs20_t_c_server_url ++ hs20_t_c_server_url hs20_release + json_get_vars hs20 disable_dgaf osen anqp_domain_id hs20_deauth_req_timeout \ + osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp \ +- hs20_t_c_server_url ++ hs20_t_c_server_url hs20_release + + set_default hs20 0 ++ set_default hs20_release 1 + set_default disable_dgaf $hs20 + set_default osen 0 + set_default anqp_domain_id 0 +@@ -1058,6 +1074,7 @@ hostapd_set_bss_options() { + if [ "$hs20" = "1" ]; then + append bss_conf "hs20=1" "$N" + append_hs20_icons ++ append bss_conf "hs20_release=$hs20_release" "$N" + append bss_conf "disable_dgaf=$disable_dgaf" "$N" + append bss_conf "osen=$osen" "$N" + append bss_conf "anqp_domain_id=$anqp_domain_id" "$N" +@@ -1248,10 +1265,10 @@ wpa_supplicant_add_network() { + default_disabled + + case "$auth_type" in +- sae|owe|eap192|eap-eap192) ++ sae|owe|eap-eap256) + set_default ieee80211w 2 + ;; +- psk-sae) ++ psk-sae|eap192|eap256) + set_default ieee80211w 1 + ;; + esac +@@ -1329,7 +1346,7 @@ wpa_supplicant_add_network() { + fi + append network_data "$passphrase" "$N$T" + ;; +- eap|eap192|eap-eap192) ++ eap|eap192|eap-eap256|eap256) + hostapd_append_wpa_key_mgmt + key_mgmt="$wpa_key_mgmt" + +-- +2.25.1 + diff --git a/patches/rest/0049-hostapd-add-wispr-bandwidth-patch.patch b/patches/wifi/0005-hostapd-add-wispr-bandwidth-patch.patch similarity index 100% rename from patches/rest/0049-hostapd-add-wispr-bandwidth-patch.patch rename to patches/wifi/0005-hostapd-add-wispr-bandwidth-patch.patch