brintos

brintos / linux-shallow public Read only

0
0
Text · 3.5 KiB · e78c359 Raw
147 lines · 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 the138 * 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);147