summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/wcn36xx/dxe.h
blob: dd8c684a3ba7536423807fa50a963e79a189c3e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
/*
 * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef _DXE_H_
#define _DXE_H_

#include "wcn36xx.h"

/*
TX_LOW	= DMA0
TX_HIGH	= DMA4
RX_LOW	= DMA1
RX_HIGH	= DMA3
H2H_TEST_RX_TX = DMA2
*/

/* DXE registers */
#define WCN36XX_DXE_MEM_REG			0

#define WCN36XX_CCU_DXE_INT_SELECT_RIVA		0x310
#define WCN36XX_CCU_DXE_INT_SELECT_PRONTO	0x10dc

/* Descriptor valid */
#define WCN36xx_DXE_CTRL_VLD		BIT(0)
/* End of packet */
#define WCN36xx_DXE_CTRL_EOP		BIT(3)
/* BD handling bit */
#define WCN36xx_DXE_CTRL_BDH		BIT(4)
/* Source is a queue */
#define WCN36xx_DXE_CTRL_SIQ		BIT(5)
/* Destination is a queue */
#define WCN36xx_DXE_CTRL_DIQ		BIT(6)
/* Pointer address is a queue */
#define WCN36xx_DXE_CTRL_PIQ		BIT(7)
/* Release PDU when done */
#define WCN36xx_DXE_CTRL_PDU_REL	BIT(8)
/* STOP channel processing */
#define WCN36xx_DXE_CTRL_STOP		BIT(16)
/* INT on descriptor done */
#define WCN36xx_DXE_CTRL_INT		BIT(17)
/* Endian byte swap enable */
#define WCN36xx_DXE_CTRL_SWAP		BIT(20)
/* Master endianness */
#define WCN36xx_DXE_CTRL_ENDIANNESS	BIT(21)

/* Transfer type */
#define WCN36xx_DXE_CTRL_XTYPE_SHIFT 1
#define WCN36xx_DXE_CTRL_XTYPE_MASK GENMASK(2, WCN36xx_DXE_CTRL_XTYPE_SHIFT)
#define WCN36xx_DXE_CTRL_XTYPE_SET(x)	((x) << WCN36xx_DXE_CTRL_XTYPE_SHIFT)

/* BMU Threshold select */
#define WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT 9
#define WCN36xx_DXE_CTRL_BTHLD_SEL_MASK GENMASK(12, WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT)
#define WCN36xx_DXE_CTRL_BTHLD_SEL_SET(x) ((x) << WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT)

/* Priority */
#define WCN36xx_DXE_CTRL_PRIO_SHIFT 13
#define WCN36xx_DXE_CTRL_PRIO_MASK GENMASK(15, WCN36xx_DXE_CTRL_PRIO_SHIFT)
#define WCN36xx_DXE_CTRL_PRIO_SET(x) ((x) << WCN36xx_DXE_CTRL_PRIO_SHIFT)

/* BD Template index */
#define WCN36xx_DXE_CTRL_BDT_IDX_SHIFT 18
#define WCN36xx_DXE_CTRL_BDT_IDX_MASK GENMASK(19, WCN36xx_DXE_CTRL_BDT_IDX_SHIFT)
#define WCN36xx_DXE_CTRL_BDT_IDX_SET(x) ((x) << WCN36xx_DXE_CTRL_BDT_IDX_SHIFT)

/* Transfer types: */
/* Host to host */
#define WCN36xx_DXE_XTYPE_H2H (0)
/* Host to BMU */
#define WCN36xx_DXE_XTYPE_H2B (2)
/* BMU to host */
#define WCN36xx_DXE_XTYPE_B2H (3)

#define WCN36XX_DXE_CTRL_TX_L	(WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
	WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | \
	WCN36xx_DXE_CTRL_PRIO_SET(4) | WCN36xx_DXE_CTRL_INT | \
	WCN36xx_DXE_CTRL_SWAP | WCN36xx_DXE_CTRL_ENDIANNESS)

#define WCN36XX_DXE_CTRL_TX_H	 (WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
	WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | \
	WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_INT | \
	WCN36xx_DXE_CTRL_SWAP | WCN36xx_DXE_CTRL_ENDIANNESS)

#define WCN36XX_DXE_CTRL_RX_L	(WCN36xx_DXE_CTRL_VLD | \
	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
	WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_SIQ | \
	WCN36xx_DXE_CTRL_PDU_REL | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(6) | \
	WCN36xx_DXE_CTRL_PRIO_SET(5) | WCN36xx_DXE_CTRL_INT | \
	WCN36xx_DXE_CTRL_SWAP)

#define WCN36XX_DXE_CTRL_RX_H	(WCN36xx_DXE_CTRL_VLD | \
	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
	WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_SIQ | \
	WCN36xx_DXE_CTRL_PDU_REL |  WCN36xx_DXE_CTRL_BTHLD_SEL_SET(8) | \
	WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_INT | \
	WCN36xx_DXE_CTRL_SWAP)

#define WCN36XX_DXE_CTRL_TX_H_BD	(WCN36xx_DXE_CTRL_VLD | \
	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
	WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | \
	WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_SWAP | \
	WCN36xx_DXE_CTRL_ENDIANNESS)

#define WCN36XX_DXE_CTRL_TX_H_SKB	(WCN36xx_DXE_CTRL_VLD | \
	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
	WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_DIQ | \
	WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | WCN36xx_DXE_CTRL_PRIO_SET(6) | \
	WCN36xx_DXE_CTRL_INT | WCN36xx_DXE_CTRL_SWAP | \
	WCN36xx_DXE_CTRL_ENDIANNESS)

#define WCN36XX_DXE_CTRL_TX_L_BD	 (WCN36xx_DXE_CTRL_VLD | \
	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
	WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | \
	WCN36xx_DXE_CTRL_PRIO_SET(4) | WCN36xx_DXE_CTRL_SWAP | \
	WCN36xx_DXE_CTRL_ENDIANNESS)

#define WCN36XX_DXE_CTRL_TX_L_SKB	(WCN36xx_DXE_CTRL_VLD | \
	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
	WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_DIQ | \
	WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | WCN36xx_DXE_CTRL_PRIO_SET(4) | \
	WCN36xx_DXE_CTRL_INT | WCN36xx_DXE_CTRL_SWAP | \
	WCN36xx_DXE_CTRL_ENDIANNESS)

/* TODO This must calculated properly but not hardcoded */
#define WCN36XX_DXE_WQ_TX_L(wcn)    ((wcn)->is_pronto_v3 ? 0x6 : 0x17)
#define WCN36XX_DXE_WQ_TX_H(wcn)    ((wcn)->is_pronto_v3 ? 0x6 : 0x17)
#define WCN36XX_DXE_WQ_RX_L			0xB
#define WCN36XX_DXE_WQ_RX_H			0x4

/* Channel enable or restart */
#define WCN36xx_DXE_CH_CTRL_EN			BIT(0)
/* End of packet bit */
#define WCN36xx_DXE_CH_CTRL_EOP			BIT(3)
/* BD Handling bit */
#define WCN36xx_DXE_CH_CTRL_BDH			BIT(4)
/* Source is queue */
#define WCN36xx_DXE_CH_CTRL_SIQ			BIT(5)
/* Destination is queue */
#define WCN36xx_DXE_CH_CTRL_DIQ			BIT(6)
/* Pointer descriptor is queue */
#define WCN36xx_DXE_CH_CTRL_PIQ			BIT(7)
/* Relase PDU when done */
#define WCN36xx_DXE_CH_CTRL_PDU_REL		BIT(8)
/* Stop channel processing */
#define WCN36xx_DXE_CH_CTRL_STOP		BIT(16)
/* Enable external descriptor interrupt */
#define WCN36xx_DXE_CH_CTRL_INE_ED		BIT(17)
/* Enable channel interrupt on errors */
#define WCN36xx_DXE_CH_CTRL_INE_ERR		BIT(18)
/* Enable Channel interrupt when done */
#define WCN36xx_DXE_CH_CTRL_INE_DONE	BIT(19)
/* External descriptor enable */
#define WCN36xx_DXE_CH_CTRL_EDEN		BIT(20)
/* Wait for valid bit */
#define WCN36xx_DXE_CH_CTRL_EDVEN		BIT(21)
/* Endianness is little endian*/
#define WCN36xx_DXE_CH_CTRL_ENDIANNESS	BIT(26)
/* Abort transfer */
#define WCN36xx_DXE_CH_CTRL_ABORT		BIT(27)
/* Long descriptor format */
#define WCN36xx_DXE_CH_CTRL_DFMT		BIT(28)
/* Endian byte swap enable */
#define WCN36xx_DXE_CH_CTRL_SWAP		BIT(31)

/* Transfer type */
#define WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT 1
#define WCN36xx_DXE_CH_CTRL_XTYPE_MASK GENMASK(2, WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT)
#define WCN36xx_DXE_CH_CTRL_XTYPE_SET(x)	((x) << WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT)

/* Channel BMU Threshold select */
#define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT 9
#define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_MASK GENMASK(12, WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT)
#define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT)

/* Channel Priority */
#define WCN36xx_DXE_CH_CTRL_PRIO_SHIFT 13
#define WCN36xx_DXE_CH_CTRL_PRIO_MASK GENMASK(15, WCN36xx_DXE_CH_CTRL_PRIO_SHIFT)
#define WCN36xx_DXE_CH_CTRL_PRIO_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_PRIO_SHIFT)

/* Counter select */
#define WCN36xx_DXE_CH_CTRL_SEL_SHIFT 22
#define WCN36xx_DXE_CH_CTRL_SEL_MASK GENMASK(25, WCN36xx_DXE_CH_CTRL_SEL_SHIFT)
#define WCN36xx_DXE_CH_CTRL_SEL_SET(x)	((x) << WCN36xx_DXE_CH_CTRL_SEL_SHIFT)

/* Channel BD template index */
#define WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT 29
#define WCN36xx_DXE_CH_CTRL_BDT_IDX_MASK GENMASK(30, WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT)
#define WCN36xx_DXE_CH_CTRL_BDT_IDX_SET(x)	((x) << WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT)

/* DXE default control register values */
#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_L (WCN36xx_DXE_CH_CTRL_EN | \
		WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
		WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_SIQ | \
		WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(6) | \
		WCN36xx_DXE_CH_CTRL_PRIO_SET(5) | WCN36xx_DXE_CH_CTRL_INE_ED | \
		WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
		WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
		WCN36xx_DXE_CH_CTRL_SEL_SET(1) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
		WCN36xx_DXE_CH_CTRL_SWAP)

#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_H (WCN36xx_DXE_CH_CTRL_EN | \
		WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
		WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_SIQ | \
		WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(8) | \
		WCN36xx_DXE_CH_CTRL_PRIO_SET(6) | WCN36xx_DXE_CH_CTRL_INE_ED | \
		WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
		WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
		WCN36xx_DXE_CH_CTRL_SEL_SET(3) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
		WCN36xx_DXE_CH_CTRL_SWAP)

#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_H	(WCN36xx_DXE_CH_CTRL_EN | \
		WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
		WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_DIQ | \
		WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(7) | \
		WCN36xx_DXE_CH_CTRL_PRIO_SET(6) | WCN36xx_DXE_CH_CTRL_INE_ED | \
		WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
		WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
		WCN36xx_DXE_CH_CTRL_SEL_SET(4) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
		WCN36xx_DXE_CH_CTRL_SWAP)

#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_L (WCN36xx_DXE_CH_CTRL_EN | \
		WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
		WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_DIQ | \
		WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(5) | \
		WCN36xx_DXE_CH_CTRL_PRIO_SET(4) | WCN36xx_DXE_CH_CTRL_INE_ED | \
		WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
		WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
		WCN36xx_DXE_CH_CTRL_SEL_SET(0) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
		WCN36xx_DXE_CH_CTRL_SWAP)

/* Common DXE registers */
#define WCN36XX_DXE_MEM_CSR			(WCN36XX_DXE_MEM_REG + 0x00)
#define WCN36XX_DXE_REG_CSR_RESET		(WCN36XX_DXE_MEM_REG + 0x00)
#define WCN36XX_DXE_ENCH_ADDR			(WCN36XX_DXE_MEM_REG + 0x04)
#define WCN36XX_DXE_REG_CH_EN			(WCN36XX_DXE_MEM_REG + 0x08)
#define WCN36XX_DXE_REG_CH_DONE			(WCN36XX_DXE_MEM_REG + 0x0C)
#define WCN36XX_DXE_REG_CH_ERR			(WCN36XX_DXE_MEM_REG + 0x10)
#define WCN36XX_DXE_INT_MASK_REG		(WCN36XX_DXE_MEM_REG + 0x18)
#define WCN36XX_DXE_INT_SRC_RAW_REG		(WCN36XX_DXE_MEM_REG + 0x20)
	/* #define WCN36XX_DXE_INT_CH6_MASK	0x00000040 */
	/* #define WCN36XX_DXE_INT_CH5_MASK	0x00000020 */
	#define WCN36XX_DXE_INT_CH4_MASK	0x00000010
	#define WCN36XX_DXE_INT_CH3_MASK	0x00000008
	/* #define WCN36XX_DXE_INT_CH2_MASK	0x00000004 */
	#define WCN36XX_DXE_INT_CH1_MASK	0x00000002
	#define WCN36XX_DXE_INT_CH0_MASK	0x00000001
#define WCN36XX_DXE_0_INT_CLR			(WCN36XX_DXE_MEM_REG + 0x30)
#define WCN36XX_DXE_0_INT_ED_CLR		(WCN36XX_DXE_MEM_REG + 0x34)
#define WCN36XX_DXE_0_INT_DONE_CLR		(WCN36XX_DXE_MEM_REG + 0x38)
#define WCN36XX_DXE_0_INT_ERR_CLR		(WCN36XX_DXE_MEM_REG + 0x3C)

#define WCN36XX_CH_STAT_INT_DONE_MASK   0x00008000
#define WCN36XX_CH_STAT_INT_ERR_MASK    0x00004000
#define WCN36XX_CH_STAT_INT_ED_MASK     0x00002000

#define WCN36XX_DXE_0_CH0_STATUS		(WCN36XX_DXE_MEM_REG + 0x404)
#define WCN36XX_DXE_0_CH1_STATUS		(WCN36XX_DXE_MEM_REG + 0x444)
#define WCN36XX_DXE_0_CH2_STATUS		(WCN36XX_DXE_MEM_REG + 0x484)
#define WCN36XX_DXE_0_CH3_STATUS		(WCN36XX_DXE_MEM_REG + 0x4C4)
#define WCN36XX_DXE_0_CH4_STATUS		(WCN36XX_DXE_MEM_REG + 0x504)

#define WCN36XX_DXE_REG_RESET			0x5c89

/* Temporary BMU Workqueue 4 */
#define WCN36XX_DXE_BMU_WQ_RX_LOW		0xB
#define WCN36XX_DXE_BMU_WQ_RX_HIGH		0x4
/* DMA channel offset */
#define WCN36XX_DXE_TX_LOW_OFFSET		0x400
#define WCN36XX_DXE_TX_HIGH_OFFSET		0x500
#define WCN36XX_DXE_RX_LOW_OFFSET		0x440
#define WCN36XX_DXE_RX_HIGH_OFFSET		0x4C0

/* Address of the next DXE descriptor */
#define WCN36XX_DXE_CH_NEXT_DESC_ADDR		0x001C
#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_L	(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_TX_LOW_OFFSET + \
						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)
#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_H	(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_TX_HIGH_OFFSET + \
						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)
#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_L	(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_RX_LOW_OFFSET + \
						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)
#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_H	(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_RX_HIGH_OFFSET + \
						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)

/* DXE Descriptor source address */
#define WCN36XX_DXE_CH_SRC_ADDR			0x000C
#define WCN36XX_DXE_CH_SRC_ADDR_RX_L		(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_RX_LOW_OFFSET + \
						 WCN36XX_DXE_CH_SRC_ADDR)
#define WCN36XX_DXE_CH_SRC_ADDR_RX_H		(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_RX_HIGH_OFFSET + \
						 WCN36XX_DXE_CH_SRC_ADDR)

/* DXE Descriptor address destination address */
#define WCN36XX_DXE_CH_DEST_ADDR		0x0014
#define WCN36XX_DXE_CH_DEST_ADDR_TX_L		(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_TX_LOW_OFFSET + \
						 WCN36XX_DXE_CH_DEST_ADDR)
#define WCN36XX_DXE_CH_DEST_ADDR_TX_H		(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_TX_HIGH_OFFSET + \
						 WCN36XX_DXE_CH_DEST_ADDR)
#define WCN36XX_DXE_CH_DEST_ADDR_RX_L		(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_RX_LOW_OFFSET + \
						 WCN36XX_DXE_CH_DEST_ADDR)
#define WCN36XX_DXE_CH_DEST_ADDR_RX_H		(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_RX_HIGH_OFFSET + \
						 WCN36XX_DXE_CH_DEST_ADDR)

/* Interrupt status */
#define WCN36XX_DXE_CH_STATUS_REG_ADDR		0x0004
#define WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L	(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_TX_LOW_OFFSET + \
						 WCN36XX_DXE_CH_STATUS_REG_ADDR)
#define WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H	(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_TX_HIGH_OFFSET + \
						 WCN36XX_DXE_CH_STATUS_REG_ADDR)
#define WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_L	(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_RX_LOW_OFFSET + \
						 WCN36XX_DXE_CH_STATUS_REG_ADDR)
#define WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_H	(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_RX_HIGH_OFFSET + \
						 WCN36XX_DXE_CH_STATUS_REG_ADDR)


/* DXE default control register */
#define WCN36XX_DXE_REG_CTL_RX_L		(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_RX_LOW_OFFSET)
#define WCN36XX_DXE_REG_CTL_RX_H		(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_RX_HIGH_OFFSET)
#define WCN36XX_DXE_REG_CTL_TX_H		(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_TX_HIGH_OFFSET)
#define WCN36XX_DXE_REG_CTL_TX_L		(WCN36XX_DXE_MEM_REG + \
						 WCN36XX_DXE_TX_LOW_OFFSET)

#define WCN36XX_SMSM_WLAN_TX_ENABLE		0x00000400
#define WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY	0x00000200


/* Interrupt control channel mask */
#define WCN36XX_INT_MASK_CHAN_TX_L		0x00000001
#define WCN36XX_INT_MASK_CHAN_RX_L		0x00000002
#define WCN36XX_INT_MASK_CHAN_RX_H		0x00000008
#define WCN36XX_INT_MASK_CHAN_TX_H		0x00000010

#define WCN36XX_BD_CHUNK_SIZE			128

#define WCN36XX_PKT_SIZE			0xF20
enum wcn36xx_dxe_ch_type {
	WCN36XX_DXE_CH_TX_L,
	WCN36XX_DXE_CH_TX_H,
	WCN36XX_DXE_CH_RX_L,
	WCN36XX_DXE_CH_RX_H
};

/* amount of descriptors per channel */
enum wcn36xx_dxe_ch_desc_num {
	WCN36XX_DXE_CH_DESC_NUMB_TX_L		= 128,
	WCN36XX_DXE_CH_DESC_NUMB_TX_H		= 10,
	WCN36XX_DXE_CH_DESC_NUMB_RX_L		= 512,
	WCN36XX_DXE_CH_DESC_NUMB_RX_H		= 40
};

/**
 * struct wcn36xx_dxe_desc - describes descriptor of one DXE buffer
 *
 * @ctrl: is a union that consists of following bits:
 * union {
 *	u32	valid		:1; //0 = DMA stop, 1 = DMA continue with this
 *				    //descriptor
 *	u32	transfer_type	:2; //0 = Host to Host space
 *	u32	eop		:1; //End of Packet
 *	u32	bd_handling	:1; //if transferType = Host to BMU, then 0
 *				    // means first 128 bytes contain BD, and 1
 *				    // means create new empty BD
 *	u32	siq		:1; // SIQ
 *	u32	diq		:1; // DIQ
 *	u32	pdu_rel		:1; //0 = don't release BD and PDUs when done,
 *				    // 1 = release them
 *	u32	bthld_sel	:4; //BMU Threshold Select
 *	u32	prio		:3; //Specifies the priority level to use for
 *				    // the transfer
 *	u32	stop_channel	:1; //1 = DMA stops processing further, channel
 *				    //requires re-enabling after this
 *	u32	intr		:1; //Interrupt on Descriptor Done
 *	u32	rsvd		:1; //reserved
 *	u32	size		:14;//14 bits used - ignored for BMU transfers,
 *				    //only used for host to host transfers?
 * } ctrl;
 */
struct wcn36xx_dxe_desc {
	u32	ctrl;
	u32	fr_len;

	u32	src_addr_l;
	u32	dst_addr_l;
	u32	phy_next_l;
	u32	src_addr_h;
	u32	dst_addr_h;
	u32	phy_next_h;
} __packed;

/* DXE Control block */
struct wcn36xx_dxe_ctl {
	struct wcn36xx_dxe_ctl	*next;
	struct wcn36xx_dxe_desc	*desc;
	unsigned int		desc_phy_addr;
	int			ctl_blk_order;
	struct sk_buff		*skb;
	void			*bd_cpu_addr;
	dma_addr_t		bd_phy_addr;
};

struct wcn36xx_dxe_ch {
	spinlock_t			lock;	/* protects head/tail ptrs */
	enum wcn36xx_dxe_ch_type	ch_type;
	void				*cpu_addr;
	dma_addr_t			dma_addr;
	enum wcn36xx_dxe_ch_desc_num	desc_num;
	/* DXE control block ring */
	struct wcn36xx_dxe_ctl		*head_blk_ctl;
	struct wcn36xx_dxe_ctl		*tail_blk_ctl;

	/* DXE channel specific configs */
	u32				dxe_wq;
	u32				ctrl_bd;
	u32				ctrl_skb;
	u32				reg_ctrl;
	u32				def_ctrl;
};

/* Memory Pool for BD headers */
struct wcn36xx_dxe_mem_pool {
	int		chunk_size;
	void		*virt_addr;
	dma_addr_t	phy_addr;
};

struct wcn36xx_tx_bd;
struct wcn36xx_vif;
int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn);
void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn);
void wcn36xx_dxe_rx_frame(struct wcn36xx *wcn);
int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn);
void wcn36xx_dxe_free_ctl_blks(struct wcn36xx *wcn);
int wcn36xx_dxe_init(struct wcn36xx *wcn);
void wcn36xx_dxe_deinit(struct wcn36xx *wcn);
int wcn36xx_dxe_init_channels(struct wcn36xx *wcn);
int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
			 struct wcn36xx_vif *vif_priv,
			 struct wcn36xx_tx_bd *bd,
			 struct sk_buff *skb,
			 bool is_low);
int wcn36xx_dxe_tx_flush(struct wcn36xx *wcn);
void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status);
#endif	/* _DXE_H_ */