aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ti/wlcore
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2012-06-25 10:46:40 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-07-10 12:10:12 -0400
commit4a1ccce852882c174d2392d2d8db1d65f48d4a10 (patch)
tree0dcf0b3644a48ac643450688ea0a1529d3296498 /drivers/net/wireless/ti/wlcore
parent01b3c0e4df483affb076405f129aa45bc2cde499 (diff)
wlcore/wl12xx/wl18xx: check min FW version
Refuse to boot if the FW version is too old. The minimum version is set per chip, with the option of setting it per PG in the future. When boot fails because of an old FW, display a helpful message. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/ti/wlcore')
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.c51
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h15
2 files changed, 66 insertions, 0 deletions
diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c
index 8965960b841a..61113291a890 100644
--- a/drivers/net/wireless/ti/wlcore/boot.c
+++ b/drivers/net/wireless/ti/wlcore/boot.c
@@ -81,6 +81,53 @@ out:
81 return ret; 81 return ret;
82} 82}
83 83
84static int wlcore_validate_fw_ver(struct wl1271 *wl)
85{
86 unsigned int *fw_ver = wl->chip.fw_ver;
87 unsigned int *min_ver = wl->min_fw_ver;
88
89 /* the chip must be exactly equal */
90 if (min_ver[FW_VER_CHIP] != fw_ver[FW_VER_CHIP])
91 goto fail;
92
93 /* always check the next digit if all previous ones are equal */
94
95 if (min_ver[FW_VER_IF_TYPE] < fw_ver[FW_VER_IF_TYPE])
96 goto out;
97 else if (min_ver[FW_VER_IF_TYPE] > fw_ver[FW_VER_IF_TYPE])
98 goto fail;
99
100 if (min_ver[FW_VER_MAJOR] < fw_ver[FW_VER_MAJOR])
101 goto out;
102 else if (min_ver[FW_VER_MAJOR] > fw_ver[FW_VER_MAJOR])
103 goto fail;
104
105 if (min_ver[FW_VER_SUBTYPE] < fw_ver[FW_VER_SUBTYPE])
106 goto out;
107 else if (min_ver[FW_VER_SUBTYPE] > fw_ver[FW_VER_SUBTYPE])
108 goto fail;
109
110 if (min_ver[FW_VER_MINOR] < fw_ver[FW_VER_MINOR])
111 goto out;
112 else if (min_ver[FW_VER_MINOR] > fw_ver[FW_VER_MINOR])
113 goto fail;
114
115out:
116 return 0;
117
118fail:
119 wl1271_error("Your WiFi FW version (%u.%u.%u.%u.%u) is outdated.\n"
120 "Please use at least FW %u.%u.%u.%u.%u.\n"
121 "You can get more information at:\n"
122 "http://wireless.kernel.org/en/users/Drivers/wl12xx",
123 fw_ver[FW_VER_CHIP], fw_ver[FW_VER_IF_TYPE],
124 fw_ver[FW_VER_MAJOR], fw_ver[FW_VER_SUBTYPE],
125 fw_ver[FW_VER_MINOR], min_ver[FW_VER_CHIP],
126 min_ver[FW_VER_IF_TYPE], min_ver[FW_VER_MAJOR],
127 min_ver[FW_VER_SUBTYPE], min_ver[FW_VER_MINOR]);
128 return -EINVAL;
129}
130
84static int wlcore_boot_static_data(struct wl1271 *wl) 131static int wlcore_boot_static_data(struct wl1271 *wl)
85{ 132{
86 struct wl1271_static_data *static_data; 133 struct wl1271_static_data *static_data;
@@ -101,6 +148,10 @@ static int wlcore_boot_static_data(struct wl1271 *wl)
101 if (ret < 0) 148 if (ret < 0)
102 goto out_free; 149 goto out_free;
103 150
151 ret = wlcore_validate_fw_ver(wl);
152 if (ret < 0)
153 goto out_free;
154
104 ret = wlcore_handle_static_data(wl, static_data); 155 ret = wlcore_handle_static_data(wl, static_data);
105 if (ret < 0) 156 if (ret < 0)
106 goto out_free; 157 goto out_free;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 216bdb0f2756..942cef13d8f4 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -390,6 +390,9 @@ struct wl1271 {
390 390
391 /* sleep auth value currently configured to FW */ 391 /* sleep auth value currently configured to FW */
392 int sleep_auth; 392 int sleep_auth;
393
394 /* the minimum FW version required for the driver to work */
395 unsigned int min_fw_ver[NUM_FW_VER];
393}; 396};
394 397
395int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); 398int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
@@ -408,6 +411,18 @@ wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band,
408 memcpy(&wl->ht_cap[band], ht_cap, sizeof(*ht_cap)); 411 memcpy(&wl->ht_cap[band], ht_cap, sizeof(*ht_cap));
409} 412}
410 413
414static inline void
415wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip,
416 unsigned int iftype, unsigned int major,
417 unsigned int subtype, unsigned int minor)
418{
419 wl->min_fw_ver[FW_VER_CHIP] = chip;
420 wl->min_fw_ver[FW_VER_IF_TYPE] = iftype;
421 wl->min_fw_ver[FW_VER_MAJOR] = major;
422 wl->min_fw_ver[FW_VER_SUBTYPE] = subtype;
423 wl->min_fw_ver[FW_VER_MINOR] = minor;
424}
425
411/* Firmware image load chunk size */ 426/* Firmware image load chunk size */
412#define CHUNK_SIZE 16384 427#define CHUNK_SIZE 16384
413 428