if_usb.c 25.2 KB
Newer Older
1 2 3 4
/**
  * This file contains functions used in USB interface module.
  */
#include <linux/delay.h>
5
#include <linux/moduleparam.h>
6 7 8 9
#include <linux/firmware.h>
#include <linux/netdevice.h>
#include <linux/usb.h>

10 11
#define DRV_NAME "usb8xxx"

12 13 14 15 16 17 18 19
#include "host.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
#include "if_usb.h"

#define MESSAGE_HEADER_LEN	4

20
static char *lbs_fw_name = "usb8388.bin";
21
module_param_named(fw_name, lbs_fw_name, charp, 0644);
22

23 24
static struct usb_device_id if_usb_table[] = {
	/* Enter the device signature inside */
25 26
	{ USB_DEVICE(0x1286, 0x2001) },
	{ USB_DEVICE(0x05a3, 0x8388) },
27 28 29 30 31 32 33
	{}	/* 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);
34
static int if_usb_prog_firmware(struct usb_card_rec *cardp);
35 36 37
static int if_usb_host_to_card(lbs_private *priv, u8 type, u8 *payload, u16 nb);
static int if_usb_get_int_status(lbs_private *priv, u8 *);
static int if_usb_read_event_cause(lbs_private *);
38
static int usb_tx_block(struct usb_card_rec *cardp, u8 *payload, u16 nb);
39
static void if_usb_free(struct usb_card_rec *cardp);
40 41
static int if_usb_submit_rx_urb(struct usb_card_rec *cardp);
static int if_usb_reset_device(struct usb_card_rec *cardp);
42 43 44 45 46 47 48 49

/**
 *  @brief  call back function to handle the status of the URB
 *  @param urb 		pointer to urb structure
 *  @return 	   	N/A
 */
static void if_usb_write_bulk_callback(struct urb *urb)
{
50
	struct usb_card_rec *cardp = (struct usb_card_rec *) urb->context;
51 52 53

	/* handle the transmission complete validations */

54
	if (urb->status == 0) {
55
		lbs_private *priv = cardp->priv;
56

57 58 59
		/*
		lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n");
		lbs_deb_usbd(&urb->dev->dev, "Actual length transmitted %d\n",
60
		       urb->actual_length);
61
		*/
62 63 64 65 66

		/* Used for both firmware TX and regular TX.  priv isn't
		 * valid at firmware load time.
		 */
		if (priv) {
67
			lbs_adapter *adapter = priv->adapter;
68 69 70 71 72 73 74 75
			struct net_device *dev = priv->dev;

			priv->dnld_sent = DNLD_RES_RECEIVED;

			/* Wake main thread if commands are pending */
			if (!adapter->cur_cmd)
				wake_up_interruptible(&priv->waitq);

76
			if (adapter->connect_status == LBS_CONNECTED)
77
				netif_wake_queue(dev);
78 79

			if (priv->mesh_dev && (adapter->mesh_connect_status == LBS_CONNECTED))
80
				netif_wake_queue(priv->mesh_dev);
81
		}
82 83 84
	} else {
		/* print the failure status number for debug */
		lbs_pr_info("URB in failure status: %d\n", urb->status);
85 86 87 88 89 90 91 92 93 94
	}

	return;
}

/**
 *  @brief  free tx/rx urb, skb and rx buffer
 *  @param cardp	pointer usb_card_rec
 *  @return 	   	N/A
 */
95
static void if_usb_free(struct usb_card_rec *cardp)
96
{
97
	lbs_deb_enter(LBS_DEB_USB);
98 99 100 101 102 103 104 105 106 107 108 109 110 111

	/* 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;

	kfree(cardp->bulk_out_buffer);
	cardp->bulk_out_buffer = NULL;

112
	lbs_deb_leave(LBS_DEB_USB);
113 114 115 116 117 118 119 120 121 122 123 124 125 126
}

/**
 *  @brief sets the configuration values
 *  @param ifnum	interface number
 *  @param id		pointer to usb_device_id
 *  @return 	   	0 on success, error code on failure
 */
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;
127
	lbs_private *priv;
128
	struct usb_card_rec *cardp;
129 130 131 132
	int i;

	udev = interface_to_usbdev(intf);

133 134
	cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
	if (!cardp) {
135 136 137 138
		lbs_pr_err("Out of memory allocating private data.\n");
		goto error;
	}

139
	cardp->udev = udev;
140 141
	iface_desc = intf->cur_altsetting;

142
	lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
143
	       " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
144 145 146 147
		     le16_to_cpu(udev->descriptor.bcdUSB),
		     udev->descriptor.bDeviceClass,
		     udev->descriptor.bDeviceSubClass,
		     udev->descriptor.bDeviceProtocol);
148 149 150 151 152 153 154

	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;
		if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
		    && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
			USB_ENDPOINT_XFER_BULK)) {
			/* we found a bulk in endpoint */
155
			lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n",
156 157
				     le16_to_cpu(endpoint->wMaxPacketSize));
			if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
158
				lbs_deb_usbd(&udev->dev,
159 160 161
				       "Rx URB allocation failed\n");
				goto dealloc;
			}
162
			cardp->rx_urb_recall = 0;
163

164
			cardp->bulk_in_size =
165
				le16_to_cpu(endpoint->wMaxPacketSize);
166
			cardp->bulk_in_endpointAddr =
167 168
			    (endpoint->
			     bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
169
			lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n",
170 171 172 173 174 175 176 177 178
			       endpoint->bEndpointAddress);
		}

		if (((endpoint->
		      bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
		     USB_DIR_OUT)
		    && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
			USB_ENDPOINT_XFER_BULK)) {
			/* We found bulk out endpoint */
179
			if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
180
				lbs_deb_usbd(&udev->dev,
181 182 183 184
				       "Tx URB allocation failed\n");
				goto dealloc;
			}

185
			cardp->bulk_out_size =
186
				le16_to_cpu(endpoint->wMaxPacketSize);
187
			lbs_deb_usbd(&udev->dev,
188 189
				     "Bulk out size is %d\n",
				     le16_to_cpu(endpoint->wMaxPacketSize));
190
			cardp->bulk_out_endpointAddr =
191
			    endpoint->bEndpointAddress;
192
			lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n",
193
				    endpoint->bEndpointAddress);
194
			cardp->bulk_out_buffer =
195 196 197
			    kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE,
				    GFP_KERNEL);

198
			if (!cardp->bulk_out_buffer) {
199
				lbs_deb_usbd(&udev->dev,
200 201 202 203 204 205
				       "Could not allocate buffer\n");
				goto dealloc;
			}
		}
	}

206 207 208 209 210 211 212
	/* Upload firmware */
	cardp->rinfo.cardp = cardp;
	if (if_usb_prog_firmware(cardp)) {
		lbs_deb_usbd(&udev->dev, "FW upload failed");
		goto err_prog_firmware;
	}

213
	if (!(priv = lbs_add_card(cardp, &udev->dev)))
214
		goto err_prog_firmware;
215

216
	cardp->priv = priv;
217

218
	if (lbs_add_mesh(priv, &udev->dev))
219
		goto err_add_mesh;
220

221 222
	cardp->eth_dev = priv->dev;

223 224 225
	priv->hw_host_to_card = if_usb_host_to_card;
	priv->hw_get_int_status = if_usb_get_int_status;
	priv->hw_read_event_cause = if_usb_read_event_cause;
226
	priv->boot2_version = udev->descriptor.bcdDevice;
227

228 229 230 231 232
	/* Delay 200 ms to waiting for the FW ready */
	if_usb_submit_rx_urb(cardp);
	msleep_interruptible(200);
	priv->adapter->fw_ready = 1;

233
	if (lbs_start_card(priv))
234
		goto err_start_card;
235

236
	usb_get_dev(udev);
237
	usb_set_intfdata(intf, cardp);
238 239 240

	return 0;

241
err_start_card:
242
	lbs_remove_mesh(priv);
243
err_add_mesh:
244
	lbs_remove_card(priv);
245 246
err_prog_firmware:
	if_usb_reset_device(cardp);
247
dealloc:
248
	if_usb_free(cardp);
249 250 251 252 253 254 255

error:
	return -ENOMEM;
}

/**
 *  @brief free resource and cleanup
256
 *  @param intf		USB interface structure
257 258 259 260 261
 *  @return 	   	N/A
 */
static void if_usb_disconnect(struct usb_interface *intf)
{
	struct usb_card_rec *cardp = usb_get_intfdata(intf);
262
	lbs_private *priv = (lbs_private *) cardp->priv;
263

264
	lbs_deb_enter(LBS_DEB_MAIN);
265

266 267
	/* Update Surprise removed to TRUE */
	cardp->surprise_removed = 1;
268

269
	if (priv) {
270
		lbs_adapter *adapter = priv->adapter;
271 272

		adapter->surpriseremoved = 1;
273 274 275
		lbs_stop_card(priv);
		lbs_remove_mesh(priv);
		lbs_remove_card(priv);
276
	}
277

278 279 280 281
	/* this is (apparently?) necessary for future usage of the device */
	lbs_prepare_and_send_command(priv, CMD_802_11_RESET, CMD_ACT_HALT,
			0, 0, NULL);

282 283 284 285 286 287
	/* Unlink and free urb */
	if_usb_free(cardp);

	usb_set_intfdata(intf, NULL);
	usb_put_dev(interface_to_usbdev(intf));

288
	lbs_deb_leave(LBS_DEB_MAIN);
289 290 291 292
}

/**
 *  @brief  This function download FW
293
 *  @param priv		pointer to lbs_private
294 295
 *  @return 	   	0
 */
296
static int if_prog_firmware(struct usb_card_rec *cardp)
297 298 299
{
	struct FWData *fwdata;
	struct fwheader *fwheader;
300
	u8 *firmware = cardp->fw->data;
301 302 303 304 305 306 307 308 309 310 311 312 313

	fwdata = kmalloc(sizeof(struct FWData), GFP_ATOMIC);

	if (!fwdata)
		return -1;

	fwheader = &fwdata->fwheader;

	if (!cardp->CRC_OK) {
		cardp->totalbytes = cardp->fwlastblksent;
		cardp->fwseqnum = cardp->lastseqnum - 1;
	}

314 315
	/*
	lbs_deb_usbd(&cardp->udev->dev, "totalbytes = %d\n",
316
		    cardp->totalbytes);
317
	*/
318 319 320 321 322 323 324

	memcpy(fwheader, &firmware[cardp->totalbytes],
	       sizeof(struct fwheader));

	cardp->fwlastblksent = cardp->totalbytes;
	cardp->totalbytes += sizeof(struct fwheader);

325
	/* lbs_deb_usbd(&cardp->udev->dev,"Copy Data\n"); */
326
	memcpy(fwdata->data, &firmware[cardp->totalbytes],
327
	       le32_to_cpu(fwdata->fwheader.datalength));
328

329 330
	/*
	lbs_deb_usbd(&cardp->udev->dev,
331
		    "Data length = %d\n", le32_to_cpu(fwdata->fwheader.datalength));
332
	*/
333 334 335

	cardp->fwseqnum = cardp->fwseqnum + 1;

336 337 338
	fwdata->seqnum = cpu_to_le32(cardp->fwseqnum);
	cardp->lastseqnum = cardp->fwseqnum;
	cardp->totalbytes += le32_to_cpu(fwdata->fwheader.datalength);
339

340
	if (fwheader->dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
341
		/*
342
		lbs_deb_usbd(&cardp->udev->dev, "There are data to follow\n");
343
		lbs_deb_usbd(&cardp->udev->dev,
344 345
			    "seqnum = %d totalbytes = %d\n", cardp->fwseqnum,
			    cardp->totalbytes);
346
		*/
347
		memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
348
		usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
349

350
	} else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
351 352
		/*
		lbs_deb_usbd(&cardp->udev->dev,
353
			    "Host has finished FW downloading\n");
354
		lbs_deb_usbd(&cardp->udev->dev,
355
			    "Donwloading FW JUMP BLOCK\n");
356
		*/
357
		memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
358
		usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
359 360 361
		cardp->fwfinalblk = 1;
	}

362 363
	/*
	lbs_deb_usbd(&cardp->udev->dev,
364 365
		    "The firmware download is done size is %d\n",
		    cardp->totalbytes);
366
	*/
367 368 369 370 371 372

	kfree(fwdata);

	return 0;
}

373
static int if_usb_reset_device(struct usb_card_rec *cardp)
374 375
{
	int ret;
376
	lbs_private * priv = cardp->priv;
377

378 379
	lbs_deb_enter(LBS_DEB_USB);

380 381 382
	/* Try a USB port reset first, if that fails send the reset
	 * command to the firmware.
	 */
383
	ret = usb_reset_device(cardp->udev);
384
	if (!ret && priv) {
385
		msleep(10);
386
		ret = lbs_reset_device(priv);
387 388
		msleep(10);
	}
389 390 391

	lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);

392 393 394 395 396
	return ret;
}

/**
 *  @brief This function transfer the data to the device.
397
 *  @param priv 	pointer to lbs_private
398 399 400 401
 *  @param payload	pointer to payload data
 *  @param nb		data length
 *  @return 	   	0 or -1
 */
402
static int usb_tx_block(struct usb_card_rec *cardp, u8 * payload, u16 nb)
403 404 405 406
{
	int ret = -1;

	/* check if device is removed */
407
	if (cardp->surprise_removed) {
408
		lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
409 410 411 412 413 414
		goto tx_ret;
	}

	usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
			  usb_sndbulkpipe(cardp->udev,
					  cardp->bulk_out_endpointAddr),
415
			  payload, nb, if_usb_write_bulk_callback, cardp);
416 417 418 419 420

	cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;

	if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
		/*  transfer failed */
421
		lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed\n");
422 423
		ret = -1;
	} else {
424
		/* lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb success\n"); */
425 426 427 428 429 430 431
		ret = 0;
	}

tx_ret:
	return ret;
}

432 433
static int __if_usb_submit_rx_urb(struct usb_card_rec *cardp,
				  void (*callbackfn)(struct urb *urb))
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
{
	struct sk_buff *skb;
	struct read_cb_info *rinfo = &cardp->rinfo;
	int ret = -1;

	if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
		lbs_pr_err("No free skb\n");
		goto rx_ret;
	}

	rinfo->skb = skb;

	/* Fill the receive configuration URB and initialise the Rx call back */
	usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
			  usb_rcvbulkpipe(cardp->udev,
					  cardp->bulk_in_endpointAddr),
D
Dan Williams 已提交
450
			  (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
451 452 453 454 455
			  MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
			  rinfo);

	cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;

456
	/* lbs_deb_usbd(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); */
457 458
	if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
		/* handle failure conditions */
459
		lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed\n");
460 461
		ret = -1;
	} else {
462
		/* lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB success\n"); */
463 464 465 466 467 468 469
		ret = 0;
	}

rx_ret:
	return ret;
}

470
static int if_usb_submit_rx_urb_fwload(struct usb_card_rec *cardp)
471
{
472
	return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
473 474
}

475
static int if_usb_submit_rx_urb(struct usb_card_rec *cardp)
476
{
477
	return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
478 479 480 481 482 483
}

static void if_usb_receive_fwload(struct urb *urb)
{
	struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
	struct sk_buff *skb = rinfo->skb;
484
	struct usb_card_rec *cardp = (struct usb_card_rec *)rinfo->cardp;
485 486 487 488
	struct fwsyncheader *syncfwheader;
	struct bootcmdrespStr bootcmdresp;

	if (urb->status) {
489
		lbs_deb_usbd(&cardp->udev->dev,
490 491 492 493 494 495 496 497
			    "URB status is failed during fw load\n");
		kfree_skb(skb);
		return;
	}

	if (cardp->bootcmdresp == 0) {
		memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
			sizeof(bootcmdresp));
498
		if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
499
			kfree_skb(skb);
500
			if_usb_submit_rx_urb_fwload(cardp);
501
			cardp->bootcmdresp = 1;
502
			lbs_deb_usbd(&cardp->udev->dev,
503 504 505
				    "Received valid boot command response\n");
			return;
		}
506
		if (bootcmdresp.u32magicnumber != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
507 508
			lbs_pr_info(
				"boot cmd response wrong magic number (0x%x)\n",
509
				le32_to_cpu(bootcmdresp.u32magicnumber));
510 511 512 513 514 515 516 517 518 519
		} else if (bootcmdresp.u8cmd_tag != BOOT_CMD_FW_BY_USB) {
			lbs_pr_info(
				"boot cmd response cmd_tag error (%d)\n",
				bootcmdresp.u8cmd_tag);
		} else if (bootcmdresp.u8result != BOOT_CMD_RESP_OK) {
			lbs_pr_info(
				"boot cmd response result error (%d)\n",
				bootcmdresp.u8result);
		} else {
			cardp->bootcmdresp = 1;
520
			lbs_deb_usbd(&cardp->udev->dev,
521 522 523
				    "Received valid boot command response\n");
		}
		kfree_skb(skb);
524
		if_usb_submit_rx_urb_fwload(cardp);
525 526 527 528 529
		return;
	}

	syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC);
	if (!syncfwheader) {
530
		lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
531 532 533 534 535 536 537 538
		kfree_skb(skb);
		return;
	}

	memcpy(syncfwheader, skb->data + IPFIELD_ALIGN_OFFSET,
			sizeof(struct fwsyncheader));

	if (!syncfwheader->cmd) {
539 540
		/*
		lbs_deb_usbd(&cardp->udev->dev,
541
			    "FW received Blk with correct CRC\n");
542
		lbs_deb_usbd(&cardp->udev->dev,
543 544
			    "FW received Blk seqnum = %d\n",
		       syncfwheader->seqnum);
545
		*/
546 547
		cardp->CRC_OK = 1;
	} else {
548
		lbs_deb_usbd(&cardp->udev->dev,
549 550 551 552 553 554 555 556 557 558 559
			    "FW received Blk with CRC error\n");
		cardp->CRC_OK = 0;
	}

	kfree_skb(skb);

	if (cardp->fwfinalblk) {
		cardp->fwdnldover = 1;
		goto exit;
	}

560
	if_prog_firmware(cardp);
561

562
	if_usb_submit_rx_urb_fwload(cardp);
563 564 565 566 567 568 569 570 571 572 573
exit:
	kfree(syncfwheader);

	return;

}

#define MRVDRV_MIN_PKT_LEN	30

static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
				       struct usb_card_rec *cardp,
574
				       lbs_private *priv)
575 576 577
{
	if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE +
	    MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) {
578
		lbs_deb_usbd(&cardp->udev->dev,
579 580 581 582 583 584 585 586
			    "Packet length is Invalid\n");
		kfree_skb(skb);
		return;
	}

	skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
	skb_put(skb, recvlength);
	skb_pull(skb, MESSAGE_HEADER_LEN);
587
	lbs_process_rxed_packet(priv, skb);
588
	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
589 590 591 592 593
}

static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
				      struct sk_buff *skb,
				      struct usb_card_rec *cardp,
594
				      lbs_private *priv)
595 596 597
{
	u8 *cmdbuf;
	if (recvlength > MRVDRV_SIZE_OF_CMD_BUFFER) {
598
		lbs_deb_usbd(&cardp->udev->dev,
599 600 601 602 603 604 605 606 607 608 609 610
			    "The receive buffer is too large\n");
		kfree_skb(skb);
		return;
	}

	if (!in_interrupt())
		BUG();

	spin_lock(&priv->adapter->driver_lock);
	/* take care of cur_cmd = NULL case by reading the
	 * data to clear the interrupt */
	if (!priv->adapter->cur_cmd) {
611
		cmdbuf = priv->upld_buf;
612
		priv->adapter->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
613 614 615
	} else
		cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;

616
	cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY;
617
	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
618
	memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN,
619
	       priv->upld_len);
620 621

	kfree_skb(skb);
622
	lbs_interrupt(priv->dev);
623 624
	spin_unlock(&priv->adapter->driver_lock);

625
	lbs_deb_usbd(&cardp->udev->dev,
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
		    "Wake up main thread to handle cmd response\n");

	return;
}

/**
 *  @brief This function reads of the packet into the upload buff,
 *  wake up the main thread and initialise the Rx callack.
 *
 *  @param urb		pointer to struct urb
 *  @return 	   	N/A
 */
static void if_usb_receive(struct urb *urb)
{
	struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
	struct sk_buff *skb = rinfo->skb;
642
	struct usb_card_rec *cardp = (struct usb_card_rec *) rinfo->cardp;
643
	lbs_private * priv = cardp->priv;
644 645 646

	int recvlength = urb->actual_length;
	u8 *recvbuff = NULL;
647
	u32 recvtype = 0;
648

649
	lbs_deb_enter(LBS_DEB_USB);
650 651

	if (recvlength) {
652 653
		__le32 tmp;

654
		if (urb->status) {
655
			lbs_deb_usbd(&cardp->udev->dev,
656 657 658 659 660 661
				    "URB status is failed\n");
			kfree_skb(skb);
			goto setup_for_next;
		}

		recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
662 663
		memcpy(&tmp, recvbuff, sizeof(u32));
		recvtype = le32_to_cpu(tmp);
664
		lbs_deb_usbd(&cardp->udev->dev,
665 666
			    "Recv length = 0x%x, Recv type = 0x%X\n",
			    recvlength, recvtype);
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
	} else if (urb->status)
		goto rx_exit;

	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:
		/* Event cause handling */
		spin_lock(&priv->adapter->driver_lock);
682
		cardp->usb_event_cause = le32_to_cpu(*(__le32 *) (recvbuff + MESSAGE_HEADER_LEN));
683
		lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n",
684 685
			    cardp->usb_event_cause);
		if (cardp->usb_event_cause & 0xffff0000) {
686
			lbs_send_tx_feedback(priv);
687
			spin_unlock(&priv->adapter->driver_lock);
688 689
			break;
		}
690
		cardp->usb_event_cause <<= 3;
691
		cardp->usb_int_cause |= MRVDRV_CARDEVENT;
692
		kfree_skb(skb);
693
		lbs_interrupt(priv->dev);
694 695 696
		spin_unlock(&priv->adapter->driver_lock);
		goto rx_exit;
	default:
697 698
		lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n",
		             recvtype);
699 700 701 702 703
		kfree_skb(skb);
		break;
	}

setup_for_next:
704
	if_usb_submit_rx_urb(cardp);
705
rx_exit:
706
	lbs_deb_leave(LBS_DEB_USB);
707 708 709 710
}

/**
 *  @brief This function downloads data to FW
711
 *  @param priv		pointer to lbs_private structure
712 713 714 715 716
 *  @param type		type of data
 *  @param buf		pointer to data buffer
 *  @param len		number of bytes
 *  @return 	   	0 or -1
 */
717
static int if_usb_host_to_card(lbs_private *priv, u8 type, u8 *payload, u16 nb)
718
{
719
	struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
720

721 722
	lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
	lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
723 724

	if (type == MVMS_CMD) {
725
		__le32 tmp = cpu_to_le32(CMD_TYPE_REQUEST);
726
		priv->dnld_sent = DNLD_CMD_SENT;
727 728 729 730
		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
		       MESSAGE_HEADER_LEN);

	} else {
731
		__le32 tmp = cpu_to_le32(CMD_TYPE_DATA);
732
		priv->dnld_sent = DNLD_DATA_SENT;
733 734 735 736 737 738
		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
		       MESSAGE_HEADER_LEN);
	}

	memcpy((cardp->bulk_out_buffer + MESSAGE_HEADER_LEN), payload, nb);

739
	return usb_tx_block(cardp, cardp->bulk_out_buffer,
740
	                    nb + MESSAGE_HEADER_LEN);
741 742 743
}

/* called with adapter->driver_lock held */
744
static int if_usb_get_int_status(lbs_private *priv, u8 *ireg)
745
{
746
	struct usb_card_rec *cardp = priv->card;
747 748 749 750

	*ireg = cardp->usb_int_cause;
	cardp->usb_int_cause = 0;

751
	lbs_deb_usbd(&cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
752 753 754 755

	return 0;
}

756
static int if_usb_read_event_cause(lbs_private * priv)
757
{
758
	struct usb_card_rec *cardp = priv->card;
759

760 761
	priv->adapter->eventcause = cardp->usb_event_cause;
	/* Re-submit rx urb here to avoid event lost issue */
762
	if_usb_submit_rx_urb(cardp);
763 764 765
	return 0;
}

766 767 768 769 770 771
/**
 *  @brief This function issues Boot command to the Boot2 code
 *  @param ivalue   1:Boot from FW by USB-Download
 *                  2:Boot from FW in EEPROM
 *  @return 	   	0
 */
772
static int if_usb_issue_boot_command(struct usb_card_rec *cardp, int ivalue)
773
{
774
	struct bootcmdstr sbootcmd;
775 776 777 778 779 780 781 782 783 784
	int i;

	/* Prepare command */
	sbootcmd.u32magicnumber = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
	sbootcmd.u8cmd_tag = ivalue;
	for (i=0; i<11; i++)
		sbootcmd.au8dumy[i]=0x00;
	memcpy(cardp->bulk_out_buffer, &sbootcmd, sizeof(struct bootcmdstr));

	/* Issue command */
785
	usb_tx_block(cardp, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
786 787 788

	return 0;
}
789 790


791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
/**
 *  @brief This function checks the validity of Boot2/FW image.
 *
 *  @param data              pointer to image
 *         len               image length
 *  @return     0 or -1
 */
static int check_fwfile_format(u8 *data, u32 totlen)
{
	u32 bincmd, exit;
	u32 blksize, offset, len;
	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)
		lbs_pr_err("firmware file format check FAIL\n");
	else
		lbs_deb_fw("firmware file format check PASS\n");

	return ret;
}


static int if_usb_prog_firmware(struct usb_card_rec *cardp)
840 841 842
{
	int i = 0;
	static int reset_count = 10;
843
	int ret = 0;
844

845
	lbs_deb_enter(LBS_DEB_USB);
846

847
	if ((ret = request_firmware(&cardp->fw, lbs_fw_name,
848 849
				    &cardp->udev->dev)) < 0) {
		lbs_pr_err("request_firmware() failed with %#x\n", ret);
850
		lbs_pr_err("firmware %s not found\n", lbs_fw_name);
851 852 853 854 855
		goto done;
	}

	if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
		goto release_fw;
856 857

restart:
858
	if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
859 860
		lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
		ret = -1;
861
		goto release_fw;
862 863 864 865 866 867 868
	}

	cardp->bootcmdresp = 0;
	do {
		int j = 0;
		i++;
		/* Issue Boot command = 1, Boot from Download-FW */
869
		if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
870 871 872 873 874 875 876 877 878
		/* wait for command response */
		do {
			j++;
			msleep_interruptible(100);
		} while (cardp->bootcmdresp == 0 && j < 10);
	} while (cardp->bootcmdresp == 0 && i < 5);

	if (cardp->bootcmdresp == 0) {
		if (--reset_count >= 0) {
879
			if_usb_reset_device(cardp);
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894
			goto restart;
		}
		return -1;
	}

	i = 0;

	cardp->totalbytes = 0;
	cardp->fwlastblksent = 0;
	cardp->CRC_OK = 1;
	cardp->fwdnldover = 0;
	cardp->fwseqnum = -1;
	cardp->totalbytes = 0;
	cardp->fwfinalblk = 0;

895
	if_prog_firmware(cardp);
896 897

	do {
898
		lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n");
899 900
		i++;
		msleep_interruptible(100);
901
		if (cardp->surprise_removed || i >= 20)
902 903 904 905 906 907
			break;
	} while (!cardp->fwdnldover);

	if (!cardp->fwdnldover) {
		lbs_pr_info("failed to load fw, resetting device!\n");
		if (--reset_count >= 0) {
908
			if_usb_reset_device(cardp);
909 910 911 912
			goto restart;
		}

		lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
913
		ret = -1;
914
		goto release_fw;
915 916
	}

917 918 919
release_fw:
	release_firmware(cardp->fw);
	cardp->fw = NULL;
920

921 922 923
done:
	lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
	return ret;
924 925
}

H
Holger Schurig 已提交
926

927 928 929 930
#ifdef CONFIG_PM
static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct usb_card_rec *cardp = usb_get_intfdata(intf);
931
	lbs_private *priv = cardp->priv;
932

933
	lbs_deb_enter(LBS_DEB_USB);
934 935 936 937

	if (priv->adapter->psstate != PS_STATE_FULL_POWER)
		return -1;

938 939 940 941 942 943 944
	if (priv->mesh_dev && !priv->mesh_autostart_enabled) {
		/* Mesh autostart must be activated while sleeping
		 * On resume it will go back to the current state
		 */
		struct cmd_ds_mesh_access mesh_access;
		memset(&mesh_access, 0, sizeof(mesh_access));
		mesh_access.data[0] = cpu_to_le32(1);
945
		lbs_prepare_and_send_command(priv,
946 947 948 949 950
				CMD_MESH_ACCESS,
				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
				CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
	}

951
	netif_device_detach(cardp->eth_dev);
952
	netif_device_detach(priv->mesh_dev);
953 954 955 956 957 958 959

	/* Unlink tx & rx urb */
	usb_kill_urb(cardp->tx_urb);
	usb_kill_urb(cardp->rx_urb);

	cardp->rx_urb_recall = 1;

960
	lbs_deb_leave(LBS_DEB_USB);
961 962 963 964 965 966
	return 0;
}

static int if_usb_resume(struct usb_interface *intf)
{
	struct usb_card_rec *cardp = usb_get_intfdata(intf);
967
	lbs_private *priv = cardp->priv;
968

969
	lbs_deb_enter(LBS_DEB_USB);
970 971 972 973 974 975

	cardp->rx_urb_recall = 0;

	if_usb_submit_rx_urb(cardp->priv);

	netif_device_attach(cardp->eth_dev);
976
	netif_device_attach(priv->mesh_dev);
977

978 979 980 981 982 983 984
	if (priv->mesh_dev && !priv->mesh_autostart_enabled) {
		/* Mesh autostart was activated while sleeping
		 * Disable it if appropriate
		 */
		struct cmd_ds_mesh_access mesh_access;
		memset(&mesh_access, 0, sizeof(mesh_access));
		mesh_access.data[0] = cpu_to_le32(0);
985
		lbs_prepare_and_send_command(priv,
986 987 988 989 990
				CMD_MESH_ACCESS,
				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
				CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
	}

991
	lbs_deb_leave(LBS_DEB_USB);
992 993 994 995 996 997 998 999
	return 0;
}
#else
#define if_usb_suspend NULL
#define if_usb_resume NULL
#endif

static struct usb_driver if_usb_driver = {
1000
	.name = DRV_NAME,
1001 1002 1003 1004 1005 1006 1007
	.probe = if_usb_probe,
	.disconnect = if_usb_disconnect,
	.id_table = if_usb_table,
	.suspend = if_usb_suspend,
	.resume = if_usb_resume,
};

1008
static int __init if_usb_init_module(void)
1009
{
1010
	int ret = 0;
1011

1012 1013 1014 1015 1016 1017
	lbs_deb_enter(LBS_DEB_MAIN);

	ret = usb_register(&if_usb_driver);

	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
1018 1019
}

1020
static void __exit if_usb_exit_module(void)
1021
{
1022 1023
	lbs_deb_enter(LBS_DEB_MAIN);

1024
	usb_deregister(&if_usb_driver);
1025 1026

	lbs_deb_leave(LBS_DEB_MAIN);
1027
}
1028 1029 1030 1031 1032 1033 1034

module_init(if_usb_init_module);
module_exit(if_usb_exit_module);

MODULE_DESCRIPTION("8388 USB WLAN Driver");
MODULE_AUTHOR("Marvell International Ltd.");
MODULE_LICENSE("GPL");