2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <linux/delay.h>
21 #include "types.h" /* forward structure declarations */
24 * support two DMA engines: 32 bits address or 64 bit addressing
25 * basic DMA register set is per channel(transmit or receive)
26 * a pair of channels is defined for convenience
29 /* 32 bits addressing */
31 struct dma32diag { /* diag access */
32 u32 fifoaddr; /* diag address */
33 u32 fifodatalow; /* low 32bits of data */
34 u32 fifodatahigh; /* high 32bits of data */
35 u32 pad; /* reserved */
38 /* 64 bits addressing */
40 /* dma registers per channel(xmt or rcv) */
42 u32 control; /* enable, et al */
43 u32 ptr; /* last descriptor posted to chip */
44 u32 addrlow; /* desc ring base address low 32-bits (8K aligned) */
45 u32 addrhigh; /* desc ring base address bits 63:32 (8K aligned) */
46 u32 status0; /* current descriptor, xmt state */
47 u32 status1; /* active descriptor, xmt error */
50 /* map/unmap direction */
51 #define DMA_TX 1 /* TX direction for DMA */
52 #define DMA_RX 2 /* RX direction for DMA */
53 #define BUS_SWAP32(v) (v)
55 /* range param for dma_getnexttxp() and dma_txreclaim */
58 DMA_RANGE_TRANSMITTED,
64 void (*detach)(struct dma_pub *dmah);
65 void (*txinit)(struct dma_pub *dmah);
66 bool (*txreset)(struct dma_pub *dmah);
67 bool (*txenabled)(struct dma_pub *dmah);
68 void (*txsuspend)(struct dma_pub *dmah);
69 void (*txresume)(struct dma_pub *dmah);
70 bool (*txsuspended)(struct dma_pub *dmah);
71 bool (*txsuspendedidle)(struct dma_pub *dmah);
72 int (*txfast)(struct dma_pub *dmah, struct sk_buff *p, bool commit);
73 int (*txunframed)(struct dma_pub *dmah, void *p, uint len, bool commit);
75 void *(*getpos)(struct dma_pub *di, bool direction);
76 bool (*txstopped)(struct dma_pub *dmah);
77 void (*txreclaim)(struct dma_pub *dmah, enum txd_range range);
78 void *(*getnexttxp)(struct dma_pub *dmah, enum txd_range range);
79 void *(*peeknexttxp) (struct dma_pub *dmah);
80 void (*txblock) (struct dma_pub *dmah);
81 void (*txunblock) (struct dma_pub *dmah);
82 uint (*txactive)(struct dma_pub *dmah);
83 void (*txrotate) (struct dma_pub *dmah);
85 void (*rxinit)(struct dma_pub *dmah);
86 bool (*rxreset)(struct dma_pub *dmah);
87 bool (*rxidle)(struct dma_pub *dmah);
88 bool (*rxstopped)(struct dma_pub *dmah);
89 bool (*rxenable)(struct dma_pub *dmah);
90 bool (*rxenabled)(struct dma_pub *dmah);
91 void *(*rx)(struct dma_pub *dmah);
92 bool (*rxfill)(struct dma_pub *dmah);
93 void (*rxreclaim)(struct dma_pub *dmah);
94 void *(*getnextrxp)(struct dma_pub *dmah, bool forceall);
95 void *(*peeknextrxp)(struct dma_pub *dmah);
96 void (*rxparam_get)(struct dma_pub *dmah, u16 *rxoffset,
99 void (*fifoloopbackenable)(struct dma_pub *dmah);
100 unsigned long (*d_getvar)(struct dma_pub *dmah, const char *name);
102 void (*counterreset)(struct dma_pub *dmah);
103 uint (*ctrlflags)(struct dma_pub *dmah, uint mask, uint flags);
104 char *(*dump)(struct dma_pub *dmah, struct brcmu_strbuf *b,
106 char *(*dumptx)(struct dma_pub *dmah, struct brcmu_strbuf *b,
108 char *(*dumprx)(struct dma_pub *dmah, struct brcmu_strbuf *b,
110 uint (*rxactive)(struct dma_pub *dmah);
111 uint (*txpending)(struct dma_pub *dmah);
112 uint (*txcommitted)(struct dma_pub *dmah);
117 * Exported data structure (read-only)
119 /* export structure */
121 const struct di_fcn_s *di_fn; /* DMA function pointers */
122 uint txavail; /* # free tx descriptors */
123 uint dmactrlflags; /* dma control flags */
125 /* rx error counters */
126 uint rxgiants; /* rx giant frames */
127 uint rxnobuf; /* rx out of dma descriptors */
128 /* tx error counters */
129 uint txnobuf; /* tx out of dma descriptors */
132 extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
133 void *dmaregstx, void *dmaregsrx, uint ntxd,
134 uint nrxd, uint rxbufsize, int rxextheadroom,
135 uint nrxpost, uint rxoffset, uint *msg_level);
137 extern const struct di_fcn_s dma64proc;
139 #define dma_detach(di) (dma64proc.detach(di))
140 #define dma_txreset(di) (dma64proc.txreset(di))
141 #define dma_rxreset(di) (dma64proc.rxreset(di))
142 #define dma_rxidle(di) (dma64proc.rxidle(di))
143 #define dma_txinit(di) (dma64proc.txinit(di))
144 #define dma_txenabled(di) (dma64proc.txenabled(di))
145 #define dma_rxinit(di) (dma64proc.rxinit(di))
146 #define dma_txsuspend(di) (dma64proc.txsuspend(di))
147 #define dma_txresume(di) (dma64proc.txresume(di))
148 #define dma_txsuspended(di) (dma64proc.txsuspended(di))
149 #define dma_txsuspendedidle(di) (dma64proc.txsuspendedidle(di))
150 #define dma_txfast(di, p, commit) (dma64proc.txfast(di, p, commit))
151 #define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit))
152 #define dma_getpos(di, dir) (dma64proc.getpos(di, dir))
153 #define dma_fifoloopbackenable(di) (dma64proc.fifoloopbackenable(di))
154 #define dma_txstopped(di) (dma64proc.txstopped(di))
155 #define dma_rxstopped(di) (dma64proc.rxstopped(di))
156 #define dma_rxenable(di) (dma64proc.rxenable(di))
157 #define dma_rxenabled(di) (dma64proc.rxenabled(di))
158 #define dma_rx(di) (dma64proc.rx(di))
159 #define dma_rxfill(di) (dma64proc.rxfill(di))
160 #define dma_txreclaim(di, range) (dma64proc.txreclaim(di, range))
161 #define dma_rxreclaim(di) (dma64proc.rxreclaim(di))
162 #define dma_getvar(di, name) (dma64proc.d_getvar(di, name))
163 #define dma_getnexttxp(di, range) (dma64proc.getnexttxp(di, range))
164 #define dma_getnextrxp(di, forceall) (dma64proc.getnextrxp(di, forceall))
165 #define dma_peeknexttxp(di) (dma64proc.peeknexttxp(di))
166 #define dma_peeknextrxp(di) (dma64proc.peeknextrxp(di))
167 #define dma_rxparam_get(di, off, bufs) (dma64proc.rxparam_get(di, off, bufs))
169 #define dma_txblock(di) (dma64proc.txblock(di))
170 #define dma_txunblock(di) (dma64proc.txunblock(di))
171 #define dma_txactive(di) (dma64proc.txactive(di))
172 #define dma_rxactive(di) (dma64proc.rxactive(di))
173 #define dma_txrotate(di) (dma64proc.txrotate(di))
174 #define dma_counterreset(di) (dma64proc.counterreset(di))
175 #define dma_ctrlflags(di, mask, flags) \
176 (dma64proc.ctrlflags((di), (mask), (flags)))
177 #define dma_txpending(di) (dma64proc.txpending(di))
178 #define dma_txcommitted(di) (dma64proc.txcommitted(di))
181 void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
182 (void *pkt, void *arg_a), void *arg_a);
185 * DMA(Bug) on some chips seems to declare that the packet is ready, but the
186 * packet length is not updated yet (by DMA) on the expected time.
187 * Workaround is to hold processor till DMA updates the length, and stay off
188 * the bus to allow DMA update the length in buffer
190 static inline void dma_spin_for_len(uint len, struct sk_buff *head)
192 #if defined(__mips__)
194 while (!(len = *(u16 *) KSEG1ADDR(head->data)))
197 *(u16 *) (head->data) = cpu_to_le16((u16) len);
199 #endif /* defined(__mips__) */
202 #endif /* _BRCM_DMA_H_ */