Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[pandora-kernel.git] / drivers / staging / brcm80211 / util / hnddma.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
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.
7  *
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.
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/string.h>
19 #include <linuxver.h>
20 #include <bcmdefs.h>
21 #include <bcmdevs.h>
22 #include <osl.h>
23 #include <bcmendian.h>
24 #include <hndsoc.h>
25 #include <bcmutils.h>
26 #include <siutils.h>
27
28 #include <sbhnddma.h>
29 #include <hnddma.h>
30
31 /* debug/trace */
32 #ifdef BCMDBG
33 #define DMA_ERROR(args) \
34         do { \
35                 if (!(*di->msg_level & 1)) \
36                         ; \
37                 else \
38                         printf args; \
39         } while (0)
40 #define DMA_TRACE(args) \
41         do { \
42                 if (!(*di->msg_level & 2)) \
43                         ; \
44                 else \
45                         printf args; \
46         } while (0)
47 #else
48 #define DMA_ERROR(args)
49 #define DMA_TRACE(args)
50 #endif                          /* BCMDBG */
51
52 #define DMA_NONE(args)
53
54 #define d32txregs       dregs.d32_u.txregs_32
55 #define d32rxregs       dregs.d32_u.rxregs_32
56 #define txd32           dregs.d32_u.txd_32
57 #define rxd32           dregs.d32_u.rxd_32
58
59 #define d64txregs       dregs.d64_u.txregs_64
60 #define d64rxregs       dregs.d64_u.rxregs_64
61 #define txd64           dregs.d64_u.txd_64
62 #define rxd64           dregs.d64_u.rxd_64
63
64 /* default dma message level (if input msg_level pointer is null in dma_attach()) */
65 static uint dma_msg_level;
66
67 #define MAXNAMEL        8       /* 8 char names */
68
69 #define DI_INFO(dmah)   ((dma_info_t *)dmah)
70
71 /* dma engine software state */
72 typedef struct dma_info {
73         struct hnddma_pub hnddma;       /* exported structure, don't use hnddma_t,
74                                          * which could be const
75                                          */
76         uint *msg_level;        /* message level pointer */
77         char name[MAXNAMEL];    /* callers name for diag msgs */
78
79         void *osh;              /* os handle */
80         si_t *sih;              /* sb handle */
81
82         bool dma64;             /* this dma engine is operating in 64-bit mode */
83         bool addrext;           /* this dma engine supports DmaExtendedAddrChanges */
84
85         union {
86                 struct {
87                         dma32regs_t *txregs_32; /* 32-bit dma tx engine registers */
88                         dma32regs_t *rxregs_32; /* 32-bit dma rx engine registers */
89                         dma32dd_t *txd_32;      /* pointer to dma32 tx descriptor ring */
90                         dma32dd_t *rxd_32;      /* pointer to dma32 rx descriptor ring */
91                 } d32_u;
92                 struct {
93                         dma64regs_t *txregs_64; /* 64-bit dma tx engine registers */
94                         dma64regs_t *rxregs_64; /* 64-bit dma rx engine registers */
95                         dma64dd_t *txd_64;      /* pointer to dma64 tx descriptor ring */
96                         dma64dd_t *rxd_64;      /* pointer to dma64 rx descriptor ring */
97                 } d64_u;
98         } dregs;
99
100         u16 dmadesc_align;      /* alignment requirement for dma descriptors */
101
102         u16 ntxd;               /* # tx descriptors tunable */
103         u16 txin;               /* index of next descriptor to reclaim */
104         u16 txout;              /* index of next descriptor to post */
105         void **txp;             /* pointer to parallel array of pointers to packets */
106         osldma_t *tx_dmah;      /* DMA TX descriptor ring handle */
107         hnddma_seg_map_t *txp_dmah;     /* DMA MAP meta-data handle */
108         dmaaddr_t txdpa;        /* Aligned physical address of descriptor ring */
109         dmaaddr_t txdpaorig;    /* Original physical address of descriptor ring */
110         u16 txdalign;   /* #bytes added to alloc'd mem to align txd */
111         u32 txdalloc;   /* #bytes allocated for the ring */
112         u32 xmtptrbase; /* When using unaligned descriptors, the ptr register
113                                  * is not just an index, it needs all 13 bits to be
114                                  * an offset from the addr register.
115                                  */
116
117         u16 nrxd;               /* # rx descriptors tunable */
118         u16 rxin;               /* index of next descriptor to reclaim */
119         u16 rxout;              /* index of next descriptor to post */
120         void **rxp;             /* pointer to parallel array of pointers to packets */
121         osldma_t *rx_dmah;      /* DMA RX descriptor ring handle */
122         hnddma_seg_map_t *rxp_dmah;     /* DMA MAP meta-data handle */
123         dmaaddr_t rxdpa;        /* Aligned physical address of descriptor ring */
124         dmaaddr_t rxdpaorig;    /* Original physical address of descriptor ring */
125         u16 rxdalign;   /* #bytes added to alloc'd mem to align rxd */
126         u32 rxdalloc;   /* #bytes allocated for the ring */
127         u32 rcvptrbase; /* Base for ptr reg when using unaligned descriptors */
128
129         /* tunables */
130         unsigned int rxbufsize; /* rx buffer size in bytes,
131                                  * not including the extra headroom
132                                  */
133         uint rxextrahdrroom;    /* extra rx headroom, reverseved to assist upper stack
134                                  *  e.g. some rx pkt buffers will be bridged to tx side
135                                  *  without byte copying. The extra headroom needs to be
136                                  *  large enough to fit txheader needs.
137                                  *  Some dongle driver may not need it.
138                                  */
139         uint nrxpost;           /* # rx buffers to keep posted */
140         unsigned int rxoffset;  /* rxcontrol offset */
141         uint ddoffsetlow;       /* add to get dma address of descriptor ring, low 32 bits */
142         uint ddoffsethigh;      /*   high 32 bits */
143         uint dataoffsetlow;     /* add to get dma address of data buffer, low 32 bits */
144         uint dataoffsethigh;    /*   high 32 bits */
145         bool aligndesc_4k;      /* descriptor base need to be aligned or not */
146 } dma_info_t;
147
148 /*
149  * If BCMDMA32 is defined, hnddma will support both 32-bit and 64-bit DMA engines.
150  * Otherwise it will support only 64-bit.
151  *
152  * DMA32_ENAB indicates whether hnddma is compiled with support for 32-bit DMA engines.
153  * DMA64_ENAB indicates whether hnddma is compiled with support for 64-bit DMA engines.
154  *
155  * DMA64_MODE indicates whether the current DMA engine is running as 64-bit.
156  */
157 #ifdef BCMDMA32
158 #define DMA32_ENAB(di)          1
159 #define DMA64_ENAB(di)          1
160 #define DMA64_MODE(di)          ((di)->dma64)
161 #else                           /* !BCMDMA32 */
162 #define DMA32_ENAB(di)          0
163 #define DMA64_ENAB(di)          1
164 #define DMA64_MODE(di)          1
165 #endif                          /* !BCMDMA32 */
166
167 /* DMA Scatter-gather list is supported. Note this is limited to TX direction only */
168 #ifdef BCMDMASGLISTOSL
169 #define DMASGLIST_ENAB true
170 #else
171 #define DMASGLIST_ENAB false
172 #endif                          /* BCMDMASGLISTOSL */
173
174 /* descriptor bumping macros */
175 #define XXD(x, n)       ((x) & ((n) - 1))       /* faster than %, but n must be power of 2 */
176 #define TXD(x)          XXD((x), di->ntxd)
177 #define RXD(x)          XXD((x), di->nrxd)
178 #define NEXTTXD(i)      TXD((i) + 1)
179 #define PREVTXD(i)      TXD((i) - 1)
180 #define NEXTRXD(i)      RXD((i) + 1)
181 #define PREVRXD(i)      RXD((i) - 1)
182
183 #define NTXDACTIVE(h, t)        TXD((t) - (h))
184 #define NRXDACTIVE(h, t)        RXD((t) - (h))
185
186 /* macros to convert between byte offsets and indexes */
187 #define B2I(bytes, type)        ((bytes) / sizeof(type))
188 #define I2B(index, type)        ((index) * sizeof(type))
189
190 #define PCI32ADDR_HIGH          0xc0000000      /* address[31:30] */
191 #define PCI32ADDR_HIGH_SHIFT    30      /* address[31:30] */
192
193 #define PCI64ADDR_HIGH          0x80000000      /* address[63] */
194 #define PCI64ADDR_HIGH_SHIFT    31      /* address[63] */
195
196 /* Common prototypes */
197 static bool _dma_isaddrext(dma_info_t *di);
198 static bool _dma_descriptor_align(dma_info_t *di);
199 static bool _dma_alloc(dma_info_t *di, uint direction);
200 static void _dma_detach(dma_info_t *di);
201 static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa);
202 static void _dma_rxinit(dma_info_t *di);
203 static void *_dma_rx(dma_info_t *di);
204 static bool _dma_rxfill(dma_info_t *di);
205 static void _dma_rxreclaim(dma_info_t *di);
206 static void _dma_rxenable(dma_info_t *di);
207 static void *_dma_getnextrxp(dma_info_t *di, bool forceall);
208 static void _dma_rx_param_get(dma_info_t *di, u16 *rxoffset,
209                               u16 *rxbufsize);
210
211 static void _dma_txblock(dma_info_t *di);
212 static void _dma_txunblock(dma_info_t *di);
213 static uint _dma_txactive(dma_info_t *di);
214 static uint _dma_rxactive(dma_info_t *di);
215 static uint _dma_txpending(dma_info_t *di);
216 static uint _dma_txcommitted(dma_info_t *di);
217
218 static void *_dma_peeknexttxp(dma_info_t *di);
219 static void *_dma_peeknextrxp(dma_info_t *di);
220 static unsigned long _dma_getvar(dma_info_t *di, const char *name);
221 static void _dma_counterreset(dma_info_t *di);
222 static void _dma_fifoloopbackenable(dma_info_t *di);
223 static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags);
224 static u8 dma_align_sizetobits(uint size);
225 static void *dma_ringalloc(osl_t *osh, u32 boundary, uint size,
226                            u16 *alignbits, uint *alloced,
227                            dmaaddr_t *descpa, osldma_t **dmah);
228
229 /* Prototypes for 32-bit routines */
230 static bool dma32_alloc(dma_info_t *di, uint direction);
231 static bool dma32_txreset(dma_info_t *di);
232 static bool dma32_rxreset(dma_info_t *di);
233 static bool dma32_txsuspendedidle(dma_info_t *di);
234 static int dma32_txfast(dma_info_t *di, void *p0, bool commit);
235 static void *dma32_getnexttxp(dma_info_t *di, txd_range_t range);
236 static void *dma32_getnextrxp(dma_info_t *di, bool forceall);
237 static void dma32_txrotate(dma_info_t *di);
238 static bool dma32_rxidle(dma_info_t *di);
239 static void dma32_txinit(dma_info_t *di);
240 static bool dma32_txenabled(dma_info_t *di);
241 static void dma32_txsuspend(dma_info_t *di);
242 static void dma32_txresume(dma_info_t *di);
243 static bool dma32_txsuspended(dma_info_t *di);
244 static void dma32_txreclaim(dma_info_t *di, txd_range_t range);
245 static bool dma32_txstopped(dma_info_t *di);
246 static bool dma32_rxstopped(dma_info_t *di);
247 static bool dma32_rxenabled(dma_info_t *di);
248
249 static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs);
250
251 /* Prototypes for 64-bit routines */
252 static bool dma64_alloc(dma_info_t *di, uint direction);
253 static bool dma64_txreset(dma_info_t *di);
254 static bool dma64_rxreset(dma_info_t *di);
255 static bool dma64_txsuspendedidle(dma_info_t *di);
256 static int dma64_txfast(dma_info_t *di, void *p0, bool commit);
257 static int dma64_txunframed(dma_info_t *di, void *p0, uint len, bool commit);
258 static void *dma64_getpos(dma_info_t *di, bool direction);
259 static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range);
260 static void *dma64_getnextrxp(dma_info_t *di, bool forceall);
261 static void dma64_txrotate(dma_info_t *di);
262
263 static bool dma64_rxidle(dma_info_t *di);
264 static void dma64_txinit(dma_info_t *di);
265 static bool dma64_txenabled(dma_info_t *di);
266 static void dma64_txsuspend(dma_info_t *di);
267 static void dma64_txresume(dma_info_t *di);
268 static bool dma64_txsuspended(dma_info_t *di);
269 static void dma64_txreclaim(dma_info_t *di, txd_range_t range);
270 static bool dma64_txstopped(dma_info_t *di);
271 static bool dma64_rxstopped(dma_info_t *di);
272 static bool dma64_rxenabled(dma_info_t *di);
273 static bool _dma64_addrext(osl_t *osh, dma64regs_t *dma64regs);
274
275 static inline u32 parity32(u32 data);
276
277 const di_fcn_t dma64proc = {
278         (di_detach_t) _dma_detach,
279         (di_txinit_t) dma64_txinit,
280         (di_txreset_t) dma64_txreset,
281         (di_txenabled_t) dma64_txenabled,
282         (di_txsuspend_t) dma64_txsuspend,
283         (di_txresume_t) dma64_txresume,
284         (di_txsuspended_t) dma64_txsuspended,
285         (di_txsuspendedidle_t) dma64_txsuspendedidle,
286         (di_txfast_t) dma64_txfast,
287         (di_txunframed_t) dma64_txunframed,
288         (di_getpos_t) dma64_getpos,
289         (di_txstopped_t) dma64_txstopped,
290         (di_txreclaim_t) dma64_txreclaim,
291         (di_getnexttxp_t) dma64_getnexttxp,
292         (di_peeknexttxp_t) _dma_peeknexttxp,
293         (di_txblock_t) _dma_txblock,
294         (di_txunblock_t) _dma_txunblock,
295         (di_txactive_t) _dma_txactive,
296         (di_txrotate_t) dma64_txrotate,
297
298         (di_rxinit_t) _dma_rxinit,
299         (di_rxreset_t) dma64_rxreset,
300         (di_rxidle_t) dma64_rxidle,
301         (di_rxstopped_t) dma64_rxstopped,
302         (di_rxenable_t) _dma_rxenable,
303         (di_rxenabled_t) dma64_rxenabled,
304         (di_rx_t) _dma_rx,
305         (di_rxfill_t) _dma_rxfill,
306         (di_rxreclaim_t) _dma_rxreclaim,
307         (di_getnextrxp_t) _dma_getnextrxp,
308         (di_peeknextrxp_t) _dma_peeknextrxp,
309         (di_rxparam_get_t) _dma_rx_param_get,
310
311         (di_fifoloopbackenable_t) _dma_fifoloopbackenable,
312         (di_getvar_t) _dma_getvar,
313         (di_counterreset_t) _dma_counterreset,
314         (di_ctrlflags_t) _dma_ctrlflags,
315         NULL,
316         NULL,
317         NULL,
318         (di_rxactive_t) _dma_rxactive,
319         (di_txpending_t) _dma_txpending,
320         (di_txcommitted_t) _dma_txcommitted,
321         39
322 };
323
324 static const di_fcn_t dma32proc = {
325         (di_detach_t) _dma_detach,
326         (di_txinit_t) dma32_txinit,
327         (di_txreset_t) dma32_txreset,
328         (di_txenabled_t) dma32_txenabled,
329         (di_txsuspend_t) dma32_txsuspend,
330         (di_txresume_t) dma32_txresume,
331         (di_txsuspended_t) dma32_txsuspended,
332         (di_txsuspendedidle_t) dma32_txsuspendedidle,
333         (di_txfast_t) dma32_txfast,
334         NULL,
335         NULL,
336         (di_txstopped_t) dma32_txstopped,
337         (di_txreclaim_t) dma32_txreclaim,
338         (di_getnexttxp_t) dma32_getnexttxp,
339         (di_peeknexttxp_t) _dma_peeknexttxp,
340         (di_txblock_t) _dma_txblock,
341         (di_txunblock_t) _dma_txunblock,
342         (di_txactive_t) _dma_txactive,
343         (di_txrotate_t) dma32_txrotate,
344
345         (di_rxinit_t) _dma_rxinit,
346         (di_rxreset_t) dma32_rxreset,
347         (di_rxidle_t) dma32_rxidle,
348         (di_rxstopped_t) dma32_rxstopped,
349         (di_rxenable_t) _dma_rxenable,
350         (di_rxenabled_t) dma32_rxenabled,
351         (di_rx_t) _dma_rx,
352         (di_rxfill_t) _dma_rxfill,
353         (di_rxreclaim_t) _dma_rxreclaim,
354         (di_getnextrxp_t) _dma_getnextrxp,
355         (di_peeknextrxp_t) _dma_peeknextrxp,
356         (di_rxparam_get_t) _dma_rx_param_get,
357
358         (di_fifoloopbackenable_t) _dma_fifoloopbackenable,
359         (di_getvar_t) _dma_getvar,
360         (di_counterreset_t) _dma_counterreset,
361         (di_ctrlflags_t) _dma_ctrlflags,
362         NULL,
363         NULL,
364         NULL,
365         (di_rxactive_t) _dma_rxactive,
366         (di_txpending_t) _dma_txpending,
367         (di_txcommitted_t) _dma_txcommitted,
368         39
369 };
370
371 hnddma_t *dma_attach(osl_t *osh, char *name, si_t *sih, void *dmaregstx,
372                      void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize,
373                      int rxextheadroom, uint nrxpost, uint rxoffset,
374                      uint *msg_level)
375 {
376         dma_info_t *di;
377         uint size;
378
379         /* allocate private info structure */
380         di = kzalloc(sizeof(dma_info_t), GFP_ATOMIC);
381         if (di == NULL) {
382 #ifdef BCMDBG
383                 printf("dma_attach: out of memory\n");
384 #endif
385                 return NULL;
386         }
387
388         di->msg_level = msg_level ? msg_level : &dma_msg_level;
389
390         /* old chips w/o sb is no longer supported */
391         ASSERT(sih != NULL);
392
393         if (DMA64_ENAB(di))
394                 di->dma64 =
395                     ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64);
396         else
397                 di->dma64 = 0;
398
399         /* check arguments */
400         ASSERT(ISPOWEROF2(ntxd));
401         ASSERT(ISPOWEROF2(nrxd));
402
403         if (nrxd == 0)
404                 ASSERT(dmaregsrx == NULL);
405         if (ntxd == 0)
406                 ASSERT(dmaregstx == NULL);
407
408         /* init dma reg pointer */
409         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
410                 ASSERT(ntxd <= D64MAXDD);
411                 ASSERT(nrxd <= D64MAXDD);
412                 di->d64txregs = (dma64regs_t *) dmaregstx;
413                 di->d64rxregs = (dma64regs_t *) dmaregsrx;
414                 di->hnddma.di_fn = (const di_fcn_t *)&dma64proc;
415         } else if (DMA32_ENAB(di)) {
416                 ASSERT(ntxd <= D32MAXDD);
417                 ASSERT(nrxd <= D32MAXDD);
418                 di->d32txregs = (dma32regs_t *) dmaregstx;
419                 di->d32rxregs = (dma32regs_t *) dmaregsrx;
420                 di->hnddma.di_fn = (const di_fcn_t *)&dma32proc;
421         } else {
422                 DMA_ERROR(("dma_attach: driver doesn't support 32-bit DMA\n"));
423                 ASSERT(0);
424                 goto fail;
425         }
426
427         /* Default flags (which can be changed by the driver calling dma_ctrlflags
428          * before enable): For backwards compatibility both Rx Overflow Continue
429          * and Parity are DISABLED.
430          * supports it.
431          */
432         di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN,
433                                     0);
434
435         DMA_TRACE(("%s: dma_attach: %s osh %p flags 0x%x ntxd %d nrxd %d rxbufsize %d " "rxextheadroom %d nrxpost %d rxoffset %d dmaregstx %p dmaregsrx %p\n", name, (DMA64_MODE(di) ? "DMA64" : "DMA32"), osh, di->hnddma.dmactrlflags, ntxd, nrxd, rxbufsize, rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx));
436
437         /* make a private copy of our callers name */
438         strncpy(di->name, name, MAXNAMEL);
439         di->name[MAXNAMEL - 1] = '\0';
440
441         di->osh = osh;
442         di->sih = sih;
443
444         /* save tunables */
445         di->ntxd = (u16) ntxd;
446         di->nrxd = (u16) nrxd;
447
448         /* the actual dma size doesn't include the extra headroom */
449         di->rxextrahdrroom =
450             (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
451         if (rxbufsize > BCMEXTRAHDROOM)
452                 di->rxbufsize = (u16) (rxbufsize - di->rxextrahdrroom);
453         else
454                 di->rxbufsize = (u16) rxbufsize;
455
456         di->nrxpost = (u16) nrxpost;
457         di->rxoffset = (u8) rxoffset;
458
459         /*
460          * figure out the DMA physical address offset for dd and data
461          *     PCI/PCIE: they map silicon backplace address to zero based memory, need offset
462          *     Other bus: use zero
463          *     SI_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
464          */
465         di->ddoffsetlow = 0;
466         di->dataoffsetlow = 0;
467         /* for pci bus, add offset */
468         if (sih->bustype == PCI_BUS) {
469                 if ((sih->buscoretype == PCIE_CORE_ID) && DMA64_MODE(di)) {
470                         /* pcie with DMA64 */
471                         di->ddoffsetlow = 0;
472                         di->ddoffsethigh = SI_PCIE_DMA_H32;
473                 } else {
474                         /* pci(DMA32/DMA64) or pcie with DMA32 */
475                         di->ddoffsetlow = SI_PCI_DMA;
476                         di->ddoffsethigh = 0;
477                 }
478                 di->dataoffsetlow = di->ddoffsetlow;
479                 di->dataoffsethigh = di->ddoffsethigh;
480         }
481 #if defined(__mips__) && defined(IL_BIGENDIAN)
482         di->dataoffsetlow = di->dataoffsetlow + SI_SDRAM_SWAPPED;
483 #endif                          /* defined(__mips__) && defined(IL_BIGENDIAN) */
484         /* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
485         if ((si_coreid(sih) == SDIOD_CORE_ID)
486             && ((si_corerev(sih) > 0) && (si_corerev(sih) <= 2)))
487                 di->addrext = 0;
488         else if ((si_coreid(sih) == I2S_CORE_ID) &&
489                  ((si_corerev(sih) == 0) || (si_corerev(sih) == 1)))
490                 di->addrext = 0;
491         else
492                 di->addrext = _dma_isaddrext(di);
493
494         /* does the descriptors need to be aligned and if yes, on 4K/8K or not */
495         di->aligndesc_4k = _dma_descriptor_align(di);
496         if (di->aligndesc_4k) {
497                 if (DMA64_MODE(di)) {
498                         di->dmadesc_align = D64RINGALIGN_BITS;
499                         if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
500                                 /* for smaller dd table, HW relax the alignment requirement */
501                                 di->dmadesc_align = D64RINGALIGN_BITS - 1;
502                         }
503                 } else
504                         di->dmadesc_align = D32RINGALIGN_BITS;
505         } else
506                 di->dmadesc_align = 4;  /* 16 byte alignment */
507
508         DMA_NONE(("DMA descriptor align_needed %d, align %d\n",
509                   di->aligndesc_4k, di->dmadesc_align));
510
511         /* allocate tx packet pointer vector */
512         if (ntxd) {
513                 size = ntxd * sizeof(void *);
514                 di->txp = kzalloc(size, GFP_ATOMIC);
515                 if (di->txp == NULL) {
516                         DMA_ERROR(("%s: dma_attach: out of tx memory\n", di->name));
517                         goto fail;
518                 }
519         }
520
521         /* allocate rx packet pointer vector */
522         if (nrxd) {
523                 size = nrxd * sizeof(void *);
524                 di->rxp = kzalloc(size, GFP_ATOMIC);
525                 if (di->rxp == NULL) {
526                         DMA_ERROR(("%s: dma_attach: out of rx memory\n", di->name));
527                         goto fail;
528                 }
529         }
530
531         /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
532         if (ntxd) {
533                 if (!_dma_alloc(di, DMA_TX))
534                         goto fail;
535         }
536
537         /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
538         if (nrxd) {
539                 if (!_dma_alloc(di, DMA_RX))
540                         goto fail;
541         }
542
543         if ((di->ddoffsetlow != 0) && !di->addrext) {
544                 if (PHYSADDRLO(di->txdpa) > SI_PCI_DMA_SZ) {
545                         DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->txdpa)));
546                         goto fail;
547                 }
548                 if (PHYSADDRLO(di->rxdpa) > SI_PCI_DMA_SZ) {
549                         DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->rxdpa)));
550                         goto fail;
551                 }
552         }
553
554         DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, di->addrext));
555
556         /* allocate DMA mapping vectors */
557         if (DMASGLIST_ENAB) {
558                 if (ntxd) {
559                         size = ntxd * sizeof(hnddma_seg_map_t);
560                         di->txp_dmah = kzalloc(size, GFP_ATOMIC);
561                         if (di->txp_dmah == NULL)
562                                 goto fail;
563                 }
564
565                 if (nrxd) {
566                         size = nrxd * sizeof(hnddma_seg_map_t);
567                         di->rxp_dmah = kzalloc(size, GFP_ATOMIC);
568                         if (di->rxp_dmah == NULL)
569                                 goto fail;
570                 }
571         }
572
573         return (hnddma_t *) di;
574
575  fail:
576         _dma_detach(di);
577         return NULL;
578 }
579
580 /* init the tx or rx descriptor */
581 static inline void
582 dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, dmaaddr_t pa, uint outidx,
583              u32 *flags, u32 bufcount)
584 {
585         /* dma32 uses 32-bit control to fit both flags and bufcounter */
586         *flags = *flags | (bufcount & CTRL_BC_MASK);
587
588         if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
589                 W_SM(&ddring[outidx].addr,
590                      BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
591                 W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags));
592         } else {
593                 /* address extension */
594                 u32 ae;
595                 ASSERT(di->addrext);
596                 ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
597                 PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
598
599                 *flags |= (ae << CTRL_AE_SHIFT);
600                 W_SM(&ddring[outidx].addr,
601                      BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
602                 W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags));
603         }
604 }
605
606 /* Check for odd number of 1's */
607 static inline u32 parity32(u32 data)
608 {
609         data ^= data >> 16;
610         data ^= data >> 8;
611         data ^= data >> 4;
612         data ^= data >> 2;
613         data ^= data >> 1;
614
615         return data & 1;
616 }
617
618 #define DMA64_DD_PARITY(dd)  parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2)
619
620 static inline void
621 dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx,
622              u32 *flags, u32 bufcount)
623 {
624         u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
625
626         /* PCI bus with big(>1G) physical address, use address extension */
627 #if defined(__mips__) && defined(IL_BIGENDIAN)
628         if ((di->dataoffsetlow == SI_SDRAM_SWAPPED)
629             || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
630 #else
631         if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
632 #endif                          /* defined(__mips__) && defined(IL_BIGENDIAN) */
633                 ASSERT((PHYSADDRHI(pa) & PCI64ADDR_HIGH) == 0);
634
635                 W_SM(&ddring[outidx].addrlow,
636                      BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
637                 W_SM(&ddring[outidx].addrhigh,
638                      BUS_SWAP32(PHYSADDRHI(pa) + di->dataoffsethigh));
639                 W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
640                 W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
641         } else {
642                 /* address extension for 32-bit PCI */
643                 u32 ae;
644                 ASSERT(di->addrext);
645
646                 ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
647                 PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
648                 ASSERT(PHYSADDRHI(pa) == 0);
649
650                 ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
651                 W_SM(&ddring[outidx].addrlow,
652                      BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
653                 W_SM(&ddring[outidx].addrhigh,
654                      BUS_SWAP32(0 + di->dataoffsethigh));
655                 W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
656                 W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
657         }
658         if (di->hnddma.dmactrlflags & DMA_CTRL_PEN) {
659                 if (DMA64_DD_PARITY(&ddring[outidx])) {
660                         W_SM(&ddring[outidx].ctrl2,
661                              BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY));
662                 }
663         }
664 }
665
666 static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs)
667 {
668         u32 w;
669
670         OR_REG(osh, &dma32regs->control, XC_AE);
671         w = R_REG(osh, &dma32regs->control);
672         AND_REG(osh, &dma32regs->control, ~XC_AE);
673         return (w & XC_AE) == XC_AE;
674 }
675
676 static bool _dma_alloc(dma_info_t *di, uint direction)
677 {
678         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
679                 return dma64_alloc(di, direction);
680         } else if (DMA32_ENAB(di)) {
681                 return dma32_alloc(di, direction);
682         } else
683                 ASSERT(0);
684 }
685
686 /* !! may be called with core in reset */
687 static void _dma_detach(dma_info_t *di)
688 {
689
690         DMA_TRACE(("%s: dma_detach\n", di->name));
691
692         /* shouldn't be here if descriptors are unreclaimed */
693         ASSERT(di->txin == di->txout);
694         ASSERT(di->rxin == di->rxout);
695
696         /* free dma descriptor rings */
697         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
698                 if (di->txd64)
699                         DMA_FREE_CONSISTENT(di->osh,
700                                             ((s8 *)di->txd64 -
701                                              di->txdalign), di->txdalloc,
702                                             (di->txdpaorig), &di->tx_dmah);
703                 if (di->rxd64)
704                         DMA_FREE_CONSISTENT(di->osh,
705                                             ((s8 *)di->rxd64 -
706                                              di->rxdalign), di->rxdalloc,
707                                             (di->rxdpaorig), &di->rx_dmah);
708         } else if (DMA32_ENAB(di)) {
709                 if (di->txd32)
710                         DMA_FREE_CONSISTENT(di->osh,
711                                             ((s8 *)di->txd32 -
712                                              di->txdalign), di->txdalloc,
713                                             (di->txdpaorig), &di->tx_dmah);
714                 if (di->rxd32)
715                         DMA_FREE_CONSISTENT(di->osh,
716                                             ((s8 *)di->rxd32 -
717                                              di->rxdalign), di->rxdalloc,
718                                             (di->rxdpaorig), &di->rx_dmah);
719         } else
720                 ASSERT(0);
721
722         /* free packet pointer vectors */
723         if (di->txp)
724                 kfree((void *)di->txp);
725         if (di->rxp)
726                 kfree((void *)di->rxp);
727
728         /* free tx packet DMA handles */
729         if (di->txp_dmah)
730                 kfree(di->txp_dmah);
731
732         /* free rx packet DMA handles */
733         if (di->rxp_dmah)
734                 kfree(di->rxp_dmah);
735
736         /* free our private info structure */
737         kfree((void *)di);
738
739 }
740
741 static bool _dma_descriptor_align(dma_info_t *di)
742 {
743         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
744                 u32 addrl;
745
746                 /* Check to see if the descriptors need to be aligned on 4K/8K or not */
747                 if (di->d64txregs != NULL) {
748                         W_REG(di->osh, &di->d64txregs->addrlow, 0xff0);
749                         addrl = R_REG(di->osh, &di->d64txregs->addrlow);
750                         if (addrl != 0)
751                                 return false;
752                 } else if (di->d64rxregs != NULL) {
753                         W_REG(di->osh, &di->d64rxregs->addrlow, 0xff0);
754                         addrl = R_REG(di->osh, &di->d64rxregs->addrlow);
755                         if (addrl != 0)
756                                 return false;
757                 }
758         }
759         return true;
760 }
761
762 /* return true if this dma engine supports DmaExtendedAddrChanges, otherwise false */
763 static bool _dma_isaddrext(dma_info_t *di)
764 {
765         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
766                 /* DMA64 supports full 32- or 64-bit operation. AE is always valid */
767
768                 /* not all tx or rx channel are available */
769                 if (di->d64txregs != NULL) {
770                         if (!_dma64_addrext(di->osh, di->d64txregs)) {
771                                 DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have AE set\n", di->name));
772                                 ASSERT(0);
773                         }
774                         return true;
775                 } else if (di->d64rxregs != NULL) {
776                         if (!_dma64_addrext(di->osh, di->d64rxregs)) {
777                                 DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have AE set\n", di->name));
778                                 ASSERT(0);
779                         }
780                         return true;
781                 }
782                 return false;
783         } else if (DMA32_ENAB(di)) {
784                 if (di->d32txregs)
785                         return _dma32_addrext(di->osh, di->d32txregs);
786                 else if (di->d32rxregs)
787                         return _dma32_addrext(di->osh, di->d32rxregs);
788         } else
789                 ASSERT(0);
790
791         return false;
792 }
793
794 /* initialize descriptor table base address */
795 static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa)
796 {
797         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
798                 if (!di->aligndesc_4k) {
799                         if (direction == DMA_TX)
800                                 di->xmtptrbase = PHYSADDRLO(pa);
801                         else
802                                 di->rcvptrbase = PHYSADDRLO(pa);
803                 }
804
805                 if ((di->ddoffsetlow == 0)
806                     || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
807                         if (direction == DMA_TX) {
808                                 W_REG(di->osh, &di->d64txregs->addrlow,
809                                       (PHYSADDRLO(pa) + di->ddoffsetlow));
810                                 W_REG(di->osh, &di->d64txregs->addrhigh,
811                                       (PHYSADDRHI(pa) + di->ddoffsethigh));
812                         } else {
813                                 W_REG(di->osh, &di->d64rxregs->addrlow,
814                                       (PHYSADDRLO(pa) + di->ddoffsetlow));
815                                 W_REG(di->osh, &di->d64rxregs->addrhigh,
816                                       (PHYSADDRHI(pa) + di->ddoffsethigh));
817                         }
818                 } else {
819                         /* DMA64 32bits address extension */
820                         u32 ae;
821                         ASSERT(di->addrext);
822                         ASSERT(PHYSADDRHI(pa) == 0);
823
824                         /* shift the high bit(s) from pa to ae */
825                         ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >>
826                             PCI32ADDR_HIGH_SHIFT;
827                         PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
828
829                         if (direction == DMA_TX) {
830                                 W_REG(di->osh, &di->d64txregs->addrlow,
831                                       (PHYSADDRLO(pa) + di->ddoffsetlow));
832                                 W_REG(di->osh, &di->d64txregs->addrhigh,
833                                       di->ddoffsethigh);
834                                 SET_REG(di->osh, &di->d64txregs->control,
835                                         D64_XC_AE, (ae << D64_XC_AE_SHIFT));
836                         } else {
837                                 W_REG(di->osh, &di->d64rxregs->addrlow,
838                                       (PHYSADDRLO(pa) + di->ddoffsetlow));
839                                 W_REG(di->osh, &di->d64rxregs->addrhigh,
840                                       di->ddoffsethigh);
841                                 SET_REG(di->osh, &di->d64rxregs->control,
842                                         D64_RC_AE, (ae << D64_RC_AE_SHIFT));
843                         }
844                 }
845
846         } else if (DMA32_ENAB(di)) {
847                 ASSERT(PHYSADDRHI(pa) == 0);
848                 if ((di->ddoffsetlow == 0)
849                     || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
850                         if (direction == DMA_TX)
851                                 W_REG(di->osh, &di->d32txregs->addr,
852                                       (PHYSADDRLO(pa) + di->ddoffsetlow));
853                         else
854                                 W_REG(di->osh, &di->d32rxregs->addr,
855                                       (PHYSADDRLO(pa) + di->ddoffsetlow));
856                 } else {
857                         /* dma32 address extension */
858                         u32 ae;
859                         ASSERT(di->addrext);
860
861                         /* shift the high bit(s) from pa to ae */
862                         ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >>
863                             PCI32ADDR_HIGH_SHIFT;
864                         PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
865
866                         if (direction == DMA_TX) {
867                                 W_REG(di->osh, &di->d32txregs->addr,
868                                       (PHYSADDRLO(pa) + di->ddoffsetlow));
869                                 SET_REG(di->osh, &di->d32txregs->control, XC_AE,
870                                         ae << XC_AE_SHIFT);
871                         } else {
872                                 W_REG(di->osh, &di->d32rxregs->addr,
873                                       (PHYSADDRLO(pa) + di->ddoffsetlow));
874                                 SET_REG(di->osh, &di->d32rxregs->control, RC_AE,
875                                         ae << RC_AE_SHIFT);
876                         }
877                 }
878         } else
879                 ASSERT(0);
880 }
881
882 static void _dma_fifoloopbackenable(dma_info_t *di)
883 {
884         DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
885
886         if (DMA64_ENAB(di) && DMA64_MODE(di))
887                 OR_REG(di->osh, &di->d64txregs->control, D64_XC_LE);
888         else if (DMA32_ENAB(di))
889                 OR_REG(di->osh, &di->d32txregs->control, XC_LE);
890         else
891                 ASSERT(0);
892 }
893
894 static void _dma_rxinit(dma_info_t *di)
895 {
896         DMA_TRACE(("%s: dma_rxinit\n", di->name));
897
898         if (di->nrxd == 0)
899                 return;
900
901         di->rxin = di->rxout = 0;
902
903         /* clear rx descriptor ring */
904         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
905                 BZERO_SM((void *)di->rxd64,
906                          (di->nrxd * sizeof(dma64dd_t)));
907
908                 /* DMA engine with out alignment requirement requires table to be inited
909                  * before enabling the engine
910                  */
911                 if (!di->aligndesc_4k)
912                         _dma_ddtable_init(di, DMA_RX, di->rxdpa);
913
914                 _dma_rxenable(di);
915
916                 if (di->aligndesc_4k)
917                         _dma_ddtable_init(di, DMA_RX, di->rxdpa);
918         } else if (DMA32_ENAB(di)) {
919                 BZERO_SM((void *)di->rxd32,
920                          (di->nrxd * sizeof(dma32dd_t)));
921                 _dma_rxenable(di);
922                 _dma_ddtable_init(di, DMA_RX, di->rxdpa);
923         } else
924                 ASSERT(0);
925 }
926
927 static void _dma_rxenable(dma_info_t *di)
928 {
929         uint dmactrlflags = di->hnddma.dmactrlflags;
930
931         DMA_TRACE(("%s: dma_rxenable\n", di->name));
932
933         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
934                 u32 control =
935                     (R_REG(di->osh, &di->d64rxregs->control) & D64_RC_AE) |
936                     D64_RC_RE;
937
938                 if ((dmactrlflags & DMA_CTRL_PEN) == 0)
939                         control |= D64_RC_PD;
940
941                 if (dmactrlflags & DMA_CTRL_ROC)
942                         control |= D64_RC_OC;
943
944                 W_REG(di->osh, &di->d64rxregs->control,
945                       ((di->rxoffset << D64_RC_RO_SHIFT) | control));
946         } else if (DMA32_ENAB(di)) {
947                 u32 control =
948                     (R_REG(di->osh, &di->d32rxregs->control) & RC_AE) | RC_RE;
949
950                 if ((dmactrlflags & DMA_CTRL_PEN) == 0)
951                         control |= RC_PD;
952
953                 if (dmactrlflags & DMA_CTRL_ROC)
954                         control |= RC_OC;
955
956                 W_REG(di->osh, &di->d32rxregs->control,
957                       ((di->rxoffset << RC_RO_SHIFT) | control));
958         } else
959                 ASSERT(0);
960 }
961
962 static void
963 _dma_rx_param_get(dma_info_t *di, u16 *rxoffset, u16 *rxbufsize)
964 {
965         /* the normal values fit into 16 bits */
966         *rxoffset = (u16) di->rxoffset;
967         *rxbufsize = (u16) di->rxbufsize;
968 }
969
970 /* !! rx entry routine
971  * returns a pointer to the next frame received, or NULL if there are no more
972  *   if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is supported
973  *      with pkts chain
974  *   otherwise, it's treated as giant pkt and will be tossed.
975  *   The DMA scattering starts with normal DMA header, followed by first buffer data.
976  *   After it reaches the max size of buffer, the data continues in next DMA descriptor
977  *   buffer WITHOUT DMA header
978  */
979 static void *BCMFASTPATH _dma_rx(dma_info_t *di)
980 {
981         void *p, *head, *tail;
982         uint len;
983         uint pkt_len;
984         int resid = 0;
985
986  next_frame:
987         head = _dma_getnextrxp(di, false);
988         if (head == NULL)
989                 return NULL;
990
991         len = ltoh16(*(u16 *) (PKTDATA(head)));
992         DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
993
994 #if defined(__mips__)
995         if (!len) {
996                 while (!(len = *(u16 *) OSL_UNCACHED(PKTDATA(head))))
997                         udelay(1);
998
999                 *(u16 *) PKTDATA(head) = htol16((u16) len);
1000         }
1001 #endif                          /* defined(__mips__) */
1002
1003         /* set actual length */
1004         pkt_len = min((di->rxoffset + len), di->rxbufsize);
1005         PKTSETLEN(head, pkt_len);
1006         resid = len - (di->rxbufsize - di->rxoffset);
1007
1008         /* check for single or multi-buffer rx */
1009         if (resid > 0) {
1010                 tail = head;
1011                 while ((resid > 0) && (p = _dma_getnextrxp(di, false))) {
1012                         PKTSETNEXT(tail, p);
1013                         pkt_len = min(resid, (int)di->rxbufsize);
1014                         PKTSETLEN(p, pkt_len);
1015
1016                         tail = p;
1017                         resid -= di->rxbufsize;
1018                 }
1019
1020 #ifdef BCMDBG
1021                 if (resid > 0) {
1022                         uint cur;
1023                         ASSERT(p == NULL);
1024                         cur = (DMA64_ENAB(di) && DMA64_MODE(di)) ?
1025                             B2I(((R_REG(di->osh, &di->d64rxregs->status0) &
1026                                   D64_RS0_CD_MASK) -
1027                                  di->rcvptrbase) & D64_RS0_CD_MASK,
1028                                 dma64dd_t) : B2I(R_REG(di->osh,
1029                                                        &di->d32rxregs->
1030                                                        status) & RS_CD_MASK,
1031                                                  dma32dd_t);
1032                         DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n",
1033                                    di->rxin, di->rxout, cur));
1034                 }
1035 #endif                          /* BCMDBG */
1036
1037                 if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
1038                         DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n",
1039                                    di->name, len));
1040                         PKTFREE(di->osh, head, false);
1041                         di->hnddma.rxgiants++;
1042                         goto next_frame;
1043                 }
1044         }
1045
1046         return head;
1047 }
1048
1049 /* post receive buffers
1050  *  return false is refill failed completely and ring is empty
1051  *  this will stall the rx dma and user might want to call rxfill again asap
1052  *  This unlikely happens on memory-rich NIC, but often on memory-constrained dongle
1053  */
1054 static bool BCMFASTPATH _dma_rxfill(dma_info_t *di)
1055 {
1056         void *p;
1057         u16 rxin, rxout;
1058         u32 flags = 0;
1059         uint n;
1060         uint i;
1061         dmaaddr_t pa;
1062         uint extra_offset = 0;
1063         bool ring_empty;
1064
1065         ring_empty = false;
1066
1067         /*
1068          * Determine how many receive buffers we're lacking
1069          * from the full complement, allocate, initialize,
1070          * and post them, then update the chip rx lastdscr.
1071          */
1072
1073         rxin = di->rxin;
1074         rxout = di->rxout;
1075
1076         n = di->nrxpost - NRXDACTIVE(rxin, rxout);
1077
1078         DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
1079
1080         if (di->rxbufsize > BCMEXTRAHDROOM)
1081                 extra_offset = di->rxextrahdrroom;
1082
1083         for (i = 0; i < n; i++) {
1084                 /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
1085                    size to be allocated
1086                  */
1087
1088                 p = osl_pktget(di->osh, di->rxbufsize + extra_offset);
1089
1090                 if (p == NULL) {
1091                         DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n",
1092                                    di->name));
1093                         if (i == 0) {
1094                                 if (DMA64_ENAB(di) && DMA64_MODE(di)) {
1095                                         if (dma64_rxidle(di)) {
1096                                                 DMA_ERROR(("%s: rxfill64: ring is empty !\n", di->name));
1097                                                 ring_empty = true;
1098                                         }
1099                                 } else if (DMA32_ENAB(di)) {
1100                                         if (dma32_rxidle(di)) {
1101                                                 DMA_ERROR(("%s: rxfill32: ring is empty !\n", di->name));
1102                                                 ring_empty = true;
1103                                         }
1104                                 } else
1105                                         ASSERT(0);
1106                         }
1107                         di->hnddma.rxnobuf++;
1108                         break;
1109                 }
1110                 /* reserve an extra headroom, if applicable */
1111                 if (extra_offset)
1112                         PKTPULL(p, extra_offset);
1113
1114                 /* Do a cached write instead of uncached write since DMA_MAP
1115                  * will flush the cache.
1116                  */
1117                 *(u32 *) (PKTDATA(p)) = 0;
1118
1119                 if (DMASGLIST_ENAB)
1120                         bzero(&di->rxp_dmah[rxout], sizeof(hnddma_seg_map_t));
1121
1122                 pa = DMA_MAP(di->osh, PKTDATA(p),
1123                              di->rxbufsize, DMA_RX, p, &di->rxp_dmah[rxout]);
1124
1125                 ASSERT(IS_ALIGNED(PHYSADDRLO(pa), 4));
1126
1127                 /* save the free packet pointer */
1128                 ASSERT(di->rxp[rxout] == NULL);
1129                 di->rxp[rxout] = p;
1130
1131                 /* reset flags for each descriptor */
1132                 flags = 0;
1133                 if (DMA64_ENAB(di) && DMA64_MODE(di)) {
1134                         if (rxout == (di->nrxd - 1))
1135                                 flags = D64_CTRL1_EOT;
1136
1137                         dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
1138                                      di->rxbufsize);
1139                 } else if (DMA32_ENAB(di)) {
1140                         if (rxout == (di->nrxd - 1))
1141                                 flags = CTRL_EOT;
1142
1143                         ASSERT(PHYSADDRHI(pa) == 0);
1144                         dma32_dd_upd(di, di->rxd32, pa, rxout, &flags,
1145                                      di->rxbufsize);
1146                 } else
1147                         ASSERT(0);
1148                 rxout = NEXTRXD(rxout);
1149         }
1150
1151         di->rxout = rxout;
1152
1153         /* update the chip lastdscr pointer */
1154         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
1155                 W_REG(di->osh, &di->d64rxregs->ptr,
1156                       di->rcvptrbase + I2B(rxout, dma64dd_t));
1157         } else if (DMA32_ENAB(di)) {
1158                 W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t));
1159         } else
1160                 ASSERT(0);
1161
1162         return ring_empty;
1163 }
1164
1165 /* like getnexttxp but no reclaim */
1166 static void *_dma_peeknexttxp(dma_info_t *di)
1167 {
1168         uint end, i;
1169
1170         if (di->ntxd == 0)
1171                 return NULL;
1172
1173         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
1174                 end =
1175                     B2I(((R_REG(di->osh, &di->d64txregs->status0) &
1176                           D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
1177                         dma64dd_t);
1178         } else if (DMA32_ENAB(di)) {
1179                 end =
1180                     B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK,
1181                         dma32dd_t);
1182         } else
1183                 ASSERT(0);
1184
1185         for (i = di->txin; i != end; i = NEXTTXD(i))
1186                 if (di->txp[i])
1187                         return di->txp[i];
1188
1189         return NULL;
1190 }
1191
1192 /* like getnextrxp but not take off the ring */
1193 static void *_dma_peeknextrxp(dma_info_t *di)
1194 {
1195         uint end, i;
1196
1197         if (di->nrxd == 0)
1198                 return NULL;
1199
1200         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
1201                 end =
1202                     B2I(((R_REG(di->osh, &di->d64rxregs->status0) &
1203                           D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK,
1204                         dma64dd_t);
1205         } else if (DMA32_ENAB(di)) {
1206                 end =
1207                     B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK,
1208                         dma32dd_t);
1209         } else
1210                 ASSERT(0);
1211
1212         for (i = di->rxin; i != end; i = NEXTRXD(i))
1213                 if (di->rxp[i])
1214                         return di->rxp[i];
1215
1216         return NULL;
1217 }
1218
1219 static void _dma_rxreclaim(dma_info_t *di)
1220 {
1221         void *p;
1222
1223         /* "unused local" warning suppression for OSLs that
1224          * define PKTFREE() without using the di->osh arg
1225          */
1226         di = di;
1227
1228         DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
1229
1230         while ((p = _dma_getnextrxp(di, true)))
1231                 PKTFREE(di->osh, p, false);
1232 }
1233
1234 static void *BCMFASTPATH _dma_getnextrxp(dma_info_t *di, bool forceall)
1235 {
1236         if (di->nrxd == 0)
1237                 return NULL;
1238
1239         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
1240                 return dma64_getnextrxp(di, forceall);
1241         } else if (DMA32_ENAB(di)) {
1242                 return dma32_getnextrxp(di, forceall);
1243         } else
1244                 ASSERT(0);
1245 }
1246
1247 static void _dma_txblock(dma_info_t *di)
1248 {
1249         di->hnddma.txavail = 0;
1250 }
1251
1252 static void _dma_txunblock(dma_info_t *di)
1253 {
1254         di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1255 }
1256
1257 static uint _dma_txactive(dma_info_t *di)
1258 {
1259         return NTXDACTIVE(di->txin, di->txout);
1260 }
1261
1262 static uint _dma_txpending(dma_info_t *di)
1263 {
1264         uint curr;
1265
1266         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
1267                 curr =
1268                     B2I(((R_REG(di->osh, &di->d64txregs->status0) &
1269                           D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
1270                         dma64dd_t);
1271         } else if (DMA32_ENAB(di)) {
1272                 curr =
1273                     B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK,
1274                         dma32dd_t);
1275         } else
1276                 ASSERT(0);
1277
1278         return NTXDACTIVE(curr, di->txout);
1279 }
1280
1281 static uint _dma_txcommitted(dma_info_t *di)
1282 {
1283         uint ptr;
1284         uint txin = di->txin;
1285
1286         if (txin == di->txout)
1287                 return 0;
1288
1289         if (DMA64_ENAB(di) && DMA64_MODE(di)) {
1290                 ptr = B2I(R_REG(di->osh, &di->d64txregs->ptr), dma64dd_t);
1291         } else if (DMA32_ENAB(di)) {
1292                 ptr = B2I(R_REG(di->osh, &di->d32txregs->ptr), dma32dd_t);
1293         } else
1294                 ASSERT(0);
1295
1296         return NTXDACTIVE(di->txin, ptr);
1297 }
1298
1299 static uint _dma_rxactive(dma_info_t *di)
1300 {
1301         return NRXDACTIVE(di->rxin, di->rxout);
1302 }
1303
1304 static void _dma_counterreset(dma_info_t *di)
1305 {
1306         /* reset all software counter */
1307         di->hnddma.rxgiants = 0;
1308         di->hnddma.rxnobuf = 0;
1309         di->hnddma.txnobuf = 0;
1310 }
1311
1312 static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags)
1313 {
1314         uint dmactrlflags = di->hnddma.dmactrlflags;
1315
1316         if (di == NULL) {
1317                 DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
1318                 return 0;
1319         }
1320
1321         ASSERT((flags & ~mask) == 0);
1322
1323         dmactrlflags &= ~mask;
1324         dmactrlflags |= flags;
1325
1326         /* If trying to enable parity, check if parity is actually supported */
1327         if (dmactrlflags & DMA_CTRL_PEN) {
1328                 u32 control;
1329
1330                 if (DMA64_ENAB(di) && DMA64_MODE(di)) {
1331                         control = R_REG(di->osh, &di->d64txregs->control);
1332                         W_REG(di->osh, &di->d64txregs->control,
1333                               control | D64_XC_PD);
1334                         if (R_REG(di->osh, &di->d64txregs->control) & D64_XC_PD) {
1335                                 /* We *can* disable it so it is supported,
1336                                  * restore control register
1337                                  */
1338                                 W_REG(di->osh, &di->d64txregs->control,
1339                                       control);
1340                         } else {
1341                                 /* Not supported, don't allow it to be enabled */
1342                                 dmactrlflags &= ~DMA_CTRL_PEN;
1343                         }
1344                 } else if (DMA32_ENAB(di)) {
1345                         control = R_REG(di->osh, &di->d32txregs->control);
1346                         W_REG(di->osh, &di->d32txregs->control,
1347                               control | XC_PD);
1348                         if (R_REG(di->osh, &di->d32txregs->control) & XC_PD) {
1349                                 W_REG(di->osh, &di->d32txregs->control,
1350                                       control);
1351                         } else {
1352                                 /* Not supported, don't allow it to be enabled */
1353                                 dmactrlflags &= ~DMA_CTRL_PEN;
1354                         }
1355                 } else
1356                         ASSERT(0);
1357         }
1358
1359         di->hnddma.dmactrlflags = dmactrlflags;
1360
1361         return dmactrlflags;
1362 }
1363
1364 /* get the address of the var in order to change later */
1365 static unsigned long _dma_getvar(dma_info_t *di, const char *name)
1366 {
1367         if (!strcmp(name, "&txavail"))
1368                 return (unsigned long)&(di->hnddma.txavail);
1369         else {
1370                 ASSERT(0);
1371         }
1372         return 0;
1373 }
1374
1375 void dma_txpioloopback(osl_t *osh, dma32regs_t *regs)
1376 {
1377         OR_REG(osh, &regs->control, XC_LE);
1378 }
1379
1380 static
1381 u8 dma_align_sizetobits(uint size)
1382 {
1383         u8 bitpos = 0;
1384         ASSERT(size);
1385         ASSERT(!(size & (size - 1)));
1386         while (size >>= 1) {
1387                 bitpos++;
1388         }
1389         return bitpos;
1390 }
1391
1392 /* This function ensures that the DMA descriptor ring will not get allocated
1393  * across Page boundary. If the allocation is done across the page boundary
1394  * at the first time, then it is freed and the allocation is done at
1395  * descriptor ring size aligned location. This will ensure that the ring will
1396  * not cross page boundary
1397  */
1398 static void *dma_ringalloc(osl_t *osh, u32 boundary, uint size,
1399                            u16 *alignbits, uint *alloced,
1400                            dmaaddr_t *descpa, osldma_t **dmah)
1401 {
1402         void *va;
1403         u32 desc_strtaddr;
1404         u32 alignbytes = 1 << *alignbits;
1405
1406         va = DMA_ALLOC_CONSISTENT(osh, size, *alignbits, alloced, descpa,
1407                 dmah);
1408         if (NULL == va)
1409                 return NULL;
1410
1411         desc_strtaddr = (u32) roundup((unsigned long)va, alignbytes);
1412         if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
1413                                                         & boundary)) {
1414                 *alignbits = dma_align_sizetobits(size);
1415                 DMA_FREE_CONSISTENT(osh, va, size, *descpa, dmah);
1416                 va = DMA_ALLOC_CONSISTENT(osh, size, *alignbits, alloced,
1417                                           descpa, dmah);
1418         }
1419         return va;
1420 }
1421
1422 /* 32-bit DMA functions */
1423
1424 static void dma32_txinit(dma_info_t *di)
1425 {
1426         u32 control = XC_XE;
1427
1428         DMA_TRACE(("%s: dma_txinit\n", di->name));
1429
1430         if (di->ntxd == 0)
1431                 return;
1432
1433         di->txin = di->txout = 0;
1434         di->hnddma.txavail = di->ntxd - 1;
1435
1436         /* clear tx descriptor ring */
1437         BZERO_SM((void *)di->txd32, (di->ntxd * sizeof(dma32dd_t)));
1438
1439         if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0)
1440                 control |= XC_PD;
1441         W_REG(di->osh, &di->d32txregs->control, control);
1442         _dma_ddtable_init(di, DMA_TX, di->txdpa);
1443 }
1444
1445 static bool dma32_txenabled(dma_info_t *di)
1446 {
1447         u32 xc;
1448
1449         /* If the chip is dead, it is not enabled :-) */
1450         xc = R_REG(di->osh, &di->d32txregs->control);
1451         return (xc != 0xffffffff) && (xc & XC_XE);
1452 }
1453
1454 static void dma32_txsuspend(dma_info_t *di)
1455 {
1456         DMA_TRACE(("%s: dma_txsuspend\n", di->name));
1457
1458         if (di->ntxd == 0)
1459                 return;
1460
1461         OR_REG(di->osh, &di->d32txregs->control, XC_SE);
1462 }
1463
1464 static void dma32_txresume(dma_info_t *di)
1465 {
1466         DMA_TRACE(("%s: dma_txresume\n", di->name));
1467
1468         if (di->ntxd == 0)
1469                 return;
1470
1471         AND_REG(di->osh, &di->d32txregs->control, ~XC_SE);
1472 }
1473
1474 static bool dma32_txsuspended(dma_info_t *di)
1475 {
1476         return (di->ntxd == 0)
1477             || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE);
1478 }
1479
1480 static void dma32_txreclaim(dma_info_t *di, txd_range_t range)
1481 {
1482         void *p;
1483
1484         DMA_TRACE(("%s: dma_txreclaim %s\n", di->name,
1485                    (range == HNDDMA_RANGE_ALL) ? "all" :
1486                    ((range ==
1487                      HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
1488                     "transfered")));
1489
1490         if (di->txin == di->txout)
1491                 return;
1492
1493         while ((p = dma32_getnexttxp(di, range)))
1494                 PKTFREE(di->osh, p, true);
1495 }
1496
1497 static bool dma32_txstopped(dma_info_t *di)
1498 {
1499         return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) ==
1500                 XS_XS_STOPPED);
1501 }
1502
1503 static bool dma32_rxstopped(dma_info_t *di)
1504 {
1505         return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) ==
1506                 RS_RS_STOPPED);
1507 }
1508
1509 static bool dma32_alloc(dma_info_t *di, uint direction)
1510 {
1511         uint size;
1512         uint ddlen;
1513         void *va;
1514         uint alloced;
1515         u16 align;
1516         u16 align_bits;
1517
1518         ddlen = sizeof(dma32dd_t);
1519
1520         size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
1521
1522         alloced = 0;
1523         align_bits = di->dmadesc_align;
1524         align = (1 << align_bits);
1525
1526         if (direction == DMA_TX) {
1527                 va = dma_ringalloc(di->osh, D32RINGALIGN, size, &align_bits,
1528                         &alloced, &di->txdpaorig, &di->tx_dmah);
1529                 if (va == NULL) {
1530                         DMA_ERROR(("%s: dma_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
1531                         return false;
1532                 }
1533
1534                 PHYSADDRHISET(di->txdpa, 0);
1535                 ASSERT(PHYSADDRHI(di->txdpaorig) == 0);
1536                 di->txd32 = (dma32dd_t *) roundup((unsigned long)va, align);
1537                 di->txdalign =
1538                     (uint) ((s8 *)di->txd32 - (s8 *) va);
1539
1540                 PHYSADDRLOSET(di->txdpa,
1541                               PHYSADDRLO(di->txdpaorig) + di->txdalign);
1542                 /* Make sure that alignment didn't overflow */
1543                 ASSERT(PHYSADDRLO(di->txdpa) >= PHYSADDRLO(di->txdpaorig));
1544
1545                 di->txdalloc = alloced;
1546                 ASSERT(IS_ALIGNED((unsigned long)di->txd32, align));
1547         } else {
1548                 va = dma_ringalloc(di->osh, D32RINGALIGN, size, &align_bits,
1549                         &alloced, &di->rxdpaorig, &di->rx_dmah);
1550                 if (va == NULL) {
1551                         DMA_ERROR(("%s: dma_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
1552                         return false;
1553                 }
1554
1555                 PHYSADDRHISET(di->rxdpa, 0);
1556                 ASSERT(PHYSADDRHI(di->rxdpaorig) == 0);
1557                 di->rxd32 = (dma32dd_t *) roundup((unsigned long)va, align);
1558                 di->rxdalign =
1559                     (uint) ((s8 *)di->rxd32 - (s8 *) va);
1560
1561                 PHYSADDRLOSET(di->rxdpa,
1562                               PHYSADDRLO(di->rxdpaorig) + di->rxdalign);
1563                 /* Make sure that alignment didn't overflow */
1564                 ASSERT(PHYSADDRLO(di->rxdpa) >= PHYSADDRLO(di->rxdpaorig));
1565                 di->rxdalloc = alloced;
1566                 ASSERT(IS_ALIGNED((unsigned long)di->rxd32, align));
1567         }
1568
1569         return true;
1570 }
1571
1572 static bool dma32_txreset(dma_info_t *di)
1573 {
1574         u32 status;
1575
1576         if (di->ntxd == 0)
1577                 return true;
1578
1579         /* suspend tx DMA first */
1580         W_REG(di->osh, &di->d32txregs->control, XC_SE);
1581         SPINWAIT(((status =
1582                    (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK))
1583                   != XS_XS_DISABLED) && (status != XS_XS_IDLE)
1584                  && (status != XS_XS_STOPPED), (10000));
1585
1586         W_REG(di->osh, &di->d32txregs->control, 0);
1587         SPINWAIT(((status = (R_REG(di->osh,
1588                                    &di->d32txregs->status) & XS_XS_MASK)) !=
1589                   XS_XS_DISABLED), 10000);
1590
1591         /* wait for the last transaction to complete */
1592         udelay(300);
1593
1594         return status == XS_XS_DISABLED;
1595 }
1596
1597 static bool dma32_rxidle(dma_info_t *di)
1598 {
1599         DMA_TRACE(("%s: dma_rxidle\n", di->name));
1600
1601         if (di->nrxd == 0)
1602                 return true;
1603
1604         return ((R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK) ==
1605                 R_REG(di->osh, &di->d32rxregs->ptr));
1606 }
1607
1608 static bool dma32_rxreset(dma_info_t *di)
1609 {
1610         u32 status;
1611
1612         if (di->nrxd == 0)
1613                 return true;
1614
1615         W_REG(di->osh, &di->d32rxregs->control, 0);
1616         SPINWAIT(((status = (R_REG(di->osh,
1617                                    &di->d32rxregs->status) & RS_RS_MASK)) !=
1618                   RS_RS_DISABLED), 10000);
1619
1620         return status == RS_RS_DISABLED;
1621 }
1622
1623 static bool dma32_rxenabled(dma_info_t *di)
1624 {
1625         u32 rc;
1626
1627         rc = R_REG(di->osh, &di->d32rxregs->control);
1628         return (rc != 0xffffffff) && (rc & RC_RE);
1629 }
1630
1631 static bool dma32_txsuspendedidle(dma_info_t *di)
1632 {
1633         if (di->ntxd == 0)
1634                 return true;
1635
1636         if (!(R_REG(di->osh, &di->d32txregs->control) & XC_SE))
1637                 return 0;
1638
1639         if ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE)
1640                 return 0;
1641
1642         udelay(2);
1643         return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) ==
1644                 XS_XS_IDLE);
1645 }
1646
1647 /* !! tx entry routine
1648  * supports full 32bit dma engine buffer addressing so
1649  * dma buffers can cross 4 Kbyte page boundaries.
1650  *
1651  * WARNING: call must check the return value for error.
1652  *   the error(toss frames) could be fatal and cause many subsequent hard to debug problems
1653  */
1654 static int dma32_txfast(dma_info_t *di, void *p0, bool commit)
1655 {
1656         void *p, *next;
1657         unsigned char *data;
1658         uint len;
1659         u16 txout;
1660         u32 flags = 0;
1661         dmaaddr_t pa;
1662
1663         DMA_TRACE(("%s: dma_txfast\n", di->name));
1664
1665         txout = di->txout;
1666
1667         /*
1668          * Walk the chain of packet buffers
1669          * allocating and initializing transmit descriptor entries.
1670          */
1671         for (p = p0; p; p = next) {
1672                 uint nsegs, j;
1673                 hnddma_seg_map_t *map;
1674
1675                 data = PKTDATA(p);
1676                 len = PKTLEN(p);
1677 #ifdef BCM_DMAPAD
1678                 len += PKTDMAPAD(di->osh, p);
1679 #endif
1680                 next = PKTNEXT(p);
1681
1682                 /* return nonzero if out of tx descriptors */
1683                 if (NEXTTXD(txout) == di->txin)
1684                         goto outoftxd;
1685
1686                 if (len == 0)
1687                         continue;
1688
1689                 if (DMASGLIST_ENAB)
1690                         bzero(&di->txp_dmah[txout], sizeof(hnddma_seg_map_t));
1691
1692                 /* get physical address of buffer start */
1693                 pa = DMA_MAP(di->osh, data, len, DMA_TX, p,
1694                              &di->txp_dmah[txout]);
1695
1696                 if (DMASGLIST_ENAB) {
1697                         map = &di->txp_dmah[txout];
1698
1699                         /* See if all the segments can be accounted for */
1700                         if (map->nsegs >
1701                             (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) -
1702                                     1))
1703                                 goto outoftxd;
1704
1705                         nsegs = map->nsegs;
1706                 } else
1707                         nsegs = 1;
1708
1709                 for (j = 1; j <= nsegs; j++) {
1710                         flags = 0;
1711                         if (p == p0 && j == 1)
1712                                 flags |= CTRL_SOF;
1713
1714                         /* With a DMA segment list, Descriptor table is filled
1715                          * using the segment list instead of looping over
1716                          * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when
1717                          * end of segment list is reached.
1718                          */
1719                         if ((!DMASGLIST_ENAB && next == NULL) ||
1720                             (DMASGLIST_ENAB && j == nsegs))
1721                                 flags |= (CTRL_IOC | CTRL_EOF);
1722                         if (txout == (di->ntxd - 1))
1723                                 flags |= CTRL_EOT;
1724
1725                         if (DMASGLIST_ENAB) {
1726                                 len = map->segs[j - 1].length;
1727                                 pa = map->segs[j - 1].addr;
1728                         }
1729                         ASSERT(PHYSADDRHI(pa) == 0);
1730
1731                         dma32_dd_upd(di, di->txd32, pa, txout, &flags, len);
1732                         ASSERT(di->txp[txout] == NULL);
1733
1734                         txout = NEXTTXD(txout);
1735                 }
1736
1737                 /* See above. No need to loop over individual buffers */
1738                 if (DMASGLIST_ENAB)
1739                         break;
1740         }
1741
1742         /* if last txd eof not set, fix it */
1743         if (!(flags & CTRL_EOF))
1744                 W_SM(&di->txd32[PREVTXD(txout)].ctrl,
1745                      BUS_SWAP32(flags | CTRL_IOC | CTRL_EOF));
1746
1747         /* save the packet */
1748         di->txp[PREVTXD(txout)] = p0;
1749
1750         /* bump the tx descriptor index */
1751         di->txout = txout;
1752
1753         /* kick the chip */
1754         if (commit)
1755                 W_REG(di->osh, &di->d32txregs->ptr, I2B(txout, dma32dd_t));
1756
1757         /* tx flow control */
1758         di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1759
1760         return 0;
1761
1762  outoftxd:
1763         DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name));
1764         PKTFREE(di->osh, p0, true);
1765         di->hnddma.txavail = 0;
1766         di->hnddma.txnobuf++;
1767         return -1;
1768 }
1769
1770 /*
1771  * Reclaim next completed txd (txds if using chained buffers) in the range
1772  * specified and return associated packet.
1773  * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be
1774  * transmitted as noted by the hardware "CurrDescr" pointer.
1775  * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be
1776  * transfered by the DMA as noted by the hardware "ActiveDescr" pointer.
1777  * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
1778  * return associated packet regardless of the value of hardware pointers.
1779  */
1780 static void *dma32_getnexttxp(dma_info_t *di, txd_range_t range)
1781 {
1782         u16 start, end, i;
1783         u16 active_desc;
1784         void *txp;
1785
1786         DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name,
1787                    (range == HNDDMA_RANGE_ALL) ? "all" :
1788                    ((range ==
1789                      HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
1790                     "transfered")));
1791
1792         if (di->ntxd == 0)
1793                 return NULL;
1794
1795         txp = NULL;
1796
1797         start = di->txin;
1798         if (range == HNDDMA_RANGE_ALL)
1799                 end = di->txout;
1800         else {
1801                 dma32regs_t *dregs = di->d32txregs;
1802
1803                 end =
1804                     (u16) B2I(R_REG(di->osh, &dregs->status) & XS_CD_MASK,
1805                                  dma32dd_t);
1806
1807                 if (range == HNDDMA_RANGE_TRANSFERED) {
1808                         active_desc =
1809                             (u16) ((R_REG(di->osh, &dregs->status) &
1810                                        XS_AD_MASK) >> XS_AD_SHIFT);
1811                         active_desc = (u16) B2I(active_desc, dma32dd_t);
1812                         if (end != active_desc)
1813                                 end = PREVTXD(active_desc);
1814                 }
1815         }
1816
1817         if ((start == 0) && (end > di->txout))
1818                 goto bogus;
1819
1820         for (i = start; i != end && !txp; i = NEXTTXD(i)) {
1821                 dmaaddr_t pa;
1822                 hnddma_seg_map_t *map = NULL;
1823                 uint size, j, nsegs;
1824
1825                 PHYSADDRLOSET(pa,
1826                               (BUS_SWAP32(R_SM(&di->txd32[i].addr)) -
1827                                di->dataoffsetlow));
1828                 PHYSADDRHISET(pa, 0);
1829
1830                 if (DMASGLIST_ENAB) {
1831                         map = &di->txp_dmah[i];
1832                         size = map->origsize;
1833                         nsegs = map->nsegs;
1834                 } else {
1835                         size =
1836                             (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) &
1837                              CTRL_BC_MASK);
1838                         nsegs = 1;
1839                 }
1840
1841                 for (j = nsegs; j > 0; j--) {
1842                         W_SM(&di->txd32[i].addr, 0xdeadbeef);
1843
1844                         txp = di->txp[i];
1845                         di->txp[i] = NULL;
1846                         if (j > 1)
1847                                 i = NEXTTXD(i);
1848                 }
1849
1850                 DMA_UNMAP(di->osh, pa, size, DMA_TX, txp, map);
1851         }
1852
1853         di->txin = i;
1854
1855         /* tx flow control */
1856         di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1857
1858         return txp;
1859
1860  bogus:
1861         DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall));
1862         return NULL;
1863 }
1864
1865 static void *dma32_getnextrxp(dma_info_t *di, bool forceall)
1866 {
1867         uint i, curr;
1868         void *rxp;
1869         dmaaddr_t pa;
1870         /* if forcing, dma engine must be disabled */
1871         ASSERT(!forceall || !dma32_rxenabled(di));
1872
1873         i = di->rxin;
1874
1875         /* return if no packets posted */
1876         if (i == di->rxout)
1877                 return NULL;
1878
1879         curr =
1880             B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t);
1881
1882         /* ignore curr if forceall */
1883         if (!forceall && (i == curr))
1884                 return NULL;
1885
1886         /* get the packet pointer that corresponds to the rx descriptor */
1887         rxp = di->rxp[i];
1888         ASSERT(rxp);
1889         di->rxp[i] = NULL;
1890
1891         PHYSADDRLOSET(pa,
1892                       (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) -
1893                        di->dataoffsetlow));
1894         PHYSADDRHISET(pa, 0);
1895
1896         /* clear this packet from the descriptor ring */
1897         DMA_UNMAP(di->osh, pa, di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]);
1898
1899         W_SM(&di->rxd32[i].addr, 0xdeadbeef);
1900
1901         di->rxin = NEXTRXD(i);
1902
1903         return rxp;
1904 }
1905
1906 /*
1907  * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
1908  */
1909 static void dma32_txrotate(dma_info_t *di)
1910 {
1911         u16 ad;
1912         uint nactive;
1913         uint rot;
1914         u16 old, new;
1915         u32 w;
1916         u16 first, last;
1917
1918         ASSERT(dma32_txsuspendedidle(di));
1919
1920         nactive = _dma_txactive(di);
1921         ad = (u16) (B2I
1922                        (((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK)
1923                          >> XS_AD_SHIFT), dma32dd_t));
1924         rot = TXD(ad - di->txin);
1925
1926         ASSERT(rot < di->ntxd);
1927
1928         /* full-ring case is a lot harder - don't worry about this */
1929         if (rot >= (di->ntxd - nactive)) {
1930                 DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
1931                 return;
1932         }
1933
1934         first = di->txin;
1935         last = PREVTXD(di->txout);
1936
1937         /* move entries starting at last and moving backwards to first */
1938         for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
1939                 new = TXD(old + rot);
1940
1941                 /*
1942                  * Move the tx dma descriptor.
1943                  * EOT is set only in the last entry in the ring.
1944                  */
1945                 w = BUS_SWAP32(R_SM(&di->txd32[old].ctrl)) & ~CTRL_EOT;
1946                 if (new == (di->ntxd - 1))
1947                         w |= CTRL_EOT;
1948                 W_SM(&di->txd32[new].ctrl, BUS_SWAP32(w));
1949                 W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr));
1950
1951                 /* zap the old tx dma descriptor address field */
1952                 W_SM(&di->txd32[old].addr, BUS_SWAP32(0xdeadbeef));
1953
1954                 /* move the corresponding txp[] entry */
1955                 ASSERT(di->txp[new] == NULL);
1956                 di->txp[new] = di->txp[old];
1957
1958                 /* Move the segment map as well */
1959                 if (DMASGLIST_ENAB) {
1960                         bcopy(&di->txp_dmah[old], &di->txp_dmah[new],
1961                               sizeof(hnddma_seg_map_t));
1962                         bzero(&di->txp_dmah[old], sizeof(hnddma_seg_map_t));
1963                 }
1964
1965                 di->txp[old] = NULL;
1966         }
1967
1968         /* update txin and txout */
1969         di->txin = ad;
1970         di->txout = TXD(di->txout + rot);
1971         di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1972
1973         /* kick the chip */
1974         W_REG(di->osh, &di->d32txregs->ptr, I2B(di->txout, dma32dd_t));
1975 }
1976
1977 /* 64-bit DMA functions */
1978
1979 static void dma64_txinit(dma_info_t *di)
1980 {
1981         u32 control = D64_XC_XE;
1982
1983         DMA_TRACE(("%s: dma_txinit\n", di->name));
1984
1985         if (di->ntxd == 0)
1986                 return;
1987
1988         di->txin = di->txout = 0;
1989         di->hnddma.txavail = di->ntxd - 1;
1990
1991         /* clear tx descriptor ring */
1992         BZERO_SM((void *)di->txd64, (di->ntxd * sizeof(dma64dd_t)));
1993
1994         /* DMA engine with out alignment requirement requires table to be inited
1995          * before enabling the engine
1996          */
1997         if (!di->aligndesc_4k)
1998                 _dma_ddtable_init(di, DMA_TX, di->txdpa);
1999
2000         if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0)
2001                 control |= D64_XC_PD;
2002         OR_REG(di->osh, &di->d64txregs->control, control);
2003
2004         /* DMA engine with alignment requirement requires table to be inited
2005          * before enabling the engine
2006          */
2007         if (di->aligndesc_4k)
2008                 _dma_ddtable_init(di, DMA_TX, di->txdpa);
2009 }
2010
2011 static bool dma64_txenabled(dma_info_t *di)
2012 {
2013         u32 xc;
2014
2015         /* If the chip is dead, it is not enabled :-) */
2016         xc = R_REG(di->osh, &di->d64txregs->control);
2017         return (xc != 0xffffffff) && (xc & D64_XC_XE);
2018 }
2019
2020 static void dma64_txsuspend(dma_info_t *di)
2021 {
2022         DMA_TRACE(("%s: dma_txsuspend\n", di->name));
2023
2024         if (di->ntxd == 0)
2025                 return;
2026
2027         OR_REG(di->osh, &di->d64txregs->control, D64_XC_SE);
2028 }
2029
2030 static void dma64_txresume(dma_info_t *di)
2031 {
2032         DMA_TRACE(("%s: dma_txresume\n", di->name));
2033
2034         if (di->ntxd == 0)
2035                 return;
2036
2037         AND_REG(di->osh, &di->d64txregs->control, ~D64_XC_SE);
2038 }
2039
2040 static bool dma64_txsuspended(dma_info_t *di)
2041 {
2042         return (di->ntxd == 0) ||
2043             ((R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE) ==
2044              D64_XC_SE);
2045 }
2046
2047 static void BCMFASTPATH dma64_txreclaim(dma_info_t *di, txd_range_t range)
2048 {
2049         void *p;
2050
2051         DMA_TRACE(("%s: dma_txreclaim %s\n", di->name,
2052                    (range == HNDDMA_RANGE_ALL) ? "all" :
2053                    ((range ==
2054                      HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
2055                     "transfered")));
2056
2057         if (di->txin == di->txout)
2058                 return;
2059
2060         while ((p = dma64_getnexttxp(di, range))) {
2061                 /* For unframed data, we don't have any packets to free */
2062                 if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED))
2063                         PKTFREE(di->osh, p, true);
2064         }
2065 }
2066
2067 static bool dma64_txstopped(dma_info_t *di)
2068 {
2069         return ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) ==
2070                 D64_XS0_XS_STOPPED);
2071 }
2072
2073 static bool dma64_rxstopped(dma_info_t *di)
2074 {
2075         return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK) ==
2076                 D64_RS0_RS_STOPPED);
2077 }
2078
2079 static bool dma64_alloc(dma_info_t *di, uint direction)
2080 {
2081         u16 size;
2082         uint ddlen;
2083         void *va;
2084         uint alloced = 0;
2085         u16 align;
2086         u16 align_bits;
2087
2088         ddlen = sizeof(dma64dd_t);
2089
2090         size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
2091         align_bits = di->dmadesc_align;
2092         align = (1 << align_bits);
2093
2094         if (direction == DMA_TX) {
2095                 va = dma_ringalloc(di->osh, D64RINGALIGN, size, &align_bits,
2096                         &alloced, &di->txdpaorig, &di->tx_dmah);
2097                 if (va == NULL) {
2098                         DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
2099                         return false;
2100                 }
2101                 align = (1 << align_bits);
2102                 di->txd64 = (dma64dd_t *) roundup((unsigned long)va, align);
2103                 di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va);
2104                 PHYSADDRLOSET(di->txdpa,
2105                               PHYSADDRLO(di->txdpaorig) + di->txdalign);
2106                 /* Make sure that alignment didn't overflow */
2107                 ASSERT(PHYSADDRLO(di->txdpa) >= PHYSADDRLO(di->txdpaorig));
2108
2109                 PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig));
2110                 di->txdalloc = alloced;
2111                 ASSERT(IS_ALIGNED((unsigned long)di->txd64, align));
2112         } else {
2113                 va = dma_ringalloc(di->osh, D64RINGALIGN, size, &align_bits,
2114                         &alloced, &di->rxdpaorig, &di->rx_dmah);
2115                 if (va == NULL) {
2116                         DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
2117                         return false;
2118                 }
2119                 align = (1 << align_bits);
2120                 di->rxd64 = (dma64dd_t *) roundup((unsigned long)va, align);
2121                 di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va);
2122                 PHYSADDRLOSET(di->rxdpa,
2123                               PHYSADDRLO(di->rxdpaorig) + di->rxdalign);
2124                 /* Make sure that alignment didn't overflow */
2125                 ASSERT(PHYSADDRLO(di->rxdpa) >= PHYSADDRLO(di->rxdpaorig));
2126
2127                 PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig));
2128                 di->rxdalloc = alloced;
2129                 ASSERT(IS_ALIGNED((unsigned long)di->rxd64, align));
2130         }
2131
2132         return true;
2133 }
2134
2135 static bool dma64_txreset(dma_info_t *di)
2136 {
2137         u32 status;
2138
2139         if (di->ntxd == 0)
2140                 return true;
2141
2142         /* suspend tx DMA first */
2143         W_REG(di->osh, &di->d64txregs->control, D64_XC_SE);
2144         SPINWAIT(((status =
2145                    (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK))
2146                   != D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
2147                  && (status != D64_XS0_XS_STOPPED), 10000);
2148
2149         W_REG(di->osh, &di->d64txregs->control, 0);
2150         SPINWAIT(((status =
2151                    (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK))
2152                   != D64_XS0_XS_DISABLED), 10000);
2153
2154         /* wait for the last transaction to complete */
2155         udelay(300);
2156
2157         return status == D64_XS0_XS_DISABLED;
2158 }
2159
2160 static bool dma64_rxidle(dma_info_t *di)
2161 {
2162         DMA_TRACE(("%s: dma_rxidle\n", di->name));
2163
2164         if (di->nrxd == 0)
2165                 return true;
2166
2167         return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
2168                 (R_REG(di->osh, &di->d64rxregs->ptr) & D64_RS0_CD_MASK));
2169 }
2170
2171 static bool dma64_rxreset(dma_info_t *di)
2172 {
2173         u32 status;
2174
2175         if (di->nrxd == 0)
2176                 return true;
2177
2178         W_REG(di->osh, &di->d64rxregs->control, 0);
2179         SPINWAIT(((status =
2180                    (R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK))
2181                   != D64_RS0_RS_DISABLED), 10000);
2182
2183         return status == D64_RS0_RS_DISABLED;
2184 }
2185
2186 static bool dma64_rxenabled(dma_info_t *di)
2187 {
2188         u32 rc;
2189
2190         rc = R_REG(di->osh, &di->d64rxregs->control);
2191         return (rc != 0xffffffff) && (rc & D64_RC_RE);
2192 }
2193
2194 static bool dma64_txsuspendedidle(dma_info_t *di)
2195 {
2196
2197         if (di->ntxd == 0)
2198                 return true;
2199
2200         if (!(R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE))
2201                 return 0;
2202
2203         if ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) ==
2204             D64_XS0_XS_IDLE)
2205                 return 1;
2206
2207         return 0;
2208 }
2209
2210 /* Useful when sending unframed data.  This allows us to get a progress report from the DMA.
2211  * We return a pointer to the beginning of the DATA buffer of the current descriptor.
2212  * If DMA is idle, we return NULL.
2213  */
2214 static void *dma64_getpos(dma_info_t *di, bool direction)
2215 {
2216         void *va;
2217         bool idle;
2218         u32 cd_offset;
2219
2220         if (direction == DMA_TX) {
2221                 cd_offset =
2222                     R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK;
2223                 idle = !NTXDACTIVE(di->txin, di->txout);
2224                 va = di->txp[B2I(cd_offset, dma64dd_t)];
2225         } else {
2226                 cd_offset =
2227                     R_REG(di->osh, &di->d64rxregs->status0) & D64_XS0_CD_MASK;
2228                 idle = !NRXDACTIVE(di->rxin, di->rxout);
2229                 va = di->rxp[B2I(cd_offset, dma64dd_t)];
2230         }
2231
2232         /* If DMA is IDLE, return NULL */
2233         if (idle) {
2234                 DMA_TRACE(("%s: DMA idle, return NULL\n", __func__));
2235                 va = NULL;
2236         }
2237
2238         return va;
2239 }
2240
2241 /* TX of unframed data
2242  *
2243  * Adds a DMA ring descriptor for the data pointed to by "buf".
2244  * This is for DMA of a buffer of data and is unlike other hnddma TX functions
2245  * that take a pointer to a "packet"
2246  * Each call to this is results in a single descriptor being added for "len" bytes of
2247  * data starting at "buf", it doesn't handle chained buffers.
2248  */
2249 static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit)
2250 {
2251         u16 txout;
2252         u32 flags = 0;
2253         dmaaddr_t pa;           /* phys addr */
2254
2255         txout = di->txout;
2256
2257         /* return nonzero if out of tx descriptors */
2258         if (NEXTTXD(txout) == di->txin)
2259                 goto outoftxd;
2260
2261         if (len == 0)
2262                 return 0;
2263
2264         pa = DMA_MAP(di->osh, buf, len, DMA_TX, NULL, &di->txp_dmah[txout]);
2265
2266         flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF);
2267
2268         if (txout == (di->ntxd - 1))
2269                 flags |= D64_CTRL1_EOT;
2270
2271         dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
2272         ASSERT(di->txp[txout] == NULL);
2273
2274         /* save the buffer pointer - used by dma_getpos */
2275         di->txp[txout] = buf;
2276
2277         txout = NEXTTXD(txout);
2278         /* bump the tx descriptor index */
2279         di->txout = txout;
2280
2281         /* kick the chip */
2282         if (commit) {
2283                 W_REG(di->osh, &di->d64txregs->ptr,
2284                       di->xmtptrbase + I2B(txout, dma64dd_t));
2285         }
2286
2287         /* tx flow control */
2288         di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
2289
2290         return 0;
2291
2292  outoftxd:
2293         DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __func__));
2294         di->hnddma.txavail = 0;
2295         di->hnddma.txnobuf++;
2296         return -1;
2297 }
2298
2299 /* !! tx entry routine
2300  * WARNING: call must check the return value for error.
2301  *   the error(toss frames) could be fatal and cause many subsequent hard to debug problems
2302  */
2303 static int BCMFASTPATH dma64_txfast(dma_info_t *di, void *p0, bool commit)
2304 {
2305         void *p, *next;
2306         unsigned char *data;
2307         uint len;
2308         u16 txout;
2309         u32 flags = 0;
2310         dmaaddr_t pa;
2311
2312         DMA_TRACE(("%s: dma_txfast\n", di->name));
2313
2314         txout = di->txout;
2315
2316         /*
2317          * Walk the chain of packet buffers
2318          * allocating and initializing transmit descriptor entries.
2319          */
2320         for (p = p0; p; p = next) {
2321                 uint nsegs, j;
2322                 hnddma_seg_map_t *map;
2323
2324                 data = PKTDATA(p);
2325                 len = PKTLEN(p);
2326 #ifdef BCM_DMAPAD
2327                 len += PKTDMAPAD(di->osh, p);
2328 #endif                          /* BCM_DMAPAD */
2329                 next = PKTNEXT(p);
2330
2331                 /* return nonzero if out of tx descriptors */
2332                 if (NEXTTXD(txout) == di->txin)
2333                         goto outoftxd;
2334
2335                 if (len == 0)
2336                         continue;
2337
2338                 /* get physical address of buffer start */
2339                 if (DMASGLIST_ENAB)
2340                         bzero(&di->txp_dmah[txout], sizeof(hnddma_seg_map_t));
2341
2342                 pa = DMA_MAP(di->osh, data, len, DMA_TX, p,
2343                              &di->txp_dmah[txout]);
2344
2345                 if (DMASGLIST_ENAB) {
2346                         map = &di->txp_dmah[txout];
2347
2348                         /* See if all the segments can be accounted for */
2349                         if (map->nsegs >
2350                             (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) -
2351                                     1))
2352                                 goto outoftxd;
2353
2354                         nsegs = map->nsegs;
2355                 } else
2356                         nsegs = 1;
2357
2358                 for (j = 1; j <= nsegs; j++) {
2359                         flags = 0;
2360                         if (p == p0 && j == 1)
2361                                 flags |= D64_CTRL1_SOF;
2362
2363                         /* With a DMA segment list, Descriptor table is filled
2364                          * using the segment list instead of looping over
2365                          * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when
2366                          * end of segment list is reached.
2367                          */
2368                         if ((!DMASGLIST_ENAB && next == NULL) ||
2369                             (DMASGLIST_ENAB && j == nsegs))
2370                                 flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
2371                         if (txout == (di->ntxd - 1))
2372                                 flags |= D64_CTRL1_EOT;
2373
2374                         if (DMASGLIST_ENAB) {
2375                                 len = map->segs[j - 1].length;
2376                                 pa = map->segs[j - 1].addr;
2377                         }
2378                         dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
2379                         ASSERT(di->txp[txout] == NULL);
2380
2381                         txout = NEXTTXD(txout);
2382                 }
2383
2384                 /* See above. No need to loop over individual buffers */
2385                 if (DMASGLIST_ENAB)
2386                         break;
2387         }
2388
2389         /* if last txd eof not set, fix it */
2390         if (!(flags & D64_CTRL1_EOF))
2391                 W_SM(&di->txd64[PREVTXD(txout)].ctrl1,
2392                      BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
2393
2394         /* save the packet */
2395         di->txp[PREVTXD(txout)] = p0;
2396
2397         /* bump the tx descriptor index */
2398         di->txout = txout;
2399
2400         /* kick the chip */
2401         if (commit)
2402                 W_REG(di->osh, &di->d64txregs->ptr,
2403                       di->xmtptrbase + I2B(txout, dma64dd_t));
2404
2405         /* tx flow control */
2406         di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
2407
2408         return 0;
2409
2410  outoftxd:
2411         DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name));
2412         PKTFREE(di->osh, p0, true);
2413         di->hnddma.txavail = 0;
2414         di->hnddma.txnobuf++;
2415         return -1;
2416 }
2417
2418 /*
2419  * Reclaim next completed txd (txds if using chained buffers) in the range
2420  * specified and return associated packet.
2421  * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be
2422  * transmitted as noted by the hardware "CurrDescr" pointer.
2423  * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be
2424  * transfered by the DMA as noted by the hardware "ActiveDescr" pointer.
2425  * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
2426  * return associated packet regardless of the value of hardware pointers.
2427  */
2428 static void *BCMFASTPATH dma64_getnexttxp(dma_info_t *di, txd_range_t range)
2429 {
2430         u16 start, end, i;
2431         u16 active_desc;
2432         void *txp;
2433
2434         DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name,
2435                    (range == HNDDMA_RANGE_ALL) ? "all" :
2436                    ((range ==
2437                      HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
2438                     "transfered")));
2439
2440         if (di->ntxd == 0)
2441                 return NULL;
2442
2443         txp = NULL;
2444
2445         start = di->txin;
2446         if (range == HNDDMA_RANGE_ALL)
2447                 end = di->txout;
2448         else {
2449                 dma64regs_t *dregs = di->d64txregs;
2450
2451                 end =
2452                     (u16) (B2I
2453                               (((R_REG(di->osh, &dregs->status0) &
2454                                  D64_XS0_CD_MASK) -
2455                                 di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t));
2456
2457                 if (range == HNDDMA_RANGE_TRANSFERED) {
2458                         active_desc =
2459                             (u16) (R_REG(di->osh, &dregs->status1) &
2460                                       D64_XS1_AD_MASK);
2461                         active_desc =
2462                             (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
2463                         active_desc = B2I(active_desc, dma64dd_t);
2464                         if (end != active_desc)
2465                                 end = PREVTXD(active_desc);
2466                 }
2467         }
2468
2469         if ((start == 0) && (end > di->txout))
2470                 goto bogus;
2471
2472         for (i = start; i != end && !txp; i = NEXTTXD(i)) {
2473                 dmaaddr_t pa;
2474                 hnddma_seg_map_t *map = NULL;
2475                 uint size, j, nsegs;
2476
2477                 PHYSADDRLOSET(pa,
2478                               (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) -
2479                                di->dataoffsetlow));
2480                 PHYSADDRHISET(pa,
2481                               (BUS_SWAP32(R_SM(&di->txd64[i].addrhigh)) -
2482                                di->dataoffsethigh));
2483
2484                 if (DMASGLIST_ENAB) {
2485                         map = &di->txp_dmah[i];
2486                         size = map->origsize;
2487                         nsegs = map->nsegs;
2488                 } else {
2489                         size =
2490                             (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) &
2491                              D64_CTRL2_BC_MASK);
2492                         nsegs = 1;
2493                 }
2494
2495                 for (j = nsegs; j > 0; j--) {
2496                         W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
2497                         W_SM(&di->txd64[i].addrhigh, 0xdeadbeef);
2498
2499                         txp = di->txp[i];
2500                         di->txp[i] = NULL;
2501                         if (j > 1)
2502                                 i = NEXTTXD(i);
2503                 }
2504
2505                 DMA_UNMAP(di->osh, pa, size, DMA_TX, txp, map);
2506         }
2507
2508         di->txin = i;
2509
2510         /* tx flow control */
2511         di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
2512
2513         return txp;
2514
2515  bogus:
2516         DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall));
2517         return NULL;
2518 }
2519
2520 static void *BCMFASTPATH dma64_getnextrxp(dma_info_t *di, bool forceall)
2521 {
2522         uint i, curr;
2523         void *rxp;
2524         dmaaddr_t pa;
2525
2526         /* if forcing, dma engine must be disabled */
2527         ASSERT(!forceall || !dma64_rxenabled(di));
2528
2529         i = di->rxin;
2530
2531         /* return if no packets posted */
2532         if (i == di->rxout)
2533                 return NULL;
2534
2535         curr =
2536             B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) -
2537                  di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t);
2538
2539         /* ignore curr if forceall */
2540         if (!forceall && (i == curr))
2541                 return NULL;
2542
2543         /* get the packet pointer that corresponds to the rx descriptor */
2544         rxp = di->rxp[i];
2545         ASSERT(rxp);
2546         di->rxp[i] = NULL;
2547
2548         PHYSADDRLOSET(pa,
2549                       (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) -
2550                        di->dataoffsetlow));
2551         PHYSADDRHISET(pa,
2552                       (BUS_SWAP32(R_SM(&di->rxd64[i].addrhigh)) -
2553                        di->dataoffsethigh));
2554
2555         /* clear this packet from the descriptor ring */
2556         DMA_UNMAP(di->osh, pa, di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]);
2557
2558         W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
2559         W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
2560
2561         di->rxin = NEXTRXD(i);
2562
2563         return rxp;
2564 }
2565
2566 static bool _dma64_addrext(osl_t *osh, dma64regs_t * dma64regs)
2567 {
2568         u32 w;
2569         OR_REG(osh, &dma64regs->control, D64_XC_AE);
2570         w = R_REG(osh, &dma64regs->control);
2571         AND_REG(osh, &dma64regs->control, ~D64_XC_AE);
2572         return (w & D64_XC_AE) == D64_XC_AE;
2573 }
2574
2575 /*
2576  * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
2577  */
2578 static void dma64_txrotate(dma_info_t *di)
2579 {
2580         u16 ad;
2581         uint nactive;
2582         uint rot;
2583         u16 old, new;
2584         u32 w;
2585         u16 first, last;
2586
2587         ASSERT(dma64_txsuspendedidle(di));
2588
2589         nactive = _dma_txactive(di);
2590         ad = (u16) (B2I
2591                        ((((R_REG(di->osh, &di->d64txregs->status1) &
2592                            D64_XS1_AD_MASK)
2593                           - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t));
2594         rot = TXD(ad - di->txin);
2595
2596         ASSERT(rot < di->ntxd);
2597
2598         /* full-ring case is a lot harder - don't worry about this */
2599         if (rot >= (di->ntxd - nactive)) {
2600                 DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
2601                 return;
2602         }
2603
2604         first = di->txin;
2605         last = PREVTXD(di->txout);
2606
2607         /* move entries starting at last and moving backwards to first */
2608         for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
2609                 new = TXD(old + rot);
2610
2611                 /*
2612                  * Move the tx dma descriptor.
2613                  * EOT is set only in the last entry in the ring.
2614                  */
2615                 w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
2616                 if (new == (di->ntxd - 1))
2617                         w |= D64_CTRL1_EOT;
2618                 W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w));
2619
2620                 w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2));
2621                 W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w));
2622
2623                 W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
2624                 W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
2625
2626                 /* zap the old tx dma descriptor address field */
2627                 W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef));
2628                 W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef));
2629
2630                 /* move the corresponding txp[] entry */
2631                 ASSERT(di->txp[new] == NULL);
2632                 di->txp[new] = di->txp[old];
2633
2634                 /* Move the map */
2635                 if (DMASGLIST_ENAB) {
2636                         bcopy(&di->txp_dmah[old], &di->txp_dmah[new],
2637                               sizeof(hnddma_seg_map_t));
2638                         bzero(&di->txp_dmah[old], sizeof(hnddma_seg_map_t));
2639                 }
2640
2641                 di->txp[old] = NULL;
2642         }
2643
2644         /* update txin and txout */
2645         di->txin = ad;
2646         di->txout = TXD(di->txout + rot);
2647         di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
2648
2649         /* kick the chip */
2650         W_REG(di->osh, &di->d64txregs->ptr,
2651               di->xmtptrbase + I2B(di->txout, dma64dd_t));
2652 }
2653
2654 uint dma_addrwidth(si_t *sih, void *dmaregs)
2655 {
2656         dma32regs_t *dma32regs;
2657         osl_t *osh;
2658
2659         osh = si_osh(sih);
2660
2661         /* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */
2662         /* DMA engine is 64-bit capable */
2663         if ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) {
2664                 /* backplane are 64-bit capable */
2665                 if (si_backplane64(sih))
2666                         /* If bus is System Backplane or PCIE then we can access 64-bits */
2667                         if ((BUSTYPE(sih->bustype) == SI_BUS) ||
2668                             ((BUSTYPE(sih->bustype) == PCI_BUS) &&
2669                              (sih->buscoretype == PCIE_CORE_ID)))
2670                                 return DMADDRWIDTH_64;
2671
2672                 /* DMA64 is always 32-bit capable, AE is always true */
2673                 ASSERT(_dma64_addrext(osh, (dma64regs_t *) dmaregs));
2674
2675                 return DMADDRWIDTH_32;
2676         }
2677
2678         /* Start checking for 32-bit / 30-bit addressing */
2679         dma32regs = (dma32regs_t *) dmaregs;
2680
2681         /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */
2682         if ((BUSTYPE(sih->bustype) == SI_BUS) ||
2683             ((BUSTYPE(sih->bustype) == PCI_BUS)
2684              && sih->buscoretype == PCIE_CORE_ID)
2685             || (_dma32_addrext(osh, dma32regs)))
2686                 return DMADDRWIDTH_32;
2687
2688         /* Fallthru */
2689         return DMADDRWIDTH_30;
2690 }