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