brintos

brintos / linux-shallow public Read only

0
0
Text · 4.2 KiB · a942a63 Raw
172 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright (C) 2023 Intel Corporation */3 4#include "idpf_controlq.h"5 6/**7 * idpf_ctlq_alloc_desc_ring - Allocate Control Queue (CQ) rings8 * @hw: pointer to hw struct9 * @cq: pointer to the specific Control queue10 */11static int idpf_ctlq_alloc_desc_ring(struct idpf_hw *hw,12				     struct idpf_ctlq_info *cq)13{14	size_t size = cq->ring_size * sizeof(struct idpf_ctlq_desc);15 16	cq->desc_ring.va = idpf_alloc_dma_mem(hw, &cq->desc_ring, size);17	if (!cq->desc_ring.va)18		return -ENOMEM;19 20	return 0;21}22 23/**24 * idpf_ctlq_alloc_bufs - Allocate Control Queue (CQ) buffers25 * @hw: pointer to hw struct26 * @cq: pointer to the specific Control queue27 *28 * Allocate the buffer head for all control queues, and if it's a receive29 * queue, allocate DMA buffers30 */31static int idpf_ctlq_alloc_bufs(struct idpf_hw *hw,32				struct idpf_ctlq_info *cq)33{34	int i;35 36	/* Do not allocate DMA buffers for transmit queues */37	if (cq->cq_type == IDPF_CTLQ_TYPE_MAILBOX_TX)38		return 0;39 40	/* We'll be allocating the buffer info memory first, then we can41	 * allocate the mapped buffers for the event processing42	 */43	cq->bi.rx_buff = kcalloc(cq->ring_size, sizeof(struct idpf_dma_mem *),44				 GFP_KERNEL);45	if (!cq->bi.rx_buff)46		return -ENOMEM;47 48	/* allocate the mapped buffers (except for the last one) */49	for (i = 0; i < cq->ring_size - 1; i++) {50		struct idpf_dma_mem *bi;51		int num = 1; /* number of idpf_dma_mem to be allocated */52 53		cq->bi.rx_buff[i] = kcalloc(num, sizeof(struct idpf_dma_mem),54					    GFP_KERNEL);55		if (!cq->bi.rx_buff[i])56			goto unwind_alloc_cq_bufs;57 58		bi = cq->bi.rx_buff[i];59 60		bi->va = idpf_alloc_dma_mem(hw, bi, cq->buf_size);61		if (!bi->va) {62			/* unwind will not free the failed entry */63			kfree(cq->bi.rx_buff[i]);64			goto unwind_alloc_cq_bufs;65		}66	}67 68	return 0;69 70unwind_alloc_cq_bufs:71	/* don't try to free the one that failed... */72	i--;73	for (; i >= 0; i--) {74		idpf_free_dma_mem(hw, cq->bi.rx_buff[i]);75		kfree(cq->bi.rx_buff[i]);76	}77	kfree(cq->bi.rx_buff);78 79	return -ENOMEM;80}81 82/**83 * idpf_ctlq_free_desc_ring - Free Control Queue (CQ) rings84 * @hw: pointer to hw struct85 * @cq: pointer to the specific Control queue86 *87 * This assumes the posted send buffers have already been cleaned88 * and de-allocated89 */90static void idpf_ctlq_free_desc_ring(struct idpf_hw *hw,91				     struct idpf_ctlq_info *cq)92{93	idpf_free_dma_mem(hw, &cq->desc_ring);94}95 96/**97 * idpf_ctlq_free_bufs - Free CQ buffer info elements98 * @hw: pointer to hw struct99 * @cq: pointer to the specific Control queue100 *101 * Free the DMA buffers for RX queues, and DMA buffer header for both RX and TX102 * queues.  The upper layers are expected to manage freeing of TX DMA buffers103 */104static void idpf_ctlq_free_bufs(struct idpf_hw *hw, struct idpf_ctlq_info *cq)105{106	void *bi;107 108	if (cq->cq_type == IDPF_CTLQ_TYPE_MAILBOX_RX) {109		int i;110 111		/* free DMA buffers for rx queues*/112		for (i = 0; i < cq->ring_size; i++) {113			if (cq->bi.rx_buff[i]) {114				idpf_free_dma_mem(hw, cq->bi.rx_buff[i]);115				kfree(cq->bi.rx_buff[i]);116			}117		}118 119		bi = (void *)cq->bi.rx_buff;120	} else {121		bi = (void *)cq->bi.tx_msg;122	}123 124	/* free the buffer header */125	kfree(bi);126}127 128/**129 * idpf_ctlq_dealloc_ring_res - Free memory allocated for control queue130 * @hw: pointer to hw struct131 * @cq: pointer to the specific Control queue132 *133 * Free the memory used by the ring, buffers and other related structures134 */135void idpf_ctlq_dealloc_ring_res(struct idpf_hw *hw, struct idpf_ctlq_info *cq)136{137	/* free ring buffers and the ring itself */138	idpf_ctlq_free_bufs(hw, cq);139	idpf_ctlq_free_desc_ring(hw, cq);140}141 142/**143 * idpf_ctlq_alloc_ring_res - allocate memory for descriptor ring and bufs144 * @hw: pointer to hw struct145 * @cq: pointer to control queue struct146 *147 * Do *NOT* hold cq_lock when calling this as the memory allocation routines148 * called are not going to be atomic context safe149 */150int idpf_ctlq_alloc_ring_res(struct idpf_hw *hw, struct idpf_ctlq_info *cq)151{152	int err;153 154	/* allocate the ring memory */155	err = idpf_ctlq_alloc_desc_ring(hw, cq);156	if (err)157		return err;158 159	/* allocate buffers in the rings */160	err = idpf_ctlq_alloc_bufs(hw, cq);161	if (err)162		goto idpf_init_cq_free_ring;163 164	/* success! */165	return 0;166 167idpf_init_cq_free_ring:168	idpf_free_dma_mem(hw, &cq->desc_ring);169 170	return err;171}172