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