net/atlantic: implement device statistics

Add support for device stats, xstats and queue stats

Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
This commit is contained in:
Pavel Belous 2018-10-12 11:09:31 +00:00 committed by Ferruh Yigit
parent 7943ba05f6
commit fbe059e872
6 changed files with 189 additions and 1 deletions

View File

@ -13,6 +13,7 @@ Supported features
^^^^^^^^^^^^^^^^^^
- Base L2 features
- Port statistics
- Checksum offload
- Jumbo Frame upto 16K

View File

@ -13,6 +13,9 @@ CRC offload = Y
L3 checksum offload = Y
L4 checksum offload = Y
Packet type parsing = Y
Basic stats = Y
Extended stats = Y
Stats per queue = Y
FW version = Y
Linux UIO = Y
ARMv8 = Y

View File

@ -24,6 +24,18 @@ static void atl_dev_close(struct rte_eth_dev *dev);
static int atl_dev_reset(struct rte_eth_dev *dev);
static int atl_dev_link_update(struct rte_eth_dev *dev, int wait);
static int atl_dev_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
struct rte_eth_xstat_name *xstats_names,
unsigned int size);
static int atl_dev_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *stats);
static int atl_dev_xstats_get(struct rte_eth_dev *dev,
struct rte_eth_xstat *stats, unsigned int n);
static void atl_dev_stats_reset(struct rte_eth_dev *dev);
static int atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
size_t fw_size);
@ -116,6 +128,33 @@ static const struct rte_eth_desc_lim tx_desc_lim = {
.nb_mtu_seg_max = ATL_TX_MAX_SEG,
};
#define ATL_XSTATS_FIELD(name) { \
#name, \
offsetof(struct aq_stats_s, name) \
}
struct atl_xstats_tbl_s {
const char *name;
unsigned int offset;
};
static struct atl_xstats_tbl_s atl_xstats_tbl[] = {
ATL_XSTATS_FIELD(uprc),
ATL_XSTATS_FIELD(mprc),
ATL_XSTATS_FIELD(bprc),
ATL_XSTATS_FIELD(erpt),
ATL_XSTATS_FIELD(uptc),
ATL_XSTATS_FIELD(mptc),
ATL_XSTATS_FIELD(bptc),
ATL_XSTATS_FIELD(erpr),
ATL_XSTATS_FIELD(ubrc),
ATL_XSTATS_FIELD(ubtc),
ATL_XSTATS_FIELD(mbrc),
ATL_XSTATS_FIELD(mbtc),
ATL_XSTATS_FIELD(bbrc),
ATL_XSTATS_FIELD(bbtc),
};
static const struct eth_dev_ops atl_eth_dev_ops = {
.dev_configure = atl_dev_configure,
.dev_start = atl_dev_start,
@ -128,6 +167,13 @@ static const struct eth_dev_ops atl_eth_dev_ops = {
/* Link */
.link_update = atl_dev_link_update,
/* Stats */
.stats_get = atl_dev_stats_get,
.xstats_get = atl_dev_xstats_get,
.xstats_get_names = atl_dev_xstats_get_names,
.stats_reset = atl_dev_stats_reset,
.xstats_reset = atl_dev_stats_reset,
.fw_version_get = atl_fw_version_get,
.dev_infos_get = atl_dev_info_get,
.dev_supported_ptypes_get = atl_dev_supported_ptypes_get,
@ -224,6 +270,9 @@ eth_atl_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->data->mac_addrs->addr_bytes) != 0)
return -EINVAL;
/* Reset the hw statistics */
atl_dev_stats_reset(eth_dev);
rte_intr_callback_register(intr_handle,
atl_dev_interrupt_handler, eth_dev);
@ -542,6 +591,90 @@ atl_dev_reset(struct rte_eth_dev *dev)
return ret;
}
static int
atl_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
struct atl_adapter *adapter = ATL_DEV_TO_ADAPTER(dev);
struct aq_hw_s *hw = &adapter->hw;
struct atl_sw_stats *swstats = &adapter->sw_stats;
unsigned int i;
hw->aq_fw_ops->update_stats(hw);
/* Fill out the rte_eth_stats statistics structure */
stats->ipackets = hw->curr_stats.dma_pkt_rc;
stats->ibytes = hw->curr_stats.dma_oct_rc;
stats->imissed = hw->curr_stats.dpc;
stats->ierrors = hw->curr_stats.erpt;
stats->opackets = hw->curr_stats.dma_pkt_tc;
stats->obytes = hw->curr_stats.dma_oct_tc;
stats->oerrors = 0;
stats->rx_nombuf = swstats->rx_nombuf;
for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
stats->q_ipackets[i] = swstats->q_ipackets[i];
stats->q_opackets[i] = swstats->q_opackets[i];
stats->q_ibytes[i] = swstats->q_ibytes[i];
stats->q_obytes[i] = swstats->q_obytes[i];
stats->q_errors[i] = swstats->q_errors[i];
}
return 0;
}
static void
atl_dev_stats_reset(struct rte_eth_dev *dev)
{
struct atl_adapter *adapter = ATL_DEV_TO_ADAPTER(dev);
struct aq_hw_s *hw = &adapter->hw;
hw->aq_fw_ops->update_stats(hw);
/* Reset software totals */
memset(&hw->curr_stats, 0, sizeof(hw->curr_stats));
memset(&adapter->sw_stats, 0, sizeof(adapter->sw_stats));
}
static int
atl_dev_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
struct rte_eth_xstat_name *xstats_names,
unsigned int size)
{
unsigned int i;
if (!xstats_names)
return RTE_DIM(atl_xstats_tbl);
for (i = 0; i < size && i < RTE_DIM(atl_xstats_tbl); i++)
snprintf(xstats_names[i].name, RTE_ETH_XSTATS_NAME_SIZE, "%s",
atl_xstats_tbl[i].name);
return size;
}
static int
atl_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
unsigned int n)
{
struct atl_adapter *adapter = ATL_DEV_TO_ADAPTER(dev);
struct aq_hw_s *hw = &adapter->hw;
unsigned int i;
if (!stats)
return 0;
for (i = 0; i < n && i < RTE_DIM(atl_xstats_tbl); i++) {
stats[i].id = i;
stats[i].value = *(u64 *)((uint8_t *)&hw->curr_stats +
atl_xstats_tbl[i].offset);
}
return n;
}
static int
atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
{

View File

@ -33,6 +33,7 @@ struct atl_interrupt {
struct atl_adapter {
struct aq_hw_s hw;
struct aq_hw_cfg_s hw_cfg;
struct atl_sw_stats sw_stats;
struct atl_interrupt intr;
};

View File

@ -874,6 +874,7 @@ atl_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
"queue_id=%u", (unsigned int)rxq->port_id,
(unsigned int)rxq->queue_id);
dev->data->rx_mbuf_alloc_failed++;
adapter->sw_stats.rx_nombuf++;
goto err_stop;
}
@ -957,6 +958,9 @@ atl_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
* of returned packets.
*/
rx_pkts[nb_rx++] = rx_mbuf_first;
adapter->sw_stats.q_ipackets[rxq->queue_id]++;
adapter->sw_stats.q_ibytes[rxq->queue_id] +=
rx_mbuf_first->pkt_len;
PMD_RX_LOG(ERR, "add mbuf segs=%d pkt_len=%d",
rx_mbuf_first->nb_segs,
@ -1102,6 +1106,8 @@ static inline void
atl_xmit_pkt(struct aq_hw_s *hw, struct atl_tx_queue *txq,
struct rte_mbuf *tx_pkt)
{
struct atl_adapter *adapter =
ATL_DEV_TO_ADAPTER(&rte_eth_devices[txq->port_id]);
uint32_t pay_len = 0;
int tail = 0;
struct atl_tx_entry *tx_entry;
@ -1182,6 +1188,9 @@ atl_xmit_pkt(struct aq_hw_s *hw, struct atl_tx_queue *txq,
txq->tx_tail = tail;
txq->tx_free -= desc_count;
adapter->sw_stats.q_opackets[txq->queue_id]++;
adapter->sw_stats.q_obytes[txq->queue_id] += pay_len;
}
uint16_t

View File

@ -140,4 +140,45 @@ struct aq_fw_ops {
int (*set_eeprom)(struct aq_hw_s *self, u32 *data, u32 len);
};
struct atl_sw_stats {
u64 crcerrs;
u64 errbc;
u64 mspdc;
u64 mpctotal;
u64 mpc[8];
u64 mlfc;
u64 mrfc;
u64 rlec;
u64 lxontxc;
u64 lxonrxc;
u64 lxofftxc;
u64 lxoffrxc;
u64 pxontxc[8];
u64 pxonrxc[8];
u64 pxofftxc[8];
u64 pxoffrxc[8];
u64 gprc;
u64 bprc;
u64 mprc;
u64 gptc;
u64 gorc;
u64 gotc;
u64 tor;
u64 tpr;
u64 tpt;
u64 mptc;
u64 bptc;
u64 xec;
u64 fccrc;
u64 ldpcec;
u64 pcrc8ec;
u64 rx_nombuf;
u64 q_ipackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
u64 q_opackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
u64 q_ibytes[RTE_ETHDEV_QUEUE_STAT_CNTRS];
u64 q_obytes[RTE_ETHDEV_QUEUE_STAT_CNTRS];
u64 q_errors[RTE_ETHDEV_QUEUE_STAT_CNTRS];
};
#endif