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