|
From: ? <uns...@us...> - 2002-05-26 07:58:40
|
Update of /cvsroot/linux-vax/kernel-2.4/drivers/net
In directory usw-pr-cvs1:/tmp/cvs-serv12992
Modified Files:
vaxsgec.c vaxsgec.h
Log Message:
Fixes to sgec_init_ring, sgec_rx, sgec_start_xmit, vax_sgec_init
Based on Christoph's patch
Index: vaxsgec.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/net/vaxsgec.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- vaxsgec.c 26 May 2002 02:02:20 -0000 1.6
+++ vaxsgec.c 26 May 2002 07:58:36 -0000 1.7
@@ -79,9 +79,6 @@
static void sgec_init_ring(struct net_device *dev)
{
struct sgec_private *lp = (struct sgec_private *) dev->priv;
-#if 0
- volatile char *ib = lp->init_block;
-#endif
unsigned long leptr;
int i;
@@ -91,24 +88,28 @@
lp->rx_new = lp->tx_new = 0;
lp->rx_old = lp->tx_old = 0;
- /* Copy the ethernet address to the sgec init block.
- * XXX bit 0 of the physical address registers has to be zero
- */
-#if 0
- memset(ib, 0xff, 128);
- memcpy(ib, dev->dev_addr, 6);
-#endif
+ /* clear all descriptors */
+ memset((void *)lp->rx_ring, 0, sizeof(lp->rx_ring));
+ memset((void *)lp->tx_ring, 0, sizeof(lp->tx_ring));
/* Setup the Tx ring entries */
for (i = 0; i < TX_RING_SIZE; i++) {
leptr = virt_to_phys(lp->card_mem->tx_buf[i]) & 0xffffff;
- lp->tx_ring[i].tx_err = SG_TDR_OWN;
- lp->tx_ring[i].flags1 = SG_TD1_CA;
+ lp->tx_ring[i].tx_err = 0; /* was SG_TDR_OWN */
+ lp->tx_ring[i].flags1 = 0; /* was SG_TD1_CA */
+ lp->tx_ring[i].bufsize = 0; /* filled by sender */
+ lp->tx_ring[i].bufaddr = leptr;
#ifdef VAX_SGEC_DEBUG
if (i < 3)
printk("%d: 0x%8.8lx(0x%8.8x)\n", i, leptr, (int) lp->card_mem->tx_buf[i]);
#endif
}
+ i = TX_RING_SIZE; /* one after last for chaining ! */
+ /* normal fill already done, now we define the ring */
+ lp->tx_ring[i].tx_err = SG_TDR_OWN;
+ lp->tx_ring[i].flags1 = SG_TD1_CA; /* chain to ring */
+ lp->tx_ring[i].bufsize = 0;
+ lp->tx_ring[i].bufaddr = virt_to_phys (lp->tx_ring);
/* Setup the Rx ring entries */
#ifdef VAX_SGEC_DEBUG
@@ -116,11 +117,20 @@
#endif
for (i = 0; i < RX_RING_SIZE; i++) {
leptr = virt_to_phys(lp->card_mem->rx_buf[i]) & 0xffffff;
+ lp->rx_ring[i].framelen = SG_FR_OWN;
+ lp->rx_ring[i].bufsize = RX_BUFF_SIZE;
+ lp->rx_ring[i].bufaddr = leptr;
#ifdef VAX_SGEC_DEBUG
if (i < 3)
printk("%d: 0x%8.8lx(0x%8.8x)\n", i, leptr, (int) lp->card_mem->rx_buf[i]);
#endif
}
+ /* take one after last element for ring chaining */
+ i = RX_RING_SIZE;
+ lp->rx_ring[i].framelen = SG_FR_OWN;
+ lp->rx_ring[i].flags1 = SG_R1_CAD;
+ lp->rx_ring[i].bufsize = RX_BUFF_SIZE;
+ lp->rx_ring[i].bufaddr = virt_to_phys (lp->rx_ring);
}
static void kick_sgec(volatile struct sgec_regs *regs)
@@ -181,10 +191,13 @@
unsigned char bits;
int len = 0;
struct sk_buff *skb = 0;
-
-#ifdef VAX_SGEC_DEBUG_BUFFERS
int i;
+#ifdef VAX_SGEC_DEBUG
+ printk("sgec_rx\n");
+#endif
+
+#ifdef VAX_SGEC_DEBUG_BUFFERS
printk("[");
for (i=0; i < RX_RING_SIZE; i++){
if (i == lp->rx_new)
@@ -195,28 +208,23 @@
printk("]");
#endif
-#ifdef VAX_SGEC_DEBUG
- printk("sgec_rx\n");
-#endif
-
for (rd=&lp->rx_ring[lp->rx_new];
!((bits = rd->framelen) & SG_FR_OWN);
rd=&lp->rx_ring[lp->rx_new]){
- /*
- * check for incomplete frame
- if ((bits & SG_R0_POK) != SG_R0_POK) {
- lp->stats.rx_over_errors ++;
- lp->stats_rx_errors++;
+ /* check for incomplete frame */
+ if ((bits & SG_R0_POK) == 0) {
+ lp->stats.rx_over_errors++;
+ lp->stats.rx_errors++;
}
else if (bits & SG_R0_ERR) {
- * only count last frame as the error
- if (bits & SG_R0_BUF) lp->stats.rx_fifo_errors++;
+ /* only count last frame as the error */
+ if (bits & SG_R0_FFO) lp->stats.rx_fifo_errors++; /* was _BUF */
if (bits & SG_R0_CRC) lp->stats.rx_crc_errors++;
if (bits & SG_R0_OFL) lp->stats.rx_over_errors++;
if (bits & SG_R0_FRA) lp->stats.rx_frame_errors++;
- if (bits & SG_R0_EOP) lp->stats.rx_errors++;
- } else { */
+ if (bits & SG_R0_LNG) lp->stats.rx_errors++; /* was _EOP */
+ } else {
len = rd->framelen;
skb = dev_alloc_skb((unsigned int)len + 2);
if (skb == 0) {
@@ -226,7 +234,7 @@
rd->framelen = SG_FR_OWN;
lp->rx_new =(lp->rx_new+1) & RX_RING_MASK;
return 0;
- /* } */
+ }
lp->stats.rx_bytes += len;
skb->dev = dev;
skb_reserve(skb,2); /*16 byte align */
@@ -240,9 +248,7 @@
dev->last_rx=jiffies;
lp->stats.rx_packets++;
}
- // rd->mblength=0;
- rd->framelen = len;
- rd->framelen &= SG_FR_OWN;
+ rd->framelen = SG_FR_OWN;
lp->rx_new = (lp->rx_new + 1) & RX_RING_MASK;
}
return 0;
@@ -519,9 +525,9 @@
lp->stats.tx_bytes += len;
entry = lp->tx_new & TX_RING_MASK;
- lp->tx_ring[entry].flags1 = len;
-
cp_to_buf((char *) lp->card_mem->tx_buf[entry], skb->data, skblen);
+ lp->tx_ring[entry].bufsize = len;
+ lp->tx_ring[entry].flags1 = SG_TD1_POK | SG_TD1_IC;
/* Clear the slack of the packet, do I need this? */
/* For a firewall its a good idea - AC */
@@ -530,7 +536,7 @@
memset ((char *) &ib->tx_buf [entry][skblen], 0, (len - skblen) << 1);
*/
/* Now, give the packet to the card */
- lp->tx_ring[entry].flags1 = SG_TDR_OWN | SG_TD1_POK; /* (LE_T1_POK | LE_T1_OWN);*/
+ lp->tx_ring[entry].tx_err = SG_TDR_OWN;
lp->tx_new = (lp->tx_new + 1) & TX_RING_MASK;
if (TX_BUFFS_AVAIL <= 0)
@@ -736,15 +742,16 @@
each (plus 128 bytes).. over 128KB */
/* At present, until we figure out the address extension
* parity control bit, ask for memory in the DMA zone */
+ /* 2^6 = 64x4KB = 256KB */
dev->mem_start = __get_free_pages(GFP_DMA, /*4*/ 6);
if (!dev->mem_start) {
/* Shouldn't we free dev->priv here if dev was non-NULL on entry? */
return -ENOMEM;
}
- dev->mem_end = dev->mem_start + 65536;
+ dev->mem_end = dev->mem_start + sizeof (struct sgec_shared_mem);
lp->card_mem = (volatile struct sgec_shared_mem *)(dev->mem_start);
- regs = (struct sgec_regs *) ioremap(sgec_phys_addr, 0x8);
+ regs = (struct sgec_regs *) ioremap(sgec_phys_addr, 0x20 /* 0x8 */);
dev->base_addr = (unsigned long) regs;
if(dev->base_addr == 0)
printk("vaxsgec.c: memory remap failed\n");
@@ -814,6 +821,7 @@
ether_setup(dev);
+ /* does anyone know what this really is supposed to do? */
/* We cannot sleep if the chip is busy during a
* multicast list update event, because such events
* can occur from interrupts (ex. IPv6). So we
Index: vaxsgec.h
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/net/vaxsgec.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- vaxsgec.h 26 May 2002 02:02:20 -0000 1.2
+++ vaxsgec.h 26 May 2002 07:58:37 -0000 1.3
@@ -118,6 +118,7 @@
#define SG_R0_OFL 0x0400 /* buffer overflow */
#define SG_R0_FSG 0x0200 /* first segment */
#define SG_R0_LSG 0x0100 /* last segment */
+#define SG_R0_POK 0x0300 /* first and last segments set */
#define SG_R0_LNG 0x0080 /* frame too long */
#define SG_R0_COL 0x0040 /* collision seen */
#define SG_R0_EFT 0x0020 /* etherenet frame type */
|