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

Commit d1b71f24 authored by Pascal Terjan's avatar Pascal Terjan Committed by Greg Kroah-Hartman
Browse files

rtl8xxxu: Fix device info for RTL8192EU devices



[ Upstream commit c240b044edefa3c3af4014a4030e017dd95b59a1 ]

Based on 2001:3319 and 2357:0109 which I used to test the fix and
0bda:818b and 2357:0108 for which I found efuse dumps online.

== 2357:0109 ==
=== Before ===
Vendor: Realtek
Product: \x03802.11n NI
Serial:
=== After ===
Vendor: Realtek
Product: 802.11n NIC
Serial not available.

== 2001:3319 ==
=== Before ===
Vendor: Realtek
Product: Wireless N
Serial: no USB Adap
=== After ===
Vendor: Realtek
Product: Wireless N Nano USB Adapter
Serial not available.

Signed-off-by: default avatarPascal Terjan <pterjan@google.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210424172959.1559890-1-pterjan@google.com


Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent cba5008c
Loading
Loading
Loading
Loading
+3 −8
Original line number Diff line number Diff line
@@ -861,15 +861,10 @@ struct rtl8192eu_efuse {
	u8 usb_optional_function;
	u8 res9[2];
	u8 mac_addr[ETH_ALEN];		/* 0xd7 */
	u8 res10[2];
	u8 vendor_name[7];
	u8 res11[2];
	u8 device_name[0x0b];		/* 0xe8 */
	u8 res12[2];
	u8 serial[0x0b];		/* 0xf5 */
	u8 res13[0x30];
	u8 device_info[80];
	u8 res11[3];
	u8 unknown[0x0d];		/* 0x130 */
	u8 res14[0xc3];
	u8 res12[0xc3];
};

struct rtl8xxxu_reg8val {
+53 −6
Original line number Diff line number Diff line
@@ -562,9 +562,43 @@ rtl8192e_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
	}
}

static void rtl8192eu_log_next_device_info(struct rtl8xxxu_priv *priv,
					   char *record_name,
					   char *device_info,
					   unsigned int *record_offset)
{
	char *record = device_info + *record_offset;

	/* A record is [ total length | 0x03 | value ] */
	unsigned char l = record[0];

	/*
	 * The whole device info section seems to be 80 characters, make sure
	 * we don't read further.
	 */
	if (*record_offset + l > 80) {
		dev_warn(&priv->udev->dev,
			 "invalid record length %d while parsing \"%s\" at offset %u.\n",
			 l, record_name, *record_offset);
		return;
	}

	if (l >= 2) {
		char value[80];

		memcpy(value, &record[2], l - 2);
		value[l - 2] = '\0';
		dev_info(&priv->udev->dev, "%s: %s\n", record_name, value);
		*record_offset = *record_offset + l;
	} else {
		dev_info(&priv->udev->dev, "%s not available.\n", record_name);
	}
}

static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv)
{
	struct rtl8192eu_efuse *efuse = &priv->efuse_wifi.efuse8192eu;
	unsigned int record_offset;
	int i;

	if (efuse->rtl_id != cpu_to_le16(0x8129))
@@ -612,12 +646,25 @@ static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv)
	priv->has_xtalk = 1;
	priv->xtalk = priv->efuse_wifi.efuse8192eu.xtal_k & 0x3f;

	dev_info(&priv->udev->dev, "Vendor: %.7s\n", efuse->vendor_name);
	dev_info(&priv->udev->dev, "Product: %.11s\n", efuse->device_name);
	if (memchr_inv(efuse->serial, 0xff, 11))
		dev_info(&priv->udev->dev, "Serial: %.11s\n", efuse->serial);
	else
		dev_info(&priv->udev->dev, "Serial not available.\n");
	/*
	 * device_info section seems to be laid out as records
	 * [ total length | 0x03 | value ] so:
	 * - vendor length + 2
	 * - 0x03
	 * - vendor string (not null terminated)
	 * - product length + 2
	 * - 0x03
	 * - product string (not null terminated)
	 * Then there is one or 2 0x00 on all the 4 devices I own or found
	 * dumped online.
	 * As previous version of the code handled an optional serial
	 * string, I now assume there may be a third record if the
	 * length is not 0.
	 */
	record_offset = 0;
	rtl8192eu_log_next_device_info(priv, "Vendor", efuse->device_info, &record_offset);
	rtl8192eu_log_next_device_info(priv, "Product", efuse->device_info, &record_offset);
	rtl8192eu_log_next_device_info(priv, "Serial", efuse->device_info, &record_offset);

	if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) {
		unsigned char *raw = priv->efuse_wifi.raw;