mac80211: rtl8xxxu: sync with linux-next 20240229
[openwrt/staging/nbd.git] / package / kernel / mac80211 / patches / rtl / 001-14-v6.9-wifi-rtl8xxxu-support-multiple-interfaces-in-add-rem.patch
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()
6
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.
10
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.
13
14 Call set_linktype() and set_mac() with the appropriate port_num.
15
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
20 ---
21 .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 4 ++
22 .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 52 +++++++++++--------
23 2 files changed, 34 insertions(+), 22 deletions(-)
24
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 {
28 u8 macid;
29 };
30
31 +struct rtl8xxxu_vif {
32 + int port_num;
33 +};
34 +
35 struct rtl8xxxu_rx_urb {
36 struct urb 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)
43 {
44 + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
45 struct rtl8xxxu_priv *priv = hw->priv;
46 - int ret;
47 + int port_num;
48 u8 val8;
49
50 - if (!priv->vif) {
51 - priv->vif = vif;
52 - priv->vifs[0] = vif;
53 - } else {
54 + if (!priv->vifs[0])
55 + port_num = 0;
56 + else if (!priv->vifs[1])
57 + port_num = 1;
58 + else
59 return -EOPNOTSUPP;
60 - }
61
62 switch (vif->type) {
63 case NL80211_IFTYPE_STATION:
64 - rtl8xxxu_stop_tx_beacon(priv);
65 + if (port_num == 0) {
66 + rtl8xxxu_stop_tx_beacon(priv);
67
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);
72 - ret = 0;
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);
77 + }
78 break;
79 case NL80211_IFTYPE_AP:
80 + if (port_num == 1)
81 + return -EOPNOTSUPP;
82 +
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);
90 -
91 - ret = 0;
92 break;
93 default:
94 - ret = -EOPNOTSUPP;
95 + return -EOPNOTSUPP;
96 }
97
98 - rtl8xxxu_set_linktype(priv, vif->type, 0);
99 + priv->vifs[port_num] = vif;
100 + priv->vif = vif;
101 + rtlvif->port_num = port_num;
102 +
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);
107
108 - return ret;
109 + return 0;
110 }
111
112 static void rtl8xxxu_remove_interface(struct ieee80211_hw *hw,
113 struct ieee80211_vif *vif)
114 {
115 + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
116 struct rtl8xxxu_priv *priv = hw->priv;
117
118 dev_dbg(&priv->udev->dev, "%s\n", __func__);
119
120 - if (priv->vif) {
121 - priv->vif = NULL;
122 - priv->vifs[0] = NULL;
123 - }
124 + priv->vif = NULL;
125 + priv->vifs[rtlvif->port_num] = NULL;
126 }
127
128 static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
129 @@ -7661,6 +7667,8 @@ static int rtl8xxxu_probe(struct usb_int
130 if (ret)
131 goto err_set_intfdata;
132
133 + hw->vif_data_size = sizeof(struct rtl8xxxu_vif);
134 +
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)