diff mbox series

[v2,1/4] Bluetooth: btintel_pcie: Setup buffers for firmware traces

Message ID 20250221144245.1012686-1-kiran.k@intel.com
State Superseded
Headers show
Series [v2,1/4] Bluetooth: btintel_pcie: Setup buffers for firmware traces | expand

Commit Message

Kiran K Feb. 21, 2025, 2:42 p.m. UTC
This patch allocates the host memory which is used by controller to dump
the firmware traces. The memory needs to be shared with controller via
context information.

Co-developed-by: Vijay Satija <vijay.satija@intel.com>
Signed-off-by: Vijay Satija <vijay.satija@intel.com>
Signed-off-by: Kiran K <kiran.k@intel.com>
---
v1 -> v2:
No change

 drivers/bluetooth/btintel_pcie.c | 89 ++++++++++++++++++++++++++++++++
 drivers/bluetooth/btintel_pcie.h | 32 ++++++++++++
 2 files changed, 121 insertions(+)

Comments

Kiran K Feb. 25, 2025, 10:56 a.m. UTC | #1
Hi Luiz,

>Subject: Re: [PATCH v2 1/4] Bluetooth: btintel_pcie: Setup buffers for firmware
>traces
>
>Hi Kiran,
>
>On Fri, Feb 21, 2025 at 9:44 AM Kiran K <kiran.k@intel.com> wrote:
>>
>> This patch allocates the host memory which is used by controller to
>> dump the firmware traces. The memory needs to be shared with
>> controller via context information.
>>
>> Co-developed-by: Vijay Satija <vijay.satija@intel.com>
>> Signed-off-by: Vijay Satija <vijay.satija@intel.com>
>> Signed-off-by: Kiran K <kiran.k@intel.com>
>> ---
>> v1 -> v2:
>> No change
>>
>>  drivers/bluetooth/btintel_pcie.c | 89
>> ++++++++++++++++++++++++++++++++  drivers/bluetooth/btintel_pcie.h |
>> 32 ++++++++++++
>>  2 files changed, 121 insertions(+)
>>
>> diff --git a/drivers/bluetooth/btintel_pcie.c
>> b/drivers/bluetooth/btintel_pcie.c
>> index b8b241a92bf9..11e2b805c7cc 100644
>> --- a/drivers/bluetooth/btintel_pcie.c
>> +++ b/drivers/bluetooth/btintel_pcie.c
>> @@ -49,6 +49,8 @@ MODULE_DEVICE_TABLE(pci, btintel_pcie_table);
>>  #define BTINTEL_PCIE_HCI_EVT_PKT       0x00000004
>>  #define BTINTEL_PCIE_HCI_ISO_PKT       0x00000005
>>
>> + #define BTINTEL_PCIE_MAGIC_NUM    0xA5A5A5A5
>> +
>>  /* Alive interrupt context */
>>  enum {
>>         BTINTEL_PCIE_ROM,
>> @@ -60,6 +62,83 @@ enum {
>>         BTINTEL_PCIE_D3
>>  };
>>
>> +/* Structure for dbgc fragment buffer
>> + * @buf_addr_lsb: LSB of the buffer's physical address
>> + * @buf_addr_msb: MSB of the buffer's physical address
>> + * @buf_size: Total size of the buffer  */ struct
>> +btintel_pcie_dbgc_ctxt_buf {
>> +       u32     buf_addr_lsb;
>> +       u32     buf_addr_msb;
>> +       u32     buf_size;
>> +};
>> +
>> +/* Structure for dbgc fragment
>> + * @magic_num: 0XA5A5A5A5
>> + * @ver: For Driver-FW compatibility
>> + * @total_size: Total size of the payload debug info
>> + * @num_buf: Num of allocated debug bufs
>> + * @bufs: All buffer's addresses and sizes  */ struct
>> +btintel_pcie_dbgc_ctxt {
>> +       u32     magic_num;
>> +       u32     ver;
>> +       u32     total_size;
>> +       u32     num_buf;
>> +       struct btintel_pcie_dbgc_ctxt_buf
>> +bufs[BTINTEL_PCIE_DBGC_BUFFER_COUNT];
>> +};
>> +
>> +/* This function initializes the memory for DBGC buffers and formats
>> +the
>> + * DBGC fragment which consists header info and DBGC buffer's LSB,
>> +MSB and
>> + * size as the payload
>> + */
>> +static int btintel_pcie_setup_dbgc(struct btintel_pcie_data *data) {
>> +       struct btintel_pcie_dbgc_ctxt db_frag;
>> +       struct data_buf *buf;
>> +       int i;
>> +
>> +       data->dbgc.count = BTINTEL_PCIE_DBGC_BUFFER_COUNT;
>> +       data->dbgc.bufs = devm_kcalloc(&data->pdev->dev, data->dbgc.count,
>> +                                      sizeof(*buf), GFP_KERNEL);
>> +       if (!data->dbgc.bufs)
>> +               return -ENOMEM;
>> +
>> +       data->dbgc.buf_v_addr = dmam_alloc_coherent(&data->pdev->dev,
>> +                                                   data->dbgc.count *
>> +                                                   BTINTEL_PCIE_DBGC_BUFFER_SIZE,
>> +                                                   &data->dbgc.buf_p_addr,
>> +                                                   GFP_KERNEL | __GFP_NOWARN);
>> +       if (!data->dbgc.buf_v_addr)
>> +               return -ENOMEM;
>> +
>> +       data->dbgc.frag_v_addr = dmam_alloc_coherent(&data->pdev->dev,
>> +                                                    sizeof(struct btintel_pcie_dbgc_ctxt),
>> +                                                    &data->dbgc.frag_p_addr,
>> +                                                    GFP_KERNEL | __GFP_NOWARN);
>> +       if (!data->dbgc.frag_v_addr)
>> +               return -ENOMEM;
>> +
>> +       data->dbgc.frag_size = sizeof(struct btintel_pcie_dbgc_ctxt);
>> +
>> +       db_frag.magic_num = BTINTEL_PCIE_MAGIC_NUM;
>> +       db_frag.ver = BTINTEL_PCIE_DBGC_FRAG_VERSION;
>> +       db_frag.total_size = BTINTEL_PCIE_DBGC_FRAG_PAYLOAD_SIZE;
>> +       db_frag.num_buf = BTINTEL_PCIE_DBGC_FRAG_BUFFER_COUNT;
>> +
>> +       for (i = 0; i < data->dbgc.count; i++) {
>> +               buf = &data->dbgc.bufs[i];
>> +               buf->data_p_addr = data->dbgc.buf_p_addr + i *
>BTINTEL_PCIE_DBGC_BUFFER_SIZE;
>> +               buf->data = data->dbgc.buf_v_addr + i *
>BTINTEL_PCIE_DBGC_BUFFER_SIZE;
>> +               db_frag.bufs[i].buf_addr_lsb = (u32)(buf->data_p_addr & 0xffffffff);
>> +               db_frag.bufs[i].buf_addr_msb = (u32)((buf->data_p_addr
>> + >> 32) & 0xffffffff);
>
>If I recall it correctly the shift was causing build errors/warnings.

I did run sparse and did not see any issue. Please let me know if there is a way to reproduce this issue.

>
>> +               db_frag.bufs[i].buf_size = BTINTEL_PCIE_DBGC_BUFFER_SIZE;
>> +       }
>> +
>> +       memcpy(data->dbgc.frag_v_addr, &db_frag, sizeof(db_frag));
>> +       return 0;
>> +}
>> +
>>  static inline void ipc_print_ia_ring(struct hci_dev *hdev, struct ia *ia,
>>                                      u16 queue_num)  { @@ -1008,6
>> +1087,11 @@ static void btintel_pcie_init_ci(struct btintel_pcie_data *data,
>>         ci->addr_urbdq1 = data->rxq.urbd1s_p_addr;
>>         ci->num_urbdq1 = data->rxq.count;
>>         ci->urbdq_db_vec = BTINTEL_PCIE_RXQ_NUM;
>> +
>> +       ci->dbg_output_mode = 0x01;
>> +       ci->dbgc_addr = data->dbgc.frag_p_addr;
>> +       ci->dbgc_size = data->dbgc.frag_size;
>> +       ci->dbg_preset = 0x00;
>>  }
>>
>>  static void btintel_pcie_free_txq_bufs(struct btintel_pcie_data
>> *data, @@ -1220,6 +1304,11 @@ static int btintel_pcie_alloc(struct
>btintel_pcie_data *data)
>>         /* Setup Index Array */
>>         btintel_pcie_setup_ia(data, p_addr, v_addr, &data->ia);
>>
>> +       /* Setup data buffers for dbgc */
>> +       err = btintel_pcie_setup_dbgc(data);
>> +       if (err)
>> +               goto exit_error_txq;
>> +
>>         /* Setup Context Information */
>>         p_addr += sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4;
>>         v_addr += sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4; diff
>> --git a/drivers/bluetooth/btintel_pcie.h
>> b/drivers/bluetooth/btintel_pcie.h
>> index f9aada0543c4..b9d32393002b 100644
>> --- a/drivers/bluetooth/btintel_pcie.h
>> +++ b/drivers/bluetooth/btintel_pcie.h
>> @@ -48,6 +48,21 @@
>>  #define BTINTEL_PCIE_CSR_MSIX_IVAR_BASE
>(BTINTEL_PCIE_CSR_MSIX_BASE + 0x0880)
>>  #define BTINTEL_PCIE_CSR_MSIX_IVAR(cause)
>(BTINTEL_PCIE_CSR_MSIX_IVAR_BASE + (cause))
>>
>> +/* The DRAM buffer count, each buffer size, and
>> + * fragment buffer size
>> + */
>> +#define BTINTEL_PCIE_DBGC_BUFFER_COUNT         16
>> +#define BTINTEL_PCIE_DBGC_BUFFER_SIZE          (256 * 1024) /* 256 KB */
>> +
>> +#define BTINTEL_PCIE_DBGC_FRAG_VERSION         1
>> +#define BTINTEL_PCIE_DBGC_FRAG_BUFFER_COUNT
>BTINTEL_PCIE_DBGC_BUFFER_COUNT
>> +
>> +/* Magic number(4), version(4), size of payload length(4) */
>> +#define BTINTEL_PCIE_DBGC_FRAG_HEADER_SIZE     12
>> +
>> +/* Num of alloc Dbg buff (4) + (LSB(4), MSB(4), Size(4)) for each buffer */
>> +#define BTINTEL_PCIE_DBGC_FRAG_PAYLOAD_SIZE    196
>> +
>>  /* Causes for the FH register interrupts */  enum msix_fh_int_causes
>> {
>>         BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0       = BIT(0),       /* cause 0 */
>> @@ -325,6 +340,22 @@ struct rxq {
>>         struct data_buf *bufs;
>>  };
>>
>> +/* Structure for DRAM Buffer
>> + * @count: Number of descriptors
>> + * @buf: Array of data_buf structure
>> + */
>> +struct btintel_pcie_dbgc {
>> +       u16             count;
>> +
>> +       void            *frag_v_addr;
>> +       dma_addr_t      frag_p_addr;
>> +       u16             frag_size;
>> +
>> +       dma_addr_t      buf_p_addr;
>> +       void            *buf_v_addr;
>> +       struct data_buf *bufs;
>> +};
>> +
>>  /* struct btintel_pcie_data
>>   * @pdev: pci device
>>   * @hdev: hdev device
>> @@ -405,6 +436,7 @@ struct btintel_pcie_data {
>>         struct txq      txq;
>>         struct rxq      rxq;
>>         u32     alive_intr_ctxt;
>> +       struct btintel_pcie_dbgc        dbgc;
>>  };
>>
>>  static inline u32 btintel_pcie_rd_reg32(struct btintel_pcie_data
>> *data,
>> --
>> 2.43.0
>>
>>
>
>
>--
>Luiz Augusto von Dentz
Thanks,
Kiran
diff mbox series

Patch

diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index b8b241a92bf9..11e2b805c7cc 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -49,6 +49,8 @@  MODULE_DEVICE_TABLE(pci, btintel_pcie_table);
 #define BTINTEL_PCIE_HCI_EVT_PKT	0x00000004
 #define BTINTEL_PCIE_HCI_ISO_PKT	0x00000005
 
+ #define BTINTEL_PCIE_MAGIC_NUM    0xA5A5A5A5
+
 /* Alive interrupt context */
 enum {
 	BTINTEL_PCIE_ROM,
@@ -60,6 +62,83 @@  enum {
 	BTINTEL_PCIE_D3
 };
 
+/* Structure for dbgc fragment buffer
+ * @buf_addr_lsb: LSB of the buffer's physical address
+ * @buf_addr_msb: MSB of the buffer's physical address
+ * @buf_size: Total size of the buffer
+ */
+struct btintel_pcie_dbgc_ctxt_buf {
+	u32	buf_addr_lsb;
+	u32	buf_addr_msb;
+	u32	buf_size;
+};
+
+/* Structure for dbgc fragment
+ * @magic_num: 0XA5A5A5A5
+ * @ver: For Driver-FW compatibility
+ * @total_size: Total size of the payload debug info
+ * @num_buf: Num of allocated debug bufs
+ * @bufs: All buffer's addresses and sizes
+ */
+struct btintel_pcie_dbgc_ctxt {
+	u32	magic_num;
+	u32     ver;
+	u32     total_size;
+	u32     num_buf;
+	struct btintel_pcie_dbgc_ctxt_buf bufs[BTINTEL_PCIE_DBGC_BUFFER_COUNT];
+};
+
+/* This function initializes the memory for DBGC buffers and formats the
+ * DBGC fragment which consists header info and DBGC buffer's LSB, MSB and
+ * size as the payload
+ */
+static int btintel_pcie_setup_dbgc(struct btintel_pcie_data *data)
+{
+	struct btintel_pcie_dbgc_ctxt db_frag;
+	struct data_buf *buf;
+	int i;
+
+	data->dbgc.count = BTINTEL_PCIE_DBGC_BUFFER_COUNT;
+	data->dbgc.bufs = devm_kcalloc(&data->pdev->dev, data->dbgc.count,
+				       sizeof(*buf), GFP_KERNEL);
+	if (!data->dbgc.bufs)
+		return -ENOMEM;
+
+	data->dbgc.buf_v_addr = dmam_alloc_coherent(&data->pdev->dev,
+						    data->dbgc.count *
+						    BTINTEL_PCIE_DBGC_BUFFER_SIZE,
+						    &data->dbgc.buf_p_addr,
+						    GFP_KERNEL | __GFP_NOWARN);
+	if (!data->dbgc.buf_v_addr)
+		return -ENOMEM;
+
+	data->dbgc.frag_v_addr = dmam_alloc_coherent(&data->pdev->dev,
+						     sizeof(struct btintel_pcie_dbgc_ctxt),
+						     &data->dbgc.frag_p_addr,
+						     GFP_KERNEL | __GFP_NOWARN);
+	if (!data->dbgc.frag_v_addr)
+		return -ENOMEM;
+
+	data->dbgc.frag_size = sizeof(struct btintel_pcie_dbgc_ctxt);
+
+	db_frag.magic_num = BTINTEL_PCIE_MAGIC_NUM;
+	db_frag.ver = BTINTEL_PCIE_DBGC_FRAG_VERSION;
+	db_frag.total_size = BTINTEL_PCIE_DBGC_FRAG_PAYLOAD_SIZE;
+	db_frag.num_buf = BTINTEL_PCIE_DBGC_FRAG_BUFFER_COUNT;
+
+	for (i = 0; i < data->dbgc.count; i++) {
+		buf = &data->dbgc.bufs[i];
+		buf->data_p_addr = data->dbgc.buf_p_addr + i * BTINTEL_PCIE_DBGC_BUFFER_SIZE;
+		buf->data = data->dbgc.buf_v_addr + i * BTINTEL_PCIE_DBGC_BUFFER_SIZE;
+		db_frag.bufs[i].buf_addr_lsb = (u32)(buf->data_p_addr & 0xffffffff);
+		db_frag.bufs[i].buf_addr_msb = (u32)((buf->data_p_addr >> 32) & 0xffffffff);
+		db_frag.bufs[i].buf_size = BTINTEL_PCIE_DBGC_BUFFER_SIZE;
+	}
+
+	memcpy(data->dbgc.frag_v_addr, &db_frag, sizeof(db_frag));
+	return 0;
+}
+
 static inline void ipc_print_ia_ring(struct hci_dev *hdev, struct ia *ia,
 				     u16 queue_num)
 {
@@ -1008,6 +1087,11 @@  static void btintel_pcie_init_ci(struct btintel_pcie_data *data,
 	ci->addr_urbdq1 = data->rxq.urbd1s_p_addr;
 	ci->num_urbdq1 = data->rxq.count;
 	ci->urbdq_db_vec = BTINTEL_PCIE_RXQ_NUM;
+
+	ci->dbg_output_mode = 0x01;
+	ci->dbgc_addr = data->dbgc.frag_p_addr;
+	ci->dbgc_size = data->dbgc.frag_size;
+	ci->dbg_preset = 0x00;
 }
 
 static void btintel_pcie_free_txq_bufs(struct btintel_pcie_data *data,
@@ -1220,6 +1304,11 @@  static int btintel_pcie_alloc(struct btintel_pcie_data *data)
 	/* Setup Index Array */
 	btintel_pcie_setup_ia(data, p_addr, v_addr, &data->ia);
 
+	/* Setup data buffers for dbgc */
+	err = btintel_pcie_setup_dbgc(data);
+	if (err)
+		goto exit_error_txq;
+
 	/* Setup Context Information */
 	p_addr += sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4;
 	v_addr += sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4;
diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h
index f9aada0543c4..b9d32393002b 100644
--- a/drivers/bluetooth/btintel_pcie.h
+++ b/drivers/bluetooth/btintel_pcie.h
@@ -48,6 +48,21 @@ 
 #define BTINTEL_PCIE_CSR_MSIX_IVAR_BASE		(BTINTEL_PCIE_CSR_MSIX_BASE + 0x0880)
 #define BTINTEL_PCIE_CSR_MSIX_IVAR(cause)	(BTINTEL_PCIE_CSR_MSIX_IVAR_BASE + (cause))
 
+/* The DRAM buffer count, each buffer size, and
+ * fragment buffer size
+ */
+#define BTINTEL_PCIE_DBGC_BUFFER_COUNT		16
+#define BTINTEL_PCIE_DBGC_BUFFER_SIZE		(256 * 1024) /* 256 KB */
+
+#define BTINTEL_PCIE_DBGC_FRAG_VERSION		1
+#define BTINTEL_PCIE_DBGC_FRAG_BUFFER_COUNT	BTINTEL_PCIE_DBGC_BUFFER_COUNT
+
+/* Magic number(4), version(4), size of payload length(4) */
+#define BTINTEL_PCIE_DBGC_FRAG_HEADER_SIZE	12
+
+/* Num of alloc Dbg buff (4) + (LSB(4), MSB(4), Size(4)) for each buffer */
+#define BTINTEL_PCIE_DBGC_FRAG_PAYLOAD_SIZE	196
+
 /* Causes for the FH register interrupts */
 enum msix_fh_int_causes {
 	BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0	= BIT(0),	/* cause 0 */
@@ -325,6 +340,22 @@  struct rxq {
 	struct data_buf	*bufs;
 };
 
+/* Structure for DRAM Buffer
+ * @count: Number of descriptors
+ * @buf: Array of data_buf structure
+ */
+struct btintel_pcie_dbgc {
+	u16		count;
+
+	void		*frag_v_addr;
+	dma_addr_t	frag_p_addr;
+	u16		frag_size;
+
+	dma_addr_t	buf_p_addr;
+	void		*buf_v_addr;
+	struct data_buf *bufs;
+};
+
 /* struct btintel_pcie_data
  * @pdev: pci device
  * @hdev: hdev device
@@ -405,6 +436,7 @@  struct btintel_pcie_data {
 	struct txq	txq;
 	struct rxq	rxq;
 	u32	alive_intr_ctxt;
+	struct btintel_pcie_dbgc	dbgc;
 };
 
 static inline u32 btintel_pcie_rd_reg32(struct btintel_pcie_data *data,