summaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2009-04-20 21:26:39 +0000
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2009-04-20 21:26:39 +0000
commit52196955dfe288cd3e8cf6e68d1f9b843b1636b1 (patch)
tree2bba7e7551f7016ffeacd1140ae30b5572500db0 /target
parentfd1e16f56021620093e4c5730df4ba8990c23ad2 (diff)
swconfig: add a generic method for setting the port primary vlan id (used for transparently fixing up pvid for untagged port when setting vlan ports)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@15307 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target')
-rw-r--r--target/linux/generic-2.6/files/drivers/net/phy/swconfig.c47
-rw-r--r--target/linux/generic-2.6/files/include/linux/switch.h2
2 files changed, 42 insertions, 7 deletions
diff --git a/target/linux/generic-2.6/files/drivers/net/phy/swconfig.c b/target/linux/generic-2.6/files/drivers/net/phy/swconfig.c
index 83da094ee..8bae66708 100644
--- a/target/linux/generic-2.6/files/drivers/net/phy/swconfig.c
+++ b/target/linux/generic-2.6/files/drivers/net/phy/swconfig.c
@@ -75,6 +75,7 @@ swconfig_get_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr,
static int
swconfig_set_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
+ struct switch_port *ports = val->value.ports;
int i;
if (val->port_vlan >= dev->vlans)
@@ -84,15 +85,42 @@ swconfig_set_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr,
if (val->len > dev->ports)
return -EINVAL;
+ if (!dev->set_vlan_ports)
+ return -EOPNOTSUPP;
+
for (i = 0; i < val->len; i++) {
- if (val->value.ports[i].id >= dev->ports)
+ if (ports[i].id >= dev->ports)
return -EINVAL;
+
+ if (dev->set_port_pvid && !(ports[i].flags & SWITCH_PORT_FLAG_TAGGED))
+ dev->set_port_pvid(dev, ports[i].id, val->port_vlan);
}
- if (!dev->set_vlan_ports)
+ return dev->set_vlan_ports(dev, val);
+}
+
+static int
+swconfig_set_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
+{
+ if (val->port_vlan >= dev->ports)
+ return -EINVAL;
+
+ if (!dev->set_port_pvid)
return -EOPNOTSUPP;
- return dev->set_vlan_ports(dev, val);
+ return dev->set_port_pvid(dev, val->port_vlan, val->value.i);
+}
+
+static int
+swconfig_get_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
+{
+ if (val->port_vlan >= dev->ports)
+ return -EINVAL;
+
+ if (!dev->get_port_pvid)
+ return -EOPNOTSUPP;
+
+ return dev->get_port_pvid(dev, val->port_vlan, &val->value.i);
}
static int
@@ -115,7 +143,7 @@ enum vlan_defaults {
};
enum port_defaults {
- PORT_LINK,
+ PORT_PVID,
};
static struct switch_attr default_global[] = {
@@ -128,10 +156,12 @@ static struct switch_attr default_global[] = {
};
static struct switch_attr default_port[] = {
- [PORT_LINK] = {
+ [PORT_PVID] = {
.type = SWITCH_TYPE_INT,
- .name = "link",
- .description = "Current link speed",
+ .name = "pvid",
+ .description = "Primary VLAN ID",
+ .set = swconfig_set_pvid,
+ .get = swconfig_get_pvid,
}
};
@@ -155,6 +185,9 @@ static void swconfig_defaults_init(struct switch_dev *dev)
if (dev->get_vlan_ports || dev->set_vlan_ports)
set_bit(VLAN_PORTS, &dev->def_vlan);
+ if (dev->get_port_pvid || dev->set_port_pvid)
+ set_bit(PORT_PVID, &dev->def_port);
+
/* always present, can be no-op */
set_bit(GLOBAL_APPLY, &dev->def_global);
}
diff --git a/target/linux/generic-2.6/files/include/linux/switch.h b/target/linux/generic-2.6/files/include/linux/switch.h
index ef6b8f2ea..75c7dcfa9 100644
--- a/target/linux/generic-2.6/files/include/linux/switch.h
+++ b/target/linux/generic-2.6/files/include/linux/switch.h
@@ -129,6 +129,8 @@ struct switch_dev {
int (*get_vlan_ports)(struct switch_dev *dev, struct switch_val *val);
int (*set_vlan_ports)(struct switch_dev *dev, struct switch_val *val);
+ int (*get_port_pvid)(struct switch_dev *dev, int port, int *val);
+ int (*set_port_pvid)(struct switch_dev *dev, int port, int val);
int (*apply_config)(struct switch_dev *dev);
};