Subject: kern/2877: Transmit IRQ setting for ep driver on 3Com 3c59x/3c90x cards.
To: None <gnats-bugs@gnats.netbsd.org>
From: Curt Sampson <curt@portal.ca>
List: netbsd-bugs
Date: 10/21/1996 00:21:39
>Number:         2877
>Category:       kern
>Synopsis:       Transmit IRQ setting for ep driver on 3Com 3c59x/3c90x cards.
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Oct 21 00:35:01 1996
>Last-Modified:
>Originator:     Curt Sampson
>Organization:
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.
>Release:        1.2
>Environment:
	
System: NetBSD cynic.portal.ca 1.2 NetBSD 1.2 (CYNIC) #10: Mon Oct 14 21:52:17 PDT 1996 curt@amon.portal.ca:/usr/src/sys/arch/i386/compile/CYNIC i386

>Description:
The ep driver is not setting the transmit interrupt properly for 3c59x/3c90x
cards, causing the cards to wedge when the card buffer fills and a packet over
1122 bytes is waiting to be sent.
>How-To-Repeat:
`ping -f -s 1400' into or out of a machine with a 3c59x or 3c90x card.
>Fix:
Apply the following patch in src/sys/dev/ic.

Index: elink3.c
===================================================================
RCS file: /usr2/CVSRoot/netbsd/src/sys/dev/ic/elink3.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -r1.1.1.1 -r1.2
147a148,176
> 	/*
> 	 * 100 Mbps 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 idea is 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);	/* XXX remove later */
> 
341c370
< 		    SET_TX_AVAIL_THRESH | (len + pad + 4));
---
> 		    SET_TX_AVAIL_THRESH | ((len + pad + 4) >> sc->txashift) );
345a375
> 		/* disable txAvailable interrupt */
347c377
< 		    SET_TX_AVAIL_THRESH | 2044);
---
> 		    SET_TX_AVAIL_THRESH | 2047 );
Index: elink3reg.h
===================================================================
RCS file: /usr2/CVSRoot/netbsd/src/sys/dev/ic/elink3reg.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1
diff -r1.1.1.1 -r1.1
Index: elink3var.h
===================================================================
RCS file: /usr2/CVSRoot/netbsd/src/sys/dev/ic/elink3var.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -r1.1.1.1 -r1.2
50a51
> 	u_char	txashift;		/* shift packet size in cards w/ large packets */
>Audit-Trail:
>Unformatted: