diff options
Diffstat (limited to 'drivers/net/vmxnet3')
| -rw-r--r-- | drivers/net/vmxnet3/vmxnet3_drv.c | 143 | ||||
| -rw-r--r-- | drivers/net/vmxnet3/vmxnet3_ethtool.c | 26 | ||||
| -rw-r--r-- | drivers/net/vmxnet3/vmxnet3_int.h | 10 | 
3 files changed, 91 insertions, 88 deletions
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 7e2788c488e..b76f7dcde0d 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1078,7 +1078,7 @@ unlock_drop_pkt:  	spin_unlock_irqrestore(&tq->tx_lock, flags);  drop_pkt:  	tq->stats.drop_total++; -	dev_kfree_skb(skb); +	dev_kfree_skb_any(skb);  	return NETDEV_TX_OK;  } @@ -1235,7 +1235,9 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,  #ifdef VMXNET3_RSS  			if (rcd->rssType != VMXNET3_RCD_RSS_TYPE_NONE &&  			    (adapter->netdev->features & NETIF_F_RXHASH)) -				ctx->skb->rxhash = le32_to_cpu(rcd->rssHash); +				skb_set_hash(ctx->skb, +					     le32_to_cpu(rcd->rssHash), +					     PKT_HASH_TYPE_L3);  #endif  			skb_put(ctx->skb, rcd->len); @@ -1760,11 +1762,20 @@ vmxnet3_netpoll(struct net_device *netdev)  {  	struct vmxnet3_adapter *adapter = netdev_priv(netdev); -	if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) -		vmxnet3_disable_all_intrs(adapter); - -	vmxnet3_do_poll(adapter, adapter->rx_queue[0].rx_ring[0].size); -	vmxnet3_enable_all_intrs(adapter); +	switch (adapter->intr.type) { +#ifdef CONFIG_PCI_MSI +	case VMXNET3_IT_MSIX: { +		int i; +		for (i = 0; i < adapter->num_rx_queues; i++) +			vmxnet3_msix_rx(0, &adapter->rx_queue[i]); +		break; +	} +#endif +	case VMXNET3_IT_MSI: +	default: +		vmxnet3_intr(0, adapter->netdev); +		break; +	}  }  #endif	/* CONFIG_NET_POLL_CONTROLLER */ @@ -2578,8 +2589,8 @@ vmxnet3_open(struct net_device *netdev)  	for (i = 0; i < adapter->num_tx_queues; i++)  		spin_lock_init(&adapter->tx_queue[i].tx_lock); -	err = vmxnet3_create_queues(adapter, VMXNET3_DEF_TX_RING_SIZE, -				    VMXNET3_DEF_RX_RING_SIZE, +	err = vmxnet3_create_queues(adapter, adapter->tx_ring_size, +				    adapter->rx_ring_size,  				    VMXNET3_DEF_RX_RING_SIZE);  	if (err)  		goto queue_err; @@ -2727,47 +2738,35 @@ vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac)  /*   * Enable MSIx vectors.   * Returns : - *	0 on successful enabling of required vectors,   *	VMXNET3_LINUX_MIN_MSIX_VECT when only minimum number of vectors required - *	 could be enabled. - *	number of vectors which can be enabled otherwise (this number is smaller + *	 were enabled. + *	number of vectors which were enabled otherwise (this number is greater   *	 than VMXNET3_LINUX_MIN_MSIX_VECT)   */  static int -vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, -			     int vectors) -{ -	int err = 0, vector_threshold; -	vector_threshold = VMXNET3_LINUX_MIN_MSIX_VECT; - -	while (vectors >= vector_threshold) { -		err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries, -				      vectors); -		if (!err) { -			adapter->intr.num_intrs = vectors; -			return 0; -		} else if (err < 0) { -			dev_err(&adapter->netdev->dev, -				   "Failed to enable MSI-X, error: %d\n", err); -			vectors = 0; -		} else if (err < vector_threshold) { -			break; -		} else { -			/* If fails to enable required number of MSI-x vectors -			 * try enabling minimum number of vectors required. -			 */ -			dev_err(&adapter->netdev->dev, -				"Failed to enable %d MSI-X, trying %d instead\n", -				    vectors, vector_threshold); -			vectors = vector_threshold; -		} +vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, int nvec) +{ +	int ret = pci_enable_msix_range(adapter->pdev, +					adapter->intr.msix_entries, nvec, nvec); + +	if (ret == -ENOSPC && nvec > VMXNET3_LINUX_MIN_MSIX_VECT) { +		dev_err(&adapter->netdev->dev, +			"Failed to enable %d MSI-X, trying %d\n", +			nvec, VMXNET3_LINUX_MIN_MSIX_VECT); + +		ret = pci_enable_msix_range(adapter->pdev, +					    adapter->intr.msix_entries, +					    VMXNET3_LINUX_MIN_MSIX_VECT, +					    VMXNET3_LINUX_MIN_MSIX_VECT);  	} -	dev_info(&adapter->pdev->dev, -		 "Number of MSI-X interrupts which can be allocated " -		 "is lower than min threshold required.\n"); -	return err; +	if (ret < 0) { +		dev_err(&adapter->netdev->dev, +			"Failed to enable MSI-X, error: %d\n", ret); +	} + +	return ret;  } @@ -2794,56 +2793,50 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)  #ifdef CONFIG_PCI_MSI  	if (adapter->intr.type == VMXNET3_IT_MSIX) { -		int vector, err = 0; - -		adapter->intr.num_intrs = (adapter->share_intr == -					   VMXNET3_INTR_TXSHARE) ? 1 : -					   adapter->num_tx_queues; -		adapter->intr.num_intrs += (adapter->share_intr == -					   VMXNET3_INTR_BUDDYSHARE) ? 0 : -					   adapter->num_rx_queues; -		adapter->intr.num_intrs += 1;		/* for link event */ - -		adapter->intr.num_intrs = (adapter->intr.num_intrs > -					   VMXNET3_LINUX_MIN_MSIX_VECT -					   ? adapter->intr.num_intrs : -					   VMXNET3_LINUX_MIN_MSIX_VECT); - -		for (vector = 0; vector < adapter->intr.num_intrs; vector++) -			adapter->intr.msix_entries[vector].entry = vector; - -		err = vmxnet3_acquire_msix_vectors(adapter, -						   adapter->intr.num_intrs); +		int i, nvec; + +		nvec  = adapter->share_intr == VMXNET3_INTR_TXSHARE ? +			1 : adapter->num_tx_queues; +		nvec += adapter->share_intr == VMXNET3_INTR_BUDDYSHARE ? +			0 : adapter->num_rx_queues; +		nvec += 1;	/* for link event */ +		nvec = nvec > VMXNET3_LINUX_MIN_MSIX_VECT ? +		       nvec : VMXNET3_LINUX_MIN_MSIX_VECT; + +		for (i = 0; i < nvec; i++) +			adapter->intr.msix_entries[i].entry = i; + +		nvec = vmxnet3_acquire_msix_vectors(adapter, nvec); +		if (nvec < 0) +			goto msix_err; +  		/* If we cannot allocate one MSIx vector per queue  		 * then limit the number of rx queues to 1  		 */ -		if (err == VMXNET3_LINUX_MIN_MSIX_VECT) { +		if (nvec == VMXNET3_LINUX_MIN_MSIX_VECT) {  			if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE  			    || adapter->num_rx_queues != 1) {  				adapter->share_intr = VMXNET3_INTR_TXSHARE;  				netdev_err(adapter->netdev,  					   "Number of rx queues : 1\n");  				adapter->num_rx_queues = 1; -				adapter->intr.num_intrs = -						VMXNET3_LINUX_MIN_MSIX_VECT;  			} -			return;  		} -		if (!err) -			return; +		adapter->intr.num_intrs = nvec; +		return; + +msix_err:  		/* If we cannot allocate MSIx vectors use only one rx queue */  		dev_info(&adapter->pdev->dev,  			 "Failed to enable MSI-X, error %d. " -			 "Limiting #rx queues to 1, try MSI.\n", err); +			 "Limiting #rx queues to 1, try MSI.\n", nvec);  		adapter->intr.type = VMXNET3_IT_MSI;  	}  	if (adapter->intr.type == VMXNET3_IT_MSI) { -		int err; -		err = pci_enable_msi(adapter->pdev); -		if (!err) { +		if (!pci_enable_msi(adapter->pdev)) {  			adapter->num_rx_queues = 1;  			adapter->intr.num_intrs = 1;  			return; @@ -2975,6 +2968,9 @@ vmxnet3_probe_device(struct pci_dev *pdev,  	adapter->netdev = netdev;  	adapter->pdev = pdev; +	adapter->tx_ring_size = VMXNET3_DEF_TX_RING_SIZE; +	adapter->rx_ring_size = VMXNET3_DEF_RX_RING_SIZE; +  	spin_lock_init(&adapter->cmd_lock);  	adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter,  					     sizeof(struct vmxnet3_adapter), @@ -3132,7 +3128,6 @@ err_alloc_queue_desc:  err_alloc_shared:  	dma_unmap_single(&adapter->pdev->dev, adapter->adapter_pa,  			 sizeof(struct vmxnet3_adapter), PCI_DMA_TODEVICE); -	pci_set_drvdata(pdev, NULL);  	free_netdev(netdev);  	return err;  } diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index 600ab56c000..b725fd9e780 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -431,8 +431,8 @@ vmxnet3_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)  		ethtool_cmd_speed_set(ecmd, adapter->link_speed);  		ecmd->duplex = DUPLEX_FULL;  	} else { -		ethtool_cmd_speed_set(ecmd, -1); -		ecmd->duplex = -1; +		ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); +		ecmd->duplex = DUPLEX_UNKNOWN;  	}  	return 0;  } @@ -449,8 +449,8 @@ vmxnet3_get_ringparam(struct net_device *netdev,  	param->rx_mini_max_pending = 0;  	param->rx_jumbo_max_pending = 0; -	param->rx_pending = adapter->rx_queue[0].rx_ring[0].size; -	param->tx_pending = adapter->tx_queue[0].tx_ring.size; +	param->rx_pending = adapter->rx_ring_size; +	param->tx_pending = adapter->tx_ring_size;  	param->rx_mini_pending = 0;  	param->rx_jumbo_pending = 0;  } @@ -529,9 +529,11 @@ vmxnet3_set_ringparam(struct net_device *netdev,  			 * size */  			netdev_err(netdev, "failed to apply new sizes, "  				   "try the default ones\n"); +			new_rx_ring_size = VMXNET3_DEF_RX_RING_SIZE; +			new_tx_ring_size = VMXNET3_DEF_TX_RING_SIZE;  			err = vmxnet3_create_queues(adapter, -						    VMXNET3_DEF_TX_RING_SIZE, -						    VMXNET3_DEF_RX_RING_SIZE, +						    new_tx_ring_size, +						    new_rx_ring_size,  						    VMXNET3_DEF_RX_RING_SIZE);  			if (err) {  				netdev_err(netdev, "failed to create queues " @@ -545,6 +547,8 @@ vmxnet3_set_ringparam(struct net_device *netdev,  			netdev_err(netdev, "failed to re-activate, error %d."  				   " Closing it\n", err);  	} +	adapter->tx_ring_size = new_tx_ring_size; +	adapter->rx_ring_size = new_rx_ring_size;  out:  	clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state); @@ -579,7 +583,7 @@ vmxnet3_get_rss_indir_size(struct net_device *netdev)  }  static int -vmxnet3_get_rss_indir(struct net_device *netdev, u32 *p) +vmxnet3_get_rss(struct net_device *netdev, u32 *p, u8 *key)  {  	struct vmxnet3_adapter *adapter = netdev_priv(netdev);  	struct UPT1_RSSConf *rssConf = adapter->rss_conf; @@ -592,7 +596,7 @@ vmxnet3_get_rss_indir(struct net_device *netdev, u32 *p)  }  static int -vmxnet3_set_rss_indir(struct net_device *netdev, const u32 *p) +vmxnet3_set_rss(struct net_device *netdev, const u32 *p, const u8 *key)  {  	unsigned int i;  	unsigned long flags; @@ -628,12 +632,12 @@ static const struct ethtool_ops vmxnet3_ethtool_ops = {  	.get_rxnfc         = vmxnet3_get_rxnfc,  #ifdef VMXNET3_RSS  	.get_rxfh_indir_size = vmxnet3_get_rss_indir_size, -	.get_rxfh_indir    = vmxnet3_get_rss_indir, -	.set_rxfh_indir    = vmxnet3_set_rss_indir, +	.get_rxfh          = vmxnet3_get_rss, +	.set_rxfh          = vmxnet3_set_rss,  #endif  };  void vmxnet3_set_ethtool_ops(struct net_device *netdev)  { -	SET_ETHTOOL_OPS(netdev, &vmxnet3_ethtool_ops); +	netdev->ethtool_ops = &vmxnet3_ethtool_ops;  } diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index a03f358fd58..29ee77f2c97 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -37,7 +37,6 @@  #include <linux/spinlock.h>  #include <linux/ioport.h>  #include <linux/highmem.h> -#include <linux/init.h>  #include <linux/timer.h>  #include <linux/skbuff.h>  #include <linux/interrupt.h> @@ -350,6 +349,11 @@ struct vmxnet3_adapter {  	u32     link_speed; /* in mbps */  	u64     tx_timeout_count; + +	/* Ring sizes */ +	u32 tx_ring_size; +	u32 rx_ring_size; +  	struct work_struct work;  	unsigned long  state;    /* VMXNET3_STATE_BIT_xxx */ @@ -410,9 +414,9 @@ int  vmxnet3_create_queues(struct vmxnet3_adapter *adapter,  		      u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size); -extern void vmxnet3_set_ethtool_ops(struct net_device *netdev); +void vmxnet3_set_ethtool_ops(struct net_device *netdev); -extern struct rtnl_link_stats64 * +struct rtnl_link_stats64 *  vmxnet3_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats);  extern char vmxnet3_driver_name[];  | 
