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