wil6210: extract firmware version from file header
authorLior David <qca_liord@qca.qualcomm.com>
Mon, 22 Aug 2016 09:42:22 +0000 (12:42 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Wed, 31 Aug 2016 07:31:16 +0000 (10:31 +0300)
Currently the FW version is taken from the sw_version field
of the FW ready event. This version is based on internal
version control revision and it is difficult to map to actual
FW version.
Fix this by using the actual FW version stored in the FW file
header record.

Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/wil6210/debugfs.c
drivers/net/wireless/ath/wil6210/fw.h
drivers/net/wireless/ath/wil6210/fw_inc.c
drivers/net/wireless/ath/wil6210/main.c
drivers/net/wireless/ath/wil6210/netdev.c
drivers/net/wireless/ath/wil6210/wil6210.h
drivers/net/wireless/ath/wil6210/wmi.c

index a244a36c19bc9e7b33ce42aed74a8305499cb81c..5e4058a4037b414d1c5c2dc764f96960e6cd3c14 100644 (file)
@@ -1577,6 +1577,32 @@ static const struct file_operations fops_fw_capabilities = {
        .llseek         = seq_lseek,
 };
 
+/*---------FW version------------*/
+static int wil_fw_version_debugfs_show(struct seq_file *s, void *data)
+{
+       struct wil6210_priv *wil = s->private;
+
+       if (wil->fw_version[0])
+               seq_printf(s, "%s\n", wil->fw_version);
+       else
+               seq_puts(s, "N/A\n");
+
+       return 0;
+}
+
+static int wil_fw_version_seq_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, wil_fw_version_debugfs_show,
+                          inode->i_private);
+}
+
+static const struct file_operations fops_fw_version = {
+       .open           = wil_fw_version_seq_open,
+       .release        = single_release,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+};
+
 /*----------------*/
 static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil,
                                       struct dentry *dbg)
@@ -1628,6 +1654,7 @@ static const struct {
        {"led_cfg",     S_IRUGO | S_IWUSR,      &fops_led_cfg},
        {"led_blink_time",      S_IRUGO | S_IWUSR,      &fops_led_blink_time},
        {"fw_capabilities",     S_IRUGO,        &fops_fw_capabilities},
+       {"fw_version",  S_IRUGO,                &fops_fw_version},
 };
 
 static void wil6210_debugfs_init_files(struct wil6210_priv *wil,
@@ -1668,7 +1695,6 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil,
 static const struct dbg_off dbg_wil_off[] = {
        WIL_FIELD(privacy,      S_IRUGO,                doff_u32),
        WIL_FIELD(status[0],    S_IRUGO | S_IWUSR,      doff_ulong),
-       WIL_FIELD(fw_version,   S_IRUGO,                doff_u32),
        WIL_FIELD(hw_version,   S_IRUGO,                doff_x32),
        WIL_FIELD(recovery_count, S_IRUGO,              doff_u32),
        WIL_FIELD(ap_isolate,   S_IRUGO,                doff_u32),
index c3191c61832cd2972869a658c032ca901ef17bdf..2f2b910501ba7077c4a9dabcca92840d1be08b35 100644 (file)
@@ -102,6 +102,9 @@ struct wil_fw_record_verify { /* type == wil_fw_verify */
 /* file header
  * First record of every file
  */
+/* the FW version prefix in the comment */
+#define WIL_FW_VERSION_PREFIX "FW version: "
+#define WIL_FW_VERSION_PREFIX_LEN (sizeof(WIL_FW_VERSION_PREFIX) - 1)
 struct wil_fw_record_file_header {
        __le32 signature ; /* Wilocity signature */
        __le32 reserved;
index 3860238840ba371bc0e8239b29d7f62c4c47c726..8f40eb301924b1b0100af4f09732c556236734dc 100644 (file)
@@ -223,6 +223,13 @@ static int fw_handle_file_header(struct wil6210_priv *wil, const void *data,
        wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, d->comment,
                        sizeof(d->comment), true);
 
+       if (!memcmp(d->comment, WIL_FW_VERSION_PREFIX,
+                   WIL_FW_VERSION_PREFIX_LEN))
+               memcpy(wil->fw_version,
+                      d->comment + WIL_FW_VERSION_PREFIX_LEN,
+                      min(sizeof(d->comment) - WIL_FW_VERSION_PREFIX_LEN,
+                          sizeof(wil->fw_version) - 1));
+
        return 0;
 }
 
index 7198c86e09f2ff6c00680fd0006e008eea514b18..e7130b54d1d89a43243cf385a6caafd42bd57ba7 100644 (file)
@@ -893,6 +893,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
                         WIL_FW2_NAME);
 
                wil_halt_cpu(wil);
+               memset(wil->fw_version, 0, sizeof(wil->fw_version));
                /* Loading f/w from the file */
                rc = wil_request_firmware(wil, WIL_FW_NAME, true);
                if (rc)
index 4bc9bb0a6cb48df4ef3a212ef56b08cd6c7a7a9b..61de5e9f8ef0745d882aec0f2b329c2f7e2bab8c 100644 (file)
@@ -216,6 +216,8 @@ int wil_if_add(struct wil6210_priv *wil)
 
        wil_dbg_misc(wil, "entered");
 
+       strlcpy(wiphy->fw_version, wil->fw_version, sizeof(wiphy->fw_version));
+
        rc = wiphy_register(wiphy);
        if (rc < 0) {
                wil_err(wil, "failed to register wiphy, err %d\n", rc);
index 979536ce4591186762e9623c1b3754881d55ff9d..a949cd62bc4e752cba2dd9e67948b8158f2f25e0 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __WIL6210_H__
 #define __WIL6210_H__
 
+#include <linux/etherdevice.h>
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <net/cfg80211.h>
@@ -576,7 +577,7 @@ struct wil6210_priv {
        struct wireless_dev *wdev;
        void __iomem *csr;
        DECLARE_BITMAP(status, wil_status_last);
-       u32 fw_version;
+       u8 fw_version[ETHTOOL_FWVERS_LEN];
        u32 hw_version;
        const char *hw_name;
        DECLARE_BITMAP(hw_capabilities, hw_capability_last);
index 0b109b2a31ac516877a66c8a8eccc42aec116d0e..fae4f1285d0873c2b8afa77d75c35904e7d8ed73 100644 (file)
@@ -312,14 +312,14 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
        struct wireless_dev *wdev = wil->wdev;
        struct wmi_ready_event *evt = d;
 
-       wil->fw_version = le32_to_cpu(evt->sw_version);
        wil->n_mids = evt->numof_additional_mids;
 
-       wil_info(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version,
+       wil_info(wil, "FW ver. %s(SW %d); MAC %pM; %d MID's\n",
+                wil->fw_version, le32_to_cpu(evt->sw_version),
                 evt->mac, wil->n_mids);
        /* ignore MAC address, we already have it from the boot loader */
-       snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version),
-                "%d", wil->fw_version);
+       strlcpy(wdev->wiphy->fw_version, wil->fw_version,
+               sizeof(wdev->wiphy->fw_version));
 
        wil_set_recovery_state(wil, fw_recovery_idle);
        set_bit(wil_status_fwready, wil->status);