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