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 */ 1205