From patchwork Wed Nov 17 21:04:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625413 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E3F7C433EF for ; Wed, 17 Nov 2021 21:05:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EB00261BFA for ; Wed, 17 Nov 2021 21:05:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240350AbhKQVI0 (ORCPT ); Wed, 17 Nov 2021 16:08:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34948 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240391AbhKQVIS (ORCPT ); Wed, 17 Nov 2021 16:08:18 -0500 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6095EC061570; Wed, 17 Nov 2021 13:05:19 -0800 (PST) Received: by mail-ed1-x533.google.com with SMTP id e3so16990288edu.4; Wed, 17 Nov 2021 13:05:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Moo6C6ux3Max+74jfwWrTQaUIS07OsmKfAQTULmbues=; b=oxNuq3iaqHNFEvebZeULCPIkxAZqRtvK1AkgC3Ma+PPCZEC9JJ1pruVdLcZZDp7YmS UH7fD+ZRjIlvohXHSTfDW+VNm5zW26t2LBOFqqzUKTHZvOLJYVjO8/OizFj1nA2khY/z uLZNOW5L7iIxCDMpA9mKgRmrC687mImv1R+vzXT55lKWCs8Pd9PepAjPCcTiybhNbZ6E 1Oka6kkP3LOITU/bMJiA8DosFbaHGn13sYeM9v9fjQRU8fvybaYiskXd5gH4iWSUG2wf ysIKsv4cP06LbFQ+JIpdHPFvgo4t+Yc+sM0OY0mf9RJNmgCFMcqTyt2T13me5hMlXVeF p8yQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Moo6C6ux3Max+74jfwWrTQaUIS07OsmKfAQTULmbues=; b=csZd8dBPn1buGrjsfEhyJMYw+vaQ1ge8s3deZtJGC48wlJtNLpCUIaaNOvLyQ507+a QCJ4KKL6151B5bc76RSacAS9Wp4ap2X8kfKKmLc0Rty0HMfquA9Y7KmzDCafME34Jqho Tic3yp26dYims+58Xa2ihRb3RrGuzxhIxUhrFZsRs/8BQ0usD/G9x9jbRBJqf5GkmDAW mhkooyam1SONjyN/L++l9Vb45QoxDVo0bQeMZogCX9nVMxIQa4imJP/d7vgTSUxWueXD QwQ4WRlEwcwUgWrBGLnamVOaOQEs6NjXWRBVNO1pGsiYqakStAh+uxLtD0JTXfthHmDY vu1g== X-Gm-Message-State: AOAM533fUCOzTS+w3LTpSBd7iAlxMgJ8iCDXryfcthGQy3SGvuAZZukJ zjFGmRLkS0cvY6wYg09iK+g= X-Google-Smtp-Source: ABdhPJzkDuTqDHeE4UME6g9rnaR3ooTieU2fHLNozwyxHqcsDBA00FSjg89N8GMr/xEJfAMgY42ayg== X-Received: by 2002:a17:907:2622:: with SMTP id aq2mr25873180ejc.76.1637183117881; Wed, 17 Nov 2021 13:05:17 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:17 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Cc: kernel test robot , Dan Carpenter Subject: [net-next PATCH 02/19] net: dsa: qca8k: remove redundant check in parse_port_config Date: Wed, 17 Nov 2021 22:04:34 +0100 Message-Id: <20211117210451.26415-3-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The very next check for port 0 and 6 already make sure we don't go out of bounds with the ports_config delay table. Remove the redundant check. Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Ansuel Smith Reviewed-by: Vladimir Oltean --- drivers/net/dsa/qca8k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index a429c9750add..bfffc1fb7016 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -983,7 +983,7 @@ qca8k_parse_port_config(struct qca8k_priv *priv) u32 delay; /* We have 2 CPU port. Check them */ - for (port = 0; port < QCA8K_NUM_PORTS && cpu_port_index < QCA8K_NUM_CPU_PORTS; port++) { + for (port = 0; port < QCA8K_NUM_PORTS; port++) { /* Skip every other port */ if (port != 0 && port != 6) continue; From patchwork Wed Nov 17 21:04:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625415 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2A84C4332F for ; Wed, 17 Nov 2021 21:05:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7F72361BFB for ; Wed, 17 Nov 2021 21:05:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240392AbhKQVI2 (ORCPT ); Wed, 17 Nov 2021 16:08:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34950 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240718AbhKQVIT (ORCPT ); Wed, 17 Nov 2021 16:08:19 -0500 Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B302C061570; Wed, 17 Nov 2021 13:05:20 -0800 (PST) Received: by mail-ed1-x530.google.com with SMTP id y12so16882715eda.12; Wed, 17 Nov 2021 13:05:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=BUclrFJvY/lUooQxWpEiWnhLCpexSSSJJKHmSzu8+8M=; b=G4FOrIxLDcG5g/+ifJR9ROmuXQJONFOHzIBWfTY35HN0yTuk7MvZ4qG3pdj4DNV0u0 yJfA2lf6ZHszRpRbso9KBQJTXLvZP+/0OQMs96FS+m3VxmJYkfot38uj1ivQ/ArVm2RH 1n2RQtOukGROnwFuFXjwjCwI6HRVp6EC0cNgBiVxClFUtZjkn4nXcASllwjMYSxTYQy9 b7bchuTVYZl3VTtXi6CVCiLwClz+8oBKK8dsbCfBh1NshTbF2ORlzSpiXG54GFUGGdXm ADqEV9tizDnvQnexwfC1ey/65YWuFrujz3sJAUYpjau38P2CS6VaCY031jxaY6+kAIBp pExw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BUclrFJvY/lUooQxWpEiWnhLCpexSSSJJKHmSzu8+8M=; b=Ai9q98Vaq0ZWj75Zdpd6eHVdlnR1m/Jd+NXeTvslNSPn2q+SigGyPSbZXvaFa3E2Oc fp3bE993jAkmr1vQWAnffbCqz6PXkdHK5qCs36ApmX+851tryStCQbY2+ZYbfJ2Wrwd/ IJX7N1kzprV8IoWskQfEYAxgMgeAG+5i2oervLVCAQp+c/RIOwJs+ZWgSsjB9guoBFCm iZHQZp7qmQVsd7U/cXOQ/K0KJ0nOOgVhmgdUrkHE76E49v8ctmeu/5Y3huD8ygnmgGHh 4pdFuC9K1QfvoFWvwQCOO7QC5NW/Qu+KBkDHYxB1tP3Aq/vCmyZfkF/g2AaiuixA5QP3 LQLQ== X-Gm-Message-State: AOAM5302Fi3JtwTr/WqFm8BqOFv+DP7Z9xCOpfDYxGq3Uiw5zwscqfTd 8lytsGiXv5MGIWV1uRGdj6E= X-Google-Smtp-Source: ABdhPJxgwUPA8roxtM+Qu96hbrOA/Ov9ydrK4flHLMGbbfFsibcwZtiWGZ+O4Q8Uk23sLKL1lCVmiQ== X-Received: by 2002:a05:6402:50c7:: with SMTP id h7mr2617464edb.277.1637183118833; Wed, 17 Nov 2021 13:05:18 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:18 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 03/19] net: dsa: qca8k: skip sgmii delay on double cpu conf Date: Wed, 17 Nov 2021 22:04:35 +0100 Message-Id: <20211117210451.26415-4-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org With a dual cpu configuration rgmii+sgmii, skip configuring sgmii delay as it does cause no traffic. Configure only rgmii delay in this specific configuration. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 12 ++++++++++-- drivers/net/dsa/qca8k.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index bfffc1fb7016..ace465c878f8 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1041,8 +1041,13 @@ qca8k_parse_port_config(struct qca8k_priv *priv) if (mode == PHY_INTERFACE_MODE_RGMII || mode == PHY_INTERFACE_MODE_RGMII_ID || mode == PHY_INTERFACE_MODE_RGMII_TXID || - mode == PHY_INTERFACE_MODE_RGMII_RXID) + mode == PHY_INTERFACE_MODE_RGMII_RXID) { + if (priv->ports_config.rgmii_tx_delay[cpu_port_index] || + priv->ports_config.rgmii_rx_delay[cpu_port_index]) + priv->ports_config.skip_sgmii_delay = true; + break; + } if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) priv->ports_config.sgmii_tx_clk_falling_edge = true; @@ -1457,8 +1462,11 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, /* From original code is reported port instability as SGMII also * require delay set. Apply advised values here or take them from DT. + * In dual CPU configuration, apply only delay to rgmii as applying + * it also to the SGMII line cause no traffic to the entire switch. */ - if (state->interface == PHY_INTERFACE_MODE_SGMII) + if (state->interface == PHY_INTERFACE_MODE_SGMII && + !priv->ports_config.skip_sgmii_delay) qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); break; diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h index 128b8cf85e08..57c4c0d93558 100644 --- a/drivers/net/dsa/qca8k.h +++ b/drivers/net/dsa/qca8k.h @@ -275,6 +275,7 @@ struct qca8k_ports_config { bool sgmii_rx_clk_falling_edge; bool sgmii_tx_clk_falling_edge; bool sgmii_enable_pll; + bool skip_sgmii_delay; u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ }; From patchwork Wed Nov 17 21:04:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625417 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6984EC433F5 for ; Wed, 17 Nov 2021 21:05:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4D3CC6324B for ; Wed, 17 Nov 2021 21:05:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240726AbhKQVIa (ORCPT ); Wed, 17 Nov 2021 16:08:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34960 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235596AbhKQVIU (ORCPT ); Wed, 17 Nov 2021 16:08:20 -0500 Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 50B72C061570; Wed, 17 Nov 2021 13:05:21 -0800 (PST) Received: by mail-ed1-x530.google.com with SMTP id g14so17045584edz.2; Wed, 17 Nov 2021 13:05:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=oHAKsoBLDGcpEFSvnNYhU8xpjqPL3oa8ppZOYNkAugI=; b=jBa+xa5euwjbom15k9mXfXiDQilj1wmdUeAwAnpLrxH079OxWgSBnVNubfRNMGeQmI +mocCiyrAjOoR8h0eD7ayN25glf8RQXkLADx4uC5eTuUZ1eo/2zIJHTCKMUAwW7gqFMO eR5cIx7OPh9na9/hgUqN0Of69x/hxPyp7q+KoRCe517rPZcnz82UIPTbzyYB3ZF6E/d+ 9gNA7AqTwuNgICFV5eSDXZeoIkgrR3KQrUkcjJjWLEoUVtIqEaVIJdwdG71aJjd/KCR7 Jn30txXoguqJibh0AflLpFYqt858mHZ0LJ1/XuplP1c45PTX4s9hG9PoSfYemSAH2T0h LjZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oHAKsoBLDGcpEFSvnNYhU8xpjqPL3oa8ppZOYNkAugI=; b=7jEZab7++uncbbvotx3VgaWHck68TKtKI/3MO19uNcbjJg0OdMPuj7JPSwLZTKvQe0 T9HpFxIgZqK0UjZeSJrr0W5L7a3HAhwREeYA7Jx3L2V72eg93ES+7LcfH3ISdudkDt3k UBiBO1P3d9klN20uSVuSxevj5lQ5hYuPqjgKzcqWSy3B1HjZw3nQs4oNF1fIzd+I6ELk jksugNpNsRZhbIBA+IluhrBcjGL4HyLHVt333EMDKuuHCN6GQGbVduMYwKgWK5qHlhfv 5kUkkrGiu8mNwAxxufwzCxogxkdZ+u3GeTSkY3ZFldLP7Bo2/mdLZVzFtk4IS6snVCh1 GK7w== X-Gm-Message-State: AOAM532s6EvXq6MiLfw8UNu0xarFnrJXUGSGn3NE7YIfWZq3DffQvlgA OK4vkCGobzrNHezwdFpnWHzXFiEAhOY= X-Google-Smtp-Source: ABdhPJyS7a/9/J05+nKRtqSBgRbxGlFvWGj/fYgk9XXjIEyWnSjl2BVbsw7bfHpnPXawXUf6US25Vg== X-Received: by 2002:a17:906:6b13:: with SMTP id q19mr25728945ejr.221.1637183119722; Wed, 17 Nov 2021 13:05:19 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:19 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 04/19] net: dsa: qca8k: convert to GENMASK/FIELD_PREP/FIELD_GET Date: Wed, 17 Nov 2021 22:04:36 +0100 Message-Id: <20211117210451.26415-5-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Convert and try to standardize bit fields using GENMASK/FIELD_PREP/FIELD_GET macros. Rework some logic to support the standard macro and tidy things up. No functional change intended. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 98 ++++++++++++------------- drivers/net/dsa/qca8k.h | 153 ++++++++++++++++++++++------------------ 2 files changed, 130 insertions(+), 121 deletions(-) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index ace465c878f8..19331edf1fd4 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -319,18 +320,18 @@ qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) } /* vid - 83:72 */ - fdb->vid = (reg[2] >> QCA8K_ATU_VID_S) & QCA8K_ATU_VID_M; + fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); /* aging - 67:64 */ - fdb->aging = reg[2] & QCA8K_ATU_STATUS_M; + fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); /* portmask - 54:48 */ - fdb->port_mask = (reg[1] >> QCA8K_ATU_PORT_S) & QCA8K_ATU_PORT_M; + fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); /* mac - 47:0 */ - fdb->mac[0] = (reg[1] >> QCA8K_ATU_ADDR0_S) & 0xff; - fdb->mac[1] = reg[1] & 0xff; - fdb->mac[2] = (reg[0] >> QCA8K_ATU_ADDR2_S) & 0xff; - fdb->mac[3] = (reg[0] >> QCA8K_ATU_ADDR3_S) & 0xff; - fdb->mac[4] = (reg[0] >> QCA8K_ATU_ADDR4_S) & 0xff; - fdb->mac[5] = reg[0] & 0xff; + fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); + fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); + fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); + fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); + fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); + fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); return 0; } @@ -343,18 +344,18 @@ qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, int i; /* vid - 83:72 */ - reg[2] = (vid & QCA8K_ATU_VID_M) << QCA8K_ATU_VID_S; + reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); /* aging - 67:64 */ - reg[2] |= aging & QCA8K_ATU_STATUS_M; + reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); /* portmask - 54:48 */ - reg[1] = (port_mask & QCA8K_ATU_PORT_M) << QCA8K_ATU_PORT_S; + reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); /* mac - 47:0 */ - reg[1] |= mac[0] << QCA8K_ATU_ADDR0_S; - reg[1] |= mac[1]; - reg[0] |= mac[2] << QCA8K_ATU_ADDR2_S; - reg[0] |= mac[3] << QCA8K_ATU_ADDR3_S; - reg[0] |= mac[4] << QCA8K_ATU_ADDR4_S; - reg[0] |= mac[5]; + reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); + reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); /* load the array into the ARL table */ for (i = 0; i < 3; i++) @@ -372,7 +373,7 @@ qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) reg |= cmd; if (port >= 0) { reg |= QCA8K_ATU_FUNC_PORT_EN; - reg |= (port & QCA8K_ATU_FUNC_PORT_M) << QCA8K_ATU_FUNC_PORT_S; + reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); } /* Write the function register triggering the table access */ @@ -454,7 +455,7 @@ qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) /* Set the command and VLAN index */ reg = QCA8K_VTU_FUNC1_BUSY; reg |= cmd; - reg |= vid << QCA8K_VTU_FUNC1_VID_S; + reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); /* Write the function register triggering the table access */ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); @@ -500,13 +501,11 @@ qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) if (ret < 0) goto out; reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; - reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port)); + reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); if (untagged) - reg |= QCA8K_VTU_FUNC0_EG_MODE_UNTAG << - QCA8K_VTU_FUNC0_EG_MODE_S(port); + reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); else - reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG << - QCA8K_VTU_FUNC0_EG_MODE_S(port); + reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); if (ret) @@ -534,15 +533,13 @@ qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); if (ret < 0) goto out; - reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port)); - reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT << - QCA8K_VTU_FUNC0_EG_MODE_S(port); + reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); + reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); /* Check if we're the last member to be removed */ del = true; for (i = 0; i < QCA8K_NUM_PORTS; i++) { - mask = QCA8K_VTU_FUNC0_EG_MODE_NOT; - mask <<= QCA8K_VTU_FUNC0_EG_MODE_S(i); + mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); if ((reg & mask) != mask) { del = false; @@ -1014,7 +1011,7 @@ qca8k_parse_port_config(struct qca8k_priv *priv) mode == PHY_INTERFACE_MODE_RGMII_TXID) delay = 1; - if (delay > QCA8K_MAX_DELAY) { + if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) { dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); delay = 3; } @@ -1030,7 +1027,7 @@ qca8k_parse_port_config(struct qca8k_priv *priv) mode == PHY_INTERFACE_MODE_RGMII_RXID) delay = 2; - if (delay > QCA8K_MAX_DELAY) { + if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) { dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); delay = 3; } @@ -1146,8 +1143,8 @@ qca8k_setup(struct dsa_switch *ds) /* Enable QCA header mode on all cpu ports */ if (dsa_is_cpu_port(ds, i)) { ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), - QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S | - QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S); + FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | + FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); if (ret) { dev_err(priv->dev, "failed enabling QCA header mode"); return ret; @@ -1164,10 +1161,10 @@ qca8k_setup(struct dsa_switch *ds) * for igmp, unknown, multicast and broadcast packet */ ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, - BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S | - BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S | - BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S | - BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S); + FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | + FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | + FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | + FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); if (ret) return ret; @@ -1185,8 +1182,6 @@ qca8k_setup(struct dsa_switch *ds) /* Individual user ports get connected to CPU port only */ if (dsa_is_user_port(ds, i)) { - int shift = 16 * (i % 2); - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); @@ -1203,8 +1198,8 @@ qca8k_setup(struct dsa_switch *ds) * default egress vid */ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), - 0xfff << shift, - QCA8K_PORT_VID_DEF << shift); + QCA8K_EGREES_VLAN_PORT_MASK(i), + QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); if (ret) return ret; @@ -1251,7 +1246,7 @@ qca8k_setup(struct dsa_switch *ds) QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | QCA8K_PORT_HOL_CTRL1_WRED_EN; qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), - QCA8K_PORT_HOL_CTRL1_ING_BUF | + QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | QCA8K_PORT_HOL_CTRL1_WRED_EN, @@ -1270,8 +1265,8 @@ qca8k_setup(struct dsa_switch *ds) mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, - QCA8K_GLOBAL_FC_GOL_XON_THRES_S | - QCA8K_GLOBAL_FC_GOL_XOFF_THRES_S, + QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | + QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, mask); } @@ -1920,11 +1915,11 @@ qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, if (vlan_filtering) { ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_VLAN_MODE, + QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); } else { ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_VLAN_MODE, + QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); } @@ -1948,10 +1943,9 @@ qca8k_port_vlan_add(struct dsa_switch *ds, int port, } if (pvid) { - int shift = 16 * (port % 2); - ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), - 0xfff << shift, vlan->vid << shift); + QCA8K_EGREES_VLAN_PORT_MASK(port), + QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); if (ret) return ret; @@ -2045,7 +2039,7 @@ static int qca8k_read_switch_id(struct qca8k_priv *priv) if (ret < 0) return -ENODEV; - id = QCA8K_MASK_CTRL_DEVICE_ID(val & QCA8K_MASK_CTRL_DEVICE_ID_MASK); + id = QCA8K_MASK_CTRL_DEVICE_ID(val); if (id != data->id) { dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id); return -ENODEV; @@ -2054,7 +2048,7 @@ static int qca8k_read_switch_id(struct qca8k_priv *priv) priv->switch_id = id; /* Save revision to communicate to the internal PHY driver */ - priv->switch_revision = (val & QCA8K_MASK_CTRL_REV_ID_MASK); + priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); return 0; } diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h index 57c4c0d93558..3722fbb6b461 100644 --- a/drivers/net/dsa/qca8k.h +++ b/drivers/net/dsa/qca8k.h @@ -30,9 +30,9 @@ /* Global control registers */ #define QCA8K_REG_MASK_CTRL 0x000 #define QCA8K_MASK_CTRL_REV_ID_MASK GENMASK(7, 0) -#define QCA8K_MASK_CTRL_REV_ID(x) ((x) >> 0) +#define QCA8K_MASK_CTRL_REV_ID(x) FIELD_GET(QCA8K_MASK_CTRL_REV_ID_MASK, x) #define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8) -#define QCA8K_MASK_CTRL_DEVICE_ID(x) ((x) >> 8) +#define QCA8K_MASK_CTRL_DEVICE_ID(x) FIELD_GET(QCA8K_MASK_CTRL_DEVICE_ID_MASK, x) #define QCA8K_REG_PORT0_PAD_CTRL 0x004 #define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31) #define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19) @@ -41,12 +41,11 @@ #define QCA8K_REG_PORT6_PAD_CTRL 0x00c #define QCA8K_PORT_PAD_RGMII_EN BIT(26) #define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22) -#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) ((x) << 22) +#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, x) #define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20) -#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) ((x) << 20) +#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, x) #define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25) #define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24) -#define QCA8K_MAX_DELAY 3 #define QCA8K_PORT_PAD_SGMII_EN BIT(7) #define QCA8K_REG_PWS 0x010 #define QCA8K_PWS_POWER_ON_SEL BIT(31) @@ -68,10 +67,12 @@ #define QCA8K_MDIO_MASTER_READ BIT(27) #define QCA8K_MDIO_MASTER_WRITE 0 #define QCA8K_MDIO_MASTER_SUP_PRE BIT(26) -#define QCA8K_MDIO_MASTER_PHY_ADDR(x) ((x) << 21) -#define QCA8K_MDIO_MASTER_REG_ADDR(x) ((x) << 16) -#define QCA8K_MDIO_MASTER_DATA(x) (x) +#define QCA8K_MDIO_MASTER_PHY_ADDR_MASK GENMASK(25, 21) +#define QCA8K_MDIO_MASTER_PHY_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_PHY_ADDR_MASK, x) +#define QCA8K_MDIO_MASTER_REG_ADDR_MASK GENMASK(20, 16) +#define QCA8K_MDIO_MASTER_REG_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_REG_ADDR_MASK, x) #define QCA8K_MDIO_MASTER_DATA_MASK GENMASK(15, 0) +#define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x) #define QCA8K_MDIO_MASTER_MAX_PORTS 5 #define QCA8K_MDIO_MASTER_MAX_REG 32 #define QCA8K_GOL_MAC_ADDR0 0x60 @@ -93,9 +94,7 @@ #define QCA8K_PORT_STATUS_FLOW_AUTO BIT(12) #define QCA8K_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4)) #define QCA8K_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2) -#define QCA8K_PORT_HDR_CTRL_RX_S 2 #define QCA8K_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0) -#define QCA8K_PORT_HDR_CTRL_TX_S 0 #define QCA8K_PORT_HDR_CTRL_ALL 2 #define QCA8K_PORT_HDR_CTRL_MGMT 1 #define QCA8K_PORT_HDR_CTRL_NONE 0 @@ -105,10 +104,11 @@ #define QCA8K_SGMII_EN_TX BIT(3) #define QCA8K_SGMII_EN_SD BIT(4) #define QCA8K_SGMII_CLK125M_DELAY BIT(7) -#define QCA8K_SGMII_MODE_CTRL_MASK (BIT(22) | BIT(23)) -#define QCA8K_SGMII_MODE_CTRL_BASEX (0 << 22) -#define QCA8K_SGMII_MODE_CTRL_PHY (1 << 22) -#define QCA8K_SGMII_MODE_CTRL_MAC (2 << 22) +#define QCA8K_SGMII_MODE_CTRL_MASK GENMASK(23, 22) +#define QCA8K_SGMII_MODE_CTRL(x) FIELD_PREP(QCA8K_SGMII_MODE_CTRL_MASK, x) +#define QCA8K_SGMII_MODE_CTRL_BASEX QCA8K_SGMII_MODE_CTRL(0x0) +#define QCA8K_SGMII_MODE_CTRL_PHY QCA8K_SGMII_MODE_CTRL(0x1) +#define QCA8K_SGMII_MODE_CTRL_MAC QCA8K_SGMII_MODE_CTRL(0x2) /* MAC_PWR_SEL registers */ #define QCA8K_REG_MAC_PWR_SEL 0x0e4 @@ -121,100 +121,115 @@ /* ACL registers */ #define QCA8K_REG_PORT_VLAN_CTRL0(_i) (0x420 + (_i * 8)) -#define QCA8K_PORT_VLAN_CVID(x) (x << 16) -#define QCA8K_PORT_VLAN_SVID(x) x +#define QCA8K_PORT_VLAN_CVID_MASK GENMASK(27, 16) +#define QCA8K_PORT_VLAN_CVID(x) FIELD_PREP(QCA8K_PORT_VLAN_CVID_MASK, x) +#define QCA8K_PORT_VLAN_SVID_MASK GENMASK(11, 0) +#define QCA8K_PORT_VLAN_SVID(x) FIELD_PREP(QCA8K_PORT_VLAN_SVID_MASK, x) #define QCA8K_REG_PORT_VLAN_CTRL1(_i) (0x424 + (_i * 8)) #define QCA8K_REG_IPV4_PRI_BASE_ADDR 0x470 #define QCA8K_REG_IPV4_PRI_ADDR_MASK 0x474 /* Lookup registers */ #define QCA8K_REG_ATU_DATA0 0x600 -#define QCA8K_ATU_ADDR2_S 24 -#define QCA8K_ATU_ADDR3_S 16 -#define QCA8K_ATU_ADDR4_S 8 +#define QCA8K_ATU_ADDR2_MASK GENMASK(31, 24) +#define QCA8K_ATU_ADDR3_MASK GENMASK(23, 16) +#define QCA8K_ATU_ADDR4_MASK GENMASK(15, 8) +#define QCA8K_ATU_ADDR5_MASK GENMASK(7, 0) #define QCA8K_REG_ATU_DATA1 0x604 -#define QCA8K_ATU_PORT_M 0x7f -#define QCA8K_ATU_PORT_S 16 -#define QCA8K_ATU_ADDR0_S 8 +#define QCA8K_ATU_PORT_MASK GENMASK(22, 16) +#define QCA8K_ATU_ADDR0_MASK GENMASK(15, 8) +#define QCA8K_ATU_ADDR1_MASK GENMASK(7, 0) #define QCA8K_REG_ATU_DATA2 0x608 -#define QCA8K_ATU_VID_M 0xfff -#define QCA8K_ATU_VID_S 8 -#define QCA8K_ATU_STATUS_M 0xf +#define QCA8K_ATU_VID_MASK GENMASK(19, 8) +#define QCA8K_ATU_STATUS_MASK GENMASK(3, 0) #define QCA8K_ATU_STATUS_STATIC 0xf #define QCA8K_REG_ATU_FUNC 0x60c #define QCA8K_ATU_FUNC_BUSY BIT(31) #define QCA8K_ATU_FUNC_PORT_EN BIT(14) #define QCA8K_ATU_FUNC_MULTI_EN BIT(13) #define QCA8K_ATU_FUNC_FULL BIT(12) -#define QCA8K_ATU_FUNC_PORT_M 0xf -#define QCA8K_ATU_FUNC_PORT_S 8 +#define QCA8K_ATU_FUNC_PORT_MASK GENMASK(11, 8) #define QCA8K_REG_VTU_FUNC0 0x610 #define QCA8K_VTU_FUNC0_VALID BIT(20) #define QCA8K_VTU_FUNC0_IVL_EN BIT(19) -#define QCA8K_VTU_FUNC0_EG_MODE_S(_i) (4 + (_i) * 2) -#define QCA8K_VTU_FUNC0_EG_MODE_MASK 3 -#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD 0 -#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG 1 -#define QCA8K_VTU_FUNC0_EG_MODE_TAG 2 -#define QCA8K_VTU_FUNC0_EG_MODE_NOT 3 +/* QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(17, 4) + * It does contain VLAN_MODE for each port [5:4] for port0, + * [7:6] for port1 ... [17:16] for port6. Use virtual port + * define to handle this. + */ +#define QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i) (4 + (_i) * 2) +#define QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(1, 0) +#define QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(_i) (GENMASK(1, 0) << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) +#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x0) +#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNMOD(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNMOD << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) +#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x1) +#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNTAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) +#define QCA8K_VTU_FUNC0_EG_MODE_TAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x2) +#define QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_TAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) +#define QCA8K_VTU_FUNC0_EG_MODE_NOT FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x3) +#define QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(_i) (QCA8K_VTU_FUNC0_EG_MODE_NOT << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) #define QCA8K_REG_VTU_FUNC1 0x614 #define QCA8K_VTU_FUNC1_BUSY BIT(31) -#define QCA8K_VTU_FUNC1_VID_S 16 +#define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16) #define QCA8K_VTU_FUNC1_FULL BIT(4) #define QCA8K_REG_GLOBAL_FW_CTRL0 0x620 #define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) #define QCA8K_REG_GLOBAL_FW_CTRL1 0x624 -#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S 24 -#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_S 16 -#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_S 8 -#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_S 0 +#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24) +#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16) +#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8) +#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0) #define QCA8K_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc) #define QCA8K_PORT_LOOKUP_MEMBER GENMASK(6, 0) -#define QCA8K_PORT_LOOKUP_VLAN_MODE GENMASK(9, 8) -#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE (0 << 8) -#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK (1 << 8) -#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK (2 << 8) -#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE (3 << 8) +#define QCA8K_PORT_LOOKUP_VLAN_MODE_MASK GENMASK(9, 8) +#define QCA8K_PORT_LOOKUP_VLAN_MODE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, x) +#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE QCA8K_PORT_LOOKUP_VLAN_MODE(0x0) +#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK QCA8K_PORT_LOOKUP_VLAN_MODE(0x1) +#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK QCA8K_PORT_LOOKUP_VLAN_MODE(0x2) +#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE QCA8K_PORT_LOOKUP_VLAN_MODE(0x3) #define QCA8K_PORT_LOOKUP_STATE_MASK GENMASK(18, 16) -#define QCA8K_PORT_LOOKUP_STATE_DISABLED (0 << 16) -#define QCA8K_PORT_LOOKUP_STATE_BLOCKING (1 << 16) -#define QCA8K_PORT_LOOKUP_STATE_LISTENING (2 << 16) -#define QCA8K_PORT_LOOKUP_STATE_LEARNING (3 << 16) -#define QCA8K_PORT_LOOKUP_STATE_FORWARD (4 << 16) -#define QCA8K_PORT_LOOKUP_STATE GENMASK(18, 16) +#define QCA8K_PORT_LOOKUP_STATE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_STATE_MASK, x) +#define QCA8K_PORT_LOOKUP_STATE_DISABLED QCA8K_PORT_LOOKUP_STATE(0x0) +#define QCA8K_PORT_LOOKUP_STATE_BLOCKING QCA8K_PORT_LOOKUP_STATE(0x1) +#define QCA8K_PORT_LOOKUP_STATE_LISTENING QCA8K_PORT_LOOKUP_STATE(0x2) +#define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3) +#define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4) #define QCA8K_PORT_LOOKUP_LEARN BIT(20) #define QCA8K_REG_GLOBAL_FC_THRESH 0x800 -#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) ((x) << 16) -#define QCA8K_GLOBAL_FC_GOL_XON_THRES_S GENMASK(24, 16) -#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) ((x) << 0) -#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_S GENMASK(8, 0) +#define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16) +#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x) +#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK GENMASK(8, 0) +#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, x) #define QCA8K_REG_PORT_HOL_CTRL0(_i) (0x970 + (_i) * 0x8) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF GENMASK(3, 0) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) ((x) << 0) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF GENMASK(7, 4) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) ((x) << 4) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF GENMASK(11, 8) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) ((x) << 8) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF GENMASK(15, 12) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) ((x) << 12) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF GENMASK(19, 16) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) ((x) << 16) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF GENMASK(23, 20) -#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) ((x) << 20) -#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF GENMASK(29, 24) -#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) ((x) << 24) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK GENMASK(3, 0) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK, x) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK GENMASK(7, 4) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK, x) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK GENMASK(11, 8) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK, x) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK GENMASK(15, 12) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK, x) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK GENMASK(19, 16) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK, x) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK GENMASK(23, 20) +#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK, x) +#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK GENMASK(29, 24) +#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK, x) #define QCA8K_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8) -#define QCA8K_PORT_HOL_CTRL1_ING_BUF GENMASK(3, 0) -#define QCA8K_PORT_HOL_CTRL1_ING(x) ((x) << 0) +#define QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK GENMASK(3, 0) +#define QCA8K_PORT_HOL_CTRL1_ING(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK, x) #define QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN BIT(6) #define QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7) #define QCA8K_PORT_HOL_CTRL1_WRED_EN BIT(8) #define QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16) /* Pkt edit registers */ +#define QCA8K_EGREES_VLAN_PORT_SHIFT(_i) (16 * ((_i) % 2)) +#define QCA8K_EGREES_VLAN_PORT_MASK(_i) (GENMASK(11, 0) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) +#define QCA8K_EGREES_VLAN_PORT(_i, x) ((x) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) #define QCA8K_EGRESS_VLAN(x) (0x0c70 + (4 * (x / 2))) /* L3 registers */ From patchwork Wed Nov 17 21:04:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625419 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D0DFC433EF for ; Wed, 17 Nov 2021 21:05:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5674A61BFA for ; Wed, 17 Nov 2021 21:05:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240733AbhKQVIb (ORCPT ); Wed, 17 Nov 2021 16:08:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34968 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240262AbhKQVIX (ORCPT ); Wed, 17 Nov 2021 16:08:23 -0500 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E8520C061570; Wed, 17 Nov 2021 13:05:23 -0800 (PST) Received: by mail-ed1-x52e.google.com with SMTP id b15so16973740edd.7; Wed, 17 Nov 2021 13:05:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=yIJS/1iBvu+w7JezmkxW5wUMLoTaW6Y1Obeh9jb/iF0=; b=nOHmen3IKZ5A//I5GuBlOlIBM+ztKF/r/394EsILay5zwwujQ/CXrgC0A28LoJZfJU O53OKD08JNXAx/q2cyl5Lo47TeyI0i2pzEuF2a23Dp9QHW0aULMMGM4rM/3K+aCsMChh WWiw6c55k1yYfQNySpsAuSipT57K+Zp1uttHwMaZiG1/8Ca74Nk2JLyPgWcqS39gejOF ues1AMbPLKyVYrHsdaHJqykEuWIMR+3OkvPPYic63VHetBoKDFUqPGm/Ajpxpbb9zTJ7 ymPX71v9rzTv75Gp0AufPrNem4iGeTF1lW+mGasLe5cF0hU8IE0NSR3R2puJI1Ya5rxg sZ7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yIJS/1iBvu+w7JezmkxW5wUMLoTaW6Y1Obeh9jb/iF0=; b=rDk5/0qzbhZhuD5dttD0w+suD+lSiftH0vdyfd1fDaCAGVtKZF2w2xRkgFgoQIwnnx g1jH/1L3KGtEW3ENHgYok7K9mnbOA7L2p7B0u1NjqWjaUajrKM7fSEm8lbZdDLy7slPX D1cyPAewHZlRDBMpABuvzu0ArqL9wT6kTwXo30cGou+5UHDwRqCrab2C7l2hVJqSCrIn ZOlbppmdYdXsZyoLsRidZEVC3z5Ex6KXd5odCWPNMIPN4ZQXbaPNE2oyCssxWXYsxO2v wHF+yQT6A9AtvQXRXd/AqcgfIbq8LLSewRQDX6ZwpUOjvQaeJ7buGflEWIvpBLaN/t7p hZ1g== X-Gm-Message-State: AOAM531pUzPITMBrpLYwQebf7MRPqcfLFQKMF7zHxlI9my9YMaP0/f/r 491a8qX17EVN5+EimVP5/eo= X-Google-Smtp-Source: ABdhPJz0sfr+Rk9qlbFUJrfM0L1ZSrTix7XM6NkLFivJU/obhSPRxfurYeJk6GJZFidJbhCsVRwy5A== X-Received: by 2002:a17:906:794f:: with SMTP id l15mr26864172ejo.324.1637183122405; Wed, 17 Nov 2021 13:05:22 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:20 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 05/19] net: dsa: qca8k: move read switch id function in qca8k_setup Date: Wed, 17 Nov 2021 22:04:37 +0100 Message-Id: <20211117210451.26415-6-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Move read_switch_id function in qca8k_setup in preparation for regmap conversion. Sw probe should NOT contain function that depends on reading from switch regs. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 71 ++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index 19331edf1fd4..be98d11b17ec 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1073,6 +1073,36 @@ qca8k_parse_port_config(struct qca8k_priv *priv) return 0; } +static int qca8k_read_switch_id(struct qca8k_priv *priv) +{ + const struct qca8k_match_data *data; + u32 val; + u8 id; + int ret; + + /* get the switches ID from the compatible */ + data = of_device_get_match_data(priv->dev); + if (!data) + return -ENODEV; + + ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); + if (ret < 0) + return -ENODEV; + + id = QCA8K_MASK_CTRL_DEVICE_ID(val); + if (id != data->id) { + dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id); + return -ENODEV; + } + + priv->switch_id = id; + + /* Save revision to communicate to the internal PHY driver */ + priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); + + return 0; +} + static int qca8k_setup(struct dsa_switch *ds) { @@ -1080,6 +1110,11 @@ qca8k_setup(struct dsa_switch *ds) int cpu_port, ret, i; u32 mask; + /* Check the detected switch id */ + ret = qca8k_read_switch_id(priv); + if (ret) + return ret; + cpu_port = qca8k_find_cpu_port(ds); if (cpu_port < 0) { dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6"); @@ -2023,41 +2058,10 @@ static const struct dsa_switch_ops qca8k_switch_ops = { .get_phy_flags = qca8k_get_phy_flags, }; -static int qca8k_read_switch_id(struct qca8k_priv *priv) -{ - const struct qca8k_match_data *data; - u32 val; - u8 id; - int ret; - - /* get the switches ID from the compatible */ - data = of_device_get_match_data(priv->dev); - if (!data) - return -ENODEV; - - ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); - if (ret < 0) - return -ENODEV; - - id = QCA8K_MASK_CTRL_DEVICE_ID(val); - if (id != data->id) { - dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id); - return -ENODEV; - } - - priv->switch_id = id; - - /* Save revision to communicate to the internal PHY driver */ - priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); - - return 0; -} - static int qca8k_sw_probe(struct mdio_device *mdiodev) { struct qca8k_priv *priv; - int ret; /* allocate the private data struct so that we can probe the switches * ID register @@ -2083,11 +2087,6 @@ qca8k_sw_probe(struct mdio_device *mdiodev) gpiod_set_value_cansleep(priv->reset_gpio, 0); } - /* Check the detected switch id */ - ret = qca8k_read_switch_id(priv); - if (ret) - return ret; - priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); if (!priv->ds) return -ENOMEM; From patchwork Wed Nov 17 21:04:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625423 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2D1F8C433EF for ; Wed, 17 Nov 2021 21:05:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 185776321A for ; Wed, 17 Nov 2021 21:05:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240748AbhKQVIi (ORCPT ); Wed, 17 Nov 2021 16:08:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34976 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240315AbhKQVIY (ORCPT ); Wed, 17 Nov 2021 16:08:24 -0500 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D32FCC061764; Wed, 17 Nov 2021 13:05:24 -0800 (PST) Received: by mail-ed1-x533.google.com with SMTP id l25so513286eda.11; Wed, 17 Nov 2021 13:05:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=FNU6xPKDr3rvlUjVkPE4P9ezAnb4hLxnQhk7TRXi4rs=; b=L1EIKewXih4eldhdfjzKyHVKl5Xpo1B+4qOJENeOBpqeKTcUvWfzTgsn4kghXc8MPI eI79hUDZaBxGWosvujzcLhn1b59vDUDCN91J+Qfcmf+NglPVTVtFdV7TtvJ3FrcdxqYJ ef4N0HixG/feh9yoN9hyVWtb0BJtpfgCs1T4dibq2DXnVtrGo9K1T5eUSPR4BDzVrkaR bxyv+6n4AiEFUKD426QNiDn4LzSkyshenzO976PXFn2uSSp1OwH/aFgjoE9DCCOGck8B CTHsOLR6bFTcg/jJHC0ZBbD+AWr9EjNNzHCt++Of988JVQZuV6QoqH89sZ5LJViUm6sD BNHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FNU6xPKDr3rvlUjVkPE4P9ezAnb4hLxnQhk7TRXi4rs=; b=LV3goayS28bGXrUbLCCvF3w2DB0QayCaJKwmbTZ4rwe8kGbVjtYV0gH++WVtg3X07S Xfefe5lg1yS7ZZut7445Ze4kRTT6uUn5ccSDVDq9D660eV4S3ogec28DcM2jew+lGREg T026F9TtaIqq1lg94MJFcKVyxJWk0VnKhXSv/Gtl08iF1z/9QpQTmTn7UXhtRdyiBTBU 4wHcP+jfxH+qAM039g0TSDuOnZ6Rbq0O/WWjQWD4ETd3fJzI4tTJfU4hLzTslvLFQsCD yNHU1knC8hrmaSvrQPsWB8T9oRWf2GTfnmIJOZgbNQlstqzH3cnsbroAPxwmzrKa2tup EHCA== X-Gm-Message-State: AOAM530PIzXLVmst2QwhcfQLtQfv0FhE2igWSsD/UjJeqp6eaCIzo74N sJJR52Yu8aYjv2zBkQQpW2s= X-Google-Smtp-Source: ABdhPJzf9Com31ZU9Qz2u9t1kEP7EvHfR6VfEbtY6a9t9cq38MeKolPpkZZjvQ2Yx7PT5/Bz9qlvfQ== X-Received: by 2002:a50:9510:: with SMTP id u16mr2701745eda.134.1637183123336; Wed, 17 Nov 2021 13:05:23 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:23 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 06/19] net: dsa: qca8k: remove extra mutex_init in qca8k_setup Date: Wed, 17 Nov 2021 22:04:38 +0100 Message-Id: <20211117210451.26415-7-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Mutex is already init in sw_probe. Remove the extra init in qca8k_setup. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index be98d11b17ec..ee04b48875e7 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1126,8 +1126,6 @@ qca8k_setup(struct dsa_switch *ds) if (ret) return ret; - mutex_init(&priv->reg_mutex); - /* Start by setting up the register mapping */ priv->regmap = devm_regmap_init(ds->dev, NULL, priv, &qca8k_regmap_config); From patchwork Wed Nov 17 21:04:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625421 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0D3F6C433EF for ; Wed, 17 Nov 2021 21:05:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EB4EB63247 for ; Wed, 17 Nov 2021 21:05:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235817AbhKQVIf (ORCPT ); Wed, 17 Nov 2021 16:08:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34984 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239501AbhKQVIY (ORCPT ); Wed, 17 Nov 2021 16:08:24 -0500 Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF8C3C0613B9; Wed, 17 Nov 2021 13:05:25 -0800 (PST) Received: by mail-ed1-x52a.google.com with SMTP id z5so17018935edd.3; Wed, 17 Nov 2021 13:05:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=t1oOKjv+/U8RdtftE11t0rCXcL7mhgPsJv3IjVSG5Pg=; b=Mn2AOqTW4ZhtLcqyjUQCdSIl1ysUOuyA10BrQYxnSGBRhKKyMN8A57Rk598GVbv3km n3Xmsl2d60SymdAnQvR17B2y0ijwx5nP0IVbRtjQ3QHYrimAzAlgh73JPbbLXW5WTFnW 2mqiTVXd7amUwLhw2h/bw/hxBGaIiYVkC9zeekR52YaCPce64JDpZYjWlL6nGABJcKIC jSiBQfg7zUzPA/w3K2b61h4c0l34P9xY2ANEXUIHoF3f/3+6Iss4A5o5OSzB6le6YJP2 4OwfAUA2pbDCusxCe/qYdo73BVpSgzQn2dZqUOFtirwITrSvHn+8gcIJTDC17rbBtQzQ 187Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=t1oOKjv+/U8RdtftE11t0rCXcL7mhgPsJv3IjVSG5Pg=; b=VQTuAtF30s3EBksHqPiaBv1tMiOv0jlWWfGdiemGQopacuQIUFdsLdP95tQ2ktdLmV jz7je/TQAiSwEg+10LHWj+Q56dB1YiQMTg77HdYnmC0Aw1G57zSUlynBf7P5hziu6o4D luEIvfPJh0VpEC5Bo3cwdvKDeVCJ1IvTRpJR72jnTnbSEXrZtwOZ3VBuZ5N7qBMTiYpj Io5NUPZ0/uGLvYdkhEK1r8EYs2AAi81FACnJljW5ff83FRodAu5b+ckS2Zwc24Cv3AFX v+7oBixCszpEzMJGhPnYkynO3nWKqLa+0js6ZRiIYoEkZXza06zWj8hJNSYv1SUwcROE 12vw== X-Gm-Message-State: AOAM5324+E4Jls3aYYDo1PpLXXWnf37ViQRfPPwUKjEhwT3X0jFqNIex mn+nZZoxRJ0Djmz166Zk7hs= X-Google-Smtp-Source: ABdhPJzoNhW1A4AfFIPfzw2gQ7rXbRSscMvtCN8tEZDTKccMQAHUULiWGqfhVdNM6NZmMYvPfp1+ig== X-Received: by 2002:a05:6402:6d2:: with SMTP id n18mr2724566edy.210.1637183124245; Wed, 17 Nov 2021 13:05:24 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:24 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 07/19] net: dsa: qca8k: set regmap init as mandatory for regmap conversion Date: Wed, 17 Nov 2021 22:04:39 +0100 Message-Id: <20211117210451.26415-8-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org In preparation for regmap conversion, make regmap init mandatory and fail if any error occurs. Signed-off-by: Ansuel Smith Reviewed-by: Vladimir Oltean --- drivers/net/dsa/qca8k.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index ee04b48875e7..792b999da37c 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1110,6 +1110,14 @@ qca8k_setup(struct dsa_switch *ds) int cpu_port, ret, i; u32 mask; + /* Start by setting up the register mapping */ + priv->regmap = devm_regmap_init(ds->dev, NULL, priv, + &qca8k_regmap_config); + if (IS_ERR(priv->regmap)) { + dev_err(priv->dev, "regmap initialization failed"); + return PTR_ERR(priv->regmap); + } + /* Check the detected switch id */ ret = qca8k_read_switch_id(priv); if (ret) @@ -1126,12 +1134,6 @@ qca8k_setup(struct dsa_switch *ds) if (ret) return ret; - /* Start by setting up the register mapping */ - priv->regmap = devm_regmap_init(ds->dev, NULL, priv, - &qca8k_regmap_config); - if (IS_ERR(priv->regmap)) - dev_warn(priv->dev, "regmap initialization failed"); - ret = qca8k_setup_mdio_bus(priv); if (ret) return ret; From patchwork Wed Nov 17 21:04:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625427 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 83A8DC433F5 for ; Wed, 17 Nov 2021 21:06:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6A8BE61BFB for ; Wed, 17 Nov 2021 21:06:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240255AbhKQVI6 (ORCPT ); Wed, 17 Nov 2021 16:08:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34992 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240361AbhKQVI1 (ORCPT ); Wed, 17 Nov 2021 16:08:27 -0500 Received: from mail-ed1-x531.google.com (mail-ed1-x531.google.com [IPv6:2a00:1450:4864:20::531]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C8884C061200; Wed, 17 Nov 2021 13:05:26 -0800 (PST) Received: by mail-ed1-x531.google.com with SMTP id x15so17057095edv.1; Wed, 17 Nov 2021 13:05:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=kaU0wIO+JzI18rYuvj8kRXL8LngbZuZqA3b7/nDNnbc=; b=NrTkL5mJjGnp2h9db2pGRxOyoMKruJHvTU9kEo+6EYGpwYncxBy/vOrxEE9Rt9hLJF p5YKqLJpQIN9n2RNVnKrteFNR9Y1VjUz84cEukuY5wGsbu6w4Ckgd468uSLAHaqcrUGy ONz9K6prRAynJGlERoaSXBhslWegIZuMKL9MGi1QiANPzamTJj0W1Xtu1IBKbJlhuF7r d8CdgyzAUrnPZ+Is4AP2mSuXqm0nRVn97wJRziXY6fIdPiZE1tya3N5D0O5IQZcrrWqQ u6GSmk37pQ9k+Eengkzn9zqKWGCrR3t9dtiltTPm6dkZt6Bk011xWvGF7Wa5EQk3sPRv 8MrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kaU0wIO+JzI18rYuvj8kRXL8LngbZuZqA3b7/nDNnbc=; b=gVH7Xu3dYaRrUGW8bvLpuOnmldreXnANLrGddbvkH9nTNgAcB93PBni6MM8twcqwPZ S1M6pKBdeccdINOhOYhCmushYBhJ4heZay/pDk3hTmeHxoqtOjCrMGgDOe+akybdM9SR 9vNsYQtuf8UfE55CMpXwwd9+abVlEyxAlFzGKWcb/YIsHY5N8OBE6r6yhUePDWRKHNyt 5TBxFgj/EbX6JRfyd75hllw/9NWz2anvM6rWx04Q2ntkwJv4JIzHnJIKo27HfmmGobI9 63ihPrmP/PjW5CzSCIvOR4B1a1u4p+km02bHl68I7nBJdhrMVBeVCCJnFnHUPM6RjkYk Q+5Q== X-Gm-Message-State: AOAM532Bavfqrc8UeYd3swl7qQQOBD69E0YTpvJO4SqKTewPDkqmteaK Np2WsHjUtQJf1ZfI+a0yqNU= X-Google-Smtp-Source: ABdhPJy/ExKvmHEh3Imis+skMrryx8NuzslDciMX3Ec9rtjdPRF3QOd11gYpT4tgGrbqgXp3A1JosA== X-Received: by 2002:a05:6402:4394:: with SMTP id o20mr2693812edc.342.1637183125124; Wed, 17 Nov 2021 13:05:25 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:24 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 08/19] net: dsa: qca8k: convert qca8k to regmap helper Date: Wed, 17 Nov 2021 22:04:40 +0100 Message-Id: <20211117210451.26415-9-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Convert any qca8k read/write/rmw/set/clear/pool to regmap helper and add missing config to regmap_config struct. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 289 ++++++++++++++++++---------------------- 1 file changed, 131 insertions(+), 158 deletions(-) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index 792b999da37c..7f71607bec3f 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -150,8 +151,9 @@ qca8k_set_page(struct mii_bus *bus, u16 page) } static int -qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) +qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) { + struct qca8k_priv *priv = (struct qca8k_priv *)ctx; struct mii_bus *bus = priv->bus; u16 r1, r2, page; int ret; @@ -172,8 +174,9 @@ qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) } static int -qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) +qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) { + struct qca8k_priv *priv = (struct qca8k_priv *)ctx; struct mii_bus *bus = priv->bus; u16 r1, r2, page; int ret; @@ -194,8 +197,9 @@ qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) } static int -qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) +qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) { + struct qca8k_priv *priv = (struct qca8k_priv *)ctx; struct mii_bus *bus = priv->bus; u16 r1, r2, page; u32 val; @@ -223,34 +227,6 @@ qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) return ret; } -static int -qca8k_reg_set(struct qca8k_priv *priv, u32 reg, u32 val) -{ - return qca8k_rmw(priv, reg, 0, val); -} - -static int -qca8k_reg_clear(struct qca8k_priv *priv, u32 reg, u32 val) -{ - return qca8k_rmw(priv, reg, val, 0); -} - -static int -qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ctx; - - return qca8k_read(priv, reg, val); -} - -static int -qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ctx; - - return qca8k_write(priv, reg, val); -} - static const struct regmap_range qca8k_readable_ranges[] = { regmap_reg_range(0x0000, 0x00e4), /* Global control */ regmap_reg_range(0x0100, 0x0168), /* EEE control */ @@ -282,26 +258,19 @@ static struct regmap_config qca8k_regmap_config = { .max_register = 0x16ac, /* end MIB - Port6 range */ .reg_read = qca8k_regmap_read, .reg_write = qca8k_regmap_write, + .reg_update_bits = qca8k_regmap_update_bits, .rd_table = &qca8k_readable_table, + .disable_locking = true, /* Locking is handled by qca8k read/write */ + .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ }; static int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) { - int ret, ret1; u32 val; - ret = read_poll_timeout(qca8k_read, ret1, !(val & mask), - 0, QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, - priv, reg, &val); - - /* Check if qca8k_read has failed for a different reason - * before returning -ETIMEDOUT - */ - if (ret < 0 && ret1 < 0) - return ret1; - - return ret; + return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, + QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); } static int @@ -312,7 +281,7 @@ qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) /* load the ARL table into an array */ for (i = 0; i < 4; i++) { - ret = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4), &val); + ret = regmap_read(priv->regmap, QCA8K_REG_ATU_DATA0 + (i * 4), &val); if (ret < 0) return ret; @@ -359,7 +328,7 @@ qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, /* load the array into the ARL table */ for (i = 0; i < 3; i++) - qca8k_write(priv, QCA8K_REG_ATU_DATA0 + (i * 4), reg[i]); + regmap_write(priv->regmap, QCA8K_REG_ATU_DATA0 + (i * 4), reg[i]); } static int @@ -377,7 +346,7 @@ qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) } /* Write the function register triggering the table access */ - ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); + ret = regmap_write(priv->regmap, QCA8K_REG_ATU_FUNC, reg); if (ret) return ret; @@ -388,7 +357,7 @@ qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) /* Check for table full violation when adding an entry */ if (cmd == QCA8K_FDB_LOAD) { - ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); + ret = regmap_read(priv->regmap, QCA8K_REG_ATU_FUNC, ®); if (ret < 0) return ret; if (reg & QCA8K_ATU_FUNC_FULL) @@ -458,7 +427,7 @@ qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); /* Write the function register triggering the table access */ - ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); + ret = regmap_write(priv->regmap, QCA8K_REG_VTU_FUNC1, reg); if (ret) return ret; @@ -469,7 +438,7 @@ qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) /* Check for table full violation when adding an entry */ if (cmd == QCA8K_VLAN_LOAD) { - ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); + ret = regmap_read(priv->regmap, QCA8K_REG_VTU_FUNC1, ®); if (ret < 0) return ret; if (reg & QCA8K_VTU_FUNC1_FULL) @@ -497,7 +466,7 @@ qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) if (ret < 0) goto out; - ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); + ret = regmap_read(priv->regmap, QCA8K_REG_VTU_FUNC0, ®); if (ret < 0) goto out; reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; @@ -507,7 +476,7 @@ qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) else reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); - ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); + ret = regmap_write(priv->regmap, QCA8K_REG_VTU_FUNC0, reg); if (ret) goto out; ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); @@ -530,7 +499,7 @@ qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) if (ret < 0) goto out; - ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); + ret = regmap_read(priv->regmap, QCA8K_REG_VTU_FUNC0, ®); if (ret < 0) goto out; reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); @@ -550,7 +519,7 @@ qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) if (del) { ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); } else { - ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); + ret = regmap_write(priv->regmap, QCA8K_REG_VTU_FUNC0, reg); if (ret) goto out; ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); @@ -568,7 +537,7 @@ qca8k_mib_init(struct qca8k_priv *priv) int ret; mutex_lock(&priv->reg_mutex); - ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY); + ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY); if (ret) goto exit; @@ -576,11 +545,11 @@ qca8k_mib_init(struct qca8k_priv *priv) if (ret) goto exit; - ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); + ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); if (ret) goto exit; - ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); + ret = regmap_write(priv->regmap, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); exit: mutex_unlock(&priv->reg_mutex); @@ -597,9 +566,9 @@ qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) mask |= QCA8K_PORT_STATUS_LINK_AUTO; if (enable) - qca8k_reg_set(priv, QCA8K_REG_PORT_STATUS(port), mask); + regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); else - qca8k_reg_clear(priv, QCA8K_REG_PORT_STATUS(port), mask); + regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); } static u32 @@ -861,8 +830,8 @@ qca8k_setup_mdio_bus(struct qca8k_priv *priv) * a dt-overlay and driver reload changed the configuration */ - return qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL, - QCA8K_MDIO_MASTER_EN); + return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL, + QCA8K_MDIO_MASTER_EN); } /* Check if the devicetree declare the port:phy mapping */ @@ -903,10 +872,10 @@ qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) mask |= QCA8K_MAC_PWR_RGMII1_1_8V; if (mask) { - ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL, - QCA8K_MAC_PWR_RGMII0_1_8V | - QCA8K_MAC_PWR_RGMII1_1_8V, - mask); + ret = regmap_update_bits(priv->regmap, QCA8K_REG_MAC_PWR_SEL, + QCA8K_MAC_PWR_RGMII0_1_8V | + QCA8K_MAC_PWR_RGMII1_1_8V, + mask); } return ret; @@ -947,8 +916,9 @@ qca8k_setup_of_pws_reg(struct qca8k_priv *priv) if (data->reduced_package) val |= QCA8327_PWS_PACKAGE148_EN; - ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, - val); + ret = regmap_update_bits(priv->regmap, QCA8K_REG_PWS, + QCA8327_PWS_PACKAGE148_EN, + val); if (ret) return ret; } @@ -965,9 +935,10 @@ qca8k_setup_of_pws_reg(struct qca8k_priv *priv) val |= QCA8K_PWS_LED_OPEN_EN_CSR; } - return qca8k_rmw(priv, QCA8K_REG_PWS, - QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL, - val); + return regmap_update_bits(priv->regmap, QCA8K_REG_PWS, + QCA8K_PWS_LED_OPEN_EN_CSR | + QCA8K_PWS_POWER_ON_SEL, + val); } static int @@ -1085,7 +1056,7 @@ static int qca8k_read_switch_id(struct qca8k_priv *priv) if (!data) return -ENODEV; - ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); + ret = regmap_read(priv->regmap, QCA8K_REG_MASK_CTRL, &val); if (ret < 0) return -ENODEV; @@ -1147,16 +1118,16 @@ qca8k_setup(struct dsa_switch *ds) return ret; /* Make sure MAC06 is disabled */ - ret = qca8k_reg_clear(priv, QCA8K_REG_PORT0_PAD_CTRL, - QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); + ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, + QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); if (ret) { dev_err(priv->dev, "failed disabling MAC06 exchange"); return ret; } /* Enable CPU Port */ - ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0, - QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); + ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, + QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); if (ret) { dev_err(priv->dev, "failed enabling CPU port"); return ret; @@ -1170,16 +1141,18 @@ qca8k_setup(struct dsa_switch *ds) /* Initial setup of all ports */ for (i = 0; i < QCA8K_NUM_PORTS; i++) { /* Disable forwarding by default on all ports */ - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), - QCA8K_PORT_LOOKUP_MEMBER, 0); + ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), + QCA8K_PORT_LOOKUP_MEMBER, 0); if (ret) return ret; /* Enable QCA header mode on all cpu ports */ if (dsa_is_cpu_port(ds, i)) { - ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), - FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | - FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); + ret = regmap_write(priv->regmap, QCA8K_REG_PORT_HDR_CTRL(i), + FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, + QCA8K_PORT_HDR_CTRL_ALL) | + FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, + QCA8K_PORT_HDR_CTRL_ALL)); if (ret) { dev_err(priv->dev, "failed enabling QCA header mode"); return ret; @@ -1195,11 +1168,11 @@ qca8k_setup(struct dsa_switch *ds) * Notice that in multi-cpu config only one port should be set * for igmp, unknown, multicast and broadcast packet */ - ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, - FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | - FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | - FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | - FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); + ret = regmap_write(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL1, + FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | + FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | + FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | + FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); if (ret) return ret; @@ -1209,38 +1182,38 @@ qca8k_setup(struct dsa_switch *ds) for (i = 0; i < QCA8K_NUM_PORTS; i++) { /* CPU port gets connected to all user ports of the switch */ if (dsa_is_cpu_port(ds, i)) { - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), - QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); + ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), + QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); if (ret) return ret; } /* Individual user ports get connected to CPU port only */ if (dsa_is_user_port(ds, i)) { - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), - QCA8K_PORT_LOOKUP_MEMBER, - BIT(cpu_port)); + ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), + QCA8K_PORT_LOOKUP_MEMBER, + BIT(cpu_port)); if (ret) return ret; /* Enable ARP Auto-learning by default */ - ret = qca8k_reg_set(priv, QCA8K_PORT_LOOKUP_CTRL(i), - QCA8K_PORT_LOOKUP_LEARN); + ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), + QCA8K_PORT_LOOKUP_LEARN); if (ret) return ret; /* For port based vlans to work we need to set the * default egress vid */ - ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), - QCA8K_EGREES_VLAN_PORT_MASK(i), - QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); + ret = regmap_update_bits(priv->regmap, QCA8K_EGRESS_VLAN(i), + QCA8K_EGREES_VLAN_PORT_MASK(i), + QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); if (ret) return ret; - ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i), - QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | - QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); + ret = regmap_write(priv->regmap, QCA8K_REG_PORT_VLAN_CTRL0(i), + QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | + QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); if (ret) return ret; } @@ -1274,18 +1247,18 @@ qca8k_setup(struct dsa_switch *ds) QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); } - qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask); + regmap_write(priv->regmap, QCA8K_REG_PORT_HOL_CTRL0(i), mask); mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | QCA8K_PORT_HOL_CTRL1_WRED_EN; - qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), - QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | - QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | - QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | - QCA8K_PORT_HOL_CTRL1_WRED_EN, - mask); + regmap_update_bits(priv->regmap, QCA8K_REG_PORT_HOL_CTRL1(i), + QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | + QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | + QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | + QCA8K_PORT_HOL_CTRL1_WRED_EN, + mask); } /* Set initial MTU for every port. @@ -1299,14 +1272,14 @@ qca8k_setup(struct dsa_switch *ds) if (priv->switch_id == QCA8K_ID_QCA8327) { mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); - qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, - QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | - QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, - mask); + regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FC_THRESH, + QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | + QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, + mask); } /* Setup our port MTUs to match power on defaults */ - ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); + ret = regmap_write(priv->regmap, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); if (ret) dev_warn(priv->dev, "failed setting MTU settings"); @@ -1349,12 +1322,12 @@ qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_inde } /* Set RGMII delay based on the selected values */ - ret = qca8k_rmw(priv, reg, - QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | - QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | - QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | - QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, - val); + ret = regmap_update_bits(priv->regmap, reg, + QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | + QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | + QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | + QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, + val); if (ret) dev_err(priv->dev, "Failed to set internal delay for CPU port%d", cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6); @@ -1415,7 +1388,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_TXID: case PHY_INTERFACE_MODE_RGMII_RXID: - qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); + regmap_write(priv->regmap, reg, QCA8K_PORT_PAD_RGMII_EN); /* Configure rgmii delay */ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); @@ -1425,26 +1398,26 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, * rather than individual port registers. */ if (priv->switch_id == QCA8K_ID_QCA8337) - qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, - QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); + regmap_write(priv->regmap, QCA8K_REG_PORT5_PAD_CTRL, + QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); break; case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_1000BASEX: /* Enable SGMII on the port */ - qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); + regmap_write(priv->regmap, reg, QCA8K_PORT_PAD_SGMII_EN); /* Enable/disable SerDes auto-negotiation as necessary */ - ret = qca8k_read(priv, QCA8K_REG_PWS, &val); + ret = regmap_read(priv->regmap, QCA8K_REG_PWS, &val); if (ret) return; if (phylink_autoneg_inband(mode)) val &= ~QCA8K_PWS_SERDES_AEN_DIS; else val |= QCA8K_PWS_SERDES_AEN_DIS; - qca8k_write(priv, QCA8K_REG_PWS, val); + regmap_write(priv->regmap, QCA8K_REG_PWS, val); /* Configure the SGMII parameters */ - ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val); + ret = regmap_read(priv->regmap, QCA8K_REG_SGMII_CTRL, &val); if (ret) return; @@ -1466,7 +1439,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, val |= QCA8K_SGMII_MODE_CTRL_BASEX; } - qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); + regmap_write(priv->regmap, QCA8K_REG_SGMII_CTRL, val); /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and * falling edge is set writing in the PORT0 PAD reg @@ -1485,10 +1458,10 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; if (val) - ret = qca8k_rmw(priv, reg, - QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | - QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, - val); + ret = regmap_update_bits(priv->regmap, reg, + QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | + QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, + val); /* From original code is reported port instability as SGMII also * require delay set. Apply advised values here or take them from DT. @@ -1578,7 +1551,7 @@ qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, u32 reg; int ret; - ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), ®); + ret = regmap_read(priv->regmap, QCA8K_REG_PORT_STATUS(port), ®); if (ret < 0) return ret; @@ -1659,7 +1632,7 @@ qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; - qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg); + regmap_write(priv->regmap, QCA8K_REG_PORT_STATUS(port), reg); } static void @@ -1689,12 +1662,12 @@ qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, mib = &ar8327_mib[i]; reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; - ret = qca8k_read(priv, reg, &val); + ret = regmap_read(priv->regmap, reg, &val); if (ret < 0) continue; if (mib->size == 2) { - ret = qca8k_read(priv, reg + 4, &hi); + ret = regmap_read(priv->regmap, reg + 4, &hi); if (ret < 0) continue; } @@ -1723,7 +1696,7 @@ qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) int ret; mutex_lock(&priv->reg_mutex); - ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); + ret = regmap_read(priv->regmap, QCA8K_REG_EEE_CTRL, ®); if (ret < 0) goto exit; @@ -1731,7 +1704,7 @@ qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) reg |= lpi_en; else reg &= ~lpi_en; - ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); + ret = regmap_write(priv->regmap, QCA8K_REG_EEE_CTRL, reg); exit: mutex_unlock(&priv->reg_mutex); @@ -1770,8 +1743,8 @@ qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) break; } - qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); + regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), + QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); } static int @@ -1792,9 +1765,9 @@ qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) /* Add this port to the portvlan mask of the other ports * in the bridge */ - ret = qca8k_reg_set(priv, - QCA8K_PORT_LOOKUP_CTRL(i), - BIT(port)); + ret = regmap_set_bits(priv->regmap, + QCA8K_PORT_LOOKUP_CTRL(i), + BIT(port)); if (ret) return ret; if (i != port) @@ -1802,8 +1775,8 @@ qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) } /* Add all other ports to this ports portvlan mask */ - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_MEMBER, port_mask); + ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), + QCA8K_PORT_LOOKUP_MEMBER, port_mask); return ret; } @@ -1824,16 +1797,16 @@ qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) /* Remove this port to the portvlan mask of the other ports * in the bridge */ - qca8k_reg_clear(priv, - QCA8K_PORT_LOOKUP_CTRL(i), - BIT(port)); + regmap_clear_bits(priv->regmap, + QCA8K_PORT_LOOKUP_CTRL(i), + BIT(port)); } /* Set the cpu port to be the only one in the portvlan mask of * this port */ - qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); + regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), + QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); } static int @@ -1873,7 +1846,7 @@ qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) mtu = priv->port_mtu[i]; /* Include L2 header / FCS length */ - return qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN); + return regmap_write(priv->regmap, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN); } static int @@ -1949,13 +1922,13 @@ qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, int ret; if (vlan_filtering) { - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, - QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); + ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), + QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, + QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); } else { - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, - QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); + ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), + QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, + QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); } return ret; @@ -1978,15 +1951,15 @@ qca8k_port_vlan_add(struct dsa_switch *ds, int port, } if (pvid) { - ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), - QCA8K_EGREES_VLAN_PORT_MASK(port), - QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); + ret = regmap_update_bits(priv->regmap, QCA8K_EGRESS_VLAN(port), + QCA8K_EGREES_VLAN_PORT_MASK(port), + QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); if (ret) return ret; - ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), - QCA8K_PORT_VLAN_CVID(vlan->vid) | - QCA8K_PORT_VLAN_SVID(vlan->vid)); + ret = regmap_write(priv->regmap, QCA8K_REG_PORT_VLAN_CTRL0(port), + QCA8K_PORT_VLAN_CVID(vlan->vid) | + QCA8K_PORT_VLAN_SVID(vlan->vid)); } return ret; From patchwork Wed Nov 17 21:04:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625425 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4FAACC433FE for ; Wed, 17 Nov 2021 21:06:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3772461BFB for ; Wed, 17 Nov 2021 21:06:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240809AbhKQVI7 (ORCPT ); Wed, 17 Nov 2021 16:08:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35000 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240374AbhKQVI1 (ORCPT ); Wed, 17 Nov 2021 16:08:27 -0500 Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1CE2C061570; Wed, 17 Nov 2021 13:05:28 -0800 (PST) Received: by mail-ed1-x530.google.com with SMTP id z5so17019640edd.3; Wed, 17 Nov 2021 13:05:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=d+SVoTAK5C5wl38ctM2piKl8MvU2Rt+cFsxV/drb/dE=; b=PQncZbT1J4amBfAODMyQjDAzKPhvlbV6i4e4tLMf91PR2hDXKNK8uBNh7ADgk5OjOj IZaILl1ZvN7BcBkf9ihslBh07biYh4vxjKDWPKJv55mlWmFt6zsUqANGf9HSD4a5WvKg WICFtcBVrnf74+NLbtVdjusRa+F9sVhCvpNFjCH/p327rHpMaGROE+uTa1Jyv6Raja/V W9ZvjTPDoO485HkrK3krBmWcS0KQVBFuV3CNpXlC0jj3HMNAsx7Ijye9ZuPMrDghOgAB RbUXRXDkQDwCr1InoQO8Bx0tkQ0XBdhmRokJsIVCrjZHKZWtIS7lONgSjh62lYuGUvqU 5VeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=d+SVoTAK5C5wl38ctM2piKl8MvU2Rt+cFsxV/drb/dE=; b=tnwYvS8ZsA0z+ETAHxt50UryrjI7sE/y7rfOgpSuVFnLtd6K94OSHPmtM7KLdeUrfe f/Bp3fHtrnECvMMWanAZedUZh0+HnC1bVygFULJuWnHNLX8fq7FbKCyqf0xD45PjTEiE sUygSUmcwkomxuBrNWSQNeWCM67lDfeQ5crtUsceTdktJ+ttqdNj2Mbb5K6Otrpq4sJA izQpEwuup7nREF2mf4gJOlIJdh9jHxeSflkH6n/JtyCgtsfjjKjNfIR4eShfY1wV+kpc lSJgU5qxL82z6+A2ZUCobeKyJGD0GLzb4QICIpQ1ZDsxGe8SI0Ug/Onijgh7E6DwovNX JULw== X-Gm-Message-State: AOAM532dSVC75sVtJ8twwKrUpaJF30va96NTi5dqCWL95RdfVBSAGHen qytTz6G+hW+qurYQyBP0/Dc= X-Google-Smtp-Source: ABdhPJxlXdSLOpdcWeTLvlkdwjgRIMP6De05oHi6jyDKTpdy0hqeHSeZjIWV8pvpsjNbtQQjmbzxog== X-Received: by 2002:a05:6402:516c:: with SMTP id d12mr2652815ede.391.1637183127332; Wed, 17 Nov 2021 13:05:27 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:26 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 09/19] net: dsa: qca8k: add additional MIB counter and make it dynamic Date: Wed, 17 Nov 2021 22:04:41 +0100 Message-Id: <20211117210451.26415-10-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org We are currently missing 2 additional MIB counter present in QCA833x switch. QC832x switch have 39 MIB counter and QCA833X have 41 MIB counter. Add the additional MIB counter and rework the MIB function to print the correct supported counter from the match_data struct. Signed-off-by: Ansuel Smith Reviewed-by: Vladimir Oltean --- drivers/net/dsa/qca8k.c | 23 ++++++++++++++++++++--- drivers/net/dsa/qca8k.h | 4 ++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index 7f71607bec3f..cf4f69b36b47 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -70,6 +70,8 @@ static const struct qca8k_mib_desc ar8327_mib[] = { MIB_DESC(1, 0x9c, "TxExcDefer"), MIB_DESC(1, 0xa0, "TxDefer"), MIB_DESC(1, 0xa4, "TxLateCol"), + MIB_DESC(1, 0xa8, "RXUnicast"), + MIB_DESC(1, 0xac, "TXUnicast"), }; /* The 32bit switch registers are accessed indirectly. To achieve this we need @@ -1638,12 +1640,16 @@ qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, static void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) { + const struct qca8k_match_data *match_data; + struct qca8k_priv *priv = ds->priv; int i; if (stringset != ETH_SS_STATS) return; - for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) + match_data = of_device_get_match_data(priv->dev); + + for (i = 0; i < match_data->mib_count; i++) strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, ETH_GSTRING_LEN); } @@ -1653,12 +1659,15 @@ qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data) { struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + const struct qca8k_match_data *match_data; const struct qca8k_mib_desc *mib; u32 reg, i, val; u32 hi = 0; int ret; - for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) { + match_data = of_device_get_match_data(priv->dev); + + for (i = 0; i < match_data->mib_count; i++) { mib = &ar8327_mib[i]; reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; @@ -1681,10 +1690,15 @@ qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, static int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) { + const struct qca8k_match_data *match_data; + struct qca8k_priv *priv = ds->priv; + if (sset != ETH_SS_STATS) return 0; - return ARRAY_SIZE(ar8327_mib); + match_data = of_device_get_match_data(priv->dev); + + return match_data->mib_count; } static int @@ -2143,14 +2157,17 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, static const struct qca8k_match_data qca8327 = { .id = QCA8K_ID_QCA8327, .reduced_package = true, + .mib_count = QCA8K_QCA832X_MIB_COUNT, }; static const struct qca8k_match_data qca8328 = { .id = QCA8K_ID_QCA8327, + .mib_count = QCA8K_QCA832X_MIB_COUNT, }; static const struct qca8k_match_data qca833x = { .id = QCA8K_ID_QCA8337, + .mib_count = QCA8K_QCA833X_MIB_COUNT, }; static const struct of_device_id qca8k_of_match[] = { diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h index 3722fbb6b461..c5d83514ad2e 100644 --- a/drivers/net/dsa/qca8k.h +++ b/drivers/net/dsa/qca8k.h @@ -21,6 +21,9 @@ #define PHY_ID_QCA8337 0x004dd036 #define QCA8K_ID_QCA8337 0x13 +#define QCA8K_QCA832X_MIB_COUNT 39 +#define QCA8K_QCA833X_MIB_COUNT 41 + #define QCA8K_BUSY_WAIT_TIMEOUT 2000 #define QCA8K_NUM_FDB_RECORDS 2048 @@ -279,6 +282,7 @@ struct ar8xxx_port_status { struct qca8k_match_data { u8 id; bool reduced_package; + u8 mib_count; }; enum { From patchwork Wed Nov 17 21:04:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625429 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EC9C8C433EF for ; Wed, 17 Nov 2021 21:06:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D4845630EF for ; Wed, 17 Nov 2021 21:06:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240476AbhKQVJO (ORCPT ); Wed, 17 Nov 2021 16:09:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35010 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240725AbhKQVI3 (ORCPT ); Wed, 17 Nov 2021 16:08:29 -0500 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CE371C061202; Wed, 17 Nov 2021 13:05:29 -0800 (PST) Received: by mail-ed1-x535.google.com with SMTP id t5so17245656edd.0; Wed, 17 Nov 2021 13:05:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=Vo6cAfjs/htr35w2rIRklqSudZBIEyLbTN6ICJxY3Uk=; b=LNCD6PsNRLRMGhp6gKBkoIaU+mV7Nhe3Ef/GTdf/F/Zf2rVgwMc1x8MzqQnd+FLLag M9tH7mr0NcKWwBHaMDGUmx92h+ErNwcxA+WXupn3HpmgC6yKSyDUlm4/3gRukIyofIE2 Cu0ESfk1YwCZ/+f+5AD23af3/QAr6+hhLIXAzwKXSQm2Jgem0fzmKqv94BKynVnontzq 4V65u1JDsGc21hUd8WL7hkRnwiBhBMcXPflrY5Pp4vCzu1doGX5nNO0rNxgaWlmK3kWy RIZXzzI8oWHIbUGLfOw5NJMEgAYx5Z8ejic8S2paOP6xFRQ/akRNrc5sAAnn217VVUuh xvKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Vo6cAfjs/htr35w2rIRklqSudZBIEyLbTN6ICJxY3Uk=; b=6ARXAYoFgoYV7WyrfZFs1dpRupAVHfWDXukCNDDW4R4QS1BS/5awyiPq+lcqUr2HXy Jdi62FlHgIQF/iWoOSWAYJZDOrU5R4nOG+GePPCNaevA6wqfvsruBM4KaS0dimNtS/tc Sw4xPzCTwQotJFwnHs0Aq4vrMP89mkrzb7qCRq6nTO9OQYUALHRkdOEcNVfj5DJyDVgy C958AyHAxI3FgRfhA6lEFbAs5wN0DzgVrodD8BlqS56mEqh2PEy4MYKdR4S61IXWsGl9 AUCUFKcjctm8jsHiPIhOiGRDNwpCECkePPM+RRJrP9QSwzxb4jTnyjzhxgo34OnO8yVS l5fQ== X-Gm-Message-State: AOAM53031GewRhSwzkaDVrSjil4ULkgg/7UFVx9mNHeJWEdBATq85SBs 3AW7GfefcfS/qdEjqNIIqp0= X-Google-Smtp-Source: ABdhPJxW1eYue4tIhZOFwIbC6kcXdkHrl2GStBjV9W4g2INHRXVlzzEX0JGt6agpaeloVle8MankdQ== X-Received: by 2002:a17:906:ce2a:: with SMTP id sd10mr25635129ejb.154.1637183128359; Wed, 17 Nov 2021 13:05:28 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:28 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 10/19] net: dsa: qca8k: add support for port fast aging Date: Wed, 17 Nov 2021 22:04:42 +0100 Message-Id: <20211117210451.26415-11-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The switch doesn't support fast aging but it does support the flush of the ARL table for a specific port. Add this function to simulate fast aging and proprely support stp state set. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index cf4f69b36b47..d73886b36e6a 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1823,6 +1823,16 @@ qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); } +static void +qca8k_port_fast_age(struct dsa_switch *ds, int port) +{ + struct qca8k_priv *priv = ds->priv; + + mutex_lock(&priv->reg_mutex); + qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); + mutex_unlock(&priv->reg_mutex); +} + static int qca8k_port_enable(struct dsa_switch *ds, int port, struct phy_device *phy) @@ -2031,6 +2041,7 @@ static const struct dsa_switch_ops qca8k_switch_ops = { .port_stp_state_set = qca8k_port_stp_state_set, .port_bridge_join = qca8k_port_bridge_join, .port_bridge_leave = qca8k_port_bridge_leave, + .port_fast_age = qca8k_port_fast_age, .port_fdb_add = qca8k_port_fdb_add, .port_fdb_del = qca8k_port_fdb_del, .port_fdb_dump = qca8k_port_fdb_dump, From patchwork Wed Nov 17 21:04:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625431 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4FCCFC433FE for ; Wed, 17 Nov 2021 21:06:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 380A361BFA for ; Wed, 17 Nov 2021 21:06:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240882AbhKQVJP (ORCPT ); Wed, 17 Nov 2021 16:09:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35014 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240717AbhKQVIa (ORCPT ); Wed, 17 Nov 2021 16:08:30 -0500 Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BC8B4C061206; Wed, 17 Nov 2021 13:05:30 -0800 (PST) Received: by mail-ed1-x52f.google.com with SMTP id x6so5310663edr.5; Wed, 17 Nov 2021 13:05:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=yo+lOtp/Uy/wF44C6fwYa7t1J8Hm84Is4/Z4Fgruu1U=; b=Po+mzU0Q8Vct6JbeN7eeW3FCL7vDYucrQmODzP2ElVbSKE+tyLV3AwTS4n3PCe+IAn DMzBRly/n2e0pexZmBFxYe+rCyG+d19b1F2xj/pgHfZnfrM41EjHGRw4nfn7cYQm82Vn p87sNot6roZL1sP+RI1GrIno6hDGfc1qtH5eoLKBLLwNEnHNOMwgl3UqDQkRnVjw2faJ eEgWMdlGXPnQ8ETWzYM5MYwm3ycAjp2CYbyynPXmzUbzb1LzHyfQjx95pwKvKetqnR4U qLBXiKCcaagazl1sR4VYqWw3n6uDehiILsVu7wU7aMh5rqaM8kqbwaGu3HS9JvxIFI06 F66w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yo+lOtp/Uy/wF44C6fwYa7t1J8Hm84Is4/Z4Fgruu1U=; b=utHdzeHOHv239WGbltgtyY8Q/O9z9SHDGZ6tmT8dtMcXWQLfl3qMXd0tiyhr1Op5bX r8K0+oJ5plOcXLq188oUOAkUBxsbg5IGzgM3vbbx9OMz1FdLvJuLXQ8SURg8icXSyW/Y KU4bf8XwsqNqlDngCTLHz96s8GmoLJuA8hMsOeFRaZxoDA+H7XJaFWHSQAweGNdJz0jJ 6o520eTMB6hDnop6dIwHkt0J4vzZYC/oleznsD+HQ+zLvzWyvAD2VObzWFPy3JE2295x eRbcYNQEK/TvacHYpReIq5GGafE62AZM/u0BT1zzp7ABQoo35+A0H0IvICH3bmun7Mtw kxHg== X-Gm-Message-State: AOAM530wUQXWGxnhjgFKqiHf8BOFwKWqDqJwe6pmzG2NAN2veWCm9D1v ADGHYCDn/bklpq1L3O0e/Y8= X-Google-Smtp-Source: ABdhPJw0IZek7AwZa+zFIBAf5yA29ISgJe1TEf7BwoNk7KQkq+Q5Ip+13FSfkrDdR7Ni6TyqxGQySA== X-Received: by 2002:a17:906:18b2:: with SMTP id c18mr26269889ejf.403.1637183129247; Wed, 17 Nov 2021 13:05:29 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:29 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 11/19] net: dsa: qca8k: add support for mirror mode Date: Wed, 17 Nov 2021 22:04:43 +0100 Message-Id: <20211117210451.26415-12-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The switch support mirror mode. Only one port can set as mirror port and every other port can set to both ingress and egress mode. The mirror port is disabled and reverted to normal operation once every port is removed from sending packet to the mirror mode. Also modify the fdb logit to send packet to both destination and mirror port by default to support mirror mode. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 95 +++++++++++++++++++++++++++++++++++++++++ drivers/net/dsa/qca8k.h | 5 +++ 2 files changed, 100 insertions(+) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index d73886b36e6a..a74099131e3d 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1938,6 +1938,99 @@ qca8k_port_fdb_dump(struct dsa_switch *ds, int port, return 0; } +static int +qca8k_port_mirror_add(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror, + bool ingress) +{ + struct qca8k_priv *priv = ds->priv; + int monitor_port, ret; + u32 reg, val; + + /* Check for existent entry */ + if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) + return -EEXIST; + + ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); + if (ret) + return ret; + + /* QCA83xx can have only one port set to mirror mode. + * Check that the correct port is requested and return error otherwise. + * When no mirror port is set, the values is set to 0xF + */ + monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); + if (monitor_port != 0xF && monitor_port != mirror->to_local_port) + return -EEXIST; + + /* Set the monitor port */ + val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, + mirror->to_local_port); + ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, + QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); + if (ret) + return ret; + + if (ingress) { + reg = QCA8K_PORT_LOOKUP_CTRL(port); + val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; + } else { + reg = QCA8K_REG_PORT_HOL_CTRL1(port); + val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; + } + + ret = regmap_update_bits(priv->regmap, reg, val, val); + if (ret) + return ret; + + /* Track mirror port for tx and rx to decide when the + * mirror port has to be disabled. + */ + if (ingress) + priv->mirror_rx |= BIT(port); + else + priv->mirror_tx |= BIT(port); + + return 0; +} + +static void +qca8k_port_mirror_del(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror) +{ + struct qca8k_priv *priv = ds->priv; + u32 reg, val; + int ret; + + if (mirror->ingress) { + reg = QCA8K_PORT_LOOKUP_CTRL(port); + val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; + } else { + reg = QCA8K_REG_PORT_HOL_CTRL1(port); + val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; + } + + ret = regmap_clear_bits(priv->regmap, reg, val); + if (ret) + goto err; + + if (mirror->ingress) + priv->mirror_rx &= ~BIT(port); + else + priv->mirror_tx &= ~BIT(port); + + /* No port set to send packet to mirror port. Disable mirror port */ + if (!priv->mirror_rx && !priv->mirror_tx) { + val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); + ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, + QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); + if (ret) + goto err; + } +err: + dev_err(priv->dev, "Failed to del mirror port from %d", port); +} + static int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, struct netlink_ext_ack *extack) @@ -2045,6 +2138,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = { .port_fdb_add = qca8k_port_fdb_add, .port_fdb_del = qca8k_port_fdb_del, .port_fdb_dump = qca8k_port_fdb_dump, + .port_mirror_add = qca8k_port_mirror_add, + .port_mirror_del = qca8k_port_mirror_del, .port_vlan_filtering = qca8k_port_vlan_filtering, .port_vlan_add = qca8k_port_vlan_add, .port_vlan_del = qca8k_port_vlan_del, diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h index c5d83514ad2e..d25afdab4dea 100644 --- a/drivers/net/dsa/qca8k.h +++ b/drivers/net/dsa/qca8k.h @@ -177,6 +177,7 @@ #define QCA8K_VTU_FUNC1_FULL BIT(4) #define QCA8K_REG_GLOBAL_FW_CTRL0 0x620 #define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) +#define QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM GENMASK(7, 4) #define QCA8K_REG_GLOBAL_FW_CTRL1 0x624 #define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24) #define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16) @@ -198,6 +199,7 @@ #define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3) #define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4) #define QCA8K_PORT_LOOKUP_LEARN BIT(20) +#define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25) #define QCA8K_REG_GLOBAL_FC_THRESH 0x800 #define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16) @@ -262,6 +264,7 @@ enum qca8k_fdb_cmd { QCA8K_FDB_FLUSH = 1, QCA8K_FDB_LOAD = 2, QCA8K_FDB_PURGE = 3, + QCA8K_FDB_FLUSH_PORT = 5, QCA8K_FDB_NEXT = 6, QCA8K_FDB_SEARCH = 7, }; @@ -302,6 +305,8 @@ struct qca8k_ports_config { struct qca8k_priv { u8 switch_id; u8 switch_revision; + u8 mirror_rx; + u8 mirror_tx; bool legacy_phy_port_mapping; struct qca8k_ports_config ports_config; struct regmap *regmap; From patchwork Wed Nov 17 21:04:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625435 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F30DFC433FE for ; Wed, 17 Nov 2021 21:06:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DCD456321A for ; Wed, 17 Nov 2021 21:06:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240886AbhKQVJR (ORCPT ); Wed, 17 Nov 2021 16:09:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240728AbhKQVIb (ORCPT ); Wed, 17 Nov 2021 16:08:31 -0500 Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8D9ACC061766; Wed, 17 Nov 2021 13:05:31 -0800 (PST) Received: by mail-ed1-x532.google.com with SMTP id g14so16956437edb.8; Wed, 17 Nov 2021 13:05:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=gsCK9T2ovNwicQlA1GjlqOqzDUDeGjBNagUAANlbaoo=; b=jWJRqi2ajKfhIFCBsvnHdwJni5PiJTxFP+Z7+e7j/ULo2tg8xaXjANO4KK08DKBgOK gIHqcbFqwj974t1/M6hTzcx7AQCnw27/GZm0+u/gQOFdpe8arlwsuQrYwZiZLhLb4DdI JZhlc6TIXWVe9N3cAhzGjyxvaHK0NNYvfMSg1YdED74zbZJ00/x+li1J8mvDgqWwXIwv dA3xYQAWbQ0TCgdVNIn/Qd7FZFJ0C1fcv+bgNBAEkYypsiFyGEgwiVPAOeySQnPnyioQ gZIGtgKEcNaCDL4mmAMXMJvR7IsvVl1lOWUAN8Q+/4CM5lk+/j+HFCLj7vqTRCwesPkD Xgtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gsCK9T2ovNwicQlA1GjlqOqzDUDeGjBNagUAANlbaoo=; b=QQYed0NeCSMPN5aowLkft6bnH5E+aF/Aho62+q3ouvrNqixYzy+uxXKt1dLMj8faTH 3GWSvb1ClL4/VLM/VLM1hLsbv0mVZrigLMHwUQ+RGnkwtzHOww5oXkpB0JkimiZf5XUD sicrP5p1AKjBUvhF48vztv/ADfyjLrW2gfwTP8WlZCk8IVGgZrf227RP9zDeDMVh0tMy BzFRiMbNoYGVxT3gLe6+RLsfq3oNzTVdA0gco80ocaDcQnQlQLWQw2/kX//IceZfYoGl ykAHWDCSO50GFUc9M4cIXuCSS32wBmZqxLF1xjA0fyafVHwA3N8Bpog1sAeLgrllibCv cYEw== X-Gm-Message-State: AOAM532vSABf0rMVCOGXypKZT2A51QdIJhw2oj/2FTlJBRD7LYRdUhKI HQBonCBCbq6NPb3jU68pM1o= X-Google-Smtp-Source: ABdhPJxKjvy55eYA0CROezf9hfJ+fuZoU6VA5Ml34SB53aGJskXr29tWFECd0DKjnVFQTsxtMoypxw== X-Received: by 2002:a17:907:8a24:: with SMTP id sc36mr25175534ejc.530.1637183130075; Wed, 17 Nov 2021 13:05:30 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:29 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 12/19] net: dsa: qca8k: add set_ageing_time support Date: Wed, 17 Nov 2021 22:04:44 +0100 Message-Id: <20211117210451.26415-13-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org qca8k support setting ageing time in set of 7s. Add support for it and return error with value greater than the max value accepted of 7645m. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 18 ++++++++++++++++++ drivers/net/dsa/qca8k.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index a74099131e3d..50f19549b97d 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1833,6 +1833,23 @@ qca8k_port_fast_age(struct dsa_switch *ds, int port) mutex_unlock(&priv->reg_mutex); } +static int +qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) +{ + struct qca8k_priv *priv = ds->priv; + unsigned int secs = msecs / 1000; + u32 val; + + /* AGE_TIME reg is set in 7s step */ + val = secs / 7; + + if (val > FIELD_MAX(QCA8K_ATU_AGE_TIME_MASK)) + return -ERANGE; + + return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, + QCA8K_ATU_AGE_TIME(val)); +} + static int qca8k_port_enable(struct dsa_switch *ds, int port, struct phy_device *phy) @@ -2125,6 +2142,7 @@ static const struct dsa_switch_ops qca8k_switch_ops = { .get_strings = qca8k_get_strings, .get_ethtool_stats = qca8k_get_ethtool_stats, .get_sset_count = qca8k_get_sset_count, + .set_ageing_time = qca8k_set_ageing_time, .get_mac_eee = qca8k_get_mac_eee, .set_mac_eee = qca8k_set_mac_eee, .port_enable = qca8k_port_enable, diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h index d25afdab4dea..e1298179d7cb 100644 --- a/drivers/net/dsa/qca8k.h +++ b/drivers/net/dsa/qca8k.h @@ -175,6 +175,9 @@ #define QCA8K_VTU_FUNC1_BUSY BIT(31) #define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16) #define QCA8K_VTU_FUNC1_FULL BIT(4) +#define QCA8K_REG_ATU_CTRL 0x618 +#define QCA8K_ATU_AGE_TIME_MASK GENMASK(15, 0) +#define QCA8K_ATU_AGE_TIME(x) FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x)) #define QCA8K_REG_GLOBAL_FW_CTRL0 0x620 #define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) #define QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM GENMASK(7, 4) From patchwork Wed Nov 17 21:04:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625433 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29E3EC433F5 for ; Wed, 17 Nov 2021 21:06:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0C06A6321A for ; Wed, 17 Nov 2021 21:06:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240893AbhKQVJS (ORCPT ); Wed, 17 Nov 2021 16:09:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35030 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240730AbhKQVIb (ORCPT ); Wed, 17 Nov 2021 16:08:31 -0500 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 54AC1C0613B9; Wed, 17 Nov 2021 13:05:32 -0800 (PST) Received: by mail-ed1-x52b.google.com with SMTP id r11so16915280edd.9; Wed, 17 Nov 2021 13:05:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=UCSM6+D8ualFSitAGjm+mGVCLlZHTQ0xZ95gau5bkyA=; b=PRHZ6dN9XlRRqWlmuGc15k9QvpDTsHu4ihHGtka5zvywAq8QN0YDAu0fWzmy6Ov31A qwyc7rc8mqU/JFd2z3QjETxof8Eshr9xOmVKkKo5kQ1DKTP8aiJAcJxTi/kqmIfqjVBg 4nAl3RoejW9JJtbmRqm0FRHuUxxhUWV20J5dIZuNcqc5vRlY/9He+8lT9lA0HeMLuO8Q XYVzmZ5rGHIncVDvhePPdiuBjJkzG19tBAN/dnD3xfvVL0oxecGr1oDWAOxN1uXWJojH jDSbudJx8uJRVcFxmouzw6IaBg94KxIwiRAHHBHfwaZnCpuIToBqPOHt073iG8jpD4wj 7/yA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UCSM6+D8ualFSitAGjm+mGVCLlZHTQ0xZ95gau5bkyA=; b=EuEtEYp29db2GKqtfRN0ikMyOC2LXIG4aTCx0/RFVhTlSbv2u80Ff4ZaNpcE2el5r4 jt29s4p8h16OQyiOb5B2/EgGUN2WrzAq7b9/OrQ4BTWntAad33SIKFoSK75mpFbL/bYt Er5JMZAnxVG0ySY2e5f8Dw+Ku/tfs5nGuGFig11ylAMcHuaXgKyelqYAYlDdBbHOXvkf nJuuxrHqyy9oSjgTowCsK23oD07ZOoEPOFCjK+SvDG75IjJ2siwVWW7EJQSAGkrFF3xC dFcIa+EjM5twd+oa3Kw3cSfDJu/nD/mG066oj4KfCZiRDVcaNAb4D+SExHpMkxyldAIQ t7Pg== X-Gm-Message-State: AOAM533AE/y2INqNc6hGeXt/oNBJx8QLxwt9tgzRkgQUKZmdtVMGTpMN fuDjZsmuTCcPfD6Jy6HKn24= X-Google-Smtp-Source: ABdhPJyzmQEPjXZo8Fj5SxEpMSg1eqhAY3MOl9hJp/U/H0Tj2/fSgisxbf39d8mlQZ9C1f8c1Dr4kg== X-Received: by 2002:a17:906:5653:: with SMTP id v19mr25744014ejr.360.1637183130841; Wed, 17 Nov 2021 13:05:30 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:30 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 13/19] net: dsa: qca8k: add min/max ageing time Date: Wed, 17 Nov 2021 22:04:45 +0100 Message-Id: <20211117210451.26415-14-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add min and max ageing value for qca8k switch. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index 50f19549b97d..dda99263fe8c 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1291,6 +1291,10 @@ qca8k_setup(struct dsa_switch *ds) /* We don't have interrupts for link changes, so we need to poll */ ds->pcs_poll = true; + /* Set min a max ageing value supported */ + ds->ageing_time_min = 7000; + ds->ageing_time_max = 458745000; + return 0; } From patchwork Wed Nov 17 21:04:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625437 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC36EC433F5 for ; Wed, 17 Nov 2021 21:06:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9B34363247 for ; Wed, 17 Nov 2021 21:06:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240778AbhKQVJ2 (ORCPT ); Wed, 17 Nov 2021 16:09:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34992 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234071AbhKQVI4 (ORCPT ); Wed, 17 Nov 2021 16:08:56 -0500 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B907C061208; Wed, 17 Nov 2021 13:05:33 -0800 (PST) Received: by mail-ed1-x52e.google.com with SMTP id l25so514583eda.11; Wed, 17 Nov 2021 13:05:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=Qmv8qo+QxDVPN6UIObyaH8GywsYhFGmXd4xEC2qvNt0=; b=lkS4girpWq6e+Bw4q/pxFbyJjxoSII8F7mm5xU88aktLy5s1tFmeE8pGJHZGkNNgah VqoU2USxjzQVFXenWvNIEytVVWaZKDtKs+3h4TdyaDBWc5csKmPhEAIIqxBXi2Gt0KCo rOLlhSEIhoeVyZOVwd2RlSnc9faYaA6zBaGaiTuxi/iIOQeUiVUlD0nfLvyyvx9GL5ME 1MgOBTDWv0Cmetj4oaymQ4YRXZBypm8u3KOIBAnUH+EYc+zjNmXadd6jEy6YLxK61e5B Zps0JS1RnMGkogaOAUgGyjTX7/r7EnD0VQtMx4zy++SM3ZFIE0iSyUvBBpzNHto7cR/L aA5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Qmv8qo+QxDVPN6UIObyaH8GywsYhFGmXd4xEC2qvNt0=; b=cHgbXNh+G3YfVA722J1E3ptV1ENT8AoZSsfa1Z+lIhg5m7ARv8p0+F2G6u/8E0k5ik 7b1VNk59D5NVx13nBxtXXqTMch4fdAjLgFlrobUVr2TjRj58LQOikmKIdK4bEV0qAOYs lKKlsxTUkIzCSxPWZpxjyNEC5gNAiHUG0+xvQ+wLVE+G5JKCYmdoMS/OPQj8bcL7kjga vHQQzagMTyb204Ark16b/YJMpXK/i45L5oyhVoUzHXhzw2wJQEtJx1AULxz2OHBzEEws cbdklsg9MHoHE5Kw9NnqYU4s8UdJXc8DWHlnzET729fwyKNAcRhii/DlIx46L76KNT0+ L2jw== X-Gm-Message-State: AOAM533Burrwb9c3X/EsmBp4A1V7aq6mZh94D1Up04BdWYfM72CrYRbo h9+n7TPV0KHYXUuH/sHS9pUtJ8//P6Y= X-Google-Smtp-Source: ABdhPJzKubM5jPoYAyJYpFSMOiXVM7lLmZGfeKqZ+Sj4g9FiHP9R059s0t0/KxLoI/5i7nbGJeIINg== X-Received: by 2002:a17:907:a40b:: with SMTP id sg11mr24991330ejc.534.1637183131680; Wed, 17 Nov 2021 13:05:31 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:31 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 14/19] net: dsa: qca8k: add support for mdb_add/del Date: Wed, 17 Nov 2021 22:04:46 +0100 Message-Id: <20211117210451.26415-15-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add support for mdb add/del function. The ARL table is used to insert the rule. A new search function is introduced to search the rule and add additional port to it. If every port is removed from the rule, it's removed. It's set STATIC in the ARL table (aka it doesn't age) to not be flushed by fast age function. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 82 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index dda99263fe8c..a217c842ab45 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -417,6 +417,23 @@ qca8k_fdb_flush(struct qca8k_priv *priv) mutex_unlock(&priv->reg_mutex); } +static int +qca8k_fdb_search(struct qca8k_priv *priv, struct qca8k_fdb *fdb, const u8 *mac, u16 vid) +{ + int ret; + + mutex_lock(&priv->reg_mutex); + qca8k_fdb_write(priv, vid, 0, mac, 0); + ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); + if (ret < 0) + goto exit; + + ret = qca8k_fdb_read(priv, fdb); +exit: + mutex_unlock(&priv->reg_mutex); + return ret; +} + static int qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) { @@ -1959,6 +1976,69 @@ qca8k_port_fdb_dump(struct dsa_switch *ds, int port, return 0; } +static int +qca8k_port_mdb_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_mdb *mdb) +{ + struct qca8k_priv *priv = ds->priv; + struct qca8k_fdb fdb = { 0 }; + const u8 *addr = mdb->addr; + u8 port_mask = BIT(port); + u16 vid = mdb->vid; + int ret; + + /* Check if entry already exist */ + ret = qca8k_fdb_search(priv, &fdb, addr, vid); + if (ret < 0) + return ret; + + /* Rule exist. Delete first */ + if (!fdb.aging) { + ret = qca8k_fdb_del(priv, addr, fdb.port_mask, vid); + if (ret) + return ret; + } + + /* Add port to fdb portmask */ + fdb.port_mask |= port_mask; + + return qca8k_port_fdb_insert(priv, addr, fdb.port_mask, vid); +} + +static int +qca8k_port_mdb_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_mdb *mdb) +{ + struct qca8k_priv *priv = ds->priv; + struct qca8k_fdb fdb = { 0 }; + const u8 *addr = mdb->addr; + u8 port_mask = BIT(port); + u16 vid = mdb->vid; + int ret; + + /* Check if entry already exist */ + ret = qca8k_fdb_search(priv, &fdb, addr, vid); + if (ret < 0) + return ret; + + /* Rule doesn't exist. Why delete? */ + if (!fdb.aging) + return -EINVAL; + + ret = qca8k_fdb_del(priv, addr, port_mask, vid); + if (ret) + return ret; + + /* Only port in the rule is this port. Don't re insert */ + if (fdb.port_mask == port_mask) + return 0; + + /* Remove port from port mask */ + fdb.port_mask &= ~port_mask; + + return qca8k_port_fdb_insert(priv, addr, fdb.port_mask, vid); +} + static int qca8k_port_mirror_add(struct dsa_switch *ds, int port, struct dsa_mall_mirror_tc_entry *mirror, @@ -2160,6 +2240,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = { .port_fdb_add = qca8k_port_fdb_add, .port_fdb_del = qca8k_port_fdb_del, .port_fdb_dump = qca8k_port_fdb_dump, + .port_mdb_add = qca8k_port_mdb_add, + .port_mdb_del = qca8k_port_mdb_del, .port_mirror_add = qca8k_port_mirror_add, .port_mirror_del = qca8k_port_mirror_del, .port_vlan_filtering = qca8k_port_vlan_filtering, From patchwork Wed Nov 17 21:04:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625439 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49A0EC433F5 for ; Wed, 17 Nov 2021 21:06:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 32DAE61BFA for ; Wed, 17 Nov 2021 21:06:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240900AbhKQVJd (ORCPT ); Wed, 17 Nov 2021 16:09:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35000 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240792AbhKQVI5 (ORCPT ); Wed, 17 Nov 2021 16:08:57 -0500 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0C02DC06120A; Wed, 17 Nov 2021 13:05:34 -0800 (PST) Received: by mail-ed1-x535.google.com with SMTP id w1so16993049edc.6; Wed, 17 Nov 2021 13:05:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=RLFHG8l3wenVTzX4laLb0bZe8AmwHHmFTy9b1c1u5XA=; b=G1e7H3HRCbSPoQAsbaJibBh/sUmWDl+l2UlDkPc0QokZpuDEBeWh/LW2WHDphiRkyS rsuhAB50AyTJJ3GHHas3zt/v3BNMoH18eBBQyUXHR/GHZfsg9Iu7kJK7s+oYtRlo2LWk U6cFZ8rlS2T9Kl/zLu44VXs3ly78YGyUNsCw/x0VqC/RdAP4snJD4+iJedtJVv5fPDlF 2nSNbmI0+ip49zN2m/AOr5YeMvBHfTXjIMDtpBcIsd3sbr7Uaxu3Q5GVaKY6c0yYgkkX hquiRvCrB2kPU60Wj7D+jujVcDECN29bRb4mimfEJ0i1Lp1Edko98QfO0yYmfOceJCoA KqpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RLFHG8l3wenVTzX4laLb0bZe8AmwHHmFTy9b1c1u5XA=; b=IDU5rThkCvsZa8BdSzkKW1/nsrl6PpRkBNZY1EW5tugmh3V8E6E6E/1lHydZSyTUmE nfL7NL1nyBdHdA2uO5c2p5IE49uHaKYYth51BHayFcRgMC1w3KCCz2npeA6xMVv8Lrgl nXW3UP19mu1nDmIPwf+EzIO1O55YoESn+VxhWzDo65QgfDkVoEHFZF0ZdwkgKTfo19U0 mXTFjDSEYYFLeL4zbVymnogqXe6Du34Zh6MER8VyRzkrRMpgtDQlXuxdaNY20X1Rr83x btqTOP11fSsMFNis9gteOfA69zdwiZr2UvTI3xsZtdniZbxs7VqDU84+KhlU/Rr2cO8m kYRA== X-Gm-Message-State: AOAM531q1eaGTnQO8nZcu7N157iLgxX4LOOku3xiuq8VMDHSzF66o46A ELMgdQCYmLVIW/YEV1Cs3ow= X-Google-Smtp-Source: ABdhPJyhz/xZLmQcxiN76GthVJJUuo3AKQLK0A6OZAm8Sv98zipbq/yls8RgN22ZTe+n1JEqNMaf9Q== X-Received: by 2002:a17:906:b84f:: with SMTP id ga15mr24828786ejb.4.1637183132551; Wed, 17 Nov 2021 13:05:32 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:32 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 15/19] net: dsa: qca8k: add LAG support Date: Wed, 17 Nov 2021 22:04:47 +0100 Message-Id: <20211117210451.26415-16-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add LAG support to this switch. In Documentation this is described as trunk mode. A max of 4 LAGs are supported and each can support up to 4 port. The only tx mode supported is Hash mode and no reference is present for active backup or any other mode in Documentation. When no port are present in the trunk, the trunk is disabled in the switch. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 117 ++++++++++++++++++++++++++++++++++++++++ drivers/net/dsa/qca8k.h | 24 +++++++++ 2 files changed, 141 insertions(+) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index a217c842ab45..c3234988aabf 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1312,6 +1312,9 @@ qca8k_setup(struct dsa_switch *ds) ds->ageing_time_min = 7000; ds->ageing_time_max = 458745000; + /* Set max number of LAGs supported */ + ds->num_lag_ids = QCA8K_NUM_LAGS; + return 0; } @@ -2220,6 +2223,118 @@ qca8k_get_tag_protocol(struct dsa_switch *ds, int port, return DSA_TAG_PROTO_QCA; } +static bool +qca8k_lag_can_offload(struct dsa_switch *ds, + struct net_device *lag, + struct netdev_lag_upper_info *info) +{ + struct dsa_port *dp; + int id, members = 0; + + id = dsa_lag_id(ds->dst, lag); + if (id < 0 || id >= ds->num_lag_ids) + return false; + + dsa_lag_foreach_port(dp, ds->dst, lag) + /* Includes the port joining the LAG */ + members++; + + if (members > QCA8K_NUM_PORTS_FOR_LAG) + return false; + + if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) + return false; + + return true; +} + +static int +qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, + struct net_device *lag, bool delete) +{ + struct qca8k_priv *priv = ds->priv; + int ret, id, i; + u32 val; + + id = dsa_lag_id(ds->dst, lag); + + /* Read current port member */ + ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); + if (ret) + return ret; + + /* Shift val to the correct trunk */ + val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); + val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; + if (delete) + val &= ~BIT(port); + else + val |= BIT(port); + + /* Update port member. With empty portmap disable trunk */ + ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, + QCA8K_REG_GOL_TRUNK_MEMBER(id) | + QCA8K_REG_GOL_TRUNK_EN(id), + !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | + val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); + + /* Search empty member if adding or port on deleting */ + for (i = 0; i < 4; i++) { + ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); + if (ret) + return ret; + + val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); + val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; + + if (delete) { + /* If port flagged to be disabled assume this member is + * empty + */ + if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) + continue; + + val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; + if (val != port) + continue; + } else { + /* If port flagged to be enabled assume this member is + * already set + */ + if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) + continue; + } + + /* We find the member to remove */ + break; + } + + /* Set port in the correct port mask or disable port if in delate mode */ + return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), + QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | + QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), + !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | + port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); +} + +static int +qca8k_port_lag_join(struct dsa_switch *ds, int port, + struct net_device *lag, + struct netdev_lag_upper_info *info) +{ + if (!qca8k_lag_can_offload(ds, lag, info)) + return -EOPNOTSUPP; + + return qca8k_lag_refresh_portmap(ds, port, lag, false); +} + +static int +qca8k_port_lag_leave(struct dsa_switch *ds, int port, + struct net_device *lag) +{ + return qca8k_lag_refresh_portmap(ds, port, lag, true); +} + static const struct dsa_switch_ops qca8k_switch_ops = { .get_tag_protocol = qca8k_get_tag_protocol, .setup = qca8k_setup, @@ -2253,6 +2368,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = { .phylink_mac_link_down = qca8k_phylink_mac_link_down, .phylink_mac_link_up = qca8k_phylink_mac_link_up, .get_phy_flags = qca8k_get_phy_flags, + .port_lag_join = qca8k_port_lag_join, + .port_lag_leave = qca8k_port_lag_leave, }; static int diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h index e1298179d7cb..5310022569f3 100644 --- a/drivers/net/dsa/qca8k.h +++ b/drivers/net/dsa/qca8k.h @@ -15,6 +15,8 @@ #define QCA8K_NUM_PORTS 7 #define QCA8K_NUM_CPU_PORTS 2 #define QCA8K_MAX_MTU 9000 +#define QCA8K_NUM_LAGS 4 +#define QCA8K_NUM_PORTS_FOR_LAG 4 #define PHY_ID_QCA8327 0x004dd034 #define QCA8K_ID_QCA8327 0x12 @@ -204,6 +206,28 @@ #define QCA8K_PORT_LOOKUP_LEARN BIT(20) #define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25) +#define QCA8K_REG_GOL_TRUNK_CTRL0 0x700 +/* 4 max trunk first + * first 6 bit for member bitmap + * 7th bit is to enable trunk port + */ +#define QCA8K_REG_GOL_TRUNK_SHIFT(_i) ((_i) * 8) +#define QCA8K_REG_GOL_TRUNK_EN_MASK BIT(7) +#define QCA8K_REG_GOL_TRUNK_EN(_i) (QCA8K_REG_GOL_TRUNK_EN_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) +#define QCA8K_REG_GOL_TRUNK_MEMBER_MASK GENMASK(6, 0) +#define QCA8K_REG_GOL_TRUNK_MEMBER(_i) (QCA8K_REG_GOL_TRUNK_MEMBER_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) +/* 0x704 for TRUNK 0-1 --- 0x708 for TRUNK 2-3 */ +#define QCA8K_REG_GOL_TRUNK_CTRL(_i) (0x704 + (((_i) / 2) * 4)) +#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK GENMASK(3, 0) +#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK BIT(3) +#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK GENMASK(2, 0) +#define QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i) (((_i) / 2) * 16) +#define QCA8K_REG_GOL_MEM_ID_SHIFT(_i) ((_i) * 4) +/* Complex shift: FIRST shift for port THEN shift for trunk */ +#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j) (QCA8K_REG_GOL_MEM_ID_SHIFT(_j) + QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i)) +#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) +#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) + #define QCA8K_REG_GLOBAL_FC_THRESH 0x800 #define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16) #define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x) From patchwork Wed Nov 17 21:04:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625441 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 47203C433F5 for ; Wed, 17 Nov 2021 21:06:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 33A476325B for ; Wed, 17 Nov 2021 21:06:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240909AbhKQVJg (ORCPT ); Wed, 17 Nov 2021 16:09:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240718AbhKQVI5 (ORCPT ); Wed, 17 Nov 2021 16:08:57 -0500 Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D8A66C06120C; Wed, 17 Nov 2021 13:05:34 -0800 (PST) Received: by mail-ed1-x52a.google.com with SMTP id l25so514863eda.11; Wed, 17 Nov 2021 13:05:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=YnUMLgDp1zo1jtmDh7aRg/AZvHUDDRU4suCv1fQWM/E=; b=H9ONFhmdPbc82w1+RRAq5AqXW8ukuy2z6WdNCF3TiHP0voSOaR+912jrudXH+Or5We mrnt2deYIgXtWQkWqJnSq1HJor658sOzVNeonat3w3phhQmY0yKNzAIQkmW+hueqg9Za 0foeO8eF3Rs9BeGlQ6epsM835EGUZ0N8xteOBmlCiasQFeTOAJ7vM5qUmbtVrit/AFlr lEoYW3riM7oK1NFFEIBvSaMrU7Xg2FLni0+dtScWOvDO2hLXKAeVrSRlo0F9rWAau6YP rBy9K7Ylj8hwX8a+IxMikOBM5lAVY+8uvdxceGMBrSM/LucxTd1vFYa+ctFHqV+1pw3h 5XaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YnUMLgDp1zo1jtmDh7aRg/AZvHUDDRU4suCv1fQWM/E=; b=5UwprFPHC88yKOlkeMuq455MHHMf44s6BzW000oVInCSe+FcL42ALbseBl6SN1Vqr2 hf9Rym/p0MqoXf3ybhjbj7XtXw0fQzeXNYHvhOB8cn1nMOXkUGVxsT5S2BVcajjUPlmS 5z5utQhzMl5iky5aJ8Pd9re+8MX3rvEm+ebwkXJ6gwidr94/dOU22IPG7cPUZTFNS/oT ZTJ6bCpN536Bwj/GYsFyE+LiPMSGsAB6VYTAF8wtGupHFZDOYTGh/HYXgerK5FLylRhE v7NySPTL84nyBbh8Djp9N9GjzPXFGp29wcoR8KyFzM1lAPITOW8OIm3jEVRvkrodpVtt 3YsQ== X-Gm-Message-State: AOAM532opV/+d7V+1sCFaJVdNjmD3DRwFFRm0UFLPUGsMXfPDLkXopVh s1eU4SI+dp6vcORtV2Td1VU= X-Google-Smtp-Source: ABdhPJyMHGymr1h4ZZot9sUpAhSQqO4WfRD9qpBhGUjR7OO0NFFN79iodTQGYpnLUW5QQ4hYczgHUg== X-Received: by 2002:a17:907:a088:: with SMTP id hu8mr26457266ejc.234.1637183133391; Wed, 17 Nov 2021 13:05:33 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:33 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 16/19] net: dsa: qca8k: enable mtu_enforcement_ingress Date: Wed, 17 Nov 2021 22:04:48 +0100 Message-Id: <20211117210451.26415-17-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org qca8k have a global MTU. Inform DSA of this as the change MTU port function checks the max MTU across all port and sets the max value anyway as this switch doesn't support per port MTU. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca8k.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index c3234988aabf..cae58753bb1f 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1315,6 +1315,9 @@ qca8k_setup(struct dsa_switch *ds) /* Set max number of LAGs supported */ ds->num_lag_ids = QCA8K_NUM_LAGS; + /* Global MTU. Inform dsa that per port MTU is not supported */ + ds->mtu_enforcement_ingress = true; + return 0; } From patchwork Wed Nov 17 21:04:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625443 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EBF08C433EF for ; Wed, 17 Nov 2021 21:07:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CAB8463246 for ; Wed, 17 Nov 2021 21:07:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240838AbhKQVK3 (ORCPT ); Wed, 17 Nov 2021 16:10:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35010 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240859AbhKQVJN (ORCPT ); Wed, 17 Nov 2021 16:09:13 -0500 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3728AC06120D; Wed, 17 Nov 2021 13:05:36 -0800 (PST) Received: by mail-ed1-x535.google.com with SMTP id x6so5311765edr.5; Wed, 17 Nov 2021 13:05:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=L938AV2svNhJ44M4NS66rIX9RBK2nZqb7TB6m2Fm34I=; b=dGjmyaV9yH3K8V2sEENSRmPlMc4TNnbvRiNwpeE4U0PB/E42rgrVf7VYzjFtliOU9C bw0I4MVz0qlg4XXoSP1C7VBvaSF9bllc9eoaY6LBrcOjVquZ7q7UsUocC/jVZnnWrjSx JGea8g2vE+CmlemVHpUk+lOUJKrCV4UX4+kX/WXeZSsOHQiQxKHXpQAyAk/de7JsduQG kaDX8G0Z0rnJEwOgRREDMf442QFNI+6BtgIGSY2YmAuGNeZ+vPbTV/HKjHdR11jMQcx/ +PZyMO1DNSugHV1Bly7WPZZOS6/CvWD8QxBHYxXS/gCjZcywAKz3Xc5yqBxXTRhJOdGe mWew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=L938AV2svNhJ44M4NS66rIX9RBK2nZqb7TB6m2Fm34I=; b=c5eXQai4yTgdKWHHKwzRJ7nNnTlzH0C4/0icZOUKRw66TIIDa5a8O9LSOQOwV1Qyng WzjXNmqWaw+bTYVQXCdXV/QHR77t+M9J6FtsQJsoiKRyYemxoGgrJ8Og/jNCIrb5PtPM hzBALkoTFgLUpA6sr29pQju6n6E5QnW988e3v+uf9J2S44lvdTpwPCGvV9rj/YqcZQuy pnyfAeGPW+ulXiU+5KCZHvu+gKP2qCmuAPqANMz5I9bnJqkoNMtHsM5Mn67kxK6ze5nO DaYrrprdO4xttNACUQeX4e4RggCCJcwnhWILDD8YI+x6bSBNHrSYDlx4kaw6G29xFNGm FK7g== X-Gm-Message-State: AOAM531m1SOJgee2UGOvkz5YLjp10YmiwYMrA7fZfyj0/CO/yIwl2N6u rfmdc0wQi8FxH5hkbdzRwufY2edGy6I= X-Google-Smtp-Source: ABdhPJyVzEqGlFPi7cyjP2XowEPldSFN3EpA41/t690Ij8BbOis/bjn7+e0U7FxAC6hheVEI8NFbSA== X-Received: by 2002:a17:906:82c5:: with SMTP id a5mr26243217ejy.127.1637183134711; Wed, 17 Nov 2021 13:05:34 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:34 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 17/19] net: dsa: qca8k: move qca8k to qca dir Date: Wed, 17 Nov 2021 22:04:49 +0100 Message-Id: <20211117210451.26415-18-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Move qca8k driver to qca dir in preparation for code split of common code from specific code. Signed-off-by: Ansuel Smith --- drivers/net/dsa/Kconfig | 8 -------- drivers/net/dsa/Makefile | 1 - drivers/net/dsa/qca/Kconfig | 9 +++++++++ drivers/net/dsa/qca/Makefile | 1 + drivers/net/dsa/{ => qca}/qca8k.c | 0 drivers/net/dsa/{ => qca}/qca8k.h | 0 6 files changed, 10 insertions(+), 9 deletions(-) rename drivers/net/dsa/{ => qca}/qca8k.c (100%) rename drivers/net/dsa/{ => qca}/qca8k.h (100%) diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 7b1457a6e327..19587620ef14 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -59,14 +59,6 @@ source "drivers/net/dsa/sja1105/Kconfig" source "drivers/net/dsa/xrs700x/Kconfig" -config NET_DSA_QCA8K - tristate "Qualcomm Atheros QCA8K Ethernet switch family support" - select NET_DSA_TAG_QCA - select REGMAP - help - This enables support for the Qualcomm Atheros QCA8K Ethernet - switch chips. - config NET_DSA_REALTEK_SMI tristate "Realtek SMI Ethernet switch family support" select NET_DSA_TAG_RTL4_A diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile index 8da1569a34e6..6c6fbb14eff8 100644 --- a/drivers/net/dsa/Makefile +++ b/drivers/net/dsa/Makefile @@ -8,7 +8,6 @@ endif obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o -obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o rtl8365mb.o obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o diff --git a/drivers/net/dsa/qca/Kconfig b/drivers/net/dsa/qca/Kconfig index 13b7e679b8b5..7186f036678c 100644 --- a/drivers/net/dsa/qca/Kconfig +++ b/drivers/net/dsa/qca/Kconfig @@ -7,3 +7,12 @@ config NET_DSA_AR9331 help This enables support for the Qualcomm Atheros AR9331 built-in Ethernet switch. + +config NET_DSA_QCA8K + tristate "Qualcomm Atheros QCA8K Ethernet switch family support" + depends on NET_DSA + select NET_DSA_TAG_QCA + select REGMAP + help + This enables support for the Qualcomm Atheros QCA8K Ethernet + switch chips. \ No newline at end of file diff --git a/drivers/net/dsa/qca/Makefile b/drivers/net/dsa/qca/Makefile index 274022319066..16f84acf0246 100644 --- a/drivers/net/dsa/qca/Makefile +++ b/drivers/net/dsa/qca/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o +obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o \ No newline at end of file diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca/qca8k.c similarity index 100% rename from drivers/net/dsa/qca8k.c rename to drivers/net/dsa/qca/qca8k.c diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca/qca8k.h similarity index 100% rename from drivers/net/dsa/qca8k.h rename to drivers/net/dsa/qca/qca8k.h From patchwork Wed Nov 17 21:04:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625445 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 87896C433F5 for ; Wed, 17 Nov 2021 21:07:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 682976325A for ; Wed, 17 Nov 2021 21:07:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240849AbhKQVKb (ORCPT ); Wed, 17 Nov 2021 16:10:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35186 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240864AbhKQVJO (ORCPT ); Wed, 17 Nov 2021 16:09:14 -0500 Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9EBCCC061210; Wed, 17 Nov 2021 13:05:37 -0800 (PST) Received: by mail-ed1-x52a.google.com with SMTP id z5so17021295edd.3; Wed, 17 Nov 2021 13:05:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=oIKLkMzYcyOXWvE2NN0Dor5B9xR1JhlY89se65GsZ88=; b=NsvxGPJMqH6BWLkuCeffpwJEQYmZXHi5rdfQii3O1QyHV6Qn+AWVOpug5646sYHkhw hG0IGE4f27W4aK4t7Uc0cu8KV4kavhh5EabdR7w9EPX0eZVR0lyc26OhcKhzDq4zjwdq 5wJsAH/EpPAI7k0ZVNOsC7j3f5Dc+K4CLCGb4fNoQw7nPxqoSSU4t8ZhGwYkbmvlYhtd xCCF/NR2M/u8MX9lSpUstYSojE8XG3fPcmcjKgFCTivcsdGggcmvGkAdeZXd/MCpgKlE FsWxlc9oYm5KeVWcdY/M1gYTCrNOTKHd42F+F+7sQvuzRWIjXYYKuBkAqk1VJDjZE7Jb NqsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oIKLkMzYcyOXWvE2NN0Dor5B9xR1JhlY89se65GsZ88=; b=Rrnr2jlHUlGStRYDv0qpd4aEfQiEM5jInvo/B6DoleiK7YJkAPLzduVYOGtvRueAiA YxdRS36AGWC5swjSydmqb+RURvBrtclbRDp+qSNNDoMDS/m90F7ehpjRpFXjKIeWAJT/ VfNP7odN39LrpGTalyHVovTJODlT/79dyj+zNrsXibmLPyMY7ia1fWUT4adiBKX64i/6 9ObGjhty+kv9oz8JTV6Rgkl36k0vxfBkhhmuGbLXI0VmqIe/NfoBEbjCKIKEOdyj95+s zXrVxvLu9g5MAOGPafjQeG+0FrKTOUTt0ZjviBUHlo0vJMh3EB+wMfh7u1UdC9CoPUT6 54YQ== X-Gm-Message-State: AOAM530RbQIOPKq4rFZAIQlcU3dJSIU5lulGOpaIG3yrUYx3hlvpp/5i z6AO8MwMHTvyeJ5KmuJCP0E= X-Google-Smtp-Source: ABdhPJweD6msBp77IxJH1Me47pO1tq5qv7A1kBx4pfpNq3O7j8YnTPOW7bcSsQTvKm1vkb3LktGBNA== X-Received: by 2002:a05:6402:190c:: with SMTP id e12mr2590497edz.309.1637183136145; Wed, 17 Nov 2021 13:05:36 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:35 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 18/19] net: dsa: qca8k: use device_get_match_data instead of the OF variant Date: Wed, 17 Nov 2021 22:04:50 +0100 Message-Id: <20211117210451.26415-19-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Drop of_platform include and device_get_match_data instead of the OF variant. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca/qca8k.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/dsa/qca/qca8k.c b/drivers/net/dsa/qca/qca8k.c index cae58753bb1f..260cdac53990 100644 --- a/drivers/net/dsa/qca/qca8k.c +++ b/drivers/net/dsa/qca/qca8k.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -929,7 +928,7 @@ qca8k_setup_of_pws_reg(struct qca8k_priv *priv) * Should be applied by default but we set this just to make sure. */ if (priv->switch_id == QCA8K_ID_QCA8327) { - data = of_device_get_match_data(priv->dev); + data = device_get_match_data(priv->dev); /* Set the correct package of 148 pin for QCA8327 */ if (data->reduced_package) @@ -1071,7 +1070,7 @@ static int qca8k_read_switch_id(struct qca8k_priv *priv) int ret; /* get the switches ID from the compatible */ - data = of_device_get_match_data(priv->dev); + data = device_get_match_data(priv->dev); if (!data) return -ENODEV; @@ -1674,7 +1673,7 @@ qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) if (stringset != ETH_SS_STATS) return; - match_data = of_device_get_match_data(priv->dev); + match_data = device_get_match_data(priv->dev); for (i = 0; i < match_data->mib_count; i++) strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, @@ -1692,7 +1691,7 @@ qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, u32 hi = 0; int ret; - match_data = of_device_get_match_data(priv->dev); + match_data = device_get_match_data(priv->dev); for (i = 0; i < match_data->mib_count; i++) { mib = &ar8327_mib[i]; @@ -1723,7 +1722,7 @@ qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) if (sset != ETH_SS_STATS) return 0; - match_data = of_device_get_match_data(priv->dev); + match_data = device_get_match_data(priv->dev); return match_data->mib_count; } From patchwork Wed Nov 17 21:04:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12625447 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57DEAC433F5 for ; Wed, 17 Nov 2021 21:07:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3444E63285 for ; Wed, 17 Nov 2021 21:07:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240871AbhKQVKe (ORCPT ); Wed, 17 Nov 2021 16:10:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35014 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240724AbhKQVJO (ORCPT ); Wed, 17 Nov 2021 16:09:14 -0500 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 995E0C06121D; Wed, 17 Nov 2021 13:05:39 -0800 (PST) Received: by mail-ed1-x52b.google.com with SMTP id b15so16976647edd.7; Wed, 17 Nov 2021 13:05:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=voHasubOl4yjrBnGvpgDnZaTAFDHFUdqqD3/Df86kaU=; b=ZAaA9+J3QDqsQuWcYdwuAVNnHLHZyvMvMg/o3O2gg44YGGKK/xF05asoR5A/aEpGM8 GFCE2KqQ4f7mX0KwEKmSiFgB3o/v1QimsrN27PW/738XJIMKC4WnCzF7rrJF2ekBPUe0 Lrl/D3Qh4tQ2zpZ0nwmYXPSTj7BZ1SqZ2cbK7RBvSjOJPqdeRRslZCqO/AmC95RJ9k8N NmunusufzAeTW43H/5vvy3nt6BNhFmPi/aczEgLWSvzgqKe+eyMBrmxP1CTsHnKJDmzQ +ZwYT5eRgML0fEXWYKSOLyJBVuwocC+KKeqIISUtnuGbYvd70CoIXsCTG6a1q+rSPOLL FKMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=voHasubOl4yjrBnGvpgDnZaTAFDHFUdqqD3/Df86kaU=; b=z1F2lO+EUJtTVwI0uNueXtXTdBsGD9mVgsjy+dgjqAcu6laylHWJhnG550/W4oMVLT 49IwN2gA4RtITbPZ/s52T2PqrGsxsIZf5TPtHzeCR37G/vaiMvSVbYJvdltEBDcjfRz4 3FGnplxORMAMS+FtePqxDgiYRRcdfETXM4y4UXhwPL6hbIWG9XoyMgWlyg1b4LvWRqp/ bWsKbX0vpLy6eZHXNYMRjON1lVxlhAY7hu9t2Xnl2uej3e/KaXBZfJo/fU9t3jMXJMfz GG9o5DbHb5B/lwoRsLyAYskuSK9EOIU0JzYeixqZfWZ71/yWa17QhLdKMGgKs+lD/plg I2ng== X-Gm-Message-State: AOAM53321YDxTjBAt3ebPu2kpCsXaZQvjpjjbCPZ+f0NCyAgLawk/7Xg ubrOC+e5zsT3KMYixPf7Rpc= X-Google-Smtp-Source: ABdhPJwY7FN/r60ySNI4td5AXvv9WlxpshDRuqxQB74DsL273+GUc7iOhIqWPyEhd9c6Y9+E7mdRPw== X-Received: by 2002:a17:906:a1da:: with SMTP id bx26mr26520839ejb.558.1637183137663; Wed, 17 Nov 2021 13:05:37 -0800 (PST) Received: from localhost.localdomain (93-42-71-246.ip85.fastwebnet.it. [93.42.71.246]) by smtp.googlemail.com with ESMTPSA id di4sm467070ejc.11.2021.11.17.13.05.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 13:05:37 -0800 (PST) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Russell King , Ansuel Smith , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [net-next PATCH 19/19] net: dsa: qca8k: split qca8k in common and 8xxx specific code Date: Wed, 17 Nov 2021 22:04:51 +0100 Message-Id: <20211117210451.26415-20-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211117210451.26415-1-ansuelsmth@gmail.com> References: <20211117210451.26415-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The qca8k family reg structure is used also in the internal ipq40xx switch. Split qca8k common code from specific code for future implementation of ipq40xx internal switch based on qca8k. Signed-off-by: Ansuel Smith --- drivers/net/dsa/qca/Makefile | 3 +- drivers/net/dsa/qca/{qca8k.c => qca8k-8xxx.c} | 1168 +---------------- drivers/net/dsa/qca/qca8k-common.c | 1157 ++++++++++++++++ drivers/net/dsa/qca/qca8k.h | 50 + 4 files changed, 1222 insertions(+), 1156 deletions(-) rename drivers/net/dsa/qca/{qca8k.c => qca8k-8xxx.c} (56%) create mode 100644 drivers/net/dsa/qca/qca8k-common.c diff --git a/drivers/net/dsa/qca/Makefile b/drivers/net/dsa/qca/Makefile index 16f84acf0246..31ef72d4b20a 100644 --- a/drivers/net/dsa/qca/Makefile +++ b/drivers/net/dsa/qca/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o -obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o \ No newline at end of file +obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o +qca8k-y += qca8k-common.o qca8k-8xxx.o \ No newline at end of file diff --git a/drivers/net/dsa/qca/qca8k.c b/drivers/net/dsa/qca/qca8k-8xxx.c similarity index 56% rename from drivers/net/dsa/qca/qca8k.c rename to drivers/net/dsa/qca/qca8k-8xxx.c index 260cdac53990..1dbb8fe52457 100644 --- a/drivers/net/dsa/qca/qca8k.c +++ b/drivers/net/dsa/qca/qca8k-8xxx.c @@ -22,57 +22,6 @@ #include "qca8k.h" -#define MIB_DESC(_s, _o, _n) \ - { \ - .size = (_s), \ - .offset = (_o), \ - .name = (_n), \ - } - -static const struct qca8k_mib_desc ar8327_mib[] = { - MIB_DESC(1, 0x00, "RxBroad"), - MIB_DESC(1, 0x04, "RxPause"), - MIB_DESC(1, 0x08, "RxMulti"), - MIB_DESC(1, 0x0c, "RxFcsErr"), - MIB_DESC(1, 0x10, "RxAlignErr"), - MIB_DESC(1, 0x14, "RxRunt"), - MIB_DESC(1, 0x18, "RxFragment"), - MIB_DESC(1, 0x1c, "Rx64Byte"), - MIB_DESC(1, 0x20, "Rx128Byte"), - MIB_DESC(1, 0x24, "Rx256Byte"), - MIB_DESC(1, 0x28, "Rx512Byte"), - MIB_DESC(1, 0x2c, "Rx1024Byte"), - MIB_DESC(1, 0x30, "Rx1518Byte"), - MIB_DESC(1, 0x34, "RxMaxByte"), - MIB_DESC(1, 0x38, "RxTooLong"), - MIB_DESC(2, 0x3c, "RxGoodByte"), - MIB_DESC(2, 0x44, "RxBadByte"), - MIB_DESC(1, 0x4c, "RxOverFlow"), - MIB_DESC(1, 0x50, "Filtered"), - MIB_DESC(1, 0x54, "TxBroad"), - MIB_DESC(1, 0x58, "TxPause"), - MIB_DESC(1, 0x5c, "TxMulti"), - MIB_DESC(1, 0x60, "TxUnderRun"), - MIB_DESC(1, 0x64, "Tx64Byte"), - MIB_DESC(1, 0x68, "Tx128Byte"), - MIB_DESC(1, 0x6c, "Tx256Byte"), - MIB_DESC(1, 0x70, "Tx512Byte"), - MIB_DESC(1, 0x74, "Tx1024Byte"), - MIB_DESC(1, 0x78, "Tx1518Byte"), - MIB_DESC(1, 0x7c, "TxMaxByte"), - MIB_DESC(1, 0x80, "TxOverSize"), - MIB_DESC(2, 0x84, "TxByte"), - MIB_DESC(1, 0x8c, "TxCollision"), - MIB_DESC(1, 0x90, "TxAbortCol"), - MIB_DESC(1, 0x94, "TxMultiCol"), - MIB_DESC(1, 0x98, "TxSingleCol"), - MIB_DESC(1, 0x9c, "TxExcDefer"), - MIB_DESC(1, 0xa0, "TxDefer"), - MIB_DESC(1, 0xa4, "TxLateCol"), - MIB_DESC(1, 0xa8, "RXUnicast"), - MIB_DESC(1, 0xac, "TXUnicast"), -}; - /* The 32bit switch registers are accessed indirectly. To achieve this we need * to set the page of the register. Track the last page that was set to reduce * mdio writes @@ -228,30 +177,6 @@ qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_ return ret; } -static const struct regmap_range qca8k_readable_ranges[] = { - regmap_reg_range(0x0000, 0x00e4), /* Global control */ - regmap_reg_range(0x0100, 0x0168), /* EEE control */ - regmap_reg_range(0x0200, 0x0270), /* Parser control */ - regmap_reg_range(0x0400, 0x0454), /* ACL */ - regmap_reg_range(0x0600, 0x0718), /* Lookup */ - regmap_reg_range(0x0800, 0x0b70), /* QM */ - regmap_reg_range(0x0c00, 0x0c80), /* PKT */ - regmap_reg_range(0x0e00, 0x0e98), /* L3 */ - regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ - regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ - regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ - regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ - regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ - regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ - regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ - -}; - -static const struct regmap_access_table qca8k_readable_table = { - .yes_ranges = qca8k_readable_ranges, - .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), -}; - static struct regmap_config qca8k_regmap_config = { .reg_bits = 16, .val_bits = 32, @@ -265,330 +190,6 @@ static struct regmap_config qca8k_regmap_config = { .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ }; -static int -qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) -{ - u32 val; - - return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, - QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); -} - -static int -qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) -{ - u32 reg[4], val; - int i, ret; - - /* load the ARL table into an array */ - for (i = 0; i < 4; i++) { - ret = regmap_read(priv->regmap, QCA8K_REG_ATU_DATA0 + (i * 4), &val); - if (ret < 0) - return ret; - - reg[i] = val; - } - - /* vid - 83:72 */ - fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); - /* aging - 67:64 */ - fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); - /* portmask - 54:48 */ - fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); - /* mac - 47:0 */ - fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); - fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); - fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); - fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); - fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); - fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); - - return 0; -} - -static void -qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, - u8 aging) -{ - u32 reg[3] = { 0 }; - int i; - - /* vid - 83:72 */ - reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); - /* aging - 67:64 */ - reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); - /* portmask - 54:48 */ - reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); - /* mac - 47:0 */ - reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); - reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); - reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); - reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); - reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); - reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); - - /* load the array into the ARL table */ - for (i = 0; i < 3; i++) - regmap_write(priv->regmap, QCA8K_REG_ATU_DATA0 + (i * 4), reg[i]); -} - -static int -qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) -{ - u32 reg; - int ret; - - /* Set the command and FDB index */ - reg = QCA8K_ATU_FUNC_BUSY; - reg |= cmd; - if (port >= 0) { - reg |= QCA8K_ATU_FUNC_PORT_EN; - reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); - } - - /* Write the function register triggering the table access */ - ret = regmap_write(priv->regmap, QCA8K_REG_ATU_FUNC, reg); - if (ret) - return ret; - - /* wait for completion */ - ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); - if (ret) - return ret; - - /* Check for table full violation when adding an entry */ - if (cmd == QCA8K_FDB_LOAD) { - ret = regmap_read(priv->regmap, QCA8K_REG_ATU_FUNC, ®); - if (ret < 0) - return ret; - if (reg & QCA8K_ATU_FUNC_FULL) - return -1; - } - - return 0; -} - -static int -qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) -{ - int ret; - - qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); - ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); - if (ret < 0) - return ret; - - return qca8k_fdb_read(priv, fdb); -} - -static int -qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, - u16 vid, u8 aging) -{ - int ret; - - mutex_lock(&priv->reg_mutex); - qca8k_fdb_write(priv, vid, port_mask, mac, aging); - ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); - mutex_unlock(&priv->reg_mutex); - - return ret; -} - -static int -qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) -{ - int ret; - - mutex_lock(&priv->reg_mutex); - qca8k_fdb_write(priv, vid, port_mask, mac, 0); - ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); - mutex_unlock(&priv->reg_mutex); - - return ret; -} - -static void -qca8k_fdb_flush(struct qca8k_priv *priv) -{ - mutex_lock(&priv->reg_mutex); - qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); - mutex_unlock(&priv->reg_mutex); -} - -static int -qca8k_fdb_search(struct qca8k_priv *priv, struct qca8k_fdb *fdb, const u8 *mac, u16 vid) -{ - int ret; - - mutex_lock(&priv->reg_mutex); - qca8k_fdb_write(priv, vid, 0, mac, 0); - ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); - if (ret < 0) - goto exit; - - ret = qca8k_fdb_read(priv, fdb); -exit: - mutex_unlock(&priv->reg_mutex); - return ret; -} - -static int -qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) -{ - u32 reg; - int ret; - - /* Set the command and VLAN index */ - reg = QCA8K_VTU_FUNC1_BUSY; - reg |= cmd; - reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); - - /* Write the function register triggering the table access */ - ret = regmap_write(priv->regmap, QCA8K_REG_VTU_FUNC1, reg); - if (ret) - return ret; - - /* wait for completion */ - ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); - if (ret) - return ret; - - /* Check for table full violation when adding an entry */ - if (cmd == QCA8K_VLAN_LOAD) { - ret = regmap_read(priv->regmap, QCA8K_REG_VTU_FUNC1, ®); - if (ret < 0) - return ret; - if (reg & QCA8K_VTU_FUNC1_FULL) - return -ENOMEM; - } - - return 0; -} - -static int -qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) -{ - u32 reg; - int ret; - - /* - We do the right thing with VLAN 0 and treat it as untagged while - preserving the tag on egress. - */ - if (vid == 0) - return 0; - - mutex_lock(&priv->reg_mutex); - ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); - if (ret < 0) - goto out; - - ret = regmap_read(priv->regmap, QCA8K_REG_VTU_FUNC0, ®); - if (ret < 0) - goto out; - reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; - reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); - if (untagged) - reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); - else - reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); - - ret = regmap_write(priv->regmap, QCA8K_REG_VTU_FUNC0, reg); - if (ret) - goto out; - ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); - -out: - mutex_unlock(&priv->reg_mutex); - - return ret; -} - -static int -qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) -{ - u32 reg, mask; - int ret, i; - bool del; - - mutex_lock(&priv->reg_mutex); - ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); - if (ret < 0) - goto out; - - ret = regmap_read(priv->regmap, QCA8K_REG_VTU_FUNC0, ®); - if (ret < 0) - goto out; - reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); - reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); - - /* Check if we're the last member to be removed */ - del = true; - for (i = 0; i < QCA8K_NUM_PORTS; i++) { - mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); - - if ((reg & mask) != mask) { - del = false; - break; - } - } - - if (del) { - ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); - } else { - ret = regmap_write(priv->regmap, QCA8K_REG_VTU_FUNC0, reg); - if (ret) - goto out; - ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); - } - -out: - mutex_unlock(&priv->reg_mutex); - - return ret; -} - -static int -qca8k_mib_init(struct qca8k_priv *priv) -{ - int ret; - - mutex_lock(&priv->reg_mutex); - ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY); - if (ret) - goto exit; - - ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); - if (ret) - goto exit; - - ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); - if (ret) - goto exit; - - ret = regmap_write(priv->regmap, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); - -exit: - mutex_unlock(&priv->reg_mutex); - return ret; -} - -static void -qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) -{ - u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; - - /* Port 0 and 6 have no internal PHY */ - if (port > 0 && port < 6) - mask |= QCA8K_PORT_STATUS_LINK_AUTO; - - if (enable) - regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); - else - regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); -} - static u32 qca8k_port_to_phy(int port) { @@ -1571,772 +1172,29 @@ qca8k_phylink_validate(struct dsa_switch *ds, int port, linkmode_and(state->advertising, state->advertising, mask); } -static int -qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, - struct phylink_link_state *state) -{ - struct qca8k_priv *priv = ds->priv; - u32 reg; - int ret; - - ret = regmap_read(priv->regmap, QCA8K_REG_PORT_STATUS(port), ®); - if (ret < 0) - return ret; - - state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP); - state->an_complete = state->link; - state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO); - state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL : - DUPLEX_HALF; - - switch (reg & QCA8K_PORT_STATUS_SPEED) { - case QCA8K_PORT_STATUS_SPEED_10: - state->speed = SPEED_10; - break; - case QCA8K_PORT_STATUS_SPEED_100: - state->speed = SPEED_100; - break; - case QCA8K_PORT_STATUS_SPEED_1000: - state->speed = SPEED_1000; - break; - default: - state->speed = SPEED_UNKNOWN; - break; - } - - state->pause = MLO_PAUSE_NONE; - if (reg & QCA8K_PORT_STATUS_RXFLOW) - state->pause |= MLO_PAUSE_RX; - if (reg & QCA8K_PORT_STATUS_TXFLOW) - state->pause |= MLO_PAUSE_TX; - - return 1; -} - -static void -qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, - phy_interface_t interface) -{ - struct qca8k_priv *priv = ds->priv; - - qca8k_port_set_status(priv, port, 0); -} - -static void -qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, - phy_interface_t interface, struct phy_device *phydev, - int speed, int duplex, bool tx_pause, bool rx_pause) -{ - struct qca8k_priv *priv = ds->priv; - u32 reg; - - if (phylink_autoneg_inband(mode)) { - reg = QCA8K_PORT_STATUS_LINK_AUTO; - } else { - switch (speed) { - case SPEED_10: - reg = QCA8K_PORT_STATUS_SPEED_10; - break; - case SPEED_100: - reg = QCA8K_PORT_STATUS_SPEED_100; - break; - case SPEED_1000: - reg = QCA8K_PORT_STATUS_SPEED_1000; - break; - default: - reg = QCA8K_PORT_STATUS_LINK_AUTO; - break; - } - - if (duplex == DUPLEX_FULL) - reg |= QCA8K_PORT_STATUS_DUPLEX; - - if (rx_pause || dsa_is_cpu_port(ds, port)) - reg |= QCA8K_PORT_STATUS_RXFLOW; - - if (tx_pause || dsa_is_cpu_port(ds, port)) - reg |= QCA8K_PORT_STATUS_TXFLOW; - } - - reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; - - regmap_write(priv->regmap, QCA8K_REG_PORT_STATUS(port), reg); -} - -static void -qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) -{ - const struct qca8k_match_data *match_data; - struct qca8k_priv *priv = ds->priv; - int i; - - if (stringset != ETH_SS_STATS) - return; - - match_data = device_get_match_data(priv->dev); - - for (i = 0; i < match_data->mib_count; i++) - strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, - ETH_GSTRING_LEN); -} - -static void -qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, - uint64_t *data) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - const struct qca8k_match_data *match_data; - const struct qca8k_mib_desc *mib; - u32 reg, i, val; - u32 hi = 0; - int ret; - - match_data = device_get_match_data(priv->dev); - - for (i = 0; i < match_data->mib_count; i++) { - mib = &ar8327_mib[i]; - reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; - - ret = regmap_read(priv->regmap, reg, &val); - if (ret < 0) - continue; - - if (mib->size == 2) { - ret = regmap_read(priv->regmap, reg + 4, &hi); - if (ret < 0) - continue; - } - - data[i] = val; - if (mib->size == 2) - data[i] |= (u64)hi << 32; - } -} - -static int -qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) +static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) { - const struct qca8k_match_data *match_data; struct qca8k_priv *priv = ds->priv; - if (sset != ETH_SS_STATS) - return 0; - - match_data = device_get_match_data(priv->dev); + /* Communicate to the phy internal driver the switch revision. + * Based on the switch revision different values needs to be + * set to the dbg and mmd reg on the phy. + * The first 2 bit are used to communicate the switch revision + * to the phy driver. + */ + if (port > 0 && port < 6) + return priv->switch_revision; - return match_data->mib_count; + return 0; } -static int -qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); - u32 reg; - int ret; - - mutex_lock(&priv->reg_mutex); - ret = regmap_read(priv->regmap, QCA8K_REG_EEE_CTRL, ®); - if (ret < 0) - goto exit; - - if (eee->eee_enabled) - reg |= lpi_en; - else - reg &= ~lpi_en; - ret = regmap_write(priv->regmap, QCA8K_REG_EEE_CTRL, reg); - -exit: - mutex_unlock(&priv->reg_mutex); - return ret; -} - -static int -qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) -{ - /* Nothing to do on the port's MAC */ - return 0; -} - -static void -qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - u32 stp_state; - - switch (state) { - case BR_STATE_DISABLED: - stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; - break; - case BR_STATE_BLOCKING: - stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; - break; - case BR_STATE_LISTENING: - stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; - break; - case BR_STATE_LEARNING: - stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; - break; - case BR_STATE_FORWARDING: - default: - stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; - break; - } - - regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); -} - -static int -qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - int port_mask, cpu_port; - int i, ret; - - cpu_port = dsa_to_port(ds, port)->cpu_dp->index; - port_mask = BIT(cpu_port); - - for (i = 0; i < QCA8K_NUM_PORTS; i++) { - if (dsa_is_cpu_port(ds, i)) - continue; - if (dsa_to_port(ds, i)->bridge_dev != br) - continue; - /* Add this port to the portvlan mask of the other ports - * in the bridge - */ - ret = regmap_set_bits(priv->regmap, - QCA8K_PORT_LOOKUP_CTRL(i), - BIT(port)); - if (ret) - return ret; - if (i != port) - port_mask |= BIT(i); - } - - /* Add all other ports to this ports portvlan mask */ - ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_MEMBER, port_mask); - - return ret; -} - -static void -qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - int cpu_port, i; - - cpu_port = dsa_to_port(ds, port)->cpu_dp->index; - - for (i = 0; i < QCA8K_NUM_PORTS; i++) { - if (dsa_is_cpu_port(ds, i)) - continue; - if (dsa_to_port(ds, i)->bridge_dev != br) - continue; - /* Remove this port to the portvlan mask of the other ports - * in the bridge - */ - regmap_clear_bits(priv->regmap, - QCA8K_PORT_LOOKUP_CTRL(i), - BIT(port)); - } - - /* Set the cpu port to be the only one in the portvlan mask of - * this port - */ - regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); -} - -static void -qca8k_port_fast_age(struct dsa_switch *ds, int port) -{ - struct qca8k_priv *priv = ds->priv; - - mutex_lock(&priv->reg_mutex); - qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); - mutex_unlock(&priv->reg_mutex); -} - -static int -qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) -{ - struct qca8k_priv *priv = ds->priv; - unsigned int secs = msecs / 1000; - u32 val; - - /* AGE_TIME reg is set in 7s step */ - val = secs / 7; - - if (val > FIELD_MAX(QCA8K_ATU_AGE_TIME_MASK)) - return -ERANGE; - - return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, - QCA8K_ATU_AGE_TIME(val)); -} - -static int -qca8k_port_enable(struct dsa_switch *ds, int port, - struct phy_device *phy) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - - qca8k_port_set_status(priv, port, 1); - priv->port_sts[port].enabled = 1; - - if (dsa_is_user_port(ds, port)) - phy_support_asym_pause(phy); - - return 0; -} - -static void -qca8k_port_disable(struct dsa_switch *ds, int port) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - - qca8k_port_set_status(priv, port, 0); - priv->port_sts[port].enabled = 0; -} - -static int -qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) -{ - struct qca8k_priv *priv = ds->priv; - int i, mtu = 0; - - priv->port_mtu[port] = new_mtu; - - for (i = 0; i < QCA8K_NUM_PORTS; i++) - if (priv->port_mtu[i] > mtu) - mtu = priv->port_mtu[i]; - - /* Include L2 header / FCS length */ - return regmap_write(priv->regmap, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN); -} - -static int -qca8k_port_max_mtu(struct dsa_switch *ds, int port) -{ - return QCA8K_MAX_MTU; -} - -static int -qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, - u16 port_mask, u16 vid) -{ - /* Set the vid to the port vlan id if no vid is set */ - if (!vid) - vid = QCA8K_PORT_VID_DEF; - - return qca8k_fdb_add(priv, addr, port_mask, vid, - QCA8K_ATU_STATUS_STATIC); -} - -static int -qca8k_port_fdb_add(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - u16 port_mask = BIT(port); - - return qca8k_port_fdb_insert(priv, addr, port_mask, vid); -} - -static int -qca8k_port_fdb_del(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - u16 port_mask = BIT(port); - - if (!vid) - vid = QCA8K_PORT_VID_DEF; - - return qca8k_fdb_del(priv, addr, port_mask, vid); -} - -static int -qca8k_port_fdb_dump(struct dsa_switch *ds, int port, - dsa_fdb_dump_cb_t *cb, void *data) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - struct qca8k_fdb _fdb = { 0 }; - int cnt = QCA8K_NUM_FDB_RECORDS; - bool is_static; - int ret = 0; - - mutex_lock(&priv->reg_mutex); - while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { - if (!_fdb.aging) - break; - is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); - ret = cb(_fdb.mac, _fdb.vid, is_static, data); - if (ret) - break; - } - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -static int -qca8k_port_mdb_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_mdb *mdb) -{ - struct qca8k_priv *priv = ds->priv; - struct qca8k_fdb fdb = { 0 }; - const u8 *addr = mdb->addr; - u8 port_mask = BIT(port); - u16 vid = mdb->vid; - int ret; - - /* Check if entry already exist */ - ret = qca8k_fdb_search(priv, &fdb, addr, vid); - if (ret < 0) - return ret; - - /* Rule exist. Delete first */ - if (!fdb.aging) { - ret = qca8k_fdb_del(priv, addr, fdb.port_mask, vid); - if (ret) - return ret; - } - - /* Add port to fdb portmask */ - fdb.port_mask |= port_mask; - - return qca8k_port_fdb_insert(priv, addr, fdb.port_mask, vid); -} - -static int -qca8k_port_mdb_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_mdb *mdb) -{ - struct qca8k_priv *priv = ds->priv; - struct qca8k_fdb fdb = { 0 }; - const u8 *addr = mdb->addr; - u8 port_mask = BIT(port); - u16 vid = mdb->vid; - int ret; - - /* Check if entry already exist */ - ret = qca8k_fdb_search(priv, &fdb, addr, vid); - if (ret < 0) - return ret; - - /* Rule doesn't exist. Why delete? */ - if (!fdb.aging) - return -EINVAL; - - ret = qca8k_fdb_del(priv, addr, port_mask, vid); - if (ret) - return ret; - - /* Only port in the rule is this port. Don't re insert */ - if (fdb.port_mask == port_mask) - return 0; - - /* Remove port from port mask */ - fdb.port_mask &= ~port_mask; - - return qca8k_port_fdb_insert(priv, addr, fdb.port_mask, vid); -} - -static int -qca8k_port_mirror_add(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror, - bool ingress) -{ - struct qca8k_priv *priv = ds->priv; - int monitor_port, ret; - u32 reg, val; - - /* Check for existent entry */ - if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) - return -EEXIST; - - ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); - if (ret) - return ret; - - /* QCA83xx can have only one port set to mirror mode. - * Check that the correct port is requested and return error otherwise. - * When no mirror port is set, the values is set to 0xF - */ - monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); - if (monitor_port != 0xF && monitor_port != mirror->to_local_port) - return -EEXIST; - - /* Set the monitor port */ - val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, - mirror->to_local_port); - ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, - QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); - if (ret) - return ret; - - if (ingress) { - reg = QCA8K_PORT_LOOKUP_CTRL(port); - val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; - } else { - reg = QCA8K_REG_PORT_HOL_CTRL1(port); - val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; - } - - ret = regmap_update_bits(priv->regmap, reg, val, val); - if (ret) - return ret; - - /* Track mirror port for tx and rx to decide when the - * mirror port has to be disabled. - */ - if (ingress) - priv->mirror_rx |= BIT(port); - else - priv->mirror_tx |= BIT(port); - - return 0; -} - -static void -qca8k_port_mirror_del(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror) -{ - struct qca8k_priv *priv = ds->priv; - u32 reg, val; - int ret; - - if (mirror->ingress) { - reg = QCA8K_PORT_LOOKUP_CTRL(port); - val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; - } else { - reg = QCA8K_REG_PORT_HOL_CTRL1(port); - val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; - } - - ret = regmap_clear_bits(priv->regmap, reg, val); - if (ret) - goto err; - - if (mirror->ingress) - priv->mirror_rx &= ~BIT(port); - else - priv->mirror_tx &= ~BIT(port); - - /* No port set to send packet to mirror port. Disable mirror port */ - if (!priv->mirror_rx && !priv->mirror_tx) { - val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); - ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, - QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); - if (ret) - goto err; - } -err: - dev_err(priv->dev, "Failed to del mirror port from %d", port); -} - -static int -qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, - struct netlink_ext_ack *extack) -{ - struct qca8k_priv *priv = ds->priv; - int ret; - - if (vlan_filtering) { - ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, - QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); - } else { - ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, - QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); - } - - return ret; -} - -static int -qca8k_port_vlan_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan, - struct netlink_ext_ack *extack) -{ - bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; - bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; - struct qca8k_priv *priv = ds->priv; - int ret; - - ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); - if (ret) { - dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); - return ret; - } - - if (pvid) { - ret = regmap_update_bits(priv->regmap, QCA8K_EGRESS_VLAN(port), - QCA8K_EGREES_VLAN_PORT_MASK(port), - QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); - if (ret) - return ret; - - ret = regmap_write(priv->regmap, QCA8K_REG_PORT_VLAN_CTRL0(port), - QCA8K_PORT_VLAN_CVID(vlan->vid) | - QCA8K_PORT_VLAN_SVID(vlan->vid)); - } - - return ret; -} - -static int -qca8k_port_vlan_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan) -{ - struct qca8k_priv *priv = ds->priv; - int ret; - - ret = qca8k_vlan_del(priv, port, vlan->vid); - if (ret) - dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); - - return ret; -} - -static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) -{ - struct qca8k_priv *priv = ds->priv; - - /* Communicate to the phy internal driver the switch revision. - * Based on the switch revision different values needs to be - * set to the dbg and mmd reg on the phy. - * The first 2 bit are used to communicate the switch revision - * to the phy driver. - */ - if (port > 0 && port < 6) - return priv->switch_revision; - - return 0; -} - -static enum dsa_tag_protocol -qca8k_get_tag_protocol(struct dsa_switch *ds, int port, - enum dsa_tag_protocol mp) +static enum dsa_tag_protocol +qca8k_get_tag_protocol(struct dsa_switch *ds, int port, + enum dsa_tag_protocol mp) { return DSA_TAG_PROTO_QCA; } -static bool -qca8k_lag_can_offload(struct dsa_switch *ds, - struct net_device *lag, - struct netdev_lag_upper_info *info) -{ - struct dsa_port *dp; - int id, members = 0; - - id = dsa_lag_id(ds->dst, lag); - if (id < 0 || id >= ds->num_lag_ids) - return false; - - dsa_lag_foreach_port(dp, ds->dst, lag) - /* Includes the port joining the LAG */ - members++; - - if (members > QCA8K_NUM_PORTS_FOR_LAG) - return false; - - if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) - return false; - - return true; -} - -static int -qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, - struct net_device *lag, bool delete) -{ - struct qca8k_priv *priv = ds->priv; - int ret, id, i; - u32 val; - - id = dsa_lag_id(ds->dst, lag); - - /* Read current port member */ - ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); - if (ret) - return ret; - - /* Shift val to the correct trunk */ - val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); - val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; - if (delete) - val &= ~BIT(port); - else - val |= BIT(port); - - /* Update port member. With empty portmap disable trunk */ - ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, - QCA8K_REG_GOL_TRUNK_MEMBER(id) | - QCA8K_REG_GOL_TRUNK_EN(id), - !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | - val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); - - /* Search empty member if adding or port on deleting */ - for (i = 0; i < 4; i++) { - ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); - if (ret) - return ret; - - val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); - val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; - - if (delete) { - /* If port flagged to be disabled assume this member is - * empty - */ - if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) - continue; - - val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; - if (val != port) - continue; - } else { - /* If port flagged to be enabled assume this member is - * already set - */ - if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) - continue; - } - - /* We find the member to remove */ - break; - } - - /* Set port in the correct port mask or disable port if in delate mode */ - return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), - QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | - QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), - !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | - port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); -} - -static int -qca8k_port_lag_join(struct dsa_switch *ds, int port, - struct net_device *lag, - struct netdev_lag_upper_info *info) -{ - if (!qca8k_lag_can_offload(ds, lag, info)) - return -EOPNOTSUPP; - - return qca8k_lag_refresh_portmap(ds, port, lag, false); -} - -static int -qca8k_port_lag_leave(struct dsa_switch *ds, int port, - struct net_device *lag) -{ - return qca8k_lag_refresh_portmap(ds, port, lag, true); -} - static const struct dsa_switch_ops qca8k_switch_ops = { .get_tag_protocol = qca8k_get_tag_protocol, .setup = qca8k_setup, diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c new file mode 100644 index 000000000000..fdd5c92a278f --- /dev/null +++ b/drivers/net/dsa/qca/qca8k-common.c @@ -0,0 +1,1157 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2009 Felix Fietkau + * Copyright (C) 2011-2012 Gabor Juhos + * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016 John Crispin + */ + +#include +#include +#include +#include +#include +#include + +#include "qca8k.h" + +static const struct regmap_range qca8k_readable_ranges[] = { + regmap_reg_range(0x0000, 0x00e4), /* Global control */ + regmap_reg_range(0x0100, 0x0168), /* EEE control */ + regmap_reg_range(0x0200, 0x0270), /* Parser control */ + regmap_reg_range(0x0400, 0x0454), /* ACL */ + regmap_reg_range(0x0600, 0x0718), /* Lookup */ + regmap_reg_range(0x0800, 0x0b70), /* QM */ + regmap_reg_range(0x0c00, 0x0c80), /* PKT */ + regmap_reg_range(0x0e00, 0x0e98), /* L3 */ + regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ + regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ + regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ + regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ + regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ + regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ + regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ + +}; + +const struct regmap_access_table qca8k_readable_table = { + .yes_ranges = qca8k_readable_ranges, + .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), +}; + +#define MIB_DESC(_s, _o, _n) \ + { \ + .size = (_s), \ + .offset = (_o), \ + .name = (_n), \ + } + +static const struct qca8k_mib_desc ar8327_mib[] = { + MIB_DESC(1, 0x00, "RxBroad"), + MIB_DESC(1, 0x04, "RxPause"), + MIB_DESC(1, 0x08, "RxMulti"), + MIB_DESC(1, 0x0c, "RxFcsErr"), + MIB_DESC(1, 0x10, "RxAlignErr"), + MIB_DESC(1, 0x14, "RxRunt"), + MIB_DESC(1, 0x18, "RxFragment"), + MIB_DESC(1, 0x1c, "Rx64Byte"), + MIB_DESC(1, 0x20, "Rx128Byte"), + MIB_DESC(1, 0x24, "Rx256Byte"), + MIB_DESC(1, 0x28, "Rx512Byte"), + MIB_DESC(1, 0x2c, "Rx1024Byte"), + MIB_DESC(1, 0x30, "Rx1518Byte"), + MIB_DESC(1, 0x34, "RxMaxByte"), + MIB_DESC(1, 0x38, "RxTooLong"), + MIB_DESC(2, 0x3c, "RxGoodByte"), + MIB_DESC(2, 0x44, "RxBadByte"), + MIB_DESC(1, 0x4c, "RxOverFlow"), + MIB_DESC(1, 0x50, "Filtered"), + MIB_DESC(1, 0x54, "TxBroad"), + MIB_DESC(1, 0x58, "TxPause"), + MIB_DESC(1, 0x5c, "TxMulti"), + MIB_DESC(1, 0x60, "TxUnderRun"), + MIB_DESC(1, 0x64, "Tx64Byte"), + MIB_DESC(1, 0x68, "Tx128Byte"), + MIB_DESC(1, 0x6c, "Tx256Byte"), + MIB_DESC(1, 0x70, "Tx512Byte"), + MIB_DESC(1, 0x74, "Tx1024Byte"), + MIB_DESC(1, 0x78, "Tx1518Byte"), + MIB_DESC(1, 0x7c, "TxMaxByte"), + MIB_DESC(1, 0x80, "TxOverSize"), + MIB_DESC(2, 0x84, "TxByte"), + MIB_DESC(1, 0x8c, "TxCollision"), + MIB_DESC(1, 0x90, "TxAbortCol"), + MIB_DESC(1, 0x94, "TxMultiCol"), + MIB_DESC(1, 0x98, "TxSingleCol"), + MIB_DESC(1, 0x9c, "TxExcDefer"), + MIB_DESC(1, 0xa0, "TxDefer"), + MIB_DESC(1, 0xa4, "TxLateCol"), + MIB_DESC(1, 0xa8, "RXUnicast"), + MIB_DESC(1, 0xac, "TXUnicast"), +}; + +static int +qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) +{ + u32 val; + + return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, + QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); +} + +static int +qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) +{ + u32 reg[4], val; + int i, ret; + + /* load the ARL table into an array */ + for (i = 0; i < 4; i++) { + ret = regmap_read(priv->regmap, QCA8K_REG_ATU_DATA0 + (i * 4), &val); + if (ret < 0) + return ret; + + reg[i] = val; + } + + /* vid - 83:72 */ + fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); + /* aging - 67:64 */ + fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); + /* portmask - 54:48 */ + fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); + /* mac - 47:0 */ + fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); + fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); + fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); + fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); + fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); + fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); + + return 0; +} + +static void +qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, + u8 aging) +{ + u32 reg[3] = { 0 }; + int i; + + /* vid - 83:72 */ + reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); + /* aging - 67:64 */ + reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); + /* portmask - 54:48 */ + reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); + /* mac - 47:0 */ + reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); + reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); + + /* load the array into the ARL table */ + for (i = 0; i < 3; i++) + regmap_write(priv->regmap, QCA8K_REG_ATU_DATA0 + (i * 4), reg[i]); +} + +static int +qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) +{ + u32 reg; + int ret; + + /* Set the command and FDB index */ + reg = QCA8K_ATU_FUNC_BUSY; + reg |= cmd; + if (port >= 0) { + reg |= QCA8K_ATU_FUNC_PORT_EN; + reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); + } + + /* Write the function register triggering the table access */ + ret = regmap_write(priv->regmap, QCA8K_REG_ATU_FUNC, reg); + if (ret) + return ret; + + /* wait for completion */ + ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); + if (ret) + return ret; + + /* Check for table full violation when adding an entry */ + if (cmd == QCA8K_FDB_LOAD) { + ret = regmap_read(priv->regmap, QCA8K_REG_ATU_FUNC, ®); + if (ret < 0) + return ret; + if (reg & QCA8K_ATU_FUNC_FULL) + return -1; + } + + return 0; +} + +static int +qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) +{ + int ret; + + qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); + ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); + if (ret < 0) + return ret; + + return qca8k_fdb_read(priv, fdb); +} + +static int +qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, + u16 vid, u8 aging) +{ + int ret; + + mutex_lock(&priv->reg_mutex); + qca8k_fdb_write(priv, vid, port_mask, mac, aging); + ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); + mutex_unlock(&priv->reg_mutex); + + return ret; +} + +static int +qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) +{ + int ret; + + mutex_lock(&priv->reg_mutex); + qca8k_fdb_write(priv, vid, port_mask, mac, 0); + ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); + mutex_unlock(&priv->reg_mutex); + + return ret; +} + +void +qca8k_fdb_flush(struct qca8k_priv *priv) +{ + mutex_lock(&priv->reg_mutex); + qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); + mutex_unlock(&priv->reg_mutex); +} + +static int +qca8k_fdb_search(struct qca8k_priv *priv, struct qca8k_fdb *fdb, const u8 *mac, u16 vid) +{ + int ret; + + mutex_lock(&priv->reg_mutex); + qca8k_fdb_write(priv, vid, 0, mac, 0); + ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); + if (ret < 0) + goto exit; + + ret = qca8k_fdb_read(priv, fdb); +exit: + mutex_unlock(&priv->reg_mutex); + return ret; +} + +static int +qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) +{ + u32 reg; + int ret; + + /* Set the command and VLAN index */ + reg = QCA8K_VTU_FUNC1_BUSY; + reg |= cmd; + reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); + + /* Write the function register triggering the table access */ + ret = regmap_write(priv->regmap, QCA8K_REG_VTU_FUNC1, reg); + if (ret) + return ret; + + /* wait for completion */ + ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); + if (ret) + return ret; + + /* Check for table full violation when adding an entry */ + if (cmd == QCA8K_VLAN_LOAD) { + ret = regmap_read(priv->regmap, QCA8K_REG_VTU_FUNC1, ®); + if (ret < 0) + return ret; + if (reg & QCA8K_VTU_FUNC1_FULL) + return -ENOMEM; + } + + return 0; +} + +static int +qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) +{ + u32 reg; + int ret; + + /* We do the right thing with VLAN 0 and treat it as untagged while + * preserving the tag on egress. + */ + if (vid == 0) + return 0; + + mutex_lock(&priv->reg_mutex); + ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); + if (ret < 0) + goto out; + + ret = regmap_read(priv->regmap, QCA8K_REG_VTU_FUNC0, ®); + if (ret < 0) + goto out; + reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; + reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); + if (untagged) + reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); + else + reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); + + ret = regmap_write(priv->regmap, QCA8K_REG_VTU_FUNC0, reg); + if (ret) + goto out; + ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); + +out: + mutex_unlock(&priv->reg_mutex); + + return ret; +} + +static int +qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) +{ + u32 reg, mask; + int ret, i; + bool del; + + mutex_lock(&priv->reg_mutex); + ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); + if (ret < 0) + goto out; + + ret = regmap_read(priv->regmap, QCA8K_REG_VTU_FUNC0, ®); + if (ret < 0) + goto out; + reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); + reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); + + /* Check if we're the last member to be removed */ + del = true; + for (i = 0; i < QCA8K_NUM_PORTS; i++) { + mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); + + if ((reg & mask) != mask) { + del = false; + break; + } + } + + if (del) { + ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); + } else { + ret = regmap_write(priv->regmap, QCA8K_REG_VTU_FUNC0, reg); + if (ret) + goto out; + ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); + } + +out: + mutex_unlock(&priv->reg_mutex); + + return ret; +} + +int +qca8k_mib_init(struct qca8k_priv *priv) +{ + int ret; + + mutex_lock(&priv->reg_mutex); + ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY); + if (ret) + goto exit; + + ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); + if (ret) + goto exit; + + ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); + if (ret) + goto exit; + + ret = regmap_write(priv->regmap, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); + +exit: + mutex_unlock(&priv->reg_mutex); + return ret; +} + +void +qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) +{ + u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; + + /* Port 0 and 6 have no internal PHY */ + if (port > 0 && port < 6) + mask |= QCA8K_PORT_STATUS_LINK_AUTO; + + if (enable) + regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); + else + regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); +} + +int +qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, + struct phylink_link_state *state) +{ + struct qca8k_priv *priv = ds->priv; + u32 reg; + int ret; + + ret = regmap_read(priv->regmap, QCA8K_REG_PORT_STATUS(port), ®); + if (ret < 0) + return ret; + + state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP); + state->an_complete = state->link; + state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO); + state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL : + DUPLEX_HALF; + + switch (reg & QCA8K_PORT_STATUS_SPEED) { + case QCA8K_PORT_STATUS_SPEED_10: + state->speed = SPEED_10; + break; + case QCA8K_PORT_STATUS_SPEED_100: + state->speed = SPEED_100; + break; + case QCA8K_PORT_STATUS_SPEED_1000: + state->speed = SPEED_1000; + break; + default: + state->speed = SPEED_UNKNOWN; + break; + } + + state->pause = MLO_PAUSE_NONE; + if (reg & QCA8K_PORT_STATUS_RXFLOW) + state->pause |= MLO_PAUSE_RX; + if (reg & QCA8K_PORT_STATUS_TXFLOW) + state->pause |= MLO_PAUSE_TX; + + return 1; +} + +void +qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, + phy_interface_t interface) +{ + struct qca8k_priv *priv = ds->priv; + + qca8k_port_set_status(priv, port, 0); +} + +void +qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, + phy_interface_t interface, struct phy_device *phydev, + int speed, int duplex, bool tx_pause, bool rx_pause) +{ + struct qca8k_priv *priv = ds->priv; + u32 reg; + + if (phylink_autoneg_inband(mode)) { + reg = QCA8K_PORT_STATUS_LINK_AUTO; + } else { + switch (speed) { + case SPEED_10: + reg = QCA8K_PORT_STATUS_SPEED_10; + break; + case SPEED_100: + reg = QCA8K_PORT_STATUS_SPEED_100; + break; + case SPEED_1000: + reg = QCA8K_PORT_STATUS_SPEED_1000; + break; + default: + reg = QCA8K_PORT_STATUS_LINK_AUTO; + break; + } + + if (duplex == DUPLEX_FULL) + reg |= QCA8K_PORT_STATUS_DUPLEX; + + if (rx_pause || dsa_is_cpu_port(ds, port)) + reg |= QCA8K_PORT_STATUS_RXFLOW; + + if (tx_pause || dsa_is_cpu_port(ds, port)) + reg |= QCA8K_PORT_STATUS_TXFLOW; + } + + reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; + + regmap_write(priv->regmap, QCA8K_REG_PORT_STATUS(port), reg); +} + +void +qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) +{ + const struct qca8k_match_data *match_data; + struct qca8k_priv *priv = ds->priv; + int i; + + if (stringset != ETH_SS_STATS) + return; + + match_data = device_get_match_data(priv->dev); + + for (i = 0; i < match_data->mib_count; i++) + strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, + ETH_GSTRING_LEN); +} + +void +qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, + uint64_t *data) +{ + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + const struct qca8k_match_data *match_data; + const struct qca8k_mib_desc *mib; + u32 reg, i, val; + u32 hi = 0; + int ret; + + match_data = device_get_match_data(priv->dev); + + for (i = 0; i < match_data->mib_count; i++) { + mib = &ar8327_mib[i]; + reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; + + ret = regmap_read(priv->regmap, reg, &val); + if (ret < 0) + continue; + + if (mib->size == 2) { + ret = regmap_read(priv->regmap, reg + 4, &hi); + if (ret < 0) + continue; + } + + data[i] = val; + if (mib->size == 2) + data[i] |= (u64)hi << 32; + } +} + +int +qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) +{ + const struct qca8k_match_data *match_data; + struct qca8k_priv *priv = ds->priv; + + if (sset != ETH_SS_STATS) + return 0; + + match_data = device_get_match_data(priv->dev); + + return match_data->mib_count; +} + +int +qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) +{ + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); + u32 reg; + int ret; + + mutex_lock(&priv->reg_mutex); + ret = regmap_read(priv->regmap, QCA8K_REG_EEE_CTRL, ®); + if (ret < 0) + goto exit; + + if (eee->eee_enabled) + reg |= lpi_en; + else + reg &= ~lpi_en; + ret = regmap_write(priv->regmap, QCA8K_REG_EEE_CTRL, reg); + +exit: + mutex_unlock(&priv->reg_mutex); + return ret; +} + +int +qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) +{ + /* Nothing to do on the port's MAC */ + return 0; +} + +void +qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) +{ + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + u32 stp_state; + + switch (state) { + case BR_STATE_DISABLED: + stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; + break; + case BR_STATE_BLOCKING: + stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; + break; + case BR_STATE_LISTENING: + stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; + break; + case BR_STATE_LEARNING: + stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; + break; + case BR_STATE_FORWARDING: + default: + stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; + break; + } + + regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), + QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); +} + +int +qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) +{ + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + int port_mask, cpu_port; + int i, ret; + + cpu_port = dsa_to_port(ds, port)->cpu_dp->index; + port_mask = BIT(cpu_port); + + for (i = 0; i < QCA8K_NUM_PORTS; i++) { + if (dsa_is_cpu_port(ds, i)) + continue; + if (dsa_to_port(ds, i)->bridge_dev != br) + continue; + /* Add this port to the portvlan mask of the other ports + * in the bridge + */ + ret = regmap_set_bits(priv->regmap, + QCA8K_PORT_LOOKUP_CTRL(i), + BIT(port)); + if (ret) + return ret; + if (i != port) + port_mask |= BIT(i); + } + + /* Add all other ports to this ports portvlan mask */ + ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), + QCA8K_PORT_LOOKUP_MEMBER, port_mask); + + return ret; +} + +void +qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) +{ + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + int cpu_port, i; + + cpu_port = dsa_to_port(ds, port)->cpu_dp->index; + + for (i = 0; i < QCA8K_NUM_PORTS; i++) { + if (dsa_is_cpu_port(ds, i)) + continue; + if (dsa_to_port(ds, i)->bridge_dev != br) + continue; + /* Remove this port to the portvlan mask of the other ports + * in the bridge + */ + regmap_clear_bits(priv->regmap, + QCA8K_PORT_LOOKUP_CTRL(i), + BIT(port)); + } + + /* Set the cpu port to be the only one in the portvlan mask of + * this port + */ + regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), + QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); +} + +void +qca8k_port_fast_age(struct dsa_switch *ds, int port) +{ + struct qca8k_priv *priv = ds->priv; + + mutex_lock(&priv->reg_mutex); + qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); + mutex_unlock(&priv->reg_mutex); +} + +int +qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) +{ + struct qca8k_priv *priv = ds->priv; + unsigned int secs = msecs / 1000; + u32 val; + + /* AGE_TIME reg is set in 7s step */ + val = secs / 7; + + if (val > FIELD_MAX(QCA8K_ATU_AGE_TIME_MASK)) + return -ERANGE; + + return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, + QCA8K_ATU_AGE_TIME_MASK, QCA8K_ATU_AGE_TIME(val)); +} + +int +qca8k_port_enable(struct dsa_switch *ds, int port, + struct phy_device *phy) +{ + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + + qca8k_port_set_status(priv, port, 1); + priv->port_sts[port].enabled = 1; + + if (dsa_is_user_port(ds, port)) + phy_support_asym_pause(phy); + + return 0; +} + +void +qca8k_port_disable(struct dsa_switch *ds, int port) +{ + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + + qca8k_port_set_status(priv, port, 0); + priv->port_sts[port].enabled = 0; +} + +int +qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) +{ + struct qca8k_priv *priv = ds->priv; + int i, mtu = 0; + + priv->port_mtu[port] = new_mtu; + + for (i = 0; i < QCA8K_NUM_PORTS; i++) + if (priv->port_mtu[i] > mtu) + mtu = priv->port_mtu[i]; + + /* Include L2 header / FCS length */ + return regmap_write(priv->regmap, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN); +} + +int +qca8k_port_max_mtu(struct dsa_switch *ds, int port) +{ + return QCA8K_MAX_MTU; +} + +int +qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, + u16 port_mask, u16 vid) +{ + /* Set the vid to the port vlan id if no vid is set */ + if (!vid) + vid = QCA8K_PORT_VID_DEF; + + return qca8k_fdb_add(priv, addr, port_mask, vid, + QCA8K_ATU_STATUS_STATIC); +} + +int +qca8k_port_fdb_add(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid) +{ + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + u16 port_mask = BIT(port); + + return qca8k_port_fdb_insert(priv, addr, port_mask, vid); +} + +int +qca8k_port_fdb_del(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid) +{ + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + u16 port_mask = BIT(port); + + if (!vid) + vid = QCA8K_PORT_VID_DEF; + + return qca8k_fdb_del(priv, addr, port_mask, vid); +} + +int +qca8k_port_fdb_dump(struct dsa_switch *ds, int port, + dsa_fdb_dump_cb_t *cb, void *data) +{ + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + struct qca8k_fdb _fdb = { 0 }; + int cnt = QCA8K_NUM_FDB_RECORDS; + bool is_static; + int ret = 0; + + mutex_lock(&priv->reg_mutex); + while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { + if (!_fdb.aging) + break; + is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); + ret = cb(_fdb.mac, _fdb.vid, is_static, data); + if (ret) + break; + } + mutex_unlock(&priv->reg_mutex); + + return 0; +} + +int +qca8k_port_mdb_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_mdb *mdb) +{ + struct qca8k_priv *priv = ds->priv; + struct qca8k_fdb fdb = { 0 }; + const u8 *addr = mdb->addr; + u8 port_mask = BIT(port); + u16 vid = mdb->vid; + int ret; + + /* Check if entry already exist */ + ret = qca8k_fdb_search(priv, &fdb, addr, vid); + if (ret < 0) + return ret; + + /* Rule exist. Delete first */ + if (!fdb.aging) { + ret = qca8k_fdb_del(priv, addr, fdb.port_mask, vid); + if (ret) + return ret; + } + + /* Add port to fdb portmask */ + fdb.port_mask |= port_mask; + + return qca8k_port_fdb_insert(priv, addr, fdb.port_mask, vid); +} + +int +qca8k_port_mdb_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_mdb *mdb) +{ + struct qca8k_priv *priv = ds->priv; + struct qca8k_fdb fdb = { 0 }; + const u8 *addr = mdb->addr; + u8 port_mask = BIT(port); + u16 vid = mdb->vid; + int ret; + + /* Check if entry already exist */ + ret = qca8k_fdb_search(priv, &fdb, addr, vid); + if (ret < 0) + return ret; + + /* Rule doesn't exist. Why delete? */ + if (!fdb.aging) + return -EINVAL; + + ret = qca8k_fdb_del(priv, addr, port_mask, vid); + if (ret) + return ret; + + /* Only port in the rule is this port. Don't re insert */ + if (fdb.port_mask == port_mask) + return 0; + + /* Remove port from port mask */ + fdb.port_mask &= ~port_mask; + + return qca8k_port_fdb_insert(priv, addr, fdb.port_mask, vid); +} + +int +qca8k_port_mirror_add(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror, + bool ingress) +{ + struct qca8k_priv *priv = ds->priv; + int monitor_port, ret; + u32 reg, val; + + /* Check for existent entry */ + if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) + return -EEXIST; + + ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); + if (ret) + return ret; + + /* QCA83xx can have only one port set to mirror mode. + * Check that the correct port is requested and return error otherwise. + * When no mirror port is set, the values is set to 0xF + */ + monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); + if (monitor_port != 0xF && monitor_port != mirror->to_local_port) + return -EEXIST; + + /* Set the monitor port */ + val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, + mirror->to_local_port); + ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, + QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); + if (ret) + return ret; + + if (ingress) { + reg = QCA8K_PORT_LOOKUP_CTRL(port); + val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; + } else { + reg = QCA8K_REG_PORT_HOL_CTRL1(port); + val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; + } + + ret = regmap_update_bits(priv->regmap, reg, val, val); + if (ret) + return ret; + + /* Track mirror port for tx and rx to decide when the + * mirror port has to be disabled. + */ + if (ingress) + priv->mirror_rx |= BIT(port); + else + priv->mirror_tx |= BIT(port); + + return 0; +} + +void +qca8k_port_mirror_del(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror) +{ + struct qca8k_priv *priv = ds->priv; + u32 reg, val; + int ret; + + if (mirror->ingress) { + reg = QCA8K_PORT_LOOKUP_CTRL(port); + val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; + } else { + reg = QCA8K_REG_PORT_HOL_CTRL1(port); + val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; + } + + ret = regmap_clear_bits(priv->regmap, reg, val); + if (ret) + goto err; + + if (mirror->ingress) + priv->mirror_rx &= ~BIT(port); + else + priv->mirror_tx &= ~BIT(port); + + /* No port set to send packet to mirror port. Disable mirror port */ + if (!priv->mirror_rx && !priv->mirror_tx) { + val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); + ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, + QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); + if (ret) + goto err; + } +err: + dev_err(priv->dev, "Failed to del mirror port from %d", port); +} + +int +qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, + struct netlink_ext_ack *extack) +{ + struct qca8k_priv *priv = ds->priv; + int ret; + + if (vlan_filtering) { + ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), + QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, + QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); + } else { + ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), + QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, + QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); + } + + return ret; +} + +int +qca8k_port_vlan_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct netlink_ext_ack *extack) +{ + bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; + bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; + struct qca8k_priv *priv = ds->priv; + int ret; + + ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); + if (ret) { + dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); + return ret; + } + + if (pvid) { + ret = regmap_update_bits(priv->regmap, QCA8K_EGRESS_VLAN(port), + QCA8K_EGREES_VLAN_PORT_MASK(port), + QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); + if (ret) + return ret; + + ret = regmap_write(priv->regmap, QCA8K_REG_PORT_VLAN_CTRL0(port), + QCA8K_PORT_VLAN_CVID(vlan->vid) | + QCA8K_PORT_VLAN_SVID(vlan->vid)); + } + + return ret; +} + +int +qca8k_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan) +{ + struct qca8k_priv *priv = ds->priv; + int ret; + + ret = qca8k_vlan_del(priv, port, vlan->vid); + if (ret) + dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); + + return ret; +} + +bool +qca8k_lag_can_offload(struct dsa_switch *ds, + struct net_device *lag, + struct netdev_lag_upper_info *info) +{ + struct dsa_port *dp; + int id, members = 0; + + id = dsa_lag_id(ds->dst, lag); + if (id < 0 || id >= ds->num_lag_ids) + return false; + + dsa_lag_foreach_port(dp, ds->dst, lag) + /* Includes the port joining the LAG */ + members++; + + if (members > QCA8K_NUM_PORTS_FOR_LAG) + return false; + + if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) + return false; + + return true; +} + +int +qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, + struct net_device *lag, bool delete) +{ + struct qca8k_priv *priv = ds->priv; + int ret, id, i; + u32 val; + + id = dsa_lag_id(ds->dst, lag); + + /* Read current port member */ + ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); + if (ret) + return ret; + + /* Shift val to the correct trunk */ + val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); + val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; + if (delete) + val &= ~BIT(port); + else + val |= BIT(port); + + /* Update port member. With empty portmap disable trunk */ + ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, + QCA8K_REG_GOL_TRUNK_MEMBER(id) | + QCA8K_REG_GOL_TRUNK_EN(id), + !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | + val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); + + /* Search empty member if adding or port on deleting */ + for (i = 0; i < 4; i++) { + ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); + if (ret) + return ret; + + val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); + val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; + + if (delete) { + /* If port flagged to be disabled assume this member is + * empty + */ + if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) + continue; + + val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; + if (val != port) + continue; + } else { + /* If port flagged to be enabled assume this member is + * already set + */ + if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) + continue; + } + + /* We find the member to remove */ + break; + } + + /* Set port in the correct port mask or disable port if in delate mode */ + return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), + QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | + QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), + !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | + port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); +} + +int +qca8k_port_lag_join(struct dsa_switch *ds, int port, + struct net_device *lag, + struct netdev_lag_upper_info *info) +{ + if (!qca8k_lag_can_offload(ds, lag, info)) + return -EOPNOTSUPP; + + return qca8k_lag_refresh_portmap(ds, port, lag, false); +} + +int +qca8k_port_lag_leave(struct dsa_switch *ds, int port, + struct net_device *lag) +{ + return qca8k_lag_refresh_portmap(ds, port, lag, true); +} diff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h index 5310022569f3..8e3888bf6823 100644 --- a/drivers/net/dsa/qca/qca8k.h +++ b/drivers/net/dsa/qca/qca8k.h @@ -360,4 +360,54 @@ struct qca8k_fdb { u8 mac[6]; }; +/* Common setup function */ +extern const struct regmap_access_table qca8k_readable_table; + +void qca8k_fdb_flush(struct qca8k_priv *priv); +int qca8k_mib_init(struct qca8k_priv *priv); +void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable); +void qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, + phy_interface_t interface, struct phy_device *phydev, int speed, + int duplex, bool tx_pause, bool rx_pause); +void qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, + phy_interface_t interface); +int qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, struct phylink_link_state *state); + +/* Common ops function */ +void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data); +void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data); +int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset); +int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee); +int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); +void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state); +int qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br); +void qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br); +void qca8k_port_fast_age(struct dsa_switch *ds, int port); +int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs); +int qca8k_port_enable(struct dsa_switch *ds, int port, struct phy_device *phy); +void qca8k_port_disable(struct dsa_switch *ds, int port); +int qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu); +int qca8k_port_max_mtu(struct dsa_switch *ds, int port); +int qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, u16 port_mask, u16 vid); +int qca8k_port_fdb_add(struct dsa_switch *ds, int port, const unsigned char *addr, u16 vid); +int qca8k_port_fdb_del(struct dsa_switch *ds, int port, const unsigned char *addr, u16 vid); +int qca8k_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb, void *data); +int qca8k_port_mdb_add(struct dsa_switch *ds, int port, const struct switchdev_obj_port_mdb *mdb); +int qca8k_port_mdb_del(struct dsa_switch *ds, int port, const struct switchdev_obj_port_mdb *mdb); +int qca8k_port_mirror_add(struct dsa_switch *ds, int port, struct dsa_mall_mirror_tc_entry *mirror, + bool ingress); +void qca8k_port_mirror_del(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror); +int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, + struct netlink_ext_ack *extack); +int qca8k_port_vlan_add(struct dsa_switch *ds, int port, const struct switchdev_obj_port_vlan *vlan, + struct netlink_ext_ack *extack); +int qca8k_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan); +bool qca8k_lag_can_offload(struct dsa_switch *ds, struct net_device *lag, + struct netdev_lag_upper_info *info); +int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct net_device *lag, + struct netdev_lag_upper_info *info); +int qca8k_port_lag_leave(struct dsa_switch *ds, int port, struct net_device *lag); + #endif /* __QCA8K_H */