X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/a8fb744861bfea47b0097db0b1a8fb0e59edf950..1fc390136389ce02142df9be56861cd1df34f3c2:/target/linux/generic/files/drivers/net/phy/rtl8366rb.c diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366rb.c b/target/linux/generic/files/drivers/net/phy/rtl8366rb.c index 2156078f8..99d49c5b2 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8366rb.c +++ b/target/linux/generic/files/drivers/net/phy/rtl8366rb.c @@ -248,11 +248,11 @@ static int rtl8366rb_hw_init(struct rtl8366_smi *smi) /* enable all ports */ REG_WR(smi, RTL8366RB_PECR, 0); - /* disable learning for all ports */ - REG_WR(smi, RTL8366RB_SSCR0, RTL8366RB_PORT_ALL); + /* enable learning for all ports */ + REG_WR(smi, RTL8366RB_SSCR0, 0); - /* disable auto ageing for all ports */ - REG_WR(smi, RTL8366RB_SSCR1, RTL8366RB_PORT_ALL); + /* enable auto ageing for all ports */ + REG_WR(smi, RTL8366RB_SSCR1, 0); /* * discard VLAN tagged packets if the port is not a member of @@ -552,6 +552,14 @@ static int rtl8366rb_set_mc_index(struct rtl8366_smi *smi, int port, int index) RTL8366RB_PORT_VLAN_CTRL_SHIFT(port)); } +static int rtl8366rb_is_vlan_valid(struct rtl8366_smi *smi, unsigned vlan) +{ + if (vlan == 0 || vlan >= RTL8366RB_NUM_VLANS) + return 0; + + return 1; +} + static int rtl8366rb_vlan_set_vlan(struct rtl8366_smi *smi, int enable) { return rtl8366_smi_rmwr(smi, RTL8366RB_SGCR, RTL8366RB_SGCR_EN_VLAN, @@ -641,6 +649,41 @@ static int rtl8366rb_sw_set_vlan_enable(struct switch_dev *dev, return rtl8366rb_vlan_set_4ktable(smi, val->value.i); } +static int rtl8366rb_sw_get_learning_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); + u32 data; + + rtl8366_smi_read_reg(smi, RTL8366RB_SSCR0, &data); + val->value.i = !data; + + return 0; +} + + +static int rtl8366rb_sw_set_learning_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); + u32 portmask = 0; + int err = 0; + + if (!val->value.i) + portmask = RTL8366RB_PORT_ALL; + + /* set learning for all ports */ + REG_WR(smi, RTL8366RB_SSCR0, portmask); + + /* set auto ageing for all ports */ + REG_WR(smi, RTL8366RB_SSCR1, portmask); + + return 0; +} + + static const char *rtl8366rb_speed_str(unsigned speed) { switch (speed) { @@ -697,47 +740,6 @@ static int rtl8366rb_sw_get_port_link(struct switch_dev *dev, return 0; } -static int rtl8366rb_sw_get_vlan_info(struct switch_dev *dev, - const struct switch_attr *attr, - struct switch_val *val) -{ - int i; - u32 len = 0; - struct rtl8366_vlan_4k vlan4k; - struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); - char *buf = smi->buf; - int err; - - if (val->port_vlan == 0 || val->port_vlan >= RTL8366RB_NUM_VLANS) - return -EINVAL; - - memset(buf, '\0', sizeof(smi->buf)); - - err = rtl8366rb_get_vlan_4k(smi, val->port_vlan, &vlan4k); - if (err) - return err; - - len += snprintf(buf + len, sizeof(smi->buf) - len, - "VLAN %d: Ports: '", vlan4k.vid); - - for (i = 0; i < RTL8366RB_NUM_PORTS; i++) { - if (!(vlan4k.member & (1 << i))) - continue; - - len += snprintf(buf + len, sizeof(smi->buf) - len, "%d%s", i, - (vlan4k.untag & (1 << i)) ? "" : "t"); - } - - len += snprintf(buf + len, sizeof(smi->buf) - len, - "', members=%04x, untag=%04x, fid=%u", - vlan4k.member, vlan4k.untag, vlan4k.fid); - - val->value.s = buf; - val->len = len; - - return 0; -} - static int rtl8366rb_sw_set_port_led(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) @@ -792,101 +794,6 @@ static int rtl8366rb_sw_reset_port_mibs(struct switch_dev *dev, RTL8366RB_MIB_CTRL_PORT_RESET(val->port_vlan)); } -static int rtl8366rb_sw_get_port_mib(struct switch_dev *dev, - const struct switch_attr *attr, - struct switch_val *val) -{ - struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); - int i, len = 0; - unsigned long long counter = 0; - char *buf = smi->buf; - - if (val->port_vlan >= RTL8366RB_NUM_PORTS) - return -EINVAL; - - len += snprintf(buf + len, sizeof(smi->buf) - len, - "Port %d MIB counters\n", - val->port_vlan); - - for (i = 0; i < ARRAY_SIZE(rtl8366rb_mib_counters); ++i) { - len += snprintf(buf + len, sizeof(smi->buf) - len, - "%-36s: ", rtl8366rb_mib_counters[i].name); - if (!rtl8366rb_get_mib_counter(smi, i, val->port_vlan, &counter)) - len += snprintf(buf + len, sizeof(smi->buf) - len, - "%llu\n", counter); - else - len += snprintf(buf + len, sizeof(smi->buf) - len, - "%s\n", "error"); - } - - val->value.s = buf; - val->len = len; - return 0; -} - -static int rtl8366rb_sw_get_vlan_ports(struct switch_dev *dev, - struct switch_val *val) -{ - struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); - struct switch_port *port; - struct rtl8366_vlan_4k vlan4k; - int i; - - if (val->port_vlan == 0 || val->port_vlan >= RTL8366RB_NUM_VLANS) - return -EINVAL; - - rtl8366rb_get_vlan_4k(smi, val->port_vlan, &vlan4k); - - port = &val->value.ports[0]; - val->len = 0; - for (i = 0; i < RTL8366RB_NUM_PORTS; i++) { - if (!(vlan4k.member & BIT(i))) - continue; - - port->id = i; - port->flags = (vlan4k.untag & BIT(i)) ? - 0 : BIT(SWITCH_PORT_FLAG_TAGGED); - val->len++; - port++; - } - return 0; -} - -static int rtl8366rb_sw_set_vlan_ports(struct switch_dev *dev, - struct switch_val *val) -{ - struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); - struct switch_port *port; - u32 member = 0; - u32 untag = 0; - int i; - - if (val->port_vlan == 0 || val->port_vlan >= RTL8366RB_NUM_VLANS) - return -EINVAL; - - port = &val->value.ports[0]; - for (i = 0; i < val->len; i++, port++) { - member |= BIT(port->id); - - if (!(port->flags & BIT(SWITCH_PORT_FLAG_TAGGED))) - untag |= BIT(port->id); - } - - 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 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 rtl8366_set_pvid(smi, port, val); -} - static int rtl8366rb_sw_reset_switch(struct switch_dev *dev) { struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); @@ -905,6 +812,13 @@ static int rtl8366rb_sw_reset_switch(struct switch_dev *dev) static struct switch_attr rtl8366rb_globals[] = { { + .type = SWITCH_TYPE_INT, + .name = "enable_learning", + .description = "Enable learning, enable aging", + .set = rtl8366rb_sw_set_learning_enable, + .get = rtl8366rb_sw_get_learning_enable, + .max = 1 + }, { .type = SWITCH_TYPE_INT, .name = "enable_vlan", .description = "Enable VLAN mode", @@ -955,7 +869,7 @@ static struct switch_attr rtl8366rb_port[] = { .description = "Get MIB counters for port", .max = 33, .set = NULL, - .get = rtl8366rb_sw_get_port_mib, + .get = rtl8366_sw_get_port_mib, }, { .type = SWITCH_TYPE_INT, .name = "led", @@ -973,16 +887,11 @@ static struct switch_attr rtl8366rb_vlan[] = { .description = "Get vlan information", .max = 1, .set = NULL, - .get = rtl8366rb_sw_get_vlan_info, + .get = rtl8366_sw_get_vlan_info, }, }; -/* 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), @@ -996,10 +905,10 @@ static struct switch_dev rtl8366_switch_dev = { .n_attr = ARRAY_SIZE(rtl8366rb_vlan), }, - .get_vlan_ports = rtl8366rb_sw_get_vlan_ports, - .set_vlan_ports = rtl8366rb_sw_set_vlan_ports, - .get_port_pvid = rtl8366rb_sw_get_port_pvid, - .set_port_pvid = rtl8366rb_sw_set_port_pvid, + .get_vlan_ports = rtl8366_sw_get_vlan_ports, + .set_vlan_ports = rtl8366_sw_set_vlan_ports, + .get_port_pvid = rtl8366_sw_get_port_pvid, + .set_port_pvid = rtl8366_sw_set_port_pvid, .reset_switch = rtl8366rb_sw_reset_switch, }; @@ -1008,8 +917,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); @@ -1103,6 +1015,8 @@ static int rtl8366rb_detect(struct rtl8366_smi *smi) static struct rtl8366_smi_ops rtl8366rb_smi_ops = { .detect = rtl8366rb_detect, + .setup = rtl8366rb_setup, + .mii_read = rtl8366rb_mii_read, .mii_write = rtl8366rb_mii_write, @@ -1113,6 +1027,7 @@ static struct rtl8366_smi_ops rtl8366rb_smi_ops = { .get_mc_index = rtl8366rb_get_mc_index, .set_mc_index = rtl8366rb_set_mc_index, .get_mib_counter = rtl8366rb_get_mib_counter, + .is_vlan_valid = rtl8366rb_is_vlan_valid, }; static int __init rtl8366rb_probe(struct platform_device *pdev) @@ -1133,14 +1048,12 @@ static int __init rtl8366rb_probe(struct platform_device *pdev) goto err_out; } - smi = kzalloc(sizeof(*smi), GFP_KERNEL); + smi = rtl8366_smi_alloc(&pdev->dev); if (!smi) { - dev_err(&pdev->dev, "no memory for private data\n"); err = -ENOMEM; goto err_out; } - smi->parent = &pdev->dev; smi->gpio_sda = pdata->gpio_sda; smi->gpio_sck = pdata->gpio_sck; smi->ops = &rtl8366rb_smi_ops; @@ -1156,10 +1069,6 @@ static int __init rtl8366rb_probe(struct platform_device *pdev) platform_set_drvdata(pdev, smi); - err = rtl8366rb_setup(smi); - if (err) - goto err_clear_drvdata; - err = rtl8366rb_switch_init(smi); if (err) goto err_clear_drvdata;