Commit 3fcdab70 authored by Eliad Peller's avatar Eliad Peller Committed by Luciano Coelho
Browse files

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: default avatarGery Kahn <geryk@ti.com>
Signed-off-by: default avatarEliad Peller <eliad@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent f95f9aad
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl)
	if (ret < 0)
		goto out;

	if (wl->state == WL1271_STATE_ON &&
	if (wl->state == WL1271_STATE_ON && !wl->plt &&
	    time_after(jiffies, wl->stats.fw_stats_update +
		       msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) {
		wl1271_acx_statistics(wl, wl->stats.fw_stats);
+35 −18
Original line number Diff line number Diff line
@@ -993,16 +993,29 @@ out:
	return IRQ_HANDLED;
}

static int wl1271_fetch_firmware(struct wl1271 *wl)
static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
{
	const struct firmware *fw;
	const char *fw_name;
	enum wl12xx_fw_type fw_type;
	int ret;

	if (plt) {
		fw_type = WL12XX_FW_TYPE_PLT;
		if (wl->chip.id == CHIP_ID_1283_PG20)
			fw_name = WL128X_PLT_FW_NAME;
		else
			fw_name	= WL127X_PLT_FW_NAME;
	} else {
		fw_type = WL12XX_FW_TYPE_NORMAL;
		if (wl->chip.id == CHIP_ID_1283_PG20)
			fw_name = WL128X_FW_NAME;
		else
			fw_name	= WL127X_FW_NAME;
	}

	if (wl->fw_type == fw_type)
		return 0;

	wl1271_debug(DEBUG_BOOT, "booting firmware %s", fw_name);

@@ -1021,6 +1034,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
	}

	vfree(wl->fw);
	wl->fw_type = WL12XX_FW_TYPE_NONE;
	wl->fw_len = fw->size;
	wl->fw = vmalloc(wl->fw_len);

@@ -1032,7 +1046,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)

	memcpy(wl->fw, fw->data, wl->fw_len);
	ret = 0;

	wl->fw_type = fw_type;
out:
	release_firmware(fw);

@@ -1160,7 +1174,7 @@ static void wl1271_recovery_work(struct work_struct *work)

	mutex_lock(&wl->mutex);

	if (wl->state != WL1271_STATE_ON)
	if (wl->state != WL1271_STATE_ON || wl->plt)
		goto out_unlock;

	/* Avoid a recursive recovery */
@@ -1261,7 +1275,7 @@ out:
	return ret;
}

static int wl1271_chip_wakeup(struct wl1271 *wl)
static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt)
{
	int ret = 0;

@@ -1316,11 +1330,9 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
		goto out;
	}

	if (wl->fw == NULL) {
		ret = wl1271_fetch_firmware(wl);
	ret = wl12xx_fetch_firmware(wl, plt);
	if (ret < 0)
		goto out;
	}

	/* No NVS from netlink, try to get it from the filesystem */
	if (wl->nvs == NULL) {
@@ -1352,7 +1364,7 @@ int wl1271_plt_start(struct wl1271 *wl)

	while (retries) {
		retries--;
		ret = wl1271_chip_wakeup(wl);
		ret = wl12xx_chip_wakeup(wl, true);
		if (ret < 0)
			goto power_off;

@@ -1364,7 +1376,8 @@ int wl1271_plt_start(struct wl1271 *wl)
		if (ret < 0)
			goto irq_disable;

		wl->state = WL1271_STATE_PLT;
		wl->plt = true;
		wl->state = WL1271_STATE_ON;
		wl1271_notice("firmware booted in PLT mode (%s)",
			      wl->chip.fw_ver_str);

@@ -1413,7 +1426,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
	 */
	wl1271_disable_interrupts(wl);
	mutex_lock(&wl->mutex);
	if (wl->state != WL1271_STATE_PLT) {
	if (!wl->plt) {
		mutex_unlock(&wl->mutex);

		/*
@@ -1440,6 +1453,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
	wl1271_power_off(wl);
	wl->flags = 0;
	wl->state = WL1271_STATE_OFF;
	wl->plt = false;
	wl->rx_counter = 0;
	mutex_unlock(&wl->mutex);

@@ -1995,7 +2009,7 @@ static bool wl12xx_init_fw(struct wl1271 *wl)

	while (retries) {
		retries--;
		ret = wl1271_chip_wakeup(wl);
		ret = wl12xx_chip_wakeup(wl, false);
		if (ret < 0)
			goto power_off;

@@ -2098,6 +2112,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
		goto out;
	}


	ret = wl12xx_init_vif_data(wl, vif);
	if (ret < 0)
		goto out;
@@ -5009,7 +5024,7 @@ out:

static void wl1271_unregister_hw(struct wl1271 *wl)
{
	if (wl->state == WL1271_STATE_PLT)
	if (wl->plt)
		wl1271_plt_stop(wl);

	unregister_netdevice_notifier(&wl1271_dev_notifier);
@@ -5186,6 +5201,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
	spin_lock_init(&wl->wl_lock);

	wl->state = WL1271_STATE_OFF;
	wl->fw_type = WL12XX_FW_TYPE_NONE;
	mutex_init(&wl->mutex);

	/* Apply default driver configuration. */
@@ -5253,6 +5269,7 @@ static int wl1271_free_hw(struct wl1271 *wl)

	vfree(wl->fw);
	wl->fw = NULL;
	wl->fw_type = WL12XX_FW_TYPE_NONE;
	kfree(wl->nvs);
	wl->nvs = NULL;

+1 −1
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
	 * In PLT mode we seem to get frames and mac80211 warns about them,
	 * workaround this by not retrieving them at all.
	 */
	if (unlikely(wl->state == WL1271_STATE_PLT))
	if (unlikely(wl->plt))
		return -EINVAL;

	/* the data read starts with the descriptor */
+2 −0
Original line number Diff line number Diff line
@@ -372,3 +372,5 @@ MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
MODULE_FIRMWARE(WL127X_FW_NAME);
MODULE_FIRMWARE(WL128X_FW_NAME);
MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
+2 −0
Original line number Diff line number Diff line
@@ -435,4 +435,6 @@ MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
MODULE_FIRMWARE(WL127X_FW_NAME);
MODULE_FIRMWARE(WL128X_FW_NAME);
MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
MODULE_ALIAS("spi:wl1271");
Loading