qed: Change metadata needed for SPQ entries
[deliverable/linux.git] / drivers / staging / rtl8188eu / os_dep / usb_intf.c
1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 *
19 ******************************************************************************/
20
21 #define pr_fmt(fmt) "R8188EU: " fmt
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <recv_osdep.h>
25 #include <xmit_osdep.h>
26 #include <hal_intf.h>
27 #include <linux/usb.h>
28 #include <linux/vmalloc.h>
29 #include <mon.h>
30 #include <osdep_intf.h>
31
32 #include <usb_ops_linux.h>
33 #include <usb_hal.h>
34 #include <rtw_ioctl.h>
35
36 #define USB_VENDER_ID_REALTEK 0x0bda
37
38 /* DID_USB_v916_20130116 */
39 static struct usb_device_id rtw_usb_id_tbl[] = {
40 /*=== Realtek demoboard ===*/
41 {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8179)}, /* 8188EUS */
42 {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */
43 /*=== Customer ID ===*/
44 /****** 8188EUS ********/
45 {USB_DEVICE(0x056e, 0x4008)}, /* Elecom WDC-150SU2M */
46 {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */
47 {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
48 {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
49 {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
50 {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */
51 {} /* Terminating entry */
52 };
53
54 MODULE_DEVICE_TABLE(usb, rtw_usb_id_tbl);
55
56 static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
57 {
58 int i;
59 struct dvobj_priv *pdvobjpriv;
60 struct usb_host_config *phost_conf;
61 struct usb_config_descriptor *pconf_desc;
62 struct usb_host_interface *phost_iface;
63 struct usb_interface_descriptor *piface_desc;
64 struct usb_endpoint_descriptor *pendp_desc;
65 struct usb_device *pusbd;
66
67 pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL);
68 if (pdvobjpriv == NULL)
69 return NULL;
70
71 pdvobjpriv->pusbintf = usb_intf;
72 pusbd = interface_to_usbdev(usb_intf);
73 pdvobjpriv->pusbdev = pusbd;
74 usb_set_intfdata(usb_intf, pdvobjpriv);
75
76 pdvobjpriv->RtNumInPipes = 0;
77 pdvobjpriv->RtNumOutPipes = 0;
78
79 phost_conf = pusbd->actconfig;
80 pconf_desc = &phost_conf->desc;
81
82 phost_iface = &usb_intf->altsetting[0];
83 piface_desc = &phost_iface->desc;
84
85 pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces;
86 pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber;
87 pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
88
89 for (i = 0; i < pdvobjpriv->nr_endpoint; i++) {
90 int ep_num;
91 pendp_desc = &phost_iface->endpoint[i].desc;
92
93 ep_num = usb_endpoint_num(pendp_desc);
94
95 if (usb_endpoint_is_bulk_in(pendp_desc)) {
96 pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num;
97 pdvobjpriv->RtNumInPipes++;
98 } else if (usb_endpoint_is_int_in(pendp_desc)) {
99 pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num;
100 pdvobjpriv->RtNumInPipes++;
101 } else if (usb_endpoint_is_bulk_out(pendp_desc)) {
102 pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] =
103 ep_num;
104 pdvobjpriv->RtNumOutPipes++;
105 }
106 pdvobjpriv->ep_num[i] = ep_num;
107 }
108
109 if (pusbd->speed == USB_SPEED_HIGH)
110 pdvobjpriv->ishighspeed = true;
111 else
112 pdvobjpriv->ishighspeed = false;
113
114 mutex_init(&pdvobjpriv->usb_vendor_req_mutex);
115 pdvobjpriv->usb_vendor_req_buf = kzalloc(MAX_USB_IO_CTL_SIZE, GFP_KERNEL);
116
117 if (!pdvobjpriv->usb_vendor_req_buf) {
118 usb_set_intfdata(usb_intf, NULL);
119 kfree(pdvobjpriv);
120 return NULL;
121 }
122 usb_get_dev(pusbd);
123
124 return pdvobjpriv;
125 }
126
127 static void usb_dvobj_deinit(struct usb_interface *usb_intf)
128 {
129 struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf);
130
131 usb_set_intfdata(usb_intf, NULL);
132 if (dvobj) {
133 /* Modify condition for 92DU DMDP 2010.11.18, by Thomas */
134 if ((dvobj->NumInterfaces != 2 &&
135 dvobj->NumInterfaces != 3) ||
136 (dvobj->InterfaceNumber == 1)) {
137 if (interface_to_usbdev(usb_intf)->state !=
138 USB_STATE_NOTATTACHED) {
139 /* If we didn't unplug usb dongle and
140 * remove/insert module, driver fails
141 * on sitesurvey for the first time when
142 * device is up . Reset usb port for sitesurvey
143 * fail issue. */
144 pr_debug("usb attached..., try to reset usb device\n");
145 usb_reset_device(interface_to_usbdev(usb_intf));
146 }
147 }
148
149 kfree(dvobj->usb_vendor_req_buf);
150 mutex_destroy(&dvobj->usb_vendor_req_mutex);
151 kfree(dvobj);
152 }
153
154 usb_put_dev(interface_to_usbdev(usb_intf));
155
156 }
157
158 static void usb_intf_start(struct adapter *padapter)
159 {
160 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_start\n"));
161
162 rtw_hal_inirp_init(padapter);
163
164 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_start\n"));
165 }
166
167 static void usb_intf_stop(struct adapter *padapter)
168 {
169 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_stop\n"));
170
171 /* disable_hw_interrupt */
172 if (!padapter->bSurpriseRemoved) {
173 /* device still exists, so driver can do i/o operation */
174 /* TODO: */
175 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
176 ("SurpriseRemoved == false\n"));
177 }
178
179 /* cancel in irp */
180 rtw_hal_inirp_deinit(padapter);
181
182 /* cancel out irp */
183 usb_write_port_cancel(padapter);
184
185 /* todo:cancel other irps */
186
187 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_stop\n"));
188 }
189
190 static void rtw_dev_unload(struct adapter *padapter)
191 {
192 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_dev_unload\n"));
193
194 if (padapter->bup) {
195 pr_debug("===> rtw_dev_unload\n");
196 padapter->bDriverStopped = true;
197 if (padapter->xmitpriv.ack_tx)
198 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP);
199 /* s3. */
200 if (padapter->intf_stop)
201 padapter->intf_stop(padapter);
202 /* s4. */
203 if (!padapter->pwrctrlpriv.bInternalAutoSuspend)
204 rtw_stop_drv_threads(padapter);
205
206 /* s5. */
207 if (!padapter->bSurpriseRemoved) {
208 rtw_hal_deinit(padapter);
209 padapter->bSurpriseRemoved = true;
210 }
211
212 padapter->bup = false;
213 } else {
214 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
215 ("r871x_dev_unload():padapter->bup == false\n"));
216 }
217
218 pr_debug("<=== rtw_dev_unload\n");
219
220 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n"));
221 }
222
223 static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message)
224 {
225 struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
226 struct adapter *padapter = dvobj->if1;
227 struct net_device *pnetdev = padapter->pnetdev;
228 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
229 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
230 unsigned long start_time = jiffies;
231
232 pr_debug("==> %s (%s:%d)\n", __func__, current->comm, current->pid);
233
234 if ((!padapter->bup) || (padapter->bDriverStopped) ||
235 (padapter->bSurpriseRemoved)) {
236 pr_debug("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n",
237 padapter->bup, padapter->bDriverStopped,
238 padapter->bSurpriseRemoved);
239 goto exit;
240 }
241
242 pwrpriv->bInSuspend = true;
243 rtw_cancel_all_timer(padapter);
244 LeaveAllPowerSaveMode(padapter);
245
246 _enter_pwrlock(&pwrpriv->lock);
247 /* s1. */
248 if (pnetdev) {
249 netif_carrier_off(pnetdev);
250 netif_tx_stop_all_queues(pnetdev);
251 }
252
253 /* s2. */
254 rtw_disassoc_cmd(padapter, 0, false);
255
256 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
257 check_fwstate(pmlmepriv, _FW_LINKED)) {
258 pr_debug("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n",
259 __func__, __LINE__,
260 pmlmepriv->cur_network.network.Ssid.Ssid,
261 pmlmepriv->cur_network.network.MacAddress,
262 pmlmepriv->cur_network.network.Ssid.SsidLength,
263 pmlmepriv->assoc_ssid.SsidLength);
264
265 pmlmepriv->to_roaming = 1;
266 }
267 /* s2-2. indicate disconnect to os */
268 rtw_indicate_disconnect(padapter);
269 /* s2-3. */
270 rtw_free_assoc_resources(padapter);
271 /* s2-4. */
272 rtw_free_network_queue(padapter, true);
273
274 rtw_dev_unload(padapter);
275 _exit_pwrlock(&pwrpriv->lock);
276
277 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
278 rtw_indicate_scan_done(padapter, 1);
279
280 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
281 rtw_indicate_disconnect(padapter);
282
283 exit:
284 pr_debug("<=== %s .............. in %dms\n", __func__,
285 jiffies_to_msecs(jiffies - start_time));
286
287 return 0;
288 }
289
290 static int rtw_resume_process(struct adapter *padapter)
291 {
292 struct net_device *pnetdev;
293 struct pwrctrl_priv *pwrpriv = NULL;
294 int ret = -1;
295 unsigned long start_time = jiffies;
296
297 pr_debug("==> %s (%s:%d)\n", __func__, current->comm, current->pid);
298
299 if (padapter) {
300 pnetdev = padapter->pnetdev;
301 pwrpriv = &padapter->pwrctrlpriv;
302 } else {
303 goto exit;
304 }
305
306 _enter_pwrlock(&pwrpriv->lock);
307 rtw_reset_drv_sw(padapter);
308 pwrpriv->bkeepfwalive = false;
309
310 pr_debug("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive);
311 if (pm_netdev_open(pnetdev, true) != 0)
312 goto exit;
313
314 netif_device_attach(pnetdev);
315 netif_carrier_on(pnetdev);
316
317 _exit_pwrlock(&pwrpriv->lock);
318
319 rtw_roaming(padapter, NULL);
320
321 ret = 0;
322 exit:
323 if (pwrpriv)
324 pwrpriv->bInSuspend = false;
325 pr_debug("<=== %s return %d.............. in %dms\n", __func__,
326 ret, jiffies_to_msecs(jiffies - start_time));
327
328 return ret;
329 }
330
331 static int rtw_resume(struct usb_interface *pusb_intf)
332 {
333 struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
334 struct adapter *padapter = dvobj->if1;
335
336 return rtw_resume_process(padapter);
337 }
338
339 /*
340 * drv_init() - a device potentially for us
341 *
342 * notes: drv_init() is called when the bus driver has located
343 * a card for us to support.
344 * We accept the new device by returning 0.
345 */
346
347 static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
348 struct usb_interface *pusb_intf, const struct usb_device_id *pdid)
349 {
350 struct adapter *padapter = NULL;
351 struct net_device *pnetdev = NULL;
352 struct net_device *pmondev;
353 int status = _FAIL;
354
355 padapter = (struct adapter *)vzalloc(sizeof(*padapter));
356 if (padapter == NULL)
357 goto exit;
358 padapter->dvobj = dvobj;
359 dvobj->if1 = padapter;
360
361 padapter->bDriverStopped = true;
362 mutex_init(&padapter->hw_init_mutex);
363 padapter->chip_type = RTL8188E;
364
365 pnetdev = rtw_init_netdev(padapter);
366 if (pnetdev == NULL)
367 goto free_adapter;
368 SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj));
369 padapter = rtw_netdev_priv(pnetdev);
370
371 if (padapter->registrypriv.monitor_enable) {
372 pmondev = rtl88eu_mon_init();
373 if (pmondev == NULL)
374 netdev_warn(pnetdev, "Failed to initialize monitor interface");
375 padapter->pmondev = pmondev;
376 }
377
378 /* step 2. hook HalFunc, allocate HalData */
379 hal_set_hal_ops(padapter);
380
381 padapter->intf_start = &usb_intf_start;
382 padapter->intf_stop = &usb_intf_stop;
383
384 /* step read_chip_version */
385 rtw_hal_read_chip_version(padapter);
386
387 /* step usb endpoint mapping */
388 rtw_hal_chip_configure(padapter);
389
390 /* step read efuse/eeprom data and get mac_addr */
391 rtw_hal_read_chip_info(padapter);
392
393 /* step 5. */
394 if (rtw_init_drv_sw(padapter) == _FAIL) {
395 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
396 ("Initialize driver software resource Failed!\n"));
397 goto free_hal_data;
398 }
399
400 #ifdef CONFIG_PM
401 if (padapter->pwrctrlpriv.bSupportRemoteWakeup) {
402 dvobj->pusbdev->do_remote_wakeup = 1;
403 pusb_intf->needs_remote_wakeup = 1;
404 device_init_wakeup(&pusb_intf->dev, 1);
405 pr_debug("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~~~~\n");
406 pr_debug("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n",
407 device_may_wakeup(&pusb_intf->dev));
408 }
409 #endif
410
411 /* 2012-07-11 Move here to prevent the 8723AS-VAU BT auto
412 * suspend influence */
413 if (usb_autopm_get_interface(pusb_intf) < 0)
414 pr_debug("can't get autopm:\n");
415
416 /* alloc dev name after read efuse. */
417 rtw_init_netdev_name(pnetdev, padapter->registrypriv.ifname);
418 rtw_macaddr_cfg(padapter->eeprompriv.mac_addr);
419 memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
420 pr_debug("MAC Address from pnetdev->dev_addr = %pM\n",
421 pnetdev->dev_addr);
422
423 /* step 6. Tell the network stack we exist */
424 if (register_netdev(pnetdev) != 0) {
425 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("register_netdev() failed\n"));
426 goto free_hal_data;
427 }
428
429 pr_debug("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n"
430 , padapter->bDriverStopped
431 , padapter->bSurpriseRemoved
432 , padapter->bup
433 , padapter->hw_init_completed
434 );
435
436 status = _SUCCESS;
437
438 free_hal_data:
439 if (status != _SUCCESS)
440 kfree(padapter->HalData);
441 free_adapter:
442 if (status != _SUCCESS) {
443 if (pnetdev)
444 rtw_free_netdev(pnetdev);
445 else if (padapter)
446 vfree(padapter);
447 padapter = NULL;
448 }
449 exit:
450 return padapter;
451 }
452
453 static void rtw_usb_if1_deinit(struct adapter *if1)
454 {
455 struct net_device *pnetdev = if1->pnetdev;
456 struct mlme_priv *pmlmepriv = &if1->mlmepriv;
457
458 if (check_fwstate(pmlmepriv, _FW_LINKED))
459 rtw_disassoc_cmd(if1, 0, false);
460
461 #ifdef CONFIG_88EU_AP_MODE
462 free_mlme_ap_info(if1);
463 #endif
464
465 if (pnetdev) {
466 /* will call netdev_close() */
467 unregister_netdev(pnetdev);
468 rtw_proc_remove_one(pnetdev);
469 }
470 rtl88eu_mon_deinit(if1->pmondev);
471 rtw_cancel_all_timer(if1);
472
473 rtw_dev_unload(if1);
474 pr_debug("+r871xu_dev_remove, hw_init_completed=%d\n",
475 if1->hw_init_completed);
476 rtw_free_drv_sw(if1);
477 if (pnetdev)
478 rtw_free_netdev(pnetdev);
479 }
480
481 static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid)
482 {
483 struct adapter *if1 = NULL;
484 struct dvobj_priv *dvobj;
485
486 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_init\n"));
487
488 /* Initialize dvobj_priv */
489 dvobj = usb_dvobj_init(pusb_intf);
490 if (dvobj == NULL) {
491 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
492 ("initialize device object priv Failed!\n"));
493 goto exit;
494 }
495
496 if1 = rtw_usb_if1_init(dvobj, pusb_intf, pdid);
497 if (if1 == NULL) {
498 pr_debug("rtw_init_primarystruct adapter Failed!\n");
499 goto free_dvobj;
500 }
501
502 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-871x_drv - drv_init, success!\n"));
503
504 return 0;
505
506 free_dvobj:
507 usb_dvobj_deinit(pusb_intf);
508 exit:
509 return -ENODEV;
510 }
511
512 /*
513 * dev_remove() - our device is being removed
514 */
515 /* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() => how to recognize both */
516 static void rtw_dev_remove(struct usb_interface *pusb_intf)
517 {
518 struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
519 struct adapter *padapter = dvobj->if1;
520
521 pr_debug("+rtw_dev_remove\n");
522 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n"));
523
524 if (!pusb_intf->unregistering)
525 padapter->bSurpriseRemoved = true;
526
527 rtw_pm_set_ips(padapter, IPS_NONE);
528 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
529
530 LeaveAllPowerSaveMode(padapter);
531
532 rtw_usb_if1_deinit(padapter);
533
534 usb_dvobj_deinit(pusb_intf);
535
536 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-dev_remove()\n"));
537 pr_debug("-r871xu_dev_remove, done\n");
538 }
539
540 static struct usb_driver rtl8188e_usb_drv = {
541 .name = "r8188eu",
542 .probe = rtw_drv_init,
543 .disconnect = rtw_dev_remove,
544 .id_table = rtw_usb_id_tbl,
545 .suspend = rtw_suspend,
546 .resume = rtw_resume,
547 .reset_resume = rtw_resume,
548 };
549
550 module_usb_driver(rtl8188e_usb_drv)
This page took 0.056906 seconds and 5 git commands to generate.