Subject: kern/20437: Intel EtherExpress16 should be able to autoconfigure (ix* in config)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <djbarnes@ieee.org>
List: netbsd-bugs
Date: 02/19/2003 21:00:09
>Number:         20437
>Category:       kern
>Synopsis:       Intel EtherExpress16 should be able to autoconfigure (ix* in config)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Feb 19 21:01:01 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Dave Barnes
>Release:        1.6-current (1.6L)
>Organization:
>Environment:
>Description:
As it is now you have to specify the ioaddress, shared memory address and interrupt for the Intel EtherExpress16 NIC in the config.  The EEPROM on the NIC has the shared memory and irq info.  A fairly safe probe exists to find the ee16.
>How-To-Repeat:
Can't use the ix1 and ix0 settings in the kernel config for some reason.
>Fix:
The fix is to change the config to:

ix*	at isa? port 0x300 irq ?   #EtherExpress/16

... and let the driver find the card.  Simple enough. Here's the diff:

*** dev/isa/if_ix.c.orig	Wed Feb 19 22:19:00 2003
--- dev/isa/if_ix.c	Wed Feb 19 22:29:50 2003
***************
*** 518,524 ****
  	struct cfdata *cf;
  	void *aux;
  {
! 	int i;
  	int rv = 0;
  	bus_addr_t maddr;
  	bus_size_t msize;
--- 518,524 ----
  	struct cfdata *cf;
  	void *aux;
  {
! 	int i, j;
  	int rv = 0;
  	bus_addr_t maddr;
  	bus_size_t msize;
***************
*** 529,536 ****
--- 529,545 ----
  	u_short pg, adjust, decode, edecode;
  	u_short board_id, id_var1, id_var2, irq, irq_encoded;
  	struct isa_attach_args * const ia = aux;
+ 
+ /*  irq settings include irq12 and irq15
+ 	short irq_translate[] = {0x0c, 0x09, 0x03, 0x04, 0x05, 0x0a, 0x0b, 0x0f};
+ */
  	short irq_translate[] = {0, 0x09, 0x03, 0x04, 0x05, 0x0a, 0x0b, 0};
  
+ /* XXX Change num_ports if io addresses are added or removed */
+     /* Do not use ports 200-20f, 220-22f, 230-23f, 270-27f, 330-33f and 370-37f due to conflicts */
+     int	valid_ioaddr[] = {0x300, 0x310, 0x320, 0x340, 0x350, 0x360, 0x210, 0x240, 0x250, 0x260};
+     int num_ports;
+ 
  	if (ia->ia_nio < 1)
  		return (0);
  	if (ia->ia_niomem < 1)
***************
*** 544,557 ****
  	iot = ia->ia_iot;
  
  	if (ia->ia_io[0].ir_addr == ISACF_PORT_DEFAULT)
! 		return (0);
! 
! 	if (bus_space_map(iot, ia->ia_io[0].ir_addr,
! 			  IX_IOSIZE, 0, &ioh) != 0) {
! 		DPRINTF(("Can't map io space at 0x%x\n", ia->ia_iobase));
! 		return (0);
  	}
  
  	/* XXX: reset any ee16 at the current iobase */
  	bus_space_write_1(iot, ioh, IX_ECTRL, IX_RESET_ASIC);
  	bus_space_write_1(iot, ioh, IX_ECTRL, 0);
--- 553,575 ----
  	iot = ia->ia_iot;
  
  	if (ia->ia_io[0].ir_addr == ISACF_PORT_DEFAULT)
! 		/* No io address in config ? then scan for ee16 */
! 		num_ports = 9;
!     else {
!     	/* Use the io address from config */
!     	valid_ioaddr[0] = ia->ia_io[0].ir_addr;
!     	num_ports = 1;
  	}
  
+ 
+     /* XXX may cause hang if some other hardware responds at any of these io addresses XXX */
+     /*  scan valid addresses for ee16 */
+ 	DPRINTF(("Searching for ee16 @\n"));
+ 	for (i = 0; i < num_ports; i++) {
+ 
+        	DPRINTF(("   0x%x",valid_ioaddr[i]));
+        	if (bus_space_map(iot, valid_ioaddr[i], IX_IOSIZE, 0, &ioh) == 0) {
+            	DPRINTF(("/mapped"));
             	/* XXX: reset any ee16 at the current iobase */
             	bus_space_write_1(iot, ioh, IX_ECTRL, IX_RESET_ASIC);
             	bus_space_write_1(iot, ioh, IX_ECTRL, 0);
***************
*** 559,575 ****
  
  	/* now look for ee16. */
  	board_id = id_var1 = id_var2 = 0;
! 	for (i = 0; i < 4 ; i++) {
  		id_var1 = bus_space_read_1(iot, ioh, IX_ID_PORT);
  		id_var2 = ((id_var1 & 0x03) << 2);
  		board_id |= (( id_var1 >> 4)  << id_var2);
  	}
! 
! 	if (board_id != IX_ID) {
! 		DPRINTF(("BART ID mismatch (got 0x%04x, expected 0x%04x)\n",
! 			board_id, IX_ID));
! 		goto out;
  	}
  
  	/*
  	 * The shared RAM size and location of the EE16 is encoded into
--- 577,600 ----
  
             	/* now look for ee16. */
             	board_id = id_var1 = id_var2 = 0;
!            	for (j = 0; j < 4 ; j++) {
             		id_var1 = bus_space_read_1(iot, ioh, IX_ID_PORT);
             		id_var2 = ((id_var1 & 0x03) << 2);
             		board_id |= (( id_var1 >> 4)  << id_var2);
         	    }
! 			if (board_id == IX_ID) {
! 				DPRINTF(("/found\n"));
! 				ia->ia_io[0].ir_addr = valid_ioaddr[i];
! 				break;
  			}
+ 			else {
+ 				DPRINTF(("/unmapped\n"));
+ 				if (i == (num_ports - 1)) goto out;
+ 				bus_space_unmap(iot, ioh, IX_IOSIZE);
+ 			}
+ 		}
+ 	}
+ 
  
  	/*
  	 * The shared RAM size and location of the EE16 is encoded into
***************
*** 716,722 ****
  	ia->ia_nirq = 1;
  	ia->ia_irq[0].ir_irq = irq;
  
! 	DPRINTF(("ix_match: found board @ 0x%x\n", ia->ia_iobase));
  
  out:
  	bus_space_unmap(iot, ioh, IX_IOSIZE);
--- 741,747 ----
  	ia->ia_nirq = 1;
  	ia->ia_irq[0].ir_irq = irq;
  
! 	DPRINTF(("ix_match: found board @ 0x%x\n", ia->ia_irq[0].ir_irq));
  
  out:
  	bus_space_unmap(iot, ioh, IX_IOSIZE);
***************
*** 756,762 ****
  			  ia->ia_io[0].ir_size, 0, &ioh) != 0) {
  
  		DPRINTF(("\n%s: can't map i/o space 0x%x-0x%x\n",
! 			  sc->sc_dev.dv_xname, ia->ia_[0].ir_addr,
  			  ia->ia_io[0].ir_addr + ia->ia_io[0].ir_size - 1));
  		return;
  	}
--- 781,787 ----
  			  ia->ia_io[0].ir_size, 0, &ioh) != 0) {
  
  		DPRINTF(("\n%s: can't map i/o space 0x%x-0x%x\n",
! 			  sc->sc_dev.dv_xname, ia->ia_io[0].ir_addr,
  			  ia->ia_io[0].ir_addr + ia->ia_io[0].ir_size - 1));
  		return;
  	}
***************
*** 1012,1018 ****
  		      ix_media, NIX_MEDIA, media);
  
  	if (isc->use_pio)
! 		printf("%s: unsupported memory config, using PIO to access %d bytes of memory\n", sc->sc_dev.dv_xname, sc->sc_msize);
  
  	isc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
  	    IST_EDGE, IPL_NET, i82586_intr, sc);
--- 1037,1043 ----
  		      ix_media, NIX_MEDIA, media);
  
  	if (isc->use_pio)
! 		printf("%s: ... using PIO to access %d bytes of memory\n", sc->sc_dev.dv_xname, sc->sc_msize);
  
  	isc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
  	    IST_EDGE, IPL_NET, i82586_intr, sc);


>Release-Note:
>Audit-Trail:
>Unformatted: