PKG_NAME:=mac80211
-PKG_VERSION:=6.1.24
-PKG_RELEASE:=4
-# PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/
-PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
-PKG_HASH:=5d39aca7e34c33cb9b3e366117b2e86841b7bdd37933679d6b1e61be6b150648
+PKG_VERSION:=6.1.97-1
+PKG_RELEASE:=1
+PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v6.1.97/
+PKG_HASH:=8e9ae2d02f373252dd61f5c6a81c88eec67ca773464d9ef3d844752dc6775540
PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
$(Build/Patch)
rm -rf \
$(PKG_BUILD_DIR)/include/linux/ssb \
- $(PKG_BUILD_DIR)/include/linux/bcma \
- $(PKG_BUILD_DIR)/include/net/bluetooth
+ $(PKG_BUILD_DIR)/include/linux/bcma
rm -f \
- $(PKG_BUILD_DIR)/include/linux/cordic.h \
- $(PKG_BUILD_DIR)/include/linux/crc8.h \
- $(PKG_BUILD_DIR)/include/linux/eeprom_93cx6.h \
- $(PKG_BUILD_DIR)/include/linux/wl12xx.h \
$(PKG_BUILD_DIR)/include/linux/mhi.h \
- $(PKG_BUILD_DIR)/include/net/ieee80211.h \
- $(PKG_BUILD_DIR)/backport-include/linux/bcm47xx_nvram.h
+ $(PKG_BUILD_DIR)/include/trace/events/qrtr.h \
+ $(PKG_BUILD_DIR)/include/net/rsi_91x.h \
+ $(PKG_BUILD_DIR)/backport-include/linux/platform_data/brcmnand.h \
+ $(PKG_BUILD_DIR)/backport-include/linux/soc/mediatek/mtk_wed.h
echo 'compat-wireless-$(PKG_VERSION)-$(PKG_RELEASE)-$(REVISION)' > $(PKG_BUILD_DIR)/compat_version
endef
ifeq ($(strip $(CONFIG_EXTERNAL_KERNEL_TREE)),"")
ifeq ($(strip $(CONFIG_KERNEL_GIT_CLONE_URI)),"")
define Build/Configure
- cmp $(PKG_BUILD_DIR)/include/linux/ath9k_platform.h $(LINUX_DIR)/include/linux/ath9k_platform.h
cmp $(PKG_BUILD_DIR)/include/linux/ath5k_platform.h $(LINUX_DIR)/include/linux/ath5k_platform.h
endef
endif
CFLAGS_trace.o := -I$(src)
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
-@@ -317,14 +317,7 @@ void _ath_dbg(struct ath_common *common,
+@@ -321,14 +321,7 @@ void _ath_dbg(struct ath_common *common,
#endif /* CPTCFG_ATH_DEBUG */
/** Returns string describing opmode, or NULL if unknown mode. */
help
--- a/local-symbols
+++ b/local-symbols
-@@ -102,6 +102,7 @@ ADM8211=
+@@ -94,6 +94,7 @@ ADM8211=
ATH_COMMON=
WLAN_VENDOR_ATH=
ATH_DEBUG=
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
-@@ -3370,6 +3370,8 @@ void regulatory_hint_country_ie(struct w
+@@ -3373,6 +3373,8 @@ void regulatory_hint_country_ie(struct w
enum environment_cap env = ENVIRON_ANY;
struct regulatory_request *request = NULL, *lr;
/* IE len must be evenly divisible by 2 */
if (country_ie_len & 0x01)
return;
-@@ -3621,6 +3623,7 @@ static bool is_wiphy_all_set_reg_flag(en
+@@ -3624,6 +3626,7 @@ static bool is_wiphy_all_set_reg_flag(en
void regulatory_hint_disconnect(void)
{
debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
-@@ -149,6 +149,7 @@ struct ath_common {
+@@ -151,6 +151,7 @@ struct ath_common {
int debug_mask;
enum ath_device_state state;
unsigned long op_flags;
---- a/include/linux/ath9k_platform.h
-+++ b/include/linux/ath9k_platform.h
-@@ -46,6 +46,9 @@ struct ath9k_platform_data {
- int (*external_reset)(void);
-
- bool use_eeprom;
-+
-+ int num_leds;
-+ const struct gpio_led *leds;
- };
-
- #endif /* _LINUX_ATH9K_PLATFORM_H */
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -15,6 +15,7 @@
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
-@@ -538,6 +538,11 @@ irqreturn_t ath_isr(int irq, void *dev)
+@@ -537,6 +537,11 @@ irqreturn_t ath_isr(int irq, void *dev)
return IRQ_HANDLED;
}
if (pdata && pdata->leds && pdata->num_leds)
for (i = 0; i < pdata->num_leds; i++) {
---- a/include/linux/ath9k_platform.h
-+++ b/include/linux/ath9k_platform.h
-@@ -49,6 +49,10 @@ struct ath9k_platform_data {
-
- int num_leds;
- const struct gpio_led *leds;
-+
-+ unsigned num_btns;
-+ const struct gpio_keys_button *btns;
-+ unsigned btn_poll_interval;
- };
-
- #endif /* _LINUX_ATH9K_PLATFORM_H */
static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop);
-@@ -659,6 +660,7 @@ void ath_reset_work(struct work_struct *
+@@ -658,6 +659,7 @@ void ath_reset_work(struct work_struct *
static int ath9k_start(struct ieee80211_hw *hw)
{
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan;
-@@ -737,6 +739,11 @@ static int ath9k_start(struct ieee80211_
+@@ -736,6 +738,11 @@ static int ath9k_start(struct ieee80211_
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
}
--- a/local-symbols
+++ b/local-symbols
-@@ -129,6 +129,7 @@ ATH9K_WOW=
+@@ -121,6 +121,7 @@ ATH9K_WOW=
ATH9K_RFKILL=
ATH9K_CHANNEL_CONTEXT=
ATH9K_PCOEM=
@set -e ; test -f local-symbols || ( \
echo "/--------------" ;\
echo "| You shouldn't run make in the backports tree, but only in" ;\
-@@ -60,58 +62,62 @@ mrproper:
+@@ -60,57 +62,61 @@ mrproper:
echo "| (that isn't currently running.)" ;\
echo "\\--" ;\
false)
- done \
- ) > Kconfig.kernel ;\
- kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \
-- kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
+- kernelversion | sed 's/^\(\([3-6]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
- test "$$kver" != "" || echo "Kernel version parse failed!" ;\
- test "$$kver" != "" ;\
-- kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\
-- kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\
- kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')" ;\
-- kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')" ;\
+- kvers="$$kvers $$(seq 0 19 | sed 's/^/5./')" ;\
+- kvers="$$kvers $$(seq 0 20 | sed 's/^/6./')" ;\
- print=0 ;\
- for v in $$kvers ; do \
- if [ "$$print" = "1" ] ; then \
+
+Kconfig.versions: Kconfig.kernel
+ @kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \
-+ kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
++ kernelversion | sed 's/^\(\([3-6]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
+ test "$$kver" != "" || echo "Kernel version parse failed!" ;\
+ test "$$kver" != "" ;\
-+ kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\
-+ kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\
+ kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')" ;\
-+ kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')" ;\
++ kvers="$$kvers $$(seq 0 19 | sed 's/^/5./')" ;\
++ kvers="$$kvers $$(seq 0 20 | sed 's/^/6./')" ;\
+ print=0 ;\
+ for v in $$kvers ; do \
+ if [ "$$print" = "1" ] ; then \
--- a/local-symbols
+++ b/local-symbols
-@@ -470,43 +470,6 @@ USB_VL600=
+@@ -462,43 +462,6 @@ USB_VL600=
USB_NET_CH9200=
USB_NET_AQC111=
USB_RTL8153_ECM=
config B43_PHY_G
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
-@@ -2853,7 +2853,7 @@ static struct ssb_device *b43_ssb_gpio_d
+@@ -2854,7 +2854,7 @@ static struct ssb_device *b43_ssb_gpio_d
{
struct ssb_bus *bus = dev->dev->sdev->bus;
return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
#else
return bus->chipco.dev;
-@@ -4871,7 +4871,7 @@ static int b43_wireless_core_init(struct
+@@ -4873,7 +4873,7 @@ static int b43_wireless_core_init(struct
}
if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
depends on CORDIC
--- a/Kconfig.local
+++ b/Kconfig.local
-@@ -1414,117 +1414,6 @@ config BACKPORTED_USB_NET_AQC111
+@@ -1390,117 +1390,6 @@ config BACKPORTED_USB_NET_AQC111
config BACKPORTED_USB_RTL8153_ECM
tristate
default USB_RTL8153_ECM
source "$BACKPORT_DIR/drivers/staging/Kconfig"
--- a/Makefile.kernel
+++ b/Makefile.kernel
-@@ -43,8 +43,6 @@ obj-$(CPTCFG_QRTR) += net/qrtr/
+@@ -42,8 +42,6 @@ obj-$(CPTCFG_QRTR) += net/qrtr/
obj-$(CPTCFG_QCOM_QMI_HELPERS) += drivers/soc/qcom/
obj-$(CPTCFG_MHI_BUS) += drivers/bus/mhi/
obj-$(CPTCFG_WLAN) += drivers/net/wireless/
+++ /dev/null
---- a/drivers/net/wireless/mac80211_hwsim.c
-+++ b/drivers/net/wireless/mac80211_hwsim.c
-@@ -5363,7 +5363,9 @@ static struct genl_family hwsim_genl_fam
- .module = THIS_MODULE,
- .small_ops = hwsim_ops,
- .n_small_ops = ARRAY_SIZE(hwsim_ops),
-+#if LINUX_VERSION_IS_GEQ(6,1,0)
- .resv_start_op = HWSIM_CMD_DEL_MAC_ADDR + 1,
-+#endif
- .mcgrps = hwsim_mcgrps,
- .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
- };
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -17233,7 +17233,9 @@ static struct genl_family nl80211_fam __
- .n_ops = ARRAY_SIZE(nl80211_ops),
- .small_ops = nl80211_small_ops,
- .n_small_ops = ARRAY_SIZE(nl80211_small_ops),
-+#if LINUX_VERSION_IS_GEQ(6,1,0)
- .resv_start_op = NL80211_CMD_REMOVE_LINK_STA + 1,
-+#endif
- .mcgrps = nl80211_mcgrps,
- .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
- .parallel_ops = true,
also requires QRTR however its AHB variant from the kernel will conflict
with the core provided by backports.
-Since MHI also conflicts with existing libreCMC kmods providing MHI drop
-both from backports and use the ones provided by libreCMC kernel.
+Since MHI also conflicts with existing OpenWrt kmods providing MHI drop
+both from backports and use the ones provided by OpenWrt kernel.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
source "$BACKPORT_DIR/drivers/net/usb/Kconfig"
--- a/Makefile.kernel
+++ b/Makefile.kernel
-@@ -39,9 +39,7 @@ obj-y += compat/
+@@ -38,9 +38,7 @@ obj-y += compat/
obj-$(CPTCFG_CFG80211) += net/wireless/
obj-$(CPTCFG_MAC80211) += net/mac80211/
--- a/local-symbols
+++ b/local-symbols
-@@ -65,14 +65,6 @@ MAC80211_MESH_PS_DEBUG=
+@@ -57,14 +57,6 @@ MAC80211_MESH_PS_DEBUG=
MAC80211_TDLS_DEBUG=
MAC80211_DEBUG_COUNTERS=
MAC80211_STA_HASH_MAX_SIZE=
+++ /dev/null
---- a/backport-include/linux/skbuff.h
-+++ b/backport-include/linux/skbuff.h
-@@ -144,4 +144,8 @@ static inline u64 skb_get_kcov_handle(st
- #define napi_build_skb build_skb
- #endif
-
-+#if LINUX_VERSION_IS_LESS(5,11,0)
-+#define napi_build_skb build_skb
-+#endif
-+
- #endif /* __BACKPORT_SKBUFF_H */
Date: Mon, 27 Oct 2014 00:00:00 +0100
Subject: [PATCH] mac80211: preseve AP mode keys across STA reconnect
-Used for AP+STA support in libreCMC - preserve AP mode keys across STA reconnect
+Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnect
---
net/mac80211/cfg.c | 1 -
1 file changed, 1 deletion(-)
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1519,7 +1519,6 @@ static int ieee80211_stop_ap(struct wiph
+@@ -1523,7 +1523,6 @@ static int ieee80211_stop_ap(struct wiph
link_conf->bssid_indicator = 0;
__sta_info_flush(sdata, true);
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -2727,6 +2727,8 @@ static int ieee80211_scan(struct wiphy *
+@@ -2733,6 +2733,8 @@ static int ieee80211_scan(struct wiphy *
*/
fallthrough;
case NL80211_IFTYPE_AP:
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
-@@ -554,6 +554,7 @@ __sta_info_alloc(struct ieee80211_sub_if
+@@ -557,6 +557,7 @@ __sta_info_alloc(struct ieee80211_sub_if
INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
mutex_init(&sta->ampdu_mlme.mtx);
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -3984,7 +3984,7 @@ struct ieee80211_txq *ieee80211_next_txq
+@@ -3992,7 +3992,7 @@ struct ieee80211_txq *ieee80211_next_txq
if (deficit < 0)
sta->airtime[txqi->txq.ac].deficit +=
if (deficit < 0 || !aql_check) {
list_move_tail(&txqi->schedule_order,
-@@ -4127,7 +4127,8 @@ bool ieee80211_txq_may_transmit(struct i
+@@ -4135,7 +4135,8 @@ bool ieee80211_txq_may_transmit(struct i
}
sta = container_of(iter->txq.sta, struct sta_info, sta);
if (ieee80211_sta_deficit(sta, ac) < 0)
list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
}
-@@ -4135,7 +4136,7 @@ bool ieee80211_txq_may_transmit(struct i
+@@ -4143,7 +4144,7 @@ bool ieee80211_txq_may_transmit(struct i
if (sta->airtime[ac].deficit >= 0)
goto out;
*
* Drivers can optionally delegate responsibility for scheduling queues to
* mac80211, to take advantage of airtime fairness accounting. In this case, to
-@@ -2248,8 +2249,8 @@ struct ieee80211_link_sta {
+@@ -2257,8 +2258,8 @@ struct ieee80211_link_sta {
* For non MLO STA it will point to the deflink data. For MLO STA
* ieee80211_sta_recalc_aggregates() must be called to update it.
* @support_p2p_ps: indicates whether the STA supports P2P PS mechanism or not.
* @deflink: This holds the default link STA information, for non MLO STA all link
* specific STA information is accessed through @deflink or through
* link[0] which points to address of @deflink. For MLO Link STA
-@@ -5687,7 +5688,7 @@ void ieee80211_key_replay(struct ieee802
+@@ -5700,7 +5701,7 @@ void ieee80211_key_replay(struct ieee802
* @hw: pointer as obtained from ieee80211_alloc_hw().
* @queue: queue number (counted from zero).
*
*/
void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue);
-@@ -5696,7 +5697,7 @@ void ieee80211_wake_queue(struct ieee802
+@@ -5709,7 +5710,7 @@ void ieee80211_wake_queue(struct ieee802
* @hw: pointer as obtained from ieee80211_alloc_hw().
* @queue: queue number (counted from zero).
*
*/
void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue);
-@@ -5705,7 +5706,7 @@ void ieee80211_stop_queue(struct ieee802
+@@ -5718,7 +5719,7 @@ void ieee80211_stop_queue(struct ieee802
* @hw: pointer as obtained from ieee80211_alloc_hw().
* @queue: queue number (counted from zero).
*
*
* Return: %true if the queue is stopped. %false otherwise.
*/
-@@ -5716,7 +5717,7 @@ int ieee80211_queue_stopped(struct ieee8
+@@ -5729,7 +5730,7 @@ int ieee80211_queue_stopped(struct ieee8
* ieee80211_stop_queues - stop all queues
* @hw: pointer as obtained from ieee80211_alloc_hw().
*
*/
void ieee80211_stop_queues(struct ieee80211_hw *hw);
-@@ -5724,7 +5725,7 @@ void ieee80211_stop_queues(struct ieee80
+@@ -5737,7 +5738,7 @@ void ieee80211_stop_queues(struct ieee80
* ieee80211_wake_queues - wake all queues
* @hw: pointer as obtained from ieee80211_alloc_hw().
*
*/
void ieee80211_wake_queues(struct ieee80211_hw *hw);
-@@ -6946,6 +6947,18 @@ static inline struct sk_buff *ieee80211_
+@@ -6960,6 +6961,18 @@ static inline struct sk_buff *ieee80211_
}
/**
.remove_interface = ar5523_remove_interface,
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -8587,6 +8587,7 @@ err_fallback:
+@@ -8592,6 +8592,7 @@ err_fallback:
static const struct ieee80211_ops ath11k_ops = {
.tx = ath11k_mac_op_tx,
.config = at76_config,
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
-@@ -5171,6 +5171,7 @@ static int b43_op_get_survey(struct ieee
+@@ -5173,6 +5173,7 @@ static int b43_op_get_survey(struct ieee
static const struct ieee80211_ops b43_hw_ops = {
.tx = b43_op_tx,
.add_interface = rtl8187_add_interface,
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -6548,6 +6548,7 @@ static void rtl8xxxu_stop(struct ieee802
+@@ -6546,6 +6546,7 @@ static void rtl8xxxu_stop(struct ieee802
static const struct ieee80211_ops rtl8xxxu_ops = {
.tx = rtl8xxxu_tx,
.change_interface = rtl_op_change_interface,
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
-@@ -896,6 +896,7 @@ static void rtw_ops_sta_rc_update(struct
+@@ -892,6 +892,7 @@ static void rtw_ops_sta_rc_update(struct
const struct ieee80211_ops rtw_ops = {
.tx = rtw_ops_tx,
.stop = rtw_ops_stop,
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
-@@ -918,6 +918,7 @@ static int rtw89_ops_set_tid_config(stru
+@@ -916,6 +916,7 @@ static int rtw89_ops_set_tid_config(stru
const struct ieee80211_ops rtw89_ops = {
.tx = rtw89_ops_tx,
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -4346,9 +4346,6 @@ static int ieee80211_get_txq_stats(struc
+@@ -4357,9 +4357,6 @@ static int ieee80211_get_txq_stats(struc
struct ieee80211_sub_if_data *sdata;
int ret = 0;
NL80211_EXT_FEATURE_AQL))
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -2294,7 +2294,6 @@ void ieee80211_wake_queue_by_reason(stru
+@@ -2300,7 +2300,6 @@ void ieee80211_wake_queue_by_reason(stru
void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
enum queue_stop_reason reason,
bool refcounted);
ieee80211_roc_purge(local, sdata);
switch (sdata->vif.type) {
-@@ -813,13 +807,6 @@ static void ieee80211_uninit(struct net_
+@@ -813,25 +807,6 @@ static void ieee80211_uninit(struct net_
ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
}
+-#if LINUX_VERSION_IS_GEQ(5,2,0)
-static u16 ieee80211_netdev_select_queue(struct net_device *dev,
- struct sk_buff *skb,
- struct net_device *sb_dev)
+-#elif LINUX_VERSION_IS_GEQ(4,19,0)
+-static u16 ieee80211_netdev_select_queue(struct net_device *dev,
+- struct sk_buff *skb,
+- struct net_device *sb_dev,
+- select_queue_fallback_t fallback)
+-#else
+-static u16 ieee80211_netdev_select_queue(struct net_device *dev,
+- struct sk_buff *skb,
+- void *accel_priv,
+- select_queue_fallback_t fallback)
+-#endif
-{
- return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb);
-}
static void
ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
-@@ -833,7 +820,6 @@ static const struct net_device_ops ieee8
+@@ -845,7 +820,6 @@ static const struct net_device_ops ieee8
.ndo_start_xmit = ieee80211_subif_start_xmit,
.ndo_set_rx_mode = ieee80211_set_multicast_list,
.ndo_set_mac_address = ieee80211_change_mac,
.ndo_get_stats64 = ieee80211_get_stats64,
};
-@@ -941,7 +927,6 @@ static const struct net_device_ops ieee8
+@@ -967,7 +941,6 @@ static const struct net_device_ops ieee8
.ndo_start_xmit = ieee80211_subif_start_xmit_8023,
.ndo_set_rx_mode = ieee80211_set_multicast_list,
.ndo_set_mac_address = ieee80211_change_mac,
- .ndo_select_queue = ieee80211_netdev_select_queue,
.ndo_get_stats64 = ieee80211_get_stats64,
+ #if LINUX_VERSION_IS_GEQ(5,13,0)
.ndo_fill_forward_path = ieee80211_netdev_fill_forward_path,
- };
-@@ -1443,35 +1428,6 @@ int ieee80211_do_open(struct wireless_de
+@@ -1471,35 +1444,6 @@ int ieee80211_do_open(struct wireless_de
ieee80211_recalc_ps(local);
set_bit(SDATA_STATE_RUNNING, &sdata->state);
return 0;
-@@ -1501,17 +1457,12 @@ static void ieee80211_if_setup(struct ne
+@@ -1529,17 +1473,12 @@ static void ieee80211_if_setup(struct ne
{
ether_setup(dev);
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
static void ieee80211_iface_process_skb(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb)
-@@ -2096,9 +2047,7 @@ int ieee80211_if_add(struct ieee80211_lo
+@@ -2124,9 +2063,7 @@ int ieee80211_if_add(struct ieee80211_lo
struct net_device *ndev = NULL;
struct ieee80211_sub_if_data *sdata = NULL;
struct txq_info *txqi;
ASSERT_RTNL();
-@@ -2121,30 +2070,18 @@ int ieee80211_if_add(struct ieee80211_lo
+@@ -2149,30 +2086,18 @@ int ieee80211_if_add(struct ieee80211_lo
sizeof(void *));
int txq_size = 0;
ndev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
-@@ -630,7 +630,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
+@@ -627,7 +627,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config ||
!ops->add_interface || !ops->remove_interface ||
return NULL;
if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove)))
-@@ -719,9 +719,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
+@@ -716,9 +716,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
if (!ops->set_key)
wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM);
wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
-@@ -834,10 +832,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
+@@ -831,10 +829,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
atomic_set(&local->agg_queue_stop[i], 0);
}
tasklet_setup(&local->tx_pending_tasklet, ieee80211_tx_pending);
skb_queue_head_init(&local->skb_queue);
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -1571,9 +1571,6 @@ static void sta_ps_start(struct sta_info
+@@ -1573,9 +1573,6 @@ static void sta_ps_start(struct sta_info
ieee80211_clear_fast_xmit(sta);
}
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-@@ -425,8 +423,7 @@ void sta_info_free(struct ieee80211_loca
+@@ -428,8 +426,7 @@ void sta_info_free(struct ieee80211_loca
sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
kfree(rcu_dereference_raw(sta->sta.rates));
#ifdef CPTCFG_MAC80211_MESH
kfree(sta->mesh);
-@@ -527,6 +524,8 @@ __sta_info_alloc(struct ieee80211_sub_if
+@@ -530,6 +527,8 @@ __sta_info_alloc(struct ieee80211_sub_if
struct ieee80211_local *local = sdata->local;
struct ieee80211_hw *hw = &local->hw;
struct sta_info *sta;
int i;
sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
-@@ -597,21 +596,18 @@ __sta_info_alloc(struct ieee80211_sub_if
+@@ -600,21 +599,18 @@ __sta_info_alloc(struct ieee80211_sub_if
sta->last_connected = ktime_get_seconds();
}
if (sta_prepare_rate_control(local, sta, gfp))
-@@ -685,8 +681,7 @@ __sta_info_alloc(struct ieee80211_sub_if
+@@ -688,8 +684,7 @@ __sta_info_alloc(struct ieee80211_sub_if
return sta;
free_txq:
free:
sta_info_free_link(&sta->deflink);
#ifdef CPTCFG_MAC80211_MESH
-@@ -1960,9 +1955,6 @@ ieee80211_sta_ps_deliver_response(struct
+@@ -1965,9 +1960,6 @@ ieee80211_sta_ps_deliver_response(struct
* TIM recalculation.
*/
for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
if (!sta->sta.txq[tid] ||
!(driver_release_tids & BIT(tid)) ||
-@@ -2447,7 +2439,7 @@ static void sta_set_tidstats(struct sta_
+@@ -2452,7 +2444,7 @@ static void sta_set_tidstats(struct sta_
tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid];
}
spin_lock_bh(&local->fq.lock);
rcu_read_lock();
-@@ -2775,9 +2767,6 @@ unsigned long ieee80211_sta_last_active(
+@@ -2780,9 +2772,6 @@ unsigned long ieee80211_sta_last_active(
static void sta_update_codel_params(struct sta_info *sta, u32 thr)
{
* Set the WLAN_TDLS_TEARDOWN flag to indicate a teardown in progress.
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -1600,9 +1600,6 @@ int ieee80211_txq_setup_flows(struct iee
+@@ -1606,9 +1606,6 @@ int ieee80211_txq_setup_flows(struct iee
bool supp_vht = false;
enum nl80211_band band;
ret = fq_init(fq, 4096);
if (ret)
return ret;
-@@ -1650,9 +1647,6 @@ void ieee80211_txq_teardown_flows(struct
+@@ -1656,9 +1653,6 @@ void ieee80211_txq_teardown_flows(struct
{
struct fq *fq = &local->fq;
kfree(local->cvars);
local->cvars = NULL;
-@@ -1669,8 +1663,7 @@ static bool ieee80211_queue_skb(struct i
+@@ -1675,8 +1669,7 @@ static bool ieee80211_queue_skb(struct i
struct ieee80211_vif *vif;
struct txq_info *txqi;
return false;
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-@@ -4193,12 +4186,7 @@ void __ieee80211_subif_start_xmit(struct
+@@ -4201,12 +4194,7 @@ void __ieee80211_subif_start_xmit(struct
if (IS_ERR(sta))
sta = NULL;
ieee80211_aggr_check(sdata, sta, skb);
sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
-@@ -4509,11 +4497,7 @@ static void ieee80211_8023_xmit(struct i
+@@ -4517,11 +4505,7 @@ static void ieee80211_8023_xmit(struct i
struct tid_ampdu_tx *tid_tx;
u8 tid;
if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) &&
test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
-@@ -4767,9 +4751,6 @@ void ieee80211_tx_pending(struct tasklet
+@@ -4775,9 +4759,6 @@ void ieee80211_tx_pending(struct tasklet
if (!txok)
break;
}
}
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-@@ -5962,10 +5943,9 @@ int ieee80211_tx_control_port(struct wip
+@@ -5970,10 +5951,9 @@ int ieee80211_tx_control_port(struct wip
}
if (!IS_ERR(sta)) {
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
-@@ -896,7 +896,6 @@ static void rtw_ops_sta_rc_update(struct
+@@ -892,7 +892,6 @@ static void rtw_ops_sta_rc_update(struct
const struct ieee80211_ops rtw_ops = {
.tx = rtw_ops_tx,
.stop = rtw_ops_stop,
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
-@@ -918,7 +918,6 @@ static int rtw89_ops_set_tid_config(stru
+@@ -916,7 +916,6 @@ static int rtw89_ops_set_tid_config(stru
const struct ieee80211_ops rtw89_ops = {
.tx = rtw89_ops_tx,
flow = fq_find_fattest_flow(fq);
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -1807,6 +1807,10 @@ struct ieee80211_vif_cfg {
+@@ -1816,6 +1816,10 @@ struct ieee80211_vif_cfg {
* @addr: address of this interface
* @p2p: indicates whether this AP or STA interface is a p2p
* interface, i.e. a GO or p2p-sta respectively
* @driver_flags: flags/capabilities the driver has for this interface,
* these need to be set (or cleared) when the interface is added
* or, if supported by the driver, the interface type is changed
-@@ -1846,6 +1850,7 @@ struct ieee80211_vif {
+@@ -1855,6 +1859,7 @@ struct ieee80211_vif {
struct ieee80211_txq *txq;
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
-@@ -2181,6 +2181,7 @@ int ieee80211_if_add(struct ieee80211_lo
+@@ -2197,6 +2197,7 @@ int ieee80211_if_add(struct ieee80211_lo
ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
ndev->hw_features |= ndev->features &
MAC80211_SUPPORTED_FEATURES_TX;
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -1356,7 +1356,11 @@ static struct txq_info *ieee80211_get_tx
+@@ -1362,7 +1362,11 @@ static struct txq_info *ieee80211_get_tx
static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb)
{
}
static u32 codel_skb_len_func(const struct sk_buff *skb)
-@@ -3579,55 +3583,79 @@ ieee80211_xmit_fast_finish(struct ieee80
+@@ -3585,55 +3589,79 @@ ieee80211_xmit_fast_finish(struct ieee80
return TX_CONTINUE;
}
/* will not be crypto-handled beyond what we do here, so use false
* as the may-encrypt argument for the resize to not account for
-@@ -3636,10 +3664,8 @@ static bool ieee80211_xmit_fast(struct i
+@@ -3642,10 +3670,8 @@ static bool ieee80211_xmit_fast(struct i
if (unlikely(ieee80211_skb_resize(sdata, skb,
max_t(int, extra_head + hw_headroom -
skb_headroom(skb), 0),
memcpy(ð, skb->data, ETH_HLEN - 2);
hdr = skb_push(skb, extra_head);
-@@ -3653,7 +3679,7 @@ static bool ieee80211_xmit_fast(struct i
+@@ -3659,7 +3685,7 @@ static bool ieee80211_xmit_fast(struct i
info->control.vif = &sdata->vif;
info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT |
IEEE80211_TX_CTL_DONTFRAG |
info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT |
u32_encode_bits(IEEE80211_LINK_UNSPECIFIED,
IEEE80211_TX_CTRL_MLO_LINK);
-@@ -3677,16 +3703,14 @@ static bool ieee80211_xmit_fast(struct i
+@@ -3683,16 +3709,14 @@ static bool ieee80211_xmit_fast(struct i
tx.key = fast_tx->key;
if (ieee80211_queue_skb(local, sdata, sta, skb))
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
sdata = container_of(sdata->bss,
-@@ -3694,6 +3718,56 @@ static bool ieee80211_xmit_fast(struct i
+@@ -3700,6 +3724,56 @@ static bool ieee80211_xmit_fast(struct i
__skb_queue_tail(&tx.skbs, skb);
ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false);
return true;
}
-@@ -4201,31 +4275,14 @@ void __ieee80211_subif_start_xmit(struct
+@@ -4209,31 +4283,14 @@ void __ieee80211_subif_start_xmit(struct
goto out;
}
}
skb_list_walk_safe(skb, skb, next) {
-@@ -4443,9 +4500,11 @@ normal:
+@@ -4451,9 +4508,11 @@ normal:
return NETDEV_TX_OK;
}
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_tx_control control = {};
-@@ -4454,14 +4513,6 @@ static bool ieee80211_tx_8023(struct iee
+@@ -4462,14 +4521,6 @@ static bool ieee80211_tx_8023(struct iee
unsigned long flags;
int q = info->hw_queue;
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
if (local->queue_stop_reasons[q] ||
-@@ -4488,6 +4539,26 @@ static bool ieee80211_tx_8023(struct iee
+@@ -4496,6 +4547,26 @@ static bool ieee80211_tx_8023(struct iee
return true;
}
static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
struct net_device *dev, struct sta_info *sta,
struct ieee80211_key *key, struct sk_buff *skb)
-@@ -4495,9 +4566,13 @@ static void ieee80211_8023_xmit(struct i
+@@ -4503,9 +4574,13 @@ static void ieee80211_8023_xmit(struct i
struct ieee80211_tx_info *info;
struct ieee80211_local *local = sdata->local;
struct tid_ampdu_tx *tid_tx;
if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) &&
test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
-@@ -4507,9 +4582,6 @@ static void ieee80211_8023_xmit(struct i
+@@ -4515,9 +4590,6 @@ static void ieee80211_8023_xmit(struct i
if (unlikely(!skb))
return;
ieee80211_aggr_check(sdata, sta, skb);
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-@@ -4523,22 +4595,20 @@ static void ieee80211_8023_xmit(struct i
+@@ -4531,22 +4603,20 @@ static void ieee80211_8023_xmit(struct i
return;
}
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
sdata = container_of(sdata->bss,
-@@ -4550,6 +4620,24 @@ static void ieee80211_8023_xmit(struct i
+@@ -4558,6 +4628,24 @@ static void ieee80211_8023_xmit(struct i
if (key)
info->control.hw_key = &key->conf;
ieee80211_tx_8023(sdata, skb, sta, false);
return;
-@@ -4591,6 +4679,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8
+@@ -4599,6 +4687,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8
key->conf.cipher == WLAN_CIPHER_SUITE_TKIP))
goto skip_offload;
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2403,7 +2403,6 @@ static int ieee80211_802_1x_port_control
+@@ -2405,7 +2405,6 @@ static int ieee80211_802_1x_port_control
static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
{
struct sk_buff *skb = rx->skb;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
-@@ -2414,31 +2413,6 @@ static int ieee80211_drop_unencrypted(st
+@@ -2416,31 +2415,6 @@ static int ieee80211_drop_unencrypted(st
if (status->flag & RX_FLAG_DECRYPTED)
return 0;
/* Drop unencrypted frames if key is set. */
if (unlikely(!ieee80211_has_protected(fc) &&
!ieee80211_is_any_nullfunc(fc) &&
-@@ -2892,8 +2866,16 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
+@@ -2898,8 +2872,16 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
hdr = (struct ieee80211_hdr *) skb->data;
mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -329,7 +329,6 @@ struct mesh_stats {
+@@ -333,7 +333,6 @@ struct mesh_stats {
__u32 fwded_frames; /* Mesh total forwarded frames */
__u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/
__u32 dropped_frames_no_route; /* Not transmitted, no route found */
#define PREQ_Q_F_START 0x1
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2926,11 +2926,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
+@@ -2932,11 +2932,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
return RX_CONTINUE;
ac = ieee802_1d_to_ac[skb->priority];
struct rx_packet_hdr *rx_hdr;
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -6208,11 +6208,36 @@ static inline int ieee80211_data_to_8023
+@@ -6324,11 +6324,36 @@ static inline int ieee80211_data_to_8023
* @extra_headroom: The hardware extra headroom for SKBs in the @list.
* @check_da: DA to check in the inner ethernet header, or NULL
* @check_sa: SA to check in the inner ethernet header, or NULL
* cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2720,6 +2720,174 @@ ieee80211_deliver_skb(struct ieee80211_r
+@@ -2726,6 +2726,174 @@ ieee80211_deliver_skb(struct ieee80211_r
}
}
static ieee80211_rx_result debug_noinline
__ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
{
-@@ -2728,8 +2896,10 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
+@@ -2734,8 +2902,10 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
__le16 fc = hdr->frame_control;
struct sk_buff_head frame_list;
if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
check_da = NULL;
-@@ -2746,6 +2916,8 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
+@@ -2752,6 +2922,8 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
break;
case NL80211_IFTYPE_MESH_POINT:
check_sa = NULL;
break;
default:
break;
-@@ -2763,17 +2935,29 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
+@@ -2769,17 +2941,29 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
rx->sdata->vif.type,
rx->local->hw.extra_tx_headroom,
}
return RX_QUEUED;
-@@ -2806,6 +2990,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
+@@ -2812,6 +2996,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
if (!rx->sdata->u.mgd.use_4addr)
return RX_DROP_UNUSABLE;
break;
default:
return RX_DROP_UNUSABLE;
}
-@@ -2834,155 +3020,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
+@@ -2840,155 +3026,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
return __ieee80211_rx_h_amsdu(rx, 0);
}
static ieee80211_rx_result debug_noinline
ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
{
-@@ -2991,6 +3028,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_
+@@ -2997,6 +3034,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_
struct net_device *dev = sdata->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
__le16 fc = hdr->frame_control;
bool port_control;
int err;
-@@ -3017,6 +3055,10 @@ ieee80211_rx_h_data(struct ieee80211_rx_
+@@ -3023,6 +3061,10 @@ ieee80211_rx_h_data(struct ieee80211_rx_
if (unlikely(err))
return RX_DROP_UNUSABLE;
if (!ieee80211_frame_allowed(rx, fc))
return RX_DROP_MONITOR;
-@@ -3987,10 +4029,6 @@ static void ieee80211_rx_handlers(struct
+@@ -3997,10 +4039,6 @@ static void ieee80211_rx_handlers(struct
CALL_RXH(ieee80211_rx_h_defragment);
CALL_RXH(ieee80211_rx_h_michael_mic_verify);
/* must be after MMIC verify so header is counted in MPDU mic */
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -6194,6 +6194,19 @@ static inline int ieee80211_data_to_8023
+@@ -6310,6 +6310,19 @@ static inline int ieee80211_data_to_8023
}
/**
* Decode an IEEE 802.11 A-MSDU and convert it to a list of 802.3 frames.
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2899,7 +2899,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
+@@ -2905,7 +2905,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
static ieee80211_rx_result res;
struct ethhdr ethhdr;
const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
check_da = NULL;
-@@ -2917,7 +2916,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
+@@ -2923,7 +2922,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
case NL80211_IFTYPE_MESH_POINT:
check_sa = NULL;
check_da = NULL;
break;
default:
break;
-@@ -2932,10 +2930,21 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
+@@ -2938,10 +2936,21 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
data_offset, true))
return RX_DROP_UNUSABLE;
rx->skb = __skb_dequeue(&frame_list);
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
-@@ -591,6 +591,9 @@ __sta_info_alloc(struct ieee80211_sub_if
+@@ -594,6 +594,9 @@ __sta_info_alloc(struct ieee80211_sub_if
sta->sta_state = IEEE80211_STA_NONE;
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -696,7 +696,7 @@ struct ieee80211_if_mesh {
+@@ -700,7 +700,7 @@ struct ieee80211_if_mesh {
struct mesh_stats mshstats;
struct mesh_config mshcfg;
atomic_t estab_plinks;
/* Maximum number of broadcast/multicast frames to buffer when some of the
* associated stations are using power saving. */
-@@ -656,6 +657,19 @@ struct mesh_table {
+@@ -660,6 +661,19 @@ struct mesh_table {
atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */
};
struct ieee80211_if_mesh {
struct timer_list housekeeping_timer;
struct timer_list mesh_path_timer;
-@@ -734,6 +748,7 @@ struct ieee80211_if_mesh {
+@@ -738,6 +752,7 @@ struct ieee80211_if_mesh {
struct mesh_table mpp_paths; /* Store paths for MPP&MAP */
int mesh_paths_generation;
int mpp_paths_generation;
};
#ifdef CPTCFG_MAC80211_MESH
-@@ -2002,6 +2017,11 @@ int ieee80211_tx_control_port(struct wip
+@@ -2007,6 +2022,11 @@ int ieee80211_tx_control_port(struct wip
int link_id, u64 *cookie);
int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len);
mesh_path_free_rcu(tbl, mpath);
}
-@@ -747,6 +1026,7 @@ void mesh_path_fix_nexthop(struct mesh_p
+@@ -760,6 +1039,7 @@ void mesh_path_fix_nexthop(struct mesh_p
mpath->exp_time = 0;
mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID;
mesh_path_activate(mpath);
spin_unlock_bh(&mpath->state_lock);
ewma_mesh_fail_avg_init(&next_hop->mesh->fail_avg);
/* init it at a low value - 0 start is tricky */
-@@ -758,6 +1038,7 @@ void mesh_pathtbl_init(struct ieee80211_
+@@ -771,6 +1051,7 @@ void mesh_pathtbl_init(struct ieee80211_
{
mesh_table_init(&sdata->u.mesh.mesh_paths);
mesh_table_init(&sdata->u.mesh.mpp_paths);
}
static
-@@ -785,6 +1066,7 @@ void mesh_path_expire(struct ieee80211_s
+@@ -798,6 +1079,7 @@ void mesh_path_expire(struct ieee80211_s
void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata)
{
}
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2791,6 +2791,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
+@@ -2797,6 +2797,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
if (mesh_hdr->flags & MESH_FLAGS_AE) {
struct mesh_path *mppath;
char *proxied_addr;
if (multicast)
proxied_addr = mesh_hdr->eaddr1;
-@@ -2806,11 +2807,18 @@ ieee80211_rx_mesh_data(struct ieee80211_
+@@ -2812,11 +2813,18 @@ ieee80211_rx_mesh_data(struct ieee80211_
mpp_path_add(sdata, proxied_addr, eth->h_source);
} else {
spin_lock_bh(&mppath->state_lock);
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -3022,6 +3022,9 @@ void ieee80211_check_fast_xmit(struct st
+@@ -3028,6 +3028,9 @@ void ieee80211_check_fast_xmit(struct st
if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT))
return;
/* Locking here protects both the pointer itself, and against concurrent
* invocations winning data access races to, e.g., the key pointer that
* is used.
-@@ -3403,6 +3406,9 @@ static bool ieee80211_amsdu_aggregate(st
+@@ -3409,6 +3412,9 @@ static bool ieee80211_amsdu_aggregate(st
if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
return false;
if (skb_is_gso(skb))
return false;
-@@ -3635,10 +3641,11 @@ free:
+@@ -3641,10 +3647,11 @@ free:
return NULL;
}
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
-@@ -3647,7 +3654,6 @@ static void __ieee80211_xmit_fast(struct
+@@ -3653,7 +3660,6 @@ static void __ieee80211_xmit_fast(struct
ieee80211_tx_result r;
int hw_headroom = sdata->local->hw.extra_tx_headroom;
int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
-@@ -3667,11 +3673,10 @@ static void __ieee80211_xmit_fast(struct
+@@ -3673,11 +3679,10 @@ static void __ieee80211_xmit_fast(struct
ENCRYPT_NO)))
goto free;
info = IEEE80211_SKB_CB(skb);
memset(info, 0, sizeof(*info));
-@@ -3690,7 +3695,8 @@ static void __ieee80211_xmit_fast(struct
+@@ -3696,7 +3701,8 @@ static void __ieee80211_xmit_fast(struct
#endif
if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
*ieee80211_get_qos_ctl(hdr) = tid;
}
-@@ -3733,6 +3739,7 @@ static bool ieee80211_xmit_fast(struct i
+@@ -3739,6 +3745,7 @@ static bool ieee80211_xmit_fast(struct i
struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
struct tid_ampdu_tx *tid_tx = NULL;
struct sk_buff *next;
u8 tid = IEEE80211_NUM_TIDS;
/* control port protocol needs a lot of special handling */
-@@ -3758,6 +3765,8 @@ static bool ieee80211_xmit_fast(struct i
+@@ -3764,6 +3771,8 @@ static bool ieee80211_xmit_fast(struct i
}
}
/* after this point (skb is modified) we cannot return false */
skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata));
if (!skb)
-@@ -3765,7 +3774,8 @@ static bool ieee80211_xmit_fast(struct i
+@@ -3771,7 +3780,8 @@ static bool ieee80211_xmit_fast(struct i
skb_list_walk_safe(skb, skb, next) {
skb_mark_not_on_list(skb);
}
return true;
-@@ -4252,8 +4262,15 @@ void __ieee80211_subif_start_xmit(struct
+@@ -4260,8 +4270,15 @@ void __ieee80211_subif_start_xmit(struct
return;
}
if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
goto out_free;
-@@ -4263,8 +4280,6 @@ void __ieee80211_subif_start_xmit(struct
+@@ -4271,8 +4288,6 @@ void __ieee80211_subif_start_xmit(struct
skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
ieee80211_aggr_check(sdata, sta, skb);
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2720,6 +2720,65 @@ ieee80211_deliver_skb(struct ieee80211_r
+@@ -2726,6 +2726,65 @@ ieee80211_deliver_skb(struct ieee80211_r
}
}
static ieee80211_rx_result
ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta,
struct sk_buff *skb)
-@@ -2824,6 +2883,10 @@ ieee80211_rx_mesh_data(struct ieee80211_
+@@ -2830,6 +2889,10 @@ ieee80211_rx_mesh_data(struct ieee80211_
skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]);
ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control,
eth->h_dest, eth->h_source);
hdrlen = ieee80211_hdrlen(hdr.frame_control);
-@@ -2862,6 +2925,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
+@@ -2868,6 +2931,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
info->control.vif = &sdata->vif;
info->control.jiffies = jiffies;
if (multicast) {
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
-@@ -2883,7 +2947,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
+@@ -2889,7 +2953,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
}
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
rx_accept:
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -2022,6 +2022,8 @@ void __ieee80211_xmit_fast(struct ieee80
+@@ -2027,6 +2027,8 @@ void __ieee80211_xmit_fast(struct ieee80
struct ieee80211_fast_tx *fast_tx,
struct sk_buff *skb, bool ampdu,
const u8 *da, const u8 *sa);
void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -1191,10 +1191,8 @@ static bool ieee80211_tx_prep_agg(struct
+@@ -1197,10 +1197,8 @@ static bool ieee80211_tx_prep_agg(struct
return queued;
}
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2904,6 +2904,9 @@ ieee80211_rx_mesh_data(struct ieee80211_
+@@ -2910,6 +2910,9 @@ ieee80211_rx_mesh_data(struct ieee80211_
if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr)))
return RX_DROP_UNUSABLE;
}
fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr));
-@@ -2918,7 +2921,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
+@@ -2924,7 +2927,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
hdrlen += ETH_ALEN;
else
fwd_skb->protocol = htons(fwd_skb->len - hdrlen);
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2824,17 +2824,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
+@@ -2830,17 +2830,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
mesh_rmc_check(sdata, eth->h_source, mesh_hdr))
return RX_DROP_MONITOR;
/* forward packet */
if (sdata->crypto_tx_tailroom_needed_cnt)
tailroom = IEEE80211_ENCRYPT_TAILROOM;
-@@ -2881,6 +2870,17 @@ ieee80211_rx_mesh_data(struct ieee80211_
+@@ -2887,6 +2876,17 @@ ieee80211_rx_mesh_data(struct ieee80211_
rcu_read_unlock();
}
/**
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1252,6 +1252,21 @@ static int ieee80211_start_ap(struct wip
+@@ -1255,6 +1255,21 @@ static int ieee80211_start_ap(struct wip
prev_beacon_int = link_conf->beacon_int;
link_conf->beacon_int = params->beacon_interval;
/**
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1281,6 +1281,21 @@ static int ieee80211_start_ap(struct wip
+@@ -1284,6 +1284,21 @@ static int ieee80211_start_ap(struct wip
changed |= BSS_CHANGED_HE_BSS_COLOR;
}
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -5964,6 +5964,18 @@ void ieee80211_queue_delayed_work(struct
+@@ -5977,6 +5977,18 @@ void ieee80211_queue_delayed_work(struct
unsigned long delay);
/**
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -4564,6 +4564,12 @@ void ieee80211_check_fast_rx(struct sta_
+@@ -4580,6 +4580,12 @@ void ieee80211_check_fast_rx(struct sta_
}
break;
default:
goto clear;
}
-@@ -4772,6 +4778,7 @@ static bool ieee80211_invoke_fast_rx(str
+@@ -4788,6 +4794,7 @@ static bool ieee80211_invoke_fast_rx(str
struct sk_buff *skb = rx->skb;
struct ieee80211_hdr *hdr = (void *)skb->data;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
int orig_len = skb->len;
int hdrlen = ieee80211_hdrlen(hdr->frame_control);
int snap_offs = hdrlen;
-@@ -4833,7 +4840,8 @@ static bool ieee80211_invoke_fast_rx(str
+@@ -4849,7 +4856,8 @@ static bool ieee80211_invoke_fast_rx(str
snap_offs += IEEE80211_CCMP_HDR_LEN;
}
if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
return false;
-@@ -4872,13 +4880,29 @@ static bool ieee80211_invoke_fast_rx(str
+@@ -4888,13 +4896,29 @@ static bool ieee80211_invoke_fast_rx(str
/* 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);
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -4192,6 +4192,10 @@ struct ieee80211_prep_tx_info {
+@@ -4201,6 +4201,10 @@ struct ieee80211_prep_tx_info {
* Note that a sta can also be inserted or removed with valid links,
* i.e. passed to @sta_add/@sta_state with sta->valid_links not zero.
* In fact, cannot change from having valid_links and not having them.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
-@@ -4547,6 +4551,11 @@ struct ieee80211_ops {
+@@ -4556,6 +4560,11 @@ struct ieee80211_ops {
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
u16 old_links, u16 new_links);
u16 old_links, u16 new_links,
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -1939,7 +1939,8 @@ void ieee80211_color_collision_detection
+@@ -1944,7 +1944,8 @@ void ieee80211_color_collision_detection
/* interface handling */
#define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
NETIF_F_HW_CSUM | NETIF_F_SG | \
+ .ndo_setup_tc = ieee80211_netdev_setup_tc,
};
- static u16 ieee80211_monitor_select_queue(struct net_device *dev,
-@@ -929,6 +945,7 @@ static const struct net_device_ops ieee8
- .ndo_set_mac_address = ieee80211_change_mac,
- .ndo_get_stats64 = ieee80211_get_stats64,
+ #if LINUX_VERSION_IS_GEQ(5,2,0)
+@@ -945,6 +961,7 @@ static const struct net_device_ops ieee8
+ #if LINUX_VERSION_IS_GEQ(5,13,0)
.ndo_fill_forward_path = ieee80211_netdev_fill_forward_path,
+ #endif
+ .ndo_setup_tc = ieee80211_netdev_setup_tc,
};
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2828,14 +2828,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
+@@ -2834,14 +2834,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
if (sdata->crypto_tx_tailroom_needed_cnt)
tailroom = IEEE80211_ENCRYPT_TAILROOM;
if (mesh_hdr->flags & MESH_FLAGS_AE) {
struct mesh_path *mppath;
char *proxied_addr;
-@@ -2874,6 +2866,14 @@ ieee80211_rx_mesh_data(struct ieee80211_
+@@ -2880,6 +2872,14 @@ ieee80211_rx_mesh_data(struct ieee80211_
if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
goto rx_accept;
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
-@@ -601,8 +601,9 @@ static void iwl_mvm_skb_prepare_status(s
+@@ -605,8 +605,9 @@ static void iwl_mvm_skb_prepare_status(s
static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm,
struct ieee80211_tx_info *info,
struct iwl_mvm_vif *mvmvif =
iwl_mvm_vif_from_mac80211(info->control.vif);
__le16 fc = hdr->frame_control;
-@@ -621,7 +622,7 @@ static int iwl_mvm_get_ctrl_vif_queue(st
+@@ -625,7 +626,7 @@ static int iwl_mvm_get_ctrl_vif_queue(st
* reason 7 ("Class 3 frame received from nonassociated STA").
*/
if (ieee80211_is_mgmt(fc) &&
ieee80211_is_deauth(fc) || ieee80211_is_disassoc(fc)))
return mvm->probe_queue;
-@@ -740,7 +741,7 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mv
+@@ -744,7 +745,7 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mv
else
sta_id = mvmvif->mcast_sta.sta_id;
* ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set
* @seq_ctrl: frame sequence control bytes in little-endian byteorder
*/
-@@ -4121,6 +4107,44 @@ static inline u8 *ieee80211_get_DA(struc
+@@ -4123,6 +4109,44 @@ static inline u8 *ieee80211_get_DA(struc
}
/**
info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
return TX_CONTINUE;
}
-@@ -1326,7 +1326,7 @@ static struct txq_info *ieee80211_get_tx
+@@ -1332,7 +1332,7 @@ static struct txq_info *ieee80211_get_tx
if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
unlikely(!ieee80211_is_data_present(hdr->frame_control))) {
if ((!ieee80211_is_mgmt(hdr->frame_control) ||
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
-@@ -1271,6 +1271,14 @@ static void __sta_info_destroy_part2(str
+@@ -1276,6 +1276,14 @@ static void __sta_info_destroy_part2(str
WARN_ON_ONCE(ret);
}
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
-@@ -4854,9 +4854,6 @@ static void iwl_mvm_mac_flush(struct iee
+@@ -4844,9 +4844,6 @@ static void iwl_mvm_mac_flush(struct iee
return;
}
/* Make sure we're done with the deferred traffic before flushing */
flush_work(&mvm->add_stream_wk);
-@@ -4874,9 +4871,6 @@ static void iwl_mvm_mac_flush(struct iee
+@@ -4864,9 +4861,6 @@ static void iwl_mvm_mac_flush(struct iee
if (mvmsta->vif != vif)
continue;
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -3918,6 +3918,10 @@ struct ieee80211_prep_tx_info {
+@@ -3927,6 +3927,10 @@ struct ieee80211_prep_tx_info {
* Note that vif can be NULL.
* The callback can sleep.
*
* @channel_switch: Drivers that need (or want) to offload the channel
* switch operation for CSAs received from the AP may implement this
* callback. They must then call ieee80211_chswitch_done() to indicate
-@@ -4372,6 +4376,8 @@ struct ieee80211_ops {
+@@ -4381,6 +4385,8 @@ struct ieee80211_ops {
#endif
void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop);
struct ieee80211_channel_switch *ch_switch)
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
-@@ -1276,8 +1276,12 @@ static void __sta_info_destroy_part2(str
+@@ -1281,8 +1281,12 @@ static void __sta_info_destroy_part2(str
* frames sitting on hardware queues might be sent out without
* any encryption at all.
*/
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
-@@ -4890,6 +4890,31 @@ static void iwl_mvm_mac_flush(struct iee
+@@ -4880,6 +4880,31 @@ static void iwl_mvm_mac_flush(struct iee
iwl_trans_wait_tx_queues_empty(mvm->trans, msk);
}
static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx,
struct survey_info *survey)
{
-@@ -5417,6 +5442,7 @@ const struct ieee80211_ops iwl_mvm_hw_op
+@@ -5407,6 +5432,7 @@ const struct ieee80211_ops iwl_mvm_hw_op
.mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx,
.mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover,
.flush = iwl_mvm_mac_flush,
bool vht_mu_beamformer;
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1252,7 +1252,15 @@ static int ieee80211_start_ap(struct wip
+@@ -1255,7 +1255,15 @@ static int ieee80211_start_ap(struct wip
prev_beacon_int = link_conf->beacon_int;
link_conf->beacon_int = params->beacon_interval;
link_conf->vht_su_beamformer =
params->vht_cap->vht_cap_info &
cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
-@@ -1282,6 +1290,9 @@ static int ieee80211_start_ap(struct wip
+@@ -1285,6 +1293,9 @@ static int ieee80211_start_ap(struct wip
}
if (params->he_cap) {
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -5252,6 +5252,74 @@ ieee80211_beacon_get_template(struct iee
+@@ -5265,6 +5265,74 @@ ieee80211_beacon_get_template(struct iee
unsigned int link_id);
/**
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1122,11 +1122,11 @@ static int ieee80211_assign_beacon(struc
+@@ -1125,11 +1125,11 @@ static int ieee80211_assign_beacon(struc
if (params->mbssid_ies) {
mbssid = params->mbssid_ies;
size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
}
new = kzalloc(size, GFP_KERNEL);
-@@ -3384,8 +3384,11 @@ cfg80211_beacon_dup(struct cfg80211_beac
+@@ -3394,8 +3394,11 @@ cfg80211_beacon_dup(struct cfg80211_beac
len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len +
beacon->proberesp_ies_len + beacon->assocresp_ies_len +
if (!new_beacon)
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -1182,13 +1182,17 @@ ieee80211_vif_get_shift(struct ieee80211
+@@ -1186,13 +1186,17 @@ ieee80211_vif_get_shift(struct ieee80211
}
static inline int
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -5205,13 +5205,20 @@ ieee80211_beacon_get_finish(struct ieee8
+@@ -5213,13 +5213,20 @@ ieee80211_beacon_get_finish(struct ieee8
}
static void
for (i = 0; i < beacon->mbssid_ies->cnt; i++)
skb_put_data(skb, beacon->mbssid_ies->elem[i].data,
beacon->mbssid_ies->elem[i].len);
-@@ -5224,7 +5231,8 @@ ieee80211_beacon_get_ap(struct ieee80211
+@@ -5232,7 +5239,8 @@ ieee80211_beacon_get_ap(struct ieee80211
struct ieee80211_mutable_offsets *offs,
bool is_template,
struct beacon_data *beacon,
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
-@@ -5243,7 +5251,9 @@ ieee80211_beacon_get_ap(struct ieee80211
+@@ -5251,7 +5259,9 @@ ieee80211_beacon_get_ap(struct ieee80211
/* headroom, head length,
* tail length, maximum TIM length and multiple BSSID length
*/
skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
beacon->tail_len + 256 +
local->hw.extra_beacon_tailroom + mbssid_len);
-@@ -5261,7 +5271,7 @@ ieee80211_beacon_get_ap(struct ieee80211
+@@ -5269,7 +5279,7 @@ ieee80211_beacon_get_ap(struct ieee80211
offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
if (mbssid_len) {
offs->mbssid_off = skb->len - mbssid_len;
}
-@@ -5280,12 +5290,51 @@ ieee80211_beacon_get_ap(struct ieee80211
+@@ -5288,12 +5298,51 @@ ieee80211_beacon_get_ap(struct ieee80211
return skb;
}
{
struct ieee80211_local *local = hw_to_local(hw);
struct beacon_data *beacon = NULL;
-@@ -5314,8 +5363,29 @@ __ieee80211_beacon_get(struct ieee80211_
+@@ -5322,8 +5371,29 @@ __ieee80211_beacon_get(struct ieee80211_
if (!beacon)
goto out;
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_hdr *hdr;
-@@ -5403,10 +5473,50 @@ ieee80211_beacon_get_template(struct iee
+@@ -5411,10 +5481,50 @@ ieee80211_beacon_get_template(struct iee
struct ieee80211_mutable_offsets *offs,
unsigned int link_id)
{
struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u16 *tim_offset, u16 *tim_length,
-@@ -5414,7 +5524,9 @@ struct sk_buff *ieee80211_beacon_get_tim
+@@ -5422,7 +5532,9 @@ struct sk_buff *ieee80211_beacon_get_tim
{
struct ieee80211_mutable_offsets offs = {};
struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false,
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Tue, 11 Jul 2023 13:30:12 +0200
+Subject: [PATCH] wifi: cfg80211: fix receving mesh packets without RFC1042
+ header
+
+Fix ethernet header length field after stripping the mesh header
+
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/CT5GNZSK28AI.2K6M69OXM9RW5@syracuse/
+Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces")
+Reported-by: Nicolas Escande <nico.escande@gmail.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -580,6 +580,8 @@ int ieee80211_strip_8023_mesh_hdr(struct
+ hdrlen += ETH_ALEN + 2;
+ else if (!pskb_may_pull(skb, hdrlen))
+ return -EINVAL;
++ else
++ payload.eth.h_proto = htons(skb->len - hdrlen);
+
+ mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN;
+ switch (payload.flags & MESH_FLAGS_AE) {
{
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
-@@ -477,6 +477,8 @@ void cfg80211_set_dfs_state(struct wiphy
+@@ -491,6 +491,8 @@ void cfg80211_set_dfs_state(struct wiphy
enum nl80211_dfs_state dfs_state);
void cfg80211_dfs_channels_update_work(struct work_struct *work);
cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
-@@ -891,6 +891,8 @@ void cfg80211_dfs_channels_update_work(s
+@@ -904,6 +904,8 @@ void cfg80211_dfs_channels_update_work(s
if (c->dfs_state == NL80211_DFS_UNAVAILABLE) {
time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS;
radar_event = NL80211_RADAR_NOP_FINISHED;
} else {
if (regulatory_pre_cac_allowed(wiphy) ||
cfg80211_any_wiphy_oper_chan(wiphy, c))
-@@ -898,11 +900,10 @@ void cfg80211_dfs_channels_update_work(s
+@@ -911,11 +913,10 @@ void cfg80211_dfs_channels_update_work(s
time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -6005,7 +6005,7 @@ done:
+@@ -6010,7 +6010,7 @@ done:
brcmf_dbg(CONN, "Report roaming result\n");
if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft) {
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -7720,6 +7720,8 @@ void cfg80211_roamed(struct net_device *
+@@ -7836,6 +7836,8 @@ void cfg80211_roamed(struct net_device *
*
* @dev: network device
* @bssid: the BSSID of the AP
* @gfp: allocation flags
*
* This function should be called by a driver that supports 4 way handshake
-@@ -7730,7 +7732,7 @@ void cfg80211_roamed(struct net_device *
+@@ -7846,7 +7848,7 @@ void cfg80211_roamed(struct net_device *
* indicate the 802.11 association.
*/
void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
-@@ -271,6 +271,8 @@ struct cfg80211_event {
+@@ -277,6 +277,8 @@ struct cfg80211_event {
} ij;
struct {
u8 bssid[ETH_ALEN];
} pa;
};
};
-@@ -409,7 +411,8 @@ int cfg80211_disconnect(struct cfg80211_
+@@ -421,7 +423,8 @@ int cfg80211_disconnect(struct cfg80211_
bool wextev);
void __cfg80211_roamed(struct wireless_dev *wdev,
struct cfg80211_roam_info *info);
void cfg80211_autodisconnect_wk(struct work_struct *work);
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
-@@ -17936,7 +17936,8 @@ void nl80211_send_roamed(struct cfg80211
+@@ -17993,7 +17993,8 @@ void nl80211_send_roamed(struct cfg80211
}
void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
{
struct sk_buff *msg;
void *hdr;
-@@ -17956,6 +17957,11 @@ void nl80211_send_port_authorized(struct
+@@ -18013,6 +18014,11 @@ void nl80211_send_port_authorized(struct
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
goto nla_put_failure;
* Use the wdev event list so that if there are pending
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
-@@ -1057,7 +1057,9 @@ void cfg80211_process_wdev_events(struct
+@@ -1059,7 +1059,9 @@ void cfg80211_process_wdev_events(struct
__cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev);
break;
case EVENT_PORT_AUTHORIZED:
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -1468,6 +1468,7 @@ enum mac80211_rx_encoding {
+@@ -1477,6 +1477,7 @@ enum mac80211_rx_encoding {
RX_ENC_HT,
RX_ENC_VHT,
RX_ENC_HE,
};
/**
-@@ -1501,7 +1502,7 @@ enum mac80211_rx_encoding {
+@@ -1510,7 +1511,7 @@ enum mac80211_rx_encoding {
* @antenna: antenna used
* @rate_idx: index of data rate into band's supported rates or MCS index if
* HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
* @flag: %RX_FLAG_\*
* @encoding: &enum mac80211_rx_encoding
* @bw: &enum rate_info_bw
-@@ -1509,6 +1510,8 @@ enum mac80211_rx_encoding {
+@@ -1518,6 +1519,8 @@ enum mac80211_rx_encoding {
* @he_ru: HE RU, from &enum nl80211_he_ru_alloc
* @he_gi: HE GI, from &enum nl80211_he_gi
* @he_dcm: HE DCM value
* @rx_flags: internal RX flags for mac80211
* @ampdu_reference: A-MPDU reference number, must be a different value for
* each A-MPDU but the same for each subframe within one A-MPDU
-@@ -1530,8 +1533,18 @@ struct ieee80211_rx_status {
+@@ -1539,8 +1542,18 @@ struct ieee80211_rx_status {
u32 flag;
u16 freq: 13, freq_offset: 1;
u8 enc_flags;
u8 rx_flags;
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -5328,6 +5328,15 @@ void ieee80211_rx_list(struct ieee80211_
+@@ -5358,6 +5358,15 @@ void ieee80211_rx_list(struct ieee80211_
status->rate_idx, status->nss))
goto drop;
break;
*/
#include <linux/module.h>
-@@ -2385,6 +2385,13 @@ static void sta_stats_decode_rate(struct
+@@ -2389,6 +2389,13 @@ static void sta_stats_decode_rate(struct
rinfo->he_ru_alloc = STA_STATS_GET(HE_RU, rate);
rinfo->he_dcm = STA_STATS_GET(HE_DCM, rate);
break;
return STA_STATS_RATE_INVALID;
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
-@@ -3900,6 +3900,19 @@ u64 ieee80211_calculate_rx_timestamp(str
+@@ -3898,6 +3898,19 @@ u64 ieee80211_calculate_rx_timestamp(str
/* Fill cfg80211 rate info */
switch (status->encoding) {
bool mu_mimo_owner;
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -4184,7 +4184,7 @@ static int ieee80211_set_ap_chanwidth(st
+@@ -4195,7 +4195,7 @@ static int ieee80211_set_ap_chanwidth(st
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_link_data *link;
int ret;
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
-@@ -1916,7 +1916,7 @@ int ieee80211_link_use_reserved_context(
+@@ -1935,7 +1935,7 @@ int ieee80211_link_use_reserved_context(
int ieee80211_link_change_bandwidth(struct ieee80211_link_data *link,
const struct cfg80211_chan_def *chandef,
struct ieee80211_bss_conf *link_conf = link->conf;
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -2491,7 +2491,7 @@ int ieee80211_link_unreserve_chanctx(str
+@@ -2497,7 +2497,7 @@ int ieee80211_link_unreserve_chanctx(str
int __must_check
ieee80211_link_change_bandwidth(struct ieee80211_link_data *link,
const struct cfg80211_chan_def *chandef,
{
struct ieee80211_sub_if_data *sdata = link->sdata;
struct ieee80211_local *local = sdata->local;
-@@ -4111,6 +4246,7 @@ static bool ieee80211_assoc_config_link(
+@@ -4140,6 +4275,7 @@ static bool ieee80211_assoc_config_link(
link_sta);
bss_conf->eht_support = link_sta->pub->eht_cap.has_eht;
} else {
bss_conf->eht_support = false;
}
-@@ -5423,6 +5559,45 @@ static bool ieee80211_rx_our_beacon(cons
+@@ -5452,6 +5588,45 @@ static bool ieee80211_rx_our_beacon(cons
return ether_addr_equal(tx_bssid, bss->transmitted_bss->bssid);
}
static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
struct ieee80211_hdr *hdr, size_t len,
struct ieee80211_rx_status *rx_status)
-@@ -5439,7 +5614,7 @@ static void ieee80211_rx_mgmt_beacon(str
+@@ -5468,7 +5643,7 @@ static void ieee80211_rx_mgmt_beacon(str
struct ieee80211_channel *chan;
struct link_sta_info *link_sta;
struct sta_info *sta;
bool erp_valid;
u8 erp_value = 0;
u32 ncrc = 0;
-@@ -5731,6 +5906,21 @@ static void ieee80211_rx_mgmt_beacon(str
+@@ -5761,6 +5936,21 @@ static void ieee80211_rx_mgmt_beacon(str
elems->pwr_constr_elem,
elems->cisco_dtpc_elem);
ieee80211_link_info_change_notify(sdata, link, changed);
free:
kfree(elems);
-@@ -6832,9 +7022,12 @@ ieee80211_setup_assoc_link(struct ieee80
+@@ -6862,9 +7052,12 @@ ieee80211_setup_assoc_link(struct ieee80
ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
}
const struct element *elem;
u8 dtim_count = 0;
-@@ -6863,6 +7056,31 @@ ieee80211_setup_assoc_link(struct ieee80
+@@ -6893,6 +7086,31 @@ ieee80211_setup_assoc_link(struct ieee80
link->conf->ema_ap = true;
else
link->conf->ema_ap = false;
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -8951,4 +8951,16 @@ static inline int cfg80211_color_change_
+@@ -9067,4 +9067,16 @@ static inline int cfg80211_color_change_
0, 0);
}
break;
link->u.mgd.conn_flags |=
ieee80211_chandef_downgrade(chandef);
-@@ -5584,8 +5523,8 @@ static bool ieee80211_config_puncturing(
+@@ -5613,8 +5552,8 @@ static bool ieee80211_config_puncturing(
extracted == link->conf->eht_puncturing)
return true;
link_info(link,
"Got an invalid disable subchannel bitmap from AP %pM: bitmap = 0x%x, bw = 0x%x. disconnect\n",
link->u.mgd.bssid,
-@@ -7072,8 +7011,8 @@ ieee80211_setup_assoc_link(struct ieee80
+@@ -7102,8 +7041,8 @@ ieee80211_setup_assoc_link(struct ieee80
u16 bitmap;
bitmap = get_unaligned_le16(disable_subchannel_bitmap);
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -1330,6 +1330,9 @@ struct cfg80211_unsol_bcast_probe_resp {
+@@ -1333,6 +1333,9 @@ struct cfg80211_unsol_bcast_probe_resp {
* @fils_discovery: FILS discovery transmission parameters
* @unsol_bcast_probe_resp: Unsolicited broadcast probe response parameters
* @mbssid_config: AP settings for multiple bssid
*/
struct cfg80211_ap_settings {
struct cfg80211_chan_def chandef;
-@@ -1364,6 +1367,7 @@ struct cfg80211_ap_settings {
+@@ -1367,6 +1370,7 @@ struct cfg80211_ap_settings {
struct cfg80211_fils_discovery fils_discovery;
struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp;
struct cfg80211_mbssid_config mbssid_config;
};
/**
-@@ -1381,6 +1385,9 @@ struct cfg80211_ap_settings {
+@@ -1384,6 +1388,9 @@ struct cfg80211_ap_settings {
* @radar_required: whether radar detection is required on the new channel
* @block_tx: whether transmissions should be blocked while changing
* @count: number of beacons until switch
*/
struct cfg80211_csa_settings {
struct cfg80211_chan_def chandef;
-@@ -1393,6 +1400,7 @@ struct cfg80211_csa_settings {
+@@ -1396,6 +1403,7 @@ struct cfg80211_csa_settings {
bool radar_required;
bool block_tx;
u8 count;
NUM_NL80211_EXT_FEATURES,
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
-@@ -799,6 +799,7 @@ static const struct nla_policy nl80211_p
+@@ -819,6 +819,7 @@ static const struct nla_policy nl80211_p
[NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
};
/* policy for the key attributes */
-@@ -3167,6 +3168,21 @@ static bool nl80211_can_set_dev_channel(
+@@ -3187,6 +3188,21 @@ static bool nl80211_can_set_dev_channel(
wdev->iftype == NL80211_IFTYPE_P2P_GO;
}
int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
struct genl_info *info,
struct cfg80211_chan_def *chandef)
-@@ -5912,6 +5928,14 @@ static int nl80211_start_ap(struct sk_bu
+@@ -5938,6 +5954,14 @@ static int nl80211_start_ap(struct sk_bu
goto out;
}
if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, ¶ms->chandef,
wdev->iftype)) {
err = -EINVAL;
-@@ -10050,6 +10074,14 @@ skip_beacons:
+@@ -10076,6 +10100,14 @@ skip_beacons:
if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
params.block_tx = true;
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -8325,13 +8325,14 @@ bool cfg80211_reg_can_beacon_relax(struc
+@@ -8441,13 +8441,14 @@ bool cfg80211_reg_can_beacon_relax(struc
* @dev: the device which switched channels
* @chandef: the new channel definition
* @link_id: the link ID for MLO, must be 0 for non-MLO
/*
* cfg80211_ch_switch_started_notify - notify channel switch start
-@@ -8340,6 +8341,7 @@ void cfg80211_ch_switch_notify(struct ne
+@@ -8456,6 +8457,7 @@ void cfg80211_ch_switch_notify(struct ne
* @link_id: the link ID for MLO, must be 0 for non-MLO
* @count: the number of TBTTs until the channel switch happens
* @quiet: whether or not immediate quiet was requested by the AP
*
* Inform the userspace about the channel switch that has just
* started, so that it can take appropriate actions (eg. starting
-@@ -8348,7 +8350,7 @@ void cfg80211_ch_switch_notify(struct ne
+@@ -8464,7 +8466,7 @@ void cfg80211_ch_switch_notify(struct ne
void cfg80211_ch_switch_started_notify(struct net_device *dev,
struct cfg80211_chan_def *chandef,
unsigned int link_id, u8 count,
* ieee80211_operating_class_to_band - convert operating class to band
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -3600,7 +3600,8 @@ static int __ieee80211_csa_finalize(stru
+@@ -3610,7 +3610,8 @@ static int __ieee80211_csa_finalize(stru
if (err)
return err;
return 0;
}
-@@ -3872,7 +3873,7 @@ __ieee80211_channel_switch(struct wiphy
+@@ -3882,7 +3883,7 @@ __ieee80211_channel_switch(struct wiphy
cfg80211_ch_switch_started_notify(sdata->dev,
&sdata->deflink.csa_chandef, 0,
ieee80211_link_info_change_notify(sdata, &sdata->deflink,
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
-@@ -1778,7 +1778,7 @@ static void ieee80211_chswitch_post_beac
+@@ -1784,7 +1784,7 @@ static void ieee80211_chswitch_post_beac
return;
}
}
void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
-@@ -1988,7 +1988,7 @@ ieee80211_sta_process_chanswitch(struct
+@@ -1994,7 +1994,7 @@ ieee80211_sta_process_chanswitch(struct
mutex_unlock(&local->mtx);
cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef, 0,
/* use driver's channel switch callback */
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
-@@ -18973,7 +18973,7 @@ static void nl80211_ch_switch_notify(str
+@@ -19054,7 +19054,7 @@ static void nl80211_ch_switch_notify(str
struct cfg80211_chan_def *chandef,
gfp_t gfp,
enum nl80211_commands notif,
{
struct wireless_dev *wdev = netdev->ieee80211_ptr;
struct sk_buff *msg;
-@@ -19007,6 +19007,9 @@ static void nl80211_ch_switch_notify(str
+@@ -19088,6 +19088,9 @@ static void nl80211_ch_switch_notify(str
goto nla_put_failure;
}
genlmsg_end(msg, hdr);
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
-@@ -19019,7 +19022,7 @@ static void nl80211_ch_switch_notify(str
+@@ -19100,7 +19103,7 @@ static void nl80211_ch_switch_notify(str
void cfg80211_ch_switch_notify(struct net_device *dev,
struct cfg80211_chan_def *chandef,
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
-@@ -19028,7 +19031,7 @@ void cfg80211_ch_switch_notify(struct ne
+@@ -19109,7 +19112,7 @@ void cfg80211_ch_switch_notify(struct ne
ASSERT_WDEV_LOCK(wdev);
WARN_INVALID_LINK_ID(wdev, link_id);
switch (wdev->iftype) {
case NL80211_IFTYPE_STATION:
-@@ -19056,14 +19059,15 @@ void cfg80211_ch_switch_notify(struct ne
+@@ -19137,14 +19140,15 @@ void cfg80211_ch_switch_notify(struct ne
cfg80211_sched_dfs_chan_update(rdev);
nl80211_ch_switch_notify(rdev, dev, link_id, chandef, GFP_KERNEL,
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
-@@ -19072,11 +19076,13 @@ void cfg80211_ch_switch_started_notify(s
+@@ -19153,11 +19157,13 @@ void cfg80211_ch_switch_started_notify(s
ASSERT_WDEV_LOCK(wdev);
WARN_INVALID_LINK_ID(wdev, link_id);
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1220,7 +1220,7 @@ static int ieee80211_start_ap(struct wip
+@@ -1223,7 +1223,7 @@ static int ieee80211_start_ap(struct wip
struct ieee80211_local *local = sdata->local;
struct beacon_data *old;
struct ieee80211_sub_if_data *vlan;
BSS_CHANGED_BEACON_ENABLED |
BSS_CHANGED_BEACON |
BSS_CHANGED_P2P_PS |
-@@ -1307,6 +1307,11 @@ static int ieee80211_start_ap(struct wip
+@@ -1310,6 +1310,11 @@ static int ieee80211_start_ap(struct wip
IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO;
}
if (sdata->vif.type == NL80211_IFTYPE_AP &&
params->mbssid_config.tx_wdev) {
err = ieee80211_set_ap_mbssid_options(sdata,
-@@ -3559,6 +3564,12 @@ static int __ieee80211_csa_finalize(stru
+@@ -3569,6 +3574,12 @@ static int __ieee80211_csa_finalize(stru
lockdep_assert_held(&local->mtx);
lockdep_assert_held(&local->chanctx_mtx);
/*
* using reservation isn't immediate as it may be deferred until later
* with multi-vif. once reservation is complete it will re-schedule the
-@@ -3601,7 +3612,7 @@ static int __ieee80211_csa_finalize(stru
+@@ -3611,7 +3622,7 @@ static int __ieee80211_csa_finalize(stru
return err;
cfg80211_ch_switch_notify(sdata->dev, &sdata->deflink.csa_chandef, 0,
return 0;
}
-@@ -3863,9 +3874,13 @@ __ieee80211_channel_switch(struct wiphy
+@@ -3873,9 +3884,13 @@ __ieee80211_channel_switch(struct wiphy
goto out;
}
if (sdata->deflink.csa_block_tx)
ieee80211_stop_vif_queues(local, sdata,
-@@ -3873,7 +3888,8 @@ __ieee80211_channel_switch(struct wiphy
+@@ -3883,7 +3898,8 @@ __ieee80211_channel_switch(struct wiphy
cfg80211_ch_switch_started_notify(sdata->dev,
&sdata->deflink.csa_chandef, 0,
/**
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1310,6 +1310,22 @@ static int ieee80211_start_ap(struct wip
+@@ -1313,6 +1313,22 @@ static int ieee80211_start_ap(struct wip
if (params->eht_cap) {
link_conf->eht_puncturing = params->punct_bitmap;
changed |= BSS_CHANGED_EHT_PUNCTURING;
--- /dev/null
+From a1e91ef92392e5da15a1a16f8545ede2c02f7049 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Wed, 1 Mar 2023 12:09:24 +0200
+Subject: [PATCH] wifi: mac80211: warn only once on AP probe
+
+We should perhaps support this API for MLO, but it's not
+clear that it makes sense, in any case then we'd have to
+update it to probe the correct BSS.
+
+For now, if it happens, warn only once so that we don't
+get flooded with messages if the driver misbehaves and
+calls this.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230301115906.1c8499b6fbe6.I1a76a2be3b42ff93904870ac069f0319507adc23@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+ net/mac80211/mlme.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -3239,7 +3239,7 @@ static void ieee80211_mgd_probe_ap(struc
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ bool already = false;
+
+- if (WARN_ON(sdata->vif.valid_links))
++ if (WARN_ON_ONCE(sdata->vif.valid_links))
+ return;
+
+ if (!ieee80211_sdata_running(sdata))
--- /dev/null
+From acb8bca343f8d5b8697d027771abf8a371580d53 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 4 May 2023 16:45:05 +0300
+Subject: [PATCH] wifi: mac80211: HW restart for MLO
+
+Implement proper reconfiguration for interfaces that are
+doing MLO, in order to be able to recover from HW restart
+correctly.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230504134511.828474-6-gregory.greenman@intel.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+ net/mac80211/util.c | 107 ++++++++++++++++++++++++++++++--------------
+ 1 file changed, 73 insertions(+), 34 deletions(-)
+
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -2493,21 +2493,55 @@ int ieee80211_reconfig(struct ieee80211_
+
+ /* Finally also reconfigure all the BSS information */
+ list_for_each_entry(sdata, &local->interfaces, list) {
++ /* common change flags for all interface types - link only */
++ u32 changed = BSS_CHANGED_ERP_CTS_PROT |
++ BSS_CHANGED_ERP_PREAMBLE |
++ BSS_CHANGED_ERP_SLOT |
++ BSS_CHANGED_HT |
++ BSS_CHANGED_BASIC_RATES |
++ BSS_CHANGED_BEACON_INT |
++ BSS_CHANGED_BSSID |
++ BSS_CHANGED_CQM |
++ BSS_CHANGED_QOS |
++ BSS_CHANGED_TXPOWER |
++ BSS_CHANGED_MCAST_RATE;
++ struct ieee80211_link_data *link = NULL;
+ unsigned int link_id;
+- u32 changed;
++ u32 active_links = 0;
+
+ if (!ieee80211_sdata_running(sdata))
+ continue;
+
+ sdata_lock(sdata);
++ if (sdata->vif.valid_links) {
++ struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS] = {
++ [0] = &sdata->vif.bss_conf,
++ };
++
++ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
++ /* start with a single active link */
++ active_links = sdata->vif.active_links;
++ link_id = ffs(active_links) - 1;
++ sdata->vif.active_links = BIT(link_id);
++ }
++
++ drv_change_vif_links(local, sdata, 0,
++ sdata->vif.active_links,
++ old);
++ }
++
+ for (link_id = 0;
+ link_id < ARRAY_SIZE(sdata->vif.link_conf);
+ link_id++) {
+- struct ieee80211_link_data *link;
++ if (sdata->vif.valid_links &&
++ !(sdata->vif.active_links & BIT(link_id)))
++ continue;
+
+ link = sdata_dereference(sdata->link[link_id], sdata);
+- if (link)
+- ieee80211_assign_chanctx(local, sdata, link);
++ if (!link)
++ continue;
++
++ ieee80211_assign_chanctx(local, sdata, link);
+ }
+
+ switch (sdata->vif.type) {
+@@ -2527,42 +2561,42 @@ int ieee80211_reconfig(struct ieee80211_
+ &sdata->deflink.tx_conf[i]);
+ break;
+ }
+- sdata_unlock(sdata);
+-
+- /* common change flags for all interface types */
+- changed = BSS_CHANGED_ERP_CTS_PROT |
+- BSS_CHANGED_ERP_PREAMBLE |
+- BSS_CHANGED_ERP_SLOT |
+- BSS_CHANGED_HT |
+- BSS_CHANGED_BASIC_RATES |
+- BSS_CHANGED_BEACON_INT |
+- BSS_CHANGED_BSSID |
+- BSS_CHANGED_CQM |
+- BSS_CHANGED_QOS |
+- BSS_CHANGED_IDLE |
+- BSS_CHANGED_TXPOWER |
+- BSS_CHANGED_MCAST_RATE;
+
+ if (sdata->vif.bss_conf.mu_mimo_owner)
+ changed |= BSS_CHANGED_MU_GROUPS;
+
++ if (!sdata->vif.valid_links)
++ changed |= BSS_CHANGED_IDLE;
++
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_STATION:
+- changed |= BSS_CHANGED_ASSOC |
+- BSS_CHANGED_ARP_FILTER |
+- BSS_CHANGED_PS;
+-
+- /* Re-send beacon info report to the driver */
+- if (sdata->deflink.u.mgd.have_beacon)
+- changed |= BSS_CHANGED_BEACON_INFO;
+-
+- if (sdata->vif.bss_conf.max_idle_period ||
+- sdata->vif.bss_conf.protected_keep_alive)
+- changed |= BSS_CHANGED_KEEP_ALIVE;
+-
+- sdata_lock(sdata);
+- ieee80211_bss_info_change_notify(sdata, changed);
+- sdata_unlock(sdata);
++ if (!sdata->vif.valid_links) {
++ changed |= BSS_CHANGED_ASSOC |
++ BSS_CHANGED_ARP_FILTER |
++ BSS_CHANGED_PS;
++
++ /* Re-send beacon info report to the driver */
++ if (sdata->deflink.u.mgd.have_beacon)
++ changed |= BSS_CHANGED_BEACON_INFO;
++
++ if (sdata->vif.bss_conf.max_idle_period ||
++ sdata->vif.bss_conf.protected_keep_alive)
++ changed |= BSS_CHANGED_KEEP_ALIVE;
++
++ if (sdata->vif.bss_conf.eht_puncturing)
++ changed |= BSS_CHANGED_EHT_PUNCTURING;
++
++ ieee80211_bss_info_change_notify(sdata,
++ changed);
++ } else if (!WARN_ON(!link)) {
++ ieee80211_link_info_change_notify(sdata, link,
++ changed);
++ changed = BSS_CHANGED_ASSOC |
++ BSS_CHANGED_IDLE |
++ BSS_CHANGED_PS |
++ BSS_CHANGED_ARP_FILTER;
++ ieee80211_vif_cfg_change_notify(sdata, changed);
++ }
+ break;
+ case NL80211_IFTYPE_OCB:
+ changed |= BSS_CHANGED_OCB;
+@@ -2597,6 +2631,7 @@ int ieee80211_reconfig(struct ieee80211_
+ case NL80211_IFTYPE_NAN:
+ res = ieee80211_reconfig_nan(sdata);
+ if (res < 0) {
++ sdata_unlock(sdata);
+ ieee80211_handle_reconfig_failure(local);
+ return res;
+ }
+@@ -2614,6 +2649,10 @@ int ieee80211_reconfig(struct ieee80211_
+ WARN_ON(1);
+ break;
+ }
++ sdata_unlock(sdata);
++
++ if (active_links)
++ ieee80211_set_active_links(&sdata->vif, active_links);
+ }
+
+ ieee80211_recalc_ps(local);
--- /dev/null
+From 61403414e1719f929386dda8fb954bb302628ef3 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 4 May 2023 16:45:11 +0300
+Subject: [PATCH] wifi: mac80211: implement proper AP MLD HW restart
+
+Previously, I didn't implement restarting here at all if the
+interface is an MLD, so it only worked for non-MLO. Add the
+needed code to restart an AP MLD correctly.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230504134511.828474-12-gregory.greenman@intel.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+ net/mac80211/util.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 43 insertions(+), 1 deletion(-)
+
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -2344,6 +2344,35 @@ static int ieee80211_reconfig_nan(struct
+ return 0;
+ }
+
++static void ieee80211_reconfig_ap_links(struct ieee80211_local *local,
++ struct ieee80211_sub_if_data *sdata,
++ u32 changed)
++{
++ int link_id;
++
++ for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) {
++ struct ieee80211_link_data *link;
++
++ if (!(sdata->vif.active_links & BIT(link_id)))
++ continue;
++
++ link = sdata_dereference(sdata->link[link_id], sdata);
++ if (!link)
++ continue;
++
++ if (rcu_access_pointer(link->u.ap.beacon))
++ drv_start_ap(local, sdata, link->conf);
++
++ if (!link->conf->enable_beacon)
++ continue;
++
++ changed |= BSS_CHANGED_BEACON |
++ BSS_CHANGED_BEACON_ENABLED;
++
++ ieee80211_link_info_change_notify(sdata, link, changed);
++ }
++}
++
+ int ieee80211_reconfig(struct ieee80211_local *local)
+ {
+ struct ieee80211_hw *hw = &local->hw;
+@@ -2606,7 +2635,13 @@ int ieee80211_reconfig(struct ieee80211_
+ changed |= BSS_CHANGED_IBSS;
+ fallthrough;
+ case NL80211_IFTYPE_AP:
+- changed |= BSS_CHANGED_SSID | BSS_CHANGED_P2P_PS;
++ changed |= BSS_CHANGED_P2P_PS;
++
++ if (sdata->vif.valid_links)
++ ieee80211_vif_cfg_change_notify(sdata,
++ BSS_CHANGED_SSID);
++ else
++ changed |= BSS_CHANGED_SSID;
+
+ if (sdata->vif.bss_conf.ftm_responder == 1 &&
+ wiphy_ext_feature_isset(sdata->local->hw.wiphy,
+@@ -2616,6 +2651,13 @@ int ieee80211_reconfig(struct ieee80211_
+ if (sdata->vif.type == NL80211_IFTYPE_AP) {
+ changed |= BSS_CHANGED_AP_PROBE_RESP;
+
++ if (sdata->vif.valid_links) {
++ ieee80211_reconfig_ap_links(local,
++ sdata,
++ changed);
++ break;
++ }
++
+ if (rcu_access_pointer(sdata->deflink.u.ap.beacon))
+ drv_start_ap(local, sdata,
+ sdata->deflink.conf);
--- /dev/null
+From f1871abd27641c020298b5c7654e1d8341f22e5f Mon Sep 17 00:00:00 2001
+From: Ilan Peer <ilan.peer@intel.com>
+Date: Thu, 8 Jun 2023 16:36:08 +0300
+Subject: [PATCH] wifi: mac80211: Add getter functions for vif MLD state
+
+As a preparation to support disabled/dormant links, add the
+following function:
+
+- ieee80211_vif_usable_links(): returns the bitmap of the links
+ that can be activated. Use this function in all the places that
+ the bitmap of the usable links is needed.
+
+- ieee80211_vif_is_mld(): returns true iff the vif is an MLD.
+ Use this function in all the places where an indication that the
+ connection is a MLD is needed.
+
+Signed-off-by: Ilan Peer <ilan.peer@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230608163202.86e3351da1fc.If6fe3a339fda2019f13f57ff768ecffb711b710a@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+ include/net/mac80211.h | 21 +++++++++++++++++++
+ net/mac80211/cfg.c | 4 ++--
+ net/mac80211/debug.h | 8 +++----
+ net/mac80211/ieee80211_i.h | 2 +-
+ net/mac80211/iface.c | 4 ++--
+ net/mac80211/link.c | 4 ++--
+ net/mac80211/mlme.c | 43 +++++++++++++++++++-------------------
+ net/mac80211/rx.c | 2 +-
+ net/mac80211/tx.c | 22 +++++++++----------
+ net/mac80211/util.c | 14 ++++++-------
+ 10 files changed, 73 insertions(+), 51 deletions(-)
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1936,6 +1936,27 @@ struct ieee80211_vif {
+ u8 drv_priv[] __aligned(sizeof(void *));
+ };
+
++/**
++ * ieee80211_vif_usable_links - Return the usable links for the vif
++ * @vif: the vif for which the usable links are requested
++ * Return: the usable link bitmap
++ */
++static inline u16 ieee80211_vif_usable_links(const struct ieee80211_vif *vif)
++{
++ return vif->valid_links;
++}
++
++/**
++ * ieee80211_vif_is_mld - Returns true iff the vif is an MLD one
++ * @vif: the vif
++ * Return: %true if the vif is an MLD, %false otherwise.
++ */
++static inline bool ieee80211_vif_is_mld(const struct ieee80211_vif *vif)
++{
++ /* valid_links != 0 indicates this vif is an MLD */
++ return vif->valid_links != 0;
++}
++
+ #define for_each_vif_active_link(vif, link, link_id) \
+ for (link_id = 0; link_id < ARRAY_SIZE((vif)->link_conf); link_id++) \
+ if ((!(vif)->active_links || \
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -35,7 +35,7 @@ ieee80211_link_or_deflink(struct ieee802
+ * the return value at all (if it's not a pairwise key),
+ * so in that case (require_valid==false) don't error.
+ */
+- if (require_valid && sdata->vif.valid_links)
++ if (require_valid && ieee80211_vif_is_mld(&sdata->vif))
+ return ERR_PTR(-EINVAL);
+
+ return &sdata->deflink;
+@@ -228,7 +228,7 @@ static int ieee80211_change_iface(struct
+ return 0;
+
+ /* FIXME: no support for 4-addr MLO yet */
+- if (sdata->vif.valid_links)
++ if (ieee80211_vif_is_mld(&sdata->vif))
+ return -EOPNOTSUPP;
+
+ sdata->u.mgd.use_4addr = params->use_4addr;
+--- a/net/mac80211/debug.h
++++ b/net/mac80211/debug.h
+@@ -1,7 +1,7 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+ /*
+ * Portions
+- * Copyright (C) 2022 Intel Corporation
++ * Copyright (C) 2022 - 2023 Intel Corporation
+ */
+ #ifndef __MAC80211_DEBUG_H
+ #define __MAC80211_DEBUG_H
+@@ -136,7 +136,7 @@ do { \
+
+ #define link_info(link, fmt, ...) \
+ do { \
+- if ((link)->sdata->vif.valid_links) \
++ if (ieee80211_vif_is_mld(&(link)->sdata->vif)) \
+ _sdata_info((link)->sdata, "[link %d] " fmt, \
+ (link)->link_id, \
+ ##__VA_ARGS__); \
+@@ -145,7 +145,7 @@ do { \
+ } while (0)
+ #define link_err(link, fmt, ...) \
+ do { \
+- if ((link)->sdata->vif.valid_links) \
++ if (ieee80211_vif_is_mld(&(link)->sdata->vif)) \
+ _sdata_err((link)->sdata, "[link %d] " fmt, \
+ (link)->link_id, \
+ ##__VA_ARGS__); \
+@@ -154,7 +154,7 @@ do { \
+ } while (0)
+ #define link_dbg(link, fmt, ...) \
+ do { \
+- if ((link)->sdata->vif.valid_links) \
++ if (ieee80211_vif_is_mld(&(link)->sdata->vif)) \
+ _sdata_dbg(1, (link)->sdata, "[link %d] " fmt, \
+ (link)->link_id, \
+ ##__VA_ARGS__); \
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1600,7 +1600,7 @@ ieee80211_get_sband(struct ieee80211_sub
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ enum nl80211_band band;
+
+- WARN_ON(sdata->vif.valid_links);
++ WARN_ON(ieee80211_vif_is_mld(&sdata->vif));
+
+ rcu_read_lock();
+ chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -521,7 +521,7 @@ static void ieee80211_do_stop(struct iee
+ cancel_work_sync(&sdata->recalc_smps);
+
+ sdata_lock(sdata);
+- WARN(sdata->vif.valid_links,
++ WARN(ieee80211_vif_is_mld(&sdata->vif),
+ "destroying interface with valid links 0x%04x\n",
+ sdata->vif.valid_links);
+
+@@ -1834,7 +1834,7 @@ static int ieee80211_runtime_change_ifty
+ return -EBUSY;
+
+ /* for now, don't support changing while links exist */
+- if (sdata->vif.valid_links)
++ if (ieee80211_vif_is_mld(&sdata->vif))
+ return -EBUSY;
+
+ switch (sdata->vif.type) {
+--- a/net/mac80211/link.c
++++ b/net/mac80211/link.c
+@@ -324,7 +324,7 @@ static int _ieee80211_set_active_links(s
+ return -EINVAL;
+
+ /* cannot activate links that don't exist */
+- if (active_links & ~sdata->vif.valid_links)
++ if (active_links & ~ieee80211_vif_usable_links(&sdata->vif))
+ return -EINVAL;
+
+ /* nothing to do */
+@@ -463,7 +463,7 @@ void ieee80211_set_active_links_async(st
+ return;
+
+ /* cannot activate links that don't exist */
+- if (active_links & ~sdata->vif.valid_links)
++ if (active_links & ~ieee80211_vif_usable_links(&sdata->vif))
+ return;
+
+ /* nothing to do */
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -1287,7 +1287,7 @@ static void ieee80211_assoc_add_ml_elem(
+ u8 *ml_elem_len;
+ void *capab_pos;
+
+- if (!sdata->vif.valid_links)
++ if (!ieee80211_vif_is_mld(&sdata->vif))
+ return;
+
+ ift_ext_capa = cfg80211_get_iftype_ext_capa(local->hw.wiphy,
+@@ -1461,7 +1461,7 @@ static int ieee80211_send_assoc(struct i
+ capab |= WLAN_CAPABILITY_PRIVACY;
+ }
+
+- if (sdata->vif.valid_links) {
++ if (ieee80211_vif_is_mld(&sdata->vif)) {
+ /* consider the multi-link element with STA profile */
+ size += sizeof(struct ieee80211_multi_link_elem);
+ /* max common info field in basic multi-link element */
+@@ -1792,7 +1792,7 @@ void ieee80211_chswitch_done(struct ieee
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+- if (WARN_ON(sdata->vif.valid_links))
++ if (WARN_ON(ieee80211_vif_is_mld(&sdata->vif)))
+ success = false;
+
+ trace_api_chswitch_done(sdata, success);
+@@ -2855,7 +2855,7 @@ static void ieee80211_set_associated(str
+ if (vif_cfg->arp_addr_cnt)
+ vif_changed |= BSS_CHANGED_ARP_FILTER;
+
+- if (sdata->vif.valid_links) {
++ if (ieee80211_vif_is_mld(&sdata->vif)) {
+ for (link_id = 0;
+ link_id < IEEE80211_MLD_MAX_NUM_LINKS;
+ link_id++) {
+@@ -2886,7 +2886,7 @@ static void ieee80211_set_associated(str
+ mutex_unlock(&local->iflist_mtx);
+
+ /* leave this here to not change ordering in non-MLO cases */
+- if (!sdata->vif.valid_links)
++ if (!ieee80211_vif_is_mld(&sdata->vif))
+ ieee80211_recalc_smps(sdata, &sdata->deflink);
+ ieee80211_recalc_ps_vif(sdata);
+
+@@ -2982,7 +2982,7 @@ static void ieee80211_set_disassoc(struc
+ sta_info_flush(sdata);
+
+ /* finally reset all BSS / config parameters */
+- if (!sdata->vif.valid_links)
++ if (!ieee80211_vif_is_mld(&sdata->vif))
+ changed |= ieee80211_reset_erp_info(sdata);
+
+ ieee80211_led_assoc(local, 0);
+@@ -3007,7 +3007,7 @@ static void ieee80211_set_disassoc(struc
+ sizeof(sdata->vif.bss_conf.mu_group.membership));
+ memset(sdata->vif.bss_conf.mu_group.position, 0,
+ sizeof(sdata->vif.bss_conf.mu_group.position));
+- if (!sdata->vif.valid_links)
++ if (!ieee80211_vif_is_mld(&sdata->vif))
+ changed |= BSS_CHANGED_MU_GROUPS;
+ sdata->vif.bss_conf.mu_mimo_owner = false;
+
+@@ -3021,7 +3021,7 @@ static void ieee80211_set_disassoc(struc
+ changed |= BSS_CHANGED_ARP_FILTER;
+
+ sdata->vif.bss_conf.qos = false;
+- if (!sdata->vif.valid_links) {
++ if (!ieee80211_vif_is_mld(&sdata->vif)) {
+ changed |= BSS_CHANGED_QOS;
+ /* The BSSID (not really interesting) and HT changed */
+ changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
+@@ -3191,7 +3191,7 @@ static void ieee80211_mgd_probe_ap_send(
+ u8 unicast_limit = max(1, max_probe_tries - 3);
+ struct sta_info *sta;
+
+- if (WARN_ON(sdata->vif.valid_links))
++ if (WARN_ON(ieee80211_vif_is_mld(&sdata->vif)))
+ return;
+
+ /*
+@@ -3239,7 +3239,7 @@ static void ieee80211_mgd_probe_ap(struc
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ bool already = false;
+
+- if (WARN_ON_ONCE(sdata->vif.valid_links))
++ if (WARN_ON_ONCE(ieee80211_vif_is_mld(&sdata->vif)))
+ return;
+
+ if (!ieee80211_sdata_running(sdata))
+@@ -3314,7 +3314,7 @@ struct sk_buff *ieee80211_ap_probereq_ge
+ int ssid_len;
+
+ if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
+- sdata->vif.valid_links))
++ ieee80211_vif_is_mld(&sdata->vif)))
+ return NULL;
+
+ sdata_assert_lock(sdata);
+@@ -3379,7 +3379,8 @@ static void __ieee80211_disconnect(struc
+ }
+
+ /* in MLO assume we have a link where we can TX the frame */
+- tx = sdata->vif.valid_links || !sdata->deflink.csa_block_tx;
++ tx = ieee80211_vif_is_mld(&sdata->vif) ||
++ !sdata->deflink.csa_block_tx;
+
+ if (!ifmgd->driver_disconnect) {
+ unsigned int link_id;
+@@ -3578,7 +3579,7 @@ static void ieee80211_destroy_assoc_data
+ for (i = 0; i < ARRAY_SIZE(data.bss); i++)
+ data.bss[i] = assoc_data->link[i].bss;
+
+- if (sdata->vif.valid_links)
++ if (ieee80211_vif_is_mld(&sdata->vif))
+ data.ap_mld_addr = assoc_data->ap_addr;
+
+ cfg80211_assoc_failure(sdata->dev, &data);
+@@ -4979,7 +4980,7 @@ static bool ieee80211_assoc_success(stru
+ if (WARN_ON(!sta))
+ goto out_err;
+
+- if (sdata->vif.valid_links) {
++ if (ieee80211_vif_is_mld(&sdata->vif)) {
+ u16 valid_links = 0;
+
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
+@@ -5008,7 +5009,7 @@ static bool ieee80211_assoc_success(stru
+ if (WARN_ON(!link))
+ goto out_err;
+
+- if (sdata->vif.valid_links)
++ if (ieee80211_vif_is_mld(&sdata->vif))
+ link_info(link,
+ "local address %pM, AP link address %pM\n",
+ link->conf->addr,
+@@ -5240,7 +5241,7 @@ static void ieee80211_rx_mgmt_assoc_resp
+ ifmgd->broken_ap = true;
+ }
+
+- if (sdata->vif.valid_links) {
++ if (ieee80211_vif_is_mld(&sdata->vif)) {
+ if (!elems->multi_link) {
+ sdata_info(sdata,
+ "MLO association with %pM but no multi-link element in response!\n",
+@@ -5304,7 +5305,7 @@ static void ieee80211_rx_mgmt_assoc_resp
+ resp.uapsd_queues |= ieee80211_ac_to_qos_mask[ac];
+ }
+
+- if (sdata->vif.valid_links) {
++ if (ieee80211_vif_is_mld(&sdata->vif)) {
+ ether_addr_copy(ap_mld_addr, sdata->vif.cfg.ap_addr);
+ resp.ap_mld_addr = ap_mld_addr;
+ }
+@@ -5629,7 +5630,7 @@ static void ieee80211_rx_mgmt_beacon(str
+ rcu_read_unlock();
+
+ if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon &&
+- !WARN_ON(sdata->vif.valid_links) &&
++ !WARN_ON(ieee80211_vif_is_mld(&sdata->vif)) &&
+ ieee80211_rx_our_beacon(bssid, ifmgd->assoc_data->link[0].bss)) {
+ parse_params.bss = ifmgd->assoc_data->link[0].bss;
+ elems = ieee802_11_parse_elems_full(&parse_params);
+@@ -6319,7 +6320,7 @@ static void ieee80211_sta_bcn_mon_timer(
+ struct ieee80211_sub_if_data *sdata =
+ from_timer(sdata, t, u.mgd.bcn_mon_timer);
+
+- if (WARN_ON(sdata->vif.valid_links))
++ if (WARN_ON(ieee80211_vif_is_mld(&sdata->vif)))
+ return;
+
+ if (sdata->vif.bss_conf.csa_active &&
+@@ -6343,7 +6344,7 @@ static void ieee80211_sta_conn_mon_timer
+ struct sta_info *sta;
+ unsigned long timeout;
+
+- if (WARN_ON(sdata->vif.valid_links))
++ if (WARN_ON(ieee80211_vif_is_mld(&sdata->vif)))
+ return;
+
+ if (sdata->vif.bss_conf.csa_active &&
+@@ -6898,7 +6899,7 @@ int ieee80211_mgd_auth(struct ieee80211_
+ return 0;
+
+ err_clear:
+- if (!sdata->vif.valid_links) {
++ if (!ieee80211_vif_is_mld(&sdata->vif)) {
+ eth_zero_addr(sdata->deflink.u.mgd.bssid);
+ ieee80211_link_info_change_notify(sdata, &sdata->deflink,
+ BSS_CHANGED_BSSID);
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2526,7 +2526,7 @@ bool ieee80211_is_our_addr(struct ieee80
+ if (ether_addr_equal(sdata->vif.addr, addr))
+ return true;
+
+- if (!sdata->vif.valid_links)
++ if (!ieee80211_vif_is_mld(&sdata->vif))
+ return false;
+
+ for (link_id = 0; link_id < ARRAY_SIZE(sdata->vif.link_conf); link_id++) {
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -866,7 +866,7 @@ ieee80211_tx_h_sequence(struct ieee80211
+
+ /* SNS11 from 802.11be 10.3.2.14 */
+ if (unlikely(is_multicast_ether_addr(hdr->addr1) &&
+- info->control.vif->valid_links &&
++ ieee80211_vif_is_mld(info->control.vif) &&
+ info->control.vif->type == NL80211_IFTYPE_AP)) {
+ if (info->control.flags & IEEE80211_TX_CTRL_MCAST_MLO_FIRST_TX)
+ tx->sdata->mld_mcast_seq += 0x10;
+@@ -2635,7 +2635,7 @@ static struct sk_buff *ieee80211_build_h
+ ethertype = (skb->data[12] << 8) | skb->data[13];
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
+
+- if (!sdata->vif.valid_links)
++ if (!ieee80211_vif_is_mld(&sdata->vif))
+ chanctx_conf =
+ rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+
+@@ -2652,7 +2652,7 @@ static struct sk_buff *ieee80211_build_h
+ authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
+ wme_sta = sta->sta.wme;
+ }
+- if (!sdata->vif.valid_links) {
++ if (!ieee80211_vif_is_mld(&sdata->vif)) {
+ struct ieee80211_sub_if_data *ap_sdata;
+
+ /* override chanctx_conf from AP (we don't have one) */
+@@ -2670,7 +2670,7 @@ static struct sk_buff *ieee80211_build_h
+ /* DA BSSID SA */
+ memcpy(hdr.addr1, skb->data, ETH_ALEN);
+
+- if (sdata->vif.valid_links && sta && !sta->sta.mlo) {
++ if (ieee80211_vif_is_mld(&sdata->vif) && sta && !sta->sta.mlo) {
+ struct ieee80211_link_data *link;
+
+ link_id = sta->deflink.link_id;
+@@ -2822,7 +2822,7 @@ static struct sk_buff *ieee80211_build_h
+ }
+
+ if (!chanctx_conf) {
+- if (!sdata->vif.valid_links) {
++ if (!ieee80211_vif_is_mld(&sdata->vif)) {
+ ret = -ENOTCONN;
+ goto free;
+ }
+@@ -3064,7 +3064,7 @@ void ieee80211_check_fast_xmit(struct st
+ !ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG))
+ goto out;
+
+- if (!sdata->vif.valid_links) {
++ if (!ieee80211_vif_is_mld(&sdata->vif)) {
+ rcu_read_lock();
+ chanctx_conf =
+ rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+@@ -3135,7 +3135,7 @@ void ieee80211_check_fast_xmit(struct st
+ fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
+ /* DA BSSID SA */
+ build.da_offs = offsetof(struct ieee80211_hdr, addr1);
+- if (sta->sta.mlo || !sdata->vif.valid_links) {
++ if (sta->sta.mlo || !ieee80211_vif_is_mld(&sdata->vif)) {
+ memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
+ } else {
+ unsigned int link_id = sta->deflink.link_id;
+@@ -4507,7 +4507,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s
+ __ieee80211_subif_start_xmit(skb, dev, 0,
+ IEEE80211_TX_CTRL_MLO_LINK_UNSPEC,
+ NULL);
+- } else if (sdata->vif.valid_links &&
++ } else if (ieee80211_vif_is_mld(&sdata->vif) &&
+ sdata->vif.type == NL80211_IFTYPE_AP &&
+ !ieee80211_hw_check(&sdata->local->hw, MLO_MCAST_MULTI_LINK_TX)) {
+ ieee80211_mlo_multicast_tx(dev, skb);
+@@ -4785,7 +4785,7 @@ static bool ieee80211_tx_pending_skb(str
+
+ if (info->control.flags & IEEE80211_TX_INTCFL_NEED_TXPROCESSING) {
+ /* update band only for non-MLD */
+- if (!sdata->vif.valid_links) {
++ if (!ieee80211_vif_is_mld(&sdata->vif)) {
+ chanctx_conf =
+ rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+ if (unlikely(!chanctx_conf)) {
+@@ -6008,7 +6008,7 @@ void __ieee80211_tx_skb_tid_band(struct
+ BUILD_BUG_ON(!FIELD_FIT(IEEE80211_TX_CTRL_MLO_LINK,
+ IEEE80211_LINK_UNSPECIFIED));
+
+- if (!sdata->vif.valid_links) {
++ if (!ieee80211_vif_is_mld(&sdata->vif)) {
+ link = 0;
+ } else if (link_id >= 0) {
+ link = link_id;
+@@ -6054,7 +6054,7 @@ void ieee80211_tx_skb_tid(struct ieee802
+ enum nl80211_band band;
+
+ rcu_read_lock();
+- if (!sdata->vif.valid_links) {
++ if (!ieee80211_vif_is_mld(&sdata->vif)) {
+ WARN_ON(link_id >= 0);
+ chanctx_conf =
+ rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -1701,7 +1701,7 @@ void ieee80211_send_auth(struct ieee8021
+ struct ieee80211_local *local = sdata->local;
+ struct sk_buff *skb;
+ struct ieee80211_mgmt *mgmt;
+- bool multi_link = sdata->vif.valid_links;
++ bool multi_link = ieee80211_vif_is_mld(&sdata->vif);
+ struct {
+ u8 id;
+ u8 len;
+@@ -2542,7 +2542,7 @@ int ieee80211_reconfig(struct ieee80211_
+ continue;
+
+ sdata_lock(sdata);
+- if (sdata->vif.valid_links) {
++ if (ieee80211_vif_is_mld(&sdata->vif)) {
+ struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS] = {
+ [0] = &sdata->vif.bss_conf,
+ };
+@@ -2562,7 +2562,7 @@ int ieee80211_reconfig(struct ieee80211_
+ for (link_id = 0;
+ link_id < ARRAY_SIZE(sdata->vif.link_conf);
+ link_id++) {
+- if (sdata->vif.valid_links &&
++ if (ieee80211_vif_is_mld(&sdata->vif) &&
+ !(sdata->vif.active_links & BIT(link_id)))
+ continue;
+
+@@ -2594,12 +2594,12 @@ int ieee80211_reconfig(struct ieee80211_
+ if (sdata->vif.bss_conf.mu_mimo_owner)
+ changed |= BSS_CHANGED_MU_GROUPS;
+
+- if (!sdata->vif.valid_links)
++ if (!ieee80211_vif_is_mld(&sdata->vif))
+ changed |= BSS_CHANGED_IDLE;
+
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_STATION:
+- if (!sdata->vif.valid_links) {
++ if (!ieee80211_vif_is_mld(&sdata->vif)) {
+ changed |= BSS_CHANGED_ASSOC |
+ BSS_CHANGED_ARP_FILTER |
+ BSS_CHANGED_PS;
+@@ -2637,7 +2637,7 @@ int ieee80211_reconfig(struct ieee80211_
+ case NL80211_IFTYPE_AP:
+ changed |= BSS_CHANGED_P2P_PS;
+
+- if (sdata->vif.valid_links)
++ if (ieee80211_vif_is_mld(&sdata->vif))
+ ieee80211_vif_cfg_change_notify(sdata,
+ BSS_CHANGED_SSID);
+ else
+@@ -2651,7 +2651,7 @@ int ieee80211_reconfig(struct ieee80211_
+ if (sdata->vif.type == NL80211_IFTYPE_AP) {
+ changed |= BSS_CHANGED_AP_PROBE_RESP;
+
+- if (sdata->vif.valid_links) {
++ if (ieee80211_vif_is_mld(&sdata->vif)) {
+ ieee80211_reconfig_ap_links(local,
+ sdata,
+ changed);
--- /dev/null
+From ee0db868ee4d88493dfdc82f59e3b4e449ddddd5 Mon Sep 17 00:00:00 2001
+From: Oldřich Jedlička <oldium.pro@gmail.com>
+Date: Sat, 4 Nov 2023 15:13:33 +0100
+Subject: wifi: mac80211: do not pass AP_VLAN vif pointer to drivers during
+ flush
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+[ Upstream commit 3e3a2b645c043f7e3e488d5011478cefb69bbe8b ]
+
+This fixes WARN_ONs when using AP_VLANs after station removal. The flush
+call passed AP_VLAN vif to driver, but because these vifs are virtual and
+not registered with drivers, we need to translate to the correct AP vif
+first.
+
+Closes: https://github.com/openwrt/openwrt/issues/12420
+Fixes: 0b75a1b1e42e ("wifi: mac80211: flush queues on STA removal")
+Fixes: d00800a289c9 ("wifi: mac80211: add flush_sta method")
+Tested-by: Konstantin Demin <rockdrilla@gmail.com>
+Tested-by: Koen Vandeputte <koen.vandeputte@citymesh.com>
+Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
+Link: https://lore.kernel.org/r/20231104141333.3710-1-oldium.pro@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/driver-ops.h | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/net/mac80211/driver-ops.h
++++ b/net/mac80211/driver-ops.h
+@@ -21,7 +21,7 @@
+ static inline struct ieee80211_sub_if_data *
+ get_bss_sdata(struct ieee80211_sub_if_data *sdata)
+ {
+- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
++ if (sdata && sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
+ u.ap);
+
+@@ -604,10 +604,13 @@ static inline void drv_flush(struct ieee
+ struct ieee80211_sub_if_data *sdata,
+ u32 queues, bool drop)
+ {
+- struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL;
++ struct ieee80211_vif *vif;
+
+ might_sleep();
+
++ sdata = get_bss_sdata(sdata);
++ vif = sdata ? &sdata->vif : NULL;
++
+ if (sdata && !check_sdata_in_driver(sdata))
+ return;
+
+@@ -623,6 +626,8 @@ static inline void drv_flush_sta(struct
+ {
+ might_sleep();
+
++ sdata = get_bss_sdata(sdata);
++
+ if (sdata && !check_sdata_in_driver(sdata))
+ return;
+
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Tue, 12 Sep 2023 15:09:27 +0200
+Subject: [PATCH] mac80211: fix mesh id corruption on 32 bit systems
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since the changed field size was increased to u64, mesh_bss_info_changed
+pulls invalid bits from the first 3 bytes of the mesh id, clears them, and
+passes them on to ieee80211_link_info_change_notify, because
+ifmsh->mbss_changed was not updated to match its size.
+Fix this by turning into ifmsh->mbss_changed into an unsigned long array with
+64 bit size.
+
+Fixes: 15ddba5f4311 ("wifi: mac80211: consistently use u64 for BSS changes")
+Reported-by: Thomas Hühn <thomas.huehn@hs-nordhausen.de>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -680,7 +680,7 @@ struct ieee80211_if_mesh {
+ struct timer_list mesh_path_root_timer;
+
+ unsigned long wrkq_flags;
+- unsigned long mbss_changed;
++ unsigned long mbss_changed[64 / BITS_PER_LONG];
+
+ bool userspace_handles_dfs;
+
+--- a/net/mac80211/mesh.c
++++ b/net/mac80211/mesh.c
+@@ -1106,7 +1106,7 @@ void ieee80211_mbss_info_change_notify(s
+
+ /* if we race with running work, worst case this work becomes a noop */
+ for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE)
+- set_bit(bit, &ifmsh->mbss_changed);
++ set_bit(bit, ifmsh->mbss_changed);
+ set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags);
+ ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+ }
+@@ -1188,7 +1188,7 @@ void ieee80211_stop_mesh(struct ieee8021
+
+ /* clear any mesh work (for next join) we may have accrued */
+ ifmsh->wrkq_flags = 0;
+- ifmsh->mbss_changed = 0;
++ memset(ifmsh->mbss_changed, 0, sizeof(ifmsh->mbss_changed));
+
+ local->fif_other_bss--;
+ atomic_dec(&local->iff_allmultis);
+@@ -1653,9 +1653,9 @@ static void mesh_bss_info_changed(struct
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ u32 bit, changed = 0;
+
+- for_each_set_bit(bit, &ifmsh->mbss_changed,
++ for_each_set_bit(bit, ifmsh->mbss_changed,
+ sizeof(changed) * BITS_PER_BYTE) {
+- clear_bit(bit, &ifmsh->mbss_changed);
++ clear_bit(bit, ifmsh->mbss_changed);
+ changed |= BIT(bit);
+ }
+
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
-@@ -614,21 +614,6 @@ static int wiphy_verify_combinations(str
+@@ -658,21 +658,6 @@ static int wiphy_verify_combinations(str
c->limits[j].max > 1))
return -EINVAL;
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -4092,6 +4092,7 @@ struct mgmt_frame_regs {
+@@ -4095,6 +4095,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
*
* @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting
* functions to adjust rfkill hw state
-@@ -4442,6 +4443,7 @@ struct cfg80211_ops {
+@@ -4445,6 +4446,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);
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -1705,6 +1705,7 @@ enum ieee80211_smps_mode {
+@@ -1714,6 +1714,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
*
* @chandef: the channel definition to tune to
* @radar_enabled: whether radar detection is enabled
-@@ -1725,6 +1726,7 @@ enum ieee80211_smps_mode {
+@@ -1734,6 +1735,7 @@ enum ieee80211_smps_mode {
struct ieee80211_conf {
u32 flags;
int power_level, dynamic_ps_timeout;
__NL80211_ATTR_AFTER_LAST,
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -3067,6 +3067,19 @@ static int ieee80211_get_tx_power(struct
+@@ -3077,6 +3077,19 @@ static int ieee80211_get_tx_power(struct
return 0;
}
static void ieee80211_rfkill_poll(struct wiphy *wiphy)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
-@@ -4989,6 +5002,7 @@ const struct cfg80211_ops mac80211_confi
+@@ -5007,6 +5020,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,
CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump)
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -1542,6 +1542,7 @@ struct ieee80211_local {
+@@ -1546,6 +1546,7 @@ struct ieee80211_local {
int dynamic_ps_forced_timeout;
int user_power_level; /* in dBm, for all interfaces */
if (local->hw.conf.power_level != power) {
changed |= IEEE80211_CONF_CHANGE_POWER;
local->hw.conf.power_level = power;
-@@ -762,6 +768,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
+@@ -759,6 +765,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;
local->hw.max_mtu = IEEE80211_MAX_DATA_LEN;
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
-@@ -800,6 +800,7 @@ static const struct nla_policy nl80211_p
+@@ -820,6 +820,7 @@ static const struct nla_policy nl80211_p
[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
[NL80211_ATTR_PUNCT_BITMAP] = NLA_POLICY_RANGE(NLA_U8, 0, 0xffff),
};
/* policy for the key attributes */
-@@ -3527,6 +3528,22 @@ static int nl80211_set_wiphy(struct sk_b
+@@ -3547,6 +3548,22 @@ static int nl80211_set_wiphy(struct sk_b
if (result)
goto out;
}
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
-@@ -2364,6 +2364,13 @@ static void sta_stats_decode_rate(struct
+@@ -2368,6 +2368,13 @@ static void sta_stats_decode_rate(struct
sband = local->hw.wiphy->bands[band];
--- /dev/null
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Mon, 28 Aug 2023 09:54:39 +0200
+Subject: [PATCH] wifi: cfg80211: add ieee80211_set_sband_iftype_data() helper
+ macro
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[rmilecki: extract from the e8c1841278a7]
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+---
+
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -555,6 +555,33 @@ struct ieee80211_supported_band {
+ };
+
+ /**
++ * _ieee80211_set_sband_iftype_data - set sband iftype data array
++ * @sband: the sband to initialize
++ * @iftd: the iftype data array pointer
++ * @n_iftd: the length of the iftype data array
++ *
++ * Set the sband iftype data array; use this where the length cannot
++ * be derived from the ARRAY_SIZE() of the argument, but prefer
++ * ieee80211_set_sband_iftype_data() where it can be used.
++ */
++static inline void
++_ieee80211_set_sband_iftype_data(struct ieee80211_supported_band *sband,
++ const struct ieee80211_sband_iftype_data *iftd,
++ u16 n_iftd)
++{
++ sband->iftype_data = iftd;
++ sband->n_iftype_data = n_iftd;
++}
++
++/**
++ * ieee80211_set_sband_iftype_data - set sband iftype data array
++ * @sband: the sband to initialize
++ * @iftd: the iftype data array
++ */
++#define ieee80211_set_sband_iftype_data(sband, iftd) \
++ _ieee80211_set_sband_iftype_data(sband, iftd, ARRAY_SIZE(iftd))
++
++/**
+ * ieee80211_get_sband_iftype_data - return sband data for a given iftype
+ * @sband: the sband to search for the STA on
+ * @iftype: enum nl80211_iftype