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>
This commit is contained in:
committed by
David S. Miller
parent
10bca0d5f4
commit
c9cd6f9d63
@@ -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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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,7 +542,8 @@ 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)) {
|
||||||
lbs_pr_info("Firmware already seems alive; resetting\n");
|
if (!cardp->bootcmdresp)
|
||||||
|
lbs_pr_info("Firmware already seems alive; resetting\n");
|
||||||
cardp->bootcmdresp = -1;
|
cardp->bootcmdresp = -1;
|
||||||
} else {
|
} else {
|
||||||
lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
|
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)
|
|||||||
|
|
||||||
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 @@ restart:
|
|||||||
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");
|
||||||
|
Reference in New Issue
Block a user