]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/brcm80211/brcmsmac/dma.c
staging: brcm80211: removed 'hnd' from everything but function names
[mv-sheeva.git] / drivers / staging / brcm80211 / brcmsmac / dma.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 <linux/netdevice.h>
20 #include <linux/pci.h>
21 #include <bcmdefs.h>
22 #include <bcmdevs.h>
23 #include <bcmsoc.h>
24 #include <bcmutils.h>
25 #include <aiutils.h>
26
27 #include <sbdma.h>
28 #include <bcmdma.h>
29
30 #if defined(__mips__)
31 #include <asm/addrspace.h>
32 #endif
33
34 /* debug/trace */
35 #ifdef BCMDBG
36 #define DMA_ERROR(args) \
37         do { \
38                 if (!(*di->msg_level & 1)) \
39                         ; \
40                 else \
41                         printk args; \
42         } while (0)
43 #define DMA_TRACE(args) \
44         do { \
45                 if (!(*di->msg_level & 2)) \
46                         ; \
47                 else \
48                         printk args; \
49         } while (0)
50 #else
51 #define DMA_ERROR(args)
52 #define DMA_TRACE(args)
53 #endif                          /* BCMDBG */
54
55 #define DMA_NONE(args)
56
57 #define d64txregs       dregs.d64_u.txregs_64
58 #define d64rxregs       dregs.d64_u.rxregs_64
59 #define txd64           dregs.d64_u.txd_64
60 #define rxd64           dregs.d64_u.rxd_64
61
62 /* default dma message level (if input msg_level pointer is null in dma_attach()) */
63 static uint dma_msg_level;
64
65 #define MAXNAMEL        8       /* 8 char names */
66
67 #define DI_INFO(dmah)   ((dma_info_t *)dmah)
68
69 #define R_SM(r)         (*(r))
70 #define W_SM(r, v)      (*(r) = (v))
71
72 /* dma engine software state */
73 typedef struct dma_info {
74         struct dma_pub dma; /* exported structure */
75         uint *msg_level;        /* message level pointer */
76         char name[MAXNAMEL];    /* callers name for diag msgs */
77
78         void *pbus;             /* bus handle */
79
80         bool dma64;             /* this dma engine is operating in 64-bit mode */
81         bool addrext;           /* this dma engine supports DmaExtendedAddrChanges */
82
83         union {
84                 struct {
85                         dma64regs_t *txregs_64; /* 64-bit dma tx engine registers */
86                         dma64regs_t *rxregs_64; /* 64-bit dma rx engine registers */
87                         dma64dd_t *txd_64;      /* pointer to dma64 tx descriptor ring */
88                         dma64dd_t *rxd_64;      /* pointer to dma64 rx descriptor ring */
89                 } d64_u;
90         } dregs;
91
92         u16 dmadesc_align;      /* alignment requirement for dma descriptors */
93
94         u16 ntxd;               /* # tx descriptors tunable */
95         u16 txin;               /* index of next descriptor to reclaim */
96         u16 txout;              /* index of next descriptor to post */
97         void **txp;             /* pointer to parallel array of pointers to packets */
98         dma_seg_map_t *txp_dmah;        /* DMA MAP meta-data handle */
99         dmaaddr_t txdpa;        /* Aligned physical address of descriptor ring */
100         dmaaddr_t txdpaorig;    /* Original physical address of descriptor ring */
101         u16 txdalign;   /* #bytes added to alloc'd mem to align txd */
102         u32 txdalloc;   /* #bytes allocated for the ring */
103         u32 xmtptrbase; /* When using unaligned descriptors, the ptr register
104                                  * is not just an index, it needs all 13 bits to be
105                                  * an offset from the addr register.
106                                  */
107
108         u16 nrxd;               /* # rx descriptors tunable */
109         u16 rxin;               /* index of next descriptor to reclaim */
110         u16 rxout;              /* index of next descriptor to post */
111         void **rxp;             /* pointer to parallel array of pointers to packets */
112         dma_seg_map_t *rxp_dmah;        /* DMA MAP meta-data handle */
113         dmaaddr_t rxdpa;        /* Aligned physical address of descriptor ring */
114         dmaaddr_t rxdpaorig;    /* Original physical address of descriptor ring */
115         u16 rxdalign;   /* #bytes added to alloc'd mem to align rxd */
116         u32 rxdalloc;   /* #bytes allocated for the ring */
117         u32 rcvptrbase; /* Base for ptr reg when using unaligned descriptors */
118
119         /* tunables */
120         unsigned int rxbufsize; /* rx buffer size in bytes,
121                                  * not including the extra headroom
122                                  */
123         uint rxextrahdrroom;    /* extra rx headroom, reverseved to assist upper stack
124                                  *  e.g. some rx pkt buffers will be bridged to tx side
125                                  *  without byte copying. The extra headroom needs to be
126                                  *  large enough to fit txheader needs.
127                                  *  Some dongle driver may not need it.
128                                  */
129         uint nrxpost;           /* # rx buffers to keep posted */
130         unsigned int rxoffset;  /* rxcontrol offset */
131         uint ddoffsetlow;       /* add to get dma address of descriptor ring, low 32 bits */
132         uint ddoffsethigh;      /*   high 32 bits */
133         uint dataoffsetlow;     /* add to get dma address of data buffer, low 32 bits */
134         uint dataoffsethigh;    /*   high 32 bits */
135         bool aligndesc_4k;      /* descriptor base need to be aligned or not */
136 } dma_info_t;
137
138 /* DMA Scatter-gather list is supported. Note this is limited to TX direction only */
139 #ifdef BCMDMASGLISTOSL
140 #define DMASGLIST_ENAB true
141 #else
142 #define DMASGLIST_ENAB false
143 #endif                          /* BCMDMASGLISTOSL */
144
145 /* descriptor bumping macros */
146 #define XXD(x, n)       ((x) & ((n) - 1))       /* faster than %, but n must be power of 2 */
147 #define TXD(x)          XXD((x), di->ntxd)
148 #define RXD(x)          XXD((x), di->nrxd)
149 #define NEXTTXD(i)      TXD((i) + 1)
150 #define PREVTXD(i)      TXD((i) - 1)
151 #define NEXTRXD(i)      RXD((i) + 1)
152 #define PREVRXD(i)      RXD((i) - 1)
153
154 #define NTXDACTIVE(h, t)        TXD((t) - (h))
155 #define NRXDACTIVE(h, t)        RXD((t) - (h))
156
157 /* macros to convert between byte offsets and indexes */
158 #define B2I(bytes, type)        ((bytes) / sizeof(type))
159 #define I2B(index, type)        ((index) * sizeof(type))
160
161 #define PCI32ADDR_HIGH          0xc0000000      /* address[31:30] */
162 #define PCI32ADDR_HIGH_SHIFT    30      /* address[31:30] */
163
164 #define PCI64ADDR_HIGH          0x80000000      /* address[63] */
165 #define PCI64ADDR_HIGH_SHIFT    31      /* address[63] */
166
167 /* Common prototypes */
168 static bool _dma_isaddrext(dma_info_t *di);
169 static bool _dma_descriptor_align(dma_info_t *di);
170 static bool _dma_alloc(dma_info_t *di, uint direction);
171 static void _dma_detach(dma_info_t *di);
172 static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa);
173 static void _dma_rxinit(dma_info_t *di);
174 static void *_dma_rx(dma_info_t *di);
175 static bool _dma_rxfill(dma_info_t *di);
176 static void _dma_rxreclaim(dma_info_t *di);
177 static void _dma_rxenable(dma_info_t *di);
178 static void *_dma_getnextrxp(dma_info_t *di, bool forceall);
179 static void _dma_rx_param_get(dma_info_t *di, u16 *rxoffset,
180                               u16 *rxbufsize);
181
182 static void _dma_txblock(dma_info_t *di);
183 static void _dma_txunblock(dma_info_t *di);
184 static uint _dma_txactive(dma_info_t *di);
185 static uint _dma_rxactive(dma_info_t *di);
186 static uint _dma_txpending(dma_info_t *di);
187 static uint _dma_txcommitted(dma_info_t *di);
188
189 static void *_dma_peeknexttxp(dma_info_t *di);
190 static void *_dma_peeknextrxp(dma_info_t *di);
191 static unsigned long _dma_getvar(dma_info_t *di, const char *name);
192 static void _dma_counterreset(dma_info_t *di);
193 static void _dma_fifoloopbackenable(dma_info_t *di);
194 static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags);
195 static u8 dma_align_sizetobits(uint size);
196 static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size,
197                            u16 *alignbits, uint *alloced,
198                            dmaaddr_t *descpa);
199
200 /* Prototypes for 64-bit routines */
201 static bool dma64_alloc(dma_info_t *di, uint direction);
202 static bool dma64_txreset(dma_info_t *di);
203 static bool dma64_rxreset(dma_info_t *di);
204 static bool dma64_txsuspendedidle(dma_info_t *di);
205 static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, bool commit);
206 static int dma64_txunframed(dma_info_t *di, void *p0, uint len, bool commit);
207 static void *dma64_getpos(dma_info_t *di, bool direction);
208 static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range);
209 static void *dma64_getnextrxp(dma_info_t *di, bool forceall);
210 static void dma64_txrotate(dma_info_t *di);
211
212 static bool dma64_rxidle(dma_info_t *di);
213 static void dma64_txinit(dma_info_t *di);
214 static bool dma64_txenabled(dma_info_t *di);
215 static void dma64_txsuspend(dma_info_t *di);
216 static void dma64_txresume(dma_info_t *di);
217 static bool dma64_txsuspended(dma_info_t *di);
218 static void dma64_txreclaim(dma_info_t *di, txd_range_t range);
219 static bool dma64_txstopped(dma_info_t *di);
220 static bool dma64_rxstopped(dma_info_t *di);
221 static bool dma64_rxenabled(dma_info_t *di);
222 static bool _dma64_addrext(dma64regs_t *dma64regs);
223
224 static inline u32 parity32(u32 data);
225
226 const di_fcn_t dma64proc = {
227         (di_detach_t) _dma_detach,
228         (di_txinit_t) dma64_txinit,
229         (di_txreset_t) dma64_txreset,
230         (di_txenabled_t) dma64_txenabled,
231         (di_txsuspend_t) dma64_txsuspend,
232         (di_txresume_t) dma64_txresume,
233         (di_txsuspended_t) dma64_txsuspended,
234         (di_txsuspendedidle_t) dma64_txsuspendedidle,
235         (di_txfast_t) dma64_txfast,
236         (di_txunframed_t) dma64_txunframed,
237         (di_getpos_t) dma64_getpos,
238         (di_txstopped_t) dma64_txstopped,
239         (di_txreclaim_t) dma64_txreclaim,
240         (di_getnexttxp_t) dma64_getnexttxp,
241         (di_peeknexttxp_t) _dma_peeknexttxp,
242         (di_txblock_t) _dma_txblock,
243         (di_txunblock_t) _dma_txunblock,
244         (di_txactive_t) _dma_txactive,
245         (di_txrotate_t) dma64_txrotate,
246
247         (di_rxinit_t) _dma_rxinit,
248         (di_rxreset_t) dma64_rxreset,
249         (di_rxidle_t) dma64_rxidle,
250         (di_rxstopped_t) dma64_rxstopped,
251         (di_rxenable_t) _dma_rxenable,
252         (di_rxenabled_t) dma64_rxenabled,
253         (di_rx_t) _dma_rx,
254         (di_rxfill_t) _dma_rxfill,
255         (di_rxreclaim_t) _dma_rxreclaim,
256         (di_getnextrxp_t) _dma_getnextrxp,
257         (di_peeknextrxp_t) _dma_peeknextrxp,
258         (di_rxparam_get_t) _dma_rx_param_get,
259
260         (di_fifoloopbackenable_t) _dma_fifoloopbackenable,
261         (di_getvar_t) _dma_getvar,
262         (di_counterreset_t) _dma_counterreset,
263         (di_ctrlflags_t) _dma_ctrlflags,
264         NULL,
265         NULL,
266         NULL,
267         (di_rxactive_t) _dma_rxactive,
268         (di_txpending_t) _dma_txpending,
269         (di_txcommitted_t) _dma_txcommitted,
270         39
271 };
272
273 struct dma_pub *dma_attach(char *name, si_t *sih,
274                      void *dmaregstx, void *dmaregsrx, uint ntxd,
275                      uint nrxd, uint rxbufsize, int rxextheadroom,
276                      uint nrxpost, uint rxoffset, uint *msg_level)
277 {
278         dma_info_t *di;
279         uint size;
280
281         /* allocate private info structure */
282         di = kzalloc(sizeof(dma_info_t), GFP_ATOMIC);
283         if (di == NULL) {
284 #ifdef BCMDBG
285                 printk(KERN_ERR "dma_attach: out of memory\n");
286 #endif
287                 return NULL;
288         }
289
290         di->msg_level = msg_level ? msg_level : &dma_msg_level;
291
292
293         di->dma64 = ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64);
294
295         /* init dma reg pointer */
296         di->d64txregs = (dma64regs_t *) dmaregstx;
297         di->d64rxregs = (dma64regs_t *) dmaregsrx;
298         di->dma.di_fn = (const di_fcn_t *)&dma64proc;
299
300         /* Default flags (which can be changed by the driver calling dma_ctrlflags
301          * before enable): For backwards compatibility both Rx Overflow Continue
302          * and Parity are DISABLED.
303          * supports it.
304          */
305         di->dma.di_fn->ctrlflags(&di->dma, DMA_CTRL_ROC | DMA_CTRL_PEN,
306                                  0);
307
308         DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d "
309                    "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
310                    "dmaregstx %p dmaregsrx %p\n", name, "DMA64",
311                    di->dma.dmactrlflags, ntxd, nrxd, rxbufsize,
312                    rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx));
313
314         /* make a private copy of our callers name */
315         strncpy(di->name, name, MAXNAMEL);
316         di->name[MAXNAMEL - 1] = '\0';
317
318         di->pbus = ((struct si_info *)sih)->pbus;
319
320         /* save tunables */
321         di->ntxd = (u16) ntxd;
322         di->nrxd = (u16) nrxd;
323
324         /* the actual dma size doesn't include the extra headroom */
325         di->rxextrahdrroom =
326             (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
327         if (rxbufsize > BCMEXTRAHDROOM)
328                 di->rxbufsize = (u16) (rxbufsize - di->rxextrahdrroom);
329         else
330                 di->rxbufsize = (u16) rxbufsize;
331
332         di->nrxpost = (u16) nrxpost;
333         di->rxoffset = (u8) rxoffset;
334
335         /*
336          * figure out the DMA physical address offset for dd and data
337          *     PCI/PCIE: they map silicon backplace address to zero based memory, need offset
338          *     Other bus: use zero
339          *     SI_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
340          */
341         di->ddoffsetlow = 0;
342         di->dataoffsetlow = 0;
343         /* for pci bus, add offset */
344         if (sih->bustype == PCI_BUS) {
345                 /* pcie with DMA64 */
346                 di->ddoffsetlow = 0;
347                 di->ddoffsethigh = SI_PCIE_DMA_H32;
348                 di->dataoffsetlow = di->ddoffsetlow;
349                 di->dataoffsethigh = di->ddoffsethigh;
350         }
351 #if defined(__mips__) && defined(IL_BIGENDIAN)
352         di->dataoffsetlow = di->dataoffsetlow + SI_SDRAM_SWAPPED;
353 #endif                          /* defined(__mips__) && defined(IL_BIGENDIAN) */
354         /* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
355         if ((ai_coreid(sih) == SDIOD_CORE_ID)
356             && ((ai_corerev(sih) > 0) && (ai_corerev(sih) <= 2)))
357                 di->addrext = 0;
358         else if ((ai_coreid(sih) == I2S_CORE_ID) &&
359                  ((ai_corerev(sih) == 0) || (ai_corerev(sih) == 1)))
360                 di->addrext = 0;
361         else
362                 di->addrext = _dma_isaddrext(di);
363
364         /* does the descriptors need to be aligned and if yes, on 4K/8K or not */
365         di->aligndesc_4k = _dma_descriptor_align(di);
366         if (di->aligndesc_4k) {
367                 di->dmadesc_align = D64RINGALIGN_BITS;
368                 if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
369                         /* for smaller dd table, HW relax alignment reqmnt */
370                         di->dmadesc_align = D64RINGALIGN_BITS - 1;
371                 }
372         } else
373                 di->dmadesc_align = 4;  /* 16 byte alignment */
374
375         DMA_NONE(("DMA descriptor align_needed %d, align %d\n",
376                   di->aligndesc_4k, di->dmadesc_align));
377
378         /* allocate tx packet pointer vector */
379         if (ntxd) {
380                 size = ntxd * sizeof(void *);
381                 di->txp = kzalloc(size, GFP_ATOMIC);
382                 if (di->txp == NULL) {
383                         DMA_ERROR(("%s: dma_attach: out of tx memory\n", di->name));
384                         goto fail;
385                 }
386         }
387
388         /* allocate rx packet pointer vector */
389         if (nrxd) {
390                 size = nrxd * sizeof(void *);
391                 di->rxp = kzalloc(size, GFP_ATOMIC);
392                 if (di->rxp == NULL) {
393                         DMA_ERROR(("%s: dma_attach: out of rx memory\n", di->name));
394                         goto fail;
395                 }
396         }
397
398         /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
399         if (ntxd) {
400                 if (!_dma_alloc(di, DMA_TX))
401                         goto fail;
402         }
403
404         /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
405         if (nrxd) {
406                 if (!_dma_alloc(di, DMA_RX))
407                         goto fail;
408         }
409
410         if ((di->ddoffsetlow != 0) && !di->addrext) {
411                 if (PHYSADDRLO(di->txdpa) > SI_PCI_DMA_SZ) {
412                         DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->txdpa)));
413                         goto fail;
414                 }
415                 if (PHYSADDRLO(di->rxdpa) > SI_PCI_DMA_SZ) {
416                         DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->rxdpa)));
417                         goto fail;
418                 }
419         }
420
421         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));
422
423         /* allocate DMA mapping vectors */
424         if (DMASGLIST_ENAB) {
425                 if (ntxd) {
426                         size = ntxd * sizeof(dma_seg_map_t);
427                         di->txp_dmah = kzalloc(size, GFP_ATOMIC);
428                         if (di->txp_dmah == NULL)
429                                 goto fail;
430                 }
431
432                 if (nrxd) {
433                         size = nrxd * sizeof(dma_seg_map_t);
434                         di->rxp_dmah = kzalloc(size, GFP_ATOMIC);
435                         if (di->rxp_dmah == NULL)
436                                 goto fail;
437                 }
438         }
439
440         return (struct dma_pub *) di;
441
442  fail:
443         _dma_detach(di);
444         return NULL;
445 }
446
447 /* Check for odd number of 1's */
448 static inline u32 parity32(u32 data)
449 {
450         data ^= data >> 16;
451         data ^= data >> 8;
452         data ^= data >> 4;
453         data ^= data >> 2;
454         data ^= data >> 1;
455
456         return data & 1;
457 }
458
459 #define DMA64_DD_PARITY(dd)  parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2)
460
461 static inline void
462 dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx,
463              u32 *flags, u32 bufcount)
464 {
465         u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
466
467         /* PCI bus with big(>1G) physical address, use address extension */
468 #if defined(__mips__) && defined(IL_BIGENDIAN)
469         if ((di->dataoffsetlow == SI_SDRAM_SWAPPED)
470             || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
471 #else
472         if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
473 #endif                          /* defined(__mips__) && defined(IL_BIGENDIAN) */
474
475                 W_SM(&ddring[outidx].addrlow,
476                      BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
477                 W_SM(&ddring[outidx].addrhigh,
478                      BUS_SWAP32(PHYSADDRHI(pa) + di->dataoffsethigh));
479                 W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
480                 W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
481         } else {
482                 /* address extension for 32-bit PCI */
483                 u32 ae;
484
485                 ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
486                 PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
487
488                 ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
489                 W_SM(&ddring[outidx].addrlow,
490                      BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
491                 W_SM(&ddring[outidx].addrhigh,
492                      BUS_SWAP32(0 + di->dataoffsethigh));
493                 W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
494                 W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
495         }
496         if (di->dma.dmactrlflags & DMA_CTRL_PEN) {
497                 if (DMA64_DD_PARITY(&ddring[outidx])) {
498                         W_SM(&ddring[outidx].ctrl2,
499                              BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY));
500                 }
501         }
502 }
503
504 static bool _dma_alloc(dma_info_t *di, uint direction)
505 {
506         return dma64_alloc(di, direction);
507 }
508
509 void *dma_alloc_consistent(struct pci_dev *pdev, uint size, u16 align_bits,
510                                uint *alloced, unsigned long *pap)
511 {
512         if (align_bits) {
513                 u16 align = (1 << align_bits);
514                 if (!IS_ALIGNED(PAGE_SIZE, align))
515                         size += align;
516                 *alloced = size;
517         }
518         return pci_alloc_consistent(pdev, size, (dma_addr_t *) pap);
519 }
520
521 /* !! may be called with core in reset */
522 static void _dma_detach(dma_info_t *di)
523 {
524
525         DMA_TRACE(("%s: dma_detach\n", di->name));
526
527         /* free dma descriptor rings */
528         if (di->txd64)
529                 pci_free_consistent(di->pbus, di->txdalloc,
530                                     ((s8 *)di->txd64 - di->txdalign),
531                                     (di->txdpaorig));
532         if (di->rxd64)
533                 pci_free_consistent(di->pbus, di->rxdalloc,
534                                     ((s8 *)di->rxd64 - di->rxdalign),
535                                     (di->rxdpaorig));
536
537         /* free packet pointer vectors */
538         kfree(di->txp);
539         kfree(di->rxp);
540
541         /* free tx packet DMA handles */
542         kfree(di->txp_dmah);
543
544         /* free rx packet DMA handles */
545         kfree(di->rxp_dmah);
546
547         /* free our private info structure */
548         kfree(di);
549
550 }
551
552 static bool _dma_descriptor_align(dma_info_t *di)
553 {
554         u32 addrl;
555
556         /* Check to see if the descriptors need to be aligned on 4K/8K or not */
557         if (di->d64txregs != NULL) {
558                 W_REG(&di->d64txregs->addrlow, 0xff0);
559                 addrl = R_REG(&di->d64txregs->addrlow);
560                 if (addrl != 0)
561                         return false;
562         } else if (di->d64rxregs != NULL) {
563                 W_REG(&di->d64rxregs->addrlow, 0xff0);
564                 addrl = R_REG(&di->d64rxregs->addrlow);
565                 if (addrl != 0)
566                         return false;
567         }
568         return true;
569 }
570
571 /* return true if this dma engine supports DmaExtendedAddrChanges, otherwise false */
572 static bool _dma_isaddrext(dma_info_t *di)
573 {
574         /* DMA64 supports full 32- or 64-bit operation. AE is always valid */
575
576         /* not all tx or rx channel are available */
577         if (di->d64txregs != NULL) {
578                 if (!_dma64_addrext(di->d64txregs)) {
579                         DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have "
580                                    "AE set\n", di->name));
581                 }
582                 return true;
583         } else if (di->d64rxregs != NULL) {
584                 if (!_dma64_addrext(di->d64rxregs)) {
585                         DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have "
586                                    "AE set\n", di->name));
587                 }
588                 return true;
589         }
590         return false;
591 }
592
593 /* initialize descriptor table base address */
594 static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa)
595 {
596         if (!di->aligndesc_4k) {
597                 if (direction == DMA_TX)
598                         di->xmtptrbase = PHYSADDRLO(pa);
599                 else
600                         di->rcvptrbase = PHYSADDRLO(pa);
601         }
602
603         if ((di->ddoffsetlow == 0)
604             || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
605                 if (direction == DMA_TX) {
606                         W_REG(&di->d64txregs->addrlow,
607                               (PHYSADDRLO(pa) + di->ddoffsetlow));
608                         W_REG(&di->d64txregs->addrhigh,
609                               (PHYSADDRHI(pa) + di->ddoffsethigh));
610                 } else {
611                         W_REG(&di->d64rxregs->addrlow,
612                               (PHYSADDRLO(pa) + di->ddoffsetlow));
613                         W_REG(&di->d64rxregs->addrhigh,
614                                 (PHYSADDRHI(pa) + di->ddoffsethigh));
615                 }
616         } else {
617                 /* DMA64 32bits address extension */
618                 u32 ae;
619
620                 /* shift the high bit(s) from pa to ae */
621                 ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >>
622                     PCI32ADDR_HIGH_SHIFT;
623                 PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
624
625                 if (direction == DMA_TX) {
626                         W_REG(&di->d64txregs->addrlow,
627                               (PHYSADDRLO(pa) + di->ddoffsetlow));
628                         W_REG(&di->d64txregs->addrhigh,
629                               di->ddoffsethigh);
630                         SET_REG(&di->d64txregs->control,
631                                 D64_XC_AE, (ae << D64_XC_AE_SHIFT));
632                 } else {
633                         W_REG(&di->d64rxregs->addrlow,
634                               (PHYSADDRLO(pa) + di->ddoffsetlow));
635                         W_REG(&di->d64rxregs->addrhigh,
636                               di->ddoffsethigh);
637                         SET_REG(&di->d64rxregs->control,
638                                 D64_RC_AE, (ae << D64_RC_AE_SHIFT));
639                 }
640         }
641 }
642
643 static void _dma_fifoloopbackenable(dma_info_t *di)
644 {
645         DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
646
647         OR_REG(&di->d64txregs->control, D64_XC_LE);
648 }
649
650 static void _dma_rxinit(dma_info_t *di)
651 {
652         DMA_TRACE(("%s: dma_rxinit\n", di->name));
653
654         if (di->nrxd == 0)
655                 return;
656
657         di->rxin = di->rxout = 0;
658
659         /* clear rx descriptor ring */
660         memset((void *)di->rxd64, '\0',
661                 (di->nrxd * sizeof(dma64dd_t)));
662
663         /* DMA engine with out alignment requirement requires table to be inited
664          * before enabling the engine
665          */
666         if (!di->aligndesc_4k)
667                 _dma_ddtable_init(di, DMA_RX, di->rxdpa);
668
669         _dma_rxenable(di);
670
671         if (di->aligndesc_4k)
672                 _dma_ddtable_init(di, DMA_RX, di->rxdpa);
673 }
674
675 static void _dma_rxenable(dma_info_t *di)
676 {
677         uint dmactrlflags = di->dma.dmactrlflags;
678         u32 control;
679
680         DMA_TRACE(("%s: dma_rxenable\n", di->name));
681
682         control =
683             (R_REG(&di->d64rxregs->control) & D64_RC_AE) |
684             D64_RC_RE;
685
686         if ((dmactrlflags & DMA_CTRL_PEN) == 0)
687                 control |= D64_RC_PD;
688
689         if (dmactrlflags & DMA_CTRL_ROC)
690                 control |= D64_RC_OC;
691
692         W_REG(&di->d64rxregs->control,
693                 ((di->rxoffset << D64_RC_RO_SHIFT) | control));
694 }
695
696 static void
697 _dma_rx_param_get(dma_info_t *di, u16 *rxoffset, u16 *rxbufsize)
698 {
699         /* the normal values fit into 16 bits */
700         *rxoffset = (u16) di->rxoffset;
701         *rxbufsize = (u16) di->rxbufsize;
702 }
703
704 /* !! rx entry routine
705  * returns a pointer to the next frame received, or NULL if there are no more
706  *   if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is supported
707  *      with pkts chain
708  *   otherwise, it's treated as giant pkt and will be tossed.
709  *   The DMA scattering starts with normal DMA header, followed by first buffer data.
710  *   After it reaches the max size of buffer, the data continues in next DMA descriptor
711  *   buffer WITHOUT DMA header
712  */
713 static void *_dma_rx(dma_info_t *di)
714 {
715         struct sk_buff *p, *head, *tail;
716         uint len;
717         uint pkt_len;
718         int resid = 0;
719
720  next_frame:
721         head = _dma_getnextrxp(di, false);
722         if (head == NULL)
723                 return NULL;
724
725         len = le16_to_cpu(*(u16 *) (head->data));
726         DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
727         dma_spin_for_len(len, head);
728
729         /* set actual length */
730         pkt_len = min((di->rxoffset + len), di->rxbufsize);
731         __skb_trim(head, pkt_len);
732         resid = len - (di->rxbufsize - di->rxoffset);
733
734         /* check for single or multi-buffer rx */
735         if (resid > 0) {
736                 tail = head;
737                 while ((resid > 0) && (p = _dma_getnextrxp(di, false))) {
738                         tail->next = p;
739                         pkt_len = min(resid, (int)di->rxbufsize);
740                         __skb_trim(p, pkt_len);
741
742                         tail = p;
743                         resid -= di->rxbufsize;
744                 }
745
746 #ifdef BCMDBG
747                 if (resid > 0) {
748                         uint cur;
749                         cur =
750                             B2I(((R_REG(&di->d64rxregs->status0) &
751                                   D64_RS0_CD_MASK) -
752                                  di->rcvptrbase) & D64_RS0_CD_MASK,
753                                 dma64dd_t);
754                         DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n",
755                                    di->rxin, di->rxout, cur));
756                 }
757 #endif                          /* BCMDBG */
758
759                 if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
760                         DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n",
761                                    di->name, len));
762                         bcm_pkt_buf_free_skb(head);
763                         di->dma.rxgiants++;
764                         goto next_frame;
765                 }
766         }
767
768         return head;
769 }
770
771 /* post receive buffers
772  *  return false is refill failed completely and ring is empty
773  *  this will stall the rx dma and user might want to call rxfill again asap
774  *  This unlikely happens on memory-rich NIC, but often on memory-constrained dongle
775  */
776 static bool _dma_rxfill(dma_info_t *di)
777 {
778         struct sk_buff *p;
779         u16 rxin, rxout;
780         u32 flags = 0;
781         uint n;
782         uint i;
783         dmaaddr_t pa;
784         uint extra_offset = 0;
785         bool ring_empty;
786
787         ring_empty = false;
788
789         /*
790          * Determine how many receive buffers we're lacking
791          * from the full complement, allocate, initialize,
792          * and post them, then update the chip rx lastdscr.
793          */
794
795         rxin = di->rxin;
796         rxout = di->rxout;
797
798         n = di->nrxpost - NRXDACTIVE(rxin, rxout);
799
800         DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
801
802         if (di->rxbufsize > BCMEXTRAHDROOM)
803                 extra_offset = di->rxextrahdrroom;
804
805         for (i = 0; i < n; i++) {
806                 /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
807                    size to be allocated
808                  */
809
810                 p = bcm_pkt_buf_get_skb(di->rxbufsize + extra_offset);
811
812                 if (p == NULL) {
813                         DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n",
814                                    di->name));
815                         if (i == 0 && dma64_rxidle(di)) {
816                                 DMA_ERROR(("%s: rxfill64: ring is empty !\n",
817                                            di->name));
818                                 ring_empty = true;
819                         }
820                         di->dma.rxnobuf++;
821                         break;
822                 }
823                 /* reserve an extra headroom, if applicable */
824                 if (extra_offset)
825                         skb_pull(p, extra_offset);
826
827                 /* Do a cached write instead of uncached write since DMA_MAP
828                  * will flush the cache.
829                  */
830                 *(u32 *) (p->data) = 0;
831
832                 if (DMASGLIST_ENAB)
833                         memset(&di->rxp_dmah[rxout], 0,
834                                 sizeof(dma_seg_map_t));
835
836                 pa = pci_map_single(di->pbus, p->data,
837                         di->rxbufsize, PCI_DMA_FROMDEVICE);
838
839                 /* save the free packet pointer */
840                 di->rxp[rxout] = p;
841
842                 /* reset flags for each descriptor */
843                 flags = 0;
844                 if (rxout == (di->nrxd - 1))
845                         flags = D64_CTRL1_EOT;
846
847                 dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
848                              di->rxbufsize);
849                 rxout = NEXTRXD(rxout);
850         }
851
852         di->rxout = rxout;
853
854         /* update the chip lastdscr pointer */
855         W_REG(&di->d64rxregs->ptr,
856               di->rcvptrbase + I2B(rxout, dma64dd_t));
857
858         return ring_empty;
859 }
860
861 /* like getnexttxp but no reclaim */
862 static void *_dma_peeknexttxp(dma_info_t *di)
863 {
864         uint end, i;
865
866         if (di->ntxd == 0)
867                 return NULL;
868
869         end =
870             B2I(((R_REG(&di->d64txregs->status0) &
871                   D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
872                   dma64dd_t);
873
874         for (i = di->txin; i != end; i = NEXTTXD(i))
875                 if (di->txp[i])
876                         return di->txp[i];
877
878         return NULL;
879 }
880
881 /* like getnextrxp but not take off the ring */
882 static void *_dma_peeknextrxp(dma_info_t *di)
883 {
884         uint end, i;
885
886         if (di->nrxd == 0)
887                 return NULL;
888
889         end =
890             B2I(((R_REG(&di->d64rxregs->status0) &
891                   D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK,
892                   dma64dd_t);
893
894         for (i = di->rxin; i != end; i = NEXTRXD(i))
895                 if (di->rxp[i])
896                         return di->rxp[i];
897
898         return NULL;
899 }
900
901 static void _dma_rxreclaim(dma_info_t *di)
902 {
903         void *p;
904
905         DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
906
907         while ((p = _dma_getnextrxp(di, true)))
908                 bcm_pkt_buf_free_skb(p);
909 }
910
911 static void *_dma_getnextrxp(dma_info_t *di, bool forceall)
912 {
913         if (di->nrxd == 0)
914                 return NULL;
915
916         return dma64_getnextrxp(di, forceall);
917 }
918
919 static void _dma_txblock(dma_info_t *di)
920 {
921         di->dma.txavail = 0;
922 }
923
924 static void _dma_txunblock(dma_info_t *di)
925 {
926         di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
927 }
928
929 static uint _dma_txactive(dma_info_t *di)
930 {
931         return NTXDACTIVE(di->txin, di->txout);
932 }
933
934 static uint _dma_txpending(dma_info_t *di)
935 {
936         uint curr;
937
938         curr =
939             B2I(((R_REG(&di->d64txregs->status0) &
940                   D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
941                   dma64dd_t);
942
943         return NTXDACTIVE(curr, di->txout);
944 }
945
946 static uint _dma_txcommitted(dma_info_t *di)
947 {
948         uint ptr;
949         uint txin = di->txin;
950
951         if (txin == di->txout)
952                 return 0;
953
954         ptr = B2I(R_REG(&di->d64txregs->ptr), dma64dd_t);
955
956         return NTXDACTIVE(di->txin, ptr);
957 }
958
959 static uint _dma_rxactive(dma_info_t *di)
960 {
961         return NRXDACTIVE(di->rxin, di->rxout);
962 }
963
964 static void _dma_counterreset(dma_info_t *di)
965 {
966         /* reset all software counter */
967         di->dma.rxgiants = 0;
968         di->dma.rxnobuf = 0;
969         di->dma.txnobuf = 0;
970 }
971
972 static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags)
973 {
974         uint dmactrlflags = di->dma.dmactrlflags;
975
976         if (di == NULL) {
977                 DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
978                 return 0;
979         }
980
981         dmactrlflags &= ~mask;
982         dmactrlflags |= flags;
983
984         /* If trying to enable parity, check if parity is actually supported */
985         if (dmactrlflags & DMA_CTRL_PEN) {
986                 u32 control;
987
988                 control = R_REG(&di->d64txregs->control);
989                 W_REG(&di->d64txregs->control,
990                       control | D64_XC_PD);
991                 if (R_REG(&di->d64txregs->control) & D64_XC_PD) {
992                         /* We *can* disable it so it is supported,
993                          * restore control register
994                          */
995                         W_REG(&di->d64txregs->control,
996                         control);
997                 } else {
998                         /* Not supported, don't allow it to be enabled */
999                         dmactrlflags &= ~DMA_CTRL_PEN;
1000                 }
1001         }
1002
1003         di->dma.dmactrlflags = dmactrlflags;
1004
1005         return dmactrlflags;
1006 }
1007
1008 /* get the address of the var in order to change later */
1009 static unsigned long _dma_getvar(dma_info_t *di, const char *name)
1010 {
1011         if (!strcmp(name, "&txavail"))
1012                 return (unsigned long)&(di->dma.txavail);
1013         return 0;
1014 }
1015
1016 static
1017 u8 dma_align_sizetobits(uint size)
1018 {
1019         u8 bitpos = 0;
1020         while (size >>= 1) {
1021                 bitpos++;
1022         }
1023         return bitpos;
1024 }
1025
1026 /* This function ensures that the DMA descriptor ring will not get allocated
1027  * across Page boundary. If the allocation is done across the page boundary
1028  * at the first time, then it is freed and the allocation is done at
1029  * descriptor ring size aligned location. This will ensure that the ring will
1030  * not cross page boundary
1031  */
1032 static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size,
1033                            u16 *alignbits, uint *alloced,
1034                            dmaaddr_t *descpa)
1035 {
1036         void *va;
1037         u32 desc_strtaddr;
1038         u32 alignbytes = 1 << *alignbits;
1039
1040         va = dma_alloc_consistent(di->pbus, size, *alignbits, alloced, descpa);
1041
1042         if (NULL == va)
1043                 return NULL;
1044
1045         desc_strtaddr = (u32) roundup((unsigned long)va, alignbytes);
1046         if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
1047                                                         & boundary)) {
1048                 *alignbits = dma_align_sizetobits(size);
1049                 pci_free_consistent(di->pbus, size, va, *descpa);
1050                 va = dma_alloc_consistent(di->pbus, size, *alignbits,
1051                         alloced, descpa);
1052         }
1053         return va;
1054 }
1055
1056 /* 64-bit DMA functions */
1057
1058 static void dma64_txinit(dma_info_t *di)
1059 {
1060         u32 control = D64_XC_XE;
1061
1062         DMA_TRACE(("%s: dma_txinit\n", di->name));
1063
1064         if (di->ntxd == 0)
1065                 return;
1066
1067         di->txin = di->txout = 0;
1068         di->dma.txavail = di->ntxd - 1;
1069
1070         /* clear tx descriptor ring */
1071         memset((void *)di->txd64, '\0', (di->ntxd * sizeof(dma64dd_t)));
1072
1073         /* DMA engine with out alignment requirement requires table to be inited
1074          * before enabling the engine
1075          */
1076         if (!di->aligndesc_4k)
1077                 _dma_ddtable_init(di, DMA_TX, di->txdpa);
1078
1079         if ((di->dma.dmactrlflags & DMA_CTRL_PEN) == 0)
1080                 control |= D64_XC_PD;
1081         OR_REG(&di->d64txregs->control, control);
1082
1083         /* DMA engine with alignment requirement requires table to be inited
1084          * before enabling the engine
1085          */
1086         if (di->aligndesc_4k)
1087                 _dma_ddtable_init(di, DMA_TX, di->txdpa);
1088 }
1089
1090 static bool dma64_txenabled(dma_info_t *di)
1091 {
1092         u32 xc;
1093
1094         /* If the chip is dead, it is not enabled :-) */
1095         xc = R_REG(&di->d64txregs->control);
1096         return (xc != 0xffffffff) && (xc & D64_XC_XE);
1097 }
1098
1099 static void dma64_txsuspend(dma_info_t *di)
1100 {
1101         DMA_TRACE(("%s: dma_txsuspend\n", di->name));
1102
1103         if (di->ntxd == 0)
1104                 return;
1105
1106         OR_REG(&di->d64txregs->control, D64_XC_SE);
1107 }
1108
1109 static void dma64_txresume(dma_info_t *di)
1110 {
1111         DMA_TRACE(("%s: dma_txresume\n", di->name));
1112
1113         if (di->ntxd == 0)
1114                 return;
1115
1116         AND_REG(&di->d64txregs->control, ~D64_XC_SE);
1117 }
1118
1119 static bool dma64_txsuspended(dma_info_t *di)
1120 {
1121         return (di->ntxd == 0) ||
1122             ((R_REG(&di->d64txregs->control) & D64_XC_SE) ==
1123              D64_XC_SE);
1124 }
1125
1126 static void dma64_txreclaim(dma_info_t *di, txd_range_t range)
1127 {
1128         void *p;
1129
1130         DMA_TRACE(("%s: dma_txreclaim %s\n", di->name,
1131                    (range == HNDDMA_RANGE_ALL) ? "all" :
1132                    ((range ==
1133                      HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
1134                     "transferred")));
1135
1136         if (di->txin == di->txout)
1137                 return;
1138
1139         while ((p = dma64_getnexttxp(di, range))) {
1140                 /* For unframed data, we don't have any packets to free */
1141                 if (!(di->dma.dmactrlflags & DMA_CTRL_UNFRAMED))
1142                         bcm_pkt_buf_free_skb(p);
1143         }
1144 }
1145
1146 static bool dma64_txstopped(dma_info_t *di)
1147 {
1148         return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
1149                 D64_XS0_XS_STOPPED);
1150 }
1151
1152 static bool dma64_rxstopped(dma_info_t *di)
1153 {
1154         return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) ==
1155                 D64_RS0_RS_STOPPED);
1156 }
1157
1158 static bool dma64_alloc(dma_info_t *di, uint direction)
1159 {
1160         u16 size;
1161         uint ddlen;
1162         void *va;
1163         uint alloced = 0;
1164         u16 align;
1165         u16 align_bits;
1166
1167         ddlen = sizeof(dma64dd_t);
1168
1169         size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
1170         align_bits = di->dmadesc_align;
1171         align = (1 << align_bits);
1172
1173         if (direction == DMA_TX) {
1174                 va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
1175                         &alloced, &di->txdpaorig);
1176                 if (va == NULL) {
1177                         DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
1178                         return false;
1179                 }
1180                 align = (1 << align_bits);
1181                 di->txd64 = (dma64dd_t *) roundup((unsigned long)va, align);
1182                 di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va);
1183                 PHYSADDRLOSET(di->txdpa,
1184                               PHYSADDRLO(di->txdpaorig) + di->txdalign);
1185                 PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig));
1186                 di->txdalloc = alloced;
1187         } else {
1188                 va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
1189                         &alloced, &di->rxdpaorig);
1190                 if (va == NULL) {
1191                         DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
1192                         return false;
1193                 }
1194                 align = (1 << align_bits);
1195                 di->rxd64 = (dma64dd_t *) roundup((unsigned long)va, align);
1196                 di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va);
1197                 PHYSADDRLOSET(di->rxdpa,
1198                               PHYSADDRLO(di->rxdpaorig) + di->rxdalign);
1199                 PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig));
1200                 di->rxdalloc = alloced;
1201         }
1202
1203         return true;
1204 }
1205
1206 static bool dma64_txreset(dma_info_t *di)
1207 {
1208         u32 status;
1209
1210         if (di->ntxd == 0)
1211                 return true;
1212
1213         /* suspend tx DMA first */
1214         W_REG(&di->d64txregs->control, D64_XC_SE);
1215         SPINWAIT(((status =
1216                    (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
1217                   != D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
1218                  && (status != D64_XS0_XS_STOPPED), 10000);
1219
1220         W_REG(&di->d64txregs->control, 0);
1221         SPINWAIT(((status =
1222                    (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
1223                   != D64_XS0_XS_DISABLED), 10000);
1224
1225         /* wait for the last transaction to complete */
1226         udelay(300);
1227
1228         return status == D64_XS0_XS_DISABLED;
1229 }
1230
1231 static bool dma64_rxidle(dma_info_t *di)
1232 {
1233         DMA_TRACE(("%s: dma_rxidle\n", di->name));
1234
1235         if (di->nrxd == 0)
1236                 return true;
1237
1238         return ((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
1239                 (R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK));
1240 }
1241
1242 static bool dma64_rxreset(dma_info_t *di)
1243 {
1244         u32 status;
1245
1246         if (di->nrxd == 0)
1247                 return true;
1248
1249         W_REG(&di->d64rxregs->control, 0);
1250         SPINWAIT(((status =
1251                    (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK))
1252                   != D64_RS0_RS_DISABLED), 10000);
1253
1254         return status == D64_RS0_RS_DISABLED;
1255 }
1256
1257 static bool dma64_rxenabled(dma_info_t *di)
1258 {
1259         u32 rc;
1260
1261         rc = R_REG(&di->d64rxregs->control);
1262         return (rc != 0xffffffff) && (rc & D64_RC_RE);
1263 }
1264
1265 static bool dma64_txsuspendedidle(dma_info_t *di)
1266 {
1267
1268         if (di->ntxd == 0)
1269                 return true;
1270
1271         if (!(R_REG(&di->d64txregs->control) & D64_XC_SE))
1272                 return 0;
1273
1274         if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
1275             D64_XS0_XS_IDLE)
1276                 return 1;
1277
1278         return 0;
1279 }
1280
1281 /* Useful when sending unframed data.  This allows us to get a progress report from the DMA.
1282  * We return a pointer to the beginning of the DATA buffer of the current descriptor.
1283  * If DMA is idle, we return NULL.
1284  */
1285 static void *dma64_getpos(dma_info_t *di, bool direction)
1286 {
1287         void *va;
1288         bool idle;
1289         u32 cd_offset;
1290
1291         if (direction == DMA_TX) {
1292                 cd_offset =
1293                     R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK;
1294                 idle = !NTXDACTIVE(di->txin, di->txout);
1295                 va = di->txp[B2I(cd_offset, dma64dd_t)];
1296         } else {
1297                 cd_offset =
1298                     R_REG(&di->d64rxregs->status0) & D64_XS0_CD_MASK;
1299                 idle = !NRXDACTIVE(di->rxin, di->rxout);
1300                 va = di->rxp[B2I(cd_offset, dma64dd_t)];
1301         }
1302
1303         /* If DMA is IDLE, return NULL */
1304         if (idle) {
1305                 DMA_TRACE(("%s: DMA idle, return NULL\n", __func__));
1306                 va = NULL;
1307         }
1308
1309         return va;
1310 }
1311
1312 /* TX of unframed data
1313  *
1314  * Adds a DMA ring descriptor for the data pointed to by "buf".
1315  * This is for DMA of a buffer of data and is unlike other dma TX functions
1316  * that take a pointer to a "packet"
1317  * Each call to this is results in a single descriptor being added for "len" bytes of
1318  * data starting at "buf", it doesn't handle chained buffers.
1319  */
1320 static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit)
1321 {
1322         u16 txout;
1323         u32 flags = 0;
1324         dmaaddr_t pa;           /* phys addr */
1325
1326         txout = di->txout;
1327
1328         /* return nonzero if out of tx descriptors */
1329         if (NEXTTXD(txout) == di->txin)
1330                 goto outoftxd;
1331
1332         if (len == 0)
1333                 return 0;
1334
1335         pa = pci_map_single(di->pbus, buf, len, PCI_DMA_TODEVICE);
1336
1337         flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF);
1338
1339         if (txout == (di->ntxd - 1))
1340                 flags |= D64_CTRL1_EOT;
1341
1342         dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
1343
1344         /* save the buffer pointer - used by dma_getpos */
1345         di->txp[txout] = buf;
1346
1347         txout = NEXTTXD(txout);
1348         /* bump the tx descriptor index */
1349         di->txout = txout;
1350
1351         /* kick the chip */
1352         if (commit) {
1353                 W_REG(&di->d64txregs->ptr,
1354                       di->xmtptrbase + I2B(txout, dma64dd_t));
1355         }
1356
1357         /* tx flow control */
1358         di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1359
1360         return 0;
1361
1362  outoftxd:
1363         DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __func__));
1364         di->dma.txavail = 0;
1365         di->dma.txnobuf++;
1366         return -1;
1367 }
1368
1369 /* !! tx entry routine
1370  * WARNING: call must check the return value for error.
1371  *   the error(toss frames) could be fatal and cause many subsequent hard to debug problems
1372  */
1373 static int dma64_txfast(dma_info_t *di, struct sk_buff *p0,
1374                                     bool commit)
1375 {
1376         struct sk_buff *p, *next;
1377         unsigned char *data;
1378         uint len;
1379         u16 txout;
1380         u32 flags = 0;
1381         dmaaddr_t pa;
1382
1383         DMA_TRACE(("%s: dma_txfast\n", di->name));
1384
1385         txout = di->txout;
1386
1387         /*
1388          * Walk the chain of packet buffers
1389          * allocating and initializing transmit descriptor entries.
1390          */
1391         for (p = p0; p; p = next) {
1392                 uint nsegs, j;
1393                 dma_seg_map_t *map;
1394
1395                 data = p->data;
1396                 len = p->len;
1397                 next = p->next;
1398
1399                 /* return nonzero if out of tx descriptors */
1400                 if (NEXTTXD(txout) == di->txin)
1401                         goto outoftxd;
1402
1403                 if (len == 0)
1404                         continue;
1405
1406                 /* get physical address of buffer start */
1407                 if (DMASGLIST_ENAB)
1408                         memset(&di->txp_dmah[txout], 0,
1409                                 sizeof(dma_seg_map_t));
1410
1411                 pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE);
1412
1413                 if (DMASGLIST_ENAB) {
1414                         map = &di->txp_dmah[txout];
1415
1416                         /* See if all the segments can be accounted for */
1417                         if (map->nsegs >
1418                             (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) -
1419                                     1))
1420                                 goto outoftxd;
1421
1422                         nsegs = map->nsegs;
1423                 } else
1424                         nsegs = 1;
1425
1426                 for (j = 1; j <= nsegs; j++) {
1427                         flags = 0;
1428                         if (p == p0 && j == 1)
1429                                 flags |= D64_CTRL1_SOF;
1430
1431                         /* With a DMA segment list, Descriptor table is filled
1432                          * using the segment list instead of looping over
1433                          * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when
1434                          * end of segment list is reached.
1435                          */
1436                         if ((!DMASGLIST_ENAB && next == NULL) ||
1437                             (DMASGLIST_ENAB && j == nsegs))
1438                                 flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
1439                         if (txout == (di->ntxd - 1))
1440                                 flags |= D64_CTRL1_EOT;
1441
1442                         if (DMASGLIST_ENAB) {
1443                                 len = map->segs[j - 1].length;
1444                                 pa = map->segs[j - 1].addr;
1445                         }
1446                         dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
1447
1448                         txout = NEXTTXD(txout);
1449                 }
1450
1451                 /* See above. No need to loop over individual buffers */
1452                 if (DMASGLIST_ENAB)
1453                         break;
1454         }
1455
1456         /* if last txd eof not set, fix it */
1457         if (!(flags & D64_CTRL1_EOF))
1458                 W_SM(&di->txd64[PREVTXD(txout)].ctrl1,
1459                      BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
1460
1461         /* save the packet */
1462         di->txp[PREVTXD(txout)] = p0;
1463
1464         /* bump the tx descriptor index */
1465         di->txout = txout;
1466
1467         /* kick the chip */
1468         if (commit)
1469                 W_REG(&di->d64txregs->ptr,
1470                       di->xmtptrbase + I2B(txout, dma64dd_t));
1471
1472         /* tx flow control */
1473         di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1474
1475         return 0;
1476
1477  outoftxd:
1478         DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name));
1479         bcm_pkt_buf_free_skb(p0);
1480         di->dma.txavail = 0;
1481         di->dma.txnobuf++;
1482         return -1;
1483 }
1484
1485 /*
1486  * Reclaim next completed txd (txds if using chained buffers) in the range
1487  * specified and return associated packet.
1488  * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be
1489  * transmitted as noted by the hardware "CurrDescr" pointer.
1490  * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be
1491  * transferred by the DMA as noted by the hardware "ActiveDescr" pointer.
1492  * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
1493  * return associated packet regardless of the value of hardware pointers.
1494  */
1495 static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range)
1496 {
1497         u16 start, end, i;
1498         u16 active_desc;
1499         void *txp;
1500
1501         DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name,
1502                    (range == HNDDMA_RANGE_ALL) ? "all" :
1503                    ((range ==
1504                      HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
1505                     "transferred")));
1506
1507         if (di->ntxd == 0)
1508                 return NULL;
1509
1510         txp = NULL;
1511
1512         start = di->txin;
1513         if (range == HNDDMA_RANGE_ALL)
1514                 end = di->txout;
1515         else {
1516                 dma64regs_t *dregs = di->d64txregs;
1517
1518                 end =
1519                     (u16) (B2I
1520                               (((R_REG(&dregs->status0) &
1521                                  D64_XS0_CD_MASK) -
1522                                 di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t));
1523
1524                 if (range == HNDDMA_RANGE_TRANSFERED) {
1525                         active_desc =
1526                             (u16) (R_REG(&dregs->status1) &
1527                                       D64_XS1_AD_MASK);
1528                         active_desc =
1529                             (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
1530                         active_desc = B2I(active_desc, dma64dd_t);
1531                         if (end != active_desc)
1532                                 end = PREVTXD(active_desc);
1533                 }
1534         }
1535
1536         if ((start == 0) && (end > di->txout))
1537                 goto bogus;
1538
1539         for (i = start; i != end && !txp; i = NEXTTXD(i)) {
1540                 dmaaddr_t pa;
1541                 dma_seg_map_t *map = NULL;
1542                 uint size, j, nsegs;
1543
1544                 PHYSADDRLOSET(pa,
1545                               (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) -
1546                                di->dataoffsetlow));
1547                 PHYSADDRHISET(pa,
1548                               (BUS_SWAP32(R_SM(&di->txd64[i].addrhigh)) -
1549                                di->dataoffsethigh));
1550
1551                 if (DMASGLIST_ENAB) {
1552                         map = &di->txp_dmah[i];
1553                         size = map->origsize;
1554                         nsegs = map->nsegs;
1555                 } else {
1556                         size =
1557                             (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) &
1558                              D64_CTRL2_BC_MASK);
1559                         nsegs = 1;
1560                 }
1561
1562                 for (j = nsegs; j > 0; j--) {
1563                         W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
1564                         W_SM(&di->txd64[i].addrhigh, 0xdeadbeef);
1565
1566                         txp = di->txp[i];
1567                         di->txp[i] = NULL;
1568                         if (j > 1)
1569                                 i = NEXTTXD(i);
1570                 }
1571
1572                 pci_unmap_single(di->pbus, pa, size, PCI_DMA_TODEVICE);
1573         }
1574
1575         di->txin = i;
1576
1577         /* tx flow control */
1578         di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1579
1580         return txp;
1581
1582  bogus:
1583         DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall));
1584         return NULL;
1585 }
1586
1587 static void *dma64_getnextrxp(dma_info_t *di, bool forceall)
1588 {
1589         uint i, curr;
1590         void *rxp;
1591         dmaaddr_t pa;
1592
1593         i = di->rxin;
1594
1595         /* return if no packets posted */
1596         if (i == di->rxout)
1597                 return NULL;
1598
1599         curr =
1600             B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) -
1601                  di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t);
1602
1603         /* ignore curr if forceall */
1604         if (!forceall && (i == curr))
1605                 return NULL;
1606
1607         /* get the packet pointer that corresponds to the rx descriptor */
1608         rxp = di->rxp[i];
1609         di->rxp[i] = NULL;
1610
1611         PHYSADDRLOSET(pa,
1612                       (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) -
1613                        di->dataoffsetlow));
1614         PHYSADDRHISET(pa,
1615                       (BUS_SWAP32(R_SM(&di->rxd64[i].addrhigh)) -
1616                        di->dataoffsethigh));
1617
1618         /* clear this packet from the descriptor ring */
1619         pci_unmap_single(di->pbus, pa, di->rxbufsize, PCI_DMA_FROMDEVICE);
1620
1621         W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
1622         W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
1623
1624         di->rxin = NEXTRXD(i);
1625
1626         return rxp;
1627 }
1628
1629 static bool _dma64_addrext(dma64regs_t *dma64regs)
1630 {
1631         u32 w;
1632         OR_REG(&dma64regs->control, D64_XC_AE);
1633         w = R_REG(&dma64regs->control);
1634         AND_REG(&dma64regs->control, ~D64_XC_AE);
1635         return (w & D64_XC_AE) == D64_XC_AE;
1636 }
1637
1638 /*
1639  * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
1640  */
1641 static void dma64_txrotate(dma_info_t *di)
1642 {
1643         u16 ad;
1644         uint nactive;
1645         uint rot;
1646         u16 old, new;
1647         u32 w;
1648         u16 first, last;
1649
1650         nactive = _dma_txactive(di);
1651         ad = (u16) (B2I
1652                        ((((R_REG(&di->d64txregs->status1) &
1653                            D64_XS1_AD_MASK)
1654                           - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t));
1655         rot = TXD(ad - di->txin);
1656
1657         /* full-ring case is a lot harder - don't worry about this */
1658         if (rot >= (di->ntxd - nactive)) {
1659                 DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
1660                 return;
1661         }
1662
1663         first = di->txin;
1664         last = PREVTXD(di->txout);
1665
1666         /* move entries starting at last and moving backwards to first */
1667         for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
1668                 new = TXD(old + rot);
1669
1670                 /*
1671                  * Move the tx dma descriptor.
1672                  * EOT is set only in the last entry in the ring.
1673                  */
1674                 w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
1675                 if (new == (di->ntxd - 1))
1676                         w |= D64_CTRL1_EOT;
1677                 W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w));
1678
1679                 w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2));
1680                 W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w));
1681
1682                 W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
1683                 W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
1684
1685                 /* zap the old tx dma descriptor address field */
1686                 W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef));
1687                 W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef));
1688
1689                 /* move the corresponding txp[] entry */
1690                 di->txp[new] = di->txp[old];
1691
1692                 /* Move the map */
1693                 if (DMASGLIST_ENAB) {
1694                         memcpy(&di->txp_dmah[new], &di->txp_dmah[old],
1695                                sizeof(dma_seg_map_t));
1696                         memset(&di->txp_dmah[old], 0, sizeof(dma_seg_map_t));
1697                 }
1698
1699                 di->txp[old] = NULL;
1700         }
1701
1702         /* update txin and txout */
1703         di->txin = ad;
1704         di->txout = TXD(di->txout + rot);
1705         di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1706
1707         /* kick the chip */
1708         W_REG(&di->d64txregs->ptr,
1709               di->xmtptrbase + I2B(di->txout, dma64dd_t));
1710 }
1711
1712 uint dma_addrwidth(si_t *sih, void *dmaregs)
1713 {
1714         /* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */
1715         /* DMA engine is 64-bit capable */
1716         if ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) {
1717                 /* backplane are 64-bit capable */
1718                 if (ai_backplane64(sih))
1719                         /* If bus is System Backplane or PCIE then we can access 64-bits */
1720                         if ((sih->bustype == SI_BUS) ||
1721                             ((sih->bustype == PCI_BUS) &&
1722                              (sih->buscoretype == PCIE_CORE_ID)))
1723                                 return DMADDRWIDTH_64;
1724         }
1725         /* DMA hardware not supported by this driver*/
1726         return DMADDRWIDTH_64;
1727 }
1728
1729 /*
1730  * Mac80211 initiated actions sometimes require packets in the DMA queue to be
1731  * modified. The modified portion of the packet is not under control of the DMA
1732  * engine. This function calls a caller-supplied function for each packet in
1733  * the caller specified dma chain.
1734  */
1735 void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
1736                       (void *pkt, void *arg_a), void *arg_a)
1737 {
1738         dma_info_t *di = (dma_info_t *) dmah;
1739         uint i =   di->txin;
1740         uint end = di->txout;
1741         struct sk_buff *skb;
1742         struct ieee80211_tx_info *tx_info;
1743
1744         while (i != end) {
1745                 skb = (struct sk_buff *)di->txp[i];
1746                 if (skb != NULL) {
1747                         tx_info = (struct ieee80211_tx_info *)skb->cb;
1748                         (callback_fnc)(tx_info, arg_a);
1749                 }
1750                 i = NEXTTXD(i);
1751         }
1752 }