usb_intf.c revision c174eae6f71bf3da736460e7872cdfc23c854fbc
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_dir_in(const struct usb_endpoint_descriptor *epd) 63b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 64b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN; 65b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 66b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 67b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic inline int RT_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd) 68b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 69b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT; 70b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 71b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 72b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic inline int RT_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd) 73b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 74b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT; 75b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 76b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 77b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic inline int RT_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd) 78b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 79b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK; 80b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 81b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 82b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) 83b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 84b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_in(epd); 85b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 86b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 87b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) 88b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 89b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_out(epd); 90b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 91b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 92b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic inline int RT_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) 93b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 94b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return RT_usb_endpoint_xfer_int(epd) && RT_usb_endpoint_dir_in(epd); 95b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 96b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 97b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic inline int RT_usb_endpoint_num(const struct usb_endpoint_descriptor *epd) 98b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 99b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 100b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 101b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 10286c3e3f11e83af86ad3876ecb1f9e98e35851d1bJes Sorensenstatic int rtw_init_intf_priv(struct dvobj_priv *dvobj) 103b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 10486c3e3f11e83af86ad3876ecb1f9e98e35851d1bJes Sorensen int rst = _SUCCESS; 105b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 106b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_init(&dvobj->usb_vendor_req_mutex); 107b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj->usb_alloc_vendor_req_buf = kzalloc(MAX_USB_IO_CTL_SIZE, 108b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_KERNEL); 109b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (dvobj->usb_alloc_vendor_req_buf == NULL) { 110b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("alloc usb_vendor_req_buf failed... /n"); 111b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rst = _FAIL; 112b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 113b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 114b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj->usb_vendor_req_buf = 115b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger PTR_ALIGN(dvobj->usb_alloc_vendor_req_buf, ALIGNMENT_UNIT); 116b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 117b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return rst; 118b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 119b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 12086c3e3f11e83af86ad3876ecb1f9e98e35851d1bJes Sorensenstatic int rtw_deinit_intf_priv(struct dvobj_priv *dvobj) 121b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 12286c3e3f11e83af86ad3876ecb1f9e98e35851d1bJes Sorensen int rst = _SUCCESS; 123b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 124b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(dvobj->usb_alloc_vendor_req_buf); 125b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 126b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&dvobj->usb_vendor_req_mutex); 127b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 128b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return rst; 129b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 130b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 131b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) 132b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 133b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *pdvobjpriv; 134b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_device_descriptor *pdev_desc; 135b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_host_config *phost_conf; 136b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_config_descriptor *pconf_desc; 137b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_host_interface *phost_iface; 138b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_interface_descriptor *piface_desc; 139b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_host_endpoint *phost_endp; 140b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_endpoint_descriptor *pendp_desc; 141b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_device *pusbd; 142b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int i; 143b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int status = _FAIL; 144b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 145b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL); 146b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!pdvobjpriv) 147b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 148b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 149b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_init(&pdvobjpriv->hw_init_mutex); 150b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_init(&pdvobjpriv->h2c_fwcmd_mutex); 151b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_init(&pdvobjpriv->setch_mutex); 152b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_init(&pdvobjpriv->setbw_mutex); 153b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 154b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->pusbintf = usb_intf; 155b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pusbd = interface_to_usbdev(usb_intf); 156b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->pusbdev = pusbd; 157b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_set_intfdata(usb_intf, pdvobjpriv); 158b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 159b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumInPipes = 0; 160b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumOutPipes = 0; 161b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 162b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdev_desc = &pusbd->descriptor; 163b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 164b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phost_conf = pusbd->actconfig; 165b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pconf_desc = &phost_conf->desc; 166b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 167b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phost_iface = &usb_intf->altsetting[0]; 168b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger piface_desc = &phost_iface->desc; 169b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 170b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces; 171b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber; 172b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; 173b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 174b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (i = 0; i < pdvobjpriv->nr_endpoint; i++) { 175b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phost_endp = phost_iface->endpoint + i; 176b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (phost_endp) { 177b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pendp_desc = &phost_endp->desc; 178b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 179b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("\nusb_endpoint_descriptor(%d):\n", i); 180b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bLength =%x\n", pendp_desc->bLength); 181b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bDescriptorType =%x\n", 182b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pendp_desc->bDescriptorType); 183b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bEndpointAddress =%x\n", 184b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pendp_desc->bEndpointAddress); 185b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("wMaxPacketSize =%d\n", 186b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger le16_to_cpu(pendp_desc->wMaxPacketSize)); 187b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bInterval =%x\n", pendp_desc->bInterval); 188b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 189b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (RT_usb_endpoint_is_bulk_in(pendp_desc)) { 190b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RT_usb_endpoint_is_bulk_in = %x\n", 191b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_usb_endpoint_num(pendp_desc)); 192b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = 193b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_usb_endpoint_num(pendp_desc); 194b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumInPipes++; 195b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (RT_usb_endpoint_is_int_in(pendp_desc)) { 196b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RT_usb_endpoint_is_int_in = %x, Interval = %x\n", 197b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_usb_endpoint_num(pendp_desc), 198b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pendp_desc->bInterval); 199b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = 200b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_usb_endpoint_num(pendp_desc); 201b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumInPipes++; 202b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (RT_usb_endpoint_is_bulk_out(pendp_desc)) { 203b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RT_usb_endpoint_is_bulk_out = %x\n", 204b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_usb_endpoint_num(pendp_desc)); 205b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = 206b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_usb_endpoint_num(pendp_desc); 207b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumOutPipes++; 208b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 209b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->ep_num[i] = RT_usb_endpoint_num(pendp_desc); 210b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 211b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 212b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("nr_endpoint =%d, in_num =%d, out_num =%d\n\n", 213b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->nr_endpoint, pdvobjpriv->RtNumInPipes, 214b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->RtNumOutPipes); 215b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 216b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pusbd->speed == USB_SPEED_HIGH) { 217b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->ishighspeed = true; 218b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("USB_SPEED_HIGH\n"); 219b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 220b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv->ishighspeed = false; 221b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("NON USB_SPEED_HIGH\n"); 222b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 223b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 224b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_init_intf_priv(pdvobjpriv) == _FAIL) { 225b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_os_intfs_c_, _drv_err_, 226b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("\n Can't INIT rtw_init_intf_priv\n")); 227b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto free_dvobj; 228b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 229b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 3 misc */ 230b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_reset_continual_urb_error(pdvobjpriv); 231b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_get_dev(pusbd); 232b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger status = _SUCCESS; 233b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_dvobj: 234b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS && pdvobjpriv) { 235b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_set_intfdata(usb_intf, NULL); 236b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&pdvobjpriv->hw_init_mutex); 237b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&pdvobjpriv->h2c_fwcmd_mutex); 238b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&pdvobjpriv->setch_mutex); 239b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&pdvobjpriv->setbw_mutex); 240b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(pdvobjpriv); 241b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdvobjpriv = NULL; 242b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 243b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 244b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return pdvobjpriv; 245b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 246b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 247b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void usb_dvobj_deinit(struct usb_interface *usb_intf) 248b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 249b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf); 250b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 251b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_set_intfdata(usb_intf, NULL); 252b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (dvobj) { 253b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Modify condition for 92DU DMDP 2010.11.18, by Thomas */ 254b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((dvobj->NumInterfaces != 2 && dvobj->NumInterfaces != 3) || 255b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (dvobj->InterfaceNumber == 1)) { 256b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (interface_to_usbdev(usb_intf)->state != 257b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger USB_STATE_NOTATTACHED) { 258b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* If we didn't unplug usb dongle and 259b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * remove/insert module, driver fails on 260b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * sitesurvey for the first time when 261b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * device is up . 262b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * Reset usb port for sitesurvey fail issue. 263b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 264b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("usb attached..., try to reset usb device\n"); 265b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_reset_device(interface_to_usbdev(usb_intf)); 266b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 267b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 268b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_deinit_intf_priv(dvobj); 269b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&dvobj->hw_init_mutex); 270b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&dvobj->h2c_fwcmd_mutex); 271b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&dvobj->setch_mutex); 272b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mutex_destroy(&dvobj->setbw_mutex); 273b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(dvobj); 274b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 275b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_put_dev(interface_to_usbdev(usb_intf)); 276b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 277b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 278b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void usb_intf_start(struct rtw_adapter *padapter) 279b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 280b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_start\n")); 2811aaa37613ff34f2a2828aee3d9dfb9e83c6b340fJes Sorensen rtl8723au_inirp_init(padapter); 282b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_start\n")); 283b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 284b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 285b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void usb_intf_stop(struct rtw_adapter *padapter) 286b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 287b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_stop\n")); 288b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 289b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* disable_hw_interrupt */ 290b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!padapter->bSurpriseRemoved) { 291b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* device still exists, so driver can do i/o operation 292b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * TODO: 293b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 294b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, 295b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("SurpriseRemoved == false\n")); 296b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 297b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 298b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* cancel in irp */ 2991aaa37613ff34f2a2828aee3d9dfb9e83c6b340fJes Sorensen rtl8723au_inirp_deinit(padapter); 300b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 301b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* cancel out irp */ 302b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_write_port_cancel(padapter); 303b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 304b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* todo:cancel other irps */ 305b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_stop\n")); 306b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 307b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 308b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_dev_unload(struct rtw_adapter *padapter) 309b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 310b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_dev_unload\n")); 311b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 312b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->bup) { 313b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("===> rtw_dev_unload\n"); 314b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 315b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bDriverStopped = true; 316b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->xmitpriv.ack_tx) 317b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_ack_tx_done23a(&padapter->xmitpriv, 318b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RTW_SCTX_DONE_DRV_STOP); 319b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 320b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s3. */ 321b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->intf_stop) 322b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->intf_stop(padapter); 323b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 324b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s4. */ 325b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!padapter->pwrctrlpriv.bInternalAutoSuspend) 326fdedd9fab0bc6999d788d658a014842e4c223a68Jes Sorensen flush_workqueue(padapter->cmdpriv.wq); 327b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 328b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s5. */ 329b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!padapter->bSurpriseRemoved) { 330b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_hal_deinit23a(padapter); 331b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bSurpriseRemoved = true; 332b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 333b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bup = false; 334b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 335b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, 336b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("r871x_dev_unload():padapter->bup == false\n")); 337b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 338b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("<=== rtw_dev_unload\n"); 339b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n")); 340b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 341b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 342b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerint rtw_hw_suspend23a(struct rtw_adapter *padapter) 343b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 344b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 345b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = padapter->pnetdev; 34690102edc28162210694b68a422192017e80fcbfdJes Sorensen struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 347b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 348b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((!padapter->bup) || (padapter->bDriverStopped) || 349b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (padapter->bSurpriseRemoved)) { 350b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("padapter->bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n", 351b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bup, padapter->bDriverStopped, 352b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bSurpriseRemoved); 353b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto error_exit; 354b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 355b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 356b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter) { /* system suspend */ 357b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger LeaveAllPowerSaveMode23a(padapter); 358b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 359b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("==> rtw_hw_suspend23a\n"); 360b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger down(&pwrpriv->lock); 361b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bips_processing = true; 362b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* padapter->net_closed = true; */ 363b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s1. */ 364b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetdev) { 365b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_carrier_off(pnetdev); 366b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_tx_stop_all_queues(pnetdev); 367b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 368b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 369b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2. */ 370b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_disassoc_cmd23a(padapter, 500, false); 371b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 372b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-2. indicate disconnect to os */ 373b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* rtw_indicate_disconnect23a(padapter); */ 37490102edc28162210694b68a422192017e80fcbfdJes Sorensen if (check_fwstate(pmlmepriv, _FW_LINKED)) { 37590102edc28162210694b68a422192017e80fcbfdJes Sorensen _clr_fwstate_(pmlmepriv, _FW_LINKED); 376b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 37790102edc28162210694b68a422192017e80fcbfdJes Sorensen rtw_led_control(padapter, LED_CTL_NO_LINK); 378b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 37990102edc28162210694b68a422192017e80fcbfdJes Sorensen rtw_os_indicate_disconnect23a(padapter); 380b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 38190102edc28162210694b68a422192017e80fcbfdJes Sorensen /* donnot enqueue cmd */ 38290102edc28162210694b68a422192017e80fcbfdJes Sorensen rtw_lps_ctrl_wk_cmd23a(padapter, 38390102edc28162210694b68a422192017e80fcbfdJes Sorensen LPS_CTRL_DISCONNECT, 0); 384b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 385b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-3. */ 386b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_free_assoc_resources23a(padapter, 1); 387b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 388b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-4. */ 389528e5c1dc78b9b4429f06d148014c048538019b5Jes Sorensen rtw_free_network_queue23a(padapter); 390b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_ips_dev_unload23a(padapter); 391b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->rf_pwrstate = rf_off; 392b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bips_processing = false; 393b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger up(&pwrpriv->lock); 394b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 395b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto error_exit; 396b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 397b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 398b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingererror_exit: 399b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, failed\n", __func__); 400b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -1; 401b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 402b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 403b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerint rtw_hw_resume23a(struct rtw_adapter *padapter) 404b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 405b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 406b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = padapter->pnetdev; 407b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 408b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter) { /* system resume */ 409b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("==> rtw_hw_resume23a\n"); 410b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger down(&pwrpriv->lock); 411b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bips_processing = true; 412b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_reset_drv_sw23a(padapter); 413b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 414b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pm_netdev_open23a(pnetdev, false)) { 415b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger up(&pwrpriv->lock); 416b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto error_exit; 417b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 418b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 419b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_device_attach(pnetdev); 420b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_carrier_on(pnetdev); 421b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 422b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!rtw_netif_queue_stopped(pnetdev)) 423b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_tx_start_all_queues(pnetdev); 424b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 425b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_tx_wake_all_queues(pnetdev); 426b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 427b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bkeepfwalive = false; 428b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->brfoffbyhw = false; 429b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 430b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->rf_pwrstate = rf_on; 431b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bips_processing = false; 432b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 433b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger up(&pwrpriv->lock); 434b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 435b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto error_exit; 436b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 437b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 438b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingererror_exit: 439b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, Open net dev failed\n", __func__); 440b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -1; 441b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 442b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 443b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) 444b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 445b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); 446b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = dvobj->if1; 447b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = padapter->pnetdev; 448b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 449b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 450b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 451b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned long start_time = jiffies; 452b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 453b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("==> %s (%s:%d)\n", __func__, current->comm, current->pid); 454b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 455b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((!padapter->bup) || (padapter->bDriverStopped) || 456b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (padapter->bSurpriseRemoved)) { 457b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("padapter->bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n", 458b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bup, padapter->bDriverStopped, 459b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bSurpriseRemoved); 460b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 461b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 462b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bInSuspend = true; 463b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cancel_all_timer23a(padapter); 464b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger LeaveAllPowerSaveMode23a(padapter); 465b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 466b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger down(&pwrpriv->lock); 467b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* padapter->net_closed = true; */ 468b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s1. */ 469b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetdev) { 470b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_carrier_off(pnetdev); 471b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_tx_stop_all_queues(pnetdev); 472b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 473b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 474b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2. */ 475b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_disassoc_cmd23a(padapter, 0, false); 476b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 477b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && 478b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger check_fwstate(pmlmepriv, _FW_LINKED)) { 479b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n", 480b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__, __LINE__, 481b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->cur_network.network.Ssid.ssid, 482b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->cur_network.network.MacAddress, 483b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->cur_network.network.Ssid.ssid_len, 484b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_ssid.ssid_len); 485b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 486b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_set_roaming(padapter, 1); 487b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 488b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-2. indicate disconnect to os */ 489b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_indicate_disconnect23a(padapter); 490b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-3. */ 491b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_free_assoc_resources23a(padapter, 1); 492b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* s2-4. */ 493528e5c1dc78b9b4429f06d148014c048538019b5Jes Sorensen rtw_free_network_queue23a(padapter); 494b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 495b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_dev_unload(padapter); 496b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger up(&pwrpriv->lock); 497b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 498b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) 499810c832f5d9b99cec69b3dcb763c8c35215abf94Jes Sorensen rtw_cfg80211_indicate_scan_done( 500810c832f5d9b99cec69b3dcb763c8c35215abf94Jes Sorensen wdev_to_priv(padapter->rtw_wdev), true); 501b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 502b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) 503b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_indicate_disconnect23a(padapter); 504b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 505b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 506b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("<=== %s return %d.............. in %dms\n", __func__, 507b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret, jiffies_to_msecs(jiffies - start_time)); 508b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 509b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 510b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 511b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 512b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_resume(struct usb_interface *pusb_intf) 513b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 514b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); 515b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = dvobj->if1; 516b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 517b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 518b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 519b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwrpriv->bInternalAutoSuspend) 520b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_resume_process23a(padapter); 521b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 522b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_resume_process23a(padapter); 523b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 524b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 525b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 526b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 527b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerint rtw_resume_process23a(struct rtw_adapter *padapter) 528b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 529b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev; 530b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pwrctrl_priv *pwrpriv = NULL; 531b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = -1; 532b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned long start_time = jiffies; 533b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 534b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("==> %s (%s:%d)\n", __func__, current->comm, current->pid); 535b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 536b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!padapter) 537b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 538b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetdev = padapter->pnetdev; 539b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv = &padapter->pwrctrlpriv; 540b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 541b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger down(&pwrpriv->lock); 542b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_reset_drv_sw23a(padapter); 543b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bkeepfwalive = false; 544b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 545b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive); 546b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pm_netdev_open23a(pnetdev, true) != 0) 547b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 548b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 549b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_device_attach(pnetdev); 550b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger netif_carrier_on(pnetdev); 551b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 552b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger up(&pwrpriv->lock); 553b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 554b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->pid[1] != 0) { 555b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("pid[1]:%d\n", padapter->pid[1]); 556ce16d2f18944f9ba6cafbc73be20803d848adf78Jes Sorensen kill_pid(find_vpid(padapter->pid[1]), SIGUSR2, 1); 557b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 558b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 559b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw23a_roaming(padapter, NULL); 560b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 561b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = 0; 562b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 563b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwrpriv) 564b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwrpriv->bInSuspend = false; 565b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("<=== %s return %d.............. in %dms\n", __func__, 566b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret, jiffies_to_msecs(jiffies - start_time)); 567b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 568b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 569b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 570b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 571b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger/* 572b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * drv_init() - a device potentially for us 573b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * 574b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * notes: drv_init() is called when the bus driver has located a card 575b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * for us to support. 576b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * We accept the new device by returning 0. 577b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 578b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct rtw_adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, 579b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct usb_interface *pusb_intf, 580b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const struct usb_device_id *pdid) 581b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 582b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = NULL; 583b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = NULL; 584b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int status = _FAIL; 585b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 586b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetdev = rtw_init_netdev23a(padapter); 587b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!pnetdev) 588b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto handle_dualmac; 589b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter = netdev_priv(pnetdev); 590b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 591b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->dvobj = dvobj; 592b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bDriverStopped = true; 593b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj->if1 = padapter; 594b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj->padapters[dvobj->iface_nums++] = padapter; 595b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->iface_id = IFACE_ID0; 596b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 597c174eae6f71bf3da736460e7872cdfc23c854fbcJes Sorensen rtl8723au_set_hw_type(padapter); 598b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 599b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_handle_dualmac23a(padapter, 1) != _SUCCESS) 600b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto free_adapter; 601b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 602b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj)); 603b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 604b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj))) 605b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto handle_dualmac; 606b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6079385d861bddfb451145500ed1375304fa6ccec41Jes Sorensen /* step 2. allocate HalData */ 6089385d861bddfb451145500ed1375304fa6ccec41Jes Sorensen padapter->HalData = kzalloc(sizeof(struct hal_data_8723a), GFP_KERNEL); 6099385d861bddfb451145500ed1375304fa6ccec41Jes Sorensen if (!padapter->HalData) 6109385d861bddfb451145500ed1375304fa6ccec41Jes Sorensen goto free_wdev; 611b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 612b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->intf_start = &usb_intf_start; 613b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->intf_stop = &usb_intf_stop; 614b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6155827c6555ce5edfba003deedc00cc30efca600f7Jes Sorensen rtl8723au_set_intf_ops(padapter); 616b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 617b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* step read_chip_version */ 61844e621c7a6234f5913ba315866712585fe6bc3e4Jes Sorensen rtl8723a_read_chip_version(padapter); 619b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 620b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* step usb endpoint mapping */ 62182ccb5972409fe838dd695ce45b79dc597428a4aJes Sorensen rtl8723au_chip_configure(padapter); 622b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 623b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* step read efuse/eeprom data and get mac_addr */ 6241f4746f1c51a42e4ad2f7316bdc89e67191a053eJes Sorensen rtl8723a_read_adapter_info(padapter); 625b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 626b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* step 5. */ 627b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_init_drv_sw23a(padapter) == _FAIL) { 628b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, 629b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("Initialize driver software resource Failed!\n")); 630b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto free_hal_data; 631b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 632b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 633b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_PM 634b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->pwrctrlpriv.bSupportRemoteWakeup) { 635b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj->pusbdev->do_remote_wakeup = 1; 636b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pusb_intf->needs_remote_wakeup = 1; 637b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger device_init_wakeup(&pusb_intf->dev, 1); 638b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~~~~\n"); 639b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n", 640b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger device_may_wakeup(&pusb_intf->dev)); 641b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 642b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 643b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 2012-07-11 Move here to prevent the 8723AS-VAU BT 644b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * auto suspend influence 645b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 646b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (usb_autopm_get_interface(pusb_intf) < 0) 647b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("can't get autopm:\n"); 648b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_BT_COEXIST 649b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->pwrctrlpriv.autopm_cnt = 1; 650b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 651b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6529d85833d1956c88bd1b19d4df5e3cc5712519a63Jes Sorensen /* If the eeprom mac address is corrupted, assign a random address */ 6539d85833d1956c88bd1b19d4df5e3cc5712519a63Jes Sorensen if (is_broadcast_ether_addr(padapter->eeprompriv.mac_addr) || 6549d85833d1956c88bd1b19d4df5e3cc5712519a63Jes Sorensen is_zero_ether_addr(padapter->eeprompriv.mac_addr)) 6559d85833d1956c88bd1b19d4df5e3cc5712519a63Jes Sorensen eth_random_addr(padapter->eeprompriv.mac_addr); 656b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 657b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n", 658b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bDriverStopped, padapter->bSurpriseRemoved, 659b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->bup, padapter->hw_init_completed 660b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ); 661b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger status = _SUCCESS; 662b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 663b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_hal_data: 664b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS) 665b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(padapter->HalData); 6669385d861bddfb451145500ed1375304fa6ccec41Jes Sorensenfree_wdev: 667b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS) { 668b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev_unregister(padapter->rtw_wdev); 669b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev_free(padapter->rtw_wdev); 670b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 671b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerhandle_dualmac: 672b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS) 673b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_handle_dualmac23a(padapter, 0); 674b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_adapter: 675b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS) { 676b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetdev) 677b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger free_netdev(pnetdev); 678b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter = NULL; 679b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 680b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return padapter; 681b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 682b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 683b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_usb_if1_deinit(struct rtw_adapter *if1) 684b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 685b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = if1->pnetdev; 686b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &if1->mlmepriv; 687b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 688b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_LINKED)) 689b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_disassoc_cmd23a(if1, 0, false); 690b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 691b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 692b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger free_mlme_ap_info23a(if1); 693b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 694b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 695b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetdev) 696b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unregister_netdev(pnetdev); /* will call netdev_close() */ 697b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 698b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cancel_all_timer23a(if1); 699b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 700b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_dev_unload(if1); 701b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 702b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("+r871xu_dev_remove, hw_init_completed =%d\n", 703b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if1->hw_init_completed); 704b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 705b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_handle_dualmac23a(if1, 0); 706b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 707b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (if1->rtw_wdev) { 708b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev_unregister(if1->rtw_wdev); 709b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev_free(if1->rtw_wdev); 710b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 711b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 712b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_BT_COEXIST 713b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (1 == if1->pwrctrlpriv.autopm_cnt) { 714b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_autopm_put_interface(adapter_to_dvobj(if1)->pusbintf); 715b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if1->pwrctrlpriv.autopm_cnt--; 716b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 717b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 718b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 719b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_free_drv_sw23a(if1); 720b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 721b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetdev) 722b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger free_netdev(pnetdev); 723b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 724b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 725b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_drv_init(struct usb_interface *pusb_intf, 726b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const struct usb_device_id *pdid) 727b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 728b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *if1 = NULL; 729b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *dvobj; 730b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int status = _FAIL; 731b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 732b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_init\n")); 733b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 734b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Initialize dvobj_priv */ 735b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj = usb_dvobj_init(pusb_intf); 736b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!dvobj) { 737b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, 738b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("initialize device object priv Failed!\n")); 739b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 740b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 741b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 742b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if1 = rtw_usb_if1_init(dvobj, pusb_intf, pdid); 743b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!if1) { 744b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("rtw_init_primary_adapter Failed!\n"); 745b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto free_dvobj; 746b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 747b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 748b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* dev_alloc_name && register_netdev */ 749b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger status = rtw_drv_register_netdev(if1); 750b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS) 751b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto free_if1; 752b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, 753b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("-871x_drv - drv_init, success!\n")); 754b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 755b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger status = _SUCCESS; 756b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 757b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_if1: 758b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS && if1) 759b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_usb_if1_deinit(if1); 760b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_dvobj: 761b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (status != _SUCCESS) 762b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_dvobj_deinit(pusb_intf); 763b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 764b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return status == _SUCCESS ? 0 : -ENODEV; 765b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 766b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 767b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger/* dev_remove() - our device is being removed */ 768b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_disconnect(struct usb_interface *pusb_intf) 769b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 770b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct dvobj_priv *dvobj; 771b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter; 772b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev; 773b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv; 774b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 775b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dvobj = usb_get_intfdata(pusb_intf); 776b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!dvobj) 777b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 778b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 779b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter = dvobj->if1; 780b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetdev = padapter->pnetdev; 781b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv = &padapter->mlmepriv; 782b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 783b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_set_intfdata(pusb_intf, NULL); 784b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 785b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n")); 786b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 787b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_pm_set_ips23a(padapter, IPS_NONE); 788b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_pm_set_lps23a(padapter, PS_MODE_ACTIVE); 789b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 790b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger LeaveAllPowerSaveMode23a(padapter); 791b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 792b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_usb_if1_deinit(padapter); 793b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 794b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_dvobj_deinit(pusb_intf); 795b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 796b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-dev_remove()\n")); 797b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("-r871xu_dev_remove, done\n"); 798b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 799b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 800b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 801b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 802b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int __init rtw_drv_entry(void) 803b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 804b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_entry\n")); 805b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return usb_register(usb_drv); 806b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 807b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 808b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void __exit rtw_drv_halt(void) 809b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 810b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_halt\n")); 811b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("+rtw_drv_halt\n"); 812b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 813b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger usb_deregister(usb_drv); 814b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 815b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("-rtw_drv_halt\n"); 816b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 817b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 818b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingermodule_init(rtw_drv_entry); 819b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingermodule_exit(rtw_drv_halt); 820