if_usb.c revision 7732ca45c68f893689a8c0d8c6e2eb2bfefbc087
1/**
2  * This file contains functions used in USB interface module.
3  */
4#include <linux/delay.h>
5#include <linux/moduleparam.h>
6#include <linux/firmware.h>
7#include <linux/netdevice.h>
8#include <linux/list.h>
9#include <linux/usb.h>
10
11#define DRV_NAME "usb8xxx"
12
13#include "host.h"
14#include "decl.h"
15#include "defs.h"
16#include "dev.h"
17#include "if_usb.h"
18
19#define MESSAGE_HEADER_LEN	4
20
21static const char usbdriver_name[] = "usb8xxx";
22static u8 *default_fw_name = "usb8388.bin";
23
24char *libertas_fw_name = NULL;
25module_param_named(fw_name, libertas_fw_name, charp, 0644);
26
27/*
28 * We need to send a RESET command to all USB devices before
29 * we tear down the USB connection. Otherwise we would not
30 * be able to re-init device the device if the module gets
31 * loaded again. This is a list of all initialized USB devices,
32 * for the reset code see if_usb_reset_device()
33*/
34static LIST_HEAD(usb_devices);
35
36static struct usb_device_id if_usb_table[] = {
37	/* Enter the device signature inside */
38	{ USB_DEVICE(0x1286, 0x2001) },
39	{ USB_DEVICE(0x05a3, 0x8388) },
40	{}	/* Terminating entry */
41};
42
43MODULE_DEVICE_TABLE(usb, if_usb_table);
44
45static void if_usb_receive(struct urb *urb);
46static void if_usb_receive_fwload(struct urb *urb);
47static int if_usb_reset_device(wlan_private *priv);
48static int if_usb_register_dev(wlan_private * priv);
49static int if_usb_unregister_dev(wlan_private *);
50static int if_usb_prog_firmware(wlan_private *);
51static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
52static int if_usb_get_int_status(wlan_private * priv, u8 *);
53static int if_usb_read_event_cause(wlan_private *);
54
55/**
56 *  @brief  call back function to handle the status of the URB
57 *  @param urb 		pointer to urb structure
58 *  @return 	   	N/A
59 */
60static void if_usb_write_bulk_callback(struct urb *urb)
61{
62	wlan_private *priv = (wlan_private *) (urb->context);
63	wlan_adapter *adapter = priv->adapter;
64	struct net_device *dev = priv->dev;
65
66	/* handle the transmission complete validations */
67
68	if (urb->status != 0) {
69		/* print the failure status number for debug */
70		lbs_pr_info("URB in failure status: %d\n", urb->status);
71	} else {
72		/*
73		lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n");
74		lbs_deb_usbd(&urb->dev->dev, "Actual length transmitted %d\n",
75		       urb->actual_length);
76		*/
77		priv->dnld_sent = DNLD_RES_RECEIVED;
78		/* Wake main thread if commands are pending */
79		if (!adapter->cur_cmd)
80			wake_up_interruptible(&priv->mainthread.waitq);
81		if ((adapter->connect_status == libertas_connected)) {
82			netif_wake_queue(dev);
83			netif_wake_queue(priv->mesh_dev);
84		}
85	}
86
87	return;
88}
89
90/**
91 *  @brief  free tx/rx urb, skb and rx buffer
92 *  @param cardp	pointer usb_card_rec
93 *  @return 	   	N/A
94 */
95void if_usb_free(struct usb_card_rec *cardp)
96{
97	lbs_deb_enter(LBS_DEB_USB);
98
99	/* Unlink tx & rx urb */
100	usb_kill_urb(cardp->tx_urb);
101	usb_kill_urb(cardp->rx_urb);
102
103	usb_free_urb(cardp->tx_urb);
104	cardp->tx_urb = NULL;
105
106	usb_free_urb(cardp->rx_urb);
107	cardp->rx_urb = NULL;
108
109	kfree(cardp->bulk_out_buffer);
110	cardp->bulk_out_buffer = NULL;
111
112	lbs_deb_leave(LBS_DEB_USB);
113}
114
115/**
116 *  @brief sets the configuration values
117 *  @param ifnum	interface number
118 *  @param id		pointer to usb_device_id
119 *  @return 	   	0 on success, error code on failure
120 */
121static int if_usb_probe(struct usb_interface *intf,
122			const struct usb_device_id *id)
123{
124	struct usb_device *udev;
125	struct usb_host_interface *iface_desc;
126	struct usb_endpoint_descriptor *endpoint;
127	wlan_private *priv;
128	struct usb_card_rec *cardp;
129	int i;
130
131	udev = interface_to_usbdev(intf);
132
133	cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
134	if (!cardp) {
135		lbs_pr_err("Out of memory allocating private data.\n");
136		goto error;
137	}
138
139	cardp->udev = udev;
140	iface_desc = intf->cur_altsetting;
141
142	lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
143	       " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
144	       udev->descriptor.bcdUSB,
145	       udev->descriptor.bDeviceClass,
146	       udev->descriptor.bDeviceSubClass,
147	       udev->descriptor.bDeviceProtocol);
148
149	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
150		endpoint = &iface_desc->endpoint[i].desc;
151		if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
152		    && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
153			USB_ENDPOINT_XFER_BULK)) {
154			/* we found a bulk in endpoint */
155			lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n",
156			       endpoint->wMaxPacketSize);
157			if (!
158			    (cardp->rx_urb =
159			     usb_alloc_urb(0, GFP_KERNEL))) {
160				lbs_deb_usbd(&udev->dev,
161				       "Rx URB allocation failed\n");
162				goto dealloc;
163			}
164			cardp->rx_urb_recall = 0;
165
166			cardp->bulk_in_size =
167			    endpoint->wMaxPacketSize;
168			cardp->bulk_in_endpointAddr =
169			    (endpoint->
170			     bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
171			lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n",
172			       endpoint->bEndpointAddress);
173		}
174
175		if (((endpoint->
176		      bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
177		     USB_DIR_OUT)
178		    && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
179			USB_ENDPOINT_XFER_BULK)) {
180			/* We found bulk out endpoint */
181			if (!
182			    (cardp->tx_urb =
183			     usb_alloc_urb(0, GFP_KERNEL))) {
184				lbs_deb_usbd(&udev->dev,
185				       "Tx URB allocation failed\n");
186				goto dealloc;
187			}
188
189			cardp->bulk_out_size =
190			    endpoint->wMaxPacketSize;
191			lbs_deb_usbd(&udev->dev,
192				    "Bulk out size is %d\n",
193				    endpoint->wMaxPacketSize);
194			cardp->bulk_out_endpointAddr =
195			    endpoint->bEndpointAddress;
196			lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n",
197				    endpoint->bEndpointAddress);
198			cardp->bulk_out_buffer =
199			    kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE,
200				    GFP_KERNEL);
201
202			if (!cardp->bulk_out_buffer) {
203				lbs_deb_usbd(&udev->dev,
204				       "Could not allocate buffer\n");
205				goto dealloc;
206			}
207		}
208	}
209
210	if (!(priv = libertas_add_card(cardp, &udev->dev)))
211		goto dealloc;
212
213	if (libertas_add_mesh(priv, &udev->dev))
214		goto err_add_mesh;
215
216	priv->hw_register_dev = if_usb_register_dev;
217	priv->hw_unregister_dev = if_usb_unregister_dev;
218	priv->hw_prog_firmware = if_usb_prog_firmware;
219	priv->hw_host_to_card = if_usb_host_to_card;
220	priv->hw_get_int_status = if_usb_get_int_status;
221	priv->hw_read_event_cause = if_usb_read_event_cause;
222
223	if (libertas_activate_card(priv, libertas_fw_name))
224		goto err_activate_card;
225
226	list_add_tail(&cardp->list, &usb_devices);
227
228	usb_get_dev(udev);
229	usb_set_intfdata(intf, cardp);
230
231	return 0;
232
233err_activate_card:
234	unregister_netdev(priv->mesh_dev);
235	free_netdev(priv->mesh_dev);
236err_add_mesh:
237	free_netdev(priv->dev);
238	kfree(priv->adapter);
239dealloc:
240	if_usb_free(cardp);
241
242error:
243	return -ENOMEM;
244}
245
246/**
247 *  @brief free resource and cleanup
248 *  @param intf		USB interface structure
249 *  @return 	   	N/A
250 */
251static void if_usb_disconnect(struct usb_interface *intf)
252{
253	struct usb_card_rec *cardp = usb_get_intfdata(intf);
254	wlan_private *priv = (wlan_private *) cardp->priv;
255	wlan_adapter *adapter = NULL;
256
257	adapter = priv->adapter;
258
259	/*
260	 * Update Surprise removed to TRUE
261	 */
262	adapter->surpriseremoved = 1;
263
264	list_del(&cardp->list);
265
266	/* card is removed and we can call wlan_remove_card */
267	lbs_deb_usbd(&cardp->udev->dev, "call remove card\n");
268	libertas_remove_mesh(priv);
269	libertas_remove_card(priv);
270
271	/* Unlink and free urb */
272	if_usb_free(cardp);
273
274	usb_set_intfdata(intf, NULL);
275	usb_put_dev(interface_to_usbdev(intf));
276
277	return;
278}
279
280/**
281 *  @brief  This function download FW
282 *  @param priv		pointer to wlan_private
283 *  @return 	   	0
284 */
285static int if_prog_firmware(wlan_private * priv)
286{
287	struct usb_card_rec *cardp = priv->card;
288	struct FWData *fwdata;
289	struct fwheader *fwheader;
290	u8 *firmware = priv->firmware->data;
291
292	fwdata = kmalloc(sizeof(struct FWData), GFP_ATOMIC);
293
294	if (!fwdata)
295		return -1;
296
297	fwheader = &fwdata->fwheader;
298
299	if (!cardp->CRC_OK) {
300		cardp->totalbytes = cardp->fwlastblksent;
301		cardp->fwseqnum = cardp->lastseqnum - 1;
302	}
303
304	/*
305	lbs_deb_usbd(&cardp->udev->dev, "totalbytes = %d\n",
306		    cardp->totalbytes);
307	*/
308
309	memcpy(fwheader, &firmware[cardp->totalbytes],
310	       sizeof(struct fwheader));
311
312	cardp->fwlastblksent = cardp->totalbytes;
313	cardp->totalbytes += sizeof(struct fwheader);
314
315	/* lbs_deb_usbd(&cardp->udev->dev,"Copy Data\n"); */
316	memcpy(fwdata->data, &firmware[cardp->totalbytes],
317	       fwdata->fwheader.datalength);
318
319	/*
320	lbs_deb_usbd(&cardp->udev->dev,
321		    "Data length = %d\n", fwdata->fwheader.datalength);
322	*/
323
324	cardp->fwseqnum = cardp->fwseqnum + 1;
325
326	fwdata->seqnum = cardp->fwseqnum;
327	cardp->lastseqnum = fwdata->seqnum;
328	cardp->totalbytes += fwdata->fwheader.datalength;
329
330	if (fwheader->dnldcmd == FW_HAS_DATA_TO_RECV) {
331		/*
332		lbs_deb_usbd(&cardp->udev->dev, "There is data to follow\n");
333		lbs_deb_usbd(&cardp->udev->dev,
334			    "seqnum = %d totalbytes = %d\n", cardp->fwseqnum,
335			    cardp->totalbytes);
336		*/
337		memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
338		usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
339
340	} else if (fwdata->fwheader.dnldcmd == FW_HAS_LAST_BLOCK) {
341		/*
342		lbs_deb_usbd(&cardp->udev->dev,
343			    "Host has finished FW downloading\n");
344		lbs_deb_usbd(&cardp->udev->dev,
345			    "Donwloading FW JUMP BLOCK\n");
346		*/
347		memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
348		usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
349		cardp->fwfinalblk = 1;
350	}
351
352	/*
353	lbs_deb_usbd(&cardp->udev->dev,
354		    "The firmware download is done size is %d\n",
355		    cardp->totalbytes);
356	*/
357
358	kfree(fwdata);
359
360	return 0;
361}
362
363static int libertas_do_reset(wlan_private *priv)
364{
365	int ret;
366	struct usb_card_rec *cardp = priv->card;
367
368	lbs_deb_enter(LBS_DEB_USB);
369
370	ret = usb_reset_device(cardp->udev);
371	if (!ret) {
372		msleep(10);
373		if_usb_reset_device(priv);
374		msleep(10);
375	}
376
377	lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
378
379	return ret;
380}
381
382/**
383 *  @brief This function transfer the data to the device.
384 *  @param priv 	pointer to wlan_private
385 *  @param payload	pointer to payload data
386 *  @param nb		data length
387 *  @return 	   	0 or -1
388 */
389int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb)
390{
391	/* pointer to card structure */
392	struct usb_card_rec *cardp = priv->card;
393	int ret = -1;
394
395	/* check if device is removed */
396	if (priv->adapter->surpriseremoved) {
397		lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
398		goto tx_ret;
399	}
400
401	usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
402			  usb_sndbulkpipe(cardp->udev,
403					  cardp->bulk_out_endpointAddr),
404			  payload, nb, if_usb_write_bulk_callback, priv);
405
406	cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
407
408	if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
409		/*  transfer failed */
410		lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed\n");
411		ret = -1;
412	} else {
413		/* lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb success\n"); */
414		ret = 0;
415	}
416
417tx_ret:
418	return ret;
419}
420
421static int __if_usb_submit_rx_urb(wlan_private * priv,
422				  void (*callbackfn)
423				  (struct urb *urb))
424{
425	struct usb_card_rec *cardp = priv->card;
426	struct sk_buff *skb;
427	struct read_cb_info *rinfo = &cardp->rinfo;
428	int ret = -1;
429
430	if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
431		lbs_pr_err("No free skb\n");
432		goto rx_ret;
433	}
434
435	rinfo->skb = skb;
436
437	/* Fill the receive configuration URB and initialise the Rx call back */
438	usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
439			  usb_rcvbulkpipe(cardp->udev,
440					  cardp->bulk_in_endpointAddr),
441			  (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
442			  MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
443			  rinfo);
444
445	cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
446
447	/* lbs_deb_usbd(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); */
448	if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
449		/* handle failure conditions */
450		lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed\n");
451		ret = -1;
452	} else {
453		/* lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB success\n"); */
454		ret = 0;
455	}
456
457rx_ret:
458	return ret;
459}
460
461static inline int if_usb_submit_rx_urb_fwload(wlan_private * priv)
462{
463	return __if_usb_submit_rx_urb(priv, &if_usb_receive_fwload);
464}
465
466static inline int if_usb_submit_rx_urb(wlan_private * priv)
467{
468	return __if_usb_submit_rx_urb(priv, &if_usb_receive);
469}
470
471static void if_usb_receive_fwload(struct urb *urb)
472{
473	struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
474	wlan_private *priv = rinfo->priv;
475	struct sk_buff *skb = rinfo->skb;
476	struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
477	struct fwsyncheader *syncfwheader;
478	struct bootcmdrespStr bootcmdresp;
479
480	if (urb->status) {
481		lbs_deb_usbd(&cardp->udev->dev,
482			    "URB status is failed during fw load\n");
483		kfree_skb(skb);
484		return;
485	}
486
487	if (cardp->bootcmdresp == 0) {
488		memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
489			sizeof(bootcmdresp));
490		if (cardp->udev->descriptor.bcdDevice < 0x3106) {
491			kfree_skb(skb);
492			if_usb_submit_rx_urb_fwload(priv);
493			cardp->bootcmdresp = 1;
494			lbs_deb_usbd(&cardp->udev->dev,
495				    "Received valid boot command response\n");
496			return;
497		}
498		if (bootcmdresp.u32magicnumber != BOOT_CMD_MAGIC_NUMBER) {
499			lbs_pr_info(
500				"boot cmd response wrong magic number (0x%x)\n",
501				bootcmdresp.u32magicnumber);
502		} else if (bootcmdresp.u8cmd_tag != BOOT_CMD_FW_BY_USB) {
503			lbs_pr_info(
504				"boot cmd response cmd_tag error (%d)\n",
505				bootcmdresp.u8cmd_tag);
506		} else if (bootcmdresp.u8result != BOOT_CMD_RESP_OK) {
507			lbs_pr_info(
508				"boot cmd response result error (%d)\n",
509				bootcmdresp.u8result);
510		} else {
511			cardp->bootcmdresp = 1;
512			lbs_deb_usbd(&cardp->udev->dev,
513				    "Received valid boot command response\n");
514		}
515		kfree_skb(skb);
516		if_usb_submit_rx_urb_fwload(priv);
517		return;
518	}
519
520	syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC);
521	if (!syncfwheader) {
522		lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
523		kfree_skb(skb);
524		return;
525	}
526
527	memcpy(syncfwheader, skb->data + IPFIELD_ALIGN_OFFSET,
528			sizeof(struct fwsyncheader));
529
530	if (!syncfwheader->cmd) {
531		/*
532		lbs_deb_usbd(&cardp->udev->dev,
533			    "FW received Blk with correct CRC\n");
534		lbs_deb_usbd(&cardp->udev->dev,
535			    "FW received Blk seqnum = %d\n",
536		       syncfwheader->seqnum);
537		*/
538		cardp->CRC_OK = 1;
539	} else {
540		lbs_deb_usbd(&cardp->udev->dev,
541			    "FW received Blk with CRC error\n");
542		cardp->CRC_OK = 0;
543	}
544
545	kfree_skb(skb);
546
547	if (cardp->fwfinalblk) {
548		cardp->fwdnldover = 1;
549		goto exit;
550	}
551
552	if_prog_firmware(priv);
553
554	if_usb_submit_rx_urb_fwload(priv);
555exit:
556	kfree(syncfwheader);
557
558	return;
559
560}
561
562#define MRVDRV_MIN_PKT_LEN	30
563
564static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
565				       struct usb_card_rec *cardp,
566				       wlan_private *priv)
567{
568	if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE +
569	    MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) {
570		lbs_deb_usbd(&cardp->udev->dev,
571			    "Packet length is Invalid\n");
572		kfree_skb(skb);
573		return;
574	}
575
576	skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
577	skb_put(skb, recvlength);
578	skb_pull(skb, MESSAGE_HEADER_LEN);
579	libertas_process_rxed_packet(priv, skb);
580	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
581}
582
583static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
584				      struct sk_buff *skb,
585				      struct usb_card_rec *cardp,
586				      wlan_private *priv)
587{
588	u8 *cmdbuf;
589	if (recvlength > MRVDRV_SIZE_OF_CMD_BUFFER) {
590		lbs_deb_usbd(&cardp->udev->dev,
591			    "The receive buffer is too large\n");
592		kfree_skb(skb);
593		return;
594	}
595
596	if (!in_interrupt())
597		BUG();
598
599	spin_lock(&priv->adapter->driver_lock);
600	/* take care of cur_cmd = NULL case by reading the
601	 * data to clear the interrupt */
602	if (!priv->adapter->cur_cmd) {
603		cmdbuf = priv->upld_buf;
604		priv->adapter->hisregcpy &= ~his_cmdupldrdy;
605	} else
606		cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;
607
608	cardp->usb_int_cause |= his_cmdupldrdy;
609	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
610	memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN,
611	       priv->upld_len);
612
613	kfree_skb(skb);
614	libertas_interrupt(priv->dev);
615	spin_unlock(&priv->adapter->driver_lock);
616
617	lbs_deb_usbd(&cardp->udev->dev,
618		    "Wake up main thread to handle cmd response\n");
619
620	return;
621}
622
623/**
624 *  @brief This function reads of the packet into the upload buff,
625 *  wake up the main thread and initialise the Rx callack.
626 *
627 *  @param urb		pointer to struct urb
628 *  @return 	   	N/A
629 */
630static void if_usb_receive(struct urb *urb)
631{
632	struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
633	wlan_private *priv = rinfo->priv;
634	struct sk_buff *skb = rinfo->skb;
635	struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
636
637	int recvlength = urb->actual_length;
638	u8 *recvbuff = NULL;
639	u32 recvtype;
640
641	lbs_deb_enter(LBS_DEB_USB);
642
643	if (recvlength) {
644		if (urb->status) {
645			lbs_deb_usbd(&cardp->udev->dev,
646				    "URB status is failed\n");
647			kfree_skb(skb);
648			goto setup_for_next;
649		}
650
651		recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
652		memcpy(&recvtype, recvbuff, sizeof(u32));
653		lbs_deb_usbd(&cardp->udev->dev,
654			    "Recv length = 0x%x\n", recvlength);
655		lbs_deb_usbd(&cardp->udev->dev,
656			    "Receive type = 0x%X\n", recvtype);
657		recvtype = le32_to_cpu(recvtype);
658		lbs_deb_usbd(&cardp->udev->dev,
659			    "Receive type after = 0x%X\n", recvtype);
660	} else if (urb->status)
661		goto rx_exit;
662
663
664	switch (recvtype) {
665	case CMD_TYPE_DATA:
666		process_cmdtypedata(recvlength, skb, cardp, priv);
667		break;
668
669	case CMD_TYPE_REQUEST:
670		process_cmdrequest(recvlength, recvbuff, skb, cardp, priv);
671		break;
672
673	case CMD_TYPE_INDICATION:
674		/* Event cause handling */
675		spin_lock(&priv->adapter->driver_lock);
676		cardp->usb_event_cause = *(u32 *) (recvbuff + MESSAGE_HEADER_LEN);
677		lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n",
678			    cardp->usb_event_cause);
679		if (cardp->usb_event_cause & 0xffff0000) {
680			libertas_send_tx_feedback(priv);
681			spin_unlock(&priv->adapter->driver_lock);
682			break;
683		}
684		cardp->usb_event_cause = le32_to_cpu(cardp->usb_event_cause) << 3;
685		cardp->usb_int_cause |= his_cardevent;
686		kfree_skb(skb);
687		libertas_interrupt(priv->dev);
688		spin_unlock(&priv->adapter->driver_lock);
689		goto rx_exit;
690	default:
691		kfree_skb(skb);
692		break;
693	}
694
695setup_for_next:
696	if_usb_submit_rx_urb(priv);
697rx_exit:
698	lbs_deb_leave(LBS_DEB_USB);
699}
700
701/**
702 *  @brief This function downloads data to FW
703 *  @param priv		pointer to wlan_private structure
704 *  @param type		type of data
705 *  @param buf		pointer to data buffer
706 *  @param len		number of bytes
707 *  @return 	   	0 or -1
708 */
709static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb)
710{
711	int ret = -1;
712	u32 tmp;
713	struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
714
715	lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
716	lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
717
718	if (type == MVMS_CMD) {
719		tmp = cpu_to_le32(CMD_TYPE_REQUEST);
720		priv->dnld_sent = DNLD_CMD_SENT;
721		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
722		       MESSAGE_HEADER_LEN);
723
724	} else {
725		tmp = cpu_to_le32(CMD_TYPE_DATA);
726		priv->dnld_sent = DNLD_DATA_SENT;
727		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
728		       MESSAGE_HEADER_LEN);
729	}
730
731	memcpy((cardp->bulk_out_buffer + MESSAGE_HEADER_LEN), payload, nb);
732
733	ret =
734	    usb_tx_block(priv, cardp->bulk_out_buffer, nb + MESSAGE_HEADER_LEN);
735
736	return ret;
737}
738
739/* called with adapter->driver_lock held */
740static int if_usb_get_int_status(wlan_private * priv, u8 * ireg)
741{
742	struct usb_card_rec *cardp = priv->card;
743
744	*ireg = cardp->usb_int_cause;
745	cardp->usb_int_cause = 0;
746
747	lbs_deb_usbd(&cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
748
749	return 0;
750}
751
752static int if_usb_read_event_cause(wlan_private * priv)
753{
754	struct usb_card_rec *cardp = priv->card;
755	priv->adapter->eventcause = cardp->usb_event_cause;
756	/* Re-submit rx urb here to avoid event lost issue */
757	if_usb_submit_rx_urb(priv);
758	return 0;
759}
760
761static int if_usb_reset_device(wlan_private *priv)
762{
763	int ret;
764
765	lbs_deb_enter(LBS_DEB_USB);
766	ret = libertas_prepare_and_send_command(priv, cmd_802_11_reset,
767				    cmd_act_halt, 0, 0, NULL);
768	msleep_interruptible(10);
769
770	lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
771	return ret;
772}
773
774static int if_usb_unregister_dev(wlan_private * priv)
775{
776	int ret = 0;
777
778	/* Need to send a Reset command to device before USB resources freed
779	 * and wlan_remove_card() called, then device can handle FW download
780	 * again.
781	 */
782	if (priv)
783		if_usb_reset_device(priv);
784
785	return ret;
786}
787
788
789/**
790 *  @brief  This function register usb device and initialize parameter
791 *  @param		priv pointer to wlan_private
792 *  @return		0 or -1
793 */
794static int if_usb_register_dev(wlan_private * priv)
795{
796	struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
797
798	lbs_deb_enter(LBS_DEB_USB);
799
800	cardp->priv = priv;
801	cardp->eth_dev = priv->dev;
802	priv->hotplug_device = &(cardp->udev->dev);
803
804	lbs_deb_usbd(&cardp->udev->dev, "udev pointer is at %p\n",
805		    cardp->udev);
806
807	lbs_deb_leave(LBS_DEB_USB);
808	return 0;
809}
810
811
812
813static int if_usb_prog_firmware(wlan_private * priv)
814{
815	struct usb_card_rec *cardp = priv->card;
816	int i = 0;
817	static int reset_count = 10;
818	int ret = 0;
819
820	lbs_deb_enter(LBS_DEB_USB);
821
822	cardp->rinfo.priv = priv;
823
824restart:
825	if (if_usb_submit_rx_urb_fwload(priv) < 0) {
826		lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
827		ret = -1;
828		goto done;
829	}
830
831	cardp->bootcmdresp = 0;
832	do {
833		int j = 0;
834		i++;
835		/* Issue Boot command = 1, Boot from Download-FW */
836		if_usb_issue_boot_command(priv, BOOT_CMD_FW_BY_USB);
837		/* wait for command response */
838		do {
839			j++;
840			msleep_interruptible(100);
841		} while (cardp->bootcmdresp == 0 && j < 10);
842	} while (cardp->bootcmdresp == 0 && i < 5);
843
844	if (cardp->bootcmdresp == 0) {
845		if (--reset_count >= 0) {
846			libertas_do_reset(priv);
847			goto restart;
848		}
849		return -1;
850	}
851
852	i = 0;
853	priv->adapter->fw_ready = 0;
854
855	cardp->totalbytes = 0;
856	cardp->fwlastblksent = 0;
857	cardp->CRC_OK = 1;
858	cardp->fwdnldover = 0;
859	cardp->fwseqnum = -1;
860	cardp->totalbytes = 0;
861	cardp->fwfinalblk = 0;
862
863	if_prog_firmware(priv);
864
865	do {
866		lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n");
867		i++;
868		msleep_interruptible(100);
869		if (priv->adapter->surpriseremoved || i >= 20)
870			break;
871	} while (!cardp->fwdnldover);
872
873	if (!cardp->fwdnldover) {
874		lbs_pr_info("failed to load fw, resetting device!\n");
875		if (--reset_count >= 0) {
876			libertas_do_reset(priv);
877			goto restart;
878		}
879
880		lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
881		ret = -1;
882		goto done;
883	}
884
885	if_usb_submit_rx_urb(priv);
886
887	/* Delay 200 ms to waiting for the FW ready */
888	msleep_interruptible(200);
889
890	priv->adapter->fw_ready = 1;
891
892done:
893	lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
894	return ret;
895}
896
897#ifdef CONFIG_PM
898static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
899{
900	struct usb_card_rec *cardp = usb_get_intfdata(intf);
901	wlan_private *priv = cardp->priv;
902
903	lbs_deb_enter(LBS_DEB_USB);
904
905	if (priv->adapter->psstate != PS_STATE_FULL_POWER)
906		return -1;
907
908	netif_device_detach(cardp->eth_dev);
909	netif_device_detach(priv->mesh_dev);
910
911	/* Unlink tx & rx urb */
912	usb_kill_urb(cardp->tx_urb);
913	usb_kill_urb(cardp->rx_urb);
914
915	cardp->rx_urb_recall = 1;
916
917	lbs_deb_leave(LBS_DEB_USB);
918	return 0;
919}
920
921static int if_usb_resume(struct usb_interface *intf)
922{
923	struct usb_card_rec *cardp = usb_get_intfdata(intf);
924	wlan_private *priv = cardp->priv;
925
926	lbs_deb_enter(LBS_DEB_USB);
927
928	cardp->rx_urb_recall = 0;
929
930	if_usb_submit_rx_urb(cardp->priv);
931
932	netif_device_attach(cardp->eth_dev);
933	netif_device_attach(priv->mesh_dev);
934
935	lbs_deb_leave(LBS_DEB_USB);
936	return 0;
937}
938#else
939#define if_usb_suspend NULL
940#define if_usb_resume NULL
941#endif
942
943static struct usb_driver if_usb_driver = {
944	/* driver name */
945	.name = usbdriver_name,
946	/* probe function name */
947	.probe = if_usb_probe,
948	/* disconnect function  name */
949	.disconnect = if_usb_disconnect,
950	/* device signature table */
951	.id_table = if_usb_table,
952	.suspend = if_usb_suspend,
953	.resume = if_usb_resume,
954};
955
956static int if_usb_init_module(void)
957{
958	int ret = 0;
959
960	lbs_deb_enter(LBS_DEB_MAIN);
961
962	if (libertas_fw_name == NULL) {
963		libertas_fw_name = default_fw_name;
964	}
965
966	ret = usb_register(&if_usb_driver);
967
968	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
969	return ret;
970}
971
972static void if_usb_exit_module(void)
973{
974	struct list_head *ptr;
975	struct usb_card_rec *cardp;
976
977	lbs_deb_enter(LBS_DEB_MAIN);
978
979	list_for_each(ptr, &usb_devices) {
980		cardp = list_entry(ptr, struct usb_card_rec, list);
981		if_usb_reset_device((wlan_private *) cardp->priv);
982	}
983
984	/* API unregisters the driver from USB subsystem */
985	usb_deregister(&if_usb_driver);
986
987	lbs_deb_leave(LBS_DEB_MAIN);
988}
989
990module_init(if_usb_init_module);
991module_exit(if_usb_exit_module);
992
993MODULE_DESCRIPTION("8388 USB WLAN Driver");
994MODULE_AUTHOR("Marvell International Ltd.");
995MODULE_LICENSE("GPL");
996