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 |
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 --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,