Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux-2.6-block.git] / net / dsa / master.c
index 5e8c9bef78bd2ec26b405d1de6e9a74845492e8b..71bb15f491c81af1c911d4182d746e89095ae68e 100644 (file)
@@ -179,10 +179,38 @@ static const struct attribute_group dsa_group = {
        .attrs  = dsa_slave_attrs,
 };
 
+static void dsa_master_set_mtu(struct net_device *dev, struct dsa_port *cpu_dp)
+{
+       unsigned int mtu = ETH_DATA_LEN + cpu_dp->tag_ops->overhead;
+       int err;
+
+       rtnl_lock();
+       if (mtu <= dev->max_mtu) {
+               err = dev_set_mtu(dev, mtu);
+               if (err)
+                       netdev_dbg(dev, "Unable to set MTU to include for DSA overheads\n");
+       }
+       rtnl_unlock();
+}
+
+static void dsa_master_reset_mtu(struct net_device *dev)
+{
+       int err;
+
+       rtnl_lock();
+       err = dev_set_mtu(dev, ETH_DATA_LEN);
+       if (err)
+               netdev_dbg(dev,
+                          "Unable to reset MTU to exclude DSA overheads\n");
+       rtnl_unlock();
+}
+
 int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp)
 {
        int ret;
 
+       dsa_master_set_mtu(dev,  cpu_dp);
+
        /* If we use a tagging format that doesn't have an ethertype
         * field, make sure that all packets from this point on get
         * sent to the tag format's receive function.
@@ -206,6 +234,7 @@ void dsa_master_teardown(struct net_device *dev)
 {
        sysfs_remove_group(&dev->dev.kobj, &dsa_group);
        dsa_master_ethtool_teardown(dev);
+       dsa_master_reset_mtu(dev);
 
        dev->dsa_ptr = NULL;