void octeon_eth_start(struct ifnet *ifp) { struct octeon_eth_softc *sc = ifp->if_softc; struct mbuf *m; /* * performance tuning * presend iobdma request */ octeon_eth_send_queue_flush_prefetch(sc); if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd)) goto last; if (__predict_false(!cn30xxgmx_link_status(sc->sc_gmx_port))) goto last; for (;;) { octeon_eth_send_queue_flush_fetch(sc); /* XXX */ /* * XXXSEIL * If no free send buffer is available, free all the sent buffer * and bail out. */ if (octeon_eth_send_queue_is_full(sc)) { return; } /* XXX */ IFQ_DEQUEUE(&ifp->if_snd, m); if (m == NULL) return; #if NBPFILTER > 0 if (ifp->if_bpf != NULL) bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); #endif /* XXX */ if (ml_len(&sc->sc_sendq) > sc->sc_soft_req_thresh) octeon_eth_send_queue_flush(sc); if (octeon_eth_send(sc, m)) { ifp->if_oerrors++; m_freem(m); log(LOG_WARNING, "%s: failed to transmit packet\n", sc->sc_dev.dv_xname); } /* XXX */ /* * send next iobdma request */ octeon_eth_send_queue_flush_prefetch(sc); } last: octeon_eth_send_queue_flush_fetch(sc); }
void octeon_eth_start(struct ifnet *ifp) { struct octeon_eth_softc *sc = ifp->if_softc; struct mbuf *m; /* * performance tuning * presend iobdma request */ octeon_eth_send_queue_flush_prefetch(sc); if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) goto last; /* XXX assume that OCTEON doesn't buffer packets */ if (__predict_false(!cn30xxgmx_link_status(sc->sc_gmx_port))) { /* dequeue and drop them */ while (1) { IFQ_DEQUEUE(&ifp->if_snd, m); if (m == NULL) break; #if 0 #ifdef DDB m_print(m, "cd", printf); #endif printf("%s: drop\n", sc->sc_dev.dv_xname); #endif m_freem(m); IF_DROP(&ifp->if_snd); } goto last; } for (;;) { IFQ_POLL(&ifp->if_snd, m); if (__predict_false(m == NULL)) break; octeon_eth_send_queue_flush_fetch(sc); /* XXX */ /* * XXXSEIL * If no free send buffer is available, free all the sent buffer * and bail out. */ if (octeon_eth_send_queue_is_full(sc)) { return; } /* XXX */ IFQ_DEQUEUE(&ifp->if_snd, m); OCTEON_ETH_TAP(ifp, m, BPF_DIRECTION_OUT); /* XXX */ if (sc->sc_soft_req_cnt > sc->sc_soft_req_thresh) octeon_eth_send_queue_flush(sc); if (octeon_eth_send(sc, m)) { ifp->if_oerrors++; m_freem(m); log(LOG_WARNING, "%s: failed to transmit packet\n", sc->sc_dev.dv_xname); } else { sc->sc_soft_req_cnt++; } if (sc->sc_flush) octeon_eth_send_queue_flush_sync(sc); /* XXX */ /* * send next iobdma request */ octeon_eth_send_queue_flush_prefetch(sc); } /* * XXXSEIL * Don't schedule send-buffer-free callout every time - those buffers are freed * by "free tick". This makes some packets like NFS slower, but it normally * doesn't happen on SEIL. */ #ifdef OCTEON_ETH_USENFS if (__predict_false(sc->sc_ext_callback_cnt > 0)) { int timo; /* ??? */ timo = hz - (100 * sc->sc_ext_callback_cnt); if (timo < 10) timo = 10; callout_schedule(&sc->sc_tick_free_ch, timo); } #endif last: octeon_eth_send_queue_flush_fetch(sc); }