ramips: add MT7530 switch port-mirroring support
Compile & run tested on MT7620, MT7621 Signed-off-by: Deng Qingfang <dengqf6@mail2.sysu.edu.cn> [Tested on Phicomm PSG1218 rev.A, MediaTek MT7620A ver:2 eco:6] Tested-by: MingHao Chen <cmheia@email.com>
This commit is contained in:
		 Deng Qingfang
					Deng Qingfang
				
			
				
					committed by
					
						 Chuanhong Guo
						Chuanhong Guo
					
				
			
			
				
	
			
			
			 Chuanhong Guo
						Chuanhong Guo
					
				
			
						parent
						
							a6da3f9ef7
						
					
				
				
					commit
					fd4804ce33
				
			| @@ -51,6 +51,11 @@ | ||||
| #define MT7621_PORT_MIB_RXB_ID	37	/* RxByte */ | ||||
|  | ||||
| /* registers */ | ||||
| #define REG_ESW_WT_MAC_MFC		0x10 | ||||
|  | ||||
| #define REG_ESW_WT_MAC_MFC_MIRROR_ENABLE	BIT(3) | ||||
| #define REG_ESW_WT_MAC_MFC_MIRROR_DEST_MASK	0x07 | ||||
|  | ||||
| #define REG_ESW_VLAN_VTCR		0x90 | ||||
| #define REG_ESW_VLAN_VAWD1		0x94 | ||||
| #define REG_ESW_VLAN_VAWD2		0x98 | ||||
| @@ -72,6 +77,11 @@ enum { | ||||
| #define REG_ESW_PORT_PVC(x)	(0x2010 | ((x) << 8)) | ||||
| #define REG_ESW_PORT_PPBV1(x)	(0x2014 | ((x) << 8)) | ||||
|  | ||||
| #define REG_ESW_PORT_PCR_MIRROR_SRC_RX_BIT	BIT(8) | ||||
| #define REG_ESW_PORT_PCR_MIRROR_SRC_TX_BIT	BIT(9) | ||||
| #define REG_ESW_PORT_PCR_MIRROR_SRC_RX_MASK	0x0100 | ||||
| #define REG_ESW_PORT_PCR_MIRROR_SRC_TX_MASK	0x0200 | ||||
|  | ||||
| #define REG_HWTRAP		0x7804 | ||||
|  | ||||
| #define MIB_DESC(_s , _o, _n)   \ | ||||
| @@ -183,6 +193,8 @@ enum { | ||||
|  | ||||
| struct mt7530_port_entry { | ||||
| 	u16	pvid; | ||||
| 	bool	mirror_rx; | ||||
| 	bool	mirror_tx; | ||||
| }; | ||||
|  | ||||
| struct mt7530_vlan_entry { | ||||
| @@ -196,6 +208,8 @@ struct mt7530_priv { | ||||
| 	struct mii_bus		*bus; | ||||
| 	struct switch_dev	swdev; | ||||
|  | ||||
| 	u8			mirror_src_port; | ||||
| 	u8			mirror_dest_port; | ||||
| 	bool			global_vlan_enable; | ||||
| 	struct mt7530_vlan_entry	vlan_entries[MT7530_NUM_VLANS]; | ||||
| 	struct mt7530_port_entry	port_entries[MT7530_NUM_PORTS]; | ||||
| @@ -505,6 +519,138 @@ mt7530_get_vid(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_get_mirror_rx_enable(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	val->value.i = priv->port_entries[priv->mirror_src_port].mirror_rx; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_set_mirror_rx_enable(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	priv->port_entries[priv->mirror_src_port].mirror_rx = val->value.i; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_get_mirror_tx_enable(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	val->value.i = priv->port_entries[priv->mirror_src_port].mirror_tx; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_set_mirror_tx_enable(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	priv->port_entries[priv->mirror_src_port].mirror_tx = val->value.i; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_get_mirror_monitor_port(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	val->value.i = priv->mirror_dest_port; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_set_mirror_monitor_port(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	priv->mirror_dest_port = val->value.i; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_get_mirror_source_port(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	val->value.i = priv->mirror_src_port; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_set_mirror_source_port(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	priv->mirror_src_port = val->value.i; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_get_port_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	val->value.i =  priv->port_entries[val->port_vlan].mirror_rx; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_set_port_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	priv->port_entries[val->port_vlan].mirror_rx = val->value.i; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_get_port_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	val->value.i =  priv->port_entries[val->port_vlan].mirror_tx; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mt7530_set_port_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr, | ||||
| 		struct switch_val *val) | ||||
| { | ||||
| 	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); | ||||
|  | ||||
| 	priv->port_entries[val->port_vlan].mirror_tx = val->value.i; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void | ||||
| mt7530_write_vlan_entry(struct mt7530_priv *priv, int vlan, u16 vid, | ||||
| 	                    u8 ports, u8 etags) | ||||
| @@ -558,6 +704,7 @@ mt7530_apply_config(struct switch_dev *dev) | ||||
| 	int i, j; | ||||
| 	u8 tag_ports; | ||||
| 	u8 untag_ports; | ||||
| 	bool is_mirror = false; | ||||
|  | ||||
| 	if (!priv->global_vlan_enable) { | ||||
| 		for (i = 0; i < MT7530_NUM_PORTS; i++) | ||||
| @@ -637,6 +784,31 @@ mt7530_apply_config(struct switch_dev *dev) | ||||
| 		mt7530_w32(priv, REG_ESW_PORT_PPBV1(i), val); | ||||
| 	} | ||||
|  | ||||
| 	/* set mirroring source port */ | ||||
| 	for (i = 0; i < MT7530_NUM_PORTS; i++)	{ | ||||
| 		u32 val = mt7530_r32(priv, REG_ESW_PORT_PCR(i)); | ||||
| 		if (priv->port_entries[i].mirror_rx) { | ||||
| 			val |= REG_ESW_PORT_PCR_MIRROR_SRC_RX_BIT; | ||||
| 			is_mirror = true; | ||||
| 		} | ||||
|  | ||||
| 		if (priv->port_entries[i].mirror_tx) { | ||||
| 			val |= REG_ESW_PORT_PCR_MIRROR_SRC_TX_BIT; | ||||
| 			is_mirror = true; | ||||
| 		} | ||||
|  | ||||
| 		mt7530_w32(priv, REG_ESW_PORT_PCR(i), val); | ||||
| 	} | ||||
|  | ||||
| 	/* set mirroring monitor port */ | ||||
| 	if (is_mirror) { | ||||
| 		u32 val = mt7530_r32(priv, REG_ESW_WT_MAC_MFC); | ||||
| 		val |= REG_ESW_WT_MAC_MFC_MIRROR_ENABLE; | ||||
| 		val &= ~REG_ESW_WT_MAC_MFC_MIRROR_DEST_MASK; | ||||
| 		val |= priv->mirror_dest_port; | ||||
| 		mt7530_w32(priv, REG_ESW_WT_MAC_MFC, val); | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -830,6 +1002,34 @@ static const struct switch_attr mt7530_global[] = { | ||||
| 		.description = "Get MIB counters for switch", | ||||
| 		.get = mt7530_sw_get_mib, | ||||
| 		.set = NULL, | ||||
| 	}, { | ||||
| 		.type = SWITCH_TYPE_INT, | ||||
| 		.name = "enable_mirror_rx", | ||||
| 		.description = "Enable mirroring of RX packets", | ||||
| 		.set = mt7530_set_mirror_rx_enable, | ||||
| 		.get = mt7530_get_mirror_rx_enable, | ||||
| 		.max = 1 | ||||
| 	}, { | ||||
| 		.type = SWITCH_TYPE_INT, | ||||
| 		.name = "enable_mirror_tx", | ||||
| 		.description = "Enable mirroring of TX packets", | ||||
| 		.set = mt7530_set_mirror_tx_enable, | ||||
| 		.get = mt7530_get_mirror_tx_enable, | ||||
| 		.max = 1 | ||||
| 	}, { | ||||
| 		.type = SWITCH_TYPE_INT, | ||||
| 		.name = "mirror_monitor_port", | ||||
| 		.description = "Mirror monitor port", | ||||
| 		.set = mt7530_set_mirror_monitor_port, | ||||
| 		.get = mt7530_get_mirror_monitor_port, | ||||
| 		.max = MT7530_NUM_PORTS - 1 | ||||
| 	}, { | ||||
| 		.type = SWITCH_TYPE_INT, | ||||
| 		.name = "mirror_source_port", | ||||
| 		.description = "Mirror source port", | ||||
| 		.set = mt7530_set_mirror_source_port, | ||||
| 		.get = mt7530_get_mirror_source_port, | ||||
| 		.max = MT7530_NUM_PORTS - 1 | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| @@ -840,6 +1040,20 @@ static const struct switch_attr mt7621_port[] = { | ||||
| 		.description = "Get MIB counters for port", | ||||
| 		.get = mt7621_sw_get_port_mib, | ||||
| 		.set = NULL, | ||||
| 	}, { | ||||
| 		.type = SWITCH_TYPE_INT, | ||||
| 		.name = "enable_mirror_rx", | ||||
| 		.description = "Enable mirroring of RX packets", | ||||
| 		.set = mt7530_set_port_mirror_rx, | ||||
| 		.get = mt7530_get_port_mirror_rx, | ||||
| 		.max = 1, | ||||
| 	}, { | ||||
| 		.type = SWITCH_TYPE_INT, | ||||
| 		.name = "enable_mirror_tx", | ||||
| 		.description = "Enable mirroring of TX packets", | ||||
| 		.set = mt7530_set_port_mirror_tx, | ||||
| 		.get = mt7530_get_port_mirror_tx, | ||||
| 		.max = 1, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| @@ -861,6 +1075,20 @@ static const struct switch_attr mt7530_port[] = { | ||||
| 		.description = "Get MIB counters for port", | ||||
| 		.get = mt7530_sw_get_port_mib, | ||||
| 		.set = NULL, | ||||
| 	}, { | ||||
| 		.type = SWITCH_TYPE_INT, | ||||
| 		.name = "enable_mirror_rx", | ||||
| 		.description = "Enable mirroring of RX packets", | ||||
| 		.set = mt7530_set_port_mirror_rx, | ||||
| 		.get = mt7530_get_port_mirror_rx, | ||||
| 		.max = 1, | ||||
| 	}, { | ||||
| 		.type = SWITCH_TYPE_INT, | ||||
| 		.name = "enable_mirror_tx", | ||||
| 		.description = "Enable mirroring of TX packets", | ||||
| 		.set = mt7530_set_port_mirror_tx, | ||||
| 		.get = mt7530_get_port_mirror_tx, | ||||
| 		.max = 1, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user