From dad6101c7c225ce27438e65dc1a8987a1966126c Mon Sep 17 00:00:00 2001 From: OPPEN321 Date: Fri, 21 Nov 2025 09:29:29 +0800 Subject: [PATCH] Merge Official Source --- .../210-wireless_netns_local_backport.patch | 5 +- ...DS-Params-IE-into-beacons-if-missing.patch | 116 ++++++++++++++++++ ...700-mwl8k-missing-pci-id-for-WNR854T.patch | 2 +- ...940-mwl8k_init_devices_synchronously.patch | 4 +- 4 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 patches/mwl/001-mwl8k-inject-DS-Params-IE-into-beacons-if-missing.patch diff --git a/patches/build/210-wireless_netns_local_backport.patch b/patches/build/210-wireless_netns_local_backport.patch index 9e027fe..af51220 100644 --- a/patches/build/210-wireless_netns_local_backport.patch +++ b/patches/build/210-wireless_netns_local_backport.patch @@ -4,11 +4,10 @@ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { if (!wdev->netdev) continue; -- wdev->netdev->netns_immutable = false; +#if LINUX_VERSION_IS_GEQ(6,15,0) -+ wdev->netdev->netns_immutable = true; + wdev->netdev->netns_immutable = false; +#elif LINUX_VERSION_IS_GEQ(6,12,0) -+ wdev->netdev->netns_local = true; ++ wdev->netdev->netns_local = false; +#endif err = dev_change_net_namespace(wdev->netdev, net, "wlan%d"); if (err) diff --git a/patches/mwl/001-mwl8k-inject-DS-Params-IE-into-beacons-if-missing.patch b/patches/mwl/001-mwl8k-inject-DS-Params-IE-into-beacons-if-missing.patch new file mode 100644 index 0000000..ca66c9c --- /dev/null +++ b/patches/mwl/001-mwl8k-inject-DS-Params-IE-into-beacons-if-missing.patch @@ -0,0 +1,116 @@ +From f4e661a75cdfa7eb88ac0fa832edd4a90775805d Mon Sep 17 00:00:00 2001 +From: Pawel Dembicki +Date: Fri, 7 Nov 2025 23:05:56 +0100 +Subject: [PATCH] mwl8k: inject DS Params IE into beacons if missing + +Some Marvell AP firmware used with mwl8k misbehaves when beacon frames +do not contain a WLAN_EID_DS_PARAMS information element with the current +channel. It was reported on OpenWrt Github issues [0]. + +When hostapd/mac80211 omits DS Params from the beacon (which is valid on +some bands), the firmware stops transmitting sane frames and RX status +starts reporting bogus channel information. This makes AP mode unusable. + +Newer Marvell drivers (mwlwifi [1]) hard-code DS Params IE into AP beacons +for all chips, which suggests this is a firmware requirement rather than +a mwl8k-specific quirk. + +Mirror that behaviour in mwl8k: when setting the beacon, check if +WLAN_EID_DS_PARAMS is present, and if not, extend the beacon and inject +a DS Params IE at the beginning of the IE list, using the current +channel from hw->conf.chandef.chan. + +Tested on Linksys EA4500 (88W8366). + +[0] https://github.com/openwrt/openwrt/issues/19088 +[1] https://github.com/kaloz/mwlwifi/blob/db97edf20fadea2617805006f5230665fadc6a8c/hif/fwcmd.c#L675 + +Tested-by: Antony Kolitsos +Signed-off-by: Pawel Dembicki +--- + drivers/net/wireless/marvell/mwl8k.c | 61 +++++++++++++++++++++++++--- + 1 file changed, 56 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/marvell/mwl8k.c ++++ b/drivers/net/wireless/marvell/mwl8k.c +@@ -2962,6 +2962,42 @@ mwl8k_cmd_rf_antenna(struct ieee80211_hw + /* + * CMD_SET_BEACON. + */ ++ ++static bool mwl8k_beacon_has_ds_params(const u8 *buf, int len) ++{ ++ const struct ieee80211_mgmt *mgmt = (const void *)buf; ++ int ies_len; ++ ++ if (len <= offsetof(struct ieee80211_mgmt, u.beacon.variable)) ++ return false; ++ ++ ies_len = len - offsetof(struct ieee80211_mgmt, u.beacon.variable); ++ ++ return cfg80211_find_ie(WLAN_EID_DS_PARAMS, mgmt->u.beacon.variable, ++ ies_len) != NULL; ++} ++ ++static void mwl8k_beacon_copy_inject_ds_params(struct ieee80211_hw *hw, ++ u8 *buf_dst, const u8 *buf_src, ++ int src_len) ++{ ++ const struct ieee80211_mgmt *mgmt = (const void *)buf_src; ++ const u8 *ies; ++ int hdr_len, left; ++ ++ ies = mgmt->u.beacon.variable; ++ hdr_len = ies - buf_src; ++ left = src_len - hdr_len; ++ ++ memcpy(buf_dst, buf_src, hdr_len); ++ ++ /* Inject a DS Params IE at the beginning of the IE list */ ++ buf_dst[hdr_len + 0] = WLAN_EID_DS_PARAMS; ++ buf_dst[hdr_len + 1] = 1; ++ buf_dst[hdr_len + 2] = hw->conf.chandef.chan->hw_value; ++ ++ memcpy(buf_dst + hdr_len + 3, buf_src + hdr_len, left); ++} + struct mwl8k_cmd_set_beacon { + struct mwl8k_cmd_pkt_hdr header; + __le16 beacon_len; +@@ -2971,17 +3007,32 @@ struct mwl8k_cmd_set_beacon { + static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u8 *beacon, int len) + { ++ bool ds_params_present = mwl8k_beacon_has_ds_params(beacon, len); + struct mwl8k_cmd_set_beacon *cmd; +- int rc; ++ int rc, final_len = len; ++ ++ if (!ds_params_present) ++ /* ++ * mwl8k firmware requires a DS Params IE with the current ++ * channel in AP beacons. If mac80211/hostapd does not ++ * include it, inject one here. IE ID + length + channel ++ * number = 3 bytes. ++ */ ++ final_len += 3; + +- cmd = kzalloc(sizeof(*cmd) + len, GFP_KERNEL); ++ cmd = kzalloc(sizeof(*cmd) + final_len, GFP_KERNEL); + if (cmd == NULL) + return -ENOMEM; + + cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON); +- cmd->header.length = cpu_to_le16(sizeof(*cmd) + len); +- cmd->beacon_len = cpu_to_le16(len); +- memcpy(cmd->beacon, beacon, len); ++ cmd->header.length = cpu_to_le16(sizeof(*cmd) + final_len); ++ cmd->beacon_len = cpu_to_le16(final_len); ++ ++ if (ds_params_present) ++ memcpy(cmd->beacon, beacon, len); ++ else ++ mwl8k_beacon_copy_inject_ds_params(hw, cmd->beacon, beacon, ++ len); + + rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); + kfree(cmd); diff --git a/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch b/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch index cfb7dcf..3998afc 100644 --- a/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch +++ b/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c -@@ -5712,6 +5712,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") +@@ -5763,6 +5763,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); static const struct pci_device_id mwl8k_pci_id_table[] = { diff --git a/patches/mwl/940-mwl8k_init_devices_synchronously.patch b/patches/mwl/940-mwl8k_init_devices_synchronously.patch index d09cfac..a229be9 100644 --- a/patches/mwl/940-mwl8k_init_devices_synchronously.patch +++ b/patches/mwl/940-mwl8k_init_devices_synchronously.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c -@@ -6298,6 +6298,8 @@ static int mwl8k_probe(struct pci_dev *p +@@ -6349,6 +6349,8 @@ static int mwl8k_probe(struct pci_dev *p priv->running_bsses = 0; @@ -9,7 +9,7 @@ return rc; err_stop_firmware: -@@ -6331,8 +6333,6 @@ static void mwl8k_remove(struct pci_dev +@@ -6382,8 +6384,6 @@ static void mwl8k_remove(struct pci_dev return; priv = hw->priv;