aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2009-04-20 21:26:39 +0000
committerFelix Fietkau <nbd@openwrt.org>2009-04-20 21:26:39 +0000
commitf6f55bae7d4eeb753be2949f718a49fd39f85519 (patch)
tree84e13ac48c8ad669bb3df72df58d6df16eda2821 /target/linux
parent4320a28228222c76b0c67fb8ef470d9886195990 (diff)
downloadupstream-f6f55bae7d4eeb753be2949f718a49fd39f85519.tar.gz
upstream-f6f55bae7d4eeb753be2949f718a49fd39f85519.tar.bz2
upstream-f6f55bae7d4eeb753be2949f718a49fd39f85519.zip
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)
SVN-Revision: 15307
Diffstat (limited to 'target/linux')
-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 83da094ee1..8bae667081 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 ef6b8f2ea4..75c7dcfa91 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);
};