Files
OpenUniFi/src/models.c
T
2026-07-12 00:43:46 +00:00

200 lines
9.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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 (eth0eth4) → 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 <string.h>
/* ═══════════════════════════════════════════════════════════════════
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 */
}