/[packages]/backports/8/kernel/current/SOURCES/net-wireless-rtw88-6.2-git.patch
ViewVC logotype

Contents of /backports/8/kernel/current/SOURCES/net-wireless-rtw88-6.2-git.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1928606 - (show annotations) (download)
Sun Jan 1 13:13:06 2023 UTC (15 months, 2 weeks ago) by tmb
File size: 75002 byte(s)
sync with Cauldron kernel-6.1.2-1.mga9
1
2 drivers/net/wireless/realtek/rtw88/Kconfig | 47 +++++++++
3 drivers/net/wireless/realtek/rtw88/Makefile | 15 +++
4 drivers/net/wireless/realtek/rtw88/coex.c | 3
5 drivers/net/wireless/realtek/rtw88/debug.c | 15 +++
6 drivers/net/wireless/realtek/rtw88/fw.c | 31 +++---
7 drivers/net/wireless/realtek/rtw88/fw.h | 11 ++
8 drivers/net/wireless/realtek/rtw88/hci.h | 9 -
9 drivers/net/wireless/realtek/rtw88/mac.c | 21 ++++
10 drivers/net/wireless/realtek/rtw88/mac80211.c | 2
11 drivers/net/wireless/realtek/rtw88/main.c | 12 +-
12 drivers/net/wireless/realtek/rtw88/main.h | 12 +-
13 drivers/net/wireless/realtek/rtw88/phy.c | 6 -
14 drivers/net/wireless/realtek/rtw88/ps.c | 2
15 drivers/net/wireless/realtek/rtw88/reg.h | 1
16 drivers/net/wireless/realtek/rtw88/rtw8723d.c | 28 +++++
17 drivers/net/wireless/realtek/rtw88/rtw8723d.h | 13 ++
18 drivers/net/wireless/realtek/rtw88/rtw8723du.c | 36 +++++++
19 drivers/net/wireless/realtek/rtw88/rtw8821c.c | 18 +++
20 drivers/net/wireless/realtek/rtw88/rtw8821c.h | 21 ++++
21 drivers/net/wireless/realtek/rtw88/rtw8821cu.c | 50 ++++++++++
22 drivers/net/wireless/realtek/rtw88/rtw8822b.c | 19 +++
23 drivers/net/wireless/realtek/rtw88/rtw8822bu.c | 90 ++++++++++++++++++
24 drivers/net/wireless/realtek/rtw88/rtw8822c.c | 24 ++++
25 drivers/net/wireless/realtek/rtw88/rtw8822cu.c | 44 ++++++++
26 drivers/net/wireless/realtek/rtw88/tx.h | 31 ++++++
27 drivers/net/wireless/realtek/rtw88/usb.c | 911 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
28 drivers/net/wireless/realtek/rtw88/usb.h | 107 +++++++++++++++++++++
29 drivers/net/wireless/realtek/rtw88/util.c | 103 ++++++++++++++++++++
30 drivers/net/wireless/realtek/rtw88/util.h | 12 +-
31 29 files changed, 1650 insertions(+), 44 deletions(-)
32
33 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/coex.c linux-6.2/drivers/net/wireless/realtek/rtw88/coex.c
34 --- linux-6.1/drivers/net/wireless/realtek/rtw88/coex.c 2022-12-12 00:15:18.000000000 +0200
35 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/coex.c 2022-12-24 00:49:25.771376835 +0200
36 @@ -633,7 +633,7 @@ static struct sk_buff *rtw_coex_info_req
37 struct rtw_coex *coex = &rtwdev->coex;
38 struct sk_buff *skb_resp = NULL;
39
40 - mutex_lock(&coex->mutex);
41 + lockdep_assert_held(&rtwdev->mutex);
42
43 rtw_fw_query_bt_mp_info(rtwdev, req);
44
45 @@ -650,7 +650,6 @@ static struct sk_buff *rtw_coex_info_req
46 }
47
48 out:
49 - mutex_unlock(&coex->mutex);
50 return skb_resp;
51 }
52
53 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/debug.c linux-6.2/drivers/net/wireless/realtek/rtw88/debug.c
54 --- linux-6.1/drivers/net/wireless/realtek/rtw88/debug.c 2022-12-12 00:15:18.000000000 +0200
55 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/debug.c 2022-12-24 00:49:25.771376835 +0200
56 @@ -144,7 +144,9 @@ static int rtw_debugfs_get_rf_read(struc
57 addr = debugfs_priv->rf_addr;
58 mask = debugfs_priv->rf_mask;
59
60 + mutex_lock(&rtwdev->mutex);
61 val = rtw_read_rf(rtwdev, path, addr, mask);
62 + mutex_unlock(&rtwdev->mutex);
63
64 seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n",
65 path, addr, mask, val);
66 @@ -390,7 +392,9 @@ static ssize_t rtw_debugfs_set_h2c(struc
67 return -EINVAL;
68 }
69
70 + mutex_lock(&rtwdev->mutex);
71 rtw_fw_h2c_cmd_dbg(rtwdev, param);
72 + mutex_unlock(&rtwdev->mutex);
73
74 return count;
75 }
76 @@ -414,7 +418,9 @@ static ssize_t rtw_debugfs_set_rf_write(
77 return count;
78 }
79
80 + mutex_lock(&rtwdev->mutex);
81 rtw_write_rf(rtwdev, path, addr, mask, val);
82 + mutex_unlock(&rtwdev->mutex);
83 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
84 "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n",
85 path, addr, mask, val);
86 @@ -519,6 +525,8 @@ static int rtw_debug_get_rf_dump(struct
87 u32 addr, offset, data;
88 u8 path;
89
90 + mutex_lock(&rtwdev->mutex);
91 +
92 for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
93 seq_printf(m, "RF path:%d\n", path);
94 for (addr = 0; addr < 0x100; addr += 4) {
95 @@ -533,6 +541,8 @@ static int rtw_debug_get_rf_dump(struct
96 seq_puts(m, "\n");
97 }
98
99 + mutex_unlock(&rtwdev->mutex);
100 +
101 return 0;
102 }
103
104 @@ -831,7 +841,9 @@ static int rtw_debugfs_get_coex_info(str
105 struct rtw_debugfs_priv *debugfs_priv = m->private;
106 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
107
108 + mutex_lock(&rtwdev->mutex);
109 rtw_coex_display_coex_info(rtwdev, m);
110 + mutex_unlock(&rtwdev->mutex);
111
112 return 0;
113 }
114 @@ -1026,6 +1038,8 @@ static void dump_gapk_status(struct rtw_
115 dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+',
116 rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]);
117
118 + mutex_lock(&rtwdev->mutex);
119 +
120 for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
121 val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK);
122 seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val);
123 @@ -1035,6 +1049,7 @@ static void dump_gapk_status(struct rtw_
124 txgapk->rf3f_fs[path][i], i);
125 seq_puts(m, "\n");
126 }
127 + mutex_unlock(&rtwdev->mutex);
128 }
129
130 static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v)
131 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/fw.c linux-6.2/drivers/net/wireless/realtek/rtw88/fw.c
132 --- linux-6.1/drivers/net/wireless/realtek/rtw88/fw.c 2022-12-12 00:15:18.000000000 +0200
133 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/fw.c 2022-12-24 00:49:25.771376835 +0200
134 @@ -311,10 +311,10 @@ EXPORT_SYMBOL(rtw_fw_c2h_cmd_isr);
135 static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
136 u8 *h2c)
137 {
138 + struct rtw_h2c_cmd *h2c_cmd = (struct rtw_h2c_cmd *)h2c;
139 u8 box;
140 u8 box_state;
141 u32 box_reg, box_ex_reg;
142 - int idx;
143 int ret;
144
145 rtw_dbg(rtwdev, RTW_DBG_FW,
146 @@ -322,7 +322,7 @@ static void rtw_fw_send_h2c_command(stru
147 h2c[3], h2c[2], h2c[1], h2c[0],
148 h2c[7], h2c[6], h2c[5], h2c[4]);
149
150 - spin_lock(&rtwdev->h2c.lock);
151 + lockdep_assert_held(&rtwdev->mutex);
152
153 box = rtwdev->h2c.last_box_num;
154 switch (box) {
155 @@ -344,7 +344,7 @@ static void rtw_fw_send_h2c_command(stru
156 break;
157 default:
158 WARN(1, "invalid h2c mail box number\n");
159 - goto out;
160 + return;
161 }
162
163 ret = read_poll_timeout_atomic(rtw_read8, box_state,
164 @@ -353,19 +353,14 @@ static void rtw_fw_send_h2c_command(stru
165
166 if (ret) {
167 rtw_err(rtwdev, "failed to send h2c command\n");
168 - goto out;
169 + return;
170 }
171
172 - for (idx = 0; idx < 4; idx++)
173 - rtw_write8(rtwdev, box_reg + idx, h2c[idx]);
174 - for (idx = 0; idx < 4; idx++)
175 - rtw_write8(rtwdev, box_ex_reg + idx, h2c[idx + 4]);
176 + rtw_write32(rtwdev, box_ex_reg, le32_to_cpu(h2c_cmd->msg_ext));
177 + rtw_write32(rtwdev, box_reg, le32_to_cpu(h2c_cmd->msg));
178
179 if (++rtwdev->h2c.last_box_num >= 4)
180 rtwdev->h2c.last_box_num = 0;
181 -
182 -out:
183 - spin_unlock(&rtwdev->h2c.lock);
184 }
185
186 void rtw_fw_h2c_cmd_dbg(struct rtw_dev *rtwdev, u8 *h2c)
187 @@ -377,15 +372,13 @@ static void rtw_fw_send_h2c_packet(struc
188 {
189 int ret;
190
191 - spin_lock(&rtwdev->h2c.lock);
192 + lockdep_assert_held(&rtwdev->mutex);
193
194 FW_OFFLOAD_H2C_SET_SEQ_NUM(h2c_pkt, rtwdev->h2c.seq);
195 ret = rtw_hci_write_data_h2c(rtwdev, h2c_pkt, H2C_PKT_SIZE);
196 if (ret)
197 rtw_err(rtwdev, "failed to send h2c packet\n");
198 rtwdev->h2c.seq++;
199 -
200 - spin_unlock(&rtwdev->h2c.lock);
201 }
202
203 void
204 @@ -823,6 +816,16 @@ void rtw_fw_set_nlo_info(struct rtw_dev
205
206 rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
207 }
208 +
209 +void rtw_fw_set_recover_bt_device(struct rtw_dev *rtwdev)
210 +{
211 + u8 h2c_pkt[H2C_PKT_SIZE] = {0};
212 +
213 + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RECOVER_BT_DEV);
214 + SET_RECOVER_BT_DEV_EN(h2c_pkt, 1);
215 +
216 + rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
217 +}
218
219 void rtw_fw_set_pg_info(struct rtw_dev *rtwdev)
220 {
221 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/fw.h linux-6.2/drivers/net/wireless/realtek/rtw88/fw.h
222 --- linux-6.1/drivers/net/wireless/realtek/rtw88/fw.h 2022-12-12 00:15:18.000000000 +0200
223 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/fw.h 2022-12-24 00:49:25.771376835 +0200
224 @@ -81,6 +81,11 @@ struct rtw_c2h_adaptivity {
225 u8 option;
226 } __packed;
227
228 +struct rtw_h2c_cmd {
229 + __le32 msg;
230 + __le32 msg_ext;
231 +} __packed;
232 +
233 enum rtw_rsvd_packet_type {
234 RSVD_BEACON,
235 RSVD_DUMMY,
236 @@ -550,6 +555,8 @@ static inline void rtw_h2c_pkt_set_heade
237 #define H2C_CMD_AOAC_GLOBAL_INFO 0x82
238 #define H2C_CMD_NLO_INFO 0x8C
239
240 +#define H2C_CMD_RECOVER_BT_DEV 0xD1
241 +
242 #define SET_H2C_CMD_ID_CLASS(h2c_pkt, value) \
243 le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(7, 0))
244
245 @@ -749,6 +756,9 @@ static inline void rtw_h2c_pkt_set_heade
246 #define SET_NLO_LOC_NLO_INFO(h2c_pkt, value) \
247 le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16))
248
249 +#define SET_RECOVER_BT_DEV_EN(h2c_pkt, value) \
250 + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8))
251 +
252 #define GET_FW_DUMP_LEN(_header) \
253 le32_get_bits(*((__le32 *)(_header) + 0x00), GENMASK(15, 0))
254 #define GET_FW_DUMP_SEQ(_header) \
255 @@ -838,6 +848,7 @@ void rtw_fw_set_aoac_global_info_cmd(str
256 u8 group_key_enc);
257
258 void rtw_fw_set_nlo_info(struct rtw_dev *rtwdev, bool enable);
259 +void rtw_fw_set_recover_bt_device(struct rtw_dev *rtwdev);
260 void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev,
261 struct cfg80211_ssid *ssid);
262 void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable);
263 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/hci.h linux-6.2/drivers/net/wireless/realtek/rtw88/hci.h
264 --- linux-6.1/drivers/net/wireless/realtek/rtw88/hci.h 2022-12-12 00:15:18.000000000 +0200
265 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/hci.h 2022-12-24 00:49:25.771376835 +0200
266 @@ -166,12 +166,11 @@ static inline u32
267 rtw_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
268 u32 addr, u32 mask)
269 {
270 - unsigned long flags;
271 u32 val;
272
273 - spin_lock_irqsave(&rtwdev->rf_lock, flags);
274 + lockdep_assert_held(&rtwdev->mutex);
275 +
276 val = rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask);
277 - spin_unlock_irqrestore(&rtwdev->rf_lock, flags);
278
279 return val;
280 }
281 @@ -180,11 +179,9 @@ static inline void
282 rtw_write_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
283 u32 addr, u32 mask, u32 data)
284 {
285 - unsigned long flags;
286 + lockdep_assert_held(&rtwdev->mutex);
287
288 - spin_lock_irqsave(&rtwdev->rf_lock, flags);
289 rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data);
290 - spin_unlock_irqrestore(&rtwdev->rf_lock, flags);
291 }
292
293 static inline u32
294 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/Kconfig linux-6.2/drivers/net/wireless/realtek/rtw88/Kconfig
295 --- linux-6.1/drivers/net/wireless/realtek/rtw88/Kconfig 2022-12-12 00:15:18.000000000 +0200
296 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/Kconfig 2022-12-24 00:49:25.770376835 +0200
297 @@ -16,6 +16,9 @@ config RTW88_CORE
298 config RTW88_PCI
299 tristate
300
301 +config RTW88_USB
302 + tristate
303 +
304 config RTW88_8822B
305 tristate
306
307 @@ -39,6 +42,17 @@ config RTW88_8822BE
308
309 802.11ac PCIe wireless network adapter
310
311 +config RTW88_8822BU
312 + tristate "Realtek 8822BU USB wireless network adapter"
313 + depends on USB
314 + select RTW88_CORE
315 + select RTW88_USB
316 + select RTW88_8822B
317 + help
318 + Select this option will enable support for 8822BU chipset
319 +
320 + 802.11ac USB wireless network adapter
321 +
322 config RTW88_8822CE
323 tristate "Realtek 8822CE PCI wireless network adapter"
324 depends on PCI
325 @@ -50,6 +64,17 @@ config RTW88_8822CE
326
327 802.11ac PCIe wireless network adapter
328
329 +config RTW88_8822CU
330 + tristate "Realtek 8822CU USB wireless network adapter"
331 + depends on USB
332 + select RTW88_CORE
333 + select RTW88_USB
334 + select RTW88_8822C
335 + help
336 + Select this option will enable support for 8822CU chipset
337 +
338 + 802.11ac USB wireless network adapter
339 +
340 config RTW88_8723DE
341 tristate "Realtek 8723DE PCI wireless network adapter"
342 depends on PCI
343 @@ -61,6 +86,17 @@ config RTW88_8723DE
344
345 802.11n PCIe wireless network adapter
346
347 +config RTW88_8723DU
348 + tristate "Realtek 8723DU USB wireless network adapter"
349 + depends on USB
350 + select RTW88_CORE
351 + select RTW88_USB
352 + select RTW88_8723D
353 + help
354 + Select this option will enable support for 8723DU chipset
355 +
356 + 802.11n USB wireless network adapter
357 +
358 config RTW88_8821CE
359 tristate "Realtek 8821CE PCI wireless network adapter"
360 depends on PCI
361 @@ -72,6 +108,17 @@ config RTW88_8821CE
362
363 802.11ac PCIe wireless network adapter
364
365 +config RTW88_8821CU
366 + tristate "Realtek 8821CU USB wireless network adapter"
367 + depends on USB
368 + select RTW88_CORE
369 + select RTW88_USB
370 + select RTW88_8821C
371 + help
372 + Select this option will enable support for 8821CU chipset
373 +
374 + 802.11ac USB wireless network adapter
375 +
376 config RTW88_DEBUG
377 bool "Realtek rtw88 debug support"
378 depends on RTW88_CORE
379 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/mac80211.c linux-6.2/drivers/net/wireless/realtek/rtw88/mac80211.c
380 --- linux-6.1/drivers/net/wireless/realtek/rtw88/mac80211.c 2022-12-12 00:15:18.000000000 +0200
381 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/mac80211.c 2022-12-24 00:49:25.772376835 +0200
382 @@ -487,8 +487,8 @@ static int rtw_ops_sta_remove(struct iee
383 {
384 struct rtw_dev *rtwdev = hw->priv;
385
386 - rtw_fw_beacon_filter_config(rtwdev, false, vif);
387 mutex_lock(&rtwdev->mutex);
388 + rtw_fw_beacon_filter_config(rtwdev, false, vif);
389 rtw_sta_remove(rtwdev, sta, true);
390 mutex_unlock(&rtwdev->mutex);
391
392 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/mac.c linux-6.2/drivers/net/wireless/realtek/rtw88/mac.c
393 --- linux-6.1/drivers/net/wireless/realtek/rtw88/mac.c 2022-12-12 00:15:18.000000000 +0200
394 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/mac.c 2022-12-24 00:49:25.772376835 +0200
395 @@ -906,7 +906,8 @@ out:
396 return ret;
397 }
398
399 -int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)
400 +static
401 +int _rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)
402 {
403 if (rtw_chip_wcpu_11n(rtwdev))
404 return __rtw_download_firmware_legacy(rtwdev, fw);
405 @@ -914,6 +915,21 @@ int rtw_download_firmware(struct rtw_dev
406 return __rtw_download_firmware(rtwdev, fw);
407 }
408
409 +int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)
410 +{
411 + int ret;
412 +
413 + ret = _rtw_download_firmware(rtwdev, fw);
414 + if (ret)
415 + return ret;
416 +
417 + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE &&
418 + rtwdev->chip->id == RTW_CHIP_TYPE_8821C)
419 + rtw_fw_set_recover_bt_device(rtwdev);
420 +
421 + return 0;
422 +}
423 +
424 static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues)
425 {
426 const struct rtw_rqpn *rqpn = rtwdev->fifo.rqpn;
427 @@ -1032,6 +1048,9 @@ static int txdma_queue_mapping(struct rt
428 if (rtw_chip_wcpu_11ac(rtwdev))
429 rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL);
430
431 + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB)
432 + rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_ARBBW_EN);
433 +
434 return 0;
435 }
436
437 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/main.c linux-6.2/drivers/net/wireless/realtek/rtw88/main.c
438 --- linux-6.1/drivers/net/wireless/realtek/rtw88/main.c 2022-12-12 00:15:18.000000000 +0200
439 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/main.c 2022-12-24 00:49:25.772376835 +0200
440 @@ -1731,7 +1731,8 @@ static void rtw_load_firmware_cb(const s
441 update_firmware_info(rtwdev, fw);
442 complete_all(&fw->completion);
443
444 - rtw_info(rtwdev, "Firmware version %u.%u.%u, H2C version %u\n",
445 + rtw_info(rtwdev, "%sFirmware version %u.%u.%u, H2C version %u\n",
446 + fw->type == RTW_WOWLAN_FW ? "WOW " : "",
447 fw->version, fw->sub_version, fw->sub_index, fw->h2c_version);
448 }
449
450 @@ -1757,6 +1758,7 @@ static int rtw_load_firmware(struct rtw_
451 return -ENOENT;
452 }
453
454 + fw->type = type;
455 fw->rtwdev = rtwdev;
456 init_completion(&fw->completion);
457
458 @@ -1781,6 +1783,10 @@ static int rtw_chip_parameter_setup(stru
459 rtwdev->hci.rpwm_addr = 0x03d9;
460 rtwdev->hci.cpwm_addr = 0x03da;
461 break;
462 + case RTW_HCI_TYPE_USB:
463 + rtwdev->hci.rpwm_addr = 0xfe58;
464 + rtwdev->hci.cpwm_addr = 0xfe57;
465 + break;
466 default:
467 rtw_err(rtwdev, "unsupported hci type\n");
468 return -EINVAL;
469 @@ -2065,13 +2071,10 @@ int rtw_core_init(struct rtw_dev *rtwdev
470 skb_queue_head_init(&rtwdev->coex.queue);
471 skb_queue_head_init(&rtwdev->tx_report.queue);
472
473 - spin_lock_init(&rtwdev->rf_lock);
474 - spin_lock_init(&rtwdev->h2c.lock);
475 spin_lock_init(&rtwdev->txq_lock);
476 spin_lock_init(&rtwdev->tx_report.q_lock);
477
478 mutex_init(&rtwdev->mutex);
479 - mutex_init(&rtwdev->coex.mutex);
480 mutex_init(&rtwdev->hal.tx_power_mutex);
481
482 init_waitqueue_head(&rtwdev->coex.wait);
483 @@ -2143,7 +2146,6 @@ void rtw_core_deinit(struct rtw_dev *rtw
484 }
485
486 mutex_destroy(&rtwdev->mutex);
487 - mutex_destroy(&rtwdev->coex.mutex);
488 mutex_destroy(&rtwdev->hal.tx_power_mutex);
489 }
490 EXPORT_SYMBOL(rtw_core_deinit);
491 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/main.h linux-6.2/drivers/net/wireless/realtek/rtw88/main.h
492 --- linux-6.1/drivers/net/wireless/realtek/rtw88/main.h 2022-12-12 00:15:18.000000000 +0200
493 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/main.h 2022-12-24 00:49:25.773376835 +0200
494 @@ -871,6 +871,10 @@ struct rtw_chip_ops {
495 bool is_tx2_path);
496 void (*config_txrx_mode)(struct rtw_dev *rtwdev, u8 tx_path,
497 u8 rx_path, bool is_tx2_path);
498 + /* for USB/SDIO only */
499 + void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev,
500 + struct rtw_tx_pkt_info *pkt_info,
501 + u8 *txdesc);
502
503 /* for coex */
504 void (*coex_set_init)(struct rtw_dev *rtwdev);
505 @@ -1501,8 +1505,6 @@ struct rtw_coex_stat {
506 };
507
508 struct rtw_coex {
509 - /* protects coex info request section */
510 - struct mutex mutex;
511 struct sk_buff_head queue;
512 wait_queue_head_t wait;
513
514 @@ -1851,6 +1853,7 @@ struct rtw_fw_state {
515 u16 h2c_version;
516 u32 feature;
517 u32 feature_ext;
518 + enum rtw_fw_type type;
519 };
520
521 enum rtw_sar_sources {
522 @@ -1994,9 +1997,6 @@ struct rtw_dev {
523 /* ensures exclusive access from mac80211 callbacks */
524 struct mutex mutex;
525
526 - /* read/write rf register */
527 - spinlock_t rf_lock;
528 -
529 /* watch dog every 2 sec */
530 struct delayed_work watch_dog_work;
531 u32 watch_dog_cnt;
532 @@ -2022,8 +2022,6 @@ struct rtw_dev {
533 struct {
534 /* incicate the mail box to use with fw */
535 u8 last_box_num;
536 - /* protect to send h2c to fw */
537 - spinlock_t lock;
538 u32 seq;
539 } h2c;
540
541 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/Makefile linux-6.2/drivers/net/wireless/realtek/rtw88/Makefile
542 --- linux-6.1/drivers/net/wireless/realtek/rtw88/Makefile 2022-12-12 00:15:18.000000000 +0200
543 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/Makefile 2022-12-24 00:49:25.770376835 +0200
544 @@ -26,23 +26,38 @@ rtw88_8822b-objs := rtw8822b.o rtw8822b
545 obj-$(CONFIG_RTW88_8822BE) += rtw88_8822be.o
546 rtw88_8822be-objs := rtw8822be.o
547
548 +obj-$(CONFIG_RTW88_8822BU) += rtw88_8822bu.o
549 +rtw88_8822bu-objs := rtw8822bu.o
550 +
551 obj-$(CONFIG_RTW88_8822C) += rtw88_8822c.o
552 rtw88_8822c-objs := rtw8822c.o rtw8822c_table.o
553
554 obj-$(CONFIG_RTW88_8822CE) += rtw88_8822ce.o
555 rtw88_8822ce-objs := rtw8822ce.o
556
557 +obj-$(CONFIG_RTW88_8822CU) += rtw88_8822cu.o
558 +rtw88_8822cu-objs := rtw8822cu.o
559 +
560 obj-$(CONFIG_RTW88_8723D) += rtw88_8723d.o
561 rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o
562
563 obj-$(CONFIG_RTW88_8723DE) += rtw88_8723de.o
564 rtw88_8723de-objs := rtw8723de.o
565
566 +obj-$(CONFIG_RTW88_8723DU) += rtw88_8723du.o
567 +rtw88_8723du-objs := rtw8723du.o
568 +
569 obj-$(CONFIG_RTW88_8821C) += rtw88_8821c.o
570 rtw88_8821c-objs := rtw8821c.o rtw8821c_table.o
571
572 obj-$(CONFIG_RTW88_8821CE) += rtw88_8821ce.o
573 rtw88_8821ce-objs := rtw8821ce.o
574
575 +obj-$(CONFIG_RTW88_8821CU) += rtw88_8821cu.o
576 +rtw88_8821cu-objs := rtw8821cu.o
577 +
578 obj-$(CONFIG_RTW88_PCI) += rtw88_pci.o
579 rtw88_pci-objs := pci.o
580 +
581 +obj-$(CONFIG_RTW88_USB) += rtw88_usb.o
582 +rtw88_usb-objs := usb.o
583 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/phy.c linux-6.2/drivers/net/wireless/realtek/rtw88/phy.c
584 --- linux-6.1/drivers/net/wireless/realtek/rtw88/phy.c 2022-12-12 00:15:18.000000000 +0200
585 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/phy.c 2022-12-24 00:49:25.773376835 +0200
586 @@ -300,7 +300,7 @@ static void rtw_phy_stat_rssi(struct rtw
587
588 data.rtwdev = rtwdev;
589 data.min_rssi = U8_MAX;
590 - rtw_iterate_stas_atomic(rtwdev, rtw_phy_stat_rssi_iter, &data);
591 + rtw_iterate_stas(rtwdev, rtw_phy_stat_rssi_iter, &data);
592
593 dm_info->pre_min_rssi = dm_info->min_rssi;
594 dm_info->min_rssi = data.min_rssi;
595 @@ -544,7 +544,7 @@ static void rtw_phy_ra_info_update(struc
596 if (rtwdev->watch_dog_cnt & 0x3)
597 return;
598
599 - rtw_iterate_stas_atomic(rtwdev, rtw_phy_ra_info_update_iter, rtwdev);
600 + rtw_iterate_stas(rtwdev, rtw_phy_ra_info_update_iter, rtwdev);
601 }
602
603 static u32 rtw_phy_get_rrsr_mask(struct rtw_dev *rtwdev, u8 rate_idx)
604 @@ -597,7 +597,7 @@ static void rtw_phy_rrsr_update(struct r
605 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
606
607 dm_info->rrsr_mask_min = RRSR_RATE_ORDER_MAX;
608 - rtw_iterate_stas_atomic(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev);
609 + rtw_iterate_stas(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev);
610 rtw_write32(rtwdev, REG_RRSR, dm_info->rrsr_val_init & dm_info->rrsr_mask_min);
611 }
612
613 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/ps.c linux-6.2/drivers/net/wireless/realtek/rtw88/ps.c
614 --- linux-6.1/drivers/net/wireless/realtek/rtw88/ps.c 2022-12-12 00:15:18.000000000 +0200
615 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/ps.c 2022-12-24 00:49:25.773376835 +0200
616 @@ -61,7 +61,7 @@ int rtw_leave_ips(struct rtw_dev *rtwdev
617 return ret;
618 }
619
620 - rtw_iterate_vifs_atomic(rtwdev, rtw_restore_port_cfg_iter, rtwdev);
621 + rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev);
622
623 rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE);
624
625 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/reg.h linux-6.2/drivers/net/wireless/realtek/rtw88/reg.h
626 --- linux-6.1/drivers/net/wireless/realtek/rtw88/reg.h 2022-12-12 00:15:18.000000000 +0200
627 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/reg.h 2022-12-24 00:49:25.773376835 +0200
628 @@ -184,6 +184,7 @@
629 #define BIT_TXDMA_VIQ_MAP(x) \
630 (((x) & BIT_MASK_TXDMA_VIQ_MAP) << BIT_SHIFT_TXDMA_VIQ_MAP)
631 #define REG_TXDMA_PQ_MAP 0x010C
632 +#define BIT_RXDMA_ARBBW_EN BIT(0)
633 #define BIT_SHIFT_TXDMA_BEQ_MAP 8
634 #define BIT_MASK_TXDMA_BEQ_MAP 0x3
635 #define BIT_TXDMA_BEQ_MAP(x) \
636 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723d.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723d.c
637 --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2022-12-12 00:15:18.000000000 +0200
638 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2022-12-24 00:49:25.773376835 +0200
639 @@ -210,6 +210,12 @@ static void rtw8723de_efuse_parsing(stru
640 ether_addr_copy(efuse->addr, map->e.mac_addr);
641 }
642
643 +static void rtw8723du_efuse_parsing(struct rtw_efuse *efuse,
644 + struct rtw8723d_efuse *map)
645 +{
646 + ether_addr_copy(efuse->addr, map->u.mac_addr);
647 +}
648 +
649 static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
650 {
651 struct rtw_efuse *efuse = &rtwdev->efuse;
652 @@ -239,6 +245,9 @@ static int rtw8723d_read_efuse(struct rt
653 case RTW_HCI_TYPE_PCIE:
654 rtw8723de_efuse_parsing(efuse, map);
655 break;
656 + case RTW_HCI_TYPE_USB:
657 + rtw8723du_efuse_parsing(efuse, map);
658 + break;
659 default:
660 /* unsupported now */
661 return -ENOTSUPP;
662 @@ -1945,6 +1954,24 @@ static void rtw8723d_pwr_track(struct rt
663 dm_info->pwr_trk_triggered = false;
664 }
665
666 +static void rtw8723d_fill_txdesc_checksum(struct rtw_dev *rtwdev,
667 + struct rtw_tx_pkt_info *pkt_info,
668 + u8 *txdesc)
669 +{
670 + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
671 + __le16 chksum = 0;
672 + __le16 *data = (__le16 *)(txdesc);
673 +
674 + SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000);
675 +
676 + while (words--)
677 + chksum ^= *data++;
678 +
679 + chksum = ~chksum;
680 +
681 + SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum));
682 +}
683 +
684 static struct rtw_chip_ops rtw8723d_ops = {
685 .phy_set_param = rtw8723d_phy_set_param,
686 .read_efuse = rtw8723d_read_efuse,
687 @@ -1965,6 +1992,7 @@ static struct rtw_chip_ops rtw8723d_ops
688 .config_bfee = NULL,
689 .set_gid_table = NULL,
690 .cfg_csi_rate = NULL,
691 + .fill_txdesc_checksum = rtw8723d_fill_txdesc_checksum,
692
693 .coex_set_init = rtw8723d_coex_cfg_init,
694 .coex_set_ant_switch = NULL,
695 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723d.h linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723d.h
696 --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2022-12-12 00:15:18.000000000 +0200
697 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2022-12-24 00:49:25.773376835 +0200
698 @@ -41,6 +41,14 @@ struct rtw8723de_efuse {
699 u8 sub_device_id[2];
700 };
701
702 +struct rtw8723du_efuse {
703 + u8 res4[48]; /* 0xd0 */
704 + u8 vender_id[2]; /* 0x100 */
705 + u8 product_id[2]; /* 0x102 */
706 + u8 usb_option; /* 0x104 */
707 + u8 mac_addr[ETH_ALEN]; /* 0x107 */
708 +};
709 +
710 struct rtw8723d_efuse {
711 __le16 rtl_id;
712 u8 rsvd[2];
713 @@ -69,7 +77,10 @@ struct rtw8723d_efuse {
714 u8 rfe_option;
715 u8 country_code[2];
716 u8 res[3];
717 - struct rtw8723de_efuse e;
718 + union {
719 + struct rtw8723de_efuse e;
720 + struct rtw8723du_efuse u;
721 + };
722 };
723
724 extern const struct rtw_chip_info rtw8723d_hw_spec;
725 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723du.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723du.c
726 --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723du.c 1970-01-01 02:00:00.000000000 +0200
727 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723du.c 2022-12-24 00:49:25.773376835 +0200
728 @@ -0,0 +1,36 @@
729 +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
730 +/* Copyright(c) 2018-2019 Realtek Corporation
731 + */
732 +
733 +#include <linux/module.h>
734 +#include <linux/usb.h>
735 +#include "main.h"
736 +#include "rtw8723d.h"
737 +#include "usb.h"
738 +
739 +static const struct usb_device_id rtw_8723du_id_table[] = {
740 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd723, 0xff, 0xff, 0xff),
741 + .driver_info = (kernel_ulong_t)&(rtw8723d_hw_spec) }, /* 8723DU 1*1 */
742 + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd611, 0xff, 0xff, 0xff),
743 + .driver_info = (kernel_ulong_t)&(rtw8723d_hw_spec) }, /* Edimax EW-7611ULB V2 */
744 + { },
745 +};
746 +MODULE_DEVICE_TABLE(usb, rtw_8723du_id_table);
747 +
748 +static int rtw8723du_probe(struct usb_interface *intf,
749 + const struct usb_device_id *id)
750 +{
751 + return rtw_usb_probe(intf, id);
752 +}
753 +
754 +static struct usb_driver rtw_8723du_driver = {
755 + .name = "rtw_8723du",
756 + .id_table = rtw_8723du_id_table,
757 + .probe = rtw8723du_probe,
758 + .disconnect = rtw_usb_disconnect,
759 +};
760 +module_usb_driver(rtw_8723du_driver);
761 +
762 +MODULE_AUTHOR("Hans Ulli Kroll <linux@ulli-kroll.de>");
763 +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723du driver");
764 +MODULE_LICENSE("Dual BSD/GPL");
765 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821c.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821c.c
766 --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2022-12-12 00:15:18.000000000 +0200
767 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2022-12-24 00:49:25.774376835 +0200
768 @@ -26,6 +26,12 @@ static void rtw8821ce_efuse_parsing(stru
769 ether_addr_copy(efuse->addr, map->e.mac_addr);
770 }
771
772 +static void rtw8821cu_efuse_parsing(struct rtw_efuse *efuse,
773 + struct rtw8821c_efuse *map)
774 +{
775 + ether_addr_copy(efuse->addr, map->u.mac_addr);
776 +}
777 +
778 enum rtw8821ce_rf_set {
779 SWITCH_TO_BTG,
780 SWITCH_TO_WLG,
781 @@ -68,6 +74,9 @@ static int rtw8821c_read_efuse(struct rt
782 case RTW_HCI_TYPE_PCIE:
783 rtw8821ce_efuse_parsing(efuse, map);
784 break;
785 + case RTW_HCI_TYPE_USB:
786 + rtw8821cu_efuse_parsing(efuse, map);
787 + break;
788 default:
789 /* unsupported now */
790 return -ENOTSUPP;
791 @@ -1148,6 +1157,13 @@ static void rtw8821c_phy_cck_pd_set(stru
792 dm_info->cck_pd_default + new_lvl * 2);
793 }
794
795 +static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
796 + struct rtw_tx_pkt_info *pkt_info,
797 + u8 *txdesc)
798 +{
799 + fill_txdesc_checksum_common(txdesc, 16);
800 +}
801 +
802 static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
803 {0x0086,
804 RTW_PWR_CUT_ALL_MSK,
805 @@ -1521,6 +1537,7 @@ static const struct rtw_rfe_def rtw8821c
806 [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
807 [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
808 [6] = RTW_DEF_RFE(8821c, 0, 0),
809 + [34] = RTW_DEF_RFE(8821c, 0, 0),
810 };
811
812 static struct rtw_hw_reg rtw8821c_dig[] = {
813 @@ -1595,6 +1612,7 @@ static struct rtw_chip_ops rtw8821c_ops
814 .config_bfee = rtw8821c_bf_config_bfee,
815 .set_gid_table = rtw_bf_set_gid_table,
816 .cfg_csi_rate = rtw_bf_cfg_csi_rate,
817 + .fill_txdesc_checksum = rtw8821c_fill_txdesc_checksum,
818
819 .coex_set_init = rtw8821c_coex_cfg_init,
820 .coex_set_ant_switch = rtw8821c_coex_cfg_ant_switch,
821 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821c.h linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821c.h
822 --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2022-12-12 00:15:18.000000000 +0200
823 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2022-12-24 00:49:25.774376835 +0200
824 @@ -9,6 +9,26 @@
825
826 #define RCR_VHT_ACK BIT(26)
827
828 +struct rtw8821cu_efuse {
829 + u8 res4[4]; /* 0xd0 */
830 + u8 usb_optional_function;
831 + u8 res5[0x1e];
832 + u8 res6[2];
833 + u8 serial[0x0b]; /* 0xf5 */
834 + u8 vid; /* 0x100 */
835 + u8 res7;
836 + u8 pid;
837 + u8 res8[4];
838 + u8 mac_addr[ETH_ALEN]; /* 0x107 */
839 + u8 res9[2];
840 + u8 vendor_name[0x07];
841 + u8 res10[2];
842 + u8 device_name[0x14];
843 + u8 res11[0xcf];
844 + u8 package_type; /* 0x1fb */
845 + u8 res12[0x4];
846 +};
847 +
848 struct rtw8821ce_efuse {
849 u8 mac_addr[ETH_ALEN]; /* 0xd0 */
850 u8 vender_id[2];
851 @@ -73,6 +93,7 @@ struct rtw8821c_efuse {
852 u8 res[3];
853 union {
854 struct rtw8821ce_efuse e;
855 + struct rtw8821cu_efuse u;
856 };
857 };
858
859 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821cu.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821cu.c
860 --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821cu.c 1970-01-01 02:00:00.000000000 +0200
861 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821cu.c 2022-12-24 00:49:25.774376835 +0200
862 @@ -0,0 +1,50 @@
863 +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
864 +/* Copyright(c) 2018-2019 Realtek Corporation
865 + */
866 +
867 +#include <linux/module.h>
868 +#include <linux/usb.h>
869 +#include "main.h"
870 +#include "rtw8821c.h"
871 +#include "usb.h"
872 +
873 +static const struct usb_device_id rtw_8821cu_id_table[] = {
874 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82b, 0xff, 0xff, 0xff),
875 + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
876 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb820, 0xff, 0xff, 0xff),
877 + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
878 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc821, 0xff, 0xff, 0xff),
879 + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
880 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc820, 0xff, 0xff, 0xff),
881 + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
882 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82a, 0xff, 0xff, 0xff),
883 + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
884 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82b, 0xff, 0xff, 0xff),
885 + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
886 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc811, 0xff, 0xff, 0xff),
887 + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8811CU */
888 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8811, 0xff, 0xff, 0xff),
889 + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8811CU */
890 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2006, 0xff, 0xff, 0xff),
891 + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* TOTOLINK A650UA v3 */
892 + {},
893 +};
894 +MODULE_DEVICE_TABLE(usb, rtw_8821cu_id_table);
895 +
896 +static int rtw_8821cu_probe(struct usb_interface *intf,
897 + const struct usb_device_id *id)
898 +{
899 + return rtw_usb_probe(intf, id);
900 +}
901 +
902 +static struct usb_driver rtw_8821cu_driver = {
903 + .name = "rtw_8821cu",
904 + .id_table = rtw_8821cu_id_table,
905 + .probe = rtw_8821cu_probe,
906 + .disconnect = rtw_usb_disconnect,
907 +};
908 +module_usb_driver(rtw_8821cu_driver);
909 +
910 +MODULE_AUTHOR("Hans Ulli Kroll <linux@ulli-kroll.de>");
911 +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821cu driver");
912 +MODULE_LICENSE("Dual BSD/GPL");
913 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822b.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822b.c
914 --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2022-12-12 00:15:18.000000000 +0200
915 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2022-12-24 00:49:25.774376835 +0200
916 @@ -26,6 +26,12 @@ static void rtw8822be_efuse_parsing(stru
917 ether_addr_copy(efuse->addr, map->e.mac_addr);
918 }
919
920 +static void rtw8822bu_efuse_parsing(struct rtw_efuse *efuse,
921 + struct rtw8822b_efuse *map)
922 +{
923 + ether_addr_copy(efuse->addr, map->u.mac_addr);
924 +}
925 +
926 static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
927 {
928 struct rtw_efuse *efuse = &rtwdev->efuse;
929 @@ -56,6 +62,9 @@ static int rtw8822b_read_efuse(struct rt
930 case RTW_HCI_TYPE_PCIE:
931 rtw8822be_efuse_parsing(efuse, map);
932 break;
933 + case RTW_HCI_TYPE_USB:
934 + rtw8822bu_efuse_parsing(efuse, map);
935 + break;
936 default:
937 /* unsupported now */
938 return -ENOTSUPP;
939 @@ -1588,6 +1597,15 @@ static void rtw8822b_adaptivity(struct r
940 rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
941 }
942
943 +static void rtw8822b_fill_txdesc_checksum(struct rtw_dev *rtwdev,
944 + struct rtw_tx_pkt_info *pkt_info,
945 + u8 *txdesc)
946 +{
947 + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
948 +
949 + fill_txdesc_checksum_common(txdesc, words);
950 +}
951 +
952 static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = {
953 {0x0086,
954 RTW_PWR_CUT_ALL_MSK,
955 @@ -2163,6 +2181,7 @@ static struct rtw_chip_ops rtw8822b_ops
956 .cfg_csi_rate = rtw_bf_cfg_csi_rate,
957 .adaptivity_init = rtw8822b_adaptivity_init,
958 .adaptivity = rtw8822b_adaptivity,
959 + .fill_txdesc_checksum = rtw8822b_fill_txdesc_checksum,
960
961 .coex_set_init = rtw8822b_coex_cfg_init,
962 .coex_set_ant_switch = rtw8822b_coex_cfg_ant_switch,
963 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822bu.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822bu.c
964 --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822bu.c 1970-01-01 02:00:00.000000000 +0200
965 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822bu.c 2022-12-24 00:49:25.774376835 +0200
966 @@ -0,0 +1,90 @@
967 +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
968 +/* Copyright(c) 2018-2019 Realtek Corporation
969 + */
970 +
971 +#include <linux/module.h>
972 +#include <linux/usb.h>
973 +#include "main.h"
974 +#include "rtw8822b.h"
975 +#include "usb.h"
976 +
977 +static const struct usb_device_id rtw_8822bu_id_table[] = {
978 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb812, 0xff, 0xff, 0xff),
979 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
980 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82c, 0xff, 0xff, 0xff),
981 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
982 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2102, 0xff, 0xff, 0xff),
983 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* CCNC */
984 + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb822, 0xff, 0xff, 0xff),
985 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822ULC */
986 + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc822, 0xff, 0xff, 0xff),
987 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UTC */
988 + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd822, 0xff, 0xff, 0xff),
989 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */
990 + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xe822, 0xff, 0xff, 0xff),
991 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */
992 + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xf822, 0xff, 0xff, 0xff),
993 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UAD */
994 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb81a, 0xff, 0xff, 0xff),
995 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID */
996 + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1841, 0xff, 0xff, 0xff),
997 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS AC1300 USB-AC55 B1 */
998 + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x184c, 0xff, 0xff, 0xff),
999 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS U2 */
1000 + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x19aa, 0xff, 0xff, 0xff),
1001 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS - USB-AC58 rev A1 */
1002 + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1870, 0xff, 0xff, 0xff),
1003 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */
1004 + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1874, 0xff, 0xff, 0xff),
1005 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */
1006 + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331e, 0xff, 0xff, 0xff),
1007 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-181 */
1008 + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331c, 0xff, 0xff, 0xff),
1009 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-182 - D1 */
1010 + {USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331f, 0xff, 0xff, 0xff),
1011 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec)}, /* Dlink - DWA-183 D Ver */
1012 + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff),
1013 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB6400M */
1014 + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0045, 0xff, 0xff, 0xff),
1015 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB3600 v2 */
1016 + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012d, 0xff, 0xff, 0xff),
1017 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U v1 */
1018 + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0138, 0xff, 0xff, 0xff),
1019 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U Plus v1 */
1020 + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0115, 0xff, 0xff, 0xff),
1021 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T4U V3 */
1022 + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012e, 0xff, 0xff, 0xff),
1023 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */
1024 + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0116, 0xff, 0xff, 0xff),
1025 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */
1026 + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0117, 0xff, 0xff, 0xff),
1027 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */
1028 + { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9055, 0xff, 0xff, 0xff),
1029 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Netgear A6150 */
1030 + { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0025, 0xff, 0xff, 0xff),
1031 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Hawking HW12ACU */
1032 + { USB_DEVICE_AND_INTERFACE_INFO(0x04ca, 0x8602, 0xff, 0xff, 0xff),
1033 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */
1034 + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x808a, 0xff, 0xff, 0xff),
1035 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */
1036 + {},
1037 +};
1038 +MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table);
1039 +
1040 +static int rtw8822bu_probe(struct usb_interface *intf,
1041 + const struct usb_device_id *id)
1042 +{
1043 + return rtw_usb_probe(intf, id);
1044 +}
1045 +
1046 +static struct usb_driver rtw_8822bu_driver = {
1047 + .name = "rtw_8822bu",
1048 + .id_table = rtw_8822bu_id_table,
1049 + .probe = rtw8822bu_probe,
1050 + .disconnect = rtw_usb_disconnect,
1051 +};
1052 +module_usb_driver(rtw_8822bu_driver);
1053 +
1054 +MODULE_AUTHOR("Realtek Corporation");
1055 +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822bu driver");
1056 +MODULE_LICENSE("Dual BSD/GPL");
1057 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822c.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822c.c
1058 --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2022-12-12 00:15:18.000000000 +0200
1059 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2022-12-24 00:49:25.775376835 +0200
1060 @@ -29,6 +29,12 @@ static void rtw8822ce_efuse_parsing(stru
1061 ether_addr_copy(efuse->addr, map->e.mac_addr);
1062 }
1063
1064 +static void rtw8822cu_efuse_parsing(struct rtw_efuse *efuse,
1065 + struct rtw8822c_efuse *map)
1066 +{
1067 + ether_addr_copy(efuse->addr, map->u.mac_addr);
1068 +}
1069 +
1070 static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
1071 {
1072 struct rtw_efuse *efuse = &rtwdev->efuse;
1073 @@ -58,6 +64,9 @@ static int rtw8822c_read_efuse(struct rt
1074 case RTW_HCI_TYPE_PCIE:
1075 rtw8822ce_efuse_parsing(efuse, map);
1076 break;
1077 + case RTW_HCI_TYPE_USB:
1078 + rtw8822cu_efuse_parsing(efuse, map);
1079 + break;
1080 default:
1081 /* unsupported now */
1082 return -ENOTSUPP;
1083 @@ -4557,6 +4566,18 @@ static void rtw8822c_adaptivity(struct r
1084 rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
1085 }
1086
1087 +static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
1088 + struct rtw_tx_pkt_info *pkt_info,
1089 + u8 *txdesc)
1090 +{
1091 + const struct rtw_chip_info *chip = rtwdev->chip;
1092 + size_t words;
1093 +
1094 + words = (pkt_info->pkt_offset * 8 + chip->tx_pkt_desc_sz) / 2;
1095 +
1096 + fill_txdesc_checksum_common(txdesc, words);
1097 +}
1098 +
1099 static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = {
1100 {0x0086,
1101 RTW_PWR_CUT_ALL_MSK,
1102 @@ -4895,6 +4916,8 @@ static const struct rtw_rfe_def rtw8822c
1103 [0] = RTW_DEF_RFE(8822c, 0, 0),
1104 [1] = RTW_DEF_RFE(8822c, 0, 0),
1105 [2] = RTW_DEF_RFE(8822c, 0, 0),
1106 + [3] = RTW_DEF_RFE(8822c, 0, 0),
1107 + [4] = RTW_DEF_RFE(8822c, 0, 0),
1108 [5] = RTW_DEF_RFE(8822c, 0, 5),
1109 [6] = RTW_DEF_RFE(8822c, 0, 0),
1110 };
1111 @@ -4978,6 +5001,7 @@ static struct rtw_chip_ops rtw8822c_ops
1112 .cfo_track = rtw8822c_cfo_track,
1113 .config_tx_path = rtw8822c_config_tx_path,
1114 .config_txrx_mode = rtw8822c_config_trx_mode,
1115 + .fill_txdesc_checksum = rtw8822c_fill_txdesc_checksum,
1116
1117 .coex_set_init = rtw8822c_coex_cfg_init,
1118 .coex_set_ant_switch = NULL,
1119 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822cu.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822cu.c
1120 --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822cu.c 1970-01-01 02:00:00.000000000 +0200
1121 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822cu.c 2022-12-24 00:49:25.775376835 +0200
1122 @@ -0,0 +1,44 @@
1123 +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
1124 +/* Copyright(c) 2018-2019 Realtek Corporation
1125 + */
1126 +
1127 +#include <linux/module.h>
1128 +#include <linux/usb.h>
1129 +#include "main.h"
1130 +#include "rtw8822c.h"
1131 +#include "usb.h"
1132 +
1133 +static const struct usb_device_id rtw_8822cu_id_table[] = {
1134 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82c, 0xff, 0xff, 0xff),
1135 + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
1136 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc812, 0xff, 0xff, 0xff),
1137 + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
1138 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82e, 0xff, 0xff, 0xff),
1139 + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
1140 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd820, 0xff, 0xff, 0xff),
1141 + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
1142 + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd82b, 0xff, 0xff, 0xff),
1143 + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
1144 + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff),
1145 + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* Alpha - Alpha */
1146 + {},
1147 +};
1148 +MODULE_DEVICE_TABLE(usb, rtw_8822cu_id_table);
1149 +
1150 +static int rtw8822bu_probe(struct usb_interface *intf,
1151 + const struct usb_device_id *id)
1152 +{
1153 + return rtw_usb_probe(intf, id);
1154 +}
1155 +
1156 +static struct usb_driver rtw_8822cu_driver = {
1157 + .name = "rtw_8822cu",
1158 + .id_table = rtw_8822cu_id_table,
1159 + .probe = rtw8822bu_probe,
1160 + .disconnect = rtw_usb_disconnect,
1161 +};
1162 +module_usb_driver(rtw_8822cu_driver);
1163 +
1164 +MODULE_AUTHOR("Realtek Corporation");
1165 +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cu driver");
1166 +MODULE_LICENSE("Dual BSD/GPL");
1167 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/tx.h linux-6.2/drivers/net/wireless/realtek/rtw88/tx.h
1168 --- linux-6.1/drivers/net/wireless/realtek/rtw88/tx.h 2022-12-12 00:15:18.000000000 +0200
1169 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/tx.h 2022-12-24 00:49:25.775376835 +0200
1170 @@ -71,6 +71,14 @@
1171 le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15))
1172 #define SET_TX_DESC_BT_NULL(txdesc, value) \
1173 le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23))
1174 +#define SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value) \
1175 + le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(15, 0))
1176 +#define SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value) \
1177 + le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(31, 24))
1178 +#define GET_TX_DESC_PKT_OFFSET(txdesc) \
1179 + le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(28, 24))
1180 +#define GET_TX_DESC_QSEL(txdesc) \
1181 + le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(12, 8))
1182
1183 enum rtw_tx_desc_queue_select {
1184 TX_DESC_QSEL_TID0 = 0,
1185 @@ -123,4 +131,27 @@ rtw_tx_write_data_h2c_get(struct rtw_dev
1186 struct rtw_tx_pkt_info *pkt_info,
1187 u8 *buf, u32 size);
1188
1189 +static inline
1190 +void fill_txdesc_checksum_common(u8 *txdesc, size_t words)
1191 +{
1192 + __le16 chksum = 0;
1193 + __le16 *data = (__le16 *)(txdesc);
1194 +
1195 + SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000);
1196 +
1197 + while (words--)
1198 + chksum ^= *data++;
1199 +
1200 + SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum));
1201 +}
1202 +
1203 +static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev,
1204 + struct rtw_tx_pkt_info *pkt_info,
1205 + u8 *txdesc)
1206 +{
1207 + const struct rtw_chip_info *chip = rtwdev->chip;
1208 +
1209 + chip->ops->fill_txdesc_checksum(rtwdev, pkt_info, txdesc);
1210 +}
1211 +
1212 #endif
1213 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/usb.c linux-6.2/drivers/net/wireless/realtek/rtw88/usb.c
1214 --- linux-6.1/drivers/net/wireless/realtek/rtw88/usb.c 1970-01-01 02:00:00.000000000 +0200
1215 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/usb.c 2022-12-24 00:49:25.775376835 +0200
1216 @@ -0,0 +1,911 @@
1217 +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
1218 +/* Copyright(c) 2018-2019 Realtek Corporation
1219 + */
1220 +
1221 +#include <linux/module.h>
1222 +#include <linux/usb.h>
1223 +#include <linux/mutex.h>
1224 +#include "main.h"
1225 +#include "debug.h"
1226 +#include "reg.h"
1227 +#include "tx.h"
1228 +#include "rx.h"
1229 +#include "fw.h"
1230 +#include "ps.h"
1231 +#include "usb.h"
1232 +
1233 +#define RTW_USB_MAX_RXQ_LEN 512
1234 +
1235 +struct rtw_usb_txcb {
1236 + struct rtw_dev *rtwdev;
1237 + struct sk_buff_head tx_ack_queue;
1238 +};
1239 +
1240 +static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb,
1241 + struct sk_buff *skb, int agg_num)
1242 +{
1243 + struct rtw_dev *rtwdev = rtwusb->rtwdev;
1244 + struct rtw_tx_pkt_info pkt_info;
1245 +
1246 + SET_TX_DESC_DMA_TXAGG_NUM(skb->data, agg_num);
1247 + pkt_info.pkt_offset = GET_TX_DESC_PKT_OFFSET(skb->data);
1248 + rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data);
1249 +}
1250 +
1251 +static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len)
1252 +{
1253 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1254 + struct usb_device *udev = rtwusb->udev;
1255 + __le32 *data;
1256 + unsigned long flags;
1257 + int idx, ret;
1258 + static int count;
1259 +
1260 + spin_lock_irqsave(&rtwusb->usb_lock, flags);
1261 +
1262 + idx = rtwusb->usb_data_index;
1263 + rtwusb->usb_data_index = (idx + 1) & (RTW_USB_MAX_RXTX_COUNT - 1);
1264 +
1265 + spin_unlock_irqrestore(&rtwusb->usb_lock, flags);
1266 +
1267 + data = &rtwusb->usb_data[idx];
1268 +
1269 + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
1270 + RTW_USB_CMD_REQ, RTW_USB_CMD_READ, addr,
1271 + RTW_USB_VENQT_CMD_IDX, data, len, 1000);
1272 + if (ret < 0 && ret != -ENODEV && count++ < 4)
1273 + rtw_err(rtwdev, "read register 0x%x failed with %d\n",
1274 + addr, ret);
1275 +
1276 + return le32_to_cpu(*data);
1277 +}
1278 +
1279 +static u8 rtw_usb_read8(struct rtw_dev *rtwdev, u32 addr)
1280 +{
1281 + return (u8)rtw_usb_read(rtwdev, addr, 1);
1282 +}
1283 +
1284 +static u16 rtw_usb_read16(struct rtw_dev *rtwdev, u32 addr)
1285 +{
1286 + return (u16)rtw_usb_read(rtwdev, addr, 2);
1287 +}
1288 +
1289 +static u32 rtw_usb_read32(struct rtw_dev *rtwdev, u32 addr)
1290 +{
1291 + return (u32)rtw_usb_read(rtwdev, addr, 4);
1292 +}
1293 +
1294 +static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len)
1295 +{
1296 + struct rtw_usb *rtwusb = (struct rtw_usb *)rtwdev->priv;
1297 + struct usb_device *udev = rtwusb->udev;
1298 + unsigned long flags;
1299 + __le32 *data;
1300 + int idx, ret;
1301 + static int count;
1302 +
1303 + spin_lock_irqsave(&rtwusb->usb_lock, flags);
1304 +
1305 + idx = rtwusb->usb_data_index;
1306 + rtwusb->usb_data_index = (idx + 1) & (RTW_USB_MAX_RXTX_COUNT - 1);
1307 +
1308 + spin_unlock_irqrestore(&rtwusb->usb_lock, flags);
1309 +
1310 + data = &rtwusb->usb_data[idx];
1311 +
1312 + *data = cpu_to_le32(val);
1313 +
1314 + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
1315 + RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE,
1316 + addr, 0, data, len, 30000);
1317 + if (ret < 0 && ret != -ENODEV && count++ < 4)
1318 + rtw_err(rtwdev, "write register 0x%x failed with %d\n",
1319 + addr, ret);
1320 +}
1321 +
1322 +static void rtw_usb_write8(struct rtw_dev *rtwdev, u32 addr, u8 val)
1323 +{
1324 + rtw_usb_write(rtwdev, addr, val, 1);
1325 +}
1326 +
1327 +static void rtw_usb_write16(struct rtw_dev *rtwdev, u32 addr, u16 val)
1328 +{
1329 + rtw_usb_write(rtwdev, addr, val, 2);
1330 +}
1331 +
1332 +static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val)
1333 +{
1334 + rtw_usb_write(rtwdev, addr, val, 4);
1335 +}
1336 +
1337 +static int rtw_usb_parse(struct rtw_dev *rtwdev,
1338 + struct usb_interface *interface)
1339 +{
1340 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1341 + struct usb_host_interface *host_interface = &interface->altsetting[0];
1342 + struct usb_interface_descriptor *interface_desc = &host_interface->desc;
1343 + struct usb_endpoint_descriptor *endpoint;
1344 + struct usb_device *usbd = interface_to_usbdev(interface);
1345 + int num_out_pipes = 0;
1346 + int i;
1347 + u8 num;
1348 +
1349 + for (i = 0; i < interface_desc->bNumEndpoints; i++) {
1350 + endpoint = &host_interface->endpoint[i].desc;
1351 + num = usb_endpoint_num(endpoint);
1352 +
1353 + if (usb_endpoint_dir_in(endpoint) &&
1354 + usb_endpoint_xfer_bulk(endpoint)) {
1355 + if (rtwusb->pipe_in) {
1356 + rtw_err(rtwdev, "IN pipes overflow\n");
1357 + return -EINVAL;
1358 + }
1359 +
1360 + rtwusb->pipe_in = num;
1361 + }
1362 +
1363 + if (usb_endpoint_dir_in(endpoint) &&
1364 + usb_endpoint_xfer_int(endpoint)) {
1365 + if (rtwusb->pipe_interrupt) {
1366 + rtw_err(rtwdev, "INT pipes overflow\n");
1367 + return -EINVAL;
1368 + }
1369 +
1370 + rtwusb->pipe_interrupt = num;
1371 + }
1372 +
1373 + if (usb_endpoint_dir_out(endpoint) &&
1374 + usb_endpoint_xfer_bulk(endpoint)) {
1375 + if (num_out_pipes >= ARRAY_SIZE(rtwusb->out_ep)) {
1376 + rtw_err(rtwdev, "OUT pipes overflow\n");
1377 + return -EINVAL;
1378 + }
1379 +
1380 + rtwusb->out_ep[num_out_pipes++] = num;
1381 + }
1382 + }
1383 +
1384 + switch (usbd->speed) {
1385 + case USB_SPEED_LOW:
1386 + case USB_SPEED_FULL:
1387 + rtwusb->bulkout_size = RTW_USB_FULL_SPEED_BULK_SIZE;
1388 + break;
1389 + case USB_SPEED_HIGH:
1390 + rtwusb->bulkout_size = RTW_USB_HIGH_SPEED_BULK_SIZE;
1391 + break;
1392 + case USB_SPEED_SUPER:
1393 + rtwusb->bulkout_size = RTW_USB_SUPER_SPEED_BULK_SIZE;
1394 + break;
1395 + default:
1396 + rtw_err(rtwdev, "failed to detect usb speed\n");
1397 + return -EINVAL;
1398 + }
1399 +
1400 + rtwdev->hci.bulkout_num = num_out_pipes;
1401 +
1402 + switch (num_out_pipes) {
1403 + case 4:
1404 + case 3:
1405 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 2;
1406 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 2;
1407 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 2;
1408 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 2;
1409 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = 1;
1410 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = 1;
1411 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = 0;
1412 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = 0;
1413 + break;
1414 + case 2:
1415 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 1;
1416 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 1;
1417 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 1;
1418 + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 1;
1419 + break;
1420 + case 1:
1421 + break;
1422 + default:
1423 + rtw_err(rtwdev, "failed to get out_pipes(%d)\n", num_out_pipes);
1424 + return -EINVAL;
1425 + }
1426 +
1427 + return 0;
1428 +}
1429 +
1430 +static void rtw_usb_write_port_tx_complete(struct urb *urb)
1431 +{
1432 + struct rtw_usb_txcb *txcb = urb->context;
1433 + struct rtw_dev *rtwdev = txcb->rtwdev;
1434 + struct ieee80211_hw *hw = rtwdev->hw;
1435 +
1436 + while (true) {
1437 + struct sk_buff *skb = skb_dequeue(&txcb->tx_ack_queue);
1438 + struct ieee80211_tx_info *info;
1439 + struct rtw_usb_tx_data *tx_data;
1440 +
1441 + if (!skb)
1442 + break;
1443 +
1444 + info = IEEE80211_SKB_CB(skb);
1445 + tx_data = rtw_usb_get_tx_data(skb);
1446 +
1447 + /* enqueue to wait for tx report */
1448 + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
1449 + rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn);
1450 + continue;
1451 + }
1452 +
1453 + /* always ACK for others, then they won't be marked as drop */
1454 + ieee80211_tx_info_clear_status(info);
1455 + if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1456 + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
1457 + else
1458 + info->flags |= IEEE80211_TX_STAT_ACK;
1459 +
1460 + ieee80211_tx_status_irqsafe(hw, skb);
1461 + }
1462 +
1463 + kfree(txcb);
1464 +}
1465 +
1466 +static int qsel_to_ep(struct rtw_usb *rtwusb, unsigned int qsel)
1467 +{
1468 + if (qsel >= ARRAY_SIZE(rtwusb->qsel_to_ep))
1469 + return 0;
1470 +
1471 + return rtwusb->qsel_to_ep[qsel];
1472 +}
1473 +
1474 +static int rtw_usb_write_port(struct rtw_dev *rtwdev, u8 qsel, struct sk_buff *skb,
1475 + usb_complete_t cb, void *context)
1476 +{
1477 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1478 + struct usb_device *usbd = rtwusb->udev;
1479 + struct urb *urb;
1480 + unsigned int pipe;
1481 + int ret;
1482 + int ep = qsel_to_ep(rtwusb, qsel);
1483 +
1484 + pipe = usb_sndbulkpipe(usbd, rtwusb->out_ep[ep]);
1485 + urb = usb_alloc_urb(0, GFP_ATOMIC);
1486 + if (!urb)
1487 + return -ENOMEM;
1488 +
1489 + usb_fill_bulk_urb(urb, usbd, pipe, skb->data, skb->len, cb, context);
1490 + ret = usb_submit_urb(urb, GFP_ATOMIC);
1491 +
1492 + usb_free_urb(urb);
1493 +
1494 + return ret;
1495 +}
1496 +
1497 +static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list)
1498 +{
1499 + struct rtw_dev *rtwdev = rtwusb->rtwdev;
1500 + struct rtw_usb_txcb *txcb;
1501 + struct sk_buff *skb_head;
1502 + struct sk_buff *skb_iter;
1503 + int agg_num = 0;
1504 + unsigned int align_next = 0;
1505 +
1506 + if (skb_queue_empty(list))
1507 + return false;
1508 +
1509 + txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC);
1510 + if (!txcb)
1511 + return false;
1512 +
1513 + txcb->rtwdev = rtwdev;
1514 + skb_queue_head_init(&txcb->tx_ack_queue);
1515 +
1516 + skb_iter = skb_dequeue(list);
1517 +
1518 + if (skb_queue_empty(list)) {
1519 + skb_head = skb_iter;
1520 + goto queue;
1521 + }
1522 +
1523 + skb_head = dev_alloc_skb(RTW_USB_MAX_XMITBUF_SZ);
1524 + if (!skb_head) {
1525 + skb_head = skb_iter;
1526 + goto queue;
1527 + }
1528 +
1529 + while (skb_iter) {
1530 + unsigned long flags;
1531 +
1532 + skb_put(skb_head, align_next);
1533 + skb_put_data(skb_head, skb_iter->data, skb_iter->len);
1534 +
1535 + align_next = ALIGN(skb_iter->len, 8) - skb_iter->len;
1536 +
1537 + agg_num++;
1538 +
1539 + skb_queue_tail(&txcb->tx_ack_queue, skb_iter);
1540 +
1541 + spin_lock_irqsave(&list->lock, flags);
1542 +
1543 + skb_iter = skb_peek(list);
1544 +
1545 + if (skb_iter && skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ)
1546 + __skb_unlink(skb_iter, list);
1547 + else
1548 + skb_iter = NULL;
1549 + spin_unlock_irqrestore(&list->lock, flags);
1550 + }
1551 +
1552 + if (agg_num > 1)
1553 + rtw_usb_fill_tx_checksum(rtwusb, skb_head, agg_num);
1554 +
1555 +queue:
1556 + skb_queue_tail(&txcb->tx_ack_queue, skb_head);
1557 +
1558 + rtw_usb_write_port(rtwdev, GET_TX_DESC_QSEL(skb_head->data), skb_head,
1559 + rtw_usb_write_port_tx_complete, txcb);
1560 +
1561 + return true;
1562 +}
1563 +
1564 +static void rtw_usb_tx_handler(struct work_struct *work)
1565 +{
1566 + struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, tx_work);
1567 + int i, limit;
1568 +
1569 + for (i = ARRAY_SIZE(rtwusb->tx_queue) - 1; i >= 0; i--) {
1570 + for (limit = 0; limit < 200; limit++) {
1571 + struct sk_buff_head *list = &rtwusb->tx_queue[i];
1572 +
1573 + if (!rtw_usb_tx_agg_skb(rtwusb, list))
1574 + break;
1575 + }
1576 + }
1577 +}
1578 +
1579 +static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb)
1580 +{
1581 + int i;
1582 +
1583 + for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++)
1584 + skb_queue_purge(&rtwusb->tx_queue[i]);
1585 +}
1586 +
1587 +static void rtw_usb_write_port_complete(struct urb *urb)
1588 +{
1589 + struct sk_buff *skb = urb->context;
1590 +
1591 + dev_kfree_skb_any(skb);
1592 +}
1593 +
1594 +static int rtw_usb_write_data(struct rtw_dev *rtwdev,
1595 + struct rtw_tx_pkt_info *pkt_info,
1596 + u8 *buf)
1597 +{
1598 + const struct rtw_chip_info *chip = rtwdev->chip;
1599 + struct sk_buff *skb;
1600 + unsigned int desclen, headsize, size;
1601 + u8 qsel;
1602 + int ret = 0;
1603 +
1604 + size = pkt_info->tx_pkt_size;
1605 + qsel = pkt_info->qsel;
1606 + desclen = chip->tx_pkt_desc_sz;
1607 + headsize = pkt_info->offset ? pkt_info->offset : desclen;
1608 +
1609 + skb = dev_alloc_skb(headsize + size);
1610 + if (unlikely(!skb))
1611 + return -ENOMEM;
1612 +
1613 + skb_reserve(skb, headsize);
1614 + skb_put_data(skb, buf, size);
1615 + skb_push(skb, headsize);
1616 + memset(skb->data, 0, headsize);
1617 + rtw_tx_fill_tx_desc(pkt_info, skb);
1618 + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
1619 +
1620 + ret = rtw_usb_write_port(rtwdev, qsel, skb,
1621 + rtw_usb_write_port_complete, skb);
1622 + if (unlikely(ret))
1623 + rtw_err(rtwdev, "failed to do USB write, ret=%d\n", ret);
1624 +
1625 + return ret;
1626 +}
1627 +
1628 +static int rtw_usb_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf,
1629 + u32 size)
1630 +{
1631 + const struct rtw_chip_info *chip = rtwdev->chip;
1632 + struct rtw_usb *rtwusb;
1633 + struct rtw_tx_pkt_info pkt_info = {0};
1634 + u32 len, desclen;
1635 +
1636 + rtwusb = rtw_get_usb_priv(rtwdev);
1637 +
1638 + pkt_info.tx_pkt_size = size;
1639 + pkt_info.qsel = TX_DESC_QSEL_BEACON;
1640 +
1641 + desclen = chip->tx_pkt_desc_sz;
1642 + len = desclen + size;
1643 + if (len % rtwusb->bulkout_size == 0) {
1644 + len += RTW_USB_PACKET_OFFSET_SZ;
1645 + pkt_info.offset = desclen + RTW_USB_PACKET_OFFSET_SZ;
1646 + pkt_info.pkt_offset = 1;
1647 + } else {
1648 + pkt_info.offset = desclen;
1649 + }
1650 +
1651 + return rtw_usb_write_data(rtwdev, &pkt_info, buf);
1652 +}
1653 +
1654 +static int rtw_usb_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size)
1655 +{
1656 + struct rtw_tx_pkt_info pkt_info = {0};
1657 +
1658 + pkt_info.tx_pkt_size = size;
1659 + pkt_info.qsel = TX_DESC_QSEL_H2C;
1660 +
1661 + return rtw_usb_write_data(rtwdev, &pkt_info, buf);
1662 +}
1663 +
1664 +static u8 rtw_usb_tx_queue_mapping_to_qsel(struct sk_buff *skb)
1665 +{
1666 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1667 + __le16 fc = hdr->frame_control;
1668 + u8 qsel;
1669 +
1670 + if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)))
1671 + qsel = TX_DESC_QSEL_MGMT;
1672 + else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK)
1673 + qsel = skb->priority;
1674 + else
1675 + qsel = TX_DESC_QSEL_BEACON;
1676 +
1677 + return qsel;
1678 +}
1679 +
1680 +static int rtw_usb_tx_write(struct rtw_dev *rtwdev,
1681 + struct rtw_tx_pkt_info *pkt_info,
1682 + struct sk_buff *skb)
1683 +{
1684 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1685 + const struct rtw_chip_info *chip = rtwdev->chip;
1686 + struct rtw_usb_tx_data *tx_data;
1687 + u8 *pkt_desc;
1688 + int ep;
1689 +
1690 + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
1691 + memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
1692 + pkt_info->qsel = rtw_usb_tx_queue_mapping_to_qsel(skb);
1693 + ep = qsel_to_ep(rtwusb, pkt_info->qsel);
1694 + rtw_tx_fill_tx_desc(pkt_info, skb);
1695 + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
1696 + tx_data = rtw_usb_get_tx_data(skb);
1697 + tx_data->sn = pkt_info->sn;
1698 +
1699 + skb_queue_tail(&rtwusb->tx_queue[ep], skb);
1700 +
1701 + return 0;
1702 +}
1703 +
1704 +static void rtw_usb_tx_kick_off(struct rtw_dev *rtwdev)
1705 +{
1706 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1707 +
1708 + queue_work(rtwusb->txwq, &rtwusb->tx_work);
1709 +}
1710 +
1711 +static void rtw_usb_rx_handler(struct work_struct *work)
1712 +{
1713 + struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work);
1714 + struct rtw_dev *rtwdev = rtwusb->rtwdev;
1715 + const struct rtw_chip_info *chip = rtwdev->chip;
1716 + struct rtw_rx_pkt_stat pkt_stat;
1717 + struct ieee80211_rx_status rx_status;
1718 + struct sk_buff *skb;
1719 + u32 pkt_desc_sz = chip->rx_pkt_desc_sz;
1720 + u32 pkt_offset;
1721 + u8 *rx_desc;
1722 + int limit;
1723 +
1724 + for (limit = 0; limit < 200; limit++) {
1725 + skb = skb_dequeue(&rtwusb->rx_queue);
1726 + if (!skb)
1727 + break;
1728 +
1729 + rx_desc = skb->data;
1730 + chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
1731 + &rx_status);
1732 + pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
1733 + pkt_stat.shift;
1734 +
1735 + if (pkt_stat.is_c2h) {
1736 + skb_put(skb, pkt_stat.pkt_len + pkt_offset);
1737 + rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb);
1738 + continue;
1739 + }
1740 +
1741 + if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) {
1742 + rtw_err(rtwdev, "failed to get rx_queue, overflow\n");
1743 + dev_kfree_skb_any(skb);
1744 + continue;
1745 + }
1746 +
1747 + skb_put(skb, pkt_stat.pkt_len);
1748 + skb_reserve(skb, pkt_offset);
1749 + memcpy(skb->cb, &rx_status, sizeof(rx_status));
1750 + ieee80211_rx_irqsafe(rtwdev->hw, skb);
1751 + }
1752 +}
1753 +
1754 +static void rtw_usb_read_port_complete(struct urb *urb);
1755 +
1756 +static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb, struct rx_usb_ctrl_block *rxcb)
1757 +{
1758 + struct rtw_dev *rtwdev = rtwusb->rtwdev;
1759 + int error;
1760 +
1761 + rxcb->rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_ATOMIC);
1762 + if (!rxcb->rx_skb)
1763 + return;
1764 +
1765 + usb_fill_bulk_urb(rxcb->rx_urb, rtwusb->udev,
1766 + usb_rcvbulkpipe(rtwusb->udev, rtwusb->pipe_in),
1767 + rxcb->rx_skb->data, RTW_USB_MAX_RECVBUF_SZ,
1768 + rtw_usb_read_port_complete, rxcb);
1769 +
1770 + error = usb_submit_urb(rxcb->rx_urb, GFP_ATOMIC);
1771 + if (error) {
1772 + kfree_skb(rxcb->rx_skb);
1773 + if (error != -ENODEV)
1774 + rtw_err(rtwdev, "Err sending rx data urb %d\n",
1775 + error);
1776 + }
1777 +}
1778 +
1779 +static void rtw_usb_read_port_complete(struct urb *urb)
1780 +{
1781 + struct rx_usb_ctrl_block *rxcb = urb->context;
1782 + struct rtw_dev *rtwdev = rxcb->rtwdev;
1783 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1784 + struct sk_buff *skb = rxcb->rx_skb;
1785 +
1786 + if (urb->status == 0) {
1787 + if (urb->actual_length >= RTW_USB_MAX_RECVBUF_SZ ||
1788 + urb->actual_length < 24) {
1789 + rtw_err(rtwdev, "failed to get urb length:%d\n",
1790 + urb->actual_length);
1791 + if (skb)
1792 + dev_kfree_skb_any(skb);
1793 + } else {
1794 + skb_queue_tail(&rtwusb->rx_queue, skb);
1795 + queue_work(rtwusb->rxwq, &rtwusb->rx_work);
1796 + }
1797 + rtw_usb_rx_resubmit(rtwusb, rxcb);
1798 + } else {
1799 + switch (urb->status) {
1800 + case -EINVAL:
1801 + case -EPIPE:
1802 + case -ENODEV:
1803 + case -ESHUTDOWN:
1804 + case -ENOENT:
1805 + case -EPROTO:
1806 + case -EILSEQ:
1807 + case -ETIME:
1808 + case -ECOMM:
1809 + case -EOVERFLOW:
1810 + case -EINPROGRESS:
1811 + break;
1812 + default:
1813 + rtw_err(rtwdev, "status %d\n", urb->status);
1814 + break;
1815 + }
1816 + if (skb)
1817 + dev_kfree_skb_any(skb);
1818 + }
1819 +}
1820 +
1821 +static void rtw_usb_cancel_rx_bufs(struct rtw_usb *rtwusb)
1822 +{
1823 + struct rx_usb_ctrl_block *rxcb;
1824 + int i;
1825 +
1826 + for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
1827 + rxcb = &rtwusb->rx_cb[i];
1828 + if (rxcb->rx_urb)
1829 + usb_kill_urb(rxcb->rx_urb);
1830 + }
1831 +}
1832 +
1833 +static void rtw_usb_free_rx_bufs(struct rtw_usb *rtwusb)
1834 +{
1835 + struct rx_usb_ctrl_block *rxcb;
1836 + int i;
1837 +
1838 + for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
1839 + rxcb = &rtwusb->rx_cb[i];
1840 + if (rxcb->rx_urb) {
1841 + usb_kill_urb(rxcb->rx_urb);
1842 + usb_free_urb(rxcb->rx_urb);
1843 + }
1844 + }
1845 +}
1846 +
1847 +static int rtw_usb_alloc_rx_bufs(struct rtw_usb *rtwusb)
1848 +{
1849 + int i;
1850 +
1851 + for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
1852 + struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i];
1853 +
1854 + rxcb->n = i;
1855 + rxcb->rtwdev = rtwusb->rtwdev;
1856 + rxcb->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
1857 + if (!rxcb->rx_urb)
1858 + goto err;
1859 + }
1860 +
1861 + return 0;
1862 +err:
1863 + rtw_usb_free_rx_bufs(rtwusb);
1864 + return -ENOMEM;
1865 +}
1866 +
1867 +static int rtw_usb_setup(struct rtw_dev *rtwdev)
1868 +{
1869 + /* empty function for rtw_hci_ops */
1870 + return 0;
1871 +}
1872 +
1873 +static int rtw_usb_start(struct rtw_dev *rtwdev)
1874 +{
1875 + return 0;
1876 +}
1877 +
1878 +static void rtw_usb_stop(struct rtw_dev *rtwdev)
1879 +{
1880 +}
1881 +
1882 +static void rtw_usb_deep_ps(struct rtw_dev *rtwdev, bool enter)
1883 +{
1884 + /* empty function for rtw_hci_ops */
1885 +}
1886 +
1887 +static void rtw_usb_link_ps(struct rtw_dev *rtwdev, bool enter)
1888 +{
1889 + /* empty function for rtw_hci_ops */
1890 +}
1891 +
1892 +static void rtw_usb_interface_cfg(struct rtw_dev *rtwdev)
1893 +{
1894 + /* empty function for rtw_hci_ops */
1895 +}
1896 +
1897 +static struct rtw_hci_ops rtw_usb_ops = {
1898 + .tx_write = rtw_usb_tx_write,
1899 + .tx_kick_off = rtw_usb_tx_kick_off,
1900 + .setup = rtw_usb_setup,
1901 + .start = rtw_usb_start,
1902 + .stop = rtw_usb_stop,
1903 + .deep_ps = rtw_usb_deep_ps,
1904 + .link_ps = rtw_usb_link_ps,
1905 + .interface_cfg = rtw_usb_interface_cfg,
1906 +
1907 + .write8 = rtw_usb_write8,
1908 + .write16 = rtw_usb_write16,
1909 + .write32 = rtw_usb_write32,
1910 + .read8 = rtw_usb_read8,
1911 + .read16 = rtw_usb_read16,
1912 + .read32 = rtw_usb_read32,
1913 +
1914 + .write_data_rsvd_page = rtw_usb_write_data_rsvd_page,
1915 + .write_data_h2c = rtw_usb_write_data_h2c,
1916 +};
1917 +
1918 +static int rtw_usb_init_rx(struct rtw_dev *rtwdev)
1919 +{
1920 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1921 + int i;
1922 +
1923 + rtwusb->rxwq = create_singlethread_workqueue("rtw88_usb: rx wq");
1924 + if (!rtwusb->rxwq) {
1925 + rtw_err(rtwdev, "failed to create RX work queue\n");
1926 + return -ENOMEM;
1927 + }
1928 +
1929 + skb_queue_head_init(&rtwusb->rx_queue);
1930 +
1931 + INIT_WORK(&rtwusb->rx_work, rtw_usb_rx_handler);
1932 +
1933 + for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
1934 + struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i];
1935 +
1936 + rtw_usb_rx_resubmit(rtwusb, rxcb);
1937 + }
1938 +
1939 + return 0;
1940 +}
1941 +
1942 +static void rtw_usb_deinit_rx(struct rtw_dev *rtwdev)
1943 +{
1944 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1945 +
1946 + skb_queue_purge(&rtwusb->rx_queue);
1947 +
1948 + flush_workqueue(rtwusb->rxwq);
1949 + destroy_workqueue(rtwusb->rxwq);
1950 +}
1951 +
1952 +static int rtw_usb_init_tx(struct rtw_dev *rtwdev)
1953 +{
1954 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1955 + int i;
1956 +
1957 + rtwusb->txwq = create_singlethread_workqueue("rtw88_usb: tx wq");
1958 + if (!rtwusb->txwq) {
1959 + rtw_err(rtwdev, "failed to create TX work queue\n");
1960 + return -ENOMEM;
1961 + }
1962 +
1963 + for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++)
1964 + skb_queue_head_init(&rtwusb->tx_queue[i]);
1965 +
1966 + INIT_WORK(&rtwusb->tx_work, rtw_usb_tx_handler);
1967 +
1968 + return 0;
1969 +}
1970 +
1971 +static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev)
1972 +{
1973 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1974 +
1975 + rtw_usb_tx_queue_purge(rtwusb);
1976 + flush_workqueue(rtwusb->txwq);
1977 + destroy_workqueue(rtwusb->txwq);
1978 +}
1979 +
1980 +static int rtw_usb_intf_init(struct rtw_dev *rtwdev,
1981 + struct usb_interface *intf)
1982 +{
1983 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1984 + struct usb_device *udev = usb_get_dev(interface_to_usbdev(intf));
1985 + int ret;
1986 +
1987 + rtwusb->udev = udev;
1988 + ret = rtw_usb_parse(rtwdev, intf);
1989 + if (ret)
1990 + return ret;
1991 +
1992 + rtwusb->usb_data = kcalloc(RTW_USB_MAX_RXTX_COUNT, sizeof(u32),
1993 + GFP_KERNEL);
1994 + if (!rtwusb->usb_data)
1995 + return -ENOMEM;
1996 +
1997 + usb_set_intfdata(intf, rtwdev->hw);
1998 +
1999 + SET_IEEE80211_DEV(rtwdev->hw, &intf->dev);
2000 + spin_lock_init(&rtwusb->usb_lock);
2001 +
2002 + return 0;
2003 +}
2004 +
2005 +static void rtw_usb_intf_deinit(struct rtw_dev *rtwdev,
2006 + struct usb_interface *intf)
2007 +{
2008 + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
2009 +
2010 + usb_put_dev(rtwusb->udev);
2011 + usb_set_intfdata(intf, NULL);
2012 +}
2013 +
2014 +int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
2015 +{
2016 + struct rtw_dev *rtwdev;
2017 + struct ieee80211_hw *hw;
2018 + struct rtw_usb *rtwusb;
2019 + int drv_data_size;
2020 + int ret;
2021 +
2022 + drv_data_size = sizeof(struct rtw_dev) + sizeof(struct rtw_usb);
2023 + hw = ieee80211_alloc_hw(drv_data_size, &rtw_ops);
2024 + if (!hw)
2025 + return -ENOMEM;
2026 +
2027 + rtwdev = hw->priv;
2028 + rtwdev->hw = hw;
2029 + rtwdev->dev = &intf->dev;
2030 + rtwdev->chip = (struct rtw_chip_info *)id->driver_info;
2031 + rtwdev->hci.ops = &rtw_usb_ops;
2032 + rtwdev->hci.type = RTW_HCI_TYPE_USB;
2033 +
2034 + rtwusb = rtw_get_usb_priv(rtwdev);
2035 + rtwusb->rtwdev = rtwdev;
2036 +
2037 + ret = rtw_usb_alloc_rx_bufs(rtwusb);
2038 + if (ret)
2039 + return ret;
2040 +
2041 + ret = rtw_core_init(rtwdev);
2042 + if (ret)
2043 + goto err_release_hw;
2044 +
2045 + ret = rtw_usb_intf_init(rtwdev, intf);
2046 + if (ret) {
2047 + rtw_err(rtwdev, "failed to init USB interface\n");
2048 + goto err_deinit_core;
2049 + }
2050 +
2051 + ret = rtw_usb_init_tx(rtwdev);
2052 + if (ret) {
2053 + rtw_err(rtwdev, "failed to init USB TX\n");
2054 + goto err_destroy_usb;
2055 + }
2056 +
2057 + ret = rtw_usb_init_rx(rtwdev);
2058 + if (ret) {
2059 + rtw_err(rtwdev, "failed to init USB RX\n");
2060 + goto err_destroy_txwq;
2061 + }
2062 +
2063 + ret = rtw_chip_info_setup(rtwdev);
2064 + if (ret) {
2065 + rtw_err(rtwdev, "failed to setup chip information\n");
2066 + goto err_destroy_rxwq;
2067 + }
2068 +
2069 + ret = rtw_register_hw(rtwdev, rtwdev->hw);
2070 + if (ret) {
2071 + rtw_err(rtwdev, "failed to register hw\n");
2072 + goto err_destroy_rxwq;
2073 + }
2074 +
2075 + return 0;
2076 +
2077 +err_destroy_rxwq:
2078 + rtw_usb_deinit_rx(rtwdev);
2079 +
2080 +err_destroy_txwq:
2081 + rtw_usb_deinit_tx(rtwdev);
2082 +
2083 +err_destroy_usb:
2084 + rtw_usb_intf_deinit(rtwdev, intf);
2085 +
2086 +err_deinit_core:
2087 + rtw_core_deinit(rtwdev);
2088 +
2089 +err_release_hw:
2090 + ieee80211_free_hw(hw);
2091 +
2092 + return ret;
2093 +}
2094 +EXPORT_SYMBOL(rtw_usb_probe);
2095 +
2096 +void rtw_usb_disconnect(struct usb_interface *intf)
2097 +{
2098 + struct ieee80211_hw *hw = usb_get_intfdata(intf);
2099 + struct rtw_dev *rtwdev;
2100 + struct rtw_usb *rtwusb;
2101 +
2102 + if (!hw)
2103 + return;
2104 +
2105 + rtwdev = hw->priv;
2106 + rtwusb = rtw_get_usb_priv(rtwdev);
2107 +
2108 + rtw_usb_cancel_rx_bufs(rtwusb);
2109 +
2110 + rtw_unregister_hw(rtwdev, hw);
2111 + rtw_usb_deinit_tx(rtwdev);
2112 + rtw_usb_deinit_rx(rtwdev);
2113 +
2114 + if (rtwusb->udev->state != USB_STATE_NOTATTACHED)
2115 + usb_reset_device(rtwusb->udev);
2116 +
2117 + rtw_usb_free_rx_bufs(rtwusb);
2118 +
2119 + rtw_usb_intf_deinit(rtwdev, intf);
2120 + rtw_core_deinit(rtwdev);
2121 + ieee80211_free_hw(hw);
2122 +}
2123 +EXPORT_SYMBOL(rtw_usb_disconnect);
2124 +
2125 +MODULE_AUTHOR("Realtek Corporation");
2126 +MODULE_DESCRIPTION("Realtek 802.11ac wireless USB driver");
2127 +MODULE_LICENSE("Dual BSD/GPL");
2128 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/usb.h linux-6.2/drivers/net/wireless/realtek/rtw88/usb.h
2129 --- linux-6.1/drivers/net/wireless/realtek/rtw88/usb.h 1970-01-01 02:00:00.000000000 +0200
2130 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/usb.h 2022-12-24 00:49:25.775376835 +0200
2131 @@ -0,0 +1,107 @@
2132 +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2133 +/* Copyright(c) 2018-2019 Realtek Corporation
2134 + */
2135 +
2136 +#ifndef __RTW_USB_H_
2137 +#define __RTW_USB_H_
2138 +
2139 +#define FW_8192C_START_ADDRESS 0x1000
2140 +#define FW_8192C_END_ADDRESS 0x5fff
2141 +
2142 +#define RTW_USB_MAX_RXTX_COUNT 128
2143 +#define RTW_USB_VENQT_MAX_BUF_SIZE 254
2144 +#define MAX_USBCTRL_VENDORREQ_TIMES 10
2145 +
2146 +#define RTW_USB_CMD_READ 0xc0
2147 +#define RTW_USB_CMD_WRITE 0x40
2148 +#define RTW_USB_CMD_REQ 0x05
2149 +
2150 +#define RTW_USB_VENQT_CMD_IDX 0x00
2151 +
2152 +#define RTW_USB_SUPER_SPEED_BULK_SIZE 1024
2153 +#define RTW_USB_HIGH_SPEED_BULK_SIZE 512
2154 +#define RTW_USB_FULL_SPEED_BULK_SIZE 64
2155 +
2156 +#define RTW_USB_TX_SEL_HQ BIT(0)
2157 +#define RTW_USB_TX_SEL_LQ BIT(1)
2158 +#define RTW_USB_TX_SEL_NQ BIT(2)
2159 +#define RTW_USB_TX_SEL_EQ BIT(3)
2160 +
2161 +#define RTW_USB_BULK_IN_ADDR 0x80
2162 +#define RTW_USB_INT_IN_ADDR 0x81
2163 +
2164 +#define RTW_USB_HW_QUEUE_ENTRY 8
2165 +
2166 +#define RTW_USB_PACKET_OFFSET_SZ 8
2167 +#define RTW_USB_MAX_XMITBUF_SZ (1024 * 20)
2168 +#define RTW_USB_MAX_RECVBUF_SZ 32768
2169 +
2170 +#define RTW_USB_RECVBUFF_ALIGN_SZ 8
2171 +
2172 +#define RTW_USB_RXAGG_SIZE 6
2173 +#define RTW_USB_RXAGG_TIMEOUT 10
2174 +
2175 +#define RTW_USB_RXCB_NUM 4
2176 +
2177 +#define RTW_USB_EP_MAX 4
2178 +
2179 +#define TX_DESC_QSEL_MAX 20
2180 +
2181 +#define RTW_USB_VENDOR_ID_REALTEK 0x0bda
2182 +
2183 +static inline struct rtw_usb *rtw_get_usb_priv(struct rtw_dev *rtwdev)
2184 +{
2185 + return (struct rtw_usb *)rtwdev->priv;
2186 +}
2187 +
2188 +struct rx_usb_ctrl_block {
2189 + struct rtw_dev *rtwdev;
2190 + struct urb *rx_urb;
2191 + struct sk_buff *rx_skb;
2192 + int n;
2193 +};
2194 +
2195 +struct rtw_usb_tx_data {
2196 + u8 sn;
2197 +};
2198 +
2199 +struct rtw_usb {
2200 + struct rtw_dev *rtwdev;
2201 + struct usb_device *udev;
2202 +
2203 + /* protects usb_data_index */
2204 + spinlock_t usb_lock;
2205 + __le32 *usb_data;
2206 + unsigned int usb_data_index;
2207 +
2208 + u32 bulkout_size;
2209 + u8 pipe_interrupt;
2210 + u8 pipe_in;
2211 + u8 out_ep[RTW_USB_EP_MAX];
2212 + u8 qsel_to_ep[TX_DESC_QSEL_MAX];
2213 + u8 usb_txagg_num;
2214 +
2215 + struct workqueue_struct *txwq, *rxwq;
2216 +
2217 + struct sk_buff_head tx_queue[RTW_USB_EP_MAX];
2218 + struct work_struct tx_work;
2219 +
2220 + struct rx_usb_ctrl_block rx_cb[RTW_USB_RXCB_NUM];
2221 + struct sk_buff_head rx_queue;
2222 + struct work_struct rx_work;
2223 +};
2224 +
2225 +static inline struct rtw_usb_tx_data *rtw_usb_get_tx_data(struct sk_buff *skb)
2226 +{
2227 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2228 +
2229 + BUILD_BUG_ON(sizeof(struct rtw_usb_tx_data) >
2230 + sizeof(info->status.status_driver_data));
2231 +
2232 + return (struct rtw_usb_tx_data *)info->status.status_driver_data;
2233 +}
2234 +
2235 +int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id);
2236 +void rtw_usb_disconnect(struct usb_interface *intf);
2237 +
2238 +#endif
2239 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/util.c linux-6.2/drivers/net/wireless/realtek/rtw88/util.c
2240 --- linux-6.1/drivers/net/wireless/realtek/rtw88/util.c 2022-12-12 00:15:18.000000000 +0200
2241 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/util.c 2022-12-24 00:49:25.775376835 +0200
2242 @@ -105,3 +105,106 @@ void rtw_desc_to_mcsrate(u16 rate, u8 *m
2243 *mcs = rate - DESC_RATEMCS0;
2244 }
2245 }
2246 +
2247 +struct rtw_stas_entry {
2248 + struct list_head list;
2249 + struct ieee80211_sta *sta;
2250 +};
2251 +
2252 +struct rtw_iter_stas_data {
2253 + struct rtw_dev *rtwdev;
2254 + struct list_head list;
2255 +};
2256 +
2257 +static void rtw_collect_sta_iter(void *data, struct ieee80211_sta *sta)
2258 +{
2259 + struct rtw_iter_stas_data *iter_stas = data;
2260 + struct rtw_stas_entry *stas_entry;
2261 +
2262 + stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC);
2263 + if (!stas_entry)
2264 + return;
2265 +
2266 + stas_entry->sta = sta;
2267 + list_add_tail(&stas_entry->list, &iter_stas->list);
2268 +}
2269 +
2270 +void rtw_iterate_stas(struct rtw_dev *rtwdev,
2271 + void (*iterator)(void *data,
2272 + struct ieee80211_sta *sta),
2273 + void *data)
2274 +{
2275 + struct rtw_iter_stas_data iter_data;
2276 + struct rtw_stas_entry *sta_entry, *tmp;
2277 +
2278 + /* &rtwdev->mutex makes sure no stations can be removed between
2279 + * collecting the stations and iterating over them.
2280 + */
2281 + lockdep_assert_held(&rtwdev->mutex);
2282 +
2283 + iter_data.rtwdev = rtwdev;
2284 + INIT_LIST_HEAD(&iter_data.list);
2285 +
2286 + ieee80211_iterate_stations_atomic(rtwdev->hw, rtw_collect_sta_iter,
2287 + &iter_data);
2288 +
2289 + list_for_each_entry_safe(sta_entry, tmp, &iter_data.list,
2290 + list) {
2291 + list_del_init(&sta_entry->list);
2292 + iterator(data, sta_entry->sta);
2293 + kfree(sta_entry);
2294 + }
2295 +}
2296 +
2297 +struct rtw_vifs_entry {
2298 + struct list_head list;
2299 + struct ieee80211_vif *vif;
2300 + u8 mac[ETH_ALEN];
2301 +};
2302 +
2303 +struct rtw_iter_vifs_data {
2304 + struct rtw_dev *rtwdev;
2305 + struct list_head list;
2306 +};
2307 +
2308 +static void rtw_collect_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
2309 +{
2310 + struct rtw_iter_vifs_data *iter_stas = data;
2311 + struct rtw_vifs_entry *vifs_entry;
2312 +
2313 + vifs_entry = kmalloc(sizeof(*vifs_entry), GFP_ATOMIC);
2314 + if (!vifs_entry)
2315 + return;
2316 +
2317 + vifs_entry->vif = vif;
2318 + ether_addr_copy(vifs_entry->mac, mac);
2319 + list_add_tail(&vifs_entry->list, &iter_stas->list);
2320 +}
2321 +
2322 +void rtw_iterate_vifs(struct rtw_dev *rtwdev,
2323 + void (*iterator)(void *data, u8 *mac,
2324 + struct ieee80211_vif *vif),
2325 + void *data)
2326 +{
2327 + struct rtw_iter_vifs_data iter_data;
2328 + struct rtw_vifs_entry *vif_entry, *tmp;
2329 +
2330 + /* &rtwdev->mutex makes sure no interfaces can be removed between
2331 + * collecting the interfaces and iterating over them.
2332 + */
2333 + lockdep_assert_held(&rtwdev->mutex);
2334 +
2335 + iter_data.rtwdev = rtwdev;
2336 + INIT_LIST_HEAD(&iter_data.list);
2337 +
2338 + ieee80211_iterate_active_interfaces_atomic(rtwdev->hw,
2339 + IEEE80211_IFACE_ITER_NORMAL,
2340 + rtw_collect_vif_iter, &iter_data);
2341 +
2342 + list_for_each_entry_safe(vif_entry, tmp, &iter_data.list,
2343 + list) {
2344 + list_del_init(&vif_entry->list);
2345 + iterator(data, vif_entry->mac, vif_entry->vif);
2346 + kfree(vif_entry);
2347 + }
2348 +}
2349 diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/util.h linux-6.2/drivers/net/wireless/realtek/rtw88/util.h
2350 --- linux-6.1/drivers/net/wireless/realtek/rtw88/util.h 2022-12-12 00:15:18.000000000 +0200
2351 +++ linux-6.2/drivers/net/wireless/realtek/rtw88/util.h 2022-12-24 00:49:25.775376835 +0200
2352 @@ -7,9 +7,6 @@
2353
2354 struct rtw_dev;
2355
2356 -#define rtw_iterate_vifs(rtwdev, iterator, data) \
2357 - ieee80211_iterate_active_interfaces(rtwdev->hw, \
2358 - IEEE80211_IFACE_ITER_NORMAL, iterator, data)
2359 #define rtw_iterate_vifs_atomic(rtwdev, iterator, data) \
2360 ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, \
2361 IEEE80211_IFACE_ITER_NORMAL, iterator, data)
2362 @@ -20,6 +17,15 @@ struct rtw_dev;
2363 #define rtw_iterate_keys_rcu(rtwdev, vif, iterator, data) \
2364 ieee80211_iter_keys_rcu((rtwdev)->hw, vif, iterator, data)
2365
2366 +void rtw_iterate_vifs(struct rtw_dev *rtwdev,
2367 + void (*iterator)(void *data, u8 *mac,
2368 + struct ieee80211_vif *vif),
2369 + void *data);
2370 +void rtw_iterate_stas(struct rtw_dev *rtwdev,
2371 + void (*iterator)(void *data,
2372 + struct ieee80211_sta *sta),
2373 + void *data);
2374 +
2375 static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
2376 {
2377 __le16 fc = hdr->frame_control;

  ViewVC Help
Powered by ViewVC 1.1.30