brintos

brintos / linux-shallow public Read only

0
0
Text · 4.1 KiB · ff5b80b Raw
126 lines · c
1/*2 * Copyright (c) 2010 Broadcom Corporation3 *4 * Permission to use, copy, modify, and/or distribute this software for any5 * purpose with or without fee is hereby granted, provided that the above6 * copyright notice and this permission notice appear in all copies.7 *8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.15 */16 17#ifndef	_BRCM_DMA_H_18#define	_BRCM_DMA_H_19 20#include <linux/delay.h>21#include <linux/skbuff.h>22#include "types.h"		/* forward structure declarations */23 24/* map/unmap direction */25#define	DMA_TX	1		/* TX direction for DMA */26#define	DMA_RX	2		/* RX direction for DMA */27 28/* DMA structure:29 *  support two DMA engines: 32 bits address or 64 bit addressing30 *  basic DMA register set is per channel(transmit or receive)31 *  a pair of channels is defined for convenience32 */33 34/* 32 bits addressing */35 36struct dma32diag {	/* diag access */37	u32 fifoaddr;	/* diag address */38	u32 fifodatalow;	/* low 32bits of data */39	u32 fifodatahigh;	/* high 32bits of data */40	u32 pad;		/* reserved */41};42 43/* 64 bits addressing */44 45/* dma registers per channel(xmt or rcv) */46struct dma64regs {47	u32 control;	/* enable, et al */48	u32 ptr;	/* last descriptor posted to chip */49	u32 addrlow;	/* desc ring base address low 32-bits (8K aligned) */50	u32 addrhigh;	/* desc ring base address bits 63:32 (8K aligned) */51	u32 status0;	/* current descriptor, xmt state */52	u32 status1;	/* active descriptor, xmt error */53};54 55/* range param for dma_getnexttxp() and dma_txreclaim */56enum txd_range {57	DMA_RANGE_ALL = 1,58	DMA_RANGE_TRANSMITTED,59	DMA_RANGE_TRANSFERED60};61 62/*63 * Exported data structure (read-only)64 */65/* export structure */66struct dma_pub {67	uint txavail;		/* # free tx descriptors */68	uint dmactrlflags;	/* dma control flags */69 70	/* rx error counters */71	uint rxgiants;		/* rx giant frames */72	uint rxnobuf;		/* rx out of dma descriptors */73	/* tx error counters */74	uint txnobuf;		/* tx out of dma descriptors */75};76 77extern struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,78				  uint txregbase, uint rxregbase,79				  uint ntxd, uint nrxd,80				  uint rxbufsize, int rxextheadroom,81				  uint nrxpost, uint rxoffset);82 83void dma_rxinit(struct dma_pub *pub);84int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list);85bool dma_rxfill(struct dma_pub *pub);86bool dma_rxreset(struct dma_pub *pub);87bool dma_txreset(struct dma_pub *pub);88void dma_txinit(struct dma_pub *pub);89int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,90	       struct sk_buff *p0);91void dma_txflush(struct dma_pub *pub);92int dma_txpending(struct dma_pub *pub);93void dma_kick_tx(struct dma_pub *pub);94void dma_txsuspend(struct dma_pub *pub);95bool dma_txsuspended(struct dma_pub *pub);96void dma_txresume(struct dma_pub *pub);97void dma_txreclaim(struct dma_pub *pub, enum txd_range range);98void dma_rxreclaim(struct dma_pub *pub);99void dma_detach(struct dma_pub *pub);100unsigned long dma_getvar(struct dma_pub *pub, const char *name);101struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range);102void dma_counterreset(struct dma_pub *pub);103 104void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)105		      (void *pkt, void *arg_a), void *arg_a);106 107/*108 * DMA(Bug) on bcm47xx chips seems to declare that the packet is ready, but109 * the packet length is not updated yet (by DMA) on the expected time.110 * Workaround is to hold processor till DMA updates the length, and stay off111 * the bus to allow DMA update the length in buffer112 */113static inline void dma_spin_for_len(uint len, struct sk_buff *head)114{115#if defined(CONFIG_BCM47XX)116	if (!len) {117		while (!(len = *(u16 *) KSEG1ADDR(head->data)))118			udelay(1);119 120		*(u16 *) (head->data) = cpu_to_le16((u16) len);121	}122#endif				/* defined(CONFIG_BCM47XX) */123}124 125#endif				/* _BRCM_DMA_H_ */126