diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx/main.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 53 |
1 files changed, 35 insertions, 18 deletions
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 | ||