FILE
fdma_api.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/microchip/fdma/fdma_api.c
1// SPDX-License-Identifier: GPL-2.0+ 2 3#include "fdma_api.h" 4 5#include <linux/bits.h> 6#include <linux/etherdevice.h> 7#include <linux/types.h> 8 9/* Add a DB to a DCB, providing a callback for getting the DB dataptr. */ 10static int __fdma_db_add(struct fdma *fdma, int dcb_idx, int db_idx, u64 status, 11 int (*cb)(struct fdma *fdma, int dcb_idx, 12 int db_idx, u64 *dataptr)) 13{ 14 struct fdma_db *db = fdma_db_get(fdma, dcb_idx, db_idx); 15 16 db->status = status; 17 18 return cb(fdma, dcb_idx, db_idx, &db->dataptr); 19} 20 21/* Add a DB to a DCB, using the callback set in the fdma_ops struct. */ 22int fdma_db_add(struct fdma *fdma, int dcb_idx, int db_idx, u64 status) 23{ 24 return __fdma_db_add(fdma, 25 dcb_idx, 26 db_idx, 27 status, 28 fdma->ops.dataptr_cb); 29} 30 31/* Add a DCB with callbacks for getting the DB dataptr and the DCB nextptr. */ 32int __fdma_dcb_add(struct fdma *fdma, int dcb_idx, u64 info, u64 status, 33 int (*dcb_cb)(struct fdma *fdma, int dcb_idx, u64 *nextptr), 34 int (*db_cb)(struct fdma *fdma, int dcb_idx, int db_idx, 35 u64 *dataptr)) 36{ 37 struct fdma_dcb *dcb = fdma_dcb_get(fdma, dcb_idx); 38 int i, err; 39 40 for (i = 0; i < fdma->n_dbs; i++) { 41 err = __fdma_db_add(fdma, dcb_idx, i, status, db_cb); 42 if (unlikely(err)) 43 return err; 44 } 45 46 err = dcb_cb(fdma, dcb_idx, &fdma->last_dcb->nextptr); 47 if (unlikely(err)) 48 return err; 49 50 fdma->last_dcb = dcb; 51 52 dcb->nextptr = FDMA_DCB_INVALID_DATA; 53 dcb->info = info; 54 55 return 0; 56} 57EXPORT_SYMBOL_GPL(__fdma_dcb_add); 58 59/* Add a DCB, using the preset callbacks in the fdma_ops struct. */ 60int fdma_dcb_add(struct fdma *fdma, int dcb_idx, u64 info, u64 status) 61{ 62 return __fdma_dcb_add(fdma, 63 dcb_idx, 64 info, status, 65 fdma->ops.nextptr_cb, 66 fdma->ops.dataptr_cb); 67} 68EXPORT_SYMBOL_GPL(fdma_dcb_add); 69 70/* Initialize the DCB's and DB's. */ 71int fdma_dcbs_init(struct fdma *fdma, u64 info, u64 status) 72{ 73 int i, err; 74 75 fdma->last_dcb = fdma->dcbs; 76 fdma->db_index = 0; 77 fdma->dcb_index = 0; 78 79 for (i = 0; i < fdma->n_dcbs; i++) { 80 err = fdma_dcb_add(fdma, i, info, status); 81 if (err) 82 return err; 83 } 84 85 return 0; 86} 87EXPORT_SYMBOL_GPL(fdma_dcbs_init); 88 89/* Allocate coherent DMA memory for FDMA. */ 90int fdma_alloc_coherent(struct device *dev, struct fdma *fdma) 91{ 92 fdma->dcbs = dma_alloc_coherent(dev, 93 fdma->size, 94 &fdma->dma, 95 GFP_KERNEL); 96 if (!fdma->dcbs) 97 return -ENOMEM; 98 99 return 0; 100} 101EXPORT_SYMBOL_GPL(fdma_alloc_coherent); 102 103/* Allocate physical memory for FDMA. */ 104int fdma_alloc_phys(struct fdma *fdma) 105{ 106 fdma->dcbs = kzalloc(fdma->size, GFP_KERNEL); 107 if (!fdma->dcbs) 108 return -ENOMEM; 109 110 fdma->dma = virt_to_phys(fdma->dcbs); 111 112 return 0; 113} 114EXPORT_SYMBOL_GPL(fdma_alloc_phys); 115 116/* Free coherent DMA memory. */ 117void fdma_free_coherent(struct device *dev, struct fdma *fdma) 118{ 119 dma_free_coherent(dev, fdma->size, fdma->dcbs, fdma->dma); 120} 121EXPORT_SYMBOL_GPL(fdma_free_coherent); 122 123/* Free virtual memory. */ 124void fdma_free_phys(struct fdma *fdma) 125{ 126 kfree(fdma->dcbs); 127} 128EXPORT_SYMBOL_GPL(fdma_free_phys); 129 130/* Get the size of the FDMA memory */ 131u32 fdma_get_size(struct fdma *fdma) 132{ 133 return ALIGN(sizeof(struct fdma_dcb) * fdma->n_dcbs, PAGE_SIZE); 134} 135EXPORT_SYMBOL_GPL(fdma_get_size); 136 137/* Get the size of the FDMA memory. This function is only applicable if the 138 * dataptr addresses and DCB's are in contiguous memory. 139 */ 140u32 fdma_get_size_contiguous(struct fdma *fdma) 141{ 142 return ALIGN(fdma->n_dcbs * sizeof(struct fdma_dcb) + 143 fdma->n_dcbs * fdma->n_dbs * fdma->db_size, 144 PAGE_SIZE); 145} 146EXPORT_SYMBOL_GPL(fdma_get_size_contiguous);
~/
Read-only file preview.