if_usb.c 25.7 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
#include "host.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
16
#include "cmd.h"
17 18 19 20
#include "if_usb.h"

#define MESSAGE_HEADER_LEN	4

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

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

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

	/* handle the transmission complete validations */

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

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

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

	return;
}

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

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

102
	lbs_deb_leave(LBS_DEB_USB);
103 104
}

105 106 107 108 109
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 已提交
110
	b2_cmd.version = priv->boot2_version;
111

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

116
static void if_usb_fw_timeo(unsigned long priv)
117 118
{
	struct usb_card_rec *cardp = (void *)priv;
119

120 121 122 123 124 125 126 127
	if (cardp->fwdnldover) {
		lbs_deb_usb("Download complete, no event. Assuming success\n");
	} else {
		lbs_pr_err("Download timed out\n");
		cardp->surprise_removed = 1;
	}
	wake_up(&cardp->fw_wq);
}
128 129 130 131 132 133 134 135 136 137 138 139
/**
 *  @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;
140
	struct lbs_private *priv;
141
	struct usb_card_rec *cardp;
142 143 144 145
	int i;

	udev = interface_to_usbdev(intf);

146 147
	cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
	if (!cardp) {
148 149 150 151
		lbs_pr_err("Out of memory allocating private data.\n");
		goto error;
	}

152 153 154
	setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
	init_waitqueue_head(&cardp->fw_wq);
								     
155
	cardp->udev = udev;
156 157
	iface_desc = intf->cur_altsetting;

158
	lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
159
	       " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
160 161 162 163
		     le16_to_cpu(udev->descriptor.bcdUSB),
		     udev->descriptor.bDeviceClass,
		     udev->descriptor.bDeviceSubClass,
		     udev->descriptor.bDeviceProtocol);
164 165 166 167 168 169 170

	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 */
171
			lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n",
172 173
				     le16_to_cpu(endpoint->wMaxPacketSize));
			if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
174
				lbs_deb_usbd(&udev->dev,
175 176 177
				       "Rx URB allocation failed\n");
				goto dealloc;
			}
178
			cardp->bulk_in_size =
179
				le16_to_cpu(endpoint->wMaxPacketSize);
180
			cardp->bulk_in_endpointAddr =
181 182
			    (endpoint->
			     bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
183
			lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n",
184 185 186 187 188 189 190 191 192
			       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 */
193
			if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
194
				lbs_deb_usbd(&udev->dev,
195 196 197 198
				       "Tx URB allocation failed\n");
				goto dealloc;
			}

199
			cardp->bulk_out_size =
200
				le16_to_cpu(endpoint->wMaxPacketSize);
201
			lbs_deb_usbd(&udev->dev,
202 203
				     "Bulk out size is %d\n",
				     le16_to_cpu(endpoint->wMaxPacketSize));
204
			cardp->bulk_out_endpointAddr =
205
			    endpoint->bEndpointAddress;
206
			lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n",
207
				    endpoint->bEndpointAddress);
208
			cardp->bulk_out_buffer =
209 210 211
			    kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE,
				    GFP_KERNEL);

212
			if (!cardp->bulk_out_buffer) {
213
				lbs_deb_usbd(&udev->dev,
214 215 216 217 218 219
				       "Could not allocate buffer\n");
				goto dealloc;
			}
		}
	}

220 221 222
	/* Upload firmware */
	cardp->rinfo.cardp = cardp;
	if (if_usb_prog_firmware(cardp)) {
223
		lbs_deb_usbd(&udev->dev, "FW upload failed\n");
224 225 226
		goto err_prog_firmware;
	}

227
	if (!(priv = lbs_add_card(cardp, &udev->dev)))
228
		goto err_prog_firmware;
229

230
	cardp->priv = priv;
231
	cardp->priv->fw_ready = 1;
232

233 234 235
	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 已提交
236
	priv->boot2_version = udev->descriptor.bcdDevice;
237

238 239
	if_usb_submit_rx_urb(cardp);

240
	if (lbs_start_card(priv))
241
		goto err_start_card;
242

243
	if_usb_set_boot2_ver(priv);
244

245 246 247
	priv->wol_gpio = 2; /* Wake via GPIO2... */
	priv->wol_gap = 20; /* ... after 20ms    */
	lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);
248

249
	usb_get_dev(udev);
250
	usb_set_intfdata(intf, cardp);
251 252 253

	return 0;

254
err_start_card:
255
	lbs_remove_card(priv);
256 257
err_prog_firmware:
	if_usb_reset_device(cardp);
258
dealloc:
259
	if_usb_free(cardp);
260 261 262 263 264 265 266

error:
	return -ENOMEM;
}

/**
 *  @brief free resource and cleanup
267
 *  @param intf		USB interface structure
268 269 270 271 272
 *  @return 	   	N/A
 */
static void if_usb_disconnect(struct usb_interface *intf)
{
	struct usb_card_rec *cardp = usb_get_intfdata(intf);
273
	struct lbs_private *priv = (struct lbs_private *) cardp->priv;
274

275
	lbs_deb_enter(LBS_DEB_MAIN);
276

277 278
	/* Update Surprise removed to TRUE */
	cardp->surprise_removed = 1;
279

280
	if (priv) {
281
		priv->surpriseremoved = 1;
282 283
		lbs_stop_card(priv);
		lbs_remove_card(priv);
284
	}
285 286 287 288 289 290 291

	/* Unlink and free urb */
	if_usb_free(cardp);

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

292
	lbs_deb_leave(LBS_DEB_MAIN);
293 294 295 296
}

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

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

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

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

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

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

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

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

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

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

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

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

	kfree(fwdata);

	return 0;
}

377
static int if_usb_reset_device(struct usb_card_rec *cardp)
378
{
379
	struct cmd_ds_command *cmd = (void *)&cardp->bulk_out_buffer[4];
380 381
	int ret;

382 383
	lbs_deb_enter(LBS_DEB_USB);

384 385 386 387 388 389 390 391 392
	*(__le32 *)cardp->bulk_out_buffer = cpu_to_le32(CMD_TYPE_REQUEST);

	cmd->command = cpu_to_le16(CMD_802_11_RESET);
	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN);
	cmd->result = cpu_to_le16(0);
	cmd->seqnum = cpu_to_le16(0x5a5a);
	cmd->params.reset.action = cpu_to_le16(CMD_ACT_HALT);
	usb_tx_block(cardp, cardp->bulk_out_buffer, 4 + S_DS_GEN + sizeof(struct cmd_ds_802_11_reset));

393
	msleep(100);
394
	ret = usb_reset_device(cardp->udev);
395
	msleep(100);
396 397 398

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

399 400 401 402 403
	return ret;
}

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

	/* check if device is removed */
414
	if (cardp->surprise_removed) {
415
		lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
416 417 418 419 420 421
		goto tx_ret;
	}

	usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
			  usb_sndbulkpipe(cardp->udev,
					  cardp->bulk_out_endpointAddr),
422
			  payload, nb, if_usb_write_bulk_callback, cardp);
423 424 425 426 427

	cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;

	if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
		/*  transfer failed */
428
		lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
429 430
		ret = -1;
	} else {
431
		/* lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb success\n"); */
432 433 434 435 436 437 438
		ret = 0;
	}

tx_ret:
	return ret;
}

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

	cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;

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

rx_ret:
	return ret;
}

479
static int if_usb_submit_rx_urb_fwload(struct usb_card_rec *cardp)
480
{
481
	return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
482 483
}

484
static int if_usb_submit_rx_urb(struct usb_card_rec *cardp)
485
{
486
	return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
487 488 489 490 491 492
}

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;
493
	struct usb_card_rec *cardp = (struct usb_card_rec *)rinfo->cardp;
494 495 496 497
	struct fwsyncheader *syncfwheader;
	struct bootcmdrespStr bootcmdresp;

	if (urb->status) {
498
		lbs_deb_usbd(&cardp->udev->dev,
499 500 501 502 503
			    "URB status is failed during fw load\n");
		kfree_skb(skb);
		return;
	}

504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
	if (cardp->fwdnldover) {
		__le32 *tmp = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);

		if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
		    tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
			lbs_pr_info("Firmware ready event received\n");
			wake_up(&cardp->fw_wq);
		} else {
			lbs_deb_usb("Waiting for confirmation; got %x %x\n", le32_to_cpu(tmp[0]),
				    le32_to_cpu(tmp[1]));
			if_usb_submit_rx_urb_fwload(cardp);
		}
		kfree_skb(skb);
		return;
	}
519
	if (cardp->bootcmdresp <= 0) {
520 521
		memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
			sizeof(bootcmdresp));
522
		if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
523
			kfree_skb(skb);
524
			if_usb_submit_rx_urb_fwload(cardp);
525
			cardp->bootcmdresp = 1;
526
			lbs_deb_usbd(&cardp->udev->dev,
527 528 529
				    "Received valid boot command response\n");
			return;
		}
530
		if (bootcmdresp.u32magicnumber != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
531 532 533
			if (bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_REQUEST) ||
			    bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_DATA) ||
			    bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_INDICATION)) {
534 535
				if (!cardp->bootcmdresp)
					lbs_pr_info("Firmware already seems alive; resetting\n");
536 537 538 539 540
				cardp->bootcmdresp = -1;
			} else {
				lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
					    le32_to_cpu(bootcmdresp.u32magicnumber));
			}
541 542 543 544 545 546 547 548 549 550
		} 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;
551
			lbs_deb_usbd(&cardp->udev->dev,
552 553 554
				    "Received valid boot command response\n");
		}
		kfree_skb(skb);
555
		if_usb_submit_rx_urb_fwload(cardp);
556 557 558 559 560
		return;
	}

	syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC);
	if (!syncfwheader) {
561
		lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
562 563 564 565 566 567 568 569
		kfree_skb(skb);
		return;
	}

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

	if (!syncfwheader->cmd) {
570 571
		/*
		lbs_deb_usbd(&cardp->udev->dev,
572
			    "FW received Blk with correct CRC\n");
573
		lbs_deb_usbd(&cardp->udev->dev,
574 575
			    "FW received Blk seqnum = %d\n",
		       syncfwheader->seqnum);
576
		*/
577 578
		cardp->CRC_OK = 1;
	} else {
579
		lbs_deb_usbd(&cardp->udev->dev,
580 581 582 583 584 585
			    "FW received Blk with CRC error\n");
		cardp->CRC_OK = 0;
	}

	kfree_skb(skb);

586 587 588
	/* reschedule timer for 200ms hence */
	mod_timer(&cardp->fw_timeout, jiffies + (HZ/5));

589 590 591 592 593
	if (cardp->fwfinalblk) {
		cardp->fwdnldover = 1;
		goto exit;
	}

594
	if_usb_send_fw_pkt(cardp);
595

596
 exit:
597 598
	if_usb_submit_rx_urb_fwload(cardp);

599 600 601 602 603 604 605 606 607
	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,
608
				       struct lbs_private *priv)
609 610 611
{
	if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE +
	    MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) {
612
		lbs_deb_usbd(&cardp->udev->dev,
613 614 615 616 617 618 619 620
			    "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);
621
	lbs_process_rxed_packet(priv, skb);
622
	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
623 624 625 626 627
}

static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
				      struct sk_buff *skb,
				      struct usb_card_rec *cardp,
628
				      struct lbs_private *priv)
629 630
{
	u8 *cmdbuf;
631
	if (recvlength > LBS_CMD_BUFFER_SIZE) {
632
		lbs_deb_usbd(&cardp->udev->dev,
633 634 635 636 637 638 639 640
			    "The receive buffer is too large\n");
		kfree_skb(skb);
		return;
	}

	if (!in_interrupt())
		BUG();

641
	spin_lock(&priv->driver_lock);
642 643
	/* take care of cur_cmd = NULL case by reading the
	 * data to clear the interrupt */
644
	if (!priv->cur_cmd) {
645
		lbs_deb_hex(LBS_DEB_HOST, "Unsolicited CMD_RESP", (void *) recvbuff + MESSAGE_HEADER_LEN, priv->upld_len);
646
		cmdbuf = priv->upld_buf;
647
		priv->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
648
	} else
649
		cmdbuf = (u8 *) priv->cur_cmd->cmdbuf;
650

651
	cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY;
652
	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
653
	memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN,
654
	       priv->upld_len);
655 656

	kfree_skb(skb);
657
	lbs_interrupt(priv);
658
	spin_unlock(&priv->driver_lock);
659

660
	lbs_deb_usbd(&cardp->udev->dev,
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
		    "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;
677
	struct usb_card_rec *cardp = (struct usb_card_rec *) rinfo->cardp;
678
	struct lbs_private *priv = cardp->priv;
679 680 681

	int recvlength = urb->actual_length;
	u8 *recvbuff = NULL;
682
	u32 recvtype = 0;
683

684
	lbs_deb_enter(LBS_DEB_USB);
685 686

	if (recvlength) {
687 688
		__le32 tmp;

689
		if (urb->status) {
690
			lbs_deb_usbd(&cardp->udev->dev,
691 692 693 694 695 696
				    "URB status is failed\n");
			kfree_skb(skb);
			goto setup_for_next;
		}

		recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
697 698
		memcpy(&tmp, recvbuff, sizeof(u32));
		recvtype = le32_to_cpu(tmp);
699
		lbs_deb_usbd(&cardp->udev->dev,
700 701
			    "Recv length = 0x%x, Recv type = 0x%X\n",
			    recvlength, recvtype);
702 703
	} else if (urb->status) {
		kfree_skb(skb);
704
		goto rx_exit;
705
	}
706 707 708 709 710 711 712 713 714 715 716 717

	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 */
718
		spin_lock(&priv->driver_lock);
719
		cardp->usb_event_cause = le32_to_cpu(*(__le32 *) (recvbuff + MESSAGE_HEADER_LEN));
720
		lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n",
721 722
			    cardp->usb_event_cause);
		if (cardp->usb_event_cause & 0xffff0000) {
723
			lbs_send_tx_feedback(priv);
724
			spin_unlock(&priv->driver_lock);
725 726
			break;
		}
727
		cardp->usb_event_cause <<= 3;
728
		cardp->usb_int_cause |= MRVDRV_CARDEVENT;
729
		kfree_skb(skb);
730
		lbs_interrupt(priv);
731
		spin_unlock(&priv->driver_lock);
732 733
		goto rx_exit;
	default:
734 735
		lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n",
		             recvtype);
736 737 738 739 740
		kfree_skb(skb);
		break;
	}

setup_for_next:
741
	if_usb_submit_rx_urb(cardp);
742
rx_exit:
743
	lbs_deb_leave(LBS_DEB_USB);
744 745 746 747
}

/**
 *  @brief This function downloads data to FW
748
 *  @param priv		pointer to struct lbs_private structure
749 750 751 752 753
 *  @param type		type of data
 *  @param buf		pointer to data buffer
 *  @param len		number of bytes
 *  @return 	   	0 or -1
 */
754 755 756 757
static int if_usb_host_to_card(struct lbs_private *priv,
	u8 type,
	u8 *payload,
	u16 nb)
758
{
759
	struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
760

761 762
	lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
	lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
763 764

	if (type == MVMS_CMD) {
765
		__le32 tmp = cpu_to_le32(CMD_TYPE_REQUEST);
766
		priv->dnld_sent = DNLD_CMD_SENT;
767 768 769 770
		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
		       MESSAGE_HEADER_LEN);

	} else {
771
		__le32 tmp = cpu_to_le32(CMD_TYPE_DATA);
772
		priv->dnld_sent = DNLD_DATA_SENT;
773 774 775 776 777 778
		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
		       MESSAGE_HEADER_LEN);
	}

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

779
	return usb_tx_block(cardp, cardp->bulk_out_buffer,
780
	                    nb + MESSAGE_HEADER_LEN);
781 782
}

783
/* called with priv->driver_lock held */
784
static int if_usb_get_int_status(struct lbs_private *priv, u8 *ireg)
785
{
786
	struct usb_card_rec *cardp = priv->card;
787 788 789 790

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

791
	lbs_deb_usbd(&cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
792 793 794 795

	return 0;
}

796
static int if_usb_read_event_cause(struct lbs_private *priv)
797
{
798
	struct usb_card_rec *cardp = priv->card;
799

800
	priv->eventcause = cardp->usb_event_cause;
801
	/* Re-submit rx urb here to avoid event lost issue */
802
	if_usb_submit_rx_urb(cardp);
803 804 805
	return 0;
}

806 807 808 809 810 811
/**
 *  @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
 */
812
static int if_usb_issue_boot_command(struct usb_card_rec *cardp, int ivalue)
813
{
814
	struct bootcmdstr sbootcmd;
815 816 817 818 819 820 821 822 823 824
	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 */
825
	usb_tx_block(cardp, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
826 827 828

	return 0;
}
829 830


831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879
/**
 *  @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)
880 881 882
{
	int i = 0;
	static int reset_count = 10;
883
	int ret = 0;
884

885
	lbs_deb_enter(LBS_DEB_USB);
886

887
	if ((ret = request_firmware(&cardp->fw, lbs_fw_name,
888 889
				    &cardp->udev->dev)) < 0) {
		lbs_pr_err("request_firmware() failed with %#x\n", ret);
890
		lbs_pr_err("firmware %s not found\n", lbs_fw_name);
891 892 893 894 895
		goto done;
	}

	if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
		goto release_fw;
896 897

restart:
898
	if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
899 900
		lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
		ret = -1;
901
		goto release_fw;
902 903 904 905 906 907 908
	}

	cardp->bootcmdresp = 0;
	do {
		int j = 0;
		i++;
		/* Issue Boot command = 1, Boot from Download-FW */
909
		if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
910 911 912 913 914 915 916
		/* wait for command response */
		do {
			j++;
			msleep_interruptible(100);
		} while (cardp->bootcmdresp == 0 && j < 10);
	} while (cardp->bootcmdresp == 0 && i < 5);

917
	if (cardp->bootcmdresp <= 0) {
918
		if (--reset_count >= 0) {
919
			if_usb_reset_device(cardp);
920 921 922 923 924 925 926 927 928 929 930 931 932 933 934
			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;

935 936
	/* Send the first firmware packet... */
	if_usb_send_fw_pkt(cardp);
937

938 939 940 941
	/* ... and wait for the process to complete */
	wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
	
	del_timer_sync(&cardp->fw_timeout);
942
	usb_kill_urb(cardp->rx_urb);
943 944 945 946

	if (!cardp->fwdnldover) {
		lbs_pr_info("failed to load fw, resetting device!\n");
		if (--reset_count >= 0) {
947
			if_usb_reset_device(cardp);
948 949 950 951
			goto restart;
		}

		lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
952
		ret = -1;
953
		goto release_fw;
954 955
	}

956 957 958
release_fw:
	release_firmware(cardp->fw);
	cardp->fw = NULL;
959

960 961 962
done:
	lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
	return ret;
963 964
}

H
Holger Schurig 已提交
965

966 967 968 969
#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);
970
	struct lbs_private *priv = cardp->priv;
971
	int ret;
972

973
	lbs_deb_enter(LBS_DEB_USB);
974

975
	if (priv->psstate != PS_STATE_FULL_POWER)
976 977
		return -1;

978 979 980
	ret = lbs_suspend(priv);
	if (ret)
		goto out;
981 982 983 984 985

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

986
 out:
987
	lbs_deb_leave(LBS_DEB_USB);
988
	return ret;
989 990 991 992 993
}

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

996
	lbs_deb_enter(LBS_DEB_USB);
997

998
	if_usb_submit_rx_urb(cardp);
999

1000
	lbs_resume(priv);
1001

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

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

1019
static int __init if_usb_init_module(void)
1020
{
1021
	int ret = 0;
1022

1023 1024 1025 1026 1027 1028
	lbs_deb_enter(LBS_DEB_MAIN);

	ret = usb_register(&if_usb_driver);

	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
1029 1030
}

1031
static void __exit if_usb_exit_module(void)
1032
{
1033 1034
	lbs_deb_enter(LBS_DEB_MAIN);

1035
	usb_deregister(&if_usb_driver);
1036 1037

	lbs_deb_leave(LBS_DEB_MAIN);
1038
}
1039 1040 1041 1042 1043 1044 1045

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