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