xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/ath/wcn36xx/dxe.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com>
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission to use, copy, modify, and/or distribute this software for any
5*4882a593Smuzhiyun  * purpose with or without fee is hereby granted, provided that the above
6*4882a593Smuzhiyun  * copyright notice and this permission notice appear in all copies.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*4882a593Smuzhiyun  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*4882a593Smuzhiyun  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11*4882a593Smuzhiyun  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*4882a593Smuzhiyun  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13*4882a593Smuzhiyun  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14*4882a593Smuzhiyun  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #ifndef _DXE_H_
18*4882a593Smuzhiyun #define _DXE_H_
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include "wcn36xx.h"
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun /*
23*4882a593Smuzhiyun TX_LOW	= DMA0
24*4882a593Smuzhiyun TX_HIGH	= DMA4
25*4882a593Smuzhiyun RX_LOW	= DMA1
26*4882a593Smuzhiyun RX_HIGH	= DMA3
27*4882a593Smuzhiyun H2H_TEST_RX_TX = DMA2
28*4882a593Smuzhiyun */
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /* DXE registers */
31*4882a593Smuzhiyun #define WCN36XX_DXE_MEM_REG			0
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define WCN36XX_CCU_DXE_INT_SELECT_RIVA		0x310
34*4882a593Smuzhiyun #define WCN36XX_CCU_DXE_INT_SELECT_PRONTO	0x10dc
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun /* Descriptor valid */
37*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_VLD		BIT(0)
38*4882a593Smuzhiyun /* End of packet */
39*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_EOP		BIT(3)
40*4882a593Smuzhiyun /* BD handling bit */
41*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_BDH		BIT(4)
42*4882a593Smuzhiyun /* Source is a queue */
43*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_SIQ		BIT(5)
44*4882a593Smuzhiyun /* Destination is a queue */
45*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_DIQ		BIT(6)
46*4882a593Smuzhiyun /* Pointer address is a queue */
47*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_PIQ		BIT(7)
48*4882a593Smuzhiyun /* Release PDU when done */
49*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_PDU_REL	BIT(8)
50*4882a593Smuzhiyun /* STOP channel processing */
51*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_STOP		BIT(16)
52*4882a593Smuzhiyun /* INT on descriptor done */
53*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_INT		BIT(17)
54*4882a593Smuzhiyun /* Endian byte swap enable */
55*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_SWAP		BIT(20)
56*4882a593Smuzhiyun /* Master endianness */
57*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_ENDIANNESS	BIT(21)
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /* Transfer type */
60*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_XTYPE_SHIFT 1
61*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_XTYPE_MASK GENMASK(2, WCN36xx_DXE_CTRL_XTYPE_SHIFT)
62*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_XTYPE_SET(x)	((x) << WCN36xx_DXE_CTRL_XTYPE_SHIFT)
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun /* BMU Threshold select */
65*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT 9
66*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_BTHLD_SEL_MASK GENMASK(12, WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT)
67*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_BTHLD_SEL_SET(x) ((x) << WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT)
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun /* Priority */
70*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_PRIO_SHIFT 13
71*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_PRIO_MASK GENMASK(15, WCN36xx_DXE_CTRL_PRIO_SHIFT)
72*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_PRIO_SET(x) ((x) << WCN36xx_DXE_CTRL_PRIO_SHIFT)
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun /* BD Template index */
75*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_BDT_IDX_SHIFT 18
76*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_BDT_IDX_MASK GENMASK(19, WCN36xx_DXE_CTRL_BDT_IDX_SHIFT)
77*4882a593Smuzhiyun #define WCN36xx_DXE_CTRL_BDT_IDX_SET(x) ((x) << WCN36xx_DXE_CTRL_BDT_IDX_SHIFT)
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /* Transfer types: */
80*4882a593Smuzhiyun /* Host to host */
81*4882a593Smuzhiyun #define WCN36xx_DXE_XTYPE_H2H (0)
82*4882a593Smuzhiyun /* Host to BMU */
83*4882a593Smuzhiyun #define WCN36xx_DXE_XTYPE_H2B (2)
84*4882a593Smuzhiyun /* BMU to host */
85*4882a593Smuzhiyun #define WCN36xx_DXE_XTYPE_B2H (3)
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun #define WCN36XX_DXE_CTRL_TX_L	(WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
88*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | \
89*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_PRIO_SET(4) | WCN36xx_DXE_CTRL_INT | \
90*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_SWAP | WCN36xx_DXE_CTRL_ENDIANNESS)
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun #define WCN36XX_DXE_CTRL_TX_H	 (WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
93*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | \
94*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_INT | \
95*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_SWAP | WCN36xx_DXE_CTRL_ENDIANNESS)
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun #define WCN36XX_DXE_CTRL_RX_L	(WCN36xx_DXE_CTRL_VLD | \
98*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
99*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_SIQ | \
100*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_PDU_REL | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(6) | \
101*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_PRIO_SET(5) | WCN36xx_DXE_CTRL_INT | \
102*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_SWAP)
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun #define WCN36XX_DXE_CTRL_RX_H	(WCN36xx_DXE_CTRL_VLD | \
105*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
106*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_SIQ | \
107*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_PDU_REL |  WCN36xx_DXE_CTRL_BTHLD_SEL_SET(8) | \
108*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_INT | \
109*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_SWAP)
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun #define WCN36XX_DXE_CTRL_TX_H_BD	(WCN36xx_DXE_CTRL_VLD | \
112*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
113*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | \
114*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_SWAP | \
115*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_ENDIANNESS)
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun #define WCN36XX_DXE_CTRL_TX_H_SKB	(WCN36xx_DXE_CTRL_VLD | \
118*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
119*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_DIQ | \
120*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | WCN36xx_DXE_CTRL_PRIO_SET(6) | \
121*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_INT | WCN36xx_DXE_CTRL_SWAP | \
122*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_ENDIANNESS)
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun #define WCN36XX_DXE_CTRL_TX_L_BD	 (WCN36xx_DXE_CTRL_VLD | \
125*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
126*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | \
127*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_PRIO_SET(4) | WCN36xx_DXE_CTRL_SWAP | \
128*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_ENDIANNESS)
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun #define WCN36XX_DXE_CTRL_TX_L_SKB	(WCN36xx_DXE_CTRL_VLD | \
131*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
132*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_DIQ | \
133*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | WCN36xx_DXE_CTRL_PRIO_SET(4) | \
134*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_INT | WCN36xx_DXE_CTRL_SWAP | \
135*4882a593Smuzhiyun 	WCN36xx_DXE_CTRL_ENDIANNESS)
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun /* TODO This must calculated properly but not hardcoded */
138*4882a593Smuzhiyun #define WCN36XX_DXE_WQ_TX_L			0x17
139*4882a593Smuzhiyun #define WCN36XX_DXE_WQ_TX_H			0x17
140*4882a593Smuzhiyun #define WCN36XX_DXE_WQ_RX_L			0xB
141*4882a593Smuzhiyun #define WCN36XX_DXE_WQ_RX_H			0x4
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun /* Channel enable or restart */
144*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_EN			BIT(0)
145*4882a593Smuzhiyun /* End of packet bit */
146*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_EOP			BIT(3)
147*4882a593Smuzhiyun /* BD Handling bit */
148*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_BDH			BIT(4)
149*4882a593Smuzhiyun /* Source is queue */
150*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_SIQ			BIT(5)
151*4882a593Smuzhiyun /* Destination is queue */
152*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_DIQ			BIT(6)
153*4882a593Smuzhiyun /* Pointer descriptor is queue */
154*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_PIQ			BIT(7)
155*4882a593Smuzhiyun /* Relase PDU when done */
156*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_PDU_REL		BIT(8)
157*4882a593Smuzhiyun /* Stop channel processing */
158*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_STOP		BIT(16)
159*4882a593Smuzhiyun /* Enable external descriptor interrupt */
160*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_INE_ED		BIT(17)
161*4882a593Smuzhiyun /* Enable channel interrupt on errors */
162*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_INE_ERR		BIT(18)
163*4882a593Smuzhiyun /* Enable Channel interrupt when done */
164*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_INE_DONE	BIT(19)
165*4882a593Smuzhiyun /* External descriptor enable */
166*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_EDEN		BIT(20)
167*4882a593Smuzhiyun /* Wait for valid bit */
168*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_EDVEN		BIT(21)
169*4882a593Smuzhiyun /* Endianness is little endian*/
170*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_ENDIANNESS	BIT(26)
171*4882a593Smuzhiyun /* Abort transfer */
172*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_ABORT		BIT(27)
173*4882a593Smuzhiyun /* Long descriptor format */
174*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_DFMT		BIT(28)
175*4882a593Smuzhiyun /* Endian byte swap enable */
176*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_SWAP		BIT(31)
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun /* Transfer type */
179*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT 1
180*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_XTYPE_MASK GENMASK(2, WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT)
181*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_XTYPE_SET(x)	((x) << WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT)
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun /* Channel BMU Threshold select */
184*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT 9
185*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_MASK GENMASK(12, WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT)
186*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT)
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun /* Channel Priority */
189*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_PRIO_SHIFT 13
190*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_PRIO_MASK GENMASK(15, WCN36xx_DXE_CH_CTRL_PRIO_SHIFT)
191*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_PRIO_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_PRIO_SHIFT)
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun /* Counter select */
194*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_SEL_SHIFT 22
195*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_SEL_MASK GENMASK(25, WCN36xx_DXE_CH_CTRL_SEL_SHIFT)
196*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_SEL_SET(x)	((x) << WCN36xx_DXE_CH_CTRL_SEL_SHIFT)
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun /* Channel BD template index */
199*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT 29
200*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_BDT_IDX_MASK GENMASK(30, WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT)
201*4882a593Smuzhiyun #define WCN36xx_DXE_CH_CTRL_BDT_IDX_SET(x)	((x) << WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT)
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun /* DXE default control register values */
204*4882a593Smuzhiyun #define WCN36XX_DXE_CH_DEFAULT_CTL_RX_L (WCN36xx_DXE_CH_CTRL_EN | \
205*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
206*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_SIQ | \
207*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(6) | \
208*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_PRIO_SET(5) | WCN36xx_DXE_CH_CTRL_INE_ED | \
209*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
210*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
211*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_SEL_SET(1) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
212*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_SWAP)
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun #define WCN36XX_DXE_CH_DEFAULT_CTL_RX_H (WCN36xx_DXE_CH_CTRL_EN | \
215*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
216*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_SIQ | \
217*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(8) | \
218*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_PRIO_SET(6) | WCN36xx_DXE_CH_CTRL_INE_ED | \
219*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
220*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
221*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_SEL_SET(3) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
222*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_SWAP)
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun #define WCN36XX_DXE_CH_DEFAULT_CTL_TX_H	(WCN36xx_DXE_CH_CTRL_EN | \
225*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
226*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_DIQ | \
227*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(7) | \
228*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_PRIO_SET(6) | WCN36xx_DXE_CH_CTRL_INE_ED | \
229*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
230*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
231*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_SEL_SET(4) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
232*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_SWAP)
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun #define WCN36XX_DXE_CH_DEFAULT_CTL_TX_L (WCN36xx_DXE_CH_CTRL_EN | \
235*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
236*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_DIQ | \
237*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(5) | \
238*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_PRIO_SET(4) | WCN36xx_DXE_CH_CTRL_INE_ED | \
239*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
240*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
241*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_SEL_SET(0) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
242*4882a593Smuzhiyun 		WCN36xx_DXE_CH_CTRL_SWAP)
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun /* Common DXE registers */
245*4882a593Smuzhiyun #define WCN36XX_DXE_MEM_CSR			(WCN36XX_DXE_MEM_REG + 0x00)
246*4882a593Smuzhiyun #define WCN36XX_DXE_REG_CSR_RESET		(WCN36XX_DXE_MEM_REG + 0x00)
247*4882a593Smuzhiyun #define WCN36XX_DXE_ENCH_ADDR			(WCN36XX_DXE_MEM_REG + 0x04)
248*4882a593Smuzhiyun #define WCN36XX_DXE_REG_CH_EN			(WCN36XX_DXE_MEM_REG + 0x08)
249*4882a593Smuzhiyun #define WCN36XX_DXE_REG_CH_DONE			(WCN36XX_DXE_MEM_REG + 0x0C)
250*4882a593Smuzhiyun #define WCN36XX_DXE_REG_CH_ERR			(WCN36XX_DXE_MEM_REG + 0x10)
251*4882a593Smuzhiyun #define WCN36XX_DXE_INT_MASK_REG		(WCN36XX_DXE_MEM_REG + 0x18)
252*4882a593Smuzhiyun #define WCN36XX_DXE_INT_SRC_RAW_REG		(WCN36XX_DXE_MEM_REG + 0x20)
253*4882a593Smuzhiyun 	/* #define WCN36XX_DXE_INT_CH6_MASK	0x00000040 */
254*4882a593Smuzhiyun 	/* #define WCN36XX_DXE_INT_CH5_MASK	0x00000020 */
255*4882a593Smuzhiyun 	#define WCN36XX_DXE_INT_CH4_MASK	0x00000010
256*4882a593Smuzhiyun 	#define WCN36XX_DXE_INT_CH3_MASK	0x00000008
257*4882a593Smuzhiyun 	/* #define WCN36XX_DXE_INT_CH2_MASK	0x00000004 */
258*4882a593Smuzhiyun 	#define WCN36XX_DXE_INT_CH1_MASK	0x00000002
259*4882a593Smuzhiyun 	#define WCN36XX_DXE_INT_CH0_MASK	0x00000001
260*4882a593Smuzhiyun #define WCN36XX_DXE_0_INT_CLR			(WCN36XX_DXE_MEM_REG + 0x30)
261*4882a593Smuzhiyun #define WCN36XX_DXE_0_INT_ED_CLR		(WCN36XX_DXE_MEM_REG + 0x34)
262*4882a593Smuzhiyun #define WCN36XX_DXE_0_INT_DONE_CLR		(WCN36XX_DXE_MEM_REG + 0x38)
263*4882a593Smuzhiyun #define WCN36XX_DXE_0_INT_ERR_CLR		(WCN36XX_DXE_MEM_REG + 0x3C)
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun #define WCN36XX_CH_STAT_INT_DONE_MASK   0x00008000
266*4882a593Smuzhiyun #define WCN36XX_CH_STAT_INT_ERR_MASK    0x00004000
267*4882a593Smuzhiyun #define WCN36XX_CH_STAT_INT_ED_MASK     0x00002000
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun #define WCN36XX_DXE_0_CH0_STATUS		(WCN36XX_DXE_MEM_REG + 0x404)
270*4882a593Smuzhiyun #define WCN36XX_DXE_0_CH1_STATUS		(WCN36XX_DXE_MEM_REG + 0x444)
271*4882a593Smuzhiyun #define WCN36XX_DXE_0_CH2_STATUS		(WCN36XX_DXE_MEM_REG + 0x484)
272*4882a593Smuzhiyun #define WCN36XX_DXE_0_CH3_STATUS		(WCN36XX_DXE_MEM_REG + 0x4C4)
273*4882a593Smuzhiyun #define WCN36XX_DXE_0_CH4_STATUS		(WCN36XX_DXE_MEM_REG + 0x504)
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun #define WCN36XX_DXE_REG_RESET			0x5c89
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun /* Temporary BMU Workqueue 4 */
278*4882a593Smuzhiyun #define WCN36XX_DXE_BMU_WQ_RX_LOW		0xB
279*4882a593Smuzhiyun #define WCN36XX_DXE_BMU_WQ_RX_HIGH		0x4
280*4882a593Smuzhiyun /* DMA channel offset */
281*4882a593Smuzhiyun #define WCN36XX_DXE_TX_LOW_OFFSET		0x400
282*4882a593Smuzhiyun #define WCN36XX_DXE_TX_HIGH_OFFSET		0x500
283*4882a593Smuzhiyun #define WCN36XX_DXE_RX_LOW_OFFSET		0x440
284*4882a593Smuzhiyun #define WCN36XX_DXE_RX_HIGH_OFFSET		0x4C0
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun /* Address of the next DXE descriptor */
287*4882a593Smuzhiyun #define WCN36XX_DXE_CH_NEXT_DESC_ADDR		0x001C
288*4882a593Smuzhiyun #define WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_L	(WCN36XX_DXE_MEM_REG + \
289*4882a593Smuzhiyun 						 WCN36XX_DXE_TX_LOW_OFFSET + \
290*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)
291*4882a593Smuzhiyun #define WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_H	(WCN36XX_DXE_MEM_REG + \
292*4882a593Smuzhiyun 						 WCN36XX_DXE_TX_HIGH_OFFSET + \
293*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)
294*4882a593Smuzhiyun #define WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_L	(WCN36XX_DXE_MEM_REG + \
295*4882a593Smuzhiyun 						 WCN36XX_DXE_RX_LOW_OFFSET + \
296*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)
297*4882a593Smuzhiyun #define WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_H	(WCN36XX_DXE_MEM_REG + \
298*4882a593Smuzhiyun 						 WCN36XX_DXE_RX_HIGH_OFFSET + \
299*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun /* DXE Descriptor source address */
302*4882a593Smuzhiyun #define WCN36XX_DXE_CH_SRC_ADDR			0x000C
303*4882a593Smuzhiyun #define WCN36XX_DXE_CH_SRC_ADDR_RX_L		(WCN36XX_DXE_MEM_REG + \
304*4882a593Smuzhiyun 						 WCN36XX_DXE_RX_LOW_OFFSET + \
305*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_SRC_ADDR)
306*4882a593Smuzhiyun #define WCN36XX_DXE_CH_SRC_ADDR_RX_H		(WCN36XX_DXE_MEM_REG + \
307*4882a593Smuzhiyun 						 WCN36XX_DXE_RX_HIGH_OFFSET + \
308*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_SRC_ADDR)
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun /* DXE Descriptor address destination address */
311*4882a593Smuzhiyun #define WCN36XX_DXE_CH_DEST_ADDR		0x0014
312*4882a593Smuzhiyun #define WCN36XX_DXE_CH_DEST_ADDR_TX_L		(WCN36XX_DXE_MEM_REG + \
313*4882a593Smuzhiyun 						 WCN36XX_DXE_TX_LOW_OFFSET + \
314*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_DEST_ADDR)
315*4882a593Smuzhiyun #define WCN36XX_DXE_CH_DEST_ADDR_TX_H		(WCN36XX_DXE_MEM_REG + \
316*4882a593Smuzhiyun 						 WCN36XX_DXE_TX_HIGH_OFFSET + \
317*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_DEST_ADDR)
318*4882a593Smuzhiyun #define WCN36XX_DXE_CH_DEST_ADDR_RX_L		(WCN36XX_DXE_MEM_REG + \
319*4882a593Smuzhiyun 						 WCN36XX_DXE_RX_LOW_OFFSET + \
320*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_DEST_ADDR)
321*4882a593Smuzhiyun #define WCN36XX_DXE_CH_DEST_ADDR_RX_H		(WCN36XX_DXE_MEM_REG + \
322*4882a593Smuzhiyun 						 WCN36XX_DXE_RX_HIGH_OFFSET + \
323*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_DEST_ADDR)
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun /* Interrupt status */
326*4882a593Smuzhiyun #define WCN36XX_DXE_CH_STATUS_REG_ADDR		0x0004
327*4882a593Smuzhiyun #define WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L	(WCN36XX_DXE_MEM_REG + \
328*4882a593Smuzhiyun 						 WCN36XX_DXE_TX_LOW_OFFSET + \
329*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_STATUS_REG_ADDR)
330*4882a593Smuzhiyun #define WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H	(WCN36XX_DXE_MEM_REG + \
331*4882a593Smuzhiyun 						 WCN36XX_DXE_TX_HIGH_OFFSET + \
332*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_STATUS_REG_ADDR)
333*4882a593Smuzhiyun #define WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_L	(WCN36XX_DXE_MEM_REG + \
334*4882a593Smuzhiyun 						 WCN36XX_DXE_RX_LOW_OFFSET + \
335*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_STATUS_REG_ADDR)
336*4882a593Smuzhiyun #define WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_H	(WCN36XX_DXE_MEM_REG + \
337*4882a593Smuzhiyun 						 WCN36XX_DXE_RX_HIGH_OFFSET + \
338*4882a593Smuzhiyun 						 WCN36XX_DXE_CH_STATUS_REG_ADDR)
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun /* DXE default control register */
342*4882a593Smuzhiyun #define WCN36XX_DXE_REG_CTL_RX_L		(WCN36XX_DXE_MEM_REG + \
343*4882a593Smuzhiyun 						 WCN36XX_DXE_RX_LOW_OFFSET)
344*4882a593Smuzhiyun #define WCN36XX_DXE_REG_CTL_RX_H		(WCN36XX_DXE_MEM_REG + \
345*4882a593Smuzhiyun 						 WCN36XX_DXE_RX_HIGH_OFFSET)
346*4882a593Smuzhiyun #define WCN36XX_DXE_REG_CTL_TX_H		(WCN36XX_DXE_MEM_REG + \
347*4882a593Smuzhiyun 						 WCN36XX_DXE_TX_HIGH_OFFSET)
348*4882a593Smuzhiyun #define WCN36XX_DXE_REG_CTL_TX_L		(WCN36XX_DXE_MEM_REG + \
349*4882a593Smuzhiyun 						 WCN36XX_DXE_TX_LOW_OFFSET)
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun #define WCN36XX_SMSM_WLAN_TX_ENABLE		0x00000400
352*4882a593Smuzhiyun #define WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY	0x00000200
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun /* Interrupt control channel mask */
356*4882a593Smuzhiyun #define WCN36XX_INT_MASK_CHAN_TX_L		0x00000001
357*4882a593Smuzhiyun #define WCN36XX_INT_MASK_CHAN_RX_L		0x00000002
358*4882a593Smuzhiyun #define WCN36XX_INT_MASK_CHAN_RX_H		0x00000008
359*4882a593Smuzhiyun #define WCN36XX_INT_MASK_CHAN_TX_H		0x00000010
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun #define WCN36XX_BD_CHUNK_SIZE			128
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun #define WCN36XX_PKT_SIZE			0xF20
364*4882a593Smuzhiyun enum wcn36xx_dxe_ch_type {
365*4882a593Smuzhiyun 	WCN36XX_DXE_CH_TX_L,
366*4882a593Smuzhiyun 	WCN36XX_DXE_CH_TX_H,
367*4882a593Smuzhiyun 	WCN36XX_DXE_CH_RX_L,
368*4882a593Smuzhiyun 	WCN36XX_DXE_CH_RX_H
369*4882a593Smuzhiyun };
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun /* amount of descriptors per channel */
372*4882a593Smuzhiyun enum wcn36xx_dxe_ch_desc_num {
373*4882a593Smuzhiyun 	WCN36XX_DXE_CH_DESC_NUMB_TX_L		= 128,
374*4882a593Smuzhiyun 	WCN36XX_DXE_CH_DESC_NUMB_TX_H		= 10,
375*4882a593Smuzhiyun 	WCN36XX_DXE_CH_DESC_NUMB_RX_L		= 512,
376*4882a593Smuzhiyun 	WCN36XX_DXE_CH_DESC_NUMB_RX_H		= 40
377*4882a593Smuzhiyun };
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun /**
380*4882a593Smuzhiyun  * struct wcn36xx_dxe_desc - describes descriptor of one DXE buffer
381*4882a593Smuzhiyun  *
382*4882a593Smuzhiyun  * @ctrl: is a union that consists of following bits:
383*4882a593Smuzhiyun  * union {
384*4882a593Smuzhiyun  *	u32	valid		:1; //0 = DMA stop, 1 = DMA continue with this
385*4882a593Smuzhiyun  *				    //descriptor
386*4882a593Smuzhiyun  *	u32	transfer_type	:2; //0 = Host to Host space
387*4882a593Smuzhiyun  *	u32	eop		:1; //End of Packet
388*4882a593Smuzhiyun  *	u32	bd_handling	:1; //if transferType = Host to BMU, then 0
389*4882a593Smuzhiyun  *				    // means first 128 bytes contain BD, and 1
390*4882a593Smuzhiyun  *				    // means create new empty BD
391*4882a593Smuzhiyun  *	u32	siq		:1; // SIQ
392*4882a593Smuzhiyun  *	u32	diq		:1; // DIQ
393*4882a593Smuzhiyun  *	u32	pdu_rel		:1; //0 = don't release BD and PDUs when done,
394*4882a593Smuzhiyun  *				    // 1 = release them
395*4882a593Smuzhiyun  *	u32	bthld_sel	:4; //BMU Threshold Select
396*4882a593Smuzhiyun  *	u32	prio		:3; //Specifies the priority level to use for
397*4882a593Smuzhiyun  *				    // the transfer
398*4882a593Smuzhiyun  *	u32	stop_channel	:1; //1 = DMA stops processing further, channel
399*4882a593Smuzhiyun  *				    //requires re-enabling after this
400*4882a593Smuzhiyun  *	u32	intr		:1; //Interrupt on Descriptor Done
401*4882a593Smuzhiyun  *	u32	rsvd		:1; //reserved
402*4882a593Smuzhiyun  *	u32	size		:14;//14 bits used - ignored for BMU transfers,
403*4882a593Smuzhiyun  *				    //only used for host to host transfers?
404*4882a593Smuzhiyun  * } ctrl;
405*4882a593Smuzhiyun  */
406*4882a593Smuzhiyun struct wcn36xx_dxe_desc {
407*4882a593Smuzhiyun 	u32	ctrl;
408*4882a593Smuzhiyun 	u32	fr_len;
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	u32	src_addr_l;
411*4882a593Smuzhiyun 	u32	dst_addr_l;
412*4882a593Smuzhiyun 	u32	phy_next_l;
413*4882a593Smuzhiyun 	u32	src_addr_h;
414*4882a593Smuzhiyun 	u32	dst_addr_h;
415*4882a593Smuzhiyun 	u32	phy_next_h;
416*4882a593Smuzhiyun } __packed;
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun /* DXE Control block */
419*4882a593Smuzhiyun struct wcn36xx_dxe_ctl {
420*4882a593Smuzhiyun 	struct wcn36xx_dxe_ctl	*next;
421*4882a593Smuzhiyun 	struct wcn36xx_dxe_desc	*desc;
422*4882a593Smuzhiyun 	unsigned int		desc_phy_addr;
423*4882a593Smuzhiyun 	int			ctl_blk_order;
424*4882a593Smuzhiyun 	struct sk_buff		*skb;
425*4882a593Smuzhiyun 	void			*bd_cpu_addr;
426*4882a593Smuzhiyun 	dma_addr_t		bd_phy_addr;
427*4882a593Smuzhiyun };
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun struct wcn36xx_dxe_ch {
430*4882a593Smuzhiyun 	spinlock_t			lock;	/* protects head/tail ptrs */
431*4882a593Smuzhiyun 	enum wcn36xx_dxe_ch_type	ch_type;
432*4882a593Smuzhiyun 	void				*cpu_addr;
433*4882a593Smuzhiyun 	dma_addr_t			dma_addr;
434*4882a593Smuzhiyun 	enum wcn36xx_dxe_ch_desc_num	desc_num;
435*4882a593Smuzhiyun 	/* DXE control block ring */
436*4882a593Smuzhiyun 	struct wcn36xx_dxe_ctl		*head_blk_ctl;
437*4882a593Smuzhiyun 	struct wcn36xx_dxe_ctl		*tail_blk_ctl;
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	/* DXE channel specific configs */
440*4882a593Smuzhiyun 	u32				dxe_wq;
441*4882a593Smuzhiyun 	u32				ctrl_bd;
442*4882a593Smuzhiyun 	u32				ctrl_skb;
443*4882a593Smuzhiyun 	u32				reg_ctrl;
444*4882a593Smuzhiyun 	u32				def_ctrl;
445*4882a593Smuzhiyun };
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun /* Memory Pool for BD headers */
448*4882a593Smuzhiyun struct wcn36xx_dxe_mem_pool {
449*4882a593Smuzhiyun 	int		chunk_size;
450*4882a593Smuzhiyun 	void		*virt_addr;
451*4882a593Smuzhiyun 	dma_addr_t	phy_addr;
452*4882a593Smuzhiyun };
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun struct wcn36xx_tx_bd;
455*4882a593Smuzhiyun struct wcn36xx_vif;
456*4882a593Smuzhiyun int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn);
457*4882a593Smuzhiyun void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn);
458*4882a593Smuzhiyun void wcn36xx_dxe_rx_frame(struct wcn36xx *wcn);
459*4882a593Smuzhiyun int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn);
460*4882a593Smuzhiyun void wcn36xx_dxe_free_ctl_blks(struct wcn36xx *wcn);
461*4882a593Smuzhiyun int wcn36xx_dxe_init(struct wcn36xx *wcn);
462*4882a593Smuzhiyun void wcn36xx_dxe_deinit(struct wcn36xx *wcn);
463*4882a593Smuzhiyun int wcn36xx_dxe_init_channels(struct wcn36xx *wcn);
464*4882a593Smuzhiyun int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
465*4882a593Smuzhiyun 			 struct wcn36xx_vif *vif_priv,
466*4882a593Smuzhiyun 			 struct wcn36xx_tx_bd *bd,
467*4882a593Smuzhiyun 			 struct sk_buff *skb,
468*4882a593Smuzhiyun 			 bool is_low);
469*4882a593Smuzhiyun void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status);
470*4882a593Smuzhiyun #endif	/* _DXE_H_ */
471