[go: nahoru, domu]

1/******************************************************************************
2 * usb_intf.c
3 *
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
22 *
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>
25 * Larry Finger <Larry.Finger@lwfinger.net>
26 *
27 ******************************************************************************/
28
29#define _HCI_INTF_C_
30
31#include <linux/usb.h>
32#include <linux/module.h>
33#include <linux/firmware.h>
34
35#include "osdep_service.h"
36#include "drv_types.h"
37#include "recv_osdep.h"
38#include "xmit_osdep.h"
39#include "rtl8712_efuse.h"
40#include "usb_ops.h"
41#include "usb_osintf.h"
42
43static struct usb_interface *pintf;
44
45static int r871xu_drv_init(struct usb_interface *pusb_intf,
46			   const struct usb_device_id *pdid);
47
48static void r871xu_dev_remove(struct usb_interface *pusb_intf);
49
50static struct usb_device_id rtl871x_usb_id_tbl[] = {
51
52/* RTL8188SU */
53	/* Realtek */
54	{USB_DEVICE(0x0BDA, 0x8171)},
55	{USB_DEVICE(0x0bda, 0x8173)},
56	{USB_DEVICE(0x0bda, 0x8712)},
57	{USB_DEVICE(0x0bda, 0x8713)},
58	{USB_DEVICE(0x0bda, 0xC512)},
59	/* Abocom */
60	{USB_DEVICE(0x07B8, 0x8188)},
61	/* ASUS */
62	{USB_DEVICE(0x0B05, 0x1786)},
63	{USB_DEVICE(0x0B05, 0x1791)}, /* 11n mode disable */
64	/* Belkin */
65	{USB_DEVICE(0x050D, 0x945A)},
66	/* ISY IWL - Belkin clone */
67	{USB_DEVICE(0x050D, 0x11F1)},
68	/* Corega */
69	{USB_DEVICE(0x07AA, 0x0047)},
70	/* D-Link */
71	{USB_DEVICE(0x2001, 0x3306)},
72	{USB_DEVICE(0x07D1, 0x3306)}, /* 11n mode disable */
73	/* Edimax */
74	{USB_DEVICE(0x7392, 0x7611)},
75	/* EnGenius */
76	{USB_DEVICE(0x1740, 0x9603)},
77	/* Hawking */
78	{USB_DEVICE(0x0E66, 0x0016)},
79	/* Hercules */
80	{USB_DEVICE(0x06F8, 0xE034)},
81	{USB_DEVICE(0x06F8, 0xE032)},
82	/* Logitec */
83	{USB_DEVICE(0x0789, 0x0167)},
84	/* PCI */
85	{USB_DEVICE(0x2019, 0xAB28)},
86	{USB_DEVICE(0x2019, 0xED16)},
87	/* Sitecom */
88	{USB_DEVICE(0x0DF6, 0x0057)},
89	{USB_DEVICE(0x0DF6, 0x0045)},
90	{USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */
91	{USB_DEVICE(0x0DF6, 0x004B)},
92	{USB_DEVICE(0x0DF6, 0x005B)},
93	{USB_DEVICE(0x0DF6, 0x005D)},
94	{USB_DEVICE(0x0DF6, 0x0063)},
95	/* Sweex */
96	{USB_DEVICE(0x177F, 0x0154)},
97	/* Thinkware */
98	{USB_DEVICE(0x0BDA, 0x5077)},
99	/* Toshiba */
100	{USB_DEVICE(0x1690, 0x0752)},
101	/* - */
102	{USB_DEVICE(0x20F4, 0x646B)},
103	{USB_DEVICE(0x083A, 0xC512)},
104	{USB_DEVICE(0x25D4, 0x4CA1)},
105	{USB_DEVICE(0x25D4, 0x4CAB)},
106
107/* RTL8191SU */
108	/* Realtek */
109	{USB_DEVICE(0x0BDA, 0x8172)},
110	{USB_DEVICE(0x0BDA, 0x8192)},
111	/* Amigo */
112	{USB_DEVICE(0x0EB0, 0x9061)},
113	/* ASUS/EKB */
114	{USB_DEVICE(0x13D3, 0x3323)},
115	{USB_DEVICE(0x13D3, 0x3311)}, /* 11n mode disable */
116	{USB_DEVICE(0x13D3, 0x3342)},
117	/* ASUS/EKBLenovo */
118	{USB_DEVICE(0x13D3, 0x3333)},
119	{USB_DEVICE(0x13D3, 0x3334)},
120	{USB_DEVICE(0x13D3, 0x3335)}, /* 11n mode disable */
121	{USB_DEVICE(0x13D3, 0x3336)}, /* 11n mode disable */
122	/* ASUS/Media BOX */
123	{USB_DEVICE(0x13D3, 0x3309)},
124	/* Belkin */
125	{USB_DEVICE(0x050D, 0x815F)},
126	/* D-Link */
127	{USB_DEVICE(0x07D1, 0x3302)},
128	{USB_DEVICE(0x07D1, 0x3300)},
129	{USB_DEVICE(0x07D1, 0x3303)},
130	/* Edimax */
131	{USB_DEVICE(0x7392, 0x7612)},
132	/* EnGenius */
133	{USB_DEVICE(0x1740, 0x9605)},
134	/* Guillemot */
135	{USB_DEVICE(0x06F8, 0xE031)},
136	/* Hawking */
137	{USB_DEVICE(0x0E66, 0x0015)},
138	/* Mediao */
139	{USB_DEVICE(0x13D3, 0x3306)},
140	/* PCI */
141	{USB_DEVICE(0x2019, 0xED18)},
142	{USB_DEVICE(0x2019, 0x4901)},
143	/* Sitecom */
144	{USB_DEVICE(0x0DF6, 0x0058)},
145	{USB_DEVICE(0x0DF6, 0x0049)},
146	{USB_DEVICE(0x0DF6, 0x004C)},
147	{USB_DEVICE(0x0DF6, 0x0064)},
148	/* Skyworth */
149	{USB_DEVICE(0x14b2, 0x3300)},
150	{USB_DEVICE(0x14b2, 0x3301)},
151	{USB_DEVICE(0x14B2, 0x3302)},
152	/* - */
153	{USB_DEVICE(0x04F2, 0xAFF2)},
154	{USB_DEVICE(0x04F2, 0xAFF5)},
155	{USB_DEVICE(0x04F2, 0xAFF6)},
156	{USB_DEVICE(0x13D3, 0x3339)},
157	{USB_DEVICE(0x13D3, 0x3340)}, /* 11n mode disable */
158	{USB_DEVICE(0x13D3, 0x3341)}, /* 11n mode disable */
159	{USB_DEVICE(0x13D3, 0x3310)},
160	{USB_DEVICE(0x13D3, 0x3325)},
161
162/* RTL8192SU */
163	/* Realtek */
164	{USB_DEVICE(0x0BDA, 0x8174)},
165	/* Belkin */
166	{USB_DEVICE(0x050D, 0x845A)},
167	/* Corega */
168	{USB_DEVICE(0x07AA, 0x0051)},
169	/* Edimax */
170	{USB_DEVICE(0x7392, 0x7622)},
171	/* NEC */
172	{USB_DEVICE(0x0409, 0x02B6)},
173	{}
174};
175
176MODULE_DEVICE_TABLE(usb, rtl871x_usb_id_tbl);
177
178static struct specific_device_id specific_device_id_tbl[] = {
179	{.idVendor = 0x0b05, .idProduct = 0x1791,
180		 .flags = SPEC_DEV_ID_DISABLE_HT},
181	{.idVendor = 0x0df6, .idProduct = 0x0059,
182		 .flags = SPEC_DEV_ID_DISABLE_HT},
183	{.idVendor = 0x13d3, .idProduct = 0x3306,
184		 .flags = SPEC_DEV_ID_DISABLE_HT},
185	{.idVendor = 0x13D3, .idProduct = 0x3311,
186		 .flags = SPEC_DEV_ID_DISABLE_HT},
187	{.idVendor = 0x13d3, .idProduct = 0x3335,
188		 .flags = SPEC_DEV_ID_DISABLE_HT},
189	{.idVendor = 0x13d3, .idProduct = 0x3336,
190		 .flags = SPEC_DEV_ID_DISABLE_HT},
191	{.idVendor = 0x13d3, .idProduct = 0x3340,
192		 .flags = SPEC_DEV_ID_DISABLE_HT},
193	{.idVendor = 0x13d3, .idProduct = 0x3341,
194		 .flags = SPEC_DEV_ID_DISABLE_HT},
195	{}
196};
197
198struct drv_priv {
199	struct usb_driver r871xu_drv;
200	int drv_registered;
201};
202
203#ifdef CONFIG_PM
204static int r871x_suspend(struct usb_interface *pusb_intf, pm_message_t state)
205{
206	struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
207
208	netdev_info(pnetdev, "Suspending...\n");
209	if (!pnetdev || !netif_running(pnetdev)) {
210		netdev_info(pnetdev, "Unable to suspend\n");
211		return 0;
212	}
213	if (pnetdev->netdev_ops->ndo_stop)
214		pnetdev->netdev_ops->ndo_stop(pnetdev);
215	mdelay(10);
216	netif_device_detach(pnetdev);
217	return 0;
218}
219
220static int r871x_resume(struct usb_interface *pusb_intf)
221{
222	struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
223
224	netdev_info(pnetdev,  "Resuming...\n");
225	if (!pnetdev || !netif_running(pnetdev)) {
226		netdev_info(pnetdev, "Unable to resume\n");
227		return 0;
228	}
229	netif_device_attach(pnetdev);
230	if (pnetdev->netdev_ops->ndo_open)
231		pnetdev->netdev_ops->ndo_open(pnetdev);
232	return 0;
233}
234
235static int r871x_reset_resume(struct usb_interface *pusb_intf)
236{
237	/* dummy routine */
238	return 0;
239}
240
241#endif
242
243static struct drv_priv drvpriv = {
244	.r871xu_drv.name = "r8712u",
245	.r871xu_drv.id_table = rtl871x_usb_id_tbl,
246	.r871xu_drv.probe = r871xu_drv_init,
247	.r871xu_drv.disconnect = r871xu_dev_remove,
248#ifdef CONFIG_PM
249	.r871xu_drv.suspend = r871x_suspend,
250	.r871xu_drv.resume = r871x_resume,
251	.r871xu_drv.reset_resume = r871x_reset_resume,
252#endif
253};
254
255static uint r8712_usb_dvobj_init(struct _adapter *padapter)
256{
257	uint	status = _SUCCESS;
258	struct	usb_device_descriptor		*pdev_desc;
259	struct	usb_host_config			*phost_conf;
260	struct	usb_config_descriptor		*pconf_desc;
261	struct	usb_host_interface		*phost_iface;
262	struct	usb_interface_descriptor	*piface_desc;
263	struct dvobj_priv *pdvobjpriv = &padapter->dvobjpriv;
264	struct usb_device *pusbd = pdvobjpriv->pusbdev;
265
266	pdvobjpriv->padapter = padapter;
267	padapter->EepromAddressSize = 6;
268	pdev_desc = &pusbd->descriptor;
269	phost_conf = pusbd->actconfig;
270	pconf_desc = &phost_conf->desc;
271	phost_iface = &pintf->altsetting[0];
272	piface_desc = &phost_iface->desc;
273	pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
274	if (pusbd->speed == USB_SPEED_HIGH) {
275		pdvobjpriv->ishighspeed = true;
276		dev_info(&pusbd->dev, "r8712u: USB_SPEED_HIGH with %d endpoints\n",
277			 pdvobjpriv->nr_endpoint);
278	} else {
279		pdvobjpriv->ishighspeed = false;
280		dev_info(&pusbd->dev, "r8712u: USB_SPEED_LOW with %d endpoints\n",
281			 pdvobjpriv->nr_endpoint);
282	}
283	if ((r8712_alloc_io_queue(padapter)) == _FAIL)
284		status = _FAIL;
285	return status;
286}
287
288static void r8712_usb_dvobj_deinit(struct _adapter *padapter)
289{
290}
291
292void rtl871x_intf_stop(struct _adapter *padapter)
293{
294	/*disable_hw_interrupt*/
295	if (padapter->bSurpriseRemoved == false) {
296		/*device still exists, so driver can do i/o operation
297		 * TODO: */
298	}
299
300	/* cancel in irp */
301	if (padapter->dvobjpriv.inirp_deinit != NULL)
302		padapter->dvobjpriv.inirp_deinit(padapter);
303	/* cancel out irp */
304	r8712_usb_write_port_cancel(padapter);
305	/* TODO:cancel other irps */
306}
307
308void r871x_dev_unload(struct _adapter *padapter)
309{
310	if (padapter->bup == true) {
311		/*s1.*/
312		padapter->bDriverStopped = true;
313
314		/*s3.*/
315		rtl871x_intf_stop(padapter);
316
317		/*s4.*/
318		r8712_stop_drv_threads(padapter);
319
320		/*s5.*/
321		if (padapter->bSurpriseRemoved == false) {
322			padapter->hw_init_completed = false;
323			rtl8712_hal_deinit(padapter);
324		}
325
326		/*s6.*/
327		if (padapter->dvobj_deinit)
328			padapter->dvobj_deinit(padapter);
329		padapter->bup = false;
330	}
331}
332
333static void disable_ht_for_spec_devid(const struct usb_device_id *pdid,
334				      struct _adapter *padapter)
335{
336	u16 vid, pid;
337	u32 flags;
338	int i;
339	int num = sizeof(specific_device_id_tbl) /
340		  sizeof(struct specific_device_id);
341
342	for (i = 0; i < num; i++) {
343		vid = specific_device_id_tbl[i].idVendor;
344		pid = specific_device_id_tbl[i].idProduct;
345		flags = specific_device_id_tbl[i].flags;
346
347		if ((pdid->idVendor == vid) && (pdid->idProduct == pid) &&
348		    (flags&SPEC_DEV_ID_DISABLE_HT)) {
349			padapter->registrypriv.ht_enable = 0;
350			padapter->registrypriv.cbw40_enable = 0;
351			padapter->registrypriv.ampdu_enable = 0;
352		}
353	}
354}
355
356static const struct device_type wlan_type = {
357	.name = "wlan",
358};
359
360/*
361 * drv_init() - a device potentially for us
362 *
363 * notes: drv_init() is called when the bus driver has located a card for us
364 * to support. We accept the new device by returning 0.
365*/
366static int r871xu_drv_init(struct usb_interface *pusb_intf,
367			   const struct usb_device_id *pdid)
368{
369	uint status;
370	struct _adapter *padapter = NULL;
371	struct dvobj_priv *pdvobjpriv;
372	struct net_device *pnetdev;
373	struct usb_device *udev;
374
375	printk(KERN_INFO "r8712u: Staging version\n");
376	/* In this probe function, O.S. will provide the usb interface pointer
377	 * to driver. We have to increase the reference count of the usb device
378	 * structure by using the usb_get_dev function.
379	 */
380	udev = interface_to_usbdev(pusb_intf);
381	usb_get_dev(udev);
382	pintf = pusb_intf;
383	/* step 1. */
384	pnetdev = r8712_init_netdev();
385	if (!pnetdev)
386		goto error;
387	padapter = netdev_priv(pnetdev);
388	disable_ht_for_spec_devid(pdid, padapter);
389	pdvobjpriv = &padapter->dvobjpriv;
390	pdvobjpriv->padapter = padapter;
391	padapter->dvobjpriv.pusbdev = udev;
392	padapter->pusb_intf = pusb_intf;
393	usb_set_intfdata(pusb_intf, pnetdev);
394	SET_NETDEV_DEV(pnetdev, &pusb_intf->dev);
395	pnetdev->dev.type = &wlan_type;
396	/* step 2. */
397	padapter->dvobj_init = &r8712_usb_dvobj_init;
398	padapter->dvobj_deinit = &r8712_usb_dvobj_deinit;
399	padapter->halpriv.hal_bus_init = &r8712_usb_hal_bus_init;
400	padapter->dvobjpriv.inirp_init = &r8712_usb_inirp_init;
401	padapter->dvobjpriv.inirp_deinit = &r8712_usb_inirp_deinit;
402	/* step 3.
403	 * initialize the dvobj_priv
404	 */
405	if (padapter->dvobj_init == NULL)
406			goto error;
407	else {
408		status = padapter->dvobj_init(padapter);
409		if (status != _SUCCESS)
410			goto error;
411	}
412	/* step 4. */
413	status = r8712_init_drv_sw(padapter);
414	if (status == _FAIL)
415		goto error;
416	/* step 5. read efuse/eeprom data and get mac_addr */
417	{
418		int i, offset;
419		u8 mac[6];
420		u8 tmpU1b, AutoloadFail, eeprom_CustomerID;
421		u8 *pdata = padapter->eeprompriv.efuse_eeprom_data;
422
423		tmpU1b = r8712_read8(padapter, EE_9346CR);/*CR9346*/
424
425		/* To check system boot selection.*/
426		dev_info(&udev->dev, "r8712u: Boot from %s: Autoload %s\n",
427			 (tmpU1b & _9356SEL) ? "EEPROM" : "EFUSE",
428			 (tmpU1b & _EEPROM_EN) ? "OK" : "Failed");
429
430		/* To check autoload success or not.*/
431		if (tmpU1b & _EEPROM_EN) {
432			AutoloadFail = true;
433			/* The following operations prevent Efuse leakage by
434			 * turning on 2.5V.
435			 */
436			tmpU1b = r8712_read8(padapter, EFUSE_TEST+3);
437			r8712_write8(padapter, EFUSE_TEST + 3, tmpU1b | 0x80);
438			msleep(20);
439			r8712_write8(padapter, EFUSE_TEST + 3,
440				     (tmpU1b & (~BIT(7))));
441
442			/* Retrieve Chip version.
443			 * Recognize IC version by Reg0x4 BIT15.
444			 */
445			tmpU1b = (u8)((r8712_read32(padapter, PMC_FSM) >> 15) &
446						    0x1F);
447			if (tmpU1b == 0x3)
448				padapter->registrypriv.chip_version =
449				     RTL8712_3rdCUT;
450			else
451				padapter->registrypriv.chip_version =
452				     (tmpU1b >> 1) + 1;
453			switch (padapter->registrypriv.chip_version) {
454			case RTL8712_1stCUT:
455			case RTL8712_2ndCUT:
456			case RTL8712_3rdCUT:
457				break;
458			default:
459				padapter->registrypriv.chip_version =
460				     RTL8712_2ndCUT;
461				break;
462			}
463
464			for (i = 0, offset = 0; i < 128; i += 8, offset++)
465				r8712_efuse_pg_packet_read(padapter, offset,
466						     &pdata[i]);
467
468			if (!r8712_initmac || !mac_pton(r8712_initmac, mac)) {
469				/* Use the mac address stored in the Efuse
470				 * offset = 0x12 for usb in efuse
471				 */
472				memcpy(mac, &pdata[0x12], ETH_ALEN);
473			}
474			eeprom_CustomerID = pdata[0x52];
475			switch (eeprom_CustomerID) {
476			case EEPROM_CID_ALPHA:
477				padapter->eeprompriv.CustomerID =
478						 RT_CID_819x_ALPHA;
479				break;
480			case EEPROM_CID_CAMEO:
481				padapter->eeprompriv.CustomerID =
482						 RT_CID_819x_CAMEO;
483				break;
484			case EEPROM_CID_SITECOM:
485				padapter->eeprompriv.CustomerID =
486						 RT_CID_819x_Sitecom;
487				break;
488			case EEPROM_CID_COREGA:
489				padapter->eeprompriv.CustomerID =
490						 RT_CID_COREGA;
491				break;
492			case EEPROM_CID_Senao:
493				padapter->eeprompriv.CustomerID =
494						 RT_CID_819x_Senao;
495				break;
496			case EEPROM_CID_EDIMAX_BELKIN:
497				padapter->eeprompriv.CustomerID =
498						 RT_CID_819x_Edimax_Belkin;
499				break;
500			case EEPROM_CID_SERCOMM_BELKIN:
501				padapter->eeprompriv.CustomerID =
502						 RT_CID_819x_Sercomm_Belkin;
503				break;
504			case EEPROM_CID_WNC_COREGA:
505				padapter->eeprompriv.CustomerID =
506						 RT_CID_819x_WNC_COREGA;
507				break;
508			case EEPROM_CID_WHQL:
509				break;
510			case EEPROM_CID_NetCore:
511				padapter->eeprompriv.CustomerID =
512						 RT_CID_819x_Netcore;
513				break;
514			case EEPROM_CID_CAMEO1:
515				padapter->eeprompriv.CustomerID =
516						 RT_CID_819x_CAMEO1;
517				break;
518			case EEPROM_CID_CLEVO:
519				padapter->eeprompriv.CustomerID =
520						 RT_CID_819x_CLEVO;
521				break;
522			default:
523				padapter->eeprompriv.CustomerID =
524						 RT_CID_DEFAULT;
525				break;
526			}
527			dev_info(&udev->dev, "r8712u: CustomerID = 0x%.4x\n",
528				 padapter->eeprompriv.CustomerID);
529			/* Led mode */
530			switch (padapter->eeprompriv.CustomerID) {
531			case RT_CID_DEFAULT:
532			case RT_CID_819x_ALPHA:
533			case RT_CID_819x_CAMEO:
534				padapter->ledpriv.LedStrategy = SW_LED_MODE1;
535				padapter->ledpriv.bRegUseLed = true;
536				break;
537			case RT_CID_819x_Sitecom:
538				padapter->ledpriv.LedStrategy = SW_LED_MODE2;
539				padapter->ledpriv.bRegUseLed = true;
540				break;
541			case RT_CID_COREGA:
542			case RT_CID_819x_Senao:
543				padapter->ledpriv.LedStrategy = SW_LED_MODE3;
544				padapter->ledpriv.bRegUseLed = true;
545				break;
546			case RT_CID_819x_Edimax_Belkin:
547				padapter->ledpriv.LedStrategy = SW_LED_MODE4;
548				padapter->ledpriv.bRegUseLed = true;
549				break;
550			case RT_CID_819x_Sercomm_Belkin:
551				padapter->ledpriv.LedStrategy = SW_LED_MODE5;
552				padapter->ledpriv.bRegUseLed = true;
553				break;
554			case RT_CID_819x_WNC_COREGA:
555				padapter->ledpriv.LedStrategy = SW_LED_MODE6;
556				padapter->ledpriv.bRegUseLed = true;
557				break;
558			default:
559				padapter->ledpriv.LedStrategy = SW_LED_MODE0;
560				padapter->ledpriv.bRegUseLed = false;
561				break;
562			}
563		} else
564			AutoloadFail = false;
565		if (((mac[0] == 0xff) && (mac[1] == 0xff) &&
566		     (mac[2] == 0xff) && (mac[3] == 0xff) &&
567		     (mac[4] == 0xff) && (mac[5] == 0xff)) ||
568		    ((mac[0] == 0x00) && (mac[1] == 0x00) &&
569		     (mac[2] == 0x00) && (mac[3] == 0x00) &&
570		     (mac[4] == 0x00) && (mac[5] == 0x00)) ||
571		     (AutoloadFail == false)) {
572			mac[0] = 0x00;
573			mac[1] = 0xe0;
574			mac[2] = 0x4c;
575			mac[3] = 0x87;
576			mac[4] = 0x00;
577			mac[5] = 0x00;
578		}
579		if (r8712_initmac) {
580			/* Make sure the user did not select a multicast
581			 * address by setting bit 1 of first octet.
582			 */
583			mac[0] &= 0xFE;
584			dev_info(&udev->dev,
585				"r8712u: MAC Address from user = %pM\n", mac);
586		} else
587			dev_info(&udev->dev,
588				"r8712u: MAC Address from efuse = %pM\n", mac);
589		memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
590	}
591	/* step 6. Load the firmware asynchronously */
592	if (rtl871x_load_fw(padapter))
593		goto error;
594	spin_lock_init(&padapter->lockRxFF0Filter);
595	mutex_init(&padapter->mutex_start);
596	return 0;
597error:
598	usb_put_dev(udev);
599	usb_set_intfdata(pusb_intf, NULL);
600	if (padapter && padapter->dvobj_deinit != NULL)
601		padapter->dvobj_deinit(padapter);
602	if (pnetdev)
603		free_netdev(pnetdev);
604	return -ENODEV;
605}
606
607/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove()
608 * => how to recognize both */
609static void r871xu_dev_remove(struct usb_interface *pusb_intf)
610{
611	struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
612	struct usb_device *udev = interface_to_usbdev(pusb_intf);
613
614	if (pnetdev) {
615		struct _adapter *padapter = netdev_priv(pnetdev);
616
617		usb_set_intfdata(pusb_intf, NULL);
618		release_firmware(padapter->fw);
619		/* never exit with a firmware callback pending */
620		wait_for_completion(&padapter->rtl8712_fw_ready);
621		if (drvpriv.drv_registered == true)
622			padapter->bSurpriseRemoved = true;
623		unregister_netdev(pnetdev); /* will call netdev_close() */
624		flush_scheduled_work();
625		udelay(1);
626		/* Stop driver mlme relation timer */
627		r8712_stop_drv_timers(padapter);
628		r871x_dev_unload(padapter);
629		r8712_free_drv_sw(padapter);
630
631		/* decrease the reference count of the usb device structure
632		 * when disconnect */
633		usb_put_dev(udev);
634	}
635	/* If we didn't unplug usb dongle and remove/insert module, driver
636	 * fails on sitesurvey for the first time when device is up.
637	 * Reset usb port for sitesurvey fail issue. */
638	if (udev->state != USB_STATE_NOTATTACHED)
639		usb_reset_device(udev);
640}
641
642static int __init r8712u_drv_entry(void)
643{
644	drvpriv.drv_registered = true;
645	return usb_register(&drvpriv.r871xu_drv);
646}
647
648static void __exit r8712u_drv_halt(void)
649{
650	drvpriv.drv_registered = false;
651	usb_deregister(&drvpriv.r871xu_drv);
652}
653
654module_init(r8712u_drv_entry);
655module_exit(r8712u_drv_halt);
656