Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-7]: src/sys/dev/pci Pull up following revision(s) (requested by m...
details: https://anonhg.NetBSD.org/src/rev/4a9c81ac480c
branches: netbsd-7
changeset: 800151:4a9c81ac480c
user: snj <snj%NetBSD.org@localhost>
date: Thu Mar 09 06:28:36 2017 +0000
description:
Pull up following revision(s) (requested by msaitoh in ticket #1372):
sys/dev/pci/if_wm.c: revisions 1.462, 1.464-1.465 1.474 via patch
sys/dev/pci/if_wmreg.h: revision 1.97
sys/dev/pci/if_wmvar.h: revision 1.33
- Set IPV6EXDIS bit in RFCTL register because of an Errata on 82575 and
newer devices.
- Linux and FreeBSD defines 0x10f5 as E1000_DEV_ID_ICH9_IGP_M_AMT. In
reality, This is not IGP but BM. Add new case to identify PHY type
device. Fixes PR#51924 reported byJarle Greipsland.
- Use new wm_gmii_setup_phytype() function to setup sc_phytype and
mii_{read|write}reg. This change improves detection of PHY type.
- Fix typo in comment.
diffstat:
sys/dev/pci/if_wm.c | 378 ++++++++++++++++++++++++++++++++++++------------
sys/dev/pci/if_wmreg.h | 4 +-
sys/dev/pci/if_wmvar.h | 4 +-
3 files changed, 283 insertions(+), 103 deletions(-)
diffs (truncated from 490 to 300 lines):
diff -r 2131b91d9570 -r 4a9c81ac480c sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Thu Mar 09 06:26:04 2017 +0000
+++ b/sys/dev/pci/if_wm.c Thu Mar 09 06:28:36 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.289.2.12 2016/12/18 07:53:08 snj Exp $ */
+/* $NetBSD: if_wm.c,v 1.289.2.13 2017/03/09 06:28:36 snj Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -84,7 +84,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.289.2.12 2016/12/18 07:53:08 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.289.2.13 2017/03/09 06:28:36 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -638,6 +638,7 @@
static void wm_tbi_serdes_set_linkled(struct wm_softc *);
/* GMII related */
static void wm_gmii_reset(struct wm_softc *);
+static void wm_gmii_setup_phytype(struct wm_softc *sc, uint32_t, uint16_t);
static int wm_get_phy_id_82575(struct wm_softc *);
static void wm_gmii_mediainit(struct wm_softc *, pci_product_id_t);
static int wm_gmii_mediachange(struct ifnet *);
@@ -3670,11 +3671,11 @@
}
CSR_WRITE(sc, WMREG_TARC0, tarc0);
+ switch (sc->sc_type) {
/*
- * 8257[12] Errata No.52 and some others.
+ * 8257[12] Errata No.52, 82573 Errata No.43 and some others.
* Avoid RSS Hash Value bug.
*/
- switch (sc->sc_type) {
case WM_T_82571:
case WM_T_82572:
case WM_T_82573:
@@ -3687,6 +3688,20 @@
default:
break;
}
+ } else if ((sc->sc_type >= WM_T_82575) && (sc->sc_type <= WM_T_I211)) {
+ /*
+ * 82575 Errata XXX, 82576 Errata 46, 82580 Errata 24,
+ * I350 Errata 37, I210 Errata No. 31 and I211 Errata No. 11:
+ * "Certain Malformed IPv6 Extension Headers are Not Processed
+ * Correctly by the Device"
+ *
+ * I354(C2000) Errata AVR53:
+ * "Malformed IPv6 Extension Headers May Result in LAN Device
+ * Hang"
+ */
+ reg = CSR_READ(sc, WMREG_RFCTL);
+ reg |= WMREG_RFCTL_IPV6EXDIS;
+ CSR_WRITE(sc, WMREG_RFCTL, reg);
}
}
@@ -6798,6 +6813,251 @@
}
/*
+ * Setup sc_phytype and mii_{read|write}reg.
+ *
+ * To identify PHY type, correct read/write function should be selected.
+ * To select correct read/write function, PCI ID or MAC type are required
+ * without accessing PHY registers.
+ *
+ * On the first call of this function, PHY ID is not known yet. Check
+ * PCI ID or MAC type. The list of the PCI ID may not be perfect, so the
+ * result might be incorrect.
+ *
+ * In the second call, PHY OUI and model is used to identify PHY type.
+ * It might not be perfpect because of the lack of compared entry, but it
+ * would be better than the first call.
+ *
+ * If the detected new result and previous assumption is different,
+ * diagnous message will be printed.
+ */
+static void
+wm_gmii_setup_phytype(struct wm_softc *sc, uint32_t phy_oui,
+ uint16_t phy_model)
+{
+ device_t dev = sc->sc_dev;
+ struct mii_data *mii = &sc->sc_mii;
+ uint16_t new_phytype = WMPHY_UNKNOWN;
+ uint16_t doubt_phytype = WMPHY_UNKNOWN;
+ mii_readreg_t new_readreg;
+ mii_writereg_t new_writereg;
+
+ if (mii->mii_readreg == NULL) {
+ /*
+ * This is the first call of this function. For ICH and PCH
+ * variants, it's difficult to determine the PHY access method
+ * by sc_type, so use the PCI product ID for some devices.
+ */
+
+ switch (sc->sc_pcidevid) {
+ case PCI_PRODUCT_INTEL_PCH_M_LM:
+ case PCI_PRODUCT_INTEL_PCH_M_LC:
+ /* 82577 */
+ new_phytype = WMPHY_82577;
+ break;
+ case PCI_PRODUCT_INTEL_PCH_D_DM:
+ case PCI_PRODUCT_INTEL_PCH_D_DC:
+ /* 82578 */
+ new_phytype = WMPHY_82578;
+ break;
+ case PCI_PRODUCT_INTEL_PCH2_LV_LM:
+ case PCI_PRODUCT_INTEL_PCH2_LV_V:
+ /* 82579 */
+ new_phytype = WMPHY_82579;
+ break;
+ case PCI_PRODUCT_INTEL_82801H_82567V_3:
+ case PCI_PRODUCT_INTEL_82801I_BM:
+ case PCI_PRODUCT_INTEL_82801I_IGP_M_AMT: /* Not IGP but BM */
+ case PCI_PRODUCT_INTEL_82801J_R_BM_LM:
+ case PCI_PRODUCT_INTEL_82801J_R_BM_LF:
+ case PCI_PRODUCT_INTEL_82801J_D_BM_LM:
+ case PCI_PRODUCT_INTEL_82801J_D_BM_LF:
+ case PCI_PRODUCT_INTEL_82801J_R_BM_V:
+ /* ICH8, 9, 10 with 82567 */
+ new_phytype = WMPHY_BM;
+ break;
+ default:
+ break;
+ }
+ } else {
+ /* It's not the first call. Use PHY OUI and model */
+ switch (phy_oui) {
+ case MII_OUI_ATHEROS: /* XXX ??? */
+ switch (phy_model) {
+ case 0x0004: /* XXX */
+ new_phytype = WMPHY_82578;
+ break;
+ default:
+ break;
+ }
+ break;
+ case MII_OUI_xxMARVELL:
+ switch (phy_model) {
+ case MII_MODEL_xxMARVELL_I210:
+ new_phytype = WMPHY_I210;
+ break;
+ case MII_MODEL_xxMARVELL_E1011:
+ case MII_MODEL_xxMARVELL_E1000_3:
+ case MII_MODEL_xxMARVELL_E1000_5:
+ case MII_MODEL_xxMARVELL_E1112:
+ new_phytype = WMPHY_M88;
+ break;
+ case MII_MODEL_xxMARVELL_E1149:
+ new_phytype = WMPHY_BM;
+ break;
+ case MII_MODEL_xxMARVELL_E1111:
+ case MII_MODEL_xxMARVELL_I347:
+ case MII_MODEL_xxMARVELL_E1512:
+ case MII_MODEL_xxMARVELL_E1340M:
+ case MII_MODEL_xxMARVELL_E1543:
+ new_phytype = WMPHY_M88;
+ break;
+ case MII_MODEL_xxMARVELL_I82563:
+ new_phytype = WMPHY_GG82563;
+ break;
+ default:
+ break;
+ }
+ break;
+ case MII_OUI_INTEL:
+ switch (phy_model) {
+ case MII_MODEL_INTEL_I82577:
+ new_phytype = WMPHY_82577;
+ break;
+ case MII_MODEL_INTEL_I82579:
+ new_phytype = WMPHY_82579;
+ break;
+ case MII_MODEL_INTEL_I217:
+ new_phytype = WMPHY_I217;
+ break;
+ case MII_MODEL_INTEL_I82580:
+ case MII_MODEL_INTEL_I350:
+ new_phytype = WMPHY_82580;
+ break;
+ default:
+ break;
+ }
+ break;
+ case MII_OUI_yyINTEL:
+ switch (phy_model) {
+ case MII_MODEL_yyINTEL_I82562G:
+ case MII_MODEL_yyINTEL_I82562EM:
+ case MII_MODEL_yyINTEL_I82562ET:
+ new_phytype = WMPHY_IFE;
+ break;
+ case MII_MODEL_yyINTEL_IGP01E1000:
+ new_phytype = WMPHY_IGP;
+ break;
+ case MII_MODEL_yyINTEL_I82566:
+ new_phytype = WMPHY_IGP_3;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ if (new_phytype == WMPHY_UNKNOWN)
+ aprint_verbose_dev(dev, "%s: unknown PHY model\n",
+ __func__);
+
+ if ((sc->sc_phytype != WMPHY_UNKNOWN)
+ && (sc->sc_phytype != new_phytype )) {
+ aprint_error_dev(dev, "Previously assumed PHY type(%u)"
+ "was incorrect. PHY type from PHY ID = %u\n",
+ sc->sc_phytype, new_phytype);
+ }
+ }
+
+ /* Next, use sc->sc_flags and sc->sc_type to set read/write funcs. */
+ if (((sc->sc_flags & WM_F_SGMII) != 0) && !wm_sgmii_uses_mdio(sc)) {
+ /* SGMII */
+ new_readreg = wm_sgmii_readreg;
+ new_writereg = wm_sgmii_writereg;
+ } else if ((sc->sc_type == WM_T_82574) || (sc->sc_type == WM_T_82583)){
+ /* BM2 (phyaddr == 1) */
+ if ((sc->sc_phytype != WMPHY_UNKNOWN)
+ && (new_phytype != WMPHY_BM)
+ && (new_phytype != WMPHY_UNKNOWN))
+ doubt_phytype = new_phytype;
+ new_phytype = WMPHY_BM;
+ new_readreg = wm_gmii_bm_readreg;
+ new_writereg = wm_gmii_bm_writereg;
+ } else if (sc->sc_type >= WM_T_PCH) {
+ /* All PCH* use _hv_ */
+ new_readreg = wm_gmii_hv_readreg;
+ new_writereg = wm_gmii_hv_writereg;
+ } else if (sc->sc_type >= WM_T_ICH8) {
+ /* non-82567 ICH8, 9 and 10 */
+ new_readreg = wm_gmii_i82544_readreg;
+ new_writereg = wm_gmii_i82544_writereg;
+ } else if (sc->sc_type >= WM_T_80003) {
+ /* 80003 */
+ if ((sc->sc_phytype != WMPHY_UNKNOWN)
+ && (new_phytype != WMPHY_GG82563)
+ && (new_phytype != WMPHY_UNKNOWN))
+ doubt_phytype = new_phytype;
+ new_phytype = WMPHY_GG82563;
+ new_readreg = wm_gmii_i80003_readreg;
+ new_writereg = wm_gmii_i80003_writereg;
+ } else if (sc->sc_type >= WM_T_I210) {
+ /* I210 and I211 */
+ if ((sc->sc_phytype != WMPHY_UNKNOWN)
+ && (new_phytype != WMPHY_I210)
+ && (new_phytype != WMPHY_UNKNOWN))
+ doubt_phytype = new_phytype;
+ new_phytype = WMPHY_I210;
+ new_readreg = wm_gmii_gs40g_readreg;
+ new_writereg = wm_gmii_gs40g_writereg;
+ } else if (sc->sc_type >= WM_T_82580) {
+ /* 82580, I350 and I354 */
+ new_readreg = wm_gmii_82580_readreg;
+ new_writereg = wm_gmii_82580_writereg;
+ } else if (sc->sc_type >= WM_T_82544) {
+ /* 82544, 0, [56], [17], 8257[1234] and 82583 */
+ new_readreg = wm_gmii_i82544_readreg;
+ new_writereg = wm_gmii_i82544_writereg;
+ } else {
+ new_readreg = wm_gmii_i82543_readreg;
+ new_writereg = wm_gmii_i82543_writereg;
+ }
+
+ if (new_phytype == WMPHY_BM) {
+ /* All BM use _bm_ */
+ new_readreg = wm_gmii_bm_readreg;
+ new_writereg = wm_gmii_bm_writereg;
+ }
+ if ((sc->sc_type >= WM_T_PCH) && (sc->sc_type <= WM_T_PCH_SPT)) {
+ /* All PCH* use _hv_ */
+ new_readreg = wm_gmii_hv_readreg;
+ new_writereg = wm_gmii_hv_writereg;
+ }
+
+ /* Diag output */
+ if (doubt_phytype != WMPHY_UNKNOWN)
+ aprint_error_dev(dev, "Assumed new PHY type was "
+ "incorrect. old = %u, new = %u\n", sc->sc_phytype,
+ new_phytype);
+ else if ((sc->sc_phytype != WMPHY_UNKNOWN)
+ && (sc->sc_phytype != new_phytype ))
+ aprint_error_dev(dev, "Previously assumed PHY type(%u)"
+ "was incorrect. New PHY type = %u\n",
+ sc->sc_phytype, new_phytype);
+
+ if ((mii->mii_readreg != NULL) && (new_phytype == WMPHY_UNKNOWN))
+ aprint_error_dev(dev, "PHY type is still unknown.\n");
+
+ if ((mii->mii_readreg != NULL) && (mii->mii_readreg != new_readreg))
Home |
Main Index |
Thread Index |
Old Index