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