X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/e2d43315df4bbee83c965b9b594db404276d76b5..cc2563940f4d989ecc90ef8a3b1851f6070a7fca:/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 6dbed0405..659445a64 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8366rb.c +++ b/target/linux/generic/files/drivers/net/phy/rtl8366rb.c @@ -163,11 +163,6 @@ #define RTL8366RB_VLAN_MEMBER_MASK 0xff #define RTL8366RB_VLAN_FID_MASK 0x7 -struct rtl8366rb { - struct device *parent; - struct rtl8366_smi smi; -}; - static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = { { 0, 0, 4, "IfInOctets" }, { 0, 4, 4, "EtherStatsOctets" }, @@ -218,17 +213,6 @@ static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = { return err; \ } while (0) -static inline struct rtl8366rb *smi_to_rtl8366rb(struct rtl8366_smi *smi) -{ - return container_of(smi, struct rtl8366rb, smi); -} - -static inline struct rtl8366rb *sw_to_rtl8366rb(struct switch_dev *sw) -{ - struct rtl8366_smi *smi = sw_to_rtl8366_smi(sw); - return smi_to_rtl8366rb(smi); -} - static int rtl8366rb_reset_chip(struct rtl8366_smi *smi) { int timeout = 10; @@ -568,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, @@ -713,47 +705,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) @@ -808,101 +759,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); @@ -971,7 +827,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", @@ -989,16 +845,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), @@ -1012,32 +863,35 @@ 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, }; -static int rtl8366rb_switch_init(struct rtl8366rb *rtl) +static int rtl8366rb_switch_init(struct rtl8366_smi *smi) { - struct switch_dev *dev = &rtl->smi.sw_dev; + struct switch_dev *dev = &smi->sw_dev; int err; - memcpy(dev, &rtl8366_switch_dev, sizeof(struct switch_dev)); - dev->priv = rtl; - dev->devname = dev_name(rtl->parent); + 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); if (err) - dev_err(rtl->parent, "switch registration failed\n"); + dev_err(smi->parent, "switch registration failed\n"); return err; } -static void rtl8366rb_switch_cleanup(struct rtl8366rb *rtl) +static void rtl8366rb_switch_cleanup(struct rtl8366_smi *smi) { - unregister_switch(&rtl->smi.sw_dev); + unregister_switch(&smi->sw_dev); } static int rtl8366rb_mii_read(struct mii_bus *bus, int addr, int reg) @@ -1072,9 +926,8 @@ static int rtl8366rb_mii_bus_match(struct mii_bus *bus) bus->write == rtl8366rb_mii_write); } -static int rtl8366rb_setup(struct rtl8366rb *rtl) +static int rtl8366rb_setup(struct rtl8366_smi *smi) { - struct rtl8366_smi *smi = &rtl->smi; int ret; ret = rtl8366rb_reset_chip(smi); @@ -1120,6 +973,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, @@ -1130,13 +985,13 @@ 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) { static int rtl8366_smi_version_printed; struct rtl8366rb_platform_data *pdata; - struct rtl8366rb *rtl; struct rtl8366_smi *smi; int err; @@ -1151,17 +1006,12 @@ static int __init rtl8366rb_probe(struct platform_device *pdev) goto err_out; } - rtl = kzalloc(sizeof(*rtl), GFP_KERNEL); - if (!rtl) { - dev_err(&pdev->dev, "no memory for private data\n"); + smi = rtl8366_smi_alloc(&pdev->dev); + if (!smi) { err = -ENOMEM; goto err_out; } - rtl->parent = &pdev->dev; - - smi = &rtl->smi; - smi->parent = &pdev->dev; smi->gpio_sda = pdata->gpio_sda; smi->gpio_sck = pdata->gpio_sck; smi->ops = &rtl8366rb_smi_ops; @@ -1173,15 +1023,11 @@ static int __init rtl8366rb_probe(struct platform_device *pdev) err = rtl8366_smi_init(smi); if (err) - goto err_free_rtl; - - platform_set_drvdata(pdev, rtl); + goto err_free_smi; - err = rtl8366rb_setup(rtl); - if (err) - goto err_clear_drvdata; + platform_set_drvdata(pdev, smi); - err = rtl8366rb_switch_init(rtl); + err = rtl8366rb_switch_init(smi); if (err) goto err_clear_drvdata; @@ -1190,8 +1036,8 @@ static int __init rtl8366rb_probe(struct platform_device *pdev) err_clear_drvdata: platform_set_drvdata(pdev, NULL); rtl8366_smi_cleanup(smi); - err_free_rtl: - kfree(rtl); + err_free_smi: + kfree(smi); err_out: return err; } @@ -1224,13 +1070,13 @@ static struct phy_driver rtl8366rb_phy_driver = { static int __devexit rtl8366rb_remove(struct platform_device *pdev) { - struct rtl8366rb *rtl = platform_get_drvdata(pdev); + struct rtl8366_smi *smi = platform_get_drvdata(pdev); - if (rtl) { - rtl8366rb_switch_cleanup(rtl); + if (smi) { + rtl8366rb_switch_cleanup(smi); platform_set_drvdata(pdev, NULL); - rtl8366_smi_cleanup(&rtl->smi); - kfree(rtl); + rtl8366_smi_cleanup(smi); + kfree(smi); } return 0;