From nobody Mon Jun 22 20:13:35 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79DEEC433F5 for ; Thu, 17 Mar 2022 18:49:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237604AbiCQSux (ORCPT ); Thu, 17 Mar 2022 14:50:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52324 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237598AbiCQSun (ORCPT ); Thu, 17 Mar 2022 14:50:43 -0400 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F8A414A913; Thu, 17 Mar 2022 11:49:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1647542966; x=1679078966; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PZK7t6renrW3eZPCm7Lk7qffTcGlqKELQtWdjAVV5iw=; b=q0Ox4f5zH/04Ef7JuMZNQtPh1iIneWaLI+2Hz00W7v03kdCJeERoaaqO OYqt+MfuRAl8mGn03nfcq08+1rQ9EnZqPmTTU+WqublWB9NYDuWQ07Nuk IKUgIezssVOqfBgschQ1v2gAgvuiizyCU9ieEQX0uRA4Rijzkgoh9rbSK ldCVdLv+zB1aNyg5EmmKLubZipOXPtdsStrzOxZ4g/da5g2PU0lvKJXKg nvL4Eh9EGPXOSy/2v+KMtC/qZ0XMtYeTF7x1gXp36apDQYcZeGUrPzue5 BqkXM2iX91zi4SOmMSmC2xD0GeipA0rWtJzTIJEPuBcMr/BWJKm9Y/Xs/ Q==; X-IronPort-AV: E=Sophos;i="5.90,188,1643698800"; d="scan'208";a="152385615" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 17 Mar 2022 11:49:25 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Thu, 17 Mar 2022 11:49:25 -0700 Received: from soft-dev3-1.microsemi.net (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Thu, 17 Mar 2022 11:49:23 -0700 From: Horatiu Vultur To: , , CC: , , , , Horatiu Vultur Subject: [PATCH net-next 1/5] dt-bindings: net: lan966x: Extend with FDMA interrupt Date: Thu, 17 Mar 2022 19:51:55 +0100 Message-ID: <20220317185159.1661469-2-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220317185159.1661469-1-horatiu.vultur@microchip.com> References: <20220317185159.1661469-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Extend dt-bindings for lan966x with FDMA interrupt. This is generated when receiving a frame or when a frame was transmitted. The interrupt needs to be enable for each frame. Signed-off-by: Horatiu Vultur --- .../devicetree/bindings/net/microchip,lan966x-switch.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/net/microchip,lan966x-switch= .yaml b/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml index 13812768b923..14e0bae5965f 100644 --- a/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml +++ b/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml @@ -39,6 +39,7 @@ properties: - description: frame dma based extraction - description: analyzer interrupt - description: ptp interrupt + - description: fdma interrupt =20 interrupt-names: minItems: 1 @@ -47,6 +48,7 @@ properties: - const: fdma - const: ana - const: ptp + - const: fdma =20 resets: items: --=20 2.33.0 From nobody Mon Jun 22 20:13:35 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69FD1C433FE for ; Thu, 17 Mar 2022 18:49:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237621AbiCQSvK (ORCPT ); Thu, 17 Mar 2022 14:51:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236433AbiCQSu5 (ORCPT ); Thu, 17 Mar 2022 14:50:57 -0400 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6925415282D; Thu, 17 Mar 2022 11:49:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1647542979; x=1679078979; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=WfI5G02fGHkS/S1ac3LCaw287JuZCekgMpLauxPRYAA=; b=czTl7RQWEZH17QGu11H1vWQd/++yu/b7EfDIsDSR19LZRqRa8E7+DHlP T31Wchy9DZyGlZvzRSvLzzwFN/a8s2qf4416DcMsbgn/uJJMtmjY21gFv RX8Me65ktHFRPyK2/OC0l8pRKwmEaRx3Q20+iOwPT+k4mIyfwhGp5lBF9 cjgLBqtlCohfjuYrVaA/z18OQznnmT1mapuhjKWH7enxS02/uzlRZfgFK YnNAgpOYmkwEuthzHXdhnCF3RQAfngyxiTpOz+zjnTBBgD48yDWTjPpRf 4qljackiOUQqrN7iSPULhQEf6hbbaDOOC5d6+PxgOrmWlro+9yLlnrsjy A==; X-IronPort-AV: E=Sophos;i="5.90,188,1643698800"; d="scan'208";a="157296999" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 17 Mar 2022 11:49:27 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Thu, 17 Mar 2022 11:49:27 -0700 Received: from soft-dev3-1.microsemi.net (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Thu, 17 Mar 2022 11:49:25 -0700 From: Horatiu Vultur To: , , CC: , , , , Horatiu Vultur Subject: [PATCH net-next 2/5] net: lan966x: Add registers that are used for FDMA. Date: Thu, 17 Mar 2022 19:51:56 +0100 Message-ID: <20220317185159.1661469-3-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220317185159.1661469-1-horatiu.vultur@microchip.com> References: <20220317185159.1661469-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add the registers that are used to configure the FDMA. Signed-off-by: Horatiu Vultur --- .../ethernet/microchip/lan966x/lan966x_main.c | 1 + .../ethernet/microchip/lan966x/lan966x_regs.h | 106 ++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/driver= s/net/ethernet/microchip/lan966x/lan966x_main.c index e1bcb28039dc..4240db708886 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -43,6 +43,7 @@ struct lan966x_main_io_resource { =20 static const struct lan966x_main_io_resource lan966x_main_iomap[] =3D { { TARGET_CPU, 0xc0000, 0 }, /* 0xe00c0000 */ + { TARGET_FDMA, 0xc0400, 0 }, /* 0xe00c0400 */ { TARGET_ORG, 0, 1 }, /* 0xe2000000 */ { TARGET_GCB, 0x4000, 1 }, /* 0xe2004000 */ { TARGET_QS, 0x8000, 1 }, /* 0xe2008000 */ diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h b/driver= s/net/ethernet/microchip/lan966x/lan966x_regs.h index 0c0b3e173d53..2f59285bef29 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h @@ -17,6 +17,7 @@ enum lan966x_target { TARGET_CHIP_TOP =3D 5, TARGET_CPU =3D 6, TARGET_DEV =3D 13, + TARGET_FDMA =3D 21, TARGET_GCB =3D 27, TARGET_ORG =3D 36, TARGET_PTP =3D 41, @@ -578,6 +579,111 @@ enum lan966x_target { #define DEV_PCS1G_STICKY_LINK_DOWN_STICKY_GET(x)\ FIELD_GET(DEV_PCS1G_STICKY_LINK_DOWN_STICKY, x) =20 +/* FDMA:FDMA:FDMA_CH_ACTIVATE */ +#define FDMA_CH_ACTIVATE __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 0= , 0, 1, 4) + +#define FDMA_CH_ACTIVATE_CH_ACTIVATE GENMASK(7, 0) +#define FDMA_CH_ACTIVATE_CH_ACTIVATE_SET(x)\ + FIELD_PREP(FDMA_CH_ACTIVATE_CH_ACTIVATE, x) +#define FDMA_CH_ACTIVATE_CH_ACTIVATE_GET(x)\ + FIELD_GET(FDMA_CH_ACTIVATE_CH_ACTIVATE, x) + +/* FDMA:FDMA:FDMA_CH_RELOAD */ +#define FDMA_CH_RELOAD __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 4= , 0, 1, 4) + +#define FDMA_CH_RELOAD_CH_RELOAD GENMASK(7, 0) +#define FDMA_CH_RELOAD_CH_RELOAD_SET(x)\ + FIELD_PREP(FDMA_CH_RELOAD_CH_RELOAD, x) +#define FDMA_CH_RELOAD_CH_RELOAD_GET(x)\ + FIELD_GET(FDMA_CH_RELOAD_CH_RELOAD, x) + +/* FDMA:FDMA:FDMA_CH_DISABLE */ +#define FDMA_CH_DISABLE __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 8= , 0, 1, 4) + +#define FDMA_CH_DISABLE_CH_DISABLE GENMASK(7, 0) +#define FDMA_CH_DISABLE_CH_DISABLE_SET(x)\ + FIELD_PREP(FDMA_CH_DISABLE_CH_DISABLE, x) +#define FDMA_CH_DISABLE_CH_DISABLE_GET(x)\ + FIELD_GET(FDMA_CH_DISABLE_CH_DISABLE, x) + +/* FDMA:FDMA:FDMA_CH_DB_DISCARD */ +#define FDMA_CH_DB_DISCARD __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 1= 6, 0, 1, 4) + +#define FDMA_CH_DB_DISCARD_DB_DISCARD GENMASK(7, 0) +#define FDMA_CH_DB_DISCARD_DB_DISCARD_SET(x)\ + FIELD_PREP(FDMA_CH_DB_DISCARD_DB_DISCARD, x) +#define FDMA_CH_DB_DISCARD_DB_DISCARD_GET(x)\ + FIELD_GET(FDMA_CH_DB_DISCARD_DB_DISCARD, x) + +/* FDMA:FDMA:FDMA_DCB_LLP */ +#define FDMA_DCB_LLP(r) __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 5= 2, r, 8, 4) + +/* FDMA:FDMA:FDMA_DCB_LLP1 */ +#define FDMA_DCB_LLP1(r) __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 8= 4, r, 8, 4) + +/* FDMA:FDMA:FDMA_CH_ACTIVE */ +#define FDMA_CH_ACTIVE __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 1= 80, 0, 1, 4) + +/* FDMA:FDMA:FDMA_CH_CFG */ +#define FDMA_CH_CFG(r) __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 2= 24, r, 8, 4) + +#define FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY BIT(4) +#define FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_SET(x)\ + FIELD_PREP(FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY, x) +#define FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_GET(x)\ + FIELD_GET(FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY, x) + +#define FDMA_CH_CFG_CH_INJ_PORT BIT(3) +#define FDMA_CH_CFG_CH_INJ_PORT_SET(x)\ + FIELD_PREP(FDMA_CH_CFG_CH_INJ_PORT, x) +#define FDMA_CH_CFG_CH_INJ_PORT_GET(x)\ + FIELD_GET(FDMA_CH_CFG_CH_INJ_PORT, x) + +#define FDMA_CH_CFG_CH_DCB_DB_CNT GENMASK(2, 1) +#define FDMA_CH_CFG_CH_DCB_DB_CNT_SET(x)\ + FIELD_PREP(FDMA_CH_CFG_CH_DCB_DB_CNT, x) +#define FDMA_CH_CFG_CH_DCB_DB_CNT_GET(x)\ + FIELD_GET(FDMA_CH_CFG_CH_DCB_DB_CNT, x) + +#define FDMA_CH_CFG_CH_MEM BIT(0) +#define FDMA_CH_CFG_CH_MEM_SET(x)\ + FIELD_PREP(FDMA_CH_CFG_CH_MEM, x) +#define FDMA_CH_CFG_CH_MEM_GET(x)\ + FIELD_GET(FDMA_CH_CFG_CH_MEM, x) + +/* FDMA:FDMA:FDMA_PORT_CTRL */ +#define FDMA_PORT_CTRL(r) __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 3= 76, r, 2, 4) + +#define FDMA_PORT_CTRL_INJ_STOP BIT(4) +#define FDMA_PORT_CTRL_INJ_STOP_SET(x)\ + FIELD_PREP(FDMA_PORT_CTRL_INJ_STOP, x) +#define FDMA_PORT_CTRL_INJ_STOP_GET(x)\ + FIELD_GET(FDMA_PORT_CTRL_INJ_STOP, x) + +#define FDMA_PORT_CTRL_XTR_STOP BIT(2) +#define FDMA_PORT_CTRL_XTR_STOP_SET(x)\ + FIELD_PREP(FDMA_PORT_CTRL_XTR_STOP, x) +#define FDMA_PORT_CTRL_XTR_STOP_GET(x)\ + FIELD_GET(FDMA_PORT_CTRL_XTR_STOP, x) + +/* FDMA:FDMA:FDMA_INTR_DB */ +#define FDMA_INTR_DB __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 3= 92, 0, 1, 4) + +/* FDMA:FDMA:FDMA_INTR_DB_ENA */ +#define FDMA_INTR_DB_ENA __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 3= 96, 0, 1, 4) + +#define FDMA_INTR_DB_ENA_INTR_DB_ENA GENMASK(7, 0) +#define FDMA_INTR_DB_ENA_INTR_DB_ENA_SET(x)\ + FIELD_PREP(FDMA_INTR_DB_ENA_INTR_DB_ENA, x) +#define FDMA_INTR_DB_ENA_INTR_DB_ENA_GET(x)\ + FIELD_GET(FDMA_INTR_DB_ENA_INTR_DB_ENA, x) + +/* FDMA:FDMA:FDMA_INTR_ERR */ +#define FDMA_INTR_ERR __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 4= 00, 0, 1, 4) + +/* FDMA:FDMA:FDMA_ERRORS */ +#define FDMA_ERRORS __REG(TARGET_FDMA, 0, 1, 8, 0, 1, 428, 4= 12, 0, 1, 4) + /* PTP:PTP_CFG:PTP_DOM_CFG */ #define PTP_DOM_CFG __REG(TARGET_PTP, 0, 1, 512, 0, 1, 16, 1= 2, 0, 1, 4) =20 --=20 2.33.0 From nobody Mon Jun 22 20:13:35 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E523EC433FE for ; Thu, 17 Mar 2022 18:49:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237640AbiCQSvO (ORCPT ); Thu, 17 Mar 2022 14:51:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54000 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237633AbiCQSvF (ORCPT ); Thu, 17 Mar 2022 14:51:05 -0400 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F2A8F15406C; Thu, 17 Mar 2022 11:49:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1647542981; x=1679078981; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UIA4OUtyevfFwbXDl9c8qyFkJLoal37oWQE39z9VEWc=; b=QPjdW6zNNsUDJMLKCT100FDI/A51JzPsCerXvKyY8h+RgPiBPRkcMmKR k72L++YutwNYNoatis3iI9gX4wlWQx7LofAuup2h531Bj41uk5PqZXOgb AKoOpByNP/PU9X3tf4lrgaGrWB0UdovYTQ82Hrkmh+iWisn9/ossWNakq GmgmsaRMtm4VMwxm4qrasOOBQXpjCi+hlFAGpPjBhESf1WQzxctnhNA6y t8Up657spmbVwZS5SFM6V/LK1BiomXz+kW+Cfu8TDim0MLmTrLpfn1EBS 5GJGDXHxq/WRKdzbd+7vRQ74Z/DsdKm12n5CK8eWUrSveq7+cDm7x+pgg A==; X-IronPort-AV: E=Sophos;i="5.90,188,1643698800"; d="scan'208";a="157297002" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 17 Mar 2022 11:49:30 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Thu, 17 Mar 2022 11:49:29 -0700 Received: from soft-dev3-1.microsemi.net (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Thu, 17 Mar 2022 11:49:27 -0700 From: Horatiu Vultur To: , , CC: , , , , Horatiu Vultur Subject: [PATCH net-next 3/5] net: lan966x: Expose functions that are needed by FDMA Date: Thu, 17 Mar 2022 19:51:57 +0100 Message-ID: <20220317185159.1661469-4-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220317185159.1661469-1-horatiu.vultur@microchip.com> References: <20220317185159.1661469-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Expose the following functions 'lan966x_hw_offload', 'lan966x_ifh_get_src_port' and 'lan966x_ifh_get_timestamp' in lan966x_main.h so they can be accessed by FDMA. Signed-off-by: Horatiu Vultur --- drivers/net/ethernet/microchip/lan966x/lan966x_main.c | 10 +++------- drivers/net/ethernet/microchip/lan966x/lan966x_main.h | 8 ++++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/driver= s/net/ethernet/microchip/lan966x/lan966x_main.c index 4240db708886..2c82f847ae6d 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -24,9 +24,6 @@ #define XTR_NOT_READY 0x07000080U #define XTR_VALID_BYTES(x) (4 - (((x) >> 24) & 3)) =20 -#define READL_SLEEP_US 10 -#define READL_TIMEOUT_US 100000000 - #define IO_RANGES 2 =20 static const struct of_device_id lan966x_match[] =3D { @@ -430,8 +427,7 @@ bool lan966x_netdevice_check(const struct net_device *d= ev) return dev->netdev_ops =3D=3D &lan966x_port_netdev_ops; } =20 -static bool lan966x_hw_offload(struct lan966x *lan966x, u32 port, - struct sk_buff *skb) +bool lan966x_hw_offload(struct lan966x *lan966x, u32 port, struct sk_buff = *skb) { u32 val; =20 @@ -512,7 +508,7 @@ static int lan966x_rx_frame_word(struct lan966x *lan966= x, u8 grp, u32 *rval) } } =20 -static void lan966x_ifh_get_src_port(void *ifh, u64 *src_port) +void lan966x_ifh_get_src_port(void *ifh, u64 *src_port) { packing(ifh, src_port, IFH_POS_SRCPORT + IFH_WID_SRCPORT - 1, IFH_POS_SRCPORT, IFH_LEN * 4, UNPACK, 0); @@ -524,7 +520,7 @@ static void lan966x_ifh_get_len(void *ifh, u64 *len) IFH_POS_LEN, IFH_LEN * 4, UNPACK, 0); } =20 -static void lan966x_ifh_get_timestamp(void *ifh, u64 *timestamp) +void lan966x_ifh_get_timestamp(void *ifh, u64 *timestamp) { packing(ifh, timestamp, IFH_POS_TIMESTAMP + IFH_WID_TIMESTAMP - 1, IFH_POS_TIMESTAMP, IFH_LEN * 4, UNPACK, 0); diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/driver= s/net/ethernet/microchip/lan966x/lan966x_main.h index ae282da1da74..b692c612f235 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h @@ -17,6 +17,9 @@ #define TABLE_UPDATE_SLEEP_US 10 #define TABLE_UPDATE_TIMEOUT_US 100000 =20 +#define READL_SLEEP_US 10 +#define READL_TIMEOUT_US 100000000 + #define LAN966X_BUFFER_CELL_SZ 64 #define LAN966X_BUFFER_MEMORY (160 * 1024) #define LAN966X_BUFFER_MIN_SZ 60 @@ -195,6 +198,11 @@ bool lan966x_netdevice_check(const struct net_device *= dev); void lan966x_register_notifier_blocks(void); void lan966x_unregister_notifier_blocks(void); =20 +bool lan966x_hw_offload(struct lan966x *lan966x, u32 port, struct sk_buff = *skb); + +void lan966x_ifh_get_src_port(void *ifh, u64 *src_port); +void lan966x_ifh_get_timestamp(void *ifh, u64 *timestamp); + void lan966x_stats_get(struct net_device *dev, struct rtnl_link_stats64 *stats); int lan966x_stats_init(struct lan966x *lan966x); --=20 2.33.0 From nobody Mon Jun 22 20:13:35 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 78C42C4332F for ; Thu, 17 Mar 2022 18:49:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237632AbiCQSu4 (ORCPT ); Thu, 17 Mar 2022 14:50:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237612AbiCQSuv (ORCPT ); Thu, 17 Mar 2022 14:50:51 -0400 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E703314ACBE; Thu, 17 Mar 2022 11:49:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1647542972; x=1679078972; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ijdQp/jnxn+WCsD8fYfPdKIMyKpfGqpynKIID8+tmXc=; b=ZGpSLKzSHmpZ2Hhv23qn98e3jaYCNexBBQ67mprksYnM0r7LPbcdWcK/ kybIIvntpDR8nHemyBHURHkRwtkXp7nbknXGkjLPx7+dQtNmp9iz2wWWc h1mDLQ6Oiw3+k36P8tfwxhK+sHZ1n3vfjzqzKp5TugrTD51UC3HV4fb0s +lx5qfczTxr9I//QYgqSu7XuPvOP3Shqw8NA99kTAP1FeGqJd5oizOUfR S365yK2kDoyER70TIlnMTM7G6L7RbRG/WU1m4QMVczYu01R7NU3rM5i+h AkUnBlsg2A5E+AZ90ZpPKOKxPjKUfMQBCZLh4ENpJwj9tPN1SCnE9rCQe w==; X-IronPort-AV: E=Sophos;i="5.90,188,1643698800"; d="scan'208";a="152385620" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 17 Mar 2022 11:49:32 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Thu, 17 Mar 2022 11:49:32 -0700 Received: from soft-dev3-1.microsemi.net (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Thu, 17 Mar 2022 11:49:30 -0700 From: Horatiu Vultur To: , , CC: , , , , Horatiu Vultur Subject: [PATCH net-next 4/5] net: lan966x: Add FDMA functionality Date: Thu, 17 Mar 2022 19:51:58 +0100 Message-ID: <20220317185159.1661469-5-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220317185159.1661469-1-horatiu.vultur@microchip.com> References: <20220317185159.1661469-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Ethernet frames can be extracted or injected to or from the device's DDR memory. There is one channel for injection and one channel for extraction. Each of these channels contain a linked list of DCBs which contains DB. The DCB for injection contains only 1 DB and the DCB for extraction contains 3 DBs. Each DB contains a frame. Everytime when a frame is received or transmitted an interrupt is generated. It is not possible to use both the FDMA and the manual injection/extraction of the frames. Therefore the FDMA has priority over the manual because of better performance values. FDMA: [ 5] 0.00-10.01 sec 456 MBytes 382 Mbits/sec 0 sender [ 5] 0.00-10.05 sec 315 MBytes 263 Mbits/sec receiver Manual: [ 5] 0.00-10.02 sec 94.0 MBytes 78.7 Mbits/sec 0 sender [ 5] 0.00-10.01 sec 118 MBytes 98.6 Mbits/sec receiver Signed-off-by: Horatiu Vultur --- .../net/ethernet/microchip/lan966x/Makefile | 2 +- .../ethernet/microchip/lan966x/lan966x_fdma.c | 677 ++++++++++++++++++ .../ethernet/microchip/lan966x/lan966x_main.c | 31 +- .../ethernet/microchip/lan966x/lan966x_main.h | 111 +++ .../ethernet/microchip/lan966x/lan966x_port.c | 3 + 5 files changed, 820 insertions(+), 4 deletions(-) create mode 100644 drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c diff --git a/drivers/net/ethernet/microchip/lan966x/Makefile b/drivers/net/= ethernet/microchip/lan966x/Makefile index a9ffc719aa0e..fd2e0ebb2427 100644 --- a/drivers/net/ethernet/microchip/lan966x/Makefile +++ b/drivers/net/ethernet/microchip/lan966x/Makefile @@ -8,4 +8,4 @@ obj-$(CONFIG_LAN966X_SWITCH) +=3D lan966x-switch.o lan966x-switch-objs :=3D lan966x_main.o lan966x_phylink.o lan966x_port.o \ lan966x_mac.o lan966x_ethtool.o lan966x_switchdev.o \ lan966x_vlan.o lan966x_fdb.o lan966x_mdb.o \ - lan966x_ptp.o + lan966x_ptp.o lan966x_fdma.o diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/driver= s/net/ethernet/microchip/lan966x/lan966x_fdma.c new file mode 100644 index 000000000000..c23e521a1f8b --- /dev/null +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c @@ -0,0 +1,677 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include "lan966x_main.h" + +static int lan966x_fdma_channel_active(struct lan966x *lan966x) +{ + return lan_rd(lan966x, FDMA_CH_ACTIVE); +} + +static struct sk_buff *lan966x_fdma_rx_alloc_skb(struct lan966x_rx *rx, + struct lan966x_db *db) +{ + struct lan966x *lan966x =3D rx->lan966x; + struct sk_buff *skb; + dma_addr_t dma_addr; + struct page *page; + void *buff_addr; + + page =3D dev_alloc_pages(rx->page_order); + if (unlikely(!page)) + return NULL; + + dma_addr =3D dma_map_page(lan966x->dev, page, 0, + PAGE_SIZE << rx->page_order, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(lan966x->dev, dma_addr))) { + __free_pages(page, rx->page_order); + return NULL; + } + + buff_addr =3D page_address(page); + skb =3D build_skb(buff_addr, PAGE_SIZE << rx->page_order); + + if (unlikely(!skb)) { + dev_err_ratelimited(lan966x->dev, + "build_skb failed !\n"); + dma_unmap_single(lan966x->dev, dma_addr, + PAGE_SIZE << rx->page_order, + DMA_FROM_DEVICE); + __free_pages(page, rx->page_order); + return NULL; + } + + db->dataptr =3D dma_addr; + return skb; +} + +static void lan966x_fdma_rx_free_skbs(struct lan966x_rx *rx) +{ + struct lan966x *lan966x =3D rx->lan966x; + struct lan966x_rx_dcb *dcb; + struct lan966x_db *db; + int i, j; + + for (i =3D 0; i < FDMA_DCB_MAX; ++i) { + dcb =3D &rx->dcbs[i]; + + for (j =3D 0; j < FDMA_RX_DCB_MAX_DBS; ++j) { + db =3D &dcb->db[j]; + dma_unmap_single(lan966x->dev, + (dma_addr_t)db->dataptr, + PAGE_SIZE << rx->page_order, + DMA_FROM_DEVICE); + kfree_skb(rx->skb[i][j]); + } + } +} + +static void lan966x_fdma_rx_add_dcb(struct lan966x_rx *rx, + struct lan966x_rx_dcb *dcb, + u64 nextptr) +{ + struct lan966x_db *db; + int i; + + for (i =3D 0; i < FDMA_RX_DCB_MAX_DBS; ++i) { + db =3D &dcb->db[i]; + db->status =3D FDMA_DCB_STATUS_INTR; + } + + dcb->nextptr =3D FDMA_DCB_INVALID_DATA; + dcb->info =3D FDMA_DCB_INFO_DATAL(PAGE_SIZE << rx->page_order); + + rx->last_entry->nextptr =3D nextptr; + rx->last_entry =3D dcb; +} + +static int lan966x_fdma_rx_alloc(struct lan966x_rx *rx) +{ + struct lan966x *lan966x =3D rx->lan966x; + struct lan966x_rx_dcb *dcb; + struct lan966x_db *db; + struct sk_buff *skb; + int i, j; + int size; + + /* calculate how many pages are needed to allocate the dcbs */ + size =3D sizeof(struct lan966x_rx_dcb) * FDMA_DCB_MAX; + size =3D ALIGN(size, PAGE_SIZE); + + rx->dcbs =3D dma_alloc_coherent(lan966x->dev, size, &rx->dma, GFP_ATOMIC); + rx->last_entry =3D rx->dcbs; + rx->db_index =3D 0; + rx->dcb_index =3D 0; + + /* Now for each dcb allocate the dbs */ + for (i =3D 0; i < FDMA_DCB_MAX; ++i) { + dcb =3D &rx->dcbs[i]; + dcb->info =3D 0; + + /* For each db allocate a skb and map skb data pointer to the DB + * dataptr. In this way when the frame is received the skb->data + * will contain the frame, so it is not needed any memcpy + */ + for (j =3D 0; j < FDMA_RX_DCB_MAX_DBS; ++j) { + db =3D &dcb->db[j]; + skb =3D lan966x_fdma_rx_alloc_skb(rx, db); + if (!skb) + return -ENOMEM; + + db->status =3D 0; + rx->skb[i][j] =3D skb; + } + + lan966x_fdma_rx_add_dcb(rx, dcb, rx->dma + sizeof(*dcb) * i); + } + + return 0; +} + +static void lan966x_fdma_rx_free(struct lan966x_rx *rx) +{ + struct lan966x *lan966x =3D rx->lan966x; + u32 size; + + /* Now it is possible to do the cleanup of dcb */ + size =3D sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX; + size =3D ALIGN(size, PAGE_SIZE); + dma_free_coherent(lan966x->dev, size, rx->dcbs, rx->dma); +} + +static void lan966x_fdma_rx_start(struct lan966x_rx *rx) +{ + struct lan966x *lan966x =3D rx->lan966x; + u32 mask; + + /* When activating a channel, first is required to write the first DCB + * address and then to activate it + */ + lan_wr(((u64)rx->dma) & GENMASK(31, 0), lan966x, + FDMA_DCB_LLP(rx->channel_id)); + lan_wr(((u64)rx->dma) >> 32, lan966x, FDMA_DCB_LLP1(rx->channel_id)); + + lan_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(FDMA_RX_DCB_MAX_DBS) | + FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_SET(1) | + FDMA_CH_CFG_CH_INJ_PORT_SET(0) | + FDMA_CH_CFG_CH_MEM_SET(1), + lan966x, FDMA_CH_CFG(rx->channel_id)); + + /* Start fdma */ + lan_rmw(FDMA_PORT_CTRL_XTR_STOP_SET(0), + FDMA_PORT_CTRL_XTR_STOP, + lan966x, FDMA_PORT_CTRL(0)); + + /* Enable interrupts */ + mask =3D lan_rd(lan966x, FDMA_INTR_DB_ENA); + mask =3D FDMA_INTR_DB_ENA_INTR_DB_ENA_GET(mask); + mask |=3D BIT(rx->channel_id); + lan_rmw(FDMA_INTR_DB_ENA_INTR_DB_ENA_SET(mask), + FDMA_INTR_DB_ENA_INTR_DB_ENA, + lan966x, FDMA_INTR_DB_ENA); + + /* Activate the channel */ + lan_rmw(FDMA_CH_ACTIVATE_CH_ACTIVATE_SET(BIT(rx->channel_id)), + FDMA_CH_ACTIVATE_CH_ACTIVATE, + lan966x, FDMA_CH_ACTIVATE); +} + +static void lan966x_fdma_rx_disable(struct lan966x_rx *rx) +{ + struct lan966x *lan966x =3D rx->lan966x; + u32 val; + + /* Disable the channel */ + lan_rmw(FDMA_CH_DISABLE_CH_DISABLE_SET(BIT(rx->channel_id)), + FDMA_CH_DISABLE_CH_DISABLE, + lan966x, FDMA_CH_DISABLE); + + readx_poll_timeout_atomic(lan966x_fdma_channel_active, lan966x, + val, !(val & BIT(rx->channel_id)), + READL_SLEEP_US, READL_TIMEOUT_US); + + lan_rmw(FDMA_CH_DB_DISCARD_DB_DISCARD_SET(BIT(rx->channel_id)), + FDMA_CH_DB_DISCARD_DB_DISCARD, + lan966x, FDMA_CH_DB_DISCARD); +} + +static void lan966x_fdma_rx_reload(struct lan966x_rx *rx) +{ + struct lan966x *lan966x =3D rx->lan966x; + + lan_rmw(FDMA_CH_RELOAD_CH_RELOAD_SET(BIT(rx->channel_id)), + FDMA_CH_RELOAD_CH_RELOAD, + lan966x, FDMA_CH_RELOAD); +} + +static void lan966x_fdma_tx_add_dcb(struct lan966x_tx *tx, + struct lan966x_tx_dcb *dcb) +{ + dcb->nextptr =3D FDMA_DCB_INVALID_DATA; + dcb->info =3D 0; +} + +static int lan966x_fdma_tx_alloc(struct lan966x_tx *tx) +{ + struct lan966x *lan966x =3D tx->lan966x; + struct lan966x_tx_dcb *dcb; + struct lan966x_db *db; + int size; + int i, j; + + tx->dcbs_buf =3D kcalloc(FDMA_DCB_MAX, sizeof(struct lan966x_tx_dcb_buf), + GFP_ATOMIC); + if (!tx->dcbs_buf) + return -ENOMEM; + + /* calculate how many pages are needed to allocate the dcbs */ + size =3D sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX; + size =3D ALIGN(size, PAGE_SIZE); + tx->dcbs =3D dma_alloc_coherent(lan966x->dev, size, &tx->dma, GFP_ATOMIC); + + /* Now for each dcb allocate the db */ + for (i =3D 0; i < FDMA_DCB_MAX; ++i) { + dcb =3D &tx->dcbs[i]; + + for (j =3D 0; j < FDMA_TX_DCB_MAX_DBS; ++j) { + db =3D &dcb->db[j]; + db->dataptr =3D 0; + db->status =3D 0; + } + + lan966x_fdma_tx_add_dcb(tx, dcb); + } + + return 0; +} + +static void lan966x_fdma_tx_free(struct lan966x_tx *tx) +{ + struct lan966x *lan966x =3D tx->lan966x; + int size; + + kfree(tx->dcbs_buf); + + size =3D sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX; + size =3D ALIGN(size, PAGE_SIZE); + dma_free_coherent(lan966x->dev, size, tx->dcbs, tx->dma); +} + +static void lan966x_fdma_tx_activate(struct lan966x_tx *tx) +{ + struct lan966x *lan966x =3D tx->lan966x; + u32 mask; + + /* When activating a channel, first is required to write the first DCB + * address and then to activate it + */ + lan_wr(((u64)tx->dma) & GENMASK(31, 0), lan966x, + FDMA_DCB_LLP(tx->channel_id)); + lan_wr(((u64)tx->dma) >> 32, lan966x, FDMA_DCB_LLP1(tx->channel_id)); + + lan_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(FDMA_TX_DCB_MAX_DBS) | + FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_SET(1) | + FDMA_CH_CFG_CH_INJ_PORT_SET(0) | + FDMA_CH_CFG_CH_MEM_SET(1), + lan966x, FDMA_CH_CFG(tx->channel_id)); + + /* Start fdma */ + lan_rmw(FDMA_PORT_CTRL_INJ_STOP_SET(0), + FDMA_PORT_CTRL_INJ_STOP, + lan966x, FDMA_PORT_CTRL(0)); + + /* Enable interrupts */ + mask =3D lan_rd(lan966x, FDMA_INTR_DB_ENA); + mask =3D FDMA_INTR_DB_ENA_INTR_DB_ENA_GET(mask); + mask |=3D BIT(tx->channel_id); + lan_rmw(FDMA_INTR_DB_ENA_INTR_DB_ENA_SET(mask), + FDMA_INTR_DB_ENA_INTR_DB_ENA, + lan966x, FDMA_INTR_DB_ENA); + + /* Activate the channel */ + lan_rmw(FDMA_CH_ACTIVATE_CH_ACTIVATE_SET(BIT(tx->channel_id)), + FDMA_CH_ACTIVATE_CH_ACTIVATE, + lan966x, FDMA_CH_ACTIVATE); +} + +static void lan966x_fdma_tx_disable(struct lan966x_tx *tx) +{ + struct lan966x *lan966x =3D tx->lan966x; + u32 val; + + /* Disable the channel */ + lan_rmw(FDMA_CH_DISABLE_CH_DISABLE_SET(BIT(tx->channel_id)), + FDMA_CH_DISABLE_CH_DISABLE, + lan966x, FDMA_CH_DISABLE); + + readx_poll_timeout_atomic(lan966x_fdma_channel_active, lan966x, + val, !(val & BIT(tx->channel_id)), + READL_SLEEP_US, READL_TIMEOUT_US); + + lan_rmw(FDMA_CH_DB_DISCARD_DB_DISCARD_SET(BIT(tx->channel_id)), + FDMA_CH_DB_DISCARD_DB_DISCARD, + lan966x, FDMA_CH_DB_DISCARD); + + tx->activated =3D false; +} + +static void lan966x_fdma_tx_reload(struct lan966x_tx *tx) +{ + struct lan966x *lan966x =3D tx->lan966x; + + /* Write the registers to reload the channel */ + lan_rmw(FDMA_CH_RELOAD_CH_RELOAD_SET(BIT(tx->channel_id)), + FDMA_CH_RELOAD_CH_RELOAD, + lan966x, FDMA_CH_RELOAD); +} + +static void lan966x_fdma_wakeup_netdev(struct lan966x *lan966x) +{ + struct lan966x_port *port; + int i; + + for (i =3D 0; i < lan966x->num_phys_ports; ++i) { + port =3D lan966x->ports[i]; + if (!port) + continue; + + if (netif_queue_stopped(port->dev)) + netif_wake_queue(port->dev); + } +} + +static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight) +{ + struct lan966x_tx *tx =3D &lan966x->tx; + struct lan966x_tx_dcb_buf *dcb_buf; + struct lan966x_db *db; + unsigned long flags; + bool clear =3D false; + int i; + + spin_lock_irqsave(&lan966x->tx_lock, flags); + for (i =3D 0; i < FDMA_DCB_MAX; ++i) { + dcb_buf =3D &tx->dcbs_buf[i]; + + if (!dcb_buf->used) + continue; + + db =3D &tx->dcbs[i].db[0]; + if (!(db->status & FDMA_DCB_STATUS_DONE)) + continue; + + dcb_buf->used =3D false; + dma_unmap_single(lan966x->dev, + dcb_buf->dma_addr, + dcb_buf->skb->len, + DMA_TO_DEVICE); + if (!dcb_buf->ptp) + dev_kfree_skb_any(dcb_buf->skb); + + clear =3D true; + } + spin_unlock_irqrestore(&lan966x->tx_lock, flags); + + if (clear) + lan966x_fdma_wakeup_netdev(lan966x); +} + +static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx) +{ + struct lan966x *lan966x =3D rx->lan966x; + u64 src_port, timestamp; + struct sk_buff *new_skb; + struct lan966x_db *db; + struct sk_buff *skb; + + /* Check if there is any data */ + db =3D &rx->dcbs[rx->dcb_index].db[rx->db_index]; + if (unlikely(!(db->status & FDMA_DCB_STATUS_DONE))) + return NULL; + + /* Get the received frame and unmap it */ + skb =3D rx->skb[rx->dcb_index][rx->db_index]; + dma_unmap_single(lan966x->dev, (dma_addr_t)db->dataptr, + FDMA_DCB_STATUS_BLOCKL(db->status), + DMA_FROM_DEVICE); + + /* Allocate a new skb and map it */ + new_skb =3D lan966x_fdma_rx_alloc_skb(rx, db); + if (unlikely(!new_skb)) + return NULL; + + rx->skb[rx->dcb_index][rx->db_index] =3D new_skb; + + skb_put(skb, FDMA_DCB_STATUS_BLOCKL(db->status)); + + lan966x_ifh_get_src_port(skb->data, &src_port); + lan966x_ifh_get_timestamp(skb->data, ×tamp); + + WARN_ON(src_port >=3D lan966x->num_phys_ports); + + skb->dev =3D lan966x->ports[src_port]->dev; + skb_pull(skb, IFH_LEN * sizeof(u32)); + + if (likely(!(skb->dev->features & NETIF_F_RXFCS))) + skb_trim(skb, skb->len - ETH_FCS_LEN); + + lan966x_ptp_rxtstamp(lan966x, skb, timestamp); + skb->protocol =3D eth_type_trans(skb, skb->dev); + + if (lan966x->bridge_mask & BIT(src_port)) { + skb->offload_fwd_mark =3D 1; + + skb_reset_network_header(skb); + if (!lan966x_hw_offload(lan966x, src_port, skb)) + skb->offload_fwd_mark =3D 0; + } + + skb->dev->stats.rx_bytes +=3D skb->len; + skb->dev->stats.rx_packets++; + + return skb; +} + +static int lan966x_fdma_napi_poll(struct napi_struct *napi, int weight) +{ + struct lan966x *lan966x =3D container_of(napi, struct lan966x, napi); + struct lan966x_rx *rx =3D &lan966x->rx; + struct list_head rx_list; + int counter =3D 0; + + lan966x_fdma_tx_clear_buf(lan966x, weight); + + INIT_LIST_HEAD(&rx_list); + + while (counter < weight) { + struct lan966x_rx_dcb *old_dcb; + struct sk_buff *skb; + u64 nextptr; + + skb =3D lan966x_fdma_rx_get_frame(rx); + if (!skb) + break; + list_add_tail(&skb->list, &rx_list); + + rx->db_index++; + counter++; + + /* Check if the DCB can be reused */ + if (rx->db_index !=3D FDMA_RX_DCB_MAX_DBS) + continue; + + /* Now the DCB can be reused, just advance the dcb_index + * pointer and set the nextptr in the DCB + */ + rx->db_index =3D 0; + + old_dcb =3D &rx->dcbs[rx->dcb_index]; + rx->dcb_index++; + rx->dcb_index &=3D FDMA_DCB_MAX - 1; + + nextptr =3D rx->dma + ((unsigned long)old_dcb - + (unsigned long)rx->dcbs); + lan966x_fdma_rx_add_dcb(rx, old_dcb, nextptr); + lan966x_fdma_rx_reload(rx); + } + + if (counter < weight) { + napi_complete_done(napi, counter); + lan_wr(0xff, lan966x, FDMA_INTR_DB_ENA); + } + + netif_receive_skb_list(&rx_list); + + return counter; +} + +irqreturn_t lan966x_fdma_irq_handler(int irq, void *args) +{ + struct lan966x *lan966x =3D args; + u32 db, err, err_type; + + db =3D lan_rd(lan966x, FDMA_INTR_DB); + err =3D lan_rd(lan966x, FDMA_INTR_ERR); + + if (db) { + lan_wr(0, lan966x, FDMA_INTR_DB_ENA); + lan_wr(db, lan966x, FDMA_INTR_DB); + + napi_schedule(&lan966x->napi); + } + + if (err) { + err_type =3D lan_rd(lan966x, FDMA_ERRORS); + + WARN(1, "Unexpected error: %d, error_type: %d\n", err, err_type); + + lan_wr(err, lan966x, FDMA_INTR_ERR); + lan_wr(err_type, lan966x, FDMA_ERRORS); + } + + return IRQ_HANDLED; +} + +static int lan966x_fdma_get_next_dcb(struct lan966x_tx *tx) +{ + struct lan966x_tx_dcb_buf *dcb_buf; + int i; + + for (i =3D 0; i < FDMA_DCB_MAX; ++i) { + dcb_buf =3D &tx->dcbs_buf[i]; + if (!dcb_buf->used && i !=3D tx->last_in_use) + return i; + } + + return -1; +} + +int lan966x_fdma_xmit(struct sk_buff *skb, __be32 *ifh, struct net_device = *dev) +{ + struct lan966x_port *port =3D netdev_priv(dev); + struct lan966x *lan966x =3D port->lan966x; + struct lan966x_tx_dcb_buf *next_dcb_buf; + struct lan966x_tx_dcb *next_dcb, *dcb; + struct lan966x_tx *tx =3D &lan966x->tx; + struct lan966x_db *next_db; + dma_addr_t dma_addr; + int next_to_use; + int err; + + /* Get next index */ + next_to_use =3D lan966x_fdma_get_next_dcb(tx); + if (next_to_use < 0) { + netif_stop_queue(dev); + err =3D NETDEV_TX_BUSY; + goto out; + } + + if (skb_put_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + err =3D NETDEV_TX_OK; + goto out; + } + + /* skb processing */ + skb_tx_timestamp(skb); + if (skb_headroom(skb) < IFH_LEN * sizeof(u32)) { + err =3D pskb_expand_head(skb, + IFH_LEN * sizeof(u32) - skb_headroom(skb), + 0, GFP_ATOMIC); + if (unlikely(err)) { + dev->stats.tx_dropped++; + err =3D NETDEV_TX_OK; + goto release; + } + } + + skb_push(skb, IFH_LEN * sizeof(u32)); + memcpy(skb->data, ifh, IFH_LEN * sizeof(u32)); + skb_put(skb, 4); + + dma_addr =3D dma_map_single(lan966x->dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(lan966x->dev, dma_addr)) { + dev->stats.tx_dropped++; + err =3D NETDEV_TX_OK; + goto release; + } + + /* Setup next dcb */ + next_dcb =3D &tx->dcbs[next_to_use]; + next_dcb->nextptr =3D FDMA_DCB_INVALID_DATA; + + next_db =3D &next_dcb->db[0]; + next_db->dataptr =3D dma_addr; + next_db->status =3D FDMA_DCB_STATUS_SOF | + FDMA_DCB_STATUS_EOF | + FDMA_DCB_STATUS_INTR | + FDMA_DCB_STATUS_BLOCKO(0) | + FDMA_DCB_STATUS_BLOCKL(skb->len); + + /* Fill up the buffer */ + next_dcb_buf =3D &tx->dcbs_buf[next_to_use]; + next_dcb_buf->skb =3D skb; + next_dcb_buf->dma_addr =3D dma_addr; + next_dcb_buf->used =3D true; + next_dcb_buf->ptp =3D false; + + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && + LAN966X_SKB_CB(skb)->rew_op =3D=3D IFH_REW_OP_TWO_STEP_PTP) + next_dcb_buf->ptp =3D true; + + if (likely(lan966x->tx.activated)) { + /* Connect current dcb to the next db */ + dcb =3D &tx->dcbs[tx->last_in_use]; + dcb->nextptr =3D tx->dma + (next_to_use * + sizeof(struct lan966x_tx_dcb)); + + lan966x_fdma_tx_reload(tx); + } else { + /* Because it is first time, then just activate */ + lan966x->tx.activated =3D true; + lan966x_fdma_tx_activate(tx); + } + + /* Move to next dcb because this last in use */ + tx->last_in_use =3D next_to_use; + + dev->stats.tx_packets++; + dev->stats.tx_bytes +=3D skb->len; + + return NETDEV_TX_OK; + +out: + return err; + +release: + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && + LAN966X_SKB_CB(skb)->rew_op =3D=3D IFH_REW_OP_TWO_STEP_PTP) + lan966x_ptp_txtstamp_release(port, skb); + + dev_kfree_skb_any(skb); + return err; +} + +void lan966x_fdma_netdev_init(struct lan966x *lan966x, struct net_device *= dev) +{ + if (lan966x->fdma_ndev) + return; + + lan966x->fdma_ndev =3D dev; + netif_napi_add(dev, &lan966x->napi, lan966x_fdma_napi_poll, + FDMA_WEIGHT); + napi_enable(&lan966x->napi); +} + +void lan966x_fdma_netdev_deinit(struct lan966x *lan966x, struct net_device= *dev) +{ + if (lan966x->fdma_ndev =3D=3D dev) { + netif_napi_del(&lan966x->napi); + lan966x->fdma_ndev =3D NULL; + } +} + +void lan966x_fdma_init(struct lan966x *lan966x) +{ + lan966x->rx.lan966x =3D lan966x; + lan966x->rx.channel_id =3D FDMA_XTR_CHANNEL; + lan966x->tx.lan966x =3D lan966x; + lan966x->tx.channel_id =3D FDMA_INJ_CHANNEL; + lan966x->tx.last_in_use =3D -1; + + lan966x_fdma_rx_alloc(&lan966x->rx); + lan966x_fdma_tx_alloc(&lan966x->tx); + + lan966x_fdma_rx_start(&lan966x->rx); +} + +void lan966x_fdma_deinit(struct lan966x *lan966x) +{ + lan966x_fdma_rx_disable(&lan966x->rx); + lan966x_fdma_tx_disable(&lan966x->tx); + + lan966x_fdma_rx_free_skbs(&lan966x->rx); + lan966x_fdma_rx_free(&lan966x->rx); + lan966x_fdma_tx_free(&lan966x->tx); +} diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/driver= s/net/ethernet/microchip/lan966x/lan966x_main.c index 2c82f847ae6d..6cb9fffc3058 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -341,7 +341,10 @@ static int lan966x_port_xmit(struct sk_buff *skb, stru= ct net_device *dev) } =20 spin_lock(&lan966x->tx_lock); - err =3D lan966x_port_ifh_xmit(skb, ifh, dev); + if (port->lan966x->fdma) + err =3D lan966x_fdma_xmit(skb, ifh, dev); + else + err =3D lan966x_port_ifh_xmit(skb, ifh, dev); spin_unlock(&lan966x->tx_lock); =20 return err; @@ -640,6 +643,9 @@ static void lan966x_cleanup_ports(struct lan966x *lan96= 6x) if (port->dev) unregister_netdev(port->dev); =20 + if (lan966x->fdma && lan966x->fdma_ndev =3D=3D port->dev) + lan966x_fdma_netdev_deinit(lan966x, port->dev); + if (port->phylink) { rtnl_lock(); lan966x_port_stop(port->dev); @@ -659,6 +665,11 @@ static void lan966x_cleanup_ports(struct lan966x *lan9= 66x) disable_irq(lan966x->ana_irq); lan966x->ana_irq =3D -ENXIO; } + + if (lan966x->fdma_irq) { + disable_irq(lan966x->fdma_irq); + lan966x->fdma_irq =3D -ENXIO; + } } =20 static int lan966x_probe_port(struct lan966x *lan966x, u32 p, @@ -787,12 +798,12 @@ static void lan966x_init(struct lan966x *lan966x) /* Do byte-swap and expect status after last data word * Extraction: Mode: manual extraction) | Byte_swap */ - lan_wr(QS_XTR_GRP_CFG_MODE_SET(1) | + lan_wr(QS_XTR_GRP_CFG_MODE_SET(lan966x->fdma ? 2 : 1) | QS_XTR_GRP_CFG_BYTE_SWAP_SET(1), lan966x, QS_XTR_GRP_CFG(0)); =20 /* Injection: Mode: manual injection | Byte_swap */ - lan_wr(QS_INJ_GRP_CFG_MODE_SET(1) | + lan_wr(QS_INJ_GRP_CFG_MODE_SET(lan966x->fdma ? 2 : 1) | QS_INJ_GRP_CFG_BYTE_SWAP_SET(1), lan966x, QS_INJ_GRP_CFG(0)); =20 @@ -1014,6 +1025,17 @@ static int lan966x_probe(struct platform_device *pde= v) lan966x->ptp =3D 1; } =20 + lan966x->fdma_irq =3D platform_get_irq_byname(pdev, "fdma"); + if (lan966x->fdma_irq > 0) { + err =3D devm_request_threaded_irq(&pdev->dev, lan966x->fdma_irq, NULL, + lan966x_fdma_irq_handler, IRQF_ONESHOT, + "fdma irq", lan966x); + if (err) + return dev_err_probe(&pdev->dev, err, "Unable to use fdma irq"); + + lan966x->fdma =3D true; + } + /* init switch */ lan966x_init(lan966x); lan966x_stats_init(lan966x); @@ -1043,6 +1065,8 @@ static int lan966x_probe(struct platform_device *pdev) lan966x_port_init(lan966x->ports[p]); } =20 + lan966x_fdma_init(lan966x); + lan966x_mdb_init(lan966x); err =3D lan966x_fdb_init(lan966x); if (err) @@ -1073,6 +1097,7 @@ static int lan966x_remove(struct platform_device *pde= v) { struct lan966x *lan966x =3D platform_get_drvdata(pdev); =20 + lan966x_fdma_deinit(lan966x); lan966x_cleanup_ports(lan966x); =20 cancel_delayed_work_sync(&lan966x->stats_work); diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/driver= s/net/ethernet/microchip/lan966x/lan966x_main.h index b692c612f235..bfa7feea2b56 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h @@ -61,6 +61,23 @@ #define IFH_REW_OP_ONE_STEP_PTP 0x3 #define IFH_REW_OP_TWO_STEP_PTP 0x4 =20 +#define FDMA_RX_DCB_MAX_DBS 3 +#define FDMA_TX_DCB_MAX_DBS 1 +#define FDMA_DCB_INFO_DATAL(x) ((x) & GENMASK(15, 0)) + +#define FDMA_DCB_STATUS_BLOCKL(x) ((x) & GENMASK(15, 0)) +#define FDMA_DCB_STATUS_SOF BIT(16) +#define FDMA_DCB_STATUS_EOF BIT(17) +#define FDMA_DCB_STATUS_INTR BIT(18) +#define FDMA_DCB_STATUS_DONE BIT(19) +#define FDMA_DCB_STATUS_BLOCKO(x) (((x) << 20) & GENMASK(31, 20)) +#define FDMA_DCB_INVALID_DATA 0x1 + +#define FDMA_XTR_CHANNEL 6 +#define FDMA_INJ_CHANNEL 0 +#define FDMA_DCB_MAX 512 +#define FDMA_WEIGHT 64 + /* MAC table entry types. * ENTRYTYPE_NORMAL is subject to aging. * ENTRYTYPE_LOCKED is not subject to aging. @@ -76,6 +93,85 @@ enum macaccess_entry_type { =20 struct lan966x_port; =20 +struct lan966x_db { + u64 dataptr; + u64 status; +}; + +struct lan966x_rx_dcb { + u64 nextptr; + u64 info; + struct lan966x_db db[FDMA_RX_DCB_MAX_DBS]; +}; + +struct lan966x_tx_dcb { + u64 nextptr; + u64 info; + struct lan966x_db db[FDMA_TX_DCB_MAX_DBS]; +}; + +struct lan966x_rx { + struct lan966x *lan966x; + + /* Pointer to the array of hardware dcbs. */ + struct lan966x_rx_dcb *dcbs; + + /* Pointer to the last address in the dcbs. */ + struct lan966x_rx_dcb *last_entry; + + /* For each DB, there is a skb, and the skb data pointer is mapped in + * the DB. Once a frame is received the skb is given to the upper layers + * and a new skb is added to the db. + */ + struct sk_buff *skb[FDMA_DCB_MAX][FDMA_RX_DCB_MAX_DBS]; + + /* Represents the db_index, it can have a value between 0 and + * FDMA_RX_DCB_MAX_DBS, once it reaches the value of FDMA_RX_DCB_MAX_DBS + * it means that the DCB can be reused. + */ + int db_index; + + /* Represents the index in the dcbs. It has a value between 0 and + * FDMA_DCB_MAX + */ + int dcb_index; + + /* Represents the dma address to the dcbs array */ + dma_addr_t dma; + + /* Represents the page order that is used to allocate the pages for the + * RX buffers. This value is calculated based on max MTU of the devices. + */ + u8 page_order; + + u8 channel_id; +}; + +struct lan966x_tx_dcb_buf { + struct sk_buff *skb; + dma_addr_t dma_addr; + bool used; + bool ptp; +}; + +struct lan966x_tx { + struct lan966x *lan966x; + + /* Pointer to the dcb list */ + struct lan966x_tx_dcb *dcbs; + u16 last_in_use; + + /* Represents the DMA address to the first entry of the dcb entries. */ + dma_addr_t dma; + + /* Array of dcbs that are given to the HW */ + struct lan966x_tx_dcb_buf *dcbs_buf; + + u8 channel_id; + + bool activated; +}; + struct lan966x_stat_layout { u32 offset; char name[ETH_GSTRING_LEN]; @@ -137,6 +233,7 @@ struct lan966x { int xtr_irq; int ana_irq; int ptp_irq; + int fdma_irq; =20 /* worqueue for fdb */ struct workqueue_struct *fdb_work; @@ -153,6 +250,13 @@ struct lan966x { spinlock_t ptp_ts_id_lock; /* lock for ts_id */ struct mutex ptp_lock; /* lock for ptp interface state */ u16 ptp_skbs; + + /* fdma */ + bool fdma; + struct net_device *fdma_ndev; + struct lan966x_rx rx; + struct lan966x_tx tx; + struct napi_struct napi; }; =20 struct lan966x_port_config { @@ -292,6 +396,13 @@ void lan966x_ptp_txtstamp_release(struct lan966x_port = *port, struct sk_buff *skb); irqreturn_t lan966x_ptp_irq_handler(int irq, void *args); =20 +int lan966x_fdma_xmit(struct sk_buff *skb, __be32 *ifh, struct net_device = *dev); +void lan966x_fdma_netdev_init(struct lan966x *lan966x, struct net_device *= dev); +void lan966x_fdma_netdev_deinit(struct lan966x *lan966x, struct net_device= *dev); +void lan966x_fdma_init(struct lan966x *lan966x); +void lan966x_fdma_deinit(struct lan966x *lan966x); +irqreturn_t lan966x_fdma_irq_handler(int irq, void *args); + static inline void __iomem *lan_addr(void __iomem *base[], int id, int tinst, int tcnt, int gbase, int ginst, diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c b/driver= s/net/ethernet/microchip/lan966x/lan966x_port.c index 237555845a52..f141644e4372 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_port.c @@ -393,6 +393,9 @@ void lan966x_port_init(struct lan966x_port *port) =20 lan966x_port_config_down(port); =20 + if (lan966x->fdma) + lan966x_fdma_netdev_init(lan966x, port->dev); + if (config->portmode !=3D PHY_INTERFACE_MODE_QSGMII) return; =20 --=20 2.33.0 From nobody Mon Jun 22 20:13:35 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77CC8C433F5 for ; Thu, 17 Mar 2022 18:50:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237674AbiCQSvS (ORCPT ); Thu, 17 Mar 2022 14:51:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237650AbiCQSvH (ORCPT ); Thu, 17 Mar 2022 14:51:07 -0400 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 175251557EF; Thu, 17 Mar 2022 11:49:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1647542984; x=1679078984; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RIdhHdpM5nL7HMZXAvGb9SlP3iancAtq9XoW3asZ+fA=; b=Pu3O+0bCfB/IKGjZYx6GfB0vBGF8KVblmJHZccAHDx2rEVuqT8pvX+b+ eShCNihi+xCwupmgA7JAwtVhXZLTkp3evRevZoAkFEBaq6CKB+1FmP938 mMxxUVnb7kEhFdJ4fN/ihjAfolVMCu6hzp+UsSb5lRGlYWCBIUOsEXydu AuvTmKMDloBlqZ2Ll+i8QCh+q3/9d3CL540ctehq9Ofk1/1CdehPxvu2D JOdeKYfPzHrpEURUVpjlj+DRu/mvbXgFy782wkGgm6Z0BQEHv+ma6s3CG JpKDLwDfF9DyzK/6QUv6j/Tz0uLKGZL0OcbVl8wpSuQ2eZJ+wNn2R2nWn A==; X-IronPort-AV: E=Sophos;i="5.90,188,1643698800"; d="scan'208";a="152385628" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 17 Mar 2022 11:49:39 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Thu, 17 Mar 2022 11:49:34 -0700 Received: from soft-dev3-1.microsemi.net (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Thu, 17 Mar 2022 11:49:32 -0700 From: Horatiu Vultur To: , , CC: , , , , Horatiu Vultur Subject: [PATCH net-next 5/5] net: lan96x: Update FDMA to change MTU. Date: Thu, 17 Mar 2022 19:51:59 +0100 Message-ID: <20220317185159.1661469-6-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220317185159.1661469-1-horatiu.vultur@microchip.com> References: <20220317185159.1661469-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" When changing the MTU, it is required to change also the size of the DBs. In case those frames will arrive to CPU. Signed-off-by: Horatiu Vultur --- .../ethernet/microchip/lan966x/lan966x_fdma.c | 95 +++++++++++++++++++ .../ethernet/microchip/lan966x/lan966x_main.c | 2 +- .../ethernet/microchip/lan966x/lan966x_main.h | 1 + 3 files changed, 97 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/driver= s/net/ethernet/microchip/lan966x/lan966x_fdma.c index c23e521a1f8b..a33329cc4834 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c @@ -633,6 +633,101 @@ int lan966x_fdma_xmit(struct sk_buff *skb, __be32 *if= h, struct net_device *dev) return err; } =20 +static int lan966x_fdma_get_max_mtu(struct lan966x *lan966x) +{ + int max_mtu =3D 0; + int i; + + for (i =3D 0; i < lan966x->num_phys_ports; ++i) { + int mtu; + + if (!lan966x->ports[i]) + continue; + + mtu =3D lan966x->ports[i]->dev->mtu; + if (mtu > max_mtu) + max_mtu =3D mtu; + } + + return max_mtu; +} + +static int lan966x_qsys_sw_status(struct lan966x *lan966x) +{ + return lan_rd(lan966x, QSYS_SW_STATUS(CPU_PORT)); +} + +static void lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu) +{ + void *rx_dcb, *tx_dcb, *tx_dcb_buf; + dma_addr_t rx_dma, tx_dma; + unsigned long flags; + u32 size; + + /* Store these for later to free them */ + rx_dma =3D lan966x->rx.dma; + tx_dma =3D lan966x->tx.dma; + rx_dcb =3D lan966x->rx.dcbs; + tx_dcb =3D lan966x->tx.dcbs; + tx_dcb_buf =3D lan966x->tx.dcbs_buf; + + lan966x_fdma_rx_disable(&lan966x->rx); + lan966x_fdma_rx_free_skbs(&lan966x->rx); + lan966x->rx.page_order =3D round_up(new_mtu, PAGE_SIZE) / PAGE_SIZE - 1; + lan966x_fdma_rx_alloc(&lan966x->rx); + lan966x_fdma_rx_start(&lan966x->rx); + + spin_lock_irqsave(&lan966x->tx_lock, flags); + lan966x_fdma_tx_disable(&lan966x->tx); + lan966x_fdma_tx_alloc(&lan966x->tx); + spin_unlock_irqrestore(&lan966x->tx_lock, flags); + + /* Now it is possible to clean */ + size =3D sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX; + size =3D ALIGN(size, PAGE_SIZE); + dma_free_coherent(lan966x->dev, size, tx_dcb, tx_dma); + + kfree(tx_dcb_buf); + + size =3D sizeof(struct lan966x_rx_dcb) * FDMA_DCB_MAX; + size =3D ALIGN(size, PAGE_SIZE); + dma_free_coherent(lan966x->dev, size, rx_dcb, rx_dma); +} + +int lan966x_fdma_change_mtu(struct lan966x *lan966x) +{ + int max_mtu; + u32 val; + + max_mtu =3D lan966x_fdma_get_max_mtu(lan966x); + if (round_up(max_mtu, PAGE_SIZE) / PAGE_SIZE - 1 =3D=3D + lan966x->rx.page_order) + return 0; + + /* Disable the CPU port */ + lan_rmw(QSYS_SW_PORT_MODE_PORT_ENA_SET(0), + QSYS_SW_PORT_MODE_PORT_ENA, + lan966x, QSYS_SW_PORT_MODE(CPU_PORT)); + + /* Flush the CPU queues */ + readx_poll_timeout(lan966x_qsys_sw_status, lan966x, + val, !(QSYS_SW_STATUS_EQ_AVAIL_GET(val)), + READL_SLEEP_US, READL_TIMEOUT_US); + + /* Add a sleep in case there are frames between the queues and the CPU + * port + */ + usleep_range(1000, 2000); + + lan966x_fdma_reload(lan966x, max_mtu); + + /* Enable back the CPU port */ + lan_rmw(QSYS_SW_PORT_MODE_PORT_ENA_SET(1), + QSYS_SW_PORT_MODE_PORT_ENA, + lan966x, QSYS_SW_PORT_MODE(CPU_PORT)); + return 0; +} + void lan966x_fdma_netdev_init(struct lan966x *lan966x, struct net_device *= dev) { if (lan966x->fdma_ndev) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/driver= s/net/ethernet/microchip/lan966x/lan966x_main.c index 6cb9fffc3058..a78fee5471e7 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -359,7 +359,7 @@ static int lan966x_port_change_mtu(struct net_device *d= ev, int new_mtu) lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port)); dev->mtu =3D new_mtu; =20 - return 0; + return !lan966x->fdma ? 0 : lan966x_fdma_change_mtu(lan966x); } =20 static int lan966x_mc_unsync(struct net_device *dev, const unsigned char *= addr) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/driver= s/net/ethernet/microchip/lan966x/lan966x_main.h index bfa7feea2b56..fa4016f2b5d4 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h @@ -397,6 +397,7 @@ void lan966x_ptp_txtstamp_release(struct lan966x_port *= port, irqreturn_t lan966x_ptp_irq_handler(int irq, void *args); =20 int lan966x_fdma_xmit(struct sk_buff *skb, __be32 *ifh, struct net_device = *dev); +int lan966x_fdma_change_mtu(struct lan966x *lan966x); void lan966x_fdma_netdev_init(struct lan966x *lan966x, struct net_device *= dev); void lan966x_fdma_netdev_deinit(struct lan966x *lan966x, struct net_device= *dev); void lan966x_fdma_init(struct lan966x *lan966x); --=20 2.33.0