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