summaryrefslogtreecommitdiff
path: root/drivers/net/vxge/vxge-ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/vxge/vxge-ethtool.c')
-rw-r--r--drivers/net/vxge/vxge-ethtool.c112
1 files changed, 80 insertions, 32 deletions
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
index b67746eef923..1dd3a21b3a43 100644
--- a/drivers/net/vxge/vxge-ethtool.c
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -11,7 +11,7 @@
* Virtualized Server Adapter.
* Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
-#include<linux/ethtool.h>
+#include <linux/ethtool.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/etherdevice.h>
@@ -29,7 +29,6 @@
* Return value:
* 0 on success.
*/
-
static int vxge_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info)
{
/* We currently only support 10Gb/FULL */
@@ -79,10 +78,9 @@ static int vxge_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
* Returns driver specefic information like name, version etc.. to ethtool.
*/
static void vxge_ethtool_gdrvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
+ struct ethtool_drvinfo *info)
{
- struct vxgedev *vdev;
- vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
strlcpy(info->driver, VXGE_DRIVER_NAME, sizeof(VXGE_DRIVER_NAME));
strlcpy(info->version, DRV_VERSION, sizeof(DRV_VERSION));
strlcpy(info->fw_version, vdev->fw_version, VXGE_HW_FW_STRLEN);
@@ -104,15 +102,14 @@ static void vxge_ethtool_gdrvinfo(struct net_device *dev,
* buffer area.
*/
static void vxge_ethtool_gregs(struct net_device *dev,
- struct ethtool_regs *regs, void *space)
+ struct ethtool_regs *regs, void *space)
{
int index, offset;
enum vxge_hw_status status;
u64 reg;
- u64 *reg_space = (u64 *) space;
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
- struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
- pci_get_drvdata(vdev->pdev);
+ u64 *reg_space = (u64 *)space;
+ struct vxgedev *vdev = netdev_priv(dev);
+ struct __vxge_hw_device *hldev = vdev->devh;
regs->len = sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
regs->version = vdev->pdev->subsystem_device;
@@ -147,9 +144,8 @@ static void vxge_ethtool_gregs(struct net_device *dev,
*/
static int vxge_ethtool_idnic(struct net_device *dev, u32 data)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
- struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
- pci_get_drvdata(vdev->pdev);
+ struct vxgedev *vdev = netdev_priv(dev);
+ struct __vxge_hw_device *hldev = vdev->devh;
vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON);
msleep_interruptible(data ? (data * HZ) : VXGE_MAX_FLICKER_TIME);
@@ -168,11 +164,10 @@ static int vxge_ethtool_idnic(struct net_device *dev, u32 data)
* void
*/
static void vxge_ethtool_getpause_data(struct net_device *dev,
- struct ethtool_pauseparam *ep)
+ struct ethtool_pauseparam *ep)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
- struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
- pci_get_drvdata(vdev->pdev);
+ struct vxgedev *vdev = netdev_priv(dev);
+ struct __vxge_hw_device *hldev = vdev->devh;
vxge_hw_device_getpause_data(hldev, 0, &ep->tx_pause, &ep->rx_pause);
}
@@ -188,11 +183,10 @@ static void vxge_ethtool_getpause_data(struct net_device *dev,
* int, returns 0 on Success
*/
static int vxge_ethtool_setpause_data(struct net_device *dev,
- struct ethtool_pauseparam *ep)
+ struct ethtool_pauseparam *ep)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
- struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
- pci_get_drvdata(vdev->pdev);
+ struct vxgedev *vdev = netdev_priv(dev);
+ struct __vxge_hw_device *hldev = vdev->devh;
vxge_hw_device_setpause_data(hldev, 0, ep->tx_pause, ep->rx_pause);
@@ -209,9 +203,8 @@ static void vxge_get_ethtool_stats(struct net_device *dev,
enum vxge_hw_status status;
enum vxge_hw_status swstatus;
struct vxge_vpath *vpath = NULL;
-
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
- struct __vxge_hw_device *hldev = vdev->devh;
+ struct vxgedev *vdev = netdev_priv(dev);
+ struct __vxge_hw_device *hldev = vdev->devh;
struct vxge_hw_xmac_stats *xmac_stats;
struct vxge_hw_device_stats_sw_info *sw_stats;
struct vxge_hw_device_stats_hw_info *hw_stats;
@@ -574,12 +567,12 @@ static void vxge_get_ethtool_stats(struct net_device *dev,
kfree(hw_stats);
}
-static void vxge_ethtool_get_strings(struct net_device *dev,
- u32 stringset, u8 *data)
+static void vxge_ethtool_get_strings(struct net_device *dev, u32 stringset,
+ u8 *data)
{
int stat_size = 0;
int i, j;
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
switch (stringset) {
case ETH_SS_STATS:
vxge_add_string("VPATH STATISTICS%s\t\t\t",
@@ -1066,21 +1059,21 @@ static void vxge_ethtool_get_strings(struct net_device *dev,
static int vxge_ethtool_get_regs_len(struct net_device *dev)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
return sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
}
static u32 vxge_get_rx_csum(struct net_device *dev)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
return vdev->rx_csum;
}
static int vxge_set_rx_csum(struct net_device *dev, u32 data)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
if (data)
vdev->rx_csum = 1;
@@ -1102,7 +1095,7 @@ static int vxge_ethtool_op_set_tso(struct net_device *dev, u32 data)
static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
switch (sset) {
case ETH_SS_STATS:
@@ -1119,6 +1112,59 @@ static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
}
}
+static int vxge_set_flags(struct net_device *dev, u32 data)
+{
+ struct vxgedev *vdev = netdev_priv(dev);
+ enum vxge_hw_status status;
+
+ if (data & ~ETH_FLAG_RXHASH)
+ return -EOPNOTSUPP;
+
+ if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en)
+ return 0;
+
+ if (netif_running(dev) || (vdev->config.rth_steering == NO_STEERING))
+ return -EINVAL;
+
+ vdev->devh->config.rth_en = !!(data & ETH_FLAG_RXHASH);
+
+ /* Enabling RTH requires some of the logic in vxge_device_register and a
+ * vpath reset. Due to these restrictions, only allow modification
+ * while the interface is down.
+ */
+ status = vxge_reset_all_vpaths(vdev);
+ if (status != VXGE_HW_OK) {
+ vdev->devh->config.rth_en = !vdev->devh->config.rth_en;
+ return -EFAULT;
+ }
+
+ if (vdev->devh->config.rth_en)
+ dev->features |= NETIF_F_RXHASH;
+ else
+ dev->features &= ~NETIF_F_RXHASH;
+
+ return 0;
+}
+
+static int vxge_fw_flash(struct net_device *dev, struct ethtool_flash *parms)
+{
+ struct vxgedev *vdev = netdev_priv(dev);
+
+ if (vdev->max_vpath_supported != VXGE_HW_MAX_VIRTUAL_PATHS) {
+ printk(KERN_INFO "Single Function Mode is required to flash the"
+ " firmware\n");
+ return -EINVAL;
+ }
+
+ if (netif_running(dev)) {
+ printk(KERN_INFO "Interface %s must be down to flash the "
+ "firmware\n", dev->name);
+ return -EBUSY;
+ }
+
+ return vxge_fw_upgrade(vdev, parms->data, 1);
+}
+
static const struct ethtool_ops vxge_ethtool_ops = {
.get_settings = vxge_ethtool_gset,
.set_settings = vxge_ethtool_sset,
@@ -1131,7 +1177,7 @@ static const struct ethtool_ops vxge_ethtool_ops = {
.get_rx_csum = vxge_get_rx_csum,
.set_rx_csum = vxge_set_rx_csum,
.get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
+ .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_tso = ethtool_op_get_tso,
@@ -1140,6 +1186,8 @@ static const struct ethtool_ops vxge_ethtool_ops = {
.phys_id = vxge_ethtool_idnic,
.get_sset_count = vxge_ethtool_get_sset_count,
.get_ethtool_stats = vxge_get_ethtool_stats,
+ .set_flags = vxge_set_flags,
+ .flash_device = vxge_fw_flash,
};
void vxge_initialize_ethtool_ops(struct net_device *ndev)