Module Name:    src
Committed By:   msaitoh
Date:           Tue Dec 13 10:01:44 UTC 2016

Modified Files:
        src/sys/dev/pci: if_wm.c if_wmreg.h

Log Message:
- Change to use 2500Base-KX correctly on C2000(I354). It worked, but the
output of ifconfig and if_baudrate was not good. Tested by nils@:
  - The STATUS_TBIMODE bit in the STATUS register is deleted since 82575,
    so check for 82575 and newer first and then check for old devices.
  - Check the 2P5_SKU and 2P5_SKU_OVER bit for KX.
  - Set IFM_2500_SX instead of IFM_1000_SX for 2.5G.
- Check SERDES's speed directly from the PCS layer (PCS_LSTS register) for old
  devices.
- Style fix.


To generate a diff of this commit:
cvs rdiff -u -r1.456 -r1.457 src/sys/dev/pci/if_wm.c
cvs rdiff -u -r1.93 -r1.94 src/sys/dev/pci/if_wmreg.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.456 src/sys/dev/pci/if_wm.c:1.457
--- src/sys/dev/pci/if_wm.c:1.456	Thu Dec  8 01:12:01 2016
+++ src/sys/dev/pci/if_wm.c	Tue Dec 13 10:01:44 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wm.c,v 1.456 2016/12/08 01:12:01 ozaki-r Exp $	*/
+/*	$NetBSD: if_wm.c,v 1.457 2016/12/13 10:01:44 msaitoh 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.456 2016/12/08 01:12:01 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.457 2016/12/13 10:01:44 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -2411,100 +2411,91 @@ alloc_retry:
 	    || sc->sc_type == WM_T_82574 || sc->sc_type == WM_T_82583) {
 		/* STATUS_TBIMODE reserved/reused, can't rely on it */
 		wm_gmii_mediainit(sc, wmp->wmp_product);
-	} else if (sc->sc_type < WM_T_82543 ||
-	    (CSR_READ(sc, WMREG_STATUS) & STATUS_TBIMODE) != 0) {
-		if (sc->sc_mediatype == WM_MEDIATYPE_COPPER) {
-			aprint_error_dev(sc->sc_dev,
-			    "WARNING: TBIMODE set on 1000BASE-T product!\n");
-			sc->sc_mediatype = WM_MEDIATYPE_FIBER;
-		}
-		wm_tbi_mediainit(sc);
-	} else {
-		switch (sc->sc_type) {
-		case WM_T_82575:
-		case WM_T_82576:
-		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_CTRL_EXT);
-			link_mode = reg & CTRL_EXT_LINK_MODE_MASK;
-			switch (link_mode) {
-			case CTRL_EXT_LINK_MODE_1000KX:
-				aprint_verbose_dev(sc->sc_dev, "1000KX\n");
-				sc->sc_mediatype = WM_MEDIATYPE_SERDES;
+	} else if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576)
+	    || (sc->sc_type ==WM_T_82580) || (sc->sc_type ==WM_T_I350)
+	    || (sc->sc_type ==WM_T_I354) || (sc->sc_type ==WM_T_I210)
+	    || (sc->sc_type ==WM_T_I211)) {
+		reg = CSR_READ(sc, WMREG_CTRL_EXT);
+		link_mode = reg & CTRL_EXT_LINK_MODE_MASK;
+		switch (link_mode) {
+		case CTRL_EXT_LINK_MODE_1000KX:
+			aprint_verbose_dev(sc->sc_dev, "1000KX\n");
+			sc->sc_mediatype = WM_MEDIATYPE_SERDES;
+			break;
+		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;
+				sc->sc_mediatype = WM_MEDIATYPE_COPPER;
 				break;
-			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;
+			}
+			aprint_verbose_dev(sc->sc_dev, "SGMII(I2C)\n");
+			/*FALLTHROUGH*/
+		case CTRL_EXT_LINK_MODE_PCIE_SERDES:
+			sc->sc_mediatype = wm_sfp_get_media_type(sc);
+			if (sc->sc_mediatype == WM_MEDIATYPE_UNKNOWN) {
+				if (link_mode
+				    == CTRL_EXT_LINK_MODE_SGMII) {
 					sc->sc_mediatype = WM_MEDIATYPE_COPPER;
-					break;
-				}
-				aprint_verbose_dev(sc->sc_dev, "SGMII(I2C)\n");
-				/*FALLTHROUGH*/
-			case CTRL_EXT_LINK_MODE_PCIE_SERDES:
-				sc->sc_mediatype = wm_sfp_get_media_type(sc);
-				if (sc->sc_mediatype == WM_MEDIATYPE_UNKNOWN) {
-					if (link_mode
-					    == CTRL_EXT_LINK_MODE_SGMII) {
-						sc->sc_mediatype
-						    = WM_MEDIATYPE_COPPER;
-						sc->sc_flags |= WM_F_SGMII;
-					} else {
-						sc->sc_mediatype
-						    = WM_MEDIATYPE_SERDES;
-						aprint_verbose_dev(sc->sc_dev,
-						    "SERDES\n");
-					}
-					break;
-				}
-				if (sc->sc_mediatype == WM_MEDIATYPE_SERDES)
+					sc->sc_flags |= WM_F_SGMII;
+				} else {
+					sc->sc_mediatype = WM_MEDIATYPE_SERDES;
 					aprint_verbose_dev(sc->sc_dev,
 					    "SERDES\n");
-
-				/* Change current link mode setting */
-				reg &= ~CTRL_EXT_LINK_MODE_MASK;
-				switch (sc->sc_mediatype) {
-				case WM_MEDIATYPE_COPPER:
-					reg |= CTRL_EXT_LINK_MODE_SGMII;
-					break;
-				case WM_MEDIATYPE_SERDES:
-					reg |= CTRL_EXT_LINK_MODE_PCIE_SERDES;
-					break;
-				default:
-					break;
 				}
-				CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
 				break;
-			case CTRL_EXT_LINK_MODE_GMII:
+			}
+			if (sc->sc_mediatype == WM_MEDIATYPE_SERDES)
+				aprint_verbose_dev(sc->sc_dev, "SERDES\n");
+
+			/* Change current link mode setting */
+			reg &= ~CTRL_EXT_LINK_MODE_MASK;
+			switch (sc->sc_mediatype) {
+			case WM_MEDIATYPE_COPPER:
+				reg |= CTRL_EXT_LINK_MODE_SGMII;
+				break;
+			case WM_MEDIATYPE_SERDES:
+				reg |= CTRL_EXT_LINK_MODE_PCIE_SERDES;
+				break;
 			default:
-				aprint_verbose_dev(sc->sc_dev, "Copper\n");
-				sc->sc_mediatype = WM_MEDIATYPE_COPPER;
 				break;
 			}
-
-			reg &= ~CTRL_EXT_I2C_ENA;
-			if ((sc->sc_flags & WM_F_SGMII) != 0)
-				reg |= CTRL_EXT_I2C_ENA;
-			else
-				reg &= ~CTRL_EXT_I2C_ENA;
 			CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
-
-			if (sc->sc_mediatype == WM_MEDIATYPE_COPPER)
-				wm_gmii_mediainit(sc, wmp->wmp_product);
-			else
-				wm_tbi_mediainit(sc);
 			break;
+		case CTRL_EXT_LINK_MODE_GMII:
 		default:
-			if (sc->sc_mediatype == WM_MEDIATYPE_FIBER)
-				aprint_error_dev(sc->sc_dev,
-				    "WARNING: TBIMODE clear on 1000BASE-X product!\n");
+			aprint_verbose_dev(sc->sc_dev, "Copper\n");
 			sc->sc_mediatype = WM_MEDIATYPE_COPPER;
+			break;
+		}
+
+		reg &= ~CTRL_EXT_I2C_ENA;
+		if ((sc->sc_flags & WM_F_SGMII) != 0)
+			reg |= CTRL_EXT_I2C_ENA;
+		else
+			reg &= ~CTRL_EXT_I2C_ENA;
+		CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
+
+		if (sc->sc_mediatype == WM_MEDIATYPE_COPPER)
 			wm_gmii_mediainit(sc, wmp->wmp_product);
+		else
+			wm_tbi_mediainit(sc);
+	} else if (sc->sc_type < WM_T_82543 ||
+	    (CSR_READ(sc, WMREG_STATUS) & STATUS_TBIMODE) != 0) {
+		if (sc->sc_mediatype == WM_MEDIATYPE_COPPER) {
+			aprint_error_dev(sc->sc_dev,
+			    "WARNING: TBIMODE set on 1000BASE-T product!\n");
+			sc->sc_mediatype = WM_MEDIATYPE_FIBER;
+		}
+		wm_tbi_mediainit(sc);
+	} else {
+		if (sc->sc_mediatype == WM_MEDIATYPE_FIBER) {
+			aprint_error_dev(sc->sc_dev,
+			    "WARNING: TBIMODE clear on 1000BASE-X product!\n");
+			sc->sc_mediatype = WM_MEDIATYPE_COPPER;
 		}
+		wm_gmii_mediainit(sc, wmp->wmp_product);
 	}
 
 	ifp = &sc->sc_ethercom.ec_if;
@@ -9677,8 +9668,17 @@ do {									\
 
 	aprint_normal_dev(sc->sc_dev, "");
 
-	/* Only 82545 is LX */
-	if (sc->sc_type == WM_T_82545) {
+	if (sc->sc_type == WM_T_I354) {
+		uint32_t status;
+
+		status = CSR_READ(sc, WMREG_STATUS);
+		if (((status & STATUS_2P5_SKU) != 0)
+		    && ((status & STATUS_2P5_SKU_OVER) == 0)) {
+			ADD("2500baseKX-FDX", IFM_2500_SX | IFM_FDX,ANAR_X_FD);
+		} else
+			ADD("1000baseSX-FDX", IFM_1000_SX | IFM_FDX,ANAR_X_FD);
+	} else if (sc->sc_type == WM_T_82545) {
+		/* Only 82545 is LX (XXX except SFP) */
 		ADD("1000baseLX", IFM_1000_LX, ANAR_X_HD);
 		ADD("1000baseLX-FDX", IFM_1000_LX | IFM_FDX, ANAR_X_FD);
 	} else {
@@ -10087,7 +10087,32 @@ wm_serdes_mediastatus(struct ifnet *ifp,
 
 	sc->sc_tbi_linkup = 1;
 	ifmr->ifm_status |= IFM_ACTIVE;
-	ifmr->ifm_active |= IFM_1000_SX; /* XXX */
+	if (sc->sc_type == WM_T_I354) {
+		uint32_t status;
+
+		status = CSR_READ(sc, WMREG_STATUS);
+		if (((status & STATUS_2P5_SKU) != 0)
+		    && ((status & STATUS_2P5_SKU_OVER) == 0)) {
+			ifmr->ifm_active |= IFM_2500_SX; /* XXX KX */
+		} else
+			ifmr->ifm_active |= IFM_1000_SX; /* XXX KX */
+	} else {
+		switch (__SHIFTOUT(reg, PCS_LSTS_SPEED)) {
+		case PCS_LSTS_SPEED_10:
+			ifmr->ifm_active |= IFM_10_T; /* XXX */
+			break;
+		case PCS_LSTS_SPEED_100:
+			ifmr->ifm_active |= IFM_100_FX; /* XXX */
+			break;
+		case PCS_LSTS_SPEED_1000:
+			ifmr->ifm_active |= IFM_1000_SX; /* XXX */
+			break;
+		default:
+			device_printf(sc->sc_dev, "Unknown speed\n");
+			ifmr->ifm_active |= IFM_1000_SX; /* XXX */
+			break;
+		}
+	}
 	if ((reg & PCS_LSTS_FDX) != 0)
 		ifmr->ifm_active |= IFM_FDX;
 	else
@@ -10120,7 +10145,6 @@ wm_serdes_mediastatus(struct ifnet *ifp,
 		    && (pcs_lpab & TXCW_ASYM_PAUSE)) {
 			mii->mii_media_active |= IFM_FLOW
 			    | IFM_ETH_RXPAUSE;
-		} else {
 		}
 	}
 	ifmr->ifm_active = (ifmr->ifm_active & ~IFM_ETH_FMASK)
@@ -10161,7 +10185,7 @@ wm_serdes_tick(struct wm_softc *sc)
 	} else {
 		mii->mii_media_status |= IFM_NONE;
 		sc->sc_tbi_linkup = 0;
-		    /* If the timer expired, retry autonegotiation */
+		/* If the timer expired, retry autonegotiation */
 		if ((IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO)
 		    && (++sc->sc_tbi_serdes_ticks
 			>= sc->sc_tbi_serdes_anegticks)) {

Index: src/sys/dev/pci/if_wmreg.h
diff -u src/sys/dev/pci/if_wmreg.h:1.93 src/sys/dev/pci/if_wmreg.h:1.94
--- src/sys/dev/pci/if_wmreg.h:1.93	Wed Nov 16 08:56:17 2016
+++ src/sys/dev/pci/if_wmreg.h	Tue Dec 13 10:01:44 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wmreg.h,v 1.93 2016/11/16 08:56:17 msaitoh Exp $	*/
+/*	$NetBSD: if_wmreg.h,v 1.94 2016/12/13 10:01:44 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -267,7 +267,9 @@ struct livengood_tcpip_ctxdesc {
 #define	STATUS_PHYRA	(1U << 10)	/* PHY Reset Asserted (PCH) */
 #define	STATUS_PCI66	(1U << 11)	/* 66MHz bus (Livengood) */
 #define	STATUS_BUS64	(1U << 12)	/* 64-bit bus (Livengood) */
+#define	STATUS_2P5_SKU	__BIT(12)	/* Value of the 2.5GBE SKU strap */
 #define	STATUS_PCIX_MODE (1U << 13)	/* PCIX mode (Cordova) */
+#define	STATUS_2P5_SKU_OVER __BIT(13)	/* Value of the 2.5GBE SKU override */
 #define	STATUS_PCIXSPD(x) ((x) << 14)	/* PCIX speed indication (Cordova) */
 #define	STATUS_PCIXSPD_50_66   STATUS_PCIXSPD(0)
 #define	STATUS_PCIXSPD_66_100  STATUS_PCIXSPD(1)
@@ -915,8 +917,10 @@ struct livengood_tcpip_ctxdesc {
 
 #define	WMREG_PCS_LSTS	0x420c	/* PCS Link Status */
 #define PCS_LSTS_LINKOK	__BIT(0)
-#define PCS_LSTS_SPEED_100  __BIT(1)
-#define PCS_LSTS_SPEED_1000 __BIT(2)
+#define PCS_LSTS_SPEED	__BITS(2, 1)
+#define PCS_LSTS_SPEED_10	0
+#define PCS_LSTS_SPEED_100	1
+#define PCS_LSTS_SPEED_1000	2
 #define PCS_LSTS_FDX	__BIT(3)
 #define PCS_LSTS_AN_COMP __BIT(16)
 

Reply via email to