Commit c9cd6f9d authored by David Woodhouse's avatar David Woodhouse Committed by David S. Miller

libertas: wait for 'firmware ready' event from firmware after loading

Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 10bca0d5
...@@ -304,5 +304,6 @@ enum cmd_mesh_access_opts { ...@@ -304,5 +304,6 @@ enum cmd_mesh_access_opts {
#define MACREG_INT_CODE_RSSI_HIGH 28 #define MACREG_INT_CODE_RSSI_HIGH 28
#define MACREG_INT_CODE_SNR_HIGH 29 #define MACREG_INT_CODE_SNR_HIGH 29
#define MACREG_INT_CODE_MESH_AUTO_STARTED 35 #define MACREG_INT_CODE_MESH_AUTO_STARTED 35
#define MACREG_INT_CODE_FIRMWARE_READY 48
#endif #endif
...@@ -230,6 +230,7 @@ static int if_usb_probe(struct usb_interface *intf, ...@@ -230,6 +230,7 @@ static int if_usb_probe(struct usb_interface *intf,
goto err_prog_firmware; goto err_prog_firmware;
cardp->priv = priv; cardp->priv = priv;
cardp->priv->fw_ready = 1;
if (lbs_add_mesh(priv, &udev->dev)) if (lbs_add_mesh(priv, &udev->dev))
goto err_add_mesh; goto err_add_mesh;
...@@ -241,10 +242,7 @@ static int if_usb_probe(struct usb_interface *intf, ...@@ -241,10 +242,7 @@ static int if_usb_probe(struct usb_interface *intf,
priv->hw_read_event_cause = if_usb_read_event_cause; priv->hw_read_event_cause = if_usb_read_event_cause;
priv->boot2_version = udev->descriptor.bcdDevice; priv->boot2_version = udev->descriptor.bcdDevice;
/* Delay 200 ms to waiting for the FW ready */
if_usb_submit_rx_urb(cardp); if_usb_submit_rx_urb(cardp);
msleep_interruptible(200);
priv->fw_ready = 1;
if (lbs_start_card(priv)) if (lbs_start_card(priv))
goto err_start_card; goto err_start_card;
...@@ -514,6 +512,21 @@ static void if_usb_receive_fwload(struct urb *urb) ...@@ -514,6 +512,21 @@ static void if_usb_receive_fwload(struct urb *urb)
return; return;
} }
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;
}
if (cardp->bootcmdresp <= 0) { if (cardp->bootcmdresp <= 0) {
memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET, memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
sizeof(bootcmdresp)); sizeof(bootcmdresp));
...@@ -529,6 +542,7 @@ static void if_usb_receive_fwload(struct urb *urb) ...@@ -529,6 +542,7 @@ static void if_usb_receive_fwload(struct urb *urb)
if (bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_REQUEST) || if (bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_REQUEST) ||
bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_DATA) || bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_DATA) ||
bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_INDICATION)) { bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_INDICATION)) {
if (!cardp->bootcmdresp)
lbs_pr_info("Firmware already seems alive; resetting\n"); lbs_pr_info("Firmware already seems alive; resetting\n");
cardp->bootcmdresp = -1; cardp->bootcmdresp = -1;
} else { } else {
...@@ -590,8 +604,9 @@ static void if_usb_receive_fwload(struct urb *urb) ...@@ -590,8 +604,9 @@ static void if_usb_receive_fwload(struct urb *urb)
if_usb_send_fw_pkt(cardp); if_usb_send_fw_pkt(cardp);
if_usb_submit_rx_urb_fwload(cardp);
exit: exit:
if_usb_submit_rx_urb_fwload(cardp);
kfree(syncfwheader); kfree(syncfwheader);
return; return;
...@@ -934,6 +949,7 @@ static int if_usb_prog_firmware(struct usb_card_rec *cardp) ...@@ -934,6 +949,7 @@ static int if_usb_prog_firmware(struct usb_card_rec *cardp)
wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover); wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
del_timer_sync(&cardp->fw_timeout); del_timer_sync(&cardp->fw_timeout);
usb_kill_urb(cardp->rx_urb);
if (!cardp->fwdnldover) { if (!cardp->fwdnldover) {
lbs_pr_info("failed to load fw, resetting device!\n"); lbs_pr_info("failed to load fw, resetting device!\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment