|
| 1 | +From d818f80f3ced5cba7612c987e8443d54ada9c74d Mon Sep 17 00:00:00 2001 |
| 2 | +From: Jo-Philipp Wich < [email protected]> |
| 3 | +Date: Mon, 9 Jan 2023 18:00:34 +0100 |
| 4 | +Subject: [iwinfo PATCH] devices: add support for declaring compatible matched |
| 5 | + devices |
| 6 | + |
| 7 | +Some device have embedded wifi card that are not connected with usb or |
| 8 | +internall with pci. Such device have fake device_id and only the |
| 9 | +vendor_id actually reflect something real but internally they don't have |
| 10 | +any id and are just matched by the node compatible binding in DT. |
| 11 | + |
| 12 | +We currently match this with a big if-else to match the single devices |
| 13 | +but this can be improved and be matched directly in devices.txt |
| 14 | + |
| 15 | +Rework this so that we can drop the big if-else and move the matching |
| 16 | +from devices.txt |
| 17 | + |
| 18 | +When a device is matched using compatible in iwinfo the hardware will be |
| 19 | +flagged as embedded and won't print empty ids. |
| 20 | + |
| 21 | +Tested-by: Christian Marangi < [email protected]> |
| 22 | +Co-developed-by: Christian Marangi < [email protected]> |
| 23 | +Signed-off-by: Jo-Philipp Wich < [email protected]> |
| 24 | +Signed-off-by: Christian Marangi < [email protected]> |
| 25 | +--- |
| 26 | + devices.txt | 13 +++++++++ |
| 27 | + include/iwinfo.h | 2 ++ |
| 28 | + iwinfo_cli.c | 9 ++++-- |
| 29 | + iwinfo_nl80211.c | 71 ++++++------------------------------------------ |
| 30 | + iwinfo_utils.c | 8 +++++- |
| 31 | + 5 files changed, 36 insertions(+), 67 deletions(-) |
| 32 | + |
| 33 | +diff --git a/devices.txt b/devices.txt |
| 34 | +index d76bbca..93938b5 100644 |
| 35 | +--- a/devices.txt |
| 36 | ++++ b/devices.txt |
| 37 | +@@ -206,3 +206,16 @@ |
| 38 | + # USB devices |
| 39 | + # 0x0000 | 0x0000 | vendor id | product id | ... |
| 40 | + 0x0000 0x0000 0x0e8d 0x7961 0 0 "MediaTek" "MT7921AU" |
| 41 | ++ |
| 42 | ++# FDT compatible strings |
| 43 | ++# "compatible" | txpower offset | frequency offset | ... |
| 44 | ++"qca,ar9130-wmac" 0 0 "Atheros" "AR9130" |
| 45 | ++"qca,ar9330-wmac" 0 0 "Atheros" "AR9330" |
| 46 | ++"qca,ar9340-wmac" 0 0 "Atheros" "AR9340" |
| 47 | ++"qca,qca9530-wmac" 0 0 "Qualcomm Atheros" "QCA9530" |
| 48 | ++"qca,qca9550-wmac" 0 0 "Qualcomm Atheros" "QCA9550" |
| 49 | ++"qca,qca9560-wmac" 0 0 "Qualcomm Atheros" "QCA9560" |
| 50 | ++"qcom,ipq4019-wifi" 0 0 "Qualcomm Atheros" "IPQ4019" |
| 51 | ++"qcom,ipq8074-wifi" 0 0 "Qualcomm Atheros" "IPQ8074" |
| 52 | ++"mediatek,mt7622-wmac" 0 0 "MediaTek" "MT7622" |
| 53 | ++"mediatek,mt7986-wmac" 0 0 "MediaTek" "MT7986" |
| 54 | +diff --git a/include/iwinfo.h b/include/iwinfo.h |
| 55 | +index e87ad18..4b63f1e 100644 |
| 56 | +--- a/include/iwinfo.h |
| 57 | ++++ b/include/iwinfo.h |
| 58 | +@@ -243,6 +243,7 @@ struct iwinfo_hardware_id { |
| 59 | + uint16_t device_id; |
| 60 | + uint16_t subsystem_vendor_id; |
| 61 | + uint16_t subsystem_device_id; |
| 62 | ++ char compatible[128]; |
| 63 | + }; |
| 64 | + |
| 65 | + struct iwinfo_hardware_entry { |
| 66 | +@@ -254,6 +255,7 @@ struct iwinfo_hardware_entry { |
| 67 | + uint16_t subsystem_device_id; |
| 68 | + int16_t txpower_offset; |
| 69 | + int16_t frequency_offset; |
| 70 | ++ char compatible[128]; |
| 71 | + }; |
| 72 | + |
| 73 | + extern const struct iwinfo_iso3166_label IWINFO_ISO3166_NAMES[]; |
| 74 | +diff --git a/iwinfo_cli.c b/iwinfo_cli.c |
| 75 | +index d70f7fb..9b3e8e3 100644 |
| 76 | +--- a/iwinfo_cli.c |
| 77 | ++++ b/iwinfo_cli.c |
| 78 | +@@ -335,9 +335,12 @@ static char * print_hardware_id(const struct iwinfo_ops *iw, const char *ifname) |
| 79 | + |
| 80 | + if (!iw->hardware_id(ifname, (char *)&ids)) |
| 81 | + { |
| 82 | +- snprintf(buf, sizeof(buf), "%04X:%04X %04X:%04X", |
| 83 | +- ids.vendor_id, ids.device_id, |
| 84 | +- ids.subsystem_vendor_id, ids.subsystem_device_id); |
| 85 | ++ if (strlen(ids.compatible) > 0) |
| 86 | ++ snprintf(buf, sizeof(buf), "embedded"); |
| 87 | ++ else |
| 88 | ++ snprintf(buf, sizeof(buf), "%04X:%04X %04X:%04X", |
| 89 | ++ ids.vendor_id, ids.device_id, |
| 90 | ++ ids.subsystem_vendor_id, ids.subsystem_device_id); |
| 91 | + } |
| 92 | + else |
| 93 | + { |
| 94 | +diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c |
| 95 | +index 916192f..a9e2adf 100644 |
| 96 | +--- a/iwinfo_nl80211.c |
| 97 | ++++ b/iwinfo_nl80211.c |
| 98 | +@@ -3445,7 +3445,7 @@ static int nl80211_get_mbssid_support(const char *ifname, int *buf) |
| 99 | + |
| 100 | + static int nl80211_hardware_id_from_fdt(struct iwinfo_hardware_id *id, const char *ifname) |
| 101 | + { |
| 102 | +- char *phy, compat[64], path[PATH_MAX]; |
| 103 | ++ char *phy, path[PATH_MAX]; |
| 104 | + |
| 105 | + /* Try to determine the phy name from the given interface */ |
| 106 | + phy = nl80211_ifname2phy(ifname); |
| 107 | +@@ -3453,62 +3453,10 @@ static int nl80211_hardware_id_from_fdt(struct iwinfo_hardware_id *id, const cha |
| 108 | + snprintf(path, sizeof(path), "/sys/class/%s/%s/device/of_node/compatible", |
| 109 | + phy ? "ieee80211" : "net", phy ? phy : ifname); |
| 110 | + |
| 111 | +- if (nl80211_readstr(path, compat, sizeof(compat)) <= 0) |
| 112 | ++ if (nl80211_readstr(path, id->compatible, sizeof(id->compatible)) <= 0) |
| 113 | + return -1; |
| 114 | + |
| 115 | +- if (!strcmp(compat, "qca,ar9130-wmac")) { |
| 116 | +- id->vendor_id = 0x168c; |
| 117 | +- id->device_id = 0x0029; |
| 118 | +- id->subsystem_vendor_id = 0x168c; |
| 119 | +- id->subsystem_device_id = 0x9130; |
| 120 | +- } else if (!strcmp(compat, "qca,ar9330-wmac")) { |
| 121 | +- id->vendor_id = 0x168c; |
| 122 | +- id->device_id = 0x0030; |
| 123 | +- id->subsystem_vendor_id = 0x168c; |
| 124 | +- id->subsystem_device_id = 0x9330; |
| 125 | +- } else if (!strcmp(compat, "qca,ar9340-wmac")) { |
| 126 | +- id->vendor_id = 0x168c; |
| 127 | +- id->device_id = 0x0030; |
| 128 | +- id->subsystem_vendor_id = 0x168c; |
| 129 | +- id->subsystem_device_id = 0x9340; |
| 130 | +- } else if (!strcmp(compat, "qca,qca9530-wmac")) { |
| 131 | +- id->vendor_id = 0x168c; |
| 132 | +- id->device_id = 0x0033; |
| 133 | +- id->subsystem_vendor_id = 0x168c; |
| 134 | +- id->subsystem_device_id = 0x9530; |
| 135 | +- } else if (!strcmp(compat, "qca,qca9550-wmac")) { |
| 136 | +- id->vendor_id = 0x168c; |
| 137 | +- id->device_id = 0x0033; |
| 138 | +- id->subsystem_vendor_id = 0x168c; |
| 139 | +- id->subsystem_device_id = 0x9550; |
| 140 | +- } else if (!strcmp(compat, "qca,qca9560-wmac")) { |
| 141 | +- id->vendor_id = 0x168c; |
| 142 | +- id->device_id = 0x0033; |
| 143 | +- id->subsystem_vendor_id = 0x168c; |
| 144 | +- id->subsystem_device_id = 0x9560; |
| 145 | +- } else if (!strcmp(compat, "qcom,ipq4019-wifi")) { |
| 146 | +- id->vendor_id = 0x168c; |
| 147 | +- id->device_id = 0x003c; |
| 148 | +- id->subsystem_vendor_id = 0x168c; |
| 149 | +- id->subsystem_device_id = 0x4019; |
| 150 | +- } else if (!strcmp(compat, "qcom,ipq8074-wifi")) { |
| 151 | +- id->vendor_id = 0x168c; |
| 152 | +- id->device_id = 0x8074; |
| 153 | +- id->subsystem_vendor_id = 0x168c; |
| 154 | +- id->subsystem_device_id = 0x8074; |
| 155 | +- } else if (!strcmp(compat, "mediatek,mt7622-wmac")) { |
| 156 | +- id->vendor_id = 0x14c3; |
| 157 | +- id->device_id = 0x7622; |
| 158 | +- id->subsystem_vendor_id = 0x14c3; |
| 159 | +- id->subsystem_device_id = 0x7622; |
| 160 | +- } else if (!strcmp(compat, "mediatek,mt7986-wmac")) { |
| 161 | +- id->vendor_id = 0x14c3; |
| 162 | +- id->device_id = 0x7986; |
| 163 | +- id->subsystem_vendor_id = 0x14c3; |
| 164 | +- id->subsystem_device_id = 0x7986; |
| 165 | +- } |
| 166 | +- |
| 167 | +- return (id->vendor_id && id->device_id) ? 0 : -1; |
| 168 | ++ return 0; |
| 169 | + } |
| 170 | + |
| 171 | + |
| 172 | +@@ -3542,16 +3490,13 @@ static int nl80211_get_hardware_id(const char *ifname, char *buf) |
| 173 | + *lookup[i].dest = strtoul(num, NULL, 16); |
| 174 | + } |
| 175 | + |
| 176 | +- /* Failed to obtain hardware IDs, try FDT */ |
| 177 | +- if (id->vendor_id == 0 && id->device_id == 0 && |
| 178 | +- id->subsystem_vendor_id == 0 && id->subsystem_device_id == 0) |
| 179 | +- if (!nl80211_hardware_id_from_fdt(id, ifname)) |
| 180 | +- return 0; |
| 181 | +- |
| 182 | +- /* Failed to obtain hardware IDs, search board config */ |
| 183 | ++ /* Failed to obtain hardware PCI/USB IDs... */ |
| 184 | + if (id->vendor_id == 0 && id->device_id == 0 && |
| 185 | + id->subsystem_vendor_id == 0 && id->subsystem_device_id == 0) |
| 186 | +- return iwinfo_hardware_id_from_mtd(id); |
| 187 | ++ /* ... first fallback to FDT ... */ |
| 188 | ++ if (nl80211_hardware_id_from_fdt(id, ifname) == -1) |
| 189 | ++ /* ... then board config */ |
| 190 | ++ return iwinfo_hardware_id_from_mtd(id); |
| 191 | + |
| 192 | + return 0; |
| 193 | + } |
| 194 | +diff --git a/iwinfo_utils.c b/iwinfo_utils.c |
| 195 | +index a342b6a..ecd1dff 100644 |
| 196 | +--- a/iwinfo_utils.c |
| 197 | ++++ b/iwinfo_utils.c |
| 198 | +@@ -286,7 +286,10 @@ struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id) |
| 199 | + &e.vendor_id, &e.device_id, |
| 200 | + &e.subsystem_vendor_id, &e.subsystem_device_id, |
| 201 | + &e.txpower_offset, &e.frequency_offset, |
| 202 | +- e.vendor_name, e.device_name) < 8) |
| 203 | ++ e.vendor_name, e.device_name) != 8 && |
| 204 | ++ sscanf(buf, "\"%127[^\"]\" %hd %hd \"%63[^\"]\" \"%63[^\"]\"", |
| 205 | ++ e.compatible, &e.txpower_offset, &e.frequency_offset, |
| 206 | ++ e.vendor_name, e.device_name) != 5) |
| 207 | + continue; |
| 208 | + |
| 209 | + if ((e.vendor_id != 0xffff) && (e.vendor_id != id->vendor_id)) |
| 210 | +@@ -303,6 +306,9 @@ struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id) |
| 211 | + (e.subsystem_device_id != id->subsystem_device_id)) |
| 212 | + continue; |
| 213 | + |
| 214 | ++ if (strcmp(e.compatible, id->compatible)) |
| 215 | ++ continue; |
| 216 | ++ |
| 217 | + rv = &e; |
| 218 | + break; |
| 219 | + } |
| 220 | +-- |
| 221 | +2.37.2 |
| 222 | + |
0 commit comments