diff options
Diffstat (limited to 'net/dsa')
| -rw-r--r-- | net/dsa/dsa.c | 4 | ||||
| -rw-r--r-- | net/dsa/slave.c | 56 | 
2 files changed, 47 insertions, 13 deletions
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index e6f6cc3a1bcf..392e29a0227d 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -359,7 +359,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,  	 */  	ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL);  	if (ds == NULL) -		return NULL; +		return ERR_PTR(-ENOMEM);  	ds->dst = dst;  	ds->index = index; @@ -370,7 +370,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,  	ret = dsa_switch_setup_one(ds, parent);  	if (ret) -		return NULL; +		return ERR_PTR(ret);  	return ds;  } diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 827cda560a55..0917123790ea 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -112,7 +112,7 @@ static int dsa_slave_open(struct net_device *dev)  clear_promisc:  	if (dev->flags & IFF_PROMISC) -		dev_set_promiscuity(master, 0); +		dev_set_promiscuity(master, -1);  clear_allmulti:  	if (dev->flags & IFF_ALLMULTI)  		dev_set_allmulti(master, -1); @@ -345,6 +345,24 @@ static int dsa_slave_stp_update(struct net_device *dev, u8 state)  	return ret;  } +static int dsa_slave_port_attr_set(struct net_device *dev, +				   struct switchdev_attr *attr) +{ +	int ret = 0; + +	switch (attr->id) { +	case SWITCHDEV_ATTR_PORT_STP_STATE: +		if (attr->trans == SWITCHDEV_TRANS_COMMIT) +			ret = dsa_slave_stp_update(dev, attr->u.stp_state); +		break; +	default: +		ret = -EOPNOTSUPP; +		break; +	} + +	return ret; +} +  static int dsa_slave_bridge_port_join(struct net_device *dev,  				      struct net_device *br)  { @@ -382,14 +400,20 @@ static int dsa_slave_bridge_port_leave(struct net_device *dev)  	return ret;  } -static int dsa_slave_parent_id_get(struct net_device *dev, -				   struct netdev_phys_item_id *psid) +static int dsa_slave_port_attr_get(struct net_device *dev, +				   struct switchdev_attr *attr)  {  	struct dsa_slave_priv *p = netdev_priv(dev);  	struct dsa_switch *ds = p->parent; -	psid->id_len = sizeof(ds->index); -	memcpy(&psid->id, &ds->index, psid->id_len); +	switch (attr->id) { +	case SWITCHDEV_ATTR_PORT_PARENT_ID: +		attr->u.ppid.id_len = sizeof(ds->index); +		memcpy(&attr->u.ppid.id, &ds->index, attr->u.ppid.id_len); +		break; +	default: +		return -EOPNOTSUPP; +	}  	return 0;  } @@ -675,9 +699,9 @@ static const struct net_device_ops dsa_slave_netdev_ops = {  	.ndo_get_iflink		= dsa_slave_get_iflink,  }; -static const struct swdev_ops dsa_slave_swdev_ops = { -	.swdev_parent_id_get = dsa_slave_parent_id_get, -	.swdev_port_stp_update = dsa_slave_stp_update, +static const struct switchdev_ops dsa_slave_switchdev_ops = { +	.switchdev_port_attr_get	= dsa_slave_port_attr_get, +	.switchdev_port_attr_set	= dsa_slave_port_attr_set,  };  static void dsa_slave_adjust_link(struct net_device *dev) @@ -810,12 +834,19 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,  	return 0;  } +static struct lock_class_key dsa_slave_netdev_xmit_lock_key; +static void dsa_slave_set_lockdep_class_one(struct net_device *dev, +					    struct netdev_queue *txq, +					    void *_unused) +{ +	lockdep_set_class(&txq->_xmit_lock, +			  &dsa_slave_netdev_xmit_lock_key); +} +  int dsa_slave_suspend(struct net_device *slave_dev)  {  	struct dsa_slave_priv *p = netdev_priv(slave_dev); -	netif_device_detach(slave_dev); -  	if (p->phy) {  		phy_stop(p->phy);  		p->old_pause = -1; @@ -859,7 +890,10 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,  	eth_hw_addr_inherit(slave_dev, master);  	slave_dev->tx_queue_len = 0;  	slave_dev->netdev_ops = &dsa_slave_netdev_ops; -	slave_dev->swdev_ops = &dsa_slave_swdev_ops; +	slave_dev->switchdev_ops = &dsa_slave_switchdev_ops; + +	netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one, +				 NULL);  	SET_NETDEV_DEV(slave_dev, parent);  	slave_dev->dev.of_node = ds->pd->port_dn[port];  |