From patchwork Tue Feb 9 20:21:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Horatiu Vultur X-Patchwork-Id: 12079131 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ACFC6C433E6 for ; Tue, 9 Feb 2021 20:46:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6709064E70 for ; Tue, 9 Feb 2021 20:46:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233972AbhBIUo7 (ORCPT ); Tue, 9 Feb 2021 15:44:59 -0500 Received: from esa.microchip.iphmx.com ([68.232.154.123]:13289 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233674AbhBIUgT (ORCPT ); Tue, 9 Feb 2021 15:36:19 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1612902978; x=1644438978; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=IhUdd2jlbfwy16e6uNnfyIi6STcN4Cush5DPbsaIFTY=; b=yPGUIlssDtUqVU9XlsVQ8cqDT0FjacjLaOUYK0O9u5BYxiIHPEJSdEp9 z3TO6ZnOGpkO48eYPSJ6Sc0ZJPKnFkEM7+AtRzli6Oc5qrL4FnJ/oA4qt DKihTOgzhzw0Z6ry5xqz6trBGqMBdJNz9etmPE+i7en4xuwxGX76nVeQf qWUBFo0LXmt5SWtf8yqJV3U4ZG1/aMxGqucfYTLNRSWnpSalosEQkeveU hbPZ/gCm3M4i556jyQQcTT643LUJFdYjvMMud2KCxlcD/22IZ3hZMyrME K84Lni87aZDefH7Kahdk84Jkk/1go6W81Mo1dXzzp59t9L8QXcBFkOEXy w==; IronPort-SDR: O/2fqCzSvt06FAhn1bRmmaudCFo6rtgtKGyugMyzBemGzVfnpoQIZPn+WHQfDJ2Rsu4OJ2PMf6 ILStXzz4o7pMsZSUv2LqqpG58GSMHSom9P/mDU40qQL0R887zeMey0TtZBH+DDqBmGdf8hJCeS r1j1R61aFGcA6hnpS8mKmxlODOpVqoYSOI0JjftaD8UPrI/2REd1ehIGQOKHMIcawzk2VuT0dj KXy1QEOWVoS8Ao9ysEal2HXBk+AI46q6RYmaXFe99K9P6+blPDQ3ZAIv/VLi7g0JLisYdyrrEO a7Y= X-IronPort-AV: E=Sophos;i="5.81,166,1610434800"; d="scan'208";a="106029120" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 09 Feb 2021 13:24:19 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Tue, 9 Feb 2021 13:24:19 -0700 Received: from soft-dev3.localdomain (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Tue, 9 Feb 2021 13:24:16 -0700 From: Horatiu Vultur To: , , , , , , , , , , , , , , CC: Horatiu Vultur Subject: [PATCH net-next v3 1/5] switchdev: mrp: Extend ring_role_mrp and in_role_mrp Date: Tue, 9 Feb 2021 21:21:08 +0100 Message-ID: <20210209202112.2545325-2-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210209202112.2545325-1-horatiu.vultur@microchip.com> References: <20210209202112.2545325-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add the member sw_backup to the structures switchdev_obj_ring_role_mrp and switchdev_obj_in_role_mrp. In this way the SW can call the driver in 2 ways, once when sw_backup is set to false, meaning that the driver should implement this completely in HW. And if that is not supported the SW will call again but with sw_backup set to true, meaning that the HW should help or allow the SW to run the protocol. For example when role is MRM, if the HW can't detect when it stops receiving MRP Test frames but it can trap these frames to CPU, then it needs to return -EOPNOTSUPP when sw_backup is false and return 0 when sw_backup is true. Signed-off-by: Horatiu Vultur --- include/net/switchdev.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/net/switchdev.h b/include/net/switchdev.h index 6dcfc4c51a6e..067f259279e1 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -130,6 +130,7 @@ struct switchdev_obj_ring_role_mrp { struct switchdev_obj obj; u8 ring_role; u32 ring_id; + u8 sw_backup; }; #define SWITCHDEV_OBJ_RING_ROLE_MRP(OBJ) \ @@ -164,6 +165,7 @@ struct switchdev_obj_in_role_mrp { u32 ring_id; u16 in_id; u8 in_role; + u8 sw_backup; }; #define SWITCHDEV_OBJ_IN_ROLE_MRP(OBJ) \ From patchwork Tue Feb 9 20:21:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Horatiu Vultur X-Patchwork-Id: 12079145 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 30AB0C433E0 for ; Tue, 9 Feb 2021 20:49:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0473864E6F for ; Tue, 9 Feb 2021 20:49:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233443AbhBIUtI (ORCPT ); Tue, 9 Feb 2021 15:49:08 -0500 Received: from esa.microchip.iphmx.com ([68.232.153.233]:54902 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233719AbhBIUfh (ORCPT ); Tue, 9 Feb 2021 15:35:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1612902936; x=1644438936; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EHLVPvUVJez21AH8PebxAXBSYM5AvLzTmtWmafYTWPs=; b=UCTir8jeHWWyumutCnlkXE1qxTYqOB7zWLvg5nhBDUIZEV+B0OwtgDDG EQzk2Xqupy7E/qa7/ZzVe1FU7wxn/xjiqlEOCkErCA3GZt8obxZyZRNyD Ct7bBW40XwmFpRqpGWocl5h4PkFo1Zmjni5r0Q1oK5oRJPKoA2GcDKdBz xYQLdxLrGDKPCfmbbjowMGT1FyFnJ3rX1GxANKmnujQsPka54O0Jw5aMd sNgbp/Wox8Zfcr0ld3rvzSH6Kgj9dQTZDxiMygOjZQUl06SvaUfQbDC0f Ww+AAL6G46FVkgcfSfvvVUf1Xn6pM6iBwfxAp3+115iY2zpRak4q9jac8 A==; IronPort-SDR: Oju202nIkkMU8pXEVI3BqXqb0RWdKUozUz5kt4tNCAFAd0J2XSBaRxcWdKWH6AIB6QwXo7p9nv IJ2b8Be5yRgZ1p+wxko5mTvhyuQ77QULLOgBSBS68lvPt0/A8/hjG0n0h2O/sRRGfgmb3Zf6oU r/VaFOWSeknhPem7dgzrcZnFNmE1llE6xEu+IVmhmFF/Zo2Nwj5jU37uuCuzJJYYh/elcGLQek JpqCTXTRK1/s4ywwO74fK8t7RGCOq5dV6TCnW04ZpJckOEG7fpbyc9NT6NAv5KvcuZs+Xw7Sk4 G+Y= X-IronPort-AV: E=Sophos;i="5.81,166,1610434800"; d="scan'208";a="114457590" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 09 Feb 2021 13:24:22 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Tue, 9 Feb 2021 13:24:22 -0700 Received: from soft-dev3.localdomain (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Tue, 9 Feb 2021 13:24:19 -0700 From: Horatiu Vultur To: , , , , , , , , , , , , , , CC: Horatiu Vultur Subject: [PATCH net-next v3 2/5] bridge: mrp: Add 'enum br_mrp_hw_support' Date: Tue, 9 Feb 2021 21:21:09 +0100 Message-ID: <20210209202112.2545325-3-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210209202112.2545325-1-horatiu.vultur@microchip.com> References: <20210209202112.2545325-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add the enum br_mrp_hw_support that is used by the br_mrp_switchdev functions to allow the SW to detect the cases where HW can't implement the functionality or when SW is used as a backup. Signed-off-by: Horatiu Vultur --- net/bridge/br_private_mrp.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/net/bridge/br_private_mrp.h b/net/bridge/br_private_mrp.h index 32a48e5418da..a94017f86cda 100644 --- a/net/bridge/br_private_mrp.h +++ b/net/bridge/br_private_mrp.h @@ -46,6 +46,20 @@ struct br_mrp { struct rcu_head rcu; }; +/* This type is returned by br_mrp_switchdev functions that allow to have a SW + * backup in case the HW can't implement completely the protocol. + * BR_MRP_NONE - means the HW can't run at all the protocol, so the SW stops + * configuring the node anymore. + * BR_MRP_SW - the HW can help the SW to run the protocol, by redirecting MRP + * frames to CPU. + * BR_MRP_HW - the HW can implement completely the protocol. + */ +enum br_mrp_hw_support { + BR_MRP_NONE, + BR_MRP_SW, + BR_MRP_HW, +}; + /* br_mrp.c */ int br_mrp_add(struct net_bridge *br, struct br_mrp_instance *instance); int br_mrp_del(struct net_bridge *br, struct br_mrp_instance *instance); From patchwork Tue Feb 9 20:21:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Horatiu Vultur X-Patchwork-Id: 12079143 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC1A7C433E0 for ; Tue, 9 Feb 2021 20:47:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A8A2664E6C for ; Tue, 9 Feb 2021 20:47:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233986AbhBIUrA (ORCPT ); Tue, 9 Feb 2021 15:47:00 -0500 Received: from esa.microchip.iphmx.com ([68.232.153.233]:34693 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233277AbhBIUgR (ORCPT ); Tue, 9 Feb 2021 15:36:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1612902977; x=1644438977; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=CKsk90s1Zwe7NmvCndD9QVFLL8JUzWHwEz1IrisAv3o=; b=TBoe3EEgzi3v64l5616vr7mhFONKoPUVKLKSDK/aJuZOtNA9PDvsqx2p Ct4Ku4U05DVlzsVZ8LuL2iSVLnxZVxxYQHP4ssFfri6IphIhKThgrkvkJ /PfY2QEwGYFsz3knbZnSE9BS6YHEI6LmMxS6aXYh1Nqjd0dPy9IY8WSuD FUcOovsydD+QECbSD42pk77G8HoULU4vMmZPQ/C1p9RloBY1cNxgdBFWn ZhuzPSnpVATX+TKNrzCMJpGU9xI6K4UfWxB0BAD8nWTkbnNRjrHT0VxMr Jqcpu8o188MXl5Fd3Op8h4x8oV8qpKIylMzpkuw+Ts+DhzJfMA6SxQKdS w==; IronPort-SDR: O3UxgYNutTnhtQNE3qsZTWxjV4Uxg628tpU8RNzMtyBIgmUnepk/LQRZn/5Tx+p+NPnmiiyoxX enb6AspEvLGHZGkTD7dVO136mseb+/0aRofs+10KINejSdsAP6WamZhzAo0cIQzO57WFNqQjQO Tsn9swvgBZMeUwUfm47Gjp1JY0COp0N6gQszTCWgzzertEGzTOE2ZMzGaNyUeS3gZ7q9J+qcU4 aTAFAXXARwpgSTCvOF5SUtolHT3bCeEMI8xuEZ0yemizipoXYWIreU6Q01r2/KH0aqwCo3+4bL Amo= X-IronPort-AV: E=Sophos;i="5.81,166,1610434800"; d="scan'208";a="114457597" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 09 Feb 2021 13:24:25 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Tue, 9 Feb 2021 13:24:25 -0700 Received: from soft-dev3.localdomain (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Tue, 9 Feb 2021 13:24:22 -0700 From: Horatiu Vultur To: , , , , , , , , , , , , , , CC: Horatiu Vultur Subject: [PATCH net-next v3 3/5] bridge: mrp: Extend br_mrp_switchdev to detect better the errors Date: Tue, 9 Feb 2021 21:21:10 +0100 Message-ID: <20210209202112.2545325-4-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210209202112.2545325-1-horatiu.vultur@microchip.com> References: <20210209202112.2545325-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This patch extends the br_mrp_switchdev functions to be able to have a better understanding what cause the issue and if the SW needs to be used as a backup. There are the following cases: - when the code is compiled without CONFIG_NET_SWITCHDEV. In this case return success so the SW can continue with the protocol. Depending on the function, it returns 0 or BR_MRP_SW. - when code is compiled with CONFIG_NET_SWITCHDEV and the driver doesn't implement any MRP callbacks. In this case the HW can't run MRP so it just returns -EOPNOTSUPP. So the SW will stop further to configure the node. - when code is compiled with CONFIG_NET_SWITCHDEV and the driver fully supports any MRP functionality. In this case the SW doesn't need to do anything. The functions will return 0 or BR_MRP_HW. - when code is compiled with CONFIG_NET_SWITCHDEV and the HW can't run completely the protocol but it can help the SW to run it. For example, the HW can't support completely MRM role(can't detect when it stops receiving MRP Test frames) but it can redirect these frames to CPU. In this case it is possible to have a SW fallback. The SW will try initially to call the driver with sw_backup set to false, meaning that the HW should implement completely the role. If the driver returns -EOPNOTSUPP, the SW will try again with sw_backup set to false, meaning that the SW will detect when it stops receiving the frames but it needs HW support to redirect the frames to CPU. In case the driver returns 0 then the SW will continue to configure the node accordingly. Signed-off-by: Horatiu Vultur --- net/bridge/br_mrp_switchdev.c | 171 +++++++++++++++++++++------------- net/bridge/br_private_mrp.h | 24 +++-- 2 files changed, 118 insertions(+), 77 deletions(-) diff --git a/net/bridge/br_mrp_switchdev.c b/net/bridge/br_mrp_switchdev.c index c971030adeea..8beb00827186 100644 --- a/net/bridge/br_mrp_switchdev.c +++ b/net/bridge/br_mrp_switchdev.c @@ -4,6 +4,30 @@ #include "br_private_mrp.h" +static enum br_mrp_hw_support +br_mrp_switchdev_port_obj(struct net_bridge *br, + const struct switchdev_obj *obj, bool add) +{ + int err; + + if (add) + err = switchdev_port_obj_add(br->dev, obj, NULL); + else + err = switchdev_port_obj_del(br->dev, obj); + + /* In case of success just return and notify the SW that doesn't need + * to do anything + */ + if (!err) + return BR_MRP_HW; + + if (err != -EOPNOTSUPP) + return BR_MRP_NONE; + + /* Continue with SW backup */ + return BR_MRP_SW; +} + int br_mrp_switchdev_add(struct net_bridge *br, struct br_mrp *mrp) { struct switchdev_obj_mrp mrp_obj = { @@ -14,14 +38,11 @@ int br_mrp_switchdev_add(struct net_bridge *br, struct br_mrp *mrp) .ring_id = mrp->ring_id, .prio = mrp->prio, }; - int err; - err = switchdev_port_obj_add(br->dev, &mrp_obj.obj, NULL); + if (!IS_ENABLED(CONFIG_NET_SWITCHDEV)) + return 0; - if (err && err != -EOPNOTSUPP) - return err; - - return 0; + return switchdev_port_obj_add(br->dev, &mrp_obj.obj, NULL); } int br_mrp_switchdev_del(struct net_bridge *br, struct br_mrp *mrp) @@ -33,40 +54,54 @@ int br_mrp_switchdev_del(struct net_bridge *br, struct br_mrp *mrp) .s_port = NULL, .ring_id = mrp->ring_id, }; - int err; - - err = switchdev_port_obj_del(br->dev, &mrp_obj.obj); - if (err && err != -EOPNOTSUPP) - return err; + if (!IS_ENABLED(CONFIG_NET_SWITCHDEV)) + return 0; - return 0; + return switchdev_port_obj_del(br->dev, &mrp_obj.obj); } -int br_mrp_switchdev_set_ring_role(struct net_bridge *br, - struct br_mrp *mrp, - enum br_mrp_ring_role_type role) +enum br_mrp_hw_support +br_mrp_switchdev_set_ring_role(struct net_bridge *br, struct br_mrp *mrp, + enum br_mrp_ring_role_type role) { struct switchdev_obj_ring_role_mrp mrp_role = { .obj.orig_dev = br->dev, .obj.id = SWITCHDEV_OBJ_ID_RING_ROLE_MRP, .ring_role = role, .ring_id = mrp->ring_id, + .sw_backup = false, }; + enum br_mrp_hw_support support; int err; - if (role == BR_MRP_RING_ROLE_DISABLED) - err = switchdev_port_obj_del(br->dev, &mrp_role.obj); - else + if (!IS_ENABLED(CONFIG_NET_SWITCHDEV)) + return BR_MRP_SW; + + support = br_mrp_switchdev_port_obj(br, &mrp_role.obj, + role != BR_MRP_RING_ROLE_DISABLED); + if (support != BR_MRP_SW) + return support; + + /* If the driver can't configure to run completely the protocol in HW, + * then try again to configure the HW so the SW can run the protocol. + */ + mrp_role.sw_backup = true; + if (role != BR_MRP_RING_ROLE_DISABLED) err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL); + else + err = switchdev_port_obj_del(br->dev, &mrp_role.obj); - return err; + if (!err) + return BR_MRP_SW; + + return BR_MRP_NONE; } -int br_mrp_switchdev_send_ring_test(struct net_bridge *br, - struct br_mrp *mrp, u32 interval, - u8 max_miss, u32 period, - bool monitor) +enum br_mrp_hw_support +br_mrp_switchdev_send_ring_test(struct net_bridge *br, struct br_mrp *mrp, + u32 interval, u8 max_miss, u32 period, + bool monitor) { struct switchdev_obj_ring_test_mrp test = { .obj.orig_dev = br->dev, @@ -77,14 +112,11 @@ int br_mrp_switchdev_send_ring_test(struct net_bridge *br, .period = period, .monitor = monitor, }; - int err; - if (interval == 0) - err = switchdev_port_obj_del(br->dev, &test.obj); - else - err = switchdev_port_obj_add(br->dev, &test.obj, NULL); + if (!IS_ENABLED(CONFIG_NET_SWITCHDEV)) + return BR_MRP_SW; - return err; + return br_mrp_switchdev_port_obj(br, &test.obj, interval != 0); } int br_mrp_switchdev_set_ring_state(struct net_bridge *br, @@ -97,19 +129,17 @@ int br_mrp_switchdev_set_ring_state(struct net_bridge *br, .ring_state = state, .ring_id = mrp->ring_id, }; - int err; - - err = switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL); - if (err && err != -EOPNOTSUPP) - return err; + if (!IS_ENABLED(CONFIG_NET_SWITCHDEV)) + return 0; - return 0; + return switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL); } -int br_mrp_switchdev_set_in_role(struct net_bridge *br, struct br_mrp *mrp, - u16 in_id, u32 ring_id, - enum br_mrp_in_role_type role) +enum br_mrp_hw_support +br_mrp_switchdev_set_in_role(struct net_bridge *br, struct br_mrp *mrp, + u16 in_id, u32 ring_id, + enum br_mrp_in_role_type role) { struct switchdev_obj_in_role_mrp mrp_role = { .obj.orig_dev = br->dev, @@ -118,15 +148,32 @@ int br_mrp_switchdev_set_in_role(struct net_bridge *br, struct br_mrp *mrp, .in_id = mrp->in_id, .ring_id = mrp->ring_id, .i_port = rtnl_dereference(mrp->i_port)->dev, + .sw_backup = false, }; + enum br_mrp_hw_support support; int err; - if (role == BR_MRP_IN_ROLE_DISABLED) - err = switchdev_port_obj_del(br->dev, &mrp_role.obj); - else + if (!IS_ENABLED(CONFIG_NET_SWITCHDEV)) + return BR_MRP_SW; + + support = br_mrp_switchdev_port_obj(br, &mrp_role.obj, + role != BR_MRP_IN_ROLE_DISABLED); + if (support != BR_MRP_NONE) + return support; + + /* If the driver can't configure to run completely the protocol in HW, + * then try again to configure the HW so the SW can run the protocol. + */ + mrp_role.sw_backup = true; + if (role != BR_MRP_IN_ROLE_DISABLED) err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL); + else + err = switchdev_port_obj_del(br->dev, &mrp_role.obj); + + if (!err) + return BR_MRP_SW; - return err; + return BR_MRP_NONE; } int br_mrp_switchdev_set_in_state(struct net_bridge *br, struct br_mrp *mrp, @@ -138,18 +185,16 @@ int br_mrp_switchdev_set_in_state(struct net_bridge *br, struct br_mrp *mrp, .in_state = state, .in_id = mrp->in_id, }; - int err; - - err = switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL); - if (err && err != -EOPNOTSUPP) - return err; + if (!IS_ENABLED(CONFIG_NET_SWITCHDEV)) + return 0; - return 0; + return switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL); } -int br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp, - u32 interval, u8 max_miss, u32 period) +enum br_mrp_hw_support +br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp, + u32 interval, u8 max_miss, u32 period) { struct switchdev_obj_in_test_mrp test = { .obj.orig_dev = br->dev, @@ -159,14 +204,11 @@ int br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp, .in_id = mrp->in_id, .period = period, }; - int err; - if (interval == 0) - err = switchdev_port_obj_del(br->dev, &test.obj); - else - err = switchdev_port_obj_add(br->dev, &test.obj, NULL); + if (!IS_ENABLED(CONFIG_NET_SWITCHDEV)) + return BR_MRP_SW; - return err; + return br_mrp_switchdev_port_obj(br, &test.obj, interval != 0); } int br_mrp_port_switchdev_set_state(struct net_bridge_port *p, @@ -177,14 +219,11 @@ int br_mrp_port_switchdev_set_state(struct net_bridge_port *p, .id = SWITCHDEV_ATTR_ID_PORT_STP_STATE, .u.stp_state = state, }; - int err; - err = switchdev_port_attr_set(p->dev, &attr); - if (err && err != -EOPNOTSUPP) - br_warn(p->br, "error setting offload MRP state on port %u(%s)\n", - (unsigned int)p->port_no, p->dev->name); + if (!IS_ENABLED(CONFIG_NET_SWITCHDEV)) + return 0; - return err; + return switchdev_port_attr_set(p->dev, &attr); } int br_mrp_port_switchdev_set_role(struct net_bridge_port *p, @@ -195,11 +234,9 @@ int br_mrp_port_switchdev_set_role(struct net_bridge_port *p, .id = SWITCHDEV_ATTR_ID_MRP_PORT_ROLE, .u.mrp_port_role = role, }; - int err; - err = switchdev_port_attr_set(p->dev, &attr); - if (err && err != -EOPNOTSUPP) - return err; + if (!IS_ENABLED(CONFIG_NET_SWITCHDEV)) + return 0; - return 0; + return switchdev_port_attr_set(p->dev, &attr); } diff --git a/net/bridge/br_private_mrp.h b/net/bridge/br_private_mrp.h index a94017f86cda..587a0381a6ce 100644 --- a/net/bridge/br_private_mrp.h +++ b/net/bridge/br_private_mrp.h @@ -79,24 +79,28 @@ int br_mrp_start_in_test(struct net_bridge *br, /* br_mrp_switchdev.c */ int br_mrp_switchdev_add(struct net_bridge *br, struct br_mrp *mrp); int br_mrp_switchdev_del(struct net_bridge *br, struct br_mrp *mrp); -int br_mrp_switchdev_set_ring_role(struct net_bridge *br, struct br_mrp *mrp, - enum br_mrp_ring_role_type role); +enum br_mrp_hw_support +br_mrp_switchdev_set_ring_role(struct net_bridge *br, struct br_mrp *mrp, + enum br_mrp_ring_role_type role); int br_mrp_switchdev_set_ring_state(struct net_bridge *br, struct br_mrp *mrp, enum br_mrp_ring_state_type state); -int br_mrp_switchdev_send_ring_test(struct net_bridge *br, struct br_mrp *mrp, - u32 interval, u8 max_miss, u32 period, - bool monitor); +enum br_mrp_hw_support +br_mrp_switchdev_send_ring_test(struct net_bridge *br, struct br_mrp *mrp, + u32 interval, u8 max_miss, u32 period, + bool monitor); int br_mrp_port_switchdev_set_state(struct net_bridge_port *p, enum br_mrp_port_state_type state); int br_mrp_port_switchdev_set_role(struct net_bridge_port *p, enum br_mrp_port_role_type role); -int br_mrp_switchdev_set_in_role(struct net_bridge *br, struct br_mrp *mrp, - u16 in_id, u32 ring_id, - enum br_mrp_in_role_type role); +enum br_mrp_hw_support +br_mrp_switchdev_set_in_role(struct net_bridge *br, struct br_mrp *mrp, + u16 in_id, u32 ring_id, + enum br_mrp_in_role_type role); int br_mrp_switchdev_set_in_state(struct net_bridge *br, struct br_mrp *mrp, enum br_mrp_in_state_type state); -int br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp, - u32 interval, u8 max_miss, u32 period); +enum br_mrp_hw_support +br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp, + u32 interval, u8 max_miss, u32 period); /* br_mrp_netlink.c */ int br_mrp_ring_port_open(struct net_device *dev, u8 loc); From patchwork Tue Feb 9 20:21:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Horatiu Vultur X-Patchwork-Id: 12079121 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 843C5C433E0 for ; Tue, 9 Feb 2021 20:40:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3BF4A61606 for ; Tue, 9 Feb 2021 20:40:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233760AbhBIUjl (ORCPT ); Tue, 9 Feb 2021 15:39:41 -0500 Received: from esa.microchip.iphmx.com ([68.232.153.233]:34880 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233411AbhBIUeN (ORCPT ); Tue, 9 Feb 2021 15:34:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1612902853; x=1644438853; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=f5geSd6pjJ0N+Fxoxpo/NSh5XSs8UlW8frZ6CCHDsDY=; b=L5zw6VaxyCO03PJPXAM/3V5H4FsbriL1MPeBthDPH+HTUVnl10S6VjMt B4nHv33LOq+e0pqcd41wHoPa4Ot5tFvq30+y7eACJ/0VW4jZ92hMPGWds poP5yfo8p9KsuLASuc5QmCMSPIiWVURGLP80AgrlYgX1zaWZCmoyaXLCR er/BRJXF/B8o0lqpUQBnqtAjPWy+wgyEW1AxjcMIGTyopHRAaTnvhGvSb p7Gr3pAuEavXAQcdjUDmf3d5Ov0FaeHHhZ6I4lGSW9/zSkL1D+GEClRpY SPKwplC2ZxFdPUJc5yAaw6SJJPmqNnEcBus8U/tvmMmQQVTPv8tgi/yWr g==; IronPort-SDR: oAzYc2gSFMk/b3LcYlV1yCKJ5eMZjxn88O3euNs+Xuzsce+73MAuOtAXScZv4ygidJSfnUXHAO cr6PW60VdRhN3xqdV6t+cuhm2/Cz58szCawN8CsmHBJamz6MstvYHPD6aV+pQOPTyvnOxGok2S ry9p9K4inhYtfPM83USNvoDpCMOy0lQFeGPDm9m9fKluIVSaCnymMBpxsyINgUkm1UJiHcQWV5 x1u9rRNLG24Ha5TU0CJQLlma5t4K7adRTEjglfRmmeAp2t+2NS6IAzeIq69VsMFCa0uM6UV4JR 07c= X-IronPort-AV: E=Sophos;i="5.81,166,1610434800"; d="scan'208";a="114457601" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 09 Feb 2021 13:24:29 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Tue, 9 Feb 2021 13:24:28 -0700 Received: from soft-dev3.localdomain (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Tue, 9 Feb 2021 13:24:25 -0700 From: Horatiu Vultur To: , , , , , , , , , , , , , , CC: Horatiu Vultur Subject: [PATCH net-next v3 4/5] bridge: mrp: Update br_mrp to use new return values of br_mrp_switchdev Date: Tue, 9 Feb 2021 21:21:11 +0100 Message-ID: <20210209202112.2545325-5-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210209202112.2545325-1-horatiu.vultur@microchip.com> References: <20210209202112.2545325-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Check the return values of the br_mrp_switchdev function. In case of: - BR_MRP_NONE, return the error to userspace, - BR_MRP_SW, continue with SW implementation, - BR_MRP_HW, continue without SW implementation, Signed-off-by: Horatiu Vultur --- net/bridge/br_mrp.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/net/bridge/br_mrp.c b/net/bridge/br_mrp.c index 01c67ed727a9..12487f6fe9b4 100644 --- a/net/bridge/br_mrp.c +++ b/net/bridge/br_mrp.c @@ -639,7 +639,7 @@ int br_mrp_set_ring_role(struct net_bridge *br, struct br_mrp_ring_role *role) { struct br_mrp *mrp = br_mrp_find_id(br, role->ring_id); - int err; + enum br_mrp_hw_support support; if (!mrp) return -EINVAL; @@ -647,9 +647,9 @@ int br_mrp_set_ring_role(struct net_bridge *br, mrp->ring_role = role->ring_role; /* If there is an error just bailed out */ - err = br_mrp_switchdev_set_ring_role(br, mrp, role->ring_role); - if (err && err != -EOPNOTSUPP) - return err; + support = br_mrp_switchdev_set_ring_role(br, mrp, role->ring_role); + if (support == BR_MRP_NONE) + return -EOPNOTSUPP; /* Now detect if the HW actually applied the role or not. If the HW * applied the role it means that the SW will not to do those operations @@ -657,7 +657,7 @@ int br_mrp_set_ring_role(struct net_bridge *br, * SW when ring is open, but if the is not pushed to the HW the SW will * need to detect when the ring is open */ - mrp->ring_role_offloaded = err == -EOPNOTSUPP ? 0 : 1; + mrp->ring_role_offloaded = support == BR_MRP_SW ? 0 : 1; return 0; } @@ -670,6 +670,7 @@ int br_mrp_start_test(struct net_bridge *br, struct br_mrp_start_test *test) { struct br_mrp *mrp = br_mrp_find_id(br, test->ring_id); + enum br_mrp_hw_support support; if (!mrp) return -EINVAL; @@ -677,9 +678,13 @@ int br_mrp_start_test(struct net_bridge *br, /* Try to push it to the HW and if it fails then continue with SW * implementation and if that also fails then return error. */ - if (!br_mrp_switchdev_send_ring_test(br, mrp, test->interval, - test->max_miss, test->period, - test->monitor)) + support = br_mrp_switchdev_send_ring_test(br, mrp, test->interval, + test->max_miss, test->period, + test->monitor); + if (support == BR_MRP_NONE) + return -EOPNOTSUPP; + + if (support == BR_MRP_HW) return 0; mrp->test_interval = test->interval; @@ -721,8 +726,8 @@ int br_mrp_set_in_state(struct net_bridge *br, struct br_mrp_in_state *state) int br_mrp_set_in_role(struct net_bridge *br, struct br_mrp_in_role *role) { struct br_mrp *mrp = br_mrp_find_id(br, role->ring_id); + enum br_mrp_hw_support support; struct net_bridge_port *p; - int err; if (!mrp) return -EINVAL; @@ -780,10 +785,10 @@ int br_mrp_set_in_role(struct net_bridge *br, struct br_mrp_in_role *role) mrp->in_id = role->in_id; /* If there is an error just bailed out */ - err = br_mrp_switchdev_set_in_role(br, mrp, role->in_id, - role->ring_id, role->in_role); - if (err && err != -EOPNOTSUPP) - return err; + support = br_mrp_switchdev_set_in_role(br, mrp, role->in_id, + role->ring_id, role->in_role); + if (support == BR_MRP_NONE) + return -EOPNOTSUPP; /* Now detect if the HW actually applied the role or not. If the HW * applied the role it means that the SW will not to do those operations @@ -791,7 +796,7 @@ int br_mrp_set_in_role(struct net_bridge *br, struct br_mrp_in_role *role) * SW when interconnect ring is open, but if the is not pushed to the HW * the SW will need to detect when the interconnect ring is open. */ - mrp->in_role_offloaded = err == -EOPNOTSUPP ? 0 : 1; + mrp->in_role_offloaded = support == BR_MRP_SW ? 0 : 1; return 0; } @@ -804,6 +809,7 @@ int br_mrp_start_in_test(struct net_bridge *br, struct br_mrp_start_in_test *in_test) { struct br_mrp *mrp = br_mrp_find_in_id(br, in_test->in_id); + enum br_mrp_hw_support support; if (!mrp) return -EINVAL; @@ -814,8 +820,13 @@ int br_mrp_start_in_test(struct net_bridge *br, /* Try to push it to the HW and if it fails then continue with SW * implementation and if that also fails then return error. */ - if (!br_mrp_switchdev_send_in_test(br, mrp, in_test->interval, - in_test->max_miss, in_test->period)) + support = br_mrp_switchdev_send_in_test(br, mrp, in_test->interval, + in_test->max_miss, + in_test->period); + if (support == BR_MRP_NONE) + return -EOPNOTSUPP; + + if (support == BR_MRP_HW) return 0; mrp->in_test_interval = in_test->interval; From patchwork Tue Feb 9 20:21:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Horatiu Vultur X-Patchwork-Id: 12079129 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E007BC433E0 for ; Tue, 9 Feb 2021 20:44:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8B02364E70 for ; Tue, 9 Feb 2021 20:44:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233967AbhBIUoD (ORCPT ); Tue, 9 Feb 2021 15:44:03 -0500 Received: from esa.microchip.iphmx.com ([68.232.154.123]:16803 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233683AbhBIUfi (ORCPT ); Tue, 9 Feb 2021 15:35:38 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1612902937; x=1644438937; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QtwOaRIv2PtLKpYjgqSxl18uh6l2sLduk/xVC1keVzM=; b=fGa39mLvx7Bv6MckgjHSZ6Uc2p1ezIWNd0mkBV6r8LcGhAuYOJcMetWi Rmv9I0HZwFUADCvMywB4tRzkbsx2WFks1WGlNKgpNfz3GwPBQCD25fagn O6EgXIaQLu+QZOtBQ2kqMHNVwkpXWfELL/e0H66gsXd2xauOvkurQddz/ xYtu+6RK0MU6eeAGY1No7zzC1lXZEYt8qPML8EoP2DixV3j6Yf3cTQE3r I018F6a7bk6ZwmArwCh3KDkklKDX8QRH0Kpabhn2XVlILclu9vVG99w9U A8uwcm1tkATyvQRkxv7oVVCP75iWGfDT/QlSc0bIDbEr+9zyQPeIgPR7e w==; IronPort-SDR: Vb7Um2pEoBO0QCEow2JZpz8BURFdA7gAH6j8HEmiPnJ8nikSWUtG9fgHUO0e7VaWUeXW0e2hry ZQ4aWdiwZkGZGjfCc4v6tp3Pf84njJikaX0chnV63eKgVMFxNGGPEsqpmwwGPsQiTFz4/eeJ2v nVMqn7FM4VtqOuSmN+MisxMpM/nZPoa5gteOBCh47cyshK8IoOqztFS1KpNXbDFM/DUEoibj+1 TgaTC4Zt4kcnYAS3skQxlN15mNKRbgYSCYQfCKSDPc50a1fti9zN+j/WQ5Ofxf3ESvYH4Q0Lmc Z4c= X-IronPort-AV: E=Sophos;i="5.81,166,1610434800"; d="scan'208";a="43538545" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 09 Feb 2021 13:24:36 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Tue, 9 Feb 2021 13:24:32 -0700 Received: from soft-dev3.localdomain (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Tue, 9 Feb 2021 13:24:29 -0700 From: Horatiu Vultur To: , , , , , , , , , , , , , , CC: Horatiu Vultur Subject: [PATCH net-next v3 5/5] net: mscc: ocelot: Add support for MRP Date: Tue, 9 Feb 2021 21:21:12 +0100 Message-ID: <20210209202112.2545325-6-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210209202112.2545325-1-horatiu.vultur@microchip.com> References: <20210209202112.2545325-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add basic support for MRP. The HW will just trap all MRP frames on the ring ports to CPU and allow the SW to process them. In this way it is possible to for this node to behave both as MRM and MRC. Current limitations are: - it doesn't support Interconnect roles. - it supports only a single ring. - the HW should be able to do forwarding of MRP Test frames so the SW will not need to do this. So it would be able to have the role MRC without SW support. Signed-off-by: Horatiu Vultur --- drivers/net/ethernet/mscc/ocelot_net.c | 154 +++++++++++++++++++++ drivers/net/ethernet/mscc/ocelot_vsc7514.c | 6 + include/soc/mscc/ocelot.h | 6 + 3 files changed, 166 insertions(+) diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 8f12fa45b1b5..65971403e823 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -9,7 +9,10 @@ */ #include +#include #include +#include +#include #include "ocelot.h" #include "ocelot_vcap.h" @@ -1069,6 +1072,139 @@ static int ocelot_port_obj_del_mdb(struct net_device *dev, return ocelot_port_mdb_del(ocelot, port, mdb); } +#if IS_ENABLED(CONFIG_BRIDGE_MRP) +static int ocelot_mrp_del_vcap(struct ocelot *ocelot, int port) +{ + struct ocelot_vcap_block *block_vcap_is2; + struct ocelot_vcap_filter *filter; + + block_vcap_is2 = &ocelot->block[VCAP_IS2]; + filter = ocelot_vcap_block_find_filter_by_id(block_vcap_is2, port, + false); + if (!filter) + return 0; + + return ocelot_vcap_filter_del(ocelot, filter); +} + +static int ocelot_add_mrp(struct net_device *dev, + const struct switchdev_obj_mrp *mrp) +{ + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; + struct ocelot *ocelot = ocelot_port->ocelot; + + if (mrp->p_port != dev && mrp->s_port != dev) + return 0; + + if (ocelot->mrp_ring_id != 0 && + ocelot->mrp_s_port && + ocelot->mrp_p_port) + return -EINVAL; + + if (mrp->p_port == dev) + ocelot->mrp_p_port = dev; + + if (mrp->s_port == dev) + ocelot->mrp_s_port = dev; + + ocelot->mrp_ring_id = mrp->ring_id; + + return 0; +} + +static int ocelot_del_mrp(struct net_device *dev, + const struct switchdev_obj_mrp *mrp) +{ + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; + struct ocelot *ocelot = ocelot_port->ocelot; + + if (ocelot->mrp_p_port != dev && ocelot->mrp_s_port != dev) + return 0; + + if (ocelot->mrp_ring_id == 0 && + !ocelot->mrp_s_port && + !ocelot->mrp_p_port) + return -EINVAL; + + if (ocelot_mrp_del_vcap(ocelot, priv->chip_port)) + return -EINVAL; + + if (ocelot->mrp_p_port == dev) + ocelot->mrp_p_port = NULL; + + if (ocelot->mrp_s_port == dev) + ocelot->mrp_s_port = NULL; + + ocelot->mrp_ring_id = 0; + + return 0; +} + +static int ocelot_add_ring_role(struct net_device *dev, + const struct switchdev_obj_ring_role_mrp *mrp) +{ + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; + struct ocelot *ocelot = ocelot_port->ocelot; + struct ocelot_vcap_filter *filter; + int err; + + if (ocelot->mrp_ring_id != mrp->ring_id) + return -EINVAL; + + if (!mrp->sw_backup) + return -EOPNOTSUPP; + + if (ocelot->mrp_p_port != dev && ocelot->mrp_s_port != dev) + return 0; + + filter = kzalloc(sizeof(*filter), GFP_KERNEL); + if (!filter) + return -ENOMEM; + + filter->key_type = OCELOT_VCAP_KEY_ETYPE; + filter->prio = 1; + filter->id.cookie = priv->chip_port; + filter->id.tc_offload = false; + filter->block_id = VCAP_IS2; + filter->type = OCELOT_VCAP_FILTER_OFFLOAD; + filter->ingress_port_mask = BIT(priv->chip_port); + *(__be16 *)filter->key.etype.etype.value = htons(ETH_P_MRP); + *(__be16 *)filter->key.etype.etype.mask = htons(0xffff); + filter->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY; + filter->action.port_mask = 0x0; + filter->action.cpu_copy_ena = true; + filter->action.cpu_qu_num = 0; + + err = ocelot_vcap_filter_add(ocelot, filter, NULL); + if (err) + kfree(filter); + + return err; +} + +static int ocelot_del_ring_role(struct net_device *dev, + const struct switchdev_obj_ring_role_mrp *mrp) +{ + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; + struct ocelot *ocelot = ocelot_port->ocelot; + + if (ocelot->mrp_ring_id != mrp->ring_id) + return -EINVAL; + + if (!mrp->sw_backup) + return -EOPNOTSUPP; + + if (ocelot->mrp_p_port != dev && ocelot->mrp_s_port != dev) + return 0; + + return ocelot_mrp_del_vcap(ocelot, priv->chip_port); +} +#endif + static int ocelot_port_obj_add(struct net_device *dev, const struct switchdev_obj *obj, struct netlink_ext_ack *extack) @@ -1083,6 +1219,15 @@ static int ocelot_port_obj_add(struct net_device *dev, case SWITCHDEV_OBJ_ID_PORT_MDB: ret = ocelot_port_obj_add_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj)); break; +#if IS_ENABLED(CONFIG_BRIDGE_MRP) + case SWITCHDEV_OBJ_ID_MRP: + ret = ocelot_add_mrp(dev, SWITCHDEV_OBJ_MRP(obj)); + break; + case SWITCHDEV_OBJ_ID_RING_ROLE_MRP: + ret = ocelot_add_ring_role(dev, + SWITCHDEV_OBJ_RING_ROLE_MRP(obj)); + break; +#endif default: return -EOPNOTSUPP; } @@ -1103,6 +1248,15 @@ static int ocelot_port_obj_del(struct net_device *dev, case SWITCHDEV_OBJ_ID_PORT_MDB: ret = ocelot_port_obj_del_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj)); break; +#if IS_ENABLED(CONFIG_BRIDGE_MRP) + case SWITCHDEV_OBJ_ID_MRP: + ret = ocelot_del_mrp(dev, SWITCHDEV_OBJ_MRP(obj)); + break; + case SWITCHDEV_OBJ_ID_RING_ROLE_MRP: + ret = ocelot_del_ring_role(dev, + SWITCHDEV_OBJ_RING_ROLE_MRP(obj)); + break; +#endif default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/mscc/ocelot_vsc7514.c b/drivers/net/ethernet/mscc/ocelot_vsc7514.c index 6b6eb92149ba..96a9c9f98060 100644 --- a/drivers/net/ethernet/mscc/ocelot_vsc7514.c +++ b/drivers/net/ethernet/mscc/ocelot_vsc7514.c @@ -698,6 +698,12 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg) skb->offload_fwd_mark = 1; skb->protocol = eth_type_trans(skb, dev); +#if IS_ENABLED(CONFIG_BRIDGE_MRP) + if (skb->protocol == ntohs(ETH_P_MRP) && + (priv->dev == ocelot->mrp_p_port || + priv->dev == ocelot->mrp_s_port)) + skb->offload_fwd_mark = 0; +#endif if (!skb_defer_rx_timestamp(skb)) netif_rx(skb); dev->stats.rx_bytes += len; diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index d0d48e9620fb..d95c019ad84e 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -682,6 +682,12 @@ struct ocelot { /* Protects the PTP clock */ spinlock_t ptp_clock_lock; struct ptp_pin_desc ptp_pins[OCELOT_PTP_PINS_NUM]; + +#if IS_ENABLED(CONFIG_BRIDGE_MRP) + u16 mrp_ring_id; + struct net_device *mrp_p_port; + struct net_device *mrp_s_port; +#endif }; struct ocelot_policer {