• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Dongle BUS interface
4  * USB Linux Implementation
5  *
6  * Copyright (C) 1999-2016, Broadcom Corporation
7  *
8  *      Unless you and Broadcom execute a separate written software license
9  * agreement governing use of this software, this software is licensed to you
10  * under the terms of the GNU General Public License version 2 (the "GPL"),
11  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
12  * following added to such license:
13  *
14  *      As a special exception, the copyright holders of this software give you
15  * permission to link this software with independent modules, and to copy and
16  * distribute the resulting executable under terms of your choice, provided that
17  * you also meet, for each linked independent module, the terms and conditions of
18  * the license of that module.  An independent module is a module which is not
19  * derived from this software.  The special exception does not apply to any
20  * modifications of the software.
21  *
22  *      Notwithstanding the above, under no circumstances may you combine this
23  * software in any way with any other Broadcom software provided under a license
24  * other than the GPL, without Broadcom's express prior written consent.
25  *
26  *
27  * <<Broadcom-WL-IPTag/Open:>>
28  *
29  * $Id: dbus_usb_linux.c 564663 2015-06-18 02:34:42Z $
30  */
31 
32 /**
33  * @file @brief
34  * This file contains DBUS code that is USB *and* OS (Linux) specific. DBUS is a Broadcom
35  * proprietary host specific abstraction layer.
36  */
37 
38 #include <typedefs.h>
39 #include <osl.h>
40 
41 /**
42  * DBUS_LINUX_RXDPC is created for router platform performance tuning. A separate thread is created
43  * to handle USB RX and avoid the call chain getting too long and enhance cache hit rate.
44  *
45  * DBUS_LINUX_RXDPC setting is in wlconfig file.
46  */
47 
48 /*
49  * If DBUS_LINUX_RXDPC is off, spin_lock_bh() for CTFPOOL in
50  * linux_osl.c has to be changed to spin_lock_irqsave() because
51  * PKTGET/PKTFREE are no longer in bottom half.
52  *
53  * Right now we have another queue rpcq in wl_linux.c. Maybe we
54  * can eliminate that one to reduce the overhead.
55  *
56  * Enabling 2nd EP and DBUS_LINUX_RXDPC causing traffic from
57  * both EP's to be queued in the same rx queue. If we want
58  * RXDPC to work with 2nd EP. The EP for RPC call return
59  * should bypass the dpc and go directly up.
60  */
61 
62 /* #define DBUS_LINUX_RXDPC */
63 
64 /* Dbus histogram for ntxq, nrxq, dpc parameter tuning */
65 /* #define DBUS_LINUX_HIST */
66 
67 #include <usbrdl.h>
68 #include <bcmendian.h>
69 #include <linux/init.h>
70 #include <linux/kernel.h>
71 #include <linux/slab.h>
72 #include <linux/usb.h>
73 #include <linux/skbuff.h>
74 #include <linux/netdevice.h>
75 #include <linux/random.h>
76 #include <linux/spinlock.h>
77 #include <linux/list.h>
78 #include <linux/uaccess.h>
79 #include <asm/unaligned.h>
80 #include <dbus.h>
81 #include <bcmutils.h>
82 #include <bcmdevs.h>
83 #include <linux/usb.h>
84 #include <usbrdl.h>
85 #include <linux/firmware.h>
86 #include <dngl_stats.h>
87 #include <dhd.h>
88 
89 #if defined(USBOS_THREAD) || defined(USBOS_TX_THREAD)
90 
91 /**
92  * The usb-thread is designed to provide currency on multiprocessors and SMP linux kernels. On the
93  * dual cores platform, the WLAN driver, without threads, executed only on CPU0. The driver consumed
94  * almost of 100% on CPU0, while CPU1 remained idle. The behavior was observed on Broadcom's STB.
95  *
96  * The WLAN driver consumed most of CPU0 and not CPU1 because tasklets/queues, software irq, and
97  * hardware irq are executing from CPU0, only. CPU0 became the system's bottle-neck. TPUT is lower
98  * and system's responsiveness is slower.
99  *
100  * To improve system responsiveness and TPUT usb-thread was implemented. The system's threads could
101  * be scheduled to run on any core. One core could be processing data in the usb-layer and the other
102  * core could be processing data in the wl-layer.
103  *
104  * For further info see [WlThreadAndUsbThread] Twiki.
105  */
106 
107 #include <linux/kthread.h>
108 #include <linux/interrupt.h>
109 #include <linux/irq.h>
110 #include <asm/hardirq.h>
111 #include <linux/list.h>
112 #include <linux_osl.h>
113 #endif /* USBOS_THREAD || USBOS_TX_THREAD */
114 
115 
116 
117 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
118 #define KERNEL26
119 #endif
120 
121 /**
122  * Starting with the 3.10 kernel release, dynamic PM support for USB is present whenever
123  * the kernel was built with CONFIG_PM_RUNTIME enabled. The CONFIG_USB_SUSPEND option has
124  * been eliminated.
125  */
126 #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21)) && defined(CONFIG_USB_SUSPEND)) \
127 	|| ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) && defined(CONFIG_PM_RUNTIME))
128 /* For USB power management support, see Linux kernel: Documentation/usb/power-management.txt */
129 #define USB_SUSPEND_AVAILABLE
130 #endif
131 
132 /* Define alternate fw/nvram paths used in Android */
133 #ifdef OEM_ANDROID
134 #define CONFIG_ANDROID_BCMDHD_FW_PATH "broadcom/dhd/firmware/fw.bin.trx"
135 #define CONFIG_ANDROID_BCMDHD_NVRAM_PATH "broadcom/dhd/nvrams/nvm.txt"
136 #endif /* OEM_ANDROID */
137 
usb_submit_urb_linux(struct urb * urb)138 static inline int usb_submit_urb_linux(struct urb *urb)
139 {
140 
141 #ifdef BCM_MAX_URB_LEN
142 	if (urb && (urb->transfer_buffer_length > BCM_MAX_URB_LEN)) {
143 		DBUSERR(("URB transfer length=%d exceeded %d ra=%p\n", urb->transfer_buffer_length,
144 		BCM_MAX_URB_LEN, __builtin_return_address(0)));
145 		return DBUS_ERR;
146 	}
147 #endif
148 
149 #ifdef KERNEL26
150 	return usb_submit_urb(urb, GFP_ATOMIC);
151 #else
152 	return usb_submit_urb(urb);
153 #endif
154 
155 }
156 
157 #define USB_SUBMIT_URB(urb) usb_submit_urb_linux(urb)
158 
159 #ifdef KERNEL26
160 
161 #define USB_ALLOC_URB()				usb_alloc_urb(0, GFP_ATOMIC)
162 #define USB_UNLINK_URB(urb)			(usb_kill_urb(urb))
163 #define USB_FREE_URB(urb)			(usb_free_urb(urb))
164 #define USB_REGISTER()				usb_register(&dbus_usbdev)
165 #define USB_DEREGISTER()			usb_deregister(&dbus_usbdev)
166 
167 #ifdef USB_SUSPEND_AVAILABLE
168 
169 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33))
170 #define USB_AUTOPM_SET_INTERFACE(intf)		usb_autopm_set_interface(intf)
171 #else
172 #define USB_ENABLE_AUTOSUSPEND(udev)		usb_enable_autosuspend(udev)
173 #define USB_DISABLE_AUTOSUSPEND(udev)       usb_disable_autosuspend(udev)
174 #endif  /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33))  */
175 
176 #define USB_AUTOPM_GET_INTERFACE(intf)		usb_autopm_get_interface(intf)
177 #define USB_AUTOPM_PUT_INTERFACE(intf)		usb_autopm_put_interface(intf)
178 #define USB_AUTOPM_GET_INTERFACE_ASYNC(intf)	usb_autopm_get_interface_async(intf)
179 #define USB_AUTOPM_PUT_INTERFACE_ASYNC(intf)	usb_autopm_put_interface_async(intf)
180 #define USB_MARK_LAST_BUSY(dev)			usb_mark_last_busy(dev)
181 
182 #else /* USB_SUSPEND_AVAILABLE */
183 
184 #define USB_AUTOPM_GET_INTERFACE(intf)		do {} while (0)
185 #define USB_AUTOPM_PUT_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_BULK_MSG(dev, pipe, data, len, actual_length, timeout) \
195 	usb_bulk_msg((dev), (pipe), (data), (len), (actual_length), (timeout))
196 #define USB_BUFFER_ALLOC(dev, size, mem, dma)	usb_buffer_alloc(dev, size, mem, dma)
197 #define USB_BUFFER_FREE(dev, size, data, dma)	usb_buffer_free(dev, size, data, dma)
198 
199 #ifdef WL_URB_ZPKT
200 #define URB_QUEUE_BULK   URB_ZERO_PACKET
201 #else
202 #define URB_QUEUE_BULK   0
203 #endif /* WL_URB_ZPKT */
204 
205 #define CALLBACK_ARGS		struct urb *urb, struct pt_regs *regs
206 #define CALLBACK_ARGS_DATA	urb, regs
207 #define CONFIGDESC(usb)		(&((usb)->actconfig)->desc)
208 #define IFPTR(usb, idx)		((usb)->actconfig->interface[idx])
209 #define IFALTS(usb, idx)	(IFPTR((usb), (idx))->altsetting[0])
210 #define IFDESC(usb, idx)	IFALTS((usb), (idx)).desc
211 #define IFEPDESC(usb, idx, ep)	(IFALTS((usb), (idx)).endpoint[ep]).desc
212 
213 #else /* KERNEL26 */
214 
215 #define USB_ALLOC_URB()				usb_alloc_urb(0)
216 #define USB_UNLINK_URB(urb)			usb_unlink_urb(urb)
217 #define USB_FREE_URB(urb)			(usb_free_urb(urb))
218 #define USB_REGISTER()				usb_register(&dbus_usbdev)
219 #define USB_DEREGISTER()			usb_deregister(&dbus_usbdev)
220 #define USB_AUTOPM_GET_INTERFACE(intf)		do {} while (0)
221 #define USB_AUTOPM_GET_INTERFACE_ASYNC(intf)	do {} while (0)
222 #define USB_AUTOPM_PUT_INTERFACE_ASYNC(intf)	do {} while (0)
223 #define USB_MARK_LAST_BUSY(dev)			do {} while (0)
224 
225 #define USB_CONTROL_MSG(dev, pipe, request, requesttype, value, index, data, size, timeout) \
226 	usb_control_msg((dev), (pipe), (request), (requesttype), (value), (index), \
227 	(data), (size), (timeout))
228 #define USB_BUFFER_ALLOC(dev, size, mem, dma)  kmalloc(size, mem)
229 #define USB_BUFFER_FREE(dev, size, data, dma)  kfree(data)
230 
231 #ifdef WL_URB_ZPKT
232 #define URB_QUEUE_BULK   USB_QUEUE_BULK|URB_ZERO_PACKET
233 #else
234 #define URB_QUEUE_BULK   0
235 #endif /*  WL_URB_ZPKT */
236 
237 #define CALLBACK_ARGS		struct urb *urb
238 #define CALLBACK_ARGS_DATA	urb
239 #define CONFIGDESC(usb)		((usb)->actconfig)
240 #define IFPTR(usb, idx)		(&(usb)->actconfig->interface[idx])
241 #define IFALTS(usb, idx)	((usb)->actconfig->interface[idx].altsetting[0])
242 #define IFDESC(usb, idx)	IFALTS((usb), (idx))
243 #define IFEPDESC(usb, idx, ep)	(IFALTS((usb), (idx)).endpoint[ep])
244 
245 
246 #endif /* KERNEL26 */
247 
248 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
249 #define USB_SPEED_SUPER		5
250 #endif  /* #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) */
251 
252 #define CONTROL_IF   0
253 #define BULK_IF      0
254 
255 #ifdef BCMUSBDEV_COMPOSITE
256 #define USB_COMPIF_MAX       4
257 
258 #define USB_CLASS_WIRELESS	0xe0
259 #define USB_CLASS_MISC		0xef
260 #define USB_SUBCLASS_COMMON	0x02
261 #define USB_PROTO_IAD		0x01
262 #define USB_PROTO_VENDOR	0xff
263 
264 #define USB_QUIRK_NO_SET_INTF   0x04 /* device does not support set_interface */
265 #endif /* BCMUSBDEV_COMPOSITE */
266 
267 #define USB_SYNC_WAIT_TIMEOUT  300  /* ms */
268 
269 /* Private data kept in skb */
270 #define SKB_PRIV(skb, idx)  (&((void **)skb->cb)[idx])
271 #define SKB_PRIV_URB(skb)   (*(struct urb **)SKB_PRIV(skb, 0))
272 
273 #ifndef DBUS_USB_RXQUEUE_BATCH_ADD
274 /* items to add each time within limit */
275 #define DBUS_USB_RXQUEUE_BATCH_ADD            8
276 #endif
277 
278 #ifndef DBUS_USB_RXQUEUE_LOWER_WATERMARK
279 /* add a new batch req to rx queue when waiting item count reduce to this number */
280 #define DBUS_USB_RXQUEUE_LOWER_WATERMARK      4
281 #endif
282 
283 enum usbos_suspend_state {
284 	USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow suspend */
285 	USBOS_SUSPEND_STATE_SUSPEND_PENDING,   /* Device is idle, can be suspended */
286 	                                       /* Wating PM to suspend */
287 	USBOS_SUSPEND_STATE_SUSPENDED          /* Device suspended */
288 };
289 
290 enum usbos_request_state {
291 	USBOS_REQUEST_STATE_UNSCHEDULED = 0,	/* USB TX request not scheduled */
292 	USBOS_REQUEST_STATE_SCHEDULED,		/* USB TX request given to TX thread */
293 	USBOS_REQUEST_STATE_SUBMITTED		/* USB TX request submitted */
294 };
295 
296 typedef struct {
297 	uint32 notification;
298 	uint32 reserved;
299 } intr_t;
300 
301 typedef struct {
302 	dbus_pub_t *pub;
303 
304 	void *cbarg;
305 	dbus_intf_callbacks_t *cbs;
306 
307 	/* Imported */
308 	struct usb_device *usb;	/* USB device pointer from OS */
309 	struct urb *intr_urb; /* URB for interrupt endpoint */
310 	struct list_head req_rxfreeq;
311 	struct list_head req_txfreeq;
312 	struct list_head req_rxpostedq;	/* Posted down to USB driver for RX */
313 	struct list_head req_txpostedq;	/* Posted down to USB driver for TX */
314 	spinlock_t rxfree_lock; /* Lock for rx free list */
315 	spinlock_t txfree_lock; /* Lock for tx free list */
316 	spinlock_t rxposted_lock; /* Lock for rx posted list */
317 	spinlock_t txposted_lock; /* Lock for tx posted list */
318 	uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; /* Pipe numbers for USB I/O */
319 	uint rxbuf_len;
320 
321 	struct list_head req_rxpendingq; /* RXDPC: Pending for dpc to send up */
322 	spinlock_t rxpending_lock;	/* RXDPC: Lock for rx pending list */
323 	long dpc_pid;
324 	struct semaphore dpc_sem;
325 	struct completion dpc_exited;
326 	int rxpending;
327 
328 	struct urb               *ctl_urb;
329 	int                      ctl_in_pipe, ctl_out_pipe;
330 	struct usb_ctrlrequest   ctl_write;
331 	struct usb_ctrlrequest   ctl_read;
332 	struct semaphore         ctl_lock;     /* Lock for CTRL transfers via tx_thread */
333 #ifdef USBOS_TX_THREAD
334 	enum usbos_request_state ctl_state;
335 #endif /* USBOS_TX_THREAD */
336 
337 	spinlock_t rxlock;      /* Lock for rxq management */
338 	spinlock_t txlock;      /* Lock for txq management */
339 
340 	int intr_size;          /* Size of interrupt message */
341 	int interval;           /* Interrupt polling interval */
342 	intr_t intr;            /* Data buffer for interrupt endpoint */
343 
344 	int maxps;
345 	atomic_t txposted;
346 	atomic_t rxposted;
347 	atomic_t txallocated;
348 	atomic_t rxallocated;
349 	bool rxctl_deferrespok;	/* Get a response for setup from dongle */
350 
351 	wait_queue_head_t wait;
352 	bool waitdone;
353 	int sync_urb_status;
354 
355 	struct urb *blk_urb; /* Used for downloading embedded image */
356 
357 #ifdef USBOS_THREAD
358 	spinlock_t              ctrl_lock;
359 	spinlock_t              usbos_list_lock;
360 	struct list_head        usbos_list;
361 	struct list_head        usbos_free_list;
362 	atomic_t                usbos_list_cnt;
363 	wait_queue_head_t       usbos_queue_head;
364 	struct task_struct      *usbos_kt;
365 #endif /* USBOS_THREAD */
366 
367 #ifdef USBOS_TX_THREAD
368 	spinlock_t              usbos_tx_list_lock;
369 	struct list_head	usbos_tx_list;
370 	wait_queue_head_t	usbos_tx_queue_head;
371 	struct task_struct      *usbos_tx_kt;
372 #endif /* USBOS_TX_THREAD */
373 
374 	struct dma_pool *qtd_pool; /* QTD pool for USB optimization only */
375 	int tx_ep, rx_ep, rx2_ep;  /* EPs for USB optimization */
376 	struct usb_device *usb_device; /* USB device for optimization */
377 } usbos_info_t;
378 
379 typedef struct urb_req {
380 	void         *pkt;
381 	int          buf_len;
382 	struct urb   *urb;
383 	void         *arg;
384 	usbos_info_t *usbinfo;
385 	struct list_head urb_list;
386 } urb_req_t;
387 
388 #ifdef USBOS_THREAD
389 typedef struct usbos_list_entry {
390 	struct list_head    list;   /* must be first */
391 	void               *urb_context;
392 	int                 urb_length;
393 	int                 urb_status;
394 } usbos_list_entry_t;
395 
396 static void* dbus_usbos_thread_init(usbos_info_t *usbos_info);
397 static void  dbus_usbos_thread_deinit(usbos_info_t *usbos_info);
398 static void  dbus_usbos_dispatch_schedule(CALLBACK_ARGS);
399 static int   dbus_usbos_thread_func(void *data);
400 #endif /* USBOS_THREAD */
401 
402 #ifdef USBOS_TX_THREAD
403 void* dbus_usbos_tx_thread_init(usbos_info_t *usbos_info);
404 void  dbus_usbos_tx_thread_deinit(usbos_info_t *usbos_info);
405 int   dbus_usbos_tx_thread_func(void *data);
406 #endif /* USBOS_TX_THREAD */
407 
408 /* Shared Function prototypes */
409 bool dbus_usbos_dl_cmd(usbos_info_t *usbinfo, uint8 cmd, void *buffer, int buflen);
410 int dbus_usbos_wait(usbos_info_t *usbinfo, uint16 ms);
411 bool dbus_usbos_dl_send_bulk(usbos_info_t *usbinfo, void *buffer, int len);
412 int dbus_write_membytes(usbos_info_t *usbinfo, bool set, uint32 address, uint8 *data, uint size);
413 
414 /* Local function prototypes */
415 static void dbus_usbos_send_complete(CALLBACK_ARGS);
416 static void dbus_usbos_recv_complete(CALLBACK_ARGS);
417 static int  dbus_usbos_errhandler(void *bus, int err);
418 static int  dbus_usbos_state_change(void *bus, int state);
419 static void dbusos_stop(usbos_info_t *usbos_info);
420 
421 #ifdef KERNEL26
422 static int dbus_usbos_probe(struct usb_interface *intf, const struct usb_device_id *id);
423 static void dbus_usbos_disconnect(struct usb_interface *intf);
424 #if defined(USB_SUSPEND_AVAILABLE)
425 static int dbus_usbos_resume(struct usb_interface *intf);
426 static int dbus_usbos_suspend(struct usb_interface *intf, pm_message_t message);
427 /* at the moment, used for full dongle host driver only */
428 static int dbus_usbos_reset_resume(struct usb_interface *intf);
429 #endif /* USB_SUSPEND_AVAILABLE */
430 #else /* KERNEL26 */
431 static void *dbus_usbos_probe(struct usb_device *usb, unsigned int ifnum,
432 	const struct usb_device_id *id);
433 static void dbus_usbos_disconnect(struct usb_device *usb, void *ptr);
434 #endif /* KERNEL26 */
435 
436 
437 /**
438  * have to disable missing-field-initializers warning as last element {} triggers it
439  * and different versions of kernel have different number of members so it is impossible
440  * to specify the initializer. BTW issuing the warning here is bug og GCC as  universal
441  * zero {0} specified in C99 standard as correct way of initialization of struct to all zeros
442  */
443 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
444 	4 && __GNUC_MINOR__ >= 6))
445 #pragma GCC diagnostic push
446 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
447 #endif
448 
449 static struct usb_device_id devid_table[] = {
450 	{ USB_DEVICE(BCM_DNGL_VID, 0x0000) }, /* Configurable via register() */
451 #if defined(BCM_REQUEST_FW)
452 	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4328) },
453 	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4322) },
454 	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4319) },
455 	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_43236) },
456 	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_43143) },
457 	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_43242) },
458 	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4360) },
459 	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4350) },
460 	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_43569) },
461 #endif
462 #ifdef EXTENDED_VID_PID
463 	EXTENDED_VID_PID,
464 #endif /* EXTENDED_VID_PID */
465 	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BDC_PID) }, /* Default BDC */
466 	{ }
467 };
468 
469 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
470 	4 && __GNUC_MINOR__ >= 6))
471 #pragma GCC diagnostic pop
472 #endif
473 
474 MODULE_DEVICE_TABLE(usb, devid_table);
475 
476 /** functions called by the Linux kernel USB subsystem */
477 static struct usb_driver dbus_usbdev = {
478 	name:           "dbus_usbdev",
479 	probe:          dbus_usbos_probe,
480 	disconnect:     dbus_usbos_disconnect,
481 	id_table:       devid_table,
482 #if defined(USB_SUSPEND_AVAILABLE)
483 	suspend:        dbus_usbos_suspend,
484 	resume:         dbus_usbos_resume,
485 	reset_resume:	dbus_usbos_reset_resume,
486 	/* Linux USB core will allow autosuspend for devices bound to this driver */
487 	supports_autosuspend: 1
488 #endif /* USB_SUSPEND_AVAILABLE */
489 };
490 
491 /**
492  * This stores USB info during Linux probe callback since attach() is not called yet at this point
493  */
494 typedef struct {
495 	void    *usbos_info;
496 	struct usb_device *usb; /* USB device pointer from OS */
497 	uint    rx_pipe;   /* Pipe numbers for USB I/O */
498 	uint    tx_pipe;   /* Pipe numbers for USB I/O */
499 	uint    intr_pipe; /* Pipe numbers for USB I/O */
500 	uint    rx_pipe2;  /* Pipe numbers for USB I/O */
501 	int     intr_size; /* Size of interrupt message */
502 	int     interval;  /* Interrupt polling interval */
503 	bool    dldone;
504 	int     vid;
505 	int     pid;
506 	bool    dereged;
507 	bool    disc_cb_done;
508 	DEVICE_SPEED    device_speed;
509 	enum usbos_suspend_state suspend_state;
510 	struct usb_interface     *intf;
511 } probe_info_t;
512 
513 /*
514  * USB Linux dbus_intf_t
515  */
516 static void *dbus_usbos_intf_attach(dbus_pub_t *pub, void *cbarg, dbus_intf_callbacks_t *cbs);
517 static void dbus_usbos_intf_detach(dbus_pub_t *pub, void *info);
518 static int  dbus_usbos_intf_send_irb(void *bus, dbus_irb_tx_t *txirb);
519 static int  dbus_usbos_intf_recv_irb(void *bus, dbus_irb_rx_t *rxirb);
520 static int  dbus_usbos_intf_recv_irb_from_ep(void *bus, dbus_irb_rx_t *rxirb, uint32 ep_idx);
521 static int  dbus_usbos_intf_cancel_irb(void *bus, dbus_irb_tx_t *txirb);
522 static int  dbus_usbos_intf_send_ctl(void *bus, uint8 *buf, int len);
523 static int  dbus_usbos_intf_recv_ctl(void *bus, uint8 *buf, int len);
524 static int  dbus_usbos_intf_get_attrib(void *bus, dbus_attrib_t *attrib);
525 static int  dbus_usbos_intf_up(void *bus);
526 static int  dbus_usbos_intf_down(void *bus);
527 static int  dbus_usbos_intf_stop(void *bus);
528 static int  dbus_usbos_readreg(void *bus, uint32 regaddr, int datalen, uint32 *value);
529 extern int dbus_usbos_loopback_tx(void *usbos_info_ptr, int cnt, int size);
530 int dbus_usbos_writereg(void *bus, uint32 regaddr, int datalen, uint32 data);
531 static int  dbus_usbos_intf_set_config(void *bus, dbus_config_t *config);
532 static bool dbus_usbos_intf_recv_needed(void *bus);
533 static void *dbus_usbos_intf_exec_rxlock(void *bus, exec_cb_t cb, struct exec_parms *args);
534 static void *dbus_usbos_intf_exec_txlock(void *bus, exec_cb_t cb, struct exec_parms *args);
535 #ifdef BCMUSBDEV_COMPOSITE
536 static int dbus_usbos_intf_wlan(struct usb_device *usb);
537 #endif /* BCMUSBDEV_COMPOSITE */
538 
539 /** functions called by dbus_usb.c */
540 static dbus_intf_t dbus_usbos_intf = {
541 	.attach = dbus_usbos_intf_attach,
542 	.detach = dbus_usbos_intf_detach,
543 	.up = dbus_usbos_intf_up,
544 	.down = dbus_usbos_intf_down,
545 	.send_irb = dbus_usbos_intf_send_irb,
546 	.recv_irb = dbus_usbos_intf_recv_irb,
547 	.cancel_irb = dbus_usbos_intf_cancel_irb,
548 	.send_ctl = dbus_usbos_intf_send_ctl,
549 	.recv_ctl = dbus_usbos_intf_recv_ctl,
550 	.get_stats = NULL,
551 	.get_attrib = dbus_usbos_intf_get_attrib,
552 	.remove = NULL,
553 	.resume = NULL,
554 	.suspend = NULL,
555 	.stop = dbus_usbos_intf_stop,
556 	.reset = NULL,
557 	.pktget = NULL,
558 	.pktfree = NULL,
559 	.iovar_op = NULL,
560 	.dump = NULL,
561 	.set_config = dbus_usbos_intf_set_config,
562 	.get_config = NULL,
563 	.device_exists = NULL,
564 	.dlneeded = NULL,
565 	.dlstart = NULL,
566 	.dlrun = NULL,
567 	.recv_needed = dbus_usbos_intf_recv_needed,
568 	.exec_rxlock = dbus_usbos_intf_exec_rxlock,
569 	.exec_txlock = dbus_usbos_intf_exec_txlock,
570 
571 	.tx_timer_init = NULL,
572 	.tx_timer_start = NULL,
573 	.tx_timer_stop = NULL,
574 
575 	.sched_dpc = NULL,
576 	.lock = NULL,
577 	.unlock = NULL,
578 	.sched_probe_cb = NULL,
579 
580 	.shutdown = NULL,
581 
582 	.recv_stop = NULL,
583 	.recv_resume = NULL,
584 
585 	.recv_irb_from_ep = dbus_usbos_intf_recv_irb_from_ep,
586 	.readreg = dbus_usbos_readreg
587 };
588 
589 static probe_info_t    g_probe_info;
590 static probe_cb_t      probe_cb = NULL;
591 static disconnect_cb_t disconnect_cb = NULL;
592 static void            *probe_arg = NULL;
593 static void            *disc_arg = NULL;
594 
595 
596 
597 static volatile int loopback_rx_cnt, loopback_tx_cnt;
598 int loopback_size;
599 bool is_loopback_pkt(void *buf);
600 int matches_loopback_pkt(void *buf);
601 
602 /**
603  * multiple code paths in this file dequeue a URB request, this function makes sure that it happens
604  * in a concurrency save manner. Don't call this from a sleepable process context.
605  */
606 static urb_req_t * BCMFASTPATH
dbus_usbos_qdeq(struct list_head * urbreq_q,spinlock_t * lock)607 dbus_usbos_qdeq(struct list_head *urbreq_q, spinlock_t *lock)
608 {
609 	unsigned long flags;
610 	urb_req_t *req;
611 
612 	ASSERT(urbreq_q != NULL);
613 
614 	spin_lock_irqsave(lock, flags);
615 
616 	if (list_empty(urbreq_q)) {
617 		req = NULL;
618 	} else {
619 		ASSERT(urbreq_q->next != NULL);
620 		ASSERT(urbreq_q->next != urbreq_q);
621 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
622 #pragma GCC diagnostic push
623 #pragma GCC diagnostic ignored "-Wcast-qual"
624 #endif
625 		req = list_entry(urbreq_q->next, urb_req_t, urb_list);
626 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
627 #pragma GCC diagnostic pop
628 #endif
629 		list_del_init(&req->urb_list);
630 	}
631 
632 	spin_unlock_irqrestore(lock, flags);
633 
634 	return req;
635 }
636 
637 static void BCMFASTPATH
dbus_usbos_qenq(struct list_head * urbreq_q,urb_req_t * req,spinlock_t * lock)638 dbus_usbos_qenq(struct list_head *urbreq_q, urb_req_t *req, spinlock_t *lock)
639 {
640 	unsigned long flags;
641 
642 	spin_lock_irqsave(lock, flags);
643 
644 	list_add_tail(&req->urb_list, urbreq_q);
645 
646 	spin_unlock_irqrestore(lock, flags);
647 }
648 
649 /**
650  * multiple code paths in this file remove a URB request from a list, this function makes sure that
651  * it happens in a concurrency save manner. Don't call this from a sleepable process context.
652  * Is quite similar to dbus_usbos_qdeq(), I wonder why this function is needed.
653  */
654 static void
dbus_usbos_req_del(urb_req_t * req,spinlock_t * lock)655 dbus_usbos_req_del(urb_req_t *req, spinlock_t *lock)
656 {
657 	unsigned long flags;
658 
659 	spin_lock_irqsave(lock, flags);
660 
661 	list_del_init(&req->urb_list);
662 
663 	spin_unlock_irqrestore(lock, flags);
664 }
665 
666 
667 /**
668  * Driver requires a pool of URBs to operate. This function is called during
669  * initialization (attach phase), allocates a number of URBs, and puts them
670  * on the free (req_rxfreeq and req_txfreeq) queue
671  */
672 static int
dbus_usbos_urbreqs_alloc(usbos_info_t * usbos_info,uint32 count,bool is_rx)673 dbus_usbos_urbreqs_alloc(usbos_info_t *usbos_info, uint32 count, bool is_rx)
674 {
675 	int i;
676 	int allocated = 0;
677 	int err = DBUS_OK;
678 
679 	for (i = 0; i < count; i++) {
680 		urb_req_t *req;
681 
682 		req = MALLOC(usbos_info->pub->osh, sizeof(urb_req_t));
683 		if (req == NULL) {
684 			DBUSERR(("%s: MALLOC req failed\n", __FUNCTION__));
685 			err = DBUS_ERR_NOMEM;
686 			goto fail;
687 		}
688 		bzero(req, sizeof(urb_req_t));
689 
690 		req->urb = USB_ALLOC_URB();
691 		if (req->urb == NULL) {
692 			DBUSERR(("%s: USB_ALLOC_URB req->urb failed\n", __FUNCTION__));
693 			err = DBUS_ERR_NOMEM;
694 			goto fail;
695 		}
696 
697 		INIT_LIST_HEAD(&req->urb_list);
698 
699 		if (is_rx) {
700 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
701 			/* don't allocate now. Do it on demand */
702 			req->pkt = NULL;
703 #else
704 			/* pre-allocate  buffers never to be released */
705 			req->pkt = MALLOC(usbos_info->pub->osh, usbos_info->rxbuf_len);
706 			if (req->pkt == NULL) {
707 				DBUSERR(("%s: MALLOC req->pkt failed\n", __FUNCTION__));
708 				err = DBUS_ERR_NOMEM;
709 				goto fail;
710 			}
711 #endif
712 			req->buf_len = usbos_info->rxbuf_len;
713 			dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
714 		} else {
715 			req->buf_len = 0;
716 			dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
717 		}
718 		allocated++;
719 		continue;
720 
721 fail:
722 		if (req) {
723 			if (is_rx && req->pkt) {
724 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
725 				/* req->pkt is NULL in "NOCOPY" mode */
726 #else
727 				MFREE(usbos_info->pub->osh, req->pkt, req->buf_len);
728 #endif
729 			}
730 			if (req->urb) {
731 				USB_FREE_URB(req->urb);
732 			}
733 			MFREE(usbos_info->pub->osh, req, sizeof(urb_req_t));
734 		}
735 		break;
736 	}
737 
738 	atomic_add(allocated, is_rx ? &usbos_info->rxallocated : &usbos_info->txallocated);
739 
740 	if (is_rx) {
741 		DBUSTRACE(("%s: add %d (total %d) rx buf, each has %d bytes\n", __FUNCTION__,
742 			allocated, atomic_read(&usbos_info->rxallocated), usbos_info->rxbuf_len));
743 	} else {
744 		DBUSTRACE(("%s: add %d (total %d) tx req\n", __FUNCTION__,
745 			allocated, atomic_read(&usbos_info->txallocated)));
746 	}
747 
748 	return err;
749 } /* dbus_usbos_urbreqs_alloc */
750 
751 /** Typically called during detach or when attach failed. Don't call until all URBs unlinked */
752 static int
dbus_usbos_urbreqs_free(usbos_info_t * usbos_info,bool is_rx)753 dbus_usbos_urbreqs_free(usbos_info_t *usbos_info, bool is_rx)
754 {
755 	int rtn = 0;
756 	urb_req_t *req;
757 	struct list_head *req_q;
758 	spinlock_t *lock;
759 
760 	if (is_rx) {
761 		req_q = &usbos_info->req_rxfreeq;
762 		lock = &usbos_info->rxfree_lock;
763 	} else {
764 		req_q = &usbos_info->req_txfreeq;
765 		lock = &usbos_info->txfree_lock;
766 	}
767 	while ((req = dbus_usbos_qdeq(req_q, lock)) != NULL) {
768 
769 		if (is_rx) {
770 			if (req->pkt) {
771 				/* We do MFREE instead of PKTFREE because the pkt has been
772 				 * converted to native already
773 				 */
774 				MFREE(usbos_info->pub->osh, req->pkt, req->buf_len);
775 				req->pkt = NULL;
776 				req->buf_len = 0;
777 			}
778 		} else {
779 			/* sending req should not be assigned pkt buffer */
780 			ASSERT(req->pkt == NULL);
781 		}
782 
783 		if (req->urb) {
784 			USB_FREE_URB(req->urb);
785 			req->urb = NULL;
786 		}
787 		MFREE(usbos_info->pub->osh, req, sizeof(urb_req_t));
788 
789 		rtn++;
790 	}
791 	return rtn;
792 } /* dbus_usbos_urbreqs_free */
793 
794 /**
795  * called by Linux kernel on URB completion. Upper DBUS layer (dbus_usb.c) has to be notified of
796  * send completion.
797  */
798 void
dbus_usbos_send_complete(CALLBACK_ARGS)799 dbus_usbos_send_complete(CALLBACK_ARGS)
800 {
801 	urb_req_t *req = urb->context;
802 	dbus_irb_tx_t *txirb = req->arg;
803 	usbos_info_t *usbos_info = req->usbinfo;
804 	unsigned long flags;
805 	int status = DBUS_OK;
806 	int txposted;
807 
808 	USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
809 
810 	spin_lock_irqsave(&usbos_info->txlock, flags);
811 
812 	dbus_usbos_req_del(req, &usbos_info->txposted_lock);
813 	txposted = atomic_dec_return(&usbos_info->txposted);
814 	if (unlikely (txposted < 0)) {
815 		DBUSERR(("%s ERROR: txposted is negative (%d)!!\n", __FUNCTION__, txposted));
816 	}
817 	spin_unlock_irqrestore(&usbos_info->txlock, flags);
818 
819 	if (unlikely (urb->status)) {
820 		status = DBUS_ERR_TXFAIL;
821 		DBUSTRACE(("txfail status %d\n", urb->status));
822 	}
823 
824 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
825 	/* sending req should not be assigned pkt buffer */
826 	ASSERT(req->pkt == NULL);
827 #endif
828 	/*  txirb should always be set, except for ZLP. ZLP is reusing this callback function. */
829 	if (txirb != NULL) {
830 		if (txirb->send_buf != NULL) {
831 			MFREE(usbos_info->pub->osh, txirb->send_buf, req->buf_len);
832 			txirb->send_buf = NULL;
833 			req->buf_len = 0;
834 		}
835 		if (likely (usbos_info->cbarg && usbos_info->cbs)) {
836 			if (likely (usbos_info->cbs->send_irb_complete != NULL))
837 			    usbos_info->cbs->send_irb_complete(usbos_info->cbarg, txirb, status);
838 		}
839 	}
840 
841 	dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
842 } /* dbus_usbos_send_complete */
843 
844 /**
845  * In order to receive USB traffic from the dongle, we need to supply the Linux kernel with a free
846  * URB that is going to contain received data.
847  */
848 static int BCMFASTPATH
dbus_usbos_recv_urb_submit(usbos_info_t * usbos_info,dbus_irb_rx_t * rxirb,uint32 ep_idx)849 dbus_usbos_recv_urb_submit(usbos_info_t *usbos_info, dbus_irb_rx_t *rxirb, uint32 ep_idx)
850 {
851 	urb_req_t *req;
852 	int ret = DBUS_OK;
853 	unsigned long flags;
854 	void *p;
855 	uint rx_pipe;
856 	int rxposted;
857 
858 	BCM_REFERENCE(rxposted);
859 
860 	if (!(req = dbus_usbos_qdeq(&usbos_info->req_rxfreeq, &usbos_info->rxfree_lock))) {
861 		DBUSTRACE(("%s No free URB!\n", __FUNCTION__));
862 		return DBUS_ERR_RXDROP;
863 	}
864 
865 	spin_lock_irqsave(&usbos_info->rxlock, flags);
866 
867 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
868 	req->pkt = rxirb->pkt = PKTGET(usbos_info->pub->osh, req->buf_len, FALSE);
869 	if (!rxirb->pkt) {
870 		DBUSERR(("%s: PKTGET failed\n", __FUNCTION__));
871 		dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
872 		ret = DBUS_ERR_RXDROP;
873 		goto fail;
874 	}
875 	/* consider the packet "native" so we don't count it as MALLOCED in the osl */
876 	PKTTONATIVE(usbos_info->pub->osh, req->pkt);
877 	rxirb->buf = NULL;
878 	p = PKTDATA(usbos_info->pub->osh, req->pkt);
879 #else
880 	if (req->buf_len != usbos_info->rxbuf_len) {
881 		ASSERT(req->pkt);
882 		MFREE(usbos_info->pub->osh, req->pkt, req->buf_len);
883 		DBUSTRACE(("%s: replace rx buff: old len %d, new len %d\n", __FUNCTION__,
884 			req->buf_len, usbos_info->rxbuf_len));
885 		req->buf_len = 0;
886 		req->pkt = MALLOC(usbos_info->pub->osh, usbos_info->rxbuf_len);
887 		if (req->pkt == NULL) {
888 			DBUSERR(("%s: MALLOC req->pkt failed\n", __FUNCTION__));
889 			ret = DBUS_ERR_NOMEM;
890 			goto fail;
891 		}
892 		req->buf_len = usbos_info->rxbuf_len;
893 	}
894 	rxirb->buf = req->pkt;
895 	p = rxirb->buf;
896 #endif /* defined(BCM_RPC_NOCOPY) */
897 	rxirb->buf_len = req->buf_len;
898 	req->usbinfo = usbos_info;
899 	req->arg = rxirb;
900 	if (ep_idx == 0) {
901 		rx_pipe = usbos_info->rx_pipe;
902 	} else {
903 		rx_pipe = usbos_info->rx_pipe2;
904 		ASSERT(usbos_info->rx_pipe2);
905 	}
906 	/* Prepare the URB */
907 	usb_fill_bulk_urb(req->urb, usbos_info->usb, rx_pipe,
908 		p,
909 		rxirb->buf_len,
910 		(usb_complete_t)dbus_usbos_recv_complete, req);
911 		req->urb->transfer_flags |= URB_QUEUE_BULK;
912 
913 	if ((ret = USB_SUBMIT_URB(req->urb))) {
914 		DBUSERR(("%s USB_SUBMIT_URB failed. status %d\n", __FUNCTION__, ret));
915 		dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
916 		ret = DBUS_ERR_RXFAIL;
917 		goto fail;
918 	}
919 	rxposted = atomic_inc_return(&usbos_info->rxposted);
920 
921 	dbus_usbos_qenq(&usbos_info->req_rxpostedq, req, &usbos_info->rxposted_lock);
922 fail:
923 	spin_unlock_irqrestore(&usbos_info->rxlock, flags);
924 	return ret;
925 } /* dbus_usbos_recv_urb_submit */
926 
927 
928 /**
929  * Called by worked thread when a 'receive URB' completed or Linux kernel when it returns a URB to
930  * this driver.
931  */
932 static void BCMFASTPATH
dbus_usbos_recv_complete_handle(urb_req_t * req,int len,int status)933 dbus_usbos_recv_complete_handle(urb_req_t *req, int len, int status)
934 {
935 	dbus_irb_rx_t *rxirb = req->arg;
936 	usbos_info_t *usbos_info = req->usbinfo;
937 	unsigned long flags;
938 	int rxallocated, rxposted;
939 	int dbus_status = DBUS_OK;
940 	bool killed = (g_probe_info.suspend_state == USBOS_SUSPEND_STATE_SUSPEND_PENDING) ? 1 : 0;
941 
942 	spin_lock_irqsave(&usbos_info->rxlock, flags);
943 	dbus_usbos_req_del(req, &usbos_info->rxposted_lock);
944 	rxposted = atomic_dec_return(&usbos_info->rxposted);
945 	rxallocated = atomic_read(&usbos_info->rxallocated);
946 	spin_unlock_irqrestore(&usbos_info->rxlock, flags);
947 
948 	if ((rxallocated < usbos_info->pub->nrxq) && (!status) &&
949 		(rxposted == DBUS_USB_RXQUEUE_LOWER_WATERMARK)) {
950 			DBUSTRACE(("%s: need more rx buf: rxallocated %d rxposted %d!\n",
951 				__FUNCTION__, rxallocated, rxposted));
952 			dbus_usbos_urbreqs_alloc(usbos_info,
953 				MIN(DBUS_USB_RXQUEUE_BATCH_ADD,
954 				usbos_info->pub->nrxq - rxallocated), TRUE);
955 	}
956 
957 	/* Handle errors */
958 	if (status) {
959 		/*
960 		 * Linux 2.4 disconnect: -ENOENT or -EILSEQ for CRC error; rmmod: -ENOENT
961 		 * Linux 2.6 disconnect: -EPROTO, rmmod: -ESHUTDOWN
962 		 */
963 		if ((status == -ENOENT && (!killed))|| status == -ESHUTDOWN) {
964 			/* NOTE: unlink() can not be called from URB callback().
965 			 * Do not call dbusos_stop() here.
966 			 */
967 			DBUSTRACE(("%s rx error %d\n", __FUNCTION__, status));
968 			dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
969 		} else if (status == -EPROTO) {
970 			DBUSTRACE(("%s rx error %d\n", __FUNCTION__, status));
971 		} else if (killed && (status == -EHOSTUNREACH || status == -ENOENT)) {
972 			/* Device is suspended */
973 		} else {
974 			DBUSTRACE(("%s rx error %d\n", __FUNCTION__, status));
975 			dbus_usbos_errhandler(usbos_info, DBUS_ERR_RXFAIL);
976 		}
977 
978 		/* On error, don't submit more URBs yet */
979 		rxirb->buf = NULL;
980 		rxirb->actual_len = 0;
981 		dbus_status = DBUS_ERR_RXFAIL;
982 		goto fail;
983 	}
984 
985 	/* Make the skb represent the received urb */
986 	rxirb->actual_len = len;
987 
988 	if (rxirb->actual_len < sizeof(uint32)) {
989 		DBUSTRACE(("small pkt len %d, process as ZLP\n", rxirb->actual_len));
990 		dbus_status = DBUS_ERR_RXZLP;
991 	}
992 
993 fail:
994 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
995 	/* detach the packet from the queue */
996 	req->pkt = NULL;
997 #endif /* BCM_RPC_NOCOPY || BCM_RPC_RXNOCOPY */
998 
999 	if (usbos_info->cbarg && usbos_info->cbs) {
1000 		if (usbos_info->cbs->recv_irb_complete) {
1001 			usbos_info->cbs->recv_irb_complete(usbos_info->cbarg, rxirb, dbus_status);
1002 		}
1003 	}
1004 
1005 	dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
1006 
1007 	/* Mark the interface as busy to reset USB autosuspend timer */
1008 	USB_MARK_LAST_BUSY(usbos_info->usb);
1009 } /* dbus_usbos_recv_complete_handle */
1010 
1011 /** called by Linux kernel when it returns a URB to this driver */
1012 static void
dbus_usbos_recv_complete(CALLBACK_ARGS)1013 dbus_usbos_recv_complete(CALLBACK_ARGS)
1014 {
1015 #ifdef USBOS_THREAD
1016 	dbus_usbos_dispatch_schedule(CALLBACK_ARGS_DATA);
1017 #else /*  !USBOS_THREAD */
1018 	dbus_usbos_recv_complete_handle(urb->context, urb->actual_length, urb->status);
1019 #endif /*  USBOS_THREAD */
1020 }
1021 
1022 
1023 /**
1024  * If Linux notifies our driver that a control read or write URB has completed, we should notify
1025  * the DBUS layer above us (dbus_usb.c in this case).
1026  */
1027 static void
dbus_usbos_ctl_complete(usbos_info_t * usbos_info,int type,int urbstatus)1028 dbus_usbos_ctl_complete(usbos_info_t *usbos_info, int type, int urbstatus)
1029 {
1030 	int status = DBUS_ERR;
1031 
1032 	if (usbos_info == NULL)
1033 		return;
1034 
1035 	switch (urbstatus) {
1036 		case 0:
1037 			status = DBUS_OK;
1038 		break;
1039 		case -EINPROGRESS:
1040 		case -ENOENT:
1041 		default:
1042 #ifdef INTR_EP_ENABLE
1043 			DBUSERR(("%s:%d fail status %d bus:%d susp:%d intr:%d ctli:%d ctlo:%d\n",
1044 				__FUNCTION__, type, urbstatus,
1045 				usbos_info->pub->busstate, g_probe_info.suspend_state,
1046 				usbos_info->intr_urb_submitted, usbos_info->ctlin_urb_submitted,
1047 				usbos_info->ctlout_urb_submitted));
1048 #else
1049 			DBUSERR(("%s: failed with status %d\n", __FUNCTION__, urbstatus));
1050 			status = DBUS_ERR;
1051 		break;
1052 #endif /* INTR_EP_ENABLE */
1053 	}
1054 
1055 	if (usbos_info->cbarg && usbos_info->cbs) {
1056 		if (usbos_info->cbs->ctl_complete)
1057 			usbos_info->cbs->ctl_complete(usbos_info->cbarg, type, status);
1058 	}
1059 }
1060 
1061 /** called by Linux */
1062 static void
dbus_usbos_ctlread_complete(CALLBACK_ARGS)1063 dbus_usbos_ctlread_complete(CALLBACK_ARGS)
1064 {
1065 	usbos_info_t *usbos_info = (usbos_info_t *)urb->context;
1066 
1067 	ASSERT(urb);
1068 	usbos_info = (usbos_info_t *)urb->context;
1069 
1070 	dbus_usbos_ctl_complete(usbos_info, DBUS_CBCTL_READ, urb->status);
1071 
1072 #ifdef USBOS_THREAD
1073 	if (usbos_info->rxctl_deferrespok) {
1074 		usbos_info->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_CLASS |
1075 		USB_RECIP_INTERFACE;
1076 		usbos_info->ctl_read.bRequest = 1;
1077 	}
1078 #endif
1079 
1080 	up(&usbos_info->ctl_lock);
1081 
1082 	USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
1083 }
1084 
1085 /** called by Linux */
1086 static void
dbus_usbos_ctlwrite_complete(CALLBACK_ARGS)1087 dbus_usbos_ctlwrite_complete(CALLBACK_ARGS)
1088 {
1089 	usbos_info_t *usbos_info = (usbos_info_t *)urb->context;
1090 
1091 	ASSERT(urb);
1092 	usbos_info = (usbos_info_t *)urb->context;
1093 
1094 	dbus_usbos_ctl_complete(usbos_info, DBUS_CBCTL_WRITE, urb->status);
1095 
1096 #ifdef USBOS_TX_THREAD
1097 	usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
1098 #endif /* USBOS_TX_THREAD */
1099 
1100 	up(&usbos_info->ctl_lock);
1101 
1102 	USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
1103 }
1104 
1105 #ifdef INTR_EP_ENABLE
1106 /** called by Linux */
1107 static void
dbus_usbos_intr_complete(CALLBACK_ARGS)1108 dbus_usbos_intr_complete(CALLBACK_ARGS)
1109 {
1110 	usbos_info_t *usbos_info = (usbos_info_t *)urb->context;
1111 	bool killed = (g_probe_info.suspend_state == USBOS_SUSPEND_STATE_SUSPEND_PENDING) ? 1 : 0;
1112 
1113 	if (usbos_info == NULL || usbos_info->pub == NULL)
1114 		return;
1115 	if ((urb->status == -ENOENT && (!killed)) || urb->status == -ESHUTDOWN ||
1116 		urb->status == -ENODEV) {
1117 		dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
1118 	}
1119 
1120 	if (usbos_info->pub->busstate == DBUS_STATE_DOWN) {
1121 		DBUSERR(("%s: intr cb when DBUS down, ignoring\n", __FUNCTION__));
1122 		return;
1123 	}
1124 	dbus_usbos_ctl_complete(usbos_info, DBUS_CBINTR_POLL, urb->status);
1125 }
1126 #endif	/* INTR_EP_ENABLE */
1127 
1128 /**
1129  * when the bus is going to sleep or halt, the Linux kernel requires us to take ownership of our
1130  * URBs again. Multiple code paths in this file require a list of URBs to be cancelled in a
1131  * concurrency save manner.
1132  */
1133 static void
dbus_usbos_unlink(struct list_head * urbreq_q,spinlock_t * lock)1134 dbus_usbos_unlink(struct list_head *urbreq_q, spinlock_t *lock)
1135 {
1136 	urb_req_t *req;
1137 
1138 	/* dbus_usbos_recv_complete() adds req back to req_freeq */
1139 	while ((req = dbus_usbos_qdeq(urbreq_q, lock)) != NULL) {
1140 		ASSERT(req->urb != NULL);
1141 		USB_UNLINK_URB(req->urb);
1142 	}
1143 }
1144 
1145 /** multiple code paths in this file require the bus to stop */
1146 static void
dbus_usbos_cancel_all_urbs(usbos_info_t * usbos_info)1147 dbus_usbos_cancel_all_urbs(usbos_info_t *usbos_info)
1148 {
1149 	int rxposted, txposted;
1150 
1151 	DBUSTRACE(("%s: unlink all URBs\n", __FUNCTION__));
1152 
1153 #ifdef USBOS_TX_THREAD
1154 	usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
1155 
1156 	/* Yield the CPU to TX thread so all pending requests are submitted */
1157 	while (!list_empty(&usbos_info->usbos_tx_list)) {
1158 		wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
1159 		OSL_SLEEP(10);
1160 	}
1161 #endif /* USBOS_TX_THREAD */
1162 
1163 	/* tell Linux kernel to cancel a single intr, ctl and blk URB */
1164 	if (usbos_info->intr_urb)
1165 		USB_UNLINK_URB(usbos_info->intr_urb);
1166 	if (usbos_info->ctl_urb)
1167 		USB_UNLINK_URB(usbos_info->ctl_urb);
1168 	if (usbos_info->blk_urb)
1169 		USB_UNLINK_URB(usbos_info->blk_urb);
1170 
1171 	dbus_usbos_unlink(&usbos_info->req_txpostedq, &usbos_info->txposted_lock);
1172 	dbus_usbos_unlink(&usbos_info->req_rxpostedq, &usbos_info->rxposted_lock);
1173 
1174 	/* Wait until the callbacks for all submitted URBs have been called, because the
1175 	 * handler needs to know is an USB suspend is in progress.
1176 	 */
1177 	SPINWAIT((atomic_read(&usbos_info->txposted) != 0 ||
1178 		atomic_read(&usbos_info->rxposted) != 0), 10000);
1179 
1180 	txposted = atomic_read(&usbos_info->txposted);
1181 	rxposted = atomic_read(&usbos_info->rxposted);
1182 	if (txposted != 0 || rxposted != 0) {
1183 		DBUSERR(("%s ERROR: REQs posted, rx=%d tx=%d!\n",
1184 			__FUNCTION__, rxposted, txposted));
1185 	}
1186 } /* dbus_usbos_cancel_all_urbs */
1187 
1188 /** multiple code paths require the bus to stop */
1189 static void
dbusos_stop(usbos_info_t * usbos_info)1190 dbusos_stop(usbos_info_t *usbos_info)
1191 {
1192 	urb_req_t *req;
1193 	int rxposted;
1194 	req = NULL;
1195 	BCM_REFERENCE(req);
1196 
1197 	ASSERT(usbos_info);
1198 
1199 	dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
1200 
1201 	dbus_usbos_cancel_all_urbs(usbos_info);
1202 
1203 #ifdef USBOS_THREAD
1204 	/* yield the CPU to rx packet thread */
1205 	while (1) {
1206 		if (atomic_read(&usbos_info->usbos_list_cnt) <= 0)	break;
1207 		wake_up_interruptible(&usbos_info->usbos_queue_head);
1208 		OSL_SLEEP(3);
1209 	}
1210 #endif /* USBOS_THREAD */
1211 
1212 	rxposted = atomic_read(&usbos_info->rxposted);
1213 	if (rxposted > 0) {
1214 		DBUSERR(("%s ERROR: rx REQs posted=%d in stop!\n", __FUNCTION__,
1215 			rxposted));
1216 	}
1217 
1218 	ASSERT(atomic_read(&usbos_info->txposted) == 0 && rxposted == 0);
1219 
1220 } /* dbusos_stop */
1221 
1222 #if defined(USB_SUSPEND_AVAILABLE)
1223 
1224 /**
1225  * Linux kernel sports a 'USB auto suspend' feature. See: http://lwn.net/Articles/373550/
1226  * The suspend method is called by the Linux kernel to warn the driver that the device is going to
1227  * be suspended.  If the driver returns a negative error code, the suspend will be aborted. If the
1228  * driver returns 0, it must cancel all outstanding URBs (usb_kill_urb()) and not submit any more.
1229  */
1230 static int
dbus_usbos_suspend(struct usb_interface * intf,pm_message_t message)1231 dbus_usbos_suspend(struct usb_interface *intf,
1232             pm_message_t message)
1233 {
1234 	DBUSERR(("%s suspend state: %d\n", __FUNCTION__, g_probe_info.suspend_state));
1235 	/* DHD for full dongle model */
1236 	g_probe_info.suspend_state = USBOS_SUSPEND_STATE_SUSPEND_PENDING;
1237 	dbus_usbos_state_change((usbos_info_t*)g_probe_info.usbos_info, DBUS_STATE_SLEEP);
1238 	dbus_usbos_cancel_all_urbs((usbos_info_t*)g_probe_info.usbos_info);
1239 	g_probe_info.suspend_state = USBOS_SUSPEND_STATE_SUSPENDED;
1240 
1241 	return 0;
1242 }
1243 
1244 /**
1245  * The resume method is called to tell the driver that the device has been resumed and the driver
1246  * can return to normal operation.  URBs may once more be submitted.
1247  */
dbus_usbos_resume(struct usb_interface * intf)1248 static int dbus_usbos_resume(struct usb_interface *intf)
1249 {
1250 	DBUSERR(("%s Device resumed\n", __FUNCTION__));
1251 
1252 	dbus_usbos_state_change((usbos_info_t*)g_probe_info.usbos_info, DBUS_STATE_UP);
1253 	g_probe_info.suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
1254 	return 0;
1255 }
1256 
1257 /**
1258 * This function is directly called by the Linux kernel, when the suspended device has been reset
1259 * instead of being resumed
1260 */
dbus_usbos_reset_resume(struct usb_interface * intf)1261 static int dbus_usbos_reset_resume(struct usb_interface *intf)
1262 {
1263 	DBUSERR(("%s Device reset resumed\n", __FUNCTION__));
1264 
1265 	/* The device may have lost power, so a firmware download may be required */
1266 	dbus_usbos_state_change((usbos_info_t*)g_probe_info.usbos_info, DBUS_STATE_DL_NEEDED);
1267 	g_probe_info.suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
1268 	return 0;
1269 }
1270 
1271 #endif /* USB_SUSPEND_AVAILABLE */
1272 
1273 /**
1274  * Called by Linux kernel at initialization time, kernel wants to know if our driver will accept the
1275  * caller supplied USB interface. Note that USB drivers are bound to interfaces, and not to USB
1276  * devices.
1277  */
1278 #ifdef KERNEL26
1279 #define DBUS_USBOS_PROBE() static int dbus_usbos_probe(struct usb_interface *intf, const struct usb_device_id *id)
1280 #define DBUS_USBOS_DISCONNECT() static void dbus_usbos_disconnect(struct usb_interface *intf)
1281 #else
1282 #define DBUS_USBOS_PROBE() static void * dbus_usbos_probe(struct usb_device *usb, unsigned int ifnum, const struct usb_device_id *id)
1283 #define DBUS_USBOS_DISCONNECT() static void dbus_usbos_disconnect(struct usb_device *usb, void *ptr)
1284 #endif /* KERNEL26 */
1285 
DBUS_USBOS_PROBE()1286 DBUS_USBOS_PROBE()
1287 {
1288 	int ep;
1289 	struct usb_endpoint_descriptor *endpoint;
1290 	int ret = 0;
1291 #ifdef KERNEL26
1292 	struct usb_device *usb = interface_to_usbdev(intf);
1293 #else
1294 	int claimed = 0;
1295 #endif
1296 	int num_of_eps;
1297 #ifdef BCMUSBDEV_COMPOSITE
1298 	int wlan_if = -1;
1299 	bool intr_ep = FALSE;
1300 #endif /* BCMUSBDEV_COMPOSITE */
1301 	wifi_adapter_info_t *adapter;
1302 
1303 	DHD_MUTEX_LOCK();
1304 
1305 	DBUSERR(("%s: bus num(busnum)=%d, slot num (portnum)=%d\n", __FUNCTION__,
1306 		usb->bus->busnum, usb->portnum));
1307 	adapter = dhd_wifi_platform_attach_adapter(USB_BUS, usb->bus->busnum,
1308 		usb->portnum, WIFI_STATUS_POWER_ON);
1309 	if (adapter == NULL) {
1310 		DBUSERR(("%s: can't find adapter info for this chip\n", __FUNCTION__));
1311 		goto fail;
1312 	}
1313 
1314 #ifdef BCMUSBDEV_COMPOSITE
1315 	wlan_if = dbus_usbos_intf_wlan(usb);
1316 #ifdef KERNEL26
1317 	if ((wlan_if >= 0) && (IFPTR(usb, wlan_if) == intf))
1318 #else
1319 	if (wlan_if == ifnum)
1320 #endif /* KERNEL26 */
1321 	{
1322 #endif /* BCMUSBDEV_COMPOSITE */
1323 		g_probe_info.usb = usb;
1324 		g_probe_info.dldone = TRUE;
1325 #ifdef BCMUSBDEV_COMPOSITE
1326 	} else {
1327 		DBUSTRACE(("dbus_usbos_probe: skip probe for non WLAN interface\n"));
1328 		ret = BCME_UNSUPPORTED;
1329 		goto fail;
1330 	}
1331 #endif /* BCMUSBDEV_COMPOSITE */
1332 
1333 #ifdef KERNEL26
1334 	g_probe_info.intf = intf;
1335 #endif /* KERNEL26 */
1336 
1337 #ifdef BCMUSBDEV_COMPOSITE
1338 	if (IFDESC(usb, wlan_if).bInterfaceNumber > USB_COMPIF_MAX)
1339 #else
1340 	if (IFDESC(usb, CONTROL_IF).bInterfaceNumber)
1341 #endif /* BCMUSBDEV_COMPOSITE */
1342 	{
1343 		ret = -1;
1344 		goto fail;
1345 	}
1346 	if (id != NULL) {
1347 		g_probe_info.vid = id->idVendor;
1348 		g_probe_info.pid = id->idProduct;
1349 	}
1350 
1351 #ifdef KERNEL26
1352 	usb_set_intfdata(intf, &g_probe_info);
1353 #endif
1354 
1355 	/* Check that the device supports only one configuration */
1356 	if (usb->descriptor.bNumConfigurations != 1) {
1357 		ret = -1;
1358 		goto fail;
1359 	}
1360 
1361 	if (usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) {
1362 #ifdef BCMUSBDEV_COMPOSITE
1363 		if ((usb->descriptor.bDeviceClass != USB_CLASS_MISC) &&
1364 			(usb->descriptor.bDeviceClass != USB_CLASS_WIRELESS)) {
1365 #endif /* BCMUSBDEV_COMPOSITE */
1366 			ret = -1;
1367 			goto fail;
1368 #ifdef BCMUSBDEV_COMPOSITE
1369 		}
1370 #endif /* BCMUSBDEV_COMPOSITE */
1371 	}
1372 
1373 	/*
1374 	 * Only the BDC interface configuration is supported:
1375 	 *	Device class: USB_CLASS_VENDOR_SPEC
1376 	 *	if0 class: USB_CLASS_VENDOR_SPEC
1377 	 *	if0/ep0: control
1378 	 *	if0/ep1: bulk in
1379 	 *	if0/ep2: bulk out (ok if swapped with bulk in)
1380 	 */
1381 	if (CONFIGDESC(usb)->bNumInterfaces != 1) {
1382 #ifdef BCMUSBDEV_COMPOSITE
1383 		if (CONFIGDESC(usb)->bNumInterfaces > USB_COMPIF_MAX) {
1384 #endif /* BCMUSBDEV_COMPOSITE */
1385 			ret = -1;
1386 			goto fail;
1387 #ifdef BCMUSBDEV_COMPOSITE
1388 		}
1389 #endif /* BCMUSBDEV_COMPOSITE */
1390 	}
1391 
1392 	/* Check interface */
1393 #ifndef KERNEL26
1394 #ifdef BCMUSBDEV_COMPOSITE
1395 	if (usb_interface_claimed(IFPTR(usb, wlan_if)))
1396 #else
1397 	if (usb_interface_claimed(IFPTR(usb, CONTROL_IF)))
1398 #endif /* BCMUSBDEV_COMPOSITE */
1399 	{
1400 		ret = -1;
1401 		goto fail;
1402 	}
1403 #endif /* !KERNEL26 */
1404 
1405 #ifdef BCMUSBDEV_COMPOSITE
1406 	if ((IFDESC(usb, wlan_if).bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
1407 		IFDESC(usb, wlan_if).bInterfaceSubClass != 2 ||
1408 		IFDESC(usb, wlan_if).bInterfaceProtocol != 0xff) &&
1409 		(IFDESC(usb, wlan_if).bInterfaceClass != USB_CLASS_MISC ||
1410 		IFDESC(usb, wlan_if).bInterfaceSubClass != USB_SUBCLASS_COMMON ||
1411 		IFDESC(usb, wlan_if).bInterfaceProtocol != USB_PROTO_IAD))
1412 #else
1413 	if (IFDESC(usb, CONTROL_IF).bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
1414 		IFDESC(usb, CONTROL_IF).bInterfaceSubClass != 2 ||
1415 		IFDESC(usb, CONTROL_IF).bInterfaceProtocol != 0xff)
1416 #endif /* BCMUSBDEV_COMPOSITE */
1417 	{
1418 #ifdef BCMUSBDEV_COMPOSITE
1419 			DBUSERR(("%s: invalid control interface: class %d, subclass %d, proto %d\n",
1420 				__FUNCTION__,
1421 				IFDESC(usb, wlan_if).bInterfaceClass,
1422 				IFDESC(usb, wlan_if).bInterfaceSubClass,
1423 				IFDESC(usb, wlan_if).bInterfaceProtocol));
1424 #else
1425 			DBUSERR(("%s: invalid control interface: class %d, subclass %d, proto %d\n",
1426 				__FUNCTION__,
1427 				IFDESC(usb, CONTROL_IF).bInterfaceClass,
1428 				IFDESC(usb, CONTROL_IF).bInterfaceSubClass,
1429 				IFDESC(usb, CONTROL_IF).bInterfaceProtocol));
1430 #endif /* BCMUSBDEV_COMPOSITE */
1431 			ret = -1;
1432 			goto fail;
1433 	}
1434 
1435 	/* Check control endpoint */
1436 #ifdef BCMUSBDEV_COMPOSITE
1437 	endpoint = &IFEPDESC(usb, wlan_if, 0);
1438 #else
1439 	endpoint = &IFEPDESC(usb, CONTROL_IF, 0);
1440 #endif /* BCMUSBDEV_COMPOSITE */
1441 	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
1442 #ifdef BCMUSBDEV_COMPOSITE
1443 		if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
1444 			USB_ENDPOINT_XFER_BULK) {
1445 #endif /* BCMUSBDEV_COMPOSITE */
1446 			DBUSERR(("%s: invalid control endpoint %d\n",
1447 				__FUNCTION__, endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK));
1448 			ret = -1;
1449 			goto fail;
1450 #ifdef BCMUSBDEV_COMPOSITE
1451 		}
1452 #endif /* BCMUSBDEV_COMPOSITE */
1453 	}
1454 
1455 #ifdef BCMUSBDEV_COMPOSITE
1456 	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
1457 #endif /* BCMUSBDEV_COMPOSITE */
1458 		g_probe_info.intr_pipe =
1459 			usb_rcvintpipe(usb, endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
1460 #ifdef BCMUSBDEV_COMPOSITE
1461 		intr_ep = TRUE;
1462 	}
1463 #endif /* BCMUSBDEV_COMPOSITE */
1464 
1465 #ifndef KERNEL26
1466 	/* Claim interface */
1467 #ifdef BCMUSBDEV_COMPOSITE
1468 	usb_driver_claim_interface(&dbus_usbdev, IFPTR(usb, wlan_if), &g_probe_info);
1469 #else
1470 	usb_driver_claim_interface(&dbus_usbdev, IFPTR(usb, CONTROL_IF), &g_probe_info);
1471 #endif /* BCMUSBDEV_COMPOSITE */
1472 	claimed = 1;
1473 #endif /* !KERNEL26 */
1474 	g_probe_info.rx_pipe = 0;
1475 	g_probe_info.rx_pipe2 = 0;
1476 	g_probe_info.tx_pipe = 0;
1477 #ifdef BCMUSBDEV_COMPOSITE
1478 	if (intr_ep)
1479 		ep = 1;
1480 	else
1481 		ep = 0;
1482 	num_of_eps = IFDESC(usb, wlan_if).bNumEndpoints - 1;
1483 #else
1484 	num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
1485 #endif /* BCMUSBDEV_COMPOSITE */
1486 
1487 	if ((num_of_eps != 2) && (num_of_eps != 3)) {
1488 #ifdef BCMUSBDEV_COMPOSITE
1489 		if (num_of_eps > 7)
1490 #endif /* BCMUSBDEV_COMPOSITE */
1491 			ASSERT(0);
1492 	}
1493 	/* Check data endpoints and get pipes */
1494 #ifdef BCMUSBDEV_COMPOSITE
1495 	for (; ep <= num_of_eps; ep++)
1496 #else
1497 	for (ep = 1; ep <= num_of_eps; ep++)
1498 #endif /* BCMUSBDEV_COMPOSITE */
1499 	{
1500 #ifdef BCMUSBDEV_COMPOSITE
1501 		endpoint = &IFEPDESC(usb, wlan_if, ep);
1502 #else
1503 		endpoint = &IFEPDESC(usb, BULK_IF, ep);
1504 #endif /* BCMUSBDEV_COMPOSITE */
1505 		if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
1506 		    USB_ENDPOINT_XFER_BULK) {
1507 			DBUSERR(("%s: invalid data endpoint %d\n",
1508 			           __FUNCTION__, ep));
1509 			ret = -1;
1510 			goto fail;
1511 		}
1512 
1513 		if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
1514 			/* direction: dongle->host */
1515 			if (!g_probe_info.rx_pipe) {
1516 				g_probe_info.rx_pipe = usb_rcvbulkpipe(usb,
1517 					(endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK));
1518 			} else {
1519 				g_probe_info.rx_pipe2 = usb_rcvbulkpipe(usb,
1520 					(endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK));
1521 			}
1522 
1523 		} else
1524 			g_probe_info.tx_pipe = usb_sndbulkpipe(usb, (endpoint->bEndpointAddress &
1525 			     USB_ENDPOINT_NUMBER_MASK));
1526 	}
1527 
1528 	/* Allocate interrupt URB and data buffer */
1529 	/* RNDIS says 8-byte intr, our old drivers used 4-byte */
1530 #ifdef BCMUSBDEV_COMPOSITE
1531 	g_probe_info.intr_size = (IFEPDESC(usb, wlan_if, 0).wMaxPacketSize == 16) ? 8 : 4;
1532 	g_probe_info.interval = IFEPDESC(usb, wlan_if, 0).bInterval;
1533 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21))
1534 	usb->quirks |= USB_QUIRK_NO_SET_INTF;
1535 #endif
1536 #else
1537 	g_probe_info.intr_size = (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == 16) ? 8 : 4;
1538 	g_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
1539 #endif /* BCMUSBDEV_COMPOSITE */
1540 
1541 #ifndef KERNEL26
1542 	/* usb_fill_int_urb does the interval decoding in 2.6 */
1543 	if (usb->speed == USB_SPEED_HIGH)
1544 		g_probe_info.interval = 1 << (g_probe_info.interval - 1);
1545 #endif
1546 	if (usb->speed == USB_SPEED_SUPER) {
1547 		g_probe_info.device_speed = SUPER_SPEED;
1548 		DBUSERR(("super speed device detected\n"));
1549 	} else if (usb->speed == USB_SPEED_HIGH) {
1550 		g_probe_info.device_speed = HIGH_SPEED;
1551 		DBUSERR(("high speed device detected\n"));
1552 	} else {
1553 		g_probe_info.device_speed = FULL_SPEED;
1554 		DBUSERR(("full speed device detected\n"));
1555 	}
1556 	if (g_probe_info.dereged == FALSE && probe_cb) {
1557 		disc_arg = probe_cb(probe_arg, "", USB_BUS, usb->bus->busnum, usb->portnum, 0);
1558 	}
1559 
1560 	g_probe_info.disc_cb_done = FALSE;
1561 
1562 #ifdef KERNEL26
1563 	intf->needs_remote_wakeup = 1;
1564 #endif /* KERNEL26 */
1565 	DHD_MUTEX_UNLOCK();
1566 
1567 	/* Success */
1568 #ifdef KERNEL26
1569 	return DBUS_OK;
1570 #else
1571 	usb_inc_dev_use(usb);
1572 	return &g_probe_info;
1573 #endif
1574 
1575 fail:
1576 	printf("%s: Exit ret=%d\n", __FUNCTION__, ret);
1577 #ifdef BCMUSBDEV_COMPOSITE
1578 	if (ret != BCME_UNSUPPORTED)
1579 #endif /* BCMUSBDEV_COMPOSITE */
1580 		DBUSERR(("%s: failed with errno %d\n", __FUNCTION__, ret));
1581 #ifndef KERNEL26
1582 	if (claimed)
1583 #ifdef BCMUSBDEV_COMPOSITE
1584 		usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, wlan_if));
1585 #else
1586 		usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, CONTROL_IF));
1587 #endif /* BCMUSBDEV_COMPOSITE */
1588 #endif /* !KERNEL26 */
1589 
1590 	DHD_MUTEX_UNLOCK();
1591 #ifdef KERNEL26
1592 	usb_set_intfdata(intf, NULL);
1593 	return ret;
1594 #else
1595 	return NULL;
1596 #endif
1597 } /* dbus_usbos_probe */
1598 
1599 /** Called by Linux kernel, is the counter part of dbus_usbos_probe() */
DBUS_USBOS_DISCONNECT()1600 DBUS_USBOS_DISCONNECT()
1601 {
1602 #ifdef KERNEL26
1603 	struct usb_device *usb = interface_to_usbdev(intf);
1604 	probe_info_t *probe_usb_init_data = usb_get_intfdata(intf);
1605 #else
1606 	probe_info_t *probe_usb_init_data = (probe_info_t *) ptr;
1607 #endif
1608 	usbos_info_t *usbos_info;
1609 
1610 	DHD_MUTEX_LOCK();
1611 
1612 	DBUSERR(("%s: bus num(busnum)=%d, slot num (portnum)=%d\n", __FUNCTION__,
1613 		usb->bus->busnum, usb->portnum));
1614 
1615 	if (probe_usb_init_data) {
1616 		usbos_info = (usbos_info_t *) probe_usb_init_data->usbos_info;
1617 		if (usbos_info) {
1618 			if ((probe_usb_init_data->dereged == FALSE) && disconnect_cb && disc_arg) {
1619 				disconnect_cb(disc_arg);
1620 				disc_arg = NULL;
1621 				probe_usb_init_data->disc_cb_done = TRUE;
1622 			}
1623 		}
1624 	}
1625 
1626 	if (usb) {
1627 #ifndef KERNEL26
1628 #ifdef BCMUSBDEV_COMPOSITE
1629 		usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, wlan_if));
1630 #else
1631 		usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, CONTROL_IF));
1632 #endif /* BCMUSBDEV_COMPOSITE */
1633 		usb_dec_dev_use(usb);
1634 #endif /* !KERNEL26 */
1635 	}
1636 	DHD_MUTEX_UNLOCK();
1637 } /* dbus_usbos_disconnect */
1638 
1639 #define LOOPBACK_PKT_START 0xBABE1234
1640 
is_loopback_pkt(void * buf)1641 bool is_loopback_pkt(void *buf)
1642 {
1643 
1644 	uint32 *buf_ptr = (uint32 *) buf;
1645 
1646 	if (*buf_ptr == LOOPBACK_PKT_START)
1647 		return TRUE;
1648 	return FALSE;
1649 
1650 }
1651 
matches_loopback_pkt(void * buf)1652 int matches_loopback_pkt(void *buf)
1653 {
1654 	int i, j;
1655 	unsigned char *cbuf = (unsigned char *) buf;
1656 
1657 	for (i = 4; i < loopback_size; i++) {
1658 		if (cbuf[i] != (i % 256)) {
1659 			printf("%s: mismatch at i=%d %d : ", __FUNCTION__, i, cbuf[i]);
1660 			for (j = i; ((j < i+ 16) && (j < loopback_size)); j++) {
1661 				printf("%d ", cbuf[j]);
1662 			}
1663 			printf("\n");
1664 			return 0;
1665 		}
1666 	}
1667 	loopback_rx_cnt++;
1668 	return 1;
1669 }
1670 
dbus_usbos_loopback_tx(void * usbos_info_ptr,int cnt,int size)1671 int dbus_usbos_loopback_tx(void *usbos_info_ptr, int cnt, int size)
1672 {
1673 	usbos_info_t *usbos_info = (usbos_info_t *) usbos_info_ptr;
1674 	unsigned char *buf;
1675 	int j;
1676 	void* p = NULL;
1677 	int rc, last_rx_cnt;
1678 	int tx_failed_cnt;
1679 	int max_size = 1650;
1680 	int usb_packet_size = 512;
1681 	int min_packet_size = 10;
1682 
1683 	if (size % usb_packet_size == 0) {
1684 		size = size - 1;
1685 		DBUSERR(("%s: overriding size=%d \n", __FUNCTION__, size));
1686 	}
1687 
1688 	if (size < min_packet_size) {
1689 		size = min_packet_size;
1690 		DBUSERR(("%s: overriding size=%d\n", __FUNCTION__, min_packet_size));
1691 	}
1692 	if (size > max_size) {
1693 		size = max_size;
1694 		DBUSERR(("%s: overriding size=%d\n", __FUNCTION__, max_size));
1695 	}
1696 
1697 	loopback_tx_cnt = 0;
1698 	loopback_rx_cnt = 0;
1699 	tx_failed_cnt = 0;
1700 	loopback_size   = size;
1701 
1702 	while (loopback_tx_cnt < cnt) {
1703 		uint32 *x;
1704 		int pkt_size = loopback_size;
1705 
1706 		p = PKTGET(usbos_info->pub->osh, pkt_size, TRUE);
1707 		if (p == NULL) {
1708 			DBUSERR(("%s:%d Failed to allocate packet sz=%d\n",
1709 			       __FUNCTION__, __LINE__, pkt_size));
1710 			return BCME_ERROR;
1711 		}
1712 		x = (uint32*) PKTDATA(usbos_info->pub->osh, p);
1713 		*x = LOOPBACK_PKT_START;
1714 		buf = (unsigned char*) x;
1715 		for (j = 4; j < pkt_size; j++) {
1716 			buf[j] = j % 256;
1717 		}
1718 		rc = dbus_send_buf(usbos_info->pub, buf, pkt_size, p);
1719 		if (rc != BCME_OK) {
1720 			DBUSERR(("%s:%d Freeing packet \n", __FUNCTION__, __LINE__));
1721 			PKTFREE(usbos_info->pub->osh, p, TRUE);
1722 			dbus_usbos_wait(usbos_info, 1);
1723 			tx_failed_cnt++;
1724 		} else {
1725 			loopback_tx_cnt++;
1726 			tx_failed_cnt = 0;
1727 		}
1728 		if (tx_failed_cnt == 5) {
1729 			DBUSERR(("%s : Failed to send loopback packets cnt=%d loopback_tx_cnt=%d\n",
1730 			 __FUNCTION__, cnt, loopback_tx_cnt));
1731 			break;
1732 		}
1733 	}
1734 	printf("Transmitted %d loopback packets of size %d\n", loopback_tx_cnt, loopback_size);
1735 
1736 	last_rx_cnt = loopback_rx_cnt;
1737 	while (loopback_rx_cnt < loopback_tx_cnt) {
1738 		dbus_usbos_wait(usbos_info, 1);
1739 		if (loopback_rx_cnt <= last_rx_cnt) {
1740 			DBUSERR(("%s: Matched rx cnt stuck at %d \n", __FUNCTION__, last_rx_cnt));
1741 			return BCME_ERROR;
1742 		}
1743 		last_rx_cnt = loopback_rx_cnt;
1744 	}
1745 	printf("Received %d loopback packets of size %d\n", loopback_tx_cnt, loopback_size);
1746 
1747 	return BCME_OK;
1748 } /* dbus_usbos_loopback_tx */
1749 
1750 /**
1751  * Higher layer (dbus_usb.c) wants to transmit an I/O Request Block
1752  *     @param[in] txirb txirb->pkt, if non-zero, contains a single or a chain of packets
1753  */
1754 static int
dbus_usbos_intf_send_irb(void * bus,dbus_irb_tx_t * txirb)1755 dbus_usbos_intf_send_irb(void *bus, dbus_irb_tx_t *txirb)
1756 {
1757 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
1758 	urb_req_t *req, *req_zlp = NULL;
1759 	int ret = DBUS_OK;
1760 	unsigned long flags;
1761 	void *pkt;
1762 	uint32 buffer_length;
1763 	uint8 *buf;
1764 
1765 	if ((usbos_info == NULL) || !usbos_info->tx_pipe) {
1766 		return DBUS_ERR;
1767 	}
1768 
1769 	if (txirb->pkt != NULL) {
1770 		buffer_length = pkttotlen(usbos_info->pub->osh, txirb->pkt);
1771 		/* In case of multiple packets the values below may be overwritten */
1772 		txirb->send_buf = NULL;
1773 		buf = PKTDATA(usbos_info->pub->osh, txirb->pkt);
1774 	} else { /* txirb->buf != NULL */
1775 		ASSERT(txirb->buf != NULL);
1776 		ASSERT(txirb->send_buf == NULL);
1777 		buffer_length = txirb->len;
1778 		buf = txirb->buf;
1779 	}
1780 
1781 	if (!(req = dbus_usbos_qdeq(&usbos_info->req_txfreeq, &usbos_info->txfree_lock))) {
1782 		DBUSERR(("%s No free URB!\n", __FUNCTION__));
1783 		return DBUS_ERR_TXDROP;
1784 	}
1785 
1786 	/* If not using standard Linux kernel functionality for handling Zero Length Packet(ZLP),
1787 	 * the dbus needs to generate ZLP when length is multiple of MaxPacketSize.
1788 	 */
1789 #ifndef WL_URB_ZPKT
1790 	if (!(buffer_length % usbos_info->maxps)) {
1791 		if (!(req_zlp =
1792 			dbus_usbos_qdeq(&usbos_info->req_txfreeq, &usbos_info->txfree_lock))) {
1793 			DBUSERR(("%s No free URB for ZLP!\n", __FUNCTION__));
1794 			dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
1795 			return DBUS_ERR_TXDROP;
1796 		}
1797 
1798 		/* No txirb, so that dbus_usbos_send_complete can differentiate between
1799 		 * DATA and ZLP.
1800 		 */
1801 		req_zlp->arg = NULL;
1802 		req_zlp->usbinfo = usbos_info;
1803 		req_zlp->buf_len = 0;
1804 
1805 		usb_fill_bulk_urb(req_zlp->urb, usbos_info->usb, usbos_info->tx_pipe, NULL,
1806 			0, (usb_complete_t)dbus_usbos_send_complete, req_zlp);
1807 
1808 		req_zlp->urb->transfer_flags |= URB_QUEUE_BULK;
1809 	}
1810 #endif /* !WL_URB_ZPKT */
1811 
1812 #ifndef USBOS_TX_THREAD
1813 	/* Disable USB autosuspend until this request completes, request USB resume if needed.
1814 	 * Because this call runs asynchronously, there is no guarantee the bus is resumed before
1815 	 * the URB is submitted, and the URB might be dropped. Use USBOS_TX_THREAD to avoid
1816 	 * this.
1817 	 */
1818 	USB_AUTOPM_GET_INTERFACE_ASYNC(g_probe_info.intf);
1819 #endif /* !USBOS_TX_THREAD */
1820 
1821 	spin_lock_irqsave(&usbos_info->txlock, flags);
1822 
1823 	req->arg = txirb;
1824 	req->usbinfo = usbos_info;
1825 	req->buf_len = 0;
1826 
1827 	/* Prepare the URB */
1828 	if (txirb->pkt != NULL) {
1829 		uint32 pktlen;
1830 		uint8 *transfer_buf;
1831 
1832 		/* For multiple packets, allocate contiguous buffer and copy packet data to it */
1833 		if (PKTNEXT(usbos_info->pub->osh, txirb->pkt)) {
1834 			transfer_buf = MALLOC(usbos_info->pub->osh, buffer_length);
1835 			if (!transfer_buf) {
1836 				ret = DBUS_ERR_TXDROP;
1837 				DBUSERR(("fail to alloc to usb buffer\n"));
1838 				goto fail;
1839 			}
1840 
1841 			pkt = txirb->pkt;
1842 			txirb->send_buf = transfer_buf;
1843 			req->buf_len = buffer_length;
1844 
1845 			while (pkt) {
1846 				pktlen = PKTLEN(usbos_info->pub->osh, pkt);
1847 				bcopy(PKTDATA(usbos_info->pub->osh, pkt), transfer_buf, pktlen);
1848 				transfer_buf += pktlen;
1849 				pkt = PKTNEXT(usbos_info->pub->osh, pkt);
1850 			}
1851 
1852 			ASSERT(((uint8 *) txirb->send_buf + buffer_length) == transfer_buf);
1853 
1854 			/* Overwrite buf pointer with pointer to allocated contiguous transfer_buf
1855 			 */
1856 			buf = txirb->send_buf;
1857 		}
1858 	}
1859 
1860 	usb_fill_bulk_urb(req->urb, usbos_info->usb, usbos_info->tx_pipe, buf,
1861 		buffer_length, (usb_complete_t)dbus_usbos_send_complete, req);
1862 
1863 	req->urb->transfer_flags |= URB_QUEUE_BULK;
1864 
1865 #ifdef USBOS_TX_THREAD
1866 	/* Enqueue TX request, the TX thread will resume the bus if needed and submit
1867 	 * it asynchronously
1868 	 */
1869 	dbus_usbos_qenq(&usbos_info->usbos_tx_list, req, &usbos_info->usbos_tx_list_lock);
1870 	if (req_zlp != NULL) {
1871 		dbus_usbos_qenq(&usbos_info->usbos_tx_list, req_zlp,
1872 			&usbos_info->usbos_tx_list_lock);
1873 	}
1874 	spin_unlock_irqrestore(&usbos_info->txlock, flags);
1875 
1876 	wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
1877 	return DBUS_OK;
1878 #else
1879 	if ((ret = USB_SUBMIT_URB(req->urb))) {
1880 		ret = DBUS_ERR_TXDROP;
1881 		goto fail;
1882 	}
1883 
1884 	dbus_usbos_qenq(&usbos_info->req_txpostedq, req, &usbos_info->txposted_lock);
1885 	atomic_inc(&usbos_info->txposted);
1886 
1887 	if (req_zlp != NULL) {
1888 		if ((ret = USB_SUBMIT_URB(req_zlp->urb))) {
1889 			DBUSERR(("failed to submit ZLP URB!\n"));
1890 			ASSERT(0);
1891 			ret = DBUS_ERR_TXDROP;
1892 			goto fail2;
1893 		}
1894 
1895 		dbus_usbos_qenq(&usbos_info->req_txpostedq, req_zlp, &usbos_info->txposted_lock);
1896 		/* Also increment txposted for zlp packet, as it will be decremented in
1897 		 * dbus_usbos_send_complete()
1898 		 */
1899 		atomic_inc(&usbos_info->txposted);
1900 	}
1901 
1902 	spin_unlock_irqrestore(&usbos_info->txlock, flags);
1903 	return DBUS_OK;
1904 #endif /* USBOS_TX_THREAD */
1905 
1906 fail:
1907 	if (txirb->send_buf != NULL) {
1908 		MFREE(usbos_info->pub->osh, txirb->send_buf, req->buf_len);
1909 		txirb->send_buf = NULL;
1910 		req->buf_len = 0;
1911 	}
1912 	dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
1913 #ifndef USBOS_TX_THREAD
1914 fail2:
1915 #endif
1916 	if (req_zlp != NULL) {
1917 		dbus_usbos_qenq(&usbos_info->req_txfreeq, req_zlp, &usbos_info->txfree_lock);
1918 	}
1919 
1920 	spin_unlock_irqrestore(&usbos_info->txlock, flags);
1921 
1922 #ifndef USBOS_TX_THREAD
1923 	USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
1924 #endif /* !USBOS_TX_THREAD */
1925 
1926 	return ret;
1927 } /* dbus_usbos_intf_send_irb */
1928 
1929 /** Higher layer (dbus_usb.c) recycles a received (and used) packet. */
1930 static int
dbus_usbos_intf_recv_irb(void * bus,dbus_irb_rx_t * rxirb)1931 dbus_usbos_intf_recv_irb(void *bus, dbus_irb_rx_t *rxirb)
1932 {
1933 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
1934 	int ret = DBUS_OK;
1935 
1936 	if (usbos_info == NULL)
1937 		return DBUS_ERR;
1938 
1939 	ret = dbus_usbos_recv_urb_submit(usbos_info, rxirb, 0);
1940 	return ret;
1941 }
1942 
1943 static int
dbus_usbos_intf_recv_irb_from_ep(void * bus,dbus_irb_rx_t * rxirb,uint32 ep_idx)1944 dbus_usbos_intf_recv_irb_from_ep(void *bus, dbus_irb_rx_t *rxirb, uint32 ep_idx)
1945 {
1946 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
1947 	int ret = DBUS_OK;
1948 
1949 	if (usbos_info == NULL)
1950 		return DBUS_ERR;
1951 
1952 #ifdef INTR_EP_ENABLE
1953 		/* By specifying the ep_idx value of 0xff, the cdc layer is asking to
1954 		* submit an interrupt URB
1955 		*/
1956 		if (rxirb == NULL && ep_idx == 0xff) {
1957 			/* submit intr URB */
1958 			if ((ret = USB_SUBMIT_URB(usbos_info->intr_urb)) < 0) {
1959 				DBUSERR(("%s intr USB_SUBMIT_URB failed, status %d\n",
1960 					__FUNCTION__, ret));
1961 			}
1962 			return ret;
1963 		}
1964 #else
1965 		if (rxirb == NULL) {
1966 			return DBUS_ERR;
1967 		}
1968 #endif /* INTR_EP_ENABLE */
1969 
1970 	ret = dbus_usbos_recv_urb_submit(usbos_info, rxirb, ep_idx);
1971 	return ret;
1972 }
1973 
1974 /** Higher layer (dbus_usb.c) want to cancel an IRB */
1975 static int
dbus_usbos_intf_cancel_irb(void * bus,dbus_irb_tx_t * txirb)1976 dbus_usbos_intf_cancel_irb(void *bus, dbus_irb_tx_t *txirb)
1977 {
1978 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
1979 
1980 	if (usbos_info == NULL)
1981 		return DBUS_ERR;
1982 
1983 	return DBUS_ERR;
1984 }
1985 
1986 /** Only one CTL transfer can be pending at any time. This function may block. */
1987 static int
dbus_usbos_intf_send_ctl(void * bus,uint8 * buf,int len)1988 dbus_usbos_intf_send_ctl(void *bus, uint8 *buf, int len)
1989 {
1990 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
1991 	uint16 size;
1992 #ifndef USBOS_TX_THREAD
1993 	int status;
1994 #endif /* USBOS_TX_THREAD */
1995 
1996 	if ((usbos_info == NULL) || (buf == NULL) || (len == 0))
1997 		return DBUS_ERR;
1998 
1999 	if (usbos_info->ctl_urb == NULL)
2000 		return DBUS_ERR;
2001 
2002 	/* Block until a pending CTL transfer has completed */
2003 	if (down_interruptible(&usbos_info->ctl_lock) != 0) {
2004 		return DBUS_ERR_TXCTLFAIL;
2005 	}
2006 
2007 #ifdef USBOS_TX_THREAD
2008 	ASSERT(usbos_info->ctl_state == USBOS_REQUEST_STATE_UNSCHEDULED);
2009 #else
2010 	/* Disable USB autosuspend until this request completes, request USB resume if needed.
2011 	 * Because this call runs asynchronously, there is no guarantee the bus is resumed before
2012 	 * the URB is submitted, and the URB might be dropped. Use USBOS_TX_THREAD to avoid
2013 	 * this.
2014 	 */
2015 	USB_AUTOPM_GET_INTERFACE_ASYNC(g_probe_info.intf);
2016 #endif /* USBOS_TX_THREAD */
2017 
2018 	size = len;
2019 	usbos_info->ctl_write.wLength = cpu_to_le16p(&size);
2020 	usbos_info->ctl_urb->transfer_buffer_length = size;
2021 
2022 	usb_fill_control_urb(usbos_info->ctl_urb,
2023 		usbos_info->usb,
2024 		usb_sndctrlpipe(usbos_info->usb, 0),
2025 		(unsigned char *) &usbos_info->ctl_write,
2026 		buf, size, (usb_complete_t)dbus_usbos_ctlwrite_complete, usbos_info);
2027 
2028 #ifdef USBOS_TX_THREAD
2029 	/* Enqueue CTRL request for transmission by the TX thread. The
2030 	 * USB bus will first be resumed if needed.
2031 	 */
2032 	usbos_info->ctl_state = USBOS_REQUEST_STATE_SCHEDULED;
2033 	wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
2034 #else
2035 	status = USB_SUBMIT_URB(usbos_info->ctl_urb);
2036 	if (status < 0) {
2037 		DBUSERR(("%s: usb_submit_urb failed %d\n", __FUNCTION__, status));
2038 		up(&usbos_info->ctl_lock);
2039 
2040 		USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
2041 
2042 		return DBUS_ERR_TXCTLFAIL;
2043 	}
2044 #endif /* USBOS_TX_THREAD */
2045 
2046 	return DBUS_OK;
2047 } /* dbus_usbos_intf_send_ctl */
2048 
2049 /** This function does not seem to be called by anyone, including dbus_usb.c */
2050 static int
dbus_usbos_intf_recv_ctl(void * bus,uint8 * buf,int len)2051 dbus_usbos_intf_recv_ctl(void *bus, uint8 *buf, int len)
2052 {
2053 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
2054 	int status;
2055 	uint16 size;
2056 
2057 	if ((usbos_info == NULL) || (buf == NULL) || (len == 0))
2058 		return DBUS_ERR;
2059 
2060 	if (usbos_info->ctl_urb == NULL)
2061 		return DBUS_ERR;
2062 
2063 	/* Block until a pending CTRL transfer has completed */
2064 	if (down_interruptible(&usbos_info->ctl_lock) != 0) {
2065 		return DBUS_ERR_TXCTLFAIL;
2066 	}
2067 
2068 	/* Disable USB autosuspend until this request completes, request USB resume if needed. */
2069 	USB_AUTOPM_GET_INTERFACE_ASYNC(g_probe_info.intf);
2070 
2071 	size = len;
2072 	usbos_info->ctl_read.wLength = cpu_to_le16p(&size);
2073 	usbos_info->ctl_urb->transfer_buffer_length = size;
2074 
2075 	if (usbos_info->rxctl_deferrespok) {
2076 		/* BMAC model */
2077 		usbos_info->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR |
2078 			USB_RECIP_INTERFACE;
2079 		usbos_info->ctl_read.bRequest = DL_DEFER_RESP_OK;
2080 	} else {
2081 		/* full dongle model */
2082 		usbos_info->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_CLASS |
2083 			USB_RECIP_INTERFACE;
2084 		usbos_info->ctl_read.bRequest = 1;
2085 	}
2086 
2087 	usb_fill_control_urb(usbos_info->ctl_urb,
2088 		usbos_info->usb,
2089 		usb_rcvctrlpipe(usbos_info->usb, 0),
2090 		(unsigned char *) &usbos_info->ctl_read,
2091 		buf, size, (usb_complete_t)dbus_usbos_ctlread_complete, usbos_info);
2092 
2093 	status = USB_SUBMIT_URB(usbos_info->ctl_urb);
2094 	if (status < 0) {
2095 		DBUSERR(("%s: usb_submit_urb failed %d\n", __FUNCTION__, status));
2096 		up(&usbos_info->ctl_lock);
2097 
2098 		USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
2099 
2100 		return DBUS_ERR_RXCTLFAIL;
2101 	}
2102 
2103 	return DBUS_OK;
2104 }
2105 
2106 static int
dbus_usbos_intf_get_attrib(void * bus,dbus_attrib_t * attrib)2107 dbus_usbos_intf_get_attrib(void *bus, dbus_attrib_t *attrib)
2108 {
2109 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
2110 
2111 	if ((usbos_info == NULL) || (attrib == NULL))
2112 		return DBUS_ERR;
2113 
2114 	attrib->bustype = DBUS_USB;
2115 	attrib->vid = g_probe_info.vid;
2116 	attrib->pid = g_probe_info.pid;
2117 	attrib->devid = 0x4322;
2118 
2119 	attrib->nchan = 1;
2120 
2121 	/* MaxPacketSize for USB hi-speed bulk out is 512 bytes
2122 	 * and 64-bytes for full-speed.
2123 	 * When sending pkt > MaxPacketSize, Host SW breaks it
2124 	 * up into multiple packets.
2125 	 */
2126 	attrib->mtu = usbos_info->maxps;
2127 
2128 	return DBUS_OK;
2129 }
2130 
2131 /** Called by higher layer (dbus_usb.c) when it wants to 'up' the USB interface to the dongle */
2132 static int
dbus_usbos_intf_up(void * bus)2133 dbus_usbos_intf_up(void *bus)
2134 {
2135 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
2136 	uint16 ifnum;
2137 #ifdef BCMUSBDEV_COMPOSITE
2138 	int wlan_if = 0;
2139 #endif
2140 	if (usbos_info == NULL)
2141 		return DBUS_ERR;
2142 
2143 	if (usbos_info->usb == NULL)
2144 		return DBUS_ERR;
2145 
2146 #if defined(INTR_EP_ENABLE)
2147 	/* full dongle use intr EP, bmac doesn't use it */
2148 	if (usbos_info->intr_urb) {
2149 		int ret;
2150 
2151 		usb_fill_int_urb(usbos_info->intr_urb, usbos_info->usb,
2152 			usbos_info->intr_pipe, &usbos_info->intr,
2153 			usbos_info->intr_size, (usb_complete_t)dbus_usbos_intr_complete,
2154 			usbos_info, usbos_info->interval);
2155 
2156 		if ((ret = USB_SUBMIT_URB(usbos_info->intr_urb))) {
2157 			DBUSERR(("%s USB_SUBMIT_URB failed with status %d\n", __FUNCTION__, ret));
2158 			return DBUS_ERR;
2159 		}
2160 	}
2161 #endif
2162 
2163 	if (usbos_info->ctl_urb) {
2164 		usbos_info->ctl_in_pipe = usb_rcvctrlpipe(usbos_info->usb, 0);
2165 		usbos_info->ctl_out_pipe = usb_sndctrlpipe(usbos_info->usb, 0);
2166 
2167 #ifdef BCMUSBDEV_COMPOSITE
2168 		wlan_if = dbus_usbos_intf_wlan(usbos_info->usb);
2169 		ifnum = cpu_to_le16(IFDESC(usbos_info->usb, wlan_if).bInterfaceNumber);
2170 #else
2171 		ifnum = cpu_to_le16(IFDESC(usbos_info->usb, CONTROL_IF).bInterfaceNumber);
2172 #endif /* BCMUSBDEV_COMPOSITE */
2173 		/* CTL Write */
2174 		usbos_info->ctl_write.bRequestType =
2175 			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
2176 		usbos_info->ctl_write.bRequest = 0;
2177 		usbos_info->ctl_write.wValue = cpu_to_le16(0);
2178 		usbos_info->ctl_write.wIndex = cpu_to_le16p(&ifnum);
2179 
2180 		/* CTL Read */
2181 		usbos_info->ctl_read.bRequestType =
2182 			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
2183 		usbos_info->ctl_read.bRequest = 1;
2184 		usbos_info->ctl_read.wValue = cpu_to_le16(0);
2185 		usbos_info->ctl_read.wIndex = cpu_to_le16p(&ifnum);
2186 	}
2187 
2188 	/* Success, indicate usbos_info is fully up */
2189 	dbus_usbos_state_change(usbos_info, DBUS_STATE_UP);
2190 
2191 	return DBUS_OK;
2192 } /* dbus_usbos_intf_up */
2193 
2194 static int
dbus_usbos_intf_down(void * bus)2195 dbus_usbos_intf_down(void *bus)
2196 {
2197 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
2198 
2199 	if (usbos_info == NULL)
2200 		return DBUS_ERR;
2201 
2202 	dbusos_stop(usbos_info);
2203 	return DBUS_OK;
2204 }
2205 
2206 static int
dbus_usbos_intf_stop(void * bus)2207 dbus_usbos_intf_stop(void *bus)
2208 {
2209 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
2210 
2211 	if (usbos_info == NULL)
2212 		return DBUS_ERR;
2213 
2214 	dbusos_stop(usbos_info);
2215 	return DBUS_OK;
2216 }
2217 
2218 
2219 /** Called by higher layer (dbus_usb.c) */
2220 static int
dbus_usbos_intf_set_config(void * bus,dbus_config_t * config)2221 dbus_usbos_intf_set_config(void *bus, dbus_config_t *config)
2222 {
2223 	int err = DBUS_ERR;
2224 	usbos_info_t* usbos_info = bus;
2225 
2226 	if (config->config_id == DBUS_CONFIG_ID_RXCTL_DEFERRES) {
2227 		usbos_info->rxctl_deferrespok = config->rxctl_deferrespok;
2228 		err = DBUS_OK;
2229 	} else if (config->config_id == DBUS_CONFIG_ID_AGGR_LIMIT) {
2230 		/* DBUS_CONFIG_ID_AGGR_LIMIT shouldn't be called after probe stage */
2231 		ASSERT(disc_arg == NULL);
2232 		ASSERT(config->aggr_param.maxrxsf > 0);
2233 		ASSERT(config->aggr_param.maxrxsize > 0);
2234 		if (config->aggr_param.maxrxsize > usbos_info->rxbuf_len) {
2235 			int state = usbos_info->pub->busstate;
2236 			dbus_usbos_unlink(&usbos_info->req_rxpostedq, &usbos_info->rxposted_lock);
2237 			while (atomic_read(&usbos_info->rxposted)) {
2238 				DBUSTRACE(("%s rxposted is %d, delay 1 ms\n", __FUNCTION__,
2239 					atomic_read(&usbos_info->rxposted)));
2240 				dbus_usbos_wait(usbos_info, 1);
2241 			}
2242 			usbos_info->rxbuf_len = config->aggr_param.maxrxsize;
2243 			dbus_usbos_state_change(usbos_info, state);
2244 		}
2245 		err = DBUS_OK;
2246 	}
2247 
2248 	return err;
2249 }
2250 
2251 
2252 /** Called by dbus_usb.c when it wants to download firmware into the dongle */
2253 bool
dbus_usbos_dl_cmd(usbos_info_t * usbinfo,uint8 cmd,void * buffer,int buflen)2254 dbus_usbos_dl_cmd(usbos_info_t *usbinfo, uint8 cmd, void *buffer, int buflen)
2255 {
2256 	int transferred;
2257 	int index = 0;
2258 	char *tmpbuf;
2259 
2260 	if ((usbinfo == NULL) || (buffer == NULL) || (buflen == 0))
2261 		return FALSE;
2262 
2263 	tmpbuf = (char *) MALLOC(usbinfo->pub->osh, buflen);
2264 	if (!tmpbuf) {
2265 		DBUSERR(("%s: Unable to allocate memory \n", __FUNCTION__));
2266 		return FALSE;
2267 	}
2268 
2269 #ifdef BCM_REQUEST_FW
2270 	if (cmd == DL_GO) {
2271 		index = 1;
2272 	}
2273 #endif
2274 
2275 	/* Disable USB autosuspend until this request completes, request USB resume if needed. */
2276 	USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
2277 
2278 	transferred = USB_CONTROL_MSG(usbinfo->usb, usb_rcvctrlpipe(usbinfo->usb, 0),
2279 		cmd, (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE),
2280 		0, index,
2281 		(void*) tmpbuf, buflen, USB_CTRL_EP_TIMEOUT);
2282 	if (transferred == buflen) {
2283 		memcpy(buffer, tmpbuf, buflen);
2284 	} else {
2285 		DBUSERR(("%s: usb_control_msg failed %d\n", __FUNCTION__, transferred));
2286 	}
2287 
2288 	USB_AUTOPM_PUT_INTERFACE(g_probe_info.intf);
2289 
2290 	MFREE(usbinfo->pub->osh, tmpbuf, buflen);
2291 	return (transferred == buflen);
2292 }
2293 
2294 /**
2295  * Called by dbus_usb.c when it wants to download a buffer into the dongle (e.g. as part of the
2296  * download process, when writing nvram variables).
2297  */
2298 int
dbus_write_membytes(usbos_info_t * usbinfo,bool set,uint32 address,uint8 * data,uint size)2299 dbus_write_membytes(usbos_info_t* usbinfo, bool set, uint32 address, uint8 *data, uint size)
2300 {
2301 	hwacc_t hwacc;
2302 	int write_bytes = 4;
2303 	int status;
2304 	int retval = 0;
2305 
2306 	DBUSTRACE(("Enter:%s\n", __FUNCTION__));
2307 
2308 	/* Read is not supported */
2309 	if (set == 0) {
2310 		DBUSERR(("Currently read is not supported!!\n"));
2311 		return -1;
2312 	}
2313 
2314 	USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
2315 
2316 	hwacc.cmd = DL_CMD_WRHW;
2317 	hwacc.addr = address;
2318 
2319 	DBUSTRACE(("Address:%x size:%d", hwacc.addr, size));
2320 	do {
2321 		if (size >= 4) {
2322 			write_bytes = 4;
2323 		} else if (size >= 2) {
2324 			write_bytes = 2;
2325 		} else {
2326 			write_bytes = 1;
2327 		}
2328 
2329 		hwacc.len = write_bytes;
2330 
2331 		while (size >= write_bytes) {
2332 			hwacc.data = *((unsigned int*)data);
2333 
2334 			status = USB_CONTROL_MSG(usbinfo->usb, usb_sndctrlpipe(usbinfo->usb, 0),
2335 				DL_WRHW, (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE),
2336 				1, 0, (char *)&hwacc, sizeof(hwacc_t), USB_CTRL_EP_TIMEOUT);
2337 
2338 			if (status < 0) {
2339 				retval = -1;
2340 				DBUSERR((" Ctrl write hwacc failed w/status %d @ address:%x \n",
2341 					status, hwacc.addr));
2342 				goto err;
2343 			}
2344 
2345 			hwacc.addr += write_bytes;
2346 			data += write_bytes;
2347 			size -= write_bytes;
2348 		}
2349 	} while (size > 0);
2350 
2351 err:
2352 	USB_AUTOPM_PUT_INTERFACE(g_probe_info.intf);
2353 
2354 	return retval;
2355 }
2356 
2357 int
dbus_usbos_readreg(void * bus,uint32 regaddr,int datalen,uint32 * value)2358 dbus_usbos_readreg(void *bus, uint32 regaddr, int datalen, uint32 *value)
2359 {
2360 	usbos_info_t *usbinfo = (usbos_info_t *) bus;
2361 	int ret = DBUS_OK;
2362 	int transferred;
2363 	uint32 cmd;
2364 	hwacc_t	hwacc;
2365 
2366 	if (usbinfo == NULL)
2367 		return DBUS_ERR;
2368 
2369 	if (datalen == 1)
2370 		cmd = DL_RDHW8;
2371 	else if (datalen == 2)
2372 		cmd = DL_RDHW16;
2373 	else
2374 		cmd = DL_RDHW32;
2375 
2376 	USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
2377 
2378 	transferred = USB_CONTROL_MSG(usbinfo->usb, usb_rcvctrlpipe(usbinfo->usb, 0),
2379 		cmd, (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE),
2380 		(uint16)(regaddr), (uint16)(regaddr >> 16),
2381 		(void *) &hwacc, sizeof(hwacc_t), USB_CTRL_EP_TIMEOUT);
2382 
2383 	if (transferred >= sizeof(hwacc_t)) {
2384 		*value = hwacc.data;
2385 	} else {
2386 		DBUSERR(("%s: usb_control_msg failed %d\n", __FUNCTION__, transferred));
2387 		ret = DBUS_ERR;
2388 	}
2389 
2390 	USB_AUTOPM_PUT_INTERFACE(g_probe_info.intf);
2391 
2392 	return ret;
2393 }
2394 
2395 int
dbus_usbos_writereg(void * bus,uint32 regaddr,int datalen,uint32 data)2396 dbus_usbos_writereg(void *bus, uint32 regaddr, int datalen, uint32 data)
2397 {
2398 	usbos_info_t *usbinfo = (usbos_info_t *) bus;
2399 	int ret = DBUS_OK;
2400 	int transferred;
2401 	uint32 cmd = DL_WRHW;
2402 	hwacc_t	hwacc;
2403 
2404 	if (usbinfo == NULL)
2405 		return DBUS_ERR;
2406 
2407 	USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
2408 
2409 	hwacc.cmd = DL_WRHW;
2410 	hwacc.addr = regaddr;
2411 	hwacc.data = data;
2412 	hwacc.len = datalen;
2413 
2414 	transferred = USB_CONTROL_MSG(usbinfo->usb, usb_sndctrlpipe(usbinfo->usb, 0),
2415 		cmd, (USB_DIR_OUT| USB_TYPE_VENDOR | USB_RECIP_INTERFACE),
2416 		1, 0,
2417 		(void *) &hwacc, sizeof(hwacc_t), USB_CTRL_EP_TIMEOUT);
2418 
2419 	if (transferred != sizeof(hwacc_t)) {
2420 		DBUSERR(("%s: usb_control_msg failed %d\n", __FUNCTION__, transferred));
2421 		ret = DBUS_ERR;
2422 	}
2423 
2424 	USB_AUTOPM_PUT_INTERFACE(g_probe_info.intf);
2425 
2426 	return ret;
2427 }
2428 
2429 int
dbus_usbos_wait(usbos_info_t * usbinfo,uint16 ms)2430 dbus_usbos_wait(usbos_info_t *usbinfo, uint16 ms)
2431 {
2432 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
2433 	if (in_interrupt())
2434 		mdelay(ms);
2435 	else
2436 		msleep_interruptible(ms);
2437 #else
2438 	wait_ms(ms);
2439 #endif
2440 	return DBUS_OK;
2441 }
2442 
2443 /** Called by dbus_usb.c as part of the firmware download process */
2444 bool
dbus_usbos_dl_send_bulk(usbos_info_t * usbinfo,void * buffer,int len)2445 dbus_usbos_dl_send_bulk(usbos_info_t *usbinfo, void *buffer, int len)
2446 {
2447 	bool ret = TRUE;
2448 	int status;
2449 	int transferred = 0;
2450 
2451 	if (usbinfo == NULL)
2452 		return DBUS_ERR;
2453 
2454 	USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
2455 
2456 	status = USB_BULK_MSG(usbinfo->usb, usbinfo->tx_pipe,
2457 		buffer, len,
2458 		&transferred, USB_BULK_EP_TIMEOUT);
2459 
2460 	if (status < 0) {
2461 		DBUSERR(("%s: usb_bulk_msg failed %d\n", __FUNCTION__, status));
2462 		ret = FALSE;
2463 	}
2464 
2465 	USB_AUTOPM_PUT_INTERFACE(g_probe_info.intf);
2466 
2467 	return ret;
2468 }
2469 
2470 static bool
dbus_usbos_intf_recv_needed(void * bus)2471 dbus_usbos_intf_recv_needed(void *bus)
2472 {
2473 	return FALSE;
2474 }
2475 
2476 /**
2477  * Higher layer (dbus_usb.c) wants to execute a function on the condition that the rx spin lock has
2478  * been acquired.
2479  */
2480 static void*
dbus_usbos_intf_exec_rxlock(void * bus,exec_cb_t cb,struct exec_parms * args)2481 dbus_usbos_intf_exec_rxlock(void *bus, exec_cb_t cb, struct exec_parms *args)
2482 {
2483 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
2484 	void *ret;
2485 	unsigned long flags;
2486 
2487 	if (usbos_info == NULL)
2488 		return NULL;
2489 
2490 	spin_lock_irqsave(&usbos_info->rxlock, flags);
2491 	ret = cb(args);
2492 	spin_unlock_irqrestore(&usbos_info->rxlock, flags);
2493 
2494 	return ret;
2495 }
2496 
2497 static void*
dbus_usbos_intf_exec_txlock(void * bus,exec_cb_t cb,struct exec_parms * args)2498 dbus_usbos_intf_exec_txlock(void *bus, exec_cb_t cb, struct exec_parms *args)
2499 {
2500 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
2501 	void *ret;
2502 	unsigned long flags;
2503 
2504 	if (usbos_info == NULL)
2505 		return NULL;
2506 
2507 	spin_lock_irqsave(&usbos_info->txlock, flags);
2508 	ret = cb(args);
2509 	spin_unlock_irqrestore(&usbos_info->txlock, flags);
2510 
2511 	return ret;
2512 }
2513 
2514 /**
2515  * if an error condition was detected in this module, the higher DBUS layer (dbus_usb.c) has to
2516  * be notified.
2517  */
2518 int
dbus_usbos_errhandler(void * bus,int err)2519 dbus_usbos_errhandler(void *bus, int err)
2520 {
2521 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
2522 
2523 	if (usbos_info == NULL)
2524 		return DBUS_ERR;
2525 
2526 	if (usbos_info->cbarg && usbos_info->cbs) {
2527 		if (usbos_info->cbs->errhandler)
2528 			usbos_info->cbs->errhandler(usbos_info->cbarg, err);
2529 	}
2530 
2531 	return DBUS_OK;
2532 }
2533 
2534 /**
2535  * if a change in bus state was detected in this module, the higher DBUS layer (dbus_usb.c) has to
2536  * be notified.
2537  */
2538 int
dbus_usbos_state_change(void * bus,int state)2539 dbus_usbos_state_change(void *bus, int state)
2540 {
2541 	usbos_info_t *usbos_info = (usbos_info_t *) bus;
2542 
2543 	if (usbos_info == NULL)
2544 		return DBUS_ERR;
2545 
2546 	if (usbos_info->cbarg && usbos_info->cbs) {
2547 		if (usbos_info->cbs->state_change)
2548 			usbos_info->cbs->state_change(usbos_info->cbarg, state);
2549 	}
2550 
2551 	usbos_info->pub->busstate = state;
2552 	return DBUS_OK;
2553 }
2554 
2555 int
dbus_bus_osl_register(int vid,int pid,probe_cb_t prcb,disconnect_cb_t discb,void * prarg,dbus_intf_t ** intf,void * param1,void * param2)2556 dbus_bus_osl_register(int vid, int pid, probe_cb_t prcb,
2557 	disconnect_cb_t discb, void *prarg, dbus_intf_t **intf, void *param1, void *param2)
2558 {
2559 	bzero(&g_probe_info, sizeof(probe_info_t));
2560 
2561 	probe_cb = prcb;
2562 	disconnect_cb = discb;
2563 	probe_arg = prarg;
2564 
2565 	devid_table[0].idVendor = vid;
2566 	devid_table[0].idProduct = pid;
2567 
2568 	*intf = &dbus_usbos_intf;
2569 
2570 	USB_REGISTER();
2571 
2572 	return DBUS_ERR_NODEVICE;
2573 }
2574 
2575 int
dbus_bus_osl_deregister()2576 dbus_bus_osl_deregister()
2577 {
2578 	g_probe_info.dereged = TRUE;
2579 
2580 	DHD_MUTEX_LOCK();
2581 	if (disconnect_cb && disc_arg && (g_probe_info.disc_cb_done == FALSE)) {
2582 		disconnect_cb(disc_arg);
2583 		disc_arg = NULL;
2584 	}
2585 	DHD_MUTEX_UNLOCK();
2586 
2587 	USB_DEREGISTER();
2588 
2589 	return DBUS_OK;
2590 }
2591 
2592 void *
dbus_usbos_intf_attach(dbus_pub_t * pub,void * cbarg,dbus_intf_callbacks_t * cbs)2593 dbus_usbos_intf_attach(dbus_pub_t *pub, void *cbarg, dbus_intf_callbacks_t *cbs)
2594 {
2595 	usbos_info_t *usbos_info;
2596 
2597 	if (g_probe_info.dldone == FALSE) {
2598 		DBUSERR(("%s: err device not downloaded!\n", __FUNCTION__));
2599 		return NULL;
2600 	}
2601 
2602 	/* Sanity check for BUS_INFO() */
2603 	ASSERT(OFFSETOF(usbos_info_t, pub) == 0);
2604 
2605 	usbos_info = MALLOC(pub->osh, sizeof(usbos_info_t));
2606 	if (usbos_info == NULL)
2607 		return NULL;
2608 
2609 	bzero(usbos_info, sizeof(usbos_info_t));
2610 
2611 	usbos_info->pub = pub;
2612 	usbos_info->cbarg = cbarg;
2613 	usbos_info->cbs = cbs;
2614 
2615 	/* Needed for disconnect() */
2616 	g_probe_info.usbos_info = usbos_info;
2617 
2618 	/* Update USB Info */
2619 	usbos_info->usb = g_probe_info.usb;
2620 	usbos_info->rx_pipe = g_probe_info.rx_pipe;
2621 	usbos_info->rx_pipe2 = g_probe_info.rx_pipe2;
2622 	usbos_info->tx_pipe = g_probe_info.tx_pipe;
2623 	usbos_info->intr_pipe = g_probe_info.intr_pipe;
2624 	usbos_info->intr_size = g_probe_info.intr_size;
2625 	usbos_info->interval = g_probe_info.interval;
2626 	usbos_info->pub->device_speed = g_probe_info.device_speed;
2627 	if (usbos_info->rx_pipe2) {
2628 		usbos_info->pub->attrib.has_2nd_bulk_in_ep = 1;
2629 	} else {
2630 		usbos_info->pub->attrib.has_2nd_bulk_in_ep = 0;
2631 	}
2632 
2633 	if (usbos_info->tx_pipe)
2634 		usbos_info->maxps = usb_maxpacket(usbos_info->usb,
2635 			usbos_info->tx_pipe, usb_pipeout(usbos_info->tx_pipe));
2636 
2637 	INIT_LIST_HEAD(&usbos_info->req_rxfreeq);
2638 	INIT_LIST_HEAD(&usbos_info->req_txfreeq);
2639 	INIT_LIST_HEAD(&usbos_info->req_rxpostedq);
2640 	INIT_LIST_HEAD(&usbos_info->req_txpostedq);
2641 	spin_lock_init(&usbos_info->rxfree_lock);
2642 	spin_lock_init(&usbos_info->txfree_lock);
2643 	spin_lock_init(&usbos_info->rxposted_lock);
2644 	spin_lock_init(&usbos_info->txposted_lock);
2645 	spin_lock_init(&usbos_info->rxlock);
2646 	spin_lock_init(&usbos_info->txlock);
2647 
2648 	atomic_set(&usbos_info->rxposted, 0);
2649 	atomic_set(&usbos_info->txposted, 0);
2650 
2651 
2652 #ifdef USB_DISABLE_INT_EP
2653 	usbos_info->intr_urb = NULL;
2654 #else
2655 	if (!(usbos_info->intr_urb = USB_ALLOC_URB())) {
2656 		DBUSERR(("%s: usb_alloc_urb (tx) failed\n", __FUNCTION__));
2657 		goto fail;
2658 	}
2659 #endif
2660 
2661 	if (!(usbos_info->ctl_urb = USB_ALLOC_URB())) {
2662 		DBUSERR(("%s: usb_alloc_urb (tx) failed\n", __FUNCTION__));
2663 		goto fail;
2664 	}
2665 
2666 	init_waitqueue_head(&usbos_info->wait);
2667 
2668 	if (!(usbos_info->blk_urb = USB_ALLOC_URB())) {	/* for embedded image downloading */
2669 		DBUSERR(("%s: usb_alloc_urb (tx) failed\n", __FUNCTION__));
2670 		goto fail;
2671 	}
2672 
2673 	usbos_info->rxbuf_len = (uint)usbos_info->pub->rxsize;
2674 
2675 
2676 
2677 	atomic_set(&usbos_info->txallocated, 0);
2678 	if (DBUS_OK != dbus_usbos_urbreqs_alloc(usbos_info,
2679 		usbos_info->pub->ntxq, FALSE)) {
2680 		goto fail;
2681 	}
2682 
2683 	atomic_set(&usbos_info->rxallocated, 0);
2684 	if (DBUS_OK != dbus_usbos_urbreqs_alloc(usbos_info,
2685 		MIN(DBUS_USB_RXQUEUE_BATCH_ADD, usbos_info->pub->nrxq),
2686 		TRUE)) {
2687 		goto fail;
2688 	}
2689 
2690 	sema_init(&usbos_info->ctl_lock, 1);
2691 
2692 #ifdef USBOS_THREAD
2693 	if (dbus_usbos_thread_init(usbos_info) == NULL)
2694 		goto fail;
2695 #endif /* USBOS_THREAD */
2696 
2697 #ifdef USBOS_TX_THREAD
2698 	if (dbus_usbos_tx_thread_init(usbos_info) == NULL)
2699 		goto fail;
2700 #endif /* USBOS_TX_THREAD */
2701 
2702 	pub->dev_info = g_probe_info.usb;
2703 
2704 
2705 	return (void *) usbos_info;
2706 fail:
2707 	if (usbos_info->intr_urb) {
2708 		USB_FREE_URB(usbos_info->intr_urb);
2709 		usbos_info->intr_urb = NULL;
2710 	}
2711 
2712 	if (usbos_info->ctl_urb) {
2713 		USB_FREE_URB(usbos_info->ctl_urb);
2714 		usbos_info->ctl_urb = NULL;
2715 	}
2716 
2717 #if defined(BCM_REQUEST_FW)
2718 	if (usbos_info->blk_urb) {
2719 		USB_FREE_URB(usbos_info->blk_urb);
2720 		usbos_info->blk_urb = NULL;
2721 	}
2722 #endif
2723 
2724 	dbus_usbos_urbreqs_free(usbos_info, TRUE);
2725 	atomic_set(&usbos_info->rxallocated, 0);
2726 	dbus_usbos_urbreqs_free(usbos_info, FALSE);
2727 	atomic_set(&usbos_info->txallocated, 0);
2728 
2729 	g_probe_info.usbos_info = NULL;
2730 
2731 	MFREE(pub->osh, usbos_info, sizeof(usbos_info_t));
2732 	return NULL;
2733 } /* dbus_usbos_intf_attach */
2734 
2735 void
dbus_usbos_intf_detach(dbus_pub_t * pub,void * info)2736 dbus_usbos_intf_detach(dbus_pub_t *pub, void *info)
2737 {
2738 	usbos_info_t *usbos_info = (usbos_info_t *) info;
2739 	osl_t *osh = pub->osh;
2740 
2741 	if (usbos_info == NULL) {
2742 		return;
2743 	}
2744 
2745 #ifdef USBOS_TX_THREAD
2746 	dbus_usbos_tx_thread_deinit(usbos_info);
2747 #endif /* USBOS_TX_THREAD */
2748 
2749 	/* Must unlink all URBs prior to driver unload;
2750 	 * otherwise an URB callback can occur after driver
2751 	 * has been de-allocated and rmmod'd
2752 	 */
2753 	dbusos_stop(usbos_info);
2754 
2755 	if (usbos_info->intr_urb) {
2756 		USB_FREE_URB(usbos_info->intr_urb);
2757 		usbos_info->intr_urb = NULL;
2758 	}
2759 
2760 	if (usbos_info->ctl_urb) {
2761 		USB_FREE_URB(usbos_info->ctl_urb);
2762 		usbos_info->ctl_urb = NULL;
2763 	}
2764 
2765 	if (usbos_info->blk_urb) {
2766 		USB_FREE_URB(usbos_info->blk_urb);
2767 		usbos_info->blk_urb = NULL;
2768 	}
2769 
2770 	dbus_usbos_urbreqs_free(usbos_info, TRUE);
2771 	atomic_set(&usbos_info->rxallocated, 0);
2772 	dbus_usbos_urbreqs_free(usbos_info, FALSE);
2773 	atomic_set(&usbos_info->txallocated, 0);
2774 
2775 #ifdef USBOS_THREAD
2776 	dbus_usbos_thread_deinit(usbos_info);
2777 #endif /* USBOS_THREAD */
2778 
2779 	g_probe_info.usbos_info = NULL;
2780 	MFREE(osh, usbos_info, sizeof(usbos_info_t));
2781 } /* dbus_usbos_intf_detach */
2782 
2783 
2784 #ifdef USBOS_TX_THREAD
2785 
2786 void*
dbus_usbos_tx_thread_init(usbos_info_t * usbos_info)2787 dbus_usbos_tx_thread_init(usbos_info_t *usbos_info)
2788 {
2789 	spin_lock_init(&usbos_info->usbos_tx_list_lock);
2790 	INIT_LIST_HEAD(&usbos_info->usbos_tx_list);
2791 	init_waitqueue_head(&usbos_info->usbos_tx_queue_head);
2792 
2793 	usbos_info->usbos_tx_kt = kthread_create(dbus_usbos_tx_thread_func,
2794 		usbos_info, "usb-tx-thread");
2795 
2796 	if (IS_ERR(usbos_info->usbos_tx_kt)) {
2797 		DBUSERR(("Thread Creation failed\n"));
2798 		return (NULL);
2799 	}
2800 
2801 	usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
2802 	wake_up_process(usbos_info->usbos_tx_kt);
2803 
2804 	return (usbos_info->usbos_tx_kt);
2805 }
2806 
2807 void
dbus_usbos_tx_thread_deinit(usbos_info_t * usbos_info)2808 dbus_usbos_tx_thread_deinit(usbos_info_t *usbos_info)
2809 {
2810 	urb_req_t *req;
2811 
2812 	if (usbos_info->usbos_tx_kt) {
2813 		wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
2814 		kthread_stop(usbos_info->usbos_tx_kt);
2815 	}
2816 
2817 	/* Move pending requests to free queue so they can be freed */
2818 	while ((req = dbus_usbos_qdeq(
2819 		&usbos_info->usbos_tx_list, &usbos_info->usbos_tx_list_lock)) != NULL) {
2820 		dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
2821 	}
2822 }
2823 
2824 /**
2825  * Allow USB in-band resume to block by submitting CTRL and DATA URBs on a separate thread.
2826  */
2827 int
dbus_usbos_tx_thread_func(void * data)2828 dbus_usbos_tx_thread_func(void *data)
2829 {
2830 	usbos_info_t  *usbos_info = (usbos_info_t *)data;
2831 	urb_req_t     *req;
2832 	dbus_irb_tx_t *txirb;
2833 	int           ret;
2834 	unsigned long flags;
2835 
2836 #ifdef WL_THREADNICE
2837 	set_user_nice(current, WL_THREADNICE);
2838 #endif
2839 
2840 	while (1) {
2841 		/* Wait until there are URBs to submit */
2842 		wait_event_interruptible_timeout(
2843 			usbos_info->usbos_tx_queue_head,
2844 			!list_empty(&usbos_info->usbos_tx_list) ||
2845 			usbos_info->ctl_state == USBOS_REQUEST_STATE_SCHEDULED,
2846 			100);
2847 
2848 		if (kthread_should_stop())
2849 			break;
2850 
2851 		/* Submit CTRL URB if needed */
2852 		if (usbos_info->ctl_state == USBOS_REQUEST_STATE_SCHEDULED) {
2853 
2854 			/* Disable USB autosuspend until this request completes. If the
2855 			 * interface was suspended, this call blocks until it has been resumed.
2856 			 */
2857 			USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
2858 
2859 			usbos_info->ctl_state = USBOS_REQUEST_STATE_SUBMITTED;
2860 
2861 			ret = USB_SUBMIT_URB(usbos_info->ctl_urb);
2862 			if (ret != 0) {
2863 				DBUSERR(("%s CTRL USB_SUBMIT_URB failed, status %d\n",
2864 					__FUNCTION__, ret));
2865 
2866 				usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
2867 				up(&usbos_info->ctl_lock);
2868 
2869 				USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
2870 			}
2871 		}
2872 
2873 		/* Submit all available TX URBs */
2874 		while ((req = dbus_usbos_qdeq(&usbos_info->usbos_tx_list,
2875 			&usbos_info->usbos_tx_list_lock)) != NULL) {
2876 
2877 			/* Disable USB autosuspend until this request completes. If the
2878 			 * interface was suspended, this call blocks until it has been resumed.
2879 			 */
2880 			USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
2881 
2882 			spin_lock_irqsave(&usbos_info->txlock, flags);
2883 
2884 			ret = USB_SUBMIT_URB(req->urb);
2885 			if (ret == 0) {
2886 				/* URB submitted successfully */
2887 				dbus_usbos_qenq(&usbos_info->req_txpostedq, req,
2888 					&usbos_info->txposted_lock);
2889 				atomic_inc(&usbos_info->txposted);
2890 			} else {
2891 				/* Submitting the URB failed. */
2892 				DBUSERR(("%s TX USB_SUBMIT_URB failed, status %d\n",
2893 					__FUNCTION__, ret));
2894 
2895 				USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
2896 			}
2897 
2898 			spin_unlock_irqrestore(&usbos_info->txlock, flags);
2899 
2900 			if (ret != 0) {
2901 				/* Cleanup and notify higher layers */
2902 				dbus_usbos_qenq(&usbos_info->req_txfreeq, req,
2903 					&usbos_info->txfree_lock);
2904 
2905 				txirb = req->arg;
2906 				if (txirb->send_buf) {
2907 					MFREE(usbos_info->pub->osh, txirb->send_buf, req->buf_len);
2908 					txirb->send_buf = NULL;
2909 					req->buf_len = 0;
2910 				}
2911 
2912 				if (likely (usbos_info->cbarg && usbos_info->cbs)) {
2913 					if (likely (usbos_info->cbs->send_irb_complete != NULL))
2914 						usbos_info->cbs->send_irb_complete(
2915 							usbos_info->cbarg, txirb, DBUS_ERR_TXDROP);
2916 				}
2917 			}
2918 		}
2919 	}
2920 
2921 	return 0;
2922 } /* dbus_usbos_tx_thread_func */
2923 
2924 #endif /* USBOS_TX_THREAD */
2925 
2926 #ifdef USBOS_THREAD
2927 
2928 /**
2929  * Increase system performance by creating a USB thread that runs parallel to other system
2930  * activity.
2931  */
2932 static void*
dbus_usbos_thread_init(usbos_info_t * usbos_info)2933 dbus_usbos_thread_init(usbos_info_t *usbos_info)
2934 {
2935 	usbos_list_entry_t  *entry;
2936 	unsigned long       flags, ii;
2937 
2938 	spin_lock_init(&usbos_info->usbos_list_lock);
2939 	spin_lock_init(&usbos_info->ctrl_lock);
2940 	INIT_LIST_HEAD(&usbos_info->usbos_list);
2941 	INIT_LIST_HEAD(&usbos_info->usbos_free_list);
2942 	init_waitqueue_head(&usbos_info->usbos_queue_head);
2943 	atomic_set(&usbos_info->usbos_list_cnt, 0);
2944 
2945 
2946 	for (ii = 0; ii < (usbos_info->pub->nrxq + usbos_info->pub->ntxq); ii++) {
2947 		entry = MALLOC(usbos_info->pub->osh, sizeof(usbos_list_entry_t));
2948 		if (entry) {
2949 			spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
2950 			list_add_tail((struct list_head*) entry, &usbos_info->usbos_free_list);
2951 			spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
2952 		} else {
2953 			DBUSERR(("Failed to create list\n"));
2954 		}
2955 	}
2956 
2957 	usbos_info->usbos_kt = kthread_create(dbus_usbos_thread_func,
2958 		usbos_info, "usb-thread");
2959 
2960 	if (IS_ERR(usbos_info->usbos_kt)) {
2961 		DBUSERR(("Thread Creation failed\n"));
2962 		return (NULL);
2963 	}
2964 
2965 	wake_up_process(usbos_info->usbos_kt);
2966 
2967 	return (usbos_info->usbos_kt);
2968 }
2969 
2970 static void
dbus_usbos_thread_deinit(usbos_info_t * usbos_info)2971 dbus_usbos_thread_deinit(usbos_info_t *usbos_info)
2972 {
2973 	struct list_head    *cur, *next;
2974 	usbos_list_entry_t  *entry;
2975 	unsigned long       flags;
2976 
2977 	if (usbos_info->usbos_kt) {
2978 		wake_up_interruptible(&usbos_info->usbos_queue_head);
2979 		kthread_stop(usbos_info->usbos_kt);
2980 	}
2981 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
2982 #pragma GCC diagnostic push
2983 #pragma GCC diagnostic ignored "-Wcast-qual"
2984 #endif
2985 	list_for_each_safe(cur, next, &usbos_info->usbos_list)
2986 	{
2987 		entry = list_entry(cur, struct usbos_list_entry, list);
2988 		/* detach this entry from the list and then free the entry */
2989 		spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
2990 		list_del(cur);
2991 		MFREE(usbos_info->pub->osh, entry, sizeof(usbos_list_entry_t));
2992 		spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
2993 	}
2994 
2995 	list_for_each_safe(cur, next, &usbos_info->usbos_free_list)
2996 	{
2997 		entry = list_entry(cur, struct usbos_list_entry, list);
2998 		/* detach this entry from the list and then free the entry */
2999 		spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
3000 		list_del(cur);
3001 		MFREE(usbos_info->pub->osh, entry, sizeof(usbos_list_entry_t));
3002 		spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
3003 	}
3004 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
3005 #pragma GCC diagnostic pop
3006 #endif
3007 }
3008 
3009 /** Process completed URBs in a worker thread */
3010 static int
dbus_usbos_thread_func(void * data)3011 dbus_usbos_thread_func(void *data)
3012 {
3013 	usbos_info_t        *usbos_info = (usbos_info_t *)data;
3014 	usbos_list_entry_t  *entry;
3015 	struct list_head    *cur, *next;
3016 	unsigned long       flags;
3017 
3018 #ifdef WL_THREADNICE
3019 	set_user_nice(current, WL_THREADNICE);
3020 #endif
3021 
3022 	while (1) {
3023 		/* If the list is empty, then go to sleep */
3024 		wait_event_interruptible_timeout
3025 		(usbos_info->usbos_queue_head,
3026 			atomic_read(&usbos_info->usbos_list_cnt) > 0,
3027 			100);
3028 
3029 		if (kthread_should_stop())
3030 			break;
3031 
3032 		spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
3033 
3034 		/* For each entry on the list, process it.  Remove the entry from
3035 		* the list when done.
3036 		*/
3037 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
3038 #pragma GCC diagnostic push
3039 #pragma GCC diagnostic ignored "-Wcast-qual"
3040 #endif
3041 		list_for_each_safe(cur, next, &usbos_info->usbos_list)
3042 		{
3043 			urb_req_t           *req;
3044 			int                 len;
3045 			int                 stat;
3046 			usbos_info_t        *usbos_info_local;
3047 
3048 			entry = list_entry(cur, struct usbos_list_entry, list);
3049 			if (entry == NULL)
3050 				break;
3051 
3052 			req = entry->urb_context;
3053 			len = entry->urb_length;
3054 			stat = entry->urb_status;
3055 			usbos_info_local = req->usbinfo;
3056 
3057 			/* detach this entry from the list and attach it to the free list */
3058 			list_del_init(cur);
3059 			spin_unlock_irqrestore(&usbos_info_local->usbos_list_lock, flags);
3060 
3061 			dbus_usbos_recv_complete_handle(req, len, stat);
3062 
3063 			spin_lock_irqsave(&usbos_info_local->usbos_list_lock, flags);
3064 
3065 			list_add_tail(cur, &usbos_info_local->usbos_free_list);
3066 
3067 			atomic_dec(&usbos_info_local->usbos_list_cnt);
3068 		}
3069 
3070 		spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
3071 
3072 	}
3073 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
3074 #pragma GCC diagnostic pop
3075 #endif
3076 
3077 	return 0;
3078 } /* dbus_usbos_thread_func */
3079 
3080 /** Called on Linux calling URB callback, see dbus_usbos_recv_complete() */
3081 static void
dbus_usbos_dispatch_schedule(CALLBACK_ARGS)3082 dbus_usbos_dispatch_schedule(CALLBACK_ARGS)
3083 {
3084 	urb_req_t           *req = urb->context;
3085 	usbos_info_t        *usbos_info = req->usbinfo;
3086 	usbos_list_entry_t  *entry;
3087 	unsigned long       flags;
3088 	struct list_head    *cur;
3089 
3090 	spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
3091 
3092 	cur   = usbos_info->usbos_free_list.next;
3093 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
3094 #pragma GCC diagnostic push
3095 #pragma GCC diagnostic ignored "-Wcast-qual"
3096 #endif
3097 	entry = list_entry(cur, struct usbos_list_entry, list);
3098 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
3099 #pragma GCC diagnostic pop
3100 #endif
3101 
3102 	/* detach this entry from the free list and prepare it insert it to use list */
3103 	list_del_init(cur);
3104 
3105 	if (entry) {
3106 		entry->urb_context = urb->context;
3107 		entry->urb_length  = urb->actual_length;
3108 		entry->urb_status  = urb->status;
3109 
3110 		atomic_inc(&usbos_info->usbos_list_cnt);
3111 		list_add_tail(cur, &usbos_info->usbos_list);
3112 	} else {
3113 		DBUSERR(("!!!!!!OUT OF MEMORY!!!!!!!\n"));
3114 	}
3115 
3116 	spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
3117 
3118 	/* thread */
3119 	wake_up_interruptible(&usbos_info->usbos_queue_head);
3120 } /* dbus_usbos_dispatch_schedule */
3121 
3122 #endif /* USBOS_THREAD */
3123 
3124 
3125 
3126 
3127 #ifdef BCM_REQUEST_FW
3128 
3129 struct request_fw_context {
3130 	const struct firmware *firmware;
3131 	struct semaphore lock;
3132 };
3133 
3134 /*
3135  * Callback for dbus_request_firmware().
3136  */
3137 static void
dbus_request_firmware_done(const struct firmware * firmware,void * ctx)3138 dbus_request_firmware_done(const struct firmware *firmware, void *ctx)
3139 {
3140 	struct request_fw_context *context = (struct request_fw_context*)ctx;
3141 
3142 	/* Store the received firmware handle in the context and wake requester */
3143 	context->firmware = firmware;
3144 	up(&context->lock);
3145 }
3146 
3147 /*
3148  * Send a firmware request and wait for completion.
3149  *
3150  * The use of the asynchronous version of request_firmware() is needed to avoid
3151  * kernel oopses when we just come out of system hibernate.
3152  */
3153 static int
dbus_request_firmware(const char * name,const struct firmware ** firmware)3154 dbus_request_firmware(const char *name, const struct firmware **firmware)
3155 {
3156 	struct request_fw_context *context;
3157 	int ret;
3158 
3159 	context = kzalloc(sizeof(*context), GFP_KERNEL);
3160 	if (!context)
3161 		return -ENOMEM;
3162 
3163 	sema_init(&context->lock, 0);
3164 
3165 	ret = request_firmware_nowait(THIS_MODULE, true, name, &g_probe_info.usb->dev,
3166 	                              GFP_KERNEL, context, dbus_request_firmware_done);
3167 	if (ret) {
3168 		kfree(context);
3169 		return ret;
3170 	}
3171 
3172 	/* Wait for completion */
3173 	if (down_interruptible(&context->lock) != 0) {
3174 		kfree(context);
3175 		return -ERESTARTSYS;
3176 	}
3177 
3178 	*firmware = context->firmware;
3179 	kfree(context);
3180 
3181 	return *firmware != NULL ? 0 : -ENOENT;
3182 }
3183 
3184 static void *
dbus_get_fwfile(int devid,int chiprev,uint8 ** fw,int * fwlen,uint16 boardtype,uint16 boardrev)3185 dbus_get_fwfile(int devid, int chiprev, uint8 **fw, int *fwlen, uint16 boardtype, uint16 boardrev)
3186 {
3187 	const struct firmware *firmware = NULL;
3188 #ifndef OEM_ANDROID
3189 	s8 *device_id = NULL;
3190 	s8 *chip_rev = "";
3191 #endif /* OEM_ANDROID */
3192 	s8 file_name[64];
3193 	int ret;
3194 
3195 #ifndef OEM_ANDROID
3196 	switch (devid) {
3197 		case BCM4350_CHIP_ID:
3198 		case BCM4354_CHIP_ID:
3199 		case BCM43556_CHIP_ID:
3200 		case BCM43558_CHIP_ID:
3201 		case BCM43566_CHIP_ID:
3202 		case BCM43568_CHIP_ID:
3203 		case BCM43570_CHIP_ID:
3204 		case BCM4358_CHIP_ID:
3205 			device_id = "4350";
3206 			break;
3207 		case BCM43143_CHIP_ID:
3208 			device_id = "43143";
3209 			break;
3210 		case BCM43234_CHIP_ID:
3211 		case BCM43235_CHIP_ID:
3212 		case BCM43236_CHIP_ID:
3213 			device_id = "43236";
3214 			break;
3215 		case BCM43242_CHIP_ID:
3216 			device_id = "43242";
3217 			break;
3218 		case BCM43238_CHIP_ID:
3219 			device_id = "43238";
3220 			break;
3221 		case BCM43526_CHIP_ID:
3222 			device_id = "43526";
3223 			break;
3224 		case BCM43569_CHIP_ID:
3225 			device_id = "43569";
3226 			switch (chiprev) {
3227 				case 0:
3228 					chip_rev = "a0";
3229 					break;
3230 				case 2:
3231 					chip_rev = "a2";
3232 					break;
3233 				default:
3234 					break;
3235 			}
3236 			break;
3237 		default:
3238 			DBUSERR(("unsupported device %x\n", devid));
3239 			return NULL;
3240 	}
3241 
3242 	/* Load firmware */
3243 	snprintf(file_name, sizeof(file_name), "brcm/bcm%s%s-firmware.bin", device_id, chip_rev);
3244 #else
3245 	snprintf(file_name, sizeof(file_name), "%s", CONFIG_ANDROID_BCMDHD_FW_PATH);
3246 #endif /* OEM_ANDROID */
3247 
3248 	ret = dbus_request_firmware(file_name, &firmware);
3249 	if (ret) {
3250 		DBUSERR(("fail to request firmware %s\n", file_name));
3251 		return NULL;
3252 	}
3253 
3254 	*fwlen = firmware->size;
3255 	*fw = (uint8 *)firmware->data;
3256 	return (void *)firmware;
3257 
3258 }
3259 
3260 static void *
dbus_get_nvfile(int devid,int chiprev,uint8 ** fw,int * fwlen,uint16 boardtype,uint16 boardrev)3261 dbus_get_nvfile(int devid, int chiprev, uint8 **fw, int *fwlen, uint16 boardtype, uint16 boardrev)
3262 {
3263 	const struct firmware *firmware = NULL;
3264 #ifndef OEM_ANDROID
3265 	s8 *device_id = NULL;
3266 	s8 *chip_rev = "";
3267 #endif /* OEM_ANDROID */
3268 	s8 file_name[64];
3269 	int ret;
3270 
3271 #ifndef OEM_ANDROID
3272 	switch (devid) {
3273 		case BCM4350_CHIP_ID:
3274 		case BCM4354_CHIP_ID:
3275 		case BCM43556_CHIP_ID:
3276 		case BCM43558_CHIP_ID:
3277 		case BCM43566_CHIP_ID:
3278 		case BCM43568_CHIP_ID:
3279 		case BCM43570_CHIP_ID:
3280 		case BCM4358_CHIP_ID:
3281 			device_id = "4350";
3282 			break;
3283 		case BCM43143_CHIP_ID:
3284 			device_id = "43143";
3285 			break;
3286 		case BCM43234_CHIP_ID:
3287 			device_id = "43234";
3288 			break;
3289 		case BCM43235_CHIP_ID:
3290 			device_id = "43235";
3291 			break;
3292 		case BCM43236_CHIP_ID:
3293 			device_id = "43236";
3294 			break;
3295 		case BCM43238_CHIP_ID:
3296 			device_id = "43238";
3297 			break;
3298 		case BCM43242_CHIP_ID:
3299 			device_id = "43242";
3300 			break;
3301 		case BCM43526_CHIP_ID:
3302 			device_id = "43526";
3303 			break;
3304 		case BCM43569_CHIP_ID:
3305 			device_id = "43569";
3306 			switch (chiprev) {
3307 				case 0:
3308 					chip_rev = "a0";
3309 					break;
3310 				case 2:
3311 					chip_rev = "a2";
3312 					break;
3313 				default:
3314 					break;
3315 			}
3316 			break;
3317 		default:
3318 			DBUSERR(("unsupported device %x\n", devid));
3319 			return NULL;
3320 	}
3321 
3322 	/* Load board specific nvram file */
3323 	snprintf(file_name, sizeof(file_name), "brcm/bcm%s%s-%2x-%2x.nvm",
3324 	         device_id, chip_rev, boardtype, boardrev);
3325 #else
3326 	snprintf(file_name, sizeof(file_name), "%s", CONFIG_ANDROID_BCMDHD_NVRAM_PATH);
3327 #endif /* OEM_ANDROID */
3328 
3329 	ret = dbus_request_firmware(file_name, &firmware);
3330 	if (ret) {
3331 		DBUSERR(("fail to request nvram %s\n", file_name));
3332 
3333 #ifndef OEM_ANDROID
3334 		/* Load generic nvram file */
3335 		snprintf(file_name, sizeof(file_name), "brcm/bcm%s%s.nvm",
3336 		         device_id, chip_rev);
3337 
3338 		ret = dbus_request_firmware(file_name, &firmware);
3339 #endif /* OEM_ANDROID */
3340 
3341 		if (ret) {
3342 			DBUSERR(("fail to request nvram %s\n", file_name));
3343 			return NULL;
3344 		}
3345 	}
3346 
3347 	*fwlen = firmware->size;
3348 	*fw = (uint8 *)firmware->data;
3349 	return (void *)firmware;
3350 }
3351 
3352 void *
dbus_get_fw_nvfile(int devid,int chiprev,uint8 ** fw,int * fwlen,int type,uint16 boardtype,uint16 boardrev)3353 dbus_get_fw_nvfile(int devid, int chiprev, uint8 **fw, int *fwlen, int type, uint16 boardtype,
3354 	uint16 boardrev)
3355 {
3356 	switch (type) {
3357 		case DBUS_FIRMWARE:
3358 			return dbus_get_fwfile(devid, chiprev, fw, fwlen, boardtype, boardrev);
3359 		case DBUS_NVFILE:
3360 			return dbus_get_nvfile(devid, chiprev, fw, fwlen, boardtype, boardrev);
3361 		default:
3362 			return NULL;
3363 	}
3364 }
3365 
3366 void
dbus_release_fw_nvfile(void * firmware)3367 dbus_release_fw_nvfile(void *firmware)
3368 {
3369 	release_firmware((struct firmware *)firmware);
3370 }
3371 #endif /* BCM_REQUEST_FW */
3372 
3373 #ifdef BCMUSBDEV_COMPOSITE
3374 /**
3375  * For a composite device the interface order is not guaranteed, scan the device struct for the WLAN
3376  * interface.
3377  */
3378 static int
dbus_usbos_intf_wlan(struct usb_device * usb)3379 dbus_usbos_intf_wlan(struct usb_device *usb)
3380 {
3381 	int i, num_of_eps, ep, intf_wlan = -1;
3382 	int num_intf = CONFIGDESC(usb)->bNumInterfaces;
3383 	struct usb_endpoint_descriptor *endpoint;
3384 
3385 	for (i = 0; i < num_intf; i++) {
3386 		if (IFDESC(usb, i).bInterfaceClass != USB_CLASS_VENDOR_SPEC)
3387 			continue;
3388 		num_of_eps = IFDESC(usb, i).bNumEndpoints;
3389 
3390 		for (ep = 0; ep < num_of_eps; ep++) {
3391 			endpoint = &IFEPDESC(usb, i, ep);
3392 			if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
3393 				USB_ENDPOINT_XFER_BULK) {
3394 				intf_wlan = i;
3395 				break;
3396 			}
3397 		}
3398 		if (ep < num_of_eps)
3399 			break;
3400 	}
3401 
3402 	return intf_wlan;
3403 }
3404 #endif /* BCMUSBDEV_COMPOSITE */
3405