Merged version (Re: tulip driver: fixed for Tx hung error)
Stephen R. van den Berg
srb@cuci.nl
Tue Dec 21 19:52:26 1999
>So you may mail to Stephen R. van den Berg <srb@cuci.nl> and ask him if
>he already has a merge.
I had. But I see that in 14pre16, other changes have been merged in
as well. If people think they are a move forward, then the following
merged version (between 14pre16 and Donald's Tulip 0.91u) might be of
interest:
Patch relative to 2.2.14pre16 tulip:
--- tulip.c Wed Dec 22 00:08:37 1999
+++ ../tulip.c Wed Dec 22 01:42:47 1999
@@ -18,7 +18,7 @@
*/
#define SMP_CHECK
-static const char version[] = "tulip.c:v0.91g-ppc 7/16/99 becker@cesdis.gsfc.nasa.gov\n";
+static const char version[] = "tulip.c:v0.91gB 7/16/99 becker@cesdis.gsfc.nasa.gov\n";
/* A few user-configurable values. */
@@ -51,6 +51,7 @@
bonding and packet priority.
There are no ill effects from too-large receive rings. */
#define TX_RING_SIZE 16
+#define TX_QUEUE_LEN 10
#define RX_RING_SIZE 32
/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
@@ -361,7 +362,7 @@
HAS_MII=1, HAS_MEDIA_TABLE=2, CSR12_IN_SROM=4, ALWAYS_CHECK_MII=8,
HAS_PWRDWN=0x10, MC_HASH_ONLY=0x20, /* Hash-only multicast filter. */
HAS_PNICNWAY=0x80, HAS_NWAY143=0x40, /* Uses internal NWay xcvr. */
- HAS_8023X=0x100,
+ HAS_INTR_MITIGATION=0x100, HAS_8023X=0x400,
};
static struct tulip_chip_table {
char *chip_name;
@@ -375,7 +376,8 @@
{ "Digital DS21140 Tulip", 128, 0x0001ebef,
HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, tulip_timer },
{ "Digital DS21143 Tulip", 128, 0x0801fbff,
- HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_PWRDWN | HAS_NWAY143,
+ HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_PWRDWN | HAS_NWAY143
+ | HAS_INTR_MITIGATION,
t21142_timer },
{ "Lite-On 82c168 PNIC", 256, 0x0001ebef,
HAS_MII | HAS_PNICNWAY, pnic_timer },
@@ -2530,7 +2532,7 @@
tulip_start_xmit(struct sk_buff *skb, struct device *dev)
{
struct tulip_private *tp = (struct tulip_private *)dev->priv;
- int entry;
+ int entry, q_used_cnt;
u32 flag;
/* Block a timer-based transmit from overlapping. This could better be
@@ -2547,15 +2549,16 @@
/* Calculate the next Tx descriptor entry. */
entry = tp->cur_tx % TX_RING_SIZE;
+ q_used_cnt = tp->cur_tx - tp->dirty_tx;
tp->tx_skbuff[entry] = skb;
tp->tx_ring[entry].buffer1 = virt_to_le32desc(skb->data);
- if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
+ if (q_used_cnt < TX_QUEUE_LEN/2) {/* Typical path */
flag = 0x60000000; /* No interrupt */
- } else if (tp->cur_tx - tp->dirty_tx == TX_RING_SIZE/2) {
+ } else if (q_used_cnt == TX_QUEUE_LEN/2) {
flag = 0xe0000000; /* Tx-done intr. */
- } else if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE - 2) {
+ } else if (q_used_cnt < TX_QUEUE_LEN) {
flag = 0x60000000; /* No Tx-done intr. */
} else { /* Leave room for set_rx_mode() to fill entries. */
tp->tx_full = 1;
@@ -2686,7 +2689,7 @@
#endif
if (tp->tx_full && dev->tbusy
- && tp->cur_tx - dirty_tx < TX_RING_SIZE - 2) {
+ && tp->cur_tx - dirty_tx < TX_QUEUE_LEN - 4) {
/* The ring is no longer full, clear tbusy. */
tp->tx_full = 0;
dev->tbusy = 0;
@@ -2753,11 +2756,18 @@
"csr5=0x%8.8x. (%lu) (%d,%d,%d)\n", dev->name, csr5, tp->nir, tx, rx, oi);
/* Acknowledge all interrupt sources. */
#if 0
- /* Clear all interrupting sources, set timer to re-enable. */
- outl(((~csr5) & 0x0001ebef) | NormalIntr | AbnormalIntr | TimerInt,
- ioaddr + CSR7);
- outl(12, ioaddr + CSR11);
- tp->ttimer = 1;
+ outl(0x8001ffff, ioaddr + CSR5);
+#endif
+ if (tp->flags & HAS_INTR_MITIGATION)
+ outl(0x45240000, ioaddr + CSR11);
+#if 0
+ else {
+ /* Mask all interrupting sources, set timer to e-enable. */
+ outl(((~csr5) & 0x0001ebef) | AbnormalIntr | TimerInt,
+ ioaddr + CSR7);
+ outl(0x0012, ioaddr + CSR11);
+ }
+ tp->ttimer = 1;
#endif
break;
}
--
Sincerely, srb@cuci.nl
Stephen R. van den Berg (AKA BuGless).
"Good moaning!"