Skip to content

Commit

Permalink
ethtool: Add GGRO and SGRO ops
Browse files Browse the repository at this point in the history
This patch adds the ethtool ops to enable and disable GRO.  It also
makes GRO depend on RX checksum offload much the same as how TSO
depends on SG support.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Herbert Xu authored and David S. Miller committed Dec 16, 2008
1 parent bf296b1 commit b240a0e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
2 changes: 2 additions & 0 deletions include/linux/ethtool.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,8 @@ struct ethtool_ops {

#define ETHTOOL_GRXFH 0x00000029 /* Get RX flow hash configuration */
#define ETHTOOL_SRXFH 0x0000002a /* Set RX flow hash configuration */
#define ETHTOOL_GGRO 0x0000002b /* Get GRO enable (ethtool_value) */
#define ETHTOOL_SGRO 0x0000002c /* Set GRO enable (ethtool_value) */

/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
Expand Down
53 changes: 51 additions & 2 deletions net/core/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,22 @@ static int ethtool_set_tx_csum(struct net_device *dev, char __user *useraddr)
return dev->ethtool_ops->set_tx_csum(dev, edata.data);
}

static int ethtool_set_rx_csum(struct net_device *dev, char __user *useraddr)
{
struct ethtool_value edata;

if (!dev->ethtool_ops->set_rx_csum)
return -EOPNOTSUPP;

if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;

if (!edata.data && dev->ethtool_ops->set_sg)
dev->features &= ~NETIF_F_GRO;

return dev->ethtool_ops->set_rx_csum(dev, edata.data);
}

static int ethtool_set_sg(struct net_device *dev, char __user *useraddr)
{
struct ethtool_value edata;
Expand Down Expand Up @@ -599,6 +615,34 @@ static int ethtool_set_gso(struct net_device *dev, char __user *useraddr)
return 0;
}

static int ethtool_get_gro(struct net_device *dev, char __user *useraddr)
{
struct ethtool_value edata = { ETHTOOL_GGRO };

edata.data = dev->features & NETIF_F_GRO;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}

static int ethtool_set_gro(struct net_device *dev, char __user *useraddr)
{
struct ethtool_value edata;

if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;

if (edata.data) {
if (!dev->ethtool_ops->get_rx_csum ||
!dev->ethtool_ops->get_rx_csum(dev))
return -EINVAL;
dev->features |= NETIF_F_GRO;
} else
dev->features &= ~NETIF_F_GRO;

return 0;
}

static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
{
struct ethtool_test test;
Expand Down Expand Up @@ -932,8 +976,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
dev->ethtool_ops->get_rx_csum);
break;
case ETHTOOL_SRXCSUM:
rc = ethtool_set_value(dev, useraddr,
dev->ethtool_ops->set_rx_csum);
rc = ethtool_set_rx_csum(dev, useraddr);
break;
case ETHTOOL_GTXCSUM:
rc = ethtool_get_value(dev, useraddr, ethcmd,
Expand Down Expand Up @@ -1014,6 +1057,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_SRXFH:
rc = ethtool_set_rxhash(dev, useraddr);
break;
case ETHTOOL_GGRO:
rc = ethtool_get_gro(dev, useraddr);
break;
case ETHTOOL_SGRO:
rc = ethtool_set_gro(dev, useraddr);
break;
default:
rc = -EOPNOTSUPP;
}
Expand Down

0 comments on commit b240a0e

Please sign in to comment.