if msk runs out of mbufs, the rx ring remains empty and there's
nothing except an ifconfig down and up to get it going again.

this adds a timeout to refill the ring. it's largely copied from
other drivers (vr in this case).

tests? ok?

Index: if_mskvar.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_mskvar.h,v
retrieving revision 1.13
diff -u -p -r1.13 if_mskvar.h
--- if_mskvar.h 2 Jun 2017 01:47:36 -0000       1.13
+++ if_mskvar.h 23 Oct 2017 01:32:04 -0000
@@ -212,6 +212,7 @@ struct sk_if_softc {
        int                     sk_pktlen;
        int                     sk_link;
        struct timeout          sk_tick_ch;
+       struct timeout          sk_tick_rx;
        struct msk_chain_data   sk_cdata;
        struct msk_ring_data    *sk_rdata;
        bus_dmamap_t            sk_ring_map;
Index: if_msk.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_msk.c,v
retrieving revision 1.130
diff -u -p -r1.130 if_msk.c
--- if_msk.c    3 Oct 2017 15:37:58 -0000       1.130
+++ if_msk.c    23 Oct 2017 01:32:04 -0000
@@ -148,7 +148,7 @@ void msk_ifmedia_sts(struct ifnet *, str
 int msk_newbuf(struct sk_if_softc *);
 int msk_init_rx_ring(struct sk_if_softc *);
 int msk_init_tx_ring(struct sk_if_softc *);
-void msk_fill_rx_ring(struct sk_if_softc *);
+void msk_fill_rx_ring(struct sk_if_softc *, int);
 
 int msk_miibus_readreg(struct device *, int, int);
 void msk_miibus_writereg(struct device *, int, int, int);
@@ -156,6 +156,7 @@ void msk_miibus_statchg(struct device *)
 
 void msk_iff(struct sk_if_softc *);
 void msk_tick(void *);
+void msk_fill_rx_tick(void *);
 
 #ifdef MSK_DEBUG
 #define DPRINTF(x)     if (mskdebug) printf x
@@ -428,7 +429,7 @@ msk_init_rx_ring(struct sk_if_softc *sc_
        /* two ring entries per packet, so the effective ring size is halved */
        if_rxr_init(&sc_if->sk_cdata.sk_rx_ring, 2, MSK_RX_RING_CNT/2);
 
-       msk_fill_rx_ring(sc_if);
+       msk_fill_rx_ring(sc_if, 0);
        return (0);
 }
 
@@ -1027,6 +1028,7 @@ msk_attach(struct device *parent, struct
                ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_AUTO);
 
        timeout_set(&sc_if->sk_tick_ch, msk_tick, sc_if);
+       timeout_set(&sc_if->sk_tick_rx, msk_fill_rx_tick, sc_if);
 
        /*
         * Call MI attach routines.
@@ -1779,7 +1781,7 @@ msk_txeof(struct sk_if_softc *sc_if)
 }
 
 void
-msk_fill_rx_ring(struct sk_if_softc *sc_if)
+msk_fill_rx_ring(struct sk_if_softc *sc_if, int ticks)
 {
        u_int slots, used;
 
@@ -1792,6 +1794,20 @@ msk_fill_rx_ring(struct sk_if_softc *sc_
                slots -= used;
        }
        if_rxr_put(&sc_if->sk_cdata.sk_rx_ring, slots);
+       if (if_rxr_inuse(&sc_if->sk_cdata.sk_rx_ring) == 0)
+               timeout_add(&sc_if->sk_tick_rx, ticks);
+}
+
+void
+msk_fill_rx_tick(void *xsc_if)
+{
+       struct sk_if_softc *sc_if = xsc_if;
+       int s;
+
+       s = splnet();
+       if (if_rxr_inuse(&sc_if->sk_cdata.sk_rx_ring) == 0)
+               msk_fill_rx_ring(sc_if, 1);
+       splx(s);
 }
 
 void
@@ -1902,12 +1918,12 @@ msk_intr(void *xsc)
        CSR_WRITE_4(sc, SK_Y2_ICR, 2);
 
        if (rx[0]) {
-               msk_fill_rx_ring(sc_if0);
+               msk_fill_rx_ring(sc_if0, 0);
                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);
+               msk_fill_rx_ring(sc_if1, 0);
                SK_IF_WRITE_2(sc_if1, 0, SK_RXQ1_Y2_PREF_PUTIDX,
                    sc_if1->sk_cdata.sk_rx_prod);
        }

Reply via email to