svn commit: r186593 - user/kmacy/HEAD_fast_net/sys/dev/mxge
Kip Macy
kmacy at FreeBSD.org
Tue Dec 30 05:35:54 UTC 2008
Author: kmacy
Date: Tue Dec 30 05:35:54 2008
New Revision: 186593
URL: http://svn.freebsd.org/changeset/base/186593
Log:
import multiple tx queue support from HEAD_fast_multi_xmit
Modified:
user/kmacy/HEAD_fast_net/sys/dev/mxge/if_mxge.c
user/kmacy/HEAD_fast_net/sys/dev/mxge/if_mxge_var.h
Modified: user/kmacy/HEAD_fast_net/sys/dev/mxge/if_mxge.c
==============================================================================
--- user/kmacy/HEAD_fast_net/sys/dev/mxge/if_mxge.c Tue Dec 30 05:35:27 2008 (r186592)
+++ user/kmacy/HEAD_fast_net/sys/dev/mxge/if_mxge.c Tue Dec 30 05:35:54 2008 (r186593)
@@ -30,6 +30,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#define IFNET_MULTIQUEUE
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/linker.h>
@@ -66,6 +68,9 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/in_cksum.h>
#include <machine/resource.h>
+#ifdef IFNET_MULTIQUEUE
+#include <sys/buf_ring.h>
+#endif
#include <sys/bus.h>
#include <sys/rman.h>
#include <sys/smp.h>
@@ -1207,6 +1212,9 @@ mxge_reset(mxge_softc_t *sc, int interru
*/
cmd.data0 = sc->num_slices;
cmd.data1 = MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE;
+#ifdef IFNET_MULTIQUEUE
+ cmd.data1 |= MXGEFW_SLICE_ENABLE_MULTIPLE_TX_QUEUES;
+#endif
status = mxge_send_cmd(sc, MXGEFW_CMD_ENABLE_RSS_QUEUES,
&cmd);
if (status != 0) {
@@ -1266,6 +1274,9 @@ mxge_reset(mxge_softc_t *sc, int interru
ss->tx.req = 0;
ss->tx.done = 0;
ss->tx.pkt_done = 0;
+ ss->tx.queue_active = 0;
+ ss->tx.activate = 0;
+ ss->tx.deactivate = 0;
ss->tx.wake = 0;
ss->tx.defrag = 0;
ss->tx.stall = 0;
@@ -1598,10 +1609,6 @@ mxge_add_sysctls(mxge_softc_t *sc)
"rx_big_cnt",
CTLFLAG_RD, &ss->rx_big.cnt,
0, "rx_small_cnt");
- SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "tx_req",
- CTLFLAG_RD, &ss->tx.req,
- 0, "tx_req");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
"lro_flushed", CTLFLAG_RD, &ss->lro_flushed,
0, "number of lro merge queues flushed");
@@ -1611,9 +1618,15 @@ mxge_add_sysctls(mxge_softc_t *sc)
0, "number of frames appended to lro merge"
"queues");
+#ifndef IFNET_MULTIQUEUE
/* only transmit from slice 0 for now */
if (slice > 0)
continue;
+#endif
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO,
+ "tx_req",
+ CTLFLAG_RD, &ss->tx.req,
+ 0, "tx_req");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
"tx_done",
@@ -1635,6 +1648,18 @@ mxge_add_sysctls(mxge_softc_t *sc)
"tx_defrag",
CTLFLAG_RD, &ss->tx.defrag,
0, "tx_defrag");
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO,
+ "tx_queue_active",
+ CTLFLAG_RD, &ss->tx.queue_active,
+ 0, "tx_queue_active");
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO,
+ "tx_activate",
+ CTLFLAG_RD, &ss->tx.activate,
+ 0, "tx_activate");
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO,
+ "tx_deactivate",
+ CTLFLAG_RD, &ss->tx.deactivate,
+ 0, "tx_deactivate");
}
}
@@ -1857,12 +1882,21 @@ mxge_encap_tso(struct mxge_slice_state *
tx->info[((cnt - 1) + tx->req) & tx->mask].flag = 1;
mxge_submit_req(tx, tx->req_list, cnt);
+#ifdef IFNET_MULTIQUEUE
+ if ((ss->sc->num_slices > 1) && tx->queue_active == 0) {
+ /* tell the NIC to start polling this slice */
+ *tx->send_go = 1;
+ tx->queue_active = 1;
+ tx->activate++;
+ wmb();
+ }
+#endif
return;
drop:
bus_dmamap_unload(tx->dmat, tx->info[tx->req & tx->mask].map);
m_freem(m);
- ss->sc->ifp->if_oerrors++;
+ ss->oerrors++;
if (!once) {
printf("tx->max_desc exceeded via TSO!\n");
printf("mss = %d, %ld, %d!\n", mss,
@@ -2059,16 +2093,114 @@ mxge_encap(struct mxge_slice_state *ss,
#endif
tx->info[((cnt - 1) + tx->req) & tx->mask].flag = 1;
mxge_submit_req(tx, tx->req_list, cnt);
+#ifdef IFNET_MULTIQUEUE
+ if ((ss->sc->num_slices > 1) && tx->queue_active == 0) {
+ /* tell the NIC to start polling this slice */
+ *tx->send_go = 1;
+ tx->queue_active = 1;
+ tx->activate++;
+ wmb();
+ }
+#endif
return;
drop:
m_freem(m);
- ifp->if_oerrors++;
+ ss->oerrors++;
return;
}
+#ifdef IFNET_MULTIQUEUE
+static inline void
+mxge_start_locked(struct mxge_slice_state *ss)
+{
+ mxge_softc_t *sc;
+ struct mbuf *m;
+ struct ifnet *ifp;
+ mxge_tx_ring_t *tx;
+
+ sc = ss->sc;
+ ifp = sc->ifp;
+ tx = &ss->tx;
+
+ while (((tx->mask - (tx->req - tx->done)) > tx->max_desc)
+ && (!buf_ring_empty(tx->br))) {
+ m = buf_ring_dequeue_sc(tx->br);
+ if (m == NULL) {
+ return;
+ }
+ /* let BPF see it */
+ BPF_MTAP(ifp, m);
+
+ /* give it to the nic */
+ mxge_encap(ss, m);
+ }
+ /* ran out of transmit slots */
+ if (((ss->if_drv_flags & IFF_DRV_OACTIVE) == 0)
+ && (!buf_ring_empty(tx->br))) {
+ ss->if_drv_flags |= IFF_DRV_OACTIVE;
+ tx->stall++;
+ }
+}
+
+static int
+mxge_transmit_locked(struct mxge_slice_state *ss, struct mbuf *m)
+{
+ mxge_softc_t *sc;
+ struct ifnet *ifp;
+ mxge_tx_ring_t *tx;
+ int err;
+
+ sc = ss->sc;
+ ifp = sc->ifp;
+ tx = &ss->tx;
+
+ if ((ss->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING) {
+ err = drbr_enqueue(ifp, tx->br, m);
+ return (err);
+ }
+
+ if (buf_ring_empty(tx->br) &&
+ ((tx->mask - (tx->req - tx->done)) > tx->max_desc)) {
+ /* let BPF see it */
+ BPF_MTAP(ifp, m);
+ /* give it to the nic */
+ mxge_encap(ss, m);
+ } else if ((err = drbr_enqueue(ifp, tx->br, m)) != 0) {
+ return (err);
+ }
+ if (!buf_ring_empty(tx->br))
+ mxge_start_locked(ss);
+ return (0);
+}
+
+static int
+mxge_transmit(struct ifnet *ifp, struct mbuf *m)
+{
+ mxge_softc_t *sc = ifp->if_softc;
+ struct mxge_slice_state *ss;
+ mxge_tx_ring_t *tx;
+ int err = 0;
+ int slice;
+
+ slice = m->m_pkthdr.flowid;
+
+ slice &= (sc->num_slices - 1); /* num_slices always power of 2 */
+ ss = &sc->ss[slice];
+ tx = &ss->tx;
+ if (mtx_trylock(&tx->mtx)) {
+ err = mxge_transmit_locked(ss, m);
+ mtx_unlock(&tx->mtx);
+ } else {
+ err = drbr_enqueue(ifp, tx->br, m);
+ }
+ return (err);
+}
+
+#else
static inline void
mxge_start_locked(struct mxge_slice_state *ss)
@@ -2098,7 +2230,7 @@ mxge_start_locked(struct mxge_slice_stat
tx->stall++;
}
}
-
+#endif
static void
mxge_start(struct ifnet *ifp)
{
@@ -2349,6 +2481,7 @@ mxge_rx_done_big(struct mxge_slice_state
m->m_data += MXGEFW_PAD;
m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.flowid = ss - sc->ss;
m->m_len = m->m_pkthdr.len = len;
ss->ipackets++;
eh = mtod(m, struct ether_header *);
@@ -2409,6 +2542,7 @@ mxge_rx_done_small(struct mxge_slice_sta
m->m_data += MXGEFW_PAD;
m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.flowid = ss - sc->ss;
m->m_len = m->m_pkthdr.len = len;
ss->ipackets++;
eh = mtod(m, struct ether_header *);
@@ -2470,6 +2604,7 @@ mxge_tx_done(struct mxge_slice_state *ss
struct mbuf *m;
bus_dmamap_t map;
int idx;
+ int *flags;
tx = &ss->tx;
ifp = ss->sc->ifp;
@@ -2480,7 +2615,12 @@ mxge_tx_done(struct mxge_slice_state *ss
/* mbuf and DMA map only attached to the first
segment per-mbuf */
if (m != NULL) {
- ifp->if_opackets++;
+#ifdef IFNET_MULTIQUEUE
+ ss->obytes += m->m_pkthdr.len;
+ if (m->m_flags & M_MCAST)
+ ss->omcasts++;
+#endif
+ ss->opackets++;
tx->info[idx].m = NULL;
map = tx->info[idx].map;
bus_dmamap_unload(tx->dmat, map);
@@ -2494,15 +2634,33 @@ mxge_tx_done(struct mxge_slice_state *ss
/* If we have space, clear IFF_OACTIVE to tell the stack that
its OK to send packets */
-
- if (ifp->if_drv_flags & IFF_DRV_OACTIVE &&
+#ifdef IFNET_MULTIQUEUE
+ flags = &ss->if_drv_flags;
+#else
+ flags = &ifp->if_drv_flags;
+#endif
+ mtx_lock(&ss->tx.mtx);
+ if ((*flags) & IFF_DRV_OACTIVE &&
tx->req - tx->done < (tx->mask + 1)/4) {
- mtx_lock(&ss->tx.mtx);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ *(flags) &= ~IFF_DRV_OACTIVE;
ss->tx.wake++;
mxge_start_locked(ss);
- mtx_unlock(&ss->tx.mtx);
}
+#ifdef IFNET_MULTIQUEUE
+ if ((ss->sc->num_slices > 1) && (tx->req == tx->done)) {
+ /* let the NIC stop polling this queue, since there
+ * are no more transmits pending */
+ if (tx->req == tx->done) {
+ *tx->send_stop = 1;
+ tx->queue_active = 0;
+ tx->deactivate++;
+ wmb();
+ }
+ }
+ mtx_unlock(&ss->tx.mtx);
+
+#endif
+
}
static struct mxge_media_type mxge_media_types[] =
@@ -2653,6 +2811,7 @@ mxge_intr(void *arg)
uint8_t valid;
+#ifndef IFNET_MULTIQUEUE
/* an interrupt on a non-zero slice is implicitly valid
since MSI-X irqs are not shared */
if (ss != sc->ss) {
@@ -2660,6 +2819,7 @@ mxge_intr(void *arg)
*ss->irq_claim = be32toh(3);
return;
}
+#endif
/* make sure the DMA has finished */
if (!stats->valid) {
@@ -2683,7 +2843,8 @@ mxge_intr(void *arg)
send_done_count = be32toh(stats->send_done_count);
while ((send_done_count != tx->pkt_done) ||
(rx_done->entry[rx_done->idx].length != 0)) {
- mxge_tx_done(ss, (int)send_done_count);
+ if (send_done_count != tx->pkt_done)
+ mxge_tx_done(ss, (int)send_done_count);
mxge_clean_rx_done(ss);
send_done_count = be32toh(stats->send_done_count);
}
@@ -2691,7 +2852,8 @@ mxge_intr(void *arg)
wmb();
} while (*((volatile uint8_t *) &stats->valid));
- if (__predict_false(stats->stats_updated)) {
+ /* fw stats meaningful only on the first slice */
+ if (__predict_false((ss == sc->ss) && stats->stats_updated)) {
if (sc->link_state != stats->link_up) {
sc->link_state = stats->link_up;
if (sc->link_state) {
@@ -2980,11 +3142,11 @@ mxge_alloc_slice_rings(struct mxge_slice
}
/* now allocate TX resouces */
-
+#ifndef IFNET_MULTIQUEUE
/* only use a single TX ring for now */
if (ss != ss->sc->ss)
return 0;
-
+#endif
ss->tx.mask = tx_ring_entries - 1;
ss->tx.max_desc = MIN(MXGE_MAX_SEND_DESC, tx_ring_entries / 4);
@@ -3149,13 +3311,21 @@ mxge_slice_open(struct mxge_slice_state
/* get the lanai pointers to the send and receive rings */
err = 0;
+#ifndef IFNET_MULTIQUEUE
/* We currently only send from the first slice */
if (slice == 0) {
+#endif
cmd.data0 = slice;
err = mxge_send_cmd(sc, MXGEFW_CMD_GET_SEND_OFFSET, &cmd);
ss->tx.lanai =
(volatile mcp_kreq_ether_send_t *)(sc->sram + cmd.data0);
+ ss->tx.send_go = (volatile uint32_t *)
+ (sc->sram + MXGEFW_ETH_SEND_GO + 64 * slice);
+ ss->tx.send_stop = (volatile uint32_t *)
+ (sc->sram + MXGEFW_ETH_SEND_STOP + 64 * slice);
+#ifndef IFNET_MULTIQUEUE
}
+#endif
cmd.data0 = slice;
err |= mxge_send_cmd(sc,
MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd);
@@ -3207,6 +3377,7 @@ mxge_open(mxge_softc_t *sc)
int err, big_bytes, nbufs, slice, cl_size, i;
bus_addr_t bus;
volatile uint8_t *itable;
+ struct mxge_slice_state *ss;
/* Copy the MAC address in case it was overridden */
bcopy(IF_LLADDR(sc->ifp), sc->mac_addr, ETHER_ADDR_LEN);
@@ -3276,10 +3447,22 @@ mxge_open(mxge_softc_t *sc)
}
/* Now give him the pointer to the stats block */
- cmd.data0 = MXGE_LOWPART_TO_U32(sc->ss->fw_stats_dma.bus_addr);
- cmd.data1 = MXGE_HIGHPART_TO_U32(sc->ss->fw_stats_dma.bus_addr);
- cmd.data2 = sizeof(struct mcp_irq_data);
- err = mxge_send_cmd(sc, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd);
+ for (slice = 0;
+#ifdef IFNET_MULTIQUEUE
+ slice < sc->num_slices;
+#else
+ slice < 1;
+#endif
+ slice++) {
+ ss = &sc->ss[slice];
+ cmd.data0 =
+ MXGE_LOWPART_TO_U32(ss->fw_stats_dma.bus_addr);
+ cmd.data1 =
+ MXGE_HIGHPART_TO_U32(ss->fw_stats_dma.bus_addr);
+ cmd.data2 = sizeof(struct mcp_irq_data);
+ cmd.data2 |= (slice << 16);
+ err |= mxge_send_cmd(sc, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd);
+ }
if (err != 0) {
bus = sc->ss->fw_stats_dma.bus_addr;
@@ -3315,8 +3498,16 @@ mxge_open(mxge_softc_t *sc)
device_printf(sc->dev, "Couldn't bring up link\n");
goto abort;
}
+#ifdef IFNET_MULTIQUEUE
+ for (slice = 0; slice < sc->num_slices; slice++) {
+ ss = &sc->ss[slice];
+ ss->if_drv_flags |= IFF_DRV_RUNNING;
+ ss->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ }
+#endif
sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc);
return 0;
@@ -3333,8 +3524,18 @@ mxge_close(mxge_softc_t *sc)
{
mxge_cmd_t cmd;
int err, old_down_cnt;
+#ifdef IFNET_MULTIQUEUE
+ struct mxge_slice_state *ss;
+ int slice;
+#endif
callout_stop(&sc->co_hdl);
+#ifdef IFNET_MULTIQUEUE
+ for (slice = 0; slice < sc->num_slices; slice++) {
+ ss = &sc->ss[slice];
+ ss->if_drv_flags &= ~IFF_DRV_RUNNING;
+ }
+#endif
sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
old_down_cnt = sc->down_cnt;
wmb();
@@ -3400,9 +3601,10 @@ mxge_read_reboot(mxge_softc_t *sc)
}
static int
-mxge_watchdog_reset(mxge_softc_t *sc)
+mxge_watchdog_reset(mxge_softc_t *sc, int slice)
{
struct pci_devinfo *dinfo;
+ mxge_tx_ring_t *tx;
int err;
uint32_t reboot;
uint16_t cmd;
@@ -3449,11 +3651,17 @@ mxge_watchdog_reset(mxge_softc_t *sc)
err = mxge_open(sc);
}
} else {
- device_printf(sc->dev, "NIC did not reboot, ring state:\n");
- device_printf(sc->dev, "tx.req=%d tx.done=%d\n",
- sc->ss->tx.req, sc->ss->tx.done);
+ tx = &sc->ss[slice].tx;
+ device_printf(sc->dev,
+ "NIC did not reboot, slice %d ring state:\n",
+ slice);
+ device_printf(sc->dev,
+ "tx.req=%d tx.done=%d, tx.queue_active=%d\n",
+ tx->req, tx->done, tx->queue_active);
+ device_printf(sc->dev, "tx.activate=%d tx.deactivate=%d\n",
+ tx->activate, tx->deactivate);
device_printf(sc->dev, "pkt_done=%d fw=%d\n",
- sc->ss->tx.pkt_done,
+ tx->pkt_done,
be32toh(sc->ss->fw_stats->send_done_count));
device_printf(sc->dev, "not resetting\n");
}
@@ -3463,26 +3671,35 @@ mxge_watchdog_reset(mxge_softc_t *sc)
static int
mxge_watchdog(mxge_softc_t *sc)
{
- mxge_tx_ring_t *tx = &sc->ss->tx;
+ mxge_tx_ring_t *tx;
uint32_t rx_pause = be32toh(sc->ss->fw_stats->dropped_pause);
- int err = 0;
+ int i, err = 0;
/* see if we have outstanding transmits, which
have been pending for more than mxge_ticks */
- if (tx->req != tx->done &&
- tx->watchdog_req != tx->watchdog_done &&
- tx->done == tx->watchdog_done) {
- /* check for pause blocking before resetting */
- if (tx->watchdog_rx_pause == rx_pause)
- err = mxge_watchdog_reset(sc);
- else
- device_printf(sc->dev, "Flow control blocking "
- "xmits, check link partner\n");
- }
+ for (i = 0;
+#ifdef IFNET_MULTIQUEUE
+ (i < sc->num_slices) && (err == 0);
+#else
+ (i < 1) && (err == 0);
+#endif
+ i++) {
+ tx = &sc->ss[i].tx;
+ if (tx->req != tx->done &&
+ tx->watchdog_req != tx->watchdog_done &&
+ tx->done == tx->watchdog_done) {
+ /* check for pause blocking before resetting */
+ if (tx->watchdog_rx_pause == rx_pause)
+ err = mxge_watchdog_reset(sc, i);
+ else
+ device_printf(sc->dev, "Flow control blocking "
+ "xmits, check link partner\n");
+ }
- tx->watchdog_req = tx->req;
- tx->watchdog_done = tx->done;
- tx->watchdog_rx_pause = rx_pause;
+ tx->watchdog_req = tx->req;
+ tx->watchdog_done = tx->done;
+ tx->watchdog_rx_pause = rx_pause;
+ }
if (sc->need_media_probe)
mxge_media_probe(sc);
@@ -3494,15 +3711,36 @@ mxge_update_stats(mxge_softc_t *sc)
{
struct mxge_slice_state *ss;
u_long ipackets = 0;
+ u_long opackets = 0;
+#ifdef IFNET_MULTIQUEUE
+ u_long obytes = 0;
+ u_long omcasts = 0;
+ u_long odrops = 0;
+#endif
+ u_long oerrors = 0;
int slice;
- for(slice = 0; slice < sc->num_slices; slice++) {
+ for (slice = 0; slice < sc->num_slices; slice++) {
ss = &sc->ss[slice];
ipackets += ss->ipackets;
+ opackets += ss->opackets;
+#ifdef IFNET_MULTIQUEUE
+ obytes += ss->obytes;
+ omcasts += ss->omcasts;
+ odrops += ss->tx.br->br_drops;
+#endif
+ oerrors += ss->oerrors;
}
sc->ifp->if_ipackets = ipackets;
-
+ sc->ifp->if_opackets = opackets;
+#ifdef IFNET_MULTIQUEUE
+ sc->ifp->if_obytes = obytes;
+ sc->ifp->if_omcasts = omcasts;
+ sc->ifp->if_snd.ifq_drops = odrops;
+#endif
+ sc->ifp->if_oerrors = oerrors;
}
+
static void
mxge_tick(void *arg)
{
@@ -3724,6 +3962,12 @@ mxge_free_slices(mxge_softc_t *sc)
if (ss->fw_stats != NULL) {
mxge_dma_free(&ss->fw_stats_dma);
ss->fw_stats = NULL;
+#ifdef IFNET_MULTIQUEUE
+ if (ss->tx.br != NULL) {
+ drbr_free(ss->tx.br, M_DEVBUF);
+ ss->tx.br = NULL;
+ }
+#endif
mtx_destroy(&ss->tx.mtx);
}
if (ss->rx_done.entry != NULL) {
@@ -3774,9 +4018,10 @@ mxge_alloc_slices(mxge_softc_t *sc)
* (including tx) are used used only on the first
* slice for now
*/
+#ifndef IFNET_MULTIQUEUE
if (i > 0)
continue;
-
+#endif
bytes = sizeof (*ss->fw_stats);
err = mxge_dma_alloc(sc, &ss->fw_stats_dma,
sizeof (*ss->fw_stats), 64);
@@ -3786,6 +4031,11 @@ mxge_alloc_slices(mxge_softc_t *sc)
snprintf(ss->tx.mtx_name, sizeof(ss->tx.mtx_name),
"%s:tx(%d)", device_get_nameunit(sc->dev), i);
mtx_init(&ss->tx.mtx, ss->tx.mtx_name, NULL, MTX_DEF);
+#ifdef IFNET_MULTIQUEUE
+ ss->tx.br = buf_ring_alloc(2048, M_DEVBUF, M_WAITOK,
+ &ss->tx.mtx);
+#endif
+
}
return (0);
@@ -4259,6 +4509,9 @@ mxge_attach(device_t dev)
ifp->if_mtu = 9000;
mxge_add_sysctls(sc);
+#ifdef IFNET_MULTIQUEUE
+ ifp->if_transmit = mxge_transmit;
+#endif
return 0;
abort_with_rings:
Modified: user/kmacy/HEAD_fast_net/sys/dev/mxge/if_mxge_var.h
==============================================================================
--- user/kmacy/HEAD_fast_net/sys/dev/mxge/if_mxge_var.h Tue Dec 30 05:35:27 2008 (r186592)
+++ user/kmacy/HEAD_fast_net/sys/dev/mxge/if_mxge_var.h Tue Dec 30 05:35:54 2008 (r186593)
@@ -125,7 +125,12 @@ typedef struct
typedef struct
{
struct mtx mtx;
+#ifdef IFNET_MULTIQUEUE
+ struct buf_ring *br;
+#endif
volatile mcp_kreq_ether_send_t *lanai; /* lanai ptr for sendq */
+ volatile uint32_t *send_go; /* doorbell for sendq */
+ volatile uint32_t *send_stop; /* doorbell for sendq */
mcp_kreq_ether_send_t *req_list; /* host shadow of sendq */
char *req_bytes;
bus_dma_segment_t *seg_list;
@@ -136,6 +141,9 @@ typedef struct
int done; /* transmits completed */
int pkt_done; /* packets completed */
int max_desc; /* max descriptors per xmit */
+ int queue_active; /* fw currently polling this queue*/
+ int activate;
+ int deactivate;
int stall; /* #times hw queue exhausted */
int wake; /* #times irq re-enabled xmit */
int watchdog_req; /* cache of req */
@@ -182,6 +190,11 @@ struct mxge_slice_state {
mcp_irq_data_t *fw_stats;
volatile uint32_t *irq_claim;
u_long ipackets;
+ u_long opackets;
+ u_long obytes;
+ u_long omcasts;
+ u_long oerrors;
+ int if_drv_flags;
struct lro_head lro_active;
struct lro_head lro_free;
int lro_queued;
More information about the svn-src-user
mailing list