diff options
Diffstat (limited to 'drivers/net/ethernet/intel/iavf/iavf_ethtool.c')
| -rw-r--r-- | drivers/net/ethernet/intel/iavf/iavf_ethtool.c | 60 | 
1 files changed, 39 insertions, 21 deletions
| diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c index 461f5237a2f8..3bb56714beb0 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c @@ -331,9 +331,16 @@ static int iavf_get_link_ksettings(struct net_device *netdev,   **/  static int iavf_get_sset_count(struct net_device *netdev, int sset)  { +	/* Report the maximum number queues, even if not every queue is +	 * currently configured. Since allocation of queues is in pairs, +	 * use netdev->real_num_tx_queues * 2. The real_num_tx_queues is set +	 * at device creation and never changes. +	 */ +  	if (sset == ETH_SS_STATS)  		return IAVF_STATS_LEN + -			(IAVF_QUEUE_STATS_LEN * 2 * IAVF_MAX_REQ_QUEUES); +			(IAVF_QUEUE_STATS_LEN * 2 * +			 netdev->real_num_tx_queues);  	else if (sset == ETH_SS_PRIV_FLAGS)  		return IAVF_PRIV_FLAGS_STR_LEN;  	else @@ -360,17 +367,18 @@ static void iavf_get_ethtool_stats(struct net_device *netdev,  	iavf_add_ethtool_stats(&data, adapter, iavf_gstrings_stats);  	rcu_read_lock(); -	for (i = 0; i < IAVF_MAX_REQ_QUEUES; i++) { +	/* As num_active_queues describe both tx and rx queues, we can use +	 * it to iterate over rings' stats. +	 */ +	for (i = 0; i < adapter->num_active_queues; i++) {  		struct iavf_ring *ring; -		/* Avoid accessing un-allocated queues */ -		ring = (i < adapter->num_active_queues ? -			&adapter->tx_rings[i] : NULL); +		/* Tx rings stats */ +		ring = &adapter->tx_rings[i];  		iavf_add_queue_stats(&data, ring); -		/* Avoid accessing un-allocated queues */ -		ring = (i < adapter->num_active_queues ? -			&adapter->rx_rings[i] : NULL); +		/* Rx rings stats */ +		ring = &adapter->rx_rings[i];  		iavf_add_queue_stats(&data, ring);  	}  	rcu_read_unlock(); @@ -407,10 +415,10 @@ static void iavf_get_stat_strings(struct net_device *netdev, u8 *data)  	iavf_add_stat_strings(&data, iavf_gstrings_stats); -	/* Queues are always allocated in pairs, so we just use num_tx_queues -	 * for both Tx and Rx queues. +	/* Queues are always allocated in pairs, so we just use +	 * real_num_tx_queues for both Tx and Rx queues.  	 */ -	for (i = 0; i < netdev->num_tx_queues; i++) { +	for (i = 0; i < netdev->real_num_tx_queues; i++) {  		iavf_add_stat_strings(&data, iavf_gstrings_queue_stats,  				      "tx", i);  		iavf_add_stat_strings(&data, iavf_gstrings_queue_stats, @@ -583,12 +591,16 @@ static void iavf_get_drvinfo(struct net_device *netdev,   * iavf_get_ringparam - Get ring parameters   * @netdev: network interface device structure   * @ring: ethtool ringparam structure + * @kernel_ring: ethtool extenal ringparam structure + * @extack: netlink extended ACK report struct   *   * Returns current ring parameters. TX and RX rings are reported separately,   * but the number of rings is not reported.   **/  static void iavf_get_ringparam(struct net_device *netdev, -			       struct ethtool_ringparam *ring) +			       struct ethtool_ringparam *ring, +			       struct kernel_ethtool_ringparam *kernel_ring, +			       struct netlink_ext_ack *extack)  {  	struct iavf_adapter *adapter = netdev_priv(netdev); @@ -602,12 +614,16 @@ static void iavf_get_ringparam(struct net_device *netdev,   * iavf_set_ringparam - Set ring parameters   * @netdev: network interface device structure   * @ring: ethtool ringparam structure + * @kernel_ring: ethtool external ringparam structure + * @extack: netlink extended ACK report struct   *   * Sets ring parameters. TX and RX rings are controlled separately, but the   * number of rings is not specified, so all rings get the same settings.   **/  static int iavf_set_ringparam(struct net_device *netdev, -			      struct ethtool_ringparam *ring) +			      struct ethtool_ringparam *ring, +			      struct kernel_ethtool_ringparam *kernel_ring, +			      struct netlink_ext_ack *extack)  {  	struct iavf_adapter *adapter = netdev_priv(netdev);  	u32 new_rx_count, new_tx_count; @@ -1923,7 +1939,7 @@ static int iavf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,   * @key: hash key   * @hfunc: hash function to use   * - * Returns -EINVAL if the table specifies an inavlid queue id, otherwise + * Returns -EINVAL if the table specifies an invalid queue id, otherwise   * returns 0 after programming the table.   **/  static int iavf_set_rxfh(struct net_device *netdev, const u32 *indir, @@ -1932,19 +1948,21 @@ static int iavf_set_rxfh(struct net_device *netdev, const u32 *indir,  	struct iavf_adapter *adapter = netdev_priv(netdev);  	u16 i; -	/* We do not allow change in unsupported parameters */ -	if (key || -	    (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)) +	/* Only support toeplitz hash function */ +	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)  		return -EOPNOTSUPP; -	if (!indir) + +	if (!key && !indir)  		return 0;  	if (key)  		memcpy(adapter->rss_key, key, adapter->rss_key_size); -	/* Each 32 bits pointed by 'indir' is stored with a lut entry */ -	for (i = 0; i < adapter->rss_lut_size; i++) -		adapter->rss_lut[i] = (u8)(indir[i]); +	if (indir) { +		/* Each 32 bits pointed by 'indir' is stored with a lut entry */ +		for (i = 0; i < adapter->rss_lut_size; i++) +			adapter->rss_lut[i] = (u8)(indir[i]); +	}  	return iavf_config_rss(adapter);  } |