em(4): Put back the workaround and related comment for 82542 rev2
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 17 Feb 2009 12:58:57 +0000 (20:58 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 24 Feb 2009 10:50:47 +0000 (18:50 +0800)
sys/dev/netif/em/if_em.c
sys/dev/netif/ig_hal/e1000_defines.h

index 220cde6..485c1d0 100644 (file)
@@ -3257,7 +3257,22 @@ em_enable_intr(struct adapter *adapter)
 static void
 em_disable_intr(struct adapter *adapter)
 {
-       E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
+       uint32_t clear = 0xffffffff;
+
+       /*
+        * The first version of 82542 had an errata where when link was forced
+        * it would stay up even up even if the cable was disconnected.
+        * Sequence errors were used to detect the disconnect and then the
+        * driver would unforce the link.  This code in the in the ISR.  For
+        * this to work correctly the Sequence error interrupt had to be
+        * enabled all the time.
+        */
+       if (adapter->hw.mac.type == e1000_82542 &&
+           adapter->hw.revision_id == E1000_REVISION_2)
+               clear &= ~E1000_IMC_RXSEQ;
+
+       E1000_WRITE_REG(&adapter->hw, E1000_IMC, clear);
+
        lwkt_serialize_handler_disable(adapter->arpcom.ac_if.if_serializer);
 }
 
index 81259a1..b454a69 100644 (file)
 #define E1000_EIMS_TCP_TIMER    E1000_EICR_TCP_TIMER /* TCP Timer */
 #define E1000_EIMS_OTHER        E1000_EICR_OTHER   /* Interrupt Cause Active */
 
+/* Interrupt Mask Clear */
+#define E1000_IMC_RXSEQ                E1000_ICR_RXSEQ /* rx sequence error */
+
 /* Interrupt Cause Set */
 #define E1000_ICS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
 #define E1000_ICS_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */