diff options
author | Eliad Peller <eliad@wizery.com> | 2012-02-06 05:47:54 -0500 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2012-02-15 01:38:35 -0500 |
commit | 3fcdab7066a31ae90ac2beba7d38e8e606374998 (patch) | |
tree | 17cec887b8fa6dc97c31ce0d5c820f9874cfc888 | |
parent | f95f9aad150238236b2338efa60a14891081026e (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.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 53 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/rx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/sdio.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/spi.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/testmode.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 11 |
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 | ||
996 | static int wl1271_fetch_firmware(struct wl1271 *wl) | 996 | static 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; | |
1036 | out: | 1050 | out: |
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 | ||
1264 | static int wl1271_chip_wakeup(struct wl1271 *wl) | 1278 | static 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 | ||
5010 | static void wl1271_unregister_hw(struct wl1271 *wl) | 5025 | static 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>"); | |||
372 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 372 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); |
373 | MODULE_FIRMWARE(WL127X_FW_NAME); | 373 | MODULE_FIRMWARE(WL127X_FW_NAME); |
374 | MODULE_FIRMWARE(WL128X_FW_NAME); | 374 | MODULE_FIRMWARE(WL128X_FW_NAME); |
375 | MODULE_FIRMWARE(WL127X_PLT_FW_NAME); | ||
376 | MODULE_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>"); | |||
435 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 435 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); |
436 | MODULE_FIRMWARE(WL127X_FW_NAME); | 436 | MODULE_FIRMWARE(WL127X_FW_NAME); |
437 | MODULE_FIRMWARE(WL128X_FW_NAME); | 437 | MODULE_FIRMWARE(WL128X_FW_NAME); |
438 | MODULE_FIRMWARE(WL127X_PLT_FW_NAME); | ||
439 | MODULE_FIRMWARE(WL128X_PLT_FW_NAME); | ||
438 | MODULE_ALIAS("spi:wl1271"); | 440 | MODULE_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 @@ | |||
90 | enum wl1271_state { | 92 | enum wl1271_state { |
91 | WL1271_STATE_OFF, | 93 | WL1271_STATE_OFF, |
92 | WL1271_STATE_ON, | 94 | WL1271_STATE_ON, |
93 | WL1271_STATE_PLT, | 95 | }; |
96 | |||
97 | enum wl12xx_fw_type { | ||
98 | WL12XX_FW_TYPE_NONE, | ||
99 | WL12XX_FW_TYPE_NORMAL, | ||
100 | WL12XX_FW_TYPE_PLT, | ||
94 | }; | 101 | }; |
95 | 102 | ||
96 | enum wl1271_partition_type { | 103 | enum 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; |