linux/drivers/staging/rtl8188eu/os_dep/usb_intf.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12 * more details.
  13 *
  14 * You should have received a copy of the GNU General Public License along with
  15 * this program; if not, write to the Free Software Foundation, Inc.,
  16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17 *
  18 *
  19 ******************************************************************************/
  20#define _HCI_INTF_C_
  21
  22#include <osdep_service.h>
  23#include <drv_types.h>
  24#include <recv_osdep.h>
  25#include <xmit_osdep.h>
  26#include <hal_intf.h>
  27#include <rtw_version.h>
  28#include <linux/usb.h>
  29#include <osdep_intf.h>
  30
  31#include <usb_vendor_req.h>
  32#include <usb_ops.h>
  33#include <usb_osintf.h>
  34#include <usb_hal.h>
  35#include <rtw_ioctl.h>
  36
  37int ui_pid[3] = {0, 0, 0};
  38
  39static int rtw_suspend(struct usb_interface *intf, pm_message_t message);
  40static int rtw_resume(struct usb_interface *intf);
  41
  42
  43static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid);
  44static void rtw_dev_remove(struct usb_interface *pusb_intf);
  45
  46
  47#define USB_VENDER_ID_REALTEK           0x0bda
  48
  49/* DID_USB_v916_20130116 */
  50static struct usb_device_id rtw_usb_id_tbl[] = {
  51        /*=== Realtek demoboard ===*/
  52        {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8179)}, /* 8188EUS */
  53        {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */
  54        /*=== Customer ID ===*/
  55        /****** 8188EUS ********/
  56        {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */
  57        {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
  58        {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
  59        {}      /* Terminating entry */
  60};
  61
  62MODULE_DEVICE_TABLE(usb, rtw_usb_id_tbl);
  63
  64static struct specific_device_id specific_device_id_tbl[] = {
  65        {}              /* empty table for now */
  66};
  67
  68struct rtw_usb_drv {
  69        struct usb_driver usbdrv;
  70        int drv_registered;
  71        struct mutex hw_init_mutex;
  72};
  73
  74static struct rtw_usb_drv rtl8188e_usb_drv = {
  75        .usbdrv.name = "r8188eu",
  76        .usbdrv.probe = rtw_drv_init,
  77        .usbdrv.disconnect = rtw_dev_remove,
  78        .usbdrv.id_table = rtw_usb_id_tbl,
  79        .usbdrv.suspend =  rtw_suspend,
  80        .usbdrv.resume = rtw_resume,
  81        .usbdrv.reset_resume   = rtw_resume,
  82};
  83
  84static struct rtw_usb_drv *usb_drv = &rtl8188e_usb_drv;
  85
  86static inline int RT_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
  87{
  88        return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN;
  89}
  90
  91static inline int RT_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
  92{
  93        return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT;
  94}
  95
  96static inline int RT_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
  97{
  98        return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT;
  99}
 100
 101static inline int RT_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd)
 102{
 103        return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK;
 104}
 105
 106static inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd)
 107{
 108        return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_in(epd);
 109}
 110
 111static inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd)
 112{
 113        return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_out(epd);
 114}
 115
 116static inline int usb_endpoint_is_int(const struct usb_endpoint_descriptor *epd)
 117{
 118        return RT_usb_endpoint_xfer_int(epd) && RT_usb_endpoint_dir_in(epd);
 119}
 120
 121static inline int RT_usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
 122{
 123        return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 124}
 125
 126static u8 rtw_init_intf_priv(struct dvobj_priv *dvobj)
 127{
 128        u8 rst = _SUCCESS;
 129
 130        mutex_init(&dvobj->usb_vendor_req_mutex);
 131
 132        dvobj->usb_alloc_vendor_req_buf = rtw_zmalloc(MAX_USB_IO_CTL_SIZE);
 133        if (dvobj->usb_alloc_vendor_req_buf == NULL) {
 134                DBG_88E("alloc usb_vendor_req_buf failed... /n");
 135                rst = _FAIL;
 136                goto exit;
 137        }
 138        dvobj->usb_vendor_req_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(dvobj->usb_alloc_vendor_req_buf), ALIGNMENT_UNIT);
 139exit:
 140        return rst;
 141}
 142
 143static u8 rtw_deinit_intf_priv(struct dvobj_priv *dvobj)
 144{
 145        u8 rst = _SUCCESS;
 146
 147        kfree(dvobj->usb_alloc_vendor_req_buf);
 148        mutex_destroy(&dvobj->usb_vendor_req_mutex);
 149        return rst;
 150}
 151
 152static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
 153{
 154        int     i;
 155        int     status = _FAIL;
 156        struct dvobj_priv *pdvobjpriv;
 157        struct usb_host_config          *phost_conf;
 158        struct usb_config_descriptor    *pconf_desc;
 159        struct usb_host_interface       *phost_iface;
 160        struct usb_interface_descriptor *piface_desc;
 161        struct usb_host_endpoint        *phost_endp;
 162        struct usb_endpoint_descriptor  *pendp_desc;
 163        struct usb_device       *pusbd;
 164
 165_func_enter_;
 166
 167        pdvobjpriv = (struct dvobj_priv *)rtw_zmalloc(sizeof(*pdvobjpriv));
 168        if (pdvobjpriv == NULL)
 169                goto exit;
 170
 171        pdvobjpriv->pusbintf = usb_intf;
 172        pusbd = interface_to_usbdev(usb_intf);
 173        pdvobjpriv->pusbdev = pusbd;
 174        usb_set_intfdata(usb_intf, pdvobjpriv);
 175
 176        pdvobjpriv->RtNumInPipes = 0;
 177        pdvobjpriv->RtNumOutPipes = 0;
 178
 179        phost_conf = pusbd->actconfig;
 180        pconf_desc = &phost_conf->desc;
 181
 182        phost_iface = &usb_intf->altsetting[0];
 183        piface_desc = &phost_iface->desc;
 184
 185        pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces;
 186        pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber;
 187        pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
 188
 189        for (i = 0; i < pdvobjpriv->nr_endpoint; i++) {
 190                phost_endp = phost_iface->endpoint + i;
 191                if (phost_endp) {
 192                        pendp_desc = &phost_endp->desc;
 193
 194                        DBG_88E("\nusb_endpoint_descriptor(%d):\n", i);
 195                        DBG_88E("bLength=%x\n", pendp_desc->bLength);
 196                        DBG_88E("bDescriptorType=%x\n",
 197                                pendp_desc->bDescriptorType);
 198                        DBG_88E("bEndpointAddress=%x\n",
 199                                pendp_desc->bEndpointAddress);
 200                        DBG_88E("wMaxPacketSize=%d\n",
 201                                le16_to_cpu(pendp_desc->wMaxPacketSize));
 202                        DBG_88E("bInterval=%x\n", pendp_desc->bInterval);
 203
 204                        if (RT_usb_endpoint_is_bulk_in(pendp_desc)) {
 205                                DBG_88E("RT_usb_endpoint_is_bulk_in = %x\n",
 206                                        RT_usb_endpoint_num(pendp_desc));
 207                                pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = RT_usb_endpoint_num(pendp_desc);
 208                                pdvobjpriv->RtNumInPipes++;
 209                        } else if (usb_endpoint_is_int(pendp_desc)) {
 210                                DBG_88E("usb_endpoint_is_int = %x, Interval = %x\n",
 211                                        RT_usb_endpoint_num(pendp_desc),
 212                                        pendp_desc->bInterval);
 213                                pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = RT_usb_endpoint_num(pendp_desc);
 214                                pdvobjpriv->RtNumInPipes++;
 215                        } else if (RT_usb_endpoint_is_bulk_out(pendp_desc)) {
 216                                DBG_88E("RT_usb_endpoint_is_bulk_out = %x\n",
 217                                        RT_usb_endpoint_num(pendp_desc));
 218                                pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = RT_usb_endpoint_num(pendp_desc);
 219                                pdvobjpriv->RtNumOutPipes++;
 220                        }
 221                        pdvobjpriv->ep_num[i] = RT_usb_endpoint_num(pendp_desc);
 222                }
 223        }
 224
 225        DBG_88E("nr_endpoint=%d, in_num=%d, out_num=%d\n\n",
 226                pdvobjpriv->nr_endpoint, pdvobjpriv->RtNumInPipes,
 227                pdvobjpriv->RtNumOutPipes);
 228
 229        if (pusbd->speed == USB_SPEED_HIGH) {
 230                pdvobjpriv->ishighspeed = true;
 231                DBG_88E("USB_SPEED_HIGH\n");
 232        } else {
 233                pdvobjpriv->ishighspeed = false;
 234                DBG_88E("NON USB_SPEED_HIGH\n");
 235        }
 236
 237        if (rtw_init_intf_priv(pdvobjpriv) == _FAIL) {
 238                RT_TRACE(_module_os_intfs_c_, _drv_err_,
 239                         ("\n Can't INIT rtw_init_intf_priv\n"));
 240                goto free_dvobj;
 241        }
 242
 243        /* 3 misc */
 244        sema_init(&(pdvobjpriv->usb_suspend_sema), 0);
 245        rtw_reset_continual_urb_error(pdvobjpriv);
 246
 247        usb_get_dev(pusbd);
 248
 249        status = _SUCCESS;
 250
 251free_dvobj:
 252        if (status != _SUCCESS && pdvobjpriv) {
 253                usb_set_intfdata(usb_intf, NULL);
 254                kfree(pdvobjpriv);
 255                pdvobjpriv = NULL;
 256        }
 257exit:
 258_func_exit_;
 259        return pdvobjpriv;
 260}
 261
 262static void usb_dvobj_deinit(struct usb_interface *usb_intf)
 263{
 264        struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf);
 265
 266_func_enter_;
 267
 268        usb_set_intfdata(usb_intf, NULL);
 269        if (dvobj) {
 270                /* Modify condition for 92DU DMDP 2010.11.18, by Thomas */
 271                if ((dvobj->NumInterfaces != 2 &&
 272                    dvobj->NumInterfaces != 3) ||
 273                    (dvobj->InterfaceNumber == 1)) {
 274                        if (interface_to_usbdev(usb_intf)->state !=
 275                            USB_STATE_NOTATTACHED) {
 276                                /* If we didn't unplug usb dongle and
 277                                 * remove/insert module, driver fails
 278                                 * on sitesurvey for the first time when
 279                                 * device is up . Reset usb port for sitesurvey
 280                                 * fail issue. */
 281                                DBG_88E("usb attached..., try to reset usb device\n");
 282                                usb_reset_device(interface_to_usbdev(usb_intf));
 283                        }
 284                }
 285                rtw_deinit_intf_priv(dvobj);
 286                kfree(dvobj);
 287        }
 288
 289        usb_put_dev(interface_to_usbdev(usb_intf));
 290
 291_func_exit_;
 292}
 293
 294static void chip_by_usb_id(struct adapter *padapter,
 295                           const struct usb_device_id *pdid)
 296{
 297        padapter->chip_type = NULL_CHIP_TYPE;
 298        hal_set_hw_type(padapter);
 299}
 300
 301static void usb_intf_start(struct adapter *padapter)
 302{
 303        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_start\n"));
 304
 305        rtw_hal_inirp_init(padapter);
 306
 307        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_start\n"));
 308}
 309
 310static void usb_intf_stop(struct adapter *padapter)
 311{
 312        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_stop\n"));
 313
 314        /* disabel_hw_interrupt */
 315        if (!padapter->bSurpriseRemoved) {
 316                /* device still exists, so driver can do i/o operation */
 317                /* TODO: */
 318                RT_TRACE(_module_hci_intfs_c_, _drv_err_,
 319                         ("SurpriseRemoved == false\n"));
 320        }
 321
 322        /* cancel in irp */
 323        rtw_hal_inirp_deinit(padapter);
 324
 325        /* cancel out irp */
 326        rtw_write_port_cancel(padapter);
 327
 328        /* todo:cancel other irps */
 329
 330        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_stop\n"));
 331}
 332
 333static void rtw_dev_unload(struct adapter *padapter)
 334{
 335        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_dev_unload\n"));
 336
 337        if (padapter->bup) {
 338                DBG_88E("===> rtw_dev_unload\n");
 339                padapter->bDriverStopped = true;
 340                if (padapter->xmitpriv.ack_tx)
 341                        rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP);
 342                /* s3. */
 343                if (padapter->intf_stop)
 344                        padapter->intf_stop(padapter);
 345                /* s4. */
 346                if (!padapter->pwrctrlpriv.bInternalAutoSuspend)
 347                        rtw_stop_drv_threads(padapter);
 348
 349                /* s5. */
 350                if (!padapter->bSurpriseRemoved) {
 351                        rtw_hal_deinit(padapter);
 352                        padapter->bSurpriseRemoved = true;
 353                }
 354
 355                padapter->bup = false;
 356        } else {
 357                RT_TRACE(_module_hci_intfs_c_, _drv_err_,
 358                         ("r871x_dev_unload():padapter->bup == false\n"));
 359        }
 360
 361        DBG_88E("<=== rtw_dev_unload\n");
 362
 363        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n"));
 364}
 365
 366static void process_spec_devid(const struct usb_device_id *pdid)
 367{
 368        u16 vid, pid;
 369        u32 flags;
 370        int i;
 371        int num = sizeof(specific_device_id_tbl) /
 372                  sizeof(struct specific_device_id);
 373
 374        for (i = 0; i < num; i++) {
 375                vid = specific_device_id_tbl[i].idVendor;
 376                pid = specific_device_id_tbl[i].idProduct;
 377                flags = specific_device_id_tbl[i].flags;
 378
 379                if ((pdid->idVendor == vid) && (pdid->idProduct == pid) &&
 380                    (flags&SPEC_DEV_ID_DISABLE_HT)) {
 381                        rtw_ht_enable = 0;
 382                        rtw_cbw40_enable = 0;
 383                        rtw_ampdu_enable = 0;
 384                }
 385        }
 386}
 387
 388int rtw_hw_suspend(struct adapter *padapter)
 389{
 390        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
 391        struct net_device *pnetdev = padapter->pnetdev;
 392
 393        _func_enter_;
 394
 395        if ((!padapter->bup) || (padapter->bDriverStopped) ||
 396            (padapter->bSurpriseRemoved)) {
 397                DBG_88E("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n",
 398                        padapter->bup, padapter->bDriverStopped,
 399                        padapter->bSurpriseRemoved);
 400                goto error_exit;
 401        }
 402
 403        if (padapter) { /* system suspend */
 404                LeaveAllPowerSaveMode(padapter);
 405
 406                DBG_88E("==> rtw_hw_suspend\n");
 407                _enter_pwrlock(&pwrpriv->lock);
 408                pwrpriv->bips_processing = true;
 409                /* s1. */
 410                if (pnetdev) {
 411                        netif_carrier_off(pnetdev);
 412                        rtw_netif_stop_queue(pnetdev);
 413                }
 414
 415                /* s2. */
 416                rtw_disassoc_cmd(padapter, 500, false);
 417
 418                /* s2-2.  indicate disconnect to os */
 419                {
 420                        struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
 421
 422                        if (check_fwstate(pmlmepriv, _FW_LINKED)) {
 423                                _clr_fwstate_(pmlmepriv, _FW_LINKED);
 424
 425                                rtw_led_control(padapter, LED_CTL_NO_LINK);
 426
 427                                rtw_os_indicate_disconnect(padapter);
 428
 429                                /* donnot enqueue cmd */
 430                                rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 0);
 431                        }
 432                }
 433                /* s2-3. */
 434                rtw_free_assoc_resources(padapter, 1);
 435
 436                /* s2-4. */
 437                rtw_free_network_queue(padapter, true);
 438                rtw_ips_dev_unload(padapter);
 439                pwrpriv->rf_pwrstate = rf_off;
 440                pwrpriv->bips_processing = false;
 441
 442                _exit_pwrlock(&pwrpriv->lock);
 443        } else {
 444                goto error_exit;
 445        }
 446        _func_exit_;
 447        return 0;
 448
 449error_exit:
 450        DBG_88E("%s, failed\n", __func__);
 451        return -1;
 452}
 453
 454int rtw_hw_resume(struct adapter *padapter)
 455{
 456        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
 457        struct net_device *pnetdev = padapter->pnetdev;
 458
 459        _func_enter_;
 460
 461        if (padapter) { /* system resume */
 462                DBG_88E("==> rtw_hw_resume\n");
 463                _enter_pwrlock(&pwrpriv->lock);
 464                pwrpriv->bips_processing = true;
 465                rtw_reset_drv_sw(padapter);
 466
 467                if (pm_netdev_open(pnetdev, false) != 0) {
 468                        _exit_pwrlock(&pwrpriv->lock);
 469                        goto error_exit;
 470                }
 471
 472                netif_device_attach(pnetdev);
 473                netif_carrier_on(pnetdev);
 474
 475                if (!netif_queue_stopped(pnetdev))
 476                        netif_start_queue(pnetdev);
 477                else
 478                        netif_wake_queue(pnetdev);
 479
 480                pwrpriv->bkeepfwalive = false;
 481                pwrpriv->brfoffbyhw = false;
 482
 483                pwrpriv->rf_pwrstate = rf_on;
 484                pwrpriv->bips_processing = false;
 485
 486                _exit_pwrlock(&pwrpriv->lock);
 487        } else {
 488                goto error_exit;
 489        }
 490
 491        _func_exit_;
 492
 493        return 0;
 494error_exit:
 495        DBG_88E("%s, Open net dev failed\n", __func__);
 496        return -1;
 497}
 498
 499static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message)
 500{
 501        struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
 502        struct adapter *padapter = dvobj->if1;
 503        struct net_device *pnetdev = padapter->pnetdev;
 504        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 505        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
 506
 507        int ret = 0;
 508        u32 start_time = jiffies;
 509
 510        _func_enter_;
 511
 512        DBG_88E("==> %s (%s:%d)\n", __func__, current->comm, current->pid);
 513
 514        if ((!padapter->bup) || (padapter->bDriverStopped) ||
 515            (padapter->bSurpriseRemoved)) {
 516                DBG_88E("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n",
 517                        padapter->bup, padapter->bDriverStopped,
 518                        padapter->bSurpriseRemoved);
 519                goto exit;
 520        }
 521
 522        pwrpriv->bInSuspend = true;
 523        rtw_cancel_all_timer(padapter);
 524        LeaveAllPowerSaveMode(padapter);
 525
 526        _enter_pwrlock(&pwrpriv->lock);
 527        /* s1. */
 528        if (pnetdev) {
 529                netif_carrier_off(pnetdev);
 530                rtw_netif_stop_queue(pnetdev);
 531        }
 532
 533        /* s2. */
 534        rtw_disassoc_cmd(padapter, 0, false);
 535
 536        if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
 537            check_fwstate(pmlmepriv, _FW_LINKED)) {
 538                DBG_88E("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n",
 539                        __func__, __LINE__,
 540                        pmlmepriv->cur_network.network.Ssid.Ssid,
 541                        pmlmepriv->cur_network.network.MacAddress,
 542                        pmlmepriv->cur_network.network.Ssid.SsidLength,
 543                        pmlmepriv->assoc_ssid.SsidLength);
 544
 545                pmlmepriv->to_roaming = 1;
 546        }
 547        /* s2-2.  indicate disconnect to os */
 548        rtw_indicate_disconnect(padapter);
 549        /* s2-3. */
 550        rtw_free_assoc_resources(padapter, 1);
 551        /* s2-4. */
 552        rtw_free_network_queue(padapter, true);
 553
 554        rtw_dev_unload(padapter);
 555        _exit_pwrlock(&pwrpriv->lock);
 556
 557        if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
 558                rtw_indicate_scan_done(padapter, 1);
 559
 560        if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
 561                rtw_indicate_disconnect(padapter);
 562
 563exit:
 564        DBG_88E("<===  %s return %d.............. in %dms\n", __func__
 565                , ret, rtw_get_passing_time_ms(start_time));
 566
 567        _func_exit_;
 568        return ret;
 569}
 570
 571static int rtw_resume(struct usb_interface *pusb_intf)
 572{
 573        struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
 574        struct adapter *padapter = dvobj->if1;
 575        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
 576         int ret = 0;
 577
 578        if (pwrpriv->bInternalAutoSuspend)
 579                ret = rtw_resume_process(padapter);
 580        else
 581                ret = rtw_resume_process(padapter);
 582        return ret;
 583}
 584
 585int rtw_resume_process(struct adapter *padapter)
 586{
 587        struct net_device *pnetdev;
 588        struct pwrctrl_priv *pwrpriv = NULL;
 589        int ret = -1;
 590        u32 start_time = jiffies;
 591        _func_enter_;
 592
 593        DBG_88E("==> %s (%s:%d)\n", __func__, current->comm, current->pid);
 594
 595        if (padapter) {
 596                pnetdev = padapter->pnetdev;
 597                pwrpriv = &padapter->pwrctrlpriv;
 598        } else {
 599                goto exit;
 600        }
 601
 602        _enter_pwrlock(&pwrpriv->lock);
 603        rtw_reset_drv_sw(padapter);
 604        if (pwrpriv)
 605                pwrpriv->bkeepfwalive = false;
 606
 607        DBG_88E("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive);
 608        if (pm_netdev_open(pnetdev, true) != 0)
 609                goto exit;
 610
 611        netif_device_attach(pnetdev);
 612        netif_carrier_on(pnetdev);
 613
 614        _exit_pwrlock(&pwrpriv->lock);
 615
 616        if (padapter->pid[1] != 0) {
 617                DBG_88E("pid[1]:%d\n", padapter->pid[1]);
 618                rtw_signal_process(padapter->pid[1], SIGUSR2);
 619        }
 620
 621        rtw_roaming(padapter, NULL);
 622
 623        ret = 0;
 624exit:
 625        if (pwrpriv)
 626                pwrpriv->bInSuspend = false;
 627        DBG_88E("<===  %s return %d.............. in %dms\n", __func__,
 628                ret, rtw_get_passing_time_ms(start_time));
 629
 630        _func_exit_;
 631
 632        return ret;
 633}
 634
 635/*
 636 * drv_init() - a device potentially for us
 637 *
 638 * notes: drv_init() is called when the bus driver has located
 639 * a card for us to support.
 640 *        We accept the new device by returning 0.
 641 */
 642
 643static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
 644        struct usb_interface *pusb_intf, const struct usb_device_id *pdid)
 645{
 646        struct adapter *padapter = NULL;
 647        struct net_device *pnetdev = NULL;
 648        int status = _FAIL;
 649
 650        padapter = (struct adapter *)rtw_zvmalloc(sizeof(*padapter));
 651        if (padapter == NULL)
 652                goto exit;
 653        padapter->dvobj = dvobj;
 654        dvobj->if1 = padapter;
 655
 656        padapter->bDriverStopped = true;
 657
 658        padapter->hw_init_mutex = &usb_drv->hw_init_mutex;
 659
 660        /* step 1-1., decide the chip_type via vid/pid */
 661        chip_by_usb_id(padapter, pdid);
 662
 663        if (rtw_handle_dualmac(padapter, 1) != _SUCCESS)
 664                goto free_adapter;
 665
 666        pnetdev = rtw_init_netdev(padapter);
 667        if (pnetdev == NULL)
 668                goto handle_dualmac;
 669        SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj));
 670        padapter = rtw_netdev_priv(pnetdev);
 671
 672        /* step 2. hook HalFunc, allocate HalData */
 673        hal_set_hal_ops(padapter);
 674
 675        padapter->intf_start = &usb_intf_start;
 676        padapter->intf_stop = &usb_intf_stop;
 677
 678        /* step init_io_priv */
 679        rtw_init_io_priv(padapter, usb_set_intf_ops);
 680
 681        /* step read_chip_version */
 682        rtw_hal_read_chip_version(padapter);
 683
 684        /* step usb endpoint mapping */
 685        rtw_hal_chip_configure(padapter);
 686
 687        /* step read efuse/eeprom data and get mac_addr */
 688        rtw_hal_read_chip_info(padapter);
 689
 690        /* step 5. */
 691        if (rtw_init_drv_sw(padapter) == _FAIL) {
 692                RT_TRACE(_module_hci_intfs_c_, _drv_err_,
 693                         ("Initialize driver software resource Failed!\n"));
 694                goto free_hal_data;
 695        }
 696
 697#ifdef CONFIG_PM
 698        if (padapter->pwrctrlpriv.bSupportRemoteWakeup) {
 699                dvobj->pusbdev->do_remote_wakeup = 1;
 700                pusb_intf->needs_remote_wakeup = 1;
 701                device_init_wakeup(&pusb_intf->dev, 1);
 702                DBG_88E("\n  padapter->pwrctrlpriv.bSupportRemoteWakeup~~~~~~\n");
 703                DBG_88E("\n  padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n",
 704                        device_may_wakeup(&pusb_intf->dev));
 705        }
 706#endif
 707
 708        /* 2012-07-11 Move here to prevent the 8723AS-VAU BT auto
 709         * suspend influence */
 710        if (usb_autopm_get_interface(pusb_intf) < 0)
 711                        DBG_88E("can't get autopm:\n");
 712
 713        /*  alloc dev name after read efuse. */
 714        rtw_init_netdev_name(pnetdev, padapter->registrypriv.ifname);
 715        rtw_macaddr_cfg(padapter->eeprompriv.mac_addr);
 716#ifdef CONFIG_88EU_P2P
 717        rtw_init_wifidirect_addrs(padapter, padapter->eeprompriv.mac_addr,
 718                                  padapter->eeprompriv.mac_addr);
 719#endif
 720        memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
 721        DBG_88E("MAC Address from pnetdev->dev_addr =  %pM\n",
 722                pnetdev->dev_addr);
 723
 724        /* step 6. Tell the network stack we exist */
 725        if (register_netdev(pnetdev) != 0) {
 726                RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("register_netdev() failed\n"));
 727                goto free_hal_data;
 728        }
 729
 730        DBG_88E("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n"
 731                , padapter->bDriverStopped
 732                , padapter->bSurpriseRemoved
 733                , padapter->bup
 734                , padapter->hw_init_completed
 735        );
 736
 737        status = _SUCCESS;
 738
 739free_hal_data:
 740        if (status != _SUCCESS)
 741                kfree(padapter->HalData);
 742handle_dualmac:
 743        if (status != _SUCCESS)
 744                rtw_handle_dualmac(padapter, 0);
 745free_adapter:
 746        if (status != _SUCCESS) {
 747                if (pnetdev)
 748                        rtw_free_netdev(pnetdev);
 749                else if (padapter)
 750                        rtw_vmfree((u8 *)padapter, sizeof(*padapter));
 751                padapter = NULL;
 752        }
 753exit:
 754        return padapter;
 755}
 756
 757static void rtw_usb_if1_deinit(struct adapter *if1)
 758{
 759        struct net_device *pnetdev = if1->pnetdev;
 760        struct mlme_priv *pmlmepriv = &if1->mlmepriv;
 761
 762        if (check_fwstate(pmlmepriv, _FW_LINKED))
 763                rtw_disassoc_cmd(if1, 0, false);
 764
 765#ifdef CONFIG_88EU_AP_MODE
 766        free_mlme_ap_info(if1);
 767#endif
 768
 769        if (if1->DriverState != DRIVER_DISAPPEAR) {
 770                if (pnetdev) {
 771                        /* will call netdev_close() */
 772                        unregister_netdev(pnetdev);
 773                        rtw_proc_remove_one(pnetdev);
 774                }
 775        }
 776        rtw_cancel_all_timer(if1);
 777
 778        rtw_dev_unload(if1);
 779        DBG_88E("+r871xu_dev_remove, hw_init_completed=%d\n",
 780                if1->hw_init_completed);
 781        rtw_handle_dualmac(if1, 0);
 782        rtw_free_drv_sw(if1);
 783        if (pnetdev)
 784                rtw_free_netdev(pnetdev);
 785}
 786
 787static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid)
 788{
 789        struct adapter *if1 = NULL;
 790        int status;
 791        struct dvobj_priv *dvobj;
 792
 793        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_init\n"));
 794
 795        /* step 0. */
 796        process_spec_devid(pdid);
 797
 798        /* Initialize dvobj_priv */
 799        dvobj = usb_dvobj_init(pusb_intf);
 800        if (dvobj == NULL) {
 801                RT_TRACE(_module_hci_intfs_c_, _drv_err_,
 802                         ("initialize device object priv Failed!\n"));
 803                goto exit;
 804        }
 805
 806        if1 = rtw_usb_if1_init(dvobj, pusb_intf, pdid);
 807        if (if1 == NULL) {
 808                DBG_88E("rtw_init_primarystruct adapter Failed!\n");
 809                goto free_dvobj;
 810        }
 811
 812        if (ui_pid[1] != 0) {
 813                DBG_88E("ui_pid[1]:%d\n", ui_pid[1]);
 814                rtw_signal_process(ui_pid[1], SIGUSR2);
 815        }
 816
 817        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-871x_drv - drv_init, success!\n"));
 818
 819        status = _SUCCESS;
 820
 821        if (status != _SUCCESS && if1)
 822                rtw_usb_if1_deinit(if1);
 823free_dvobj:
 824        if (status != _SUCCESS)
 825                usb_dvobj_deinit(pusb_intf);
 826exit:
 827        return status == _SUCCESS ? 0 : -ENODEV;
 828}
 829
 830/*
 831 * dev_remove() - our device is being removed
 832*/
 833/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() => how to recognize both */
 834static void rtw_dev_remove(struct usb_interface *pusb_intf)
 835{
 836        struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
 837        struct adapter *padapter = dvobj->if1;
 838
 839_func_enter_;
 840
 841        DBG_88E("+rtw_dev_remove\n");
 842        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n"));
 843
 844        if (usb_drv->drv_registered)
 845                padapter->bSurpriseRemoved = true;
 846
 847        rtw_pm_set_ips(padapter, IPS_NONE);
 848        rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
 849
 850        LeaveAllPowerSaveMode(padapter);
 851
 852        rtw_usb_if1_deinit(padapter);
 853
 854        usb_dvobj_deinit(pusb_intf);
 855
 856        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-dev_remove()\n"));
 857        DBG_88E("-r871xu_dev_remove, done\n");
 858_func_exit_;
 859
 860        return;
 861}
 862
 863static int __init rtw_drv_entry(void)
 864{
 865        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_entry\n"));
 866
 867        DBG_88E(DRV_NAME " driver version=%s\n", DRIVERVERSION);
 868
 869        mutex_init(&usb_drv->hw_init_mutex);
 870
 871        usb_drv->drv_registered = true;
 872        return usb_register(&usb_drv->usbdrv);
 873}
 874
 875static void __exit rtw_drv_halt(void)
 876{
 877        RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_halt\n"));
 878        DBG_88E("+rtw_drv_halt\n");
 879
 880        usb_drv->drv_registered = false;
 881        usb_deregister(&usb_drv->usbdrv);
 882
 883        mutex_destroy(&usb_drv->hw_init_mutex);
 884        DBG_88E("-rtw_drv_halt\n");
 885}
 886
 887module_init(rtw_drv_entry);
 888module_exit(rtw_drv_halt);
 889
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.