diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbevf/ethtool.c')
| -rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ethtool.c | 172 | 
1 files changed, 87 insertions, 85 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c index e8dddf572d3..8f2070439b5 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c +++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c @@ -43,7 +43,6 @@  #define IXGBE_ALL_RAR_ENTRIES 16 -#ifdef ETHTOOL_GSTATS  struct ixgbe_stats {  	char stat_string[ETH_GSTRING_LEN];  	int sizeof_stat; @@ -75,21 +74,17 @@ static const struct ixgbe_stats ixgbe_gstrings_stats[] = {  						zero_base)},  	{"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base,  					      zero_base)}, -	{"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base, zero_base)},  };  #define IXGBE_QUEUE_STATS_LEN 0  #define IXGBE_GLOBAL_STATS_LEN	ARRAY_SIZE(ixgbe_gstrings_stats)  #define IXGBEVF_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN) -#endif /* ETHTOOL_GSTATS */ -#ifdef ETHTOOL_TEST  static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {  	"Register test  (offline)",  	"Link test   (on/offline)"  };  #define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN) -#endif /* ETHTOOL_TEST */  static int ixgbevf_get_settings(struct net_device *netdev,  				struct ethtool_cmd *ecmd) @@ -289,13 +284,11 @@ static void ixgbevf_get_ringparam(struct net_device *netdev,  				  struct ethtool_ringparam *ring)  {  	struct ixgbevf_adapter *adapter = netdev_priv(netdev); -	struct ixgbevf_ring *tx_ring = adapter->tx_ring; -	struct ixgbevf_ring *rx_ring = adapter->rx_ring;  	ring->rx_max_pending = IXGBEVF_MAX_RXD;  	ring->tx_max_pending = IXGBEVF_MAX_TXD; -	ring->rx_pending = rx_ring->count; -	ring->tx_pending = tx_ring->count; +	ring->rx_pending = adapter->rx_ring_count; +	ring->tx_pending = adapter->tx_ring_count;  }  static int ixgbevf_set_ringparam(struct net_device *netdev, @@ -303,33 +296,28 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,  {  	struct ixgbevf_adapter *adapter = netdev_priv(netdev);  	struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL; -	int i, err = 0;  	u32 new_rx_count, new_tx_count; +	int i, err = 0;  	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))  		return -EINVAL; -	new_rx_count = max(ring->rx_pending, (u32)IXGBEVF_MIN_RXD); -	new_rx_count = min(new_rx_count, (u32)IXGBEVF_MAX_RXD); -	new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE); - -	new_tx_count = max(ring->tx_pending, (u32)IXGBEVF_MIN_TXD); -	new_tx_count = min(new_tx_count, (u32)IXGBEVF_MAX_TXD); +	new_tx_count = max_t(u32, ring->tx_pending, IXGBEVF_MIN_TXD); +	new_tx_count = min_t(u32, new_tx_count, IXGBEVF_MAX_TXD);  	new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE); -	if ((new_tx_count == adapter->tx_ring->count) && -	    (new_rx_count == adapter->rx_ring->count)) { -		/* nothing to do */ +	new_rx_count = max_t(u32, ring->rx_pending, IXGBEVF_MIN_RXD); +	new_rx_count = min_t(u32, new_rx_count, IXGBEVF_MAX_RXD); +	new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE); + +	/* if nothing to do return success */ +	if ((new_tx_count == adapter->tx_ring_count) && +	    (new_rx_count == adapter->rx_ring_count))  		return 0; -	}  	while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state)) -		msleep(1); +		usleep_range(1000, 2000); -	/* -	 * If the adapter isn't up and running then just set the -	 * new parameters and scurry for the exits. -	 */  	if (!netif_running(adapter->netdev)) {  		for (i = 0; i < adapter->num_tx_queues; i++)  			adapter->tx_ring[i].count = new_tx_count; @@ -340,82 +328,98 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,  		goto clear_reset;  	} -	tx_ring = kcalloc(adapter->num_tx_queues, -			  sizeof(struct ixgbevf_ring), GFP_KERNEL); -	if (!tx_ring) { -		err = -ENOMEM; -		goto clear_reset; -	} - -	rx_ring = kcalloc(adapter->num_rx_queues, -			  sizeof(struct ixgbevf_ring), GFP_KERNEL); -	if (!rx_ring) { -		err = -ENOMEM; -		goto err_rx_setup; -	} - -	ixgbevf_down(adapter); +	if (new_tx_count != adapter->tx_ring_count) { +		tx_ring = vmalloc(adapter->num_tx_queues * sizeof(*tx_ring)); +		if (!tx_ring) { +			err = -ENOMEM; +			goto clear_reset; +		} -	memcpy(tx_ring, adapter->tx_ring, -	       adapter->num_tx_queues * sizeof(struct ixgbevf_ring)); -	for (i = 0; i < adapter->num_tx_queues; i++) { -		tx_ring[i].count = new_tx_count; -		err = ixgbevf_setup_tx_resources(adapter, &tx_ring[i]); -		if (err) { +		for (i = 0; i < adapter->num_tx_queues; i++) { +			/* clone ring and setup updated count */ +			tx_ring[i] = adapter->tx_ring[i]; +			tx_ring[i].count = new_tx_count; +			err = ixgbevf_setup_tx_resources(adapter, &tx_ring[i]); +			if (!err) +				continue;  			while (i) {  				i--; -				ixgbevf_free_tx_resources(adapter, -							  &tx_ring[i]); +				ixgbevf_free_tx_resources(adapter, &tx_ring[i]);  			} -			goto err_tx_ring_setup; + +			vfree(tx_ring); +			tx_ring = NULL; + +			goto clear_reset;  		} -		tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;  	} -	memcpy(rx_ring, adapter->rx_ring, -	       adapter->num_rx_queues * sizeof(struct ixgbevf_ring)); -	for (i = 0; i < adapter->num_rx_queues; i++) { -		rx_ring[i].count = new_rx_count; -		err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]); -		if (err) { +	if (new_rx_count != adapter->rx_ring_count) { +		rx_ring = vmalloc(adapter->num_rx_queues * sizeof(*rx_ring)); +		if (!rx_ring) { +			err = -ENOMEM; +			goto clear_reset; +		} + +		for (i = 0; i < adapter->num_rx_queues; i++) { +			/* clone ring and setup updated count */ +			rx_ring[i] = adapter->rx_ring[i]; +			rx_ring[i].count = new_rx_count; +			err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]); +			if (!err) +				continue;  			while (i) {  				i--; -				ixgbevf_free_rx_resources(adapter, -							  &rx_ring[i]); +				ixgbevf_free_rx_resources(adapter, &rx_ring[i]);  			} -				goto err_rx_ring_setup; + +			vfree(rx_ring); +			rx_ring = NULL; + +			goto clear_reset;  		} -		rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;  	} -	/* -	 * Only switch to new rings if all the prior allocations -	 * and ring setups have succeeded. -	 */ -	kfree(adapter->tx_ring); -	adapter->tx_ring = tx_ring; -	adapter->tx_ring_count = new_tx_count; - -	kfree(adapter->rx_ring); -	adapter->rx_ring = rx_ring; -	adapter->rx_ring_count = new_rx_count; +	/* bring interface down to prepare for update */ +	ixgbevf_down(adapter); -	/* success! */ -	ixgbevf_up(adapter); +	/* Tx */ +	if (tx_ring) { +		for (i = 0; i < adapter->num_tx_queues; i++) { +			ixgbevf_free_tx_resources(adapter, +						  &adapter->tx_ring[i]); +			adapter->tx_ring[i] = tx_ring[i]; +		} +		adapter->tx_ring_count = new_tx_count; -	goto clear_reset; +		vfree(tx_ring); +		tx_ring = NULL; +	} -err_rx_ring_setup: -	for(i = 0; i < adapter->num_tx_queues; i++) -		ixgbevf_free_tx_resources(adapter, &tx_ring[i]); +	/* Rx */ +	if (rx_ring) { +		for (i = 0; i < adapter->num_rx_queues; i++) { +			ixgbevf_free_rx_resources(adapter, +						  &adapter->rx_ring[i]); +			adapter->rx_ring[i] = rx_ring[i]; +		} +		adapter->rx_ring_count = new_rx_count; -err_tx_ring_setup: -	kfree(rx_ring); +		vfree(rx_ring); +		rx_ring = NULL; +	} -err_rx_setup: -	kfree(tx_ring); +	/* restore interface using new values */ +	ixgbevf_up(adapter);  clear_reset: +	/* free Tx resources if Rx error is encountered */ +	if (tx_ring) { +		for (i = 0; i < adapter->num_tx_queues; i++) +			ixgbevf_free_tx_resources(adapter, &tx_ring[i]); +		vfree(tx_ring); +	} +  	clear_bit(__IXGBEVF_RESETTING, &adapter->state);  	return err;  } @@ -674,10 +678,8 @@ static int ixgbevf_nway_reset(struct net_device *netdev)  {  	struct ixgbevf_adapter *adapter = netdev_priv(netdev); -	if (netif_running(netdev)) { -		if (!adapter->dev_closed) -			ixgbevf_reinit_locked(adapter); -	} +	if (netif_running(netdev)) +		ixgbevf_reinit_locked(adapter);  	return 0;  }  |