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 MODULE_DEVICE_TABLE(usb
, InterfaceUsbtable
);
14 VOID
InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter
)
17 // Wake up the wait_queue...
18 if(psIntfAdapter
->psAdapter
->LEDInfo
.led_thread_running
& BCM_LED_THREAD_RUNNING_ACTIVELY
)
20 psIntfAdapter
->psAdapter
->DriverState
= DRIVER_HALT
;
21 wake_up(&psIntfAdapter
->psAdapter
->LEDInfo
.notify_led_event
);
23 reset_card_proc(psIntfAdapter
->psAdapter
);
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
)
29 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
,"Device is being Accessed \n");
32 /* Free interrupt URB */
33 //psIntfAdapter->psAdapter->device_removed = TRUE;
34 if(psIntfAdapter
->psInterruptUrb
)
36 usb_free_urb(psIntfAdapter
->psInterruptUrb
);
39 /* Free transmit URBs */
40 for(i
= 0; i
< MAXIMUM_USB_TCB
; i
++)
42 if(psIntfAdapter
->asUsbTcb
[i
].urb
!= NULL
)
44 usb_free_urb(psIntfAdapter
->asUsbTcb
[i
].urb
);
45 psIntfAdapter
->asUsbTcb
[i
].urb
= NULL
;
48 /* Free receive URB and buffers */
49 for(i
= 0; i
< MAXIMUM_USB_RCB
; i
++)
51 if (psIntfAdapter
->asUsbRcb
[i
].urb
!= NULL
)
53 bcm_kfree(psIntfAdapter
->asUsbRcb
[i
].urb
->transfer_buffer
);
54 usb_free_urb(psIntfAdapter
->asUsbRcb
[i
].urb
);
55 psIntfAdapter
->asUsbRcb
[i
].urb
= NULL
;
58 AdapterFree(psIntfAdapter
->psAdapter
);
63 static int usbbcm_open(struct inode
*inode
, struct file
*file
)
68 static int usbbcm_release(struct inode
*inode
, struct file
*file
)
73 static ssize_t
usbbcm_read(struct file
*file
, char __user
*buffer
, size_t count
, loff_t
*ppos
)
78 static ssize_t
usbbcm_write(struct file
*file
, const char __user
*user_buffer
, size_t count
, loff_t
*ppos
)
84 VOID
ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter
)
88 // Program EP2 MAX_PKT_SIZE
89 ulReg
= ntohl(EP2_MPS_REG
);
90 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x128,4,TRUE
);
91 ulReg
= ntohl(EP2_MPS
);
92 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x12C,4,TRUE
);
94 ulReg
= ntohl(EP2_CFG_REG
);
95 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x132,4,TRUE
);
96 if(((PS_INTERFACE_ADAPTER
)(Adapter
->pvInterfaceAdapter
))->bHighSpeedDevice
== TRUE
)
98 ulReg
= ntohl(EP2_CFG_INT
);
99 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x136,4,TRUE
);
103 // USE BULK EP as TX in FS mode.
104 ulReg
= ntohl(EP2_CFG_BULK
);
105 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x136,4,TRUE
);
109 // Program EP4 MAX_PKT_SIZE.
110 ulReg
= ntohl(EP4_MPS_REG
);
111 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x13C,4,TRUE
);
112 ulReg
= ntohl(EP4_MPS
);
113 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x140,4,TRUE
);
115 // Program TX EP as interrupt (Alternate Setting)
116 if( rdmalt(Adapter
,0x0F0110F8, (PUINT
)&ulReg
,4))
118 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "reading of Tx EP is failing");
123 ulReg
= ntohl(ulReg
);
124 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1CC,4,TRUE
);
126 ulReg
= ntohl(EP4_CFG_REG
);
127 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1C8,4,TRUE
);
128 // Program ISOCHRONOUS EP size to zero.
129 ulReg
= ntohl(ISO_MPS_REG
);
130 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1D2,4,TRUE
);
131 ulReg
= ntohl(ISO_MPS
);
132 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1D6,4,TRUE
);
134 // Update EEPROM Version.
135 // Read 4 bytes from 508 and modify 511 and 510.
137 ReadBeceemEEPROM(Adapter
,0x1FC,(PUINT
)&ulReg
);
139 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1FC,4,TRUE
);
141 //Update length field if required. Also make the string NULL terminated.
143 ReadBeceemEEPROM(Adapter
,0xA8,(PUINT
)&ulReg
);
144 if((ulReg
&0x00FF0000)>>16 > 0x30)
146 ulReg
= (ulReg
&0xFF00FFFF)|(0x30<<16);
147 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0xA8,4,TRUE
);
149 ReadBeceemEEPROM(Adapter
,0x148,(PUINT
)&ulReg
);
150 if((ulReg
&0x00FF0000)>>16 > 0x30)
152 ulReg
= (ulReg
&0xFF00FFFF)|(0x30<<16);
153 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x148,4,TRUE
);
156 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x122,4,TRUE
);
158 BeceemEEPROMBulkWrite(Adapter
,(PUCHAR
)&ulReg
,0x1C2,4,TRUE
);
162 static struct file_operations usbbcm_fops
= {
164 .release
= usbbcm_release
,
166 .write
= usbbcm_write
,
167 .owner
= THIS_MODULE
,
171 static struct usb_class_driver usbbcm_class
= {
173 .fops
= &usbbcm_fops
,
174 .minor_base
= BCM_USB_MINOR_BASE
,
178 usbbcm_device_probe(struct usb_interface
*intf
, const struct usb_device_id
*id
)
181 PMINI_ADAPTER psAdapter
= NULL
;
182 PS_INTERFACE_ADAPTER psIntfAdapter
= NULL
;
183 struct usb_device
*udev
= NULL
;
185 // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usbbcm probe!!");
186 if((intf
== NULL
) || (id
== NULL
))
188 // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf or id is NULL");
192 /* Allocate Adapter structure */
193 if((psAdapter
= kzalloc(sizeof(MINI_ADAPTER
), GFP_KERNEL
)) == NULL
)
195 BCM_DEBUG_PRINT(psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Out of memory");
199 /* Init default driver debug state */
201 psAdapter
->stDebugState
.debug_level
= DBG_LVL_CURR
;
202 psAdapter
->stDebugState
.type
= DBG_TYPE_INITEXIT
;
203 memset (psAdapter
->stDebugState
.subtype
, 0, sizeof (psAdapter
->stDebugState
.subtype
));
205 /* Technically, one can start using BCM_DEBUG_PRINT after this point.
206 * However, realize that by default the Type/Subtype bitmaps are all zero now;
207 * so no prints will actually appear until the TestApp turns on debug paths via
208 * the ioctl(); so practically speaking, in early init, no logging happens.
210 * A solution (used below): we explicitly set the bitmaps to 1 for Type=DBG_TYPE_INITEXIT
211 * and ALL subtype's of the same. Now all bcm debug statements get logged, enabling debug
213 * Further, we turn this OFF once init_module() completes.
216 psAdapter
->stDebugState
.subtype
[DBG_TYPE_INITEXIT
] = 0xff;
217 BCM_SHOW_DEBUG_BITMAP(psAdapter
);
219 retval
= InitAdapter(psAdapter
);
222 BCM_DEBUG_PRINT (psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "InitAdapter Failed\n");
223 AdapterFree(psAdapter
);
227 /* Allocate interface adapter structure */
228 if((psAdapter
->pvInterfaceAdapter
=
229 kmalloc(sizeof(S_INTERFACE_ADAPTER
), GFP_KERNEL
)) == NULL
)
231 BCM_DEBUG_PRINT(psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Out of memory");
232 AdapterFree (psAdapter
);
235 memset(psAdapter
->pvInterfaceAdapter
, 0, sizeof(S_INTERFACE_ADAPTER
));
237 psIntfAdapter
= InterfaceAdapterGet(psAdapter
);
238 psIntfAdapter
->psAdapter
= psAdapter
;
240 /* Store usb interface in Interface Adapter */
241 psIntfAdapter
->interface
= intf
;
242 usb_set_intfdata(intf
, psIntfAdapter
);
244 BCM_DEBUG_PRINT(psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "psIntfAdapter 0x%p",psIntfAdapter
);
245 retval
= InterfaceAdapterInit(psIntfAdapter
);
248 /* If the Firmware/Cfg File is not present
249 * then return success, let the application
250 * download the files.
252 if(-ENOENT
== retval
){
253 BCM_DEBUG_PRINT(psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "File Not Found, Use App to Download\n");
254 return STATUS_SUCCESS
;
256 BCM_DEBUG_PRINT(psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "InterfaceAdapterInit Failed \n");
257 usb_set_intfdata(intf
, NULL
);
258 udev
= interface_to_usbdev (intf
);
260 if(psAdapter
->bUsbClassDriverRegistered
== TRUE
)
261 usb_deregister_dev (intf
, &usbbcm_class
);
262 InterfaceAdapterFree(psIntfAdapter
);
265 if(psAdapter
->chip_id
> T3
)
267 uint32_t uiNackZeroLengthInt
=4;
268 if(wrmalt(psAdapter
, DISABLE_USB_ZERO_LEN_INT
, &uiNackZeroLengthInt
, sizeof(uiNackZeroLengthInt
)))
274 udev
= interface_to_usbdev (intf
);
275 /* Check whether the USB-Device Supports remote Wake-Up */
276 if(USB_CONFIG_ATT_WAKEUP
& udev
->actconfig
->desc
.bmAttributes
)
278 /* If Suspend then only support dynamic suspend */
279 if(psAdapter
->bDoSuspend
)
282 udev
->autosuspend_delay
= 0;
283 intf
->needs_remote_wakeup
= 1;
284 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
285 udev
->autosuspend_disabled
= 0;
287 usb_enable_autosuspend(udev
);
289 device_init_wakeup(&intf
->dev
,1);
290 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
291 usb_autopm_disable(intf
);
293 INIT_WORK(&psIntfAdapter
->usbSuspendWork
, putUsbSuspend
);
294 BCM_DEBUG_PRINT(psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Enabling USB Auto-Suspend\n");
299 intf
->needs_remote_wakeup
= 0;
300 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
301 udev
->autosuspend_disabled
= 1;
303 usb_disable_autosuspend(udev
);
308 psAdapter
->stDebugState
.subtype
[DBG_TYPE_INITEXIT
] = 0x0;
312 static void usbbcm_disconnect (struct usb_interface
*intf
)
314 PS_INTERFACE_ADAPTER psIntfAdapter
= NULL
;
315 PMINI_ADAPTER psAdapter
= NULL
;
316 struct usb_device
*udev
= NULL
;
317 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
319 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Usb disconnected");
322 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "intf pointer is NULL");
325 psIntfAdapter
= usb_get_intfdata(intf
);
326 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "psIntfAdapter 0x%p",psIntfAdapter
);
327 if(psIntfAdapter
== NULL
)
329 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "InterfaceAdapter pointer is NULL");
332 psAdapter
= psIntfAdapter
->psAdapter
;
333 if(psAdapter
->bDoSuspend
)
334 intf
->needs_remote_wakeup
= 0;
336 psAdapter
->device_removed
= TRUE
;
337 usb_set_intfdata(intf
, NULL
);
338 InterfaceAdapterFree(psIntfAdapter
);
339 udev
= interface_to_usbdev (intf
);
341 usb_deregister_dev (intf
, &usbbcm_class
);
345 static __inline
int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter
)
348 for(i
= 0; i
< MAXIMUM_USB_TCB
; i
++)
350 if((psIntfAdapter
->asUsbTcb
[i
].urb
=
351 usb_alloc_urb(0, GFP_KERNEL
)) == NULL
)
353 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Cant allocate Tx urb for index %d", i
);
358 for(i
= 0; i
< MAXIMUM_USB_RCB
; i
++)
360 if ((psIntfAdapter
->asUsbRcb
[i
].urb
=
361 usb_alloc_urb(0, GFP_KERNEL
)) == NULL
)
363 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Cant allocate Rx urb for index %d", i
);
366 if((psIntfAdapter
->asUsbRcb
[i
].urb
->transfer_buffer
=
367 kmalloc(MAX_DATA_BUFFER_SIZE
, GFP_KERNEL
)) == NULL
)
369 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Cant allocate Rx buffer for index %d", i
);
372 psIntfAdapter
->asUsbRcb
[i
].urb
->transfer_buffer_length
= MAX_DATA_BUFFER_SIZE
;
379 static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter
)
382 UINT status
= STATUS_SUCCESS
;
384 status
= InitCardAndDownloadFirmware(psIntfAdapter
->psAdapter
);
385 if(status
!= STATUS_SUCCESS
)
387 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "InitCardAndDownloadFirmware failed.\n");
390 if(TRUE
== psIntfAdapter
->psAdapter
->fw_download_done
)
393 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Sending first interrupt URB down......");
394 if(StartInterruptUrb(psIntfAdapter
))
396 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Cannot send interrupt in URB");
398 //now register the cntrl interface.
399 //after downloading the f/w waiting for 5 sec to get the mailbox interrupt.
401 psIntfAdapter
->psAdapter
->waiting_to_fw_download_done
= FALSE
;
402 value
= wait_event_timeout(psIntfAdapter
->psAdapter
->ioctl_fw_dnld_wait_queue
,
403 psIntfAdapter
->psAdapter
->waiting_to_fw_download_done
, 5*HZ
);
407 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
,"Mailbox Interrupt has not reached to Driver..");
411 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
,"Got the mailbox interrupt ...Registering control interface...\n ");
413 if(register_control_device_interface(psIntfAdapter
->psAdapter
) < 0)
415 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Register Control Device failed...");
423 static void print_usb_interface_desc(struct usb_interface_descriptor
*usb_intf_desc
)
425 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "**************** INTERFACE DESCRIPTOR *********************");
426 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bLength: %x", usb_intf_desc
->bLength
);
427 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bDescriptorType: %x", usb_intf_desc
->bDescriptorType
);
428 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bInterfaceNumber: %x", usb_intf_desc
->bInterfaceNumber
);
429 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bAlternateSetting: %x", usb_intf_desc
->bAlternateSetting
);
430 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bNumEndpoints: %x", usb_intf_desc
->bNumEndpoints
);
431 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bInterfaceClass: %x", usb_intf_desc
->bInterfaceClass
);
432 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bInterfaceSubClass: %x", usb_intf_desc
->bInterfaceSubClass
);
433 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bInterfaceProtocol: %x", usb_intf_desc
->bInterfaceProtocol
);
434 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "iInterface :%x\n",usb_intf_desc
->iInterface
);
436 static void print_usb_endpoint_descriptor(struct usb_endpoint_descriptor
*usb_ep_desc
)
438 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "**************** ENDPOINT DESCRIPTOR *********************");
439 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bLength :%x ", usb_ep_desc
->bLength
);
440 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bDescriptorType :%x ", usb_ep_desc
->bDescriptorType
);
441 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bEndpointAddress :%x ", usb_ep_desc
->bEndpointAddress
);
442 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bmAttributes :%x ", usb_ep_desc
->bmAttributes
);
443 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "wMaxPacketSize :%x ",usb_ep_desc
->wMaxPacketSize
);
444 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "bInterval :%x ",usb_ep_desc
->bInterval
);
449 static inline int bcm_usb_endpoint_num(const struct usb_endpoint_descriptor
*epd
)
451 return epd
->bEndpointAddress
& USB_ENDPOINT_NUMBER_MASK
;
454 static inline int bcm_usb_endpoint_type(const struct usb_endpoint_descriptor
*epd
)
456 return epd
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
;
459 static inline int bcm_usb_endpoint_dir_in(const struct usb_endpoint_descriptor
*epd
)
461 return ((epd
->bEndpointAddress
& USB_ENDPOINT_DIR_MASK
) == USB_DIR_IN
);
464 static inline int bcm_usb_endpoint_dir_out(const struct usb_endpoint_descriptor
*epd
)
466 return ((epd
->bEndpointAddress
& USB_ENDPOINT_DIR_MASK
) == USB_DIR_OUT
);
469 static inline int bcm_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor
*epd
)
471 return ((epd
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) ==
472 USB_ENDPOINT_XFER_BULK
);
475 static inline int bcm_usb_endpoint_xfer_control(const struct usb_endpoint_descriptor
*epd
)
477 return ((epd
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) ==
478 USB_ENDPOINT_XFER_CONTROL
);
481 static inline int bcm_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor
*epd
)
483 return ((epd
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) ==
484 USB_ENDPOINT_XFER_INT
);
487 static inline int bcm_usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor
*epd
)
489 return ((epd
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) ==
490 USB_ENDPOINT_XFER_ISOC
);
493 static inline int bcm_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor
*epd
)
495 return (bcm_usb_endpoint_xfer_bulk(epd
) && bcm_usb_endpoint_dir_in(epd
));
498 static inline int bcm_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor
*epd
)
500 return (bcm_usb_endpoint_xfer_bulk(epd
) && bcm_usb_endpoint_dir_out(epd
));
503 static inline int bcm_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor
*epd
)
505 return (bcm_usb_endpoint_xfer_int(epd
) && bcm_usb_endpoint_dir_in(epd
));
508 static inline int bcm_usb_endpoint_is_int_out(const struct usb_endpoint_descriptor
*epd
)
510 return (bcm_usb_endpoint_xfer_int(epd
) && bcm_usb_endpoint_dir_out(epd
));
513 static inline int bcm_usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor
*epd
)
515 return (bcm_usb_endpoint_xfer_isoc(epd
) && bcm_usb_endpoint_dir_in(epd
));
518 static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor
*epd
)
520 return (bcm_usb_endpoint_xfer_isoc(epd
) && bcm_usb_endpoint_dir_out(epd
));
523 INT
InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter
)
525 struct usb_host_interface
*iface_desc
;
526 struct usb_endpoint_descriptor
*endpoint
;
530 INT usedIntOutForBulkTransfer
= 0 ;
531 BOOLEAN bBcm16
= FALSE
;
534 /* Store the usb dev into interface adapter */
535 psIntfAdapter
->udev
= usb_get_dev(interface_to_usbdev(
536 psIntfAdapter
->interface
));
538 if((psIntfAdapter
->udev
->speed
== USB_SPEED_HIGH
))
540 psIntfAdapter
->bHighSpeedDevice
= TRUE
;
541 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "MODEM IS CONFIGURED TO HIGH_SPEED ");
545 psIntfAdapter
->bHighSpeedDevice
= FALSE
;
546 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "MODEM IS CONFIGURED TO FULL_SPEED ");
549 psIntfAdapter
->psAdapter
->interface_rdm
= BcmRDM
;
550 psIntfAdapter
->psAdapter
->interface_wrm
= BcmWRM
;
552 if(rdmalt(psIntfAdapter
->psAdapter
, CHIP_ID_REG
, (PUINT
)&(psIntfAdapter
->psAdapter
->chip_id
), sizeof(UINT
)) < 0)
554 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "CHIP ID Read Failed\n");
555 return STATUS_FAILURE
;
557 if(0xbece3200==(psIntfAdapter
->psAdapter
->chip_id
&~(0xF0)))
559 psIntfAdapter
->psAdapter
->chip_id
=(psIntfAdapter
->psAdapter
->chip_id
&~(0xF0));
562 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "First RDM Chip ID 0x%lx\n", psIntfAdapter
->psAdapter
->chip_id
);
564 iface_desc
= psIntfAdapter
->interface
->cur_altsetting
;
565 //print_usb_interface_desc(&(iface_desc->desc));
567 if(psIntfAdapter
->psAdapter
->chip_id
== T3B
)
571 //T3B device will have EEPROM,check if EEPROM is proper and BCM16 can be done or not.
573 BeceemEEPROMBulkRead(psIntfAdapter
->psAdapter
,&uiData
,0x0,4);
578 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
);
581 //selecting alternate setting one as a default setting for High Speed modem.
582 if(psIntfAdapter
->bHighSpeedDevice
)
583 retval
= usb_set_interface(psIntfAdapter
->udev
,DEFAULT_SETTING_0
,ALTERNATE_SETTING_1
);
584 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "BCM16 is Applicable on this dongle");
585 if(retval
|| (psIntfAdapter
->bHighSpeedDevice
== FALSE
))
587 usedIntOutForBulkTransfer
= EP2
;
588 endpoint
= &iface_desc
->endpoint
[EP2
].desc
;
589 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");
591 If Modem is high speed device EP2 should be INT OUT End point
592 If Mode is FS then EP2 should be bulk end point
594 if(((psIntfAdapter
->bHighSpeedDevice
==TRUE
) && (bcm_usb_endpoint_is_int_out(endpoint
)== FALSE
))
595 ||((psIntfAdapter
->bHighSpeedDevice
== FALSE
)&& (bcm_usb_endpoint_is_bulk_out(endpoint
)== FALSE
)))
597 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
,"Configuring the EEPROM ");
598 //change the EP2, EP4 to INT OUT end point
599 ConfigureEndPointTypesThroughEEPROM(psIntfAdapter
->psAdapter
);
602 It resets the device and if any thing gets changed in USB descriptor it will show fail and
603 re-enumerate the device
605 retval
= usb_reset_device(psIntfAdapter
->udev
);
608 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "reset got failed. hence Re-enumerating the device \n");
613 if((psIntfAdapter
->bHighSpeedDevice
== FALSE
) && bcm_usb_endpoint_is_bulk_out(endpoint
))
615 // Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail.
616 UINT _uiData
= ntohl(EP2_CFG_INT
);
617 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
,"Reverting Bulk to INT as it is FS MODE");
618 BeceemEEPROMBulkWrite(psIntfAdapter
->psAdapter
,(PUCHAR
)&_uiData
,0x136,4,TRUE
);
623 usedIntOutForBulkTransfer
= EP4
;
624 endpoint
= &iface_desc
->endpoint
[EP4
].desc
;
625 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Choosing AltSetting as a default setting");
626 if( bcm_usb_endpoint_is_int_out(endpoint
) == FALSE
)
628 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, " Dongle does not have BCM16 Fix");
629 //change the EP2, EP4 to INT OUT end point and use EP4 in altsetting
630 ConfigureEndPointTypesThroughEEPROM(psIntfAdapter
->psAdapter
);
633 It resets the device and if any thing gets changed in USB descriptor it will show fail and
634 re-enumerate the device
636 retval
= usb_reset_device(psIntfAdapter
->udev
);
639 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "reset got failed. hence Re-enumerating the device \n");
648 iface_desc
= psIntfAdapter
->interface
->cur_altsetting
;
649 //print_usb_interface_desc(&(iface_desc->desc));
650 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Current number of endpoints :%x \n", iface_desc
->desc
.bNumEndpoints
);
651 for (value
= 0; value
< iface_desc
->desc
.bNumEndpoints
; ++value
)
653 endpoint
= &iface_desc
->endpoint
[value
].desc
;
654 //print_usb_endpoint_descriptor(endpoint);
656 if (!psIntfAdapter
->sBulkIn
.bulk_in_endpointAddr
&& bcm_usb_endpoint_is_bulk_in(endpoint
))
658 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
659 psIntfAdapter
->sBulkIn
.bulk_in_size
= buffer_size
;
660 psIntfAdapter
->sBulkIn
.bulk_in_endpointAddr
=
661 endpoint
->bEndpointAddress
;
662 psIntfAdapter
->sBulkIn
.bulk_in_pipe
=
663 usb_rcvbulkpipe(psIntfAdapter
->udev
,
664 psIntfAdapter
->sBulkIn
.bulk_in_endpointAddr
);
667 if (!psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
&& bcm_usb_endpoint_is_bulk_out(endpoint
))
670 psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
=
671 endpoint
->bEndpointAddress
;
672 psIntfAdapter
->sBulkOut
.bulk_out_pipe
=
673 usb_sndbulkpipe(psIntfAdapter
->udev
,
674 psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
);
677 if (!psIntfAdapter
->sIntrIn
.int_in_endpointAddr
&& bcm_usb_endpoint_is_int_in(endpoint
))
679 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
680 psIntfAdapter
->sIntrIn
.int_in_size
= buffer_size
;
681 psIntfAdapter
->sIntrIn
.int_in_endpointAddr
=
682 endpoint
->bEndpointAddress
;
683 psIntfAdapter
->sIntrIn
.int_in_interval
= endpoint
->bInterval
;
684 psIntfAdapter
->sIntrIn
.int_in_buffer
=
685 kmalloc(buffer_size
, GFP_KERNEL
);
686 if (!psIntfAdapter
->sIntrIn
.int_in_buffer
) {
687 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Could not allocate interrupt_in_buffer");
690 //psIntfAdapter->sIntrIn.int_in_pipe =
693 if (!psIntfAdapter
->sIntrOut
.int_out_endpointAddr
&& bcm_usb_endpoint_is_int_out(endpoint
))
696 if( !psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
&&
697 (psIntfAdapter
->psAdapter
->chip_id
== T3B
) && (value
== usedIntOutForBulkTransfer
))
699 //use first intout end point as a bulk out end point
700 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
701 psIntfAdapter
->sBulkOut
.bulk_out_size
= buffer_size
;
702 //printk("\nINT OUT Endpoing buffer size :%x endpoint :%x\n", buffer_size, value +1);
703 psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
=
704 endpoint
->bEndpointAddress
;
705 psIntfAdapter
->sBulkOut
.bulk_out_pipe
=
706 usb_sndintpipe(psIntfAdapter
->udev
,
707 psIntfAdapter
->sBulkOut
.bulk_out_endpointAddr
);
708 psIntfAdapter
->sBulkOut
.int_out_interval
= endpoint
->bInterval
;
711 else if(value
== EP6
)
713 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
714 psIntfAdapter
->sIntrOut
.int_out_size
= buffer_size
;
715 psIntfAdapter
->sIntrOut
.int_out_endpointAddr
=
716 endpoint
->bEndpointAddress
;
717 psIntfAdapter
->sIntrOut
.int_out_interval
= endpoint
->bInterval
;
718 psIntfAdapter
->sIntrOut
.int_out_buffer
= kmalloc(buffer_size
,
720 if (!psIntfAdapter
->sIntrOut
.int_out_buffer
)
722 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Could not allocate interrupt_out_buffer");
728 usb_set_intfdata(psIntfAdapter
->interface
, psIntfAdapter
);
729 retval
= usb_register_dev(psIntfAdapter
->interface
, &usbbcm_class
);
732 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "usb register dev failed = %d", retval
);
733 psIntfAdapter
->psAdapter
->bUsbClassDriverRegistered
= FALSE
;
738 psIntfAdapter
->psAdapter
->bUsbClassDriverRegistered
= TRUE
;
739 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "usb dev registered");
742 psIntfAdapter
->psAdapter
->bcm_file_download
= InterfaceFileDownload
;
743 psIntfAdapter
->psAdapter
->bcm_file_readback_from_chip
=
744 InterfaceFileReadbackFromChip
;
745 psIntfAdapter
->psAdapter
->interface_transmit
= InterfaceTransmitPacket
;
747 retval
= CreateInterruptUrb(psIntfAdapter
);
751 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Cannot create interrupt urb");
755 retval
= AllocUsbCb(psIntfAdapter
);
762 retval
= device_run(psIntfAdapter
);
772 static int InterfaceSuspend (struct usb_interface
*intf
, pm_message_t message
)
774 PS_INTERFACE_ADAPTER psIntfAdapter
= usb_get_intfdata(intf
);
775 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "=================================\n");
776 //Bcm_kill_all_URBs(psIntfAdapter);
777 psIntfAdapter
->bSuspended
= TRUE
;
779 if(TRUE
== psIntfAdapter
->bPreparingForBusSuspend
)
781 psIntfAdapter
->bPreparingForBusSuspend
= FALSE
;
783 if(psIntfAdapter
->psAdapter
->LinkStatus
== LINKUP_DONE
)
785 psIntfAdapter
->psAdapter
->IdleMode
= TRUE
;
786 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Host Entered in PMU Idle Mode..");
790 psIntfAdapter
->psAdapter
->bShutStatus
= TRUE
;
791 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_INITEXIT
, DRV_ENTRY
, DBG_LVL_ALL
, "Host Entered in PMU Shutdown Mode..");
794 psIntfAdapter
->psAdapter
->bPreparingForLowPowerMode
= FALSE
;
796 //Signaling the control pkt path
797 wake_up(&psIntfAdapter
->psAdapter
->lowpower_mode_wait_queue
);
802 static 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
);
817 static int InterfacePreReset(struct usb_interface
*intf
)
819 printk("====================>");
820 return STATUS_SUCCESS
;
823 static int InterfacePostReset(struct usb_interface
*intf
)
825 printk("Do Post chip reset setting here if it is required");
826 return STATUS_SUCCESS
;
828 static struct usb_driver usbbcm_driver
= {
830 .probe
= usbbcm_device_probe
,
831 .disconnect
= usbbcm_disconnect
,
832 .suspend
= InterfaceSuspend
,
833 .resume
= InterfaceResume
,
834 .pre_reset
=InterfacePreReset
,
835 .post_reset
=InterfacePostReset
,
836 .id_table
= InterfaceUsbtable
,
837 .supports_autosuspend
= 1,
842 Function: InterfaceInitialize
844 Description: This is the hardware specific initialization Function.
845 Registering the driver with NDIS , other device specific NDIS
846 and hardware initializations are done here.
848 Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
851 Return: BCM_STATUS_SUCCESS - If Initialization of the
852 HW Interface was successful.
853 Other - If an error occured.
855 INT
InterfaceInitialize(void)
857 // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering Usb driver!!");
858 return usb_register(&usbbcm_driver
);
861 INT
InterfaceExit(void)
863 //PMINI_ADAPTER psAdapter = NULL;
866 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Deregistering Usb driver!!");
867 usb_deregister(&usbbcm_driver
);