]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Bluetooth: btintel_pcie: Align shared DMA memory to 128 bytes
authorKiran K <kiran.k@intel.com>
Tue, 7 Apr 2026 10:02:40 +0000 (15:32 +0530)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Mon, 13 Apr 2026 13:19:42 +0000 (09:19 -0400)
Align each descriptor/index/context region to 128 bytes before
calculating the total DMA pool size. This ensures the memory layout
shared with firmware meets the 128-byte alignment requirement.

The DMA pool alignment is also set to 128 bytes to match the firmware
expectation for all shared structures.

Signed-off-by: Kiran K <kiran.k@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
drivers/bluetooth/btintel_pcie.c
drivers/bluetooth/btintel_pcie.h

index 05f82bc3f0d7839e0a79ff5f9776e31a03533175..8fb3ebe98146b635a9d97a4972cfb3eacbba09b8 100644 (file)
@@ -37,6 +37,8 @@
 
 #define POLL_INTERVAL_US       10
 
+#define BTINTEL_PCIE_DMA_ALIGN_128B    128 /* 128 byte aligned */
+
 /* Intel Bluetooth PCIe device id table */
 static const struct pci_device_id btintel_pcie_table[] = {
        /* BlazarI, Wildcat Lake */
@@ -1751,27 +1753,6 @@ static int btintel_pcie_setup_rxq_bufs(struct btintel_pcie_data *data,
        return 0;
 }
 
-static void btintel_pcie_setup_ia(struct btintel_pcie_data *data,
-                                 dma_addr_t p_addr, void *v_addr,
-                                 struct ia *ia)
-{
-       /* TR Head Index Array */
-       ia->tr_hia_p_addr = p_addr;
-       ia->tr_hia = v_addr;
-
-       /* TR Tail Index Array */
-       ia->tr_tia_p_addr = p_addr + sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES;
-       ia->tr_tia = v_addr + sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES;
-
-       /* CR Head index Array */
-       ia->cr_hia_p_addr = p_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 2);
-       ia->cr_hia = v_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 2);
-
-       /* CR Tail Index Array */
-       ia->cr_tia_p_addr = p_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 3);
-       ia->cr_tia = v_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 3);
-}
-
 static void btintel_pcie_free(struct btintel_pcie_data *data)
 {
        btintel_pcie_free_rxq_bufs(data, &data->rxq);
@@ -1789,13 +1770,16 @@ static int btintel_pcie_alloc(struct btintel_pcie_data *data)
        size_t total;
        dma_addr_t p_addr;
        void *v_addr;
+       size_t tfd_size, frbd_size, ctx_size, ci_size, urbd0_size, urbd1_size;
 
        /* Allocate the chunk of DMA memory for descriptors, index array, and
         * context information, instead of allocating individually.
         * The DMA memory for data buffer is allocated while setting up the
         * each queue.
         *
-        * Total size is sum of the following
+        * Total size is sum of the following and each of the individual sizes
+        * are aligned to 128 bytes before adding up.
+        *
         *  + size of TFD * Number of descriptors in queue
         *  + size of URBD0 * Number of descriptors in queue
         *  + size of FRBD * Number of descriptors in queue
@@ -1803,15 +1787,25 @@ static int btintel_pcie_alloc(struct btintel_pcie_data *data)
         *  + size of index * Number of queues(2) * type of index array(4)
         *  + size of context information
         */
-       total = (sizeof(struct tfd) + sizeof(struct urbd0)) * BTINTEL_PCIE_TX_DESCS_COUNT;
-       total += (sizeof(struct frbd) + sizeof(struct urbd1)) * BTINTEL_PCIE_RX_DESCS_COUNT;
+       tfd_size = ALIGN(sizeof(struct tfd) * BTINTEL_PCIE_TX_DESCS_COUNT,
+                        BTINTEL_PCIE_DMA_ALIGN_128B);
+       urbd0_size = ALIGN(sizeof(struct urbd0) * BTINTEL_PCIE_TX_DESCS_COUNT,
+                          BTINTEL_PCIE_DMA_ALIGN_128B);
 
-       /* Add the sum of size of index array and size of ci struct */
-       total += (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4) + sizeof(struct ctx_info);
+       frbd_size = ALIGN(sizeof(struct frbd) * BTINTEL_PCIE_RX_DESCS_COUNT,
+                         BTINTEL_PCIE_DMA_ALIGN_128B);
+       urbd1_size = ALIGN(sizeof(struct urbd1) * BTINTEL_PCIE_RX_DESCS_COUNT,
+                          BTINTEL_PCIE_DMA_ALIGN_128B);
+
+       ci_size = ALIGN(sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES,
+                       BTINTEL_PCIE_DMA_ALIGN_128B);
+
+       ctx_size = ALIGN(sizeof(struct ctx_info), BTINTEL_PCIE_DMA_ALIGN_128B);
+
+       total = tfd_size + urbd0_size + frbd_size + urbd1_size + ctx_size + ci_size * 4;
 
-       /* Allocate DMA Pool */
        data->dma_pool = dma_pool_create(KBUILD_MODNAME, &data->pdev->dev,
-                                        total, BTINTEL_PCIE_DMA_POOL_ALIGNMENT, 0);
+                                        total, BTINTEL_PCIE_DMA_ALIGN_128B, 0);
        if (!data->dma_pool) {
                err = -ENOMEM;
                goto exit_error;
@@ -1836,29 +1830,29 @@ static int btintel_pcie_alloc(struct btintel_pcie_data *data)
        data->txq.tfds_p_addr = p_addr;
        data->txq.tfds = v_addr;
 
-       p_addr += (sizeof(struct tfd) * BTINTEL_PCIE_TX_DESCS_COUNT);
-       v_addr += (sizeof(struct tfd) * BTINTEL_PCIE_TX_DESCS_COUNT);
+       p_addr += tfd_size;
+       v_addr += tfd_size;
 
        /* Setup urbd0 */
        data->txq.urbd0s_p_addr = p_addr;
        data->txq.urbd0s = v_addr;
 
-       p_addr += (sizeof(struct urbd0) * BTINTEL_PCIE_TX_DESCS_COUNT);
-       v_addr += (sizeof(struct urbd0) * BTINTEL_PCIE_TX_DESCS_COUNT);
+       p_addr += urbd0_size;
+       v_addr += urbd0_size;
 
        /* Setup FRBD*/
        data->rxq.frbds_p_addr = p_addr;
        data->rxq.frbds = v_addr;
 
-       p_addr += (sizeof(struct frbd) * BTINTEL_PCIE_RX_DESCS_COUNT);
-       v_addr += (sizeof(struct frbd) * BTINTEL_PCIE_RX_DESCS_COUNT);
+       p_addr += frbd_size;
+       v_addr += frbd_size;
 
        /* Setup urbd1 */
        data->rxq.urbd1s_p_addr = p_addr;
        data->rxq.urbd1s = v_addr;
 
-       p_addr += (sizeof(struct urbd1) * BTINTEL_PCIE_RX_DESCS_COUNT);
-       v_addr += (sizeof(struct urbd1) * BTINTEL_PCIE_RX_DESCS_COUNT);
+       p_addr += urbd1_size;
+       v_addr += urbd1_size;
 
        /* Setup data buffers for txq */
        err = btintel_pcie_setup_txq_bufs(data, &data->txq);
@@ -1870,8 +1864,29 @@ static int btintel_pcie_alloc(struct btintel_pcie_data *data)
        if (err)
                goto exit_error_txq;
 
-       /* Setup Index Array */
-       btintel_pcie_setup_ia(data, p_addr, v_addr, &data->ia);
+       /* TR Head Index Array */
+       data->ia.tr_hia_p_addr = p_addr;
+       data->ia.tr_hia = v_addr;
+       p_addr += ci_size;
+       v_addr += ci_size;
+
+       /* TR Tail Index Array */
+       data->ia.tr_tia_p_addr = p_addr;
+       data->ia.tr_tia = v_addr;
+       p_addr += ci_size;
+       v_addr += ci_size;
+
+       /* CR Head index Array */
+       data->ia.cr_hia_p_addr = p_addr;
+       data->ia.cr_hia = v_addr;
+       p_addr += ci_size;
+       v_addr += ci_size;
+
+       /* CR Tail Index Array */
+       data->ia.cr_tia_p_addr = p_addr;
+       data->ia.cr_tia = v_addr;
+       p_addr += ci_size;
+       v_addr += ci_size;
 
        /* Setup data buffers for dbgc */
        err = btintel_pcie_setup_dbgc(data);
@@ -1879,9 +1894,6 @@ static int btintel_pcie_alloc(struct btintel_pcie_data *data)
                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;
-
        data->ci = v_addr;
        data->ci_p_addr = p_addr;
 
index e3d941ffef4aa8072d95b68e8ca86d4bde9140bb..3c7bb708362ded4e7168db0b9b3c552b773064c5 100644 (file)
@@ -178,9 +178,6 @@ enum {
 /* The size of DMA buffer for TX and RX in bytes */
 #define BTINTEL_PCIE_BUFFER_SIZE       4096
 
-/* DMA allocation alignment */
-#define BTINTEL_PCIE_DMA_POOL_ALIGNMENT        256
-
 #define BTINTEL_PCIE_TX_WAIT_TIMEOUT_MS                500
 
 /* Doorbell vector for TFD */