root/drivers/staging/rtl8723bs/hal/sdio_ops.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. HalSdioGetCmdAddr8723BSdio
  2. get_deviceid
  3. _cvrt2ftaddr
  4. sdio_read8
  5. sdio_read16
  6. sdio_read32
  7. sdio_readN
  8. sdio_write8
  9. sdio_write16
  10. sdio_write32
  11. sdio_writeN
  12. sdio_f0_read8
  13. sdio_read_mem
  14. sdio_write_mem
  15. sdio_read_port
  16. sdio_write_port
  17. sdio_set_intf_ops
  18. _sdio_local_read
  19. sdio_local_read
  20. sdio_local_write
  21. SdioLocalCmd52Read1Byte
  22. SdioLocalCmd52Read2Byte
  23. SdioLocalCmd53Read4Byte
  24. SdioLocalCmd52Write1Byte
  25. SdioLocalCmd52Write4Byte
  26. ReadInterrupt8723BSdio
  27. InitInterrupt8723BSdio
  28. InitSysInterrupt8723BSdio
  29. EnableInterrupt8723BSdio
  30. DisableInterrupt8723BSdio
  31. CheckIPSStatus
  32. sd_recv_rxfifo
  33. sd_rxhandler
  34. sd_int_dpc
  35. sd_int_hdl
  36. HalQueryTxBufferStatus8723BSdio
  37. HalQueryTxOQTBufferStatus8723BSdio
  38. RecvOnePkt

   1 // SPDX-License-Identifier: GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   5  *
   6  *******************************************************************************/
   7 #define _SDIO_OPS_C_
   8 
   9 #include <drv_types.h>
  10 #include <rtw_debug.h>
  11 #include <rtl8723b_hal.h>
  12 
  13 /* define SDIO_DEBUG_IO 1 */
  14 
  15 
  16 /*  */
  17 /*  Description: */
  18 /*      The following mapping is for SDIO host local register space. */
  19 /*  */
  20 /*  Creadted by Roger, 2011.01.31. */
  21 /*  */
  22 static void HalSdioGetCmdAddr8723BSdio(
  23         struct adapter *adapter,
  24         u8 device_id,
  25         u32 addr,
  26         u32 *cmdaddr
  27 )
  28 {
  29         switch (device_id) {
  30         case SDIO_LOCAL_DEVICE_ID:
  31                 *cmdaddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (addr & SDIO_LOCAL_MSK));
  32                 break;
  33 
  34         case WLAN_IOREG_DEVICE_ID:
  35                 *cmdaddr = ((WLAN_IOREG_DEVICE_ID << 13) | (addr & WLAN_IOREG_MSK));
  36                 break;
  37 
  38         case WLAN_TX_HIQ_DEVICE_ID:
  39                 *cmdaddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
  40                 break;
  41 
  42         case WLAN_TX_MIQ_DEVICE_ID:
  43                 *cmdaddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
  44                 break;
  45 
  46         case WLAN_TX_LOQ_DEVICE_ID:
  47                 *cmdaddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
  48                 break;
  49 
  50         case WLAN_RX0FF_DEVICE_ID:
  51                 *cmdaddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (addr & WLAN_RX0FF_MSK));
  52                 break;
  53 
  54         default:
  55                 break;
  56         }
  57 }
  58 
  59 static u8 get_deviceid(u32 addr)
  60 {
  61         u8 devide_id;
  62         u16 pseudo_id;
  63 
  64 
  65         pseudo_id = (u16)(addr >> 16);
  66         switch (pseudo_id) {
  67         case 0x1025:
  68                 devide_id = SDIO_LOCAL_DEVICE_ID;
  69                 break;
  70 
  71         case 0x1026:
  72                 devide_id = WLAN_IOREG_DEVICE_ID;
  73                 break;
  74 
  75 /*              case 0x1027: */
  76 /*                      devide_id = SDIO_FIRMWARE_FIFO; */
  77 /*                      break; */
  78 
  79         case 0x1031:
  80                 devide_id = WLAN_TX_HIQ_DEVICE_ID;
  81                 break;
  82 
  83         case 0x1032:
  84                 devide_id = WLAN_TX_MIQ_DEVICE_ID;
  85                 break;
  86 
  87         case 0x1033:
  88                 devide_id = WLAN_TX_LOQ_DEVICE_ID;
  89                 break;
  90 
  91         case 0x1034:
  92                 devide_id = WLAN_RX0FF_DEVICE_ID;
  93                 break;
  94 
  95         default:
  96 /*                      devide_id = (u8)((addr >> 13) & 0xF); */
  97                 devide_id = WLAN_IOREG_DEVICE_ID;
  98                 break;
  99         }
 100 
 101         return devide_id;
 102 }
 103 
 104 /*
 105  * Ref:
 106  *HalSdioGetCmdAddr8723BSdio()
 107  */
 108 static u32 _cvrt2ftaddr(const u32 addr, u8 *pdevice_id, u16 *poffset)
 109 {
 110         u8 device_id;
 111         u16 offset;
 112         u32 ftaddr;
 113 
 114 
 115         device_id = get_deviceid(addr);
 116         offset = 0;
 117 
 118         switch (device_id) {
 119         case SDIO_LOCAL_DEVICE_ID:
 120                 offset = addr & SDIO_LOCAL_MSK;
 121                 break;
 122 
 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;
 127                 break;
 128 
 129         case WLAN_RX0FF_DEVICE_ID:
 130                 offset = addr & WLAN_RX0FF_MSK;
 131                 break;
 132 
 133         case WLAN_IOREG_DEVICE_ID:
 134         default:
 135                 device_id = WLAN_IOREG_DEVICE_ID;
 136                 offset = addr & WLAN_IOREG_MSK;
 137                 break;
 138         }
 139         ftaddr = (device_id << 13) | offset;
 140 
 141         if (pdevice_id)
 142                 *pdevice_id = device_id;
 143         if (poffset)
 144                 *poffset = offset;
 145 
 146         return ftaddr;
 147 }
 148 
 149 static u8 sdio_read8(struct intf_hdl *intfhdl, u32 addr)
 150 {
 151         u32 ftaddr;
 152         ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
 153 
 154         return sd_read8(intfhdl, ftaddr, NULL);
 155 }
 156 
 157 static u16 sdio_read16(struct intf_hdl *intfhdl, u32 addr)
 158 {
 159         u32 ftaddr;
 160         __le16 le_tmp;
 161 
 162         ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
 163         sd_cmd52_read(intfhdl, ftaddr, 2, (u8 *)&le_tmp);
 164 
 165         return le16_to_cpu(le_tmp);
 166 }
 167 
 168 static u32 sdio_read32(struct intf_hdl *intfhdl, u32 addr)
 169 {
 170         struct adapter *adapter;
 171         u8 mac_pwr_ctrl_on;
 172         u8 device_id;
 173         u16 offset;
 174         u32 ftaddr;
 175         u8 shift;
 176         u32 val;
 177         s32 err;
 178         __le32 le_tmp;
 179 
 180         adapter = intfhdl->padapter;
 181         ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
 182 
 183         rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 184         if (
 185                 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
 186                 (!mac_pwr_ctrl_on) ||
 187                 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
 188         ) {
 189                 err = sd_cmd52_read(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
 190 #ifdef SDIO_DEBUG_IO
 191                 if (!err) {
 192 #endif
 193                         return le32_to_cpu(le_tmp);
 194 #ifdef SDIO_DEBUG_IO
 195                 }
 196 
 197                 DBG_8192C(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr = 0x%x\n", __func__, err, addr);
 198                 return SDIO_ERR_VAL32;
 199 #endif
 200         }
 201 
 202         /*  4 bytes alignment */
 203         shift = ftaddr & 0x3;
 204         if (shift == 0) {
 205                 val = sd_read32(intfhdl, ftaddr, NULL);
 206         } else {
 207                 u8 *tmpbuf;
 208 
 209                 tmpbuf = rtw_malloc(8);
 210                 if (!tmpbuf) {
 211                         DBG_8192C(KERN_ERR "%s: Allocate memory FAIL!(size =8) addr = 0x%x\n", __func__, addr);
 212                         return SDIO_ERR_VAL32;
 213                 }
 214 
 215                 ftaddr &= ~(u16)0x3;
 216                 sd_read(intfhdl, ftaddr, 8, tmpbuf);
 217                 memcpy(&le_tmp, tmpbuf + shift, 4);
 218                 val = le32_to_cpu(le_tmp);
 219 
 220                 kfree(tmpbuf);
 221         }
 222         return val;
 223 }
 224 
 225 static s32 sdio_readN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf)
 226 {
 227         struct adapter *adapter;
 228         u8 mac_pwr_ctrl_on;
 229         u8 device_id;
 230         u16 offset;
 231         u32 ftaddr;
 232         u8 shift;
 233         s32 err;
 234 
 235         adapter = intfhdl->padapter;
 236         err = 0;
 237 
 238         ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
 239 
 240         rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 241         if (
 242                 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
 243                 (!mac_pwr_ctrl_on) ||
 244                 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
 245         )
 246                 return sd_cmd52_read(intfhdl, ftaddr, cnt, buf);
 247 
 248         /*  4 bytes alignment */
 249         shift = ftaddr & 0x3;
 250         if (shift == 0) {
 251                 err = sd_read(intfhdl, ftaddr, cnt, buf);
 252         } else {
 253                 u8 *tmpbuf;
 254                 u32 n;
 255 
 256                 ftaddr &= ~(u16)0x3;
 257                 n = cnt + shift;
 258                 tmpbuf = rtw_malloc(n);
 259                 if (!tmpbuf)
 260                         return -1;
 261 
 262                 err = sd_read(intfhdl, ftaddr, n, tmpbuf);
 263                 if (!err)
 264                         memcpy(buf, tmpbuf + shift, cnt);
 265                 kfree(tmpbuf);
 266         }
 267         return err;
 268 }
 269 
 270 static s32 sdio_write8(struct intf_hdl *intfhdl, u32 addr, u8 val)
 271 {
 272         u32 ftaddr;
 273         s32 err;
 274 
 275         ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
 276         sd_write8(intfhdl, ftaddr, val, &err);
 277 
 278         return err;
 279 }
 280 
 281 static s32 sdio_write16(struct intf_hdl *intfhdl, u32 addr, u16 val)
 282 {
 283         u32 ftaddr;
 284         __le16 le_tmp;
 285 
 286         ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
 287         le_tmp = cpu_to_le16(val);
 288         return sd_cmd52_write(intfhdl, ftaddr, 2, (u8 *)&le_tmp);
 289 }
 290 
 291 static s32 sdio_write32(struct intf_hdl *intfhdl, u32 addr, u32 val)
 292 {
 293         struct adapter *adapter;
 294         u8 mac_pwr_ctrl_on;
 295         u8 device_id;
 296         u16 offset;
 297         u32 ftaddr;
 298         u8 shift;
 299         s32 err;
 300         __le32 le_tmp;
 301 
 302         adapter = intfhdl->padapter;
 303         err = 0;
 304 
 305         ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
 306 
 307         rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 308         if (
 309                 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
 310                 (!mac_pwr_ctrl_on) ||
 311                 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
 312         ) {
 313                 le_tmp = cpu_to_le32(val);
 314 
 315                 return sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
 316         }
 317 
 318         /*  4 bytes alignment */
 319         shift = ftaddr & 0x3;
 320         if (shift == 0) {
 321                 sd_write32(intfhdl, ftaddr, val, &err);
 322         } else {
 323                 le_tmp = cpu_to_le32(val);
 324                 err = sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
 325         }
 326         return err;
 327 }
 328 
 329 static s32 sdio_writeN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf)
 330 {
 331         struct adapter *adapter;
 332         u8 mac_pwr_ctrl_on;
 333         u8 device_id;
 334         u16 offset;
 335         u32 ftaddr;
 336         u8 shift;
 337         s32 err;
 338 
 339         adapter = intfhdl->padapter;
 340         err = 0;
 341 
 342         ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
 343 
 344         rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 345         if (
 346                 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
 347                 (!mac_pwr_ctrl_on) ||
 348                 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
 349         )
 350                 return sd_cmd52_write(intfhdl, ftaddr, cnt, buf);
 351 
 352         shift = ftaddr & 0x3;
 353         if (shift == 0) {
 354                 err = sd_write(intfhdl, ftaddr, cnt, buf);
 355         } else {
 356                 u8 *tmpbuf;
 357                 u32 n;
 358 
 359                 ftaddr &= ~(u16)0x3;
 360                 n = cnt + shift;
 361                 tmpbuf = rtw_malloc(n);
 362                 if (!tmpbuf)
 363                         return -1;
 364                 err = sd_read(intfhdl, ftaddr, 4, tmpbuf);
 365                 if (err) {
 366                         kfree(tmpbuf);
 367                         return err;
 368                 }
 369                 memcpy(tmpbuf + shift, buf, cnt);
 370                 err = sd_write(intfhdl, ftaddr, n, tmpbuf);
 371                 kfree(tmpbuf);
 372         }
 373         return err;
 374 }
 375 
 376 static u8 sdio_f0_read8(struct intf_hdl *intfhdl, u32 addr)
 377 {
 378         return sd_f0_read8(intfhdl, addr, NULL);
 379 }
 380 
 381 static void sdio_read_mem(
 382         struct intf_hdl *intfhdl,
 383         u32 addr,
 384         u32 cnt,
 385         u8 *rmem
 386 )
 387 {
 388         s32 err;
 389 
 390         err = sdio_readN(intfhdl, addr, cnt, rmem);
 391         /* TODO: Report error is err not zero */
 392 }
 393 
 394 static void sdio_write_mem(
 395         struct intf_hdl *intfhdl,
 396         u32 addr,
 397         u32 cnt,
 398         u8 *wmem
 399 )
 400 {
 401         sdio_writeN(intfhdl, addr, cnt, wmem);
 402 }
 403 
 404 /*
 405  * Description:
 406  *Read from RX FIFO
 407  *Round read size to block size,
 408  *and make sure data transfer will be done in one command.
 409  *
 410  * Parameters:
 411  *intfhdl       a pointer of intf_hdl
 412  *addr          port ID
 413  *cnt                   size to read
 414  *rmem          address to put data
 415  *
 416  * Return:
 417  *_SUCCESS(1)           Success
 418  *_FAIL(0)              Fail
 419  */
 420 static u32 sdio_read_port(
 421         struct intf_hdl *intfhdl,
 422         u32 addr,
 423         u32 cnt,
 424         u8 *mem
 425 )
 426 {
 427         struct adapter *adapter;
 428         struct sdio_data *psdio;
 429         struct hal_com_data *hal;
 430         u32 oldcnt;
 431         s32 err;
 432 
 433 
 434         adapter = intfhdl->padapter;
 435         psdio = &adapter_to_dvobj(adapter)->intf_data;
 436         hal = GET_HAL_DATA(adapter);
 437 
 438         HalSdioGetCmdAddr8723BSdio(adapter, addr, hal->SdioRxFIFOCnt++, &addr);
 439 
 440         oldcnt = cnt;
 441         if (cnt > psdio->block_transfer_len)
 442                 cnt = _RND(cnt, psdio->block_transfer_len);
 443 /*      cnt = sdio_align_size(cnt); */
 444 
 445         err = _sd_read(intfhdl, addr, cnt, mem);
 446 
 447         if (err)
 448                 return _FAIL;
 449         return _SUCCESS;
 450 }
 451 
 452 /*
 453  * Description:
 454  *Write to TX FIFO
 455  *Align write size block size,
 456  *and make sure data could be written in one command.
 457  *
 458  * Parameters:
 459  *intfhdl       a pointer of intf_hdl
 460  *addr          port ID
 461  *cnt                   size to write
 462  *wmem          data pointer to write
 463  *
 464  * Return:
 465  *_SUCCESS(1)           Success
 466  *_FAIL(0)              Fail
 467  */
 468 static u32 sdio_write_port(
 469         struct intf_hdl *intfhdl,
 470         u32 addr,
 471         u32 cnt,
 472         u8 *mem
 473 )
 474 {
 475         struct adapter *adapter;
 476         struct sdio_data *psdio;
 477         s32 err;
 478         struct xmit_buf *xmitbuf = (struct xmit_buf *)mem;
 479 
 480         adapter = intfhdl->padapter;
 481         psdio = &adapter_to_dvobj(adapter)->intf_data;
 482 
 483         if (!adapter->hw_init_completed) {
 484                 DBG_871X("%s [addr = 0x%x cnt =%d] adapter->hw_init_completed == false\n", __func__, addr, cnt);
 485                 return _FAIL;
 486         }
 487 
 488         cnt = _RND4(cnt);
 489         HalSdioGetCmdAddr8723BSdio(adapter, addr, cnt >> 2, &addr);
 490 
 491         if (cnt > psdio->block_transfer_len)
 492                 cnt = _RND(cnt, psdio->block_transfer_len);
 493 /*      cnt = sdio_align_size(cnt); */
 494 
 495         err = sd_write(intfhdl, addr, cnt, xmitbuf->pdata);
 496 
 497         rtw_sctx_done_err(
 498                 &xmitbuf->sctx,
 499                 err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS
 500         );
 501 
 502         if (err)
 503                 return _FAIL;
 504         return _SUCCESS;
 505 }
 506 
 507 void sdio_set_intf_ops(struct adapter *adapter, struct _io_ops *ops)
 508 {
 509         ops->_read8 = &sdio_read8;
 510         ops->_read16 = &sdio_read16;
 511         ops->_read32 = &sdio_read32;
 512         ops->_read_mem = &sdio_read_mem;
 513         ops->_read_port = &sdio_read_port;
 514 
 515         ops->_write8 = &sdio_write8;
 516         ops->_write16 = &sdio_write16;
 517         ops->_write32 = &sdio_write32;
 518         ops->_writeN = &sdio_writeN;
 519         ops->_write_mem = &sdio_write_mem;
 520         ops->_write_port = &sdio_write_port;
 521 
 522         ops->_sd_f0_read8 = sdio_f0_read8;
 523 }
 524 
 525 /*
 526  * Todo: align address to 4 bytes.
 527  */
 528 static s32 _sdio_local_read(
 529         struct adapter *adapter,
 530         u32 addr,
 531         u32 cnt,
 532         u8 *buf
 533 )
 534 {
 535         struct intf_hdl *intfhdl;
 536         u8 mac_pwr_ctrl_on;
 537         s32 err;
 538         u8 *tmpbuf;
 539         u32 n;
 540 
 541 
 542         intfhdl = &adapter->iopriv.intf;
 543 
 544         HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 545 
 546         rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 547         if (!mac_pwr_ctrl_on)
 548                 return _sd_cmd52_read(intfhdl, addr, cnt, buf);
 549 
 550         n = RND4(cnt);
 551         tmpbuf = rtw_malloc(n);
 552         if (!tmpbuf)
 553                 return -1;
 554 
 555         err = _sd_read(intfhdl, addr, n, tmpbuf);
 556         if (!err)
 557                 memcpy(buf, tmpbuf, cnt);
 558 
 559         kfree(tmpbuf);
 560 
 561         return err;
 562 }
 563 
 564 /*
 565  * Todo: align address to 4 bytes.
 566  */
 567 s32 sdio_local_read(
 568         struct adapter *adapter,
 569         u32 addr,
 570         u32 cnt,
 571         u8 *buf
 572 )
 573 {
 574         struct intf_hdl *intfhdl;
 575         u8 mac_pwr_ctrl_on;
 576         s32 err;
 577         u8 *tmpbuf;
 578         u32 n;
 579 
 580         intfhdl = &adapter->iopriv.intf;
 581 
 582         HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 583 
 584         rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 585         if (
 586                 (!mac_pwr_ctrl_on) ||
 587                 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
 588         )
 589                 return sd_cmd52_read(intfhdl, addr, cnt, buf);
 590 
 591         n = RND4(cnt);
 592         tmpbuf = rtw_malloc(n);
 593         if (!tmpbuf)
 594                 return -1;
 595 
 596         err = sd_read(intfhdl, addr, n, tmpbuf);
 597         if (!err)
 598                 memcpy(buf, tmpbuf, cnt);
 599 
 600         kfree(tmpbuf);
 601 
 602         return err;
 603 }
 604 
 605 /*
 606  * Todo: align address to 4 bytes.
 607  */
 608 s32 sdio_local_write(
 609         struct adapter *adapter,
 610         u32 addr,
 611         u32 cnt,
 612         u8 *buf
 613 )
 614 {
 615         struct intf_hdl *intfhdl;
 616         u8 mac_pwr_ctrl_on;
 617         s32 err;
 618         u8 *tmpbuf;
 619 
 620         if (addr & 0x3)
 621                 DBG_8192C("%s, address must be 4 bytes alignment\n", __func__);
 622 
 623         if (cnt  & 0x3)
 624                 DBG_8192C("%s, size must be the multiple of 4\n", __func__);
 625 
 626         intfhdl = &adapter->iopriv.intf;
 627 
 628         HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 629 
 630         rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 631         if (
 632                 (!mac_pwr_ctrl_on) ||
 633                 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
 634         )
 635                 return sd_cmd52_write(intfhdl, addr, cnt, buf);
 636 
 637         tmpbuf = rtw_malloc(cnt);
 638         if (!tmpbuf)
 639                 return -1;
 640 
 641         memcpy(tmpbuf, buf, cnt);
 642 
 643         err = sd_write(intfhdl, addr, cnt, tmpbuf);
 644 
 645         kfree(tmpbuf);
 646 
 647         return err;
 648 }
 649 
 650 u8 SdioLocalCmd52Read1Byte(struct adapter *adapter, u32 addr)
 651 {
 652         u8 val = 0;
 653         struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 654 
 655         HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 656         sd_cmd52_read(intfhdl, addr, 1, &val);
 657 
 658         return val;
 659 }
 660 
 661 static u16 SdioLocalCmd52Read2Byte(struct adapter *adapter, u32 addr)
 662 {
 663         __le16 val = 0;
 664         struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 665 
 666         HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 667         sd_cmd52_read(intfhdl, addr, 2, (u8 *)&val);
 668 
 669         return le16_to_cpu(val);
 670 }
 671 
 672 static u32 SdioLocalCmd53Read4Byte(struct adapter *adapter, u32 addr)
 673 {
 674 
 675         u8 mac_pwr_ctrl_on;
 676         u32 val = 0;
 677         struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 678         __le32 le_tmp;
 679 
 680         HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 681         rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 682         if (!mac_pwr_ctrl_on || adapter_to_pwrctl(adapter)->bFwCurrentInPSMode) {
 683                 sd_cmd52_read(intfhdl, addr, 4, (u8 *)&le_tmp);
 684                 val = le32_to_cpu(le_tmp);
 685         } else {
 686                 val = sd_read32(intfhdl, addr, NULL);
 687         }
 688         return val;
 689 }
 690 
 691 void SdioLocalCmd52Write1Byte(struct adapter *adapter, u32 addr, u8 v)
 692 {
 693         struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 694 
 695         HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 696         sd_cmd52_write(intfhdl, addr, 1, &v);
 697 }
 698 
 699 static void SdioLocalCmd52Write4Byte(struct adapter *adapter, u32 addr, u32 v)
 700 {
 701         struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 702         __le32 le_tmp;
 703 
 704         HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 705         le_tmp = cpu_to_le32(v);
 706         sd_cmd52_write(intfhdl, addr, 4, (u8 *)&le_tmp);
 707 }
 708 
 709 static s32 ReadInterrupt8723BSdio(struct adapter *adapter, u32 *phisr)
 710 {
 711         u32 hisr, himr;
 712         u8 val8, hisr_len;
 713 
 714 
 715         if (!phisr)
 716                 return false;
 717 
 718         himr = GET_HAL_DATA(adapter)->sdio_himr;
 719 
 720         /*  decide how many bytes need to be read */
 721         hisr_len = 0;
 722         while (himr) {
 723                 hisr_len++;
 724                 himr >>= 8;
 725         }
 726 
 727         hisr = 0;
 728         while (hisr_len != 0) {
 729                 hisr_len--;
 730                 val8 = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HISR + hisr_len);
 731                 hisr |= (val8 << (8 * hisr_len));
 732         }
 733 
 734         *phisr = hisr;
 735 
 736         return true;
 737 }
 738 
 739 /*  */
 740 /*      Description: */
 741 /*              Initialize SDIO Host Interrupt Mask configuration variables for future use. */
 742 /*  */
 743 /*      Assumption: */
 744 /*              Using SDIO Local register ONLY for configuration. */
 745 /*  */
 746 /*      Created by Roger, 2011.02.11. */
 747 /*  */
 748 void InitInterrupt8723BSdio(struct adapter *adapter)
 749 {
 750         struct hal_com_data *haldata;
 751 
 752 
 753         haldata = GET_HAL_DATA(adapter);
 754         haldata->sdio_himr = (u32)(             \
 755                                                                 SDIO_HIMR_RX_REQUEST_MSK                        |
 756                                                                 SDIO_HIMR_AVAL_MSK                                      |
 757 /*                                                              SDIO_HIMR_TXERR_MSK                             | */
 758 /*                                                              SDIO_HIMR_RXERR_MSK                             | */
 759 /*                                                              SDIO_HIMR_TXFOVW_MSK                            | */
 760 /*                                                              SDIO_HIMR_RXFOVW_MSK                            | */
 761 /*                                                              SDIO_HIMR_TXBCNOK_MSK                           | */
 762 /*                                                              SDIO_HIMR_TXBCNERR_MSK                  | */
 763 /*                                                              SDIO_HIMR_BCNERLY_INT_MSK                       | */
 764 /*                                                              SDIO_HIMR_C2HCMD_MSK                            | */
 765 /*                                                              SDIO_HIMR_HSISR_IND_MSK                 | */
 766 /*                                                              SDIO_HIMR_GTINT3_IND_MSK                        | */
 767 /*                                                              SDIO_HIMR_GTINT4_IND_MSK                        | */
 768 /*                                                              SDIO_HIMR_PSTIMEOUT_MSK                 | */
 769 /*                                                              SDIO_HIMR_OCPINT_MSK                            | */
 770 /*                                                              SDIO_HIMR_ATIMEND_MSK                           | */
 771 /*                                                              SDIO_HIMR_ATIMEND_E_MSK                 | */
 772 /*                                                              SDIO_HIMR_CTWEND_MSK                            | */
 773                                                                 0);
 774 }
 775 
 776 /*  */
 777 /*      Description: */
 778 /*              Initialize System Host Interrupt Mask configuration variables for future use. */
 779 /*  */
 780 /*      Created by Roger, 2011.08.03. */
 781 /*  */
 782 void InitSysInterrupt8723BSdio(struct adapter *adapter)
 783 {
 784         struct hal_com_data *haldata;
 785 
 786 
 787         haldata = GET_HAL_DATA(adapter);
 788 
 789         haldata->SysIntrMask = (                \
 790 /*                                                      HSIMR_GPIO12_0_INT_EN                   | */
 791 /*                                                      HSIMR_SPS_OCP_INT_EN                    | */
 792 /*                                                      HSIMR_RON_INT_EN                                | */
 793 /*                                                      HSIMR_PDNINT_EN                         | */
 794 /*                                                      HSIMR_GPIO9_INT_EN                              | */
 795                                                         0);
 796 }
 797 
 798 /*  */
 799 /*      Description: */
 800 /*              Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain. */
 801 /*  */
 802 /*      Assumption: */
 803 /*              1. Using SDIO Local register ONLY for configuration. */
 804 /*              2. PASSIVE LEVEL */
 805 /*  */
 806 /*      Created by Roger, 2011.02.11. */
 807 /*  */
 808 void EnableInterrupt8723BSdio(struct adapter *adapter)
 809 {
 810         struct hal_com_data *haldata;
 811         __le32 himr;
 812         u32 tmp;
 813 
 814         haldata = GET_HAL_DATA(adapter);
 815 
 816         himr = cpu_to_le32(haldata->sdio_himr);
 817         sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
 818 
 819         RT_TRACE(
 820                 _module_hci_ops_c_,
 821                 _drv_notice_,
 822                 (
 823                         "%s: enable SDIO HIMR = 0x%08X\n",
 824                         __func__,
 825                         haldata->sdio_himr
 826                 )
 827         );
 828 
 829         /*  Update current system IMR settings */
 830         tmp = rtw_read32(adapter, REG_HSIMR);
 831         rtw_write32(adapter, REG_HSIMR, tmp | haldata->SysIntrMask);
 832 
 833         RT_TRACE(
 834                 _module_hci_ops_c_,
 835                 _drv_notice_,
 836                 (
 837                         "%s: enable HSIMR = 0x%08X\n",
 838                         __func__,
 839                         haldata->SysIntrMask
 840                 )
 841         );
 842 
 843         /*  */
 844         /*  <Roger_Notes> There are some C2H CMDs have been sent before system interrupt is enabled, e.g., C2H, CPWM. */
 845         /*  So we need to clear all C2H events that FW has notified, otherwise FW won't schedule any commands anymore. */
 846         /*  2011.10.19. */
 847         /*  */
 848         rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
 849 }
 850 
 851 /*  */
 852 /*      Description: */
 853 /*              Disable SDIO Host IMR configuration to mask unnecessary interrupt service. */
 854 /*  */
 855 /*      Assumption: */
 856 /*              Using SDIO Local register ONLY for configuration. */
 857 /*  */
 858 /*      Created by Roger, 2011.02.11. */
 859 /*  */
 860 void DisableInterrupt8723BSdio(struct adapter *adapter)
 861 {
 862         __le32 himr;
 863 
 864         himr = cpu_to_le32(SDIO_HIMR_DISABLED);
 865         sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
 866 }
 867 
 868 /*  */
 869 /*      Description: */
 870 /*              Using 0x100 to check the power status of FW. */
 871 /*  */
 872 /*      Assumption: */
 873 /*              Using SDIO Local register ONLY for configuration. */
 874 /*  */
 875 /*      Created by Isaac, 2013.09.10. */
 876 /*  */
 877 u8 CheckIPSStatus(struct adapter *adapter)
 878 {
 879         DBG_871X(
 880                 "%s(): Read 0x100 = 0x%02x 0x86 = 0x%02x\n",
 881                 __func__,
 882                 rtw_read8(adapter, 0x100),
 883                 rtw_read8(adapter, 0x86)
 884         );
 885 
 886         if (rtw_read8(adapter, 0x100) == 0xEA)
 887                 return true;
 888         else
 889                 return false;
 890 }
 891 
 892 static struct recv_buf *sd_recv_rxfifo(struct adapter *adapter, u32 size)
 893 {
 894         u32 readsize, ret;
 895         u8 *readbuf;
 896         struct recv_priv *recv_priv;
 897         struct recv_buf *recvbuf;
 898 
 899 
 900         /*  Patch for some SDIO Host 4 bytes issue */
 901         /*  ex. RK3188 */
 902         readsize = RND4(size);
 903 
 904         /* 3 1. alloc recvbuf */
 905         recv_priv = &adapter->recvpriv;
 906         recvbuf = rtw_dequeue_recvbuf(&recv_priv->free_recv_buf_queue);
 907         if (!recvbuf) {
 908                 DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __func__);
 909                 return NULL;
 910         }
 911 
 912         /* 3 2. alloc skb */
 913         if (!recvbuf->pskb) {
 914                 SIZE_PTR tmpaddr = 0;
 915                 SIZE_PTR alignment = 0;
 916 
 917                 recvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
 918 
 919                 if (recvbuf->pskb) {
 920                         recvbuf->pskb->dev = adapter->pnetdev;
 921 
 922                         tmpaddr = (SIZE_PTR)recvbuf->pskb->data;
 923                         alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
 924                         skb_reserve(recvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
 925                 }
 926 
 927                 if (!recvbuf->pskb) {
 928                         DBG_871X("%s: alloc_skb fail! read =%d\n", __func__, readsize);
 929                         return NULL;
 930                 }
 931         }
 932 
 933         /* 3 3. read data from rxfifo */
 934         readbuf = recvbuf->pskb->data;
 935         ret = sdio_read_port(&adapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, readbuf);
 936         if (ret == _FAIL) {
 937                 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __func__));
 938                 return NULL;
 939         }
 940 
 941 
 942         /* 3 4. init recvbuf */
 943         recvbuf->len = size;
 944         recvbuf->phead = recvbuf->pskb->head;
 945         recvbuf->pdata = recvbuf->pskb->data;
 946         skb_set_tail_pointer(recvbuf->pskb, size);
 947         recvbuf->ptail = skb_tail_pointer(recvbuf->pskb);
 948         recvbuf->pend = skb_end_pointer(recvbuf->pskb);
 949 
 950         return recvbuf;
 951 }
 952 
 953 static void sd_rxhandler(struct adapter *adapter, struct recv_buf *recvbuf)
 954 {
 955         struct recv_priv *recv_priv;
 956         struct __queue *pending_queue;
 957 
 958         recv_priv = &adapter->recvpriv;
 959         pending_queue = &recv_priv->recv_buf_pending_queue;
 960 
 961         /* 3 1. enqueue recvbuf */
 962         rtw_enqueue_recvbuf(recvbuf, pending_queue);
 963 
 964         /* 3 2. schedule tasklet */
 965         tasklet_schedule(&recv_priv->recv_tasklet);
 966 }
 967 
 968 void sd_int_dpc(struct adapter *adapter)
 969 {
 970         struct hal_com_data *hal;
 971         struct dvobj_priv *dvobj;
 972         struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 973         struct pwrctrl_priv *pwrctl;
 974 
 975 
 976         hal = GET_HAL_DATA(adapter);
 977         dvobj = adapter_to_dvobj(adapter);
 978         pwrctl = dvobj_to_pwrctl(dvobj);
 979 
 980         if (hal->sdio_hisr & SDIO_HISR_AVAL) {
 981                 u8 freepage[4];
 982 
 983                 _sdio_local_read(adapter, SDIO_REG_FREE_TXPG, 4, freepage);
 984                 complete(&(adapter->xmitpriv.xmit_comp));
 985         }
 986 
 987         if (hal->sdio_hisr & SDIO_HISR_CPWM1) {
 988                 struct reportpwrstate_parm report;
 989 
 990                 u8 bcancelled;
 991                 _cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled);
 992 
 993                 report.state = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HCPWM1_8723B);
 994 
 995                 /* cpwm_int_hdl(adapter, &report); */
 996                 _set_workitem(&(pwrctl->cpwm_event));
 997         }
 998 
 999         if (hal->sdio_hisr & SDIO_HISR_TXERR) {
1000                 u8 *status;
1001                 u32 addr;
1002 
1003                 status = rtw_malloc(4);
1004                 if (status) {
1005                         addr = REG_TXDMA_STATUS;
1006                         HalSdioGetCmdAddr8723BSdio(adapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
1007                         _sd_read(intfhdl, addr, 4, status);
1008                         _sd_write(intfhdl, addr, 4, status);
1009                         DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32 *)status));
1010                         kfree(status);
1011                 } else {
1012                         DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
1013                 }
1014         }
1015 
1016         if (hal->sdio_hisr & SDIO_HISR_TXBCNOK)
1017                 DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
1018 
1019         if (hal->sdio_hisr & SDIO_HISR_TXBCNERR)
1020                 DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
1021 #ifndef CONFIG_C2H_PACKET_EN
1022         if (hal->sdio_hisr & SDIO_HISR_C2HCMD) {
1023                 struct c2h_evt_hdr_88xx *c2h_evt;
1024 
1025                 DBG_8192C("%s: C2H Command\n", __func__);
1026                 c2h_evt = rtw_zmalloc(16);
1027                 if (c2h_evt) {
1028                         if (c2h_evt_read_88xx(adapter, (u8 *)c2h_evt) == _SUCCESS) {
1029                                 if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) {
1030                                         /* Handle CCX report here */
1031                                         rtw_hal_c2h_handler(adapter, (u8 *)c2h_evt);
1032                                         kfree((u8 *)c2h_evt);
1033                                 } else {
1034                                         rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt);
1035                                 }
1036                         }
1037                 } else {
1038                         /* Error handling for malloc fail */
1039                         if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, NULL) != _SUCCESS)
1040                                 DBG_871X("%s rtw_cbuf_push fail\n", __func__);
1041                         _set_workitem(&adapter->evtpriv.c2h_wk);
1042                 }
1043         }
1044 #endif
1045 
1046         if (hal->sdio_hisr & SDIO_HISR_RXFOVW)
1047                 DBG_8192C("%s: Rx Overflow\n", __func__);
1048 
1049         if (hal->sdio_hisr & SDIO_HISR_RXERR)
1050                 DBG_8192C("%s: Rx Error\n", __func__);
1051 
1052 
1053         if (hal->sdio_hisr & SDIO_HISR_RX_REQUEST) {
1054                 struct recv_buf *recvbuf;
1055                 int alloc_fail_time = 0;
1056                 u32 hisr;
1057 
1058 /*              DBG_8192C("%s: RX Request, size =%d\n", __func__, hal->SdioRxFIFOSize); */
1059                 hal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
1060                 do {
1061                         hal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(adapter, SDIO_REG_RX0_REQ_LEN);
1062                         if (hal->SdioRxFIFOSize != 0) {
1063                                 recvbuf = sd_recv_rxfifo(adapter, hal->SdioRxFIFOSize);
1064                                 if (recvbuf)
1065                                         sd_rxhandler(adapter, recvbuf);
1066                                 else {
1067                                         alloc_fail_time++;
1068                                         DBG_871X("recvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time);
1069                                         if (alloc_fail_time >= 10)
1070                                                 break;
1071                                 }
1072                                 hal->SdioRxFIFOSize = 0;
1073                         } else
1074                                 break;
1075 
1076                         hisr = 0;
1077                         ReadInterrupt8723BSdio(adapter, &hisr);
1078                         hisr &= SDIO_HISR_RX_REQUEST;
1079                         if (!hisr)
1080                                 break;
1081                 } while (1);
1082 
1083                 if (alloc_fail_time == 10)
1084                         DBG_871X("exit because alloc memory failed more than 10 times\n");
1085 
1086         }
1087 }
1088 
1089 void sd_int_hdl(struct adapter *adapter)
1090 {
1091         struct hal_com_data *hal;
1092 
1093 
1094         if (
1095                 (adapter->bDriverStopped) || (adapter->bSurpriseRemoved)
1096         )
1097                 return;
1098 
1099         hal = GET_HAL_DATA(adapter);
1100 
1101         hal->sdio_hisr = 0;
1102         ReadInterrupt8723BSdio(adapter, &hal->sdio_hisr);
1103 
1104         if (hal->sdio_hisr & hal->sdio_himr) {
1105                 u32 v32;
1106 
1107                 hal->sdio_hisr &= hal->sdio_himr;
1108 
1109                 /*  clear HISR */
1110                 v32 = hal->sdio_hisr & MASK_SDIO_HISR_CLEAR;
1111                 if (v32)
1112                         SdioLocalCmd52Write4Byte(adapter, SDIO_REG_HISR, v32);
1113 
1114                 sd_int_dpc(adapter);
1115         } else {
1116                 RT_TRACE(_module_hci_ops_c_, _drv_err_,
1117                                 ("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n",
1118                                 __func__, hal->sdio_hisr, hal->sdio_himr));
1119         }
1120 }
1121 
1122 /*  */
1123 /*      Description: */
1124 /*              Query SDIO Local register to query current the number of Free TxPacketBuffer page. */
1125 /*  */
1126 /*      Assumption: */
1127 /*              1. Running at PASSIVE_LEVEL */
1128 /*              2. RT_TX_SPINLOCK is NOT acquired. */
1129 /*  */
1130 /*      Created by Roger, 2011.01.28. */
1131 /*  */
1132 u8 HalQueryTxBufferStatus8723BSdio(struct adapter *adapter)
1133 {
1134         struct hal_com_data *hal;
1135         u32 numof_free_page;
1136         /* _irql irql; */
1137 
1138 
1139         hal = GET_HAL_DATA(adapter);
1140 
1141         numof_free_page = SdioLocalCmd53Read4Byte(adapter, SDIO_REG_FREE_TXPG);
1142 
1143         /* spin_lock_bh(&phal->SdioTxFIFOFreePageLock); */
1144         memcpy(hal->SdioTxFIFOFreePage, &numof_free_page, 4);
1145         RT_TRACE(_module_hci_ops_c_, _drv_notice_,
1146                         ("%s: Free page for HIQ(%#x), MIDQ(%#x), LOWQ(%#x), PUBQ(%#x)\n",
1147                         __func__,
1148                         hal->SdioTxFIFOFreePage[HI_QUEUE_IDX],
1149                         hal->SdioTxFIFOFreePage[MID_QUEUE_IDX],
1150                         hal->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
1151                         hal->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
1152         /* spin_unlock_bh(&hal->SdioTxFIFOFreePageLock); */
1153 
1154         return true;
1155 }
1156 
1157 /*  */
1158 /*      Description: */
1159 /*              Query SDIO Local register to get the current number of TX OQT Free Space. */
1160 /*  */
1161 void HalQueryTxOQTBufferStatus8723BSdio(struct adapter *adapter)
1162 {
1163         struct hal_com_data *haldata = GET_HAL_DATA(adapter);
1164 
1165         haldata->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_OQT_FREE_PG);
1166 }
1167 
1168 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1169 u8 RecvOnePkt(struct adapter *adapter, u32 size)
1170 {
1171         struct recv_buf *recvbuf;
1172         struct dvobj_priv *sddev;
1173         struct sdio_func *func;
1174 
1175         u8 res = false;
1176 
1177         DBG_871X("+%s: size: %d+\n", __func__, size);
1178 
1179         if (!adapter) {
1180                 DBG_871X(KERN_ERR "%s: adapter is NULL!\n", __func__);
1181                 return false;
1182         }
1183 
1184         sddev = adapter_to_dvobj(adapter);
1185         psdio_data = &sddev->intf_data;
1186         func = psdio_data->func;
1187 
1188         if (size) {
1189                 sdio_claim_host(func);
1190                 recvbuf = sd_recv_rxfifo(adapter, size);
1191 
1192                 if (recvbuf) {
1193                         /* printk("Completed Recv One Pkt.\n"); */
1194                         sd_rxhandler(adapter, recvbuf);
1195                         res = true;
1196                 } else {
1197                         res = false;
1198                 }
1199                 sdio_release_host(func);
1200         }
1201         DBG_871X("-%s-\n", __func__);
1202         return res;
1203 }
1204 #endif /* CONFIG_WOWLAN */

/* [<][>][^][v][top][bottom][index][help] */