[BRIDGE]: limited ethtool support
[linux-2.6-block.git] / net / bridge / br_device.c
index f7a66abf5def7c5c9c4596da2df2b719597cd422..0b33a7b3a00cd5c05b0b8e16ec91f0aec4a58599 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/ethtool.h>
 
 #include <asm/uaccess.h>
 #include "br_private.h"
@@ -106,6 +107,64 @@ static int br_set_mac_address(struct net_device *dev, void *p)
        return err;
 }
 
+static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+       strcpy(info->driver, "bridge");
+       strcpy(info->version, BR_VERSION);
+       strcpy(info->fw_version, "N/A");
+       strcpy(info->bus_info, "N/A");
+}
+
+static int br_set_sg(struct net_device *dev, u32 data)
+{
+       struct net_bridge *br = netdev_priv(dev);
+
+       if (data)
+               br->feature_mask |= NETIF_F_SG;
+       else
+               br->feature_mask &= ~NETIF_F_SG;
+
+       br_features_recompute(br);
+       return 0;
+}
+
+static int br_set_tso(struct net_device *dev, u32 data)
+{
+       struct net_bridge *br = netdev_priv(dev);
+
+       if (data)
+               br->feature_mask |= NETIF_F_TSO;
+       else
+               br->feature_mask &= ~NETIF_F_TSO;
+
+       br_features_recompute(br);
+       return 0;
+}
+
+static int br_set_tx_csum(struct net_device *dev, u32 data)
+{
+       struct net_bridge *br = netdev_priv(dev);
+
+       if (data)
+               br->feature_mask |= NETIF_F_IP_CSUM;
+       else
+               br->feature_mask &= ~NETIF_F_IP_CSUM;
+
+       br_features_recompute(br);
+       return 0;
+}
+
+static struct ethtool_ops br_ethtool_ops = {
+       .get_drvinfo = br_getinfo,
+       .get_link = ethtool_op_get_link,
+       .get_sg = ethtool_op_get_sg,
+       .set_sg = br_set_sg,
+       .get_tx_csum = ethtool_op_get_tx_csum,
+       .set_tx_csum = br_set_tx_csum,
+       .get_tso = ethtool_op_get_tso,
+       .set_tso = br_set_tso,
+};
+
 void br_dev_setup(struct net_device *dev)
 {
        memset(dev->dev_addr, 0, ETH_ALEN);
@@ -120,8 +179,12 @@ void br_dev_setup(struct net_device *dev)
        dev->change_mtu = br_change_mtu;
        dev->destructor = free_netdev;
        SET_MODULE_OWNER(dev);
+       SET_ETHTOOL_OPS(dev, &br_ethtool_ops);
        dev->stop = br_dev_stop;
        dev->tx_queue_len = 0;
        dev->set_mac_address = br_set_mac_address;
        dev->priv_flags = IFF_EBRIDGE;
+
+       dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
+               | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM;
 }