f75a0201d82abbe883f4fb782bbf420b5b1b3784
[cascardo/linux.git] / drivers / staging / brcm80211 / brcmsmac / dma.h
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 #ifndef _BRCM_DMA_H_
18 #define _BRCM_DMA_H_
19
20 #include <linux/delay.h>
21 #include "types.h"              /* forward structure declarations */
22
23 /* DMA structure:
24  *  support two DMA engines: 32 bits address or 64 bit addressing
25  *  basic DMA register set is per channel(transmit or receive)
26  *  a pair of channels is defined for convenience
27  */
28
29 /* 32 bits addressing */
30
31 struct dma32diag {      /* diag access */
32         u32 fifoaddr;   /* diag address */
33         u32 fifodatalow;        /* low 32bits of data */
34         u32 fifodatahigh;       /* high 32bits of data */
35         u32 pad;                /* reserved */
36 };
37
38 /* 64 bits addressing */
39
40 /* dma registers per channel(xmt or rcv) */
41 struct dma64regs {
42         u32 control;    /* enable, et al */
43         u32 ptr;        /* last descriptor posted to chip */
44         u32 addrlow;    /* desc ring base address low 32-bits (8K aligned) */
45         u32 addrhigh;   /* desc ring base address bits 63:32 (8K aligned) */
46         u32 status0;    /* current descriptor, xmt state */
47         u32 status1;    /* active descriptor, xmt error */
48 };
49
50 /* map/unmap direction */
51 #define DMA_TX  1               /* TX direction for DMA */
52 #define DMA_RX  2               /* RX direction for DMA */
53 #define BUS_SWAP32(v)           (v)
54
55 /* range param for dma_getnexttxp() and dma_txreclaim */
56 enum txd_range {
57         DMA_RANGE_ALL = 1,
58         DMA_RANGE_TRANSMITTED,
59         DMA_RANGE_TRANSFERED
60 };
61
62 /* dma opsvec */
63 struct di_fcn_s {
64         void (*detach)(struct dma_pub *dmah);
65         void (*txinit)(struct dma_pub *dmah);
66         bool (*txreset)(struct dma_pub *dmah);
67         bool (*txenabled)(struct dma_pub *dmah);
68         void (*txsuspend)(struct dma_pub *dmah);
69         void (*txresume)(struct dma_pub *dmah);
70         bool (*txsuspended)(struct dma_pub *dmah);
71         bool (*txsuspendedidle)(struct dma_pub *dmah);
72         int (*txfast)(struct dma_pub *dmah, struct sk_buff *p, bool commit);
73         int (*txunframed)(struct dma_pub *dmah, void *p, uint len, bool commit);
74
75         void *(*getpos)(struct dma_pub *di, bool direction);
76         bool (*txstopped)(struct dma_pub *dmah);
77         void (*txreclaim)(struct dma_pub *dmah, enum txd_range range);
78         void *(*getnexttxp)(struct dma_pub *dmah, enum txd_range range);
79         void *(*peeknexttxp) (struct dma_pub *dmah);
80         void (*txblock) (struct dma_pub *dmah);
81         void (*txunblock) (struct dma_pub *dmah);
82         uint (*txactive)(struct dma_pub *dmah);
83         void (*txrotate) (struct dma_pub *dmah);
84
85         void (*rxinit)(struct dma_pub *dmah);
86         bool (*rxreset)(struct dma_pub *dmah);
87         bool (*rxidle)(struct dma_pub *dmah);
88         bool (*rxstopped)(struct dma_pub *dmah);
89         bool (*rxenable)(struct dma_pub *dmah);
90         bool (*rxenabled)(struct dma_pub *dmah);
91         void *(*rx)(struct dma_pub *dmah);
92         bool (*rxfill)(struct dma_pub *dmah);
93         void (*rxreclaim)(struct dma_pub *dmah);
94         void *(*getnextrxp)(struct dma_pub *dmah, bool forceall);
95         void *(*peeknextrxp)(struct dma_pub *dmah);
96         void (*rxparam_get)(struct dma_pub *dmah, u16 *rxoffset,
97                             u16 *rxbufsize);
98
99         void (*fifoloopbackenable)(struct dma_pub *dmah);
100         unsigned long (*d_getvar)(struct dma_pub *dmah, const char *name);
101
102         void (*counterreset)(struct dma_pub *dmah);
103         uint (*ctrlflags)(struct dma_pub *dmah, uint mask, uint flags);
104         char *(*dump)(struct dma_pub *dmah, struct brcmu_strbuf *b,
105                       bool dumpring);
106         char *(*dumptx)(struct dma_pub *dmah, struct brcmu_strbuf *b,
107                         bool dumpring);
108         char *(*dumprx)(struct dma_pub *dmah, struct brcmu_strbuf *b,
109                         bool dumpring);
110         uint (*rxactive)(struct dma_pub *dmah);
111         uint (*txpending)(struct dma_pub *dmah);
112         uint (*txcommitted)(struct dma_pub *dmah);
113         uint endnum;
114 };
115
116 /*
117  * Exported data structure (read-only)
118  */
119 /* export structure */
120 struct dma_pub {
121         const struct di_fcn_s *di_fn;   /* DMA function pointers */
122         uint txavail;           /* # free tx descriptors */
123         uint dmactrlflags;      /* dma control flags */
124
125         /* rx error counters */
126         uint rxgiants;          /* rx giant frames */
127         uint rxnobuf;           /* rx out of dma descriptors */
128         /* tx error counters */
129         uint txnobuf;           /* tx out of dma descriptors */
130 };
131
132 extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
133                             void *dmaregstx, void *dmaregsrx, uint ntxd,
134                             uint nrxd, uint rxbufsize, int rxextheadroom,
135                             uint nrxpost, uint rxoffset, uint *msg_level);
136
137 extern const struct di_fcn_s dma64proc;
138
139 #define dma_detach(di)                  (dma64proc.detach(di))
140 #define dma_txreset(di)                 (dma64proc.txreset(di))
141 #define dma_rxreset(di)                 (dma64proc.rxreset(di))
142 #define dma_rxidle(di)                  (dma64proc.rxidle(di))
143 #define dma_txinit(di)                  (dma64proc.txinit(di))
144 #define dma_txenabled(di)               (dma64proc.txenabled(di))
145 #define dma_rxinit(di)                  (dma64proc.rxinit(di))
146 #define dma_txsuspend(di)               (dma64proc.txsuspend(di))
147 #define dma_txresume(di)                (dma64proc.txresume(di))
148 #define dma_txsuspended(di)             (dma64proc.txsuspended(di))
149 #define dma_txsuspendedidle(di)         (dma64proc.txsuspendedidle(di))
150 #define dma_txfast(di, p, commit)       (dma64proc.txfast(di, p, commit))
151 #define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit))
152 #define dma_getpos(di, dir)             (dma64proc.getpos(di, dir))
153 #define dma_fifoloopbackenable(di)      (dma64proc.fifoloopbackenable(di))
154 #define dma_txstopped(di)               (dma64proc.txstopped(di))
155 #define dma_rxstopped(di)               (dma64proc.rxstopped(di))
156 #define dma_rxenable(di)                (dma64proc.rxenable(di))
157 #define dma_rxenabled(di)               (dma64proc.rxenabled(di))
158 #define dma_rx(di)                      (dma64proc.rx(di))
159 #define dma_rxfill(di)                  (dma64proc.rxfill(di))
160 #define dma_txreclaim(di, range)        (dma64proc.txreclaim(di, range))
161 #define dma_rxreclaim(di)               (dma64proc.rxreclaim(di))
162 #define dma_getvar(di, name)            (dma64proc.d_getvar(di, name))
163 #define dma_getnexttxp(di, range)       (dma64proc.getnexttxp(di, range))
164 #define dma_getnextrxp(di, forceall)    (dma64proc.getnextrxp(di, forceall))
165 #define dma_peeknexttxp(di)             (dma64proc.peeknexttxp(di))
166 #define dma_peeknextrxp(di)             (dma64proc.peeknextrxp(di))
167 #define dma_rxparam_get(di, off, bufs)  (dma64proc.rxparam_get(di, off, bufs))
168
169 #define dma_txblock(di)                 (dma64proc.txblock(di))
170 #define dma_txunblock(di)               (dma64proc.txunblock(di))
171 #define dma_txactive(di)                (dma64proc.txactive(di))
172 #define dma_rxactive(di)                (dma64proc.rxactive(di))
173 #define dma_txrotate(di)                (dma64proc.txrotate(di))
174 #define dma_counterreset(di)            (dma64proc.counterreset(di))
175 #define dma_ctrlflags(di, mask, flags) \
176         (dma64proc.ctrlflags((di), (mask), (flags)))
177 #define dma_txpending(di)               (dma64proc.txpending(di))
178 #define dma_txcommitted(di)             (dma64proc.txcommitted(di))
179
180
181 void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
182                       (void *pkt, void *arg_a), void *arg_a);
183
184 /*
185  * DMA(Bug) on some chips seems to declare that the packet is ready, but the
186  * packet length is not updated yet (by DMA) on the expected time.
187  * Workaround is to hold processor till DMA updates the length, and stay off
188  * the bus to allow DMA update the length in buffer
189  */
190 static inline void dma_spin_for_len(uint len, struct sk_buff *head)
191 {
192 #if defined(__mips__)
193         if (!len) {
194                 while (!(len = *(u16 *) KSEG1ADDR(head->data)))
195                         udelay(1);
196
197                 *(u16 *) (head->data) = cpu_to_le16((u16) len);
198         }
199 #endif                          /* defined(__mips__) */
200 }
201
202 #endif                          /* _BRCM_DMA_H_ */