[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ALTQ/FreeBSD] ti(4), sk(4) ALTQ driver for FreeBSD 5.2R



Hello All,

FreeBSD-ALTQ's main weak-point is lack of ALTQ enabled network
drivers. If users don't have NICs listed on ATLQ enabled drivers,
they can't try and we have no feedback. This is a kind of
chicken-egg problem. I'm not kernel guru nor device driver
expert but it is really easy to make ALTQ enabled network
drivers. For example, I believe almost all Bill Paul's driver
can be converted without much efforts.
(Some paseudo drivers like tun(4) are not easy, though.)
So if you have a NIC not yet supported by FreeBSD-ALTQ and know
C language you can make ALTQ enabled driver for that NIC.

Here is patch for ALTQ drivers sk(4) and ti(4).
For Bill Paul's driver, almost the same approach can be used.
I don't have these cards so can't test it at the moment.
However, at least, we may get complaing report.

Thank you.
Regards,
Pyun YongHyeon
-- 
Pyun YongHyeon <http://www.kr.freebsd.org/~yongari>
--- sys/pci/if_sk.c.ORG	Sun Nov 30 04:33:01 2003
+++ sys/pci/if_sk.c	Mon Jan 19 17:01:51 2004
@@ -1413,7 +1413,8 @@
 	ifp->if_watchdog = sk_watchdog;
 	ifp->if_init = sk_init;
 	ifp->if_baudrate = 1000000000;
-	ifp->if_snd.ifq_maxlen = SK_TX_RING_CNT - 1;
+	IFQ_SET_MAXLEN(&ifp->if_snd, SK_TX_RING_CNT - 1);
+	IFQ_SET_READY(&ifp->if_snd);
 
 	callout_handle_init(&sc_if->sk_tick_ch);
 
@@ -1756,6 +1757,7 @@
         struct sk_if_softc	*sc_if;
         struct mbuf		*m_head = NULL;
         u_int32_t		idx;
+	int			pkts = 0;
 
 	sc_if = ifp->if_softc;
 	sc = sc_if->sk_softc;
@@ -1765,9 +1767,12 @@
 	idx = sc_if->sk_cdata.sk_tx_prod;
 
 	while(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) {
-		IF_DEQUEUE(&ifp->if_snd, m_head);
-		if (m_head == NULL)
+		IFQ_LOCK(&ifp->if_snd);
+		IFQ_POLL_NOLOCK(&ifp->if_snd, m_head);
+		if (m_head == NULL) {
+			IFQ_UNLOCK(&ifp->if_snd);
 			break;
+		}
 
 		/*
 		 * Pack the data into the transmit ring. If we
@@ -1775,11 +1780,16 @@
 		 * for the NIC to drain the ring.
 		 */
 		if (sk_encap(sc_if, m_head, &idx)) {
-			IF_PREPEND(&ifp->if_snd, m_head);
+			IFQ_UNLOCK(&ifp->if_snd);
 			ifp->if_flags |= IFF_OACTIVE;
 			break;
 		}
 
+		/* now we are committed to transmit the packet */
+		IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m_head);
+		IFQ_UNLOCK(&ifp->if_snd);
+		pkts++;
+
 		/*
 		 * If there's a BPF listener, bounce a copy of this frame
 		 * to him.
@@ -1787,6 +1797,11 @@
 		BPF_MTAP(ifp, m_head);
 	}
 
+	if (pkts == 0) {
+		SK_IF_UNLOCK(sc_if);
+		return;
+	}
+
 	/* Transmit */
 	sc_if->sk_cdata.sk_tx_prod = idx;
 	CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
@@ -2172,9 +2187,9 @@
 
 	CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
 
-	if (ifp0 != NULL && ifp0->if_snd.ifq_head != NULL)
+	if (ifp0 != NULL && !IFQ_IS_EMPTY(&ifp0->if_snd))
 		sk_start(ifp0);
-	if (ifp1 != NULL && ifp1->if_snd.ifq_head != NULL)
+	if (ifp1 != NULL && !IFQ_IS_EMPTY(&ifp1->if_snd))
 		sk_start(ifp1);
 
 	SK_UNLOCK(sc);
--- sys/pci/if_ti.c.ORG	Sat Nov 15 04:00:32 2003
+++ sys/pci/if_ti.c	Mon Jan 19 17:01:45 2004
@@ -2196,7 +2196,8 @@
 	ifp->if_watchdog = ti_watchdog;
 	ifp->if_init = ti_init;
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_snd.ifq_maxlen = TI_TX_RING_CNT - 1;
+	IFQ_SET_MAXLEN(&ifp->if_snd, TI_TX_RING_CNT - 1);
+	IFQ_SET_READY(&ifp->if_snd);
 
 	/* Set up ifmedia support. */
 	if (sc->ti_copper) {
@@ -2584,7 +2585,7 @@
 	/* Re-enable interrupts. */
 	CSR_WRITE_4(sc, TI_MB_HOSTINTR, 0);
 
-	if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL)
+	if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
 		ti_start(ifp);
 
 	TI_UNLOCK(sc);
@@ -2720,6 +2721,7 @@
 	struct ti_softc		*sc;
 	struct mbuf		*m_head = NULL;
 	u_int32_t		prodidx = 0;
+	int			pkts = 0;
 
 	sc = ifp->if_softc;
 	TI_LOCK(sc);
@@ -2727,9 +2729,12 @@
 	prodidx = CSR_READ_4(sc, TI_MB_SENDPROD_IDX);
 
 	while(sc->ti_cdata.ti_tx_chain[prodidx] == NULL) {
-		IF_DEQUEUE(&ifp->if_snd, m_head);
-		if (m_head == NULL)
+		IFQ_LOCK(&ifp->if_snd);
+		IFQ_POLL_NOLOCK(&ifp->if_snd, m_head);
+		if (m_head == NULL) {
+			IFQ_UNLOCK(&ifp->if_snd);
 			break;
+		}
 
 		/*
 		 * XXX
@@ -2743,7 +2748,7 @@
 		    m_head->m_pkthdr.csum_flags & (CSUM_DELAY_DATA)) {
 			if ((TI_TX_RING_CNT - sc->ti_txcnt) <
 			    m_head->m_pkthdr.csum_data + 16) {
-				IF_PREPEND(&ifp->if_snd, m_head);
+				IFQ_UNLOCK(&ifp->if_snd);
 				ifp->if_flags |= IFF_OACTIVE;
 				break;
 			}
@@ -2755,16 +2760,26 @@
 		 * for the NIC to drain the ring.
 		 */
 		if (ti_encap(sc, m_head, &prodidx)) {
-			IF_PREPEND(&ifp->if_snd, m_head);
+			IFQ_UNLOCK(&ifp->if_snd);
 			ifp->if_flags |= IFF_OACTIVE;
 			break;
 		}
 
+		/* now we are committed to transmit the packet */
+		IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m_head);
+		IFQ_UNLOCK(&ifp->if_snd);
+		pkts++;
+
 		/*
 		 * If there's a BPF listener, bounce a copy of this frame
 		 * to him.
 		 */
 		BPF_MTAP(ifp, m_head);
+	}
+
+	if (pkts == 0) {
+		TI_UNLOCK(sc);
+		return;
 	}
 
 	/* Transmit */