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