All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] RTW88: Add support for USB variants
@ 2022-05-18  8:23 Sascha Hauer
  2022-05-18  8:23 ` [PATCH 01/10] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held Sascha Hauer
                   ` (11 more replies)
  0 siblings, 12 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:23 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, Sascha Hauer

This series adds support for the USB chip variants to the RTW88 driver.

The first patches in the series consolidate the locking in the driver.
The rtw88 driver protects the register accesses with spinlocks which
naturally don't cope well with the asynchronous nature of USB. It turned
out though that in most cases where additional locks are taken the
global driver mutex is acquired anyway which makes them mostly
unnecessary. The exception is the debugfs code which depends on the
additional locks. This is changed to acquire the global driver mutex as
well, so the additional locks can be removed.  I verified the callstacks
leading to the different locks with a cscope based shell script, so I am
pretty confident that I haven't missed any pathes. Nevertheless please
have a careful look, please.

Another problem to address is that the driver uses
ieee80211_iterate_stations_atomic() and
ieee80211_iterate_active_interfaces_atomic() and does register accesses
in the iterator. This doesn't work with USB, so iteration is done in two
steps now: The ieee80211_iterate_*_atomic() functions are only used to
collect the stations/interfaces on a list which is then iterated over
non-atomically in the second step. The implementation for this is
basically the one suggested by Ping-Ke here:
https://lore.kernel.org/lkml/423f474e15c948eda4db5bc9a50fd391@realtek.com/

The USB driver code itself is based on
https://github.com/ulli-kroll/rtw88-usb.git.  The most significant
change to that code base is likely the TX queue handling.  It seems the
PCI versions of the RTW88 chips have eight differently prioritized TX
queues whereas the USB variants only have one to three queues (one per
bulk endpoint).  The original code base first mapped the TX packets
coming into the driver onto eight TX queues which were then re-mapped
again to the existing endpoints. As the eight TX queues do not
physically exist on the USB variants I changed that to map the incoming
TX packets directly onto the bulk endpoints.

I tested this series on the RTW8822CU only. I don't have access to any
of the other chips supported by the RTW88 driver, so testing feedback
would be greatly appreciated.

This is my first excursion to the Linux wireless world, so please review
carefully :)

Sascha


Sascha Hauer (10):
  rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held
  rtw88: Drop rf_lock
  rtw88: Drop h2c.lock
  rtw88: Drop coex mutex
  rtw88: Do not access registers while atomic
  rtw88: Add common USB chip support
  rtw88: Add rtw8723du chipset support
  rtw88: Add rtw8821cu chipset support
  rtw88: Add rtw8822bu chipset support
  rtw88: Add rtw8822cu 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     |    9 +-
 drivers/net/wireless/realtek/rtw88/main.h     |   11 +-
 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 |   19 +
 drivers/net/wireless/realtek/rtw88/rtw8723d.h |    1 +
 .../net/wireless/realtek/rtw88/rtw8723du.c    |   40 +
 .../net/wireless/realtek/rtw88/rtw8723du.h    |   13 +
 drivers/net/wireless/realtek/rtw88/rtw8821c.c |   23 +
 drivers/net/wireless/realtek/rtw88/rtw8821c.h |   21 +
 .../net/wireless/realtek/rtw88/rtw8821cu.c    |   69 ++
 .../net/wireless/realtek/rtw88/rtw8821cu.h    |   15 +
 drivers/net/wireless/realtek/rtw88/rtw8822b.c |   19 +
 .../net/wireless/realtek/rtw88/rtw8822bu.c    |   62 +
 .../net/wireless/realtek/rtw88/rtw8822bu.h    |   15 +
 drivers/net/wireless/realtek/rtw88/rtw8822c.c |   24 +
 .../net/wireless/realtek/rtw88/rtw8822cu.c    |   40 +
 .../net/wireless/realtek/rtw88/rtw8822cu.h    |   15 +
 drivers/net/wireless/realtek/rtw88/tx.h       |   31 +
 drivers/net/wireless/realtek/rtw88/usb.c      | 1051 +++++++++++++++++
 drivers/net/wireless/realtek/rtw88/usb.h      |  109 ++
 drivers/net/wireless/realtek/rtw88/util.c     |   92 ++
 drivers/net/wireless/realtek/rtw88/util.h     |   12 +-
 32 files changed, 1770 insertions(+), 36 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] 43+ messages in thread

* [PATCH 01/10] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
@ 2022-05-18  8:23 ` Sascha Hauer
  2022-05-18  8:23 ` [PATCH 02/10] rtw88: Drop rf_lock Sascha Hauer
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:23 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, 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 5cdc54c9a9aae..3c07485d6ba47 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -466,8 +466,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] 43+ messages in thread

* [PATCH 02/10] rtw88: Drop rf_lock
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
  2022-05-18  8:23 ` [PATCH 01/10] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held Sascha Hauer
@ 2022-05-18  8:23 ` Sascha Hauer
  2022-05-20  3:49   ` Pkshih
  2022-05-18  8:23 ` [PATCH 03/10] rtw88: Drop h2c.lock Sascha Hauer
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:23 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, 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 1a52ff585fbc7..ba5ba852efb8c 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);
@@ -418,7 +420,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);
@@ -523,6 +527,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) {
@@ -537,6 +543,8 @@ static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
 		seq_puts(m, "\n");
 	}
 
+	mutex_unlock(&rtwdev->mutex);
+
 	return 0;
 }
 
@@ -1027,6 +1035,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);
@@ -1036,6 +1046,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 8b9899e41b0bb..f9864840ffd9c 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1994,7 +1994,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 17815af9dd4ea..df6c6032bbd3b 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1994,9 +1994,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] 43+ messages in thread

* [PATCH 03/10] rtw88: Drop h2c.lock
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
  2022-05-18  8:23 ` [PATCH 01/10] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held Sascha Hauer
  2022-05-18  8:23 ` [PATCH 02/10] rtw88: Drop rf_lock Sascha Hauer
@ 2022-05-18  8:23 ` Sascha Hauer
  2022-05-18  8:23 ` [PATCH 04/10] rtw88: Drop coex mutex Sascha Hauer
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:23 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, 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 ba5ba852efb8c..79939aa6b752c 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -396,7 +396,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 aa2aeb5fb2ccd..c3ad2a1b47212 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -320,7 +320,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) {
@@ -342,7 +342,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,
@@ -351,7 +351,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++)
@@ -361,9 +361,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)
@@ -375,15 +372,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 f9864840ffd9c..baf4d29fde678 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1994,7 +1994,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 df6c6032bbd3b..619ee6e8d2807 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -2018,8 +2018,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] 43+ messages in thread

* [PATCH 04/10] rtw88: Drop coex mutex
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
                   ` (2 preceding siblings ...)
  2022-05-18  8:23 ` [PATCH 03/10] rtw88: Drop h2c.lock Sascha Hauer
@ 2022-05-18  8:23 ` Sascha Hauer
  2022-05-18  8:23 ` [PATCH 05/10] rtw88: Do not access registers while atomic Sascha Hauer
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:23 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, 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 cac053f485c3b..b156f8c48ffbb 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 79939aa6b752c..1453a32ea3ef0 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -842,7 +842,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 baf4d29fde678..5afb8bef9696a 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1998,7 +1998,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);
@@ -2066,7 +2065,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 619ee6e8d2807..fc27066a67a72 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1507,8 +1507,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] 43+ messages in thread

* [PATCH 05/10] rtw88: Do not access registers while atomic
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
                   ` (3 preceding siblings ...)
  2022-05-18  8:23 ` [PATCH 04/10] rtw88: Drop coex mutex Sascha Hauer
@ 2022-05-18  8:23 ` Sascha Hauer
  2022-05-20  6:06   ` Pkshih
  2022-05-20 17:32   ` Larry Finger
  2022-05-18  8:23 ` [PATCH 06/10] rtw88: Add common USB chip support Sascha Hauer
                   ` (6 subsequent siblings)
  11 siblings, 2 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:23 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, 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>
---
 drivers/net/wireless/realtek/rtw88/phy.c  |  6 +-
 drivers/net/wireless/realtek/rtw88/ps.c   |  2 +-
 drivers/net/wireless/realtek/rtw88/util.c | 92 +++++++++++++++++++++++
 drivers/net/wireless/realtek/rtw88/util.h | 12 ++-
 4 files changed, 105 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index e505d17f107e4..5521a7c2c1afe 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 bfa64c038f5f0..a7213ff2c2244 100644
--- a/drivers/net/wireless/realtek/rtw88/ps.c
+++ b/drivers/net/wireless/realtek/rtw88/ps.c
@@ -58,7 +58,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 2c515af214e76..db55dbd5c533e 100644
--- a/drivers/net/wireless/realtek/rtw88/util.c
+++ b/drivers/net/wireless/realtek/rtw88/util.c
@@ -105,3 +105,95 @@ 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;
+};
+
+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;
+
+	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;
+};
+
+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;
+
+	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] 43+ messages in thread

* [PATCH 06/10] rtw88: Add common USB chip support
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
                   ` (4 preceding siblings ...)
  2022-05-18  8:23 ` [PATCH 05/10] rtw88: Do not access registers while atomic Sascha Hauer
@ 2022-05-18  8:23 ` Sascha Hauer
  2022-05-18  8:32   ` Sascha Hauer
                     ` (3 more replies)
  2022-05-18  8:23 ` [PATCH 07/10] rtw88: Add rtw8723du chipset support Sascha Hauer
                   ` (5 subsequent siblings)
  11 siblings, 4 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:23 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, 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>
---
 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   |    5 +
 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    | 1051 +++++++++++++++++++
 drivers/net/wireless/realtek/rtw88/usb.h    |  109 ++
 9 files changed, 1209 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 d1678aed9d9cb..19728c705eaa9 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 5afb8bef9696a..162fa432ce0d1 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1715,6 +1715,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;
@@ -2105,6 +2109,7 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
 	hw->wiphy->available_antennas_rx = hal->antenna_rx;
 
 	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
+			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
 			    WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
 
 	hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index fc27066a67a72..007da6df088a3 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -876,6 +876,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 84ba9ec489c37..a928899030863 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 56371eff9f7ff..c02d7a15895c6 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.h
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
@@ -67,6 +67,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,
@@ -119,4 +127,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)
+{
+	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..7641ea6f6ad1a
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -0,0 +1,1051 @@
+// 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 void usbctrl_async_callback(struct urb *urb)
+{
+	/* free dr */
+	kfree(urb->setup_packet);
+	/* free databuf */
+	kfree(urb->transfer_buffer);
+}
+
+static int usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
+					  u16 value, u16 index, void *pdata,
+					  u16 len)
+{
+	int rc;
+	unsigned int pipe;
+	u8 reqtype;
+	struct usb_ctrlrequest *dr;
+	struct urb *urb;
+	const u16 databuf_maxlen = RTW_USB_VENQT_MAX_BUF_SIZE;
+	u8 *databuf;
+
+	if (WARN_ON_ONCE(len > databuf_maxlen))
+		len = databuf_maxlen;
+
+	pipe = usb_sndctrlpipe(udev, 0); /* write_out */
+	reqtype = RTW_USB_CMD_WRITE;
+
+	dr = kzalloc(sizeof(*dr), GFP_ATOMIC);
+	if (!dr)
+		return -ENOMEM;
+
+	databuf = kmemdup(pdata, len, GFP_ATOMIC);
+	if (!databuf) {
+		kfree(dr);
+		return -ENOMEM;
+	}
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!urb) {
+		kfree(databuf);
+		kfree(dr);
+		return -ENOMEM;
+	}
+
+	dr->bRequestType = reqtype;
+	dr->bRequest = request;
+	dr->wValue = cpu_to_le16(value);
+	dr->wIndex = cpu_to_le16(index);
+	dr->wLength = cpu_to_le16(len);
+
+	usb_fill_control_urb(urb, udev, pipe,
+			     (unsigned char *)dr, databuf, len,
+			     usbctrl_async_callback, NULL);
+	rc = usb_submit_urb(urb, GFP_ATOMIC);
+	if (rc < 0) {
+		kfree(databuf);
+		kfree(dr);
+	}
+
+	usb_free_urb(urb);
+
+	return rc;
+}
+
+static u32 rtw_usb_read_sync(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);
+
+	if (++rtwusb->usb_data_index >= RTW_USB_MAX_RX_COUNT)
+		rtwusb->usb_data_index = 0;
+	data = &rtwusb->usb_data[rtwusb->usb_data_index];
+
+	spin_unlock_irqrestore(&rtwusb->usb_lock, flags);
+
+	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, "reg 0x%x, usbctrl_vendorreq failed with %d\n",
+			addr, ret);
+
+	return le32_to_cpu(*data);
+}
+
+static u8 rtw_usb_read8_sync(struct rtw_dev *rtwdev, u32 addr)
+{
+	return (u8)rtw_usb_read_sync(rtwdev, addr, 1);
+}
+
+static u16 rtw_usb_read16_sync(struct rtw_dev *rtwdev, u32 addr)
+{
+	return (u16)rtw_usb_read_sync(rtwdev, addr, 2);
+}
+
+static u32 rtw_usb_read32_sync(struct rtw_dev *rtwdev, u32 addr)
+{
+	return (u32)rtw_usb_read_sync(rtwdev, addr, 4);
+}
+
+static void rtw_usb_write_async(struct rtw_dev *rtwdev, u32 addr, u32 val,
+				u16 len)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+	struct usb_device *udev = rtwusb->udev;
+	u8 request;
+	u16 wvalue;
+	u16 index;
+	__le32 data;
+
+	request = RTW_USB_CMD_REQ;
+	index = RTW_USB_VENQT_CMD_IDX; /* n/a */
+	wvalue = (u16)(addr & 0x0000ffff);
+	data = cpu_to_le32(val);
+	usbctrl_vendorreq_async_write(udev, request, wvalue, index, &data, len);
+}
+
+static void rtw_usb_write8_async(struct rtw_dev *rtwdev, u32 addr, u8 val)
+{
+	rtw_usb_write_async(rtwdev, addr, val, 1);
+}
+
+static void rtw_usb_write16_async(struct rtw_dev *rtwdev, u32 addr, u16 val)
+{
+	rtw_usb_write_async(rtwdev, addr, val, 2);
+}
+
+static void rtw_usb_write32_async(struct rtw_dev *rtwdev, u32 addr, u32 val)
+{
+	rtw_usb_write_async(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] = 1;
+		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = 1;
+		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_txcb_enqueue(struct rtw_usb_txcb *txcb, struct sk_buff *skb)
+{
+	skb_queue_tail(&txcb->tx_ack_queue, skb);
+}
+
+static void rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list,
+			       struct sk_buff *skb_head, struct sk_buff *skb,
+			       struct rtw_usb_txcb *txcb)
+{
+	struct sk_buff *skb_iter;
+	unsigned long flags;
+	u8 *data_ptr;
+	int agg_num = 0, len, max_len;
+
+	data_ptr = skb_head->data;
+	skb_iter = skb;
+
+	while (skb_iter) {
+		memcpy(data_ptr, skb_iter->data, skb_iter->len);
+		len = ALIGN(skb_iter->len, 8);
+		skb_put(skb_head, len);
+		data_ptr += len;
+		agg_num++;
+
+		rtw_usb_txcb_enqueue(txcb, skb_iter);
+
+		spin_lock_irqsave(&list->lock, flags);
+
+		skb_iter = skb_peek(list);
+		max_len = RTW_USB_MAX_XMITBUF_SZ - skb_head->len;
+
+		if (skb_iter && skb_iter->len < max_len)
+			__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);
+}
+
+static void rtw_usb_indicate_tx_status(struct rtw_dev *rtwdev,
+				       struct sk_buff *skb)
+{
+	struct ieee80211_hw *hw = rtwdev->hw;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct rtw_usb_tx_data *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);
+		return;
+	}
+
+	/* 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);
+}
+
+static void rtw_usb_write_port_tx_complete(struct urb *urb)
+{
+	struct rtw_usb_txcb *txcb = urb->context;
+	struct rtw_dev *rtwdev = txcb->rtwdev;
+
+	while (true) {
+		struct sk_buff *skb = skb_dequeue(&txcb->tx_ack_queue);
+		if (!skb)
+			break;
+
+		if (GET_TX_DESC_QSEL(skb->data) <= TX_DESC_QSEL_TID7)
+			rtw_usb_indicate_tx_status(rtwdev, skb);
+		else
+			dev_kfree_skb_any(skb);
+	}
+
+	kfree(txcb);
+}
+
+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 = rtwusb->qsel_to_ep[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 struct sk_buff *rtw_usb_tx_agg_check(struct rtw_usb *rtwusb,
+					    struct sk_buff *skb,
+					    int index,
+					    struct rtw_usb_txcb *txcb)
+{
+	struct sk_buff_head *list;
+	struct sk_buff *skb_head;
+
+	list = &rtwusb->tx_queue[index];
+	if (skb_queue_empty(list))
+		return NULL;
+
+	skb_head = dev_alloc_skb(RTW_USB_MAX_XMITBUF_SZ);
+	if (!skb_head)
+		return NULL;
+
+	rtw_usb_tx_agg_skb(rtwusb, list, skb_head, skb, txcb);
+
+	return skb_head;
+}
+
+static void rtw_usb_tx_agg(struct rtw_usb *rtwusb, struct sk_buff *skb, int index)
+{
+	struct rtw_dev *rtwdev = rtwusb->rtwdev;
+	struct sk_buff *skb_head;
+	struct rtw_usb_txcb *txcb;
+	u8 qsel;
+
+	txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC);
+	if (!txcb)
+		return;
+
+	txcb->rtwdev = rtwdev;
+	skb_queue_head_init(&txcb->tx_ack_queue);
+
+	skb_head = rtw_usb_tx_agg_check(rtwusb, skb, index, txcb);
+	if (!skb_head) {
+		skb_head = skb;
+		rtw_usb_txcb_enqueue(txcb, skb);
+	}
+
+	qsel = GET_TX_DESC_QSEL(skb->data);
+
+	rtw_usb_write_port(rtwdev, qsel, skb_head,
+			   rtw_usb_write_port_tx_complete, txcb);
+
+	if (skb_head != skb)
+		dev_kfree_skb(skb_head);
+}
+
+static void rtw_usb_tx_handler(struct work_struct *work)
+{
+	struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, tx_work);
+	struct sk_buff *skb;
+	int index, limit;
+
+	for (index = ARRAY_SIZE(rtwusb->tx_queue) - 1; index >= 0; index--) {
+		for (limit = 0; limit < 200; limit++) {
+			skb = skb_dequeue(&rtwusb->tx_queue[index]);
+			if (skb)
+				rtw_usb_tx_agg(rtwusb, skb, index);
+			else
+				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)
+{
+	struct rtw_chip_info *chip = rtwdev->chip;
+	struct sk_buff *skb;
+	unsigned int desclen, headsize, size;
+	u8 qsel;
+	int ret = 0;
+
+	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)
+{
+	struct rtw_chip_info *chip = rtwdev->chip;
+	struct rtw_usb *rtwusb;
+	struct rtw_tx_pkt_info pkt_info = {0};
+	u32 len, desclen;
+
+	if (unlikely(!rtwdev))
+		return -EINVAL;
+
+	rtwusb = rtw_get_usb_priv(rtwdev);
+	if (unlikely(!rtwusb))
+		return -EINVAL;
+
+	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);
+	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 = rtwusb->qsel_to_ep[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;
+	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_rx_data_put(struct rtw_usb *rtwusb,
+				struct rx_usb_ctrl_block *rxcb)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
+	list_move(&rxcb->list, &rtwusb->rx_data_free);
+	spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
+}
+
+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_data_put(rtwusb, rxcb);
+		queue_work(rtwusb->rxwq, &rtwusb->rx_refill_work);
+	} 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 unknown=%d\n", urb->status);
+			break;
+		}
+		if (skb)
+			dev_kfree_skb_any(skb);
+	}
+}
+
+static void rtw_usb_rx_refill_work(struct work_struct *work)
+{
+	struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_refill_work);
+	struct rtw_dev *rtwdev = rtwusb->rtwdev;
+	struct rx_usb_ctrl_block *rxcb;
+	unsigned long flags;
+	int error;
+
+	do {
+		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
+
+		rxcb = list_first_entry_or_null(&rtwusb->rx_data_free,
+						struct rx_usb_ctrl_block, list);
+
+		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
+		if (!rxcb)
+			return;
+
+		rxcb->rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_KERNEL);
+		if (!rxcb->rx_skb) {
+			rtw_err(rtwdev, "could not allocate rx skbuff\n");
+			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);
+
+		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
+		list_move(&rxcb->list, &rtwusb->rx_data_used);
+		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
+
+		error = usb_submit_urb(rxcb->rx_urb, GFP_KERNEL);
+		if (error) {
+			kfree_skb(rxcb->rx_skb);
+			if (error != -ENODEV)
+				rtw_err(rtwdev, "Err sending rx data urb %d\n",
+					   error);
+			rtw_usb_rx_data_put(rtwusb, rxcb);
+
+			return;
+		}
+	} while (true);
+}
+
+static void rtw_usb_cancel_rx_bufs(struct rtw_usb *rtwusb)
+{
+	struct rx_usb_ctrl_block *rxcb;
+	unsigned long flags;
+
+	spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
+
+	while (true) {
+		rxcb = list_first_entry_or_null(&rtwusb->rx_data_used,
+						struct rx_usb_ctrl_block, list);
+
+		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
+
+		if (!rxcb)
+			break;
+
+		usb_kill_urb(rxcb->rx_urb);
+
+		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
+		list_move(&rxcb->list, &rtwusb->rx_data_free);
+	}
+}
+
+static void rtw_usb_free_rx_bufs(struct rtw_usb *rtwusb)
+{
+	struct rx_usb_ctrl_block *rxcb;
+	unsigned long flags;
+
+	rtw_usb_cancel_rx_bufs(rtwusb);
+
+	spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
+
+	while (true) {
+		rxcb = list_first_entry_or_null(&rtwusb->rx_data_free, struct rx_usb_ctrl_block, list);
+
+		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
+
+		if (!rxcb)
+			break;
+
+		usb_free_urb(rxcb->rx_urb);
+
+		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
+		list_del(&rxcb->list);
+	}
+}
+
+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->rtwdev = rtwusb->rtwdev;
+		rxcb->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!rxcb->rx_urb)
+			goto err;
+		list_add_tail(&rxcb->list, &rtwusb->rx_data_free);
+	}
+
+	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)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+
+	queue_work(rtwusb->rxwq, &rtwusb->rx_refill_work);
+
+	return 0;
+}
+
+static void rtw_usb_stop(struct rtw_dev *rtwdev)
+{
+	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+
+	cancel_work_sync(&rtwusb->rx_refill_work);
+	rtw_usb_cancel_rx_bufs(rtwusb);
+}
+
+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_async,
+	.write16 = rtw_usb_write16_async,
+	.write32 = rtw_usb_write32_async,
+	.read8	= rtw_usb_read8_sync,
+	.read16 = rtw_usb_read16_sync,
+	.read32 = rtw_usb_read32_sync,
+
+	.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);
+
+	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);
+
+	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_RX_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;
+
+	INIT_WORK(&rtwusb->rx_refill_work, rtw_usb_rx_refill_work);
+	INIT_LIST_HEAD(&rtwusb->rx_data_free);
+	INIT_LIST_HEAD(&rtwusb->rx_data_used);
+	spin_lock_init(&rtwusb->rx_data_list_lock);
+
+	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_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..4d714372f265c
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/usb.h
@@ -0,0 +1,109 @@
+/* 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_RX_COUNT		100
+#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		(1592 * 3)
+#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
+
+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;
+	struct list_head list;
+};
+
+struct rtw_usb_tx_data {
+	u8 sn;
+};
+
+struct rtw_usb {
+	struct rtw_dev *rtwdev;
+	struct usb_device *udev;
+
+	spinlock_t rx_data_list_lock;
+	struct work_struct rx_refill_work;
+	struct list_head rx_data_free;
+	struct list_head rx_data_used;
+
+	spinlock_t usb_lock;
+	__le32 *usb_data;
+	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] 43+ messages in thread

* [PATCH 07/10] rtw88: Add rtw8723du chipset support
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
                   ` (5 preceding siblings ...)
  2022-05-18  8:23 ` [PATCH 06/10] rtw88: Add common USB chip support Sascha Hauer
@ 2022-05-18  8:23 ` Sascha Hauer
  2022-05-18 16:55   ` kernel test robot
                     ` (2 more replies)
  2022-05-18  8:23 ` [PATCH 08/10] rtw88: Add rtw8821cu " Sascha Hauer
                   ` (4 subsequent siblings)
  11 siblings, 3 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:23 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, 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>
---
 drivers/net/wireless/realtek/rtw88/Kconfig    | 11 +++++
 drivers/net/wireless/realtek/rtw88/Makefile   |  3 ++
 drivers/net/wireless/realtek/rtw88/rtw8723d.c | 19 +++++++++
 drivers/net/wireless/realtek/rtw88/rtw8723d.h |  1 +
 .../net/wireless/realtek/rtw88/rtw8723du.c    | 40 +++++++++++++++++++
 .../net/wireless/realtek/rtw88/rtw8723du.h    | 13 ++++++
 6 files changed, 87 insertions(+)
 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 1624c5db69bac..ad1ac453015a9 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -64,6 +64,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 9e095f8181483..eb26c215fcde3 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -38,6 +38,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 ad2b323a0423c..ccd23902756e1 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,15 @@ 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) */
+
+	fill_txdesc_checksum_common(txdesc, words);
+}
+
 static struct rtw_chip_ops rtw8723d_ops = {
 	.phy_set_param		= rtw8723d_phy_set_param,
 	.read_efuse		= rtw8723d_read_efuse,
@@ -1965,6 +1983,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 41d35174a5425..8113bd97edf57 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
@@ -70,6 +70,7 @@ struct rtw8723d_efuse {
 	u8 country_code[2];
 	u8 res[3];
 	struct rtw8723de_efuse e;
+	struct rtw8723de_efuse u;
 };
 
 /* phy status page0 */
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723du.c b/drivers/net/wireless/realtek/rtw88/rtw8723du.c
new file mode 100644
index 0000000000000..910f64c168131
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.c
@@ -0,0 +1,40 @@
+// 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[] = {
+	/*
+	 * ULLI :
+	 * ID found in rtw8822bu sources
+	 */
+	{ 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..2e069f65c0551
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#ifndef __RTW_8723DU_H_
+#define __RTW_8723DU_H_
+
+/* USB Vendor/Product IDs */
+#define RTW_USB_VENDOR_ID_REALTEK		0x0BDA
+
+extern struct rtw_chip_info rtw8723d_hw_spec;
+
+#endif
-- 
2.30.2


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

* [PATCH 08/10] rtw88: Add rtw8821cu chipset support
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
                   ` (6 preceding siblings ...)
  2022-05-18  8:23 ` [PATCH 07/10] rtw88: Add rtw8723du chipset support Sascha Hauer
@ 2022-05-18  8:23 ` Sascha Hauer
  2022-05-20  7:56   ` Pkshih
  2022-05-18  8:23 ` [PATCH 09/10] rtw88: Add rtw8822bu " Sascha Hauer
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:23 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, 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>
---
 drivers/net/wireless/realtek/rtw88/Kconfig    | 11 +++
 drivers/net/wireless/realtek/rtw88/Makefile   |  3 +
 drivers/net/wireless/realtek/rtw88/rtw8821c.c | 23 +++++++
 drivers/net/wireless/realtek/rtw88/rtw8821c.h | 21 ++++++
 .../net/wireless/realtek/rtw88/rtw8821cu.c    | 69 +++++++++++++++++++
 .../net/wireless/realtek/rtw88/rtw8821cu.h    | 15 ++++
 6 files changed, 142 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 ad1ac453015a9..5b1bafccd3d4c 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -86,6 +86,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 eb26c215fcde3..5498e8bbcbf17 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -47,6 +47,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 99eee128ae945..82e78559d8264 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;
@@ -1142,6 +1151,18 @@ 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)
+{
+	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 struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
 	{0x0086,
 	 RTW_PWR_CUT_ALL_MSK,
@@ -1515,6 +1536,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[] = {
@@ -1589,6 +1611,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 d9fbddd7b0f35..3ac54ea533117 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..e6710c5ebdfc8
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c
@@ -0,0 +1,69 @@
+// 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 */
+	/*=== Customer ID ===*/
+	{ USB_DEVICE(0x0bda, 0x2006),
+	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Totolink */
+	{ USB_DEVICE(0x0bda, 0xc811),
+	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Simplecom NW602 */
+	{},
+};
+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..bddbd96aa45fa
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#ifndef __RTW_8821CU_H_
+#define __RTW_8821CU_H_
+
+/* USB Vendor/Product IDs */
+#define RTW_USB_VENDOR_ID_REALTEK		0x0BDA
+#define RTW_USB_PRODUCT_ID_REALTEK_8811C	0xC811
+#define RTW_USB_PRODUCT_ID_REALTEK_8821C	0xC81C
+
+extern struct rtw_chip_info rtw8821c_hw_spec;
+
+#endif
-- 
2.30.2


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

* [PATCH 09/10] rtw88: Add rtw8822bu chipset support
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
                   ` (7 preceding siblings ...)
  2022-05-18  8:23 ` [PATCH 08/10] rtw88: Add rtw8821cu " Sascha Hauer
@ 2022-05-18  8:23 ` Sascha Hauer
  2022-05-20  7:58   ` Pkshih
  2022-05-23 11:56   ` Rin Cat (鈴猫)
  2022-05-18  8:23 ` [PATCH 10/10] rtw88: Add rtw8822cu " Sascha Hauer
                   ` (2 subsequent siblings)
  11 siblings, 2 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:23 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, 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>
---
 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    | 62 +++++++++++++++++++
 .../net/wireless/realtek/rtw88/rtw8822bu.h    | 15 +++++
 5 files changed, 110 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 5b1bafccd3d4c..e4c60f1449ec8 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 5498e8bbcbf17..e4126ddf7d659 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 eee7bf0354030..10497d351f229 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..5becebdc32471
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.c
@@ -0,0 +1,62 @@
+// 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"
+
+#define RTW_USB_VENDER_ID_EDIMAX	0x7392
+
+static const struct usb_device_id rtw_8822bu_id_table[] = {
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK,
+				       RTW_USB_PRODUCT_ID_REALTEK_8812B,
+				       0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK,
+				       RTW_USB_PRODUCT_ID_REALTEK_8822B,
+				       0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDER_ID_EDIMAX,
+					0xB822,
+					0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDER_ID_EDIMAX,
+					0xC822,
+					0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{ USB_DEVICE(0x0b05, 0x184c),	/* ASUS AC53 Nano */
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{ USB_DEVICE(0x0b05, 0x1841),	/* ASUS AC55 B1 */
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{ USB_DEVICE(0x2001, 0x331c),	/* D-Link DWA-182 rev D1 */
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{ USB_DEVICE(0x13b1, 0x0043),	/* Linksys WUSB6400M */
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{ USB_DEVICE(0x2357, 0x012D),	/* TP-Link AC1300 T3U */
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{ USB_DEVICE(0x2357, 0x0138),	/* TP-Link AC1300 T3U */
+	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
+	{},
+};
+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..20f01ecd74415
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#ifndef __RTW_8822BU_H_
+#define __RTW_8822BU_H_
+
+/* USB Vendor/Product IDs */
+#define RTW_USB_VENDOR_ID_REALTEK		0x0BDA
+#define RTW_USB_PRODUCT_ID_REALTEK_8812B	0xB812
+#define RTW_USB_PRODUCT_ID_REALTEK_8822B	0xB82C
+
+extern struct rtw_chip_info rtw8822b_hw_spec;
+
+#endif
-- 
2.30.2


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

* [PATCH 10/10] rtw88: Add rtw8822cu chipset support
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
                   ` (8 preceding siblings ...)
  2022-05-18  8:23 ` [PATCH 09/10] rtw88: Add rtw8822bu " Sascha Hauer
@ 2022-05-18  8:23 ` Sascha Hauer
  2022-05-20  8:03   ` Pkshih
  2022-05-23  4:07 ` [PATCH 00/10] RTW88: Add support for USB variants Hans Ulli Kroll
  2022-05-30  9:25 ` Kalle Valo
  11 siblings, 1 reply; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:23 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, 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>
---
 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    | 40 +++++++++++++++++++
 .../net/wireless/realtek/rtw88/rtw8822cu.h    | 15 +++++++
 5 files changed, 93 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 e4c60f1449ec8..651ab56d9c6bd 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 e4126ddf7d659..e0950dbc2565a 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 cd74607a61a28..51c90ef20c456 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)
+{
+	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..36dc734f76eb3
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822cu.c
@@ -0,0 +1,40 @@
+// 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,
+					RTW_USB_PRODUCT_ID_REALTEK_8822C,
+					0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK,
+					RTW_USB_PRODUCT_ID_REALTEK_8812C,
+					0xff, 0xff, 0xff),
+	  .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
+	{},
+};
+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..16afe22a8216c
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822cu.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019  Realtek Corporation
+ */
+
+#ifndef __RTW_8822CU_H_
+#define __RTW_8822CU_H_
+
+/* USB Vendor/Product IDs */
+#define RTW_USB_VENDOR_ID_REALTEK		0x0BDA
+#define RTW_USB_PRODUCT_ID_REALTEK_8812C	0xC812
+#define RTW_USB_PRODUCT_ID_REALTEK_8822C	0xC82C
+
+extern struct rtw_chip_info rtw8822c_hw_spec;
+
+#endif
-- 
2.30.2


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

* Re: [PATCH 06/10] rtw88: Add common USB chip support
  2022-05-18  8:23 ` [PATCH 06/10] rtw88: Add common USB chip support Sascha Hauer
@ 2022-05-18  8:32   ` Sascha Hauer
  2022-05-18  8:34     ` Johannes Berg
  2022-05-20  7:39   ` Pkshih
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 43+ messages in thread
From: Sascha Hauer @ 2022-05-18  8:32 UTC (permalink / raw)
  To: linux-wireless
  Cc: Ping-Ke Shih, Hans Ulli Kroll, Martin Blumenstingl, netdev,
	Kalle Valo, Yan-Hsuan Chuang, linux-kernel, Neo Jou, kernel,
	Johannes Berg, neo_jou

On Wed, May 18, 2022 at 10:23:14AM +0200, Sascha Hauer wrote:
> 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>
> ---
>  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   |    5 +
>  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    | 1051 +++++++++++++++++++
>  drivers/net/wireless/realtek/rtw88/usb.h    |  109 ++
>  9 files changed, 1209 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 d1678aed9d9cb..19728c705eaa9 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 5afb8bef9696a..162fa432ce0d1 100644
> --- a/drivers/net/wireless/realtek/rtw88/main.c
> +++ b/drivers/net/wireless/realtek/rtw88/main.c
> @@ -1715,6 +1715,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;
> @@ -2105,6 +2109,7 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
>  	hw->wiphy->available_antennas_rx = hal->antenna_rx;
>  
>  	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
> +			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
>  			    WIPHY_FLAG_TDLS_EXTERNAL_SETUP;

This change should be in a separate patch. I don't have an idea though
what it's good for anyway. Is this change desired for the PCI variants
as well or only for USB? Do we want to have this change at all?

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] 43+ messages in thread

* Re: [PATCH 06/10] rtw88: Add common USB chip support
  2022-05-18  8:32   ` Sascha Hauer
@ 2022-05-18  8:34     ` Johannes Berg
  2022-05-19 13:58       ` Sascha Hauer
  0 siblings, 1 reply; 43+ messages in thread
From: Johannes Berg @ 2022-05-18  8:34 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Ping-Ke Shih, Hans Ulli Kroll, Martin Blumenstingl, netdev,
	Kalle Valo, Yan-Hsuan Chuang, linux-kernel, Neo Jou, kernel,
	neo_jou

On Wed, 2022-05-18 at 10:32 +0200, Sascha Hauer wrote:
> 
> >  	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
> > +			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
> >  			    WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
> 
> This change should be in a separate patch. I don't have an idea though
> what it's good for anyway. Is this change desired for the PCI variants
> as well or only for USB? Do we want to have this change at all?
> 

This driver uses mac80211, so that change should just not be there.
mac80211 will set it automatically if it's possible, see in
net/mac80211/main.c.

johannes

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

* Re: [PATCH 07/10] rtw88: Add rtw8723du chipset support
  2022-05-18  8:23 ` [PATCH 07/10] rtw88: Add rtw8723du chipset support Sascha Hauer
@ 2022-05-18 16:55   ` kernel test robot
  2022-05-20  7:47   ` Pkshih
  2022-05-30  6:34   ` Icenowy Zheng
  2 siblings, 0 replies; 43+ messages in thread
From: kernel test robot @ 2022-05-18 16:55 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: kbuild-all, Neo Jou, Hans Ulli Kroll, Ping-Ke Shih,
	Yan-Hsuan Chuang, Kalle Valo, netdev, linux-kernel,
	Martin Blumenstingl, kernel, Johannes Berg, Sascha Hauer

Hi Sascha,

I love your patch! Perhaps something to improve:

[auto build test WARNING on wireless-next/main]
[also build test WARNING on wireless/main v5.18-rc7 next-20220518]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Sascha-Hauer/RTW88-Add-support-for-USB-variants/20220518-162621
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20220519/202205190028.z15SPbJx-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 11.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/0a06adba364ef264404e3c7ae111a71f0d74c5a9
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Sascha-Hauer/RTW88-Add-support-for-USB-variants/20220518-162621
        git checkout 0a06adba364ef264404e3c7ae111a71f0d74c5a9
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash drivers/net/wireless/realtek/rtw88/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/net/wireless/realtek/rtw88/util.c:119:6: warning: no previous prototype for 'rtw_collect_sta_iter' [-Wmissing-prototypes]
     119 | void rtw_collect_sta_iter(void *data, struct ieee80211_sta *sta)
         |      ^~~~~~~~~~~~~~~~~~~~
>> drivers/net/wireless/realtek/rtw88/util.c:165:6: warning: no previous prototype for 'rtw_collect_vif_iter' [-Wmissing-prototypes]
     165 | void rtw_collect_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
         |      ^~~~~~~~~~~~~~~~~~~~


vim +/rtw_collect_sta_iter +119 drivers/net/wireless/realtek/rtw88/util.c

1c99f6652d3fbb Sascha Hauer 2022-05-18  118  
1c99f6652d3fbb Sascha Hauer 2022-05-18 @119  void rtw_collect_sta_iter(void *data, struct ieee80211_sta *sta)
1c99f6652d3fbb Sascha Hauer 2022-05-18  120  {
1c99f6652d3fbb Sascha Hauer 2022-05-18  121  	struct rtw_iter_stas_data *iter_stas = data;
1c99f6652d3fbb Sascha Hauer 2022-05-18  122  	struct rtw_stas_entry *stas_entry;
1c99f6652d3fbb Sascha Hauer 2022-05-18  123  
1c99f6652d3fbb Sascha Hauer 2022-05-18  124  	stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC);
1c99f6652d3fbb Sascha Hauer 2022-05-18  125  	if (!stas_entry)
1c99f6652d3fbb Sascha Hauer 2022-05-18  126  		return;
1c99f6652d3fbb Sascha Hauer 2022-05-18  127  
1c99f6652d3fbb Sascha Hauer 2022-05-18  128  	stas_entry->sta = sta;
1c99f6652d3fbb Sascha Hauer 2022-05-18  129  	list_add_tail(&stas_entry->list, &iter_stas->list);
1c99f6652d3fbb Sascha Hauer 2022-05-18  130  }
1c99f6652d3fbb Sascha Hauer 2022-05-18  131  
1c99f6652d3fbb Sascha Hauer 2022-05-18  132  void rtw_iterate_stas(struct rtw_dev *rtwdev,
1c99f6652d3fbb Sascha Hauer 2022-05-18  133  		      void (*iterator)(void *data,
1c99f6652d3fbb Sascha Hauer 2022-05-18  134  				       struct ieee80211_sta *sta),
1c99f6652d3fbb Sascha Hauer 2022-05-18  135  				       void *data)
1c99f6652d3fbb Sascha Hauer 2022-05-18  136  {
1c99f6652d3fbb Sascha Hauer 2022-05-18  137  	struct rtw_iter_stas_data iter_data;
1c99f6652d3fbb Sascha Hauer 2022-05-18  138  	struct rtw_stas_entry *sta_entry, *tmp;
1c99f6652d3fbb Sascha Hauer 2022-05-18  139  
1c99f6652d3fbb Sascha Hauer 2022-05-18  140  	iter_data.rtwdev = rtwdev;
1c99f6652d3fbb Sascha Hauer 2022-05-18  141  	INIT_LIST_HEAD(&iter_data.list);
1c99f6652d3fbb Sascha Hauer 2022-05-18  142  
1c99f6652d3fbb Sascha Hauer 2022-05-18  143  	ieee80211_iterate_stations_atomic(rtwdev->hw, rtw_collect_sta_iter,
1c99f6652d3fbb Sascha Hauer 2022-05-18  144  					  &iter_data);
1c99f6652d3fbb Sascha Hauer 2022-05-18  145  
1c99f6652d3fbb Sascha Hauer 2022-05-18  146  	list_for_each_entry_safe(sta_entry, tmp, &iter_data.list,
1c99f6652d3fbb Sascha Hauer 2022-05-18  147  				 list) {
1c99f6652d3fbb Sascha Hauer 2022-05-18  148  		list_del_init(&sta_entry->list);
1c99f6652d3fbb Sascha Hauer 2022-05-18  149  		iterator(data, sta_entry->sta);
1c99f6652d3fbb Sascha Hauer 2022-05-18  150  		kfree(sta_entry);
1c99f6652d3fbb Sascha Hauer 2022-05-18  151  	}
1c99f6652d3fbb Sascha Hauer 2022-05-18  152  }
1c99f6652d3fbb Sascha Hauer 2022-05-18  153  
1c99f6652d3fbb Sascha Hauer 2022-05-18  154  struct rtw_vifs_entry {
1c99f6652d3fbb Sascha Hauer 2022-05-18  155  	struct list_head list;
1c99f6652d3fbb Sascha Hauer 2022-05-18  156  	struct ieee80211_vif *vif;
1c99f6652d3fbb Sascha Hauer 2022-05-18  157  	u8 mac[ETH_ALEN];
1c99f6652d3fbb Sascha Hauer 2022-05-18  158  };
1c99f6652d3fbb Sascha Hauer 2022-05-18  159  
1c99f6652d3fbb Sascha Hauer 2022-05-18  160  struct rtw_iter_vifs_data {
1c99f6652d3fbb Sascha Hauer 2022-05-18  161  	struct rtw_dev *rtwdev;
1c99f6652d3fbb Sascha Hauer 2022-05-18  162  	struct list_head list;
1c99f6652d3fbb Sascha Hauer 2022-05-18  163  };
1c99f6652d3fbb Sascha Hauer 2022-05-18  164  
1c99f6652d3fbb Sascha Hauer 2022-05-18 @165  void rtw_collect_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1c99f6652d3fbb Sascha Hauer 2022-05-18  166  {
1c99f6652d3fbb Sascha Hauer 2022-05-18  167  	struct rtw_iter_vifs_data *iter_stas = data;
1c99f6652d3fbb Sascha Hauer 2022-05-18  168  	struct rtw_vifs_entry *vifs_entry;
1c99f6652d3fbb Sascha Hauer 2022-05-18  169  
1c99f6652d3fbb Sascha Hauer 2022-05-18  170  	vifs_entry = kmalloc(sizeof(*vifs_entry), GFP_ATOMIC);
1c99f6652d3fbb Sascha Hauer 2022-05-18  171  	if (!vifs_entry)
1c99f6652d3fbb Sascha Hauer 2022-05-18  172  		return;
1c99f6652d3fbb Sascha Hauer 2022-05-18  173  
1c99f6652d3fbb Sascha Hauer 2022-05-18  174  	vifs_entry->vif = vif;
1c99f6652d3fbb Sascha Hauer 2022-05-18  175  	ether_addr_copy(vifs_entry->mac, mac);
1c99f6652d3fbb Sascha Hauer 2022-05-18  176  	list_add_tail(&vifs_entry->list, &iter_stas->list);
1c99f6652d3fbb Sascha Hauer 2022-05-18  177  }
1c99f6652d3fbb Sascha Hauer 2022-05-18  178  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

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

* Re: [PATCH 06/10] rtw88: Add common USB chip support
  2022-05-18  8:34     ` Johannes Berg
@ 2022-05-19 13:58       ` Sascha Hauer
  0 siblings, 0 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-19 13:58 UTC (permalink / raw)
  To: Johannes Berg
  Cc: linux-wireless, Ping-Ke Shih, Hans Ulli Kroll,
	Martin Blumenstingl, netdev, Kalle Valo, Yan-Hsuan Chuang,
	linux-kernel, Neo Jou, kernel, neo_jou

On Wed, May 18, 2022 at 10:34:58AM +0200, Johannes Berg wrote:
> On Wed, 2022-05-18 at 10:32 +0200, Sascha Hauer wrote:
> > 
> > >  	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
> > > +			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
> > >  			    WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
> > 
> > This change should be in a separate patch. I don't have an idea though
> > what it's good for anyway. Is this change desired for the PCI variants
> > as well or only for USB? Do we want to have this change at all?
> > 
> 
> This driver uses mac80211, so that change should just not be there.
> mac80211 will set it automatically if it's possible, see in
> net/mac80211/main.c.

Ok, removing it doesn't seem to have any visible effect. I'll drop that
hunk for the next round.

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] 43+ messages in thread

* Re: [PATCH 02/10] rtw88: Drop rf_lock
  2022-05-18  8:23 ` [PATCH 02/10] rtw88: Drop rf_lock Sascha Hauer
@ 2022-05-20  3:49   ` Pkshih
  2022-05-20  6:54     ` s.hauer
  0 siblings, 1 reply; 43+ messages in thread
From: Pkshih @ 2022-05-20  3:49 UTC (permalink / raw)
  To: s.hauer, linux-wireless
  Cc: johannes, kernel, neojou, kvalo, tony0620emma, linux-kernel,
	martin.blumenstingl, linux, netdev

On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> 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 1a52ff585fbc7..ba5ba852efb8c 100644
> --- a/drivers/net/wireless/realtek/rtw88/debug.c
> +++ b/drivers/net/wireless/realtek/rtw88/debug.c
> 

[...]

> @@ -523,6 +527,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) {
> @@ -537,6 +543,8 @@ static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
>  		seq_puts(m, "\n");
>  	}
>  
> +	mutex_unlock(&rtwdev->mutex);
> +
>  	return 0;
>  }
> 

This will take time to dump all RF registers for debugging
purpose. For PCI interface, I think this would be okay.
Could you try to dump registers via debufs while you are
using a USB WiFi device, such as play Youtube or download files...

If it doesn't work very well, I suggest to use rf_mutex to
replace rf_lock inplace, but not just remove rf_lock.

--
Ping-Ke



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

* Re: [PATCH 05/10] rtw88: Do not access registers while atomic
  2022-05-18  8:23 ` [PATCH 05/10] rtw88: Do not access registers while atomic Sascha Hauer
@ 2022-05-20  6:06   ` Pkshih
  2022-05-20  7:07     ` s.hauer
  2022-05-20 17:32   ` Larry Finger
  1 sibling, 1 reply; 43+ messages in thread
From: Pkshih @ 2022-05-20  6:06 UTC (permalink / raw)
  To: s.hauer, linux-wireless
  Cc: johannes, kernel, neojou, kvalo, tony0620emma, linux-kernel,
	martin.blumenstingl, linux, netdev

On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> 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
                                           ^^^^^^^ does?
> 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.

I think the subject could be "iterate over vif/sta list non-atomically"

> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Suggested-by: Pkshih <pkshih@realtek.com>
> ---
>  drivers/net/wireless/realtek/rtw88/phy.c  |  6 +-
>  drivers/net/wireless/realtek/rtw88/ps.c   |  2 +-
>  drivers/net/wireless/realtek/rtw88/util.c | 92 +++++++++++++++++++++++
>  drivers/net/wireless/realtek/rtw88/util.h | 12 ++-
>  4 files changed, 105 insertions(+), 7 deletions(-)
> 
> 

[...]

>  
> diff --git a/drivers/net/wireless/realtek/rtw88/util.c b/drivers/net/wireless/realtek/rtw88/util.c
> index 2c515af214e76..db55dbd5c533e 100644
> --- a/drivers/net/wireless/realtek/rtw88/util.c
> +++ b/drivers/net/wireless/realtek/rtw88/util.c
> @@ -105,3 +105,95 @@ void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss)
>  		*mcs = rate - DESC_RATEMCS0;
>  	}
>  }
> 

[...]

> +
> +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;

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);
> +	}
> +}
> +

[...]

> +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;

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);
> +	}
> +}
> 

[...]

--
Ping-Ke



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

* Re: [PATCH 02/10] rtw88: Drop rf_lock
  2022-05-20  3:49   ` Pkshih
@ 2022-05-20  6:54     ` s.hauer
  0 siblings, 0 replies; 43+ messages in thread
From: s.hauer @ 2022-05-20  6:54 UTC (permalink / raw)
  To: Pkshih
  Cc: linux-wireless, johannes, kernel, neojou, kvalo, tony0620emma,
	linux-kernel, martin.blumenstingl, linux, netdev

On Fri, May 20, 2022 at 03:49:06AM +0000, Pkshih wrote:
> On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> > 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 1a52ff585fbc7..ba5ba852efb8c 100644
> > --- a/drivers/net/wireless/realtek/rtw88/debug.c
> > +++ b/drivers/net/wireless/realtek/rtw88/debug.c
> > 
> 
> [...]
> 
> > @@ -523,6 +527,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) {
> > @@ -537,6 +543,8 @@ static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
> >  		seq_puts(m, "\n");
> >  	}
> >  
> > +	mutex_unlock(&rtwdev->mutex);
> > +
> >  	return 0;
> >  }
> > 
> 
> This will take time to dump all RF registers for debugging
> purpose. For PCI interface, I think this would be okay.
> Could you try to dump registers via debufs while you are
> using a USB WiFi device, such as play Youtube or download files...

I just did a ping and iperf test while doing a:

while true; do cat /sys/kernel/debug/ieee80211/phy0/rtw88/rf_dump ; done

The register dumping has no influence on neither the throughput or the
latency.

Adding some debugging to the mutex_lock also tells why: rtwdev->mutex
isn't acquired for normal rx/tx. It is only acquired every two seconds
or so.

So I would say adding the mutex_lock around the register dump is not a
problem. If latency is a concern we could still move the mutex_lock()
into the loop.

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] 43+ messages in thread

* Re: [PATCH 05/10] rtw88: Do not access registers while atomic
  2022-05-20  6:06   ` Pkshih
@ 2022-05-20  7:07     ` s.hauer
  0 siblings, 0 replies; 43+ messages in thread
From: s.hauer @ 2022-05-20  7:07 UTC (permalink / raw)
  To: Pkshih
  Cc: linux-wireless, johannes, kernel, neojou, kvalo, tony0620emma,
	linux-kernel, martin.blumenstingl, linux, netdev

On Fri, May 20, 2022 at 06:06:05AM +0000, Pkshih wrote:
> On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> > 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
>                                            ^^^^^^^ does?
> > 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.
> 
> I think the subject could be "iterate over vif/sta list non-atomically"

Ok.

> > +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;
> 
> 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);
> > +	}
> > +}
> > +
> 
> [...]
> 
> > +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;
> 
> lockdep_assert_held(&rtwdev->mutex);

Ok, will add these. For what it's worth they didn't trigger in a short
test.

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] 43+ messages in thread

* Re: [PATCH 06/10] rtw88: Add common USB chip support
  2022-05-18  8:23 ` [PATCH 06/10] rtw88: Add common USB chip support Sascha Hauer
  2022-05-18  8:32   ` Sascha Hauer
@ 2022-05-20  7:39   ` Pkshih
  2022-05-20  8:51     ` s.hauer
  2022-05-20 18:33   ` Larry Finger
  2022-05-23  4:07   ` Hans Ulli Kroll
  3 siblings, 1 reply; 43+ messages in thread
From: Pkshih @ 2022-05-20  7:39 UTC (permalink / raw)
  To: s.hauer, linux-wireless
  Cc: johannes, kernel, neojou, kvalo, tony0620emma, linux-kernel,
	martin.blumenstingl, linux, netdev, neo_jou

On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> 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>
> ---
>  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   |    5 +
>  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    | 1051 +++++++++++++++++++
>  drivers/net/wireless/realtek/rtw88/usb.h    |  109 ++
>  9 files changed, 1209 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/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
> index 84ba9ec489c37..a928899030863 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)                                                   \
				^^^^^^^ replace 8 spaces by one tab

>  	(((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)                                                   \
					^^^^^ use tab

> diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h
> index 56371eff9f7ff..c02d7a15895c6 100644
> --- a/drivers/net/wireless/realtek/rtw88/tx.h
> +++ b/drivers/net/wireless/realtek/rtw88/tx.h
> @@ -67,6 +67,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)                                        \
						^^^^ use tab

I think you can run ./script/checkpatch.pl to find out these coding style issues.

> +	le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(12, 8))
>  
>  enum rtw_tx_desc_queue_select {
>  	TX_DESC_QSEL_TID0	= 0,
> @@ -119,4 +127,27 @@ rtw_tx_write_data_h2c_get(struct rtw_dev *rtwdev,
>  			  struct rtw_tx_pkt_info *pkt_info,
>  			  u8 *buf, u32 size);
>  
> 

[...]

> diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
> new file mode 100644
> index 0000000000000..7641ea6f6ad1a
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/usb.c
> @@ -0,0 +1,1051 @@
> +// 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 void usbctrl_async_callback(struct urb *urb)
> +{
> +	/* free dr */
> +	kfree(urb->setup_packet);
> +	/* free databuf */
> +	kfree(urb->transfer_buffer);
> +}
> +
> +static int usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
> +					  u16 value, u16 index, void *pdata,
> +					  u16 len)
> +{
> +	int rc;

Normally, we use 'ret' as return code instead.

> +	unsigned int pipe;
> +	u8 reqtype;
> +	struct usb_ctrlrequest *dr;
> +	struct urb *urb;
> +	const u16 databuf_maxlen = RTW_USB_VENQT_MAX_BUF_SIZE;
> +	u8 *databuf;

declare in reverse X'mas tree:

const u16 databuf_maxlen = RTW_USB_VENQT_MAX_BUF_SIZE;
struct usb_ctrlrequest *dr;
unsigned int pipe;
struct urb *urb;
u8 *databuf;
int ret;


> +
> +	if (WARN_ON_ONCE(len > databuf_maxlen))
> +		len = databuf_maxlen;
> +
> +	pipe = usb_sndctrlpipe(udev, 0); /* write_out */
> +	reqtype = RTW_USB_CMD_WRITE;
> +
> +	dr = kzalloc(sizeof(*dr), GFP_ATOMIC);
> +	if (!dr)
> +		return -ENOMEM;
> +
> +	databuf = kmemdup(pdata, len, GFP_ATOMIC);
> +	if (!databuf) {
> +		kfree(dr);
> +		return -ENOMEM;
> +	}
> +
> +	urb = usb_alloc_urb(0, GFP_ATOMIC);
> +	if (!urb) {
> +		kfree(databuf);
> +		kfree(dr);
> +		return -ENOMEM;
> +	}
> +
> +	dr->bRequestType = reqtype;
> +	dr->bRequest = request;
> +	dr->wValue = cpu_to_le16(value);
> +	dr->wIndex = cpu_to_le16(index);
> +	dr->wLength = cpu_to_le16(len);
> +
> +	usb_fill_control_urb(urb, udev, pipe,
> +			     (unsigned char *)dr, databuf, len,
> +			     usbctrl_async_callback, NULL);
> +	rc = usb_submit_urb(urb, GFP_ATOMIC);
> +	if (rc < 0) {
> +		kfree(databuf);
> +		kfree(dr);
> +	}
> +
> +	usb_free_urb(urb);
> +
> +	return rc;
> +}
> +
> +static u32 rtw_usb_read_sync(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);
> +
> +	if (++rtwusb->usb_data_index >= RTW_USB_MAX_RX_COUNT)
> +		rtwusb->usb_data_index = 0;
> +	data = &rtwusb->usb_data[rtwusb->usb_data_index];
> +
> +	spin_unlock_irqrestore(&rtwusb->usb_lock, flags);
> +
> +	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
> +				 RTW_USB_CMD_REQ, RTW_USB_CMD_READ, addr,
			     ^^^^ align open parenthesis (codging style)

checkpatch.pl can help this.


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

[...]

> +
> +static void rtw_usb_rx_refill_work(struct work_struct *work)
> +{
> +	struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_refill_work);
> +	struct rtw_dev *rtwdev = rtwusb->rtwdev;
> +	struct rx_usb_ctrl_block *rxcb;
> +	unsigned long flags;
> +	int error;
> +
> +	do {
> +		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> +
> +		rxcb = list_first_entry_or_null(&rtwusb->rx_data_free,
> +						struct rx_usb_ctrl_block, list);
> +
> +		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
> +		if (!rxcb)
> +			return;
> +
> +		rxcb->rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_KERNEL);
> +		if (!rxcb->rx_skb) {
> +			rtw_err(rtwdev, "could not allocate rx skbuff\n");
> +			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);
> +
> +		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> +		list_move(&rxcb->list, &rtwusb->rx_data_used);
> +		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
> +
> +		error = usb_submit_urb(rxcb->rx_urb, GFP_KERNEL);
> +		if (error) {
> +			kfree_skb(rxcb->rx_skb);
> +			if (error != -ENODEV)
> +				rtw_err(rtwdev, "Err sending rx data urb %d\n",
> +					   error);
> +			rtw_usb_rx_data_put(rtwusb, rxcb);
> +
> +			return;
> +		}
> +	} while (true);

Can we have a limit of 'for(;<limit;)' insetad of 'while (true)'?

> +}
> +
> +static void rtw_usb_cancel_rx_bufs(struct rtw_usb *rtwusb)
> +{
> +	struct rx_usb_ctrl_block *rxcb;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> +
> +	while (true) {
> +		rxcb = list_first_entry_or_null(&rtwusb->rx_data_used,
> +						struct rx_usb_ctrl_block, list);
> +
> +		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
> +
> +		if (!rxcb)
> +			break;
> +
> +		usb_kill_urb(rxcb->rx_urb);
> +
> +		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> +		list_move(&rxcb->list, &rtwusb->rx_data_free);
> +	}
> +}

The spin_lock pairs are not intuitive.
Can we change this chunk to

while (true) {
     spin_lock();
     rxcb = list_first_entry_or_null();
     spin_unlock()

     if (!rxcb)
        return;

     usb_free_urb();

     spin_lock();
     list_del();
     spin_unlock();
}

The drawback is lock/unlock twice in single loop.

rtw_usb_free_rx_bufs() has similar coding.


> +
> +static void rtw_usb_free_rx_bufs(struct rtw_usb *rtwusb)
> +{
> +	struct rx_usb_ctrl_block *rxcb;
> +	unsigned long flags;
> +
> +	rtw_usb_cancel_rx_bufs(rtwusb);
> +
> +	spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> +
> +	while (true) {
> +		rxcb = list_first_entry_or_null(&rtwusb->rx_data_free, struct rx_usb_ctrl_block,
> list);
> +
> +		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
> +
> +		if (!rxcb)
> +			break;
> +
> +		usb_free_urb(rxcb->rx_urb);
> +
> +		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> +		list_del(&rxcb->list);
> +	}


> diff --git a/drivers/net/wireless/realtek/rtw88/usb.h b/drivers/net/wireless/realtek/rtw88/usb.h
> new file mode 100644
> index 0000000000000..4d714372f265c
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/usb.h
> @@ -0,0 +1,109 @@
> +/* 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
				^^^^^^^^^^ use tab

> +
> +#define RTW_USB_MAX_RX_COUNT		100
> +#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
          ^^^^^ use space
> +
> +#define RTW_USB_SUPER_SPEED_BULK_SIZE	1024
> +#define RTW_USB_HIGH_SPEED_BULK_SIZE	512
> +#define RTW_USB_FULL_SPEED_BULK_SIZE	64
> +

--
Ping-Ke



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

* Re: [PATCH 07/10] rtw88: Add rtw8723du chipset support
  2022-05-18  8:23 ` [PATCH 07/10] rtw88: Add rtw8723du chipset support Sascha Hauer
  2022-05-18 16:55   ` kernel test robot
@ 2022-05-20  7:47   ` Pkshih
  2022-05-20  8:16     ` s.hauer
  2022-05-30  6:34   ` Icenowy Zheng
  2 siblings, 1 reply; 43+ messages in thread
From: Pkshih @ 2022-05-20  7:47 UTC (permalink / raw)
  To: s.hauer, linux-wireless
  Cc: johannes, kernel, neojou, kvalo, tony0620emma, linux-kernel,
	martin.blumenstingl, linux, netdev

On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> 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>
> ---
>  drivers/net/wireless/realtek/rtw88/Kconfig    | 11 +++++
>  drivers/net/wireless/realtek/rtw88/Makefile   |  3 ++
>  drivers/net/wireless/realtek/rtw88/rtw8723d.c | 19 +++++++++
>  drivers/net/wireless/realtek/rtw88/rtw8723d.h |  1 +
>  .../net/wireless/realtek/rtw88/rtw8723du.c    | 40 +++++++++++++++++++
>  .../net/wireless/realtek/rtw88/rtw8723du.h    | 13 ++++++
>  6 files changed, 87 insertions(+)
>  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/rtw8723du.c
> b/drivers/net/wireless/realtek/rtw88/rtw8723du.c
> new file mode 100644
> index 0000000000000..910f64c168131
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.c
> @@ -0,0 +1,40 @@
> +// 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[] = {
> +	/*
> +	 * ULLI :
> +	 * ID found in rtw8822bu sources
> +	 */

checkpatch.pl will tell us this comment block should be

/* ULLI :
 * ID found in rtw8822bu sources
 */

But, I think we can just "/* ULLI: ID found in rtw8822bu sources */" 
if we really want to keep this comment.


[...]

> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723du.h
> b/drivers/net/wireless/realtek/rtw88/rtw8723du.h
> new file mode 100644
> index 0000000000000..2e069f65c0551
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
> +/* Copyright(c) 2018-2019  Realtek Corporation
> + */
> +
> +#ifndef __RTW_8723DU_H_
> +#define __RTW_8723DU_H_
> +
> +/* USB Vendor/Product IDs */
> +#define RTW_USB_VENDOR_ID_REALTEK		0x0BDA

rtw8821cu.h and rtw8822bu.h define this too.
Can we move it to usb.h?


> +
> +extern struct rtw_chip_info rtw8723d_hw_spec;
> +
> +#endif


Ping-Ke



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

* Re: [PATCH 08/10] rtw88: Add rtw8821cu chipset support
  2022-05-18  8:23 ` [PATCH 08/10] rtw88: Add rtw8821cu " Sascha Hauer
@ 2022-05-20  7:56   ` Pkshih
  0 siblings, 0 replies; 43+ messages in thread
From: Pkshih @ 2022-05-20  7:56 UTC (permalink / raw)
  To: s.hauer, linux-wireless
  Cc: johannes, kernel, neojou, kvalo, tony0620emma, linux-kernel,
	martin.blumenstingl, linux, netdev

On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> 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>
> ---
>  drivers/net/wireless/realtek/rtw88/Kconfig    | 11 +++
>  drivers/net/wireless/realtek/rtw88/Makefile   |  3 +
>  drivers/net/wireless/realtek/rtw88/rtw8821c.c | 23 +++++++
>  drivers/net/wireless/realtek/rtw88/rtw8821c.h | 21 ++++++
>  .../net/wireless/realtek/rtw88/rtw8821cu.c    | 69 +++++++++++++++++++
>  .../net/wireless/realtek/rtw88/rtw8821cu.h    | 15 ++++
>  6 files changed, 142 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/rtw8821cu.c
> b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c
> new file mode 100644
> index 0000000000000..e6710c5ebdfc8
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c
> @@ -0,0 +1,69 @@
> +// 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 */
> +	/*=== Customer ID ===*/
> +	{ USB_DEVICE(0x0bda, 0x2006),

USB_DEVICE(RTW_USB_VENDOR_ID_REALTEK, 0x2006),

> +	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Totolink */
> +	{ USB_DEVICE(0x0bda, 0xc811),

USB_DEVICE(RTW_USB_VENDOR_ID_REALTEK, 0xc811),


> +	  .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Simplecom NW602 */
> +	{},
> +};
> +MODULE_DEVICE_TABLE(usb, rtw_8821cu_id_table);
> +
> 

[...]

> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821cu.h
> b/drivers/net/wireless/realtek/rtw88/rtw8821cu.h
> new file mode 100644
> index 0000000000000..bddbd96aa45fa
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
> +/* Copyright(c) 2018-2019  Realtek Corporation
> + */
> +
> +#ifndef __RTW_8821CU_H_
> +#define __RTW_8821CU_H_
> +
> +/* USB Vendor/Product IDs */
> +#define RTW_USB_VENDOR_ID_REALTEK		0x0BDA

move to usb.h

> +#define RTW_USB_PRODUCT_ID_REALTEK_8811C	0xC811
> +#define RTW_USB_PRODUCT_ID_REALTEK_8821C	0xC81C

These two are not used.

> +
> +extern struct rtw_chip_info rtw8821c_hw_spec;
> +
> +#endif


--
Ping-Ke


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

* Re: [PATCH 09/10] rtw88: Add rtw8822bu chipset support
  2022-05-18  8:23 ` [PATCH 09/10] rtw88: Add rtw8822bu " Sascha Hauer
@ 2022-05-20  7:58   ` Pkshih
  2022-05-23 11:56   ` Rin Cat (鈴猫)
  1 sibling, 0 replies; 43+ messages in thread
From: Pkshih @ 2022-05-20  7:58 UTC (permalink / raw)
  To: s.hauer, linux-wireless
  Cc: johannes, kernel, neojou, kvalo, tony0620emma, linux-kernel,
	martin.blumenstingl, linux, netdev

On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> 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>
> ---
>  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    | 62 +++++++++++++++++++
>  .../net/wireless/realtek/rtw88/rtw8822bu.h    | 15 +++++
>  5 files changed, 110 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/rtw8822bu.h
> b/drivers/net/wireless/realtek/rtw88/rtw8822bu.h
> new file mode 100644
> index 0000000000000..20f01ecd74415
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
> +/* Copyright(c) 2018-2019  Realtek Corporation
> + */
> +
> +#ifndef __RTW_8822BU_H_
> +#define __RTW_8822BU_H_
> +
> +/* USB Vendor/Product IDs */
> +#define RTW_USB_VENDOR_ID_REALTEK		0x0BDA

like others, move this to usb.h


--
Ping-Ke



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

* Re: [PATCH 10/10] rtw88: Add rtw8822cu chipset support
  2022-05-18  8:23 ` [PATCH 10/10] rtw88: Add rtw8822cu " Sascha Hauer
@ 2022-05-20  8:03   ` Pkshih
  2022-05-20  8:56     ` s.hauer
  0 siblings, 1 reply; 43+ messages in thread
From: Pkshih @ 2022-05-20  8:03 UTC (permalink / raw)
  To: s.hauer, linux-wireless
  Cc: johannes, kernel, neojou, kvalo, tony0620emma, linux-kernel,
	martin.blumenstingl, linux, netdev

On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> 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>
> ---
>  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    | 40 +++++++++++++++++++
>  .../net/wireless/realtek/rtw88/rtw8822cu.h    | 15 +++++++
>  5 files changed, 93 insertions(+)
>  create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cu.c
>  create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cu.h
> 
> 

[...]

> +MODULE_AUTHOR("Realtek Corporation");

Out of curiosity, there are many authors in your patchset.
Do you collect these driver from various places?

rtw8723du.c:MODULE_AUTHOR("Hans Ulli Kroll <linux@ulli-kroll.de>");
rtw8821cu.c:MODULE_AUTHOR("Hans Ulli Kroll <linux@ulli-kroll.de>");
rtw8822bu.c:MODULE_AUTHOR("Realtek Corporation");
rtw8822cu.c:MODULE_AUTHOR("Realtek Corporation");
usb.c: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..16afe22a8216c
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8822cu.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
> +/* Copyright(c) 2018-2019  Realtek Corporation
> + */
> +
> +#ifndef __RTW_8822CU_H_
> +#define __RTW_8822CU_H_
> +
> +/* USB Vendor/Product IDs */
> +#define RTW_USB_VENDOR_ID_REALTEK		0x0BDA

Like others, move this to usb.h

> +#define RTW_USB_PRODUCT_ID_REALTEK_8812C	0xC812
> +#define RTW_USB_PRODUCT_ID_REALTEK_8822C	0xC82C
> +
> +extern struct rtw_chip_info rtw8822c_hw_spec;
> +
> +#endif


--
Ping-Ke



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

* Re: [PATCH 07/10] rtw88: Add rtw8723du chipset support
  2022-05-20  7:47   ` Pkshih
@ 2022-05-20  8:16     ` s.hauer
  0 siblings, 0 replies; 43+ messages in thread
From: s.hauer @ 2022-05-20  8:16 UTC (permalink / raw)
  To: Pkshih
  Cc: linux-wireless, linux, martin.blumenstingl, netdev, kvalo,
	linux-kernel, tony0620emma, neojou, kernel, johannes

On Fri, May 20, 2022 at 07:47:44AM +0000, Pkshih wrote:
> On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> > 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>
> > ---
> >  drivers/net/wireless/realtek/rtw88/Kconfig    | 11 +++++
> >  drivers/net/wireless/realtek/rtw88/Makefile   |  3 ++
> >  drivers/net/wireless/realtek/rtw88/rtw8723d.c | 19 +++++++++
> >  drivers/net/wireless/realtek/rtw88/rtw8723d.h |  1 +
> >  .../net/wireless/realtek/rtw88/rtw8723du.c    | 40 +++++++++++++++++++
> >  .../net/wireless/realtek/rtw88/rtw8723du.h    | 13 ++++++
> >  6 files changed, 87 insertions(+)
> >  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/rtw8723du.c
> > b/drivers/net/wireless/realtek/rtw88/rtw8723du.c
> > new file mode 100644
> > index 0000000000000..910f64c168131
> > --- /dev/null
> > +++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.c
> > @@ -0,0 +1,40 @@
> > +// 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[] = {
> > +	/*
> > +	 * ULLI :
> > +	 * ID found in rtw8822bu sources
> > +	 */
> 
> checkpatch.pl will tell us this comment block should be
> 
> /* ULLI :
>  * ID found in rtw8822bu sources
>  */
> 
> But, I think we can just "/* ULLI: ID found in rtw8822bu sources */" 
> if we really want to keep this comment.

I'll drop this comment.

> > +
> > +#ifndef __RTW_8723DU_H_
> > +#define __RTW_8723DU_H_
> > +
> > +/* USB Vendor/Product IDs */
> > +#define RTW_USB_VENDOR_ID_REALTEK		0x0BDA
> 
> rtw8821cu.h and rtw8822bu.h define this too.
> Can we move it to usb.h?

Yes.

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] 43+ messages in thread

* Re: [PATCH 06/10] rtw88: Add common USB chip support
  2022-05-20  7:39   ` Pkshih
@ 2022-05-20  8:51     ` s.hauer
  2022-05-20  9:23       ` Pkshih
  0 siblings, 1 reply; 43+ messages in thread
From: s.hauer @ 2022-05-20  8:51 UTC (permalink / raw)
  To: Pkshih
  Cc: linux-wireless, johannes, kernel, neojou, kvalo, tony0620emma,
	linux-kernel, martin.blumenstingl, linux, netdev, neo_jou

On Fri, May 20, 2022 at 07:39:03AM +0000, Pkshih wrote:
> On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> > 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>
> > ---
> >  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   |    5 +
> >  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    | 1051 +++++++++++++++++++
> >  drivers/net/wireless/realtek/rtw88/usb.h    |  109 ++
> >  9 files changed, 1209 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/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
> > index 84ba9ec489c37..a928899030863 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)                                                   \
> 				^^^^^^^ replace 8 spaces by one tab

This line is not added by me. There are spaces used before the
linebreaks throughout this file.

> > +	do {
> > +		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> > +
> > +		rxcb = list_first_entry_or_null(&rtwusb->rx_data_free,
> > +						struct rx_usb_ctrl_block, list);
> > +
> > +		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
> > +		if (!rxcb)
> > +			return;
> > +
> > +		rxcb->rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_KERNEL);
> > +		if (!rxcb->rx_skb) {
> > +			rtw_err(rtwdev, "could not allocate rx skbuff\n");
> > +			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);
> > +
> > +		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> > +		list_move(&rxcb->list, &rtwusb->rx_data_used);
> > +		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
> > +
> > +		error = usb_submit_urb(rxcb->rx_urb, GFP_KERNEL);
> > +		if (error) {
> > +			kfree_skb(rxcb->rx_skb);
> > +			if (error != -ENODEV)
> > +				rtw_err(rtwdev, "Err sending rx data urb %d\n",
> > +					   error);
> > +			rtw_usb_rx_data_put(rtwusb, rxcb);
> > +
> > +			return;
> > +		}
> > +	} while (true);
> 
> Can we have a limit of 'for(;<limit;)' insetad of 'while (true)'?

Not sure if it's worth it, but yes, it shouldn't hurt either.

> 
> > +}
> > +
> > +static void rtw_usb_cancel_rx_bufs(struct rtw_usb *rtwusb)
> > +{
> > +	struct rx_usb_ctrl_block *rxcb;
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> > +
> > +	while (true) {
> > +		rxcb = list_first_entry_or_null(&rtwusb->rx_data_used,
> > +						struct rx_usb_ctrl_block, list);
> > +
> > +		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
> > +
> > +		if (!rxcb)
> > +			break;
> > +
> > +		usb_kill_urb(rxcb->rx_urb);
> > +
> > +		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> > +		list_move(&rxcb->list, &rtwusb->rx_data_free);
> > +	}
> > +}
> 
> The spin_lock pairs are not intuitive.
> Can we change this chunk to
> 
> while (true) {
>      spin_lock();
>      rxcb = list_first_entry_or_null();
>      spin_unlock()
> 
>      if (!rxcb)
>         return;
> 
>      usb_free_urb();
> 
>      spin_lock();
>      list_del();
>      spin_unlock();
> }
> 
> The drawback is lock/unlock twice in single loop.

Yes, that's why I did it the way I did ;)

How about:

	while (true) {
		unsigned long flags;

		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);

		rxcb = list_first_entry_or_null(&rtwusb->rx_data_free,
						struct rx_usb_ctrl_block, list);
		if (rxcb)
			list_del(&rxcb->list);

		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);

		if (!rxcb)
			break;

		usb_free_urb(rxcb->rx_urb);
	}

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] 43+ messages in thread

* Re: [PATCH 10/10] rtw88: Add rtw8822cu chipset support
  2022-05-20  8:03   ` Pkshih
@ 2022-05-20  8:56     ` s.hauer
  0 siblings, 0 replies; 43+ messages in thread
From: s.hauer @ 2022-05-20  8:56 UTC (permalink / raw)
  To: Pkshih
  Cc: linux-wireless, linux, martin.blumenstingl, netdev, kvalo,
	linux-kernel, tony0620emma, neojou, kernel, johannes

On Fri, May 20, 2022 at 08:03:30AM +0000, Pkshih wrote:
> On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> > 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>
> > ---
> >  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    | 40 +++++++++++++++++++
> >  .../net/wireless/realtek/rtw88/rtw8822cu.h    | 15 +++++++
> >  5 files changed, 93 insertions(+)
> >  create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cu.c
> >  create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cu.h
> > 
> > 
> 
> [...]
> 
> > +MODULE_AUTHOR("Realtek Corporation");
> 
> Out of curiosity, there are many authors in your patchset.
> Do you collect these driver from various places?

No, the driver is completely based on
https://github.com/ulli-kroll/rtw88-usb.git

> 
> rtw8723du.c:MODULE_AUTHOR("Hans Ulli Kroll <linux@ulli-kroll.de>");
> rtw8821cu.c:MODULE_AUTHOR("Hans Ulli Kroll <linux@ulli-kroll.de>");
> rtw8822bu.c:MODULE_AUTHOR("Realtek Corporation");
> rtw8822cu.c:MODULE_AUTHOR("Realtek Corporation");
> usb.c:MODULE_AUTHOR("Realtek Corporation");

The driver is originally from Neo Jou (at least that's what the git log
tells me). The rtw8723du and rtw8821cu support was added later by Ulli
Kroll.

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] 43+ messages in thread

* Re: [PATCH 06/10] rtw88: Add common USB chip support
  2022-05-20  8:51     ` s.hauer
@ 2022-05-20  9:23       ` Pkshih
  0 siblings, 0 replies; 43+ messages in thread
From: Pkshih @ 2022-05-20  9:23 UTC (permalink / raw)
  To: s.hauer
  Cc: johannes, kernel, neojou, kvalo, tony0620emma, linux-wireless,
	martin.blumenstingl, linux-kernel, netdev, linux, neo_jou

On Fri, 2022-05-20 at 10:51 +0200, s.hauer@pengutronix.de wrote:
> On Fri, May 20, 2022 at 07:39:03AM +0000, Pkshih wrote:
> > On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> > > 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>
> > > ---
> > >  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   |    5 +
> > >  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    | 1051 +++++++++++++++++++
> > >  drivers/net/wireless/realtek/rtw88/usb.h    |  109 ++
> > >  9 files changed, 1209 insertions(+)
> > >  create mode 100644 drivers/net/wireless/realtek/rtw88/usb.c
> > >  create mode 100644 drivers/net/wireless/realtek/rtw88/usb.h
> > > 
> > 
> > > +}
> > > +
> > > +static void rtw_usb_cancel_rx_bufs(struct rtw_usb *rtwusb)
> > > +{
> > > +	struct rx_usb_ctrl_block *rxcb;
> > > +	unsigned long flags;
> > > +
> > > +	spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> > > +
> > > +	while (true) {
> > > +		rxcb = list_first_entry_or_null(&rtwusb->rx_data_used,
> > > +						struct rx_usb_ctrl_block, list);
> > > +
> > > +		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
> > > +
> > > +		if (!rxcb)
> > > +			break;
> > > +
> > > +		usb_kill_urb(rxcb->rx_urb);
> > > +
> > > +		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> > > +		list_move(&rxcb->list, &rtwusb->rx_data_free);
> > > +	}
> > > +}
> > 
> > The spin_lock pairs are not intuitive.
> > Can we change this chunk to
> > 
> > while (true) {
> >      spin_lock();
> >      rxcb = list_first_entry_or_null();
> >      spin_unlock()
> > 
> >      if (!rxcb)
> >         return;
> > 
> >      usb_free_urb();
> > 
> >      spin_lock();
> >      list_del();
> >      spin_unlock();
> > }
> > 
> > The drawback is lock/unlock twice in single loop.
> 
> Yes, that's why I did it the way I did ;)
> 
> How about:
> 
> 	while (true) {
> 		unsigned long flags;
> 
> 		spin_lock_irqsave(&rtwusb->rx_data_list_lock, flags);
> 
> 		rxcb = list_first_entry_or_null(&rtwusb->rx_data_free,
> 						struct rx_usb_ctrl_block, list);
> 		if (rxcb)
> 			list_del(&rxcb->list);
> 
> 		spin_unlock_irqrestore(&rtwusb->rx_data_list_lock, flags);
> 
> 		if (!rxcb)
> 			break;
> 
> 		usb_free_urb(rxcb->rx_urb);
> 	}
> 

With the new one, I can easily check spin_lock/_unlock is paired, so
I vote it.

--
Ping-Ke



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

* Re: [PATCH 05/10] rtw88: Do not access registers while atomic
  2022-05-18  8:23 ` [PATCH 05/10] rtw88: Do not access registers while atomic Sascha Hauer
  2022-05-20  6:06   ` Pkshih
@ 2022-05-20 17:32   ` Larry Finger
  1 sibling, 0 replies; 43+ messages in thread
From: Larry Finger @ 2022-05-20 17:32 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg

On 5/18/22 03:23, Sascha Hauer wrote:
> 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>
> ---
>   drivers/net/wireless/realtek/rtw88/phy.c  |  6 +-
>   drivers/net/wireless/realtek/rtw88/ps.c   |  2 +-
>   drivers/net/wireless/realtek/rtw88/util.c | 92 +++++++++++++++++++++++
>   drivers/net/wireless/realtek/rtw88/util.h | 12 ++-
>   4 files changed, 105 insertions(+), 7 deletions(-)
> 

...

> diff --git a/drivers/net/wireless/realtek/rtw88/util.c b/drivers/net/wireless/realtek/rtw88/util.c
> index 2c515af214e76..db55dbd5c533e 100644
> --- a/drivers/net/wireless/realtek/rtw88/util.c
> +++ b/drivers/net/wireless/realtek/rtw88/util.c
> @@ -105,3 +105,95 @@ 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;
> +};
> +
> +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;
> +
> +	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;
> +};
> +
> +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;
> +
> +	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);
> +	}
> +}

Sasha,

Sparse shows the following warnings:

   CHECK   /home/finger/iwireless-next/drivers/net/wireless/realtek/rtw88/util.c
/home/finger/wireless-next/drivers/net/wireless/realtek/rtw88/util.c:119:6: 
warning: symbol 'rtw_collect_sta_iter' was not declared. Should it be static?
/home/finger/wireless-next/drivers/net/wireless/realtek/rtw88/util.c:165:6: 
warning: symbol 'rtw_collect_vif_iter' was not declared. Should it be static?

Larry

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

* Re: [PATCH 06/10] rtw88: Add common USB chip support
  2022-05-18  8:23 ` [PATCH 06/10] rtw88: Add common USB chip support Sascha Hauer
  2022-05-18  8:32   ` Sascha Hauer
  2022-05-20  7:39   ` Pkshih
@ 2022-05-20 18:33   ` Larry Finger
  2022-05-23  4:07   ` Hans Ulli Kroll
  3 siblings, 0 replies; 43+ messages in thread
From: Larry Finger @ 2022-05-20 18:33 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg, neo_jou

On 5/18/22 03:23, Sascha Hauer wrote:
> 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>
> ---
>   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   |    5 +
>   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    | 1051 +++++++++++++++++++
>   drivers/net/wireless/realtek/rtw88/usb.h    |  109 ++
>   9 files changed, 1209 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 d1678aed9d9cb..19728c705eaa9 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 5afb8bef9696a..162fa432ce0d1 100644
> --- a/drivers/net/wireless/realtek/rtw88/main.c
> +++ b/drivers/net/wireless/realtek/rtw88/main.c
> @@ -1715,6 +1715,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;
> @@ -2105,6 +2109,7 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
>   	hw->wiphy->available_antennas_rx = hal->antenna_rx;
>   
>   	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
> +			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
>   			    WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
>   
>   	hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
> diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
> index fc27066a67a72..007da6df088a3 100644
> --- a/drivers/net/wireless/realtek/rtw88/main.h
> +++ b/drivers/net/wireless/realtek/rtw88/main.h
> @@ -876,6 +876,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 84ba9ec489c37..a928899030863 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 56371eff9f7ff..c02d7a15895c6 100644
> --- a/drivers/net/wireless/realtek/rtw88/tx.h
> +++ b/drivers/net/wireless/realtek/rtw88/tx.h
> @@ -67,6 +67,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,
> @@ -119,4 +127,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)
> +{
> +	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..7641ea6f6ad1a
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/usb.c
> @@ -0,0 +1,1051 @@
> +// 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 void usbctrl_async_callback(struct urb *urb)
> +{
> +	/* free dr */
> +	kfree(urb->setup_packet);
> +	/* free databuf */
> +	kfree(urb->transfer_buffer);
> +}
> +
> +static int usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
> +					  u16 value, u16 index, void *pdata,
> +					  u16 len)
> +{
> +	int rc;
> +	unsigned int pipe;
> +	u8 reqtype;
> +	struct usb_ctrlrequest *dr;
> +	struct urb *urb;
> +	const u16 databuf_maxlen = RTW_USB_VENQT_MAX_BUF_SIZE;
> +	u8 *databuf;
> +
> +	if (WARN_ON_ONCE(len > databuf_maxlen))
> +		len = databuf_maxlen;
> +
> +	pipe = usb_sndctrlpipe(udev, 0); /* write_out */
> +	reqtype = RTW_USB_CMD_WRITE;
> +
> +	dr = kzalloc(sizeof(*dr), GFP_ATOMIC);
> +	if (!dr)
> +		return -ENOMEM;
> +
> +	databuf = kmemdup(pdata, len, GFP_ATOMIC);
> +	if (!databuf) {
> +		kfree(dr);
> +		return -ENOMEM;
> +	}
> +
> +	urb = usb_alloc_urb(0, GFP_ATOMIC);
> +	if (!urb) {
> +		kfree(databuf);
> +		kfree(dr);
> +		return -ENOMEM;
> +	}
> +
> +	dr->bRequestType = reqtype;
> +	dr->bRequest = request;
> +	dr->wValue = cpu_to_le16(value);
> +	dr->wIndex = cpu_to_le16(index);
> +	dr->wLength = cpu_to_le16(len);
> +
> +	usb_fill_control_urb(urb, udev, pipe,
> +			     (unsigned char *)dr, databuf, len,
> +			     usbctrl_async_callback, NULL);
> +	rc = usb_submit_urb(urb, GFP_ATOMIC);
> +	if (rc < 0) {
> +		kfree(databuf);
> +		kfree(dr);
> +	}
> +
> +	usb_free_urb(urb);
> +
> +	return rc;
> +}
> +
> +static u32 rtw_usb_read_sync(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);
> +
> +	if (++rtwusb->usb_data_index >= RTW_USB_MAX_RX_COUNT)
> +		rtwusb->usb_data_index = 0;
> +	data = &rtwusb->usb_data[rtwusb->usb_data_index];
> +
> +	spin_unlock_irqrestore(&rtwusb->usb_lock, flags);
> +
> +	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, "reg 0x%x, usbctrl_vendorreq failed with %d\n",
> +			addr, ret);
> +
> +	return le32_to_cpu(*data);
> +}
> +
> +static u8 rtw_usb_read8_sync(struct rtw_dev *rtwdev, u32 addr)
> +{
> +	return (u8)rtw_usb_read_sync(rtwdev, addr, 1);
> +}
> +
> +static u16 rtw_usb_read16_sync(struct rtw_dev *rtwdev, u32 addr)
> +{
> +	return (u16)rtw_usb_read_sync(rtwdev, addr, 2);
> +}
> +
> +static u32 rtw_usb_read32_sync(struct rtw_dev *rtwdev, u32 addr)
> +{
> +	return (u32)rtw_usb_read_sync(rtwdev, addr, 4);
> +}
> +
> +static void rtw_usb_write_async(struct rtw_dev *rtwdev, u32 addr, u32 val,
> +				u16 len)
> +{
> +	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
> +	struct usb_device *udev = rtwusb->udev;
> +	u8 request;
> +	u16 wvalue;
> +	u16 index;
> +	__le32 data;
> +
> +	request = RTW_USB_CMD_REQ;
> +	index = RTW_USB_VENQT_CMD_IDX; /* n/a */
> +	wvalue = (u16)(addr & 0x0000ffff);
> +	data = cpu_to_le32(val);
> +	usbctrl_vendorreq_async_write(udev, request, wvalue, index, &data, len);
> +}
> +
> +static void rtw_usb_write8_async(struct rtw_dev *rtwdev, u32 addr, u8 val)
> +{
> +	rtw_usb_write_async(rtwdev, addr, val, 1);
> +}
> +
> +static void rtw_usb_write16_async(struct rtw_dev *rtwdev, u32 addr, u16 val)
> +{
> +	rtw_usb_write_async(rtwdev, addr, val, 2);
> +}
> +
> +static void rtw_usb_write32_async(struct rtw_dev *rtwdev, u32 addr, u32 val)
> +{
> +	rtw_usb_write_async(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] = 1;
> +		rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = 1;
> +		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_txcb_enqueue(struct rtw_usb_txcb *txcb, struct sk_buff *skb)
> +{
> +	skb_queue_tail(&txcb->tx_ack_queue, skb);
> +}
> +
> +static void rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list,
> +			       struct sk_buff *skb_head, struct sk_buff *skb,
> +			       struct rtw_usb_txcb *txcb)
> +{
> +	struct sk_buff *skb_iter;
> +	unsigned long flags;
> +	u8 *data_ptr;
> +	int agg_num = 0, len, max_len;
> +
> +	data_ptr = skb_head->data;
> +	skb_iter = skb;
> +
> +	while (skb_iter) {
> +		memcpy(data_ptr, skb_iter->data, skb_iter->len);
> +		len = ALIGN(skb_iter->len, 8);
> +		skb_put(skb_head, len);
> +		data_ptr += len;
> +		agg_num++;
> +
> +		rtw_usb_txcb_enqueue(txcb, skb_iter);
> +
> +		spin_lock_irqsave(&list->lock, flags);
> +
> +		skb_iter = skb_peek(list);
> +		max_len = RTW_USB_MAX_XMITBUF_SZ - skb_head->len;
> +
> +		if (skb_iter && skb_iter->len < max_len)
> +			__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);
> +}
> +
> +static void rtw_usb_indicate_tx_status(struct rtw_dev *rtwdev,
> +				       struct sk_buff *skb)
> +{
> +	struct ieee80211_hw *hw = rtwdev->hw;
> +	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
> +	struct rtw_usb_tx_data *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);
> +		return;
> +	}
> +
> +	/* 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);
> +}
> +
> +static void rtw_usb_write_port_tx_complete(struct urb *urb)
> +{
> +	struct rtw_usb_txcb *txcb = urb->context;
> +	struct rtw_dev *rtwdev = txcb->rtwdev;
> +
> +	while (true) {
> +		struct sk_buff *skb = skb_dequeue(&txcb->tx_ack_queue);
> +		if (!skb)
> +			break;
> +
> +		if (GET_TX_DESC_QSEL(skb->data) <= TX_DESC_QSEL_TID7)
> +			rtw_usb_indicate_tx_status(rtwdev, skb);
> +		else
> +			dev_kfree_skb_any(skb);
> +	}
> +
> +	kfree(txcb);
> +}
> +
> +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 = rtwusb->qsel_to_ep[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 struct sk_buff *rtw_usb_tx_agg_check(struct rtw_usb *rtwusb,
> +					    struct sk_buff *skb,
> +					    int index,
> +					    struct rtw_usb_txcb *txcb)
> +{
> +	struct sk_buff_head *list;
> +	struct sk_buff *skb_head;
> +
> +	list = &rtwusb->tx_queue[index];
> +	if (skb_queue_empty(list))
> +		return NULL;
> +
> +	skb_head = dev_alloc_skb(RTW_USB_MAX_XMITBUF_SZ);
> +	if (!skb_head)
> +		return NULL;
> +
> +	rtw_usb_tx_agg_skb(rtwusb, list, skb_head, skb, txcb);
> +
> +	return skb_head;
> +}
> +
> +static void rtw_usb_tx_agg(struct rtw_usb *rtwusb, struct sk_buff *skb, int index)
> +{
> +	struct rtw_dev *rtwdev = rtwusb->rtwdev;
> +	struct sk_buff *skb_head;
> +	struct rtw_usb_txcb *txcb;
> +	u8 qsel;
> +
> +	txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC);
> +	if (!txcb)
> +		return;
> +
> +	txcb->rtwdev = rtwdev;
> +	skb_queue_head_init(&txcb->tx_ack_queue);
> +
> +	skb_head = rtw_usb_tx_agg_check(rtwusb, skb, index, txcb);
> +	if (!skb_head) {
> +		skb_head = skb;
> +		rtw_usb_txcb_enqueue(txcb, skb);
> +	}
> +
> +	qsel = GET_TX_DESC_QSEL(skb->data);
> +
> +	rtw_usb_write_port(rtwdev, qsel, skb_head,
> +			   rtw_usb_write_port_tx_complete, txcb);
> +
> +	if (skb_head != skb)
> +		dev_kfree_skb(skb_head);
> +}
> +
> +static void rtw_usb_tx_handler(struct work_struct *work)
> +{
> +	struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, tx_work);
> +	struct sk_buff *skb;
> +	int index, limit;
> +
> +	for (index = ARRAY_SIZE(rtwusb->tx_queue) - 1; index >= 0; index--) {
> +		for (limit = 0; limit < 200; limit++) {
> +			skb = skb_dequeue(&rtwusb->tx_queue[index]);
> +			if (skb)
> +				rtw_usb_tx_agg(rtwusb, skb, index);
> +			else
> +				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)
> +{
> +	struct rtw_chip_info *chip = rtwdev->chip;
> +	struct sk_buff *skb;
> +	unsigned int desclen, headsize, size;
> +	u8 qsel;
> +	int ret = 0;
> +
> +	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)
> +{
> +	struct rtw_chip_info *chip = rtwdev->chip;
> +	struct rtw_usb *rtwusb;
> +	struct rtw_tx_pkt_info pkt_info = {0};
> +	u32 len, desclen;
> +
> +	if (unlikely(!rtwdev))
> +		return -EINVAL;

You check rtwdev after you dereference it to get the chip info. I think the test 
can be dropped. If rtwdev is NULL, a lot of things will have brohen earlier.

Larry

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

* Re: [PATCH 00/10] RTW88: Add support for USB variants
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
                   ` (9 preceding siblings ...)
  2022-05-18  8:23 ` [PATCH 10/10] rtw88: Add rtw8822cu " Sascha Hauer
@ 2022-05-23  4:07 ` Hans Ulli Kroll
  2022-05-23  6:53   ` Sascha Hauer
  2022-05-23 10:13   ` Sascha Hauer
  2022-05-30  9:25 ` Kalle Valo
  11 siblings, 2 replies; 43+ messages in thread
From: Hans Ulli Kroll @ 2022-05-23  4:07 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Ping-Ke Shih, Yan-Hsuan Chuang, Kalle Valo, netdev,
	linux-kernel, Martin Blumenstingl, kernel, Johannes Berg

On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> This series adds support for the USB chip variants to the RTW88 driver.
> 

Hi Sascha

glad you found some *working* devices for rtw88 !

I spend some of the weekend testing your driver submission.

for rtl8821cu devices I get following output

some Logilink device

[ 1686.605567] usb 1-5.1.2: New USB device found, idVendor=0bda, idProduct=c811, bcdDevice=
2.00
[ 1686.614186] usb 1-5.1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 1686.621721] usb 1-5.1.2: Product: 802.11ac NIC
[ 1686.626227] usb 1-5.1.2: Manufacturer: Realtek
[ 1686.630695] usb 1-5.1.2: SerialNumber: 123456
[ 1686.640480] rtw_8821cu 1-5.1.2:1.0: Firmware version 24.5.0, H2C version 12
[ 1686.932828] rtw_8821cu 1-5.1.2:1.0: failed to download firmware
[ 1686.945206] rtw_8821cu 1-5.1.2:1.0: failed to setup chip efuse info
[ 1686.951538] rtw_8821cu 1-5.1.2:1.0: failed to setup chip information
[ 1686.958402] rtw_8821cu: probe of 1-5.1.2:1.0 failed with error -22

above is same with some from Comfast

The worst in the list is one from EDUP

[ 1817.855704] rtw_8821cu 1-5.1.2:1.2: Firmware version 24.5.0, H2C version 12
[ 1818.153918] rtw_8821cu 1-5.1.2:1.2: rfe 255 isn't supported
[ 1818.165176] rtw_8821cu 1-5.1.2:1.2: failed to setup chip efuse info
[ 1818.171505] rtw_8821cu 1-5.1.2:1.2: failed to setup chip information

rtl8822bu devices are working fine ...

Hans Ulli

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

* Re: [PATCH 06/10] rtw88: Add common USB chip support
  2022-05-18  8:23 ` [PATCH 06/10] rtw88: Add common USB chip support Sascha Hauer
                     ` (2 preceding siblings ...)
  2022-05-20 18:33   ` Larry Finger
@ 2022-05-23  4:07   ` Hans Ulli Kroll
  3 siblings, 0 replies; 43+ messages in thread
From: Hans Ulli Kroll @ 2022-05-23  4:07 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Ping-Ke Shih, Yan-Hsuan Chuang, Kalle Valo, netdev,
	linux-kernel, Martin Blumenstingl, kernel, Johannes Berg,
	neo_jou

On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> 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.
> 

Neo Jou borrowed the usb logic from rtlwifi.
This was (maybe) also in the early stages of the vendor driver.

Newer ones doesn't use async write for register access.

In short it looks like this.
The extra "time consume" is added between v5.2.4 and v5.3.1

static int __rtw_usb_vendor_request(struct usb_device *udev, unsigned int pipe,
				    u8 request, u8 requesttype, u16 val, u16 index,
				    void *buf, size_t len)
{
	int i, ret;

	for (i = 0; i < MAX_USBCTRL_VENDORREQ_TIMES; i++) {
		ret = usb_control_msg(udev, pipe, request, requesttype, val,
				      index, buf, len, RTW_USBCTRL_MSG_TIMEOUT);

		if (ret <= 0)
			return ret;
	}

	if (val <= 0xff ||
	    (val >= 0x1000 && val <= 0x10ff)) {
		/* add a write to consume time on device */

		unsigned int t_pipe = usb_sndctrlpipe(udev, 0);/* write_out */
		u8 t_reqtype =  RTW_USB_CMD_WRITE;
		u8 t_len = 1;
		u8 t_req = RTW_USB_CMD_REQ;
		u16 t_reg = 0x4e0;	/* unknown reg on device */
		u16 t_index = 0;

		ret = usb_control_msg(udev, t_pipe, t_req, t_reqtype,
				      t_reg, t_index, buf, t_len,
				      RTW_USBCTRL_MSG_TIMEOUT);

		if (ret != 1)
			return ret;
	}


	return ret;
}

static int rtw_vendor_request(struct rtw_usb *rtwusb, unsigned int pipe,
			      u8 request, u8 requesttype, u16 val, u16 index,
			      void *buf, size_t len)
{
	struct usb_device *udev = rtwusb->udev;
	int ret;

	mutex_lock(&rtwusb->usb_ctrl_mtx);
	ret = __rtw_usb_vendor_request(udev, pipe, request, requesttype,
				       val, index, buf, len);
	mutex_unlock(&rtwusb->usb_ctrl_mtx);

	return ret;
}


Hans Ulli

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

* Re: [PATCH 00/10] RTW88: Add support for USB variants
  2022-05-23  4:07 ` [PATCH 00/10] RTW88: Add support for USB variants Hans Ulli Kroll
@ 2022-05-23  6:53   ` Sascha Hauer
  2022-05-23 11:39     ` Ping-Ke Shih
  2022-05-23 10:13   ` Sascha Hauer
  1 sibling, 1 reply; 43+ messages in thread
From: Sascha Hauer @ 2022-05-23  6:53 UTC (permalink / raw)
  To: Hans Ulli Kroll
  Cc: linux-wireless, Neo Jou, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg

Hi Hans Ulli,

On Mon, May 23, 2022 at 06:07:16AM +0200, Hans Ulli Kroll wrote:
> On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> > This series adds support for the USB chip variants to the RTW88 driver.
> > 
> 
> Hi Sascha
> 
> glad you found some *working* devices for rtw88 !

Well, not fully. I had to add [3] = RTW_DEF_RFE(8822c, 0, 0), to the
rtw8822c_rfe_defs array.

> 
> I spend some of the weekend testing your driver submission.
> 
> for rtl8821cu devices I get following output
> 
> some Logilink device
> 
> [ 1686.605567] usb 1-5.1.2: New USB device found, idVendor=0bda, idProduct=c811, bcdDevice=
> 2.00
> [ 1686.614186] usb 1-5.1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
> [ 1686.621721] usb 1-5.1.2: Product: 802.11ac NIC
> [ 1686.626227] usb 1-5.1.2: Manufacturer: Realtek
> [ 1686.630695] usb 1-5.1.2: SerialNumber: 123456
> [ 1686.640480] rtw_8821cu 1-5.1.2:1.0: Firmware version 24.5.0, H2C version 12
> [ 1686.932828] rtw_8821cu 1-5.1.2:1.0: failed to download firmware
> [ 1686.945206] rtw_8821cu 1-5.1.2:1.0: failed to setup chip efuse info
> [ 1686.951538] rtw_8821cu 1-5.1.2:1.0: failed to setup chip information
> [ 1686.958402] rtw_8821cu: probe of 1-5.1.2:1.0 failed with error -22
> 
> above is same with some from Comfast
> 
> The worst in the list is one from EDUP
> 
> [ 1817.855704] rtw_8821cu 1-5.1.2:1.2: Firmware version 24.5.0, H2C version 12
> [ 1818.153918] rtw_8821cu 1-5.1.2:1.2: rfe 255 isn't supported
> [ 1818.165176] rtw_8821cu 1-5.1.2:1.2: failed to setup chip efuse info
> [ 1818.171505] rtw_8821cu 1-5.1.2:1.2: failed to setup chip information

Do these chips work with your out of tree variant of this driver?

Is the efuse info completely 0xff or only the field indicating the rfe
option?

> 
> rtl8822bu devices are working fine ...

Nice. Did you test a rtw8723du device as well?

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] 43+ messages in thread

* Re: [PATCH 00/10] RTW88: Add support for USB variants
  2022-05-23  4:07 ` [PATCH 00/10] RTW88: Add support for USB variants Hans Ulli Kroll
  2022-05-23  6:53   ` Sascha Hauer
@ 2022-05-23 10:13   ` Sascha Hauer
  1 sibling, 0 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-23 10:13 UTC (permalink / raw)
  To: Hans Ulli Kroll
  Cc: linux-wireless, Neo Jou, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg

On Mon, May 23, 2022 at 06:07:16AM +0200, Hans Ulli Kroll wrote:
> On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> > This series adds support for the USB chip variants to the RTW88 driver.
> > 
> 
> Hi Sascha
> 
> glad you found some *working* devices for rtw88 !
> 
> I spend some of the weekend testing your driver submission.
> 
> for rtl8821cu devices I get following output
> 
> some Logilink device
> 
> [ 1686.605567] usb 1-5.1.2: New USB device found, idVendor=0bda, idProduct=c811, bcdDevice=
> 2.00

Most devices in the driver are described as:

	USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc82c, 0xff, 0xff, 0xff),

This particular one has:

	USB_DEVICE(0x0bda, 0xc811),

When I use USB_DEVICE() instead of USB_DEVICE_AND_INTERFACE_INFO() on my
device then the Wifi driver tries to bind to the bluetooth interface on
the same device which then fails with similar error messages. Maybe you
have to use

	USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc811, 0xff, 0xff, 0xff)

instead. I could imagine that the plain USB_DEVICE() once worked for you
because the bluetooth driver was faster to probe and only left the Wifi
interface free for the Wifi driver to probe.

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] 43+ messages in thread

* Re: [PATCH 00/10] RTW88: Add support for USB variants
  2022-05-23  6:53   ` Sascha Hauer
@ 2022-05-23 11:39     ` Ping-Ke Shih
  2022-05-24  6:54       ` s.hauer
  0 siblings, 1 reply; 43+ messages in thread
From: Ping-Ke Shih @ 2022-05-23 11:39 UTC (permalink / raw)
  To: s.hauer, linux
  Cc: johannes, kernel, neojou, kvalo, tony0620emma, linux-wireless,
	martin.blumenstingl, linux-kernel, netdev

On Mon, 2022-05-23 at 08:53 +0200, Sascha Hauer wrote:
> Hi Hans Ulli,
> 
> On Mon, May 23, 2022 at 06:07:16AM +0200, Hans Ulli Kroll wrote:
> > On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> > > This series adds support for the USB chip variants to the RTW88 driver.
> > > 
> > 
> > Hi Sascha
> > 
> > glad you found some *working* devices for rtw88 !
> 
> Well, not fully. I had to add [3] = RTW_DEF_RFE(8822c, 0, 0), to the
> rtw8822c_rfe_defs array.
> 
> > I spend some of the weekend testing your driver submission.
> > 
> > for rtl8821cu devices I get following output
> > 
> > some Logilink device
> > 
> > [ 1686.605567] usb 1-5.1.2: New USB device found, idVendor=0bda, idProduct=c811, bcdDevice=
> > 2.00
> > [ 1686.614186] usb 1-5.1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
> > [ 1686.621721] usb 1-5.1.2: Product: 802.11ac NIC
> > [ 1686.626227] usb 1-5.1.2: Manufacturer: Realtek
> > [ 1686.630695] usb 1-5.1.2: SerialNumber: 123456
> > [ 1686.640480] rtw_8821cu 1-5.1.2:1.0: Firmware version 24.5.0, H2C version 12
> > [ 1686.932828] rtw_8821cu 1-5.1.2:1.0: failed to download firmware
> > [ 1686.945206] rtw_8821cu 1-5.1.2:1.0: failed to setup chip efuse info
> > [ 1686.951538] rtw_8821cu 1-5.1.2:1.0: failed to setup chip information
> > [ 1686.958402] rtw_8821cu: probe of 1-5.1.2:1.0 failed with error -22
> > 
> > above is same with some from Comfast
> > 
> > The worst in the list is one from EDUP
> > 
> > [ 1817.855704] rtw_8821cu 1-5.1.2:1.2: Firmware version 24.5.0, H2C version 12
> > [ 1818.153918] rtw_8821cu 1-5.1.2:1.2: rfe 255 isn't supported
> > [ 1818.165176] rtw_8821cu 1-5.1.2:1.2: failed to setup chip efuse info
> > [ 1818.171505] rtw_8821cu 1-5.1.2:1.2: failed to setup chip information
> 
> Do these chips work with your out of tree variant of this driver?
> 
> Is the efuse info completely 0xff or only the field indicating the rfe
> option?

I check RFE allocation of 8821c. 255 isn't defined.
If efuse info isn't complete 0xff, try to force RFE 0 to see if it works.

> 
> > rtl8822bu devices are working fine ...
> 
> Nice. Did you test a rtw8723du device as well?
> 

I have a 8723DU module.

With this patchset, it can find AP, but can't estiablish connection.
I check air capture, but no TX packets found.
That says RX works, but TX doesn't.

With master branch of Hans Ulli GitHub, it shows many "atomic scheduling"
warnings when I insert the USB dongle.
When I do 'iw scan', it is going to get stuck, and I can only push
power button to turn off my laptop.

Ping-Ke



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

* Re: [PATCH 09/10] rtw88: Add rtw8822bu chipset support
  2022-05-18  8:23 ` [PATCH 09/10] rtw88: Add rtw8822bu " Sascha Hauer
  2022-05-20  7:58   ` Pkshih
@ 2022-05-23 11:56   ` Rin Cat (鈴猫)
  2022-05-23 12:34     ` Sascha Hauer
  1 sibling, 1 reply; 43+ messages in thread
From: Rin Cat (鈴猫) @ 2022-05-23 11:56 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg


[-- Attachment #1.1.1: Type: text/plain, Size: 8279 bytes --]

Hi, here are all current known vender rtw8822bu devices IDs from my maintained 
Realtek driver.
https://github.com/RinCat/RTL88x2BU-Linux-Driver/blob/master/os_dep/linux/usb_intf.c#L239=

ASUS vender ID 0x0B05:
0x1841 ASUS AC1300 USB-AC55 B1
0x184C ASUS U2
0x19AA ASUS USB-AC58

Edimax vender ID 0x7392:
0xB822 Edimax EW-7822ULC
0xC822 Edimax EW-7822UTC
0xF822 Edimax EW-7822UAD

Dlink vender ID 0x2001:
0x331E Dlink - DWA-181
0x331C Dlink - DWA-182
0x331F Dlink - DWA-183 Ver. D

NetGear vender ID 0x0846:
0x9055 NetGear A6150

TP-Link vender ID 0x2357:
0x012D TP-Link Archer T3U
0x0138 TP-Link Archer T3U Plus
0x0115 TP-Link Archer T4U V3

TRENDnet vender ID 0x20F4:
0x808A TRENDnet TEW-808UBM

Thanks.

Signed-off-by: Rin Cat (鈴猫) <dev@rincat.ch>

On 2022-05-18 04:23, Sascha Hauer wrote:
> 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>
> ---
>   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    | 62 +++++++++++++++++++
>   .../net/wireless/realtek/rtw88/rtw8822bu.h    | 15 +++++
>   5 files changed, 110 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 5b1bafccd3d4c..e4c60f1449ec8 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 5498e8bbcbf17..e4126ddf7d659 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 eee7bf0354030..10497d351f229 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..5becebdc32471
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.c
> @@ -0,0 +1,62 @@
> +// 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"
> +
> +#define RTW_USB_VENDER_ID_EDIMAX	0x7392
> +
> +static const struct usb_device_id rtw_8822bu_id_table[] = {
> +	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK,
> +				       RTW_USB_PRODUCT_ID_REALTEK_8812B,
> +				       0xff, 0xff, 0xff),
> +	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
> +	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK,
> +				       RTW_USB_PRODUCT_ID_REALTEK_8822B,
> +				       0xff, 0xff, 0xff),
> +	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
> +	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDER_ID_EDIMAX,
> +					0xB822,
> +					0xff, 0xff, 0xff),
> +	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
> +	{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDER_ID_EDIMAX,
> +					0xC822,
> +					0xff, 0xff, 0xff),
> +	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
> +	{ USB_DEVICE(0x0b05, 0x184c),	/* ASUS AC53 Nano */
> +	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
> +	{ USB_DEVICE(0x0b05, 0x1841),	/* ASUS AC55 B1 */
> +	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
> +	{ USB_DEVICE(0x2001, 0x331c),	/* D-Link DWA-182 rev D1 */
> +	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
> +	{ USB_DEVICE(0x13b1, 0x0043),	/* Linksys WUSB6400M */
> +	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
> +	{ USB_DEVICE(0x2357, 0x012D),	/* TP-Link AC1300 T3U */
> +	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
> +	{ USB_DEVICE(0x2357, 0x0138),	/* TP-Link AC1300 T3U */
> +	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
> +	{},
> +};
> +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..20f01ecd74415
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
> +/* Copyright(c) 2018-2019  Realtek Corporation
> + */
> +
> +#ifndef __RTW_8822BU_H_
> +#define __RTW_8822BU_H_
> +
> +/* USB Vendor/Product IDs */
> +#define RTW_USB_VENDOR_ID_REALTEK		0x0BDA
> +#define RTW_USB_PRODUCT_ID_REALTEK_8812B	0xB812
> +#define RTW_USB_PRODUCT_ID_REALTEK_8822B	0xB82C
> +
> +extern struct rtw_chip_info rtw8822b_hw_spec;
> +
> +#endif

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 1391 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]

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

* Re: [PATCH 09/10] rtw88: Add rtw8822bu chipset support
  2022-05-23 11:56   ` Rin Cat (鈴猫)
@ 2022-05-23 12:34     ` Sascha Hauer
  0 siblings, 0 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-23 12:34 UTC (permalink / raw)
  To: Rin Cat (鈴猫)
  Cc: linux-wireless, Neo Jou, Hans Ulli Kroll, Ping-Ke Shih,
	Yan-Hsuan Chuang, Kalle Valo, netdev, linux-kernel,
	Martin Blumenstingl, kernel, Johannes Berg

On Mon, May 23, 2022 at 07:56:14AM -0400, Rin Cat (鈴猫) wrote:
> Hi, here are all current known vender rtw8822bu devices IDs from my
> maintained Realtek driver.
> https://github.com/RinCat/RTL88x2BU-Linux-Driver/blob/master/os_dep/linux/usb_intf.c#L239=

Man, how many incarnations of this driver are there? It's really about time
to mainline it.

Modulo the IDs posted by Nick Morrow already only this one is missing:

	{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331f, 0xff, 0xff, 0xff),
	  .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec)}, /* Dlink - DWA-183 D Ver */

Will add it for the next round.

Thanks,
  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] 43+ messages in thread

* Re: [PATCH 00/10] RTW88: Add support for USB variants
  2022-05-23 11:39     ` Ping-Ke Shih
@ 2022-05-24  6:54       ` s.hauer
  0 siblings, 0 replies; 43+ messages in thread
From: s.hauer @ 2022-05-24  6:54 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: linux, johannes, kernel, neojou, kvalo, tony0620emma,
	linux-wireless, martin.blumenstingl, linux-kernel, netdev

On Mon, May 23, 2022 at 11:39:49AM +0000, Ping-Ke Shih wrote:
> On Mon, 2022-05-23 at 08:53 +0200, Sascha Hauer wrote:
> > Hi Hans Ulli,
> > 
> > On Mon, May 23, 2022 at 06:07:16AM +0200, Hans Ulli Kroll wrote:
> > > On Wed, 2022-05-18 at 10:23 +0200, Sascha Hauer wrote:
> > > > This series adds support for the USB chip variants to the RTW88 driver.
> > > > 
> > > 
> > > Hi Sascha
> > > 
> > > glad you found some *working* devices for rtw88 !
> > 
> > Well, not fully. I had to add [3] = RTW_DEF_RFE(8822c, 0, 0), to the
> > rtw8822c_rfe_defs array.
> > 
> > > I spend some of the weekend testing your driver submission.
> > > 
> > > for rtl8821cu devices I get following output
> > > 
> > > some Logilink device
> > > 
> > > [ 1686.605567] usb 1-5.1.2: New USB device found, idVendor=0bda, idProduct=c811, bcdDevice=
> > > 2.00
> > > [ 1686.614186] usb 1-5.1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
> > > [ 1686.621721] usb 1-5.1.2: Product: 802.11ac NIC
> > > [ 1686.626227] usb 1-5.1.2: Manufacturer: Realtek
> > > [ 1686.630695] usb 1-5.1.2: SerialNumber: 123456
> > > [ 1686.640480] rtw_8821cu 1-5.1.2:1.0: Firmware version 24.5.0, H2C version 12
> > > [ 1686.932828] rtw_8821cu 1-5.1.2:1.0: failed to download firmware
> > > [ 1686.945206] rtw_8821cu 1-5.1.2:1.0: failed to setup chip efuse info
> > > [ 1686.951538] rtw_8821cu 1-5.1.2:1.0: failed to setup chip information
> > > [ 1686.958402] rtw_8821cu: probe of 1-5.1.2:1.0 failed with error -22
> > > 
> > > above is same with some from Comfast
> > > 
> > > The worst in the list is one from EDUP
> > > 
> > > [ 1817.855704] rtw_8821cu 1-5.1.2:1.2: Firmware version 24.5.0, H2C version 12
> > > [ 1818.153918] rtw_8821cu 1-5.1.2:1.2: rfe 255 isn't supported
> > > [ 1818.165176] rtw_8821cu 1-5.1.2:1.2: failed to setup chip efuse info
> > > [ 1818.171505] rtw_8821cu 1-5.1.2:1.2: failed to setup chip information
> > 
> > Do these chips work with your out of tree variant of this driver?
> > 
> > Is the efuse info completely 0xff or only the field indicating the rfe
> > option?
> 
> I check RFE allocation of 8821c. 255 isn't defined.
> If efuse info isn't complete 0xff, try to force RFE 0 to see if it works.
> 
> > 
> > > rtl8822bu devices are working fine ...
> > 
> > Nice. Did you test a rtw8723du device as well?
> > 
> 
> I have a 8723DU module.
> 
> With this patchset, it can find AP, but can't estiablish connection.
> I check air capture, but no TX packets found.
> That says RX works, but TX doesn't.

The rtw88 repository has 8723DU support added with:

	initial for RTW8723DU devices

    	not tested, no Device
	Hints are found in rtl8822bu code

No active commits to this file since then, so it's probably not supposed
to work.  Unless somebody comes up with fixes I'll remove support for
this chip for now.

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] 43+ messages in thread

* Re: [PATCH 07/10] rtw88: Add rtw8723du chipset support
  2022-05-18  8:23 ` [PATCH 07/10] rtw88: Add rtw8723du chipset support Sascha Hauer
  2022-05-18 16:55   ` kernel test robot
  2022-05-20  7:47   ` Pkshih
@ 2022-05-30  6:34   ` Icenowy Zheng
  2 siblings, 0 replies; 43+ messages in thread
From: Icenowy Zheng @ 2022-05-30  6:34 UTC (permalink / raw)
  To: Sascha Hauer, linux-wireless
  Cc: Neo Jou, Hans Ulli Kroll, Ping-Ke Shih, Yan-Hsuan Chuang,
	Kalle Valo, netdev, linux-kernel, Martin Blumenstingl, kernel,
	Johannes Berg

在 2022-05-18星期三的 10:23 +0200,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>
> Reported-by: kernel test robot <lkp@intel.com>
> ---
>  drivers/net/wireless/realtek/rtw88/Kconfig    | 11 +++++
>  drivers/net/wireless/realtek/rtw88/Makefile   |  3 ++
>  drivers/net/wireless/realtek/rtw88/rtw8723d.c | 19 +++++++++
>  drivers/net/wireless/realtek/rtw88/rtw8723d.h |  1 +
>  .../net/wireless/realtek/rtw88/rtw8723du.c    | 40
> +++++++++++++++++++
>  .../net/wireless/realtek/rtw88/rtw8723du.h    | 13 ++++++
>  6 files changed, 87 insertions(+)
>  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 1624c5db69bac..ad1ac453015a9 100644
> --- a/drivers/net/wireless/realtek/rtw88/Kconfig
> +++ b/drivers/net/wireless/realtek/rtw88/Kconfig
> @@ -64,6 +64,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 9e095f8181483..eb26c215fcde3 100644
> --- a/drivers/net/wireless/realtek/rtw88/Makefile
> +++ b/drivers/net/wireless/realtek/rtw88/Makefile
> @@ -38,6 +38,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 ad2b323a0423c..ccd23902756e1 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,15 @@ 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) */
> +
> +       fill_txdesc_checksum_common(txdesc, words);
> +}
> +
>  static struct rtw_chip_ops rtw8723d_ops = {
>         .phy_set_param          = rtw8723d_phy_set_param,
>         .read_efuse             = rtw8723d_read_efuse,
> @@ -1965,6 +1983,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 41d35174a5425..8113bd97edf57 100644
> --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
> @@ -70,6 +70,7 @@ struct rtw8723d_efuse {
>         u8 country_code[2];
>         u8 res[3];
>         struct rtw8723de_efuse e;
> +       struct rtw8723de_efuse u;

The code here looks ridiculously wrong.

Should there be a rtw8723du_efuse struct and an union here?

BTW I found that Ulli's rtw88-usb repo has the same error, but I doubt
whether 8723du support is tested there.

>  };
>  
>  /* phy status page0 */
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723du.c
> b/drivers/net/wireless/realtek/rtw88/rtw8723du.c
> new file mode 100644
> index 0000000000000..910f64c168131
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.c
> @@ -0,0 +1,40 @@
> +// 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[] = {
> +       /*
> +        * ULLI :
> +        * ID found in rtw8822bu sources
> +        */
> +       { 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..2e069f65c0551
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
> +/* Copyright(c) 2018-2019  Realtek Corporation
> + */
> +
> +#ifndef __RTW_8723DU_H_
> +#define __RTW_8723DU_H_
> +
> +/* USB Vendor/Product IDs */
> +#define RTW_USB_VENDOR_ID_REALTEK              0x0BDA
> +
> +extern struct rtw_chip_info rtw8723d_hw_spec;
> +
> +#endif



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

* Re: [PATCH 00/10] RTW88: Add support for USB variants
  2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
                   ` (10 preceding siblings ...)
  2022-05-23  4:07 ` [PATCH 00/10] RTW88: Add support for USB variants Hans Ulli Kroll
@ 2022-05-30  9:25 ` Kalle Valo
  2022-05-30  9:52   ` Sascha Hauer
  11 siblings, 1 reply; 43+ messages in thread
From: Kalle Valo @ 2022-05-30  9:25 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: linux-wireless, Neo Jou, Hans Ulli Kroll, Ping-Ke Shih,
	Yan-Hsuan Chuang, netdev, linux-kernel, Martin Blumenstingl,
	kernel, Johannes Berg

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

> Another problem to address is that the driver uses
> ieee80211_iterate_stations_atomic() and
> ieee80211_iterate_active_interfaces_atomic() and does register accesses
> in the iterator. This doesn't work with USB, so iteration is done in two
> steps now: The ieee80211_iterate_*_atomic() functions are only used to
> collect the stations/interfaces on a list which is then iterated over
> non-atomically in the second step. The implementation for this is
> basically the one suggested by Ping-Ke here:
>
> https://lore.kernel.org/lkml/423f474e15c948eda4db5bc9a50fd391@realtek.com/

Isn't this racy? What guarantees that vifs are not deleted after
ieee80211_iterate_active_interfaces_atomic() call?

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

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

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

* Re: [PATCH 00/10] RTW88: Add support for USB variants
  2022-05-30  9:25 ` Kalle Valo
@ 2022-05-30  9:52   ` Sascha Hauer
  2022-05-30 10:07     ` Kalle Valo
  0 siblings, 1 reply; 43+ messages in thread
From: Sascha Hauer @ 2022-05-30  9:52 UTC (permalink / raw)
  To: Kalle Valo
  Cc: linux-wireless, Neo Jou, Hans Ulli Kroll, Ping-Ke Shih,
	Yan-Hsuan Chuang, netdev, linux-kernel, Martin Blumenstingl,
	kernel, Johannes Berg

On Mon, May 30, 2022 at 12:25:13PM +0300, Kalle Valo wrote:
> Sascha Hauer <s.hauer@pengutronix.de> writes:
> 
> > Another problem to address is that the driver uses
> > ieee80211_iterate_stations_atomic() and
> > ieee80211_iterate_active_interfaces_atomic() and does register accesses
> > in the iterator. This doesn't work with USB, so iteration is done in two
> > steps now: The ieee80211_iterate_*_atomic() functions are only used to
> > collect the stations/interfaces on a list which is then iterated over
> > non-atomically in the second step. The implementation for this is
> > basically the one suggested by Ping-Ke here:
> >
> > https://lore.kernel.org/lkml/423f474e15c948eda4db5bc9a50fd391@realtek.com/
> 
> Isn't this racy? What guarantees that vifs are not deleted after
> ieee80211_iterate_active_interfaces_atomic() call?

The driver mutex &rtwdev->mutex is acquired during the whole
collection/iteration process. For deleting an interface
ieee80211_ops::remove_interface would have to be called, right?
That would acquire &rtwdev->mutex as well, so I think this should be
safe.

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] 43+ messages in thread

* Re: [PATCH 00/10] RTW88: Add support for USB variants
  2022-05-30  9:52   ` Sascha Hauer
@ 2022-05-30 10:07     ` Kalle Valo
  2022-05-30 10:16       ` Sascha Hauer
  0 siblings, 1 reply; 43+ messages in thread
From: Kalle Valo @ 2022-05-30 10:07 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: linux-wireless, Neo Jou, Hans Ulli Kroll, Ping-Ke Shih,
	Yan-Hsuan Chuang, netdev, linux-kernel, Martin Blumenstingl,
	kernel, Johannes Berg

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

> On Mon, May 30, 2022 at 12:25:13PM +0300, Kalle Valo wrote:
>> Sascha Hauer <s.hauer@pengutronix.de> writes:
>> 
>> > Another problem to address is that the driver uses
>> > ieee80211_iterate_stations_atomic() and
>> > ieee80211_iterate_active_interfaces_atomic() and does register accesses
>> > in the iterator. This doesn't work with USB, so iteration is done in two
>> > steps now: The ieee80211_iterate_*_atomic() functions are only used to
>> > collect the stations/interfaces on a list which is then iterated over
>> > non-atomically in the second step. The implementation for this is
>> > basically the one suggested by Ping-Ke here:
>> >
>> > https://lore.kernel.org/lkml/423f474e15c948eda4db5bc9a50fd391@realtek.com/
>> 
>> Isn't this racy? What guarantees that vifs are not deleted after
>> ieee80211_iterate_active_interfaces_atomic() call?
>
> The driver mutex &rtwdev->mutex is acquired during the whole
> collection/iteration process. For deleting an interface
> ieee80211_ops::remove_interface would have to be called, right?
> That would acquire &rtwdev->mutex as well, so I think this should be
> safe.

Can you add a comment to the code explaining this? And
lockdep_assert_held() is a good way to guarantee that the mutex is
really held.

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

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

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

* Re: [PATCH 00/10] RTW88: Add support for USB variants
  2022-05-30 10:07     ` Kalle Valo
@ 2022-05-30 10:16       ` Sascha Hauer
  0 siblings, 0 replies; 43+ messages in thread
From: Sascha Hauer @ 2022-05-30 10:16 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Ping-Ke Shih, Hans Ulli Kroll, Martin Blumenstingl, netdev,
	linux-wireless, Yan-Hsuan Chuang, linux-kernel, Neo Jou, kernel,
	Johannes Berg

On Mon, May 30, 2022 at 01:07:25PM +0300, Kalle Valo wrote:
> Sascha Hauer <s.hauer@pengutronix.de> writes:
> 
> > On Mon, May 30, 2022 at 12:25:13PM +0300, Kalle Valo wrote:
> >> Sascha Hauer <s.hauer@pengutronix.de> writes:
> >> 
> >> > Another problem to address is that the driver uses
> >> > ieee80211_iterate_stations_atomic() and
> >> > ieee80211_iterate_active_interfaces_atomic() and does register accesses
> >> > in the iterator. This doesn't work with USB, so iteration is done in two
> >> > steps now: The ieee80211_iterate_*_atomic() functions are only used to
> >> > collect the stations/interfaces on a list which is then iterated over
> >> > non-atomically in the second step. The implementation for this is
> >> > basically the one suggested by Ping-Ke here:
> >> >
> >> > https://lore.kernel.org/lkml/423f474e15c948eda4db5bc9a50fd391@realtek.com/
> >> 
> >> Isn't this racy? What guarantees that vifs are not deleted after
> >> ieee80211_iterate_active_interfaces_atomic() call?
> >
> > The driver mutex &rtwdev->mutex is acquired during the whole
> > collection/iteration process. For deleting an interface
> > ieee80211_ops::remove_interface would have to be called, right?
> > That would acquire &rtwdev->mutex as well, so I think this should be
> > safe.
> 
> Can you add a comment to the code explaining this?

Sure.

> And
> lockdep_assert_held() is a good way to guarantee that the mutex is
> really held.

Yes, Ping-Ke already pointed that out. Will add in the next round.

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] 43+ messages in thread

end of thread, other threads:[~2022-05-30 10:16 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-18  8:23 [PATCH 00/10] RTW88: Add support for USB variants Sascha Hauer
2022-05-18  8:23 ` [PATCH 01/10] rtw88: Call rtw_fw_beacon_filter_config() with rtwdev->mutex held Sascha Hauer
2022-05-18  8:23 ` [PATCH 02/10] rtw88: Drop rf_lock Sascha Hauer
2022-05-20  3:49   ` Pkshih
2022-05-20  6:54     ` s.hauer
2022-05-18  8:23 ` [PATCH 03/10] rtw88: Drop h2c.lock Sascha Hauer
2022-05-18  8:23 ` [PATCH 04/10] rtw88: Drop coex mutex Sascha Hauer
2022-05-18  8:23 ` [PATCH 05/10] rtw88: Do not access registers while atomic Sascha Hauer
2022-05-20  6:06   ` Pkshih
2022-05-20  7:07     ` s.hauer
2022-05-20 17:32   ` Larry Finger
2022-05-18  8:23 ` [PATCH 06/10] rtw88: Add common USB chip support Sascha Hauer
2022-05-18  8:32   ` Sascha Hauer
2022-05-18  8:34     ` Johannes Berg
2022-05-19 13:58       ` Sascha Hauer
2022-05-20  7:39   ` Pkshih
2022-05-20  8:51     ` s.hauer
2022-05-20  9:23       ` Pkshih
2022-05-20 18:33   ` Larry Finger
2022-05-23  4:07   ` Hans Ulli Kroll
2022-05-18  8:23 ` [PATCH 07/10] rtw88: Add rtw8723du chipset support Sascha Hauer
2022-05-18 16:55   ` kernel test robot
2022-05-20  7:47   ` Pkshih
2022-05-20  8:16     ` s.hauer
2022-05-30  6:34   ` Icenowy Zheng
2022-05-18  8:23 ` [PATCH 08/10] rtw88: Add rtw8821cu " Sascha Hauer
2022-05-20  7:56   ` Pkshih
2022-05-18  8:23 ` [PATCH 09/10] rtw88: Add rtw8822bu " Sascha Hauer
2022-05-20  7:58   ` Pkshih
2022-05-23 11:56   ` Rin Cat (鈴猫)
2022-05-23 12:34     ` Sascha Hauer
2022-05-18  8:23 ` [PATCH 10/10] rtw88: Add rtw8822cu " Sascha Hauer
2022-05-20  8:03   ` Pkshih
2022-05-20  8:56     ` s.hauer
2022-05-23  4:07 ` [PATCH 00/10] RTW88: Add support for USB variants Hans Ulli Kroll
2022-05-23  6:53   ` Sascha Hauer
2022-05-23 11:39     ` Ping-Ke Shih
2022-05-24  6:54       ` s.hauer
2022-05-23 10:13   ` Sascha Hauer
2022-05-30  9:25 ` Kalle Valo
2022-05-30  9:52   ` Sascha Hauer
2022-05-30 10:07     ` Kalle Valo
2022-05-30 10:16       ` Sascha Hauer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.