summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authormsaitoh <msaitoh@NetBSD.org>2021-11-05 05:52:49 +0000
committermsaitoh <msaitoh@NetBSD.org>2021-11-05 05:52:49 +0000
commitb2e346e0be7bbde80d8a85f30640415dd5a41555 (patch)
tree1fc068ad9d2aa24d4e39059a4f8bea562296d0d1 /sys/dev
parent8aae1fb0dc23bc9bddb610bee22c03dcfea0c925 (diff)
Fix a bug that device timeout still happens on ICH/PCH. Fixes PR kern/56478.
- if_wm.c rev. 1.695 for PR kern/40981 still had a problem. The workaround flag was unexpectedly cleared when a cable is not connected, SIOCINITIFADDR was called, or if_init was called. Fix it. - Add debug printf()s.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_wm.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/sys/dev/pci/if_wm.c b/sys/dev/pci/if_wm.c
index 9073d7acc58..a81f2c28460 100644
--- a/sys/dev/pci/if_wm.c
+++ b/sys/dev/pci/if_wm.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.717 2021/11/05 01:49:14 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.718 2021/11/05 05:52:49 msaitoh Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -82,7 +82,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.717 2021/11/05 01:49:14 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.718 2021/11/05 05:52:49 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -3154,8 +3154,12 @@ alloc_retry:
sc->sc_txrx_use_workqueue = false;
- if (wm_phy_need_linkdown_discard(sc))
+ if (wm_phy_need_linkdown_discard(sc)) {
+ DPRINTF(sc, WM_DEBUG_LINK,
+ ("%s: %s: Set linkdown discard flag\n",
+ device_xname(sc->sc_dev), __func__));
wm_set_linkdown_discard(sc);
+ }
wm_init_sysctls(sc);
@@ -3625,10 +3629,12 @@ wm_ioctl(struct ifnet *ifp, u_long cmd, void *data)
WM_CORE_UNLOCK(sc);
error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
if (error == 0 && wm_phy_need_linkdown_discard(sc)) {
- if (IFM_SUBTYPE(ifr->ifr_media) == IFM_NONE)
+ if (IFM_SUBTYPE(ifr->ifr_media) == IFM_NONE) {
+ DPRINTF(sc, WM_DEBUG_LINK,
+ ("%s: %s: Set linkdown discard flag\n",
+ device_xname(sc->sc_dev), __func__));
wm_set_linkdown_discard(sc);
- else
- wm_clear_linkdown_discard(sc);
+ }
}
break;
case SIOCINITIFADDR:
@@ -3644,14 +3650,14 @@ wm_ioctl(struct ifnet *ifp, u_long cmd, void *data)
break;
}
WM_CORE_UNLOCK(sc);
- if (((ifp->if_flags & IFF_UP) == 0) && wm_phy_need_linkdown_discard(sc))
- wm_clear_linkdown_discard(sc);
/*FALLTHROUGH*/
default:
if (cmd == SIOCSIFFLAGS && wm_phy_need_linkdown_discard(sc)) {
- if (((ifp->if_flags & IFF_UP) == 0) && ((ifr->ifr_flags & IFF_UP) != 0)) {
- wm_clear_linkdown_discard(sc);
- } else if (((ifp->if_flags & IFF_UP) != 0) && ((ifr->ifr_flags & IFF_UP) == 0)) {
+ if (((ifp->if_flags & IFF_UP) != 0) &&
+ ((ifr->ifr_flags & IFF_UP) == 0)) {
+ DPRINTF(sc, WM_DEBUG_LINK,
+ ("%s: %s: Set linkdown discard flag\n",
+ device_xname(sc->sc_dev), __func__));
wm_set_linkdown_discard(sc);
}
}
@@ -7479,7 +7485,9 @@ wm_init_tx_queue(struct wm_softc *sc, struct wm_queue *wmq,
wm_init_tx_regs(sc, wmq, txq);
wm_init_tx_buffer(sc, txq);
- txq->txq_flags = 0; /* Clear WM_TXQ_NO_SPACE */
+ /* Clear other than WM_TXQ_LINKDOWN_DISCARD */
+ txq->txq_flags &= WM_TXQ_LINKDOWN_DISCARD;
+
txq->txq_sending = false;
}
@@ -9490,13 +9498,21 @@ wm_linkintr_gmii(struct wm_softc *sc, uint32_t icr)
DPRINTF(sc, WM_DEBUG_LINK, ("%s: LINK: LSC -> up %s\n",
device_xname(dev),
(status & STATUS_FD) ? "FDX" : "HDX"));
- if (wm_phy_need_linkdown_discard(sc))
+ if (wm_phy_need_linkdown_discard(sc)) {
+ DPRINTF(sc, WM_DEBUG_LINK,
+ ("%s: linkintr: Clear linkdown discard flag\n",
+ device_xname(dev)));
wm_clear_linkdown_discard(sc);
+ }
} else {
DPRINTF(sc, WM_DEBUG_LINK, ("%s: LINK: LSC -> down\n",
device_xname(dev)));
- if (wm_phy_need_linkdown_discard(sc))
+ if (wm_phy_need_linkdown_discard(sc)) {
+ DPRINTF(sc, WM_DEBUG_LINK,
+ ("%s: linkintr: Set linkdown discard flag\n",
+ device_xname(dev)));
wm_set_linkdown_discard(sc);
+ }
}
if ((sc->sc_type == WM_T_ICH8) && (link == false))
wm_gig_downshift_workaround_ich8lan(sc);