* interface must be reset (down/up) for it
* to take effect.
*/
-static int xn_enable_lro = 1;
+static int xn_enable_lro = 0;
TUNABLE_INT("hw.xn.enable_lro", &xn_enable_lro);
/*
while ((m = mbufq_dequeue(&rxq)) != NULL) {
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
+ /* XXX Setting flowid breaks the stream, need
+ * to investigate more.
+ */
+ /* m->m_pkthdr.flowid = queue->num; */
+ /* M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); */
+
/*
* Do we really need to drop the rx lock?
*/
#else
(*ifp->if_input)(ifp, m);
#endif
+
XN_RX_LOCK(queue);
}
return (err);
}
+#ifndef XN_LEGACY_TX
+static int
+xn_txq_mq_start(struct ifnet *ifp, struct mbuf *m)
+{
+ struct netfront_info *np;
+ struct netfront_queue_info *queue;
+ int i, npairs, error;
+ int notify;
+
+ np = ifp->if_softc;
+ npairs = np->num_queues;
+
+ /* check if flowid is set */
+ if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE)
+ i = m->m_pkthdr.flowid % npairs;
+ else
+ i = curcpu % npairs;
+
+ queue = &np->queue[i];
+
+ XN_TX_LOCK(queue);
+
+ /*
+ * XXX should just drop or push to deferred queue if not slots
+ * are available.
+ */
+ if (xn_tx_slot_available(queue)) {
+ error = xn_assemble_tx_request(queue, m);
+
+ RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&queue->tx, notify);
+ if (notify)
+ xen_intr_signal(queue->xen_intr_handle);
+ } else {
+ error = ENOMEM; /* XXX not the right errno */
+ m_freem(m);
+ }
+
+ if (RING_FULL(&queue->tx))
+ queue->tx_full = 1;
+
+ XN_TX_UNLOCK(queue);
+
+ return (error);
+}
+
+static void
+xn_qflush(struct ifnet *ifp)
+{
+ if_qflush(ifp);
+}
+#endif
+
/**
* Create a network device.
* @param dev Newbus device representing this virtual NIC.
if_initname(ifp, "xn", device_get_unit(dev));
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = xn_ioctl;
+
+#ifndef XN_LEGACY_TX
+ ifp->if_transmit = xn_txq_mq_start;
+ ifp->if_qflush = xn_qflush;
+#else
ifp->if_start = xn_start;
+ ifp->if_snd.ifq_drv_maxlen = NET_TX_RING_SIZE - 1;
+ IFQ_SET_MAXLEN(&ifp->if_snd, NET_TX_RING_SIZE - 1);
+ IFQ_SET_READY(&ifp->if_snd);
+#endif
+
#ifdef notyet
ifp->if_watchdog = xn_watchdog;
#endif
ifp->if_init = xn_ifinit;
- ifp->if_snd.ifq_maxlen = NET_TX_RING_SIZE - 1;
ifp->if_hwassist = XN_CSUM_FEATURES;
ifp->if_capabilities = IFCAP_HWCSUM;