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