Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/e1000/if_igb.c
Show First 20 Lines • Show All 1,040 Lines • ▼ Show 20 Lines | if ((err = igb_xmit(txr, &next)) != 0) { | ||||
* may have changed it. | * may have changed it. | ||||
*/ | */ | ||||
drbr_putback(ifp, txr->br, next); | drbr_putback(ifp, txr->br, next); | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
drbr_advance(ifp, txr->br); | drbr_advance(ifp, txr->br); | ||||
enq++; | enq++; | ||||
if_inc_counter(ifp, IFCOUNTER_OBYTES, next->m_pkthdr.len); | if (next->m_flags & M_MCAST && adapter->vf_ifp) | ||||
if (next->m_flags & M_MCAST) | |||||
if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1); | if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1); | ||||
ETHER_BPF_MTAP(ifp, next); | ETHER_BPF_MTAP(ifp, next); | ||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) | if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) | ||||
break; | break; | ||||
} | } | ||||
if (enq > 0) { | if (enq > 0) { | ||||
/* Set the watchdog */ | /* Set the watchdog */ | ||||
txr->queue_status |= IGB_QUEUE_WORKING; | txr->queue_status |= IGB_QUEUE_WORKING; | ||||
▲ Show 20 Lines • Show All 2,991 Lines • ▼ Show 20 Lines | |||||
* tx_buffer is put back on the free queue. | * tx_buffer is put back on the free queue. | ||||
* | * | ||||
* TRUE return means there's work in the ring to clean, FALSE its empty. | * TRUE return means there's work in the ring to clean, FALSE its empty. | ||||
**********************************************************************/ | **********************************************************************/ | ||||
static bool | static bool | ||||
igb_txeof(struct tx_ring *txr) | igb_txeof(struct tx_ring *txr) | ||||
{ | { | ||||
struct adapter *adapter = txr->adapter; | struct adapter *adapter = txr->adapter; | ||||
#ifdef DEV_NETMAP | |||||
struct ifnet *ifp = adapter->ifp; | struct ifnet *ifp = adapter->ifp; | ||||
#endif /* DEV_NETMAP */ | |||||
u32 work, processed = 0; | u32 work, processed = 0; | ||||
u16 limit = txr->process_limit; | u16 limit = txr->process_limit; | ||||
struct igb_tx_buf *buf; | struct igb_tx_buf *buf; | ||||
union e1000_adv_tx_desc *txd; | union e1000_adv_tx_desc *txd; | ||||
mtx_assert(&txr->tx_mtx, MA_OWNED); | mtx_assert(&txr->tx_mtx, MA_OWNED); | ||||
#ifdef DEV_NETMAP | #ifdef DEV_NETMAP | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | while (txd != eop) { | ||||
buf->m_head = NULL; | buf->m_head = NULL; | ||||
} | } | ||||
++txr->tx_avail; | ++txr->tx_avail; | ||||
buf->eop = NULL; | buf->eop = NULL; | ||||
} | } | ||||
++txr->packets; | ++txr->packets; | ||||
++processed; | ++processed; | ||||
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); | |||||
txr->watchdog_time = ticks; | txr->watchdog_time = ticks; | ||||
/* Try the next packet */ | /* Try the next packet */ | ||||
++txd; | ++txd; | ||||
++buf; | ++buf; | ||||
++work; | ++work; | ||||
/* reset with a wrap */ | /* reset with a wrap */ | ||||
if (__predict_false(!work)) { | if (__predict_false(!work)) { | ||||
▲ Show 20 Lines • Show All 980 Lines • ▼ Show 20 Lines | if (rxr->fmp == NULL) { | ||||
/* Chain mbuf's together */ | /* Chain mbuf's together */ | ||||
rxr->lmp->m_next = mh; | rxr->lmp->m_next = mh; | ||||
rxr->lmp = rxr->lmp->m_next; | rxr->lmp = rxr->lmp->m_next; | ||||
rxr->fmp->m_pkthdr.len += mh->m_len; | rxr->fmp->m_pkthdr.len += mh->m_len; | ||||
} | } | ||||
if (eop) { | if (eop) { | ||||
rxr->fmp->m_pkthdr.rcvif = ifp; | rxr->fmp->m_pkthdr.rcvif = ifp; | ||||
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); | |||||
rxr->rx_packets++; | rxr->rx_packets++; | ||||
/* capture data for AIM */ | /* capture data for AIM */ | ||||
rxr->packets++; | rxr->packets++; | ||||
rxr->bytes += rxr->fmp->m_pkthdr.len; | rxr->bytes += rxr->fmp->m_pkthdr.len; | ||||
rxr->rx_bytes += rxr->fmp->m_pkthdr.len; | rxr->rx_bytes += rxr->fmp->m_pkthdr.len; | ||||
if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) | if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) | ||||
igb_rx_checksum(staterr, rxr->fmp, ptype); | igb_rx_checksum(staterr, rxr->fmp, ptype); | ||||
▲ Show 20 Lines • Show All 416 Lines • ▼ Show 20 Lines | igb_led_func(void *arg, int onoff) | ||||
} else { | } else { | ||||
e1000_led_off(&adapter->hw); | e1000_led_off(&adapter->hw); | ||||
e1000_cleanup_led(&adapter->hw); | e1000_cleanup_led(&adapter->hw); | ||||
} | } | ||||
IGB_CORE_UNLOCK(adapter); | IGB_CORE_UNLOCK(adapter); | ||||
} | } | ||||
static uint64_t | static uint64_t | ||||
igb_get_vf_counter(if_t ifp, ift_counter cnt) | |||||
{ | |||||
struct adapter *adapter; | |||||
struct e1000_vf_stats *stats; | |||||
#ifndef IGB_LEGACY_TX | |||||
struct tx_ring *txr; | |||||
uint64_t rv; | |||||
#endif | |||||
adapter = if_getsoftc(ifp); | |||||
stats = (struct e1000_vf_stats *)adapter->stats; | |||||
switch (cnt) { | |||||
case IFCOUNTER_IPACKETS: | |||||
return (stats->gprc); | |||||
case IFCOUNTER_OPACKETS: | |||||
return (stats->gptc); | |||||
case IFCOUNTER_IBYTES: | |||||
return (stats->gorc); | |||||
case IFCOUNTER_OBYTES: | |||||
return (stats->gotc); | |||||
case IFCOUNTER_IMCASTS: | |||||
return (stats->mprc); | |||||
case IFCOUNTER_IERRORS: | |||||
return (adapter->dropped_pkts); | |||||
case IFCOUNTER_OERRORS: | |||||
return (adapter->watchdog_events); | |||||
#ifndef IGB_LEGACY_TX | |||||
case IFCOUNTER_OQDROPS: | |||||
rv = 0; | |||||
txr = adapter->tx_rings; | |||||
for (int i = 0; i < adapter->num_queues; i++, txr++) | |||||
rv += txr->br->br_drops; | |||||
return (rv); | |||||
#endif | |||||
default: | |||||
return (if_get_counter_default(ifp, cnt)); | |||||
} | |||||
} | |||||
static uint64_t | |||||
igb_get_counter(if_t ifp, ift_counter cnt) | igb_get_counter(if_t ifp, ift_counter cnt) | ||||
{ | { | ||||
struct adapter *adapter; | struct adapter *adapter; | ||||
struct e1000_hw_stats *stats; | struct e1000_hw_stats *stats; | ||||
#ifndef IGB_LEGACY_TX | |||||
struct tx_ring *txr; | |||||
uint64_t rv; | |||||
#endif | |||||
adapter = if_getsoftc(ifp); | adapter = if_getsoftc(ifp); | ||||
if (adapter->vf_ifp) | |||||
return (igb_get_vf_counter(ifp, cnt)); | |||||
stats = (struct e1000_hw_stats *)adapter->stats; | stats = (struct e1000_hw_stats *)adapter->stats; | ||||
switch (cnt) { | switch (cnt) { | ||||
case IFCOUNTER_IPACKETS: | |||||
return (stats->gprc); | |||||
case IFCOUNTER_OPACKETS: | |||||
return (stats->gptc); | |||||
case IFCOUNTER_IBYTES: | |||||
return (stats->gorc); | |||||
case IFCOUNTER_OBYTES: | |||||
return (stats->gotc); | |||||
case IFCOUNTER_IMCASTS: | |||||
return (stats->mprc); | |||||
case IFCOUNTER_OMCASTS: | |||||
return (stats->mptc); | |||||
case IFCOUNTER_IERRORS: | case IFCOUNTER_IERRORS: | ||||
return (adapter->dropped_pkts + stats->rxerrc + | return (adapter->dropped_pkts + stats->rxerrc + | ||||
stats->crcerrs + stats->algnerrc + | stats->crcerrs + stats->algnerrc + | ||||
stats->ruc + stats->roc + stats->mpc + stats->cexterr); | stats->ruc + stats->roc + stats->cexterr); | ||||
case IFCOUNTER_OERRORS: | case IFCOUNTER_OERRORS: | ||||
return (stats->ecol + stats->latecol + | return (stats->ecol + stats->latecol + | ||||
adapter->watchdog_events); | adapter->watchdog_events); | ||||
case IFCOUNTER_COLLISIONS: | case IFCOUNTER_COLLISIONS: | ||||
return (stats->colc); | return (stats->colc); | ||||
case IFCOUNTER_IQDROPS: | |||||
return (stats->mpc); | |||||
#ifndef IGB_LEGACY_TX | |||||
case IFCOUNTER_OQDROPS: | |||||
rv = 0; | |||||
txr = adapter->tx_rings; | |||||
for (int i = 0; i < adapter->num_queues; i++, txr++) | |||||
rv += txr->br->br_drops; | |||||
return (rv); | |||||
#endif | |||||
default: | default: | ||||
return (if_get_counter_default(ifp, cnt)); | return (if_get_counter_default(ifp, cnt)); | ||||
} | } | ||||
} | } | ||||
/********************************************************************** | /********************************************************************** | ||||
* | * | ||||
* Update the board statistics counters. | * Update the board statistics counters. | ||||
▲ Show 20 Lines • Show All 807 Lines • Show Last 20 Lines |