From nobody Mon Jun 8 22:55:05 2026 Received: from DM5PR21CU001.outbound.protection.outlook.com (mail-centralusazon11011056.outbound.protection.outlook.com [52.101.62.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AC2DD355F47; Mon, 25 May 2026 18:27:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.62.56 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779733641; cv=fail; b=k/NOqZKVtrj7evuawJr1otR4dcScAJ9ClJ8uxMFmPqHagpaAtluZkISmkQiuLOL/XIl5HuXhpvcNVfNEM/OrwBc3Et/tTIpeHWnxBb+o7mtyUNIUg8AVT4EA7jHCNCDVI+Vfdnxl8ExF0DOhWdWZo92f2F7mgJbGpd25R8Uk8Pc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779733641; c=relaxed/simple; bh=nqm/pmGH3suat8JxnzIooSvHcgWXlwJIYYUaHJJzrTE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nh6AqOJPvzjv9eUx/sB/UAaBwTtjyLRMv0c7O1y4HOeKWM7cEb4yNSh4f3NIfQ5jW1suXJQTx3MmxI341KOB+ZvKYkfx+GloiDbypVKk+uxAXIv3DIfAOuwQ+yQDgDvib653HcsMXZUA2r9Lf130kKlDCzn/ruCICQTRvRLnp6s= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=PJXKA08S; arc=fail smtp.client-ip=52.101.62.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="PJXKA08S" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=LfKRPeEWf7Jf59cFXOrHtQPIqQdF7Ix/jq9SCYyGLGfVFhsWuNiqigE6zTzEVfYaIToxliabxGHztjgKwyEI9t0FOAg+MJ6DMx7F+0xnmLAZblpKq1XQatN68zFhlXIL3rfDsgOieP/AM56Hdg563yeLnaNCBU4QFwQZA0FQXp+ebydGEPnk6EbE7BymllT0juJVmZ3KRtQMprvtYtUy8TGt8yr2DuruSsGKegrqIjrSC7vSIYwSzwm15YT51H0XsyAx20Qd0t4a4Q9PdTsA2RTlQMrf3+FJkvjxEYgTtbtd126XegyrGrBtcqVI78V3pQwxThbKFOlWMQ7GugKBmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=3hokIAi1rYapGOc+ITEf0MHEsqvpw3Fm83dY8u9+Qvc=; b=KzEDYOh/sX4p35BetDgiawIMPuJ1Jqfx9uY9X2R0SJFTxi9kiE9yCCSUrAReXFwZ95E6vIM05vGEQ3HFhq1qwwgViSksJviEkMWKPpqBi0DNRHfWH2eU7xtffX20egkJ2SMAS6CBXxEkqem8Hg0FDfUXjuvZGbr30MKBifvsksOzeOGwcYfHjgO3ggPP77s7mQdkTCulxGQlROIBuw34ivOB7tZ8AVNOUPotrGZg+2NA6xc7y2OO6XNmHEyso5lPrDUZEuEi+kqH09cI4v/wSF+by3sg5YMGnOGZrdYRHT89Y+gPSS9v6GQOshcaXs0k3upgi9PNrJCz5VWS5RfFkw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 198.47.21.194) smtp.rcpttodomain=gmail.com smtp.mailfrom=ti.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=ti.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=3hokIAi1rYapGOc+ITEf0MHEsqvpw3Fm83dY8u9+Qvc=; b=PJXKA08S0nvg+aDXkfq7gygJa+/qZaA5+hvIOUTDn3ubI86lf8mr3KbM4G0SjM9/WwHh1BQUQjSx+OuY1BBTNeI27vZKpHDTXja4w2L2ausHyYXNI7lNpPPtwDWP90flMJqaTKvi1/VCX56xPaes1sxbF5A8ILGMem2MRVHRNrM= Received: from SA1P222CA0015.NAMP222.PROD.OUTLOOK.COM (2603:10b6:806:22c::33) by LV3PR10MB7938.namprd10.prod.outlook.com (2603:10b6:408:217::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.48.20; Mon, 25 May 2026 18:27:14 +0000 Received: from SN1PEPF000397B3.namprd05.prod.outlook.com (2603:10b6:806:22c:cafe::78) by SA1P222CA0015.outlook.office365.com (2603:10b6:806:22c::33) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.48.20 via Frontend Transport; Mon, 25 May 2026 18:27:14 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 198.47.21.194) smtp.mailfrom=ti.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=ti.com; Received-SPF: Pass (protection.outlook.com: domain of ti.com designates 198.47.21.194 as permitted sender) receiver=protection.outlook.com; client-ip=198.47.21.194; helo=flwvzet200.ext.ti.com; pr=C Received: from flwvzet200.ext.ti.com (198.47.21.194) by SN1PEPF000397B3.mail.protection.outlook.com (10.167.248.57) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.71.7 via Frontend Transport; Mon, 25 May 2026 18:27:13 +0000 Received: from DFLE208.ent.ti.com (10.64.6.66) by flwvzet200.ext.ti.com (10.248.192.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.37; Mon, 25 May 2026 13:27:12 -0500 Received: from DFLE212.ent.ti.com (10.64.6.70) by DFLE208.ent.ti.com (10.64.6.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.37; Mon, 25 May 2026 13:27:10 -0500 Received: from lelvem-mr06.itg.ti.com (10.180.75.8) by DFLE212.ent.ti.com (10.64.6.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.37 via Frontend Transport; Mon, 25 May 2026 13:27:10 -0500 Received: from lelv0854.itg.ti.com (lelv0854.itg.ti.com [10.181.64.140]) by lelvem-mr06.itg.ti.com (8.18.1/8.18.1) with ESMTP id 64PIRAWD3512349; Mon, 25 May 2026 13:27:10 -0500 Received: from localhost (meghana-pc.dhcp.ti.com [10.24.69.13] (may be forged)) by lelv0854.itg.ti.com (8.14.7/8.14.7) with ESMTP id 64PIR9w8018232; Mon, 25 May 2026 13:27:10 -0500 From: Meghana Malladi To: , , , , , , , , , , , , , , , , , , , CC: , , , , Vignesh Raghavendra Subject: [PATCH net-next v6 1/2] net: ti: icssg-prueth: Add Frame Preemption MAC Merge support Date: Mon, 25 May 2026 23:56:59 +0530 Message-ID: <20260525182700.3135858-2-m-malladi@ti.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260525182700.3135858-1-m-malladi@ti.com> References: <20260525182700.3135858-1-m-malladi@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF000397B3:EE_|LV3PR10MB7938:EE_ X-MS-Office365-Filtering-Correlation-Id: 7b7d89bd-454b-464f-a131-08deba8b3daf X-LD-Processed: e5b49634-450b-4709-8abb-1e2b19b982b7,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|82310400026|7416014|376014|36860700016|921020|6133799003|3023799007|22082099003|56012099003|18002099003|13003099007; X-Microsoft-Antispam-Message-Info: aOfhbQxM3UIaAp9U94IpXirzZPlKas1KtFnXO6rYvBIi8UrDc+6ws+u8jSwocGgYQKUUGjqjOiG1DAUpxUr3YzUe6RnNi13B6lJXm9w6dQzLRcyc+0I97/a3XxvICw/ZbNKj823o8twt2AJiLFp2tj2WX98JDWT9JUNGYh3pndyI3+W18w5iRSG+F+gwlsCT3M6inBDIBd7WlP2cM6Ecq1l/TArfLLoNk5DjDKV8UrvsoD8ppeFxtBTnhj9gyZ++YQVZZrKVhLJ8QlJjOjEakmlnkVK23h53JhvRsvZEiajL5sTJKT4g0EcUtC0OHhd26yDkRl5y1E4QIQ0+FDIJEC0sIr5DIrvAIjqa4bzFBKtLwZr5LpK5PEBniqoKAx2pnH9xVBCmbgoRvIU/Ge3gOOwrJdDb0zkcJQO3i8N5tqgb5HFOfQDX6sPxenWZqL4cjKPT3XpK7ApZDgbW/Hu9pJnPNfNClww6N4VhlVYa9jVyJQnunpu+PLL2lHTwPlZxwQDhiSCSpKcPMqTy2i9iCbFRCIRe3h4j0H0RsfzLDQzFaHEopvwdmdv3dGspxTda0wt5cm07OGGJgPAaF3GZovXrCdl4kBmkVCdXXNWV7jbfLMmcLGtySIj2R5lcU9aAzOqy5ie8YVHGM9VynEl71m5er5QwZ2jixSUTu1SqZYyVIweTLl0SuNj6qHrtEnML2tJKD1X0QTLc5gyLfCWVRijFPpPg1UeOB4Hvg8P5cMI= X-Forefront-Antispam-Report: CIP:198.47.21.194;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:flwvzet200.ext.ti.com;PTR:ErrorRetry;CAT:NONE;SFS:(13230040)(1800799024)(82310400026)(7416014)(376014)(36860700016)(921020)(6133799003)(3023799007)(22082099003)(56012099003)(18002099003)(13003099007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: T/90PgXNjMptliZwFmVBco8CIfkwX4s3pVzZKwYOnF3YOWKecGsdpwPlMsr1Xn06uPMxUQnNcHJoh+rANLXI3xszANa8CJH6+B0oBboSs8HVX/DgbPf3AzLYha6aZzr6BwZ4893ka7UkldINEa7QIh2YYjclXUxn9oDG97m+8iodBsAAeXrwST5wv8h4nQPWfUBMe8b7kj2eDacvQrdVOXkQZY1UHsn/pwNJGSqaX9IHLZQXSv4jobr1CkDyS9A+ibIaW+rUh4TdxFcqA0crCQCgCcfJLc8uFAE3ajzLplf1xSHz9qk+4exDyK6VcbjJTfgjT8eVxOPahTEv+zZ2C4Os2DIYgMPQ8XDclFzxle2mCcTaXGhXRs2E6A4dJXD1rQKyDm2NQJzvJzYdVnmnoXVbGN2BSeBc7ml+qgBtLf/rxCQjvc/NLkML32jEy6Cz X-OriginatorOrg: ti.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 May 2026 18:27:13.0445 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7b7d89bd-454b-464f-a131-08deba8b3daf X-MS-Exchange-CrossTenant-Id: e5b49634-450b-4709-8abb-1e2b19b982b7 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=e5b49634-450b-4709-8abb-1e2b19b982b7;Ip=[198.47.21.194];Helo=[flwvzet200.ext.ti.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF000397B3.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV3PR10MB7938 Content-Type: text/plain; charset="utf-8" From: MD Danish Anwar Introduce QoS infrastructure for Frame Preemption (FPE) support in the ICSSG Ethernet driver. prueth_qos_iet tracks FPE enable/active state and verify state machine status via firmware-reported enum icssg_ietfpe_verify_states. icssg_config_ietfpe() configures IET FPE in firmware, triggers verify state machine based on ethtool MAC Merge parameters. Polls firmware verify status up to 3 times with verify_time_ms intervals and driver handles timeout by logging error and returning. In case of any failure during configuration for enable/disable, IET FPE falls back to disabled state. For MQPRIO qdisc support all queues are express by default later gets override by user-provided preemptible_tcs bitmask via tc qdisc mask Preempt mask configuration: Maps traffic classes to queue express/preemptib= le state and applied only when FPE is active (Tx enabled) Verify state machine re-triggers on link up/down events based on fpe_enabled and fpe_active flags, and for memory protection, fpe_lock serializes all FPE state mutations, preventing races between ethtool config, qdisc setup, and link events Signed-off-by: MD Danish Anwar Signed-off-by: Meghana Malladi --- v6-v5: - Balance fpe_lock mutex lifecycle on all error paths=20 - Remove deadcode inside icssg_iet_set_preempt_mask() - Add fallback label inside icssg_config_ietfpe() to fix stale state machine handling. - Replace netdev_err with netdev_info and netdev_dbg wherever applicable - Remove EXPORT_SYMBOL_GPL for icssg_config_ietfpe() - Remove redundant code inside icssg_qos_init() - qdisc deletion path clears per-queue map as well. - Protect all read/writes to p_mqprio with a mutex All the above changes address the comments raised by sashiko drivers/net/ethernet/ti/Makefile | 3 +- drivers/net/ethernet/ti/icssg/icssg_common.c | 1 + drivers/net/ethernet/ti/icssg/icssg_config.h | 9 - drivers/net/ethernet/ti/icssg/icssg_prueth.c | 6 + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 2 + drivers/net/ethernet/ti/icssg/icssg_qos.c | 269 +++++++++++++++++++ drivers/net/ethernet/ti/icssg/icssg_qos.h | 66 +++++ 7 files changed, 346 insertions(+), 10 deletions(-) create mode 100644 drivers/net/ethernet/ti/icssg/icssg_qos.c create mode 100644 drivers/net/ethernet/ti/icssg/icssg_qos.h diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Mak= efile index f4276c9a77620..d19bcd25c9d07 100644 --- a/drivers/net/ethernet/ti/Makefile +++ b/drivers/net/ethernet/ti/Makefile @@ -46,6 +46,7 @@ icssg-y :=3D icssg/icssg_common.o \ icssg/icssg_config.o \ icssg/icssg_mii_cfg.o \ icssg/icssg_stats.o \ - icssg/icssg_ethtool.o + icssg/icssg_ethtool.o \ + icssg/icssg_qos.o =20 obj-$(CONFIG_TI_ICSS_IEP) +=3D icssg/icss_iep.o diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/eth= ernet/ti/icssg/icssg_common.c index a28a608f9bf4b..c3ee97e96cd50 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_common.c +++ b/drivers/net/ethernet/ti/icssg/icssg_common.c @@ -1724,6 +1724,7 @@ void prueth_netdev_exit(struct prueth *prueth, =20 netif_napi_del(&emac->napi_rx); =20 + mutex_destroy(&emac->qos.iet.fpe_lock); pruss_release_mem_region(prueth->pruss, &emac->dram); free_netdev(emac->ndev); prueth->emac[mac] =3D NULL; diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/eth= ernet/ti/icssg/icssg_config.h index 60d69744ffae2..1ac202f855ed4 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_config.h +++ b/drivers/net/ethernet/ti/icssg/icssg_config.h @@ -323,13 +323,4 @@ struct prueth_fdb_slot { u8 fid; u8 fid_c2; } __packed; - -enum icssg_ietfpe_verify_states { - ICSSG_IETFPE_STATE_UNKNOWN =3D 0, - ICSSG_IETFPE_STATE_INITIAL, - ICSSG_IETFPE_STATE_VERIFYING, - ICSSG_IETFPE_STATE_SUCCEEDED, - ICSSG_IETFPE_STATE_FAILED, - ICSSG_IETFPE_STATE_DISABLED -}; #endif /* __NET_TI_ICSSG_CONFIG_H */ diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/eth= ernet/ti/icssg/icssg_prueth.c index 591be5c8056b4..39f379df923bf 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c @@ -392,6 +392,8 @@ static void emac_adjust_link(struct net_device *ndev) } else { icssg_set_port_state(emac, ICSSG_EMAC_PORT_DISABLE); } + + icssg_qos_link_state_update(ndev); } =20 if (emac->link) { @@ -1652,6 +1654,7 @@ static const struct net_device_ops emac_netdev_ops = =3D { .ndo_hwtstamp_get =3D icssg_ndo_get_ts_config, .ndo_hwtstamp_set =3D icssg_ndo_set_ts_config, .ndo_xsk_wakeup =3D prueth_xsk_wakeup, + .ndo_setup_tc =3D icssg_qos_ndo_setup_tc, }; =20 static int prueth_netdev_init(struct prueth *prueth, @@ -1686,6 +1689,8 @@ static int prueth_netdev_init(struct prueth *prueth, =20 INIT_DELAYED_WORK(&emac->stats_work, icssg_stats_work_handler); =20 + icssg_qos_init(ndev); + ret =3D pruss_request_mem_region(prueth->pruss, port =3D=3D PRUETH_PORT_MII0 ? PRUSS_MEM_DRAM0 : PRUSS_MEM_DRAM1, @@ -1793,6 +1798,7 @@ static int prueth_netdev_init(struct prueth *prueth, free: pruss_release_mem_region(prueth->pruss, &emac->dram); free_ndev: + mutex_destroy(&emac->qos.iet.fpe_lock); emac->ndev =3D NULL; prueth->emac[mac] =3D NULL; free_netdev(ndev); diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/eth= ernet/ti/icssg/icssg_prueth.h index df93d15c5b786..85f7017d2c8e7 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h @@ -44,6 +44,7 @@ #include "icssg_config.h" #include "icss_iep.h" #include "icssg_switch_map.h" +#include "icssg_qos.h" =20 #define PRUETH_MAX_MTU (2000 - ETH_HLEN - ETH_FCS_LEN) #define PRUETH_MIN_PKT_SIZE (VLAN_ETH_ZLEN) @@ -254,6 +255,7 @@ struct prueth_emac { struct bpf_prog *xdp_prog; struct xdp_attachment_info xdpi; int xsk_qid; + struct prueth_qos qos; }; =20 /* The buf includes headroom compatible with both skb and xdpf */ diff --git a/drivers/net/ethernet/ti/icssg/icssg_qos.c b/drivers/net/ethern= et/ti/icssg/icssg_qos.c new file mode 100644 index 0000000000000..2781abf39e9bb --- /dev/null +++ b/drivers/net/ethernet/ti/icssg/icssg_qos.c @@ -0,0 +1,269 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Texas Instruments ICSSG PRUETH QoS submodule + * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/ + */ + +#include "icssg_prueth.h" +#include "icssg_switch_map.h" + +static void icssg_iet_set_preempt_mask(struct prueth_emac *emac) +{ + void __iomem *config =3D emac->dram.va + ICSSG_CONFIG_OFFSET; + struct prueth_qos_mqprio *p_mqprio =3D &emac->qos.mqprio; + struct tc_mqprio_qopt *qopt =3D &p_mqprio->mqprio.qopt; + struct prueth_qos_iet *iet =3D &emac->qos.iet; + int prempt_mask =3D 0, i; + u8 tc, num_tc; + + if (!iet->preemptible_tcs) + goto reset_hw; + + if (iet->fpe_active) { + /* Configure the queues based on the preemptible tc map set by the user = */ + num_tc =3D p_mqprio->mqprio.qopt.num_tc; + for (tc =3D 0; tc < num_tc; tc++) { + /* check if the tc is preemptive or not */ + if (iet->preemptible_tcs & BIT(tc)) { + for (i =3D qopt->offset[tc]; i < qopt->offset[tc] + qopt->count[tc]; i= ++) { + /* Set all the queues in this tc as preemptive queues */ + writeb(BIT(4), config + EXPRESS_PRE_EMPTIVE_Q_MAP + i); + } + } else { + /* Set all the queues in this tc as express queues */ + for (i =3D qopt->offset[tc]; i < qopt->offset[tc] + qopt->count[tc]; i= ++) { + writeb(0, config + EXPRESS_PRE_EMPTIVE_Q_MAP + i); + prempt_mask |=3D BIT(i); + } + } + netdev_set_tc_queue(emac->ndev, tc, qopt->count[tc], qopt->offset[tc]); + } + writeb(prempt_mask, config + EXPRESS_PRE_EMPTIVE_Q_MASK); + return; + } + +reset_hw: + /* Reset to default: all queues as express */ + for (i =3D 0; i < ICSSG_MAX_TC_QUEUES; i++) + writeb(0, config + EXPRESS_PRE_EMPTIVE_Q_MAP + i); + writeb(ICSSG_EXPRESS_Q_MASK_ALL, config + EXPRESS_PRE_EMPTIVE_Q_MASK); +} + +static int icssg_iet_verify_wait(struct prueth_emac *emac) +{ + void __iomem *config =3D emac->dram.va + ICSSG_CONFIG_OFFSET; + struct prueth_qos_iet *iet =3D &emac->qos.iet; + int try =3D 3; + + do { + msleep(iet->verify_time_ms); + iet->verify_status =3D readb(config + PRE_EMPTION_VERIFY_STATUS); + if (iet->verify_status =3D=3D ICSSG_IETFPE_STATE_SUCCEEDED) + return 0; + } while (--try > 0); + + netdev_err(emac->ndev, "MAC Verify timeout\n"); + return -ETIMEDOUT; +} + +/* Direct synchronous configuration of IET FPE. + * Caller must hold iet->fpe_lock. + */ +int icssg_config_ietfpe(struct net_device *ndev, bool enable) +{ + struct prueth_emac *emac =3D netdev_priv(ndev); + void __iomem *config =3D emac->dram.va + ICSSG_CONFIG_OFFSET; + struct prueth_qos_iet *iet =3D &emac->qos.iet; + int ret; + u8 val; + + lockdep_assert_held(&iet->fpe_lock); + + if (!netif_running(ndev)) { + netdev_dbg(ndev, "cannot change IET/FPE state when interface is down\n"); + return 0; + } + + /* Update FPE Tx enable bit (PRE_EMPTION_ENABLE_TX) if + * fpe_enabled is set to enable MM in Tx direction + */ + writeb(enable ? 1 : 0, config + PRE_EMPTION_ENABLE_TX); + + /* If FPE is to be enabled, first configure MAC Verify state + * machine in firmware as firmware kicks the Verify process + * as soon as ICSSG_EMAC_PORT_PREMPT_TX_ENABLE command is + * received. + */ + if (enable && iet->mac_verify_configure) { + writeb(1, config + PRE_EMPTION_ENABLE_VERIFY); + writew(iet->tx_min_frag_size + ETH_FCS_LEN, + config + PRE_EMPTION_ADD_FRAG_SIZE_LOCAL); + writel(iet->verify_time_ms, config + PRE_EMPTION_VERIFY_TIME); + } else { + writeb(0, config + PRE_EMPTION_ENABLE_VERIFY); + iet->verify_status =3D ICSSG_IETFPE_STATE_DISABLED; + } + + /* Send command to enable FPE Tx side. Rx is always enabled */ + ret =3D icssg_set_port_state(emac, + enable ? ICSSG_EMAC_PORT_PREMPT_TX_ENABLE : + ICSSG_EMAC_PORT_PREMPT_TX_DISABLE); + if (ret) { + netdev_err(ndev, "TX preempt %s command failed\n", + str_enable_disable(enable)); + goto fallback; + } + + if (enable && iet->mac_verify_configure) { + ret =3D icssg_iet_verify_wait(emac); + if (ret) { + netdev_err(ndev, "MAC Verification failed with timeout\n"); + goto disable_tx; + } + } else if (enable) { + /* Give firmware some time to update PRE_EMPTION_ACTIVE_TX state */ + usleep_range(100, 200); + } + + if (enable) { + val =3D readb(config + PRE_EMPTION_ACTIVE_TX); + if (val !=3D 1) { + netdev_err(ndev, + "Firmware fails to activate IET/FPE\n"); + ret =3D -EIO; + goto disable_tx; + } + iet->fpe_active =3D true; + } else { + iet->fpe_active =3D false; + } + + icssg_iet_set_preempt_mask(emac); + netdev_info(ndev, "IET FPE %s successfully\n", + str_enable_disable(iet->fpe_active)); + return ret; + +disable_tx: + icssg_set_port_state(emac, ICSSG_EMAC_PORT_PREMPT_TX_DISABLE); +fallback: + writeb(0, config + PRE_EMPTION_ENABLE_TX); + writeb(0, config + PRE_EMPTION_ENABLE_VERIFY); + iet->verify_status =3D ICSSG_IETFPE_STATE_DISABLED; + iet->fpe_active =3D false; + return ret; +} + +void icssg_qos_init(struct net_device *ndev) +{ + struct prueth_emac *emac =3D netdev_priv(ndev); + struct prueth_qos_iet *iet =3D &emac->qos.iet; + + mutex_init(&iet->fpe_lock); + /* Set default values to prevent garbage values during .get_mm() */ + mutex_lock(&iet->fpe_lock); + iet->verify_time_ms =3D ICSSG_IET_MAX_VERIFY_TIME; + iet->tx_min_frag_size =3D ETH_ZLEN; + mutex_unlock(&iet->fpe_lock); +} +EXPORT_SYMBOL_GPL(icssg_qos_init); + +static int icssg_iet_change_preemptible_tcs(struct prueth_emac *emac) +{ + struct prueth_qos_iet *iet =3D &emac->qos.iet; + int ret; + + mutex_lock(&iet->fpe_lock); + ret =3D icssg_config_ietfpe(emac->ndev, iet->fpe_enabled); + mutex_unlock(&iet->fpe_lock); + + return ret; +} + +static int emac_tc_query_caps(struct net_device *ndev, void *type_data) +{ + struct tc_query_caps_base *base =3D type_data; + + switch (base->type) { + case TC_SETUP_QDISC_MQPRIO: { + struct tc_mqprio_caps *caps =3D base->caps; + + caps->validate_queue_counts =3D true; + return 0; + } + default: + return -EOPNOTSUPP; + } +} + +static int emac_tc_setup_mqprio(struct net_device *ndev, void *type_data) +{ + struct prueth_emac *emac =3D netdev_priv(ndev); + struct prueth_qos_mqprio *p_mqprio =3D &emac->qos.mqprio; + struct tc_mqprio_qopt_offload *mqprio =3D type_data; + struct prueth_qos_iet *iet =3D &emac->qos.iet; + int ret; + + /* Validate parameters */ + if (mqprio->qopt.num_tc > ICSSG_MAX_TC_QUEUES) { + netdev_err(ndev, "Number of traffic classes (%u) exceeds hardware limit\= n", + mqprio->qopt.num_tc); + return -EINVAL; + } + + if (mqprio->flags & TC_MQPRIO_F_SHAPER) { + netdev_err(ndev, "traffic shaping is not supported\n"); + return -EINVAL; + } + + if (mqprio->flags & (TC_MQPRIO_F_MIN_RATE | TC_MQPRIO_F_MAX_RATE)) { + netdev_err(ndev, "per-queue rate limiting is not supported\n"); + return -EINVAL; + } + + if (!mqprio->qopt.num_tc) { + netdev_reset_tc(ndev); + } else { + netdev_set_num_tc(ndev, mqprio->qopt.num_tc); + } + + mutex_lock(&iet->fpe_lock); + if (!mqprio->qopt.num_tc) { + iet->preemptible_tcs =3D 0; + } else { + memcpy(&p_mqprio->mqprio, mqprio, sizeof(*mqprio)); + iet->preemptible_tcs =3D mqprio->preemptible_tcs; + } + mutex_unlock(&iet->fpe_lock); + + netdev_dbg(ndev, "dev->num_tc %u dev->real_num_tx_queues %u\n", + ndev->num_tc, ndev->real_num_tx_queues); + + ret =3D icssg_iet_change_preemptible_tcs(emac); + return ret; +} + +int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type typ= e, + void *type_data) +{ + switch (type) { + case TC_QUERY_CAPS: + return emac_tc_query_caps(ndev, type_data); + case TC_SETUP_QDISC_MQPRIO: + return emac_tc_setup_mqprio(ndev, type_data); + default: + return -EOPNOTSUPP; + } +} +EXPORT_SYMBOL_GPL(icssg_qos_ndo_setup_tc); + +void icssg_qos_link_state_update(struct net_device *ndev) +{ + struct prueth_emac *emac =3D netdev_priv(ndev); + struct prueth_qos_iet *iet =3D &emac->qos.iet; + int ret; + + ret =3D icssg_iet_change_preemptible_tcs(emac); + if (ret) + netdev_dbg(ndev, "IET FPE %s failed\n", + str_enable_disable(iet->fpe_active)); +} +EXPORT_SYMBOL_GPL(icssg_qos_link_state_update); diff --git a/drivers/net/ethernet/ti/icssg/icssg_qos.h b/drivers/net/ethern= et/ti/icssg/icssg_qos.h new file mode 100644 index 0000000000000..9355e96bbcda8 --- /dev/null +++ b/drivers/net/ethernet/ti/icssg/icssg_qos.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/ + */ + +#ifndef __NET_TI_ICSSG_QOS_H +#define __NET_TI_ICSSG_QOS_H + +#include +#include +#include + +#define ICSSG_MAX_TC_QUEUES 8 +#define ICSSG_EXPRESS_Q_MASK_ALL 0xFF +#define ICSSG_IET_MAX_VERIFY_TIME 128 +#define ICSSG_IET_MIN_VERIFY_TIME 1 + +/** + * enum icssg_ietfpe_verify_states - status of MAC Merge Verify returned b= y firmware + * @ICSSG_IETFPE_STATE_UNKNOWN: + * verification status is unknown + * @ICSSG_IETFPE_STATE_INITIAL: + * Firmware returns this if verify state diagram is idle + * @ICSSG_IETFPE_STATE_VERIFYING: + * Firmware returns this if verification is ongoing + * @ICSSG_IETFPE_STATE_SUCCEEDED: + * Firmware returns this if verify state diagram completes verification + * @ICSSG_IETFPE_STATE_FAILED: + * Firmware returns this if verify state diagram fails during verification + * @ICSSG_IETFPE_STATE_DISABLED: + * verification is disabled by the driver + */ +enum icssg_ietfpe_verify_states { + ICSSG_IETFPE_STATE_UNKNOWN =3D 0, + ICSSG_IETFPE_STATE_INITIAL, + ICSSG_IETFPE_STATE_VERIFYING, + ICSSG_IETFPE_STATE_SUCCEEDED, + ICSSG_IETFPE_STATE_FAILED, + ICSSG_IETFPE_STATE_DISABLED +}; + +struct prueth_qos_mqprio { + struct tc_mqprio_qopt_offload mqprio; +}; + +struct prueth_qos_iet { + bool fpe_enabled; + bool mac_verify_configure; + u32 tx_min_frag_size; + u32 verify_time_ms; + bool fpe_active; + enum icssg_ietfpe_verify_states verify_status; + struct mutex fpe_lock; + u8 preemptible_tcs; +}; + +struct prueth_qos { + struct prueth_qos_iet iet; + struct prueth_qos_mqprio mqprio; +}; + +void icssg_qos_init(struct net_device *ndev); +void icssg_qos_link_state_update(struct net_device *ndev); +int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type typ= e, + void *type_data); +int icssg_config_ietfpe(struct net_device *ndev, bool enable); +#endif /* __NET_TI_ICSSG_QOS_H */ --=20 2.43.0 From nobody Mon Jun 8 22:55:05 2026 Received: from CY3PR05CU001.outbound.protection.outlook.com (mail-westcentralusazon11013017.outbound.protection.outlook.com [40.93.201.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 735B636405E; Mon, 25 May 2026 18:27:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.201.17 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779733652; cv=fail; b=Ug09c2N+mZqMuWB+LJDirjfNfE3u2o7ucMpb/YH0QNNeaDYalofhm+arfdAi7XOKbVwPlt7jpotDAOCjtWwKkQYCG4x5lO385Ck7X4zGjOyV+fGTUq3khC9Kfrvb/zU0nT4shrMlrTRi8hdF8IpyMbFIlQln3olIOYvJaU7s3Ks= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779733652; c=relaxed/simple; bh=wlTrwHDFqCUgyowSe8kc5GXoKzHP/5nWaPTeHnf3MGQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=BOtiaH6KUeKL3JL7hDuEGcXx0wdhHPdvTWJwuN1gzTEAlX34nNI27DqG31O4JaPq/oDwp1i7FBA/zjOnpssI5+kqumvDVHBrb/c0gubR1NmClKFRiasikVYI1JnUg0xHODTicfkSz4/iIxf1uYQPiqOnLkOuBS44H/hsa5ZET4o= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=cqjTU19q; arc=fail smtp.client-ip=40.93.201.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="cqjTU19q" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=St+MmFN+Ib71eVu35eULjfXjv4eJXWevQ9hY6l+HkRvA/u6K64N5XZWHYsNX0aoMFVwen3CVmsSACtL+2EW1xzVGt3HN3pAtjxSoATehoBN0gRMPpniY9SVo7YGe6WkTKPyT/bLiybOC43Djm/w8xfwCnJPBIKag40NPPto33xpZrSFMd5Z+5o7BoPyy8zhh9yXsCU4+Wsf+l3BdpIL0WiRLX4zvkp9xwcsok3f7Me70EFsPcW0EcFy0I5SvVKf33ShO4kGfbkZ4kSbfbJxvRrsgjV5bjHL7tBrhsbwmb3MW1LfRWdKyxd+CgnYcKsadvptHQoD7gpBrR/7EMBlypw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ggDon9qhm+f3Y1UrHWAvMI0aSJXoQZDqyBTp4UYKinM=; b=hkVTTRv8KDR49f1RIhT6t8D+k6SFUlBfZMAmCxNODqW8Rw38PfTfqk9g/bIDrrKJQ6mIjEx72QcbdDEXgyer5z9dyJMoLtaAr0nbfIGmhUsIwvCfIlHMUwW+QJhvowgWGFmIap7W8iZsbQkgMmu/Klo5iljgk3A89C2jFqG/pgKtjdIFLOwCclBR5jBsdT7CDyvGd7m1pBvWCdIaEHMh2s26iBFc1xLx/ZGEK1lD7tE/Q1kH9mZc4YZ+pHGQQ0ljuZboSS99vG+7EgKdviscN/nTncRiPsX9oh2ZpxTzLjKVNSdFo213dv1kOXlJEHMa+m/jowEDMHDuO0AuK+JinQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 198.47.21.195) smtp.rcpttodomain=gmail.com smtp.mailfrom=ti.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=ti.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ggDon9qhm+f3Y1UrHWAvMI0aSJXoQZDqyBTp4UYKinM=; b=cqjTU19qV/zrLZ7DXlhYyAyzI883rrPv/dQaENp/74MQENy5uPCbQfkqdC8/N/eSs9uQL9Gb01z2Hh6uxXYyHwpQQmNHIAHt2CrEHFGUZYlfS5Mp9saW/oVBrRiifYZYrCjx5Y+58uaESOOw6eKdOhfqVTUYKFQwMAiL6klbIfw= Received: from MW4PR03CA0094.namprd03.prod.outlook.com (2603:10b6:303:b7::9) by IA1PR10MB5969.namprd10.prod.outlook.com (2603:10b6:208:3ef::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.48.19; Mon, 25 May 2026 18:27:17 +0000 Received: from MWH0EPF000A6734.namprd04.prod.outlook.com (2603:10b6:303:b7:cafe::3e) by MW4PR03CA0094.outlook.office365.com (2603:10b6:303:b7::9) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.48.20 via Frontend Transport; Mon, 25 May 2026 18:27:16 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 198.47.21.195) smtp.mailfrom=ti.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=ti.com; Received-SPF: Pass (protection.outlook.com: domain of ti.com designates 198.47.21.195 as permitted sender) receiver=protection.outlook.com; client-ip=198.47.21.195; helo=flwvzet201.ext.ti.com; pr=C Received: from flwvzet201.ext.ti.com (198.47.21.195) by MWH0EPF000A6734.mail.protection.outlook.com (10.167.249.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.71.7 via Frontend Transport; Mon, 25 May 2026 18:27:15 +0000 Received: from DFLE214.ent.ti.com (10.64.6.72) by flwvzet201.ext.ti.com (10.248.192.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.37; Mon, 25 May 2026 13:27:15 -0500 Received: from DFLE205.ent.ti.com (10.64.6.63) by DFLE214.ent.ti.com (10.64.6.72) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.37; Mon, 25 May 2026 13:27:12 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) by DFLE205.ent.ti.com (10.64.6.63) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.37 via Frontend Transport; Mon, 25 May 2026 13:27:12 -0500 Received: from lelv0854.itg.ti.com (lelv0854.itg.ti.com [10.181.64.140]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 64PIRCTC4056334; Mon, 25 May 2026 13:27:12 -0500 Received: from localhost (meghana-pc.dhcp.ti.com [10.24.69.13] (may be forged)) by lelv0854.itg.ti.com (8.14.7/8.14.7) with ESMTP id 64PIRBCl018239; Mon, 25 May 2026 13:27:12 -0500 From: Meghana Malladi To: , , , , , , , , , , , , , , , , , , , CC: , , , , Vignesh Raghavendra Subject: [PATCH net-next v6 2/2] net: ti: icssg-prueth: Add ethtool ops for Frame Preemption MAC Merge Date: Mon, 25 May 2026 23:57:00 +0530 Message-ID: <20260525182700.3135858-3-m-malladi@ti.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260525182700.3135858-1-m-malladi@ti.com> References: <20260525182700.3135858-1-m-malladi@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MWH0EPF000A6734:EE_|IA1PR10MB5969:EE_ X-MS-Office365-Filtering-Correlation-Id: 216472cb-5c1e-426c-33c0-08deba8b3f50 X-LD-Processed: e5b49634-450b-4709-8abb-1e2b19b982b7,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700016|82310400026|7416014|376014|921020|56012099003|22082099003|18002099003|6133799003|3023799007; X-Microsoft-Antispam-Message-Info: zWdMpNiWNxj9CQwk+aUIPXmL4VjLnIey190/cFvSPVKx+JZkge0MEEWsR5lMybHLDLyq9r9ZTQ6GF/6Od4YuLMdUh9m/xPb75epYtgCLNn6AB77BnQM+RZY9NK4tAG5FvfYt/XaGhAoSW2r1O6OzrESyLWCYXDd0O2mUyBAN+nQ/M4vokaPJV6CnLEth3Xl4WYilCR7LEVPlVabsSS59JSNCjmopSUuPS6onUKZ2AZhs2JG8q9DetHeFEzjV+rpnbQ8Movp1mJPpivRw7V5jRc/zBVLDL7ASNmxtAit/B2r+FTChBiMaU2Xu3Mt9crOoURM5VLzR4D/ziUrGpp+GjoqLTIaMP0LUrJwG8ZUuIxlUZIg63fHYWIjgyEOAPSM1CgW2iMZESXZhCLhH3pS0t7Xw5hqBZtBgHzJUtKoL1wMJtgNe4TJEPTPzBwOHR+GjQdRZxnpcQ2LFkJcogtmZM+Ao+AOb0qvGdlPkTbtyXnEM7Y4/mHYA/ibvA08y6alcZn8eyl540oBuAvz5UF5g9PKL2FCvANIwC4asoUTvsVFYwC5wU6J465u7/7LoE0qkW/yUXhK0ggm2oFoSCwt3sTkQdtmefOsmtRFFzhrrmGv4oA0AmtwZ4tbZzQChbWUcRaAB1eDKHMmVLX7dXRrPgVrfpp3x1W157QF0mNmPEFnvFOjpAtgWB/CA+ZJxJIO4omUT8+ANjizCkxK736lDNtqBsBRr9mb3KjMSI2j1peabWc6XQa5etjeiGdkey2PpSDavYYQ4JBpdQUSi0BLZLA== X-Forefront-Antispam-Report: CIP:198.47.21.195;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:flwvzet201.ext.ti.com;PTR:ErrorRetry;CAT:NONE;SFS:(13230040)(1800799024)(36860700016)(82310400026)(7416014)(376014)(921020)(56012099003)(22082099003)(18002099003)(6133799003)(3023799007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: dvd0qXkXgJLC/qdhD3cq/ckIOLUpvd110h4nIeeRgq00ZR+aKOOH17HlV0DffDQWuqRVozQG+VXu5BpgVmpbY66Nteyn9Qa+D38GWAyCOSyhvAXF4j298HOfj6qC4Yu1A5LYM6qKomsklw/x9pW7ytYl3vlABNfX7ZuPdiIXjXmD4pHh4Fg/0MV1QP/CUXGv92Qr7lNtjh3G2S+Nd1I6l/FmS2YLXqO5x0oavpU1TJCHrD+ZMFDYeSjOm2RInVgMxcPnqtaMF+avrwGz5mNzoBg5UxB0slZUQOeRBtpBokrYTKuk/1GUMLs15uEvwKfxC6UixlUbX0o4ar+Qxfw7b6fv67P725c4a+LL6Sb2vcdhxOR2stpLQiSyXOCsP4ylXtY2dfqkcHPVEWeLyWW/CAzOmd67xauqEUFRv2blWdYg7IPlNf56uMoryAIOQ3kD X-OriginatorOrg: ti.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 May 2026 18:27:15.7314 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 216472cb-5c1e-426c-33c0-08deba8b3f50 X-MS-Exchange-CrossTenant-Id: e5b49634-450b-4709-8abb-1e2b19b982b7 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=e5b49634-450b-4709-8abb-1e2b19b982b7;Ip=[198.47.21.195];Helo=[flwvzet201.ext.ti.com] X-MS-Exchange-CrossTenant-AuthSource: MWH0EPF000A6734.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR10MB5969 Content-Type: text/plain; charset="utf-8" From: MD Danish Anwar Add driver support for viewing and changing the MAC Merge sublayer parameters via ethtool ops: .set_mm(), .get_mm() and .get_mm_stats(). The minimum size of non-final mPacket fragments supported by the firmware without leading errors is 64 Bytes (including FCS). Verify time bounded to 1-128 ms per 802.3-2018 clause 30.14.1.6. Add a check to ensure user passed tx_min_frag_size argument via ethtool, honors this. Add pa stats registers to check statistics for preemption, which can be dumped using ethtool ops. Fix emac_get_stat_by_name() to return u64 instead of int and return 0 on error instead of -EINVAL. This prevents invalid stat lookups from corrupting output stats with signed error codes cast to u64. Error conditions are still logged via netdev_err(). Signed-off-by: MD Danish Anwar Signed-off-by: Meghana Malladi --- v6-v5: - Initialize tx_min_frag_size and verify_time with valid values to avoid returning corrupted values during get_mm() - Fix rx_min_frag_size to ETH_ZLEN excluding ETH_FCS_LEN - Fix return codes for emac_set_mm() All the above changes address the comments raised by sashiko drivers/net/ethernet/ti/icssg/icssg_ethtool.c | 106 ++++++++++++++++++ drivers/net/ethernet/ti/icssg/icssg_prueth.h | 7 +- drivers/net/ethernet/ti/icssg/icssg_qos.h | 46 ++++++++ drivers/net/ethernet/ti/icssg/icssg_stats.c | 4 +- drivers/net/ethernet/ti/icssg/icssg_stats.h | 7 +- .../net/ethernet/ti/icssg/icssg_switch_map.h | 5 + 6 files changed, 168 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c b/drivers/net/et= hernet/ti/icssg/icssg_ethtool.c index b715af21d23ac..ee940051644d6 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c +++ b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c @@ -294,6 +294,109 @@ static int emac_set_per_queue_coalesce(struct net_dev= ice *ndev, u32 queue, return 0; } =20 +static int emac_get_mm(struct net_device *ndev, struct ethtool_mm_state *s= tate) +{ + struct prueth_emac *emac =3D netdev_priv(ndev); + struct prueth_qos_iet *iet =3D &emac->qos.iet; + enum icssg_ietfpe_verify_states verify_status; + + if (emac->is_sr1) + return -EOPNOTSUPP; + + mutex_lock(&iet->fpe_lock); + state->tx_enabled =3D iet->fpe_enabled; + state->tx_min_frag_size =3D iet->tx_min_frag_size; + state->tx_active =3D iet->fpe_active; + state->verify_enabled =3D iet->mac_verify_configure; + state->verify_time =3D iet->verify_time_ms; + verify_status =3D iet->verify_status; + mutex_unlock(&iet->fpe_lock); + + state->rx_min_frag_size =3D ETH_ZLEN; + state->pmac_enabled =3D true; + + switch (verify_status) { + case ICSSG_IETFPE_STATE_DISABLED: + state->verify_status =3D ETHTOOL_MM_VERIFY_STATUS_DISABLED; + break; + case ICSSG_IETFPE_STATE_INITIAL: + state->verify_status =3D ETHTOOL_MM_VERIFY_STATUS_INITIAL; + break; + case ICSSG_IETFPE_STATE_VERIFYING: + state->verify_status =3D ETHTOOL_MM_VERIFY_STATUS_VERIFYING; + break; + case ICSSG_IETFPE_STATE_SUCCEEDED: + state->verify_status =3D ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED; + break; + case ICSSG_IETFPE_STATE_FAILED: + state->verify_status =3D ETHTOOL_MM_VERIFY_STATUS_FAILED; + break; + default: + state->verify_status =3D ETHTOOL_MM_VERIFY_STATUS_UNKNOWN; + break; + } + + /* 802.3-2018 clause 30.14.1.6, says that the aMACMergeVerifyTime + * variable has a range between 1 and 128 ms inclusive. Limit to that. + */ + state->max_verify_time =3D ETHTOOL_MM_MAX_VERIFY_TIME_MS; + + return 0; +} + +static int emac_set_mm(struct net_device *ndev, struct ethtool_mm_cfg *cfg, + struct netlink_ext_ack *extack) +{ + struct prueth_emac *emac =3D netdev_priv(ndev); + struct prueth_qos_iet *iet =3D &emac->qos.iet; + int err; + + if (emac->is_sr1) + return -EOPNOTSUPP; + + if (!cfg->pmac_enabled) { + NL_SET_ERR_MSG_MOD(extack, "preemptible MAC is always enabled"); + return -EOPNOTSUPP; + } + + err =3D icssg_qos_validate_tx_min_frag_size(cfg->tx_min_frag_size, extack= ); + if (err) + return err; + + err =3D icssg_qos_validate_verify_time(cfg->verify_time, extack); + if (err) + return err; + + mutex_lock(&iet->fpe_lock); + iet->verify_time_ms =3D cfg->verify_time; + iet->tx_min_frag_size =3D cfg->tx_min_frag_size; + iet->fpe_enabled =3D cfg->tx_enabled; + iet->mac_verify_configure =3D cfg->verify_enabled; + err =3D icssg_config_ietfpe(ndev, cfg->tx_enabled); + mutex_unlock(&iet->fpe_lock); + + return err; +} + +static void emac_get_mm_stats(struct net_device *ndev, + struct ethtool_mm_stats *s) +{ + struct prueth_emac *emac =3D netdev_priv(ndev); + + if (emac->is_sr1) + return; + + if (!emac->prueth->pa_stats) + return; + + /* MACMergeHoldCount stats is not tracked by the firmware */ + s->MACMergeFrameAssOkCount =3D emac_get_stat_by_name(emac, "FW_PREEMPT_AS= SEMBLY_OK"); + s->MACMergeFrameAssErrorCount =3D emac_get_stat_by_name(emac, "FW_PREEMPT= _ASSEMBLY_ERR"); + s->MACMergeFragCountRx =3D emac_get_stat_by_name(emac, "FW_PREEMPT_FRAG_C= NT_RX"); + s->MACMergeFragCountTx =3D emac_get_stat_by_name(emac, "FW_PREEMPT_FRAG_C= NT_TX"); + s->MACMergeFrameSmdErrorCount =3D emac_get_stat_by_name(emac, "FW_PREEMPT= _BAD_FRAG"); +} + const struct ethtool_ops icssg_ethtool_ops =3D { .get_drvinfo =3D emac_get_drvinfo, .get_msglevel =3D emac_get_msglevel, @@ -317,5 +420,8 @@ const struct ethtool_ops icssg_ethtool_ops =3D { .set_eee =3D emac_set_eee, .nway_reset =3D emac_nway_reset, .get_rmon_stats =3D emac_get_rmon_stats, + .get_mm =3D emac_get_mm, + .set_mm =3D emac_set_mm, + .get_mm_stats =3D emac_get_mm_stats, }; EXPORT_SYMBOL_GPL(icssg_ethtool_ops); diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/eth= ernet/ti/icssg/icssg_prueth.h index 85f7017d2c8e7..61320c252bec2 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h @@ -45,6 +45,7 @@ #include "icss_iep.h" #include "icssg_switch_map.h" #include "icssg_qos.h" +#include "icssg_stats.h" =20 #define PRUETH_MAX_MTU (2000 - ETH_HLEN - ETH_FCS_LEN) #define PRUETH_MIN_PKT_SIZE (VLAN_ETH_ZLEN) @@ -58,8 +59,8 @@ =20 #define ICSSG_MAX_RFLOWS 8 /* per slice */ =20 -#define ICSSG_NUM_PA_STATS 32 -#define ICSSG_NUM_MIIG_STATS 60 +#define ICSSG_NUM_PA_STATS ARRAY_SIZE(icssg_all_pa_stats) +#define ICSSG_NUM_MIIG_STATS ARRAY_SIZE(icssg_all_miig_stats) /* Number of ICSSG related stats */ #define ICSSG_NUM_STATS (ICSSG_NUM_MIIG_STATS + ICSSG_NUM_PA_STATS) #define ICSSG_NUM_STANDARD_STATS 31 @@ -460,7 +461,7 @@ int emac_fdb_flow_id_updated(struct prueth_emac *emac); =20 void icssg_stats_work_handler(struct work_struct *work); void emac_update_hardware_stats(struct prueth_emac *emac); -int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name); +u64 emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name); =20 /* Common functions */ void prueth_cleanup_rx_chns(struct prueth_emac *emac, diff --git a/drivers/net/ethernet/ti/icssg/icssg_qos.h b/drivers/net/ethern= et/ti/icssg/icssg_qos.h index 9355e96bbcda8..87ca031afcaa4 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_qos.h +++ b/drivers/net/ethernet/ti/icssg/icssg_qos.h @@ -13,6 +13,7 @@ #define ICSSG_EXPRESS_Q_MASK_ALL 0xFF #define ICSSG_IET_MAX_VERIFY_TIME 128 #define ICSSG_IET_MIN_VERIFY_TIME 1 +#define ICSSG_IET_MAX_TX_MIN_FRAG_SIZE 252 =20 /** * enum icssg_ietfpe_verify_states - status of MAC Merge Verify returned b= y firmware @@ -63,4 +64,49 @@ void icssg_qos_link_state_update(struct net_device *ndev= ); int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type typ= e, void *type_data); int icssg_config_ietfpe(struct net_device *ndev, bool enable); +static inline int icssg_qos_validate_tx_min_frag_size(u32 min_frag_size, + struct netlink_ext_ack *extack) +{ + /* Firmware takes min_frag_size including FCS length. + * The firmware requires the fragment size (including FCS) to be + * a multiple of 64 bytes. Since 64 bytes =3D ETH_ZLEN + ETH_FCS_LEN, + * valid user-facing values are: 60, 124, 188, 252. + */ + + if (min_frag_size < ETH_ZLEN) { + NL_SET_ERR_MSG_MOD(extack, + "tx_min_frag_size must be at least 60 bytes"); + return -EINVAL; + } + + if (min_frag_size > ICSSG_IET_MAX_TX_MIN_FRAG_SIZE) { + NL_SET_ERR_MSG_MOD(extack, + "tx_min_frag_size must not exceed 252 bytes"); + return -EINVAL; + } + + if ((min_frag_size + ETH_FCS_LEN) % (ETH_ZLEN + ETH_FCS_LEN)) { + NL_SET_ERR_MSG_MOD(extack, + "tx_min_frag_size must be a multiple of 64 bytes minus 4"); + return -EINVAL; + } + + return 0; +} + +static inline int icssg_qos_validate_verify_time(u32 verify_time_ms, + struct netlink_ext_ack *extack) +{ + /* 802.3-2018 clause 30.14.1.6: aMACMergeVerifyTime must be + * between 1 and 128 ms inclusive + */ + if (verify_time_ms < ICSSG_IET_MIN_VERIFY_TIME || + verify_time_ms > ICSSG_IET_MAX_VERIFY_TIME) { + NL_SET_ERR_MSG_MOD(extack, + "verify_time must be between 1 and 128 ms"); + return -EINVAL; + } + + return 0; +} #endif /* __NET_TI_ICSSG_QOS_H */ diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.c b/drivers/net/ethe= rnet/ti/icssg/icssg_stats.c index 7159baa0155cf..cfdb6f5dc5da1 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_stats.c +++ b/drivers/net/ethernet/ti/icssg/icssg_stats.c @@ -74,7 +74,7 @@ void icssg_stats_work_handler(struct work_struct *work) } EXPORT_SYMBOL_GPL(icssg_stats_work_handler); =20 -int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name) +u64 emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name) { int i; =20 @@ -91,5 +91,5 @@ int emac_get_stat_by_name(struct prueth_emac *emac, char = *stat_name) } =20 netdev_err(emac->ndev, "Invalid stats %s\n", stat_name); - return -EINVAL; + return 0; } diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.h b/drivers/net/ethe= rnet/ti/icssg/icssg_stats.h index 5ec0b38e0c67d..8073deac35c3e 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_stats.h +++ b/drivers/net/ethernet/ti/icssg/icssg_stats.h @@ -8,8 +8,6 @@ #ifndef __NET_TI_ICSSG_STATS_H #define __NET_TI_ICSSG_STATS_H =20 -#include "icssg_prueth.h" - #define STATS_TIME_LIMIT_1G_MS 25000 /* 25 seconds @ 1G */ =20 struct miig_stats_regs { @@ -189,6 +187,11 @@ static const struct icssg_pa_stats icssg_all_pa_stats[= ] =3D { ICSSG_PA_STATS(FW_INF_DROP_PRIOTAGGED), ICSSG_PA_STATS(FW_INF_DROP_NOTAG), ICSSG_PA_STATS(FW_INF_DROP_NOTMEMBER), + ICSSG_PA_STATS(FW_PREEMPT_BAD_FRAG), + ICSSG_PA_STATS(FW_PREEMPT_ASSEMBLY_ERR), + ICSSG_PA_STATS(FW_PREEMPT_FRAG_CNT_TX), + ICSSG_PA_STATS(FW_PREEMPT_ASSEMBLY_OK), + ICSSG_PA_STATS(FW_PREEMPT_FRAG_CNT_RX), ICSSG_PA_STATS(FW_RX_EOF_SHORT_FRMERR), ICSSG_PA_STATS(FW_RX_B0_DROP_EARLY_EOF), ICSSG_PA_STATS(FW_TX_JUMBO_FRM_CUTOFF), diff --git a/drivers/net/ethernet/ti/icssg/icssg_switch_map.h b/drivers/net= /ethernet/ti/icssg/icssg_switch_map.h index 7e053b8af3ece..855fd4ed0b3f6 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_switch_map.h +++ b/drivers/net/ethernet/ti/icssg/icssg_switch_map.h @@ -256,6 +256,11 @@ #define FW_INF_DROP_PRIOTAGGED 0x0148 #define FW_INF_DROP_NOTAG 0x0150 #define FW_INF_DROP_NOTMEMBER 0x0158 +#define FW_PREEMPT_BAD_FRAG 0x0160 +#define FW_PREEMPT_ASSEMBLY_ERR 0x0168 +#define FW_PREEMPT_FRAG_CNT_TX 0x0170 +#define FW_PREEMPT_ASSEMBLY_OK 0x0178 +#define FW_PREEMPT_FRAG_CNT_RX 0x0180 #define FW_RX_EOF_SHORT_FRMERR 0x0188 #define FW_RX_B0_DROP_EARLY_EOF 0x0190 #define FW_TX_JUMBO_FRM_CUTOFF 0x0198 --=20 2.43.0