1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
6 *******************************************************************************/
10 #include <rtw_debug.h>
11 #include <rtl8723b_hal.h>
13 /* define SDIO_DEBUG_IO 1 */
18 /* The following mapping is for SDIO host local register space. */
20 /* Creadted by Roger, 2011.01.31. */
22 static void HalSdioGetCmdAddr8723BSdio(
23 struct adapter *adapter,
30 case SDIO_LOCAL_DEVICE_ID:
31 *cmdaddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (addr & SDIO_LOCAL_MSK));
34 case WLAN_IOREG_DEVICE_ID:
35 *cmdaddr = ((WLAN_IOREG_DEVICE_ID << 13) | (addr & WLAN_IOREG_MSK));
38 case WLAN_TX_HIQ_DEVICE_ID:
39 *cmdaddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
42 case WLAN_TX_MIQ_DEVICE_ID:
43 *cmdaddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
46 case WLAN_TX_LOQ_DEVICE_ID:
47 *cmdaddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
50 case WLAN_RX0FF_DEVICE_ID:
51 *cmdaddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (addr & WLAN_RX0FF_MSK));
59 static u8 get_deviceid(u32 addr)
65 pseudo_id = (u16)(addr >> 16);
68 devide_id = SDIO_LOCAL_DEVICE_ID;
72 devide_id = WLAN_IOREG_DEVICE_ID;
76 /* devide_id = SDIO_FIRMWARE_FIFO; */
80 devide_id = WLAN_TX_HIQ_DEVICE_ID;
84 devide_id = WLAN_TX_MIQ_DEVICE_ID;
88 devide_id = WLAN_TX_LOQ_DEVICE_ID;
92 devide_id = WLAN_RX0FF_DEVICE_ID;
96 /* devide_id = (u8)((addr >> 13) & 0xF); */
97 devide_id = WLAN_IOREG_DEVICE_ID;
106 *HalSdioGetCmdAddr8723BSdio()
108 static u32 _cvrt2ftaddr(const u32 addr, u8 *pdevice_id, u16 *poffset)
115 device_id = get_deviceid(addr);
119 case SDIO_LOCAL_DEVICE_ID:
120 offset = addr & SDIO_LOCAL_MSK;
123 case WLAN_TX_HIQ_DEVICE_ID:
124 case WLAN_TX_MIQ_DEVICE_ID:
125 case WLAN_TX_LOQ_DEVICE_ID:
126 offset = addr & WLAN_FIFO_MSK;
129 case WLAN_RX0FF_DEVICE_ID:
130 offset = addr & WLAN_RX0FF_MSK;
133 case WLAN_IOREG_DEVICE_ID:
135 device_id = WLAN_IOREG_DEVICE_ID;
136 offset = addr & WLAN_IOREG_MSK;
139 ftaddr = (device_id << 13) | offset;
142 *pdevice_id = device_id;
149 static u8 sdio_read8(struct intf_hdl *intfhdl, u32 addr)
152 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
154 return sd_read8(intfhdl, ftaddr, NULL);
157 static u16 sdio_read16(struct intf_hdl *intfhdl, u32 addr)
162 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
163 sd_cmd52_read(intfhdl, ftaddr, 2, (u8 *)&le_tmp);
165 return le16_to_cpu(le_tmp);
168 static u32 sdio_read32(struct intf_hdl *intfhdl, u32 addr)
170 struct adapter *adapter;
180 adapter = intfhdl->padapter;
181 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
183 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
185 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
186 (!mac_pwr_ctrl_on) ||
187 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
189 err = sd_cmd52_read(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
193 return le32_to_cpu(le_tmp);
197 DBG_8192C(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr = 0x%x\n", __func__, err, addr);
198 return SDIO_ERR_VAL32;
202 /* 4 bytes alignment */
203 shift = ftaddr & 0x3;
205 val = sd_read32(intfhdl, ftaddr, NULL);
209 tmpbuf = rtw_malloc(8);
211 DBG_8192C(KERN_ERR "%s: Allocate memory FAIL!(size =8) addr = 0x%x\n", __func__, addr);
212 return SDIO_ERR_VAL32;
216 sd_read(intfhdl, ftaddr, 8, tmpbuf);
217 memcpy(&le_tmp, tmpbuf+shift, 4);
218 val = le32_to_cpu(le_tmp);
225 static s32 sdio_readN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf)
227 struct adapter *adapter;
235 adapter = intfhdl->padapter;
238 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
240 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
242 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
243 (!mac_pwr_ctrl_on) ||
244 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
246 return sd_cmd52_read(intfhdl, ftaddr, cnt, buf);
248 /* 4 bytes alignment */
249 shift = ftaddr & 0x3;
251 err = sd_read(intfhdl, ftaddr, cnt, buf);
258 tmpbuf = rtw_malloc(n);
262 err = sd_read(intfhdl, ftaddr, n, tmpbuf);
264 memcpy(buf, tmpbuf+shift, cnt);
270 static s32 sdio_write8(struct intf_hdl *intfhdl, u32 addr, u8 val)
275 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
276 sd_write8(intfhdl, ftaddr, val, &err);
281 static s32 sdio_write16(struct intf_hdl *intfhdl, u32 addr, u16 val)
286 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
287 le_tmp = cpu_to_le16(val);
288 return sd_cmd52_write(intfhdl, ftaddr, 2, (u8 *)&le_tmp);
291 static s32 sdio_write32(struct intf_hdl *intfhdl, u32 addr, u32 val)
293 struct adapter *adapter;
302 adapter = intfhdl->padapter;
305 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
307 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
309 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
310 (!mac_pwr_ctrl_on) ||
311 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
313 le_tmp = cpu_to_le32(val);
315 return sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
318 /* 4 bytes alignment */
319 shift = ftaddr & 0x3;
321 sd_write32(intfhdl, ftaddr, val, &err);
323 le_tmp = cpu_to_le32(val);
324 err = sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
329 static s32 sdio_writeN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf)
331 struct adapter *adapter;
339 adapter = intfhdl->padapter;
342 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
344 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
346 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
347 (!mac_pwr_ctrl_on) ||
348 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
350 return sd_cmd52_write(intfhdl, ftaddr, cnt, buf);
352 shift = ftaddr & 0x3;
354 err = sd_write(intfhdl, ftaddr, cnt, buf);
361 tmpbuf = rtw_malloc(n);
364 err = sd_read(intfhdl, ftaddr, 4, tmpbuf);
369 memcpy(tmpbuf+shift, buf, cnt);
370 err = sd_write(intfhdl, ftaddr, n, tmpbuf);
376 static u8 sdio_f0_read8(struct intf_hdl *intfhdl, u32 addr)
378 return sd_f0_read8(intfhdl, addr, NULL);
381 static void sdio_read_mem(
382 struct intf_hdl *intfhdl,
390 err = sdio_readN(intfhdl, addr, cnt, rmem);
391 /* TODO: Report error is err not zero */
394 static void sdio_write_mem(
395 struct intf_hdl *intfhdl,
401 sdio_writeN(intfhdl, addr, cnt, wmem);
407 *Round read size to block size,
408 *and make sure data transfer will be done in one command.
411 *intfhdl a pointer of intf_hdl
414 *rmem address to put data
420 static u32 sdio_read_port(
421 struct intf_hdl *intfhdl,
427 struct adapter *adapter;
429 struct hal_com_data *hal;
431 #ifdef SDIO_DYNAMIC_ALLOC_MEM
437 adapter = intfhdl->padapter;
438 psdio = &adapter_to_dvobj(adapter)->intf_data;
439 hal = GET_HAL_DATA(adapter);
441 HalSdioGetCmdAddr8723BSdio(adapter, addr, hal->SdioRxFIFOCnt++, &addr);
444 if (cnt > psdio->block_transfer_len)
445 cnt = _RND(cnt, psdio->block_transfer_len);
446 /* cnt = sdio_align_size(cnt); */
448 err = _sd_read(intfhdl, addr, cnt, mem);
450 #ifdef SDIO_DYNAMIC_ALLOC_MEM
451 if ((oldcnt != cnt) && (oldmem)) {
452 memcpy(oldmem, mem, oldcnt);
465 *Align write size block size,
466 *and make sure data could be written in one command.
469 *intfhdl a pointer of intf_hdl
472 *wmem data pointer to write
478 static u32 sdio_write_port(
479 struct intf_hdl *intfhdl,
485 struct adapter *adapter;
488 struct xmit_buf *xmitbuf = (struct xmit_buf *)mem;
490 adapter = intfhdl->padapter;
491 psdio = &adapter_to_dvobj(adapter)->intf_data;
493 if (!adapter->hw_init_completed) {
494 DBG_871X("%s [addr = 0x%x cnt =%d] adapter->hw_init_completed == false\n", __func__, addr, cnt);
499 HalSdioGetCmdAddr8723BSdio(adapter, addr, cnt >> 2, &addr);
501 if (cnt > psdio->block_transfer_len)
502 cnt = _RND(cnt, psdio->block_transfer_len);
503 /* cnt = sdio_align_size(cnt); */
505 err = sd_write(intfhdl, addr, cnt, xmitbuf->pdata);
509 err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS
517 void sdio_set_intf_ops(struct adapter *adapter, struct _io_ops *ops)
519 ops->_read8 = &sdio_read8;
520 ops->_read16 = &sdio_read16;
521 ops->_read32 = &sdio_read32;
522 ops->_read_mem = &sdio_read_mem;
523 ops->_read_port = &sdio_read_port;
525 ops->_write8 = &sdio_write8;
526 ops->_write16 = &sdio_write16;
527 ops->_write32 = &sdio_write32;
528 ops->_writeN = &sdio_writeN;
529 ops->_write_mem = &sdio_write_mem;
530 ops->_write_port = &sdio_write_port;
532 ops->_sd_f0_read8 = sdio_f0_read8;
536 * Todo: align address to 4 bytes.
538 static s32 _sdio_local_read(
539 struct adapter *adapter,
545 struct intf_hdl *intfhdl;
552 intfhdl = &adapter->iopriv.intf;
554 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
556 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
557 if (!mac_pwr_ctrl_on)
558 return _sd_cmd52_read(intfhdl, addr, cnt, buf);
561 tmpbuf = rtw_malloc(n);
565 err = _sd_read(intfhdl, addr, n, tmpbuf);
567 memcpy(buf, tmpbuf, cnt);
575 * Todo: align address to 4 bytes.
578 struct adapter *adapter,
584 struct intf_hdl *intfhdl;
590 intfhdl = &adapter->iopriv.intf;
592 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
594 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
596 (!mac_pwr_ctrl_on) ||
597 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
599 return sd_cmd52_read(intfhdl, addr, cnt, buf);
602 tmpbuf = rtw_malloc(n);
606 err = sd_read(intfhdl, addr, n, tmpbuf);
608 memcpy(buf, tmpbuf, cnt);
616 * Todo: align address to 4 bytes.
618 s32 sdio_local_write(
619 struct adapter *adapter,
625 struct intf_hdl *intfhdl;
631 DBG_8192C("%s, address must be 4 bytes alignment\n", __func__);
634 DBG_8192C("%s, size must be the multiple of 4\n", __func__);
636 intfhdl = &adapter->iopriv.intf;
638 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
640 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
642 (!mac_pwr_ctrl_on) ||
643 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
645 return sd_cmd52_write(intfhdl, addr, cnt, buf);
647 tmpbuf = rtw_malloc(cnt);
651 memcpy(tmpbuf, buf, cnt);
653 err = sd_write(intfhdl, addr, cnt, tmpbuf);
660 u8 SdioLocalCmd52Read1Byte(struct adapter *adapter, u32 addr)
663 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
665 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
666 sd_cmd52_read(intfhdl, addr, 1, &val);
671 static u16 SdioLocalCmd52Read2Byte(struct adapter *adapter, u32 addr)
674 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
676 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
677 sd_cmd52_read(intfhdl, addr, 2, (u8 *)&val);
679 return le16_to_cpu(val);
682 static u32 SdioLocalCmd53Read4Byte(struct adapter *adapter, u32 addr)
687 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
690 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
691 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
692 if (!mac_pwr_ctrl_on || adapter_to_pwrctl(adapter)->bFwCurrentInPSMode) {
693 sd_cmd52_read(intfhdl, addr, 4, (u8 *)&le_tmp);
694 val = le32_to_cpu(le_tmp);
696 val = sd_read32(intfhdl, addr, NULL);
701 void SdioLocalCmd52Write1Byte(struct adapter *adapter, u32 addr, u8 v)
703 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
705 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
706 sd_cmd52_write(intfhdl, addr, 1, &v);
709 static void SdioLocalCmd52Write4Byte(struct adapter *adapter, u32 addr, u32 v)
711 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
714 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
715 le_tmp = cpu_to_le32(v);
716 sd_cmd52_write(intfhdl, addr, 4, (u8 *)&le_tmp);
719 static s32 ReadInterrupt8723BSdio(struct adapter *adapter, u32 *phisr)
728 himr = GET_HAL_DATA(adapter)->sdio_himr;
730 /* decide how many bytes need to be read */
738 while (hisr_len != 0) {
740 val8 = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HISR+hisr_len);
741 hisr |= (val8 << (8*hisr_len));
751 /* Initialize SDIO Host Interrupt Mask configuration variables for future use. */
754 /* Using SDIO Local register ONLY for configuration. */
756 /* Created by Roger, 2011.02.11. */
758 void InitInterrupt8723BSdio(struct adapter *adapter)
760 struct hal_com_data *haldata;
763 haldata = GET_HAL_DATA(adapter);
764 haldata->sdio_himr = (u32)( \
765 SDIO_HIMR_RX_REQUEST_MSK |
767 /* SDIO_HIMR_TXERR_MSK | */
768 /* SDIO_HIMR_RXERR_MSK | */
769 /* SDIO_HIMR_TXFOVW_MSK | */
770 /* SDIO_HIMR_RXFOVW_MSK | */
771 /* SDIO_HIMR_TXBCNOK_MSK | */
772 /* SDIO_HIMR_TXBCNERR_MSK | */
773 /* SDIO_HIMR_BCNERLY_INT_MSK | */
774 /* SDIO_HIMR_C2HCMD_MSK | */
775 /* SDIO_HIMR_HSISR_IND_MSK | */
776 /* SDIO_HIMR_GTINT3_IND_MSK | */
777 /* SDIO_HIMR_GTINT4_IND_MSK | */
778 /* SDIO_HIMR_PSTIMEOUT_MSK | */
779 /* SDIO_HIMR_OCPINT_MSK | */
780 /* SDIO_HIMR_ATIMEND_MSK | */
781 /* SDIO_HIMR_ATIMEND_E_MSK | */
782 /* SDIO_HIMR_CTWEND_MSK | */
788 /* Initialize System Host Interrupt Mask configuration variables for future use. */
790 /* Created by Roger, 2011.08.03. */
792 void InitSysInterrupt8723BSdio(struct adapter *adapter)
794 struct hal_com_data *haldata;
797 haldata = GET_HAL_DATA(adapter);
799 haldata->SysIntrMask = ( \
800 /* HSIMR_GPIO12_0_INT_EN | */
801 /* HSIMR_SPS_OCP_INT_EN | */
802 /* HSIMR_RON_INT_EN | */
803 /* HSIMR_PDNINT_EN | */
804 /* HSIMR_GPIO9_INT_EN | */
811 /* Clear corresponding SDIO Host ISR interrupt service. */
814 /* Using SDIO Local register ONLY for configuration. */
816 /* Created by Roger, 2011.02.11. */
818 void clearinterrupt8723bsdio(struct adapter *adapter)
820 struct hal_com_data *haldata;
823 if (adapter->bSurpriseRemoved)
826 haldata = GET_HAL_DATA(adapter);
827 clear = rtw_zmalloc(4);
829 /* Clear corresponding HISR Content if needed */
830 *(__le32 *)clear = cpu_to_le32(haldata->sdio_hisr & MASK_SDIO_HISR_CLEAR);
831 if (*(__le32 *)clear) {
832 /* Perform write one clear operation */
833 sdio_local_write(padapter, SDIO_REG_HISR, 4, clear);
842 /* Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain. */
845 /* 1. Using SDIO Local register ONLY for configuration. */
846 /* 2. PASSIVE LEVEL */
848 /* Created by Roger, 2011.02.11. */
850 void EnableInterrupt8723BSdio(struct adapter *adapter)
852 struct hal_com_data *haldata;
856 haldata = GET_HAL_DATA(adapter);
858 himr = cpu_to_le32(haldata->sdio_himr);
859 sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
865 "%s: enable SDIO HIMR = 0x%08X\n",
871 /* Update current system IMR settings */
872 tmp = rtw_read32(adapter, REG_HSIMR);
873 rtw_write32(adapter, REG_HSIMR, tmp | haldata->SysIntrMask);
879 "%s: enable HSIMR = 0x%08X\n",
886 /* <Roger_Notes> There are some C2H CMDs have been sent before system interrupt is enabled, e.g., C2H, CPWM. */
887 /* So we need to clear all C2H events that FW has notified, otherwise FW won't schedule any commands anymore. */
890 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
895 /* Disable SDIO Host IMR configuration to mask unnecessary interrupt service. */
898 /* Using SDIO Local register ONLY for configuration. */
900 /* Created by Roger, 2011.02.11. */
902 void DisableInterrupt8723BSdio(struct adapter *adapter)
906 himr = cpu_to_le32(SDIO_HIMR_DISABLED);
907 sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
912 /* Using 0x100 to check the power status of FW. */
915 /* Using SDIO Local register ONLY for configuration. */
917 /* Created by Isaac, 2013.09.10. */
919 u8 CheckIPSStatus(struct adapter *adapter)
922 "%s(): Read 0x100 = 0x%02x 0x86 = 0x%02x\n",
924 rtw_read8(adapter, 0x100),
925 rtw_read8(adapter, 0x86)
928 if (rtw_read8(adapter, 0x100) == 0xEA)
934 static struct recv_buf *sd_recv_rxfifo(struct adapter *adapter, u32 size)
938 struct recv_priv *recv_priv;
939 struct recv_buf *recvbuf;
942 /* Patch for some SDIO Host 4 bytes issue */
944 readsize = RND4(size);
946 /* 3 1. alloc recvbuf */
947 recv_priv = &adapter->recvpriv;
948 recvbuf = rtw_dequeue_recvbuf(&recv_priv->free_recv_buf_queue);
950 DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __func__);
955 if (!recvbuf->pskb) {
956 SIZE_PTR tmpaddr = 0;
957 SIZE_PTR alignment = 0;
959 recvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
962 recvbuf->pskb->dev = adapter->pnetdev;
964 tmpaddr = (SIZE_PTR)recvbuf->pskb->data;
965 alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
966 skb_reserve(recvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
969 if (!recvbuf->pskb) {
970 DBG_871X("%s: alloc_skb fail! read =%d\n", __func__, readsize);
975 /* 3 3. read data from rxfifo */
976 readbuf = recvbuf->pskb->data;
977 ret = sdio_read_port(&adapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, readbuf);
979 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __func__));
984 /* 3 4. init recvbuf */
986 recvbuf->phead = recvbuf->pskb->head;
987 recvbuf->pdata = recvbuf->pskb->data;
988 skb_set_tail_pointer(recvbuf->pskb, size);
989 recvbuf->ptail = skb_tail_pointer(recvbuf->pskb);
990 recvbuf->pend = skb_end_pointer(recvbuf->pskb);
995 static void sd_rxhandler(struct adapter *adapter, struct recv_buf *recvbuf)
997 struct recv_priv *recv_priv;
998 struct __queue *pending_queue;
1000 recv_priv = &adapter->recvpriv;
1001 pending_queue = &recv_priv->recv_buf_pending_queue;
1003 /* 3 1. enqueue recvbuf */
1004 rtw_enqueue_recvbuf(recvbuf, pending_queue);
1006 /* 3 2. schedule tasklet */
1007 tasklet_schedule(&recv_priv->recv_tasklet);
1010 void sd_int_dpc(struct adapter *adapter)
1012 struct hal_com_data *hal;
1013 struct dvobj_priv *dvobj;
1014 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
1015 struct pwrctrl_priv *pwrctl;
1018 hal = GET_HAL_DATA(adapter);
1019 dvobj = adapter_to_dvobj(adapter);
1020 pwrctl = dvobj_to_pwrctl(dvobj);
1022 if (hal->sdio_hisr & SDIO_HISR_AVAL) {
1025 _sdio_local_read(adapter, SDIO_REG_FREE_TXPG, 4, freepage);
1026 up(&(adapter->xmitpriv.xmit_sema));
1029 if (hal->sdio_hisr & SDIO_HISR_CPWM1) {
1030 struct reportpwrstate_parm report;
1033 _cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled);
1035 report.state = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HCPWM1_8723B);
1037 /* cpwm_int_hdl(adapter, &report); */
1038 _set_workitem(&(pwrctl->cpwm_event));
1041 if (hal->sdio_hisr & SDIO_HISR_TXERR) {
1045 status = rtw_malloc(4);
1047 addr = REG_TXDMA_STATUS;
1048 HalSdioGetCmdAddr8723BSdio(adapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
1049 _sd_read(intfhdl, addr, 4, status);
1050 _sd_write(intfhdl, addr, 4, status);
1051 DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32 *)status));
1054 DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
1058 if (hal->sdio_hisr & SDIO_HISR_TXBCNOK) {
1059 DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
1062 if (hal->sdio_hisr & SDIO_HISR_TXBCNERR) {
1063 DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
1065 #ifndef CONFIG_C2H_PACKET_EN
1066 if (hal->sdio_hisr & SDIO_HISR_C2HCMD) {
1067 struct c2h_evt_hdr_88xx *c2h_evt;
1069 DBG_8192C("%s: C2H Command\n", __func__);
1070 c2h_evt = rtw_zmalloc(16);
1071 if (c2h_evt != NULL) {
1072 if (rtw_hal_c2h_evt_read(adapter, (u8 *)c2h_evt) == _SUCCESS) {
1073 if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) {
1074 /* Handle CCX report here */
1075 rtw_hal_c2h_handler(adapter, (u8 *)c2h_evt);
1076 kfree((u8 *)c2h_evt);
1078 rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt);
1084 /* Error handling for malloc fail */
1085 if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, NULL) != _SUCCESS)
1086 DBG_871X("%s rtw_cbuf_push fail\n", __func__);
1087 _set_workitem(&adapter->evtpriv.c2h_wk);
1092 if (hal->sdio_hisr & SDIO_HISR_RXFOVW) {
1093 DBG_8192C("%s: Rx Overflow\n", __func__);
1096 if (hal->sdio_hisr & SDIO_HISR_RXERR) {
1097 DBG_8192C("%s: Rx Error\n", __func__);
1100 if (hal->sdio_hisr & SDIO_HISR_RX_REQUEST) {
1101 struct recv_buf *recvbuf;
1102 int alloc_fail_time = 0;
1105 /* DBG_8192C("%s: RX Request, size =%d\n", __func__, hal->SdioRxFIFOSize); */
1106 hal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
1108 hal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(adapter, SDIO_REG_RX0_REQ_LEN);
1109 if (hal->SdioRxFIFOSize != 0) {
1110 recvbuf = sd_recv_rxfifo(adapter, hal->SdioRxFIFOSize);
1112 sd_rxhandler(adapter, recvbuf);
1115 DBG_871X("recvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time);
1116 if (alloc_fail_time >= 10)
1119 hal->SdioRxFIFOSize = 0;
1124 ReadInterrupt8723BSdio(adapter, &hisr);
1125 hisr &= SDIO_HISR_RX_REQUEST;
1130 if (alloc_fail_time == 10)
1131 DBG_871X("exit because alloc memory failed more than 10 times\n");
1136 void sd_int_hdl(struct adapter *adapter)
1138 struct hal_com_data *hal;
1142 (adapter->bDriverStopped) || (adapter->bSurpriseRemoved)
1146 hal = GET_HAL_DATA(adapter);
1149 ReadInterrupt8723BSdio(adapter, &hal->sdio_hisr);
1151 if (hal->sdio_hisr & hal->sdio_himr) {
1154 hal->sdio_hisr &= hal->sdio_himr;
1157 v32 = hal->sdio_hisr & MASK_SDIO_HISR_CLEAR;
1159 SdioLocalCmd52Write4Byte(adapter, SDIO_REG_HISR, v32);
1162 sd_int_dpc(adapter);
1164 RT_TRACE(_module_hci_ops_c_, _drv_err_,
1165 ("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n",
1166 __func__, hal->sdio_hisr, hal->sdio_himr));
1172 /* Query SDIO Local register to query current the number of Free TxPacketBuffer page. */
1175 /* 1. Running at PASSIVE_LEVEL */
1176 /* 2. RT_TX_SPINLOCK is NOT acquired. */
1178 /* Created by Roger, 2011.01.28. */
1180 u8 HalQueryTxBufferStatus8723BSdio(struct adapter *adapter)
1182 struct hal_com_data *hal;
1183 u32 numof_free_page;
1187 hal = GET_HAL_DATA(adapter);
1189 numof_free_page = SdioLocalCmd53Read4Byte(adapter, SDIO_REG_FREE_TXPG);
1191 /* spin_lock_bh(&phal->SdioTxFIFOFreePageLock); */
1192 memcpy(hal->SdioTxFIFOFreePage, &numof_free_page, 4);
1193 RT_TRACE(_module_hci_ops_c_, _drv_notice_,
1194 ("%s: Free page for HIQ(%#x), MIDQ(%#x), LOWQ(%#x), PUBQ(%#x)\n",
1196 hal->SdioTxFIFOFreePage[HI_QUEUE_IDX],
1197 hal->SdioTxFIFOFreePage[MID_QUEUE_IDX],
1198 hal->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
1199 hal->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
1200 /* spin_unlock_bh(&hal->SdioTxFIFOFreePageLock); */
1207 /* Query SDIO Local register to get the current number of TX OQT Free Space. */
1209 u8 HalQueryTxOQTBufferStatus8723BSdio(struct adapter *adapter)
1211 struct hal_com_data *haldata = GET_HAL_DATA(adapter);
1213 haldata->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_OQT_FREE_PG);
1217 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1218 u8 RecvOnePkt(struct adapter *adapter, u32 size)
1220 struct recv_buf *recvbuf;
1221 struct dvobj_priv *sddev;
1222 PSDIO_DATA psdio_data;
1223 struct sdio_func *func;
1227 DBG_871X("+%s: size: %d+\n", __func__, size);
1230 DBG_871X(KERN_ERR "%s: adapter is NULL!\n", __func__);
1234 sddev = adapter_to_dvobj(adapter);
1235 psdio_data = &sddev->intf_data;
1236 func = psdio_data->func;
1239 sdio_claim_host(func);
1240 recvbuf = sd_recv_rxfifo(adapter, size);
1243 /* printk("Completed Recv One Pkt.\n"); */
1244 sd_rxhandler(adapter, recvbuf);
1249 sdio_release_host(func);
1251 DBG_871X("-%s-\n", __func__);
1254 #endif /* CONFIG_WOWLAN */