Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a1ccce8 authored by Arik Nemtsov's avatar Arik Nemtsov Committed by John W. Linville
Browse files

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: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 01b3c0e4
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -646,6 +646,9 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
		/* read data preparation is only needed by wl127x */
		wl->ops->prepare_read = wl127x_prepare_read;

		wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, WL127X_IFTYPE_VER,
				      WL127X_MAJOR_VER, WL127X_SUBTYPE_VER,
				      WL127X_MINOR_VER);
		break;

	case CHIP_ID_1271_PG20:
@@ -663,6 +666,9 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
		/* read data preparation is only needed by wl127x */
		wl->ops->prepare_read = wl127x_prepare_read;

		wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, WL127X_IFTYPE_VER,
				      WL127X_MAJOR_VER, WL127X_SUBTYPE_VER,
				      WL127X_MINOR_VER);
		break;

	case CHIP_ID_1283_PG20:
@@ -676,6 +682,9 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
		wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
			      WLCORE_QUIRK_TKIP_HEADER_SPACE;

		wlcore_set_min_fw_ver(wl, WL128X_CHIP_VER, WL128X_IFTYPE_VER,
				      WL128X_MAJOR_VER, WL128X_SUBTYPE_VER,
				      WL128X_MINOR_VER);
		break;
	case CHIP_ID_1283_PG10:
	default:
+14 −0
Original line number Diff line number Diff line
@@ -24,6 +24,20 @@

#include "conf.h"

/* minimum FW required for driver for wl127x */
#define WL127X_CHIP_VER		6
#define WL127X_IFTYPE_VER	3
#define WL127X_MAJOR_VER	10
#define WL127X_SUBTYPE_VER	2
#define WL127X_MINOR_VER	115

/* minimum FW required for driver for wl128x */
#define WL128X_CHIP_VER		7
#define WL128X_IFTYPE_VER	3
#define WL128X_MAJOR_VER	10
#define WL128X_SUBTYPE_VER	2
#define WL128X_MINOR_VER	115

struct wl127x_rx_mem_pool_addr {
	u32 addr;
	u32 addr_extra;
+4 −0
Original line number Diff line number Diff line
@@ -611,6 +611,10 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
			      WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
			      WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN |
			      WLCORE_QUIRK_TX_PAD_LAST_FRAME;

		wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER, WL18XX_IFTYPE_VER,
				      WL18XX_MAJOR_VER, WL18XX_SUBTYPE_VER,
				      WL18XX_MINOR_VER);
		break;
	case CHIP_ID_185x_PG10:
		wl1271_warning("chip id 0x%x (185x PG10) is deprecated",
+7 −0
Original line number Diff line number Diff line
@@ -24,6 +24,13 @@

#include "conf.h"

/* minimum FW required for driver */
#define WL18XX_CHIP_VER		8
#define WL18XX_IFTYPE_VER	2
#define WL18XX_MAJOR_VER	0
#define WL18XX_SUBTYPE_VER	0
#define WL18XX_MINOR_VER	100

#define WL18XX_CMD_MAX_SIZE          740

struct wl18xx_priv {
+51 −0
Original line number Diff line number Diff line
@@ -81,6 +81,53 @@ static int wlcore_boot_parse_fw_ver(struct wl1271 *wl,
	return ret;
}

static int wlcore_validate_fw_ver(struct wl1271 *wl)
{
	unsigned int *fw_ver = wl->chip.fw_ver;
	unsigned int *min_ver = wl->min_fw_ver;

	/* the chip must be exactly equal */
	if (min_ver[FW_VER_CHIP] != fw_ver[FW_VER_CHIP])
		goto fail;

	/* always check the next digit if all previous ones are equal */

	if (min_ver[FW_VER_IF_TYPE] < fw_ver[FW_VER_IF_TYPE])
		goto out;
	else if (min_ver[FW_VER_IF_TYPE] > fw_ver[FW_VER_IF_TYPE])
		goto fail;

	if (min_ver[FW_VER_MAJOR] < fw_ver[FW_VER_MAJOR])
		goto out;
	else if (min_ver[FW_VER_MAJOR] > fw_ver[FW_VER_MAJOR])
		goto fail;

	if (min_ver[FW_VER_SUBTYPE] < fw_ver[FW_VER_SUBTYPE])
		goto out;
	else if (min_ver[FW_VER_SUBTYPE] > fw_ver[FW_VER_SUBTYPE])
		goto fail;

	if (min_ver[FW_VER_MINOR] < fw_ver[FW_VER_MINOR])
		goto out;
	else if (min_ver[FW_VER_MINOR] > fw_ver[FW_VER_MINOR])
		goto fail;

out:
	return 0;

fail:
	wl1271_error("Your WiFi FW version (%u.%u.%u.%u.%u) is outdated.\n"
		     "Please use at least FW %u.%u.%u.%u.%u.\n"
		     "You can get more information at:\n"
		     "http://wireless.kernel.org/en/users/Drivers/wl12xx",
		     fw_ver[FW_VER_CHIP], fw_ver[FW_VER_IF_TYPE],
		     fw_ver[FW_VER_MAJOR], fw_ver[FW_VER_SUBTYPE],
		     fw_ver[FW_VER_MINOR], min_ver[FW_VER_CHIP],
		     min_ver[FW_VER_IF_TYPE], min_ver[FW_VER_MAJOR],
		     min_ver[FW_VER_SUBTYPE], min_ver[FW_VER_MINOR]);
	return -EINVAL;
}

static int wlcore_boot_static_data(struct wl1271 *wl)
{
	struct wl1271_static_data *static_data;
@@ -101,6 +148,10 @@ static int wlcore_boot_static_data(struct wl1271 *wl)
	if (ret < 0)
		goto out_free;

	ret = wlcore_validate_fw_ver(wl);
	if (ret < 0)
		goto out_free;

	ret = wlcore_handle_static_data(wl, static_data);
	if (ret < 0)
		goto out_free;
Loading