1/****************************************************************************** 2 * 3 * Copyright(c) 2007 - 2011 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 <osdep_service.h> 18#include <drv_types.h> 19#include <recv_osdep.h> 20#include <xmit_osdep.h> 21#include <hal_intf.h> 22#include <rtw_version.h> 23#include <osdep_intf.h> 24#include <usb_ops.h> 25#include <rtl8723a_hal.h> 26 27static int rtw_suspend(struct usb_interface *intf, pm_message_t message); 28static int rtw_resume(struct usb_interface *intf); 29static int rtw_drv_init(struct usb_interface *pusb_intf, 30 const struct usb_device_id *pdid); 31static void rtw_disconnect(struct usb_interface *pusb_intf); 32 33#define USB_VENDER_ID_REALTEK 0x0BDA 34 35#define RTL8723A_USB_IDS \ 36 {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x8724, \ 37 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */ \ 38 {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x1724, \ 39 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */ \ 40 {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x0724, \ 41 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */ 42 43static struct usb_device_id rtl8723a_usb_id_tbl[] = { 44 RTL8723A_USB_IDS 45 {} /* Terminating entry */ 46}; 47 48MODULE_DEVICE_TABLE(usb, rtl8723a_usb_id_tbl); 49 50static struct usb_driver rtl8723a_usb_drv = { 51 .name = (char *)"rtl8723au", 52 .probe = rtw_drv_init, 53 .disconnect = rtw_disconnect, 54 .id_table = rtl8723a_usb_id_tbl, 55 .suspend = rtw_suspend, 56 .resume = rtw_resume, 57 .reset_resume = rtw_resume, 58}; 59 60static struct usb_driver *usb_drv = &rtl8723a_usb_drv; 61 62static inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) 63{ 64 return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd); 65} 66 67static inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) 68{ 69 return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd); 70} 71 72static inline int RT_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) 73{ 74 return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd); 75} 76 77static int rtw_init_intf_priv(struct dvobj_priv *dvobj) 78{ 79 mutex_init(&dvobj->usb_vendor_req_mutex); 80 81 return _SUCCESS; 82} 83 84static int rtw_deinit_intf_priv(struct dvobj_priv *dvobj) 85{ 86 mutex_destroy(&dvobj->usb_vendor_req_mutex); 87 88 return _SUCCESS; 89} 90 91static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) 92{ 93 struct dvobj_priv *pdvobjpriv; 94 struct usb_host_config *phost_conf; 95 struct usb_config_descriptor *pconf_desc; 96 struct usb_host_interface *phost_iface; 97 struct usb_interface_descriptor *piface_desc; 98 struct usb_host_endpoint *phost_endp; 99 struct usb_endpoint_descriptor *pendp_desc; 100 struct usb_device *pusbd; 101 int i; 102 int status = _FAIL; 103 104 pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL); 105 if (!pdvobjpriv) 106 goto exit; 107 108 mutex_init(&pdvobjpriv->hw_init_mutex); 109 mutex_init(&pdvobjpriv->h2c_fwcmd_mutex); 110 mutex_init(&pdvobjpriv->setch_mutex); 111 mutex_init(&pdvobjpriv->setbw_mutex); 112 113 pdvobjpriv->pusbintf = usb_intf; 114 pusbd = interface_to_usbdev(usb_intf); 115 pdvobjpriv->pusbdev = pusbd; 116 usb_set_intfdata(usb_intf, pdvobjpriv); 117 118 pdvobjpriv->RtNumInPipes = 0; 119 pdvobjpriv->RtNumOutPipes = 0; 120 121 phost_conf = pusbd->actconfig; 122 pconf_desc = &phost_conf->desc; 123 124 phost_iface = &usb_intf->altsetting[0]; 125 piface_desc = &phost_iface->desc; 126 127 pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces; 128 pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber; 129 pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; 130 131 for (i = 0; i < pdvobjpriv->nr_endpoint; i++) { 132 phost_endp = phost_iface->endpoint + i; 133 if (phost_endp) { 134 pendp_desc = &phost_endp->desc; 135 136 DBG_8723A("\nusb_endpoint_descriptor(%d):\n", i); 137 DBG_8723A("bLength =%x\n", pendp_desc->bLength); 138 DBG_8723A("bDescriptorType =%x\n", 139 pendp_desc->bDescriptorType); 140 DBG_8723A("bEndpointAddress =%x\n", 141 pendp_desc->bEndpointAddress); 142 DBG_8723A("wMaxPacketSize =%d\n", 143 le16_to_cpu(pendp_desc->wMaxPacketSize)); 144 DBG_8723A("bInterval =%x\n", pendp_desc->bInterval); 145 146 if (RT_usb_endpoint_is_bulk_in(pendp_desc)) { 147 DBG_8723A("RT_usb_endpoint_is_bulk_in = %x\n", 148 usb_endpoint_num(pendp_desc)); 149 pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = 150 usb_endpoint_num(pendp_desc); 151 pdvobjpriv->RtNumInPipes++; 152 } else if (RT_usb_endpoint_is_int_in(pendp_desc)) { 153 DBG_8723A("RT_usb_endpoint_is_int_in = %x, Interval = %x\n", 154 usb_endpoint_num(pendp_desc), 155 pendp_desc->bInterval); 156 pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = 157 usb_endpoint_num(pendp_desc); 158 pdvobjpriv->RtNumInPipes++; 159 } else if (RT_usb_endpoint_is_bulk_out(pendp_desc)) { 160 DBG_8723A("RT_usb_endpoint_is_bulk_out = %x\n", 161 usb_endpoint_num(pendp_desc)); 162 pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = 163 usb_endpoint_num(pendp_desc); 164 pdvobjpriv->RtNumOutPipes++; 165 } 166 pdvobjpriv->ep_num[i] = usb_endpoint_num(pendp_desc); 167 } 168 } 169 DBG_8723A("nr_endpoint =%d, in_num =%d, out_num =%d\n\n", 170 pdvobjpriv->nr_endpoint, pdvobjpriv->RtNumInPipes, 171 pdvobjpriv->RtNumOutPipes); 172 173 if (pusbd->speed == USB_SPEED_HIGH) { 174 pdvobjpriv->ishighspeed = true; 175 DBG_8723A("USB_SPEED_HIGH\n"); 176 } else { 177 pdvobjpriv->ishighspeed = false; 178 DBG_8723A("NON USB_SPEED_HIGH\n"); 179 } 180 181 if (rtw_init_intf_priv(pdvobjpriv) == _FAIL) { 182 RT_TRACE(_module_os_intfs_c_, _drv_err_, 183 ("\n Can't INIT rtw_init_intf_priv\n")); 184 goto free_dvobj; 185 } 186 /* 3 misc */ 187 rtw_reset_continual_urb_error(pdvobjpriv); 188 usb_get_dev(pusbd); 189 status = _SUCCESS; 190free_dvobj: 191 if (status != _SUCCESS && pdvobjpriv) { 192 usb_set_intfdata(usb_intf, NULL); 193 mutex_destroy(&pdvobjpriv->hw_init_mutex); 194 mutex_destroy(&pdvobjpriv->h2c_fwcmd_mutex); 195 mutex_destroy(&pdvobjpriv->setch_mutex); 196 mutex_destroy(&pdvobjpriv->setbw_mutex); 197 kfree(pdvobjpriv); 198 pdvobjpriv = NULL; 199 } 200exit: 201 return pdvobjpriv; 202} 203 204static void usb_dvobj_deinit(struct usb_interface *usb_intf) 205{ 206 struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf); 207 208 usb_set_intfdata(usb_intf, NULL); 209 if (dvobj) { 210 /* Modify condition for 92DU DMDP 2010.11.18, by Thomas */ 211 if ((dvobj->NumInterfaces != 2 && dvobj->NumInterfaces != 3) || 212 (dvobj->InterfaceNumber == 1)) { 213 if (interface_to_usbdev(usb_intf)->state != 214 USB_STATE_NOTATTACHED) { 215 /* If we didn't unplug usb dongle and 216 * remove/insert module, driver fails on 217 * sitesurvey for the first time when 218 * device is up . 219 * Reset usb port for sitesurvey fail issue. 220 */ 221 DBG_8723A("usb attached..., try to reset usb device\n"); 222 usb_reset_device(interface_to_usbdev(usb_intf)); 223 } 224 } 225 rtw_deinit_intf_priv(dvobj); 226 mutex_destroy(&dvobj->hw_init_mutex); 227 mutex_destroy(&dvobj->h2c_fwcmd_mutex); 228 mutex_destroy(&dvobj->setch_mutex); 229 mutex_destroy(&dvobj->setbw_mutex); 230 kfree(dvobj); 231 } 232 usb_put_dev(interface_to_usbdev(usb_intf)); 233} 234 235void rtl8723a_usb_intf_stop(struct rtw_adapter *padapter) 236{ 237 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_stop\n")); 238 239 /* disable_hw_interrupt */ 240 if (!padapter->bSurpriseRemoved) { 241 /* device still exists, so driver can do i/o operation 242 * TODO: 243 */ 244 RT_TRACE(_module_hci_intfs_c_, _drv_err_, 245 ("SurpriseRemoved == false\n")); 246 } 247 248 /* cancel in irp */ 249 rtl8723au_inirp_deinit(padapter); 250 251 /* cancel out irp */ 252 rtl8723au_write_port_cancel(padapter); 253 254 /* todo:cancel other irps */ 255 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_stop\n")); 256} 257 258static void rtw_dev_unload(struct rtw_adapter *padapter) 259{ 260 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_dev_unload\n")); 261 262 if (padapter->bup) { 263 DBG_8723A("===> rtw_dev_unload\n"); 264 265 padapter->bDriverStopped = true; 266 if (padapter->xmitpriv.ack_tx) 267 rtw_ack_tx_done23a(&padapter->xmitpriv, 268 RTW_SCTX_DONE_DRV_STOP); 269 270 /* s3. */ 271 rtl8723a_usb_intf_stop(padapter); 272 273 /* s4. */ 274 flush_workqueue(padapter->cmdpriv.wq); 275 276 /* s5. */ 277 if (!padapter->bSurpriseRemoved) { 278 rtl8723au_hal_deinit(padapter); 279 padapter->bSurpriseRemoved = true; 280 } 281 padapter->bup = false; 282 } else { 283 RT_TRACE(_module_hci_intfs_c_, _drv_err_, 284 ("r871x_dev_unload():padapter->bup == false\n")); 285 } 286 DBG_8723A("<=== rtw_dev_unload\n"); 287 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n")); 288} 289 290int rtw_hw_suspend23a(struct rtw_adapter *padapter) 291{ 292 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 293 struct net_device *pnetdev = padapter->pnetdev; 294 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 295 296 if ((!padapter->bup) || (padapter->bDriverStopped) || 297 (padapter->bSurpriseRemoved)) { 298 DBG_8723A("padapter->bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n", 299 padapter->bup, padapter->bDriverStopped, 300 padapter->bSurpriseRemoved); 301 goto error_exit; 302 } 303 304 if (padapter) { /* system suspend */ 305 LeaveAllPowerSaveMode23a(padapter); 306 307 DBG_8723A("==> rtw_hw_suspend23a\n"); 308 down(&pwrpriv->lock); 309 pwrpriv->bips_processing = true; 310 /* padapter->net_closed = true; */ 311 /* s1. */ 312 if (pnetdev) { 313 netif_carrier_off(pnetdev); 314 netif_tx_stop_all_queues(pnetdev); 315 } 316 317 /* s2. */ 318 rtw_disassoc_cmd23a(padapter, 500, false); 319 320 /* s2-2. indicate disconnect to os */ 321 /* rtw_indicate_disconnect23a(padapter); */ 322 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 323 _clr_fwstate_(pmlmepriv, _FW_LINKED); 324 325 rtw_led_control(padapter, LED_CTL_NO_LINK); 326 327 rtw_os_indicate_disconnect23a(padapter); 328 329 /* donnot enqueue cmd */ 330 rtw_lps_ctrl_wk_cmd23a(padapter, 331 LPS_CTRL_DISCONNECT, 0); 332 } 333 /* s2-3. */ 334 rtw_free_assoc_resources23a(padapter, 1); 335 336 /* s2-4. */ 337 rtw_free_network_queue23a(padapter); 338 rtw_ips_dev_unload23a(padapter); 339 pwrpriv->rf_pwrstate = rf_off; 340 pwrpriv->bips_processing = false; 341 up(&pwrpriv->lock); 342 } else { 343 goto error_exit; 344 } 345 return 0; 346error_exit: 347 DBG_8723A("%s, failed\n", __func__); 348 return -1; 349} 350 351int rtw_hw_resume23a(struct rtw_adapter *padapter) 352{ 353 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 354 struct net_device *pnetdev = padapter->pnetdev; 355 356 if (padapter) { /* system resume */ 357 DBG_8723A("==> rtw_hw_resume23a\n"); 358 down(&pwrpriv->lock); 359 pwrpriv->bips_processing = true; 360 rtw_reset_drv_sw23a(padapter); 361 362 if (pm_netdev_open23a(pnetdev, false)) { 363 up(&pwrpriv->lock); 364 goto error_exit; 365 } 366 367 netif_device_attach(pnetdev); 368 netif_carrier_on(pnetdev); 369 370 if (!rtw_netif_queue_stopped(pnetdev)) 371 netif_tx_start_all_queues(pnetdev); 372 else 373 netif_tx_wake_all_queues(pnetdev); 374 375 pwrpriv->bkeepfwalive = false; 376 377 pwrpriv->rf_pwrstate = rf_on; 378 pwrpriv->bips_processing = false; 379 380 up(&pwrpriv->lock); 381 } else { 382 goto error_exit; 383 } 384 return 0; 385error_exit: 386 DBG_8723A("%s, Open net dev failed\n", __func__); 387 return -1; 388} 389 390static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) 391{ 392 struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); 393 struct rtw_adapter *padapter = dvobj->if1; 394 struct net_device *pnetdev = padapter->pnetdev; 395 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 396 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 397 int ret = 0; 398 unsigned long start_time = jiffies; 399 400 DBG_8723A("==> %s (%s:%d)\n", __func__, current->comm, current->pid); 401 402 if ((!padapter->bup) || (padapter->bDriverStopped) || 403 (padapter->bSurpriseRemoved)) { 404 DBG_8723A("padapter->bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n", 405 padapter->bup, padapter->bDriverStopped, 406 padapter->bSurpriseRemoved); 407 goto exit; 408 } 409 pwrpriv->bInSuspend = true; 410 rtw_cancel_all_timer23a(padapter); 411 LeaveAllPowerSaveMode23a(padapter); 412 413 down(&pwrpriv->lock); 414 /* padapter->net_closed = true; */ 415 /* s1. */ 416 if (pnetdev) { 417 netif_carrier_off(pnetdev); 418 netif_tx_stop_all_queues(pnetdev); 419 } 420 421 /* s2. */ 422 rtw_disassoc_cmd23a(padapter, 0, false); 423 424 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && 425 check_fwstate(pmlmepriv, _FW_LINKED)) { 426 DBG_8723A("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n", 427 __func__, __LINE__, 428 pmlmepriv->cur_network.network.Ssid.ssid, 429 pmlmepriv->cur_network.network.MacAddress, 430 pmlmepriv->cur_network.network.Ssid.ssid_len, 431 pmlmepriv->assoc_ssid.ssid_len); 432 433 rtw_set_roaming(padapter, 1); 434 } 435 /* s2-2. indicate disconnect to os */ 436 rtw_indicate_disconnect23a(padapter); 437 /* s2-3. */ 438 rtw_free_assoc_resources23a(padapter, 1); 439 /* s2-4. */ 440 rtw_free_network_queue23a(padapter); 441 442 rtw_dev_unload(padapter); 443 up(&pwrpriv->lock); 444 445 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) 446 rtw_cfg80211_indicate_scan_done( 447 wdev_to_priv(padapter->rtw_wdev), true); 448 449 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) 450 rtw_indicate_disconnect23a(padapter); 451 452exit: 453 DBG_8723A("<=== %s return %d.............. in %dms\n", __func__, 454 ret, jiffies_to_msecs(jiffies - start_time)); 455 456 return ret; 457} 458 459static int rtw_resume(struct usb_interface *pusb_intf) 460{ 461 struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); 462 struct rtw_adapter *padapter = dvobj->if1; 463 struct net_device *pnetdev; 464 struct pwrctrl_priv *pwrpriv = NULL; 465 int ret = -1; 466 unsigned long start_time = jiffies; 467 468 DBG_8723A("==> %s (%s:%d)\n", __func__, current->comm, current->pid); 469 470 if (!padapter) 471 goto exit; 472 pnetdev = padapter->pnetdev; 473 pwrpriv = &padapter->pwrctrlpriv; 474 475 down(&pwrpriv->lock); 476 rtw_reset_drv_sw23a(padapter); 477 pwrpriv->bkeepfwalive = false; 478 479 DBG_8723A("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive); 480 if (pm_netdev_open23a(pnetdev, true) != 0) { 481 up(&pwrpriv->lock); 482 goto exit; 483 } 484 485 netif_device_attach(pnetdev); 486 netif_carrier_on(pnetdev); 487 488 up(&pwrpriv->lock); 489 490 if (padapter->pid[1] != 0) { 491 DBG_8723A("pid[1]:%d\n", padapter->pid[1]); 492 kill_pid(find_vpid(padapter->pid[1]), SIGUSR2, 1); 493 } 494 495 rtw23a_roaming(padapter, NULL); 496 497 ret = 0; 498exit: 499 if (pwrpriv) 500 pwrpriv->bInSuspend = false; 501 DBG_8723A("<=== %s return %d.............. in %dms\n", __func__, 502 ret, jiffies_to_msecs(jiffies - start_time)); 503 504 return ret; 505} 506 507/* 508 * drv_init() - a device potentially for us 509 * 510 * notes: drv_init() is called when the bus driver has located a card 511 * for us to support. 512 * We accept the new device by returning 0. 513 */ 514static struct rtw_adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, 515 struct usb_interface *pusb_intf, 516 const struct usb_device_id *pdid) 517{ 518 struct rtw_adapter *padapter = NULL; 519 struct net_device *pnetdev = NULL; 520 int status = _FAIL; 521 522 pnetdev = rtw_init_netdev23a(padapter); 523 if (!pnetdev) 524 goto free_adapter; 525 padapter = netdev_priv(pnetdev); 526 527 padapter->dvobj = dvobj; 528 padapter->bDriverStopped = true; 529 dvobj->if1 = padapter; 530 dvobj->padapters[dvobj->iface_nums++] = padapter; 531 padapter->iface_id = IFACE_ID0; 532 533 rtl8723au_set_hw_type(padapter); 534 535 SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj)); 536 537 if (rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj))) 538 goto free_adapter; 539 540 /* step 2. allocate HalData */ 541 padapter->HalData = kzalloc(sizeof(struct hal_data_8723a), GFP_KERNEL); 542 if (!padapter->HalData) 543 goto free_wdev; 544 545 /* step read_chip_version */ 546 rtl8723a_read_chip_version(padapter); 547 548 /* step usb endpoint mapping */ 549 rtl8723au_chip_configure(padapter); 550 551 /* step read efuse/eeprom data and get mac_addr */ 552 rtl8723a_read_adapter_info(padapter); 553 554 /* step 5. */ 555 if (rtw_init_drv_sw23a(padapter) == _FAIL) { 556 RT_TRACE(_module_hci_intfs_c_, _drv_err_, 557 ("Initialize driver software resource Failed!\n")); 558 goto free_hal_data; 559 } 560 561#ifdef CONFIG_PM 562 if (padapter->pwrctrlpriv.bSupportRemoteWakeup) { 563 dvobj->pusbdev->do_remote_wakeup = 1; 564 pusb_intf->needs_remote_wakeup = 1; 565 device_init_wakeup(&pusb_intf->dev, 1); 566 DBG_8723A("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~~~~\n"); 567 DBG_8723A("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n", 568 device_may_wakeup(&pusb_intf->dev)); 569 } 570#endif 571 /* 2012-07-11 Move here to prevent the 8723AS-VAU BT 572 * auto suspend influence 573 */ 574 if (usb_autopm_get_interface(pusb_intf) < 0) 575 DBG_8723A("can't get autopm:\n"); 576#ifdef CONFIG_8723AU_BT_COEXIST 577 padapter->pwrctrlpriv.autopm_cnt = 1; 578#endif 579 580 /* If the eeprom mac address is corrupted, assign a random address */ 581 if (is_broadcast_ether_addr(padapter->eeprompriv.mac_addr) || 582 is_zero_ether_addr(padapter->eeprompriv.mac_addr)) 583 eth_random_addr(padapter->eeprompriv.mac_addr); 584 585 DBG_8723A("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n", 586 padapter->bDriverStopped, padapter->bSurpriseRemoved, 587 padapter->bup, padapter->hw_init_completed 588 ); 589 status = _SUCCESS; 590 591free_hal_data: 592 if (status != _SUCCESS) 593 kfree(padapter->HalData); 594free_wdev: 595 if (status != _SUCCESS) { 596 rtw_wdev_unregister(padapter->rtw_wdev); 597 rtw_wdev_free(padapter->rtw_wdev); 598 } 599free_adapter: 600 if (status != _SUCCESS) { 601 if (pnetdev) 602 free_netdev(pnetdev); 603 padapter = NULL; 604 } 605 return padapter; 606} 607 608static void rtw_usb_if1_deinit(struct rtw_adapter *if1) 609{ 610 struct net_device *pnetdev = if1->pnetdev; 611 struct mlme_priv *pmlmepriv = &if1->mlmepriv; 612 613 if (check_fwstate(pmlmepriv, _FW_LINKED)) 614 rtw_disassoc_cmd23a(if1, 0, false); 615 616#ifdef CONFIG_8723AU_AP_MODE 617 free_mlme_ap_info23a(if1); 618#endif 619 620 if (pnetdev) 621 unregister_netdev(pnetdev); /* will call netdev_close() */ 622 623 rtw_cancel_all_timer23a(if1); 624 625 rtw_dev_unload(if1); 626 627 DBG_8723A("+r871xu_dev_remove, hw_init_completed =%d\n", 628 if1->hw_init_completed); 629 630 if (if1->rtw_wdev) { 631 rtw_wdev_unregister(if1->rtw_wdev); 632 rtw_wdev_free(if1->rtw_wdev); 633 } 634 635#ifdef CONFIG_8723AU_BT_COEXIST 636 if (1 == if1->pwrctrlpriv.autopm_cnt) { 637 usb_autopm_put_interface(adapter_to_dvobj(if1)->pusbintf); 638 if1->pwrctrlpriv.autopm_cnt--; 639 } 640#endif 641 642 rtw_free_drv_sw23a(if1); 643 644 if (pnetdev) 645 free_netdev(pnetdev); 646} 647 648static int rtw_drv_init(struct usb_interface *pusb_intf, 649 const struct usb_device_id *pdid) 650{ 651 struct rtw_adapter *if1 = NULL; 652 struct dvobj_priv *dvobj; 653 int status = _FAIL; 654 655 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_init\n")); 656 657 /* Initialize dvobj_priv */ 658 dvobj = usb_dvobj_init(pusb_intf); 659 if (!dvobj) { 660 RT_TRACE(_module_hci_intfs_c_, _drv_err_, 661 ("initialize device object priv Failed!\n")); 662 goto exit; 663 } 664 665 if1 = rtw_usb_if1_init(dvobj, pusb_intf, pdid); 666 if (!if1) { 667 DBG_8723A("rtw_init_primary_adapter Failed!\n"); 668 goto free_dvobj; 669 } 670 671 /* dev_alloc_name && register_netdev */ 672 status = rtw_drv_register_netdev(if1); 673 if (status != _SUCCESS) 674 goto free_if1; 675 RT_TRACE(_module_hci_intfs_c_, _drv_err_, 676 ("-871x_drv - drv_init, success!\n")); 677 678 status = _SUCCESS; 679 680free_if1: 681 if (status != _SUCCESS && if1) 682 rtw_usb_if1_deinit(if1); 683free_dvobj: 684 if (status != _SUCCESS) 685 usb_dvobj_deinit(pusb_intf); 686exit: 687 return status == _SUCCESS ? 0 : -ENODEV; 688} 689 690/* dev_remove() - our device is being removed */ 691static void rtw_disconnect(struct usb_interface *pusb_intf) 692{ 693 struct dvobj_priv *dvobj; 694 struct rtw_adapter *padapter; 695 struct net_device *pnetdev; 696 struct mlme_priv *pmlmepriv; 697 698 dvobj = usb_get_intfdata(pusb_intf); 699 if (!dvobj) 700 return; 701 702 padapter = dvobj->if1; 703 pnetdev = padapter->pnetdev; 704 pmlmepriv = &padapter->mlmepriv; 705 706 usb_set_intfdata(pusb_intf, NULL); 707 708 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n")); 709 710 rtw_pm_set_ips23a(padapter, IPS_NONE); 711 rtw_pm_set_lps23a(padapter, PS_MODE_ACTIVE); 712 713 LeaveAllPowerSaveMode23a(padapter); 714 715 rtw_usb_if1_deinit(padapter); 716 717 usb_dvobj_deinit(pusb_intf); 718 719 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-dev_remove()\n")); 720 DBG_8723A("-r871xu_dev_remove, done\n"); 721 722 return; 723} 724 725static int __init rtw_drv_entry(void) 726{ 727 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_entry\n")); 728 return usb_register(usb_drv); 729} 730 731static void __exit rtw_drv_halt(void) 732{ 733 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_halt\n")); 734 DBG_8723A("+rtw_drv_halt\n"); 735 736 usb_deregister(usb_drv); 737 738 DBG_8723A("-rtw_drv_halt\n"); 739} 740 741module_init(rtw_drv_entry); 742module_exit(rtw_drv_halt); 743