Signed-off-by: Howard Wang <howard_w...@realsil.com.cn> --- drivers/net/r8169/r8169_base.h | 16 +++++++ drivers/net/r8169/r8169_ethdev.c | 48 +++++++++++++++++++ drivers/net/r8169/r8169_ethdev.h | 3 ++ drivers/net/r8169/r8169_hw.c | 80 ++++++++++++++++++++++++++++++++ drivers/net/r8169/r8169_hw.h | 6 +++ 5 files changed, 153 insertions(+)
diff --git a/drivers/net/r8169/r8169_base.h b/drivers/net/r8169/r8169_base.h index 2120337b3e..04ca305d97 100644 --- a/drivers/net/r8169/r8169_base.h +++ b/drivers/net/r8169/r8169_base.h @@ -24,6 +24,22 @@ typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; +struct rtl_counters { + u64 tx_packets; + u64 rx_packets; + u64 tx_errors; + u32 rx_errors; + u16 rx_missed; + u16 align_errors; + u32 tx_one_collision; + u32 tx_multi_collision; + u64 rx_unicast; + u64 rx_broadcast; + u32 rx_multicast; + u16 tx_aborted; + u16 tx_underun; +}; + enum mcfg { CFG_METHOD_1 = 1, CFG_METHOD_2, diff --git a/drivers/net/r8169/r8169_ethdev.c b/drivers/net/r8169/r8169_ethdev.c index 30bb9ad0ae..3597fe5982 100644 --- a/drivers/net/r8169/r8169_ethdev.c +++ b/drivers/net/r8169/r8169_ethdev.c @@ -40,6 +40,9 @@ static int rtl_dev_set_link_up(struct rte_eth_dev *dev); static int rtl_dev_set_link_down(struct rte_eth_dev *dev); static int rtl_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info); +static int rtl_dev_stats_get(struct rte_eth_dev *dev, + struct rte_eth_stats *rte_stats); +static int rtl_dev_stats_reset(struct rte_eth_dev *dev); /* * The set of PCI devices this driver supports @@ -78,6 +81,9 @@ static const struct eth_dev_ops rtl_eth_dev_ops = { .link_update = rtl_dev_link_update, + .stats_get = rtl_dev_stats_get, + .stats_reset = rtl_dev_stats_reset, + .rx_queue_setup = rtl_rx_queue_setup, .rx_queue_release = rtl_rx_queue_release, .rxq_info_get = rtl_rxq_info_get, @@ -241,6 +247,11 @@ rtl_dev_start(struct rte_eth_dev *dev) goto error; } + /* This can fail when allocating mem for tally counters */ + err = rtl_tally_init(dev); + if (err) + goto error; + /* Enable uio/vfio intr/eventfd mapping */ rte_intr_enable(intr_handle); @@ -287,6 +298,8 @@ rtl_dev_stop(struct rte_eth_dev *dev) rtl_stop_queues(dev); + rtl_tally_free(dev); + /* Clear the recorded link status */ memset(&link, 0, sizeof(link)); rte_eth_linkstatus_set(dev, &link); @@ -372,6 +385,41 @@ rtl_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) return 0; } +static int +rtl_dev_stats_reset(struct rte_eth_dev *dev) +{ + struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); + struct rtl_hw *hw = &adapter->hw; + + rtl_clear_tally_stats(hw); + + memset(&adapter->sw_stats, 0, sizeof(adapter->sw_stats)); + + return 0; +} + +static void +rtl_sw_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats) +{ + struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); + struct rtl_sw_stats *sw_stats = &adapter->sw_stats; + + rte_stats->ibytes = sw_stats->rx_bytes; + rte_stats->obytes = sw_stats->tx_bytes; +} + +static int +rtl_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats) +{ + struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); + struct rtl_hw *hw = &adapter->hw; + + rtl_get_tally_stats(hw, rte_stats); + rtl_sw_stats_get(dev, rte_stats); + + return 0; +} + /* Return 0 means link status changed, -1 means not changed */ static int rtl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused) diff --git a/drivers/net/r8169/r8169_ethdev.h b/drivers/net/r8169/r8169_ethdev.h index f67fa59c84..77999c6e2f 100644 --- a/drivers/net/r8169/r8169_ethdev.h +++ b/drivers/net/r8169/r8169_ethdev.h @@ -47,6 +47,9 @@ struct rtl_hw { u8 mac_addr[MAC_ADDR_LEN]; u32 rx_buf_sz; + struct rtl_counters *tally_vaddr; + u64 tally_paddr; + u8 RequirePhyMdiSwapPatch; u8 NotWrMcuPatchCode; u8 HwSuppMacMcuVer; diff --git a/drivers/net/r8169/r8169_hw.c b/drivers/net/r8169/r8169_hw.c index 3bb848714c..55775ee788 100644 --- a/drivers/net/r8169/r8169_hw.c +++ b/drivers/net/r8169/r8169_hw.c @@ -1504,3 +1504,83 @@ rtl_rar_set(struct rtl_hw *hw, uint8_t *addr) rtl_disable_cfg9346_write(hw); } +void +rtl_get_tally_stats(struct rtl_hw *hw, struct rte_eth_stats *rte_stats) +{ + struct rtl_counters *counters; + uint64_t paddr; + u32 cmd; + u32 wait_cnt; + + counters = hw->tally_vaddr; + paddr = hw->tally_paddr; + if (!counters) + return; + + RTL_W32(hw, CounterAddrHigh, (u64)paddr >> 32); + cmd = (u64)paddr & DMA_BIT_MASK(32); + RTL_W32(hw, CounterAddrLow, cmd); + RTL_W32(hw, CounterAddrLow, cmd | CounterDump); + + wait_cnt = 0; + while (RTL_R32(hw, CounterAddrLow) & CounterDump) { + rte_delay_us(10); + + wait_cnt++; + if (wait_cnt > 20) + break; + } + + /* RX errors */ + rte_stats->imissed = rte_le_to_cpu_64(counters->rx_missed); + rte_stats->ierrors = rte_le_to_cpu_64(counters->rx_errors); + + /* TX errors */ + rte_stats->oerrors = rte_le_to_cpu_64(counters->tx_errors); + + rte_stats->ipackets = rte_le_to_cpu_64(counters->rx_packets); + rte_stats->opackets = rte_le_to_cpu_64(counters->tx_packets); +} + +void +rtl_clear_tally_stats(struct rtl_hw *hw) +{ + if (!hw->tally_paddr) + return; + + RTL_W32(hw, CounterAddrHigh, (u64)hw->tally_paddr >> 32); + RTL_W32(hw, CounterAddrLow, + ((u64)hw->tally_paddr & (DMA_BIT_MASK(32))) | CounterReset); +} + +int +rtl_tally_init(struct rte_eth_dev *dev) +{ + struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); + struct rtl_hw *hw = &adapter->hw; + const struct rte_memzone *mz; + + mz = rte_eth_dma_zone_reserve(dev, "tally_counters", 0, + sizeof(struct rtl_counters), 64, rte_socket_id()); + if (mz == NULL) + return -ENOMEM; + + hw->tally_vaddr = mz->addr; + hw->tally_paddr = mz->iova; + + /* Fill tally addrs */ + RTL_W32(hw, CounterAddrHigh, (u64)hw->tally_paddr >> 32); + RTL_W32(hw, CounterAddrLow, (u64)hw->tally_paddr & (DMA_BIT_MASK(32))); + + /* Reset the hw statistics */ + rtl_clear_tally_stats(hw); + + return 0; +} + +void +rtl_tally_free(struct rte_eth_dev *dev) +{ + rte_eth_dma_zone_free(dev, "tally_counters", 0); +} + diff --git a/drivers/net/r8169/r8169_hw.h b/drivers/net/r8169/r8169_hw.h index 0094a5a4cb..a045948252 100644 --- a/drivers/net/r8169/r8169_hw.h +++ b/drivers/net/r8169/r8169_hw.h @@ -54,6 +54,12 @@ void rtl_rar_set(struct rtl_hw *hw, uint8_t *addr); void rtl_set_link_option(struct rtl_hw *hw, u8 autoneg, u32 speed, u8 duplex, enum rtl_fc_mode fc); +void rtl_get_tally_stats(struct rtl_hw *hw, struct rte_eth_stats *rte_stats); +void rtl_clear_tally_stats(struct rtl_hw *hw); + +int rtl_tally_init(struct rte_eth_dev *dev); +void rtl_tally_free(struct rte_eth_dev *dev); + extern const struct rtl_hw_ops rtl8125a_ops; extern const struct rtl_hw_ops rtl8125b_ops; extern const struct rtl_hw_ops rtl8125bp_ops; -- 2.34.1