Author: yongari
Date: Thu Dec  4 01:58:40 2008
New Revision: 185596
URL: http://svn.freebsd.org/changeset/base/185596

Log:
  Add support for newer JMC250/JMC260 revisions.
   o Chip full mask revision 2 or later controllers have to
     set correct Tx MAC and Tx offload clock depending on negotiated
     link speed.
   o JMC260 chip full mask revision 2 has a silicon bug that can't
     handle 64bit DMA addressing. Add workaround to the bug by
     limiting DMA address space to be within 32bit.
   o Valid FIFO space of receive control and status register was
     changed on chip full mask revision 2 or later controllers. For
     these controllers, use default 16QW as it's supposed to be the
     safest value for maximum PCIe compatibility. JMicron confirmed
     performance will not be reduced even if the FIFO space is set
     to 16QW.
   o When interface is put into suspend/shutdown state, remove Tx MAC
     and Tx offload clock to save more power. We don't need Tx clock
     at all in this state.
   o Added new register definition for chip full mask revision 2 or
     later controllers.
  
  Thanks to JMicron for their continuous support of FreeBSD.

Modified:
  head/sys/dev/jme/if_jme.c
  head/sys/dev/jme/if_jmereg.h
  head/sys/dev/jme/if_jmevar.h

Modified: head/sys/dev/jme/if_jme.c
==============================================================================
--- head/sys/dev/jme/if_jme.c   Thu Dec  4 01:24:21 2008        (r185595)
+++ head/sys/dev/jme/if_jme.c   Thu Dec  4 01:58:40 2008        (r185596)
@@ -651,6 +651,13 @@ jme_attach(device_t dev)
                goto fail;
        }
 
+       if (CHIPMODE_REVFM(sc->jme_chip_rev) >= 2) {
+               if ((sc->jme_rev & DEVICEID_JMC2XX_MASK) == DEVICEID_JMC260 &&
+                   CHIPMODE_REVFM(sc->jme_chip_rev) == 2)
+                       sc->jme_flags |= JME_FLAG_DMA32BIT;
+               sc->jme_flags |= JME_FLAG_TXCLK;
+       }
+
        /* Reset the ethernet controller. */
        jme_reset(sc);
 
@@ -1007,6 +1014,8 @@ jme_dma_alloc(struct jme_softc *sc)
        int error, i;
 
        lowaddr = BUS_SPACE_MAXADDR;
+       if ((sc->jme_flags & JME_FLAG_DMA32BIT) != 0)
+               lowaddr = BUS_SPACE_MAXADDR_32BIT;
 
 again:
        /* Create parent ring tag. */
@@ -1106,25 +1115,32 @@ again:
        }
        sc->jme_rdata.jme_rx_ring_paddr = ctx.jme_busaddr;
 
-       /* Tx/Rx descriptor queue should reside within 4GB boundary. */
-       tx_ring_end = sc->jme_rdata.jme_tx_ring_paddr + JME_TX_RING_SIZE;
-       rx_ring_end = sc->jme_rdata.jme_rx_ring_paddr + JME_RX_RING_SIZE;
-       if ((JME_ADDR_HI(tx_ring_end) !=
-           JME_ADDR_HI(sc->jme_rdata.jme_tx_ring_paddr)) ||
-           (JME_ADDR_HI(rx_ring_end) !=
-           JME_ADDR_HI(sc->jme_rdata.jme_rx_ring_paddr))) {
-               device_printf(sc->jme_dev, "4GB boundary crossed, "
-                   "switching to 32bit DMA address mode.\n");
-               jme_dma_free(sc);
-               /* Limit DMA address space to 32bit and try again. */
-               lowaddr = BUS_SPACE_MAXADDR_32BIT;
-               goto again;
+       if (lowaddr != BUS_SPACE_MAXADDR_32BIT) {
+               /* Tx/Rx descriptor queue should reside within 4GB boundary. */
+               tx_ring_end = sc->jme_rdata.jme_tx_ring_paddr +
+                   JME_TX_RING_SIZE;
+               rx_ring_end = sc->jme_rdata.jme_rx_ring_paddr +
+                   JME_RX_RING_SIZE;
+               if ((JME_ADDR_HI(tx_ring_end) !=
+                   JME_ADDR_HI(sc->jme_rdata.jme_tx_ring_paddr)) ||
+                   (JME_ADDR_HI(rx_ring_end) !=
+                    JME_ADDR_HI(sc->jme_rdata.jme_rx_ring_paddr))) {
+                       device_printf(sc->jme_dev, "4GB boundary crossed, "
+                           "switching to 32bit DMA address mode.\n");
+                       jme_dma_free(sc);
+                       /* Limit DMA address space to 32bit and try again. */
+                       lowaddr = BUS_SPACE_MAXADDR_32BIT;
+                       goto again;
+               }
        }
 
+       lowaddr = BUS_SPACE_MAXADDR;
+       if ((sc->jme_flags & JME_FLAG_DMA32BIT) != 0)
+               lowaddr = BUS_SPACE_MAXADDR_32BIT;
        /* Create parent buffer tag. */
        error = bus_dma_tag_create(bus_get_dma_tag(sc->jme_dev),/* parent */
            1, 0,                       /* algnmnt, boundary */
-           BUS_SPACE_MAXADDR,          /* lowaddr */
+           lowaddr,                    /* lowaddr */
            BUS_SPACE_MAXADDR,          /* highaddr */
            NULL, NULL,                 /* filter, filterarg */
            BUS_SPACE_MAXSIZE_32BIT,    /* maxsize */
@@ -1445,6 +1461,11 @@ jme_setwol(struct jme_softc *sc)
        JME_LOCK_ASSERT(sc);
 
        if (pci_find_extcap(sc->jme_dev, PCIY_PMG, &pmc) != 0) {
+               /* Remove Tx MAC/offload clock to save more power. */
+               if ((sc->jme_flags & JME_FLAG_TXCLK) != 0)
+                       CSR_WRITE_4(sc, JME_GHC, CSR_READ_4(sc, JME_GHC) &
+                           ~(GHC_TX_OFFLD_CLK_100 | GHC_TX_MAC_CLK_100 |
+                           GHC_TX_OFFLD_CLK_1000 | GHC_TX_MAC_CLK_1000));
                /* No PME capability, PHY power down. */
                jme_miibus_writereg(sc->jme_dev, sc->jme_phyaddr,
                    MII_BMCR, BMCR_PDOWN);
@@ -1466,7 +1487,11 @@ jme_setwol(struct jme_softc *sc)
 
        CSR_WRITE_4(sc, JME_PMCS, pmcs);
        CSR_WRITE_4(sc, JME_GPREG0, gpr);
-
+       /* Remove Tx MAC/offload clock to save more power. */
+       if ((sc->jme_flags & JME_FLAG_TXCLK) != 0)
+               CSR_WRITE_4(sc, JME_GHC, CSR_READ_4(sc, JME_GHC) &
+                   ~(GHC_TX_OFFLD_CLK_100 | GHC_TX_MAC_CLK_100 |
+                   GHC_TX_OFFLD_CLK_1000 | GHC_TX_MAC_CLK_1000));
        /* Request PME. */
        pmstat = pci_read_config(sc->jme_dev, pmc + PCIR_POWER_STATUS, 2);
        pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
@@ -1941,6 +1966,7 @@ jme_mac_config(struct jme_softc *sc)
 {
        struct mii_data *mii;
        uint32_t ghc, gpreg, rxmac, txmac, txpause;
+       uint32_t txclk;
 
        JME_LOCK_ASSERT(sc);
 
@@ -1950,6 +1976,7 @@ jme_mac_config(struct jme_softc *sc)
        DELAY(10);
        CSR_WRITE_4(sc, JME_GHC, 0);
        ghc = 0;
+       txclk = 0;
        rxmac = CSR_READ_4(sc, JME_RXMAC);
        rxmac &= ~RXMAC_FC_ENB;
        txmac = CSR_READ_4(sc, JME_TXMAC);
@@ -1982,14 +2009,17 @@ jme_mac_config(struct jme_softc *sc)
        switch (IFM_SUBTYPE(mii->mii_media_active)) {
        case IFM_10_T:
                ghc |= GHC_SPEED_10;
+               txclk |= GHC_TX_OFFLD_CLK_100 | GHC_TX_MAC_CLK_100;
                break;
        case IFM_100_TX:
                ghc |= GHC_SPEED_100;
+               txclk |= GHC_TX_OFFLD_CLK_100 | GHC_TX_MAC_CLK_100;
                break;
        case IFM_1000_T:
                if ((sc->jme_flags & JME_FLAG_FASTETH) != 0)
                        break;
                ghc |= GHC_SPEED_1000;
+               txclk |= GHC_TX_OFFLD_CLK_1000 | GHC_TX_MAC_CLK_1000;
                if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) == 0)
                        txmac |= TXMAC_CARRIER_EXT | TXMAC_FRAME_BURST;
                break;
@@ -2019,6 +2049,8 @@ jme_mac_config(struct jme_softc *sc)
                            0x1B, 0x0004);
                }
        }
+       if ((sc->jme_flags & JME_FLAG_TXCLK) != 0)
+               ghc |= txclk;
        CSR_WRITE_4(sc, JME_GHC, ghc);
        CSR_WRITE_4(sc, JME_RXMAC, rxmac);
        CSR_WRITE_4(sc, JME_TXMAC, txmac);
@@ -2637,13 +2669,19 @@ jme_init_locked(struct jme_softc *sc)
         * decrease FIFO threshold to reduce the FIFO overruns for
         * frames larger than 4000 bytes.
         * For best performance of standard MTU sized frames use
-        * maximum allowable FIFO threshold, 128QW.
+        * maximum allowable FIFO threshold, 128QW. Note these do
+        * not hold on chip full mask verion >=2. For these
+        * controllers 64QW and 128QW are not valid value.
         */
-       if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +
-           ETHER_CRC_LEN) > JME_RX_FIFO_SIZE)
+       if (CHIPMODE_REVFM(sc->jme_chip_rev) >= 2)
                sc->jme_rxcsr |= RXCSR_FIFO_THRESH_16QW;
-       else
-               sc->jme_rxcsr |= RXCSR_FIFO_THRESH_128QW;
+       else {
+               if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +
+                   ETHER_CRC_LEN) > JME_RX_FIFO_SIZE)
+                       sc->jme_rxcsr |= RXCSR_FIFO_THRESH_16QW;
+               else
+                       sc->jme_rxcsr |= RXCSR_FIFO_THRESH_128QW;
+       }
        sc->jme_rxcsr |= sc->jme_rx_dma_size | RXCSR_RXQ_N_SEL(RXCSR_RXQ0);
        sc->jme_rxcsr |= RXCSR_DESC_RT_CNT(RXCSR_DESC_RT_CNT_DEFAULT);
        sc->jme_rxcsr |= RXCSR_DESC_RT_GAP_256 & RXCSR_DESC_RT_GAP_MASK;

Modified: head/sys/dev/jme/if_jmereg.h
==============================================================================
--- head/sys/dev/jme/if_jmereg.h        Thu Dec  4 01:24:21 2008        
(r185595)
+++ head/sys/dev/jme/if_jmereg.h        Thu Dec  4 01:58:40 2008        
(r185596)
@@ -239,8 +239,8 @@
 #define        RXCSR_FIFO_FTHRESH_MASK 0x30000000
 #define        RXCSR_FIFO_THRESH_16QW  0x00000000
 #define        RXCSR_FIFO_THRESH_32QW  0x04000000
-#define        RXCSR_FIFO_THRESH_64QW  0x08000000
-#define        RXCSR_FIFO_THRESH_128QW 0x0C000000
+#define        RXCSR_FIFO_THRESH_64QW  0x08000000      /* JMC250/JMC260 REVFM 
< 2 */
+#define        RXCSR_FIFO_THRESH_128QW 0x0C000000      /* JMC250/JMC260 REVFM 
< 2 */
 #define        RXCSR_FIFO_THRESH_MASK  0x0C000000
 #define        RXCSR_DMA_SIZE_16       0x00000000
 #define        RXCSR_DMA_SIZE_32       0x01000000
@@ -357,6 +357,16 @@
 #define        JME_GHC                 0x0054
 #define        GHC_LOOPBACK            0x80000000
 #define        GHC_RESET               0x40000000
+#define        GHC_RX_DMA_PWR_DIS      0x04000000      /* JMC250 REVFM >= 2 */
+#define        GHC_FIFO_RD_PWR_DIS     0x02000000      /* JMC250 REVFM >= 2 */
+#define        GHC_FIFO_WR_PWR_DIS     0x01000000      /* JMC250 REVFM >= 2 */
+#define        GHC_TX_OFFLD_CLK_100    0x00800000      /* JMC250/JMC260 REVFM 
>= 2 */
+#define        GHC_TX_OFFLD_CLK_1000   0x00400000      /* JMC250/JMC260 REVFM 
>= 2 */
+#define        GHC_TX_OFFLD_CLK_DIS    0x00000000      /* JMC250/JMC260 REVFM 
>= 2 */
+#define        GHC_TX_MAC_CLK_100      0x00200000      /* JMC250/JMC260 REVFM 
>= 2 */
+#define        GHC_TX_MAC_CLK_1000     0x00100000      /* JMC250/JMC260 REVFM 
>= 2 */
+#define        GHC_TX_MAC_CLK_DIS      0x00000000      /* JMC250/JMC260 REVFM 
>= 2 */
+#define        GHC_AUTO_PHY_STAT_DIS   0x00000080      /* JMC250/JMC260 REVFM 
>= 2 */
 #define        GHC_FULL_DUPLEX         0x00000040
 #define        GHC_SPEED_UNKNOWN       0x00000000
 #define        GHC_SPEED_10            0x00000010
@@ -755,6 +765,10 @@
 #define        CHIPMODE_MODE_128P_MAC  0x00000003
 #define        CHIPMODE_MODE_128P_DBG  0x00000002
 #define        CHIPMODE_MODE_128P_PHY  0x00000000
+/* Chip full mask revision. */
+#define        CHIPMODE_REVFM(x)       ((x) & 0x0F)
+/* Chip ECO revision. */
+#define        CHIPMODE_REVECO(x)      (((x) >> 4) & 0x0F)
 
 /* Shadow status base address high/low. */
 #define        JME_SHBASE_ADDR_HI      0x0848

Modified: head/sys/dev/jme/if_jmevar.h
==============================================================================
--- head/sys/dev/jme/if_jmevar.h        Thu Dec  4 01:24:21 2008        
(r185595)
+++ head/sys/dev/jme/if_jmevar.h        Thu Dec  4 01:58:40 2008        
(r185596)
@@ -181,6 +181,8 @@ struct jme_softc {
 #define        JME_FLAG_PMCAP          0x0020
 #define        JME_FLAG_FASTETH        0x0040
 #define        JME_FLAG_NOJUMBO        0x0080
+#define        JME_FLAG_TXCLK          0x0100
+#define        JME_FLAG_DMA32BIT       0x0200
 #define        JME_FLAG_DETACH         0x4000
 #define        JME_FLAG_LINK           0x8000
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to