diff options
Diffstat (limited to 'target/linux/generic/files')
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/ar8216.c | 66 | ||||
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/ip17xx.c | 84 | ||||
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/rtl8306.c | 128 | ||||
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/rtl8366rb.c | 14 | ||||
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/rtl8366s.c | 14 | ||||
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/swconfig.c | 54 | ||||
-rw-r--r-- | target/linux/generic/files/include/linux/switch.h | 53 |
7 files changed, 224 insertions, 189 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index 4ae61da233..98bfc7eb31 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -52,7 +52,6 @@ struct ar8216_priv { u8 vlan_tagged; u16 pvid[AR8216_NUM_PORTS]; }; -static struct switch_dev athdev; #define to_ar8216(_dev) container_of(_dev, struct ar8216_priv, dev) @@ -631,11 +630,34 @@ ar8216_reset_switch(struct switch_dev *dev) return ar8216_hw_apply(dev); } + +static const struct switch_dev_ops ar8216_ops = { + .attr_global = { + .attr = ar8216_globals, + .n_attr = ARRAY_SIZE(ar8216_globals), + }, + .attr_port = { + .attr = ar8216_port, + .n_attr = ARRAY_SIZE(ar8216_port), + }, + .attr_vlan = { + .attr = ar8216_vlan, + .n_attr = ARRAY_SIZE(ar8216_vlan), + }, + .get_port_pvid = ar8216_get_pvid, + .set_port_pvid = ar8216_set_pvid, + .get_vlan_ports = ar8216_get_ports, + .set_vlan_ports = ar8216_set_ports, + .apply_config = ar8216_hw_apply, + .reset_switch = ar8216_reset_switch, +}; + static int ar8216_config_init(struct phy_device *pdev) { struct ar8216_priv *priv; struct net_device *dev = pdev->attached_dev; + struct switch_dev *swdev; int ret; priv = kzalloc(sizeof(struct ar8216_priv), GFP_KERNEL); @@ -667,14 +689,22 @@ ar8216_config_init(struct phy_device *pdev) mutex_init(&priv->reg_mutex); priv->read = ar8216_mii_read; priv->write = ar8216_mii_write; - memcpy(&priv->dev, &athdev, sizeof(struct switch_dev)); + pdev->priv = priv; + swdev = &priv->dev; + swdev->cpu_port = AR8216_PORT_CPU; + swdev->ops = &ar8216_ops; + if (priv->chip == AR8316) { - priv->dev.name = "Atheros AR8316"; - priv->dev.vlans = AR8X16_MAX_VLANS; + swdev->name = "Atheros AR8316"; + swdev->vlans = AR8X16_MAX_VLANS; /* port 5 connected to the other mac, therefore unusable */ - priv->dev.ports = (AR8216_NUM_PORTS - 1); + swdev->ports = (AR8216_NUM_PORTS - 1); + } else { + swdev->name = "Atheros AR8216"; + swdev->vlans = AR8216_NUM_VLANS; + swdev->ports = AR8216_NUM_PORTS; } if ((ret = register_switch(&priv->dev, pdev->attached_dev)) < 0) { @@ -782,32 +812,6 @@ ar8216_remove(struct phy_device *pdev) kfree(priv); } -/* template */ -static struct switch_dev athdev = { - .name = "Atheros AR8216", - .cpu_port = AR8216_PORT_CPU, - .ports = AR8216_NUM_PORTS, - .vlans = AR8216_NUM_VLANS, - .attr_global = { - .attr = ar8216_globals, - .n_attr = ARRAY_SIZE(ar8216_globals), - }, - .attr_port = { - .attr = ar8216_port, - .n_attr = ARRAY_SIZE(ar8216_port), - }, - .attr_vlan = { - .attr = ar8216_vlan, - .n_attr = ARRAY_SIZE(ar8216_vlan), - }, - .get_port_pvid = ar8216_get_pvid, - .set_port_pvid = ar8216_set_pvid, - .get_vlan_ports = ar8216_get_ports, - .set_vlan_ports = ar8216_set_ports, - .apply_config = ar8216_hw_apply, - .reset_switch = ar8216_reset_switch, -}; - static struct phy_driver ar8216_driver = { .phy_id = 0x004d0000, .name = "Atheros AR8216/AR8316", diff --git a/target/linux/generic/files/drivers/net/phy/ip17xx.c b/target/linux/generic/files/drivers/net/phy/ip17xx.c index 864168ffd2..646a842654 100644 --- a/target/linux/generic/files/drivers/net/phy/ip17xx.c +++ b/target/linux/generic/files/drivers/net/phy/ip17xx.c @@ -323,6 +323,7 @@ struct ip17xx_state { char buf[80]; }; +#define get_state(_dev) container_of((_dev), struct ip17xx_state, dev) static int ip_phy_read(struct ip17xx_state *state, int port, int reg) { @@ -734,7 +735,7 @@ static int ip175d_reset(struct ip17xx_state *state) static int ip17xx_get_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); val->value.i = state->vlan_enabled; return 0; @@ -756,7 +757,7 @@ static void ip17xx_reset_vlan_config(struct ip17xx_state *state) static int ip17xx_set_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int enable; enable = val->value.i; @@ -774,7 +775,7 @@ static int ip17xx_set_enable_vlan(struct switch_dev *dev, const struct switch_at static int ip17xx_get_ports(struct switch_dev *dev, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int b; int ind; unsigned int ports; @@ -802,7 +803,7 @@ static int ip17xx_get_ports(struct switch_dev *dev, struct switch_val *val) static int ip17xx_set_ports(struct switch_dev *dev, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int i; if (val->port_vlan >= dev->vlans || val->port_vlan < 0) @@ -826,7 +827,7 @@ static int ip17xx_set_ports(struct switch_dev *dev, struct switch_val *val) static int ip17xx_apply(struct switch_dev *dev) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); if (REG_SUPP(state->regs->MII_REGISTER_EN)) { int val = getPhy(state, state->regs->MII_REGISTER_EN); @@ -841,7 +842,7 @@ static int ip17xx_apply(struct switch_dev *dev) static int ip17xx_reset(struct switch_dev *dev) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int i, err; if (REG_SUPP(state->regs->RESET_REG)) { @@ -874,7 +875,7 @@ static int ip17xx_reset(struct switch_dev *dev) static int ip17xx_get_tagged(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); if (state->add_tag & (1<<val->port_vlan)) { if (state->remove_tag & (1<<val->port_vlan)) @@ -892,7 +893,7 @@ static int ip17xx_get_tagged(struct switch_dev *dev, const struct switch_attr *a static int ip17xx_set_tagged(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); state->add_tag &= ~(1<<val->port_vlan); state->remove_tag &= ~(1<<val->port_vlan); @@ -908,7 +909,7 @@ static int ip17xx_set_tagged(struct switch_dev *dev, const struct switch_attr *a /** Get the current phy address */ static int ip17xx_get_phy(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); val->value.i = state->proc_mii.p; return 0; @@ -917,7 +918,7 @@ static int ip17xx_get_phy(struct switch_dev *dev, const struct switch_attr *attr /** Set a new phy address for low level access to registers */ static int ip17xx_set_phy(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int new_reg = val->value.i; if (new_reg < 0 || new_reg > 31) @@ -930,7 +931,7 @@ static int ip17xx_set_phy(struct switch_dev *dev, const struct switch_attr *attr /** Get the current register number */ static int ip17xx_get_reg(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); val->value.i = state->proc_mii.m; return 0; @@ -939,7 +940,7 @@ static int ip17xx_get_reg(struct switch_dev *dev, const struct switch_attr *attr /** Set a new register address for low level access to registers */ static int ip17xx_set_reg(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int new_reg = val->value.i; if (new_reg < 0 || new_reg > 31) @@ -952,7 +953,7 @@ static int ip17xx_set_reg(struct switch_dev *dev, const struct switch_attr *attr /** Get the register content of state->proc_mii */ static int ip17xx_get_val(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int retval = -EINVAL; if (REG_SUPP(state->proc_mii)) retval = getPhy(state, state->proc_mii); @@ -968,7 +969,7 @@ static int ip17xx_get_val(struct switch_dev *dev, const struct switch_attr *attr /** Write a value to the register defined by phy/reg above */ static int ip17xx_set_val(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int myval, err = -EINVAL; myval = val->value.i; @@ -980,14 +981,14 @@ static int ip17xx_set_val(struct switch_dev *dev, const struct switch_attr *attr static int ip17xx_read_name(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); val->value.s = state->regs->NAME; // Just a const pointer, won't be freed by swconfig. return 0; } static int ip17xx_get_tag(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int vlan = val->port_vlan; if (vlan < 0 || vlan >= MAX_VLANS) @@ -999,7 +1000,7 @@ static int ip17xx_get_tag(struct switch_dev *dev, const struct switch_attr *attr static int ip17xx_set_tag(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int vlan = val->port_vlan; int tag = val->value.i; @@ -1015,7 +1016,7 @@ static int ip17xx_set_tag(struct switch_dev *dev, const struct switch_attr *attr static int ip17xx_set_port_speed(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int nr = val->port_vlan; int ctrl; int autoneg; @@ -1052,7 +1053,7 @@ static int ip17xx_set_port_speed(struct switch_dev *dev, const struct switch_att static int ip17xx_get_port_speed(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int nr = val->port_vlan; int speed, status; @@ -1079,7 +1080,7 @@ static int ip17xx_get_port_speed(struct switch_dev *dev, const struct switch_att static int ip17xx_get_port_status(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); int ctrl, speed, status; int nr = val->port_vlan; int len; @@ -1123,7 +1124,7 @@ static int ip17xx_get_port_status(struct switch_dev *dev, const struct switch_at static int ip17xx_get_pvid(struct switch_dev *dev, int port, int *val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); *val = state->ports[port].pvid; return 0; @@ -1131,7 +1132,7 @@ static int ip17xx_get_pvid(struct switch_dev *dev, int port, int *val) static int ip17xx_set_pvid(struct switch_dev *dev, int port, int val) { - struct ip17xx_state *state = dev->priv; + struct ip17xx_state *state = get_state(dev); if (val < 0 || val >= MAX_VLANS) return -EINVAL; @@ -1243,6 +1244,28 @@ static const struct switch_attr ip17xx_port[] = { }, }; +static const struct switch_dev_ops ip17xx_ops = { + .attr_global = { + .attr = ip17xx_global, + .n_attr = ARRAY_SIZE(ip17xx_global), + }, + .attr_port = { + .attr = ip17xx_port, + .n_attr = ARRAY_SIZE(ip17xx_port), + }, + .attr_vlan = { + .attr = ip17xx_vlan, + .n_attr = ARRAY_SIZE(ip17xx_vlan), + }, + + .get_port_pvid = ip17xx_get_pvid, + .set_port_pvid = ip17xx_set_pvid, + .get_vlan_ports = ip17xx_get_ports, + .set_vlan_ports = ip17xx_set_ports, + .apply_config = ip17xx_apply, + .reset_switch = ip17xx_reset, +}; + static int ip17xx_probe(struct phy_device *pdev) { struct ip17xx_state *state; @@ -1258,21 +1281,7 @@ static int ip17xx_probe(struct phy_device *pdev) return -ENOMEM; dev = &state->dev; - dev->attr_global.attr = ip17xx_global; - dev->attr_global.n_attr = ARRAY_SIZE(ip17xx_global); - dev->attr_port.attr = ip17xx_port; - dev->attr_port.n_attr = ARRAY_SIZE(ip17xx_port); - dev->attr_vlan.attr = ip17xx_vlan; - dev->attr_vlan.n_attr = ARRAY_SIZE(ip17xx_vlan); - - dev->get_port_pvid = ip17xx_get_pvid; - dev->set_port_pvid = ip17xx_set_pvid; - dev->get_vlan_ports = ip17xx_get_ports; - dev->set_vlan_ports = ip17xx_set_ports; - dev->apply_config = ip17xx_apply; - dev->reset_switch = ip17xx_reset; - - dev->priv = state; + pdev->priv = state; state->mii_bus = pdev->bus; @@ -1284,6 +1293,7 @@ static int ip17xx_probe(struct phy_device *pdev) dev->cpu_port = state->regs->CPU_PORT; dev->ports = state->regs->NUM_PORTS; dev->name = state->regs->NAME; + dev->ops = &ip17xx_ops; pr_info("IP17xx: Found %s at %s\n", dev->name, dev_name(&pdev->dev)); return 0; diff --git a/target/linux/generic/files/drivers/net/phy/rtl8306.c b/target/linux/generic/files/drivers/net/phy/rtl8306.c index 901b5b2f83..87c661a77a 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8306.c +++ b/target/linux/generic/files/drivers/net/phy/rtl8306.c @@ -250,11 +250,6 @@ static const struct rtl_reg rtl_regs[] = { }; -/* IFXMIPS compat stuff - remove after PHY layer migration */ -static struct switch_dev rtldev; -/* END IFXMIPS compat stuff */ - - static inline void rtl_set_page(struct rtl_priv *priv, unsigned int page) { @@ -706,64 +701,6 @@ rtl_set_ports(struct switch_dev *dev, struct switch_val *val) return 0; } -static int -rtl8306_config_init(struct phy_device *pdev) -{ - struct net_device *netdev = pdev->attached_dev; - struct rtl_priv *priv = pdev->priv; - struct switch_dev *dev = &priv->dev; - struct switch_val val; - unsigned int chipid, chipver, chiptype; - int err; - - /* Only init the switch for the primary PHY */ - if (pdev->addr != 0) - return 0; - - val.value.i = 1; - memcpy(&priv->dev, &rtldev, sizeof(struct switch_dev)); - priv->do_cpu = 0; - priv->page = -1; - priv->bus = pdev->bus; - - dev->priv = priv; - - chipid = rtl_get(dev, RTL_REG_CHIPID); - chipver = rtl_get(dev, RTL_REG_CHIPVER); - chiptype = rtl_get(dev, RTL_REG_CHIPTYPE); - switch(chiptype) { - case 0: - case 2: - strncpy(priv->hwname, RTL_NAME_S, sizeof(priv->hwname)); - priv->type = RTL_TYPE_S; - break; - case 1: - strncpy(priv->hwname, RTL_NAME_SD, sizeof(priv->hwname)); - priv->type = RTL_TYPE_SD; - break; - case 3: - strncpy(priv->hwname, RTL_NAME_SDM, sizeof(priv->hwname)); - priv->type = RTL_TYPE_SDM; - break; - default: - strncpy(priv->hwname, RTL_NAME_UNKNOWN, sizeof(priv->hwname)); - break; - } - - dev->name = priv->hwname; - rtl_hw_init(dev); - - printk(KERN_INFO "Registering %s switch with Chip ID: 0x%04x, version: 0x%04x\n", priv->hwname, chipid, chipver); - - err = register_switch(dev, netdev); - if (err < 0) { - kfree(priv); - return err; - } - - return 0; -} - static struct switch_attr rtl_globals[] = { { .type = SWITCH_TYPE_INT, @@ -897,11 +834,7 @@ static struct switch_attr rtl_vlan[] = { }, }; -/* template */ -static struct switch_dev rtldev = { - .cpu_port = RTL8306_PORT_CPU, - .ports = RTL8306_NUM_PORTS, - .vlans = RTL8306_NUM_VLANS, +static const struct switch_dev_ops rtl8306_ops = { .attr_global = { .attr = rtl_globals, .n_attr = ARRAY_SIZE(rtl_globals), @@ -920,6 +853,65 @@ static struct switch_dev rtldev = { .apply_config = rtl_hw_apply, }; +static int +rtl8306_config_init(struct phy_device *pdev) +{ + struct net_device *netdev = pdev->attached_dev; + struct rtl_priv *priv = pdev->priv; + struct switch_dev *dev = &priv->dev; + struct switch_val val; + unsigned int chipid, chipver, chiptype; + int err; + + /* Only init the switch for the primary PHY */ + if (pdev->addr != 0) + return 0; + + val.value.i = 1; + priv->dev.cpu_port = RTL8306_PORT_CPU; + priv->dev.ports = RTL8306_NUM_PORTS; + priv->dev.vlans = RTL8306_NUM_VLANS; + priv->dev.ops = &rtl8306_ops; + priv->do_cpu = 0; + priv->page = -1; + priv->bus = pdev->bus; + + chipid = rtl_get(dev, RTL_REG_CHIPID); + chipver = rtl_get(dev, RTL_REG_CHIPVER); + chiptype = rtl_get(dev, RTL_REG_CHIPTYPE); + switch(chiptype) { + case 0: + case 2: + strncpy(priv->hwname, RTL_NAME_S, sizeof(priv->hwname)); + priv->type = RTL_TYPE_S; + break; + case 1: + strncpy(priv->hwname, RTL_NAME_SD, sizeof(priv->hwname)); + priv->type = RTL_TYPE_SD; + break; + case 3: + strncpy(priv->hwname, RTL_NAME_SDM, sizeof(priv->hwname)); + priv->type = RTL_TYPE_SDM; + break; + default: + strncpy(priv->hwname, RTL_NAME_UNKNOWN, sizeof(priv->hwname)); + break; + } + + dev->name = priv->hwname; + rtl_hw_init(dev); + + printk(KERN_INFO "Registering %s switch with Chip ID: 0x%04x, version: 0x%04x\n", priv->hwname, chipid, chipver); + + err = register_switch(dev, netdev); + if (err < 0) { + kfree(priv); + return err; + } + + return 0; +} + static int rtl8306_fixup(struct phy_device *pdev) diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366rb.c b/target/linux/generic/files/drivers/net/phy/rtl8366rb.c index 79533263bb..659445a64c 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8366rb.c +++ b/target/linux/generic/files/drivers/net/phy/rtl8366rb.c @@ -849,12 +849,7 @@ static struct switch_attr rtl8366rb_vlan[] = { }, }; -/* template */ -static struct switch_dev rtl8366_switch_dev = { - .name = "RTL8366S", - .cpu_port = RTL8366RB_PORT_NUM_CPU, - .ports = RTL8366RB_NUM_PORTS, - .vlans = RTL8366RB_NUM_VLANS, +static const struct switch_dev_ops rtl8366_ops = { .attr_global = { .attr = rtl8366rb_globals, .n_attr = ARRAY_SIZE(rtl8366rb_globals), @@ -880,8 +875,11 @@ static int rtl8366rb_switch_init(struct rtl8366_smi *smi) struct switch_dev *dev = &smi->sw_dev; int err; - memcpy(dev, &rtl8366_switch_dev, sizeof(struct switch_dev)); - dev->priv = smi; + dev->name = "RTL8366RB"; + dev->cpu_port = RTL8366RB_PORT_NUM_CPU; + dev->ports = RTL8366RB_NUM_PORTS; + dev->vlans = RTL8366RB_NUM_VLANS; + dev->ops = &rtl8366_ops; dev->devname = dev_name(smi->parent); err = register_switch(dev, NULL); diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366s.c b/target/linux/generic/files/drivers/net/phy/rtl8366s.c index 17050451fc..7aab8341cf 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8366s.c +++ b/target/linux/generic/files/drivers/net/phy/rtl8366s.c @@ -876,12 +876,7 @@ static struct switch_attr rtl8366s_vlan[] = { }, }; -/* template */ -static struct switch_dev rtl8366_switch_dev = { - .name = "RTL8366S", - .cpu_port = RTL8366S_PORT_NUM_CPU, - .ports = RTL8366S_NUM_PORTS, - .vlans = RTL8366S_NUM_VLANS, +static const struct switch_dev_ops rtl8366_ops = { .attr_global = { .attr = rtl8366s_globals, .n_attr = ARRAY_SIZE(rtl8366s_globals), @@ -907,8 +902,11 @@ static int rtl8366s_switch_init(struct rtl8366_smi *smi) struct switch_dev *dev = &smi->sw_dev; int err; - memcpy(dev, &rtl8366_switch_dev, sizeof(struct switch_dev)); - dev->priv = smi; + dev->name = "RTL8366S"; + dev->cpu_port = RTL8366S_PORT_NUM_CPU; + dev->ports = RTL8366S_NUM_PORTS; + dev->vlans = RTL8366S_NUM_VLANS; + dev->ops = &rtl8366_ops; dev->devname = dev_name(smi->parent); err = register_switch(dev, NULL); diff --git a/target/linux/generic/files/drivers/net/phy/swconfig.c b/target/linux/generic/files/drivers/net/phy/swconfig.c index dea8e78b79..799fc29d17 100644 --- a/target/linux/generic/files/drivers/net/phy/swconfig.c +++ b/target/linux/generic/files/drivers/net/phy/swconfig.c @@ -65,10 +65,10 @@ swconfig_get_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, if (val->port_vlan >= dev->vlans) return -EINVAL; - if (!dev->get_vlan_ports) + if (!dev->ops->get_vlan_ports) return -EOPNOTSUPP; - ret = dev->get_vlan_ports(dev, val); + ret = dev->ops->get_vlan_ports(dev, val); return ret; } @@ -76,6 +76,7 @@ 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; + const struct switch_dev_ops *ops = dev->ops; int i; if (val->port_vlan >= dev->vlans) @@ -85,18 +86,19 @@ 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) + if (!ops->set_vlan_ports) return -EOPNOTSUPP; for (i = 0; i < val->len; i++) { if (ports[i].id >= dev->ports) return -EINVAL; - if (dev->set_port_pvid && !(ports[i].flags & (1 << SWITCH_PORT_FLAG_TAGGED))) - dev->set_port_pvid(dev, ports[i].id, val->port_vlan); + if (ops->set_port_pvid && + !(ports[i].flags & (1 << SWITCH_PORT_FLAG_TAGGED))) + ops->set_port_pvid(dev, ports[i].id, val->port_vlan); } - return dev->set_vlan_ports(dev, val); + return ops->set_vlan_ports(dev, val); } static int @@ -105,10 +107,10 @@ swconfig_set_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct if (val->port_vlan >= dev->ports) return -EINVAL; - if (!dev->set_port_pvid) + if (!dev->ops->set_port_pvid) return -EOPNOTSUPP; - return dev->set_port_pvid(dev, val->port_vlan, val->value.i); + return dev->ops->set_port_pvid(dev, val->port_vlan, val->value.i); } static int @@ -117,30 +119,30 @@ swconfig_get_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct if (val->port_vlan >= dev->ports) return -EINVAL; - if (!dev->get_port_pvid) + if (!dev->ops->get_port_pvid) return -EOPNOTSUPP; - return dev->get_port_pvid(dev, val->port_vlan, &val->value.i); + return dev->ops->get_port_pvid(dev, val->port_vlan, &val->value.i); } static int swconfig_apply_config(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { /* don't complain if not supported by the switch driver */ - if (!dev->apply_config) + if (!dev->ops->apply_config) return 0; - return dev->apply_config(dev); + return dev->ops->apply_config(dev); } static int swconfig_reset_switch(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { /* don't complain if not supported by the switch driver */ - if (!dev->reset_switch) + if (!dev->ops->reset_switch) return 0; - return dev->reset_switch(dev); + return dev->ops->reset_switch(dev); } enum global_defaults { @@ -194,14 +196,16 @@ static struct switch_attr default_vlan[] = { static void swconfig_defaults_init(struct switch_dev *dev) { + const struct switch_dev_ops *ops = dev->ops; + dev->def_global = 0; dev->def_vlan = 0; dev->def_port = 0; - if (dev->get_vlan_ports || dev->set_vlan_ports) + if (ops->get_vlan_ports || ops->set_vlan_ports) set_bit(VLAN_PORTS, &dev->def_vlan); - if (dev->get_port_pvid || dev->set_port_pvid) + if (ops->get_port_pvid || ops->set_port_pvid) set_bit(PORT_PVID, &dev->def_port); /* always present, can be no-op */ @@ -335,7 +339,7 @@ swconfig_send_multipart(struct swconfig_callback *cb, void *arg) if (cb->close(cb, arg) < 0) goto error; } - err = genlmsg_unicast(cb->msg, info->snd_pid); + err = genlmsg_reply(cb->msg, info); cb->msg = NULL; if (err < 0) goto error; @@ -371,19 +375,19 @@ swconfig_list_attrs(struct sk_buff *skb, struct genl_info *info) switch(hdr->cmd) { case SWITCH_CMD_LIST_GLOBAL: - alist = &dev->attr_global; + alist = &dev->ops->attr_global; def_list = default_global; def_active = &dev->def_global; n_def = ARRAY_SIZE(default_global); break; case SWITCH_CMD_LIST_VLAN: - alist = &dev->attr_vlan; + alist = &dev->ops->attr_vlan; def_list = default_vlan; def_active = &dev->def_vlan; n_def = ARRAY_SIZE(default_vlan); break; case SWITCH_CMD_LIST_PORT: - alist = &dev->attr_port; + alist = &dev->ops->attr_port; def_list = default_port; def_active = &dev->def_port; n_def = ARRAY_SIZE(default_port); @@ -419,7 +423,7 @@ swconfig_list_attrs(struct sk_buff *skb, struct genl_info *info) if (!cb.msg) return 0; - return genlmsg_unicast(cb.msg, info->snd_pid); + return genlmsg_reply(cb.msg, info); error: if (cb.msg) @@ -449,14 +453,14 @@ swconfig_lookup_attr(struct switch_dev *dev, struct genl_info *info, switch(hdr->cmd) { case SWITCH_CMD_SET_GLOBAL: case SWITCH_CMD_GET_GLOBAL: - alist = &dev->attr_global; + alist = &dev->ops->attr_global; def_list = default_global; def_active = &dev->def_global; n_def = ARRAY_SIZE(default_global); break; case SWITCH_CMD_SET_VLAN: case SWITCH_CMD_GET_VLAN: - alist = &dev->attr_vlan; + alist = &dev->ops->attr_vlan; def_list = default_vlan; def_active = &dev->def_vlan; n_def = ARRAY_SIZE(default_vlan); @@ -468,7 +472,7 @@ swconfig_lookup_attr(struct switch_dev *dev, struct genl_info *info, break; case SWITCH_CMD_SET_PORT: case SWITCH_CMD_GET_PORT: - alist = &dev->attr_port; + alist = &dev->ops->attr_port; def_list = default_port; def_active = &dev->def_port; n_def = ARRAY_SIZE(default_port); @@ -732,7 +736,7 @@ swconfig_get_attr(struct sk_buff *skb, struct genl_info *info) goto nla_put_failure; swconfig_put_dev(dev); - return genlmsg_unicast(msg, info->snd_pid); + return genlmsg_reply(msg, info); nla_put_failure: if (msg) diff --git a/target/linux/generic/files/include/linux/switch.h b/target/linux/generic/files/include/linux/switch.h index 25aedb83b0..ef2dc3ad9f 100644 --- a/target/linux/generic/files/include/linux/switch.h +++ b/target/linux/generic/files/include/linux/switch.h @@ -102,16 +102,50 @@ struct switch_attrlist; int register_switch(struct switch_dev *dev, struct net_device *netdev); void unregister_switch(struct switch_dev *dev); +/** + * struct switch_attrlist - attribute list + * + * @n_attr: number of attributes + * @attr: pointer to the attributes array + */ struct switch_attrlist { - /* filled in by the driver */ int n_attr; const struct switch_attr *attr; }; +/** + * struct switch_dev_ops - switch driver operations + * + * @attr_global: global switch attribute list + * @attr_port: port attribute list + * @attr_vlan: vlan attribute list + * + * Callbacks: + * + * @get_vlan_ports: read the port list of a VLAN + * @set_vlan_ports: set the port list of a VLAN + * + * @get_port_pvid: get the primary VLAN ID of a port + * @set_port_pvid: set the primary VLAN ID of a port + * + * @apply_config: apply all changed settings to the switch + * @reset_switch: resetting the switch + */ +struct switch_dev_ops { + struct switch_attrlist attr_global, attr_port, attr_vlan; + + 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); + int (*reset_switch)(struct switch_dev *dev); +}; struct switch_dev { - int id; - void *priv; + const struct switch_dev_ops *ops; const char *name; /* NB: either devname or netdev must be set */ @@ -121,19 +155,14 @@ struct switch_dev { int ports; int vlans; int cpu_port; - struct switch_attrlist attr_global, attr_port, attr_vlan; - spinlock_t lock; - struct switch_port *portbuf; + /* the following fields are internal for swconfig */ + int id; struct list_head dev_list; unsigned long def_global, def_port, def_vlan; - 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); - int (*reset_switch)(struct switch_dev *dev); + spinlock_t lock; + struct switch_port *portbuf; }; struct switch_port { |