QEMU e1000's PHY code doesn't reflect the PSSR_LINK bit. Do workaround.

IEEE 802.3 clause 22's PHY device has a link status bit in the BMCR
  register, but it's required to read twice to get the correct value.
  Almost all PHY devices have the vendor specific register which has
  the link status bit that it's not required to read twice. makphy(4)
  use the bit in the PSSR register to reduce the access cost.

   QEMU's e1000 provides the PHY specific status register at 0x11 but the
  link indication bit (PSSR_LINK.) is always 1 because
  e1000x_update_regs_on_link_{down,up}() modify MII_SR_LINK_STATUS
  (BMSR_LINK in NetBSD) but don't modify PSSR_LINK. It causes
  "virsh domif-setlink xxx yyy down" doesn't work.
  To avoid this problem, read the BMSR and check the BMSR_LINK bit. Add
  MAKPHY_QUIRK_PSSR_LINK bit for this quirk. Set it if MII_EXTSR doesn't
  exist because it's one of the case of QEMU.

  Found and tested by ozaki-r.
This commit is contained in:
msaitoh 2022-01-06 07:39:10 +00:00
parent ebe5c3e633
commit fd0f817df7
2 changed files with 31 additions and 5 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: makphy.c,v 1.71 2021/12/28 06:36:29 msaitoh Exp $ */
/* $NetBSD: makphy.c,v 1.72 2022/01/06 07:39:10 msaitoh Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.71 2021/12/28 06:36:29 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.72 2022/01/06 07:39:10 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -216,6 +216,12 @@ page0:
"Regard as 1000BASE-T.\n");
sc->mii_extcapabilities
|= EXTSR_1000TFDX | EXTSR_1000THDX;
/*
* Also assume it doesn't support PSSR_LINK bit.
* It's for QEMU.
*/
maksc->sc_flags |= MAKPHY_QUIRK_PSSR_LINK;
}
}
@ -438,6 +444,7 @@ makphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
static void
makphy_status(struct mii_softc *sc)
{
struct makphy_softc *maksc = (struct makphy_softc *)sc;
struct mii_data *mii = sc->mii_pdata;
uint16_t bmcr, gsr, pssr, essr;
@ -450,6 +457,23 @@ makphy_status(struct mii_softc *sc)
/* XXX FIXME: Use different page for Fiber on newer chips */
PHY_READ(sc, MAKPHY_PSSR, &pssr);
if ((maksc->sc_flags & MAKPHY_QUIRK_PSSR_LINK) != 0) {
uint16_t bmsr;
/*
* QEMU e1000 driver has the PSSR register but it doesn't
* support the PSSR_LINK bit well. It always returns 1.
* To avoid this problem, use the BMSR_LINK bit. It's not
* required to read it twice as real device because it's not
* latched.
*/
PHY_READ(sc, MII_BMSR, &bmsr);
if (bmsr & BMSR_LINK)
pssr |= MAKPHY_PSSR_LINK;
else
pssr &= ~MAKPHY_PSSR_LINK;
}
if (pssr & MAKPHY_PSSR_LINK)
mii->mii_media_status |= IFM_ACTIVE;
@ -488,8 +512,6 @@ makphy_status(struct mii_softc *sc)
mii->mii_media_active |= IFM_1000_SX;
} else if ((sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1011) ||
(sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1111)) {
struct makphy_softc *maksc = (struct makphy_softc *)sc;
if ((maksc->sc_flags & MAKPHY_F_FICO_AUTOSEL) != 0) {
/* Fiber/Copper auto select mode */
PHY_READ(sc, MAKPHY_ESSR, &essr);

View File

@ -1,4 +1,4 @@
/* $NetBSD: makphyvar.h,v 1.3 2021/12/28 06:36:29 msaitoh Exp $ */
/* $NetBSD: makphyvar.h,v 1.4 2022/01/06 07:39:10 msaitoh Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@ -39,5 +39,9 @@ struct makphy_softc {
#define MAKPHY_F_I210 __BIT(0) /* Identify I210 (mii_model == 0) */
#define MAKPHY_F_FICO_AUTOSEL __BIT(1) /* Fiber/Copper autoselect mode */
#define MAKPHY_QUIRK_PSSR_LINK __BIT(2) /*
* For emulator which doesn't support
* PSSR_LINK (e.g. QEMU).
*/
#endif /* _MII_MAKPHYVAR_H_ */