Module Name:    src
Committed By:   yamaguchi
Date:           Thu Mar 24 08:02:21 UTC 2022

Modified Files:
        src/sys/dev/pci: if_vioif.c

Log Message:
vioif(4): adopt ether_set_ifflags_cb


To generate a diff of this commit:
cvs rdiff -u -r1.74 -r1.75 src/sys/dev/pci/if_vioif.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_vioif.c
diff -u src/sys/dev/pci/if_vioif.c:1.74 src/sys/dev/pci/if_vioif.c:1.75
--- src/sys/dev/pci/if_vioif.c:1.74	Thu Mar 24 07:57:10 2022
+++ src/sys/dev/pci/if_vioif.c	Thu Mar 24 08:02:21 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_vioif.c,v 1.74 2022/03/24 07:57:10 yamaguchi Exp $	*/
+/*	$NetBSD: if_vioif.c,v 1.75 2022/03/24 08:02:21 yamaguchi Exp $	*/
 
 /*
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.74 2022/03/24 07:57:10 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.75 2022/03/24 08:02:21 yamaguchi Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -317,7 +317,6 @@ struct vioif_softc {
 
 	uint8_t			sc_mac[ETHER_ADDR_LEN];
 	struct ethercom		sc_ethercom;
-	short			sc_deferred_init_done;
 	bool			sc_link_active;
 
 	struct vioif_txqueue	*sc_txq;
@@ -352,7 +351,6 @@ struct vioif_softc {
 /* cfattach interface functions */
 static int	vioif_match(device_t, cfdata_t, void *);
 static void	vioif_attach(device_t, device_t, void *);
-static void	vioif_deferred_init(device_t);
 static int	vioif_finalize_teardown(device_t);
 
 /* ifnet interface functions */
@@ -364,6 +362,7 @@ static int	vioif_transmit(struct ifnet *
 static void	vioif_transmit_locked(struct ifnet *, struct vioif_txqueue *);
 static int	vioif_ioctl(struct ifnet *, u_long, void *);
 static void	vioif_watchdog(struct ifnet *);
+static int	vioif_ifflags_cb(struct ethercom *);
 
 /* rx */
 static int	vioif_add_rx_mbuf(struct vioif_rxqueue *, int);
@@ -416,6 +415,7 @@ static void	vioif_enable_interrupt_vqpai
 static void	vioif_disable_interrupt_vqpairs(struct vioif_softc *);
 static int	vioif_setup_sysctl(struct vioif_softc *);
 static void	vioif_setup_stats(struct vioif_softc *);
+static int	vioif_ifflags(struct vioif_softc *);
 
 CFATTACH_DECL_NEW(vioif, sizeof(struct vioif_softc),
 		  vioif_match, vioif_attach, NULL, NULL);
@@ -1050,6 +1050,7 @@ vioif_attach(device_t parent, device_t s
 	if_attach(ifp);
 	if_deferred_start_init(ifp, NULL);
 	ether_ifattach(ifp, sc->sc_mac);
+	ether_set_ifflags_cb(&sc->sc_ethercom, vioif_ifflags_cb);
 
 	return;
 
@@ -1118,23 +1119,6 @@ vioif_finalize_teardown(device_t self)
 	return 0;
 }
 
-/* we need interrupts to make promiscuous mode off */
-static void
-vioif_deferred_init(device_t self)
-{
-	struct vioif_softc *sc = device_private(self);
-	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
-	int r;
-
-	if (ifp->if_flags & IFF_PROMISC)
-		return;
-
-	r =  vioif_set_promisc(sc, false);
-	if (r != 0)
-		aprint_error_dev(self, "resetting promisc mode failed, "
-		    "error code %d\n", r);
-}
-
 static void
 vioif_enable_interrupt_vqpairs(struct vioif_softc *sc)
 {
@@ -1218,18 +1202,12 @@ vioif_init(struct ifnet *ifp)
 
 	vioif_enable_interrupt_vqpairs(sc);
 
-	if (!sc->sc_deferred_init_done) {
-		sc->sc_deferred_init_done = 1;
-		if (sc->sc_has_ctrl)
-			vioif_deferred_init(sc->sc_dev);
-	}
-
 	vioif_update_link_status(sc);
 	ifp->if_flags |= IFF_RUNNING;
 	ifp->if_flags &= ~IFF_OACTIVE;
-	vioif_rx_filter(sc);
+	r = vioif_rx_filter(sc);
 
-	return 0;
+	return r;
 }
 
 static void
@@ -1495,12 +1473,12 @@ vioif_ioctl(struct ifnet *ifp, u_long cm
 	s = splnet();
 
 	r = ether_ioctl(ifp, cmd, data);
-	if ((r == 0 && cmd == SIOCSIFFLAGS) ||
-	    (r == ENETRESET && (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI))) {
-		if (ifp->if_flags & IFF_RUNNING)
+	if (r == ENETRESET && (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI)) {
+		if (ifp->if_flags & IFF_RUNNING) {
 			r = vioif_rx_filter(ifp->if_softc);
-		else
+		} else {
 			r = 0;
+		}
 	}
 
 	splx(s);
@@ -2276,14 +2254,57 @@ vioif_ctrl_intr(void *arg)
 	return 1;
 }
 
+static int
+vioif_ifflags(struct vioif_softc *sc)
+{
+	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+	bool onoff;
+	int r;
+
+	if (!sc->sc_has_ctrl) {
+		/* no ctrl vq; always promisc and allmulti */
+		ifp->if_flags |= (IFF_PROMISC | IFF_ALLMULTI);
+		return 0;
+	}
+
+	onoff = ifp->if_flags & IFF_ALLMULTI ? true : false;
+	r = vioif_set_allmulti(sc, onoff);
+	if (r != 0) {
+		log(LOG_WARNING,
+		    "%s: couldn't %sable ALLMULTI\n",
+		    ifp->if_xname, onoff ? "en" : "dis");
+		if (onoff == false) {
+			ifp->if_flags |= IFF_ALLMULTI;
+		}
+	}
+
+	onoff = ifp->if_flags & IFF_PROMISC ? true : false;
+	r = vioif_set_promisc(sc, onoff);
+	if (r != 0) {
+		log(LOG_WARNING,
+		    "%s: couldn't %sable PROMISC\n",
+		    ifp->if_xname, onoff ? "en" : "dis");
+		if (onoff == false) {
+			ifp->if_flags |= IFF_PROMISC;
+		}
+	}
+
+	return 0;
+}
+
+static int
+vioif_ifflags_cb(struct ethercom *ec)
+{
+	struct ifnet *ifp = &ec->ec_if;
+	struct vioif_softc *sc = ifp->if_softc;
+
+	return vioif_ifflags(sc);
+}
+
 /*
- * If IFF_PROMISC requested,  set promiscuous
  * If multicast filter small enough (<=MAXENTRIES) set rx filter
  * If large multicast filter exist use ALLMULTI
- */
-/*
  * If setting rx filter fails fall back to ALLMULTI
- * If ALLMULTI fails fall back to PROMISC
  */
 static int
 vioif_rx_filter(struct vioif_softc *sc)
@@ -2295,81 +2316,68 @@ vioif_rx_filter(struct vioif_softc *sc)
 	struct ether_multistep step;
 	struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
 	int nentries;
-	int promisc = 0, allmulti = 0, rxfilter = 0;
+	bool allmulti = 0;
 	int r;
 
-	if (!sc->sc_has_ctrl) {	/* no ctrl vq; always promisc */
-		ifp->if_flags |= IFF_PROMISC;
-		return 0;
-	}
-
-	if (ifp->if_flags & IFF_PROMISC) {
-		promisc = 1;
-		goto set;
+	if (!sc->sc_has_ctrl) {
+		goto set_ifflags;
 	}
 
 	memcpy(ctrlq->ctrlq_mac_tbl_uc->macs[0],
 	    CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
 
-	nentries = -1;
+	nentries = 0;
+	allmulti = false;
+
 	ETHER_LOCK(ec);
-	ETHER_FIRST_MULTI(step, ec, enm);
-	while (nentries++, enm != NULL) {
+	for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL;
+	    ETHER_NEXT_MULTI(step, enm)) {
 		if (nentries >= VIRTIO_NET_CTRL_MAC_MAXENTRIES) {
-			allmulti = 1;
-			goto set_unlock;
+			allmulti = true;
+			break;
 		}
 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
-			allmulti = 1;
-			goto set_unlock;
+			allmulti = true;
+			break;
 		}
+
 		memcpy(ctrlq->ctrlq_mac_tbl_mc->macs[nentries],
 		    enm->enm_addrlo, ETHER_ADDR_LEN);
-		ETHER_NEXT_MULTI(step, enm);
+		nentries++;
 	}
-	rxfilter = 1;
-
-set_unlock:
 	ETHER_UNLOCK(ec);
 
-set:
 	r = vioif_set_mac_addr(sc);
 	if (r != 0) {
 		log(LOG_WARNING, "%s: couldn't set MAC address\n",
 		    ifp->if_xname);
 	}
 
-	if (rxfilter) {
+	if (!allmulti) {
 		ctrlq->ctrlq_mac_tbl_uc->nentries = virtio_rw32(vsc, 1);
 		ctrlq->ctrlq_mac_tbl_mc->nentries = virtio_rw32(vsc, nentries);
 		r = vioif_set_rx_filter(sc);
 		if (r != 0) {
-			rxfilter = 0;
-			allmulti = 1; /* fallback */
+			allmulti = true; /* fallback */
 		}
-	} else {
-		/* remove rx filter */
+	}
+
+	if (allmulti) {
 		ctrlq->ctrlq_mac_tbl_uc->nentries = virtio_rw32(vsc, 0);
 		ctrlq->ctrlq_mac_tbl_mc->nentries = virtio_rw32(vsc, 0);
 		r = vioif_set_rx_filter(sc);
-		/* what to do on failure? */
-	}
-	if (allmulti) {
-		r = vioif_set_allmulti(sc, true);
 		if (r != 0) {
-			allmulti = 0;
-			promisc = 1; /* fallback */
+			log(LOG_DEBUG, "%s: couldn't clear RX filter\n",
+			    ifp->if_xname);
+			/* what to do on failure? */
 		}
-	} else {
-		r = vioif_set_allmulti(sc, false);
-		/* what to do on failure? */
-	}
-	if (promisc) {
-		r = vioif_set_promisc(sc, true);
-	} else {
-		r = vioif_set_promisc(sc, false);
+
+		ifp->if_flags |= IFF_ALLMULTI;
 	}
 
+set_ifflags:
+	r = vioif_ifflags(sc);
+
 	return r;
 }
 

Reply via email to