2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/*
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * This file contains functions used in USB interface module.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <linux/delay.h>
							 | 
						
					
						
							
								
									
										
										
										
											2011-08-30 14:18:44 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <linux/module.h>
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <linux/firmware.h>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <linux/netdevice.h>
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files.  percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed.  Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability.  As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
  http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
  only the necessary includes are there.  ie. if only gfp is used,
  gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
  blocks and try to put the new include such that its order conforms
  to its surrounding.  It's put in the include block which contains
  core kernel includes, in the same order that the rest are ordered -
  alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
  doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
  because the file doesn't have fitting include block), it prints out
  an error message indicating which .h file needs to be added to the
  file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
   over 4000 files, deleting around 700 includes and adding ~480 gfp.h
   and ~3000 slab.h inclusions.  The script emitted errors for ~400
   files.
2. Each error was manually checked.  Some didn't need the inclusion,
   some needed manual addition while adding it to implementation .h or
   embedding .c file was more appropriate for others.  This step added
   inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
   from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
   e.g. lib/decompress_*.c used malloc/free() wrappers around slab
   APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
   editing them as sprinkling gfp.h and slab.h inclusions around .h
   files could easily lead to inclusion dependency hell.  Most gfp.h
   inclusion directives were ignored as stuff from gfp.h was usually
   wildly available and often used in preprocessor macros.  Each
   slab.h inclusion directive was examined and added manually as
   necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
   were fixed.  CONFIG_GCOV_KERNEL was turned off for all tests (as my
   distributed build env didn't work with gcov compiles) and a few
   more options had to be turned off depending on archs to make things
   build (like ipr on powerpc/64 which failed due to missing writeq).
   * x86 and x86_64 UP and SMP allmodconfig and a custom test config.
   * powerpc and powerpc64 SMP allmodconfig
   * sparc and sparc64 SMP allmodconfig
   * ia64 SMP allmodconfig
   * s390 SMP allmodconfig
   * alpha SMP allmodconfig
   * um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
   a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
											
										 
										
											2010-03-24 17:04:11 +09:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <linux/slab.h>
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <linux/usb.h>
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-11 01:16:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <linux/olpc-ec.h>
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-20 16:48:52 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#ifdef CONFIG_OLPC
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <asm/olpc.h>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:49:10 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define DRV_NAME "usb8xxx"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "host.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "decl.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "defs.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "dev.h"
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-10 15:11:23 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include "cmd.h"
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "if_usb.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define INSANEDEBUG	0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define lbs_deb_usb2(...) do { if (INSANEDEBUG) lbs_deb_usbd(__VA_ARGS__); } while (0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MESSAGE_HEADER_LEN	4
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-08-07 21:13:57 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								MODULE_FIRMWARE("libertas/usb8388_v9.bin");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								MODULE_FIRMWARE("libertas/usb8388_v5.bin");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								MODULE_FIRMWARE("libertas/usb8388.bin");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								MODULE_FIRMWARE("libertas/usb8682.bin");
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-07 22:00:03 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								MODULE_FIRMWARE("usb8388.bin");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-08-07 21:13:57 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								enum {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									MODEL_UNKNOWN = 0x0,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									MODEL_8388 = 0x1,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									MODEL_8682 = 0x2
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/* table of firmware file names */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static const struct lbs_fw_table fw_table[] = {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ MODEL_8388, "libertas/usb8388_olpc.bin", NULL },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ MODEL_8388, "libertas/usb8388_v9.bin", NULL },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ MODEL_8388, "libertas/usb8388_v5.bin", NULL },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ MODEL_8388, "libertas/usb8388.bin", NULL },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ MODEL_8388, "usb8388.bin", NULL },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ MODEL_8682, "libertas/usb8682.bin", NULL }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static struct usb_device_id if_usb_table[] = {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Enter the device signature inside */
							 | 
						
					
						
							
								
									
										
										
										
											2010-08-07 21:13:57 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ USB_DEVICE(0x05a3, 0x8388), .driver_info = MODEL_8388 },
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{}	/* Terminating entry */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								MODULE_DEVICE_TABLE(usb, if_usb_table);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void if_usb_receive(struct urb *urb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void if_usb_receive_fwload(struct urb *urb);
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 const struct firmware *fw,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 const struct firmware *unused);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       uint8_t *payload, uint16_t nb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											uint16_t nb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void if_usb_free(struct if_usb_card *cardp);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static int if_usb_reset_device(struct if_usb_card *cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * if_usb_write_bulk_callback - callback function to handle the status
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * of the URB
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @urb:	pointer to &urb structure
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * returns:	N/A
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void if_usb_write_bulk_callback(struct urb *urb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct if_usb_card *cardp = (struct if_usb_card *) urb->context;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* handle the transmission complete validations */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (urb->status == 0) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-23 15:43:44 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										struct lbs_private *priv = cardp->priv;
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb2(&urb->dev->dev, "URB status is successful\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb2(&urb->dev->dev, "Actual length transmitted %d\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											     urb->actual_length);
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										/* Boot commands such as UPDATE_FW and UPDATE_BOOT2 are not
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 * passed up to the lbs level.
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										 */
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (priv && priv->dnld_sent != DNLD_BOOTCMD_SENT)
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-06 14:36:11 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											lbs_host_to_card_done(priv);
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* print the failure status number for debug */
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										pr_info("URB in failure status: %d\n", urb->status);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * if_usb_free - free tx/rx urb, skb and rx buffer
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @cardp:	pointer to &if_usb_card
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * returns:	N/A
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static void if_usb_free(struct if_usb_card *cardp)
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_enter(LBS_DEB_USB);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Unlink tx & rx urb */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_kill_urb(cardp->tx_urb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_kill_urb(cardp->rx_urb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_free_urb(cardp->tx_urb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->tx_urb = NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_free_urb(cardp->rx_urb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->rx_urb = NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									kfree(cardp->ep_out_buf);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->ep_out_buf = NULL;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_leave(LBS_DEB_USB);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-17 14:42:33 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static void if_usb_setup_firmware(struct lbs_private *priv)
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-06 12:51:00 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2008-01-16 15:52:58 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct if_usb_card *cardp = priv->card;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-06 12:51:00 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct cmd_ds_set_boot2_ver b2_cmd;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-17 14:42:33 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct cmd_ds_802_11_fw_wake_method wake_method;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-06 12:51:00 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-15 03:46:44 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd));
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-06 12:51:00 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									b2_cmd.action = 0;
							 | 
						
					
						
							
								
									
										
										
										
											2008-01-16 15:52:58 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									b2_cmd.version = cardp->boot2_version;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-06 12:51:00 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-15 01:22:09 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (lbs_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd))
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-06 12:51:00 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb("Setting boot2 version failed\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-17 14:42:33 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									priv->wol_gpio = 2; /* Wake via GPIO2... */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									priv->wol_gap = 20; /* ... after 20ms    */
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-20 16:46:56 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											(struct wol_config *) NULL);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-17 14:42:33 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									wake_method.action = cpu_to_le16(CMD_ACT_GET);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) {
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:15 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										netdev_info(priv->dev, "Firmware does not seem to support PS mode\n");
							 | 
						
					
						
							
								
									
										
										
										
											2009-06-16 13:20:01 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										priv->fwcapinfo &= ~FW_CAPINFO_PS;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-17 14:42:33 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											lbs_deb_usb("Firmware seems to support PS with wake-via-command\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											/* The versions which boot up this way don't seem to
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											   work even if we set it to the command interrupt */
							 | 
						
					
						
							
								
									
										
										
										
											2009-06-16 13:20:01 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											priv->fwcapinfo &= ~FW_CAPINFO_PS;
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:15 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											netdev_info(priv->dev,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												    "Firmware doesn't wake via command interrupt; disabling PS mode\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-17 14:42:33 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-06 12:51:00 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 17:44:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static void if_usb_fw_timeo(unsigned long priv)
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 00:07:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct if_usb_card *cardp = (void *)priv;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-06 12:51:00 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 00:07:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (cardp->fwdnldover) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb("Download complete, no event. Assuming success\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										pr_err("Download timed out\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 00:07:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										cardp->surprise_removed = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									wake_up(&cardp->fw_wq);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-20 16:48:52 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#ifdef CONFIG_OLPC
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void if_usb_reset_olpc_card(struct lbs_private *priv)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									printk(KERN_CRIT "Resetting OLPC wireless via EC...\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									olpc_ec_cmd(0x25, NULL, 0, NULL, 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * if_usb_probe - sets the configuration values
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @intf:	&usb_interface pointer
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @id:	pointer to usb_device_id
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * returns:	0 on success, error code on failure
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static int if_usb_probe(struct usb_interface *intf,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											const struct usb_device_id *id)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct usb_device *udev;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct usb_host_interface *iface_desc;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct usb_endpoint_descriptor *endpoint;
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-23 15:43:44 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct lbs_private *priv;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct if_usb_card *cardp;
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									int r = -ENOMEM;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									int i;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									udev = interface_to_usbdev(intf);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
							 | 
						
					
						
							
								
									
										
										
										
											2012-01-29 12:56:23 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (!cardp)
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto error;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 00:07:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									init_waitqueue_head(&cardp->fw_wq);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 22:53:41 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:41:52 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cardp->udev = udev;
							 | 
						
					
						
							
								
									
										
										
										
											2010-08-07 21:13:57 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cardp->model = (uint32_t) id->driver_info;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									iface_desc = intf->cur_altsetting;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										     " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 23:36:54 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										     le16_to_cpu(udev->descriptor.bcdUSB),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										     udev->descriptor.bDeviceClass,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										     udev->descriptor.bDeviceSubClass,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										     udev->descriptor.bDeviceProtocol);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										endpoint = &iface_desc->endpoint[i].desc;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (usb_endpoint_is_bulk_in(endpoint)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											cardp->ep_in_size = le16_to_cpu(endpoint->wMaxPacketSize);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											cardp->ep_in = usb_endpoint_num(endpoint);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if (usb_endpoint_is_bulk_out(endpoint)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											cardp->ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											cardp->ep_out = usb_endpoint_num(endpoint);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											lbs_deb_usbd(&udev->dev, "Bulk out size is %d\n", cardp->ep_out_size);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (!cardp->ep_out_size || !cardp->ep_in_size) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&udev->dev, "Endpoints not found\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto dealloc;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&udev->dev, "Rx URB allocation failed\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto dealloc;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&udev->dev, "Tx URB allocation failed\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto dealloc;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, GFP_KERNEL);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!cardp->ep_out_buf) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&udev->dev, "Could not allocate buffer\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto dealloc;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2011-07-21 20:43:44 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (!(priv = lbs_add_card(cardp, &intf->dev)))
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										goto err_add_card;
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:01:42 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cardp->priv = priv;
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-02 13:16:55 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:17:06 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									priv->hw_host_to_card = if_usb_host_to_card;
							 | 
						
					
						
							
								
									
										
										
										
											2009-09-30 20:04:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									priv->enter_deep_sleep = NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									priv->exit_deep_sleep = NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									priv->reset_deep_sleep_wakeup = NULL;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-20 16:48:52 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#ifdef CONFIG_OLPC
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (machine_is_olpc())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										priv->reset_card = if_usb_reset_olpc_card;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-01-16 15:52:58 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cardp->boot2_version = udev->descriptor.bcdDevice;
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:17:06 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_get_dev(udev);
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:41:52 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									usb_set_intfdata(intf, cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									r = lbs_get_firmware_async(priv, &udev->dev, cardp->model,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												   fw_table, if_usb_prog_firmware);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (r)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto err_get_fw;
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-31 13:40:33 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								err_get_fw:
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-15 18:05:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_remove_card(priv);
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								err_add_card:
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if_usb_reset_device(cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								dealloc:
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:41:52 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if_usb_free(cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								error:
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return r;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * if_usb_disconnect - free resource and cleanup
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @intf:	USB interface structure
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * returns:	N/A
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void if_usb_disconnect(struct usb_interface *intf)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct if_usb_card *cardp = usb_get_intfdata(intf);
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-04 12:44:17 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct lbs_private *priv = cardp->priv;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_enter(LBS_DEB_MAIN);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cardp->surprise_removed = 1;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (priv) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-15 18:05:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_stop_card(priv);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_remove_card(priv);
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Unlink and free urb */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if_usb_free(cardp);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_set_intfdata(intf, NULL);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_put_dev(interface_to_usbdev(intf));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_leave(LBS_DEB_MAIN);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * if_usb_send_fw_pkt - download FW
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @cardp:	pointer to &struct if_usb_card
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * returns:	0
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct fwdata *fwdata = cardp->ep_out_buf;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-23 18:37:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									const uint8_t *firmware = cardp->fw->data;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/* If we got a CRC failure on the last block, back
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									   up and retry it */
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!cardp->CRC_OK) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										cardp->totalbytes = cardp->fwlastblksent;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										cardp->fwseqnum--;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										     cardp->totalbytes);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/* struct fwdata (which we sent to the card) has an
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									   extra __le32 field in between the header and the data,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									   which is not in the struct fwheader in the actual
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									   firmware binary. Insert the seqnum in the middle... */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memcpy(&fwdata->hdr, &firmware[cardp->totalbytes],
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									       sizeof(struct fwheader));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->fwlastblksent = cardp->totalbytes;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->totalbytes += sizeof(struct fwheader);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memcpy(fwdata->data, &firmware[cardp->totalbytes],
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									       le32_to_cpu(fwdata->hdr.datalength));
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_usb2(&cardp->udev->dev, "Data length = %d\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										     le32_to_cpu(fwdata->hdr.datalength));
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										     le32_to_cpu(fwdata->hdr.datalength));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											     cardp->fwseqnum, cardp->totalbytes);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										cardp->fwfinalblk = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										     cardp->totalbytes);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static int if_usb_reset_device(struct if_usb_card *cardp)
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-27 13:08:08 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct cmd_header *cmd = cardp->ep_out_buf + 4;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									int ret;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:01:42 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_enter(LBS_DEB_USB);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-08 23:49:06 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cmd->command = cpu_to_le16(CMD_802_11_RESET);
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-27 13:08:08 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cmd->size = cpu_to_le16(sizeof(cmd));
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-08 23:49:06 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cmd->result = cpu_to_le16(0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cmd->seqnum = cpu_to_le16(0x5a5a);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-10 09:04:33 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									usb_tx_block(cardp, cardp->ep_out_buf, 4 + sizeof(struct cmd_header));
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-08 23:49:06 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-10 18:53:34 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									msleep(100);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									ret = usb_reset_device(cardp->udev);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-10 18:53:34 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									msleep(100);
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:01:42 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-20 16:48:52 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#ifdef CONFIG_OLPC
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (ret && machine_is_olpc())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if_usb_reset_olpc_card(NULL);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:01:42 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return ret;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 *  usb_tx_block - transfer the data to the device
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  @cardp: 	pointer to &struct if_usb_card
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  @payload:	pointer to payload data
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  @nb:	data length
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  returns:	0 for success or negative error code
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-13 20:14:56 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									int ret;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* check if device is removed */
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (cardp->surprise_removed) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-13 20:14:56 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ret = -ENODEV;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto tx_ret;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											  usb_sndbulkpipe(cardp->udev,
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
													  cardp->ep_out),
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											  payload, nb, if_usb_write_bulk_callback, cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-07 15:12:26 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ret = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								tx_ret:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return ret;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												  void (*callbackfn)(struct urb *urb))
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct sk_buff *skb;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									int ret = -1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										pr_err("No free skb\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto rx_ret;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cardp->rx_skb = skb;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Fill the receive configuration URB and initialise the Rx call back */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											  usb_rcvbulkpipe(cardp->udev, cardp->ep_in),
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-30 17:45:14 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											  skb->data + IPFIELD_ALIGN_OFFSET,
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											  MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											  cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-07 15:12:26 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-28 16:20:51 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										cardp->rx_skb = NULL;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ret = -1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb2(&cardp->udev->dev, "Submit Rx URB success\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ret = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								rx_ret:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return ret;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp)
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static int if_usb_submit_rx_urb(struct if_usb_card *cardp)
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void if_usb_receive_fwload(struct urb *urb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct if_usb_card *cardp = urb->context;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct sk_buff *skb = cardp->rx_skb;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct fwsyncheader *syncfwheader;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct bootcmdresp bootcmdresp;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (urb->status) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev,
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											     "URB status is failed during fw load\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 13:15:25 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (cardp->fwdnldover) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										__le32 *tmp = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										    tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											pr_info("Firmware ready event received\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 13:15:25 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											wake_up(&cardp->fw_wq);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											lbs_deb_usb("Waiting for confirmation; got %x %x\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												    le32_to_cpu(tmp[0]), le32_to_cpu(tmp[1]));
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 13:15:25 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if_usb_submit_rx_urb_fwload(cardp);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-10 18:53:34 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (cardp->bootcmdresp <= 0) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sizeof(bootcmdresp));
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 23:36:54 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											kfree_skb(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if_usb_submit_rx_urb_fwload(cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											cardp->bootcmdresp = BOOT_CMD_RESP_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											lbs_deb_usbd(&cardp->udev->dev,
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												     "Received valid boot command response\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (bootcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (bootcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											    bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											    bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 13:15:25 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												if (!cardp->bootcmdresp)
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
													pr_info("Firmware already seems alive; resetting\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-08 23:49:06 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												cardp->bootcmdresp = -1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											} else {
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												pr_info("boot cmd response wrong magic number (0x%x)\n",
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
													    le32_to_cpu(bootcmdresp.magic));
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-08 23:49:06 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											   (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											   (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) {
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											pr_info("boot cmd response cmd_tag error (%d)\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												bootcmdresp.cmd);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if (bootcmdresp.result != BOOT_CMD_RESP_OK) {
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											pr_info("boot cmd response result error (%d)\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												bootcmdresp.result);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											cardp->bootcmdresp = 1;
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											lbs_deb_usbd(&cardp->udev->dev,
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												     "Received valid boot command response\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if_usb_submit_rx_urb_fwload(cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-05-15 23:12:28 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									syncfwheader = kmemdup(skb->data + IPFIELD_ALIGN_OFFSET,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       sizeof(struct fwsyncheader), GFP_ATOMIC);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!syncfwheader) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!syncfwheader->cmd) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											     le32_to_cpu(syncfwheader->seqnum));
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										cardp->CRC_OK = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										cardp->CRC_OK = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/* Give device 5s to either write firmware to its RAM or eeprom */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									mod_timer(&cardp->fw_timeout, jiffies + (HZ*5));
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 00:07:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (cardp->fwfinalblk) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										cardp->fwdnldover = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto exit;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 00:07:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if_usb_send_fw_pkt(cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 00:07:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 exit:
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 13:15:25 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if_usb_submit_rx_urb_fwload(cardp);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									kfree(syncfwheader);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MRVDRV_MIN_PKT_LEN	30
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												       struct if_usb_card *cardp,
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-23 15:43:44 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												       struct lbs_private *priv)
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    || recvlength < MRVDRV_MIN_PKT_LEN) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									skb_put(skb, recvlength);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									skb_pull(skb, MESSAGE_HEADER_LEN);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-15 18:05:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_process_rxed_packet(priv, skb);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												      struct sk_buff *skb,
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												      struct if_usb_card *cardp,
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-23 15:43:44 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												      struct lbs_private *priv)
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2008-04-01 14:50:43 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									u8 i;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 13:49:39 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (recvlength > LBS_CMD_BUFFER_SIZE) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev,
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											     "The receive buffer is too large\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-04-11 14:50:23 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									BUG_ON(!in_interrupt());
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-08 20:04:36 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spin_lock(&priv->driver_lock);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-04-01 14:50:43 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									i = (priv->resp_idx == 0) ? 1 : 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BUG_ON(priv->resp_len[i]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									priv->resp_len[i] = (recvlength - MESSAGE_HEADER_LEN);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memcpy(priv->resp_buf[i], recvbuff + MESSAGE_HEADER_LEN,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										priv->resp_len[i]);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									kfree_skb(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2008-04-01 14:50:43 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_notify_command_response(priv, i);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-08 20:04:36 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spin_unlock(&priv->driver_lock);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_usbd(&cardp->udev->dev,
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										    "Wake up main thread to handle cmd response\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 *  if_usb_receive - read the packet into the upload buffer,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  wake up the main thread and initialise the Rx callack
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 *  @urb:	pointer to &struct urb
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  returns:	N/A
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void if_usb_receive(struct urb *urb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct if_usb_card *cardp = urb->context;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct sk_buff *skb = cardp->rx_skb;
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-23 15:43:44 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct lbs_private *priv = cardp->priv;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									int recvlength = urb->actual_length;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									uint8_t *recvbuff = NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									uint32_t recvtype = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									__le32 *pkt = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
							 | 
						
					
						
							
								
									
										
										
										
											2008-04-01 14:50:43 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									uint32_t event;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_enter(LBS_DEB_USB);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (recvlength) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (urb->status) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											lbs_deb_usbd(&cardp->udev->dev, "RX URB failed: %d\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												     urb->status);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											goto setup_for_next;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										recvtype = le32_to_cpu(pkt[0]);
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev,
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-03 09:40:55 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											    "Recv length = 0x%x, Recv type = 0x%X\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											    recvlength, recvtype);
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-28 16:20:51 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									} else if (urb->status) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto rx_exit;
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-28 16:20:51 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									switch (recvtype) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case CMD_TYPE_DATA:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										process_cmdtypedata(recvlength, skb, cardp, priv);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case CMD_TYPE_REQUEST:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										process_cmdrequest(recvlength, recvbuff, skb, cardp, priv);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case CMD_TYPE_INDICATION:
							 | 
						
					
						
							
								
									
										
										
										
											2008-04-01 14:50:43 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										/* Event handling */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										event = le32_to_cpu(pkt[1]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", event);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-04-01 14:50:43 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										/* Icky undocumented magic special case */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (event & 0xffff0000) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											u32 trycount = (event & 0xffff0000) >> 16;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-04-01 14:50:43 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											lbs_send_tx_feedback(priv, trycount);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											lbs_queue_event(priv, event & 0xFF);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									default:
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-03 09:40:55 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n",
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											     recvtype);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								setup_for_next:
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if_usb_submit_rx_urb(cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								rx_exit:
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_leave(LBS_DEB_USB);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 *  if_usb_host_to_card - downloads data to FW
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  @priv:	pointer to &struct lbs_private structure
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  @type:	type of data
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  @payload:	pointer to data buffer
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  @nb:	number of bytes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  returns:	0 for success or negative error code
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       uint8_t *payload, uint16_t nb)
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct if_usb_card *cardp = priv->card;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (type == MVMS_CMD) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 13:05:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										priv->dnld_sent = DNLD_CMD_SENT;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_DATA);
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 13:05:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										priv->dnld_sent = DNLD_DATA_SENT;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									memcpy((cardp->ep_out_buf + MESSAGE_HEADER_LEN), payload, nb);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return usb_tx_block(cardp, cardp->ep_out_buf, nb + MESSAGE_HEADER_LEN);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-02 11:14:49 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 *  if_usb_issue_boot_command - issues Boot command to the Boot2 code
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  @cardp:	pointer to &if_usb_card
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  @ivalue:	1:Boot from FW by USB-Download
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *		2:Boot from FW in EEPROM
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  returns:	0 for success or negative error code
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-02 11:14:49 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-02 11:14:49 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct bootcmd *bootcmd = cardp->ep_out_buf;
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-02 11:14:49 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Prepare command */
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									bootcmd->magic = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									bootcmd->cmd = ivalue;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memset(bootcmd->pad, 0, sizeof(bootcmd->pad));
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-02 11:14:49 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Issue command */
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									usb_tx_block(cardp, cardp->ep_out_buf, sizeof(*bootcmd));
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-02 11:14:49 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 *  check_fwfile_format - check the validity of Boot2/FW image
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							
								
									
										
										
										
											2011-04-26 15:25:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 *  @data:	pointer to image
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  @totlen:	image length
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  returns:     0 (good) or 1 (failure)
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-23 18:37:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									uint32_t bincmd, exit;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									uint32_t blksize, offset, len;
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									int ret;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									ret = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									exit = len = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									do {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										struct fwheader *fwh = (void *)data;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										bincmd = le32_to_cpu(fwh->dnldcmd);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										blksize = le32_to_cpu(fwh->datalength);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										switch (bincmd) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case FW_HAS_DATA_TO_RECV:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											offset = sizeof(struct fwheader) + blksize;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											data += offset;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											len += offset;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (len >= totlen)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												exit = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case FW_HAS_LAST_BLOCK:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											exit = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											ret = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										default:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											exit = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} while (!exit);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (ret)
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										pr_err("firmware file format check FAIL\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lbs_deb_fw("firmware file format check PASS\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return ret;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 const struct firmware *fw,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 const struct firmware *unused)
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct if_usb_card *cardp = priv->card;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									int i = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									static int reset_count = 10;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_enter(LBS_DEB_USB);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-08-07 21:13:57 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (ret) {
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										pr_err("failed to find firmware (%d)\n", ret);
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										goto done;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cardp->fw = fw;
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ret = -EINVAL;
							 | 
						
					
						
							
								
									
										
										
										
											2013-10-14 17:51:55 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										goto done;
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Cancel any pending usb business */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_kill_urb(cardp->rx_urb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_kill_urb(cardp->tx_urb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->fwlastblksent = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->fwdnldover = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->totalbytes = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->fwfinalblk = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->bootcmdresp = 0;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								restart:
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ret = -EIO;
							 | 
						
					
						
							
								
									
										
										
										
											2013-10-14 17:51:55 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										goto done;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->bootcmdresp = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									do {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										int j = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										i++;
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:52:42 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* wait for command response */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										do {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											j++;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											msleep_interruptible(100);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} while (cardp->bootcmdresp == 0 && j < 10);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} while (cardp->bootcmdresp == 0 && i < 5);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (cardp->bootcmdresp == BOOT_CMD_RESP_NOT_SUPPORTED) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* Return to normal operation */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ret = -EOPNOTSUPP;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										usb_kill_urb(cardp->rx_urb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										usb_kill_urb(cardp->tx_urb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (if_usb_submit_rx_urb(cardp) < 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											ret = -EIO;
							 | 
						
					
						
							
								
									
										
										
										
											2013-10-14 17:51:55 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										goto done;
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									} else if (cardp->bootcmdresp <= 0) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (--reset_count >= 0) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if_usb_reset_device(cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											goto restart;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ret = -EIO;
							 | 
						
					
						
							
								
									
										
										
										
											2013-10-14 17:51:55 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										goto done;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									i = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->totalbytes = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->fwlastblksent = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->CRC_OK = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->fwdnldover = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->fwseqnum = -1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->totalbytes = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cardp->fwfinalblk = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 00:07:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/* Send the first firmware packet... */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if_usb_send_fw_pkt(cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 00:07:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/* ... and wait for the process to complete */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 22:53:41 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 00:07:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									del_timer_sync(&cardp->fw_timeout);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 13:15:25 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									usb_kill_urb(cardp->rx_urb);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!cardp->fwdnldover) {
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										pr_info("failed to load fw, resetting device!\n");
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (--reset_count >= 0) {
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-20 11:43:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if_usb_reset_device(cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											goto restart;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-02 16:49:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										pr_info("FW download failure, time = %d ms\n", i * 100);
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-21 11:02:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ret = -EIO;
							 | 
						
					
						
							
								
									
										
										
										
											2013-10-14 17:51:55 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										goto done;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cardp->priv->fw_ready = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if_usb_submit_rx_urb(cardp);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (lbs_start_card(priv))
							 | 
						
					
						
							
								
									
										
										
										
											2013-10-14 17:51:55 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										goto done;
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if_usb_setup_firmware(priv);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/*
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									priv->wol_criteria = EHS_REMOVE_WAKEUP;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										priv->ehs_remove_supported = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 done:
							 | 
						
					
						
							
								
									
										
										
										
											2013-10-14 17:51:55 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									cardp->fw = NULL;
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 23:53:55 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_leave(LBS_DEB_USB);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-08-02 11:45:12 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#ifdef CONFIG_PM
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct if_usb_card *cardp = usb_get_intfdata(intf);
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-23 15:43:44 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct lbs_private *priv = cardp->priv;
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-12 17:40:56 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									int ret;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_enter(LBS_DEB_USB);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-16 17:44:00 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (priv->psstate != PS_STATE_FULL_POWER) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ret = -1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto out;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2011-07-27 17:19:00 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#ifdef CONFIG_OLPC
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (machine_is_olpc()) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (priv->wol_criteria == EHS_REMOVE_WAKEUP)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											olpc_ec_wakeup_clear(EC_SCI_SRC_WLAN);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											olpc_ec_wakeup_set(EC_SCI_SRC_WLAN);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-12 17:40:56 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									ret = lbs_suspend(priv);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (ret)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto out;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Unlink tx & rx urb */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_kill_urb(cardp->tx_urb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									usb_kill_urb(cardp->rx_urb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-12 17:40:56 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 out:
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_leave(LBS_DEB_USB);
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-12 17:40:56 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return ret;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static int if_usb_resume(struct usb_interface *intf)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct if_usb_card *cardp = usb_get_intfdata(intf);
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-23 15:43:44 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct lbs_private *priv = cardp->priv;
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_enter(LBS_DEB_USB);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-11 12:53:43 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if_usb_submit_rx_urb(cardp);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-12 17:40:56 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_resume(priv);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 11:27:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									lbs_deb_leave(LBS_DEB_USB);
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define if_usb_suspend NULL
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define if_usb_resume NULL
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static struct usb_driver if_usb_driver = {
							 | 
						
					
						
							
								
									
										
										
										
											2007-11-20 17:44:04 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									.name = DRV_NAME,
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									.probe = if_usb_probe,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									.disconnect = if_usb_disconnect,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									.id_table = if_usb_table,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									.suspend = if_usb_suspend,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									.resume = if_usb_resume,
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-01 11:43:53 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									.reset_resume = if_usb_resume,
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-23 10:08:51 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									.disable_hub_initiated_lpm = 1,
							 | 
						
					
						
							
								
									
										
										
										
											2007-02-10 12:25:27 -02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2011-11-18 09:44:20 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								module_usb_driver(if_usb_driver);
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:37:58 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								MODULE_DESCRIPTION("8388 USB WLAN Driver");
							 | 
						
					
						
							
								
									
										
										
										
											2007-12-14 00:47:05 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								MODULE_AUTHOR("Marvell International Ltd. and Red Hat, Inc.");
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-25 12:37:58 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								MODULE_LICENSE("GPL");
							 |