Page MenuHomeFreeBSD

D56138.diff
No OneTemporary

D56138.diff

diff --git a/sys/dev/usb/net/if_ure.c b/sys/dev/usb/net/if_ure.c
--- a/sys/dev/usb/net/if_ure.c
+++ b/sys/dev/usb/net/if_ure.c
@@ -34,6 +34,7 @@
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/sx.h>
#include <sys/sbuf.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
@@ -137,7 +138,6 @@
static miibus_readreg_t ure_miibus_readreg;
static miibus_writereg_t ure_miibus_writereg;
static miibus_statchg_t ure_miibus_statchg;
-static miibus_linkchg_t ure_miibus_linkchg;
static uether_fn_t ure_attach_post;
static uether_fn_t ure_init;
@@ -194,7 +194,6 @@
DEVMETHOD(miibus_readreg, ure_miibus_readreg),
DEVMETHOD(miibus_writereg, ure_miibus_writereg),
DEVMETHOD(miibus_statchg, ure_miibus_statchg),
- DEVMETHOD(miibus_linkchg, ure_miibus_linkchg),
DEVMETHOD_END
};
@@ -454,8 +453,6 @@
struct mii_data *mii;
if_t ifp;
int locked;
- uint16_t bmsr;
- bool new_link, old_link;
sc = device_get_softc(dev);
mii = GET_MII(sc);
@@ -468,7 +465,6 @@
(if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0)
goto done;
- old_link = (sc->sc_flags & URE_FLAG_LINK) ? true : false;
sc->sc_flags &= ~URE_FLAG_LINK;
if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
(IFM_ACTIVE | IFM_AVALID)) {
@@ -489,72 +485,14 @@
}
}
- new_link = (sc->sc_flags & URE_FLAG_LINK) ? true : false;
- if (old_link && !new_link) {
- /*
- * MII layer reports link down. Verify by reading
- * the PHY BMSR register directly. BMSR link status
- * is latched-low, so read twice: first clears any
- * stale latch, second gives current state.
- */
- (void)ure_ocp_reg_read(sc,
- URE_OCP_BASE_MII + MII_BMSR * 2);
- bmsr = ure_ocp_reg_read(sc,
- URE_OCP_BASE_MII + MII_BMSR * 2);
-
- if (bmsr & BMSR_LINK) {
- /*
- * PHY still has link. This is a spurious
- * link-down from the MII polling race (see
- * PR 252165). Restore IFM_ACTIVE so the
- * subsequent MIIBUS_LINKCHG check in
- * mii_phy_update sees no change.
- */
- device_printf(dev,
- "spurious link down (PHY link up), overriding\n");
- sc->sc_flags |= URE_FLAG_LINK;
- mii->mii_media_status |= IFM_ACTIVE;
- }
- }
+ /* Lost link, do nothing. */
+ if ((sc->sc_flags & URE_FLAG_LINK) == 0)
+ goto done;
done:
if (!locked)
URE_UNLOCK(sc);
}
-static void
-ure_miibus_linkchg(device_t dev)
-{
- struct ure_softc *sc;
- struct mii_data *mii;
- int locked;
- uint16_t bmsr;
-
- sc = device_get_softc(dev);
- mii = GET_MII(sc);
- locked = mtx_owned(&sc->sc_mtx);
- if (locked == 0)
- URE_LOCK(sc);
-
- /*
- * This is called by the default miibus linkchg handler
- * before it calls if_link_state_change(). If the PHY
- * still has link but the MII layer lost IFM_ACTIVE due
- * to the polling race (see PR 252165), restore it so the
- * notification goes out as LINK_STATE_UP rather than DOWN.
- */
- if (mii != NULL && (mii->mii_media_status & IFM_ACTIVE) == 0) {
- (void)ure_ocp_reg_read(sc,
- URE_OCP_BASE_MII + MII_BMSR * 2);
- bmsr = ure_ocp_reg_read(sc,
- URE_OCP_BASE_MII + MII_BMSR * 2);
- if (bmsr & BMSR_LINK)
- mii->mii_media_status |= IFM_ACTIVE;
- }
-
- if (locked == 0)
- URE_UNLOCK(sc);
-}
-
/*
* Probe for a RTL8152/RTL8153/RTL8156 chip.
*/
@@ -591,6 +529,7 @@
sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
device_set_usb_desc(dev);
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+ sx_init(&sc->sc_mii_lock, "uremii");
iface_index = URE_IFACE_IDX;
@@ -665,6 +604,7 @@
usbd_transfer_unsetup(sc->sc_tx_xfer, URE_MAX_TX);
usbd_transfer_unsetup(sc->sc_rx_xfer, URE_MAX_RX);
uether_ifdetach(ue);
+ sx_destroy(&sc->sc_mii_lock);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -1242,6 +1182,13 @@
if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) {
ure_link_state(sc);
} else {
+ URE_UNLOCK(sc);
+ if (!URE_MII_TRYLOCK(sc)) {
+ URE_LOCK(sc);
+ return;
+ }
+ URE_LOCK(sc);
+
mii = GET_MII(sc);
mii_tick(mii);
if ((sc->sc_flags & URE_FLAG_LINK) == 0
@@ -1251,6 +1198,10 @@
sc->sc_rxstarted = 0;
ure_start(ue);
}
+
+ URE_UNLOCK(sc);
+ URE_MII_UNLOCK(sc);
+ URE_LOCK(sc);
}
}
@@ -1417,9 +1368,18 @@
mii = GET_MII(sc);
URE_LOCK_ASSERT(sc, MA_OWNED);
+
+ URE_UNLOCK(sc);
+ URE_MII_LOCK(sc);
+ URE_LOCK(sc);
+
LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
PHY_RESET(miisc);
error = mii_mediachg(mii);
+
+ URE_UNLOCK(sc);
+ URE_MII_UNLOCK(sc);
+ URE_LOCK(sc);
return (error);
}
@@ -1461,11 +1421,13 @@
mii = GET_MII(sc);
+ URE_MII_LOCK(sc);
URE_LOCK(sc);
mii_pollstat(mii);
ifmr->ifm_active = mii->mii_media_active;
ifmr->ifm_status = mii->mii_media_status;
URE_UNLOCK(sc);
+ URE_MII_UNLOCK(sc);
}
static void
diff --git a/sys/dev/usb/net/if_urereg.h b/sys/dev/usb/net/if_urereg.h
--- a/sys/dev/usb/net/if_urereg.h
+++ b/sys/dev/usb/net/if_urereg.h
@@ -581,6 +581,7 @@
struct usb_ether sc_ue;
struct ifmedia sc_ifmedia;
struct mtx sc_mtx;
+ struct sx sc_mii_lock;
struct usb_xfer *sc_rx_xfer[URE_MAX_RX];
struct usb_xfer *sc_tx_xfer[URE_MAX_TX];
@@ -616,5 +617,8 @@
#define URE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define URE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define URE_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)
+#define URE_MII_LOCK(_sc) sx_xlock(&(_sc)->sc_mii_lock)
+#define URE_MII_UNLOCK(_sc) sx_xunlock(&(_sc)->sc_mii_lock)
+#define URE_MII_TRYLOCK(_sc) sx_try_xlock(&(_sc)->sc_mii_lock)
#endif /* _IF_UREREG_H_ */

File Metadata

Mime Type
text/plain
Expires
Mon, Jun 22, 5:18 AM (13 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34175187
Default Alt Text
D56138.diff (5 KB)

Event Timeline