Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/virtio/network/if_vtnet.c
Show First 20 Lines • Show All 204 Lines • ▼ Show 20 Lines | |||||
static void vtnet_rx_filter(struct vtnet_softc *); | static void vtnet_rx_filter(struct vtnet_softc *); | ||||
static void vtnet_rx_filter_mac(struct vtnet_softc *); | static void vtnet_rx_filter_mac(struct vtnet_softc *); | ||||
static int vtnet_exec_vlan_filter(struct vtnet_softc *, int, uint16_t); | static int vtnet_exec_vlan_filter(struct vtnet_softc *, int, uint16_t); | ||||
static void vtnet_rx_filter_vlan(struct vtnet_softc *); | static void vtnet_rx_filter_vlan(struct vtnet_softc *); | ||||
static void vtnet_update_vlan_filter(struct vtnet_softc *, int, uint16_t); | static void vtnet_update_vlan_filter(struct vtnet_softc *, int, uint16_t); | ||||
static void vtnet_register_vlan(void *, struct ifnet *, uint16_t); | static void vtnet_register_vlan(void *, struct ifnet *, uint16_t); | ||||
static void vtnet_unregister_vlan(void *, struct ifnet *, uint16_t); | static void vtnet_unregister_vlan(void *, struct ifnet *, uint16_t); | ||||
static void vtnet_update_speed_duplex(struct vtnet_softc *); | |||||
static int vtnet_is_link_up(struct vtnet_softc *); | static int vtnet_is_link_up(struct vtnet_softc *); | ||||
static void vtnet_update_link_status(struct vtnet_softc *); | static void vtnet_update_link_status(struct vtnet_softc *); | ||||
static int vtnet_ifmedia_upd(struct ifnet *); | static int vtnet_ifmedia_upd(struct ifnet *); | ||||
static void vtnet_ifmedia_sts(struct ifnet *, struct ifmediareq *); | static void vtnet_ifmedia_sts(struct ifnet *, struct ifmediareq *); | ||||
static void vtnet_get_hwaddr(struct vtnet_softc *); | static void vtnet_get_hwaddr(struct vtnet_softc *); | ||||
static void vtnet_set_hwaddr(struct vtnet_softc *); | static void vtnet_set_hwaddr(struct vtnet_softc *); | ||||
static void vtnet_vlan_tag_remove(struct mbuf *); | static void vtnet_vlan_tag_remove(struct mbuf *); | ||||
static void vtnet_set_rx_process_limit(struct vtnet_softc *); | static void vtnet_set_rx_process_limit(struct vtnet_softc *); | ||||
▲ Show 20 Lines • Show All 761 Lines • ▼ Show 20 Lines | vtnet_setup_interface(struct vtnet_softc *sc) | ||||
ifp = sc->vtnet_ifp = if_alloc(IFT_ETHER); | ifp = sc->vtnet_ifp = if_alloc(IFT_ETHER); | ||||
if (ifp == NULL) { | if (ifp == NULL) { | ||||
device_printf(dev, "cannot allocate ifnet structure\n"); | device_printf(dev, "cannot allocate ifnet structure\n"); | ||||
return (ENOSPC); | return (ENOSPC); | ||||
} | } | ||||
if_initname(ifp, device_get_name(dev), device_get_unit(dev)); | if_initname(ifp, device_get_name(dev), device_get_unit(dev)); | ||||
ifp->if_baudrate = IF_Gbps(10); /* Approx. */ | |||||
ifp->if_softc = sc; | ifp->if_softc = sc; | ||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | | ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | | ||||
IFF_KNOWSEPOCH; | IFF_KNOWSEPOCH; | ||||
ifp->if_init = vtnet_init; | ifp->if_init = vtnet_init; | ||||
ifp->if_ioctl = vtnet_ioctl; | ifp->if_ioctl = vtnet_ioctl; | ||||
ifp->if_get_counter = vtnet_get_counter; | ifp->if_get_counter = vtnet_get_counter; | ||||
#ifndef VTNET_LEGACY_TX | #ifndef VTNET_LEGACY_TX | ||||
ifp->if_transmit = vtnet_txq_mq_start; | ifp->if_transmit = vtnet_txq_mq_start; | ||||
ifp->if_qflush = vtnet_qflush; | ifp->if_qflush = vtnet_qflush; | ||||
#else | #else | ||||
struct virtqueue *vq = sc->vtnet_txqs[0].vtntx_vq; | struct virtqueue *vq = sc->vtnet_txqs[0].vtntx_vq; | ||||
ifp->if_start = vtnet_start; | ifp->if_start = vtnet_start; | ||||
IFQ_SET_MAXLEN(&ifp->if_snd, virtqueue_size(vq) - 1); | IFQ_SET_MAXLEN(&ifp->if_snd, virtqueue_size(vq) - 1); | ||||
ifp->if_snd.ifq_drv_maxlen = virtqueue_size(vq) - 1; | ifp->if_snd.ifq_drv_maxlen = virtqueue_size(vq) - 1; | ||||
IFQ_SET_READY(&ifp->if_snd); | IFQ_SET_READY(&ifp->if_snd); | ||||
#endif | #endif | ||||
ifmedia_init(&sc->vtnet_media, IFM_IMASK, vtnet_ifmedia_upd, | if (virtio_with_feature(dev, VIRTIO_NET_F_SPEED_DUPLEX)) { | ||||
vtnet_ifmedia_sts); | uint32_t speed = virtio_read_dev_config_4(dev, | ||||
ifmedia_add(&sc->vtnet_media, VTNET_MEDIATYPE, 0, NULL); | offsetof(struct virtio_net_config, speed)); | ||||
ifmedia_set(&sc->vtnet_media, VTNET_MEDIATYPE); | if (speed != -1) | ||||
ifp->if_baudrate = IF_Mbps(speed); | |||||
else | |||||
ifp->if_baudrate = IF_Gbps(10); /* Approx. */ | |||||
} else | |||||
ifp->if_baudrate = IF_Gbps(10); /* Approx. */ | |||||
ifmedia_init(&sc->vtnet_media, 0, vtnet_ifmedia_upd, vtnet_ifmedia_sts); | |||||
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_hwaddr(sc); | ||||
ether_ifattach(ifp, sc->vtnet_hwaddr); | ether_ifattach(ifp, sc->vtnet_hwaddr); | ||||
if (virtio_with_feature(dev, VIRTIO_NET_F_STATUS)) | if (virtio_with_feature(dev, VIRTIO_NET_F_STATUS)) | ||||
ifp->if_capabilities |= IFCAP_LINKSTATE; | ifp->if_capabilities |= IFCAP_LINKSTATE; | ||||
/* Tell the upper layer(s) we support long frames. */ | /* Tell the upper layer(s) we support long frames. */ | ||||
ifp->if_hdrlen = sizeof(struct ether_vlan_header); | ifp->if_hdrlen = sizeof(struct ether_vlan_header); | ||||
▲ Show 20 Lines • Show All 2,572 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
if (ifp->if_softc != arg) | if (ifp->if_softc != arg) | ||||
return; | return; | ||||
vtnet_update_vlan_filter(arg, 0, tag); | vtnet_update_vlan_filter(arg, 0, tag); | ||||
} | } | ||||
static void | |||||
vtnet_update_speed_duplex(struct vtnet_softc *sc) | |||||
{ | |||||
device_t dev; | |||||
struct ifnet *ifp; | |||||
uint32_t speed; | |||||
dev = sc->vtnet_dev; | |||||
ifp = sc->vtnet_ifp; | |||||
/* BMV: Ignore duplex. */ | |||||
if ((sc->vtnet_features & VIRTIO_NET_F_SPEED_DUPLEX) == 0) | |||||
speed = -1; | |||||
else | |||||
speed = virtio_read_dev_config_4(dev, | |||||
offsetof(struct virtio_net_config, speed)); | |||||
if (speed != -1) | |||||
ifp->if_baudrate = IF_Mbps(speed); | |||||
} | |||||
static int | static int | ||||
vtnet_is_link_up(struct vtnet_softc *sc) | vtnet_is_link_up(struct vtnet_softc *sc) | ||||
{ | { | ||||
device_t dev; | device_t dev; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
uint16_t status; | uint16_t status; | ||||
dev = sc->vtnet_dev; | dev = sc->vtnet_dev; | ||||
Show All 10 Lines | |||||
static void | static void | ||||
vtnet_update_link_status(struct vtnet_softc *sc) | vtnet_update_link_status(struct vtnet_softc *sc) | ||||
{ | { | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
int link; | int link; | ||||
ifp = sc->vtnet_ifp; | ifp = sc->vtnet_ifp; | ||||
VTNET_CORE_LOCK_ASSERT(sc); | VTNET_CORE_LOCK_ASSERT(sc); | ||||
link = vtnet_is_link_up(sc); | link = vtnet_is_link_up(sc); | ||||
/* Notify if the link status has changed. */ | /* Notify if the link status has changed. */ | ||||
if (link != 0 && sc->vtnet_link_active == 0) { | if (link != 0 && sc->vtnet_link_active == 0) { | ||||
vtnet_update_speed_duplex(sc); | |||||
sc->vtnet_link_active = 1; | sc->vtnet_link_active = 1; | ||||
if_link_state_change(ifp, LINK_STATE_UP); | if_link_state_change(ifp, LINK_STATE_UP); | ||||
} else if (link == 0 && sc->vtnet_link_active != 0) { | } else if (link == 0 && sc->vtnet_link_active != 0) { | ||||
sc->vtnet_link_active = 0; | sc->vtnet_link_active = 0; | ||||
if_link_state_change(ifp, LINK_STATE_DOWN); | if_link_state_change(ifp, LINK_STATE_DOWN); | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
vtnet_ifmedia_upd(struct ifnet *ifp) | vtnet_ifmedia_upd(struct ifnet *ifp) | ||||
{ | { | ||||
struct vtnet_softc *sc; | return (EOPNOTSUPP); | ||||
struct ifmedia *ifm; | |||||
sc = ifp->if_softc; | |||||
ifm = &sc->vtnet_media; | |||||
if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) | |||||
return (EINVAL); | |||||
return (0); | |||||
} | } | ||||
static void | static void | ||||
vtnet_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) | vtnet_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) | ||||
{ | { | ||||
struct vtnet_softc *sc; | struct vtnet_softc *sc; | ||||
sc = ifp->if_softc; | sc = ifp->if_softc; | ||||
ifmr->ifm_status = IFM_AVALID; | ifmr->ifm_status = IFM_AVALID; | ||||
ifmr->ifm_active = IFM_ETHER; | ifmr->ifm_active = IFM_ETHER; | ||||
VTNET_CORE_LOCK(sc); | VTNET_CORE_LOCK(sc); | ||||
if (vtnet_is_link_up(sc) != 0) { | if (vtnet_is_link_up(sc) != 0) { | ||||
ifmr->ifm_status |= IFM_ACTIVE; | ifmr->ifm_status |= IFM_ACTIVE; | ||||
ifmr->ifm_active |= VTNET_MEDIATYPE; | ifmr->ifm_active |= IFM_10G_T | IFM_FDX; | ||||
} else | } else | ||||
ifmr->ifm_active |= IFM_NONE; | ifmr->ifm_active |= IFM_NONE; | ||||
VTNET_CORE_UNLOCK(sc); | VTNET_CORE_UNLOCK(sc); | ||||
} | } | ||||
static void | static void | ||||
vtnet_set_hwaddr(struct vtnet_softc *sc) | vtnet_set_hwaddr(struct vtnet_softc *sc) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 443 Lines • Show Last 20 Lines |