wl12xx: Use a dedicated fw for PLT
authorEliad Peller <eliad@wizery.com>
Mon, 6 Feb 2012 10:47:54 +0000 (12:47 +0200)
committerLuciano Coelho <coelho@ti.com>
Wed, 15 Feb 2012 06:38:35 +0000 (08:38 +0200)
A special PLT firmware is used for calibration.

Add multiple fw support by introducing a new fw_type member,
representing the currently saved fw (the actual fw state
can be determined by wl->state).

Signed-off-by: Gery Kahn <geryk@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/sdio.c
drivers/net/wireless/wl12xx/spi.c
drivers/net/wireless/wl12xx/testmode.c
drivers/net/wireless/wl12xx/wl12xx.h

index 00dbe1595a7f1617231b4c68630a3b584877e147..e1cf727659650a90f9ae43f8636003409404eb00 100644 (file)
@@ -113,7 +113,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl)
        if (ret < 0)
                goto out;
 
-       if (wl->state == WL1271_STATE_ON &&
+       if (wl->state == WL1271_STATE_ON && !wl->plt &&
            time_after(jiffies, wl->stats.fw_stats_update +
                       msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) {
                wl1271_acx_statistics(wl, wl->stats.fw_stats);
index 723df48ed44730d67fa2663fd6b51119ee36a5ac..c10940703e8c904c214660144f2525b065761697 100644 (file)
@@ -993,16 +993,29 @@ out:
        return IRQ_HANDLED;
 }
 
-static int wl1271_fetch_firmware(struct wl1271 *wl)
+static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
 {
        const struct firmware *fw;
        const char *fw_name;
+       enum wl12xx_fw_type fw_type;
        int ret;
 
-       if (wl->chip.id == CHIP_ID_1283_PG20)
-               fw_name = WL128X_FW_NAME;
-       else
-               fw_name = WL127X_FW_NAME;
+       if (plt) {
+               fw_type = WL12XX_FW_TYPE_PLT;
+               if (wl->chip.id == CHIP_ID_1283_PG20)
+                       fw_name = WL128X_PLT_FW_NAME;
+               else
+                       fw_name = WL127X_PLT_FW_NAME;
+       } else {
+               fw_type = WL12XX_FW_TYPE_NORMAL;
+               if (wl->chip.id == CHIP_ID_1283_PG20)
+                       fw_name = WL128X_FW_NAME;
+               else
+                       fw_name = WL127X_FW_NAME;
+       }
+
+       if (wl->fw_type == fw_type)
+               return 0;
 
        wl1271_debug(DEBUG_BOOT, "booting firmware %s", fw_name);
 
@@ -1021,6 +1034,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
        }
 
        vfree(wl->fw);
+       wl->fw_type = WL12XX_FW_TYPE_NONE;
        wl->fw_len = fw->size;
        wl->fw = vmalloc(wl->fw_len);
 
@@ -1032,7 +1046,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
 
        memcpy(wl->fw, fw->data, wl->fw_len);
        ret = 0;
-
+       wl->fw_type = fw_type;
 out:
        release_firmware(fw);
 
@@ -1160,7 +1174,7 @@ static void wl1271_recovery_work(struct work_struct *work)
 
        mutex_lock(&wl->mutex);
 
-       if (wl->state != WL1271_STATE_ON)
+       if (wl->state != WL1271_STATE_ON || wl->plt)
                goto out_unlock;
 
        /* Avoid a recursive recovery */
@@ -1261,7 +1275,7 @@ out:
        return ret;
 }
 
-static int wl1271_chip_wakeup(struct wl1271 *wl)
+static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt)
 {
        int ret = 0;
 
@@ -1316,11 +1330,9 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
                goto out;
        }
 
-       if (wl->fw == NULL) {
-               ret = wl1271_fetch_firmware(wl);
-               if (ret < 0)
-                       goto out;
-       }
+       ret = wl12xx_fetch_firmware(wl, plt);
+       if (ret < 0)
+               goto out;
 
        /* No NVS from netlink, try to get it from the filesystem */
        if (wl->nvs == NULL) {
@@ -1352,7 +1364,7 @@ int wl1271_plt_start(struct wl1271 *wl)
 
        while (retries) {
                retries--;
-               ret = wl1271_chip_wakeup(wl);
+               ret = wl12xx_chip_wakeup(wl, true);
                if (ret < 0)
                        goto power_off;
 
@@ -1364,7 +1376,8 @@ int wl1271_plt_start(struct wl1271 *wl)
                if (ret < 0)
                        goto irq_disable;
 
-               wl->state = WL1271_STATE_PLT;
+               wl->plt = true;
+               wl->state = WL1271_STATE_ON;
                wl1271_notice("firmware booted in PLT mode (%s)",
                              wl->chip.fw_ver_str);
 
@@ -1413,7 +1426,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
         */
        wl1271_disable_interrupts(wl);
        mutex_lock(&wl->mutex);
-       if (wl->state != WL1271_STATE_PLT) {
+       if (!wl->plt) {
                mutex_unlock(&wl->mutex);
 
                /*
@@ -1440,6 +1453,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
        wl1271_power_off(wl);
        wl->flags = 0;
        wl->state = WL1271_STATE_OFF;
+       wl->plt = false;
        wl->rx_counter = 0;
        mutex_unlock(&wl->mutex);
 
@@ -1995,7 +2009,7 @@ static bool wl12xx_init_fw(struct wl1271 *wl)
 
        while (retries) {
                retries--;
-               ret = wl1271_chip_wakeup(wl);
+               ret = wl12xx_chip_wakeup(wl, false);
                if (ret < 0)
                        goto power_off;
 
@@ -2098,6 +2112,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
                goto out;
        }
 
+
        ret = wl12xx_init_vif_data(wl, vif);
        if (ret < 0)
                goto out;
@@ -5009,7 +5024,7 @@ out:
 
 static void wl1271_unregister_hw(struct wl1271 *wl)
 {
-       if (wl->state == WL1271_STATE_PLT)
+       if (wl->plt)
                wl1271_plt_stop(wl);
 
        unregister_netdevice_notifier(&wl1271_dev_notifier);
@@ -5186,6 +5201,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
        spin_lock_init(&wl->wl_lock);
 
        wl->state = WL1271_STATE_OFF;
+       wl->fw_type = WL12XX_FW_TYPE_NONE;
        mutex_init(&wl->mutex);
 
        /* Apply default driver configuration. */
@@ -5253,6 +5269,7 @@ static int wl1271_free_hw(struct wl1271 *wl)
 
        vfree(wl->fw);
        wl->fw = NULL;
+       wl->fw_type = WL12XX_FW_TYPE_NONE;
        kfree(wl->nvs);
        wl->nvs = NULL;
 
index 4fbd2a722ffabf28eb4f3c383490b2060c1535dc..cfa6071704c591d3be1100b469a140302da95489 100644 (file)
@@ -113,7 +113,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
         * In PLT mode we seem to get frames and mac80211 warns about them,
         * workaround this by not retrieving them at all.
         */
-       if (unlikely(wl->state == WL1271_STATE_PLT))
+       if (unlikely(wl->plt))
                return -EINVAL;
 
        /* the data read starts with the descriptor */
index ce3b9a99463e1569341578db3d7ac2fa255cd547..1c0264ca021fa39c90491f507967621c5fee2caf 100644 (file)
@@ -372,3 +372,5 @@ MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
 MODULE_FIRMWARE(WL127X_FW_NAME);
 MODULE_FIRMWARE(WL128X_FW_NAME);
+MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
+MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
index 92caa7ce6053efc1c36227553b03b05e61844cbe..5c2d4a0ef000609268545a31eb1900f9d2573583 100644 (file)
@@ -435,4 +435,6 @@ MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
 MODULE_FIRMWARE(WL127X_FW_NAME);
 MODULE_FIRMWARE(WL128X_FW_NAME);
+MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
+MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
 MODULE_ALIAS("spi:wl1271");
index b6b433e5562f1aae3cc5a68e4878330dba6aa2b2..1e93bb9c0246cfa02e44f6160851909b422b14ec 100644 (file)
@@ -274,7 +274,7 @@ static int wl12xx_tm_cmd_get_mac(struct wl1271 *wl, struct nlattr *tb[])
 
        mutex_lock(&wl->mutex);
 
-       if (wl->state != WL1271_STATE_PLT) {
+       if (!wl->plt) {
                ret = -EINVAL;
                goto out;
        }
index 81af416d17da46ed7b79888ebbaeb551587e694b..9b48aa48cdca3263774ebdfdc43cc96acda1c727 100644 (file)
@@ -37,6 +37,8 @@
 
 #define WL127X_FW_NAME "ti-connectivity/wl127x-fw-4-sr.bin"
 #define WL128X_FW_NAME "ti-connectivity/wl128x-fw-4-sr.bin"
+#define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin"
+#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
 
 /*
  * wl127x and wl128x are using the same NVS file name. However, the
 enum wl1271_state {
        WL1271_STATE_OFF,
        WL1271_STATE_ON,
-       WL1271_STATE_PLT,
+};
+
+enum wl12xx_fw_type {
+       WL12XX_FW_TYPE_NONE,
+       WL12XX_FW_TYPE_NORMAL,
+       WL12XX_FW_TYPE_PLT,
 };
 
 enum wl1271_partition_type {
@@ -294,6 +301,8 @@ struct wl1271 {
        spinlock_t wl_lock;
 
        enum wl1271_state state;
+       enum wl12xx_fw_type fw_type;
+       bool plt;
        struct mutex mutex;
 
        unsigned long flags;