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