diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-06 12:30:19 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-06 12:30:19 -0800 |
commit | abb359450f20c32ae03039d8736f12b1d561caf5 (patch) | |
tree | 6e8723885feb66a138f19f0ff31615dc13a8d859 /drivers/net/vxge/vxge-ethtool.c | |
parent | cb600d2f83c854ec3d6660063e4466431999489b (diff) | |
parent | 4e3dbdb1392a83bd21a6ff8f6bc785495058d37c (diff) | |
download | linux-abb359450f20c32ae03039d8736f12b1d561caf5.tar.bz2 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1436 commits)
cassini: Use local-mac-address prom property for Cassini MAC address
net: remove the duplicate #ifdef __KERNEL__
net: bridge: check the length of skb after nf_bridge_maybe_copy_header()
netconsole: clarify stopping message
netconsole: don't announce stopping if nothing happened
cnic: Fix the type field in SPQ messages
netfilter: fix export secctx error handling
netfilter: fix the race when initializing nf_ct_expect_hash_rnd
ipv4: IP defragmentation must be ECN aware
net: r6040: Return proper error for r6040_init_one
dcb: use after free in dcb_flushapp()
dcb: unlock on error in dcbnl_ieee_get()
net: ixp4xx_eth: Return proper error for eth_init_one
include/linux/if_ether.h: Add #define ETH_P_LINK_CTL for HPNA and wlan local tunnel
net: add POLLPRI to sock_def_readable()
af_unix: Avoid socket->sk NULL OOPS in stream connect security hooks.
net_sched: pfifo_head_drop problem
mac80211: remove stray extern
mac80211: implement off-channel TX using hw r-o-c offload
mac80211: implement hardware offload for remain-on-channel
...
Diffstat (limited to 'drivers/net/vxge/vxge-ethtool.c')
-rw-r--r-- | drivers/net/vxge/vxge-ethtool.c | 112 |
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) |