diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c --- a/sys/dev/virtio/network/if_vtnet.c +++ b/sys/dev/virtio/network/if_vtnet.c @@ -214,8 +214,9 @@ static void vtnet_update_link_status(struct vtnet_softc *); static int vtnet_ifmedia_upd(struct ifnet *); static void vtnet_ifmedia_sts(struct ifnet *, struct ifmediareq *); -static void vtnet_get_hwaddr(struct vtnet_softc *); -static void vtnet_set_hwaddr(struct vtnet_softc *); +static void vtnet_get_macaddr(struct vtnet_softc *); +static void vtnet_set_macaddr(struct vtnet_softc *); +static void vtnet_attached_set_macaddr(struct vtnet_softc *); static void vtnet_vlan_tag_remove(struct mbuf *); static void vtnet_set_rx_process_limit(struct vtnet_softc *); static void vtnet_set_tx_intr_threshold(struct vtnet_softc *); @@ -568,6 +569,13 @@ static int vtnet_attach_completed(device_t dev) { + struct vtnet_softc *sc; + + sc = device_get_softc(dev); + + VTNET_CORE_LOCK(sc); + vtnet_attached_set_macaddr(sc); + VTNET_CORE_UNLOCK(sc); return (0); } @@ -1016,7 +1024,7 @@ ifmedia_add(&sc->vtnet_media, IFM_ETHER | IFM_AUTO, 0, NULL); ifmedia_set(&sc->vtnet_media, IFM_ETHER | IFM_AUTO); - vtnet_get_hwaddr(sc); + vtnet_get_macaddr(sc); ether_ifattach(ifp, sc->vtnet_hwaddr); if (virtio_with_feature(dev, VIRTIO_NET_F_STATUS)) @@ -3108,7 +3116,7 @@ /* Use the current MAC address. */ bcopy(IF_LLADDR(ifp), sc->vtnet_hwaddr, ETHER_ADDR_LEN); - vtnet_set_hwaddr(sc); + vtnet_set_macaddr(sc); vtnet_set_active_vq_pairs(sc); @@ -3669,22 +3677,36 @@ } static void -vtnet_set_hwaddr(struct vtnet_softc *sc) +vtnet_get_macaddr(struct vtnet_softc *sc) { - device_t dev; - dev = sc->vtnet_dev; + if (sc->vtnet_flags & VTNET_FLAG_MAC) { + virtio_read_device_config_array(sc->vtnet_dev, + offsetof(struct virtio_net_config, mac), + &sc->vtnet_hwaddr[0], sizeof(uint8_t), ETHER_ADDR_LEN); + } else { + /* Generate a random locally administered unicast address. */ + sc->vtnet_hwaddr[0] = 0xB2; + arc4rand(&sc->vtnet_hwaddr[1], ETHER_ADDR_LEN - 1, 0); + } +} + +static void +vtnet_set_macaddr(struct vtnet_softc *sc) +{ + int error; if (sc->vtnet_flags & VTNET_FLAG_CTRL_MAC) { - if (vtnet_ctrl_mac_cmd(sc, sc->vtnet_hwaddr) != 0) - device_printf(dev, "unable to set MAC address\n"); + error = vtnet_ctrl_mac_cmd(sc, sc->vtnet_hwaddr); + if (error) + if_printf(sc->vtnet_ifp, "unable to set MAC address\n"); return; } - /* In modern VirtIO the MAC config is read-only. */ + /* MAC in config is read-only in modern VirtIO. */ if (!vtnet_modern(sc) && sc->vtnet_flags & VTNET_FLAG_MAC) { for (int i = 0; i < ETHER_ADDR_LEN; i++) { - virtio_write_dev_config_1(dev, + virtio_write_dev_config_1(sc->vtnet_dev, offsetof(struct virtio_net_config, mac) + i, sc->vtnet_hwaddr[i]); } @@ -3692,20 +3714,12 @@ } static void -vtnet_get_hwaddr(struct vtnet_softc *sc) +vtnet_attached_set_macaddr(struct vtnet_softc *sc) { - if (sc->vtnet_flags & VTNET_FLAG_MAC) { - virtio_read_device_config_array(sc->vtnet_dev, - offsetof(struct virtio_net_config, mac), - &sc->vtnet_hwaddr[0], sizeof(uint8_t), ETHER_ADDR_LEN); - } else { - /* Generate a random locally administered unicast address. */ - sc->vtnet_hwaddr[0] = 0xB2; - arc4rand(&sc->vtnet_hwaddr[1], ETHER_ADDR_LEN - 1, 0); - /* BMV: FIXME Cannot do before DRIVER_OK! See 3.1.2 */ - vtnet_set_hwaddr(sc); - } + /* Assign MAC address if it was generated. */ + if ((sc->vtnet_flags & VTNET_FLAG_MAC) == 0) + vtnet_set_macaddr(sc); } static void