[PATCH] libertas: support boot commands for flashing boot2 and persistent firmware

Brian Cavagnolo brian at cozybit.com
Mon Jun 2 14:22:21 EDT 2008


Based on a patch from Brajesh Dave
Also refine error codes returned by if_usb_prog_firmware.

Signed-off-by: Brian Cavagnolo <brian at cozybit.com>
---
 drivers/net/wireless/libertas/if_usb.c |   57 +++++++++++++++++++++++--------
 1 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 7db8e6c..91413a6 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -35,7 +35,8 @@ MODULE_DEVICE_TABLE(usb, if_usb_table);
 
 static void if_usb_receive(struct urb *urb);
 static void if_usb_receive_fwload(struct urb *urb);
-static int if_usb_prog_firmware(struct if_usb_card *cardp);
+static int if_usb_prog_firmware(struct if_usb_card *cardp,
+					const char *fwname, int cmd);
 static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
 			       uint8_t *payload, uint16_t nb);
 static int if_usb_get_int_status(struct lbs_private *priv, uint8_t *);
@@ -220,7 +220,7 @@ static int if_usb_probe(struct usb_interface *intf,
 	}
 
 	/* Upload firmware */
-	if (if_usb_prog_firmware(cardp)) {
+	if (if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) {
 		lbs_deb_usbd(&udev->dev, "FW upload failed\n");
 		goto err_prog_firmware;
 	}
@@ -507,7 +507,9 @@ static void if_usb_receive_fwload(struct urb *urb)
 				lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
 					    le32_to_cpu(bootcmdresp.magic));
 			}
-		} else if (bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) {
+		} else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) &&
+			   (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) &&
+			   (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) {
 			lbs_pr_info("boot cmd response cmd_tag error (%d)\n",
 				    bootcmdresp.cmd);
 		} else if (bootcmdresp.result != BOOT_CMD_RESP_OK) {
@@ -545,8 +547,8 @@ static void if_usb_receive_fwload(struct urb *urb)
 
 	kfree_skb(skb);
 
-	/* reschedule timer for 200ms hence */
-	mod_timer(&cardp->fw_timeout, jiffies + (HZ/5));
+	/* Give device 5s to either write firmware to its RAM or eeprom */
+	mod_timer(&cardp->fw_timeout, jiffies + (HZ*5));
 
 	if (cardp->fwfinalblk) {
 		cardp->fwdnldover = 1;
@@ -814,8 +816,17 @@ static int check_fwfile_format(uint8_t *data, uint32_t totlen)
 	return ret;
 }
 
-
-static int if_usb_prog_firmware(struct if_usb_card *cardp)
+/**
+ *  @brief This function programs the firmware subject to cmd
+ *
+ *  @param cardp             the if_usb_card descriptor
+ *         fwname            firmware or boot2 image file name
+ *         cmd               either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
+ *                           or BOOT_CMD_UPDATE_BOOT2.
+ *  @return     0 or error code
+ */
+static int if_usb_prog_firmware(struct if_usb_card *cardp,
+					const char *fwname, int cmd)
 {
 	int i = 0;
 	static int reset_count = 10;
@@ -823,20 +833,39 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp)
 
 	lbs_deb_enter(LBS_DEB_USB);
 
-	if ((ret = request_firmware(&cardp->fw, lbs_fw_name,
-				    &cardp->udev->dev)) < 0) {
+	/* Don't mess with the firmware if the interface is up */
+	if (cardp->priv &&
+		(cardp->priv->mesh_open || cardp->priv->infra_open)) {
+		ret = -EPERM;
+		goto done;
+	}
+
+	ret = request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
+	if (ret < 0) {
 		lbs_pr_err("request_firmware() failed with %#x\n", ret);
-		lbs_pr_err("firmware %s not found\n", lbs_fw_name);
+		lbs_pr_err("firmware %s not found\n", fwname);
 		goto done;
 	}
 
-	if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
+	if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) {
+		ret = -EINVAL;
 		goto release_fw;
+	}
+
+	/* Cancel any pending usb business */
+	usb_kill_urb(cardp->rx_urb);
+	usb_kill_urb(cardp->tx_urb);
+
+	cardp->fwlastblksent = 0;
+	cardp->fwdnldover = 0;
+	cardp->totalbytes = 0;
+	cardp->fwfinalblk = 0;
+	cardp->bootcmdresp = 0;
 
 restart:
 	if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
 		lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
-		ret = -1;
+		ret = -EIO;
 		goto release_fw;
 	}
 
@@ -844,8 +872,7 @@ restart:
 	do {
 		int j = 0;
 		i++;
-		/* Issue Boot command = 1, Boot from Download-FW */
-		if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
+		if_usb_issue_boot_command(cardp, cmd);
 		/* wait for command response */
 		do {
 			j++;
@@ -858,7 +885,7 @@ restart:
 			if_usb_reset_device(cardp);
 			goto restart;
 		}
-		return -1;
+		return -EIO;
 	}
 
 	i = 0;
@@ -888,7 +915,7 @@ restart:
 		}
 
 		lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
-		ret = -1;
+		ret = -EIO;
 		goto release_fw;
 	}
 
-- 
1.5.2.5






More information about the libertas-dev mailing list