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