From: Shiji Yang Date: Thu, 22 Feb 2024 21:36:50 +0000 (+0800) Subject: mac80211: rtl8xxxu: sync with linux-next 20240229 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=97f542238a23a1c8461b40dfb26d9213826d8e78;p=openwrt%2Fstaging%2Fthess.git mac80211: rtl8xxxu: sync with linux-next 20240229 Backporting upstream patches to improve RTL8188F support. Signed-off-by: Shiji Yang --- diff --git a/package/kernel/mac80211/patches/rtl/001-01-v6.9-wifi-rtl8xxxu-remove-assignment-of-priv-vif-in-rtl8x.patch b/package/kernel/mac80211/patches/rtl/001-01-v6.9-wifi-rtl8xxxu-remove-assignment-of-priv-vif-in-rtl8x.patch new file mode 100644 index 0000000000..e0a01a8120 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-01-v6.9-wifi-rtl8xxxu-remove-assignment-of-priv-vif-in-rtl8x.patch @@ -0,0 +1,27 @@ +From d55cb6d8a99441aff55cb9ce663a07f7f1667e83 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:22 +0100 +Subject: [PATCH 01/21] wifi: rtl8xxxu: remove assignment of priv->vif in + rtl8xxxu_bss_info_changed() + +priv->vif gets already set in rtl8xxxu_add_interface, there is no need +to set it also in rtl8xxxu_bss_info_changed(). + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-2-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -5004,7 +5004,6 @@ rtl8xxxu_bss_info_changed(struct ieee802 + + rtl8xxxu_update_ra_report(rarpt, highest_rate, sgi, bw); + +- priv->vif = vif; + priv->rssi_level = RTL8XXXU_RATR_STA_INIT; + + priv->fops->update_rate_mask(priv, ramask, 0, sgi, diff --git a/package/kernel/mac80211/patches/rtl/001-02-v6.9-wifi-rtl8xxxu-prepare-supporting-two-virtual-interfa.patch b/package/kernel/mac80211/patches/rtl/001-02-v6.9-wifi-rtl8xxxu-prepare-supporting-two-virtual-interfa.patch new file mode 100644 index 0000000000..b1948bb7c2 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-02-v6.9-wifi-rtl8xxxu-prepare-supporting-two-virtual-interfa.patch @@ -0,0 +1,61 @@ +From 2bbd7d584046038ce655e476628bb15e1460fac6 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:23 +0100 +Subject: [PATCH 02/21] wifi: rtl8xxxu: prepare supporting two virtual + interfaces + +To prepare for concurrent mode, add an array ("vifs") to rtl8xxxu_priv +to keep track of both interfaces. + +Keep the old priv->vif as long there are still users of it and let +priv->vifs[0] point to the same location. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-3-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 2 ++ + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 10 +++++++--- + 2 files changed, 9 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +@@ -1897,6 +1897,8 @@ struct rtl8xxxu_priv { + * is supported and no iface_combinations are provided. + */ + struct ieee80211_vif *vif; ++ ++ struct ieee80211_vif *vifs[2]; + struct delayed_work ra_watchdog; + struct work_struct c2hcmd_work; + struct sk_buff_head c2hcmd_queue; +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -6569,10 +6569,12 @@ static int rtl8xxxu_add_interface(struct + int ret; + u8 val8; + +- if (!priv->vif) ++ if (!priv->vif) { + priv->vif = vif; +- else ++ priv->vifs[0] = vif; ++ } else { + return -EOPNOTSUPP; ++ } + + switch (vif->type) { + case NL80211_IFTYPE_STATION: +@@ -6622,8 +6624,10 @@ static void rtl8xxxu_remove_interface(st + + dev_dbg(&priv->udev->dev, "%s\n", __func__); + +- if (priv->vif) ++ if (priv->vif) { + priv->vif = NULL; ++ priv->vifs[0] = NULL; ++ } + } + + static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed) diff --git a/package/kernel/mac80211/patches/rtl/001-03-v6.9-wifi-rtl8xxxu-support-setting-linktype-for-both-inte.patch b/package/kernel/mac80211/patches/rtl/001-03-v6.9-wifi-rtl8xxxu-support-setting-linktype-for-both-inte.patch new file mode 100644 index 0000000000..f473fad118 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-03-v6.9-wifi-rtl8xxxu-support-setting-linktype-for-both-inte.patch @@ -0,0 +1,102 @@ +From 7f444692cde83c1455682c2d0d2c9a666422b867 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:24 +0100 +Subject: [PATCH 03/21] wifi: rtl8xxxu: support setting linktype for both + interfaces + +To prepare for concurrent mode, enhance the set_linktype function to be +able to set the linktype in the MSR register for both hardware ports. + +Until the users of set_linktype can handle multiple interfaces, use +port_num = 0. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-4-martin.kaistra@linutronix.de +--- + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 37 +++++++++++-------- + 1 file changed, 22 insertions(+), 15 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -1633,33 +1633,41 @@ rtl8xxxu_gen1_set_tx_power(struct rtl8xx + } + + static void rtl8xxxu_set_linktype(struct rtl8xxxu_priv *priv, +- enum nl80211_iftype linktype) ++ enum nl80211_iftype linktype, int port_num) + { +- u8 val8; +- +- val8 = rtl8xxxu_read8(priv, REG_MSR); +- val8 &= ~MSR_LINKTYPE_MASK; ++ u8 val8, type; + + switch (linktype) { + case NL80211_IFTYPE_UNSPECIFIED: +- val8 |= MSR_LINKTYPE_NONE; ++ type = MSR_LINKTYPE_NONE; + break; + case NL80211_IFTYPE_ADHOC: +- val8 |= MSR_LINKTYPE_ADHOC; ++ type = MSR_LINKTYPE_ADHOC; + break; + case NL80211_IFTYPE_STATION: +- val8 |= MSR_LINKTYPE_STATION; ++ type = MSR_LINKTYPE_STATION; + break; + case NL80211_IFTYPE_AP: +- val8 |= MSR_LINKTYPE_AP; ++ type = MSR_LINKTYPE_AP; + break; + default: +- goto out; ++ return; ++ } ++ ++ switch (port_num) { ++ case 0: ++ val8 = rtl8xxxu_read8(priv, REG_MSR) & 0x0c; ++ val8 |= type; ++ break; ++ case 1: ++ val8 = rtl8xxxu_read8(priv, REG_MSR) & 0x03; ++ val8 |= type << 2; ++ break; ++ default: ++ return; + } + + rtl8xxxu_write8(priv, REG_MSR, val8); +-out: +- return; + } + + static void +@@ -4236,7 +4244,6 @@ static int rtl8xxxu_init_device(struct i + } + + rtl8xxxu_set_mac(priv); +- rtl8xxxu_set_linktype(priv, NL80211_IFTYPE_STATION); + + /* + * Configure initial WMAC settings +@@ -4964,7 +4971,7 @@ rtl8xxxu_bss_info_changed(struct ieee802 + if (changed & BSS_CHANGED_ASSOC) { + dev_dbg(dev, "Changed ASSOC: %i!\n", vif->cfg.assoc); + +- rtl8xxxu_set_linktype(priv, vif->type); ++ rtl8xxxu_set_linktype(priv, vif->type, 0); + + if (vif->cfg.assoc) { + u32 ramask; +@@ -6610,7 +6617,7 @@ static int rtl8xxxu_add_interface(struct + ret = -EOPNOTSUPP; + } + +- rtl8xxxu_set_linktype(priv, vif->type); ++ rtl8xxxu_set_linktype(priv, vif->type, 0); + ether_addr_copy(priv->mac_addr, vif->addr); + rtl8xxxu_set_mac(priv); + diff --git a/package/kernel/mac80211/patches/rtl/001-04-v6.9-wifi-rtl8xxxu-8188e-convert-usage-of-priv-vif-to-pri.patch b/package/kernel/mac80211/patches/rtl/001-04-v6.9-wifi-rtl8xxxu-8188e-convert-usage-of-priv-vif-to-pri.patch new file mode 100644 index 0000000000..160a71adc7 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-04-v6.9-wifi-rtl8xxxu-8188e-convert-usage-of-priv-vif-to-pri.patch @@ -0,0 +1,28 @@ +From a047e46a7b98de384a158b25a05dc09aa7d70c5f Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:25 +0100 +Subject: [PATCH 04/21] wifi: rtl8xxxu: 8188e: convert usage of priv->vif to + priv->vifs[0] + +The driver currently does not support AP or concurrent mode for 8188e, +so just use priv->vifs[0] instead of priv->vif for now. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-5-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c +@@ -1699,7 +1699,7 @@ void rtl8188e_handle_ra_tx_report2(struc + /* We only use macid 0, so only the first item is relevant. + * AP mode will use more of them if it's ever implemented. + */ +- if (!priv->vif || priv->vif->type == NL80211_IFTYPE_STATION) ++ if (!priv->vifs[0] || priv->vifs[0]->type == NL80211_IFTYPE_STATION) + items = 1; + + for (macid = 0; macid < items; macid++) { diff --git a/package/kernel/mac80211/patches/rtl/001-05-v6.9-wifi-rtl8xxxu-support-setting-mac-address-register-f.patch b/package/kernel/mac80211/patches/rtl/001-05-v6.9-wifi-rtl8xxxu-support-setting-mac-address-register-f.patch new file mode 100644 index 0000000000..c3e3fea450 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-05-v6.9-wifi-rtl8xxxu-support-setting-mac-address-register-f.patch @@ -0,0 +1,72 @@ +From 00add60cad3c9690ac0f9d4f6685f96ccd607670 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:26 +0100 +Subject: [PATCH 05/21] wifi: rtl8xxxu: support setting mac address register + for both interfaces + +To prepare for concurrent mode, enhance rtl8xxxu_set_mac() to write the +mac address of the respective interface to REG_MACID or REG_MACID1. + +Remove the call to rtl8xxxu_set_mac() from the init function as we set +it in rtl8xxxu_add_interface() later anyway. + +Until rtl8xxxu_add_interface() can handle both interfaces, call +rtl8xxxu_set_mac() with port_num = 0. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-6-martin.kaistra@linutronix.de +--- + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 20 +++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -3580,15 +3580,25 @@ void rtl8723a_phy_lc_calibrate(struct rt + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); + } + +-static int rtl8xxxu_set_mac(struct rtl8xxxu_priv *priv) ++static int rtl8xxxu_set_mac(struct rtl8xxxu_priv *priv, int port_num) + { + int i; + u16 reg; + +- reg = REG_MACID; ++ switch (port_num) { ++ case 0: ++ reg = REG_MACID; ++ break; ++ case 1: ++ reg = REG_MACID1; ++ break; ++ default: ++ WARN_ONCE("%s: invalid port_num\n", __func__); ++ return -EINVAL; ++ } + + for (i = 0; i < ETH_ALEN; i++) +- rtl8xxxu_write8(priv, reg + i, priv->mac_addr[i]); ++ rtl8xxxu_write8(priv, reg + i, priv->vifs[port_num]->addr[i]); + + return 0; + } +@@ -4243,8 +4253,6 @@ static int rtl8xxxu_init_device(struct i + rtl8xxxu_write32(priv, REG_HIMR, 0xffffffff); + } + +- rtl8xxxu_set_mac(priv); +- + /* + * Configure initial WMAC settings + */ +@@ -6619,7 +6627,7 @@ static int rtl8xxxu_add_interface(struct + + rtl8xxxu_set_linktype(priv, vif->type, 0); + ether_addr_copy(priv->mac_addr, vif->addr); +- rtl8xxxu_set_mac(priv); ++ rtl8xxxu_set_mac(priv, 0); + + return ret; + } diff --git a/package/kernel/mac80211/patches/rtl/001-06-v6.9-wifi-rtl8xxxu-extend-wifi-connected-check-to-both-in.patch b/package/kernel/mac80211/patches/rtl/001-06-v6.9-wifi-rtl8xxxu-extend-wifi-connected-check-to-both-in.patch new file mode 100644 index 0000000000..70879f861f --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-06-v6.9-wifi-rtl8xxxu-extend-wifi-connected-check-to-both-in.patch @@ -0,0 +1,75 @@ +From 9aa776209ca31695bead52674ad943848ccc97d5 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:27 +0100 +Subject: [PATCH 06/21] wifi: rtl8xxxu: extend wifi connected check to both + interfaces + +There are multiple places in the code where the current connection +status of wifi is checked. The driver will support two interfaces soon +and either one of them (or both) could be connected. + +Convert all uses of (vif && vif->cfg.assoc) to a new helper +function rtl8xxxu_is_assoc() which checks both interfaces. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-7-martin.kaistra@linutronix.de +--- + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 20 +++++++++---------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -6043,18 +6043,20 @@ void rtl8723bu_update_bt_link_info(struc + btcoex->bt_busy = false; + } + ++static inline bool rtl8xxxu_is_assoc(struct rtl8xxxu_priv *priv) ++{ ++ return (priv->vifs[0] && priv->vifs[0]->cfg.assoc) || ++ (priv->vifs[1] && priv->vifs[1]->cfg.assoc); ++} ++ + static + void rtl8723bu_handle_bt_inquiry(struct rtl8xxxu_priv *priv) + { +- struct ieee80211_vif *vif; + struct rtl8xxxu_btcoex *btcoex; +- bool wifi_connected; + +- vif = priv->vif; + btcoex = &priv->bt_coex; +- wifi_connected = (vif && vif->cfg.assoc); + +- if (!wifi_connected) { ++ if (!rtl8xxxu_is_assoc(priv)) { + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0); + rtl8723bu_set_coex_with_type(priv, 0); + } else if (btcoex->has_sco || btcoex->has_hid || btcoex->has_a2dp) { +@@ -6072,15 +6074,11 @@ void rtl8723bu_handle_bt_inquiry(struct + static + void rtl8723bu_handle_bt_info(struct rtl8xxxu_priv *priv) + { +- struct ieee80211_vif *vif; + struct rtl8xxxu_btcoex *btcoex; +- bool wifi_connected; + +- vif = priv->vif; + btcoex = &priv->bt_coex; +- wifi_connected = (vif && vif->cfg.assoc); + +- if (wifi_connected) { ++ if (rtl8xxxu_is_assoc(priv)) { + u32 val32 = 0; + u32 high_prio_tx = 0, high_prio_rx = 0; + +@@ -7103,7 +7101,7 @@ static void rtl8xxxu_track_cfo(struct rt + int cfo_khz_a, cfo_khz_b, cfo_average; + int crystal_cap; + +- if (!priv->vif || !priv->vif->cfg.assoc) { ++ if (!rtl8xxxu_is_assoc(priv)) { + /* Reset */ + cfo->adjust = true; + diff --git a/package/kernel/mac80211/patches/rtl/001-07-v6.9-wifi-rtl8xxxu-extend-check-for-matching-bssid-to-bot.patch b/package/kernel/mac80211/patches/rtl/001-07-v6.9-wifi-rtl8xxxu-extend-check-for-matching-bssid-to-bot.patch new file mode 100644 index 0000000000..2c53aded28 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-07-v6.9-wifi-rtl8xxxu-extend-check-for-matching-bssid-to-bot.patch @@ -0,0 +1,70 @@ +From 80fd8687db41b1e04f78c37137d090f2165cca6e Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:28 +0100 +Subject: [PATCH 07/21] wifi: rtl8xxxu: extend check for matching bssid to both + interfaces + +The driver will support two interfaces soon, which both can be in +station mode, so extend the check, whether cfo information should be +parsed, to cover both interfaces. + +For better code readability put the lines with priv->vifs[port_num] in a +separate function. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-8-martin.kaistra@linutronix.de +--- + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 22 ++++++++++++------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -5706,6 +5706,16 @@ static void rtl8xxxu_update_beacon_work_ + rtl8xxxu_send_beacon_frame(hw, vif); + } + ++static inline bool rtl8xxxu_is_packet_match_bssid(struct rtl8xxxu_priv *priv, ++ struct ieee80211_hdr *hdr, ++ int port_num) ++{ ++ return priv->vifs[port_num] && ++ priv->vifs[port_num]->type == NL80211_IFTYPE_STATION && ++ priv->vifs[port_num]->cfg.assoc && ++ ether_addr_equal(priv->vifs[port_num]->bss_conf.bssid, hdr->addr2); ++} ++ + void rtl8723au_rx_parse_phystats(struct rtl8xxxu_priv *priv, + struct ieee80211_rx_status *rx_status, + struct rtl8723au_phy_stats *phy_stats, +@@ -5722,12 +5732,10 @@ void rtl8723au_rx_parse_phystats(struct + rx_status->signal = priv->fops->cck_rssi(priv, phy_stats); + } else { + bool parse_cfo = priv->fops->set_crystal_cap && +- priv->vif && +- priv->vif->type == NL80211_IFTYPE_STATION && +- priv->vif->cfg.assoc && + !crc_icv_err && + !ieee80211_is_ctl(hdr->frame_control) && +- ether_addr_equal(priv->vif->bss_conf.bssid, hdr->addr2); ++ (rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) || ++ rtl8xxxu_is_packet_match_bssid(priv, hdr, 1)); + + if (parse_cfo) { + priv->cfo_tracking.cfo_tail[0] = phy_stats->path_cfotail[0]; +@@ -5762,12 +5770,10 @@ static void jaguar2_rx_parse_phystats_ty + bool crc_icv_err) + { + bool parse_cfo = priv->fops->set_crystal_cap && +- priv->vif && +- priv->vif->type == NL80211_IFTYPE_STATION && +- priv->vif->cfg.assoc && + !crc_icv_err && + !ieee80211_is_ctl(hdr->frame_control) && +- ether_addr_equal(priv->vif->bss_conf.bssid, hdr->addr2); ++ (rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) || ++ rtl8xxxu_is_packet_match_bssid(priv, hdr, 1)); + u8 pwdb_max = 0; + int rx_path; + diff --git a/package/kernel/mac80211/patches/rtl/001-08-v6.9-wifi-rtl8xxxu-don-t-parse-CFO-if-both-interfaces-are.patch b/package/kernel/mac80211/patches/rtl/001-08-v6.9-wifi-rtl8xxxu-don-t-parse-CFO-if-both-interfaces-are.patch new file mode 100644 index 0000000000..bad1c3cb27 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-08-v6.9-wifi-rtl8xxxu-don-t-parse-CFO-if-both-interfaces-are.patch @@ -0,0 +1,51 @@ +From f86dd8eaf8da84ee5b803d90b8c311d7e2725d0b Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:29 +0100 +Subject: [PATCH 08/21] wifi: rtl8xxxu: don't parse CFO, if both interfaces are + connected in STA mode + +If both interfaces are in STATION mode and both are connected to an AP, +there might be conflicting CFO values for the two connections. Ignore +the CFO information in this case. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-9-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -5716,6 +5716,14 @@ static inline bool rtl8xxxu_is_packet_ma + ether_addr_equal(priv->vifs[port_num]->bss_conf.bssid, hdr->addr2); + } + ++static inline bool rtl8xxxu_is_sta_sta(struct rtl8xxxu_priv *priv) ++{ ++ return (priv->vifs[0] && priv->vifs[0]->cfg.assoc && ++ priv->vifs[0]->type == NL80211_IFTYPE_STATION) && ++ (priv->vifs[1] && priv->vifs[1]->cfg.assoc && ++ priv->vifs[1]->type == NL80211_IFTYPE_STATION); ++} ++ + void rtl8723au_rx_parse_phystats(struct rtl8xxxu_priv *priv, + struct ieee80211_rx_status *rx_status, + struct rtl8723au_phy_stats *phy_stats, +@@ -5734,6 +5742,7 @@ void rtl8723au_rx_parse_phystats(struct + bool parse_cfo = priv->fops->set_crystal_cap && + !crc_icv_err && + !ieee80211_is_ctl(hdr->frame_control) && ++ !rtl8xxxu_is_sta_sta(priv) && + (rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) || + rtl8xxxu_is_packet_match_bssid(priv, hdr, 1)); + +@@ -5772,6 +5781,7 @@ static void jaguar2_rx_parse_phystats_ty + bool parse_cfo = priv->fops->set_crystal_cap && + !crc_icv_err && + !ieee80211_is_ctl(hdr->frame_control) && ++ !rtl8xxxu_is_sta_sta(priv) && + (rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) || + rtl8xxxu_is_packet_match_bssid(priv, hdr, 1)); + u8 pwdb_max = 0; diff --git a/package/kernel/mac80211/patches/rtl/001-09-v6.9-wifi-rtl8xxxu-support-setting-bssid-register-for-mul.patch b/package/kernel/mac80211/patches/rtl/001-09-v6.9-wifi-rtl8xxxu-support-setting-bssid-register-for-mul.patch new file mode 100644 index 0000000000..def70343b0 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-09-v6.9-wifi-rtl8xxxu-support-setting-bssid-register-for-mul.patch @@ -0,0 +1,67 @@ +From 3ff7a05996f901a7a10068b42e9dc8435f908a4c Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:30 +0100 +Subject: [PATCH 09/21] wifi: rtl8xxxu: support setting bssid register for + multiple interfaces + +To prepare for concurrent mode, enhance rtl8xxxu_set_bssid() to write the +BSSID of the respective interface to REG_BSSID or REG_BSSID1. + +Like done with rtl8xxxu_set_mac(), call rtl8xxxu_set_bssid() with +port_num = 0, until the callers also support multiple interfaces. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-10-martin.kaistra@linutronix.de +--- + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -3603,14 +3603,24 @@ static int rtl8xxxu_set_mac(struct rtl8x + return 0; + } + +-static int rtl8xxxu_set_bssid(struct rtl8xxxu_priv *priv, const u8 *bssid) ++static int rtl8xxxu_set_bssid(struct rtl8xxxu_priv *priv, const u8 *bssid, int port_num) + { + int i; + u16 reg; + + dev_dbg(&priv->udev->dev, "%s: (%pM)\n", __func__, bssid); + +- reg = REG_BSSID; ++ switch (port_num) { ++ case 0: ++ reg = REG_BSSID; ++ break; ++ case 1: ++ reg = REG_BSSID1; ++ break; ++ default: ++ WARN_ONCE("%s: invalid port_num\n", __func__); ++ return -EINVAL; ++ } + + for (i = 0; i < ETH_ALEN; i++) + rtl8xxxu_write8(priv, reg + i, bssid[i]); +@@ -5068,7 +5078,7 @@ rtl8xxxu_bss_info_changed(struct ieee802 + + if (changed & BSS_CHANGED_BSSID) { + dev_dbg(dev, "Changed BSSID!\n"); +- rtl8xxxu_set_bssid(priv, bss_conf->bssid); ++ rtl8xxxu_set_bssid(priv, bss_conf->bssid, 0); + } + + if (changed & BSS_CHANGED_BASIC_RATES) { +@@ -5097,7 +5107,7 @@ static int rtl8xxxu_start_ap(struct ieee + struct device *dev = &priv->udev->dev; + + dev_dbg(dev, "Start AP mode\n"); +- rtl8xxxu_set_bssid(priv, vif->bss_conf.bssid); ++ rtl8xxxu_set_bssid(priv, vif->bss_conf.bssid, 0); + rtl8xxxu_write16(priv, REG_BCN_INTERVAL, vif->bss_conf.beacon_int); + priv->fops->report_connect(priv, RTL8XXXU_BC_MC_MACID, 0, true); + diff --git a/package/kernel/mac80211/patches/rtl/001-10-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-set_aif.patch b/package/kernel/mac80211/patches/rtl/001-10-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-set_aif.patch new file mode 100644 index 0000000000..b8cb66dd92 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-10-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-set_aif.patch @@ -0,0 +1,44 @@ +From 43532c050f8eec4056a21978fdb5b958e1477553 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:31 +0100 +Subject: [PATCH 10/21] wifi: rtl8xxxu: support multiple interfaces in + set_aifs() + +In concurrent mode supported by this driver, both interfaces will use +the same channel and same wireless mode. +It is therefore possible to get the wireless mode by checking the first +connected interface. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-11-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4913,14 +4913,20 @@ static void rtl8xxxu_set_aifs(struct rtl + u8 aifs, aifsn, sifs; + int i; + +- if (priv->vif) { ++ for (i = 0; i < ARRAY_SIZE(priv->vifs); i++) { ++ if (!priv->vifs[i]) ++ continue; ++ + struct ieee80211_sta *sta; + + rcu_read_lock(); +- sta = ieee80211_find_sta(priv->vif, priv->vif->bss_conf.bssid); ++ sta = ieee80211_find_sta(priv->vifs[i], priv->vifs[i]->bss_conf.bssid); + if (sta) + wireless_mode = rtl8xxxu_wireless_mode(priv->hw, sta); + rcu_read_unlock(); ++ ++ if (wireless_mode) ++ break; + } + + if (priv->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ || diff --git a/package/kernel/mac80211/patches/rtl/001-11-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-update_.patch b/package/kernel/mac80211/patches/rtl/001-11-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-update_.patch new file mode 100644 index 0000000000..63960e7ae7 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-11-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-update_.patch @@ -0,0 +1,28 @@ +From 05b22e9b7d84253f765cde01cb09d144094b61c9 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:32 +0100 +Subject: [PATCH 11/21] wifi: rtl8xxxu: support multiple interfaces in + update_beacon_work_callback() + +As we only want to support AP mode/sending beacons on port 0, it is +enough to replace priv->vif with priv->vifs[0]. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-12-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -5712,7 +5712,7 @@ static void rtl8xxxu_update_beacon_work_ + struct rtl8xxxu_priv *priv = + container_of(work, struct rtl8xxxu_priv, update_beacon_work); + struct ieee80211_hw *hw = priv->hw; +- struct ieee80211_vif *vif = priv->vif; ++ struct ieee80211_vif *vif = priv->vifs[0]; + + if (!vif) { + WARN_ONCE(true, "no vif to update beacon\n"); diff --git a/package/kernel/mac80211/patches/rtl/001-12-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-configu.patch b/package/kernel/mac80211/patches/rtl/001-12-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-configu.patch new file mode 100644 index 0000000000..707236b7dc --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-12-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-configu.patch @@ -0,0 +1,33 @@ +From 6b76638287055791e74b32c401a39ea1b91e7158 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:33 +0100 +Subject: [PATCH 12/21] wifi: rtl8xxxu: support multiple interfaces in + configure_filter() + +As we only want to support AP mode/sending beacons on port 0, change +from priv->vif to priv->vifs[0] in the check for AP mode. +Additionally, if we are in AP mode, don't filter RX beacon and probe +response frames to still allow working STATION mode on the other +interface. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-13-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -6794,8 +6794,8 @@ static void rtl8xxxu_configure_filter(st + else + rcr |= RCR_CHECK_BSSID_BEACON | RCR_CHECK_BSSID_MATCH; + +- if (priv->vif && priv->vif->type == NL80211_IFTYPE_AP) +- rcr &= ~RCR_CHECK_BSSID_MATCH; ++ if (priv->vifs[0] && priv->vifs[0]->type == NL80211_IFTYPE_AP) ++ rcr &= ~(RCR_CHECK_BSSID_MATCH | RCR_CHECK_BSSID_BEACON); + + if (*total_flags & FIF_CONTROL) + rcr |= RCR_ACCEPT_CTRL_FRAME; diff --git a/package/kernel/mac80211/patches/rtl/001-13-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-watchdo.patch b/package/kernel/mac80211/patches/rtl/001-13-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-watchdo.patch new file mode 100644 index 0000000000..b174b704d7 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-13-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-watchdo.patch @@ -0,0 +1,66 @@ +From 3f9baa99f8429ea6f56e7cc8d881c027518e9573 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:34 +0100 +Subject: [PATCH 13/21] wifi: rtl8xxxu: support multiple interfaces in + watchdog_callback() + +Check first whether priv->vifs[0] exists and is of type STATION, then go +to priv->vifs[1]. Make sure to call refresh_rate_mask for both +interfaces. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-14-martin.kaistra@linutronix.de +--- + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -7200,11 +7200,15 @@ static void rtl8xxxu_watchdog_callback(s + { + struct ieee80211_vif *vif; + struct rtl8xxxu_priv *priv; ++ int i; + + priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work); +- vif = priv->vif; ++ for (i = 0; i < ARRAY_SIZE(priv->vifs); i++) { ++ vif = priv->vifs[i]; ++ ++ if (!vif || vif->type != NL80211_IFTYPE_STATION) ++ continue; + +- if (vif && vif->type == NL80211_IFTYPE_STATION) { + int signal; + struct ieee80211_sta *sta; + +@@ -7215,22 +7219,21 @@ static void rtl8xxxu_watchdog_callback(s + + dev_dbg(dev, "%s: no sta found\n", __func__); + rcu_read_unlock(); +- goto out; ++ continue; + } + rcu_read_unlock(); + + signal = ieee80211_ave_rssi(vif); + +- priv->fops->report_rssi(priv, 0, ++ priv->fops->report_rssi(priv, rtl8xxxu_get_macid(priv, sta), + rtl8xxxu_signal_to_snr(signal)); + +- if (priv->fops->set_crystal_cap) +- rtl8xxxu_track_cfo(priv); +- + rtl8xxxu_refresh_rate_mask(priv, signal, sta, false); + } + +-out: ++ if (priv->fops->set_crystal_cap) ++ rtl8xxxu_track_cfo(priv); ++ + schedule_delayed_work(&priv->ra_watchdog, 2 * HZ); + } + diff --git a/package/kernel/mac80211/patches/rtl/001-14-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-add-rem.patch b/package/kernel/mac80211/patches/rtl/001-14-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-add-rem.patch new file mode 100644 index 0000000000..7fcbb02afe --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-14-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-add-rem.patch @@ -0,0 +1,137 @@ +From eef55f1545c92c7181d5083453dee1296298ad3e Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:35 +0100 +Subject: [PATCH 14/21] wifi: rtl8xxxu: support multiple interfaces in + {add,remove}_interface() + +Add a custom struct to store in vif->drv_priv with a reference to +port_num and fill it when a new interface is added. Choose a free +port_num for the newly added interface. + +As we only want to support AP mode/sending beacons on port 0, only change +the beacon settings if a new interface is actually assigned to port 0. + +Call set_linktype() and set_mac() with the appropriate port_num. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-15-martin.kaistra@linutronix.de +--- + .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 4 ++ + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 52 +++++++++++-------- + 2 files changed, 34 insertions(+), 22 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +@@ -1921,6 +1921,10 @@ struct rtl8xxxu_sta_info { + u8 macid; + }; + ++struct rtl8xxxu_vif { ++ int port_num; ++}; ++ + struct rtl8xxxu_rx_urb { + struct urb urb; + struct ieee80211_hw *hw; +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -6610,28 +6610,33 @@ error: + static int rtl8xxxu_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) + { ++ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; +- int ret; ++ int port_num; + u8 val8; + +- if (!priv->vif) { +- priv->vif = vif; +- priv->vifs[0] = vif; +- } else { ++ if (!priv->vifs[0]) ++ port_num = 0; ++ else if (!priv->vifs[1]) ++ port_num = 1; ++ else + return -EOPNOTSUPP; +- } + + switch (vif->type) { + case NL80211_IFTYPE_STATION: +- rtl8xxxu_stop_tx_beacon(priv); ++ if (port_num == 0) { ++ rtl8xxxu_stop_tx_beacon(priv); + +- val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL); +- val8 |= BEACON_ATIM | BEACON_FUNCTION_ENABLE | +- BEACON_DISABLE_TSF_UPDATE; +- rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8); +- ret = 0; ++ val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL); ++ val8 |= BEACON_ATIM | BEACON_FUNCTION_ENABLE | ++ BEACON_DISABLE_TSF_UPDATE; ++ rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8); ++ } + break; + case NL80211_IFTYPE_AP: ++ if (port_num == 1) ++ return -EOPNOTSUPP; ++ + rtl8xxxu_write8(priv, REG_BEACON_CTRL, + BEACON_DISABLE_TSF_UPDATE | BEACON_CTRL_MBSSID); + rtl8xxxu_write8(priv, REG_ATIMWND, 0x0c); /* 12ms */ +@@ -6648,31 +6653,32 @@ static int rtl8xxxu_add_interface(struct + val8 = rtl8xxxu_read8(priv, REG_CCK_CHECK); + val8 &= ~BIT_BCN_PORT_SEL; + rtl8xxxu_write8(priv, REG_CCK_CHECK, val8); +- +- ret = 0; + break; + default: +- ret = -EOPNOTSUPP; ++ return -EOPNOTSUPP; + } + +- rtl8xxxu_set_linktype(priv, vif->type, 0); ++ priv->vifs[port_num] = vif; ++ priv->vif = vif; ++ rtlvif->port_num = port_num; ++ ++ rtl8xxxu_set_linktype(priv, vif->type, port_num); + ether_addr_copy(priv->mac_addr, vif->addr); +- rtl8xxxu_set_mac(priv, 0); ++ rtl8xxxu_set_mac(priv, port_num); + +- return ret; ++ return 0; + } + + static void rtl8xxxu_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) + { ++ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + + dev_dbg(&priv->udev->dev, "%s\n", __func__); + +- if (priv->vif) { +- priv->vif = NULL; +- priv->vifs[0] = NULL; +- } ++ priv->vif = NULL; ++ priv->vifs[rtlvif->port_num] = NULL; + } + + static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed) +@@ -7661,6 +7667,8 @@ static int rtl8xxxu_probe(struct usb_int + if (ret) + goto err_set_intfdata; + ++ hw->vif_data_size = sizeof(struct rtl8xxxu_vif); ++ + hw->wiphy->max_scan_ssids = 1; + hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; + if (priv->fops->max_macid_num) diff --git a/package/kernel/mac80211/patches/rtl/001-15-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-bss_inf.patch b/package/kernel/mac80211/patches/rtl/001-15-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-bss_inf.patch new file mode 100644 index 0000000000..5c5c1948d3 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-15-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-bss_inf.patch @@ -0,0 +1,57 @@ +From 073401c3b6b9eaea027240baf07f2b84dd2d2d26 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:36 +0100 +Subject: [PATCH 15/21] wifi: rtl8xxxu: support multiple interfaces in + bss_info_changed() + +Call set_linktype and set_bssid now with correct port_num. Call +stop_tx_beacon only for port 0, as we don't support beacons on port 1. +Explicit changes to BEACON will only happen for AP type interfaces, so +we don't need an additional check there. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-16-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4983,6 +4983,7 @@ static void + rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, u64 changed) + { ++ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + struct ieee80211_sta *sta; +@@ -4995,7 +4996,7 @@ rtl8xxxu_bss_info_changed(struct ieee802 + if (changed & BSS_CHANGED_ASSOC) { + dev_dbg(dev, "Changed ASSOC: %i!\n", vif->cfg.assoc); + +- rtl8xxxu_set_linktype(priv, vif->type, 0); ++ rtl8xxxu_set_linktype(priv, vif->type, rtlvif->port_num); + + if (vif->cfg.assoc) { + u32 ramask; +@@ -5042,7 +5043,8 @@ rtl8xxxu_bss_info_changed(struct ieee802 + + rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff); + +- rtl8xxxu_stop_tx_beacon(priv); ++ if (rtlvif->port_num == 0) ++ rtl8xxxu_stop_tx_beacon(priv); + + /* joinbss sequence */ + rtl8xxxu_write16(priv, REG_BCN_PSR_RPT, +@@ -5084,7 +5086,7 @@ rtl8xxxu_bss_info_changed(struct ieee802 + + if (changed & BSS_CHANGED_BSSID) { + dev_dbg(dev, "Changed BSSID!\n"); +- rtl8xxxu_set_bssid(priv, bss_conf->bssid, 0); ++ rtl8xxxu_set_bssid(priv, bss_conf->bssid, rtlvif->port_num); + } + + if (changed & BSS_CHANGED_BASIC_RATES) { diff --git a/package/kernel/mac80211/patches/rtl/001-16-v6.9-wifi-rtl8xxxu-support-multiple-interface-in-start_ap.patch b/package/kernel/mac80211/patches/rtl/001-16-v6.9-wifi-rtl8xxxu-support-multiple-interface-in-start_ap.patch new file mode 100644 index 0000000000..25d0238461 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-16-v6.9-wifi-rtl8xxxu-support-multiple-interface-in-start_ap.patch @@ -0,0 +1,32 @@ +From 61fdbd9e2a9d74c716bf4d9684653de5efdee691 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:37 +0100 +Subject: [PATCH 16/21] wifi: rtl8xxxu: support multiple interface in + start_ap() + +Call set_bssid() with the correct port_num now. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-17-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -5111,11 +5111,12 @@ error: + static int rtl8xxxu_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) + { ++ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + + dev_dbg(dev, "Start AP mode\n"); +- rtl8xxxu_set_bssid(priv, vif->bss_conf.bssid, 0); ++ rtl8xxxu_set_bssid(priv, vif->bss_conf.bssid, rtlvif->port_num); + rtl8xxxu_write16(priv, REG_BCN_INTERVAL, vif->bss_conf.beacon_int); + priv->fops->report_connect(priv, RTL8XXXU_BC_MC_MACID, 0, true); + diff --git a/package/kernel/mac80211/patches/rtl/001-17-v6.9-wifi-rtl8xxxu-add-macids-for-STA-mode.patch b/package/kernel/mac80211/patches/rtl/001-17-v6.9-wifi-rtl8xxxu-add-macids-for-STA-mode.patch new file mode 100644 index 0000000000..9f8d0a3aaf --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-17-v6.9-wifi-rtl8xxxu-add-macids-for-STA-mode.patch @@ -0,0 +1,82 @@ +From 5ce0d7e8aee03e73b35f0fe1f1ebbdd4e45776f3 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:38 +0100 +Subject: [PATCH 17/21] wifi: rtl8xxxu: add macids for STA mode + +Until now, the driver only assigned a dedicated macid for connections +made in AP mode, in STA mode the return value of rtl8xxxu_get_macid() +was simply 0. +To differentiate between port 0 and 1, when both are in STA mode, +allocate a second macid (with value 1) and set sta_info->macid according +to the used port_num in rtl8xxxu_sta_add(). + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-18-martin.kaistra@linutronix.de +--- + .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 1 + + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 18 +++++++++++++++++- + 2 files changed, 18 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +@@ -1774,6 +1774,7 @@ struct rtl8xxxu_cfo_tracking { + #define RTL8XXXU_HW_LED_CONTROL 2 + #define RTL8XXXU_MAX_MAC_ID_NUM 128 + #define RTL8XXXU_BC_MC_MACID 0 ++#define RTL8XXXU_BC_MC_MACID1 1 + + struct rtl8xxxu_priv { + struct ieee80211_hw *hw; +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4053,10 +4053,13 @@ static inline u8 rtl8xxxu_get_macid(stru + { + struct rtl8xxxu_sta_info *sta_info; + +- if (!priv->vif || priv->vif->type == NL80211_IFTYPE_STATION || !sta) ++ if (!sta) + return 0; + + sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; ++ if (!sta_info) ++ return 0; ++ + return sta_info->macid; + } + +@@ -4536,6 +4539,7 @@ static int rtl8xxxu_init_device(struct i + rtl8188e_ra_info_init_all(&priv->ra_info); + + set_bit(RTL8XXXU_BC_MC_MACID, priv->mac_id_map); ++ set_bit(RTL8XXXU_BC_MC_MACID1, priv->mac_id_map); + + exit: + return ret; +@@ -7375,6 +7379,7 @@ static int rtl8xxxu_sta_add(struct ieee8 + struct ieee80211_sta *sta) + { + struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; ++ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + + if (vif->type == NL80211_IFTYPE_AP) { +@@ -7384,6 +7389,17 @@ static int rtl8xxxu_sta_add(struct ieee8 + + rtl8xxxu_refresh_rate_mask(priv, 0, sta, true); + priv->fops->report_connect(priv, sta_info->macid, H2C_MACID_ROLE_STA, true); ++ } else { ++ switch (rtlvif->port_num) { ++ case 0: ++ sta_info->macid = RTL8XXXU_BC_MC_MACID; ++ break; ++ case 1: ++ sta_info->macid = RTL8XXXU_BC_MC_MACID1; ++ break; ++ default: ++ break; ++ } + } + + return 0; diff --git a/package/kernel/mac80211/patches/rtl/001-18-v6.9-wifi-rtl8xxxu-remove-obsolete-priv-vif.patch b/package/kernel/mac80211/patches/rtl/001-18-v6.9-wifi-rtl8xxxu-remove-obsolete-priv-vif.patch new file mode 100644 index 0000000000..5cf65eb519 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-18-v6.9-wifi-rtl8xxxu-remove-obsolete-priv-vif.patch @@ -0,0 +1,49 @@ +From f232e9d91bb84817c60c051a3e3b56dd2721a7b3 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:39 +0100 +Subject: [PATCH 18/21] wifi: rtl8xxxu: remove obsolete priv->vif + +Now that all uses of priv->vif have been converted to priv->vifs[] +remove the old attribute. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-19-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 5 ----- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 2 -- + 2 files changed, 7 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +@@ -1893,11 +1893,6 @@ struct rtl8xxxu_priv { + u8 rssi_level; + DECLARE_BITMAP(tx_aggr_started, IEEE80211_NUM_TIDS); + DECLARE_BITMAP(tid_tx_operational, IEEE80211_NUM_TIDS); +- /* +- * Only one virtual interface permitted because only STA mode +- * is supported and no iface_combinations are provided. +- */ +- struct ieee80211_vif *vif; + + struct ieee80211_vif *vifs[2]; + struct delayed_work ra_watchdog; +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -6666,7 +6666,6 @@ static int rtl8xxxu_add_interface(struct + } + + priv->vifs[port_num] = vif; +- priv->vif = vif; + rtlvif->port_num = port_num; + + rtl8xxxu_set_linktype(priv, vif->type, port_num); +@@ -6684,7 +6683,6 @@ static void rtl8xxxu_remove_interface(st + + dev_dbg(&priv->udev->dev, "%s\n", __func__); + +- priv->vif = NULL; + priv->vifs[rtlvif->port_num] = NULL; + } + diff --git a/package/kernel/mac80211/patches/rtl/001-19-v6.9-wifi-rtl8xxxu-add-hw-crypto-support-for-AP-mode.patch b/package/kernel/mac80211/patches/rtl/001-19-v6.9-wifi-rtl8xxxu-add-hw-crypto-support-for-AP-mode.patch new file mode 100644 index 0000000000..b5f9307496 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-19-v6.9-wifi-rtl8xxxu-add-hw-crypto-support-for-AP-mode.patch @@ -0,0 +1,226 @@ +From b837f78fbffa5f8e7e7c59879db54793abf161ec Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:40 +0100 +Subject: [PATCH 19/21] wifi: rtl8xxxu: add hw crypto support for AP mode + +Add a custom function for allocating entries in the sec cam. This allows +us to store multiple keys with the same keyidx. + +The maximum number of sec cam entries for 8188f is 16 according to the +vendor driver. Add the number to rtl8xxxu_fileops, so that other chips +which might support more entries, can set a different number there. + +Set the bssid as mac address for group keys instead of just using the +ethernet broadcast address and use BIT(6) in the sec cam ctrl entry +for differentiating them from pairwise keys like in the vendor driver. + +Add the TXDESC_EN_DESC_ID bit and the hw_key_idx to tx +broadcast/multicast packets in AP mode. + +Finally, allow the usage of rtl8xxxu_set_key() for AP mode. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-20-martin.kaistra@linutronix.de +--- + .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 5 ++ + .../realtek/rtl8xxxu/rtl8xxxu_8188f.c | 1 + + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 48 +++++++++++++++---- + 3 files changed, 44 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +@@ -498,6 +498,7 @@ struct rtl8xxxu_txdesc40 { + #define DESC_RATE_ID_SHIFT 16 + #define DESC_RATE_ID_MASK 0xf + #define TXDESC_NAVUSEHDR BIT(20) ++#define TXDESC_EN_DESC_ID BIT(21) + #define TXDESC_SEC_RC4 0x00400000 + #define TXDESC_SEC_AES 0x00c00000 + #define TXDESC_PKT_OFFSET_SHIFT 26 +@@ -1775,6 +1776,7 @@ struct rtl8xxxu_cfo_tracking { + #define RTL8XXXU_MAX_MAC_ID_NUM 128 + #define RTL8XXXU_BC_MC_MACID 0 + #define RTL8XXXU_BC_MC_MACID1 1 ++#define RTL8XXXU_MAX_SEC_CAM_NUM 64 + + struct rtl8xxxu_priv { + struct ieee80211_hw *hw; +@@ -1908,6 +1910,7 @@ struct rtl8xxxu_priv { + char led_name[32]; + struct led_classdev led_cdev; + DECLARE_BITMAP(mac_id_map, RTL8XXXU_MAX_MAC_ID_NUM); ++ DECLARE_BITMAP(cam_map, RTL8XXXU_MAX_SEC_CAM_NUM); + }; + + struct rtl8xxxu_sta_info { +@@ -1919,6 +1922,7 @@ struct rtl8xxxu_sta_info { + + struct rtl8xxxu_vif { + int port_num; ++ u8 hw_key_idx; + }; + + struct rtl8xxxu_rx_urb { +@@ -1993,6 +1997,7 @@ struct rtl8xxxu_fileops { + u16 max_aggr_num; + u8 supports_ap:1; + u16 max_macid_num; ++ u16 max_sec_cam_num; + u32 adda_1t_init; + u32 adda_1t_path_on; + u32 adda_2t_path_on_a; +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c +@@ -1751,6 +1751,7 @@ struct rtl8xxxu_fileops rtl8188fu_fops = + .max_aggr_num = 0x0c14, + .supports_ap = 1, + .max_macid_num = 16, ++ .max_sec_cam_num = 16, + .adda_1t_init = 0x03c00014, + .adda_1t_path_on = 0x03c00014, + .trxff_boundary = 0x3f7f, +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4559,8 +4559,10 @@ static void rtl8xxxu_cam_write(struct rt + * This is a bit of a hack - the lower bits of the cipher + * suite selector happens to match the cipher index in the CAM + */ +- addr = key->keyidx << CAM_CMD_KEY_SHIFT; ++ addr = key->hw_key_idx << CAM_CMD_KEY_SHIFT; + ctrl = (key->cipher & 0x0f) << 2 | key->keyidx | CAM_WRITE_VALID; ++ if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) ++ ctrl |= BIT(6); + + for (j = 5; j >= 0; j--) { + switch (j) { +@@ -5546,13 +5548,14 @@ static void rtl8xxxu_tx(struct ieee80211 + struct rtl8xxxu_tx_urb *tx_urb; + struct ieee80211_sta *sta = NULL; + struct ieee80211_vif *vif = tx_info->control.vif; ++ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct device *dev = &priv->udev->dev; + u32 queue, rts_rate; + u16 pktlen = skb->len; + int tx_desc_size = priv->fops->tx_desc_size; + u8 macid; + int ret; +- bool ampdu_enable, sgi = false, short_preamble = false; ++ bool ampdu_enable, sgi = false, short_preamble = false, bmc = false; + + if (skb_headroom(skb) < tx_desc_size) { + dev_warn(dev, +@@ -5594,10 +5597,14 @@ static void rtl8xxxu_tx(struct ieee80211 + tx_desc->txdw0 = + TXDESC_OWN | TXDESC_FIRST_SEGMENT | TXDESC_LAST_SEGMENT; + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || +- is_broadcast_ether_addr(ieee80211_get_DA(hdr))) ++ is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { + tx_desc->txdw0 |= TXDESC_BROADMULTICAST; ++ bmc = true; ++ } ++ + + tx_desc->txdw1 = cpu_to_le32(queue << TXDESC_QUEUE_SHIFT); ++ macid = rtl8xxxu_get_macid(priv, sta); + + if (tx_info->control.hw_key) { + switch (tx_info->control.hw_key->cipher) { +@@ -5612,6 +5619,10 @@ static void rtl8xxxu_tx(struct ieee80211 + default: + break; + } ++ if (bmc && rtlvif->hw_key_idx != 0xff) { ++ tx_desc->txdw1 |= TXDESC_EN_DESC_ID; ++ macid = rtlvif->hw_key_idx; ++ } + } + + /* (tx_info->flags & IEEE80211_TX_CTL_AMPDU) && */ +@@ -5655,7 +5666,6 @@ static void rtl8xxxu_tx(struct ieee80211 + else + rts_rate = 0; + +- macid = rtl8xxxu_get_macid(priv, sta); + priv->fops->fill_txdesc(hw, hdr, tx_info, tx_desc, sgi, short_preamble, + ampdu_enable, rts_rate, macid); + +@@ -6667,6 +6677,7 @@ static int rtl8xxxu_add_interface(struct + + priv->vifs[port_num] = vif; + rtlvif->port_num = port_num; ++ rtlvif->hw_key_idx = 0xff; + + rtl8xxxu_set_linktype(priv, vif->type, port_num); + ether_addr_copy(priv->mac_addr, vif->addr); +@@ -6843,11 +6854,19 @@ static int rtl8xxxu_set_rts_threshold(st + return 0; + } + ++static int rtl8xxxu_get_free_sec_cam(struct ieee80211_hw *hw) ++{ ++ struct rtl8xxxu_priv *priv = hw->priv; ++ ++ return find_first_zero_bit(priv->cam_map, priv->fops->max_sec_cam_num); ++} ++ + static int rtl8xxxu_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) + { ++ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; + u8 mac_addr[ETH_ALEN]; +@@ -6859,9 +6878,6 @@ static int rtl8xxxu_set_key(struct ieee8 + dev_dbg(dev, "%s: cmd %02x, cipher %08x, index %i\n", + __func__, cmd, key->cipher, key->keyidx); + +- if (vif->type != NL80211_IFTYPE_STATION) +- return -EOPNOTSUPP; +- + if (key->keyidx > 3) + return -EOPNOTSUPP; + +@@ -6885,7 +6901,7 @@ static int rtl8xxxu_set_key(struct ieee8 + ether_addr_copy(mac_addr, sta->addr); + } else { + dev_dbg(dev, "%s: group key\n", __func__); +- eth_broadcast_addr(mac_addr); ++ ether_addr_copy(mac_addr, vif->bss_conf.bssid); + } + + val16 = rtl8xxxu_read16(priv, REG_CR); +@@ -6899,16 +6915,28 @@ static int rtl8xxxu_set_key(struct ieee8 + + switch (cmd) { + case SET_KEY: +- key->hw_key_idx = key->keyidx; ++ ++ retval = rtl8xxxu_get_free_sec_cam(hw); ++ if (retval < 0) ++ return -EOPNOTSUPP; ++ ++ key->hw_key_idx = retval; ++ ++ if (vif->type == NL80211_IFTYPE_AP && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) ++ rtlvif->hw_key_idx = key->hw_key_idx; ++ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + rtl8xxxu_cam_write(priv, key, mac_addr); ++ set_bit(key->hw_key_idx, priv->cam_map); + retval = 0; + break; + case DISABLE_KEY: + rtl8xxxu_write32(priv, REG_CAM_WRITE, 0x00000000); + val32 = CAM_CMD_POLLING | CAM_CMD_WRITE | +- key->keyidx << CAM_CMD_KEY_SHIFT; ++ key->hw_key_idx << CAM_CMD_KEY_SHIFT; + rtl8xxxu_write32(priv, REG_CAM_CMD, val32); ++ rtlvif->hw_key_idx = 0xff; ++ clear_bit(key->hw_key_idx, priv->cam_map); + retval = 0; + break; + default: diff --git a/package/kernel/mac80211/patches/rtl/001-20-v6.9-wifi-rtl8xxxu-make-supporting-AP-mode-only-on-port-0.patch b/package/kernel/mac80211/patches/rtl/001-20-v6.9-wifi-rtl8xxxu-make-supporting-AP-mode-only-on-port-0.patch new file mode 100644 index 0000000000..4b55b0ede7 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-20-v6.9-wifi-rtl8xxxu-make-supporting-AP-mode-only-on-port-0.patch @@ -0,0 +1,130 @@ +From 69abad618efd17e50bc6f880332ab36b660b0b34 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:41 +0100 +Subject: [PATCH 20/21] wifi: rtl8xxxu: make supporting AP mode only on port 0 + transparent + +When the driver is used for concurrent mode, both virtual interfaces can +be set to station or AP mode, though only one can be in AP mode at the +same time. + +In order to keep the code simple, use only hw port 0 for AP mode. When +an interface is added in AP mode which would be assigned to port 1, use +a switch_port function to transparently swap the mapping between virtual +interface and hw port. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-21-martin.kaistra@linutronix.de +--- + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 91 ++++++++++++++++++- + 1 file changed, 89 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -6624,6 +6624,91 @@ error: + return ret; + } + ++static void rtl8xxxu_switch_ports(struct rtl8xxxu_priv *priv) ++{ ++ u8 macid[ETH_ALEN], bssid[ETH_ALEN], macid_1[ETH_ALEN], bssid_1[ETH_ALEN]; ++ u8 msr, bcn_ctrl, bcn_ctrl_1, atimwnd[2], atimwnd_1[2]; ++ struct rtl8xxxu_vif *rtlvif; ++ struct ieee80211_vif *vif; ++ u8 tsftr[8], tsftr_1[8]; ++ int i; ++ ++ msr = rtl8xxxu_read8(priv, REG_MSR); ++ bcn_ctrl = rtl8xxxu_read8(priv, REG_BEACON_CTRL); ++ bcn_ctrl_1 = rtl8xxxu_read8(priv, REG_BEACON_CTRL_1); ++ ++ for (i = 0; i < ARRAY_SIZE(atimwnd); i++) ++ atimwnd[i] = rtl8xxxu_read8(priv, REG_ATIMWND + i); ++ for (i = 0; i < ARRAY_SIZE(atimwnd_1); i++) ++ atimwnd_1[i] = rtl8xxxu_read8(priv, REG_ATIMWND_1 + i); ++ ++ for (i = 0; i < ARRAY_SIZE(tsftr); i++) ++ tsftr[i] = rtl8xxxu_read8(priv, REG_TSFTR + i); ++ for (i = 0; i < ARRAY_SIZE(tsftr); i++) ++ tsftr_1[i] = rtl8xxxu_read8(priv, REG_TSFTR1 + i); ++ ++ for (i = 0; i < ARRAY_SIZE(macid); i++) ++ macid[i] = rtl8xxxu_read8(priv, REG_MACID + i); ++ ++ for (i = 0; i < ARRAY_SIZE(bssid); i++) ++ bssid[i] = rtl8xxxu_read8(priv, REG_BSSID + i); ++ ++ for (i = 0; i < ARRAY_SIZE(macid_1); i++) ++ macid_1[i] = rtl8xxxu_read8(priv, REG_MACID1 + i); ++ ++ for (i = 0; i < ARRAY_SIZE(bssid_1); i++) ++ bssid_1[i] = rtl8xxxu_read8(priv, REG_BSSID1 + i); ++ ++ /* disable bcn function, disable update TSF */ ++ rtl8xxxu_write8(priv, REG_BEACON_CTRL, (bcn_ctrl & ++ (~BEACON_FUNCTION_ENABLE)) | BEACON_DISABLE_TSF_UPDATE); ++ rtl8xxxu_write8(priv, REG_BEACON_CTRL_1, (bcn_ctrl_1 & ++ (~BEACON_FUNCTION_ENABLE)) | BEACON_DISABLE_TSF_UPDATE); ++ ++ /* switch msr */ ++ msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2); ++ rtl8xxxu_write8(priv, REG_MSR, msr); ++ ++ /* write port0 */ ++ rtl8xxxu_write8(priv, REG_BEACON_CTRL, bcn_ctrl_1 & ~BEACON_FUNCTION_ENABLE); ++ for (i = 0; i < ARRAY_SIZE(atimwnd_1); i++) ++ rtl8xxxu_write8(priv, REG_ATIMWND + i, atimwnd_1[i]); ++ for (i = 0; i < ARRAY_SIZE(tsftr_1); i++) ++ rtl8xxxu_write8(priv, REG_TSFTR + i, tsftr_1[i]); ++ for (i = 0; i < ARRAY_SIZE(macid_1); i++) ++ rtl8xxxu_write8(priv, REG_MACID + i, macid_1[i]); ++ for (i = 0; i < ARRAY_SIZE(bssid_1); i++) ++ rtl8xxxu_write8(priv, REG_BSSID + i, bssid_1[i]); ++ ++ /* write port1 */ ++ rtl8xxxu_write8(priv, REG_BEACON_CTRL_1, bcn_ctrl & ~BEACON_FUNCTION_ENABLE); ++ for (i = 0; i < ARRAY_SIZE(atimwnd); i++) ++ rtl8xxxu_write8(priv, REG_ATIMWND_1 + i, atimwnd[i]); ++ for (i = 0; i < ARRAY_SIZE(tsftr); i++) ++ rtl8xxxu_write8(priv, REG_TSFTR1 + i, tsftr[i]); ++ for (i = 0; i < ARRAY_SIZE(macid); i++) ++ rtl8xxxu_write8(priv, REG_MACID1 + i, macid[i]); ++ for (i = 0; i < ARRAY_SIZE(bssid); i++) ++ rtl8xxxu_write8(priv, REG_BSSID1 + i, bssid[i]); ++ ++ /* write bcn ctl */ ++ rtl8xxxu_write8(priv, REG_BEACON_CTRL, bcn_ctrl_1); ++ rtl8xxxu_write8(priv, REG_BEACON_CTRL_1, bcn_ctrl); ++ ++ vif = priv->vifs[0]; ++ priv->vifs[0] = priv->vifs[1]; ++ priv->vifs[1] = vif; ++ ++ /* priv->vifs[0] is NULL here, based on how this function is currently ++ * called from rtl8xxxu_add_interface(). ++ * When this function will be used in the future for a different ++ * scenario, please check whether vifs[0] or vifs[1] can be NULL and if ++ * necessary add code to set port_num = 1. ++ */ ++ rtlvif = (struct rtl8xxxu_vif *)priv->vifs[1]->drv_priv; ++ rtlvif->port_num = 1; ++} ++ + static int rtl8xxxu_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) + { +@@ -6651,8 +6736,10 @@ static int rtl8xxxu_add_interface(struct + } + break; + case NL80211_IFTYPE_AP: +- if (port_num == 1) +- return -EOPNOTSUPP; ++ if (port_num == 1) { ++ rtl8xxxu_switch_ports(priv); ++ port_num = 0; ++ } + + rtl8xxxu_write8(priv, REG_BEACON_CTRL, + BEACON_DISABLE_TSF_UPDATE | BEACON_CTRL_MBSSID); diff --git a/package/kernel/mac80211/patches/rtl/001-21-v6.9-wifi-rtl8xxxu-declare-concurrent-mode-support-for-81.patch b/package/kernel/mac80211/patches/rtl/001-21-v6.9-wifi-rtl8xxxu-declare-concurrent-mode-support-for-81.patch new file mode 100644 index 0000000000..6322541434 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-21-v6.9-wifi-rtl8xxxu-declare-concurrent-mode-support-for-81.patch @@ -0,0 +1,76 @@ +From 1cd165adf314f6bf25cde58f02f4ff51d01730b0 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Fri, 22 Dec 2023 11:14:42 +0100 +Subject: [PATCH 21/21] wifi: rtl8xxxu: declare concurrent mode support for + 8188f + +Everything is in place now for concurrent mode, we can tell the system +that we support it. +We will allow a maximum of 2 virtual interfaces, one of them can be in +AP mode. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231222101442.626837-22-martin.kaistra@linutronix.de +--- + .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 1 + + .../realtek/rtl8xxxu/rtl8xxxu_8188f.c | 1 + + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 19 +++++++++++++++++++ + 3 files changed, 21 insertions(+) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +@@ -1992,6 +1992,7 @@ struct rtl8xxxu_fileops { + u8 init_reg_rxfltmap:1; + u8 init_reg_pkt_life_time:1; + u8 init_reg_hmtfr:1; ++ u8 supports_concurrent:1; + u8 ampdu_max_time; + u8 ustime_tsf_edca; + u16 max_aggr_num; +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c +@@ -1752,6 +1752,7 @@ struct rtl8xxxu_fileops rtl8188fu_fops = + .supports_ap = 1, + .max_macid_num = 16, + .max_sec_cam_num = 16, ++ .supports_concurrent = 1, + .adda_1t_init = 0x03c00014, + .adda_1t_path_on = 0x03c00014, + .trxff_boundary = 0x3f7f, +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -7665,6 +7665,20 @@ static void rtl8xxxu_deinit_led(struct r + led_classdev_unregister(led); + } + ++struct ieee80211_iface_limit rtl8xxxu_limits[] = { ++ { .max = 2, .types = BIT(NL80211_IFTYPE_STATION), }, ++ { .max = 1, .types = BIT(NL80211_IFTYPE_AP), }, ++}; ++ ++struct ieee80211_iface_combination rtl8xxxu_combinations[] = { ++ { ++ .limits = rtl8xxxu_limits, ++ .n_limits = ARRAY_SIZE(rtl8xxxu_limits), ++ .max_interfaces = 2, ++ .num_different_channels = 1, ++ }, ++}; ++ + static int rtl8xxxu_probe(struct usb_interface *interface, + const struct usb_device_id *id) + { +@@ -7810,6 +7824,11 @@ static int rtl8xxxu_probe(struct usb_int + hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); + hw->queues = 4; + ++ if (priv->fops->supports_concurrent) { ++ hw->wiphy->iface_combinations = rtl8xxxu_combinations; ++ hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtl8xxxu_combinations); ++ } ++ + sband = &rtl8xxxu_supported_band; + sband->ht_cap.ht_supported = true; + sband->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; diff --git a/package/kernel/mac80211/patches/rtl/002-01-v6.9-wifi-rtl8xxxu-Fix-LED-control-code-of-RTL8192FU.patch b/package/kernel/mac80211/patches/rtl/002-01-v6.9-wifi-rtl8xxxu-Fix-LED-control-code-of-RTL8192FU.patch new file mode 100644 index 0000000000..d1a480d53f --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/002-01-v6.9-wifi-rtl8xxxu-Fix-LED-control-code-of-RTL8192FU.patch @@ -0,0 +1,98 @@ +From 9475cc7ac31503521af95e38151e9d856e8ff30b Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Sun, 31 Dec 2023 00:45:54 +0200 +Subject: [PATCH 1/2] wifi: rtl8xxxu: Fix LED control code of RTL8192FU + +Some devices, like the Comfast CF-826F, use LED1, which already works. +Others, like Asus USB-N13 C1, use LED0, which doesn't work correctly. + +Write the right values to the LED control registers to make LED0 work +as well. + +This is unfortunately tested only with the Comfast CF-826F. + +Signed-off-by: Bitterblue Smith +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/7a2c3158-3a45-4466-b11e-fc09802b20e2@gmail.com +--- + .../realtek/rtl8xxxu/rtl8xxxu_8192f.c | 32 +++++++++++++------ + .../wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h | 15 +++++++++ + 2 files changed, 38 insertions(+), 9 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c +@@ -2014,26 +2014,40 @@ static int rtl8192fu_led_brightness_set( + struct rtl8xxxu_priv *priv = container_of(led_cdev, + struct rtl8xxxu_priv, + led_cdev); +- u16 ledcfg; ++ u32 ledcfg; + + /* Values obtained by observing the USB traffic from the Windows driver. */ + rtl8xxxu_write32(priv, REG_SW_GPIO_SHARE_CTRL_0, 0x20080); + rtl8xxxu_write32(priv, REG_SW_GPIO_SHARE_CTRL_1, 0x1b0000); + +- ledcfg = rtl8xxxu_read16(priv, REG_LEDCFG0); ++ ledcfg = rtl8xxxu_read32(priv, REG_LEDCFG0); ++ ++ /* Comfast CF-826F uses LED1. Asus USB-N13 C1 uses LED0. Set both. */ ++ ++ u32p_replace_bits(&ledcfg, LED_GPIO_ENABLE, LEDCFG0_LED2EN); ++ u32p_replace_bits(&ledcfg, LED_IO_MODE_OUTPUT, LEDCFG0_LED0_IO_MODE); ++ u32p_replace_bits(&ledcfg, LED_IO_MODE_OUTPUT, LEDCFG0_LED1_IO_MODE); + + if (brightness == LED_OFF) { +- /* Value obtained like above. */ +- ledcfg = BIT(1) | BIT(7); ++ u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED0CM); ++ u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED0SV); ++ u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED1CM); ++ u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED1SV); + } else if (brightness == LED_ON) { +- /* Value obtained like above. */ +- ledcfg = BIT(1) | BIT(7) | BIT(11); ++ u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED0CM); ++ u32p_replace_bits(&ledcfg, LED_SW_ON, LEDCFG0_LED0SV); ++ u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED1CM); ++ u32p_replace_bits(&ledcfg, LED_SW_ON, LEDCFG0_LED1SV); + } else if (brightness == RTL8XXXU_HW_LED_CONTROL) { +- /* Value obtained by brute force. */ +- ledcfg = BIT(8) | BIT(9); ++ u32p_replace_bits(&ledcfg, LED_MODE_TX_OR_RX_EVENTS, ++ LEDCFG0_LED0CM); ++ u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED0SV); ++ u32p_replace_bits(&ledcfg, LED_MODE_TX_OR_RX_EVENTS, ++ LEDCFG0_LED1CM); ++ u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED1SV); + } + +- rtl8xxxu_write16(priv, REG_LEDCFG0, ledcfg); ++ rtl8xxxu_write32(priv, REG_LEDCFG0, ledcfg); + + return 0; + } +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h +@@ -146,6 +146,21 @@ + #define GPIO_INTM_EDGE_TRIG_IRQ BIT(9) + + #define REG_LEDCFG0 0x004c ++#define LEDCFG0_LED0CM GENMASK(2, 0) ++#define LEDCFG0_LED1CM GENMASK(10, 8) ++#define LED_MODE_SW_CTRL 0x0 ++#define LED_MODE_TX_OR_RX_EVENTS 0x3 ++#define LEDCFG0_LED0SV BIT(3) ++#define LEDCFG0_LED1SV BIT(11) ++#define LED_SW_OFF 0x0 ++#define LED_SW_ON 0x1 ++#define LEDCFG0_LED0_IO_MODE BIT(7) ++#define LEDCFG0_LED1_IO_MODE BIT(15) ++#define LED_IO_MODE_OUTPUT 0x0 ++#define LED_IO_MODE_INPUT 0x1 ++#define LEDCFG0_LED2EN BIT(21) ++#define LED_GPIO_DISABLE 0x0 ++#define LED_GPIO_ENABLE 0x1 + #define LEDCFG0_DPDT_SELECT BIT(23) + #define REG_LEDCFG1 0x004d + #define LEDCFG1_HW_LED_CONTROL BIT(1) diff --git a/package/kernel/mac80211/patches/rtl/002-02-v6.9-wifi-rtl8xxxu-Fix-off-by-one-initial-RTS-rate.patch b/package/kernel/mac80211/patches/rtl/002-02-v6.9-wifi-rtl8xxxu-Fix-off-by-one-initial-RTS-rate.patch new file mode 100644 index 0000000000..7d1c67f2e0 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/002-02-v6.9-wifi-rtl8xxxu-Fix-off-by-one-initial-RTS-rate.patch @@ -0,0 +1,36 @@ +From 80850ca041f2c7ee28fa5e47c5c1b106415f099f Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Tue, 2 Jan 2024 21:33:07 +0200 +Subject: [PATCH 2/2] wifi: rtl8xxxu: Fix off by one initial RTS rate + +rtl8xxxu_set_basic_rates() sets the wrong initial RTS rate. It sets the +next higher rate than the one it should set, e.g. 36M instead of 24M. + +The while loop was supposed to find the index of the most significant +bit which is 1, but it was copied incorrectly from the vendor driver. +Use __fls() instead. + +Signed-off-by: Bitterblue Smith +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/761e6836-6cd6-4930-91b6-0446834655c5@gmail.com +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4870,10 +4870,9 @@ static void rtl8xxxu_set_basic_rates(str + + dev_dbg(&priv->udev->dev, "%s: rates %08x\n", __func__, rate_cfg); + +- while (rate_cfg) { +- rate_cfg = (rate_cfg >> 1); +- rate_idx++; +- } ++ if (rate_cfg) ++ rate_idx = __fls(rate_cfg); ++ + rtl8xxxu_write8(priv, REG_INIRTS_RATE_SEL, rate_idx); + } + diff --git a/package/kernel/mac80211/patches/rtl/003-01-v6.9-wifi-rtl8xxxu-add-cancel_work_sync-for-c2hcmd_work.patch b/package/kernel/mac80211/patches/rtl/003-01-v6.9-wifi-rtl8xxxu-add-cancel_work_sync-for-c2hcmd_work.patch new file mode 100644 index 0000000000..612b5f8738 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/003-01-v6.9-wifi-rtl8xxxu-add-cancel_work_sync-for-c2hcmd_work.patch @@ -0,0 +1,27 @@ +From 1213acb478a7181cd73eeaf00db430f1e45b1361 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Thu, 11 Jan 2024 17:36:27 +0100 +Subject: [PATCH 1/2] wifi: rtl8xxxu: add cancel_work_sync() for c2hcmd_work + +The workqueue might still be running, when the driver is stopped. To +avoid a use-after-free, call cancel_work_sync() in rtl8xxxu_stop(). + +Fixes: e542e66b7c2e ("rtl8xxxu: add bluetooth co-existence support for single antenna") +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240111163628.320697-2-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -7480,6 +7480,7 @@ static void rtl8xxxu_stop(struct ieee802 + if (priv->usb_interrupts) + rtl8xxxu_write32(priv, REG_USB_HIMR, 0); + ++ cancel_work_sync(&priv->c2hcmd_work); + cancel_delayed_work_sync(&priv->ra_watchdog); + + rtl8xxxu_free_rx_resources(priv); diff --git a/package/kernel/mac80211/patches/rtl/003-02-v6.9-wifi-rtl8xxxu-enable-channel-switch-support.patch b/package/kernel/mac80211/patches/rtl/003-02-v6.9-wifi-rtl8xxxu-enable-channel-switch-support.patch new file mode 100644 index 0000000000..6c78d3901b --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/003-02-v6.9-wifi-rtl8xxxu-enable-channel-switch-support.patch @@ -0,0 +1,100 @@ +From ece90a8622320bf5a24d3326da1f8e109891573c Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Thu, 11 Jan 2024 17:36:28 +0100 +Subject: [PATCH 2/2] wifi: rtl8xxxu: enable channel switch support + +The CSA countdown in the beacon frames, which are sent out by firmware, +needs to get updated by the driver. To achieve this, convert +update_beacon_work to delayed_work and schedule it with the beacon +interval in case CSA is active and the countdown is not complete. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240111163628.320697-3-martin.kaistra@linutronix.de +--- + .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 2 +- + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 19 +++++++++++++++---- + 2 files changed, 16 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +@@ -1900,7 +1900,7 @@ struct rtl8xxxu_priv { + struct delayed_work ra_watchdog; + struct work_struct c2hcmd_work; + struct sk_buff_head c2hcmd_queue; +- struct work_struct update_beacon_work; ++ struct delayed_work update_beacon_work; + struct rtl8xxxu_btcoex bt_coex; + struct rtl8xxxu_ra_report ra_report; + struct rtl8xxxu_cfo_tracking cfo_tracking; +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4605,7 +4605,7 @@ static int rtl8xxxu_set_tim(struct ieee8 + { + struct rtl8xxxu_priv *priv = hw->priv; + +- schedule_work(&priv->update_beacon_work); ++ schedule_delayed_work(&priv->update_beacon_work, 0); + + return 0; + } +@@ -5107,7 +5107,7 @@ rtl8xxxu_bss_info_changed(struct ieee802 + } + + if (changed & BSS_CHANGED_BEACON) +- schedule_work(&priv->update_beacon_work); ++ schedule_delayed_work(&priv->update_beacon_work, 0); + + error: + return; +@@ -5726,7 +5726,7 @@ static void rtl8xxxu_send_beacon_frame(s + static void rtl8xxxu_update_beacon_work_callback(struct work_struct *work) + { + struct rtl8xxxu_priv *priv = +- container_of(work, struct rtl8xxxu_priv, update_beacon_work); ++ container_of(work, struct rtl8xxxu_priv, update_beacon_work.work); + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_vif *vif = priv->vifs[0]; + +@@ -5735,6 +5735,14 @@ static void rtl8xxxu_update_beacon_work_ + return; + } + ++ if (vif->bss_conf.csa_active) { ++ if (ieee80211_beacon_cntdwn_is_complete(vif)) { ++ ieee80211_csa_finish(vif); ++ return; ++ } ++ schedule_delayed_work(&priv->update_beacon_work, ++ msecs_to_jiffies(vif->bss_conf.beacon_int)); ++ } + rtl8xxxu_send_beacon_frame(hw, vif); + } + +@@ -7482,6 +7490,7 @@ static void rtl8xxxu_stop(struct ieee802 + + cancel_work_sync(&priv->c2hcmd_work); + cancel_delayed_work_sync(&priv->ra_watchdog); ++ cancel_delayed_work_sync(&priv->update_beacon_work); + + rtl8xxxu_free_rx_resources(priv); + rtl8xxxu_free_tx_resources(priv); +@@ -7763,7 +7772,7 @@ static int rtl8xxxu_probe(struct usb_int + spin_lock_init(&priv->rx_urb_lock); + INIT_WORK(&priv->rx_urb_wq, rtl8xxxu_rx_urb_work); + INIT_DELAYED_WORK(&priv->ra_watchdog, rtl8xxxu_watchdog_callback); +- INIT_WORK(&priv->update_beacon_work, rtl8xxxu_update_beacon_work_callback); ++ INIT_DELAYED_WORK(&priv->update_beacon_work, rtl8xxxu_update_beacon_work_callback); + skb_queue_head_init(&priv->c2hcmd_queue); + + usb_set_intfdata(interface, hw); +@@ -7824,6 +7833,8 @@ static int rtl8xxxu_probe(struct usb_int + hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); + hw->queues = 4; + ++ hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; ++ + if (priv->fops->supports_concurrent) { + hw->wiphy->iface_combinations = rtl8xxxu_combinations; + hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtl8xxxu_combinations); diff --git a/package/kernel/mac80211/patches/rtl/004-01-v6.9-wifi-rtl8xxxu-convert-EN_DESC_ID-of-TX-descriptor-to.patch b/package/kernel/mac80211/patches/rtl/004-01-v6.9-wifi-rtl8xxxu-convert-EN_DESC_ID-of-TX-descriptor-to.patch new file mode 100644 index 0000000000..a88a52231d --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/004-01-v6.9-wifi-rtl8xxxu-convert-EN_DESC_ID-of-TX-descriptor-to.patch @@ -0,0 +1,31 @@ +From 426e7b4773921d07ab4ab8ba16fbad396d6c9971 Mon Sep 17 00:00:00 2001 +From: Ping-Ke Shih +Date: Tue, 16 Jan 2024 16:09:44 +0800 +Subject: [PATCH 1/2] wifi: rtl8xxxu: convert EN_DESC_ID of TX descriptor to + le32 type + +Fields of TX descriptor are little-endian order, so correct EN_DESC_ID +field to le32 type. + +Fixes: b837f78fbffa ("wifi: rtl8xxxu: add hw crypto support for AP mode") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202401161318.YtXoCkjU-lkp@intel.com/ +Cc: Martin Kaistra +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240116080945.20172-1-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -5619,7 +5619,7 @@ static void rtl8xxxu_tx(struct ieee80211 + break; + } + if (bmc && rtlvif->hw_key_idx != 0xff) { +- tx_desc->txdw1 |= TXDESC_EN_DESC_ID; ++ tx_desc->txdw1 |= cpu_to_le32(TXDESC_EN_DESC_ID); + macid = rtlvif->hw_key_idx; + } + } diff --git a/package/kernel/mac80211/patches/rtl/004-02-v6.9-wifi-rtl8xxxu-make-instances-of-iface-limit-and-comb.patch b/package/kernel/mac80211/patches/rtl/004-02-v6.9-wifi-rtl8xxxu-make-instances-of-iface-limit-and-comb.patch new file mode 100644 index 0000000000..68848e28e0 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/004-02-v6.9-wifi-rtl8xxxu-make-instances-of-iface-limit-and-comb.patch @@ -0,0 +1,36 @@ +From 92c7428f942da7dfcdc629b05b5114f80822d7a4 Mon Sep 17 00:00:00 2001 +From: Ping-Ke Shih +Date: Tue, 16 Jan 2024 16:09:45 +0800 +Subject: [PATCH 2/2] wifi: rtl8xxxu: make instances of iface limit and + combination to be static const + +rtl8xxxu_limits and rtl8xxxu_combinations can be static const, so add +modifiers as desire. Otherwise, Sparse reports warnings + +rtl8xxxu_core.c:7677:30: warning: symbol 'rtl8xxxu_limits' was not declared. Should it be static? +rtl8xxxu_core.c:7682:36: warning: symbol 'rtl8xxxu_combinations' was not declared. Should it be static? + +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240116080945.20172-2-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -7674,12 +7674,12 @@ static void rtl8xxxu_deinit_led(struct r + led_classdev_unregister(led); + } + +-struct ieee80211_iface_limit rtl8xxxu_limits[] = { ++static const struct ieee80211_iface_limit rtl8xxxu_limits[] = { + { .max = 2, .types = BIT(NL80211_IFTYPE_STATION), }, + { .max = 1, .types = BIT(NL80211_IFTYPE_AP), }, + }; + +-struct ieee80211_iface_combination rtl8xxxu_combinations[] = { ++static const struct ieee80211_iface_combination rtl8xxxu_combinations[] = { + { + .limits = rtl8xxxu_limits, + .n_limits = ARRAY_SIZE(rtl8xxxu_limits), diff --git a/package/kernel/mac80211/patches/rtl/005-v6.9-wifi-rtl8xxxu-add-missing-number-of-sec-cam-entries-.patch b/package/kernel/mac80211/patches/rtl/005-v6.9-wifi-rtl8xxxu-add-missing-number-of-sec-cam-entries-.patch new file mode 100644 index 0000000000..9fba6befef --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/005-v6.9-wifi-rtl8xxxu-add-missing-number-of-sec-cam-entries-.patch @@ -0,0 +1,100 @@ +From 563d5025cf3b51c7bf20e6966af433ed5f838875 Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Tue, 16 Jan 2024 10:50:01 +0100 +Subject: [PATCH] wifi: rtl8xxxu: add missing number of sec cam entries for all + variants + +Commit b837f78fbffa ("wifi: rtl8xxxu: add hw crypto support for AP +mode") introduced max_sec_cam_num as a member of rtl8xxxu_fileops. +It was missed to set this number for all variants except 8188f, which +caused rtl8xxxu_get_free_sec_cam() to always return 0 and therefore breaking +encrypted traffic. + +Fix it by adding the numbers for all variants. The values are taken from +the vendor drivers and rtlwifi. + +Link: https://lore.kernel.org/linux-wireless/20240111163603.2325-1-zenmchen@gmail.com/ +Fixes: b837f78fbffa ("wifi: rtl8xxxu: add hw crypto support for AP mode") +Signed-off-by: Martin Kaistra +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240116095001.399500-1-martin.kaistra@linutronix.de +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c | 1 + + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c | 1 + + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c | 1 + + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c | 1 + + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8710b.c | 1 + + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c | 1 + + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c | 1 + + 7 files changed, 7 insertions(+) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c +@@ -1882,6 +1882,7 @@ struct rtl8xxxu_fileops rtl8188eu_fops = + .has_tx_report = 1, + .init_reg_pkt_life_time = 1, + .gen2_thermal_meter = 1, ++ .max_sec_cam_num = 32, + .adda_1t_init = 0x0b1b25a0, + .adda_1t_path_on = 0x0bdb25a0, + /* +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c +@@ -613,6 +613,7 @@ struct rtl8xxxu_fileops rtl8192cu_fops = + .rx_agg_buf_size = 16000, + .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32), + .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16), ++ .max_sec_cam_num = 32, + .adda_1t_init = 0x0b1b25a0, + .adda_1t_path_on = 0x0bdb25a0, + .adda_2t_path_on_a = 0x04db25a4, +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c +@@ -1769,6 +1769,7 @@ struct rtl8xxxu_fileops rtl8192eu_fops = + .needs_full_init = 1, + .supports_ap = 1, + .max_macid_num = 128, ++ .max_sec_cam_num = 64, + .adda_1t_init = 0x0fc01616, + .adda_1t_path_on = 0x0fc01616, + .adda_2t_path_on_a = 0x0fc01616, +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c +@@ -2095,6 +2095,7 @@ struct rtl8xxxu_fileops rtl8192fu_fops = + .max_aggr_num = 0x1f1f, + .supports_ap = 1, + .max_macid_num = 128, ++ .max_sec_cam_num = 64, + .trxff_boundary = 0x3f3f, + .pbp_rx = PBP_PAGE_SIZE_256, + .pbp_tx = PBP_PAGE_SIZE_256, +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8710b.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8710b.c +@@ -1877,6 +1877,7 @@ struct rtl8xxxu_fileops rtl8710bu_fops = + .max_aggr_num = 0x0c14, + .supports_ap = 1, + .max_macid_num = 16, ++ .max_sec_cam_num = 32, + .adda_1t_init = 0x03c00016, + .adda_1t_path_on = 0x03c00016, + .trxff_boundary = 0x3f7f, +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c +@@ -510,6 +510,7 @@ struct rtl8xxxu_fileops rtl8723au_fops = + .rx_agg_buf_size = 16000, + .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32), + .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16), ++ .max_sec_cam_num = 32, + .adda_1t_init = 0x0b1b25a0, + .adda_1t_path_on = 0x0bdb25a0, + .adda_2t_path_on_a = 0x04db25a4, +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c +@@ -1744,6 +1744,7 @@ struct rtl8xxxu_fileops rtl8723bu_fops = + .max_aggr_num = 0x0c14, + .supports_ap = 1, + .max_macid_num = 128, ++ .max_sec_cam_num = 64, + .adda_1t_init = 0x01c00014, + .adda_1t_path_on = 0x01c00014, + .adda_2t_path_on_a = 0x01c00014, diff --git a/package/kernel/mac80211/patches/rtl/006-v6.9-wifi-rtl8xxxu-fix-error-messages.patch b/package/kernel/mac80211/patches/rtl/006-v6.9-wifi-rtl8xxxu-fix-error-messages.patch new file mode 100644 index 0000000000..961f613161 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/006-v6.9-wifi-rtl8xxxu-fix-error-messages.patch @@ -0,0 +1,37 @@ +From 17903a283593c1dbf9da041f836004163ca30f7b Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 31 Jan 2024 10:10:07 +0300 +Subject: [PATCH] wifi: rtl8xxxu: fix error messages + +The first parameter of WARN_ONCE() is a condition so this code will end +up printing the function name instead of the proper message. + +Fixes: 3ff7a05996f9 ("wifi: rtl8xxxu: support setting bssid register for multiple interfaces") +Signed-off-by: Dan Carpenter +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/7b144531-a8da-4725-8911-9b614a525a35@moroto.mountain +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -3593,7 +3593,7 @@ static int rtl8xxxu_set_mac(struct rtl8x + reg = REG_MACID1; + break; + default: +- WARN_ONCE("%s: invalid port_num\n", __func__); ++ WARN_ONCE(1, "%s: invalid port_num\n", __func__); + return -EINVAL; + } + +@@ -3618,7 +3618,7 @@ static int rtl8xxxu_set_bssid(struct rtl + reg = REG_BSSID1; + break; + default: +- WARN_ONCE("%s: invalid port_num\n", __func__); ++ WARN_ONCE(1, "%s: invalid port_num\n", __func__); + return -EINVAL; + } + diff --git a/package/kernel/mac80211/patches/rtl/007-v6.9-wifi-rtl8xxxu-Add-TP-Link-TL-WN823N-V2.patch b/package/kernel/mac80211/patches/rtl/007-v6.9-wifi-rtl8xxxu-Add-TP-Link-TL-WN823N-V2.patch new file mode 100644 index 0000000000..7ccc08c28d --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/007-v6.9-wifi-rtl8xxxu-Add-TP-Link-TL-WN823N-V2.patch @@ -0,0 +1,36 @@ +From 1209f487d452ff7e822dec30661fd6b5163fb8cf Mon Sep 17 00:00:00 2001 +From: Chun Qiu +Date: Mon, 29 Jan 2024 13:30:30 +0800 +Subject: [PATCH] wifi: rtl8xxxu: Add TP-Link TL-WN823N V2 + +TP-Link TL-WN823N V2 (2357:0135) is based on rtl8192fu and has been +tested to work with the rtl8xxxu driver. + +Signed-off-by: Chun Qiu +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240129053030.16369-1-cqca@cock.lu +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -7733,7 +7733,7 @@ static int rtl8xxxu_probe(struct usb_int + untested = 0; + break; + case 0x2357: +- if (id->idProduct == 0x0109) ++ if (id->idProduct == 0x0109 || id->idProduct == 0x0135) + untested = 0; + break; + case 0x0b05: +@@ -8025,6 +8025,9 @@ static const struct usb_device_id dev_ta + .driver_info = (unsigned long)&rtl8192fu_fops}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x318b, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192fu_fops}, ++/* TP-Link TL-WN823N V2 */ ++{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0135, 0xff, 0xff, 0xff), ++ .driver_info = (unsigned long)&rtl8192fu_fops}, + #ifdef CPTCFG_RTL8XXXU_UNTESTED + /* Still supported by rtlwifi */ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8176, 0xff, 0xff, 0xff), diff --git a/package/kernel/mac80211/patches/rtl/008-v6.9-wifi-rtl8xxxu-update-rate-mask-per-sta.patch b/package/kernel/mac80211/patches/rtl/008-v6.9-wifi-rtl8xxxu-update-rate-mask-per-sta.patch new file mode 100644 index 0000000000..66cd70c6b1 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/008-v6.9-wifi-rtl8xxxu-update-rate-mask-per-sta.patch @@ -0,0 +1,411 @@ +From 94dd7ce1885e530a7b10bbe50d5d68ba1bb99e6e Mon Sep 17 00:00:00 2001 +From: Martin Kaistra +Date: Mon, 5 Feb 2024 10:30:40 +0100 +Subject: [PATCH] wifi: rtl8xxxu: update rate mask per sta + +Until now, rtl8xxxu_watchdog_callback() only fetches RSSI and updates +the rate mask in station mode. This means, in AP mode only the default +rate mask is used. + +In order to have the rate mask reflect the actual connection quality, +extend rtl8xxxu_watchdog_callback() to iterate over every sta. Like in +the rtw88 driver, add a function to collect all currently present stas +and then iterate over a list of copies to ensure no RCU lock problems +for register access via USB. Remove the existing RCU lock in +rtl8xxxu_refresh_rate_mask(). + +Since the currently used ieee80211_ave_rssi() is only for 'vif', add +driver-level tracking of RSSI per sta. + +Signed-off-by: Martin Kaistra +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240205093040.1941140-1-martin.kaistra@linutronix.de +--- + .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 8 +- + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 188 ++++++++++++++---- + 2 files changed, 158 insertions(+), 38 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +@@ -6,6 +6,7 @@ + */ + + #include ++#include + + #define RTL8XXXU_DEBUG_REG_WRITE 0x01 + #define RTL8XXXU_DEBUG_REG_READ 0x02 +@@ -1858,6 +1859,8 @@ struct rtl8xxxu_priv { + int next_mbox; + int nr_out_eps; + ++ /* Ensure no added or deleted stas while iterating */ ++ struct mutex sta_mutex; + struct mutex h2c_mutex; + /* Protect the indirect register accesses of RTL8710BU. */ + struct mutex syson_indirect_access_mutex; +@@ -1892,7 +1895,6 @@ struct rtl8xxxu_priv { + u8 pi_enabled:1; + u8 no_pape:1; + u8 int_buf[USB_INTR_CONTENT_LENGTH]; +- u8 rssi_level; + DECLARE_BITMAP(tx_aggr_started, IEEE80211_NUM_TIDS); + DECLARE_BITMAP(tid_tx_operational, IEEE80211_NUM_TIDS); + +@@ -1913,11 +1915,15 @@ struct rtl8xxxu_priv { + DECLARE_BITMAP(cam_map, RTL8XXXU_MAX_SEC_CAM_NUM); + }; + ++DECLARE_EWMA(rssi, 10, 16); ++ + struct rtl8xxxu_sta_info { + struct ieee80211_sta *sta; + struct ieee80211_vif *vif; + + u8 macid; ++ struct ewma_rssi avg_rssi; ++ u8 rssi_level; + }; + + struct rtl8xxxu_vif { +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4991,10 +4991,11 @@ rtl8xxxu_bss_info_changed(struct ieee802 + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + struct device *dev = &priv->udev->dev; ++ struct rtl8xxxu_sta_info *sta_info; + struct ieee80211_sta *sta; + struct rtl8xxxu_ra_report *rarpt; ++ u8 val8, macid; + u32 val32; +- u8 val8; + + rarpt = &priv->ra_report; + +@@ -5017,6 +5018,7 @@ rtl8xxxu_bss_info_changed(struct ieee802 + rcu_read_unlock(); + goto error; + } ++ macid = rtl8xxxu_get_macid(priv, sta); + + if (sta->deflink.ht_cap.ht_supported) + dev_info(dev, "%s: HT supported\n", __func__); +@@ -5037,14 +5039,15 @@ rtl8xxxu_bss_info_changed(struct ieee802 + bw = RATE_INFO_BW_40; + else + bw = RATE_INFO_BW_20; ++ ++ sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; ++ sta_info->rssi_level = RTL8XXXU_RATR_STA_INIT; + rcu_read_unlock(); + + rtl8xxxu_update_ra_report(rarpt, highest_rate, sgi, bw); + +- priv->rssi_level = RTL8XXXU_RATR_STA_INIT; +- + priv->fops->update_rate_mask(priv, ramask, 0, sgi, +- bw == RATE_INFO_BW_40, 0); ++ bw == RATE_INFO_BW_40, macid); + + rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff); + +@@ -6317,6 +6320,76 @@ static void rtl8188e_c2hcmd_callback(str + } + } + ++#define rtl8xxxu_iterate_vifs_atomic(priv, iterator, data) \ ++ ieee80211_iterate_active_interfaces_atomic((priv)->hw, \ ++ IEEE80211_IFACE_ITER_NORMAL, iterator, data) ++ ++struct rtl8xxxu_rx_update_rssi_data { ++ struct rtl8xxxu_priv *priv; ++ struct ieee80211_hdr *hdr; ++ struct ieee80211_rx_status *rx_status; ++ u8 *bssid; ++}; ++ ++static void rtl8xxxu_rx_update_rssi_iter(void *data, u8 *mac, ++ struct ieee80211_vif *vif) ++{ ++ struct rtl8xxxu_rx_update_rssi_data *iter_data = data; ++ struct ieee80211_sta *sta; ++ struct ieee80211_hdr *hdr = iter_data->hdr; ++ struct rtl8xxxu_priv *priv = iter_data->priv; ++ struct rtl8xxxu_sta_info *sta_info; ++ struct ieee80211_rx_status *rx_status = iter_data->rx_status; ++ u8 *bssid = iter_data->bssid; ++ ++ if (!ether_addr_equal(vif->bss_conf.bssid, bssid)) ++ return; ++ ++ if (!(ether_addr_equal(vif->addr, hdr->addr1) || ++ ieee80211_is_beacon(hdr->frame_control))) ++ return; ++ ++ sta = ieee80211_find_sta_by_ifaddr(priv->hw, hdr->addr2, ++ vif->addr); ++ if (!sta) ++ return; ++ ++ sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; ++ ewma_rssi_add(&sta_info->avg_rssi, -rx_status->signal); ++} ++ ++static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) ++{ ++ __le16 fc = hdr->frame_control; ++ u8 *bssid; ++ ++ if (ieee80211_has_tods(fc)) ++ bssid = hdr->addr1; ++ else if (ieee80211_has_fromds(fc)) ++ bssid = hdr->addr2; ++ else ++ bssid = hdr->addr3; ++ ++ return bssid; ++} ++ ++static void rtl8xxxu_rx_update_rssi(struct rtl8xxxu_priv *priv, ++ struct ieee80211_rx_status *rx_status, ++ struct ieee80211_hdr *hdr) ++{ ++ struct rtl8xxxu_rx_update_rssi_data data = {}; ++ ++ if (ieee80211_is_ctl(hdr->frame_control)) ++ return; ++ ++ data.priv = priv; ++ data.hdr = hdr; ++ data.rx_status = rx_status; ++ data.bssid = get_hdr_bssid(hdr); ++ ++ rtl8xxxu_iterate_vifs_atomic(priv, rtl8xxxu_rx_update_rssi_iter, &data); ++} ++ + int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb) + { + struct ieee80211_hw *hw = priv->hw; +@@ -6376,18 +6449,26 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8x + skb_queue_tail(&priv->c2hcmd_queue, skb); + schedule_work(&priv->c2hcmd_work); + } else { ++ struct ieee80211_hdr *hdr; ++ + phy_stats = (struct rtl8723au_phy_stats *)skb->data; + + skb_pull(skb, drvinfo_sz + desc_shift); + + skb_trim(skb, pkt_len); + +- if (rx_desc->phy_stats) ++ hdr = (struct ieee80211_hdr *)skb->data; ++ if (rx_desc->phy_stats) { + priv->fops->parse_phystats( + priv, rx_status, phy_stats, + rx_desc->rxmcs, +- (struct ieee80211_hdr *)skb->data, ++ hdr, + rx_desc->crc32 || rx_desc->icverr); ++ if (!rx_desc->crc32 && !rx_desc->icverr) ++ rtl8xxxu_rx_update_rssi(priv, ++ rx_status, ++ hdr); ++ } + + rx_status->mactime = rx_desc->tsfl; + rx_status->flag |= RX_FLAG_MACTIME_START; +@@ -6484,10 +6565,15 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8x + } else { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + +- if (rx_desc->phy_stats) ++ if (rx_desc->phy_stats) { + priv->fops->parse_phystats(priv, rx_status, phy_stats, + rx_desc->rxmcs, hdr, + rx_desc->crc32 || rx_desc->icverr); ++ if (!rx_desc->crc32 && !rx_desc->icverr) ++ rtl8xxxu_rx_update_rssi(priv, ++ rx_status, ++ hdr); ++ } + + rx_status->mactime = rx_desc->tsfl; + rx_status->flag |= RX_FLAG_MACTIME_START; +@@ -7111,6 +7197,7 @@ static void rtl8xxxu_refresh_rate_mask(s + int signal, struct ieee80211_sta *sta, + bool force) + { ++ struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; + struct ieee80211_hw *hw = priv->hw; + u16 wireless_mode; + u8 rssi_level, ratr_idx; +@@ -7119,7 +7206,7 @@ static void rtl8xxxu_refresh_rate_mask(s + u8 go_up_gap = 5; + u8 macid = rtl8xxxu_get_macid(priv, sta); + +- rssi_level = priv->rssi_level; ++ rssi_level = sta_info->rssi_level; + snr = rtl8xxxu_signal_to_snr(signal); + snr_thresh_high = RTL8XXXU_SNR_THRESH_HIGH; + snr_thresh_low = RTL8XXXU_SNR_THRESH_LOW; +@@ -7144,18 +7231,16 @@ static void rtl8xxxu_refresh_rate_mask(s + else + rssi_level = RTL8XXXU_RATR_STA_LOW; + +- if (rssi_level != priv->rssi_level || force) { ++ if (rssi_level != sta_info->rssi_level || force) { + int sgi = 0; + u32 rate_bitmap = 0; + +- rcu_read_lock(); + rate_bitmap = (sta->deflink.supp_rates[0] & 0xfff) | + (sta->deflink.ht_cap.mcs.rx_mask[0] << 12) | + (sta->deflink.ht_cap.mcs.rx_mask[1] << 20); + if (sta->deflink.ht_cap.cap & + (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20)) + sgi = 1; +- rcu_read_unlock(); + + wireless_mode = rtl8xxxu_wireless_mode(hw, sta); + switch (wireless_mode) { +@@ -7236,7 +7321,7 @@ static void rtl8xxxu_refresh_rate_mask(s + break; + } + +- priv->rssi_level = rssi_level; ++ sta_info->rssi_level = rssi_level; + priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi, txbw_40mhz, macid); + } + } +@@ -7329,40 +7414,60 @@ static void rtl8xxxu_track_cfo(struct rt + rtl8xxxu_set_atc_status(priv, abs(cfo_average) >= CFO_TH_ATC); + } + +-static void rtl8xxxu_watchdog_callback(struct work_struct *work) ++static void rtl8xxxu_ra_iter(void *data, struct ieee80211_sta *sta) + { +- struct ieee80211_vif *vif; +- struct rtl8xxxu_priv *priv; +- int i; ++ struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; ++ struct rtl8xxxu_priv *priv = data; ++ int signal = -ewma_rssi_read(&sta_info->avg_rssi); + +- priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work); +- for (i = 0; i < ARRAY_SIZE(priv->vifs); i++) { +- vif = priv->vifs[i]; ++ priv->fops->report_rssi(priv, rtl8xxxu_get_macid(priv, sta), ++ rtl8xxxu_signal_to_snr(signal)); ++ rtl8xxxu_refresh_rate_mask(priv, signal, sta, false); ++} ++ ++struct rtl8xxxu_stas_entry { ++ struct list_head list; ++ struct ieee80211_sta *sta; ++}; + +- if (!vif || vif->type != NL80211_IFTYPE_STATION) +- continue; ++struct rtl8xxxu_iter_stas_data { ++ struct rtl8xxxu_priv *priv; ++ struct list_head list; ++}; + +- int signal; +- struct ieee80211_sta *sta; ++static void rtl8xxxu_collect_sta_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtl8xxxu_iter_stas_data *iter_stas = data; ++ struct rtl8xxxu_stas_entry *stas_entry; + +- rcu_read_lock(); +- sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); +- if (!sta) { +- struct device *dev = &priv->udev->dev; ++ stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC); ++ if (!stas_entry) ++ return; + +- dev_dbg(dev, "%s: no sta found\n", __func__); +- rcu_read_unlock(); +- continue; +- } +- rcu_read_unlock(); ++ stas_entry->sta = sta; ++ list_add_tail(&stas_entry->list, &iter_stas->list); ++} + +- signal = ieee80211_ave_rssi(vif); ++static void rtl8xxxu_watchdog_callback(struct work_struct *work) ++{ + +- priv->fops->report_rssi(priv, rtl8xxxu_get_macid(priv, sta), +- rtl8xxxu_signal_to_snr(signal)); ++ struct rtl8xxxu_iter_stas_data iter_data; ++ struct rtl8xxxu_stas_entry *sta_entry, *tmp; ++ struct rtl8xxxu_priv *priv; + +- rtl8xxxu_refresh_rate_mask(priv, signal, sta, false); ++ priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work); ++ iter_data.priv = priv; ++ INIT_LIST_HEAD(&iter_data.list); ++ ++ mutex_lock(&priv->sta_mutex); ++ ieee80211_iterate_stations_atomic(priv->hw, rtl8xxxu_collect_sta_iter, ++ &iter_data); ++ list_for_each_entry_safe(sta_entry, tmp, &iter_data.list, list) { ++ list_del_init(&sta_entry->list); ++ rtl8xxxu_ra_iter(priv, sta_entry->sta); ++ kfree(sta_entry); + } ++ mutex_unlock(&priv->sta_mutex); + + if (priv->fops->set_crystal_cap) + rtl8xxxu_track_cfo(priv); +@@ -7504,10 +7609,15 @@ static int rtl8xxxu_sta_add(struct ieee8 + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + ++ mutex_lock(&priv->sta_mutex); ++ ewma_rssi_init(&sta_info->avg_rssi); + if (vif->type == NL80211_IFTYPE_AP) { ++ sta_info->rssi_level = RTL8XXXU_RATR_STA_INIT; + sta_info->macid = rtl8xxxu_acquire_macid(priv); +- if (sta_info->macid >= RTL8XXXU_MAX_MAC_ID_NUM) ++ if (sta_info->macid >= RTL8XXXU_MAX_MAC_ID_NUM) { ++ mutex_unlock(&priv->sta_mutex); + return -ENOSPC; ++ } + + rtl8xxxu_refresh_rate_mask(priv, 0, sta, true); + priv->fops->report_connect(priv, sta_info->macid, H2C_MACID_ROLE_STA, true); +@@ -7523,6 +7633,7 @@ static int rtl8xxxu_sta_add(struct ieee8 + break; + } + } ++ mutex_unlock(&priv->sta_mutex); + + return 0; + } +@@ -7534,8 +7645,10 @@ static int rtl8xxxu_sta_remove(struct ie + struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv; + struct rtl8xxxu_priv *priv = hw->priv; + ++ mutex_lock(&priv->sta_mutex); + if (vif->type == NL80211_IFTYPE_AP) + rtl8xxxu_release_macid(priv, sta_info->macid); ++ mutex_unlock(&priv->sta_mutex); + + return 0; + } +@@ -7766,6 +7879,7 @@ static int rtl8xxxu_probe(struct usb_int + mutex_init(&priv->usb_buf_mutex); + mutex_init(&priv->syson_indirect_access_mutex); + mutex_init(&priv->h2c_mutex); ++ mutex_init(&priv->sta_mutex); + INIT_LIST_HEAD(&priv->tx_urb_free_list); + spin_lock_init(&priv->tx_urb_lock); + INIT_LIST_HEAD(&priv->rx_urb_pending_list); diff --git a/package/kernel/mac80211/patches/rtl/009-v6.9-wifi-rtl8xxxu-check-vif-before-using-in-rtl8xxxu_tx.patch b/package/kernel/mac80211/patches/rtl/009-v6.9-wifi-rtl8xxxu-check-vif-before-using-in-rtl8xxxu_tx.patch new file mode 100644 index 0000000000..600f7c37df --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/009-v6.9-wifi-rtl8xxxu-check-vif-before-using-in-rtl8xxxu_tx.patch @@ -0,0 +1,40 @@ +From 513c559ca9f05394da79fbf20a8f89eec5f53dce Mon Sep 17 00:00:00 2001 +From: Ping-Ke Shih +Date: Fri, 16 Feb 2024 11:39:23 +0800 +Subject: [PATCH] wifi: rtl8xxxu: check vif before using in rtl8xxxu_tx() + +The 'vif' is from tx_info of SKB, and other codes check 'vif' before using, +which raises smatch warnings: + +drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c:5656 rtl8xxxu_tx() + warn: variable dereferenced before check 'vif' (see line 5553) + +Compile tested only. + +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240216033923.34683-1-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -5550,7 +5550,7 @@ static void rtl8xxxu_tx(struct ieee80211 + struct rtl8xxxu_tx_urb *tx_urb; + struct ieee80211_sta *sta = NULL; + struct ieee80211_vif *vif = tx_info->control.vif; +- struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv; ++ struct rtl8xxxu_vif *rtlvif = vif ? (struct rtl8xxxu_vif *)vif->drv_priv : NULL; + struct device *dev = &priv->udev->dev; + u32 queue, rts_rate; + u16 pktlen = skb->len; +@@ -5621,7 +5621,7 @@ static void rtl8xxxu_tx(struct ieee80211 + default: + break; + } +- if (bmc && rtlvif->hw_key_idx != 0xff) { ++ if (bmc && rtlvif && rtlvif->hw_key_idx != 0xff) { + tx_desc->txdw1 |= cpu_to_le32(TXDESC_EN_DESC_ID); + macid = rtlvif->hw_key_idx; + } diff --git a/package/kernel/mac80211/patches/rtl/010-v6.9-wifi-rtl8xxxu-fix-mixed-declarations-and-code-warnin.patch b/package/kernel/mac80211/patches/rtl/010-v6.9-wifi-rtl8xxxu-fix-mixed-declarations-and-code-warnin.patch new file mode 100644 index 0000000000..e1de784b09 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/010-v6.9-wifi-rtl8xxxu-fix-mixed-declarations-and-code-warnin.patch @@ -0,0 +1,34 @@ +From a7e178259c5bc900da762b33d3a20b7ee1206f07 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Fri, 23 Feb 2024 21:34:32 +0800 +Subject: [PATCH] wifi: rtl8xxxu: fix mixed declarations in rtl8xxxu_set_aifs() + +Moving struct ieee80211_sta *sta variable definition to the front +of the code to fix the ISO C90 forbids mixed declarations and code +warning. + +Fixes: 43532c050f8e ("wifi: rtl8xxxu: support multiple interfaces in set_aifs()") +Signed-off-by: Shiji Yang +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/TYAP286MB03157A408E0D69F2F6FBD88ABC552@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4919,11 +4919,11 @@ static void rtl8xxxu_set_aifs(struct rtl + int i; + + for (i = 0; i < ARRAY_SIZE(priv->vifs); i++) { ++ struct ieee80211_sta *sta; ++ + if (!priv->vifs[i]) + continue; + +- struct ieee80211_sta *sta; +- + rcu_read_lock(); + sta = ieee80211_find_sta(priv->vifs[i], priv->vifs[i]->bss_conf.bssid); + if (sta)