summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2009-11-24 14:21:27 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2009-11-24 14:21:27 +0000
commit901b3cc08d323c2ac56e911613a501e1bfd828ed (patch)
tree185b6542e8107661256e7e002ad796c85d01793a /sys
parent24ea18d3074a089c24ffc62af769447d02be92d8 (diff)
for MCLGETI to work correctly drivers need to first dequeue all available
packets and then refill the RX ring. When not done this way the rx ring can not grow correctly. Tested by jmc@, OK deraadt@, kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_msk.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/sys/dev/pci/if_msk.c b/sys/dev/pci/if_msk.c
index b61bfe13cff..5ee135bb7dc 100644
--- a/sys/dev/pci/if_msk.c
+++ b/sys/dev/pci/if_msk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_msk.c,v 1.80 2009/11/24 14:18:21 claudio Exp $ */
+/* $OpenBSD: if_msk.c,v 1.81 2009/11/24 14:21:26 claudio Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@@ -982,6 +982,7 @@ msk_attach(struct device *parent, struct device *self, void *aux)
*/
if_attach(ifp);
ether_ifattach(ifp);
+ m_clsetwms(ifp, sc_if->sk_pktlen, 2, MSK_RX_RING_CNT);
sc_if->sk_sdhook = shutdownhook_establish(mskc_shutdown, sc);
@@ -1740,7 +1741,7 @@ msk_intr(void *xsc)
struct sk_if_softc *sc_if0 = sc->sk_if[SK_PORT_A];
struct sk_if_softc *sc_if1 = sc->sk_if[SK_PORT_B];
struct ifnet *ifp0 = NULL, *ifp1 = NULL;
- int claimed = 0;
+ int claimed = 0, rx[2] = {0, 0};
u_int32_t status;
struct msk_status_desc *cur_st;
@@ -1778,11 +1779,9 @@ msk_intr(void *xsc)
switch (cur_st->sk_opcode) {
case SK_Y2_STOPC_RXSTAT:
sc_if = sc->sk_if[cur_st->sk_link & 0x01];
+ rx[cur_st->sk_link & 0x01] = 1;
msk_rxeof(sc_if, letoh16(cur_st->sk_len),
letoh32(cur_st->sk_status));
- msk_fill_rx_ring(sc_if);
- SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_PUTIDX,
- sc_if->sk_cdata.sk_rx_prod);
break;
case SK_Y2_STOPC_TXSTAT:
if (sc_if0)
@@ -1808,6 +1807,17 @@ msk_intr(void *xsc)
CSR_WRITE_4(sc, SK_Y2_ICR, 2);
+ if (rx[0]) {
+ msk_fill_rx_ring(sc_if0);
+ SK_IF_WRITE_2(sc_if0, 0, SK_RXQ1_Y2_PREF_PUTIDX,
+ sc_if0->sk_cdata.sk_rx_prod);
+ }
+ if (rx[1]) {
+ msk_fill_rx_ring(sc_if1);
+ SK_IF_WRITE_2(sc_if1, 0, SK_RXQ1_Y2_PREF_PUTIDX,
+ sc_if1->sk_cdata.sk_rx_prod);
+ }
+
if (ifp0 != NULL && !IFQ_IS_EMPTY(&ifp0->if_snd))
msk_start(ifp0);
if (ifp1 != NULL && !IFQ_IS_EMPTY(&ifp1->if_snd))