summaryrefslogtreecommitdiffstats
path: root/sys/dev/sk
diff options
context:
space:
mode:
authorjmg <jmg@FreeBSD.org>2004-11-15 19:37:21 +0000
committerjmg <jmg@FreeBSD.org>2004-11-15 19:37:21 +0000
commit079e5a8053bea01154a0d15506fad08b72beb28b (patch)
tree98cec7c72d4b46e1ca451b8e10ef4d43d9895c63 /sys/dev/sk
parentec2edfc1aecdac7754677942fe24d4d6e8ba56c5 (diff)
downloadFreeBSD-src-079e5a8053bea01154a0d15506fad08b72beb28b.zip
FreeBSD-src-079e5a8053bea01154a0d15506fad08b72beb28b.tar.gz
fix the missing lock in sk_jfree (verified w/ an assert)
also fix up handling and proding of the tx, _OACTIVE is now handled better... Submitted by: Peter Edwards (sk_jfree) Obtained from: OpenBSD and/or NetBSD (tx prod)
Diffstat (limited to 'sys/dev/sk')
-rw-r--r--sys/dev/sk/if_sk.c32
-rw-r--r--sys/dev/sk/if_skreg.h1
2 files changed, 23 insertions, 10 deletions
diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c
index 7f577d7..2bc4f15 100644
--- a/sys/dev/sk/if_sk.c
+++ b/sys/dev/sk/if_sk.c
@@ -1075,9 +1075,11 @@ sk_jalloc(sc_if)
struct sk_if_softc *sc_if;
{
struct sk_jpool_entry *entry;
-
+
+ SK_IF_LOCK_ASSERT(sc_if);
+
entry = SLIST_FIRST(&sc_if->sk_jfree_listhead);
-
+
if (entry == NULL) {
#ifdef SK_VERBOSE
printf("sk%d: no free jumbo buffers\n", sc_if->sk_unit);
@@ -1104,6 +1106,7 @@ sk_jfree(buf, args)
/* Extract the softc struct pointer. */
sc_if = (struct sk_if_softc *)args;
+ SK_IF_LOCK(sc_if);
if (sc_if == NULL)
panic("sk_jfree: didn't get softc pointer!");
@@ -1122,6 +1125,7 @@ sk_jfree(buf, args)
SLIST_REMOVE_HEAD(&sc_if->sk_jinuse_listhead, jpool_entries);
SLIST_INSERT_HEAD(&sc_if->sk_jfree_listhead, entry, jpool_entries);
+ SK_IF_UNLOCK(sc_if);
return;
}
@@ -1781,6 +1785,8 @@ sk_encap(sc_if, m_head, txidx)
struct mbuf *m;
u_int32_t frag, cur, cnt = 0;
+ SK_IF_LOCK_ASSERT(sc_if);
+
m = m_head;
cur = frag = *txidx;
@@ -1861,11 +1867,13 @@ sk_start(ifp)
}
/* Transmit */
- sc_if->sk_cdata.sk_tx_prod = idx;
- CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
+ if (idx != sc_if->sk_cdata.sk_tx_prod) {
+ sc_if->sk_cdata.sk_tx_prod = idx;
+ CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
- /* Set a timeout in case the chip goes out to lunch. */
- ifp->if_timer = 5;
+ /* Set a timeout in case the chip goes out to lunch. */
+ ifp->if_timer = 5;
+ }
SK_IF_UNLOCK(sc_if);
return;
@@ -1982,10 +1990,12 @@ static void
sk_txeof(sc_if)
struct sk_if_softc *sc_if;
{
+ struct sk_softc *sc;
struct sk_tx_desc *cur_tx = NULL;
struct ifnet *ifp;
u_int32_t idx;
+ sc = sc_if->sk_softc;
ifp = &sc_if->arpcom.ac_if;
/*
@@ -2005,13 +2015,15 @@ sk_txeof(sc_if)
}
sc_if->sk_cdata.sk_tx_cnt--;
SK_INC(idx, SK_TX_RING_CNT);
- ifp->if_timer = 0;
}
- sc_if->sk_cdata.sk_tx_cons = idx;
-
- if (cur_tx != NULL)
+ if (sc_if->sk_cdata.sk_tx_cnt == 0) {
+ ifp->if_timer = 0;
ifp->if_flags &= ~IFF_OACTIVE;
+ } else /* nudge chip to keep tx ring moving */
+ CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
+
+ sc_if->sk_cdata.sk_tx_cons = idx;
return;
}
diff --git a/sys/dev/sk/if_skreg.h b/sys/dev/sk/if_skreg.h
index 8271c03..b70e172 100644
--- a/sys/dev/sk/if_skreg.h
+++ b/sys/dev/sk/if_skreg.h
@@ -1442,6 +1442,7 @@ struct sk_softc {
#define SK_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sk_mtx, MA_OWNED)
#define SK_IF_LOCK(_sc) SK_LOCK((_sc)->sk_softc)
#define SK_IF_UNLOCK(_sc) SK_UNLOCK((_sc)->sk_softc)
+#define SK_IF_LOCK_ASSERT(_sc) SK_LOCK_ASSERT((_sc)->sk_softc)
/* Softc for each logical interface */
struct sk_if_softc {
OpenPOWER on IntegriCloud