Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Jul 2008 22:30:36 +0800
From:      mirnshi@gmail.com
To:        freebsd-drivers@freebsd.org
Subject:   patch for Attansic L2 FastEthernet
Message-ID:  <fe3493cd0807140730j1dd3bc09j27d2c8dacdc2ebad@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
------=_Part_57398_27213851.1216045836272
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Recently, I got an eeepc 701. And I installed FreeBSD 7.0 on it . The url
http://wiki.freebsd.org/AsusEee gives me a big hand. But, the driver of lan
did not work. The problem is that the driver can be loaded by kldload, but
the interrupt storm caused the system to stop responding when I use ifconfig
to mark the nic 'up'.  BTW, I used 10MB hub.

The driver uses taskqueue_enqueue. 'ae_intr' reads nic register, but
'ae_int_task' reads it again. So I merge them into the new 'ae_intr'.
I test 'ping' and 'ftp', it works well.

Please refer to the patch for details.

--- if_ae.c    2008-06-27 20:19:43.000000000 +0800
+++ /sys/dev/if_ae/if_ae.c    2008-07-14 21:54:06.000000000 +0800
@@ -1450,20 +1450,56 @@
 {
     ae_softc_t *sc;
     uint32_t val;
+    struct ifnet *ifp;
+    struct mii_data *mii;

     sc = (ae_softc_t *)arg;
+    AE_LOCK(sc);
     KASSERT(sc != NULL, ("[ae, %d]: sc is null", __LINE__));

     val = AE_READ_4(sc, AE_ISR_REG);
-    if (val == 0 || (val & AE_IMR_DEFAULT) == 0)
+    if (val == 0 || (val & AE_IMR_DEFAULT) == 0) {
+        AE_UNLOCK(sc);
         return FILTER_STRAY;
+    }

-    /* Disable interrupts. */
-    AE_WRITE_4(sc, AE_ISR_REG, AE_ISR_DISABLE);
+    /* Clear interrupts and disable them. */
+    AE_WRITE_4(sc, AE_ISR_REG, val | AE_ISR_DISABLE);

-    /* Schedule interrupt processing. */
-    taskqueue_enqueue(sc->tq, &sc->int_task);
+    ifp = sc->ifp;

+    if ((val & AE_ISR_PHY) != 0) {
+        /*
+         * Clear PHY interrupt. Not sure if it needed. From Linux.
+         */
+        ae_miibus_readreg(sc->miibus, 1, 19);
+    }
+
+#ifdef AE_DEBUG
+    if_printf(ifp, "Interrupt received: 0x%08x\n", val);
+#endif
+
+    if ((val & (AE_ISR_PHY | AE_ISR_MANUAL)) != 0) {
+        mii = device_get_softc(sc->miibus);
+        mii_mediachg(mii);
+    }
+
+    if ((val & (AE_ISR_DMAR_TIMEOUT | AE_ISR_DMAW_TIMEOUT |
+        AE_ISR_PHY_LINKDOWN)) != 0) {
+        ae_init_locked(sc);
+    }
+    if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+        if ((val & AE_ISR_TX_EVENT) != 0)
+            ae_tx_intr(sc);
+
+        if ((val & AE_ISR_RX_EVENT) != 0)
+            ae_rx_intr(sc);
+    }
+
+    /* Re-enable interrupts. */
+    AE_WRITE_4(sc, AE_ISR_REG, 0);
+
+    AE_UNLOCK(sc);
     return (FILTER_HANDLED);
 }

------=_Part_57398_27213851.1216045836272--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?fe3493cd0807140730j1dd3bc09j27d2c8dacdc2ebad>