[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 */