mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-30 10:39:04 +00:00
97f542238a
Backporting upstream patches to improve RTL8188F support. Signed-off-by: Shiji Yang <yangshiji66@qq.com>
131 lines
4.7 KiB
Diff
131 lines
4.7 KiB
Diff
From 69abad618efd17e50bc6f880332ab36b660b0b34 Mon Sep 17 00:00:00 2001
|
|
From: Martin Kaistra <martin.kaistra@linutronix.de>
|
|
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 <martin.kaistra@linutronix.de>
|
|
Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
|
|
Signed-off-by: Kalle Valo <kvalo@kernel.org>
|
|
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);
|