adt3-S dhd_driver source code [1/1]
[GitHub/LineageOS/G12/android_hardware_amlogic_kernel-modules_dhd-driver.git] / bcmdhd-usb.1.201.88.27.x / dbus_usb_linux.c
1 /*
2 * Dongle BUS interface
3 * USB Linux Implementation
4 *
5 * Copyright (C) 1999-2015, Broadcom Corporation
6 *
7 * Unless you and Broadcom execute a separate written software license
8 * agreement governing use of this software, this software is licensed to you
9 * under the terms of the GNU General Public License version 2 (the "GPL"),
10 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
11 * following added to such license:
12 *
13 * As a special exception, the copyright holders of this software give you
14 * permission to link this software with independent modules, and to copy and
15 * distribute the resulting executable under terms of your choice, provided that
16 * you also meet, for each linked independent module, the terms and conditions of
17 * the license of that module. An independent module is a module which is not
18 * derived from this software. The special exception does not apply to any
19 * modifications of the software.
20 *
21 * Notwithstanding the above, under no circumstances may you combine this
22 * software in any way with any other Broadcom software provided under a license
23 * other than the GPL, without Broadcom's express prior written consent.
24 *
25 * $Id: dbus_usb_linux.c 571551 2015-07-15 13:32:46Z $
26 */
27
28 #include <typedefs.h>
29 #include <osl.h>
30
31 /**
32 * DBUS_LINUX_RXDPC is created for router platform performance tuning. A separate thread is created
33 * to handle USB RX and avoid the call chain getting too long and enhance cache hit rate.
34 *
35 * DBUS_LINUX_RXDPC setting is in wlconfig file.
36 */
37
38 /*
39 * If DBUS_LINUX_RXDPC is off, spin_lock_bh() for CTFPOOL in
40 * linux_osl.c has to be changed to spin_lock_irqsave() because
41 * PKTGET/PKTFREE are no longer in bottom half.
42 *
43 * Right now we have another queue rpcq in wl_linux.c. Maybe we
44 * can eliminate that one to reduce the overhead.
45 *
46 * Enabling 2nd EP and DBUS_LINUX_RXDPC causing traffic from
47 * both EP's to be queued in the same rx queue. If we want
48 * RXDPC to work with 2nd EP. The EP for RPC call return
49 * should bypass the dpc and go directly up.
50 */
51
52 /* #define DBUS_LINUX_RXDPC */
53
54 /* Dbus histogram for ntxq, nrxq, dpc parameter tuning */
55 /* #define DBUS_LINUX_HIST */
56
57 #include <usbrdl.h>
58 #include <bcmendian.h>
59 #include <linux/init.h>
60 #include <linux/kernel.h>
61 #include <linux/slab.h>
62 #include <linux/usb.h>
63 #include <linux/skbuff.h>
64 #include <linux/netdevice.h>
65 #include <linux/random.h>
66 #include <linux/spinlock.h>
67 #include <linux/list.h>
68 #include <asm/uaccess.h>
69 #include <asm/unaligned.h>
70 #include <dbus.h>
71 #include <bcmutils.h>
72 #include <bcmdevs.h>
73 #include <linux/usb.h>
74 #include <usbrdl.h>
75 #include <linux/firmware.h>
76 #include <linux/kmod.h>
77 #ifdef DBUS_LINUX_RXDPC
78 #include <linux/sched.h>
79 #endif
80
81 #if defined(BCM_REQUEST_FW)
82 #if !defined(__FreeBSD__)
83 #include <linux/vmalloc.h>
84 #endif /* !defined(__FreeBSD__) */
85 #endif /* defined(BCM_REQUEST_FW) */
86
87 #if defined(USBOS_THREAD) || defined(USBOS_TX_THREAD)
88 /**
89 * The usb-thread is designed to provide currency on multiprocessors and SMP linux kernels. On the
90 * dual cores platform, the WLAN driver, without threads, executed only on CPU0. The driver consumed
91 * almost of 100% on CPU0, while CPU1 remained idle. The behavior was observed on Broadcom's STB.
92 *
93 * The WLAN driver consumed most of CPU0 and not CPU1 because tasklets/queues, software irq, and
94 * hardware irq are executing from CPU0, only. CPU0 became the system's bottle-neck. TPUT is lower
95 * and system's responsiveness is slower.
96 *
97 * To improve system responsiveness and TPUT usb-thread was implemented. The system's threads could
98 * be scheduled to run on any core. One core could be processing data in the usb-layer and the other
99 * core could be processing data in the wl-layer.
100 *
101 * For further info see [WlThreadAndUsbThread] Twiki.
102 */
103
104 #include <linux/kthread.h>
105 #include <linux/interrupt.h>
106 #include <linux/irq.h>
107 #include <asm/hardirq.h>
108 #include <linux/list.h>
109 #include <linux_osl.h>
110 #endif /* USBOS_THREAD || USBOS_TX_THREAD */
111
112 #ifdef DBUS_LINUX_RXDPC
113 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
114 #define RESCHED() _cond_resched()
115 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
116 #define RESCHED() cond_resched()
117 #else
118 #define RESCHED() __cond_resched()
119 #endif /* LINUX_VERSION_CODE */
120 #endif /* DBUS_LINUX_RXDPC */
121
122 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
123 #define KERNEL26
124 #endif
125
126 #define MOD_PARAM_PATHLEN 2048
127 extern char firmware_path[MOD_PARAM_PATHLEN];
128 extern char nvram_path[MOD_PARAM_PATHLEN];
129
130 /* Starting with the 3.10 kernel release, dynamic PM support for USB is present whenever
131 * the kernel was built with CONFIG_PM_RUNTIME enabled. The CONFIG_USB_SUSPEND option has
132 * been eliminated.
133 */
134 #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21)) && defined(CONFIG_USB_SUSPEND)) \
135 || ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) && defined(CONFIG_PM_RUNTIME))
136 /* For USB power management support, see Linux kernel: Documentation/usb/power-management.txt */
137 #define USB_SUSPEND_AVAILABLE
138 #endif
139
140 static inline int usb_submit_urb_linux(struct urb *urb)
141 {
142
143 #ifdef BCM_MAX_URB_LEN
144 if (urb && (urb->transfer_buffer_length > BCM_MAX_URB_LEN)) {
145 DBUSERR(("URB transfer length=%d exceeded %d ra=%p\n", urb->transfer_buffer_length,
146 BCM_MAX_URB_LEN, __builtin_return_address(0)));
147 return DBUS_ERR;
148 }
149 #endif
150
151 #ifdef KERNEL26
152 return usb_submit_urb(urb, GFP_ATOMIC);
153 #else
154 return usb_submit_urb(urb);
155 #endif
156
157 }
158
159 #define USB_SUBMIT_URB(urb) usb_submit_urb_linux(urb)
160
161 #ifdef KERNEL26
162
163 #define USB_ALLOC_URB() usb_alloc_urb(0, GFP_ATOMIC)
164 #define USB_UNLINK_URB(urb) (usb_kill_urb(urb))
165 #define USB_FREE_URB(urb) (usb_free_urb(urb))
166 #define USB_REGISTER() usb_register(&dbus_usbdev)
167 #define USB_DEREGISTER() usb_deregister(&dbus_usbdev)
168
169 #ifdef USB_SUSPEND_AVAILABLE
170
171 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33))
172 #define USB_AUTOPM_SET_INTERFACE(intf) usb_autopm_set_interface(intf)
173 #else
174 #define USB_ENABLE_AUTOSUSPEND(udev) usb_enable_autosuspend(udev)
175 #define USB_DISABLE_AUTOSUSPEND(udev) usb_disable_autosuspend(udev)
176 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) */
177
178 #define USB_AUTOPM_GET_INTERFACE(intf) usb_autopm_get_interface(intf)
179 #define USB_AUTOPM_GET_INTERFACE_ASYNC(intf) usb_autopm_get_interface_async(intf)
180 #define USB_AUTOPM_PUT_INTERFACE_ASYNC(intf) usb_autopm_put_interface_async(intf)
181 #define USB_MARK_LAST_BUSY(dev) usb_mark_last_busy(dev)
182
183 #else /* USB_SUSPEND_AVAILABLE */
184
185 #define USB_AUTOPM_GET_INTERFACE(intf) do {} while (0)
186 #define USB_AUTOPM_GET_INTERFACE_ASYNC(intf) do {} while (0)
187 #define USB_AUTOPM_PUT_INTERFACE_ASYNC(intf) do {} while (0)
188 #define USB_MARK_LAST_BUSY(dev) do {} while (0)
189 #endif /* USB_SUSPEND_AVAILABLE */
190
191 #define USB_CONTROL_MSG(dev, pipe, request, requesttype, value, index, data, size, timeout) \
192 usb_control_msg((dev), (pipe), (request), (requesttype), (value), (index), \
193 (data), (size), (timeout))
194 #define USB_BUFFER_ALLOC(dev, size, mem, dma) usb_buffer_alloc(dev, size, mem, dma)
195 #define USB_BUFFER_FREE(dev, size, data, dma) usb_buffer_free(dev, size, data, dma)
196
197 #ifdef WL_URB_ZPKT
198 #define URB_QUEUE_BULK URB_ZERO_PACKET
199 #else
200 #define URB_QUEUE_BULK 0
201 #endif /* WL_URB_ZPKT */
202
203 #define CALLBACK_ARGS struct urb *urb, struct pt_regs *regs
204 #define CALLBACK_ARGS_DATA urb, regs
205 #define CONFIGDESC(usb) (&((usb)->actconfig)->desc)
206 #define IFPTR(usb, idx) ((usb)->actconfig->interface[idx])
207 #define IFALTS(usb, idx) (IFPTR((usb), (idx))->altsetting[0])
208 #define IFDESC(usb, idx) IFALTS((usb), (idx)).desc
209 #define IFEPDESC(usb, idx, ep) (IFALTS((usb), (idx)).endpoint[ep]).desc
210 #ifdef DBUS_LINUX_RXDPC
211 #define DAEMONIZE(a) daemonize(a); allow_signal(SIGKILL); allow_signal(SIGTERM);
212 #define SET_NICE(n) set_user_nice(current, n)
213 #endif
214
215 #else /* KERNEL26 */
216
217 #define USB_ALLOC_URB() usb_alloc_urb(0)
218 #define USB_UNLINK_URB(urb) usb_unlink_urb(urb)
219 #define USB_FREE_URB(urb) (usb_free_urb(urb))
220 #define USB_REGISTER() usb_register(&dbus_usbdev)
221 #define USB_DEREGISTER() usb_deregister(&dbus_usbdev)
222 #define USB_AUTOPM_GET_INTERFACE(intf) do {} while (0)
223 #define USB_AUTOPM_GET_INTERFACE_ASYNC(intf) do {} while (0)
224 #define USB_AUTOPM_PUT_INTERFACE_ASYNC(intf) do {} while (0)
225 #define USB_MARK_LAST_BUSY(dev) do {} while (0)
226
227 #define USB_CONTROL_MSG(dev, pipe, request, requesttype, value, index, data, size, timeout) \
228 usb_control_msg((dev), (pipe), (request), (requesttype), (value), (index), \
229 (data), (size), (timeout))
230 #define USB_BUFFER_ALLOC(dev, size, mem, dma) kmalloc(size, mem)
231 #define USB_BUFFER_FREE(dev, size, data, dma) kfree(data)
232
233 #ifdef WL_URB_ZPKT
234 #define URB_QUEUE_BULK USB_QUEUE_BULK|URB_ZERO_PACKET
235 #else
236 #define URB_QUEUE_BULK 0
237 #endif /* WL_URB_ZPKT */
238
239 #define CALLBACK_ARGS struct urb *urb
240 #define CALLBACK_ARGS_DATA urb
241 #define CONFIGDESC(usb) ((usb)->actconfig)
242 #define IFPTR(usb, idx) (&(usb)->actconfig->interface[idx])
243 #define IFALTS(usb, idx) ((usb)->actconfig->interface[idx].altsetting[0])
244 #define IFDESC(usb, idx) IFALTS((usb), (idx))
245 #define IFEPDESC(usb, idx, ep) (IFALTS((usb), (idx)).endpoint[ep])
246
247 #ifdef DBUS_LINUX_RXDPC
248 #define DAEMONIZE(a) daemonize();
249 #define SET_NICE(n) do {current->nice = (n);} while (0)
250 #endif /* DBUS_LINUX_RXDPC */
251
252 #endif /* KERNEL26 */
253
254 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
255 #define USB_SPEED_SUPER 5
256 #endif /* #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) */
257
258 #define CONTROL_IF 0
259 #define BULK_IF 0
260
261 #ifdef BCMUSBDEV_COMPOSITE
262 #define USB_COMPIF_MAX 4
263
264 #define USB_CLASS_WIRELESS 0xe0
265 #define USB_CLASS_MISC 0xef
266 #define USB_SUBCLASS_COMMON 0x02
267 #define USB_PROTO_IAD 0x01
268 #define USB_PROTO_VENDOR 0xff
269
270 #define USB_QUIRK_NO_SET_INTF 0x04 /* device does not support set_interface */
271 #endif /* BCMUSBDEV_COMPOSITE */
272
273 #define USB_SYNC_WAIT_TIMEOUT 300 /* ms */
274
275 #define FW_NAME_PREFIX_LEN 8 /* FW_NAME prefix length */
276
277 /* Private data kept in skb */
278 #define SKB_PRIV(skb, idx) (&((void **)skb->cb)[idx])
279 #define SKB_PRIV_URB(skb) (*(struct urb **)SKB_PRIV(skb, 0))
280
281 #ifndef DBUS_USB_RXQUEUE_BATCH_ADD
282 /* items to add each time within limit */
283 #define DBUS_USB_RXQUEUE_BATCH_ADD 8
284 #endif
285 #ifndef DBUS_USB_RXQUEUE_LOWER_WATERMARK
286 /* add a new batch req to rx queue when waiting item count reduce to this number */
287 #define DBUS_USB_RXQUEUE_LOWER_WATERMARK 4
288 #endif
289 enum usbos_suspend_state {
290 USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow suspend */
291 USBOS_SUSPEND_STATE_SUSPEND_PENDING, /* Device is idle, can be suspended */
292 /* Wating PM to suspend */
293 USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */
294 };
295
296 enum usbos_request_state {
297 USBOS_REQUEST_STATE_UNSCHEDULED = 0, /* USB TX request not scheduled */
298 USBOS_REQUEST_STATE_SCHEDULED, /* USB TX request given to TX thread */
299 USBOS_REQUEST_STATE_SUBMITTED /* USB TX request submitted */
300 };
301
302 typedef struct {
303 uint32 notification;
304 uint32 reserved;
305 } intr_t;
306
307 typedef struct {
308 dbus_pub_t *pub;
309
310 void *cbarg;
311 dbus_intf_callbacks_t *cbs;
312
313 /* Imported */
314 struct usb_device *usb; /* USB device pointer from OS */
315 struct urb *intr_urb; /* URB for interrupt endpoint */
316 struct list_head req_rxfreeq;
317 struct list_head req_txfreeq;
318 struct list_head req_rxpostedq; /* Posted down to USB driver for RX */
319 struct list_head req_txpostedq; /* Posted down to USB driver for TX */
320 spinlock_t rxfree_lock; /* Lock for rx free list */
321 spinlock_t txfree_lock; /* Lock for tx free list */
322 spinlock_t rxposted_lock; /* Lock for rx posted list */
323 spinlock_t txposted_lock; /* Lock for tx posted list */
324 uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; /* Pipe numbers for USB I/O */
325 uint rxbuf_len;
326
327 struct list_head req_rxpendingq; /* RXDPC: Pending for dpc to send up */
328 spinlock_t rxpending_lock; /* RXDPC: Lock for rx pending list */
329 long dpc_pid;
330 struct semaphore dpc_sem;
331 struct completion dpc_exited;
332 int rxpending;
333 #if defined(DBUS_LINUX_HIST)
334 int dpc_cnt, dpc_pktcnt, dpc_maxpktcnt;
335 #endif
336
337 struct urb *ctl_urb;
338 struct urb *ctl_tx_urb;
339 int ctl_in_pipe, ctl_out_pipe;
340 struct usb_ctrlrequest ctl_write;
341 struct usb_ctrlrequest ctl_read;
342 #ifdef USBOS_TX_THREAD
343 enum usbos_request_state ctl_state;
344 #endif /* USBOS_TX_THREAD */
345
346 spinlock_t rxlock; /* Lock for rxq management */
347 spinlock_t txlock; /* Lock for txq management */
348
349 int intr_size; /* Size of interrupt message */
350 int interval; /* Interrupt polling interval */
351 intr_t intr; /* Data buffer for interrupt endpoint */
352
353 int maxps;
354 atomic_t txposted;
355 atomic_t rxposted;
356 atomic_t txallocated;
357 atomic_t rxallocated;
358 bool rxctl_deferrespok; /* Get a response for setup from dongle */
359
360 wait_queue_head_t wait;
361 bool waitdone;
362 int sync_urb_status;
363
364 struct urb *blk_urb; /* Used for downloading embedded image */
365
366 #if defined(DBUS_LINUX_HIST)
367 int *txposted_hist;
368 int *rxposted_hist;
369 #endif
370 #ifdef USBOS_THREAD
371 spinlock_t ctrl_lock;
372 spinlock_t usbos_list_lock;
373 struct list_head usbos_list;
374 struct list_head usbos_free_list;
375 atomic_t usbos_list_cnt;
376 wait_queue_head_t usbos_queue_head;
377 struct task_struct *usbos_kt;
378 #endif /* USBOS_THREAD */
379
380 #ifdef USBOS_TX_THREAD
381 spinlock_t usbos_tx_list_lock;
382 struct list_head usbos_tx_list;
383 wait_queue_head_t usbos_tx_queue_head;
384 struct task_struct *usbos_tx_kt;
385 #endif /* USBOS_TX_THREAD */
386
387 struct dma_pool *qtd_pool; /* QTD pool for USB optimization only */
388 int tx_ep, rx_ep, rx2_ep; /* EPs for USB optimization */
389 struct usb_device *usb_device; /* USB device for optimization */
390 #if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX) /** Linux USB AP related */
391 spinlock_t fastpath_lock;
392 #endif
393 } usbos_info_t;
394
395 typedef struct urb_req {
396 void *pkt;
397 int buf_len;
398 struct urb *urb;
399 void *arg;
400 usbos_info_t *usbinfo;
401 struct list_head urb_list;
402 } urb_req_t;
403
404 #ifdef USBOS_THREAD
405 typedef struct usbos_list_entry {
406 struct list_head list; /* must be first */
407 void *urb_context;
408 int urb_length;
409 int urb_status;
410 } usbos_list_entry_t;
411
412 static void* dbus_usbos_thread_init(usbos_info_t *usbos_info);
413 static void dbus_usbos_thread_deinit(usbos_info_t *usbos_info);
414 static void dbus_usbos_dispatch_schedule(CALLBACK_ARGS);
415 static int dbus_usbos_thread_func(void *data);
416 #endif /* USBOS_THREAD */
417
418 #ifdef USBOS_TX_THREAD
419 void* dbus_usbos_tx_thread_init(usbos_info_t *usbos_info);
420 void dbus_usbos_tx_thread_deinit(usbos_info_t *usbos_info);
421 int dbus_usbos_tx_thread_func(void *data);
422 #endif /* USBOS_TX_THREAD */
423
424 /* Shared Function prototypes */
425 bool dbus_usbos_dl_cmd(usbos_info_t *usbinfo, uint8 cmd, void *buffer, int buflen);
426 int dbus_usbos_wait(usbos_info_t *usbinfo, uint16 ms);
427 bool dbus_usbos_dl_send_bulk(usbos_info_t *usbinfo, void *buffer, int len);
428 int dbus_write_membytes(usbos_info_t *usbinfo, bool set, uint32 address, uint8 *data, uint size);
429
430 /* Local function prototypes */
431 static void dbus_usbos_send_complete(CALLBACK_ARGS);
432 #ifdef DBUS_LINUX_RXDPC
433 static void dbus_usbos_recv_dpc(usbos_info_t *usbos_info);
434 static int dbus_usbos_dpc_thread(void *data);
435 #endif /* DBUS_LINUX_RXDPC */
436 static void dbus_usbos_recv_complete(CALLBACK_ARGS);
437 static int dbus_usbos_errhandler(void *bus, int err);
438 static int dbus_usbos_state_change(void *bus, int state);
439 static void dbusos_stop(usbos_info_t *usbos_info);
440
441 static int dbus_usbos_resume(struct usb_interface *intf);
442 static int dbus_usbos_suspend(struct usb_interface *intf, pm_message_t message);
443 #ifdef KERNEL26
444 static int dbus_usbos_probe(struct usb_interface *intf, const struct usb_device_id *id);
445 static void dbus_usbos_disconnect(struct usb_interface *intf);
446 #if defined(USB_SUSPEND_AVAILABLE)
447 static int dbus_usbos_resume(struct usb_interface *intf);
448 static int dbus_usbos_suspend(struct usb_interface *intf, pm_message_t message);
449 /* at the moment, used for full dongle host driver only */
450 static int dbus_usbos_reset_resume(struct usb_interface *intf);
451 #endif /* USB_SUSPEND_AVAILABLE */
452 #else /* KERNEL26 */
453 static void *dbus_usbos_probe(struct usb_device *usb, unsigned int ifnum,
454 const struct usb_device_id *id);
455 static void dbus_usbos_disconnect(struct usb_device *usb, void *ptr);
456 #endif /* KERNEL26 */
457 #if defined(BCM_REQUEST_FW)
458 static int get_file_buf(char *file_path, char **filebuf, int *filelen);
459 #endif
460
461 static uint32 time_diff(struct timeval *now, struct timeval *then);
462
463 #ifdef USB_TRIGGER_DEBUG
464 static bool dbus_usbos_ctl_send_debugtrig(usbos_info_t *usbinfo);
465 #endif /* USB_TRIGGER_DEBUG */
466 static struct usb_device_id devid_table[] = {
467 { USB_DEVICE(BCM_DNGL_VID, 0x0000) }, /* Configurable via register() */
468 #if defined(BCM_REQUEST_FW)
469 { USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4328) },
470 { USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4322) },
471 { USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4319) },
472 { USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_43236) },
473 { USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_43143) },
474 { USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_43242) },
475 { USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4360) },
476 { USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4350) },
477 { USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_43569) },
478 #endif
479 #ifdef EXTENDED_VID_PID
480 EXTENDED_VID_PID,
481 #endif /* EXTENDED_VID_PID */
482 { USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BDC_PID) }, /* Default BDC */
483 { }
484 };
485
486 MODULE_DEVICE_TABLE(usb, devid_table);
487
488 /** functions called by the Linux kernel USB subsystem */
489 static struct usb_driver dbus_usbdev = {
490 name: "dbus_usbdev",
491 probe: dbus_usbos_probe,
492 disconnect: dbus_usbos_disconnect,
493 id_table: devid_table,
494 suspend: dbus_usbos_suspend,
495 resume: dbus_usbos_resume,
496 #if defined(USB_SUSPEND_AVAILABLE)
497 suspend: dbus_usbos_suspend,
498 resume: dbus_usbos_resume,
499 reset_resume: dbus_usbos_reset_resume,
500 /* Linux USB core will allow autosuspend for devices bound to this driver */
501 supports_autosuspend: 1
502 #endif /* USB_SUSPEND_AVAILABLE */
503 };
504
505 /** This stores USB info during Linux probe callback
506 * since attach() is not called yet at this point
507 */
508 typedef struct {
509 void *usbos_info;
510 struct usb_device *usb; /* USB device pointer from OS */
511 uint rx_pipe; /* Pipe numbers for USB I/O */
512 uint tx_pipe; /* Pipe numbers for USB I/O */
513 uint intr_pipe; /* Pipe numbers for USB I/O */
514 uint rx_pipe2; /* Pipe numbers for USB I/O */
515 int intr_size; /* Size of interrupt message */
516 int interval; /* Interrupt polling interval */
517 bool dldone;
518 int vid;
519 int pid;
520 bool dereged;
521 bool disc_cb_done;
522 DEVICE_SPEED device_speed;
523 enum usbos_suspend_state suspend_state;
524 struct usb_interface *intf;
525 } probe_info_t;
526
527 /*
528 * USB Linux dbus_intf_t
529 */
530 static void *dbus_usbos_intf_attach(dbus_pub_t *pub, void *cbarg, dbus_intf_callbacks_t *cbs);
531 static void dbus_usbos_intf_detach(dbus_pub_t *pub, void *info);
532 static int dbus_usbos_intf_send_irb(void *bus, dbus_irb_tx_t *txirb);
533 static int dbus_usbos_intf_recv_irb(void *bus, dbus_irb_rx_t *rxirb);
534 static int dbus_usbos_intf_recv_irb_from_ep(void *bus, dbus_irb_rx_t *rxirb, uint32 ep_idx);
535 static int dbus_usbos_intf_cancel_irb(void *bus, dbus_irb_tx_t *txirb);
536 static int dbus_usbos_intf_send_ctl(void *bus, uint8 *buf, int len);
537 static int dbus_usbos_intf_recv_ctl(void *bus, uint8 *buf, int len);
538 static int dbus_usbos_intf_get_attrib(void *bus, dbus_attrib_t *attrib);
539 static int dbus_usbos_intf_up(void *bus);
540 static int dbus_usbos_intf_down(void *bus);
541 static int dbus_usbos_intf_stop(void *bus);
542 static int dbus_usbos_readreg(void *bus, uint32 regaddr, int datalen, uint32 *value);
543 extern int dbus_usbos_loopback_tx(void *usbos_info_ptr, int cnt, int size);
544 #ifndef LINUX_POSTMOGRIFY_REMOVAL
545 int dbus_usbos_writereg(void *bus, uint32 regaddr, int datalen, uint32 data);
546 #endif /* LINUX_POSTMOGRIFY_REMOVAL */
547 #if defined(DBUS_LINUX_HIST)
548 static void dbus_usbos_intf_dump(void *bus, struct bcmstrbuf *b);
549 #endif
550 static int dbus_usbos_intf_set_config(void *bus, dbus_config_t *config);
551 static bool dbus_usbos_intf_recv_needed(void *bus);
552 static void *dbus_usbos_intf_exec_rxlock(void *bus, exec_cb_t cb, struct exec_parms *args);
553 static void *dbus_usbos_intf_exec_txlock(void *bus, exec_cb_t cb, struct exec_parms *args);
554 #ifdef BCMUSBDEV_COMPOSITE
555 static int dbus_usbos_intf_wlan(struct usb_device *usb);
556 #endif /* BCMUSBDEV_COMPOSITE */
557
558 /** functions called by dbus_usb.c */
559 static dbus_intf_t dbus_usbos_intf = {
560 .attach = dbus_usbos_intf_attach,
561 .detach = dbus_usbos_intf_detach,
562 .up = dbus_usbos_intf_up,
563 .down = dbus_usbos_intf_down,
564 .send_irb = dbus_usbos_intf_send_irb,
565 .recv_irb = dbus_usbos_intf_recv_irb,
566 .cancel_irb = dbus_usbos_intf_cancel_irb,
567 .send_ctl = dbus_usbos_intf_send_ctl,
568 .recv_ctl = dbus_usbos_intf_recv_ctl,
569 .get_stats = NULL,
570 .get_attrib = dbus_usbos_intf_get_attrib,
571 .remove = NULL,
572 .resume = NULL,
573 .suspend = NULL,
574 .stop = dbus_usbos_intf_stop,
575 .reset = NULL,
576 .pktget = NULL,
577 .pktfree = NULL,
578 .iovar_op = NULL,
579 #if defined(DBUS_LINUX_HIST)
580 .dump = dbus_usbos_intf_dump,
581 #else
582 .dump = NULL,
583 #endif
584 .set_config = dbus_usbos_intf_set_config,
585 .get_config = NULL,
586 .device_exists = NULL,
587 .dlneeded = NULL,
588 .dlstart = NULL,
589 .dlrun = NULL,
590 .recv_needed = dbus_usbos_intf_recv_needed,
591 .exec_rxlock = dbus_usbos_intf_exec_rxlock,
592 .exec_txlock = dbus_usbos_intf_exec_txlock,
593
594 .tx_timer_init = NULL,
595 .tx_timer_start = NULL,
596 .tx_timer_stop = NULL,
597
598 .sched_dpc = NULL,
599 .lock = NULL,
600 .unlock = NULL,
601 .sched_probe_cb = NULL,
602
603 .shutdown = NULL,
604
605 .recv_stop = NULL,
606 .recv_resume = NULL,
607
608 .recv_irb_from_ep = dbus_usbos_intf_recv_irb_from_ep,
609 .readreg = dbus_usbos_readreg
610 };
611
612 static probe_info_t g_probe_info;
613 static probe_cb_t probe_cb = NULL;
614 static disconnect_cb_t disconnect_cb = NULL;
615 static void *probe_arg = NULL;
616 static void *disc_arg = NULL;
617
618 #if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX)
619 #define EHCI_PAGE_SIZE 4096
620
621 /* Copies of structures located elsewhere. */
622
623 typedef struct {
624 dbus_pub_t *pub;
625
626 void *cbarg;
627 dbus_intf_callbacks_t *cbs;
628 dbus_intf_t *drvintf;
629 void *usbosl_info;
630 } usb_info_t;
631
632 /** General info for all BUS */
633 typedef struct dbus_irbq {
634 dbus_irb_t *head;
635 dbus_irb_t *tail;
636 int cnt;
637 } dbus_irbq_t;
638
639 /** This private structure dbus_info_t is also declared in dbus.c.
640 * All the fields must be consistent in both declarations.
641 */
642 typedef struct dbus_info {
643 dbus_pub_t pub; /* MUST BE FIRST */
644
645 void *cbarg;
646 dbus_callbacks_t *cbs;
647 void *bus_info;
648 dbus_intf_t *drvintf;
649 uint8 *fw;
650 int fwlen;
651 uint32 errmask;
652 int rx_low_watermark;
653 int tx_low_watermark;
654 bool txoff;
655 bool txoverride;
656 bool rxoff;
657 bool tx_timer_ticking;
658 dbus_irbq_t *rx_q;
659 dbus_irbq_t *tx_q;
660
661 #ifdef EHCI_FASTPATH_RX
662 atomic_t rx_outstanding;
663 #endif
664 uint8 *nvram;
665 int nvram_len;
666 uint8 *image; /* buffer for combine fw and nvram */
667 int image_len;
668 uint8 *orig_fw;
669 int origfw_len;
670 int decomp_memsize;
671 dbus_extdl_t extdl;
672 int nvram_nontxt;
673 } dbus_info_t;
674
675 static atomic_t s_tx_pending;
676
677 static int optimize_init(usbos_info_t *usbos_info, struct usb_device *usb, int out,
678 int in, int in2);
679 static int optimize_deinit(usbos_info_t *usbos_info, struct usb_device *usb);
680 #endif /* #if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX) */
681
682
683 static volatile int loopback_rx_cnt, loopback_tx_cnt;
684 int loopback_size;
685 bool is_loopback_pkt(void *buf);
686 int matches_loopback_pkt(void *buf);
687 /**
688 * multiple code paths in this file dequeue a URB request, this function makes sure that it happens
689 * in a concurrency save manner. Don't call this from a sleepable process context.
690 */
691 static urb_req_t * BCMFASTPATH
692 dbus_usbos_qdeq(struct list_head *urbreq_q, spinlock_t *lock)
693 {
694 unsigned long flags;
695 urb_req_t *req;
696
697 ASSERT(urbreq_q != NULL);
698
699 spin_lock_irqsave(lock, flags);
700
701 if (list_empty(urbreq_q)) {
702 req = NULL;
703 } else {
704 ASSERT(urbreq_q->next != NULL);
705 ASSERT(urbreq_q->next != urbreq_q);
706
707 req = list_entry(urbreq_q->next, urb_req_t, urb_list);
708 list_del_init(&req->urb_list);
709 }
710
711 spin_unlock_irqrestore(lock, flags);
712
713 return req;
714 }
715
716 static void BCMFASTPATH
717 dbus_usbos_qenq(struct list_head *urbreq_q, urb_req_t *req, spinlock_t *lock)
718 {
719 unsigned long flags;
720
721 spin_lock_irqsave(lock, flags);
722
723 list_add_tail(&req->urb_list, urbreq_q);
724
725 spin_unlock_irqrestore(lock, flags);
726
727 }
728
729 /**
730 * multiple code paths in this file remove a URB request from a list, this function makes sure that
731 * it happens in a concurrency save manner. Don't call this from a sleepable process context.
732 * Is quite similar to dbus_usbos_qdeq(), I wonder why this function is needed.
733 */
734 static void
735 dbus_usbos_req_del(urb_req_t *req, spinlock_t *lock)
736 {
737 unsigned long flags;
738
739 spin_lock_irqsave(lock, flags);
740
741 list_del_init(&req->urb_list);
742
743 spin_unlock_irqrestore(lock, flags);
744 }
745
746
747 /**
748 * Driver requires a pool of URBs to operate. This function is called during
749 * initialization (attach phase), allocates a number of URBs, and puts them
750 * on the free (req_rxfreeq and req_txfreeq) queue
751 */
752 static int
753 dbus_usbos_urbreqs_alloc(usbos_info_t *usbos_info, uint32 count, bool is_rx)
754 {
755 int i;
756 int allocated = 0;
757 int err = DBUS_OK;
758
759 for (i = 0; i < count; i++) {
760 urb_req_t *req;
761
762 req = MALLOC(usbos_info->pub->osh, sizeof(urb_req_t));
763 if (req == NULL) {
764 DBUSERR(("%s: MALLOC req failed\n", __FUNCTION__));
765 err = DBUS_ERR_NOMEM;
766 goto fail;
767 }
768 bzero(req, sizeof(urb_req_t));
769
770 req->urb = USB_ALLOC_URB();
771 if (req->urb == NULL) {
772 DBUSERR(("%s: USB_ALLOC_URB req->urb failed\n", __FUNCTION__));
773 err = DBUS_ERR_NOMEM;
774 goto fail;
775 }
776
777 INIT_LIST_HEAD(&req->urb_list);
778
779 if (is_rx) {
780 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
781 /* don't allocate now. Do it on demand */
782 req->pkt = NULL;
783 #else
784 /* pre-allocate buffers never to be released */
785 req->pkt = MALLOC(usbos_info->pub->osh, usbos_info->rxbuf_len);
786 if (req->pkt == NULL) {
787 DBUSERR(("%s: MALLOC req->pkt failed\n", __FUNCTION__));
788 err = DBUS_ERR_NOMEM;
789 goto fail;
790 }
791 #endif
792 req->buf_len = usbos_info->rxbuf_len;
793 dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
794 } else {
795 req->buf_len = 0;
796 dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
797 }
798 allocated++;
799 continue;
800
801 fail:
802 if (req) {
803 if (is_rx && req->pkt) {
804 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
805 /* req->pkt is NULL in "NOCOPY" mode */
806 #else
807 MFREE(usbos_info->pub->osh, req->pkt, req->buf_len);
808 #endif
809 }
810 if (req->urb) {
811 USB_FREE_URB(req->urb);
812 }
813 MFREE(usbos_info->pub->osh, req, sizeof(urb_req_t));
814 }
815 break;
816 }
817
818 atomic_add(allocated, is_rx ? &usbos_info->rxallocated : &usbos_info->txallocated);
819
820 if (is_rx) {
821 DBUSTRACE(("%s: add %d (total %d) rx buf, each has %d bytes\n", __FUNCTION__,
822 allocated, atomic_read(&usbos_info->rxallocated), usbos_info->rxbuf_len));
823 } else {
824 DBUSTRACE(("%s: add %d (total %d) tx req\n", __FUNCTION__,
825 allocated, atomic_read(&usbos_info->txallocated)));
826 }
827
828 return err;
829 }
830
831 /** Typically called during detach or when attach failed. Don't call until all URBs unlinked */
832 static int
833 dbus_usbos_urbreqs_free(usbos_info_t *usbos_info, bool is_rx)
834 {
835 int rtn = 0;
836 urb_req_t *req;
837 struct list_head *req_q;
838 spinlock_t *lock;
839
840 if (is_rx) {
841 req_q = &usbos_info->req_rxfreeq;
842 lock = &usbos_info->rxfree_lock;
843 } else {
844 req_q = &usbos_info->req_txfreeq;
845 lock = &usbos_info->txfree_lock;
846 }
847 while ((req = dbus_usbos_qdeq(req_q, lock)) != NULL) {
848
849 if (is_rx) {
850 if (req->pkt) {
851 /* We do MFREE instead of PKTFREE because the pkt has been
852 * converted to native already
853 */
854 MFREE(usbos_info->pub->osh, req->pkt, req->buf_len);
855 req->pkt = NULL;
856 req->buf_len = 0;
857 }
858 }
859 else {
860 /* sending req should not be assigned pkt buffer */
861 ASSERT(req->pkt == NULL);
862 }
863
864 if (req->urb) {
865 USB_FREE_URB(req->urb);
866 req->urb = NULL;
867 }
868 MFREE(usbos_info->pub->osh, req, sizeof(urb_req_t));
869
870 rtn++;
871 }
872 return rtn;
873 }
874
875 /**
876 * called by Linux kernel on URB completion. Upper DBUS layer (dbus_usb.c) has to be notified of
877 * send completion.
878 */
879 void
880 dbus_usbos_send_complete(CALLBACK_ARGS)
881 {
882 urb_req_t *req = urb->context;
883 dbus_irb_tx_t *txirb = req->arg;
884 usbos_info_t *usbos_info = req->usbinfo;
885 unsigned long flags;
886 int status = DBUS_OK;
887 int txposted;
888
889 /* Enable USB autosuspend if no packets are being sent */
890 USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
891
892 spin_lock_irqsave(&usbos_info->txlock, flags);
893
894 dbus_usbos_req_del(req, &usbos_info->txposted_lock);
895 txposted = atomic_dec_return(&usbos_info->txposted);
896 #if defined(DBUS_LINUX_HIST)
897 if (usbos_info->txposted_hist) {
898 usbos_info->txposted_hist[txposted]++;
899 }
900 #endif
901 if (unlikely (txposted < 0)) {
902 DBUSERR(("%s ERROR: txposted is negative (%d)!!\n", __FUNCTION__, txposted));
903 }
904 spin_unlock_irqrestore(&usbos_info->txlock, flags);
905
906 if (unlikely (urb->status)) {
907 status = DBUS_ERR_TXFAIL;
908 DBUSTRACE(("txfail status %d\n", urb->status));
909 }
910
911 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
912 /* sending req should not be assigned pkt buffer */
913 ASSERT(req->pkt == NULL);
914 #endif
915 /* txirb should always be set, except for ZLP. ZLP is reusing this callback function. */
916 if (txirb != NULL) {
917 if (txirb->send_buf != NULL) {
918 MFREE(usbos_info->pub->osh, txirb->send_buf, req->buf_len);
919 txirb->send_buf = NULL;
920 req->buf_len = 0;
921 }
922 if (likely (usbos_info->cbarg && usbos_info->cbs)) {
923 if (likely (usbos_info->cbs->send_irb_complete != NULL))
924 usbos_info->cbs->send_irb_complete(usbos_info->cbarg, txirb, status);
925 }
926 }
927
928 dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
929 }
930
931 /**
932 * In order to receive USB traffic from the dongle, we need to supply the Linux kernel with a free
933 * URB that is going to contain received data.
934 */
935 static int BCMFASTPATH
936 dbus_usbos_recv_urb_submit(usbos_info_t *usbos_info, dbus_irb_rx_t *rxirb, uint32 ep_idx)
937 {
938 urb_req_t *req;
939 int ret = DBUS_OK;
940 unsigned long flags;
941 void *p;
942 uint rx_pipe;
943 int rxposted;
944
945 BCM_REFERENCE(rxposted);
946
947 if (!(req = dbus_usbos_qdeq(&usbos_info->req_rxfreeq, &usbos_info->rxfree_lock))) {
948 DBUSTRACE(("%s No free URB!\n", __FUNCTION__));
949 return DBUS_ERR_RXDROP;
950 }
951
952 spin_lock_irqsave(&usbos_info->rxlock, flags);
953
954 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
955 req->pkt = rxirb->pkt = PKTGET(usbos_info->pub->osh, req->buf_len, FALSE);
956 if (!rxirb->pkt) {
957 DBUSERR(("%s: PKTGET failed\n", __FUNCTION__));
958 dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
959 ret = DBUS_ERR_RXDROP;
960 goto fail;
961 }
962 /* consider the packet "native" so we don't count it as MALLOCED in the osl */
963 PKTTONATIVE(usbos_info->pub->osh, req->pkt);
964 rxirb->buf = NULL;
965 p = PKTDATA(usbos_info->pub->osh, req->pkt);
966 #else
967 if (req->buf_len != usbos_info->rxbuf_len) {
968 ASSERT(req->pkt);
969 MFREE(usbos_info->pub->osh, req->pkt, req->buf_len);
970 DBUSTRACE(("%s: replace rx buff: old len %d, new len %d\n", __FUNCTION__,
971 req->buf_len, usbos_info->rxbuf_len));
972 req->buf_len = 0;
973 req->pkt = MALLOC(usbos_info->pub->osh, usbos_info->rxbuf_len);
974 if (req->pkt == NULL) {
975 DBUSERR(("%s: MALLOC req->pkt failed\n", __FUNCTION__));
976 ret = DBUS_ERR_NOMEM;
977 goto fail;
978 }
979 req->buf_len = usbos_info->rxbuf_len;
980 }
981 rxirb->buf = req->pkt;
982 p = rxirb->buf;
983 #endif /* defined(BCM_RPC_NOCOPY) */
984 rxirb->buf_len = req->buf_len;
985 req->usbinfo = usbos_info;
986 req->arg = rxirb;
987 if (ep_idx == 0) {
988 rx_pipe = usbos_info->rx_pipe;
989 } else {
990 rx_pipe = usbos_info->rx_pipe2;
991 ASSERT(usbos_info->rx_pipe2);
992 }
993 /* Prepare the URB */
994 usb_fill_bulk_urb(req->urb, usbos_info->usb, rx_pipe,
995 p,
996 rxirb->buf_len,
997 (usb_complete_t)dbus_usbos_recv_complete, req);
998 req->urb->transfer_flags |= URB_QUEUE_BULK;
999
1000 if ((ret = USB_SUBMIT_URB(req->urb))) {
1001 DBUSERR(("%s USB_SUBMIT_URB failed. status %d\n", __FUNCTION__, ret));
1002 dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
1003 ret = DBUS_ERR_RXFAIL;
1004 goto fail;
1005 }
1006 rxposted = atomic_inc_return(&usbos_info->rxposted);
1007 #if defined(DBUS_LINUX_HIST)
1008 if (usbos_info->rxposted_hist) {
1009 usbos_info->rxposted_hist[rxposted]++;
1010 }
1011 #endif
1012
1013 dbus_usbos_qenq(&usbos_info->req_rxpostedq, req, &usbos_info->rxposted_lock);
1014 fail:
1015 spin_unlock_irqrestore(&usbos_info->rxlock, flags);
1016 return ret;
1017 }
1018
1019 #ifdef DBUS_LINUX_RXDPC
1020 static void BCMFASTPATH
1021 dbus_usbos_recv_dpc(usbos_info_t *usbos_info)
1022 {
1023 urb_req_t *req = NULL;
1024 dbus_irb_rx_t *rxirb = NULL;
1025 int dbus_status = DBUS_OK;
1026 bool killed = (g_probe_info.suspend_state == USBOS_SUSPEND_STATE_SUSPEND_PENDING) ? 1 : 0;
1027
1028 #if defined(DBUS_LINUX_HIST)
1029 int cnt = 0;
1030
1031 usbos_info->dpc_cnt++;
1032 #endif
1033
1034 while ((req = dbus_usbos_qdeq(&usbos_info->req_rxpendingq,
1035 &usbos_info->rxpending_lock)) != NULL) {
1036 struct urb *urb = req->urb;
1037 rxirb = req->arg;
1038
1039 /* Handle errors */
1040 if (urb->status) {
1041 /*
1042 * Linux 2.4 disconnect: -ENOENT or -EILSEQ for CRC error; rmmod: -ENOENT
1043 * Linux 2.6 disconnect: -EPROTO, rmmod: -ESHUTDOWN
1044 */
1045 if ((urb->status == -ENOENT && (!killed)) || urb->status == -ESHUTDOWN) {
1046 /* NOTE: unlink() can not be called from URB callback().
1047 * Do not call dbusos_stop() here.
1048 */
1049 dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
1050 } else if (urb->status == -EPROTO) {
1051 } else {
1052 DBUSERR(("%s rx error %d\n", __FUNCTION__, urb->status));
1053 dbus_usbos_errhandler(usbos_info, DBUS_ERR_RXFAIL);
1054 }
1055
1056 /* On error, don't submit more URBs yet */
1057 DBUSERR(("%s %d rx error %d\n", __FUNCTION__, __LINE__, urb->status));
1058 rxirb->buf = NULL;
1059 rxirb->actual_len = 0;
1060 dbus_status = DBUS_ERR_RXFAIL;
1061 goto fail;
1062 }
1063
1064 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
1065 /* detach the packet from the req */
1066 req->pkt = NULL;
1067 #endif
1068 /* Make the skb represent the received urb */
1069 rxirb->actual_len = urb->actual_length;
1070
1071 fail:
1072 usbos_info->rxpending--;
1073 #if defined(DBUS_LINUX_HIST)
1074 cnt++;
1075 #endif
1076 if (usbos_info->cbarg && usbos_info->cbs &&
1077 usbos_info->cbs->recv_irb_complete) {
1078 usbos_info->cbs->recv_irb_complete(usbos_info->cbarg, rxirb, dbus_status);
1079 }
1080 dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
1081 }
1082
1083 #if defined(DBUS_LINUX_HIST)
1084 usbos_info->dpc_pktcnt += cnt;
1085 usbos_info->dpc_maxpktcnt = MAX(cnt, usbos_info->dpc_maxpktcnt);
1086 #endif
1087 #ifdef DBUS_LINUX_HIST
1088 {
1089 static unsigned long last_dump = 0;
1090
1091 /* dump every 20 sec */
1092 if (jiffies > (last_dump + 20*HZ)) {
1093 dbus_usbos_intf_dump(usbos_info, NULL);
1094 last_dump = jiffies;
1095 }
1096 }
1097 #endif /* DBUS_LINUX_HIST */
1098 }
1099
1100 static int BCMFASTPATH
1101 dbus_usbos_dpc_thread(void *data)
1102 {
1103 usbos_info_t *usbos_info = (usbos_info_t*)data;
1104
1105 DAEMONIZE("dbus_rx_dpc");
1106 /* High priority for short response time. We will yield by ourselves. */
1107 /* SET_NICE(-10); */
1108
1109 /* Run until signal received */
1110 while (1) {
1111 if (down_interruptible(&usbos_info->dpc_sem) == 0) {
1112 dbus_usbos_recv_dpc(usbos_info);
1113 RESCHED();
1114 } else
1115 break;
1116 }
1117
1118 complete_and_exit(&usbos_info->dpc_exited, 0);
1119 return 0;
1120 }
1121 #endif /* DBUS_LINUX_RXDPC */
1122
1123 /* called by worked thread when a 'receive URB' completed */
1124 /* or Linux kernel when it returns a URB to this driver */
1125 static void BCMFASTPATH
1126 dbus_usbos_recv_complete_handle(urb_req_t *req, int len, int status)
1127 {
1128 #ifdef DBUS_LINUX_RXDPC
1129 usbos_info_t *usbos_info = req->usbinfo;
1130 unsigned long flags;
1131 int rxallocated, rxposted;
1132
1133 spin_lock_irqsave(&usbos_info->rxlock, flags);
1134 /* detach the packet from the queue */
1135 dbus_usbos_req_del(req, &usbos_info->rxposted_lock);
1136 rxposted = atomic_dec_return(&usbos_info->rxposted);
1137 rxallocated = atomic_read(&usbos_info->rxallocated);
1138
1139 /* Enqueue to rxpending queue */
1140 usbos_info->rxpending++;
1141 dbus_usbos_qenq(&usbos_info->req_rxpendingq, req, &usbos_info->rxpending_lock);
1142 spin_unlock_irqrestore(&usbos_info->rxlock, flags);
1143
1144 #error "RX req/buf appending-mode not verified for DBUS_LINUX_RXDPC because it was disabled"
1145 if ((rxallocated < usbos_info->pub->nrxq) && (!status) &&
1146 (rxposted == DBUS_USB_RXQUEUE_LOWER_WATERMARK)) {
1147 DBUSTRACE(("%s: need more rx buf: rxallocated %d rxposted %d!\n",
1148 __FUNCTION__, rxallocated, rxposted));
1149 dbus_usbos_urbreqs_alloc(usbos_info,
1150 MIN(DBUS_USB_RXQUEUE_BATCH_ADD,
1151 usbos_info->pub->nrxq - rxallocated), TRUE);
1152 }
1153 #error "Please verify above code works if you happened to enable DBUS_LINUX_RXDPC!!"
1154
1155 /* Wake up dpc for further processing */
1156 ASSERT(usbos_info->dpc_pid >= 0);
1157 up(&usbos_info->dpc_sem);
1158 #else
1159 dbus_irb_rx_t *rxirb = req->arg;
1160 usbos_info_t *usbos_info = req->usbinfo;
1161 unsigned long flags;
1162 int rxallocated, rxposted;
1163 int dbus_status = DBUS_OK;
1164 bool killed = (g_probe_info.suspend_state == USBOS_SUSPEND_STATE_SUSPEND_PENDING) ? 1 : 0;
1165
1166 spin_lock_irqsave(&usbos_info->rxlock, flags);
1167 dbus_usbos_req_del(req, &usbos_info->rxposted_lock);
1168 rxposted = atomic_dec_return(&usbos_info->rxposted);
1169 rxallocated = atomic_read(&usbos_info->rxallocated);
1170 spin_unlock_irqrestore(&usbos_info->rxlock, flags);
1171
1172 if ((rxallocated < usbos_info->pub->nrxq) && (!status) &&
1173 (rxposted == DBUS_USB_RXQUEUE_LOWER_WATERMARK)) {
1174 DBUSTRACE(("%s: need more rx buf: rxallocated %d rxposted %d!\n",
1175 __FUNCTION__, rxallocated, rxposted));
1176 dbus_usbos_urbreqs_alloc(usbos_info,
1177 MIN(DBUS_USB_RXQUEUE_BATCH_ADD,
1178 usbos_info->pub->nrxq - rxallocated), TRUE);
1179 }
1180
1181 /* Handle errors */
1182 if (status) {
1183 /*
1184 * Linux 2.4 disconnect: -ENOENT or -EILSEQ for CRC error; rmmod: -ENOENT
1185 * Linux 2.6 disconnect: -EPROTO, rmmod: -ESHUTDOWN
1186 */
1187 if ((status == -ENOENT && (!killed))|| status == -ESHUTDOWN) {
1188 /* NOTE: unlink() can not be called from URB callback().
1189 * Do not call dbusos_stop() here.
1190 */
1191 dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
1192 } else if (status == -EPROTO) {
1193 } else {
1194 DBUSTRACE(("%s rx error %d\n", __FUNCTION__, status));
1195 dbus_usbos_errhandler(usbos_info, DBUS_ERR_RXFAIL);
1196 }
1197 printf("%s rx error %d\n", __FUNCTION__, status);
1198
1199 /* On error, don't submit more URBs yet */
1200 rxirb->buf = NULL;
1201 rxirb->actual_len = 0;
1202 dbus_status = DBUS_ERR_RXFAIL;
1203 goto fail;
1204 }
1205
1206 /* Make the skb represent the received urb */
1207 rxirb->actual_len = len;
1208
1209 if (rxirb->actual_len < sizeof(uint32)) {
1210 DBUSTRACE(("small pkt len %d, process as ZLP\n", rxirb->actual_len));
1211 dbus_status = DBUS_ERR_RXZLP;
1212 }
1213
1214 fail:
1215 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
1216 /* detach the packet from the queue */
1217 req->pkt = NULL;
1218 #endif /* BCM_RPC_NOCOPY || BCM_RPC_RXNOCOPY */
1219
1220 if (usbos_info->cbarg && usbos_info->cbs) {
1221 if (usbos_info->cbs->recv_irb_complete) {
1222 usbos_info->cbs->recv_irb_complete(usbos_info->cbarg, rxirb, dbus_status);
1223 }
1224 }
1225
1226 dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
1227 #endif /* DBUS_LINUX_RXDPC */
1228
1229 /* Mark the interface as busy to reset USB autosuspend timer */
1230 USB_MARK_LAST_BUSY(usbos_info->usb);
1231 }
1232
1233 /** called by Linux kernel when it returns a URB to this driver */
1234 static void
1235 dbus_usbos_recv_complete(CALLBACK_ARGS)
1236 {
1237 #ifdef USBOS_THREAD
1238 dbus_usbos_dispatch_schedule(CALLBACK_ARGS_DATA);
1239 #else /* !USBOS_THREAD */
1240 dbus_usbos_recv_complete_handle(urb->context, urb->actual_length, urb->status);
1241 #endif /* USBOS_THREAD */
1242 }
1243
1244
1245 /**
1246 * If Linux notifies our driver that a control read or write URB has completed, we should notify
1247 * the DBUS layer above us (dbus_usb.c in this case).
1248 */
1249 static void
1250 dbus_usbos_ctl_complete(usbos_info_t *usbos_info, int type, int urbstatus)
1251 {
1252 int status = DBUS_ERR;
1253
1254 if (usbos_info == NULL)
1255 return;
1256
1257 switch (urbstatus) {
1258 case 0:
1259 status = DBUS_OK;
1260 break;
1261 case -EINPROGRESS:
1262 case -ENOENT:
1263 default:
1264 #ifdef INTR_EP_ENABLE
1265 DBUSERR(("%s:%d fail status %d bus:%d susp:%d intr:%d ctli:%d ctlo:%d\n",
1266 __FUNCTION__, type, urbstatus,
1267 usbos_info->pub->busstate, g_probe_info.suspend_state,
1268 usbos_info->intr_urb_submitted, usbos_info->ctlin_urb_submitted,
1269 usbos_info->ctlout_urb_submitted));
1270 #else
1271 DBUSERR(("%s: failed with status %d\n", __FUNCTION__, urbstatus));
1272 status = DBUS_ERR;
1273 break;
1274 #endif /* INTR_EP_ENABLE */
1275 }
1276
1277 if (usbos_info->cbarg && usbos_info->cbs) {
1278 if (usbos_info->cbs->ctl_complete)
1279 usbos_info->cbs->ctl_complete(usbos_info->cbarg, type, status);
1280 }
1281 }
1282
1283 #ifndef USB_SYNC_CTRL_URB
1284 /** called by Linux */
1285 static void
1286 dbus_usbos_ctlread_complete(CALLBACK_ARGS)
1287 {
1288 usbos_info_t *usbos_info = (usbos_info_t *)urb->context;
1289 #ifdef USBOS_THREAD
1290 unsigned long flags;
1291
1292 spin_lock_irqsave(&usbos_info->ctrl_lock, flags);
1293 #endif /* USBOS_THREAD */
1294
1295 ASSERT(urb);
1296 usbos_info = (usbos_info_t *)urb->context;
1297
1298 dbus_usbos_ctl_complete(usbos_info, DBUS_CBCTL_READ, urb->status);
1299
1300 #ifdef USBOS_THREAD
1301 if (usbos_info->rxctl_deferrespok) {
1302 usbos_info->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_CLASS |
1303 USB_RECIP_INTERFACE;
1304 usbos_info->ctl_read.bRequest = 1;
1305 }
1306 spin_unlock_irqrestore(&usbos_info->ctrl_lock, flags);
1307 #endif
1308 }
1309
1310 /** called by Linux */
1311 static void
1312 dbus_usbos_ctlwrite_complete(CALLBACK_ARGS)
1313 {
1314 usbos_info_t *usbos_info = (usbos_info_t *)urb->context;
1315 #ifdef USBOS_THREAD
1316 unsigned long flags;
1317
1318 spin_lock_irqsave(&usbos_info->ctrl_lock, flags);
1319 #endif /* USBOS_THREAD */
1320
1321 ASSERT(urb);
1322 usbos_info = (usbos_info_t *)urb->context;
1323
1324 dbus_usbos_ctl_complete(usbos_info, DBUS_CBCTL_WRITE, urb->status);
1325
1326 #ifdef USBOS_TX_THREAD
1327 usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
1328 #endif /* USBOS_TX_THREAD */
1329
1330 #ifdef USBOS_THREAD
1331 spin_unlock_irqrestore(&usbos_info->ctrl_lock, flags);
1332 #endif
1333
1334 /* Enable USB autosuspend if no packets are being sent */
1335 USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
1336 }
1337 #endif /* USB_SYNC_CTRL_URB */
1338
1339 #ifdef INTR_EP_ENABLE
1340 /** called by Linux */
1341 static void
1342 dbus_usbos_intr_complete(CALLBACK_ARGS)
1343 {
1344 usbos_info_t *usbos_info = (usbos_info_t *)urb->context;
1345 bool killed = (g_probe_info.suspend_state == USBOS_SUSPEND_STATE_SUSPEND_PENDING) ? 1 : 0;
1346
1347 if (usbos_info == NULL || usbos_info->pub == NULL)
1348 return;
1349 if ((urb->status == -ENOENT && (!killed)) || urb->status == -ESHUTDOWN ||
1350 urb->status == -ENODEV) {
1351 dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
1352 }
1353
1354 if (usbos_info->pub->busstate == DBUS_STATE_DOWN) {
1355 DBUSERR(("%s: intr cb when DBUS down, ignoring\n", __FUNCTION__));
1356 return;
1357 }
1358 dbus_usbos_ctl_complete(usbos_info, DBUS_CBINTR_POLL, urb->status);
1359 }
1360 #endif /* INTR_EP_ENABLE */
1361
1362 /**
1363 * when the bus is going to sleep or halt, the Linux kernel requires us to take ownership of our
1364 * URBs again. Multiple code paths in this file require a list of URBs to be cancelled in a
1365 * concurrency save manner.
1366 */
1367 static void
1368 dbus_usbos_unlink(struct list_head *urbreq_q, spinlock_t *lock)
1369 {
1370 urb_req_t *req;
1371
1372 /* dbus_usbos_recv_complete() adds req back to req_freeq */
1373 while ((req = dbus_usbos_qdeq(urbreq_q, lock)) != NULL) {
1374 ASSERT(req->urb != NULL);
1375 USB_UNLINK_URB(req->urb);
1376 }
1377 }
1378
1379 /** multiple code paths in this file require the bus to stop */
1380 static void
1381 dbus_usbos_cancel_all_urbs(usbos_info_t *usbos_info)
1382 {
1383 int rxposted, txposted;
1384
1385 DBUSTRACE(("%s: unlink all URBs\n", __FUNCTION__));
1386
1387 #ifdef USBOS_TX_THREAD
1388 usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
1389
1390 /* Yield the CPU to TX thread so all pending requests are submitted */
1391 while (!list_empty(&usbos_info->usbos_tx_list)) {
1392 wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
1393 OSL_SLEEP(10);
1394 }
1395 #endif /* USBOS_TX_THREAD */
1396
1397 /* tell Linux kernel to cancel a single intr, ctl and blk URB */
1398 if (usbos_info->intr_urb)
1399 USB_UNLINK_URB(usbos_info->intr_urb);
1400 if (usbos_info->ctl_urb)
1401 USB_UNLINK_URB(usbos_info->ctl_urb);
1402 if (usbos_info->ctl_tx_urb)
1403 USB_UNLINK_URB(usbos_info->ctl_tx_urb);
1404 if (usbos_info->blk_urb)
1405 USB_UNLINK_URB(usbos_info->blk_urb);
1406
1407 dbus_usbos_unlink(&usbos_info->req_txpostedq, &usbos_info->txposted_lock);
1408 dbus_usbos_unlink(&usbos_info->req_rxpostedq, &usbos_info->rxposted_lock);
1409
1410 /* Wait until the callbacks for all submitted URBs have been called, because the
1411 * handler needs to know is an USB suspend is in progress.
1412 */
1413 SPINWAIT((atomic_read(&usbos_info->txposted) != 0 ||
1414 atomic_read(&usbos_info->rxposted) != 0), 10000);
1415
1416 txposted = atomic_read(&usbos_info->txposted);
1417 rxposted = atomic_read(&usbos_info->rxposted);
1418 if (txposted != 0 || rxposted != 0) {
1419 DBUSERR(("%s ERROR: REQs posted, rx=%d tx=%d!\n",
1420 __FUNCTION__, rxposted, txposted));
1421 }
1422 }
1423
1424 /** multiple code paths require the bus to stop */
1425 static void
1426 dbusos_stop(usbos_info_t *usbos_info)
1427 {
1428 urb_req_t *req;
1429 int rxposted;
1430 req = NULL;
1431 BCM_REFERENCE(req);
1432
1433 ASSERT(usbos_info);
1434
1435 #ifdef USB_TRIGGER_DEBUG
1436 dbus_usbos_ctl_send_debugtrig(usbos_info);
1437 #endif /* USB_TRIGGER_DEBUG */
1438 dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
1439
1440 dbus_usbos_cancel_all_urbs(usbos_info);
1441
1442 #ifdef USBOS_THREAD
1443 /* yield the CPU to rx packet thread */
1444 while (1) {
1445 if (atomic_read(&usbos_info->usbos_list_cnt) <= 0) break;
1446 wake_up_interruptible(&usbos_info->usbos_queue_head);
1447 OSL_SLEEP(3);
1448 }
1449 #endif /* USBOS_THREAD */
1450
1451 rxposted = atomic_read(&usbos_info->rxposted);
1452 if (rxposted > 0) {
1453 DBUSERR(("%s ERROR: rx REQs posted=%d in stop!\n", __FUNCTION__,
1454 rxposted));
1455 }
1456
1457 ASSERT(atomic_read(&usbos_info->txposted) == 0 && rxposted == 0);
1458
1459 #ifdef DBUS_LINUX_RXDPC
1460 /* Stop the dpc thread */
1461 if (usbos_info->dpc_pid >= 0) {
1462 KILL_PROC(usbos_info->dpc_pid, SIGTERM);
1463 wait_for_completion(&usbos_info->dpc_exited);
1464 }
1465
1466 /* Move pending reqs to free queue so they can be freed */
1467 while ((req = dbus_usbos_qdeq(&usbos_info->req_rxpendingq,
1468 &usbos_info->rxpending_lock)) != NULL) {
1469 dbus_usbos_qenq(&usbos_info->req_rxfreeq, req,
1470 &usbos_info->rxfree_lock);
1471 }
1472 #endif /* DBUS_LINUX_RXDPC */
1473 }
1474
1475 static int
1476 dbus_usbos_suspend(struct usb_interface *intf,
1477 pm_message_t message)
1478 {
1479 printk("AP6269: dbus_usbos_suspend enter, calling disconnect\n");
1480 dbus_usbos_disconnect(intf);
1481 return 0;
1482 }
1483
1484 /**
1485 * The resume method is called to tell the driver that the device has been resumed and the driver
1486 * can return to normal operation. URBs may once more be submitted.
1487 */
1488 static int dbus_usbos_resume(struct usb_interface *intf)
1489 {
1490
1491 return 0;
1492 }
1493
1494 #if defined(USB_SUSPEND_AVAILABLE)
1495
1496 /**
1497 * Linux kernel sports a 'USB auto suspend' feature. See: http://lwn.net/Articles/373550/
1498 * The suspend method is called by the Linux kernel to warn the driver that the device is going to
1499 * be suspended. If the driver returns a negative error code, the suspend will be aborted. If the
1500 * driver returns 0, it must cancel all outstanding URBs (usb_kill_urb()) and not submit any more.
1501 */
1502 static int
1503 dbus_usbos_suspend(struct usb_interface *intf,
1504 pm_message_t message)
1505 {
1506 DBUSERR(("%s suspend state: %d\n", __FUNCTION__, g_probe_info.suspend_state));
1507 /* DHD for full dongle model */
1508 g_probe_info.suspend_state = USBOS_SUSPEND_STATE_SUSPEND_PENDING;
1509 dbus_usbos_state_change((usbos_info_t*)g_probe_info.usbos_info, DBUS_STATE_SLEEP);
1510 dbus_usbos_cancel_all_urbs((usbos_info_t*)g_probe_info.usbos_info);
1511 g_probe_info.suspend_state = USBOS_SUSPEND_STATE_SUSPENDED;
1512
1513 return 0;
1514 }
1515
1516 /**
1517 * The resume method is called to tell the driver that the device has been resumed and the driver
1518 * can return to normal operation. URBs may once more be submitted.
1519 */
1520 static int dbus_usbos_resume(struct usb_interface *intf)
1521 {
1522 DBUSERR(("%s Device resumed\n", __FUNCTION__));
1523
1524 dbus_usbos_state_change((usbos_info_t*)g_probe_info.usbos_info, DBUS_STATE_UP);
1525 g_probe_info.suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
1526 return 0;
1527 }
1528
1529 /**
1530 * This function is directly called by the Linux kernel, when the suspended device has been reset
1531 * instead of being resumed
1532 */
1533 static int dbus_usbos_reset_resume(struct usb_interface *intf)
1534 {
1535 DBUSERR(("%s Device reset resumed\n", __FUNCTION__));
1536 return dbus_usbos_resume(intf);
1537 }
1538
1539 #endif /* USB_SUSPEND_AVAILABLE */
1540
1541 /**
1542 * Called by Linux kernel at initialization time, kernel wants to know if our driver will accept the
1543 * caller supplied USB interface. Note that USB drivers are bound to interfaces, and not to USB
1544 * devices.
1545 */
1546 #ifdef KERNEL26
1547 static int
1548 dbus_usbos_probe(struct usb_interface *intf, const struct usb_device_id *id)
1549 #else
1550 static void *
1551 dbus_usbos_probe(struct usb_device *usb, unsigned int ifnum, const struct usb_device_id *id)
1552 #endif /* KERNEL26 */
1553 {
1554 int ep;
1555 struct usb_endpoint_descriptor *endpoint;
1556 int ret = 0;
1557 #ifdef KERNEL26
1558 struct usb_device *usb = interface_to_usbdev(intf);
1559 #else
1560 int claimed = 0;
1561 #endif
1562 int num_of_eps;
1563 #ifdef BCMUSBDEV_COMPOSITE
1564 int wlan_if = -1;
1565 bool intr_ep = FALSE;
1566 #endif /* BCMUSBDEV_COMPOSITE */
1567
1568 #ifdef BCMUSBDEV_COMPOSITE
1569 wlan_if = dbus_usbos_intf_wlan(usb);
1570 #ifdef KERNEL26
1571 if ((wlan_if >= 0) && (IFPTR(usb, wlan_if) == intf)) {
1572 #else
1573 if (wlan_if == ifnum) {
1574 #endif /* KERNEL26 */
1575 #endif /* BCMUSBDEV_COMPOSITE */
1576 g_probe_info.usb = usb;
1577 g_probe_info.dldone = TRUE;
1578 #ifdef BCMUSBDEV_COMPOSITE
1579 } else {
1580 DBUSTRACE(("dbus_usbos_probe: skip probe for non WLAN interface\n"));
1581 ret = BCME_UNSUPPORTED;
1582 goto fail;
1583 }
1584 #endif /* BCMUSBDEV_COMPOSITE */
1585
1586 #ifdef KERNEL26
1587 g_probe_info.intf = intf;
1588 #endif /* KERNEL26 */
1589
1590 #ifdef BCMUSBDEV_COMPOSITE
1591 if (IFDESC(usb, wlan_if).bInterfaceNumber > USB_COMPIF_MAX) {
1592 #else
1593 if (IFDESC(usb, CONTROL_IF).bInterfaceNumber) {
1594 #endif /* BCMUSBDEV_COMPOSITE */
1595 ret = -1;
1596 goto fail;
1597 }
1598 if (id != NULL) {
1599 g_probe_info.vid = id->idVendor;
1600 g_probe_info.pid = id->idProduct;
1601 }
1602
1603 #ifdef KERNEL26
1604 usb_set_intfdata(intf, &g_probe_info);
1605 #endif
1606
1607 /* Check that the device supports only one configuration */
1608 if (usb->descriptor.bNumConfigurations != 1) {
1609 ret = -1;
1610 goto fail;
1611 }
1612
1613 if (usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) {
1614 #ifdef BCMUSBDEV_COMPOSITE
1615 if ((usb->descriptor.bDeviceClass != USB_CLASS_MISC) &&
1616 (usb->descriptor.bDeviceClass != USB_CLASS_WIRELESS)) {
1617 #endif /* BCMUSBDEV_COMPOSITE */
1618 ret = -1;
1619 goto fail;
1620 #ifdef BCMUSBDEV_COMPOSITE
1621 }
1622 #endif /* BCMUSBDEV_COMPOSITE */
1623 }
1624
1625 /*
1626 * Only the BDC interface configuration is supported:
1627 * Device class: USB_CLASS_VENDOR_SPEC
1628 * if0 class: USB_CLASS_VENDOR_SPEC
1629 * if0/ep0: control
1630 * if0/ep1: bulk in
1631 * if0/ep2: bulk out (ok if swapped with bulk in)
1632 */
1633 if (CONFIGDESC(usb)->bNumInterfaces != 1) {
1634 #ifdef BCMUSBDEV_COMPOSITE
1635 if (CONFIGDESC(usb)->bNumInterfaces > USB_COMPIF_MAX) {
1636 #endif /* BCMUSBDEV_COMPOSITE */
1637 ret = -1;
1638 goto fail;
1639 #ifdef BCMUSBDEV_COMPOSITE
1640 }
1641 #endif /* BCMUSBDEV_COMPOSITE */
1642 }
1643
1644 /* Check interface */
1645 #ifndef KERNEL26
1646 #ifdef BCMUSBDEV_COMPOSITE
1647 if (usb_interface_claimed(IFPTR(usb, wlan_if))) {
1648 #else
1649 if (usb_interface_claimed(IFPTR(usb, CONTROL_IF))) {
1650 #endif /* BCMUSBDEV_COMPOSITE */
1651 ret = -1;
1652 goto fail;
1653 }
1654 #endif /* !KERNEL26 */
1655
1656 #ifdef BCMUSBDEV_COMPOSITE
1657 if ((IFDESC(usb, wlan_if).bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
1658 IFDESC(usb, wlan_if).bInterfaceSubClass != 2 ||
1659 IFDESC(usb, wlan_if).bInterfaceProtocol != 0xff) &&
1660 (IFDESC(usb, wlan_if).bInterfaceClass != USB_CLASS_MISC ||
1661 IFDESC(usb, wlan_if).bInterfaceSubClass != USB_SUBCLASS_COMMON ||
1662 IFDESC(usb, wlan_if).bInterfaceProtocol != USB_PROTO_IAD)) {
1663 DBUSERR(("%s: invalid control interface: class %d, subclass %d, proto %d\n",
1664 __FUNCTION__,
1665 IFDESC(usb, wlan_if).bInterfaceClass,
1666 IFDESC(usb, wlan_if).bInterfaceSubClass,
1667 IFDESC(usb, wlan_if).bInterfaceProtocol));
1668 #else
1669 if (IFDESC(usb, CONTROL_IF).bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
1670 IFDESC(usb, CONTROL_IF).bInterfaceSubClass != 2 ||
1671 IFDESC(usb, CONTROL_IF).bInterfaceProtocol != 0xff) {
1672 DBUSERR(("%s: invalid control interface: class %d, subclass %d, proto %d\n",
1673 __FUNCTION__,
1674 IFDESC(usb, CONTROL_IF).bInterfaceClass,
1675 IFDESC(usb, CONTROL_IF).bInterfaceSubClass,
1676 IFDESC(usb, CONTROL_IF).bInterfaceProtocol));
1677 #endif /* BCMUSBDEV_COMPOSITE */
1678 ret = -1;
1679 goto fail;
1680 }
1681
1682 /* Check control endpoint */
1683 #ifdef BCMUSBDEV_COMPOSITE
1684 endpoint = &IFEPDESC(usb, wlan_if, 0);
1685 #else
1686 endpoint = &IFEPDESC(usb, CONTROL_IF, 0);
1687 #endif /* BCMUSBDEV_COMPOSITE */
1688 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
1689 #ifdef BCMUSBDEV_COMPOSITE
1690 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
1691 USB_ENDPOINT_XFER_BULK) {
1692 #endif /* BCMUSBDEV_COMPOSITE */
1693 DBUSERR(("%s: invalid control endpoint %d\n",
1694 __FUNCTION__, endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK));
1695 ret = -1;
1696 goto fail;
1697 #ifdef BCMUSBDEV_COMPOSITE
1698 }
1699 #endif /* BCMUSBDEV_COMPOSITE */
1700 }
1701
1702 #ifdef BCMUSBDEV_COMPOSITE
1703 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
1704 #endif /* BCMUSBDEV_COMPOSITE */
1705 g_probe_info.intr_pipe =
1706 usb_rcvintpipe(usb, endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
1707 #ifdef BCMUSBDEV_COMPOSITE
1708 intr_ep = TRUE;
1709 }
1710 #endif /* BCMUSBDEV_COMPOSITE */
1711
1712 #ifndef KERNEL26
1713 /* Claim interface */
1714 #ifdef BCMUSBDEV_COMPOSITE
1715 usb_driver_claim_interface(&dbus_usbdev, IFPTR(usb, wlan_if), &g_probe_info);
1716 #else
1717 usb_driver_claim_interface(&dbus_usbdev, IFPTR(usb, CONTROL_IF), &g_probe_info);
1718 #endif /* BCMUSBDEV_COMPOSITE */
1719 claimed = 1;
1720 #endif /* !KERNEL26 */
1721 g_probe_info.rx_pipe = 0;
1722 g_probe_info.rx_pipe2 = 0;
1723 g_probe_info.tx_pipe = 0;
1724 #ifdef BCMUSBDEV_COMPOSITE
1725 if (intr_ep)
1726 ep = 1;
1727 else
1728 ep = 0;
1729 num_of_eps = IFDESC(usb, wlan_if).bNumEndpoints - 1;
1730 #else
1731 num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
1732 #endif /* BCMUSBDEV_COMPOSITE */
1733
1734 if ((num_of_eps != 2) && (num_of_eps != 3)) {
1735 #ifdef BCMUSBDEV_COMPOSITE
1736 if (num_of_eps > 7)
1737 #endif /* BCMUSBDEV_COMPOSITE */
1738 ASSERT(0);
1739 }
1740 /* Check data endpoints and get pipes */
1741 #ifdef BCMUSBDEV_COMPOSITE
1742 for (; ep <= num_of_eps; ep++) {
1743 endpoint = &IFEPDESC(usb, wlan_if, ep);
1744 #else
1745 for (ep = 1; ep <= num_of_eps; ep++) {
1746 endpoint = &IFEPDESC(usb, BULK_IF, ep);
1747 #endif /* BCMUSBDEV_COMPOSITE */
1748 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
1749 USB_ENDPOINT_XFER_BULK) {
1750 DBUSERR(("%s: invalid data endpoint %d\n",
1751 __FUNCTION__, ep));
1752 ret = -1;
1753 goto fail;
1754 }
1755
1756 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
1757 if (!g_probe_info.rx_pipe) {
1758 g_probe_info.rx_pipe = usb_rcvbulkpipe(usb,
1759 (endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK));
1760 } else {
1761 g_probe_info.rx_pipe2 = usb_rcvbulkpipe(usb,
1762 (endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK));
1763 }
1764
1765 } else
1766 g_probe_info.tx_pipe = usb_sndbulkpipe(usb, (endpoint->bEndpointAddress &
1767 USB_ENDPOINT_NUMBER_MASK));
1768 }
1769
1770 /* Allocate interrupt URB and data buffer */
1771 /* RNDIS says 8-byte intr, our old drivers used 4-byte */
1772 #ifdef BCMUSBDEV_COMPOSITE
1773 g_probe_info.intr_size = (IFEPDESC(usb, wlan_if, 0).wMaxPacketSize == 16) ? 8 : 4;
1774 g_probe_info.interval = IFEPDESC(usb, wlan_if, 0).bInterval;
1775 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21))
1776 usb->quirks |= USB_QUIRK_NO_SET_INTF;
1777 #endif
1778 #else
1779 g_probe_info.intr_size = (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == 16) ? 8 : 4;
1780 g_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
1781 #endif /* BCMUSBDEV_COMPOSITE */
1782
1783 #ifndef KERNEL26
1784 /* usb_fill_int_urb does the interval decoding in 2.6 */
1785 if (usb->speed == USB_SPEED_HIGH)
1786 g_probe_info.interval = 1 << (g_probe_info.interval - 1);
1787 #endif
1788 if (usb->speed == USB_SPEED_SUPER) {
1789 g_probe_info.device_speed = SUPER_SPEED;
1790 DBUSERR(("super speed device detected\n"));
1791 } else if (usb->speed == USB_SPEED_HIGH) {
1792 g_probe_info.device_speed = HIGH_SPEED;
1793 DBUSERR(("high speed device detected\n"));
1794 } else {
1795 g_probe_info.device_speed = FULL_SPEED;
1796 DBUSERR(("full speed device detected\n"));
1797 }
1798 if (g_probe_info.dereged == FALSE && probe_cb) {
1799 disc_arg = probe_cb(probe_arg, "", USB_BUS, 0);
1800 }
1801
1802 g_probe_info.disc_cb_done = FALSE;
1803
1804 #ifdef KERNEL26
1805 intf->needs_remote_wakeup = 1;
1806 #endif /* KERNEL26 */
1807
1808 /* Success */
1809 #ifdef KERNEL26
1810 return DBUS_OK;
1811 #else
1812 usb_inc_dev_use(usb);
1813 return &g_probe_info;
1814 #endif
1815
1816 fail:
1817 #ifdef BCMUSBDEV_COMPOSITE
1818 if (ret != BCME_UNSUPPORTED)
1819 #endif /* BCMUSBDEV_COMPOSITE */
1820 DBUSERR(("%s: failed with errno %d\n", __FUNCTION__, ret));
1821 #ifndef KERNEL26
1822 if (claimed)
1823 #ifdef BCMUSBDEV_COMPOSITE
1824 usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, wlan_if));
1825 #else
1826 usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, CONTROL_IF));
1827 #endif /* BCMUSBDEV_COMPOSITE */
1828 #endif /* !KERNEL26 */
1829
1830 #ifdef KERNEL26
1831 usb_set_intfdata(intf, NULL);
1832 return ret;
1833 #else
1834 return NULL;
1835 #endif
1836 }
1837
1838 /** Called by Linux kernel, is the counter part of dbus_usbos_probe() */
1839 #ifdef KERNEL26
1840 static void
1841 dbus_usbos_disconnect(struct usb_interface *intf)
1842 #else
1843 static void
1844 dbus_usbos_disconnect(struct usb_device *usb, void *ptr)
1845 #endif
1846 {
1847 #ifdef KERNEL26
1848 struct usb_device *usb = interface_to_usbdev(intf);
1849 probe_info_t *probe_usb_init_data = usb_get_intfdata(intf);
1850 #else
1851 probe_info_t *probe_usb_init_data = (probe_info_t *) ptr;
1852 #endif
1853 usbos_info_t *usbos_info;
1854
1855 if (probe_usb_init_data) {
1856 usbos_info = (usbos_info_t *) probe_usb_init_data->usbos_info;
1857 if (usbos_info) {
1858 if ((probe_usb_init_data->dereged == FALSE) && disconnect_cb && disc_arg) {
1859 disconnect_cb(disc_arg);
1860 disc_arg = NULL;
1861 probe_usb_init_data->disc_cb_done = TRUE;
1862 }
1863 }
1864 }
1865
1866 if (usb) {
1867 #ifndef KERNEL26
1868 #ifdef BCMUSBDEV_COMPOSITE
1869 usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, wlan_if));
1870 #else
1871 usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, CONTROL_IF));
1872 #endif /* BCMUSBDEV_COMPOSITE */
1873 usb_dec_dev_use(usb);
1874 #endif /* !KERNEL26 */
1875 }
1876 }
1877
1878 #define LOOPBACK_PKT_START 0xBABE1234
1879
1880 bool is_loopback_pkt(void *buf)
1881 {
1882
1883 uint32 *buf_ptr = (uint32 *) buf;
1884
1885 if (*buf_ptr == LOOPBACK_PKT_START)
1886 return TRUE;
1887 return FALSE;
1888
1889 }
1890
1891 int matches_loopback_pkt(void *buf)
1892 {
1893 int i, j;
1894 unsigned char *cbuf = (unsigned char *) buf;
1895 uint32 *x = (uint32*) buf;
1896
1897 for (i = 8; i < loopback_size; i++) {
1898 if (cbuf[i] != (i % 256)) {
1899 printf("%s: mismatch at i=%d %d : ", __FUNCTION__, i, cbuf[i]);
1900 printf("%s: rx packet index %u\n", __FUNCTION__, x[1]);
1901 for (j = i; ((j < i+ 16) && (j < loopback_size)); j++) {
1902 printf("%d ", cbuf[j]);
1903 }
1904 printf("\n");
1905 return 0;
1906 }
1907 }
1908 loopback_rx_cnt++;
1909 return 1;
1910 }
1911
1912 uint32 time_diff(struct timeval *now, struct timeval *then)
1913 {
1914 return (now->tv_usec >= then->tv_usec) ?
1915 now->tv_usec - then->tv_usec :
1916 1000000 - (then->tv_usec - now->tv_usec);
1917 }
1918
1919 int dbus_usbos_loopback_tx(void *usbos_info_ptr, int cnt, int size)
1920 {
1921 usbos_info_t *usbos_info = (usbos_info_t *) usbos_info_ptr;
1922 unsigned char *buf;
1923 int j;
1924 void* p = NULL;
1925 int rc, last_rx_cnt;
1926 int tx_failed_cnt;
1927 int rx_wait_cnt;
1928 int max_size = 1650;
1929 int usb_packet_size = 512;
1930 int min_packet_size = 10;
1931 struct timeval su_time;
1932 struct timeval du_time;
1933 uint32 actual_bw = 0;
1934
1935 if (size % usb_packet_size == 0) {
1936 size = size - 1;
1937 DBUSERR(("%s: overriding size=%d \n", __FUNCTION__, size));
1938 }
1939
1940 if (size < min_packet_size) {
1941 size = min_packet_size;
1942 DBUSERR(("%s: overriding size=%d\n", __FUNCTION__, min_packet_size));
1943 }
1944 if (size > max_size) {
1945 size = max_size;
1946 DBUSERR(("%s: overriding size=%d\n", __FUNCTION__, max_size));
1947 }
1948
1949 loopback_tx_cnt = 0;
1950 loopback_rx_cnt = 0;
1951 tx_failed_cnt = 0;
1952 rx_wait_cnt = 0;
1953 loopback_size = size;
1954
1955 do_gettimeofday(&su_time);
1956
1957 while (loopback_tx_cnt < cnt) {
1958 uint32 *x;
1959 int pkt_size = loopback_size;
1960
1961 p = PKTGET(usbos_info->pub->osh, pkt_size, TRUE);
1962 if (p == NULL) {
1963 DBUSERR(("%s:%d Failed to allocate packet sz=%d\n",
1964 __FUNCTION__, __LINE__, pkt_size));
1965 return BCME_ERROR;
1966 }
1967
1968 /*
1969 * Loopback packet data
1970 * ---------------------------------------------------------------------------
1971 * | | Loopback Indicator | PKT Index | Data... |
1972 * ---------------------------------------------------------------------------
1973 * 4 4
1974 */
1975
1976 x = (uint32*) PKTDATA(usbos_info->pub->osh, p);
1977 *x = LOOPBACK_PKT_START;
1978 x[1] = loopback_tx_cnt;
1979 buf = (unsigned char*) x;
1980 for (j = 8; j < pkt_size; j++) {
1981 buf[j] = j % 256;
1982 }
1983 rc = dbus_send_buf(usbos_info->pub, buf, pkt_size, p);
1984 if (rc != BCME_OK) {
1985 DBUSERR(("%s:%d Freeing packet \n", __FUNCTION__, __LINE__));
1986 PKTFREE(usbos_info->pub->osh, p, TRUE);
1987 dbus_usbos_wait(usbos_info, 1);
1988 tx_failed_cnt++;
1989 } else {
1990 loopback_tx_cnt++;
1991 tx_failed_cnt = 0;
1992 }
1993 if (tx_failed_cnt == 5) {
1994 DBUSERR(("%s : Failed to send loopback packets cnt=%d loopback_tx_cnt=%d\n",
1995 __FUNCTION__, cnt, loopback_tx_cnt));
1996 break;
1997 }
1998 }
1999 printf("Transmitted %d loopback packets of size %d\n", loopback_tx_cnt, loopback_size);
2000
2001 last_rx_cnt = loopback_rx_cnt;
2002 while (loopback_rx_cnt < loopback_tx_cnt) {
2003 dbus_usbos_wait(usbos_info, 1);
2004 if (loopback_rx_cnt <= last_rx_cnt) {
2005 rx_wait_cnt++;
2006 if (rx_wait_cnt > 5) {
2007 DBUSERR(("%s: Matched rx cnt stuck at %d \n",
2008 __FUNCTION__, last_rx_cnt));
2009 return BCME_ERROR;
2010 }
2011 } else {
2012 rx_wait_cnt = 0;
2013 last_rx_cnt = loopback_rx_cnt;
2014 }
2015 }
2016
2017 do_gettimeofday(&du_time);
2018
2019 actual_bw = (loopback_tx_cnt + loopback_rx_cnt) * loopback_size * 8 /
2020 time_diff(&du_time, &su_time)*1000000;
2021
2022 printf("Received %d loopback packets of size %d\n", loopback_tx_cnt, loopback_size);
2023 printf("BW : %u bps\n", actual_bw);
2024
2025 return BCME_OK;
2026 }
2027
2028
2029 /** Higher layer (dbus_usb.c) wants to transmit an I/O Request Block */
2030 static int
2031 dbus_usbos_intf_send_irb(void *bus, dbus_irb_tx_t *txirb)
2032 {
2033 usbos_info_t *usbos_info = (usbos_info_t *) bus;
2034 urb_req_t *req, *req_zlp = NULL;
2035 int ret = DBUS_OK;
2036 unsigned long flags = 0;
2037 void *pkt;
2038 uint32 buffer_length;
2039 uint8 *buf;
2040 bool reqs_obtained = FALSE;
2041
2042 BCM_REFERENCE(flags);
2043
2044 if ((usbos_info == NULL) || !usbos_info->tx_pipe) {
2045 return DBUS_ERR;
2046 }
2047
2048 if (txirb->pkt != NULL) {
2049 buffer_length = pkttotlen(usbos_info->pub->osh, txirb->pkt);
2050 /* In case of multiple packets the values below may be overwritten */
2051 txirb->send_buf = NULL;
2052 buf = PKTDATA(usbos_info->pub->osh, txirb->pkt);
2053 } else { /* txirb->buf != NULL */
2054 ASSERT(txirb->buf != NULL);
2055 ASSERT(txirb->send_buf == NULL);
2056 buffer_length = txirb->len;
2057 buf = txirb->buf;
2058 }
2059
2060 if (!(req = dbus_usbos_qdeq(&usbos_info->req_txfreeq, &usbos_info->txfree_lock))) {
2061 DBUSERR(("%s No free URB!\n", __FUNCTION__));
2062 return DBUS_ERR_TXDROP;
2063 }
2064
2065 /* If not using standard Linux kernel functionality for handling Zero Length Packet(ZLP),
2066 * the dbus needs to generate ZLP when length is multiple of MaxPacketSize.
2067 */
2068 #ifndef WL_URB_ZPKT
2069 if (!(buffer_length % usbos_info->maxps)) {
2070 if (!(req_zlp =
2071 dbus_usbos_qdeq(&usbos_info->req_txfreeq, &usbos_info->txfree_lock))) {
2072 DBUSERR(("%s No free URB for ZLP!\n", __FUNCTION__));
2073 ret = DBUS_ERR_TXDROP;
2074 goto fail;
2075 }
2076
2077 /* No txirb, so that dbus_usbos_send_complete can differentiate between
2078 * DATA and ZLP.
2079 */
2080 req_zlp->arg = NULL;
2081 req_zlp->usbinfo = usbos_info;
2082 req_zlp->buf_len = 0;
2083
2084 usb_fill_bulk_urb(req_zlp->urb, usbos_info->usb, usbos_info->tx_pipe, NULL,
2085 0, (usb_complete_t)dbus_usbos_send_complete, req_zlp);
2086
2087 req_zlp->urb->transfer_flags |= URB_QUEUE_BULK;
2088 }
2089 #endif /* !WL_URB_ZPKT */
2090
2091 /* In case of fail, this boolean is used to determine if the USB autosuspend needs to be
2092 * enabled and if spin_unlock_irqrestore() needs to be called.
2093 */
2094 reqs_obtained = TRUE;
2095
2096 #ifndef USBOS_TX_THREAD
2097 /* Disable USB autosuspend until this request completes, and request USB resume if needed.
2098 * Because this call runs asynchronously, there is no guarantee the bus is resumed before
2099 * the URB is submitted, and this request might be dropped. Use USB_SUSPEND_THREAD to avoid
2100 * this.
2101 */
2102 USB_AUTOPM_GET_INTERFACE_ASYNC(g_probe_info.intf);
2103 #endif /* !USBOS_TX_THREAD */
2104
2105 spin_lock_irqsave(&usbos_info->txlock, flags);
2106
2107 req->arg = txirb;
2108 req->usbinfo = usbos_info;
2109 req->buf_len = 0;
2110
2111 /* Prepare the URB */
2112 if (txirb->pkt != NULL) {
2113 uint32 pktlen;
2114 void *transfer_buf;
2115
2116 /* For multiple packets, allocate contiguous buffer and copy packet data to it */
2117 if (PKTNEXT(usbos_info->pub->osh, txirb->pkt)) {
2118 transfer_buf = MALLOC(usbos_info->pub->osh, buffer_length);
2119 if (!transfer_buf) {
2120 ret = DBUS_ERR_TXDROP;
2121 DBUSERR(("fail to alloc to usb buffer\n"));
2122 goto fail;
2123 }
2124
2125 pkt = txirb->pkt;
2126 txirb->send_buf = transfer_buf;
2127 req->buf_len = buffer_length;
2128
2129 while (pkt) {
2130 pktlen = PKTLEN(usbos_info->pub->osh, pkt);
2131 bcopy(PKTDATA(usbos_info->pub->osh, pkt), transfer_buf, pktlen);
2132 transfer_buf += pktlen;
2133 pkt = PKTNEXT(usbos_info->pub->osh, pkt);
2134 }
2135
2136 ASSERT(((uint8 *) txirb->send_buf + buffer_length) == (transfer_buf));
2137
2138 /* Overwrite buf pointer with pointer to allocated contiguous transfer_buf
2139 */
2140 buf = txirb->send_buf;
2141 }
2142 }
2143
2144 usb_fill_bulk_urb(req->urb, usbos_info->usb, usbos_info->tx_pipe, buf,
2145 buffer_length, (usb_complete_t)dbus_usbos_send_complete, req);
2146
2147 req->urb->transfer_flags |= URB_QUEUE_BULK;
2148
2149 #ifdef USBOS_TX_THREAD
2150 /* Enqueue TX request, the TX thread will resume the bus if needed and submit
2151 * it asynchronously
2152 */
2153 dbus_usbos_qenq(&usbos_info->usbos_tx_list, req, &usbos_info->usbos_tx_list_lock);
2154 if (req_zlp != NULL) {
2155 dbus_usbos_qenq(&usbos_info->usbos_tx_list, req_zlp,
2156 &usbos_info->usbos_tx_list_lock);
2157 }
2158 spin_unlock_irqrestore(&usbos_info->txlock, flags);
2159
2160 wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
2161 return DBUS_OK;
2162 #else
2163 if ((ret = USB_SUBMIT_URB(req->urb))) {
2164 ret = DBUS_ERR_TXDROP;
2165 goto fail;
2166 }
2167
2168 dbus_usbos_qenq(&usbos_info->req_txpostedq, req, &usbos_info->txposted_lock);
2169 atomic_inc(&usbos_info->txposted);
2170
2171 if (req_zlp != NULL) {
2172 if ((ret = USB_SUBMIT_URB(req_zlp->urb))) {
2173 DBUSERR(("failed to submit ZLP URB!\n"));
2174 ASSERT(0);
2175 ret = DBUS_ERR_TXDROP;
2176 goto fail2;
2177 }
2178
2179 dbus_usbos_qenq(&usbos_info->req_txpostedq, req_zlp, &usbos_info->txposted_lock);
2180 /* Also increment txposted for zlp packet, as it will be decremented in
2181 * dbus_usbos_send_complete()
2182 */
2183 atomic_inc(&usbos_info->txposted);
2184 }
2185
2186 spin_unlock_irqrestore(&usbos_info->txlock, flags);
2187 return DBUS_OK;
2188 #endif /* USBOS_TX_THREAD */
2189
2190 fail:
2191 if (txirb->send_buf != NULL) {
2192 MFREE(usbos_info->pub->osh, txirb->send_buf, req->buf_len);
2193 txirb->send_buf = NULL;
2194 req->buf_len = 0;
2195 }
2196 dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
2197 #ifndef USBOS_TX_THREAD
2198 fail2:
2199 #endif
2200 if (req_zlp != NULL) {
2201 dbus_usbos_qenq(&usbos_info->req_txfreeq, req_zlp, &usbos_info->txfree_lock);
2202 }
2203
2204 if (reqs_obtained) {
2205 spin_unlock_irqrestore(&usbos_info->txlock, flags);
2206
2207 #ifndef USBOS_TX_THREAD
2208 /* Enable USB autosuspend if no packets are being sent */
2209 USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
2210 #endif /* !USBOS_TX_THREAD */
2211 }
2212
2213 return ret;
2214 }
2215
2216 /** Higher layer (dbus_usb.c) recycles a received (and used) packet. */
2217 static int
2218 dbus_usbos_intf_recv_irb(void *bus, dbus_irb_rx_t *rxirb)
2219 {
2220 usbos_info_t *usbos_info = (usbos_info_t *) bus;
2221 int ret = DBUS_OK;
2222
2223 if (usbos_info == NULL)
2224 return DBUS_ERR;
2225
2226 ret = dbus_usbos_recv_urb_submit(usbos_info, rxirb, 0);
2227 return ret;
2228 }
2229
2230 static int
2231 dbus_usbos_intf_recv_irb_from_ep(void *bus, dbus_irb_rx_t *rxirb, uint32 ep_idx)
2232 {
2233 usbos_info_t *usbos_info = (usbos_info_t *) bus;
2234 int ret = DBUS_OK;
2235
2236 if (usbos_info == NULL)
2237 return DBUS_ERR;
2238
2239 #ifdef INTR_EP_ENABLE
2240 /* By specifying the ep_idx value of 0xff, the cdc layer is asking to
2241 * submit an interrupt URB
2242 */
2243 if (rxirb == NULL && ep_idx == 0xff) {
2244 /* submit intr URB */
2245 if ((ret = USB_SUBMIT_URB(usbos_info->intr_urb)) < 0) {
2246 DBUSERR(("%s intr USB_SUBMIT_URB failed, status %d\n",
2247 __FUNCTION__, ret));
2248 }
2249 return ret;
2250 }
2251 #else
2252 if (rxirb == NULL) {
2253 return DBUS_ERR;
2254 }
2255 #endif /* INTR_EP_ENABLE */
2256
2257 ret = dbus_usbos_recv_urb_submit(usbos_info, rxirb, ep_idx);
2258 return ret;
2259 }
2260
2261 /** Higher layer (dbus_usb.c) want to cancel an IRB */
2262 static int
2263 dbus_usbos_intf_cancel_irb(void *bus, dbus_irb_tx_t *txirb)
2264 {
2265 usbos_info_t *usbos_info = (usbos_info_t *) bus;
2266
2267 if (usbos_info == NULL)
2268 return DBUS_ERR;
2269
2270 return DBUS_ERR;
2271 }
2272
2273 static int
2274 dbus_usbos_intf_send_ctl(void *bus, uint8 *buf, int len)
2275 {
2276 usbos_info_t *usbos_info = (usbos_info_t *) bus;
2277 int ret = DBUS_OK;
2278 uint16 size;
2279 #ifdef USB_SYNC_CTRL_URB
2280 int status;
2281 #endif /* USB_SYNC_CTRL_URB */
2282
2283 if ((usbos_info == NULL) || (buf == NULL) || (len == 0))
2284 return DBUS_ERR;
2285
2286 if (usbos_info->ctl_tx_urb == NULL)
2287 return DBUS_ERR;
2288
2289 #ifdef USBOS_TX_THREAD
2290 if (usbos_info->ctl_state != USBOS_REQUEST_STATE_UNSCHEDULED) {
2291 return DBUS_ERR_TXCTLFAIL;
2292 }
2293 #else
2294 /* Disable USB autosuspend until this request completes, and request USB resume if needed.
2295 * Because this call runs asynchronously, there is no guarantee the bus is resumed before
2296 * the URB is submitted, and this request might be dropped. Use USB_SUSPEND_THREAD to avoid
2297 * this.
2298 */
2299 USB_AUTOPM_GET_INTERFACE_ASYNC(g_probe_info.intf);
2300 #endif /* USBOS_TX_THREAD */
2301
2302 size = len;
2303 usbos_info->ctl_write.wLength = cpu_to_le16p(&size);
2304 usbos_info->ctl_tx_urb->transfer_buffer_length = size;
2305
2306
2307 #ifdef USB_SYNC_CTRL_URB
2308 #ifdef USBOS_TX_THREAD
2309 usbos_info->ctl_state = USBOS_REQUEST_STATE_SCHEDULED;
2310 #endif
2311
2312 ret = USB_CONTROL_MSG(usbos_info->usb, usbos_info->ctl_out_pipe,
2313 usbos_info->ctl_write.bRequest, usbos_info->ctl_write.bRequestType,
2314 usbos_info->ctl_write.wValue, usbos_info->ctl_write.wIndex,
2315 buf, usbos_info->ctl_write.wLength, USB_CTRL_EP_TIMEOUT);
2316
2317 USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
2318
2319 if (ret < 0) {
2320 DBUSERR(("%s: usb_control_msg failed %d\n", __FUNCTION__, ret));
2321 ret = DBUS_ERR_TXCTLFAIL;
2322 status = DBUS_ERR;
2323 } else {
2324 status = DBUS_OK;
2325 ret = DBUS_OK;
2326 }
2327
2328 #ifdef USBOS_TX_THREAD
2329 usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
2330 #endif
2331 dbus_usbos_ctl_complete(usbos_info, DBUS_CBCTL_WRITE, status);
2332
2333 #else
2334
2335 usb_fill_control_urb(usbos_info->ctl_tx_urb,
2336 usbos_info->usb,
2337 usbos_info->ctl_out_pipe,
2338 (unsigned char *) &usbos_info->ctl_write,
2339 buf, size, (usb_complete_t)dbus_usbos_ctlwrite_complete, usbos_info);
2340
2341 #ifdef USBOS_TX_THREAD
2342 /* Enqueue CTRL request, the TX thread will resume the bus if needed and submit
2343 * it asynchronously
2344 */
2345 usbos_info->ctl_state = USBOS_REQUEST_STATE_SCHEDULED;
2346 wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
2347 #else
2348 if ((ret = USB_SUBMIT_URB(usbos_info->ctl_tx_urb))) {
2349 DBUSERR(("%s: usb_submit_urb failed %d\n", __FUNCTION__, ret));
2350
2351 /* Enable USB autosuspend if no packets are being sent */
2352 USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
2353
2354 return DBUS_ERR_TXCTLFAIL;
2355 }
2356 #endif /* USBOS_TX_THREAD */
2357 ret = DBUS_OK;
2358
2359 #endif /* USB_SYNC_CTRL_URB */
2360
2361 return ret;
2362 }
2363
2364 /** This function does not seem to be called by anyone, including dbus_usb.c */
2365 static int
2366 dbus_usbos_intf_recv_ctl(void *bus, uint8 *buf, int len)
2367 {
2368 usbos_info_t *usbos_info = (usbos_info_t *) bus;
2369 int ret = DBUS_OK;
2370 uint16 size;
2371 #ifdef USBOS_THREAD
2372 unsigned long flags;
2373 #endif /* USBOS_THREAD */
2374 #ifdef USB_SYNC_CTRL_URB
2375 int status;
2376 #endif /* USB_SYNC_CTRL_URB */
2377
2378 if ((usbos_info == NULL) || (buf == NULL) || (len == 0))
2379 return DBUS_ERR;
2380
2381 if (usbos_info->ctl_urb == NULL)
2382 return DBUS_ERR;
2383
2384 #if defined(USBOS_THREAD) && !defined(USB_SYNC_CTRL_URB)
2385 spin_lock_irqsave(&usbos_info->ctrl_lock, flags);
2386 #endif
2387 size = len;
2388 usbos_info->ctl_read.wLength = cpu_to_le16p(&size);
2389 usbos_info->ctl_urb->transfer_buffer_length = size;
2390
2391 if (usbos_info->rxctl_deferrespok) {
2392 /* BMAC model */
2393 usbos_info->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR |
2394 USB_RECIP_INTERFACE;
2395 usbos_info->ctl_read.bRequest = DL_DEFER_RESP_OK;
2396 } else {
2397 /* full dongle model */
2398 usbos_info->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_CLASS |
2399 USB_RECIP_INTERFACE;
2400 usbos_info->ctl_read.bRequest = 1;
2401 }
2402
2403 #ifdef USB_SYNC_CTRL_URB
2404
2405 ret = USB_CONTROL_MSG(usbos_info->usb, usbos_info->ctl_in_pipe,
2406 usbos_info->ctl_read.bRequest, usbos_info->ctl_read.bRequestType,
2407 usbos_info->ctl_read.wValue, usbos_info->ctl_read.wIndex,
2408 buf, usbos_info->ctl_read.wLength, USB_CTRL_EP_TIMEOUT);
2409
2410 if (ret < 0) {
2411 DBUSERR(("%s: usb_control_msg failed %d\n", __FUNCTION__, ret));
2412 ret = DBUS_ERR_RXCTLFAIL;
2413 status = DBUS_ERR;
2414 } else {
2415 ret = DBUS_OK;
2416 status = DBUS_OK;
2417 }
2418
2419 dbus_usbos_ctl_complete(usbos_info, DBUS_CBCTL_READ, status);
2420 #else
2421
2422 usb_fill_control_urb(usbos_info->ctl_urb,
2423 usbos_info->usb,
2424 usbos_info->ctl_in_pipe,
2425 (unsigned char *) &usbos_info->ctl_read,
2426 buf, size, (usb_complete_t)dbus_usbos_ctlread_complete, usbos_info);
2427
2428 ret = USB_SUBMIT_URB(usbos_info->ctl_urb);
2429 #ifdef USBOS_THREAD
2430 spin_unlock_irqrestore(&usbos_info->ctrl_lock, flags);
2431 #endif
2432 if (ret < 0) {
2433 DBUSERR(("%s: usb_submit_urb failed %d\n", __FUNCTION__, ret));
2434 return DBUS_ERR_RXCTLFAIL;
2435 }
2436
2437 #endif /* USB_SYNC_CTRL_URB */
2438 return ret;
2439 }
2440
2441 static int
2442 dbus_usbos_intf_get_attrib(void *bus, dbus_attrib_t *attrib)
2443 {
2444 usbos_info_t *usbos_info = (usbos_info_t *) bus;
2445
2446 if ((usbos_info == NULL) || (attrib == NULL))
2447 return DBUS_ERR;
2448
2449 attrib->bustype = DBUS_USB;
2450 attrib->vid = g_probe_info.vid;
2451 attrib->pid = g_probe_info.pid;
2452 attrib->devid = 0x4322;
2453
2454 attrib->nchan = 1;
2455
2456 /* MaxPacketSize for USB hi-speed bulk out is 512 bytes
2457 * and 64-bytes for full-speed.
2458 * When sending pkt > MaxPacketSize, Host SW breaks it
2459 * up into multiple packets.
2460 */
2461 attrib->mtu = usbos_info->maxps;
2462
2463 return DBUS_OK;
2464 }
2465
2466 /** Called by higher layer (dbus_usb.c) when it wants to 'up' the USB interface to the dongle */
2467 static int
2468 dbus_usbos_intf_up(void *bus)
2469 {
2470 usbos_info_t *usbos_info = (usbos_info_t *) bus;
2471 uint16 ifnum;
2472 #ifdef BCMUSBDEV_COMPOSITE
2473 int wlan_if = 0;
2474 #endif
2475 if (usbos_info == NULL)
2476 return DBUS_ERR;
2477
2478 if (usbos_info->usb == NULL)
2479 return DBUS_ERR;
2480
2481 #if defined(INTR_EP_ENABLE)
2482 /* full dongle use intr EP, bmac doesn't use it */
2483 if (usbos_info->intr_urb) {
2484 int ret;
2485
2486 usb_fill_int_urb(usbos_info->intr_urb, usbos_info->usb,
2487 usbos_info->intr_pipe, &usbos_info->intr,
2488 usbos_info->intr_size, (usb_complete_t)dbus_usbos_intr_complete,
2489 usbos_info, usbos_info->interval);
2490
2491 if ((ret = USB_SUBMIT_URB(usbos_info->intr_urb))) {
2492 DBUSERR(("%s USB_SUBMIT_URB failed with status %d\n", __FUNCTION__, ret));
2493 return DBUS_ERR;
2494 }
2495 }
2496 #endif
2497
2498 if (usbos_info->ctl_urb && usbos_info->ctl_tx_urb) {
2499 usbos_info->ctl_in_pipe = usb_rcvctrlpipe(usbos_info->usb, 0);
2500 usbos_info->ctl_out_pipe = usb_sndctrlpipe(usbos_info->usb, 0);
2501
2502 #ifdef BCMUSBDEV_COMPOSITE
2503 wlan_if = dbus_usbos_intf_wlan(usbos_info->usb);
2504 ifnum = cpu_to_le16(IFDESC(usbos_info->usb, wlan_if).bInterfaceNumber);
2505 #else
2506 ifnum = cpu_to_le16(IFDESC(usbos_info->usb, CONTROL_IF).bInterfaceNumber);
2507 #endif /* BCMUSBDEV_COMPOSITE */
2508 /* CTL Write */
2509 usbos_info->ctl_write.bRequestType =
2510 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
2511 usbos_info->ctl_write.bRequest = 0;
2512 usbos_info->ctl_write.wValue = cpu_to_le16(0);
2513 usbos_info->ctl_write.wIndex = cpu_to_le16p(&ifnum);
2514
2515 /* CTL Read */
2516 usbos_info->ctl_read.bRequestType =
2517 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
2518 usbos_info->ctl_read.bRequest = 1;
2519 usbos_info->ctl_read.wValue = cpu_to_le16(0);
2520 usbos_info->ctl_read.wIndex = cpu_to_le16p(&ifnum);
2521 }
2522
2523 /* Success, indicate usbos_info is fully up */
2524 dbus_usbos_state_change(usbos_info, DBUS_STATE_UP);
2525
2526 return DBUS_OK;
2527 }
2528
2529 static int
2530 dbus_usbos_intf_down(void *bus)
2531 {
2532 usbos_info_t *usbos_info = (usbos_info_t *) bus;
2533
2534 if (usbos_info == NULL)
2535 return DBUS_ERR;
2536
2537 dbusos_stop(usbos_info);
2538 return DBUS_OK;
2539 }
2540
2541 static int
2542 dbus_usbos_intf_stop(void *bus)
2543 {
2544 usbos_info_t *usbos_info = (usbos_info_t *) bus;
2545
2546 if (usbos_info == NULL)
2547 return DBUS_ERR;
2548
2549 dbusos_stop(usbos_info);
2550 return DBUS_OK;
2551 }
2552
2553 #if defined(DBUS_LINUX_HIST)
2554 static void
2555 dbus_usbos_intf_dump(void *bus, struct bcmstrbuf *b)
2556 {
2557 usbos_info_t *usbos_info = (usbos_info_t *) bus;
2558 int i = 0, j = 0, rxposted, txposted;
2559
2560 rxposted = atomic_read(&usbos_info->rxposted);
2561 txposted = atomic_read(&usbos_info->txposted);
2562 if (b) {
2563 bcm_bprintf(b, "\ndbus linux dump\n");
2564 bcm_bprintf(b, "txposted %d rxposted %d\n",
2565 txposted, rxposted);
2566
2567 bcm_bprintf(b, "RXDPC: dpc_cnt %d dpc_pktcnt %d dpc_maxpktcnt %d avg_dpc_pktcnt\n",
2568 usbos_info->dpc_cnt, usbos_info->dpc_pktcnt,
2569 usbos_info->dpc_maxpktcnt, usbos_info->dpc_cnt ?
2570 (usbos_info->dpc_pktcnt/usbos_info->dpc_cnt):1);
2571
2572 /* Histogram */
2573 bcm_bprintf(b, "txposted\n");
2574 } else {
2575 printf("\ndbus linux dump\n");
2576 printf("txposted %d rxposted %d\n",
2577 txposted, rxposted);
2578 printf("RXDPC: dpc_cnt %d dpc_pktcnt %d dpc_maxpktcnt %d avg_dpc_pktcnt %d\n",
2579 usbos_info->dpc_cnt, usbos_info->dpc_pktcnt,
2580 usbos_info->dpc_maxpktcnt, usbos_info->dpc_cnt ?
2581 (usbos_info->dpc_pktcnt/usbos_info->dpc_cnt):1);
2582
2583 /* Histogram */
2584 printf("txposted\n");
2585 }
2586
2587 for (i = 0; i < usbos_info->pub->ntxq; i++) {
2588 if (usbos_info->txposted_hist == NULL) {
2589 break;
2590 }
2591 if (usbos_info->txposted_hist[i]) {
2592 if (b)
2593 bcm_bprintf(b, "%d: %d ", i, usbos_info->txposted_hist[i]);
2594 else
2595 printf("%d: %d ", i, usbos_info->txposted_hist[i]);
2596 j++;
2597 if (j % 10 == 0) {
2598 if (b)
2599 bcm_bprintf(b, "\n");
2600 else
2601 printf("\n");
2602 }
2603 }
2604 }
2605
2606 j = 0;
2607 if (b)
2608 bcm_bprintf(b, "\nrxposted\n");
2609 else
2610 printf("\nrxposted\n");
2611 for (i = 0; i < usbos_info->pub->nrxq; i++) {
2612 if (usbos_info->rxposted_hist == NULL) {
2613 break;
2614 }
2615 if (usbos_info->rxposted_hist[i]) {
2616 if (b)
2617 bcm_bprintf(b, "%d: %d ", i, usbos_info->rxposted_hist[i]);
2618 else
2619 printf("%d: %d ", i, usbos_info->rxposted_hist[i]);
2620 j++;
2621 if (j % 10 == 0) {
2622 if (b)
2623 bcm_bprintf(b, "\n");
2624 else
2625 printf("\n");
2626 }
2627 }
2628 }
2629 if (b)
2630 bcm_bprintf(b, "\n");
2631 else
2632 printf("\n");
2633
2634 return;
2635 }
2636 #endif
2637
2638 /** Called by higher layer (dbus_usb.c) */
2639 static int
2640 dbus_usbos_intf_set_config(void *bus, dbus_config_t *config)
2641 {
2642 int err = DBUS_ERR;
2643 usbos_info_t* usbos_info = bus;
2644
2645 if (config->config_id == DBUS_CONFIG_ID_RXCTL_DEFERRES) {
2646 usbos_info->rxctl_deferrespok = config->rxctl_deferrespok;
2647 err = DBUS_OK;
2648 } else if (config->config_id == DBUS_CONFIG_ID_AGGR_LIMIT) {
2649 #ifndef BCM_FD_AGGR
2650 /* DBUS_CONFIG_ID_AGGR_LIMIT shouldn't be called after probe stage */
2651 ASSERT(disc_arg == NULL);
2652 #endif /* BCM_FD_AGGR */
2653 ASSERT(config->aggr_param.maxrxsf > 0);
2654 ASSERT(config->aggr_param.maxrxsize > 0);
2655 if (config->aggr_param.maxrxsize > usbos_info->rxbuf_len) {
2656 int state = usbos_info->pub->busstate;
2657 dbus_usbos_unlink(&usbos_info->req_rxpostedq, &usbos_info->rxposted_lock);
2658 while (atomic_read(&usbos_info->rxposted)) {
2659 DBUSTRACE(("%s rxposted is %d, delay 1 ms\n", __FUNCTION__,
2660 atomic_read(&usbos_info->rxposted)));
2661 dbus_usbos_wait(usbos_info, 1);
2662 }
2663 usbos_info->rxbuf_len = config->aggr_param.maxrxsize;
2664 dbus_usbos_state_change(usbos_info, state);
2665 }
2666 err = DBUS_OK;
2667 }
2668
2669 return err;
2670 }
2671
2672 /**
2673 * In some cases, the code must submit an URB and wait for its completion.
2674 * Related: dbus_usbos_sync_complete()
2675 */
2676 static int
2677 dbus_usbos_sync_wait(usbos_info_t *usbinfo, uint16 time)
2678 {
2679 int ret;
2680 int err = DBUS_OK;
2681 int ms = time;
2682
2683 ret = wait_event_interruptible_timeout(usbinfo->wait,
2684 usbinfo->waitdone == TRUE, (ms * HZ / 1000));
2685
2686 if ((usbinfo->waitdone == FALSE) || (usbinfo->sync_urb_status)) {
2687 DBUSERR(("%s: timeout(%d) or urb err=0x%x\n",
2688 __FUNCTION__, ret, usbinfo->sync_urb_status));
2689 err = DBUS_ERR;
2690 BCM_REFERENCE(ret);
2691 }
2692 usbinfo->waitdone = FALSE;
2693 return err;
2694 }
2695
2696 /**
2697 * In some cases, the code must submit an URB and wait for its completion.
2698 * Related: dbus_usbos_sync_wait()
2699 */
2700 static void
2701 dbus_usbos_sync_complete(CALLBACK_ARGS)
2702 {
2703 usbos_info_t *usbos_info = (usbos_info_t *)urb->context;
2704
2705 usbos_info->waitdone = TRUE;
2706 wake_up_interruptible(&usbos_info->wait);
2707
2708 usbos_info->sync_urb_status = urb->status;
2709
2710 if (urb->status) {
2711 DBUSERR(("%s: sync urb error %d\n", __FUNCTION__, urb->status));
2712 }
2713 }
2714
2715 /** Called by dbus_usb.c when it wants to download firmware into the dongle */
2716 bool
2717 dbus_usbos_dl_cmd(usbos_info_t *usbinfo, uint8 cmd, void *buffer, int buflen)
2718 {
2719 int ret = DBUS_OK;
2720 char *tmpbuf;
2721 uint16 size;
2722
2723 if ((usbinfo == NULL) || (buffer == NULL) || (buflen == 0))
2724 return FALSE;
2725
2726 if (usbinfo->ctl_urb == NULL)
2727 return FALSE;
2728
2729 tmpbuf = (char *) MALLOC(usbinfo->pub->osh, buflen);
2730 if (!tmpbuf) {
2731 DBUSERR(("%s: Unable to allocate memory \n", __FUNCTION__));
2732 return FALSE;
2733 }
2734
2735 size = buflen;
2736 usbinfo->ctl_urb->transfer_buffer_length = size;
2737
2738 usbinfo->ctl_read.wLength = cpu_to_le16p(&size);
2739 usbinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR |
2740 USB_RECIP_INTERFACE;
2741 usbinfo->ctl_read.bRequest = cmd;
2742
2743 #if defined(BCM_REQUEST_FW)
2744 if (cmd == DL_GO) {
2745 usbinfo->ctl_read.wIndex = 0x1;
2746 }
2747 #endif
2748
2749 #ifdef USB_SYNC_CTRL_URB
2750 ret = USB_CONTROL_MSG(usbinfo->usb, usb_rcvctrlpipe(usbinfo->usb, 0),
2751 usbinfo->ctl_read.bRequest, usbinfo->ctl_read.bRequestType,
2752 usbinfo->ctl_read.wValue, usbinfo->ctl_read.wIndex,
2753 (void *) tmpbuf, usbinfo->ctl_read.wLength, USB_CTRL_EP_TIMEOUT);
2754 #else
2755 usb_fill_control_urb(usbinfo->ctl_urb,
2756 usbinfo->usb,
2757 usb_rcvctrlpipe(usbinfo->usb, 0),
2758 (unsigned char *) &usbinfo->ctl_read,
2759 (void *) tmpbuf, size, (usb_complete_t)dbus_usbos_sync_complete, usbinfo);
2760
2761 ret = USB_SUBMIT_URB(usbinfo->ctl_urb);
2762 #endif
2763
2764 if (ret < 0) {
2765 DBUSERR(("%s: usb_submit_urb failed %d\n", __FUNCTION__, ret));
2766 MFREE(usbinfo->pub->osh, tmpbuf, buflen);
2767 return FALSE;
2768 }
2769
2770 #ifndef USB_SYNC_CTRL_URB
2771 ret = dbus_usbos_sync_wait(usbinfo, USB_SYNC_WAIT_TIMEOUT);
2772 #endif
2773 memcpy(buffer, tmpbuf, buflen);
2774 MFREE(usbinfo->pub->osh, tmpbuf, buflen);
2775 #ifdef USB_SYNC_CTRL_URB
2776 return TRUE;
2777 #else
2778 return (ret == DBUS_OK);
2779 #endif
2780 }
2781
2782 /**
2783 * Called by dbus_usb.c when it wants to download a buffer into the dongle (e.g. as part of the
2784 * download process, when writing nvram variables).
2785 */
2786 int
2787 dbus_write_membytes(usbos_info_t* usbinfo, bool set, uint32 address, uint8 *data, uint size)
2788 {
2789 hwacc_t hwacc;
2790 int write_bytes = 4;
2791 int status;
2792 int retval = 0;
2793
2794 DBUSTRACE(("Enter:%s\n", __FUNCTION__));
2795
2796 /* Read is not supported */
2797 if (set == 0) {
2798 DBUSERR(("Currently read is not supported!!\n"));
2799 return -1;
2800 }
2801
2802 hwacc.cmd = DL_CMD_WRHW;
2803 hwacc.addr = address;
2804
2805 DBUSTRACE(("Address:%x size:%d", hwacc.addr, size));
2806 do {
2807 if (size >= 4) {
2808 write_bytes = 4;
2809 } else if (size >= 2) {
2810 write_bytes = 2;
2811 } else {
2812 write_bytes = 1;
2813 }
2814
2815 hwacc.len = write_bytes;
2816
2817 while (size >= write_bytes) {
2818 hwacc.data = *((unsigned int*)data);
2819
2820 status = USB_CONTROL_MSG(usbinfo->usb, usb_sndctrlpipe(usbinfo->usb, 0),
2821 DL_WRHW, (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE),
2822 1, 0, (char *)&hwacc, sizeof(hwacc_t), USB_CTRL_EP_TIMEOUT);
2823
2824 if (status < 0) {
2825 retval = -1;
2826 DBUSERR((" Ctrl write hwacc failed w/status %d @ address:%x \n",
2827 status, hwacc.addr));
2828 goto err;
2829 }
2830
2831 hwacc.addr += write_bytes;
2832 data += write_bytes;
2833 size -= write_bytes;
2834 }
2835 } while (size > 0);
2836
2837 err:
2838 return retval;
2839 }
2840
2841 int
2842 dbus_usbos_readreg(void *bus, uint32 regaddr, int datalen, uint32 *value)
2843 {
2844 usbos_info_t *usbinfo = (usbos_info_t *) bus;
2845 int ret = DBUS_ERR;
2846 uint32 cmd;
2847 hwacc_t hwacc;
2848 uint16 size = sizeof(hwacc_t);
2849
2850 if (datalen == 1)
2851 cmd = DL_RDHW8;
2852 else if (datalen == 2)
2853 cmd = DL_RDHW16;
2854 else
2855 cmd = DL_RDHW32;
2856
2857 if (usbinfo == NULL)
2858 return ret;
2859
2860 if (usbinfo->ctl_urb == NULL)
2861 return ret;
2862
2863 usbinfo->ctl_urb->transfer_buffer_length = size;
2864
2865 usbinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR |
2866 USB_RECIP_INTERFACE;
2867 usbinfo->ctl_read.bRequest = cmd;
2868 usbinfo->ctl_read.wLength = htol16(size);
2869 usbinfo->ctl_read.wValue = htol16(regaddr & 0xFFFF);
2870 usbinfo->ctl_read.wIndex = htol16(regaddr >> 16);
2871
2872 #ifdef USB_SYNC_CTRL_URB
2873 ret = USB_CONTROL_MSG(usbinfo->usb, usb_rcvctrlpipe(usbinfo->usb, 0),
2874 usbinfo->ctl_read.bRequest, usbinfo->ctl_read.bRequestType,
2875 usbinfo->ctl_read.wValue, usbinfo->ctl_read.wIndex,
2876 (void *) &hwacc, usbinfo->ctl_read.wLength, USB_CTRL_EP_TIMEOUT);
2877
2878 if (ret >= 0) {
2879 *value = hwacc.data;
2880 return DBUS_OK;
2881 }
2882 #else
2883 usb_fill_control_urb(usbinfo->ctl_urb,
2884 usbinfo->usb,
2885 usb_rcvctrlpipe(usbinfo->usb, 0),
2886 (unsigned char *) &usbinfo->ctl_read,
2887 (void *) &hwacc, size, (usb_complete_t)dbus_usbos_sync_complete, usbinfo);
2888
2889 ret = USB_SUBMIT_URB(usbinfo->ctl_urb);
2890 if (ret < 0) {
2891 DBUSERR(("%s: usb_submit_urb failed %d\n", __FUNCTION__, ret));
2892 return ret;
2893 }
2894
2895 ret = dbus_usbos_sync_wait(usbinfo, USB_SYNC_WAIT_TIMEOUT);
2896
2897 if (ret == DBUS_OK) {
2898 *value = hwacc.data;
2899 return ret;
2900 }
2901 #endif /* USB_SYNC_CTRL_URB */
2902
2903 return ret;
2904 }
2905
2906 #ifndef LINUX_POSTMOGRIFY_REMOVAL
2907 int
2908 dbus_usbos_writereg(void *bus, uint32 regaddr, int datalen, uint32 data)
2909 {
2910 usbos_info_t *usbinfo = (usbos_info_t *) bus;
2911 int ret = DBUS_ERR;
2912 uint32 cmd = DL_WRHW;
2913 hwacc_t hwacc;
2914 uint16 size = sizeof(hwacc_t);
2915
2916 if (usbinfo == NULL)
2917 return ret;
2918
2919 if (usbinfo->ctl_urb == NULL)
2920 return ret;
2921
2922 hwacc.cmd = DL_WRHW;
2923 hwacc.addr = regaddr;
2924 hwacc.data = data;
2925 hwacc.len = datalen;
2926
2927 usbinfo->ctl_urb->transfer_buffer_length = size;
2928
2929 usbinfo->ctl_write.bRequestType = USB_DIR_OUT| USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
2930 usbinfo->ctl_write.bRequest = cmd;
2931 usbinfo->ctl_write.wLength = htol16(size);
2932 usbinfo->ctl_write.wValue = htol16(1);
2933 usbinfo->ctl_write.wIndex = htol16(0);
2934
2935 #ifdef USB_SYNC_CTRL_URB
2936 ret = USB_CONTROL_MSG(usbinfo->usb, usb_sndctrlpipe(usbinfo->usb, 0),
2937 usbinfo->ctl_write.bRequest, usbinfo->ctl_write.bRequestType,
2938 usbinfo->ctl_write.wValue, usbinfo->ctl_write.wIndex,
2939 (void *) &hwacc, usbinfo->ctl_write.wLength, USB_CTRL_EP_TIMEOUT);
2940
2941 if (ret < 0) {
2942 DBUSERR(("%s: usb_control_msg failed %d\n", __FUNCTION__, ret));
2943 return ret;
2944 }
2945 ret = DBUS_OK;
2946 #else
2947 usb_fill_control_urb(usbinfo->ctl_urb,
2948 usbinfo->usb,
2949 usb_sndctrlpipe(usbinfo->usb, 0),
2950 (unsigned char *) &usbinfo->ctl_write,
2951 (void *) &hwacc, size, (usb_complete_t)dbus_usbos_sync_complete, usbinfo);
2952
2953 ret = USB_SUBMIT_URB(usbinfo->ctl_urb);
2954 if (ret < 0) {
2955 DBUSERR(("%s: usb_submit_urb failed %d\n", __FUNCTION__, ret));
2956 return ret;
2957 }
2958
2959 ret = dbus_usbos_sync_wait(usbinfo, USB_SYNC_WAIT_TIMEOUT);
2960 #endif /* USB_SYNC_CTRL_URB */
2961 return ret;
2962 }
2963
2964
2965 #endif /* LINUX_POSTMOGRIFY_REMOVAL */
2966
2967 int
2968 dbus_usbos_wait(usbos_info_t *usbinfo, uint16 ms)
2969 {
2970 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
2971 if (in_interrupt())
2972 mdelay(ms);
2973 else
2974 msleep_interruptible(ms);
2975 #else
2976 wait_ms(ms);
2977 #endif
2978 return DBUS_OK;
2979 }
2980
2981 /** Called by dbus_usb.c as part of the firmware download process */
2982 bool
2983 dbus_usbos_dl_send_bulk(usbos_info_t *usbinfo, void *buffer, int len)
2984 {
2985 int ret = DBUS_OK;
2986
2987 #ifdef EHCI_FASTPATH_TX
2988 struct ehci_qtd *qtd = optimize_ehci_qtd_alloc(GFP_KERNEL);
2989 int token = EHCI_QTD_SET_CERR(3);
2990
2991 if (qtd == NULL)
2992 goto fail;
2993
2994 optimize_qtd_fill_with_data(usbinfo->pub, 0, qtd, buffer, token, len);
2995 optimize_submit_async(qtd, 0);
2996 #else
2997 if (usbinfo == NULL)
2998 goto fail;
2999
3000 if (usbinfo->blk_urb == NULL)
3001 goto fail;
3002
3003 /* Prepare the URB */
3004 usb_fill_bulk_urb(usbinfo->blk_urb, usbinfo->usb, usbinfo->tx_pipe, buffer,
3005 len, (usb_complete_t)dbus_usbos_sync_complete, usbinfo);
3006
3007 usbinfo->blk_urb->transfer_flags |= URB_QUEUE_BULK;
3008
3009 if ((ret = USB_SUBMIT_URB(usbinfo->blk_urb))) {
3010 DBUSERR(("%s: usb_submit_urb failed %d\n", __FUNCTION__, ret));
3011 goto fail;
3012 }
3013 #endif /* EHCI_FASTPATH_TX */
3014
3015 ret = dbus_usbos_sync_wait(usbinfo, USB_SYNC_WAIT_TIMEOUT);
3016
3017 return (ret == DBUS_OK);
3018 fail:
3019 return FALSE;
3020 }
3021
3022 static bool
3023 dbus_usbos_intf_recv_needed(void *bus)
3024 {
3025 return FALSE;
3026 }
3027
3028 /**
3029 * Higher layer (dbus_usb.c) wants to execute a function on the condition that the rx spin lock has
3030 * been acquired.
3031 */
3032 static void*
3033 dbus_usbos_intf_exec_rxlock(void *bus, exec_cb_t cb, struct exec_parms *args)
3034 {
3035 usbos_info_t *usbos_info = (usbos_info_t *) bus;
3036 void *ret;
3037 unsigned long flags;
3038
3039 if (usbos_info == NULL)
3040 return NULL;
3041
3042 spin_lock_irqsave(&usbos_info->rxlock, flags);
3043 ret = cb(args);
3044 spin_unlock_irqrestore(&usbos_info->rxlock, flags);
3045
3046 return ret;
3047 }
3048
3049 static void*
3050 dbus_usbos_intf_exec_txlock(void *bus, exec_cb_t cb, struct exec_parms *args)
3051 {
3052 usbos_info_t *usbos_info = (usbos_info_t *) bus;
3053 void *ret;
3054 unsigned long flags;
3055
3056 if (usbos_info == NULL)
3057 return NULL;
3058
3059 spin_lock_irqsave(&usbos_info->txlock, flags);
3060 ret = cb(args);
3061 spin_unlock_irqrestore(&usbos_info->txlock, flags);
3062
3063 return ret;
3064 }
3065
3066 /**
3067 * if an error condition was detected in this module, the higher DBUS layer (dbus_usb.c) has to
3068 * be notified.
3069 */
3070 int
3071 dbus_usbos_errhandler(void *bus, int err)
3072 {
3073 usbos_info_t *usbos_info = (usbos_info_t *) bus;
3074
3075 if (usbos_info == NULL)
3076 return DBUS_ERR;
3077
3078 if (usbos_info->cbarg && usbos_info->cbs) {
3079 if (usbos_info->cbs->errhandler)
3080 usbos_info->cbs->errhandler(usbos_info->cbarg, err);
3081 }
3082
3083 return DBUS_OK;
3084 }
3085
3086 /**
3087 * if a change in bus state was detected in this module, the higher DBUS layer (dbus_usb.c) has to
3088 * be notified.
3089 */
3090 int
3091 dbus_usbos_state_change(void *bus, int state)
3092 {
3093 usbos_info_t *usbos_info = (usbos_info_t *) bus;
3094
3095 if (usbos_info == NULL)
3096 return DBUS_ERR;
3097
3098 if (usbos_info->cbarg && usbos_info->cbs) {
3099 if (usbos_info->cbs->state_change)
3100 usbos_info->cbs->state_change(usbos_info->cbarg, state);
3101 }
3102
3103 usbos_info->pub->busstate = state;
3104 return DBUS_OK;
3105 }
3106
3107 int
3108 dbus_bus_osl_register(int vid, int pid, probe_cb_t prcb,
3109 disconnect_cb_t discb, void *prarg, dbus_intf_t **intf, void *param1, void *param2)
3110 {
3111 bzero(&g_probe_info, sizeof(probe_info_t));
3112
3113 probe_cb = prcb;
3114 disconnect_cb = discb;
3115 probe_arg = prarg;
3116
3117 devid_table[0].idVendor = vid;
3118 devid_table[0].idProduct = pid;
3119
3120 *intf = &dbus_usbos_intf;
3121
3122 USB_REGISTER();
3123
3124 return DBUS_ERR_NODEVICE;
3125 }
3126
3127 int
3128 dbus_bus_osl_deregister()
3129 {
3130 g_probe_info.dereged = TRUE;
3131
3132 if (disconnect_cb && disc_arg && (g_probe_info.disc_cb_done == FALSE)) {
3133 disconnect_cb(disc_arg);
3134 disc_arg = NULL;
3135 }
3136
3137 USB_DEREGISTER();
3138
3139 return DBUS_OK;
3140 }
3141
3142 void *
3143 dbus_usbos_intf_attach(dbus_pub_t *pub, void *cbarg, dbus_intf_callbacks_t *cbs)
3144 {
3145 usbos_info_t *usbos_info;
3146
3147 if (g_probe_info.dldone == FALSE) {
3148 DBUSERR(("%s: err device not downloaded!\n", __FUNCTION__));
3149 return NULL;
3150 }
3151
3152 /* Sanity check for BUS_INFO() */
3153 ASSERT(OFFSETOF(usbos_info_t, pub) == 0);
3154
3155 usbos_info = MALLOC(pub->osh, sizeof(usbos_info_t));
3156 if (usbos_info == NULL)
3157 return NULL;
3158
3159 bzero(usbos_info, sizeof(usbos_info_t));
3160
3161 usbos_info->pub = pub;
3162 usbos_info->cbarg = cbarg;
3163 usbos_info->cbs = cbs;
3164
3165 /* Needed for disconnect() */
3166 g_probe_info.usbos_info = usbos_info;
3167
3168 /* Update USB Info */
3169 usbos_info->usb = g_probe_info.usb;
3170 usbos_info->rx_pipe = g_probe_info.rx_pipe;
3171 usbos_info->rx_pipe2 = g_probe_info.rx_pipe2;
3172 usbos_info->tx_pipe = g_probe_info.tx_pipe;
3173 usbos_info->intr_pipe = g_probe_info.intr_pipe;
3174 usbos_info->intr_size = g_probe_info.intr_size;
3175 usbos_info->interval = g_probe_info.interval;
3176 usbos_info->pub->device_speed = g_probe_info.device_speed;
3177 if (usbos_info->rx_pipe2) {
3178 usbos_info->pub->attrib.has_2nd_bulk_in_ep = 1;
3179 } else {
3180 usbos_info->pub->attrib.has_2nd_bulk_in_ep = 0;
3181 }
3182
3183 if (usbos_info->tx_pipe)
3184 usbos_info->maxps = usb_maxpacket(usbos_info->usb,
3185 usbos_info->tx_pipe, usb_pipeout(usbos_info->tx_pipe));
3186
3187 INIT_LIST_HEAD(&usbos_info->req_rxfreeq);
3188 INIT_LIST_HEAD(&usbos_info->req_txfreeq);
3189 INIT_LIST_HEAD(&usbos_info->req_rxpostedq);
3190 INIT_LIST_HEAD(&usbos_info->req_txpostedq);
3191 spin_lock_init(&usbos_info->rxfree_lock);
3192 spin_lock_init(&usbos_info->txfree_lock);
3193 spin_lock_init(&usbos_info->rxposted_lock);
3194 spin_lock_init(&usbos_info->txposted_lock);
3195 spin_lock_init(&usbos_info->rxlock);
3196 spin_lock_init(&usbos_info->txlock);
3197
3198 atomic_set(&usbos_info->rxposted, 0);
3199 atomic_set(&usbos_info->txposted, 0);
3200
3201 #ifdef DBUS_LINUX_RXDPC
3202 INIT_LIST_HEAD(&usbos_info->req_rxpendingq);
3203 spin_lock_init(&usbos_info->rxpending_lock);
3204 #endif /* DBUS_LINUX_RXDPC */
3205
3206 #if defined(DBUS_LINUX_HIST)
3207 usbos_info->txposted_hist = MALLOC(pub->osh, (usbos_info->pub->ntxq+1) * sizeof(int));
3208 if (usbos_info->txposted_hist) {
3209 bzero(usbos_info->txposted_hist, (usbos_info->pub->ntxq+1) * sizeof(int));
3210 }
3211 usbos_info->rxposted_hist = MALLOC(pub->osh, (usbos_info->pub->nrxq+1) * sizeof(int));
3212 if (usbos_info->rxposted_hist) {
3213 bzero(usbos_info->rxposted_hist, (usbos_info->pub->nrxq+1) * sizeof(int));
3214 }
3215 #endif
3216 #ifdef USB_DISABLE_INT_EP
3217 usbos_info->intr_urb = NULL;
3218 #else
3219 if (!(usbos_info->intr_urb = USB_ALLOC_URB())) {
3220 DBUSERR(("%s: usb_alloc_urb (tx) failed\n", __FUNCTION__));
3221 goto fail;
3222 }
3223 #endif
3224
3225 if (!(usbos_info->ctl_urb = USB_ALLOC_URB())) {
3226 DBUSERR(("%s: usb_alloc_urb (tx) failed\n", __FUNCTION__));
3227 goto fail;
3228 }
3229
3230 if (!(usbos_info->ctl_tx_urb = USB_ALLOC_URB())) {
3231 DBUSERR(("%s: usb_alloc_urb (tx) failed\n", __FUNCTION__));
3232 goto fail;
3233 }
3234
3235 init_waitqueue_head(&usbos_info->wait);
3236
3237 if (!(usbos_info->blk_urb = USB_ALLOC_URB())) { /* for embedded image downloading */
3238 DBUSERR(("%s: usb_alloc_urb (tx) failed\n", __FUNCTION__));
3239 goto fail;
3240 }
3241
3242 usbos_info->rxbuf_len = (uint)usbos_info->pub->rxsize;
3243
3244
3245 #ifdef DBUS_LINUX_RXDPC /* Initialize DPC thread */
3246 sema_init(&usbos_info->dpc_sem, 0);
3247 init_completion(&usbos_info->dpc_exited);
3248 usbos_info->dpc_pid = kernel_thread(dbus_usbos_dpc_thread, usbos_info, 0);
3249 if (usbos_info->dpc_pid < 0) {
3250 DBUSERR(("%s: failed to create dpc thread\n", __FUNCTION__));
3251 goto fail;
3252 }
3253 #endif /* DBUS_LINUX_RXDPC */
3254
3255 atomic_set(&usbos_info->txallocated, 0);
3256 if (DBUS_OK != dbus_usbos_urbreqs_alloc(usbos_info,
3257 usbos_info->pub->ntxq, FALSE)) {
3258 goto fail;
3259 }
3260
3261 atomic_set(&usbos_info->rxallocated, 0);
3262 if (DBUS_OK != dbus_usbos_urbreqs_alloc(usbos_info,
3263 #ifdef CTFPOOL
3264 usbos_info->pub->nrxq,
3265 #else
3266 MIN(DBUS_USB_RXQUEUE_BATCH_ADD, usbos_info->pub->nrxq),
3267 #endif
3268 TRUE)) {
3269 goto fail;
3270 }
3271
3272 #ifdef USBOS_THREAD
3273 if (dbus_usbos_thread_init(usbos_info) == NULL)
3274 goto fail;
3275 #endif /* USBOS_THREAD */
3276
3277 #ifdef USBOS_TX_THREAD
3278 if (dbus_usbos_tx_thread_init(usbos_info) == NULL)
3279 goto fail;
3280 #endif /* USBOS_TX_THREAD */
3281
3282 pub->dev_info = g_probe_info.usb;
3283
3284 #if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX)
3285 spin_lock_init(&usbos_info->fastpath_lock);
3286 if (optimize_init(usbos_info, usbos_info->usb, usbos_info->tx_pipe,
3287 usbos_info->rx_pipe, usbos_info->rx_pipe2) != 0) {
3288 DBUSERR(("%s: optimize_init failed!\n", __FUNCTION__));
3289 goto fail;
3290 }
3291
3292 #endif /* EHCI_FASTPATH_TX || EHCI_FASTPATH_RX */
3293
3294 return (void *) usbos_info;
3295 fail:
3296 #ifdef DBUS_LINUX_RXDPC
3297 if (usbos_info->dpc_pid >= 0) {
3298 KILL_PROC(usbos_info->dpc_pid, SIGTERM);
3299 wait_for_completion(&usbos_info->dpc_exited);
3300 }
3301 #endif /* DBUS_LINUX_RXDPC */
3302 if (usbos_info->intr_urb) {
3303 USB_FREE_URB(usbos_info->intr_urb);
3304 usbos_info->intr_urb = NULL;
3305 }
3306
3307 if (usbos_info->ctl_urb) {
3308 USB_FREE_URB(usbos_info->ctl_urb);
3309 usbos_info->ctl_urb = NULL;
3310 }
3311
3312 if (usbos_info->ctl_tx_urb) {
3313 USB_FREE_URB(usbos_info->ctl_tx_urb);
3314 usbos_info->ctl_tx_urb = NULL;
3315 }
3316
3317 #if defined(BCM_REQUEST_FW)
3318 if (usbos_info->blk_urb) {
3319 USB_FREE_URB(usbos_info->blk_urb);
3320 usbos_info->blk_urb = NULL;
3321 }
3322 #endif
3323
3324 dbus_usbos_urbreqs_free(usbos_info, TRUE);
3325 atomic_set(&usbos_info->rxallocated, 0);
3326 dbus_usbos_urbreqs_free(usbos_info, FALSE);
3327 atomic_set(&usbos_info->txallocated, 0);
3328
3329 g_probe_info.usbos_info = NULL;
3330
3331 MFREE(pub->osh, usbos_info, sizeof(usbos_info_t));
3332 return NULL;
3333
3334 }
3335
3336 void
3337 dbus_usbos_intf_detach(dbus_pub_t *pub, void *info)
3338 {
3339 usbos_info_t *usbos_info = (usbos_info_t *) info;
3340 osl_t *osh = pub->osh;
3341
3342 if (usbos_info == NULL) {
3343 return;
3344 }
3345
3346 #ifdef USBOS_TX_THREAD
3347 dbus_usbos_tx_thread_deinit(usbos_info);
3348 #endif /* USBOS_TX_THREAD */
3349
3350 #if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX)
3351 optimize_deinit(usbos_info, usbos_info->usb);
3352 #endif
3353 /* Must unlink all URBs prior to driver unload;
3354 * otherwise an URB callback can occur after driver
3355 * has been de-allocated and rmmod'd
3356 */
3357 dbusos_stop(usbos_info);
3358
3359 if (usbos_info->intr_urb) {
3360 USB_FREE_URB(usbos_info->intr_urb);
3361 usbos_info->intr_urb = NULL;
3362 }
3363
3364 if (usbos_info->ctl_urb) {
3365 USB_FREE_URB(usbos_info->ctl_urb);
3366 usbos_info->ctl_urb = NULL;
3367 }
3368
3369 if (usbos_info->ctl_tx_urb) {
3370 USB_FREE_URB(usbos_info->ctl_tx_urb);
3371 usbos_info->ctl_tx_urb = NULL;
3372 }
3373
3374 if (usbos_info->blk_urb) {
3375 USB_FREE_URB(usbos_info->blk_urb);
3376 usbos_info->blk_urb = NULL;
3377 }
3378
3379 dbus_usbos_urbreqs_free(usbos_info, TRUE);
3380 atomic_set(&usbos_info->rxallocated, 0);
3381 dbus_usbos_urbreqs_free(usbos_info, FALSE);
3382 atomic_set(&usbos_info->txallocated, 0);
3383
3384 #if defined(DBUS_LINUX_HIST)
3385 if (usbos_info->txposted_hist) {
3386 MFREE(osh, usbos_info->txposted_hist, (usbos_info->pub->ntxq+1) * sizeof(int));
3387 }
3388 if (usbos_info->rxposted_hist) {
3389 MFREE(osh, usbos_info->rxposted_hist, (usbos_info->pub->nrxq+1) * sizeof(int));
3390 }
3391 #endif
3392 #ifdef USBOS_THREAD
3393 dbus_usbos_thread_deinit(usbos_info);
3394 #endif /* USBOS_THREAD */
3395
3396 g_probe_info.usbos_info = NULL;
3397 MFREE(osh, usbos_info, sizeof(usbos_info_t));
3398 }
3399
3400
3401 #ifdef USBOS_TX_THREAD
3402 void*
3403 dbus_usbos_tx_thread_init(usbos_info_t *usbos_info)
3404 {
3405 spin_lock_init(&usbos_info->usbos_tx_list_lock);
3406 INIT_LIST_HEAD(&usbos_info->usbos_tx_list);
3407 init_waitqueue_head(&usbos_info->usbos_tx_queue_head);
3408
3409 usbos_info->usbos_tx_kt = kthread_create(dbus_usbos_tx_thread_func,
3410 usbos_info, "usb-tx-thread");
3411
3412 if (IS_ERR(usbos_info->usbos_tx_kt)) {
3413 DBUSERR(("Thread Creation failed\n"));
3414 return (NULL);
3415 }
3416
3417 usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
3418 wake_up_process(usbos_info->usbos_tx_kt);
3419
3420 return (usbos_info->usbos_tx_kt);
3421 }
3422
3423 void
3424 dbus_usbos_tx_thread_deinit(usbos_info_t *usbos_info)
3425 {
3426 urb_req_t *req;
3427
3428 if (usbos_info->usbos_tx_kt) {
3429 wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
3430 kthread_stop(usbos_info->usbos_tx_kt);
3431 }
3432
3433 /* Move pending requests to free queue so they can be freed */
3434 while ((req = dbus_usbos_qdeq(
3435 &usbos_info->usbos_tx_list, &usbos_info->usbos_tx_list_lock)) != NULL) {
3436 dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
3437 }
3438 }
3439
3440 /**
3441 * Allow USB in-band resume to block by submitting CTRL and DATA URBs in a separate thread.
3442 */
3443 int
3444 dbus_usbos_tx_thread_func(void *data)
3445 {
3446 usbos_info_t *usbos_info = (usbos_info_t *)data;
3447 urb_req_t *req;
3448 dbus_irb_tx_t *txirb;
3449 int ret;
3450 unsigned long flags;
3451
3452 #ifdef WL_THREADNICE
3453 set_user_nice(current, WL_THREADNICE);
3454 #endif
3455
3456 while (1) {
3457 /* Wait until there are URBs to submit */
3458 wait_event_interruptible_timeout(
3459 usbos_info->usbos_tx_queue_head,
3460 !list_empty(&usbos_info->usbos_tx_list) ||
3461 usbos_info->ctl_state == USBOS_REQUEST_STATE_SCHEDULED,
3462 100);
3463
3464 if (kthread_should_stop())
3465 break;
3466
3467 /* Submit CTRL URB if needed */
3468 if (usbos_info->ctl_state == USBOS_REQUEST_STATE_SCHEDULED) {
3469
3470 /* Increment the interface PM usage counter. If the interface was
3471 * suspended, this call blocks until it has been resumed.
3472 */
3473 USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
3474
3475 usbos_info->ctl_state = USBOS_REQUEST_STATE_SUBMITTED;
3476
3477 ret = USB_SUBMIT_URB(usbos_info->ctl_tx_urb);
3478 if (ret != 0) {
3479 DBUSERR(("%s CTRL USB_SUBMIT_URB failed, status %d\n",
3480 __FUNCTION__, ret));
3481
3482 usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
3483
3484 /* Enable USB autosuspend if no packets are being sent */
3485 USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
3486 }
3487 }
3488
3489 /* Submit all available TX URBs */
3490 while ((req = dbus_usbos_qdeq(&usbos_info->usbos_tx_list,
3491 &usbos_info->usbos_tx_list_lock)) != NULL) {
3492
3493 /* Increment the interface PM usage counter. If the interface was
3494 * suspended, this call blocks until it has been resumed.
3495 */
3496 USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
3497
3498 spin_lock_irqsave(&usbos_info->txlock, flags);
3499
3500 ret = USB_SUBMIT_URB(req->urb);
3501 if (ret == 0) {
3502 /* URB submitted successfully */
3503 dbus_usbos_qenq(&usbos_info->req_txpostedq, req,
3504 &usbos_info->txposted_lock);
3505 atomic_inc(&usbos_info->txposted);
3506 } else {
3507 /* Submitting the URB failed. */
3508 DBUSERR(("%s TX USB_SUBMIT_URB failed, status %d\n",
3509 __FUNCTION__, ret));
3510
3511 /* Enable USB autosuspend if no packets are being sent */
3512 USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
3513 }
3514
3515 spin_unlock_irqrestore(&usbos_info->txlock, flags);
3516
3517 if (ret != 0) {
3518 /* Cleanup and notify higher layers */
3519 dbus_usbos_qenq(&usbos_info->req_txfreeq, req,
3520 &usbos_info->txfree_lock);
3521
3522 txirb = req->arg;
3523 if (txirb->send_buf) {
3524 MFREE(usbos_info->pub->osh, txirb->send_buf, req->buf_len);
3525 txirb->send_buf = NULL;
3526 req->buf_len = 0;
3527 }
3528
3529 if (likely (usbos_info->cbarg && usbos_info->cbs)) {
3530 if (likely (usbos_info->cbs->send_irb_complete != NULL))
3531 usbos_info->cbs->send_irb_complete(
3532 usbos_info->cbarg, txirb, DBUS_ERR_TXDROP);
3533 }
3534 }
3535 }
3536 }
3537
3538 return 0;
3539 }
3540 #endif /* USBOS_TX_THREAD */
3541
3542 #ifdef USBOS_THREAD
3543 /**
3544 * Increase system performance by creating a USB thread that runs parallel to other system
3545 * activity.
3546 */
3547 static void*
3548 dbus_usbos_thread_init(usbos_info_t *usbos_info)
3549 {
3550 usbos_list_entry_t *entry;
3551 unsigned long flags, ii;
3552
3553 spin_lock_init(&usbos_info->usbos_list_lock);
3554 spin_lock_init(&usbos_info->ctrl_lock);
3555 INIT_LIST_HEAD(&usbos_info->usbos_list);
3556 INIT_LIST_HEAD(&usbos_info->usbos_free_list);
3557 init_waitqueue_head(&usbos_info->usbos_queue_head);
3558 atomic_set(&usbos_info->usbos_list_cnt, 0);
3559
3560
3561 for (ii = 0; ii < (usbos_info->pub->nrxq + usbos_info->pub->ntxq); ii++) {
3562 entry = MALLOC(usbos_info->pub->osh, sizeof(usbos_list_entry_t));
3563 if (entry) {
3564 spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
3565 list_add_tail((struct list_head*) entry, &usbos_info->usbos_free_list);
3566 spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
3567 } else {
3568 DBUSERR(("Failed to create list\n"));
3569 }
3570 }
3571
3572 usbos_info->usbos_kt = kthread_create(dbus_usbos_thread_func,
3573 usbos_info, "usb-thread");
3574
3575 if (IS_ERR(usbos_info->usbos_kt)) {
3576 DBUSERR(("Thread Creation failed\n"));
3577 return (NULL);
3578 }
3579
3580 wake_up_process(usbos_info->usbos_kt);
3581
3582 return (usbos_info->usbos_kt);
3583 }
3584
3585
3586 static void
3587 dbus_usbos_thread_deinit(usbos_info_t *usbos_info)
3588 {
3589 struct list_head *cur, *next;
3590 usbos_list_entry_t *entry;
3591 unsigned long flags;
3592
3593 if (usbos_info->usbos_kt) {
3594 wake_up_interruptible(&usbos_info->usbos_queue_head);
3595 kthread_stop(usbos_info->usbos_kt);
3596 }
3597
3598 list_for_each_safe(cur, next, &usbos_info->usbos_list)
3599 {
3600 entry = list_entry(cur, struct usbos_list_entry, list);
3601 /* detach this entry from the list and then free the entry */
3602 spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
3603 list_del(cur);
3604 MFREE(usbos_info->pub->osh, entry, sizeof(usbos_list_entry_t));
3605 spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
3606 }
3607
3608 list_for_each_safe(cur, next, &usbos_info->usbos_free_list)
3609 {
3610 entry = list_entry(cur, struct usbos_list_entry, list);
3611 /* detach this entry from the list and then free the entry */
3612 spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
3613 list_del(cur);
3614 MFREE(usbos_info->pub->osh, entry, sizeof(usbos_list_entry_t));
3615 spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
3616 }
3617 }
3618
3619 /** Process completed URBs in a worker thread */
3620 static int
3621 dbus_usbos_thread_func(void *data)
3622 {
3623 usbos_info_t *usbos_info = (usbos_info_t *)data;
3624 usbos_list_entry_t *entry;
3625 struct list_head *cur, *next;
3626 unsigned long flags;
3627
3628 #ifdef WL_THREADNICE
3629 set_user_nice(current, WL_THREADNICE);
3630 #endif
3631
3632 while (1) {
3633 /* If the list is empty, then go to sleep */
3634 wait_event_interruptible_timeout
3635 (usbos_info->usbos_queue_head,
3636 atomic_read(&usbos_info->usbos_list_cnt) > 0,
3637 100);
3638
3639 if (kthread_should_stop())
3640 break;
3641
3642 spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
3643
3644 /* For each entry on the list, process it. Remove the entry from
3645 * the list when done.
3646 */
3647 list_for_each_safe(cur, next, &usbos_info->usbos_list)
3648 {
3649 urb_req_t *req;
3650 int len;
3651 int stat;
3652 usbos_info_t *usbos_info;
3653
3654 entry = list_entry(cur, struct usbos_list_entry, list);
3655 if (entry == NULL)
3656 break;
3657
3658 req = entry->urb_context;
3659 len = entry->urb_length;
3660 stat = entry->urb_status;
3661 usbos_info = req->usbinfo;
3662
3663 /* detach this entry from the list and attach it to the free list */
3664 list_del_init(cur);
3665 spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
3666
3667 dbus_usbos_recv_complete_handle(req, len, stat);
3668
3669 spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
3670
3671 list_add_tail(cur, &usbos_info->usbos_free_list);
3672
3673 atomic_dec(&usbos_info->usbos_list_cnt);
3674 }
3675
3676 spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
3677
3678 }
3679
3680 return 0;
3681 }
3682
3683 /* Called on Linux calling URB callback, see dbus_usbos_recv_complete() */
3684 static void
3685 dbus_usbos_dispatch_schedule(CALLBACK_ARGS)
3686 {
3687 urb_req_t *req = urb->context;
3688 usbos_info_t *usbos_info = req->usbinfo;
3689 usbos_list_entry_t *entry;
3690 unsigned long flags;
3691 struct list_head *cur;
3692
3693 spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
3694
3695 cur = usbos_info->usbos_free_list.next;
3696 entry = list_entry(cur, struct usbos_list_entry, list);
3697
3698 /* detach this entry from the free list and prepare it insert it to use list */
3699 list_del_init(cur);
3700
3701 if (entry) {
3702 entry->urb_context = urb->context;
3703 entry->urb_length = urb->actual_length;
3704 entry->urb_status = urb->status;
3705
3706 atomic_inc(&usbos_info->usbos_list_cnt);
3707 list_add_tail(cur, &usbos_info->usbos_list);
3708 }
3709 else {
3710 DBUSERR(("!!!!!!OUT OF MEMORY!!!!!!!\n"));
3711 }
3712
3713 spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
3714
3715 /* thread */
3716 wake_up_interruptible(&usbos_info->usbos_queue_head);
3717
3718 }
3719
3720 #endif /* USBOS_THREAD */
3721
3722 #ifdef USB_TRIGGER_DEBUG
3723 static bool
3724 dbus_usbos_ctl_send_debugtrig(usbos_info_t* usbinfo)
3725 {
3726 bootrom_id_t id;
3727
3728 if (usbinfo == NULL)
3729 return FALSE;
3730
3731 id.chip = 0xDEAD;
3732
3733 dbus_usbos_dl_cmd(usbinfo, DL_DBGTRIG, &id, sizeof(bootrom_id_t));
3734
3735 /* ignore the result for now */
3736 return TRUE;
3737 }
3738 #endif /* USB_TRIGGER_DEBUG */
3739
3740
3741 #if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX)
3742 /** New optimized code for USB AP */
3743 void inline optimize_ehci_qtd_init(struct ehci_qtd *qtd, dma_addr_t dma)
3744 {
3745 memset(qtd, 0, sizeof(*qtd));
3746 wmb();
3747 qtd->qtd_self = dma;
3748 qtd->qtd_status = cpu_to_le32(EHCI_QTD_HALTED);
3749 qtd->qtd_next = EHCI_NULL;
3750 qtd->qtd_altnext = EHCI_NULL;
3751 qtd->obj_next = NULL;
3752 qtd->rpc = NULL;
3753 /* qtd->buff = NULL; */
3754 qtd->xacterrs = EHCI_QTD_XACTERR_MAX;
3755 wmb();
3756 }
3757
3758 struct ehci_qtd *optimize_ehci_qtd_alloc(gfp_t flags)
3759 {
3760 struct ehci_qtd *qtd;
3761 dma_addr_t dma;
3762
3763 usbos_info_t *usbos_info = g_probe_info.usbos_info;
3764
3765 struct dma_pool *pool = usbos_info->qtd_pool;
3766
3767 qtd = dma_pool_alloc(pool, flags, &dma);
3768 if (qtd != NULL) {
3769 optimize_ehci_qtd_init(qtd, dma);
3770 }
3771 return qtd;
3772 }
3773
3774 void optimize_ehci_qtd_free(struct ehci_qtd *qtd)
3775 {
3776 usbos_info_t *usbos_info = g_probe_info.usbos_info;
3777 struct dma_pool *pool = usbos_info->qtd_pool;
3778 dma_pool_free(pool, qtd, qtd->qtd_self);
3779 }
3780
3781 /*
3782 * Loosely follows qtd_copy_status
3783 * Greatly simplified as there are only three options: normal, short read, and disaster
3784 */
3785 static int BCMFASTPATH get_qtd_status(struct ehci_qtd *qtd, int token, int *actual_length)
3786 {
3787 int status = -EINPROGRESS;
3788
3789 *actual_length += qtd->length - EHCI_QTD_GET_BYTES(token);
3790
3791 /* Short read is not an error */
3792 if (unlikely (SHORT_READ_Q (token)))
3793 status = -EREMOTEIO;
3794
3795 /* Check for serious problems */
3796 if (token & EHCI_QTD_HALTED) {
3797 status = -EPROTO;
3798 if (token & (EHCI_QTD_BABBLE | EHCI_QTD_MISSEDMICRO | EHCI_QTD_BUFERR |
3799 EHCI_QTD_XACTERR))
3800 printk("EHCI Fastpath: Serious USB issue qtd %p token %08x --> status %d\n",
3801 qtd, token, status);
3802 }
3803
3804 return status;
3805
3806 }
3807
3808 static void dump_qtd(struct ehci_qtd *qtd)
3809 {
3810 printk("qtd_next %08x qtd_altnext %08x qtd_status %08x\n", qtd->qtd_next,
3811 qtd->qtd_altnext, qtd->qtd_status);
3812 }
3813
3814 static void dump_qh(struct ehci_qh *qh)
3815 {
3816 struct ehci_qtd *qtd = (struct ehci_qtd *)(qh->qh_curqtd | 0xa0000000);
3817 printk("EHCI Fastpath: QH %p Dump\n", qh);
3818 printk("qtd_next %08x info1 %08x info2 %08x current %08x\n", qh->qh_link, qh->qh_endp,
3819 qh->qh_endphub, qh->qh_curqtd);
3820 printk("overlay\n");
3821 dump_qtd((struct ehci_qtd *)&qh->ow_next);
3822 while ((((int)qtd)&EHCI_NULL) == 0)
3823 {
3824 printk("QTD %p\n", qtd);
3825 dump_qtd((struct ehci_qtd *)qtd);
3826 qtd = (struct ehci_qtd *)(qtd->qtd_next | 0xa0000000);
3827 }
3828 }
3829
3830
3831 /**
3832 * This code assumes the caller holding a lock
3833 * It is currently called from scan_async that should have the lock
3834 * Lock shall be dropped around the actual completion, then reacquired
3835 * This is a clean implementation of the qh_completions()
3836 */
3837 static void BCMFASTPATH ehci_bypass_callback(int pipeindex, struct ehci_qh *qh, spinlock_t *lock)
3838 {
3839 /* Loop variables */
3840 struct ehci_qtd *qtd, /* current QTD */
3841 *end = qh->dummy, /* "afterend" */
3842 *next;
3843 int stopped;
3844
3845 usbos_info_t *usbos_info = g_probe_info.usbos_info;
3846
3847 /* printk("EHCI Fastpath: callback pipe %d QH %p lock %p\n", pipeindex, qh, lock); */
3848
3849 /*
3850 * This code should not require any interlocking with QTD additions
3851 * The additions never touch QH, we should never touch 'end'
3852 * Note that QTD additions will keep 'end' in place
3853 */
3854 for (qtd = qh->first_qtd; qtd != end; qtd = next)
3855 {
3856 u32 status; /* Status bits from QTD */
3857
3858 /* Get the status bits from the QTD */
3859 rmb();
3860 status = hc32_to_cpu(qtd->qtd_status);
3861
3862 if ((status & EHCI_QTD_ACTIVE) == 0) {
3863 if (unlikely((status & EHCI_QTD_HALTED) != 0)) {
3864 /* Retry transaction errors until we
3865 * reach the software xacterr limit
3866 */
3867 if ((status & EHCI_QTD_XACTERR) &&
3868 EHCI_QTD_GET_CERR(status) == 0 &&
3869 --qtd->xacterrs > 0) {
3870 /* Reset the token in the qtd and the
3871 * qh overlay (which still contains
3872 * the qtd) so that we pick up from
3873 * where we left off
3874 */
3875 printk("EHCI Fastpath: detected XactErr "
3876 "qtd %p len %d/%d retry %d\n",
3877 qtd, qtd->length - EHCI_QTD_GET_BYTES(status),
3878 qtd->length,
3879 EHCI_QTD_XACTERR_MAX - qtd->xacterrs);
3880
3881 status &= ~EHCI_QTD_HALTED;
3882 status |= EHCI_QTD_ACTIVE | EHCI_QTD_SET_CERR(3);
3883 qtd->qtd_status = cpu_to_le32(status);
3884 wmb();
3885 qh->ow_status = cpu_to_le32(status);
3886
3887 break;
3888 }
3889
3890 /* QTD processing was aborted - highly unlikely (never seen, so not
3891 * tested). In very new 2.6, we can retry. In 2.4 and older 2.6,
3892 * life sucks (the USB stack does the same)
3893 */
3894 printk("EHCI Fastpath: QTD halted\n");
3895 dump_qh(qh);
3896 stopped = 1;
3897 }
3898 } else
3899 /* Inactive QTD is an afterend, finished the list */
3900 break;
3901
3902 /* Remove the QTD from software QH. This should be done before dropping the lock
3903 * in for upper layer
3904 */
3905 next = qtd->obj_next;
3906 qh->first_qtd = next;
3907
3908 /* Upper layer processing. */
3909 if (EHCI_QTD_GET_PID(status) == 0) /* OUT pipe */
3910 {
3911 if (qtd->rpc == NULL)
3912 {
3913 usbos_info->waitdone = TRUE;
3914 wake_up_interruptible(&usbos_info->wait);
3915 usbos_info->sync_urb_status = 0;
3916 } else {
3917
3918
3919
3920 /* usb_info_t *usb_info = (usb_info_t *) handle; */
3921 usb_info_t *usb_info = (usb_info_t *) usbos_info->cbarg;
3922 /* if(usb_info && usb_info->cbs && usb_info->cbs->send_irb_complete)
3923 * usb_info->cbs->send_irb_complete(usb_info->cbarg, txirb, status);
3924 */
3925
3926 dbus_info_t *dbus_info = (dbus_info_t *)usb_info->cbarg;
3927
3928 /* Free the coalesce buffer, if multi-buffer packet only. Do not
3929 * rely on buff, as it might not even exist
3930 */
3931 if (PKTNEXT(usbos_info->pub->osh, qtd->rpc)) {
3932 /* printk("k-Freeing %p\n", qtd->buff); */
3933 kfree(qtd->buff);
3934 }
3935
3936 if (dbus_info->cbs && dbus_info->cbs->send_complete)
3937 {
3938 atomic_dec(&s_tx_pending);
3939 spin_unlock(lock);
3940 /* printk("Sending to RPC qtd %p\n", qtd); */
3941 #if !(defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_TXNOCOPY) || defined(BCM_RPC_TOC))
3942 #error Configuration not supported; read dbus_if_send_irb_complete for guidelines
3943 #endif
3944 dbus_info->cbs->send_complete(dbus_info->cbarg, qtd->rpc,
3945 0);
3946 if ((atomic_read(&s_tx_pending) < 16) &&
3947 dbus_info->txoff && !dbus_info->txoverride) {
3948 dbus_flowctrl_tx(dbus_info, OFF);
3949 }
3950 spin_lock(lock);
3951
3952 /* Things could have happened while the lock was gone,
3953 * resync to the hardware
3954 */
3955 next = qh->first_qtd;
3956 end = qh->dummy;
3957 }
3958 }
3959
3960 optimize_ehci_qtd_free(qtd);
3961 }
3962 else /* IN pipe */
3963 {
3964 /* Simulates the upstream travel */
3965 usb_info_t *usb_info = (usb_info_t *) usbos_info->cbarg;
3966 dbus_info_t *dbus_info = (dbus_info_t *)usb_info->cbarg;
3967 /* unsigned long flags; */
3968 int actual_length = 0;
3969
3970 /* All our reads must be short */
3971 if (!SHORT_READ_Q (status)) ASSERT(0);
3972
3973 /* Done with hardware, convert status to error codes */
3974 status = get_qtd_status(qtd, status, &actual_length);
3975
3976 switch (status) {
3977 /* success */
3978 case 0:
3979 case -EINPROGRESS:
3980 case -EREMOTEIO:
3981 status = 0;
3982 break;
3983
3984 case -ECONNRESET: /* canceled */
3985 case -ENOENT:
3986 case -EPROTO:
3987 DBUSERR(("%s: ehci unlink. status %x\n", __FUNCTION__, status));
3988 break;
3989 }
3990
3991 if (g_probe_info.dereged) {
3992 printk("%s: DBUS deregistering, ignoring recv callback\n",
3993 __FUNCTION__);
3994 return;
3995 }
3996
3997 dma_unmap_single(
3998 usbos_info->usb->bus->controller,
3999 (dma_addr_t)qtd->qtd_buffer_hi[0],
4000 actual_length,
4001 DMA_FROM_DEVICE);
4002
4003
4004 if (dbus_info->pub.busstate != DBUS_STATE_DOWN) {
4005 if (status == 0) {
4006 void *buf = qtd->rpc;
4007
4008 ASSERT(buf != NULL);
4009 spin_unlock(lock);
4010 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
4011 /* Note that these ifdefs are indirectly coming from
4012 * dbus_usbos_recv_urb_submit The code itself is from
4013 * dbus_if_recv_irb_complete that makes the decision
4014 * at runtime, yet it is only pkt or buf depending on
4015 * the NOCOPY setup, never both :-)
4016 */
4017 if (dbus_info->cbs && dbus_info->cbs->recv_pkt)
4018 dbus_info->cbs->recv_pkt(dbus_info->cbarg, buf);
4019 #else
4020 if (actual_length > 0) {
4021 if (dbus_info->cbs && dbus_info->cbs->recv_buf)
4022 dbus_info->cbs->recv_buf(dbus_info->cbarg,
4023 buf, actual_length);
4024 }
4025 #endif
4026 spin_lock(lock);
4027
4028 /* Things could have happened while the lock was gone,
4029 * resync to the hardware
4030 */
4031 next = qh->first_qtd;
4032 end = qh->dummy;
4033
4034 /* Reinitialize this qtd since it will be reused. */
4035 optimize_ehci_qtd_init(qtd, qtd->qtd_self);
4036
4037 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
4038 /* Note that these ifdefs are coming from
4039 * dbus_usbos_recv_urb_submit. In the NOCOPY configuration,
4040 * force an allocation of a new packet
4041 */
4042 optimize_submit_rx_request(&dbus_info->pub, 1, qtd, NULL);
4043
4044 #else
4045 /* In the copy mode, simply reuse the buffer; upper level
4046 * had already consumed the data
4047 */
4048 optimize_submit_rx_request(&dbus_info->pub, 1, qtd, buf);
4049 #endif
4050 /* Not to free this qtd because it will be reused. */
4051 continue;
4052 }
4053 } else {
4054 printk("%s: DBUS down, ignoring recv callback\n", __FUNCTION__);
4055 }
4056 optimize_ehci_qtd_free(qtd);
4057 }
4058 }
4059 }
4060
4061 static void optimize_urb_callback(struct urb *urb)
4062 {
4063 struct usb_ctrlrequest *req = urb->context;
4064
4065 kfree(req);
4066 USB_FREE_URB(urb);
4067 }
4068
4069 /* Shall be called under an external lock (currently RPC_TP_LOCK) */
4070 static int optimize_submit_urb(struct usb_device *usb, void *ptr, int request)
4071 {
4072 struct usb_ctrlrequest *req;
4073 struct urb *urb;
4074
4075 if ((urb = USB_ALLOC_URB()) == NULL) {
4076 printk("EHCI Fastpath: Error allocating URB in optimize_EP!");
4077 return -ENOMEM;
4078 }
4079
4080 if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
4081 printk("EHCI Fastpath: Failed to allocate memory for control request in"
4082 " optimize_EP!");
4083 USB_FREE_URB(urb);
4084 return -ENOMEM;
4085 }
4086
4087 req->bRequestType = (USB_TYPE_VENDOR | USB_RECIP_OTHER);
4088 req->bRequest = request;
4089
4090 /* Use this instead of a buffer */
4091 req->wValue = ((int)ptr & 0xffff);
4092 req->wIndex = ((((int)ptr)>>16) & 0xffff);
4093 req->wLength = 0;
4094
4095 printk("EHCI Fastpath: usb_dev %p\n", usb);
4096 printk("EHCI Fastpath: bus %p\n", usb->bus);
4097 printk("EHCI Fastpath: Hub %p\n", usb->bus->root_hub);
4098
4099 usb_fill_control_urb(
4100 urb,
4101 usb->bus->root_hub,
4102 usb_sndctrlpipe(usb->bus->root_hub, 0),
4103 (void *)req,
4104 NULL,
4105 0,
4106 optimize_urb_callback,
4107 req);
4108
4109 USB_SUBMIT_URB(urb);
4110
4111 if (urb->status != 0) {
4112 printk("EHCI Fastpath: Cannot submit URB in optimize_EP: %d\n", urb->status);
4113 }
4114
4115 return urb->status;
4116 }
4117
4118 static int epnum(int pipe)
4119 {
4120 int epn = usb_pipeendpoint(pipe);
4121 if (usb_pipein (pipe))
4122 epn |= 0x10;
4123 return epn;
4124 }
4125
4126
4127 static int optimize_init(usbos_info_t *usbos_info, struct usb_device *usb, int out, int in, int in2)
4128 {
4129 int retval = -EPIPE;
4130
4131 atomic_set(&s_tx_pending, 0);
4132 /* atomic_set(&s_rx_pending, 0); */
4133
4134 usbos_info->tx_ep = epnum(out);
4135 usbos_info->rx_ep = epnum(in);
4136 usbos_info->rx2_ep = epnum(in2);
4137 usbos_info->usb_device = usb;
4138
4139 /* printk("EHCI Fastpath: Create pool %p %p %p\n", usb, usb->bus, usb->bus->controller); */
4140
4141 /* QTDs for bulk transfers - separate pool */
4142 usbos_info->qtd_pool = dma_pool_create("usbnet_qtd",
4143 usb->bus->controller,
4144 sizeof(struct ehci_qtd),
4145 EHCI_QTD_ALIGN /* byte alignment (for hw parts) */,
4146 4096 /* can't cross 4K */);
4147 if (!usbos_info->qtd_pool) {
4148 printk("EHCI Fastpath: Cannot create the QTD pool\n");
4149 goto fail;
4150 }
4151
4152 /* detaching the EP */
4153 if (optimize_submit_urb(usb, usb, EHCI_SET_BYPASS_DEV) != 0)
4154 goto fail;
4155 optimize_submit_urb(usb, ehci_bypass_callback, EHCI_SET_BYPASS_CB);
4156 optimize_submit_urb(usb, usbos_info->qtd_pool, EHCI_SET_BYPASS_POOL);
4157 #ifdef EHCI_FASTPATH_TX
4158 optimize_submit_urb(usb, (void*)((0<<16)|usbos_info->tx_ep), EHCI_FASTPATH);
4159 #endif
4160 #ifdef EHCI_FASTPATH_RX
4161 optimize_submit_urb(usb, (void*)((1<<16)|usbos_info->rx_ep), EHCI_FASTPATH);
4162 #endif
4163
4164 /* getting the QH */
4165 printk("EHCI Fastpath: EP in %d EP in2 %d EP out %d\n", usbos_info->rx_ep,
4166 usbos_info->rx2_ep, usbos_info->tx_ep);
4167
4168 return 0;
4169
4170 fail:
4171 return retval;
4172 }
4173
4174 static int optimize_deinit_qtds(struct ehci_qh *qh, int coalesce_buf)
4175 {
4176 usbos_info_t *usbos_info = g_probe_info.usbos_info;
4177 struct ehci_qtd *qtd, *end, *next;
4178 unsigned long flags;
4179
4180 if (qh == NULL)
4181 return 0;
4182
4183 end = qh->dummy;
4184
4185 printk("%s %d. qh = %p\n", __func__, __LINE__, qh);
4186
4187 spin_lock_irqsave(&usbos_info->fastpath_lock, flags);
4188 for (qtd = qh->first_qtd; qtd != end; qtd = next) {
4189 next = qtd->obj_next;
4190 qh->first_qtd = next;
4191
4192 /* Free the coalesce buffer, if multi-buffer packet only. Do not
4193 * rely on buff, as it might not even exist
4194 */
4195 if (coalesce_buf && PKTNEXT(usbos_info->pub->osh, qtd->rpc)) {
4196 printk("k-Freeing %p, ", qtd->buff);
4197 kfree(qtd->buff);
4198 }
4199 printk("freeing qtd %p\n", qtd);
4200
4201 optimize_ehci_qtd_free(qtd);
4202 }
4203 spin_unlock_irqrestore(&usbos_info->fastpath_lock, flags);
4204
4205 return 0;
4206 }
4207
4208
4209 static BCMFASTPATH struct ehci_qh *get_ep(usbos_info_t *usbos_info, int ep)
4210 {
4211 #ifdef KERNEL26
4212 struct usb_host_endpoint *epp = NULL;
4213 switch (ep)
4214 {
4215 case 0: epp = usbos_info->usb_device->ep_out[usbos_info->tx_ep&0xf]; break;
4216 case 1: epp = usbos_info->usb_device->ep_in[usbos_info->rx_ep&0xf]; break;
4217 case 2: epp = usbos_info->usb_device->ep_in[usbos_info->rx2_ep&0xf]; break;
4218 default: ASSERT(0);
4219 }
4220 if (epp != NULL)
4221 return (struct ehci_qh *)epp->hcpriv;
4222 else return NULL;
4223 #else
4224 switch (ep)
4225 {
4226 case 0: return (struct ehci_qh *)(((struct hcd_dev*)(usbos_info->
4227 usb_device->hcpriv))->ep[usbos_info->tx_ep]);
4228 case 1: return (struct ehci_qh *)(((struct hcd_dev*)(usbos_info->
4229 usb_device->hcpriv))->ep[usbos_info->rx_ep]);
4230 case 2: return (struct ehci_qh *)(((struct hcd_dev*)(usbos_info->
4231 usb_device->hcpriv))->ep[usbos_info->rx2_ep]);
4232 default: ASSERT(0);
4233 }
4234 return NULL;
4235 #endif /* KERNEL26 */
4236 }
4237
4238 int optimize_deinit(usbos_info_t *usbos_info, struct usb_device *usb)
4239 {
4240 optimize_deinit_qtds(get_ep(usbos_info, 0), 1);
4241 optimize_deinit_qtds(get_ep(usbos_info, 1), 0);
4242 #if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX)
4243 optimize_submit_urb(usb, (void *)0, EHCI_CLR_EP_BYPASS);
4244 #endif
4245 dma_pool_destroy(usbos_info->qtd_pool);
4246 return 0;
4247 }
4248
4249 /** Reassemble the segmented packet */
4250 static int BCMFASTPATH optimize_gather(const dbus_pub_t *pub, void *pkt, void **buf)
4251 {
4252 int len = 0;
4253
4254 void *transfer_buf = kmalloc(pkttotlen(pub->osh, pkt),
4255 GFP_ATOMIC);
4256 *buf = transfer_buf;
4257
4258 if (!transfer_buf) {
4259 printk("fail to alloc to usb buffer\n");
4260 return 0;
4261 }
4262
4263 while (pkt) {
4264 int pktlen = PKTLEN(pub->osh, pkt);
4265 bcopy(PKTDATA(pub->osh, pkt), transfer_buf, pktlen);
4266 transfer_buf += pktlen;
4267 len += pktlen;
4268 pkt = PKTNEXT(pub->osh, pkt);
4269 }
4270
4271 /* printk("Coalesced a %d-byte buffer\n", len); */
4272
4273 return len;
4274 }
4275
4276 int BCMFASTPATH optimize_qtd_fill_with_rpc(const dbus_pub_t *pub, int epn,
4277 struct ehci_qtd *qtd, void *rpc, int token, int len)
4278 {
4279 void *data = NULL;
4280
4281 if (len == 0)
4282 return optimize_qtd_fill_with_data(pub, epn, qtd, data, token, len);
4283
4284 ASSERT(rpc != NULL);
4285 data = PKTDATA(pub->osh, rpc);
4286 qtd->rpc = rpc;
4287
4288 if (PKTNEXT(pub->osh, rpc)) {
4289 len = optimize_gather(pub, rpc, &data);
4290 qtd->buff = data;
4291 }
4292
4293 return optimize_qtd_fill_with_data(pub, epn, qtd, data, token, len);
4294 }
4295
4296 /** Fill the QTD from the data buffer */
4297 int BCMFASTPATH optimize_qtd_fill_with_data(const dbus_pub_t *pub, int epn,
4298 struct ehci_qtd *qtd, void *data, int token, int len)
4299 {
4300 int i, bytes_fit, page_offset;
4301 dma_addr_t addr = 0;
4302
4303 /* struct usb_host_endpoint *ep = get_ep(epn); */
4304 usbos_info_t *usbos_info = g_probe_info.usbos_info;
4305
4306 token |= (EHCI_QTD_ACTIVE | EHCI_QTD_IOC); /* Allow execution, force interrupt */
4307
4308 if (len > 0) {
4309 addr = dma_map_single(
4310 usbos_info->usb->bus->controller,
4311 data,
4312 len,
4313 EHCI_QTD_GET_PID(token) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
4314 }
4315
4316 qtd->qtd_buffer[0] = cpu_to_hc32((u32)addr);
4317 /* Here qtd->qtd_buffer_hi[0] is leveraged to store addr value, which
4318 * is needed when invoking dma_unmap_single() in ehci_bypass_callback().
4319 * This is valid for EHCI 32bit only.
4320 */
4321 qtd->qtd_buffer_hi[0] = cpu_to_hc32((u32)addr);
4322 page_offset = (addr & (EHCI_PAGE_SIZE-1));
4323 bytes_fit = EHCI_PAGE_SIZE - page_offset;
4324 addr -= page_offset;
4325 if (len < bytes_fit)
4326 bytes_fit = len;
4327 else {
4328 addr += EHCI_PAGE_SIZE;
4329
4330 for (i = 1; bytes_fit < len && i < EHCI_QTD_NBUFFERS; i++) {
4331 qtd->qtd_buffer[i] = cpu_to_hc32((u32)addr);
4332 qtd->qtd_buffer_hi[i] = 0;
4333 addr += EHCI_PAGE_SIZE;
4334 if ((bytes_fit + EHCI_PAGE_SIZE) < len)
4335 bytes_fit += EHCI_PAGE_SIZE;
4336 else
4337 bytes_fit = len;
4338 }
4339
4340 if (bytes_fit != len)
4341 {
4342 ASSERT(0);
4343 }
4344 }
4345 qtd->qtd_status = cpu_to_hc32((bytes_fit << 16) | token);
4346 qtd->length = bytes_fit;
4347
4348 return bytes_fit;
4349 }
4350
4351
4352 /** Reimplementation of qh_append_tds()
4353 * Returns nonzero if too many requests pending
4354 */
4355 int BCMFASTPATH optimize_submit_async(struct ehci_qtd *qtd, int epn)
4356 {
4357 /* Clean implementation along the lines of qh_append_tds() */
4358
4359 struct ehci_qtd *afterend; /* Element at the end of the QTD chain (after the
4360 * last useful one, "after-end")
4361 */
4362 dma_addr_t hw_addr;
4363 __hc32 status;
4364 unsigned long flags;
4365
4366 usbos_info_t *usbos_info = g_probe_info.usbos_info;
4367 struct ehci_qh *qh = get_ep(usbos_info, epn);
4368 usb_info_t *usb_info = (usb_info_t *) usbos_info->cbarg;
4369 dbus_info_t *dbus_info = (dbus_info_t *)usb_info->cbarg;
4370
4371 /* printk("Submit qtd %p to pipe %d (%p)\n", qtd, epn, qh); */
4372 if (qh == NULL)
4373 {
4374 printk("EHCI Fastpath: Attempt of optimized submit to a non-optimized pipe\n");
4375 return -1;
4376 }
4377
4378 spin_lock_irqsave(&usbos_info->fastpath_lock, flags);
4379
4380 /* Limit outstanding - for rpc behavior only */
4381 /* printk("QH qtd_status %08x\n", qh->hw->qtd_status); */
4382
4383 if ((qtd->qtd_status & (1<<8)) == 0)
4384 {
4385 atomic_inc(&s_tx_pending);
4386 if (atomic_read(&s_tx_pending) > 16*2) /* (dbus_info->tx_low_watermark * 3)) */
4387 dbus_flowctrl_tx(dbus_info, TRUE);
4388 }
4389
4390 ASSERT(qh != NULL);
4391
4392
4393 /*
4394 * Standard list processing trick:
4395 * * old "afterend" is filled with the incoming data while still HALTed
4396 * * new element is appended and prepared to serve as new afterend
4397 * * now old afterend is activated
4398 * This way, HW never races the SW - no semaphores are necessary, as long as this function
4399 * is not reentered for the same QH
4400 */
4401
4402 /* Make new QTD to be HALTed, wait for it to actually happen */
4403 status = qtd->qtd_status;
4404 qtd->qtd_status = cpu_to_le32(EHCI_QTD_HALTED);
4405 wmb();
4406
4407 /* Now copy all information from the new QTD to the old afterend,
4408 * except the own HW address
4409 */
4410 afterend = qh->dummy;
4411 hw_addr = afterend->qtd_self;
4412 *afterend = *qtd;
4413 afterend->qtd_self = hw_addr;
4414
4415 /* The new QTD is ready to serve as a new afterend, append it */
4416 qh->dummy = qtd;
4417 afterend->qtd_next = qtd->qtd_self;
4418 afterend->qtd_altnext = qtd->qtd_self; /* Always assume short read. Harmless in our case */
4419 afterend->obj_next = qtd;
4420
4421 /* Wait for writes to happen and enable the old afterend (now containing the QTD data) */
4422 wmb();
4423 afterend->qtd_status = status;
4424 wmb();
4425
4426 spin_unlock_irqrestore(&usbos_info->fastpath_lock, flags);
4427
4428 return 0;
4429 }
4430
4431 void BCMFASTPATH optimize_submit_rx_request(const dbus_pub_t *pub, int epn, struct ehci_qtd *qtd_in,
4432 void *buf)
4433 {
4434 usbos_info_t *usbos_info = g_probe_info.usbos_info;
4435 int len = usbos_info->rxbuf_len;
4436 void *pkt;
4437 struct ehci_qtd *qtd;
4438 int token = EHCI_QTD_SET_CERR(3) | EHCI_QTD_SET_PID(1);
4439
4440 if (qtd_in == NULL) {
4441 qtd = optimize_ehci_qtd_alloc(GFP_KERNEL);
4442 if (!qtd) {
4443 printk("EHCI Fastpath: Out of QTDs\n");
4444 return;
4445 }
4446 }
4447 else
4448 qtd = qtd_in;
4449
4450 if (buf == NULL)
4451 {
4452 /* NOCOPY, allocate own packet */
4453 /* Follow dbus_usbos_recv_urb_submit */
4454 pkt = PKTGET(usbos_info->pub->osh, len, FALSE);
4455 if (pkt == NULL) {
4456 printk("%s: PKTGET failed\n", __FUNCTION__);
4457 optimize_ehci_qtd_free(qtd);
4458 return;
4459 }
4460 /* consider the packet "native" so we don't count it as MALLOCED in the osl */
4461 PKTTONATIVE(usbos_info->pub->osh, pkt);
4462 qtd->rpc = pkt;
4463 buf = PKTDATA(usbos_info->pub->osh, pkt);
4464
4465 }
4466 else
4467 qtd->rpc = buf;
4468
4469 optimize_qtd_fill_with_data(pub, epn, qtd, buf, token, len);
4470 optimize_submit_async(qtd, epn);
4471 }
4472 #endif /* EHCI_FASTPATH_TX || EHCI_FASTPATH_RX */
4473
4474 #ifdef BCM_REQUEST_FW
4475 static int
4476 get_file_buf(char *file_path, char **filebuf, int *filelen)
4477 {
4478 int tmp_len;
4479 struct file *fp;
4480
4481 DBUSINFO(("File path = %s %d \n", file_path, strlen(file_path)));
4482
4483 fp = osl_os_open_image(file_path);
4484 if (fp == NULL) {
4485 DBUSERR(("%s: file is Not exist \n", __FUNCTION__));
4486 return DBUS_ERR;
4487 }
4488 *filelen = osl_os_image_size(fp);
4489 *filebuf = vmalloc(*filelen);
4490 if (*filebuf == NULL) {
4491 *filelen = 0;
4492 DBUSERR(("%s: filebuf alloc fail \n", __FUNCTION__));
4493 return DBUS_ERR;
4494 }
4495
4496 tmp_len = osl_os_get_image_block(*filebuf, *filelen, fp);
4497 if (tmp_len != *filelen) {
4498 DBUSERR(("%s: file get fail \n", __FUNCTION__));
4499 vfree(*filebuf);
4500 return DBUS_ERR;
4501 }
4502
4503 osl_os_close_image(fp);
4504
4505 if (*filelen == 0) {
4506 return DBUS_ERR;
4507 }
4508
4509 return DBUS_OK;
4510 }
4511
4512
4513 void *
4514 dbus_get_fw_nvfile(int devid, int chiprev, uint8 **fw, int *fwlen, int type, uint16 boardtype,
4515 uint16 boardrev)
4516 {
4517 s8 fw_name[64];
4518 const struct firmware *firmware = NULL;
4519 char * filebuf;
4520 int filelen;
4521 int err;
4522
4523 strncpy(fw_name, "brcm/bcm", FW_NAME_PREFIX_LEN);
4524 fw_name[FW_NAME_PREFIX_LEN] = '\0';
4525 if (type == DBUS_FIRMWARE) {
4526 switch (devid) {
4527 case BCM4350_CHIP_ID:
4528 case BCM4354_CHIP_ID:
4529 case BCM43556_CHIP_ID:
4530 case BCM43558_CHIP_ID:
4531 case BCM43566_CHIP_ID:
4532 case BCM43568_CHIP_ID:
4533 case BCM43570_CHIP_ID:
4534 case BCM4358_CHIP_ID:
4535 strcat(fw_name, "4350");
4536 break;
4537 case BCM43143_CHIP_ID:
4538 strcat(fw_name, "43143");
4539 break;
4540 case BCM43234_CHIP_ID:
4541 case BCM43235_CHIP_ID:
4542 case BCM43236_CHIP_ID:
4543 strcat(fw_name, "43236");
4544 break;
4545 case BCM43242_CHIP_ID:
4546 strcat(fw_name, "43242");
4547 break;
4548 case BCM43238_CHIP_ID:
4549 strcat(fw_name, "43238");
4550 break;
4551 case BCM43526_CHIP_ID:
4552 strcat(fw_name, "43526");
4553 break;
4554 case BCM43569_CHIP_ID:
4555 strcat(fw_name, "43569");
4556 switch (chiprev) {
4557 case 0:
4558 strcat(fw_name, "a0");
4559 break;
4560 case 2:
4561 strcat(fw_name, "a2");
4562 break;
4563 default:
4564 break;
4565 }
4566 break;
4567 default:
4568 DBUSERR(("unsupported device %x\n", devid));
4569 return NULL;
4570 }
4571
4572 strcat(fw_name, "-firmware.bin");
4573 if (firmware_path[0] != '\0') {
4574 filebuf = NULL;
4575 filelen = 0;
4576
4577 snprintf(fw_name, sizeof(fw_name), "%s%s", firmware_path, fw_name);
4578 err = get_file_buf(fw_name, &filebuf, &filelen);
4579 if (err) {
4580 DBUSERR(("fail to request firmware %s\n", fw_name));
4581 return NULL;
4582 }
4583
4584 if ((filebuf != NULL) && (filelen != 0)) {
4585 *fw = (uint8 *)filebuf;
4586 *fwlen = filelen;
4587 } else {
4588 return NULL;
4589 }
4590 } else {
4591 /* load firmware */
4592 err = request_firmware(&firmware, fw_name, &g_probe_info.usb->dev);
4593 if (err) {
4594 DBUSERR(("fail to request firmware %s\n", fw_name));
4595 return NULL;
4596 }
4597 }
4598 } else {
4599 switch (devid) {
4600 case BCM4350_CHIP_ID:
4601 case BCM4354_CHIP_ID:
4602 case BCM43556_CHIP_ID:
4603 case BCM43558_CHIP_ID:
4604 case BCM43566_CHIP_ID:
4605 case BCM43568_CHIP_ID:
4606 case BCM43570_CHIP_ID:
4607 case BCM4358_CHIP_ID:
4608 strcat(fw_name, "4350");
4609 break;
4610 case BCM43143_CHIP_ID:
4611 strcat(fw_name, "43143");
4612 break;
4613 case BCM43234_CHIP_ID:
4614 strcat(fw_name, "43234");
4615 break;
4616 case BCM43235_CHIP_ID:
4617 strcat(fw_name, "43235");
4618 break;
4619 case BCM43236_CHIP_ID:
4620 strcat(fw_name, "43236");
4621 break;
4622 case BCM43238_CHIP_ID:
4623 strcat(fw_name, "43238");
4624 break;
4625 case BCM43242_CHIP_ID:
4626 strcat(fw_name, "43242");
4627 break;
4628 case BCM43526_CHIP_ID:
4629 strcat(fw_name, "43526");
4630 break;
4631 case BCM43569_CHIP_ID:
4632 strcat(fw_name, "43569");
4633 switch (chiprev) {
4634 case 0:
4635 strcat(fw_name, "a0");
4636 break;
4637 case 2:
4638 strcat(fw_name, "a2");
4639 break;
4640 default:
4641 break;
4642 }
4643 break;
4644 default:
4645 DBUSERR(("unsupported device %x\n", devid));
4646 return NULL;
4647 }
4648
4649 /* load board specific nvram file */
4650 snprintf(fw_name, sizeof(fw_name), "%s-%2x-%2x.nvm", fw_name,
4651 boardtype, boardrev);
4652 fw_name[strlen(fw_name)] = '\0';
4653
4654 if (nvram_path[0] != '\0') {
4655 filebuf = NULL;
4656 filelen = 0;
4657 err = get_file_buf(fw_name, &filebuf, &filelen);
4658 if (err) {
4659 snprintf(fw_name, sizeof(fw_name), "%s%s.nvm",
4660 nvram_path, fw_name);
4661 fw_name[strlen(fw_name)] = '\0';
4662 err = get_file_buf(fw_name, &filebuf, &filelen);
4663 if (err) {
4664 DBUSERR(("fail to get firmware %s\n", fw_name));
4665 return NULL;
4666 }
4667 }
4668
4669 if ((filebuf != NULL) && (filelen != 0)) {
4670 *fw = (uint8 *)filebuf;
4671 *fwlen = filelen;
4672 } else {
4673 return NULL;
4674 }
4675
4676 } else {
4677 err = request_firmware(&firmware, fw_name, &g_probe_info.usb->dev);
4678 if (err) {
4679 /* board specific file missing - load the generic nvram file */
4680 snprintf(fw_name, sizeof(fw_name), "%s.nvm", fw_name);
4681 err = request_firmware(&firmware, fw_name,
4682 &g_probe_info.usb->dev);
4683 if (err) {
4684 return NULL;
4685 }
4686 }
4687 }
4688 }
4689
4690 if ((nvram_path[0] != '\0') || (firmware_path[0] != '\0'))
4691 return NULL;
4692
4693 if (firmware == NULL) {
4694 return NULL;
4695 }
4696
4697 *fwlen = firmware->size;
4698 *fw = (uint8 *)firmware->data;
4699
4700 return (void *)firmware;
4701 }
4702
4703 void
4704 dbus_release_fw_nvfile(void *firmware)
4705 {
4706 release_firmware((struct firmware *)firmware);
4707 }
4708 #endif /* #ifdef BCM_REQUEST_FW */
4709
4710 /** For a composite device the interface order is not guaranteed,
4711 * scan the device struct for the WLAN interface
4712 */
4713 #ifdef BCMUSBDEV_COMPOSITE
4714 static int
4715 dbus_usbos_intf_wlan(struct usb_device *usb)
4716 {
4717 int i, num_of_eps, ep, intf_wlan = -1;
4718 int num_intf = CONFIGDESC(usb)->bNumInterfaces;
4719 struct usb_endpoint_descriptor *endpoint;
4720
4721 for (i = 0; i < num_intf; i++) {
4722 if (IFDESC(usb, i).bInterfaceClass != USB_CLASS_VENDOR_SPEC)
4723 continue;
4724 num_of_eps = IFDESC(usb, i).bNumEndpoints;
4725
4726 for (ep = 0; ep < num_of_eps; ep++) {
4727 endpoint = &IFEPDESC(usb, i, ep);
4728 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
4729 USB_ENDPOINT_XFER_BULK) {
4730 intf_wlan = i;
4731 break;
4732 }
4733 }
4734 if (ep < num_of_eps)
4735 break;
4736 }
4737
4738 return intf_wlan;
4739 }
4740 #endif /* BCMUSBDEV_COMPOSITE */