Exemple #1
0
static int dsa_slave_port_vlan_add(struct net_device *dev,
				   const struct switchdev_obj_port_vlan *vlan,
				   struct switchdev_trans *trans)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	u16 vid;
	int err;

	if (switchdev_trans_ph_prepare(trans)) {
		if (!ds->drv->port_vlan_add || !ds->drv->port_pvid_set)
			return -EOPNOTSUPP;

		/* If the requested port doesn't belong to the same bridge as
		 * the VLAN members, fallback to software VLAN (hopefully).
		 */
		err = dsa_bridge_check_vlan_range(ds, p->bridge_dev,
						  vlan->vid_begin,
						  vlan->vid_end);
		if (err)
			return err;
	} else {
		for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
			err = ds->drv->port_vlan_add(ds, p->port, vid,
						     vlan->flags &
						     BRIDGE_VLAN_INFO_UNTAGGED);
			if (!err && vlan->flags & BRIDGE_VLAN_INFO_PVID)
				err = ds->drv->port_pvid_set(ds, p->port, vid);
			if (err)
				return err;
		}
	}

	return 0;
}
Exemple #2
0
static int dsa_slave_port_vlan_add(struct net_device *dev,
				   const struct switchdev_obj_port_vlan *vlan,
				   struct switchdev_trans *trans)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	int err;

	if (switchdev_trans_ph_prepare(trans)) {
		if (!ds->drv->port_vlan_prepare || !ds->drv->port_vlan_add)
			return -EOPNOTSUPP;

		/* If the requested port doesn't belong to the same bridge as
		 * the VLAN members, fallback to software VLAN (hopefully).
		 */
		err = dsa_bridge_check_vlan_range(ds, p->bridge_dev,
						  vlan->vid_begin,
						  vlan->vid_end);
		if (err)
			return err;

		err = ds->drv->port_vlan_prepare(ds, p->port, vlan, trans);
		if (err)
			return err;
	} else {
		err = ds->drv->port_vlan_add(ds, p->port, vlan, trans);
		if (err)
			return err;
	}

	return 0;
}
Exemple #3
0
static int dsa_slave_port_vlan_add(struct net_device *dev,
				   struct switchdev_obj *obj)
{
	struct switchdev_obj_vlan *vlan = &obj->u.vlan;
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	u16 vid;
	int err;

	switch (obj->trans) {
	case SWITCHDEV_TRANS_PREPARE:
		if (!ds->drv->port_vlan_add || !ds->drv->port_pvid_set)
			return -EOPNOTSUPP;

		/* If the requested port doesn't belong to the same bridge as
		 * the VLAN members, fallback to software VLAN (hopefully).
		 */
		err = dsa_bridge_check_vlan_range(ds, p->bridge_dev,
						  vlan->vid_begin,
						  vlan->vid_end);
		if (err)
			return err;
		break;
	case SWITCHDEV_TRANS_COMMIT:
		for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
			err = ds->drv->port_vlan_add(ds, p->port, vid,
						     vlan->flags &
						     BRIDGE_VLAN_INFO_UNTAGGED);
			if (!err && vlan->flags & BRIDGE_VLAN_INFO_PVID)
				err = ds->drv->port_pvid_set(ds, p->port, vid);
			if (err)
				return err;
		}
		break;
	default:
		return -EOPNOTSUPP;
	}

	return 0;
}