patch-2.4.11-dontuse linux/drivers/net/3c507.c
Next file: linux/drivers/net/3c509.c
Previous file: linux/drivers/net/3c505.c
Back to the patch index
Back to the overall index
- Lines: 89
- Date:
Sun Sep 30 12:26:08 2001
- Orig file:
v2.4.10/linux/drivers/net/3c507.c
- Orig date:
Wed Jul 25 17:10:21 2001
diff -u --recursive --new-file v2.4.10/linux/drivers/net/3c507.c linux/drivers/net/3c507.c
@@ -126,6 +126,7 @@
ushort tx_head;
ushort tx_cmd_link;
ushort tx_reap;
+ ushort tx_pkts_in_ring;
spinlock_t lock;
};
@@ -194,7 +195,7 @@
#define DUMP_DATA 0x56 /* A 170 byte buffer for dump and Set-MC into. */
#define TX_BUF_START 0x0100
-#define NUM_TX_BUFS 4
+#define NUM_TX_BUFS 5
#define TX_BUF_SIZE (1518+14+20+16) /* packet+header+TBD */
#define RX_BUF_START 0x2000
@@ -463,6 +464,7 @@
printk ("Resetting board.\n");
/* Completely reset the adaptor. */
init_82586_mem (dev);
+ lp->tx_pkts_in_ring = 0;
} else {
/* Issue the channel attention signal and hope it "gets better". */
if (net_debug > 1)
@@ -538,30 +540,34 @@
outb(0x80, ioaddr + MISC_CTRL);
/* Reap the Tx packet buffers. */
- while (lp->tx_reap != lp->tx_head) {
+ while (lp->tx_pkts_in_ring) {
unsigned short tx_status = isa_readw(shmem+lp->tx_reap);
-
- if (tx_status == 0) {
- if (net_debug > 5) printk("Couldn't reap %#x.\n", lp->tx_reap);
+ if (!(tx_status & 0x8000)) {
+ if (net_debug > 5)
+ printk("Tx command incomplete (%#x).\n", lp->tx_reap);
break;
}
- if (tx_status & 0x2000) {
- lp->stats.tx_packets++;
- lp->stats.collisions += tx_status & 0xf;
- netif_wake_queue(dev);
- } else {
+ /* Tx unsuccessful or some interesting status bit set. */
+ if (!(tx_status & 0x2000) || (tx_status & 0x0f3f)) {
lp->stats.tx_errors++;
if (tx_status & 0x0600) lp->stats.tx_carrier_errors++;
if (tx_status & 0x0100) lp->stats.tx_fifo_errors++;
if (!(tx_status & 0x0040)) lp->stats.tx_heartbeat_errors++;
if (tx_status & 0x0020) lp->stats.tx_aborted_errors++;
+ lp->stats.collisions += tx_status & 0xf;
}
+ lp->stats.tx_packets++;
if (net_debug > 5)
printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
lp->tx_reap += TX_BUF_SIZE;
if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
lp->tx_reap = TX_BUF_START;
- if (++boguscount > 4)
+
+ lp->tx_pkts_in_ring--;
+ /* There is always more space in the Tx ring buffer now. */
+ netif_wake_queue(dev);
+
+ if (++boguscount > 10)
break;
}
@@ -782,7 +788,8 @@
dev->name, ioaddr, length, tx_block, lp->tx_head);
}
- if (lp->tx_head != lp->tx_reap)
+ /* Grimly block further packets if there has been insufficient reaping. */
+ if (++lp->tx_pkts_in_ring < NUM_TX_BUFS)
netif_wake_queue(dev);
}
@@ -892,6 +899,8 @@
release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
}
#endif /* MODULE */
+MODULE_LICENSE("GPL");
+
/*
* Local variables:
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)