blob: 88ad34dff2f23b07b30e6accd18ecdc8be0ba208 [file] [log] [blame]
John W. Linvillef2223132006-01-23 16:59:58 -05001#ifndef BCM43xx_DMA_H_
2#define BCM43xx_DMA_H_
3
4#include <linux/list.h>
5#include <linux/spinlock.h>
6#include <linux/workqueue.h>
7#include <linux/linkage.h>
8#include <asm/atomic.h>
9
10
11/* DMA-Interrupt reasons. */
12/*TODO: add the missing ones. */
13#define BCM43xx_DMAIRQ_ERR0 (1 << 10)
14#define BCM43xx_DMAIRQ_ERR1 (1 << 11)
15#define BCM43xx_DMAIRQ_ERR2 (1 << 12)
16#define BCM43xx_DMAIRQ_ERR3 (1 << 13)
17#define BCM43xx_DMAIRQ_ERR4 (1 << 14)
18#define BCM43xx_DMAIRQ_ERR5 (1 << 15)
19#define BCM43xx_DMAIRQ_RX_DONE (1 << 16)
20/* helpers */
21#define BCM43xx_DMAIRQ_ANYERR (BCM43xx_DMAIRQ_ERR0 | \
22 BCM43xx_DMAIRQ_ERR1 | \
23 BCM43xx_DMAIRQ_ERR2 | \
24 BCM43xx_DMAIRQ_ERR3 | \
25 BCM43xx_DMAIRQ_ERR4 | \
26 BCM43xx_DMAIRQ_ERR5)
27#define BCM43xx_DMAIRQ_FATALERR (BCM43xx_DMAIRQ_ERR0 | \
28 BCM43xx_DMAIRQ_ERR1 | \
29 BCM43xx_DMAIRQ_ERR2 | \
30 BCM43xx_DMAIRQ_ERR4 | \
31 BCM43xx_DMAIRQ_ERR5)
32#define BCM43xx_DMAIRQ_NONFATALERR BCM43xx_DMAIRQ_ERR3
33
34/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */
35#define BCM43xx_DMA_TX_CONTROL 0x00
36#define BCM43xx_DMA_TX_DESC_RING 0x04
37#define BCM43xx_DMA_TX_DESC_INDEX 0x08
38#define BCM43xx_DMA_TX_STATUS 0x0c
39#define BCM43xx_DMA_RX_CONTROL 0x10
40#define BCM43xx_DMA_RX_DESC_RING 0x14
41#define BCM43xx_DMA_RX_DESC_INDEX 0x18
42#define BCM43xx_DMA_RX_STATUS 0x1c
43
44/* DMA controller channel control word values. */
45#define BCM43xx_DMA_TXCTRL_ENABLE (1 << 0)
46#define BCM43xx_DMA_TXCTRL_SUSPEND (1 << 1)
47#define BCM43xx_DMA_TXCTRL_LOOPBACK (1 << 2)
48#define BCM43xx_DMA_TXCTRL_FLUSH (1 << 4)
49#define BCM43xx_DMA_RXCTRL_ENABLE (1 << 0)
50#define BCM43xx_DMA_RXCTRL_FRAMEOFF_MASK 0x000000fe
51#define BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT 1
52#define BCM43xx_DMA_RXCTRL_PIO (1 << 8)
53/* DMA controller channel status word values. */
54#define BCM43xx_DMA_TXSTAT_DPTR_MASK 0x00000fff
55#define BCM43xx_DMA_TXSTAT_STAT_MASK 0x0000f000
56#define BCM43xx_DMA_TXSTAT_STAT_DISABLED 0x00000000
57#define BCM43xx_DMA_TXSTAT_STAT_ACTIVE 0x00001000
58#define BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT 0x00002000
59#define BCM43xx_DMA_TXSTAT_STAT_STOPPED 0x00003000
60#define BCM43xx_DMA_TXSTAT_STAT_SUSP 0x00004000
61#define BCM43xx_DMA_TXSTAT_ERROR_MASK 0x000f0000
62#define BCM43xx_DMA_TXSTAT_FLUSHED (1 << 20)
63#define BCM43xx_DMA_RXSTAT_DPTR_MASK 0x00000fff
64#define BCM43xx_DMA_RXSTAT_STAT_MASK 0x0000f000
65#define BCM43xx_DMA_RXSTAT_STAT_DISABLED 0x00000000
66#define BCM43xx_DMA_RXSTAT_STAT_ACTIVE 0x00001000
67#define BCM43xx_DMA_RXSTAT_STAT_IDLEWAIT 0x00002000
68#define BCM43xx_DMA_RXSTAT_STAT_RESERVED 0x00003000
69#define BCM43xx_DMA_RXSTAT_STAT_ERRORS 0x00004000
70#define BCM43xx_DMA_RXSTAT_ERROR_MASK 0x000f0000
71
72/* DMA descriptor control field values. */
73#define BCM43xx_DMADTOR_BYTECNT_MASK 0x00001fff
74#define BCM43xx_DMADTOR_DTABLEEND (1 << 28) /* End of descriptor table */
75#define BCM43xx_DMADTOR_COMPIRQ (1 << 29) /* IRQ on completion request */
76#define BCM43xx_DMADTOR_FRAMEEND (1 << 30)
77#define BCM43xx_DMADTOR_FRAMESTART (1 << 31)
78
79/* Misc DMA constants */
80#define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE
81#define BCM43xx_DMA_BUSADDRMAX 0x3FFFFFFF
82#define BCM43xx_DMA_DMABUSADDROFFSET (1 << 30)
83#define BCM43xx_DMA1_RX_FRAMEOFFSET 30
84#define BCM43xx_DMA4_RX_FRAMEOFFSET 0
85
86/* DMA engine tuning knobs */
87#define BCM43xx_TXRING_SLOTS 512
88#define BCM43xx_RXRING_SLOTS 64
89#define BCM43xx_DMA1_RXBUFFERSIZE (2304 + 100)
90#define BCM43xx_DMA4_RXBUFFERSIZE 16
91/* Suspend the tx queue, if less than this percent slots are free. */
92#define BCM43xx_TXSUSPEND_PERCENT 20
93/* Resume the tx queue, if more than this percent slots are free. */
94#define BCM43xx_TXRESUME_PERCENT 50
95
96
Michael Buesch77db31e2006-02-12 16:47:44 +010097
98#ifdef CONFIG_BCM43XX_DMA
99
100
John W. Linvillef2223132006-01-23 16:59:58 -0500101struct sk_buff;
102struct bcm43xx_private;
103struct bcm43xx_xmitstatus;
104
105
106struct bcm43xx_dmadesc {
107 __le32 _control;
108 __le32 _address;
109} __attribute__((__packed__));
110
111/* Macros to access the bcm43xx_dmadesc struct */
112#define get_desc_ctl(desc) le32_to_cpu((desc)->_control)
113#define set_desc_ctl(desc, ctl) do { (desc)->_control = cpu_to_le32(ctl); } while (0)
114#define get_desc_addr(desc) le32_to_cpu((desc)->_address)
115#define set_desc_addr(desc, addr) do { (desc)->_address = cpu_to_le32(addr); } while (0)
116
117struct bcm43xx_dmadesc_meta {
118 /* The kernel DMA-able buffer. */
119 struct sk_buff *skb;
120 /* DMA base bus-address of the descriptor buffer. */
121 dma_addr_t dmaaddr;
122 /* Pointer to our txb (can be NULL).
123 * This should be freed in completion IRQ.
124 */
125 struct ieee80211_txb *txb;
126};
127
128struct bcm43xx_dmaring {
John W. Linvillef2223132006-01-23 16:59:58 -0500129 struct bcm43xx_private *bcm;
130 /* Kernel virtual base address of the ring memory. */
131 struct bcm43xx_dmadesc *vbase;
132 /* DMA memory offset */
133 dma_addr_t memoffset;
134 /* (Unadjusted) DMA base bus-address of the ring memory. */
135 dma_addr_t dmabase;
136 /* Meta data about all descriptors. */
137 struct bcm43xx_dmadesc_meta *meta;
138 /* Number of descriptor slots in the ring. */
139 int nr_slots;
140 /* Number of used descriptor slots. */
141 int used_slots;
142 /* Currently used slot in the ring. */
143 int current_slot;
144 /* Marks to suspend/resume the queue. */
145 int suspend_mark;
146 int resume_mark;
147 /* Frameoffset in octets. */
148 u32 frameoffset;
149 /* Descriptor buffer size. */
150 u16 rx_buffersize;
151 /* The MMIO base register of the DMA controller, this
152 * ring is posted to.
153 */
154 u16 mmio_base;
155 u8 tx:1, /* TRUE, if this is a TX ring. */
156 suspended:1; /* TRUE, if transfers are suspended on this ring. */
157#ifdef CONFIG_BCM43XX_DEBUG
158 /* Maximum number of used slots. */
159 int max_used_slots;
160#endif /* CONFIG_BCM43XX_DEBUG*/
161};
162
163
164int bcm43xx_dma_init(struct bcm43xx_private *bcm);
165void bcm43xx_dma_free(struct bcm43xx_private *bcm);
166
167int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
168 u16 dmacontroller_mmio_base);
169int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
170 u16 dmacontroller_mmio_base);
171
Michael Bueschea72ab22006-01-27 17:26:20 +0100172void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
173 struct bcm43xx_xmitstatus *status);
John W. Linvillef2223132006-01-23 16:59:58 -0500174
Michael Bueschea72ab22006-01-27 17:26:20 +0100175int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
176 struct ieee80211_txb *txb);
177void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
John W. Linvillef2223132006-01-23 16:59:58 -0500178
Michael Buesch77db31e2006-02-12 16:47:44 +0100179
180#else /* CONFIG_BCM43XX_DMA */
181
182
183static inline
184int bcm43xx_dma_init(struct bcm43xx_private *bcm)
185{
186 return 0;
187}
188static inline
189void bcm43xx_dma_free(struct bcm43xx_private *bcm)
190{
191}
192static inline
193int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
194 u16 dmacontroller_mmio_base)
195{
196 return 0;
197}
198static inline
199int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
200 u16 dmacontroller_mmio_base)
201{
202 return 0;
203}
204static inline
205int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
206 struct ieee80211_txb *txb)
207{
208 return 0;
209}
210static inline
211void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
212 struct bcm43xx_xmitstatus *status)
213{
214}
215static inline
216void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
217{
218}
219
220#endif /* CONFIG_BCM43XX_DMA */
John W. Linvillef2223132006-01-23 16:59:58 -0500221#endif /* BCM43xx_DMA_H_ */