Module Name:    src
Committed By:   tsutsui
Date:           Fri Sep 18 13:45:20 UTC 2009

Modified Files:
        src/sys/dev/sbus: be.c

Log Message:
Make be(4) is properly initialized at the first ifconfig(8) command:
- make beinit() and bestop() match struct ifnet
- if ether_ioctl() returns ENETRESET always call init function


To generate a diff of this commit:
cvs rdiff -u -r1.67 -r1.68 src/sys/dev/sbus/be.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/sbus/be.c
diff -u src/sys/dev/sbus/be.c:1.67 src/sys/dev/sbus/be.c:1.68
--- src/sys/dev/sbus/be.c:1.67	Fri Sep 18 12:23:16 2009
+++ src/sys/dev/sbus/be.c	Fri Sep 18 13:45:20 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: be.c,v 1.67 2009/09/18 12:23:16 tsutsui Exp $	*/
+/*	$NetBSD: be.c,v 1.68 2009/09/18 13:45:20 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: be.c,v 1.67 2009/09/18 12:23:16 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: be.c,v 1.68 2009/09/18 13:45:20 tsutsui Exp $");
 
 #include "opt_ddb.h"
 #include "opt_inet.h"
@@ -161,12 +161,13 @@
 int	bematch(device_t, cfdata_t, void *);
 void	beattach(device_t, device_t, void *);
 
-void	beinit(struct be_softc *);
+int	beinit(struct ifnet *);
 void	bestart(struct ifnet *);
-void	bestop(struct be_softc *);
+void	bestop(struct ifnet *, int);
 void	bewatchdog(struct ifnet *);
 int	beioctl(struct ifnet *, u_long, void *);
 void	bereset(struct be_softc *);
+void	behwreset(struct be_softc *);
 
 int	beintr(void *);
 int	berint(struct be_softc *);
@@ -277,8 +278,6 @@
 
 	callout_init(&sc->sc_tick_ch, 0);
 
-	bestop(sc);
-
 	sc->sc_channel = prom_getpropint(node, "channel#", -1);
 	if (sc->sc_channel == -1)
 		sc->sc_channel = 0;
@@ -457,6 +456,8 @@
 	ifp->if_start = bestart;
 	ifp->if_ioctl = beioctl;
 	ifp->if_watchdog = bewatchdog;
+	ifp->if_init = beinit;
+	ifp->if_stop = bestop;
 	ifp->if_flags =
 		IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
 	IFQ_SET_READY(&ifp->if_snd);
@@ -656,11 +657,9 @@
 }
 
 void
-bestop(struct be_softc *sc)
+bestop(struct ifnet *ifp, int disable)
 {
-	int n;
-	bus_space_tag_t t = sc->sc_bustag;
-	bus_space_handle_t br = sc->sc_br;
+	struct be_softc *sc = ifp->if_softc;
 
 	callout_stop(&sc->sc_tick_ch);
 
@@ -668,6 +667,16 @@
 	mii_down(&sc->sc_mii);
 	(void)be_intphy_service(sc, &sc->sc_mii, MII_DOWN);
 
+	behwreset(sc);
+}
+
+void
+behwreset(struct be_softc *sc)
+{
+	int n;
+	bus_space_tag_t t = sc->sc_bustag;
+	bus_space_handle_t br = sc->sc_br;
+
 	/* Stop the transmitter */
 	bus_space_write_4(t, br, BE_BRI_TXCFG, 0);
 	for (n = 32; n > 0; n--) {
@@ -691,12 +700,13 @@
 void
 bereset(struct be_softc *sc)
 {
+	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 	int s;
 
 	s = splnet();
-	bestop(sc);
+	behwreset(sc);
 	if ((sc->sc_ethercom.ec_if.if_flags & IFF_UP) != 0)
-		beinit(sc);
+		beinit(ifp);
 	splx(s);
 }
 
@@ -963,7 +973,7 @@
 	switch (cmd) {
 	case SIOCINITIFADDR:
 		ifp->if_flags |= IFF_UP;
-		beinit(sc);
+		beinit(ifp);
 		switch (ifa->ifa_addr->sa_family) {
 #ifdef INET
 		case AF_INET:
@@ -985,7 +995,7 @@
 			 * If interface is marked down and it is running, then
 			 * stop it.
 			 */
-			bestop(sc);
+			bestop(ifp, 0);
 			ifp->if_flags &= ~IFF_RUNNING;
 			break;
 		case IFF_UP:
@@ -993,15 +1003,15 @@
 			 * If interface is marked up and it is stopped, then
 			 * start it.
 			 */
-			beinit(sc);
+			beinit(ifp);
 			break;
 		default:
 			/*
 			 * Reset the interface to pick up changes in any other
 			 * flags that affect hardware registers.
 			 */
-			bestop(sc);
-			beinit(sc);
+			bestop(ifp, 0);
+			beinit(ifp);
 			break;
 		}
 #ifdef BEDEBUG
@@ -1012,35 +1022,32 @@
 #endif
 		break;
 
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
+	case SIOCGIFMEDIA:
+	case SIOCSIFMEDIA:
+		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
+		break;
+	default:
 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
 			/*
 			 * Multicast list has changed; set the hardware filter
 			 * accordingly.
 			 */
 			if (ifp->if_flags & IFF_RUNNING)
-				be_mcreset(sc);
-			error = 0;
+				error = beinit(ifp);
+			else
+				error = 0;
 		}
 		break;
-	case SIOCGIFMEDIA:
-	case SIOCSIFMEDIA:
-		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
-		break;
-	default:
-		error = ether_ioctl(ifp, cmd, data);
-		break;
 	}
 	splx(s);
 	return (error);
 }
 
 
-void
-beinit(struct be_softc *sc)
+int
+beinit(struct ifnet *ifp)
 {
-	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+	struct be_softc *sc = ifp->if_softc;
 	bus_space_tag_t t = sc->sc_bustag;
 	bus_space_handle_t br = sc->sc_br;
 	bus_space_handle_t cr = sc->sc_cr;
@@ -1054,7 +1061,7 @@
 
 	qec_meminit(&sc->sc_rb, BE_PKT_BUF_SZ);
 
-	bestop(sc);
+	bestop(ifp, 1);
 
 	ea = sc->sc_enaddr;
 	bus_space_write_4(t, br, BE_BRI_MACADDR0, (ea[0] << 8) | ea[1]);
@@ -1137,8 +1144,11 @@
 	ifp->if_flags &= ~IFF_OACTIVE;
 
 	callout_reset(&sc->sc_tick_ch, hz, be_tick, sc);
+
+	return 0;
 out:
 	splx(s);
+	return rc;
 }
 
 void

Reply via email to