diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-11-24 14:21:27 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-11-24 14:21:27 +0000 |
commit | 901b3cc08d323c2ac56e911613a501e1bfd828ed (patch) | |
tree | 185b6542e8107661256e7e002ad796c85d01793a /sys | |
parent | 24ea18d3074a089c24ffc62af769447d02be92d8 (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.c | 20 |
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)) |