git: 1a6d987b7f32 - main - enetc: Wait for pending transmissions before disabling TX queues
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 31 Jan 2022 08:00:04 UTC
The branch main has been updated by wma:
URL: https://cgit.FreeBSD.org/src/commit/?id=1a6d987b7f32d6e93ef1dd75bed0335d4e6c91fa
commit 1a6d987b7f32d6e93ef1dd75bed0335d4e6c91fa
Author: Kornel Duleba <mindal@semihalf.com>
AuthorDate: 2022-01-27 10:25:25 +0000
Commit: Wojciech Macek <wma@FreeBSD.org>
CommitDate: 2022-01-31 07:57:48 +0000
enetc: Wait for pending transmissions before disabling TX queues
According to the RM it's not safe to disable a TX ring while it is busy
transmitting frames.
In order to be safe wait until the ring is empty. (cidx==pidx)
Use this opportunity to remove a set-but-unused variable.
Obtained from: Semihalf
Sponsored by: Alstom Group
---
sys/dev/enetc/if_enetc.c | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/sys/dev/enetc/if_enetc.c b/sys/dev/enetc/if_enetc.c
index 75c582e81696..0f2f3a9d1270 100644
--- a/sys/dev/enetc/if_enetc.c
+++ b/sys/dev/enetc/if_enetc.c
@@ -364,7 +364,6 @@ enetc_setup_phy(struct enetc_softc *sc)
static int
enetc_attach_pre(if_ctx_t ctx)
{
- struct ifnet *ifp;
if_softc_ctx_t scctx;
struct enetc_softc *sc;
int error, rid;
@@ -374,7 +373,6 @@ enetc_attach_pre(if_ctx_t ctx)
sc->ctx = ctx;
sc->dev = iflib_get_dev(ctx);
sc->shared = scctx;
- ifp = iflib_get_ifp(ctx);
mtx_init(&sc->mii_lock, "enetc_mdio", NULL, MTX_DEF);
@@ -958,6 +956,29 @@ enetc_init(if_ctx_t ctx)
enetc_promisc_set(ctx, if_getflags(ifp));
}
+static void
+enetc_disable_txq(struct enetc_softc *sc, int qid)
+{
+ qidx_t cidx, pidx;
+ int timeout = 10000; /* this * DELAY(100) = 1s */
+
+ /* At this point iflib shouldn't be enquing any more frames. */
+ pidx = ENETC_TXQ_RD4(sc, qid, ENETC_TBPIR);
+ cidx = ENETC_TXQ_RD4(sc, qid, ENETC_TBCIR);
+
+ while (pidx != cidx && timeout--) {
+ DELAY(100);
+ cidx = ENETC_TXQ_RD4(sc, qid, ENETC_TBCIR);
+ }
+
+ if (timeout == 0)
+ device_printf(sc->dev,
+ "Timeout while waiting for txq%d to stop transmitting packets\n",
+ qid);
+
+ ENETC_TXQ_WR4(sc, qid, ENETC_TBMR, 0);
+}
+
static void
enetc_stop(if_ctx_t ctx)
{
@@ -966,11 +987,11 @@ enetc_stop(if_ctx_t ctx)
sc = iflib_get_softc(ctx);
- for (i = 0; i < sc->tx_num_queues; i++)
- ENETC_TXQ_WR4(sc, i, ENETC_TBMR, 0);
-
for (i = 0; i < sc->rx_num_queues; i++)
ENETC_RXQ_WR4(sc, i, ENETC_RBMR, 0);
+
+ for (i = 0; i < sc->tx_num_queues; i++)
+ enetc_disable_txq(sc, i);
}
static int