#include "defs.h"
#include "dev.h"
#include "if_usb.h"
+#include "decl.h"
#define MESSAGE_HEADER_LEN 4
static const char usbdriver_name[] = "usb8xxx";
static u8 *default_fw_name = "usb8388.bin";
-char *libertas_fw_name = NULL;
+static char *libertas_fw_name = NULL;
module_param_named(fw_name, libertas_fw_name, charp, 0644);
/*
static void if_usb_receive(struct urb *urb);
static void if_usb_receive_fwload(struct urb *urb);
-static int if_usb_reset_device(wlan_private *priv);
static int if_usb_register_dev(wlan_private * priv);
static int if_usb_unregister_dev(wlan_private *);
static int if_usb_prog_firmware(wlan_private *);
static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
static int if_usb_get_int_status(wlan_private * priv, u8 *);
static int if_usb_read_event_cause(wlan_private *);
+static int usb_tx_block(wlan_private *priv, u8 *payload, u16 nb);
+static void if_usb_free(struct usb_card_rec *cardp);
/**
* @brief call back function to handle the status of the URB
priv->dnld_sent = DNLD_RES_RECEIVED;
/* Wake main thread if commands are pending */
if (!adapter->cur_cmd)
- wake_up_interruptible(&priv->mainthread.waitq);
- if ((adapter->connect_status == libertas_connected)) {
+ wake_up_interruptible(&priv->waitq);
+ if ((adapter->connect_status == LIBERTAS_CONNECTED)) {
netif_wake_queue(dev);
netif_wake_queue(priv->mesh_dev);
}
* @param cardp pointer usb_card_rec
* @return N/A
*/
-void if_usb_free(struct usb_card_rec *cardp)
+static void if_usb_free(struct usb_card_rec *cardp)
{
lbs_deb_enter(LBS_DEB_USB);
priv->hw_get_int_status = if_usb_get_int_status;
priv->hw_read_event_cause = if_usb_read_event_cause;
- if (libertas_activate_card(priv, libertas_fw_name))
+ if (libertas_activate_card(priv))
goto err_activate_card;
list_add_tail(&cardp->list, &usb_devices);
return 0;
}
-static int libertas_do_reset(wlan_private *priv)
+static int if_usb_reset_device(wlan_private *priv)
{
int ret;
struct usb_card_rec *cardp = priv->card;
lbs_deb_enter(LBS_DEB_USB);
+ /* Try a USB port reset first, if that fails send the reset
+ * command to the firmware.
+ */
ret = usb_reset_device(cardp->udev);
if (!ret) {
msleep(10);
- if_usb_reset_device(priv);
+ ret = libertas_reset_device(priv);
msleep(10);
}
* @param nb data length
* @return 0 or -1
*/
-int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb)
+static int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb)
{
/* pointer to card structure */
struct usb_card_rec *cardp = priv->card;
* data to clear the interrupt */
if (!priv->adapter->cur_cmd) {
cmdbuf = priv->upld_buf;
- priv->adapter->hisregcpy &= ~his_cmdupldrdy;
+ priv->adapter->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
} else
cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;
- cardp->usb_int_cause |= his_cmdupldrdy;
+ cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY;
priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN,
priv->upld_len);
break;
}
cardp->usb_event_cause <<= 3;
- cardp->usb_int_cause |= his_cardevent;
+ cardp->usb_int_cause |= MRVDRV_CARDEVENT;
kfree_skb(skb);
libertas_interrupt(priv->dev);
spin_unlock(&priv->adapter->driver_lock);
return 0;
}
-static int if_usb_reset_device(wlan_private *priv)
-{
- int ret;
-
- lbs_deb_enter(LBS_DEB_USB);
- ret = libertas_prepare_and_send_command(priv, cmd_802_11_reset,
- cmd_act_halt, 0, 0, NULL);
- msleep_interruptible(10);
-
- lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
- return ret;
-}
-
static int if_usb_unregister_dev(wlan_private * priv)
{
int ret = 0;
* again.
*/
if (priv)
- if_usb_reset_device(priv);
+ libertas_reset_device(priv);
return ret;
}
return 0;
}
+/**
+ * @brief This function issues Boot command to the Boot2 code
+ * @param ivalue 1:Boot from FW by USB-Download
+ * 2:Boot from FW in EEPROM
+ * @return 0
+ */
+static int if_usb_issue_boot_command(wlan_private *priv, int ivalue)
+{
+ struct usb_card_rec *cardp = priv->card;
+ struct bootcmdstr sbootcmd;
+ int i;
+
+ /* Prepare command */
+ sbootcmd.u32magicnumber = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
+ sbootcmd.u8cmd_tag = ivalue;
+ for (i=0; i<11; i++)
+ sbootcmd.au8dumy[i]=0x00;
+ memcpy(cardp->bulk_out_buffer, &sbootcmd, sizeof(struct bootcmdstr));
+
+ /* Issue command */
+ usb_tx_block(priv, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
+
+ return 0;
+}
-static int if_usb_prog_firmware(wlan_private * priv)
+static int if_usb_do_prog_firmware(wlan_private * priv)
{
struct usb_card_rec *cardp = priv->card;
int i = 0;
if (cardp->bootcmdresp == 0) {
if (--reset_count >= 0) {
- libertas_do_reset(priv);
+ if_usb_reset_device(priv);
goto restart;
}
return -1;
if (!cardp->fwdnldover) {
lbs_pr_info("failed to load fw, resetting device!\n");
if (--reset_count >= 0) {
- libertas_do_reset(priv);
+ if_usb_reset_device(priv);
goto restart;
}
return ret;
}
+/**
+ * @brief This function checks the validity of Boot2/FW image.
+ *
+ * @param data pointer to image
+ * len image length
+ * @return 0 or -1
+ */
+static int check_fwfile_format(u8 *data, u32 totlen)
+{
+ u32 bincmd, exit;
+ u32 blksize, offset, len;
+ int ret;
+
+ ret = 1;
+ exit = len = 0;
+
+ do {
+ struct fwheader *fwh = (void *)data;
+
+ bincmd = le32_to_cpu(fwh->dnldcmd);
+ blksize = le32_to_cpu(fwh->datalength);
+ switch (bincmd) {
+ case FW_HAS_DATA_TO_RECV:
+ offset = sizeof(struct fwheader) + blksize;
+ data += offset;
+ len += offset;
+ if (len >= totlen)
+ exit = 1;
+ break;
+ case FW_HAS_LAST_BLOCK:
+ exit = 1;
+ ret = 0;
+ break;
+ default:
+ exit = 1;
+ break;
+ }
+ } while (!exit);
+
+ if (ret)
+ lbs_pr_err("firmware file format check FAIL\n");
+ else
+ lbs_deb_fw("firmware file format check PASS\n");
+
+ return ret;
+}
+
+
+static int if_usb_prog_firmware(wlan_private *priv)
+{
+ int ret = -1;
+
+ lbs_deb_enter(LBS_DEB_FW);
+
+ if ((ret = request_firmware(&priv->firmware, libertas_fw_name,
+ priv->hotplug_device)) < 0) {
+ lbs_pr_err("request_firmware() failed with %#x\n", ret);
+ lbs_pr_err("firmware %s not found\n", libertas_fw_name);
+ goto done;
+ }
+
+ if (check_fwfile_format(priv->firmware->data, priv->firmware->size)) {
+ release_firmware(priv->firmware);
+ goto done;
+ }
+
+ ret = if_usb_do_prog_firmware(priv);
+
+ release_firmware(priv->firmware);
+done:
+ return ret;
+}
+
+
#ifdef CONFIG_PM
static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
{
lbs_deb_enter(LBS_DEB_MAIN);
list_for_each_entry_safe(cardp, cardp_temp, &usb_devices, list)
- if_usb_reset_device((wlan_private *) cardp->priv);
+ libertas_reset_device((wlan_private *) cardp->priv);
/* API unregisters the driver from USB subsystem */
usb_deregister(&if_usb_driver);