summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authormsaitoh <msaitoh@NetBSD.org>2019-11-19 09:54:07 +0000
committermsaitoh <msaitoh@NetBSD.org>2019-11-19 09:54:07 +0000
commitbe9582a0495c98395086a3fd32d00a1372f69563 (patch)
tree4100b4d5a6fca66a8071e3af67d711921526a259 /sys/dev
parentef43b20ee560aefe7e3383d64638f8fd6d3cf0cf (diff)
Fixes a bug that "ifmedia vge0 media 1000baseT-FDX" causes device timeout.
If the interface's media is NOT in the "best" mode (i.e. other than IFM_AUTO), control VGE_DIAGCTL_GMII bit.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_vge.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/sys/dev/pci/if_vge.c b/sys/dev/pci/if_vge.c
index 3f2306651e9..69fcbb8c684 100644
--- a/sys/dev/pci/if_vge.c
+++ b/sys/dev/pci/if_vge.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vge.c,v 1.75 2019/10/08 14:26:27 msaitoh Exp $ */
+/* $NetBSD: if_vge.c,v 1.76 2019/11/19 09:54:07 msaitoh Exp $ */
/*-
* Copyright (c) 2004
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vge.c,v 1.75 2019/10/08 14:26:27 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vge.c,v 1.76 2019/11/19 09:54:07 msaitoh Exp $");
/*
* VIA Networking Technologies VT612x PCI gigabit ethernet NIC driver.
@@ -1916,6 +1916,7 @@ vge_miibus_statchg(struct ifnet *ifp)
struct vge_softc *sc = ifp->if_softc;
struct mii_data *mii = &sc->sc_mii;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
+ uint8_t dctl;
/*
* If the user manually selects a media mode, we need to turn
@@ -1928,23 +1929,26 @@ vge_miibus_statchg(struct ifnet *ifp)
* the FDX bit cleared.
*/
+ dctl = CSR_READ_1(sc, VGE_DIAGCTL);
+
switch (IFM_SUBTYPE(ife->ifm_media)) {
case IFM_AUTO:
- CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_MACFORCE);
- CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_FDXFORCE);
+ dctl &= ~VGE_DIAGCTL_MACFORCE;
+ dctl &= ~VGE_DIAGCTL_FDXFORCE;
break;
case IFM_1000_T:
- CSR_SETBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_MACFORCE);
- CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_FDXFORCE);
+ dctl |= VGE_DIAGCTL_MACFORCE;
+ dctl &= ~VGE_DIAGCTL_FDXFORCE;
+ dctl |= VGE_DIAGCTL_GMII;
break;
case IFM_100_TX:
case IFM_10_T:
- CSR_SETBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_MACFORCE);
- if ((ife->ifm_media & IFM_FDX) != 0) {
- CSR_SETBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_FDXFORCE);
- } else {
- CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_FDXFORCE);
- }
+ dctl |= VGE_DIAGCTL_MACFORCE;
+ dctl &= ~VGE_DIAGCTL_GMII;
+ if ((ife->ifm_media & IFM_FDX) != 0)
+ dctl |= VGE_DIAGCTL_FDXFORCE;
+ else
+ dctl &= ~VGE_DIAGCTL_FDXFORCE;
break;
default:
printf("%s: unknown media type: %x\n",
@@ -1952,6 +1956,8 @@ vge_miibus_statchg(struct ifnet *ifp)
IFM_SUBTYPE(ife->ifm_media));
break;
}
+
+ CSR_WRITE_1(sc, VGE_DIAGCTL, dctl);
}
static int