Resent-Date: Tue, 5 Jan 1999 11:22:58 +0100 (MET)
Sender: schmitz@lbl.gov
Date: Tue, 05 Jan 1999 02:22:58 -0800
From: Michael Schmitz <MSchmitz@lbl.gov>
Organization: Tinoco Lab, UC Berkekely / Lawrence Berkeley Laboratory
To: Jes Sorensen <Jes.Sorensen@cern.ch>
CC: linux-m68k@lists.linux-m68k.org, linux-mac68k@baltimore.wwaves.com,
        ddkilzer@earthlink.net
Subject: Re: Mac68k patch for 2.1.131
References: <368AB851.AB755387@lbl.gov> <d3g19qoxlw.fsf@valhall.cern.ch>
Resent-From: linux-m68k@phil.uni-sb.de

This is a multi-part message in MIME format.
--------------9307E7248CB2AFEA2DF339E7
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Jes Sorensen wrote:
> Just looking over your patch (while fighting through the ton of email
> people bombarded me with over xmas), a few comments:

Thanks for looking into it...

> head.S stuff will have to wait until Roman (or someone else) sorts it
> out for the Amiga - guess it won't take all that long. Could you

We're currently fighting Roman's head.S patch (the one from the
experimental
set, to end all patches...). Either that works out, or someone finds out
what in the Mac version breaks on Amiga. The same diff went to
linux-mac68k
and the FTP site, that's what head.S is for.

> please bump the Sonic stuff past Thomas Bogendoerfer or whoever is in
> charge of that driver - it makes it a lot easier to get it past Linus
> if it comes with the original owner of the file's approval than for me
> to try to convince him that it doesn't break other people's code.

Got his latest (0.92) Sonic driver already split up, plugged it in,
replaced
macsonic.c with my version and the Sonic just works like a charm. The
patch went to Thomas already, patch relative to mac-2.1.131 attached.
And a tiny
ESP patch as a little extra. 

	Michael
--------------9307E7248CB2AFEA2DF339E7
Content-Type: text/plain; charset=us-ascii; name="mac-2.1.131-macesp.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="mac-2.1.131-macesp.diff"

--- linux-2.1.131/drivers/scsi/mac_esp.c.org	Sun Jan  3 09:02:53 1999
+++ linux-2.1.131/drivers/scsi/mac_esp.c	Sun Jan  3 09:03:02 1999
@@ -59,10 +59,15 @@
 static void dma_setup(struct NCR_ESP * esp, __u32 addr, int count, int write);
 static void dma_setup_quick(struct NCR_ESP * esp, __u32 addr, int count, int write);
 
-
 static int esp_dafb_dma_irq_p(struct NCR_ESP * espdev);
 static int esp_iosb_dma_irq_p(struct NCR_ESP * espdev);
 
+volatile unsigned char cmd_buffer[16];
+				/* This is where all commands are put
+				 * before they are transfered to the ESP chip
+				 * via PIO.
+				 */
+
 static int esp_initialized = 0;
 
 static int setup_num_esps = -1;
@@ -358,9 +363,12 @@
 
 		} /* chipnum == 0 */
 
-
 		/* use pio for command bytes; pio for message/data: TBI */
 		esp->do_pio_cmds = 1;
+
+		/* Set the command buffer */
+		esp->esp_command = (volatile unsigned char*) cmd_buffer;
+		esp->esp_command_dvma = (volatile unsigned char*) cmd_buffer;
 
 		/* various functions */
 		esp->dma_bytes_sent = &dma_bytes_sent;

--------------9307E7248CB2AFEA2DF339E7
Content-Type: application/octet-stream; name="mac-2.1.131-sonic"
Content-Transfer-Encoding: x-uuencode
Content-Disposition: attachment; filename="mac-2.1.131-sonic"

--- linux-2.1.131/drivers/net/jazzsonic.c.mac1	Fri Jan  1 11:38:44 1999
+++ linux-2.1.131/drivers/net/jazzsonic.c	Fri Jan  1 11:39:23 1999
@@ -1,19 +1,18 @@
 /*
- * jazzsonic.c
+ * sonic.c
  *
- * (C) 1996 by Thomas Bogendoerfer (tsbogend@bigbug.franken.de)
+ * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  * 
  * This driver is based on work from Andreas Busse, but most of
  * the code is rewritten.
  * 
  * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de)
  *
- *
  * A driver for the onboard Sonic ethernet controller on Mips Jazz
  * systems (Acer Pica-61, Mips Magnum 4000, Olivetti M700 and
  * perhaps others, too)
  */
- 
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
@@ -33,16 +32,16 @@
 #include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/dma.h>
-
 #include <asm/jazz.h>
 #include <asm/jazzdma.h>
-
 #include <linux/errno.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#define SREGS_PAD(n)    u16 n;
+
 #include "sonic.h"
 
 /*
@@ -55,13 +54,20 @@
 	*((volatile unsigned int *)base_addr+reg) = val
 
 
+/* use 0 for production, 1 for verification, >2 for debug */
+#ifdef SONIC_DEBUG
+static unsigned int sonic_debug = SONIC_DEBUG;
+#else 
+static unsigned int sonic_debug = 1;
+#endif
+
 /*
  * Base address and interupt of the SONIC controller on JAZZ boards
  */
 static struct {
     unsigned int port;
     unsigned int irq;
-    } sonic_portlist[] = { {JAZZ_ETHERNET_BASE, JAZZ_ETHERNET_IRQ}, {0, 0}};
+} sonic_portlist[] = { {JAZZ_ETHERNET_BASE, JAZZ_ETHERNET_IRQ}, {0, 0}};
 
 /*
  * We cannot use station (ethernet) address prefixes to detect the
@@ -74,6 +80,8 @@
   0xffff			/* end of list */
 };
 
+/* Index to functions, as function prototypes. */
+
 extern int sonic_probe(struct device *dev);
 static int sonic_probe1(struct device *dev, unsigned int base_addr, unsigned int irq);
 
@@ -92,7 +100,7 @@
      */
     if (mips_machgroup != MACH_GROUP_JAZZ)
 	return -ENODEV;
-    if (base_addr > 0x1ff)	/* Check a single specified location. */
+    if (base_addr >= KSEG0)	/* Check a single specified location. */
 	return sonic_probe1(dev, base_addr, dev->irq);
     else if (base_addr != 0)	/* Don't probe at all. */
 	return -ENXIO;
@@ -235,26 +243,24 @@
     dev->get_stats	= sonic_get_stats;
     dev->set_multicast_list = &sonic_multicast_list;
 
+    /*
+     * clear tally counter
+     */
+    SONIC_WRITE(SONIC_CRCT,0xffff);
+    SONIC_WRITE(SONIC_FAET,0xffff);
+    SONIC_WRITE(SONIC_MPT,0xffff);
+
     /* Fill in the fields of the device structure with ethernet values. */
     ether_setup(dev);
     return 0;
 }
 
 /*
- *	SONIC uses a normal IRQ
+ *      SONIC uses a normal IRQ
  */
- 
-#define sonic_request_irq	request_irq
-#define sonic_free_irq		free_irq
-
-#define sonic_chiptomem(x)	KSEG1ADDR(vdma_log2phys(x))
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifdef SONIC_DEBUG
-static unsigned int sonic_debug = SONIC_DEBUG;
-#else 
-static unsigned int sonic_debug = 2;
-#endif
+#define sonic_request_irq       request_irq
+#define sonic_free_irq          free_irq
 
+#define sonic_chiptomem(x)      KSEG1ADDR(vdma_log2phys(x))
 
 #include "sonic.c"
--- linux-2.1.131/drivers/net/macsonic.c.mac1	Fri Jan  1 11:38:56 1999
+++ linux-2.1.131/drivers/net/macsonic.c	Sun Jan  3 10:08:12 1999
@@ -49,9 +49,13 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#include <config/macsonic.h>
+
+#define SREGS_PAD(n)    u16 n;
+
 #include "sonic.h"
 
-extern int mac_onboard_sonic_probe(struct device *unused);
+extern int mac_onboard_sonic_probe(void);
 
 static int setup_debug = -1;
 static int setup_offset = -1;
@@ -168,9 +172,9 @@
 static unsigned char nibbletab[] = {0, 8, 4, 12, 2, 10, 6, 14,
 				    1, 9, 5, 13, 3, 11, 7, 15};
 
-__initfunc(int mac_onboard_sonic_probe(struct device *unused))
+__initfunc(int mac_onboard_sonic_probe(void))
 {
-	static struct device *dev;
+	struct device *dev;
 	unsigned int silicon_revision;
 	unsigned int val;
 	struct sonic_local *lp;
@@ -394,13 +398,8 @@
 		 */
 		lp = NULL;
 		i = 0;
-
-		/* 
-		 * Isn't there a better way to allocate a 64kb segment?
-		 */
 		do
 		{
-			/* should we use GFP_DMA here? */
 			lp = (struct sonic_local *) kmalloc(sizeof(*lp), GFP_KERNEL);
 			if ((unsigned long) lp >> 16 != ((unsigned long) lp + sizeof(*lp)) >> 16)
 			{
--- linux-2.1.131/drivers/net/sonic.c.mac1	Fri Jan  1 11:39:03 1999
+++ linux-2.1.131/drivers/net/sonic.c	Fri Jan  1 11:39:23 1999
@@ -1,20 +1,16 @@
 /*
  * sonic.c
  *
- * (C) 1996 by Thomas Bogendoerfer (tsbogend@bigbug.franken.de)
+ * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  * 
  * This driver is based on work from Andreas Busse, but most of
  * the code is rewritten.
  * 
  * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de)
  *
- *
- *	Core code included by system sonic drivers
+ *    Core code included by system sonic drivers
  */
 
-static const char *version =
-	"sonic.c:v0.10 6.7.96 tsbogend@bigbug.franken.de\n";
-
 /*
  * Sources: Olivetti M700-10 Risc Personal Computer hardware handbook,
  * National Semiconductors data sheet for the DP83932B Sonic Ethernet
@@ -30,7 +26,6 @@
  *  registers that "should" only need to be set once at boot, so that
  *  there is non-reboot way to recover if something goes wrong.
  */
-
 static int sonic_open(struct device *dev)
 {
     if (sonic_debug > 2)
@@ -46,10 +41,10 @@
  * covering another bug otherwise corrupting data.  This doesn't mean
  * this glue works ok under all situations.
  */
-//    if (request_irq(dev->irq, &sonic_interrupt, 0, "sonic", dev)) {
+//    if (sonic_request_irq(dev->irq, &sonic_interrupt, 0, "sonic", dev)) {
     if (sonic_request_irq(dev->irq, &sonic_interrupt, SA_INTERRUPT, "sonic", dev)) {
-	  printk ("\n%s: unable to get IRQ %d .\n", dev->name, dev->irq);
-	  return EAGAIN;
+	printk ("\n%s: unable to get IRQ %d .\n", dev->name, dev->irq);
+	return EAGAIN;
     }
 
     /*
@@ -109,23 +104,23 @@
       printk("sonic_send_packet: skb=%p, dev=%p\n",skb,dev);
   
     if (dev->tbusy) {
-	  int tickssofar = jiffies - dev->trans_start;
+	int tickssofar = jiffies - dev->trans_start;
 
-	  /* If we get here, some higher level has decided we are broken.
-		 There should really be a "kick me" function call instead. */
+	/* If we get here, some higher level has decided we are broken.
+	 There should really be a "kick me" function call instead. */
       
-	  if (sonic_debug > 1)
-		printk("sonic_send_packet: called with dev->tbusy = 1 !\n");
+	if (sonic_debug > 1)
+	  printk("sonic_send_packet: called with dev->tbusy = 1 !\n");
 	
-	  if (tickssofar < 5)
-		return 1;
+	if (tickssofar < 5)
+	  return 1;
 	
-	  printk("%s: transmit timed out.\n", dev->name);
+	printk("%s: transmit timed out.\n", dev->name);
 	
-	  /* Try to restart the adaptor. */
-	  sonic_init(dev);
-	  dev->tbusy=0;
-	  dev->trans_start = jiffies;
+	/* Try to restart the adaptor. */
+	sonic_init(dev);
+	dev->tbusy=0;
+	dev->trans_start = jiffies;
     }
 
     /* 
@@ -133,24 +128,25 @@
      * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
      */
     if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
-	  printk("%s: Transmitter access conflict.\n", dev->name);
-	  return 1;
+	printk("%s: Transmitter access conflict.\n", dev->name);
+	return 1;
     }
     
     /*
      * Map the packet data into the logical DMA address space
      */
     if ((laddr = vdma_alloc(PHYSADDR(skb->data),skb->len)) == ~0UL) {
-	  printk("%s: no VDMA entry for transmit available.\n",dev->name);
-	  dev_kfree_skb(skb);
-	  dev->tbusy = 0;
-	  return 1;
+	printk("%s: no VDMA entry for transmit available.\n",dev->name);
+	dev_kfree_skb(skb);
+	dev->tbusy = 0;
+	return 1;
     }
     entry = lp->cur_tx & SONIC_TDS_MASK;    
     lp->tx_laddr[entry] = laddr;
     lp->tx_skb[entry] = skb;
     
     length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
+    flush_cache_all();
     
     /*
      * Setup the transmit descriptor and issue the transmit command.
@@ -161,17 +157,11 @@
     lp->tda[entry].tx_frag_ptr_l = laddr & 0xffff;
     lp->tda[entry].tx_frag_ptr_h = laddr >> 16;
     lp->tda[entry].tx_frag_size  = length;
-    
-    /* if there are already packets queued, allow sending serveral packets at once */
-    if (lp->dirty_tx != lp->cur_tx)
-	  lp->tda[(lp->cur_tx-1) % SONIC_TDS_MASK].link &= ~SONIC_END_OF_LINKS;
-    
     lp->cur_tx++;
+    lp->stats.tx_bytes += length;
     
     if (sonic_debug > 2)
-      printk("sonic_send_packet: issuing Tx command\n");
-
-    flush_cache_all();
+      printk("sonic_send_packet: issueing Tx command\n");
 
     SONIC_WRITE(SONIC_CMD,SONIC_CR_TXP);
 
@@ -199,8 +189,8 @@
     int status;
 
     if (dev == NULL) {
-	  printk ("sonic_interrupt: irq %d for unknown device.\n", irq);
-	  return;
+	printk ("sonic_interrupt: irq %d for unknown device.\n", irq);
+	return;
     }
     dev->interrupt = 1;
     lp = (struct sonic_local *)dev->priv;
@@ -212,78 +202,79 @@
       printk("sonic_interrupt: ISR=%x\n",status);
 
     if (status & SONIC_INT_PKTRX) {
-			if (sonic_debug > 3)
-					printk("received packet!!\n");
-			sonic_rx(dev);				/* got packet(s) */
+	sonic_rx(dev);				/* got packet(s) */
     }
     
     if (status & SONIC_INT_TXDN) {
-	  int dirty_tx = lp->dirty_tx;
-	
-	  while (dirty_tx < lp->cur_tx) {
+	int dirty_tx = lp->dirty_tx;
+
+	while (dirty_tx < lp->cur_tx) {
 	    int entry = dirty_tx & SONIC_TDS_MASK;
 	    int status = lp->tda[entry].tx_status;
-	    
+
 	    if (sonic_debug > 3)
 	      printk ("sonic_interrupt: status %d, cur_tx %d, dirty_tx %d\n",
 		      status,lp->cur_tx,lp->dirty_tx);
-	    
-	    if (status == 0)
-	      break;			/* It still hasn't been Txed */
+
+	    if (status == 0) {
+		/* It still hasn't been Txed, kick the sonic again */
+		SONIC_WRITE(SONIC_CMD,SONIC_CR_TXP);		
+		break;
+	    }
 
 	    /* put back EOL and free descriptor */
-	    lp->tda[entry].link |= SONIC_END_OF_LINKS;
+	    lp->tda[entry].tx_frag_count = 0;
 	    lp->tda[entry].tx_status = 0;
 
 	    if (status & 0x0001)
 	      lp->stats.tx_packets++;
 	    else {
-		  lp->stats.tx_errors++;
-		  if (status & 0x0642) lp->stats.tx_aborted_errors++;
-		  if (status & 0x0180) lp->stats.tx_carrier_errors++;
-		  if (status & 0x0020) lp->stats.tx_window_errors++;
-		  if (status & 0x0004) lp->stats.tx_fifo_errors++;
+		lp->stats.tx_errors++;
+		if (status & 0x0642) lp->stats.tx_aborted_errors++;
+		if (status & 0x0180) lp->stats.tx_carrier_errors++;
+		if (status & 0x0020) lp->stats.tx_window_errors++;
+		if (status & 0x0004) lp->stats.tx_fifo_errors++;
 	    }
 
 	    /* We must free the original skb */
 	    if (lp->tx_skb[entry]) {
-		  dev_kfree_skb(lp->tx_skb[entry]);
-		  lp->tx_skb[entry] = 0;
+		dev_kfree_skb(lp->tx_skb[entry]);
+		lp->tx_skb[entry] = 0;
 	    }
 	    /* and the VDMA address */
 	    vdma_free(lp->tx_laddr[entry]);
 	    dirty_tx++;
-	  }
+	}
 	
-	  if (lp->tx_full && dev->tbusy
+	if (lp->tx_full && dev->tbusy
 	    && dirty_tx + SONIC_NUM_TDS > lp->cur_tx + 2) {
 	    /* The ring is no longer full, clear tbusy. */
 	    lp->tx_full = 0;
 	    dev->tbusy = 0;
 	    mark_bh(NET_BH);
-	  }
+	}
 	
-	  lp->dirty_tx = dirty_tx;
+	lp->dirty_tx = dirty_tx;
     }
     
     /*
      * check error conditions
      */
     if (status & SONIC_INT_RFO) {
-	  printk ("%s: receive fifo underrun\n",dev->name);
-	  lp->stats.rx_fifo_errors++;
+	printk ("%s: receive fifo underrun\n",dev->name);
+	lp->stats.rx_fifo_errors++;
     }
     if (status & SONIC_INT_RDE) {
-	  printk ("%s: receive descriptors exhausted\n",dev->name);
-	  lp->stats.rx_dropped++;
+	printk ("%s: receive descriptors exhausted\n",dev->name);
+	lp->stats.rx_dropped++;
     }
     if (status & SONIC_INT_RBE) {
-	  printk ("%s: receive buffer exhausted\n",dev->name);
-	  lp->stats.rx_dropped++;	
+	printk ("%s: receive buffer exhausted\n",dev->name);
+	lp->stats.rx_dropped++;	
     }
     if (status & SONIC_INT_RBAE) {
-	  printk ("%s: receive buffer area exhausted\n",dev->name);
-	  lp->stats.rx_dropped++;	
+	printk ("%s: receive buffer area exhausted\n",dev->name);
+	lp->stats.rx_dropped++;	
     }
 
     /* counter overruns; all counters are 16bit wide */
@@ -314,35 +305,33 @@
 {
     unsigned int base_addr = dev->base_addr;
     struct sonic_local *lp = (struct sonic_local *)dev->priv;
-    int entry = lp->cur_rx & SONIC_RDS_MASK;
+    sonic_rd_t *rd = &lp->rda[lp->cur_rx & SONIC_RDS_MASK];
     int status;
 
-    while(lp->rda[entry].in_use == 0)
-    {
-	  struct sk_buff *skb;
-	  int pkt_len;
-	  unsigned char *pkt_ptr;
-	
-	  status = lp->rda[entry].rx_status;
-	  if (sonic_debug > 3)
-		printk ("status %x, cur_rx %d, cur_rra %d\n",status,lp->cur_rx,lp->cur_rra);
-	  if (status & SONIC_RCR_PRX) {	    
-	    pkt_len = lp->rda[entry].rx_pktlen;
-	    pkt_ptr = (char *)sonic_chiptomem((lp->rda[entry].rx_pktptr_h << 16) +
-										  lp->rda[entry].rx_pktptr_l);
+    while (rd->in_use == 0) {
+	struct sk_buff *skb;
+	int pkt_len;
+	unsigned char *pkt_ptr;
+	
+	status = rd->rx_status;
+	if (sonic_debug > 3)
+	  printk ("status %x, cur_rx %d, cur_rra %x\n",status,lp->cur_rx,lp->cur_rra);
+	if (status & SONIC_RCR_PRX) {	    
+	    pkt_len = rd->rx_pktlen;
+	    pkt_ptr = (char *)sonic_chiptomem((rd->rx_pktptr_h << 16) +
+						      rd->rx_pktptr_l);
 	    
 	    if (sonic_debug > 3)
-	      printk ("pktptr %p (rba %p) h:%x l:%x, rra h:%x l:%x bsize h:%x l:%x\n", pkt_ptr,lp->rba,
-				  lp->rda[entry].rx_pktptr_h,lp->rda[entry].rx_pktptr_l,
-				  lp->rra[lp->cur_rra & 15].rx_bufadr_h,lp->rra[lp->cur_rra & 15].rx_bufadr_l,
-				  SONIC_READ(SONIC_RBWC1),SONIC_READ(SONIC_RBWC0));
-		
+	      printk ("pktptr %p (rba %p) h:%x l:%x, bsize h:%x l:%x\n", pkt_ptr,lp->rba,
+		      rd->rx_pktptr_h,rd->rx_pktptr_l,
+		      SONIC_READ(SONIC_RBWC1),SONIC_READ(SONIC_RBWC0));
+	
 	    /* Malloc up new buffer. */
 	    skb = dev_alloc_skb(pkt_len+2);
 	    if (skb == NULL) {
-		  printk("%s: Memory squeeze, dropping packet.\n", dev->name);
-		  lp->stats.rx_dropped++;
-		  break;
+		printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+		lp->stats.rx_dropped++;
+		break;
 	    }
 	    skb->dev = dev;
 	    skb_reserve(skb,2);	/* 16 byte align */
@@ -351,29 +340,35 @@
 	    skb->protocol=eth_type_trans(skb,dev);
 	    netif_rx(skb);			/* pass the packet to upper layers */
 	    lp->stats.rx_packets++;
+	    lp->stats.rx_bytes += pkt_len;
 	    
-	  } else {
-		/* This should only happen, if we enable accepting broken packets. */
-		lp->stats.rx_errors++;
-		if (status & SONIC_RCR_FAER) lp->stats.rx_frame_errors++;
-		if (status & SONIC_RCR_CRCR) lp->stats.rx_crc_errors++;
-	  }
-	  
-	  lp->rda[entry].in_use = 1;
-	  entry = (++lp->cur_rx) & SONIC_RDS_MASK;
-	  /* now give back the buffer to the receive buffer area */
-	  if (status & SONIC_RCR_LPKT) {
+	} else {
+	    /* This should only happen, if we enable accepting broken packets. */
+	    lp->stats.rx_errors++;
+	    if (status & SONIC_RCR_FAER) lp->stats.rx_frame_errors++;
+	    if (status & SONIC_RCR_CRCR) lp->stats.rx_crc_errors++;
+	}
+	
+	rd->in_use = 1;
+	rd = &lp->rda[(++lp->cur_rx) & SONIC_RDS_MASK];
+	/* now give back the buffer to the receive buffer area */
+	if (status & SONIC_RCR_LPKT) {
 	    /*
 	     * this was the last packet out of the current receice buffer
 	     * give the buffer back to the SONIC
 	     */
-	    SONIC_WRITE(SONIC_RWP,(lp->rra_laddr + (++lp->cur_rra & 15) * sizeof(sonic_rr_t)) & 0xffff);
-	  }
+	    lp->cur_rra += sizeof(sonic_rr_t);
+	    if (lp->cur_rra > (lp->rra_laddr + (SONIC_NUM_RRS-1) * sizeof(sonic_rr_t)))
+		lp->cur_rra = lp->rra_laddr;
+	    SONIC_WRITE(SONIC_RWP, lp->cur_rra & 0xffff);
+	} else
+	    printk ("%s: rx desc without RCR_LPKT. Shouldn't happen !?\n",dev->name);
     }
-	
-    /* If any worth-while packets have been received, netif_rx()
-	   has done a mark_bh(NET_BH) for us and will work on them
-	   when we get to the bottom-half routine. */
+    /*
+     * If any worth-while packets have been received, dev_rint()
+     * has done a mark_bh(NET_BH) for us and will work on them
+     * when we get to the bottom-half routine.
+     */
     return;
 }
 
@@ -417,41 +412,27 @@
     rcr |= SONIC_RCR_BRD; /* accept broadcast packets */
     
     if (dev->flags & IFF_PROMISC) {         /* set promiscuous mode */
-	  rcr |= SONIC_RCR_PRO;
+	rcr |= SONIC_RCR_PRO;
     } else {
-#ifdef DEBUG_CAM /* XXX */
-	if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 14)) {
-#else
 	if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) {
-#endif
 	    rcr |= SONIC_RCR_AMC;
 	} else {
-	  if (sonic_debug > 2)
-		printk ("sonic_multicast_list: mc_count %d\n",dev->mc_count);
-#ifdef DEBUG_CAM /* XXX skip CAM0+1 */
-	  lp->cda.cam_enable = 3; /* always enable our own address */
-	  for (i = 2; i <= dev->mc_count; i++) {
-#else
+	    if (sonic_debug > 2)
+	      printk ("sonic_multicast_list: mc_count %d\n",dev->mc_count);
 	    lp->cda.cam_enable = 1; /* always enable our own address */
 	    for (i = 1; i <= dev->mc_count; i++) {
-#endif
-		  addr = dmi->dmi_addr;
-		  dmi = dmi->next;
-		  lp->cda.cam_desc[i].cam_frag2 = addr[1] << 8 | addr[0];
-		  lp->cda.cam_desc[i].cam_frag1 = addr[3] << 8 | addr[2];
-		  lp->cda.cam_desc[i].cam_frag0 = addr[5] << 8 | addr[4];
-		  lp->cda.cam_enable |= (1 << i);
+		addr = dmi->dmi_addr;
+		dmi = dmi->next;
+		lp->cda.cam_desc[i].cam_cap0 = addr[1] << 8 | addr[0];
+		lp->cda.cam_desc[i].cam_cap1 = addr[3] << 8 | addr[2];
+		lp->cda.cam_desc[i].cam_cap2 = addr[5] << 8 | addr[4];
+		lp->cda.cam_enable |= (1 << i);
 	    }
-	    /* number of CAM entries to load */
-#ifdef DEBUG_CAM
-	    SONIC_WRITE(SONIC_CDC,dev->mc_count+2);
-#else
-	    SONIC_WRITE(SONIC_CDC,dev->mc_count+1);
-#endif
+	    SONIC_WRITE(SONIC_CDC,16);
 	    /* issue Load CAM command */
 	    SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);	    
-	    SONIC_WRITE(SONIC_CMD,SONIC_CR_LCAM);	    
-	  }
+	    SONIC_WRITE(SONIC_CMD,SONIC_CR_LCAM);
+	}
     }
     
     if (sonic_debug > 2)
@@ -488,7 +469,6 @@
     SONIC_WRITE(SONIC_CMD,0);
     SONIC_WRITE(SONIC_CMD,SONIC_CR_RXDIS);
 
-
     /*
      * initialize the receive resource area
      */
@@ -499,10 +479,10 @@
     rra_end   = (rra_start + (SONIC_NUM_RRS * sizeof(sonic_rr_t))) & 0xffff;
   
     for (i = 0; i < SONIC_NUM_RRS; i++) {
-	  lp->rra[i].rx_bufadr_l = (lp->rba_laddr + i * SONIC_RBSIZE) & 0xffff;
-	  lp->rra[i].rx_bufadr_h = (lp->rba_laddr + i * SONIC_RBSIZE) >> 16;
-	  lp->rra[i].rx_bufsize_l = SONIC_RBSIZE >> 1;
-	  lp->rra[i].rx_bufsize_h = 0;
+	lp->rra[i].rx_bufadr_l = (lp->rba_laddr + i * SONIC_RBSIZE) & 0xffff;
+	lp->rra[i].rx_bufadr_h = (lp->rba_laddr + i * SONIC_RBSIZE) >> 16;
+	lp->rra[i].rx_bufsize_l = SONIC_RBSIZE >> 1;
+	lp->rra[i].rx_bufsize_h = 0;
     }
 
     /* initialize all RRA registers */
@@ -513,7 +493,7 @@
     SONIC_WRITE(SONIC_URRA,lp->rra_laddr >> 16);
     SONIC_WRITE(SONIC_EOBC,(SONIC_RBSIZE-2) >> 1);
     
-    lp->cur_rra = SONIC_NUM_RRS - 2;
+    lp->cur_rra = lp->rra_laddr + (SONIC_NUM_RRS-1) * sizeof(sonic_rr_t);
 
     /* load the resource pointers */
     if (sonic_debug > 3)
@@ -522,8 +502,8 @@
     SONIC_WRITE(SONIC_CMD,SONIC_CR_RRRA);
     i = 0;
     while (i++ < 100) {
-	  if (SONIC_READ(SONIC_CMD) & SONIC_CR_RRRA)
-		break;
+	if (SONIC_READ(SONIC_CMD) & SONIC_CR_RRRA)
+	  break;
     }
     
     if (sonic_debug > 2)
@@ -537,18 +517,17 @@
     if (sonic_debug > 2)
       printk ("sonic_init: initialize receive descriptors\n");      
     for (i=0; i<SONIC_NUM_RDS; i++) {
-	  lp->rda[i].rx_status = 0;
-	  lp->rda[i].rx_pktlen = 0;
-	  lp->rda[i].rx_pktptr_l = 0;
-	  lp->rda[i].rx_pktptr_h = 0;
-	  lp->rda[i].rx_seqno = 0;
-	  lp->rda[i].in_use = 1;		       	
-	  lp->rda[i].link = lp->rda_laddr + (i+1) * sizeof (sonic_rd_t);
+	lp->rda[i].rx_status = 0;
+	lp->rda[i].rx_pktlen = 0;
+	lp->rda[i].rx_pktptr_l = 0;
+	lp->rda[i].rx_pktptr_h = 0;
+	lp->rda[i].rx_seqno = 0;
+	lp->rda[i].in_use = 1;		       	
+	lp->rda[i].link = lp->rda_laddr + (i+1) * sizeof (sonic_rd_t);
     }
     /* fix last descriptor */
     lp->rda[SONIC_NUM_RDS-1].link = lp->rda_laddr;
     lp->cur_rx = 0;
-    
     SONIC_WRITE(SONIC_URDA,lp->rda_laddr >> 16);
     SONIC_WRITE(SONIC_CRDA,lp->rda_laddr & 0xffff);
     
@@ -558,44 +537,26 @@
     if (sonic_debug > 2)
       printk ("sonic_init: initialize transmit descriptors\n");
     for (i = 0; i < SONIC_NUM_TDS; i++) {
-	  lp->tda[i].tx_status = 0;
-	  lp->tda[i].tx_config = 0;
-	  lp->tda[i].tx_pktsize = 0;
-	  lp->tda[i].tx_frag_count = 0;
-	  lp->tda[i].link = (lp->tda_laddr + (i+1) * sizeof (sonic_td_t)) | SONIC_END_OF_LINKS;
+	lp->tda[i].tx_status = 0;
+	lp->tda[i].tx_config = 0;
+	lp->tda[i].tx_pktsize = 0;
+	lp->tda[i].tx_frag_count = 0;
+	lp->tda[i].link = (lp->tda_laddr + (i+1) * sizeof (sonic_td_t)) | SONIC_END_OF_LINKS;
     }
     lp->tda[SONIC_NUM_TDS-1].link = (lp->tda_laddr & 0xffff) | SONIC_END_OF_LINKS;    
 
     SONIC_WRITE(SONIC_UTDA,lp->tda_laddr >> 16);
     SONIC_WRITE(SONIC_CTDA,lp->tda_laddr & 0xffff);
+    lp->cur_tx = lp->dirty_tx = 0;
     
     /*
      * put our own address to CAM desc[0]
      */
-    lp->cda.cam_desc[0].cam_frag2 = dev->dev_addr[1] << 8 | dev->dev_addr[0];
-    lp->cda.cam_desc[0].cam_frag1 = dev->dev_addr[3] << 8 | dev->dev_addr[2];
-    lp->cda.cam_desc[0].cam_frag0 = dev->dev_addr[5] << 8 | dev->dev_addr[4];
+    lp->cda.cam_desc[0].cam_cap0 = dev->dev_addr[1] << 8 | dev->dev_addr[0];
+    lp->cda.cam_desc[0].cam_cap1 = dev->dev_addr[3] << 8 | dev->dev_addr[2];
+    lp->cda.cam_desc[0].cam_cap2 = dev->dev_addr[5] << 8 | dev->dev_addr[4];
     lp->cda.cam_enable = 1;
-
-#ifdef DEBUG_CAM
-    /* byte reversed in CAM 1 */
-    lp->cda.cam_desc[1].cam_frag2 = dev->dev_addr[0] << 8 | dev->dev_addr[1];
-    lp->cda.cam_desc[1].cam_frag1 = dev->dev_addr[2] << 8 | dev->dev_addr[3];
-    lp->cda.cam_desc[1].cam_frag0 = dev->dev_addr[4] << 8 | dev->dev_addr[4];
-    lp->cda.cam_enable = 3;
-
-    if (sonic_debug > 2) {
-	  printk("This is what should be put into CAM desc[0]:\n");
-	  printk("cda.cam_desc[0].cam_frag2=%x\n",lp->cda.cam_desc[0].cam_frag2);
-	  printk("cda.cam_desc[0].cam_frag1=%x\n",lp->cda.cam_desc[0].cam_frag1);
-	  printk("cda.cam_desc[0].cam_frag0=%x\n",lp->cda.cam_desc[0].cam_frag0);
-	  printk("This is what should be put into CAM desc[1]:\n");
-	  printk("cda.cam_desc[1].cam_frag2=%x\n",lp->cda.cam_desc[1].cam_frag2);
-	  printk("cda.cam_desc[1].cam_frag1=%x\n",lp->cda.cam_desc[1].cam_frag1);
-	  printk("cda.cam_desc[1].cam_frag0=%x\n",lp->cda.cam_desc[1].cam_frag0);
-    }
-#endif
-
+    
     for (i=0; i < 16; i++)
       lp->cda.cam_desc[i].cam_entry_pointer = i;
 
@@ -603,12 +564,8 @@
      * initialize CAM registers
      */
     SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);
-#ifdef DEBUG_CAM
-    SONIC_WRITE(SONIC_CDC,2);
-#else
-    SONIC_WRITE(SONIC_CDC,1);
-#endif    
-
+    SONIC_WRITE(SONIC_CDC,16);
+    
     /*
      * load the CAM
      */
@@ -616,30 +573,13 @@
     
     i = 0;
     while (i++ < 100) {
-	  if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD)
-		break;
+	if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD)
+	  break;
     }
     if (sonic_debug > 2) {
-#ifdef DEBUG_CAM
-	  printk("This is what got put into CAM desc[0]\n");
-	  SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
-	  SONIC_WRITE(SONIC_CEP,0);
-	  printk("CAP0: %x - CAP1: %x - CAP2: %x\n",
-			 SONIC_READ(SONIC_CAP0),
-			 SONIC_READ(SONIC_CAP1),
-			 SONIC_READ(SONIC_CAP2));
-	  printk("This is what got put into CAM desc[1]\n");
-	  SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
-	  SONIC_WRITE(SONIC_CEP,1);
-	  printk("CAP0: %x - CAP1: %x - CAP2: %x\n",
-			 SONIC_READ(SONIC_CAP0),
-			 SONIC_READ(SONIC_CAP1),
-			 SONIC_READ(SONIC_CAP2));
-	  SONIC_WRITE(SONIC_CMD,0);
-#endif
-	  printk("sonic_init: CMD=%x, ISR=%x\n",
-			 SONIC_READ(SONIC_CMD),
-			 SONIC_READ(SONIC_ISR));
+	printk("sonic_init: CMD=%x, ISR=%x\n",
+	       SONIC_READ(SONIC_CMD),
+	       SONIC_READ(SONIC_ISR));
     }
 
     /*
@@ -654,12 +594,12 @@
 
     cmd = SONIC_READ(SONIC_CMD);
     if ((cmd & SONIC_CR_RXEN) == 0 ||
-		(cmd & SONIC_CR_STP) == 0)
+	(cmd & SONIC_CR_STP) == 0)
       printk("sonic_init: failed, status=%x\n",cmd);
-	
+
     if (sonic_debug > 2)
       printk("sonic_init: new status=%x\n",SONIC_READ(SONIC_CMD));
-	
+
     return(0);
 }
 
--- linux-2.1.131/drivers/net/sonic.h.mac1	Fri Jan  1 11:39:11 1999
+++ linux-2.1.131/drivers/net/sonic.h	Fri Jan  1 11:52:13 1999
@@ -17,7 +17,6 @@
 #ifndef SONIC_H
 #define SONIC_H
 
-
 /*
  * SONIC register offsets
  */
@@ -236,9 +235,9 @@
  */
 
 typedef struct {
-  u16 pad0;
+  SREGS_PAD(pad0);
   u16 rx_status;	/* status after reception of a packet */
-  u16 pad1;
+  SREGS_PAD(pad1);
   u16 rx_pktlen;	/* length of the packet incl. CRC */
   
   /*
@@ -246,22 +245,22 @@
    * where the packet resides. A packet is always received into
    * a contiguous piece of memory.
    */
-  u16 pad2;
+  SREGS_PAD(pad2);
   u16 rx_pktptr_l;
-  u16 pad3;
+  SREGS_PAD(pad3);
   u16 rx_pktptr_h;
 
-  u16 pad4;
+  SREGS_PAD(pad4);
   u16 rx_seqno;	/* sequence no. */
 
-  u16 pad5;
+  SREGS_PAD(pad5);
   u16 link;		/* link to next RDD (end if EOL bit set) */
 
   /*
    * Owner of this descriptor, 0= driver, 1=sonic
    */
   
-  u16 pad6;
+  SREGS_PAD(pad6);
   u16 in_use;	
 
   caddr_t rda_next;		/* pointer to next RD */
@@ -272,23 +271,23 @@
  * Describes a Transmit Descriptor
  */
 typedef struct {
-  u16 pad0;		
+  SREGS_PAD(pad0);		
   u16 tx_status;	/* status after transmission of a packet */
-  u16 pad1;		
+  SREGS_PAD(pad1);		
   u16 tx_config;	/* transmit configuration for this packet */
-  u16 pad2;		
+  SREGS_PAD(pad2);		
   u16 tx_pktsize;	/* size of the packet to be transmitted */
-  u16 pad3;		
+  SREGS_PAD(pad3);		
   u16 tx_frag_count;	/* no. of fragments */
 
-  u16 pad4;		
+  SREGS_PAD(pad4);		
   u16 tx_frag_ptr_l;
-  u16 pad5;		
+  SREGS_PAD(pad5);		
   u16 tx_frag_ptr_h;
-  u16 pad6;		
+  SREGS_PAD(pad6);		
   u16 tx_frag_size;
   
-  u16 pad7;		
+  SREGS_PAD(pad7);		
   u16 link;		/* ptr to next descriptor */
 } sonic_td_t;
 
@@ -298,14 +297,14 @@
  */
 
 typedef struct {
-  u16 pad;
+  SREGS_PAD(pad0);
   u16 cam_entry_pointer;
-  u16 pad2;
-  u16 cam_frag2;
-  u16 pad1;
-  u16 cam_frag1;
-  u16 pad0;
-  u16 cam_frag0;
+  SREGS_PAD(pad1);
+  u16 cam_cap0;
+  SREGS_PAD(pad2);
+  u16 cam_cap1;
+  SREGS_PAD(pad3);
+  u16 cam_cap2;
 } sonic_cd_t;
 
 #define CAM_DESCRIPTORS 16
@@ -313,7 +312,7 @@
 
 typedef struct {
   sonic_cd_t cam_desc[CAM_DESCRIPTORS];
-  u16 pad;
+  SREGS_PAD(pad);
   u16 cam_enable;
 } sonic_cda_t;
 
@@ -338,9 +337,9 @@
 
 typedef struct {
   u16 rx_status;	/* status after reception of a packet */
-  u16 pad0;
+  SREGS_PAD(pad0);
   u16 rx_pktlen;	/* length of the packet incl. CRC */
-  u16 pad1;
+  SREGS_PAD(pad1);
   
   /*
    * Pointers to the location in the receive buffer area (RBA)
@@ -348,22 +347,22 @@
    * a contiguous piece of memory.
    */
   u16 rx_pktptr_l;
-  u16 pad2;
+  SREGS_PAD(pad2);
   u16 rx_pktptr_h;
-  u16 pad3;
+  SREGS_PAD(pad3);
 
   u16 rx_seqno;	/* sequence no. */
-  u16 pad4;
+  SREGS_PAD(pad4);
 
   u16 link;		/* link to next RDD (end if EOL bit set) */
-  u16 pad5;
+  SREGS_PAD(pad5);
 
   /*
    * Owner of this descriptor, 0= driver, 1=sonic
    */
   
   u16 in_use;	
-  u16 pad6;
+  SREGS_PAD(pad6);
 
   caddr_t rda_next;		/* pointer to next RD */
 } sonic_rd_t;
@@ -374,23 +373,23 @@
  */
 typedef struct {
   u16 tx_status;	/* status after transmission of a packet */
-  u16 pad0;		
+  SREGS_PAD(pad0);
   u16 tx_config;	/* transmit configuration for this packet */
-  u16 pad1;		
+  SREGS_PAD(pad1);
   u16 tx_pktsize;	/* size of the packet to be transmitted */
-  u16 pad2;		
+  SREGS_PAD(pad2);
   u16 tx_frag_count;	/* no. of fragments */
-  u16 pad3;		
+  SREGS_PAD(pad3);
 
   u16 tx_frag_ptr_l;
-  u16 pad4;		
+  SREGS_PAD(pad4);
   u16 tx_frag_ptr_h;
-  u16 pad5;		
+  SREGS_PAD(pad5);
   u16 tx_frag_size;
-  u16 pad6;		
+  SREGS_PAD(pad6);
   
   u16 link;		/* ptr to next descriptor */
-  u16 pad7;		
+  SREGS_PAD(pad7);
 } sonic_td_t;
 
 
@@ -400,13 +399,13 @@
 
 typedef struct {
   u16 cam_entry_pointer;
-  u16 pad;
-  u16 cam_frag2;
-  u16 pad2;
-  u16 cam_frag1;
-  u16 pad1;
-  u16 cam_frag0;
-  u16 pad0;
+  SREGS_PAD(pad0);
+  u16 cam_cap0;
+  SREGS_PAD(pad1);
+  u16 cam_cap1;
+  SREGS_PAD(pad2);
+  u16 cam_cap2;
+  SREGS_PAD(pad3);
 } sonic_cd_t;
 
 #define CAM_DESCRIPTORS 16
@@ -415,7 +414,7 @@
 typedef struct {
   sonic_cd_t cam_desc[CAM_DESCRIPTORS];
   u16 cam_enable;
-  u16 pad;
+  SREGS_PAD(pad);
 } sonic_cda_t;
 #endif	/* endianness */ 
 
@@ -439,6 +438,7 @@
 #define SONIC_RDS_MASK   (SONIC_NUM_RDS-1)
 #define SONIC_TDS_MASK   (SONIC_NUM_TDS-1)
 
+
 /* Information that need to be kept for each board. */
 struct sonic_local {
     sonic_cda_t   cda;                     /* virtual CPU address of CDA */
@@ -453,8 +453,10 @@
     unsigned int  rra_laddr;               /* logical DMA address of RRA */    
     unsigned int  rda_laddr;               /* logical DMA address of RDA */
     unsigned int  rba_laddr;               /* logical DMA address of RBA */
-    unsigned int  cur_tx, cur_rx;          /* current indexes to resource areas */
-    unsigned int  dirty_tx,cur_rra;        /* last unacked transmit packet */
+    unsigned int  cur_rra;                 /* current indexes to resource areas */
+    unsigned int  cur_rx;
+    unsigned int  cur_tx;
+    unsigned int  dirty_tx;                /* last unacked transmit packet */
     char tx_full;
     struct enet_statistics stats;
 };
@@ -469,5 +471,8 @@
 static struct enet_statistics *sonic_get_stats(struct device *dev);
 static void sonic_multicast_list(struct device *dev);
 static int sonic_init(struct device *dev);
+
+static const char *version =
+	"sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n";
 
 #endif /* SONIC_H */

--------------9307E7248CB2AFEA2DF339E7--

