xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/nxp/mlan/mlan_sdio.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /** @file mlan_sdio.h
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * @brief This file contains definitions for SDIO interface.
4*4882a593Smuzhiyun  * driver.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  *  Copyright 2008-2021 NXP
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  *  This software file (the File) is distributed by NXP
10*4882a593Smuzhiyun  *  under the terms of the GNU General Public License Version 2, June 1991
11*4882a593Smuzhiyun  *  (the License).  You may use, redistribute and/or modify the File in
12*4882a593Smuzhiyun  *  accordance with the terms and conditions of the License, a copy of which
13*4882a593Smuzhiyun  *  is available by writing to the Free Software Foundation, Inc.,
14*4882a593Smuzhiyun  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
15*4882a593Smuzhiyun  *  worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  *  THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
18*4882a593Smuzhiyun  *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
19*4882a593Smuzhiyun  *  ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
20*4882a593Smuzhiyun  *  this warranty disclaimer.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  */
23*4882a593Smuzhiyun /****************************************************
24*4882a593Smuzhiyun Change log:
25*4882a593Smuzhiyun ****************************************************/
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #ifndef _MLAN_SDIO_H
28*4882a593Smuzhiyun #define _MLAN_SDIO_H
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /** Block mode */
31*4882a593Smuzhiyun #ifndef BLOCK_MODE
32*4882a593Smuzhiyun #define BLOCK_MODE 1
33*4882a593Smuzhiyun #endif
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun /** Fixed address mode */
36*4882a593Smuzhiyun #ifndef FIXED_ADDRESS
37*4882a593Smuzhiyun #define FIXED_ADDRESS 0
38*4882a593Smuzhiyun #endif
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /* Host Control Registers */
41*4882a593Smuzhiyun /** Host Control Registers : Host to Card Event */
42*4882a593Smuzhiyun #define HOST_TO_CARD_EVENT_REG 0x00
43*4882a593Smuzhiyun /** Host Control Registers : Host terminates Command 53 */
44*4882a593Smuzhiyun #define HOST_TERM_CMD53 (0x1U << 2)
45*4882a593Smuzhiyun /** Host Control Registers : Host without Command 53 finish host */
46*4882a593Smuzhiyun #define HOST_WO_CMD53_FINISH_HOST (0x1U << 2)
47*4882a593Smuzhiyun /** Host Control Registers : Host power up */
48*4882a593Smuzhiyun #define HOST_POWER_UP (0x1U << 1)
49*4882a593Smuzhiyun /** Host Control Registers : Host power down */
50*4882a593Smuzhiyun #define HOST_POWER_DOWN (0x1U << 0)
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun /** Host Control Registers : Upload host interrupt RSR */
53*4882a593Smuzhiyun #define UP_LD_HOST_INT_RSR (0x1U)
54*4882a593Smuzhiyun #define HOST_INT_RSR_MASK 0xFF
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun /** Host Control Registers : Upload command port host interrupt status */
57*4882a593Smuzhiyun #define UP_LD_CMD_PORT_HOST_INT_STATUS (0x40U)
58*4882a593Smuzhiyun /** Host Control Registers : Download command port host interrupt status */
59*4882a593Smuzhiyun #define DN_LD_CMD_PORT_HOST_INT_STATUS (0x80U)
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /** Host Control Registers : Upload host interrupt mask */
62*4882a593Smuzhiyun #define UP_LD_HOST_INT_MASK (0x1U)
63*4882a593Smuzhiyun /** Host Control Registers : Download host interrupt mask */
64*4882a593Smuzhiyun #define DN_LD_HOST_INT_MASK (0x2U)
65*4882a593Smuzhiyun /** Host Control Registers : Cmd port upload interrupt mask */
66*4882a593Smuzhiyun #define CMD_PORT_UPLD_INT_MASK (0x1U << 6)
67*4882a593Smuzhiyun /** Host Control Registers : Cmd port download interrupt mask */
68*4882a593Smuzhiyun #define CMD_PORT_DNLD_INT_MASK (0x1U << 7)
69*4882a593Smuzhiyun /** Enable Host interrupt mask */
70*4882a593Smuzhiyun #define HIM_ENABLE                                                             \
71*4882a593Smuzhiyun 	(UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK | CMD_PORT_UPLD_INT_MASK |  \
72*4882a593Smuzhiyun 	 CMD_PORT_DNLD_INT_MASK)
73*4882a593Smuzhiyun /** Disable Host interrupt mask */
74*4882a593Smuzhiyun #define HIM_DISABLE 0xff
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun /** Host Control Registers : Upload host interrupt status */
77*4882a593Smuzhiyun #define UP_LD_HOST_INT_STATUS (0x1U)
78*4882a593Smuzhiyun /** Host Control Registers : Download host interrupt status */
79*4882a593Smuzhiyun #define DN_LD_HOST_INT_STATUS (0x2U)
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun /** Host Control Registers : Download CRC error */
82*4882a593Smuzhiyun #define DN_LD_CRC_ERR (0x1U << 2)
83*4882a593Smuzhiyun /** Host Control Registers : Upload restart */
84*4882a593Smuzhiyun #define UP_LD_RESTART (0x1U << 1)
85*4882a593Smuzhiyun /** Host Control Registers : Download restart */
86*4882a593Smuzhiyun #define DN_LD_RESTART (0x1U << 0)
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /** Card Control Registers : Command port upload ready */
89*4882a593Smuzhiyun #define UP_LD_CP_RDY (0x1U << 6)
90*4882a593Smuzhiyun /** Card Control Registers : Command port download ready */
91*4882a593Smuzhiyun #define DN_LD_CP_RDY (0x1U << 7)
92*4882a593Smuzhiyun /** Card Control Registers : Card I/O ready */
93*4882a593Smuzhiyun #define CARD_IO_READY (0x1U << 3)
94*4882a593Smuzhiyun /** Card Control Registers : CIS card ready */
95*4882a593Smuzhiyun #define CIS_CARD_RDY (0x1U << 2)
96*4882a593Smuzhiyun /** Card Control Registers : Upload card ready */
97*4882a593Smuzhiyun #define UP_LD_CARD_RDY (0x1U << 1)
98*4882a593Smuzhiyun /** Card Control Registers : Download card ready */
99*4882a593Smuzhiyun #define DN_LD_CARD_RDY (0x1U << 0)
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun /** Card Control Registers : Host power interrupt mask */
102*4882a593Smuzhiyun #define HOST_POWER_INT_MASK (0x1U << 3)
103*4882a593Smuzhiyun /** Card Control Registers : Abort card interrupt mask */
104*4882a593Smuzhiyun #define ABORT_CARD_INT_MASK (0x1U << 2)
105*4882a593Smuzhiyun /** Card Control Registers : Upload card interrupt mask */
106*4882a593Smuzhiyun #define UP_LD_CARD_INT_MASK (0x1U << 1)
107*4882a593Smuzhiyun /** Card Control Registers : Download card interrupt mask */
108*4882a593Smuzhiyun #define DN_LD_CARD_INT_MASK (0x1U << 0)
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun /** Card Control Registers : Power up interrupt */
111*4882a593Smuzhiyun #define POWER_UP_INT (0x1U << 4)
112*4882a593Smuzhiyun /** Card Control Registers : Power down interrupt */
113*4882a593Smuzhiyun #define POWER_DOWN_INT (0x1U << 3)
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun /** Card Control Registers : Power up RSR */
116*4882a593Smuzhiyun #define POWER_UP_RSR (0x1U << 4)
117*4882a593Smuzhiyun /** Card Control Registers : Power down RSR */
118*4882a593Smuzhiyun #define POWER_DOWN_RSR (0x1U << 3)
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun /** Card Control Registers : SD test BUS 0 */
121*4882a593Smuzhiyun #define SD_TESTBUS0 (0x1U)
122*4882a593Smuzhiyun /** Card Control Registers : SD test BUS 1 */
123*4882a593Smuzhiyun #define SD_TESTBUS1 (0x1U)
124*4882a593Smuzhiyun /** Card Control Registers : SD test BUS 2 */
125*4882a593Smuzhiyun #define SD_TESTBUS2 (0x1U)
126*4882a593Smuzhiyun /** Card Control Registers : SD test BUS 3 */
127*4882a593Smuzhiyun #define SD_TESTBUS3 (0x1U)
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun /** Port for registers */
130*4882a593Smuzhiyun #define REG_PORT 0
131*4882a593Smuzhiyun /** Port for memory */
132*4882a593Smuzhiyun #define MEM_PORT 0x10000
133*4882a593Smuzhiyun /** Ctrl port */
134*4882a593Smuzhiyun #define CTRL_PORT 0
135*4882a593Smuzhiyun /** Ctrl port mask */
136*4882a593Smuzhiyun #define CTRL_PORT_MASK 0x0001
137*4882a593Smuzhiyun /** Card Control Registers : cmd53 new mode */
138*4882a593Smuzhiyun #define CMD53_NEW_MODE (0x1U << 0)
139*4882a593Smuzhiyun /** Card Control Registers : cmd53 tx len format 1 (0x10) */
140*4882a593Smuzhiyun #define CMD53_TX_LEN_FORMAT_1 (0x1U << 4)
141*4882a593Smuzhiyun /** Card Control Registers : cmd53 tx len format 2 (0x20)*/
142*4882a593Smuzhiyun #define CMD53_TX_LEN_FORMAT_2 (0x1U << 5)
143*4882a593Smuzhiyun /** Card Control Registers : cmd53 rx len format 1 (0x40) */
144*4882a593Smuzhiyun #define CMD53_RX_LEN_FORMAT_1 (0x1U << 6)
145*4882a593Smuzhiyun /** Card Control Registers : cmd53 rx len format 2 (0x80)*/
146*4882a593Smuzhiyun #define CMD53_RX_LEN_FORMAT_2 (0x1U << 7)
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun #define CMD_PORT_RD_LEN_EN (0x1U << 2)
149*4882a593Smuzhiyun /* Card Control Registers : cmd port auto enable */
150*4882a593Smuzhiyun #define CMD_PORT_AUTO_EN (0x1U << 0)
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun /* Command port */
153*4882a593Smuzhiyun #define CMD_PORT_SLCT 0x8000
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun /** Misc. Config Register : Auto Re-enable interrupts */
156*4882a593Smuzhiyun #define AUTO_RE_ENABLE_INT MBIT(4)
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun /** Enable GPIO-1 as a duplicated signal of interrupt as appear of SDIO_DAT1*/
159*4882a593Smuzhiyun #define ENABLE_GPIO_1_INT_MODE 0x88
160*4882a593Smuzhiyun /** Scratch reg 3 2  :     Configure GPIO-1 INT*/
161*4882a593Smuzhiyun #define SCRATCH_REG_32 0xEE
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun /** Event header Len*/
164*4882a593Smuzhiyun #define MLAN_EVENT_HEADER_LEN 8
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun /** SDIO byte mode size */
167*4882a593Smuzhiyun #define MAX_BYTE_MODE_SIZE 512
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun /** The base address for packet with multiple ports aggregation */
170*4882a593Smuzhiyun #define SDIO_MPA_ADDR_BASE 0x1000
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun /** SDIO Tx aggregation in progress ? */
173*4882a593Smuzhiyun #define MP_TX_AGGR_IN_PROGRESS(a) (a->pcard_sd->mpa_tx.pkt_cnt > 0)
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun /** SDIO Tx aggregation buffer room for next packet ? */
176*4882a593Smuzhiyun #define MP_TX_AGGR_BUF_HAS_ROOM(a, mbuf, len)                                  \
177*4882a593Smuzhiyun 	(((a->pcard_sd->mpa_tx.buf_len) + len) <=                              \
178*4882a593Smuzhiyun 	 (a->pcard_sd->mpa_tx.buf_size))
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun /** Copy current packet (SDIO Tx aggregation buffer) to SDIO buffer */
181*4882a593Smuzhiyun #define MP_TX_AGGR_BUF_PUT(a, mbuf, port)                                      \
182*4882a593Smuzhiyun 	do {                                                                   \
183*4882a593Smuzhiyun 		pmadapter->callbacks.moal_memmove(                             \
184*4882a593Smuzhiyun 			a->pmoal_handle,                                       \
185*4882a593Smuzhiyun 			&a->pcard_sd->mpa_tx.buf[a->pcard_sd->mpa_tx.buf_len], \
186*4882a593Smuzhiyun 			mbuf->pbuf + mbuf->data_offset, mbuf->data_len);       \
187*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.buf_len += mbuf->data_len;                 \
188*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.mp_wr_info[a->pcard_sd->mpa_tx.pkt_cnt] =  \
189*4882a593Smuzhiyun 			*(t_u16 *)(mbuf->pbuf + mbuf->data_offset);            \
190*4882a593Smuzhiyun 		if (!a->pcard_sd->mpa_tx.pkt_cnt) {                            \
191*4882a593Smuzhiyun 			a->pcard_sd->mpa_tx.start_port = port;                 \
192*4882a593Smuzhiyun 		}                                                              \
193*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.ports |= (1 << port);                      \
194*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.pkt_cnt++;                                 \
195*4882a593Smuzhiyun 	} while (0)
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun #define MP_TX_AGGR_BUF_PUT_NONEWMODE(a, mbuf, port)                            \
198*4882a593Smuzhiyun 	do {                                                                   \
199*4882a593Smuzhiyun 		pmadapter->callbacks.moal_memmove(                             \
200*4882a593Smuzhiyun 			a->pmoal_handle,                                       \
201*4882a593Smuzhiyun 			&a->pcard_sd->mpa_tx.buf[a->pcard_sd->mpa_tx.buf_len], \
202*4882a593Smuzhiyun 			mbuf->pbuf + mbuf->data_offset, mbuf->data_len);       \
203*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.buf_len += mbuf->data_len;                 \
204*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.mp_wr_info[a->pcard_sd->mpa_tx.pkt_cnt] =  \
205*4882a593Smuzhiyun 			*(t_u16 *)(mbuf->pbuf + mbuf->data_offset);            \
206*4882a593Smuzhiyun 		if (!a->pcard_sd->mpa_tx.pkt_cnt) {                            \
207*4882a593Smuzhiyun 			a->pcard_sd->mpa_tx.start_port = port;                 \
208*4882a593Smuzhiyun 		}                                                              \
209*4882a593Smuzhiyun 		if (a->pcard_sd->mpa_tx.start_port <= port) {                  \
210*4882a593Smuzhiyun 			a->pcard_sd->mpa_tx.ports |=                           \
211*4882a593Smuzhiyun 				(1 << (a->pcard_sd->mpa_tx.pkt_cnt));          \
212*4882a593Smuzhiyun 		} else {                                                       \
213*4882a593Smuzhiyun 			a->pcard_sd->mpa_tx.ports |=                           \
214*4882a593Smuzhiyun 				(1 << (a->pcard_sd->mpa_tx.pkt_cnt + 1 +       \
215*4882a593Smuzhiyun 				       (a->pcard_sd->max_ports -               \
216*4882a593Smuzhiyun 					a->pcard_sd->mp_end_port)));           \
217*4882a593Smuzhiyun 		}                                                              \
218*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.pkt_cnt++;                                 \
219*4882a593Smuzhiyun 	} while (0)
220*4882a593Smuzhiyun #define MP_TX_AGGR_BUF_PUT_SG(a, mbuf, port)                                   \
221*4882a593Smuzhiyun 	do {                                                                   \
222*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.buf_len += mbuf->data_len;                 \
223*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.mp_wr_info[a->pcard_sd->mpa_tx.pkt_cnt] =  \
224*4882a593Smuzhiyun 			*(t_u16 *)(mbuf->pbuf + mbuf->data_offset);            \
225*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.mbuf_arr[a->pcard_sd->mpa_tx.pkt_cnt] =    \
226*4882a593Smuzhiyun 			mbuf;                                                  \
227*4882a593Smuzhiyun 		if (!a->pcard_sd->mpa_tx.pkt_cnt) {                            \
228*4882a593Smuzhiyun 			a->pcard_sd->mpa_tx.start_port = port;                 \
229*4882a593Smuzhiyun 		}                                                              \
230*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.ports |= (1 << port);                      \
231*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.pkt_cnt++;                                 \
232*4882a593Smuzhiyun 	} while (0)
233*4882a593Smuzhiyun #define MP_TX_AGGR_BUF_PUT_SG_NONEWMODE(a, mbuf, port)                         \
234*4882a593Smuzhiyun 	do {                                                                   \
235*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.buf_len += mbuf->data_len;                 \
236*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.mp_wr_info[a->pcard_sd->mpa_tx.pkt_cnt] =  \
237*4882a593Smuzhiyun 			*(t_u16 *)(mbuf->pbuf + mbuf->data_offset);            \
238*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.mbuf_arr[a->pcard_sd->mpa_tx.pkt_cnt] =    \
239*4882a593Smuzhiyun 			mbuf;                                                  \
240*4882a593Smuzhiyun 		if (!a->pcard_sd->mpa_tx.pkt_cnt) {                            \
241*4882a593Smuzhiyun 			a->pcard_sd->mpa_tx.start_port = port;                 \
242*4882a593Smuzhiyun 		}                                                              \
243*4882a593Smuzhiyun 		if (a->pcard_sd->mpa_tx.start_port <= port) {                  \
244*4882a593Smuzhiyun 			a->pcard_sd->mpa_tx.ports |=                           \
245*4882a593Smuzhiyun 				(1 << (a->pcard_sd->mpa_tx.pkt_cnt));          \
246*4882a593Smuzhiyun 		} else {                                                       \
247*4882a593Smuzhiyun 			a->pcard_sd->mpa_tx.ports |=                           \
248*4882a593Smuzhiyun 				(1 << (a->pcard_sd->mpa_tx.pkt_cnt + 1 +       \
249*4882a593Smuzhiyun 				       (a->pcard_sd->max_ports -               \
250*4882a593Smuzhiyun 					a->pcard_sd->mp_end_port)));           \
251*4882a593Smuzhiyun 		}                                                              \
252*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.pkt_cnt++;                                 \
253*4882a593Smuzhiyun 	} while (0)
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun /** SDIO Tx aggregation limit ? */
256*4882a593Smuzhiyun #define MP_TX_AGGR_PKT_LIMIT_REACHED(a)                                        \
257*4882a593Smuzhiyun 	((a->pcard_sd->mpa_tx.pkt_cnt) == (a->pcard_sd->mpa_tx.pkt_aggr_limit))
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun #define MP_TX_AGGR_PORT_LIMIT_REACHED(a)                                       \
260*4882a593Smuzhiyun 	((a->pcard_sd->curr_wr_port < a->pcard_sd->mpa_tx.start_port) &&       \
261*4882a593Smuzhiyun 	 (((a->pcard_sd->max_ports - a->pcard_sd->mpa_tx.start_port) +         \
262*4882a593Smuzhiyun 	   a->pcard_sd->curr_wr_port) >= a->pcard_sd->mp_aggr_pkt_limit))
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun /** Reset SDIO Tx aggregation buffer parameters */
265*4882a593Smuzhiyun #define MP_TX_AGGR_BUF_RESET(a)                                                \
266*4882a593Smuzhiyun 	do {                                                                   \
267*4882a593Smuzhiyun 		memset(a, a->pcard_sd->mpa_tx.mp_wr_info, 0,                   \
268*4882a593Smuzhiyun 		       sizeof(a->pcard_sd->mpa_tx.mp_wr_info));                \
269*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.pkt_cnt = 0;                               \
270*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.buf_len = 0;                               \
271*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.ports = 0;                                 \
272*4882a593Smuzhiyun 		a->pcard_sd->mpa_tx.start_port = 0;                            \
273*4882a593Smuzhiyun 	} while (0)
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun /** SDIO Rx aggregation limit ? */
276*4882a593Smuzhiyun #define MP_RX_AGGR_PKT_LIMIT_REACHED(a)                                        \
277*4882a593Smuzhiyun 	(a->pcard_sd->mpa_rx.pkt_cnt == a->pcard_sd->mpa_rx.pkt_aggr_limit)
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun /** SDIO Rx aggregation port limit ? */
280*4882a593Smuzhiyun /** this is for test only, because port 0 is reserved for control port */
281*4882a593Smuzhiyun /* #define MP_RX_AGGR_PORT_LIMIT_REACHED(a) (a->curr_rd_port == 1) */
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun /* receive packets aggregated up to a half of mp_end_port */
284*4882a593Smuzhiyun /* note: hw rx wraps round only after port (MAX_PORT-1) */
285*4882a593Smuzhiyun #define MP_RX_AGGR_PORT_LIMIT_REACHED(a)                                       \
286*4882a593Smuzhiyun 	(((a->pcard_sd->curr_rd_port < a->pcard_sd->mpa_rx.start_port) &&      \
287*4882a593Smuzhiyun 	  (((a->pcard_sd->max_ports - a->pcard_sd->mpa_rx.start_port) +        \
288*4882a593Smuzhiyun 	    a->pcard_sd->curr_rd_port) >= (a->pcard_sd->mp_end_port >> 1))) || \
289*4882a593Smuzhiyun 	 ((a->pcard_sd->curr_rd_port - a->pcard_sd->mpa_rx.start_port) >=      \
290*4882a593Smuzhiyun 	  (a->pcard_sd->mp_end_port >> 1)))
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun #define MP_RX_AGGR_PORT_LIMIT_REACHED_NONEWMODE(a)                             \
293*4882a593Smuzhiyun 	((a->pcard_sd->curr_rd_port < a->pcard_sd->mpa_rx.start_port) &&       \
294*4882a593Smuzhiyun 	 (((a->pcard_sd->max_ports - a->pcard_sd->mpa_rx.start_port) +         \
295*4882a593Smuzhiyun 	   a->pcard_sd->curr_rd_port) >= a->pcard_sd->mp_aggr_pkt_limit))
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun /** SDIO Rx aggregation in progress ? */
298*4882a593Smuzhiyun #define MP_RX_AGGR_IN_PROGRESS(a) (a->pcard_sd->mpa_rx.pkt_cnt > 0)
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun /** SDIO Rx aggregation buffer room for next packet ? */
301*4882a593Smuzhiyun #define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len)                                     \
302*4882a593Smuzhiyun 	((a->pcard_sd->mpa_rx.buf_len + rx_len) <= a->pcard_sd->mpa_rx.buf_size)
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun /** Prepare to copy current packet from card to SDIO Rx aggregation buffer */
305*4882a593Smuzhiyun #define MP_RX_AGGR_SETUP(a, mbuf, port, rx_len)                                \
306*4882a593Smuzhiyun 	do {                                                                   \
307*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.buf_len += rx_len;                         \
308*4882a593Smuzhiyun 		if (!a->pcard_sd->mpa_rx.pkt_cnt) {                            \
309*4882a593Smuzhiyun 			a->pcard_sd->mpa_rx.start_port = port;                 \
310*4882a593Smuzhiyun 		}                                                              \
311*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.ports |= (1 << port);                      \
312*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.mbuf_arr[a->pcard_sd->mpa_rx.pkt_cnt] =    \
313*4882a593Smuzhiyun 			mbuf;                                                  \
314*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.len_arr[a->pcard_sd->mpa_rx.pkt_cnt] =     \
315*4882a593Smuzhiyun 			rx_len;                                                \
316*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.pkt_cnt++;                                 \
317*4882a593Smuzhiyun 	} while (0)
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun #define MP_RX_AGGR_SETUP_NONEWMODE(a, mbuf, port, rx_len)                      \
320*4882a593Smuzhiyun 	do {                                                                   \
321*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.buf_len += rx_len;                         \
322*4882a593Smuzhiyun 		if (!a->pcard_sd->mpa_rx.pkt_cnt) {                            \
323*4882a593Smuzhiyun 			a->pcard_sd->mpa_rx.start_port = port;                 \
324*4882a593Smuzhiyun 		}                                                              \
325*4882a593Smuzhiyun 		if (a->pcard_sd->mpa_rx.start_port <= port) {                  \
326*4882a593Smuzhiyun 			a->pcard_sd->mpa_rx.ports |=                           \
327*4882a593Smuzhiyun 				(1 << (a->pcard_sd->mpa_rx.pkt_cnt));          \
328*4882a593Smuzhiyun 		} else {                                                       \
329*4882a593Smuzhiyun 			a->pcard_sd->mpa_rx.ports |=                           \
330*4882a593Smuzhiyun 				(1 << (a->pcard_sd->mpa_rx.pkt_cnt + 1));      \
331*4882a593Smuzhiyun 		}                                                              \
332*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.mbuf_arr[a->pcard_sd->mpa_rx.pkt_cnt] =    \
333*4882a593Smuzhiyun 			mbuf;                                                  \
334*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.len_arr[a->pcard_sd->mpa_rx.pkt_cnt] =     \
335*4882a593Smuzhiyun 			rx_len;                                                \
336*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.pkt_cnt++;                                 \
337*4882a593Smuzhiyun 	} while (0);
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun /** Reset SDIO Rx aggregation buffer parameters */
340*4882a593Smuzhiyun #define MP_RX_AGGR_BUF_RESET(a)                                                \
341*4882a593Smuzhiyun 	do {                                                                   \
342*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.pkt_cnt = 0;                               \
343*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.buf_len = 0;                               \
344*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.ports = 0;                                 \
345*4882a593Smuzhiyun 		a->pcard_sd->mpa_rx.start_port = 0;                            \
346*4882a593Smuzhiyun 	} while (0)
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun /** aggr buf size 32k  */
349*4882a593Smuzhiyun #define SDIO_MP_AGGR_BUF_SIZE_32K (32768)
350*4882a593Smuzhiyun /** max aggr buf size 64k-256 */
351*4882a593Smuzhiyun #define SDIO_MP_AGGR_BUF_SIZE_MAX (65280)
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun extern mlan_adapter_operations mlan_sdio_ops;
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun /** Probe and initialization function */
356*4882a593Smuzhiyun mlan_status wlan_sdio_probe(pmlan_adapter pmadapter);
357*4882a593Smuzhiyun mlan_status wlan_get_sdio_device(pmlan_adapter pmadapter);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun mlan_status wlan_send_mp_aggr_buf(mlan_adapter *pmadapter);
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun mlan_status wlan_re_alloc_sdio_rx_mpa_buffer(mlan_adapter *pmadapter);
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun void wlan_decode_spa_buffer(mlan_adapter *pmadapter, t_u8 *buf, t_u32 len);
364*4882a593Smuzhiyun t_void wlan_sdio_deaggr_rx_pkt(pmlan_adapter pmadapter, mlan_buffer *pmbuf);
365*4882a593Smuzhiyun /** Transfer data to card */
366*4882a593Smuzhiyun mlan_status wlan_sdio_host_to_card(mlan_adapter *pmadapter, t_u8 type,
367*4882a593Smuzhiyun 				   mlan_buffer *mbuf, mlan_tx_param *tx_param);
368*4882a593Smuzhiyun mlan_status wlan_set_sdio_gpio_int(pmlan_private priv);
369*4882a593Smuzhiyun mlan_status wlan_cmd_sdio_gpio_int(pmlan_private pmpriv,
370*4882a593Smuzhiyun 				   HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
371*4882a593Smuzhiyun 				   t_void *pdata_buf);
372*4882a593Smuzhiyun mlan_status wlan_reset_fw(pmlan_adapter pmadapter);
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun #endif /* _MLAN_SDIO_H */
375