1/*
2 * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _DXE_H_
18#define _DXE_H_
19
20#include "wcn36xx.h"
21
22/*
23TX_LOW	= DMA0
24TX_HIGH	= DMA4
25RX_LOW	= DMA1
26RX_HIGH	= DMA3
27H2H_TEST_RX_TX = DMA2
28*/
29
30/* DXE registers */
31#define WCN36XX_DXE_MEM_REG			0x202000
32
33#define WCN36XX_DXE_CCU_INT			0xA0011
34#define WCN36XX_DXE_REG_CCU_INT_3660		0x200b10
35#define WCN36XX_DXE_REG_CCU_INT_3680		0x2050dc
36
37/* TODO This must calculated properly but not hardcoded */
38#define WCN36XX_DXE_CTRL_TX_L			0x328a44
39#define WCN36XX_DXE_CTRL_TX_H			0x32ce44
40#define WCN36XX_DXE_CTRL_RX_L			0x12ad2f
41#define WCN36XX_DXE_CTRL_RX_H			0x12d12f
42#define WCN36XX_DXE_CTRL_TX_H_BD		0x30ce45
43#define WCN36XX_DXE_CTRL_TX_H_SKB		0x32ce4d
44#define WCN36XX_DXE_CTRL_TX_L_BD		0x308a45
45#define WCN36XX_DXE_CTRL_TX_L_SKB		0x328a4d
46
47/* TODO This must calculated properly but not hardcoded */
48#define WCN36XX_DXE_WQ_TX_L			0x17
49#define WCN36XX_DXE_WQ_TX_H			0x17
50#define WCN36XX_DXE_WQ_RX_L			0xB
51#define WCN36XX_DXE_WQ_RX_H			0x4
52
53/* DXE descriptor control filed */
54#define WCN36XX_DXE_CTRL_VALID_MASK (0x00000001)
55
56/* TODO This must calculated properly but not hardcoded */
57/* DXE default control register values */
58#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_L		0x847EAD2F
59#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_H		0x84FED12F
60#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_H		0x853ECF4D
61#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_L		0x843e8b4d
62
63/* Common DXE registers */
64#define WCN36XX_DXE_MEM_CSR			(WCN36XX_DXE_MEM_REG + 0x00)
65#define WCN36XX_DXE_REG_CSR_RESET		(WCN36XX_DXE_MEM_REG + 0x00)
66#define WCN36XX_DXE_ENCH_ADDR			(WCN36XX_DXE_MEM_REG + 0x04)
67#define WCN36XX_DXE_REG_CH_EN			(WCN36XX_DXE_MEM_REG + 0x08)
68#define WCN36XX_DXE_REG_CH_DONE			(WCN36XX_DXE_MEM_REG + 0x0C)
69#define WCN36XX_DXE_REG_CH_ERR			(WCN36XX_DXE_MEM_REG + 0x10)
70#define WCN36XX_DXE_INT_MASK_REG		(WCN36XX_DXE_MEM_REG + 0x18)
71#define WCN36XX_DXE_INT_SRC_RAW_REG		(WCN36XX_DXE_MEM_REG + 0x20)
72	/* #define WCN36XX_DXE_INT_CH6_MASK	0x00000040 */
73	/* #define WCN36XX_DXE_INT_CH5_MASK	0x00000020 */
74	#define WCN36XX_DXE_INT_CH4_MASK	0x00000010
75	#define WCN36XX_DXE_INT_CH3_MASK	0x00000008
76	/* #define WCN36XX_DXE_INT_CH2_MASK	0x00000004 */
77	#define WCN36XX_DXE_INT_CH1_MASK	0x00000002
78	#define WCN36XX_DXE_INT_CH0_MASK	0x00000001
79#define WCN36XX_DXE_0_INT_CLR			(WCN36XX_DXE_MEM_REG + 0x30)
80#define WCN36XX_DXE_0_INT_ED_CLR		(WCN36XX_DXE_MEM_REG + 0x34)
81#define WCN36XX_DXE_0_INT_DONE_CLR		(WCN36XX_DXE_MEM_REG + 0x38)
82#define WCN36XX_DXE_0_INT_ERR_CLR		(WCN36XX_DXE_MEM_REG + 0x3C)
83
84#define WCN36XX_DXE_0_CH0_STATUS		(WCN36XX_DXE_MEM_REG + 0x404)
85#define WCN36XX_DXE_0_CH1_STATUS		(WCN36XX_DXE_MEM_REG + 0x444)
86#define WCN36XX_DXE_0_CH2_STATUS		(WCN36XX_DXE_MEM_REG + 0x484)
87#define WCN36XX_DXE_0_CH3_STATUS		(WCN36XX_DXE_MEM_REG + 0x4C4)
88#define WCN36XX_DXE_0_CH4_STATUS		(WCN36XX_DXE_MEM_REG + 0x504)
89
90#define WCN36XX_DXE_REG_RESET			0x5c89
91
92/* Temporary BMU Workqueue 4 */
93#define WCN36XX_DXE_BMU_WQ_RX_LOW		0xB
94#define WCN36XX_DXE_BMU_WQ_RX_HIGH		0x4
95/* DMA channel offset */
96#define WCN36XX_DXE_TX_LOW_OFFSET		0x400
97#define WCN36XX_DXE_TX_HIGH_OFFSET		0x500
98#define WCN36XX_DXE_RX_LOW_OFFSET		0x440
99#define WCN36XX_DXE_RX_HIGH_OFFSET		0x4C0
100
101/* Address of the next DXE descriptor */
102#define WCN36XX_DXE_CH_NEXT_DESC_ADDR		0x001C
103#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_L	(WCN36XX_DXE_MEM_REG + \
104						 WCN36XX_DXE_TX_LOW_OFFSET + \
105						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)
106#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_H	(WCN36XX_DXE_MEM_REG + \
107						 WCN36XX_DXE_TX_HIGH_OFFSET + \
108						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)
109#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_L	(WCN36XX_DXE_MEM_REG + \
110						 WCN36XX_DXE_RX_LOW_OFFSET + \
111						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)
112#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_H	(WCN36XX_DXE_MEM_REG + \
113						 WCN36XX_DXE_RX_HIGH_OFFSET + \
114						 WCN36XX_DXE_CH_NEXT_DESC_ADDR)
115
116/* DXE Descriptor source address */
117#define WCN36XX_DXE_CH_SRC_ADDR			0x000C
118#define WCN36XX_DXE_CH_SRC_ADDR_RX_L		(WCN36XX_DXE_MEM_REG + \
119						 WCN36XX_DXE_RX_LOW_OFFSET + \
120						 WCN36XX_DXE_CH_SRC_ADDR)
121#define WCN36XX_DXE_CH_SRC_ADDR_RX_H		(WCN36XX_DXE_MEM_REG + \
122						 WCN36XX_DXE_RX_HIGH_OFFSET + \
123						 WCN36XX_DXE_CH_SRC_ADDR)
124
125/* DXE Descriptor address destination address */
126#define WCN36XX_DXE_CH_DEST_ADDR		0x0014
127#define WCN36XX_DXE_CH_DEST_ADDR_TX_L		(WCN36XX_DXE_MEM_REG + \
128						 WCN36XX_DXE_TX_LOW_OFFSET + \
129						 WCN36XX_DXE_CH_DEST_ADDR)
130#define WCN36XX_DXE_CH_DEST_ADDR_TX_H		(WCN36XX_DXE_MEM_REG + \
131						 WCN36XX_DXE_TX_HIGH_OFFSET + \
132						 WCN36XX_DXE_CH_DEST_ADDR)
133#define WCN36XX_DXE_CH_DEST_ADDR_RX_L		(WCN36XX_DXE_MEM_REG + \
134						 WCN36XX_DXE_RX_LOW_OFFSET + \
135						 WCN36XX_DXE_CH_DEST_ADDR)
136#define WCN36XX_DXE_CH_DEST_ADDR_RX_H		(WCN36XX_DXE_MEM_REG + \
137						 WCN36XX_DXE_RX_HIGH_OFFSET + \
138						 WCN36XX_DXE_CH_DEST_ADDR)
139
140/* Interrupt status */
141#define WCN36XX_DXE_CH_STATUS_REG_ADDR		0x0004
142#define WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L	(WCN36XX_DXE_MEM_REG + \
143						 WCN36XX_DXE_TX_LOW_OFFSET + \
144						 WCN36XX_DXE_CH_STATUS_REG_ADDR)
145#define WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H	(WCN36XX_DXE_MEM_REG + \
146						 WCN36XX_DXE_TX_HIGH_OFFSET + \
147						 WCN36XX_DXE_CH_STATUS_REG_ADDR)
148#define WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_L	(WCN36XX_DXE_MEM_REG + \
149						 WCN36XX_DXE_RX_LOW_OFFSET + \
150						 WCN36XX_DXE_CH_STATUS_REG_ADDR)
151#define WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_H	(WCN36XX_DXE_MEM_REG + \
152						 WCN36XX_DXE_RX_HIGH_OFFSET + \
153						 WCN36XX_DXE_CH_STATUS_REG_ADDR)
154
155
156/* DXE default control register */
157#define WCN36XX_DXE_REG_CTL_RX_L		(WCN36XX_DXE_MEM_REG + \
158						 WCN36XX_DXE_RX_LOW_OFFSET)
159#define WCN36XX_DXE_REG_CTL_RX_H		(WCN36XX_DXE_MEM_REG + \
160						 WCN36XX_DXE_RX_HIGH_OFFSET)
161#define WCN36XX_DXE_REG_CTL_TX_H		(WCN36XX_DXE_MEM_REG + \
162						 WCN36XX_DXE_TX_HIGH_OFFSET)
163#define WCN36XX_DXE_REG_CTL_TX_L		(WCN36XX_DXE_MEM_REG + \
164						 WCN36XX_DXE_TX_LOW_OFFSET)
165
166#define WCN36XX_SMSM_WLAN_TX_ENABLE		0x00000400
167#define WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY	0x00000200
168
169
170/* Interrupt control channel mask */
171#define WCN36XX_INT_MASK_CHAN_TX_L		0x00000001
172#define WCN36XX_INT_MASK_CHAN_RX_L		0x00000002
173#define WCN36XX_INT_MASK_CHAN_RX_H		0x00000008
174#define WCN36XX_INT_MASK_CHAN_TX_H		0x00000010
175
176#define WCN36XX_BD_CHUNK_SIZE			128
177
178#define WCN36XX_PKT_SIZE			0xF20
179enum wcn36xx_dxe_ch_type {
180	WCN36XX_DXE_CH_TX_L,
181	WCN36XX_DXE_CH_TX_H,
182	WCN36XX_DXE_CH_RX_L,
183	WCN36XX_DXE_CH_RX_H
184};
185
186/* amount of descriptors per channel */
187enum wcn36xx_dxe_ch_desc_num {
188	WCN36XX_DXE_CH_DESC_NUMB_TX_L		= 128,
189	WCN36XX_DXE_CH_DESC_NUMB_TX_H		= 10,
190	WCN36XX_DXE_CH_DESC_NUMB_RX_L		= 512,
191	WCN36XX_DXE_CH_DESC_NUMB_RX_H		= 40
192};
193
194/**
195 * struct wcn36xx_dxe_desc - describes descriptor of one DXE buffer
196 *
197 * @ctrl: is a union that consists of following bits:
198 * union {
199 *	u32	valid		:1; //0 = DMA stop, 1 = DMA continue with this
200 *				    //descriptor
201 *	u32	transfer_type	:2; //0 = Host to Host space
202 *	u32	eop		:1; //End of Packet
203 *	u32	bd_handling	:1; //if transferType = Host to BMU, then 0
204 *				    // means first 128 bytes contain BD, and 1
205 *				    // means create new empty BD
206 *	u32	siq		:1; // SIQ
207 *	u32	diq		:1; // DIQ
208 *	u32	pdu_rel		:1; //0 = don't release BD and PDUs when done,
209 *				    // 1 = release them
210 *	u32	bthld_sel	:4; //BMU Threshold Select
211 *	u32	prio		:3; //Specifies the priority level to use for
212 *				    // the transfer
213 *	u32	stop_channel	:1; //1 = DMA stops processing further, channel
214 *				    //requires re-enabling after this
215 *	u32	intr		:1; //Interrupt on Descriptor Done
216 *	u32	rsvd		:1; //reserved
217 *	u32	size		:14;//14 bits used - ignored for BMU transfers,
218 *				    //only used for host to host transfers?
219 * } ctrl;
220 */
221struct wcn36xx_dxe_desc {
222	u32	ctrl;
223	u32	fr_len;
224
225	u32	src_addr_l;
226	u32	dst_addr_l;
227	u32	phy_next_l;
228	u32	src_addr_h;
229	u32	dst_addr_h;
230	u32	phy_next_h;
231} __packed;
232
233/* DXE Control block */
234struct wcn36xx_dxe_ctl {
235	struct wcn36xx_dxe_ctl	*next;
236	struct wcn36xx_dxe_desc	*desc;
237	unsigned int		desc_phy_addr;
238	int			ctl_blk_order;
239	struct sk_buff		*skb;
240	spinlock_t              skb_lock;
241	void			*bd_cpu_addr;
242	dma_addr_t		bd_phy_addr;
243};
244
245struct wcn36xx_dxe_ch {
246	enum wcn36xx_dxe_ch_type	ch_type;
247	void				*cpu_addr;
248	dma_addr_t			dma_addr;
249	enum wcn36xx_dxe_ch_desc_num	desc_num;
250	/* DXE control block ring */
251	struct wcn36xx_dxe_ctl		*head_blk_ctl;
252	struct wcn36xx_dxe_ctl		*tail_blk_ctl;
253
254	/* DXE channel specific configs */
255	u32				dxe_wq;
256	u32				ctrl_bd;
257	u32				ctrl_skb;
258	u32				reg_ctrl;
259	u32				def_ctrl;
260};
261
262/* Memory Pool for BD headers */
263struct wcn36xx_dxe_mem_pool {
264	int		chunk_size;
265	void		*virt_addr;
266	dma_addr_t	phy_addr;
267};
268
269struct wcn36xx_vif;
270int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn);
271void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn);
272void wcn36xx_dxe_rx_frame(struct wcn36xx *wcn);
273int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn);
274void wcn36xx_dxe_free_ctl_blks(struct wcn36xx *wcn);
275int wcn36xx_dxe_init(struct wcn36xx *wcn);
276void wcn36xx_dxe_deinit(struct wcn36xx *wcn);
277int wcn36xx_dxe_init_channels(struct wcn36xx *wcn);
278int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
279			 struct wcn36xx_vif *vif_priv,
280			 struct sk_buff *skb,
281			 bool is_low);
282void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status);
283void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low);
284#endif	/* _DXE_H_ */
285