I mean that storm filtering registers are different and seems that the logic should be too, but the original driver is confusing also that's why I ask if you've tested this.
Regards, Roman On 28 September 2010 22:00, Roman Yeryomin <leroi.li...@gmail.com> wrote: > Did you test this? Seems that you confused rtl8366rb with rtl8368s. > > Regards, > Roman > > On 28 September 2010 19:44, Luca Niccoli <lultimou...@gmail.com> wrote: >> This second version of the patch is rebased on the work done by Roman >> Yeryomin and applied in r23126. >> It corrects a minor miscalculation in the port rate code and cleans the >> code a bit, plus it adds support for jumbo frames, port priority and storm >> control. >> >> Signed-off-by: Luca Niccoli <lultimou...@gmail.com> >> >> >> Index: target/linux/generic/files/drivers/net/phy/rtl8366rb.c >> =================================================================== >> --- target/linux/generic/files/drivers/net/phy/rtl8366rb.c (revisione >> 23144) >> +++ target/linux/generic/files/drivers/net/phy/rtl8366rb.c (copia >> locale) >> @@ -1,9 +1,10 @@ >> /* >> - * Platform driver for the Realtek RTL8366S ethernet switch >> + * Platform driver for the Realtek RTL8366RB ethernet switch >> * >> * Copyright (C) 2009-2010 Gabor Juhos <juh...@openwrt.org> >> * Copyright (C) 2010 Antti Seppälä <a.sepp...@gmail.com> >> * Copyright (C) 2010 Roman Yeryomin <ro...@advem.lv> >> + * Copyright (C) 2010 Luca Niccoli <lultimou...@gmai.com> >> * >> * This program is free software; you can redistribute it and/or modify it >> * under the terms of the GNU General Public License version 2 as published >> @@ -181,8 +182,8 @@ >> #define RTL8366RB_EB_PREIFG_OFFSET 9 >> #define RTL8366RB_EB_PREIFG_MASK (1 << RTL8366RB_EB_PREIFG_OFFSET) >> >> -#define RTL8366RB_BDTH_SW_MAX 1048512 >> -#define RTL8366RB_BDTH_BASE 64 >> +#define RTL8366RB_BDTH_SW_MAX 1048576 >> +#define RTL8366RB_BDTH_UNIT 64 >> #define RTL8366RB_BDTH_REG_DEFAULT 16383 >> >> /* QOS */ >> @@ -192,6 +193,28 @@ >> #define RTL8366RB_QOS_DEFAULT_PREIFG 1 >> >> >> +/* Port-based priority register */ >> +#define RTL8366RB_PORT_PRIORITY_BASE 0x020C >> +#define RTL8366RB_PORT_PRIORITY_BITS 3 >> +#define RTL8366RB_PORT_PRIORITY_MASK 0x7 >> + >> + >> +/* Storm Control Register >> + * Filter for: broadcast, multicast, unknown address, unknown multicast >> + */ >> +#define RTL8366RB_STORM_BC_REG 0x03E0 >> +#define RTL8366RB_STORM_MC_REG 0x03E1 >> +#define RTL8366RB_STORM_UA_REG 0x03E2 >> +#define RTL8366RB_STORM_UM_REG 0x03E3 >> +#define RTL8366RB_STORM_PORT_MASK(pnum) (1 << pnum) >> +#define RTL8366RB_STORM_RATE_BASE 0x03E4 >> +#define RTL8366RB_STORM_RATE_REG(pnum) (RTL8366RB_STORM_RATE_BASE + pnum) >> +#define RTL8366RB_STORM_RATE_MASK 0x3FFF >> +#define RTL8366RB_STORM_RATE_MAX 1048576 >> +#define RTL8366RB_STORM_RATE_UNIT 64 >> +#define RTL8366RB_STORM_RATE_DEFAULT 0 >> + >> + >> static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = { >> { 0, 0, 4, "IfInOctets" }, >> { 0, 4, 4, "EtherStatsOctets" }, >> @@ -679,7 +702,49 @@ >> return 0; >> } >> >> +static int rtl8366rb_sw_get_max_length(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_SGCR, &data); >> + >> + val->value.i = ((data & (RTL8366RB_SGCR_MAX_LENGTH_MASK)) >> 4); >> + >> + return 0; >> +} >> + >> +static int rtl8366rb_sw_set_max_length(struct switch_dev *dev, >> + const struct switch_attr *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + char length_code; >> + >> + switch (val->value.i) { >> + case 0: >> + length_code = RTL8366RB_SGCR_MAX_LENGTH_1522; >> + break; >> + case 1: >> + length_code = RTL8366RB_SGCR_MAX_LENGTH_1536; >> + break; >> + case 2: >> + length_code = RTL8366RB_SGCR_MAX_LENGTH_1552; >> + break; >> + case 3: >> + length_code = RTL8366RB_SGCR_MAX_LENGTH_9216; >> + break; >> + default: >> + return -EINVAL; >> + } >> + return rtl8366_smi_rmwr(smi, RTL8366RB_SGCR, >> + RTL8366RB_SGCR_MAX_LENGTH_MASK, >> + length_code); >> +} >> + >> + >> static const char *rtl8366rb_speed_str(unsigned speed) >> { >> switch (speed) { >> @@ -777,6 +842,61 @@ >> return 0; >> } >> >> +static int rtl8366rb_sw_set_port_pri(struct switch_dev *dev, >> + const struct switch_attr *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + u32 mask; >> + u32 reg; >> + u32 data; >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS || val->value.i > >> attr->max) >> + return -EINVAL; >> + >> + if (val->port_vlan < 5) { >> + mask = RTL8366RB_PORT_PRIORITY_MASK << >> + (RTL8366RB_PORT_PRIORITY_BITS * >> val->port_vlan); >> + reg = RTL8366RB_PORT_PRIORITY_BASE; >> + data = val->value.i << >> + (RTL8366RB_PORT_PRIORITY_BITS * >> val->port_vlan); >> + } else { >> + mask = RTL8366RB_PORT_PRIORITY_MASK; >> + reg = RTL8366RB_PORT_PRIORITY_BASE + 1; >> + data = val->value.i; >> + } >> + >> + return rtl8366_smi_rmwr(smi, reg, mask, data); >> +} >> + >> +static int rtl8366rb_sw_get_port_pri(struct switch_dev *dev, >> + const struct switch_attr *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + u32 reg; >> + u32 shift; >> + u32 data = 0; >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS) >> + return -EINVAL; >> + >> + if (val->port_vlan < 5) { >> + reg = RTL8366RB_PORT_PRIORITY_BASE; >> + shift = RTL8366RB_PORT_PRIORITY_BITS * val->port_vlan; >> + >> + } else { >> + reg = RTL8366RB_PORT_PRIORITY_BASE + 1; >> + shift = 0; >> + } >> + >> + rtl8366_smi_read_reg(smi, reg, &data); >> + >> + val->value.i = ((data >> shift) & RTL8366RB_PORT_PRIORITY_MASK); >> + >> + return 0; >> +} >> + >> static int rtl8366rb_sw_set_port_disable(struct switch_dev *dev, >> const struct switch_attr *attr, >> struct switch_val *val) >> @@ -821,12 +941,11 @@ >> { >> struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> >> - if (val->port_vlan >= RTL8366RB_NUM_PORTS) >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS || val->value.i > >> attr->max) >> return -EINVAL; >> >> - if (val->value.i > 0 && val->value.i < RTL8366RB_BDTH_SW_MAX) >> - val->value.i = (val->value.i - 1) / RTL8366RB_BDTH_BASE; >> - else >> + val->value.i = (val->value.i - 1) / RTL8366RB_BDTH_UNIT; >> + if (val->value.i < 0) >> val->value.i = RTL8366RB_BDTH_REG_DEFAULT; >> >> return rtl8366_smi_rmwr(smi, RTL8366RB_IB_REG(val->port_vlan), >> @@ -848,10 +967,9 @@ >> >> rtl8366_smi_read_reg(smi, RTL8366RB_IB_REG(val->port_vlan), &data); >> data &= RTL8366RB_IB_BDTH_MASK; >> - if (data < RTL8366RB_IB_BDTH_MASK) >> - data += 1; >> + data += 1; >> >> - val->value.i = (int)data * RTL8366RB_BDTH_BASE; >> + val->value.i = (int)data * RTL8366RB_BDTH_UNIT; >> >> return 0; >> } >> @@ -862,16 +980,15 @@ >> { >> struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> >> - if (val->port_vlan >= RTL8366RB_NUM_PORTS) >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS || val->value.i > >> attr->max) >> return -EINVAL; >> >> rtl8366_smi_rmwr(smi, RTL8366RB_EB_PREIFG_REG, >> RTL8366RB_EB_PREIFG_MASK, >> (RTL8366RB_QOS_DEFAULT_PREIFG << RTL8366RB_EB_PREIFG_OFFSET)); >> >> - if (val->value.i > 0 && val->value.i < RTL8366RB_BDTH_SW_MAX) >> - val->value.i = (val->value.i - 1) / RTL8366RB_BDTH_BASE; >> - else >> + val->value.i = (val->value.i - 1) / RTL8366RB_BDTH_UNIT; >> + if (val->value.i < 0) >> val->value.i = RTL8366RB_BDTH_REG_DEFAULT; >> >> return rtl8366_smi_rmwr(smi, RTL8366RB_EB_REG(val->port_vlan), >> @@ -891,14 +1008,175 @@ >> >> rtl8366_smi_read_reg(smi, RTL8366RB_EB_REG(val->port_vlan), &data); >> data &= RTL8366RB_EB_BDTH_MASK; >> - if (data < RTL8366RB_EB_BDTH_MASK) >> - data += 1; >> + data += 1; >> >> - val->value.i = (int)data * RTL8366RB_BDTH_BASE; >> + val->value.i = (int)data * RTL8366RB_BDTH_UNIT; >> >> return 0; >> } >> >> +static int rtl8366rb_sw_set_port_bc_stfilter(struct switch_dev *dev, >> + const struct switch_attr *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS || val->value.i > >> attr->max) >> + return -EINVAL; >> + >> + return rtl8366_smi_rmwr(smi, RTL8366RB_STORM_BC_REG, >> + RTL8366RB_STORM_PORT_MASK(val->port_vlan), >> + (val->value.i << val->port_vlan)); >> +} >> + >> +static int rtl8366rb_sw_get_port_bc_stfilter(struct switch_dev *dev, >> + const struct switch_attr *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + u32 data; >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS) >> + return -EINVAL; >> + >> + rtl8366_smi_read_reg(smi, RTL8366RB_STORM_BC_REG, &data); >> + val->value.i= (data & RTL8366RB_STORM_PORT_MASK(val->port_vlan)) >> + >> val->port_vlan; >> + >> + return 0; >> +} >> + >> +static int rtl8366rb_sw_set_port_mc_stfilter(struct switch_dev *dev, >> + const struct switch_attr *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS || val->value.i > >> attr->max) >> + return -EINVAL; >> + >> + return rtl8366_smi_rmwr(smi, RTL8366RB_STORM_MC_REG, >> + RTL8366RB_STORM_PORT_MASK(val->port_vlan), >> + (val->value.i << val->port_vlan)); >> +} >> + >> +static int rtl8366rb_sw_get_port_mc_stfilter(struct switch_dev *dev, >> + const struct switch_attr *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + u32 data; >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS) >> + return -EINVAL; >> + >> + rtl8366_smi_read_reg(smi, RTL8366RB_STORM_MC_REG, &data); >> + val->value.i= (data & RTL8366RB_STORM_PORT_MASK(val->port_vlan)) >> + >> val->port_vlan; >> + >> + return 0; >> +} >> + >> +static int rtl8366rb_sw_set_port_ua_stfilter(struct switch_dev *dev, >> + const struct switch_attr *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS || val->value.i > >> attr->max) >> + return -EINVAL; >> + >> + return rtl8366_smi_rmwr(smi, RTL8366RB_STORM_UA_REG, >> + RTL8366RB_STORM_PORT_MASK(val->port_vlan), >> + (val->value.i << val->port_vlan)); >> +} >> + >> +static int rtl8366rb_sw_get_port_ua_stfilter(struct switch_dev *dev, >> + const struct switch_attr *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + u32 data; >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS) >> + return -EINVAL; >> + >> + rtl8366_smi_read_reg(smi, RTL8366RB_STORM_UA_REG, &data); >> + val->value.i= (data & RTL8366RB_STORM_PORT_MASK(val->port_vlan)) >> + >> val->port_vlan; >> + >> + return 0; >> +} >> + >> +static int rtl8366rb_sw_set_port_um_stfilter(struct switch_dev *dev, >> + const struct switch_attr *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS || val->value.i > >> attr->max) >> + return -EINVAL; >> + >> + return rtl8366_smi_rmwr(smi, RTL8366RB_STORM_UM_REG, >> + RTL8366RB_STORM_PORT_MASK(val->port_vlan), >> + (val->value.i << val->port_vlan)); >> +} >> + >> +static int rtl8366rb_sw_get_port_um_stfilter(struct switch_dev *dev, >> + const struct switch_attr *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + u32 data; >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS) >> + return -EINVAL; >> + >> + rtl8366_smi_read_reg(smi, RTL8366RB_STORM_UM_REG, &data); >> + val->value.i= (data & RTL8366RB_STORM_PORT_MASK(val->port_vlan)) >> + >> val->port_vlan; >> + >> + return 0; >> +} >> + >> +static int rtl8366rb_sw_set_port_stfilter_rate(struct switch_dev *dev, >> + const struct switch_attr >> *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS || val->value.i > >> attr->max) >> + return -EINVAL; >> + >> + val->value.i = (val->value.i - 1) / RTL8366RB_STORM_RATE_UNIT; >> + if (val->value.i < 0) >> + val->value.i = RTL8366RB_STORM_RATE_DEFAULT; >> + >> + return rtl8366_smi_rmwr(smi, >> RTL8366RB_STORM_RATE_REG(val->port_vlan), >> + RTL8366RB_STORM_RATE_MASK, >> + val->value.i); >> +} >> + >> +static int rtl8366rb_sw_get_port_stfilter_rate(struct switch_dev *dev, >> + const struct switch_attr >> *attr, >> + struct switch_val *val) >> +{ >> + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); >> + u32 data; >> + >> + if (val->port_vlan >= RTL8366RB_NUM_PORTS) >> + return -EINVAL; >> + >> + rtl8366_smi_read_reg(smi, RTL8366RB_STORM_RATE_REG(val->port_vlan), >> + &data); >> + >> + data &= RTL8366RB_STORM_RATE_MASK; >> + data += 1; >> + >> + val->value.i = data * RTL8366RB_STORM_RATE_UNIT; >> + >> + return 0; >> +} >> static int rtl8366rb_sw_set_qos_enable(struct switch_dev *dev, >> const struct switch_attr *attr, >> struct switch_val *val) >> @@ -1003,6 +1281,14 @@ >> .set = rtl8366rb_sw_set_qos_enable, >> .get = rtl8366rb_sw_get_qos_enable, >> .max = 1 >> + }, { >> + .type = SWITCH_TYPE_INT, >> + .name = "max_length", >> + .description = "Get/Set the maximum length of valid packets" >> + " (0 = 1522, 1 = 1536, 2 = 1552, 3 = 9216)", >> + .set = rtl8366rb_sw_set_max_length, >> + .get = rtl8366rb_sw_get_max_length, >> + .max = 3, >> }, >> }; >> >> @@ -1054,7 +1340,50 @@ >> .max = RTL8366RB_BDTH_SW_MAX, >> .set = rtl8366rb_sw_set_port_rate_out, >> .get = rtl8366rb_sw_get_port_rate_out, >> + }, { >> + .type = SWITCH_TYPE_INT, >> + .name = "priority", >> + .description = "Get/Set port priority (0-7)", >> + .set = rtl8366rb_sw_set_port_pri, >> + .get = rtl8366rb_sw_get_port_pri, >> + .max = 7 >> + }, { >> + .type = SWITCH_TYPE_INT, >> + .name = "bc_storm_filter", >> + .description = "Get/Set broadcast storm filtering (enabled >> or disabled)", >> + .max = 1, >> + .set = rtl8366rb_sw_set_port_bc_stfilter, >> + .get = rtl8366rb_sw_get_port_bc_stfilter, >> + }, { >> + .type = SWITCH_TYPE_INT, >> + .name = "mc_storm_filter", >> + .description = "Get/Set multicast storm filtering (enabled >> or disabled)", >> + .max = 1, >> + .set = rtl8366rb_sw_set_port_mc_stfilter, >> + .get = rtl8366rb_sw_get_port_mc_stfilter, >> + }, { >> + .type = SWITCH_TYPE_INT, >> + .name = "ua_storm_filter", >> + .description = "Get/Set unknown address storm filtering >> (enabled or disabled)", >> + .max = 1, >> + .set = rtl8366rb_sw_set_port_ua_stfilter, >> + .get = rtl8366rb_sw_get_port_ua_stfilter, >> + }, { >> + .type = SWITCH_TYPE_INT, >> + .name = "um_storm_filter", >> + .description = "Get/Set unknown multicast storm filtering >> (enabled or disabled)", >> + .max = 1, >> + .set = rtl8366rb_sw_set_port_um_stfilter, >> + .get = rtl8366rb_sw_get_port_um_stfilter, >> + }, { >> + .type = SWITCH_TYPE_INT, >> + .name = "storm_filter_rate", >> + .description = "Get/Set storm filtering rate in kbps", >> + .max = RTL8366RB_STORM_RATE_MAX, >> + .set = rtl8366rb_sw_set_port_stfilter_rate, >> + .get = rtl8366rb_sw_get_port_stfilter_rate, >> }, >> + >> }; >> >> static struct switch_attr rtl8366rb_vlan[] = { >> @@ -1347,5 +1676,6 @@ >> MODULE_AUTHOR("Gabor Juhos <juh...@openwrt.org>"); >> MODULE_AUTHOR("Antti Seppälä <a.sepp...@gmail.com>"); >> MODULE_AUTHOR("Roman Yeryomin <ro...@advem.lv>"); >> +MODULE_AUTHOR("Luca Niccoli <lultimou...@gmail.com>"); >> MODULE_LICENSE("GPL v2"); >> MODULE_ALIAS("platform:" RTL8366RB_DRIVER_NAME); >> _______________________________________________ >> openwrt-devel mailing list >> openwrt-devel@lists.openwrt.org >> https://lists.openwrt.org/mailman/listinfo/openwrt-devel >> > _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel