Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 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 | |
Ali Bahar | 359140a | 2011-09-04 03:14:11 +0800 | [diff] [blame] | 31 | #include <linux/usb.h> |
Stephen Rothwell | 81e07c0 | 2011-10-04 18:32:57 +1100 | [diff] [blame] | 32 | #include <linux/module.h> |
Larry Finger | 2080913 | 2012-02-25 18:10:21 -0600 | [diff] [blame] | 33 | #include <linux/firmware.h> |
Ali Bahar | 359140a | 2011-09-04 03:14:11 +0800 | [diff] [blame] | 34 | |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 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" |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 40 | #include "usb_ops.h" |
| 41 | #include "usb_osintf.h" |
| 42 | |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 43 | static struct usb_interface *pintf; |
| 44 | |
| 45 | static int r871xu_drv_init(struct usb_interface *pusb_intf, |
| 46 | const struct usb_device_id *pdid); |
| 47 | |
| 48 | static void r871xu_dev_remove(struct usb_interface *pusb_intf); |
| 49 | |
| 50 | static struct usb_device_id rtl871x_usb_id_tbl[] = { |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 51 | |
| 52 | /* RTL8188SU */ |
| 53 | /* Realtek */ |
| 54 | {USB_DEVICE(0x0BDA, 0x8171)}, |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 55 | {USB_DEVICE(0x0bda, 0x8173)}, |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 56 | {USB_DEVICE(0x0bda, 0x8712)}, |
| 57 | {USB_DEVICE(0x0bda, 0x8713)}, |
| 58 | {USB_DEVICE(0x0bda, 0xC512)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 59 | /* Abocom */ |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 60 | {USB_DEVICE(0x07B8, 0x8188)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 61 | /* ASUS */ |
| 62 | {USB_DEVICE(0x0B05, 0x1786)}, |
| 63 | {USB_DEVICE(0x0B05, 0x1791)}, /* 11n mode disable */ |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 64 | /* Belkin */ |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 65 | {USB_DEVICE(0x050D, 0x945A)}, |
Larry Finger | da849a9 | 2012-12-29 11:36:53 -0600 | [diff] [blame] | 66 | /* ISY IWL - Belkin clone */ |
| 67 | {USB_DEVICE(0x050D, 0x11F1)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 68 | /* Corega */ |
| 69 | {USB_DEVICE(0x07AA, 0x0047)}, |
| 70 | /* D-Link */ |
| 71 | {USB_DEVICE(0x2001, 0x3306)}, |
| 72 | {USB_DEVICE(0x07D1, 0x3306)}, /* 11n mode disable */ |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 73 | /* Edimax */ |
| 74 | {USB_DEVICE(0x7392, 0x7611)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 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)}, |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 87 | /* Sitecom */ |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 88 | {USB_DEVICE(0x0DF6, 0x0057)}, |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 89 | {USB_DEVICE(0x0DF6, 0x0045)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 90 | {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */ |
| 91 | {USB_DEVICE(0x0DF6, 0x004B)}, |
Larry Finger | 1793bf1 | 2012-01-07 10:07:03 -0600 | [diff] [blame] | 92 | {USB_DEVICE(0x0DF6, 0x005B)}, |
Larry Finger | c7caf4d | 2011-12-11 10:27:54 -0600 | [diff] [blame] | 93 | {USB_DEVICE(0x0DF6, 0x005D)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 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)}, |
Lubomir Schmidt | 3026b0e | 2012-06-15 15:12:17 -0500 | [diff] [blame] | 104 | {USB_DEVICE(0x25D4, 0x4CA1)}, |
| 105 | {USB_DEVICE(0x25D4, 0x4CAB)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 106 | |
| 107 | /* RTL8191SU */ |
| 108 | /* Realtek */ |
| 109 | {USB_DEVICE(0x0BDA, 0x8172)}, |
Martin Krause | 07b99cf | 2012-03-02 13:01:40 +0100 | [diff] [blame] | 110 | {USB_DEVICE(0x0BDA, 0x8192)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 111 | /* Amigo */ |
| 112 | {USB_DEVICE(0x0EB0, 0x9061)}, |
| 113 | /* ASUS/EKB */ |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 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)}, |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 136 | /* Hawking */ |
| 137 | {USB_DEVICE(0x0E66, 0x0015)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 138 | /* Mediao */ |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 139 | {USB_DEVICE(0x13D3, 0x3306)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 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)}, |
Larry Finger | 1e6e632 | 2015-10-18 22:14:48 -0500 | [diff] [blame] | 147 | {USB_DEVICE(0x0DF6, 0x006C)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 148 | {USB_DEVICE(0x0DF6, 0x0064)}, |
| 149 | /* Skyworth */ |
| 150 | {USB_DEVICE(0x14b2, 0x3300)}, |
| 151 | {USB_DEVICE(0x14b2, 0x3301)}, |
| 152 | {USB_DEVICE(0x14B2, 0x3302)}, |
| 153 | /* - */ |
| 154 | {USB_DEVICE(0x04F2, 0xAFF2)}, |
| 155 | {USB_DEVICE(0x04F2, 0xAFF5)}, |
| 156 | {USB_DEVICE(0x04F2, 0xAFF6)}, |
| 157 | {USB_DEVICE(0x13D3, 0x3339)}, |
| 158 | {USB_DEVICE(0x13D3, 0x3340)}, /* 11n mode disable */ |
| 159 | {USB_DEVICE(0x13D3, 0x3341)}, /* 11n mode disable */ |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 160 | {USB_DEVICE(0x13D3, 0x3310)}, |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 161 | {USB_DEVICE(0x13D3, 0x3325)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 162 | |
| 163 | /* RTL8192SU */ |
| 164 | /* Realtek */ |
| 165 | {USB_DEVICE(0x0BDA, 0x8174)}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 166 | /* Belkin */ |
| 167 | {USB_DEVICE(0x050D, 0x845A)}, |
| 168 | /* Corega */ |
| 169 | {USB_DEVICE(0x07AA, 0x0051)}, |
| 170 | /* Edimax */ |
| 171 | {USB_DEVICE(0x7392, 0x7622)}, |
| 172 | /* NEC */ |
| 173 | {USB_DEVICE(0x0409, 0x02B6)}, |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 174 | {} |
| 175 | }; |
| 176 | |
| 177 | MODULE_DEVICE_TABLE(usb, rtl871x_usb_id_tbl); |
| 178 | |
| 179 | static struct specific_device_id specific_device_id_tbl[] = { |
| 180 | {.idVendor = 0x0b05, .idProduct = 0x1791, |
| 181 | .flags = SPEC_DEV_ID_DISABLE_HT}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 182 | {.idVendor = 0x0df6, .idProduct = 0x0059, |
| 183 | .flags = SPEC_DEV_ID_DISABLE_HT}, |
| 184 | {.idVendor = 0x13d3, .idProduct = 0x3306, |
| 185 | .flags = SPEC_DEV_ID_DISABLE_HT}, |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 186 | {.idVendor = 0x13D3, .idProduct = 0x3311, |
| 187 | .flags = SPEC_DEV_ID_DISABLE_HT}, |
Axel Köllhofer | 6b28405 | 2011-01-22 14:33:50 -0600 | [diff] [blame] | 188 | {.idVendor = 0x13d3, .idProduct = 0x3335, |
| 189 | .flags = SPEC_DEV_ID_DISABLE_HT}, |
| 190 | {.idVendor = 0x13d3, .idProduct = 0x3336, |
| 191 | .flags = SPEC_DEV_ID_DISABLE_HT}, |
| 192 | {.idVendor = 0x13d3, .idProduct = 0x3340, |
| 193 | .flags = SPEC_DEV_ID_DISABLE_HT}, |
| 194 | {.idVendor = 0x13d3, .idProduct = 0x3341, |
| 195 | .flags = SPEC_DEV_ID_DISABLE_HT}, |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 196 | {} |
| 197 | }; |
| 198 | |
| 199 | struct drv_priv { |
| 200 | struct usb_driver r871xu_drv; |
| 201 | int drv_registered; |
| 202 | }; |
| 203 | |
| 204 | #ifdef CONFIG_PM |
| 205 | static int r871x_suspend(struct usb_interface *pusb_intf, pm_message_t state) |
| 206 | { |
| 207 | struct net_device *pnetdev = usb_get_intfdata(pusb_intf); |
Hemmo Nieminen | 39e9526 | 2015-12-04 00:11:32 +0200 | [diff] [blame] | 208 | struct _adapter *padapter = netdev_priv(pnetdev); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 209 | |
Przemo Firszt | 87a573a | 2012-12-10 23:21:21 +0000 | [diff] [blame] | 210 | netdev_info(pnetdev, "Suspending...\n"); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 211 | if (!pnetdev || !netif_running(pnetdev)) { |
Przemo Firszt | 87a573a | 2012-12-10 23:21:21 +0000 | [diff] [blame] | 212 | netdev_info(pnetdev, "Unable to suspend\n"); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 213 | return 0; |
| 214 | } |
Hemmo Nieminen | 39e9526 | 2015-12-04 00:11:32 +0200 | [diff] [blame] | 215 | padapter->bSuspended = true; |
| 216 | rtl871x_intf_stop(padapter); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 217 | if (pnetdev->netdev_ops->ndo_stop) |
| 218 | pnetdev->netdev_ops->ndo_stop(pnetdev); |
| 219 | mdelay(10); |
| 220 | netif_device_detach(pnetdev); |
| 221 | return 0; |
| 222 | } |
| 223 | |
Amitoj Kaur Chawla | f99ca86 | 2016-02-16 18:31:55 +0530 | [diff] [blame] | 224 | static void rtl871x_intf_resume(struct _adapter *padapter) |
Hemmo Nieminen | 39e9526 | 2015-12-04 00:11:32 +0200 | [diff] [blame] | 225 | { |
| 226 | if (padapter->dvobjpriv.inirp_init) |
| 227 | padapter->dvobjpriv.inirp_init(padapter); |
| 228 | } |
| 229 | |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 230 | static int r871x_resume(struct usb_interface *pusb_intf) |
| 231 | { |
| 232 | struct net_device *pnetdev = usb_get_intfdata(pusb_intf); |
Hemmo Nieminen | 39e9526 | 2015-12-04 00:11:32 +0200 | [diff] [blame] | 233 | struct _adapter *padapter = netdev_priv(pnetdev); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 234 | |
Przemo Firszt | 87a573a | 2012-12-10 23:21:21 +0000 | [diff] [blame] | 235 | netdev_info(pnetdev, "Resuming...\n"); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 236 | if (!pnetdev || !netif_running(pnetdev)) { |
Przemo Firszt | 87a573a | 2012-12-10 23:21:21 +0000 | [diff] [blame] | 237 | netdev_info(pnetdev, "Unable to resume\n"); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 238 | return 0; |
| 239 | } |
| 240 | netif_device_attach(pnetdev); |
| 241 | if (pnetdev->netdev_ops->ndo_open) |
| 242 | pnetdev->netdev_ops->ndo_open(pnetdev); |
Hemmo Nieminen | 39e9526 | 2015-12-04 00:11:32 +0200 | [diff] [blame] | 243 | padapter->bSuspended = false; |
| 244 | rtl871x_intf_resume(padapter); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 245 | return 0; |
| 246 | } |
| 247 | |
| 248 | static int r871x_reset_resume(struct usb_interface *pusb_intf) |
| 249 | { |
| 250 | /* dummy routine */ |
| 251 | return 0; |
| 252 | } |
| 253 | |
| 254 | #endif |
| 255 | |
| 256 | static struct drv_priv drvpriv = { |
| 257 | .r871xu_drv.name = "r8712u", |
| 258 | .r871xu_drv.id_table = rtl871x_usb_id_tbl, |
| 259 | .r871xu_drv.probe = r871xu_drv_init, |
| 260 | .r871xu_drv.disconnect = r871xu_dev_remove, |
| 261 | #ifdef CONFIG_PM |
| 262 | .r871xu_drv.suspend = r871x_suspend, |
| 263 | .r871xu_drv.resume = r871x_resume, |
| 264 | .r871xu_drv.reset_resume = r871x_reset_resume, |
| 265 | #endif |
| 266 | }; |
| 267 | |
| 268 | static uint r8712_usb_dvobj_init(struct _adapter *padapter) |
| 269 | { |
| 270 | uint status = _SUCCESS; |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 271 | struct usb_host_interface *phost_iface; |
| 272 | struct usb_interface_descriptor *piface_desc; |
| 273 | struct dvobj_priv *pdvobjpriv = &padapter->dvobjpriv; |
| 274 | struct usb_device *pusbd = pdvobjpriv->pusbdev; |
| 275 | |
| 276 | pdvobjpriv->padapter = padapter; |
| 277 | padapter->EepromAddressSize = 6; |
Johan Hovold | c7fbb19 | 2019-12-10 12:47:51 +0100 | [diff] [blame] | 278 | phost_iface = pintf->cur_altsetting; |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 279 | piface_desc = &phost_iface->desc; |
| 280 | pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; |
| 281 | if (pusbd->speed == USB_SPEED_HIGH) { |
| 282 | pdvobjpriv->ishighspeed = true; |
Przemo Firszt | 87a573a | 2012-12-10 23:21:21 +0000 | [diff] [blame] | 283 | dev_info(&pusbd->dev, "r8712u: USB_SPEED_HIGH with %d endpoints\n", |
| 284 | pdvobjpriv->nr_endpoint); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 285 | } else { |
| 286 | pdvobjpriv->ishighspeed = false; |
Przemo Firszt | 87a573a | 2012-12-10 23:21:21 +0000 | [diff] [blame] | 287 | dev_info(&pusbd->dev, "r8712u: USB_SPEED_LOW with %d endpoints\n", |
| 288 | pdvobjpriv->nr_endpoint); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 289 | } |
| 290 | if ((r8712_alloc_io_queue(padapter)) == _FAIL) |
| 291 | status = _FAIL; |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 292 | return status; |
| 293 | } |
| 294 | |
| 295 | static void r8712_usb_dvobj_deinit(struct _adapter *padapter) |
| 296 | { |
| 297 | } |
| 298 | |
| 299 | void rtl871x_intf_stop(struct _adapter *padapter) |
| 300 | { |
| 301 | /*disable_hw_interrupt*/ |
Tapasweni Pathak | 366ba42 | 2014-10-06 14:23:18 +0530 | [diff] [blame] | 302 | if (!padapter->bSurpriseRemoved) { |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 303 | /*device still exists, so driver can do i/o operation |
Raphaël Beamonte | bef611a | 2016-09-09 11:31:45 -0400 | [diff] [blame] | 304 | * TODO: |
| 305 | */ |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 306 | } |
| 307 | |
| 308 | /* cancel in irp */ |
Tapasweni Pathak | 366ba42 | 2014-10-06 14:23:18 +0530 | [diff] [blame] | 309 | if (padapter->dvobjpriv.inirp_deinit) |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 310 | padapter->dvobjpriv.inirp_deinit(padapter); |
| 311 | /* cancel out irp */ |
| 312 | r8712_usb_write_port_cancel(padapter); |
| 313 | /* TODO:cancel other irps */ |
| 314 | } |
| 315 | |
| 316 | void r871x_dev_unload(struct _adapter *padapter) |
| 317 | { |
Luis de Bethencourt | 1ca9688 | 2015-10-19 18:14:29 +0100 | [diff] [blame] | 318 | if (padapter->bup) { |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 319 | /*s1.*/ |
| 320 | padapter->bDriverStopped = true; |
| 321 | |
| 322 | /*s3.*/ |
| 323 | rtl871x_intf_stop(padapter); |
| 324 | |
| 325 | /*s4.*/ |
| 326 | r8712_stop_drv_threads(padapter); |
| 327 | |
| 328 | /*s5.*/ |
Tapasweni Pathak | 366ba42 | 2014-10-06 14:23:18 +0530 | [diff] [blame] | 329 | if (!padapter->bSurpriseRemoved) { |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 330 | padapter->hw_init_completed = false; |
| 331 | rtl8712_hal_deinit(padapter); |
| 332 | } |
| 333 | |
| 334 | /*s6.*/ |
| 335 | if (padapter->dvobj_deinit) |
| 336 | padapter->dvobj_deinit(padapter); |
| 337 | padapter->bup = false; |
| 338 | } |
| 339 | } |
| 340 | |
| 341 | static void disable_ht_for_spec_devid(const struct usb_device_id *pdid, |
| 342 | struct _adapter *padapter) |
| 343 | { |
| 344 | u16 vid, pid; |
| 345 | u32 flags; |
| 346 | int i; |
Shraddha Barke | eef6c80 | 2015-10-09 00:55:18 +0530 | [diff] [blame] | 347 | int num = ARRAY_SIZE(specific_device_id_tbl); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 348 | |
| 349 | for (i = 0; i < num; i++) { |
| 350 | vid = specific_device_id_tbl[i].idVendor; |
| 351 | pid = specific_device_id_tbl[i].idProduct; |
| 352 | flags = specific_device_id_tbl[i].flags; |
| 353 | |
| 354 | if ((pdid->idVendor == vid) && (pdid->idProduct == pid) && |
Luis de Bethencourt | 4ef2de5 | 2015-10-19 18:16:01 +0100 | [diff] [blame] | 355 | (flags & SPEC_DEV_ID_DISABLE_HT)) { |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 356 | padapter->registrypriv.ht_enable = 0; |
| 357 | padapter->registrypriv.cbw40_enable = 0; |
| 358 | padapter->registrypriv.ampdu_enable = 0; |
| 359 | } |
| 360 | } |
| 361 | } |
| 362 | |
Larry Finger | 3a21f00 | 2013-12-24 11:22:54 -0600 | [diff] [blame] | 363 | static const struct device_type wlan_type = { |
| 364 | .name = "wlan", |
| 365 | }; |
| 366 | |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 367 | /* |
| 368 | * drv_init() - a device potentially for us |
| 369 | * |
| 370 | * notes: drv_init() is called when the bus driver has located a card for us |
| 371 | * to support. We accept the new device by returning 0. |
Gonçalo Salazar | 1140c8a | 2016-09-26 20:42:58 +0100 | [diff] [blame] | 372 | */ |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 373 | static int r871xu_drv_init(struct usb_interface *pusb_intf, |
| 374 | const struct usb_device_id *pdid) |
| 375 | { |
| 376 | uint status; |
| 377 | struct _adapter *padapter = NULL; |
| 378 | struct dvobj_priv *pdvobjpriv; |
| 379 | struct net_device *pnetdev; |
Ali Bahar | ee5b1aa | 2011-09-04 03:14:21 +0800 | [diff] [blame] | 380 | struct usb_device *udev; |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 381 | |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 382 | /* In this probe function, O.S. will provide the usb interface pointer |
| 383 | * to driver. We have to increase the reference count of the usb device |
| 384 | * structure by using the usb_get_dev function. |
| 385 | */ |
Ali Bahar | ee5b1aa | 2011-09-04 03:14:21 +0800 | [diff] [blame] | 386 | udev = interface_to_usbdev(pusb_intf); |
| 387 | usb_get_dev(udev); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 388 | pintf = pusb_intf; |
| 389 | /* step 1. */ |
| 390 | pnetdev = r8712_init_netdev(); |
| 391 | if (!pnetdev) |
| 392 | goto error; |
Ali Bahar | ee5b1aa | 2011-09-04 03:14:21 +0800 | [diff] [blame] | 393 | padapter = netdev_priv(pnetdev); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 394 | disable_ht_for_spec_devid(pdid, padapter); |
| 395 | pdvobjpriv = &padapter->dvobjpriv; |
| 396 | pdvobjpriv->padapter = padapter; |
Ali Bahar | ee5b1aa | 2011-09-04 03:14:21 +0800 | [diff] [blame] | 397 | padapter->dvobjpriv.pusbdev = udev; |
Larry Finger | 8c213fa59 | 2012-02-05 21:12:26 -0600 | [diff] [blame] | 398 | padapter->pusb_intf = pusb_intf; |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 399 | usb_set_intfdata(pusb_intf, pnetdev); |
| 400 | SET_NETDEV_DEV(pnetdev, &pusb_intf->dev); |
Larry Finger | 3a21f00 | 2013-12-24 11:22:54 -0600 | [diff] [blame] | 401 | pnetdev->dev.type = &wlan_type; |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 402 | /* step 2. */ |
Amitoj Kaur Chawla | ecf2e02 | 2016-02-21 19:53:27 +0530 | [diff] [blame] | 403 | padapter->dvobj_init = r8712_usb_dvobj_init; |
| 404 | padapter->dvobj_deinit = r8712_usb_dvobj_deinit; |
| 405 | padapter->halpriv.hal_bus_init = r8712_usb_hal_bus_init; |
| 406 | padapter->dvobjpriv.inirp_init = r8712_usb_inirp_init; |
| 407 | padapter->dvobjpriv.inirp_deinit = r8712_usb_inirp_deinit; |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 408 | /* step 3. |
| 409 | * initialize the dvobj_priv |
| 410 | */ |
Luis de Bethencourt | 168a2c1 | 2015-10-19 18:15:29 +0100 | [diff] [blame] | 411 | if (!padapter->dvobj_init) { |
| 412 | goto error; |
| 413 | } else { |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 414 | status = padapter->dvobj_init(padapter); |
| 415 | if (status != _SUCCESS) |
| 416 | goto error; |
| 417 | } |
| 418 | /* step 4. */ |
| 419 | status = r8712_init_drv_sw(padapter); |
| 420 | if (status == _FAIL) |
| 421 | goto error; |
| 422 | /* step 5. read efuse/eeprom data and get mac_addr */ |
| 423 | { |
| 424 | int i, offset; |
| 425 | u8 mac[6]; |
| 426 | u8 tmpU1b, AutoloadFail, eeprom_CustomerID; |
| 427 | u8 *pdata = padapter->eeprompriv.efuse_eeprom_data; |
| 428 | |
| 429 | tmpU1b = r8712_read8(padapter, EE_9346CR);/*CR9346*/ |
| 430 | |
| 431 | /* To check system boot selection.*/ |
Przemo Firszt | 87a573a | 2012-12-10 23:21:21 +0000 | [diff] [blame] | 432 | dev_info(&udev->dev, "r8712u: Boot from %s: Autoload %s\n", |
| 433 | (tmpU1b & _9356SEL) ? "EEPROM" : "EFUSE", |
| 434 | (tmpU1b & _EEPROM_EN) ? "OK" : "Failed"); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 435 | |
| 436 | /* To check autoload success or not.*/ |
| 437 | if (tmpU1b & _EEPROM_EN) { |
| 438 | AutoloadFail = true; |
| 439 | /* The following operations prevent Efuse leakage by |
| 440 | * turning on 2.5V. |
| 441 | */ |
Luis de Bethencourt | 4ef2de5 | 2015-10-19 18:16:01 +0100 | [diff] [blame] | 442 | tmpU1b = r8712_read8(padapter, EFUSE_TEST + 3); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 443 | r8712_write8(padapter, EFUSE_TEST + 3, tmpU1b | 0x80); |
| 444 | msleep(20); |
| 445 | r8712_write8(padapter, EFUSE_TEST + 3, |
| 446 | (tmpU1b & (~BIT(7)))); |
| 447 | |
| 448 | /* Retrieve Chip version. |
| 449 | * Recognize IC version by Reg0x4 BIT15. |
| 450 | */ |
| 451 | tmpU1b = (u8)((r8712_read32(padapter, PMC_FSM) >> 15) & |
| 452 | 0x1F); |
| 453 | if (tmpU1b == 0x3) |
| 454 | padapter->registrypriv.chip_version = |
| 455 | RTL8712_3rdCUT; |
| 456 | else |
| 457 | padapter->registrypriv.chip_version = |
| 458 | (tmpU1b >> 1) + 1; |
| 459 | switch (padapter->registrypriv.chip_version) { |
| 460 | case RTL8712_1stCUT: |
| 461 | case RTL8712_2ndCUT: |
| 462 | case RTL8712_3rdCUT: |
| 463 | break; |
| 464 | default: |
| 465 | padapter->registrypriv.chip_version = |
| 466 | RTL8712_2ndCUT; |
| 467 | break; |
| 468 | } |
| 469 | |
| 470 | for (i = 0, offset = 0; i < 128; i += 8, offset++) |
| 471 | r8712_efuse_pg_packet_read(padapter, offset, |
| 472 | &pdata[i]); |
| 473 | |
Andy Shevchenko | 3076543 | 2013-09-13 17:59:43 +0300 | [diff] [blame] | 474 | if (!r8712_initmac || !mac_pton(r8712_initmac, mac)) { |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 475 | /* Use the mac address stored in the Efuse |
| 476 | * offset = 0x12 for usb in efuse |
| 477 | */ |
Heba Aamer | 36e4d88 | 2015-01-30 00:11:36 +0200 | [diff] [blame] | 478 | ether_addr_copy(mac, &pdata[0x12]); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 479 | } |
| 480 | eeprom_CustomerID = pdata[0x52]; |
| 481 | switch (eeprom_CustomerID) { |
| 482 | case EEPROM_CID_ALPHA: |
| 483 | padapter->eeprompriv.CustomerID = |
| 484 | RT_CID_819x_ALPHA; |
| 485 | break; |
| 486 | case EEPROM_CID_CAMEO: |
| 487 | padapter->eeprompriv.CustomerID = |
| 488 | RT_CID_819x_CAMEO; |
| 489 | break; |
| 490 | case EEPROM_CID_SITECOM: |
| 491 | padapter->eeprompriv.CustomerID = |
| 492 | RT_CID_819x_Sitecom; |
| 493 | break; |
| 494 | case EEPROM_CID_COREGA: |
| 495 | padapter->eeprompriv.CustomerID = |
| 496 | RT_CID_COREGA; |
| 497 | break; |
| 498 | case EEPROM_CID_Senao: |
| 499 | padapter->eeprompriv.CustomerID = |
| 500 | RT_CID_819x_Senao; |
| 501 | break; |
| 502 | case EEPROM_CID_EDIMAX_BELKIN: |
| 503 | padapter->eeprompriv.CustomerID = |
| 504 | RT_CID_819x_Edimax_Belkin; |
| 505 | break; |
| 506 | case EEPROM_CID_SERCOMM_BELKIN: |
| 507 | padapter->eeprompriv.CustomerID = |
| 508 | RT_CID_819x_Sercomm_Belkin; |
| 509 | break; |
| 510 | case EEPROM_CID_WNC_COREGA: |
| 511 | padapter->eeprompriv.CustomerID = |
| 512 | RT_CID_819x_WNC_COREGA; |
| 513 | break; |
| 514 | case EEPROM_CID_WHQL: |
| 515 | break; |
| 516 | case EEPROM_CID_NetCore: |
| 517 | padapter->eeprompriv.CustomerID = |
| 518 | RT_CID_819x_Netcore; |
| 519 | break; |
| 520 | case EEPROM_CID_CAMEO1: |
| 521 | padapter->eeprompriv.CustomerID = |
| 522 | RT_CID_819x_CAMEO1; |
| 523 | break; |
| 524 | case EEPROM_CID_CLEVO: |
| 525 | padapter->eeprompriv.CustomerID = |
| 526 | RT_CID_819x_CLEVO; |
| 527 | break; |
| 528 | default: |
| 529 | padapter->eeprompriv.CustomerID = |
| 530 | RT_CID_DEFAULT; |
| 531 | break; |
| 532 | } |
Przemo Firszt | 87a573a | 2012-12-10 23:21:21 +0000 | [diff] [blame] | 533 | dev_info(&udev->dev, "r8712u: CustomerID = 0x%.4x\n", |
| 534 | padapter->eeprompriv.CustomerID); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 535 | /* Led mode */ |
| 536 | switch (padapter->eeprompriv.CustomerID) { |
| 537 | case RT_CID_DEFAULT: |
| 538 | case RT_CID_819x_ALPHA: |
| 539 | case RT_CID_819x_CAMEO: |
| 540 | padapter->ledpriv.LedStrategy = SW_LED_MODE1; |
| 541 | padapter->ledpriv.bRegUseLed = true; |
| 542 | break; |
| 543 | case RT_CID_819x_Sitecom: |
| 544 | padapter->ledpriv.LedStrategy = SW_LED_MODE2; |
| 545 | padapter->ledpriv.bRegUseLed = true; |
| 546 | break; |
| 547 | case RT_CID_COREGA: |
| 548 | case RT_CID_819x_Senao: |
| 549 | padapter->ledpriv.LedStrategy = SW_LED_MODE3; |
| 550 | padapter->ledpriv.bRegUseLed = true; |
| 551 | break; |
| 552 | case RT_CID_819x_Edimax_Belkin: |
| 553 | padapter->ledpriv.LedStrategy = SW_LED_MODE4; |
| 554 | padapter->ledpriv.bRegUseLed = true; |
| 555 | break; |
| 556 | case RT_CID_819x_Sercomm_Belkin: |
| 557 | padapter->ledpriv.LedStrategy = SW_LED_MODE5; |
| 558 | padapter->ledpriv.bRegUseLed = true; |
| 559 | break; |
| 560 | case RT_CID_819x_WNC_COREGA: |
| 561 | padapter->ledpriv.LedStrategy = SW_LED_MODE6; |
| 562 | padapter->ledpriv.bRegUseLed = true; |
| 563 | break; |
| 564 | default: |
| 565 | padapter->ledpriv.LedStrategy = SW_LED_MODE0; |
| 566 | padapter->ledpriv.bRegUseLed = false; |
| 567 | break; |
| 568 | } |
Luis de Bethencourt | 168a2c1 | 2015-10-19 18:15:29 +0100 | [diff] [blame] | 569 | } else { |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 570 | AutoloadFail = false; |
Luis de Bethencourt | 168a2c1 | 2015-10-19 18:15:29 +0100 | [diff] [blame] | 571 | } |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 572 | if (((mac[0] == 0xff) && (mac[1] == 0xff) && |
| 573 | (mac[2] == 0xff) && (mac[3] == 0xff) && |
| 574 | (mac[4] == 0xff) && (mac[5] == 0xff)) || |
| 575 | ((mac[0] == 0x00) && (mac[1] == 0x00) && |
| 576 | (mac[2] == 0x00) && (mac[3] == 0x00) && |
| 577 | (mac[4] == 0x00) && (mac[5] == 0x00)) || |
Tapasweni Pathak | 366ba42 | 2014-10-06 14:23:18 +0530 | [diff] [blame] | 578 | (!AutoloadFail)) { |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 579 | mac[0] = 0x00; |
| 580 | mac[1] = 0xe0; |
| 581 | mac[2] = 0x4c; |
| 582 | mac[3] = 0x87; |
| 583 | mac[4] = 0x00; |
| 584 | mac[5] = 0x00; |
| 585 | } |
| 586 | if (r8712_initmac) { |
| 587 | /* Make sure the user did not select a multicast |
| 588 | * address by setting bit 1 of first octet. |
| 589 | */ |
| 590 | mac[0] &= 0xFE; |
Tapasweni Pathak | 57b6686 | 2014-09-21 06:42:21 +0530 | [diff] [blame] | 591 | dev_info(&udev->dev, |
| 592 | "r8712u: MAC Address from user = %pM\n", mac); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 593 | } else |
Tapasweni Pathak | 57b6686 | 2014-09-21 06:42:21 +0530 | [diff] [blame] | 594 | dev_info(&udev->dev, |
| 595 | "r8712u: MAC Address from efuse = %pM\n", mac); |
Heba Aamer | 36e4d88 | 2015-01-30 00:11:36 +0200 | [diff] [blame] | 596 | ether_addr_copy(pnetdev->dev_addr, mac); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 597 | } |
Larry Finger | 8c213fa59 | 2012-02-05 21:12:26 -0600 | [diff] [blame] | 598 | /* step 6. Load the firmware asynchronously */ |
| 599 | if (rtl871x_load_fw(padapter)) |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 600 | goto error; |
Ali Bahar | ee5b1aa | 2011-09-04 03:14:21 +0800 | [diff] [blame] | 601 | spin_lock_init(&padapter->lockRxFF0Filter); |
Larry Finger | 8c213fa59 | 2012-02-05 21:12:26 -0600 | [diff] [blame] | 602 | mutex_init(&padapter->mutex_start); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 603 | return 0; |
| 604 | error: |
Ali Bahar | ee5b1aa | 2011-09-04 03:14:21 +0800 | [diff] [blame] | 605 | usb_put_dev(udev); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 606 | usb_set_intfdata(pusb_intf, NULL); |
Rickard Strandqvist | ac082bc | 2014-05-20 23:34:25 +0200 | [diff] [blame] | 607 | if (padapter && padapter->dvobj_deinit != NULL) |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 608 | padapter->dvobj_deinit(padapter); |
| 609 | if (pnetdev) |
Ali Bahar | 7bcd9ce | 2011-09-04 03:14:06 +0800 | [diff] [blame] | 610 | free_netdev(pnetdev); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 611 | return -ENODEV; |
| 612 | } |
| 613 | |
| 614 | /* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() |
Raphaël Beamonte | bef611a | 2016-09-09 11:31:45 -0400 | [diff] [blame] | 615 | * => how to recognize both |
| 616 | */ |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 617 | static void r871xu_dev_remove(struct usb_interface *pusb_intf) |
| 618 | { |
| 619 | struct net_device *pnetdev = usb_get_intfdata(pusb_intf); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 620 | struct usb_device *udev = interface_to_usbdev(pusb_intf); |
| 621 | |
Thomas Vegas | 5947956 | 2014-06-01 14:34:39 +0200 | [diff] [blame] | 622 | if (pnetdev) { |
| 623 | struct _adapter *padapter = netdev_priv(pnetdev); |
| 624 | |
| 625 | usb_set_intfdata(pusb_intf, NULL); |
Thomas Vegas | 22649bb | 2014-06-01 14:34:40 +0200 | [diff] [blame] | 626 | release_firmware(padapter->fw); |
Thomas Vegas | 5947956 | 2014-06-01 14:34:39 +0200 | [diff] [blame] | 627 | /* never exit with a firmware callback pending */ |
| 628 | wait_for_completion(&padapter->rtl8712_fw_ready); |
Luis de Bethencourt | 1ca9688 | 2015-10-19 18:14:29 +0100 | [diff] [blame] | 629 | if (drvpriv.drv_registered) |
Thomas Vegas | 5947956 | 2014-06-01 14:34:39 +0200 | [diff] [blame] | 630 | padapter->bSurpriseRemoved = true; |
| 631 | unregister_netdev(pnetdev); /* will call netdev_close() */ |
| 632 | flush_scheduled_work(); |
| 633 | udelay(1); |
| 634 | /* Stop driver mlme relation timer */ |
Thomas Vegas | 22649bb | 2014-06-01 14:34:40 +0200 | [diff] [blame] | 635 | r8712_stop_drv_timers(padapter); |
Thomas Vegas | 5947956 | 2014-06-01 14:34:39 +0200 | [diff] [blame] | 636 | r871x_dev_unload(padapter); |
| 637 | r8712_free_drv_sw(padapter); |
| 638 | |
| 639 | /* decrease the reference count of the usb device structure |
Raphaël Beamonte | bef611a | 2016-09-09 11:31:45 -0400 | [diff] [blame] | 640 | * when disconnect |
| 641 | */ |
Thomas Vegas | 5947956 | 2014-06-01 14:34:39 +0200 | [diff] [blame] | 642 | usb_put_dev(udev); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 643 | } |
Justin P. Mattock | be10ac2 | 2012-05-07 07:38:22 -0700 | [diff] [blame] | 644 | /* If we didn't unplug usb dongle and remove/insert module, driver |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 645 | * fails on sitesurvey for the first time when device is up. |
Raphaël Beamonte | bef611a | 2016-09-09 11:31:45 -0400 | [diff] [blame] | 646 | * Reset usb port for sitesurvey fail issue. |
| 647 | */ |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 648 | if (udev->state != USB_STATE_NOTATTACHED) |
| 649 | usb_reset_device(udev); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 650 | } |
| 651 | |
| 652 | static int __init r8712u_drv_entry(void) |
| 653 | { |
| 654 | drvpriv.drv_registered = true; |
| 655 | return usb_register(&drvpriv.r871xu_drv); |
| 656 | } |
| 657 | |
| 658 | static void __exit r8712u_drv_halt(void) |
| 659 | { |
| 660 | drvpriv.drv_registered = false; |
| 661 | usb_deregister(&drvpriv.r871xu_drv); |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 662 | } |
| 663 | |
| 664 | module_init(r8712u_drv_entry); |
| 665 | module_exit(r8712u_drv_halt); |