* Original copy of the master netdev ethtool_ops
         */
        struct ethtool_ops      master_ethtool_ops;
+       const struct ethtool_ops *master_orig_ethtool_ops;
 
        /*
         * The switch and port to which the CPU is attached.
 
        return ops;
 }
 
+int dsa_cpu_port_ethtool_setup(struct dsa_switch *ds)
+{
+       struct net_device *master;
+       struct ethtool_ops *cpu_ops;
+
+       master = ds->dst->master_netdev;
+       if (ds->master_netdev)
+               master = ds->master_netdev;
+
+       cpu_ops = devm_kzalloc(ds->dev, sizeof(*cpu_ops), GFP_KERNEL);
+       if (!cpu_ops)
+               return -ENOMEM;
+
+       memcpy(&ds->dst->master_ethtool_ops, master->ethtool_ops,
+              sizeof(struct ethtool_ops));
+       ds->dst->master_orig_ethtool_ops = master->ethtool_ops;
+       memcpy(cpu_ops, &ds->dst->master_ethtool_ops,
+              sizeof(struct ethtool_ops));
+       dsa_cpu_port_ethtool_init(cpu_ops);
+       master->ethtool_ops = cpu_ops;
+
+       return 0;
+}
+
+void dsa_cpu_port_ethtool_restore(struct dsa_switch *ds)
+{
+       struct net_device *master;
+
+       master = ds->dst->master_netdev;
+       if (ds->master_netdev)
+               master = ds->master_netdev;
+
+       master->ethtool_ops = ds->dst->master_orig_ethtool_ops;
+}
+
 static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
 {
        struct dsa_switch_driver *drv = ds->drv;
                ret = 0;
        }
 
+       ret = dsa_cpu_port_ethtool_setup(ds);
+       if (ret)
+               return ret;
+
 #ifdef CONFIG_NET_DSA_HWMON
        /* If the switch provides a temperature sensor,
         * register with hardware monitoring subsystem.
                        dsa_switch_destroy(ds);
        }
 
+       dsa_cpu_port_ethtool_restore(dst->ds[0]);
+
        dev_put(dst->master_netdev);
 }
 
 
                        return err;
        }
 
+       err = dsa_cpu_port_ethtool_setup(dst->ds[0]);
+       if (err)
+               return err;
+
        /* 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.
                dsa_ds_unapply(dst, ds);
        }
 
+       dsa_cpu_port_ethtool_restore(dst->ds[0]);
+
        pr_info("DSA: tree %d unapplied\n", dst->tree);
        dst->applied = false;
 }
 
                      struct device_node *port_dn, int port);
 void dsa_cpu_dsa_destroy(struct device_node *port_dn);
 const struct dsa_device_ops *dsa_resolve_tag_protocol(int tag_protocol);
+int dsa_cpu_port_ethtool_setup(struct dsa_switch *ds);
+void dsa_cpu_port_ethtool_restore(struct dsa_switch *ds);
 
 /* slave.c */
 extern const struct dsa_device_ops notag_netdev_ops;
 
        .get_eee                = dsa_slave_get_eee,
 };
 
-static struct ethtool_ops dsa_cpu_port_ethtool_ops;
-
 static const struct net_device_ops dsa_slave_netdev_ops = {
        .ndo_open               = dsa_slave_open,
        .ndo_stop               = dsa_slave_close,
 
        slave_dev->features = master->vlan_features;
        slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
-       if (master->ethtool_ops != &dsa_cpu_port_ethtool_ops) {
-               memcpy(&dst->master_ethtool_ops, master->ethtool_ops,
-                      sizeof(struct ethtool_ops));
-               memcpy(&dsa_cpu_port_ethtool_ops, &dst->master_ethtool_ops,
-                      sizeof(struct ethtool_ops));
-               dsa_cpu_port_ethtool_init(&dsa_cpu_port_ethtool_ops);
-               master->ethtool_ops = &dsa_cpu_port_ethtool_ops;
-       }
        eth_hw_addr_inherit(slave_dev, master);
        slave_dev->priv_flags |= IFF_NO_QUEUE;
        slave_dev->netdev_ops = &dsa_slave_netdev_ops;