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 */
 

Reply via email to