Module Name: src
Committed By: msaitoh
Date: Tue Oct 8 14:26:27 UTC 2019
Modified Files:
src/sys/dev/pci: if_vge.c if_vgereg.h
Log Message:
Copy vge_clrwol() from FreeBSD and call it in vge_attach() to recover from
powerdown mode. Fixes PR kern/41525 reported by Aran Clauson.
To generate a diff of this commit:
cvs rdiff -u -r1.74 -r1.75 src/sys/dev/pci/if_vge.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/pci/if_vgereg.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/if_vge.c
diff -u src/sys/dev/pci/if_vge.c:1.74 src/sys/dev/pci/if_vge.c:1.75
--- src/sys/dev/pci/if_vge.c:1.74 Fri Sep 13 07:55:07 2019
+++ src/sys/dev/pci/if_vge.c Tue Oct 8 14:26:27 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vge.c,v 1.74 2019/09/13 07:55:07 msaitoh Exp $ */
+/* $NetBSD: if_vge.c,v 1.75 2019/10/08 14:26:27 msaitoh Exp $ */
/*-
* Copyright (c) 2004
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vge.c,v 1.74 2019/09/13 07:55:07 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vge.c,v 1.75 2019/10/08 14:26:27 msaitoh Exp $");
/*
* VIA Networking Technologies VT612x PCI gigabit ethernet NIC driver.
@@ -328,6 +328,7 @@ static void vge_miibus_statchg(struct if
static void vge_cam_clear(struct vge_softc *);
static int vge_cam_set(struct vge_softc *, uint8_t *);
+static void vge_clrwol(struct vge_softc *);
static void vge_setmulti(struct vge_softc *);
static void vge_reset(struct vge_softc *);
@@ -953,6 +954,9 @@ vge_attach(device_t parent, device_t sel
aprint_normal_dev(self, "Ethernet address %s\n",
ether_sprintf(eaddr));
+ /* Clear WOL and take hardware from powerdown. */
+ vge_clrwol(sc);
+
/*
* Use the 32bit tag. Hardware supports 48bit physical addresses,
* but we don't use that for now.
@@ -2156,3 +2160,30 @@ vge_shutdown(device_t self, int howto)
return true;
}
+
+static void
+vge_clrwol(struct vge_softc *sc)
+{
+ uint8_t val;
+
+ val = CSR_READ_1(sc, VGE_PWRSTAT);
+ val &= ~VGE_STICKHW_SWPTAG;
+ CSR_WRITE_1(sc, VGE_PWRSTAT, val);
+ /* Disable WOL and clear power state indicator. */
+ val = CSR_READ_1(sc, VGE_PWRSTAT);
+ val &= ~(VGE_STICKHW_DS0 | VGE_STICKHW_DS1);
+ CSR_WRITE_1(sc, VGE_PWRSTAT, val);
+
+ CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_GMII);
+ CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_MACFORCE);
+
+ /* Clear WOL on pattern match. */
+ CSR_WRITE_1(sc, VGE_WOLCR0C, VGE_WOLCR0_PATTERN_ALL);
+ /* Disable WOL on magic/unicast packet. */
+ CSR_WRITE_1(sc, VGE_WOLCR1C, 0x0F);
+ CSR_WRITE_1(sc, VGE_WOLCFGC, VGE_WOLCFG_SAB | VGE_WOLCFG_SAM |
+ VGE_WOLCFG_PMEOVR);
+ /* Clear WOL status on pattern match. */
+ CSR_WRITE_1(sc, VGE_WOLSR0C, 0xFF);
+ CSR_WRITE_1(sc, VGE_WOLSR1C, 0xFF);
+}
Index: src/sys/dev/pci/if_vgereg.h
diff -u src/sys/dev/pci/if_vgereg.h:1.4 src/sys/dev/pci/if_vgereg.h:1.5
--- src/sys/dev/pci/if_vgereg.h:1.4 Thu Jul 11 03:49:51 2019
+++ src/sys/dev/pci/if_vgereg.h Tue Oct 8 14:26:27 2019
@@ -540,6 +540,31 @@
#define VGE_TXBLOCK_128PKTS 0x08
#define VGE_TXBLOCK_8PKTS 0x0C
+/* Sticky bit shadow register */
+
+#define VGE_STICKHW_DS0 0x01
+#define VGE_STICKHW_DS1 0x02
+#define VGE_STICKHW_WOL_ENB 0x04
+#define VGE_STICKHW_WOL_STS 0x08
+#define VGE_STICKHW_SWPTAG 0x10
+
+/* WOL pattern control */
+#define VGE_WOLCR0_PATTERN0 0x01
+#define VGE_WOLCR0_PATTERN1 0x02
+#define VGE_WOLCR0_PATTERN2 0x04
+#define VGE_WOLCR0_PATTERN3 0x08
+#define VGE_WOLCR0_PATTERN4 0x10
+#define VGE_WOLCR0_PATTERN5 0x20
+#define VGE_WOLCR0_PATTERN6 0x40
+#define VGE_WOLCR0_PATTERN7 0x80
+#define VGE_WOLCR0_PATTERN_ALL 0xFF
+
+/* WOL config register */
+#define VGE_WOLCFG_PHYINT_ENB 0x01
+#define VGE_WOLCFG_SAB 0x10
+#define VGE_WOLCFG_SAM 0x20
+#define VGE_WOLCFG_PMEOVR 0x80
+
/* EEPROM control/status register */
#define VGE_EECSR_EDO 0x01 /* data out pin */