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 *******************************************************************************/
17 #include <drv_types.h>
18 #include <rtw_debug.h>
19 #include <rtl8723b_hal.h>
21 /* define SDIO_DEBUG_IO 1 */
26 /* The following mapping is for SDIO host local register space. */
28 /* Creadted by Roger, 2011.01.31. */
30 static void HalSdioGetCmdAddr8723BSdio(
31 struct adapter *adapter,
38 case SDIO_LOCAL_DEVICE_ID:
39 *cmdaddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (addr & SDIO_LOCAL_MSK));
42 case WLAN_IOREG_DEVICE_ID:
43 *cmdaddr = ((WLAN_IOREG_DEVICE_ID << 13) | (addr & WLAN_IOREG_MSK));
46 case WLAN_TX_HIQ_DEVICE_ID:
47 *cmdaddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
50 case WLAN_TX_MIQ_DEVICE_ID:
51 *cmdaddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
54 case WLAN_TX_LOQ_DEVICE_ID:
55 *cmdaddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
58 case WLAN_RX0FF_DEVICE_ID:
59 *cmdaddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (addr & WLAN_RX0FF_MSK));
67 static u8 get_deviceid(u32 addr)
73 pseudo_id = (u16)(addr >> 16);
76 devide_id = SDIO_LOCAL_DEVICE_ID;
80 devide_id = WLAN_IOREG_DEVICE_ID;
84 /* devide_id = SDIO_FIRMWARE_FIFO; */
88 devide_id = WLAN_TX_HIQ_DEVICE_ID;
92 devide_id = WLAN_TX_MIQ_DEVICE_ID;
96 devide_id = WLAN_TX_LOQ_DEVICE_ID;
100 devide_id = WLAN_RX0FF_DEVICE_ID;
104 /* devide_id = (u8)((addr >> 13) & 0xF); */
105 devide_id = WLAN_IOREG_DEVICE_ID;
114 *HalSdioGetCmdAddr8723BSdio()
116 static u32 _cvrt2ftaddr(const u32 addr, u8 *pdevice_id, u16 *poffset)
123 device_id = get_deviceid(addr);
127 case SDIO_LOCAL_DEVICE_ID:
128 offset = addr & SDIO_LOCAL_MSK;
131 case WLAN_TX_HIQ_DEVICE_ID:
132 case WLAN_TX_MIQ_DEVICE_ID:
133 case WLAN_TX_LOQ_DEVICE_ID:
134 offset = addr & WLAN_FIFO_MSK;
137 case WLAN_RX0FF_DEVICE_ID:
138 offset = addr & WLAN_RX0FF_MSK;
141 case WLAN_IOREG_DEVICE_ID:
143 device_id = WLAN_IOREG_DEVICE_ID;
144 offset = addr & WLAN_IOREG_MSK;
147 ftaddr = (device_id << 13) | offset;
150 *pdevice_id = device_id;
157 static u8 sdio_read8(struct intf_hdl *intfhdl, u32 addr)
160 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
162 return sd_read8(intfhdl, ftaddr, NULL);
165 static u16 sdio_read16(struct intf_hdl *intfhdl, u32 addr)
170 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
171 sd_cmd52_read(intfhdl, ftaddr, 2, (u8 *)&le_tmp);
173 return le16_to_cpu(le_tmp);
176 static u32 sdio_read32(struct intf_hdl *intfhdl, u32 addr)
178 struct adapter *adapter;
188 adapter = intfhdl->padapter;
189 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
191 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
193 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
194 (!mac_pwr_ctrl_on) ||
195 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
197 err = sd_cmd52_read(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
201 return le32_to_cpu(le_tmp);
205 DBG_8192C(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr = 0x%x\n", __func__, err, addr);
206 return SDIO_ERR_VAL32;
210 /* 4 bytes alignment */
211 shift = ftaddr & 0x3;
213 val = sd_read32(intfhdl, ftaddr, NULL);
217 tmpbuf = rtw_malloc(8);
219 DBG_8192C(KERN_ERR "%s: Allocate memory FAIL!(size =8) addr = 0x%x\n", __func__, addr);
220 return SDIO_ERR_VAL32;
224 sd_read(intfhdl, ftaddr, 8, tmpbuf);
225 memcpy(&le_tmp, tmpbuf+shift, 4);
226 val = le32_to_cpu(le_tmp);
233 static s32 sdio_readN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf)
235 struct adapter *adapter;
243 adapter = intfhdl->padapter;
246 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
248 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
250 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
251 (!mac_pwr_ctrl_on) ||
252 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
254 return sd_cmd52_read(intfhdl, ftaddr, cnt, buf);
256 /* 4 bytes alignment */
257 shift = ftaddr & 0x3;
259 err = sd_read(intfhdl, ftaddr, cnt, buf);
266 tmpbuf = rtw_malloc(n);
270 err = sd_read(intfhdl, ftaddr, n, tmpbuf);
272 memcpy(buf, tmpbuf+shift, cnt);
278 static s32 sdio_write8(struct intf_hdl *intfhdl, u32 addr, u8 val)
283 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
284 sd_write8(intfhdl, ftaddr, val, &err);
289 static s32 sdio_write16(struct intf_hdl *intfhdl, u32 addr, u16 val)
294 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
295 le_tmp = cpu_to_le16(val);
296 return sd_cmd52_write(intfhdl, ftaddr, 2, (u8 *)&le_tmp);
299 static s32 sdio_write32(struct intf_hdl *intfhdl, u32 addr, u32 val)
301 struct adapter *adapter;
310 adapter = intfhdl->padapter;
313 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
315 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
317 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
318 (!mac_pwr_ctrl_on) ||
319 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
321 le_tmp = cpu_to_le32(val);
323 return sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
326 /* 4 bytes alignment */
327 shift = ftaddr & 0x3;
329 sd_write32(intfhdl, ftaddr, val, &err);
331 le_tmp = cpu_to_le32(val);
332 err = sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
337 static s32 sdio_writeN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf)
339 struct adapter *adapter;
347 adapter = intfhdl->padapter;
350 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
352 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
354 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
355 (!mac_pwr_ctrl_on) ||
356 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
358 return sd_cmd52_write(intfhdl, ftaddr, cnt, buf);
360 shift = ftaddr & 0x3;
362 err = sd_write(intfhdl, ftaddr, cnt, buf);
369 tmpbuf = rtw_malloc(n);
372 err = sd_read(intfhdl, ftaddr, 4, tmpbuf);
377 memcpy(tmpbuf+shift, buf, cnt);
378 err = sd_write(intfhdl, ftaddr, n, tmpbuf);
384 static u8 sdio_f0_read8(struct intf_hdl *intfhdl, u32 addr)
386 return sd_f0_read8(intfhdl, addr, NULL);
389 static void sdio_read_mem(
390 struct intf_hdl *intfhdl,
398 err = sdio_readN(intfhdl, addr, cnt, rmem);
399 /* TODO: Report error is err not zero */
402 static void sdio_write_mem(
403 struct intf_hdl *intfhdl,
409 sdio_writeN(intfhdl, addr, cnt, wmem);
415 *Round read size to block size,
416 *and make sure data transfer will be done in one command.
419 *intfhdl a pointer of intf_hdl
422 *rmem address to put data
428 static u32 sdio_read_port(
429 struct intf_hdl *intfhdl,
435 struct adapter *adapter;
437 struct hal_com_data *hal;
439 #ifdef SDIO_DYNAMIC_ALLOC_MEM
445 adapter = intfhdl->padapter;
446 psdio = &adapter_to_dvobj(adapter)->intf_data;
447 hal = GET_HAL_DATA(adapter);
449 HalSdioGetCmdAddr8723BSdio(adapter, addr, hal->SdioRxFIFOCnt++, &addr);
452 if (cnt > psdio->block_transfer_len)
453 cnt = _RND(cnt, psdio->block_transfer_len);
454 /* cnt = sdio_align_size(cnt); */
456 err = _sd_read(intfhdl, addr, cnt, mem);
458 #ifdef SDIO_DYNAMIC_ALLOC_MEM
459 if ((oldcnt != cnt) && (oldmem)) {
460 memcpy(oldmem, mem, oldcnt);
473 *Align write size block size,
474 *and make sure data could be written in one command.
477 *intfhdl a pointer of intf_hdl
480 *wmem data pointer to write
486 static u32 sdio_write_port(
487 struct intf_hdl *intfhdl,
493 struct adapter *adapter;
496 struct xmit_buf *xmitbuf = (struct xmit_buf *)mem;
498 adapter = intfhdl->padapter;
499 psdio = &adapter_to_dvobj(adapter)->intf_data;
501 if (!adapter->hw_init_completed) {
502 DBG_871X("%s [addr = 0x%x cnt =%d] adapter->hw_init_completed == false\n", __func__, addr, cnt);
507 HalSdioGetCmdAddr8723BSdio(adapter, addr, cnt >> 2, &addr);
509 if (cnt > psdio->block_transfer_len)
510 cnt = _RND(cnt, psdio->block_transfer_len);
511 /* cnt = sdio_align_size(cnt); */
513 err = sd_write(intfhdl, addr, cnt, xmitbuf->pdata);
517 err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS
525 void sdio_set_intf_ops(struct adapter *adapter, struct _io_ops *ops)
527 ops->_read8 = &sdio_read8;
528 ops->_read16 = &sdio_read16;
529 ops->_read32 = &sdio_read32;
530 ops->_read_mem = &sdio_read_mem;
531 ops->_read_port = &sdio_read_port;
533 ops->_write8 = &sdio_write8;
534 ops->_write16 = &sdio_write16;
535 ops->_write32 = &sdio_write32;
536 ops->_writeN = &sdio_writeN;
537 ops->_write_mem = &sdio_write_mem;
538 ops->_write_port = &sdio_write_port;
540 ops->_sd_f0_read8 = sdio_f0_read8;
544 * Todo: align address to 4 bytes.
546 static s32 _sdio_local_read(
547 struct adapter *adapter,
553 struct intf_hdl *intfhdl;
560 intfhdl = &adapter->iopriv.intf;
562 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
564 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
565 if (!mac_pwr_ctrl_on)
566 return _sd_cmd52_read(intfhdl, addr, cnt, buf);
569 tmpbuf = rtw_malloc(n);
573 err = _sd_read(intfhdl, addr, n, tmpbuf);
575 memcpy(buf, tmpbuf, cnt);
583 * Todo: align address to 4 bytes.
586 struct adapter *adapter,
592 struct intf_hdl *intfhdl;
598 intfhdl = &adapter->iopriv.intf;
600 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
602 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
604 (!mac_pwr_ctrl_on) ||
605 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
607 return sd_cmd52_read(intfhdl, addr, cnt, buf);
610 tmpbuf = rtw_malloc(n);
614 err = sd_read(intfhdl, addr, n, tmpbuf);
616 memcpy(buf, tmpbuf, cnt);
624 * Todo: align address to 4 bytes.
626 s32 sdio_local_write(
627 struct adapter *adapter,
633 struct intf_hdl *intfhdl;
639 DBG_8192C("%s, address must be 4 bytes alignment\n", __func__);
642 DBG_8192C("%s, size must be the multiple of 4\n", __func__);
644 intfhdl = &adapter->iopriv.intf;
646 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
648 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
650 (!mac_pwr_ctrl_on) ||
651 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
653 return sd_cmd52_write(intfhdl, addr, cnt, buf);
655 tmpbuf = rtw_malloc(cnt);
659 memcpy(tmpbuf, buf, cnt);
661 err = sd_write(intfhdl, addr, cnt, tmpbuf);
668 u8 SdioLocalCmd52Read1Byte(struct adapter *adapter, u32 addr)
671 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
673 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
674 sd_cmd52_read(intfhdl, addr, 1, &val);
679 static u16 SdioLocalCmd52Read2Byte(struct adapter *adapter, u32 addr)
682 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
684 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
685 sd_cmd52_read(intfhdl, addr, 2, (u8 *)&val);
687 return le16_to_cpu(val);
690 static u32 SdioLocalCmd53Read4Byte(struct adapter *adapter, u32 addr)
695 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
698 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
699 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
700 if (!mac_pwr_ctrl_on || adapter_to_pwrctl(adapter)->bFwCurrentInPSMode) {
701 sd_cmd52_read(intfhdl, addr, 4, (u8 *)&le_tmp);
702 val = le32_to_cpu(le_tmp);
704 val = sd_read32(intfhdl, addr, NULL);
709 void SdioLocalCmd52Write1Byte(struct adapter *adapter, u32 addr, u8 v)
711 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
713 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
714 sd_cmd52_write(intfhdl, addr, 1, &v);
717 static void SdioLocalCmd52Write4Byte(struct adapter *adapter, u32 addr, u32 v)
719 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
722 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
723 le_tmp = cpu_to_le32(v);
724 sd_cmd52_write(intfhdl, addr, 4, (u8 *)&le_tmp);
727 static s32 ReadInterrupt8723BSdio(struct adapter *adapter, u32 *phisr)
736 himr = GET_HAL_DATA(adapter)->sdio_himr;
738 /* decide how many bytes need to be read */
746 while (hisr_len != 0) {
748 val8 = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HISR+hisr_len);
749 hisr |= (val8 << (8*hisr_len));
759 /* Initialize SDIO Host Interrupt Mask configuration variables for future use. */
762 /* Using SDIO Local register ONLY for configuration. */
764 /* Created by Roger, 2011.02.11. */
766 void InitInterrupt8723BSdio(struct adapter *adapter)
768 struct hal_com_data *haldata;
771 haldata = GET_HAL_DATA(adapter);
772 haldata->sdio_himr = (u32)( \
773 SDIO_HIMR_RX_REQUEST_MSK |
775 /* SDIO_HIMR_TXERR_MSK | */
776 /* SDIO_HIMR_RXERR_MSK | */
777 /* SDIO_HIMR_TXFOVW_MSK | */
778 /* SDIO_HIMR_RXFOVW_MSK | */
779 /* SDIO_HIMR_TXBCNOK_MSK | */
780 /* SDIO_HIMR_TXBCNERR_MSK | */
781 /* SDIO_HIMR_BCNERLY_INT_MSK | */
782 /* SDIO_HIMR_C2HCMD_MSK | */
783 /* SDIO_HIMR_HSISR_IND_MSK | */
784 /* SDIO_HIMR_GTINT3_IND_MSK | */
785 /* SDIO_HIMR_GTINT4_IND_MSK | */
786 /* SDIO_HIMR_PSTIMEOUT_MSK | */
787 /* SDIO_HIMR_OCPINT_MSK | */
788 /* SDIO_HIMR_ATIMEND_MSK | */
789 /* SDIO_HIMR_ATIMEND_E_MSK | */
790 /* SDIO_HIMR_CTWEND_MSK | */
796 /* Initialize System Host Interrupt Mask configuration variables for future use. */
798 /* Created by Roger, 2011.08.03. */
800 void InitSysInterrupt8723BSdio(struct adapter *adapter)
802 struct hal_com_data *haldata;
805 haldata = GET_HAL_DATA(adapter);
807 haldata->SysIntrMask = ( \
808 /* HSIMR_GPIO12_0_INT_EN | */
809 /* HSIMR_SPS_OCP_INT_EN | */
810 /* HSIMR_RON_INT_EN | */
811 /* HSIMR_PDNINT_EN | */
812 /* HSIMR_GPIO9_INT_EN | */
819 /* Clear corresponding SDIO Host ISR interrupt service. */
822 /* Using SDIO Local register ONLY for configuration. */
824 /* Created by Roger, 2011.02.11. */
826 void clearinterrupt8723bsdio(struct adapter *adapter)
828 struct hal_com_data *haldata;
831 if (adapter->bSurpriseRemoved)
834 haldata = GET_HAL_DATA(adapter);
835 clear = rtw_zmalloc(4);
837 /* Clear corresponding HISR Content if needed */
838 *(__le32 *)clear = cpu_to_le32(haldata->sdio_hisr & MASK_SDIO_HISR_CLEAR);
839 if (*(__le32 *)clear) {
840 /* Perform write one clear operation */
841 sdio_local_write(padapter, SDIO_REG_HISR, 4, clear);
850 /* Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain. */
853 /* 1. Using SDIO Local register ONLY for configuration. */
854 /* 2. PASSIVE LEVEL */
856 /* Created by Roger, 2011.02.11. */
858 void EnableInterrupt8723BSdio(struct adapter *adapter)
860 struct hal_com_data *haldata;
864 haldata = GET_HAL_DATA(adapter);
866 himr = cpu_to_le32(haldata->sdio_himr);
867 sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
873 "%s: enable SDIO HIMR = 0x%08X\n",
879 /* Update current system IMR settings */
880 tmp = rtw_read32(adapter, REG_HSIMR);
881 rtw_write32(adapter, REG_HSIMR, tmp | haldata->SysIntrMask);
887 "%s: enable HSIMR = 0x%08X\n",
894 /* <Roger_Notes> There are some C2H CMDs have been sent before system interrupt is enabled, e.g., C2H, CPWM. */
895 /* So we need to clear all C2H events that FW has notified, otherwise FW won't schedule any commands anymore. */
898 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
903 /* Disable SDIO Host IMR configuration to mask unnecessary interrupt service. */
906 /* Using SDIO Local register ONLY for configuration. */
908 /* Created by Roger, 2011.02.11. */
910 void DisableInterrupt8723BSdio(struct adapter *adapter)
914 himr = cpu_to_le32(SDIO_HIMR_DISABLED);
915 sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
920 /* Using 0x100 to check the power status of FW. */
923 /* Using SDIO Local register ONLY for configuration. */
925 /* Created by Isaac, 2013.09.10. */
927 u8 CheckIPSStatus(struct adapter *adapter)
930 "%s(): Read 0x100 = 0x%02x 0x86 = 0x%02x\n",
932 rtw_read8(adapter, 0x100),
933 rtw_read8(adapter, 0x86)
936 if (rtw_read8(adapter, 0x100) == 0xEA)
942 static struct recv_buf *sd_recv_rxfifo(struct adapter *adapter, u32 size)
946 struct recv_priv *recv_priv;
947 struct recv_buf *recvbuf;
950 /* Patch for some SDIO Host 4 bytes issue */
952 readsize = RND4(size);
954 /* 3 1. alloc recvbuf */
955 recv_priv = &adapter->recvpriv;
956 recvbuf = rtw_dequeue_recvbuf(&recv_priv->free_recv_buf_queue);
958 DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __func__);
963 if (!recvbuf->pskb) {
964 SIZE_PTR tmpaddr = 0;
965 SIZE_PTR alignment = 0;
967 recvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
970 recvbuf->pskb->dev = adapter->pnetdev;
972 tmpaddr = (SIZE_PTR)recvbuf->pskb->data;
973 alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
974 skb_reserve(recvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
977 if (!recvbuf->pskb) {
978 DBG_871X("%s: alloc_skb fail! read =%d\n", __func__, readsize);
983 /* 3 3. read data from rxfifo */
984 readbuf = recvbuf->pskb->data;
985 ret = sdio_read_port(&adapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, readbuf);
987 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __func__));
992 /* 3 4. init recvbuf */
994 recvbuf->phead = recvbuf->pskb->head;
995 recvbuf->pdata = recvbuf->pskb->data;
996 skb_set_tail_pointer(recvbuf->pskb, size);
997 recvbuf->ptail = skb_tail_pointer(recvbuf->pskb);
998 recvbuf->pend = skb_end_pointer(recvbuf->pskb);
1003 static void sd_rxhandler(struct adapter *adapter, struct recv_buf *recvbuf)
1005 struct recv_priv *recv_priv;
1006 struct __queue *pending_queue;
1008 recv_priv = &adapter->recvpriv;
1009 pending_queue = &recv_priv->recv_buf_pending_queue;
1011 /* 3 1. enqueue recvbuf */
1012 rtw_enqueue_recvbuf(recvbuf, pending_queue);
1014 /* 3 2. schedule tasklet */
1015 tasklet_schedule(&recv_priv->recv_tasklet);
1018 void sd_int_dpc(struct adapter *adapter)
1020 struct hal_com_data *hal;
1021 struct dvobj_priv *dvobj;
1022 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
1023 struct pwrctrl_priv *pwrctl;
1026 hal = GET_HAL_DATA(adapter);
1027 dvobj = adapter_to_dvobj(adapter);
1028 pwrctl = dvobj_to_pwrctl(dvobj);
1030 if (hal->sdio_hisr & SDIO_HISR_AVAL) {
1033 _sdio_local_read(adapter, SDIO_REG_FREE_TXPG, 4, freepage);
1034 up(&(adapter->xmitpriv.xmit_sema));
1037 if (hal->sdio_hisr & SDIO_HISR_CPWM1) {
1038 struct reportpwrstate_parm report;
1041 _cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled);
1043 report.state = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HCPWM1_8723B);
1045 /* cpwm_int_hdl(adapter, &report); */
1046 _set_workitem(&(pwrctl->cpwm_event));
1049 if (hal->sdio_hisr & SDIO_HISR_TXERR) {
1053 status = rtw_malloc(4);
1055 addr = REG_TXDMA_STATUS;
1056 HalSdioGetCmdAddr8723BSdio(adapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
1057 _sd_read(intfhdl, addr, 4, status);
1058 _sd_write(intfhdl, addr, 4, status);
1059 DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32 *)status));
1062 DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
1066 if (hal->sdio_hisr & SDIO_HISR_TXBCNOK) {
1067 DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
1070 if (hal->sdio_hisr & SDIO_HISR_TXBCNERR) {
1071 DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
1073 #ifndef CONFIG_C2H_PACKET_EN
1074 if (hal->sdio_hisr & SDIO_HISR_C2HCMD) {
1075 struct c2h_evt_hdr_88xx *c2h_evt;
1077 DBG_8192C("%s: C2H Command\n", __func__);
1078 c2h_evt = rtw_zmalloc(16);
1079 if (c2h_evt != NULL) {
1080 if (rtw_hal_c2h_evt_read(adapter, (u8 *)c2h_evt) == _SUCCESS) {
1081 if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) {
1082 /* Handle CCX report here */
1083 rtw_hal_c2h_handler(adapter, (u8 *)c2h_evt);
1084 kfree((u8 *)c2h_evt);
1086 rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt);
1090 /* Error handling for malloc fail */
1091 if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, NULL) != _SUCCESS)
1092 DBG_871X("%s rtw_cbuf_push fail\n", __func__);
1093 _set_workitem(&adapter->evtpriv.c2h_wk);
1098 if (hal->sdio_hisr & SDIO_HISR_RXFOVW) {
1099 DBG_8192C("%s: Rx Overflow\n", __func__);
1102 if (hal->sdio_hisr & SDIO_HISR_RXERR) {
1103 DBG_8192C("%s: Rx Error\n", __func__);
1106 if (hal->sdio_hisr & SDIO_HISR_RX_REQUEST) {
1107 struct recv_buf *recvbuf;
1108 int alloc_fail_time = 0;
1111 /* DBG_8192C("%s: RX Request, size =%d\n", __func__, hal->SdioRxFIFOSize); */
1112 hal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
1114 hal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(adapter, SDIO_REG_RX0_REQ_LEN);
1115 if (hal->SdioRxFIFOSize != 0) {
1116 recvbuf = sd_recv_rxfifo(adapter, hal->SdioRxFIFOSize);
1118 sd_rxhandler(adapter, recvbuf);
1121 DBG_871X("recvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time);
1122 if (alloc_fail_time >= 10)
1125 hal->SdioRxFIFOSize = 0;
1130 ReadInterrupt8723BSdio(adapter, &hisr);
1131 hisr &= SDIO_HISR_RX_REQUEST;
1136 if (alloc_fail_time == 10)
1137 DBG_871X("exit because alloc memory failed more than 10 times\n");
1142 void sd_int_hdl(struct adapter *adapter)
1144 struct hal_com_data *hal;
1148 (adapter->bDriverStopped) || (adapter->bSurpriseRemoved)
1152 hal = GET_HAL_DATA(adapter);
1155 ReadInterrupt8723BSdio(adapter, &hal->sdio_hisr);
1157 if (hal->sdio_hisr & hal->sdio_himr) {
1160 hal->sdio_hisr &= hal->sdio_himr;
1163 v32 = hal->sdio_hisr & MASK_SDIO_HISR_CLEAR;
1165 SdioLocalCmd52Write4Byte(adapter, SDIO_REG_HISR, v32);
1168 sd_int_dpc(adapter);
1170 RT_TRACE(_module_hci_ops_c_, _drv_err_,
1171 ("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n",
1172 __func__, hal->sdio_hisr, hal->sdio_himr));
1178 /* Query SDIO Local register to query current the number of Free TxPacketBuffer page. */
1181 /* 1. Running at PASSIVE_LEVEL */
1182 /* 2. RT_TX_SPINLOCK is NOT acquired. */
1184 /* Created by Roger, 2011.01.28. */
1186 u8 HalQueryTxBufferStatus8723BSdio(struct adapter *adapter)
1188 struct hal_com_data *hal;
1189 u32 numof_free_page;
1193 hal = GET_HAL_DATA(adapter);
1195 numof_free_page = SdioLocalCmd53Read4Byte(adapter, SDIO_REG_FREE_TXPG);
1197 /* spin_lock_bh(&phal->SdioTxFIFOFreePageLock); */
1198 memcpy(hal->SdioTxFIFOFreePage, &numof_free_page, 4);
1199 RT_TRACE(_module_hci_ops_c_, _drv_notice_,
1200 ("%s: Free page for HIQ(%#x), MIDQ(%#x), LOWQ(%#x), PUBQ(%#x)\n",
1202 hal->SdioTxFIFOFreePage[HI_QUEUE_IDX],
1203 hal->SdioTxFIFOFreePage[MID_QUEUE_IDX],
1204 hal->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
1205 hal->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
1206 /* spin_unlock_bh(&hal->SdioTxFIFOFreePageLock); */
1213 /* Query SDIO Local register to get the current number of TX OQT Free Space. */
1215 u8 HalQueryTxOQTBufferStatus8723BSdio(struct adapter *adapter)
1217 struct hal_com_data *haldata = GET_HAL_DATA(adapter);
1219 haldata->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_OQT_FREE_PG);
1223 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1224 u8 RecvOnePkt(struct adapter *adapter, u32 size)
1226 struct recv_buf *recvbuf;
1227 struct dvobj_priv *sddev;
1228 PSDIO_DATA psdio_data;
1229 struct sdio_func *func;
1233 DBG_871X("+%s: size: %d+\n", __func__, size);
1236 DBG_871X(KERN_ERR "%s: adapter is NULL!\n", __func__);
1240 sddev = adapter_to_dvobj(adapter);
1241 psdio_data = &sddev->intf_data;
1242 func = psdio_data->func;
1245 sdio_claim_host(func);
1246 recvbuf = sd_recv_rxfifo(adapter, size);
1249 /* printk("Completed Recv One Pkt.\n"); */
1250 sd_rxhandler(adapter, recvbuf);
1255 sdio_release_host(func);
1257 DBG_871X("-%s-\n", __func__);
1260 #endif /* CONFIG_WOWLAN */