net: Fix the rollback test in dev_change_name()
[safe/jmp/linux-2.6] / net / core / ethtool.c
index 244ca56..4c12ddb 100644 (file)
@@ -30,10 +30,17 @@ u32 ethtool_op_get_link(struct net_device *dev)
        return netif_carrier_ok(dev) ? 1 : 0;
 }
 
+u32 ethtool_op_get_rx_csum(struct net_device *dev)
+{
+       return (dev->features & NETIF_F_ALL_CSUM) != 0;
+}
+EXPORT_SYMBOL(ethtool_op_get_rx_csum);
+
 u32 ethtool_op_get_tx_csum(struct net_device *dev)
 {
        return (dev->features & NETIF_F_ALL_CSUM) != 0;
 }
+EXPORT_SYMBOL(ethtool_op_get_tx_csum);
 
 int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
 {
@@ -261,8 +268,7 @@ static int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr)
        ret = 0;
 
 err_out:
-       if (rule_buf)
-               kfree(rule_buf);
+       kfree(rule_buf);
 
        return ret;
 }
@@ -892,6 +898,19 @@ static int ethtool_set_value(struct net_device *dev, char __user *useraddr,
        return actor(dev, edata.data);
 }
 
+static int ethtool_flash_device(struct net_device *dev, char __user *useraddr)
+{
+       struct ethtool_flash efl;
+
+       if (copy_from_user(&efl, useraddr, sizeof(efl)))
+               return -EFAULT;
+
+       if (!dev->ethtool_ops->flash_device)
+               return -EOPNOTSUPP;
+
+       return dev->ethtool_ops->flash_device(dev, &efl);
+}
+
 /* The main entry point in this file.  Called from net/core/dev.c */
 
 int dev_ethtool(struct net *net, struct ifreq *ifr)
@@ -1005,7 +1024,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
                break;
        case ETHTOOL_GRXCSUM:
                rc = ethtool_get_value(dev, useraddr, ethcmd,
-                                      dev->ethtool_ops->get_rx_csum);
+                                      (dev->ethtool_ops->get_rx_csum ?
+                                       dev->ethtool_ops->get_rx_csum :
+                                       ethtool_op_get_rx_csum));
                break;
        case ETHTOOL_SRXCSUM:
                rc = ethtool_set_rx_csum(dev, useraddr);
@@ -1069,7 +1090,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
                break;
        case ETHTOOL_GFLAGS:
                rc = ethtool_get_value(dev, useraddr, ethcmd,
-                                      dev->ethtool_ops->get_flags);
+                                      (dev->ethtool_ops->get_flags ?
+                                       dev->ethtool_ops->get_flags :
+                                       ethtool_op_get_flags));
                break;
        case ETHTOOL_SFLAGS:
                rc = ethtool_set_value(dev, useraddr,
@@ -1101,6 +1124,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
        case ETHTOOL_SGRO:
                rc = ethtool_set_gro(dev, useraddr);
                break;
+       case ETHTOOL_FLASHDEV:
+               rc = ethtool_flash_device(dev, useraddr);
+               break;
        default:
                rc = -EOPNOTSUPP;
        }
@@ -1117,7 +1143,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
 EXPORT_SYMBOL(ethtool_op_get_link);
 EXPORT_SYMBOL(ethtool_op_get_sg);
 EXPORT_SYMBOL(ethtool_op_get_tso);
-EXPORT_SYMBOL(ethtool_op_get_tx_csum);
 EXPORT_SYMBOL(ethtool_op_set_sg);
 EXPORT_SYMBOL(ethtool_op_set_tso);
 EXPORT_SYMBOL(ethtool_op_set_tx_csum);