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.
This commit is contained in:
parent
d3adc65594
commit
f37739d7ab
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=185596
@ -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 @@ jme_dma_alloc(struct jme_softc *sc)
|
||||
}
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user