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