]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/dsa/dsa.c
net: dsa: Relocate master ethtool operations
[karo-tx-linux.git] / net / dsa / dsa.c
index 26130ae438da53f3f99a4e9fa712a572f40ca779..416ac4ef9ba9c5d77f36e6902cf031628f72cc05 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/phy_fixed.h>
 #include <linux/gpio/consumer.h>
 #include <linux/etherdevice.h>
-#include <net/dsa.h>
+
 #include "dsa_priv.h"
 
 static struct sk_buff *dsa_slave_notag_xmit(struct sk_buff *skb,
@@ -40,26 +40,29 @@ static const struct dsa_device_ops none_ops = {
 };
 
 const struct dsa_device_ops *dsa_device_ops[DSA_TAG_LAST] = {
+#ifdef CONFIG_NET_DSA_TAG_BRCM
+       [DSA_TAG_PROTO_BRCM] = &brcm_netdev_ops,
+#endif
 #ifdef CONFIG_NET_DSA_TAG_DSA
        [DSA_TAG_PROTO_DSA] = &dsa_netdev_ops,
 #endif
 #ifdef CONFIG_NET_DSA_TAG_EDSA
        [DSA_TAG_PROTO_EDSA] = &edsa_netdev_ops,
 #endif
-#ifdef CONFIG_NET_DSA_TAG_TRAILER
-       [DSA_TAG_PROTO_TRAILER] = &trailer_netdev_ops,
+#ifdef CONFIG_NET_DSA_TAG_KSZ
+       [DSA_TAG_PROTO_KSZ] = &ksz_netdev_ops,
 #endif
-#ifdef CONFIG_NET_DSA_TAG_BRCM
-       [DSA_TAG_PROTO_BRCM] = &brcm_netdev_ops,
-#endif
-#ifdef CONFIG_NET_DSA_TAG_QCA
-       [DSA_TAG_PROTO_QCA] = &qca_netdev_ops,
+#ifdef CONFIG_NET_DSA_TAG_LAN9303
+       [DSA_TAG_PROTO_LAN9303] = &lan9303_netdev_ops,
 #endif
 #ifdef CONFIG_NET_DSA_TAG_MTK
        [DSA_TAG_PROTO_MTK] = &mtk_netdev_ops,
 #endif
-#ifdef CONFIG_NET_DSA_TAG_LAN9303
-       [DSA_TAG_PROTO_LAN9303] = &lan9303_netdev_ops,
+#ifdef CONFIG_NET_DSA_TAG_QCA
+       [DSA_TAG_PROTO_QCA] = &qca_netdev_ops,
+#endif
+#ifdef CONFIG_NET_DSA_TAG_TRAILER
+       [DSA_TAG_PROTO_TRAILER] = &trailer_netdev_ops,
 #endif
        [DSA_TAG_PROTO_NONE] = &none_ops,
 };
@@ -109,23 +112,22 @@ const struct dsa_device_ops *dsa_resolve_tag_protocol(int tag_protocol)
        return ops;
 }
 
-int dsa_cpu_port_ethtool_setup(struct dsa_switch *ds)
+int dsa_cpu_port_ethtool_setup(struct dsa_port *cpu_dp)
 {
+       struct dsa_switch *ds = cpu_dp->ds;
        struct net_device *master;
        struct ethtool_ops *cpu_ops;
 
-       master = ds->dst->master_netdev;
-       if (ds->master_netdev)
-               master = ds->master_netdev;
+       master = cpu_dp->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,
+       memcpy(&cpu_dp->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,
+       cpu_dp->orig_ethtool_ops = master->ethtool_ops;
+       memcpy(cpu_ops, &cpu_dp->ethtool_ops,
               sizeof(struct ethtool_ops));
        dsa_cpu_port_ethtool_init(cpu_ops);
        master->ethtool_ops = cpu_ops;
@@ -133,15 +135,9 @@ int dsa_cpu_port_ethtool_setup(struct dsa_switch *ds)
        return 0;
 }
 
-void dsa_cpu_port_ethtool_restore(struct dsa_switch *ds)
+void dsa_cpu_port_ethtool_restore(struct dsa_port *cpu_dp)
 {
-       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;
+       cpu_dp->netdev->ethtool_ops = cpu_dp->orig_ethtool_ops;
 }
 
 void dsa_cpu_dsa_destroy(struct dsa_port *port)
@@ -223,6 +219,53 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+int dsa_switch_suspend(struct dsa_switch *ds)
+{
+       int i, ret = 0;
+
+       /* Suspend slave network devices */
+       for (i = 0; i < ds->num_ports; i++) {
+               if (!dsa_is_port_initialized(ds, i))
+                       continue;
+
+               ret = dsa_slave_suspend(ds->ports[i].netdev);
+               if (ret)
+                       return ret;
+       }
+
+       if (ds->ops->suspend)
+               ret = ds->ops->suspend(ds);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dsa_switch_suspend);
+
+int dsa_switch_resume(struct dsa_switch *ds)
+{
+       int i, ret = 0;
+
+       if (ds->ops->resume)
+               ret = ds->ops->resume(ds);
+
+       if (ret)
+               return ret;
+
+       /* Resume slave network devices */
+       for (i = 0; i < ds->num_ports; i++) {
+               if (!dsa_is_port_initialized(ds, i))
+                       continue;
+
+               ret = dsa_slave_resume(ds->ports[i].netdev);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dsa_switch_resume);
+#endif
+
 static struct packet_type dsa_pack_type __read_mostly = {
        .type   = cpu_to_be16(ETH_P_XDSA),
        .func   = dsa_switch_rcv,