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 38 39 40
static int if_usb_host_to_card(struct lbs_private *priv,
	u8 type,
	u8 *payload,
	u16 nb);
static int if_usb_get_int_status(struct lbs_private *priv, u8 *);
static int if_usb_read_event_cause(struct lbs_private *);
41
static int usb_tx_block(struct usb_card_rec *cardp, u8 *payload, u16 nb);
42
static void if_usb_free(struct usb_card_rec *cardp);
43 44
static int if_usb_submit_rx_urb(struct usb_card_rec *cardp);
static int if_usb_reset_device(struct usb_card_rec *cardp);
45 46 47 48 49 50 51 52

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

	/* handle the transmission complete validations */

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

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

		/* Used for both firmware TX and regular TX.  priv isn't
		 * valid at firmware load time.
		 */
69 70
		if (priv)
			lbs_host_to_card_done(priv);
71 72 73
	} else {
		/* print the failure status number for debug */
		lbs_pr_info("URB in failure status: %d\n", urb->status);
74 75 76 77 78 79 80 81 82 83
	}

	return;
}

/**
 *  @brief  free tx/rx urb, skb and rx buffer
 *  @param cardp	pointer usb_card_rec
 *  @return 	   	N/A
 */
84
static void if_usb_free(struct usb_card_rec *cardp)
85
{
86
	lbs_deb_enter(LBS_DEB_USB);
87 88 89 90 91 92 93 94 95 96 97 98 99 100

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

101
	lbs_deb_leave(LBS_DEB_USB);
102 103
}

104 105 106 107 108
static void if_usb_set_boot2_ver(struct lbs_private *priv)
{
	struct cmd_ds_set_boot2_ver b2_cmd;

	b2_cmd.action = 0;
H
Holger Schurig 已提交
109
	b2_cmd.version = priv->boot2_version;
110

111
	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, &b2_cmd, sizeof(b2_cmd), NULL))
112 113 114 115
		lbs_deb_usb("Setting boot2 version failed\n");
}


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
	struct 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;
H
Holger Schurig 已提交
227
	priv->boot2_version = udev->descriptor.bcdDevice;
228

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

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

237
	if_usb_set_boot2_ver(priv);
238

239
	usb_get_dev(udev);
240
	usb_set_intfdata(intf, cardp);
241 242 243

	return 0;

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

error:
	return -ENOMEM;
}

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

267
	lbs_deb_enter(LBS_DEB_MAIN);
268

269 270
	/* Update Surprise removed to TRUE */
	cardp->surprise_removed = 1;
271

272 273
	if (priv) {

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

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

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

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

290
	lbs_deb_leave(LBS_DEB_MAIN);
291 292 293 294
}

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

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

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

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

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

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

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

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

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

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

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

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

	kfree(fwdata);

	return 0;
}

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

380 381
	lbs_deb_enter(LBS_DEB_USB);

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

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

394 395 396 397 398
	return ret;
}

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

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

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

	cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;

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

tx_ret:
	return ret;
}

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

	cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;

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

rx_ret:
	return ret;
}

474
static int if_usb_submit_rx_urb_fwload(struct usb_card_rec *cardp)
475
{
476
	return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
477 478
}

479
static int if_usb_submit_rx_urb(struct usb_card_rec *cardp)
480
{
481
	return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
482 483 484 485 486 487
}

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;
488
	struct usb_card_rec *cardp = (struct usb_card_rec *)rinfo->cardp;
489 490 491 492
	struct fwsyncheader *syncfwheader;
	struct bootcmdrespStr bootcmdresp;

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

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

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

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

	kfree_skb(skb);

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

564
	if_prog_firmware(cardp);
565

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

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

	if (!in_interrupt())
		BUG();

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

620
	cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY;
621
	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
622
	memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN,
623
	       priv->upld_len);
624 625

	kfree_skb(skb);
626
	lbs_interrupt(priv->dev);
627
	spin_unlock(&priv->driver_lock);
628

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

	int recvlength = urb->actual_length;
	u8 *recvbuff = NULL;
651
	u32 recvtype = 0;
652

653
	lbs_deb_enter(LBS_DEB_USB);
654 655

	if (recvlength) {
656 657
		__le32 tmp;

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

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

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

setup_for_next:
710
	if_usb_submit_rx_urb(cardp);
711
rx_exit:
712
	lbs_deb_leave(LBS_DEB_USB);
713 714 715 716
}

/**
 *  @brief This function downloads data to FW
717
 *  @param priv		pointer to struct lbs_private structure
718 719 720 721 722
 *  @param type		type of data
 *  @param buf		pointer to data buffer
 *  @param len		number of bytes
 *  @return 	   	0 or -1
 */
723 724 725 726
static int if_usb_host_to_card(struct lbs_private *priv,
	u8 type,
	u8 *payload,
	u16 nb)
727
{
728
	struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
729

730 731
	lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
	lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
732 733

	if (type == MVMS_CMD) {
734
		__le32 tmp = cpu_to_le32(CMD_TYPE_REQUEST);
735
		priv->dnld_sent = DNLD_CMD_SENT;
736 737 738 739
		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
		       MESSAGE_HEADER_LEN);

	} else {
740
		__le32 tmp = cpu_to_le32(CMD_TYPE_DATA);
741
		priv->dnld_sent = DNLD_DATA_SENT;
742 743 744 745 746 747
		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
		       MESSAGE_HEADER_LEN);
	}

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

748
	return usb_tx_block(cardp, cardp->bulk_out_buffer,
749
	                    nb + MESSAGE_HEADER_LEN);
750 751
}

752
/* called with priv->driver_lock held */
753
static int if_usb_get_int_status(struct lbs_private *priv, u8 *ireg)
754
{
755
	struct usb_card_rec *cardp = priv->card;
756 757 758 759

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

760
	lbs_deb_usbd(&cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
761 762 763 764

	return 0;
}

765
static int if_usb_read_event_cause(struct lbs_private *priv)
766
{
767
	struct usb_card_rec *cardp = priv->card;
768

769
	priv->eventcause = cardp->usb_event_cause;
770
	/* Re-submit rx urb here to avoid event lost issue */
771
	if_usb_submit_rx_urb(cardp);
772 773 774
	return 0;
}

775 776 777 778 779 780
/**
 *  @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
 */
781
static int if_usb_issue_boot_command(struct usb_card_rec *cardp, int ivalue)
782
{
783
	struct bootcmdstr sbootcmd;
784 785 786 787 788 789 790 791 792 793
	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 */
794
	usb_tx_block(cardp, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
795 796 797

	return 0;
}
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 841 842 843 844 845 846 847 848
/**
 *  @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)
849 850 851
{
	int i = 0;
	static int reset_count = 10;
852
	int ret = 0;
853

854
	lbs_deb_enter(LBS_DEB_USB);
855

856
	if ((ret = request_firmware(&cardp->fw, lbs_fw_name,
857 858
				    &cardp->udev->dev)) < 0) {
		lbs_pr_err("request_firmware() failed with %#x\n", ret);
859
		lbs_pr_err("firmware %s not found\n", lbs_fw_name);
860 861 862 863 864
		goto done;
	}

	if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
		goto release_fw;
865 866

restart:
867
	if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
868 869
		lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
		ret = -1;
870
		goto release_fw;
871 872 873 874 875 876 877
	}

	cardp->bootcmdresp = 0;
	do {
		int j = 0;
		i++;
		/* Issue Boot command = 1, Boot from Download-FW */
878
		if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
879 880 881 882 883 884 885 886 887
		/* 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) {
888
			if_usb_reset_device(cardp);
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
			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;

904
	if_prog_firmware(cardp);
905 906

	do {
907
		lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n");
908 909
		i++;
		msleep_interruptible(100);
910
		if (cardp->surprise_removed || i >= 20)
911 912 913 914 915 916
			break;
	} while (!cardp->fwdnldover);

	if (!cardp->fwdnldover) {
		lbs_pr_info("failed to load fw, resetting device!\n");
		if (--reset_count >= 0) {
917
			if_usb_reset_device(cardp);
918 919 920 921
			goto restart;
		}

		lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
922
		ret = -1;
923
		goto release_fw;
924 925
	}

926 927 928
release_fw:
	release_firmware(cardp->fw);
	cardp->fw = NULL;
929

930 931 932
done:
	lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
	return ret;
933 934
}

H
Holger Schurig 已提交
935

936 937 938 939
#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);
940
	struct lbs_private *priv = cardp->priv;
941

942
	lbs_deb_enter(LBS_DEB_USB);
943

944
	if (priv->psstate != PS_STATE_FULL_POWER)
945 946
		return -1;

947 948 949 950 951 952 953
	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);
954
		lbs_prepare_and_send_command(priv,
955 956 957 958 959
				CMD_MESH_ACCESS,
				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
				CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
	}

960
	netif_device_detach(cardp->eth_dev);
961
	netif_device_detach(priv->mesh_dev);
962 963 964 965 966 967 968

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

	cardp->rx_urb_recall = 1;

969
	lbs_deb_leave(LBS_DEB_USB);
970 971 972 973 974 975
	return 0;
}

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

978
	lbs_deb_enter(LBS_DEB_USB);
979 980 981 982 983 984

	cardp->rx_urb_recall = 0;

	if_usb_submit_rx_urb(cardp->priv);

	netif_device_attach(cardp->eth_dev);
985
	netif_device_attach(priv->mesh_dev);
986

987 988 989 990 991 992 993
	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);
994
		lbs_prepare_and_send_command(priv,
995 996 997 998 999
				CMD_MESH_ACCESS,
				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
				CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
	}

1000
	lbs_deb_leave(LBS_DEB_USB);
1001 1002 1003 1004 1005 1006 1007 1008
	return 0;
}
#else
#define if_usb_suspend NULL
#define if_usb_resume NULL
#endif

static struct usb_driver if_usb_driver = {
1009
	.name = DRV_NAME,
1010 1011 1012 1013 1014 1015 1016
	.probe = if_usb_probe,
	.disconnect = if_usb_disconnect,
	.id_table = if_usb_table,
	.suspend = if_usb_suspend,
	.resume = if_usb_resume,
};

1017
static int __init if_usb_init_module(void)
1018
{
1019
	int ret = 0;
1020

1021 1022 1023 1024 1025 1026
	lbs_deb_enter(LBS_DEB_MAIN);

	ret = usb_register(&if_usb_driver);

	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
1027 1028
}

1029
static void __exit if_usb_exit_module(void)
1030
{
1031 1032
	lbs_deb_enter(LBS_DEB_MAIN);

1033
	usb_deregister(&if_usb_driver);
1034 1035

	lbs_deb_leave(LBS_DEB_MAIN);
1036
}
1037 1038 1039 1040 1041 1042 1043

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