diff options
4 files changed, 217 insertions, 410 deletions
| diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c index bb2e3ba68..dacb46594 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c +++ b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c @@ -281,6 +281,209 @@ int rtl8366_smi_rmwr(struct rtl8366_smi *smi, u32 addr, u32 mask, u32 data)  }  EXPORT_SYMBOL_GPL(rtl8366_smi_rmwr); +static int rtl8366_mc_is_used(struct rtl8366_smi *smi, int mc_index, int *used) +{ +	int err; +	int i; + +	*used = 0; +	for (i = 0; i < smi->num_ports; i++) { +		int index = 0; + +		err = smi->ops->get_mc_index(smi, i, &index); +		if (err) +			return err; + +		if (mc_index == index) { +			*used = 1; +			break; +		} +	} + +	return 0; +} + +int rtl8366_set_vlan(struct rtl8366_smi *smi, int vid, u32 member, u32 untag, +		     u32 fid) +{ +	struct rtl8366_vlan_4k vlan4k; +	int err; +	int i; + +	/* Update the 4K table */ +	err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); +	if (err) +		return err; + +	vlan4k.member = member; +	vlan4k.untag = untag; +	vlan4k.fid = fid; +	err = smi->ops->set_vlan_4k(smi, &vlan4k); +	if (err) +		return err; + +	/* Try to find an existing MC entry for this VID */ +	for (i = 0; i < smi->num_vlan_mc; i++) { +		struct rtl8366_vlan_mc vlanmc; + +		err = smi->ops->get_vlan_mc(smi, i, &vlanmc); +		if (err) +			return err; + +		if (vid == vlanmc.vid) { +			/* update the MC entry */ +			vlanmc.member = member; +			vlanmc.untag = untag; +			vlanmc.fid = fid; + +			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); +			break; +		} +	} + +	return err; +} +EXPORT_SYMBOL_GPL(rtl8366_set_vlan); + +int rtl8366_reset_vlan(struct rtl8366_smi *smi) +{ +	struct rtl8366_vlan_mc vlanmc; +	int err; +	int i; + +	/* clear VLAN member configurations */ +	vlanmc.vid = 0; +	vlanmc.priority = 0; +	vlanmc.member = 0; +	vlanmc.untag = 0; +	vlanmc.fid = 0; +	for (i = 0; i < smi->num_vlan_mc; i++) { +		err = smi->ops->set_vlan_mc(smi, i, &vlanmc); +		if (err) +			return err; +	} + +	for (i = 0; i < smi->num_ports; i++) { +		if (i == smi->cpu_port) +			continue; + +		err = rtl8366_set_vlan(smi, (i + 1), +					(1 << i) | (1 << smi->cpu_port), +					(1 << i) | (1 << smi->cpu_port), +					0); +		if (err) +			return err; + +		err = rtl8366_set_pvid(smi, i, (i + 1)); +		if (err) +			return err; +	} + +	return 0; +} +EXPORT_SYMBOL_GPL(rtl8366_reset_vlan); + +int rtl8366_get_pvid(struct rtl8366_smi *smi, int port, int *val) +{ +	struct rtl8366_vlan_mc vlanmc; +	int err; +	int index; + +	err = smi->ops->get_mc_index(smi, port, &index); +	if (err) +		return err; + +	err = smi->ops->get_vlan_mc(smi, index, &vlanmc); +	if (err) +		return err; + +	*val = vlanmc.vid; +	return 0; +} +EXPORT_SYMBOL_GPL(rtl8366_get_pvid); + +int rtl8366_set_pvid(struct rtl8366_smi *smi, unsigned port, unsigned vid) +{ +	struct rtl8366_vlan_mc vlanmc; +	struct rtl8366_vlan_4k vlan4k; +	int err; +	int i; + +	/* Try to find an existing MC entry for this VID */ +	for (i = 0; i < smi->num_vlan_mc; i++) { +		err = smi->ops->get_vlan_mc(smi, i, &vlanmc); +		if (err) +			return err; + +		if (vid == vlanmc.vid) { +			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); +			if (err) +				return err; + +			err = smi->ops->set_mc_index(smi, port, i); +			return err; +		} +	} + +	/* We have no MC entry for this VID, try to find an empty one */ +	for (i = 0; i < smi->num_vlan_mc; i++) { +		err = smi->ops->get_vlan_mc(smi, i, &vlanmc); +		if (err) +			return err; + +		if (vlanmc.vid == 0 && vlanmc.member == 0) { +			/* Update the entry from the 4K table */ +			err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); +			if (err) +				return err; + +			vlanmc.vid = vid; +			vlanmc.member = vlan4k.member; +			vlanmc.untag = vlan4k.untag; +			vlanmc.fid = vlan4k.fid; +			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); +			if (err) +				return err; + +			err = smi->ops->set_mc_index(smi, port, i); +			return err; +		} +	} + +	/* MC table is full, try to find an unused entry and replace it */ +	for (i = 0; i < smi->num_vlan_mc; i++) { +		int used; + +		err = rtl8366_mc_is_used(smi, i, &used); +		if (err) +			return err; + +		if (!used) { +			/* Update the entry from the 4K table */ +			err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); +			if (err) +				return err; + +			vlanmc.vid = vid; +			vlanmc.member = vlan4k.member; +			vlanmc.untag = vlan4k.untag; +			vlanmc.fid = vlan4k.fid; +			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); +			if (err) +				return err; + +			err = smi->ops->set_mc_index(smi, port, i); +			return err; +		} +	} + +	dev_err(smi->parent, +		"all VLAN member configurations are in use\n"); + +	return -ENOSPC; +} +EXPORT_SYMBOL_GPL(rtl8366_set_pvid); +  static int rtl8366_smi_mii_init(struct rtl8366_smi *smi)  {  	int ret; diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h index 9ed8c4573..f111f2b52 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h +++ b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h @@ -71,4 +71,10 @@ int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data);  int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data);  int rtl8366_smi_rmwr(struct rtl8366_smi *smi, u32 addr, u32 mask, u32 data); +int rtl8366_set_vlan(struct rtl8366_smi *smi, int vid, u32 member, u32 untag, +		     u32 fid); +int rtl8366_reset_vlan(struct rtl8366_smi *smi); +int rtl8366_get_pvid(struct rtl8366_smi *smi, int port, int *val); +int rtl8366_set_pvid(struct rtl8366_smi *smi, unsigned port, unsigned vid); +  #endif /*  _RTL8366_SMI_H */ diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366rb.c b/target/linux/generic/files/drivers/net/phy/rtl8366rb.c index f70744ec0..02de05575 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8366rb.c +++ b/target/linux/generic/files/drivers/net/phy/rtl8366rb.c @@ -671,170 +671,6 @@ static int rtl8366rb_set_mc_index(struct rtl8366_smi *smi, int port, int index)  					RTL8366RB_PORT_VLAN_CTRL_SHIFT(port));  } -static int rtl8366rb_set_vlan(struct rtl8366_smi *smi, int vid, u32 member, -			      u32 untag, u32 fid) -{ -	struct rtl8366_vlan_4k vlan4k; -	int err; -	int i; - -	/* Update the 4K table */ -	err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); -	if (err) -		return err; - -	vlan4k.member = member; -	vlan4k.untag = untag; -	vlan4k.fid = fid; -	err = smi->ops->set_vlan_4k(smi, &vlan4k); -	if (err) -		return err; - -	/* Try to find an existing MC entry for this VID */ -	for (i = 0; i < smi->num_vlan_mc; i++) { -		struct rtl8366_vlan_mc vlanmc; - -		err = smi->ops->get_vlan_mc(smi, i, &vlanmc); -		if (err) -			return err; - -		if (vid == vlanmc.vid) { -			/* update the MC entry */ -			vlanmc.member = member; -			vlanmc.untag = untag; -			vlanmc.fid = fid; - -			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -			break; -		} -	} - -	return err; -} - -static int rtl8366rb_get_pvid(struct rtl8366_smi *smi, int port, int *val) -{ -	struct rtl8366_vlan_mc vlanmc; -	int err; -	int index; - -	err = smi->ops->get_mc_index(smi, port, &index); -	if (err) -		return err; - -	err = smi->ops->get_vlan_mc(smi, index, &vlanmc); -	if (err) -		return err; - -	*val = vlanmc.vid; -	return 0; -} - -static int rtl8366rb_mc_is_used(struct rtl8366_smi *smi, int mc_index, -				int *used) -{ -	int err; -	int i; - -	*used = 0; -	for (i = 0; i < smi->num_ports; i++) { -		int index = 0; - -		err = smi->ops->get_mc_index(smi, i, &index); -		if (err) -			return err; - -		if (mc_index == index) { -			*used = 1; -			break; -		} -	} - -	return 0; -} - -static int rtl8366rb_set_pvid(struct rtl8366_smi *smi, unsigned port, -			      unsigned vid) -{ -	struct rtl8366_vlan_mc vlanmc; -	struct rtl8366_vlan_4k vlan4k; -	int err; -	int i; - -	/* Try to find an existing MC entry for this VID */ -	for (i = 0; i < smi->num_vlan_mc; i++) { -		err = smi->ops->get_vlan_mc(smi, i, &vlanmc); -		if (err) -			return err; - -		if (vid == vlanmc.vid) { -			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -			if (err) -				return err; - -			err = smi->ops->set_mc_index(smi, port, i); -			return err; -		} -	} - -	/* We have no MC entry for this VID, try to find an empty one */ -	for (i = 0; i < smi->num_vlan_mc; i++) { -		err = smi->ops->get_vlan_mc(smi, i, &vlanmc); -		if (err) -			return err; - -		if (vlanmc.vid == 0 && vlanmc.member == 0) { -			/* Update the entry from the 4K table */ -			err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); -			if (err) -				return err; - -			vlanmc.vid = vid; -			vlanmc.member = vlan4k.member; -			vlanmc.untag = vlan4k.untag; -			vlanmc.fid = vlan4k.fid; -			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -			if (err) -				return err; - -			err = smi->ops->set_mc_index(smi, port, i); -			return err; -		} -	} - -	/* MC table is full, try to find an unused entry and replace it */ -	for (i = 0; i < smi->num_vlan_mc; i++) { -		int used; - -		err = rtl8366rb_mc_is_used(smi, i, &used); -		if (err) -			return err; - -		if (!used) { -			/* Update the entry from the 4K table */ -			err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); -			if (err) -				return err; - -			vlanmc.vid = vid; -			vlanmc.member = vlan4k.member; -			vlanmc.untag = vlan4k.untag; -			vlanmc.fid = vlan4k.fid; -			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -			if (err) -				return err; - -			err = smi->ops->set_mc_index(smi, port, i); -			return err; -		} -	} - -	dev_err(smi->parent, -		"all VLAN member configurations are in use\n"); - -	return -ENOSPC; -} -  static int rtl8366rb_vlan_set_vlan(struct rtl8366_smi *smi, int enable)  {  	return rtl8366_smi_rmwr(smi, RTL8366RB_CHIP_GLOBAL_CTRL_REG, @@ -849,43 +685,6 @@ static int rtl8366rb_vlan_set_4ktable(struct rtl8366_smi *smi, int enable)  				(enable) ? RTL8366RB_CHIP_CTRL_VLAN_4KTB : 0);  } -static int rtl8366rb_reset_vlan(struct rtl8366_smi *smi) -{ -	struct rtl8366_vlan_mc vlanmc; -	int err; -	int i; - -	/* clear VLAN member configurations */ -	vlanmc.vid = 0; -	vlanmc.priority = 0; -	vlanmc.member = 0; -	vlanmc.untag = 0; -	vlanmc.fid = 0; -	for (i = 0; i < smi->num_vlan_mc; i++) { -		err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -		if (err) -			return err; -	} - -	for (i = 0; i < smi->num_ports; i++) { -		if (i == smi->cpu_port) -			continue; - -		err = rtl8366rb_set_vlan(smi, (i + 1), -					 (1 << i) | (1 << smi->cpu_port), -					 (1 << i) | (1 << smi->cpu_port), -					 0); -		if (err) -			return err; - -		err = rtl8366rb_set_pvid(smi, i, (i + 1)); -		if (err) -			return err; -	} - -	return 0; -} -  #ifdef CONFIG_RTL8366S_PHY_DEBUG_FS  static int rtl8366rb_debugfs_open(struct inode *inode, struct file *file)  { @@ -1410,19 +1209,19 @@ static int rtl8366rb_sw_set_vlan_ports(struct switch_dev *dev,  			untag |= BIT(port->id);  	} -	return rtl8366rb_set_vlan(smi, val->port_vlan, member, untag, 0); +	return rtl8366_set_vlan(smi, val->port_vlan, member, untag, 0);  }  static int rtl8366rb_sw_get_port_pvid(struct switch_dev *dev, int port, int *val)  {  	struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -	return rtl8366rb_get_pvid(smi, port, val); +	return rtl8366_get_pvid(smi, port, val);  }  static int rtl8366rb_sw_set_port_pvid(struct switch_dev *dev, int port, int val)  {  	struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -	return rtl8366rb_set_pvid(smi, port, val); +	return rtl8366_set_pvid(smi, port, val);  }  static int rtl8366rb_sw_reset_switch(struct switch_dev *dev) @@ -1438,7 +1237,7 @@ static int rtl8366rb_sw_reset_switch(struct switch_dev *dev)  	if (err)  		return err; -	return rtl8366rb_reset_vlan(smi); +	return rtl8366_reset_vlan(smi);  }  static struct switch_attr rtl8366rb_globals[] = { diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366s.c b/target/linux/generic/files/drivers/net/phy/rtl8366s.c index fa3f3cd65..40c9c01f7 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8366s.c +++ b/target/linux/generic/files/drivers/net/phy/rtl8366s.c @@ -661,170 +661,6 @@ static int rtl8366s_set_mc_index(struct rtl8366_smi *smi, int port, int index)  					RTL8366S_PORT_VLAN_CTRL_SHIFT(port));  } -static int rtl8366s_set_vlan(struct rtl8366_smi *smi, int vid, u32 member, -			     u32 untag, u32 fid) -{ -	struct rtl8366_vlan_4k vlan4k; -	int err; -	int i; - -	/* Update the 4K table */ -	err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); -	if (err) -		return err; - -	vlan4k.member = member; -	vlan4k.untag = untag; -	vlan4k.fid = fid; -	err = smi->ops->set_vlan_4k(smi, &vlan4k); -	if (err) -		return err; - -	/* Try to find an existing MC entry for this VID */ -	for (i = 0; i < smi->num_vlan_mc; i++) { -		struct rtl8366_vlan_mc vlanmc; - -		err = smi->ops->get_vlan_mc(smi, i, &vlanmc); -		if (err) -			return err; - -		if (vid == vlanmc.vid) { -			/* update the MC entry */ -			vlanmc.member = member; -			vlanmc.untag = untag; -			vlanmc.fid = fid; - -			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -			break; -		} -	} - -	return err; -} - -static int rtl8366s_get_pvid(struct rtl8366_smi *smi, int port, int *val) -{ -	struct rtl8366_vlan_mc vlanmc; -	int err; -	int index; - -	err = smi->ops->get_mc_index(smi, port, &index); -	if (err) -		return err; - -	err = smi->ops->get_vlan_mc(smi, index, &vlanmc); -	if (err) -		return err; - -	*val = vlanmc.vid; -	return 0; -} - -static int rtl8366s_mc_is_used(struct rtl8366_smi *smi, int mc_index, -			       int *used) -{ -	int err; -	int i; - -	*used = 0; -	for (i = 0; i < smi->num_ports; i++) { -		int index = 0; - -		err = smi->ops->get_mc_index(smi, i, &index); -		if (err) -			return err; - -		if (mc_index == index) { -			*used = 1; -			break; -		} -	} - -	return 0; -} - -static int rtl8366s_set_pvid(struct rtl8366_smi *smi, unsigned port, -			     unsigned vid) -{ -	struct rtl8366_vlan_mc vlanmc; -	struct rtl8366_vlan_4k vlan4k; -	int err; -	int i; - -	/* Try to find an existing MC entry for this VID */ -	for (i = 0; i < smi->num_vlan_mc; i++) { -		err = smi->ops->get_vlan_mc(smi, i, &vlanmc); -		if (err) -			return err; - -		if (vid == vlanmc.vid) { -			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -			if (err) -				return err; - -			err = smi->ops->set_mc_index(smi, port, i); -			return err; -		} -	} - -	/* We have no MC entry for this VID, try to find an empty one */ -	for (i = 0; i < smi->num_vlan_mc; i++) { -		err = smi->ops->get_vlan_mc(smi, i, &vlanmc); -		if (err) -			return err; - -		if (vlanmc.vid == 0 && vlanmc.member == 0) { -			/* Update the entry from the 4K table */ -			err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); -			if (err) -				return err; - -			vlanmc.vid = vid; -			vlanmc.member = vlan4k.member; -			vlanmc.untag = vlan4k.untag; -			vlanmc.fid = vlan4k.fid; -			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -			if (err) -				return err; - -			err = smi->ops->set_mc_index(smi, port, i); -			return err; -		} -	} - -	/* MC table is full, try to find an unused entry and replace it */ -	for (i = 0; i < smi->num_vlan_mc; i++) { -		int used; - -		err = rtl8366s_mc_is_used(smi, i, &used); -		if (err) -			return err; - -		if (!used) { -			/* Update the entry from the 4K table */ -			err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); -			if (err) -				return err; - -			vlanmc.vid = vid; -			vlanmc.member = vlan4k.member; -			vlanmc.untag = vlan4k.untag; -			vlanmc.fid = vlan4k.fid; -			err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -			if (err) -				return err; - -			err = smi->ops->set_mc_index(smi, port, i); -			return err; -		} -	} - -	dev_err(smi->parent, -		"all VLAN member configurations are in use\n"); - -	return -ENOSPC; -} -  static int rtl8366s_vlan_set_vlan(struct rtl8366_smi *smi, int enable)  {  	return rtl8366_smi_rmwr(smi, RTL8366S_CHIP_GLOBAL_CTRL_REG, @@ -838,43 +674,6 @@ static int rtl8366s_vlan_set_4ktable(struct rtl8366_smi *smi, int enable)  				1, (enable) ? 1 : 0);  } -static int rtl8366s_reset_vlan(struct rtl8366_smi *smi) -{ -	struct rtl8366_vlan_mc vlanmc; -	int err; -	int i; - -	/* clear VLAN member configurations */ -	vlanmc.vid = 0; -	vlanmc.priority = 0; -	vlanmc.member = 0; -	vlanmc.untag = 0; -	vlanmc.fid = 0; -	for (i = 0; i < smi->num_vlan_mc; i++) { -		err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -		if (err) -			return err; -	} - -	for (i = 0; i < smi->num_ports; i++) { -		if (i == smi->cpu_port) -			continue; - -		err = rtl8366s_set_vlan(smi, (i + 1), -					 (1 << i) | (1 << smi->cpu_port), -					 (1 << i) | (1 << smi->cpu_port), -					 0); -		if (err) -			return err; - -		err = rtl8366s_set_pvid(smi, i, (i + 1)); -		if (err) -			return err; -	} - -	return 0; -} -  #ifdef CONFIG_RTL8366S_PHY_DEBUG_FS  static int rtl8366s_debugfs_open(struct inode *inode, struct file *file)  { @@ -1400,19 +1199,19 @@ static int rtl8366s_sw_set_vlan_ports(struct switch_dev *dev,  			untag |= BIT(port->id);  	} -	return rtl8366s_set_vlan(smi, val->port_vlan, member, untag, 0); +	return rtl8366_set_vlan(smi, val->port_vlan, member, untag, 0);  }  static int rtl8366s_sw_get_port_pvid(struct switch_dev *dev, int port, int *val)  {  	struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -	return rtl8366s_get_pvid(smi, port, val); +	return rtl8366_get_pvid(smi, port, val);  }  static int rtl8366s_sw_set_port_pvid(struct switch_dev *dev, int port, int val)  {  	struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -	return rtl8366s_set_pvid(smi, port, val); +	return rtl8366_set_pvid(smi, port, val);  }  static int rtl8366s_sw_reset_switch(struct switch_dev *dev) @@ -1428,7 +1227,7 @@ static int rtl8366s_sw_reset_switch(struct switch_dev *dev)  	if (err)  		return err; -	return rtl8366s_reset_vlan(smi); +	return rtl8366_reset_vlan(smi);  }  static struct switch_attr rtl8366s_globals[] = { | 
