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[]; |
