From: Kiran K Date: Tue, 7 Apr 2026 10:02:40 +0000 (+0530) Subject: Bluetooth: btintel_pcie: Align shared DMA memory to 128 bytes X-Git-Tag: v7.1-rc1~173^2~12^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9e3d074bb21ddc35374d80bf69c3592cd3d057a2;p=thirdparty%2Fkernel%2Flinux.git Bluetooth: btintel_pcie: Align shared DMA memory to 128 bytes 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 Signed-off-by: Luiz Augusto von Dentz --- diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c index 05f82bc3f0d78..8fb3ebe98146b 100644 --- a/drivers/bluetooth/btintel_pcie.c +++ b/drivers/bluetooth/btintel_pcie.c @@ -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; diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h index e3d941ffef4aa..3c7bb708362de 100644 --- a/drivers/bluetooth/btintel_pcie.h +++ b/drivers/bluetooth/btintel_pcie.h @@ -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 */