linux/drivers/staging/bcm/InterfaceInit.c
<<
>>
Prefs
   1#include "headers.h"
   2
   3static struct usb_device_id InterfaceUsbtable[] = {
   4        { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) },
   5        { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) },
   6        { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) },
   7        { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SYM) },
   8        { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) },
   9        { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) },
  10        { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) },
  11        { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_226) },
  12        { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_326) },
  13        { }
  14};
  15MODULE_DEVICE_TABLE(usb, InterfaceUsbtable);
  16
  17static int debug = -1;
  18module_param(debug, uint, 0600);
  19MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
  20
  21static const u32 default_msg =
  22        NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
  23        | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
  24        | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
  25
  26static int InterfaceAdapterInit(struct bcm_interface_adapter *Adapter);
  27
  28static void InterfaceAdapterFree(struct bcm_interface_adapter *psIntfAdapter)
  29{
  30        int i = 0;
  31
  32        /* Wake up the wait_queue... */
  33        if (psIntfAdapter->psAdapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
  34                psIntfAdapter->psAdapter->DriverState = DRIVER_HALT;
  35                wake_up(&psIntfAdapter->psAdapter->LEDInfo.notify_led_event);
  36        }
  37        reset_card_proc(psIntfAdapter->psAdapter);
  38
  39        /*
  40         * worst case time taken by the RDM/WRM will be 5 sec. will check after every 100 ms
  41         * to accertain the device is not being accessed. After this No RDM/WRM should be made.
  42         */
  43        while (psIntfAdapter->psAdapter->DeviceAccess) {
  44                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
  45                        "Device is being accessed.\n");
  46                msleep(100);
  47        }
  48        /* Free interrupt URB */
  49        /* psIntfAdapter->psAdapter->device_removed = TRUE; */
  50        usb_free_urb(psIntfAdapter->psInterruptUrb);
  51
  52        /* Free transmit URBs */
  53        for (i = 0; i < MAXIMUM_USB_TCB; i++) {
  54                if (psIntfAdapter->asUsbTcb[i].urb  != NULL) {
  55                        usb_free_urb(psIntfAdapter->asUsbTcb[i].urb);
  56                        psIntfAdapter->asUsbTcb[i].urb = NULL;
  57                }
  58        }
  59        /* Free receive URB and buffers */
  60        for (i = 0; i < MAXIMUM_USB_RCB; i++) {
  61                if (psIntfAdapter->asUsbRcb[i].urb != NULL) {
  62                        kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer);
  63                        usb_free_urb(psIntfAdapter->asUsbRcb[i].urb);
  64                        psIntfAdapter->asUsbRcb[i].urb = NULL;
  65                }
  66        }
  67        AdapterFree(psIntfAdapter->psAdapter);
  68}
  69
  70static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter)
  71{
  72        unsigned long ulReg = 0;
  73        int bytes;
  74
  75        /* Program EP2 MAX_PKT_SIZE */
  76        ulReg = ntohl(EP2_MPS_REG);
  77        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x128, 4, TRUE);
  78        ulReg = ntohl(EP2_MPS);
  79        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x12C, 4, TRUE);
  80
  81        ulReg = ntohl(EP2_CFG_REG);
  82        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x132, 4, TRUE);
  83        if (((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) {
  84                ulReg = ntohl(EP2_CFG_INT);
  85                BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE);
  86        } else {
  87                /* USE BULK EP as TX in FS mode. */
  88                ulReg = ntohl(EP2_CFG_BULK);
  89                BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE);
  90        }
  91
  92        /* Program EP4 MAX_PKT_SIZE. */
  93        ulReg = ntohl(EP4_MPS_REG);
  94        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x13C, 4, TRUE);
  95        ulReg = ntohl(EP4_MPS);
  96        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x140, 4, TRUE);
  97
  98        /* Program TX EP as interrupt(Alternate Setting) */
  99        bytes = rdmalt(Adapter, 0x0F0110F8, (u32 *)&ulReg, sizeof(u32));
 100        if (bytes < 0) {
 101                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 102                        "reading of Tx EP failed\n");
 103                return;
 104        }
 105        ulReg |= 0x6;
 106
 107        ulReg = ntohl(ulReg);
 108        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1CC, 4, TRUE);
 109
 110        ulReg = ntohl(EP4_CFG_REG);
 111        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C8, 4, TRUE);
 112        /* Program ISOCHRONOUS EP size to zero. */
 113        ulReg = ntohl(ISO_MPS_REG);
 114        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1D2, 4, TRUE);
 115        ulReg = ntohl(ISO_MPS);
 116        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1D6, 4, TRUE);
 117
 118        /*
 119         * Update EEPROM Version.
 120         * Read 4 bytes from 508 and modify 511 and 510.
 121         */
 122        ReadBeceemEEPROM(Adapter, 0x1FC, (PUINT)&ulReg);
 123        ulReg &= 0x0101FFFF;
 124        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1FC, 4, TRUE);
 125
 126        /* Update length field if required. Also make the string NULL terminated. */
 127
 128        ReadBeceemEEPROM(Adapter, 0xA8, (PUINT)&ulReg);
 129        if ((ulReg&0x00FF0000)>>16 > 0x30) {
 130                ulReg = (ulReg&0xFF00FFFF)|(0x30<<16);
 131                BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0xA8, 4, TRUE);
 132        }
 133        ReadBeceemEEPROM(Adapter, 0x148, (PUINT)&ulReg);
 134        if ((ulReg&0x00FF0000)>>16 > 0x30) {
 135                ulReg = (ulReg&0xFF00FFFF)|(0x30<<16);
 136                BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x148, 4, TRUE);
 137        }
 138        ulReg = 0;
 139        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x122, 4, TRUE);
 140        ulReg = 0;
 141        BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C2, 4, TRUE);
 142}
 143
 144static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id)
 145{
 146        struct usb_device *udev = interface_to_usbdev(intf);
 147        int retval;
 148        struct bcm_mini_adapter *psAdapter;
 149        struct bcm_interface_adapter *psIntfAdapter;
 150        struct net_device *ndev;
 151
 152        /* Reserve one extra queue for the bit-bucket */
 153        ndev = alloc_etherdev_mq(sizeof(struct bcm_mini_adapter), NO_OF_QUEUES+1);
 154        if (ndev == NULL) {
 155                dev_err(&udev->dev, DRV_NAME ": no memory for device\n");
 156                return -ENOMEM;
 157        }
 158
 159        SET_NETDEV_DEV(ndev, &intf->dev);
 160
 161        psAdapter = netdev_priv(ndev);
 162        psAdapter->dev = ndev;
 163        psAdapter->msg_enable = netif_msg_init(debug, default_msg);
 164
 165        /* Init default driver debug state */
 166
 167        psAdapter->stDebugState.debug_level = DBG_LVL_CURR;
 168        psAdapter->stDebugState.type = DBG_TYPE_INITEXIT;
 169
 170        /*
 171         * Technically, one can start using BCM_DEBUG_PRINT after this point.
 172         * However, realize that by default the Type/Subtype bitmaps are all zero now;
 173         * so no prints will actually appear until the TestApp turns on debug paths via
 174         * the ioctl(); so practically speaking, in early init, no logging happens.
 175         *
 176         * A solution (used below): we explicitly set the bitmaps to 1 for Type=DBG_TYPE_INITEXIT
 177         * and ALL subtype's of the same. Now all bcm debug statements get logged, enabling debug
 178         * during early init.
 179         * Further, we turn this OFF once init_module() completes.
 180         */
 181
 182        psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xff;
 183        BCM_SHOW_DEBUG_BITMAP(psAdapter);
 184
 185        retval = InitAdapter(psAdapter);
 186        if (retval) {
 187                dev_err(&udev->dev, DRV_NAME ": InitAdapter Failed\n");
 188                AdapterFree(psAdapter);
 189                return retval;
 190        }
 191
 192        /* Allocate interface adapter structure */
 193        psIntfAdapter = kzalloc(sizeof(struct bcm_interface_adapter),
 194                                GFP_KERNEL);
 195        if (psIntfAdapter == NULL) {
 196                AdapterFree(psAdapter);
 197                return -ENOMEM;
 198        }
 199
 200        psAdapter->pvInterfaceAdapter = psIntfAdapter;
 201        psIntfAdapter->psAdapter = psAdapter;
 202
 203        /* Store usb interface in Interface Adapter */
 204        psIntfAdapter->interface = intf;
 205        usb_set_intfdata(intf, psIntfAdapter);
 206
 207        BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 208                "psIntfAdapter 0x%p\n", psIntfAdapter);
 209        retval = InterfaceAdapterInit(psIntfAdapter);
 210        if (retval) {
 211                /* If the Firmware/Cfg File is not present
 212                 * then return success, let the application
 213                 * download the files.
 214                 */
 215                if (-ENOENT == retval) {
 216                        BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 217                                "File Not Found.  Use app to download.\n");
 218                        return STATUS_SUCCESS;
 219                }
 220                BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 221                        "InterfaceAdapterInit failed.\n");
 222                usb_set_intfdata(intf, NULL);
 223                udev = interface_to_usbdev(intf);
 224                usb_put_dev(udev);
 225                InterfaceAdapterFree(psIntfAdapter);
 226                return retval;
 227        }
 228        if (psAdapter->chip_id > T3) {
 229                uint32_t uiNackZeroLengthInt = 4;
 230
 231                retval = wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, &uiNackZeroLengthInt, sizeof(uiNackZeroLengthInt));
 232                if (retval)
 233                        return retval;
 234        }
 235
 236        /* Check whether the USB-Device Supports remote Wake-Up */
 237        if (USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes) {
 238                /* If Suspend then only support dynamic suspend */
 239                if (psAdapter->bDoSuspend) {
 240#ifdef CONFIG_PM
 241                        pm_runtime_set_autosuspend_delay(&udev->dev, 0);
 242                        intf->needs_remote_wakeup = 1;
 243                        usb_enable_autosuspend(udev);
 244                        device_init_wakeup(&intf->dev, 1);
 245                        INIT_WORK(&psIntfAdapter->usbSuspendWork, putUsbSuspend);
 246                        BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 247                                "Enabling USB Auto-Suspend\n");
 248#endif
 249                } else {
 250                        intf->needs_remote_wakeup = 0;
 251                        usb_disable_autosuspend(udev);
 252                }
 253        }
 254
 255        psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0x0;
 256        return retval;
 257}
 258
 259static void usbbcm_disconnect(struct usb_interface *intf)
 260{
 261        struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
 262        struct bcm_mini_adapter *psAdapter;
 263        struct usb_device  *udev = interface_to_usbdev(intf);
 264
 265        if (psIntfAdapter == NULL)
 266                return;
 267
 268        psAdapter = psIntfAdapter->psAdapter;
 269        netif_device_detach(psAdapter->dev);
 270
 271        if (psAdapter->bDoSuspend)
 272                intf->needs_remote_wakeup = 0;
 273
 274        psAdapter->device_removed = TRUE ;
 275        usb_set_intfdata(intf, NULL);
 276        InterfaceAdapterFree(psIntfAdapter);
 277        usb_put_dev(udev);
 278}
 279
 280static int AllocUsbCb(struct bcm_interface_adapter *psIntfAdapter)
 281{
 282        int i = 0;
 283
 284        for (i = 0; i < MAXIMUM_USB_TCB; i++) {
 285                psIntfAdapter->asUsbTcb[i].urb = usb_alloc_urb(0, GFP_KERNEL);
 286
 287                if (psIntfAdapter->asUsbTcb[i].urb == NULL) {
 288                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
 289                                "Can't allocate Tx urb for index %d\n", i);
 290                        return -ENOMEM;
 291                }
 292        }
 293
 294        for (i = 0; i < MAXIMUM_USB_RCB; i++) {
 295                psIntfAdapter->asUsbRcb[i].urb = usb_alloc_urb(0, GFP_KERNEL);
 296
 297                if (psIntfAdapter->asUsbRcb[i].urb == NULL) {
 298                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
 299                                "Can't allocate Rx urb for index %d\n", i);
 300                        return -ENOMEM;
 301                }
 302
 303                psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL);
 304
 305                if (psIntfAdapter->asUsbRcb[i].urb->transfer_buffer == NULL) {
 306                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
 307                                "Can't allocate Rx buffer for index %d\n", i);
 308                        return -ENOMEM;
 309                }
 310                psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length = MAX_DATA_BUFFER_SIZE;
 311        }
 312        return 0;
 313}
 314
 315static int device_run(struct bcm_interface_adapter *psIntfAdapter)
 316{
 317        int value = 0;
 318        UINT status = STATUS_SUCCESS;
 319
 320        status = InitCardAndDownloadFirmware(psIntfAdapter->psAdapter);
 321        if (status != STATUS_SUCCESS) {
 322                pr_err(DRV_NAME "InitCardAndDownloadFirmware failed.\n");
 323                return status;
 324        }
 325        if (TRUE == psIntfAdapter->psAdapter->fw_download_done) {
 326                if (StartInterruptUrb(psIntfAdapter)) {
 327                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 328                        "Cannot send interrupt in URB\n");
 329                }
 330
 331                /*
 332                 * now register the cntrl interface.
 333                 * after downloading the f/w waiting for 5 sec to get the mailbox interrupt.
 334                 */
 335                psIntfAdapter->psAdapter->waiting_to_fw_download_done = FALSE;
 336                value = wait_event_timeout(psIntfAdapter->psAdapter->ioctl_fw_dnld_wait_queue,
 337                                        psIntfAdapter->psAdapter->waiting_to_fw_download_done, 5*HZ);
 338
 339                if (value == 0)
 340                        pr_err(DRV_NAME ": Timeout waiting for mailbox interrupt.\n");
 341
 342                if (register_control_device_interface(psIntfAdapter->psAdapter) < 0) {
 343                        pr_err(DRV_NAME ": Register Control Device failed.\n");
 344                        return -EIO;
 345                }
 346        }
 347        return 0;
 348}
 349
 350
 351static inline int bcm_usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
 352{
 353        return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 354}
 355
 356static inline int bcm_usb_endpoint_type(const struct usb_endpoint_descriptor *epd)
 357{
 358        return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
 359}
 360
 361static inline int bcm_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
 362{
 363        return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
 364}
 365
 366static inline int bcm_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
 367{
 368        return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
 369}
 370
 371static inline int bcm_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd)
 372{
 373        return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
 374                USB_ENDPOINT_XFER_BULK);
 375}
 376
 377static inline int bcm_usb_endpoint_xfer_control(const struct usb_endpoint_descriptor *epd)
 378{
 379        return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
 380                USB_ENDPOINT_XFER_CONTROL);
 381}
 382
 383static inline int bcm_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
 384{
 385        return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
 386                USB_ENDPOINT_XFER_INT);
 387}
 388
 389static inline int bcm_usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd)
 390{
 391        return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
 392                USB_ENDPOINT_XFER_ISOC);
 393}
 394
 395static inline int bcm_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd)
 396{
 397        return bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_in(epd);
 398}
 399
 400static inline int bcm_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd)
 401{
 402        return bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_out(epd);
 403}
 404
 405static inline int bcm_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
 406{
 407        return bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_in(epd);
 408}
 409
 410static inline int bcm_usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd)
 411{
 412        return bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_out(epd);
 413}
 414
 415static inline int bcm_usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd)
 416{
 417        return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_in(epd);
 418}
 419
 420static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd)
 421{
 422        return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd);
 423}
 424
 425static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
 426{
 427        struct usb_host_interface *iface_desc;
 428        struct usb_endpoint_descriptor *endpoint;
 429        size_t buffer_size;
 430        unsigned long value;
 431        int retval = 0;
 432        int usedIntOutForBulkTransfer = 0 ;
 433        BOOLEAN bBcm16 = FALSE;
 434        UINT uiData = 0;
 435        int bytes;
 436
 437        /* Store the usb dev into interface adapter */
 438        psIntfAdapter->udev = usb_get_dev(interface_to_usbdev(psIntfAdapter->interface));
 439
 440        psIntfAdapter->bHighSpeedDevice = (psIntfAdapter->udev->speed == USB_SPEED_HIGH);
 441        psIntfAdapter->psAdapter->interface_rdm = BcmRDM;
 442        psIntfAdapter->psAdapter->interface_wrm = BcmWRM;
 443
 444        bytes = rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG,
 445                        (u32 *)&(psIntfAdapter->psAdapter->chip_id), sizeof(u32));
 446        if (bytes < 0) {
 447                retval = bytes;
 448                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "CHIP ID Read Failed\n");
 449                return retval;
 450        }
 451
 452        if (0xbece3200 == (psIntfAdapter->psAdapter->chip_id & ~(0xF0)))
 453                psIntfAdapter->psAdapter->chip_id &= ~0xF0;
 454
 455        dev_info(&psIntfAdapter->udev->dev, "RDM Chip ID 0x%lx\n",
 456                 psIntfAdapter->psAdapter->chip_id);
 457
 458        iface_desc = psIntfAdapter->interface->cur_altsetting;
 459
 460        if (psIntfAdapter->psAdapter->chip_id == T3B) {
 461                /* T3B device will have EEPROM, check if EEPROM is proper and BCM16 can be done or not. */
 462                BeceemEEPROMBulkRead(psIntfAdapter->psAdapter, &uiData, 0x0, 4);
 463                if (uiData == BECM)
 464                        bBcm16 = TRUE;
 465
 466                dev_info(&psIntfAdapter->udev->dev, "number of alternate setting %d\n",
 467                         psIntfAdapter->interface->num_altsetting);
 468
 469                if (bBcm16 == TRUE) {
 470                        /* selecting alternate setting one as a default setting for High Speed  modem. */
 471                        if (psIntfAdapter->bHighSpeedDevice)
 472                                retval = usb_set_interface(psIntfAdapter->udev, DEFAULT_SETTING_0, ALTERNATE_SETTING_1);
 473                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 474                                "BCM16 is applicable on this dongle\n");
 475                        if (retval || (psIntfAdapter->bHighSpeedDevice == FALSE)) {
 476                                usedIntOutForBulkTransfer = EP2 ;
 477                                endpoint = &iface_desc->endpoint[EP2].desc;
 478                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 479                                         "Interface altsetting failed or modem is configured to Full Speed, hence will work on default setting 0\n");
 480                                /*
 481                                 * If Modem is high speed device EP2 should be INT OUT End point
 482                                 * If Mode is FS then EP2 should be bulk end point
 483                                 */
 484                                if (((psIntfAdapter->bHighSpeedDevice == TRUE) && (bcm_usb_endpoint_is_int_out(endpoint) == FALSE))
 485                                        || ((psIntfAdapter->bHighSpeedDevice == FALSE) && (bcm_usb_endpoint_is_bulk_out(endpoint) == FALSE))) {
 486                                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 487                                                "Configuring the EEPROM\n");
 488                                        /* change the EP2, EP4 to INT OUT end point */
 489                                        ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter);
 490
 491                                        /*
 492                                         * It resets the device and if any thing gets changed
 493                                         *  in USB descriptor it will show fail and re-enumerate
 494                                         * the device
 495                                         */
 496                                        retval = usb_reset_device(psIntfAdapter->udev);
 497                                        if (retval) {
 498                                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 499                                                        "reset failed.  Re-enumerating the device.\n");
 500                                                return retval ;
 501                                        }
 502
 503                                }
 504                                if ((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint)) {
 505                                        /* Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. */
 506                                        UINT _uiData = ntohl(EP2_CFG_INT);
 507                                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 508                                                "Reverting Bulk to INT as it is in Full Speed mode.\n");
 509                                        BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter, (PUCHAR)&_uiData, 0x136, 4, TRUE);
 510                                }
 511                        } else {
 512                                usedIntOutForBulkTransfer = EP4 ;
 513                                endpoint = &iface_desc->endpoint[EP4].desc;
 514                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 515                                        "Choosing AltSetting as a default setting.\n");
 516                                if (bcm_usb_endpoint_is_int_out(endpoint) == FALSE) {
 517                                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 518                                                "Dongle does not have BCM16 Fix.\n");
 519                                        /* change the EP2, EP4 to INT OUT end point and use EP4 in altsetting */
 520                                        ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter);
 521
 522                                        /*
 523                                         * It resets the device and if any thing gets changed in
 524                                         *  USB descriptor it will show fail and re-enumerate the
 525                                         * device
 526                                         */
 527                                        retval = usb_reset_device(psIntfAdapter->udev);
 528                                        if (retval) {
 529                                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 530                                                        "reset failed.  Re-enumerating the device.\n");
 531                                                return retval;
 532                                        }
 533
 534                                }
 535                        }
 536                }
 537        }
 538
 539        iface_desc = psIntfAdapter->interface->cur_altsetting;
 540
 541        for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value) {
 542                endpoint = &iface_desc->endpoint[value].desc;
 543
 544                if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr && bcm_usb_endpoint_is_bulk_in(endpoint)) {
 545                        buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 546                        psIntfAdapter->sBulkIn.bulk_in_size = buffer_size;
 547                        psIntfAdapter->sBulkIn.bulk_in_endpointAddr = endpoint->bEndpointAddress;
 548                        psIntfAdapter->sBulkIn.bulk_in_pipe =
 549                                        usb_rcvbulkpipe(psIntfAdapter->udev,
 550                                                                psIntfAdapter->sBulkIn.bulk_in_endpointAddr);
 551                }
 552
 553                if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && bcm_usb_endpoint_is_bulk_out(endpoint)) {
 554                        psIntfAdapter->sBulkOut.bulk_out_endpointAddr = endpoint->bEndpointAddress;
 555                        psIntfAdapter->sBulkOut.bulk_out_pipe =
 556                                usb_sndbulkpipe(psIntfAdapter->udev,
 557                                        psIntfAdapter->sBulkOut.bulk_out_endpointAddr);
 558                }
 559
 560                if (!psIntfAdapter->sIntrIn.int_in_endpointAddr && bcm_usb_endpoint_is_int_in(endpoint)) {
 561                        buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 562                        psIntfAdapter->sIntrIn.int_in_size = buffer_size;
 563                        psIntfAdapter->sIntrIn.int_in_endpointAddr = endpoint->bEndpointAddress;
 564                        psIntfAdapter->sIntrIn.int_in_interval = endpoint->bInterval;
 565                        psIntfAdapter->sIntrIn.int_in_buffer =
 566                                                kmalloc(buffer_size, GFP_KERNEL);
 567                        if (!psIntfAdapter->sIntrIn.int_in_buffer)
 568                                return -EINVAL;
 569                }
 570
 571                if (!psIntfAdapter->sIntrOut.int_out_endpointAddr && bcm_usb_endpoint_is_int_out(endpoint)) {
 572                        if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr &&
 573                                (psIntfAdapter->psAdapter->chip_id == T3B) && (value == usedIntOutForBulkTransfer)) {
 574                                /* use first intout end point as a bulk out end point */
 575                                buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 576                                psIntfAdapter->sBulkOut.bulk_out_size = buffer_size;
 577                                psIntfAdapter->sBulkOut.bulk_out_endpointAddr = endpoint->bEndpointAddress;
 578                                psIntfAdapter->sBulkOut.bulk_out_pipe = usb_sndintpipe(psIntfAdapter->udev,
 579                                                                        psIntfAdapter->sBulkOut.bulk_out_endpointAddr);
 580                                psIntfAdapter->sBulkOut.int_out_interval = endpoint->bInterval;
 581                        } else if (value == EP6) {
 582                                buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 583                                psIntfAdapter->sIntrOut.int_out_size = buffer_size;
 584                                psIntfAdapter->sIntrOut.int_out_endpointAddr = endpoint->bEndpointAddress;
 585                                psIntfAdapter->sIntrOut.int_out_interval = endpoint->bInterval;
 586                                psIntfAdapter->sIntrOut.int_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
 587                                if (!psIntfAdapter->sIntrOut.int_out_buffer)
 588                                        return -EINVAL;
 589                        }
 590                }
 591        }
 592
 593        usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter);
 594
 595        psIntfAdapter->psAdapter->bcm_file_download = InterfaceFileDownload;
 596        psIntfAdapter->psAdapter->bcm_file_readback_from_chip =
 597                                InterfaceFileReadbackFromChip;
 598        psIntfAdapter->psAdapter->interface_transmit = InterfaceTransmitPacket;
 599
 600        retval = CreateInterruptUrb(psIntfAdapter);
 601
 602        if (retval) {
 603                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
 604                        "Cannot create interrupt urb\n");
 605                return retval;
 606        }
 607
 608        retval = AllocUsbCb(psIntfAdapter);
 609        if (retval)
 610                return retval;
 611
 612        return device_run(psIntfAdapter);
 613}
 614
 615static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message)
 616{
 617        struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
 618
 619        psIntfAdapter->bSuspended = TRUE;
 620
 621        if (TRUE == psIntfAdapter->bPreparingForBusSuspend) {
 622                psIntfAdapter->bPreparingForBusSuspend = FALSE;
 623
 624                if (psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) {
 625                        psIntfAdapter->psAdapter->IdleMode = TRUE ;
 626                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 627                                "Host Entered in PMU Idle Mode.\n");
 628                } else {
 629                        psIntfAdapter->psAdapter->bShutStatus = TRUE;
 630                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 631                                "Host Entered in PMU Shutdown Mode.\n");
 632                }
 633        }
 634        psIntfAdapter->psAdapter->bPreparingForLowPowerMode = FALSE;
 635
 636        /* Signaling the control pkt path */
 637        wake_up(&psIntfAdapter->psAdapter->lowpower_mode_wait_queue);
 638
 639        return 0;
 640}
 641
 642static int InterfaceResume(struct usb_interface *intf)
 643{
 644        struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
 645
 646        mdelay(100);
 647        psIntfAdapter->bSuspended = FALSE;
 648
 649        StartInterruptUrb(psIntfAdapter);
 650        InterfaceRx(psIntfAdapter);
 651        return 0;
 652}
 653
 654static struct usb_driver usbbcm_driver = {
 655        .name = "usbbcm",
 656        .probe = usbbcm_device_probe,
 657        .disconnect = usbbcm_disconnect,
 658        .suspend = InterfaceSuspend,
 659        .resume = InterfaceResume,
 660        .id_table = InterfaceUsbtable,
 661        .supports_autosuspend = 1,
 662};
 663
 664struct class *bcm_class;
 665
 666static __init int bcm_init(void)
 667{
 668        int retval;
 669
 670        pr_info("%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION);
 671        pr_info("%s\n", DRV_COPYRIGHT);
 672
 673        bcm_class = class_create(THIS_MODULE, DRV_NAME);
 674        if (IS_ERR(bcm_class)) {
 675                pr_err(DRV_NAME ": could not create class\n");
 676                return PTR_ERR(bcm_class);
 677        }
 678
 679        retval = usb_register(&usbbcm_driver);
 680        if (retval < 0) {
 681                pr_err(DRV_NAME ": could not register usb driver\n");
 682                class_destroy(bcm_class);
 683                return retval;
 684        }
 685        return 0;
 686}
 687
 688static __exit void bcm_exit(void)
 689{
 690        usb_deregister(&usbbcm_driver);
 691        class_destroy(bcm_class);
 692}
 693
 694module_init(bcm_init);
 695module_exit(bcm_exit);
 696
 697MODULE_DESCRIPTION(DRV_DESCRIPTION);
 698MODULE_VERSION(DRV_VERSION);
 699MODULE_LICENSE("GPL");
 700