2010.08.26. 1:17 keltezéssel, Roman Yeryomin írta:
> Using this patch it's possible to define port egress/ingress bandwidth
> limit with 64 kbps step (this also requires enable_qos set to 1 which
> seems to be 1 already by default after switch reset), enable or
> disable any port and set vlan to different fid (0-7). Implementation
> of fid support maybe a bit ugly and could be done together with
> set_vlan_ports (which sets fid to 0 by default so after every `set
> ports ...` one need to `set fid ...` also) but this way it works fine
> too.
> 
> Signed-off-by: Roman Yeryomin <[email protected]>
> --
> 
> Index: target/linux/generic/files/drivers/net/phy/rtl8366rb.c
> ===================================================================
> --- a/target/linux/generic/files/drivers/net/phy/rtl8366rb.c  (revision 22745)
> +++ b/target/linux/generic/files/drivers/net/phy/rtl8366rb.c  (working copy)
> @@ -3,6 +3,7 @@
>   *
>   * Copyright (C) 2009-2010 Gabor Juhos <[email protected]>
>   * Copyright (C) 2010 Antti Seppälä <[email protected]>
> + * Copyright (C) 2010 Roman Yeryomin <[email protected]>
>   *
>   * 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
> @@ -163,6 +164,27 @@
>  #define RTL8366RB_VLAN_MEMBER_MASK   0xff
>  #define RTL8366RB_VLAN_FID_MASK              0x7
>  
> +
> +/* Port ingress bandwidth control */
> +#define RTL8366RB_IB_BASE            0x0200
> +#define RTL8366RB_IB_REG(pnum)               (RTL8366RB_IB_BASE+pnum)
> +#define RTL8366RB_IB_BDTH_MASK               0x3fff
> +#define RTL8366RB_IB_PREIFG_OFFSET   14
> +#define RTL8366RB_IB_PREIFG_MASK     (1 << RTL8366RB_IB_PREIFG_OFFSET)
> +
> +/* Port egress bandwidth control */
> +#define RTL8366RB_EB_BASE            0x02d1
> +#define RTL8366RB_EB_REG(pnum)               (RTL8366RB_EB_BASE+pnum)

Please add spaces around the '+' in these macros.

> +#define RTL8366RB_EB_BDTH_MASK               0x3fff
> +#define RTL8366RB_EB_PREIFG_REG      0x02f8
> +#define RTL8366RB_EB_PREIFG_OFFSET   9
> +#define RTL8366RB_EB_PREIFG_MASK     (1 << RTL8366RB_EB_PREIFG_OFFSET)
> +
> +/* QOS */
> +/* Include/Exclude Preamble and IFG(20Bytes). 0:Exclude, 1:Include. */
> +#define RTL8366RB_QOS_DEFAULT_PREIFG 1
> +
> +
>  static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = {
>       { 0,  0, 4, "IfInOctets"                                },
>       { 0,  4, 4, "EtherStatsOctets"                          },
> @@ -455,6 +477,86 @@
>       return err;
>  }
>  
> +static int rtl8366rb_sw_get_vlan_fid(struct switch_dev *dev,
> +                                 const struct switch_attr *attr,
> +                                 struct switch_val *val)
> +{
> +     struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
> +     u32 data;
> +     int err;
> +
> +     if (val->port_vlan >= RTL8366RB_NUM_VIDS)
> +             return -EINVAL;
> +
> +     /* write VID */
> +     err = rtl8366_smi_write_reg(smi, RTL8366RB_VLAN_TABLE_WRITE_BASE,
> +                                 val->port_vlan & RTL8366RB_VLAN_VID_MASK);
> +     if (err)
> +             return err;
> +
> +     /* write table access control word */
> +     err = rtl8366_smi_write_reg(smi, RTL8366RB_TABLE_ACCESS_CTRL_REG,
> +                                 RTL8366RB_TABLE_VLAN_READ_CTRL);
> +     if (err)
> +             return err;
> +
> +     err = rtl8366_smi_read_reg(smi, RTL8366RB_VLAN_TABLE_READ_BASE + 2, 
> &data);
> +     if (err)
> +             return err;
> +
> +     val->value.i = data & RTL8366RB_VLAN_FID_MASK;
> +
> +     return 0;

You don't have to duplicate the VLAN access code, you can use the get_vlan_4k()
function of smi->ops instead. Additionally, if you would use that, then this
function would be generic, and should go into rtl8366_smi.c.

> +}
> +
> +static int rtl8366rb_sw_set_vlan_fid(struct switch_dev *dev,
> +                                 const struct switch_attr *attr,
> +                                 struct switch_val *val)
> +{
> +     struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
> +     u32 data;
> +     int err;
> +
> +     if (val->port_vlan >= RTL8366RB_NUM_VIDS ||
> +             val->value.i > RTL8366RB_FIDMAX)
> +             return -EINVAL;
> +
> +     /* write VID */
> +     err = rtl8366_smi_write_reg(smi, RTL8366RB_VLAN_TABLE_WRITE_BASE,
> +                                 val->port_vlan & RTL8366RB_VLAN_VID_MASK);
> +     if (err)
> +             return err;
> +
> +     /* write table access control word */
> +     err = rtl8366_smi_write_reg(smi, RTL8366RB_TABLE_ACCESS_CTRL_REG,
> +                                 RTL8366RB_TABLE_VLAN_READ_CTRL);
> +     if (err)
> +             return err;
> +
> +     err = rtl8366_smi_read_reg(smi, RTL8366RB_VLAN_TABLE_READ_BASE + 1, 
> &data);
> +     if (err)
> +             return err;
> 
> +     err = rtl8366_smi_write_reg(smi, RTL8366RB_VLAN_TABLE_WRITE_BASE + 1, 
> data);
> +     if (err)
> +             return err;
> +
> +     data = val->port_vlan & RTL8366RB_VLAN_VID_MASK;
> +     err = rtl8366_smi_write_reg(smi, RTL8366RB_VLAN_TABLE_WRITE_BASE, data);
> +     if (err)
> +             return err;
> +     data = val->value.i & RTL8366RB_VLAN_FID_MASK;
> +     err = rtl8366_smi_write_reg(smi, RTL8366RB_VLAN_TABLE_WRITE_BASE + 2, 
> data);
> +     if (err)
> +             return err;
> +
> +     /* write table access control word */
> +     err = rtl8366_smi_write_reg(smi, RTL8366RB_TABLE_ACCESS_CTRL_REG,
> +                                 RTL8366RB_TABLE_VLAN_WRITE_CTRL);
> +
> +     return err;

This function should be generic as well. Please move it to rtl8366_smi.c, get
the current VLAN configuration via 'smi->ops->get_vlan_4k', then update it with
'rtl8366_set_vlan'.

> +}
> +
>  static int rtl8366rb_get_vlan_mc(struct rtl8366_smi *smi, u32 index,
>                                struct rtl8366_vlan_mc *vlanmc)
>  {
> @@ -748,6 +850,163 @@
>       return 0;
>  }
>  
> +static int rtl8366rb_sw_set_port_disable(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_PECR, &data);
> +     if (val->value.i)
> +             data = data | (1<<val->port_vlan);
> +     else
> +             data = data & ~(1<<val->port_vlan);

Please add spaces around the '<<' operators everywhere in the patch.

> +
> +     return rtl8366_smi_write_reg(smi, RTL8366RB_PECR, data);

You should use 'rtl8366_smi_rmwr()' her.

> +}
> +
> +static int rtl8366rb_sw_get_port_disable(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_PECR, &data);
> +     if (data & (1<<val->port_vlan))
> +             val->value.i = 1;
> +     else
> +             val->value.i = 0;
> +
> +     return 0;
> +}
> +
> +static int rtl8366rb_sw_set_port_rate_in(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;
> +
> +     if (val->value.i > 0 && val->value.i < 1048512)
> +             val->value.i = (val->value.i - 1) / 64 ;
> +     else
> +             val->value.i = 16383;
> +     
> +     rtl8366_smi_read_reg(smi, RTL8366RB_IB_REG(val->port_vlan), &data);
> +
> +     return rtl8366_smi_write_reg(smi, RTL8366RB_IB_REG(val->port_vlan), 
> +                           (data & ~(RTL8366RB_IB_BDTH_MASK | 
> RTL8366RB_IB_PREIFG_MASK)) | val->value.i | (RTL8366RB_QOS_DEFAULT_PREIFG << 
> RTL8366RB_IB_PREIFG_OFFSET));

You should use 'rtl8366_smi_rmwr()' here too. And please don't use lines longer
than 80 characters.

> +
> +}
> +
> +static int rtl8366rb_sw_get_port_rate_in(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_IB_REG(val->port_vlan), &data);
> +     data &= RTL8366RB_IB_BDTH_MASK;
> +     if (data < RTL8366RB_IB_BDTH_MASK)
> +             data += 1;
> +     
> +     val->value.i = (int)data * 64;
> +
> +     return 0;
> +}
> +
> +static int rtl8366rb_sw_set_port_rate_out(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_EB_PREIFG_REG, &data);
> +     rtl8366_smi_write_reg(smi, RTL8366RB_EB_PREIFG_REG, 
> +                           (data & ~(RTL8366RB_EB_PREIFG_MASK)) | 
> (RTL8366RB_QOS_DEFAULT_PREIFG << RTL8366RB_EB_PREIFG_OFFSET) );

Same as above.

> +     
> +     if (val->value.i > 0 && val->value.i < 1048512)
> +             val->value.i = (val->value.i - 1) / 64 ;
> +     else
> +             val->value.i = 16383;
> +     
> +     rtl8366_smi_read_reg(smi, RTL8366RB_EB_REG(val->port_vlan), &data);
> +     return rtl8366_smi_write_reg(smi, RTL8366RB_EB_REG(val->port_vlan), 
> +                           (data & ~(RTL8366RB_EB_BDTH_MASK)) | val->value.i 
> );

Use 'rtl8366_smi_rmwr()' here as well.

> +
> +}
> +
> +static int rtl8366rb_sw_get_port_rate_out(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_EB_REG(val->port_vlan), &data);
> +     data &= RTL8366RB_EB_BDTH_MASK;
> +     if (data < RTL8366RB_EB_BDTH_MASK)
> +             data += 1;
> +     
> +     val->value.i = (int)data * 64;
> +
> +     return 0;
> +}
> +
> +static int rtl8366rb_sw_set_qos_enable(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);
> +     if (val->value.i)
> +             data = data | (1<<15);
> +     else
> +             data = data & ~(1<<15);
> +
> +     return rtl8366_smi_write_reg(smi, RTL8366RB_SGCR, data);

Ditto.

> +}
> +
> +static int rtl8366rb_sw_get_qos_enable(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);
> +     if (data & (1<<15))
> +             val->value.i = 1;
> +     else
> +             val->value.i = 0;
> +
> +     return 0;
> +}
> +
>  static int rtl8366rb_sw_reset_port_mibs(struct switch_dev *dev,
>                                      const struct switch_attr *attr,
>                                      struct switch_val *val)
> @@ -814,6 +1073,13 @@
>               .set = rtl8366rb_sw_set_blinkrate,
>               .get = rtl8366rb_sw_get_blinkrate,
>               .max = 5
> +     }, {
> +             .type = SWITCH_TYPE_INT,
> +             .name = "enable_qos",
> +             .description = "Enable QOS",
> +             .set = rtl8366rb_sw_set_qos_enable,
> +             .get = rtl8366rb_sw_get_qos_enable,
> +             .max = 1
>       },
>  };
>  
> @@ -844,6 +1110,27 @@
>               .max = 15,
>               .set = rtl8366rb_sw_set_port_led,
>               .get = rtl8366rb_sw_get_port_led,
> +     }, {
> +             .type = SWITCH_TYPE_INT,
> +             .name = "disable",
> +             .description = "Get/Set port state (enabled or disabled)",
> +             .max = 1,
> +             .set = rtl8366rb_sw_set_port_disable,
> +             .get = rtl8366rb_sw_get_port_disable,
> +     }, {
> +             .type = SWITCH_TYPE_INT,
> +             .name = "rate_in",
> +             .description = "Get/Set port ingress (incoming) bandwidth limit 
> in kbps",
> +             .max = 1048512,
> +             .set = rtl8366rb_sw_set_port_rate_in,
> +             .get = rtl8366rb_sw_get_port_rate_in,
> +     }, {
> +             .type = SWITCH_TYPE_INT,
> +             .name = "rate_out",
> +             .description = "Get/Set port egress (outgoing) bandwidth limit 
> in kbps",
> +             .max = 1048512,
> +             .set = rtl8366rb_sw_set_port_rate_out,
> +             .get = rtl8366rb_sw_get_port_rate_out,
>       },
>  };
>  
> @@ -855,6 +1142,13 @@
>               .max = 1,
>               .set = NULL,
>               .get = rtl8366_sw_get_vlan_info,
> +     }, {
> +             .type = SWITCH_TYPE_INT,
> +             .name = "fid",
> +             .description = "Get/Set vlan fid",
> +             .max = RTL8366RB_FIDMAX,
> +             .set = rtl8366rb_sw_set_vlan_fid,
> +             .get = rtl8366rb_sw_get_vlan_fid,
>       },
>  };
>  
> @@ -1132,5 +1426,6 @@
>  MODULE_VERSION(RTL8366RB_DRIVER_VER);
>  MODULE_AUTHOR("Gabor Juhos <[email protected]>");
>  MODULE_AUTHOR("Antti Seppälä <[email protected]>");
> +MODULE_AUTHOR("Roman Yeryomin <[email protected]>");
>  MODULE_LICENSE("GPL v2");
>  MODULE_ALIAS("platform:" RTL8366RB_DRIVER_NAME);
_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to