Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/netmap/netmap.c
Show First 20 Lines • Show All 631 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Convenience function used in drivers. Waits for current txsync()s/rxsync()s | * Convenience function used in drivers. Waits for current txsync()s/rxsync()s | ||||
* to finish and prevents any new one from starting. Call this before turning | * to finish and prevents any new one from starting. Call this before turning | ||||
* netmap mode off, or before removing the hardware rings (e.g., on module | * netmap mode off, or before removing the hardware rings (e.g., on module | ||||
* onload). | * onload). | ||||
*/ | */ | ||||
void | void | ||||
netmap_disable_all_rings(struct ifnet *ifp) | netmap_disable_all_rings(if_t ifp) | ||||
{ | { | ||||
if (NM_NA_VALID(ifp)) { | if (NM_NA_VALID(ifp)) { | ||||
netmap_set_all_rings(NA(ifp), NM_KR_LOCKED); | netmap_set_all_rings(NA(ifp), NM_KR_LOCKED); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Convenience function used in drivers. Re-enables rxsync and txsync on the | * Convenience function used in drivers. Re-enables rxsync and txsync on the | ||||
* adapter's rings In linux drivers, this should be placed near each | * adapter's rings In linux drivers, this should be placed near each | ||||
* napi_enable(). | * napi_enable(). | ||||
*/ | */ | ||||
void | void | ||||
netmap_enable_all_rings(struct ifnet *ifp) | netmap_enable_all_rings(if_t ifp) | ||||
{ | { | ||||
if (NM_NA_VALID(ifp)) { | if (NM_NA_VALID(ifp)) { | ||||
netmap_set_all_rings(NA(ifp), 0 /* enabled */); | netmap_set_all_rings(NA(ifp), 0 /* enabled */); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
netmap_make_zombie(struct ifnet *ifp) | netmap_make_zombie(if_t ifp) | ||||
{ | { | ||||
if (NM_NA_VALID(ifp)) { | if (NM_NA_VALID(ifp)) { | ||||
struct netmap_adapter *na = NA(ifp); | struct netmap_adapter *na = NA(ifp); | ||||
netmap_set_all_rings(na, NM_KR_LOCKED); | netmap_set_all_rings(na, NM_KR_LOCKED); | ||||
na->na_flags |= NAF_ZOMBIE; | na->na_flags |= NAF_ZOMBIE; | ||||
netmap_set_all_rings(na, 0); | netmap_set_all_rings(na, 0); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
netmap_undo_zombie(struct ifnet *ifp) | netmap_undo_zombie(if_t ifp) | ||||
{ | { | ||||
if (NM_NA_VALID(ifp)) { | if (NM_NA_VALID(ifp)) { | ||||
struct netmap_adapter *na = NA(ifp); | struct netmap_adapter *na = NA(ifp); | ||||
if (na->na_flags & NAF_ZOMBIE) { | if (na->na_flags & NAF_ZOMBIE) { | ||||
netmap_set_all_rings(na, NM_KR_LOCKED); | netmap_set_all_rings(na, NM_KR_LOCKED); | ||||
na->na_flags &= ~NAF_ZOMBIE; | na->na_flags &= ~NAF_ZOMBIE; | ||||
netmap_set_all_rings(na, 0); | netmap_set_all_rings(na, 0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
/* call with NMG_LOCK held */ | /* call with NMG_LOCK held */ | ||||
int | int | ||||
netmap_update_config(struct netmap_adapter *na) | netmap_update_config(struct netmap_adapter *na) | ||||
{ | { | ||||
struct nm_config_info info; | struct nm_config_info info; | ||||
if (na->ifp && !nm_is_bwrap(na)) { | if (na->ifp && !nm_is_bwrap(na)) { | ||||
strlcpy(na->name, na->ifp->if_xname, sizeof(na->name)); | strlcpy(na->name, if_name(na->ifp), sizeof(na->name)); | ||||
} | } | ||||
bzero(&info, sizeof(info)); | bzero(&info, sizeof(info)); | ||||
if (na->nm_config == NULL || | if (na->nm_config == NULL || | ||||
na->nm_config(na, &info)) { | na->nm_config(na, &info)) { | ||||
/* take whatever we had at init time */ | /* take whatever we had at init time */ | ||||
info.num_tx_rings = na->num_tx_rings; | info.num_tx_rings = na->num_tx_rings; | ||||
info.num_tx_descs = na->num_tx_desc; | info.num_tx_descs = na->num_tx_desc; | ||||
▲ Show 20 Lines • Show All 413 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Pass a whole queue of mbufs to the host stack as coming from 'dst' | * Pass a whole queue of mbufs to the host stack as coming from 'dst' | ||||
* We do not need to lock because the queue is private. | * We do not need to lock because the queue is private. | ||||
* After this call the queue is empty. | * After this call the queue is empty. | ||||
*/ | */ | ||||
static void | static void | ||||
netmap_send_up(struct ifnet *dst, struct mbq *q) | netmap_send_up(if_t dst, struct mbq *q) | ||||
{ | { | ||||
struct mbuf *m; | struct mbuf *m; | ||||
struct mbuf *head = NULL, *prev = NULL; | struct mbuf *head = NULL, *prev = NULL; | ||||
#ifdef __FreeBSD__ | #ifdef __FreeBSD__ | ||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ENTER(et); | ||||
#endif /* __FreeBSD__ */ | #endif /* __FreeBSD__ */ | ||||
▲ Show 20 Lines • Show All 254 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* 0 NETMAP_ADMODE_BEST NATIVE GENERIC | * 0 NETMAP_ADMODE_BEST NATIVE GENERIC | ||||
* 0 NETMAP_ADMODE_NATIVE NATIVE NULL | * 0 NETMAP_ADMODE_NATIVE NATIVE NULL | ||||
* 0 NETMAP_ADMODE_GENERIC GENERIC GENERIC | * 0 NETMAP_ADMODE_GENERIC GENERIC GENERIC | ||||
* | * | ||||
*/ | */ | ||||
static void netmap_hw_dtor(struct netmap_adapter *); /* needed by NM_IS_NATIVE() */ | static void netmap_hw_dtor(struct netmap_adapter *); /* needed by NM_IS_NATIVE() */ | ||||
int | int | ||||
netmap_get_hw_na(struct ifnet *ifp, struct netmap_mem_d *nmd, struct netmap_adapter **na) | netmap_get_hw_na(if_t ifp, struct netmap_mem_d *nmd, struct netmap_adapter **na) | ||||
{ | { | ||||
/* generic support */ | /* generic support */ | ||||
int i = netmap_admode; /* Take a snapshot. */ | int i = netmap_admode; /* Take a snapshot. */ | ||||
struct netmap_adapter *prev_na; | struct netmap_adapter *prev_na; | ||||
int error = 0; | int error = 0; | ||||
*na = NULL; /* default */ | *na = NULL; /* default */ | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | |||||
* could not be allocated. | * could not be allocated. | ||||
* If successful, hold a reference to the netmap adapter. | * If successful, hold a reference to the netmap adapter. | ||||
* | * | ||||
* If the interface specified by req is a system one, also keep | * If the interface specified by req is a system one, also keep | ||||
* a reference to it and return a valid *ifp. | * a reference to it and return a valid *ifp. | ||||
*/ | */ | ||||
int | int | ||||
netmap_get_na(struct nmreq_header *hdr, | netmap_get_na(struct nmreq_header *hdr, | ||||
struct netmap_adapter **na, struct ifnet **ifp, | struct netmap_adapter **na, if_t *ifp, | ||||
struct netmap_mem_d *nmd, int create) | struct netmap_mem_d *nmd, int create) | ||||
{ | { | ||||
struct nmreq_register *req = (struct nmreq_register *)(uintptr_t)hdr->nr_body; | struct nmreq_register *req = (struct nmreq_register *)(uintptr_t)hdr->nr_body; | ||||
int error = 0; | int error = 0; | ||||
struct netmap_adapter *ret = NULL; | struct netmap_adapter *ret = NULL; | ||||
int nmd_ref = 0; | int nmd_ref = 0; | ||||
*na = NULL; /* default return value */ | *na = NULL; /* default return value */ | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | out: | ||||
if (nmd_ref) | if (nmd_ref) | ||||
netmap_mem_put(nmd); | netmap_mem_put(nmd); | ||||
return error; | return error; | ||||
} | } | ||||
/* undo netmap_get_na() */ | /* undo netmap_get_na() */ | ||||
void | void | ||||
netmap_unget_na(struct netmap_adapter *na, struct ifnet *ifp) | netmap_unget_na(struct netmap_adapter *na, if_t ifp) | ||||
{ | { | ||||
if (ifp) | if (ifp) | ||||
if_rele(ifp); | if_rele(ifp); | ||||
if (na) | if (na) | ||||
netmap_adapter_put(na); | netmap_adapter_put(na); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 568 Lines • ▼ Show 20 Lines | if (mtu <= na->rx_buf_maxsize) { | ||||
* or transmit a single packet. Check that | * or transmit a single packet. Check that | ||||
* the adapter supports NS_MOREFRAG and that | * the adapter supports NS_MOREFRAG and that | ||||
* netmap buffers are large enough to hold | * netmap buffers are large enough to hold | ||||
* the maximum per-slot size. */ | * the maximum per-slot size. */ | ||||
if (!(na->na_flags & NAF_MOREFRAG)) { | if (!(na->na_flags & NAF_MOREFRAG)) { | ||||
nm_prerr("error: large MTU (%d) needed " | nm_prerr("error: large MTU (%d) needed " | ||||
"but %s does not support " | "but %s does not support " | ||||
"NS_MOREFRAG", mtu, | "NS_MOREFRAG", mtu, | ||||
na->ifp->if_xname); | if_name(na->ifp)); | ||||
vmaffione: `if_name()` or `if_getdname()` ? | |||||
Done Inline Actionsif_name() gets ifp->if_xname, so it's a literal conversion. jhibbits: if_name() gets ifp->if_xname, so it's a literal conversion. | |||||
Not Done Inline Actions
I think this should be if_name(). sys/net/if.c const char * if_name(if_t ifp) { return ((struct ifnet *)ifp)->if_xname; } zlei: >if_name() or if_getdname() ?
I think this should be `if_name()`.
sys/net/if.c
```
const char… | |||||
return EINVAL; | return EINVAL; | ||||
} else if (nbs < na->rx_buf_maxsize) { | } else if (nbs < na->rx_buf_maxsize) { | ||||
nm_prerr("error: using NS_MOREFRAG on " | nm_prerr("error: using NS_MOREFRAG on " | ||||
"%s requires netmap buf size " | "%s requires netmap buf size " | ||||
">= %u", na->ifp->if_xname, | ">= %u", if_name(na->ifp), | ||||
Done Inline Actionsif_getdname(), is this intended ? zlei: `if_getdname()`, is this intended ? | |||||
Not Done Inline ActionsThis should be the interface name, so if_name looks good to me vmaffione: This should be the interface name, so `if_name` looks good to me | |||||
na->rx_buf_maxsize); | na->rx_buf_maxsize); | ||||
return EINVAL; | return EINVAL; | ||||
} else { | } else { | ||||
nm_prinf("info: netmap application on " | nm_prinf("info: netmap application on " | ||||
"%s needs to support " | "%s needs to support " | ||||
"NS_MOREFRAG " | "NS_MOREFRAG " | ||||
"(MTU=%u,netmap_buf_size=%u)", | "(MTU=%u,netmap_buf_size=%u)", | ||||
na->ifp->if_xname, mtu, nbs); | if_name(na->ifp), mtu, nbs); | ||||
Done Inline Actionsthis should be if_name vmaffione: this should be `if_name` | |||||
} | } | ||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
/* Handle the offset option, if present in the hdr. | /* Handle the offset option, if present in the hdr. | ||||
* Returns 0 on success, or an error. | * Returns 0 on success, or an error. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 458 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
int | int | ||||
netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, | netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, | ||||
struct thread *td, int nr_body_is_user) | struct thread *td, int nr_body_is_user) | ||||
{ | { | ||||
struct mbq q; /* packets from RX hw queues to host stack */ | struct mbq q; /* packets from RX hw queues to host stack */ | ||||
struct netmap_adapter *na = NULL; | struct netmap_adapter *na = NULL; | ||||
struct netmap_mem_d *nmd = NULL; | struct netmap_mem_d *nmd = NULL; | ||||
struct ifnet *ifp = NULL; | if_t ifp = NULL; | ||||
int error = 0; | int error = 0; | ||||
u_int i, qfirst, qlast; | u_int i, qfirst, qlast; | ||||
struct netmap_kring **krings; | struct netmap_kring **krings; | ||||
int sync_flags; | int sync_flags; | ||||
enum txrx t; | enum txrx t; | ||||
switch (cmd) { | switch (cmd) { | ||||
case NIOCCTRL: { | case NIOCCTRL: { | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | #endif /* WITH_EXTMEM */ | ||||
req->nr_host_rx_rings = na->num_host_rx_rings; | req->nr_host_rx_rings = na->num_host_rx_rings; | ||||
error = netmap_mem_get_info(na->nm_mem, &req->nr_memsize, &memflags, | error = netmap_mem_get_info(na->nm_mem, &req->nr_memsize, &memflags, | ||||
&req->nr_mem_id); | &req->nr_mem_id); | ||||
if (error) { | if (error) { | ||||
netmap_do_unregif(priv); | netmap_do_unregif(priv); | ||||
break; | break; | ||||
} | } | ||||
if (memflags & NETMAP_MEM_PRIVATE) { | if (memflags & NETMAP_MEM_PRIVATE) { | ||||
*(uint32_t *)(uintptr_t)&nifp->ni_flags |= NI_PRIV_MEM; | *(uint32_t *)(uintptr_t)&nifp->ni_flags |= NI_PRIV_MEM; | ||||
Not Done Inline ActionsThis is not ifnet stuff, so it should not be touched. vmaffione: This is not `ifnet` stuff, so it should not be touched. | |||||
Not Done Inline Actionsplease drop the comment vmaffione: please drop the comment | |||||
} | } | ||||
for_rx_tx(t) { | for_rx_tx(t) { | ||||
priv->np_si[t] = nm_si_user(priv, t) ? | priv->np_si[t] = nm_si_user(priv, t) ? | ||||
&na->si[t] : &NMR(na, t)[priv->np_qfirst[t]]->si; | &na->si[t] : &NMR(na, t)[priv->np_qfirst[t]]->si; | ||||
} | } | ||||
if (req->nr_extra_bufs) { | if (req->nr_extra_bufs) { | ||||
if (netmap_verbose) | if (netmap_verbose) | ||||
▲ Show 20 Lines • Show All 153 Lines • ▼ Show 20 Lines | #ifdef WITH_VALE | ||||
case NETMAP_REQ_PORT_HDR_GET: { | case NETMAP_REQ_PORT_HDR_GET: { | ||||
/* Get vnet-header length for this netmap port */ | /* Get vnet-header length for this netmap port */ | ||||
struct nmreq_port_hdr *req = | struct nmreq_port_hdr *req = | ||||
(struct nmreq_port_hdr *)(uintptr_t)hdr->nr_body; | (struct nmreq_port_hdr *)(uintptr_t)hdr->nr_body; | ||||
/* Build a nmreq_register out of the nmreq_port_hdr, | /* Build a nmreq_register out of the nmreq_port_hdr, | ||||
* so that we can call netmap_get_bdg_na(). */ | * so that we can call netmap_get_bdg_na(). */ | ||||
struct nmreq_register regreq; | struct nmreq_register regreq; | ||||
struct ifnet *ifp; | if_t ifp; | ||||
bzero(®req, sizeof(regreq)); | bzero(®req, sizeof(regreq)); | ||||
regreq.nr_mode = NR_REG_ALL_NIC; | regreq.nr_mode = NR_REG_ALL_NIC; | ||||
NMG_LOCK(); | NMG_LOCK(); | ||||
hdr->nr_reqtype = NETMAP_REQ_REGISTER; | hdr->nr_reqtype = NETMAP_REQ_REGISTER; | ||||
hdr->nr_body = (uintptr_t)®req; | hdr->nr_body = (uintptr_t)®req; | ||||
error = netmap_get_na(hdr, &na, &ifp, NULL, 0); | error = netmap_get_na(hdr, &na, &ifp, NULL, 0); | ||||
hdr->nr_reqtype = NETMAP_REQ_PORT_HDR_GET; | hdr->nr_reqtype = NETMAP_REQ_PORT_HDR_GET; | ||||
▲ Show 20 Lines • Show All 917 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
if (!na->rx_buf_maxsize) { | if (!na->rx_buf_maxsize) { | ||||
/* Set a conservative default (larger is safer). */ | /* Set a conservative default (larger is safer). */ | ||||
na->rx_buf_maxsize = PAGE_SIZE; | na->rx_buf_maxsize = PAGE_SIZE; | ||||
} | } | ||||
#ifdef __FreeBSD__ | #ifdef __FreeBSD__ | ||||
if (na->na_flags & NAF_HOST_RINGS && na->ifp) { | if (na->na_flags & NAF_HOST_RINGS && na->ifp) { | ||||
na->if_input = na->ifp->if_input; /* for netmap_send_up */ | na->if_input = if_getinputfn(na->ifp); /* for netmap_send_up */ | ||||
Not Done Inline ActionsYep, we need a way to grab the if_input method. Can DRVAPI expose that? vmaffione: Yep, we need a way to grab the `if_input` method. Can DRVAPI expose that? | |||||
Done Inline ActionsYeah, I'll need to add an accessor for it. jhibbits: Yeah, I'll need to add an accessor for it. | |||||
} | } | ||||
na->pdev = na; /* make sure netmap_mem_map() is called */ | na->pdev = na; /* make sure netmap_mem_map() is called */ | ||||
#endif /* __FreeBSD__ */ | #endif /* __FreeBSD__ */ | ||||
if (na->na_flags & NAF_HOST_RINGS) { | if (na->na_flags & NAF_HOST_RINGS) { | ||||
if (na->num_host_rx_rings == 0) | if (na->num_host_rx_rings == 0) | ||||
na->num_host_rx_rings = 1; | na->num_host_rx_rings = 1; | ||||
if (na->num_host_tx_rings == 0) | if (na->num_host_tx_rings == 0) | ||||
na->num_host_tx_rings = 1; | na->num_host_tx_rings = 1; | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | |||||
* for struct netmap_adapter plus additional room private to | * for struct netmap_adapter plus additional room private to | ||||
* the caller. | * the caller. | ||||
* Return 0 on success, ENOMEM otherwise. | * Return 0 on success, ENOMEM otherwise. | ||||
*/ | */ | ||||
int | int | ||||
netmap_attach_ext(struct netmap_adapter *arg, size_t size, int override_reg) | netmap_attach_ext(struct netmap_adapter *arg, size_t size, int override_reg) | ||||
{ | { | ||||
struct netmap_hw_adapter *hwna = NULL; | struct netmap_hw_adapter *hwna = NULL; | ||||
struct ifnet *ifp = NULL; | if_t ifp = NULL; | ||||
if (size < sizeof(struct netmap_hw_adapter)) { | if (size < sizeof(struct netmap_hw_adapter)) { | ||||
if (netmap_debug & NM_DEBUG_ON) | if (netmap_debug & NM_DEBUG_ON) | ||||
nm_prerr("Invalid netmap adapter size %d", (int)size); | nm_prerr("Invalid netmap adapter size %d", (int)size); | ||||
return EINVAL; | return EINVAL; | ||||
} | } | ||||
if (arg == NULL || arg->ifp == NULL) { | if (arg == NULL || arg->ifp == NULL) { | ||||
Show All 19 Lines | if (NM_NA_CLASH(ifp)) { | ||||
return EBUSY; | return EBUSY; | ||||
} | } | ||||
hwna = nm_os_malloc(size); | hwna = nm_os_malloc(size); | ||||
if (hwna == NULL) | if (hwna == NULL) | ||||
goto fail; | goto fail; | ||||
hwna->up = *arg; | hwna->up = *arg; | ||||
hwna->up.na_flags |= NAF_HOST_RINGS | NAF_NATIVE; | hwna->up.na_flags |= NAF_HOST_RINGS | NAF_NATIVE; | ||||
strlcpy(hwna->up.name, ifp->if_xname, sizeof(hwna->up.name)); | strlcpy(hwna->up.name, if_name(ifp), sizeof(hwna->up.name)); | ||||
if (override_reg) { | if (override_reg) { | ||||
hwna->nm_hw_register = hwna->up.nm_register; | hwna->nm_hw_register = hwna->up.nm_register; | ||||
hwna->up.nm_register = netmap_hw_reg; | hwna->up.nm_register = netmap_hw_reg; | ||||
} | } | ||||
if (netmap_attach_common(&hwna->up)) { | if (netmap_attach_common(&hwna->up)) { | ||||
nm_os_free(hwna); | nm_os_free(hwna); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Called on module unload by the netmap-enabled drivers | * Called on module unload by the netmap-enabled drivers | ||||
*/ | */ | ||||
void | void | ||||
netmap_detach(struct ifnet *ifp) | netmap_detach(if_t ifp) | ||||
{ | { | ||||
struct netmap_adapter *na; | struct netmap_adapter *na; | ||||
NMG_LOCK(); | NMG_LOCK(); | ||||
if (!NM_NA_VALID(ifp)) { | if (!NM_NA_VALID(ifp)) { | ||||
NMG_UNLOCK(); | NMG_UNLOCK(); | ||||
return; | return; | ||||
Show All 29 Lines | |||||
* in the relevant rxsync routine. | * in the relevant rxsync routine. | ||||
* | * | ||||
* We rely on the OS to make sure that the ifp and na do not go | * We rely on the OS to make sure that the ifp and na do not go | ||||
* away (typically the caller checks for IFF_DRV_RUNNING or the like). | * away (typically the caller checks for IFF_DRV_RUNNING or the like). | ||||
* In nm_register() or whenever there is a reinitialization, | * In nm_register() or whenever there is a reinitialization, | ||||
* we make sure to make the mode change visible here. | * we make sure to make the mode change visible here. | ||||
*/ | */ | ||||
int | int | ||||
netmap_transmit(struct ifnet *ifp, struct mbuf *m) | netmap_transmit(if_t ifp, struct mbuf *m) | ||||
{ | { | ||||
struct netmap_adapter *na = NA(ifp); | struct netmap_adapter *na = NA(ifp); | ||||
struct netmap_kring *kring, *tx_kring; | struct netmap_kring *kring, *tx_kring; | ||||
u_int len = MBUF_LEN(m); | u_int len = MBUF_LEN(m); | ||||
u_int error = ENOBUFS; | u_int error = ENOBUFS; | ||||
unsigned int txr; | unsigned int txr; | ||||
struct mbq *q; | struct mbq *q; | ||||
int busy; | int busy; | ||||
▲ Show 20 Lines • Show All 223 Lines • ▼ Show 20 Lines | |||||
* do a selwakeup on the individual queue, plus one on the global one | * do a selwakeup on the individual queue, plus one on the global one | ||||
* if needed (multiqueue card _and_ there are multiqueue listeners), | * if needed (multiqueue card _and_ there are multiqueue listeners), | ||||
* and return NR_IRQ_COMPLETED. | * and return NR_IRQ_COMPLETED. | ||||
* | * | ||||
* Finally, if called on rx from an interface connected to a switch, | * Finally, if called on rx from an interface connected to a switch, | ||||
* calls the proper forwarding routine. | * calls the proper forwarding routine. | ||||
*/ | */ | ||||
int | int | ||||
netmap_rx_irq(struct ifnet *ifp, u_int q, u_int *work_done) | netmap_rx_irq(if_t ifp, u_int q, u_int *work_done) | ||||
{ | { | ||||
struct netmap_adapter *na = NA(ifp); | struct netmap_adapter *na = NA(ifp); | ||||
/* | /* | ||||
* XXX emulated netmap mode sets NAF_SKIP_INTR so | * XXX emulated netmap mode sets NAF_SKIP_INTR so | ||||
* we still use the regular driver even though the previous | * we still use the regular driver even though the previous | ||||
* check fails. It is unclear whether we should use | * check fails. It is unclear whether we should use | ||||
* nm_native_on() here. | * nm_native_on() here. | ||||
*/ | */ | ||||
if (!nm_netmap_on(na)) | if (!nm_netmap_on(na)) | ||||
return NM_IRQ_PASS; | return NM_IRQ_PASS; | ||||
if (na->na_flags & NAF_SKIP_INTR) { | if (na->na_flags & NAF_SKIP_INTR) { | ||||
nm_prdis("use regular interrupt"); | nm_prdis("use regular interrupt"); | ||||
return NM_IRQ_PASS; | return NM_IRQ_PASS; | ||||
} | } | ||||
return netmap_common_irq(na, q, work_done); | return netmap_common_irq(na, q, work_done); | ||||
} | } | ||||
/* set/clear native flags and if_transmit/netdev_ops */ | /* set/clear native flags and if_transmit/netdev_ops */ | ||||
void | void | ||||
nm_set_native_flags(struct netmap_adapter *na) | nm_set_native_flags(struct netmap_adapter *na) | ||||
{ | { | ||||
struct ifnet *ifp = na->ifp; | if_t ifp = na->ifp; | ||||
/* We do the setup for intercepting packets only if we are the | /* We do the setup for intercepting packets only if we are the | ||||
* first user of this adapter. */ | * first user of this adapter. */ | ||||
if (na->active_fds > 0) { | if (na->active_fds > 0) { | ||||
return; | return; | ||||
} | } | ||||
na->na_flags |= NAF_NETMAP_ON; | na->na_flags |= NAF_NETMAP_ON; | ||||
nm_os_onenter(ifp); | nm_os_onenter(ifp); | ||||
netmap_update_hostrings_mode(na); | netmap_update_hostrings_mode(na); | ||||
} | } | ||||
void | void | ||||
nm_clear_native_flags(struct netmap_adapter *na) | nm_clear_native_flags(struct netmap_adapter *na) | ||||
{ | { | ||||
struct ifnet *ifp = na->ifp; | if_t ifp = na->ifp; | ||||
/* We undo the setup for intercepting packets only if we are the | /* We undo the setup for intercepting packets only if we are the | ||||
* last user of this adapter. */ | * last user of this adapter. */ | ||||
if (na->active_fds > 0) { | if (na->active_fds > 0) { | ||||
return; | return; | ||||
} | } | ||||
netmap_update_hostrings_mode(na); | netmap_update_hostrings_mode(na); | ||||
▲ Show 20 Lines • Show All 93 Lines • Show Last 20 Lines |
if_name() or if_getdname() ?