cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

usb_intf.c (17546B)


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