diff options
Diffstat (limited to 'net/dsa/dsa.c')
| -rw-r--r-- | net/dsa/dsa.c | 42 | 
1 files changed, 33 insertions, 9 deletions
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 416ac4ef9ba9..03c58b0eb082 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -67,17 +67,17 @@ const struct dsa_device_ops *dsa_device_ops[DSA_TAG_LAST] = {  	[DSA_TAG_PROTO_NONE] = &none_ops,  }; -int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev, -		      struct dsa_port *dport, int port) +int dsa_cpu_dsa_setup(struct dsa_port *port)  { -	struct device_node *port_dn = dport->dn; +	struct device_node *port_dn = port->dn; +	struct dsa_switch *ds = port->ds;  	struct phy_device *phydev;  	int ret, mode;  	if (of_phy_is_fixed_link(port_dn)) {  		ret = of_phy_register_fixed_link(port_dn);  		if (ret) { -			dev_err(dev, "failed to register fixed PHY\n"); +			dev_err(ds->dev, "failed to register fixed PHY\n");  			return ret;  		}  		phydev = of_phy_find_device(port_dn); @@ -90,7 +90,7 @@ int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev,  		genphy_config_init(phydev);  		genphy_read_status(phydev);  		if (ds->ops->adjust_link) -			ds->ops->adjust_link(ds, port, phydev); +			ds->ops->adjust_link(ds, port->index, phydev);  		put_device(&phydev->mdio.dev);  	} @@ -186,10 +186,12 @@ struct net_device *dsa_dev_to_net_device(struct device *dev)  EXPORT_SYMBOL_GPL(dsa_dev_to_net_device);  static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, -			  struct packet_type *pt, struct net_device *orig_dev) +			  struct packet_type *pt, struct net_device *unused)  {  	struct dsa_switch_tree *dst = dev->dsa_ptr;  	struct sk_buff *nskb = NULL; +	struct pcpu_sw_netstats *s; +	struct dsa_slave_priv *p;  	if (unlikely(dst == NULL)) {  		kfree_skb(skb); @@ -200,19 +202,23 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,  	if (!skb)  		return 0; -	nskb = dst->rcv(skb, dev, pt, orig_dev); +	nskb = dst->rcv(skb, dev, pt);  	if (!nskb) {  		kfree_skb(skb);  		return 0;  	}  	skb = nskb; +	p = netdev_priv(skb->dev);  	skb_push(skb, ETH_HLEN);  	skb->pkt_type = PACKET_HOST;  	skb->protocol = eth_type_trans(skb, skb->dev); -	skb->dev->stats.rx_packets++; -	skb->dev->stats.rx_bytes += skb->len; +	s = this_cpu_ptr(p->stats64); +	u64_stats_update_begin(&s->syncp); +	s->rx_packets++; +	s->rx_bytes += skb->len; +	u64_stats_update_end(&s->syncp);  	netif_receive_skb(skb); @@ -220,6 +226,11 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,  }  #ifdef CONFIG_PM_SLEEP +static bool dsa_is_port_initialized(struct dsa_switch *ds, int p) +{ +	return ds->enabled_port_mask & (1 << p) && ds->ports[p].netdev; +} +  int dsa_switch_suspend(struct dsa_switch *ds)  {  	int i, ret = 0; @@ -271,10 +282,22 @@ static struct packet_type dsa_pack_type __read_mostly = {  	.func	= dsa_switch_rcv,  }; +static struct workqueue_struct *dsa_owq; + +bool dsa_schedule_work(struct work_struct *work) +{ +	return queue_work(dsa_owq, work); +} +  static int __init dsa_init_module(void)  {  	int rc; +	dsa_owq = alloc_ordered_workqueue("dsa_ordered", +					  WQ_MEM_RECLAIM); +	if (!dsa_owq) +		return -ENOMEM; +  	rc = dsa_slave_register_notifier();  	if (rc)  		return rc; @@ -294,6 +317,7 @@ static void __exit dsa_cleanup_module(void)  	dsa_slave_unregister_notifier();  	dev_remove_pack(&dsa_pack_type);  	dsa_legacy_unregister(); +	destroy_workqueue(dsa_owq);  }  module_exit(dsa_cleanup_module);  |