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;