linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ath11k: add register read debugfs interface for WCN6855
@ 2022-01-25  6:37 Cheng Wang
  2022-01-28 13:45 ` Kalle Valo
  0 siblings, 1 reply; 3+ messages in thread
From: Cheng Wang @ 2022-01-25  6:37 UTC (permalink / raw)
  To: ath11k; +Cc: linux-wireless, quic_chengwan

Add debugfs interface reg_addr/reg_value and use these two interfaces
to read register value.
For example, execute the following commands to read WCN6855 HW register of
“memtype=0xa offset=0x3a00d0”:

$ echo 0xa 0x3a00d0>reg_addr
$ cat reg_value
0x10200000

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1

Signed-off-by: Cheng Wang <quic_chengwan@quicinc.com>
---
 drivers/net/wireless/ath/ath11k/core.h    |   2 +
 drivers/net/wireless/ath/ath11k/debugfs.c | 167 ++++++++++++++++++++++
 drivers/net/wireless/ath/ath11k/qmi.c     | 136 ++++++++++++++++++
 drivers/net/wireless/ath/ath11k/qmi.h     |  39 +++++
 4 files changed, 344 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index 4eda15c56b04..910479427f55 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -454,6 +454,8 @@ struct ath11k_debug {
 	u32 pktlog_peer_valid;
 	u8 pktlog_peer_addr[ETH_ALEN];
 	u32 rx_filter;
+	enum qmi_allocram_arena mem_type;
+	u32 mem_offset;
 };
 
 struct ath11k_per_peer_tx_stats {
diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c
index 215b6014c0ef..2dab2f46655d 100644
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
@@ -1113,6 +1113,159 @@ static const struct file_operations fops_simulate_radar = {
 	.open = simple_open
 };
 
+static const char *ath11k_memtype2string(u32 mem_type)
+{
+	const char * const mem_type_str[] = {
+		[QMI_ALLOCRAM_HRAM_ARENA] = "hram",
+		[QMI_ALLOCRAM_HCRAM_ARENA] = "hcram",
+		[QMI_ALLOCRAM_HREMOTE_ARENA] = "hremote",
+		[QMI_ALLOCRAM_HCREMOTE_ARENA] = "hcremote",
+		[QMI_ALLOCRAM_REMOTE_ARENA] = "remote",
+		[QMI_ALLOCRAM_SRAM_ARENA] = "sram",
+		[QMI_ALLOCRAM_SRAM_AUX_ARENA] = "sram_aux",
+		[QMI_ALLOCRAM_PAGEABLE_ARENA] = "pageable",
+		[QMI_ALLOCRAM_CMEM_ARENA] = "cmem",
+		[QMI_ALLOCRAM_TRAM_ARENA] = "tram",
+		[QMI_ALLOCRAM_HWIO_ARENA] = "hwio",
+		[QMI_ALLOCRAM_CALDB_ARENA] = "caldb",
+		[QMI_ALLOCRAM_M3_ARENA] = "m3_arena",
+		[QMI_ALLOCRAM_ETMREMOTE_ARENA] = "etm_remote",
+		[QMI_ALLOCRAM_EMUPHY_ARENA] = "emu_phy",
+	};
+
+	if (mem_type < ARRAY_SIZE(mem_type_str))
+		return mem_type_str[mem_type];
+
+	return NULL;
+}
+
+static ssize_t ath11k_read_reg_addr(struct file *file,
+				    char __user *user_buf,
+				    size_t count, loff_t *ppos)
+{
+	struct ath11k *ar = file->private_data;
+	u8 buf[64];
+	size_t len = 0;
+	u32 mem_type, mem_offset;
+
+	mutex_lock(&ar->conf_mutex);
+	mem_type = ar->debug.mem_type;
+	mem_offset = ar->debug.mem_offset;
+	mutex_unlock(&ar->conf_mutex);
+
+	len += scnprintf(buf + len, sizeof(buf) - len, "0x%x 0x%x\n",
+			 mem_type, mem_offset);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath11k_write_reg_addr(struct file *file,
+				     const char __user *user_buf,
+				     size_t count, loff_t *ppos)
+{
+	struct ath11k *ar = file->private_data;
+	struct ath11k_base *ab = ar->ab;
+	char buf[64] = {0};
+	ssize_t ret;
+	int rc;
+	u32 mem_type, mem_offset;
+	char sep[] = " ";
+	char *token, *cur;
+	const char *mem_type_str;
+
+	if (*ppos != 0 || count >= sizeof(buf) || count == 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
+	if (ret < 0)
+		goto out;
+
+	/* drop the possible '\n' from the end */
+	if (buf[*ppos - 1] == '\n')
+		buf[*ppos - 1] = '\0';
+
+	ath11k_dbg(ab, ATH11K_DBG_QMI, "%s: %s\n", __func__, buf);
+	ret = count;
+	cur = buf;
+
+	token = strsep(&cur, sep);
+	rc = kstrtou32(token, 0, &mem_type);
+	if (rc) {
+		ath11k_warn(ab, "%s convert error: mem_type %s\n", __func__, token);
+		ret = -EFAULT;
+		goto out;
+	}
+
+	mem_type_str = ath11k_memtype2string(mem_type);
+	if (!mem_type_str) {
+		ath11k_warn(ab, "%s invalid mem type value %d\n", __func__, mem_type);
+		ret = -EINVAL;
+		goto out;
+	}
+	ath11k_dbg(ab, ATH11K_DBG_QMI, "%s mem_type %d %s\n", __func__, mem_type, mem_type_str);
+
+	token = strim(cur);
+	rc = kstrtou32(token, 0, &mem_offset);
+	if (rc) {
+		ath11k_warn(ab, "%s convert error: mem_offset %s\n", __func__, token);
+		ret = -EFAULT;
+		goto out;
+	}
+
+	mutex_lock(&ar->conf_mutex);
+	ar->debug.mem_type = mem_type;
+	ar->debug.mem_offset = mem_offset;
+	mutex_unlock(&ar->conf_mutex);
+
+out:
+	return ret;
+}
+
+static const struct file_operations fops_reg_addr = {
+	.read = ath11k_read_reg_addr,
+	.write = ath11k_write_reg_addr,
+	.open = simple_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t ath11k_read_reg_value(struct file *file,
+				     char __user *user_buf,
+				     size_t count, loff_t *ppos)
+{
+	struct ath11k *ar = file->private_data;
+	struct ath11k_base *ab = ar->ab;
+	u8 buf[64];
+	size_t len = 0;
+	int ret_read;
+	u32 reg_value;
+
+	if (ar->debug.mem_type >= QMI_ALLOCRAM_ARENA_MAX) {
+		ath11k_warn(ab, "%s mem type error %d\n", __func__, ar->debug.mem_type);
+		return -EINVAL;
+	}
+
+	ret_read = ath11k_qmi_wlanfw_athdiag_read_send(ab, ar->debug.mem_type,
+						       ar->debug.mem_offset, &reg_value);
+	if (ret_read < 0)
+		len += scnprintf(buf + len, sizeof(buf) - len, "failed to read reg, err=%d\n",
+				 ret_read);
+	else
+		len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_value);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_reg_value = {
+	.read = ath11k_read_reg_value,
+	.write = NULL,
+	.open = simple_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 int ath11k_debugfs_register(struct ath11k *ar)
 {
 	struct ath11k_base *ab = ar->ab;
@@ -1152,6 +1305,20 @@ int ath11k_debugfs_register(struct ath11k *ar)
 				    &ar->dfs_block_radar_events);
 	}
 
+	switch (ab->hw_rev) {
+	case ATH11K_HW_WCN6855_HW20:
+		debugfs_create_file("reg_addr", 0600,
+				    ar->debug.debugfs_pdev, ar,
+				    &fops_reg_addr);
+		debugfs_create_file("reg_value", 0400,
+				    ar->debug.debugfs_pdev, ar,
+				    &fops_reg_value);
+		break;
+	default:
+		ath11k_warn(ab, "reg_addr debugfs not support hardware: %d\n", ab->hw_rev);
+		break;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
index d0701e8eca9c..b37e69234e55 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -1628,6 +1628,85 @@ static struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = {
 	},
 };
 
+static struct qmi_elem_info qmi_wlanfw_athdiag_read_req_msg_v01_ei[] = {
+	{
+		.data_type	= QMI_UNSIGNED_4_BYTE,
+		.elem_len	= 1,
+		.elem_size	= sizeof(u32),
+		.array_type	= NO_ARRAY,
+		.tlv_type	= 0x01,
+		.offset		= offsetof(struct qmi_wlanfw_athdiag_read_req_msg_v01,
+					   mem_offset),
+	},
+	{
+		.data_type	= QMI_UNSIGNED_4_BYTE,
+		.elem_len	= 1,
+		.elem_size	= sizeof(u32),
+		.array_type	= NO_ARRAY,
+		.tlv_type	= 0x02,
+		.offset		= offsetof(struct qmi_wlanfw_athdiag_read_req_msg_v01,
+					   mem_type),
+	},
+	{
+		.data_type	= QMI_UNSIGNED_4_BYTE,
+		.elem_len	= 1,
+		.elem_size	= sizeof(u32),
+		.array_type	= NO_ARRAY,
+		.tlv_type	= 0x03,
+		.offset		= offsetof(struct qmi_wlanfw_athdiag_read_req_msg_v01,
+					   data_len),
+	},
+	{
+		.data_type	= QMI_EOTI,
+		.array_type	= NO_ARRAY,
+		.tlv_type	= QMI_COMMON_TLV_TYPE,
+	},
+};
+
+static struct qmi_elem_info qmi_wlanfw_athdiag_read_resp_msg_v01_ei[] = {
+	{
+		.data_type	= QMI_STRUCT,
+		.elem_len	= 1,
+		.elem_size	= sizeof(struct qmi_response_type_v01),
+		.array_type	= NO_ARRAY,
+		.tlv_type	= 0x02,
+		.offset		= offsetof(struct qmi_wlanfw_athdiag_read_resp_msg_v01, resp),
+		.ei_array	= qmi_response_type_v01_ei,
+	},
+	{
+		.data_type	= QMI_OPT_FLAG,
+		.elem_len	= 1,
+		.elem_size	= sizeof(u8),
+		.array_type	= NO_ARRAY,
+		.tlv_type	= 0x10,
+		.offset		= offsetof(struct qmi_wlanfw_athdiag_read_resp_msg_v01,
+					   data_valid),
+	},
+	{
+		.data_type	= QMI_DATA_LEN,
+		.elem_len	= 1,
+		.elem_size	= sizeof(u32),
+		.array_type	= NO_ARRAY,
+		.tlv_type	= 0x10,
+		.offset		= offsetof(struct qmi_wlanfw_athdiag_read_resp_msg_v01,
+					   data_len),
+	},
+	{
+		.data_type	= QMI_UNSIGNED_1_BYTE,
+		.elem_len	= QMI_WLANFW_MAX_ATHDIAG_DATA_SIZE_V01,
+		.elem_size	= sizeof(u8),
+		.array_type	= VAR_LEN_ARRAY,
+		.tlv_type	= 0x10,
+		.offset		= offsetof(struct qmi_wlanfw_athdiag_read_resp_msg_v01,
+					   data),
+	},
+	{
+		.data_type	= QMI_EOTI,
+		.array_type	= NO_ARRAY,
+		.tlv_type	= QMI_COMMON_TLV_TYPE,
+	},
+};
+
 static int ath11k_qmi_host_cap_send(struct ath11k_base *ab)
 {
 	struct qmi_wlanfw_host_cap_req_msg_v01 req;
@@ -3025,3 +3104,60 @@ void ath11k_qmi_deinit_service(struct ath11k_base *ab)
 }
 EXPORT_SYMBOL(ath11k_qmi_deinit_service);
 
+int ath11k_qmi_wlanfw_athdiag_read_send(struct ath11k_base *ab, u32 mem_type,
+					u32 mem_offset, u32 *out)
+{
+	int ret;
+	struct qmi_wlanfw_athdiag_read_req_msg_v01 req;
+	struct qmi_wlanfw_athdiag_read_resp_msg_v01 *resp;
+	struct qmi_txn txn;
+
+	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
+	if (!resp)
+		return -ENOMEM;
+
+	req.mem_type = mem_type;
+	req.mem_offset = mem_offset;
+	req.data_len = sizeof(u32);
+
+	ath11k_info(ab, "%s start, mem_type %d offset 0x%x\n",
+		    __func__, mem_type, mem_offset);
+	ret = qmi_txn_init(&ab->qmi.handle, &txn,
+			   qmi_wlanfw_athdiag_read_resp_msg_v01_ei, resp);
+	if (ret < 0)
+		goto out;
+
+	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
+			       QMI_WLANFW_ATHDIAG_READ_REQ_V01,
+			       QMI_WLANFW_ATHDIAG_READ_REQ_MSG_V01_MAX_LEN,
+			       qmi_wlanfw_athdiag_read_req_msg_v01_ei, &req);
+	if (ret < 0) {
+		qmi_txn_cancel(&txn);
+		ath11k_warn(ab, "qmi failed to send wlan diag read request, err = %d\n",
+			    ret);
+		goto out;
+	}
+
+	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
+	if (ret < 0) {
+		ath11k_warn(ab, "qmi failed wlan diag read request, err = %d\n", ret);
+		goto out;
+	}
+
+	if (resp->resp.result != QMI_RESULT_SUCCESS_V01 ||
+	    !resp->data_valid ||
+	    resp->data_len != sizeof(u32)) {
+		ath11k_warn(ab, "QMI request failed result=%d, error=%d, valid=%d, len=%d\n",
+			    resp->resp.result, resp->resp.error,
+			    resp->data_valid, resp->data_len);
+		ret = -EINVAL;
+		goto out;
+	}
+	*out = *(u32 *)resp->data;
+	ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi read reg pass, resp.data = 0x%08x\n",
+		   *(u32 *)resp->data);
+
+out:
+	kfree(resp);
+	return ret;
+}
diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h
index ba2eff4d59cb..2cd6a3043d59 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.h
+++ b/drivers/net/wireless/ath/ath11k/qmi.h
@@ -181,6 +181,43 @@ struct qmi_wlanfw_host_cap_resp_msg_v01 {
 	struct qmi_response_type_v01 resp;
 };
 
+#define QMI_WLANFW_MAX_ATHDIAG_DATA_SIZE_V01	512
+#define QMI_WLANFW_ATHDIAG_READ_REQ_V01	0x0030
+#define QMI_WLANFW_ATHDIAG_READ_RESP_V01	0x0030
+#define QMI_WLANFW_ATHDIAG_READ_REQ_MSG_V01_MAX_LEN	21
+
+enum qmi_allocram_arena {
+	QMI_ALLOCRAM_HRAM_ARENA,
+	QMI_ALLOCRAM_HCRAM_ARENA,
+	QMI_ALLOCRAM_HREMOTE_ARENA,
+	QMI_ALLOCRAM_HCREMOTE_ARENA,
+	QMI_ALLOCRAM_REMOTE_ARENA,
+	QMI_ALLOCRAM_SRAM_ARENA,
+	QMI_ALLOCRAM_SRAM_AUX_ARENA,
+	QMI_ALLOCRAM_PAGEABLE_ARENA,
+	QMI_ALLOCRAM_CMEM_ARENA,
+	QMI_ALLOCRAM_TRAM_ARENA,
+	QMI_ALLOCRAM_HWIO_ARENA,
+	QMI_ALLOCRAM_CALDB_ARENA,
+	QMI_ALLOCRAM_M3_ARENA,
+	QMI_ALLOCRAM_ETMREMOTE_ARENA,
+	QMI_ALLOCRAM_EMUPHY_ARENA,
+	QMI_ALLOCRAM_ARENA_MAX,
+};
+
+struct qmi_wlanfw_athdiag_read_req_msg_v01 {
+	u32 mem_offset;
+	u32 mem_type;
+	u32 data_len;
+};
+
+struct qmi_wlanfw_athdiag_read_resp_msg_v01 {
+	struct qmi_response_type_v01 resp;
+	u8 data_valid;
+	u32 data_len;
+	u8 data[QMI_WLANFW_MAX_ATHDIAG_DATA_SIZE_V01];
+};
+
 #define QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN		54
 #define QMI_WLANFW_IND_REGISTER_REQ_V01				0x0020
 #define QMI_WLANFW_IND_REGISTER_RESP_MSG_V01_MAX_LEN		18
@@ -492,5 +529,7 @@ void ath11k_qmi_event_work(struct work_struct *work);
 void ath11k_qmi_msg_recv_work(struct work_struct *work);
 void ath11k_qmi_deinit_service(struct ath11k_base *ab);
 int ath11k_qmi_init_service(struct ath11k_base *ab);
+int ath11k_qmi_wlanfw_athdiag_read_send(struct ath11k_base *ab, u32 mem_type,
+					u32 offset, u32 *out);
 
 #endif
-- 
2.25.1


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

* Re: [PATCH] ath11k: add register read debugfs interface for WCN6855
  2022-01-25  6:37 [PATCH] ath11k: add register read debugfs interface for WCN6855 Cheng Wang
@ 2022-01-28 13:45 ` Kalle Valo
  2022-04-23 10:32   ` Kalle Valo
  0 siblings, 1 reply; 3+ messages in thread
From: Kalle Valo @ 2022-01-28 13:45 UTC (permalink / raw)
  To: Cheng Wang; +Cc: ath11k, linux-wireless

Cheng Wang <quic_chengwan@quicinc.com> writes:

> Add debugfs interface reg_addr/reg_value and use these two interfaces
> to read register value.
> For example, execute the following commands to read WCN6855 HW register of
> “memtype=0xa offset=0x3a00d0”:
>
> $ echo 0xa 0x3a00d0>reg_addr
> $ cat reg_value
> 0x10200000
>
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
>
> Signed-off-by: Cheng Wang <quic_chengwan@quicinc.com>

This had new warnings, fixed in the pending branch:

drivers/net/wireless/ath/ath11k/debugfs.c:1207: line length of 96 exceeds 90 columns
drivers/net/wireless/ath/ath11k/debugfs.c:1253: line length of 94 exceeds 90 columns
drivers/net/wireless/ath/ath11k/debugfs.c:1318: line length of 91 exceeds 90 columns
drivers/net/wireless/ath/ath11k/qmi.c:1673: line length of 94 exceeds 90 columns

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

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

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

* Re: [PATCH] ath11k: add register read debugfs interface for WCN6855
  2022-01-28 13:45 ` Kalle Valo
@ 2022-04-23 10:32   ` Kalle Valo
  0 siblings, 0 replies; 3+ messages in thread
From: Kalle Valo @ 2022-04-23 10:32 UTC (permalink / raw)
  To: Cheng Wang; +Cc: ath11k, linux-wireless

Kalle Valo <kvalo@kernel.org> writes:

> Cheng Wang <quic_chengwan@quicinc.com> writes:
>
>> Add debugfs interface reg_addr/reg_value and use these two interfaces
>> to read register value.
>> For example, execute the following commands to read WCN6855 HW register of
>> “memtype=0xa offset=0x3a00d0”:
>>
>> $ echo 0xa 0x3a00d0>reg_addr
>> $ cat reg_value
>> 0x10200000
>>
>> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
>>
>> Signed-off-by: Cheng Wang <quic_chengwan@quicinc.com>
>
> This had new warnings, fixed in the pending branch:
>
> drivers/net/wireless/ath/ath11k/debugfs.c:1207: line length of 96 exceeds 90 columns
> drivers/net/wireless/ath/ath11k/debugfs.c:1253: line length of 94 exceeds 90 columns
> drivers/net/wireless/ath/ath11k/debugfs.c:1318: line length of 91 exceeds 90 columns
> drivers/net/wireless/ath/ath11k/qmi.c:1673: line length of 94 exceeds 90 columns

I tried to test this[1] and I couldn't get it to work:

# echo 0xa 0x3a00d0>reg_addr
# cat reg_value 
failed to read reg, err=-22

The error message from ath11k is:

[  923.629220] ath11k_pci 0000:06:00.0: ath11k_qmi_wlanfw_athdiag_read_send start, mem_type 10 offset 0x300000
[  923.647156] ath11k_pci 0000:06:00.0: QMI request failed result=0, error=0, valid=1, len=0

While reviewing the patch I found other issues:

o do not use ath11k_info()

o debug messages don't follow ath11k style

o warning messages don't follow ath11k style

o convert ab->hw_reg to struct ath11k_hw_params flag

o don't print a warning if register read feature is not supported

My setup on my NUC is:

[  679.283156] ath11k_pci 0000:06:00.0: MSI vectors: 32
[  679.283230] ath11k_pci 0000:06:00.0: wcn6855 hw2.0
[  679.486183] mhi mhi0: Requested to power ON
[  679.488864] mhi mhi0: Power on setup success
[  679.890486] mhi mhi0: Wait for device to enter SBL or Mission mode
[  680.537360] ath11k_pci 0000:06:00.0: chip_id 0x2 chip_family 0xb board_id 0x106 soc_id 0x400c0200
[  680.537669] ath11k_pci 0000:06:00.0: fw_version 0x110f0c35 fw_build_timestamp 2022-03-30 09:05 fw_build_id WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.7

[1] https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=26c7a6e468f27c1155fd7e7cc8653eabe44b9640

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

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

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

end of thread, other threads:[~2022-04-23 10:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-25  6:37 [PATCH] ath11k: add register read debugfs interface for WCN6855 Cheng Wang
2022-01-28 13:45 ` Kalle Valo
2022-04-23 10:32   ` Kalle Valo

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