[OpenWrt-Devel] Need help to integrate port mirroring support for rtl8366rb
Hi, now that we have port mirroring support in the ar8216 driver I'd like to resurrect my initial patch for the rtl8366rb driver again (http://patchwork.openwrt.org/patch/1466/). The patch still applies to trunk (minor tweak on the filename required) and runs fine on my TP-Link TL-WR1043ND. Are there any objections to the patch? Thanks, Colin ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel
Re: [OpenWrt-Devel] Can I help integrating port mirroring patches?
* ar8216 I think I have a board with this switch (arv7518pw) and I'll do my best to test it next week. As luck would have it, the AVM sources contained the necessary register definitions to support port mirroring on the AR8216. The patch should apply to the recent trunk. The AR8xx6 code path is untested, AR8327 works fine. Colin Signed-off-by: Colin Leitner colin.leit...@googlemail.com Index: target/linux/generic/files/drivers/net/phy/ar8216.c === --- target/linux/generic/files/drivers/net/phy/ar8216.c (revision 36256) +++ target/linux/generic/files/drivers/net/phy/ar8216.c (working copy) @@ -120,6 +120,12 @@ u8 vlan_table[AR8X16_MAX_VLANS]; u8 vlan_tagged; u16 pvid[AR8X16_MAX_PORTS]; + + /* Mirroring */ + bool mirror_rx; + bool mirror_tx; + int source_port; + int monitor_port; }; #define MIB_DESC(_s , _o, _n) \ @@ -1457,6 +1463,98 @@ return 0; } +static void +ar8327_set_mirror_regs(struct ar8xxx_priv *priv) +{ + int port; + + /* Reset all mirror registers */ + ar8xxx_rmw(priv, AR8327_REG_FWD_CTRL0, + AR8327_FWD_CTRL0_MIRROR_PORT, + (0xF AR8327_FWD_CTRL0_MIRROR_PORT_S)); + for (port = 0; port AR8327_NUM_PORTS; port++) { + ar8xxx_rmw(priv, AR8327_REG_PORT_LOOKUP(port), + AR8327_PORT_LOOKUP_ING_MIRROR_EN, + 0); + + ar8xxx_rmw(priv, AR8327_REG_PORT_HOL_CTRL1(port), + AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN, + 0); + } + + /* Now enable mirroring if necessary */ + if (priv-source_port = AR8327_NUM_PORTS || + priv-monitor_port = AR8327_NUM_PORTS || + priv-source_port == priv-monitor_port) { + return; + } + + ar8xxx_rmw(priv, AR8327_REG_FWD_CTRL0, + AR8327_FWD_CTRL0_MIRROR_PORT, + (priv-monitor_port AR8327_FWD_CTRL0_MIRROR_PORT_S)); + + if (priv-mirror_rx) + ar8xxx_rmw(priv, AR8327_REG_PORT_LOOKUP(priv-source_port), + AR8327_PORT_LOOKUP_ING_MIRROR_EN, + AR8327_PORT_LOOKUP_ING_MIRROR_EN); + + if (priv-mirror_tx) + ar8xxx_rmw(priv, AR8327_REG_PORT_HOL_CTRL1(priv-source_port), + AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN, + AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN); +} + +static void +ar8216_set_mirror_regs(struct ar8xxx_priv *priv) +{ + int port; + + /* Reset all mirror registers */ + ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CPUPORT, + AR8216_GLOBAL_CPUPORT_MIRROR_PORT, + (0xF AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S)); + for (port = 0; port AR8216_NUM_PORTS; port++) { + ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(port), + AR8216_PORT_CTRL_MIRROR_RX, + 0); + + ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(port), + AR8216_PORT_CTRL_MIRROR_TX, + 0); + } + + /* Now enable mirroring if necessary */ + if (priv-source_port = AR8216_NUM_PORTS || + priv-monitor_port = AR8216_NUM_PORTS || + priv-source_port == priv-monitor_port) { + return; + } + + ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CPUPORT, + AR8216_GLOBAL_CPUPORT_MIRROR_PORT, + (priv-monitor_port AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S)); + + if (priv-mirror_rx) + ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(priv-source_port), + AR8216_PORT_CTRL_MIRROR_RX, + AR8216_PORT_CTRL_MIRROR_RX); + + if (priv-mirror_tx) + ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(priv-source_port), + AR8216_PORT_CTRL_MIRROR_TX, + AR8216_PORT_CTRL_MIRROR_TX); +} + +static void +ar8xxx_set_mirror_regs(struct ar8xxx_priv *priv) +{ + if (chip_is_ar8327(priv)) { + ar8327_set_mirror_regs(priv); + } else { + ar8216_set_mirror_regs(priv); + } +} + static int ar8xxx_sw_hw_apply(struct switch_dev *dev) { @@ -1520,6 +1618,9 @@ priv-chip-setup_port(priv, i, egress, ingress, portmask[i], pvid); } + + ar8xxx_set_mirror_regs(priv); + mutex_unlock(priv-reg_mutex); return 0; } @@ -1541,7 +1642,13 @@ for (i = 0; i dev-ports; i++) priv-chip-init_port(priv, i); + priv-mirror_rx = false; + priv-mirror_tx = false; + priv-source_port = 0; + priv-monitor_port = 0; + priv-chip-init_globals(priv); + mutex_unlock(priv-reg_mutex); return ar8xxx_sw_hw_apply(dev
Re: [OpenWrt-Devel] Can I help integrating port mirroring patches?
Hi Luka, The two patches for the rtl8366rb [1] and ar8216 [2] drivers haven't drawn much (any?) attention and I wanted to know if I can help integrating them. Don't be discouraged I think this is a nice feature. We didn't have time for testing yet. I fully understand and just poked the mailing list as the patch submission guide suggested :). I dove through a couple of product briefs and datasheets and with the present set of switch drivers it should be possible to add port mirroring to the majority of drivers (datasheets are a must however): * adm6996 - not supported Why? Software or hardware? The datasheet doesn't mention mirror or monitor. It's a hardware limitation. * ar8216 I think I have a board with this switch (arv7518pw) and I'll do my best to test it next week. The current patch will only work on the AR8327 switch (which is supported by the ar8216 driver). I'll browse for a datasheet (or contact Qualcomm, no idea if they're willing to help) and try to add support for the AR8216 too (although I couldn't find any relevant documentation to this chip yet). Colin ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel
[OpenWrt-Devel] Can I help integrating port mirroring patches?
Hi, I'm interested in adding port mirroring support to OpenWRT, which allows to reuse a switch port to sniff on another port. This is a great debugging tool and is supported by most managed switches (e.g. [4]). The two patches for the rtl8366rb [1] and ar8216 [2] drivers haven't drawn much (any?) attention and I wanted to know if I can help integrating them. I dove through a couple of product briefs and datasheets and with the present set of switch drivers it should be possible to add port mirroring to the majority of drivers (datasheets are a must however): * mvswitch 88E6060 - should be possible using the Port Association Vector (tx only is possible, rx implies tx mirroring). no hardware to test against * adm6996 - not supported * ar8216 AR8316 - unknown AR8216 - unknown AR8236 - product sheet claims support AR8327 - patch available and tested on TL-WDR4300 AR8328 - product sheet claims support * b53 BCM5325E - product sheet claims support. WRT54GL is available but no datasheet BCM5236 - unknown BCM539x - unknown BCM53115 - product sheet claims support BCM53125 - unknown BCM63XX - unknown * psb6970 - product sheet claims support * ip17xx IP175A - not supported IP175C - not supported IP175D - product sheet claims support * rtl8306 - not supported * rtl8366rb - patch available and tested on TL-WR1043ND * rtl8366s - datasheet claims support through ACLs. pre-release datasheet 1.4 has no documentation on how to use ACLs * rtl8367 - product sheet claims support The available patches add four global swlib options: enable_mirror_rx enable_mirror_tx mirror_monitor_port mirror_source_port This one-to-one model doesn't reflect the capabilites some of these switches have, but I opted for a KISS solution :). LuCI integration is available too [3], so end users could use this feature right away. Thanks, Colin [1]: http://patchwork.openwrt.org/patch/1466/ [2]: http://patchwork.openwrt.org/patch/3515/ [3]: https://dev.openwrt.org/ticket/10202 [4]: http://www.netgear.de/images/FSM726v3_DS_02Feb1122-5241.pdf ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel
[OpenWrt-Devel] [PATCH] [generic] Add port mirroring/monitoring capability to AR8327 switch driver
Hi, this patch adds the swlib attributes enable_mirror_rx enable_mirror_tx mirror_monitor_port mirror_source_port to the AR8327 switch/PHY driver that allow to mirror Ethernet packets to a monitor port. Tested on a TL-WDR4300 router. Signed-off-by: Colin Leitner colin.leit...@gmail.com Index: target/linux/generic/files/drivers/net/phy/ar8216.c === --- target/linux/generic/files/drivers/net/phy/ar8216.c (revision 34185) +++ target/linux/generic/files/drivers/net/phy/ar8216.c (working copy) @@ -88,6 +88,12 @@ u8 vlan_table[AR8X16_MAX_VLANS]; u8 vlan_tagged; u16 pvid[AR8X16_MAX_PORTS]; + + /* Mirroring */ + bool mirror_rx; + bool mirror_tx; + int source_port; + int monitor_port; }; #define to_ar8216(_dev) container_of(_dev, struct ar8216_priv, dev) @@ -1001,8 +1007,132 @@ return 0; } +static void +ar8327_set_mirror_regs(struct ar8216_priv *priv) +{ + int port; + /* Reset all mirror registers */ + ar8216_rmw(priv, AR8327_REG_FWD_CTRL0, + AR8327_FWD_CTRL0_MIRROR_PORT, + (0xF AR8327_FWD_CTRL0_MIRROR_PORT_S)); + for (port = 0; port AR8327_NUM_PORTS; port++) { + ar8216_rmw(priv, AR8327_REG_PORT_LOOKUP(port), + AR8327_PORT_LOOKUP_ING_MIRROR_EN, + 0); + + ar8216_rmw(priv, AR8327_REG_PORT_HOL_CTRL1(port), + AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN, + 0); + } + + /* Now enable mirroring if necessary */ + if (priv-source_port = AR8327_NUM_PORTS || + priv-monitor_port = AR8327_NUM_PORTS || + priv-source_port == priv-monitor_port) { + return; + } + + ar8216_rmw(priv, AR8327_REG_FWD_CTRL0, + AR8327_FWD_CTRL0_MIRROR_PORT, + (priv-monitor_port AR8327_FWD_CTRL0_MIRROR_PORT_S)); + + if (priv-mirror_tx) + ar8216_rmw(priv, AR8327_REG_PORT_LOOKUP(priv-source_port), + AR8327_PORT_LOOKUP_ING_MIRROR_EN, + AR8327_PORT_LOOKUP_ING_MIRROR_EN); + + if (priv-mirror_rx) + ar8216_rmw(priv, AR8327_REG_PORT_HOL_CTRL1(priv-source_port), + AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN, + AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN); +} + static int +ar8327_sw_set_mirror_rx_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar8216_priv *priv = to_ar8216(dev); + priv-mirror_rx = !!val-value.i; + ar8327_set_mirror_regs(priv); + return 0; +} + +static int +ar8327_sw_get_mirror_rx_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar8216_priv *priv = to_ar8216(dev); + val-value.i = priv-mirror_rx; + return 0; +} + +static int +ar8327_sw_set_mirror_tx_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar8216_priv *priv = to_ar8216(dev); + priv-mirror_tx = !!val-value.i; + ar8327_set_mirror_regs(priv); + return 0; +} + +static int +ar8327_sw_get_mirror_tx_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar8216_priv *priv = to_ar8216(dev); + val-value.i = priv-mirror_tx; + return 0; +} + +static int +ar8327_sw_set_mirror_monitor_port(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar8216_priv *priv = to_ar8216(dev); + priv-monitor_port = val-value.i; + ar8327_set_mirror_regs(priv); + return 0; +} + +static int +ar8327_sw_get_mirror_monitor_port(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar8216_priv *priv = to_ar8216(dev); + val-value.i = priv-monitor_port; + return 0; +} + +static int +ar8327_sw_set_mirror_source_port(struct switch_dev *dev, +const struct switch_attr *attr, +struct switch_val *val) +{ + struct ar8216_priv *priv = to_ar8216(dev); + priv-source_port = val-value.i; + ar8327_set_mirror_regs(priv); + return 0; +} + +static int +ar8327_sw_get_mirror_source_port(struct switch_dev *dev, +const struct switch_attr *attr, +struct switch_val *val) +{ + struct
[OpenWrt-Devel] Can I somehow help to integrate the port mirroring patch?
Hello, is there something I can do to help getting this patch [1] integrated? The ticket with the LuCI enhancement can be found in Trac [2], but I'm not even sure how OpenWRT and LuCI devs interact with each other and if the OpenWRT Trac is the right place for such enhancements. Thanks to all of you for the great work that led to this great little distro! Bye, Colin [1]: http://patchwork.openwrt.org/patch/1466/ [2]: https://dev.openwrt.org/ticket/10202 ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel
[OpenWrt-Devel] [PATCH] Add port mirroring/monitoring capability to rtl8366rb switch
This patch adds swlib attributes to the RTL8366RB switch/PHY found in the TL-WR1043ND router that allow to mirror ethernet packets to a monitor port. I have a patch for LuCIs vlan.lua available. Is it enough to post it here or is there a different mailing list for LuCI enhancements? Signed-off-by: Colin Leitner colin.leit...@googlemail.com Index: target/linux/generic-2.6/files/drivers/net/phy/rtl8366rb.c === --- target/linux/generic-2.6/files/drivers/net/phy/rtl8366rb.c (Revision 28372) +++ target/linux/generic-2.6/files/drivers/net/phy/rtl8366rb.c (Arbeitskopie) @@ -4,6 +4,7 @@ * Copyright (C) 2009-2010 Gabor Juhos juh...@openwrt.org * Copyright (C) 2010 Antti Seppälä a.sepp...@gmail.com * Copyright (C) 2010 Roman Yeryomin ro...@advem.lv + * Copyright (C) 2011 Colin Leitner colin.leit...@googlemail.com * * 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 @@ -21,7 +22,7 @@ #include rtl8366_smi.h #define RTL8366RB_DRIVER_DESC Realtek RTL8366RB ethernet switch driver -#define RTL8366RB_DRIVER_VER 0.2.3 +#define RTL8366RB_DRIVER_VER 0.2.4 #define RTL8366RB_PHY_NO_MAX 4 #define RTL8366RB_PHY_PAGE_MAX 7 @@ -43,6 +44,17 @@ /* Port Enable Control register */ #define RTL8366RB_PECR 0x0001 +/* Port Mirror Control Register */ +#define RTL8366RB_PMCR 0x0007 +#define RTL8366RB_PMCR_SOURCE_PORT(_x) (_x) +#define RTL8366RB_PMCR_SOURCE_PORT_MASK0x000f +#define RTL8366RB_PMCR_MONITOR_PORT(_x)((_x) 4) +#define RTL8366RB_PMCR_MONITOR_PORT_MASK 0x00f0 +#define RTL8366RB_PMCR_MIRROR_RX BIT(8) +#define RTL8366RB_PMCR_MIRROR_TX BIT(9) +#define RTL8366RB_PMCR_MIRROR_SPC BIT(10) +#define RTL8366RB_PMCR_MIRROR_ISO BIT(11) + /* Switch Security Control registers */ #define RTL8366RB_SSCR00x0002 #define RTL8366RB_SSCR10x0003 @@ -933,6 +945,180 @@ return 0; } +static int rtl8366rb_sw_set_mirror_rx_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; + + if (val-value.i) + data = RTL8366RB_PMCR_MIRROR_RX; + else + data = 0; + + return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MIRROR_RX, data); +} + +static int rtl8366rb_sw_get_mirror_rx_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_PMCR, data); + if (data RTL8366RB_PMCR_MIRROR_RX) + val-value.i = 1; + else + val-value.i = 0; + + return 0; +} + +static int rtl8366rb_sw_set_mirror_tx_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; + + if (val-value.i) + data = RTL8366RB_PMCR_MIRROR_TX; + else + data = 0; + + return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MIRROR_TX, data); +} + +static int rtl8366rb_sw_get_mirror_tx_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_PMCR, data); + if (data RTL8366RB_PMCR_MIRROR_TX) + val-value.i = 1; + else + val-value.i = 0; + + return 0; +} + +static int rtl8366rb_sw_set_monitor_isolation_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; + + if (val-value.i) + data = RTL8366RB_PMCR_MIRROR_ISO; + else + data = 0; + + return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MIRROR_ISO, data); +} + +static int rtl8366rb_sw_get_monitor_isolation_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_PMCR, data); + if (data