Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci - Add new wm_gmii_{hv,i82544}_{read,write}reg_lo...
details: https://anonhg.NetBSD.org/src/rev/65a3ab4bf819
branches: trunk
changeset: 994575:65a3ab4bf819
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Wed Nov 14 03:41:20 2018 +0000
description:
- Add new wm_gmii_{hv,i82544}_{read,write}reg_locked() and use them in
wm_gmii_{hv,i82544}_{read,write}reg(). *_locked() functions are not
mii(4) API functions, so it's not required to keep the mii API. Change
the PHY register type from int to uint16_t. It also change the usage of
return value. It returns zero on success and non-zero on error.
- Check the return value of *_locked() function and treat it.
- Use *writereg_locked() function to reduce race condition in
wm_init_lcd_from_nvm().
- Add comment.
diffstat:
sys/dev/pci/if_wm.c | 191 ++++++++++++++++++++++++++++++++++-----------------
1 files changed, 126 insertions(+), 65 deletions(-)
diffs (truncated from 482 to 300 lines):
diff -r 683e53e8aecf -r 65a3ab4bf819 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Wed Nov 14 02:37:51 2018 +0000
+++ b/sys/dev/pci/if_wm.c Wed Nov 14 03:41:20 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.596 2018/11/03 21:39:10 christos Exp $ */
+/* $NetBSD: if_wm.c,v 1.597 2018/11/14 03:41:20 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.596 2018/11/03 21:39:10 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.597 2018/11/14 03:41:20 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -463,6 +463,8 @@
struct wm_phyop {
int (*acquire)(struct wm_softc *);
void (*release)(struct wm_softc *);
+ int (*readreg_locked)(device_t, int, int, uint16_t *);
+ int (*writereg_locked)(device_t, int, int, uint16_t);
int reset_delay_us;
};
@@ -716,7 +718,7 @@
static void wm_lan_init_done(struct wm_softc *);
static void wm_get_cfg_done(struct wm_softc *);
static void wm_phy_post_reset(struct wm_softc *);
-static void wm_write_smbus_addr(struct wm_softc *);
+static int wm_write_smbus_addr(struct wm_softc *);
static void wm_init_lcd_from_nvm(struct wm_softc *);
static void wm_initialize_hardware_bits(struct wm_softc *);
static uint32_t wm_rxpbs_adjust_82580(uint32_t);
@@ -819,16 +821,18 @@
static int wm_gmii_mdic_readreg(device_t, int, int);
static void wm_gmii_mdic_writereg(device_t, int, int, int);
static int wm_gmii_i82544_readreg(device_t, int, int);
+static int wm_gmii_i82544_readreg_locked(device_t, int, int, uint16_t *);
static void wm_gmii_i82544_writereg(device_t, int, int, int);
+static int wm_gmii_i82544_writereg_locked(device_t, int, int, uint16_t);
static int wm_gmii_i80003_readreg(device_t, int, int);
static void wm_gmii_i80003_writereg(device_t, int, int, int);
static int wm_gmii_bm_readreg(device_t, int, int);
static void wm_gmii_bm_writereg(device_t, int, int, int);
static void wm_access_phy_wakeup_reg_bm(device_t, int, int16_t *, int);
static int wm_gmii_hv_readreg(device_t, int, int);
-static int wm_gmii_hv_readreg_locked(device_t, int, int);
+static int wm_gmii_hv_readreg_locked(device_t, int, int, uint16_t *);
static void wm_gmii_hv_writereg(device_t, int, int, int);
-static void wm_gmii_hv_writereg_locked(device_t, int, int, int);
+static int wm_gmii_hv_writereg_locked(device_t, int, int, uint16_t);
static int wm_gmii_82580_readreg(device_t, int, int);
static void wm_gmii_82580_writereg(device_t, int, int, int);
static int wm_gmii_gs40g_readreg(device_t, int, int);
@@ -948,7 +952,7 @@
static void wm_init_manageability(struct wm_softc *);
static void wm_release_manageability(struct wm_softc *);
static void wm_get_wakeup(struct wm_softc *);
-static void wm_ulp_disable(struct wm_softc *);
+static int wm_ulp_disable(struct wm_softc *);
static void wm_enable_phy_wakeup(struct wm_softc *);
static void wm_igp3_phy_powerdown_workaround_ich8lan(struct wm_softc *);
static void wm_enable_wakeup(struct wm_softc *);
@@ -3826,6 +3830,7 @@
else
wm_get_auto_rd_done(sc);
+ /* Clear PHY Reset Asserted bit */
reg = CSR_READ(sc, WMREG_STATUS);
if ((reg & STATUS_PHYRA) != 0)
CSR_WRITE(sc, WMREG_STATUS, reg & ~STATUS_PHYRA);
@@ -3886,19 +3891,23 @@
}
/* Only for PCH and newer */
-static void
+static int
wm_write_smbus_addr(struct wm_softc *sc)
{
uint32_t strap, freq;
- uint32_t phy_data;
+ uint16_t phy_data;
+ int rv;
DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
device_xname(sc->sc_dev), __func__));
+ KASSERT(CSR_READ(sc, WMREG_EXTCNFCTR) & EXTCNFCTR_MDIO_SW_OWNERSHIP);
strap = CSR_READ(sc, WMREG_STRAP);
freq = __SHIFTOUT(strap, STRAP_FREQ);
- phy_data = wm_gmii_hv_readreg_locked(sc->sc_dev, 2, HV_SMB_ADDR);
+ rv = wm_gmii_hv_readreg_locked(sc->sc_dev, 2, HV_SMB_ADDR, &phy_data);
+ if (rv != 0)
+ return -1;
phy_data &= ~HV_SMB_ADDR_ADDR;
phy_data |= __SHIFTOUT(strap, STRAP_SMBUSADDR);
@@ -3920,7 +3929,8 @@
}
}
- wm_gmii_hv_writereg_locked(sc->sc_dev, 2, HV_SMB_ADDR, phy_data);
+ return wm_gmii_hv_writereg_locked(sc->sc_dev, 2, HV_SMB_ADDR,
+ phy_data);
}
void
@@ -4012,9 +4022,8 @@
reg_addr &= IGPHY_MAXREGADDR;
reg_addr |= phy_page;
- sc->phy.release(sc); /* XXX */
- sc->sc_mii.mii_writereg(sc->sc_dev, 1, reg_addr, reg_data);
- sc->phy.acquire(sc); /* XXX */
+ KASSERT(sc->phy.writereg_locked != NULL);
+ sc->phy.writereg_locked(sc->sc_dev, 1, reg_addr, reg_data);
}
release:
@@ -9708,6 +9717,13 @@
sc->sc_phytype = new_phytype;
mii->mii_readreg = new_readreg;
mii->mii_writereg = new_writereg;
+ if (new_readreg == wm_gmii_hv_readreg) {
+ sc->phy.readreg_locked = wm_gmii_hv_readreg_locked;
+ sc->phy.writereg_locked = wm_gmii_hv_writereg_locked;
+ } else if (new_readreg == wm_gmii_i82544_readreg) {
+ sc->phy.readreg_locked = wm_gmii_i82544_readreg_locked;
+ sc->phy.writereg_locked = wm_gmii_i82544_writereg_locked;
+ }
}
/*
@@ -10189,13 +10205,25 @@
wm_gmii_i82544_readreg(device_t dev, int phy, int reg)
{
struct wm_softc *sc = device_private(dev);
- int rv;
+ uint16_t val;
if (sc->phy.acquire(sc)) {
device_printf(dev, "%s: failed to get semaphore\n", __func__);
return 0;
}
+ wm_gmii_i82544_readreg_locked(dev, phy, reg, &val);
+
+ sc->phy.release(sc);
+
+ return val;
+}
+
+static int
+wm_gmii_i82544_readreg_locked(device_t dev, int phy, int reg, uint16_t *val)
+{
+ struct wm_softc *sc = device_private(dev);
+
if (reg > BME1000_MAX_MULTI_PAGE_REG) {
switch (sc->sc_phytype) {
case WMPHY_IGP:
@@ -10213,10 +10241,9 @@
}
}
- rv = wm_gmii_mdic_readreg(dev, phy, reg & MII_ADDRMASK);
- sc->phy.release(sc);
-
- return rv;
+ *val = wm_gmii_mdic_readreg(dev, phy, reg & MII_ADDRMASK);
+
+ return 0;
}
/*
@@ -10234,6 +10261,15 @@
return;
}
+ wm_gmii_i82544_writereg_locked(dev, phy, reg & MII_ADDRMASK, val);
+ sc->phy.release(sc);
+}
+
+static int
+wm_gmii_i82544_writereg_locked(device_t dev, int phy, int reg, uint16_t val)
+{
+ struct wm_softc *sc = device_private(dev);
+
if (reg > BME1000_MAX_MULTI_PAGE_REG) {
switch (sc->sc_phytype) {
case WMPHY_IGP:
@@ -10252,7 +10288,8 @@
}
wm_gmii_mdic_writereg(dev, phy, reg & MII_ADDRMASK, val);
- sc->phy.release(sc);
+
+ return 0;
}
/*
@@ -10522,7 +10559,7 @@
wm_gmii_hv_readreg(device_t dev, int phy, int reg)
{
struct wm_softc *sc = device_private(dev);
- int rv;
+ uint16_t val;
DPRINTF(WM_DEBUG_GMII, ("%s: %s called\n",
device_xname(dev), __func__));
@@ -10531,25 +10568,23 @@
return 0;
}
- rv = wm_gmii_hv_readreg_locked(dev, phy, reg);
+ wm_gmii_hv_readreg_locked(dev, phy, reg, &val);
sc->phy.release(sc);
- return rv;
-}
-
-static int
-wm_gmii_hv_readreg_locked(device_t dev, int phy, int reg)
+ return val;
+}
+
+static int
+wm_gmii_hv_readreg_locked(device_t dev, int phy, int reg, uint16_t *val)
{
uint16_t page = BM_PHY_REG_PAGE(reg);
uint16_t regnum = BM_PHY_REG_NUM(reg);
- uint16_t val;
- int rv;
phy = (page >= HV_INTC_FC_PAGE_START) ? 1 : phy;
/* Page 800 works differently than the rest so it has its own func */
if (page == BM_WUC_PAGE) {
- wm_access_phy_wakeup_reg_bm(dev, reg, &val, 1);
- return val;
+ wm_access_phy_wakeup_reg_bm(dev, reg, val, 1);
+ return 0;
}
/*
@@ -10573,8 +10608,8 @@
page << BME1000_PAGE_SHIFT);
}
- rv = wm_gmii_mdic_readreg(dev, phy, regnum & MII_ADDRMASK);
- return rv;
+ *val = wm_gmii_mdic_readreg(dev, phy, regnum & MII_ADDRMASK);
+ return 0;
}
/*
@@ -10601,8 +10636,8 @@
sc->phy.release(sc);
}
-static void
-wm_gmii_hv_writereg_locked(device_t dev, int phy, int reg, int val)
+static int
+wm_gmii_hv_writereg_locked(device_t dev, int phy, int reg, uint16_t val)
{
struct wm_softc *sc = device_private(dev);
uint16_t page = BM_PHY_REG_PAGE(reg);
@@ -10616,7 +10651,7 @@
tmp = val;
wm_access_phy_wakeup_reg_bm(dev, reg, &tmp, 0);
- return;
+ return 0;
}
/*
@@ -10625,7 +10660,7 @@
*/
if ((page > 0) && (page < HV_INTC_FC_PAGE_START)) {
printf("gmii_hv_writereg!!!\n");
- return;
+ return -1;
}
{
@@ -10659,6 +10694,8 @@
}
wm_gmii_mdic_writereg(dev, phy, regnum & MII_ADDRMASK, val);
+
+ return 0;
}
/*
@@ -13898,11 +13935,12 @@
* Unconfigure Ultra Low Power mode.
* Only for I217 and newer (see below).
*/
Home |
Main Index |
Thread Index |
Old Index