Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-6]: src/sys/dev/pci Pull up following revision(s) (requested by t...
details: https://anonhg.NetBSD.org/src/rev/0bcbb3c65887
branches: netbsd-6
changeset: 775634:0bcbb3c65887
user: riz <riz%NetBSD.org@localhost>
date: Fri Feb 08 19:35:23 2013 +0000
description:
Pull up following revision(s) (requested by taca in ticket #783):
sys/dev/pci/if_vr.c: revision 1.112
- reset the chip if the tx engine gets stuck after a link state change,
from OpenBSD
- no need to do a full reset of the chip when enabling or disabling
promiscuous mode
diffstat:
sys/dev/pci/if_vr.c | 95 ++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 76 insertions(+), 19 deletions(-)
diffs (162 lines):
diff -r 73c3b72f7331 -r 0bcbb3c65887 sys/dev/pci/if_vr.c
--- a/sys/dev/pci/if_vr.c Fri Feb 08 19:32:07 2013 +0000
+++ b/sys/dev/pci/if_vr.c Fri Feb 08 19:35:23 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vr.c,v 1.110 2012/02/02 19:43:05 tls Exp $ */
+/* $NetBSD: if_vr.c,v 1.110.2.1 2013/02/08 19:35:23 riz Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vr.c,v 1.110 2012/02/02 19:43:05 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vr.c,v 1.110.2.1 2013/02/08 19:35:23 riz Exp $");
@@ -231,6 +231,11 @@
uint32_t vr_save_membase;
uint32_t vr_save_irq;
+ bool vr_link;
+ int vr_flags;
+#define VR_F_RESTART 0x1 /* restart on next tick */
+ int vr_if_flags;
+
krndsource_t rnd_source; /* random source */
};
@@ -399,21 +404,44 @@
vr_mii_statchg(device_t self)
{
struct vr_softc *sc = device_private(self);
+ int i;
/*
* In order to fiddle with the 'full-duplex' bit in the netconfig
* register, we first have to put the transmit and/or receive logic
* in the idle state.
*/
- VR_CLRBIT16(sc, VR_COMMAND, (VR_CMD_TX_ON|VR_CMD_RX_ON));
+ if ((sc->vr_mii.mii_media_status & IFM_ACTIVE) &&
+ IFM_SUBTYPE(sc->vr_mii.mii_media_active) != IFM_NONE) {
+ sc->vr_link = true;
+
+ if (CSR_READ_2(sc, VR_COMMAND) & (VR_CMD_TX_ON|VR_CMD_RX_ON))
+ VR_CLRBIT16(sc, VR_COMMAND,
+ (VR_CMD_TX_ON|VR_CMD_RX_ON));
+
+ if (sc->vr_mii.mii_media_active & IFM_FDX)
+ VR_SETBIT16(sc, VR_COMMAND, VR_CMD_FULLDUPLEX);
+ else
+ VR_CLRBIT16(sc, VR_COMMAND, VR_CMD_FULLDUPLEX);
- if (sc->vr_mii.mii_media_active & IFM_FDX)
- VR_SETBIT16(sc, VR_COMMAND, VR_CMD_FULLDUPLEX);
- else
- VR_CLRBIT16(sc, VR_COMMAND, VR_CMD_FULLDUPLEX);
-
- if (sc->vr_ec.ec_if.if_flags & IFF_RUNNING)
VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_ON|VR_CMD_RX_ON);
+ } else {
+ sc->vr_link = false;
+ VR_CLRBIT16(sc, VR_COMMAND, VR_CMD_TX_ON|VR_CMD_RX_ON);
+ for (i = VR_TIMEOUT; i > 0; i--) {
+ delay(10);
+ if (!(CSR_READ_2(sc, VR_COMMAND) &
+ (VR_CMD_TX_ON|VR_CMD_RX_ON)))
+ break;
+ }
+ if (i == 0) {
+#ifdef VR_DEBUG
+ printf("%s: rx shutdown error!\n",
+ device_xname(sc->vr_dev));
+#endif
+ sc->vr_flags |= VR_F_RESTART;
+ }
+ }
}
#define vr_calchash(addr) \
@@ -979,6 +1007,11 @@
struct vr_descsoft *ds;
int error, firsttx, nexttx, opending;
+ if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
+ return;
+ if (sc->vr_link == false)
+ return;
+
/*
* Remember the previous txpending and the first transmit
* descriptor we use.
@@ -1228,6 +1261,7 @@
CSR_WRITE_4(sc, VR_TXADDR, VR_CDTXADDR(sc, VR_NEXTTX(sc->vr_txlast)));
/* Set current media. */
+ sc->vr_link = true;
if ((error = ether_mediachange(ifp)) != 0)
goto out;
@@ -1263,19 +1297,37 @@
s = splnet();
- error = ether_ioctl(ifp, command, data);
- if (error == ENETRESET) {
- /*
- * Multicast list has changed; set the hardware filter
- * accordingly.
- */
- if (ifp->if_flags & IFF_RUNNING)
+ switch (command) {
+ case SIOCSIFFLAGS:
+ if ((error = ifioctl_common(ifp, command, data)) != 0)
+ break;
+
+ switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
+ case IFF_RUNNING:
+ vr_stop(ifp, 1);
+ break;
+ case IFF_UP:
+ vr_init(ifp);
+ break;
+ case IFF_UP | IFF_RUNNING:
+ if ((ifp->if_flags ^ sc->vr_if_flags) == IFF_PROMISC)
+ vr_setmulti(sc);
+ else
+ vr_init(ifp);
+ break;
+ }
+ sc->vr_if_flags = ifp->if_flags;
+ break;
+ default:
+ if ((error = ether_ioctl(ifp, command, data)) != ENETRESET)
+ break;
+ error = 0;
+ if (command == SIOCADDMULTI || command == SIOCDELMULTI)
vr_setmulti(sc);
- error = 0;
}
+ splx(s);
- splx(s);
- return (error);
+ return error;
}
static void
@@ -1299,6 +1351,11 @@
int s;
s = splnet();
+ if (sc->vr_flags & VR_F_RESTART) {
+ printf("%s: restarting\n", device_xname(sc->vr_dev));
+ vr_init(&sc->vr_ec.ec_if);
+ sc->vr_flags &= ~VR_F_RESTART;
+ }
mii_tick(&sc->vr_mii);
splx(s);
Home |
Main Index |
Thread Index |
Old Index