if_usb.c 25.3 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 20
#include "host.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
#include "if_usb.h"

#define MESSAGE_HEADER_LEN	4

static const char usbdriver_name[] = "usb8xxx";
21

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

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

/**
 *  @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)
{
52
	struct usb_card_rec *cardp = (struct usb_card_rec *) urb->context;
53 54 55

	/* handle the transmission complete validations */

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

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

		/* Used for both firmware TX and regular TX.  priv isn't
		 * valid at firmware load time.
		 */
		if (priv) {
69
			lbs_adapter *adapter = priv->adapter;
70 71 72 73 74 75 76 77
			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);

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

	return;
}

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

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

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

/**
 *  @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;
128
	lbs_private *priv;
129
	struct usb_card_rec *cardp;
130 131 132 133
	int i;

	udev = interface_to_usbdev(intf);

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

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

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

	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 */
156
			lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n",
157 158
				     le16_to_cpu(endpoint->wMaxPacketSize));
			if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
159
				lbs_deb_usbd(&udev->dev,
160 161 162
				       "Rx URB allocation failed\n");
				goto dealloc;
			}
163
			cardp->rx_urb_recall = 0;
164

165
			cardp->bulk_in_size =
166
				le16_to_cpu(endpoint->wMaxPacketSize);
167
			cardp->bulk_in_endpointAddr =
168 169
			    (endpoint->
			     bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
170
			lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n",
171 172 173 174 175 176 177 178 179
			       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 */
180
			if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
181
				lbs_deb_usbd(&udev->dev,
182 183 184 185
				       "Tx URB allocation failed\n");
				goto dealloc;
			}

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

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

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

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

217
	cardp->priv = priv;
218

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

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

224 225 226
	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;
227
	priv->boot2_version = udev->descriptor.bcdDevice;
228

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

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

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

	return 0;

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

error:
	return -ENOMEM;
}

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

265
	lbs_deb_enter(LBS_DEB_MAIN);
266

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

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

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

279 280 281 282
	/* 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);

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

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

289
	lbs_deb_leave(LBS_DEB_MAIN);
290 291 292 293
}

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

	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;
	}

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

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

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

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

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

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

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

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

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

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

	kfree(fwdata);

	return 0;
}

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

379 380
	lbs_deb_enter(LBS_DEB_USB);

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

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

393 394 395 396 397
	return ret;
}

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

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

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

	cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;

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

tx_ret:
	return ret;
}

433 434
static int __if_usb_submit_rx_urb(struct usb_card_rec *cardp,
				  void (*callbackfn)(struct urb *urb))
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
{
	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 已提交
451
			  (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
452 453 454 455 456
			  MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
			  rinfo);

	cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;

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

rx_ret:
	return ret;
}

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

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

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;
485
	struct usb_card_rec *cardp = (struct usb_card_rec *)rinfo->cardp;
486 487 488 489
	struct fwsyncheader *syncfwheader;
	struct bootcmdrespStr bootcmdresp;

	if (urb->status) {
490
		lbs_deb_usbd(&cardp->udev->dev,
491 492 493 494 495 496 497 498
			    "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));
499
		if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
500
			kfree_skb(skb);
501
			if_usb_submit_rx_urb_fwload(cardp);
502
			cardp->bootcmdresp = 1;
503
			lbs_deb_usbd(&cardp->udev->dev,
504 505 506
				    "Received valid boot command response\n");
			return;
		}
507
		if (bootcmdresp.u32magicnumber != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
508 509
			lbs_pr_info(
				"boot cmd response wrong magic number (0x%x)\n",
510
				le32_to_cpu(bootcmdresp.u32magicnumber));
511 512 513 514 515 516 517 518 519 520
		} 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;
521
			lbs_deb_usbd(&cardp->udev->dev,
522 523 524
				    "Received valid boot command response\n");
		}
		kfree_skb(skb);
525
		if_usb_submit_rx_urb_fwload(cardp);
526 527 528 529 530
		return;
	}

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

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

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

	kfree_skb(skb);

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

561
	if_prog_firmware(cardp);
562

563
	if_usb_submit_rx_urb_fwload(cardp);
564 565 566 567 568 569 570 571 572 573 574
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,
575
				       lbs_private *priv)
576 577 578
{
	if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE +
	    MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) {
579
		lbs_deb_usbd(&cardp->udev->dev,
580 581 582 583 584 585 586 587
			    "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);
588
	lbs_process_rxed_packet(priv, skb);
589
	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
590 591 592 593 594
}

static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
				      struct sk_buff *skb,
				      struct usb_card_rec *cardp,
595
				      lbs_private *priv)
596 597 598
{
	u8 *cmdbuf;
	if (recvlength > MRVDRV_SIZE_OF_CMD_BUFFER) {
599
		lbs_deb_usbd(&cardp->udev->dev,
600 601 602 603 604 605 606 607 608 609 610 611
			    "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) {
612
		cmdbuf = priv->upld_buf;
613
		priv->adapter->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
614 615 616
	} else
		cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;

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

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

626
	lbs_deb_usbd(&cardp->udev->dev,
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
		    "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;
643
	struct usb_card_rec *cardp = (struct usb_card_rec *) rinfo->cardp;
644
	lbs_private * priv = cardp->priv;
645 646 647

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

650
	lbs_deb_enter(LBS_DEB_USB);
651 652

	if (recvlength) {
653 654
		__le32 tmp;

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

		recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
663 664
		memcpy(&tmp, recvbuff, sizeof(u32));
		recvtype = le32_to_cpu(tmp);
665
		lbs_deb_usbd(&cardp->udev->dev,
666 667
			    "Recv length = 0x%x, Recv type = 0x%X\n",
			    recvlength, recvtype);
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
	} 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);
683
		cardp->usb_event_cause = le32_to_cpu(*(__le32 *) (recvbuff + MESSAGE_HEADER_LEN));
684
		lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n",
685 686
			    cardp->usb_event_cause);
		if (cardp->usb_event_cause & 0xffff0000) {
687
			lbs_send_tx_feedback(priv);
688
			spin_unlock(&priv->adapter->driver_lock);
689 690
			break;
		}
691
		cardp->usb_event_cause <<= 3;
692
		cardp->usb_int_cause |= MRVDRV_CARDEVENT;
693
		kfree_skb(skb);
694
		lbs_interrupt(priv->dev);
695 696 697
		spin_unlock(&priv->adapter->driver_lock);
		goto rx_exit;
	default:
698 699
		lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n",
		             recvtype);
700 701 702 703 704
		kfree_skb(skb);
		break;
	}

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

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

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

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

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

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

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

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

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

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

	return 0;
}

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

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

767 768 769 770 771 772
/**
 *  @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
 */
773
static int if_usb_issue_boot_command(struct usb_card_rec *cardp, int ivalue)
774
{
775
	struct bootcmdstr sbootcmd;
776 777 778 779 780 781 782 783 784 785
	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 */
786
	usb_tx_block(cardp, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
787 788 789

	return 0;
}
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 840
/**
 *  @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)
841 842 843
{
	int i = 0;
	static int reset_count = 10;
844
	int ret = 0;
845

846
	lbs_deb_enter(LBS_DEB_USB);
847

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

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

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

	cardp->bootcmdresp = 0;
	do {
		int j = 0;
		i++;
		/* Issue Boot command = 1, Boot from Download-FW */
870
		if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
871 872 873 874 875 876 877 878 879
		/* 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) {
880
			if_usb_reset_device(cardp);
881 882 883 884 885 886 887 888 889 890 891 892 893 894 895
			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;

896
	if_prog_firmware(cardp);
897 898

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

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

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

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

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

H
Holger Schurig 已提交
927

928 929 930 931
#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);
932
	lbs_private *priv = cardp->priv;
933

934
	lbs_deb_enter(LBS_DEB_USB);
935 936 937 938

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

939 940 941 942 943 944 945
	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);
946
		lbs_prepare_and_send_command(priv,
947 948 949 950 951
				CMD_MESH_ACCESS,
				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
				CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
	}

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

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

	cardp->rx_urb_recall = 1;

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

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

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

	cardp->rx_urb_recall = 0;

	if_usb_submit_rx_urb(cardp->priv);

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

979 980 981 982 983 984 985
	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);
986
		lbs_prepare_and_send_command(priv,
987 988 989 990 991
				CMD_MESH_ACCESS,
				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
				CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
	}

992
	lbs_deb_leave(LBS_DEB_USB);
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
	return 0;
}
#else
#define if_usb_suspend NULL
#define if_usb_resume NULL
#endif

static struct usb_driver if_usb_driver = {
	/* driver name */
	.name = usbdriver_name,
	/* probe function name */
	.probe = if_usb_probe,
	/* disconnect function  name */
	.disconnect = if_usb_disconnect,
	/* device signature table */
	.id_table = if_usb_table,
	.suspend = if_usb_suspend,
	.resume = if_usb_resume,
};

1013
static int __init if_usb_init_module(void)
1014
{
1015
	int ret = 0;
1016

1017 1018 1019 1020 1021 1022
	lbs_deb_enter(LBS_DEB_MAIN);

	ret = usb_register(&if_usb_driver);

	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
1023 1024
}

1025
static void __exit if_usb_exit_module(void)
1026
{
1027 1028
	lbs_deb_enter(LBS_DEB_MAIN);

1029
	usb_deregister(&if_usb_driver);
1030 1031

	lbs_deb_leave(LBS_DEB_MAIN);
1032
}
1033 1034 1035 1036 1037 1038 1039

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");