From owner-FreeBSD-users-jp@jp.freebsd.org  Tue Dec  8 08:01:41 1998
Received: (from daemon@localhost)
	by jaz.jp.freebsd.org (8.9.1+3.1W/8.7.3) id IAA13744;
	Tue, 8 Dec 1998 08:01:41 +0900 (JST)
	(envelope-from owner-FreeBSD-users-jp@jp.FreeBSD.org)
Received: from pop3.tky.3web.ne.jp (root@pop3.tky.3web.ne.jp [202.235.209.51])
	by jaz.jp.freebsd.org (8.9.1+3.1W/8.7.3) with ESMTP id IAA13737
	for <FreeBSD-users-jp@jp.freebsd.org>; Tue, 8 Dec 1998 08:01:39 +0900 (JST)
	(envelope-from yukinopo@tky.3web.ne.jp)
Received: from tky.3web.ne.jp (osks030.osk.3web.ne.jp [202.235.196.30]) by pop3.tky.3web.ne.jp (8.8.8+2.7Wbeta7/3.6W-98052215) with ESMTP id IAA04050 for <FreeBSD-users-jp@jp.freebsd.org>; Tue, 8 Dec 1998 08:01:35 +0900 (JST)
Message-ID: <366C5FDA.B92D32B4@tky.3web.ne.jp>
Date: Tue, 08 Dec 1998 08:08:10 +0900
From: Kounosuke Shiomi <yukinopo@tky.3web.ne.jp>
X-Mailer: Mozilla 4.5b1 [ja] (Win95; I)
X-Accept-Language: ja
MIME-Version: 1.0
To: "FreeBSD-users-jp@jp.freebsd.org" <FreeBSD-users-jp@jp.freebsd.org>
Content-Type: multipart/mixed;
 boundary="------------3FB04EDF1EDBDBCE0F9B014D"
Reply-To: FreeBSD-users-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+981115
X-Sequence: FreeBSD-users-jp 36205
Subject: [FreeBSD-users-jp 36205] ex driver patch for EtherExpress 10 ISA patch
Errors-To: owner-FreeBSD-users-jp@jp.freebsd.org
Sender: owner-FreeBSD-users-jp@jp.freebsd.org

This is a multi-part message in MIME format.
--------------3FB04EDF1EDBDBCE0F9B014D
Content-Type: text/plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit

$B1v8+(B@3web$B$H?=$7$^$9!#(B

Intel $B$N(B EtherExpress 10 ISA$B$r(Bex$B%I%i%$%P$G;H$($k$h$&$K$9$k%Q%C%A$G$9!#(B

$B$3$N%\!<%I$O!"(Bi82595$B$r@Q$s$G$$$^$9$,!"0lIt$N%l%8%9%?$,$U$D$&$NJ}K!$G$O(B
$B%"%/%;%9=PMh$J$$$?$a!$$=$N%l%8%9%?%"%/%;%9$NItJ,$r=q$-49$($F$$$^$9!#(B

EtherExpress 10 PRO$B$G;HMQ$7$F$bLdBj$J$$$h$&$K$7$?$D$b$j$G$9$,!"%F%9%H(B
$B=PMh$k4D6-$,$J$$$N$GIT6q9g$,=P$k$+$b$7$l$^$;$s!#(B

$B$H$3$m$G!"$3$s$J%Q%C%A$r(Brelease$B$H$+$K<h$jF~$l$F$[$7$$$H;W$C$?$i!"(B
$B$I$&$9$l$P$h$$$N$G$7$g$&!)(B

---------------------------------------
Kounosuke Shiomi
	<yukinopo@tky.3web.ne.jp>
--------------3FB04EDF1EDBDBCE0F9B014D
Content-Type: text/plain; charset=iso-2022-jp;
 name="if_ex.c.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="if_ex.c.diff"

*** if_ex.c.dist	Sun Oct 18 01:20:41 1998
--- if_ex.c	Mon Dec  7 23:05:10 1998
***************
*** 102,107 ****
--- 102,110 ----
  	u_short irq_no; /* IRQ number. */
  	char *irq2ee; /* irq <-> internal representation conversion */
  	u_char *ee2irq;
+         u_int revision; /*i82595fx revision*/
+         u_int mask;     /*another's mask save area*/
+         u_int unit;     /*resolv unit no*/
  	u_int mem_size;	/* Total memory size, in bytes. */
  	u_int rx_mem_size;	/* Rx memory size (by default, first 3/4 of total memory). */
    u_int rx_lower_limit, rx_upper_limit; /* Lower and upper limits of receive buffer. */
***************
*** 109,115 ****
  	u_int tx_mem_size;	/* Tx memory size (by default, last quarter of total memory). */
    u_int tx_lower_limit, tx_upper_limit; /* Lower and upper limits of transmit buffer. */
    u_int tx_head, tx_tail; /* Head and tail of transmit ring buffer. */
!   u_int tx_last; /* Pointer to beginning of last frame in the chain. */
  };
  
  static struct ex_softc ex_sc[NEX]; /* XXX would it be better to malloc(3) the memory? */
--- 112,118 ----
  	u_int tx_mem_size;	/* Tx memory size (by default, last quarter of total memory). */
    u_int tx_lower_limit, tx_upper_limit; /* Lower and upper limits of transmit buffer. */
    u_int tx_head, tx_tail; /* Head and tail of transmit ring buffer. */
!   u_int tx_last; /* Pointer to beginning of last frame in the chain. */ 
  };
  
  static struct ex_softc ex_sc[NEX]; /* XXX would it be better to malloc(3) the memory? */
***************
*** 128,138 ****
  static void ex_reset __P((int));
  static void ex_watchdog __P((struct ifnet *));
  
! static u_short eeprom_read __P((int, int));
  static int look_for_card __P((u_int));
  static void ex_tx_intr __P((int));
  static void ex_rx_intr __P((int));
  
  struct isa_driver exdriver = {
  	ex_probe,
  	ex_attach,
--- 131,147 ----
  static void ex_reset __P((int));
  static void ex_watchdog __P((struct ifnet *));
  
! 
! 
! static u_short eeprom_read2 __P((int, int));
  static int look_for_card __P((u_int));
  static void ex_tx_intr __P((int));
  static void ex_rx_intr __P((int));
  
+ static void mask_save __P((int unit,int bank));
+ static void mask_restore __P((int unit,int bank));
+ 
+ 
  struct isa_driver exdriver = {
  	ex_probe,
  	ex_attach,
***************
*** 140,145 ****
--- 149,155 ----
  	0
  };
  
+ 
  static int look_for_card(u_int iobase)
  {
  	int count1, count2;
***************
*** 164,169 ****
--- 174,183 ----
  	u_int iobase;
  	u_short eaddr_tmp;
  	int tmp;
+ 	    u_int rev_check=0;
+ 
+ 	/* Initialize Revision flag */
+ 	sc->revision = 0;
  
  	DODEBUG(Start_End, printf("ex_probe%d: start\n", unit););
  
***************
*** 199,214 ****
  	 *	- Connector type.
  	 */
  	sc->iobase = iobase;
! 	eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Lo);
! 	sc->arpcom.ac_enaddr[5] = eaddr_tmp & 0xff;
! 	sc->arpcom.ac_enaddr[4] = eaddr_tmp >> 8;
! 	eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Mid);
! 	sc->arpcom.ac_enaddr[3] = eaddr_tmp & 0xff;
! 	sc->arpcom.ac_enaddr[2] = eaddr_tmp >> 8;
! 	eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Hi);
! 	sc->arpcom.ac_enaddr[1] = eaddr_tmp & 0xff;
! 	sc->arpcom.ac_enaddr[0] = eaddr_tmp >> 8;
! 	tmp = eeprom_read(iobase, EE_IRQ_No) & IRQ_No_Mask;
  
  	/* work out which set of irq <-> internal tables to use */
  	if (sc->arpcom.ac_enaddr[0] == 0x00 &&
--- 213,237 ----
  	 *	- Connector type.
  	 */
  	sc->iobase = iobase;
! 	sc->unit   = unit;
! 	do
! 	{
! 		eaddr_tmp = eeprom_read2(unit, EE_Eth_Addr_Lo);
! 		rev_check = eaddr_tmp;
! 		sc->arpcom.ac_enaddr[5] = eaddr_tmp & 0xff;
! 		sc->arpcom.ac_enaddr[4] = eaddr_tmp >> 8;
! 		eaddr_tmp = eeprom_read2(unit, EE_Eth_Addr_Mid);
! 		rev_check +=eaddr_tmp;
! 		sc->arpcom.ac_enaddr[3] = eaddr_tmp & 0xff;
! 		sc->arpcom.ac_enaddr[2] = eaddr_tmp >> 8;
! 		eaddr_tmp = eeprom_read2(unit, EE_Eth_Addr_Hi);
! 		rev_check +=eaddr_tmp;
! 		sc->arpcom.ac_enaddr[1] = eaddr_tmp & 0xff;
! 		sc->arpcom.ac_enaddr[0] = eaddr_tmp >> 8;
! 		if(rev_check==0)  sc->revision=1;
! 	}
! 	while(rev_check==0);
! 	tmp = eeprom_read2(unit, EE_IRQ_No) & IRQ_No_Mask;
  
  	/* work out which set of irq <-> internal tables to use */
  	if (sc->arpcom.ac_enaddr[0] == 0x00 &&
***************
*** 313,318 ****
--- 336,342 ----
  	int s, i;
  	register int iobase = sc->iobase;
  	unsigned short temp_reg;
+ 	u_int unit=sc->unit;
  
  	DODEBUG(Start_End, printf("ex_init%d: start\n", ifp->if_unit););
  
***************
*** 324,333 ****
  	/*
  	 * Load the ethernet address into the card.
  	 */
  	outb(iobase + CMD_REG, Bank2_Sel);
! 	temp_reg = inb(iobase + EEPROM_REG);
  	if (temp_reg & Trnoff_Enable)
! 	  outb(iobase + EEPROM_REG, temp_reg & ~Trnoff_Enable);
  	for (i = 0; i < ETHER_ADDR_LEN; i++)
  	  outb(iobase + I_ADDR_REG0 + i, sc->arpcom.ac_enaddr[i]);
  	/*
--- 348,359 ----
  	/*
  	 * Load the ethernet address into the card.
  	 */
+ 	if(sc->revision) mask_save(unit,2);
  	outb(iobase + CMD_REG, Bank2_Sel);
! 	temp_reg = inb(iobase + EEPROM_REG^sc->revision);
  	if (temp_reg & Trnoff_Enable)
! 	  outb(iobase + EEPROM_REG^sc->revision, temp_reg & ~Trnoff_Enable);
! 	if(sc->revision) mask_restore(unit,2);
  	for (i = 0; i < ETHER_ADDR_LEN; i++)
  	  outb(iobase + I_ADDR_REG0 + i, sc->arpcom.ac_enaddr[i]);
  	/*
***************
*** 356,363 ****
  	sc->tx_upper_limit = sc->mem_size - 2;
  	outb(iobase + RCV_LOWER_LIMIT_REG, sc->rx_lower_limit >> 8);
  	outb(iobase + RCV_UPPER_LIMIT_REG, sc->rx_upper_limit >> 8);
! 	outb(iobase + XMT_LOWER_LIMIT_REG, sc->tx_lower_limit >> 8);
! 	outb(iobase + XMT_UPPER_LIMIT_REG, sc->tx_upper_limit >> 8);
  	
  	/*
  	 * Enable receive and transmit interrupts, and clear any pending int.
--- 382,391 ----
  	sc->tx_upper_limit = sc->mem_size - 2;
  	outb(iobase + RCV_LOWER_LIMIT_REG, sc->rx_lower_limit >> 8);
  	outb(iobase + RCV_UPPER_LIMIT_REG, sc->rx_upper_limit >> 8);
! 	if(sc->revision) mask_save(unit,1);
! 	outb(iobase + XMT_LOWER_LIMIT_REG^sc->revision, sc->tx_lower_limit >> 8);
! 	outb(iobase + XMT_UPPER_LIMIT_REG^sc->revision, sc->tx_upper_limit >> 8);
! 	if(sc->revision) mask_restore(unit,1);
  	
  	/*
  	 * Enable receive and transmit interrupts, and clear any pending int.
***************
*** 373,379 ****
  	outw(iobase + RCV_BAR, sc->rx_lower_limit);
  	sc->rx_head = sc->rx_lower_limit;
  	outw(iobase + RCV_STOP_REG, sc->rx_upper_limit | 0xfe);
! 	outw(iobase + XMT_BAR, sc->tx_lower_limit);
  	sc->tx_head = sc->tx_tail = sc->tx_lower_limit;
  
  	ifp->if_flags |= IFF_RUNNING;
--- 401,416 ----
  	outw(iobase + RCV_BAR, sc->rx_lower_limit);
  	sc->rx_head = sc->rx_lower_limit;
  	outw(iobase + RCV_STOP_REG, sc->rx_upper_limit | 0xfe);
! 	if(sc->revision)
! 	{
! 	  mask_save(unit,0);
! 	  outb(iobase + XMT_BAR | sc->revision,sc->tx_lower_limit&0xff);
! 	  outb(iobase + XMT_BAR               ,sc->tx_lower_limit>>8);
! 	  mask_restore(unit,0);
! 	}
! 	else
! 	  outw(iobase + XMT_BAR, sc->tx_lower_limit);
! 
  	sc->tx_head = sc->tx_tail = sc->tx_lower_limit;
  
  	ifp->if_flags |= IFF_RUNNING;
***************
*** 511,517 ****
        outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int));
  #endif
        if (sc->tx_head == sc->tx_tail) {
! 	outw(iobase + XMT_BAR, dest);
  	outb(iobase + CMD_REG, Transmit_CMD);
  	sc->tx_head = dest;
  	DODEBUG(Sent_Pkts, printf("Transmit\n"););
--- 548,563 ----
        outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int));
  #endif
        if (sc->tx_head == sc->tx_tail) {
! 	  if(sc->revision)
! 	  {
! 		mask_save(unit,0);
! 		outb(iobase + XMT_BAR | sc->revision, dest&0xff);
! 		outb(iobase + XMT_BAR               , dest>>8);
! 		mask_restore(unit,0);
! 	  }
! 	  else
! 		outw(iobase + XMT_BAR, dest);
! 
  	outb(iobase + CMD_REG, Transmit_CMD);
  	sc->tx_head = dest;
  	DODEBUG(Sent_Pkts, printf("Transmit\n"););
***************
*** 910,924 ****
  }
  
  
! static u_short eeprom_read(int iobase, int location)
  {
  	int i;
  	u_short data = 0;
  	int ee_addr;
  	int read_cmd = location | EE_READ_CMD;
  	short ctrl_val = EECS;
  
! 	ee_addr = iobase + EEPROM_REG;
  	outb(iobase + CMD_REG, Bank2_Sel);
  	outb(ee_addr, EECS);
  	for (i = 8; i >= 0; i--) {
--- 956,976 ----
  }
  
  
!  static u_short eeprom_read2(int unit, int location)
  {
+         struct ex_softc *sc = &ex_sc[unit];
+ 
  	int i;
  	u_short data = 0;
  	int ee_addr;
  	int read_cmd = location | EE_READ_CMD;
  	short ctrl_val = EECS;
+ 
+         int iobase = sc->iobase;
+         if(sc->revision)  mask_save(unit,2);
  
! 
! 	ee_addr = sc->iobase + EEPROM_REG + sc->revision;
  	outb(iobase + CMD_REG, Bank2_Sel);
  	outb(ee_addr, EECS);
  	for (i = 8; i >= 0; i--) {
***************
*** 944,951 ****
--- 996,1025 ----
  	DELAY(3);
  	outb(ee_addr, ctrl_val);
  	DELAY(2);
+ 
+         if(sc->revision)  mask_restore(unit,0);
+ 
  	outb(iobase + CMD_REG, Bank0_Sel);
  	return(data);
  }
  
+ 
+ void mask_save(int unit,int bank)
+ {
+         struct ex_softc *sc = &ex_sc[unit];
+         outb(sc->iobase+CMD_REG,Bank1_Sel);
+         sc->mask=inb(sc->iobase+REG1);
+         outb(sc->iobase+REG1,sc->mask&0xfd);
+         outb(sc->iobase+CMD_REG,Bank0_Sel|bank<<6);
+ }
+ 
+ void mask_restore(int unit,int bank)
+ {
+         struct ex_softc *sc = &ex_sc[unit];
+ 
+         outb(sc->iobase+CMD_REG,Bank1_Sel);
+         outb(sc->iobase+REG1,sc->mask);
+         outb(sc->iobase+CMD_REG,Bank0_Sel|bank<<6);
+ }
+ 
  #endif /* NEX > 0 */

--------------3FB04EDF1EDBDBCE0F9B014D--

