summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2021-01-05 22:08:46 +0000
committerDaniel Golle <daniel@makrotopia.org>2021-01-05 22:19:42 +0000
commita17f5613c3622c85a7c8ab7db0e16be504cfff2a (patch)
treeeb9f2db8948aee9b447d61965298ce32179ee573
parent85bdda510e14df82a37099a8985da6474b3c7fcd (diff)
downloadiwinfo-a17f5613c3622c85a7c8ab7db0e16be504cfff2a.tar.gz
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>
-rw-r--r--hardware.txt1
-rw-r--r--iwinfo_nl80211.c30
2 files changed, 31 insertions, 0 deletions
diff --git a/hardware.txt b/hardware.txt
index 7255925..07a249b 100644
--- a/hardware.txt
+++ b/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"
diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c
index 2b2a043..52632de 100644
--- a/iwinfo_nl80211.c
+++ b/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);