aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2012-02-06 05:47:54 -0500
committerLuciano Coelho <coelho@ti.com>2012-02-15 01:38:35 -0500
commit3fcdab7066a31ae90ac2beba7d38e8e606374998 (patch)
tree17cec887b8fa6dc97c31ce0d5c820f9874cfc888
parentf95f9aad150238236b2338efa60a14891081026e (diff)
wl12xx: Use a dedicated fw for PLT
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>
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c2
-rw-r--r--drivers/net/wireless/wl12xx/main.c53
-rw-r--r--drivers/net/wireless/wl12xx/rx.c2
-rw-r--r--drivers/net/wireless/wl12xx/sdio.c2
-rw-r--r--drivers/net/wireless/wl12xx/spi.c2
-rw-r--r--drivers/net/wireless/wl12xx/testmode.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h11
7 files changed, 52 insertions, 22 deletions
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 00dbe1595a7f..e1cf72765965 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -113,7 +113,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl)
113 if (ret < 0) 113 if (ret < 0)
114 goto out; 114 goto out;
115 115
116 if (wl->state == WL1271_STATE_ON && 116 if (wl->state == WL1271_STATE_ON && !wl->plt &&
117 time_after(jiffies, wl->stats.fw_stats_update + 117 time_after(jiffies, wl->stats.fw_stats_update +
118 msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) { 118 msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) {
119 wl1271_acx_statistics(wl, wl->stats.fw_stats); 119 wl1271_acx_statistics(wl, wl->stats.fw_stats);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 723df48ed447..c10940703e8c 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -993,16 +993,29 @@ out:
993 return IRQ_HANDLED; 993 return IRQ_HANDLED;
994} 994}
995 995
996static int wl1271_fetch_firmware(struct wl1271 *wl) 996static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
997{ 997{
998 const struct firmware *fw; 998 const struct firmware *fw;
999 const char *fw_name; 999 const char *fw_name;
1000 enum wl12xx_fw_type fw_type;
1000 int ret; 1001 int ret;
1001 1002
1002 if (wl->chip.id == CHIP_ID_1283_PG20) 1003 if (plt) {
1003 fw_name = WL128X_FW_NAME; 1004 fw_type = WL12XX_FW_TYPE_PLT;
1004 else 1005 if (wl->chip.id == CHIP_ID_1283_PG20)
1005 fw_name = WL127X_FW_NAME; 1006 fw_name = WL128X_PLT_FW_NAME;
1007 else
1008 fw_name = WL127X_PLT_FW_NAME;
1009 } else {
1010 fw_type = WL12XX_FW_TYPE_NORMAL;
1011 if (wl->chip.id == CHIP_ID_1283_PG20)
1012 fw_name = WL128X_FW_NAME;
1013 else
1014 fw_name = WL127X_FW_NAME;
1015 }
1016
1017 if (wl->fw_type == fw_type)
1018 return 0;
1006 1019
1007 wl1271_debug(DEBUG_BOOT, "booting firmware %s", fw_name); 1020 wl1271_debug(DEBUG_BOOT, "booting firmware %s", fw_name);
1008 1021
@@ -1021,6 +1034,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
1021 } 1034 }
1022 1035
1023 vfree(wl->fw); 1036 vfree(wl->fw);
1037 wl->fw_type = WL12XX_FW_TYPE_NONE;
1024 wl->fw_len = fw->size; 1038 wl->fw_len = fw->size;
1025 wl->fw = vmalloc(wl->fw_len); 1039 wl->fw = vmalloc(wl->fw_len);
1026 1040
@@ -1032,7 +1046,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
1032 1046
1033 memcpy(wl->fw, fw->data, wl->fw_len); 1047 memcpy(wl->fw, fw->data, wl->fw_len);
1034 ret = 0; 1048 ret = 0;
1035 1049 wl->fw_type = fw_type;
1036out: 1050out:
1037 release_firmware(fw); 1051 release_firmware(fw);
1038 1052
@@ -1160,7 +1174,7 @@ static void wl1271_recovery_work(struct work_struct *work)
1160 1174
1161 mutex_lock(&wl->mutex); 1175 mutex_lock(&wl->mutex);
1162 1176
1163 if (wl->state != WL1271_STATE_ON) 1177 if (wl->state != WL1271_STATE_ON || wl->plt)
1164 goto out_unlock; 1178 goto out_unlock;
1165 1179
1166 /* Avoid a recursive recovery */ 1180 /* Avoid a recursive recovery */
@@ -1261,7 +1275,7 @@ out:
1261 return ret; 1275 return ret;
1262} 1276}
1263 1277
1264static int wl1271_chip_wakeup(struct wl1271 *wl) 1278static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt)
1265{ 1279{
1266 int ret = 0; 1280 int ret = 0;
1267 1281
@@ -1316,11 +1330,9 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
1316 goto out; 1330 goto out;
1317 } 1331 }
1318 1332
1319 if (wl->fw == NULL) { 1333 ret = wl12xx_fetch_firmware(wl, plt);
1320 ret = wl1271_fetch_firmware(wl); 1334 if (ret < 0)
1321 if (ret < 0) 1335 goto out;
1322 goto out;
1323 }
1324 1336
1325 /* No NVS from netlink, try to get it from the filesystem */ 1337 /* No NVS from netlink, try to get it from the filesystem */
1326 if (wl->nvs == NULL) { 1338 if (wl->nvs == NULL) {
@@ -1352,7 +1364,7 @@ int wl1271_plt_start(struct wl1271 *wl)
1352 1364
1353 while (retries) { 1365 while (retries) {
1354 retries--; 1366 retries--;
1355 ret = wl1271_chip_wakeup(wl); 1367 ret = wl12xx_chip_wakeup(wl, true);
1356 if (ret < 0) 1368 if (ret < 0)
1357 goto power_off; 1369 goto power_off;
1358 1370
@@ -1364,7 +1376,8 @@ int wl1271_plt_start(struct wl1271 *wl)
1364 if (ret < 0) 1376 if (ret < 0)
1365 goto irq_disable; 1377 goto irq_disable;
1366 1378
1367 wl->state = WL1271_STATE_PLT; 1379 wl->plt = true;
1380 wl->state = WL1271_STATE_ON;
1368 wl1271_notice("firmware booted in PLT mode (%s)", 1381 wl1271_notice("firmware booted in PLT mode (%s)",
1369 wl->chip.fw_ver_str); 1382 wl->chip.fw_ver_str);
1370 1383
@@ -1413,7 +1426,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
1413 */ 1426 */
1414 wl1271_disable_interrupts(wl); 1427 wl1271_disable_interrupts(wl);
1415 mutex_lock(&wl->mutex); 1428 mutex_lock(&wl->mutex);
1416 if (wl->state != WL1271_STATE_PLT) { 1429 if (!wl->plt) {
1417 mutex_unlock(&wl->mutex); 1430 mutex_unlock(&wl->mutex);
1418 1431
1419 /* 1432 /*
@@ -1440,6 +1453,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
1440 wl1271_power_off(wl); 1453 wl1271_power_off(wl);
1441 wl->flags = 0; 1454 wl->flags = 0;
1442 wl->state = WL1271_STATE_OFF; 1455 wl->state = WL1271_STATE_OFF;
1456 wl->plt = false;
1443 wl->rx_counter = 0; 1457 wl->rx_counter = 0;
1444 mutex_unlock(&wl->mutex); 1458 mutex_unlock(&wl->mutex);
1445 1459
@@ -1995,7 +2009,7 @@ static bool wl12xx_init_fw(struct wl1271 *wl)
1995 2009
1996 while (retries) { 2010 while (retries) {
1997 retries--; 2011 retries--;
1998 ret = wl1271_chip_wakeup(wl); 2012 ret = wl12xx_chip_wakeup(wl, false);
1999 if (ret < 0) 2013 if (ret < 0)
2000 goto power_off; 2014 goto power_off;
2001 2015
@@ -2098,6 +2112,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
2098 goto out; 2112 goto out;
2099 } 2113 }
2100 2114
2115
2101 ret = wl12xx_init_vif_data(wl, vif); 2116 ret = wl12xx_init_vif_data(wl, vif);
2102 if (ret < 0) 2117 if (ret < 0)
2103 goto out; 2118 goto out;
@@ -5009,7 +5024,7 @@ out:
5009 5024
5010static void wl1271_unregister_hw(struct wl1271 *wl) 5025static void wl1271_unregister_hw(struct wl1271 *wl)
5011{ 5026{
5012 if (wl->state == WL1271_STATE_PLT) 5027 if (wl->plt)
5013 wl1271_plt_stop(wl); 5028 wl1271_plt_stop(wl);
5014 5029
5015 unregister_netdevice_notifier(&wl1271_dev_notifier); 5030 unregister_netdevice_notifier(&wl1271_dev_notifier);
@@ -5186,6 +5201,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
5186 spin_lock_init(&wl->wl_lock); 5201 spin_lock_init(&wl->wl_lock);
5187 5202
5188 wl->state = WL1271_STATE_OFF; 5203 wl->state = WL1271_STATE_OFF;
5204 wl->fw_type = WL12XX_FW_TYPE_NONE;
5189 mutex_init(&wl->mutex); 5205 mutex_init(&wl->mutex);
5190 5206
5191 /* Apply default driver configuration. */ 5207 /* Apply default driver configuration. */
@@ -5253,6 +5269,7 @@ static int wl1271_free_hw(struct wl1271 *wl)
5253 5269
5254 vfree(wl->fw); 5270 vfree(wl->fw);
5255 wl->fw = NULL; 5271 wl->fw = NULL;
5272 wl->fw_type = WL12XX_FW_TYPE_NONE;
5256 kfree(wl->nvs); 5273 kfree(wl->nvs);
5257 wl->nvs = NULL; 5274 wl->nvs = NULL;
5258 5275
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
index 4fbd2a722ffa..cfa6071704c5 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -113,7 +113,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
113 * In PLT mode we seem to get frames and mac80211 warns about them, 113 * In PLT mode we seem to get frames and mac80211 warns about them,
114 * workaround this by not retrieving them at all. 114 * workaround this by not retrieving them at all.
115 */ 115 */
116 if (unlikely(wl->state == WL1271_STATE_PLT)) 116 if (unlikely(wl->plt))
117 return -EINVAL; 117 return -EINVAL;
118 118
119 /* the data read starts with the descriptor */ 119 /* the data read starts with the descriptor */
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c
index ce3b9a99463e..1c0264ca021f 100644
--- a/drivers/net/wireless/wl12xx/sdio.c
+++ b/drivers/net/wireless/wl12xx/sdio.c
@@ -372,3 +372,5 @@ MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
372MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 372MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
373MODULE_FIRMWARE(WL127X_FW_NAME); 373MODULE_FIRMWARE(WL127X_FW_NAME);
374MODULE_FIRMWARE(WL128X_FW_NAME); 374MODULE_FIRMWARE(WL128X_FW_NAME);
375MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
376MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c
index 92caa7ce6053..5c2d4a0ef000 100644
--- a/drivers/net/wireless/wl12xx/spi.c
+++ b/drivers/net/wireless/wl12xx/spi.c
@@ -435,4 +435,6 @@ MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
435MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 435MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
436MODULE_FIRMWARE(WL127X_FW_NAME); 436MODULE_FIRMWARE(WL127X_FW_NAME);
437MODULE_FIRMWARE(WL128X_FW_NAME); 437MODULE_FIRMWARE(WL128X_FW_NAME);
438MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
439MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
438MODULE_ALIAS("spi:wl1271"); 440MODULE_ALIAS("spi:wl1271");
diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c
index b6b433e5562f..1e93bb9c0246 100644
--- a/drivers/net/wireless/wl12xx/testmode.c
+++ b/drivers/net/wireless/wl12xx/testmode.c
@@ -274,7 +274,7 @@ static int wl12xx_tm_cmd_get_mac(struct wl1271 *wl, struct nlattr *tb[])
274 274
275 mutex_lock(&wl->mutex); 275 mutex_lock(&wl->mutex);
276 276
277 if (wl->state != WL1271_STATE_PLT) { 277 if (!wl->plt) {
278 ret = -EINVAL; 278 ret = -EINVAL;
279 goto out; 279 goto out;
280 } 280 }
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 81af416d17da..9b48aa48cdca 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -37,6 +37,8 @@
37 37
38#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-4-sr.bin" 38#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-4-sr.bin"
39#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-4-sr.bin" 39#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-4-sr.bin"
40#define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin"
41#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
40 42
41/* 43/*
42 * wl127x and wl128x are using the same NVS file name. However, the 44 * wl127x and wl128x are using the same NVS file name. However, the
@@ -90,7 +92,12 @@
90enum wl1271_state { 92enum wl1271_state {
91 WL1271_STATE_OFF, 93 WL1271_STATE_OFF,
92 WL1271_STATE_ON, 94 WL1271_STATE_ON,
93 WL1271_STATE_PLT, 95};
96
97enum wl12xx_fw_type {
98 WL12XX_FW_TYPE_NONE,
99 WL12XX_FW_TYPE_NORMAL,
100 WL12XX_FW_TYPE_PLT,
94}; 101};
95 102
96enum wl1271_partition_type { 103enum wl1271_partition_type {
@@ -294,6 +301,8 @@ struct wl1271 {
294 spinlock_t wl_lock; 301 spinlock_t wl_lock;
295 302
296 enum wl1271_state state; 303 enum wl1271_state state;
304 enum wl12xx_fw_type fw_type;
305 bool plt;
297 struct mutex mutex; 306 struct mutex mutex;
298 307
299 unsigned long flags; 308 unsigned long flags;