Commit 7aae80ce authored by Wojciech Drewek's avatar Wojciech Drewek Committed by Tony Nguyen
Browse files

ice: add port representor ethtool ops and stats



Introduce the following ethtool operations for VF's representor:
	-get_drvinfo
	-get_strings
	-get_ethtool_stats
	-get_sset_count
	-get_link

In all cases, existing operations were used with minor
changes which allow us to detect if ethtool op was called for
representor. Only VF VSI stats will be available for representor.

Implement ndo_get_stats64 for port representor. This will update
VF VSI stats and read them.

Signed-off-by: default avatarWojciech Drewek <wojciech.drewek@intel.com>
Tested-by: default avatarSandeep Penigalapati <sandeep.penigalapati@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent f5396b8a
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -615,6 +615,19 @@ static inline struct ice_vsi *ice_get_main_vsi(struct ice_pf *pf)
	return NULL;
}

/**
 * ice_get_netdev_priv_vsi - return VSI associated with netdev priv.
 * @np: private netdev structure
 */
static inline struct ice_vsi *ice_get_netdev_priv_vsi(struct ice_netdev_priv *np)
{
	/* In case of port representor return source port VSI. */
	if (np->repr)
		return np->repr->src_vsi;
	else
		return np->vsi;
}

/**
 * ice_get_ctrl_vsi - Get the control VSI
 * @pf: PF instance
@@ -670,6 +683,7 @@ int ice_vsi_setup_rx_rings(struct ice_vsi *vsi);
int ice_vsi_open_ctrl(struct ice_vsi *vsi);
int ice_vsi_open(struct ice_vsi *vsi);
void ice_set_ethtool_ops(struct net_device *netdev);
void ice_set_ethtool_repr_ops(struct net_device *netdev);
void ice_set_ethtool_safe_mode_ops(struct net_device *netdev);
u16 ice_get_avail_txq_count(struct ice_pf *pf);
u16 ice_get_avail_rxq_count(struct ice_pf *pf);
+5 −0
Original line number Diff line number Diff line
@@ -683,6 +683,11 @@ void ice_pf_dcb_recfg(struct ice_pf *pf)
				vsi->idx);
			continue;
		}
		/* no need to proceed with remaining cfg if it is switchdev
		 * VSI
		 */
		if (vsi->type == ICE_VSI_SWITCHDEV_CTRL)
			continue;

		ice_vsi_map_rings_to_vectors(vsi);
		if (vsi->type == ICE_VSI_PF)
+50 −5
Original line number Diff line number Diff line
@@ -170,10 +170,9 @@ static const struct ice_priv_flag ice_gstrings_priv_flags[] = {
#define ICE_PRIV_FLAG_ARRAY_SIZE	ARRAY_SIZE(ice_gstrings_priv_flags)

static void
ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
__ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo,
		  struct ice_vsi *vsi)
{
	struct ice_netdev_priv *np = netdev_priv(netdev);
	struct ice_vsi *vsi = np->vsi;
	struct ice_pf *pf = vsi->back;
	struct ice_hw *hw = &pf->hw;
	struct ice_orom_info *orom;
@@ -196,6 +195,26 @@ ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
	drvinfo->n_priv_flags = ICE_PRIV_FLAG_ARRAY_SIZE;
}

static void
ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
{
	struct ice_netdev_priv *np = netdev_priv(netdev);

	__ice_get_drvinfo(netdev, drvinfo, np->vsi);
}

static void
ice_repr_get_drvinfo(struct net_device *netdev,
		     struct ethtool_drvinfo *drvinfo)
{
	struct ice_repr *repr = ice_netdev_to_repr(netdev);

	if (ice_check_vf_ready_for_cfg(repr->vf))
		return;

	__ice_get_drvinfo(netdev, drvinfo, repr->src_vsi);
}

static int ice_get_regs_len(struct net_device __always_unused *netdev)
{
	return sizeof(ice_regs_dump_list);
@@ -869,7 +888,7 @@ ice_self_test(struct net_device *netdev, struct ethtool_test *eth_test,
static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
{
	struct ice_netdev_priv *np = netdev_priv(netdev);
	struct ice_vsi *vsi = np->vsi;
	struct ice_vsi *vsi = ice_get_netdev_priv_vsi(np);
	unsigned int i;
	u8 *p = data;

@@ -879,6 +898,9 @@ static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
			ethtool_sprintf(&p,
					ice_gstrings_vsi_stats[i].stat_string);

		if (ice_is_port_repr_netdev(netdev))
			return;

		ice_for_each_alloc_txq(vsi, i) {
			ethtool_sprintf(&p, "tx_queue_%u_packets", i);
			ethtool_sprintf(&p, "tx_queue_%u_bytes", i);
@@ -1308,6 +1330,9 @@ static int ice_get_sset_count(struct net_device *netdev, int sset)
		 * order of strings will suffer from race conditions and are
		 * not safe.
		 */
		if (ice_is_port_repr_netdev(netdev))
			return ICE_VSI_STATS_LEN;

		return ICE_ALL_STATS_LEN(netdev);
	case ETH_SS_TEST:
		return ICE_TEST_LEN;
@@ -1323,7 +1348,7 @@ ice_get_ethtool_stats(struct net_device *netdev,
		      struct ethtool_stats __always_unused *stats, u64 *data)
{
	struct ice_netdev_priv *np = netdev_priv(netdev);
	struct ice_vsi *vsi = np->vsi;
	struct ice_vsi *vsi = ice_get_netdev_priv_vsi(np);
	struct ice_pf *pf = vsi->back;
	struct ice_ring *ring;
	unsigned int j;
@@ -1339,6 +1364,9 @@ ice_get_ethtool_stats(struct net_device *netdev,
			     sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
	}

	if (ice_is_port_repr_netdev(netdev))
		return;

	/* populate per queue stats */
	rcu_read_lock();

@@ -4062,6 +4090,23 @@ void ice_set_ethtool_safe_mode_ops(struct net_device *netdev)
	netdev->ethtool_ops = &ice_ethtool_safe_mode_ops;
}

static const struct ethtool_ops ice_ethtool_repr_ops = {
	.get_drvinfo		= ice_repr_get_drvinfo,
	.get_link		= ethtool_op_get_link,
	.get_strings		= ice_get_strings,
	.get_ethtool_stats      = ice_get_ethtool_stats,
	.get_sset_count		= ice_get_sset_count,
};

/**
 * ice_set_ethtool_repr_ops - setup VF's port representor ethtool ops
 * @netdev: network interface device structure
 */
void ice_set_ethtool_repr_ops(struct net_device *netdev)
{
	netdev->ethtool_ops = &ice_ethtool_repr_ops;
}

/**
 * ice_set_ethtool_ops - setup netdev ethtool ops
 * @netdev: network interface device structure
+33 −0
Original line number Diff line number Diff line
@@ -39,6 +39,37 @@ ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len)
	return 0;
}

/**
 * ice_repr_get_stats64 - get VF stats for VFPR use
 * @netdev: pointer to port representor netdev
 * @stats: pointer to struct where stats can be stored
 */
static void
ice_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
{
	struct ice_netdev_priv *np = netdev_priv(netdev);
	struct ice_eth_stats *eth_stats;
	struct ice_vsi *vsi;

	if (ice_is_vf_disabled(np->repr->vf))
		return;
	vsi = np->repr->src_vsi;

	ice_update_vsi_stats(vsi);
	eth_stats = &vsi->eth_stats;

	stats->tx_packets = eth_stats->tx_unicast + eth_stats->tx_broadcast +
			    eth_stats->tx_multicast;
	stats->rx_packets = eth_stats->rx_unicast + eth_stats->rx_broadcast +
			    eth_stats->rx_multicast;
	stats->tx_bytes = eth_stats->tx_bytes;
	stats->rx_bytes = eth_stats->rx_bytes;
	stats->multicast = eth_stats->rx_multicast;
	stats->tx_errors = eth_stats->tx_errors;
	stats->tx_dropped = eth_stats->tx_discards;
	stats->rx_dropped = eth_stats->rx_discards;
}

/**
 * ice_netdev_to_repr - Get port representor for given netdevice
 * @netdev: pointer to port representor netdev
@@ -112,6 +143,7 @@ ice_repr_get_devlink_port(struct net_device *netdev)

static const struct net_device_ops ice_repr_netdev_ops = {
	.ndo_get_phys_port_name = ice_repr_get_phys_port_name,
	.ndo_get_stats64 = ice_repr_get_stats64,
	.ndo_open = ice_repr_open,
	.ndo_stop = ice_repr_stop,
	.ndo_start_xmit = ice_eswitch_port_start_xmit,
@@ -136,6 +168,7 @@ ice_repr_reg_netdev(struct net_device *netdev)
{
	eth_hw_addr_random(netdev);
	netdev->netdev_ops = &ice_repr_netdev_ops;
	ice_set_ethtool_repr_ops(netdev);

	netif_carrier_off(netdev);
	netif_tx_stop_all_queues(netdev);
+2 −2
Original line number Diff line number Diff line
@@ -1603,7 +1603,7 @@ bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr)
 *
 * Returns true if the PF or VF is disabled, false otherwise.
 */
static bool ice_is_vf_disabled(struct ice_vf *vf)
bool ice_is_vf_disabled(struct ice_vf *vf)
{
	struct ice_pf *pf = vf->pf;

@@ -2841,7 +2841,7 @@ static void ice_wait_on_vf_reset(struct ice_vf *vf)
 * disabled, and initialized so it can be configured and/or queried by a host
 * administrator.
 */
static int ice_check_vf_ready_for_cfg(struct ice_vf *vf)
int ice_check_vf_ready_for_cfg(struct ice_vf *vf)
{
	struct ice_pf *pf;

Loading