diff options
-rw-r--r-- | sys/dev/pci/if_jme.c | 30 | ||||
-rw-r--r-- | sys/dev/pci/if_jmereg.h | 6 | ||||
-rw-r--r-- | sys/dev/pci/if_jmevar.h | 7 |
3 files changed, 33 insertions, 10 deletions
diff --git a/sys/dev/pci/if_jme.c b/sys/dev/pci/if_jme.c index 1f0b37569dc..bd27aa36131 100644 --- a/sys/dev/pci/if_jme.c +++ b/sys/dev/pci/if_jme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_jme.c,v 1.11 2008/10/21 19:41:13 brad Exp $ */ +/* $OpenBSD: if_jme.c,v 1.12 2008/10/29 01:55:53 brad Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -550,6 +550,10 @@ jme_attach(struct device *parent, struct device *self, void *aux) } } + if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_JMICRON_JMC250 && + PCI_REVISION(pa->pa_class) == JME_REV_JMC250_A2) + sc->jme_workaround |= JME_WA_CRCERRORS | JME_WA_PACKETLOSS; + /* Reset the ethernet controller. */ jme_reset(sc); @@ -1356,8 +1360,8 @@ void jme_mac_config(struct jme_softc *sc) { struct mii_data *mii; - uint32_t ghc, rxmac, txmac, txpause; - int phyconf = JMPHY_CONF_DEFFIFO; + uint32_t ghc, rxmac, txmac, txpause, gp1; + int phyconf = JMPHY_CONF_DEFFIFO, hdx = 0; mii = &sc->sc_miibus; @@ -1394,14 +1398,26 @@ jme_mac_config(struct jme_softc *sc) TXTRHD_RT_PERIOD_ENB | TXTRHD_RT_LIMIT_ENB); } - /* Reprogram Tx/Rx MACs with resolved speed/duplex. */ + /* + * Reprogram Tx/Rx MACs with resolved speed/duplex. + */ + gp1 = CSR_READ_4(sc, JME_GPREG1); + gp1 &= ~GPREG1_HALF_PATCH; + + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) == 0) + hdx = 1; + switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_10_T: ghc |= GHC_SPEED_10; + if (hdx) + gp1 |= GPREG1_HALF_PATCH; break; case IFM_100_TX: ghc |= GHC_SPEED_100; + if (hdx) + gp1 |= GPREG1_HALF_PATCH; /* * Use extended FIFO depth to workaround CRC errors @@ -1415,7 +1431,7 @@ jme_mac_config(struct jme_softc *sc) break; ghc |= GHC_SPEED_1000; - if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) == 0) + if (hdx) txmac |= TXMAC_CARRIER_EXT | TXMAC_FRAME_BURST; break; @@ -1427,10 +1443,12 @@ jme_mac_config(struct jme_softc *sc) CSR_WRITE_4(sc, JME_TXMAC, txmac); CSR_WRITE_4(sc, JME_TXPFC, txpause); - if (sc->jme_caps & JME_CAP_EXTFIFO) { + if (sc->jme_workaround & JME_WA_CRCERRORS) { jme_miibus_writereg(&sc->sc_dev, sc->jme_phyaddr, JMPHY_CONF, phyconf); } + if (sc->jme_workaround & JME_WA_PACKETLOSS) + CSR_WRITE_4(sc, JME_GPREG1, gp1); } int diff --git a/sys/dev/pci/if_jmereg.h b/sys/dev/pci/if_jmereg.h index 1632ea9a1a2..90ced06bad2 100644 --- a/sys/dev/pci/if_jmereg.h +++ b/sys/dev/pci/if_jmereg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_jmereg.h,v 1.1 2008/09/26 10:35:15 jsg Exp $ */ +/* $OpenBSD: if_jmereg.h,v 1.2 2008/10/29 01:55:53 brad Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -555,8 +555,10 @@ #define GPREG0_PHY_ADDR_SHIFT 0 #define GPREG0_PHY_ADDR 1 -/* General purpose register 1. reserved for future use. */ +/* General purpose register 1. */ #define JME_GPREG1 0x080C +#define GPREG1_HALF_PATCH 0x00000020 /* 250A2 only, for 10/100 mode */ +#define GPREG1_RSS_PATCH 0x00000040 /* 250A2 only, for 10/100 mode */ /* MSIX entry number of interrupt source. */ #define JME_MSINUM_BASE 0x0810 diff --git a/sys/dev/pci/if_jmevar.h b/sys/dev/pci/if_jmevar.h index c8024a624a2..19a70545aa3 100644 --- a/sys/dev/pci/if_jmevar.h +++ b/sys/dev/pci/if_jmevar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_jmevar.h,v 1.2 2008/10/20 19:36:54 brad Exp $ */ +/* $OpenBSD: if_jmevar.h,v 1.3 2008/10/29 01:55:53 brad Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -192,7 +192,10 @@ struct jme_softc { #define JME_CAP_PMCAP 0x0004 #define JME_CAP_FASTETH 0x0008 #define JME_CAP_JUMBO 0x0010 -#define JME_CAP_EXTFIFO 0x0020 + + uint32_t jme_workaround; +#define JME_WA_CRCERRORS 0x0001 +#define JME_WA_PACKETLOSS 0x0002 uint32_t jme_flags; #define JME_FLAG_MSI 0x0001 |