revert: kernel: rtl8306: fix max pvid & remove port isolation

apparently this one was nt a good idea to merge

Signed-off-by: John Crispin <blogic@openwrt.org>

SVN-Revision: 40330
lede-17.01
John Crispin 2014-03-30 10:04:55 +00:00
parent e36568e74b
commit 3972b47458
1 changed files with 37 additions and 76 deletions

View File

@ -361,31 +361,6 @@ rtl_set(struct switch_dev *dev, enum rtl_regidx s, unsigned int val)
return rtl_rmw(dev, r->page, r->phy, r->reg, mask, val); return rtl_rmw(dev, r->page, r->phy, r->reg, mask, val);
} }
static void
rtl_fix_pvids(struct switch_dev *dev)
{
unsigned int port, vlan, mask;
for (port = 0; port < RTL8306_NUM_PORTS; port++)
{
/* skip tagged ports */
if (rtl_get(dev, RTL_PORT_REG(port, TAG_INSERT)) != 1)
continue;
for (vlan = 0; vlan < RTL8306_NUM_VLANS; vlan++)
{
mask = rtl_get(dev, RTL_VLAN_REG(vlan, PORTMASK));
/* skip non-members */
if (!(mask & (1 << port)))
continue;
rtl_set(dev, RTL_PORT_REG(port, PVID), vlan);
/* next port */
break;
}
}
}
static void static void
rtl_phy_save(struct switch_dev *dev, int port, struct rtl_phyregs *regs) rtl_phy_save(struct switch_dev *dev, int port, struct rtl_phyregs *regs)
{ {
@ -469,6 +444,7 @@ static void
rtl_hw_init(struct switch_dev *dev) rtl_hw_init(struct switch_dev *dev)
{ {
struct rtl_priv *priv = to_rtl(dev); struct rtl_priv *priv = to_rtl(dev);
int cpu_mask = 1 << dev->cpu_port;
int i; int i;
rtl_set(dev, RTL_REG_VLAN_ENABLE, 0); rtl_set(dev, RTL_REG_VLAN_ENABLE, 0);
@ -494,19 +470,21 @@ rtl_hw_init(struct switch_dev *dev)
rtl_set(dev, RTL_VLAN_REG(i, PORTMASK), 0); rtl_set(dev, RTL_VLAN_REG(i, PORTMASK), 0);
} }
#ifdef DEBUG
/* default to port isolation */ /* default to port isolation */
for (i = 0; i < RTL8306_NUM_PORTS; i++) { for (i = 0; i < RTL8306_NUM_PORTS; i++) {
if (i != dev->cpu_port) unsigned long mask;
rtl_set(dev, RTL_VLAN_REG(i, PORTMASK), (1 << dev->cpu_port) | (1 << i));
if ((1 << i) == cpu_mask)
mask = ((1 << RTL8306_NUM_PORTS) - 1) & ~cpu_mask; /* all bits set */
else
mask = cpu_mask | (1 << i);
rtl_set(dev, RTL_VLAN_REG(i, PORTMASK), mask);
rtl_set(dev, RTL_PORT_REG(i, PVID), i); rtl_set(dev, RTL_PORT_REG(i, PVID), i);
rtl_set(dev, RTL_PORT_REG(i, NULL_VID_REPLACE), 1); rtl_set(dev, RTL_PORT_REG(i, NULL_VID_REPLACE), 1);
rtl_set(dev, RTL_PORT_REG(i, VID_INSERT), 1); rtl_set(dev, RTL_PORT_REG(i, VID_INSERT), 1);
rtl_set(dev, RTL_PORT_REG(i, TAG_INSERT), 3); rtl_set(dev, RTL_PORT_REG(i, TAG_INSERT), 3);
} }
#endif
rtl_fix_pvids(dev);
rtl_hw_apply(dev); rtl_hw_apply(dev);
} }
@ -591,7 +569,6 @@ rtl_attr_get_int(struct switch_dev *dev, const struct switch_attr *attr, struct
return 0; return 0;
} }
#ifdef DEBUG
static int static int
rtl_attr_set_port_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) rtl_attr_set_port_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{ {
@ -608,39 +585,6 @@ rtl_attr_get_port_int(struct switch_dev *dev, const struct switch_attr *attr, st
return -EINVAL; return -EINVAL;
return rtl_attr_get_int(dev, attr, val); return rtl_attr_get_int(dev, attr, val);
} }
#endif
static int
rtl_attr_set_port_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
unsigned int vlan;
if (val->port_vlan >= RTL8306_NUM_PORTS)
return -EINVAL;
for (vlan = 0; vlan < RTL8306_NUM_VLANS; vlan++) {
if (rtl_get(dev, RTL_VLAN_REG(vlan, VID)) == val->value.i) {
rtl_set(dev, RTL_PORT_REG(val->port_vlan, PVID), vlan);
break;
}
}
return 0;
}
static int
rtl_attr_get_port_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
unsigned int vlan;
if (val->port_vlan >= RTL8306_NUM_PORTS)
return -EINVAL;
vlan = rtl_get(dev, RTL_PORT_REG(val->port_vlan, PVID));
val->value.i = rtl_get(dev, RTL_VLAN_REG(vlan, VID));
return 0;
}
static int static int
rtl_get_port_link(struct switch_dev *dev, int port, struct switch_port_link *link) rtl_get_port_link(struct switch_dev *dev, int port, struct switch_port_link *link)
@ -695,7 +639,7 @@ rtl_get_ports(struct switch_dev *dev, struct switch_val *val)
port = &val->value.ports[val->len]; port = &val->value.ports[val->len];
port->id = i; port->id = i;
if (rtl_get(dev, RTL_PORT_REG(i, TAG_INSERT)) == 2) if (rtl_get(dev, RTL_PORT_REG(i, TAG_INSERT)) == 2 || i == dev->cpu_port)
port->flags = (1 << SWITCH_PORT_FLAG_TAGGED); port->flags = (1 << SWITCH_PORT_FLAG_TAGGED);
val->len++; val->len++;
} }
@ -722,15 +666,13 @@ rtl_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct swit
if (i > 3) if (i > 3)
rtl_phy_save(dev, val->port_vlan, &port); rtl_phy_save(dev, val->port_vlan, &port);
rtl_set(dev, RTL_PORT_REG(i, NULL_VID_REPLACE), 1); rtl_set(dev, RTL_PORT_REG(i, NULL_VID_REPLACE), 1);
rtl_set(dev, RTL_PORT_REG(i, VID_INSERT), 1); rtl_set(dev, RTL_PORT_REG(i, VID_INSERT), (en ? (i == dev->cpu_port ? 0 : 1) : 1));
rtl_set(dev, RTL_PORT_REG(i, TAG_INSERT), (en ? 1 : 3)); rtl_set(dev, RTL_PORT_REG(i, TAG_INSERT), (en ? (i == dev->cpu_port ? 2 : 1) : 3));
if (i > 3) if (i > 3)
rtl_phy_restore(dev, val->port_vlan, &port); rtl_phy_restore(dev, val->port_vlan, &port);
} }
rtl_set(dev, RTL_REG_VLAN_ENABLE, en); rtl_set(dev, RTL_REG_VLAN_ENABLE, en);
rtl_fix_pvids(dev);
return 0; return 0;
} }
@ -745,6 +687,7 @@ static int
rtl_set_ports(struct switch_dev *dev, struct switch_val *val) rtl_set_ports(struct switch_dev *dev, struct switch_val *val)
{ {
unsigned int mask = 0; unsigned int mask = 0;
unsigned int oldmask;
int i; int i;
for(i = 0; i < val->len; i++) for(i = 0; i < val->len; i++)
@ -754,17 +697,37 @@ rtl_set_ports(struct switch_dev *dev, struct switch_val *val)
mask |= (1 << port->id); mask |= (1 << port->id);
if (port->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) if (port->id == dev->cpu_port)
continue;
if ((i == dev->cpu_port) ||
(port->flags & (1 << SWITCH_PORT_FLAG_TAGGED)))
tagged = true; tagged = true;
/* fix up PVIDs for added ports */
if (!tagged)
rtl_set(dev, RTL_PORT_REG(port->id, PVID), val->port_vlan);
rtl_set(dev, RTL_PORT_REG(port->id, NON_PVID_DISCARD), (tagged ? 0 : 1)); rtl_set(dev, RTL_PORT_REG(port->id, NON_PVID_DISCARD), (tagged ? 0 : 1));
rtl_set(dev, RTL_PORT_REG(port->id, VID_INSERT), (tagged ? 0 : 1)); rtl_set(dev, RTL_PORT_REG(port->id, VID_INSERT), (tagged ? 0 : 1));
rtl_set(dev, RTL_PORT_REG(port->id, TAG_INSERT), (tagged ? 2 : 1)); rtl_set(dev, RTL_PORT_REG(port->id, TAG_INSERT), (tagged ? 2 : 1));
} }
oldmask = rtl_get(dev, RTL_VLAN_REG(val->port_vlan, PORTMASK));
rtl_set(dev, RTL_VLAN_REG(val->port_vlan, PORTMASK), mask); rtl_set(dev, RTL_VLAN_REG(val->port_vlan, PORTMASK), mask);
rtl_fix_pvids(dev); /* fix up PVIDs for removed ports, default to last vlan */
oldmask &= ~mask;
for (i = 0; i < RTL8306_NUM_PORTS; i++) {
if (!(oldmask & (1 << i)))
continue;
if (i == dev->cpu_port)
continue;
if (rtl_get(dev, RTL_PORT_REG(i, PVID)) == val->port_vlan)
rtl_set(dev, RTL_PORT_REG(i, PVID), dev->vlans - 1);
}
return 0; return 0;
} }
@ -835,12 +798,10 @@ static struct switch_attr rtl_globals[] = {
}; };
static struct switch_attr rtl_port[] = { static struct switch_attr rtl_port[] = {
{ {
.type = SWITCH_TYPE_INT, RTL_PORT_REGATTR(PVID),
.set = rtl_attr_set_port_pvid,
.get = rtl_attr_get_port_pvid,
.name = "pvid", .name = "pvid",
.description = "Port VLAN ID", .description = "Port VLAN ID",
.max = 4095, .max = RTL8306_NUM_VLANS - 1,
}, },
#ifdef DEBUG #ifdef DEBUG
{ {