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