Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-9]: src/sys/dev/pci Pull up following revision(s) (requested by k...
details: https://anonhg.NetBSD.org/src/rev/32854a4ad2df
branches: netbsd-9
changeset: 964179:32854a4ad2df
user: martin <martin%NetBSD.org@localhost>
date: Wed Nov 04 11:48:26 2020 +0000
description:
Pull up following revision(s) (requested by knakahara in ticket #1126):
sys/dev/pci/if_wm.c: revision 1.694
sys/dev/pci/if_wm.c: revision 1.695 (via patch)
sys/dev/pci/if_wmvar.h: revision 1.47
Add WMPHY_I350. Not used yet.
Workaround for ihphy and atphy(ICH*/PCH*, 82580 and I350).
These phys stop DMA while link is down which causes device timeout.
Fix PR/kern 40981
Reviewed and tested by msaitoh@n.o, thanks.
XXX pullup-[89]
diffstat:
sys/dev/pci/if_wm.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++-
sys/dev/pci/if_wmvar.h | 7 +-
2 files changed, 124 insertions(+), 7 deletions(-)
diffs (241 lines):
diff -r 5a41c463b8a2 -r 32854a4ad2df sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Sun Nov 01 18:03:21 2020 +0000
+++ b/sys/dev/pci/if_wm.c Wed Nov 04 11:48:26 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.645.2.8 2020/10/16 08:03:36 martin Exp $ */
+/* $NetBSD: if_wm.c,v 1.645.2.9 2020/11/04 11:48:26 martin 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.645.2.8 2020/10/16 08:03:36 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.645.2.9 2020/11/04 11:48:26 martin Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -375,7 +375,8 @@
* to manage Tx H/W queue's busy flag.
*/
int txq_flags; /* flags for H/W queue, see below */
-#define WM_TXQ_NO_SPACE 0x1
+#define WM_TXQ_NO_SPACE 0x1
+#define WM_TXQ_LINKDOWN_DISCARD 0x2
bool txq_stopping;
@@ -1031,6 +1032,9 @@
static int wm_platform_pm_pch_lpt(struct wm_softc *, bool);
static int wm_pll_workaround_i210(struct wm_softc *);
static void wm_legacy_irq_quirk_spt(struct wm_softc *);
+static bool wm_phy_need_linkdown_discard(struct wm_softc *);
+static void wm_set_linkdown_discard(struct wm_softc *);
+static void wm_clear_linkdown_discard(struct wm_softc *);
CFATTACH_DECL3_NEW(wm, sizeof(struct wm_softc),
wm_match, wm_attach, wm_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
@@ -3077,6 +3081,9 @@
sc->sc_txrx_use_workqueue = false;
+ if (wm_phy_need_linkdown_discard(sc))
+ wm_set_linkdown_discard(sc);
+
wm_init_sysctls(sc);
if (pmf_device_register(self, wm_suspend, wm_resume))
@@ -3455,6 +3462,49 @@
return rc;
}
+static bool
+wm_phy_need_linkdown_discard(struct wm_softc *sc)
+{
+
+ switch(sc->sc_phytype) {
+ case WMPHY_82577: /* ihphy */
+ case WMPHY_82578: /* atphy */
+ case WMPHY_82579: /* ihphy */
+ case WMPHY_I217: /* ihphy */
+ case WMPHY_82580: /* ihphy */
+ case WMPHY_I350: /* ihphy */
+ return true;
+ default:
+ return false;
+ }
+}
+
+static void
+wm_set_linkdown_discard(struct wm_softc *sc)
+{
+
+ for (int i = 0; i < sc->sc_nqueues; i++) {
+ struct wm_txqueue *txq = &sc->sc_queue[i].wmq_txq;
+
+ mutex_enter(txq->txq_lock);
+ txq->txq_flags |= WM_TXQ_LINKDOWN_DISCARD;
+ mutex_exit(txq->txq_lock);
+ }
+}
+
+static void
+wm_clear_linkdown_discard(struct wm_softc *sc)
+{
+
+ for (int i = 0; i < sc->sc_nqueues; i++) {
+ struct wm_txqueue *txq = &sc->sc_queue[i].wmq_txq;
+
+ mutex_enter(txq->txq_lock);
+ txq->txq_flags &= ~WM_TXQ_LINKDOWN_DISCARD;
+ mutex_exit(txq->txq_lock);
+ }
+}
+
/*
* wm_ioctl: [ifnet interface function]
*
@@ -3498,6 +3548,12 @@
#ifdef WM_MPSAFE
splx(s);
#endif
+ if (error == 0 && wm_phy_need_linkdown_discard(sc)) {
+ if (IFM_SUBTYPE(ifr->ifr_media) == IFM_NONE)
+ wm_set_linkdown_discard(sc);
+ else
+ wm_clear_linkdown_discard(sc);
+ }
break;
case SIOCINITIFADDR:
WM_CORE_LOCK(sc);
@@ -3512,8 +3568,17 @@
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)) {
+ wm_set_linkdown_discard(sc);
+ }
+ }
#ifdef WM_MPSAFE
s = splnet();
#endif
@@ -7627,6 +7692,16 @@
return ((cpuid + ncpu - sc->sc_affinity_offset) % ncpu) % sc->sc_nqueues;
}
+static inline bool
+wm_linkdown_discard(struct wm_txqueue *txq)
+{
+
+ if ((txq->txq_flags & WM_TXQ_LINKDOWN_DISCARD) != 0)
+ return true;
+
+ return false;
+}
+
/*
* wm_start: [ifnet interface function]
*
@@ -7721,6 +7796,23 @@
if ((txq->txq_flags & WM_TXQ_NO_SPACE) != 0)
return;
+ if (__predict_false(wm_linkdown_discard(txq))) {
+ do {
+ if (is_transmit)
+ m0 = pcq_get(txq->txq_interq);
+ else
+ IFQ_DEQUEUE(&ifp->if_snd, m0);
+ /*
+ * increment successed packet counter as in the case
+ * which the packet is discarded by link down PHY.
+ */
+ if (m0 != NULL)
+ ifp->if_opackets++;
+ m_freem(m0);
+ } while (m0 != NULL);
+ return;
+ }
+
/* Remember the previous number of free descriptors. */
ofree = txq->txq_free;
@@ -8330,6 +8422,23 @@
if ((txq->txq_flags & WM_TXQ_NO_SPACE) != 0)
return;
+ if (__predict_false(wm_linkdown_discard(txq))) {
+ do {
+ if (is_transmit)
+ m0 = pcq_get(txq->txq_interq);
+ else
+ IFQ_DEQUEUE(&ifp->if_snd, m0);
+ /*
+ * increment successed packet counter as in the case
+ * which the packet is discarded by link down PHY.
+ */
+ if (m0 != NULL)
+ ifp->if_opackets++;
+ m_freem(m0);
+ } while (m0 != NULL);
+ return;
+ }
+
sent = false;
/*
@@ -9201,7 +9310,11 @@
DPRINTF(WM_DEBUG_LINK, ("%s: LINK: LSC -> up %s\n",
device_xname(dev),
(status & STATUS_FD) ? "FDX" : "HDX"));
+ if (wm_phy_need_linkdown_discard(sc))
+ wm_clear_linkdown_discard(sc);
} else {
+ if (wm_phy_need_linkdown_discard(sc))
+ wm_set_linkdown_discard(sc);
DPRINTF(WM_DEBUG_LINK, ("%s: LINK: LSC -> down\n",
device_xname(dev)));
}
@@ -10251,8 +10364,11 @@
new_phytype = WMPHY_I217;
break;
case MII_MODEL_INTEL_I82580:
+ new_phytype = WMPHY_82580;
+ break;
case MII_MODEL_INTEL_I350:
- new_phytype = WMPHY_82580;
+ new_phytype = WMPHY_I350;
+ break;
break;
default:
break;
diff -r 5a41c463b8a2 -r 32854a4ad2df sys/dev/pci/if_wmvar.h
--- a/sys/dev/pci/if_wmvar.h Sun Nov 01 18:03:21 2020 +0000
+++ b/sys/dev/pci/if_wmvar.h Wed Nov 04 11:48:26 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wmvar.h,v 1.44.4.2 2020/09/23 08:46:54 martin Exp $ */
+/* $NetBSD: if_wmvar.h,v 1.44.4.3 2020/11/04 11:48:26 martin Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -198,9 +198,10 @@
WMPHY_BM, /* 82567: ICH8 ICH9 ICH10 */
WMPHY_82578, /* 82578: PCH */
WMPHY_82577, /* 82577: PCH (NOTE: functionality newer than 82578) */
- WMPHY_82579, /* 82579 : PCH2 */
+ WMPHY_82579, /* 82579: PCH2 */
WMPHY_I217, /* I217: _LPT, I218: _LPT, I219: _SPT _CNP */
- WMPHY_82580, /* 82580: 82580 or I350 */
+ WMPHY_82580, /* 82580 */
+ WMPHY_I350, /* I350 */
WMPHY_VF,
WMPHY_I210 /* I210: I210 I211 */
} wm_phy_type;
Home |
Main Index |
Thread Index |
Old Index