Hi, this patch add the swlib port-based attribute led_polarity
to control led polarity on rt5350 based boards, tr_bad tr_good to get transmit good/bad packet counter. Also adds capability to change led blink frequency, maximal packet size and configuring broadcast storm protection by adds next swlib attributes led_freq pkt_maxlen bc_storm_protect Tested on dir-320NRU H/w release b2 Signed-off-by: Vasily E. Moskalev <[email protected]> Index: files-3.7/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h =================================================================== --- files-3.7/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h (revision 36276) +++ files-3.7/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h (working copy) @@ -22,6 +22,7 @@ u8 vlan_config; u32 reg_initval_fct2; u32 reg_initval_fpa2; + u8 led_polarity; }; #endif /* _RT305X_ESW_PLATFORM_H */ Index: files-3.7/drivers/net/ethernet/ramips/ramips_esw.c =================================================================== --- files-3.7/drivers/net/ethernet/ramips/ramips_esw.c (revision 36276) +++ files-3.7/drivers/net/ethernet/ramips/ramips_esw.c (working copy) @@ -3,6 +3,7 @@ #include <linux/mii.h> #include <rt305x_regs.h> +#include <rt305x.h> #include <rt305x_esw_platform.h> /* @@ -45,6 +46,14 @@ #define RT305X_ESW_REG_P3PC 0xf4 #define RT305X_ESW_REG_P4PC 0xf8 #define RT305X_ESW_REG_P5PC 0xfc +/* RT5350 only registers */ +#define RT305X_EWS_REG_LED_POLARITY 0x168 +#define RT305X_ESW_REG_P0TPC 0x150 +#define RT305X_ESW_REG_P1TPC 0x154 +#define RT305X_ESW_REG_P2TPC 0x158 +#define RT305X_ESW_REG_P3TPC 0x15c +#define RT305X_ESW_REG_P4TPC 0x160 +#define RT305X_ESW_REG_P5TPC 0x164 #define RT305X_ESW_LED_LINK 0 #define RT305X_ESW_LED_100M 1 @@ -55,8 +64,9 @@ #define RT305X_ESW_LED_DUPLCOLL 6 #define RT305X_ESW_LED_10MACT 7 #define RT305X_ESW_LED_100MACT 8 -/* Additional led states not in datasheet: */ +/* Additional led states (from rt5350 datasheet): */ #define RT305X_ESW_LED_BLINK 10 +#define RT305X_ESW_LED_OFF 11 #define RT305X_ESW_LED_ON 12 #define RT305X_ESW_LINK_S 25 @@ -145,6 +155,9 @@ /* Global attributes. */ RT305X_ESW_ATTR_ENABLE_VLAN, RT305X_ESW_ATTR_ALT_VLAN_DISABLE, + RT305X_ESW_ATTR_LED_FREQ, + RT305X_ESW_ATTR_PKT_LENGTH, + RT305X_ESW_ATTR_BC_STATUS, /* Port attributes. */ RT305X_ESW_ATTR_PORT_DISABLE, RT305X_ESW_ATTR_PORT_DOUBLETAG, @@ -153,6 +166,9 @@ RT305X_ESW_ATTR_PORT_LAN, RT305X_ESW_ATTR_PORT_RECV_BAD, RT305X_ESW_ATTR_PORT_RECV_GOOD, + RT305X_ESW_ATTR_PORT_TR_BAD, + RT305X_ESW_ATTR_PORT_TR_GOOD, + RT305X_ESW_ATTR_PORT_LED_POLARITY, }; struct rt305x_esw_port { @@ -179,6 +195,8 @@ bool alt_vlan_disable; struct rt305x_esw_vlan vlans[RT305X_ESW_NUM_VLANS]; struct rt305x_esw_port ports[RT305X_ESW_NUM_PORTS]; + u8 led_polarity; /* LED polarity. RT5350 only */ + u32 sgc; /* SGC value */ }; @@ -418,6 +436,7 @@ * ports. */ rt305x_esw_wr(esw, 0x0008a301, RT305X_ESW_REG_SGC); + esw->sgc=0x0008a301; /* Setup SoC Port control register */ rt305x_esw_wr(esw, @@ -436,6 +455,12 @@ rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P2LED); rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P3LED); rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P4LED); + + /* Force Link polarity on ports */ + if (soc_is_rt5350()) { + rt305x_esw_wr(esw,esw->pdata->led_polarity & 0x1F, RT305X_EWS_REG_LED_POLARITY); + esw->led_polarity= esw->pdata->led_polarity & 0x1F; + } /* Copy disabled port configuration from bootloader setup */ port_disable = rt305x_esw_get_port_disable(esw); @@ -516,6 +541,7 @@ u8 en_vlan = 0; u8 untag = 0; + rt305x_esw_wr(esw, esw->sgc, RT305X_ESW_REG_SGC); for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) { u32 vid, vmsc; if (esw->global_vlan_enable) { @@ -528,6 +554,10 @@ rt305x_esw_set_vlan_id(esw, i, vid); rt305x_esw_set_vmsc(esw, i, vmsc); } + + if (soc_is_rt5350()) { + rt305x_esw_wr(esw,esw->led_polarity, RT305X_EWS_REG_LED_POLARITY); + } for (i = 0; i < RT305X_ESW_NUM_PORTS; i++) { u32 pvid; @@ -766,6 +796,29 @@ } static int +rt305x_esw_get_port_tr_badgood(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); + int idx = val->port_vlan; + int shift = attr->id == RT305X_ESW_ATTR_PORT_TR_GOOD ? 0 : 16; + u32 reg; + + if (!soc_is_rt5350()) + return -EINVAL; + + if (idx < 0 || idx >= RT305X_ESW_NUM_LANWAN) + return -EINVAL; + + reg = rt305x_esw_rr(esw, RT305X_ESW_REG_P0TPC + 4*idx); + val->value.i = (reg >> shift) & 0xffff; + + return 0; +} + + +static int rt305x_esw_get_port_led(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) @@ -922,6 +975,122 @@ return 0; } +static int +rt305x_esw_set_port_led_polarity(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); + int idx = val->port_vlan; + + if (idx < 0 || idx >= RT305X_ESW_NUM_LEDS) + return -EINVAL; + + if (!soc_is_rt5350()) + return -EINVAL; + + if (val->value.i==0) + esw->led_polarity &= ~ (1 << idx); + else + esw->led_polarity |= (1 << idx); + return 0; +} + +static int +rt305x_esw_get_port_led_polarity(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); + int idx = val->port_vlan; + + if (!soc_is_rt5350()) + return -EINVAL; + + + if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS || + idx >= RT305X_ESW_NUM_LEDS) + return -EINVAL; + + val->value.i = (rt305x_esw_rr(esw, RT305X_EWS_REG_LED_POLARITY) >> idx) & 1; + + return 0; +} + +static int +rt305x_esw_set_led_freq(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); + + esw->sgc &= 0xfe7fffff; + esw->sgc |= ((val->value.i & 3) << 23); + return 0; +} + +static int +rt305x_esw_get_led_freq(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); + + val->value.i = (rt305x_esw_rr(esw,RT305X_ESW_REG_SGC) >> 23) & 3; + + return 0; +} + +static int +rt305x_esw_set_pkt_length(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); + + esw->sgc &= 0xffffff3f; + esw->sgc |= ((val->value.i & 3) << 6); + return 0; +} + +static int +rt305x_esw_get_pkt_length(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); + + val->value.i = (rt305x_esw_rr(esw, RT305X_ESW_REG_SGC) >> 6) & 3; + + return 0; +} + + +static int +rt305x_esw_set_bc_status(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); + + esw->sgc &= 0xffffffcf; + esw->sgc |= ((val->value.i & 3) << 4); + return 0; +} + +static int +rt305x_esw_get_bc_status(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); + + val->value.i = (rt305x_esw_rr(esw, RT305X_ESW_REG_SGC) >> 4) & 3; + + return 0; +} + + static const struct switch_attr rt305x_esw_global[] = { { .type = SWITCH_TYPE_INT, @@ -942,6 +1111,33 @@ .get = rt305x_esw_get_alt_vlan_disable, .set = rt305x_esw_set_alt_vlan_disable, }, + { + .type = SWITCH_TYPE_INT, + .name = "led_freq", + .description = "LED Flash frequency (0:30mS, 1:60mS, 2:240mS, 3:480mS)", + .max = 3, + .id = RT305X_ESW_ATTR_LED_FREQ, + .get = rt305x_esw_get_led_freq, + .set = rt305x_esw_set_led_freq, + }, + { + .type = SWITCH_TYPE_INT, + .name = "pkt_maxlen", + .description = "Maximum packet lenghth tagged/untagged (0:1536/1536, 1:1522/1518, 2:1526/1522)", + .max = 2, + .id = RT305X_ESW_ATTR_PKT_LENGTH, + .get = rt305x_esw_get_pkt_length, + .set = rt305x_esw_set_pkt_length, + }, + { + .type = SWITCH_TYPE_INT, + .name = "bc_storm_protect", + .description = "Global broadcast storm protection (0:Disable, 1:64 blocks, 2:96 blocks, 3:128 blocks)", + .max = 2, + .id = RT305X_ESW_ATTR_BC_STATUS, + .get = rt305x_esw_get_bc_status, + .set = rt305x_esw_set_bc_status, + }, }; static const struct switch_attr rt305x_esw_port[] = { @@ -978,7 +1174,7 @@ .name = "led", .description = "LED mode (0:link, 1:100m, 2:duplex, 3:activity," " 4:collision, 5:linkact, 6:duplcoll, 7:10mact," - " 8:100mact, 10:blink, 12:on)", + " 8:100mact, 10:blink, 11:off, 12:on)", .max = 15, .id = RT305X_ESW_ATTR_PORT_LED, .get = rt305x_esw_get_port_led, @@ -1006,6 +1202,29 @@ .id = RT305X_ESW_ATTR_PORT_RECV_GOOD, .get = rt305x_esw_get_port_recv_badgood, }, + { + .type = SWITCH_TYPE_INT, + .name = "led_polarity", + .description = "LED Polarity for each port (0:low active, 1:high active). rt5350 only", + .max = 1, + .id = RT305X_ESW_ATTR_PORT_LED_POLARITY, + .get = rt305x_esw_get_port_led_polarity, + .set = rt305x_esw_set_port_led_polarity, + }, + { + .type = SWITCH_TYPE_INT, + .name = "tr_bad", + .description = "Transmit bad packet counter. rt5350 only", + .id = RT305X_ESW_ATTR_PORT_TR_BAD, + .get = rt305x_esw_get_port_tr_badgood, + }, + { + .type = SWITCH_TYPE_INT, + .name = "tr_good", + .description = "Transmit good packet counter. rt5350 only", + .id = RT305X_ESW_ATTR_PORT_TR_GOOD, + .get = rt305x_esw_get_port_tr_badgood, + }, }; static const struct switch_attr rt305x_esw_vlan[] = { -- ---- AKA 2:465/[email protected]
_______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
