3 static 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
) },
12 VOID
InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter
)
15 // Wake up the wait_queue...
16 if(psIntfAdapter
->psAdapter
->LEDInfo
.led_thread_running
& BCM_LED_THREAD_RUNNING_ACTIVELY
)
18 psIntfAdapter
->psAdapter
->DriverState
= DRIVER_HALT
;
19 wake_up(&psIntfAdapter
->psAdapter
->LEDInfo
.notify_led_event
);
21 reset_card_proc(psIntfAdapter
->psAdapter
);
23 //worst case time taken by the RDM/WRM will be 5 sec. will check after every 100 ms
24 //to accertain the device is not being accessed. After this No RDM/WRM should be made.
25 while(psIntfAdapter
->psAdapter
->DeviceAccess
)
27 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
,"Device is being Accessed \n");
30 /* Free interrupt URB */
31 //psIntfAdapter->psAdapter->device_removed = TRUE;
32 if(psIntfAdapter
->psInterruptUrb
)
34 usb_free_urb(psIntfAdapter
->psInterruptUrb
);
37 /* Free transmit URBs */
38 for(i
= 0; i
< MAXIMUM_USB_TCB
; i
++)
40 if(psIntfAdapter
->asUsbTcb
[i
].urb
!= NULL
)
42 usb_free_urb(psIntfAdapter
->asUsbTcb
[i
].urb
);
43 psIntfAdapter
->asUsbTcb
[i
].urb
= NULL
;
46 /* Free receive URB and buffers */
47 for(i
= 0; i
< MAXIMUM_USB_RCB
; i
++)
49 if (psIntfAdapter
->asUsbRcb
[i
].urb
!= NULL
)
51 bcm_kfree(psIntfAdapter
->asUsbRcb
[i
].urb
->transfer_buffer
);
52 usb_free_urb(psIntfAdapter
->asUsbRcb
[i
].urb
);
53 psIntfAdapter
->asUsbRcb
[i
].urb
= NULL
;
56 AdapterFree(psIntfAdapter
->psAdapter
);
61 static int usbbcm_open(struct inode
*inode
, struct file
*file
)
66 static int usbbcm_release(struct inode
*inode
, struct file
*file
)
71 static ssize_t
usbbcm_read(struct file
*file
, char *buffer
, size_t count
, loff_t
*ppos
)
76 static ssize_t
usbbcm_write(struct file
*file
, const char *user_buffer
, size_t count
, loff_t
*ppos
)
82 VOID
ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter
)
86 // Program EP2 MAX_PKT_SIZE
87 ulReg
= ntohl(EP2_MPS_REG
);
88 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x128,4,TRUE
);
89 ulReg
= ntohl(EP2_MPS
);
90 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x12C,4,TRUE
);
92 ulReg
= ntohl(EP2_CFG_REG
);
93 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x132,4,TRUE
);
94 if(((PS_INTERFACE_ADAPTER
)(Adapter
->pvInterfaceAdapter
))->bHighSpeedDevice
== TRUE
)
96 ulReg
= ntohl(EP2_CFG_INT
);
97 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x136,4,TRUE
);
101 // USE BULK EP as TX in FS mode.
102 ulReg
= ntohl(EP2_CFG_BULK
);
103 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x136,4,TRUE
);
107 // Program EP4 MAX_PKT_SIZE.
108 ulReg
= ntohl(EP4_MPS_REG
);
109 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x13C,4,TRUE
);
110 ulReg
= ntohl(EP4_MPS
);
111 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x140,4,TRUE
);
113 // Program TX EP as interrupt (Alternate Setting)
114 if( rdmalt(Adapter
,0x0F0110F8, (PUINT
)&ulReg
,4))
116 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "reading of Tx EP is failing");
121 ulReg
= ntohl(ulReg
);
122 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1CC,4,TRUE
);
124 ulReg
= ntohl(EP4_CFG_REG
);
125 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1C8,4,TRUE
);
126 // Program ISOCHRONOUS EP size to zero.
127 ulReg
= ntohl(ISO_MPS_REG
);
128 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1D2,4,TRUE
);
129 ulReg
= ntohl(ISO_MPS
);
130 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1D6,4,TRUE
);
132 // Update EEPROM Version.
133 // Read 4 bytes from 508 and modify 511 and 510.
135 ReadBeceemEEPROM(Adapter
,0x1FC,(PUINT
)&ulReg
);
137 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1FC,4,TRUE
);
139 //Update length field if required. Also make the string NULL terminated.
141 ReadBeceemEEPROM(Adapter
,0xA8,(PUINT
)&ulReg
);
142 if((ulReg
&0x00FF0000)>>16 > 0x30)
144 ulReg
= (ulReg
&0xFF00FFFF)|(0x30<<16);
145 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0xA8,4,TRUE
);
147 ReadBeceemEEPROM(Adapter
,0x148,(PUINT
)&ulReg
);
148 if((ulReg
&0x00FF0000)>>16 > 0x30)
150 ulReg
= (ulReg
&0xFF00FFFF)|(0x30<<16);
151 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x148,4,TRUE
);
154 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x122,4,TRUE
);
156 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1C2,4,TRUE
);
160 static struct file_operations usbbcm_fops
= {
162 .release
= usbbcm_release
,
164 .write
= usbbcm_write
,
165 .owner
= THIS_MODULE
,
168 static struct usb_class_driver usbbcm_class
= {
170 .fops
= &usbbcm_fops
,
171 .minor_base
= BCM_USB_MINOR_BASE
,
175 usbbcm_device_probe(struct usb_interface
*intf
, const struct usb_device_id
*id
)
178 PMINI_ADAPTER psAdapter
= NULL
;
179 PS_INTERFACE_ADAPTER psIntfAdapter
= NULL
;
180 struct usb_device
*udev
= NULL
;
182 // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usbbcm probe!!");
183 if((intf
== NULL
) || (id
== NULL
))
185 // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf or id is NULL");
189 /* Allocate Adapter structure */
190 if((psAdapter
= kmalloc(sizeof(MINI_ADAPTER
), GFP_KERNEL
)) == NULL
)
192 //BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory");
196 memset(psAdapter
, 0, sizeof(MINI_ADAPTER
));
198 /* Init default driver debug state */
200 psAdapter
->stDebugState
.debug_level
= DBG_LVL_CURR
;
201 psAdapter
->stDebugState
.type
= DBG_TYPE_INITEXIT
;
202 memset (psAdapter
->stDebugState
.subtype
, 0, sizeof (psAdapter
->stDebugState
.subtype
));
204 /* Technically, one can start using BCM_DEBUG_PRINT after this point.
205 * However, realize that by default the Type/Subtype bitmaps are all zero now;
206 * so no prints will actually appear until the TestApp turns on debug paths via
207 * the ioctl(); so practically speaking, in early init, no logging happens.
209 * A solution (used below): we explicitly set the bitmaps to 1 for Type=DBG_TYPE_INITEXIT
210 * and ALL subtype's of the same. Now all bcm debug statements get logged, enabling debug
212 * Further, we turn this OFF once init_module() completes.
215 psAdapter
->stDebugState
.subtype
[DBG_TYPE_INITEXIT
] = 0xff;
216 BCM_SHOW_DEBUG_BITMAP(psAdapter
);
218 retval
= InitAdapter(psAdapter
);
221 BCM_DEBUG_PRINT (psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "InitAdapter Failed\n");
222 AdapterFree(psAdapter
);
226 /* Allocate interface adapter structure */
227 if((psAdapter
->pvInterfaceAdapter
=
228 kmalloc(sizeof(S_INTERFACE_ADAPTER
), GFP_KERNEL
)) == NULL
)
230 BCM_DEBUG_PRINT(psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Out of memory");
231 AdapterFree (psAdapter
);
234 memset(psAdapter
->pvInterfaceAdapter
, 0, sizeof(S_INTERFACE_ADAPTER
));
236 psIntfAdapter
= InterfaceAdapterGet(psAdapter
);
237 psIntfAdapter
->psAdapter
= psAdapter
;
239 /* Store usb interface in Interface Adapter */
240 psIntfAdapter
->interface
= intf
;
241 usb_set_intfdata(intf
, psIntfAdapter
);
243 BCM_DEBUG_PRINT(psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "psIntfAdapter 0x%x",(unsigned int)psIntfAdapter
);
244 retval
= InterfaceAdapterInit(psIntfAdapter
);
247 /* If the Firmware/Cfg File is not present
248 * then return success, let the application
249 * download the files.
251 if(-ENOENT
== retval
){
252 BCM_DEBUG_PRINT(psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "File Not Found, Use App to Download\n");
253 return STATUS_SUCCESS
;
255 BCM_DEBUG_PRINT(psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "InterfaceAdapterInit Failed \n");
256 usb_set_intfdata(intf
, NULL
);
257 udev
= interface_to_usbdev (intf
);
259 if(psAdapter
->bUsbClassDriverRegistered
== TRUE
)
260 usb_deregister_dev (intf
, &usbbcm_class
);
261 InterfaceAdapterFree(psIntfAdapter
);
264 if(psAdapter
->chip_id
> T3
)
266 uint32_t uiNackZeroLengthInt
=4;
267 if(wrmalt(psAdapter
, DISABLE_USB_ZERO_LEN_INT
, &uiNackZeroLengthInt
, sizeof(uiNackZeroLengthInt
)))
273 udev
= interface_to_usbdev (intf
);
274 /* Check whether the USB-Device Supports remote Wake-Up */
275 if(USB_CONFIG_ATT_WAKEUP
& udev
->actconfig
->desc
.bmAttributes
)
277 /* If Suspend then only support dynamic suspend */
278 if(psAdapter
->bDoSuspend
)
280 udev
->autosuspend_delay
= 0;
281 intf
->needs_remote_wakeup
= 1;
282 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
283 udev
->autosuspend_disabled
= 0;
285 usb_enable_autosuspend(udev
);
287 device_init_wakeup(&intf
->dev
,1);
288 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
289 usb_autopm_disable(intf
);
291 INIT_WORK(&psIntfAdapter
->usbSuspendWork
, putUsbSuspend
);
292 BCM_DEBUG_PRINT(psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Enabling USB Auto-Suspend\n");
296 intf
->needs_remote_wakeup
= 0;
297 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
298 udev
->autosuspend_disabled
= 1;
300 usb_disable_autosuspend(udev
);
305 psAdapter
->stDebugState
.subtype
[DBG_TYPE_INITEXIT
] = 0x0;
309 static void usbbcm_disconnect (struct usb_interface
*intf
)
311 PS_INTERFACE_ADAPTER psIntfAdapter
= NULL
;
312 PMINI_ADAPTER psAdapter
= NULL
;
313 struct usb_device
*udev
= NULL
;
314 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
316 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Usb disconnected");
319 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "intf pointer is NULL");
322 psIntfAdapter
= usb_get_intfdata(intf
);
323 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "psIntfAdapter 0x%x",(unsigned int)psIntfAdapter
);
324 if(psIntfAdapter
== NULL
)
326 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "InterfaceAdapter pointer is NULL");
329 psAdapter
= psIntfAdapter
->psAdapter
;
330 if(psAdapter
->bDoSuspend
)
331 intf
->needs_remote_wakeup
= 0;
333 psAdapter
->device_removed
= TRUE
;
334 usb_set_intfdata(intf
, NULL
);
335 InterfaceAdapterFree(psIntfAdapter
);
336 udev
= interface_to_usbdev (intf
);
338 usb_deregister_dev (intf
, &usbbcm_class
);
342 static __inline
int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter
)
345 for(i
= 0; i
< MAXIMUM_USB_TCB
; i
++)
347 if((psIntfAdapter
->asUsbTcb
[i
].urb
=
348 usb_alloc_urb(0, GFP_KERNEL
)) == NULL
)
350 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Cant allocate Tx urb for index %d", i
);
355 for(i
= 0; i
< MAXIMUM_USB_RCB
; i
++)
357 if ((psIntfAdapter
->asUsbRcb
[i
].urb
=
358 usb_alloc_urb(0, GFP_KERNEL
)) == NULL
)
360 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Cant allocate Rx urb for index %d", i
);
363 if((psIntfAdapter
->asUsbRcb
[i
].urb
->transfer_buffer
=
364 kmalloc(MAX_DATA_BUFFER_SIZE
, GFP_KERNEL
)) == NULL
)
366 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Cant allocate Rx buffer for index %d", i
);
369 psIntfAdapter
->asUsbRcb
[i
].urb
->transfer_buffer_length
= MAX_DATA_BUFFER_SIZE
;
376 static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter
)
379 UINT status
= STATUS_SUCCESS
;
381 status
= InitCardAndDownloadFirmware(psIntfAdapter
->psAdapter
);
382 if(status
!= STATUS_SUCCESS
)
384 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "InitCardAndDownloadFirmware failed.\n");
387 if(TRUE
== psIntfAdapter
->psAdapter
->fw_download_done
)
390 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Sending first interrupt URB down......");
391 if(StartInterruptUrb(psIntfAdapter
))
393 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Cannot send interrupt in URB");
395 //now register the cntrl interface.
396 //after downloading the f/w waiting for 5 sec to get the mailbox interrupt.
398 psIntfAdapter
->psAdapter
->waiting_to_fw_download_done
= FALSE
;
399 value
= wait_event_timeout(psIntfAdapter
->psAdapter
->ioctl_fw_dnld_wait_queue
,
400 psIntfAdapter
->psAdapter
->waiting_to_fw_download_done
, 5*HZ
);
404 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
,"Mailbox Interrupt has not reached to Driver..");
408 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
,"Got the mailbox interrupt ...Registering control interface...\n ");
410 if(register_control_device_interface(psIntfAdapter
->psAdapter
) < 0)
412 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Register Control Device failed...");
420 static void print_usb_interface_desc(struct usb_interface_descriptor
*usb_intf_desc
)
422 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "**************** INTERFACE DESCRIPTOR *********************");
423 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bLength: %x", usb_intf_desc
->bLength
);
424 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bDescriptorType: %x", usb_intf_desc
->bDescriptorType
);
425 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bInterfaceNumber: %x", usb_intf_desc
->bInterfaceNumber
);
426 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bAlternateSetting: %x", usb_intf_desc
->bAlternateSetting
);
427 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bNumEndpoints: %x", usb_intf_desc
->bNumEndpoints
);
428 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bInterfaceClass: %x", usb_intf_desc
->bInterfaceClass
);
429 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bInterfaceSubClass: %x", usb_intf_desc
->bInterfaceSubClass
);
430 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bInterfaceProtocol: %x", usb_intf_desc
->bInterfaceProtocol
);
431 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "iInterface :%x\n",usb_intf_desc
->iInterface
);
433 static void print_usb_endpoint_descriptor(struct usb_endpoint_descriptor
*usb_ep_desc
)
435 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "**************** ENDPOINT DESCRIPTOR *********************");
436 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bLength :%x ", usb_ep_desc
->bLength
);
437 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bDescriptorType :%x ", usb_ep_desc
->bDescriptorType
);
438 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bEndpointAddress :%x ", usb_ep_desc
->bEndpointAddress
);
439 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bmAttributes :%x ", usb_ep_desc
->bmAttributes
);
440 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "wMaxPacketSize :%x ",usb_ep_desc
->wMaxPacketSize
);
441 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bInterval :%x ",usb_ep_desc
->bInterval
);
446 static inline int bcm_usb_endpoint_num(const struct usb_endpoint_descriptor
*epd
)
448 return epd
->bEndpointAddress
& USB_ENDPOINT_NUMBER_MASK
;
451 static inline int bcm_usb_endpoint_type(const struct usb_endpoint_descriptor
*epd
)
453 return epd
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
;
456 static inline int bcm_usb_endpoint_dir_in(const struct usb_endpoint_descriptor
*epd
)
458 return ((epd
->bEndpointAddress
& USB_ENDPOINT_DIR_MASK
) == USB_DIR_IN
);
461 static inline int bcm_usb_endpoint_dir_out(const struct usb_endpoint_descriptor
*epd
)
463 return ((epd
->bEndpointAddress
& USB_ENDPOINT_DIR_MASK
) == USB_DIR_OUT
);
466 static inline int bcm_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor
*epd
)
468 return ((epd
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) ==
469 USB_ENDPOINT_XFER_BULK
);
472 static inline int bcm_usb_endpoint_xfer_control(const struct usb_endpoint_descriptor
*epd
)
474 return ((epd
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) ==
475 USB_ENDPOINT_XFER_CONTROL
);
478 static inline int bcm_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor
*epd
)
480 return ((epd
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) ==
481 USB_ENDPOINT_XFER_INT
);
484 static inline int bcm_usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor
*epd
)
486 return ((epd
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) ==
487 USB_ENDPOINT_XFER_ISOC
);
490 static inline int bcm_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor
*epd
)
492 return (bcm_usb_endpoint_xfer_bulk(epd
) && bcm_usb_endpoint_dir_in(epd
));
495 static inline int bcm_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor
*epd
)
497 return (bcm_usb_endpoint_xfer_bulk(epd
) && bcm_usb_endpoint_dir_out(epd
));
500 static inline int bcm_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor
*epd
)
502 return (bcm_usb_endpoint_xfer_int(epd
) && bcm_usb_endpoint_dir_in(epd
));
505 static inline int bcm_usb_endpoint_is_int_out(const struct usb_endpoint_descriptor
*epd
)
507 return (bcm_usb_endpoint_xfer_int(epd
) && bcm_usb_endpoint_dir_out(epd
));
510 static inline int bcm_usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor
*epd
)
512 return (bcm_usb_endpoint_xfer_isoc(epd
) && bcm_usb_endpoint_dir_in(epd
));
515 static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor
*epd
)
517 return (bcm_usb_endpoint_xfer_isoc(epd
) && bcm_usb_endpoint_dir_out(epd
));
520 INT
InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter
)
522 struct usb_host_interface
*iface_desc
;
523 struct usb_endpoint_descriptor
*endpoint
;
527 INT usedIntOutForBulkTransfer
= 0 ;
528 BOOLEAN bBcm16
= FALSE
;
531 if(psIntfAdapter
== NULL
)
533 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Interface Adapter is NULL");
536 /* Store the usb dev into interface adapter */
537 psIntfAdapter
->udev
= usb_get_dev(interface_to_usbdev(
538 psIntfAdapter
->interface
));
540 if((psIntfAdapter
->udev
->speed
== USB_SPEED_HIGH
))
542 psIntfAdapter
->bHighSpeedDevice
= TRUE
;
543 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "MODEM IS CONFIGURED TO HIGH_SPEED ");
547 psIntfAdapter
->bHighSpeedDevice
= FALSE
;
548 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "MODEM IS CONFIGURED TO FULL_SPEED ");
551 psIntfAdapter
->psAdapter
->interface_rdm
= BcmRDM
;
552 psIntfAdapter
->psAdapter
->interface_wrm
= BcmWRM
;
554 if(rdmalt(psIntfAdapter
->psAdapter
, CHIP_ID_REG
, (PUINT
)&(psIntfAdapter
->psAdapter
->chip_id
), sizeof(UINT
)) < 0)
556 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "CHIP ID Read Failed\n");
557 return STATUS_FAILURE
;
559 if(0xbece3200==(psIntfAdapter
->psAdapter
->chip_id
&~(0xF0)))
561 psIntfAdapter
->psAdapter
->chip_id
=(psIntfAdapter
->psAdapter
->chip_id
&~(0xF0));
564 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "First RDM Chip ID 0x%lx\n", psIntfAdapter
->psAdapter
->chip_id
);
566 iface_desc
= psIntfAdapter
->interface
->cur_altsetting
;
567 //print_usb_interface_desc(&(iface_desc->desc));
569 if(psIntfAdapter
->psAdapter
->chip_id
== T3B
)
573 //T3B device will have EEPROM,check if EEPROM is proper and BCM16 can be done or not.
575 BeceemEEPROMBulkRead(psIntfAdapter
->psAdapter
,&uiData
,0x0,4);
580 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
);
583 //selecting alternate setting one as a default setting for High Speed modem.
584 if(psIntfAdapter
->bHighSpeedDevice
)
585 retval
= usb_set_interface(psIntfAdapter
->udev
,DEFAULT_SETTING_0
,ALTERNATE_SETTING_1
);
586 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "BCM16 is Applicable on this dongle");
587 if(retval
|| (psIntfAdapter
->bHighSpeedDevice
== FALSE
))
589 usedIntOutForBulkTransfer
= EP2
;
590 endpoint
= &iface_desc
->endpoint
[EP2
].desc
;
591 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");
593 If Modem is high speed device EP2 should be INT OUT End point
594 If Mode is FS then EP2 should be bulk end point
596 if(((psIntfAdapter
->bHighSpeedDevice
==TRUE
) && (bcm_usb_endpoint_is_int_out(endpoint
)== FALSE
))
597 ||((psIntfAdapter
->bHighSpeedDevice
== FALSE
)&& (bcm_usb_endpoint_is_bulk_out(endpoint
)== FALSE
)))
599 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
,"Configuring the EEPROM ");
600 //change the EP2, EP4 to INT OUT end point
601 ConfigureEndPointTypesThroughEEPROM(psIntfAdapter
->psAdapter
);
604 It resets the device and if any thing gets changed in USB descriptor it will show fail and
605 re-enumerate the device
607 retval
= usb_reset_device(psIntfAdapter
->udev
);
610 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "reset got failed. hence Re-enumerating the device \n");
615 if((psIntfAdapter
->bHighSpeedDevice
== FALSE
) && bcm_usb_endpoint_is_bulk_out(endpoint
))
617 // Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail.
618 UINT uiData
= ntohl(EP2_CFG_INT
);
619 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
,"Reverting Bulk to INT as it is FS MODE");
620 BeceemEEPROMBulkWrite(psIntfAdapter
->psAdapter
,(PUCHAR
)&uiData
,0x136,4,TRUE
);
625 usedIntOutForBulkTransfer
= EP4
;
626 endpoint
= &iface_desc
->endpoint
[EP4
].desc
;
627 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Choosing AltSetting as a default setting");
628 if( bcm_usb_endpoint_is_int_out(endpoint
) == FALSE
)
630 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, " Dongle does not have BCM16 Fix");
631 //change the EP2, EP4 to INT OUT end point and use EP4 in altsetting
632 ConfigureEndPointTypesThroughEEPROM(psIntfAdapter
->psAdapter
);
635 It resets the device and if any thing gets changed in USB descriptor it will show fail and
636 re-enumerate the device
638 retval
= usb_reset_device(psIntfAdapter
->udev
);
641 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "reset got failed. hence Re-enumerating the device \n");
650 iface_desc
= psIntfAdapter
->interface
->cur_altsetting
;
651 //print_usb_interface_desc(&(iface_desc->desc));
652 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Current number of endpoints :%x \n", iface_desc
->desc
.bNumEndpoints
);
653 for (value
= 0; value
< iface_desc
->desc
.bNumEndpoints
; ++value
)
655 endpoint
= &iface_desc
->endpoint
[value
].desc
;
656 //print_usb_endpoint_descriptor(endpoint);
658 if (!psIntfAdapter
->sBulkIn
.bulk_in_endpointAddr
&& bcm_usb_endpoint_is_bulk_in(endpoint
))
660 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
661 psIntfAdapter
->sBulkIn
.bulk_in_size
= buffer_size
;
662 psIntfAdapter
->sBulkIn
.bulk_in_endpointAddr
=
663 endpoint
->bEndpointAddress
;
664 psIntfAdapter
->sBulkIn
.bulk_in_pipe
=
665 usb_rcvbulkpipe(psIntfAdapter
->udev
,
666 psIntfAdapter
->sBulkIn
.bulk_in_endpointAddr
);
669 if (!psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
&& bcm_usb_endpoint_is_bulk_out(endpoint
))
672 psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
=
673 endpoint
->bEndpointAddress
;
674 psIntfAdapter
->sBulkOut
.bulk_out_pipe
=
675 usb_sndbulkpipe(psIntfAdapter
->udev
,
676 psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
);
679 if (!psIntfAdapter
->sIntrIn
.int_in_endpointAddr
&& bcm_usb_endpoint_is_int_in(endpoint
))
681 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
682 psIntfAdapter
->sIntrIn
.int_in_size
= buffer_size
;
683 psIntfAdapter
->sIntrIn
.int_in_endpointAddr
=
684 endpoint
->bEndpointAddress
;
685 psIntfAdapter
->sIntrIn
.int_in_interval
= endpoint
->bInterval
;
686 psIntfAdapter
->sIntrIn
.int_in_buffer
=
687 kmalloc(buffer_size
, GFP_KERNEL
);
688 if (!psIntfAdapter
->sIntrIn
.int_in_buffer
) {
689 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Could not allocate interrupt_in_buffer");
692 //psIntfAdapter->sIntrIn.int_in_pipe =
695 if (!psIntfAdapter
->sIntrOut
.int_out_endpointAddr
&& bcm_usb_endpoint_is_int_out(endpoint
))
698 if( !psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
&&
699 (psIntfAdapter
->psAdapter
->chip_id
== T3B
) && (value
== usedIntOutForBulkTransfer
))
701 //use first intout end point as a bulk out end point
702 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
703 psIntfAdapter
->sBulkOut
.bulk_out_size
= buffer_size
;
704 //printk("\nINT OUT Endpoing buffer size :%x endpoint :%x\n", buffer_size, value +1);
705 psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
=
706 endpoint
->bEndpointAddress
;
707 psIntfAdapter
->sBulkOut
.bulk_out_pipe
=
708 usb_sndintpipe(psIntfAdapter
->udev
,
709 psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
);
710 psIntfAdapter
->sBulkOut
.int_out_interval
= endpoint
->bInterval
;
713 else if(value
== EP6
)
715 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
716 psIntfAdapter
->sIntrOut
.int_out_size
= buffer_size
;
717 psIntfAdapter
->sIntrOut
.int_out_endpointAddr
=
718 endpoint
->bEndpointAddress
;
719 psIntfAdapter
->sIntrOut
.int_out_interval
= endpoint
->bInterval
;
720 psIntfAdapter
->sIntrOut
.int_out_buffer
= kmalloc(buffer_size
,
722 if (!psIntfAdapter
->sIntrOut
.int_out_buffer
)
724 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Could not allocate interrupt_out_buffer");
730 usb_set_intfdata(psIntfAdapter
->interface
, psIntfAdapter
);
731 retval
= usb_register_dev(psIntfAdapter
->interface
, &usbbcm_class
);
734 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "usb register dev failed = %d", retval
);
735 psIntfAdapter
->psAdapter
->bUsbClassDriverRegistered
= FALSE
;
740 psIntfAdapter
->psAdapter
->bUsbClassDriverRegistered
= TRUE
;
741 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "usb dev registered");
744 psIntfAdapter
->psAdapter
->bcm_file_download
= InterfaceFileDownload
;
745 psIntfAdapter
->psAdapter
->bcm_file_readback_from_chip
=
746 InterfaceFileReadbackFromChip
;
747 psIntfAdapter
->psAdapter
->interface_transmit
= InterfaceTransmitPacket
;
749 retval
= CreateInterruptUrb(psIntfAdapter
);
753 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Cannot create interrupt urb");
757 retval
= AllocUsbCb(psIntfAdapter
);
764 retval
= device_run(psIntfAdapter
);
773 int InterfaceSuspend (struct usb_interface
*intf
, pm_message_t message
)
775 PS_INTERFACE_ADAPTER psIntfAdapter
= usb_get_intfdata(intf
);
776 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "=================================\n");
777 //Bcm_kill_all_URBs(psIntfAdapter);
778 psIntfAdapter
->bSuspended
= TRUE
;
780 if(TRUE
== psIntfAdapter
->bPreparingForBusSuspend
)
782 psIntfAdapter
->bPreparingForBusSuspend
= FALSE
;
784 if(psIntfAdapter
->psAdapter
->LinkStatus
== LINKUP_DONE
)
786 psIntfAdapter
->psAdapter
->IdleMode
= TRUE
;
787 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Host Entered in PMU Idle Mode..");
791 psIntfAdapter
->psAdapter
->bShutStatus
= TRUE
;
792 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Host Entered in PMU Shutdown Mode..");
795 psIntfAdapter
->psAdapter
->bPreparingForLowPowerMode
= FALSE
;
797 //Signaling the control pkt path
798 wake_up(&psIntfAdapter
->psAdapter
->lowpower_mode_wait_queue
);
802 int InterfaceResume (struct usb_interface
*intf
)
804 PS_INTERFACE_ADAPTER psIntfAdapter
= usb_get_intfdata(intf
);
805 printk("=================================\n");
807 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
808 intf
->pm_usage_cnt
=1 ;
810 psIntfAdapter
->bSuspended
= FALSE
;
812 StartInterruptUrb(psIntfAdapter
);
813 InterfaceRx(psIntfAdapter
);
816 int InterfacePreReset(struct usb_interface
*intf
)
818 printk("====================>");
819 return STATUS_SUCCESS
;
821 int InterfacePostReset(struct usb_interface
*intf
)
823 printk("Do Post chip reset setting here if it is required");
824 return STATUS_SUCCESS
;
826 static struct usb_driver usbbcm_driver
= {
828 .probe
= usbbcm_device_probe
,
829 .disconnect
= usbbcm_disconnect
,
830 .suspend
= InterfaceSuspend
,
831 .resume
= InterfaceResume
,
832 .pre_reset
=InterfacePreReset
,
833 .post_reset
=InterfacePostReset
,
834 .id_table
= InterfaceUsbtable
,
835 .supports_autosuspend
= 1,
840 Function: InterfaceInitialize
842 Description: This is the hardware specific initialization Function.
843 Registering the driver with NDIS , other device specific NDIS
844 and hardware initializations are done here.
846 Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
849 Return: BCM_STATUS_SUCCESS - If Initialization of the
850 HW Interface was successful.
851 Other - If an error occured.
853 INT
InterfaceInitialize(void)
855 // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering Usb driver!!");
856 return usb_register(&usbbcm_driver
);
859 INT
InterfaceExit(void)
861 //PMINI_ADAPTER psAdapter = NULL;
864 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Deregistering Usb driver!!");
865 usb_deregister(&usbbcm_driver
);
868 MODULE_LICENSE ("GPL");