Subject: re: 3Com 3c59x woes...
To: NetBSD-current Users <current-users@NetBSD.ORG>
From: Curt Sampson <curt@portal.ca>
List: current-users
Date: 10/10/1996 15:37:21
[This is a repost of something that went to port-i386, since I messed
up when I added current-users to the cc line of that message.]

On Thu, 10 Oct 1996, Andrew Y Ng wrote:

> Please notify me when any of u guys got a working fix for the 3c590 PCI 
> driver, ok?  thx ton!
> 
> for now, I modified cron and do ifconfig down and up every five minutes.

This patch should keep the interface from locking up completely.
Performance at 10Mbps is acceptable (7.5 Mbps on a 486/100), but
100 Mbps still has problems. Apply it in /sys/dev/ic.

Your machine should print `ep1: shifting address bits by 2' when
it boots. If it prints anything else, let me know. If anyone can
test this on other cards, I'd appreciate it. All 3c59x and 3c90x
cards should shift by 2 bits, all other should shift by zero.

If you get a message that says `ep1: TX_AVAIL_THRESH = <some number>;
interface disabled', you might want to shut down your machine; I
probably do not do the right thing in that case.

This should be in current-users, I think; please remove port-i386
from replies.

cjs

Curt Sampson    curt@portal.ca		Info at http://www.portal.ca/
Internet Portal Services, Inc.	
Vancouver, BC   (604) 257-9400		De gustibus, aut bene aut nihil.


*** elink3var.h	1996/05/15 11:33:01	1.1.1.1
--- elink3var.h	1996/10/10 22:28:23
***************
*** 48,53 ****
--- 48,54 ----
  	int	tx_start_thresh;	/* Current TX_start_thresh.	*/
  	int	tx_succ_ok;		/* # packets sent in sequence   */
  					/* w/o underrun			*/
+ 	u_char	txashift;		/* shift packet size in cards w/ large packets */
  	u_char	bustype;
  #define EP_BUS_ISA	  	0x0
  #define	EP_BUS_PCMCIA	  	0x1

*** elink3.c	1996/05/15 11:33:01	1.1.1.1
--- elink3.c	1996/10/10 22:28:28
***************
*** 145,150 ****
--- 145,197 ----
  
  	printf(" address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
  
+ 	/*
+ 	 * PCI cards allow 4500 byte packets, which an 11-bit address isn't
+ 	 * big enough to hold. In commands to these cards we give the packet
+ 	 * size in 32-bit words. To detect these cards, we write a transmit
+ 	 * threshold and see if it was interpreted as bytes or as words.
+ 	 * (This is based on code from Tom Killian (tom@research.att.com)).
+ 	 */
+ 	bus_io_write_2(bc, ioh, EP_COMMAND, SET_TX_AVAIL_THRESH | 1800 ); 
+ 	GO_WINDOW(5);
+ 	i = bus_io_read_2(bc, ioh, EP_W5_TX_AVAIL_THRESH);
+ 	GO_WINDOW(1);
+ 	switch (i)  {
+ 
+ 	case 1800:
+ 		sc->txashift = 0;
+ 		break;
+ 
+ 	case 7200:
+ 		sc->txashift = 2;
+ 		break;
+ 
+ 	default:
+ 		printf("%s: TX_AVAIL_THRESH = %d; interface disabled",
+ 		    sc->sc_dev.dv_xname, (int) i);
+ 		return;
+ 	}
+ 	printf("%s: shifting address bits by %d\n", sc->sc_dev.dv_xname, (int) sc->txashift);
+ 
  	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
  	ifp->if_softc = sc;
  	ifp->if_start = epstart;
***************
*** 338,350 ****
  
  	if (bus_io_read_2(bc, ioh, EP_W1_FREE_TX) < len + pad + 4) {
  		bus_io_write_2(bc, ioh, EP_COMMAND,
! 		    SET_TX_AVAIL_THRESH | (len + pad + 4));
  		/* not enough room in FIFO */
  		ifp->if_flags |= IFF_OACTIVE;
  		return;
  	} else {
  		bus_io_write_2(bc, ioh, EP_COMMAND,
! 		    SET_TX_AVAIL_THRESH | 2044);
  	}
  
  	IF_DEQUEUE(&ifp->if_snd, m0);
--- 385,398 ----
  
  	if (bus_io_read_2(bc, ioh, EP_W1_FREE_TX) < len + pad + 4) {
  		bus_io_write_2(bc, ioh, EP_COMMAND,
! 		    SET_TX_AVAIL_THRESH | ((len + pad + 4) >> sc->txashift) );
  		/* not enough room in FIFO */
  		ifp->if_flags |= IFF_OACTIVE;
  		return;
  	} else {
  		bus_io_write_2(bc, ioh, EP_COMMAND,
! 		    SET_TX_AVAIL_THRESH | (2044 >> sc->txashift) );
! 		/* XXX should not be shifted, perhaps? or 2047? */
  	}
  
  	IF_DEQUEUE(&ifp->if_snd, m0);