1*f3bdbd42SAbhijit Gangurde // SPDX-License-Identifier: GPL-2.0 2*f3bdbd42SAbhijit Gangurde /* Copyright (C) 2018-2025, Advanced Micro Devices, Inc. */ 3*f3bdbd42SAbhijit Gangurde 4*f3bdbd42SAbhijit Gangurde #include <linux/dma-mapping.h> 5*f3bdbd42SAbhijit Gangurde 6*f3bdbd42SAbhijit Gangurde #include "ionic_queue.h" 7*f3bdbd42SAbhijit Gangurde 8*f3bdbd42SAbhijit Gangurde int ionic_queue_init(struct ionic_queue *q, struct device *dma_dev, 9*f3bdbd42SAbhijit Gangurde int depth, size_t stride) 10*f3bdbd42SAbhijit Gangurde { 11*f3bdbd42SAbhijit Gangurde if (depth < 0 || depth > 0xffff) 12*f3bdbd42SAbhijit Gangurde return -EINVAL; 13*f3bdbd42SAbhijit Gangurde 14*f3bdbd42SAbhijit Gangurde if (stride == 0 || stride > 0x10000) 15*f3bdbd42SAbhijit Gangurde return -EINVAL; 16*f3bdbd42SAbhijit Gangurde 17*f3bdbd42SAbhijit Gangurde if (depth == 0) 18*f3bdbd42SAbhijit Gangurde depth = 1; 19*f3bdbd42SAbhijit Gangurde 20*f3bdbd42SAbhijit Gangurde q->depth_log2 = order_base_2(depth + 1); 21*f3bdbd42SAbhijit Gangurde q->stride_log2 = order_base_2(stride); 22*f3bdbd42SAbhijit Gangurde 23*f3bdbd42SAbhijit Gangurde if (q->depth_log2 + q->stride_log2 < PAGE_SHIFT) 24*f3bdbd42SAbhijit Gangurde q->depth_log2 = PAGE_SHIFT - q->stride_log2; 25*f3bdbd42SAbhijit Gangurde 26*f3bdbd42SAbhijit Gangurde if (q->depth_log2 > 16 || q->stride_log2 > 16) 27*f3bdbd42SAbhijit Gangurde return -EINVAL; 28*f3bdbd42SAbhijit Gangurde 29*f3bdbd42SAbhijit Gangurde q->size = BIT_ULL(q->depth_log2 + q->stride_log2); 30*f3bdbd42SAbhijit Gangurde q->mask = BIT(q->depth_log2) - 1; 31*f3bdbd42SAbhijit Gangurde 32*f3bdbd42SAbhijit Gangurde q->ptr = dma_alloc_coherent(dma_dev, q->size, &q->dma, GFP_KERNEL); 33*f3bdbd42SAbhijit Gangurde if (!q->ptr) 34*f3bdbd42SAbhijit Gangurde return -ENOMEM; 35*f3bdbd42SAbhijit Gangurde 36*f3bdbd42SAbhijit Gangurde /* it will always be page aligned, but just to be sure... */ 37*f3bdbd42SAbhijit Gangurde if (!PAGE_ALIGNED(q->ptr)) { 38*f3bdbd42SAbhijit Gangurde dma_free_coherent(dma_dev, q->size, q->ptr, q->dma); 39*f3bdbd42SAbhijit Gangurde return -ENOMEM; 40*f3bdbd42SAbhijit Gangurde } 41*f3bdbd42SAbhijit Gangurde 42*f3bdbd42SAbhijit Gangurde q->prod = 0; 43*f3bdbd42SAbhijit Gangurde q->cons = 0; 44*f3bdbd42SAbhijit Gangurde q->dbell = 0; 45*f3bdbd42SAbhijit Gangurde 46*f3bdbd42SAbhijit Gangurde return 0; 47*f3bdbd42SAbhijit Gangurde } 48*f3bdbd42SAbhijit Gangurde 49*f3bdbd42SAbhijit Gangurde void ionic_queue_destroy(struct ionic_queue *q, struct device *dma_dev) 50*f3bdbd42SAbhijit Gangurde { 51*f3bdbd42SAbhijit Gangurde dma_free_coherent(dma_dev, q->size, q->ptr, q->dma); 52*f3bdbd42SAbhijit Gangurde } 53