From patchwork Wed Apr 26 21:35:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Krstic X-Patchwork-Id: 755649 X-Patchwork-Delegate: blogic@openwrt.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wCth83V9Kz9s7y for ; Thu, 27 Apr 2017 07:36:56 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="fFfgIsP6"; dkim-atps=neutral Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 9F3DAB803DB; Wed, 26 Apr 2017 23:36:52 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00,FREEMAIL_FROM, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.1 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP; Wed, 26 Apr 2017 23:36:52 +0200 (CEST) Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 66FFDB801DA for ; Wed, 26 Apr 2017 23:36:51 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 CL_IP_EQ_HELO_IP=-2 (check from: .gmail. - helo: .mail-wm0-f68.google. - helo-domain: .google.) FROM/MX_MATCHES_HELO(DOMAIN)=-2; rate: -7 Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Wed, 26 Apr 2017 23:36:50 +0200 (CEST) Received: by mail-wm0-f68.google.com with SMTP id y10so439749wmh.0 for ; Wed, 26 Apr 2017 14:36:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=ths/tNsoLbyCayZPxMg8wVm1abE3xQ0dzfJFjHp2YPI=; b=fFfgIsP6rZvhi0A5STCwaM5r7btLg0z80QThP2bXD0RtMAYkG9s5us4bh49nNE9kha tqJgpUU0DxrXB9jY3zdilYqdO6CsrmpV4F2bvN45Xl+ekjXIldN3x0wmUOOnCxIoNHlV FFVR05p521cZOVHtOr1rERnitqqfV75ugu8cSzcfjKjWCkoKjWMMUuPFgwmY5+mpqrst vPL1vn5sMUukhU9T91c2YXeIzlRFqJ/j9eLjaNfLAk+wc3zDdog6qQdrXzzXVBznip3y XG2a4CCVpPNnn/aVVA961yMMT+wEoxsUhtjY9qY5v8s87Qw5JC6gR5yjBqbY+JU5t8zY EnVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=ths/tNsoLbyCayZPxMg8wVm1abE3xQ0dzfJFjHp2YPI=; b=Y/0ydkW33Tj+6QMp56eOtbvgDThGhC50dhcUhu5if2TdGvn6KLTnDwPPqPZxQf0H6k dQoGJCGxWZ9wwNzlX7mYv1SGUeDWWawHut7Z1XM+Q0mlszq/cLwBdgOfm2e9qRTsSsQE /FukOMNQmTwgGd79fLCIW82fqdZMtYw5pMN5xaJmZ7D8nCn4605EqLGE0ZobzMtYzjMd w8NSswNwo4CxnkiWdbU2umQPwbsczxrWHUIGZx37rIilOowee39+LsRJX00ZJ/Bi3ThM KdAUuTCx+FSt3jBdY7Xd7rb/g/P1S/uD8vivoDOyc1hopQQiad51Cs91+XeMe6B/vQnJ DJ3w== X-Gm-Message-State: AN3rC/55E8Lw5xmq2C0sBAj0WmdT7/Jo++3v7TeJMlMYis/2uFKV1wL2 CBg3RXBL8KJphg== X-Received: by 10.80.147.193 with SMTP id o59mr2229750eda.133.1493242609191; Wed, 26 Apr 2017 14:36:49 -0700 (PDT) Received: from localhost.localdomain.localdomain (82-161-235-250.ip.xs4all.nl. [82.161.235.250]) by smtp.gmail.com with ESMTPSA id h29sm822771eda.45.2017.04.26.14.36.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Apr 2017 14:36:48 -0700 (PDT) From: Milan Krstic To: openwrt-devel@lists.openwrt.org Date: Wed, 26 Apr 2017 23:35:53 +0200 Message-Id: <1493242553-1595-1-git-send-email-milan.krstic@gmail.com> X-Mailer: git-send-email 1.8.3.1 Subject: [OpenWrt-Devel] [PATCH] [ar71xx] ag71xx: add support for port mirroring X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" This exposes hardware port mirroring in ag71xx driver (e.g. TL-WR841ND) via swconfig API. Signed-off-by: Milan Krstic --- .../net/ethernet/atheros/ag71xx/ag71xx_ar7240.c | 154 +++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c index c5aed0d..da9c0dd 100644 --- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c @@ -77,6 +77,7 @@ #define AR7240_REG_CPU_PORT 0x78 #define AR7240_MIRROR_PORT_S 4 +#define AR7240_MIRROR_PORT_M BITM(4) #define AR7240_CPU_PORT_EN BIT(8) #define AR7240_REG_MIB_FUNCTION0 0x80 @@ -1013,6 +1014,134 @@ ar7240_get_port_stats(struct switch_dev *dev, int port, return 0; } +static int +ar7240_set_mirror_monitor_port(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + struct mii_bus *mii = as->mii_bus; + + int port = val->value.i; + + if (port > 15) + return -EINVAL; + + ar7240sw_reg_rmw(mii, AR7240_REG_CPU_PORT, + AR7240_MIRROR_PORT_M << AR7240_MIRROR_PORT_S, + port << AR7240_MIRROR_PORT_S); + + return 0; +} + +static int +ar7240_get_mirror_monitor_port(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + struct mii_bus *mii = as->mii_bus; + + u32 ret; + + ret = ar7240sw_reg_read(mii, AR7240_REG_CPU_PORT); + val->value.i = (ret >> AR7240_MIRROR_PORT_S) & AR7240_MIRROR_PORT_M; + + return 0; +} + +static int +ar7240_set_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + struct mii_bus *mii = as->mii_bus; + + int port = val->port_vlan; + + if (port >= dev->ports) + return -EINVAL; + + if (val && val->value.i == 1) + ar7240sw_reg_set(mii, AR7240_REG_PORT_CTRL(port), + AR7240_PORT_CTRL_MIRROR_RX); + else + ar7240sw_reg_rmw(mii, AR7240_REG_PORT_CTRL(port), + AR7240_PORT_CTRL_MIRROR_RX, 0); + + return 0; +} + +static int +ar7240_get_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + struct mii_bus *mii = as->mii_bus; + + u32 ctrl; + + int port = val->port_vlan; + + if (port >= dev->ports) + return -EINVAL; + + ctrl = ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(port)); + + if ((ctrl & AR7240_PORT_CTRL_MIRROR_RX) == AR7240_PORT_CTRL_MIRROR_RX) + val->value.i = 1; + else + val->value.i = 0; + + return 0; +} + +static int +ar7240_set_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + struct mii_bus *mii = as->mii_bus; + + int port = val->port_vlan; + + if (port >= dev->ports) + return -EINVAL; + + if (val && val->value.i == 1) + ar7240sw_reg_set(mii, AR7240_REG_PORT_CTRL(port), + AR7240_PORT_CTRL_MIRROR_TX); + else + ar7240sw_reg_rmw(mii, AR7240_REG_PORT_CTRL(port), + AR7240_PORT_CTRL_MIRROR_TX, 0); + + return 0; +} + +static int +ar7240_get_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + struct mii_bus *mii = as->mii_bus; + + u32 ctrl; + + int port = val->port_vlan; + + if (port >= dev->ports) + return -EINVAL; + + ctrl = ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(port)); + + if ((ctrl & AR7240_PORT_CTRL_MIRROR_TX) == AR7240_PORT_CTRL_MIRROR_TX) + val->value.i = 1; + else + val->value.i = 0; + + return 0; +} + static struct switch_attr ar7240_globals[] = { { .type = SWITCH_TYPE_INT, @@ -1022,9 +1151,34 @@ static struct switch_attr ar7240_globals[] = { .get = ar7240_get_vlan, .max = 1 }, + { + .type = SWITCH_TYPE_INT, + .name = "mirror_monitor_port", + .description = "Mirror monitor port", + .set = ar7240_set_mirror_monitor_port, + .get = ar7240_get_mirror_monitor_port, + .max = 15 + }, }; static struct switch_attr ar7240_port[] = { + { + .type = SWITCH_TYPE_INT, + .name = "enable_mirror_rx", + .description = "Enable mirroring of RX packets", + .set = ar7240_set_mirror_rx, + .get = ar7240_get_mirror_rx, + .max = 1 + }, + { + + .type = SWITCH_TYPE_INT, + .name = "enable_mirror_tx", + .description = "Enable mirroring of TX packets", + .set = ar7240_set_mirror_tx, + .get = ar7240_get_mirror_tx, + .max = 1 + }, }; static struct switch_attr ar7240_vlan[] = {