Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Jul 2000 18:30:11 -0600
From:      "Kenneth D. Merry" <ken@kdm.org>
To:        Jin Guojun <jin@george.lbl.gov>
Cc:        jhartley@netrail.net, mjacob@feral.com, freebsd-hardware@FreeBSD.ORG
Subject:   Re: SysKonnect and Intel gig boards
Message-ID:  <20000710183011.A29172@panzer.kdm.org>
In-Reply-To: <200007102356.e6ANuGk18566@portnoy.lbl.gov>; from jin@george.lbl.gov on Mon, Jul 10, 2000 at 04:56:16PM -0700
References:  <200007102356.e6ANuGk18566@portnoy.lbl.gov>

next in thread | previous in thread | raw e-mail | index | archive | help

--9amGYk9869ThD9tj
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon, Jul 10, 2000 at 16:56:16 -0700, Jin Guojun wrote:
> Matthew Jacob <mjacob@feral.com> Wrote:
> 
> > Don't use the wx driven EEPRO-1000 from 4.0 (wait for the 4.1 release which
> > will have some bug fixes).
> > 
> > I can't speak about SysKonnect. The Tigon-II based NetGear cards have been
> > peachy.
> 
> Just more info.:
> 
> SysKonnect and Intel EEPRO-1000 have the similar pricey, but they work well.
> The Tigon-II based NetGear card is cheaper, but has a couple of drawback:
> 	(1) the driver under FreeBSD up/down a couple of times at boottime,
> 		this causes NFS mount failure during boot. It is not a big
> 		deal. I fixed it in rc.local with a line:
> 
> 		df | grep $mymount_point || mount -a

You can fix that by sleeping for 5 seconds or so after the ifconfig.

I've got some patches that fix that behavior by waiting for the 5 seconds
or the link to come up before returning from the ifconfig.

The patches are against the zero copy version of the Tigon driver, and based
on a quick test, they won't apply cleanly to the -current version of the
driver.  You can probably figure out what's going on, though.  Anyway, the
patches are attached.

If you want to try the zero copy code as well, it is located here:

http://people.FreeBSD.ORG/~ken/zero_copy/

> 	(2) chewing significant CPU: (tested on completely idle machines)
> 		500 MHz P-III + single NetGear A620 I/O
> 	takes 47% CPU time
> 
> 		750 MHz AMD K7 + single NetGear A620 I/O
> 	takes less 10% CPU
> 
> 		500 MHz P-III + single SysKonnect I/O
> 	takes less 5% CPU

What benchmark are you running and what size packets are you using?

I think I mentioned to you before that the driver is probably tuned for
9000 byte packets, and you might need to tweak things somewhat to get
better performance with 1500 byte packets.

> If you have a high end machine, it is probably not a big issue. The driver
> chews CPU on both FreeBSD and Linux; so it is driver issue, but O.S. Hopefully,
> the newer driver will fix the problem.

Ken
-- 
Kenneth Merry
ken@kdm.org

--9amGYk9869ThD9tj
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="if_ti.wait_for_link.20000710"

==== //depot/cam/sys/pci/if_ti.c#32 - /a/ken/perforce2/cam/sys/pci/if_ti.c ====
*** /tmp/tmp.66522.0	Mon Jul 10 18:27:04 2000
--- /a/ken/perforce2/cam/sys/pci/if_ti.c	Mon Jul 10 14:46:23 2000
***************
*** 229,234 ****
--- 229,235 ----
  static void ti_stop		__P((struct ti_softc *));
  static void ti_watchdog		__P((struct ifnet *));
  static void ti_shutdown		__P((device_t));
+ static void ti_link_timeout	__P((void *));
  static int ti_ifmedia_upd	__P((struct ifnet *));
  static void ti_ifmedia_sts	__P((struct ifnet *, struct ifmediareq *));
  
***************
*** 966,971 ****
--- 967,975 ----
  		e = &sc->ti_rdata->ti_event_ring[sc->ti_ev_saved_considx];
  		switch(e->ti_event) {
  		case TI_EV_LINKSTAT_CHANGED:
+ 		{
+ 			int s;
+ 
  			sc->ti_linkstat = e->ti_code;
  			if (e->ti_code == TI_EV_CODE_LINK_UP)
  				printf("ti%d: 10/100 link up\n", sc->ti_unit);
***************
*** 973,979 ****
--- 977,996 ----
  				printf("ti%d: gigabit link up\n", sc->ti_unit);
  			else if (e->ti_code == TI_EV_CODE_LINK_DOWN)
  				printf("ti%d: link down\n", sc->ti_unit);
+ 			/*
+ 			 * If we're waiting for a link event to return from
+ 			 * an ifconfig type ioctl, wakeup the sleeping
+ 			 * process.
+ 			 */
+ 			s = splimp();
+ 			if (sc->ti_flags & TI_FLAG_WAIT_FOR_LINK) {
+ 				untimeout(ti_link_timeout, sc, sc->link_handle);
+ 				sc->ti_flags &= ~TI_FLAG_WAIT_FOR_LINK;
+ 				wakeup(&sc->ti_flags);
+ 			}
+ 			splx(s);
  			break;
+ 		}
  		case TI_EV_ERROR:
  			if (e->ti_code == TI_EV_CODE_ERR_INVAL_CMD)
  				printf("ti%d: invalid command\n", sc->ti_unit);
***************
*** 2961,2966 ****
--- 2978,2992 ----
  	struct ti_softc		*sc = xsc;
          int			s;
  
+ 	/*
+ 	 * We only want to initialize once, unless the watchdog timer
+ 	 * fires or we're resetting the MTU.
+ 	 */
+ #if 0
+ 	if (++sc->num_inits > 1)
+ 		return;
+ #endif
+ 
  	s = splimp();
  
  	/* Cancel pending I/O and flush buffers. */
***************
*** 3176,3188 ****
--- 3202,3241 ----
  	case SIOCSIFADDR:
  	case SIOCGIFADDR:
  		error = ether_ioctl(ifp, command, data);
+ 
+ 		/*
+ 		 * If this is somehow our first initialization of the chip
+ 		 * (the SIOCSIFADDR ioctl called ti_init() already.), we
+ 		 * need to wait for it to complete.  If this isn't the
+ 		 * first initialization, ti_init() returned without doing
+ 		 * anything so we don't need to wait.
+ 		 */
+ #if 0
+ 		if ((command == SIOCSIFADDR)
+ 		 && (sc->num_inits == 1)) {
+ #endif
+ 		if (command == SIOCSIFADDR) {
+ 			sc->link_handle = timeout(ti_link_timeout, sc,
+ 						  TI_LINK_TIMEOUT * hz);
+ 			sc->ti_flags |= TI_FLAG_WAIT_FOR_LINK;
+ 			do {
+ 				tsleep(&sc->ti_flags, PSOCK, "tilksa", 0);
+ 			} while (sc->ti_flags & TI_FLAG_WAIT_FOR_LINK);
+ 		}
  		break;
  	case SIOCSIFMTU:
  		if (ifr->ifr_mtu > TI_JUMBO_MTU)
  			error = EINVAL;
  		else {
  			ifp->if_mtu = ifr->ifr_mtu;
+ 			sc->num_inits = 0;
  			ti_init(sc);
+  			sc->link_handle = timeout(ti_link_timeout, sc,
+  						  TI_LINK_TIMEOUT * hz);
+ 			sc->ti_flags |= TI_FLAG_WAIT_FOR_LINK;
+ 			do {
+ 				tsleep(&sc->ti_flags, PSOCK, "tilkmt", 0);
+ 			} while (sc->ti_flags & TI_FLAG_WAIT_FOR_LINK);
  		}
  		break;
  	case SIOCSIFFLAGS:
***************
*** 3205,3215 ****
  			    sc->ti_if_flags & IFF_PROMISC) {
  				TI_DO_CMD(TI_CMD_SET_PROMISC_MODE,
  				    TI_CMD_CODE_PROMISC_DIS, 0);
! 			} else
  				ti_init(sc);
  		} else {
  			if (ifp->if_flags & IFF_RUNNING) {
  				ti_stop(sc);
  			}
  		}
  		sc->ti_if_flags = ifp->if_flags;
--- 3258,3297 ----
  			    sc->ti_if_flags & IFF_PROMISC) {
  				TI_DO_CMD(TI_CMD_SET_PROMISC_MODE,
  				    TI_CMD_CODE_PROMISC_DIS, 0);
! 			} else {
  				ti_init(sc);
+  				sc->link_handle = timeout(ti_link_timeout, sc,
+  							  TI_LINK_TIMEOUT * hz);
+ 				sc->ti_flags |= TI_FLAG_WAIT_FOR_LINK;
+ 				do {
+ 					tsleep(&sc->ti_flags, PSOCK,
+ 					       "tilkup", 0);
+ 				} while (sc->ti_flags & TI_FLAG_WAIT_FOR_LINK);
+ 			}
  		} else {
  			if (ifp->if_flags & IFF_RUNNING) {
+ 				/*
+ 				 * XXX KDM for some reason when you take
+ 				 * the link down, it doesn't always give
+ 				 * you a link down event.  Because of that,
+ 				 * you'll never wake up from the sleep if
+ 				 * you tsleep waiting for the link to come
+ 				 * up.
+ 				 */
+ #if 0
+ 				printf("ti%d: taking interface down\n",
+ 				       sc->ti_unit);
+ #endif
  				ti_stop(sc);
+ #if 0
+ 				sc->ti_flags |= TI_FLAG_WAIT_FOR_LINK;
+ 				do {
+ 					tsleep(&sc->ti_flags, PSOCK,
+ 						"tilkdn", 0);
+ 				} while (sc->ti_flags & TI_FLAG_WAIT_FOR_LINK);
+ 				printf("ti%d: interface is down\n",
+ 				       sc->ti_unit);
+ #endif
  			}
  		}
  		sc->ti_if_flags = ifp->if_flags;
***************
*** 3256,3261 ****
--- 3338,3365 ----
  	return(0);
  }
  
+ static void
+ ti_link_timeout(arg)
+ 	void *arg;
+ {
+ 	struct ti_softc *sc;
+ 	int s;
+ 
+ 	sc = (struct ti_softc *)arg;
+ 
+ 	if (sc == NULL)
+ 		return;
+ 
+ 	s = splimp();
+ 	if (sc->ti_flags & TI_FLAG_WAIT_FOR_LINK) {
+ 		sc->ti_flags &= ~TI_FLAG_WAIT_FOR_LINK;
+ 		wakeup(&sc->ti_flags);
+ 	}
+ 	splx(s);
+ 	printf("ti%d: timeout waiting for link (waited %d seconds)\n",
+ 	       sc->ti_unit, TI_LINK_TIMEOUT);
+ }
+ 
  static int
  ti_close(dev_t dev, int flag, int fmt, struct proc *p)
  {
***************
*** 3564,3569 ****
--- 3668,3674 ----
  	splx(s);
  
  	printf("ti%d: watchdog timeout -- resetting\n", sc->ti_unit);
+ 	sc->num_inits = 0;
  	ti_stop(sc);
  	ti_init(sc);
  
==== //depot/cam/sys/pci/if_tireg.h#16 - /a/ken/perforce2/cam/sys/pci/if_tireg.h ====
*** /tmp/tmp.66522.1	Mon Jul 10 18:27:04 2000
--- /a/ken/perforce2/cam/sys/pci/if_tireg.h	Tue Jun 27 17:13:23 2000
***************
*** 983,991 ****
--- 983,997 ----
  	TI_FLAG_WAIT_FOR_LINK	= 0x02
  } ti_flag_vals;
  
+ /*
+  * Wait 5 seconds for link, then give up.
+  */
+ #define TI_LINK_TIMEOUT		5
+ 
  struct ti_softc {
  	STAILQ_ENTRY(ti_softc)	ti_links;
  	struct arpcom		arpcom;		/* interface info */
+ 	int			num_inits;
  	bus_space_handle_t	ti_bhandle;
  	vm_offset_t		ti_vhandle;
  	bus_space_tag_t		ti_btag;
***************
*** 1021,1026 ****
--- 1027,1033 ----
  	int			ti_txcnt;
  	ti_flag_vals		ti_flags;
  	dev_t			dev;
+ 	struct callout_handle	link_handle;
  };
  
  /*

--9amGYk9869ThD9tj--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hardware" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000710183011.A29172>