From nobody Sun Feb 8 19:03:52 2026 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (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 C87072BDC04; Fri, 9 Jan 2026 10:31:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954693; cv=none; b=SbP35pGAQEegIJLrMkIlsHAECI+rJqTLDmHGZGJWeQXpucM4f1DvB9FEMHz5nRhwZBnhQYv8bMgyhjNtg5QMa5NbAsSJtZ/Y0u1sYzXK/11OGK3sDmPvh/vy3JjM5EHd5PvIlgVeA+PzwQHunvDV7DoYkd1t01KznVFhMpru3ss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954693; c=relaxed/simple; bh=4F1HAeTIF9KKxPlBfJaEEba2PxPnyPA7cGWluqW378k=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=L5Tv6Q93xm2TNmm9/OyfJJWeVkaQBJFPdNV8JvTB/oC946rmkcqNvv3ltz3QgQJhmQRBtDdnGENjZWKuOy3PufXAo3h/UJoeYtuhkCZki9sR2TlIRk+XPDYO4dbzPeMRdkrzSLkoVRfGXrLuVmyR47UyU2WHUWINV4+cR2tpDtg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=B8sJEaI2; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="B8sJEaI2" Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6092nsZ12937915; Fri, 9 Jan 2026 02:31:23 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=f kXB6NHiV2CjZHLpi/iCgwN3hmywDgLtJ4yIubRYiPM=; b=B8sJEaI2MuD5NH6aU OCrEbIGSodW5hHCYocLtZantm/nZFUP7suSbjwJviSLTE1ucsxdfA/E1Z2KF2Rq4 jI4AL34H++fi+FKXL17wgHa9d0b2sPaMeJm8m8XxkfGMNexVfyd0SFonhS4hiZL3 0YrZ91VKw24mM/xRQjyNucjN7eXu0omtSkEW8h1oQuw/qfsfUkf3DBhoK/26MVef Z9ae5X6zehBUHHjaqN6ebzCyCkSmknPib9KYOIY3pM9VGoYacxq3OCkOcB/ACbv1 Z1ZiaSmjbo8geBESYDKUpSasn6MTkkkvWU7KcFvIEbkQWGRW0o9DC+7aETGDs/KY qoAKw== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4bhwh2vmv3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 09 Jan 2026 02:31:23 -0800 (PST) Received: from DC5-EXCH05.marvell.com (10.69.176.209) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Fri, 9 Jan 2026 02:31:37 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Fri, 9 Jan 2026 02:31:37 -0800 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id E62E45B6935; Fri, 9 Jan 2026 02:31:19 -0800 (PST) From: Ratheesh Kannoth To: , CC: , , , , , , "Ratheesh Kannoth" Subject: [PATCH net-next v3 01/10] octeontx2-af: switch: Add AF to switch mbox and skeleton files Date: Fri, 9 Jan 2026 16:00:26 +0530 Message-ID: <20260109103035.2972893-2-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109103035.2972893-1-rkannoth@marvell.com> References: <20260109103035.2972893-1-rkannoth@marvell.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-Proofpoint-GUID: l3Y7z8cf9GiADheonHcfaeoPoSYtS_lu X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA5MDA3NiBTYWx0ZWRfXzm9J9A0mHbPB 1+exgw/F99F6yGiEIuByO3FsBQJqlnUxqY0nLzYk7dDZeDdriC2ETn1sdusOKMyYTGv4rV2IQTm Tx9fSFHN/OG+FOVoy98ft+yZhEorWdzkr7yBFdMPwOxT3YyRTX29fHEHbIBx/Y2adkArVPoPFMa YWzQq5qZRdrYp4eq1VlikYDDfvs2mBQnBIYthnbK6WViRSRJwtshVsboxr6fK5d1KozCKck4ye3 FM9InmLLllhkgv/eYZMutwPF8gl2n/or3KEqHwSrkfYDCduljMK1zH8KgL7qdYMCYVNbXTPj72L nzBFOn68ocbI1uiHtUdFRbfNb9fGXpz44PFWdVohbL9yNSrpFci9YqHsN8ONQDagaU2REdqIOH1 jXyQI/U0hre+Y1rut8lKUVimNUf+ed0c/VLIvDlthY4z/0QKQeet7mzgXSWppyel8m1zv3yvIow 8tqsCQ19/DMEFXSHuwQ== X-Authority-Analysis: v=2.4 cv=ROO+3oi+ c=1 sm=1 tr=0 ts=6960d8fb cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=vUbySO9Y5rIA:10 a=VkNPw1HP01LnGYTKEx00:22 a=M5GUcnROAAAA:8 a=Z4O4Qt9-gMa089bn5iwA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-ORIG-GUID: l3Y7z8cf9GiADheonHcfaeoPoSYtS_lu X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-09_03,2026-01-08_02,2025-10-01_01 Content-Type: text/plain; charset="utf-8" The Marvell switch hardware runs on a Linux OS. This OS receives various messages, which are parsed to create flow rules that can be installed on HW. The switch is capable of accelerating both L2 and L3 flows. This commit adds various mailbox messages used by the Linux OS (on arm64) to send events to the switch hardware. fdb messages: Linux bridge FDB messages fib messages: Linux routing table messages status messages: Packet status updates sent to Host Linux to keep flows active for connection-tracked flows. Signed-off-by: Ratheesh Kannoth --- .../ethernet/marvell/octeontx2/af/Makefile | 3 +- .../net/ethernet/marvell/octeontx2/af/mbox.h | 95 +++++++++++++++++++ .../marvell/octeontx2/af/switch/rvu_sw_fl.c | 21 ++++ .../marvell/octeontx2/af/switch/rvu_sw_fl.h | 11 +++ .../marvell/octeontx2/af/switch/rvu_sw_l2.c | 14 +++ .../marvell/octeontx2/af/switch/rvu_sw_l2.h | 11 +++ .../marvell/octeontx2/af/switch/rvu_sw_l3.c | 14 +++ .../marvell/octeontx2/af/switch/rvu_sw_l3.h | 11 +++ 8 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw= _fl.c create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw= _fl.h create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw= _l2.c create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw= _l2.h create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw= _l3.c create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw= _l3.h diff --git a/drivers/net/ethernet/marvell/octeontx2/af/Makefile b/drivers/n= et/ethernet/marvell/octeontx2/af/Makefile index 244de500963e..7d9c4050dc32 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/Makefile +++ b/drivers/net/ethernet/marvell/octeontx2/af/Makefile @@ -3,7 +3,7 @@ # Makefile for Marvell's RVU Admin Function driver # =20 -ccflags-y +=3D -I$(src) +ccflags-y +=3D -I$(src) -I$(src)/switch/ obj-$(CONFIG_OCTEONTX2_MBOX) +=3D rvu_mbox.o obj-$(CONFIG_OCTEONTX2_AF) +=3D rvu_af.o =20 @@ -12,5 +12,6 @@ rvu_af-y :=3D cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \ rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o \ rvu_cpt.o rvu_devlink.o rpm.o rvu_cn10k.o rvu_switch.o \ rvu_sdp.o rvu_npc_hash.o mcs.o mcs_rvu_if.o mcs_cnf10kb.o \ + switch/rvu_sw_l2.o switch/rvu_sw_l3.o switch/rvu_sw_fl.o\ rvu_rep.o cn20k/mbox_init.o cn20k/nix.o cn20k/debugfs.o \ cn20k/npa.o diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net= /ethernet/marvell/octeontx2/af/mbox.h index a3e273126e4e..a439fe17580c 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -156,6 +156,14 @@ M(PTP_GET_CAP, 0x00c, ptp_get_cap, msg_req, ptp_get_c= ap_rsp) \ M(GET_REP_CNT, 0x00d, get_rep_cnt, msg_req, get_rep_cnt_rsp) \ M(ESW_CFG, 0x00e, esw_cfg, esw_cfg_req, msg_rsp) \ M(REP_EVENT_NOTIFY, 0x00f, rep_event_notify, rep_event, msg_rsp) \ +M(FDB_NOTIFY, 0x010, fdb_notify, \ + fdb_notify_req, msg_rsp) \ +M(FIB_NOTIFY, 0x011, fib_notify, \ + fib_notify_req, msg_rsp) \ +M(FL_NOTIFY, 0x012, fl_notify, \ + fl_notify_req, msg_rsp) \ +M(FL_GET_STATS, 0x013, fl_get_stats, \ + fl_get_stats_req, fl_get_stats_rsp) \ /* CGX mbox IDs (range 0x200 - 0x3FF) */ \ M(CGX_START_RXTX, 0x200, cgx_start_rxtx, msg_req, msg_rsp) \ M(CGX_STOP_RXTX, 0x201, cgx_stop_rxtx, msg_req, msg_rsp) \ @@ -1694,6 +1702,93 @@ struct rep_event { struct rep_evt_data evt_data; }; =20 +#define FDB_ADD BIT_ULL(0) +#define FDB_DEL BIT_ULL(1) +#define FIB_CMD BIT_ULL(2) +#define FL_ADD BIT_ULL(3) +#define FL_DEL BIT_ULL(4) +#define DP_ADD BIT_ULL(5) + +struct fdb_notify_req { + struct mbox_msghdr hdr; + u64 flags; + u8 mac[ETH_ALEN]; +}; + +struct fib_entry { + u64 cmd; + u64 gw_valid : 1; + u64 mac_valid : 1; + u64 vlan_valid: 1; + u64 host : 1; + u64 bridge : 1; + u16 vlan_tag; + u32 dst; + u32 dst_len; + u32 gw; + u16 port_id; + u8 nud_state; + u8 mac[ETH_ALEN]; +}; + +struct fib_notify_req { + struct mbox_msghdr hdr; + u16 cnt; + struct fib_entry entry[16]; +}; + +struct fl_tuple { + __be32 ip4src; + __be32 m_ip4src; + __be32 ip4dst; + __be32 m_ip4dst; + __be16 sport; + __be16 m_sport; + __be16 dport; + __be16 m_dport; + __be16 eth_type; + __be16 m_eth_type; + u8 proto; + u8 smac[6]; + u8 m_smac[6]; + u8 dmac[6]; + u8 m_dmac[6]; + u64 is_xdev_br : 1; + u64 is_indev_br : 1; + u64 uni_di : 1; + u16 in_pf; + u16 xmit_pf; + u64 features; + struct { /* FLOW_ACTION_MANGLE */ + u8 offset; + u8 type; + u32 mask; + u32 val; +#define MANGLE_ARR_SZ 9 + } mangle[MANGLE_ARR_SZ]; /* 2 for ETH, 1 for VLAN, 4 for IPv6, 2 for L4. = */ +#define MANGLE_LAYER_CNT 4 + u8 mangle_map[MANGLE_LAYER_CNT]; /* 1 for ETH, 1 for VLAN, 1 for L3, 1 f= or L4 */ + u8 mangle_cnt; +}; + +struct fl_notify_req { + struct mbox_msghdr hdr; + unsigned long cookie; + u64 flags; + u64 features; + struct fl_tuple tuple; +}; + +struct fl_get_stats_req { + struct mbox_msghdr hdr; + unsigned long cookie; +}; + +struct fl_get_stats_rsp { + struct mbox_msghdr hdr; + u64 pkts_diff; +}; + struct flow_msg { unsigned char dmac[6]; unsigned char smac[6]; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.c b= /drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.c new file mode 100644 index 000000000000..1f8b82a84a5d --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Marvell RVU Admin Function driver + * + * Copyright (C) 2026 Marvell. + * + */ +#include "rvu.h" + +int rvu_mbox_handler_fl_get_stats(struct rvu *rvu, + struct fl_get_stats_req *req, + struct fl_get_stats_rsp *rsp) +{ + return 0; +} + +int rvu_mbox_handler_fl_notify(struct rvu *rvu, + struct fl_notify_req *req, + struct msg_rsp *rsp) +{ + return 0; +} diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.h b= /drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.h new file mode 100644 index 000000000000..cf3e5b884f77 --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Marvell RVU Admin Function driver + * + * Copyright (C) 2026 Marvell. + * + */ + +#ifndef RVU_SW_FL_H +#define RVU_SW_FL_H + +#endif diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.c b= /drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.c new file mode 100644 index 000000000000..5f805bfa81ed --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Marvell RVU Admin Function driver + * + * Copyright (C) 2026 Marvell. + * + */ +#include "rvu.h" + +int rvu_mbox_handler_fdb_notify(struct rvu *rvu, + struct fdb_notify_req *req, + struct msg_rsp *rsp) +{ + return 0; +} diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.h b= /drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.h new file mode 100644 index 000000000000..ff28612150c9 --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Marvell RVU Admin Function driver + * + * Copyright (C) 2026 Marvell. + * + */ + +#ifndef RVU_SW_L2_H +#define RVU_SW_L2_H + +#endif diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l3.c b= /drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l3.c new file mode 100644 index 000000000000..2b798d5f0644 --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l3.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Marvell RVU Admin Function driver + * + * Copyright (C) 2026 Marvell. + * + */ +#include "rvu.h" + +int rvu_mbox_handler_fib_notify(struct rvu *rvu, + struct fib_notify_req *req, + struct msg_rsp *rsp) +{ + return 0; +} diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l3.h b= /drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l3.h new file mode 100644 index 000000000000..ac8c4f9ba5ac --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l3.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Marvell RVU Admin Function driver + * + * Copyright (C) 2026 Marvell. + * + */ + +#ifndef RVU_SW_L3_H +#define RVU_SW_L3_H + +#endif --=20 2.43.0 From nobody Sun Feb 8 19:03:52 2026 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (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 4379033985D; Fri, 9 Jan 2026 10:31:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954697; cv=none; b=lTHc2Sqao5Dtp28oF2ut9fucFskQ+tIXS7XEEw1G4cf/P6nQQbifCZ1dKhnnviMfcWdkC27Q/eFIW3Mmth8/dnOnPOT3CZuLTMAbdkj14PJh1WSQCS4XXwqrLckDCdX1FOMesf+KlfPMyvgU3OcHRpx4DpWLzxJ+aQ5mqrO9nOE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954697; c=relaxed/simple; bh=hvRoOatdLz4eD+UTjcenXojj6NTBQLoGT9GSnTJdiSE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hibj8iWM2FWOaRaTQ3HeSNekuMpqM3N8ip3qImXrhiJsLdHwtZ6SlfMkzAba9Hc8CHASiHGugOxa/k+PlGibLowsUm/JdtUslPIwFE0l8Yv8lwzgqcD8ifsPhOYu6YYdXT32U0xzjEPHoRgR9JtEHehUZLoZUoOpqdhZ4Hoda1w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=NF0l6Tdi; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="NF0l6Tdi" Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6093EZqe2938365; Fri, 9 Jan 2026 02:31:26 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=/ ustlcCd2/vc0nz0e4vkaB2BMkO4iRIal+dWTDbD4M0=; b=NF0l6Tdi7SacOro0i EyUqmXzJrRtbzxN5mARPa4rFScWs825OF1hzoKdZVExj6XjHqpsnUTd5fQQ9w8T3 DTftq1tXtNG6JU8AjNBZcxCaEyrD4Yvgz6ieN5wWGUZqGkxZqI57dPRni9lbYEYu IynRspiCVWON2+x7N26oKtaOlIvddv7COw8j8If1BKUBqGQnjYVmiZBr5uKGxIBX lHDm4026dyqprMVdyiSeLlh93RBQMa8pZ5iXm68IcxA8Nqxi9wi4HUFLlHroeZRS jxaPhTfjOMsVtOjn3ZgtL43L0ZvZsLAFQzd5QwEovsNFJ6M+C2lha8+j4XOLVkDx 0Sz0g== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4bhwh2vmv5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 09 Jan 2026 02:31:26 -0800 (PST) Received: from DC5-EXCH05.marvell.com (10.69.176.209) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Fri, 9 Jan 2026 02:31:40 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Fri, 9 Jan 2026 02:31:40 -0800 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 14FB33F70F5; Fri, 9 Jan 2026 02:31:22 -0800 (PST) From: Ratheesh Kannoth To: , CC: , , , , , , "Ratheesh Kannoth" Subject: [PATCH net-next v3 02/10] octeontx2-af: switch: Add switch dev to AF mboxes Date: Fri, 9 Jan 2026 16:00:27 +0530 Message-ID: <20260109103035.2972893-3-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109103035.2972893-1-rkannoth@marvell.com> References: <20260109103035.2972893-1-rkannoth@marvell.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-Proofpoint-GUID: x_P2SM8K9TeSfhnrlxdfBKmD3lOZeC0F X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA5MDA3NiBTYWx0ZWRfX9h7Ve6mzAmtg RLQpBs7elY78thEWsz7g+EoZdFffqTGaP5CQDNyeRkJK6ObjbtV/9mUxEEvwMpU0sjClaQO/IKQ TmYrraTrrOrEQ0tJHVAfsxG+FtIZBN71ZpUesPgxJjrnZhd1fdPapOBiDhGDYhMoqi88bptY3kE 4tPbD8i2CbUZ++l04GKxCkfgM6IZEtraaFDSk4r1dF/TFldxMNV/Apq0fdix959gQ5RK9k1yS8o nyshaXuD7gXGSDMjPMmgcOQVxsbdP7a+BQ64jqOlK8S++yilSMVGj0wz3L0zUP7oLQaZrdjPqfd Bsr/4T2sBXqzBYJBOc7d+61pautYE8RVZ0WN7z21xT+SXUZ83Ou1WmhGIVERyVWkWcSzsWj6xFQ Cnxc5buQXPXQk+RJsr4kXAGSf+6HJBphNX+OICGrp61rE0SlTebGHjRkRS92vKysEN2BfAPw4Az 3SXCjDQrlRVm0iaBLOQ== X-Authority-Analysis: v=2.4 cv=ROO+3oi+ c=1 sm=1 tr=0 ts=6960d8fe cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=vUbySO9Y5rIA:10 a=VkNPw1HP01LnGYTKEx00:22 a=M5GUcnROAAAA:8 a=WBe6_t-ORFUBTklN5yIA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-ORIG-GUID: x_P2SM8K9TeSfhnrlxdfBKmD3lOZeC0F X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-09_03,2026-01-08_02,2025-10-01_01 Content-Type: text/plain; charset="utf-8" The Marvell switch hardware runs on a Linux OS. Switch needs various information from AF driver. These mboxes are defined to query those from AF driver. Signed-off-by: Ratheesh Kannoth --- .../ethernet/marvell/octeontx2/af/Makefile | 2 +- .../net/ethernet/marvell/octeontx2/af/mbox.h | 119 ++++++++++++++++++ .../net/ethernet/marvell/octeontx2/af/rvu.c | 110 +++++++++++++++- .../net/ethernet/marvell/octeontx2/af/rvu.h | 1 + .../ethernet/marvell/octeontx2/af/rvu_nix.c | 4 +- .../ethernet/marvell/octeontx2/af/rvu_npc.c | 77 +++++++++++- .../marvell/octeontx2/af/rvu_npc_fs.c | 11 ++ .../marvell/octeontx2/af/switch/rvu_sw.c | 15 +++ .../marvell/octeontx2/af/switch/rvu_sw.h | 11 ++ 9 files changed, 344 insertions(+), 6 deletions(-) create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw= .c create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw= .h diff --git a/drivers/net/ethernet/marvell/octeontx2/af/Makefile b/drivers/n= et/ethernet/marvell/octeontx2/af/Makefile index 7d9c4050dc32..3254b97545d0 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/Makefile +++ b/drivers/net/ethernet/marvell/octeontx2/af/Makefile @@ -12,6 +12,6 @@ rvu_af-y :=3D cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \ rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o \ rvu_cpt.o rvu_devlink.o rpm.o rvu_cn10k.o rvu_switch.o \ rvu_sdp.o rvu_npc_hash.o mcs.o mcs_rvu_if.o mcs_cnf10kb.o \ - switch/rvu_sw_l2.o switch/rvu_sw_l3.o switch/rvu_sw_fl.o\ + switch/rvu_sw.o switch/rvu_sw_l2.o switch/rvu_sw_l3.o switch/rvu_sw_fl= .o \ rvu_rep.o cn20k/mbox_init.o cn20k/nix.o cn20k/debugfs.o \ cn20k/npa.o diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net= /ethernet/marvell/octeontx2/af/mbox.h index a439fe17580c..d82d7c1b0926 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -164,6 +164,10 @@ M(FL_NOTIFY, 0x012, fl_notify, \ fl_notify_req, msg_rsp) \ M(FL_GET_STATS, 0x013, fl_get_stats, \ fl_get_stats_req, fl_get_stats_rsp) \ +M(GET_IFACE_GET_INFO, 0x014, iface_get_info, msg_req, \ + iface_get_info_rsp) \ +M(SWDEV2AF_NOTIFY, 0x015, swdev2af_notify, \ + swdev2af_notify_req, msg_rsp) \ /* CGX mbox IDs (range 0x200 - 0x3FF) */ \ M(CGX_START_RXTX, 0x200, cgx_start_rxtx, msg_req, msg_rsp) \ M(CGX_STOP_RXTX, 0x201, cgx_stop_rxtx, msg_req, msg_rsp) \ @@ -283,6 +287,14 @@ M(NPC_GET_FIELD_HASH_INFO, 0x6013, npc_get_field_hash_= info, M(NPC_GET_FIELD_STATUS, 0x6014, npc_get_field_status, \ npc_get_field_status_req, \ npc_get_field_status_rsp) \ +M(NPC_MCAM_FLOW_DEL_N_FREE, 0x6020, npc_flow_del_n_free, \ + npc_flow_del_n_free_req, msg_rsp) \ +M(NPC_MCAM_GET_MUL_STATS, 0x6021, npc_mcam_mul_stats, \ + npc_mcam_get_mul_stats_req, \ + npc_mcam_get_mul_stats_rsp) \ +M(NPC_MCAM_GET_FEATURES, 0x6022, npc_mcam_get_features, \ + msg_req, \ + npc_mcam_get_features_rsp) \ /* NIX mbox IDs (range 0x8000 - 0xFFFF) */ \ M(NIX_LF_ALLOC, 0x8000, nix_lf_alloc, \ nix_lf_alloc_req, nix_lf_alloc_rsp) \ @@ -412,6 +424,12 @@ M(MCS_INTR_NOTIFY, 0xE00, mcs_intr_notify, mcs_intr_in= fo, msg_rsp) #define MBOX_UP_REP_MESSAGES \ M(REP_EVENT_UP_NOTIFY, 0xEF0, rep_event_up_notify, rep_event, msg_rsp) \ =20 +#define MBOX_UP_AF2SWDEV_MESSAGES \ +M(AF2SWDEV, 0xEF1, af2swdev_notify, af2swdev_notify_req, msg_rsp) + +#define MBOX_UP_AF2PF_FDB_REFRESH_MESSAGES \ +M(AF2PF_FDB_REFRESH, 0xEF2, af2pf_fdb_refresh, af2pf_fdb_refresh_req, msg= _rsp) + enum { #define M(_name, _id, _1, _2, _3) MBOX_MSG_ ## _name =3D _id, MBOX_MESSAGES @@ -419,6 +437,8 @@ MBOX_UP_CGX_MESSAGES MBOX_UP_CPT_MESSAGES MBOX_UP_MCS_MESSAGES MBOX_UP_REP_MESSAGES +MBOX_UP_AF2SWDEV_MESSAGES +MBOX_UP_AF2PF_FDB_REFRESH_MESSAGES #undef M }; =20 @@ -1550,6 +1570,30 @@ struct npc_mcam_alloc_entry_rsp { u16 entry_list[NPC_MAX_NONCONTIG_ENTRIES]; }; =20 +struct npc_flow_del_n_free_req { + struct mbox_msghdr hdr; + u16 cnt; + u16 entry[256]; /* Entry index to be freed */ +}; + +struct npc_mcam_get_features_rsp { + struct mbox_msghdr hdr; + u64 rx_features; + u64 tx_features; +}; + +struct npc_mcam_get_mul_stats_req { + struct mbox_msghdr hdr; + int cnt; + u16 entry[256]; /* mcam entry */ +}; + +struct npc_mcam_get_mul_stats_rsp { + struct mbox_msghdr hdr; + int cnt; + u64 stat[256]; /* counter stats */ +}; + struct npc_mcam_free_entry_req { struct mbox_msghdr hdr; u16 entry; /* Entry index to be freed */ @@ -1789,6 +1833,81 @@ struct fl_get_stats_rsp { u64 pkts_diff; }; =20 +struct af2swdev_notify_req { + struct mbox_msghdr hdr; + u64 flags; + u32 port_id; + u32 switch_id; + union { + struct { + u8 mac[6]; + }; + struct { + u8 cnt; + struct fib_entry entry[16]; + }; + + struct { + unsigned long cookie; + u64 features; + struct fl_tuple tuple; + }; + }; +}; + +struct af2pf_fdb_refresh_req { + struct mbox_msghdr hdr; + u16 pcifunc; + u8 mac[6]; +}; + +struct iface_info { + u64 is_vf :1; + u64 is_sdp :1; + u16 pcifunc; + u16 rx_chan_base; + u16 tx_chan_base; + u16 sq_cnt; + u16 cq_cnt; + u16 rq_cnt; + u8 rx_chan_cnt; + u8 tx_chan_cnt; + u8 tx_link; + u8 nix; +}; + +struct iface_get_info_rsp { + struct mbox_msghdr hdr; + int cnt; + struct iface_info info[256 + 32]; /* 32 PFs + 256 Vs */ +}; + +struct fl_info { + unsigned long cookie; + u16 mcam_idx[2]; + u8 dis : 1; + u8 uni_di : 1; +}; + +struct swdev2af_notify_req { + struct mbox_msghdr hdr; + u64 msg_type; +#define SWDEV2AF_MSG_TYPE_FW_STATUS BIT_ULL(0) +#define SWDEV2AF_MSG_TYPE_REFRESH_FDB BIT_ULL(1) +#define SWDEV2AF_MSG_TYPE_REFRESH_FL BIT_ULL(2) + u16 pcifunc; + union { + bool fw_up; // FW_STATUS message + + u8 mac[ETH_ALEN]; // fdb refresh message + + struct { // fl refresh message + int cnt; + struct fl_info fl[64]; + }; + }; +}; + struct flow_msg { unsigned char dmac[6]; unsigned char smac[6]; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/= ethernet/marvell/octeontx2/af/rvu.c index 2d78e08f985f..6b61742a61b1 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -1396,7 +1396,6 @@ static void rvu_detach_block(struct rvu *rvu, int pci= func, int blktype) if (blkaddr < 0) return; =20 - block =3D &hw->block[blkaddr]; =20 num_lfs =3D rvu_get_rsrc_mapcount(pfvf, block->addr); @@ -1907,6 +1906,115 @@ int rvu_mbox_handler_msix_offset(struct rvu *rvu, s= truct msg_req *req, return 0; } =20 +int rvu_mbox_handler_iface_get_info(struct rvu *rvu, struct msg_req *req, + struct iface_get_info_rsp *rsp) +{ + struct iface_info *info; + struct rvu_pfvf *pfvf; + int pf, vf, numvfs; + u16 pcifunc; + int tot =3D 0; + u64 cfg; + + info =3D rsp->info; + for (pf =3D 0; pf < rvu->hw->total_pfs; pf++) { + cfg =3D rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf)); + numvfs =3D (cfg >> 12) & 0xFF; + + /* Skip not enabled PFs */ + if (!(cfg & BIT_ULL(20))) + goto chk_vfs; + + /* If Admin function, check on VFs */ + if (cfg & BIT_ULL(21)) + goto chk_vfs; + + pcifunc =3D rvu_make_pcifunc(rvu->pdev, pf, 0); + pfvf =3D rvu_get_pfvf(rvu, pcifunc); + + /* Populate iff at least one Tx channel */ + if (!pfvf->tx_chan_cnt) + goto chk_vfs; + + info->is_vf =3D 0; + info->pcifunc =3D pcifunc; + info->rx_chan_base =3D pfvf->rx_chan_base; + info->rx_chan_cnt =3D pfvf->rx_chan_cnt; + info->tx_chan_base =3D pfvf->tx_chan_base; + info->tx_chan_cnt =3D pfvf->tx_chan_cnt; + info->tx_link =3D nix_get_tx_link(rvu, pcifunc); + if (is_sdp_pfvf(rvu, pcifunc)) + info->is_sdp =3D 1; + + /* If interfaces are not UP, there are no queues */ + info->sq_cnt =3D 0; + info->cq_cnt =3D 0; + info->rq_cnt =3D 0; + + if (pfvf->sq_bmap) + info->sq_cnt =3D bitmap_weight(pfvf->sq_bmap, BITS_PER_LONG * 16); + + if (pfvf->cq_bmap) + info->cq_cnt =3D bitmap_weight(pfvf->cq_bmap, BITS_PER_LONG); + + if (pfvf->rq_bmap) + info->rq_cnt =3D bitmap_weight(pfvf->rq_bmap, BITS_PER_LONG); + + if (pfvf->nix_blkaddr =3D=3D BLKADDR_NIX0) + info->nix =3D 0; + else + info->nix =3D 1; + + info++; + tot++; + +chk_vfs: + for (vf =3D 0; vf < numvfs; vf++) { + pcifunc =3D rvu_make_pcifunc(rvu->pdev, pf, vf + 1); + pfvf =3D rvu_get_pfvf(rvu, pcifunc); + + if (!pfvf->tx_chan_cnt) + continue; + + info->is_vf =3D 1; + info->pcifunc =3D pcifunc; + info->rx_chan_base =3D pfvf->rx_chan_base; + info->rx_chan_cnt =3D pfvf->rx_chan_cnt; + info->tx_chan_base =3D pfvf->tx_chan_base; + info->tx_chan_cnt =3D pfvf->tx_chan_cnt; + info->tx_link =3D nix_get_tx_link(rvu, pcifunc); + if (is_sdp_pfvf(rvu, pcifunc)) + info->is_sdp =3D 1; + + /* If interfaces are not UP, there are no queues */ + info->sq_cnt =3D 0; + info->cq_cnt =3D 0; + info->rq_cnt =3D 0; + + if (pfvf->sq_bmap) + info->sq_cnt =3D bitmap_weight(pfvf->sq_bmap, BITS_PER_LONG * 16); + + if (pfvf->cq_bmap) + info->cq_cnt =3D bitmap_weight(pfvf->cq_bmap, BITS_PER_LONG); + + if (pfvf->rq_bmap) + info->rq_cnt =3D bitmap_weight(pfvf->rq_bmap, BITS_PER_LONG); + + if (pfvf->nix_blkaddr =3D=3D BLKADDR_NIX0) + info->nix =3D 0; + else + info->nix =3D 1; + + info++; + + tot++; + } + } + rsp->cnt =3D tot; + + return 0; +} + int rvu_mbox_handler_free_rsrc_cnt(struct rvu *rvu, struct msg_req *req, struct free_rsrcs_rsp *rsp) { diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/= ethernet/marvell/octeontx2/af/rvu.h index e85dac2c806d..4e11cdf5df63 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -1147,6 +1147,7 @@ void rvu_program_channels(struct rvu *rvu); =20 /* CN10K NIX */ void rvu_nix_block_cn10k_init(struct rvu *rvu, struct nix_hw *nix_hw); +int nix_get_tx_link(struct rvu *rvu, u16 pcifunc); =20 /* CN10K RVU - LMT*/ void rvu_reset_lmt_map_tbl(struct rvu *rvu, u16 pcifunc); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/= net/ethernet/marvell/octeontx2/af/rvu_nix.c index 2f485a930edd..e2cc33ad2b2c 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c @@ -31,7 +31,6 @@ static int nix_free_all_bandprof(struct rvu *rvu, u16 pci= func); static void nix_clear_ratelimit_aggr(struct rvu *rvu, struct nix_hw *nix_h= w, u32 leaf_prof); static const char *nix_get_ctx_name(int ctype); -static int nix_get_tx_link(struct rvu *rvu, u16 pcifunc); =20 enum mc_tbl_sz { MC_TBL_SZ_256, @@ -2055,7 +2054,7 @@ static void nix_clear_tx_xoff(struct rvu *rvu, int bl= kaddr, rvu_write64(rvu, blkaddr, reg, 0x0); } =20 -static int nix_get_tx_link(struct rvu *rvu, u16 pcifunc) +int nix_get_tx_link(struct rvu *rvu, u16 pcifunc) { struct rvu_hwinfo *hw =3D rvu->hw; int pf =3D rvu_get_pf(rvu->pdev, pcifunc); @@ -5283,7 +5282,6 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, = struct msg_req *req, /* Disable the interface if it is in any multicast list */ nix_mcast_update_mce_entry(rvu, pcifunc, 0); =20 - pfvf =3D rvu_get_pfvf(rvu, pcifunc); clear_bit(NIXLF_INITIALIZED, &pfvf->flags); =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/= net/ethernet/marvell/octeontx2/af/rvu_npc.c index c7c70429eb6c..4e2d24069d88 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c @@ -2815,6 +2815,42 @@ int rvu_mbox_handler_npc_mcam_free_entry(struct rvu = *rvu, return rc; } =20 +int rvu_mbox_handler_npc_flow_del_n_free(struct rvu *rvu, + struct npc_flow_del_n_free_req *mreq, + struct msg_rsp *rsp) +{ + struct npc_mcam_free_entry_req sreq =3D { 0 }; + struct npc_delete_flow_req dreq =3D { 0 }; + struct npc_delete_flow_rsp drsp =3D { 0 }; + int err, ret =3D 0; + + sreq.hdr.pcifunc =3D mreq->hdr.pcifunc; + dreq.hdr.pcifunc =3D mreq->hdr.pcifunc; + + if (!mreq->cnt || mreq->cnt > 256) { + dev_err(rvu->dev, "Invalid cnt=3D%d\n", mreq->cnt); + return -EINVAL; + } + + for (int i =3D 0; i < mreq->cnt; i++) { + dreq.entry =3D mreq->entry[i]; + err =3D rvu_mbox_handler_npc_delete_flow(rvu, &dreq, &drsp); + if (err) + dev_err(rvu->dev, "delete flow error for i=3D%d entry=3D%d\n", + i, mreq->entry[i]); + ret |=3D err; + + sreq.entry =3D mreq->entry[i]; + err =3D rvu_mbox_handler_npc_mcam_free_entry(rvu, &sreq, rsp); + if (err) + dev_err(rvu->dev, "free entry error for i=3D%d entry=3D%d\n", + i, mreq->entry[i]); + ret |=3D err; + } + + return ret; +} + int rvu_mbox_handler_npc_mcam_read_entry(struct rvu *rvu, struct npc_mcam_read_entry_req *req, struct npc_mcam_read_entry_rsp *rsp) @@ -3029,7 +3065,6 @@ static int __npc_mcam_alloc_counter(struct rvu *rvu, if (!req->contig && req->count > NPC_MAX_NONCONTIG_COUNTERS) return NPC_MCAM_INVALID_REQ; =20 - /* Check if unused counters are available or not */ if (!rvu_rsrc_free_count(&mcam->counters)) { return NPC_MCAM_ALLOC_FAILED; @@ -3577,6 +3612,46 @@ int rvu_mbox_handler_npc_mcam_entry_stats(struct rvu= *rvu, return 0; } =20 +int rvu_mbox_handler_npc_mcam_mul_stats(struct rvu *rvu, + struct npc_mcam_get_mul_stats_req *req, + struct npc_mcam_get_mul_stats_rsp *rsp) +{ + struct npc_mcam *mcam =3D &rvu->hw->mcam; + u16 index, cntr; + int blkaddr; + u64 regval; + u32 bank; + + if (!req->cnt || req->cnt > 256) { + dev_err(rvu->dev, "%s invalid request cnt=3D%d\n", + __func__, req->cnt); + return -EINVAL; + } + + blkaddr =3D rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); + if (blkaddr < 0) + return NPC_MCAM_INVALID_REQ; + + mutex_lock(&mcam->lock); + + for (int i =3D 0; i < req->cnt; i++) { + index =3D req->entry[i] & (mcam->banksize - 1); + bank =3D npc_get_bank(mcam, req->entry[i]); + + /* read MCAM entry STAT_ACT register */ + regval =3D rvu_read64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_STAT_ACT(index, = bank)); + cntr =3D regval & 0x1FF; + + rsp->stat[i] =3D rvu_read64(rvu, blkaddr, NPC_AF_MATCH_STATX(cntr)); + rsp->stat[i] &=3D BIT_ULL(48) - 1; + } + + rsp->cnt =3D req->cnt; + + mutex_unlock(&mcam->lock); + return 0; +} + void rvu_npc_clear_ucast_entry(struct rvu *rvu, int pcifunc, int nixlf) { struct npc_mcam *mcam =3D &rvu->hw->mcam; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drive= rs/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c index b56395ac5a74..3d6f780635a5 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c @@ -1549,6 +1549,17 @@ static int npc_delete_flow(struct rvu *rvu, struct r= vu_npc_mcam_rule *rule, return rvu_mbox_handler_npc_mcam_dis_entry(rvu, &dis_req, &dis_rsp); } =20 +int rvu_mbox_handler_npc_mcam_get_features(struct rvu *rvu, + struct msg_req *req, + struct npc_mcam_get_features_rsp *rsp) +{ + struct npc_mcam *mcam =3D &rvu->hw->mcam; + + rsp->rx_features =3D mcam->rx_features; + rsp->tx_features =3D mcam->tx_features; + return 0; +} + int rvu_mbox_handler_npc_delete_flow(struct rvu *rvu, struct npc_delete_flow_req *req, struct npc_delete_flow_rsp *rsp) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c b/dr= ivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c new file mode 100644 index 000000000000..fe143ad3f944 --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Marvell RVU Admin Function driver + * + * Copyright (C) 2026 Marvell. + * + */ + +#include "rvu.h" + +int rvu_mbox_handler_swdev2af_notify(struct rvu *rvu, + struct swdev2af_notify_req *req, + struct msg_rsp *rsp) +{ + return 0; +} diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h b/dr= ivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h new file mode 100644 index 000000000000..f28dba556d80 --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Marvell RVU Admin Function driver + * + * Copyright (C) 2026 Marvell. + * + */ + +#ifndef RVU_SWITCH_H +#define RVU_SWITCH_H + +#endif --=20 2.43.0 From nobody Sun Feb 8 19:03:52 2026 Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) (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 48E90338939; Fri, 9 Jan 2026 10:31:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.156.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954703; cv=none; b=kkVey9+A8G2Supeg5icOHw+TVx8Yj6a07368z5NOTXfg1iVdStYe1p8RG6/FzNuZCgqte3sEhMy/Hp+onurLPP1Eo4EquT41Ns4bHLyohn0CWqsfYUe8Qrj78n1QT0broaDFNePOGa7QNhJduGxMHFsNrNQ9PQVGvcEmuEof20A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954703; c=relaxed/simple; bh=C9qSQ3rnC9t568mqWd5oiPqTNZM7919WT9hDt6v5h+c=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=X0jwi8RzCnAUvL9oBfOf6PISa6kKchdy6viVRe0XvHdVSXrOSAMGKptAacJyYDpH42uXdNU9o9/n5ux9Voi19QiELhnY+S4VQdIqjVAFYV5ad9ms7sBUE5zHAmWD+l7zhw/J57pUgiQcZtr57fEzZ5i42Je1ek0ONmraF3JqJBM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=eDYyMWIQ; arc=none smtp.client-ip=67.231.156.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="eDYyMWIQ" Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6099PXBY744324; Fri, 9 Jan 2026 02:31:30 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=N Uh7MbdFfJkGhw2NiVGEmZhbhyjEQcWx0cultGiGSoY=; b=eDYyMWIQoFxs94+Xb sGP2M4JmD3Bx/qyanal0chu3dfgi1JLOE2tWvk8ds4iftduJJ3YFlXPbxPHQlxD2 4TSieQ+DuMsn72FVIvUJt979Wj4Hs/b1z9VWMsvdWAg3iEHO4ndPJ6YQvwKyY3cm Gk9oIbm81eMJq4j1FFIA2ASti9tOA6j+duGP0xwLvyWlWmXsNF/DSXP8B8Hu6Ssz DRv53hz6lDjuU1ZfPSQwjHUj2P2TOpCAiHqBeEkIdZrZHxIS3TJ/Dp+YR7gef00u 3LNxSybjvvMBRhMVFs3EkvqSAweqkX8VIlvMZVc51yoY2ZCceNm0CVtU+QmGQG+z TTLBA== Received: from dc6wp-exch02.marvell.com ([4.21.29.225]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 4bjset0x2e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 09 Jan 2026 02:31:29 -0800 (PST) Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Fri, 9 Jan 2026 02:31:29 -0800 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Fri, 9 Jan 2026 02:31:29 -0800 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 33EE23F708A; Fri, 9 Jan 2026 02:31:25 -0800 (PST) From: Ratheesh Kannoth To: , CC: , , , , , , "Ratheesh Kannoth" Subject: [PATCH net-next v3 03/10] octeontx2-pf: switch: Add pf files hierarchy Date: Fri, 9 Jan 2026 16:00:28 +0530 Message-ID: <20260109103035.2972893-4-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109103035.2972893-1-rkannoth@marvell.com> References: <20260109103035.2972893-1-rkannoth@marvell.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-Authority-Analysis: v=2.4 cv=W581lBWk c=1 sm=1 tr=0 ts=6960d901 cx=c_pps a=gIfcoYsirJbf48DBMSPrZA==:117 a=gIfcoYsirJbf48DBMSPrZA==:17 a=vUbySO9Y5rIA:10 a=VkNPw1HP01LnGYTKEx00:22 a=M5GUcnROAAAA:8 a=rErRu6woPkWivxaahN8A:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-GUID: ioGwdmJjbhLyanB1pw5bLqsdCYMVaAv- X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA5MDA3NiBTYWx0ZWRfX/h3oq/OjN4zh gJwCxFa0Yq7ta3cihbQ4OcNYC5fLghBQKCnt/9/Di/tH80s3+vQ7xWR606dXVafSxdSVmtgJgqa ej778o4NGnYOHR8cCHGoAj8GmNM7SNCwaZIMLGewCeeSNl5UmwnFo0DrNrb3+LDgMryHBQYIaD0 Fm7BEnIRFhxc8ywvK2c5y69lz5S04uG9AAo5P8S0YIy8kRID2te56eo0fInf9gvdf13dlS8CjFA 6AVvCBERGwALSdCKx8J21jjQzZBcRmJ23YS3oOaWJy19D36NJhfhg/rbY11jfzFh6r+r6XWnAb5 7Jblo5e544dyeA9UE2Ph4EAfV6LQhfIhKS2Ooe8O5Hic+vhARb+gruifw5rET5e7rjvaYXL7jQc LdeUEY0p2+nN4byLPLjb0f8mGf+fvHecUlS6DaBpa76eQK3v6FmBYEWaC29hoXfACcJZgErQ+m8 GO5T+jmbGqD5SnF3/WQ== X-Proofpoint-ORIG-GUID: ioGwdmJjbhLyanB1pw5bLqsdCYMVaAv- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-09_03,2026-01-08_02,2025-10-01_01 Content-Type: text/plain; charset="utf-8" PF driver skeleton files. Follow up patches add meat to these files. sw_nb* : Implements various notifier callbacks for linux events sw_fdb* : L2 offload sw_fib* : L3 offload sw_fl* : Flow based offload (ovs, nft etc) Signed-off-by: Ratheesh Kannoth --- drivers/net/ethernet/marvell/octeontx2/Kconfig | 12 ++++++++++++ .../net/ethernet/marvell/octeontx2/nic/Makefile | 8 +++++++- .../marvell/octeontx2/nic/switch/sw_fdb.c | 16 ++++++++++++++++ .../marvell/octeontx2/nic/switch/sw_fdb.h | 13 +++++++++++++ .../marvell/octeontx2/nic/switch/sw_fib.c | 16 ++++++++++++++++ .../marvell/octeontx2/nic/switch/sw_fib.h | 13 +++++++++++++ .../marvell/octeontx2/nic/switch/sw_fl.c | 16 ++++++++++++++++ .../marvell/octeontx2/nic/switch/sw_fl.h | 13 +++++++++++++ .../marvell/octeontx2/nic/switch/sw_nb.c | 17 +++++++++++++++++ .../marvell/octeontx2/nic/switch/sw_nb.h | 13 +++++++++++++ 10 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fd= b.c create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fd= b.h create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fi= b.c create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fi= b.h create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl= .c create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl= .h create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb= .c create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb= .h diff --git a/drivers/net/ethernet/marvell/octeontx2/Kconfig b/drivers/net/e= thernet/marvell/octeontx2/Kconfig index 35c4f5f64f58..a883efc9d9dd 100644 --- a/drivers/net/ethernet/marvell/octeontx2/Kconfig +++ b/drivers/net/ethernet/marvell/octeontx2/Kconfig @@ -28,6 +28,18 @@ config NDC_DIS_DYNAMIC_CACHING , NPA stack pages etc in NDC. Also locks down NIX SQ/CQ/RQ/RSS and NPA Aura/Pool contexts. =20 +config OCTEONTX_SWITCH + tristate "Marvell OcteonTX2 switch driver" + select OCTEONTX2_MBOX + select NET_DEVLINK + default n + select PAGE_POOL + depends on (64BIT && COMPILE_TEST) || ARM64 + help + This driver supports Marvell's OcteonTX2 switch driver. + Marvell SW HW can offload L2, L3 offload. ARM core interacts + with Marvell SW HW thru mbox. + config OCTEONTX2_PF tristate "Marvell OcteonTX2 NIC Physical Function driver" select OCTEONTX2_MBOX diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/Makefile b/drivers/= net/ethernet/marvell/octeontx2/nic/Makefile index 883e9f4d601c..da87e952c187 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/Makefile +++ b/drivers/net/ethernet/marvell/octeontx2/nic/Makefile @@ -9,7 +9,13 @@ obj-$(CONFIG_RVU_ESWITCH) +=3D rvu_rep.o =20 rvu_nicpf-y :=3D otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \ otx2_flows.o otx2_tc.o cn10k.o cn20k.o otx2_dmac_flt.o \ - otx2_devlink.o qos_sq.o qos.o otx2_xsk.o + otx2_devlink.o qos_sq.o qos.o otx2_xsk.o \ + switch/sw_fdb.o switch/sw_fl.o + +ifdef CONFIG_OCTEONTX_SWITCH +rvu_nicpf-y +=3D switch/sw_nb.o switch/sw_fib.o +endif + rvu_nicvf-y :=3D otx2_vf.o rvu_rep-y :=3D rep.o =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.c b/d= rivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.c new file mode 100644 index 000000000000..6842c8d91ffc --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Marvell RVU switch driver + * + * Copyright (C) 2026 Marvell. + * + */ +#include "sw_fdb.h" + +int sw_fdb_init(void) +{ + return 0; +} + +void sw_fdb_deinit(void) +{ +} diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.h b/d= rivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.h new file mode 100644 index 000000000000..d4314d6d3ee4 --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Marvell switch driver + * + * Copyright (C) 2026 Marvell. + * + */ +#ifndef SW_FDB_H_ +#define SW_FDB_H_ + +void sw_fdb_deinit(void); +int sw_fdb_init(void); + +#endif // SW_FDB_H diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.c b/d= rivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.c new file mode 100644 index 000000000000..12ddf8119372 --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Marvell RVU switch driver + * + * Copyright (C) 2026 Marvell. + * + */ +#include "sw_fib.h" + +int sw_fib_init(void) +{ + return 0; +} + +void sw_fib_deinit(void) +{ +} diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.h b/d= rivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.h new file mode 100644 index 000000000000..a51d15c2b80e --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Marvell switch driver + * + * Copyright (C) 2026 Marvell. + * + */ +#ifndef SW_FIB_H_ +#define SW_FIB_H_ + +void sw_fib_deinit(void); +int sw_fib_init(void); + +#endif // SW_FIB_H diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.c b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.c new file mode 100644 index 000000000000..36a2359a0a48 --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Marvell RVU switch driver + * + * Copyright (C) 2026 Marvell. + * + */ +#include "sw_fl.h" + +int sw_fl_init(void) +{ + return 0; +} + +void sw_fl_deinit(void) +{ +} diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.h b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.h new file mode 100644 index 000000000000..cd018d770a8a --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Marvell switch driver + * + * Copyright (C) 2026 Marvell. + * + */ +#ifndef SW_FL_H_ +#define SW_FL_H_ + +void sw_fl_deinit(void); +int sw_fl_init(void); + +#endif // SW_FL_H diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c new file mode 100644 index 000000000000..2d14a0590c5d --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Marvell RVU switch driver + * + * Copyright (C) 2026 Marvell. + * + */ +#include "sw_nb.h" + +int sw_nb_unregister(void) +{ + return 0; +} + +int sw_nb_register(void) +{ + return 0; +} diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.h b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.h new file mode 100644 index 000000000000..5f744cc3ecbb --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Marvell switch driver + * + * Copyright (C) 2026 Marvell. + * + */ +#ifndef SW_NB_H_ +#define SW_NB_H_ + +int sw_nb_register(void); +int sw_nb_unregister(void); + +#endif // SW_NB_H_ --=20 2.43.0 From nobody Sun Feb 8 19:03:52 2026 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (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 BC645338F5B; Fri, 9 Jan 2026 10:31:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954702; cv=none; b=oQzwicTtDzx9IjEZs9JwAKdu6gOZeSNl3FRgs5qDItu+l9qENy941Y9xBTHmWtedV2C0LsA9+PS8M/QMVs6wNVYfOwTrlj20Q4ixgPpKMzNhXMXIXrhFSl3WoQxwhfaFF5It/8mJpVm7/bXwXmvvNMBXS1ue5/x4fVHdAwc82ts= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954702; c=relaxed/simple; bh=08kjM0UEVJ3OBOcUn7eJgPUyGRiSVCOjkmpoVugQw/Y=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=AcBNeP0Nc9XnYwpe1FoXB/4qWloEns2JO+d2DQh0eUh+aMoWNDlxjnq6ZydM0Pz/gNgmSF6TGkvE1SoRiPB+O+Big7l/TX+3zYBc15T0kCsv8EUh9mtwr1cu7VnIqZxHMNNQjeZtf1ZHi/B+rpZKKFA9LJ5IyBAQKQaESPJj2XA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=LicuDmtH; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="LicuDmtH" Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6092L2BJ2938085; Fri, 9 Jan 2026 02:31:32 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=0 5yJx0JbT68f7zq+eCmKiyumjAoJaoNuNekDS+tHtr4=; b=LicuDmtHUNgYJPDTA JZEv3emEhrcpbVawNhHGJEaV/NUffWRXBOwg2O3vyYzIEByAX+QbMBQzjUq04zlB ZgDrnetsREljadVK2PAZSDNsWumqF+I6W3dQFxmj+VIi6d25tagIzPtSqdP6JJbT fg91trE5TgqhHZMBZLybpFTLsJ2g/iS32TPw0DbFdnG0dfESjM50+gPltkE3u0x+ eF0IAWL8lG+7QBjr3BNh4FIKJoFfHFBKPWhZucdBgAlcsqLpeyzecmLlXlUF4Gtp 4GFlIK31Ugsu3bO3URgc3xTuBVtpXA5ViOc/U4NZtb9qUcsmLW+Z/rIKhf4C0jxi VtqiA== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4bhwh2vmvd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 09 Jan 2026 02:31:32 -0800 (PST) Received: from DC5-EXCH05.marvell.com (10.69.176.209) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Fri, 9 Jan 2026 02:31:47 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Fri, 9 Jan 2026 02:31:47 -0800 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 51CC23F70F7; Fri, 9 Jan 2026 02:31:29 -0800 (PST) From: Ratheesh Kannoth To: , CC: , , , , , , "Ratheesh Kannoth" Subject: [PATCH net-next v3 04/10] octeontx2-af: switch: Representor for switch port Date: Fri, 9 Jan 2026 16:00:29 +0530 Message-ID: <20260109103035.2972893-5-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109103035.2972893-1-rkannoth@marvell.com> References: <20260109103035.2972893-1-rkannoth@marvell.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-Proofpoint-GUID: fMZxgO6PbfkezUBwpc-sihqSrnzm_oDi X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA5MDA3NiBTYWx0ZWRfXwtKznojo/eOl AtTUaeSPKMQcq1L5jMC7SYtUMuvLtfXmLlo+Y6uuVUXbdKr2FBbo0sdFv64cJN0ttlREigGGLFY CdegUyai++p7zDmUGNizveZ+rwD2qK1nUQ9fC0n08SYLLYwrO+pzDPXKBhmgQekGxS4TuBdqyBT C+ggsBU0MTyJDm2sxKn4e3Jxo8gzijqX3SyFHH6fJGxLexvyA53+4nWRulTDtwjvlpoBeSCA3Eu jmWDYvj2kkXTwuQH++qDG/4Ngkw2rl07Ss7fMjYalMcjR75Msq3NcAP454PPWIvJI+JQqrVnfXf f7c+zOJhD8N9QrVwCR0WaMvBlkjTPsciMoCaykwbyFbLOZmrQjmXQCCbhLF+jfqbs9xaw24S65B Gyb6IYszbQV8iCBBHCqW1ympTzS5/guwqiEImIJI1eePdhwlkcw55kcv7vv2EWK77NYAlNQjDxc DVUI6IEP8zPI4Wm2jYg== X-Authority-Analysis: v=2.4 cv=ROO+3oi+ c=1 sm=1 tr=0 ts=6960d904 cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=vUbySO9Y5rIA:10 a=VkNPw1HP01LnGYTKEx00:22 a=M5GUcnROAAAA:8 a=xXrhxGPyklmKcrYTpSYA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-ORIG-GUID: fMZxgO6PbfkezUBwpc-sihqSrnzm_oDi X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-09_03,2026-01-08_02,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Representor support is already available in AF driver. When Representors are enabled through devlink, switch id and various information are collected from AF driver and sent to switchdev thru mbox message. This message enables switchdev HW. Signed-off-by: Ratheesh Kannoth --- drivers/net/ethernet/marvell/octeontx2/af/mbox.h | 1 + drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 5 +++++ .../net/ethernet/marvell/octeontx2/af/rvu_rep.c | 3 ++- .../ethernet/marvell/octeontx2/af/switch/rvu_sw.c | 14 ++++++++++++++ .../ethernet/marvell/octeontx2/af/switch/rvu_sw.h | 3 +++ drivers/net/ethernet/marvell/octeontx2/nic/rep.c | 4 ++++ 6 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net= /ethernet/marvell/octeontx2/af/mbox.h index d82d7c1b0926..24703c27a352 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -1721,6 +1721,7 @@ struct get_rep_cnt_rsp { struct esw_cfg_req { struct mbox_msghdr hdr; u8 ena; + unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN]; u64 rsvd; }; =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/= ethernet/marvell/octeontx2/af/rvu.h index 4e11cdf5df63..0f3d1b38a7dd 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -567,6 +567,10 @@ struct rvu_switch { u16 *entry2pcifunc; u16 mode; u16 start_entry; + unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN]; +#define RVU_SWITCH_FLAG_FW_READY BIT_ULL(0) + u64 flags; + u16 pcifunc; }; =20 struct rep_evtq_ent { @@ -1185,4 +1189,5 @@ int rvu_rep_pf_init(struct rvu *rvu); int rvu_rep_install_mcam_rules(struct rvu *rvu); void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena); int rvu_rep_notify_pfvf_state(struct rvu *rvu, u16 pcifunc, bool enable); +u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc); #endif /* RVU_H */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c b/drivers/= net/ethernet/marvell/octeontx2/af/rvu_rep.c index 4415d0ce9aef..078ba5bd2369 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c @@ -181,7 +181,7 @@ int rvu_mbox_handler_nix_lf_stats(struct rvu *rvu, return 0; } =20 -static u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc) +u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc) { int id; =20 @@ -428,6 +428,7 @@ int rvu_mbox_handler_esw_cfg(struct rvu *rvu, struct es= w_cfg_req *req, return 0; =20 rvu->rep_mode =3D req->ena; + memcpy(rvu->rswitch.switch_id, req->switch_id, MAX_PHYS_ITEM_ID_LEN); =20 if (!rvu->rep_mode) rvu_npc_free_mcam_entries(rvu, req->hdr.pcifunc, -1); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c b/dr= ivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c index fe143ad3f944..533ee8725e38 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c @@ -6,6 +6,20 @@ */ =20 #include "rvu.h" +#include "rvu_sw.h" + +u32 rvu_sw_port_id(struct rvu *rvu, u16 pcifunc) +{ + u16 port_id; + u16 rep_id; + + rep_id =3D rvu_rep_get_vlan_id(rvu, pcifunc); + + port_id =3D FIELD_PREP(GENMASK_ULL(31, 16), rep_id) | + FIELD_PREP(GENMASK_ULL(15, 0), pcifunc); + + return port_id; +} =20 int rvu_mbox_handler_swdev2af_notify(struct rvu *rvu, struct swdev2af_notify_req *req, diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h b/dr= ivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h index f28dba556d80..847a8da60d0a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h @@ -8,4 +8,7 @@ #ifndef RVU_SWITCH_H #define RVU_SWITCH_H =20 +/* RVU Switch */ +u32 rvu_sw_port_id(struct rvu *rvu, u16 pcifunc); + #endif diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net= /ethernet/marvell/octeontx2/nic/rep.c index b476733a0234..9200198be71f 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c @@ -399,8 +399,11 @@ static void rvu_rep_get_stats64(struct net_device *dev, =20 static int rvu_eswitch_config(struct otx2_nic *priv, u8 ena) { + struct devlink_port_attrs attrs =3D {}; struct esw_cfg_req *req; =20 + rvu_rep_devlink_set_switch_id(priv, &attrs.switch_id); + mutex_lock(&priv->mbox.lock); req =3D otx2_mbox_alloc_msg_esw_cfg(&priv->mbox); if (!req) { @@ -408,6 +411,7 @@ static int rvu_eswitch_config(struct otx2_nic *priv, u8= ena) return -ENOMEM; } req->ena =3D ena; + memcpy(req->switch_id, attrs.switch_id.id, attrs.switch_id.id_len); otx2_sync_mbox_msg(&priv->mbox); mutex_unlock(&priv->mbox.lock); return 0; --=20 2.43.0 From nobody Sun Feb 8 19:03:52 2026 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (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 B0D2633AD9D; Fri, 9 Jan 2026 10:31:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954706; cv=none; b=lttcZQ/IuP0Ogusf+goO8pMV3TOJBtSQfcjLMa8hUI+CSyvzsSHs7bXkr6wBjTkb8lwYn19dxPttuVcyPUVEcKCGTgFTiAccX5tn8QE8KwPFpD6f4fc1E/kVaCW0K/nHV1ke6K66FMWgWvWco/OT8S2ysdfBF63AU1tI9Deqp2U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954706; c=relaxed/simple; bh=MeOsaiOgaJ7llG6zhyBycOt5bALIZxtpbATHjBGU8aA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YHYuswZ+u8iLJx9Sf/HdiinrxO+TTrOu+AZzcZDh3rsznQ88bgf7J7W/wqA11x54OrTw7e+++7IO6nzcsMeRk2MSk1AHpGzLqFuiKSNCB94rGRLimYlR/0cgEAFcJ7uwWnlYeCRuTM0//pxU9NC1qjtNSkNSTugmZMFbmHMb4BI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=NkCS0Ppx; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="NkCS0Ppx" Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6092oer22938076; Fri, 9 Jan 2026 02:31:36 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=L L1KxUgzGDP8y4RXjiXMM8xOtX1TIqHpiot3Mpa55Gk=; b=NkCS0Ppx3JWxKZ09x UrMJrYGeQnZ2/fMTm+hTeezT/3oQag8yS7JFVcTnqqT88f11z+yn7xC236Nc7C36 PBHQv9gLfeVO4q/Y1IZmA1SIWjo+eeTNe5/pfVln8+CLDa9YEdsYD1nb2EQk88S6 I6bw16kGcffEcu5yG0mQkbCRkJiBWRnDOUQdo3E/agxAekZ+TiWtT7tSnvfvGx7v u9ctZD6QB5qePrgiRwwiYMy8DFmR3OcuP9GsZxbT6eHojtGPG4Y9ZqmySyFLwFoi mtimBWgp0MnwZeL8Jz56auFXVlMSsR7Ov44ziVzG1x77GKFJKPD8r6khFU8/17J9 thqnQ== Received: from dc6wp-exch02.marvell.com ([4.21.29.225]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4bhwh2vmvf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 09 Jan 2026 02:31:36 -0800 (PST) Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Fri, 9 Jan 2026 02:31:35 -0800 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Fri, 9 Jan 2026 02:31:35 -0800 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 7DABD3F7089; Fri, 9 Jan 2026 02:31:32 -0800 (PST) From: Ratheesh Kannoth To: , CC: , , , , , , "Ratheesh Kannoth" Subject: [PATCH net-next v3 05/10] octeontx2-af: switch: Enable Switch hw port for all channels Date: Fri, 9 Jan 2026 16:00:30 +0530 Message-ID: <20260109103035.2972893-6-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109103035.2972893-1-rkannoth@marvell.com> References: <20260109103035.2972893-1-rkannoth@marvell.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-Proofpoint-GUID: 4v9iy7unIIbP1p9ZEnxfYyARXIWqW-bo X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA5MDA3NiBTYWx0ZWRfX3cBoSrdOyOJl oRrjmaQFWPFZ+i4PpZONiE18SVLAtPO33MSkaAbFvEs0F6tCSItd/WqZJBkyjX0NBCyChg1YdjJ hdNygMaDawtGorn0OX0QR1rlqcaogd0NNFXnWIUFu7zrcesxy172dGOFokOiGU6ysWBIbq0uAep xOctmzPTZHd7kK7MhAw0DHfaWt8kSJ99dz8KGkVyYNNMK+abRcX2FRKGQggqQAMn4Z6KBw3NaoB I7OP3ShqBt2RlWwlEjBIy9Mc+7MUyNmxU9XF3lwTXc+DFfuMpcsVRZ/iEdl4uWptJqscLEBAtGF U5kOb1rln+hVT/ddcmQWAjU8FCt6vMHy8GB7/4Ssf7uXm4lyLIdZxuBaTjO6ZOq7wSuiWoUa13C Eg0w7taGaXuIKJ7GSRWcm6taIYeVUDvu5RzgW72f4aU7+Tt0QfBAM+LoLUifLtyTE2PgiHc9y9O GatEiY+VqguGwBipOXA== X-Authority-Analysis: v=2.4 cv=ROO+3oi+ c=1 sm=1 tr=0 ts=6960d908 cx=c_pps a=gIfcoYsirJbf48DBMSPrZA==:117 a=gIfcoYsirJbf48DBMSPrZA==:17 a=vUbySO9Y5rIA:10 a=VkNPw1HP01LnGYTKEx00:22 a=M5GUcnROAAAA:8 a=0Cqobd3ug1408HmlttkA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-ORIG-GUID: 4v9iy7unIIbP1p9ZEnxfYyARXIWqW-bo X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-09_03,2026-01-08_02,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Switch HW should be able to fwd packets to any link based on flow rules. Set txlink enable for all channels. Signed-off-by: Ratheesh Kannoth --- .../net/ethernet/marvell/octeontx2/af/mbox.h | 4 ++ .../ethernet/marvell/octeontx2/af/rvu_nix.c | 50 ++++++++++++++++--- .../marvell/octeontx2/af/rvu_npc_fs.c | 2 +- .../marvell/octeontx2/nic/otx2_txrx.h | 2 + 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net= /ethernet/marvell/octeontx2/af/mbox.h index 24703c27a352..00bacbc22052 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -1122,6 +1122,8 @@ struct nix_txsch_alloc_req { /* Scheduler queue count request at each level */ u16 schq_contig[NIX_TXSCH_LVL_CNT]; /* No of contiguous queues */ u16 schq[NIX_TXSCH_LVL_CNT]; /* No of non-contiguous queues */ +#define NIX_TXSCH_ALLOC_FLAG_PAN BIT_ULL(0) + u64 flags; }; =20 struct nix_txsch_alloc_rsp { @@ -1140,6 +1142,7 @@ struct nix_txsch_alloc_rsp { struct nix_txsch_free_req { struct mbox_msghdr hdr; #define TXSCHQ_FREE_ALL BIT_ULL(0) +#define TXSCHQ_FREE_PAN_TL1 BIT_ULL(1) u16 flags; /* Scheduler queue level to be freed */ u16 schq_lvl; @@ -1958,6 +1961,7 @@ struct npc_install_flow_req { u16 entry; u16 channel; u16 chan_mask; + u8 set_chanmask; u8 intf; u8 set_cntr; /* If counter is available set counter for this entry ? */ u8 default_rule; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/= net/ethernet/marvell/octeontx2/af/rvu_nix.c index e2cc33ad2b2c..9d9d59affd68 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c @@ -1586,7 +1586,7 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, if (err) goto free_mem; =20 - pfvf->sq_bmap =3D kcalloc(req->sq_cnt, sizeof(long), GFP_KERNEL); + pfvf->sq_bmap =3D kcalloc(req->sq_cnt, sizeof(long) * 16, GFP_KERNEL); if (!pfvf->sq_bmap) goto free_mem; =20 @@ -2106,11 +2106,14 @@ static int nix_check_txschq_alloc_req(struct rvu *r= vu, int lvl, u16 pcifunc, if (!req_schq) return 0; =20 - link =3D nix_get_tx_link(rvu, pcifunc); + if (req->flags & NIX_TXSCH_ALLOC_FLAG_PAN) + link =3D hw->cgx_links + hw->lbk_links + 1; + else + link =3D nix_get_tx_link(rvu, pcifunc); =20 /* For traffic aggregating scheduler level, one queue is enough */ if (lvl >=3D hw->cap.nix_tx_aggr_lvl) { - if (req_schq !=3D 1) + if (req_schq !=3D 1 && !(req->flags & NIX_TXSCH_ALLOC_FLAG_PAN)) return NIX_AF_ERR_TLX_ALLOC_FAIL; return 0; } @@ -2147,11 +2150,41 @@ static void nix_txsch_alloc(struct rvu *rvu, struct= nix_txsch *txsch, struct rvu_hwinfo *hw =3D rvu->hw; u16 pcifunc =3D rsp->hdr.pcifunc; int idx, schq; + bool alloc; =20 /* For traffic aggregating levels, queue alloc is based * on transmit link to which PF_FUNC is mapped to. */ if (lvl >=3D hw->cap.nix_tx_aggr_lvl) { + if (start !=3D end) { + idx =3D 0; + alloc =3D false; + for (schq =3D start; schq <=3D end; schq++, idx++) { + if (test_bit(schq, txsch->schq.bmap)) + continue; + + set_bit(schq, txsch->schq.bmap); + + /* A single TL queue is allocated each time */ + if (rsp->schq_contig[lvl]) { + alloc =3D true; + rsp->schq_contig_list[lvl][idx] =3D schq; + continue; + } + + if (rsp->schq[lvl]) { + alloc =3D true; + rsp->schq_list[lvl][idx] =3D schq; + continue; + } + } + + if (!alloc) + dev_err(rvu->dev, + "Could not allocate schq at lvl=3D%u start=3D%u end=3D%u\n", + lvl, start, end); + return; + } /* A single TL queue is allocated */ if (rsp->schq_contig[lvl]) { rsp->schq_contig[lvl] =3D 1; @@ -2268,11 +2301,14 @@ int rvu_mbox_handler_nix_txsch_alloc(struct rvu *rv= u, rsp->schq[lvl] =3D req->schq[lvl]; rsp->schq_contig[lvl] =3D req->schq_contig[lvl]; =20 - link =3D nix_get_tx_link(rvu, pcifunc); + if (req->flags & NIX_TXSCH_ALLOC_FLAG_PAN) + link =3D hw->cgx_links + hw->lbk_links + 1; + else + link =3D nix_get_tx_link(rvu, pcifunc); =20 if (lvl >=3D hw->cap.nix_tx_aggr_lvl) { start =3D link; - end =3D link; + end =3D link + !!(req->flags & NIX_TXSCH_ALLOC_FLAG_PAN); } else if (hw->cap.nix_fixed_txschq_mapping) { nix_get_txschq_range(rvu, pcifunc, link, &start, &end); } else { @@ -2637,7 +2673,9 @@ static int nix_txschq_free_one(struct rvu *rvu, schq =3D req->schq; txsch =3D &nix_hw->txsch[lvl]; =20 - if (lvl >=3D hw->cap.nix_tx_aggr_lvl || schq >=3D txsch->schq.max) + if ((lvl >=3D hw->cap.nix_tx_aggr_lvl && + !(req->flags & TXSCHQ_FREE_PAN_TL1)) || + schq >=3D txsch->schq.max) return 0; =20 pfvf_map =3D txsch->pfvf_map; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drive= rs/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c index 3d6f780635a5..925b0b02279e 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c @@ -1469,7 +1469,7 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu, } =20 /* ignore chan_mask in case pf func is not AF, revisit later */ - if (!is_pffunc_af(req->hdr.pcifunc)) + if (!req->set_chanmask && !is_pffunc_af(req->hdr.pcifunc)) req->chan_mask =3D 0xFFF; =20 err =3D npc_check_unsupported_flows(rvu, req->features, req->intf); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h b/drive= rs/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h index acf259d72008..73a98b94426b 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h @@ -78,6 +78,8 @@ struct otx2_rcv_queue { struct sg_list { u16 num_segs; u16 flags; + u16 cq_idx; + u16 len; u64 skb; u64 size[OTX2_MAX_FRAGS_IN_SQE]; u64 dma_addr[OTX2_MAX_FRAGS_IN_SQE]; --=20 2.43.0 From nobody Sun Feb 8 19:03:52 2026 Received: from mx0a-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (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 6031333B6F6; Fri, 9 Jan 2026 10:31:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954710; cv=none; b=EhspIvzI2f8ZA74FwifwnfQGVu/0fnOpf+NhUVRJR0+TxOf5t42J6uFPm3kb90+O6r5Y1/gx8XVtrl9+TlSepPDYRXSLkmyWz3mkzN1faTojaazMfzZKp4WkJXvCcXDBo4UlFLqQ6SilFadHnGRc7mywk2sPB/mVZsbO2uToJKI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954710; c=relaxed/simple; bh=4XAmYoZ21y8NKb53o49wIwTc30wepgv/ny3+RJxWAOg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tWsVt58sea1nvjMp6GDrzvcV3amyoMEK1fdeX5ud3p0nK0RtvdtAMICCqAU/lfsyvYbyHnY1HsuaiHbbLluFYs5WHn9pYJGrTxXH5EboQRFFuwOzG8t9wO0TZ/5bGnnixFhj0uoyg+fbf6P7FRKX7xU8iEizowTp8LrG83PCj1E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=YOVuLBep; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="YOVuLBep" Received: from pps.filterd (m0431384.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 608NSs3T832412; Fri, 9 Jan 2026 02:31:39 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=+ /y/wrfklGhqQt+x0d5xBO45MM5I/V5bNVjuIISuyGQ=; b=YOVuLBepi5iprj/vw sKKN5j/sj4aTYCRHRK5I8BbxNZy6hgVznjsPacStL6TiivXDNOyHFDpi6MMmxqJi tHKXKzsPwvgTm8xhB6JzvngO4R8ahS2e1whN2N89WWV5GFKGdVU6MzggzDzsSyI5 OkEpFJi61iTDrgRZNvtrs7VBMfPkHhtTzoIl4OjZc5J4GygubioI6YQUirS1o/F0 FOaObd9uqL8b525o0iiCbZ7FBEXrDRgmJN/hEualm9kh+4Bdee0rGPY9pqGb9YHU aUIzspA8GfkSCczAJto4+egKj0Hc1auAEzEXCoss8nlN/rcAuiRM+3K4w71Nau+2 J35Cg== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4bjp9r970d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 09 Jan 2026 02:31:39 -0800 (PST) Received: from DC5-EXCH05.marvell.com (10.69.176.209) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Fri, 9 Jan 2026 02:31:53 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Fri, 9 Jan 2026 02:31:53 -0800 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id A00083F7089; Fri, 9 Jan 2026 02:31:35 -0800 (PST) From: Ratheesh Kannoth To: , CC: , , , , , , "Ratheesh Kannoth" Subject: [PATCH net-next v3 06/10] octeontx2-pf: switch: Register for notifier chains. Date: Fri, 9 Jan 2026 16:00:31 +0530 Message-ID: <20260109103035.2972893-7-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109103035.2972893-1-rkannoth@marvell.com> References: <20260109103035.2972893-1-rkannoth@marvell.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-Authority-Analysis: v=2.4 cv=e58LiKp/ c=1 sm=1 tr=0 ts=6960d90b cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=vUbySO9Y5rIA:10 a=VkNPw1HP01LnGYTKEx00:22 a=M5GUcnROAAAA:8 a=8MKmJXxhQqrjLFTQZSMA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-ORIG-GUID: ytZGaxibuNec32VDTC23_JQsoPgQqTn- X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA5MDA3NiBTYWx0ZWRfXy54kagMOR0wG ZNPnUu7IP3wDhaT17c5rA5riHhv3492aJWn/0ICcK3UOw7XwrtztqPtj9hn7xjQ95iRJY5UE3PJ uPkIiuLo/WHkst6URvo466ZHSHFFVMDq5lqrmb7L2Ul3mJX99DlY/EJRGlVGezsNIJ/TIaTDDqT YlBl6r9lrgeNMY5PP7aNaIaPi3fgVV+NfriUgr68pmE5YoqGFs8Wr33vbk5SwdsqmIKbc8xLq9l 71zZg4qx/cptDg5a2SWc9iqAoUHu6YRW3g0/lqlod81PvlfbVuetE+OC0/f/uTua8QFCma/CPy1 gXaKdld5ytuQeBeveQpwkSFRYvlMZgHVGYzeyaSEtUmKJgNF6fpz7sztjudc4eWJCSZRiNilcL/ WDN9/ZxfH8AL7xtLeK/Qwpeu8m8uz5/IdzedHiSw5u4mSu6rw9bVOKgZzzcmhLwoQeht5vAwWBw JFlLUzEYDyX3sKBGM7A== X-Proofpoint-GUID: ytZGaxibuNec32VDTC23_JQsoPgQqTn- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-09_03,2026-01-08_02,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Switchdev flow table needs information on 5tuple information to mangle/to find egress ports etc. PF driver registers for fdb/fib/netdev notifier chains to listen to events. These events are parsed and sent to switchdev HW through mbox events. Signed-off-by: Ratheesh Kannoth --- .../net/ethernet/marvell/octeontx2/nic/rep.c | 7 + .../marvell/octeontx2/nic/switch/sw_nb.c | 622 +++++++++++++++++- .../marvell/octeontx2/nic/switch/sw_nb.h | 23 +- 3 files changed, 648 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net= /ethernet/marvell/octeontx2/nic/rep.c index 9200198be71f..0edbc56ae693 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c @@ -15,6 +15,7 @@ #include "cn10k.h" #include "otx2_reg.h" #include "rep.h" +#include "switch/sw_nb.h" =20 #define DRV_NAME "rvu_rep" #define DRV_STRING "Marvell RVU Representor Driver" @@ -399,6 +400,7 @@ static void rvu_rep_get_stats64(struct net_device *dev, =20 static int rvu_eswitch_config(struct otx2_nic *priv, u8 ena) { + struct net_device *netdev =3D priv->netdev; struct devlink_port_attrs attrs =3D {}; struct esw_cfg_req *req; =20 @@ -414,6 +416,11 @@ static int rvu_eswitch_config(struct otx2_nic *priv, u= 8 ena) memcpy(req->switch_id, attrs.switch_id.id, attrs.switch_id.id_len); otx2_sync_mbox_msg(&priv->mbox); mutex_unlock(&priv->mbox.lock); + +#if IS_ENABLED(CONFIG_OCTEONTX_SWITCH) + ena ? sw_nb_register(netdev) : sw_nb_unregister(netdev); +#endif + return 0; } =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c index 2d14a0590c5d..ce565fe7035c 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c @@ -4,14 +4,632 @@ * Copyright (C) 2026 Marvell. * */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../otx2_reg.h" +#include "../otx2_common.h" +#include "../otx2_struct.h" +#include "../cn10k.h" #include "sw_nb.h" +#include "sw_fdb.h" +#include "sw_fib.h" +#include "sw_fl.h" + +static const char *sw_nb_cmd2str[OTX2_CMD_MAX] =3D { + [OTX2_DEV_UP] =3D "OTX2_DEV_UP", + [OTX2_DEV_DOWN] =3D "OTX2_DEV_DOWN", + [OTX2_DEV_CHANGE] =3D "OTX2_DEV_CHANGE", + [OTX2_NEIGH_UPDATE] =3D "OTX2_NEIGH_UPDATE", + [OTX2_FIB_ENTRY_REPLACE] =3D "OTX2_FIB_ENTRY_REPLACE", + [OTX2_FIB_ENTRY_ADD] =3D "OTX2_FIB_ENTRY_ADD", + [OTX2_FIB_ENTRY_DEL] =3D "OTX2_FIB_ENTRY_DEL", + [OTX2_FIB_ENTRY_APPEND] =3D "OTX2_FIB_ENTRY_APPEND", +}; + +const char *sw_nb_get_cmd2str(int cmd) +{ + return sw_nb_cmd2str[cmd]; +} +EXPORT_SYMBOL(sw_nb_get_cmd2str); + +static bool sw_nb_is_cavium_dev(struct net_device *netdev) +{ + struct pci_dev *pdev; + struct device *dev; + + dev =3D netdev->dev.parent; + if (!dev) + return false; + + pdev =3D container_of(dev, struct pci_dev, dev); + if (pdev->vendor !=3D PCI_VENDOR_ID_CAVIUM) + return false; + + return true; +} + +static int sw_nb_check_slaves(struct net_device *dev, + struct netdev_nested_priv *priv) +{ + int *cnt; + + if (!priv->flags) + return 0; + + priv->flags &=3D sw_nb_is_cavium_dev(dev); + if (priv->flags) { + cnt =3D priv->data; + (*cnt)++; + } + + return 0; +} + +bool sw_nb_is_valid_dev(struct net_device *netdev) +{ + struct netdev_nested_priv priv; + struct net_device *br; + int cnt =3D 0; + + priv.flags =3D true; + priv.data =3D &cnt; + + if (netif_is_bridge_master(netdev) || is_vlan_dev(netdev)) { + netdev_walk_all_lower_dev(netdev, sw_nb_check_slaves, &priv); + return priv.flags && !!*(int *)priv.data; + } + + if (netif_is_bridge_port(netdev)) { + rcu_read_lock(); + br =3D netdev_master_upper_dev_get_rcu(netdev); + if (!br) { + rcu_read_unlock(); + return false; + } + + netdev_walk_all_lower_dev(br, sw_nb_check_slaves, &priv); + rcu_read_unlock(); + return priv.flags && !!*(int *)priv.data; + } + + return sw_nb_is_cavium_dev(netdev); +} + +static int sw_nb_fdb_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev =3D switchdev_notifier_info_to_dev(ptr); + struct switchdev_notifier_fdb_info *fdb_info =3D ptr; + + if (!sw_nb_is_valid_dev(dev)) + return NOTIFY_DONE; + + switch (event) { + case SWITCHDEV_FDB_ADD_TO_DEVICE: + if (fdb_info->is_local) + break; + break; + + case SWITCHDEV_FDB_DEL_TO_DEVICE: + if (fdb_info->is_local) + break; + break; + + default: + return NOTIFY_DONE; + } + + return NOTIFY_DONE; +} + +static struct notifier_block sw_nb_fdb =3D { + .notifier_call =3D sw_nb_fdb_event, +}; + +static void __maybe_unused +sw_nb_fib_event_dump(struct net_device *dev, unsigned long event, void *pt= r) +{ + struct fib_entry_notifier_info *fen_info =3D ptr; + struct fib_nh *fib_nh; + struct fib_info *fi; + int i; + + netdev_info(dev, + "%s:%d FIB event=3D%lu dst=3D%#x dstlen=3D%u type=3D%u\n", + __func__, __LINE__, + event, fen_info->dst, fen_info->dst_len, + fen_info->type); + + fi =3D fen_info->fi; + if (!fi) + return; + + fib_nh =3D fi->fib_nh; + for (i =3D 0; i < fi->fib_nhs; i++, fib_nh++) + netdev_info(dev, "%s:%d dev=3D%s saddr=3D%#x gw=3D%#x\n", + __func__, __LINE__, + fib_nh->fib_nh_dev->name, + fib_nh->nh_saddr, fib_nh->fib_nh_gw4); +} + +#define SWITCH_NB_FIB_EVENT_DUMP(...) \ + sw_nb_fib_event_dump(__VA_ARGS__) + +static int sw_nb_fib_event_to_otx2_event(int event) +{ + switch (event) { + case FIB_EVENT_ENTRY_REPLACE: + return OTX2_FIB_ENTRY_REPLACE; + case FIB_EVENT_ENTRY_ADD: + return OTX2_FIB_ENTRY_ADD; + case FIB_EVENT_ENTRY_DEL: + return OTX2_FIB_ENTRY_DEL; + default: + break; + } + + return -1; +} + +static int sw_nb_fib_event(struct notifier_block *nb, + unsigned long event, void *ptr) +{ + struct fib_entry_notifier_info *fen_info =3D ptr; + struct net_device *dev, *pf_dev =3D NULL; + struct fib_notifier_info *info =3D ptr; + struct fib_entry *entries, *iter; + struct netdev_hw_addr *dev_addr; + struct net_device *lower; + struct list_head *lh; + struct neighbour *neigh; + struct fib_nh *fib_nh; + struct fib_info *fi; + struct otx2_nic *pf; + __be32 *haddr; + int hcnt =3D 0; + int cnt, i; + + if (info->family !=3D AF_INET) + return NOTIFY_DONE; + + switch (event) { + case FIB_EVENT_ENTRY_REPLACE: + case FIB_EVENT_ENTRY_ADD: + case FIB_EVENT_ENTRY_DEL: + break; + default: + return NOTIFY_DONE; + } + + /* Process only UNICAST routes add or del */ + if (fen_info->type !=3D RTN_UNICAST) + return NOTIFY_DONE; + + fi =3D fen_info->fi; + + if (!fi) + return NOTIFY_DONE; + + if (fi->fib_nh_is_v6) + return NOTIFY_DONE; + + entries =3D kcalloc(fi->fib_nhs, sizeof(*entries), GFP_ATOMIC); + if (!entries) + return NOTIFY_DONE; + + haddr =3D kcalloc(fi->fib_nhs, sizeof(__be32), GFP_ATOMIC); + if (!haddr) { + kfree(entries); + return NOTIFY_DONE; + } + + iter =3D entries; + fib_nh =3D fi->fib_nh; + for (i =3D 0; i < fi->fib_nhs; i++, fib_nh++) { + dev =3D fib_nh->fib_nh_dev; + + if (!dev) + continue; + + if (dev->type !=3D ARPHRD_ETHER) + continue; + + if (!sw_nb_is_valid_dev(dev)) + continue; + + iter->cmd =3D sw_nb_fib_event_to_otx2_event(event); + iter->dst =3D fen_info->dst; + iter->dst_len =3D fen_info->dst_len; + iter->gw =3D be32_to_cpu(fib_nh->fib_nh_gw4); + + netdev_dbg(dev, + "%s:%d FIB route Rule cmd=3D%lld dst=3D%#x dst_len=3D%d gw=3D%#x\n", + __func__, __LINE__, + iter->cmd, iter->dst, iter->dst_len, iter->gw); + + pf_dev =3D dev; + if (netif_is_bridge_master(dev)) { + iter->bridge =3D 1; + netdev_for_each_lower_dev(dev, lower, lh) { + pf_dev =3D lower; + break; + } + } else if (is_vlan_dev(dev)) { + iter->vlan_valid =3D 1; + pf_dev =3D vlan_dev_real_dev(dev); + iter->vlan_tag =3D vlan_dev_vlan_id(dev); + } + + pf =3D netdev_priv(pf_dev); + iter->port_id =3D pf->pcifunc; + + if (!fib_nh->fib_nh_gw4) { + if (iter->dst || iter->dst_len) + iter++; + + continue; + } + iter->gw_valid =3D 1; + + if (fib_nh->nh_saddr) + haddr[hcnt++] =3D fib_nh->nh_saddr; + + rcu_read_lock(); + neigh =3D ip_neigh_gw4(fib_nh->fib_nh_dev, fib_nh->fib_nh_gw4); + if (!neigh) { + rcu_read_unlock(); + iter++; + continue; + } + + if (is_valid_ether_addr(neigh->ha)) { + iter->mac_valid =3D 1; + ether_addr_copy(iter->mac, neigh->ha); + } + + iter++; + rcu_read_unlock(); + } + + cnt =3D iter - entries; + if (!cnt) { + kfree(entries); + kfree(haddr); + return NOTIFY_DONE; + } =20 -int sw_nb_unregister(void) + if (!hcnt) { + kfree(haddr); + return NOTIFY_DONE; + } + + entries =3D kcalloc(hcnt, sizeof(*entries), GFP_ATOMIC); + if (!entries) + return NOTIFY_DONE; + + iter =3D entries; + + for (i =3D 0; i < hcnt; i++, iter++) { + iter->cmd =3D sw_nb_fib_event_to_otx2_event(event); + iter->dst =3D be32_to_cpu(haddr[i]); + iter->dst_len =3D 32; + iter->mac_valid =3D 1; + iter->host =3D 1; + iter->port_id =3D pf->pcifunc; + + for_each_dev_addr(pf_dev, dev_addr) { + ether_addr_copy(iter->mac, dev_addr->addr); + break; + } + + netdev_dbg(dev, + "%s:%d FIB host Rule cmd=3D%lld dst=3D%#x dst_len=3D%d gw=3D%#x %s\= n", + __func__, __LINE__, + iter->cmd, iter->dst, iter->dst_len, iter->gw, dev->name); + } + + kfree(haddr); + return NOTIFY_DONE; +} + +static struct notifier_block sw_nb_fib =3D { + .notifier_call =3D sw_nb_fib_event, +}; + +static int sw_nb_net_event(struct notifier_block *nb, + unsigned long event, void *ptr) +{ + struct net_device *lower, *pf_dev; + struct neighbour *n =3D ptr; + struct fib_entry *entry; + struct list_head *iter; + struct otx2_nic *pf; + + switch (event) { + case NETEVENT_NEIGH_UPDATE: + if (n->tbl->family !=3D AF_INET) + break; + + if (n->tbl !=3D &arp_tbl) + break; + + if (!sw_nb_is_valid_dev(n->dev)) + break; + + entry =3D kcalloc(1, sizeof(*entry), GFP_ATOMIC); + if (!entry) + break; + + entry->cmd =3D OTX2_NEIGH_UPDATE; + entry->dst =3D be32_to_cpu(*(__be32 *)n->primary_key); + entry->dst_len =3D n->tbl->key_len * 8; + entry->mac_valid =3D 1; + entry->nud_state =3D n->nud_state; + ether_addr_copy(entry->mac, n->ha); + + pf_dev =3D n->dev; + if (netif_is_bridge_master(n->dev)) { + entry->bridge =3D 1; + netdev_for_each_lower_dev(n->dev, lower, iter) { + pf_dev =3D lower; + break; + } + } else if (is_vlan_dev(n->dev)) { + entry->vlan_valid =3D 1; + pf_dev =3D vlan_dev_real_dev(n->dev); + entry->vlan_tag =3D vlan_dev_vlan_id(n->dev); + } + + pf =3D netdev_priv(pf_dev); + entry->port_id =3D pf->pcifunc; + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block sw_nb_netevent =3D { + .notifier_call =3D sw_nb_net_event, + +}; + +static int sw_nb_inetaddr_event_to_otx2_event(int event) { + switch (event) { + case NETDEV_CHANGE: + return OTX2_DEV_CHANGE; + case NETDEV_UP: + return OTX2_DEV_UP; + case NETDEV_DOWN: + return OTX2_DEV_DOWN; + default: + break; + } + return -1; +} + +static int sw_nb_inetaddr_event(struct notifier_block *nb, + unsigned long event, void *ptr) +{ + struct in_ifaddr *ifa =3D (struct in_ifaddr *)ptr; + struct net_device *dev =3D ifa->ifa_dev->dev; + struct net_device *lower, *pf_dev; + struct netdev_hw_addr *dev_addr; + struct fib_entry *entry; + struct in_device *idev; + struct list_head *iter; + struct otx2_nic *pf; + + if (event !=3D NETDEV_CHANGE && + event !=3D NETDEV_UP && + event !=3D NETDEV_DOWN) { + return NOTIFY_DONE; + } + + if (!sw_nb_is_valid_dev(dev)) + return NOTIFY_DONE; + + idev =3D __in_dev_get_rtnl(dev); + if (!idev || !idev->ifa_list) + return NOTIFY_DONE; + + entry =3D kcalloc(1, sizeof(*entry), GFP_ATOMIC); + entry->cmd =3D sw_nb_inetaddr_event_to_otx2_event(event); + entry->dst =3D be32_to_cpu(ifa->ifa_address); + entry->dst_len =3D 32; + entry->mac_valid =3D 1; + entry->host =3D 1; + + pf_dev =3D dev; + if (netif_is_bridge_master(dev)) { + entry->bridge =3D 1; + netdev_for_each_lower_dev(dev, lower, iter) { + pf_dev =3D lower; + break; + } + } else if (is_vlan_dev(dev)) { + entry->vlan_valid =3D 1; + pf_dev =3D vlan_dev_real_dev(dev); + entry->vlan_tag =3D vlan_dev_vlan_id(dev); + } + + pf =3D netdev_priv(pf_dev); + entry->port_id =3D pf->pcifunc; + + for_each_dev_addr(dev, dev_addr) { + ether_addr_copy(entry->mac, dev_addr->addr); + break; + } + + netdev_dbg(dev, + "%s:%d pushing inetaddr event from HOST interface address %#x, %pM, %= s\n", + __func__, __LINE__, entry->dst, entry->mac, dev->name); + + return NOTIFY_DONE; +} + +static struct notifier_block sw_nb_inetaddr =3D { + .notifier_call =3D sw_nb_inetaddr_event, +}; + +static int sw_nb_netdev_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev =3D netdev_notifier_info_to_dev(ptr); + struct netdev_hw_addr *dev_addr; + struct net_device *pf_dev; + struct in_ifaddr *ifa; + struct fib_entry *entry; + struct in_device *idev; + struct otx2_nic *pf; + struct list_head *iter; + struct net_device *lower; + + if (event !=3D NETDEV_CHANGE && + event !=3D NETDEV_UP && + event !=3D NETDEV_DOWN) { + return NOTIFY_DONE; + } + + if (!sw_nb_is_valid_dev(dev)) + return NOTIFY_DONE; + + idev =3D __in_dev_get_rtnl(dev); + if (!idev || !idev->ifa_list) + return NOTIFY_DONE; + + ifa =3D rtnl_dereference(idev->ifa_list); + + entry =3D kcalloc(1, sizeof(*entry), GFP_KERNEL); + entry->cmd =3D sw_nb_inetaddr_event_to_otx2_event(event); + entry->dst =3D be32_to_cpu(ifa->ifa_address); + entry->dst_len =3D 32; + entry->mac_valid =3D 1; + entry->host =3D 1; + + pf_dev =3D dev; + if (netif_is_bridge_master(dev)) { + entry->bridge =3D 1; + netdev_for_each_lower_dev(dev, lower, iter) { + pf_dev =3D lower; + break; + } + } else if (is_vlan_dev(dev)) { + entry->vlan_valid =3D 1; + pf_dev =3D vlan_dev_real_dev(dev); + entry->vlan_tag =3D vlan_dev_vlan_id(dev); + } + + pf =3D netdev_priv(pf_dev); + entry->port_id =3D pf->pcifunc; + + for_each_dev_addr(dev, dev_addr) { + ether_addr_copy(entry->mac, dev_addr->addr); + break; + } + + netdev_dbg(dev, + "%s:%d pushing netdev event from HOST interface address %#x, %pM, dev= =3D%s\n", + __func__, __LINE__, entry->dst, entry->mac, dev->name); + + return NOTIFY_DONE; +} + +static struct notifier_block sw_nb_netdev =3D { + .notifier_call =3D sw_nb_netdev_event, +}; + +int sw_nb_unregister(struct net_device *netdev) +{ + int err; + + err =3D unregister_switchdev_notifier(&sw_nb_fdb); + + if (err) + netdev_err(netdev, "Failed to unregister switchdev nb\n"); + + err =3D unregister_fib_notifier(&init_net, &sw_nb_fib); + if (err) + netdev_err(netdev, "Failed to unregister fib nb\n"); + + err =3D unregister_netevent_notifier(&sw_nb_netevent); + if (err) + netdev_err(netdev, "Failed to unregister netevent\n"); + + err =3D unregister_inetaddr_notifier(&sw_nb_inetaddr); + if (err) + netdev_err(netdev, "Failed to unregister addr event\n"); + + err =3D unregister_netdevice_notifier(&sw_nb_netdev); + if (err) + netdev_err(netdev, "Failed to unregister netdev notifier\n"); + + sw_fl_deinit(); + sw_fib_deinit(); + sw_fdb_deinit(); + return 0; } +EXPORT_SYMBOL(sw_nb_unregister); =20 -int sw_nb_register(void) +int sw_nb_register(struct net_device *netdev) { + int err; + + sw_fdb_init(); + sw_fib_init(); + sw_fl_init(); + + err =3D register_switchdev_notifier(&sw_nb_fdb); + if (err) { + netdev_err(netdev, "Failed to register switchdev nb\n"); + return err; + } + + err =3D register_fib_notifier(&init_net, &sw_nb_fib, NULL, NULL); + if (err) { + netdev_err(netdev, "Failed to register fb notifier block"); + goto err1; + } + + err =3D register_netevent_notifier(&sw_nb_netevent); + if (err) { + netdev_err(netdev, "Failed to register netevent\n"); + goto err2; + } + + err =3D register_inetaddr_notifier(&sw_nb_inetaddr); + if (err) { + netdev_err(netdev, "Failed to register addr event\n"); + goto err3; + } + + err =3D register_netdevice_notifier(&sw_nb_netdev); + if (err) { + netdev_err(netdev, "Failed to register netdevice nb\n"); + goto err4; + } + return 0; + +err4: + unregister_inetaddr_notifier(&sw_nb_inetaddr); + +err3: + unregister_netevent_notifier(&sw_nb_netevent); + +err2: + unregister_fib_notifier(&init_net, &sw_nb_fib); + +err1: + unregister_switchdev_notifier(&sw_nb_fdb); + return err; } +EXPORT_SYMBOL(sw_nb_register); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.h b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.h index 5f744cc3ecbb..81a54cb28ce2 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.h @@ -7,7 +7,26 @@ #ifndef SW_NB_H_ #define SW_NB_H_ =20 -int sw_nb_register(void); -int sw_nb_unregister(void); +enum { + OTX2_DEV_UP =3D 1, + OTX2_DEV_DOWN, + OTX2_DEV_CHANGE, + OTX2_NEIGH_UPDATE, + OTX2_FIB_ENTRY_REPLACE, + OTX2_FIB_ENTRY_ADD, + OTX2_FIB_ENTRY_DEL, + OTX2_FIB_ENTRY_APPEND, + OTX2_CMD_MAX, +}; + +int sw_nb_register(struct net_device *netdev); +int sw_nb_unregister(struct net_device *netdev); +bool sw_nb_is_valid_dev(struct net_device *netdev); + +int otx2_mbox_up_handler_af2pf_fdb_refresh(struct otx2_nic *pf, + struct af2pf_fdb_refresh_req *req, + struct msg_rsp *rsp); + +const char *sw_nb_get_cmd2str(int cmd); =20 #endif // SW_NB_H_ --=20 2.43.0 From nobody Sun Feb 8 19:03:52 2026 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (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 DF53933B940; Fri, 9 Jan 2026 10:31:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954712; cv=none; b=k3nteNyJcR90r0yWMWMcl6inU/TLpgJ/PMfJpNvLM507oEm+v6NYVl7QdpLtRJD68h4EczTqzduQn2bSw+uO0SYwXWh2cHYb2ej5RuyVYNCBs467kB0ySUlzUZLy6wnAz4iSIRIY/0iuyaokBr+RFZ6tYR4fOBs8B9NwucUmNHM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954712; c=relaxed/simple; bh=ONpyeSJ4R/S9DX4kJSbgbvCffb7gEjo1nsjoXd8RHOw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VavqOI6HHqt2zZWKMpVViA09KNqc2ssnJtIfCx3yZVL1wTKSVDVQ6FiAjuce2/gIHjTp4JSgL4pTbrkVMyXvlt4lIYH5KdwKZ90dx3Q3LQ25zDqbhJnEjoL+GLAk+ekrva4AkXuWstyjZudX27SfbbBZY21NDXM9DMZB2N1xlIo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=ZZg8WXYe; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="ZZg8WXYe" Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6093EZqg2938365; Fri, 9 Jan 2026 02:31:42 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=n L/FaaAb7LBDAKquHGbF3eSw7/ajs7IfOmO2Hl8/l3k=; b=ZZg8WXYe4Yi4gTR5n 0m8Nxhl2KodLZuWEjj8kCHvtZcFmlwmXt2xnZ2+6NgQ3opKZNTxh8ijowlWvQhtw wBnGsqdWYSag8VhcmisyNLhOsviVeRq337WZ20kgZZw3e07itlMYCy8WLSw0FyPi 7mKmJk1FEXMBcjSd+w9BzBHJ1MXxjwB/3kNgb0hi1bAiMgXU08BUdt0kv785SoDM 6XElljwv9bqS32chinepffD8NuengGQkVsS5oPohKXmHEDQINp6zojBJfmUasdwK 8GITovESASvtcQmohpwRaNPHF0f4gyeYVHZWLuIuVfJz1HeKYlR9DOV2In7Pw7+0 p4T/A== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4bhwh2vmvw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 09 Jan 2026 02:31:42 -0800 (PST) Received: from DC5-EXCH05.marvell.com (10.69.176.209) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Fri, 9 Jan 2026 02:31:56 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Fri, 9 Jan 2026 02:31:56 -0800 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id EDA9B5B692B; Fri, 9 Jan 2026 02:31:38 -0800 (PST) From: Ratheesh Kannoth To: , CC: , , , , , , "Ratheesh Kannoth" Subject: [PATCH net-next v3 07/10] octeontx2: switch: L2 offload support Date: Fri, 9 Jan 2026 16:00:32 +0530 Message-ID: <20260109103035.2972893-8-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109103035.2972893-1-rkannoth@marvell.com> References: <20260109103035.2972893-1-rkannoth@marvell.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-Proofpoint-GUID: O1o5PlQPgeXXWR8hof97moDsUunYDK5S X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA5MDA3NiBTYWx0ZWRfXyLIHaQYWSG+h IGS6I5/W3gQFCBsNHQCbxKZQPwt7C5N2B2NGFhXNalVSeE63e6q3Ioyd8Udu/azj8R7vj1KnCZ5 b5ehi3HgHIn6O3kSH3TtCmzBjrt5RcXcUGVnKGt0QzqBsFsMbk+oAa4PhjzsEds7KP+B6j7wagt 30CLPPU6HcFdxfg/LduW9yrXAt+DTsjb1nMOocflBD29DDx7SfKI/YKy9xg86AiIbNdvwXcz55m GA8+k9U6BTiPow49Ld44utnSmjSfKbwtWKfFgOc6/+bR86kmZhoeZ0MVcyGwFu+r5Tx9c0T+0jq vcvwI+c0DbYsHxU0RSHCWwm1AM8Vzzvr1MS3k3mxETpkIA7Oxcno4R22EFcRid76yR/2nrbP9ZL 7IYZr4TwxfKaafhTh/0AC20jV9NZ5XSvdYatHGlbTNfEOuUNDcyGDSvJAtW4zobXzqRNGIAIgTp qgIaGqOk/gxUzW4N/Zg== X-Authority-Analysis: v=2.4 cv=ROO+3oi+ c=1 sm=1 tr=0 ts=6960d90e cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=vUbySO9Y5rIA:10 a=VkNPw1HP01LnGYTKEx00:22 a=M5GUcnROAAAA:8 a=zjSZ3cS-AAAA:8 a=cAmSjuAziB4ZO2rpmfEA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 a=ZdzWmiyDu4ucoLeQK2uw:22 X-Proofpoint-ORIG-GUID: O1o5PlQPgeXXWR8hof97moDsUunYDK5S X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-09_03,2026-01-08_02,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Linux bridge fdb events are parsed to decide on DMAC to fwd packets. Switchdev HW flow table is filled with this information. Once populated, all packet with DMAC will be accelerated. Signed-off-by: Ratheesh Kannoth --- .../net/ethernet/marvell/octeontx2/af/rvu.c | 1 + .../marvell/octeontx2/af/switch/rvu_sw.c | 18 +- .../marvell/octeontx2/af/switch/rvu_sw_l2.c | 270 ++++++++++++++++++ .../marvell/octeontx2/af/switch/rvu_sw_l2.h | 2 + .../ethernet/marvell/octeontx2/nic/otx2_vf.c | 17 ++ .../marvell/octeontx2/nic/switch/sw_fdb.c | 127 ++++++++ .../marvell/octeontx2/nic/switch/sw_fdb.h | 5 + .../marvell/octeontx2/nic/switch/sw_nb.c | 5 +- 8 files changed, 441 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/= ethernet/marvell/octeontx2/af/rvu.c index 6b61742a61b1..95decbc5fc0d 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -2460,6 +2460,7 @@ static void __rvu_mbox_up_handler(struct rvu_work *mw= ork, int type) =20 switch (msg->id) { case MBOX_MSG_CGX_LINK_EVENT: + case MBOX_MSG_AF2PF_FDB_REFRESH: break; default: if (msg->rc) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c b/dr= ivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c index 533ee8725e38..b66f9c2eb981 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c @@ -7,6 +7,8 @@ =20 #include "rvu.h" #include "rvu_sw.h" +#include "rvu_sw_l2.h" +#include "rvu_sw_fl.h" =20 u32 rvu_sw_port_id(struct rvu *rvu, u16 pcifunc) { @@ -16,7 +18,7 @@ u32 rvu_sw_port_id(struct rvu *rvu, u16 pcifunc) rep_id =3D rvu_rep_get_vlan_id(rvu, pcifunc); =20 port_id =3D FIELD_PREP(GENMASK_ULL(31, 16), rep_id) | - FIELD_PREP(GENMASK_ULL(15, 0), pcifunc); + FIELD_PREP(GENMASK_ULL(15, 0), pcifunc); =20 return port_id; } @@ -25,5 +27,17 @@ int rvu_mbox_handler_swdev2af_notify(struct rvu *rvu, struct swdev2af_notify_req *req, struct msg_rsp *rsp) { - return 0; + int rc =3D 0; + + switch (req->msg_type) { + case SWDEV2AF_MSG_TYPE_FW_STATUS: + rc =3D rvu_sw_l2_init_offl_wq(rvu, req->pcifunc, req->fw_up); + break; + + case SWDEV2AF_MSG_TYPE_REFRESH_FDB: + rc =3D rvu_sw_l2_fdb_list_entry_add(rvu, req->pcifunc, req->mac); + break; + } + + return rc; } diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.c b= /drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.c index 5f805bfa81ed..f99c9e86a25c 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.c @@ -4,11 +4,281 @@ * Copyright (C) 2026 Marvell. * */ + +#include #include "rvu.h" +#include "rvu_sw.h" +#include "rvu_sw_l2.h" + +#define M(_name, _id, _fn_name, _req_type, _rsp_type) \ +static struct _req_type __maybe_unused \ +*otx2_mbox_alloc_msg_ ## _fn_name(struct rvu *rvu, int devid) \ +{ \ + struct _req_type *req; \ + \ + req =3D (struct _req_type *)otx2_mbox_alloc_msg_rsp( \ + &rvu->afpf_wq_info.mbox_up, devid, sizeof(struct _req_type), \ + sizeof(struct _rsp_type)); \ + if (!req) \ + return NULL; \ + req->hdr.sig =3D OTX2_MBOX_REQ_SIG; \ + req->hdr.id =3D _id; \ + return req; \ +} + +MBOX_UP_AF2SWDEV_MESSAGES +MBOX_UP_AF2PF_FDB_REFRESH_MESSAGES +#undef M + +struct l2_entry { + struct list_head list; + u64 flags; + u32 port_id; + u8 mac[ETH_ALEN]; +}; + +static DEFINE_MUTEX(l2_offl_list_lock); +static LIST_HEAD(l2_offl_lh); + +static DEFINE_MUTEX(fdb_refresh_list_lock); +static LIST_HEAD(fdb_refresh_lh); + +struct rvu_sw_l2_work { + struct rvu *rvu; + struct work_struct work; +}; + +static struct rvu_sw_l2_work l2_offl_work; +static struct workqueue_struct *rvu_sw_l2_offl_wq; + +static struct rvu_sw_l2_work fdb_refresh_work; +static struct workqueue_struct *fdb_refresh_wq; + +static void rvu_sw_l2_offl_cancel_add_if_del_reqs_exist(u8 *mac) +{ + struct l2_entry *entry, *tmp; + + mutex_lock(&l2_offl_list_lock); + list_for_each_entry_safe(entry, tmp, &l2_offl_lh, list) { + if (!ether_addr_equal(mac, entry->mac)) + continue; + + if (!(entry->flags & FDB_DEL)) + continue; + + list_del_init(&entry->list); + kfree(entry); + break; + } + mutex_unlock(&l2_offl_list_lock); +} + +static int rvu_sw_l2_offl_rule_push(struct rvu *rvu, struct l2_entry *l2_e= ntry) +{ + struct af2swdev_notify_req *req; + int swdev_pf; + + swdev_pf =3D rvu_get_pf(rvu->pdev, rvu->rswitch.pcifunc); + + mutex_lock(&rvu->mbox_lock); + req =3D otx2_mbox_alloc_msg_af2swdev_notify(rvu, swdev_pf); + if (!req) { + mutex_unlock(&rvu->mbox_lock); + return -ENOMEM; + } + + ether_addr_copy(req->mac, l2_entry->mac); + req->flags =3D l2_entry->flags; + req->port_id =3D l2_entry->port_id; + + otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, swdev_pf); + otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, swdev_pf); + + mutex_unlock(&rvu->mbox_lock); + return 0; +} + +static int rvu_sw_l2_fdb_refresh(struct rvu *rvu, u16 pcifunc, u8 *mac) +{ + struct af2pf_fdb_refresh_req *req; + int pf, vidx; + + pf =3D rvu_get_pf(rvu->pdev, pcifunc); + + mutex_lock(&rvu->mbox_lock); + + if (pf) { + req =3D otx2_mbox_alloc_msg_af2pf_fdb_refresh(rvu, pf); + if (!req) { + mutex_unlock(&rvu->mbox_lock); + return -ENOMEM; + } + + req->hdr.pcifunc =3D pcifunc; + ether_addr_copy(req->mac, mac); + req->pcifunc =3D pcifunc; + + otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf); + otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf); + } else { + vidx =3D pcifunc - 1; + + req =3D (struct af2pf_fdb_refresh_req *) + otx2_mbox_alloc_msg_rsp(&rvu->afvf_wq_info.mbox_up, vidx, + sizeof(*req), sizeof(struct msg_rsp)); + if (!req) { + mutex_unlock(&rvu->mbox_lock); + return -ENOMEM; + } + req->hdr.sig =3D OTX2_MBOX_REQ_SIG; + req->hdr.id =3D MBOX_MSG_AF2PF_FDB_REFRESH; + + req->hdr.pcifunc =3D pcifunc; + ether_addr_copy(req->mac, mac); + req->pcifunc =3D pcifunc; + + otx2_mbox_wait_for_zero(&rvu->afvf_wq_info.mbox_up, vidx); + otx2_mbox_msg_send_up(&rvu->afvf_wq_info.mbox_up, vidx); + } + + mutex_unlock(&rvu->mbox_lock); + + return 0; +} + +static void rvu_sw_l2_fdb_refresh_wq_handler(struct work_struct *work) +{ + struct rvu_sw_l2_work *fdb_work; + struct l2_entry *l2_entry; + + fdb_work =3D container_of(work, struct rvu_sw_l2_work, work); + + while (1) { + mutex_lock(&fdb_refresh_list_lock); + l2_entry =3D list_first_entry_or_null(&fdb_refresh_lh, + struct l2_entry, list); + if (!l2_entry) { + mutex_unlock(&fdb_refresh_list_lock); + return; + } + + list_del_init(&l2_entry->list); + mutex_unlock(&fdb_refresh_list_lock); + + rvu_sw_l2_fdb_refresh(fdb_work->rvu, l2_entry->port_id, l2_entry->mac); + kfree(l2_entry); + } +} + +static void rvu_sw_l2_offl_rule_wq_handler(struct work_struct *work) +{ + struct rvu_sw_l2_work *offl_work; + struct l2_entry *l2_entry; + int budget =3D 16; + bool add_fdb; + + offl_work =3D container_of(work, struct rvu_sw_l2_work, work); + + while (budget--) { + mutex_lock(&l2_offl_list_lock); + l2_entry =3D list_first_entry_or_null(&l2_offl_lh, struct l2_entry, list= ); + if (!l2_entry) { + mutex_unlock(&l2_offl_list_lock); + return; + } + + list_del_init(&l2_entry->list); + mutex_unlock(&l2_offl_list_lock); + + add_fdb =3D !!(l2_entry->flags & FDB_ADD); + + if (add_fdb) + rvu_sw_l2_offl_cancel_add_if_del_reqs_exist(l2_entry->mac); + + rvu_sw_l2_offl_rule_push(offl_work->rvu, l2_entry); + kfree(l2_entry); + } + + if (!list_empty(&l2_offl_lh)) + queue_work(rvu_sw_l2_offl_wq, &l2_offl_work.work); +} + +int rvu_sw_l2_init_offl_wq(struct rvu *rvu, u16 pcifunc, bool fw_up) +{ + struct rvu_switch *rswitch; + + rswitch =3D &rvu->rswitch; + + if (fw_up) { + rswitch->flags |=3D RVU_SWITCH_FLAG_FW_READY; + rswitch->pcifunc =3D pcifunc; + + l2_offl_work.rvu =3D rvu; + INIT_WORK(&l2_offl_work.work, rvu_sw_l2_offl_rule_wq_handler); + rvu_sw_l2_offl_wq =3D alloc_workqueue("swdev_rvu_sw_l2_offl_wq", 0, 0); + if (!rvu_sw_l2_offl_wq) { + dev_err(rvu->dev, "L2 offl workqueue allocation failed\n"); + return -ENOMEM; + } + + fdb_refresh_work.rvu =3D rvu; + INIT_WORK(&fdb_refresh_work.work, rvu_sw_l2_fdb_refresh_wq_handler); + fdb_refresh_wq =3D alloc_workqueue("swdev_fdb_refresh_wq", 0, 0); + if (!fdb_refresh_wq) { + dev_err(rvu->dev, "Fdb refresh workqueue allocation failed\n"); + return -ENOMEM; + } + + return 0; + } + + rswitch->flags &=3D ~RVU_SWITCH_FLAG_FW_READY; + rswitch->pcifunc =3D -1; + flush_work(&l2_offl_work.work); + return 0; +} + +int rvu_sw_l2_fdb_list_entry_add(struct rvu *rvu, u16 pcifunc, u8 *mac) +{ + struct l2_entry *l2_entry; + + l2_entry =3D kcalloc(1, sizeof(*l2_entry), GFP_KERNEL); + if (!l2_entry) + return -ENOMEM; + + l2_entry->port_id =3D pcifunc; + ether_addr_copy(l2_entry->mac, mac); + + mutex_lock(&fdb_refresh_list_lock); + list_add_tail(&l2_entry->list, &fdb_refresh_lh); + mutex_unlock(&fdb_refresh_list_lock); + + queue_work(fdb_refresh_wq, &fdb_refresh_work.work); + return 0; +} =20 int rvu_mbox_handler_fdb_notify(struct rvu *rvu, struct fdb_notify_req *req, struct msg_rsp *rsp) { + struct l2_entry *l2_entry; + + if (!(rvu->rswitch.flags & RVU_SWITCH_FLAG_FW_READY)) + return 0; + + l2_entry =3D kcalloc(1, sizeof(*l2_entry), GFP_KERNEL); + if (!l2_entry) + return -ENOMEM; + + ether_addr_copy(l2_entry->mac, req->mac); + l2_entry->flags =3D req->flags; + l2_entry->port_id =3D rvu_sw_port_id(rvu, req->hdr.pcifunc); + + mutex_lock(&l2_offl_list_lock); + list_add_tail(&l2_entry->list, &l2_offl_lh); + mutex_unlock(&l2_offl_list_lock); + + queue_work(rvu_sw_l2_offl_wq, &l2_offl_work.work); + return 0; } diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.h b= /drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.h index ff28612150c9..56786768880e 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l2.h @@ -8,4 +8,6 @@ #ifndef RVU_SW_L2_H #define RVU_SW_L2_H =20 +int rvu_sw_l2_init_offl_wq(struct rvu *rvu, u16 pcifunc, bool fw_up); +int rvu_sw_l2_fdb_list_entry_add(struct rvu *rvu, u16 pcifunc, u8 *mac); #endif diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers= /net/ethernet/marvell/octeontx2/nic/otx2_vf.c index f4fdbfba8667..4642a1dd7ccb 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c @@ -15,6 +15,7 @@ #include "otx2_ptp.h" #include "cn10k.h" #include "cn10k_ipsec.h" +#include "switch/sw_nb.h" =20 #define DRV_NAME "rvu_nicvf" #define DRV_STRING "Marvell RVU NIC Virtual Function Driver" @@ -141,6 +142,22 @@ static int otx2vf_process_mbox_msg_up(struct otx2_nic = *vf, err =3D otx2_mbox_up_handler_cgx_link_event( vf, (struct cgx_link_info_msg *)req, rsp); return err; + + case MBOX_MSG_AF2PF_FDB_REFRESH: + rsp =3D (struct msg_rsp *)otx2_mbox_alloc_msg(&vf->mbox.mbox_up, 0, + sizeof(struct msg_rsp)); + if (!rsp) + return -ENOMEM; + + rsp->hdr.id =3D MBOX_MSG_AF2PF_FDB_REFRESH; + rsp->hdr.sig =3D OTX2_MBOX_RSP_SIG; + rsp->hdr.pcifunc =3D req->pcifunc; + rsp->hdr.rc =3D 0; + err =3D otx2_mbox_up_handler_af2pf_fdb_refresh(vf, + (struct af2pf_fdb_refresh_req *)req, + rsp); + return err; + default: otx2_reply_invalid_msg(&vf->mbox.mbox_up, 0, 0, req->id); return -ENODEV; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.c b/d= rivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.c index 6842c8d91ffc..71aec9628eb2 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.c @@ -4,13 +4,140 @@ * Copyright (C) 2026 Marvell. * */ +#include +#include +#include +#include +#include +#include + +#include "../otx2_reg.h" +#include "../otx2_common.h" +#include "../otx2_struct.h" +#include "../cn10k.h" #include "sw_fdb.h" =20 +#if !IS_ENABLED(CONFIG_OCTEONTX_SWITCH) + +int otx2_mbox_up_handler_af2pf_fdb_refresh(struct otx2_nic *pf, + struct af2pf_fdb_refresh_req *req, + struct msg_rsp *rsp) +{ + return 0; +} + +#else + +static DEFINE_SPINLOCK(sw_fdb_llock); +static LIST_HEAD(sw_fdb_lh); + +struct sw_fdb_list_entry { + struct list_head list; + u64 flags; + struct otx2_nic *pf; + u8 mac[ETH_ALEN]; + bool add_fdb; +}; + +static struct workqueue_struct *sw_fdb_wq; +static struct work_struct sw_fdb_work; + +static int sw_fdb_add_or_del(struct otx2_nic *pf, + const unsigned char *addr, + bool add_fdb) +{ + struct fdb_notify_req *req; + int rc; + + mutex_lock(&pf->mbox.lock); + req =3D otx2_mbox_alloc_msg_fdb_notify(&pf->mbox); + if (!req) { + rc =3D -ENOMEM; + goto out; + } + + ether_addr_copy(req->mac, addr); + req->flags =3D add_fdb ? FDB_ADD : FDB_DEL; + + rc =3D otx2_sync_mbox_msg(&pf->mbox); +out: + mutex_unlock(&pf->mbox.lock); + return rc; +} + +static void sw_fdb_wq_handler(struct work_struct *work) +{ + struct sw_fdb_list_entry *entry; + LIST_HEAD(tlist); + + spin_lock(&sw_fdb_llock); + list_splice_init(&sw_fdb_lh, &tlist); + spin_unlock(&sw_fdb_llock); + + while ((entry =3D + list_first_entry_or_null(&tlist, + struct sw_fdb_list_entry, + list)) !=3D NULL) { + list_del_init(&entry->list); + sw_fdb_add_or_del(entry->pf, entry->mac, entry->add_fdb); + kfree(entry); + } + + spin_lock(&sw_fdb_llock); + if (!list_empty(&sw_fdb_lh)) + queue_work(sw_fdb_wq, &sw_fdb_work); + spin_unlock(&sw_fdb_llock); +} + +int sw_fdb_add_to_list(struct net_device *dev, u8 *mac, bool add_fdb) +{ + struct otx2_nic *pf =3D netdev_priv(dev); + struct sw_fdb_list_entry *entry; + + entry =3D kcalloc(1, sizeof(*entry), GFP_ATOMIC); + if (!entry) + return -ENOMEM; + + ether_addr_copy(entry->mac, mac); + entry->add_fdb =3D add_fdb; + entry->pf =3D pf; + + spin_lock(&sw_fdb_llock); + list_add_tail(&entry->list, &sw_fdb_lh); + queue_work(sw_fdb_wq, &sw_fdb_work); + spin_unlock(&sw_fdb_llock); + + return 0; +} + int sw_fdb_init(void) { + INIT_WORK(&sw_fdb_work, sw_fdb_wq_handler); + sw_fdb_wq =3D alloc_workqueue("sw_fdb_wq", 0, 0); + if (!sw_fdb_wq) + return -ENOMEM; + return 0; } =20 void sw_fdb_deinit(void) { + cancel_work_sync(&sw_fdb_work); + destroy_workqueue(sw_fdb_wq); +} + +int otx2_mbox_up_handler_af2pf_fdb_refresh(struct otx2_nic *pf, + struct af2pf_fdb_refresh_req *req, + struct msg_rsp *rsp) +{ + struct switchdev_notifier_fdb_info item =3D {0}; + + item.addr =3D req->mac; + item.info.dev =3D pf->netdev; + call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE, + item.info.dev, &item.info, NULL); + + return 0; } +#endif +EXPORT_SYMBOL(otx2_mbox_up_handler_af2pf_fdb_refresh); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.h b/d= rivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.h index d4314d6d3ee4..f8705083418c 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fdb.h @@ -7,7 +7,12 @@ #ifndef SW_FDB_H_ #define SW_FDB_H_ =20 +int sw_fdb_add_to_list(struct net_device *dev, u8 *mac, bool add_fdb); void sw_fdb_deinit(void); int sw_fdb_init(void); =20 +int otx2_mbox_up_handler_af2pf_fdb_refresh(struct otx2_nic *pf, + struct af2pf_fdb_refresh_req *req, + struct msg_rsp *rsp); + #endif // SW_FDB_H diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c index ce565fe7035c..f5e00807c0fa 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c @@ -21,6 +21,7 @@ #include "sw_fdb.h" #include "sw_fib.h" #include "sw_fl.h" +#include "sw_nb.h" =20 static const char *sw_nb_cmd2str[OTX2_CMD_MAX] =3D { [OTX2_DEV_UP] =3D "OTX2_DEV_UP", @@ -59,7 +60,6 @@ static int sw_nb_check_slaves(struct net_device *dev, struct netdev_nested_priv *priv) { int *cnt; - if (!priv->flags) return 0; =20 @@ -115,11 +115,13 @@ static int sw_nb_fdb_event(struct notifier_block *unu= sed, case SWITCHDEV_FDB_ADD_TO_DEVICE: if (fdb_info->is_local) break; + sw_fdb_add_to_list(dev, (u8 *)fdb_info->addr, true); break; =20 case SWITCHDEV_FDB_DEL_TO_DEVICE: if (fdb_info->is_local) break; + sw_fdb_add_to_list(dev, (u8 *)fdb_info->addr, false); break; =20 default: @@ -313,7 +315,6 @@ static int sw_nb_fib_event(struct notifier_block *nb, entries =3D kcalloc(hcnt, sizeof(*entries), GFP_ATOMIC); if (!entries) return NOTIFY_DONE; - iter =3D entries; =20 for (i =3D 0; i < hcnt; i++, iter++) { --=20 2.43.0 From nobody Sun Feb 8 19:03:52 2026 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (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 0242833B971; Fri, 9 Jan 2026 10:31:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954720; cv=none; b=fr2v/S7ay1x8n17Y111Y8mt/F0BcN33fm489SgUeD0kHNBNtPeUcmo0lxkTx8emeNgIC/3eB3z1lDst9NKYlonlz3S6cwslCHScvMOEJkBIlEz97HgD7yaTguvzOsVzA0EsXoFg7o4xzuL8hU3gnV3vIjUMkoRDKTiiDGeIzyVc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954720; c=relaxed/simple; bh=hRtC5MBoqQHsbgPBjH4G8vLFpqbWE1IxmbBJ/Uo5A2Y=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=M8JLjDLohbbAQYmwu2n3i+UViy1YifYjxflMTq5ZlFB6ZuPbML5WKjqoa5UVSu+MKbut7CahjhX6vYKZhavpJAPSy7zo5ksVn2XFmQulNE+/ZE/KD/6UPOlG/Qodq6ZA4brq5FbamxiGXKmt5njvcbrWD2pz0YfZaHKeTvOC/rs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=UoAPbZgX; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="UoAPbZgX" Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 608NW5NF1844047; Fri, 9 Jan 2026 02:31:45 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=u q8fTvT3DqPKi2DD8lbkDm5hB9YfXxdVP2u5lBAOgls=; b=UoAPbZgXv85aX8t+V sivXXKsioKTd4OfAXvs00R0RyEurrf3hVyrzc0hUHq+A/X3Ij12NLOnfSozj0du0 dBm1451PLhVvdO5TSDJV6/zEgbZ7CBUDMOfS+BdSnQQyyygzLUdpj3Aq/qIUnIEd GQxCcc2bKxDlM1p1JvXs3b+7TwMRMSFnLwYhfY3kfFOHx0mQHcbCY0sfcpeGrg45 hdxCSK9Y4U0VFqWlJxLJVXimKE+kK1XT5HjwsSQ3I3G4BAS4zJwG9rU4j9ZptvCF zkqpYxYUwJWwfBFlzy2Ercp1AYVxTPpfZnG9+vAa3H9tlY7Xd49v2qBcXG17WavP j/8lQ== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4bhwh2vmw1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 09 Jan 2026 02:31:45 -0800 (PST) Received: from DC5-EXCH05.marvell.com (10.69.176.209) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Fri, 9 Jan 2026 02:31:59 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Fri, 9 Jan 2026 02:31:59 -0800 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 1C71C3F70F3; Fri, 9 Jan 2026 02:31:41 -0800 (PST) From: Ratheesh Kannoth To: , CC: , , , , , , "Ratheesh Kannoth" Subject: [PATCH net-next v3 08/10] octeontx2: switch: L3 offload support Date: Fri, 9 Jan 2026 16:00:33 +0530 Message-ID: <20260109103035.2972893-9-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109103035.2972893-1-rkannoth@marvell.com> References: <20260109103035.2972893-1-rkannoth@marvell.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-Proofpoint-GUID: qYObRmLID9qmjTy6AX66mj8wdBBCyu5- X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA5MDA3NiBTYWx0ZWRfXzaiiqStiSX5C ecKhnj5LfOJbsgtxHyQluMQHeAfX+saI5PmXCuHoHxB3n4QiR3UnwzpcFsdH2xCoxXCWLlOb9+d NrJnt3aQIKPubXCgTdMBJl5Gk9nlECUGiylb8AVKzhLagH6UV+Bi5MU0FWBdTSUuQyiWxb94Sfs HvMjGQuqLnGt0IS187ht9VDj8FmajBss46kmPTF/TNcYvRGZWtsZsthRo1y7RZ5lbcWkcH0zFAr mZQY62ZPu11HwatiXzIj9H/33Ale1HUgQ81ATKW6969RyO1bsLcDbWIlnWyZyW+hM+u8wFwP/Fd fA8r9bXWTl+CaBfl0snT5dDWTzM3P621GAeHjirRQv98/mFfovriJ8ZLshP/5omSCHB1VobQ17R wA2ckRi7Sxu6INEYNFQGn/7TrO0EIc85Sw3eB5eBhvLFDzUhJ+2dtAJuJWlTjydlHw9JABuO6Ej ocolzFArGVzhvrY0baQ== X-Authority-Analysis: v=2.4 cv=ROO+3oi+ c=1 sm=1 tr=0 ts=6960d911 cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=vUbySO9Y5rIA:10 a=VkNPw1HP01LnGYTKEx00:22 a=M5GUcnROAAAA:8 a=tLXh2gpUjKgpRBJMYcwA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-ORIG-GUID: qYObRmLID9qmjTy6AX66mj8wdBBCyu5- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-09_03,2026-01-08_02,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Linux route events are parsed to decide on destination DIP/MASK to fwd packets. Switchdev HW flow table is filled with this information. Once populated, all packet with DIP/MASK will be accelerated. Signed-off-by: Ratheesh Kannoth --- .../marvell/octeontx2/af/switch/rvu_sw.c | 2 +- .../marvell/octeontx2/af/switch/rvu_sw_l3.c | 202 ++++++++++++++++++ .../marvell/octeontx2/nic/switch/sw_fib.c | 119 +++++++++++ .../marvell/octeontx2/nic/switch/sw_fib.h | 3 + .../marvell/octeontx2/nic/switch/sw_nb.c | 20 ++ 5 files changed, 345 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c b/dr= ivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c index b66f9c2eb981..fe91b0a6baf5 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c @@ -6,9 +6,9 @@ */ =20 #include "rvu.h" -#include "rvu_sw.h" #include "rvu_sw_l2.h" #include "rvu_sw_fl.h" +#include "rvu_sw.h" =20 u32 rvu_sw_port_id(struct rvu *rvu, u16 pcifunc) { diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l3.c b= /drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l3.c index 2b798d5f0644..dc01d0ff26a7 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l3.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_l3.c @@ -4,11 +4,213 @@ * Copyright (C) 2026 Marvell. * */ + +#include #include "rvu.h" +#include "rvu_sw.h" +#include "rvu_sw_l3.h" + +#define M(_name, _id, _fn_name, _req_type, _rsp_type) \ +static struct _req_type __maybe_unused \ +*otx2_mbox_alloc_msg_ ## _fn_name(struct rvu *rvu, int devid) \ +{ \ + struct _req_type *req; \ + \ + req =3D (struct _req_type *)otx2_mbox_alloc_msg_rsp( \ + &rvu->afpf_wq_info.mbox_up, devid, sizeof(struct _req_type), \ + sizeof(struct _rsp_type)); \ + if (!req) \ + return NULL; \ + req->hdr.sig =3D OTX2_MBOX_REQ_SIG; \ + req->hdr.id =3D _id; \ + return req; \ +} + +MBOX_UP_AF2SWDEV_MESSAGES +#undef M + +struct l3_entry { + struct list_head list; + struct rvu *rvu; + u32 port_id; + int cnt; + struct fib_entry entry[]; +}; + +static DEFINE_MUTEX(l3_offl_llock); +static LIST_HEAD(l3_offl_lh); +static bool l3_offl_work_running; + +static struct workqueue_struct *sw_l3_offl_wq; +static void sw_l3_offl_work_handler(struct work_struct *work); +static DECLARE_DELAYED_WORK(l3_offl_work, sw_l3_offl_work_handler); + +static void sw_l3_offl_dump(struct l3_entry *l3_entry) +{ + struct fib_entry *entry =3D l3_entry->entry; + int i; + + for (i =3D 0; i < l3_entry->cnt; i++, entry++) { + pr_debug("%s:%d cmd=3D%llu port_id=3D%#x dst=3D%#x dst_len=3D%d gw=3D%#= x\n", + __func__, __LINE__, entry->cmd, entry->port_id, entry->dst, + entry->dst_len, entry->gw); + } +} + +static int rvu_sw_l3_offl_rule_push(struct list_head *lh) +{ + struct af2swdev_notify_req *req; + struct fib_entry *entry, *dst; + struct l3_entry *l3_entry; + struct rvu *rvu; + int swdev_pf; + int sz, cnt; + int tot_cnt =3D 0; + + l3_entry =3D list_first_entry_or_null(lh, struct l3_entry, list); + if (!l3_entry) + return 0; + + rvu =3D l3_entry->rvu; + swdev_pf =3D rvu_get_pf(rvu->pdev, rvu->rswitch.pcifunc); + + mutex_lock(&rvu->mbox_lock); + req =3D otx2_mbox_alloc_msg_af2swdev_notify(rvu, swdev_pf); + if (!req) { + mutex_unlock(&rvu->mbox_lock); + return -ENOMEM; + } + + dst =3D &req->entry[0]; + while ((l3_entry =3D + list_first_entry_or_null(lh, + struct l3_entry, list)) !=3D NULL) { + entry =3D l3_entry->entry; + cnt =3D l3_entry->cnt; + sz =3D sizeof(*entry) * cnt; + + memcpy(dst, entry, sz); + tot_cnt +=3D cnt; + dst +=3D cnt; + + sw_l3_offl_dump(l3_entry); + + list_del_init(&l3_entry->list); + kfree(l3_entry); + } + req->flags =3D FIB_CMD; + req->cnt =3D tot_cnt; + + otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, swdev_pf); + otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, swdev_pf); + + mutex_unlock(&rvu->mbox_lock); + return 0; +} + +static atomic64_t req_cnt; +static atomic64_t ack_cnt; +static atomic64_t req_processed; +static LIST_HEAD(l3_local_lh); +static int lcnt; + +static void sw_l3_offl_work_handler(struct work_struct *work) +{ + struct l3_entry *l3_entry; + struct list_head l3lh; + u64 req, ack, proc; + + INIT_LIST_HEAD(&l3lh); + + mutex_lock(&l3_offl_llock); + while (1) { + l3_entry =3D list_first_entry_or_null(&l3_offl_lh, struct l3_entry, list= ); + + if (!l3_entry) + break; + + if (lcnt + l3_entry->cnt > 16) { + req =3D atomic64_read(&req_cnt); + atomic64_set(&ack_cnt, req); + atomic64_set(&req_processed, req); + mutex_unlock(&l3_offl_llock); + goto process; + } + + lcnt +=3D l3_entry->cnt; + + atomic64_inc(&req_cnt); + list_del_init(&l3_entry->list); + list_add_tail(&l3_entry->list, &l3_local_lh); + } + mutex_unlock(&l3_offl_llock); + + req =3D atomic64_read(&req_cnt); + ack =3D atomic64_read(&ack_cnt); + + if (req > ack) { + atomic64_set(&ack_cnt, req); + queue_delayed_work(sw_l3_offl_wq, &l3_offl_work, + msecs_to_jiffies(100)); + return; + } + + proc =3D atomic64_read(&req_processed); + if (req =3D=3D proc) { + queue_delayed_work(sw_l3_offl_wq, &l3_offl_work, + msecs_to_jiffies(1000)); + return; + } + + atomic64_set(&req_processed, req); + +process: + lcnt =3D 0; + + mutex_lock(&l3_offl_llock); + list_splice_init(&l3_local_lh, &l3lh); + mutex_unlock(&l3_offl_llock); + + rvu_sw_l3_offl_rule_push(&l3lh); + + queue_delayed_work(sw_l3_offl_wq, &l3_offl_work, msecs_to_jiffies(100)); +} =20 int rvu_mbox_handler_fib_notify(struct rvu *rvu, struct fib_notify_req *req, struct msg_rsp *rsp) { + struct l3_entry *l3_entry; + int sz; + + if (!(rvu->rswitch.flags & RVU_SWITCH_FLAG_FW_READY)) + return 0; + + sz =3D req->cnt * sizeof(struct fib_entry); + + l3_entry =3D kcalloc(1, sizeof(*l3_entry) + sz, GFP_KERNEL); + if (!l3_entry) + return -ENOMEM; + + l3_entry->port_id =3D rvu_sw_port_id(rvu, req->hdr.pcifunc); + l3_entry->rvu =3D rvu; + l3_entry->cnt =3D req->cnt; + INIT_LIST_HEAD(&l3_entry->list); + memcpy(l3_entry->entry, req->entry, sz); + + mutex_lock(&l3_offl_llock); + list_add_tail(&l3_entry->list, &l3_offl_lh); + mutex_unlock(&l3_offl_llock); + + if (!l3_offl_work_running) { + sw_l3_offl_wq =3D alloc_workqueue("sw_af_fib_wq", 0, 0); + if (!sw_l3_offl_wq) + return -EFAULT; + + l3_offl_work_running =3D true; + queue_delayed_work(sw_l3_offl_wq, &l3_offl_work, + msecs_to_jiffies(1000)); + } + return 0; } diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.c b/d= rivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.c index 12ddf8119372..3d6e09ac987d 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.c @@ -4,13 +4,132 @@ * Copyright (C) 2026 Marvell. * */ +#include +#include +#include +#include +#include +#include +#include + +#include "../otx2_reg.h" +#include "../otx2_common.h" +#include "../otx2_struct.h" +#include "../cn10k.h" +#include "sw_nb.h" #include "sw_fib.h" =20 +static DEFINE_SPINLOCK(sw_fib_llock); +static LIST_HEAD(sw_fib_lh); + +static struct workqueue_struct *sw_fib_wq; +static void sw_fib_work_handler(struct work_struct *work); +static DECLARE_DELAYED_WORK(sw_fib_work, sw_fib_work_handler); + +struct sw_fib_list_entry { + struct list_head lh; + struct otx2_nic *pf; + int cnt; + struct fib_entry *entry; +}; + +static void sw_fib_dump(struct fib_entry *entry, int cnt) +{ + int i; + + for (i =3D 0; i < cnt; i++, entry++) { + pr_debug("%s:%d cmd=3D%s gw_valid=3D%d mac_valid=3D%d dst=3D%#x len=3D%d= gw=3D%#x mac=3D%pM nud_state=3D%#x\n", + __func__, __LINE__, + sw_nb_get_cmd2str(entry->cmd), + entry->gw_valid, entry->mac_valid, entry->dst, entry->dst_len, + entry->gw, entry->mac, entry->nud_state); + } +} + +static int sw_fib_notify(struct otx2_nic *pf, + int cnt, + struct fib_entry *entry) +{ + struct fib_notify_req *req; + int rc; + + mutex_lock(&pf->mbox.lock); + req =3D otx2_mbox_alloc_msg_fib_notify(&pf->mbox); + if (!req) { + rc =3D -ENOMEM; + goto out; + } + + req->cnt =3D cnt; + memcpy(req->entry, entry, sizeof(*entry) * cnt); + sw_fib_dump(req->entry, cnt); + + rc =3D otx2_sync_mbox_msg(&pf->mbox); +out: + mutex_unlock(&pf->mbox.lock); + return rc; +} + +static void sw_fib_work_handler(struct work_struct *work) +{ + struct sw_fib_list_entry *lentry; + LIST_HEAD(tlist); + + spin_lock(&sw_fib_llock); + list_splice_init(&sw_fib_lh, &tlist); + spin_unlock(&sw_fib_llock); + + while ((lentry =3D + list_first_entry_or_null(&tlist, + struct sw_fib_list_entry, lh)) !=3D NULL) { + list_del_init(&lentry->lh); + sw_fib_notify(lentry->pf, lentry->cnt, lentry->entry); + kfree(lentry->entry); + kfree(lentry); + } + + spin_lock(&sw_fib_llock); + if (!list_empty(&sw_fib_lh)) + queue_delayed_work(sw_fib_wq, &sw_fib_work, + msecs_to_jiffies(10)); + spin_unlock(&sw_fib_llock); +} + +int sw_fib_add_to_list(struct net_device *dev, + struct fib_entry *entry, int cnt) +{ + struct otx2_nic *pf =3D netdev_priv(dev); + struct sw_fib_list_entry *lentry; + + lentry =3D kcalloc(1, sizeof(*lentry), GFP_ATOMIC); + if (!lentry) + return -ENOMEM; + + lentry->pf =3D pf; + lentry->cnt =3D cnt; + lentry->entry =3D entry; + INIT_LIST_HEAD(&lentry->lh); + + spin_lock(&sw_fib_llock); + list_add_tail(&lentry->lh, &sw_fib_lh); + queue_delayed_work(sw_fib_wq, &sw_fib_work, + msecs_to_jiffies(10)); + spin_unlock(&sw_fib_llock); + + return 0; +} + int sw_fib_init(void) { + sw_fib_wq =3D alloc_workqueue("sw_pf_fib_wq", 0, 0); + if (!sw_fib_wq) + return -ENOMEM; + return 0; } =20 void sw_fib_deinit(void) { + cancel_delayed_work_sync(&sw_fib_work); + destroy_workqueue(sw_fib_wq); } diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.h b/d= rivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.h index a51d15c2b80e..50c4fbca81e8 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fib.h @@ -7,6 +7,9 @@ #ifndef SW_FIB_H_ #define SW_FIB_H_ =20 +int sw_fib_add_to_list(struct net_device *dev, + struct fib_entry *entry, int cnt); + void sw_fib_deinit(void); int sw_fib_init(void); =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c index f5e00807c0fa..7a0ed52eae95 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c @@ -307,6 +307,12 @@ static int sw_nb_fib_event(struct notifier_block *nb, return NOTIFY_DONE; } =20 + if (sw_fib_add_to_list(pf_dev, entries, cnt)) { + kfree(entries); + kfree(haddr); + return NOTIFY_DONE; + } + if (!hcnt) { kfree(haddr); return NOTIFY_DONE; @@ -336,6 +342,7 @@ static int sw_nb_fib_event(struct notifier_block *nb, iter->cmd, iter->dst, iter->dst_len, iter->gw, dev->name); } =20 + sw_fib_add_to_list(pf_dev, entries, hcnt); kfree(haddr); return NOTIFY_DONE; } @@ -390,6 +397,9 @@ static int sw_nb_net_event(struct notifier_block *nb, =20 pf =3D netdev_priv(pf_dev); entry->port_id =3D pf->pcifunc; + if (sw_fib_add_to_list(pf_dev, entry, 1)) + kfree(entry); + break; } =20 @@ -469,6 +479,11 @@ static int sw_nb_inetaddr_event(struct notifier_block = *nb, break; } =20 + if (sw_fib_add_to_list(pf_dev, entry, 1)) { + kfree(entry); + return NOTIFY_DONE; + } + netdev_dbg(dev, "%s:%d pushing inetaddr event from HOST interface address %#x, %pM, %= s\n", __func__, __LINE__, entry->dst, entry->mac, dev->name); @@ -536,6 +551,11 @@ static int sw_nb_netdev_event(struct notifier_block *u= nused, break; } =20 + if (sw_fib_add_to_list(pf_dev, entry, 1)) { + kfree(entry); + return NOTIFY_DONE; + } + netdev_dbg(dev, "%s:%d pushing netdev event from HOST interface address %#x, %pM, dev= =3D%s\n", __func__, __LINE__, entry->dst, entry->mac, dev->name); --=20 2.43.0 From nobody Sun Feb 8 19:03:52 2026 Received: from mx0a-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (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 9023933A6FB; Fri, 9 Jan 2026 10:31:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954721; cv=none; b=KBQ7q4AhWxiYpcIPjRPi4gD0qTpmFwNs+4oI720EXpLLpcxNBSPJmFb1bi/UrCZAQc2x2LSi31G7m450tN5L+L68l9en+VbBeyHfeGNZ5VFDOd2moep6z1Yv+4wdnM3xW2OJ9z94eHly+fW5eJRNRhjZN0IYoHQiGe0MHMtSAeE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954721; c=relaxed/simple; bh=vk5ooczgE2+mwwKw0s82nKLKy8IMtIOXMY6khSpjBPY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dWE38TyeYns+6xzeYI81TwCitTrYEyCEDOX17equhG0LVK1YfmW82PyUR7VUISiC9TZ1M9/8XT6+cNtp+/KBtFUogiphC3wBxhcyGuqmEyHJpS2KjpompJ8keY+fQR2XNryhbW7PoQtj4IcSCMJ/+Tw4EPIh/uoLSH7wJkZk/20= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=j7F4k99w; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="j7F4k99w" Received: from pps.filterd (m0431384.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 608NTRmr833066; Fri, 9 Jan 2026 02:31:48 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=l jCZl+E7/S+wBiSzYUOM7hpWmf9gK1tRfYV4GGJ1Emg=; b=j7F4k99wW3kdxBEox MDcVaxiNPxhzsYDehcjGkg2k5drdvIp4Scozrj0uszBjaRuK1H5HPRmw85QsJtbh XjWg9/Az8oXvnAy5+NW/dJu/2YqAkafreEszwDOX1mP/n462Oh1+OM6rq7Qg6N5Q xu4EtfVXVZm5UZS6CFCKaIDn/Dt3nKUjToQMC1SL02jG/T9DhnsCVe+PmyiJtNCH kHuJZMpwUk3AmAv9FcWaSruLiEBg/mBfuUy9eotRMUPUgmU8U2JKkR7LxSm+R9sI kgDgjRuKvSS+YGCHRqgn+c1OC/7uJdhdSVsHFYnjQHRhDNDRPcnZnA181tBJXOir Xr/Iw== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4bjp9r970s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 09 Jan 2026 02:31:48 -0800 (PST) Received: from DC5-EXCH05.marvell.com (10.69.176.209) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Fri, 9 Jan 2026 02:32:03 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Fri, 9 Jan 2026 02:32:03 -0800 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 3ACA65B692B; Fri, 9 Jan 2026 02:31:45 -0800 (PST) From: Ratheesh Kannoth To: , CC: , , , , , , "Ratheesh Kannoth" Subject: [PATCH net-next v3 09/10] octeontx2: switch: Flow offload support Date: Fri, 9 Jan 2026 16:00:34 +0530 Message-ID: <20260109103035.2972893-10-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109103035.2972893-1-rkannoth@marvell.com> References: <20260109103035.2972893-1-rkannoth@marvell.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-Authority-Analysis: v=2.4 cv=e58LiKp/ c=1 sm=1 tr=0 ts=6960d914 cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=vUbySO9Y5rIA:10 a=VkNPw1HP01LnGYTKEx00:22 a=M5GUcnROAAAA:8 a=AvFaPPdkt7eJ4n2nza0A:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-ORIG-GUID: putYkLemS59w-p0Xoqq-a0XIWzDHE2dK X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA5MDA3NiBTYWx0ZWRfX7qLUQ7iKQT6Y dUH13KKnsu2CH7BXT3ETZ8OHe5wIqVtQVb9QfYeSKQiNTyj4RsDoeldzpLIPOA7akXxJCed+66N zCte3xwgsmHSEtC+DPyCXcjHTZD7TffYZlqZzorygtWcDr15DVYIHMosp7Kwsu2XuULbp0HwAml oX7pvTibtXwv6Eii1olraIpGXW2Oryv/7dCHYY4KTH0xFKJxUvyjj8hTAt9nGC4rcxlYtmh+Oy5 xi089I2gzaf3HwMZklaUhYMvEcJFFZ03IYw9pvB68w/1zs+I6SZJ+kofmsOGCbSEIDvT3nmi/z+ NQE9Bhyqf/JNmLckEwAR9cyy2dHELGzepMBuD7TkHQ36biIVCzFf1Zu1gq8pYyAHijfO7Hg9cbE OeliMxSvuRD/5dkGvPTN+I5huqsygAh6pSe/Itrc8NeNWoY06lq3k3ftFkAWLfVk/+avkanKLd6 yl3VPhuv+6MB7VpBqnQ== X-Proofpoint-GUID: putYkLemS59w-p0Xoqq-a0XIWzDHE2dK X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-09_03,2026-01-08_02,2025-10-01_01 Content-Type: text/plain; charset="utf-8" OVS/NFT pushed HW acceleration rules to pf driver thru .ndo_tc(). Switchdev HW flow table is filled with this information. Once populated, flow will be accelerated. Signed-off-by: Ratheesh Kannoth --- .../marvell/octeontx2/af/switch/rvu_sw.c | 4 + .../marvell/octeontx2/af/switch/rvu_sw_fl.c | 278 +++++++++ .../marvell/octeontx2/af/switch/rvu_sw_fl.h | 2 + .../ethernet/marvell/octeontx2/nic/otx2_tc.c | 16 +- .../marvell/octeontx2/nic/switch/sw_fl.c | 541 ++++++++++++++++++ .../marvell/octeontx2/nic/switch/sw_fl.h | 2 + .../marvell/octeontx2/nic/switch/sw_nb.c | 1 - 7 files changed, 842 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c b/dr= ivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c index fe91b0a6baf5..10aed0ca5934 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c @@ -37,6 +37,10 @@ int rvu_mbox_handler_swdev2af_notify(struct rvu *rvu, case SWDEV2AF_MSG_TYPE_REFRESH_FDB: rc =3D rvu_sw_l2_fdb_list_entry_add(rvu, req->pcifunc, req->mac); break; + + case SWDEV2AF_MSG_TYPE_REFRESH_FL: + rc =3D rvu_sw_fl_stats_sync2db(rvu, req->fl, req->cnt); + break; } =20 return rc; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.c b= /drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.c index 1f8b82a84a5d..9104621fa0cc 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.c @@ -4,12 +4,258 @@ * Copyright (C) 2026 Marvell. * */ + +#include #include "rvu.h" +#include "rvu_sw.h" +#include "rvu_sw_fl.h" + +#define M(_name, _id, _fn_name, _req_type, _rsp_type) \ +static struct _req_type __maybe_unused \ +*otx2_mbox_alloc_msg_ ## _fn_name(struct rvu *rvu, int devid) \ +{ \ + struct _req_type *req; \ + \ + req =3D (struct _req_type *)otx2_mbox_alloc_msg_rsp( \ + &rvu->afpf_wq_info.mbox_up, devid, sizeof(struct _req_type), \ + sizeof(struct _rsp_type)); \ + if (!req) \ + return NULL; \ + req->hdr.sig =3D OTX2_MBOX_REQ_SIG; \ + req->hdr.id =3D _id; \ + return req; \ +} + +MBOX_UP_AF2SWDEV_MESSAGES +#undef M + +static struct workqueue_struct *sw_fl_offl_wq; + +struct fl_entry { + struct list_head list; + struct rvu *rvu; + u32 port_id; + unsigned long cookie; + struct fl_tuple tuple; + u64 flags; + u64 features; +}; + +static DEFINE_MUTEX(fl_offl_llock); +static LIST_HEAD(fl_offl_lh); +static bool fl_offl_work_running; + +static struct workqueue_struct *sw_fl_offl_wq; +static void sw_fl_offl_work_handler(struct work_struct *work); +static DECLARE_DELAYED_WORK(fl_offl_work, sw_fl_offl_work_handler); + +struct sw_fl_stats_node { + struct list_head list; + unsigned long cookie; + u16 mcam_idx[2]; + u64 opkts, npkts; + bool uni_di; +}; + +static LIST_HEAD(sw_fl_stats_lh); +static DEFINE_MUTEX(sw_fl_stats_lock); + +static int +rvu_sw_fl_stats_sync2db_one_entry(unsigned long cookie, u8 disabled, + u16 mcam_idx[2], bool uni_di, u64 pkts) +{ + struct sw_fl_stats_node *snode, *tmp; + + mutex_lock(&sw_fl_stats_lock); + list_for_each_entry_safe(snode, tmp, &sw_fl_stats_lh, list) { + if (snode->cookie !=3D cookie) + continue; + + if (disabled) { + list_del_init(&snode->list); + mutex_unlock(&sw_fl_stats_lock); + kfree(snode); + return 0; + } + + if (snode->uni_di !=3D uni_di) { + snode->uni_di =3D uni_di; + snode->mcam_idx[1] =3D mcam_idx[1]; + } + + if (snode->opkts =3D=3D pkts) { + mutex_unlock(&sw_fl_stats_lock); + return 0; + } + + snode->npkts =3D pkts; + mutex_unlock(&sw_fl_stats_lock); + return 0; + } + mutex_unlock(&sw_fl_stats_lock); + + snode =3D kcalloc(1, sizeof(*snode), GFP_KERNEL); + if (!snode) + return -ENOMEM; + + snode->cookie =3D cookie; + snode->mcam_idx[0] =3D mcam_idx[0]; + if (!uni_di) + snode->mcam_idx[1] =3D mcam_idx[1]; + + snode->npkts =3D pkts; + snode->uni_di =3D uni_di; + INIT_LIST_HEAD(&snode->list); + + mutex_lock(&sw_fl_stats_lock); + list_add_tail(&snode->list, &sw_fl_stats_lh); + mutex_unlock(&sw_fl_stats_lock); + + return 0; +} + +int rvu_sw_fl_stats_sync2db(struct rvu *rvu, struct fl_info *fl, int cnt) +{ + struct npc_mcam_get_mul_stats_req *req =3D NULL; + struct npc_mcam_get_mul_stats_rsp *rsp =3D NULL; + u16 i2idx_map[256]; + int tot =3D 0; + int rc =3D 0; + u64 pkts; + int idx; + + cnt =3D min(cnt, 64); + + for (int i =3D 0; i < cnt; i++) { + tot++; + if (fl[i].uni_di) + continue; + + tot++; + } + + req =3D kzalloc(sizeof(*req), GFP_KERNEL); + if (!req) + return -ENOMEM; + + rsp =3D kzalloc(sizeof(*rsp), GFP_KERNEL); + if (!rsp) { + rc =3D -ENOMEM; + goto fail; + } + + req->cnt =3D tot; + idx =3D 0; + for (int i =3D 0; i < tot; idx++) { + i2idx_map[i] =3D idx; + req->entry[i++] =3D fl[idx].mcam_idx[0]; + if (fl[idx].uni_di) + continue; + + i2idx_map[i] =3D idx; + req->entry[i++] =3D fl[idx].mcam_idx[1]; + } + + if (rvu_mbox_handler_npc_mcam_mul_stats(rvu, req, rsp)) { + dev_err(rvu->dev, "Error to get multiple stats\n"); + rc =3D -EFAULT; + goto fail; + } + + for (int i =3D 0; i < tot;) { + idx =3D i2idx_map[i]; + pkts =3D rsp->stat[i++]; + + if (!fl[idx].uni_di) + pkts +=3D rsp->stat[i++]; + + rc |=3D rvu_sw_fl_stats_sync2db_one_entry(fl[idx].cookie, fl[idx].dis, + fl[idx].mcam_idx, + fl[idx].uni_di, pkts); + } + +fail: + kfree(req); + kfree(rsp); + return rc; +} + +static void sw_fl_offl_dump(struct fl_entry *fl_entry) +{ + struct fl_tuple *tuple =3D &fl_entry->tuple; + + pr_debug("%pI4 to %pI4\n", &tuple->ip4src, &tuple->ip4dst); +} + +static int rvu_sw_fl_offl_rule_push(struct fl_entry *fl_entry) +{ + struct af2swdev_notify_req *req; + struct rvu *rvu; + int swdev_pf; + + rvu =3D fl_entry->rvu; + swdev_pf =3D rvu_get_pf(rvu->pdev, rvu->rswitch.pcifunc); + + mutex_lock(&rvu->mbox_lock); + req =3D otx2_mbox_alloc_msg_af2swdev_notify(rvu, swdev_pf); + if (!req) { + mutex_unlock(&rvu->mbox_lock); + return -ENOMEM; + } + + req->tuple =3D fl_entry->tuple; + req->flags =3D fl_entry->flags; + req->cookie =3D fl_entry->cookie; + req->features =3D fl_entry->features; + + sw_fl_offl_dump(fl_entry); + + otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, swdev_pf); + otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, swdev_pf); + + mutex_unlock(&rvu->mbox_lock); + return 0; +} + +static void sw_fl_offl_work_handler(struct work_struct *work) +{ + struct fl_entry *fl_entry; + + mutex_lock(&fl_offl_llock); + fl_entry =3D list_first_entry_or_null(&fl_offl_lh, struct fl_entry, list); + if (!fl_entry) { + mutex_unlock(&fl_offl_llock); + return; + } + + list_del_init(&fl_entry->list); + mutex_unlock(&fl_offl_llock); + + rvu_sw_fl_offl_rule_push(fl_entry); + kfree(fl_entry); + + mutex_lock(&fl_offl_llock); + if (!list_empty(&fl_offl_lh)) + queue_delayed_work(sw_fl_offl_wq, &fl_offl_work, msecs_to_jiffies(10)); + mutex_unlock(&fl_offl_llock); +} =20 int rvu_mbox_handler_fl_get_stats(struct rvu *rvu, struct fl_get_stats_req *req, struct fl_get_stats_rsp *rsp) { + struct sw_fl_stats_node *snode, *tmp; + + mutex_lock(&sw_fl_stats_lock); + list_for_each_entry_safe(snode, tmp, &sw_fl_stats_lh, list) { + if (snode->cookie !=3D req->cookie) + continue; + + rsp->pkts_diff =3D snode->npkts - snode->opkts; + snode->opkts =3D snode->npkts; + break; + } + mutex_unlock(&sw_fl_stats_lock); return 0; } =20 @@ -17,5 +263,37 @@ int rvu_mbox_handler_fl_notify(struct rvu *rvu, struct fl_notify_req *req, struct msg_rsp *rsp) { + struct fl_entry *fl_entry; + + if (!(rvu->rswitch.flags & RVU_SWITCH_FLAG_FW_READY)) + return 0; + + fl_entry =3D kcalloc(1, sizeof(*fl_entry), GFP_KERNEL); + if (!fl_entry) + return -ENOMEM; + + fl_entry->port_id =3D rvu_sw_port_id(rvu, req->hdr.pcifunc); + fl_entry->rvu =3D rvu; + INIT_LIST_HEAD(&fl_entry->list); + fl_entry->tuple =3D req->tuple; + fl_entry->cookie =3D req->cookie; + fl_entry->flags =3D req->flags; + fl_entry->features =3D req->features; + + mutex_lock(&fl_offl_llock); + list_add_tail(&fl_entry->list, &fl_offl_lh); + mutex_unlock(&fl_offl_llock); + + if (!fl_offl_work_running) { + sw_fl_offl_wq =3D alloc_workqueue("sw_af_fl_wq", 0, 0); + if (!sw_fl_offl_wq) { + kfree(fl_entry); + return -ENOMEM; + } + + fl_offl_work_running =3D true; + } + queue_delayed_work(sw_fl_offl_wq, &fl_offl_work, msecs_to_jiffies(10)); + return 0; } diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.h b= /drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.h index cf3e5b884f77..aa375413bc14 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw_fl.h @@ -8,4 +8,6 @@ #ifndef RVU_SW_FL_H #define RVU_SW_FL_H =20 +int rvu_sw_fl_stats_sync2db(struct rvu *rvu, struct fl_info *fl, int cnt); + #endif diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers= /net/ethernet/marvell/octeontx2/nic/otx2_tc.c index 26a08d2cfbb1..907f1d7da798 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c @@ -20,6 +20,7 @@ #include "cn10k.h" #include "otx2_common.h" #include "qos.h" +#include "switch/sw_fl.h" =20 #define CN10K_MAX_BURST_MANTISSA 0x7FFFULL #define CN10K_MAX_BURST_SIZE 8453888ULL @@ -1238,7 +1239,6 @@ static int otx2_tc_del_flow(struct otx2_nic *nic, mutex_unlock(&nic->mbox.lock); } =20 - free_mcam_flow: otx2_del_mcam_flow_entry(nic, flow_node->entry, NULL); otx2_tc_update_mcam_table(nic, flow_cfg, flow_node, false); @@ -1595,11 +1595,25 @@ static int otx2_setup_tc_block(struct net_device *n= etdev, int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type, void *type_data) { + struct otx2_nic *nic =3D netdev_priv(netdev); + switch (type) { case TC_SETUP_BLOCK: + if (netif_is_ovs_port(netdev)) + return flow_block_cb_setup_simple(type_data, + &otx2_block_cb_list, + sw_fl_setup_ft_block_ingress_cb, + nic, nic, true); + return otx2_setup_tc_block(netdev, type_data); case TC_SETUP_QDISC_HTB: return otx2_setup_tc_htb(netdev, type_data); + + case TC_SETUP_FT: + return flow_block_cb_setup_simple(type_data, + &otx2_block_cb_list, + sw_fl_setup_ft_block_ingress_cb, + nic, nic, true); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.c b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.c index 36a2359a0a48..c9aa0043cc4c 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.c @@ -4,13 +4,554 @@ * Copyright (C) 2026 Marvell. * */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../otx2_reg.h" +#include "../otx2_common.h" +#include "../otx2_struct.h" +#include "../cn10k.h" +#include "sw_nb.h" #include "sw_fl.h" =20 +#if !IS_ENABLED(CONFIG_OCTEONTX_SWITCH) +int sw_fl_setup_ft_block_ingress_cb(enum tc_setup_type type, + void *type_data, void *cb_priv) +{ + return -EOPNOTSUPP; +} + +#else + +static DEFINE_SPINLOCK(sw_fl_lock); +static LIST_HEAD(sw_fl_lh); + +struct sw_fl_list_entry { + struct list_head list; + u64 flags; + unsigned long cookie; + struct otx2_nic *pf; + struct fl_tuple tuple; +}; + +static struct workqueue_struct *sw_fl_wq; +static struct work_struct sw_fl_work; + +static int sw_fl_msg_send(struct otx2_nic *pf, + struct fl_tuple *tuple, + u64 flags, + unsigned long cookie) +{ + struct fl_notify_req *req; + int rc; + + mutex_lock(&pf->mbox.lock); + req =3D otx2_mbox_alloc_msg_fl_notify(&pf->mbox); + if (!req) { + rc =3D -ENOMEM; + goto out; + } + + req->tuple =3D *tuple; + req->flags =3D flags; + req->cookie =3D cookie; + + rc =3D otx2_sync_mbox_msg(&pf->mbox); +out: + mutex_unlock(&pf->mbox.lock); + return rc; +} + +static void sw_fl_wq_handler(struct work_struct *work) +{ + struct sw_fl_list_entry *entry; + LIST_HEAD(tlist); + + spin_lock(&sw_fl_lock); + list_splice_init(&sw_fl_lh, &tlist); + spin_unlock(&sw_fl_lock); + + while ((entry =3D + list_first_entry_or_null(&tlist, + struct sw_fl_list_entry, + list)) !=3D NULL) { + list_del_init(&entry->list); + sw_fl_msg_send(entry->pf, &entry->tuple, + entry->flags, entry->cookie); + kfree(entry); + } + + spin_lock(&sw_fl_lock); + if (!list_empty(&sw_fl_lh)) + queue_work(sw_fl_wq, &sw_fl_work); + spin_unlock(&sw_fl_lock); +} + +static int +sw_fl_add_to_list(struct otx2_nic *pf, struct fl_tuple *tuple, + unsigned long cookie, bool add_fl) +{ + struct sw_fl_list_entry *entry; + + entry =3D kcalloc(1, sizeof(*entry), GFP_ATOMIC); + if (!entry) + return -ENOMEM; + + entry->pf =3D pf; + entry->flags =3D add_fl ? FL_ADD : FL_DEL; + if (add_fl) + entry->tuple =3D *tuple; + entry->cookie =3D cookie; + entry->tuple.uni_di =3D netif_is_ovs_port(pf->netdev); + + spin_lock(&sw_fl_lock); + list_add_tail(&entry->list, &sw_fl_lh); + queue_work(sw_fl_wq, &sw_fl_work); + spin_unlock(&sw_fl_lock); + + return 0; +} + +static int sw_fl_parse_actions(struct otx2_nic *nic, + struct flow_action *flow_action, + struct flow_cls_offload *f, + struct fl_tuple *tuple, u64 *op) +{ + struct flow_action_entry *act; + struct net_device *netdev; + struct otx2_nic *out_nic; + int used =3D 0; + int err; + int i; + + if (!flow_action_has_entries(flow_action)) + return -EINVAL; + + netdev =3D nic->netdev; + + flow_action_for_each(i, act, flow_action) { + WARN_ON(used >=3D MANGLE_ARR_SZ); + + switch (act->id) { + case FLOW_ACTION_REDIRECT: + tuple->in_pf =3D nic->pcifunc; + out_nic =3D netdev_priv(act->dev); + tuple->xmit_pf =3D out_nic->pcifunc; + *op |=3D BIT_ULL(FLOW_ACTION_REDIRECT); + break; + + case FLOW_ACTION_CT: + err =3D nf_flow_table_offload_add_cb(act->ct.flow_table, + sw_fl_setup_ft_block_ingress_cb, + nic); + if (err !=3D -EEXIST && err) { + netdev_err(netdev, + "%s:%d Error to offload flow, err=3D%d\n", + __func__, __LINE__, err); + break; + } + + *op |=3D BIT_ULL(FLOW_ACTION_CT); + break; + + case FLOW_ACTION_MANGLE: + tuple->mangle[used].type =3D act->mangle.htype; + tuple->mangle[used].val =3D act->mangle.val; + tuple->mangle[used].mask =3D act->mangle.mask; + tuple->mangle[used].offset =3D act->mangle.offset; + tuple->mangle_map[act->mangle.htype] |=3D BIT(used); + used++; + break; + + default: + break; + } + } + + tuple->mangle_cnt =3D used; + + if (!*op) { + netdev_dbg(netdev, + "%s:%d Op is not valid\n", __func__, __LINE__); + return -EOPNOTSUPP; + } + + return 0; +} + +static int sw_fl_get_route(struct fib_result *res, __be32 addr) +{ + struct flowi4 fl4; + + memset(&fl4, 0, sizeof(fl4)); + fl4.daddr =3D addr; + return fib_lookup(&init_net, &fl4, res, 0); +} + +static int sw_fl_get_pcifunc(struct otx2_nic *nic, __be32 dst, u16 *pcifun= c, + struct fl_tuple *ftuple, bool is_in_dev) +{ + struct fib_nh_common *fib_nhc; + struct net_device *dev, *br; + struct net_device *netdev; + struct fib_result res; + struct list_head *lh; + int err; + + netdev =3D nic->netdev; + + rcu_read_lock(); + + err =3D sw_fl_get_route(&res, dst); + if (err) { + netdev_err(netdev, + "%s:%d Failed to find route to dst %pI4\n", + __func__, __LINE__, &dst); + goto done; + } + + if (res.fi->fib_type !=3D RTN_UNICAST) { + netdev_err(netdev, + "%s:%d Not unicast route to dst %pI4\n", + __func__, __LINE__, &dst); + err =3D -EFAULT; + goto done; + } + + fib_nhc =3D fib_info_nhc(res.fi, 0); + if (!fib_nhc) { + err =3D -EINVAL; + netdev_err(netdev, + "%s:%d Could not get fib_nhc for %pI4\n", + __func__, __LINE__, &dst); + goto done; + } + + if (unlikely(netif_is_bridge_master(fib_nhc->nhc_dev))) { + br =3D fib_nhc->nhc_dev; + + if (is_in_dev) + ftuple->is_indev_br =3D 1; + else + ftuple->is_xdev_br =3D 1; + + lh =3D &br->adj_list.lower; + if (list_empty(lh)) { + netdev_err(netdev, + "%s:%d Unable to find any slave device\n", + __func__, __LINE__); + err =3D -EINVAL; + goto done; + } + dev =3D netdev_next_lower_dev_rcu(br, &lh); + + } else { + dev =3D fib_nhc->nhc_dev; + } + + if (!sw_nb_is_valid_dev(dev)) { + netdev_err(netdev, + "%s:%d flow acceleration support is only for cavium devices\n", + __func__, __LINE__); + err =3D -EOPNOTSUPP; + goto done; + } + + nic =3D netdev_priv(dev); + *pcifunc =3D nic->pcifunc; + +done: + rcu_read_unlock(); + return err; +} + +static int sw_fl_parse_flow(struct otx2_nic *nic, struct flow_cls_offload = *f, + struct fl_tuple *tuple, u64 *features) +{ + struct flow_rule *rule; + u8 ip_proto =3D 0; + + *features =3D 0; + + rule =3D flow_cls_offload_flow_rule(f); + + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { + struct flow_match_basic match; + + flow_rule_match_basic(rule, &match); + + /* All EtherTypes can be matched, no hw limitation */ + + if (match.mask->n_proto) { + tuple->eth_type =3D match.key->n_proto; + tuple->m_eth_type =3D match.mask->n_proto; + *features |=3D BIT_ULL(NPC_ETYPE); + } + + if (match.mask->ip_proto && + (match.key->ip_proto !=3D IPPROTO_TCP && + match.key->ip_proto !=3D IPPROTO_UDP)) { + netdev_dbg(nic->netdev, + "ip_proto=3D%u not supported\n", + match.key->ip_proto); + } + + if (match.mask->ip_proto) + ip_proto =3D match.key->ip_proto; + + if (ip_proto =3D=3D IPPROTO_UDP) { + *features |=3D BIT_ULL(NPC_IPPROTO_UDP); + } else if (ip_proto =3D=3D IPPROTO_TCP) { + *features |=3D BIT_ULL(NPC_IPPROTO_TCP); + } else { + netdev_dbg(nic->netdev, + "ip_proto=3D%u not supported\n", + match.key->ip_proto); + } + + tuple->proto =3D ip_proto; + } + + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { + struct flow_match_eth_addrs match; + + flow_rule_match_eth_addrs(rule, &match); + + if (!is_zero_ether_addr(match.key->dst) && + is_unicast_ether_addr(match.key->dst)) { + ether_addr_copy(tuple->dmac, + match.key->dst); + + ether_addr_copy(tuple->m_dmac, + match.mask->dst); + + *features |=3D BIT_ULL(NPC_DMAC); + } + + if (!is_zero_ether_addr(match.key->src) && + is_unicast_ether_addr(match.key->src)) { + ether_addr_copy(tuple->smac, + match.key->src); + ether_addr_copy(tuple->m_smac, + match.mask->src); + *features |=3D BIT_ULL(NPC_SMAC); + } + } + + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) { + struct flow_match_ipv4_addrs match; + + flow_rule_match_ipv4_addrs(rule, &match); + + if (match.key->dst) { + tuple->ip4dst =3D match.key->dst; + tuple->m_ip4dst =3D match.mask->dst; + *features |=3D BIT_ULL(NPC_DIP_IPV4); + } + + if (match.key->src) { + tuple->ip4src =3D match.key->src; + tuple->m_ip4src =3D match.mask->src; + *features |=3D BIT_ULL(NPC_SIP_IPV4); + } + } + + if (!(*features & BIT_ULL(NPC_DMAC))) { + if (!tuple->ip4src || !tuple->ip4dst) { + netdev_err(nic->netdev, + "%s:%d Invalid src=3D%pI4 and dst=3D%pI4 addresses\n", + __func__, __LINE__, + &tuple->ip4src, &tuple->ip4dst); + return -EINVAL; + } + + if ((tuple->ip4src & tuple->m_ip4src) =3D=3D + (tuple->ip4dst & tuple->m_ip4dst)) { + netdev_err(nic->netdev, + "%s:%d Masked values are same; Invalid src=3D%pI4 and dst=3D%pI4 ad= dresses\n", + __func__, __LINE__, + &tuple->ip4src, &tuple->ip4dst); + return -EINVAL; + } + } + + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) { + struct flow_match_ports match; + + flow_rule_match_ports(rule, &match); + + if (ip_proto =3D=3D IPPROTO_UDP) { + if (match.key->dst) + *features |=3D BIT_ULL(NPC_DPORT_UDP); + + if (match.key->src) + *features |=3D BIT_ULL(NPC_SPORT_UDP); + } else if (ip_proto =3D=3D IPPROTO_TCP) { + if (match.key->dst) + *features |=3D BIT_ULL(NPC_DPORT_TCP); + + if (match.key->src) + *features |=3D BIT_ULL(NPC_SPORT_TCP); + } + + if (match.mask->src) { + tuple->sport =3D match.key->src; + tuple->m_sport =3D match.mask->src; + } + + if (match.mask->dst) { + tuple->dport =3D match.key->dst; + tuple->m_dport =3D match.mask->dst; + } + } + + if (!(*features & (BIT_ULL(NPC_DMAC) | + BIT_ULL(NPC_SMAC) | + BIT_ULL(NPC_DIP_IPV4) | + BIT_ULL(NPC_SIP_IPV4) | + BIT_ULL(NPC_DPORT_UDP) | + BIT_ULL(NPC_SPORT_UDP) | + BIT_ULL(NPC_DPORT_TCP) | + BIT_ULL(NPC_SPORT_TCP)))) { + return -EINVAL; + } + + tuple->features =3D *features; + + return 0; +} + +static int sw_fl_add(struct otx2_nic *nic, struct flow_cls_offload *f) +{ + struct fl_tuple tuple =3D { 0 }; + struct flow_rule *rule; + u64 features =3D 0; + u64 op =3D 0; + int rc; + + rule =3D flow_cls_offload_flow_rule(f); + + rc =3D sw_fl_parse_actions(nic, &rule->action, f, &tuple, &op); + if (rc) + return rc; + + if (op & BIT_ULL(FLOW_ACTION_CT)) + return 0; + + rc =3D sw_fl_parse_flow(nic, f, &tuple, &features); + if (rc) + return -EFAULT; + + if (!netif_is_ovs_port(nic->netdev)) { + rc =3D sw_fl_get_pcifunc(nic, tuple.ip4src, &tuple.in_pf, + &tuple, true); + if (rc) + return rc; + + rc =3D sw_fl_get_pcifunc(nic, tuple.ip4dst, &tuple.xmit_pf, + &tuple, false); + if (rc) + return rc; + } + + sw_fl_add_to_list(nic, &tuple, f->cookie, true); + return 0; +} + +static int sw_fl_del(struct otx2_nic *nic, struct flow_cls_offload *f) +{ + return sw_fl_add_to_list(nic, NULL, f->cookie, false); +} + +static int sw_fl_stats(struct otx2_nic *nic, struct flow_cls_offload *f) +{ + struct fl_get_stats_req *req; + struct fl_get_stats_rsp *rsp; + u64 pkts_diff; + int rc =3D 0; + + mutex_lock(&nic->mbox.lock); + + req =3D otx2_mbox_alloc_msg_fl_get_stats(&nic->mbox); + if (!req) { + netdev_err(nic->netdev, + "%s:%d Error happened while mcam alloc req\n", + __func__, __LINE__); + rc =3D -ENOMEM; + goto fail; + } + req->cookie =3D f->cookie; + + rc =3D otx2_sync_mbox_msg(&nic->mbox); + if (rc) + goto fail; + + rsp =3D (struct fl_get_stats_rsp *)otx2_mbox_get_rsp + (&nic->mbox.mbox, 0, &req->hdr); + if (IS_ERR(rsp)) { + rc =3D PTR_ERR(rsp); + goto fail; + } + + pkts_diff =3D rsp->pkts_diff; + mutex_unlock(&nic->mbox.lock); + + if (pkts_diff) { + flow_stats_update(&f->stats, 0x0, pkts_diff, + 0x0, jiffies, + FLOW_ACTION_HW_STATS_IMMEDIATE); + } + return 0; +fail: + mutex_unlock(&nic->mbox.lock); + return rc; +} + +static bool init_done; + +int sw_fl_setup_ft_block_ingress_cb(enum tc_setup_type type, + void *type_data, void *cb_priv) +{ + struct flow_cls_offload *cls =3D type_data; + struct otx2_nic *nic =3D cb_priv; + + if (!init_done) + return 0; + + switch (cls->command) { + case FLOW_CLS_REPLACE: + return sw_fl_add(nic, cls); + case FLOW_CLS_DESTROY: + return sw_fl_del(nic, cls); + case FLOW_CLS_STATS: + return sw_fl_stats(nic, cls); + default: + break; + } + + return -EOPNOTSUPP; +} + int sw_fl_init(void) { + INIT_WORK(&sw_fl_work, sw_fl_wq_handler); + sw_fl_wq =3D alloc_workqueue("sw_fl_wq", 0, 0); + if (!sw_fl_wq) + return -ENOMEM; + + init_done =3D true; return 0; } =20 void sw_fl_deinit(void) { + cancel_work_sync(&sw_fl_work); + destroy_workqueue(sw_fl_wq); } +#endif diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.h b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.h index cd018d770a8a..8dd816eb17d2 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.h @@ -9,5 +9,7 @@ =20 void sw_fl_deinit(void); int sw_fl_init(void); +int sw_fl_setup_ft_block_ingress_cb(enum tc_setup_type type, + void *type_data, void *cb_priv); =20 #endif // SW_FL_H diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c index 7a0ed52eae95..c316aeac2e81 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_nb.c @@ -21,7 +21,6 @@ #include "sw_fdb.h" #include "sw_fib.h" #include "sw_fl.h" -#include "sw_nb.h" =20 static const char *sw_nb_cmd2str[OTX2_CMD_MAX] =3D { [OTX2_DEV_UP] =3D "OTX2_DEV_UP", --=20 2.43.0 From nobody Sun Feb 8 19:03:52 2026 Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) (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 832D233A6E0; Fri, 9 Jan 2026 10:31:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.156.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954721; cv=none; b=pClDhMI4twpg4kOambgzN0AdYi/liPzbzbCRvavWRNsw119I5qx4RmrqFi2B3+AkIVdMpRffJgSEe/D7hIf61CogF97libMwPp7XPQPbvOHbFyHTVzvjUwfdia9YHuGqx6kbG8YOQY2k3A6JQAnH7fmjzVIHavhAQZRPj++HcmY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767954721; c=relaxed/simple; bh=7LdXTT/4uMU1KEnQ2Nm+9GOgr+S0ppAn+sVry4w4/mY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=EfB4QT5NTiSnOU8orRNP6eOY1pYliQmNNT+MyR4AE2qc838rlWTZbltL25rhQT7ymmE2IfxEQS8Ob/gEaWF+dNQGbyoymDAusysegqCiHQha6tMgV7ik1eDvvpnkMLM3Q47JjztVEB2P9RfPAFcYgvm6PRXAPFVV0KileJZOGps= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=Mv5PWSAA; arc=none smtp.client-ip=67.231.156.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="Mv5PWSAA" Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 60934aZ0027531; Fri, 9 Jan 2026 02:31:52 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=e Na560f65DxhyZfQm4oATo3PUgV4in3z9qiFk2KCJNo=; b=Mv5PWSAAOOr+fzAsw cNZ9Tj3fD1W/aHdC59mnkpsMM0MnrPzQTMu/5PvmtxSh8ESKK02l4LCDBv88E61a boY7eViwsEWojOu8cYzw72Urr3ojsHHoWSiY9hgKydGKgYls7l3o50rQEnA9qMwd 2vuq1kFy+2ItjsKiYhCgDvW4ZxQKMIEjXid5hS5DDIzoMFqs/M8Rnk775iRKcMeQ /QlKADRUUjTn9wHGkQjvCAtOzj5diTk92XWWDJfWNGVbm1BbUCgqOI+fDGdsIuwe GdWgF3DFowwEj5E1yewkC9M2JrSzuzBIKZLjdpZV4UMKwoDdZJ0cy58Ls2OpfBeP YC+BQ== Received: from dc6wp-exch02.marvell.com ([4.21.29.225]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 4bjset0x36-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 09 Jan 2026 02:31:51 -0800 (PST) Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Fri, 9 Jan 2026 02:31:51 -0800 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Fri, 9 Jan 2026 02:31:51 -0800 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 68A3F3F708A; Fri, 9 Jan 2026 02:31:48 -0800 (PST) From: Ratheesh Kannoth To: , CC: , , , , , , "Ratheesh Kannoth" Subject: [PATCH net-next v3 10/10] octeontx2: switch: trace support Date: Fri, 9 Jan 2026 16:00:35 +0530 Message-ID: <20260109103035.2972893-11-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109103035.2972893-1-rkannoth@marvell.com> References: <20260109103035.2972893-1-rkannoth@marvell.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-Authority-Analysis: v=2.4 cv=W581lBWk c=1 sm=1 tr=0 ts=6960d917 cx=c_pps a=gIfcoYsirJbf48DBMSPrZA==:117 a=gIfcoYsirJbf48DBMSPrZA==:17 a=vUbySO9Y5rIA:10 a=VkNPw1HP01LnGYTKEx00:22 a=M5GUcnROAAAA:8 a=gFDZAJeugxnc_ztJiqIA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-GUID: Ox0XJNy9nPamQWsCAD5XqAKjMPA9er4l X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA5MDA3NiBTYWx0ZWRfX8OVLlCo92mbJ FOi0Men1gHZMCxgOFXCzuzNB2ZSdtrZSAcJH81LY7u3/WgLI0f4Cyk0QptmVsqXKKUps0plqYsi tm8KeXAcw378fT1RRVtbb+DwBMvqiI1aj3JnjH9l6ejQcPvgve39mhEhFAV1Z2ECwO4xVS3zutc ck/GCgLmTYvyEg85kyiSq9Rm2V0mo8VPt9zRTCR4Yze7z7RnTkyQ8Am6LyXBDQFdSyBeJAgu+cf JQfQbDR2paduCytIZwn7E/DYbV5sC2A24Y7zczGQN6Hj7jYjmGTeju4iZkXDA8taSD0PFzsW+Si Rj7EEqbJOcAEOZfFbe1J9Pu3WOBc4YDN5ZdXsF1FPKZnij6NUeLnts4XQ+zghlofV9qajluF1RD tWIENPiUjlrxOgPfsF94y7wg/H/ax2sq66+vAUquc2uLPIXu8VwDXP28oZFw3g5qjtxd0kV1/R2 4xzFnaKqOHUYNxAa2EA== X-Proofpoint-ORIG-GUID: Ox0XJNy9nPamQWsCAD5XqAKjMPA9er4l X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-09_03,2026-01-08_02,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Traces are added to flow parsing to ease debugging. Signed-off-by: Ratheesh Kannoth --- .../ethernet/marvell/octeontx2/nic/Makefile | 2 +- .../marvell/octeontx2/nic/switch/sw_fl.c | 18 +++- .../marvell/octeontx2/nic/switch/sw_trace.c | 11 +++ .../marvell/octeontx2/nic/switch/sw_trace.h | 82 +++++++++++++++++++ 4 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_tr= ace.c create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_tr= ace.h diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/Makefile b/drivers/= net/ethernet/marvell/octeontx2/nic/Makefile index da87e952c187..5f722d0cfac2 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/Makefile +++ b/drivers/net/ethernet/marvell/octeontx2/nic/Makefile @@ -13,7 +13,7 @@ rvu_nicpf-y :=3D otx2_pf.o otx2_common.o otx2_txrx.o otx2= _ethtool.o \ switch/sw_fdb.o switch/sw_fl.o =20 ifdef CONFIG_OCTEONTX_SWITCH -rvu_nicpf-y +=3D switch/sw_nb.o switch/sw_fib.o +rvu_nicpf-y +=3D switch/sw_nb.o switch/sw_fib.o switch/sw_trace.o endif =20 rvu_nicvf-y :=3D otx2_vf.o diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.c b/dr= ivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.c index c9aa0043cc4c..3ddae5d08578 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_fl.c @@ -18,6 +18,7 @@ #include "../otx2_struct.h" #include "../cn10k.h" #include "sw_nb.h" +#include "sw_trace.h" #include "sw_fl.h" =20 #if !IS_ENABLED(CONFIG_OCTEONTX_SWITCH) @@ -140,6 +141,7 @@ static int sw_fl_parse_actions(struct otx2_nic *nic, =20 switch (act->id) { case FLOW_ACTION_REDIRECT: + trace_sw_act_dump(__func__, __LINE__, act->id); tuple->in_pf =3D nic->pcifunc; out_nic =3D netdev_priv(act->dev); tuple->xmit_pf =3D out_nic->pcifunc; @@ -147,6 +149,7 @@ static int sw_fl_parse_actions(struct otx2_nic *nic, break; =20 case FLOW_ACTION_CT: + trace_sw_act_dump(__func__, __LINE__, act->id); err =3D nf_flow_table_offload_add_cb(act->ct.flow_table, sw_fl_setup_ft_block_ingress_cb, nic); @@ -161,6 +164,7 @@ static int sw_fl_parse_actions(struct otx2_nic *nic, break; =20 case FLOW_ACTION_MANGLE: + trace_sw_act_dump(__func__, __LINE__, act->id); tuple->mangle[used].type =3D act->mangle.htype; tuple->mangle[used].val =3D act->mangle.val; tuple->mangle[used].mask =3D act->mangle.mask; @@ -170,6 +174,7 @@ static int sw_fl_parse_actions(struct otx2_nic *nic, break; =20 default: + trace_sw_act_dump(__func__, __LINE__, act->id); break; } } @@ -445,21 +450,28 @@ static int sw_fl_add(struct otx2_nic *nic, struct flo= w_cls_offload *f) return 0; =20 rc =3D sw_fl_parse_flow(nic, f, &tuple, &features); - if (rc) + if (rc) { + trace_sw_fl_dump(__func__, __LINE__, &tuple); return -EFAULT; + } =20 if (!netif_is_ovs_port(nic->netdev)) { rc =3D sw_fl_get_pcifunc(nic, tuple.ip4src, &tuple.in_pf, &tuple, true); - if (rc) + if (rc) { + trace_sw_fl_dump(__func__, __LINE__, &tuple); return rc; + } =20 rc =3D sw_fl_get_pcifunc(nic, tuple.ip4dst, &tuple.xmit_pf, &tuple, false); - if (rc) + if (rc) { + trace_sw_fl_dump(__func__, __LINE__, &tuple); return rc; + } } =20 + trace_sw_fl_dump(__func__, __LINE__, &tuple); sw_fl_add_to_list(nic, &tuple, f->cookie, true); return 0; } diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_trace.c b= /drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_trace.c new file mode 100644 index 000000000000..260fd2bb3606 --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_trace.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Marvell RVU Admin Function driver + * + * Copyright (C) 2026 Marvell. + * + */ + +#define CREATE_TRACE_POINTS +#include "sw_trace.h" +EXPORT_TRACEPOINT_SYMBOL(sw_fl_dump); +EXPORT_TRACEPOINT_SYMBOL(sw_act_dump); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_trace.h b= /drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_trace.h new file mode 100644 index 000000000000..e23deca0309a --- /dev/null +++ b/drivers/net/ethernet/marvell/octeontx2/nic/switch/sw_trace.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Marvell RVU Admin Function driver + * + * Copyright (C) 2026 Marvell. + * + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM rvu + +#if !defined(SW_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define SW_TRACE_H + +#include +#include + +#include "mbox.h" + +TRACE_EVENT(sw_fl_dump, + TP_PROTO(const char *fname, int line, struct fl_tuple *ftuple), + TP_ARGS(fname, line, ftuple), + TP_STRUCT__entry(__string(f, fname) + __field(int, l) + __array(u8, smac, ETH_ALEN) + __array(u8, dmac, ETH_ALEN) + __field(u16, eth_type) + __field(u32, sip) + __field(u32, dip) + __field(u8, ip_proto) + __field(u16, sport) + __field(u16, dport) + __field(u8, uni_di) + __field(u16, in_pf) + __field(u16, out_pf) + ), + TP_fast_assign(__assign_str(f); + __entry->l =3D line; + memcpy(__entry->smac, ftuple->smac, ETH_ALEN); + memcpy(__entry->dmac, ftuple->dmac, ETH_ALEN); + __entry->sip =3D (__force u32)(ftuple->ip4src); + __entry->dip =3D (__force u32)(ftuple->ip4dst); + __entry->eth_type =3D (__force u16)ftuple->eth_type; + __entry->ip_proto =3D ftuple->proto; + __entry->sport =3D (__force u16)(ftuple->sport); + __entry->dport =3D (__force u16)(ftuple->dport); + __entry->uni_di =3D ftuple->uni_di; + __entry->in_pf =3D ftuple->in_pf; + __entry->out_pf =3D ftuple->xmit_pf; + ), + TP_printk("[%s:%d] %pM %pI4:%u to %pM %pI4:%u eth_type=3D%#x proto=3D= %u uni=3D%u in=3D%#x out=3D%#x", + __get_str(f), __entry->l, __entry->smac, &__entry->sip, __entry->s= port, + __entry->dmac, &__entry->dip, __entry->dport, + ntohs((__force __be16)__entry->eth_type), __entry->ip_proto, __ent= ry->uni_di, + __entry->in_pf, __entry->out_pf) +); + +TRACE_EVENT(sw_act_dump, + TP_PROTO(const char *fname, int line, u32 act), + TP_ARGS(fname, line, act), + TP_STRUCT__entry(__string(fname, fname) + __field(int, line) + __field(u32, act) + ), + + TP_fast_assign(__assign_str(fname); + __entry->line =3D line; + __entry->act =3D act; + ), + + TP_printk("[%s:%d] %u", + __get_str(fname), __entry->line, __entry->act) +); + +#endif + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH ../../drivers/net/ethernet/marvell/octeontx2/ni= c/switch/ + +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE sw_trace + +#include --=20 2.43.0