1b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger/****************************************************************************** 2b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * 3b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 4b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * 5b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * This program is free software; you can redistribute it and/or modify it 6b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * under the terms of version 2 of the GNU General Public License as 7b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * published by the Free Software Foundation. 8b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * 9b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * This program is distributed in the hope that it will be useful, but WITHOUT 10b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * more details. 13b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * 14b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ******************************************************************************/ 15b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define _HCI_INTF_C_ 16b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 17b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <osdep_service.h> 18b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <drv_types.h> 19b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <recv_osdep.h> 20b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <xmit_osdep.h> 21b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <hal_intf.h> 22b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <rtw_version.h> 23b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <osdep_intf.h> 24b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <usb_ops.h> 251f4746f1c51a42e4ad2f7316bdc89e67191a053eJes Sorensen#include <rtl8723a_hal.h> 26b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 27b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_suspend(struct usb_interface *intf, pm_message_t message); 28b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_resume(struct usb_interface *intf); 29b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_drv_init(struct usb_interface *pusb_intf, 30b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const struct usb_device_id *pdid); 31b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_disconnect(struct usb_interface *pusb_intf); 32b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 33b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define USB_VENDER_ID_REALTEK 0x0BDA 34b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 35b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTL8723A_USB_IDS \ 36b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x8724, \ 37b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */ \ 38b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x1724, \ 39b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */ \ 40b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x0724, \ 41b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */ 42b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 43b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct usb_device_id rtl8723a_usb_id_tbl[] = { 44b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RTL8723A_USB_IDS 45b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger {} /* Terminating entry */ 46b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 47b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 48b1925ad84625302fac456d8671b2acafcabf57f5Larry FingerMODULE_DEVICE_TABLE(usb, rtl8723a_usb_id_tbl); 49b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 50b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct usb_driver rtl8723a_usb_drv = { 51b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .name = (char *)"rtl8723au", 52b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .probe = rtw_drv_init, 53b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .disconnect = rtw_disconnect, 54b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .id_table = rtl8723a_usb_id_tbl, 55b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .suspend = rtw_suspend, 56b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .resume = rtw_resume, 57b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .reset_resume = rtw_resume, 58b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 59b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 60b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct usb_driver *usb_drv = &rtl8723a_usb_drv; 61b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 62b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) 63b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 64c8875b2f1fc830f07cd08b8b5bce99471bfcffd9Jes Sorensen return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd); 65b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 66b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 67b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) 68b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 69c8875b2f1fc830f07cd08b8b5bce99471bfcffd9Jes Sorensen return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd); 70b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 71b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 72b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic inline int RT_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) 73b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 74c8875b2f1fc830f07cd08b8b5bce99471bfcffd9Jes Sorensen return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd); 75b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 76b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7786c3e3f11e83af86ad3876ecb1f9e98e35851d1bJes Sorensenstatic int rtw_init_intf_priv(struct dvobj_priv *dvobj) 78b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 79b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_init(&dvobj->usb_vendor_req_mutex); 802786faa33bfc8d61b4fa45dd2e31664de796c837Jes Sorensen 812786faa33bfc8d61b4fa45dd2e31664de796c837Jes Sorensen return _SUCCESS; 82b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 83b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 8486c3e3f11e83af86ad3876ecb1f9e98e35851d1bJes Sorensenstatic int rtw_deinit_intf_priv(struct dvobj_priv *dvobj) 85b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 86b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&dvobj->usb_vendor_req_mutex); 87b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 882786faa33bfc8d61b4fa45dd2e31664de796c837Jes Sorensen return _SUCCESS; 89b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 90b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 91b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) 92b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 93b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *pdvobjpriv; 94b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_host_config *phost_conf; 95b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_config_descriptor *pconf_desc; 96b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_host_interface *phost_iface; 97b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_interface_descriptor *piface_desc; 98b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_host_endpoint *phost_endp; 99b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_endpoint_descriptor *pendp_desc; 100b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_device *pusbd; 101b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int i; 102b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int status = _FAIL; 103b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 104b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL); 105b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!pdvobjpriv) 106b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 107b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 108b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_init(&pdvobjpriv->hw_init_mutex); 109b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_init(&pdvobjpriv->h2c_fwcmd_mutex); 110b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_init(&pdvobjpriv->setch_mutex); 111b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_init(&pdvobjpriv->setbw_mutex); 112b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 113b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->pusbintf = usb_intf; 114b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pusbd = interface_to_usbdev(usb_intf); 115b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->pusbdev = pusbd; 116b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_set_intfdata(usb_intf, pdvobjpriv); 117b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 118b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumInPipes = 0; 119b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumOutPipes = 0; 120b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 121b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phost_conf = pusbd->actconfig; 122b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pconf_desc = &phost_conf->desc; 123b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 124b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phost_iface = &usb_intf->altsetting[0]; 125b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger piface_desc = &phost_iface->desc; 126b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 127b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces; 128b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber; 129b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; 130b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 131b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (i = 0; i < pdvobjpriv->nr_endpoint; i++) { 132b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phost_endp = phost_iface->endpoint + i; 133b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (phost_endp) { 134b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pendp_desc = &phost_endp->desc; 135b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 136b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("\nusb_endpoint_descriptor(%d):\n", i); 137b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bLength =%x\n", pendp_desc->bLength); 138b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bDescriptorType =%x\n", 139b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pendp_desc->bDescriptorType); 140b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bEndpointAddress =%x\n", 141b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pendp_desc->bEndpointAddress); 142b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("wMaxPacketSize =%d\n", 143b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger le16_to_cpu(pendp_desc->wMaxPacketSize)); 144b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bInterval =%x\n", pendp_desc->bInterval); 145b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 146b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (RT_usb_endpoint_is_bulk_in(pendp_desc)) { 147b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RT_usb_endpoint_is_bulk_in = %x\n", 148c8875b2f1fc830f07cd08b8b5bce99471bfcffd9Jes Sorensen usb_endpoint_num(pendp_desc)); 149b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = 150c8875b2f1fc830f07cd08b8b5bce99471bfcffd9Jes Sorensen usb_endpoint_num(pendp_desc); 151b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumInPipes++; 152b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (RT_usb_endpoint_is_int_in(pendp_desc)) { 153b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RT_usb_endpoint_is_int_in = %x, Interval = %x\n", 154c8875b2f1fc830f07cd08b8b5bce99471bfcffd9Jes Sorensen usb_endpoint_num(pendp_desc), 155b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pendp_desc->bInterval); 156b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = 157c8875b2f1fc830f07cd08b8b5bce99471bfcffd9Jes Sorensen usb_endpoint_num(pendp_desc); 158b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumInPipes++; 159b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (RT_usb_endpoint_is_bulk_out(pendp_desc)) { 160b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RT_usb_endpoint_is_bulk_out = %x\n", 161c8875b2f1fc830f07cd08b8b5bce99471bfcffd9Jes Sorensen usb_endpoint_num(pendp_desc)); 162b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = 163c8875b2f1fc830f07cd08b8b5bce99471bfcffd9Jes Sorensen usb_endpoint_num(pendp_desc); 164b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumOutPipes++; 165b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 166c8875b2f1fc830f07cd08b8b5bce99471bfcffd9Jes Sorensen pdvobjpriv->ep_num[i] = usb_endpoint_num(pendp_desc); 167b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 168b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 169b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("nr_endpoint =%d, in_num =%d, out_num =%d\n\n", 170b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->nr_endpoint, pdvobjpriv->RtNumInPipes, 171b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumOutPipes); 172b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 173b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pusbd->speed == USB_SPEED_HIGH) { 174b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->ishighspeed = true; 175b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("USB_SPEED_HIGH\n"); 176b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 177b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->ishighspeed = false; 178b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("NON USB_SPEED_HIGH\n"); 179b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 180b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 181b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_init_intf_priv(pdvobjpriv) == _FAIL) { 182b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_os_intfs_c_, _drv_err_, 183b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("\n Can't INIT rtw_init_intf_priv\n")); 184b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto free_dvobj; 185b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 186b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 3 misc */ 187b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_reset_continual_urb_error(pdvobjpriv); 188b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_get_dev(pusbd); 189b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger status = _SUCCESS; 190b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_dvobj: 191b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS && pdvobjpriv) { 192b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_set_intfdata(usb_intf, NULL); 193b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&pdvobjpriv->hw_init_mutex); 194b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&pdvobjpriv->h2c_fwcmd_mutex); 195b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&pdvobjpriv->setch_mutex); 196b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&pdvobjpriv->setbw_mutex); 197b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(pdvobjpriv); 198b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv = NULL; 199b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 200b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 201b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return pdvobjpriv; 202b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 203b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 204b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void usb_dvobj_deinit(struct usb_interface *usb_intf) 205b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 206b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf); 207b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 208b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_set_intfdata(usb_intf, NULL); 209b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (dvobj) { 210b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Modify condition for 92DU DMDP 2010.11.18, by Thomas */ 211b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((dvobj->NumInterfaces != 2 && dvobj->NumInterfaces != 3) || 212b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (dvobj->InterfaceNumber == 1)) { 213b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (interface_to_usbdev(usb_intf)->state != 214b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger USB_STATE_NOTATTACHED) { 215b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* If we didn't unplug usb dongle and 216b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * remove/insert module, driver fails on 217b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * sitesurvey for the first time when 218b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * device is up . 219b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * Reset usb port for sitesurvey fail issue. 220b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 221b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("usb attached..., try to reset usb device\n"); 222b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_reset_device(interface_to_usbdev(usb_intf)); 223b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 224b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 225b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_deinit_intf_priv(dvobj); 226b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&dvobj->hw_init_mutex); 227b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&dvobj->h2c_fwcmd_mutex); 228b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&dvobj->setch_mutex); 229b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&dvobj->setbw_mutex); 230b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(dvobj); 231b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 232b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_put_dev(interface_to_usbdev(usb_intf)); 233b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 234b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 235596f85adaac5259b2019d41a0e34292efe8df511Jes Sorensenvoid rtl8723a_usb_intf_stop(struct rtw_adapter *padapter) 236b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 237b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_stop\n")); 238b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 239b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* disable_hw_interrupt */ 240b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!padapter->bSurpriseRemoved) { 241b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* device still exists, so driver can do i/o operation 242b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * TODO: 243b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 244b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, 245b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("SurpriseRemoved == false\n")); 246b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 247b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 248b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* cancel in irp */ 2491aaa37613ff34f2a2828aee3d9dfb9e83c6b340fJes Sorensen rtl8723au_inirp_deinit(padapter); 250b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 251b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* cancel out irp */ 25268552a904c86e3e49d53305933371a1225d8aaf2Jes Sorensen rtl8723au_write_port_cancel(padapter); 253b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 254b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* todo:cancel other irps */ 255b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_stop\n")); 256b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 257b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 258b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_dev_unload(struct rtw_adapter *padapter) 259b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 260b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_dev_unload\n")); 261b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 262b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->bup) { 263b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("===> rtw_dev_unload\n"); 264b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 265b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bDriverStopped = true; 266b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->xmitpriv.ack_tx) 267b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_ack_tx_done23a(&padapter->xmitpriv, 268b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RTW_SCTX_DONE_DRV_STOP); 269b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 270b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s3. */ 271596f85adaac5259b2019d41a0e34292efe8df511Jes Sorensen rtl8723a_usb_intf_stop(padapter); 272b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 273b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s4. */ 27432dfcb1bf22a04251de857adc70666266c08731cJes Sorensen flush_workqueue(padapter->cmdpriv.wq); 275b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 276b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s5. */ 277b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!padapter->bSurpriseRemoved) { 278dc20d1da78a631b1c823b6cebbf8f659d0faac1dJes Sorensen rtl8723au_hal_deinit(padapter); 279b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bSurpriseRemoved = true; 280b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 281b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bup = false; 282b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 283b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, 284b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("r871x_dev_unload():padapter->bup == false\n")); 285b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 286b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("<=== rtw_dev_unload\n"); 287b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n")); 288b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 289b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 290b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerint rtw_hw_suspend23a(struct rtw_adapter *padapter) 291b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 292b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 293b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = padapter->pnetdev; 29490102edc28162210694b68a422192017e80fcbfdJes Sorensen struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 295b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 296b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((!padapter->bup) || (padapter->bDriverStopped) || 297b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (padapter->bSurpriseRemoved)) { 298b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("padapter->bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n", 299b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bup, padapter->bDriverStopped, 300b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bSurpriseRemoved); 301b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto error_exit; 302b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 303b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 304b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter) { /* system suspend */ 305b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger LeaveAllPowerSaveMode23a(padapter); 306b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 307b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("==> rtw_hw_suspend23a\n"); 308b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger down(&pwrpriv->lock); 309b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bips_processing = true; 310b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* padapter->net_closed = true; */ 311b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s1. */ 312b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetdev) { 313b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_carrier_off(pnetdev); 314b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_tx_stop_all_queues(pnetdev); 315b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 316b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 317b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2. */ 318b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_disassoc_cmd23a(padapter, 500, false); 319b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 320b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-2. indicate disconnect to os */ 321b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* rtw_indicate_disconnect23a(padapter); */ 32290102edc28162210694b68a422192017e80fcbfdJes Sorensen if (check_fwstate(pmlmepriv, _FW_LINKED)) { 32390102edc28162210694b68a422192017e80fcbfdJes Sorensen _clr_fwstate_(pmlmepriv, _FW_LINKED); 324b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 32590102edc28162210694b68a422192017e80fcbfdJes Sorensen rtw_led_control(padapter, LED_CTL_NO_LINK); 326b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 32790102edc28162210694b68a422192017e80fcbfdJes Sorensen rtw_os_indicate_disconnect23a(padapter); 328b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 32990102edc28162210694b68a422192017e80fcbfdJes Sorensen /* donnot enqueue cmd */ 33090102edc28162210694b68a422192017e80fcbfdJes Sorensen rtw_lps_ctrl_wk_cmd23a(padapter, 33190102edc28162210694b68a422192017e80fcbfdJes Sorensen LPS_CTRL_DISCONNECT, 0); 332b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 333b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-3. */ 334b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_free_assoc_resources23a(padapter, 1); 335b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 336b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-4. */ 337528e5c1dc78b9b4429f06d148014c048538019b5Jes Sorensen rtw_free_network_queue23a(padapter); 338b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_ips_dev_unload23a(padapter); 339b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->rf_pwrstate = rf_off; 340b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bips_processing = false; 341b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger up(&pwrpriv->lock); 342b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 343b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto error_exit; 344b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 345b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 346b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingererror_exit: 347b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, failed\n", __func__); 348b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -1; 349b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 350b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 351b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerint rtw_hw_resume23a(struct rtw_adapter *padapter) 352b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 353b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 354b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = padapter->pnetdev; 355b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 356b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter) { /* system resume */ 357b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("==> rtw_hw_resume23a\n"); 358b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger down(&pwrpriv->lock); 359b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bips_processing = true; 360b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_reset_drv_sw23a(padapter); 361b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 362b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pm_netdev_open23a(pnetdev, false)) { 363b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger up(&pwrpriv->lock); 364b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto error_exit; 365b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 366b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 367b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_device_attach(pnetdev); 368b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_carrier_on(pnetdev); 369b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 370b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!rtw_netif_queue_stopped(pnetdev)) 371b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_tx_start_all_queues(pnetdev); 372b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 373b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_tx_wake_all_queues(pnetdev); 374b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 375b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bkeepfwalive = false; 376b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 377b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->rf_pwrstate = rf_on; 378b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bips_processing = false; 379b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 380b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger up(&pwrpriv->lock); 381b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 382b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto error_exit; 383b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 384b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 385b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingererror_exit: 386b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, Open net dev failed\n", __func__); 387b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -1; 388b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 389b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 390b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) 391b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 392b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); 393b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = dvobj->if1; 394b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = padapter->pnetdev; 395b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 396b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 397b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 398b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned long start_time = jiffies; 399b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 400b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("==> %s (%s:%d)\n", __func__, current->comm, current->pid); 401b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 402b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((!padapter->bup) || (padapter->bDriverStopped) || 403b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (padapter->bSurpriseRemoved)) { 404b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("padapter->bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n", 405b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bup, padapter->bDriverStopped, 406b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bSurpriseRemoved); 407b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 408b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 409b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bInSuspend = true; 410b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cancel_all_timer23a(padapter); 411b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger LeaveAllPowerSaveMode23a(padapter); 412b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 413b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger down(&pwrpriv->lock); 414b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* padapter->net_closed = true; */ 415b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s1. */ 416b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetdev) { 417b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_carrier_off(pnetdev); 418b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_tx_stop_all_queues(pnetdev); 419b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 420b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 421b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2. */ 422b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_disassoc_cmd23a(padapter, 0, false); 423b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 424b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && 425b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger check_fwstate(pmlmepriv, _FW_LINKED)) { 426b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n", 427b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__, __LINE__, 428b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->cur_network.network.Ssid.ssid, 429b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->cur_network.network.MacAddress, 430b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->cur_network.network.Ssid.ssid_len, 431b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_ssid.ssid_len); 432b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 433b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_set_roaming(padapter, 1); 434b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 435b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-2. indicate disconnect to os */ 436b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_indicate_disconnect23a(padapter); 437b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-3. */ 438b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_free_assoc_resources23a(padapter, 1); 439b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-4. */ 440528e5c1dc78b9b4429f06d148014c048538019b5Jes Sorensen rtw_free_network_queue23a(padapter); 441b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 442b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_dev_unload(padapter); 443b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger up(&pwrpriv->lock); 444b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 445b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) 446810c832f5d9b99cec69b3dcb763c8c35215abf94Jes Sorensen rtw_cfg80211_indicate_scan_done( 447810c832f5d9b99cec69b3dcb763c8c35215abf94Jes Sorensen wdev_to_priv(padapter->rtw_wdev), true); 448b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 449b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) 450b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_indicate_disconnect23a(padapter); 451b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 452b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 453b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("<=== %s return %d.............. in %dms\n", __func__, 454b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret, jiffies_to_msecs(jiffies - start_time)); 455b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 456b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 457b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 458b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 459b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_resume(struct usb_interface *pusb_intf) 460b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 461b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); 462b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = dvobj->if1; 463b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev; 464b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pwrctrl_priv *pwrpriv = NULL; 465b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = -1; 466b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned long start_time = jiffies; 467b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 468b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("==> %s (%s:%d)\n", __func__, current->comm, current->pid); 469b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 470b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!padapter) 471b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 472b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetdev = padapter->pnetdev; 473b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv = &padapter->pwrctrlpriv; 474b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 475b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger down(&pwrpriv->lock); 476b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_reset_drv_sw23a(padapter); 477b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bkeepfwalive = false; 478b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 479b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive); 480d71c77b1160ce5cc32ab959a86dbd25f42108f9aJes Sorensen if (pm_netdev_open23a(pnetdev, true) != 0) { 481d71c77b1160ce5cc32ab959a86dbd25f42108f9aJes Sorensen up(&pwrpriv->lock); 482b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 483d71c77b1160ce5cc32ab959a86dbd25f42108f9aJes Sorensen } 484b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 485b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_device_attach(pnetdev); 486b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_carrier_on(pnetdev); 487b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 488b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger up(&pwrpriv->lock); 489b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 490b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->pid[1] != 0) { 491b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("pid[1]:%d\n", padapter->pid[1]); 492ce16d2f18944f9ba6cafbc73be20803d848adf78Jes Sorensen kill_pid(find_vpid(padapter->pid[1]), SIGUSR2, 1); 493b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 494b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 495b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw23a_roaming(padapter, NULL); 496b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 497b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = 0; 498b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 499b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwrpriv) 500b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bInSuspend = false; 501b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("<=== %s return %d.............. in %dms\n", __func__, 502b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret, jiffies_to_msecs(jiffies - start_time)); 503b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 504b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 505b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 506b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 507b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger/* 508b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * drv_init() - a device potentially for us 509b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * 510b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * notes: drv_init() is called when the bus driver has located a card 511b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * for us to support. 512b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * We accept the new device by returning 0. 513b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 514b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct rtw_adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, 515b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_interface *pusb_intf, 516b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const struct usb_device_id *pdid) 517b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 518b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = NULL; 519b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = NULL; 520b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int status = _FAIL; 521b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 522b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetdev = rtw_init_netdev23a(padapter); 523b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!pnetdev) 524e3916153ea15f97a343e463c4b69bd819229d41aJes Sorensen goto free_adapter; 525b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter = netdev_priv(pnetdev); 526b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 527b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->dvobj = dvobj; 528b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bDriverStopped = true; 529b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj->if1 = padapter; 530b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj->padapters[dvobj->iface_nums++] = padapter; 531b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->iface_id = IFACE_ID0; 532b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 533c174eae6f71bf3da736460e7872cdfc23c854fbcJes Sorensen rtl8723au_set_hw_type(padapter); 534b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 535b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj)); 536b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 537b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj))) 538e3916153ea15f97a343e463c4b69bd819229d41aJes Sorensen goto free_adapter; 539b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5409385d861bddfb451145500ed1375304fa6ccec41Jes Sorensen /* step 2. allocate HalData */ 5419385d861bddfb451145500ed1375304fa6ccec41Jes Sorensen padapter->HalData = kzalloc(sizeof(struct hal_data_8723a), GFP_KERNEL); 5429385d861bddfb451145500ed1375304fa6ccec41Jes Sorensen if (!padapter->HalData) 5439385d861bddfb451145500ed1375304fa6ccec41Jes Sorensen goto free_wdev; 544b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 545b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* step read_chip_version */ 54644e621c7a6234f5913ba315866712585fe6bc3e4Jes Sorensen rtl8723a_read_chip_version(padapter); 547b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 548b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* step usb endpoint mapping */ 54982ccb5972409fe838dd695ce45b79dc597428a4aJes Sorensen rtl8723au_chip_configure(padapter); 550b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 551b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* step read efuse/eeprom data and get mac_addr */ 5521f4746f1c51a42e4ad2f7316bdc89e67191a053eJes Sorensen rtl8723a_read_adapter_info(padapter); 553b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 554b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* step 5. */ 555b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_init_drv_sw23a(padapter) == _FAIL) { 556b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, 557b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("Initialize driver software resource Failed!\n")); 558b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto free_hal_data; 559b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 560b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 561b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_PM 562b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->pwrctrlpriv.bSupportRemoteWakeup) { 563b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj->pusbdev->do_remote_wakeup = 1; 564b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pusb_intf->needs_remote_wakeup = 1; 565b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger device_init_wakeup(&pusb_intf->dev, 1); 566b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~~~~\n"); 567b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n", 568b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger device_may_wakeup(&pusb_intf->dev)); 569b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 570b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 571b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 2012-07-11 Move here to prevent the 8723AS-VAU BT 572b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * auto suspend influence 573b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 574b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (usb_autopm_get_interface(pusb_intf) < 0) 575b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("can't get autopm:\n"); 576b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_BT_COEXIST 577b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->pwrctrlpriv.autopm_cnt = 1; 578b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 579b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5809d85833d1956c88bd1b19d4df5e3cc5712519a63Jes Sorensen /* If the eeprom mac address is corrupted, assign a random address */ 5819d85833d1956c88bd1b19d4df5e3cc5712519a63Jes Sorensen if (is_broadcast_ether_addr(padapter->eeprompriv.mac_addr) || 5829d85833d1956c88bd1b19d4df5e3cc5712519a63Jes Sorensen is_zero_ether_addr(padapter->eeprompriv.mac_addr)) 5839d85833d1956c88bd1b19d4df5e3cc5712519a63Jes Sorensen eth_random_addr(padapter->eeprompriv.mac_addr); 584b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 585b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n", 586b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bDriverStopped, padapter->bSurpriseRemoved, 587b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bup, padapter->hw_init_completed 588b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ); 589b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger status = _SUCCESS; 590b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 591b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_hal_data: 592b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS) 593b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(padapter->HalData); 5949385d861bddfb451145500ed1375304fa6ccec41Jes Sorensenfree_wdev: 595b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS) { 596b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev_unregister(padapter->rtw_wdev); 597b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev_free(padapter->rtw_wdev); 598b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 599b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_adapter: 600b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS) { 601b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetdev) 602b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger free_netdev(pnetdev); 603b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter = NULL; 604b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 605b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return padapter; 606b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 607b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 608b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_usb_if1_deinit(struct rtw_adapter *if1) 609b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 610b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = if1->pnetdev; 611b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &if1->mlmepriv; 612b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 613b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_LINKED)) 614b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_disassoc_cmd23a(if1, 0, false); 615b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 616b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 617b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger free_mlme_ap_info23a(if1); 618b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 619b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 620b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetdev) 621b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unregister_netdev(pnetdev); /* will call netdev_close() */ 622b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 623b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cancel_all_timer23a(if1); 624b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 625b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_dev_unload(if1); 626b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 627b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("+r871xu_dev_remove, hw_init_completed =%d\n", 628b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if1->hw_init_completed); 629b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 630b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (if1->rtw_wdev) { 631b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev_unregister(if1->rtw_wdev); 632b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev_free(if1->rtw_wdev); 633b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 634b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 635b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_BT_COEXIST 636b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (1 == if1->pwrctrlpriv.autopm_cnt) { 637b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_autopm_put_interface(adapter_to_dvobj(if1)->pusbintf); 638b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if1->pwrctrlpriv.autopm_cnt--; 639b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 640b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 641b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 642b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_free_drv_sw23a(if1); 643b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 644b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetdev) 645b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger free_netdev(pnetdev); 646b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 647b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 648b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_drv_init(struct usb_interface *pusb_intf, 649b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const struct usb_device_id *pdid) 650b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 651b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *if1 = NULL; 652b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *dvobj; 653b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int status = _FAIL; 654b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 655b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_init\n")); 656b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 657b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Initialize dvobj_priv */ 658b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj = usb_dvobj_init(pusb_intf); 659b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!dvobj) { 660b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, 661b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("initialize device object priv Failed!\n")); 662b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 663b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 664b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 665b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if1 = rtw_usb_if1_init(dvobj, pusb_intf, pdid); 666b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!if1) { 667b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("rtw_init_primary_adapter Failed!\n"); 668b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto free_dvobj; 669b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 670b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 671b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* dev_alloc_name && register_netdev */ 672b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger status = rtw_drv_register_netdev(if1); 673b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS) 674b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto free_if1; 675b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, 676b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("-871x_drv - drv_init, success!\n")); 677b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 678b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger status = _SUCCESS; 679b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 680b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_if1: 681b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS && if1) 682b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_usb_if1_deinit(if1); 683b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_dvobj: 684b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS) 685b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_dvobj_deinit(pusb_intf); 686b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 687b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return status == _SUCCESS ? 0 : -ENODEV; 688b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 689b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 690b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger/* dev_remove() - our device is being removed */ 691b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_disconnect(struct usb_interface *pusb_intf) 692b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 693b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *dvobj; 694b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter; 695b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev; 696b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv; 697b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 698b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj = usb_get_intfdata(pusb_intf); 699b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!dvobj) 700b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 701b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 702b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter = dvobj->if1; 703b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetdev = padapter->pnetdev; 704b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv = &padapter->mlmepriv; 705b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 706b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_set_intfdata(pusb_intf, NULL); 707b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 708b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n")); 709b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 710b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_pm_set_ips23a(padapter, IPS_NONE); 711b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_pm_set_lps23a(padapter, PS_MODE_ACTIVE); 712b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 713b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger LeaveAllPowerSaveMode23a(padapter); 714b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 715b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_usb_if1_deinit(padapter); 716b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 717b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_dvobj_deinit(pusb_intf); 718b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 719b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-dev_remove()\n")); 720b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("-r871xu_dev_remove, done\n"); 721b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 722b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 723b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 724b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 725b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int __init rtw_drv_entry(void) 726b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 727b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_entry\n")); 728b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return usb_register(usb_drv); 729b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 730b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 731b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void __exit rtw_drv_halt(void) 732b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 733b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_halt\n")); 734b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("+rtw_drv_halt\n"); 735b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 736b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_deregister(usb_drv); 737b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 738b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("-rtw_drv_halt\n"); 739b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 740b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 741b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingermodule_init(rtw_drv_entry); 742b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingermodule_exit(rtw_drv_halt); 743