iwinfo: detect QCA IPQ4019 WiSoC from FDT
authorDaniel Golle <daniel@makrotopia.org>
Tue, 5 Jan 2021 22:08:46 +0000 (22:08 +0000)
committerDaniel Golle <daniel@makrotopia.org>
Tue, 5 Jan 2021 22:19:42 +0000 (22:19 +0000)
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>
hardware.txt
iwinfo_nl80211.c

index 72559258b552fb30f2494d508e741916cda4378e..07a249b9df09b4673f1f276319a69b5b7987a549 100644 (file)
 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"
index 2b2a04386ee5faf8a38f8601d991795f503597c5..52632dee1a197b0d39132c1b56e67fea20aedecb 100644 (file)
@@ -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);