Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ed2616f authored by Ayaz Abdulla's avatar Ayaz Abdulla Committed by Jeff Garzik
Browse files

[PATCH] forcedeth config: csum



This patch allows for configurable rx and tx checksum offloads through
ethtool support.

Signed-Off-By: default avatarAyaz Abdulla <aabdulla@nvidia.com>

Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent c42d9df9
Loading
Loading
Loading
Loading
+77 −8
Original line number Diff line number Diff line
@@ -1707,6 +1707,7 @@ static void nv_rx_process(struct net_device *dev)
					}
				}
			}
			if (np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) {
				Flags &= NV_RX2_CHECKSUMMASK;
				if (Flags == NV_RX2_CHECKSUMOK1 ||
				    Flags == NV_RX2_CHECKSUMOK2 ||
@@ -1717,6 +1718,7 @@ static void nv_rx_process(struct net_device *dev)
					dprintk(KERN_DEBUG "%s: hwchecksum miss!.\n", dev->name);
				}
			}
		}
		/* got a valid packet - forward it to the network core */
		skb = np->rx_skbuff[i];
		np->rx_skbuff[i] = NULL;
@@ -3021,6 +3023,67 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam*
	return 0;
}

static u32 nv_get_rx_csum(struct net_device *dev)
{
	struct fe_priv *np = netdev_priv(dev);
	return (np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) != 0;
}

static int nv_set_rx_csum(struct net_device *dev, u32 data)
{
	struct fe_priv *np = netdev_priv(dev);
	u8 __iomem *base = get_hwbase(dev);
	int retcode = 0;

	if (np->driver_data & DEV_HAS_CHECKSUM) {

		if (((np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) && data) ||
		    (!(np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) && !data)) {
			/* already set or unset */
			return 0;
		}

		if (data) {
			np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
		} else if (!(np->vlanctl_bits & NVREG_VLANCONTROL_ENABLE)) {
			np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK;
		} else {
			printk(KERN_INFO "Can not disable rx checksum if vlan is enabled\n");
			return -EINVAL;
		}

		if (netif_running(dev)) {
			spin_lock_irq(&np->lock);
			writel(np->txrxctl_bits, base + NvRegTxRxControl);
			spin_unlock_irq(&np->lock);
		}
	} else {
		return -EINVAL;
	}

	return retcode;
}

static int nv_set_tx_csum(struct net_device *dev, u32 data)
{
	struct fe_priv *np = netdev_priv(dev);

	if (np->driver_data & DEV_HAS_CHECKSUM)
		return ethtool_op_set_tx_hw_csum(dev, data);
	else
		return -EOPNOTSUPP;
}

static int nv_set_sg(struct net_device *dev, u32 data)
{
	struct fe_priv *np = netdev_priv(dev);

	if (np->driver_data & DEV_HAS_CHECKSUM)
		return ethtool_op_set_sg(dev, data);
	else
		return -EOPNOTSUPP;
}

static struct ethtool_ops ops = {
	.get_drvinfo = nv_get_drvinfo,
	.get_link = ethtool_op_get_link,
@@ -3038,6 +3101,12 @@ static struct ethtool_ops ops = {
	.set_ringparam = nv_set_ringparam,
	.get_pauseparam = nv_get_pauseparam,
	.set_pauseparam = nv_set_pauseparam,
	.get_rx_csum = nv_get_rx_csum,
	.set_rx_csum = nv_set_rx_csum,
	.get_tx_csum = ethtool_op_get_tx_csum,
	.set_tx_csum = nv_set_tx_csum,
	.get_sg = ethtool_op_get_sg,
	.set_sg = nv_set_sg,
};

static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)