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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Kiran,

On Fri, Feb 21, 2025 at 9:44 AM Kiran K <kiran.k@xxxxxxxxx> 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@xxxxxxxxx>
> Signed-off-by: Vijay Satija <vijay.satija@xxxxxxxxx>
> Signed-off-by: Kiran K <kiran.k@xxxxxxxxx>
> ---
> 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.

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





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux