jme: Rework software reset procedure
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 19 Dec 2010 12:07:13 +0000 (20:07 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 19 Dec 2010 12:18:04 +0000 (20:18 +0800)
There is a wired TX/RX clock synchronization issues during software reset.
To address these issues we have to disable and enable TX/RX clocks several
times according to JMicron's document.

These clock synchronization issues seem to affect JMC250C/JMC260C chips,
however, it is claimed that these issues affact all JMC250/JMC260 chips.

Thank JMicron for providing JMC250C samples and detailed document.

sys/dev/netif/jme/if_jme.c
sys/dev/netif/jme/if_jmereg.h

index 7cc5d2a..fcea1f1 100644 (file)
@@ -2268,14 +2268,73 @@ jme_tick(void *xsc)
 static void
 jme_reset(struct jme_softc *sc)
 {
-#ifdef foo
-       /* Stop receiver, transmitter. */
-       jme_stop_rx(sc);
+       uint32_t val;
+
+       /* Make sure that TX and RX are stopped */
        jme_stop_tx(sc);
-#endif
+       jme_stop_rx(sc);
+
+       /* Start reset */
        CSR_WRITE_4(sc, JME_GHC, GHC_RESET);
-       DELAY(10);
+       DELAY(20);
+
+       /*
+        * Hold reset bit before stop reset
+        */
+
+       /* Disable TXMAC and TXOFL clock sources */
+       CSR_WRITE_4(sc, JME_GHC, GHC_RESET);
+       /* Disable RXMAC clock source */
+       val = CSR_READ_4(sc, JME_GPREG1);
+       CSR_WRITE_4(sc, JME_GPREG1, val | GPREG1_DIS_RXMAC_CLKSRC);
+       /* Flush */
+       CSR_READ_4(sc, JME_GHC);
+
+       /* Stop reset */
        CSR_WRITE_4(sc, JME_GHC, 0);
+       /* Flush */
+       CSR_READ_4(sc, JME_GHC);
+
+       /*
+        * Clear reset bit after stop reset
+        */
+
+       /* Enable TXMAC and TXOFL clock sources */
+       CSR_WRITE_4(sc, JME_GHC, GHC_TXOFL_CLKSRC | GHC_TXMAC_CLKSRC);
+       /* Enable RXMAC clock source */
+       val = CSR_READ_4(sc, JME_GPREG1);
+       CSR_WRITE_4(sc, JME_GPREG1, val & ~GPREG1_DIS_RXMAC_CLKSRC);
+       /* Flush */
+       CSR_READ_4(sc, JME_GHC);
+
+       /* Disable TXMAC and TXOFL clock sources */
+       CSR_WRITE_4(sc, JME_GHC, 0);
+       /* Disable RXMAC clock source */
+       val = CSR_READ_4(sc, JME_GPREG1);
+       CSR_WRITE_4(sc, JME_GPREG1, val | GPREG1_DIS_RXMAC_CLKSRC);
+       /* Flush */
+       CSR_READ_4(sc, JME_GHC);
+
+       /* Enable TX and RX */
+       val = CSR_READ_4(sc, JME_TXCSR);
+       CSR_WRITE_4(sc, JME_TXCSR, val | TXCSR_TX_ENB);
+       val = CSR_READ_4(sc, JME_RXCSR);
+       CSR_WRITE_4(sc, JME_RXCSR, val | RXCSR_RX_ENB);
+       /* Flush */
+       CSR_READ_4(sc, JME_TXCSR);
+       CSR_READ_4(sc, JME_RXCSR);
+
+       /* Enable TXMAC and TXOFL clock sources */
+       CSR_WRITE_4(sc, JME_GHC, GHC_TXOFL_CLKSRC | GHC_TXMAC_CLKSRC);
+       /* Eisable RXMAC clock source */
+       val = CSR_READ_4(sc, JME_GPREG1);
+       CSR_WRITE_4(sc, JME_GPREG1, val & ~GPREG1_DIS_RXMAC_CLKSRC);
+       /* Flush */
+       CSR_READ_4(sc, JME_GHC);
+
+       /* Stop TX and RX */
+       jme_stop_tx(sc);
+       jme_stop_rx(sc);
 }
 
 static void
index a96f86e..460969f 100644 (file)
@@ -35,6 +35,7 @@
 #define JME_REV1_A1            0x10
 #define JME_REV1_A2            0x11    /* JMC250A2 */
 #define JME_REV2               0x20
+#define JME_REV5               0x50
 
 /* JMC250 PCI configuration register. */
 #define JME_PCIR_BAR           PCIR_BAR(0)
 #define        JME_GPREG1              0x080C
 #define GPREG1_WA_HDX          0x00000020 /* 250A2 only, for 10/100 mode */
 #define GPREG1_WA_IP6RSS       0x00000040 /* 250A2 only, for 10/100 mode */
+#define GPREG1_DIS_RXMAC_CLKSRC        0x04000000
 
 /* MSIX entry number of interrupt source. */
 #define        JME_MSINUM_BASE         0x0810