Commit 0e100440 authored by Jacob Keller's avatar Jacob Keller Committed by Jeff Kirsher

fm10k: add support for ndo_get_vf_stats operation

Support capturing and reporting statistics for all of the VFs associated
with a given PF device via the ndo_get_vf_stats callback.
Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 1df96ca7
...@@ -534,6 +534,7 @@ void fm10k_iov_suspend(struct pci_dev *pdev); ...@@ -534,6 +534,7 @@ void fm10k_iov_suspend(struct pci_dev *pdev);
int fm10k_iov_resume(struct pci_dev *pdev); int fm10k_iov_resume(struct pci_dev *pdev);
void fm10k_iov_disable(struct pci_dev *pdev); void fm10k_iov_disable(struct pci_dev *pdev);
int fm10k_iov_configure(struct pci_dev *pdev, int num_vfs); int fm10k_iov_configure(struct pci_dev *pdev, int num_vfs);
void fm10k_iov_update_stats(struct fm10k_intfc *interface);
s32 fm10k_iov_update_pvid(struct fm10k_intfc *interface, u16 glort, u16 pvid); s32 fm10k_iov_update_pvid(struct fm10k_intfc *interface, u16 glort, u16 pvid);
int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac); int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac);
int fm10k_ndo_set_vf_vlan(struct net_device *netdev, int fm10k_ndo_set_vf_vlan(struct net_device *netdev,
...@@ -542,6 +543,8 @@ int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx, ...@@ -542,6 +543,8 @@ int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx,
int __always_unused min_rate, int max_rate); int __always_unused min_rate, int max_rate);
int fm10k_ndo_get_vf_config(struct net_device *netdev, int fm10k_ndo_get_vf_config(struct net_device *netdev,
int vf_idx, struct ifla_vf_info *ivi); int vf_idx, struct ifla_vf_info *ivi);
int fm10k_ndo_get_vf_stats(struct net_device *netdev,
int vf_idx, struct ifla_vf_stats *stats);
/* DebugFS */ /* DebugFS */
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
......
...@@ -520,6 +520,27 @@ int fm10k_iov_configure(struct pci_dev *pdev, int num_vfs) ...@@ -520,6 +520,27 @@ int fm10k_iov_configure(struct pci_dev *pdev, int num_vfs)
return num_vfs; return num_vfs;
} }
/**
* fm10k_iov_update_stats - Update stats for all VFs
* @interface: device private structure
*
* Updates the VF statistics for all enabled VFs. Expects to be called by
* fm10k_update_stats and assumes that locking via the __FM10K_UPDATING_STATS
* bit is already handled.
*/
void fm10k_iov_update_stats(struct fm10k_intfc *interface)
{
struct fm10k_iov_data *iov_data = interface->iov_data;
struct fm10k_hw *hw = &interface->hw;
int i;
if (!iov_data)
return;
for (i = 0; i < iov_data->num_vfs; i++)
hw->iov.ops.update_stats(hw, iov_data->vf_info[i].stats, i);
}
static inline void fm10k_reset_vf_info(struct fm10k_intfc *interface, static inline void fm10k_reset_vf_info(struct fm10k_intfc *interface,
struct fm10k_vf_info *vf_info) struct fm10k_vf_info *vf_info)
{ {
...@@ -650,3 +671,30 @@ int fm10k_ndo_get_vf_config(struct net_device *netdev, ...@@ -650,3 +671,30 @@ int fm10k_ndo_get_vf_config(struct net_device *netdev,
return 0; return 0;
} }
int fm10k_ndo_get_vf_stats(struct net_device *netdev,
int vf_idx, struct ifla_vf_stats *stats)
{
struct fm10k_intfc *interface = netdev_priv(netdev);
struct fm10k_iov_data *iov_data = interface->iov_data;
struct fm10k_hw *hw = &interface->hw;
struct fm10k_hw_stats_q *hw_stats;
u32 idx, qpp;
/* verify SR-IOV is active and that vf idx is valid */
if (!iov_data || vf_idx >= iov_data->num_vfs)
return -EINVAL;
qpp = fm10k_queues_per_pool(hw);
hw_stats = iov_data->vf_info[vf_idx].stats;
for (idx = 0; idx < qpp; idx++) {
stats->rx_packets += hw_stats[idx].rx_packets.count;
stats->tx_packets += hw_stats[idx].tx_packets.count;
stats->rx_bytes += hw_stats[idx].rx_bytes.count;
stats->tx_bytes += hw_stats[idx].tx_bytes.count;
stats->rx_dropped += hw_stats[idx].rx_drops.count;
}
return 0;
}
...@@ -1643,6 +1643,7 @@ static const struct net_device_ops fm10k_netdev_ops = { ...@@ -1643,6 +1643,7 @@ static const struct net_device_ops fm10k_netdev_ops = {
.ndo_set_vf_vlan = fm10k_ndo_set_vf_vlan, .ndo_set_vf_vlan = fm10k_ndo_set_vf_vlan,
.ndo_set_vf_rate = fm10k_ndo_set_vf_bw, .ndo_set_vf_rate = fm10k_ndo_set_vf_bw,
.ndo_get_vf_config = fm10k_ndo_get_vf_config, .ndo_get_vf_config = fm10k_ndo_get_vf_config,
.ndo_get_vf_stats = fm10k_ndo_get_vf_stats,
.ndo_udp_tunnel_add = fm10k_udp_tunnel_add, .ndo_udp_tunnel_add = fm10k_udp_tunnel_add,
.ndo_udp_tunnel_del = fm10k_udp_tunnel_del, .ndo_udp_tunnel_del = fm10k_udp_tunnel_del,
.ndo_dfwd_add_station = fm10k_dfwd_add_station, .ndo_dfwd_add_station = fm10k_dfwd_add_station,
......
...@@ -630,6 +630,9 @@ void fm10k_update_stats(struct fm10k_intfc *interface) ...@@ -630,6 +630,9 @@ void fm10k_update_stats(struct fm10k_intfc *interface)
net_stats->rx_errors = rx_errors; net_stats->rx_errors = rx_errors;
net_stats->rx_dropped = interface->stats.nodesc_drop.count; net_stats->rx_dropped = interface->stats.nodesc_drop.count;
/* Update VF statistics */
fm10k_iov_update_stats(interface);
clear_bit(__FM10K_UPDATING_STATS, interface->state); clear_bit(__FM10K_UPDATING_STATS, interface->state);
} }
......
...@@ -581,6 +581,7 @@ struct fm10k_vf_info { ...@@ -581,6 +581,7 @@ struct fm10k_vf_info {
* at the same offset as the mailbox * at the same offset as the mailbox
*/ */
struct fm10k_mbx_info mbx; /* PF side of VF mailbox */ struct fm10k_mbx_info mbx; /* PF side of VF mailbox */
struct fm10k_hw_stats_q stats[FM10K_MAX_QUEUES_POOL];
int rate; /* Tx BW cap as defined by OS */ int rate; /* Tx BW cap as defined by OS */
u16 glort; /* resource tag for this VF */ u16 glort; /* resource tag for this VF */
u16 sw_vid; /* Switch API assigned VLAN */ u16 sw_vid; /* Switch API assigned VLAN */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment