Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/netmap/netmap_generic.c
Show First 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | |||||
#include <linux/ethtool.h> /* struct ethtool_ops, get_ringparam */ | #include <linux/ethtool.h> /* struct ethtool_ops, get_ringparam */ | ||||
#include <linux/hrtimer.h> | #include <linux/hrtimer.h> | ||||
static inline struct mbuf * | static inline struct mbuf * | ||||
nm_os_get_mbuf(struct ifnet *ifp, int len) | nm_os_get_mbuf(struct ifnet *ifp, int len) | ||||
{ | { | ||||
return alloc_skb(LL_RESERVED_SPACE(ifp) + len + | return alloc_skb(LL_RESERVED_SPACE(ifp) + len + | ||||
ifp->needed_tailroom, GFP_ATOMIC); | ifp->needed_tailroom, GFP_ATOMIC); | ||||
vmaffione: You can ignore this, it is Linux specific. | |||||
} | } | ||||
#endif /* linux */ | #endif /* linux */ | ||||
/* Common headers. */ | /* Common headers. */ | ||||
#include <net/netmap.h> | #include <net/netmap.h> | ||||
#include <dev/netmap/netmap_kern.h> | #include <dev/netmap/netmap_kern.h> | ||||
▲ Show 20 Lines • Show All 523 Lines • ▼ Show 20 Lines | |||||
* On linux this is not done directly, but using dev_queue_xmit(), | * On linux this is not done directly, but using dev_queue_xmit(), | ||||
* since it implements the TX flow control (and takes some locks). | * since it implements the TX flow control (and takes some locks). | ||||
*/ | */ | ||||
static int | static int | ||||
generic_netmap_txsync(struct netmap_kring *kring, int flags) | generic_netmap_txsync(struct netmap_kring *kring, int flags) | ||||
{ | { | ||||
struct netmap_adapter *na = kring->na; | struct netmap_adapter *na = kring->na; | ||||
struct netmap_generic_adapter *gna = (struct netmap_generic_adapter *)na; | struct netmap_generic_adapter *gna = (struct netmap_generic_adapter *)na; | ||||
struct ifnet *ifp = na->ifp; | if_t ifp = na->ifp; | ||||
struct netmap_ring *ring = kring->ring; | struct netmap_ring *ring = kring->ring; | ||||
u_int nm_i; /* index into the netmap ring */ // j | u_int nm_i; /* index into the netmap ring */ // j | ||||
u_int const lim = kring->nkr_num_slots - 1; | u_int const lim = kring->nkr_num_slots - 1; | ||||
u_int const head = kring->rhead; | u_int const head = kring->rhead; | ||||
u_int ring_nr = kring->ring_id; | u_int ring_nr = kring->ring_id; | ||||
IFRATE(rate_ctx.new.txsync++); | IFRATE(rate_ctx.new.txsync++); | ||||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | |||||
* within the attached network interface | * within the attached network interface | ||||
* in the RX subsystem, so that every mbuf passed up by | * in the RX subsystem, so that every mbuf passed up by | ||||
* the driver can be stolen to the network stack. | * the driver can be stolen to the network stack. | ||||
* Stolen packets are put in a queue where the | * Stolen packets are put in a queue where the | ||||
* generic_netmap_rxsync() callback can extract them. | * generic_netmap_rxsync() callback can extract them. | ||||
* Returns 1 if the packet was stolen, 0 otherwise. | * Returns 1 if the packet was stolen, 0 otherwise. | ||||
*/ | */ | ||||
int | int | ||||
generic_rx_handler(struct ifnet *ifp, struct mbuf *m) | generic_rx_handler(if_t ifp, struct mbuf *m) | ||||
{ | { | ||||
struct netmap_adapter *na = NA(ifp); | struct netmap_adapter *na = NA(ifp); | ||||
struct netmap_generic_adapter *gna = (struct netmap_generic_adapter *)na; | struct netmap_generic_adapter *gna = (struct netmap_generic_adapter *)na; | ||||
struct netmap_kring *kring; | struct netmap_kring *kring; | ||||
u_int work_done; | u_int work_done; | ||||
u_int r = MBUF_RXQ(m); /* receive ring number */ | u_int r = MBUF_RXQ(m); /* receive ring number */ | ||||
if (r >= na->num_rx_rings) { | if (r >= na->num_rx_rings) { | ||||
▲ Show 20 Lines • Show All 191 Lines • ▼ Show 20 Lines | generic_netmap_rxsync(struct netmap_kring *kring, int flags) | ||||
return 0; | return 0; | ||||
} | } | ||||
static void | static void | ||||
generic_netmap_dtor(struct netmap_adapter *na) | generic_netmap_dtor(struct netmap_adapter *na) | ||||
{ | { | ||||
struct netmap_generic_adapter *gna = (struct netmap_generic_adapter*)na; | struct netmap_generic_adapter *gna = (struct netmap_generic_adapter*)na; | ||||
struct ifnet *ifp = netmap_generic_getifp(gna); | if_t ifp = netmap_generic_getifp(gna); | ||||
struct netmap_adapter *prev_na = gna->prev; | struct netmap_adapter *prev_na = gna->prev; | ||||
if (prev_na != NULL) { | if (prev_na != NULL) { | ||||
netmap_adapter_put(prev_na); | netmap_adapter_put(prev_na); | ||||
if (nm_iszombie(na)) { | if (nm_iszombie(na)) { | ||||
/* | /* | ||||
* The driver has been removed without releasing | * The driver has been removed without releasing | ||||
* the reference so we need to do it here. | * the reference so we need to do it here. | ||||
Show All 24 Lines | |||||
* faster than raw sockets or similar schemes. | * faster than raw sockets or similar schemes. | ||||
* | * | ||||
* In this "emulated" mode, netmap rings do not necessarily | * In this "emulated" mode, netmap rings do not necessarily | ||||
* have the same size as those in the NIC. We use a default | * have the same size as those in the NIC. We use a default | ||||
* value and possibly override it if the OS has ways to fetch the | * value and possibly override it if the OS has ways to fetch the | ||||
* actual configuration. | * actual configuration. | ||||
*/ | */ | ||||
int | int | ||||
generic_netmap_attach(struct ifnet *ifp) | generic_netmap_attach(if_t ifp) | ||||
{ | { | ||||
struct netmap_adapter *na; | struct netmap_adapter *na; | ||||
struct netmap_generic_adapter *gna; | struct netmap_generic_adapter *gna; | ||||
int retval; | int retval; | ||||
u_int num_tx_desc, num_rx_desc; | u_int num_tx_desc, num_rx_desc; | ||||
#ifdef __FreeBSD__ | #ifdef __FreeBSD__ | ||||
if (ifp->if_type == IFT_LOOP) { | if (if_gettype(ifp) == IFT_LOOP) { | ||||
nm_prerr("if_loop is not supported by %s", __func__); | nm_prerr("if_loop is not supported by %s", __func__); | ||||
return EINVAL; | return EINVAL; | ||||
} | } | ||||
#endif | #endif | ||||
if (NM_NA_CLASH(ifp)) { | if (NM_NA_CLASH(ifp)) { | ||||
/* If NA(ifp) is not null but there is no valid netmap | /* If NA(ifp) is not null but there is no valid netmap | ||||
* adapter it means that someone else is using the same | * adapter it means that someone else is using the same | ||||
Show All 12 Lines | #endif | ||||
} | } | ||||
gna = nm_os_malloc(sizeof(*gna)); | gna = nm_os_malloc(sizeof(*gna)); | ||||
if (gna == NULL) { | if (gna == NULL) { | ||||
nm_prerr("no memory on attach, give up"); | nm_prerr("no memory on attach, give up"); | ||||
return ENOMEM; | return ENOMEM; | ||||
} | } | ||||
na = (struct netmap_adapter *)gna; | na = (struct netmap_adapter *)gna; | ||||
strlcpy(na->name, ifp->if_xname, sizeof(na->name)); | strlcpy(na->name, if_name(ifp), sizeof(na->name)); | ||||
na->ifp = ifp; | na->ifp = ifp; | ||||
na->num_tx_desc = num_tx_desc; | na->num_tx_desc = num_tx_desc; | ||||
na->num_rx_desc = num_rx_desc; | na->num_rx_desc = num_rx_desc; | ||||
na->rx_buf_maxsize = 32768; | na->rx_buf_maxsize = 32768; | ||||
na->nm_register = &generic_netmap_register; | na->nm_register = &generic_netmap_register; | ||||
na->nm_txsync = &generic_netmap_txsync; | na->nm_txsync = &generic_netmap_txsync; | ||||
na->nm_rxsync = &generic_netmap_rxsync; | na->nm_rxsync = &generic_netmap_rxsync; | ||||
na->nm_dtor = &generic_netmap_dtor; | na->nm_dtor = &generic_netmap_dtor; | ||||
/* when using generic, NAF_NETMAP_ON is set so we force | /* when using generic, NAF_NETMAP_ON is set so we force | ||||
* NAF_SKIP_INTR to use the regular interrupt handler | * NAF_SKIP_INTR to use the regular interrupt handler | ||||
*/ | */ | ||||
na->na_flags = NAF_SKIP_INTR | NAF_HOST_RINGS; | na->na_flags = NAF_SKIP_INTR | NAF_HOST_RINGS; | ||||
nm_prdis("[GNA] num_tx_queues(%d), real_num_tx_queues(%d), len(%lu)", | nm_prdis("[GNA] num_tx_queues(%d), real_num_tx_queues(%d), len(%lu)", | ||||
ifp->num_tx_queues, ifp->real_num_tx_queues, | ifp->num_tx_queues, ifp->real_num_tx_queues, | ||||
ifp->tx_queue_len); | ifp->tx_queue_len); | ||||
nm_prdis("[GNA] num_rx_queues(%d), real_num_rx_queues(%d)", | nm_prdis("[GNA] num_rx_queues(%d), real_num_rx_queues(%d)", | ||||
ifp->num_rx_queues, ifp->real_num_rx_queues); | ifp->num_rx_queues, ifp->real_num_rx_queues); | ||||
Done Inline ActionsPlease drop the comments. vmaffione: Please drop the comments. | |||||
nm_os_generic_find_num_queues(ifp, &na->num_tx_rings, &na->num_rx_rings); | nm_os_generic_find_num_queues(ifp, &na->num_tx_rings, &na->num_rx_rings); | ||||
retval = netmap_attach_common(na); | retval = netmap_attach_common(na); | ||||
if (retval) { | if (retval) { | ||||
nm_os_free(gna); | nm_os_free(gna); | ||||
return retval; | return retval; | ||||
} | } | ||||
Show All 14 Lines |
You can ignore this, it is Linux specific.