carl9170 firmware: improve mac reset handling
[carl9170fw.git] / carlfw / include / dma.h
1 /*
2  * carl9170 firmware - used by the ar9170 wireless device
3  *
4  * This module contains DMA descriptor related definitions.
5  *
6  * Copyright (c) 2000-2005 ZyDAS Technology Corporation
7  * Copyright (c) 2007-2009 Atheros Communications, Inc.
8  * Copyright    2009    Johannes Berg <johannes@sipsolutions.net>
9  * Copyright 2009, 2010 Christian Lamparter <chunkeey@googlemail.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26 #ifndef __CARL9170FW_DMA_H
27 #define __CARL9170FW_DMA_H
28
29 #include "config.h"
30 #include "types.h"
31 #include "compiler.h"
32 #include "hw.h"
33 #include "ieee80211.h"
34 #include "wlan.h"
35
36 struct dma_desc {
37         volatile uint16_t status;       /* Descriptor status */
38         volatile uint16_t ctrl;         /* Descriptor control */
39         volatile uint16_t dataSize;     /* Data size */
40         volatile uint16_t totalLen;     /* Total length */
41         struct dma_desc *lastAddr;      /* Last address of this chain */
42         union {
43                 uint8_t *_dataAddr;     /* Data buffer address */
44                 void *dataAddr;
45         } __packed;
46         struct dma_desc *nextAddr;      /* Next TD address */
47 } __packed;
48
49 /* (Up, Dn, 5x Tx, Rx), USB Int, (5x delayed Tx + retry), CAB, BA */
50 #define AR9170_TERMINATOR_NUMBER_B      8
51
52 #define AR9170_TERMINATOR_NUMBER_INT    1
53
54 #ifdef CONFIG_CARL9170FW_DELAYED_TX
55 #define AR9170_TERMINATOR_NUMBER_DELAY  6
56 #else
57 #define AR9170_TERMINATOR_NUMBER_DELAY  0
58 #endif /* CONFIG_CARL9170FW_DELAYED_TX */
59
60 #ifdef CONFIG_CARL9170FW_CAB_QUEUE
61 #define AR9170_TERMINATOR_NUMBER_CAB    CARL9170_INTF_NUM
62 #else
63 #define AR9170_TERMINATOR_NUMBER_CAB    0
64 #endif /* CONFIG_CARL9170FW_CAB_QUEUE */
65
66 #ifdef CONFIG_CARL9170FW_HANDLE_BACK_REQ
67 #define AR9170_TERMINATOR_NUMBER_BA     1
68 #else
69 #define AR9170_TERMINATOR_NUMBER_BA     0
70 #endif /* CONFIG_CARL9170FW_HANDLE_BACK_REQ */
71 #define AR9170_TERMINATOR_NUMBER (AR9170_TERMINATOR_NUMBER_B + \
72                                   AR9170_TERMINATOR_NUMBER_INT + \
73                                   AR9170_TERMINATOR_NUMBER_DELAY + \
74                                   AR9170_TERMINATOR_NUMBER_CAB + \
75                                   AR9170_TERMINATOR_NUMBER_BA)
76
77 #define AR9170_BLOCK_SIZE           (256 + 64)
78
79 #define AR9170_DESCRIPTOR_SIZE      (sizeof(struct dma_desc))
80
81 struct ar9170_tx_ba_frame {
82         struct ar9170_tx_hwdesc hdr;
83         struct ieee80211_ba ba;
84 } __packed;
85
86 struct carl9170_tx_ba_superframe {
87         struct carl9170_tx_superdesc s;
88         struct ar9170_tx_ba_frame f;
89 } __packed;
90
91 #define CARL9170_BA_BUFFER_LEN  (__roundup(sizeof(struct carl9170_tx_ba_superframe), 16))
92 #define CARL9170_RSP_BUFFER_LEN AR9170_BLOCK_SIZE
93
94 struct carl9170_sram_reserved {
95 #ifdef CONFIG_CARL9170FW_HANDLE_BACK_REQ
96         union {
97                 uint32_t buf[CARL9170_BA_BUFFER_LEN / sizeof(uint32_t)];
98                 struct carl9170_tx_ba_superframe ba;
99         } ba;
100 #endif /* CONFIG_CARL9170FW_HANDLE_BACK_REQ */
101         union {
102                 uint32_t buf[CARL9170_MAX_CMD_LEN / sizeof(uint32_t)];
103                 struct carl9170_cmd cmd;
104         } cmd;
105
106         union {
107                 uint32_t buf[CARL9170_RSP_BUFFER_LEN / sizeof(uint32_t)];
108                 struct carl9170_rsp rsp;
109         } rsp;
110
111         union {
112                 uint32_t buf[CARL9170_INTF_NUM][AR9170_MAC_BCN_LENGTH_MAX / sizeof(uint32_t)];
113         } bcn;
114 };
115
116 /*
117  * Memory layout in RAM:
118  *
119  * 0x100000                     +--
120  *                              | terminator descriptors (dma_desc)
121  *                              |  - Up (to USB host)
122  *                              |  - Down (from USB host)
123  *                              |  - TX (5x, to wifi)
124  *                              |  - RX (from wifi)
125  *                              |  - CAB Queue
126  *                              |  - FW cmd & req descriptor
127  *                              |  - BlockAck descriptor
128  *                              |  - Delayed TX (5x)
129  *                              | total: AR9170_TERMINATOR_NUMBER
130  *                              +--
131  *                              | block descriptors (dma_desc)
132  *                              | (AR9170_BLOCK_NUMBER)
133  * AR9170_BLOCK_BUFFER_BASE     +-- align to multiple of 64
134  *                              | block buffers (AR9170_BLOCK_SIZE each)
135  *                              | (AR9170_BLOCK_NUMBER)
136  * approx. 0x117c00             +--
137  *                              | BA buffer (128 bytes)
138  *                              +--
139  *                              | CMD buffer (128 bytes)
140  *                              +--
141  *                              | RSP buffer (320 bytes)
142  *                              +--
143  *                              | BEACON buffer (256 bytes)
144  *                              +--
145  *                              | unaccounted space / padding
146  *                              +--
147  * 0x18000
148  */
149
150 #define CARL9170_SRAM_RESERVED          (sizeof(struct carl9170_sram_reserved))
151
152 #define AR9170_FRAME_MEMORY_SIZE        (AR9170_SRAM_SIZE - CARL9170_SRAM_RESERVED)
153
154 #define BLOCK_ALIGNMENT         64
155
156 #define NONBLOCK_DESCRIPTORS_SIZE       \
157         (AR9170_DESCRIPTOR_SIZE * (AR9170_TERMINATOR_NUMBER))
158
159 #define NONBLOCK_DESCRIPTORS_SIZE_ALIGNED       \
160         (ALIGN(NONBLOCK_DESCRIPTORS_SIZE, BLOCK_ALIGNMENT))
161
162 #define AR9170_BLOCK_NUMBER     ((AR9170_FRAME_MEMORY_SIZE - NONBLOCK_DESCRIPTORS_SIZE_ALIGNED) / \
163                                  (AR9170_BLOCK_SIZE + AR9170_DESCRIPTOR_SIZE))
164
165 struct ar9170_data_block {
166         uint8_t data[AR9170_BLOCK_SIZE];
167 };
168
169 struct ar9170_dma_memory {
170         struct dma_desc                 terminator[AR9170_TERMINATOR_NUMBER];
171         struct dma_desc                 block[AR9170_BLOCK_NUMBER];
172         struct ar9170_data_block        data[AR9170_BLOCK_NUMBER] __attribute__((aligned(BLOCK_ALIGNMENT)));
173         struct carl9170_sram_reserved   reserved __attribute__((aligned(BLOCK_ALIGNMENT)));
174 };
175
176 extern struct ar9170_dma_memory dma_mem;
177
178 #define AR9170_DOWN_BLOCK_RATIO 2
179 #define AR9170_RX_BLOCK_RATIO   1
180 /* Tx 16*2 = 32 packets => 32*(5*320) */
181 #define AR9170_TX_BLOCK_NUMBER  (AR9170_BLOCK_NUMBER * AR9170_DOWN_BLOCK_RATIO / \
182                                 (AR9170_RX_BLOCK_RATIO + AR9170_DOWN_BLOCK_RATIO))
183 #define AR9170_RX_BLOCK_NUMBER  (AR9170_BLOCK_NUMBER - AR9170_TX_BLOCK_NUMBER)
184
185 /* Error code */
186 #define AR9170_ERR_FS_BIT       1
187 #define AR9170_ERR_LS_BIT       2
188 #define AR9170_ERR_OWN_BITS     3
189 #define AR9170_ERR_DATA_SIZE    4
190 #define AR9170_ERR_TOTAL_LEN    5
191 #define AR9170_ERR_DATA         6
192 #define AR9170_ERR_SEQ          7
193 #define AR9170_ERR_LEN          8
194
195 /* Status bits definitions */
196 /* Own bits definitions */
197 #define AR9170_OWN_BITS         0x3
198 #define AR9170_OWN_BITS_S       0
199 #define AR9170_OWN_BITS_SW      0x0
200 #define AR9170_OWN_BITS_HW      0x1
201 #define AR9170_OWN_BITS_SE      0x2
202
203 /* Control bits definitions */
204 #define AR9170_CTRL_TXFAIL      1
205 #define AR9170_CTRL_BAFAIL      2
206 #define AR9170_CTRL_FAIL        (AR9170_CTRL_TXFAIL | AR9170_CTRL_BAFAIL)
207
208 /* First segament bit */
209 #define AR9170_CTRL_LS_BIT      0x100
210 /* Last segament bit */
211 #define AR9170_CTRL_FS_BIT      0x200
212
213 struct dma_queue {
214         struct dma_desc *head;
215         struct dma_desc *terminator;
216 };
217
218 #define DESC_PAYLOAD(a)                 ((void *)a->dataAddr)
219 #define DESC_PAYLOAD_OFF(a, offset)     ((void *)((unsigned long)(a->_dataAddr) + offset))
220
221 struct dma_desc *dma_unlink_head(struct dma_queue *queue);
222 void dma_init_descriptors(void);
223 void dma_reclaim(struct dma_queue *q, struct dma_desc *desc);
224 void dma_put(struct dma_queue *q, struct dma_desc *desc);
225 void dma_queue_reclaim(struct dma_queue *dst, struct dma_queue *src);
226 void queue_dump(void);
227 void wlan_txq_hangfix(const unsigned int queue);
228
229 static inline __inline bool is_terminator(struct dma_queue *q, struct dma_desc *desc)
230 {
231         return q->terminator == desc;
232 }
233
234 static inline __inline bool queue_empty(struct dma_queue *q)
235 {
236         return q->head == q->terminator;
237 }
238
239 /*
240  * Get a completed packet with # descriptors. Return the first
241  * descriptor and pointer the head directly by lastAddr->nextAddr
242  */
243 static inline __inline struct dma_desc *dma_dequeue_bits(struct dma_queue *q,
244                                                 uint16_t bits)
245 {
246         struct dma_desc *desc = NULL;
247
248         if ((q->head->status & AR9170_OWN_BITS) == bits)
249                 desc = dma_unlink_head(q);
250
251         return desc;
252 }
253
254 static inline __inline struct dma_desc *dma_dequeue_not_bits(struct dma_queue *q,
255                                                     uint16_t bits)
256 {
257         struct dma_desc *desc = NULL;
258
259         /* AR9170_OWN_BITS_HW will be filtered out here too. */
260         if ((q->head->status & AR9170_OWN_BITS) != bits)
261                 desc = dma_unlink_head(q);
262
263         return desc;
264 }
265
266 #define for_each_desc_bits(desc, queue, bits)                           \
267         while ((desc = dma_dequeue_bits(queue, bits)))
268
269 #define for_each_desc_not_bits(desc, queue, bits)                       \
270         while ((desc = dma_dequeue_not_bits(queue, bits)))
271
272 #define for_each_desc(desc, queue)                                      \
273         while ((desc = dma_unlink_head(queue)))
274
275 #define __for_each_desc_bits(desc, queue, bits)                         \
276         for (desc = (queue)->head;                                      \
277              (desc != (queue)->terminator &&                            \
278              (desc->status & AR9170_OWN_BITS) == bits);                 \
279              desc = desc->lastAddr->nextAddr)
280
281 #define __while_desc_bits(desc, queue, bits)                            \
282         for (desc = (queue)->head;                                      \
283              (!queue_empty(queue) &&                                    \
284              (desc->status & AR9170_OWN_BITS) == bits);                 \
285              desc = (queue)->head)
286
287 #define __for_each_desc(desc, queue)                                    \
288         for (desc = (queue)->head;                                      \
289              desc != (queue)->terminator;                               \
290              desc = (desc)->lastAddr->nextAddr)
291
292 #define __for_each_desc_safe(desc, tmp, queue)                          \
293         for (desc = (queue)->head, tmp = desc->lastAddr->nextAddr;      \
294              desc != (queue)->terminator;                               \
295              desc = tmp, tmp = tmp->lastAddr->nextAddr)
296
297 #define __while_subdesc(desc, queue)                                    \
298         for (desc = (queue)->head;                                      \
299              desc != (queue)->terminator;                               \
300              desc = (desc)->nextAddr)
301
302 static inline __inline unsigned int queue_len(struct dma_queue *q)
303 {
304         struct dma_desc *desc;
305         unsigned int i = 0;
306
307         __while_subdesc(desc, q)
308                 i++;
309
310         return i;
311 }
312
313 /*
314  * rearm a completed packet, so it will be processed agian.
315  */
316 static inline __inline void dma_rearm(struct dma_desc *desc)
317 {
318         /* Set OWN bit to HW */
319         desc->status = ((desc->status & (~AR9170_OWN_BITS)) |
320                         AR9170_OWN_BITS_HW);
321 }
322
323 static inline void __check_desc(void)
324 {
325         struct ar9170_dma_memory mem;
326         BUILD_BUG_ON(sizeof(struct ar9170_data_block) != AR9170_BLOCK_SIZE);
327         BUILD_BUG_ON(sizeof(struct dma_desc) != 20);
328
329         BUILD_BUG_ON(sizeof(mem) > AR9170_SRAM_SIZE);
330
331 #ifdef CONFIG_CARL9170FW_HANDLE_BACK_REQ
332         BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, ba.buf) & (BLOCK_ALIGNMENT - 1));
333 #endif /* CONFIG_CARL9170FW_HANDLE_BACK_REQ */
334         BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, cmd.buf) & (BLOCK_ALIGNMENT - 1));
335         BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, rsp.buf) & (BLOCK_ALIGNMENT - 1));
336         BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, bcn.buf) & (BLOCK_ALIGNMENT - 1));
337 }
338
339 #endif /* __CARL9170FW_DMA_H */