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 */ |