aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/vmxnet3/vmxnet3_ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/vmxnet3/vmxnet3_ethtool.c')
-rw-r--r--drivers/net/vmxnet3/vmxnet3_ethtool.c209
1 files changed, 85 insertions, 124 deletions
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 81254be85b9..b725fd9e780 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -33,40 +33,6 @@ struct vmxnet3_stat_desc {
};
-static u32
-vmxnet3_get_rx_csum(struct net_device *netdev)
-{
- struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- return adapter->rxcsum;
-}
-
-
-static int
-vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
-{
- struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- unsigned long flags;
-
- if (adapter->rxcsum != val) {
- adapter->rxcsum = val;
- if (netif_running(netdev)) {
- if (val)
- adapter->shared->devRead.misc.uptFeatures |=
- UPT1_F_RXCSUM;
- else
- adapter->shared->devRead.misc.uptFeatures &=
- ~UPT1_F_RXCSUM;
-
- spin_lock_irqsave(&adapter->cmd_lock, flags);
- VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
- VMXNET3_CMD_UPDATE_FEATURE);
- spin_unlock_irqrestore(&adapter->cmd_lock, flags);
- }
- }
- return 0;
-}
-
-
/* per tq stats maintained by the device */
static const struct vmxnet3_stat_desc
vmxnet3_tq_dev_stats[] = {
@@ -147,15 +113,15 @@ vmxnet3_global_stats[] = {
};
-struct net_device_stats *
-vmxnet3_get_stats(struct net_device *netdev)
+struct rtnl_link_stats64 *
+vmxnet3_get_stats64(struct net_device *netdev,
+ struct rtnl_link_stats64 *stats)
{
struct vmxnet3_adapter *adapter;
struct vmxnet3_tq_driver_stats *drvTxStats;
struct vmxnet3_rq_driver_stats *drvRxStats;
struct UPT1_TxStats *devTxStats;
struct UPT1_RxStats *devRxStats;
- struct net_device_stats *net_stats = &netdev->stats;
unsigned long flags;
int i;
@@ -166,36 +132,36 @@ vmxnet3_get_stats(struct net_device *netdev)
VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
spin_unlock_irqrestore(&adapter->cmd_lock, flags);
- memset(net_stats, 0, sizeof(*net_stats));
for (i = 0; i < adapter->num_tx_queues; i++) {
devTxStats = &adapter->tqd_start[i].stats;
drvTxStats = &adapter->tx_queue[i].stats;
- net_stats->tx_packets += devTxStats->ucastPktsTxOK +
- devTxStats->mcastPktsTxOK +
- devTxStats->bcastPktsTxOK;
- net_stats->tx_bytes += devTxStats->ucastBytesTxOK +
- devTxStats->mcastBytesTxOK +
- devTxStats->bcastBytesTxOK;
- net_stats->tx_errors += devTxStats->pktsTxError;
- net_stats->tx_dropped += drvTxStats->drop_total;
+ stats->tx_packets += devTxStats->ucastPktsTxOK +
+ devTxStats->mcastPktsTxOK +
+ devTxStats->bcastPktsTxOK;
+ stats->tx_bytes += devTxStats->ucastBytesTxOK +
+ devTxStats->mcastBytesTxOK +
+ devTxStats->bcastBytesTxOK;
+ stats->tx_errors += devTxStats->pktsTxError;
+ stats->tx_dropped += drvTxStats->drop_total;
}
for (i = 0; i < adapter->num_rx_queues; i++) {
devRxStats = &adapter->rqd_start[i].stats;
drvRxStats = &adapter->rx_queue[i].stats;
- net_stats->rx_packets += devRxStats->ucastPktsRxOK +
- devRxStats->mcastPktsRxOK +
- devRxStats->bcastPktsRxOK;
+ stats->rx_packets += devRxStats->ucastPktsRxOK +
+ devRxStats->mcastPktsRxOK +
+ devRxStats->bcastPktsRxOK;
- net_stats->rx_bytes += devRxStats->ucastBytesRxOK +
- devRxStats->mcastBytesRxOK +
- devRxStats->bcastBytesRxOK;
+ stats->rx_bytes += devRxStats->ucastBytesRxOK +
+ devRxStats->mcastBytesRxOK +
+ devRxStats->bcastBytesRxOK;
- net_stats->rx_errors += devRxStats->pktsRxError;
- net_stats->rx_dropped += drvRxStats->drop_total;
- net_stats->multicast += devRxStats->mcastPktsRxOK;
+ stats->rx_errors += devRxStats->pktsRxError;
+ stats->rx_dropped += drvRxStats->drop_total;
+ stats->multicast += devRxStats->mcastPktsRxOK;
}
- return net_stats;
+
+ return stats;
}
static int
@@ -236,17 +202,12 @@ vmxnet3_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
strlcpy(drvinfo->driver, vmxnet3_driver_name, sizeof(drvinfo->driver));
- drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0';
strlcpy(drvinfo->version, VMXNET3_DRIVER_VERSION_REPORT,
sizeof(drvinfo->version));
- drvinfo->driver[sizeof(drvinfo->version) - 1] = '\0';
-
- strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
- drvinfo->fw_version[sizeof(drvinfo->fw_version) - 1] = '\0';
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
- ETHTOOL_BUSINFO_LEN);
+ sizeof(drvinfo->bus_info));
drvinfo->n_stats = vmxnet3_get_sset_count(netdev, ETH_SS_STATS);
drvinfo->testinfo_len = 0;
drvinfo->eedump_len = 0;
@@ -296,28 +257,36 @@ vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
}
}
-static int
-vmxnet3_set_flags(struct net_device *netdev, u32 data)
+int vmxnet3_set_features(struct net_device *netdev, netdev_features_t features)
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1;
- u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
unsigned long flags;
+ netdev_features_t changed = features ^ netdev->features;
- if (data & ~ETH_FLAG_LRO)
- return -EOPNOTSUPP;
-
- if (lro_requested ^ lro_present) {
- /* toggle the LRO feature*/
- netdev->features ^= NETIF_F_LRO;
+ if (changed & (NETIF_F_RXCSUM | NETIF_F_LRO |
+ NETIF_F_HW_VLAN_CTAG_RX)) {
+ if (features & NETIF_F_RXCSUM)
+ adapter->shared->devRead.misc.uptFeatures |=
+ UPT1_F_RXCSUM;
+ else
+ adapter->shared->devRead.misc.uptFeatures &=
+ ~UPT1_F_RXCSUM;
/* update harware LRO capability accordingly */
- if (lro_requested)
+ if (features & NETIF_F_LRO)
adapter->shared->devRead.misc.uptFeatures |=
UPT1_F_LRO;
else
adapter->shared->devRead.misc.uptFeatures &=
~UPT1_F_LRO;
+
+ if (features & NETIF_F_HW_VLAN_CTAG_RX)
+ adapter->shared->devRead.misc.uptFeatures |=
+ UPT1_F_RXVLAN;
+ else
+ adapter->shared->devRead.misc.uptFeatures &=
+ ~UPT1_F_RXVLAN;
+
spin_lock_irqsave(&adapter->cmd_lock, flags);
VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
VMXNET3_CMD_UPDATE_FEATURE);
@@ -459,11 +428,11 @@ vmxnet3_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed) {
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
ecmd->duplex = DUPLEX_FULL;
} else {
- ecmd->speed = -1;
- ecmd->duplex = -1;
+ ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
+ ecmd->duplex = DUPLEX_UNKNOWN;
}
return 0;
}
@@ -480,10 +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 *
- adapter->num_rx_queues;
- param->tx_pending = adapter->tx_queue[0].tx_ring.size *
- adapter->num_tx_queues;
+ param->rx_pending = adapter->rx_ring_size;
+ param->tx_pending = adapter->tx_ring_size;
param->rx_mini_pending = 0;
param->rx_jumbo_pending = 0;
}
@@ -506,6 +473,12 @@ vmxnet3_set_ringparam(struct net_device *netdev,
VMXNET3_RX_RING_MAX_SIZE)
return -EINVAL;
+ /* if adapter not yet initialized, do nothing */
+ if (adapter->rx_buf_per_pkt == 0) {
+ netdev_err(netdev, "adapter not completely initialized, "
+ "ring size cannot be changed yet\n");
+ return -EOPNOTSUPP;
+ }
/* round it up to a multiple of VMXNET3_RING_SIZE_ALIGN */
new_tx_ring_size = (param->tx_pending + VMXNET3_RING_SIZE_MASK) &
@@ -554,25 +527,28 @@ vmxnet3_set_ringparam(struct net_device *netdev,
if (err) {
/* failed, most likely because of OOM, try default
* size */
- printk(KERN_ERR "%s: failed to apply new sizes, try the"
- " default ones\n", netdev->name);
+ 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) {
- printk(KERN_ERR "%s: failed to create queues "
- "with default sizes. Closing it\n",
- netdev->name);
+ netdev_err(netdev, "failed to create queues "
+ "with default sizes. Closing it\n");
goto out;
}
}
err = vmxnet3_activate_dev(adapter);
if (err)
- printk(KERN_ERR "%s: failed to re-activate, error %d."
- " Closing it\n", netdev->name, err);
+ 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);
@@ -585,7 +561,7 @@ out:
static int
vmxnet3_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info,
- void *rules)
+ u32 *rules)
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
switch (info->cmd) {
@@ -597,44 +573,38 @@ vmxnet3_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info,
}
#ifdef VMXNET3_RSS
+static u32
+vmxnet3_get_rss_indir_size(struct net_device *netdev)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ struct UPT1_RSSConf *rssConf = adapter->rss_conf;
+
+ return rssConf->indTableSize;
+}
+
static int
-vmxnet3_get_rss_indir(struct net_device *netdev,
- struct ethtool_rxfh_indir *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;
- unsigned int n = min_t(unsigned int, p->size, rssConf->indTableSize);
+ unsigned int n = rssConf->indTableSize;
- p->size = rssConf->indTableSize;
while (n--)
- p->ring_index[n] = rssConf->indTable[n];
+ p[n] = rssConf->indTable[n];
return 0;
}
static int
-vmxnet3_set_rss_indir(struct net_device *netdev,
- const struct ethtool_rxfh_indir *p)
+vmxnet3_set_rss(struct net_device *netdev, const u32 *p, const u8 *key)
{
unsigned int i;
unsigned long flags;
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
struct UPT1_RSSConf *rssConf = adapter->rss_conf;
- if (p->size != rssConf->indTableSize)
- return -EINVAL;
- for (i = 0; i < rssConf->indTableSize; i++) {
- /*
- * Return with error code if any of the queue indices
- * is out of range
- */
- if (p->ring_index[i] < 0 ||
- p->ring_index[i] >= adapter->num_rx_queues)
- return -EINVAL;
- }
-
for (i = 0; i < rssConf->indTableSize; i++)
- rssConf->indTable[i] = p->ring_index[i];
+ rssConf->indTable[i] = p[i];
spin_lock_irqsave(&adapter->cmd_lock, flags);
VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
@@ -646,7 +616,7 @@ vmxnet3_set_rss_indir(struct net_device *netdev,
}
#endif
-static struct ethtool_ops vmxnet3_ethtool_ops = {
+static const struct ethtool_ops vmxnet3_ethtool_ops = {
.get_settings = vmxnet3_get_settings,
.get_drvinfo = vmxnet3_get_drvinfo,
.get_regs_len = vmxnet3_get_regs_len,
@@ -654,29 +624,20 @@ static struct ethtool_ops vmxnet3_ethtool_ops = {
.get_wol = vmxnet3_get_wol,
.set_wol = vmxnet3_set_wol,
.get_link = ethtool_op_get_link,
- .get_rx_csum = vmxnet3_get_rx_csum,
- .set_rx_csum = vmxnet3_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = ethtool_op_set_tso,
.get_strings = vmxnet3_get_strings,
- .get_flags = ethtool_op_get_flags,
- .set_flags = vmxnet3_set_flags,
.get_sset_count = vmxnet3_get_sset_count,
.get_ethtool_stats = vmxnet3_get_ethtool_stats,
.get_ringparam = vmxnet3_get_ringparam,
.set_ringparam = vmxnet3_set_ringparam,
.get_rxnfc = vmxnet3_get_rxnfc,
#ifdef VMXNET3_RSS
- .get_rxfh_indir = vmxnet3_get_rss_indir,
- .set_rxfh_indir = vmxnet3_set_rss_indir,
+ .get_rxfh_indir_size = vmxnet3_get_rss_indir_size,
+ .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;
}