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