#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.11 2025/10/03 14:05:12 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/conf.h>
#include <sys/device.h>
#include <net/if_ether.h>
#include <mips/cpu.h>
#include <mips/locore.h>
#include <evbmips/cavium/octeon_uboot.h>
static void findroot(void);
void
cpu_configure(void)
{
intr_init();
(void)splhigh();
if (config_rootfound("mainbus", NULL) == NULL)
panic("no mainbus found");
(void)spl0();
KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE);
}
void
cpu_rootconf(void)
{
#ifndef MEMORY_DISK_IS_ROOT
findroot();
#endif
printf("boot device: %s\n",
booted_device ? device_xname(booted_device) : "<unknown>");
rootconf();
}
extern int netboot;
static void
findroot(void)
{
device_t dv;
deviter_t di;
if (booted_device)
return;
if (rootspec && *rootspec) {
if (strncmp(rootspec, "octeth", 6) == 0) {
static char buf[sizeof("cnmacXX")];
const char *cp = &rootspec[strlen("octeth")];
KASSERT(strlen(cp) < sizeof("XX"));
snprintf(buf, sizeof(buf), "cnmac%s", cp);
rootspec = buf;
}
if (strncmp(rootspec, "cnmac", 5) == 0) {
rootfstype = "nfs";
netboot = 1;
return;
}
}
if (netboot == 0) {
for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
dv = deviter_next(&di)) {
if (device_class(dv) == DV_DISK &&
device_is_a(dv, "sd"))
booted_device = dv;
}
deviter_release(&di);
}
booted_partition = 0;
return;
}
static void
prop_set_cnmac(device_t dev)
{
prop_dictionary_t dict = device_properties(dev);
prop_number_t pn;
uint8_t enaddr[ETHER_ADDR_LEN];
uint32_t mac_lo;
int unit = device_unit(dev);
memcpy(enaddr, octeon_btinfo.obt_mac_addr_base,
sizeof(enaddr));
mac_lo = enaddr[3] << 16;
mac_lo += enaddr[4] << 8;
mac_lo += enaddr[5];
KASSERT(unit < octeon_btinfo.obt_mac_addr_count);
mac_lo += unit;
enaddr[3] = (mac_lo >> 16) & 0xff;
enaddr[4] = (mac_lo >> 8) & 0xff;
enaddr[5] = mac_lo & 0xff;
device_setprop_data(dev, "mac-address", enaddr, sizeof(enaddr));
switch (octeon_btinfo.obt_board_type) {
case BOARD_TYPE_UBIQUITI_E100:
case BOARD_TYPE_UBIQUITI_E120:
pn = prop_number_create_signed(7 - unit);
break;
case BOARD_TYPE_UBIQUITI_E300:
pn = prop_number_create_signed(4 + device_unit(dev));
break;
default:
pn = prop_number_create_signed(-1);
break;
}
KASSERT(pn != NULL);
prop_dictionary_set_and_rel(dict, "phy-addr", pn);
}
static void
prop_set_octeon_gmx(device_t dev)
{
prop_dictionary_t dict = device_properties(dev);
prop_number_t tx, rx;
tx = rx = NULL;
switch (octeon_btinfo.obt_board_type) {
case BOARD_TYPE_UBIQUITI_E100:
case BOARD_TYPE_UBIQUITI_E120:
tx = prop_number_create_signed(16);
rx = prop_number_create_signed(0);
break;
}
if (tx)
prop_dictionary_set_and_rel(dict, "rgmii-tx", tx);
if (rx)
prop_dictionary_set_and_rel(dict, "rgmii-rx", rx);
}
void
device_register(device_t dev, void *aux)
{
if ((booted_device == NULL) && (netboot == 1))
if (device_class(dev) == DV_IFNET)
booted_device = dev;
if (device_is_a(dev, "cnmac")) {
prop_set_cnmac(dev);
} else if (device_is_a(dev, "octgmx")) {
prop_set_octeon_gmx(dev);
}
}