Add support for the set_ringparam in wx_ethtool_ops_vf, which is used to set ring sizes for ngbevf and txgbevf. Signed-off-by: Mengyuan Lou --- .../net/ethernet/wangxun/libwx/wx_ethtool.c | 60 +++++++++++++++++++ .../net/ethernet/wangxun/libwx/wx_vf_common.c | 4 +- .../net/ethernet/wangxun/libwx/wx_vf_common.h | 2 + 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c index 5df971aca9e3..31034cd20870 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c @@ -9,6 +9,7 @@ #include "wx_ethtool.h" #include "wx_hw.h" #include "wx_lib.h" +#include "wx_vf_common.h" struct wx_stats { char stat_string[ETH_GSTRING_LEN]; @@ -775,6 +776,64 @@ static int wx_get_link_ksettings_vf(struct net_device *netdev, return 0; } +static int wx_set_ringparam_vf(struct net_device *netdev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam *kernel_ring, + struct netlink_ext_ack *extack) +{ + struct wx *wx = netdev_priv(netdev); + u32 new_rx_count, new_tx_count; + struct wx_ring *temp_ring; + int i, err = 0; + + new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD); + new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE); + + new_rx_count = clamp_t(u32, ring->rx_pending, WX_MIN_RXD, WX_MAX_RXD); + new_rx_count = ALIGN(new_rx_count, WX_REQ_RX_DESCRIPTOR_MULTIPLE); + + if (new_tx_count == wx->tx_ring_count && + new_rx_count == wx->rx_ring_count) + return 0; + + mutex_lock(&wx->reset_lock); + set_bit(WX_STATE_RESETTING, wx->state); + + if (!netif_running(wx->netdev)) { + for (i = 0; i < wx->num_tx_queues; i++) + wx->tx_ring[i]->count = new_tx_count; + for (i = 0; i < wx->num_rx_queues; i++) + wx->rx_ring[i]->count = new_rx_count; + wx->tx_ring_count = new_tx_count; + wx->rx_ring_count = new_rx_count; + + goto clear_reset; + } + + /* allocate temporary buffer to store rings in */ + i = max_t(int, wx->num_tx_queues, wx->num_rx_queues); + temp_ring = kvmalloc_objs(struct wx_ring, i); + if (!temp_ring) { + err = -ENOMEM; + goto clear_reset; + } + + wxvf_down(wx); + wx_free_irq(wx); + + wx_set_ring(wx, new_tx_count, new_rx_count, temp_ring); + kvfree(temp_ring); + + wx_configure_vf(wx); + wx_request_msix_irqs_vf(wx); + wxvf_up_complete(wx); + +clear_reset: + clear_bit(WX_STATE_RESETTING, wx->state); + mutex_unlock(&wx->reset_lock); + return err; +} + static const struct ethtool_ops wx_ethtool_ops_vf = { .supported_coalesce_params = ETHTOOL_COALESCE_USECS | ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ | @@ -782,6 +841,7 @@ static const struct ethtool_ops wx_ethtool_ops_vf = { .get_drvinfo = wx_get_drvinfo, .get_link = ethtool_op_get_link, .get_ringparam = wx_get_ringparam, + .set_ringparam = wx_set_ringparam_vf, .get_msglevel = wx_get_msglevel, .get_coalesce = wx_get_coalesce, .get_ts_info = ethtool_op_get_ts_info, diff --git a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c index 94ff8f5f0b4c..a3361696b783 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c @@ -269,7 +269,7 @@ static void wxvf_irq_enable(struct wx *wx) wr32(wx, WX_VXIMC, wx->eims_enable_mask); } -static void wxvf_up_complete(struct wx *wx) +void wxvf_up_complete(struct wx *wx) { /* Always set the carrier off */ netif_carrier_off(wx->netdev); @@ -323,7 +323,7 @@ int wxvf_open(struct net_device *netdev) } EXPORT_SYMBOL(wxvf_open); -static void wxvf_down(struct wx *wx) +void wxvf_down(struct wx *wx) { struct net_device *netdev = wx->netdev; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.h b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.h index cbbb1b178cb2..d45d5d8ac3ab 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.h @@ -15,7 +15,9 @@ void wx_set_rx_mode_vf(struct net_device *netdev); void wx_configure_vf(struct wx *wx); int wx_set_mac_vf(struct net_device *netdev, void *p); void wxvf_watchdog_update_link(struct wx *wx); +void wxvf_up_complete(struct wx *wx); int wxvf_open(struct net_device *netdev); +void wxvf_down(struct wx *wx); int wxvf_close(struct net_device *netdev); void wxvf_init_service(struct wx *wx); -- 2.50.1 (Apple Git-155) Add support for set_coalesce in wx_ethtool_ops_vf, which is used to set interrupt coalescing parameters. Signed-off-by: Mengyuan Lou --- drivers/net/ethernet/wangxun/libwx/wx_ethtool.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c index 31034cd20870..ab8796ea6535 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c @@ -10,6 +10,7 @@ #include "wx_hw.h" #include "wx_lib.h" #include "wx_vf_common.h" +#include "wx_vf_lib.h" struct wx_stats { char stat_string[ETH_GSTRING_LEN]; @@ -488,7 +489,10 @@ int wx_set_coalesce(struct net_device *netdev, else /* rx only or mixed */ q_vector->itr = rx_itr_param; - wx_write_eitr(q_vector); + if (wx->pdev->is_virtfn) + wx_write_eitr_vf(q_vector); + else + wx_write_eitr(q_vector); } wx_update_rsc(wx); @@ -844,6 +848,7 @@ static const struct ethtool_ops wx_ethtool_ops_vf = { .set_ringparam = wx_set_ringparam_vf, .get_msglevel = wx_get_msglevel, .get_coalesce = wx_get_coalesce, + .set_coalesce = wx_set_coalesce, .get_ts_info = ethtool_op_get_ts_info, .get_link_ksettings = wx_get_link_ksettings_vf, }; -- 2.50.1 (Apple Git-155) Add support to show hardware statistics for ethtool -S ethx. Signed-off-by: Mengyuan Lou --- .../net/ethernet/wangxun/libwx/wx_ethtool.c | 35 +++++++-- drivers/net/ethernet/wangxun/libwx/wx_hw.c | 75 ++++++++++--------- .../net/ethernet/wangxun/libwx/wx_vf_common.c | 3 + 3 files changed, 70 insertions(+), 43 deletions(-) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c index ab8796ea6535..6380074e23dd 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c @@ -48,6 +48,14 @@ static const struct wx_stats wx_gstrings_stats[] = { WX_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared), }; +static const struct wx_stats wx_gstrings_stats_vf[] = { + WX_STAT("tx_busy", tx_busy), + WX_STAT("non_eop_descs", non_eop_descs), + WX_STAT("rx_csum_offload_good_count", hw_csum_rx_good), + WX_STAT("rx_csum_offload_errors", hw_csum_rx_error), + WX_STAT("alloc_rx_buff_failed", alloc_rx_buff_failed), +}; + static const struct wx_stats wx_gstrings_fdir_stats[] = { WX_STAT("fdir_match", stats.fdirmatch), WX_STAT("fdir_miss", stats.fdirmiss), @@ -69,7 +77,9 @@ static const struct wx_stats wx_gstrings_rsc_stats[] = { #define WX_QUEUE_STATS_LEN ( \ (WX_NUM_TX_QUEUES + WX_NUM_RX_QUEUES) * \ (sizeof(struct wx_queue_stats) / sizeof(u64))) -#define WX_GLOBAL_STATS_LEN ARRAY_SIZE(wx_gstrings_stats) +#define WX_GLOBAL_STATS_LEN (wx->pdev->is_virtfn ? \ + ARRAY_SIZE(wx_gstrings_stats_vf) : \ + ARRAY_SIZE(wx_gstrings_stats)) #define WX_FDIR_STATS_LEN ARRAY_SIZE(wx_gstrings_fdir_stats) #define WX_RSC_STATS_LEN ARRAY_SIZE(wx_gstrings_rsc_stats) #define WX_STATS_LEN (WX_GLOBAL_STATS_LEN + WX_QUEUE_STATS_LEN) @@ -101,7 +111,10 @@ void wx_get_strings(struct net_device *netdev, u32 stringset, u8 *data) switch (stringset) { case ETH_SS_STATS: for (i = 0; i < WX_GLOBAL_STATS_LEN; i++) - ethtool_puts(&p, wx_gstrings_stats[i].stat_string); + if (wx->pdev->is_virtfn) + ethtool_puts(&p, wx_gstrings_stats_vf[i].stat_string); + else + ethtool_puts(&p, wx_gstrings_stats[i].stat_string); if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) { for (i = 0; i < WX_FDIR_STATS_LEN; i++) ethtool_puts(&p, wx_gstrings_fdir_stats[i].stat_string); @@ -135,9 +148,15 @@ void wx_get_ethtool_stats(struct net_device *netdev, wx_update_stats(wx); for (i = 0; i < WX_GLOBAL_STATS_LEN; i++) { - p = (char *)wx + wx_gstrings_stats[i].stat_offset; - data[i] = (wx_gstrings_stats[i].sizeof_stat == - sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + if (wx->pdev->is_virtfn) { + p = (char *)wx + wx_gstrings_stats_vf[i].stat_offset; + data[i] = (wx_gstrings_stats_vf[i].sizeof_stat == + sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + } else { + p = (char *)wx + wx_gstrings_stats[i].stat_offset; + data[i] = (wx_gstrings_stats[i].sizeof_stat == + sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + } } if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) { @@ -219,9 +238,10 @@ EXPORT_SYMBOL(wx_get_pause_stats); void wx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info) { - unsigned int stats_len = WX_STATS_LEN; struct wx *wx = netdev_priv(netdev); + unsigned int stats_len; + stats_len = WX_STATS_LEN; if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) stats_len += WX_FDIR_STATS_LEN; @@ -851,6 +871,9 @@ static const struct ethtool_ops wx_ethtool_ops_vf = { .set_coalesce = wx_set_coalesce, .get_ts_info = ethtool_op_get_ts_info, .get_link_ksettings = wx_get_link_ksettings_vf, + .get_sset_count = wx_get_sset_count, + .get_strings = wx_get_strings, + .get_ethtool_stats = wx_get_ethtool_stats, }; void wx_set_ethtool_ops_vf(struct net_device *netdev) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c index 2451f6b20b11..7244aee3fc74 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c @@ -2916,45 +2916,46 @@ void wx_update_stats(struct wx *wx) wx->restart_queue = restart_queue; wx->tx_busy = tx_busy; - wx_update_xoff_rx_lfc(wx); - - hwstats->gprc += rd32(wx, WX_RDM_PKT_CNT); - hwstats->gptc += rd32(wx, WX_TDM_PKT_CNT); - hwstats->gorc += rd64(wx, WX_RDM_BYTE_CNT_LSB); - hwstats->gotc += rd64(wx, WX_TDM_BYTE_CNT_LSB); - hwstats->tpr += rd64(wx, WX_RX_FRAME_CNT_GOOD_BAD_L); - hwstats->tpt += rd64(wx, WX_TX_FRAME_CNT_GOOD_BAD_L); - hwstats->crcerrs += rd64(wx, WX_RX_CRC_ERROR_FRAMES_L); - hwstats->rlec += rd64(wx, WX_RX_LEN_ERROR_FRAMES_L); - hwstats->bprc += rd64(wx, WX_RX_BC_FRAMES_GOOD_L); - hwstats->bptc += rd64(wx, WX_TX_BC_FRAMES_GOOD_L); - hwstats->mprc += rd64(wx, WX_RX_MC_FRAMES_GOOD_L); - hwstats->mptc += rd64(wx, WX_TX_MC_FRAMES_GOOD_L); - hwstats->roc += rd32(wx, WX_RX_OVERSIZE_FRAMES_GOOD); - hwstats->ruc += rd32(wx, WX_RX_UNDERSIZE_FRAMES_GOOD); - if (wx->mac.type >= wx_mac_aml) - hwstats->lxonrxc += rd32_wrap(wx, WX_MAC_LXONRXC_AML, - &wx->last_stats.lxonrxc); - else - hwstats->lxonrxc += rd32(wx, WX_MAC_LXONRXC); - hwstats->lxontxc += rd32(wx, WX_RDB_LXONTXC); - hwstats->lxofftxc += rd32(wx, WX_RDB_LXOFFTXC); - hwstats->o2bgptc += rd32(wx, WX_TDM_OS2BMC_CNT); - hwstats->b2ospc += rd32(wx, WX_MNG_BMC2OS_CNT); - hwstats->o2bspc += rd32(wx, WX_MNG_OS2BMC_CNT); - hwstats->b2ogprc += rd32(wx, WX_RDM_BMC2OS_CNT); - hwstats->rdmdrop += rd32(wx, WX_RDM_DRP_PKT); + if (wx->pdev->is_physfn) { + wx_update_xoff_rx_lfc(wx); + + hwstats->gprc += rd32(wx, WX_RDM_PKT_CNT); + hwstats->gptc += rd32(wx, WX_TDM_PKT_CNT); + hwstats->gorc += rd64(wx, WX_RDM_BYTE_CNT_LSB); + hwstats->gotc += rd64(wx, WX_TDM_BYTE_CNT_LSB); + hwstats->tpr += rd64(wx, WX_RX_FRAME_CNT_GOOD_BAD_L); + hwstats->tpt += rd64(wx, WX_TX_FRAME_CNT_GOOD_BAD_L); + hwstats->crcerrs += rd64(wx, WX_RX_CRC_ERROR_FRAMES_L); + hwstats->rlec += rd64(wx, WX_RX_LEN_ERROR_FRAMES_L); + hwstats->bprc += rd64(wx, WX_RX_BC_FRAMES_GOOD_L); + hwstats->bptc += rd64(wx, WX_TX_BC_FRAMES_GOOD_L); + hwstats->mprc += rd64(wx, WX_RX_MC_FRAMES_GOOD_L); + hwstats->mptc += rd64(wx, WX_TX_MC_FRAMES_GOOD_L); + hwstats->roc += rd32(wx, WX_RX_OVERSIZE_FRAMES_GOOD); + hwstats->ruc += rd32(wx, WX_RX_UNDERSIZE_FRAMES_GOOD); + if (wx->mac.type >= wx_mac_aml) + hwstats->lxonrxc += rd32_wrap(wx, WX_MAC_LXONRXC_AML, + &wx->last_stats.lxonrxc); + else + hwstats->lxonrxc += rd32(wx, WX_MAC_LXONRXC); + hwstats->lxontxc += rd32(wx, WX_RDB_LXONTXC); + hwstats->lxofftxc += rd32(wx, WX_RDB_LXOFFTXC); + hwstats->o2bgptc += rd32(wx, WX_TDM_OS2BMC_CNT); + hwstats->b2ospc += rd32(wx, WX_MNG_BMC2OS_CNT); + hwstats->o2bspc += rd32(wx, WX_MNG_OS2BMC_CNT); + hwstats->b2ogprc += rd32(wx, WX_RDM_BMC2OS_CNT); + hwstats->rdmdrop += rd32(wx, WX_RDM_DRP_PKT); + + if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) { + hwstats->fdirmatch += rd32(wx, WX_RDB_FDIR_MATCH); + hwstats->fdirmiss += rd32(wx, WX_RDB_FDIR_MISS); + } - if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) { - hwstats->fdirmatch += rd32(wx, WX_RDB_FDIR_MATCH); - hwstats->fdirmiss += rd32(wx, WX_RDB_FDIR_MISS); + for (i = wx->num_vfs * wx->num_rx_queues_per_pool; + i < wx->mac.max_rx_queues; i++) + hwstats->qmprc += rd32_wrap(wx, WX_PX_MPRC(i), + &wx->last_stats.qmprc[i]); } - - for (i = wx->num_vfs * wx->num_rx_queues_per_pool; - i < wx->mac.max_rx_queues; i++) - hwstats->qmprc += rd32_wrap(wx, WX_PX_MPRC(i), - &wx->last_stats.qmprc[i]); - spin_unlock(&wx->hw_stats_lock); } EXPORT_SYMBOL(wx_update_stats); diff --git a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c index a3361696b783..6ac1a523ce08 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c @@ -5,6 +5,7 @@ #include #include "wx_type.h" +#include "wx_hw.h" #include "wx_mbx.h" #include "wx_lib.h" #include "wx_vf.h" @@ -332,6 +333,7 @@ void wxvf_down(struct wx *wx) netif_tx_disable(netdev); netif_carrier_off(netdev); wx_napi_disable_all(wx); + wx_update_stats(wx); wx_reset_vf(wx); wx_clean_all_tx_rings(wx); @@ -405,6 +407,7 @@ static void wxvf_service_task(struct work_struct *work) wxvf_link_config_subtask(wx); wxvf_reset_subtask(wx); + wx_update_stats(wx); wx_service_event_complete(wx); } -- 2.50.1 (Apple Git-155)