/* * openuf - models.c * * Hardware descriptors for the emulated models. * * —— Why U6 In-Wall was chosen as the default model ———————————————— * * U6 In-Wall was selected because: * • 5 Gigabit Ethernet ports (eth0–eth4) → covers the majority of OpenWrt routers * with 4 LAN ports + 1 WAN port configured as independent interfaces * • WiFi 6 (802.11ax) on both 2.4 GHz and 5 GHz bands * • No PoE uplink (the router is powered by a power adapter) * • Firmware identifier recognized by UniFi Network 7.x+ * * The five ports are mapped as follows on a typical OpenWrt router: * eth0 → Port 1 (physical WAN port, reconfigured as LAN) * eth1 → Port 2 * eth2 → Port 3 * eth3 → Port 4 * eth4 → Port 5 (or the CPU port on SoCs without a physical eth4 interface) */ #include "ufmodel.h" #include /* ═══════════════════════════════════════════════════════════════════ U6 InWall — 5 ports GbE + WiFi 6 (2.4+5 GHz) ═══════════════════════════════════════════════════════════════════ */ static const uf_radio_t u6iw_radios[] = { /* name radio ch ht min max nss pwr caps ant he */ { "wifi0", "ng", 6, "HT40", 5, 23, 2, 20, 4, 0, true }, { "wifi1", "na", 36, "HT80", 5, 23, 2, 20, 7, 0, true }, }; /* 5 ports: port 0 as uplink, port 1-4 as LAN */ static const uf_port_t u6iw_ports[] = { /* ifname name idx poe_caps media speed up uplink duplex */ { "eth0", "eth0", 0, 255, "GE", 1000, false, true, true }, { "eth1", "eth1", 1, 0, "GE", 1000, false, false, true }, { "eth2", "eth2", 2, 0, "GE", 1000, false, false, true }, { "eth3", "eth3", 3, 0, "GE", 1000, false, false, true }, { "eth4", "eth4", 4, 4, "GE", 1000, false, false, true }, }; static const uf_eth_entry_t u6iw_eth[] = { { "eth0", 5 }, }; static const uf_radio_map_t u6iw_rmap[] = { { "ng", "radio0" }, { "na", "radio1" }, }; const uf_model_t model_u6inwall = { .model = "U6IW", .model_display = "U6 IW", .display_name = "U6-IW", .platform = "U6IW", .board_rev = 3, .has_eth1 = true, .fw_pre = "U6IW.mt7622_5_4.v", .fw_ver = "6.6.55.14430", .fw_buildtime = "230901.1200", .fw_factoryver = "6.6.55.14430", .radio_table = u6iw_radios, .radio_table_len = 2, .port_table = u6iw_ports, .port_table_len = 5, .ethernet_table = u6iw_eth, .ethernet_table_len = 1, .radio_map = u6iw_rmap, .radio_map_len = 2, }; /* ═══════════════════════════════════════════════════════════════════ U6 Lite — 1 port GbE + WiFi 6 (2.4+5 GHz) ═══════════════════════════════════════════════════════════════════ */ static const uf_radio_t u6lite_radios[] = { { "wifi0", "ng", 6, "HT40", 5, 23, 2, 20, 4, 0, true }, { "wifi1", "na", 36, "HT80", 5, 23, 2, 20, 7, 0, true }, }; static const uf_port_t u6lite_ports[] = { { "eth0", "eth0", 0, 255, "GE", 1000, false, true, true }, }; static const uf_eth_entry_t u6lite_eth[] = { { "eth0", 1 } }; static const uf_radio_map_t u6lite_rmap[] = { { "ng", "radio0" }, { "na", "radio1" }, }; const uf_model_t model_u6lite = { .model="U6LITE", .model_display="U6 Lite", .display_name="U6-Lite", .platform="U6LITE", .board_rev=3, .has_eth1=false, .fw_pre="U6LITE.mt7622_5_4.v", .fw_ver="6.6.55.14430", .fw_buildtime="230901.1200", .fw_factoryver="6.6.55.14430", .radio_table=u6lite_radios, .radio_table_len=2, .port_table=u6lite_ports, .port_table_len=1, .ethernet_table=u6lite_eth, .ethernet_table_len=1, .radio_map=u6lite_rmap, .radio_map_len=2, }; /* ═══════════════════════════════════════════════════════════════════ UAP Gen 1 — 1 port Fast Ethernet + WiFi N 2.4 GHz ═══════════════════════════════════════════════════════════════════ */ static const uf_radio_t uapg1_radios[] = { { "wifi0", "ng", 6, "HT20", 5, 23, 2, 20, 4, 0, false }, }; static const uf_port_t uapg1_ports[] = { { "eth0", "eth0", 0, 255, "GE", 100, false, true, true }, }; static const uf_eth_entry_t uapg1_eth[] = { { "eth0", 1 } }; static const uf_radio_map_t uapg1_rmap[] = { { "ng", "radio0" } }; const uf_model_t model_uapg1 = { .model="BZ2", .model_display="UAP", .display_name="UAP", .platform="BZ2", .board_rev=1, .has_eth1=false, .fw_pre="BZ2.ar7240.v", .fw_ver="6.6.55.14430", .fw_buildtime="230901.1200", .fw_factoryver="6.6.55.14430", .radio_table=uapg1_radios, .radio_table_len=1, .port_table=uapg1_ports, .port_table_len=1, .ethernet_table=uapg1_eth, .ethernet_table_len=1, .radio_map=uapg1_rmap, .radio_map_len=1, }; /* ═══════════════════════════════════════════════════════════════════ UAP Gen 1 LR ═══════════════════════════════════════════════════════════════════ */ static const uf_radio_t uapg1lr_radios[] = { { "wifi0", "ng", 6, "HT20", 5, 23, 2, 22, 4, 0, false }, }; static const uf_port_t uapg1lr_ports[] = { { "eth0", "eth0", 0, 255, "GE", 100, false, true, true }, }; static const uf_eth_entry_t uapg1lr_eth[] = { { "eth0", 1 } }; static const uf_radio_map_t uapg1lr_rmap[] = { { "ng", "radio0" } }; const uf_model_t model_uapg1lr = { .model="BZ2LR", .model_display="UAP-LR", .display_name="UAP-LR", .platform="BZ2LR", .board_rev=1, .has_eth1=false, .fw_pre="BZ2LR.ar7240.v", .fw_ver="6.6.55.14430", .fw_buildtime="230901.1200", .fw_factoryver="6.6.55.14430", .radio_table=uapg1lr_radios, .radio_table_len=1, .port_table=uapg1lr_ports, .port_table_len=1, .ethernet_table=uapg1lr_eth, .ethernet_table_len=1, .radio_map=uapg1lr_rmap, .radio_map_len=1, }; /* ═══════════════════════════════════════════════════════════════════ UAP AC LR — 1 port GbE + WiFi AC dual-band ═══════════════════════════════════════════════════════════════════ */ static const uf_radio_t uapg2aclr_radios[] = { { "wifi0", "ng", 6, "HT40", 5, 23, 2, 20, 4, 0, false }, { "wifi1", "na", 36, "HT80", 5, 23, 2, 20, 7, 0, false }, }; static const uf_port_t uapg2aclr_ports[] = { { "eth0", "eth0", 0, 255, "GE", 1000, false, true, true }, }; static const uf_eth_entry_t uapg2aclr_eth[] = { { "eth0", 1 } }; static const uf_radio_map_t uapg2aclr_rmap[] = { { "ng", "radio0" }, { "na", "radio1" }, }; const uf_model_t model_uapg2aclr = { .model="U2IW", .model_display="UAP-AC-LR", .display_name="UAP-AC-LR", .platform="U2IW", .board_rev=2, .has_eth1=false, .fw_pre="U2IW.qca956x.v", .fw_ver="6.7.54.15663", .fw_buildtime="260615.1200", .fw_factoryver="6.7.54.15663", .radio_table=uapg2aclr_radios, .radio_table_len=2, .port_table=uapg2aclr_ports, .port_table_len=1, .ethernet_table=uapg2aclr_eth, .ethernet_table_len=1, .radio_map=uapg2aclr_rmap, .radio_map_len=2, }; /* ─── Model Registry ─────────────────────────────────────── */ static const uf_model_t *all_models[] = { &model_u6inwall, &model_u6lite, &model_uapg1, &model_uapg1lr, &model_uapg2aclr, NULL }; const uf_model_t *ufmodel_find(const char *name) { if (!name) return &model_u6inwall; for (int i = 0; all_models[i]; i++) { const uf_model_t *m = all_models[i]; if (!strcasecmp(name, m->model) || !strcasecmp(name, m->model_display) || !strcasecmp(name, m->display_name) || !strcasecmp(name, m->platform)) return m; } /* Configuration aliases */ if (!strcasecmp(name, "u6-inwall") || !strcasecmp(name, "u6iw")) return &model_u6inwall; if (!strcasecmp(name, "u6-lite")) return &model_u6lite; if (!strcasecmp(name, "uapg1")) return &model_uapg1; if (!strcasecmp(name, "uapg1-lr")) return &model_uapg1lr; if (!strcasecmp(name, "uapg2-ac-lr")) return &model_uapg2aclr; return &model_u6inwall; /* default */ }