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