Module Name: src Committed By: msaitoh Date: Wed Jul 26 06:48:49 UTC 2017
Modified Files: src/sys/dev/pci: if_wm.c if_wmreg.h if_wmvar.h Log Message: - Our MII readreg/writereg API has not way to detect an error. kmrn_{read,write}reg() are not used for MII API, so it's not required for these functions to use the same API. So, - Change return value as error code. - Change register vaule from int to uint16_t. - read: pass pointer for uint16_t as an argument. - Check return value on caller side. - Check whether it's required to use MDIC workaround for 80003 or not in wm_reset(). If the workaround isn't required, don't use the workaround code in wm_gmii_i80003_{read,write}reg. To generate a diff of this commit: cvs rdiff -u -r1.530 -r1.531 src/sys/dev/pci/if_wm.c cvs rdiff -u -r1.102 -r1.103 src/sys/dev/pci/if_wmreg.h cvs rdiff -u -r1.35 -r1.36 src/sys/dev/pci/if_wmvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/if_wm.c diff -u src/sys/dev/pci/if_wm.c:1.530 src/sys/dev/pci/if_wm.c:1.531 --- src/sys/dev/pci/if_wm.c:1.530 Tue Jul 25 06:00:17 2017 +++ src/sys/dev/pci/if_wm.c Wed Jul 26 06:48:49 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.530 2017/07/25 06:00:17 msaitoh Exp $ */ +/* $NetBSD: if_wm.c,v 1.531 2017/07/26 06:48:49 msaitoh Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -83,7 +83,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.530 2017/07/25 06:00:17 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.531 2017/07/26 06:48:49 msaitoh Exp $"); #ifdef _KERNEL_OPT #include "opt_net_mpsafe.h" @@ -809,10 +809,10 @@ static void wm_gmii_statchg(struct ifnet * These functions are not for accessing MII registers but for accessing * kumeran specific registers. */ -static int wm_kmrn_readreg(struct wm_softc *, int); -static int wm_kmrn_readreg_locked(struct wm_softc *, int); -static void wm_kmrn_writereg(struct wm_softc *, int, int); -static void wm_kmrn_writereg_locked(struct wm_softc *, int, int); +static int wm_kmrn_readreg(struct wm_softc *, int, uint16_t *); +static int wm_kmrn_readreg_locked(struct wm_softc *, int, uint16_t *); +static int wm_kmrn_writereg(struct wm_softc *, int, uint16_t); +static int wm_kmrn_writereg_locked(struct wm_softc *, int, uint16_t); /* SGMII */ static bool wm_sgmii_uses_mdio(struct wm_softc *); static int wm_sgmii_readreg(device_t, int, int); @@ -4247,6 +4247,8 @@ wm_reset(struct wm_softc *sc) int phy_reset = 0; int i, error = 0; uint32_t reg; + uint16_t kmreg; + int rv; DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n", device_xname(sc->sc_dev), __func__)); @@ -4641,6 +4643,21 @@ wm_reset(struct wm_softc *sc) if ((sc->sc_flags & WM_F_PLL_WA_I210) != 0) wm_pll_workaround_i210(sc); + + if (sc->sc_type == WM_T_80003) { + /* default to TRUE to enable the MDIC W/A */ + sc->sc_flags |= WM_F_80003_MDIC_WA; + + rv = wm_kmrn_readreg(sc, + KUMCTRLSTA_OFFSET >> KUMCTRLSTA_OFFSET_SHIFT, &kmreg); + if (rv == 0) { + if ((kmreg & KUMCTRLSTA_OPMODE_MASK) + == KUMCTRLSTA_OPMODE_INBAND_MDIO) + sc->sc_flags &= ~WM_F_80003_MDIC_WA; + else + sc->sc_flags |= WM_F_80003_MDIC_WA; + } + } } /* @@ -5414,7 +5431,7 @@ wm_init_locked(struct ifnet *ifp) wm_set_vlan(sc); if (sc->sc_flags & WM_F_HAS_MII) { - int val; + uint16_t kmreg; switch (sc->sc_type) { case WM_T_80003: @@ -5433,19 +5450,20 @@ wm_init_locked(struct ifnet *ifp) */ wm_kmrn_writereg(sc, KUMCTRLSTA_OFFSET_TIMEOUTS, 0xFFFF); - val = wm_kmrn_readreg(sc, KUMCTRLSTA_OFFSET_INB_PARAM); - val |= 0x3F; - wm_kmrn_writereg(sc, - KUMCTRLSTA_OFFSET_INB_PARAM, val); + wm_kmrn_readreg(sc, KUMCTRLSTA_OFFSET_INB_PARAM, + &kmreg); + kmreg |= 0x3F; + wm_kmrn_writereg(sc, KUMCTRLSTA_OFFSET_INB_PARAM, + kmreg); break; default: break; } if (sc->sc_type == WM_T_80003) { - val = CSR_READ(sc, WMREG_CTRL_EXT); - val &= ~CTRL_EXT_LINK_MODE_MASK; - CSR_WRITE(sc, WMREG_CTRL_EXT, val); + reg = CSR_READ(sc, WMREG_CTRL_EXT); + reg &= ~CTRL_EXT_LINK_MODE_MASK; + CSR_WRITE(sc, WMREG_CTRL_EXT, reg); /* Bypass RX and TX FIFO's */ wm_kmrn_writereg(sc, KUMCTRLSTA_OFFSET_FIFO_CTRL, @@ -9953,6 +9971,7 @@ static int wm_gmii_i80003_readreg(device_t dev, int phy, int reg) { struct wm_softc *sc = device_private(dev); + int page_select, temp; int rv; if (phy != 1) /* only one PHY on kumeran bus */ @@ -9963,19 +9982,35 @@ wm_gmii_i80003_readreg(device_t dev, int return 0; } - if ((reg & MII_ADDRMASK) < GG82563_MIN_ALT_REG) { - wm_gmii_mdic_writereg(dev, phy, GG82563_PHY_PAGE_SELECT, - reg >> GG82563_PAGE_SHIFT); - } else { - wm_gmii_mdic_writereg(dev, phy, GG82563_PHY_PAGE_SELECT_ALT, - reg >> GG82563_PAGE_SHIFT); + if ((reg & MII_ADDRMASK) < GG82563_MIN_ALT_REG) + page_select = GG82563_PHY_PAGE_SELECT; + else { + /* + * Use Alternative Page Select register to access registers + * 30 and 31. + */ + page_select = GG82563_PHY_PAGE_SELECT_ALT; } - /* Wait more 200us for a bug of the ready bit in the MDIC register */ - delay(200); - rv = wm_gmii_mdic_readreg(dev, phy, reg & MII_ADDRMASK); - delay(200); - sc->phy.release(sc); + temp = (uint16_t)reg >> GG82563_PAGE_SHIFT; + wm_gmii_mdic_writereg(dev, phy, page_select, temp); + if ((sc->sc_flags & WM_F_80003_MDIC_WA) != 0) { + /* + * Wait more 200us for a bug of the ready bit in the MDIC + * register. + */ + delay(200); + if (wm_gmii_mdic_readreg(dev, phy, page_select) != temp) { + device_printf(dev, "%s failed\n", __func__); + rv = 0; /* XXX */ + goto out; + } + rv = wm_gmii_mdic_readreg(dev, phy, reg & MII_ADDRMASK); + delay(200); + } else + rv = wm_gmii_mdic_readreg(dev, phy, reg & MII_ADDRMASK); +out: + sc->phy.release(sc); return rv; } @@ -9990,6 +10025,7 @@ static void wm_gmii_i80003_writereg(device_t dev, int phy, int reg, int val) { struct wm_softc *sc = device_private(dev); + int page_select, temp; if (phy != 1) /* only one PHY on kumeran bus */ return; @@ -9999,18 +10035,33 @@ wm_gmii_i80003_writereg(device_t dev, in return; } - if ((reg & MII_ADDRMASK) < GG82563_MIN_ALT_REG) { - wm_gmii_mdic_writereg(dev, phy, GG82563_PHY_PAGE_SELECT, - reg >> GG82563_PAGE_SHIFT); - } else { - wm_gmii_mdic_writereg(dev, phy, GG82563_PHY_PAGE_SELECT_ALT, - reg >> GG82563_PAGE_SHIFT); + if ((reg & MII_ADDRMASK) < GG82563_MIN_ALT_REG) + page_select = GG82563_PHY_PAGE_SELECT; + else { + /* + * Use Alternative Page Select register to access registers + * 30 and 31. + */ + page_select = GG82563_PHY_PAGE_SELECT_ALT; } - /* Wait more 200us for a bug of the ready bit in the MDIC register */ - delay(200); - wm_gmii_mdic_writereg(dev, phy, reg & MII_ADDRMASK, val); - delay(200); + temp = (uint16_t)reg >> GG82563_PAGE_SHIFT; + wm_gmii_mdic_writereg(dev, phy, page_select, temp); + if ((sc->sc_flags & WM_F_80003_MDIC_WA) != 0) { + /* + * Wait more 200us for a bug of the ready bit in the MDIC + * register. + */ + delay(200); + if (wm_gmii_mdic_readreg(dev, phy, page_select) != temp) { + device_printf(dev, "%s failed\n", __func__); + goto out; + } + wm_gmii_mdic_writereg(dev, phy, reg & MII_ADDRMASK, val); + delay(200); + } else + wm_gmii_mdic_writereg(dev, phy, reg & MII_ADDRMASK, val); +out: sc->phy.release(sc); } @@ -10510,7 +10561,7 @@ wm_gmii_statchg(struct ifnet *ifp) * Read a kumeran register */ static int -wm_kmrn_readreg(struct wm_softc *sc, int reg) +wm_kmrn_readreg(struct wm_softc *sc, int reg, uint16_t *val) { int rv; @@ -10521,10 +10572,10 @@ wm_kmrn_readreg(struct wm_softc *sc, int if (rv != 0) { device_printf(sc->sc_dev, "%s: failed to get semaphore\n", __func__); - return 0; + return rv; } - rv = wm_kmrn_readreg_locked(sc, reg); + rv = wm_kmrn_readreg_locked(sc, reg, val); if (sc->sc_type == WM_T_80003) wm_put_swfw_semaphore(sc, SWFW_MAC_CSR_SM); @@ -10535,9 +10586,8 @@ wm_kmrn_readreg(struct wm_softc *sc, int } static int -wm_kmrn_readreg_locked(struct wm_softc *sc, int reg) +wm_kmrn_readreg_locked(struct wm_softc *sc, int reg, uint16_t *val) { - int rv; CSR_WRITE(sc, WMREG_KUMCTRLSTA, ((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) | @@ -10545,9 +10595,9 @@ wm_kmrn_readreg_locked(struct wm_softc * CSR_WRITE_FLUSH(sc); delay(2); - rv = CSR_READ(sc, WMREG_KUMCTRLSTA) & KUMCTRLSTA_MASK; + *val = CSR_READ(sc, WMREG_KUMCTRLSTA) & KUMCTRLSTA_MASK; - return rv; + return 0; } /* @@ -10555,8 +10605,8 @@ wm_kmrn_readreg_locked(struct wm_softc * * * Write a kumeran register */ -static void -wm_kmrn_writereg(struct wm_softc *sc, int reg, int val) +static int +wm_kmrn_writereg(struct wm_softc *sc, int reg, uint16_t val) { int rv; @@ -10567,24 +10617,27 @@ wm_kmrn_writereg(struct wm_softc *sc, in if (rv != 0) { device_printf(sc->sc_dev, "%s: failed to get semaphore\n", __func__); - return; + return rv; } - wm_kmrn_writereg_locked(sc, reg, val); + rv = wm_kmrn_writereg_locked(sc, reg, val); if (sc->sc_type == WM_T_80003) wm_put_swfw_semaphore(sc, SWFW_MAC_CSR_SM); else sc->phy.release(sc); + + return rv; } -static void -wm_kmrn_writereg_locked(struct wm_softc *sc, int reg, int val) +static int +wm_kmrn_writereg_locked(struct wm_softc *sc, int reg, uint16_t val) { CSR_WRITE(sc, WMREG_KUMCTRLSTA, - ((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) | - (val & KUMCTRLSTA_MASK)); + ((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) | val); + + return 0; } /* SGMII related */ @@ -13829,15 +13882,17 @@ out: static void wm_gig_downshift_workaround_ich8lan(struct wm_softc *sc) { - uint16_t kmrn_reg; + uint16_t kmreg; /* Only for igp3 */ if (sc->sc_phytype == WMPHY_IGP_3) { - kmrn_reg = wm_kmrn_readreg(sc, KUMCTRLSTA_OFFSET_DIAG); - kmrn_reg |= KUMCTRLSTA_DIAG_NELPBK; - wm_kmrn_writereg(sc, KUMCTRLSTA_OFFSET_DIAG, kmrn_reg); - kmrn_reg &= ~KUMCTRLSTA_DIAG_NELPBK; - wm_kmrn_writereg(sc, KUMCTRLSTA_OFFSET_DIAG, kmrn_reg); + if (wm_kmrn_readreg(sc, KUMCTRLSTA_OFFSET_DIAG, &kmreg) != 0) + return; + kmreg |= KUMCTRLSTA_DIAG_NELPBK; + if (wm_kmrn_writereg(sc, KUMCTRLSTA_OFFSET_DIAG, kmreg) != 0) + return; + kmreg &= ~KUMCTRLSTA_DIAG_NELPBK; + wm_kmrn_writereg(sc, KUMCTRLSTA_OFFSET_DIAG, kmreg); } } @@ -13941,16 +13996,21 @@ static void wm_configure_k1_ich8lan(struct wm_softc *sc, int k1_enable) { uint32_t ctrl, ctrl_ext, tmp; - uint16_t kmrn_reg; + uint16_t kmreg; + int rv; - kmrn_reg = wm_kmrn_readreg_locked(sc, KUMCTRLSTA_OFFSET_K1_CONFIG); + rv = wm_kmrn_readreg_locked(sc, KUMCTRLSTA_OFFSET_K1_CONFIG, &kmreg); + if (rv != 0) + return; if (k1_enable) - kmrn_reg |= KUMCTRLSTA_K1_ENABLE; + kmreg |= KUMCTRLSTA_K1_ENABLE; else - kmrn_reg &= ~KUMCTRLSTA_K1_ENABLE; + kmreg &= ~KUMCTRLSTA_K1_ENABLE; - wm_kmrn_writereg_locked(sc, KUMCTRLSTA_OFFSET_K1_CONFIG, kmrn_reg); + rv = wm_kmrn_writereg_locked(sc, KUMCTRLSTA_OFFSET_K1_CONFIG, kmreg); + if (rv != 0) + return; delay(20); @@ -13969,6 +14029,8 @@ wm_configure_k1_ich8lan(struct wm_softc CSR_WRITE(sc, WMREG_CTRL_EXT, ctrl_ext); CSR_WRITE_FLUSH(sc); delay(20); + + return; } /* special case - for 82575 - need to do manual init ... */ Index: src/sys/dev/pci/if_wmreg.h diff -u src/sys/dev/pci/if_wmreg.h:1.102 src/sys/dev/pci/if_wmreg.h:1.103 --- src/sys/dev/pci/if_wmreg.h:1.102 Thu Jul 13 08:22:21 2017 +++ src/sys/dev/pci/if_wmreg.h Wed Jul 26 06:48:49 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmreg.h,v 1.102 2017/07/13 08:22:21 msaitoh Exp $ */ +/* $NetBSD: if_wmreg.h,v 1.103 2017/07/26 06:48:49 msaitoh Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -616,12 +616,12 @@ struct livengood_tcpip_ctxdesc { #define KUMCTRLSTA_OFFSET_M2P_MODES 0x0000001F /* FIFO Control */ -#define KUMCTRLSTA_FIFO_CTRL_RX_BYPASS 0x00000008 -#define KUMCTRLSTA_FIFO_CTRL_TX_BYPASS 0x00000800 +#define KUMCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008 +#define KUMCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800 /* In-Band Control */ -#define KUMCTRLSTA_INB_CTRL_LINK_TMOUT_DFLT 0x00000500 -#define KUMCTRLSTA_INB_CTRL_DIS_PADDING 0x00000010 +#define KUMCTRLSTA_INB_CTRL_LINK_TMOUT_DFLT 0x0500 +#define KUMCTRLSTA_INB_CTRL_DIS_PADDING 0x0010 /* Diag */ #define KUMCTRLSTA_DIAG_NELPBK 0x1000 @@ -630,8 +630,12 @@ struct livengood_tcpip_ctxdesc { #define KUMCTRLSTA_K1_ENABLE 0x0002 /* Half-Duplex Control */ -#define KUMCTRLSTA_HD_CTRL_10_100_DEFAULT 0x00000004 -#define KUMCTRLSTA_HD_CTRL_1000_DEFAULT 0x00000000 +#define KUMCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004 +#define KUMCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 + +/* M2P Modes */ +#define KUMCTRLSTA_OPMODE_MASK 0x000c +#define KUMCTRLSTA_OPMODE_INBAND_MDIO 0x0004 #define WMREG_VET 0x0038 /* VLAN Ethertype */ #define WMREG_MDPHYA 0x003C /* PHY address - RW */ Index: src/sys/dev/pci/if_wmvar.h diff -u src/sys/dev/pci/if_wmvar.h:1.35 src/sys/dev/pci/if_wmvar.h:1.36 --- src/sys/dev/pci/if_wmvar.h:1.35 Tue Jul 25 06:00:17 2017 +++ src/sys/dev/pci/if_wmvar.h Wed Jul 26 06:48:49 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmvar.h,v 1.35 2017/07/25 06:00:17 msaitoh Exp $ */ +/* $NetBSD: if_wmvar.h,v 1.36 2017/07/26 06:48:49 msaitoh Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -93,6 +93,7 @@ #define WM_F_WOL 0x00200000 #define WM_F_EEE 0x00400000 /* Energy Efficiency Ethernet */ #define WM_F_ATTACHED 0x00800000 /* attach() finished successfully */ +#define WM_F_80003_MDIC_WA 0x01000000 /* 80003 MDIC workaround */ #define WM_F_PCS_DIS_AUTONEGO 0x02000000 /* PCS Disable Autonego */ #define WM_F_PLL_WA_I210 0x04000000 /* I21[01] PLL workaround */