Tue Oct 8 14:26:27 2019 UTC ()
 Copy vge_clrwol() from FreeBSD and call it in vge_attach() to recover from
powerdown mode. Fixes PR kern/41525 reported by Aran Clauson.


(msaitoh)
diff -r1.74 -r1.75 src/sys/dev/pci/if_vge.c
diff -r1.4 -r1.5 src/sys/dev/pci/if_vgereg.h

cvs diff -r1.74 -r1.75 src/sys/dev/pci/if_vge.c (expand / switch to unified diff)

--- src/sys/dev/pci/if_vge.c 2019/09/13 07:55:07 1.74
+++ src/sys/dev/pci/if_vge.c 2019/10/08 14:26:27 1.75
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_vge.c,v 1.74 2019/09/13 07:55:07 msaitoh Exp $ */ 1/* $NetBSD: if_vge.c,v 1.75 2019/10/08 14:26:27 msaitoh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2004 4 * Copyright (c) 2004
5 * Bill Paul <wpaul@windriver.com>. All rights reserved. 5 * Bill Paul <wpaul@windriver.com>. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE. 32 * THE POSSIBILITY OF SUCH DAMAGE.
33 * 33 *
34 * FreeBSD: src/sys/dev/vge/if_vge.c,v 1.5 2005/02/07 19:39:29 glebius Exp 34 * FreeBSD: src/sys/dev/vge/if_vge.c,v 1.5 2005/02/07 19:39:29 glebius Exp
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: if_vge.c,v 1.74 2019/09/13 07:55:07 msaitoh Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: if_vge.c,v 1.75 2019/10/08 14:26:27 msaitoh Exp $");
39 39
40/* 40/*
41 * VIA Networking Technologies VT612x PCI gigabit ethernet NIC driver. 41 * VIA Networking Technologies VT612x PCI gigabit ethernet NIC driver.
42 * 42 *
43 * Written by Bill Paul <wpaul@windriver.com> 43 * Written by Bill Paul <wpaul@windriver.com>
44 * Senior Networking Software Engineer 44 * Senior Networking Software Engineer
45 * Wind River Systems 45 * Wind River Systems
46 */ 46 */
47 47
48/* 48/*
49 * The VIA Networking VT6122 is a 32bit, 33/66 MHz PCI device that 49 * The VIA Networking VT6122 is a 32bit, 33/66 MHz PCI device that
50 * combines a tri-speed ethernet MAC and PHY, with the following 50 * combines a tri-speed ethernet MAC and PHY, with the following
51 * features: 51 * features:
@@ -318,26 +318,27 @@ static int vge_resume(device_t); @@ -318,26 +318,27 @@ static int vge_resume(device_t);
318#endif 318#endif
319static bool vge_shutdown(device_t, int); 319static bool vge_shutdown(device_t, int);
320 320
321static uint16_t vge_read_eeprom(struct vge_softc *, int); 321static uint16_t vge_read_eeprom(struct vge_softc *, int);
322 322
323static void vge_miipoll_start(struct vge_softc *); 323static void vge_miipoll_start(struct vge_softc *);
324static void vge_miipoll_stop(struct vge_softc *); 324static void vge_miipoll_stop(struct vge_softc *);
325static int vge_miibus_readreg(device_t, int, int, uint16_t *); 325static int vge_miibus_readreg(device_t, int, int, uint16_t *);
326static int vge_miibus_writereg(device_t, int, int, uint16_t); 326static int vge_miibus_writereg(device_t, int, int, uint16_t);
327static void vge_miibus_statchg(struct ifnet *); 327static void vge_miibus_statchg(struct ifnet *);
328 328
329static void vge_cam_clear(struct vge_softc *); 329static void vge_cam_clear(struct vge_softc *);
330static int vge_cam_set(struct vge_softc *, uint8_t *); 330static int vge_cam_set(struct vge_softc *, uint8_t *);
 331static void vge_clrwol(struct vge_softc *);
331static void vge_setmulti(struct vge_softc *); 332static void vge_setmulti(struct vge_softc *);
332static void vge_reset(struct vge_softc *); 333static void vge_reset(struct vge_softc *);
333 334
334CFATTACH_DECL_NEW(vge, sizeof(struct vge_softc), 335CFATTACH_DECL_NEW(vge, sizeof(struct vge_softc),
335 vge_match, vge_attach, NULL, NULL); 336 vge_match, vge_attach, NULL, NULL);
336 337
337static inline void 338static inline void
338vge_set_txaddr(struct vge_txfrag *f, bus_addr_t daddr) 339vge_set_txaddr(struct vge_txfrag *f, bus_addr_t daddr)
339{ 340{
340 341
341 f->tf_addrlo = htole32((uint32_t)daddr); 342 f->tf_addrlo = htole32((uint32_t)daddr);
342 if (sizeof(bus_addr_t) == sizeof(uint64_t)) 343 if (sizeof(bus_addr_t) == sizeof(uint64_t))
343 f->tf_addrhi = htole16(((uint64_t)daddr >> 32) & 0xFFFF); 344 f->tf_addrhi = htole16(((uint64_t)daddr >> 32) & 0xFFFF);
@@ -943,26 +944,29 @@ vge_attach(device_t parent, device_t sel @@ -943,26 +944,29 @@ vge_attach(device_t parent, device_t sel
943 val = vge_read_eeprom(sc, VGE_EE_EADDR + 0); 944 val = vge_read_eeprom(sc, VGE_EE_EADDR + 0);
944 eaddr[0] = val & 0xff; 945 eaddr[0] = val & 0xff;
945 eaddr[1] = val >> 8; 946 eaddr[1] = val >> 8;
946 val = vge_read_eeprom(sc, VGE_EE_EADDR + 1); 947 val = vge_read_eeprom(sc, VGE_EE_EADDR + 1);
947 eaddr[2] = val & 0xff; 948 eaddr[2] = val & 0xff;
948 eaddr[3] = val >> 8; 949 eaddr[3] = val >> 8;
949 val = vge_read_eeprom(sc, VGE_EE_EADDR + 2); 950 val = vge_read_eeprom(sc, VGE_EE_EADDR + 2);
950 eaddr[4] = val & 0xff; 951 eaddr[4] = val & 0xff;
951 eaddr[5] = val >> 8; 952 eaddr[5] = val >> 8;
952 953
953 aprint_normal_dev(self, "Ethernet address %s\n", 954 aprint_normal_dev(self, "Ethernet address %s\n",
954 ether_sprintf(eaddr)); 955 ether_sprintf(eaddr));
955 956
 957 /* Clear WOL and take hardware from powerdown. */
 958 vge_clrwol(sc);
 959
956 /* 960 /*
957 * Use the 32bit tag. Hardware supports 48bit physical addresses, 961 * Use the 32bit tag. Hardware supports 48bit physical addresses,
958 * but we don't use that for now. 962 * but we don't use that for now.
959 */ 963 */
960 sc->sc_dmat = pa->pa_dmat; 964 sc->sc_dmat = pa->pa_dmat;
961 965
962 if (vge_allocmem(sc) != 0) 966 if (vge_allocmem(sc) != 0)
963 return; 967 return;
964 968
965 ifp = &sc->sc_ethercom.ec_if; 969 ifp = &sc->sc_ethercom.ec_if;
966 ifp->if_softc = sc; 970 ifp->if_softc = sc;
967 strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); 971 strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
968 ifp->if_mtu = ETHERMTU; 972 ifp->if_mtu = ETHERMTU;
@@ -2146,13 +2150,40 @@ vge_resume(device_t dev) @@ -2146,13 +2150,40 @@ vge_resume(device_t dev)
2146 * Stop all chip I/O so that the kernel's probe routines don't 2150 * Stop all chip I/O so that the kernel's probe routines don't
2147 * get confused by errant DMAs when rebooting. 2151 * get confused by errant DMAs when rebooting.
2148 */ 2152 */
2149static bool 2153static bool
2150vge_shutdown(device_t self, int howto) 2154vge_shutdown(device_t self, int howto)
2151{ 2155{
2152 struct vge_softc *sc; 2156 struct vge_softc *sc;
2153 2157
2154 sc = device_private(self); 2158 sc = device_private(self);
2155 vge_stop(&sc->sc_ethercom.ec_if, 1); 2159 vge_stop(&sc->sc_ethercom.ec_if, 1);
2156 2160
2157 return true; 2161 return true;
2158} 2162}
 2163
 2164static void
 2165vge_clrwol(struct vge_softc *sc)
 2166{
 2167 uint8_t val;
 2168
 2169 val = CSR_READ_1(sc, VGE_PWRSTAT);
 2170 val &= ~VGE_STICKHW_SWPTAG;
 2171 CSR_WRITE_1(sc, VGE_PWRSTAT, val);
 2172 /* Disable WOL and clear power state indicator. */
 2173 val = CSR_READ_1(sc, VGE_PWRSTAT);
 2174 val &= ~(VGE_STICKHW_DS0 | VGE_STICKHW_DS1);
 2175 CSR_WRITE_1(sc, VGE_PWRSTAT, val);
 2176
 2177 CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_GMII);
 2178 CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_MACFORCE);
 2179
 2180 /* Clear WOL on pattern match. */
 2181 CSR_WRITE_1(sc, VGE_WOLCR0C, VGE_WOLCR0_PATTERN_ALL);
 2182 /* Disable WOL on magic/unicast packet. */
 2183 CSR_WRITE_1(sc, VGE_WOLCR1C, 0x0F);
 2184 CSR_WRITE_1(sc, VGE_WOLCFGC, VGE_WOLCFG_SAB | VGE_WOLCFG_SAM |
 2185 VGE_WOLCFG_PMEOVR);
 2186 /* Clear WOL status on pattern match. */
 2187 CSR_WRITE_1(sc, VGE_WOLSR0C, 0xFF);
 2188 CSR_WRITE_1(sc, VGE_WOLSR1C, 0xFF);
 2189}

cvs diff -r1.4 -r1.5 src/sys/dev/pci/if_vgereg.h (expand / switch to unified diff)

--- src/sys/dev/pci/if_vgereg.h 2019/07/11 03:49:51 1.4
+++ src/sys/dev/pci/if_vgereg.h 2019/10/08 14:26:27 1.5
@@ -530,26 +530,51 @@ @@ -530,26 +530,51 @@
530#define VGE_TXCFG_SNAPOPT 0x01 /* 1 == insert VLAN tag at 530#define VGE_TXCFG_SNAPOPT 0x01 /* 1 == insert VLAN tag at
531 13th byte 531 13th byte
532 0 == insert VLANM tag after 532 0 == insert VLANM tag after
533 SNAP header (21st byte) */ 533 SNAP header (21st byte) */
534#define VGE_TXCFG_NONBLK 0x02 /* priority TX/non-blocking mode */ 534#define VGE_TXCFG_NONBLK 0x02 /* priority TX/non-blocking mode */
535#define VGE_TXCFG_NONBLK_THR 0x0C /* non-blocking threshold */ 535#define VGE_TXCFG_NONBLK_THR 0x0C /* non-blocking threshold */
536#define VGE_TXCFG_ARB_PRIO 0x80 /* arbitration priority */ 536#define VGE_TXCFG_ARB_PRIO 0x80 /* arbitration priority */
537 537
538#define VGE_TXBLOCK_64PKTS 0x00 538#define VGE_TXBLOCK_64PKTS 0x00
539#define VGE_TXBLOCK_32PKTS 0x04 539#define VGE_TXBLOCK_32PKTS 0x04
540#define VGE_TXBLOCK_128PKTS 0x08 540#define VGE_TXBLOCK_128PKTS 0x08
541#define VGE_TXBLOCK_8PKTS 0x0C 541#define VGE_TXBLOCK_8PKTS 0x0C
542 542
 543/* Sticky bit shadow register */
 544
 545#define VGE_STICKHW_DS0 0x01
 546#define VGE_STICKHW_DS1 0x02
 547#define VGE_STICKHW_WOL_ENB 0x04
 548#define VGE_STICKHW_WOL_STS 0x08
 549#define VGE_STICKHW_SWPTAG 0x10
 550
 551/* WOL pattern control */
 552#define VGE_WOLCR0_PATTERN0 0x01
 553#define VGE_WOLCR0_PATTERN1 0x02
 554#define VGE_WOLCR0_PATTERN2 0x04
 555#define VGE_WOLCR0_PATTERN3 0x08
 556#define VGE_WOLCR0_PATTERN4 0x10
 557#define VGE_WOLCR0_PATTERN5 0x20
 558#define VGE_WOLCR0_PATTERN6 0x40
 559#define VGE_WOLCR0_PATTERN7 0x80
 560#define VGE_WOLCR0_PATTERN_ALL 0xFF
 561
 562/* WOL config register */
 563#define VGE_WOLCFG_PHYINT_ENB 0x01
 564#define VGE_WOLCFG_SAB 0x10
 565#define VGE_WOLCFG_SAM 0x20
 566#define VGE_WOLCFG_PMEOVR 0x80
 567
543/* EEPROM control/status register */ 568/* EEPROM control/status register */
544 569
545#define VGE_EECSR_EDO 0x01 /* data out pin */ 570#define VGE_EECSR_EDO 0x01 /* data out pin */
546#define VGE_EECSR_EDI 0x02 /* data in pin */ 571#define VGE_EECSR_EDI 0x02 /* data in pin */
547#define VGE_EECSR_ECK 0x04 /* clock pin */ 572#define VGE_EECSR_ECK 0x04 /* clock pin */
548#define VGE_EECSR_ECS 0x08 /* chip select pin */ 573#define VGE_EECSR_ECS 0x08 /* chip select pin */
549#define VGE_EECSR_DPM 0x10 /* direct program mode enable */ 574#define VGE_EECSR_DPM 0x10 /* direct program mode enable */
550#define VGE_EECSR_RELOAD 0x20 /* trigger reload from EEPROM */ 575#define VGE_EECSR_RELOAD 0x20 /* trigger reload from EEPROM */
551#define VGE_EECSR_EMBP 0x40 /* embedded program mode enable */ 576#define VGE_EECSR_EMBP 0x40 /* embedded program mode enable */
552 577
553/* EEPROM embedded command register */ 578/* EEPROM embedded command register */
554 579
555#define VGE_EECMD_ERD 0x01 /* EEPROM read command */ 580#define VGE_EECMD_ERD 0x01 /* EEPROM read command */