200 lines
9.3 KiB
C
200 lines
9.3 KiB
C
/*
|
||
* 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 <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 */
|
||
}
|