diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-12-11 13:15:25 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:06:44 -0500 |
commit | c9cd6f9d630c4422d5f7eb8018b28846e25dba20 (patch) | |
tree | 852abbf20de397a6667221b255b99164c982a53d /drivers/net/wireless | |
parent | 10bca0d5f4829a8acd9a7a51cb7b35e38b23280a (diff) |
libertas: wait for 'firmware ready' event from firmware after loading
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/libertas/host.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/if_usb.c | 26 |
2 files changed, 22 insertions, 5 deletions
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index 4828bbf6639..b23af194b42 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h | |||
@@ -304,5 +304,6 @@ enum cmd_mesh_access_opts { | |||
304 | #define MACREG_INT_CODE_RSSI_HIGH 28 | 304 | #define MACREG_INT_CODE_RSSI_HIGH 28 |
305 | #define MACREG_INT_CODE_SNR_HIGH 29 | 305 | #define MACREG_INT_CODE_SNR_HIGH 29 |
306 | #define MACREG_INT_CODE_MESH_AUTO_STARTED 35 | 306 | #define MACREG_INT_CODE_MESH_AUTO_STARTED 35 |
307 | #define MACREG_INT_CODE_FIRMWARE_READY 48 | ||
307 | 308 | ||
308 | #endif | 309 | #endif |
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 6cd6c962937..c94b6dfa20f 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c | |||
@@ -230,6 +230,7 @@ static int if_usb_probe(struct usb_interface *intf, | |||
230 | goto err_prog_firmware; | 230 | goto err_prog_firmware; |
231 | 231 | ||
232 | cardp->priv = priv; | 232 | cardp->priv = priv; |
233 | cardp->priv->fw_ready = 1; | ||
233 | 234 | ||
234 | if (lbs_add_mesh(priv, &udev->dev)) | 235 | if (lbs_add_mesh(priv, &udev->dev)) |
235 | goto err_add_mesh; | 236 | goto err_add_mesh; |
@@ -241,10 +242,7 @@ static int if_usb_probe(struct usb_interface *intf, | |||
241 | priv->hw_read_event_cause = if_usb_read_event_cause; | 242 | priv->hw_read_event_cause = if_usb_read_event_cause; |
242 | priv->boot2_version = udev->descriptor.bcdDevice; | 243 | priv->boot2_version = udev->descriptor.bcdDevice; |
243 | 244 | ||
244 | /* Delay 200 ms to waiting for the FW ready */ | ||
245 | if_usb_submit_rx_urb(cardp); | 245 | if_usb_submit_rx_urb(cardp); |
246 | msleep_interruptible(200); | ||
247 | priv->fw_ready = 1; | ||
248 | 246 | ||
249 | if (lbs_start_card(priv)) | 247 | if (lbs_start_card(priv)) |
250 | goto err_start_card; | 248 | goto err_start_card; |
@@ -514,6 +512,21 @@ static void if_usb_receive_fwload(struct urb *urb) | |||
514 | return; | 512 | return; |
515 | } | 513 | } |
516 | 514 | ||
515 | if (cardp->fwdnldover) { | ||
516 | __le32 *tmp = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET); | ||
517 | |||
518 | if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) && | ||
519 | tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) { | ||
520 | lbs_pr_info("Firmware ready event received\n"); | ||
521 | wake_up(&cardp->fw_wq); | ||
522 | } else { | ||
523 | lbs_deb_usb("Waiting for confirmation; got %x %x\n", le32_to_cpu(tmp[0]), | ||
524 | le32_to_cpu(tmp[1])); | ||
525 | if_usb_submit_rx_urb_fwload(cardp); | ||
526 | } | ||
527 | kfree_skb(skb); | ||
528 | return; | ||
529 | } | ||
517 | if (cardp->bootcmdresp <= 0) { | 530 | if (cardp->bootcmdresp <= 0) { |
518 | memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET, | 531 | memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET, |
519 | sizeof(bootcmdresp)); | 532 | sizeof(bootcmdresp)); |
@@ -529,7 +542,8 @@ static void if_usb_receive_fwload(struct urb *urb) | |||
529 | if (bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_REQUEST) || | 542 | if (bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_REQUEST) || |
530 | bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_DATA) || | 543 | bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_DATA) || |
531 | bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_INDICATION)) { | 544 | bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_INDICATION)) { |
532 | lbs_pr_info("Firmware already seems alive; resetting\n"); | 545 | if (!cardp->bootcmdresp) |
546 | lbs_pr_info("Firmware already seems alive; resetting\n"); | ||
533 | cardp->bootcmdresp = -1; | 547 | cardp->bootcmdresp = -1; |
534 | } else { | 548 | } else { |
535 | lbs_pr_info("boot cmd response wrong magic number (0x%x)\n", | 549 | lbs_pr_info("boot cmd response wrong magic number (0x%x)\n", |
@@ -590,8 +604,9 @@ static void if_usb_receive_fwload(struct urb *urb) | |||
590 | 604 | ||
591 | if_usb_send_fw_pkt(cardp); | 605 | if_usb_send_fw_pkt(cardp); |
592 | 606 | ||
593 | if_usb_submit_rx_urb_fwload(cardp); | ||
594 | exit: | 607 | exit: |
608 | if_usb_submit_rx_urb_fwload(cardp); | ||
609 | |||
595 | kfree(syncfwheader); | 610 | kfree(syncfwheader); |
596 | 611 | ||
597 | return; | 612 | return; |
@@ -934,6 +949,7 @@ restart: | |||
934 | wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover); | 949 | wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover); |
935 | 950 | ||
936 | del_timer_sync(&cardp->fw_timeout); | 951 | del_timer_sync(&cardp->fw_timeout); |
952 | usb_kill_urb(cardp->rx_urb); | ||
937 | 953 | ||
938 | if (!cardp->fwdnldover) { | 954 | if (!cardp->fwdnldover) { |
939 | lbs_pr_info("failed to load fw, resetting device!\n"); | 955 | lbs_pr_info("failed to load fw, resetting device!\n"); |