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