patch for Attansic L2 FastEthernet
mirnshi at gmail.com
mirnshi at gmail.com
Mon Jul 14 14:56:55 UTC 2008
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);
}
More information about the freebsd-drivers
mailing list