1 From eef55f1545c92c7181d5083453dee1296298ad3e Mon Sep 17 00:00:00 2001
2 From: Martin Kaistra <martin.kaistra@linutronix.de>
3 Date: Fri, 22 Dec 2023 11:14:35 +0100
4 Subject: [PATCH 14/21] wifi: rtl8xxxu: support multiple interfaces in
5 {add,remove}_interface()
7 Add a custom struct to store in vif->drv_priv with a reference to
8 port_num and fill it when a new interface is added. Choose a free
9 port_num for the newly added interface.
11 As we only want to support AP mode/sending beacons on port 0, only change
12 the beacon settings if a new interface is actually assigned to port 0.
14 Call set_linktype() and set_mac() with the appropriate port_num.
16 Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
17 Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
18 Signed-off-by: Kalle Valo <kvalo@kernel.org>
19 Link: https://msgid.link/20231222101442.626837-15-martin.kaistra@linutronix.de
21 .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 4 ++
22 .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 52 +++++++++++--------
23 2 files changed, 34 insertions(+), 22 deletions(-)
25 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
26 +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
27 @@ -1921,6 +1921,10 @@ struct rtl8xxxu_sta_info {
31 +struct rtl8xxxu_vif {
35 struct rtl8xxxu_rx_urb {
37 struct ieee80211_hw *hw;
38 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
39 +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
40 @@ -6610,28 +6610,33 @@ error:
41 static int rtl8xxxu_add_interface(struct ieee80211_hw *hw,
42 struct ieee80211_vif *vif)
44 + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
45 struct rtl8xxxu_priv *priv = hw->priv;
52 - priv->vifs[0] = vif;
56 + else if (!priv->vifs[1])
63 case NL80211_IFTYPE_STATION:
64 - rtl8xxxu_stop_tx_beacon(priv);
65 + if (port_num == 0) {
66 + rtl8xxxu_stop_tx_beacon(priv);
68 - val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
69 - val8 |= BEACON_ATIM | BEACON_FUNCTION_ENABLE |
70 - BEACON_DISABLE_TSF_UPDATE;
71 - rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
73 + val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
74 + val8 |= BEACON_ATIM | BEACON_FUNCTION_ENABLE |
75 + BEACON_DISABLE_TSF_UPDATE;
76 + rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
79 case NL80211_IFTYPE_AP:
83 rtl8xxxu_write8(priv, REG_BEACON_CTRL,
84 BEACON_DISABLE_TSF_UPDATE | BEACON_CTRL_MBSSID);
85 rtl8xxxu_write8(priv, REG_ATIMWND, 0x0c); /* 12ms */
86 @@ -6648,31 +6653,32 @@ static int rtl8xxxu_add_interface(struct
87 val8 = rtl8xxxu_read8(priv, REG_CCK_CHECK);
88 val8 &= ~BIT_BCN_PORT_SEL;
89 rtl8xxxu_write8(priv, REG_CCK_CHECK, val8);
98 - rtl8xxxu_set_linktype(priv, vif->type, 0);
99 + priv->vifs[port_num] = vif;
101 + rtlvif->port_num = port_num;
103 + rtl8xxxu_set_linktype(priv, vif->type, port_num);
104 ether_addr_copy(priv->mac_addr, vif->addr);
105 - rtl8xxxu_set_mac(priv, 0);
106 + rtl8xxxu_set_mac(priv, port_num);
112 static void rtl8xxxu_remove_interface(struct ieee80211_hw *hw,
113 struct ieee80211_vif *vif)
115 + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
116 struct rtl8xxxu_priv *priv = hw->priv;
118 dev_dbg(&priv->udev->dev, "%s\n", __func__);
122 - priv->vifs[0] = NULL;
125 + priv->vifs[rtlvif->port_num] = NULL;
128 static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
129 @@ -7661,6 +7667,8 @@ static int rtl8xxxu_probe(struct usb_int
131 goto err_set_intfdata;
133 + hw->vif_data_size = sizeof(struct rtl8xxxu_vif);
135 hw->wiphy->max_scan_ssids = 1;
136 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
137 if (priv->fops->max_macid_num)