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

Reply via email to