Module Name: src Committed By: martin Date: Sun Nov 9 12:03:18 UTC 2014
Modified Files: src/share/man/man4 [netbsd-6]: wm.4 src/sys/dev/pci [netbsd-6]: if_wm.c if_wmreg.h if_wmvar.h pcidevs Log Message: Pullup the following revisions, requested by msaitoh in ticket #1188: sys/dev/pci/pcidevs 1.1172 sys/dev/pci/if_wm.c 1.263-1.266 via patch sys/dev/pci/if_wmreg.h 1.55-1.56 sys/dev/pci/if_wmvar.h 1.17 share/man/man4/wm.4 1.26-1.27 and 1.29 via patch - Add I354 support. - Insert completion barrier between register write and delay(). - Fix the definition of CTRL_GIO_M_DIS. This bit is not bit 3 but bit 2. - Cleanup To generate a diff of this commit: cvs rdiff -u -r1.21.6.1 -r1.21.6.2 src/share/man/man4/wm.4 cvs rdiff -u -r1.227.2.11 -r1.227.2.12 src/sys/dev/pci/if_wm.c cvs rdiff -u -r1.46.2.5 -r1.46.2.6 src/sys/dev/pci/if_wmreg.h cvs rdiff -u -r1.12.10.3 -r1.12.10.4 src/sys/dev/pci/if_wmvar.h cvs rdiff -u -r1.1102.2.13 -r1.1102.2.14 src/sys/dev/pci/pcidevs Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/man/man4/wm.4 diff -u src/share/man/man4/wm.4:1.21.6.1 src/share/man/man4/wm.4:1.21.6.2 --- src/share/man/man4/wm.4:1.21.6.1 Thu Jun 28 16:06:36 2012 +++ src/share/man/man4/wm.4 Sun Nov 9 12:03:18 2014 @@ -1,4 +1,4 @@ -.\" $NetBSD: wm.4,v 1.21.6.1 2012/06/28 16:06:36 riz Exp $ +.\" $NetBSD: wm.4,v 1.21.6.2 2014/11/09 12:03:18 martin Exp $ .\" .\" Copyright 2002, 2003 Wasabi Systems, Inc. .\" All rights reserved. @@ -33,7 +33,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 20, 2012 +.Dd December 30, 2013 .Dt WM 4 .Os .Sh NAME @@ -141,6 +141,14 @@ Intel 82580 Ethernet (Copper, Fiber) Intel 82583 1000BASE-T Ethernet .It Intel I350 Ethernet (Copper, Fiber) +.It +Intel I354 (C2000 Internal) Ethernet (Copper, Fiber) +.It +Intel I210 Ethernet (Copper, Fiber) +.It +Intel I211 Ethernet +.It +Intel I217 and I218 Ethernet .El .Pp In addition to Intel's own Index: src/sys/dev/pci/if_wm.c diff -u src/sys/dev/pci/if_wm.c:1.227.2.11 src/sys/dev/pci/if_wm.c:1.227.2.12 --- src/sys/dev/pci/if_wm.c:1.227.2.11 Tue Jun 3 14:57:09 2014 +++ src/sys/dev/pci/if_wm.c Sun Nov 9 12:03:18 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.227.2.11 2014/06/03 14:57:09 msaitoh Exp $ */ +/* $NetBSD: if_wm.c,v 1.227.2.12 2014/11/09 12:03:18 martin Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -76,7 +76,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.227.2.11 2014/06/03 14:57:09 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.227.2.12 2014/11/09 12:03:18 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -543,11 +543,13 @@ static int wm_gmii_hv_readreg(device_t, static void wm_gmii_hv_writereg(device_t, int, int, int); static int wm_gmii_82580_readreg(device_t, int, int); static void wm_gmii_82580_writereg(device_t, int, int, int); +static bool wm_sgmii_uses_mdio(struct wm_softc *); static int wm_sgmii_readreg(device_t, int, int); static void wm_sgmii_writereg(device_t, int, int, int); static void wm_gmii_statchg(device_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 *); static void wm_gmii_mediastatus(struct ifnet *, struct ifmediareq *); @@ -1024,6 +1026,9 @@ static const struct wm_product { "I350 Gigabit Connection", WM_T_I350, WMP_F_1000T }, #endif + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C2000_SGMII, + "I354 Gigabit Connection", + WM_T_I354, WMP_F_1000T }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I210_T1, "I210-T1 Ethernet Server Adapter", WM_T_I210, WMP_F_1000T }, @@ -1210,8 +1215,8 @@ wm_attach(device_t parent, device_t self if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576) || (sc->sc_type == WM_T_82580) || (sc->sc_type == WM_T_82580ER) - || (sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I210) - || (sc->sc_type == WM_T_I211)) + || (sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I354) + || (sc->sc_type == WM_T_I210) || (sc->sc_type == WM_T_I211)) sc->sc_flags |= WM_F_NEWQUEUE; /* Set device properties (mactype) */ @@ -1326,7 +1331,7 @@ wm_attach(device_t parent, device_t self || (sc->sc_type == WM_T_82571) || (sc->sc_type == WM_T_80003) || (sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576) || (sc->sc_type == WM_T_82580) || (sc->sc_type == WM_T_82580ER) - || (sc->sc_type == WM_T_I350)) + || (sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I354)) sc->sc_funcid = (CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & STATUS_FUNCID_MASK; else @@ -1597,6 +1602,7 @@ wm_attach(device_t parent, device_t self case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: /* XXXX ok? */ case WM_T_80003: /* SPI */ wm_set_spiaddrbits(sc); @@ -1687,10 +1693,8 @@ wm_attach(device_t parent, device_t self case WM_T_PCH: case WM_T_PCH2: case WM_T_PCH_LPT: - if (wm_check_mng_mode(sc) != 0) { - printf ("get hw control (1)\n"); + if (wm_check_mng_mode(sc) != 0) wm_get_hw_control(sc); - } break; default: break; @@ -1773,6 +1777,7 @@ wm_attach(device_t parent, device_t self case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: /* XXX ok? */ case WM_T_ICH8: case WM_T_ICH9: case WM_T_ICH10: @@ -1899,20 +1904,30 @@ wm_attach(device_t parent, device_t self case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: case WM_T_I210: case WM_T_I211: reg = CSR_READ(sc, WMREG_CTRL_EXT); switch (reg & CTRL_EXT_LINK_MODE_MASK) { - case CTRL_EXT_LINK_MODE_SGMII: - aprint_verbose_dev(sc->sc_dev, "SGMII\n"); - sc->sc_flags |= WM_F_SGMII; + case CTRL_EXT_LINK_MODE_1000KX: + aprint_verbose_dev(sc->sc_dev, "1000KX\n"); CSR_WRITE(sc, WMREG_CTRL_EXT, reg | CTRL_EXT_I2C_ENA); - wm_gmii_mediainit(sc, wmp->wmp_product); + panic("not supported yet\n"); break; - case CTRL_EXT_LINK_MODE_1000KX: + case CTRL_EXT_LINK_MODE_SGMII: + if (wm_sgmii_uses_mdio(sc)) { + aprint_verbose_dev(sc->sc_dev, + "SGMII(MDIO)\n"); + sc->sc_flags |= WM_F_SGMII; + wm_gmii_mediainit(sc, + wmp->wmp_product); + break; + } + aprint_verbose_dev(sc->sc_dev, "SGMII(I2C)\n"); + /*FALLTHROUGH*/ case CTRL_EXT_LINK_MODE_PCIE_SERDES: - aprint_verbose_dev(sc->sc_dev, "1000KX or SERDES\n"); + aprint_verbose_dev(sc->sc_dev, "SERDES\n"); CSR_WRITE(sc, WMREG_CTRL_EXT, reg | CTRL_EXT_I2C_ENA); panic("not supported yet\n"); @@ -1965,6 +1980,7 @@ wm_attach(device_t parent, device_t self case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: /* XXXX ok? */ case WM_T_I210: case WM_T_I211: case WM_T_80003: @@ -3708,7 +3724,8 @@ wm_rxintr(struct wm_softc *sc) * For an eratta, the RCTL_SECRC bit in RCTL register * is always set in I350, so we don't trim it. */ - if ((sc->sc_type != WM_T_I350) && (sc->sc_type != WM_T_I210) + if ((sc->sc_type != WM_T_I350) && (sc->sc_type != WM_T_I354) + && (sc->sc_type != WM_T_I210) && (sc->sc_type != WM_T_I211)) { if (m->m_len < ETHER_CRC_LEN) { sc->sc_rxtail->m_len @@ -3759,6 +3776,7 @@ wm_rxintr(struct wm_softc *sc) * If VLANs are enabled, VLAN packets have been unwrapped * for us. Associate the tag with the packet. */ + /* XXXX should check for i350 and i354 */ if ((status & WRX_ST_VP) != 0) { VLAN_INPUT_TAG(ifp, m, le16toh(vlantag), @@ -4041,6 +4059,7 @@ wm_reset(struct wm_softc *sc) case WM_T_82572: case WM_T_82575: /* XXX need special handing for jumbo frames */ case WM_T_I350: + case WM_T_I354: case WM_T_80003: sc->sc_pba = PBA_32K; break; @@ -4099,7 +4118,7 @@ wm_reset(struct wm_softc *sc) /* Set the completion timeout for interface */ if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576) - || (sc->sc_type == WM_T_I350)) + || (sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I354)) wm_set_pcie_completion_timeout(sc); /* Clear interrupt */ @@ -4107,8 +4126,9 @@ wm_reset(struct wm_softc *sc) /* Stop the transmit and receive processes. */ CSR_WRITE(sc, WMREG_RCTL, 0); - CSR_WRITE(sc, WMREG_TCTL, TCTL_PSP); sc->sc_rctl &= ~RCTL_EN; + CSR_WRITE(sc, WMREG_TCTL, TCTL_PSP); + CSR_WRITE_FLUSH(sc); /* XXX set_tbi_sbp_82543() */ @@ -4133,6 +4153,7 @@ wm_reset(struct wm_softc *sc) if ((sc->sc_type == WM_T_82541) || (sc->sc_type == WM_T_82547)) { CSR_WRITE(sc, WMREG_CTRL, CSR_READ(sc, WMREG_CTRL) | CTRL_PHY_RESET); + CSR_WRITE_FLUSH(sc); delay(5000); } @@ -4193,6 +4214,7 @@ wm_reset(struct wm_softc *sc) } wm_get_swfwhw_semaphore(sc); CSR_WRITE(sc, WMREG_CTRL, reg); + /* Don't insert a completion barrier when reset */ delay(20*1000); wm_put_swfwhw_semaphore(sc); break; @@ -4212,6 +4234,7 @@ wm_reset(struct wm_softc *sc) case WM_T_82580ER: case WM_T_82583: case WM_T_I350: + case WM_T_I354: case WM_T_I210: case WM_T_I211: default: @@ -4242,6 +4265,7 @@ wm_reset(struct wm_softc *sc) delay(10); reg = CSR_READ(sc, WMREG_CTRL_EXT) | CTRL_EXT_EE_RST; CSR_WRITE(sc, WMREG_CTRL_EXT, reg); + CSR_WRITE_FLUSH(sc); delay(2000); break; case WM_T_82540: @@ -4268,6 +4292,7 @@ wm_reset(struct wm_softc *sc) delay(10); reg = CSR_READ(sc, WMREG_CTRL_EXT) | CTRL_EXT_EE_RST; CSR_WRITE(sc, WMREG_CTRL_EXT, reg); + CSR_WRITE_FLUSH(sc); } /* check EECD_EE_AUTORD */ wm_get_auto_rd_done(sc); @@ -4284,6 +4309,7 @@ wm_reset(struct wm_softc *sc) case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: case WM_T_I210: case WM_T_I211: case WM_T_80003: @@ -4310,6 +4336,7 @@ wm_reset(struct wm_softc *sc) case WM_T_82580ER: #endif case WM_T_I350: + case WM_T_I354: case WM_T_ICH8: case WM_T_ICH9: if ((CSR_READ(sc, WMREG_EECD) & EECD_EE_PRES) == 0) { @@ -4319,7 +4346,8 @@ wm_reset(struct wm_softc *sc) || (sc->sc_type == WM_T_82576) || (sc->sc_type == WM_T_82580) || (sc->sc_type == WM_T_82580ER) - || (sc->sc_type == WM_T_I350)) + || (sc->sc_type == WM_T_I350) + || (sc->sc_type == WM_T_I354)) wm_reset_init_script_82575(sc); } break; @@ -4328,7 +4356,7 @@ wm_reset(struct wm_softc *sc) } if ((sc->sc_type == WM_T_82580) || (sc->sc_type == WM_T_82580ER) - || (sc->sc_type == WM_T_I350)) { + || (sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I354)) { /* clear global device reset status bit */ CSR_WRITE(sc, WMREG_STATUS, STATUS_DEV_RST_SET); } @@ -4564,7 +4592,7 @@ wm_init(struct ifnet *ifp) * Clear out the VLAN table -- we don't use it (yet). */ CSR_WRITE(sc, WMREG_VET, 0); - if (sc->sc_type == WM_T_I350) + if ((sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I354)) trynum = 10; /* Due to hw errata */ else trynum = 1; @@ -4763,7 +4791,8 @@ wm_init(struct ifnet *ifp) * The I350 has a bug where it always strips the CRC whether * asked to or not. So ask for stripped CRC here and cope in rxeof */ - if ((sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I210)) + if ((sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I354) + || (sc->sc_type == WM_T_I210)) sc->sc_rctl |= RCTL_SECRC; if (((sc->sc_ethercom.ec_capabilities & ETHERCAP_JUMBO_MTU) != 0) @@ -4942,6 +4971,7 @@ wm_get_auto_rd_done(struct wm_softc *sc) case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: case WM_T_I210: case WM_T_I211: case WM_T_80003: @@ -5033,6 +5063,7 @@ wm_get_cfg_done(struct wm_softc *sc) case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: case WM_T_I210: case WM_T_I211: if (sc->sc_type == WM_T_82571) { @@ -5183,10 +5214,13 @@ wm_eeprom_sendbits(struct wm_softc *sc, else reg &= ~EECD_DI; CSR_WRITE(sc, WMREG_EECD, reg); + CSR_WRITE_FLUSH(sc); delay(2); CSR_WRITE(sc, WMREG_EECD, reg | EECD_SK); + CSR_WRITE_FLUSH(sc); delay(2); CSR_WRITE(sc, WMREG_EECD, reg); + CSR_WRITE_FLUSH(sc); delay(2); } } @@ -5207,10 +5241,12 @@ wm_eeprom_recvbits(struct wm_softc *sc, val = 0; for (x = nbits; x > 0; x--) { CSR_WRITE(sc, WMREG_EECD, reg | EECD_SK); + CSR_WRITE_FLUSH(sc); delay(2); if (CSR_READ(sc, WMREG_EECD) & EECD_DO) val |= (1U << (x - 1)); CSR_WRITE(sc, WMREG_EECD, reg); + CSR_WRITE_FLUSH(sc); delay(2); } *valp = val; @@ -5244,6 +5280,7 @@ wm_read_eeprom_uwire(struct wm_softc *sc CSR_WRITE(sc, WMREG_EECD, reg); reg &= ~EECD_SK; CSR_WRITE(sc, WMREG_EECD, reg); + CSR_WRITE_FLUSH(sc); delay(2); } /* XXX: end of workaround */ @@ -5251,6 +5288,7 @@ wm_read_eeprom_uwire(struct wm_softc *sc /* Set CHIP SELECT. */ reg |= EECD_CS; CSR_WRITE(sc, WMREG_EECD, reg); + CSR_WRITE_FLUSH(sc); delay(2); /* Shift in the READ command. */ @@ -5266,6 +5304,7 @@ wm_read_eeprom_uwire(struct wm_softc *sc /* Clear CHIP SELECT. */ reg = CSR_READ(sc, WMREG_EECD) & ~EECD_CS; CSR_WRITE(sc, WMREG_EECD, reg); + CSR_WRITE_FLUSH(sc); delay(2); } @@ -5311,6 +5350,7 @@ wm_read_eeprom_spi(struct wm_softc *sc, /* Clear SK and CS. */ reg = CSR_READ(sc, WMREG_EECD) & ~(EECD_SK | EECD_CS); CSR_WRITE(sc, WMREG_EECD, reg); + CSR_WRITE_FLUSH(sc); delay(2); if (wm_spi_eeprom_ready(sc)) @@ -5318,8 +5358,10 @@ wm_read_eeprom_spi(struct wm_softc *sc, /* Toggle CS to flush commands. */ CSR_WRITE(sc, WMREG_EECD, reg | EECD_CS); + CSR_WRITE_FLUSH(sc); delay(2); CSR_WRITE(sc, WMREG_EECD, reg); + CSR_WRITE_FLUSH(sc); delay(2); opc = SPI_OPC_READ; @@ -5337,6 +5379,7 @@ wm_read_eeprom_spi(struct wm_softc *sc, /* Raise CS and clear SK. */ reg = (CSR_READ(sc, WMREG_EECD) & ~EECD_SK) | EECD_CS; CSR_WRITE(sc, WMREG_EECD, reg); + CSR_WRITE_FLUSH(sc); delay(2); return 0; @@ -5357,9 +5400,11 @@ wm_read_eeprom_spi(struct wm_softc *sc, static int wm_validate_eeprom_checksum(struct wm_softc *sc) { - uint16_t checksum, valid_checksum; + uint16_t checksum; uint16_t eeprom_data; - uint16_t csum_wordaddr; +#ifdef WM_DEBUG + uint16_t csum_wordaddr, valid_checksum; +#endif int i; checksum = 0; @@ -5368,6 +5413,7 @@ wm_validate_eeprom_checksum(struct wm_so if (sc->sc_type == WM_T_I211) return 0; +#ifdef WM_DEBUG if (sc->sc_type == WM_T_PCH_LPT) { csum_wordaddr = NVM_COMPAT; valid_checksum = NVM_COMPAT_VALID_CHECKSUM; @@ -5376,7 +5422,6 @@ wm_validate_eeprom_checksum(struct wm_so valid_checksum = NVM_FUTURE_INIT_WORD1_VALID_CHECKSUM; } -#ifdef WM_DEBUG /* Dump EEPROM image for debug */ if ((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9) || (sc->sc_type == WM_T_ICH10) || (sc->sc_type == WM_T_PCH) @@ -5532,6 +5577,7 @@ wm_read_mac_addr(struct wm_softc *sc, ui case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: switch (sc->sc_funcid) { case 0: /* default value (== EEPROM_OFF_MACADDR) */ @@ -5773,7 +5819,7 @@ wm_set_filter(struct wm_softc *sc) size = WM_RAL_TABSIZE_82575; else if ((sc->sc_type == WM_T_82576) || (sc->sc_type == WM_T_82580)) size = WM_RAL_TABSIZE_82576; - else if (sc->sc_type == WM_T_I350) + else if ((sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I354)) size = WM_RAL_TABSIZE_I350; else size = WM_RAL_TABSIZE; @@ -5955,12 +6001,14 @@ wm_tbi_mediachange(struct ifnet *ifp) sc->sc_ctrl |= CTRL_SLU | CTRL_FD; sc->sc_ctrl &= ~(CTRL_TFCE | CTRL_RFCE); CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + CSR_WRITE_FLUSH(sc); delay(1000); } DPRINTF(WM_DEBUG_LINK,("%s: sc_txcw = 0x%x after autoneg check\n", device_xname(sc->sc_dev),sc->sc_txcw)); CSR_WRITE(sc, WMREG_TXCW, sc->sc_txcw); + CSR_WRITE_FLUSH(sc); delay(10000); i = CSR_READ(sc, WMREG_CTRL) & CTRL_SWDPIN(1); @@ -5979,9 +6027,11 @@ wm_tbi_mediachange(struct ifnet *ifp) */ sc->sc_ctrl |= CTRL_LRST; CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + CSR_WRITE_FLUSH(sc); delay(1000); sc->sc_ctrl &= ~CTRL_LRST; CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + CSR_WRITE_FLUSH(sc); delay(1000); } @@ -6075,12 +6125,13 @@ wm_tbi_check_link(struct wm_softc *sc) { struct ifnet *ifp = &sc->sc_ethercom.ec_if; struct ifmedia_entry *ife = sc->sc_mii.mii_media.ifm_cur; - uint32_t rxcw, ctrl, status; + uint32_t status; status = CSR_READ(sc, WMREG_STATUS); - rxcw = CSR_READ(sc, WMREG_RXCW); - ctrl = CSR_READ(sc, WMREG_CTRL); + /* XXX is this needed? */ + (void)CSR_READ(sc, WMREG_RXCW); + (void)CSR_READ(sc, WMREG_CTRL); /* set link status */ if ((status & STATUS_LU) == 0) { @@ -6114,9 +6165,11 @@ wm_tbi_check_link(struct wm_softc *sc) */ sc->sc_ctrl |= CTRL_LRST; CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + CSR_WRITE_FLUSH(sc); delay(1000); sc->sc_ctrl &= ~CTRL_LRST; CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + CSR_WRITE_FLUSH(sc); delay(1000); CSR_WRITE(sc, WMREG_TXCW, sc->sc_txcw & ~TXCW_ANE); @@ -6154,6 +6207,7 @@ wm_gmii_reset(struct wm_softc *sc) case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: case WM_T_I210: case WM_T_I211: case WM_T_80003: @@ -6200,9 +6254,11 @@ wm_gmii_reset(struct wm_softc *sc) reg |= CTRL_EXT_SWDPIO(4); CSR_WRITE(sc, WMREG_CTRL_EXT, reg); + CSR_WRITE_FLUSH(sc); delay(10*1000); CSR_WRITE(sc, WMREG_CTRL_EXT, reg | CTRL_EXT_SWDPIN(4)); + CSR_WRITE_FLUSH(sc); delay(150); #if 0 sc->sc_ctrl_ext = reg | CTRL_EXT_SWDPIN(4); @@ -6228,14 +6284,17 @@ wm_gmii_reset(struct wm_softc *sc) case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: case WM_T_I210: case WM_T_I211: case WM_T_82583: case WM_T_80003: /* generic reset */ CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_PHY_RESET); + CSR_WRITE_FLUSH(sc); delay(20000); CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + CSR_WRITE_FLUSH(sc); delay(20000); if ((sc->sc_type == WM_T_82541) @@ -6254,8 +6313,10 @@ wm_gmii_reset(struct wm_softc *sc) case WM_T_PCH_LPT: /* generic reset */ CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_PHY_RESET); + CSR_WRITE_FLUSH(sc); delay(100); CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + CSR_WRITE_FLUSH(sc); delay(150); break; default: @@ -6279,6 +6340,7 @@ wm_gmii_reset(struct wm_softc *sc) case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: case WM_T_I210: case WM_T_I211: case WM_T_80003: @@ -6323,6 +6385,7 @@ wm_gmii_reset(struct wm_softc *sc) case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: case WM_T_I210: case WM_T_I211: case WM_T_82583: @@ -6381,6 +6444,45 @@ wm_gmii_reset(struct wm_softc *sc) } /* + * wm_get_phy_id_82575: + * + * Return PHY ID. Return -1 if it failed. + */ +static int +wm_get_phy_id_82575(struct wm_softc *sc) +{ + uint32_t reg; + int phyid = -1; + + /* XXX */ + if ((sc->sc_flags & WM_F_SGMII) == 0) + return -1; + + if (wm_sgmii_uses_mdio(sc)) { + switch (sc->sc_type) { + case WM_T_82575: + case WM_T_82576: + reg = CSR_READ(sc, WMREG_MDIC); + phyid = (reg & MDIC_PHY_MASK) >> MDIC_PHY_SHIFT; + break; + case WM_T_82580: + case WM_T_I350: + case WM_T_I354: + case WM_T_I210: + case WM_T_I211: + reg = CSR_READ(sc, WMREG_MDICNFG); + phyid = (reg & MDICNFG_PHY_MASK) >> MDICNFG_PHY_SHIFT; + break; + default: + return -1; + } + } + + return phyid; +} + + +/* * wm_gmii_mediainit: * * Initialize media for use on 1000BASE-T devices. @@ -6466,7 +6568,8 @@ wm_gmii_mediainit(struct wm_softc *sc, p mii->mii_writereg = wm_gmii_bm_writereg; break; default: - if ((sc->sc_flags & WM_F_SGMII) != 0) { + if (((sc->sc_flags & WM_F_SGMII) != 0) + && !wm_sgmii_uses_mdio(sc)){ mii->mii_readreg = wm_sgmii_readreg; mii->mii_writereg = wm_sgmii_writereg; } else if (sc->sc_type >= WM_T_80003) { @@ -6498,30 +6601,39 @@ wm_gmii_mediainit(struct wm_softc *sc, p if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576) || (sc->sc_type == WM_T_82580) || (sc->sc_type == WM_T_82580ER) - || (sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I210) - || (sc->sc_type == WM_T_I211)) { + || (sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I354) + || (sc->sc_type == WM_T_I210) || (sc->sc_type == WM_T_I211)) { if ((sc->sc_flags & WM_F_SGMII) == 0) { /* Attach only one port */ mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, 1, MII_OFFSET_ANY, MIIF_DOPAUSE); } else { - int i; + int i, id; uint32_t ctrl_ext; - /* Power on sgmii phy if it is disabled */ - ctrl_ext = CSR_READ(sc, WMREG_CTRL_EXT); - CSR_WRITE(sc, WMREG_CTRL_EXT, - ctrl_ext &~ CTRL_EXT_SWDPIN(3)); - CSR_WRITE_FLUSH(sc); - delay(300*1000); /* XXX too long */ - - /* from 1 to 8 */ - for (i = 1; i < 8; i++) + id = wm_get_phy_id_82575(sc); + if (id != -1) { mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, - i, MII_OFFSET_ANY, MIIF_DOPAUSE); + id, MII_OFFSET_ANY, MIIF_DOPAUSE); + } + if ((id == -1) + || (LIST_FIRST(&mii->mii_phys) == NULL)) { + /* Power on sgmii phy if it is disabled */ + ctrl_ext = CSR_READ(sc, WMREG_CTRL_EXT); + CSR_WRITE(sc, WMREG_CTRL_EXT, + ctrl_ext &~ CTRL_EXT_SWDPIN(3)); + CSR_WRITE_FLUSH(sc); + delay(300*1000); /* XXX too long */ + + /* from 1 to 8 */ + for (i = 1; i < 8; i++) + mii_attach(sc->sc_dev, &sc->sc_mii, + 0xffffffff, i, MII_OFFSET_ANY, + MIIF_DOPAUSE); - /* restore previous sfp cage power state */ - CSR_WRITE(sc, WMREG_CTRL_EXT, ctrl_ext); + /* restore previous sfp cage power state */ + CSR_WRITE(sc, WMREG_CTRL_EXT, ctrl_ext); + } } } else { mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, @@ -6661,10 +6773,13 @@ i82543_mii_sendbits(struct wm_softc *sc, else v &= ~MDI_IO; CSR_WRITE(sc, WMREG_CTRL, v); + CSR_WRITE_FLUSH(sc); delay(10); CSR_WRITE(sc, WMREG_CTRL, v | MDI_CLK); + CSR_WRITE_FLUSH(sc); delay(10); CSR_WRITE(sc, WMREG_CTRL, v); + CSR_WRITE_FLUSH(sc); delay(10); } } @@ -6679,25 +6794,32 @@ i82543_mii_recvbits(struct wm_softc *sc) v |= CTRL_SWDPIO(3); CSR_WRITE(sc, WMREG_CTRL, v); + CSR_WRITE_FLUSH(sc); delay(10); CSR_WRITE(sc, WMREG_CTRL, v | MDI_CLK); + CSR_WRITE_FLUSH(sc); delay(10); CSR_WRITE(sc, WMREG_CTRL, v); + CSR_WRITE_FLUSH(sc); delay(10); for (i = 0; i < 16; i++) { data <<= 1; CSR_WRITE(sc, WMREG_CTRL, v | MDI_CLK); + CSR_WRITE_FLUSH(sc); delay(10); if (CSR_READ(sc, WMREG_CTRL) & MDI_IO) data |= 1; CSR_WRITE(sc, WMREG_CTRL, v); + CSR_WRITE_FLUSH(sc); delay(10); } CSR_WRITE(sc, WMREG_CTRL, v | MDI_CLK); + CSR_WRITE_FLUSH(sc); delay(10); CSR_WRITE(sc, WMREG_CTRL, v); + CSR_WRITE_FLUSH(sc); delay(10); return data; @@ -7113,6 +7235,40 @@ wm_gmii_hv_writereg(device_t self, int p } /* + * wm_sgmii_uses_mdio + * + * Check whether the transaction is to the internal PHY or the external + * MDIO interface. Return true if it's MDIO. + */ +static bool +wm_sgmii_uses_mdio(struct wm_softc *sc) +{ + uint32_t reg; + bool ismdio = false; + + switch (sc->sc_type) { + case WM_T_82575: + case WM_T_82576: + reg = CSR_READ(sc, WMREG_MDIC); + ismdio = ((reg & MDIC_DEST) != 0); + break; + case WM_T_82580: + case WM_T_82580ER: + case WM_T_I350: + case WM_T_I354: + case WM_T_I210: + case WM_T_I211: + reg = CSR_READ(sc, WMREG_MDICNFG); + ismdio = ((reg & MDICNFG_DEST) != 0); + break; + default: + break; + } + + return ismdio; +} + +/* * wm_sgmii_readreg: [mii interface function] * * Read a PHY register on the SGMII @@ -7338,6 +7494,7 @@ wm_kmrn_readreg(struct wm_softc *sc, int CSR_WRITE(sc, WMREG_KUMCTRLSTA, ((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) | KUMCTRLSTA_REN); + CSR_WRITE_FLUSH(sc); delay(2); rv = CSR_READ(sc, WMREG_KUMCTRLSTA) & KUMCTRLSTA_MASK; @@ -8359,10 +8516,12 @@ wm_configure_k1_ich8lan(struct wm_softc CSR_WRITE(sc, WMREG_CTRL, tmp); CSR_WRITE(sc, WMREG_CTRL_EXT, ctrl_ext | CTRL_EXT_SPD_BYPS); + CSR_WRITE_FLUSH(sc); delay(20); CSR_WRITE(sc, WMREG_CTRL, ctrl); CSR_WRITE(sc, WMREG_CTRL_EXT, ctrl_ext); + CSR_WRITE_FLUSH(sc); delay(20); } @@ -8377,9 +8536,11 @@ wm_smbustopci(struct wm_softc *sc) sc->sc_ctrl |= CTRL_LANPHYPC_OVERRIDE; sc->sc_ctrl &= ~CTRL_LANPHYPC_VALUE; CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + CSR_WRITE_FLUSH(sc); delay(10); sc->sc_ctrl &= ~CTRL_LANPHYPC_OVERRIDE; CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + CSR_WRITE_FLUSH(sc); delay(50*1000); /* @@ -8511,6 +8672,7 @@ wm_get_wakeup(struct wm_softc *sc) case WM_T_82580: case WM_T_82580ER: case WM_T_I350: + case WM_T_I354: if ((CSR_READ(sc, WMREG_FWSM) & FWSM_MODE_MASK) != 0) sc->sc_flags |= WM_F_ARC_SUBSYS_VALID; sc->sc_flags |= WM_F_ASF_FIRMWARE_PRES; Index: src/sys/dev/pci/if_wmreg.h diff -u src/sys/dev/pci/if_wmreg.h:1.46.2.5 src/sys/dev/pci/if_wmreg.h:1.46.2.6 --- src/sys/dev/pci/if_wmreg.h:1.46.2.5 Mon Jul 29 20:24:04 2013 +++ src/sys/dev/pci/if_wmreg.h Sun Nov 9 12:03:18 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmreg.h,v 1.46.2.5 2013/07/29 20:24:04 jdc Exp $ */ +/* $NetBSD: if_wmreg.h,v 1.46.2.6 2014/11/09 12:03:18 martin Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -209,8 +209,8 @@ struct livengood_tcpip_ctxdesc { #define CTRL_FD (1U << 0) /* full duplex */ #define CTRL_BEM (1U << 1) /* big-endian mode */ #define CTRL_PRIOR (1U << 2) /* 0 = receive, 1 = fair */ +#define CTRL_GIO_M_DIS (1U << 2) /* disabl PCI master access */ #define CTRL_LRST (1U << 3) /* link reset */ -#define CTRL_GIO_M_DIS (1U << 3) /* disabl PCI master access */ #define CTRL_ASDE (1U << 5) /* auto speed detect enable */ #define CTRL_SLU (1U << 6) /* set link up */ #define CTRL_ILOS (1U << 7) /* invert loss of signal */ @@ -417,12 +417,15 @@ struct livengood_tcpip_ctxdesc { #define WMREG_MDIC 0x0020 /* MDI Control Register */ #define MDIC_DATA(x) ((x) & 0xffff) #define MDIC_REGADD(x) ((x) << 16) +#define MDIC_PHY_SHIFT 21 +#define MDIC_PHY_MASK __BITS(25, 21) #define MDIC_PHYADD(x) ((x) << 21) #define MDIC_OP_WRITE (1U << 26) #define MDIC_OP_READ (2U << 26) #define MDIC_READY (1U << 28) #define MDIC_I (1U << 29) /* interrupt on MDI complete */ #define MDIC_E (1U << 30) /* MDI error */ +#define MDIC_DEST (1U << 31) /* Destination */ #define WMREG_SCTL 0x0024 /* SerDes Control - RW */ /* @@ -705,6 +708,12 @@ struct livengood_tcpip_ctxdesc { #define WMREG_VFTA 0x0600 +#define WMREG_MDICNFG 0x0e04 /* MDC/MDIO Configuration Register */ +#define MDICNFG_PHY_SHIFT 21 +#define MDICNFG_PHY_MASK __BITS(25, 21) +#define MDICNFG_COM_MDIO __BIT(30) +#define MDICNFG_DEST __BIT(31) + #define WM_MC_TABSIZE 128 #define WM_ICH8_MC_TABSIZE 32 #define WM_VLAN_TABSIZE 128 Index: src/sys/dev/pci/if_wmvar.h diff -u src/sys/dev/pci/if_wmvar.h:1.12.10.3 src/sys/dev/pci/if_wmvar.h:1.12.10.4 --- src/sys/dev/pci/if_wmvar.h:1.12.10.3 Sun Jul 14 20:39:13 2013 +++ src/sys/dev/pci/if_wmvar.h Sun Nov 9 12:03:18 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmvar.h,v 1.12.10.3 2013/07/14 20:39:13 riz Exp $ */ +/* $NetBSD: if_wmvar.h,v 1.12.10.4 2014/11/09 12:03:18 martin Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -121,6 +121,7 @@ typedef enum { WM_T_82580, /* i82580 */ WM_T_82580ER, /* i82580ER */ WM_T_I350, /* I350 */ + WM_T_I354, /* I354 */ WM_T_I210, /* I210 */ WM_T_I211, /* I211 */ WM_T_80003, /* i80003 */ Index: src/sys/dev/pci/pcidevs diff -u src/sys/dev/pci/pcidevs:1.1102.2.13 src/sys/dev/pci/pcidevs:1.1102.2.14 --- src/sys/dev/pci/pcidevs:1.1102.2.13 Sat Sep 7 16:39:32 2013 +++ src/sys/dev/pci/pcidevs Sun Nov 9 12:03:18 2014 @@ -1,4 +1,4 @@ -$NetBSD: pcidevs,v 1.1102.2.13 2013/09/07 16:39:32 bouyer Exp $ +$NetBSD: pcidevs,v 1.1102.2.14 2014/11/09 12:03:18 martin Exp $ /* * Copyright (c) 1995, 1996 Christopher G. Demetriou @@ -2803,6 +2803,43 @@ product INTEL MOBILE_HM76_LPC 0x1e59 Mob product INTEL MOBILE_HM75_LPC 0x1e5d Mobile HM75 LPC product INTEL MOBILE_HM70_LPC 0x1e5e Mobile HM70 LPC product INTEL NM70_LPC 0x1e5f NM70 LPC +product INTEL C2000_TROUTER_0 0x1f00 C2000 Transaction Router +product INTEL C2000_TROUTER_1 0x1f01 C2000 Transaction Router +product INTEL C2000_TROUTER_2 0x1f02 C2000 Transaction Router +product INTEL C2000_TROUTER_3 0x1f03 C2000 Transaction Router +product INTEL C2000_TROUTER_4 0x1f04 C2000 Transaction Router +product INTEL C2000_TROUTER_5 0x1f05 C2000 Transaction Router +product INTEL C2000_TROUTER_6 0x1f06 C2000 Transaction Router +product INTEL C2000_TROUTER_7 0x1f07 C2000 Transaction Router +product INTEL C2000_TROUTER_8 0x1f08 C2000 Transaction Router +product INTEL C2000_TROUTER_9 0x1f09 C2000 Transaction Router +product INTEL C2000_TROUTER_A 0x1f0a C2000 Transaction Router +product INTEL C2000_TROUTER_B 0x1f0b C2000 Transaction Router +product INTEL C2000_TROUTER_C 0x1f0c C2000 Transaction Router +product INTEL C2000_TROUTER_D 0x1f0d C2000 Transaction Router +product INTEL C2000_TROUTER_E 0x1f0e C2000 Transaction Router +product INTEL C2000_TROUTER_F 0x1f0f C2000 Transaction Router +product INTEL C2000_PCIE_1 0x1f10 C2000 PCIe Root Port +product INTEL C2000_PCIE_2 0x1f11 C2000 PCIe Root Port +product INTEL C2000_PCIE_3 0x1f12 C2000 PCIe Root Port +product INTEL C2000_PCIE_4 0x1f13 C2000 PCIe Root Port +product INTEL C2000_RAS 0x1f14 C2000 RAS +product INTEL C2000_SMBUS 0x1f15 C2000 SMBus 2.0 +product INTEL C2000_RCEC 0x1f16 C2000 RCEC +product INTEL C2000_IQIA_PHYS 0x1f18 C2000 IQIA Physical Function +product INTEL C2000_IQIA 0x1f19 C2000 IQIA +product INTEL C2000_SATA2 0x1f22 C2000 SATA2 +product INTEL C2000_USB 0x1f2c C2000 USB 2.0 +product INTEL C2000_SATA3 0x1f32 C2000 SATA3 +product INTEL C2000_PCU_1 0x1f38 C2000 PCU +product INTEL C2000_PCU_2 0x1f39 C2000 PCU +product INTEL C2000_PCU_3 0x1f3a C2000 PCU +product INTEL C2000_PCU_4 0x1f3b C2000 PCU +product INTEL C2000_PCU_SMBUS 0x1f3c C2000 PCU SMBus +product INTEL C2000_1000KX 0x1f40 C2000 Ethernet(1000BASE-KX) +product INTEL C2000_SGMII 0x1f41 C2000 Ethernet(SGMII) +product INTEL C2000_DUMMYGBE 0x1f42 C2000 Ethernet(Dummy function) +product INTEL C2000_25GBE 0x1f45 C2000 Ethernet(2.5Gbe) product INTEL 82801AA_LPC 0x2410 82801AA LPC Interface Bridge product INTEL 82801AA_IDE 0x2411 82801AA IDE Controller product INTEL 82801AA_USB 0x2412 82801AA USB Controller