1 /****************************************************************************** 2 * 3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 ******************************************************************************/ 15 #define _HCI_INTF_C_ 16 17 #include <drv_types.h> 18 #include <rtw_debug.h> 19 #include <linux/jiffies.h> 20 21 #ifndef dev_to_sdio_func 22 #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) 23 #endif 24 25 static const struct sdio_device_id sdio_ids[] = 26 { 27 { SDIO_DEVICE(0x024c, 0x0523), }, 28 { SDIO_DEVICE(0x024c, 0x0623), }, 29 { SDIO_DEVICE(0x024c, 0x0626), }, 30 { SDIO_DEVICE(0x024c, 0xb723), }, 31 { /* end: all zeroes */ }, 32 }; 33 static const struct acpi_device_id acpi_ids[] = { 34 {"OBDA8723", 0x0000}, 35 {} 36 }; 37 38 MODULE_DEVICE_TABLE(sdio, sdio_ids); 39 MODULE_DEVICE_TABLE(acpi, acpi_ids); 40 41 static int rtw_drv_init(struct sdio_func *func, const struct sdio_device_id *id); 42 static void rtw_dev_remove(struct sdio_func *func); 43 static int rtw_sdio_resume(struct device *dev); 44 static int rtw_sdio_suspend(struct device *dev); 45 46 static const struct dev_pm_ops rtw_sdio_pm_ops = { 47 .suspend = rtw_sdio_suspend, 48 .resume = rtw_sdio_resume, 49 }; 50 51 struct sdio_drv_priv { 52 struct sdio_driver r871xs_drv; 53 int drv_registered; 54 }; 55 56 static struct sdio_drv_priv sdio_drvpriv = { 57 .r871xs_drv.probe = rtw_drv_init, 58 .r871xs_drv.remove = rtw_dev_remove, 59 .r871xs_drv.name = "rtl8723bs", 60 .r871xs_drv.id_table = sdio_ids, 61 .r871xs_drv.drv = { 62 .pm = &rtw_sdio_pm_ops, 63 } 64 }; 65 66 static void sd_sync_int_hdl(struct sdio_func *func) 67 { 68 struct dvobj_priv *psdpriv; 69 70 71 psdpriv = sdio_get_drvdata(func); 72 73 if (!psdpriv->if1) { 74 DBG_871X("%s if1 == NULL\n", __func__); 75 return; 76 } 77 78 rtw_sdio_set_irq_thd(psdpriv, current); 79 sd_int_hdl(psdpriv->if1); 80 rtw_sdio_set_irq_thd(psdpriv, NULL); 81 } 82 83 static int sdio_alloc_irq(struct dvobj_priv *dvobj) 84 { 85 PSDIO_DATA psdio_data; 86 struct sdio_func *func; 87 int err; 88 89 psdio_data = &dvobj->intf_data; 90 func = psdio_data->func; 91 92 sdio_claim_host(func); 93 94 err = sdio_claim_irq(func, &sd_sync_int_hdl); 95 if (err) 96 { 97 dvobj->drv_dbg.dbg_sdio_alloc_irq_error_cnt++; 98 printk(KERN_CRIT "%s: sdio_claim_irq FAIL(%d)!\n", __func__, err); 99 } 100 else 101 { 102 dvobj->drv_dbg.dbg_sdio_alloc_irq_cnt++; 103 dvobj->irq_alloc = 1; 104 } 105 106 sdio_release_host(func); 107 108 return err?_FAIL:_SUCCESS; 109 } 110 111 static void sdio_free_irq(struct dvobj_priv *dvobj) 112 { 113 PSDIO_DATA psdio_data; 114 struct sdio_func *func; 115 int err; 116 117 if (dvobj->irq_alloc) { 118 psdio_data = &dvobj->intf_data; 119 func = psdio_data->func; 120 121 if (func) { 122 sdio_claim_host(func); 123 err = sdio_release_irq(func); 124 if (err) 125 { 126 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++; 127 DBG_871X_LEVEL(_drv_err_,"%s: sdio_release_irq FAIL(%d)!\n", __func__, err); 128 } 129 else 130 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++; 131 sdio_release_host(func); 132 } 133 dvobj->irq_alloc = 0; 134 } 135 } 136 137 #ifdef CONFIG_GPIO_WAKEUP 138 extern unsigned int oob_irq; 139 static irqreturn_t gpio_hostwakeup_irq_thread(int irq, void *data) 140 { 141 struct adapter *padapter = data; 142 DBG_871X_LEVEL(_drv_always_, "gpio_hostwakeup_irq_thread\n"); 143 /* Disable interrupt before calling handler */ 144 /* disable_irq_nosync(oob_irq); */ 145 rtw_lock_suspend_timeout(HZ/2); 146 return IRQ_HANDLED; 147 } 148 149 static u8 gpio_hostwakeup_alloc_irq(struct adapter *padapter) 150 { 151 int err; 152 if (oob_irq == 0) { 153 DBG_871X("oob_irq ZERO!\n"); 154 return _FAIL; 155 } 156 /* dont set it IRQF_TRIGGER_LOW, or wowlan */ 157 /* power is high after suspend */ 158 /* and failing can prevent can not sleep issue if */ 159 /* wifi gpio12 pin is not linked with CPU */ 160 err = request_threaded_irq(oob_irq, gpio_hostwakeup_irq_thread, NULL, 161 /* IRQF_TRIGGER_LOW | IRQF_ONESHOT, */ 162 IRQF_TRIGGER_FALLING, 163 "rtw_wifi_gpio_wakeup", padapter); 164 if (err < 0) { 165 DBG_871X("Oops: can't allocate gpio irq %d err:%d\n", oob_irq, err); 166 return false; 167 } else { 168 DBG_871X("allocate gpio irq %d ok\n", oob_irq); 169 } 170 171 enable_irq_wake(oob_irq); 172 return _SUCCESS; 173 } 174 175 static void gpio_hostwakeup_free_irq(struct adapter *padapter) 176 { 177 if (oob_irq == 0) 178 return; 179 180 disable_irq_wake(oob_irq); 181 free_irq(oob_irq, padapter); 182 } 183 #endif 184 185 static u32 sdio_init(struct dvobj_priv *dvobj) 186 { 187 PSDIO_DATA psdio_data; 188 struct sdio_func *func; 189 int err; 190 191 psdio_data = &dvobj->intf_data; 192 func = psdio_data->func; 193 194 /* 3 1. init SDIO bus */ 195 sdio_claim_host(func); 196 197 err = sdio_enable_func(func); 198 if (err) { 199 dvobj->drv_dbg.dbg_sdio_init_error_cnt++; 200 DBG_8192C(KERN_CRIT "%s: sdio_enable_func FAIL(%d)!\n", __func__, err); 201 goto release; 202 } 203 204 err = sdio_set_block_size(func, 512); 205 if (err) { 206 dvobj->drv_dbg.dbg_sdio_init_error_cnt++; 207 DBG_8192C(KERN_CRIT "%s: sdio_set_block_size FAIL(%d)!\n", __func__, err); 208 goto release; 209 } 210 psdio_data->block_transfer_len = 512; 211 psdio_data->tx_block_mode = 1; 212 psdio_data->rx_block_mode = 1; 213 214 release: 215 sdio_release_host(func); 216 217 if (err) 218 return _FAIL; 219 return _SUCCESS; 220 } 221 222 static void sdio_deinit(struct dvobj_priv *dvobj) 223 { 224 struct sdio_func *func; 225 int err; 226 227 228 RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+sdio_deinit\n")); 229 230 func = dvobj->intf_data.func; 231 232 if (func) { 233 sdio_claim_host(func); 234 err = sdio_disable_func(func); 235 if (err) 236 { 237 dvobj->drv_dbg.dbg_sdio_deinit_error_cnt++; 238 DBG_8192C(KERN_ERR "%s: sdio_disable_func(%d)\n", __func__, err); 239 } 240 241 if (dvobj->irq_alloc) { 242 err = sdio_release_irq(func); 243 if (err) 244 { 245 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++; 246 DBG_8192C(KERN_ERR "%s: sdio_release_irq(%d)\n", __func__, err); 247 } 248 else 249 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++; 250 } 251 252 sdio_release_host(func); 253 } 254 } 255 static struct dvobj_priv *sdio_dvobj_init(struct sdio_func *func) 256 { 257 int status = _FAIL; 258 struct dvobj_priv *dvobj = NULL; 259 PSDIO_DATA psdio; 260 261 dvobj = devobj_init(); 262 if (dvobj == NULL) { 263 goto exit; 264 } 265 266 sdio_set_drvdata(func, dvobj); 267 268 psdio = &dvobj->intf_data; 269 psdio->func = func; 270 271 if (sdio_init(dvobj) != _SUCCESS) { 272 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!\n", __func__)); 273 goto free_dvobj; 274 } 275 rtw_reset_continual_io_error(dvobj); 276 status = _SUCCESS; 277 278 free_dvobj: 279 if (status != _SUCCESS && dvobj) { 280 sdio_set_drvdata(func, NULL); 281 282 devobj_deinit(dvobj); 283 284 dvobj = NULL; 285 } 286 exit: 287 return dvobj; 288 } 289 290 static void sdio_dvobj_deinit(struct sdio_func *func) 291 { 292 struct dvobj_priv *dvobj = sdio_get_drvdata(func); 293 294 sdio_set_drvdata(func, NULL); 295 if (dvobj) { 296 sdio_deinit(dvobj); 297 devobj_deinit(dvobj); 298 } 299 return; 300 } 301 302 void rtw_set_hal_ops(struct adapter *padapter) 303 { 304 /* alloc memory for HAL DATA */ 305 rtw_hal_data_init(padapter); 306 307 rtl8723bs_set_hal_ops(padapter); 308 } 309 310 static void sd_intf_start(struct adapter *padapter) 311 { 312 if (padapter == NULL) { 313 DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__); 314 return; 315 } 316 317 /* hal dep */ 318 rtw_hal_enable_interrupt(padapter); 319 } 320 321 static void sd_intf_stop(struct adapter *padapter) 322 { 323 if (padapter == NULL) { 324 DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__); 325 return; 326 } 327 328 /* hal dep */ 329 rtw_hal_disable_interrupt(padapter); 330 } 331 332 333 static struct adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj, const struct sdio_device_id *pdid) 334 { 335 int status = _FAIL; 336 struct net_device *pnetdev; 337 struct adapter *padapter = NULL; 338 PSDIO_DATA psdio = &dvobj->intf_data; 339 340 padapter = (struct adapter *)vzalloc(sizeof(*padapter)); 341 if (padapter == NULL) { 342 goto exit; 343 } 344 345 padapter->dvobj = dvobj; 346 dvobj->if1 = padapter; 347 348 padapter->bDriverStopped =true; 349 350 dvobj->padapters = padapter; 351 padapter->iface_id = 0; 352 353 /* 3 1. init network device data */ 354 pnetdev = rtw_init_netdev(padapter); 355 if (!pnetdev) 356 goto free_adapter; 357 358 SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj)); 359 360 padapter = rtw_netdev_priv(pnetdev); 361 362 rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj)); 363 364 /* 3 3. init driver special setting, interface, OS and hardware relative */ 365 366 /* 4 3.1 set hardware operation functions */ 367 rtw_set_hal_ops(padapter); 368 369 370 /* 3 5. initialize Chip version */ 371 padapter->intf_start = &sd_intf_start; 372 padapter->intf_stop = &sd_intf_stop; 373 374 padapter->intf_init = &sdio_init; 375 padapter->intf_deinit = &sdio_deinit; 376 padapter->intf_alloc_irq = &sdio_alloc_irq; 377 padapter->intf_free_irq = &sdio_free_irq; 378 379 if (rtw_init_io_priv(padapter, sdio_set_intf_ops) == _FAIL) 380 { 381 RT_TRACE(_module_hci_intfs_c_, _drv_err_, 382 ("rtw_drv_init: Can't init io_priv\n")); 383 goto free_hal_data; 384 } 385 386 rtw_hal_read_chip_version(padapter); 387 388 rtw_hal_chip_configure(padapter); 389 390 rtw_btcoex_Initialize(padapter); 391 392 /* 3 6. read efuse/eeprom data */ 393 rtw_hal_read_chip_info(padapter); 394 395 /* 3 7. init driver common data */ 396 if (rtw_init_drv_sw(padapter) == _FAIL) { 397 RT_TRACE(_module_hci_intfs_c_, _drv_err_, 398 ("rtw_drv_init: Initialize driver software resource Failed!\n")); 399 goto free_hal_data; 400 } 401 402 /* 3 8. get WLan MAC address */ 403 /* set mac addr */ 404 rtw_macaddr_cfg(&psdio->func->dev, padapter->eeprompriv.mac_addr); 405 406 rtw_hal_disable_interrupt(padapter); 407 408 DBG_871X("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n" 409 , padapter->bDriverStopped 410 , padapter->bSurpriseRemoved 411 , padapter->bup 412 , padapter->hw_init_completed 413 ); 414 415 status = _SUCCESS; 416 417 free_hal_data: 418 if (status != _SUCCESS && padapter->HalData) 419 kfree(padapter->HalData); 420 421 if (status != _SUCCESS) { 422 rtw_wdev_unregister(padapter->rtw_wdev); 423 rtw_wdev_free(padapter->rtw_wdev); 424 } 425 426 free_adapter: 427 if (status != _SUCCESS) { 428 if (pnetdev) 429 rtw_free_netdev(pnetdev); 430 else 431 vfree((u8 *)padapter); 432 padapter = NULL; 433 } 434 exit: 435 return padapter; 436 } 437 438 static void rtw_sdio_if1_deinit(struct adapter *if1) 439 { 440 struct net_device *pnetdev = if1->pnetdev; 441 struct mlme_priv *pmlmepriv = &if1->mlmepriv; 442 443 if (check_fwstate(pmlmepriv, _FW_LINKED)) 444 rtw_disassoc_cmd(if1, 0, false); 445 446 free_mlme_ap_info(if1); 447 448 #ifdef CONFIG_GPIO_WAKEUP 449 gpio_hostwakeup_free_irq(if1); 450 #endif 451 452 rtw_cancel_all_timer(if1); 453 454 #ifdef CONFIG_WOWLAN 455 adapter_to_pwrctl(if1)->wowlan_mode =false; 456 DBG_871X_LEVEL(_drv_always_, "%s wowlan_mode:%d\n", __func__, adapter_to_pwrctl(if1)->wowlan_mode); 457 #endif /* CONFIG_WOWLAN */ 458 459 rtw_dev_unload(if1); 460 DBG_871X("+r871xu_dev_remove, hw_init_completed =%d\n", if1->hw_init_completed); 461 462 if (if1->rtw_wdev) { 463 rtw_wdev_free(if1->rtw_wdev); 464 } 465 466 rtw_free_drv_sw(if1); 467 468 if (pnetdev) 469 rtw_free_netdev(pnetdev); 470 } 471 472 /* 473 * drv_init() - a device potentially for us 474 * 475 * notes: drv_init() is called when the bus driver has located a card for us to support. 476 * We accept the new device by returning 0. 477 */ 478 static int rtw_drv_init( 479 struct sdio_func *func, 480 const struct sdio_device_id *id) 481 { 482 int status = _FAIL; 483 struct adapter *if1 = NULL, *if2 = NULL; 484 struct dvobj_priv *dvobj; 485 486 dvobj = sdio_dvobj_init(func); 487 if (dvobj == NULL) { 488 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("initialize device object priv Failed!\n")); 489 goto exit; 490 } 491 492 if1 = rtw_sdio_if1_init(dvobj, id); 493 if (if1 == NULL) { 494 DBG_871X("rtw_init_primarystruct adapter Failed!\n"); 495 goto free_dvobj; 496 } 497 498 /* dev_alloc_name && register_netdev */ 499 status = rtw_drv_register_netdev(if1); 500 if (status != _SUCCESS) { 501 goto free_if2; 502 } 503 504 if (sdio_alloc_irq(dvobj) != _SUCCESS) 505 goto free_if2; 506 507 #ifdef CONFIG_GPIO_WAKEUP 508 gpio_hostwakeup_alloc_irq(if1); 509 #endif 510 511 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-871x_drv - drv_init, success!\n")); 512 513 rtw_ndev_notifier_register(); 514 status = _SUCCESS; 515 516 free_if2: 517 if (status != _SUCCESS && if2) { 518 } 519 if (status != _SUCCESS && if1) { 520 rtw_sdio_if1_deinit(if1); 521 } 522 free_dvobj: 523 if (status != _SUCCESS) 524 sdio_dvobj_deinit(func); 525 exit: 526 return status == _SUCCESS?0:-ENODEV; 527 } 528 529 static void rtw_dev_remove(struct sdio_func *func) 530 { 531 struct dvobj_priv *dvobj = sdio_get_drvdata(func); 532 struct adapter *padapter = dvobj->if1; 533 534 RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+rtw_dev_remove\n")); 535 536 dvobj->processing_dev_remove = true; 537 538 rtw_unregister_netdevs(dvobj); 539 540 if (padapter->bSurpriseRemoved == false) { 541 int err; 542 543 /* test surprise remove */ 544 sdio_claim_host(func); 545 sdio_readb(func, 0, &err); 546 sdio_release_host(func); 547 if (err == -ENOMEDIUM) { 548 padapter->bSurpriseRemoved = true; 549 DBG_871X(KERN_NOTICE "%s: device had been removed!\n", __func__); 550 } 551 } 552 553 rtw_ps_deny(padapter, PS_DENY_DRV_REMOVE); 554 555 rtw_pm_set_ips(padapter, IPS_NONE); 556 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); 557 558 LeaveAllPowerSaveMode(padapter); 559 560 rtw_btcoex_HaltNotify(padapter); 561 562 rtw_sdio_if1_deinit(padapter); 563 564 sdio_dvobj_deinit(func); 565 566 RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("-rtw_dev_remove\n")); 567 } 568 569 extern int pm_netdev_open(struct net_device *pnetdev, u8 bnormal); 570 extern int pm_netdev_close(struct net_device *pnetdev, u8 bnormal); 571 572 static int rtw_sdio_suspend(struct device *dev) 573 { 574 struct sdio_func *func =dev_to_sdio_func(dev); 575 struct dvobj_priv *psdpriv = sdio_get_drvdata(func); 576 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv); 577 struct adapter *padapter = psdpriv->if1; 578 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 579 580 if (padapter->bDriverStopped == true) 581 { 582 DBG_871X("%s bDriverStopped = %d\n", __func__, padapter->bDriverStopped); 583 return 0; 584 } 585 586 if (pwrpriv->bInSuspend == true) 587 { 588 DBG_871X("%s bInSuspend = %d\n", __func__, pwrpriv->bInSuspend); 589 pdbgpriv->dbg_suspend_error_cnt++; 590 return 0; 591 } 592 593 return rtw_suspend_common(padapter); 594 } 595 596 static int rtw_resume_process(struct adapter *padapter) 597 { 598 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 599 struct dvobj_priv *psdpriv = padapter->dvobj; 600 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 601 602 if (pwrpriv->bInSuspend == false) 603 { 604 pdbgpriv->dbg_resume_error_cnt++; 605 DBG_871X("%s bInSuspend = %d\n", __func__, pwrpriv->bInSuspend); 606 return -1; 607 } 608 609 return rtw_resume_common(padapter); 610 } 611 612 static int rtw_sdio_resume(struct device *dev) 613 { 614 struct sdio_func *func =dev_to_sdio_func(dev); 615 struct dvobj_priv *psdpriv = sdio_get_drvdata(func); 616 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv); 617 struct adapter *padapter = psdpriv->if1; 618 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 619 int ret = 0; 620 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 621 622 DBG_871X("==> %s (%s:%d)\n", __func__, current->comm, current->pid); 623 624 pdbgpriv->dbg_resume_cnt++; 625 626 if (pwrpriv->bInternalAutoSuspend) 627 { 628 ret = rtw_resume_process(padapter); 629 } 630 else 631 { 632 if (pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode) 633 { 634 ret = rtw_resume_process(padapter); 635 } 636 else 637 { 638 ret = rtw_resume_process(padapter); 639 } 640 } 641 pmlmeext->last_scan_time = jiffies; 642 DBG_871X("<======== %s return %d\n", __func__, ret); 643 return ret; 644 645 } 646 647 static int __init rtw_drv_entry(void) 648 { 649 int ret = 0; 650 651 DBG_871X_LEVEL(_drv_always_, "module init start\n"); 652 dump_drv_version(RTW_DBGDUMP); 653 #ifdef BTCOEXVERSION 654 DBG_871X_LEVEL(_drv_always_, "rtl8723bs BT-Coex version = %s\n", BTCOEXVERSION); 655 #endif /* BTCOEXVERSION */ 656 657 sdio_drvpriv.drv_registered = true; 658 rtw_drv_proc_init(); 659 660 ret = sdio_register_driver(&sdio_drvpriv.r871xs_drv); 661 if (ret != 0) 662 { 663 sdio_drvpriv.drv_registered = false; 664 rtw_drv_proc_deinit(); 665 rtw_ndev_notifier_unregister(); 666 DBG_871X("%s: register driver failed!!(%d)\n", __func__, ret); 667 goto exit; 668 } 669 670 goto exit; 671 672 exit: 673 DBG_871X_LEVEL(_drv_always_, "module init ret =%d\n", ret); 674 return ret; 675 } 676 677 static void __exit rtw_drv_halt(void) 678 { 679 DBG_871X_LEVEL(_drv_always_, "module exit start\n"); 680 681 sdio_drvpriv.drv_registered = false; 682 683 sdio_unregister_driver(&sdio_drvpriv.r871xs_drv); 684 685 rtw_drv_proc_deinit(); 686 rtw_ndev_notifier_unregister(); 687 688 DBG_871X_LEVEL(_drv_always_, "module exit success\n"); 689 690 rtw_mstat_dump(RTW_DBGDUMP); 691 } 692 693 694 module_init(rtw_drv_entry); 695 module_exit(rtw_drv_halt); 696