diff options
Diffstat (limited to 'net/dsa/dsa.c')
| -rw-r--r-- | net/dsa/dsa.c | 93 | 
1 files changed, 68 insertions, 25 deletions
| diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 26130ae438da..416ac4ef9ba9 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -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, |