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