tulip needs a small delay during rxtx restart. different optimization
patterns in newer gccs served to expose this bug which was previously
hidden, so random users might hit a lack-of-networking depending on the
speed of their machine, their compiler, etc.
--
Jeff Garzik | Disbelief, that's why you fail.
Building 1024 |
MandrakeSoft |
Index: linux_2_4/drivers/net/tulip/21142.c
diff -u linux_2_4/drivers/net/tulip/21142.c:1.1.1.28
linux_2_4/drivers/net/tulip/21142.c:1.1.1.28.26.1
--- linux_2_4/drivers/net/tulip/21142.c:1.1.1.28 Wed May 16 14:46:45 2001
+++ linux_2_4/drivers/net/tulip/21142.c Fri Jun 1 02:19:08 2001
@@ -84,7 +84,7 @@
tp->csr6 &= 0x00D5;
tp->csr6 |= new_csr6;
outl(0x0301, ioaddr + CSR12);
- tulip_restart_rxtx(tp, tp->csr6);
+ tulip_restart_rxtx(tp);
}
next_tick = 3*HZ;
}
@@ -117,7 +117,7 @@
udelay(100);
outl(csr14, ioaddr + CSR14);
tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? FullDuplex : 0);
- tulip_outl_csr(tp, tp->csr6, CSR6);
+ outl(tp->csr6, ioaddr + CSR6);
if (tp->mtable && tp->mtable->csr15dir) {
outl(tp->mtable->csr15dir, ioaddr + CSR15);
outl(tp->mtable->csr15val, ioaddr + CSR15);
@@ -201,12 +201,12 @@
outl(1, ioaddr + CSR13);
}
#if 0 /* Restart shouldn't be
needed. */
- tulip_outl_csr(tp, tp->csr6 | csr6_sr, CSR6);
+ outl(tp->csr6 | RxOn, ioaddr + CSR6);
if (tulip_debug > 2)
printk(KERN_DEBUG "%s: Restarting Tx and Rx, CSR5 is
%8.8x.\n",
dev->name, inl(ioaddr + CSR5));
#endif
- tulip_outl_csr(tp, tp->csr6 | csr6_st | csr6_sr, CSR6);
+ tulip_start_rxtx(tp);
if (tulip_debug > 2)
printk(KERN_DEBUG "%s: Setting CSR6 %8.8x/%x CSR12 %8.8x.\n",
dev->name, tp->csr6, inl(ioaddr + CSR6),
@@ -252,7 +252,7 @@
tp->csr6 = 0x83860000;
outl(0x0003FF7F, ioaddr + CSR14);
outl(0x0301, ioaddr + CSR12);
- tulip_restart_rxtx(tp, tp->csr6);
+ tulip_restart_rxtx(tp);
}
}
Index: linux_2_4/drivers/net/tulip/ChangeLog
diff -u linux_2_4/drivers/net/tulip/ChangeLog:1.1.1.11
linux_2_4/drivers/net/tulip/ChangeLog:1.1.1.11.20.1
--- linux_2_4/drivers/net/tulip/ChangeLog:1.1.1.11 Sat May 19 18:57:05 2001
+++ linux_2_4/drivers/net/tulip/ChangeLog Fri Jun 1 02:19:08 2001
@@ -1,3 +1,23 @@
+2001-06-01 Jeff Garzik <[EMAIL PROTECTED]>
+
+ * tulip.h:
+ - Remove tulip_outl_csr helper, redundant.
+ - Add tulip_start_rxtx inline helper.
+ - tulip_stop_rxtx helper: Add synchronization. Always use current
+ csr6 value, instead of tp->csr6 value or value passed as arg.
+ - tulip_restart_rxtx helper: Add synchronization. Always
+ use tp->csr6 for desired mode, not value passed as arg.
+ - New RxOn, TxOn, RxTx constants for csr6 modes.
+ - Remove now-redundant constants csr6_st, csr6_sr.
+
+ * 21142.c, interrupt.c, media.c, pnic.c, tulip_core.c:
+ Update for above rxtx helper changes.
+
+ * interrupt.c:
+ - whitespace cleanup around #ifdef CONFIG_NET_HW_FLOWCONTROL,
+ convert tabs to spaces.
+ - Move tp->stats.rx_missed_errors update outside the ifdef.
+
2001-05-18 Jeff Garzik <[EMAIL PROTECTED]>
* tulip_core.c: Added ethtool support.
Index: linux_2_4/drivers/net/tulip/interrupt.c
diff -u linux_2_4/drivers/net/tulip/interrupt.c:1.1.1.40
linux_2_4/drivers/net/tulip/interrupt.c:1.1.1.40.10.1
--- linux_2_4/drivers/net/tulip/interrupt.c:1.1.1.40 Thu May 24 01:49:55 2001
+++ linux_2_4/drivers/net/tulip/interrupt.c Fri Jun 1 02:19:08 2001
@@ -418,7 +418,7 @@
printk(KERN_WARNING "%s: The transmitter
stopped."
" CSR5 is %x, CSR6 %x, new CSR6
%x.\n",
dev->name, csr5, inl(ioaddr +
CSR6), tp->csr6);
- tulip_restart_rxtx(tp, tp->csr6);
+ tulip_restart_rxtx(tp);
}
spin_unlock(&tp->lock);
}
@@ -434,7 +434,7 @@
else
tp->csr6 |= 0x00200000; /* Store-n-forward. */
/* Restart the transmit process. */
- tulip_restart_rxtx(tp, tp->csr6);
+ tulip_restart_rxtx(tp);
outl(0, ioaddr + CSR1);
}
if (csr5 & (RxDied | RxNoBuf)) {
@@ -444,16 +444,15 @@
}
}
if (csr5 & RxDied) { /* Missed a Rx frame. */
-#ifdef CONFIG_NET_HW_FLOWCONTROL
- if (tp->fc_bit && !test_bit(tp->fc_bit,
&netdev_fc_xoff)) {
- tp->stats.rx_errors++;
- tulip_outl_csr(tp, tp->csr6 | csr6_st |
csr6_sr, CSR6);
- }
tp->stats.rx_missed_errors += inl(ioaddr + CSR8) &
0xffff;
+#ifdef CONFIG_NET_HW_FLOWCONTROL
+ if (tp->fc_bit && !test_bit(tp->fc_bit,
+&netdev_fc_xoff)) {
+ tp->stats.rx_errors++;
+ tulip_start_rxtx(tp);
+ }
#else
tp->stats.rx_errors++;
- tp->stats.rx_missed_errors += inl(ioaddr + CSR8) &
0xffff;
- tulip_outl_csr(tp, tp->csr6 | csr6_st | csr6_sr, CSR6);
+ tulip_start_rxtx(tp);
#endif
}
/*
Index: linux_2_4/drivers/net/tulip/media.c
diff -u linux_2_4/drivers/net/tulip/media.c:1.1.1.33
linux_2_4/drivers/net/tulip/media.c:1.1.1.33.26.1
--- linux_2_4/drivers/net/tulip/media.c:1.1.1.33 Wed May 16 14:46:45 2001
+++ linux_2_4/drivers/net/tulip/media.c Fri Jun 1 02:19:08 2001
@@ -411,7 +411,6 @@
*/
int tulip_check_duplex(struct net_device *dev)
{
- long ioaddr = dev->base_addr;
struct tulip_private *tp = dev->priv;
unsigned int bmsr, lpa, negotiated, new_csr6;
@@ -442,11 +441,8 @@
else new_csr6 &= ~FullDuplex;
if (new_csr6 != tp->csr6) {
- if (inl(ioaddr + CSR6) & (csr6_st | csr6_sr))
- tulip_restart_rxtx(tp, new_csr6);
- else
- outl(new_csr6, ioaddr + CSR6);
tp->csr6 = new_csr6;
+ tulip_restart_rxtx(tp);
if (tulip_debug > 0)
printk(KERN_INFO "%s: Setting %s-duplex based on MII"
Index: linux_2_4/drivers/net/tulip/pnic.c
diff -u linux_2_4/drivers/net/tulip/pnic.c:1.1.1.34
linux_2_4/drivers/net/tulip/pnic.c:1.1.1.34.20.1
--- linux_2_4/drivers/net/tulip/pnic.c:1.1.1.34 Sat May 19 18:57:04 2001
+++ linux_2_4/drivers/net/tulip/pnic.c Fri Jun 1 02:19:08 2001
@@ -45,7 +45,7 @@
if (tp->csr6 != new_csr6) {
tp->csr6 = new_csr6;
/* Restart Tx */
- tulip_restart_rxtx(tp, tp->csr6);
+ tulip_restart_rxtx(tp);
dev->trans_start = jiffies;
}
}
@@ -69,7 +69,7 @@
return;
if (! tp->nwayset || jiffies - dev->trans_start > 1*HZ) {
tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff);
- tulip_outl_csr(tp, tp->csr6, CSR6);
+ outl(tp->csr6, ioaddr + CSR6);
outl(0x30, ioaddr + CSR12);
outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
dev->trans_start = jiffies;
@@ -148,7 +148,7 @@
if (tp->csr6 != new_csr6) {
tp->csr6 = new_csr6;
/* Restart Tx */
- tulip_restart_rxtx(tp, tp->csr6);
+ tulip_restart_rxtx(tp);
dev->trans_start = jiffies;
if (tulip_debug > 1)
printk(KERN_INFO "%s: Changing PNIC
configuration to %s "
Index: linux_2_4/drivers/net/tulip/timer.c
diff -u linux_2_4/drivers/net/tulip/timer.c:1.1.1.22
linux_2_4/drivers/net/tulip/timer.c:1.1.1.22.86.1
--- linux_2_4/drivers/net/tulip/timer.c:1.1.1.22 Tue Apr 3 18:32:43 2001
+++ linux_2_4/drivers/net/tulip/timer.c Fri Jun 1 02:19:08 2001
@@ -158,7 +158,7 @@
medianame[tp->mtable->mleaf[tp->cur_index].media]);
tulip_select_media(dev, 0);
/* Restart the transmit process. */
- tulip_restart_rxtx(tp, tp->csr6);
+ tulip_restart_rxtx(tp);
next_tick = (24*HZ)/10;
break;
}
Index: linux_2_4/drivers/net/tulip/tulip.h
diff -u linux_2_4/drivers/net/tulip/tulip.h:1.1.1.34
linux_2_4/drivers/net/tulip/tulip.h:1.1.1.34.10.1
--- linux_2_4/drivers/net/tulip/tulip.h:1.1.1.34 Thu May 24 01:49:56 2001
+++ linux_2_4/drivers/net/tulip/tulip.h Fri Jun 1 02:19:08 2001
@@ -22,6 +22,7 @@
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/timer.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -139,10 +140,13 @@
enum tulip_mode_bits {
TxThreshold = (1 << 22),
FullDuplex = (1 << 9),
+ TxOn = 0x2000,
AcceptBroadcast = 0x0100,
AcceptAllMulticast = 0x0080,
AcceptAllPhys = 0x0040,
AcceptRunt = 0x0008,
+ RxOn = 0x0002,
+ RxTx = (TxOn | RxOn),
};
@@ -219,7 +223,6 @@
* (1,1) * 1024 * 160 *
***********************************/
- csr6_st = (1<<13), /* Transmit conrol: 1 = transmit, 0 = stop */
csr6_fc = (1<<12), /* Forces a collision in next transmission (for testing
in loopback mode) */
csr6_om_int_loop = (1<<10), /* internal (FIFO) loopback flag */
csr6_om_ext_loop = (1<<11), /* external (PMD) loopback flag */
@@ -231,7 +234,6 @@
csr6_if = (1<<4), /* Inverse Filtering, rejects only addresses in address
table: can't be set */
csr6_pb = (1<<3), /* Pass Bad Frames, (1) causes even bad frames to be
passed on */
csr6_ho = (1<<2), /* Hash-only filtering mode: can't be set */
- csr6_sr = (1<<1), /* Start(1)/Stop(0) Receive */
csr6_hp = (1<<0), /* Hash/Perfect Receive Filtering Mode: can't be set */
csr6_mask_capture = (csr6_sc | csr6_ca),
@@ -435,20 +437,31 @@
extern u16 t21041_csr15[];
-static inline void tulip_outl_csr (struct tulip_private *tp, u32 newValue, enum
tulip_offsets offset)
+static inline void tulip_start_rxtx(struct tulip_private *tp)
{
- outl (newValue, tp->base_addr + offset);
+ long ioaddr = tp->base_addr;
+ outl(tp->csr6 | RxTx, ioaddr + CSR6);
+ barrier();
+ (void) inl(ioaddr + CSR6); /* mmio sync */
}
-static inline void tulip_stop_rxtx(struct tulip_private *tp, u32 csr6mask)
+static inline void tulip_stop_rxtx(struct tulip_private *tp)
{
- tulip_outl_csr(tp, csr6mask & ~(csr6_st | csr6_sr), CSR6);
+ long ioaddr = tp->base_addr;
+ u32 csr6 = inl(ioaddr + CSR6);
+
+ if (csr6 & RxTx) {
+ outl(csr6 & ~RxTx, ioaddr + CSR6);
+ barrier();
+ (void) inl(ioaddr + CSR6); /* mmio sync */
+ }
}
-static inline void tulip_restart_rxtx(struct tulip_private *tp, u32 csr6mask)
+static inline void tulip_restart_rxtx(struct tulip_private *tp)
{
- tulip_outl_csr(tp, csr6mask | csr6_sr, CSR6);
- tulip_outl_csr(tp, csr6mask | csr6_st | csr6_sr, CSR6);
+ tulip_stop_rxtx(tp);
+ udelay(5);
+ tulip_start_rxtx(tp);
}
#endif /* __NET_TULIP_H__ */
Index: linux_2_4/drivers/net/tulip/tulip_core.c
diff -u linux_2_4/drivers/net/tulip/tulip_core.c:1.1.1.50
linux_2_4/drivers/net/tulip/tulip_core.c:1.1.1.50.10.1
--- linux_2_4/drivers/net/tulip/tulip_core.c:1.1.1.50 Thu May 24 01:49:56 2001
+++ linux_2_4/drivers/net/tulip/tulip_core.c Fri Jun 1 02:19:08 2001
@@ -15,8 +15,8 @@
*/
#define DRV_NAME "tulip"
-#define DRV_VERSION "0.9.15-pre2"
-#define DRV_RELDATE "May 16, 2001"
+#define DRV_VERSION "0.9.15-pre3"
+#define DRV_RELDATE "June 1, 2001"
#include <linux/config.h>
#include <linux/module.h>
@@ -276,7 +276,7 @@
/* On some chip revs we must set the MII/SYM port before the reset!? */
if (tp->mii_cnt || (tp->mtable && tp->mtable->has_mii))
- tulip_outl_csr (tp, 0x00040000, CSR6);
+ outl(0x00040000, ioaddr + CSR6);
/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
outl(0x00000001, ioaddr + CSR0);
@@ -409,7 +409,7 @@
printk(KERN_INFO "%s: Using MII transceiver %d, status
"
"%4.4x.\n",
dev->name, tp->phys[0],
tulip_mdio_read(dev, tp->phys[0], 1));
- tulip_outl_csr(tp, csr6_mask_defstate, CSR6);
+ outl(csr6_mask_defstate, ioaddr + CSR6);
tp->csr6 = csr6_mask_hdcap;
dev->if_port = 11;
outl(0x0000, ioaddr + CSR13);
@@ -455,13 +455,15 @@
tulip_select_media(dev, 1);
/* Start the chip's Tx to process setup frame. */
- tulip_outl_csr(tp, tp->csr6, CSR6);
- tulip_outl_csr(tp, tp->csr6 | csr6_st, CSR6);
+ tulip_stop_rxtx(tp);
+ barrier();
+ udelay(5);
+ outl(tp->csr6 | TxOn, ioaddr + CSR6);
/* Enable interrupts by setting the interrupt mask. */
outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5);
outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
- tulip_outl_csr(tp, tp->csr6 | csr6_st | csr6_sr, CSR6);
+ tulip_start_rxtx(tp);
outl(0, ioaddr + CSR2); /* Rx poll demand */
if (tulip_debug > 2) {
@@ -626,7 +628,7 @@
if (tp->fc_bit && test_bit(tp->fc_bit,&netdev_fc_xoff))
printk("BUG tx_timeout restarting rx when fc on\n");
#endif
- tulip_restart_rxtx(tp, tp->csr6);
+ tulip_restart_rxtx(tp);
/* Trigger an immediate transmit demand. */
outl(0, ioaddr + CSR1);
@@ -756,7 +758,7 @@
outl (0x00000000, ioaddr + CSR7);
/* Stop the Tx and Rx processes. */
- tulip_stop_rxtx(tp, inl(ioaddr + CSR6));
+ tulip_stop_rxtx(tp);
/* 21040 -- Leave the card in 10baseT state. */
if (tp->chip_id == DC21040)
@@ -1193,8 +1195,7 @@
spin_unlock_irqrestore(&tp->lock, flags);
}
- /* Can someone explain to me what the OR here is supposed to accomplish???? */
- tulip_outl_csr(tp, csr6 | 0x0000, CSR6);
+ outl(csr6, ioaddr + CSR6);
}
static void __devinit tulip_mwi_config (struct pci_dev *pdev,
@@ -1437,7 +1438,7 @@
tulip_mwi_config (pdev, dev);
/* Stop the chip's Tx and Rx processes. */
- tulip_stop_rxtx(tp, inl(ioaddr + CSR6));
+ tulip_stop_rxtx(tp);
/* Clear the missed-packet counter. */
inl(ioaddr + CSR8);
@@ -1631,7 +1632,7 @@
outl(0x00000000, ioaddr + CSR13);
outl(0xFFFFFFFF, ioaddr + CSR14);
outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */
- tulip_outl_csr(tp, inl(ioaddr + CSR6) | csr6_fd, CSR6);
+ outl(inl(ioaddr + CSR6) | csr6_fd, ioaddr + CSR6);
outl(0x0000EF01, ioaddr + CSR13);
break;
case DC21040:
@@ -1647,10 +1648,10 @@
case DC21142:
case PNIC2:
if (tp->mii_cnt || tulip_media_cap[dev->if_port] & MediaIsMII) {
- tulip_outl_csr(tp, csr6_mask_defstate, CSR6);
+ outl(csr6_mask_defstate, ioaddr + CSR6);
outl(0x0000, ioaddr + CSR13);
outl(0x0000, ioaddr + CSR14);
- tulip_outl_csr(tp, csr6_mask_hdcap, CSR6);
+ outl(csr6_mask_hdcap, ioaddr + CSR6);
} else
t21142_start_nway(dev);
break;
@@ -1658,21 +1659,21 @@
if ( ! tp->mii_cnt) {
tp->nway = 1;
tp->nwayset = 0;
- tulip_outl_csr(tp, csr6_ttm | csr6_ca, CSR6);
+ outl(csr6_ttm | csr6_ca, ioaddr + CSR6);
outl(0x30, ioaddr + CSR12);
- tulip_outl_csr(tp, 0x0001F078, CSR6);
- tulip_outl_csr(tp, 0x0201F078, CSR6); /* Turn on
autonegotiation. */
+ outl(0x0001F078, ioaddr + CSR6);
+ outl(0x0201F078, ioaddr + CSR6); /* Turn on autonegotiation. */
}
break;
case MX98713:
case COMPEX9881:
- tulip_outl_csr(tp, 0x00000000, CSR6);
+ outl(0x00000000, ioaddr + CSR6);
outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
outl(0x00000001, ioaddr + CSR13);
break;
case MX98715:
case MX98725:
- tulip_outl_csr(tp, 0x01a80000, CSR6);
+ outl(0x01a80000, ioaddr + CSR6);
outl(0xFFFFFFFF, ioaddr + CSR14);
outl(0x00001000, ioaddr + CSR12);
break;