aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/if_usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/if_usb.c')
-rw-r--r--drivers/net/wireless/libertas/if_usb.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 0a3795048c2c..a086653803fe 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -113,7 +113,18 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv)
113 lbs_deb_usb("Setting boot2 version failed\n"); 113 lbs_deb_usb("Setting boot2 version failed\n");
114} 114}
115 115
116void if_usb_fw_timeo(unsigned long priv)
117{
118 struct usb_card_rec *cardp = (void *)priv;
116 119
120 if (cardp->fwdnldover) {
121 lbs_deb_usb("Download complete, no event. Assuming success\n");
122 } else {
123 lbs_pr_err("Download timed out\n");
124 cardp->surprise_removed = 1;
125 }
126 wake_up(&cardp->fw_wq);
127}
117/** 128/**
118 * @brief sets the configuration values 129 * @brief sets the configuration values
119 * @param ifnum interface number 130 * @param ifnum interface number
@@ -138,6 +149,9 @@ static int if_usb_probe(struct usb_interface *intf,
138 goto error; 149 goto error;
139 } 150 }
140 151
152 setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
153 init_waitqueue_head(&cardp->fw_wq);
154
141 cardp->udev = udev; 155 cardp->udev = udev;
142 iface_desc = intf->cur_altsetting; 156 iface_desc = intf->cur_altsetting;
143 157
@@ -296,7 +310,7 @@ static void if_usb_disconnect(struct usb_interface *intf)
296 * @param priv pointer to struct lbs_private 310 * @param priv pointer to struct lbs_private
297 * @return 0 311 * @return 0
298 */ 312 */
299static int if_prog_firmware(struct usb_card_rec *cardp) 313static int if_usb_send_fw_pkt(struct usb_card_rec *cardp)
300{ 314{
301 struct FWData *fwdata; 315 struct FWData *fwdata;
302 struct fwheader *fwheader; 316 struct fwheader *fwheader;
@@ -566,19 +580,21 @@ static void if_usb_receive_fwload(struct urb *urb)
566 580
567 kfree_skb(skb); 581 kfree_skb(skb);
568 582
583 /* reschedule timer for 200ms hence */
584 mod_timer(&cardp->fw_timeout, jiffies + (HZ/5));
585
569 if (cardp->fwfinalblk) { 586 if (cardp->fwfinalblk) {
570 cardp->fwdnldover = 1; 587 cardp->fwdnldover = 1;
571 goto exit; 588 goto exit;
572 } 589 }
573 590
574 if_prog_firmware(cardp); 591 if_usb_send_fw_pkt(cardp);
575 592
576 if_usb_submit_rx_urb_fwload(cardp); 593 if_usb_submit_rx_urb_fwload(cardp);
577exit: 594 exit:
578 kfree(syncfwheader); 595 kfree(syncfwheader);
579 596
580 return; 597 return;
581
582} 598}
583 599
584#define MRVDRV_MIN_PKT_LEN 30 600#define MRVDRV_MIN_PKT_LEN 30
@@ -911,15 +927,13 @@ restart:
911 cardp->totalbytes = 0; 927 cardp->totalbytes = 0;
912 cardp->fwfinalblk = 0; 928 cardp->fwfinalblk = 0;
913 929
914 if_prog_firmware(cardp); 930 /* Send the first firmware packet... */
931 if_usb_send_fw_pkt(cardp);
915 932
916 do { 933 /* ... and wait for the process to complete */
917 lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n"); 934 wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
918 i++; 935
919 msleep_interruptible(100); 936 del_timer_sync(&cardp->fw_timeout);
920 if (cardp->surprise_removed || i >= 20)
921 break;
922 } while (!cardp->fwdnldover);
923 937
924 if (!cardp->fwdnldover) { 938 if (!cardp->fwdnldover) {
925 lbs_pr_info("failed to load fw, resetting device!\n"); 939 lbs_pr_info("failed to load fw, resetting device!\n");