Subject: Re: device disable/enable and packet
To: Atsushi Onoe <onoe@sm.sony.co.jp>
From: enami tsugutomo <enami@sm.sony.co.jp>
List: tech-net
Date: 11/15/2002 13:33:53
Atsushi Onoe <onoe@sm.sony.co.jp> writes:
> At least, you should consider the link won't be active for long time,
> e.g. when drop cable is not phisically connected. Perhaps normal
> transmit timeout by watchdog timer should be applied for the holding
> packet.
Ok, how about changes like this?
enami.
Index: i82557var.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/i82557var.h,v
retrieving revision 1.30
diff -p -c -r1.30 i82557var.h
*** i82557var.h 2002/09/29 23:24:00 1.30
--- i82557var.h 2002/11/15 04:30:01
*************** struct fxp_softc {
*** 215,220 ****
--- 215,221 ----
#define FXPF_WRITE_ALIGN 0x0040 /* end write on cacheline */
#define FXPF_EXT_TXCB 0x0080 /* enable extended TxCB */
#define FXPF_UCODE_LOADED 0x0100 /* microcode is loaded */
+ #define FXPF_WAIT_LINKUP 0x0200 /* waiting link to up */
int sc_int_delay; /* interrupt delay */
int sc_bundle_max; /* max packet bundle */
Index: i82557.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/i82557.c,v
retrieving revision 1.69
diff -p -c -r1.69 i82557.c
*** i82557.c 2002/11/15 03:30:26 1.69
--- i82557.c 2002/11/15 04:30:01
*************** fxp_start(struct ifnet *ifp)
*** 910,915 ****
--- 916,923 ----
m0 = m;
}
+ if (0) mbuf_print(m0, 0, printf);
+
/* Initialize the fraglist. */
for (seg = 0; seg < dmamap->dm_nsegs; seg++) {
txd->txd_tbd[seg].tb_addr =
*************** fxp_txintr(struct fxp_softc *sc)
*** 1093,1099 ****
int i;
u_int16_t txstat;
- ifp->if_flags &= ~IFF_OACTIVE;
for (i = sc->sc_txdirty; sc->sc_txpending != 0;
i = FXP_NEXTTX(i), sc->sc_txpending--) {
txd = FXP_CDTX(sc, i);
--- 1101,1106 ----
*************** fxp_txintr(struct fxp_softc *sc)
*** 1118,1129 ****
/* Update the dirty transmit buffer pointer. */
sc->sc_txdirty = i;
! /*
! * Cancel the watchdog timer if there are no pending
! * transmissions.
! */
! if (sc->sc_txpending == 0)
! ifp->if_timer = 0;
}
/*
--- 1125,1139 ----
/* Update the dirty transmit buffer pointer. */
sc->sc_txdirty = i;
! if ((sc->sc_flags & FXPF_WAIT_LINKUP) == 0) {
! /*
! * Cancel the watchdog timer if there are no pending
! * transmissions.
! */
! if (sc->sc_txpending == 0)
! ifp->if_timer = 0;
! ifp->if_flags &= ~IFF_OACTIVE;
! }
}
/*
*************** fxp_watchdog(struct ifnet *ifp)
*** 1425,1430 ****
--- 1435,1453 ----
{
struct fxp_softc *sc = ifp->if_softc;
+ if (sc->sc_flags & FXPF_WAIT_LINKUP) {
+ /*
+ * The link didn't up (or failed to detect it).
+ * Give up and start transmit anyway.
+ */
+ printf("%s: link up wasn't detected\n", sc->sc_dev.dv_xname);
+ sc->sc_flags &= ~FXPF_WAIT_LINKUP;
+ ifp->if_flags &= ~IFF_OACTIVE;
+ ifp->if_timer = 0;
+ fxp_start(ifp);
+ return;
+ }
+
printf("%s: device timeout\n", sc->sc_dev.dv_xname);
ifp->if_oerrors++;
*************** fxp_init(struct ifnet *ifp)
*** 1736,1742 ****
* ...all done!
*/
ifp->if_flags |= IFF_RUNNING;
! ifp->if_flags &= ~IFF_OACTIVE;
/*
* Start the one second timer.
--- 1759,1770 ----
* ...all done!
*/
ifp->if_flags |= IFF_RUNNING;
!
! if (sc->sc_flags & FXPF_WAIT_LINKUP) {
! ifp->if_flags |= IFF_OACTIVE;
! ifp->if_timer = 5;
! } else
! ifp->if_flags &= ~IFF_OACTIVE;
/*
* Start the one second timer.
*************** fxp_mdi_read(struct device *self, int ph
*** 1875,1882 ****
void
fxp_statchg(struct device *self)
{
! /* Nothing to do. */
}
void
--- 1903,1918 ----
void
fxp_statchg(struct device *self)
{
+ struct fxp_softc *sc = (struct fxp_softc *)self;
+ struct ifnet *ifp = &sc->sc_ethercom.ec_if;
! if ((sc->sc_flags & FXPF_WAIT_LINKUP) != 0 &&
! (sc->sc_mii.mii_media_status & IFM_ACTIVE) != 0) {
! sc->sc_flags &= ~FXPF_WAIT_LINKUP;
! ifp->if_flags &= ~IFF_OACTIVE;
! ifp->if_timer = 0;
! fxp_start(ifp);
! }
}
void
*************** fxp_enable(struct fxp_softc *sc)
*** 2161,2166 ****
--- 2197,2204 ----
sc->sc_dev.dv_xname);
return (EIO);
}
+ if (sc->sc_flags & FXPF_MII)
+ sc->sc_flags |= FXPF_WAIT_LINKUP;
}
sc->sc_enabled = 1;