diff --git a/sys/dev/etherswitch/arswitch/arswitch.c b/sys/dev/etherswitch/arswitch/arswitch.c index d582c097c556..69718c97bfc4 100644 --- a/sys/dev/etherswitch/arswitch/arswitch.c +++ b/sys/dev/etherswitch/arswitch/arswitch.c @@ -483,6 +483,41 @@ ar8xxx_atu_learn_default(struct arswitch_softc *sc) * between ethernet switches. */ +/* + * Fetch the configured switch MAC address. + */ +static int +ar8xxx_hw_get_switch_macaddr(struct arswitch_softc *sc, struct ether_addr *ea) +{ + uint32_t ret0, ret1; + char *s; + + s = (void *) ea; + + ret0 = arswitch_readreg(sc->sc_dev, AR8X16_REG_SW_MAC_ADDR0); + ret1 = arswitch_readreg(sc->sc_dev, AR8X16_REG_SW_MAC_ADDR1); + + s[5] = MS(ret0, AR8X16_REG_SW_MAC_ADDR0_BYTE5); + s[4] = MS(ret0, AR8X16_REG_SW_MAC_ADDR0_BYTE4); + s[3] = MS(ret1, AR8X16_REG_SW_MAC_ADDR1_BYTE3); + s[2] = MS(ret1, AR8X16_REG_SW_MAC_ADDR1_BYTE2); + s[1] = MS(ret1, AR8X16_REG_SW_MAC_ADDR1_BYTE1); + s[0] = MS(ret1, AR8X16_REG_SW_MAC_ADDR1_BYTE0); + + return (0); +} + +/* + * Set the switch mac address. + */ +static int +ar8xxx_hw_set_switch_macaddr(struct arswitch_softc *sc, + const struct ether_addr *ea) +{ + + return (ENXIO); +} + /* * XXX TODO: this attach routine does NOT free all memory, resources * upon failure! @@ -527,6 +562,8 @@ arswitch_attach(device_t dev) sc->hal.arswitch_port_vlan_setup = ar8xxx_port_vlan_setup; sc->hal.arswitch_port_vlan_get = ar8xxx_port_vlan_get; sc->hal.arswitch_vlan_init_hw = ar8xxx_reset_vlans; + sc->hal.arswitch_hw_get_switch_macaddr = ar8xxx_hw_get_switch_macaddr; + sc->hal.arswitch_hw_set_switch_macaddr = ar8xxx_hw_set_switch_macaddr; sc->hal.arswitch_vlan_getvgroup = ar8xxx_getvgroup; sc->hal.arswitch_vlan_setvgroup = ar8xxx_setvgroup; @@ -1115,6 +1152,7 @@ static int arswitch_getconf(device_t dev, etherswitch_conf_t *conf) { struct arswitch_softc *sc; + int ret; sc = device_get_softc(dev); @@ -1122,6 +1160,13 @@ arswitch_getconf(device_t dev, etherswitch_conf_t *conf) conf->cmd = ETHERSWITCH_CONF_VLAN_MODE; conf->vlan_mode = sc->vlan_mode; + /* Return the switch ethernet address. */ + ret = sc->hal.arswitch_hw_get_switch_macaddr(sc, + &conf->switch_macaddr); + if (ret == 0) { + conf->cmd |= ETHERSWITCH_CONF_SWITCH_MACADDR; + } + return (0); } @@ -1140,6 +1185,8 @@ arswitch_setconf(device_t dev, etherswitch_conf_t *conf) return (err); } + /* TODO: Set the switch ethernet address. */ + return (0); } diff --git a/sys/dev/etherswitch/arswitch/arswitchreg.h b/sys/dev/etherswitch/arswitch/arswitchreg.h index 128f1e43d324..bfe958151a59 100644 --- a/sys/dev/etherswitch/arswitch/arswitchreg.h +++ b/sys/dev/etherswitch/arswitch/arswitchreg.h @@ -88,7 +88,20 @@ #define AR8X16_REG_IMR 0x0014 #define AR8X16_REG_SW_MAC_ADDR0 0x0020 +#define AR8X16_REG_SW_MAC_ADDR0_BYTE4 BITS(8, 8) +#define AR8X16_REG_SW_MAC_ADDR0_BYTE4_S 8 +#define AR8X16_REG_SW_MAC_ADDR0_BYTE5 BITS(0, 8) +#define AR8X16_REG_SW_MAC_ADDR0_BYTE5_S 0 + #define AR8X16_REG_SW_MAC_ADDR1 0x0024 +#define AR8X16_REG_SW_MAC_ADDR1_BYTE0 BITS(24, 8) +#define AR8X16_REG_SW_MAC_ADDR1_BYTE0_S 24 +#define AR8X16_REG_SW_MAC_ADDR1_BYTE1 BITS(16, 8) +#define AR8X16_REG_SW_MAC_ADDR1_BYTE1_S 16 +#define AR8X16_REG_SW_MAC_ADDR1_BYTE2 BITS(8, 8) +#define AR8X16_REG_SW_MAC_ADDR1_BYTE2_S 8 +#define AR8X16_REG_SW_MAC_ADDR1_BYTE3 BITS(0, 8) +#define AR8X16_REG_SW_MAC_ADDR1_BYTE3_S 0 #define AR8X16_REG_FLOOD_MASK 0x002c #define AR8X16_FLOOD_MASK_BCAST_TO_CPU (1 << 26) diff --git a/sys/dev/etherswitch/arswitch/arswitchvar.h b/sys/dev/etherswitch/arswitch/arswitchvar.h index bd13895a88cb..ff92536358ac 100644 --- a/sys/dev/etherswitch/arswitch/arswitchvar.h +++ b/sys/dev/etherswitch/arswitch/arswitchvar.h @@ -99,6 +99,11 @@ struct arswitch_softc { int (* arswitch_hw_setup) (struct arswitch_softc *); int (* arswitch_hw_global_setup) (struct arswitch_softc *); + int (* arswitch_hw_get_switch_macaddr) (struct arswitch_softc *, + struct ether_addr *sa); + int (* arswitch_hw_set_switch_macaddr) (struct arswitch_softc *, + const struct ether_addr *sa); + /* Port functions */ void (* arswitch_port_init) (struct arswitch_softc *, int);