xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8189fs/hal/rtl8188f/sdio/sdio_ops.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _SDIO_OPS_C_
16 
17 #include <rtl8188f_hal.h>
18 
19 /* #define SDIO_DEBUG_IO 1 */
20 #define CONFIG_RTW_SDIO_REG_FORCE_CMD52 0
21 
22 #define WLAN_IOREG_CMD_ADDR(addr) ((WLAN_IOREG_DEVICE_ID << 13) | ((addr) & WLAN_IOREG_MSK))
23 #define WLAN_TXHIQ_CMD_ADDR(r4_cnt) ((WLAN_TX_HIQ_DEVICE_ID << 13) | ((r4_cnt) & WLAN_FIFO_MSK))
24 #define WLAN_TXMIQ_CMD_ADDR(r4_cnt) ((WLAN_TX_MIQ_DEVICE_ID << 13) | ((r4_cnt) & WLAN_FIFO_MSK))
25 #define WLAN_TXLOQ_CMD_ADDR(r4_cnt) ((WLAN_TX_LOQ_DEVICE_ID << 13) | ((r4_cnt) & WLAN_FIFO_MSK))
26 #define WLAN_TXEXQ_CMD_ADDR(r4_cnt) ((WLAN_TX_EXQ_DEVICE_ID << 13) | ((r4_cnt) & WLAN_FIFO_MSK))
27 #define WLAN_RX0FF_CMD_ADDR(seq) ((WLAN_RX0FF_DEVICE_ID << 13) | ((seq) & WLAN_RX0FF_MSK))
28 
29 /*
30  * Description:
31  *	The following mapping is for SDIO host local register space.
32  *
33  * Creadted by Roger, 2011.01.31.
34  *   */
HalSdioGetCmdAddr8188FSdio(PADAPTER padapter,u8 DeviceID,u32 Addr,u32 * pCmdAddr)35 static void HalSdioGetCmdAddr8188FSdio(
36 		PADAPTER			padapter,
37 		u8				DeviceID,
38 		u32				Addr,
39 		u32				*pCmdAddr
40 )
41 {
42 	switch (DeviceID) {
43 	case SDIO_LOCAL_DEVICE_ID:
44 		*pCmdAddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (Addr & SDIO_LOCAL_MSK));
45 		break;
46 
47 	case WLAN_IOREG_DEVICE_ID:
48 		*pCmdAddr = ((WLAN_IOREG_DEVICE_ID << 13) | (Addr & WLAN_IOREG_MSK));
49 		break;
50 
51 	case WLAN_TX_HIQ_DEVICE_ID:
52 		*pCmdAddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
53 		break;
54 
55 	case WLAN_TX_MIQ_DEVICE_ID:
56 		*pCmdAddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
57 		break;
58 
59 	case WLAN_TX_LOQ_DEVICE_ID:
60 		*pCmdAddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
61 		break;
62 
63 	case WLAN_RX0FF_DEVICE_ID:
64 		*pCmdAddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (Addr & WLAN_RX0FF_MSK));
65 		break;
66 
67 	default:
68 		break;
69 	}
70 }
71 
get_deviceid(u32 addr)72 static u8 get_deviceid(u32 addr)
73 {
74 	u8 devideId;
75 	u16 pseudoId;
76 
77 
78 	pseudoId = (u16)(addr >> 16);
79 	switch (pseudoId) {
80 	case 0x1025:
81 		devideId = SDIO_LOCAL_DEVICE_ID;
82 		break;
83 
84 	case 0x1026:
85 		devideId = WLAN_IOREG_DEVICE_ID;
86 		break;
87 
88 	/*		case 0x1027:
89 	 *			devideId = SDIO_FIRMWARE_FIFO;
90 	 *			break; */
91 
92 	case 0x1031:
93 		devideId = WLAN_TX_HIQ_DEVICE_ID;
94 		break;
95 
96 	case 0x1032:
97 		devideId = WLAN_TX_MIQ_DEVICE_ID;
98 		break;
99 
100 	case 0x1033:
101 		devideId = WLAN_TX_LOQ_DEVICE_ID;
102 		break;
103 
104 	case 0x1034:
105 		devideId = WLAN_RX0FF_DEVICE_ID;
106 		break;
107 
108 	default:
109 		/*			devideId = (u8)((addr >> 13) & 0xF); */
110 		devideId = WLAN_IOREG_DEVICE_ID;
111 		break;
112 	}
113 
114 	return devideId;
115 }
116 
117 /*
118  * Ref:
119  *	HalSdioGetCmdAddr8188FSdio()
120  */
_cvrt2ftaddr(const u32 addr,u8 * pdeviceId,u16 * poffset)121 static u32 _cvrt2ftaddr(const u32 addr, u8 *pdeviceId, u16 *poffset)
122 {
123 	u8 deviceId;
124 	u16 offset;
125 	u32 ftaddr;
126 
127 
128 	deviceId = get_deviceid(addr);
129 	offset = 0;
130 
131 	switch (deviceId) {
132 	case SDIO_LOCAL_DEVICE_ID:
133 		offset = addr & SDIO_LOCAL_MSK;
134 		break;
135 
136 	case WLAN_TX_HIQ_DEVICE_ID:
137 	case WLAN_TX_MIQ_DEVICE_ID:
138 	case WLAN_TX_LOQ_DEVICE_ID:
139 		offset = addr & WLAN_FIFO_MSK;
140 		break;
141 
142 	case WLAN_RX0FF_DEVICE_ID:
143 		offset = addr & WLAN_RX0FF_MSK;
144 		break;
145 
146 	case WLAN_IOREG_DEVICE_ID:
147 	default:
148 		deviceId = WLAN_IOREG_DEVICE_ID;
149 		offset = addr & WLAN_IOREG_MSK;
150 		break;
151 	}
152 	ftaddr = (deviceId << 13) | offset;
153 
154 	if (pdeviceId)
155 		*pdeviceId = deviceId;
156 	if (poffset)
157 		*poffset = offset;
158 
159 	return ftaddr;
160 }
161 
162 
sdio_read8(struct intf_hdl * pintfhdl,u32 addr)163 u8 sdio_read8(struct intf_hdl *pintfhdl, u32 addr)
164 {
165 	u32 ftaddr;
166 	u8 device_id;
167 	u16 offset;
168 	u8 val;
169 	u8 sus_leave = _FALSE;
170 
171 	ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
172 
173 	if (device_id == WLAN_IOREG_DEVICE_ID && offset < 0x100)
174 		sus_leave = sdio_chk_hci_resume(pintfhdl);
175 
176 	val = sd_read8(pintfhdl, ftaddr, NULL);
177 
178 	if (sus_leave == _TRUE)
179 		sdio_chk_hci_suspend(pintfhdl);
180 
181 	return val;
182 }
183 
sdio_read16(struct intf_hdl * pintfhdl,u32 addr)184 u16 sdio_read16(struct intf_hdl *pintfhdl, u32 addr)
185 {
186 	u32 ftaddr;
187 	u8 device_id;
188 	u16 offset;
189 	u16 val;
190 	u8 sus_leave = _FALSE;
191 
192 	ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
193 
194 	if (device_id == WLAN_IOREG_DEVICE_ID && offset < 0x100)
195 		sus_leave = sdio_chk_hci_resume(pintfhdl);
196 
197 	val = 0;
198 	sd_cmd52_read(pintfhdl, ftaddr, 2, (u8 *)&val);
199 	val = le16_to_cpu(val);
200 
201 	if (sus_leave == _TRUE)
202 		sdio_chk_hci_suspend(pintfhdl);
203 
204 	return val;
205 }
206 
sdio_read32(struct intf_hdl * pintfhdl,u32 addr)207 u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr)
208 {
209 	PADAPTER padapter;
210 	u8 bMacPwrCtrlOn;
211 	u8 deviceId;
212 	u16 offset;
213 	u32 ftaddr;
214 	u8 shift;
215 	u32 val;
216 	s32 err;
217 
218 
219 	padapter = pintfhdl->padapter;
220 	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
221 
222 	bMacPwrCtrlOn = _FALSE;
223 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
224 
225 	if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
226 		|| (bMacPwrCtrlOn == _FALSE)
227 		#ifdef CONFIG_LPS_LCLK
228 		|| (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE)
229 		#endif
230 		|| CONFIG_RTW_SDIO_REG_FORCE_CMD52
231 	) {
232 		u8 sus_leave = _FALSE;
233 
234 		if (deviceId == WLAN_IOREG_DEVICE_ID && offset < 0x100)
235 			sus_leave = sdio_chk_hci_resume(pintfhdl);
236 
237 		val = 0;
238 		err = sd_cmd52_read(pintfhdl, ftaddr, 4, (u8 *)&val);
239 
240 		if (sus_leave == _TRUE)
241 			sdio_chk_hci_suspend(pintfhdl);
242 
243 #ifdef SDIO_DEBUG_IO
244 		if (!err) {
245 #endif
246 			val = le32_to_cpu(val);
247 			return val;
248 #ifdef SDIO_DEBUG_IO
249 		}
250 
251 		RTW_ERR("%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n", __func__, err, addr);
252 		return SDIO_ERR_VAL32;
253 #endif
254 	}
255 
256 	/* 4 bytes alignment */
257 	shift = ftaddr & 0x3;
258 	if (shift == 0)
259 		val = sd_read32(pintfhdl, ftaddr, NULL);
260 	else {
261 		u8 *ptmpbuf;
262 
263 		ptmpbuf = (u8 *)rtw_malloc(8);
264 		if (NULL == ptmpbuf) {
265 			RTW_ERR("%s: Allocate memory FAIL!(size=8) addr=0x%x\n", __func__, addr);
266 			return SDIO_ERR_VAL32;
267 		}
268 
269 		ftaddr &= ~(u16)0x3;
270 		err = sd_read(pintfhdl, ftaddr, 8, ptmpbuf);
271 		if (err)
272 			return SDIO_ERR_VAL32;
273 		_rtw_memcpy(&val, ptmpbuf + shift, 4);
274 		val = le32_to_cpu(val);
275 
276 		rtw_mfree(ptmpbuf, 8);
277 	}
278 
279 
280 	return val;
281 }
282 
sdio_readN(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pbuf)283 s32 sdio_readN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pbuf)
284 {
285 	PADAPTER padapter;
286 	u8 bMacPwrCtrlOn;
287 	u8 deviceId;
288 	u16 offset;
289 	u32 ftaddr;
290 	u8 shift;
291 	s32 err;
292 
293 
294 	padapter = pintfhdl->padapter;
295 	err = 0;
296 
297 	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
298 
299 	bMacPwrCtrlOn = _FALSE;
300 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
301 	if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
302 		|| (bMacPwrCtrlOn == _FALSE)
303 		#ifdef CONFIG_LPS_LCLK
304 		|| (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE)
305 		#endif
306 		|| CONFIG_RTW_SDIO_REG_FORCE_CMD52
307 	) {
308 		u8 sus_leave = _FALSE;
309 
310 		if (deviceId == WLAN_IOREG_DEVICE_ID && offset < 0x100)
311 			sus_leave = sdio_chk_hci_resume(pintfhdl);
312 
313 		err = sd_cmd52_read(pintfhdl, ftaddr, cnt, pbuf);
314 
315 		if (sus_leave == _TRUE)
316 			sdio_chk_hci_suspend(pintfhdl);
317 
318 		return err;
319 	}
320 
321 	/* 4 bytes alignment */
322 	shift = ftaddr & 0x3;
323 	if (shift == 0)
324 		err = sd_read(pintfhdl, ftaddr, cnt, pbuf);
325 	else {
326 		u8 *ptmpbuf;
327 		u32 n;
328 
329 		ftaddr &= ~(u16)0x3;
330 		n = cnt + shift;
331 		ptmpbuf = rtw_malloc(n);
332 		if (NULL == ptmpbuf)
333 			return -1;
334 		err = sd_read(pintfhdl, ftaddr, n, ptmpbuf);
335 		if (!err)
336 			_rtw_memcpy(pbuf, ptmpbuf + shift, cnt);
337 		rtw_mfree(ptmpbuf, n);
338 	}
339 
340 
341 	return err;
342 }
343 
sdio_write8(struct intf_hdl * pintfhdl,u32 addr,u8 val)344 s32 sdio_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
345 {
346 	u32 ftaddr;
347 	u8 device_id;
348 	u16 offset;
349 	s32 err;
350 	u8 sus_leave = _FALSE;
351 
352 	ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
353 
354 	if (device_id == WLAN_IOREG_DEVICE_ID && offset < 0x100)
355 		sus_leave = sdio_chk_hci_resume(pintfhdl);
356 
357 	err = 0;
358 	sd_write8(pintfhdl, ftaddr, val, &err);
359 
360 	if (sus_leave == _TRUE)
361 		sdio_chk_hci_suspend(pintfhdl);
362 
363 	return err;
364 }
365 
sdio_write16(struct intf_hdl * pintfhdl,u32 addr,u16 val)366 s32 sdio_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
367 {
368 	u32 ftaddr;
369 	u8 device_id;
370 	u16 offset;
371 	s32 err;
372 	u8 sus_leave = _FALSE;
373 
374 	ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
375 
376 	if (device_id == WLAN_IOREG_DEVICE_ID && offset < 0x100)
377 		sus_leave = sdio_chk_hci_resume(pintfhdl);
378 
379 	val = cpu_to_le16(val);
380 	err = sd_cmd52_write(pintfhdl, ftaddr, 2, (u8 *)&val);
381 
382 	if (sus_leave == _TRUE)
383 		sdio_chk_hci_suspend(pintfhdl);
384 
385 	return err;
386 }
387 
sdio_write32(struct intf_hdl * pintfhdl,u32 addr,u32 val)388 s32 sdio_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
389 {
390 	PADAPTER padapter;
391 	u8 bMacPwrCtrlOn;
392 	u8 deviceId;
393 	u16 offset;
394 	u32 ftaddr;
395 	u8 shift;
396 	s32 err;
397 
398 
399 	padapter = pintfhdl->padapter;
400 	err = 0;
401 
402 	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
403 
404 	bMacPwrCtrlOn = _FALSE;
405 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
406 
407 	if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
408 		|| (bMacPwrCtrlOn == _FALSE)
409 		#ifdef CONFIG_LPS_LCLK
410 		|| (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE)
411 		#endif
412 		|| CONFIG_RTW_SDIO_REG_FORCE_CMD52
413 	) {
414 		u8 sus_leave = _FALSE;
415 
416 		if (deviceId == WLAN_IOREG_DEVICE_ID && offset < 0x100)
417 			sus_leave = sdio_chk_hci_resume(pintfhdl);
418 
419 		val = cpu_to_le32(val);
420 		err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8 *)&val);
421 
422 		if (sus_leave == _TRUE)
423 			sdio_chk_hci_suspend(pintfhdl);
424 
425 		return err;
426 	}
427 
428 	/* 4 bytes alignment */
429 	shift = ftaddr & 0x3;
430 #if 1
431 	if (shift == 0)
432 		sd_write32(pintfhdl, ftaddr, val, &err);
433 	else {
434 		val = cpu_to_le32(val);
435 		err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8 *)&val);
436 	}
437 #else
438 	if (shift == 0)
439 		sd_write32(pintfhdl, ftaddr, val, &err);
440 	else {
441 		u8 *ptmpbuf;
442 
443 		ptmpbuf = (u8 *)rtw_malloc(8);
444 		if (NULL == ptmpbuf)
445 			return -1;
446 
447 		ftaddr &= ~(u16)0x3;
448 		err = sd_read(pintfhdl, ftaddr, 8, ptmpbuf);
449 		if (err) {
450 			rtw_mfree(ptmpbuf, 8);
451 			return err;
452 		}
453 		val = cpu_to_le32(val);
454 		_rtw_memcpy(ptmpbuf + shift, &val, 4);
455 		err = sd_write(pintfhdl, ftaddr, 8, ptmpbuf);
456 
457 		rtw_mfree(ptmpbuf, 8);
458 	}
459 #endif
460 
461 
462 	return err;
463 }
464 
sdio_writeN(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pbuf)465 s32 sdio_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pbuf)
466 {
467 	PADAPTER padapter;
468 	u8 bMacPwrCtrlOn;
469 	u8 deviceId;
470 	u16 offset;
471 	u32 ftaddr;
472 	u8 shift;
473 	s32 err;
474 
475 
476 	padapter = pintfhdl->padapter;
477 	err = 0;
478 
479 	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
480 
481 	bMacPwrCtrlOn = _FALSE;
482 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
483 	if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
484 		|| (bMacPwrCtrlOn == _FALSE)
485 		#ifdef CONFIG_LPS_LCLK
486 		|| (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE)
487 		#endif
488 		|| CONFIG_RTW_SDIO_REG_FORCE_CMD52
489 	) {
490 		u8 sus_leave = _FALSE;
491 
492 		if (deviceId == WLAN_IOREG_DEVICE_ID && offset < 0x100)
493 			sus_leave = sdio_chk_hci_resume(pintfhdl);
494 
495 		err = sd_cmd52_write(pintfhdl, ftaddr, cnt, pbuf);
496 
497 		if (sus_leave == _TRUE)
498 			sdio_chk_hci_suspend(pintfhdl);
499 
500 		return err;
501 	}
502 
503 	shift = ftaddr & 0x3;
504 	if (shift == 0)
505 		err = sd_write(pintfhdl, ftaddr, cnt, pbuf);
506 	else {
507 		u8 *ptmpbuf;
508 		u32 n;
509 
510 		ftaddr &= ~(u16)0x3;
511 		n = cnt + shift;
512 		ptmpbuf = rtw_malloc(n);
513 		if (NULL == ptmpbuf)
514 			return -1;
515 		err = sd_read(pintfhdl, ftaddr, 4, ptmpbuf);
516 		if (err) {
517 			rtw_mfree(ptmpbuf, n);
518 			return err;
519 		}
520 		_rtw_memcpy(ptmpbuf + shift, pbuf, cnt);
521 		err = sd_write(pintfhdl, ftaddr, n, ptmpbuf);
522 		rtw_mfree(ptmpbuf, n);
523 	}
524 
525 
526 	return err;
527 }
528 
sdio_f0_read8(struct intf_hdl * pintfhdl,u32 addr)529 u8 sdio_f0_read8(struct intf_hdl *pintfhdl, u32 addr)
530 {
531 	u32 ftaddr;
532 	u8 val;
533 
534 	val = sd_f0_read8(pintfhdl, addr, NULL);
535 
536 
537 	return val;
538 }
539 
sdio_read_mem(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * rmem)540 void sdio_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
541 {
542 	s32 err;
543 
544 
545 	err = sdio_readN(pintfhdl, addr, cnt, rmem);
546 
547 }
548 
sdio_write_mem(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * wmem)549 void sdio_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
550 {
551 
552 	sdio_writeN(pintfhdl, addr, cnt, wmem);
553 
554 }
555 
sdio_read_port_no_align(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * mem)556 static u32 sdio_read_port_no_align(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *mem)
557 {
558 	PADAPTER padapter;
559 	PHAL_DATA_TYPE phal;
560 	s32 err;
561 
562 	padapter = pintfhdl->padapter;
563 	phal = GET_HAL_DATA(padapter);
564 
565 	HalSdioGetCmdAddr8188FSdio(padapter, addr, phal->SdioRxFIFOCnt++, &addr);
566 
567 	err = _sd_read(pintfhdl, addr, cnt, mem);
568 	if (err)
569 		return _FAIL;
570 	return _SUCCESS;
571 }
572 
573 /*
574  * Description:
575  *	Read from RX FIFO
576  *	Round read size to block size,
577  *	and make sure data transfer will be done in one command.
578  *
579  * Parameters:
580  *	pintfhdl	a pointer of intf_hdl
581  *	addr		port ID
582  *	cnt			size to read
583  *	rmem		address to put data
584  *
585  * Return:
586  *	_SUCCESS(1)		Success
587  *	_FAIL(0)		Fail
588  */
sdio_read_port(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * mem)589 static u32 sdio_read_port(
590 	struct intf_hdl *pintfhdl,
591 	u32 addr,
592 	u32 cnt,
593 	u8 *mem)
594 {
595 	PADAPTER padapter;
596 	u32 oldcnt;
597 #ifdef SDIO_DYNAMIC_ALLOC_MEM
598 	u8 *oldmem;
599 #endif
600 	u32 ret;
601 
602 	padapter = pintfhdl->padapter;
603 
604 	oldcnt = cnt;
605 	cnt = rtw_sdio_cmd53_align_size(adapter_to_dvobj(padapter), cnt);
606 
607 	if (oldcnt != cnt) {
608 #ifdef SDIO_DYNAMIC_ALLOC_MEM
609 		oldmem = mem;
610 		mem = rtw_malloc(cnt);
611 		if (mem == NULL) {
612 			RTW_WARN("%s: allocate memory %d bytes fail!\n", __func__, cnt);
613 			mem = oldmem;
614 			oldmem == NULL;
615 		}
616 #else
617 		/* in this case, caller should gurante the buffer is big enough */
618 		/* to receive data after alignment */
619 #endif
620 	}
621 
622 	ret = sdio_read_port_no_align(pintfhdl, addr, cnt, mem);
623 
624 #ifdef SDIO_DYNAMIC_ALLOC_MEM
625 	if ((oldcnt != cnt) && (oldmem)) {
626 		_rtw_memcpy(oldmem, mem, oldcnt);
627 		rtw_mfree(mem, cnt);
628 	}
629 #endif
630 
631 	return ret;
632 }
633 
634 /*
635  * Description:
636  *	Write to TX FIFO
637  *	Align write size block size,
638  *	and make sure data could be written in one command.
639  *
640  * Parameters:
641  *	pintfhdl	a pointer of intf_hdl
642  *	addr		port ID
643  *	cnt			size to write
644  *	wmem		data pointer to write
645  *
646  * Return:
647  *	_SUCCESS(1)		Success
648  *	_FAIL(0)		Fail
649  */
sdio_write_port(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * mem)650 static u32 sdio_write_port(
651 	struct intf_hdl *pintfhdl,
652 	u32 addr,
653 	u32 cnt,
654 	u8 *mem)
655 {
656 	PADAPTER padapter;
657 	s32 err;
658 	struct xmit_buf *xmitbuf = (struct xmit_buf *)mem;
659 
660 	padapter = pintfhdl->padapter;
661 
662 	if (!rtw_is_hw_init_completed(padapter)) {
663 		RTW_INFO("%s [addr=0x%x cnt=%d] padapter->hw_init_completed == _FALSE\n", __func__, addr, cnt);
664 		return _FAIL;
665 	}
666 
667 	cnt = _RND4(cnt);
668 	HalSdioGetCmdAddr8188FSdio(padapter, addr, cnt >> 2, &addr);
669 
670 	cnt = rtw_sdio_cmd53_align_size(adapter_to_dvobj(padapter), cnt);
671 
672 	err = sd_write(pintfhdl, addr, cnt, xmitbuf->pdata);
673 
674 	rtw_sctx_done_err(&xmitbuf->sctx,
675 		  err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS);
676 
677 	if (err)
678 		return _FAIL;
679 	return _SUCCESS;
680 }
681 
682 /*
683  * Todo: align address to 4 bytes.
684  */
_sdio_local_read(PADAPTER padapter,u32 addr,u32 cnt,u8 * pbuf)685 s32 _sdio_local_read(
686 	PADAPTER	padapter,
687 	u32			addr,
688 	u32			cnt,
689 	u8			*pbuf)
690 {
691 	struct intf_hdl *pintfhdl;
692 	u8 bMacPwrCtrlOn;
693 	s32 err;
694 	u8 *ptmpbuf;
695 	u32 n;
696 
697 
698 	pintfhdl = &padapter->iopriv.intf;
699 
700 	HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
701 
702 	bMacPwrCtrlOn = _FALSE;
703 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
704 	if (bMacPwrCtrlOn == _FALSE
705 		|| CONFIG_RTW_SDIO_REG_FORCE_CMD52
706 	) {
707 		err = _sd_cmd52_read(pintfhdl, addr, cnt, pbuf);
708 		return err;
709 	}
710 
711 	n = RND4(cnt);
712 	ptmpbuf = (u8 *)rtw_malloc(n);
713 	if (!ptmpbuf)
714 		return -1;
715 
716 	err = _sd_read(pintfhdl, addr, n, ptmpbuf);
717 	if (!err)
718 		_rtw_memcpy(pbuf, ptmpbuf, cnt);
719 
720 	if (ptmpbuf)
721 		rtw_mfree(ptmpbuf, n);
722 
723 	return err;
724 }
725 
726 /*
727  * Todo: align address to 4 bytes.
728  */
sdio_local_read(PADAPTER padapter,u32 addr,u32 cnt,u8 * pbuf)729 s32 sdio_local_read(
730 	PADAPTER	padapter,
731 	u32			addr,
732 	u32			cnt,
733 	u8			*pbuf)
734 {
735 	struct intf_hdl *pintfhdl;
736 	u8 bMacPwrCtrlOn;
737 	s32 err;
738 	u8 *ptmpbuf;
739 	u32 n;
740 
741 	pintfhdl = &padapter->iopriv.intf;
742 
743 	HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
744 
745 	bMacPwrCtrlOn = _FALSE;
746 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
747 	if ((_FALSE == bMacPwrCtrlOn)
748 		#ifdef CONFIG_LPS_LCLK
749 		|| (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE)
750 		#endif
751 		|| CONFIG_RTW_SDIO_REG_FORCE_CMD52
752 	) {
753 		err = sd_cmd52_read(pintfhdl, addr, cnt, pbuf);
754 		return err;
755 	}
756 
757 	n = RND4(cnt);
758 	ptmpbuf = (u8 *)rtw_malloc(n);
759 	if (!ptmpbuf)
760 		return -1;
761 
762 	err = sd_read(pintfhdl, addr, n, ptmpbuf);
763 	if (!err)
764 		_rtw_memcpy(pbuf, ptmpbuf, cnt);
765 
766 	if (ptmpbuf)
767 		rtw_mfree(ptmpbuf, n);
768 
769 	return err;
770 }
771 
772 /*
773  * Todo: align address to 4 bytes.
774  */
_sdio_local_write(PADAPTER padapter,u32 addr,u32 cnt,u8 * pbuf)775 s32 _sdio_local_write(
776 	PADAPTER	padapter,
777 	u32			addr,
778 	u32			cnt,
779 	u8			*pbuf)
780 {
781 	struct intf_hdl *pintfhdl;
782 	u8 bMacPwrCtrlOn;
783 	s32 err;
784 	u8 *ptmpbuf;
785 
786 	if (addr & 0x3)
787 		RTW_INFO("%s, address must be 4 bytes alignment\n", __FUNCTION__);
788 
789 	if (cnt  & 0x3)
790 		RTW_INFO("%s, size must be the multiple of 4\n", __FUNCTION__);
791 
792 	pintfhdl = &padapter->iopriv.intf;
793 
794 	HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
795 
796 	bMacPwrCtrlOn = _FALSE;
797 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
798 	if ((_FALSE == bMacPwrCtrlOn)
799 		#ifdef CONFIG_LPS_LCLK
800 		|| (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE)
801 		#endif
802 		|| CONFIG_RTW_SDIO_REG_FORCE_CMD52
803 	) {
804 		err = _sd_cmd52_write(pintfhdl, addr, cnt, pbuf);
805 		return err;
806 	}
807 
808 	ptmpbuf = (u8 *)rtw_malloc(cnt);
809 	if (!ptmpbuf)
810 		return -1;
811 
812 	_rtw_memcpy(ptmpbuf, pbuf, cnt);
813 
814 	err = _sd_write(pintfhdl, addr, cnt, ptmpbuf);
815 
816 	if (ptmpbuf)
817 		rtw_mfree(ptmpbuf, cnt);
818 
819 	return err;
820 }
821 
822 /*
823  * Todo: align address to 4 bytes.
824  */
sdio_local_write(PADAPTER padapter,u32 addr,u32 cnt,u8 * pbuf)825 s32 sdio_local_write(
826 	PADAPTER	padapter,
827 	u32		addr,
828 	u32		cnt,
829 	u8		*pbuf)
830 {
831 	struct intf_hdl *pintfhdl;
832 	u8 bMacPwrCtrlOn;
833 	s32 err;
834 	u8 *ptmpbuf;
835 
836 	if (addr & 0x3)
837 		RTW_INFO("%s, address must be 4 bytes alignment\n", __FUNCTION__);
838 
839 	if (cnt  & 0x3)
840 		RTW_INFO("%s, size must be the multiple of 4\n", __FUNCTION__);
841 
842 	pintfhdl = &padapter->iopriv.intf;
843 
844 	HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
845 
846 	bMacPwrCtrlOn = _FALSE;
847 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
848 	if ((_FALSE == bMacPwrCtrlOn)
849 		#ifdef CONFIG_LPS_LCLK
850 		|| (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE)
851 		#endif
852 		|| CONFIG_RTW_SDIO_REG_FORCE_CMD52
853 	) {
854 		err = sd_cmd52_write(pintfhdl, addr, cnt, pbuf);
855 		return err;
856 	}
857 
858 	ptmpbuf = (u8 *)rtw_malloc(cnt);
859 	if (!ptmpbuf)
860 		return -1;
861 
862 	_rtw_memcpy(ptmpbuf, pbuf, cnt);
863 
864 	err = sd_write(pintfhdl, addr, cnt, ptmpbuf);
865 
866 	if (ptmpbuf)
867 		rtw_mfree(ptmpbuf, cnt);
868 
869 	return err;
870 }
871 
SdioLocalCmd52Read1Byte(PADAPTER padapter,u32 addr)872 u8 SdioLocalCmd52Read1Byte(PADAPTER padapter, u32 addr)
873 {
874 	u8 val = 0;
875 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
876 
877 	HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
878 	sd_cmd52_read(pintfhdl, addr, 1, &val);
879 
880 	return val;
881 }
882 
SdioLocalCmd52Read2Byte(PADAPTER padapter,u32 addr)883 u16 SdioLocalCmd52Read2Byte(PADAPTER padapter, u32 addr)
884 {
885 	u16 val = 0;
886 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
887 
888 	HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
889 	sd_cmd52_read(pintfhdl, addr, 2, (u8 *)&val);
890 
891 	val = le16_to_cpu(val);
892 
893 	return val;
894 }
895 
SdioLocalCmd52Read4Byte(PADAPTER padapter,u32 addr)896 u32 SdioLocalCmd52Read4Byte(PADAPTER padapter, u32 addr)
897 {
898 	u32 val = 0;
899 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
900 
901 	HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
902 	sd_cmd52_read(pintfhdl, addr, 4, (u8 *)&val);
903 
904 	val = le32_to_cpu(val);
905 
906 	return val;
907 }
908 
SdioLocalCmd53Read4Byte(PADAPTER padapter,u32 addr)909 u32 SdioLocalCmd53Read4Byte(PADAPTER padapter, u32 addr)
910 {
911 
912 	u8 bMacPwrCtrlOn;
913 	u32 val = 0;
914 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
915 
916 	HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
917 	bMacPwrCtrlOn = _FALSE;
918 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
919 	if ((_FALSE == bMacPwrCtrlOn)
920 		#ifdef CONFIG_LPS_LCLK
921 		|| (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE)
922 		#endif
923 		|| CONFIG_RTW_SDIO_REG_FORCE_CMD52
924 	) {
925 		sd_cmd52_read(pintfhdl, addr, 4, (u8 *)&val);
926 		val = le32_to_cpu(val);
927 	} else
928 		val = sd_read32(pintfhdl, addr, NULL);
929 
930 	return val;
931 }
932 
SdioLocalCmd52Write1Byte(PADAPTER padapter,u32 addr,u8 v)933 void SdioLocalCmd52Write1Byte(PADAPTER padapter, u32 addr, u8 v)
934 {
935 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
936 
937 	HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
938 	sd_cmd52_write(pintfhdl, addr, 1, &v);
939 }
940 
SdioLocalCmd52Write2Byte(PADAPTER padapter,u32 addr,u16 v)941 void SdioLocalCmd52Write2Byte(PADAPTER padapter, u32 addr, u16 v)
942 {
943 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
944 
945 	HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
946 	v = cpu_to_le16(v);
947 	sd_cmd52_write(pintfhdl, addr, 2, (u8 *)&v);
948 }
949 
SdioLocalCmd52Write4Byte(PADAPTER padapter,u32 addr,u32 v)950 void SdioLocalCmd52Write4Byte(PADAPTER padapter, u32 addr, u32 v)
951 {
952 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
953 	HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
954 	v = cpu_to_le32(v);
955 	sd_cmd52_write(pintfhdl, addr, 4, (u8 *)&v);
956 }
957 
sdio_set_intf_ops(_adapter * padapter,struct _io_ops * pops)958 void sdio_set_intf_ops(_adapter *padapter, struct _io_ops *pops)
959 {
960 
961 	pops->_read8 = &sdio_read8;
962 	pops->_read16 = &sdio_read16;
963 	pops->_read32 = &sdio_read32;
964 	pops->_read_mem = &sdio_read_mem;
965 	pops->_read_port = &sdio_read_port;
966 
967 	pops->_write8 = &sdio_write8;
968 	pops->_write16 = &sdio_write16;
969 	pops->_write32 = &sdio_write32;
970 	pops->_writeN = &sdio_writeN;
971 	pops->_write_mem = &sdio_write_mem;
972 	pops->_write_port = &sdio_write_port;
973 
974 	pops->_sd_f0_read8 = sdio_f0_read8;
975 
976 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
977 	pops->_sd_iread8 = sdio_iread8;
978 	pops->_sd_iread16 = sdio_iread16;
979 	pops->_sd_iread32 = sdio_iread32;
980 	pops->_sd_iwrite8 = sdio_iwrite8;
981 	pops->_sd_iwrite16 = sdio_iwrite16;
982 	pops->_sd_iwrite32 = sdio_iwrite32;
983 #endif
984 
985 }
986 
987 /*
988  *	Description:
989  *		Initialize SDIO Host Interrupt Mask configuration variables for future use.
990  *
991  *	Assumption:
992  *		Using SDIO Local register ONLY for configuration.
993  *
994  *	Created by Roger, 2011.02.11.
995  *   */
InitInterrupt8188FSdio(PADAPTER padapter)996 void InitInterrupt8188FSdio(PADAPTER padapter)
997 {
998 	PHAL_DATA_TYPE pHalData;
999 
1000 	pHalData = GET_HAL_DATA(padapter);
1001 	pHalData->sdio_himr = 0
1002 		| SDIO_HIMR_RX_REQUEST_MSK
1003 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
1004 		| SDIO_HIMR_AVAL_MSK
1005 #endif
1006 #if 0
1007 		| SDIO_HIMR_TXERR_MSK
1008 		| SDIO_HIMR_RXERR_MSK
1009 		| SDIO_HIMR_TXFOVW_MSK
1010 		| SDIO_HIMR_RXFOVW_MSK
1011 		| SDIO_HIMR_TXBCNOK_MSK
1012 		| SDIO_HIMR_TXBCNERR_MSK
1013 		| SDIO_HIMR_BCNERLY_INT_MSK
1014 		| SDIO_HIMR_C2HCMD_MSK
1015 #endif
1016 #if defined(CONFIG_LPS_LCLK) && !defined(CONFIG_DETECT_CPWM_BY_POLLING)
1017 		| SDIO_HIMR_CPWM1_MSK
1018 #endif
1019 #ifdef CONFIG_WOWLAN
1020 		| SDIO_HIMR_CPWM2_MSK
1021 #endif
1022 #if 0
1023 		| SDIO_HIMR_HSISR_IND_MSK
1024 		| SDIO_HIMR_GTINT3_IND_MSK
1025 		| SDIO_HIMR_GTINT4_IND_MSK
1026 		| SDIO_HIMR_PSTIMEOUT_MSK
1027 		| SDIO_HIMR_OCPINT_MSK
1028 		| SDIO_HIMR_ATIMEND_MSK
1029 		| SDIO_HIMR_ATIMEND_E_MSK
1030 		| SDIO_HIMR_CTWEND_MSK
1031 #endif
1032 		;
1033 }
1034 
1035 /*
1036  *	Description:
1037  *		Initialize System Host Interrupt Mask configuration variables for future use.
1038  *
1039  *	Created by Roger, 2011.08.03.
1040  *   */
InitSysInterrupt8188FSdio(PADAPTER padapter)1041 void InitSysInterrupt8188FSdio(PADAPTER padapter)
1042 {
1043 	PHAL_DATA_TYPE pHalData;
1044 
1045 
1046 	pHalData = GET_HAL_DATA(padapter);
1047 
1048 	pHalData->SysIntrMask = (\
1049 				 /*							HSIMR_GPIO12_0_INT_EN			|
1050 				  *							HSIMR_SPS_OCP_INT_EN			|
1051 				  *							HSIMR_RON_INT_EN				|
1052 				  *							HSIMR_PDNINT_EN				|
1053 				  *							HSIMR_GPIO9_INT_EN				| */
1054 				 0);
1055 }
1056 
1057 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1058 /*
1059  *	Description:
1060  *		Clear corresponding SDIO Host ISR interrupt service.
1061  *
1062  *	Assumption:
1063  *		Using SDIO Local register ONLY for configuration.
1064  *
1065  *	Created by Roger, 2011.02.11.
1066  *   */
ClearInterrupt8188FSdio(PADAPTER padapter)1067 void ClearInterrupt8188FSdio(PADAPTER padapter)
1068 {
1069 	PHAL_DATA_TYPE pHalData;
1070 	u8 *clear;
1071 
1072 
1073 	if (rtw_is_surprise_removed(padapter))
1074 		return;
1075 
1076 	pHalData = GET_HAL_DATA(padapter);
1077 	clear = rtw_zmalloc(4);
1078 
1079 	/* Clear corresponding HISR Content if needed */
1080 	*(u32 *)clear = cpu_to_le32(pHalData->sdio_hisr & MASK_SDIO_HISR_CLEAR);
1081 	if (*(u32 *)clear) {
1082 		/* Perform write one clear operation */
1083 		sdio_local_write(padapter, SDIO_REG_HISR, 4, clear);
1084 	}
1085 
1086 	rtw_mfree(clear, 4);
1087 }
1088 #endif
1089 
1090 /*
1091  *	Description:
1092  *		Clear corresponding system Host ISR interrupt service.
1093  *
1094  *
1095  *	Created by Roger, 2011.02.11.
1096  *   */
ClearSysInterrupt8188FSdio(PADAPTER padapter)1097 void ClearSysInterrupt8188FSdio(PADAPTER padapter)
1098 {
1099 	PHAL_DATA_TYPE pHalData;
1100 	u32 clear;
1101 
1102 
1103 	if (rtw_is_surprise_removed(padapter))
1104 		return;
1105 
1106 	pHalData = GET_HAL_DATA(padapter);
1107 
1108 	/* Clear corresponding HISR Content if needed */
1109 	clear = pHalData->SysIntrStatus & MASK_HSISR_CLEAR;
1110 	if (clear) {
1111 		/* Perform write one clear operation */
1112 		rtw_write32(padapter, REG_HSISR, clear);
1113 	}
1114 }
1115 
1116 /*
1117  *	Description:
1118  *		Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain.
1119  *
1120  *	Assumption:
1121  *		1. Using SDIO Local register ONLY for configuration.
1122  *		2. PASSIVE LEVEL
1123  *
1124  *	Created by Roger, 2011.02.11.
1125  *   */
EnableInterrupt8188FSdio(PADAPTER padapter)1126 void EnableInterrupt8188FSdio(PADAPTER padapter)
1127 {
1128 	PHAL_DATA_TYPE pHalData;
1129 	u32 himr;
1130 
1131 	pHalData = GET_HAL_DATA(padapter);
1132 
1133 	himr = cpu_to_le32(pHalData->sdio_himr);
1134 	sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
1135 
1136 
1137 	/* Update current system IMR settings */
1138 	himr = rtw_read32(padapter, REG_HSIMR);
1139 	rtw_write32(padapter, REG_HSIMR, himr | pHalData->SysIntrMask);
1140 
1141 
1142 	/*  */
1143 	/* <Roger_Notes> There are some C2H CMDs have been sent before system interrupt is enabled, e.g., C2H, CPWM. */
1144 	/* So we need to clear all C2H events that FW has notified, otherwise FW won't schedule any commands anymore. */
1145 	/* 2011.10.19. */
1146 	/*  */
1147 	rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1148 }
1149 
1150 /*
1151  *	Description:
1152  *		Disable SDIO Host IMR configuration to mask unnecessary interrupt service.
1153  *
1154  *	Assumption:
1155  *		Using SDIO Local register ONLY for configuration.
1156  *
1157  *	Created by Roger, 2011.02.11.
1158  *   */
DisableInterrupt8188FSdio(PADAPTER padapter)1159 void DisableInterrupt8188FSdio(PADAPTER padapter)
1160 {
1161 	u32 himr;
1162 
1163 	himr = cpu_to_le32(SDIO_HIMR_DISABLED);
1164 	sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
1165 
1166 }
1167 
1168 /*
1169  *	Description:
1170  *		Using 0x100 to check the power status of FW.
1171  *
1172  *	Assumption:
1173  *		Using SDIO Local register ONLY for configuration.
1174  *
1175  *	Created by Isaac, 2013.09.10.
1176  *   */
CheckIPSStatus(PADAPTER padapter)1177 u8 CheckIPSStatus(PADAPTER padapter)
1178 {
1179 	RTW_INFO("%s(): Read 0x100=0x%02x 0x86=0x%02x\n", __func__,
1180 		 rtw_read8(padapter, 0x100), rtw_read8(padapter, 0x86));
1181 
1182 	if (rtw_read8(padapter, 0x100) == 0xEA)
1183 		return _TRUE;
1184 	else
1185 		return _FALSE;
1186 }
1187 
1188 #ifdef CONFIG_WOWLAN
DisableInterruptButCpwm28188FSdio(PADAPTER padapter)1189 void DisableInterruptButCpwm28188FSdio(PADAPTER padapter)
1190 {
1191 	u32 himr, tmp;
1192 
1193 	sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
1194 	RTW_INFO("DisableInterruptButCpwm28188FSdio(): Read SDIO_REG_HIMR: 0x%08x\n", tmp);
1195 
1196 	himr = cpu_to_le32(SDIO_HIMR_DISABLED) | SDIO_HIMR_CPWM2_MSK;
1197 	sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
1198 
1199 	sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
1200 	RTW_INFO("DisableInterruptButCpwm28188FSdio(): Read again SDIO_REG_HIMR: 0x%08x\n", tmp);
1201 }
1202 #endif /* CONFIG_WOWLAN
1203  *
1204  *	Description:
1205  *		Update SDIO Host Interrupt Mask configuration on SDIO local domain.
1206  *
1207  *	Assumption:
1208  *		1. Using SDIO Local register ONLY for configuration.
1209  *		2. PASSIVE LEVEL
1210  *
1211  *	Created by Roger, 2011.02.11.
1212  *   */
UpdateInterruptMask8188FSdio(PADAPTER padapter,u32 AddMSR,u32 RemoveMSR)1213 void UpdateInterruptMask8188FSdio(PADAPTER padapter, u32 AddMSR, u32 RemoveMSR)
1214 {
1215 	HAL_DATA_TYPE *pHalData;
1216 
1217 	pHalData = GET_HAL_DATA(padapter);
1218 
1219 	if (AddMSR)
1220 		pHalData->sdio_himr |= AddMSR;
1221 
1222 	if (RemoveMSR)
1223 		pHalData->sdio_himr &= (~RemoveMSR);
1224 
1225 	DisableInterrupt8188FSdio(padapter);
1226 	EnableInterrupt8188FSdio(padapter);
1227 }
1228 
1229 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
sd_recv_loopback(PADAPTER padapter,u32 size)1230 static void sd_recv_loopback(PADAPTER padapter, u32 size)
1231 {
1232 	PLOOPBACKDATA ploopback;
1233 	u32 readsize, allocsize;
1234 	u8 *preadbuf;
1235 
1236 
1237 	readsize = size;
1238 	RTW_INFO("%s: read size=%d\n", __func__, readsize);
1239 	allocsize = _RND(readsize, rtw_sdio_get_block_size(adapter_to_dvobj(padapter)));
1240 
1241 	ploopback = padapter->ploopback;
1242 	if (ploopback) {
1243 		ploopback->rxsize = readsize;
1244 		preadbuf = ploopback->rxbuf;
1245 	} else {
1246 		preadbuf = rtw_malloc(allocsize);
1247 		if (preadbuf == NULL) {
1248 			RTW_INFO("%s: malloc fail size=%d\n", __func__, allocsize);
1249 			return;
1250 		}
1251 	}
1252 
1253 	/*	rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); */
1254 	sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
1255 
1256 	if (ploopback)
1257 		_rtw_up_sema(&ploopback->sema);
1258 	else {
1259 		u32 i;
1260 
1261 		RTW_INFO("%s: drop pkt\n", __func__);
1262 		for (i = 0; i < readsize; i += 4) {
1263 			RTW_INFO("%08X", *(u32 *)(preadbuf + i));
1264 			if ((i + 4) & 0x1F)
1265 				printk(" ");
1266 			else
1267 				printk("\n");
1268 		}
1269 		printk("\n");
1270 		rtw_mfree(preadbuf, allocsize);
1271 	}
1272 }
1273 #endif /* CONFIG_MAC_LOOPBACK_DRIVER */
1274 
1275 #ifdef CONFIG_SDIO_RX_COPY
sd_recv_alloc_buf(_adapter * adapter,u32 size,struct recv_buf ** recvbuf_ret)1276 static u32 sd_recv_alloc_buf(_adapter *adapter, u32 size, struct recv_buf **recvbuf_ret)
1277 {
1278 #ifndef CONFIG_TEST_RBUF_UNAVAIL
1279 #define CONFIG_TEST_RBUF_UNAVAIL 0
1280 #endif
1281 
1282 #if CONFIG_TEST_RBUF_UNAVAIL
1283 #define TEST_RBUF_UNAVAIL_CYCLE_MS (10 * 1000)
1284 #define TEST_RBUF_UNAVAIL_TIME_MS (50)
1285 	static systime test_start = 0;
1286 #endif
1287 	struct recv_priv *precvpriv;
1288 	struct recv_buf	*precvbuf;
1289 	u32 ret;
1290 
1291 	*recvbuf_ret = NULL;
1292 
1293 #if CONFIG_TEST_RBUF_UNAVAIL
1294 	if (test_start == 0)
1295 		test_start = rtw_get_current_time();
1296 
1297 	if (rtw_get_passing_time_ms(test_start) >= TEST_RBUF_UNAVAIL_CYCLE_MS) {
1298 		if (rtw_get_passing_time_ms(test_start) >= TEST_RBUF_UNAVAIL_CYCLE_MS + TEST_RBUF_UNAVAIL_TIME_MS)
1299 			test_start = rtw_get_current_time();
1300 		ret = RTW_RBUF_UNAVAIL;
1301 		goto exit;
1302 	}
1303 #endif
1304 
1305 	precvpriv = &adapter->recvpriv;
1306 #ifdef CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST
1307 alloc_recvbuf:
1308 #endif
1309 	/* alloc recvbuf */
1310 	precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
1311 	if (precvbuf == NULL) {
1312 		if (0)
1313 			RTW_INFO("%s: recvbuf unavailable\n", __func__);
1314 		ret = RTW_RBUF_UNAVAIL;
1315 		goto exit;
1316 	}
1317 
1318 #ifdef CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST
1319 	if (precvbuf->type == RBUF_TYPE_PWAIT_ADJ) {
1320 		recvbuf_pwait_config_hdl(precvpriv, precvbuf);
1321 		goto alloc_recvbuf;
1322 	}
1323 #endif
1324 
1325 	if (precvbuf->pskb == NULL) {
1326 		/*  alloc skb */
1327 		SIZE_PTR tmpaddr = 0;
1328 		SIZE_PTR alignment = 0;
1329 
1330 		precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
1331 		if (precvbuf->pskb == NULL) {
1332 			RTW_INFO("%s: alloc_skb fail! size=%d\n", __func__, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
1333 			rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
1334 			ret = RTW_RBUF_PKT_UNAVAIL;
1335 			goto exit;
1336 		}
1337 
1338 		precvbuf->pskb->dev = adapter->pnetdev;
1339 
1340 		tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
1341 		alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
1342 		skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
1343 
1344 		/* init recvbuf */
1345 		precvbuf->phead = precvbuf->pskb->head;
1346 		precvbuf->pdata = precvbuf->pskb->data;
1347 		precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
1348 		precvbuf->pend = skb_end_pointer(precvbuf->pskb);
1349 		precvbuf->len = 0;
1350 
1351 	} else {
1352 		/* reset recvbuf to len 0*/
1353 		precvbuf->len = 0;
1354 		precvbuf->pdata = precvbuf->pskb->data;
1355 		skb_set_tail_pointer(precvbuf->pskb, 0);
1356 		precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
1357 	}
1358 
1359 	*recvbuf_ret = precvbuf;
1360 	ret = _SUCCESS;
1361 
1362 exit:
1363 	return ret;
1364 }
1365 
sd_recv_rxfifo(_adapter * adapter,struct recv_buf * rbuf,u32 read_sz,u32 ocp_sz)1366 static u32 sd_recv_rxfifo(_adapter *adapter, struct recv_buf *rbuf, u32 read_sz, u32 ocp_sz)
1367 {
1368 	struct recv_priv *precvpriv = &adapter->recvpriv;
1369 	u32 ret;
1370 
1371 	/* read data from rxfifo */
1372 	/*	rtw_read_port(adapter, WLAN_RX0FF_DEVICE_ID, read_sz, rbuf->data); */
1373 	ret = sdio_read_port_no_align(&adapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, read_sz, rbuf->ptail);
1374 	if (ret == _FAIL) {
1375 		rtw_enqueue_recvbuf(rbuf, &precvpriv->free_recv_buf_queue);
1376 		goto exit;
1377 	}
1378 
1379 	/* increase recvbuf len */
1380 	skb_put(rbuf->pskb, ocp_sz);
1381 	rbuf->ptail = skb_tail_pointer(rbuf->pskb);
1382 	rbuf->len += ocp_sz;
1383 
1384 exit:
1385 	return ret;
1386 }
1387 #else /* !CONFIG_SDIO_RX_COPY */
sd_recv_rxfifo(PADAPTER padapter,u32 size)1388 static struct recv_buf *sd_recv_rxfifo(PADAPTER padapter, u32 size)
1389 {
1390 	u32 readsize, allocsize, ret;
1391 	u8 *preadbuf;
1392 	_pkt *ppkt;
1393 	struct recv_priv *precvpriv;
1394 	struct recv_buf	*precvbuf;
1395 
1396 	/* 3 1. alloc skb */
1397 	/* align to block size */
1398 	allocsize = rtw_sdio_cmd53_align_size(adapter_to_dvobj(padapter), readsize);
1399 
1400 	ppkt = rtw_skb_alloc(allocsize);
1401 
1402 	if (ppkt == NULL) {
1403 		return NULL;
1404 	}
1405 
1406 	/* 3 2. read data from rxfifo */
1407 	preadbuf = skb_put(ppkt, size);
1408 	/*	rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); */
1409 	ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
1410 	if (ret == _FAIL) {
1411 		rtw_skb_free(ppkt);
1412 		return NULL;
1413 	}
1414 
1415 	/* 3 3. alloc recvbuf */
1416 	precvpriv = &padapter->recvpriv;
1417 	precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
1418 	if (precvbuf == NULL) {
1419 		rtw_skb_free(ppkt);
1420 		RTW_ERR("%s: alloc recvbuf FAIL!\n", __FUNCTION__);
1421 		return NULL;
1422 	}
1423 
1424 	/* 3 4. init recvbuf */
1425 	precvbuf->pskb = ppkt;
1426 
1427 	precvbuf->len = ppkt->len;
1428 
1429 	precvbuf->phead = ppkt->head;
1430 	precvbuf->pdata = ppkt->data;
1431 	precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
1432 	precvbuf->pend = skb_end_pointer(precvbuf->pskb);
1433 
1434 	return precvbuf;
1435 }
1436 #endif /* !CONFIG_SDIO_RX_COPY */
1437 
sd_rxhandler(PADAPTER padapter,struct recv_buf * precvbuf)1438 static void sd_rxhandler(PADAPTER padapter, struct recv_buf *precvbuf)
1439 {
1440 	struct recv_priv *precvpriv;
1441 	_queue *ppending_queue;
1442 
1443 
1444 	precvpriv = &padapter->recvpriv;
1445 	ppending_queue = &precvpriv->recv_buf_pending_queue;
1446 
1447 	/* 3 1. enqueue recvbuf */
1448 	rtw_enqueue_recvbuf(precvbuf, ppending_queue);
1449 
1450 	/* 3 2. trigger recv hdl */
1451 #ifdef CONFIG_RECV_THREAD_MODE
1452 	_rtw_up_sema(&precvpriv->recv_sema);
1453 #else
1454 	#ifdef PLATFORM_LINUX
1455 	tasklet_schedule(&precvpriv->recv_tasklet);
1456 	#endif
1457 #endif
1458 }
1459 
1460 #ifndef SD_INT_HDL_DIS_HIMR_RX_REQ
1461 #define SD_INT_HDL_DIS_HIMR_RX_REQ 0
1462 #endif
1463 
1464 #ifndef CMD52_ACCESS_HISR_RX_REQ_LEN
1465 #define CMD52_ACCESS_HISR_RX_REQ_LEN 0
1466 #endif
1467 
1468 #if SD_INT_HDL_DIS_HIMR_RX_REQ
1469 #define DIS_HIMR_RX_REQ_WITH_CMD52 1
disable_himr_rx_req_8188f_sdio(_adapter * adapter)1470 static void disable_himr_rx_req_8188f_sdio(_adapter *adapter)
1471 {
1472 	HAL_DATA_TYPE *hal = GET_HAL_DATA(adapter);
1473 	u32 himr = cpu_to_le32(hal->sdio_himr & ~SDIO_HISR_RX_REQUEST);
1474 
1475 #if DIS_HIMR_RX_REQ_WITH_CMD52
1476 	SdioLocalCmd52Write1Byte(adapter, SDIO_REG_HIMR, *((u8 *)&himr));
1477 #else
1478 	sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
1479 #endif
1480 }
1481 
restore_himr_8188f_sdio(_adapter * adapter)1482 static void restore_himr_8188f_sdio(_adapter *adapter)
1483 {
1484 	HAL_DATA_TYPE *hal = GET_HAL_DATA(adapter);
1485 	u32 himr = cpu_to_le32(hal->sdio_himr);
1486 
1487 #if DIS_HIMR_RX_REQ_WITH_CMD52
1488 	SdioLocalCmd52Write1Byte(adapter, SDIO_REG_HIMR, *((u8 *)&himr));
1489 #else
1490 	sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
1491 #endif
1492 }
1493 #endif /* SD_INT_HDL_DIS_HIMR_RX_REQ */
1494 
1495 #if CMD52_ACCESS_HISR_RX_REQ_LEN
ReadInterrupt8188FSdio(PADAPTER padapter,u32 * phisr)1496 static s32 ReadInterrupt8188FSdio(PADAPTER padapter, u32 *phisr)
1497 {
1498 	u32 hisr, himr;
1499 	u8 val8, hisr_len;
1500 	int i;
1501 
1502 	if (phisr == NULL)
1503 		return _FALSE;
1504 
1505 	himr = GET_HAL_DATA(padapter)->sdio_himr;
1506 
1507 	/* decide how many bytes need to be read */
1508 	hisr_len = 0;
1509 	while (himr) {
1510 		hisr_len++;
1511 		himr >>= 8;
1512 	}
1513 
1514 	hisr = 0;
1515 	for (i = 0; i < hisr_len; i++) {
1516 		val8 = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR + i);
1517 		hisr |= (val8 << (8 * i));
1518 	}
1519 
1520 	*phisr = hisr;
1521 
1522 	return _TRUE;
1523 }
1524 #endif /* CMD52_ACCESS_HISR_RX_REQ_LEN */
1525 
sd_recv(_adapter * adapter)1526 void sd_recv(_adapter *adapter)
1527 {
1528 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
1529 	struct recv_priv *recvpriv = &adapter->recvpriv;
1530 	struct recv_buf *rbuf = NULL;
1531 	u32 read_sz, ocp_sz, buf_sz;
1532 	u32 recv_fail_cnt = 0;
1533 	u32 rx_cnt = 0;
1534 	u32 ret;
1535 
1536 	do {
1537 		if (phal->SdioRxFIFOSize == 0) {
1538 			#if CMD52_ACCESS_HISR_RX_REQ_LEN
1539 			u16 rx_req_len;
1540 
1541 			rx_req_len = SdioLocalCmd52Read2Byte(adapter, SDIO_REG_RX0_REQ_LEN);
1542 			if (rx_req_len) {
1543 				if (rx_req_len % 256 == 0)
1544 					rx_req_len += SdioLocalCmd52Read1Byte(adapter, SDIO_REG_RX0_REQ_LEN);
1545 				phal->SdioRxFIFOSize = rx_req_len;
1546 			}
1547 			#else
1548 			u8 data[4];
1549 
1550 			_sdio_local_read(adapter, SDIO_REG_RX0_REQ_LEN, 4, data);
1551 			phal->SdioRxFIFOSize = le16_to_cpu(*(u16 *)data);
1552 			#endif
1553 
1554 			if (phal->SdioRxFIFOSize == 0)
1555 				break;
1556 		}
1557 
1558 		#ifdef CONFIG_MAC_LOOPBACK_DRIVER
1559 		sd_recv_loopback(adapter, phal->SdioRxFIFOSize);
1560 		#else
1561 		read_sz = rtw_sdio_cmd53_align_size(adapter_to_dvobj(adapter), phal->SdioRxFIFOSize);
1562 		read_sz = RND4(read_sz); /* Patch for some SDIO Host 4 bytes issue, ex. RK3188 */
1563 		ocp_sz = _RND8(phal->SdioRxFIFOSize);
1564 		buf_sz = rtw_max(read_sz, ocp_sz);
1565 		if (buf_sz > MAX_RECVBUF_SZ) {
1566 			RTW_INFO(FUNC_ADPT_FMT" %u > MAX_RECVBUF_SZ(%u)\n", FUNC_ADPT_ARG(adapter), buf_sz, MAX_RECVBUF_SZ);
1567 			rtw_warn_on(1);
1568 		}
1569 
1570 		if (rbuf
1571 			&& (!recv_buf_agg(recvpriv)
1572 				|| _rtw_queue_empty(&recvpriv->recv_buf_pending_queue)
1573 				|| rbuf->ptail + buf_sz > rbuf->pend
1574 				)
1575 		) {
1576 			sd_rxhandler(adapter, rbuf);
1577 			rbuf = NULL;
1578 		}
1579 
1580 		if (!rbuf) {
1581 			struct rtw_pwait_ctx *pwctx = &recvpriv->recvbuf_pwait;
1582 
1583 			rtw_pwctx_reset(pwctx);
1584 			while (sd_recv_alloc_buf(adapter, buf_sz, &rbuf) != _SUCCESS) {
1585 				if (rtw_pwctx_exceed(&recvpriv->recvbuf_pwait)) {
1586 					if (rx_cnt)
1587 						break;
1588 				}
1589 				rtw_pwctx_wait(&recvpriv->recvbuf_pwait);
1590 			}
1591 			if (!rbuf)
1592 				break;
1593 		}
1594 
1595 		ret = sd_recv_rxfifo(adapter, rbuf, read_sz, ocp_sz);
1596 		if (ret == _SUCCESS) {
1597 			if (!recv_buf_agg(recvpriv)
1598 				|| _rtw_queue_empty(&recvpriv->recv_buf_pending_queue)
1599 				|| rbuf->ptail >= rbuf->pend
1600 			) {
1601 				sd_rxhandler(adapter, rbuf);
1602 				rbuf = NULL;
1603 			}
1604 			rx_cnt++;
1605 			phal->SdioRxFIFOSize = 0;
1606 		} else {
1607 			recv_fail_cnt++;
1608 			RTW_WARN("%s: recv fail! cnt:%u\n", __func__, recv_fail_cnt);
1609 			phal->SdioRxFIFOSize = 0;
1610 			if (recv_fail_cnt >= 10) {
1611 				RTW_WARN("%s: exit because recv_fail_cnt=%u! (rx_cnt=%u)\n"
1612 					, __func__, recv_fail_cnt, rx_cnt);
1613 				break;
1614 			}
1615 		}
1616 		#endif
1617 	} while (1);
1618 
1619 	if (rbuf)
1620 		sd_rxhandler(adapter, rbuf);
1621 }
1622 
sd_int_dpc(PADAPTER padapter)1623 void sd_int_dpc(PADAPTER padapter)
1624 {
1625 	PHAL_DATA_TYPE phal;
1626 	struct dvobj_priv *dvobj;
1627 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
1628 	struct pwrctrl_priv *pwrctl;
1629 
1630 
1631 	phal = GET_HAL_DATA(padapter);
1632 	dvobj = adapter_to_dvobj(padapter);
1633 	pwrctl = dvobj_to_pwrctl(dvobj);
1634 
1635 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
1636 	if (phal->sdio_hisr & SDIO_HISR_AVAL) {
1637 		u8 freepage[8];
1638 
1639 		_sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 8, freepage);
1640 		#ifdef DBG_TX_FREE_PAGE
1641 		RTW_INFO("SDIO_HISR_AVAL, Tx Free Page = H:%u, M:%u, L:%u, P:%u\n",
1642 			freepage[0], freepage[2], freepage[4], freepage[6]);
1643 		#endif
1644 
1645 		_rtw_up_sema(&(padapter->xmitpriv.xmit_sema));
1646 	}
1647 #endif
1648 
1649 	if (phal->sdio_hisr & SDIO_HISR_CPWM1) {
1650 		struct reportpwrstate_parm report;
1651 
1652 #ifdef CONFIG_LPS_RPWM_TIMER
1653 		_cancel_timer_ex(&(pwrctl->pwr_rpwm_timer));
1654 #endif /* CONFIG_LPS_RPWM_TIMER */
1655 
1656 		report.state = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HCPWM1_8188F);
1657 
1658 #ifdef CONFIG_LPS_LCLK
1659 		/* cpwm_int_hdl(padapter, &report); */
1660 		_set_workitem(&(pwrctl->cpwm_event));
1661 #endif
1662 	}
1663 
1664 	if (phal->sdio_hisr & SDIO_HISR_TXERR) {
1665 		u8 *status;
1666 		u32 addr;
1667 
1668 		status = rtw_malloc(4);
1669 		if (status) {
1670 			addr = REG_TXDMA_STATUS;
1671 			HalSdioGetCmdAddr8188FSdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
1672 			_sd_read(pintfhdl, addr, 4, status);
1673 			_sd_write(pintfhdl, addr, 4, status);
1674 			RTW_INFO("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32 *)status));
1675 			rtw_mfree(status, 4);
1676 		} else
1677 			RTW_INFO("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
1678 	}
1679 
1680 	if (phal->sdio_hisr & SDIO_HISR_TXBCNOK)
1681 		RTW_INFO("%s: SDIO_HISR_TXBCNOK\n", __func__);
1682 
1683 	if (phal->sdio_hisr & SDIO_HISR_TXBCNERR)
1684 		RTW_INFO("%s: SDIO_HISR_TXBCNERR\n", __func__);
1685 
1686 #ifdef CONFIG_FW_C2H_REG
1687 	if (phal->sdio_hisr & SDIO_HISR_C2HCMD) {
1688 		RTW_INFO("%s: C2H Command\n", __func__);
1689 		sd_c2h_hisr_hdl(padapter);
1690 	}
1691 #endif
1692 
1693 	if (phal->sdio_hisr & SDIO_HISR_RXFOVW)
1694 		RTW_INFO("%s: Rx Overflow\n", __func__);
1695 	if (phal->sdio_hisr & SDIO_HISR_RXERR)
1696 		RTW_INFO("%s: Rx Error\n", __func__);
1697 
1698 	if (phal->sdio_hisr & SDIO_HISR_RX_REQUEST) {
1699 		phal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
1700 		sd_recv(padapter);
1701 	}
1702 }
1703 
1704 #ifndef DBG_SD_INT_HISR_HIMR
1705 #define DBG_SD_INT_HISR_HIMR 0
1706 #endif
1707 
sd_int_hdl(PADAPTER padapter)1708 void sd_int_hdl(PADAPTER padapter)
1709 {
1710 	PHAL_DATA_TYPE phal;
1711 	#if !CMD52_ACCESS_HISR_RX_REQ_LEN
1712 	u8 data[6];
1713 	#endif
1714 
1715 	if (RTW_CANNOT_RUN(padapter))
1716 		return;
1717 
1718 	phal = GET_HAL_DATA(padapter);
1719 
1720 	#if SD_INT_HDL_DIS_HIMR_RX_REQ
1721 	disable_himr_rx_req_8188f_sdio(padapter);
1722 	#endif
1723 
1724 	#if CMD52_ACCESS_HISR_RX_REQ_LEN
1725 	phal->sdio_hisr = 0;
1726 	ReadInterrupt8188FSdio(padapter, &phal->sdio_hisr);
1727 	#else
1728 	_sdio_local_read(padapter, SDIO_REG_HISR, 6, data);
1729 	phal->sdio_hisr = le32_to_cpu(*(u32 *)data);
1730 	phal->SdioRxFIFOSize = le16_to_cpu(*(u16 *)&data[4]);
1731 	#endif
1732 
1733 	if (phal->sdio_hisr & phal->sdio_himr) {
1734 		u32 v32;
1735 		#if DBG_SD_INT_HISR_HIMR
1736 		static u32 match_cnt = 0;
1737 
1738 		if ((match_cnt++) % 1000 == 0)
1739 			RTW_INFO("%s: HISR(0x%08x) and HIMR(0x%08x) match!\n"
1740 				, __func__, phal->sdio_hisr, phal->sdio_himr);
1741 		#endif
1742 
1743 		phal->sdio_hisr &= phal->sdio_himr;
1744 
1745 		/* clear HISR */
1746 		v32 = phal->sdio_hisr & MASK_SDIO_HISR_CLEAR;
1747 		if (v32) {
1748 			#if CMD52_ACCESS_HISR_RX_REQ_LEN
1749 			SdioLocalCmd52Write4Byte(padapter, SDIO_REG_HISR, v32);
1750 			#else
1751 			v32 = cpu_to_le32(v32);
1752 			_sdio_local_write(padapter, SDIO_REG_HISR, 4, (u8 *)&v32);
1753 			#endif
1754 		}
1755 
1756 		sd_int_dpc(padapter);
1757 	}
1758 	#if DBG_SD_INT_HISR_HIMR
1759 	else
1760 		RTW_INFO("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n"
1761 			, __func__, phal->sdio_hisr, phal->sdio_himr);
1762 	#endif
1763 
1764 	#if SD_INT_HDL_DIS_HIMR_RX_REQ
1765 	restore_himr_8188f_sdio(padapter);
1766 	#endif
1767 }
1768 
1769 /*
1770  *	Description:
1771  *		Query SDIO Local register to query current the number of Free TxPacketBuffer page.
1772  *
1773  *	Assumption:
1774  *		1. Running at PASSIVE_LEVEL
1775  *		2. RT_TX_SPINLOCK is NOT acquired.
1776  *
1777  *	Created by Roger, 2011.01.28.
1778  *   */
HalQueryTxBufferStatus8188FSdio(PADAPTER padapter)1779 u8 HalQueryTxBufferStatus8188FSdio(PADAPTER padapter)
1780 {
1781 	/* TODO: EXQ */
1782 	PHAL_DATA_TYPE phal;
1783 	u8 NumOfFreePage[8];
1784 	/* _irqL irql; */
1785 
1786 	phal = GET_HAL_DATA(padapter);
1787 
1788 	sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 8, NumOfFreePage);
1789 
1790 	/* _enter_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); */
1791 	phal->SdioTxFIFOFreePage[HI_QUEUE_IDX] = NumOfFreePage[0];
1792 	phal->SdioTxFIFOFreePage[MID_QUEUE_IDX]  = NumOfFreePage[2];
1793 	phal->SdioTxFIFOFreePage[LOW_QUEUE_IDX] = NumOfFreePage[4];
1794 	phal->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] = NumOfFreePage[6];
1795 	/* _exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); */
1796 
1797 	return _TRUE;
1798 }
1799 
1800 /*
1801  *	Description:
1802  *		Query SDIO Local register to get the current number of TX OQT Free Space.
1803  *   */
HalQueryTxOQTBufferStatus8188FSdio(PADAPTER padapter)1804 u8 HalQueryTxOQTBufferStatus8188FSdio(PADAPTER padapter)
1805 {
1806 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1807 	pHalData->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_AC_OQT_FREEPG_8188F);
1808 	return _TRUE;
1809 }
1810 
1811 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
RecvOnePkt(PADAPTER padapter)1812 u8 RecvOnePkt(PADAPTER padapter)
1813 {
1814 	struct recv_buf *precvbuf;
1815 	struct dvobj_priv *psddev;
1816 	PSDIO_DATA psdio_data;
1817 	struct sdio_func *func;
1818 	u32 tmp = 0;
1819 	u16 len = 0;
1820 	u32 read_sz, ocp_sz, buf_sz;
1821 	u8 res = _FALSE;
1822 
1823 	if (padapter == NULL) {
1824 		RTW_ERR("%s: padapter is NULL!\n", __func__);
1825 		return _FALSE;
1826 	}
1827 
1828 	psddev = adapter_to_dvobj(padapter);
1829 	psdio_data = &psddev->intf_data;
1830 	func = psdio_data->func;
1831 
1832 	/* If RX_DMA is not idle, receive one pkt from DMA */
1833 	res = sdio_local_read(padapter,
1834 			  SDIO_REG_RX0_REQ_LEN, 4, (u8 *)&tmp);
1835 	len = le16_to_cpu(tmp);
1836 	RTW_INFO("+%s: size: %d+\n", __func__, len);
1837 
1838 	if (len) {
1839 		read_sz = rtw_sdio_cmd53_align_size(adapter_to_dvobj(padapter), len);
1840 		read_sz = RND4(read_sz); /* Patch for some SDIO Host 4 bytes issue, ex. RK3188 */
1841 		ocp_sz = _RND8(len);
1842 		buf_sz = rtw_max(read_sz, ocp_sz);
1843 		if (buf_sz > MAX_RECVBUF_SZ) {
1844 			RTW_INFO(FUNC_ADPT_FMT" %u > MAX_RECVBUF_SZ(%u)\n", FUNC_ADPT_ARG(padapter), buf_sz, MAX_RECVBUF_SZ);
1845 			rtw_warn_on(1);
1846 		}
1847 		if (sd_recv_alloc_buf(padapter, buf_sz, &precvbuf) != _SUCCESS) {
1848 			res = _FALSE;
1849 			goto exit;
1850 		}
1851 		sdio_claim_host(func);
1852 		if (sd_recv_rxfifo(padapter, precvbuf, read_sz, ocp_sz) == _SUCCESS) {
1853 			/* printk("Completed Recv One Pkt.\n"); */
1854 			sd_rxhandler(padapter, precvbuf);
1855 			res = _TRUE;
1856 		} else
1857 			res = _FALSE;
1858 		sdio_release_host(func);
1859 	}
1860 
1861 exit:
1862 	RTW_INFO("-%s-\n", __func__);
1863 	return res;
1864 }
1865 #endif /* CONFIG_WOWLAN */
1866