Commit d75ef1f8 authored by Hector Martin's avatar Hector Martin Committed by Kalle Valo
Browse files

wifi: brcmfmac: feature: Add support for setting feats based on WLC version



The "wlc_ver" iovar returns information on the WLC and EPI versions.
This can be used to determine whether the PMKID_V2 and _V3 features are
supported.

Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Acked-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: default avatarHector Martin <marcan@marcan.st>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230214092423.15175-4-marcan@marcan.st
parent 398ce273
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -126,6 +126,53 @@ static void brcmf_feat_firmware_overrides(struct brcmf_pub *drv)
	drv->feat_flags |= feat_flags;
}

struct brcmf_feat_wlcfeat {
	u16 min_ver_major;
	u16 min_ver_minor;
	u32 feat_flags;
};

static const struct brcmf_feat_wlcfeat brcmf_feat_wlcfeat_map[] = {
	{ 12, 0, BIT(BRCMF_FEAT_PMKID_V2) },
	{ 13, 0, BIT(BRCMF_FEAT_PMKID_V3) },
};

static void brcmf_feat_wlc_version_overrides(struct brcmf_pub *drv)
{
	struct brcmf_if *ifp = brcmf_get_ifp(drv, 0);
	const struct brcmf_feat_wlcfeat *e;
	struct brcmf_wlc_version_le ver;
	u32 feat_flags = 0;
	int i, err, major, minor;

	err = brcmf_fil_iovar_data_get(ifp, "wlc_ver", &ver, sizeof(ver));
	if (err)
		return;

	major = le16_to_cpu(ver.wlc_ver_major);
	minor = le16_to_cpu(ver.wlc_ver_minor);

	brcmf_dbg(INFO, "WLC version: %d.%d\n", major, minor);

	for (i = 0; i < ARRAY_SIZE(brcmf_feat_wlcfeat_map); i++) {
		e = &brcmf_feat_wlcfeat_map[i];
		if (major > e->min_ver_major ||
		    (major == e->min_ver_major &&
		     minor >= e->min_ver_minor)) {
			feat_flags |= e->feat_flags;
		}
	}

	if (!feat_flags)
		return;

	for (i = 0; i < BRCMF_FEAT_LAST; i++)
		if (feat_flags & BIT(i))
			brcmf_dbg(INFO, "enabling firmware feature: %s\n",
				  brcmf_feat_names[i]);
	drv->feat_flags |= feat_flags;
}

/**
 * brcmf_feat_iovar_int_get() - determine feature through iovar query.
 *
@@ -299,6 +346,7 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
		ifp->drvr->feat_flags &= ~drvr->settings->feature_disable;
	}

	brcmf_feat_wlc_version_overrides(drvr);
	brcmf_feat_firmware_overrides(drvr);

	/* set chip related quirks */
+3 −1
Original line number Diff line number Diff line
@@ -55,7 +55,9 @@
	BRCMF_FEAT_DEF(SAE) \
	BRCMF_FEAT_DEF(FWAUTH) \
	BRCMF_FEAT_DEF(DUMP_OBSS) \
	BRCMF_FEAT_DEF(SCAN_V2)
	BRCMF_FEAT_DEF(SCAN_V2) \
	BRCMF_FEAT_DEF(PMKID_V2) \
	BRCMF_FEAT_DEF(PMKID_V3)

/*
 * Quirks:
+25 −0
Original line number Diff line number Diff line
@@ -788,6 +788,31 @@ struct brcmf_rev_info_le {
	__le32 nvramrev;
};

/**
 * struct brcmf_wlc_version_le - firmware revision info.
 *
 * @version: structure version.
 * @length: structure length.
 * @epi_ver_major: EPI major version
 * @epi_ver_minor: EPI minor version
 * @epi_ver_rc: EPI rc version
 * @epi_ver_incr: EPI increment version
 * @wlc_ver_major: WLC major version
 * @wlc_ver_minor: WLC minor version
 */
struct brcmf_wlc_version_le {
	__le16 version;
	__le16 length;

	__le16 epi_ver_major;
	__le16 epi_ver_minor;
	__le16 epi_ver_rc;
	__le16 epi_ver_incr;

	__le16 wlc_ver_major;
	__le16 wlc_ver_minor;
};

/**
 * struct brcmf_assoclist_le - request assoc list.
 *