1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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 <drv_types.h>
18 #include <rtw_debug.h>
19 #include <rtl8723b_hal.h>
20 
21 /* define SDIO_DEBUG_IO 1 */
22 
23 
24 /*  */
25 /*  Description: */
26 /* 	The following mapping is for SDIO host local register space. */
27 /*  */
28 /*  Creadted by Roger, 2011.01.31. */
29 /*  */
30 static void HalSdioGetCmdAddr8723BSdio(
31 	struct adapter *padapter,
32 	u8 DeviceID,
33 	u32 Addr,
34 	u32 *pCmdAddr
35 )
36 {
37 	switch (DeviceID) {
38 	case SDIO_LOCAL_DEVICE_ID:
39 		*pCmdAddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (Addr & SDIO_LOCAL_MSK));
40 		break;
41 
42 	case WLAN_IOREG_DEVICE_ID:
43 		*pCmdAddr = ((WLAN_IOREG_DEVICE_ID << 13) | (Addr & WLAN_IOREG_MSK));
44 		break;
45 
46 	case WLAN_TX_HIQ_DEVICE_ID:
47 		*pCmdAddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
48 		break;
49 
50 	case WLAN_TX_MIQ_DEVICE_ID:
51 		*pCmdAddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
52 		break;
53 
54 	case WLAN_TX_LOQ_DEVICE_ID:
55 		*pCmdAddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
56 		break;
57 
58 	case WLAN_RX0FF_DEVICE_ID:
59 		*pCmdAddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (Addr & WLAN_RX0FF_MSK));
60 		break;
61 
62 	default:
63 		break;
64 	}
65 }
66 
67 static u8 get_deviceid(u32 addr)
68 {
69 	u8 devideId;
70 	u16 pseudoId;
71 
72 
73 	pseudoId = (u16)(addr >> 16);
74 	switch (pseudoId) {
75 	case 0x1025:
76 		devideId = SDIO_LOCAL_DEVICE_ID;
77 		break;
78 
79 	case 0x1026:
80 		devideId = WLAN_IOREG_DEVICE_ID;
81 		break;
82 
83 /* 		case 0x1027: */
84 /* 			devideId = SDIO_FIRMWARE_FIFO; */
85 /* 			break; */
86 
87 	case 0x1031:
88 		devideId = WLAN_TX_HIQ_DEVICE_ID;
89 		break;
90 
91 	case 0x1032:
92 		devideId = WLAN_TX_MIQ_DEVICE_ID;
93 		break;
94 
95 	case 0x1033:
96 		devideId = WLAN_TX_LOQ_DEVICE_ID;
97 		break;
98 
99 	case 0x1034:
100 		devideId = WLAN_RX0FF_DEVICE_ID;
101 		break;
102 
103 	default:
104 /* 			devideId = (u8)((addr >> 13) & 0xF); */
105 		devideId = WLAN_IOREG_DEVICE_ID;
106 		break;
107 	}
108 
109 	return devideId;
110 }
111 
112 /*
113  * Ref:
114  *HalSdioGetCmdAddr8723BSdio()
115  */
116 static u32 _cvrt2ftaddr(const u32 addr, u8 *pdeviceId, u16 *poffset)
117 {
118 	u8 deviceId;
119 	u16 offset;
120 	u32 ftaddr;
121 
122 
123 	deviceId = get_deviceid(addr);
124 	offset = 0;
125 
126 	switch (deviceId) {
127 	case SDIO_LOCAL_DEVICE_ID:
128 		offset = addr & SDIO_LOCAL_MSK;
129 		break;
130 
131 	case WLAN_TX_HIQ_DEVICE_ID:
132 	case WLAN_TX_MIQ_DEVICE_ID:
133 	case WLAN_TX_LOQ_DEVICE_ID:
134 		offset = addr & WLAN_FIFO_MSK;
135 		break;
136 
137 	case WLAN_RX0FF_DEVICE_ID:
138 		offset = addr & WLAN_RX0FF_MSK;
139 		break;
140 
141 	case WLAN_IOREG_DEVICE_ID:
142 	default:
143 		deviceId = WLAN_IOREG_DEVICE_ID;
144 		offset = addr & WLAN_IOREG_MSK;
145 		break;
146 	}
147 	ftaddr = (deviceId << 13) | offset;
148 
149 	if (pdeviceId)
150 		*pdeviceId = deviceId;
151 	if (poffset)
152 		*poffset = offset;
153 
154 	return ftaddr;
155 }
156 
157 static u8 sdio_read8(struct intf_hdl *pintfhdl, u32 addr)
158 {
159 	u32 ftaddr;
160 	u8 val;
161 
162 	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
163 	val = sd_read8(pintfhdl, ftaddr, NULL);
164 	return val;
165 }
166 
167 static u16 sdio_read16(struct intf_hdl *pintfhdl, u32 addr)
168 {
169 	u32 ftaddr;
170 	u16 val;
171 	__le16 le_tmp;
172 
173 	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
174 	sd_cmd52_read(pintfhdl, ftaddr, 2, (u8 *)&le_tmp);
175 	val = le16_to_cpu(le_tmp);
176 	return val;
177 }
178 
179 static u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr)
180 {
181 	struct adapter *padapter;
182 	u8 bMacPwrCtrlOn;
183 	u8 deviceId;
184 	u16 offset;
185 	u32 ftaddr;
186 	u8 shift;
187 	u32 val;
188 	s32 err;
189 	__le32 le_tmp;
190 
191 	padapter = pintfhdl->padapter;
192 	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
193 
194 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
195 	if (
196 		((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
197 		(false == bMacPwrCtrlOn) ||
198 		(true == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
199 	) {
200 		err = sd_cmd52_read(pintfhdl, ftaddr, 4, (u8 *)&le_tmp);
201 #ifdef SDIO_DEBUG_IO
202 		if (!err) {
203 #endif
204 			val = le32_to_cpu(le_tmp);
205 			return val;
206 #ifdef SDIO_DEBUG_IO
207 		}
208 
209 		DBG_8192C(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr = 0x%x\n", __func__, err, addr);
210 		return SDIO_ERR_VAL32;
211 #endif
212 	}
213 
214 	/*  4 bytes alignment */
215 	shift = ftaddr & 0x3;
216 	if (shift == 0) {
217 		val = sd_read32(pintfhdl, ftaddr, NULL);
218 	} else {
219 		u8 *ptmpbuf;
220 
221 		ptmpbuf = (u8 *)rtw_malloc(8);
222 		if (NULL == ptmpbuf) {
223 			DBG_8192C(KERN_ERR "%s: Allocate memory FAIL!(size =8) addr = 0x%x\n", __func__, addr);
224 			return SDIO_ERR_VAL32;
225 		}
226 
227 		ftaddr &= ~(u16)0x3;
228 		sd_read(pintfhdl, ftaddr, 8, ptmpbuf);
229 		memcpy(&le_tmp, ptmpbuf+shift, 4);
230 		val = le32_to_cpu(le_tmp);
231 
232 		kfree(ptmpbuf);
233 	}
234 	return val;
235 }
236 
237 static s32 sdio_readN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pbuf)
238 {
239 	struct adapter *padapter;
240 	u8 bMacPwrCtrlOn;
241 	u8 deviceId;
242 	u16 offset;
243 	u32 ftaddr;
244 	u8 shift;
245 	s32 err;
246 
247 	padapter = pintfhdl->padapter;
248 	err = 0;
249 
250 	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
251 
252 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
253 	if (
254 		((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
255 		(false == bMacPwrCtrlOn) ||
256 		(true == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
257 	) {
258 		err = sd_cmd52_read(pintfhdl, ftaddr, cnt, pbuf);
259 		return err;
260 	}
261 
262 	/*  4 bytes alignment */
263 	shift = ftaddr & 0x3;
264 	if (shift == 0) {
265 		err = sd_read(pintfhdl, ftaddr, cnt, pbuf);
266 	} else {
267 		u8 *ptmpbuf;
268 		u32 n;
269 
270 		ftaddr &= ~(u16)0x3;
271 		n = cnt + shift;
272 		ptmpbuf = rtw_malloc(n);
273 		if (NULL == ptmpbuf)
274 			return -1;
275 
276 		err = sd_read(pintfhdl, ftaddr, n, ptmpbuf);
277 		if (!err)
278 			memcpy(pbuf, ptmpbuf+shift, cnt);
279 		kfree(ptmpbuf);
280 	}
281 	return err;
282 }
283 
284 static s32 sdio_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
285 {
286 	u32 ftaddr;
287 	s32 err;
288 
289 	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
290 	sd_write8(pintfhdl, ftaddr, val, &err);
291 
292 	return err;
293 }
294 
295 static s32 sdio_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
296 {
297 	u32 ftaddr;
298 	s32 err;
299 	__le16 le_tmp;
300 
301 	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
302 	le_tmp = cpu_to_le16(val);
303 	err = sd_cmd52_write(pintfhdl, ftaddr, 2, (u8 *)&le_tmp);
304 
305 	return err;
306 }
307 
308 static s32 sdio_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
309 {
310 	struct adapter *padapter;
311 	u8 bMacPwrCtrlOn;
312 	u8 deviceId;
313 	u16 offset;
314 	u32 ftaddr;
315 	u8 shift;
316 	s32 err;
317 	__le32 le_tmp;
318 
319 	padapter = pintfhdl->padapter;
320 	err = 0;
321 
322 	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
323 
324 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
325 	if (
326 		((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
327 		(!bMacPwrCtrlOn) ||
328 		(adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
329 	) {
330 		le_tmp = cpu_to_le32(val);
331 		err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8 *)&le_tmp);
332 		return err;
333 	}
334 
335 	/*  4 bytes alignment */
336 	shift = ftaddr & 0x3;
337 	if (shift == 0) {
338 		sd_write32(pintfhdl, ftaddr, val, &err);
339 	} else {
340 		le_tmp = cpu_to_le32(val);
341 		err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8 *)&le_tmp);
342 	}
343 	return err;
344 }
345 
346 static s32 sdio_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pbuf)
347 {
348 	struct adapter *padapter;
349 	u8 bMacPwrCtrlOn;
350 	u8 deviceId;
351 	u16 offset;
352 	u32 ftaddr;
353 	u8 shift;
354 	s32 err;
355 
356 	padapter = pintfhdl->padapter;
357 	err = 0;
358 
359 	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
360 
361 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
362 	if (
363 		((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
364 		(false == bMacPwrCtrlOn) ||
365 		(true == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
366 	) {
367 		err = sd_cmd52_write(pintfhdl, ftaddr, cnt, pbuf);
368 		return err;
369 	}
370 
371 	shift = ftaddr & 0x3;
372 	if (shift == 0) {
373 		err = sd_write(pintfhdl, ftaddr, cnt, pbuf);
374 	} else {
375 		u8 *ptmpbuf;
376 		u32 n;
377 
378 		ftaddr &= ~(u16)0x3;
379 		n = cnt + shift;
380 		ptmpbuf = rtw_malloc(n);
381 		if (NULL == ptmpbuf)
382 			return -1;
383 		err = sd_read(pintfhdl, ftaddr, 4, ptmpbuf);
384 		if (err) {
385 			kfree(ptmpbuf);
386 			return err;
387 		}
388 		memcpy(ptmpbuf+shift, pbuf, cnt);
389 		err = sd_write(pintfhdl, ftaddr, n, ptmpbuf);
390 		kfree(ptmpbuf);
391 	}
392 	return err;
393 }
394 
395 static u8 sdio_f0_read8(struct intf_hdl *pintfhdl, u32 addr)
396 {
397 	return sd_f0_read8(pintfhdl, addr, NULL);
398 }
399 
400 static void sdio_read_mem(
401 	struct intf_hdl *pintfhdl,
402 	u32 addr,
403 	u32 cnt,
404 	u8 *rmem
405 )
406 {
407 	s32 err;
408 
409 	err = sdio_readN(pintfhdl, addr, cnt, rmem);
410 	/* TODO: Report error is err not zero */
411 }
412 
413 static void sdio_write_mem(
414 	struct intf_hdl *pintfhdl,
415 	u32 addr,
416 	u32 cnt,
417 	u8 *wmem
418 )
419 {
420 	sdio_writeN(pintfhdl, addr, cnt, wmem);
421 }
422 
423 /*
424  * Description:
425  *Read from RX FIFO
426  *Round read size to block size,
427  *and make sure data transfer will be done in one command.
428  *
429  * Parameters:
430  *pintfhdl	a pointer of intf_hdl
431  *addr		port ID
432  *cnt			size to read
433  *rmem		address to put data
434  *
435  * Return:
436  *_SUCCESS(1)		Success
437  *_FAIL(0)		Fail
438  */
439 static u32 sdio_read_port(
440 	struct intf_hdl *pintfhdl,
441 	u32 addr,
442 	u32 cnt,
443 	u8 *mem
444 )
445 {
446 	struct adapter *padapter;
447 	PSDIO_DATA psdio;
448 	struct hal_com_data *phal;
449 	u32 oldcnt;
450 #ifdef SDIO_DYNAMIC_ALLOC_MEM
451 	u8 *oldmem;
452 #endif
453 	s32 err;
454 
455 
456 	padapter = pintfhdl->padapter;
457 	psdio = &adapter_to_dvobj(padapter)->intf_data;
458 	phal = GET_HAL_DATA(padapter);
459 
460 	HalSdioGetCmdAddr8723BSdio(padapter, addr, phal->SdioRxFIFOCnt++, &addr);
461 
462 	oldcnt = cnt;
463 	if (cnt > psdio->block_transfer_len)
464 		cnt = _RND(cnt, psdio->block_transfer_len);
465 /* 	cnt = sdio_align_size(cnt); */
466 
467 	if (oldcnt != cnt) {
468 #ifdef SDIO_DYNAMIC_ALLOC_MEM
469 		oldmem = mem;
470 		mem = rtw_malloc(cnt);
471 		if (mem == NULL) {
472 			DBG_8192C(KERN_WARNING "%s: allocate memory %d bytes fail!\n", __func__, cnt);
473 			mem = oldmem;
474 			oldmem == NULL;
475 		}
476 #else
477 		/*  in this case, caller should gurante the buffer is big enough */
478 		/*  to receive data after alignment */
479 #endif
480 	}
481 
482 	err = _sd_read(pintfhdl, addr, cnt, mem);
483 
484 #ifdef SDIO_DYNAMIC_ALLOC_MEM
485 	if ((oldcnt != cnt) && (oldmem)) {
486 		memcpy(oldmem, mem, oldcnt);
487 		kfree(mem);
488 	}
489 #endif
490 
491 	if (err)
492 		return _FAIL;
493 	return _SUCCESS;
494 }
495 
496 /*
497  * Description:
498  *Write to TX FIFO
499  *Align write size block size,
500  *and make sure data could be written in one command.
501  *
502  * Parameters:
503  *pintfhdl	a pointer of intf_hdl
504  *addr		port ID
505  *cnt			size to write
506  *wmem		data pointer to write
507  *
508  * Return:
509  *_SUCCESS(1)		Success
510  *_FAIL(0)		Fail
511  */
512 static u32 sdio_write_port(
513 	struct intf_hdl *pintfhdl,
514 	u32 addr,
515 	u32 cnt,
516 	u8 *mem
517 )
518 {
519 	struct adapter *padapter;
520 	PSDIO_DATA psdio;
521 	s32 err;
522 	struct xmit_buf *xmitbuf = (struct xmit_buf *)mem;
523 
524 	padapter = pintfhdl->padapter;
525 	psdio = &adapter_to_dvobj(padapter)->intf_data;
526 
527 	if (padapter->hw_init_completed == false) {
528 		DBG_871X("%s [addr = 0x%x cnt =%d] padapter->hw_init_completed == false\n", __func__, addr, cnt);
529 		return _FAIL;
530 	}
531 
532 	cnt = _RND4(cnt);
533 	HalSdioGetCmdAddr8723BSdio(padapter, addr, cnt >> 2, &addr);
534 
535 	if (cnt > psdio->block_transfer_len)
536 		cnt = _RND(cnt, psdio->block_transfer_len);
537 /* 	cnt = sdio_align_size(cnt); */
538 
539 	err = sd_write(pintfhdl, addr, cnt, xmitbuf->pdata);
540 
541 	rtw_sctx_done_err(
542 		&xmitbuf->sctx,
543 		err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS
544 	);
545 
546 	if (err)
547 		return _FAIL;
548 	return _SUCCESS;
549 }
550 
551 void sdio_set_intf_ops(struct adapter *padapter, struct _io_ops *pops)
552 {
553 	pops->_read8 = &sdio_read8;
554 	pops->_read16 = &sdio_read16;
555 	pops->_read32 = &sdio_read32;
556 	pops->_read_mem = &sdio_read_mem;
557 	pops->_read_port = &sdio_read_port;
558 
559 	pops->_write8 = &sdio_write8;
560 	pops->_write16 = &sdio_write16;
561 	pops->_write32 = &sdio_write32;
562 	pops->_writeN = &sdio_writeN;
563 	pops->_write_mem = &sdio_write_mem;
564 	pops->_write_port = &sdio_write_port;
565 
566 	pops->_sd_f0_read8 = sdio_f0_read8;
567 }
568 
569 /*
570  * Todo: align address to 4 bytes.
571  */
572 static s32 _sdio_local_read(
573 	struct adapter *padapter,
574 	u32 addr,
575 	u32 cnt,
576 	u8 *pbuf
577 )
578 {
579 	struct intf_hdl *pintfhdl;
580 	u8 bMacPwrCtrlOn;
581 	s32 err;
582 	u8 *ptmpbuf;
583 	u32 n;
584 
585 
586 	pintfhdl = &padapter->iopriv.intf;
587 
588 	HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
589 
590 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
591 	if (false == bMacPwrCtrlOn) {
592 		err = _sd_cmd52_read(pintfhdl, addr, cnt, pbuf);
593 		return err;
594 	}
595 
596 	n = RND4(cnt);
597 	ptmpbuf = (u8 *)rtw_malloc(n);
598 	if (!ptmpbuf)
599 		return (-1);
600 
601 	err = _sd_read(pintfhdl, addr, n, ptmpbuf);
602 	if (!err)
603 		memcpy(pbuf, ptmpbuf, cnt);
604 
605 	kfree(ptmpbuf);
606 
607 	return err;
608 }
609 
610 /*
611  * Todo: align address to 4 bytes.
612  */
613 s32 sdio_local_read(
614 	struct adapter *padapter,
615 	u32 addr,
616 	u32 cnt,
617 	u8 *pbuf
618 )
619 {
620 	struct intf_hdl *pintfhdl;
621 	u8 bMacPwrCtrlOn;
622 	s32 err;
623 	u8 *ptmpbuf;
624 	u32 n;
625 
626 	pintfhdl = &padapter->iopriv.intf;
627 
628 	HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
629 
630 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
631 	if (
632 		(false == bMacPwrCtrlOn) ||
633 		(true == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
634 	) {
635 		err = sd_cmd52_read(pintfhdl, addr, cnt, pbuf);
636 		return err;
637 	}
638 
639 	n = RND4(cnt);
640 	ptmpbuf = (u8 *)rtw_malloc(n);
641 	if (!ptmpbuf)
642 		return (-1);
643 
644 	err = sd_read(pintfhdl, addr, n, ptmpbuf);
645 	if (!err)
646 		memcpy(pbuf, ptmpbuf, cnt);
647 
648 	kfree(ptmpbuf);
649 
650 	return err;
651 }
652 
653 /*
654  * Todo: align address to 4 bytes.
655  */
656 s32 sdio_local_write(
657 	struct adapter *padapter,
658 	u32 addr,
659 	u32 cnt,
660 	u8 *pbuf
661 )
662 {
663 	struct intf_hdl *pintfhdl;
664 	u8 bMacPwrCtrlOn;
665 	s32 err;
666 	u8 *ptmpbuf;
667 
668 	if (addr & 0x3)
669 		DBG_8192C("%s, address must be 4 bytes alignment\n", __func__);
670 
671 	if (cnt  & 0x3)
672 		DBG_8192C("%s, size must be the multiple of 4\n", __func__);
673 
674 	pintfhdl = &padapter->iopriv.intf;
675 
676 	HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
677 
678 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
679 	if (
680 		(false == bMacPwrCtrlOn) ||
681 		(true == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
682 	) {
683 		err = sd_cmd52_write(pintfhdl, addr, cnt, pbuf);
684 		return err;
685 	}
686 
687 	ptmpbuf = (u8 *)rtw_malloc(cnt);
688 	if (!ptmpbuf)
689 		return (-1);
690 
691 	memcpy(ptmpbuf, pbuf, cnt);
692 
693 	err = sd_write(pintfhdl, addr, cnt, ptmpbuf);
694 
695 	kfree(ptmpbuf);
696 
697 	return err;
698 }
699 
700 u8 SdioLocalCmd52Read1Byte(struct adapter *padapter, u32 addr)
701 {
702 	u8 val = 0;
703 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
704 
705 	HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
706 	sd_cmd52_read(pintfhdl, addr, 1, &val);
707 
708 	return val;
709 }
710 
711 static u16 SdioLocalCmd52Read2Byte(struct adapter *padapter, u32 addr)
712 {
713 	__le16 val = 0;
714 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
715 
716 	HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
717 	sd_cmd52_read(pintfhdl, addr, 2, (u8 *)&val);
718 
719 	return le16_to_cpu(val);
720 }
721 
722 static u32 SdioLocalCmd53Read4Byte(struct adapter *padapter, u32 addr)
723 {
724 
725 	u8 bMacPwrCtrlOn;
726 	u32 val = 0;
727 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
728 	__le32 le_tmp;
729 
730 	HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
731 	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
732 	if (!bMacPwrCtrlOn || adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) {
733 		sd_cmd52_read(pintfhdl, addr, 4, (u8 *)&le_tmp);
734 		val = le32_to_cpu(le_tmp);
735 	} else {
736 		val = sd_read32(pintfhdl, addr, NULL);
737 	}
738 	return val;
739 }
740 
741 void SdioLocalCmd52Write1Byte(struct adapter *padapter, u32 addr, u8 v)
742 {
743 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
744 
745 	HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
746 	sd_cmd52_write(pintfhdl, addr, 1, &v);
747 }
748 
749 static void SdioLocalCmd52Write4Byte(struct adapter *padapter, u32 addr, u32 v)
750 {
751 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
752 	__le32 le_tmp;
753 
754 	HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
755 	le_tmp = cpu_to_le32(v);
756 	sd_cmd52_write(pintfhdl, addr, 4, (u8 *)&le_tmp);
757 }
758 
759 static s32 ReadInterrupt8723BSdio(struct adapter *padapter, u32 *phisr)
760 {
761 	u32 hisr, himr;
762 	u8 val8, hisr_len;
763 
764 
765 	if (phisr == NULL)
766 		return false;
767 
768 	himr = GET_HAL_DATA(padapter)->sdio_himr;
769 
770 	/*  decide how many bytes need to be read */
771 	hisr_len = 0;
772 	while (himr) {
773 		hisr_len++;
774 		himr >>= 8;
775 	}
776 
777 	hisr = 0;
778 	while (hisr_len != 0) {
779 		hisr_len--;
780 		val8 = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR+hisr_len);
781 		hisr |= (val8 << (8*hisr_len));
782 	}
783 
784 	*phisr = hisr;
785 
786 	return true;
787 }
788 
789 /*  */
790 /* 	Description: */
791 /* 		Initialize SDIO Host Interrupt Mask configuration variables for future use. */
792 /*  */
793 /* 	Assumption: */
794 /* 		Using SDIO Local register ONLY for configuration. */
795 /*  */
796 /* 	Created by Roger, 2011.02.11. */
797 /*  */
798 void InitInterrupt8723BSdio(struct adapter *padapter)
799 {
800 	struct hal_com_data *pHalData;
801 
802 
803 	pHalData = GET_HAL_DATA(padapter);
804 	pHalData->sdio_himr = (u32)(		\
805 								SDIO_HIMR_RX_REQUEST_MSK			|
806 								SDIO_HIMR_AVAL_MSK					|
807 /* 								SDIO_HIMR_TXERR_MSK				| */
808 /* 								SDIO_HIMR_RXERR_MSK				| */
809 /* 								SDIO_HIMR_TXFOVW_MSK				| */
810 /* 								SDIO_HIMR_RXFOVW_MSK				| */
811 /* 								SDIO_HIMR_TXBCNOK_MSK				| */
812 /* 								SDIO_HIMR_TXBCNERR_MSK			| */
813 /* 								SDIO_HIMR_BCNERLY_INT_MSK			| */
814 /* 								SDIO_HIMR_C2HCMD_MSK				| */
815 /* 								SDIO_HIMR_HSISR_IND_MSK			| */
816 /* 								SDIO_HIMR_GTINT3_IND_MSK			| */
817 /* 								SDIO_HIMR_GTINT4_IND_MSK			| */
818 /* 								SDIO_HIMR_PSTIMEOUT_MSK			| */
819 /* 								SDIO_HIMR_OCPINT_MSK				| */
820 /* 								SDIO_HIMR_ATIMEND_MSK				| */
821 /* 								SDIO_HIMR_ATIMEND_E_MSK			| */
822 /* 								SDIO_HIMR_CTWEND_MSK				| */
823 								0);
824 }
825 
826 /*  */
827 /* 	Description: */
828 /* 		Initialize System Host Interrupt Mask configuration variables for future use. */
829 /*  */
830 /* 	Created by Roger, 2011.08.03. */
831 /*  */
832 void InitSysInterrupt8723BSdio(struct adapter *padapter)
833 {
834 	struct hal_com_data *pHalData;
835 
836 
837 	pHalData = GET_HAL_DATA(padapter);
838 
839 	pHalData->SysIntrMask = (		\
840 /* 							HSIMR_GPIO12_0_INT_EN			| */
841 /* 							HSIMR_SPS_OCP_INT_EN			| */
842 /* 							HSIMR_RON_INT_EN				| */
843 /* 							HSIMR_PDNINT_EN				| */
844 /* 							HSIMR_GPIO9_INT_EN				| */
845 							0);
846 }
847 
848 #ifdef CONFIG_WOWLAN
849 /*  */
850 /* 	Description: */
851 /* 		Clear corresponding SDIO Host ISR interrupt service. */
852 /*  */
853 /* 	Assumption: */
854 /* 		Using SDIO Local register ONLY for configuration. */
855 /*  */
856 /* 	Created by Roger, 2011.02.11. */
857 /*  */
858 void ClearInterrupt8723BSdio(struct adapter *padapter)
859 {
860 	struct hal_com_data *pHalData;
861 	u8 *clear;
862 
863 
864 	if (true == padapter->bSurpriseRemoved)
865 		return;
866 
867 	pHalData = GET_HAL_DATA(padapter);
868 	clear = rtw_zmalloc(4);
869 
870 	/*  Clear corresponding HISR Content if needed */
871 	*(__le32 *)clear = cpu_to_le32(pHalData->sdio_hisr & MASK_SDIO_HISR_CLEAR);
872 	if (*(__le32 *)clear) {
873 		/*  Perform write one clear operation */
874 		sdio_local_write(padapter, SDIO_REG_HISR, 4, clear);
875 	}
876 
877 	kfree(clear);
878 }
879 #endif
880 
881 /*  */
882 /* 	Description: */
883 /* 		Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain. */
884 /*  */
885 /* 	Assumption: */
886 /* 		1. Using SDIO Local register ONLY for configuration. */
887 /* 		2. PASSIVE LEVEL */
888 /*  */
889 /* 	Created by Roger, 2011.02.11. */
890 /*  */
891 void EnableInterrupt8723BSdio(struct adapter *padapter)
892 {
893 	struct hal_com_data *pHalData;
894 	__le32 himr;
895 	u32 tmp;
896 
897 	pHalData = GET_HAL_DATA(padapter);
898 
899 	himr = cpu_to_le32(pHalData->sdio_himr);
900 	sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
901 
902 	RT_TRACE(
903 		_module_hci_ops_c_,
904 		_drv_notice_,
905 		(
906 			"%s: enable SDIO HIMR = 0x%08X\n",
907 			__func__,
908 			pHalData->sdio_himr
909 		)
910 	);
911 
912 	/*  Update current system IMR settings */
913 	tmp = rtw_read32(padapter, REG_HSIMR);
914 	rtw_write32(padapter, REG_HSIMR, tmp | pHalData->SysIntrMask);
915 
916 	RT_TRACE(
917 		_module_hci_ops_c_,
918 		_drv_notice_,
919 		(
920 			"%s: enable HSIMR = 0x%08X\n",
921 			__func__,
922 			pHalData->SysIntrMask
923 		)
924 	);
925 
926 	/*  */
927 	/*  <Roger_Notes> There are some C2H CMDs have been sent before system interrupt is enabled, e.g., C2H, CPWM. */
928 	/*  So we need to clear all C2H events that FW has notified, otherwise FW won't schedule any commands anymore. */
929 	/*  2011.10.19. */
930 	/*  */
931 	rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
932 }
933 
934 /*  */
935 /* 	Description: */
936 /* 		Disable SDIO Host IMR configuration to mask unnecessary interrupt service. */
937 /*  */
938 /* 	Assumption: */
939 /* 		Using SDIO Local register ONLY for configuration. */
940 /*  */
941 /* 	Created by Roger, 2011.02.11. */
942 /*  */
943 void DisableInterrupt8723BSdio(struct adapter *padapter)
944 {
945 	__le32 himr;
946 
947 	himr = cpu_to_le32(SDIO_HIMR_DISABLED);
948 	sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
949 }
950 
951 /*  */
952 /* 	Description: */
953 /* 		Using 0x100 to check the power status of FW. */
954 /*  */
955 /* 	Assumption: */
956 /* 		Using SDIO Local register ONLY for configuration. */
957 /*  */
958 /* 	Created by Isaac, 2013.09.10. */
959 /*  */
960 u8 CheckIPSStatus(struct adapter *padapter)
961 {
962 	DBG_871X(
963 		"%s(): Read 0x100 = 0x%02x 0x86 = 0x%02x\n",
964 		__func__,
965 		rtw_read8(padapter, 0x100),
966 		rtw_read8(padapter, 0x86)
967 	);
968 
969 	if (rtw_read8(padapter, 0x100) == 0xEA)
970 		return true;
971 	else
972 		return false;
973 }
974 
975 static struct recv_buf *sd_recv_rxfifo(struct adapter *padapter, u32 size)
976 {
977 	u32 readsize, ret;
978 	u8 *preadbuf;
979 	struct recv_priv *precvpriv;
980 	struct recv_buf	*precvbuf;
981 
982 
983 	/*  Patch for some SDIO Host 4 bytes issue */
984 	/*  ex. RK3188 */
985 	readsize = RND4(size);
986 
987 	/* 3 1. alloc recvbuf */
988 	precvpriv = &padapter->recvpriv;
989 	precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
990 	if (precvbuf == NULL) {
991 		DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __func__);
992 		return NULL;
993 	}
994 
995 	/* 3 2. alloc skb */
996 	if (precvbuf->pskb == NULL) {
997 		SIZE_PTR tmpaddr = 0;
998 		SIZE_PTR alignment = 0;
999 
1000 		precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
1001 
1002 		if (precvbuf->pskb) {
1003 			precvbuf->pskb->dev = padapter->pnetdev;
1004 
1005 			tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
1006 			alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
1007 			skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
1008 		}
1009 
1010 		if (precvbuf->pskb == NULL) {
1011 			DBG_871X("%s: alloc_skb fail! read =%d\n", __func__, readsize);
1012 			return NULL;
1013 		}
1014 	}
1015 
1016 	/* 3 3. read data from rxfifo */
1017 	preadbuf = precvbuf->pskb->data;
1018 	ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
1019 	if (ret == _FAIL) {
1020 		RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __func__));
1021 		return NULL;
1022 	}
1023 
1024 
1025 	/* 3 4. init recvbuf */
1026 	precvbuf->len = size;
1027 	precvbuf->phead = precvbuf->pskb->head;
1028 	precvbuf->pdata = precvbuf->pskb->data;
1029 	skb_set_tail_pointer(precvbuf->pskb, size);
1030 	precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
1031 	precvbuf->pend = skb_end_pointer(precvbuf->pskb);
1032 
1033 	return precvbuf;
1034 }
1035 
1036 static void sd_rxhandler(struct adapter *padapter, struct recv_buf *precvbuf)
1037 {
1038 	struct recv_priv *precvpriv;
1039 	struct __queue *ppending_queue;
1040 
1041 	precvpriv = &padapter->recvpriv;
1042 	ppending_queue = &precvpriv->recv_buf_pending_queue;
1043 
1044 	/* 3 1. enqueue recvbuf */
1045 	rtw_enqueue_recvbuf(precvbuf, ppending_queue);
1046 
1047 	/* 3 2. schedule tasklet */
1048 	tasklet_schedule(&precvpriv->recv_tasklet);
1049 }
1050 
1051 void sd_int_dpc(struct adapter *padapter)
1052 {
1053 	struct hal_com_data *phal;
1054 	struct dvobj_priv *dvobj;
1055 	struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
1056 	struct pwrctrl_priv *pwrctl;
1057 
1058 
1059 	phal = GET_HAL_DATA(padapter);
1060 	dvobj = adapter_to_dvobj(padapter);
1061 	pwrctl = dvobj_to_pwrctl(dvobj);
1062 
1063 	if (phal->sdio_hisr & SDIO_HISR_AVAL) {
1064 		u8 freepage[4];
1065 
1066 		_sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 4, freepage);
1067 		up(&(padapter->xmitpriv.xmit_sema));
1068 	}
1069 
1070 	if (phal->sdio_hisr & SDIO_HISR_CPWM1) {
1071 		struct reportpwrstate_parm report;
1072 
1073 		u8 bcancelled;
1074 		_cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled);
1075 
1076 		report.state = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HCPWM1_8723B);
1077 
1078 		/* cpwm_int_hdl(padapter, &report); */
1079 		_set_workitem(&(pwrctl->cpwm_event));
1080 	}
1081 
1082 	if (phal->sdio_hisr & SDIO_HISR_TXERR) {
1083 		u8 *status;
1084 		u32 addr;
1085 
1086 		status = rtw_malloc(4);
1087 		if (status) {
1088 			addr = REG_TXDMA_STATUS;
1089 			HalSdioGetCmdAddr8723BSdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
1090 			_sd_read(pintfhdl, addr, 4, status);
1091 			_sd_write(pintfhdl, addr, 4, status);
1092 			DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32 *)status));
1093 			kfree(status);
1094 		} else {
1095 			DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
1096 		}
1097 	}
1098 
1099 	if (phal->sdio_hisr & SDIO_HISR_TXBCNOK) {
1100 		DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
1101 	}
1102 
1103 	if (phal->sdio_hisr & SDIO_HISR_TXBCNERR) {
1104 		DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
1105 	}
1106 #ifndef CONFIG_C2H_PACKET_EN
1107 	if (phal->sdio_hisr & SDIO_HISR_C2HCMD) {
1108 		struct c2h_evt_hdr_88xx *c2h_evt;
1109 
1110 		DBG_8192C("%s: C2H Command\n", __func__);
1111 		c2h_evt = (struct c2h_evt_hdr_88xx *)rtw_zmalloc(16);
1112 		if (c2h_evt != NULL) {
1113 			if (rtw_hal_c2h_evt_read(padapter, (u8 *)c2h_evt) == _SUCCESS) {
1114 				if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) {
1115 					/* Handle CCX report here */
1116 					rtw_hal_c2h_handler(padapter, (u8 *)c2h_evt);
1117 					kfree((u8 *)c2h_evt);
1118 				} else {
1119 					rtw_c2h_wk_cmd(padapter, (u8 *)c2h_evt);
1120 				}
1121 			}
1122 		} else {
1123 			/* Error handling for malloc fail */
1124 			if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, NULL) != _SUCCESS)
1125 				DBG_871X("%s rtw_cbuf_push fail\n", __func__);
1126 			_set_workitem(&padapter->evtpriv.c2h_wk);
1127 		}
1128 	}
1129 #endif
1130 
1131 	if (phal->sdio_hisr & SDIO_HISR_RXFOVW) {
1132 		DBG_8192C("%s: Rx Overflow\n", __func__);
1133 	}
1134 
1135 	if (phal->sdio_hisr & SDIO_HISR_RXERR) {
1136 		DBG_8192C("%s: Rx Error\n", __func__);
1137 	}
1138 
1139 	if (phal->sdio_hisr & SDIO_HISR_RX_REQUEST) {
1140 		struct recv_buf *precvbuf;
1141 		int alloc_fail_time = 0;
1142 		u32 hisr;
1143 
1144 /* 		DBG_8192C("%s: RX Request, size =%d\n", __func__, phal->SdioRxFIFOSize); */
1145 		phal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
1146 		do {
1147 			phal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(padapter, SDIO_REG_RX0_REQ_LEN);
1148 			if (phal->SdioRxFIFOSize != 0) {
1149 				precvbuf = sd_recv_rxfifo(padapter, phal->SdioRxFIFOSize);
1150 				if (precvbuf)
1151 					sd_rxhandler(padapter, precvbuf);
1152 				else {
1153 					alloc_fail_time++;
1154 					DBG_871X("precvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time);
1155 					if (alloc_fail_time >= 10)
1156 						break;
1157 				}
1158 				phal->SdioRxFIFOSize = 0;
1159 			} else
1160 				break;
1161 
1162 			hisr = 0;
1163 			ReadInterrupt8723BSdio(padapter, &hisr);
1164 			hisr &= SDIO_HISR_RX_REQUEST;
1165 			if (!hisr)
1166 				break;
1167 		} while (1);
1168 
1169 		if (alloc_fail_time == 10)
1170 			DBG_871X("exit because alloc memory failed more than 10 times\n");
1171 
1172 	}
1173 }
1174 
1175 void sd_int_hdl(struct adapter *padapter)
1176 {
1177 	struct hal_com_data *phal;
1178 
1179 
1180 	if (
1181 		(padapter->bDriverStopped == true) ||
1182 		(padapter->bSurpriseRemoved == true)
1183 	)
1184 		return;
1185 
1186 	phal = GET_HAL_DATA(padapter);
1187 
1188 	phal->sdio_hisr = 0;
1189 	ReadInterrupt8723BSdio(padapter, &phal->sdio_hisr);
1190 
1191 	if (phal->sdio_hisr & phal->sdio_himr) {
1192 		u32 v32;
1193 
1194 		phal->sdio_hisr &= phal->sdio_himr;
1195 
1196 		/*  clear HISR */
1197 		v32 = phal->sdio_hisr & MASK_SDIO_HISR_CLEAR;
1198 		if (v32) {
1199 			SdioLocalCmd52Write4Byte(padapter, SDIO_REG_HISR, v32);
1200 		}
1201 
1202 		sd_int_dpc(padapter);
1203 	} else {
1204 		RT_TRACE(_module_hci_ops_c_, _drv_err_,
1205 				("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n",
1206 				__func__, phal->sdio_hisr, phal->sdio_himr));
1207 	}
1208 }
1209 
1210 /*  */
1211 /* 	Description: */
1212 /* 		Query SDIO Local register to query current the number of Free TxPacketBuffer page. */
1213 /*  */
1214 /* 	Assumption: */
1215 /* 		1. Running at PASSIVE_LEVEL */
1216 /* 		2. RT_TX_SPINLOCK is NOT acquired. */
1217 /*  */
1218 /* 	Created by Roger, 2011.01.28. */
1219 /*  */
1220 u8 HalQueryTxBufferStatus8723BSdio(struct adapter *padapter)
1221 {
1222 	struct hal_com_data *phal;
1223 	u32 NumOfFreePage;
1224 	/* _irqL irql; */
1225 
1226 
1227 	phal = GET_HAL_DATA(padapter);
1228 
1229 	NumOfFreePage = SdioLocalCmd53Read4Byte(padapter, SDIO_REG_FREE_TXPG);
1230 
1231 	/* spin_lock_bh(&phal->SdioTxFIFOFreePageLock); */
1232 	memcpy(phal->SdioTxFIFOFreePage, &NumOfFreePage, 4);
1233 	RT_TRACE(_module_hci_ops_c_, _drv_notice_,
1234 			("%s: Free page for HIQ(%#x), MIDQ(%#x), LOWQ(%#x), PUBQ(%#x)\n",
1235 			__func__,
1236 			phal->SdioTxFIFOFreePage[HI_QUEUE_IDX],
1237 			phal->SdioTxFIFOFreePage[MID_QUEUE_IDX],
1238 			phal->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
1239 			phal->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
1240 	/* spin_unlock_bh(&phal->SdioTxFIFOFreePageLock); */
1241 
1242 	return true;
1243 }
1244 
1245 /*  */
1246 /* 	Description: */
1247 /* 		Query SDIO Local register to get the current number of TX OQT Free Space. */
1248 /*  */
1249 u8 HalQueryTxOQTBufferStatus8723BSdio(struct adapter *padapter)
1250 {
1251 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1252 
1253 	pHalData->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_OQT_FREE_PG);
1254 	return true;
1255 }
1256 
1257 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1258 u8 RecvOnePkt(struct adapter *padapter, u32 size)
1259 {
1260 	struct recv_buf *precvbuf;
1261 	struct dvobj_priv *psddev;
1262 	PSDIO_DATA psdio_data;
1263 	struct sdio_func *func;
1264 
1265 	u8 res = false;
1266 
1267 	DBG_871X("+%s: size: %d+\n", __func__, size);
1268 
1269 	if (padapter == NULL) {
1270 		DBG_871X(KERN_ERR "%s: padapter is NULL!\n", __func__);
1271 		return false;
1272 	}
1273 
1274 	psddev = adapter_to_dvobj(padapter);
1275 	psdio_data = &psddev->intf_data;
1276 	func = psdio_data->func;
1277 
1278 	if (size) {
1279 		sdio_claim_host(func);
1280 		precvbuf = sd_recv_rxfifo(padapter, size);
1281 
1282 		if (precvbuf) {
1283 			/* printk("Completed Recv One Pkt.\n"); */
1284 			sd_rxhandler(padapter, precvbuf);
1285 			res = true;
1286 		} else {
1287 			res = false;
1288 		}
1289 		sdio_release_host(func);
1290 	}
1291 	DBG_871X("-%s-\n", __func__);
1292 	return res;
1293 }
1294 #endif /* CONFIG_WOWLAN */
1295