Changeset View
Changeset View
Standalone View
Standalone View
sys/net/iflib.c
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
#include <net/if_var.h> | #include <net/if_var.h> | ||||
#include <net/if_types.h> | #include <net/if_types.h> | ||||
#include <net/if_media.h> | #include <net/if_media.h> | ||||
#include <net/bpf.h> | #include <net/bpf.h> | ||||
#include <net/ethernet.h> | #include <net/ethernet.h> | ||||
#include <net/mp_ring.h> | #include <net/mp_ring.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <netinet/in_pcb.h> | |||||
#include <netinet/tcp_lro.h> | #include <netinet/tcp_lro.h> | ||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <dev/led/led.h> | #include <dev/led/led.h> | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | |||||
#define MTX_NAME_LEN 16 | #define MTX_NAME_LEN 16 | ||||
char ift_mtx_name[MTX_NAME_LEN]; | char ift_mtx_name[MTX_NAME_LEN]; | ||||
#define BATCH_SIZE 32 | #define BATCH_SIZE 32 | ||||
struct mbuf *ift_mp[BATCH_SIZE]; | struct mbuf *ift_mp[BATCH_SIZE]; | ||||
int ift_id; | int ift_id; | ||||
iflib_sd_t ift_sds; | iflib_sd_t ift_sds; | ||||
int ift_nbr; | int ift_nbr; | ||||
struct mp_ring **ift_br; | struct mp_ring **ift_br; | ||||
struct grouptask ift_task; | struct grouptask ift_task; | ||||
int ift_qstatus; | int ift_qstatus; | ||||
int ift_active; | int ift_active; | ||||
int ift_watchdog_time; | int ift_watchdog_time; | ||||
struct iflib_filter_info ift_filter_info; | struct iflib_filter_info ift_filter_info; | ||||
iflib_dma_info_t ift_ifdi; | iflib_dma_info_t ift_ifdi; | ||||
int ift_closed; | |||||
}; | }; | ||||
struct iflib_fl { | struct iflib_fl { | ||||
uint32_t ifl_cidx; | uint32_t ifl_cidx; | ||||
uint32_t ifl_pidx; | uint32_t ifl_pidx; | ||||
uint32_t ifl_gen; | uint32_t ifl_gen; | ||||
uint32_t ifl_size; | uint32_t ifl_size; | ||||
uint32_t ifl_credits; | uint32_t ifl_credits; | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
iflib_txq_t txq = r->cookie; | iflib_txq_t txq = r->cookie; | ||||
if_ctx_t ctx = txq->ift_ctx; | if_ctx_t ctx = txq->ift_ctx; | ||||
if_t ifp = ctx->ifc_ifp; | if_t ifp = ctx->ifc_ifp; | ||||
struct mbuf **mp = &txq->ift_mp[0]; | struct mbuf **mp = &txq->ift_mp[0]; | ||||
int i, count, pkt_sent, bytes_sent, mcast_sent, avail; | int i, count, pkt_sent, bytes_sent, mcast_sent, avail; | ||||
avail = IDXDIFF(pidx, cidx, r->size); | avail = IDXDIFF(pidx, cidx, r->size); | ||||
if (avail < (r->size >> 1)) { | |||||
txq->ift_closed = FALSE; | |||||
inp_rexmt_start(txq->ift_id, ctx->ifc_softc_ctx.isc_nqsets); | |||||
} | |||||
if (ctx->ifc_flags & IFC_QFLUSH) { | if (ctx->ifc_flags & IFC_QFLUSH) { | ||||
DBG_COUNTER_INC(txq_drain_flushing); | DBG_COUNTER_INC(txq_drain_flushing); | ||||
for (i = 0; i < avail; i++) { | for (i = 0; i < avail; i++) { | ||||
m_freem(r->items[(cidx + i) & (r->size-1)]); | m_freem(r->items[(cidx + i) & (r->size-1)]); | ||||
r->items[(cidx + i) & (r->size-1)] = NULL; | r->items[(cidx + i) & (r->size-1)] = NULL; | ||||
} | } | ||||
return (avail); | return (avail); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | |||||
int err, i, count, qidx; | int err, i, count, qidx; | ||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || !LINK_ACTIVE(ctx)) { | if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || !LINK_ACTIVE(ctx)) { | ||||
DBG_COUNTER_INC(tx_frees); | DBG_COUNTER_INC(tx_frees); | ||||
m_freem(m); | m_freem(m); | ||||
return (0); | return (0); | ||||
} | } | ||||
qidx = 0; | |||||
if ((NQSETS(ctx) > 1) && M_HASHTYPE_GET(m)) | |||||
qidx = QIDX(ctx, m); | |||||
/* | |||||
* XXX calculate buf_ring based on flowid (divvy up bits?) | |||||
*/ | |||||
txq = &ctx->ifc_txqs[qidx]; | |||||
if (txq->ift_closed) { | |||||
while (m != NULL) { | |||||
next = m->m_nextpkt; | |||||
m->m_nextpkt = NULL; | |||||
m_freem(m); | |||||
m = next; | |||||
} | |||||
return (ENOBUFS); | |||||
} | |||||
qidx = count = 0; | qidx = count = 0; | ||||
mp = marr; | mp = marr; | ||||
next = m; | next = m; | ||||
do { | do { | ||||
count++; | count++; | ||||
next = next->m_nextpkt; | next = next->m_nextpkt; | ||||
} while (next != NULL); | } while (next != NULL); | ||||
if (count > 16) | if (count > 16) | ||||
if ((mp = malloc(count*sizeof(struct mbuf *), M_IFLIB, M_NOWAIT)) == NULL) { | if ((mp = malloc(count*sizeof(struct mbuf *), M_IFLIB, M_NOWAIT)) == NULL) { | ||||
/* XXX check nextpkt */ | /* XXX check nextpkt */ | ||||
m_freem(m); | m_freem(m); | ||||
/* XXX simplify for now */ | /* XXX simplify for now */ | ||||
DBG_COUNTER_INC(tx_frees); | DBG_COUNTER_INC(tx_frees); | ||||
return (ENOBUFS); | return (ENOBUFS); | ||||
} | } | ||||
for (next = m, i = 0; next != NULL; i++) { | for (next = m, i = 0; next != NULL; i++) { | ||||
mp[i] = next; | mp[i] = next; | ||||
next = next->m_nextpkt; | next = next->m_nextpkt; | ||||
mp[i]->m_nextpkt = NULL; | mp[i]->m_nextpkt = NULL; | ||||
} | } | ||||
if ((NQSETS(ctx) > 1) && M_HASHTYPE_GET(m)) | |||||
qidx = QIDX(ctx, m); | |||||
/* | |||||
* XXX calculate buf_ring based on flowid (divvy up bits?) | |||||
*/ | |||||
txq = &ctx->ifc_txqs[qidx]; | |||||
DBG_COUNTER_INC(tx_seen); | DBG_COUNTER_INC(tx_seen); | ||||
err = mp_ring_enqueue(txq->ift_br[0], (void **)mp, count, IFLIB_BUDGET); | err = mp_ring_enqueue(txq->ift_br[0], (void **)mp, count, IFLIB_BUDGET); | ||||
/* drain => err = iflib_txq_transmit(ifp, txq, m); */ | /* drain => err = iflib_txq_transmit(ifp, txq, m); */ | ||||
if (err) { | if (err) { | ||||
txq->ift_closed = TRUE; | |||||
for (i = 0; i < count; i++) | for (i = 0; i < count; i++) | ||||
m_freem(mp[i]); | m_freem(mp[i]); | ||||
mp_ring_check_drainage(txq->ift_br[0], BATCH_SIZE); | mp_ring_check_drainage(txq->ift_br[0], BATCH_SIZE); | ||||
} | } | ||||
if (count > 16) | if (count > 16) | ||||
free(mp, M_IFLIB); | free(mp, M_IFLIB); | ||||
return (err); | return (err); | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
iflib_iov_intr_deferred(if_ctx_t ctx) | iflib_iov_intr_deferred(if_ctx_t ctx) | ||||
{ | { | ||||
GROUPTASK_ENQUEUE(&ctx->ifc_vflr_task); | GROUPTASK_ENQUEUE(&ctx->ifc_vflr_task); | ||||
} | } | ||||
void | void | ||||
iflib_io_tqg_attach(struct grouptask *gt, void *uniq, int cpu, char *name) | |||||
{ | |||||
taskqgroup_attach_cpu(gctx->igc_io_tqg, gt, uniq, cpu, -1, name); | |||||
} | |||||
void | |||||
iflib_link_state_change(if_ctx_t ctx, int link_state) | iflib_link_state_change(if_ctx_t ctx, int link_state) | ||||
{ | { | ||||
if_t ifp = ctx->ifc_ifp; | if_t ifp = ctx->ifc_ifp; | ||||
iflib_txq_t txq = ctx->ifc_txqs; | iflib_txq_t txq = ctx->ifc_txqs; | ||||
#if 0 | #if 0 | ||||
if_setbaudrate(ifp, baudrate); | if_setbaudrate(ifp, baudrate); | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 82 Lines • Show Last 20 Lines |