1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
14 ******************************************************************************/
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <recv_osdep.h>
20 #include <xmit_osdep.h>
22 #include <rtw_version.h>
23 #include <osdep_intf.h>
24 #include <usb_vendor_req.h>
26 #include <usb_osintf.h>
29 static int rtw_suspend(struct usb_interface *intf, pm_message_t message);
30 static int rtw_resume(struct usb_interface *intf);
31 static int rtw_drv_init(struct usb_interface *pusb_intf,
32 const struct usb_device_id *pdid);
33 static void rtw_disconnect(struct usb_interface *pusb_intf);
35 #define USB_VENDER_ID_REALTEK 0x0BDA
37 #define RTL8723A_USB_IDS \
38 {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x8724, \
39 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */ \
40 {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x1724, \
41 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */ \
42 {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x0724, \
43 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */
45 static struct usb_device_id rtl8723a_usb_id_tbl[] = {
47 {} /* Terminating entry */
50 MODULE_DEVICE_TABLE(usb, rtl8723a_usb_id_tbl);
52 static struct usb_driver rtl8723a_usb_drv = {
53 .name = (char *)"rtl8723au",
54 .probe = rtw_drv_init,
55 .disconnect = rtw_disconnect,
56 .id_table = rtl8723a_usb_id_tbl,
57 .suspend = rtw_suspend,
59 .reset_resume = rtw_resume,
62 static struct usb_driver *usb_drv = &rtl8723a_usb_drv;
64 static inline int RT_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
66 return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN;
69 static inline int RT_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
71 return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT;
74 static inline int RT_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
76 return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT;
79 static inline int RT_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd)
81 return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK;
84 static inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd)
86 return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_in(epd);
89 static inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd)
91 return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_out(epd);
94 static inline int RT_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
96 return RT_usb_endpoint_xfer_int(epd) && RT_usb_endpoint_dir_in(epd);
99 static inline int RT_usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
101 return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
104 static u8 rtw_init_intf_priv(struct dvobj_priv *dvobj)
108 mutex_init(&dvobj->usb_vendor_req_mutex);
109 dvobj->usb_alloc_vendor_req_buf = kzalloc(MAX_USB_IO_CTL_SIZE,
111 if (dvobj->usb_alloc_vendor_req_buf == NULL) {
112 DBG_8723A("alloc usb_vendor_req_buf failed... /n");
116 dvobj->usb_vendor_req_buf =
117 PTR_ALIGN(dvobj->usb_alloc_vendor_req_buf, ALIGNMENT_UNIT);
122 static u8 rtw_deinit_intf_priv(struct dvobj_priv *dvobj)
126 kfree(dvobj->usb_alloc_vendor_req_buf);
128 mutex_destroy(&dvobj->usb_vendor_req_mutex);
133 static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
135 struct dvobj_priv *pdvobjpriv;
136 struct usb_device_descriptor *pdev_desc;
137 struct usb_host_config *phost_conf;
138 struct usb_config_descriptor *pconf_desc;
139 struct usb_host_interface *phost_iface;
140 struct usb_interface_descriptor *piface_desc;
141 struct usb_host_endpoint *phost_endp;
142 struct usb_endpoint_descriptor *pendp_desc;
143 struct usb_device *pusbd;
147 pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL);
151 mutex_init(&pdvobjpriv->hw_init_mutex);
152 mutex_init(&pdvobjpriv->h2c_fwcmd_mutex);
153 mutex_init(&pdvobjpriv->setch_mutex);
154 mutex_init(&pdvobjpriv->setbw_mutex);
156 pdvobjpriv->pusbintf = usb_intf;
157 pusbd = interface_to_usbdev(usb_intf);
158 pdvobjpriv->pusbdev = pusbd;
159 usb_set_intfdata(usb_intf, pdvobjpriv);
161 pdvobjpriv->RtNumInPipes = 0;
162 pdvobjpriv->RtNumOutPipes = 0;
164 pdev_desc = &pusbd->descriptor;
166 phost_conf = pusbd->actconfig;
167 pconf_desc = &phost_conf->desc;
169 phost_iface = &usb_intf->altsetting[0];
170 piface_desc = &phost_iface->desc;
172 pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces;
173 pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber;
174 pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
176 for (i = 0; i < pdvobjpriv->nr_endpoint; i++) {
177 phost_endp = phost_iface->endpoint + i;
179 pendp_desc = &phost_endp->desc;
181 DBG_8723A("\nusb_endpoint_descriptor(%d):\n", i);
182 DBG_8723A("bLength =%x\n", pendp_desc->bLength);
183 DBG_8723A("bDescriptorType =%x\n",
184 pendp_desc->bDescriptorType);
185 DBG_8723A("bEndpointAddress =%x\n",
186 pendp_desc->bEndpointAddress);
187 DBG_8723A("wMaxPacketSize =%d\n",
188 le16_to_cpu(pendp_desc->wMaxPacketSize));
189 DBG_8723A("bInterval =%x\n", pendp_desc->bInterval);
191 if (RT_usb_endpoint_is_bulk_in(pendp_desc)) {
192 DBG_8723A("RT_usb_endpoint_is_bulk_in = %x\n",
193 RT_usb_endpoint_num(pendp_desc));
194 pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
195 RT_usb_endpoint_num(pendp_desc);
196 pdvobjpriv->RtNumInPipes++;
197 } else if (RT_usb_endpoint_is_int_in(pendp_desc)) {
198 DBG_8723A("RT_usb_endpoint_is_int_in = %x, Interval = %x\n",
199 RT_usb_endpoint_num(pendp_desc),
200 pendp_desc->bInterval);
201 pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
202 RT_usb_endpoint_num(pendp_desc);
203 pdvobjpriv->RtNumInPipes++;
204 } else if (RT_usb_endpoint_is_bulk_out(pendp_desc)) {
205 DBG_8723A("RT_usb_endpoint_is_bulk_out = %x\n",
206 RT_usb_endpoint_num(pendp_desc));
207 pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] =
208 RT_usb_endpoint_num(pendp_desc);
209 pdvobjpriv->RtNumOutPipes++;
211 pdvobjpriv->ep_num[i] = RT_usb_endpoint_num(pendp_desc);
214 DBG_8723A("nr_endpoint =%d, in_num =%d, out_num =%d\n\n",
215 pdvobjpriv->nr_endpoint, pdvobjpriv->RtNumInPipes,
216 pdvobjpriv->RtNumOutPipes);
218 if (pusbd->speed == USB_SPEED_HIGH) {
219 pdvobjpriv->ishighspeed = true;
220 DBG_8723A("USB_SPEED_HIGH\n");
222 pdvobjpriv->ishighspeed = false;
223 DBG_8723A("NON USB_SPEED_HIGH\n");
226 if (rtw_init_intf_priv(pdvobjpriv) == _FAIL) {
227 RT_TRACE(_module_os_intfs_c_, _drv_err_,
228 ("\n Can't INIT rtw_init_intf_priv\n"));
232 sema_init(&(pdvobjpriv->usb_suspend_sema), 0);
233 rtw_reset_continual_urb_error(pdvobjpriv);
237 if (status != _SUCCESS && pdvobjpriv) {
238 usb_set_intfdata(usb_intf, NULL);
239 mutex_destroy(&pdvobjpriv->hw_init_mutex);
240 mutex_destroy(&pdvobjpriv->h2c_fwcmd_mutex);
241 mutex_destroy(&pdvobjpriv->setch_mutex);
242 mutex_destroy(&pdvobjpriv->setbw_mutex);
250 static void usb_dvobj_deinit(struct usb_interface *usb_intf)
252 struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf);
254 usb_set_intfdata(usb_intf, NULL);
256 /* Modify condition for 92DU DMDP 2010.11.18, by Thomas */
257 if ((dvobj->NumInterfaces != 2 && dvobj->NumInterfaces != 3) ||
258 (dvobj->InterfaceNumber == 1)) {
259 if (interface_to_usbdev(usb_intf)->state !=
260 USB_STATE_NOTATTACHED) {
261 /* If we didn't unplug usb dongle and
262 * remove/insert module, driver fails on
263 * sitesurvey for the first time when
265 * Reset usb port for sitesurvey fail issue.
267 DBG_8723A("usb attached..., try to reset usb device\n");
268 usb_reset_device(interface_to_usbdev(usb_intf));
271 rtw_deinit_intf_priv(dvobj);
272 mutex_destroy(&dvobj->hw_init_mutex);
273 mutex_destroy(&dvobj->h2c_fwcmd_mutex);
274 mutex_destroy(&dvobj->setch_mutex);
275 mutex_destroy(&dvobj->setbw_mutex);
278 usb_put_dev(interface_to_usbdev(usb_intf));
281 static void decide_chip_type_by_usb_device_id(struct rtw_adapter *padapter,
282 const struct usb_device_id *pdid)
284 padapter->chip_type = NULL_CHIP_TYPE;
285 hal_set_hw_type(padapter);
288 static void usb_intf_start(struct rtw_adapter *padapter)
290 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_start\n"));
291 rtw_hal_inirp_init23a(padapter);
292 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_start\n"));
295 static void usb_intf_stop(struct rtw_adapter *padapter)
297 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_stop\n"));
299 /* disable_hw_interrupt */
300 if (!padapter->bSurpriseRemoved) {
301 /* device still exists, so driver can do i/o operation
304 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
305 ("SurpriseRemoved == false\n"));
309 rtw_hal_inirp_deinit23a(padapter);
312 rtw_write_port_cancel(padapter);
314 /* todo:cancel other irps */
315 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_stop\n"));
318 static void rtw_dev_unload(struct rtw_adapter *padapter)
320 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_dev_unload\n"));
323 DBG_8723A("===> rtw_dev_unload\n");
325 padapter->bDriverStopped = true;
326 if (padapter->xmitpriv.ack_tx)
327 rtw_ack_tx_done23a(&padapter->xmitpriv,
328 RTW_SCTX_DONE_DRV_STOP);
331 if (padapter->intf_stop)
332 padapter->intf_stop(padapter);
335 if (!padapter->pwrctrlpriv.bInternalAutoSuspend)
336 rtw_stop_drv_threads23a(padapter);
339 if (!padapter->bSurpriseRemoved) {
340 rtw_hal_deinit23a(padapter);
341 padapter->bSurpriseRemoved = true;
343 padapter->bup = false;
345 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
346 ("r871x_dev_unload():padapter->bup == false\n"));
348 DBG_8723A("<=== rtw_dev_unload\n");
349 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n"));
352 int rtw_hw_suspend23a(struct rtw_adapter *padapter)
354 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
355 struct net_device *pnetdev = padapter->pnetdev;
356 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
358 if ((!padapter->bup) || (padapter->bDriverStopped) ||
359 (padapter->bSurpriseRemoved)) {
360 DBG_8723A("padapter->bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n",
361 padapter->bup, padapter->bDriverStopped,
362 padapter->bSurpriseRemoved);
366 if (padapter) { /* system suspend */
367 LeaveAllPowerSaveMode23a(padapter);
369 DBG_8723A("==> rtw_hw_suspend23a\n");
370 down(&pwrpriv->lock);
371 pwrpriv->bips_processing = true;
372 /* padapter->net_closed = true; */
375 netif_carrier_off(pnetdev);
376 netif_tx_stop_all_queues(pnetdev);
380 rtw_disassoc_cmd23a(padapter, 500, false);
382 /* s2-2. indicate disconnect to os */
383 /* rtw_indicate_disconnect23a(padapter); */
384 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
385 _clr_fwstate_(pmlmepriv, _FW_LINKED);
387 rtw_led_control(padapter, LED_CTL_NO_LINK);
389 rtw_os_indicate_disconnect23a(padapter);
391 /* donnot enqueue cmd */
392 rtw_lps_ctrl_wk_cmd23a(padapter,
393 LPS_CTRL_DISCONNECT, 0);
396 rtw_free_assoc_resources23a(padapter, 1);
399 rtw_free_network_queue23a(padapter, true);
400 rtw_ips_dev_unload23a(padapter);
401 pwrpriv->rf_pwrstate = rf_off;
402 pwrpriv->bips_processing = false;
409 DBG_8723A("%s, failed\n", __func__);
413 int rtw_hw_resume23a(struct rtw_adapter *padapter)
415 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
416 struct net_device *pnetdev = padapter->pnetdev;
418 if (padapter) { /* system resume */
419 DBG_8723A("==> rtw_hw_resume23a\n");
420 down(&pwrpriv->lock);
421 pwrpriv->bips_processing = true;
422 rtw_reset_drv_sw23a(padapter);
424 if (pm_netdev_open23a(pnetdev, false)) {
429 netif_device_attach(pnetdev);
430 netif_carrier_on(pnetdev);
432 if (!rtw_netif_queue_stopped(pnetdev))
433 netif_tx_start_all_queues(pnetdev);
435 netif_tx_wake_all_queues(pnetdev);
437 pwrpriv->bkeepfwalive = false;
438 pwrpriv->brfoffbyhw = false;
440 pwrpriv->rf_pwrstate = rf_on;
441 pwrpriv->bips_processing = false;
449 DBG_8723A("%s, Open net dev failed\n", __func__);
453 static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message)
455 struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
456 struct rtw_adapter *padapter = dvobj->if1;
457 struct net_device *pnetdev = padapter->pnetdev;
458 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
459 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
461 unsigned long start_time = jiffies;
463 DBG_8723A("==> %s (%s:%d)\n", __func__, current->comm, current->pid);
465 if ((!padapter->bup) || (padapter->bDriverStopped) ||
466 (padapter->bSurpriseRemoved)) {
467 DBG_8723A("padapter->bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n",
468 padapter->bup, padapter->bDriverStopped,
469 padapter->bSurpriseRemoved);
472 pwrpriv->bInSuspend = true;
473 rtw_cancel_all_timer23a(padapter);
474 LeaveAllPowerSaveMode23a(padapter);
476 down(&pwrpriv->lock);
477 /* padapter->net_closed = true; */
480 netif_carrier_off(pnetdev);
481 netif_tx_stop_all_queues(pnetdev);
485 rtw_disassoc_cmd23a(padapter, 0, false);
487 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
488 check_fwstate(pmlmepriv, _FW_LINKED)) {
489 DBG_8723A("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n",
491 pmlmepriv->cur_network.network.Ssid.ssid,
492 pmlmepriv->cur_network.network.MacAddress,
493 pmlmepriv->cur_network.network.Ssid.ssid_len,
494 pmlmepriv->assoc_ssid.ssid_len);
496 rtw_set_roaming(padapter, 1);
498 /* s2-2. indicate disconnect to os */
499 rtw_indicate_disconnect23a(padapter);
501 rtw_free_assoc_resources23a(padapter, 1);
503 rtw_free_network_queue23a(padapter, true);
505 rtw_dev_unload(padapter);
508 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
509 rtw_cfg80211_indicate_scan_done(
510 wdev_to_priv(padapter->rtw_wdev), true);
512 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
513 rtw_indicate_disconnect23a(padapter);
516 DBG_8723A("<=== %s return %d.............. in %dms\n", __func__,
517 ret, jiffies_to_msecs(jiffies - start_time));
522 static int rtw_resume(struct usb_interface *pusb_intf)
524 struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
525 struct rtw_adapter *padapter = dvobj->if1;
526 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
529 if (pwrpriv->bInternalAutoSuspend)
530 ret = rtw_resume_process23a(padapter);
532 ret = rtw_resume_process23a(padapter);
537 int rtw_resume_process23a(struct rtw_adapter *padapter)
539 struct net_device *pnetdev;
540 struct pwrctrl_priv *pwrpriv = NULL;
542 unsigned long start_time = jiffies;
544 DBG_8723A("==> %s (%s:%d)\n", __func__, current->comm, current->pid);
548 pnetdev = padapter->pnetdev;
549 pwrpriv = &padapter->pwrctrlpriv;
551 down(&pwrpriv->lock);
552 rtw_reset_drv_sw23a(padapter);
553 pwrpriv->bkeepfwalive = false;
555 DBG_8723A("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive);
556 if (pm_netdev_open23a(pnetdev, true) != 0)
559 netif_device_attach(pnetdev);
560 netif_carrier_on(pnetdev);
564 if (padapter->pid[1] != 0) {
565 DBG_8723A("pid[1]:%d\n", padapter->pid[1]);
566 kill_pid(find_vpid(padapter->pid[1]), SIGUSR2, 1);
569 rtw23a_roaming(padapter, NULL);
574 pwrpriv->bInSuspend = false;
575 DBG_8723A("<=== %s return %d.............. in %dms\n", __func__,
576 ret, jiffies_to_msecs(jiffies - start_time));
582 * drv_init() - a device potentially for us
584 * notes: drv_init() is called when the bus driver has located a card
586 * We accept the new device by returning 0.
588 static struct rtw_adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
589 struct usb_interface *pusb_intf,
590 const struct usb_device_id *pdid)
592 struct rtw_adapter *padapter = NULL;
593 struct net_device *pnetdev = NULL;
596 pnetdev = rtw_init_netdev23a(padapter);
599 padapter = netdev_priv(pnetdev);
601 padapter->dvobj = dvobj;
602 padapter->bDriverStopped = true;
603 dvobj->if1 = padapter;
604 dvobj->padapters[dvobj->iface_nums++] = padapter;
605 padapter->iface_id = IFACE_ID0;
607 /* step 1-1., decide the chip_type via vid/pid */
608 decide_chip_type_by_usb_device_id(padapter, pdid);
610 if (rtw_handle_dualmac23a(padapter, 1) != _SUCCESS)
613 SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj));
615 if (rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj)))
618 /* step 2. hook HalFunc, allocate HalData */
619 if (rtl8723au_set_hal_ops(padapter))
622 padapter->intf_start = &usb_intf_start;
623 padapter->intf_stop = &usb_intf_stop;
625 /* step init_io_priv */
626 rtw_init_io_priv23a(padapter, usb_set_intf_ops);
628 /* step read_chip_version */
629 rtw_hal_read_chip_version23a(padapter);
631 /* step usb endpoint mapping */
632 rtw_hal_chip_configure23a(padapter);
634 /* step read efuse/eeprom data and get mac_addr */
635 rtw_hal_read_chip_info23a(padapter);
638 if (rtw_init_drv_sw23a(padapter) == _FAIL) {
639 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
640 ("Initialize driver software resource Failed!\n"));
645 if (padapter->pwrctrlpriv.bSupportRemoteWakeup) {
646 dvobj->pusbdev->do_remote_wakeup = 1;
647 pusb_intf->needs_remote_wakeup = 1;
648 device_init_wakeup(&pusb_intf->dev, 1);
649 DBG_8723A("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~~~~\n");
650 DBG_8723A("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n",
651 device_may_wakeup(&pusb_intf->dev));
654 /* 2012-07-11 Move here to prevent the 8723AS-VAU BT
655 * auto suspend influence
657 if (usb_autopm_get_interface(pusb_intf) < 0)
658 DBG_8723A("can't get autopm:\n");
659 #ifdef CONFIG_8723AU_BT_COEXIST
660 padapter->pwrctrlpriv.autopm_cnt = 1;
664 rtw_macaddr_cfg23a(padapter->eeprompriv.mac_addr);
666 DBG_8723A("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n",
667 padapter->bDriverStopped, padapter->bSurpriseRemoved,
668 padapter->bup, padapter->hw_init_completed
673 if (status != _SUCCESS)
674 kfree(padapter->HalData);
675 if (status != _SUCCESS) {
676 rtw_wdev_unregister(padapter->rtw_wdev);
677 rtw_wdev_free(padapter->rtw_wdev);
680 if (status != _SUCCESS)
681 rtw_handle_dualmac23a(padapter, 0);
683 if (status != _SUCCESS) {
685 free_netdev(pnetdev);
691 static void rtw_usb_if1_deinit(struct rtw_adapter *if1)
693 struct net_device *pnetdev = if1->pnetdev;
694 struct mlme_priv *pmlmepriv = &if1->mlmepriv;
696 if (check_fwstate(pmlmepriv, _FW_LINKED))
697 rtw_disassoc_cmd23a(if1, 0, false);
699 #ifdef CONFIG_8723AU_AP_MODE
700 free_mlme_ap_info23a(if1);
704 unregister_netdev(pnetdev); /* will call netdev_close() */
706 rtw_cancel_all_timer23a(if1);
710 DBG_8723A("+r871xu_dev_remove, hw_init_completed =%d\n",
711 if1->hw_init_completed);
713 rtw_handle_dualmac23a(if1, 0);
716 rtw_wdev_unregister(if1->rtw_wdev);
717 rtw_wdev_free(if1->rtw_wdev);
720 #ifdef CONFIG_8723AU_BT_COEXIST
721 if (1 == if1->pwrctrlpriv.autopm_cnt) {
722 usb_autopm_put_interface(adapter_to_dvobj(if1)->pusbintf);
723 if1->pwrctrlpriv.autopm_cnt--;
727 rtw_free_drv_sw23a(if1);
730 free_netdev(pnetdev);
733 static int rtw_drv_init(struct usb_interface *pusb_intf,
734 const struct usb_device_id *pdid)
736 struct rtw_adapter *if1 = NULL;
737 struct dvobj_priv *dvobj;
740 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_init\n"));
742 /* Initialize dvobj_priv */
743 dvobj = usb_dvobj_init(pusb_intf);
745 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
746 ("initialize device object priv Failed!\n"));
750 if1 = rtw_usb_if1_init(dvobj, pusb_intf, pdid);
752 DBG_8723A("rtw_init_primary_adapter Failed!\n");
756 /* dev_alloc_name && register_netdev */
757 status = rtw_drv_register_netdev(if1);
758 if (status != _SUCCESS)
760 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
761 ("-871x_drv - drv_init, success!\n"));
766 if (status != _SUCCESS && if1)
767 rtw_usb_if1_deinit(if1);
769 if (status != _SUCCESS)
770 usb_dvobj_deinit(pusb_intf);
772 return status == _SUCCESS ? 0 : -ENODEV;
775 /* dev_remove() - our device is being removed */
776 static void rtw_disconnect(struct usb_interface *pusb_intf)
778 struct dvobj_priv *dvobj;
779 struct rtw_adapter *padapter;
780 struct net_device *pnetdev;
781 struct mlme_priv *pmlmepriv;
783 dvobj = usb_get_intfdata(pusb_intf);
787 padapter = dvobj->if1;
788 pnetdev = padapter->pnetdev;
789 pmlmepriv = &padapter->mlmepriv;
791 usb_set_intfdata(pusb_intf, NULL);
793 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n"));
795 rtw_pm_set_ips23a(padapter, IPS_NONE);
796 rtw_pm_set_lps23a(padapter, PS_MODE_ACTIVE);
798 LeaveAllPowerSaveMode23a(padapter);
800 rtw_usb_if1_deinit(padapter);
802 usb_dvobj_deinit(pusb_intf);
804 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-dev_remove()\n"));
805 DBG_8723A("-r871xu_dev_remove, done\n");
810 static int __init rtw_drv_entry(void)
812 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_entry\n"));
813 return usb_register(usb_drv);
816 static void __exit rtw_drv_halt(void)
818 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_halt\n"));
819 DBG_8723A("+rtw_drv_halt\n");
821 usb_deregister(usb_drv);
823 DBG_8723A("-rtw_drv_halt\n");
826 module_init(rtw_drv_entry);
827 module_exit(rtw_drv_halt);