1/*
2 * Generic Broadcom Home Networking Division (HND) DMA engine SW interface
3 * This supports the following chips: BCM42xx, 44xx, 47xx .
4 *
5 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 * $Id: hnddma.h 456077 2014-02-17 20:17:52Z $
20 */
21
22#ifndef	_hnddma_h_
23#define	_hnddma_h_
24
25#ifndef _hnddma_pub_
26#define _hnddma_pub_
27/* for pktpool_t */
28#include <bcmutils.h>
29
30typedef const struct hnddma_pub hnddma_t;
31#endif /* _hnddma_pub_ */
32
33/* range param for dma_getnexttxp() and dma_txreclaim */
34typedef enum txd_range {
35	HNDDMA_RANGE_ALL		= 1,
36	HNDDMA_RANGE_TRANSMITTED,
37	HNDDMA_RANGE_TRANSFERED
38} txd_range_t;
39
40/* dma parameters id */
41enum dma_param_id {
42	HNDDMA_PID_TX_MULTI_OUTSTD_RD	= 0,
43	HNDDMA_PID_TX_PREFETCH_CTL,
44	HNDDMA_PID_TX_PREFETCH_THRESH,
45	HNDDMA_PID_TX_BURSTLEN,
46
47	HNDDMA_PID_RX_PREFETCH_CTL	= 0x100,
48	HNDDMA_PID_RX_PREFETCH_THRESH,
49	HNDDMA_PID_RX_BURSTLEN,
50	HNDDMA_PID_BURSTLEN_CAP,
51	HNDDMA_PID_BURSTLEN_WAR,
52	HNDDMA_SEP_RX_HDR
53};
54
55/* dma function type */
56typedef void (*di_detach_t)(hnddma_t *dmah);
57typedef bool (*di_txreset_t)(hnddma_t *dmah);
58typedef bool (*di_rxreset_t)(hnddma_t *dmah);
59typedef bool (*di_rxidle_t)(hnddma_t *dmah);
60typedef void (*di_txinit_t)(hnddma_t *dmah);
61typedef bool (*di_txenabled_t)(hnddma_t *dmah);
62typedef void (*di_rxinit_t)(hnddma_t *dmah);
63typedef void (*di_txsuspend_t)(hnddma_t *dmah);
64typedef void (*di_txresume_t)(hnddma_t *dmah);
65typedef bool (*di_txsuspended_t)(hnddma_t *dmah);
66typedef bool (*di_txsuspendedidle_t)(hnddma_t *dmah);
67#ifdef WL_MULTIQUEUE
68typedef void (*di_txflush_t)(hnddma_t *dmah);
69typedef void (*di_txflush_clear_t)(hnddma_t *dmah);
70#endif /* WL_MULTIQUEUE */
71typedef int (*di_txfast_t)(hnddma_t *dmah, void *p, bool commit);
72typedef int (*di_txunframed_t)(hnddma_t *dmah, void *p, uint len, bool commit);
73typedef void* (*di_getpos_t)(hnddma_t *di, bool direction);
74typedef void (*di_fifoloopbackenable_t)(hnddma_t *dmah);
75typedef bool  (*di_txstopped_t)(hnddma_t *dmah);
76typedef bool  (*di_rxstopped_t)(hnddma_t *dmah);
77typedef bool  (*di_rxenable_t)(hnddma_t *dmah);
78typedef bool  (*di_rxenabled_t)(hnddma_t *dmah);
79typedef void* (*di_rx_t)(hnddma_t *dmah);
80typedef bool (*di_rxfill_t)(hnddma_t *dmah);
81typedef void (*di_txreclaim_t)(hnddma_t *dmah, txd_range_t range);
82typedef void (*di_rxreclaim_t)(hnddma_t *dmah);
83typedef	uintptr	(*di_getvar_t)(hnddma_t *dmah, const char *name);
84typedef void* (*di_getnexttxp_t)(hnddma_t *dmah, txd_range_t range);
85typedef void* (*di_getnextrxp_t)(hnddma_t *dmah, bool forceall);
86typedef void* (*di_peeknexttxp_t)(hnddma_t *dmah);
87typedef void* (*di_peekntxp_t)(hnddma_t *dmah, int *len, void *txps[], txd_range_t range);
88typedef void* (*di_peeknextrxp_t)(hnddma_t *dmah);
89typedef void (*di_rxparam_get_t)(hnddma_t *dmah, uint16 *rxoffset, uint16 *rxbufsize);
90typedef void (*di_txblock_t)(hnddma_t *dmah);
91typedef void (*di_txunblock_t)(hnddma_t *dmah);
92typedef uint (*di_txactive_t)(hnddma_t *dmah);
93typedef void (*di_txrotate_t)(hnddma_t *dmah);
94typedef void (*di_counterreset_t)(hnddma_t *dmah);
95typedef uint (*di_ctrlflags_t)(hnddma_t *dmah, uint mask, uint flags);
96typedef char* (*di_dump_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring);
97typedef char* (*di_dumptx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring);
98typedef char* (*di_dumprx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring);
99typedef uint (*di_rxactive_t)(hnddma_t *dmah);
100typedef uint (*di_txpending_t)(hnddma_t *dmah);
101typedef uint (*di_txcommitted_t)(hnddma_t *dmah);
102typedef int (*di_pktpool_set_t)(hnddma_t *dmah, pktpool_t *pool);
103typedef bool (*di_rxtxerror_t)(hnddma_t *dmah, bool istx);
104typedef void (*di_burstlen_set_t)(hnddma_t *dmah, uint8 rxburstlen, uint8 txburstlen);
105typedef uint (*di_avoidancecnt_t)(hnddma_t *dmah);
106typedef void (*di_param_set_t)(hnddma_t *dmah, uint16 paramid, uint16 paramval);
107typedef bool (*dma_glom_enable_t) (hnddma_t *dmah, uint32 val);
108typedef uint (*dma_active_rxbuf_t) (hnddma_t *dmah);
109/* dma opsvec */
110typedef struct di_fcn_s {
111	di_detach_t		detach;
112	di_txinit_t             txinit;
113	di_txreset_t		txreset;
114	di_txenabled_t          txenabled;
115	di_txsuspend_t          txsuspend;
116	di_txresume_t           txresume;
117	di_txsuspended_t        txsuspended;
118	di_txsuspendedidle_t    txsuspendedidle;
119#ifdef WL_MULTIQUEUE
120	di_txflush_t            txflush;
121	di_txflush_clear_t      txflush_clear;
122#endif /* WL_MULTIQUEUE */
123	di_txfast_t             txfast;
124	di_txunframed_t         txunframed;
125	di_getpos_t             getpos;
126	di_txstopped_t		txstopped;
127	di_txreclaim_t          txreclaim;
128	di_getnexttxp_t         getnexttxp;
129	di_peeknexttxp_t        peeknexttxp;
130	di_peekntxp_t           peekntxp;
131	di_txblock_t            txblock;
132	di_txunblock_t          txunblock;
133	di_txactive_t           txactive;
134	di_txrotate_t           txrotate;
135
136	di_rxinit_t             rxinit;
137	di_rxreset_t            rxreset;
138	di_rxidle_t             rxidle;
139	di_rxstopped_t		rxstopped;
140	di_rxenable_t		rxenable;
141	di_rxenabled_t		rxenabled;
142	di_rx_t                 rx;
143	di_rxfill_t             rxfill;
144	di_rxreclaim_t          rxreclaim;
145	di_getnextrxp_t         getnextrxp;
146	di_peeknextrxp_t        peeknextrxp;
147	di_rxparam_get_t	rxparam_get;
148
149	di_fifoloopbackenable_t fifoloopbackenable;
150	di_getvar_t             d_getvar;
151	di_counterreset_t       counterreset;
152	di_ctrlflags_t          ctrlflags;
153	di_dump_t		dump;
154	di_dumptx_t		dumptx;
155	di_dumprx_t		dumprx;
156	di_rxactive_t		rxactive;
157	di_txpending_t		txpending;
158	di_txcommitted_t	txcommitted;
159	di_pktpool_set_t	pktpool_set;
160	di_rxtxerror_t		rxtxerror;
161	di_burstlen_set_t	burstlen_set;
162	di_avoidancecnt_t	avoidancecnt;
163	di_param_set_t		param_set;
164	dma_glom_enable_t	glom_enab;
165	dma_active_rxbuf_t	dma_activerxbuf;
166	uint			endnum;
167} di_fcn_t;
168
169/*
170 * Exported data structure (read-only)
171 */
172/* export structure */
173struct hnddma_pub {
174	const di_fcn_t	*di_fn;		/* DMA function pointers */
175	uint		txavail;	/* # free tx descriptors */
176	uint		dmactrlflags;	/* dma control flags */
177
178	/* rx error counters */
179	uint		rxgiants;	/* rx giant frames */
180	uint		rxnobuf;	/* rx out of dma descriptors */
181	/* tx error counters */
182	uint		txnobuf;	/* tx out of dma descriptors */
183	uint		txnodesc;	/* tx out of dma descriptors running count */
184};
185#ifdef PCIE_PHANTOM_DEV
186extern int dma_blwar_alloc(hnddma_t *di);
187#endif
188extern hnddma_t * dma_attach(osl_t *osh, const char *name, si_t *sih,
189	volatile void *dmaregstx, volatile void *dmaregsrx,
190	uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost,
191	uint rxoffset, uint *msg_level);
192#ifdef BCMDMA32
193
194#define dma_detach(di)			((di)->di_fn->detach(di))
195#define dma_txreset(di)			((di)->di_fn->txreset(di))
196#define dma_rxreset(di)			((di)->di_fn->rxreset(di))
197#define dma_rxidle(di)			((di)->di_fn->rxidle(di))
198#define dma_txinit(di)                  ((di)->di_fn->txinit(di))
199#define dma_txenabled(di)               ((di)->di_fn->txenabled(di))
200#define dma_rxinit(di)                  ((di)->di_fn->rxinit(di))
201#define dma_txsuspend(di)               ((di)->di_fn->txsuspend(di))
202#define dma_txresume(di)                ((di)->di_fn->txresume(di))
203#define dma_txsuspended(di)             ((di)->di_fn->txsuspended(di))
204#define dma_txsuspendedidle(di)         ((di)->di_fn->txsuspendedidle(di))
205#ifdef WL_MULTIQUEUE
206#define dma_txflush(di)                 ((di)->di_fn->txflush(di))
207#define dma_txflush_clear(di)           ((di)->di_fn->txflush_clear(di))
208#endif /* WL_MULTIQUEUE */
209#define dma_txfast(di, p, commit)	((di)->di_fn->txfast(di, p, commit))
210#define dma_txfast(di, p, commit)		((di)->di_fn->txfast(di, p, commit))
211#define dma_fifoloopbackenable(di)      ((di)->di_fn->fifoloopbackenable(di))
212#define dma_fifoloopbackenable(di)      ((di)->di_fn->fifoloopbackenable(di))
213#define dma_txstopped(di)               ((di)->di_fn->txstopped(di))
214#define dma_rxstopped(di)               ((di)->di_fn->rxstopped(di))
215#define dma_rxenable(di)                ((di)->di_fn->rxenable(di))
216#define dma_rxenabled(di)               ((di)->di_fn->rxenabled(di))
217#define dma_rx(di)                      ((di)->di_fn->rx(di))
218#define dma_rxfill(di)                  ((di)->di_fn->rxfill(di))
219#define dma_txreclaim(di, range)	((di)->di_fn->txreclaim(di, range))
220#define dma_rxreclaim(di)               ((di)->di_fn->rxreclaim(di))
221#define dma_getvar(di, name)		((di)->di_fn->d_getvar(di, name))
222#define dma_getnexttxp(di, range)	((di)->di_fn->getnexttxp(di, range))
223#define dma_getnextrxp(di, forceall)    ((di)->di_fn->getnextrxp(di, forceall))
224#define dma_peeknexttxp(di)             ((di)->di_fn->peeknexttxp(di))
225#define dma_peekntxp(di, l, t, r)       ((di)->di_fn->peekntxp(di, l, t, r))
226#define dma_peeknextrxp(di)             ((di)->di_fn->peeknextrxp(di))
227#define dma_rxparam_get(di, off, bufs)	((di)->di_fn->rxparam_get(di, off, bufs))
228
229#define dma_txblock(di)                 ((di)->di_fn->txblock(di))
230#define dma_txunblock(di)               ((di)->di_fn->txunblock(di))
231#define dma_txactive(di)                ((di)->di_fn->txactive(di))
232#define dma_rxactive(di)                ((di)->di_fn->rxactive(di))
233#define dma_txrotate(di)                ((di)->di_fn->txrotate(di))
234#define dma_counterreset(di)            ((di)->di_fn->counterreset(di))
235#define dma_ctrlflags(di, mask, flags)  ((di)->di_fn->ctrlflags((di), (mask), (flags)))
236#define dma_txpending(di)		((di)->di_fn->txpending(di))
237#define dma_txcommitted(di)		((di)->di_fn->txcommitted(di))
238#define dma_pktpool_set(di, pool)	((di)->di_fn->pktpool_set((di), (pool)))
239#if defined(BCMDBG_DUMP)
240#define dma_dump(di, buf, dumpring)	((di)->di_fn->dump(di, buf, dumpring))
241#define dma_dumptx(di, buf, dumpring)	((di)->di_fn->dumptx(di, buf, dumpring))
242#define dma_dumprx(di, buf, dumpring)	((di)->di_fn->dumprx(di, buf, dumpring))
243#endif
244#define dma_rxtxerror(di, istx)	((di)->di_fn->rxtxerror(di, istx))
245#define dma_burstlen_set(di, rxlen, txlen)	((di)->di_fn->burstlen_set(di, rxlen, txlen))
246#define dma_avoidance_cnt(di)		((di)->di_fn->avoidancecnt(di))
247#define dma_param_set(di, paramid, paramval)	((di)->di_fn->param_set(di, paramid, paramval))
248#define dma_activerxbuf(di)		((di)->di_fn->dma_activerxbuf(di))
249
250#define dma_glom_enable(di, val)	(0)
251
252#else /* BCMDMA32 */
253extern const di_fcn_t dma64proc;
254
255#define dma_detach(di)			(dma64proc.detach(di))
256#define dma_txreset(di)			(dma64proc.txreset(di))
257#define dma_rxreset(di)			(dma64proc.rxreset(di))
258#define dma_rxidle(di)			(dma64proc.rxidle(di))
259#define dma_txinit(di)                  (dma64proc.txinit(di))
260#define dma_txenabled(di)               (dma64proc.txenabled(di))
261#define dma_rxinit(di)                  (dma64proc.rxinit(di))
262#define dma_txsuspend(di)               (dma64proc.txsuspend(di))
263#define dma_txresume(di)                (dma64proc.txresume(di))
264#define dma_txsuspended(di)             (dma64proc.txsuspended(di))
265#define dma_txsuspendedidle(di)         (dma64proc.txsuspendedidle(di))
266#ifdef WL_MULTIQUEUE
267#define dma_txflush(di)                 (dma64proc.txflush(di))
268#define dma_txflush_clear(di)           (dma64proc.txflush_clear(di))
269#endif /* WL_MULTIQUEUE */
270#define dma_txfast(di, p, commit)	(dma64proc.txfast(di, p, commit))
271#define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit))
272#define dma_getpos(di, dir)		(dma64proc.getpos(di, dir))
273#define dma_fifoloopbackenable(di)      (dma64proc.fifoloopbackenable(di))
274#define dma_txstopped(di)               (dma64proc.txstopped(di))
275#define dma_rxstopped(di)               (dma64proc.rxstopped(di))
276#define dma_rxenable(di)                (dma64proc.rxenable(di))
277#define dma_rxenabled(di)               (dma64proc.rxenabled(di))
278#define dma_rx(di)                      (dma64proc.rx(di))
279#define dma_rxfill(di)                  (dma64proc.rxfill(di))
280#define dma_txreclaim(di, range)	(dma64proc.txreclaim(di, range))
281#define dma_rxreclaim(di)               (dma64proc.rxreclaim(di))
282#define dma_getvar(di, name)		(dma64proc.d_getvar(di, name))
283#define dma_getnexttxp(di, range)	(dma64proc.getnexttxp(di, range))
284#define dma_getnextrxp(di, forceall)    (dma64proc.getnextrxp(di, forceall))
285#define dma_peeknexttxp(di)             (dma64proc.peeknexttxp(di))
286#define dma_peekntxp(di, l, t, r)       (dma64proc.peekntxp(di, l, t, r))
287#define dma_peeknextrxp(di)             (dma64proc.peeknextrxp(di))
288#define dma_rxparam_get(di, off, bufs)	(dma64proc.rxparam_get(di, off, bufs))
289
290#define dma_txblock(di)                 (dma64proc.txblock(di))
291#define dma_txunblock(di)               (dma64proc.txunblock(di))
292#define dma_txactive(di)                (dma64proc.txactive(di))
293#define dma_rxactive(di)                (dma64proc.rxactive(di))
294#define dma_txrotate(di)                (dma64proc.txrotate(di))
295#define dma_counterreset(di)            (dma64proc.counterreset(di))
296#define dma_ctrlflags(di, mask, flags)  (dma64proc.ctrlflags((di), (mask), (flags)))
297#define dma_txpending(di)		(dma64proc.txpending(di))
298#define dma_txcommitted(di)		(dma64proc.txcommitted(di))
299#define dma_pktpool_set(di, pool)	(dma64proc.pktpool_set((di), (pool)))
300#if defined(BCMDBG_DUMP)
301#define dma_dump(di, buf, dumpring)	(dma64proc.dump(di, buf, dumpring))
302#define dma_dumptx(di, buf, dumpring)	(dma64proc.dumptx(di, buf, dumpring))
303#define dma_dumprx(di, buf, dumpring)	(dma64proc.dumprx(di, buf, dumpring))
304#endif
305#define dma_rxtxerror(di, istx)	(dma64proc.rxtxerror(di, istx))
306#define dma_burstlen_set(di, rxlen, txlen)	(dma64proc.burstlen_set(di, rxlen, txlen))
307#define dma_avoidance_cnt(di)		(dma64proc.avoidancecnt(di))
308#define dma_param_set(di, paramid, paramval)	(dma64proc.param_set(di, paramid, paramval))
309
310#define dma_glom_enable(di, val)	(dma64proc.glom_enab(di, val))
311#define dma_activerxbuf(di)	(dma64proc.dma_activerxbuf(di))
312
313#endif /* BCMDMA32 */
314
315/* return addresswidth allowed
316 * This needs to be done after SB attach but before dma attach.
317 * SB attach provides ability to probe backplane and dma core capabilities
318 * This info is needed by DMA_ALLOC_CONSISTENT in dma attach
319 */
320extern uint dma_addrwidth(si_t *sih, void *dmaregs);
321
322#ifdef WL_MULTIQUEUE
323extern void dma_txrewind(hnddma_t *di);
324#endif
325
326/* pio helpers */
327extern void dma_txpioloopback(osl_t *osh, dma32regs_t *);
328extern int dma_msgbuf_txfast(hnddma_t *di, dma64addr_t p0, bool com, uint32 ln, bool fst, bool lst);
329
330extern int dma_rxfast(hnddma_t *di, dma64addr_t p, uint32 len);
331extern int dma_rxfill_suspend(hnddma_t *dmah, bool suspended);
332#endif	/* _hnddma_h_ */
333