summaryrefslogtreecommitdiffstats
path: root/sys/dev/re
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2011-12-05 15:33:13 +0000
committerluigi <luigi@FreeBSD.org>2011-12-05 15:33:13 +0000
commit87c928ba8bd259a1f13404bce1a7f026e914ce8a (patch)
tree0468f65e6f84d60ea34b5b2444875d96d2aabb8a /sys/dev/re
parent50d8e226ac73ce549c1901a2afb3b524cd378f01 (diff)
downloadFreeBSD-src-87c928ba8bd259a1f13404bce1a7f026e914ce8a.zip
FreeBSD-src-87c928ba8bd259a1f13404bce1a7f026e914ce8a.tar.gz
add netmap support for "em", "lem", "igb" and "re".
On my hardware, "em" in netmap mode does about 1.388 Mpps on one card (on an Asus motherboard), and 1.1 Mpps on another card (PCIe bus). Both seem to be NIC-limited, because i have the same rate even with the CPU running at 150 MHz. On the "re" driver the tx throughput is around 420-450 Kpps on various (8111C and the like) chipsets. On the Rx side performance seems much better, and i can receive the full load generated by the "em" cards. "igb" is untested as i don't have the hardware.
Diffstat (limited to 'sys/dev/re')
-rw-r--r--sys/dev/re/if_re.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c
index da90951..92fbbfe 100644
--- a/sys/dev/re/if_re.c
+++ b/sys/dev/re/if_re.c
@@ -296,6 +296,10 @@ static void re_setwol (struct rl_softc *);
static void re_clrwol (struct rl_softc *);
static void re_set_linkspeed (struct rl_softc *);
+#ifdef DEV_NETMAP /* see ixgbe.c for details */
+#include <dev/netmap/if_re_netmap.h>
+#endif /* !DEV_NETMAP */
+
#ifdef RE_DIAG
static int re_diag (struct rl_softc *);
#endif
@@ -1620,6 +1624,9 @@ re_attach(device_t dev)
*/
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
+#ifdef DEV_NETMAP
+ re_netmap_attach(sc);
+#endif /* DEV_NETMAP */
#ifdef RE_DIAG
/*
* Perform hardware diagnostic on the original RTL8169.
@@ -1815,6 +1822,9 @@ re_detach(device_t dev)
bus_dma_tag_destroy(sc->rl_ldata.rl_stag);
}
+#ifdef DEV_NETMAP
+ netmap_detach(ifp);
+#endif /* DEV_NETMAP */
if (sc->rl_parent_tag)
bus_dma_tag_destroy(sc->rl_parent_tag);
@@ -1989,6 +1999,9 @@ re_tx_list_init(struct rl_softc *sc)
sc->rl_ldata.rl_tx_desc_cnt * sizeof(struct rl_desc));
for (i = 0; i < sc->rl_ldata.rl_tx_desc_cnt; i++)
sc->rl_ldata.rl_tx_desc[i].tx_m = NULL;
+#ifdef DEV_NETMAP
+ re_netmap_tx_init(sc);
+#endif /* DEV_NETMAP */
/* Set EOR. */
desc = &sc->rl_ldata.rl_tx_list[sc->rl_ldata.rl_tx_desc_cnt - 1];
desc->rl_cmdstat |= htole32(RL_TDESC_CMD_EOR);
@@ -2016,6 +2029,9 @@ re_rx_list_init(struct rl_softc *sc)
if ((error = re_newbuf(sc, i)) != 0)
return (error);
}
+#ifdef DEV_NETMAP
+ re_netmap_rx_init(sc);
+#endif /* DEV_NETMAP */
/* Flush the RX descriptors */
@@ -2072,6 +2088,12 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp)
RL_LOCK_ASSERT(sc);
ifp = sc->rl_ifp;
+#ifdef DEV_NETMAP
+ if (ifp->if_capenable & IFCAP_NETMAP) {
+ selwakeuppri(&NA(ifp)->rx_rings->si, PI_NET);
+ return 0;
+ }
+#endif /* DEV_NETMAP */
if (ifp->if_mtu > RL_MTU && (sc->rl_flags & RL_FLAG_JUMBOV2) != 0)
jumbo = 1;
else
@@ -2313,6 +2335,12 @@ re_txeof(struct rl_softc *sc)
return;
ifp = sc->rl_ifp;
+#ifdef DEV_NETMAP
+ if (ifp->if_capenable & IFCAP_NETMAP) {
+ selwakeuppri(&NA(ifp)->tx_rings[0].si, PI_NET);
+ return;
+ }
+#endif /* DEV_NETMAP */
/* Invalidate the TX descriptor list */
bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag,
sc->rl_ldata.rl_tx_list_map,
@@ -2831,6 +2859,21 @@ re_start_locked(struct ifnet *ifp)
sc = ifp->if_softc;
+#ifdef DEV_NETMAP
+ /* XXX is this necessary ? */
+ if (ifp->if_capenable & IFCAP_NETMAP) {
+ struct netmap_kring *kring = &NA(ifp)->tx_rings[0];
+ if (sc->rl_ldata.rl_tx_prodidx != kring->nr_hwcur) {
+ /* kick the tx unit */
+ CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START);
+#ifdef RE_TX_MODERATION
+ CSR_WRITE_4(sc, RL_TIMERCNT, 1);
+#endif
+ sc->rl_watchdog_timer = 5;
+ }
+ return;
+ }
+#endif /* DEV_NETMAP */
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0)
return;
OpenPOWER on IntegriCloud