diff options
author | Deng Qingfang <dengqf6@mail2.sysu.edu.cn> | 2018-12-16 23:49:07 +0800 |
---|---|---|
committer | Chuanhong Guo <gch981213@gmail.com> | 2019-08-18 22:08:42 +0800 |
commit | fd4804ce33d00da189aea1669c851c5772a99630 (patch) | |
tree | 5f754fefd1e7c5aa790bc79bfb64a2966b465a2b /target/linux/ramips | |
parent | a6da3f9ef746101b84a6f530f5a40de28341b69a (diff) | |
download | upstream-fd4804ce33d00da189aea1669c851c5772a99630.tar.gz upstream-fd4804ce33d00da189aea1669c851c5772a99630.tar.bz2 upstream-fd4804ce33d00da189aea1669c851c5772a99630.zip |
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>
Diffstat (limited to 'target/linux/ramips')
-rw-r--r-- | target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mt7530.c | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mt7530.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mt7530.c index 5216cb5c66..9acea3bc84 100644 --- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mt7530.c +++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mt7530.c @@ -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, }, }; |