--- a/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h
+++ b/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h
@@ -22,6 +22,7 @@ struct rt305x_esw_platform_data
 	u8 vlan_config;
 	u32 reg_initval_fct2;
 	u32 reg_initval_fpa2;
+	u8 led_polarity;
 };
 
 #endif /* _RT305X_ESW_PLATFORM_H */
--- a/drivers/net/ethernet/ramips/ramips_esw.c
+++ b/drivers/net/ethernet/ramips/ramips_esw.c
@@ -48,6 +48,15 @@
 #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
@@ -58,8 +67,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
@@ -152,6 +162,9 @@ enum {
 	/* 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,
@@ -160,6 +173,9 @@ enum {
 	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 {
@@ -193,6 +209,9 @@ struct rt305x_esw {
 	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 */
 
 };
 
@@ -435,6 +454,7 @@ rt305x_esw_hw_init(struct rt305x_esw *es
 	 * ports.
 	 */
 	rt305x_esw_wr(esw, 0x0008a301, RT305X_ESW_REG_SGC);
+	esw->sgc=0x0008a301;
 
 	/* Setup SoC Port control register */
 	rt305x_esw_wr(esw,
@@ -457,6 +477,12 @@ rt305x_esw_hw_init(struct rt305x_esw *es
 	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);
 	for (i = 0; i < 6; i++)
@@ -555,6 +581,8 @@ rt305x_esw_apply_config(struct switch_de
 	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) {
@@ -568,6 +596,10 @@ rt305x_esw_apply_config(struct switch_de
 		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;
 		disable |= esw->ports[i].disable << i;
@@ -805,6 +837,29 @@ rt305x_esw_get_port_recv_badgood(struct
 }
 
 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)
@@ -961,6 +1016,122 @@ rt305x_esw_set_vlan_ports(struct switch_
 	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,
@@ -981,6 +1152,33 @@ static const struct switch_attr rt305x_e
 		.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[] = {
@@ -1017,7 +1215,7 @@ static const struct switch_attr rt305x_e
 		.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,
@@ -1045,6 +1243,29 @@ static const struct switch_attr rt305x_e
 		.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[] = {
@@ -1096,7 +1317,7 @@ rt305x_esw_probe(struct platform_device
 {
 	struct device_node *np = pdev->dev.of_node;
 	const struct rt305x_esw_platform_data *pdata;
-	const __be32 *port_map, *reg_init;
+	const __be32 *led_polarity, *port_map, *reg_init;
 	struct rt305x_esw *esw;
 	struct switch_dev *swdev;
 	struct resource *res, *irq;
@@ -1139,6 +1360,10 @@ rt305x_esw_probe(struct platform_device
 		goto free_esw;
 	}
 
+	led_polarity = of_get_property(np, "ralink,led-polarity", NULL);
+        if (led_polarity)
+		esw->led_polarity = be32_to_cpu(*led_polarity);
+
 	port_map = of_get_property(np, "ralink,portmap", NULL);
         if (port_map)
 		esw->port_map = be32_to_cpu(*port_map);
