Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci - Our MII readreg/writereg API has not way to d...
details: https://anonhg.NetBSD.org/src/rev/3e462182e7bf
branches: trunk
changeset: 355337:3e462182e7bf
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Wed Jul 26 06:48:49 2017 +0000
description:
- 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.
diffstat:
sys/dev/pci/if_wm.c | 210 +++++++++++++++++++++++++++++++-----------------
sys/dev/pci/if_wmreg.h | 18 ++-
sys/dev/pci/if_wmvar.h | 3 +-
3 files changed, 149 insertions(+), 82 deletions(-)
diffs (truncated from 429 to 300 lines):
diff -r 090919986b7e -r 3e462182e7bf sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Wed Jul 26 06:44:50 2017 +0000
+++ b/sys/dev/pci/if_wm.c Wed Jul 26 06:48:49 2017 +0000
@@ -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 @@
* 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 @@
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 @@
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_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_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 @@
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 @@
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);
- }
- /* 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);
+ 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;
+ }
+ 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 @@
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 @@
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);
- }
- /* 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);
-
+ 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;
+ }
+ 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 @@
* 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 @@
if (rv != 0) {
device_printf(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
- return 0;
- }
-
- rv = wm_kmrn_readreg_locked(sc, reg);
+ return rv;
+ }
+
+ 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 @@
}
static int
-wm_kmrn_readreg_locked(struct wm_softc *sc, int reg)
-{
- int rv;
+wm_kmrn_readreg_locked(struct wm_softc *sc, int reg, uint16_t *val)
+{
CSR_WRITE(sc, WMREG_KUMCTRLSTA,
((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) |
@@ -10545,9 +10595,9 @@
CSR_WRITE_FLUSH(sc);
delay(2);
- rv = CSR_READ(sc, WMREG_KUMCTRLSTA) & KUMCTRLSTA_MASK;
-
- return rv;
+ *val = CSR_READ(sc, WMREG_KUMCTRLSTA) & KUMCTRLSTA_MASK;
+
+ return 0;
}
/*
@@ -10555,8 +10605,8 @@
*
* 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 @@
if (rv != 0) {
device_printf(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
- return;
- }
-
- wm_kmrn_writereg_locked(sc, reg, val);
+ return rv;
+ }
+
+ 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);
-}
-
-static void
-wm_kmrn_writereg_locked(struct wm_softc *sc, int reg, int val)
+
+ return rv;
+}
+
+static int
+wm_kmrn_writereg_locked(struct wm_softc *sc, int reg, uint16_t val)
{
Home |
Main Index |
Thread Index |
Old Index