1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
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
18 *******************************************************************************/
21 #include <rtl8723b_hal.h>
23 //#define SDIO_DEBUG_IO 1
28 // The following mapping is for SDIO host local register space.
30 // Creadted by Roger, 2011.01.31.
32 static void HalSdioGetCmdAddr8723BSdio(
41 case SDIO_LOCAL_DEVICE_ID:
42 *pCmdAddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (Addr & SDIO_LOCAL_MSK));
45 case WLAN_IOREG_DEVICE_ID:
46 *pCmdAddr = ((WLAN_IOREG_DEVICE_ID << 13) | (Addr & WLAN_IOREG_MSK));
49 case WLAN_TX_HIQ_DEVICE_ID:
50 *pCmdAddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
53 case WLAN_TX_MIQ_DEVICE_ID:
54 *pCmdAddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
57 case WLAN_TX_LOQ_DEVICE_ID:
58 *pCmdAddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
61 case WLAN_RX0FF_DEVICE_ID:
62 *pCmdAddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (Addr & WLAN_RX0FF_MSK));
70 static u8 get_deviceid(u32 addr)
76 pseudoId = (u16)(addr >> 16);
80 devideId = SDIO_LOCAL_DEVICE_ID;
84 devideId = WLAN_IOREG_DEVICE_ID;
88 // devideId = SDIO_FIRMWARE_FIFO;
92 devideId = WLAN_TX_HIQ_DEVICE_ID;
96 devideId = WLAN_TX_MIQ_DEVICE_ID;
100 devideId = WLAN_TX_LOQ_DEVICE_ID;
104 devideId = WLAN_RX0FF_DEVICE_ID;
108 // devideId = (u8)((addr >> 13) & 0xF);
109 devideId = WLAN_IOREG_DEVICE_ID;
118 * HalSdioGetCmdAddr8723BSdio()
120 static u32 _cvrt2ftaddr(const u32 addr, u8 *pdeviceId, u16 *poffset)
127 deviceId = get_deviceid(addr);
132 case SDIO_LOCAL_DEVICE_ID:
133 offset = addr & SDIO_LOCAL_MSK;
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;
142 case WLAN_RX0FF_DEVICE_ID:
143 offset = addr & WLAN_RX0FF_MSK;
146 case WLAN_IOREG_DEVICE_ID:
148 deviceId = WLAN_IOREG_DEVICE_ID;
149 offset = addr & WLAN_IOREG_MSK;
152 ftaddr = (deviceId << 13) | offset;
154 if (pdeviceId) *pdeviceId = deviceId;
155 if (poffset) *poffset = offset;
160 u8 sdio_read8(struct intf_hdl *pintfhdl, u32 addr)
166 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
167 val = sd_read8(pintfhdl, ftaddr, NULL);
174 u16 sdio_read16(struct intf_hdl *pintfhdl, u32 addr)
180 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
181 sd_cmd52_read(pintfhdl, ftaddr, 2, (u8*)&val);
182 val = le16_to_cpu(val);
189 u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr)
202 padapter = pintfhdl->padapter;
203 ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
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)
213 err = sd_cmd52_read(pintfhdl, ftaddr, 4, (u8*)&val);
217 val = le32_to_cpu(val);
222 DBG_8192C(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n", __func__, err, addr);
223 return SDIO_ERR_VAL32;
228 shift = ftaddr & 0x3;
230 val = sd_read32(pintfhdl, ftaddr, NULL);
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;
241 sd_read(pintfhdl, ftaddr, 8, ptmpbuf);
242 _rtw_memcpy(&val, ptmpbuf+shift, 4);
243 val = le32_to_cpu(val);
245 rtw_mfree(ptmpbuf, 8);
253 s32 sdio_readN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pbuf)
265 padapter = pintfhdl->padapter;
268 ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
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)
278 err = sd_cmd52_read(pintfhdl, ftaddr, cnt, pbuf);
283 shift = ftaddr & 0x3;
285 err = sd_read(pintfhdl, ftaddr, cnt, pbuf);
292 ptmpbuf = rtw_malloc(n);
293 if (NULL == ptmpbuf) return -1;
294 err = sd_read(pintfhdl, ftaddr, n, ptmpbuf);
296 _rtw_memcpy(pbuf, ptmpbuf+shift, cnt);
297 rtw_mfree(ptmpbuf, n);
305 s32 sdio_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
311 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
312 sd_write8(pintfhdl, ftaddr, val, &err);
319 s32 sdio_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
326 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
327 val = cpu_to_le16(val);
328 err = sd_cmd52_write(pintfhdl, ftaddr, 2, (u8*)&val);
335 s32 sdio_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
347 padapter = pintfhdl->padapter;
350 ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
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)
360 val = cpu_to_le32(val);
361 err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8*)&val);
366 shift = ftaddr & 0x3;
370 sd_write32(pintfhdl, ftaddr, val, &err);
374 val = cpu_to_le32(val);
375 err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8*)&val);
379 sd_write32(pintfhdl, ftaddr, val, &err);
383 ptmpbuf = (u8*)rtw_malloc(8);
384 if (NULL == ptmpbuf) return (-1);
387 err = sd_read(pintfhdl, ftaddr, 8, ptmpbuf);
389 rtw_mfree(ptmpbuf, 8);
392 val = cpu_to_le32(val);
393 _rtw_memcpy(ptmpbuf+shift, &val, 4);
394 err = sd_write(pintfhdl, ftaddr, 8, ptmpbuf);
396 rtw_mfree(ptmpbuf, 8);
405 s32 sdio_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8* pbuf)
417 padapter = pintfhdl->padapter;
420 ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
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)
430 err = sd_cmd52_write(pintfhdl, ftaddr, cnt, pbuf);
434 shift = ftaddr & 0x3;
436 err = sd_write(pintfhdl, ftaddr, cnt, pbuf);
443 ptmpbuf = rtw_malloc(n);
444 if (NULL == ptmpbuf) return -1;
445 err = sd_read(pintfhdl, ftaddr, 4, ptmpbuf);
447 rtw_mfree(ptmpbuf, n);
450 _rtw_memcpy(ptmpbuf+shift, pbuf, cnt);
451 err = sd_write(pintfhdl, ftaddr, n, ptmpbuf);
452 rtw_mfree(ptmpbuf, n);
460 u8 sdio_f0_read8(struct intf_hdl *pintfhdl, u32 addr)
466 val = sd_f0_read8(pintfhdl, addr, NULL);
473 void sdio_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
479 err = sdio_readN(pintfhdl, addr, cnt, rmem);
484 void sdio_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
488 sdio_writeN(pintfhdl, addr, cnt, wmem);
496 * Round read size to block size,
497 * and make sure data transfer will be done in one command.
500 * pintfhdl a pointer of intf_hdl
503 * rmem address to put data
506 * _SUCCESS(1) Success
509 static u32 sdio_read_port(
510 struct intf_hdl *pintfhdl,
519 #ifdef SDIO_DYNAMIC_ALLOC_MEM
525 padapter = pintfhdl->padapter;
526 psdio = &adapter_to_dvobj(padapter)->intf_data;
527 phal = GET_HAL_DATA(padapter);
529 HalSdioGetCmdAddr8723BSdio(padapter, addr, phal->SdioRxFIFOCnt++, &addr);
532 if (cnt > psdio->block_transfer_len)
533 cnt = _RND(cnt, psdio->block_transfer_len);
534 // cnt = sdio_align_size(cnt);
537 #ifdef SDIO_DYNAMIC_ALLOC_MEM
539 mem = rtw_malloc(cnt);
541 DBG_8192C(KERN_WARNING "%s: allocate memory %d bytes fail!\n", __func__, cnt);
546 // in this case, caller should gurante the buffer is big enough
547 // to receive data after alignment
551 err = _sd_read(pintfhdl, addr, cnt, mem);
553 #ifdef SDIO_DYNAMIC_ALLOC_MEM
554 if ((oldcnt != cnt) && (oldmem)) {
555 _rtw_memcpy(oldmem, mem, oldcnt);
560 if (err) return _FAIL;
567 * Align write size block size,
568 * and make sure data could be written in one command.
571 * pintfhdl a pointer of intf_hdl
574 * wmem data pointer to write
577 * _SUCCESS(1) Success
580 static u32 sdio_write_port(
581 struct intf_hdl *pintfhdl,
589 struct xmit_buf *xmitbuf = (struct xmit_buf *)mem;
591 padapter = pintfhdl->padapter;
592 psdio = &adapter_to_dvobj(padapter)->intf_data;
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);
600 HalSdioGetCmdAddr8723BSdio(padapter, addr, cnt >> 2, &addr);
602 if (cnt > psdio->block_transfer_len)
603 cnt = _RND(cnt, psdio->block_transfer_len);
604 // cnt = sdio_align_size(cnt);
606 err = sd_write(pintfhdl, addr, cnt, xmitbuf->pdata);
608 rtw_sctx_done_err(&xmitbuf->sctx,
609 err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS);
611 if (err) return _FAIL;
615 void sdio_set_intf_ops(_adapter *padapter, struct _io_ops *pops)
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;
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;
632 pops->_sd_f0_read8 = sdio_f0_read8;
638 * Todo: align address to 4 bytes.
640 s32 _sdio_local_read(
646 struct intf_hdl * pintfhdl;
653 pintfhdl=&padapter->iopriv.intf;
655 HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
657 rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
658 if (_FALSE == bMacPwrCtrlOn)
660 err = _sd_cmd52_read(pintfhdl, addr, cnt, pbuf);
665 ptmpbuf = (u8*)rtw_malloc(n);
669 err = _sd_read(pintfhdl, addr, n, ptmpbuf);
671 _rtw_memcpy(pbuf, ptmpbuf, cnt);
674 rtw_mfree(ptmpbuf, n);
680 * Todo: align address to 4 bytes.
688 struct intf_hdl * pintfhdl;
694 pintfhdl=&padapter->iopriv.intf;
696 HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
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)
705 err = sd_cmd52_read(pintfhdl, addr, cnt, pbuf);
710 ptmpbuf = (u8*)rtw_malloc(n);
714 err = sd_read(pintfhdl, addr, n, ptmpbuf);
716 _rtw_memcpy(pbuf, ptmpbuf, cnt);
719 rtw_mfree(ptmpbuf, n);
725 * Todo: align address to 4 bytes.
727 s32 _sdio_local_write(
733 struct intf_hdl * pintfhdl;
739 DBG_8192C("%s, address must be 4 bytes alignment\n", __FUNCTION__);
742 DBG_8192C("%s, size must be the multiple of 4 \n", __FUNCTION__);
744 pintfhdl=&padapter->iopriv.intf;
746 HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
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)
755 err = _sd_cmd52_write(pintfhdl, addr, cnt, pbuf);
759 ptmpbuf = (u8*)rtw_malloc(cnt);
763 _rtw_memcpy(ptmpbuf, pbuf, cnt);
765 err = _sd_write(pintfhdl, addr, cnt, ptmpbuf);
768 rtw_mfree(ptmpbuf, cnt);
774 * Todo: align address to 4 bytes.
776 s32 sdio_local_write(
782 struct intf_hdl * pintfhdl;
788 DBG_8192C("%s, address must be 4 bytes alignment\n", __FUNCTION__);
791 DBG_8192C("%s, size must be the multiple of 4 \n", __FUNCTION__);
793 pintfhdl=&padapter->iopriv.intf;
795 HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
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)
804 err = sd_cmd52_write(pintfhdl, addr, cnt, pbuf);
808 ptmpbuf = (u8*)rtw_malloc(cnt);
812 _rtw_memcpy(ptmpbuf, pbuf, cnt);
814 err = sd_write(pintfhdl, addr, cnt, ptmpbuf);
817 rtw_mfree(ptmpbuf, cnt);
822 u8 SdioLocalCmd52Read1Byte(PADAPTER padapter, u32 addr)
825 struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
827 HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
828 sd_cmd52_read(pintfhdl, addr, 1, &val);
833 u16 SdioLocalCmd52Read2Byte(PADAPTER padapter, u32 addr)
836 struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
838 HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
839 sd_cmd52_read(pintfhdl, addr, 2, (u8*)&val);
841 val = le16_to_cpu(val);
846 u32 SdioLocalCmd52Read4Byte(PADAPTER padapter, u32 addr)
849 struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
851 HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
852 sd_cmd52_read(pintfhdl, addr, 4, (u8*)&val);
854 val = le32_to_cpu(val);
859 u32 SdioLocalCmd53Read4Byte(PADAPTER padapter, u32 addr)
864 struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
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)
874 sd_cmd52_read(pintfhdl, addr, 4, (u8*)&val);
875 val = le32_to_cpu(val);
878 val = sd_read32(pintfhdl, addr, NULL);
883 void SdioLocalCmd52Write1Byte(PADAPTER padapter, u32 addr, u8 v)
885 struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
887 HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
888 sd_cmd52_write(pintfhdl, addr, 1, &v);
891 void SdioLocalCmd52Write2Byte(PADAPTER padapter, u32 addr, u16 v)
893 struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
895 HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
897 sd_cmd52_write(pintfhdl, addr, 2, (u8*)&v);
900 void SdioLocalCmd52Write4Byte(PADAPTER padapter, u32 addr, u32 v)
902 struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
903 HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
905 sd_cmd52_write(pintfhdl, addr, 4, (u8*)&v);
910 DumpLoggedInterruptHistory8723Sdio(
914 HAL_DATA_TYPE *pHalData=GET_HAL_DATA(padapter);
915 u4Byte DebugLevel = DBG_LOUD;
917 if (DBG_Var.DbgPrintIsr == 0)
920 DBG_ChkDrvResource(padapter);
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));
926 if(pHalData->InterruptLog.nISR_AVAL)
927 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# AVAL[%ld]\t\n", pHalData->InterruptLog.nISR_AVAL));
929 if(pHalData->InterruptLog.nISR_TXERR)
930 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXERR[%ld]\t\n", pHalData->InterruptLog.nISR_TXERR));
932 if(pHalData->InterruptLog.nISR_RXERR)
933 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# RXERR[%ld]\t\n", pHalData->InterruptLog.nISR_RXERR));
935 if(pHalData->InterruptLog.nISR_TXFOVW)
936 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXFOVW[%ld]\t\n", pHalData->InterruptLog.nISR_TXFOVW));
938 if(pHalData->InterruptLog.nISR_RXFOVW)
939 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# RXFOVW[%ld]\t\n", pHalData->InterruptLog.nISR_RXFOVW));
941 if(pHalData->InterruptLog.nISR_TXBCNOK)
942 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXBCNOK[%ld]\t\n", pHalData->InterruptLog.nISR_TXBCNOK));
944 if(pHalData->InterruptLog.nISR_TXBCNERR)
945 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXBCNERR[%ld]\t\n", pHalData->InterruptLog.nISR_TXBCNERR));
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));
950 if(pHalData->InterruptLog.nISR_C2HCMD)
951 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# C2HCMD[%ld]\t\n", pHalData->InterruptLog.nISR_C2HCMD));
953 if(pHalData->InterruptLog.nISR_CPWM1)
954 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CPWM1L[%ld]\t\n", pHalData->InterruptLog.nISR_CPWM1));
956 if(pHalData->InterruptLog.nISR_CPWM2)
957 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CPWM2[%ld]\t\n", pHalData->InterruptLog.nISR_CPWM2));
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));
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));
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));
968 if(pHalData->InterruptLog.nISR_PSTIMEOUT)
969 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# PSTIMEOUT[%ld]\t\n", pHalData->InterruptLog.nISR_PSTIMEOUT));
971 if(pHalData->InterruptLog.nISR_OCPINT)
972 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# OCPINT[%ld]\t\n", pHalData->InterruptLog.nISR_OCPINT));
974 if(pHalData->InterruptLog.nISR_ATIMEND)
975 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# ATIMEND[%ld]\t\n", pHalData->InterruptLog.nISR_ATIMEND));
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));
980 if(pHalData->InterruptLog.nISR_CTWEND)
981 RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CTWEND[%ld]\t\n", pHalData->InterruptLog.nISR_CTWEND));
985 LogInterruptHistory8723Sdio(
987 PRT_ISR_CONTENT pIsrContent
990 HAL_DATA_TYPE *pHalData=GET_HAL_DATA(padapter);
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++;
1056 DumpHardwareProfile8723Sdio(
1057 IN PADAPTER padapter
1060 DumpLoggedInterruptHistory8723Sdio(padapter);
1064 static s32 ReadInterrupt8723BSdio(PADAPTER padapter, u32 *phisr)
1073 himr = GET_HAL_DATA(padapter)->sdio_himr;
1075 // decide how many bytes need to be read
1084 while (hisr_len != 0)
1087 val8 = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR+hisr_len);
1088 hisr |= (val8 << (8*hisr_len));
1098 // Initialize SDIO Host Interrupt Mask configuration variables for future use.
1101 // Using SDIO Local register ONLY for configuration.
1103 // Created by Roger, 2011.02.11.
1105 void InitInterrupt8723BSdio(PADAPTER padapter)
1107 PHAL_DATA_TYPE pHalData;
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 |
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 |
1141 // Initialize System Host Interrupt Mask configuration variables for future use.
1143 // Created by Roger, 2011.08.03.
1145 void InitSysInterrupt8723BSdio(PADAPTER padapter)
1147 PHAL_DATA_TYPE pHalData;
1150 pHalData = GET_HAL_DATA(padapter);
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 |
1161 #ifdef CONFIG_WOWLAN
1164 // Clear corresponding SDIO Host ISR interrupt service.
1167 // Using SDIO Local register ONLY for configuration.
1169 // Created by Roger, 2011.02.11.
1171 void ClearInterrupt8723BSdio(PADAPTER padapter)
1173 PHAL_DATA_TYPE pHalData;
1177 if (_TRUE == padapter->bSurpriseRemoved)
1180 pHalData = GET_HAL_DATA(padapter);
1181 clear = rtw_zmalloc(4);
1183 // Clear corresponding HISR Content if needed
1184 *(u32*)clear = cpu_to_le32(pHalData->sdio_hisr & MASK_SDIO_HISR_CLEAR);
1187 // Perform write one clear operation
1188 sdio_local_write(padapter, SDIO_REG_HISR, 4, clear);
1191 rtw_mfree(clear, 4);
1197 // Clear corresponding system Host ISR interrupt service.
1200 // Created by Roger, 2011.02.11.
1202 void ClearSysInterrupt8723BSdio(PADAPTER padapter)
1204 PHAL_DATA_TYPE pHalData;
1208 if (_TRUE == padapter->bSurpriseRemoved)
1211 pHalData = GET_HAL_DATA(padapter);
1213 // Clear corresponding HISR Content if needed
1214 clear = pHalData->SysIntrStatus & MASK_HSISR_CLEAR;
1217 // Perform write one clear operation
1218 rtw_write32(padapter, REG_HSISR, clear);
1224 // Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain.
1227 // 1. Using SDIO Local register ONLY for configuration.
1230 // Created by Roger, 2011.02.11.
1232 void EnableInterrupt8723BSdio(PADAPTER padapter)
1234 PHAL_DATA_TYPE pHalData;
1237 #ifdef CONFIG_CONCURRENT_MODE
1238 if ((padapter->isprimary == _FALSE) && padapter->pbuddy_adapter){
1239 padapter = padapter->pbuddy_adapter;
1242 pHalData = GET_HAL_DATA(padapter);
1244 himr = cpu_to_le32(pHalData->sdio_himr);
1245 sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8*)&himr);
1247 RT_TRACE(_module_hci_ops_c_, _drv_notice_,
1248 ("%s: enable SDIO HIMR=0x%08X\n", __FUNCTION__, pHalData->sdio_himr));
1250 // Update current system IMR settings
1251 himr = rtw_read32(padapter, REG_HSIMR);
1252 rtw_write32(padapter, REG_HSIMR, himr|pHalData->SysIntrMask);
1254 RT_TRACE(_module_hci_ops_c_, _drv_notice_,
1255 ("%s: enable HSIMR=0x%08X\n", __FUNCTION__, pHalData->SysIntrMask));
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.
1262 rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1267 // Disable SDIO Host IMR configuration to mask unnecessary interrupt service.
1270 // Using SDIO Local register ONLY for configuration.
1272 // Created by Roger, 2011.02.11.
1274 void DisableInterrupt8723BSdio(PADAPTER padapter)
1278 #ifdef CONFIG_CONCURRENT_MODE
1279 if ((padapter->isprimary == _FALSE) && padapter->pbuddy_adapter){
1280 padapter = padapter->pbuddy_adapter;
1283 himr = cpu_to_le32(SDIO_HIMR_DISABLED);
1284 sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8*)&himr);
1290 // Using 0x100 to check the power status of FW.
1293 // Using SDIO Local register ONLY for configuration.
1295 // Created by Isaac, 2013.09.10.
1297 u8 CheckIPSStatus(PADAPTER padapter)
1299 DBG_871X("%s(): Read 0x100=0x%02x 0x86=0x%02x\n", __func__,
1300 rtw_read8(padapter, 0x100),rtw_read8(padapter, 0x86));
1302 if (rtw_read8(padapter, 0x100) == 0xEA)
1308 #ifdef CONFIG_WOWLAN
1309 void DisableInterruptButCpwm28723BSdio(PADAPTER padapter)
1313 #ifdef CONFIG_CONCURRENT_MODE
1314 if ((padapter->isprimary == _FALSE) && padapter->pbuddy_adapter){
1315 padapter = padapter->pbuddy_adapter;
1318 sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
1319 DBG_871X("DisableInterruptButCpwm28723BSdio(): Read SDIO_REG_HIMR: 0x%08x\n", tmp);
1321 himr = cpu_to_le32(SDIO_HIMR_DISABLED)|SDIO_HIMR_CPWM2_MSK;
1322 sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8*)&himr);
1324 sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
1325 DBG_871X("DisableInterruptButCpwm28723BSdio(): Read again SDIO_REG_HIMR: 0x%08x\n", tmp);
1327 #endif //CONFIG_WOWLAN
1330 // Update SDIO Host Interrupt Mask configuration on SDIO local domain.
1333 // 1. Using SDIO Local register ONLY for configuration.
1336 // Created by Roger, 2011.02.11.
1338 void UpdateInterruptMask8723BSdio(PADAPTER padapter, u32 AddMSR, u32 RemoveMSR)
1340 HAL_DATA_TYPE *pHalData;
1342 #ifdef CONFIG_CONCURRENT_MODE
1343 if ((padapter->isprimary == _FALSE) && padapter->pbuddy_adapter){
1344 padapter = padapter->pbuddy_adapter;
1347 pHalData = GET_HAL_DATA(padapter);
1350 pHalData->sdio_himr |= AddMSR;
1353 pHalData->sdio_himr &= (~RemoveMSR);
1355 DisableInterrupt8723BSdio(padapter);
1356 EnableInterrupt8723BSdio(padapter);
1359 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
1360 static void sd_recv_loopback(PADAPTER padapter, u32 size)
1362 PLOOPBACKDATA ploopback;
1363 u32 readsize, allocsize;
1368 DBG_8192C("%s: read size=%d\n", __func__, readsize);
1369 allocsize = _RND(readsize, adapter_to_dvobj(padapter)->intf_data.block_transfer_len);
1371 ploopback = padapter->ploopback;
1373 ploopback->rxsize = readsize;
1374 preadbuf = ploopback->rxbuf;
1377 preadbuf = rtw_malloc(allocsize);
1378 if (preadbuf == NULL) {
1379 DBG_8192C("%s: malloc fail size=%d\n", __func__, allocsize);
1384 // rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
1385 sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
1388 _rtw_up_sema(&ploopback->sema);
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(" ");
1399 rtw_mfree(preadbuf, allocsize);
1402 #endif // CONFIG_MAC_LOOPBACK_DRIVER
1404 #ifdef CONFIG_SDIO_RX_COPY
1405 static struct recv_buf* sd_recv_rxfifo(PADAPTER padapter, u32 size)
1409 struct recv_priv *precvpriv;
1410 struct recv_buf *precvbuf;
1416 // Patch for some SDIO Host 4 bytes issue
1418 readsize = RND4(size);
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__);
1430 if (precvbuf->pskb == NULL) {
1432 SIZE_PTR alignment=0;
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);
1441 precvbuf->pskb->dev = padapter->pnetdev;
1443 tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
1444 alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
1445 skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
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);
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);
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);
1468 #else // !CONFIG_SDIO_RX_COPY
1469 static struct recv_buf* sd_recv_rxfifo(PADAPTER padapter, u32 size)
1471 u32 sdioblksize, readsize, allocsize, ret;
1474 struct recv_priv *precvpriv;
1475 struct recv_buf *precvbuf;
1478 sdioblksize = adapter_to_dvobj(padapter)->intf_data.block_transfer_len;
1482 // Patch for some SDIO Host 4 bytes issue
1484 readsize = RND4(size);
1488 // align to block size
1489 if (readsize > sdioblksize)
1490 allocsize = _RND(readsize, sdioblksize);
1492 allocsize = readsize;
1494 ppkt = rtw_skb_alloc(allocsize);
1497 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: alloc_skb fail! alloc=%d read=%d\n", __FUNCTION__, allocsize, readsize));
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);
1507 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __FUNCTION__));
1511 //3 3. alloc recvbuf
1512 precvpriv = &padapter->recvpriv;
1513 precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
1514 if (precvbuf == NULL) {
1516 DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __FUNCTION__);
1521 precvbuf->pskb = ppkt;
1523 precvbuf->len = ppkt->len;
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);
1532 #endif // !CONFIG_SDIO_RX_COPY
1534 static void sd_rxhandler(PADAPTER padapter, struct recv_buf *precvbuf)
1536 struct recv_priv *precvpriv;
1537 _queue *ppending_queue;
1540 precvpriv = &padapter->recvpriv;
1541 ppending_queue = &precvpriv->recv_buf_pending_queue;
1543 //3 1. enqueue recvbuf
1544 rtw_enqueue_recvbuf(precvbuf, ppending_queue);
1546 //3 2. schedule tasklet
1547 #ifdef PLATFORM_LINUX
1548 tasklet_schedule(&precvpriv->recv_tasklet);
1552 void sd_int_dpc(PADAPTER padapter)
1554 PHAL_DATA_TYPE phal;
1555 struct dvobj_priv *dvobj;
1556 struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
1557 struct pwrctrl_priv *pwrctl;
1560 phal = GET_HAL_DATA(padapter);
1561 dvobj = adapter_to_dvobj(padapter);
1562 pwrctl = dvobj_to_pwrctl(dvobj);
1564 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
1565 if (phal->sdio_hisr & SDIO_HISR_AVAL)
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",
1579 _rtw_up_sema(&(padapter->xmitpriv.xmit_sema));
1582 if (phal->sdio_hisr & SDIO_HISR_CPWM1)
1584 struct reportpwrstate_parm report;
1586 #ifdef CONFIG_LPS_RPWM_TIMER
1588 _cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled);
1589 #endif // CONFIG_LPS_RPWM_TIMER
1591 report.state = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HCPWM1_8723B);
1593 #ifdef CONFIG_LPS_LCLK
1594 //cpwm_int_hdl(padapter, &report);
1595 _set_workitem(&(pwrctl->cpwm_event));
1599 if (phal->sdio_hisr & SDIO_HISR_TXERR)
1604 status = rtw_malloc(4);
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);
1614 DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
1618 if (phal->sdio_hisr & SDIO_HISR_TXBCNOK)
1620 DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
1623 if (phal->sdio_hisr & SDIO_HISR_TXBCNERR)
1625 DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
1627 #ifndef CONFIG_C2H_PACKET_EN
1628 if (phal->sdio_hisr & SDIO_HISR_C2HCMD)
1630 struct c2h_evt_hdr_88xx *c2h_evt;
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);
1640 rtw_c2h_wk_cmd(padapter, (u8 *)c2h_evt);
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);
1652 if (phal->sdio_hisr & SDIO_HISR_RXFOVW)
1654 DBG_8192C("%s: Rx Overflow\n", __func__);
1656 if (phal->sdio_hisr & SDIO_HISR_RXERR)
1658 DBG_8192C("%s: Rx Error\n", __func__);
1661 if (phal->sdio_hisr & SDIO_HISR_RX_REQUEST)
1663 struct recv_buf *precvbuf;
1664 int alloc_fail_time=0;
1667 // DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize);
1668 phal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
1670 phal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(padapter, SDIO_REG_RX0_REQ_LEN);
1671 if (phal->SdioRxFIFOSize != 0)
1673 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
1674 sd_recv_loopback(padapter, phal->SdioRxFIFOSize);
1676 precvbuf = sd_recv_rxfifo(padapter, phal->SdioRxFIFOSize);
1678 sd_rxhandler(padapter, precvbuf);
1682 DBG_871X("%s: recv fail!(time=%d)\n", __func__, alloc_fail_time);
1683 if (alloc_fail_time >= 10)
1686 phal->SdioRxFIFOSize = 0;
1693 ReadInterrupt8723BSdio(padapter, &hisr);
1694 hisr &= SDIO_HISR_RX_REQUEST;
1699 if (alloc_fail_time == 10)
1700 DBG_871X("%s: exit because recv failed more than 10 times!\n", __func__);
1704 void sd_int_hdl(PADAPTER padapter)
1706 PHAL_DATA_TYPE phal;
1709 if ((padapter->bDriverStopped == _TRUE) ||
1710 (padapter->bSurpriseRemoved == _TRUE))
1713 phal = GET_HAL_DATA(padapter);
1715 phal->sdio_hisr = 0;
1716 ReadInterrupt8723BSdio(padapter, &phal->sdio_hisr);
1718 if (phal->sdio_hisr & phal->sdio_himr)
1722 phal->sdio_hisr &= phal->sdio_himr;
1725 v32 = phal->sdio_hisr & MASK_SDIO_HISR_CLEAR;
1727 SdioLocalCmd52Write4Byte(padapter, SDIO_REG_HISR, v32);
1730 sd_int_dpc(padapter);
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));
1740 // Query SDIO Local register to query current the number of Free TxPacketBuffer page.
1743 // 1. Running at PASSIVE_LEVEL
1744 // 2. RT_TX_SPINLOCK is NOT acquired.
1746 // Created by Roger, 2011.01.28.
1748 u8 HalQueryTxBufferStatus8723BSdio(PADAPTER padapter)
1750 PHAL_DATA_TYPE phal;
1755 phal = GET_HAL_DATA(padapter);
1757 NumOfFreePage = SdioLocalCmd53Read4Byte(padapter, SDIO_REG_FREE_TXPG);
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",
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);
1775 // Query SDIO Local register to get the current number of TX OQT Free Space.
1777 u8 HalQueryTxOQTBufferStatus8723BSdio(PADAPTER padapter)
1779 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1780 pHalData->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_OQT_FREE_PG);
1784 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1785 u8 RecvOnePkt(PADAPTER padapter, u32 size)
1787 struct recv_buf *precvbuf;
1788 struct dvobj_priv *psddev;
1789 PSDIO_DATA psdio_data;
1790 struct sdio_func *func;
1794 DBG_871X("+%s: size: %d+\n", __func__, size);
1796 if (padapter == NULL) {
1797 DBG_871X(KERN_ERR "%s: padapter is NULL!\n", __func__);
1801 psddev = adapter_to_dvobj(padapter);
1802 psdio_data = &psddev->intf_data;
1803 func = psdio_data->func;
1806 sdio_claim_host(func);
1807 precvbuf = sd_recv_rxfifo(padapter, size);
1810 //printk("Completed Recv One Pkt.\n");
1811 sd_rxhandler(padapter, precvbuf);
1816 sdio_release_host(func);
1818 DBG_871X("-%s-\n", __func__);
1821 #endif //CONFIG_WOWLAN