• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor * epd)62 static 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 
RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor * epd)67 static 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 
RT_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor * epd)72 static 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 
rtw_init_intf_priv(struct dvobj_priv * dvobj)77 static int rtw_init_intf_priv(struct dvobj_priv *dvobj)
78 {
79 	mutex_init(&dvobj->usb_vendor_req_mutex);
80 
81 	return _SUCCESS;
82 }
83 
rtw_deinit_intf_priv(struct dvobj_priv * dvobj)84 static int rtw_deinit_intf_priv(struct dvobj_priv *dvobj)
85 {
86 	mutex_destroy(&dvobj->usb_vendor_req_mutex);
87 
88 	return _SUCCESS;
89 }
90 
usb_dvobj_init(struct usb_interface * usb_intf)91 static 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;
190 free_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 	}
200 exit:
201 	return pdvobjpriv;
202 }
203 
usb_dvobj_deinit(struct usb_interface * usb_intf)204 static 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 
rtl8723a_usb_intf_stop(struct rtw_adapter * padapter)235 void 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 
rtw_dev_unload(struct rtw_adapter * padapter)258 static 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 
rtw_hw_suspend23a(struct rtw_adapter * padapter)290 int 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;
346 error_exit:
347 	DBG_8723A("%s, failed\n", __func__);
348 	return -1;
349 }
350 
rtw_hw_resume23a(struct rtw_adapter * padapter)351 int 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;
385 error_exit:
386 	DBG_8723A("%s, Open net dev failed\n", __func__);
387 	return -1;
388 }
389 
rtw_suspend(struct usb_interface * pusb_intf,pm_message_t message)390 static 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 
452 exit:
453 	DBG_8723A("<===  %s return %d.............. in %dms\n", __func__,
454 		  ret, jiffies_to_msecs(jiffies - start_time));
455 
456 	return ret;
457 }
458 
rtw_resume(struct usb_interface * pusb_intf)459 static 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;
498 exit:
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  */
rtw_usb_if1_init(struct dvobj_priv * dvobj,struct usb_interface * pusb_intf,const struct usb_device_id * pdid)514 static 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 
591 free_hal_data:
592 	if (status != _SUCCESS)
593 		kfree(padapter->HalData);
594 free_wdev:
595 	if (status != _SUCCESS) {
596 		rtw_wdev_unregister(padapter->rtw_wdev);
597 		rtw_wdev_free(padapter->rtw_wdev);
598 	}
599 free_adapter:
600 	if (status != _SUCCESS) {
601 		if (pnetdev)
602 			free_netdev(pnetdev);
603 		padapter = NULL;
604 	}
605 	return padapter;
606 }
607 
rtw_usb_if1_deinit(struct rtw_adapter * if1)608 static 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 
rtw_drv_init(struct usb_interface * pusb_intf,const struct usb_device_id * pdid)648 static 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 
680 free_if1:
681 	if (status != _SUCCESS && if1)
682 		rtw_usb_if1_deinit(if1);
683 free_dvobj:
684 	if (status != _SUCCESS)
685 		usb_dvobj_deinit(pusb_intf);
686 exit:
687 	return status == _SUCCESS ? 0 : -ENODEV;
688 }
689 
690 /* dev_remove() - our device is being removed */
rtw_disconnect(struct usb_interface * pusb_intf)691 static 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 
rtw_drv_entry(void)725 static 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 
rtw_drv_halt(void)731 static 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 
741 module_init(rtw_drv_entry);
742 module_exit(rtw_drv_halt);
743