Browse Source

iwinfo: detect QCA IPQ4019 WiSoC from FDT

As it's the most reliable and straight forward way on modern platforms,
detect the hardware ID by checking the 'compatible'-string of non-PCI
(ie. built-in) devices.
As this is only relevant for WiSoCs, there won't be that many records,
so it's not worth making any larger structural changes. Hence just
match the compatible string and translate it into fake PCI IDs.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Daniel Golle 3 years ago
parent
commit
a17f5613c3
2 changed files with 31 additions and 0 deletions
  1. 1 0
      hardware.txt
  2. 30 0
      iwinfo_nl80211.c

+ 1 - 0
hardware.txt

@@ -160,6 +160,7 @@
 0x168c 0x003c 0x168c 0x3223    0      0  "Qualcomm Atheros" "QCA9880"
 0x168c 0x003c 0x1a56 0x1420    0      0  "Qualcomm Atheros" "QCA9862"
 0x168c 0x003c 0x19b6 0xd03c    0      0  "Mikrotik" "R11e-5HacT"
+0x168c 0x003c 0x168c 0x4019    0      0  "Qualcomm Atheros" "IPQ4019"
 0x168c 0x003c 0x19b6 0xd075    0      0  "Mikrotik" "R11e-5HacD"
 0x168c 0x0040 0x168c 0x0002    0      0  "Qualcomm Atheros" "QCA9990"
 0x168c 0x0046 0x168c 0xcafe    0      0  "Qualcomm Atheros" "QCA9984"

+ 30 - 0
iwinfo_nl80211.c

@@ -3109,6 +3109,31 @@ static int nl80211_get_mbssid_support(const char *ifname, int *buf)
 	return 0;
 }
 
+static int nl80211_hardware_id_from_fdt(struct iwinfo_hardware_id *id, const char *ifname)
+{
+	char *phy, compat[64], path[PATH_MAX];
+	int i;
+
+	/* Try to determine the phy name from the given interface */
+	phy = nl80211_ifname2phy(ifname);
+
+	snprintf(path, sizeof(path), "/sys/class/%s/%s/device/of_node/compatible",
+	         phy ? "ieee80211" : "net", phy ? phy : ifname);
+
+	if (nl80211_readstr(path, compat, sizeof(compat)) <= 0)
+		return -1;
+
+	if (!strcmp(compat, "qcom,ipq4019-wifi")) {
+		id->vendor_id = 0x168c;
+		id->device_id = 0x003c;
+		id->subsystem_vendor_id = 0x168c;
+		id->subsystem_device_id = 0x4019;
+	}
+
+	return (id->vendor_id && id->device_id) ? 0 : -1;
+}
+
+
 static int nl80211_get_hardware_id(const char *ifname, char *buf)
 {
 	struct iwinfo_hardware_id *id = (struct iwinfo_hardware_id *)buf;
@@ -3137,6 +3162,11 @@ static int nl80211_get_hardware_id(const char *ifname, char *buf)
 			*lookup[i].dest = strtoul(num, NULL, 16);
 	}
 
+	/* Failed to obtain hardware IDs, try FDT */
+	if (id->vendor_id == 0 || id->device_id == 0)
+		if (!nl80211_hardware_id_from_fdt(id, ifname))
+			return 0;
+
 	/* Failed to obtain hardware IDs, search board config */
 	if (id->vendor_id == 0 || id->device_id == 0)
 		return iwinfo_hardware_id_from_mtd(id);