diff options
author | Ayaz Abdulla <aabdulla@nvidia.com> | 2006-06-10 22:47:59 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-06-11 09:25:15 -0400 |
commit | 5ed2616f621b41d3477d4f4ae2ba0e0a0e80bdce (patch) | |
tree | 3455e8f39b655cd9cef5c347fb345383be43b008 /drivers/net/forcedeth.c | |
parent | c42d9df932ce3732044dc1394114380140ccffe0 (diff) |
[PATCH] forcedeth config: csum
This patch allows for configurable rx and tx checksum offloads through
ethtool support.
Signed-Off-By: Ayaz Abdulla <aabdulla@nvidia.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r-- | drivers/net/forcedeth.c | 85 |
1 files changed, 77 insertions, 8 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index d9b7345198c4..eaf6de9a9dfa 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -1707,14 +1707,16 @@ static void nv_rx_process(struct net_device *dev) | |||
1707 | } | 1707 | } |
1708 | } | 1708 | } |
1709 | } | 1709 | } |
1710 | Flags &= NV_RX2_CHECKSUMMASK; | 1710 | if (np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) { |
1711 | if (Flags == NV_RX2_CHECKSUMOK1 || | 1711 | Flags &= NV_RX2_CHECKSUMMASK; |
1712 | Flags == NV_RX2_CHECKSUMOK2 || | 1712 | if (Flags == NV_RX2_CHECKSUMOK1 || |
1713 | Flags == NV_RX2_CHECKSUMOK3) { | 1713 | Flags == NV_RX2_CHECKSUMOK2 || |
1714 | dprintk(KERN_DEBUG "%s: hw checksum hit!.\n", dev->name); | 1714 | Flags == NV_RX2_CHECKSUMOK3) { |
1715 | np->rx_skbuff[i]->ip_summed = CHECKSUM_UNNECESSARY; | 1715 | dprintk(KERN_DEBUG "%s: hw checksum hit!.\n", dev->name); |
1716 | } else { | 1716 | np->rx_skbuff[i]->ip_summed = CHECKSUM_UNNECESSARY; |
1717 | dprintk(KERN_DEBUG "%s: hwchecksum miss!.\n", dev->name); | 1717 | } else { |
1718 | dprintk(KERN_DEBUG "%s: hwchecksum miss!.\n", dev->name); | ||
1719 | } | ||
1718 | } | 1720 | } |
1719 | } | 1721 | } |
1720 | /* got a valid packet - forward it to the network core */ | 1722 | /* got a valid packet - forward it to the network core */ |
@@ -3021,6 +3023,67 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* | |||
3021 | return 0; | 3023 | return 0; |
3022 | } | 3024 | } |
3023 | 3025 | ||
3026 | static u32 nv_get_rx_csum(struct net_device *dev) | ||
3027 | { | ||
3028 | struct fe_priv *np = netdev_priv(dev); | ||
3029 | return (np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) != 0; | ||
3030 | } | ||
3031 | |||
3032 | static int nv_set_rx_csum(struct net_device *dev, u32 data) | ||
3033 | { | ||
3034 | struct fe_priv *np = netdev_priv(dev); | ||
3035 | u8 __iomem *base = get_hwbase(dev); | ||
3036 | int retcode = 0; | ||
3037 | |||
3038 | if (np->driver_data & DEV_HAS_CHECKSUM) { | ||
3039 | |||
3040 | if (((np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) && data) || | ||
3041 | (!(np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) && !data)) { | ||
3042 | /* already set or unset */ | ||
3043 | return 0; | ||
3044 | } | ||
3045 | |||
3046 | if (data) { | ||
3047 | np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; | ||
3048 | } else if (!(np->vlanctl_bits & NVREG_VLANCONTROL_ENABLE)) { | ||
3049 | np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK; | ||
3050 | } else { | ||
3051 | printk(KERN_INFO "Can not disable rx checksum if vlan is enabled\n"); | ||
3052 | return -EINVAL; | ||
3053 | } | ||
3054 | |||
3055 | if (netif_running(dev)) { | ||
3056 | spin_lock_irq(&np->lock); | ||
3057 | writel(np->txrxctl_bits, base + NvRegTxRxControl); | ||
3058 | spin_unlock_irq(&np->lock); | ||
3059 | } | ||
3060 | } else { | ||
3061 | return -EINVAL; | ||
3062 | } | ||
3063 | |||
3064 | return retcode; | ||
3065 | } | ||
3066 | |||
3067 | static int nv_set_tx_csum(struct net_device *dev, u32 data) | ||
3068 | { | ||
3069 | struct fe_priv *np = netdev_priv(dev); | ||
3070 | |||
3071 | if (np->driver_data & DEV_HAS_CHECKSUM) | ||
3072 | return ethtool_op_set_tx_hw_csum(dev, data); | ||
3073 | else | ||
3074 | return -EOPNOTSUPP; | ||
3075 | } | ||
3076 | |||
3077 | static int nv_set_sg(struct net_device *dev, u32 data) | ||
3078 | { | ||
3079 | struct fe_priv *np = netdev_priv(dev); | ||
3080 | |||
3081 | if (np->driver_data & DEV_HAS_CHECKSUM) | ||
3082 | return ethtool_op_set_sg(dev, data); | ||
3083 | else | ||
3084 | return -EOPNOTSUPP; | ||
3085 | } | ||
3086 | |||
3024 | static struct ethtool_ops ops = { | 3087 | static struct ethtool_ops ops = { |
3025 | .get_drvinfo = nv_get_drvinfo, | 3088 | .get_drvinfo = nv_get_drvinfo, |
3026 | .get_link = ethtool_op_get_link, | 3089 | .get_link = ethtool_op_get_link, |
@@ -3038,6 +3101,12 @@ static struct ethtool_ops ops = { | |||
3038 | .set_ringparam = nv_set_ringparam, | 3101 | .set_ringparam = nv_set_ringparam, |
3039 | .get_pauseparam = nv_get_pauseparam, | 3102 | .get_pauseparam = nv_get_pauseparam, |
3040 | .set_pauseparam = nv_set_pauseparam, | 3103 | .set_pauseparam = nv_set_pauseparam, |
3104 | .get_rx_csum = nv_get_rx_csum, | ||
3105 | .set_rx_csum = nv_set_rx_csum, | ||
3106 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
3107 | .set_tx_csum = nv_set_tx_csum, | ||
3108 | .get_sg = ethtool_op_get_sg, | ||
3109 | .set_sg = nv_set_sg, | ||
3041 | }; | 3110 | }; |
3042 | 3111 | ||
3043 | static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | 3112 | static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) |