linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/11] RTW88: Add support for USB variants
@ 2022-11-22 14:52 Sascha Hauer
  2022-11-22 14:52 ` [PATCH v3 01/11] rtw88: print firmware type in info message Sascha Hauer
                   ` (12 more replies)
  0 siblings, 13 replies; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer

This is the third round of adding support for the USB variants to the
RTW88 driver. There are a few changes to the last version which make it
worth looking at this version.

First of all RTL8723du and RTL8821cu are tested working now. The issue
here was that the txdesc checksum calculation was wrong. I found the
correct calculation in various downstream drivers found on github.

The second big issue was that TX packet aggregation was wrong. When
aggregating packets each packet start has to be aligned to eight bytes.
The necessary alignment was added to the total URB length before
checking if there is another packet to aggregate, so the URB length
included that padding after the last packet, which is wrong.  Fixing
this makes the driver work much more reliably.

I added all people to Cc: who showed interest in this driver and I want
to welcome you for testing and reviewing.

Sascha


Sascha Hauer (11):
  rtw88: print firmware type in info message
  rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held
  rtw88: Drop rf_lock
  rtw88: Drop h2c.lock
  rtw88: Drop coex mutex
  rtw88: iterate over vif/sta list non-atomically
  rtw88: Add common USB chip support
  rtw88: Add rtw8821cu chipset support
  rtw88: Add rtw8822bu chipset support
  rtw88: Add rtw8822cu chipset support
  rtw88: Add rtw8723du chipset support

 drivers/net/wireless/realtek/rtw88/Kconfig    |  47 +
 drivers/net/wireless/realtek/rtw88/Makefile   |  14 +
 drivers/net/wireless/realtek/rtw88/coex.c     |   3 +-
 drivers/net/wireless/realtek/rtw88/debug.c    |  15 +
 drivers/net/wireless/realtek/rtw88/fw.c       |  13 +-
 drivers/net/wireless/realtek/rtw88/hci.h      |   9 +-
 drivers/net/wireless/realtek/rtw88/mac.c      |   3 +
 drivers/net/wireless/realtek/rtw88/mac80211.c |   2 +-
 drivers/net/wireless/realtek/rtw88/main.c     |  12 +-
 drivers/net/wireless/realtek/rtw88/main.h     |  12 +-
 drivers/net/wireless/realtek/rtw88/phy.c      |   6 +-
 drivers/net/wireless/realtek/rtw88/ps.c       |   2 +-
 drivers/net/wireless/realtek/rtw88/reg.h      |   1 +
 drivers/net/wireless/realtek/rtw88/rtw8723d.c |  28 +
 drivers/net/wireless/realtek/rtw88/rtw8723d.h |  13 +-
 .../net/wireless/realtek/rtw88/rtw8723du.c    |  36 +
 .../net/wireless/realtek/rtw88/rtw8723du.h    |  10 +
 drivers/net/wireless/realtek/rtw88/rtw8821c.c |  18 +
 drivers/net/wireless/realtek/rtw88/rtw8821c.h |  21 +
 .../net/wireless/realtek/rtw88/rtw8821cu.c    |  50 +
 .../net/wireless/realtek/rtw88/rtw8821cu.h    |  10 +
 drivers/net/wireless/realtek/rtw88/rtw8822b.c |  19 +
 .../net/wireless/realtek/rtw88/rtw8822bu.c    |  90 ++
 .../net/wireless/realtek/rtw88/rtw8822bu.h    |  10 +
 drivers/net/wireless/realtek/rtw88/rtw8822c.c |  24 +
 .../net/wireless/realtek/rtw88/rtw8822cu.c    |  44 +
 .../net/wireless/realtek/rtw88/rtw8822cu.h    |  10 +
 drivers/net/wireless/realtek/rtw88/tx.h       |  31 +
 drivers/net/wireless/realtek/rtw88/usb.c      | 918 ++++++++++++++++++
 drivers/net/wireless/realtek/rtw88/usb.h      | 107 ++
 drivers/net/wireless/realtek/rtw88/util.c     | 103 ++
 drivers/net/wireless/realtek/rtw88/util.h     |  12 +-
 32 files changed, 1655 insertions(+), 38 deletions(-)
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723du.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723du.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821cu.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821cu.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822bu.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822bu.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cu.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cu.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/usb.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/usb.h

-- 
2.30.2


^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v3 01/11] rtw88: print firmware type in info message
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
@ 2022-11-22 14:52 ` Sascha Hauer
  2022-11-25  8:27   ` Ping-Ke Shih
  2022-11-22 14:52 ` [PATCH v3 02/11] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held Sascha Hauer
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer

It's confusing to read two different firmware versions in the syslog
for the same device:

rtw_8822cu 2-1:1.2: Firmware version 9.9.4, H2C version 15
rtw_8822cu 2-1:1.2: Firmware version 9.9.11, H2C version 15

Print the firmware type in this message to make clear these are really
two different firmwares for different purposes:

rtw_8822cu 1-1.4:1.2: WOW Firmware version 9.9.4, H2C version 15
rtw_8822cu 1-1.4:1.2: Firmware version 9.9.11, H2C version 15

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---

Notes:
    Changes since v2:
    - new patch

 drivers/net/wireless/realtek/rtw88/main.c | 4 +++-
 drivers/net/wireless/realtek/rtw88/main.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 67151dbf83842..a7331872e8530 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1731,7 +1731,8 @@ static void rtw_load_firmware_cb(const struct firmware *firmware, void *context)
 	update_firmware_info(rtwdev, fw);
 	complete_all(&fw->completion);
 
-	rtw_info(rtwdev, "Firmware version %u.%u.%u, H2C version %u\n",
+	rtw_info(rtwdev, "%sFirmware version %u.%u.%u, H2C version %u\n",
+		 fw->type == RTW_WOWLAN_FW ? "WOW " : "",
 		 fw->version, fw->sub_version, fw->sub_index, fw->h2c_version);
 }
 
@@ -1757,6 +1758,7 @@ static int rtw_load_firmware(struct rtw_dev *rtwdev, enum rtw_fw_type type)
 		return -ENOENT;
 	}
 
+	fw->type = type;
 	fw->rtwdev = rtwdev;
 	init_completion(&fw->completion);
 
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index bccd7b28f60c7..6e5875f6d07f4 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1851,6 +1851,7 @@ struct rtw_fw_state {
 	u16 h2c_version;
 	u32 feature;
 	u32 feature_ext;
+	enum rtw_fw_type type;
 };
 
 enum rtw_sar_sources {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 02/11] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
  2022-11-22 14:52 ` [PATCH v3 01/11] rtw88: print firmware type in info message Sascha Hauer
@ 2022-11-22 14:52 ` Sascha Hauer
  2022-11-25  8:27   ` Ping-Ke Shih
  2022-11-22 14:52 ` [PATCH v3 03/11] rtw88: Drop rf_lock Sascha Hauer
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer

rtw_fw_beacon_filter_config() is called once with rtwdev->mutex held
and once without the mutex held. Call it consistently with rtwdev->mutex
held.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/wireless/realtek/rtw88/mac80211.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index 07578ccc4bab3..776a9a9884b5d 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -487,8 +487,8 @@ static int rtw_ops_sta_remove(struct ieee80211_hw *hw,
 {
 	struct rtw_dev *rtwdev = hw->priv;
 
-	rtw_fw_beacon_filter_config(rtwdev, false, vif);
 	mutex_lock(&rtwdev->mutex);
+	rtw_fw_beacon_filter_config(rtwdev, false, vif);
 	rtw_sta_remove(rtwdev, sta, true);
 	mutex_unlock(&rtwdev->mutex);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 03/11] rtw88: Drop rf_lock
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
  2022-11-22 14:52 ` [PATCH v3 01/11] rtw88: print firmware type in info message Sascha Hauer
  2022-11-22 14:52 ` [PATCH v3 02/11] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held Sascha Hauer
@ 2022-11-22 14:52 ` Sascha Hauer
  2022-11-25  8:29   ` Ping-Ke Shih
  2022-11-22 14:52 ` [PATCH v3 04/11] rtw88: Drop h2c.lock Sascha Hauer
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer

The rtwdev->rf_lock spinlock protects the rf register accesses in
rtw_read_rf() and rtw_write_rf(). Most callers of these functions hold
rtwdev->mutex already with the exception of the callsites in the debugfs
code. The debugfs code doesn't justify an extra lock, so acquire the mutex
there as well before calling rf register accessors and drop the now
unnecessary spinlock.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/wireless/realtek/rtw88/debug.c | 11 +++++++++++
 drivers/net/wireless/realtek/rtw88/hci.h   |  9 +++------
 drivers/net/wireless/realtek/rtw88/main.c  |  1 -
 drivers/net/wireless/realtek/rtw88/main.h  |  3 ---
 4 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
index 9ebe544e51d0d..70e19f2a1a355 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -144,7 +144,9 @@ static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v)
 	addr = debugfs_priv->rf_addr;
 	mask = debugfs_priv->rf_mask;
 
+	mutex_lock(&rtwdev->mutex);
 	val = rtw_read_rf(rtwdev, path, addr, mask);
+	mutex_unlock(&rtwdev->mutex);
 
 	seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n",
 		   path, addr, mask, val);
@@ -414,7 +416,9 @@ static ssize_t rtw_debugfs_set_rf_write(struct file *filp,
 		return count;
 	}
 
+	mutex_lock(&rtwdev->mutex);
 	rtw_write_rf(rtwdev, path, addr, mask, val);
+	mutex_unlock(&rtwdev->mutex);
 	rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
 		"write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n",
 		path, addr, mask, val);
@@ -519,6 +523,8 @@ static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
 	u32 addr, offset, data;
 	u8 path;
 
+	mutex_lock(&rtwdev->mutex);
+
 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
 		seq_printf(m, "RF path:%d\n", path);
 		for (addr = 0; addr < 0x100; addr += 4) {
@@ -533,6 +539,8 @@ static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
 		seq_puts(m, "\n");
 	}
 
+	mutex_unlock(&rtwdev->mutex);
+
 	return 0;
 }
 
@@ -1026,6 +1034,8 @@ static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m)
 		   dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+',
 		   rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]);
 
+	mutex_lock(&rtwdev->mutex);
+
 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
 		val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK);
 		seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val);
@@ -1035,6 +1045,7 @@ static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m)
 				   txgapk->rf3f_fs[path][i], i);
 		seq_puts(m, "\n");
 	}
+	mutex_unlock(&rtwdev->mutex);
 }
 
 static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v)
diff --git a/drivers/net/wireless/realtek/rtw88/hci.h b/drivers/net/wireless/realtek/rtw88/hci.h
index 4c6fc6fb3f83b..830d7532f2a35 100644
--- a/drivers/net/wireless/realtek/rtw88/hci.h
+++ b/drivers/net/wireless/realtek/rtw88/hci.h
@@ -166,12 +166,11 @@ static inline u32
 rtw_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
 	    u32 addr, u32 mask)
 {
-	unsigned long flags;
 	u32 val;
 
-	spin_lock_irqsave(&rtwdev->rf_lock, flags);
+	lockdep_assert_held(&rtwdev->mutex);
+
 	val = rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask);
-	spin_unlock_irqrestore(&rtwdev->rf_lock, flags);
 
 	return val;
 }
@@ -180,11 +179,9 @@ static inline void
 rtw_write_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
 	     u32 addr, u32 mask, u32 data)
 {
-	unsigned long flags;
+	lockdep_assert_held(&rtwdev->mutex);
 
-	spin_lock_irqsave(&rtwdev->rf_lock, flags);
 	rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data);
-	spin_unlock_irqrestore(&rtwdev->rf_lock, flags);
 }
 
 static inline u32
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index a7331872e8530..710ddb0283c82 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -2067,7 +2067,6 @@ int rtw_core_init(struct rtw_dev *rtwdev)
 	skb_queue_head_init(&rtwdev->coex.queue);
 	skb_queue_head_init(&rtwdev->tx_report.queue);
 
-	spin_lock_init(&rtwdev->rf_lock);
 	spin_lock_init(&rtwdev->h2c.lock);
 	spin_lock_init(&rtwdev->txq_lock);
 	spin_lock_init(&rtwdev->tx_report.q_lock);
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 6e5875f6d07f4..f24d17f482aaa 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1995,9 +1995,6 @@ struct rtw_dev {
 	/* ensures exclusive access from mac80211 callbacks */
 	struct mutex mutex;
 
-	/* read/write rf register */
-	spinlock_t rf_lock;
-
 	/* watch dog every 2 sec */
 	struct delayed_work watch_dog_work;
 	u32 watch_dog_cnt;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 04/11] rtw88: Drop h2c.lock
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
                   ` (2 preceding siblings ...)
  2022-11-22 14:52 ` [PATCH v3 03/11] rtw88: Drop rf_lock Sascha Hauer
@ 2022-11-22 14:52 ` Sascha Hauer
  2022-11-22 14:52 ` [PATCH v3 05/11] rtw88: Drop coex mutex Sascha Hauer
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer

The h2c.lock spinlock is used in rtw_fw_send_h2c_command() and
rtw_fw_send_h2c_packet().  Most callers call this with rtwdev->mutex
held, except from one callsite in the debugfs code. The debugfs code
alone doesn't justify the extra lock, so acquire rtwdev->mutex in
debugfs and drop the now unnecessary spinlock.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/wireless/realtek/rtw88/debug.c |  2 ++
 drivers/net/wireless/realtek/rtw88/fw.c    | 13 ++++---------
 drivers/net/wireless/realtek/rtw88/main.c  |  1 -
 drivers/net/wireless/realtek/rtw88/main.h  |  2 --
 4 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
index 70e19f2a1a355..f5b8a77ebc67b 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -392,7 +392,9 @@ static ssize_t rtw_debugfs_set_h2c(struct file *filp,
 		return -EINVAL;
 	}
 
+	mutex_lock(&rtwdev->mutex);
 	rtw_fw_h2c_cmd_dbg(rtwdev, param);
+	mutex_unlock(&rtwdev->mutex);
 
 	return count;
 }
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 0b5f903c0f366..a58c80d4825b1 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -322,7 +322,7 @@ static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
 		h2c[3], h2c[2], h2c[1], h2c[0],
 		h2c[7], h2c[6], h2c[5], h2c[4]);
 
-	spin_lock(&rtwdev->h2c.lock);
+	lockdep_assert_held(&rtwdev->mutex);
 
 	box = rtwdev->h2c.last_box_num;
 	switch (box) {
@@ -344,7 +344,7 @@ static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
 		break;
 	default:
 		WARN(1, "invalid h2c mail box number\n");
-		goto out;
+		return;
 	}
 
 	ret = read_poll_timeout_atomic(rtw_read8, box_state,
@@ -353,7 +353,7 @@ static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
 
 	if (ret) {
 		rtw_err(rtwdev, "failed to send h2c command\n");
-		goto out;
+		return;
 	}
 
 	for (idx = 0; idx < 4; idx++)
@@ -363,9 +363,6 @@ static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
 
 	if (++rtwdev->h2c.last_box_num >= 4)
 		rtwdev->h2c.last_box_num = 0;
-
-out:
-	spin_unlock(&rtwdev->h2c.lock);
 }
 
 void rtw_fw_h2c_cmd_dbg(struct rtw_dev *rtwdev, u8 *h2c)
@@ -377,15 +374,13 @@ static void rtw_fw_send_h2c_packet(struct rtw_dev *rtwdev, u8 *h2c_pkt)
 {
 	int ret;
 
-	spin_lock(&rtwdev->h2c.lock);
+	lockdep_assert_held(&rtwdev->mutex);
 
 	FW_OFFLOAD_H2C_SET_SEQ_NUM(h2c_pkt, rtwdev->h2c.seq);
 	ret = rtw_hci_write_data_h2c(rtwdev, h2c_pkt, H2C_PKT_SIZE);
 	if (ret)
 		rtw_err(rtwdev, "failed to send h2c packet\n");
 	rtwdev->h2c.seq++;
-
-	spin_unlock(&rtwdev->h2c.lock);
 }
 
 void
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 710ddb0283c82..c98e56890401c 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -2067,7 +2067,6 @@ int rtw_core_init(struct rtw_dev *rtwdev)
 	skb_queue_head_init(&rtwdev->coex.queue);
 	skb_queue_head_init(&rtwdev->tx_report.queue);
 
-	spin_lock_init(&rtwdev->h2c.lock);
 	spin_lock_init(&rtwdev->txq_lock);
 	spin_lock_init(&rtwdev->tx_report.q_lock);
 
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index f24d17f482aaa..4b57542bef1e9 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -2020,8 +2020,6 @@ struct rtw_dev {
 	struct {
 		/* incicate the mail box to use with fw */
 		u8 last_box_num;
-		/* protect to send h2c to fw */
-		spinlock_t lock;
 		u32 seq;
 	} h2c;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 05/11] rtw88: Drop coex mutex
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
                   ` (3 preceding siblings ...)
  2022-11-22 14:52 ` [PATCH v3 04/11] rtw88: Drop h2c.lock Sascha Hauer
@ 2022-11-22 14:52 ` Sascha Hauer
  2022-11-22 14:52 ` [PATCH v3 06/11] rtw88: iterate over vif/sta list non-atomically Sascha Hauer
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer

coex->mutex is used in rtw_coex_info_request() only. Most callers of this
function hold rtwdev->mutex already, except for one callsite in the
debugfs code. The debugfs code alone doesn't justify the extra lock, so
acquire rtwdev->mutex there as well and drop the now unnecessary
spinlock.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/wireless/realtek/rtw88/coex.c  | 3 +--
 drivers/net/wireless/realtek/rtw88/debug.c | 2 ++
 drivers/net/wireless/realtek/rtw88/main.c  | 2 --
 drivers/net/wireless/realtek/rtw88/main.h  | 2 --
 4 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
index 6276ad6242991..38697237ee5f0 100644
--- a/drivers/net/wireless/realtek/rtw88/coex.c
+++ b/drivers/net/wireless/realtek/rtw88/coex.c
@@ -633,7 +633,7 @@ static struct sk_buff *rtw_coex_info_request(struct rtw_dev *rtwdev,
 	struct rtw_coex *coex = &rtwdev->coex;
 	struct sk_buff *skb_resp = NULL;
 
-	mutex_lock(&coex->mutex);
+	lockdep_assert_held(&rtwdev->mutex);
 
 	rtw_fw_query_bt_mp_info(rtwdev, req);
 
@@ -650,7 +650,6 @@ static struct sk_buff *rtw_coex_info_request(struct rtw_dev *rtwdev,
 	}
 
 out:
-	mutex_unlock(&coex->mutex);
 	return skb_resp;
 }
 
diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
index f5b8a77ebc67b..fa3d73b333ba0 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -841,7 +841,9 @@ static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v)
 	struct rtw_debugfs_priv *debugfs_priv = m->private;
 	struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
 
+	mutex_lock(&rtwdev->mutex);
 	rtw_coex_display_coex_info(rtwdev, m);
+	mutex_unlock(&rtwdev->mutex);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index c98e56890401c..0a2ce7f50f412 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -2071,7 +2071,6 @@ int rtw_core_init(struct rtw_dev *rtwdev)
 	spin_lock_init(&rtwdev->tx_report.q_lock);
 
 	mutex_init(&rtwdev->mutex);
-	mutex_init(&rtwdev->coex.mutex);
 	mutex_init(&rtwdev->hal.tx_power_mutex);
 
 	init_waitqueue_head(&rtwdev->coex.wait);
@@ -2143,7 +2142,6 @@ void rtw_core_deinit(struct rtw_dev *rtwdev)
 	}
 
 	mutex_destroy(&rtwdev->mutex);
-	mutex_destroy(&rtwdev->coex.mutex);
 	mutex_destroy(&rtwdev->hal.tx_power_mutex);
 }
 EXPORT_SYMBOL(rtw_core_deinit);
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 4b57542bef1e9..77fd48b6cc453 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1501,8 +1501,6 @@ struct rtw_coex_stat {
 };
 
 struct rtw_coex {
-	/* protects coex info request section */
-	struct mutex mutex;
 	struct sk_buff_head queue;
 	wait_queue_head_t wait;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 06/11] rtw88: iterate over vif/sta list non-atomically
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
                   ` (4 preceding siblings ...)
  2022-11-22 14:52 ` [PATCH v3 05/11] rtw88: Drop coex mutex Sascha Hauer
@ 2022-11-22 14:52 ` Sascha Hauer
  2022-11-25  8:50   ` Ping-Ke Shih
  2022-11-22 14:52 ` [PATCH v3 07/11] rtw88: Add common USB chip support Sascha Hauer
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer

The driver uses ieee80211_iterate_active_interfaces_atomic()
and ieee80211_iterate_stations_atomic() in several places and does
register accesses in the iterators. This doesn't cope with upcoming
USB support as registers can only be accessed non-atomically.

Split these into a two stage process: First use the atomic iterator
functions to collect all active interfaces or stations on a list, then
iterate over the list non-atomically and call the iterator on each
entry.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Suggested-by: Pkshih <pkshih@realtek.com>
---

Notes:
    Changes since v1:
    - Change subject
    - Add some lockdep_assert_held(&rtwdev->mutex);
    - make locally used functions static
    - Add comment how &rtwdev->mutex protects us from stations/interfaces
      being deleted between collecting them and iterating over them.

 drivers/net/wireless/realtek/rtw88/phy.c  |   6 +-
 drivers/net/wireless/realtek/rtw88/ps.c   |   2 +-
 drivers/net/wireless/realtek/rtw88/util.c | 103 ++++++++++++++++++++++
 drivers/net/wireless/realtek/rtw88/util.h |  12 ++-
 4 files changed, 116 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index bd7d05e080848..128e75a81bf3c 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -300,7 +300,7 @@ static void rtw_phy_stat_rssi(struct rtw_dev *rtwdev)
 
 	data.rtwdev = rtwdev;
 	data.min_rssi = U8_MAX;
-	rtw_iterate_stas_atomic(rtwdev, rtw_phy_stat_rssi_iter, &data);
+	rtw_iterate_stas(rtwdev, rtw_phy_stat_rssi_iter, &data);
 
 	dm_info->pre_min_rssi = dm_info->min_rssi;
 	dm_info->min_rssi = data.min_rssi;
@@ -544,7 +544,7 @@ static void rtw_phy_ra_info_update(struct rtw_dev *rtwdev)
 	if (rtwdev->watch_dog_cnt & 0x3)
 		return;
 
-	rtw_iterate_stas_atomic(rtwdev, rtw_phy_ra_info_update_iter, rtwdev);
+	rtw_iterate_stas(rtwdev, rtw_phy_ra_info_update_iter, rtwdev);
 }
 
 static u32 rtw_phy_get_rrsr_mask(struct rtw_dev *rtwdev, u8 rate_idx)
@@ -597,7 +597,7 @@ static void rtw_phy_rrsr_update(struct rtw_dev *rtwdev)
 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
 
 	dm_info->rrsr_mask_min = RRSR_RATE_ORDER_MAX;
-	rtw_iterate_stas_atomic(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev);
+	rtw_iterate_stas(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev);
 	rtw_write32(rtwdev, REG_RRSR, dm_info->rrsr_val_init & dm_info->rrsr_mask_min);
 }
 
diff --git a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c
index c93da743681fc..11594940d6b00 100644
--- a/drivers/net/wireless/realtek/rtw88/ps.c
+++ b/drivers/net/wireless/realtek/rtw88/ps.c
@@ -61,7 +61,7 @@ int rtw_leave_ips(struct rtw_dev *rtwdev)
 		return ret;
 	}
 
-	rtw_iterate_vifs_atomic(rtwdev, rtw_restore_port_cfg_iter, rtwdev);
+	rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev);
 
 	rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE);
 
diff --git a/drivers/net/wireless/realtek/rtw88/util.c b/drivers/net/wireless/realtek/rtw88/util.c
index cdfd66a85075a..ff3c269fb1a72 100644
--- a/drivers/net/wireless/realtek/rtw88/util.c
+++ b/drivers/net/wireless/realtek/rtw88/util.c
@@ -105,3 +105,106 @@ void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss)
 		*mcs = rate - DESC_RATEMCS0;
 	}
 }
+
+struct rtw_stas_entry {
+	struct list_head list;
+	struct ieee80211_sta *sta;
+};
+
+struct rtw_iter_stas_data {
+	struct rtw_dev *rtwdev;
+	struct list_head list;
+};
+
+static void rtw_collect_sta_iter(void *data, struct ieee80211_sta *sta)
+{
+	struct rtw_iter_stas_data *iter_stas = data;
+	struct rtw_stas_entry *stas_entry;
+
+	stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC);
+	if (!stas_entry)
+		return;
+
+	stas_entry->sta = sta;
+	list_add_tail(&stas_entry->list, &iter_stas->list);
+}
+
+void rtw_iterate_stas(struct rtw_dev *rtwdev,
+		      void (*iterator)(void *data,
+				       struct ieee80211_sta *sta),
+		      void *data)
+{
+	struct rtw_iter_stas_data iter_data;
+	struct rtw_stas_entry *sta_entry, *tmp;
+
+	/* &rtwdev->mutex makes sure no stations can be removed between
+	 * collecting the stations and iterating over them.
+	 */
+	lockdep_assert_held(&rtwdev->mutex);
+
+	iter_data.rtwdev = rtwdev;
+	INIT_LIST_HEAD(&iter_data.list);
+
+	ieee80211_iterate_stations_atomic(rtwdev->hw, rtw_collect_sta_iter,
+					  &iter_data);
+
+	list_for_each_entry_safe(sta_entry, tmp, &iter_data.list,
+				 list) {
+		list_del_init(&sta_entry->list);
+		iterator(data, sta_entry->sta);
+		kfree(sta_entry);
+	}
+}
+
+struct rtw_vifs_entry {
+	struct list_head list;
+	struct ieee80211_vif *vif;
+	u8 mac[ETH_ALEN];
+};
+
+struct rtw_iter_vifs_data {
+	struct rtw_dev *rtwdev;
+	struct list_head list;
+};
+
+static void rtw_collect_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct rtw_iter_vifs_data *iter_stas = data;
+	struct rtw_vifs_entry *vifs_entry;
+
+	vifs_entry = kmalloc(sizeof(*vifs_entry), GFP_ATOMIC);
+	if (!vifs_entry)
+		return;
+
+	vifs_entry->vif = vif;
+	ether_addr_copy(vifs_entry->mac, mac);
+	list_add_tail(&vifs_entry->list, &iter_stas->list);
+}
+
+void rtw_iterate_vifs(struct rtw_dev *rtwdev,
+		      void (*iterator)(void *data, u8 *mac,
+				       struct ieee80211_vif *vif),
+		      void *data)
+{
+	struct rtw_iter_vifs_data iter_data;
+	struct rtw_vifs_entry *vif_entry, *tmp;
+
+	/* &rtwdev->mutex makes sure no interfaces can be removed between
+	 * collecting the interfaces and iterating over them.
+	 */
+	lockdep_assert_held(&rtwdev->mutex);
+
+	iter_data.rtwdev = rtwdev;
+	INIT_LIST_HEAD(&iter_data.list);
+
+	ieee80211_iterate_active_interfaces_atomic(rtwdev->hw,
+						   IEEE80211_IFACE_ITER_NORMAL,
+						   rtw_collect_vif_iter, &iter_data);
+
+	list_for_each_entry_safe(vif_entry, tmp, &iter_data.list,
+				 list) {
+		list_del_init(&vif_entry->list);
+		iterator(data, vif_entry->mac, vif_entry->vif);
+		kfree(vif_entry);
+	}
+}
diff --git a/drivers/net/wireless/realtek/rtw88/util.h b/drivers/net/wireless/realtek/rtw88/util.h
index 0c23b5069be0b..dc89655254002 100644
--- a/drivers/net/wireless/realtek/rtw88/util.h
+++ b/drivers/net/wireless/realtek/rtw88/util.h
@@ -7,9 +7,6 @@
 
 struct rtw_dev;
 
-#define rtw_iterate_vifs(rtwdev, iterator, data)                               \
-	ieee80211_iterate_active_interfaces(rtwdev->hw,                        \
-			IEEE80211_IFACE_ITER_NORMAL, iterator, data)
 #define rtw_iterate_vifs_atomic(rtwdev, iterator, data)                        \
 	ieee80211_iterate_active_interfaces_atomic(rtwdev->hw,                 \
 			IEEE80211_IFACE_ITER_NORMAL, iterator, data)
@@ -20,6 +17,15 @@ struct rtw_dev;
 #define rtw_iterate_keys_rcu(rtwdev, vif, iterator, data)		       \
 	ieee80211_iter_keys_rcu((rtwdev)->hw, vif, iterator, data)
 
+void rtw_iterate_vifs(struct rtw_dev *rtwdev,
+		      void (*iterator)(void *data, u8 *mac,
+				       struct ieee80211_vif *vif),
+		      void *data);
+void rtw_iterate_stas(struct rtw_dev *rtwdev,
+		      void (*iterator)(void *data,
+				       struct ieee80211_sta *sta),
+				       void *data);
+
 static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
 {
 	__le16 fc = hdr->frame_control;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 07/11] rtw88: Add common USB chip support
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
                   ` (5 preceding siblings ...)
  2022-11-22 14:52 ` [PATCH v3 06/11] rtw88: iterate over vif/sta list non-atomically Sascha Hauer
@ 2022-11-22 14:52 ` Sascha Hauer
  2022-11-28  2:00   ` Ping-Ke Shih
  2022-11-22 14:52 ` [PATCH v3 08/11] rtw88: Add rtw8821cu chipset support Sascha Hauer
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer, neo_jou

Add the common bits and pieces to add USB support to the RTW88 driver.
This is based on https://github.com/ulli-kroll/rtw88-usb.git which
itself is first written by Neo Jou.

Signed-off-by: neo_jou <neo_jou@realtek.com>
Signed-off-by: Hans Ulli Kroll <linux@ulli-kroll.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---

Notes:
    Changes since v2:
    - Fix buffer length for aggregated tx packets
    - Increase maximum transmit buffer size to 20KiB as found in downstream drivers
    - Change register write functions to synchronous accesses instead of just firing
      a URB without waiting for its completion
    - requeue rx URBs directly in completion handler rather than having a workqueue
      for it.
    
    Changes since v1:
    - Make checkpatch.pl clean
    - Drop WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL flag
    - Use 'ret' as variable name for return values
    - Sort variable declarations in reverse Xmas tree order
    - Change potentially endless loop to a limited loop
    - Change locking to be more obviously correct
    - drop unnecessary check for !rtwdev
    - make sure the refill workqueue is not restarted again after we have
      cancelled it

 drivers/net/wireless/realtek/rtw88/Kconfig  |   3 +
 drivers/net/wireless/realtek/rtw88/Makefile |   2 +
 drivers/net/wireless/realtek/rtw88/mac.c    |   3 +
 drivers/net/wireless/realtek/rtw88/main.c   |   4 +
 drivers/net/wireless/realtek/rtw88/main.h   |   4 +
 drivers/net/wireless/realtek/rtw88/reg.h    |   1 +
 drivers/net/wireless/realtek/rtw88/tx.h     |  31 +
 drivers/net/wireless/realtek/rtw88/usb.c    | 918 ++++++++++++++++++++
 drivers/net/wireless/realtek/rtw88/usb.h    | 107 +++
 9 files changed, 1073 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/usb.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/usb.h

diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
index e3d7cb6c12902..1624c5db69bac 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -16,6 +16,9 @@ config RTW88_CORE
 config RTW88_PCI
 	tristate
 
+config RTW88_USB
+	tristate
+
 config RTW88_8822B
 	tristate
 
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile
index 834c66ec0af9e..9e095f8181483 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -45,4 +45,6 @@ obj-$(CONFIG_RTW88_8821CE)	+= rtw88_8821ce.o
 rtw88_8821ce-objs		:= rtw8821ce.o
 
 obj-$(CONFIG_RTW88_PCI)		+= rtw88_pci.o
+obj-$(CONFIG_RTW88_USB)		+= rtw88_usb.o
 rtw88_pci-objs			:= pci.o
+rtw88_usb-objs			:= usb.o
diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
index 52076e89d59a3..5882fc0fb885b 100644
--- a/drivers/net/wireless/realtek/rtw88/mac.c
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -1032,6 +1032,9 @@ static int txdma_queue_mapping(struct rtw_dev *rtwdev)
 	if (rtw_chip_wcpu_11ac(rtwdev))
 		rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL);
 
+	if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB)
+		rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_ARBBW_EN);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 0a2ce7f50f412..888427cf3bdf9 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1783,6 +1783,10 @@ static int rtw_chip_parameter_setup(struct rtw_dev *rtwdev)
 		rtwdev->hci.rpwm_addr = 0x03d9;
 		rtwdev->hci.cpwm_addr = 0x03da;
 		break;
+	case RTW_HCI_TYPE_USB:
+		rtwdev->hci.rpwm_addr = 0xfe58;
+		rtwdev->hci.cpwm_addr = 0xfe57;
+		break;
 	default:
 		rtw_err(rtwdev, "unsupported hci type\n");
 		return -EINVAL;
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 77fd48b6cc453..165f299e8e1f9 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -871,6 +871,10 @@ struct rtw_chip_ops {
 			       bool is_tx2_path);
 	void (*config_txrx_mode)(struct rtw_dev *rtwdev, u8 tx_path,
 				 u8 rx_path, bool is_tx2_path);
+	/* for USB/SDIO only */
+	void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev,
+				     struct rtw_tx_pkt_info *pkt_info,
+				     u8 *txdesc);
 
 	/* for coex */
 	void (*coex_set_init)(struct rtw_dev *rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
index 03bd8dc53f72a..8852b24d6c2ac 100644
--- a/drivers/net/wireless/realtek/rtw88/reg.h
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
@@ -184,6 +184,7 @@
 #define BIT_TXDMA_VIQ_MAP(x)                                                   \
 	(((x) & BIT_MASK_TXDMA_VIQ_MAP) << BIT_SHIFT_TXDMA_VIQ_MAP)
 #define REG_TXDMA_PQ_MAP	0x010C
+#define BIT_RXDMA_ARBBW_EN	BIT(0)
 #define BIT_SHIFT_TXDMA_BEQ_MAP	8
 #define BIT_MASK_TXDMA_BEQ_MAP	0x3
 #define BIT_TXDMA_BEQ_MAP(x)                                                   \
diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h
index 8419603adce4a..a2f3ac326041b 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.h
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
@@ -71,6 +71,14 @@
 	le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15))
 #define SET_TX_DESC_BT_NULL(txdesc, value)				       \
 	le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23))
+#define SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value)				\
+	le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(15, 0))
+#define SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value)				\
+	le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(31, 24))
+#define GET_TX_DESC_PKT_OFFSET(txdesc)						\
+	le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(28, 24))
+#define GET_TX_DESC_QSEL(txdesc)						\
+	le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(12, 8))
 
 enum rtw_tx_desc_queue_select {
 	TX_DESC_QSEL_TID0	= 0,
@@ -123,4 +131,27 @@ rtw_tx_write_data_h2c_get(struct rtw_dev *rtwdev,
 			  struct rtw_tx_pkt_info *pkt_info,
 			  u8 *buf, u32 size);
 
+static inline
+void fill_txdesc_checksum_common(u8 *txdesc, size_t words)
+{
+	__le16 chksum = 0;
+	__le16 *data = (__le16 *)(txdesc);
+
+	SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000);
+
+	while (words--)
+		chksum ^= *data++;
+
+	SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum));
+}
+
+static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev,
+					       struct rtw_tx_pkt_info *pkt_info,
+					       u8 *txdesc)
+{
+	const struct rtw_chip_info *chip = rtwdev->chip;
+
+	chip->ops->fill_txdesc_checksum(rtwdev, pkt_info, txdesc);
+}
+
 #endif
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
new file mode 100644
index 0000000000000..4a12934d20712
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -0,0 +1,918 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+#include "main.h"
+#include "debug.h"
+#include "reg.h"
+#include "tx.h"
+#include "rx.h"
+#include "fw.h"
+#include "ps.h"
+#include "usb.h"
+
+#define RTW_USB_MAX_RXQ_LEN	128
+
+struct rtw_usb_txcb {
+	struct rtw_dev *rtwdev;
+	struct sk_buff_head tx_ack_queue;
+};
+
+static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb,
+				     struct sk_buff *skb, int agg_num)
+{
+	struct rtw_dev *rtwdev = rtwusb->rtwdev;
+	struct rtw_tx_pkt_info pkt_info;
+
+	SET_TX_DESC_DMA_TXAGG_NUM(skb->data, agg_num);
+	pkt_info.pkt_offset = GET_TX_DESC_PKT_OFFSET(skb->data);
+	rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data);
+}
+
+static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+	struct usb_device *udev = rtwusb->udev;
+	__le32 *data;
+	unsigned long flags;
+	int ret;
+	static int count;
+
+	spin_lock_irqsave(&rtwusb->usb_lock, flags);
+
+	rtwusb->usb_data_index++;
+	rtwusb->usb_data_index &= (RTW_USB_MAX_RXTX_COUNT - 1);
+
+	spin_unlock_irqrestore(&rtwusb->usb_lock, flags);
+
+	data = &rtwusb->usb_data[rtwusb->usb_data_index];
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+			      RTW_USB_CMD_REQ, RTW_USB_CMD_READ, addr,
+			      RTW_USB_VENQT_CMD_IDX, data, len, 1000);
+	if (ret < 0 && ret != -ENODEV && count++ < 4)
+		rtw_err(rtwdev, "read register 0x%x failed with %d\n",
+			addr, ret);
+
+	return le32_to_cpu(*data);
+}
+
+static u8 rtw_usb_read8(struct rtw_dev *rtwdev, u32 addr)
+{
+	return (u8)rtw_usb_read(rtwdev, addr, 1);
+}
+
+static u16 rtw_usb_read16(struct rtw_dev *rtwdev, u32 addr)
+{
+	return (u16)rtw_usb_read(rtwdev, addr, 2);
+}
+
+static u32 rtw_usb_read32(struct rtw_dev *rtwdev, u32 addr)
+{
+	return (u32)rtw_usb_read(rtwdev, addr, 4);
+}
+
+static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len)
+{
+	struct rtw_usb *rtwusb = (struct rtw_usb *)rtwdev->priv;
+	struct usb_device *udev = rtwusb->udev;
+	unsigned long flags;
+	__le32 *data;
+	int ret;
+	static int count;
+
+	spin_lock_irqsave(&rtwusb->usb_lock, flags);
+
+	rtwusb->usb_data_index++;
+	rtwusb->usb_data_index &= (RTW_USB_MAX_RXTX_COUNT - 1);
+
+	spin_unlock_irqrestore(&rtwusb->usb_lock, flags);
+
+	data = &rtwusb->usb_data[rtwusb->usb_data_index];
+
+	*data = cpu_to_le32(val);
+
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+			      RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE,
+			      addr, 0, data, len, 30000);
+	if (ret < 0 && ret != -ENODEV && count++ < 4)
+		rtw_err(rtwdev, "write register 0x%x failed with %d\n",
+			addr, ret);
+}
+
+static void rtw_usb_write8(struct rtw_dev *rtwdev, u32 addr, u8 val)
+{
+	rtw_usb_write(rtwdev, addr, val, 1);
+}
+
+static void rtw_usb_write16(struct rtw_dev *rtwdev, u32 addr, u16 val)
+{
+	rtw_usb_write(rtwdev, addr, val, 2);
+}
+
+static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val)
+{
+	rtw_usb_write(rtwdev, addr, val, 4);
+}
+
+static int rtw_usb_parse(struct rtw_dev *rtwdev,
+			 struct usb_interface *interface)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+	struct usb_host_interface *host_interface = &interface->altsetting[0];
+	struct usb_interface_descriptor *interface_desc = &host_interface->desc;
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_device *usbd = interface_to_usbdev(interface);
+	int num_out_pipes = 0;
+	int i;
+	u8 num;
+
+	for (i = 0; i < interface_desc->bNumEndpoints; i++) {
+		endpoint = &host_interface->endpoint[i].desc;
+		num = usb_endpoint_num(endpoint);
+
+		if (usb_endpoint_dir_in(endpoint) &&
+		    usb_endpoint_xfer_bulk(endpoint)) {
+			if (rtwusb->pipe_in) {
+				rtw_err(rtwdev, "IN pipes overflow\n");
+				return -EINVAL;
+			}
+
+			rtwusb->pipe_in = num;
+		}
+
+		if (usb_endpoint_dir_in(endpoint) &&
+		    usb_endpoint_xfer_int(endpoint)) {
+			if (rtwusb->pipe_interrupt) {
+				rtw_err(rtwdev, "INT pipes overflow\n");
+				return -EINVAL;
+			}
+
+			rtwusb->pipe_interrupt = num;
+		}
+
+		if (usb_endpoint_dir_out(endpoint) &&
+		    usb_endpoint_xfer_bulk(endpoint)) {
+			if (num_out_pipes >= ARRAY_SIZE(rtwusb->out_ep)) {
+				rtw_err(rtwdev, "OUT pipes overflow\n");
+				return -EINVAL;
+			}
+
+			rtwusb->out_ep[num_out_pipes++] = num;
+		}
+	}
+
+	switch (usbd->speed) {
+	case USB_SPEED_LOW:
+	case USB_SPEED_FULL:
+		rtwusb->bulkout_size = RTW_USB_FULL_SPEED_BULK_SIZE;
+		break;
+	case USB_SPEED_HIGH:
+		rtwusb->bulkout_size = RTW_USB_HIGH_SPEED_BULK_SIZE;
+		break;
+	case USB_SPEED_SUPER:
+		rtwusb->bulkout_size = RTW_USB_SUPER_SPEED_BULK_SIZE;
+		break;
+	default:
+		rtw_err(rtwdev, "failed to detect usb speed\n");
+		return -EINVAL;
+	}
+
+	rtwdev->hci.bulkout_num = num_out_pipes;
+
+	switch (num_out_pipes) {
+	case 4:
+	case 3:
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 2;
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 2;
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 2;
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 2;
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = 1;
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = 1;
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = 0;
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = 0;
+		break;
+	case 2:
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 1;
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 1;
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 1;
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 1;
+		break;
+	case 1:
+		break;
+	default:
+		rtw_err(rtwdev, "failed to get out_pipes(%d)\n", num_out_pipes);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void rtw_usb_write_port_tx_complete(struct urb *urb)
+{
+	struct rtw_usb_txcb *txcb = urb->context;
+	struct rtw_dev *rtwdev = txcb->rtwdev;
+	struct ieee80211_hw *hw = rtwdev->hw;
+
+	while (true) {
+		struct sk_buff *skb = skb_dequeue(&txcb->tx_ack_queue);
+		struct ieee80211_tx_info *info;
+		struct rtw_usb_tx_data *tx_data;
+
+		if (!skb)
+			break;
+
+		info = IEEE80211_SKB_CB(skb);
+		tx_data = rtw_usb_get_tx_data(skb);
+
+		/* enqueue to wait for tx report */
+		if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
+			rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn);
+			continue;
+		}
+
+		/* always ACK for others, then they won't be marked as drop */
+		ieee80211_tx_info_clear_status(info);
+		if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+			info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
+		else
+			info->flags |= IEEE80211_TX_STAT_ACK;
+
+		ieee80211_tx_status_irqsafe(hw, skb);
+	}
+
+	kfree(txcb);
+}
+
+static int qsel_to_ep(struct rtw_usb *rtwusb, unsigned int qsel)
+{
+	if (qsel >= ARRAY_SIZE(rtwusb->qsel_to_ep))
+		return 0;
+
+	return rtwusb->qsel_to_ep[qsel];
+}
+
+static int rtw_usb_write_port(struct rtw_dev *rtwdev, u8 qsel, struct sk_buff *skb,
+			      usb_complete_t cb, void *context)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+	struct usb_device *usbd = rtwusb->udev;
+	struct urb *urb;
+	unsigned int pipe;
+	int ret;
+	int ep = qsel_to_ep(rtwusb, qsel);
+
+	pipe = usb_sndbulkpipe(usbd, rtwusb->out_ep[ep]);
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!urb)
+		return -ENOMEM;
+
+	usb_fill_bulk_urb(urb, usbd, pipe, skb->data, skb->len, cb, context);
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+
+	usb_free_urb(urb);
+
+	return ret;
+}
+
+static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list)
+{
+	struct rtw_dev *rtwdev = rtwusb->rtwdev;
+	struct rtw_usb_txcb *txcb;
+	struct sk_buff *skb_head;
+	struct sk_buff *skb_iter;
+	u8 *data_ptr;
+	int agg_num = 0;
+	unsigned int align_next = 0;
+
+	if (skb_queue_empty(list))
+		return false;
+
+	txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC);
+	if (!txcb)
+		return false;
+
+	txcb->rtwdev = rtwdev;
+	skb_queue_head_init(&txcb->tx_ack_queue);
+
+	skb_iter = skb_dequeue(list);
+
+	if (skb_queue_empty(list)) {
+		skb_head = skb_iter;
+		goto queue;
+	}
+
+	skb_head = dev_alloc_skb(RTW_USB_MAX_XMITBUF_SZ);
+	if (!skb_head) {
+		skb_head = skb_iter;
+		goto queue;
+	}
+
+	data_ptr = skb_head->data;
+
+	while (skb_iter) {
+		unsigned long flags;
+
+		memcpy(data_ptr, skb_iter->data, skb_iter->len);
+		skb_put(skb_head, skb_iter->len + align_next);
+
+		align_next = ALIGN(skb_iter->len, 8) - skb_iter->len;
+		data_ptr += skb_iter->len + align_next;
+
+		agg_num++;
+
+		skb_queue_tail(&txcb->tx_ack_queue, skb_iter);
+
+		spin_lock_irqsave(&list->lock, flags);
+
+		skb_iter = skb_peek(list);
+
+		if (skb_iter && skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ)
+			__skb_unlink(skb_iter, list);
+		else
+			skb_iter = NULL;
+		spin_unlock_irqrestore(&list->lock, flags);
+	}
+
+	if (agg_num > 1)
+		rtw_usb_fill_tx_checksum(rtwusb, skb_head, agg_num);
+
+queue:
+	skb_queue_tail(&txcb->tx_ack_queue, skb_head);
+
+	rtw_usb_write_port(rtwdev, GET_TX_DESC_QSEL(skb_head->data), skb_head,
+			   rtw_usb_write_port_tx_complete, txcb);
+
+	return true;
+}
+
+static void rtw_usb_tx_handler(struct work_struct *work)
+{
+	struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, tx_work);
+	int i, limit;
+
+	for (i = ARRAY_SIZE(rtwusb->tx_queue) - 1; i >= 0; i--) {
+		for (limit = 0; limit < 200; limit++) {
+			struct sk_buff_head *list = &rtwusb->tx_queue[i];
+
+			if (!rtw_usb_tx_agg_skb(rtwusb, list))
+				break;
+		}
+	}
+}
+
+static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++)
+		skb_queue_purge(&rtwusb->tx_queue[i]);
+}
+
+static void rtw_usb_write_port_complete(struct urb *urb)
+{
+	struct sk_buff *skb = urb->context;
+
+	dev_kfree_skb_any(skb);
+}
+
+static int rtw_usb_write_data(struct rtw_dev *rtwdev,
+			      struct rtw_tx_pkt_info *pkt_info,
+			      u8 *buf)
+{
+	const struct rtw_chip_info *chip = rtwdev->chip;
+	struct sk_buff *skb;
+	unsigned int desclen, headsize, size;
+	u8 qsel;
+	int ret = 0;
+	struct rtw_usb *rtwusb;
+
+	rtwusb = rtw_get_usb_priv(rtwdev);
+
+	size = pkt_info->tx_pkt_size;
+	qsel = pkt_info->qsel;
+	desclen = chip->tx_pkt_desc_sz;
+	headsize = pkt_info->offset ? pkt_info->offset : desclen;
+
+	skb = dev_alloc_skb(headsize + size);
+	if (unlikely(!skb))
+		return -ENOMEM;
+
+	skb_reserve(skb, headsize);
+	skb_put_data(skb, buf, size);
+	skb_push(skb, headsize);
+	memset(skb->data, 0, headsize);
+	rtw_tx_fill_tx_desc(pkt_info, skb);
+	rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
+
+	ret = rtw_usb_write_port(rtwdev, qsel, skb,
+				 rtw_usb_write_port_complete, skb);
+	if (unlikely(ret))
+		rtw_err(rtwdev, "failed to do USB write, ret=%d\n", ret);
+
+	return ret;
+}
+
+static int rtw_usb_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf,
+					u32 size)
+{
+	const struct rtw_chip_info *chip = rtwdev->chip;
+	struct rtw_usb *rtwusb;
+	struct rtw_tx_pkt_info pkt_info = {0};
+	u32 len, desclen;
+
+	rtwusb = rtw_get_usb_priv(rtwdev);
+
+	pkt_info.tx_pkt_size = size;
+	pkt_info.qsel = TX_DESC_QSEL_BEACON;
+
+	desclen = chip->tx_pkt_desc_sz;
+	len = desclen + size;
+	if (len % rtwusb->bulkout_size == 0) {
+		len += RTW_USB_PACKET_OFFSET_SZ;
+		pkt_info.offset = desclen + RTW_USB_PACKET_OFFSET_SZ;
+		pkt_info.pkt_offset = 1;
+	} else {
+		pkt_info.offset = desclen;
+	}
+
+	return rtw_usb_write_data(rtwdev, &pkt_info, buf);
+}
+
+static int rtw_usb_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size)
+{
+	struct rtw_tx_pkt_info pkt_info = {0};
+
+	pkt_info.tx_pkt_size = size;
+	pkt_info.qsel = TX_DESC_QSEL_H2C;
+
+	return rtw_usb_write_data(rtwdev, &pkt_info, buf);
+}
+
+static u8 rtw_usb_tx_queue_mapping_to_qsel(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	__le16 fc = hdr->frame_control;
+	u8 qsel;
+
+	if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)))
+		qsel = TX_DESC_QSEL_MGMT;
+	else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK)
+		qsel = skb->priority;
+	else
+		qsel = TX_DESC_QSEL_BEACON;
+
+	return qsel;
+}
+
+static int rtw_usb_tx_write(struct rtw_dev *rtwdev,
+			    struct rtw_tx_pkt_info *pkt_info,
+			    struct sk_buff *skb)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+	const struct rtw_chip_info *chip = rtwdev->chip;
+	struct rtw_usb_tx_data *tx_data;
+	u8 *pkt_desc;
+	int ep;
+
+	pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
+	memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
+	pkt_info->qsel = rtw_usb_tx_queue_mapping_to_qsel(skb);
+	ep = qsel_to_ep(rtwusb, pkt_info->qsel);
+	rtw_tx_fill_tx_desc(pkt_info, skb);
+	rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
+	tx_data = rtw_usb_get_tx_data(skb);
+	tx_data->sn = pkt_info->sn;
+
+	skb_queue_tail(&rtwusb->tx_queue[ep], skb);
+
+	return 0;
+}
+
+static void rtw_usb_tx_kick_off(struct rtw_dev *rtwdev)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+
+	queue_work(rtwusb->txwq, &rtwusb->tx_work);
+}
+
+static void rtw_usb_rx_handler(struct work_struct *work)
+{
+	struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work);
+	struct rtw_dev *rtwdev = rtwusb->rtwdev;
+	const struct rtw_chip_info *chip = rtwdev->chip;
+	struct rtw_rx_pkt_stat pkt_stat;
+	struct ieee80211_rx_status rx_status;
+	struct sk_buff *skb;
+	u32 pkt_desc_sz = chip->rx_pkt_desc_sz;
+	u32 pkt_offset;
+	u8 *rx_desc;
+	int limit;
+
+	for (limit = 0; limit < 200; limit++) {
+		skb = skb_dequeue(&rtwusb->rx_queue);
+		if (!skb)
+			break;
+
+		rx_desc = skb->data;
+		chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
+					 &rx_status);
+		pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
+			     pkt_stat.shift;
+
+		if (pkt_stat.is_c2h) {
+			skb_put(skb, pkt_stat.pkt_len + pkt_offset);
+			rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb);
+			continue;
+		}
+
+		if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) {
+			rtw_err(rtwdev, "failed to get rx_queue, overflow\n");
+			dev_kfree_skb_any(skb);
+			continue;
+		}
+
+		skb_put(skb, pkt_stat.pkt_len);
+		skb_reserve(skb, pkt_offset);
+		memcpy(skb->cb, &rx_status, sizeof(rx_status));
+		ieee80211_rx_irqsafe(rtwdev->hw, skb);
+	}
+}
+
+static void rtw_usb_read_port_complete(struct urb *urb);
+
+static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb, struct rx_usb_ctrl_block *rxcb)
+{
+	struct rtw_dev *rtwdev = rtwusb->rtwdev;
+	int error;
+
+	rxcb->rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_ATOMIC);
+	if (!rxcb->rx_skb)
+		return;
+
+	usb_fill_bulk_urb(rxcb->rx_urb, rtwusb->udev,
+			  usb_rcvbulkpipe(rtwusb->udev, rtwusb->pipe_in),
+			  rxcb->rx_skb->data, RTW_USB_MAX_RECVBUF_SZ,
+			  rtw_usb_read_port_complete, rxcb);
+
+	error = usb_submit_urb(rxcb->rx_urb, GFP_ATOMIC);
+	if (error) {
+		kfree_skb(rxcb->rx_skb);
+		if (error != -ENODEV)
+			rtw_err(rtwdev, "Err sending rx data urb %d\n",
+				error);
+	}
+}
+
+static void rtw_usb_read_port_complete(struct urb *urb)
+{
+	struct rx_usb_ctrl_block *rxcb = urb->context;
+	struct rtw_dev *rtwdev = rxcb->rtwdev;
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+	struct sk_buff *skb = rxcb->rx_skb;
+
+	if (urb->status == 0) {
+		if (urb->actual_length >= RTW_USB_MAX_RECVBUF_SZ ||
+		    urb->actual_length < 24) {
+			rtw_err(rtwdev, "failed to get urb length:%d\n",
+				urb->actual_length);
+			if (skb)
+				dev_kfree_skb_any(skb);
+		} else {
+			skb_queue_tail(&rtwusb->rx_queue, skb);
+			queue_work(rtwusb->rxwq, &rtwusb->rx_work);
+		}
+		rtw_usb_rx_resubmit(rtwusb, rxcb);
+	} else {
+		switch (urb->status) {
+		case -EINVAL:
+		case -EPIPE:
+		case -ENODEV:
+		case -ESHUTDOWN:
+		case -ENOENT:
+		case -EPROTO:
+		case -EILSEQ:
+		case -ETIME:
+		case -ECOMM:
+		case -EOVERFLOW:
+		case -EINPROGRESS:
+			break;
+		default:
+			rtw_err(rtwdev, "status %d\n", urb->status);
+			break;
+		}
+		if (skb)
+			dev_kfree_skb_any(skb);
+	}
+}
+
+static void rtw_usb_cancel_rx_bufs(struct rtw_usb *rtwusb)
+{
+	struct rx_usb_ctrl_block *rxcb;
+	int i;
+
+	for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
+		rxcb = &rtwusb->rx_cb[i];
+		if (rxcb->rx_urb)
+			usb_kill_urb(rxcb->rx_urb);
+	}
+}
+
+static void rtw_usb_free_rx_bufs(struct rtw_usb *rtwusb)
+{
+	struct rx_usb_ctrl_block *rxcb;
+	int i;
+
+	for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
+		rxcb = &rtwusb->rx_cb[i];
+		if (rxcb->rx_urb) {
+			usb_kill_urb(rxcb->rx_urb);
+			usb_free_urb(rxcb->rx_urb);
+		}
+	}
+}
+
+static int rtw_usb_alloc_rx_bufs(struct rtw_usb *rtwusb)
+{
+	int i;
+
+	for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
+		struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i];
+
+		rxcb->n = i;
+		rxcb->rtwdev = rtwusb->rtwdev;
+		rxcb->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!rxcb->rx_urb)
+			goto err;
+	}
+
+	return 0;
+err:
+	rtw_usb_free_rx_bufs(rtwusb);
+	return -ENOMEM;
+}
+
+static int rtw_usb_setup(struct rtw_dev *rtwdev)
+{
+	/* empty function for rtw_hci_ops */
+	return 0;
+}
+
+static int rtw_usb_start(struct rtw_dev *rtwdev)
+{
+	return 0;
+}
+
+static void rtw_usb_stop(struct rtw_dev *rtwdev)
+{
+}
+
+static void rtw_usb_deep_ps(struct rtw_dev *rtwdev, bool enter)
+{
+	/* empty function for rtw_hci_ops */
+}
+
+static void rtw_usb_link_ps(struct rtw_dev *rtwdev, bool enter)
+{
+	/* empty function for rtw_hci_ops */
+}
+
+static void rtw_usb_interface_cfg(struct rtw_dev *rtwdev)
+{
+	/* empty function for rtw_hci_ops */
+}
+
+static struct rtw_hci_ops rtw_usb_ops = {
+	.tx_write = rtw_usb_tx_write,
+	.tx_kick_off = rtw_usb_tx_kick_off,
+	.setup = rtw_usb_setup,
+	.start = rtw_usb_start,
+	.stop = rtw_usb_stop,
+	.deep_ps = rtw_usb_deep_ps,
+	.link_ps = rtw_usb_link_ps,
+	.interface_cfg = rtw_usb_interface_cfg,
+
+	.write8  = rtw_usb_write8,
+	.write16 = rtw_usb_write16,
+	.write32 = rtw_usb_write32,
+	.read8	= rtw_usb_read8,
+	.read16 = rtw_usb_read16,
+	.read32 = rtw_usb_read32,
+
+	.write_data_rsvd_page = rtw_usb_write_data_rsvd_page,
+	.write_data_h2c = rtw_usb_write_data_h2c,
+};
+
+static int rtw_usb_init_rx(struct rtw_dev *rtwdev)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+	int i;
+
+	rtwusb->rxwq = create_singlethread_workqueue("rtw88_usb: rx wq");
+	if (!rtwusb->rxwq) {
+		rtw_err(rtwdev, "failed to create RX work queue\n");
+		return -ENOMEM;
+	}
+
+	skb_queue_head_init(&rtwusb->rx_queue);
+
+	INIT_WORK(&rtwusb->rx_work, rtw_usb_rx_handler);
+
+	for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
+		struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i];
+
+		rtw_usb_rx_resubmit(rtwusb, rxcb);
+	}
+
+	return 0;
+}
+
+static void rtw_usb_deinit_rx(struct rtw_dev *rtwdev)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+
+	skb_queue_purge(&rtwusb->rx_queue);
+
+	flush_workqueue(rtwusb->rxwq);
+	destroy_workqueue(rtwusb->rxwq);
+}
+
+static int rtw_usb_init_tx(struct rtw_dev *rtwdev)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+	int i;
+
+	rtwusb->txwq = create_singlethread_workqueue("rtw88_usb: tx wq");
+	if (!rtwusb->txwq) {
+		rtw_err(rtwdev, "failed to create TX work queue\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++)
+		skb_queue_head_init(&rtwusb->tx_queue[i]);
+
+	INIT_WORK(&rtwusb->tx_work, rtw_usb_tx_handler);
+
+	return 0;
+}
+
+static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+
+	rtw_usb_tx_queue_purge(rtwusb);
+	flush_workqueue(rtwusb->txwq);
+	destroy_workqueue(rtwusb->txwq);
+}
+
+static int rtw_usb_intf_init(struct rtw_dev *rtwdev,
+			     struct usb_interface *intf)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+	struct usb_device *udev = usb_get_dev(interface_to_usbdev(intf));
+	int ret;
+
+	rtwusb->udev = udev;
+	ret = rtw_usb_parse(rtwdev, intf);
+	if (ret)
+		return ret;
+
+	rtwusb->usb_data = kcalloc(RTW_USB_MAX_RXTX_COUNT, sizeof(u32),
+				   GFP_KERNEL);
+	if (!rtwusb->usb_data)
+		return -ENOMEM;
+
+	usb_set_intfdata(intf, rtwdev->hw);
+
+	SET_IEEE80211_DEV(rtwdev->hw, &intf->dev);
+	spin_lock_init(&rtwusb->usb_lock);
+
+	return 0;
+}
+
+static void rtw_usb_intf_deinit(struct rtw_dev *rtwdev,
+				struct usb_interface *intf)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+
+	usb_put_dev(rtwusb->udev);
+	usb_set_intfdata(intf, NULL);
+}
+
+int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct rtw_dev *rtwdev;
+	struct ieee80211_hw *hw;
+	struct rtw_usb *rtwusb;
+	int drv_data_size;
+	int ret;
+
+	drv_data_size = sizeof(struct rtw_dev) + sizeof(struct rtw_usb);
+	hw = ieee80211_alloc_hw(drv_data_size, &rtw_ops);
+	if (!hw)
+		return -ENOMEM;
+
+	rtwdev = hw->priv;
+	rtwdev->hw = hw;
+	rtwdev->dev = &intf->dev;
+	rtwdev->chip = (struct rtw_chip_info *)id->driver_info;
+	rtwdev->hci.ops = &rtw_usb_ops;
+	rtwdev->hci.type = RTW_HCI_TYPE_USB;
+
+	rtwusb = rtw_get_usb_priv(rtwdev);
+	rtwusb->rtwdev = rtwdev;
+
+	ret = rtw_usb_alloc_rx_bufs(rtwusb);
+	if (ret)
+		return ret;
+
+	ret = rtw_core_init(rtwdev);
+	if (ret)
+		goto err_release_hw;
+
+	ret = rtw_usb_intf_init(rtwdev, intf);
+	if (ret) {
+		rtw_err(rtwdev, "failed to init USB interface\n");
+		goto err_deinit_core;
+	}
+
+	ret = rtw_usb_init_tx(rtwdev);
+	if (ret) {
+		rtw_err(rtwdev, "failed to init USB TX\n");
+		goto err_destroy_usb;
+	}
+
+	ret = rtw_usb_init_rx(rtwdev);
+	if (ret) {
+		rtw_err(rtwdev, "failed to init USB RX\n");
+		goto err_destroy_txwq;
+	}
+
+	ret = rtw_chip_info_setup(rtwdev);
+	if (ret) {
+		rtw_err(rtwdev, "failed to setup chip information\n");
+		goto err_destroy_rxwq;
+	}
+
+	ret = rtw_register_hw(rtwdev, rtwdev->hw);
+	if (ret) {
+		rtw_err(rtwdev, "failed to register hw\n");
+		goto err_destroy_rxwq;
+	}
+
+	return 0;
+
+err_destroy_rxwq:
+	rtw_usb_deinit_rx(rtwdev);
+
+err_destroy_txwq:
+	rtw_usb_deinit_tx(rtwdev);
+
+err_destroy_usb:
+	rtw_usb_intf_deinit(rtwdev, intf);
+
+err_deinit_core:
+	rtw_core_deinit(rtwdev);
+
+err_release_hw:
+	ieee80211_free_hw(hw);
+
+	return ret;
+}
+EXPORT_SYMBOL(rtw_usb_probe);
+
+void rtw_usb_disconnect(struct usb_interface *intf)
+{
+	struct ieee80211_hw *hw = usb_get_intfdata(intf);
+	struct rtw_dev *rtwdev;
+	struct rtw_usb *rtwusb;
+
+	if (!hw)
+		return;
+
+	rtwdev = hw->priv;
+	rtwusb = rtw_get_usb_priv(rtwdev);
+
+	rtw_usb_cancel_rx_bufs(rtwusb);
+
+	rtw_unregister_hw(rtwdev, hw);
+	rtw_usb_deinit_tx(rtwdev);
+	rtw_usb_deinit_rx(rtwdev);
+
+	if (rtwusb->udev->state != USB_STATE_NOTATTACHED)
+		usb_reset_device(rtwusb->udev);
+
+	rtw_usb_free_rx_bufs(rtwusb);
+
+	rtw_usb_intf_deinit(rtwdev, intf);
+	rtw_core_deinit(rtwdev);
+	ieee80211_free_hw(hw);
+}
+EXPORT_SYMBOL(rtw_usb_disconnect);
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless USB driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/usb.h b/drivers/net/wireless/realtek/rtw88/usb.h
new file mode 100644
index 0000000000000..e26f8afb09f29
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/usb.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#ifndef __RTW_USB_H_
+#define __RTW_USB_H_
+
+#define FW_8192C_START_ADDRESS		0x1000
+#define FW_8192C_END_ADDRESS		0x5fff
+
+#define RTW_USB_MAX_RXTX_COUNT		128
+#define RTW_USB_VENQT_MAX_BUF_SIZE	254
+#define MAX_USBCTRL_VENDORREQ_TIMES	10
+
+#define RTW_USB_CMD_READ		0xc0
+#define RTW_USB_CMD_WRITE		0x40
+#define RTW_USB_CMD_REQ			0x05
+
+#define RTW_USB_VENQT_CMD_IDX		0x00
+
+#define RTW_USB_SUPER_SPEED_BULK_SIZE	1024
+#define RTW_USB_HIGH_SPEED_BULK_SIZE	512
+#define RTW_USB_FULL_SPEED_BULK_SIZE	64
+
+#define RTW_USB_TX_SEL_HQ		BIT(0)
+#define RTW_USB_TX_SEL_LQ		BIT(1)
+#define RTW_USB_TX_SEL_NQ		BIT(2)
+#define RTW_USB_TX_SEL_EQ		BIT(3)
+
+#define RTW_USB_BULK_IN_ADDR		0x80
+#define RTW_USB_INT_IN_ADDR		0x81
+
+#define RTW_USB_HW_QUEUE_ENTRY		8
+
+#define RTW_USB_PACKET_OFFSET_SZ	8
+#define RTW_USB_MAX_XMITBUF_SZ		(1024 * 20)
+#define RTW_USB_MAX_RECVBUF_SZ		32768
+
+#define RTW_USB_RECVBUFF_ALIGN_SZ	8
+
+#define RTW_USB_RXAGG_SIZE		6
+#define RTW_USB_RXAGG_TIMEOUT		10
+
+#define RTW_USB_RXCB_NUM		4
+
+#define RTW_USB_EP_MAX			4
+
+#define TX_DESC_QSEL_MAX		20
+
+#define RTW_USB_VENDOR_ID_REALTEK	0x0bda
+
+static inline struct rtw_usb *rtw_get_usb_priv(struct rtw_dev *rtwdev)
+{
+	return (struct rtw_usb *)rtwdev->priv;
+}
+
+struct rx_usb_ctrl_block {
+	struct rtw_dev *rtwdev;
+	struct urb *rx_urb;
+	struct sk_buff *rx_skb;
+	int n;
+};
+
+struct rtw_usb_tx_data {
+	u8 sn;
+};
+
+struct rtw_usb {
+	struct rtw_dev *rtwdev;
+	struct usb_device *udev;
+
+	/* protects usb_data_index */
+	spinlock_t usb_lock;
+	__le32 *usb_data;
+	unsigned int usb_data_index;
+
+	u32 bulkout_size;
+	u8 pipe_interrupt;
+	u8 pipe_in;
+	u8 out_ep[RTW_USB_EP_MAX];
+	u8 qsel_to_ep[TX_DESC_QSEL_MAX];
+	u8 usb_txagg_num;
+
+	struct workqueue_struct *txwq, *rxwq;
+
+	struct sk_buff_head tx_queue[RTW_USB_EP_MAX];
+	struct work_struct tx_work;
+
+	struct rx_usb_ctrl_block rx_cb[RTW_USB_RXCB_NUM];
+	struct sk_buff_head rx_queue;
+	struct work_struct rx_work;
+};
+
+static inline struct rtw_usb_tx_data *rtw_usb_get_tx_data(struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+	BUILD_BUG_ON(sizeof(struct rtw_usb_tx_data) >
+		sizeof(info->status.status_driver_data));
+
+	return (struct rtw_usb_tx_data *)info->status.status_driver_data;
+}
+
+int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id);
+void rtw_usb_disconnect(struct usb_interface *intf);
+
+#endif
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 08/11] rtw88: Add rtw8821cu chipset support
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
                   ` (6 preceding siblings ...)
  2022-11-22 14:52 ` [PATCH v3 07/11] rtw88: Add common USB chip support Sascha Hauer
@ 2022-11-22 14:52 ` Sascha Hauer
  2022-11-28  2:13   ` Ping-Ke Shih
  2022-11-22 14:52 ` [PATCH v3 09/11] rtw88: Add rtw8822bu " Sascha Hauer
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer

Add support for the rtw8821cu chipset based on
https://github.com/ulli-kroll/rtw88-usb.git

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---

Notes:
    Changes since v2:
    - Fix txdesc checksum calculation. The checksum must be calculated over
      a fixed number of words.

 drivers/net/wireless/realtek/rtw88/Kconfig    | 11 ++++
 drivers/net/wireless/realtek/rtw88/Makefile   |  3 ++
 drivers/net/wireless/realtek/rtw88/rtw8821c.c | 18 +++++++
 drivers/net/wireless/realtek/rtw88/rtw8821c.h | 21 ++++++++
 .../net/wireless/realtek/rtw88/rtw8821cu.c    | 50 +++++++++++++++++++
 .../net/wireless/realtek/rtw88/rtw8821cu.h    | 10 ++++
 6 files changed, 113 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821cu.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821cu.h

diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
index 1624c5db69bac..2b500dbefbc2d 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -75,6 +75,17 @@ config RTW88_8821CE
 
 	  802.11ac PCIe wireless network adapter
 
+config RTW88_8821CU
+	tristate "Realtek 8821CU USB wireless network adapter"
+	depends on USB
+	select RTW88_CORE
+	select RTW88_USB
+	select RTW88_8821C
+	help
+	  Select this option will enable support for 8821CU chipset
+
+	  802.11ac USB wireless network adapter
+
 config RTW88_DEBUG
 	bool "Realtek rtw88 debug support"
 	depends on RTW88_CORE
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile
index 9e095f8181483..3c1f08f12e44e 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -44,6 +44,9 @@ rtw88_8821c-objs		:= rtw8821c.o rtw8821c_table.o
 obj-$(CONFIG_RTW88_8821CE)	+= rtw88_8821ce.o
 rtw88_8821ce-objs		:= rtw8821ce.o
 
+obj-$(CONFIG_RTW88_8821CU)	+= rtw88_8821cu.o
+rtw88_8821cu-objs		:= rtw8821cu.o
+
 obj-$(CONFIG_RTW88_PCI)		+= rtw88_pci.o
 obj-$(CONFIG_RTW88_USB)		+= rtw88_usb.o
 rtw88_pci-objs			:= pci.o
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
index 9afdc5ce86b43..17f800f6efbd0 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -26,6 +26,12 @@ static void rtw8821ce_efuse_parsing(struct rtw_efuse *efuse,
 	ether_addr_copy(efuse->addr, map->e.mac_addr);
 }
 
+static void rtw8821cu_efuse_parsing(struct rtw_efuse *efuse,
+				    struct rtw8821c_efuse *map)
+{
+	ether_addr_copy(efuse->addr, map->u.mac_addr);
+}
+
 enum rtw8821ce_rf_set {
 	SWITCH_TO_BTG,
 	SWITCH_TO_WLG,
@@ -68,6 +74,9 @@ static int rtw8821c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
 	case RTW_HCI_TYPE_PCIE:
 		rtw8821ce_efuse_parsing(efuse, map);
 		break;
+	case RTW_HCI_TYPE_USB:
+		rtw8821cu_efuse_parsing(efuse, map);
+		break;
 	default:
 		/* unsupported now */
 		return -ENOTSUPP;
@@ -1148,6 +1157,13 @@ static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl)
 			 dm_info->cck_pd_default + new_lvl * 2);
 }
 
+static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
+					  struct rtw_tx_pkt_info *pkt_info,
+					  u8 *txdesc)
+{
+	fill_txdesc_checksum_common(txdesc, 16);
+}
+
 static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
 	{0x0086,
 	 RTW_PWR_CUT_ALL_MSK,
@@ -1521,6 +1537,7 @@ static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
 	[2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
 	[4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
 	[6] = RTW_DEF_RFE(8821c, 0, 0),
+	[34] = RTW_DEF_RFE(8821c, 0, 0),
 };
 
 static struct rtw_hw_reg rtw8821c_dig[] = {
@@ -1595,6 +1612,7 @@ static struct rtw_chip_ops rtw8821c_ops = {
 	.config_bfee		= rtw8821c_bf_config_bfee,
 	.set_gid_table		= rtw_bf_set_gid_table,
 	.cfg_csi_rate		= rtw_bf_cfg_csi_rate,
+	.fill_txdesc_checksum	= rtw8821c_fill_txdesc_checksum,
 
 	.coex_set_init		= rtw8821c_coex_cfg_init,
 	.coex_set_ant_switch	= rtw8821c_coex_cfg_ant_switch,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h
index 2698801fc35d5..1c81260f3a542 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h
@@ -9,6 +9,26 @@
 
 #define RCR_VHT_ACK		BIT(26)
 
+struct rtw8821cu_efuse {
+	u8 res4[4];			/* 0xd0 */
+	u8 usb_optional_function;
+	u8 res5[0x1e];
+	u8 res6[2];
+	u8 serial[0x0b];		/* 0xf5 */
+	u8 vid;				/* 0x100 */
+	u8 res7;
+	u8 pid;
+	u8 res8[4];
+	u8 mac_addr[ETH_ALEN];		/* 0x107 */
+	u8 res9[2];
+	u8 vendor_name[0x07];
+	u8 res10[2];
+	u8 device_name[0x14];
+	u8 res11[0xcf];
+	u8 package_type;		/* 0x1fb */
+	u8 res12[0x4];
+};
+
 struct rtw8821ce_efuse {
 	u8 mac_addr[ETH_ALEN];		/* 0xd0 */
 	u8 vender_id[2];
@@ -73,6 +93,7 @@ struct rtw8821c_efuse {
 	u8 res[3];
 	union {
 		struct rtw8821ce_efuse e;
+		struct rtw8821cu_efuse u;
 	};
 };
 
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821cu.c b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c
new file mode 100644
index 0000000000000..f43e200515f5b
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "main.h"
+#include "rtw8821cu.h"
+#include "usb.h"
+
+static const struct usb_device_id rtw_8821cu_id_table[] = {
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82b, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb820, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc821, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc820, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82a, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82b, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc811, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8811CU */
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8811, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8811CU */
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2006, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* TOTOLINK A650UA v3 */
+	{},
+};
+MODULE_DEVICE_TABLE(usb, rtw_8821cu_id_table);
+
+static int rtw_8821cu_probe(struct usb_interface *intf,
+			    const struct usb_device_id *id)
+{
+	return rtw_usb_probe(intf, id);
+}
+
+static struct usb_driver rtw_8821cu_driver = {
+	.name = "rtw_8821cu",
+	.id_table = rtw_8821cu_id_table,
+	.probe = rtw_8821cu_probe,
+	.disconnect = rtw_usb_disconnect,
+};
+module_usb_driver(rtw_8821cu_driver);
+
+MODULE_AUTHOR("Hans Ulli Kroll <linux@ulli-kroll.de>");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821cu driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821cu.h b/drivers/net/wireless/realtek/rtw88/rtw8821cu.h
new file mode 100644
index 0000000000000..c896792240011
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#ifndef __RTW_8821CU_H_
+#define __RTW_8821CU_H_
+
+extern struct rtw_chip_info rtw8821c_hw_spec;
+
+#endif
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 09/11] rtw88: Add rtw8822bu chipset support
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
                   ` (7 preceding siblings ...)
  2022-11-22 14:52 ` [PATCH v3 08/11] rtw88: Add rtw8821cu chipset support Sascha Hauer
@ 2022-11-22 14:52 ` Sascha Hauer
  2022-11-28  5:39   ` Ryan Finnie
  2022-11-22 14:52 ` [PATCH v3 10/11] rtw88: Add rtw8822cu " Sascha Hauer
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer

Add support for the rtw8822bu chipset based on
https://github.com/ulli-kroll/rtw88-usb.git

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---

Notes:
    Changes since v1:
    - Add more Device IDs from https://github.com/morrownr/88x2bu-20210702.git

 drivers/net/wireless/realtek/rtw88/Kconfig    | 11 +++
 drivers/net/wireless/realtek/rtw88/Makefile   |  3 +
 drivers/net/wireless/realtek/rtw88/rtw8822b.c | 19 ++++
 .../net/wireless/realtek/rtw88/rtw8822bu.c    | 90 +++++++++++++++++++
 .../net/wireless/realtek/rtw88/rtw8822bu.h    | 10 +++
 5 files changed, 133 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822bu.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822bu.h

diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
index 2b500dbefbc2d..10f4e7f88b858 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -42,6 +42,17 @@ config RTW88_8822BE
 
 	  802.11ac PCIe wireless network adapter
 
+config RTW88_8822BU
+	tristate "Realtek 8822BU USB wireless network adapter"
+	depends on USB
+	select RTW88_CORE
+	select RTW88_USB
+	select RTW88_8822B
+	help
+	  Select this option will enable support for 8822BU chipset
+
+	  802.11ac USB wireless network adapter
+
 config RTW88_8822CE
 	tristate "Realtek 8822CE PCI wireless network adapter"
 	depends on PCI
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile
index 3c1f08f12e44e..1d28cc4fff7b2 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -26,6 +26,9 @@ rtw88_8822b-objs		:= rtw8822b.o rtw8822b_table.o
 obj-$(CONFIG_RTW88_8822BE)	+= rtw88_8822be.o
 rtw88_8822be-objs		:= rtw8822be.o
 
+obj-$(CONFIG_RTW88_8822BU)	+= rtw88_8822bu.o
+rtw88_8822bu-objs		:= rtw8822bu.o
+
 obj-$(CONFIG_RTW88_8822C)	+= rtw88_8822c.o
 rtw88_8822c-objs		:= rtw8822c.o rtw8822c_table.o
 
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index 690e35c98f6e5..74dfb89b2c948 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -26,6 +26,12 @@ static void rtw8822be_efuse_parsing(struct rtw_efuse *efuse,
 	ether_addr_copy(efuse->addr, map->e.mac_addr);
 }
 
+static void rtw8822bu_efuse_parsing(struct rtw_efuse *efuse,
+				    struct rtw8822b_efuse *map)
+{
+	ether_addr_copy(efuse->addr, map->u.mac_addr);
+}
+
 static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
 {
 	struct rtw_efuse *efuse = &rtwdev->efuse;
@@ -56,6 +62,9 @@ static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
 	case RTW_HCI_TYPE_PCIE:
 		rtw8822be_efuse_parsing(efuse, map);
 		break;
+	case RTW_HCI_TYPE_USB:
+		rtw8822bu_efuse_parsing(efuse, map);
+		break;
 	default:
 		/* unsupported now */
 		return -ENOTSUPP;
@@ -1588,6 +1597,15 @@ static void rtw8822b_adaptivity(struct rtw_dev *rtwdev)
 	rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
 }
 
+static void rtw8822b_fill_txdesc_checksum(struct rtw_dev *rtwdev,
+					  struct rtw_tx_pkt_info *pkt_info,
+					  u8 *txdesc)
+{
+	size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
+
+	fill_txdesc_checksum_common(txdesc, words);
+}
+
 static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = {
 	{0x0086,
 	 RTW_PWR_CUT_ALL_MSK,
@@ -2163,6 +2181,7 @@ static struct rtw_chip_ops rtw8822b_ops = {
 	.cfg_csi_rate		= rtw_bf_cfg_csi_rate,
 	.adaptivity_init	= rtw8822b_adaptivity_init,
 	.adaptivity		= rtw8822b_adaptivity,
+	.fill_txdesc_checksum	= rtw8822b_fill_txdesc_checksum,
 
 	.coex_set_init		= rtw8822b_coex_cfg_init,
 	.coex_set_ant_switch	= rtw8822b_coex_cfg_ant_switch,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822bu.c b/drivers/net/wireless/realtek/rtw88/rtw8822bu.c
new file mode 100644
index 0000000000000..d1ddb3a32694f
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "main.h"
+#include "rtw8822bu.h"
+#include "usb.h"
+
+static const struct usb_device_id rtw_8822bu_id_table[] = {
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb812, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82c, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2102, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* CCNC */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb822, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822ULC */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc822, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UTC */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd822, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xe822, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xf822, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UAD */
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb81a, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1841, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS AC1300 USB-AC55 B1 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x184c, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS U2 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x19aa, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS - USB-AC58 rev A1 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1870, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1874, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331e, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-181 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331c, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-182 - D1 */
+	{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331f, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec)}, /* Dlink - DWA-183 D Ver */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB6400M */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0045, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB3600 v2 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012d, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U v1 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0138, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U Plus v1 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0115, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T4U V3 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012e, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0116, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0117, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9055, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Netgear A6150 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0025, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Hawking HW12ACU */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x04ca, 0x8602, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x808a, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */
+	{},
+};
+MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table);
+
+static int rtw8822bu_probe(struct usb_interface *intf,
+			   const struct usb_device_id *id)
+{
+	return rtw_usb_probe(intf, id);
+}
+
+static struct usb_driver rtw_8822bu_driver = {
+	.name = "rtw_8822bu",
+	.id_table = rtw_8822bu_id_table,
+	.probe = rtw8822bu_probe,
+	.disconnect = rtw_usb_disconnect,
+};
+module_usb_driver(rtw_8822bu_driver);
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822bu driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822bu.h b/drivers/net/wireless/realtek/rtw88/rtw8822bu.h
new file mode 100644
index 0000000000000..8a6deb28d13aa
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#ifndef __RTW_8822BU_H_
+#define __RTW_8822BU_H_
+
+extern struct rtw_chip_info rtw8822b_hw_spec;
+
+#endif
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 10/11] rtw88: Add rtw8822cu chipset support
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
                   ` (8 preceding siblings ...)
  2022-11-22 14:52 ` [PATCH v3 09/11] rtw88: Add rtw8822bu " Sascha Hauer
@ 2022-11-22 14:52 ` Sascha Hauer
  2022-11-22 14:52 ` [PATCH v3 11/11] rtw88: Add rtw8723du " Sascha Hauer
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer

Add support for the rtw8822cu chipset based on
https://github.com/ulli-kroll/rtw88-usb.git

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---

Notes:
    Changes since v1:
    - Add more Device IDs from https://github.com/morrownr/8821cu-20210118.git

 drivers/net/wireless/realtek/rtw88/Kconfig    | 11 +++++
 drivers/net/wireless/realtek/rtw88/Makefile   |  3 ++
 drivers/net/wireless/realtek/rtw88/rtw8822c.c | 24 ++++++++++
 .../net/wireless/realtek/rtw88/rtw8822cu.c    | 44 +++++++++++++++++++
 .../net/wireless/realtek/rtw88/rtw8822cu.h    | 10 +++++
 5 files changed, 92 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cu.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cu.h

diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
index 10f4e7f88b858..138289bc5ad0c 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -64,6 +64,17 @@ config RTW88_8822CE
 
 	  802.11ac PCIe wireless network adapter
 
+config RTW88_8822CU
+	tristate "Realtek 8822CU USB wireless network adapter"
+	depends on USB
+	select RTW88_CORE
+	select RTW88_USB
+	select RTW88_8822C
+	help
+	  Select this option will enable support for 8822CU chipset
+
+	  802.11ac USB wireless network adapter
+
 config RTW88_8723DE
 	tristate "Realtek 8723DE PCI wireless network adapter"
 	depends on PCI
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile
index 1d28cc4fff7b2..06883d7323b05 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -35,6 +35,9 @@ rtw88_8822c-objs		:= rtw8822c.o rtw8822c_table.o
 obj-$(CONFIG_RTW88_8822CE)	+= rtw88_8822ce.o
 rtw88_8822ce-objs		:= rtw8822ce.o
 
+obj-$(CONFIG_RTW88_8822CU)	+= rtw88_8822cu.o
+rtw88_8822cu-objs		:= rtw8822cu.o
+
 obj-$(CONFIG_RTW88_8723D)	+= rtw88_8723d.o
 rtw88_8723d-objs		:= rtw8723d.o rtw8723d_table.o
 
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index fccb15dfb9595..964e27887fe2d 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -29,6 +29,12 @@ static void rtw8822ce_efuse_parsing(struct rtw_efuse *efuse,
 	ether_addr_copy(efuse->addr, map->e.mac_addr);
 }
 
+static void rtw8822cu_efuse_parsing(struct rtw_efuse *efuse,
+				    struct rtw8822c_efuse *map)
+{
+	ether_addr_copy(efuse->addr, map->u.mac_addr);
+}
+
 static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
 {
 	struct rtw_efuse *efuse = &rtwdev->efuse;
@@ -58,6 +64,9 @@ static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
 	case RTW_HCI_TYPE_PCIE:
 		rtw8822ce_efuse_parsing(efuse, map);
 		break;
+	case RTW_HCI_TYPE_USB:
+		rtw8822cu_efuse_parsing(efuse, map);
+		break;
 	default:
 		/* unsupported now */
 		return -ENOTSUPP;
@@ -4557,6 +4566,18 @@ static void rtw8822c_adaptivity(struct rtw_dev *rtwdev)
 	rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
 }
 
+static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
+					  struct rtw_tx_pkt_info *pkt_info,
+					  u8 *txdesc)
+{
+	const struct rtw_chip_info *chip = rtwdev->chip;
+	size_t words;
+
+	words = (pkt_info->pkt_offset * 8 + chip->tx_pkt_desc_sz) / 2;
+
+	fill_txdesc_checksum_common(txdesc, words);
+}
+
 static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = {
 	{0x0086,
 	 RTW_PWR_CUT_ALL_MSK,
@@ -4895,6 +4916,8 @@ static const struct rtw_rfe_def rtw8822c_rfe_defs[] = {
 	[0] = RTW_DEF_RFE(8822c, 0, 0),
 	[1] = RTW_DEF_RFE(8822c, 0, 0),
 	[2] = RTW_DEF_RFE(8822c, 0, 0),
+	[3] = RTW_DEF_RFE(8822c, 0, 0),
+	[4] = RTW_DEF_RFE(8822c, 0, 0),
 	[5] = RTW_DEF_RFE(8822c, 0, 5),
 	[6] = RTW_DEF_RFE(8822c, 0, 0),
 };
@@ -4978,6 +5001,7 @@ static struct rtw_chip_ops rtw8822c_ops = {
 	.cfo_track		= rtw8822c_cfo_track,
 	.config_tx_path		= rtw8822c_config_tx_path,
 	.config_txrx_mode	= rtw8822c_config_trx_mode,
+	.fill_txdesc_checksum	= rtw8822c_fill_txdesc_checksum,
 
 	.coex_set_init		= rtw8822c_coex_cfg_init,
 	.coex_set_ant_switch	= NULL,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822cu.c b/drivers/net/wireless/realtek/rtw88/rtw8822cu.c
new file mode 100644
index 0000000000000..f839790e9fd08
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822cu.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "main.h"
+#include "rtw8822cu.h"
+#include "usb.h"
+
+static const struct usb_device_id rtw_8822cu_id_table[] = {
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82c, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc812, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82e, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd820, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd82b, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* Alpha - Alpha */
+	{},
+};
+MODULE_DEVICE_TABLE(usb, rtw_8822cu_id_table);
+
+static int rtw8822bu_probe(struct usb_interface *intf,
+			   const struct usb_device_id *id)
+{
+	return rtw_usb_probe(intf, id);
+}
+
+static struct usb_driver rtw_8822cu_driver = {
+	.name = "rtw_8822cu",
+	.id_table = rtw_8822cu_id_table,
+	.probe = rtw8822bu_probe,
+	.disconnect = rtw_usb_disconnect,
+};
+module_usb_driver(rtw_8822cu_driver);
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cu driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822cu.h b/drivers/net/wireless/realtek/rtw88/rtw8822cu.h
new file mode 100644
index 0000000000000..4b35343aacb1c
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822cu.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#ifndef __RTW_8822CU_H_
+#define __RTW_8822CU_H_
+
+extern struct rtw_chip_info rtw8822c_hw_spec;
+
+#endif
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 11/11] rtw88: Add rtw8723du chipset support
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
                   ` (9 preceding siblings ...)
  2022-11-22 14:52 ` [PATCH v3 10/11] rtw88: Add rtw8822cu " Sascha Hauer
@ 2022-11-22 14:52 ` Sascha Hauer
  2022-11-22 14:55 ` [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
  2022-11-28  3:45 ` Ping-Ke Shih
  12 siblings, 0 replies; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:52 UTC (permalink / raw)
  To: linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Po-Hao Huang,
	Viktor Petrenko, Sascha Hauer

Add support for the rtw8723du chipset based on
https://github.com/ulli-kroll/rtw88-usb.git

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---

Notes:
    Changes since v2:
    - Re-add this patch, tested on hardware now
    
    Changes since v1:
    - Fix txdesc checksum calculation: Unlike other chips this one needs
      a chksum = ~chksum at the end
    - Fix efuse layout (struct rtw8723de_efuse and struct rtw8723du_efuse need
      to be in a union as they are used alternatively)

 drivers/net/wireless/realtek/rtw88/Kconfig    | 11 ++++++
 drivers/net/wireless/realtek/rtw88/Makefile   |  3 ++
 drivers/net/wireless/realtek/rtw88/rtw8723d.c | 28 +++++++++++++++
 drivers/net/wireless/realtek/rtw88/rtw8723d.h | 13 ++++++-
 .../net/wireless/realtek/rtw88/rtw8723du.c    | 36 +++++++++++++++++++
 .../net/wireless/realtek/rtw88/rtw8723du.h    | 10 ++++++
 6 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723du.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723du.h

diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
index 138289bc5ad0c..651ab56d9c6bd 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -86,6 +86,17 @@ config RTW88_8723DE
 
 	  802.11n PCIe wireless network adapter
 
+config RTW88_8723DU
+	tristate "Realtek 8723DU USB wireless network adapter"
+	depends on USB
+	select RTW88_CORE
+	select RTW88_USB
+	select RTW88_8723D
+	help
+	  Select this option will enable support for 8723DU chipset
+
+	  802.11n USB wireless network adapter
+
 config RTW88_8821CE
 	tristate "Realtek 8821CE PCI wireless network adapter"
 	depends on PCI
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile
index 06883d7323b05..e0950dbc2565a 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -44,6 +44,9 @@ rtw88_8723d-objs		:= rtw8723d.o rtw8723d_table.o
 obj-$(CONFIG_RTW88_8723DE)	+= rtw88_8723de.o
 rtw88_8723de-objs		:= rtw8723de.o
 
+obj-$(CONFIG_RTW88_8723DU)	+= rtw88_8723du.o
+rtw88_8723du-objs		:= rtw8723du.o
+
 obj-$(CONFIG_RTW88_8821C)	+= rtw88_8821c.o
 rtw88_8821c-objs		:= rtw8821c.o rtw8821c_table.o
 
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index 0a4f770fcbb7e..2d2f768bae2ea 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -210,6 +210,12 @@ static void rtw8723de_efuse_parsing(struct rtw_efuse *efuse,
 	ether_addr_copy(efuse->addr, map->e.mac_addr);
 }
 
+static void rtw8723du_efuse_parsing(struct rtw_efuse *efuse,
+				    struct rtw8723d_efuse *map)
+{
+	ether_addr_copy(efuse->addr, map->u.mac_addr);
+}
+
 static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
 {
 	struct rtw_efuse *efuse = &rtwdev->efuse;
@@ -239,6 +245,9 @@ static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
 	case RTW_HCI_TYPE_PCIE:
 		rtw8723de_efuse_parsing(efuse, map);
 		break;
+	case RTW_HCI_TYPE_USB:
+		rtw8723du_efuse_parsing(efuse, map);
+		break;
 	default:
 		/* unsupported now */
 		return -ENOTSUPP;
@@ -1945,6 +1954,24 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev)
 	dm_info->pwr_trk_triggered = false;
 }
 
+static void rtw8723d_fill_txdesc_checksum(struct rtw_dev *rtwdev,
+					  struct rtw_tx_pkt_info *pkt_info,
+					  u8 *txdesc)
+{
+	size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
+	__le16 chksum = 0;
+	__le16 *data = (__le16 *)(txdesc);
+
+	SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000);
+
+	while (words--)
+		chksum ^= *data++;
+
+	chksum = ~chksum;
+
+	SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum));
+}
+
 static struct rtw_chip_ops rtw8723d_ops = {
 	.phy_set_param		= rtw8723d_phy_set_param,
 	.read_efuse		= rtw8723d_read_efuse,
@@ -1965,6 +1992,7 @@ static struct rtw_chip_ops rtw8723d_ops = {
 	.config_bfee		= NULL,
 	.set_gid_table		= NULL,
 	.cfg_csi_rate		= NULL,
+	.fill_txdesc_checksum	= rtw8723d_fill_txdesc_checksum,
 
 	.coex_set_init		= rtw8723d_coex_cfg_init,
 	.coex_set_ant_switch	= NULL,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
index 4641f6e047b41..a356318a5c15b 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
@@ -41,6 +41,14 @@ struct rtw8723de_efuse {
 	u8 sub_device_id[2];
 };
 
+struct rtw8723du_efuse {
+	u8 res4[48];                    /* 0xd0 */
+	u8 vender_id[2];                /* 0x100 */
+	u8 product_id[2];               /* 0x102 */
+	u8 usb_option;                  /* 0x104 */
+	u8 mac_addr[ETH_ALEN];          /* 0x107 */
+};
+
 struct rtw8723d_efuse {
 	__le16 rtl_id;
 	u8 rsvd[2];
@@ -69,7 +77,10 @@ struct rtw8723d_efuse {
 	u8 rfe_option;
 	u8 country_code[2];
 	u8 res[3];
-	struct rtw8723de_efuse e;
+	union {
+		struct rtw8723de_efuse e;
+		struct rtw8723du_efuse u;
+	};
 };
 
 extern const struct rtw_chip_info rtw8723d_hw_spec;
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723du.c b/drivers/net/wireless/realtek/rtw88/rtw8723du.c
new file mode 100644
index 0000000000000..d2c8a114d19af
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "main.h"
+#include "rtw8723du.h"
+#include "usb.h"
+
+static const struct usb_device_id rtw_8723du_id_table[] = {
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK,
+					0xD723,
+					0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8723d_hw_spec) }, /* 8723DU 1*1 */
+	{ },
+};
+MODULE_DEVICE_TABLE(usb, rtw_8723du_id_table);
+
+static int rtw8723du_probe(struct usb_interface *intf,
+			   const struct usb_device_id *id)
+{
+	return rtw_usb_probe(intf, id);
+}
+
+static struct usb_driver rtw_8723du_driver = {
+	.name = "rtw_8723du",
+	.id_table = rtw_8723du_id_table,
+	.probe = rtw8723du_probe,
+	.disconnect = rtw_usb_disconnect,
+};
+module_usb_driver(rtw_8723du_driver);
+
+MODULE_AUTHOR("Hans Ulli Kroll <linux@ulli-kroll.de>");
+MODULE_DESCRIPTION("Realtek 802.11n wireless 8723du driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723du.h b/drivers/net/wireless/realtek/rtw88/rtw8723du.h
new file mode 100644
index 0000000000000..c0ffd621f087d
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#ifndef __RTW_8723DU_H_
+#define __RTW_8723DU_H_
+
+extern struct rtw_chip_info rtw8723d_hw_spec;
+
+#endif
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 00/11] RTW88: Add support for USB variants
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
                   ` (10 preceding siblings ...)
  2022-11-22 14:52 ` [PATCH v3 11/11] rtw88: Add rtw8723du " Sascha Hauer
@ 2022-11-22 14:55 ` Sascha Hauer
  2022-11-24  6:48   ` Ping-Ke Shih
  2022-11-28  3:45 ` Ping-Ke Shih
  12 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2022-11-22 14:55 UTC (permalink / raw)
  To: Po-Hao Huang
  Cc: linux-wireless, Ping-Ke Shih, Hans Ulli Kroll,
	Martin Blumenstingl, netdev, Kalle Valo, Yan-Hsuan Chuang,
	linux-kernel, Viktor Petrenko, Neo Jou, Po-Hao Huang, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue

On Tue, Nov 22, 2022 at 03:52:15PM +0100, Sascha Hauer wrote:
> This is the third round of adding support for the USB variants to the
> RTW88 driver. There are a few changes to the last version which make it
> worth looking at this version.
> 
> First of all RTL8723du and RTL8821cu are tested working now. The issue
> here was that the txdesc checksum calculation was wrong. I found the
> correct calculation in various downstream drivers found on github.
> 
> The second big issue was that TX packet aggregation was wrong. When
> aggregating packets each packet start has to be aligned to eight bytes.
> The necessary alignment was added to the total URB length before
> checking if there is another packet to aggregate, so the URB length
> included that padding after the last packet, which is wrong.  Fixing
> this makes the driver work much more reliably.
> 
> I added all people to Cc: who showed interest in this driver and I want
> to welcome you for testing and reviewing.

There still is a problem with the RTL8822cu chipset I have here.  When
using NetworkManager I immediately lose the connection to the AP after
it has been connected:

[  376.213846] wlan0: authenticate with 76:83:c2:ce:81:b1
[  380.085463] wlan0: send auth to 76:83:c2:ce:81:b1 (try 1/3)
[  380.091446] wlan0: authenticated
[  380.108864] wlan0: associate with 76:83:c2:ce:81:b1 (try 1/3)
[  380.136448] wlan0: RX AssocResp from 76:83:c2:ce:81:b1 (capab=0x1411 status=0 aid=2)
[  380.202955] wlan0: associated
[  380.268140] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
[  380.275328] wlan0: Connection to AP 76:83:c2:ce:81:b1 lost

That doesn't happen when using plain wpa_supplicant. This seems to go
down to cd96e22bc1da ("rtw88: add beacon filter support"). After being
connected I get a BCN_FILTER_CONNECTION_LOSS beacon. Plain
wpa_supplicant seems to go another code patch and doesn't activate
connection quality monitoring.

The connection to the AP works fluently also with NetworkManager though
when I just ignore the BCN_FILTER_CONNECTION_LOSS beacon.

Any idea what may be wrong here?

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH v3 00/11] RTW88: Add support for USB variants
  2022-11-22 14:55 ` [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
@ 2022-11-24  6:48   ` Ping-Ke Shih
  2022-11-24  8:21     ` Sascha Hauer
  0 siblings, 1 reply; 29+ messages in thread
From: Ping-Ke Shih @ 2022-11-24  6:48 UTC (permalink / raw)
  To: Sascha Hauer, Bernie Huang
  Cc: linux-wireless, Hans Ulli Kroll, Martin Blumenstingl, netdev,
	Kalle Valo, Yan-Hsuan Chuang, linux-kernel, Viktor Petrenko,
	Neo Jou, Bernie Huang, kernel, Johannes Berg, Alexander Hochbaum,
	Da Xue


> -----Original Message-----
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Sent: Tuesday, November 22, 2022 10:55 PM
> To: Bernie Huang <phhuang@realtek.com>
> Cc: linux-wireless@vger.kernel.org; Ping-Ke Shih <pkshih@realtek.com>; Hans Ulli Kroll
> <linux@ulli-kroll.de>; Martin Blumenstingl <martin.blumenstingl@googlemail.com>; netdev@vger.kernel.org;
> Kalle Valo <kvalo@kernel.org>; Yan-Hsuan Chuang <tony0620emma@gmail.com>; linux-kernel@vger.kernel.org;
> Viktor Petrenko <g0000ga@gmail.com>; Neo Jou <neojou@gmail.com>; Bernie Huang <phhuang@realtek.com>;
> kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>;
> Da Xue <da@libre.computer>
> Subject: Re: [PATCH v3 00/11] RTW88: Add support for USB variants
> 
> On Tue, Nov 22, 2022 at 03:52:15PM +0100, Sascha Hauer wrote:
> > This is the third round of adding support for the USB variants to the
> > RTW88 driver. There are a few changes to the last version which make it
> > worth looking at this version.
> >
> > First of all RTL8723du and RTL8821cu are tested working now. The issue
> > here was that the txdesc checksum calculation was wrong. I found the
> > correct calculation in various downstream drivers found on github.
> >
> > The second big issue was that TX packet aggregation was wrong. When
> > aggregating packets each packet start has to be aligned to eight bytes.
> > The necessary alignment was added to the total URB length before
> > checking if there is another packet to aggregate, so the URB length
> > included that padding after the last packet, which is wrong.  Fixing
> > this makes the driver work much more reliably.
> >
> > I added all people to Cc: who showed interest in this driver and I want
> > to welcome you for testing and reviewing.
> 
> There still is a problem with the RTL8822cu chipset I have here.  When
> using NetworkManager I immediately lose the connection to the AP after
> it has been connected:
> 
> [  376.213846] wlan0: authenticate with 76:83:c2:ce:81:b1
> [  380.085463] wlan0: send auth to 76:83:c2:ce:81:b1 (try 1/3)
> [  380.091446] wlan0: authenticated
> [  380.108864] wlan0: associate with 76:83:c2:ce:81:b1 (try 1/3)
> [  380.136448] wlan0: RX AssocResp from 76:83:c2:ce:81:b1 (capab=0x1411 status=0 aid=2)
> [  380.202955] wlan0: associated
> [  380.268140] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
> [  380.275328] wlan0: Connection to AP 76:83:c2:ce:81:b1 lost
> 
> That doesn't happen when using plain wpa_supplicant. This seems to go
> down to cd96e22bc1da ("rtw88: add beacon filter support"). After being
> connected I get a BCN_FILTER_CONNECTION_LOSS beacon. Plain
> wpa_supplicant seems to go another code patch and doesn't activate
> connection quality monitoring.
> 
> The connection to the AP works fluently also with NetworkManager though
> when I just ignore the BCN_FILTER_CONNECTION_LOSS beacon.
> 
> Any idea what may be wrong here?
> 

Please reference to below patch to see if it can work to you.

https://lore.kernel.org/linux-wireless/20221124064442.28042-1-pkshih@realtek.com/T/#u

Ping-Ke


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 00/11] RTW88: Add support for USB variants
  2022-11-24  6:48   ` Ping-Ke Shih
@ 2022-11-24  8:21     ` Sascha Hauer
  2022-11-24  8:26       ` Ping-Ke Shih
                         ` (2 more replies)
  0 siblings, 3 replies; 29+ messages in thread
From: Sascha Hauer @ 2022-11-24  8:21 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: Bernie Huang, linux-wireless, Hans Ulli Kroll,
	Martin Blumenstingl, netdev, Kalle Valo, Yan-Hsuan Chuang,
	linux-kernel, Viktor Petrenko, Neo Jou, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue

On Thu, Nov 24, 2022 at 06:48:23AM +0000, Ping-Ke Shih wrote:
> 
> > -----Original Message-----
> > From: Sascha Hauer <s.hauer@pengutronix.de>
> > Sent: Tuesday, November 22, 2022 10:55 PM
> > To: Bernie Huang <phhuang@realtek.com>
> > Cc: linux-wireless@vger.kernel.org; Ping-Ke Shih <pkshih@realtek.com>; Hans Ulli Kroll
> > <linux@ulli-kroll.de>; Martin Blumenstingl <martin.blumenstingl@googlemail.com>; netdev@vger.kernel.org;
> > Kalle Valo <kvalo@kernel.org>; Yan-Hsuan Chuang <tony0620emma@gmail.com>; linux-kernel@vger.kernel.org;
> > Viktor Petrenko <g0000ga@gmail.com>; Neo Jou <neojou@gmail.com>; Bernie Huang <phhuang@realtek.com>;
> > kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>;
> > Da Xue <da@libre.computer>
> > Subject: Re: [PATCH v3 00/11] RTW88: Add support for USB variants
> > 
> > On Tue, Nov 22, 2022 at 03:52:15PM +0100, Sascha Hauer wrote:
> > > This is the third round of adding support for the USB variants to the
> > > RTW88 driver. There are a few changes to the last version which make it
> > > worth looking at this version.
> > >
> > > First of all RTL8723du and RTL8821cu are tested working now. The issue
> > > here was that the txdesc checksum calculation was wrong. I found the
> > > correct calculation in various downstream drivers found on github.
> > >
> > > The second big issue was that TX packet aggregation was wrong. When
> > > aggregating packets each packet start has to be aligned to eight bytes.
> > > The necessary alignment was added to the total URB length before
> > > checking if there is another packet to aggregate, so the URB length
> > > included that padding after the last packet, which is wrong.  Fixing
> > > this makes the driver work much more reliably.
> > >
> > > I added all people to Cc: who showed interest in this driver and I want
> > > to welcome you for testing and reviewing.
> > 
> > There still is a problem with the RTL8822cu chipset I have here.  When
> > using NetworkManager I immediately lose the connection to the AP after
> > it has been connected:
> > 
> > [  376.213846] wlan0: authenticate with 76:83:c2:ce:81:b1
> > [  380.085463] wlan0: send auth to 76:83:c2:ce:81:b1 (try 1/3)
> > [  380.091446] wlan0: authenticated
> > [  380.108864] wlan0: associate with 76:83:c2:ce:81:b1 (try 1/3)
> > [  380.136448] wlan0: RX AssocResp from 76:83:c2:ce:81:b1 (capab=0x1411 status=0 aid=2)
> > [  380.202955] wlan0: associated
> > [  380.268140] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
> > [  380.275328] wlan0: Connection to AP 76:83:c2:ce:81:b1 lost
> > 
> > That doesn't happen when using plain wpa_supplicant. This seems to go
> > down to cd96e22bc1da ("rtw88: add beacon filter support"). After being
> > connected I get a BCN_FILTER_CONNECTION_LOSS beacon. Plain
> > wpa_supplicant seems to go another code patch and doesn't activate
> > connection quality monitoring.
> > 
> > The connection to the AP works fluently also with NetworkManager though
> > when I just ignore the BCN_FILTER_CONNECTION_LOSS beacon.
> > 
> > Any idea what may be wrong here?
> > 
> 
> Please reference to below patch to see if it can work to you.
> 
> https://lore.kernel.org/linux-wireless/20221124064442.28042-1-pkshih@realtek.com/T/#u

Great! That solves this issue \o/

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH v3 00/11] RTW88: Add support for USB variants
  2022-11-24  8:21     ` Sascha Hauer
@ 2022-11-24  8:26       ` Ping-Ke Shih
  2022-11-24  8:36         ` Sascha Hauer
  2022-11-24  8:33       ` Kalle Valo
  2022-11-24  9:20       ` Sascha Hauer
  2 siblings, 1 reply; 29+ messages in thread
From: Ping-Ke Shih @ 2022-11-24  8:26 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Bernie Huang, linux-wireless, Hans Ulli Kroll,
	Martin Blumenstingl, netdev, Kalle Valo, Yan-Hsuan Chuang,
	linux-kernel, Viktor Petrenko, Neo Jou, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue



> -----Original Message-----
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Sent: Thursday, November 24, 2022 4:22 PM
> To: Ping-Ke Shih <pkshih@realtek.com>
> Cc: Bernie Huang <phhuang@realtek.com>; linux-wireless@vger.kernel.org; Hans Ulli Kroll
> <linux@ulli-kroll.de>; Martin Blumenstingl <martin.blumenstingl@googlemail.com>; netdev@vger.kernel.org;
> Kalle Valo <kvalo@kernel.org>; Yan-Hsuan Chuang <tony0620emma@gmail.com>; linux-kernel@vger.kernel.org;
> Viktor Petrenko <g0000ga@gmail.com>; Neo Jou <neojou@gmail.com>; kernel@pengutronix.de; Johannes Berg
> <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>; Da Xue <da@libre.computer>
> Subject: Re: [PATCH v3 00/11] RTW88: Add support for USB variants
> 
> On Thu, Nov 24, 2022 at 06:48:23AM +0000, Ping-Ke Shih wrote:
> >
> > > -----Original Message-----
> > > From: Sascha Hauer <s.hauer@pengutronix.de>
> > > Sent: Tuesday, November 22, 2022 10:55 PM
> > > To: Bernie Huang <phhuang@realtek.com>
> > > Cc: linux-wireless@vger.kernel.org; Ping-Ke Shih <pkshih@realtek.com>; Hans Ulli Kroll
> > > <linux@ulli-kroll.de>; Martin Blumenstingl <martin.blumenstingl@googlemail.com>;
> netdev@vger.kernel.org;
> > > Kalle Valo <kvalo@kernel.org>; Yan-Hsuan Chuang <tony0620emma@gmail.com>;
> linux-kernel@vger.kernel.org;
> > > Viktor Petrenko <g0000ga@gmail.com>; Neo Jou <neojou@gmail.com>; Bernie Huang <phhuang@realtek.com>;
> > > kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum
> <alex@appudo.com>;
> > > Da Xue <da@libre.computer>
> > > Subject: Re: [PATCH v3 00/11] RTW88: Add support for USB variants
> > >
> > > On Tue, Nov 22, 2022 at 03:52:15PM +0100, Sascha Hauer wrote:
> > > > This is the third round of adding support for the USB variants to the
> > > > RTW88 driver. There are a few changes to the last version which make it
> > > > worth looking at this version.
> > > >
> > > > First of all RTL8723du and RTL8821cu are tested working now. The issue
> > > > here was that the txdesc checksum calculation was wrong. I found the
> > > > correct calculation in various downstream drivers found on github.
> > > >
> > > > The second big issue was that TX packet aggregation was wrong. When
> > > > aggregating packets each packet start has to be aligned to eight bytes.
> > > > The necessary alignment was added to the total URB length before
> > > > checking if there is another packet to aggregate, so the URB length
> > > > included that padding after the last packet, which is wrong.  Fixing
> > > > this makes the driver work much more reliably.
> > > >
> > > > I added all people to Cc: who showed interest in this driver and I want
> > > > to welcome you for testing and reviewing.
> > >
> > > There still is a problem with the RTL8822cu chipset I have here.  When
> > > using NetworkManager I immediately lose the connection to the AP after
> > > it has been connected:
> > >
> > > [  376.213846] wlan0: authenticate with 76:83:c2:ce:81:b1
> > > [  380.085463] wlan0: send auth to 76:83:c2:ce:81:b1 (try 1/3)
> > > [  380.091446] wlan0: authenticated
> > > [  380.108864] wlan0: associate with 76:83:c2:ce:81:b1 (try 1/3)
> > > [  380.136448] wlan0: RX AssocResp from 76:83:c2:ce:81:b1 (capab=0x1411 status=0 aid=2)
> > > [  380.202955] wlan0: associated
> > > [  380.268140] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
> > > [  380.275328] wlan0: Connection to AP 76:83:c2:ce:81:b1 lost
> > >
> > > That doesn't happen when using plain wpa_supplicant. This seems to go
> > > down to cd96e22bc1da ("rtw88: add beacon filter support"). After being
> > > connected I get a BCN_FILTER_CONNECTION_LOSS beacon. Plain
> > > wpa_supplicant seems to go another code patch and doesn't activate
> > > connection quality monitoring.
> > >
> > > The connection to the AP works fluently also with NetworkManager though
> > > when I just ignore the BCN_FILTER_CONNECTION_LOSS beacon.
> > >
> > > Any idea what may be wrong here?
> > >
> >
> > Please reference to below patch to see if it can work to you.
> >
> > https://lore.kernel.org/linux-wireless/20221124064442.28042-1-pkshih@realtek.com/T/#u
> 
> Great! That solves this issue \o/
> 

Do you mind to add "Tested-by:" tag to the patch?  :-)

Ping-Ke



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 00/11] RTW88: Add support for USB variants
  2022-11-24  8:21     ` Sascha Hauer
  2022-11-24  8:26       ` Ping-Ke Shih
@ 2022-11-24  8:33       ` Kalle Valo
  2022-11-24  9:20       ` Sascha Hauer
  2 siblings, 0 replies; 29+ messages in thread
From: Kalle Valo @ 2022-11-24  8:33 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Ping-Ke Shih, Bernie Huang, linux-wireless, Hans Ulli Kroll,
	Martin Blumenstingl, netdev, Yan-Hsuan Chuang, linux-kernel,
	Viktor Petrenko, Neo Jou, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue

Sascha Hauer <s.hauer@pengutronix.de> writes:

>> > There still is a problem with the RTL8822cu chipset I have here.  When
>> > using NetworkManager I immediately lose the connection to the AP after
>> > it has been connected:
>> > 
>> > [  376.213846] wlan0: authenticate with 76:83:c2:ce:81:b1
>> > [  380.085463] wlan0: send auth to 76:83:c2:ce:81:b1 (try 1/3)
>> > [  380.091446] wlan0: authenticated
>> > [  380.108864] wlan0: associate with 76:83:c2:ce:81:b1 (try 1/3)
>> > [ 380.136448] wlan0: RX AssocResp from 76:83:c2:ce:81:b1
>> > (capab=0x1411 status=0 aid=2)
>> > [  380.202955] wlan0: associated
>> > [  380.268140] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
>> > [  380.275328] wlan0: Connection to AP 76:83:c2:ce:81:b1 lost
>> > 
>> > That doesn't happen when using plain wpa_supplicant. This seems to go
>> > down to cd96e22bc1da ("rtw88: add beacon filter support"). After being
>> > connected I get a BCN_FILTER_CONNECTION_LOSS beacon. Plain
>> > wpa_supplicant seems to go another code patch and doesn't activate
>> > connection quality monitoring.
>> > 
>> > The connection to the AP works fluently also with NetworkManager though
>> > when I just ignore the BCN_FILTER_CONNECTION_LOSS beacon.
>> > 
>> > Any idea what may be wrong here?
>> > 
>> 
>> Please reference to below patch to see if it can work to you.
>> 
>> https://lore.kernel.org/linux-wireless/20221124064442.28042-1-pkshih@realtek.com/T/#u
>
> Great! That solves this issue \o/

Awesome, great work Ping and Ji-Pin!

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 00/11] RTW88: Add support for USB variants
  2022-11-24  8:26       ` Ping-Ke Shih
@ 2022-11-24  8:36         ` Sascha Hauer
  0 siblings, 0 replies; 29+ messages in thread
From: Sascha Hauer @ 2022-11-24  8:36 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: Bernie Huang, linux-wireless, Hans Ulli Kroll,
	Martin Blumenstingl, netdev, Kalle Valo, Yan-Hsuan Chuang,
	linux-kernel, Viktor Petrenko, Neo Jou, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue

On Thu, Nov 24, 2022 at 08:26:23AM +0000, Ping-Ke Shih wrote:
> 
> 
> > -----Original Message-----
> > From: Sascha Hauer <s.hauer@pengutronix.de>
> > Sent: Thursday, November 24, 2022 4:22 PM
> > To: Ping-Ke Shih <pkshih@realtek.com>
> > Cc: Bernie Huang <phhuang@realtek.com>; linux-wireless@vger.kernel.org; Hans Ulli Kroll
> > <linux@ulli-kroll.de>; Martin Blumenstingl <martin.blumenstingl@googlemail.com>; netdev@vger.kernel.org;
> > Kalle Valo <kvalo@kernel.org>; Yan-Hsuan Chuang <tony0620emma@gmail.com>; linux-kernel@vger.kernel.org;
> > Viktor Petrenko <g0000ga@gmail.com>; Neo Jou <neojou@gmail.com>; kernel@pengutronix.de; Johannes Berg
> > <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>; Da Xue <da@libre.computer>
> > Subject: Re: [PATCH v3 00/11] RTW88: Add support for USB variants
> > 
> > On Thu, Nov 24, 2022 at 06:48:23AM +0000, Ping-Ke Shih wrote:
> > >
> > > > -----Original Message-----
> > > > From: Sascha Hauer <s.hauer@pengutronix.de>
> > > > Sent: Tuesday, November 22, 2022 10:55 PM
> > > > To: Bernie Huang <phhuang@realtek.com>
> > > > Cc: linux-wireless@vger.kernel.org; Ping-Ke Shih <pkshih@realtek.com>; Hans Ulli Kroll
> > > > <linux@ulli-kroll.de>; Martin Blumenstingl <martin.blumenstingl@googlemail.com>;
> > netdev@vger.kernel.org;
> > > > Kalle Valo <kvalo@kernel.org>; Yan-Hsuan Chuang <tony0620emma@gmail.com>;
> > linux-kernel@vger.kernel.org;
> > > > Viktor Petrenko <g0000ga@gmail.com>; Neo Jou <neojou@gmail.com>; Bernie Huang <phhuang@realtek.com>;
> > > > kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum
> > <alex@appudo.com>;
> > > > Da Xue <da@libre.computer>
> > > > Subject: Re: [PATCH v3 00/11] RTW88: Add support for USB variants
> > > >
> > > > On Tue, Nov 22, 2022 at 03:52:15PM +0100, Sascha Hauer wrote:
> > > > > This is the third round of adding support for the USB variants to the
> > > > > RTW88 driver. There are a few changes to the last version which make it
> > > > > worth looking at this version.
> > > > >
> > > > > First of all RTL8723du and RTL8821cu are tested working now. The issue
> > > > > here was that the txdesc checksum calculation was wrong. I found the
> > > > > correct calculation in various downstream drivers found on github.
> > > > >
> > > > > The second big issue was that TX packet aggregation was wrong. When
> > > > > aggregating packets each packet start has to be aligned to eight bytes.
> > > > > The necessary alignment was added to the total URB length before
> > > > > checking if there is another packet to aggregate, so the URB length
> > > > > included that padding after the last packet, which is wrong.  Fixing
> > > > > this makes the driver work much more reliably.
> > > > >
> > > > > I added all people to Cc: who showed interest in this driver and I want
> > > > > to welcome you for testing and reviewing.
> > > >
> > > > There still is a problem with the RTL8822cu chipset I have here.  When
> > > > using NetworkManager I immediately lose the connection to the AP after
> > > > it has been connected:
> > > >
> > > > [  376.213846] wlan0: authenticate with 76:83:c2:ce:81:b1
> > > > [  380.085463] wlan0: send auth to 76:83:c2:ce:81:b1 (try 1/3)
> > > > [  380.091446] wlan0: authenticated
> > > > [  380.108864] wlan0: associate with 76:83:c2:ce:81:b1 (try 1/3)
> > > > [  380.136448] wlan0: RX AssocResp from 76:83:c2:ce:81:b1 (capab=0x1411 status=0 aid=2)
> > > > [  380.202955] wlan0: associated
> > > > [  380.268140] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
> > > > [  380.275328] wlan0: Connection to AP 76:83:c2:ce:81:b1 lost
> > > >
> > > > That doesn't happen when using plain wpa_supplicant. This seems to go
> > > > down to cd96e22bc1da ("rtw88: add beacon filter support"). After being
> > > > connected I get a BCN_FILTER_CONNECTION_LOSS beacon. Plain
> > > > wpa_supplicant seems to go another code patch and doesn't activate
> > > > connection quality monitoring.
> > > >
> > > > The connection to the AP works fluently also with NetworkManager though
> > > > when I just ignore the BCN_FILTER_CONNECTION_LOSS beacon.
> > > >
> > > > Any idea what may be wrong here?
> > > >
> > >
> > > Please reference to below patch to see if it can work to you.
> > >
> > > https://lore.kernel.org/linux-wireless/20221124064442.28042-1-pkshih@realtek.com/T/#u
> > 
> > Great! That solves this issue \o/
> > 
> 
> Do you mind to add "Tested-by:" tag to the patch?  :-)

You should already find it in your inbox. Thank you very much for the
fast response :)

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 00/11] RTW88: Add support for USB variants
  2022-11-24  8:21     ` Sascha Hauer
  2022-11-24  8:26       ` Ping-Ke Shih
  2022-11-24  8:33       ` Kalle Valo
@ 2022-11-24  9:20       ` Sascha Hauer
  2 siblings, 0 replies; 29+ messages in thread
From: Sascha Hauer @ 2022-11-24  9:20 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: Bernie Huang, linux-wireless, Hans Ulli Kroll,
	Martin Blumenstingl, netdev, Kalle Valo, Yan-Hsuan Chuang,
	linux-kernel, Viktor Petrenko, Neo Jou, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue

On Thu, Nov 24, 2022 at 09:21:58AM +0100, Sascha Hauer wrote:
> On Thu, Nov 24, 2022 at 06:48:23AM +0000, Ping-Ke Shih wrote:
> > 
> > > -----Original Message-----
> > > From: Sascha Hauer <s.hauer@pengutronix.de>
> > > Sent: Tuesday, November 22, 2022 10:55 PM
> > > To: Bernie Huang <phhuang@realtek.com>
> > > Cc: linux-wireless@vger.kernel.org; Ping-Ke Shih <pkshih@realtek.com>; Hans Ulli Kroll
> > > <linux@ulli-kroll.de>; Martin Blumenstingl <martin.blumenstingl@googlemail.com>; netdev@vger.kernel.org;
> > > Kalle Valo <kvalo@kernel.org>; Yan-Hsuan Chuang <tony0620emma@gmail.com>; linux-kernel@vger.kernel.org;
> > > Viktor Petrenko <g0000ga@gmail.com>; Neo Jou <neojou@gmail.com>; Bernie Huang <phhuang@realtek.com>;
> > > kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>;
> > > Da Xue <da@libre.computer>
> > > Subject: Re: [PATCH v3 00/11] RTW88: Add support for USB variants
> > > 
> > > On Tue, Nov 22, 2022 at 03:52:15PM +0100, Sascha Hauer wrote:
> > > > This is the third round of adding support for the USB variants to the
> > > > RTW88 driver. There are a few changes to the last version which make it
> > > > worth looking at this version.
> > > >
> > > > First of all RTL8723du and RTL8821cu are tested working now. The issue
> > > > here was that the txdesc checksum calculation was wrong. I found the
> > > > correct calculation in various downstream drivers found on github.
> > > >
> > > > The second big issue was that TX packet aggregation was wrong. When
> > > > aggregating packets each packet start has to be aligned to eight bytes.
> > > > The necessary alignment was added to the total URB length before
> > > > checking if there is another packet to aggregate, so the URB length
> > > > included that padding after the last packet, which is wrong.  Fixing
> > > > this makes the driver work much more reliably.
> > > >
> > > > I added all people to Cc: who showed interest in this driver and I want
> > > > to welcome you for testing and reviewing.
> > > 
> > > There still is a problem with the RTL8822cu chipset I have here.  When
> > > using NetworkManager I immediately lose the connection to the AP after
> > > it has been connected:
> > > 
> > > [  376.213846] wlan0: authenticate with 76:83:c2:ce:81:b1
> > > [  380.085463] wlan0: send auth to 76:83:c2:ce:81:b1 (try 1/3)
> > > [  380.091446] wlan0: authenticated
> > > [  380.108864] wlan0: associate with 76:83:c2:ce:81:b1 (try 1/3)
> > > [  380.136448] wlan0: RX AssocResp from 76:83:c2:ce:81:b1 (capab=0x1411 status=0 aid=2)
> > > [  380.202955] wlan0: associated
> > > [  380.268140] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
> > > [  380.275328] wlan0: Connection to AP 76:83:c2:ce:81:b1 lost
> > > 
> > > That doesn't happen when using plain wpa_supplicant. This seems to go
> > > down to cd96e22bc1da ("rtw88: add beacon filter support"). After being
> > > connected I get a BCN_FILTER_CONNECTION_LOSS beacon. Plain
> > > wpa_supplicant seems to go another code patch and doesn't activate
> > > connection quality monitoring.
> > > 
> > > The connection to the AP works fluently also with NetworkManager though
> > > when I just ignore the BCN_FILTER_CONNECTION_LOSS beacon.
> > > 
> > > Any idea what may be wrong here?
> > > 
> > 
> > Please reference to below patch to see if it can work to you.
> > 
> > https://lore.kernel.org/linux-wireless/20221124064442.28042-1-pkshih@realtek.com/T/#u
> 
> Great! That solves this issue \o/

I am also happy to say that this patch is a real performance boost.
Here are some numbers:

RTL8723DU, no patch
===================
tx [  5]   0.00-10.00  sec  1.08 MBytes   903 Kbits/sec    1 sender
rx [  5]   0.00-10.26  sec  10.3 MBytes  8.41 Mbits/sec    0 sender

RTL8723DU, with patch
=====================
tx [  5]   0.00-10.00  sec  34.7 MBytes  29.1 Mbits/sec    9 sender
rx [  5]   0.00-10.05  sec  34.4 MBytes  28.7 Mbits/sec    5 sender

RTL8821CU, no patch
===================
tx [  5]   0.00-10.00  sec  6.01 MBytes  5.04 Mbits/sec    0 sender
rx [  5]   0.00-10.44  sec  53.4 MBytes  42.9 Mbits/sec    0 sender

RTL8821CU, with patch
===================
tx [  5]   0.00-10.00  sec  57.9 MBytes  48.6 Mbits/sec    0 sender
rx [  5]   0.00-10.15  sec  66.3 MBytes  54.8 Mbits/sec  419 sender

RTL8822CU, no patch
===================
tx [  5]   0.00-10.00  sec  11.8 MBytes  9.91 Mbits/sec    1 sender
rx [  5]   0.00-10.18  sec   105 MBytes  86.3 Mbits/sec  805 sender

RTL8822CU, with patch
===================
tx [  5]   0.00-10.01  sec  80.0 MBytes  67.1 Mbits/sec    0 sender
rx [  5]   0.00-10.12  sec   117 MBytes  97.2 Mbits/sec  658 sender

Tested with:

tx: iperf3 -c 192.168.0.57 -i0
rx: iperf3 -c 192.168.0.57 -i0 -R

Especially the RTL8723DU now starts being useful.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH v3 01/11] rtw88: print firmware type in info message
  2022-11-22 14:52 ` [PATCH v3 01/11] rtw88: print firmware type in info message Sascha Hauer
@ 2022-11-25  8:27   ` Ping-Ke Shih
  0 siblings, 0 replies; 29+ messages in thread
From: Ping-Ke Shih @ 2022-11-25  8:27 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Yan-Hsuan Chuang, Kalle Valo, netdev,
	linux-kernel, Martin Blumenstingl, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue, Bernie Huang, Viktor Petrenko



> -----Original Message-----
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Sent: Tuesday, November 22, 2022 10:52 PM
> To: linux-wireless@vger.kernel.org
> Cc: Neo Jou <neojou@gmail.com>; Hans Ulli Kroll <linux@ulli-kroll.de>; Ping-Ke Shih <pkshih@realtek.com>;
> Yan-Hsuan Chuang <tony0620emma@gmail.com>; Kalle Valo <kvalo@kernel.org>; netdev@vger.kernel.org;
> linux-kernel@vger.kernel.org; Martin Blumenstingl <martin.blumenstingl@googlemail.com>;
> kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>;
> Da Xue <da@libre.computer>; Bernie Huang <phhuang@realtek.com>; Viktor Petrenko <g0000ga@gmail.com>;
> Sascha Hauer <s.hauer@pengutronix.de>
> Subject: [PATCH v3 01/11] rtw88: print firmware type in info message
> 
> It's confusing to read two different firmware versions in the syslog
> for the same device:
> 
> rtw_8822cu 2-1:1.2: Firmware version 9.9.4, H2C version 15
> rtw_8822cu 2-1:1.2: Firmware version 9.9.11, H2C version 15
> 
> Print the firmware type in this message to make clear these are really
> two different firmwares for different purposes:
> 
> rtw_8822cu 1-1.4:1.2: WOW Firmware version 9.9.4, H2C version 15
> rtw_8822cu 1-1.4:1.2: Firmware version 9.9.11, H2C version 15
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>

[...]


^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH v3 02/11] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held
  2022-11-22 14:52 ` [PATCH v3 02/11] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held Sascha Hauer
@ 2022-11-25  8:27   ` Ping-Ke Shih
  0 siblings, 0 replies; 29+ messages in thread
From: Ping-Ke Shih @ 2022-11-25  8:27 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Yan-Hsuan Chuang, Kalle Valo, netdev,
	linux-kernel, Martin Blumenstingl, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue, Bernie Huang, Viktor Petrenko


> -----Original Message-----
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Sent: Tuesday, November 22, 2022 10:52 PM
> To: linux-wireless@vger.kernel.org
> Cc: Neo Jou <neojou@gmail.com>; Hans Ulli Kroll <linux@ulli-kroll.de>; Ping-Ke Shih <pkshih@realtek.com>;
> Yan-Hsuan Chuang <tony0620emma@gmail.com>; Kalle Valo <kvalo@kernel.org>; netdev@vger.kernel.org;
> linux-kernel@vger.kernel.org; Martin Blumenstingl <martin.blumenstingl@googlemail.com>;
> kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>;
> Da Xue <da@libre.computer>; Bernie Huang <phhuang@realtek.com>; Viktor Petrenko <g0000ga@gmail.com>;
> Sascha Hauer <s.hauer@pengutronix.de>
> Subject: [PATCH v3 02/11] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held
> 
> rtw_fw_beacon_filter_config() is called once with rtwdev->mutex held
> and once without the mutex held. Call it consistently with rtwdev->mutex
> held.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>

[...]



^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH v3 03/11] rtw88: Drop rf_lock
  2022-11-22 14:52 ` [PATCH v3 03/11] rtw88: Drop rf_lock Sascha Hauer
@ 2022-11-25  8:29   ` Ping-Ke Shih
  0 siblings, 0 replies; 29+ messages in thread
From: Ping-Ke Shih @ 2022-11-25  8:29 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Yan-Hsuan Chuang, Kalle Valo, netdev,
	linux-kernel, Martin Blumenstingl, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue, Bernie Huang, Viktor Petrenko



> -----Original Message-----
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Sent: Tuesday, November 22, 2022 10:52 PM
> To: linux-wireless@vger.kernel.org
> Cc: Neo Jou <neojou@gmail.com>; Hans Ulli Kroll <linux@ulli-kroll.de>; Ping-Ke Shih <pkshih@realtek.com>;
> Yan-Hsuan Chuang <tony0620emma@gmail.com>; Kalle Valo <kvalo@kernel.org>; netdev@vger.kernel.org;
> linux-kernel@vger.kernel.org; Martin Blumenstingl <martin.blumenstingl@googlemail.com>;
> kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>;
> Da Xue <da@libre.computer>; Bernie Huang <phhuang@realtek.com>; Viktor Petrenko <g0000ga@gmail.com>;
> Sascha Hauer <s.hauer@pengutronix.de>
> Subject: [PATCH v3 03/11] rtw88: Drop rf_lock
> 
> The rtwdev->rf_lock spinlock protects the rf register accesses in
> rtw_read_rf() and rtw_write_rf(). Most callers of these functions hold
> rtwdev->mutex already with the exception of the callsites in the debugfs
> code. The debugfs code doesn't justify an extra lock, so acquire the mutex
> there as well before calling rf register accessors and drop the now
> unnecessary spinlock.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>

[...]


^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH v3 06/11] rtw88: iterate over vif/sta list non-atomically
  2022-11-22 14:52 ` [PATCH v3 06/11] rtw88: iterate over vif/sta list non-atomically Sascha Hauer
@ 2022-11-25  8:50   ` Ping-Ke Shih
  0 siblings, 0 replies; 29+ messages in thread
From: Ping-Ke Shih @ 2022-11-25  8:50 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Yan-Hsuan Chuang, Kalle Valo, netdev,
	linux-kernel, Martin Blumenstingl, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue, Bernie Huang, Viktor Petrenko



> -----Original Message-----
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Sent: Tuesday, November 22, 2022 10:52 PM
> To: linux-wireless@vger.kernel.org
> Cc: Neo Jou <neojou@gmail.com>; Hans Ulli Kroll <linux@ulli-kroll.de>; Ping-Ke Shih <pkshih@realtek.com>;
> Yan-Hsuan Chuang <tony0620emma@gmail.com>; Kalle Valo <kvalo@kernel.org>; netdev@vger.kernel.org;
> linux-kernel@vger.kernel.org; Martin Blumenstingl <martin.blumenstingl@googlemail.com>;
> kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>;
> Da Xue <da@libre.computer>; Bernie Huang <phhuang@realtek.com>; Viktor Petrenko <g0000ga@gmail.com>;
> Sascha Hauer <s.hauer@pengutronix.de>
> Subject: [PATCH v3 06/11] rtw88: iterate over vif/sta list non-atomically
> 
> The driver uses ieee80211_iterate_active_interfaces_atomic()
> and ieee80211_iterate_stations_atomic() in several places and does
> register accesses in the iterators. This doesn't cope with upcoming
> USB support as registers can only be accessed non-atomically.
> 
> Split these into a two stage process: First use the atomic iterator
> functions to collect all active interfaces or stations on a list, then
> iterate over the list non-atomically and call the iterator on each
> entry.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Suggested-by: Pkshih <pkshih@realtek.com>

Please correct my full name. The old setting of my mailer is improper.

Suggested-by: Ping-Ke Shih <pkshih@realtek.com>
Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>



^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH v3 07/11] rtw88: Add common USB chip support
  2022-11-22 14:52 ` [PATCH v3 07/11] rtw88: Add common USB chip support Sascha Hauer
@ 2022-11-28  2:00   ` Ping-Ke Shih
  2022-11-28 10:30     ` Sascha Hauer
  0 siblings, 1 reply; 29+ messages in thread
From: Ping-Ke Shih @ 2022-11-28  2:00 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Yan-Hsuan Chuang, Kalle Valo, netdev,
	linux-kernel, Martin Blumenstingl, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue, Bernie Huang, Viktor Petrenko,
	neo_jou



> -----Original Message-----
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Sent: Tuesday, November 22, 2022 10:52 PM
> To: linux-wireless@vger.kernel.org
> Cc: Neo Jou <neojou@gmail.com>; Hans Ulli Kroll <linux@ulli-kroll.de>; Ping-Ke Shih <pkshih@realtek.com>;
> Yan-Hsuan Chuang <tony0620emma@gmail.com>; Kalle Valo <kvalo@kernel.org>; netdev@vger.kernel.org;
> linux-kernel@vger.kernel.org; Martin Blumenstingl <martin.blumenstingl@googlemail.com>;
> kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>;
> Da Xue <da@libre.computer>; Bernie Huang <phhuang@realtek.com>; Viktor Petrenko <g0000ga@gmail.com>;
> Sascha Hauer <s.hauer@pengutronix.de>; neo_jou <neo_jou@realtek.com>
> Subject: [PATCH v3 07/11] rtw88: Add common USB chip support
> 
> Add the common bits and pieces to add USB support to the RTW88 driver.
> This is based on https://github.com/ulli-kroll/rtw88-usb.git which
> itself is first written by Neo Jou.
> 
> Signed-off-by: neo_jou <neo_jou@realtek.com>
> Signed-off-by: Hans Ulli Kroll <linux@ulli-kroll.de>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> 
> Notes:
>     Changes since v2:
>     - Fix buffer length for aggregated tx packets
>     - Increase maximum transmit buffer size to 20KiB as found in downstream drivers
>     - Change register write functions to synchronous accesses instead of just firing
>       a URB without waiting for its completion
>     - requeue rx URBs directly in completion handler rather than having a workqueue
>       for it.
> 
>     Changes since v1:
>     - Make checkpatch.pl clean
>     - Drop WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL flag
>     - Use 'ret' as variable name for return values
>     - Sort variable declarations in reverse Xmas tree order
>     - Change potentially endless loop to a limited loop
>     - Change locking to be more obviously correct
>     - drop unnecessary check for !rtwdev
>     - make sure the refill workqueue is not restarted again after we have
>       cancelled it
> 
>  drivers/net/wireless/realtek/rtw88/Kconfig  |   3 +
>  drivers/net/wireless/realtek/rtw88/Makefile |   2 +
>  drivers/net/wireless/realtek/rtw88/mac.c    |   3 +
>  drivers/net/wireless/realtek/rtw88/main.c   |   4 +
>  drivers/net/wireless/realtek/rtw88/main.h   |   4 +
>  drivers/net/wireless/realtek/rtw88/reg.h    |   1 +
>  drivers/net/wireless/realtek/rtw88/tx.h     |  31 +
>  drivers/net/wireless/realtek/rtw88/usb.c    | 918 ++++++++++++++++++++
>  drivers/net/wireless/realtek/rtw88/usb.h    | 107 +++
>  9 files changed, 1073 insertions(+)
>  create mode 100644 drivers/net/wireless/realtek/rtw88/usb.c
>  create mode 100644 drivers/net/wireless/realtek/rtw88/usb.h
> 
> diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
> index e3d7cb6c12902..1624c5db69bac 100644
> --- a/drivers/net/wireless/realtek/rtw88/Kconfig
> +++ b/drivers/net/wireless/realtek/rtw88/Kconfig
> @@ -16,6 +16,9 @@ config RTW88_CORE
>  config RTW88_PCI
>  	tristate
> 
> +config RTW88_USB
> +	tristate
> +
>  config RTW88_8822B
>  	tristate
> 
> diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile
> index 834c66ec0af9e..9e095f8181483 100644
> --- a/drivers/net/wireless/realtek/rtw88/Makefile
> +++ b/drivers/net/wireless/realtek/rtw88/Makefile
> @@ -45,4 +45,6 @@ obj-$(CONFIG_RTW88_8821CE)	+= rtw88_8821ce.o
>  rtw88_8821ce-objs		:= rtw8821ce.o
> 
>  obj-$(CONFIG_RTW88_PCI)		+= rtw88_pci.o
> +obj-$(CONFIG_RTW88_USB)		+= rtw88_usb.o
>  rtw88_pci-objs			:= pci.o
> +rtw88_usb-objs			:= usb.o

nit: I prefer not interleaving with PCI.


[...]

> diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
> new file mode 100644
> index 0000000000000..4a12934d20712
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/usb.c

[...]

> +static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len)
> +{
> +	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
> +	struct usb_device *udev = rtwusb->udev;
> +	__le32 *data;
> +	unsigned long flags;
> +	int ret;
> +	static int count;
> +
> +	spin_lock_irqsave(&rtwusb->usb_lock, flags);
> +
> +	rtwusb->usb_data_index++;
> +	rtwusb->usb_data_index &= (RTW_USB_MAX_RXTX_COUNT - 1);
> +
> +	spin_unlock_irqrestore(&rtwusb->usb_lock, flags);
> +
> +	data = &rtwusb->usb_data[rtwusb->usb_data_index];

Don't you need to hold &rtwusb->usb_lock to access rtwusb->usb_data_index?
rtw_usb_write() has similar code.

> +
> +	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
> +			      RTW_USB_CMD_REQ, RTW_USB_CMD_READ, addr,
> +			      RTW_USB_VENQT_CMD_IDX, data, len, 1000);
> +	if (ret < 0 && ret != -ENODEV && count++ < 4)
> +		rtw_err(rtwdev, "read register 0x%x failed with %d\n",
> +			addr, ret);
> +
> +	return le32_to_cpu(*data);
> +}
> +

[...]

> +
> +static void rtw_usb_write_port_tx_complete(struct urb *urb)
> +{
> +	struct rtw_usb_txcb *txcb = urb->context;
> +	struct rtw_dev *rtwdev = txcb->rtwdev;
> +	struct ieee80211_hw *hw = rtwdev->hw;
> +
> +	while (true) {

Is it possible to have a hard limit to prevent unexpected infinite loop?

> +		struct sk_buff *skb = skb_dequeue(&txcb->tx_ack_queue);
> +		struct ieee80211_tx_info *info;
> +		struct rtw_usb_tx_data *tx_data;
> +
> +		if (!skb)
> +			break;
> +
> +		info = IEEE80211_SKB_CB(skb);
> +		tx_data = rtw_usb_get_tx_data(skb);
> +
> +		/* enqueue to wait for tx report */
> +		if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
> +			rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn);
> +			continue;
> +		}
> +
> +		/* always ACK for others, then they won't be marked as drop */
> +		ieee80211_tx_info_clear_status(info);
> +		if (info->flags & IEEE80211_TX_CTL_NO_ACK)
> +			info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
> +		else
> +			info->flags |= IEEE80211_TX_STAT_ACK;
> +
> +		ieee80211_tx_status_irqsafe(hw, skb);
> +	}
> +
> +	kfree(txcb);
> +}
> +

[...]

> +
> +static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list)
> +{
> +	struct rtw_dev *rtwdev = rtwusb->rtwdev;
> +	struct rtw_usb_txcb *txcb;
> +	struct sk_buff *skb_head;
> +	struct sk_buff *skb_iter;
> +	u8 *data_ptr;
> +	int agg_num = 0;
> +	unsigned int align_next = 0;
> +
> +	if (skb_queue_empty(list))
> +		return false;
> +
> +	txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC);
> +	if (!txcb)
> +		return false;
> +
> +	txcb->rtwdev = rtwdev;
> +	skb_queue_head_init(&txcb->tx_ack_queue);
> +
> +	skb_iter = skb_dequeue(list);
> +
> +	if (skb_queue_empty(list)) {
> +		skb_head = skb_iter;
> +		goto queue;
> +	}
> +
> +	skb_head = dev_alloc_skb(RTW_USB_MAX_XMITBUF_SZ);
> +	if (!skb_head) {
> +		skb_head = skb_iter;
> +		goto queue;
> +	}
> +
> +	data_ptr = skb_head->data;
> +
> +	while (skb_iter) {
> +		unsigned long flags;
> +
> +		memcpy(data_ptr, skb_iter->data, skb_iter->len);
> +		skb_put(skb_head, skb_iter->len + align_next);

skb_put(skb_head, align_next);
skb_put_data(skb_head, skb_iter->data, skb_iter->len);

Then, don't need to maintain 'data_ptr'.

> +
> +		align_next = ALIGN(skb_iter->len, 8) - skb_iter->len;
> +		data_ptr += skb_iter->len + align_next;
> +
> +		agg_num++;
> +
> +		skb_queue_tail(&txcb->tx_ack_queue, skb_iter);
> +
> +		spin_lock_irqsave(&list->lock, flags);
> +
> +		skb_iter = skb_peek(list);
> +
> +		if (skb_iter && skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ)
> +			__skb_unlink(skb_iter, list);
> +		else
> +			skb_iter = NULL;
> +		spin_unlock_irqrestore(&list->lock, flags);
> +	}
> +
> +	if (agg_num > 1)
> +		rtw_usb_fill_tx_checksum(rtwusb, skb_head, agg_num);
> +
> +queue:
> +	skb_queue_tail(&txcb->tx_ack_queue, skb_head);
> +
> +	rtw_usb_write_port(rtwdev, GET_TX_DESC_QSEL(skb_head->data), skb_head,
> +			   rtw_usb_write_port_tx_complete, txcb);
> +
> +	return true;
> +}
> +

[...]

> +
> +static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb, struct rx_usb_ctrl_block *rxcb)
> +{
> +	struct rtw_dev *rtwdev = rtwusb->rtwdev;
> +	int error;
> +
> +	rxcb->rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_ATOMIC);
> +	if (!rxcb->rx_skb)
> +		return;
> +
> +	usb_fill_bulk_urb(rxcb->rx_urb, rtwusb->udev,
> +			  usb_rcvbulkpipe(rtwusb->udev, rtwusb->pipe_in),
> +			  rxcb->rx_skb->data, RTW_USB_MAX_RECVBUF_SZ,
> +			  rtw_usb_read_port_complete, rxcb);
> +
> +	error = usb_submit_urb(rxcb->rx_urb, GFP_ATOMIC);
> +	if (error) {
> +		kfree_skb(rxcb->rx_skb);
> +		if (error != -ENODEV)
> +			rtw_err(rtwdev, "Err sending rx data urb %d\n",
> +				error);

nit: straighten rtw_err()

> +	}
> +}
> +

[...]

> diff --git a/drivers/net/wireless/realtek/rtw88/usb.h b/drivers/net/wireless/realtek/rtw88/usb.h
> new file mode 100644
> index 0000000000000..e26f8afb09f29
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/usb.h

[...]

> +
> +static inline struct rtw_usb_tx_data *rtw_usb_get_tx_data(struct sk_buff *skb)
> +{
> +	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
> +
> +	BUILD_BUG_ON(sizeof(struct rtw_usb_tx_data) >
> +		sizeof(info->status.status_driver_data));

coding style: 

align the open parenthesis 

	BUILD_BUG_ON(sizeof(struct rtw_usb_tx_data) >
		     sizeof(info->status.status_driver_data));

> +
> +	return (struct rtw_usb_tx_data *)info->status.status_driver_data;
> +}
> +
> +int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id);
> +void rtw_usb_disconnect(struct usb_interface *intf);
> +
> +#endif
> --
> 2.30.2


^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH v3 08/11] rtw88: Add rtw8821cu chipset support
  2022-11-22 14:52 ` [PATCH v3 08/11] rtw88: Add rtw8821cu chipset support Sascha Hauer
@ 2022-11-28  2:13   ` Ping-Ke Shih
  0 siblings, 0 replies; 29+ messages in thread
From: Ping-Ke Shih @ 2022-11-28  2:13 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Yan-Hsuan Chuang, Kalle Valo, netdev,
	linux-kernel, Martin Blumenstingl, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue, Bernie Huang, Viktor Petrenko



> -----Original Message-----
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Sent: Tuesday, November 22, 2022 10:52 PM
> To: linux-wireless@vger.kernel.org
> Cc: Neo Jou <neojou@gmail.com>; Hans Ulli Kroll <linux@ulli-kroll.de>; Ping-Ke Shih <pkshih@realtek.com>;
> Yan-Hsuan Chuang <tony0620emma@gmail.com>; Kalle Valo <kvalo@kernel.org>; netdev@vger.kernel.org;
> linux-kernel@vger.kernel.org; Martin Blumenstingl <martin.blumenstingl@googlemail.com>;
> kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>;
> Da Xue <da@libre.computer>; Bernie Huang <phhuang@realtek.com>; Viktor Petrenko <g0000ga@gmail.com>;
> Sascha Hauer <s.hauer@pengutronix.de>
> Subject: [PATCH v3 08/11] rtw88: Add rtw8821cu chipset support
> 
> Add support for the rtw8821cu chipset based on
> https://github.com/ulli-kroll/rtw88-usb.git
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> 
> Notes:
>     Changes since v2:
>     - Fix txdesc checksum calculation. The checksum must be calculated over
>       a fixed number of words.
> 
>  drivers/net/wireless/realtek/rtw88/Kconfig    | 11 ++++
>  drivers/net/wireless/realtek/rtw88/Makefile   |  3 ++
>  drivers/net/wireless/realtek/rtw88/rtw8821c.c | 18 +++++++
>  drivers/net/wireless/realtek/rtw88/rtw8821c.h | 21 ++++++++
>  .../net/wireless/realtek/rtw88/rtw8821cu.c    | 50 +++++++++++++++++++
>  .../net/wireless/realtek/rtw88/rtw8821cu.h    | 10 ++++
>  6 files changed, 113 insertions(+)
>  create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821cu.c
>  create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821cu.h
> 

[...]

> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.h
> @@ -0,0 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
> +/* Copyright(c) 2018-2019  Realtek Corporation
> + */
> +
> +#ifndef __RTW_8821CU_H_
> +#define __RTW_8821CU_H_
> +
> +extern struct rtw_chip_info rtw8821c_hw_spec;

This has been moved to rtw8821c.h by
89d8f53ff6e ("wifi: rtw88: Fix Sparse warning for rtw8821c_hw_spec")

So, we don't need rtw8821cu.h anymore. 
Please apply this rule to other chips.

> +
> +#endif
> --
> 2.30.2


^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH v3 00/11] RTW88: Add support for USB variants
  2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
                   ` (11 preceding siblings ...)
  2022-11-22 14:55 ` [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
@ 2022-11-28  3:45 ` Ping-Ke Shih
  12 siblings, 0 replies; 29+ messages in thread
From: Ping-Ke Shih @ 2022-11-28  3:45 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Yan-Hsuan Chuang, Kalle Valo, netdev,
	linux-kernel, Martin Blumenstingl, kernel, Johannes Berg,
	Alexander Hochbaum, Da Xue, Bernie Huang, Viktor Petrenko


> -----Original Message-----
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Sent: Tuesday, November 22, 2022 10:52 PM
> To: linux-wireless@vger.kernel.org
> Cc: Neo Jou <neojou@gmail.com>; Hans Ulli Kroll <linux@ulli-kroll.de>; Ping-Ke Shih <pkshih@realtek.com>;
> Yan-Hsuan Chuang <tony0620emma@gmail.com>; Kalle Valo <kvalo@kernel.org>; netdev@vger.kernel.org;
> linux-kernel@vger.kernel.org; Martin Blumenstingl <martin.blumenstingl@googlemail.com>;
> kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>;
> Da Xue <da@libre.computer>; Bernie Huang <phhuang@realtek.com>; Viktor Petrenko <g0000ga@gmail.com>;
> Sascha Hauer <s.hauer@pengutronix.de>
> Subject: [PATCH v3 00/11] RTW88: Add support for USB variants
> 
> This is the third round of adding support for the USB variants to the
> RTW88 driver. There are a few changes to the last version which make it
> worth looking at this version.
> 
> First of all RTL8723du and RTL8821cu are tested working now. The issue
> here was that the txdesc checksum calculation was wrong. I found the
> correct calculation in various downstream drivers found on github.
> 
> The second big issue was that TX packet aggregation was wrong. When
> aggregating packets each packet start has to be aligned to eight bytes.
> The necessary alignment was added to the total URB length before
> checking if there is another packet to aggregate, so the URB length
> included that padding after the last packet, which is wrong.  Fixing
> this makes the driver work much more reliably.
> 

Thanks for your finding and fixes on this driver. I have reviewed this 
patchset and written some comments. No big problem.


> 
> Sascha Hauer (11):
>   rtw88: print firmware type in info message
>   rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held
>   rtw88: Drop rf_lock
>   rtw88: Drop h2c.lock
>   rtw88: Drop coex mutex
>   rtw88: iterate over vif/sta list non-atomically
>   rtw88: Add common USB chip support
>   rtw88: Add rtw8821cu chipset support
>   rtw88: Add rtw8822bu chipset support
>   rtw88: Add rtw8822cu chipset support
>   rtw88: Add rtw8723du chipset support

Please use "wifi: rtw88: " as prefix in next version.

--
Ping-Ke



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 09/11] rtw88: Add rtw8822bu chipset support
  2022-11-22 14:52 ` [PATCH v3 09/11] rtw88: Add rtw8822bu " Sascha Hauer
@ 2022-11-28  5:39   ` Ryan Finnie
  0 siblings, 0 replies; 29+ messages in thread
From: Ryan Finnie @ 2022-11-28  5:39 UTC (permalink / raw)
  To: s.hauer
  Cc: alex, da, g0000ga, johannes, kernel, kvalo, linux-kernel,
	linux-wireless, linux, martin.blumenstingl, neojou, netdev,
	phhuang, pkshih, tony0620emma

> +	{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012e, 0xff, 0xff, 0xff),
> +	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */

This device is confirmed in the wild as "TP-LINK Archer T3U Nano", and
is a miniaturized version of 0x012d.

(I have not personally tested this patchset, but have verified against
the DKMS tree at https://github.com/cilynx/rtl88x2bu with 0x012e added.)

Thank you,
Ryan Finnie

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 07/11] rtw88: Add common USB chip support
  2022-11-28  2:00   ` Ping-Ke Shih
@ 2022-11-28 10:30     ` Sascha Hauer
  2022-11-28 13:41       ` Kalle Valo
  0 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2022-11-28 10:30 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: linux-wireless, Neo Jou, Hans Ulli Kroll, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, Alexander Hochbaum, Da Xue, Bernie Huang,
	Viktor Petrenko, neo_jou

On Mon, Nov 28, 2022 at 02:00:54AM +0000, Ping-Ke Shih wrote:
> 
> 
> > -----Original Message-----
> > From: Sascha Hauer <s.hauer@pengutronix.de>
> > Sent: Tuesday, November 22, 2022 10:52 PM
> > To: linux-wireless@vger.kernel.org
> > Cc: Neo Jou <neojou@gmail.com>; Hans Ulli Kroll <linux@ulli-kroll.de>; Ping-Ke Shih <pkshih@realtek.com>;
> > Yan-Hsuan Chuang <tony0620emma@gmail.com>; Kalle Valo <kvalo@kernel.org>; netdev@vger.kernel.org;
> > linux-kernel@vger.kernel.org; Martin Blumenstingl <martin.blumenstingl@googlemail.com>;
> > kernel@pengutronix.de; Johannes Berg <johannes@sipsolutions.net>; Alexander Hochbaum <alex@appudo.com>;
> > Da Xue <da@libre.computer>; Bernie Huang <phhuang@realtek.com>; Viktor Petrenko <g0000ga@gmail.com>;
> > Sascha Hauer <s.hauer@pengutronix.de>; neo_jou <neo_jou@realtek.com>
> > Subject: [PATCH v3 07/11] rtw88: Add common USB chip support
> > 
> > Add the common bits and pieces to add USB support to the RTW88 driver.
> > This is based on https://github.com/ulli-kroll/rtw88-usb.git which
> > itself is first written by Neo Jou.
> > 
> > Signed-off-by: neo_jou <neo_jou@realtek.com>
> > Signed-off-by: Hans Ulli Kroll <linux@ulli-kroll.de>
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > 
> > Notes:
> >     Changes since v2:
> >     - Fix buffer length for aggregated tx packets
> >     - Increase maximum transmit buffer size to 20KiB as found in downstream drivers
> >     - Change register write functions to synchronous accesses instead of just firing
> >       a URB without waiting for its completion
> >     - requeue rx URBs directly in completion handler rather than having a workqueue
> >       for it.
> > 
> >     Changes since v1:
> >     - Make checkpatch.pl clean
> >     - Drop WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL flag
> >     - Use 'ret' as variable name for return values
> >     - Sort variable declarations in reverse Xmas tree order
> >     - Change potentially endless loop to a limited loop
> >     - Change locking to be more obviously correct
> >     - drop unnecessary check for !rtwdev
> >     - make sure the refill workqueue is not restarted again after we have
> >       cancelled it
> > 
> >  drivers/net/wireless/realtek/rtw88/Kconfig  |   3 +
> >  drivers/net/wireless/realtek/rtw88/Makefile |   2 +
> >  drivers/net/wireless/realtek/rtw88/mac.c    |   3 +
> >  drivers/net/wireless/realtek/rtw88/main.c   |   4 +
> >  drivers/net/wireless/realtek/rtw88/main.h   |   4 +
> >  drivers/net/wireless/realtek/rtw88/reg.h    |   1 +
> >  drivers/net/wireless/realtek/rtw88/tx.h     |  31 +
> >  drivers/net/wireless/realtek/rtw88/usb.c    | 918 ++++++++++++++++++++
> >  drivers/net/wireless/realtek/rtw88/usb.h    | 107 +++
> >  9 files changed, 1073 insertions(+)
> >  create mode 100644 drivers/net/wireless/realtek/rtw88/usb.c
> >  create mode 100644 drivers/net/wireless/realtek/rtw88/usb.h
> > 
> > diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
> > index e3d7cb6c12902..1624c5db69bac 100644
> > --- a/drivers/net/wireless/realtek/rtw88/Kconfig
> > +++ b/drivers/net/wireless/realtek/rtw88/Kconfig
> > @@ -16,6 +16,9 @@ config RTW88_CORE
> >  config RTW88_PCI
> >  	tristate
> > 
> > +config RTW88_USB
> > +	tristate
> > +
> >  config RTW88_8822B
> >  	tristate
> > 
> > diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile
> > index 834c66ec0af9e..9e095f8181483 100644
> > --- a/drivers/net/wireless/realtek/rtw88/Makefile
> > +++ b/drivers/net/wireless/realtek/rtw88/Makefile
> > @@ -45,4 +45,6 @@ obj-$(CONFIG_RTW88_8821CE)	+= rtw88_8821ce.o
> >  rtw88_8821ce-objs		:= rtw8821ce.o
> > 
> >  obj-$(CONFIG_RTW88_PCI)		+= rtw88_pci.o
> > +obj-$(CONFIG_RTW88_USB)		+= rtw88_usb.o
> >  rtw88_pci-objs			:= pci.o
> > +rtw88_usb-objs			:= usb.o
> 
> nit: I prefer not interleaving with PCI.

Ok.

> > +static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len)
> > +{
> > +	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
> > +	struct usb_device *udev = rtwusb->udev;
> > +	__le32 *data;
> > +	unsigned long flags;
> > +	int ret;
> > +	static int count;
> > +
> > +	spin_lock_irqsave(&rtwusb->usb_lock, flags);
> > +
> > +	rtwusb->usb_data_index++;
> > +	rtwusb->usb_data_index &= (RTW_USB_MAX_RXTX_COUNT - 1);
> > +
> > +	spin_unlock_irqrestore(&rtwusb->usb_lock, flags);
> > +
> > +	data = &rtwusb->usb_data[rtwusb->usb_data_index];
> 
> Don't you need to hold &rtwusb->usb_lock to access rtwusb->usb_data_index?
> rtw_usb_write() has similar code.

Right. Will rewrite to:

	spin_lock_irqsave(&rtwusb->usb_lock, flags);

	idx = rtwusb->usb_data_index;
	rtwusb->usb_data_index = (idx + 1) & (RTW_USB_MAX_RXTX_COUNT - 1);

	spin_unlock_irqrestore(&rtwusb->usb_lock, flags);

	data = &rtwusb->usb_data[idx];

> > +static void rtw_usb_write_port_tx_complete(struct urb *urb)
> > +{
> > +	struct rtw_usb_txcb *txcb = urb->context;
> > +	struct rtw_dev *rtwdev = txcb->rtwdev;
> > +	struct ieee80211_hw *hw = rtwdev->hw;
> > +
> > +	while (true) {
> 
> Is it possible to have a hard limit to prevent unexpected infinite loop?

Yes, that would be possible, but do you think it's necessary?

Each *txcb is used only once, It's allocated in rtw_usb_tx_agg_skb() and
&txcb->tx_ack_queue is filled with a limited number of skbs there. These
skbs is then iterated over in rtw_usb_write_port_tx_complete(), so I don't
see a way how we could end up in an infinite loop here.

It's not that &txcb->tx_ack_queue is filled in a concurrent thread while we
try to catch up in rtw_usb_write_port_tx_complete().

> > +	skb_head = dev_alloc_skb(RTW_USB_MAX_XMITBUF_SZ);
> > +	if (!skb_head) {
> > +		skb_head = skb_iter;
> > +		goto queue;
> > +	}
> > +
> > +	data_ptr = skb_head->data;
> > +
> > +	while (skb_iter) {
> > +		unsigned long flags;
> > +
> > +		memcpy(data_ptr, skb_iter->data, skb_iter->len);
> > +		skb_put(skb_head, skb_iter->len + align_next);
> 
> skb_put(skb_head, align_next);
> skb_put_data(skb_head, skb_iter->data, skb_iter->len);
> 
> Then, don't need to maintain 'data_ptr'.

Right. Looks much better this way.

> > +	error = usb_submit_urb(rxcb->rx_urb, GFP_ATOMIC);
> > +	if (error) {
> > +		kfree_skb(rxcb->rx_skb);
> > +		if (error != -ENODEV)
> > +			rtw_err(rtwdev, "Err sending rx data urb %d\n",
> > +				error);
> 
> nit: straighten rtw_err()

Ok.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 07/11] rtw88: Add common USB chip support
  2022-11-28 10:30     ` Sascha Hauer
@ 2022-11-28 13:41       ` Kalle Valo
  0 siblings, 0 replies; 29+ messages in thread
From: Kalle Valo @ 2022-11-28 13:41 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Ping-Ke Shih, linux-wireless, Neo Jou, Hans Ulli Kroll,
	Yan-Hsuan Chuang, netdev, linux-kernel, Martin Blumenstingl,
	kernel, Johannes Berg, Alexander Hochbaum, Da Xue, Bernie Huang,
	Viktor Petrenko, neo_jou

Sascha Hauer <s.hauer@pengutronix.de> writes:

>> > +static void rtw_usb_write_port_tx_complete(struct urb *urb)
>> > +{
>> > +	struct rtw_usb_txcb *txcb = urb->context;
>> > +	struct rtw_dev *rtwdev = txcb->rtwdev;
>> > +	struct ieee80211_hw *hw = rtwdev->hw;
>> > +
>> > +	while (true) {
>> 
>> Is it possible to have a hard limit to prevent unexpected infinite loop?
>
> Yes, that would be possible, but do you think it's necessary?

It's a common advice to have a limit for loops in kernel.

> Each *txcb is used only once, It's allocated in rtw_usb_tx_agg_skb() and
> &txcb->tx_ack_queue is filled with a limited number of skbs there. These
> skbs is then iterated over in rtw_usb_write_port_tx_complete(), so I don't
> see a way how we could end up in an infinite loop here.

Everyone always say that their code is bugfree ;) More seriously though,
even if it would be bugfree now someone else can add buggy code later.
So much better to have a limit for the loop.

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2022-11-28 13:41 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-22 14:52 [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
2022-11-22 14:52 ` [PATCH v3 01/11] rtw88: print firmware type in info message Sascha Hauer
2022-11-25  8:27   ` Ping-Ke Shih
2022-11-22 14:52 ` [PATCH v3 02/11] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held Sascha Hauer
2022-11-25  8:27   ` Ping-Ke Shih
2022-11-22 14:52 ` [PATCH v3 03/11] rtw88: Drop rf_lock Sascha Hauer
2022-11-25  8:29   ` Ping-Ke Shih
2022-11-22 14:52 ` [PATCH v3 04/11] rtw88: Drop h2c.lock Sascha Hauer
2022-11-22 14:52 ` [PATCH v3 05/11] rtw88: Drop coex mutex Sascha Hauer
2022-11-22 14:52 ` [PATCH v3 06/11] rtw88: iterate over vif/sta list non-atomically Sascha Hauer
2022-11-25  8:50   ` Ping-Ke Shih
2022-11-22 14:52 ` [PATCH v3 07/11] rtw88: Add common USB chip support Sascha Hauer
2022-11-28  2:00   ` Ping-Ke Shih
2022-11-28 10:30     ` Sascha Hauer
2022-11-28 13:41       ` Kalle Valo
2022-11-22 14:52 ` [PATCH v3 08/11] rtw88: Add rtw8821cu chipset support Sascha Hauer
2022-11-28  2:13   ` Ping-Ke Shih
2022-11-22 14:52 ` [PATCH v3 09/11] rtw88: Add rtw8822bu " Sascha Hauer
2022-11-28  5:39   ` Ryan Finnie
2022-11-22 14:52 ` [PATCH v3 10/11] rtw88: Add rtw8822cu " Sascha Hauer
2022-11-22 14:52 ` [PATCH v3 11/11] rtw88: Add rtw8723du " Sascha Hauer
2022-11-22 14:55 ` [PATCH v3 00/11] RTW88: Add support for USB variants Sascha Hauer
2022-11-24  6:48   ` Ping-Ke Shih
2022-11-24  8:21     ` Sascha Hauer
2022-11-24  8:26       ` Ping-Ke Shih
2022-11-24  8:36         ` Sascha Hauer
2022-11-24  8:33       ` Kalle Valo
2022-11-24  9:20       ` Sascha Hauer
2022-11-28  3:45 ` Ping-Ke Shih

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).