aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/forcedeth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r--drivers/net/forcedeth.c85
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
3026static 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
3032static 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
3067static 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
3077static 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
3024static struct ethtool_ops ops = { 3087static 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
3043static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) 3112static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)