From nobody Fri Sep 25 03:16:18 2026 Received: from mail-ua1-f99.google.com (mail-ua1-f99.google.com [209.85.222.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED8054457AC for ; Thu, 17 Sep 2026 06:46:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.99 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627572; cv=none; b=m8psM0XhS/40+O7HTvrwFes64l0PecHWEfbtzaqmJyHYEh+usx8lJRSNC7IjUC2LE6lGpHFxinK/vBfmfw5BOb9NELi3Rqu1YOP6BPAA/VZnFIVZUvuQVICgOIXpP2RkI8IrV/RAPYQN4BnAJwpDOWl49OjJh8lQEIGwnoatCcA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627572; c=relaxed/simple; bh=7CTJlmlkpUV75kzLCWq5iYzg6XYHKDImSoSt4OPBDWY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K1py7k79J1ZXVNMpgtPwXMcXfYZVdpKzR9SO0XvNQe36+adWqdolQeA8AP9yA6gAZlLHUH8E8POzw3bLETAA254kdKnQRtaPYuxsMdGSDEkagtN4stgaiQvQ3fx29lCydlmge+eFMH8raU5yIEY47orrQllOsIJSIgIdCuSfJxc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=a9d6kqpW; arc=none smtp.client-ip=209.85.222.99 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="a9d6kqpW" Received: by mail-ua1-f99.google.com with SMTP id a1e0cc1a2514c-9809ce25a29so339375241.1 for ; Wed, 16 Sep 2026 23:46:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789627566; x=1790232366; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=SMSuN4WTt6I7qMCgUb4Qu38XrQnC03P67hyi5FUJGKw=; b=WFCyKW3L9GqCsKo1lZzXMSm6dcOAzLB/d1VBV0HNpPtFL5kUR+F9kJoYp4FJhtv2u7 7TnFIMePVIXOkYhp2zVIWCvlt/M20S+GUQqA/eR0uYEmrdtNjVsZ9kJHWQv0flW+VcPY 78Dx4/KOkrrUGxN58qfE8TPUfVQJJpNFART2un0Lk22aS2rxXWDNnaYckVqM2eARnBMc fIuR2UVeMDhkqyQ2Kvg/CyMhMirBBTzzBwUJ7vmSJpreG8Xn58kncWgtq/sK6cFthghx 942WPCYJ1HjmZYESe39YuLRHlfgXJG0Qq/gOEckmqcPuQDtZ0+qKu0FW/B3fuqPSBRWb M3dA== X-Forwarded-Encrypted: i=1; AKwUvBxbvX4yk5TORam9SbQhKiDHGnkw42OXCJQRG3Dl3+pieHozBBbVdQr4rt5HB+XTfoCxmy87w271+k+cJr4=@vger.kernel.org X-Gm-Message-State: AFuF++nVarymUUyQi5ATr2c26X/9DlTOSN8o1koCpVXR+8BVdfmh/chU STp6m6JVE53+r453qLUBsy/qMQRqJ6xi9ApArQ8mnvkrkcQU87mG2QLb2zquqPODqBQwebBQDJw edOxP8m7yG1+wUWZRzbt0klYwUqpdz+MTzTGfLQOA2zBCfLGAQcLxM4n3UPWIJImHdPeBY2H80C ksgc4dVTj+ZSYqlEQIdcWHh0MIgF+En0KVlRIajwSelh4lIbMJhUZEEnEErQw18tdGLX+S0lWrO 5Aw6GD+wYatrfbENA== X-Gm-Gg: AYBFou020Gql1cAPr+Wi8btSsIgk3FdsBkTsVVtxurhN38onofV+7RuL9Jd9UNUXwHm DMtVoVCKcEqJaa/UNsKFOPZbcboZdTWiOGrVhfmbDNQzY0SuvZaxftKEIL1/cVGA9AHiazAlChD omFC2j22hmjuLCPKrcxuiklojAybtmFP+V/XHXKmrJo53c3O98xN2SW89AvHL+POpFQNLnCE5xq nxWB328jaiTqp3O1q1eIwSb3460Tw/0MUKZQZrePBGDJMR7HVprJFNxNGo5ZUOWel4cJL4Rh4Mv bPEHB+oCSu4CM5JYC1Mc2LN2V5nYpIhrS+9WVQ0PLdqGaBxVrHSrQFLMoEwupn/Q5kB9xPE54Ko wL3w0BghbNTO7rLiMclcbXDEtBWyk4vdqeToXO5w1UIWDYMEO39bxdSBkSvtugaURwi8GeRoFqv Y3sK7DoDBi0RG2p9jMzFr0nZDLh2Fy0TFB5w== X-Received: by 2002:a05:6102:631a:20b0:7a1:f2b5:6462 with SMTP id ada2fe7eead31-7a1f2b5658dmr466501137.31.1789627565747; Wed, 16 Sep 2026 23:46:05 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-25.dlp.protect.broadcom.com. [144.49.247.25]) by smtp-relay.gmail.com with ESMTPS id a1e0cc1a2514c-983233e9fc2sm675735241.2.2026.09.16.23.46.05 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2026 23:46:05 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pg1-f199.google.com with SMTP id 41be03b00d2f7-cb48f41343aso451569a12.1 for ; Wed, 16 Sep 2026 23:46:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1789627564; x=1790232364; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=SMSuN4WTt6I7qMCgUb4Qu38XrQnC03P67hyi5FUJGKw=; b=a9d6kqpWtL8f3xL+pcNvBpp/Weaiqlufri4Yy8whZ6Nd2YUWHRkFDAYOtCs2zktuu6 ub20IFHF7NNTWK3sgoLoM7E9zVjbAB+oc2UUM9igWP9nlWsPLCbSU1vXJk1wIpdJcrlR WQJqQDwOWUo8W/dLmi3sNZUzwilnFizQPbqkQ= X-Forwarded-Encrypted: i=1; AKwUvBzyEwPwxEaTId3Rg5DXkWS6TchTg1kbGcL6kfRdxqO9cQDHkA8cocJMo7n9LVtx1uCQoyHhpE8I+geExRs=@vger.kernel.org X-Received: by 2002:a05:6a21:e8a:b0:3dd:65a5:a33 with SMTP id adf61e73a8af0-3dd725dca83mr3849714637.10.1789627564504; Wed, 16 Sep 2026 23:46:04 -0700 (PDT) X-Received: by 2002:a05:6a21:e8a:b0:3dd:65a5:a33 with SMTP id adf61e73a8af0-3dd725dca83mr3849663637.10.1789627563900; Wed, 16 Sep 2026 23:46:03 -0700 (PDT) Received: from H5S1 ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc50ab960edsm2754293a12.20.2026.09.16.23.45.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 23:46:03 -0700 (PDT) From: Vikas Gupta To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com, vsrama-krishna.nemani@broadcom.com, rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com, ajit.khaparde@broadcom.com, Vikas Gupta Subject: [net-next, v3 01/11] bnge: update HSI Date: Thu, 17 Sep 2026 12:15:38 +0530 Message-ID: <20260917064548.773334-2-vikas.gupta@broadcom.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260917064548.773334-1-vikas.gupta@broadcom.com> References: <20260917064548.773334-1-vikas.gupta@broadcom.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-DetectorID-Processed: b00c1d49-9d2e-4205-b15f-d015386d3d5e Content-Type: text/plain; charset="utf-8" Update HSI to support future patches implementing multi-RSS and NTUPLE-related features. Signed-off-by: Vikas Gupta Reviewed-by: Dharmender Garg --- include/linux/bnge/hsi.h | 136 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-) diff --git a/include/linux/bnge/hsi.h b/include/linux/bnge/hsi.h index 1f7bd96415a5..d4fe662d60b1 100644 --- a/include/linux/bnge/hsi.h +++ b/include/linux/bnge/hsi.h @@ -8607,6 +8607,7 @@ struct hwrm_cfa_l2_filter_alloc_input { #define CFA_L2_FILTER_ALLOC_REQ_ENABLES_MIRROR_VNIC_ID 0x10000UL #define CFA_L2_FILTER_ALLOC_REQ_ENABLES_NUM_VLANS 0x20000UL #define CFA_L2_FILTER_ALLOC_REQ_ENABLES_T_NUM_VLANS 0x40000UL + #define CFA_L2_FILTER_ALLOC_REQ_ENABLES_RFS_RING_TBL_IDX 0x80000UL u8 l2_addr[6]; u8 num_vlans; u8 t_num_vlans; @@ -8663,7 +8664,8 @@ struct hwrm_cfa_l2_filter_alloc_input { #define CFA_L2_FILTER_ALLOC_REQ_PRI_HINT_MIN 0x4UL #define CFA_L2_FILTER_ALLOC_REQ_PRI_HINT_LAST CFA_L2_FILTER_ALLOC_= REQ_PRI_HINT_MIN u8 unused_5; - __le32 unused_6; + __le16 rfs_ring_tbl_idx; + __le16 unused_6; __le64 l2_filter_id_hint; }; =20 @@ -8900,6 +8902,95 @@ struct hwrm_cfa_tunnel_filter_free_output { u8 valid; }; =20 +/* hwrm_cfa_ntuple_filter_alloc_input (size:1024b/128B) */ +struct hwrm_cfa_ntuple_filter_alloc_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le32 flags; + #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_LOOPBACK 0x1UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DROP 0x2UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_METER 0x4UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DEST_FID 0x8UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_ARP_REPLY 0x10UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DEST_RFS_RING_IDX 0x20UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_NO_L2_CONTEXT 0x40UL + __le32 enables; + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_L2_FILTER_ID 0x1UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_ETHERTYPE 0x2UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_TUNNEL_TYPE 0x4UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_MACADDR 0x8UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_IPADDR_TYPE 0x10UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR 0x20UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR_MASK 0x40UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_IPADDR 0x80UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_IPADDR_MASK 0x100UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_IP_PROTOCOL 0x200UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_PORT 0x400UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_PORT_MASK 0x800UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_PORT 0x1000UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_PORT_MASK 0x2000UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_PRI_HINT 0x4000UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_NTUPLE_FILTER_ID 0x8000UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_ID 0x10000UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_MIRROR_VNIC_ID 0x20000UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_MACADDR 0x40000UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_RFS_RING_TBL_IDX 0x80000UL + __le64 l2_filter_id; + u8 src_macaddr[6]; + __be16 ethertype; + u8 ip_addr_type; + #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_UNKNOWN 0x0UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV4 0x4UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV6 0x6UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_LAST CFA_NTUPLE_FILTER= _ALLOC_REQ_IP_ADDR_TYPE_IPV6 + u8 ip_protocol; + #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_UNKNOWN 0x0UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_TCP 0x6UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_UDP 0x11UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_ICMP 0x1UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_ICMPV6 0x3aUL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_RSVD 0xffUL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_LAST CFA_NTUPLE_FILTER_= ALLOC_REQ_IP_PROTOCOL_RSVD + __le16 dst_id; + __le16 rfs_ring_tbl_idx; + u8 tunnel_type; + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NONTUNNEL 0x0UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN 0x1UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE 0x2UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_L2GRE 0x3UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPIP 0x4UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_GENEVE 0x5UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_MPLS 0x6UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_STT 0x7UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE 0x8UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE_V1 0xaUL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_L2_ETYPE 0xbUL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN_GPE_V6 0xcUL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN_GPE 0x10UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL 0xffUL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_LAST CFA_NTUPLE_FI= LTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL + u8 pri_hint; + #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_NO_PREFER 0x0UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_ABOVE 0x1UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_BELOW 0x2UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_HIGHEST 0x3UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_LOWEST 0x4UL + #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_LAST CFA_NTUPLE_FILTER_A= LLOC_REQ_PRI_HINT_LOWEST + __be32 src_ipaddr[4]; + __be32 src_ipaddr_mask[4]; + __be32 dst_ipaddr[4]; + __be32 dst_ipaddr_mask[4]; + __be16 src_port; + __be16 src_port_mask; + __be16 dst_port; + __be16 dst_port_mask; + __le64 ntuple_filter_id_hint; +}; + /* hwrm_cfa_ntuple_filter_alloc_output (size:192b/24B) */ struct hwrm_cfa_ntuple_filter_alloc_output { __le16 error_code; @@ -9014,6 +9105,49 @@ struct hwrm_cfa_ntuple_filter_cfg_output { u8 valid; }; =20 +/* hwrm_cfa_adv_flow_mgnt_qcaps_input (size:256b/32B) */ +struct hwrm_cfa_adv_flow_mgnt_qcaps_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le32 unused_0[4]; +}; + +/* hwrm_cfa_adv_flow_mgnt_qcaps_output (size:128b/16B) */ +struct hwrm_cfa_adv_flow_mgnt_qcaps_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le32 flags; + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_FLOW_HND_16BIT_SUPPORTED = 0x1UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_FLOW_HND_64BIT_SUPPORTED = 0x2UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_FLOW_BATCH_DELETE_SUPPORTED = 0x4UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_FLOW_RESET_ALL_SUPPORTED = 0x8UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NTUPLE_FLOW_DEST_FUNC_SUPPORTE= D 0x10UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_TX_EEM_FLOW_SUPPORTED = 0x20UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_RX_EEM_FLOW_SUPPORTED = 0x40UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_FLOW_COUNTER_ALLOC_SUPPORTED = 0x80UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_RFS_RING_TBL_IDX_SUPPORTED = 0x100UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_UNTAGGED_VLAN_SUPPORTED = 0x200UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_XDP_SUPPORTED = 0x400UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_L2_HEADER_SOURCE_FIELDS_SUPPOR= TED 0x800UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NTUPLE_FLOW_RX_ARP_SUPPORTED = 0x1000UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_RFS_RING_TBL_IDX_V2_SUPPORTED = 0x2000UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NTUPLE_FLOW_RX_ETHERTYPE_IP_SU= PPORTED 0x4000UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_TRUFLOW_CAPABLE = 0x8000UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_L2_FILTER_TRAFFIC_TYPE_L2_ROCE= _SUPPORTED 0x10000UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_LAG_SUPPORTED = 0x20000UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NTUPLE_FLOW_NO_L2CTX_SUPPORTED= 0x40000UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NIC_FLOW_STATS_SUPPORTED = 0x80000UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NTUPLE_FLOW_RX_EXT_IP_PROTO_SU= PPORTED 0x100000UL + #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_RFS_RING_TBL_IDX_V3_SUPPORTED = 0x200000UL + u8 unused_0[3]; + u8 valid; +}; + /* hwrm_tunnel_dst_port_alloc_input (size:192b/24B) */ struct hwrm_tunnel_dst_port_alloc_input { __le16 req_type; --=20 2.52.0 From nobody Fri Sep 25 03:16:18 2026 Received: from mail-pg1-f227.google.com (mail-pg1-f227.google.com [209.85.215.227]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9394E44236C for ; Thu, 17 Sep 2026 06:46:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.227 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627575; cv=none; b=VAsGRjDqs8tzALDKDfNYwabRM8CyVNlMbcIe+b6QLeEE3Y2K9Azgj9pW298DIjOgMmKm1vdMhyTf+4wA3Sa05rQMMETbefMmINAiFjFQPh/NLyG/8n0E4XdrljKJFoLElOylsbfBV3zfC4b4Ny1XYPArQ0uMLLTBasXrJqfSb9E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627575; c=relaxed/simple; bh=+neVQHy/a/XpTpeXkgvVEjnXSohEwN5Mxj/PeYy6YL0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UQIWc0I9j7mU8JBa4JrkG0OCOfMIu7+nnX3jxLOOOXKVkc6gPQBBemjDFs97CcJ6mI2B9nZqZmSEujy3FHKiE8CWhkuUFVo3lobUpDclg3owB3FNAZ3GVfm9TJzTr0veJC2BOlrNCMkW8BI4j/Yau1bRAQsXta8f7Wk8mcpB164= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=GXWnxi9o; arc=none smtp.client-ip=209.85.215.227 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="GXWnxi9o" Received: by mail-pg1-f227.google.com with SMTP id 41be03b00d2f7-cc4be0e5351so58534a12.0 for ; Wed, 16 Sep 2026 23:46:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789627573; x=1790232373; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=OdtHI0n4iqvwr04IuorftxO7ZjIWxdozmmIlywJMFHA=; b=hF8rH7Wwzhkcm/IrMnIGbE/hkE60/2/TcASWoBFHpC/PIjVCh/G+Wo+rK2m0fFFizd kfujGtadlzNB67KZ4DlWPp7jZPBzfnORasqUs66DOnGFgvW4ROfmUFl74aUQ+qYkICGy c9WlUTe5UmkiUdgKGMm2IQF5u7zfZwOaFLu7JDn9IEm1H1dPnV/x1NRcNYJeIiNAhXCC NST6Ml63A/0ZALvld3dC+/qta+PM2/Jnr0fJurdC7KsHEIi5+WvclboexDXOiIWupSdL LTVdET8ZK+fAz9eZJ/qGnJ1FeNn607Bh4zTCLEVIRE1nuOmevF8ODJGNdWEN4/lVo0qo 9n6A== X-Forwarded-Encrypted: i=1; AKwUvBzvJHmTCstUa4g85uaMj6rSTV6fNYKvgwctvW+jhLOOJksvTd7Ea7w8U14i8wRZiJz5ls3troS4dwqFKfM=@vger.kernel.org X-Gm-Message-State: AFuF++lE8u5d6Kf1CdoGHPGMiRK8GddBXylezvNHdGMhEshM1bkDbMUS iPdWC4qsbUT1mtq1oob2P2k4Av2TRJPsM1rijQRYXbphuUy0CXUvWhiA6zYvu2mBt/XynBVqBr3 hrSn86ZvIfdRepv9ttH1jKK40ZmRjoH/EPt9/yqkWN1Y6qBYqgzqs+T8T3dI/J6vDds6sRN8d5i nK9CP8q8BbUEaBkET0DaqWJ0gQkgfv3xO/8hkdvFoKeZIDgnuQpd38GkEyz1hdqKOKnh0zNktL5 PsafTasgItBTZIiuw== X-Gm-Gg: AYBFou3DNqhLb/VzwuT3f23dbHUMh9GEc5JTFuGqfm/QXu9JnAMazKfEN9xhyfjTDV+ wdah3fagj7pjKLrvw5FgvQNoeDm7SaS6WzktWmi/RoaU5o+Pi5a+oOy9alv854d29Skr+kaDMbl mufe4CRkCYz+KO7Dejwk6GeO1JAGOToBf6Z+aEtGAjzFp0LSOVCtU9sdKVGx6vA9FtCKmYTQNsd e33vNeRPnezSnNLJrWYb3r7l8RlFfLEC65maOvHj1exNZFoF+KNwDwoz5aXSBOMtf+uOUpzWB3Q IW5SwTcfPzS9Vq58YwVAaxEoLOjCFwNBZ2ahIo4CId3ROg662Puxn/Do/jXj+g8t9aeQC7wnePA kbAwNFgL+0SWLaxo37QzoMQrlyr9cD/HjCk7OZ4hCYlxluj9A3LdwkgAYyofxDEgsl1fuNceKr0 83RjW3RF8c88JBHhgWbBc5qbIwJ2ZT870UIg== X-Received: by 2002:a17:90b:384c:b0:38e:9ef9:eb97 with SMTP id 98e67ed59e1d1-39e1e48a0c5mr11852709a91.16.1789627572704; Wed, 16 Sep 2026 23:46:12 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-29.dlp.protect.broadcom.com. [144.49.247.29]) by smtp-relay.gmail.com with ESMTPS id 98e67ed59e1d1-39e390b3c6fsm171008a91.0.2026.09.16.23.46.12 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2026 23:46:12 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-8710450f731so725802b3a.0 for ; Wed, 16 Sep 2026 23:46:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1789627571; x=1790232371; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OdtHI0n4iqvwr04IuorftxO7ZjIWxdozmmIlywJMFHA=; b=GXWnxi9ocu/J/RAvOUve9oZhK25LVylluLNwghsX9h4Nny9KXOtBMqsSNCZW48YqFr 408RIPxLSwuFj0EhWBAj3J4zmWU+aLXYHnKefaxI0jyjBWapdTdghrMJIfpX0s7q0whz Ufzv8ryzjeMdH5fmZFbwdCzMEmES5ZzRUBEvA= X-Forwarded-Encrypted: i=1; AKwUvBwBgwba5lmw+08RxjgUU1KTMnbPPIflTHo6i7XZ5G/5glixSZ5JA1Q5b8lI2pCKZDSBpVnD5Da+UfW4vo4=@vger.kernel.org X-Received: by 2002:a05:6a00:ad84:b0:869:c368:3675 with SMTP id d2e1a72fcca58-87238f94fb7mr12002182b3a.17.1789627570531; Wed, 16 Sep 2026 23:46:10 -0700 (PDT) X-Received: by 2002:a05:6a00:ad84:b0:869:c368:3675 with SMTP id d2e1a72fcca58-87238f94fb7mr12002138b3a.17.1789627569971; Wed, 16 Sep 2026 23:46:09 -0700 (PDT) Received: from H5S1 ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc50ab960edsm2754293a12.20.2026.09.16.23.46.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 23:46:09 -0700 (PDT) From: Vikas Gupta To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com, vsrama-krishna.nemani@broadcom.com, rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com, ajit.khaparde@broadcom.com, Vikas Gupta Subject: [net-next, v3 02/11] bnge: restructure VNIC and filter code Date: Thu, 17 Sep 2026 12:15:39 +0530 Message-ID: <20260917064548.773334-3-vikas.gupta@broadcom.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260917064548.773334-1-vikas.gupta@broadcom.com> References: <20260917064548.773334-1-vikas.gupta@broadcom.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-DetectorID-Processed: b00c1d49-9d2e-4205-b15f-d015386d3d5e Content-Type: text/plain; charset="utf-8" Move VNIC and L2 filter code out of bnge_netdev.c into dedicated bnge_vnic.c/h and bnge_filter.c/h files in preparation for multi-VNIC, RSS context, and NTUPLE filter support. This is a code reorganization with no functional change, which helps centralize the functions into their respective modules. Reviewed-by: Dharmender Garg Signed-off-by: Vikas Gupta --- drivers/net/ethernet/broadcom/bnge/Makefile | 4 +- drivers/net/ethernet/broadcom/bnge/bnge.h | 7 - .../net/ethernet/broadcom/bnge/bnge_filter.c | 113 ++++++++++++ .../net/ethernet/broadcom/bnge/bnge_filter.h | 54 ++++++ .../ethernet/broadcom/bnge/bnge_hwrm_lib.c | 2 + .../ethernet/broadcom/bnge/bnge_hwrm_lib.h | 2 + .../net/ethernet/broadcom/bnge/bnge_netdev.c | 170 +----------------- .../net/ethernet/broadcom/bnge/bnge_netdev.h | 72 -------- .../net/ethernet/broadcom/bnge/bnge_resc.c | 31 +--- .../net/ethernet/broadcom/bnge/bnge_vnic.c | 100 +++++++++++ .../net/ethernet/broadcom/bnge/bnge_vnic.h | 62 +++++++ 11 files changed, 345 insertions(+), 272 deletions(-) create mode 100644 drivers/net/ethernet/broadcom/bnge/bnge_filter.c create mode 100644 drivers/net/ethernet/broadcom/bnge/bnge_filter.h create mode 100644 drivers/net/ethernet/broadcom/bnge/bnge_vnic.c create mode 100644 drivers/net/ethernet/broadcom/bnge/bnge_vnic.h diff --git a/drivers/net/ethernet/broadcom/bnge/Makefile b/drivers/net/ethe= rnet/broadcom/bnge/Makefile index 8e07cb307d21..d0a3cb24dc1d 100644 --- a/drivers/net/ethernet/broadcom/bnge/Makefile +++ b/drivers/net/ethernet/broadcom/bnge/Makefile @@ -12,4 +12,6 @@ bng_en-y :=3D bnge_core.o \ bnge_ethtool.o \ bnge_auxr.o \ bnge_txrx.o \ - bnge_link.o + bnge_link.o \ + bnge_vnic.o \ + bnge_filter.o diff --git a/drivers/net/ethernet/broadcom/bnge/bnge.h b/drivers/net/ethern= et/broadcom/bnge/bnge.h index 4479ccd071f5..bde54ba5d50f 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge.h @@ -163,13 +163,6 @@ struct bnge_dev { #define BNGE_L2_FLTR_MAX_FLTR 1024 =20 u32 *rss_indir_tbl; -#define BNGE_RSS_TABLE_ENTRIES 64 -#define BNGE_RSS_TABLE_SIZE (BNGE_RSS_TABLE_ENTRIES * 4) -#define BNGE_RSS_TABLE_MAX_TBL 8 -#define BNGE_MAX_RSS_TABLE_SIZE \ - (BNGE_RSS_TABLE_SIZE * BNGE_RSS_TABLE_MAX_TBL) -#define BNGE_MAX_RSS_TABLE_ENTRIES \ - (BNGE_RSS_TABLE_ENTRIES * BNGE_RSS_TABLE_MAX_TBL) u16 rss_indir_tbl_entries; =20 u32 rss_cap; diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.c b/drivers/net= /ethernet/broadcom/bnge/bnge_filter.c new file mode 100644 index 000000000000..d1279a4babcd --- /dev/null +++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2026 Broadcom. + +#include +#include +#include + +#include "bnge.h" +#include "bnge_netdev.h" +#include "bnge_vnic.h" +#include "bnge_hwrm_lib.h" +#include "bnge_filter.h" + +void bnge_del_l2_filter(struct bnge_net *bn, struct bnge_l2_filter *fltr) +{ + if (!refcount_dec_and_test(&fltr->refcnt)) + return; + hlist_del_rcu(&fltr->base.hlist); + kfree_rcu(fltr, base.rcu); +} + +static void bnge_init_l2_filter(struct bnge_net *bn, + struct bnge_l2_filter *fltr, + struct bnge_l2_key *key, u32 idx) +{ + struct hlist_head *head; + + ether_addr_copy(fltr->l2_key.dst_mac_addr, key->dst_mac_addr); + fltr->l2_key.vlan =3D key->vlan; + fltr->base.type =3D BNGE_FLTR_TYPE_L2; + + head =3D &bn->l2_fltr_hash_tbl[idx]; + hlist_add_head_rcu(&fltr->base.hlist, head); + refcount_set(&fltr->refcnt, 1); +} + +static struct bnge_l2_filter *__bnge_lookup_l2_filter(struct bnge_net *bn, + struct bnge_l2_key *key, + u32 idx) +{ + struct bnge_l2_filter *fltr; + struct hlist_head *head; + + head =3D &bn->l2_fltr_hash_tbl[idx]; + hlist_for_each_entry_rcu(fltr, head, base.hlist) { + struct bnge_l2_key *l2_key =3D &fltr->l2_key; + + if (ether_addr_equal(l2_key->dst_mac_addr, key->dst_mac_addr) && + l2_key->vlan =3D=3D key->vlan) + return fltr; + } + return NULL; +} + +struct bnge_l2_filter *bnge_lookup_l2_filter(struct bnge_net *bn, + struct bnge_l2_key *key, + u32 idx) +{ + struct bnge_l2_filter *fltr; + + rcu_read_lock(); + fltr =3D __bnge_lookup_l2_filter(bn, key, idx); + if (fltr) + refcount_inc(&fltr->refcnt); + rcu_read_unlock(); + return fltr; +} + +static struct bnge_l2_filter *bnge_alloc_l2_filter(struct bnge_net *bn, + struct bnge_l2_key *key, + gfp_t gfp) +{ + struct bnge_l2_filter *fltr; + u32 idx; + + idx =3D jhash2(&key->filter_key, BNGE_L2_KEY_SIZE, bn->hash_seed) & + BNGE_L2_FLTR_HASH_MASK; + fltr =3D bnge_lookup_l2_filter(bn, key, idx); + if (fltr) + return fltr; + + fltr =3D kzalloc_obj(*fltr, gfp); + if (!fltr) + return ERR_PTR(-ENOMEM); + + bnge_init_l2_filter(bn, fltr, key, idx); + return fltr; +} + +int bnge_hwrm_set_vnic_filter(struct bnge_net *bn, u16 vnic_id, u16 idx, + const u8 *mac_addr) +{ + struct bnge_l2_filter *fltr; + struct bnge_l2_key key; + int rc; + + ether_addr_copy(key.dst_mac_addr, mac_addr); + key.vlan =3D 0; + fltr =3D bnge_alloc_l2_filter(bn, &key, GFP_KERNEL); + if (IS_ERR(fltr)) + return PTR_ERR(fltr); + + fltr->base.fw_vnic_id =3D bn->vnic_info[vnic_id].fw_vnic_id; + rc =3D bnge_hwrm_l2_filter_alloc(bn->bd, fltr); + if (rc) + goto err_del_l2_filter; + bn->vnic_info[vnic_id].l2_filters[idx] =3D fltr; + return rc; + +err_del_l2_filter: + bnge_del_l2_filter(bn, fltr); + return rc; +} diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.h b/drivers/net= /ethernet/broadcom/bnge/bnge_filter.h new file mode 100644 index 000000000000..44ee1357a0ff --- /dev/null +++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2026 Broadcom */ + +#ifndef _BNGE_FILTER_H_ +#define _BNGE_FILTER_H_ + +enum { + BNGE_FLTR_TYPE_L2 =3D 1 +}; + +enum { + BNGE_FLTR_VALID, + BNGE_FLTR_FW_DELETED +}; + +struct bnge_filter_base { + struct hlist_node hlist; + struct list_head list_node; + __le64 filter_id; + u8 type; + u8 flags; + u16 rxq; + u16 fw_vnic_id; + u16 vf_idx; + unsigned long state; + + struct rcu_head rcu; +}; + +struct bnge_l2_key { + union { + struct { + u8 dst_mac_addr[ETH_ALEN]; + u16 vlan; + }; + u32 filter_key; + }; +}; + +#define BNGE_L2_KEY_SIZE (sizeof(struct bnge_l2_key) / 4) +struct bnge_l2_filter { + /* base filter must be the first member */ + struct bnge_filter_base base; + struct bnge_l2_key l2_key; + refcount_t refcnt; +}; + +void bnge_del_l2_filter(struct bnge_net *bn, struct bnge_l2_filter *fltr); +struct bnge_l2_filter *bnge_lookup_l2_filter(struct bnge_net *bn, + struct bnge_l2_key *key, + u32 idx); +int bnge_hwrm_set_vnic_filter(struct bnge_net *bn, u16 vnic_id, u16 idx, + const u8 *mac_addr); +#endif /* _BNGE_FILTER_H_ */ diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/n= et/ethernet/broadcom/bnge/bnge_hwrm_lib.c index 651c5e783516..91d246c8dcf2 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c @@ -15,6 +15,8 @@ #include "bnge_rmem.h" #include "bnge_resc.h" #include "bnge_netdev.h" +#include "bnge_vnic.h" +#include "bnge_filter.h" =20 static const u16 bnge_async_events_arr[] =3D { ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE, diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h b/drivers/n= et/ethernet/broadcom/bnge/bnge_hwrm_lib.h index bf452e390d5b..ae03041c36ac 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h @@ -4,6 +4,8 @@ #ifndef _BNGE_HWRM_LIB_H_ #define _BNGE_HWRM_LIB_H_ =20 +struct bnge_l2_filter; + #define BNGE_PLC_EN_JUMBO_THRES_VALID \ VNIC_PLCMODES_CFG_REQ_ENABLES_JUMBO_THRESH_VALID #define BNGE_PLC_EN_HDS_THRES_VALID \ diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.c index a4288f0258f8..9e64b1933c02 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -25,6 +25,8 @@ #include "bnge_ethtool.h" #include "bnge_rmem.h" #include "bnge_txrx.h" +#include "bnge_vnic.h" +#include "bnge_filter.h" =20 #define BNGE_RING_TO_TC_OFF(bd, tx) \ ((tx) % (bd)->tx_nr_rings_per_tc) @@ -1977,174 +1979,6 @@ static int bnge_hwrm_ring_alloc(struct bnge_net *bn) return rc; } =20 -void bnge_fill_hw_rss_tbl(struct bnge_net *bn, struct bnge_vnic_info *vnic) -{ - __le16 *ring_tbl =3D vnic->rss_table; - struct bnge_rx_ring_info *rxr; - struct bnge_dev *bd =3D bn->bd; - u16 tbl_size, i; - - tbl_size =3D bnge_get_rxfh_indir_size(bd); - - for (i =3D 0; i < tbl_size; i++) { - u32 j; - - j =3D bd->rss_indir_tbl[i]; - rxr =3D &bn->rx_ring[j]; - - *ring_tbl++ =3D cpu_to_le16(rxr->rx_ring_struct.fw_ring_id); - *ring_tbl++ =3D cpu_to_le16(bnge_cp_ring_for_rx(rxr)); - } -} - -static int bnge_hwrm_vnic_rss_cfg(struct bnge_net *bn, - struct bnge_vnic_info *vnic) -{ - int rc; - - rc =3D bnge_hwrm_vnic_set_rss(bn, vnic, true); - if (rc) { - netdev_err(bn->netdev, "hwrm vnic %d set rss failure rc: %d\n", - vnic->vnic_id, rc); - return rc; - } - rc =3D bnge_hwrm_vnic_cfg(bn, vnic); - if (rc) - netdev_err(bn->netdev, "hwrm vnic %d cfg failure rc: %d\n", - vnic->vnic_id, rc); - return rc; -} - -static int bnge_setup_vnic(struct bnge_net *bn, struct bnge_vnic_info *vni= c) -{ - struct bnge_dev *bd =3D bn->bd; - int rc, i, nr_ctxs; - - nr_ctxs =3D bnge_cal_nr_rss_ctxs(bd->rx_nr_rings); - for (i =3D 0; i < nr_ctxs; i++) { - rc =3D bnge_hwrm_vnic_ctx_alloc(bd, vnic, i); - if (rc) { - netdev_err(bn->netdev, "hwrm vnic %d ctx %d alloc failure rc: %d\n", - vnic->vnic_id, i, rc); - return -ENOMEM; - } - bn->rsscos_nr_ctxs++; - } - - rc =3D bnge_hwrm_vnic_rss_cfg(bn, vnic); - if (rc) - return rc; - - if (bnge_is_agg_reqd(bd)) { - rc =3D bnge_hwrm_vnic_set_hds(bn, vnic); - if (rc) - netdev_err(bn->netdev, "hwrm vnic %d set hds failure rc: %d\n", - vnic->vnic_id, rc); - } - return rc; -} - -static void bnge_del_l2_filter(struct bnge_net *bn, struct bnge_l2_filter = *fltr) -{ - if (!refcount_dec_and_test(&fltr->refcnt)) - return; - hlist_del_rcu(&fltr->base.hash); - kfree_rcu(fltr, base.rcu); -} - -static void bnge_init_l2_filter(struct bnge_net *bn, - struct bnge_l2_filter *fltr, - struct bnge_l2_key *key, u32 idx) -{ - struct hlist_head *head; - - ether_addr_copy(fltr->l2_key.dst_mac_addr, key->dst_mac_addr); - fltr->l2_key.vlan =3D key->vlan; - fltr->base.type =3D BNGE_FLTR_TYPE_L2; - - head =3D &bn->l2_fltr_hash_tbl[idx]; - hlist_add_head_rcu(&fltr->base.hash, head); - refcount_set(&fltr->refcnt, 1); -} - -static struct bnge_l2_filter *__bnge_lookup_l2_filter(struct bnge_net *bn, - struct bnge_l2_key *key, - u32 idx) -{ - struct bnge_l2_filter *fltr; - struct hlist_head *head; - - head =3D &bn->l2_fltr_hash_tbl[idx]; - hlist_for_each_entry_rcu(fltr, head, base.hash) { - struct bnge_l2_key *l2_key =3D &fltr->l2_key; - - if (ether_addr_equal(l2_key->dst_mac_addr, key->dst_mac_addr) && - l2_key->vlan =3D=3D key->vlan) - return fltr; - } - return NULL; -} - -static struct bnge_l2_filter *bnge_lookup_l2_filter(struct bnge_net *bn, - struct bnge_l2_key *key, - u32 idx) -{ - struct bnge_l2_filter *fltr; - - rcu_read_lock(); - fltr =3D __bnge_lookup_l2_filter(bn, key, idx); - if (fltr) - refcount_inc(&fltr->refcnt); - rcu_read_unlock(); - return fltr; -} - -static struct bnge_l2_filter *bnge_alloc_l2_filter(struct bnge_net *bn, - struct bnge_l2_key *key, - gfp_t gfp) -{ - struct bnge_l2_filter *fltr; - u32 idx; - - idx =3D jhash2(&key->filter_key, BNGE_L2_KEY_SIZE, bn->hash_seed) & - BNGE_L2_FLTR_HASH_MASK; - fltr =3D bnge_lookup_l2_filter(bn, key, idx); - if (fltr) - return fltr; - - fltr =3D kzalloc_obj(*fltr, gfp); - if (!fltr) - return ERR_PTR(-ENOMEM); - - bnge_init_l2_filter(bn, fltr, key, idx); - return fltr; -} - -static int bnge_hwrm_set_vnic_filter(struct bnge_net *bn, u16 vnic_id, u16= idx, - const u8 *mac_addr) -{ - struct bnge_l2_filter *fltr; - struct bnge_l2_key key; - int rc; - - ether_addr_copy(key.dst_mac_addr, mac_addr); - key.vlan =3D 0; - fltr =3D bnge_alloc_l2_filter(bn, &key, GFP_KERNEL); - if (IS_ERR(fltr)) - return PTR_ERR(fltr); - - fltr->base.fw_vnic_id =3D bn->vnic_info[vnic_id].fw_vnic_id; - rc =3D bnge_hwrm_l2_filter_alloc(bn->bd, fltr); - if (rc) - goto err_del_l2_filter; - bn->vnic_info[vnic_id].l2_filters[idx] =3D fltr; - return rc; - -err_del_l2_filter: - bnge_del_l2_filter(bn, fltr); - return rc; -} - static bool bnge_mc_list_updated(struct bnge_net *bn, u32 *rx_mask, const struct netdev_hw_addr_list *mc) { diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.h index 476b5bab96fe..ee649cc644db 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h @@ -558,8 +558,6 @@ struct bnge_napi { }; =20 #define INVALID_STATS_CTX_ID -1 -#define BNGE_VNIC_DEFAULT 0 -#define BNGE_MAX_UC_ADDRS 4 =20 #define BNGE_RX_MASK_CFG_FLAGS \ (CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS | \ @@ -567,78 +565,8 @@ struct bnge_napi { CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST | \ CFA_L2_SET_RX_MASK_REQ_MASK_BCAST) =20 -struct bnge_vnic_info { - u16 fw_vnic_id; -#define BNGE_MAX_CTX_PER_VNIC 8 - u16 fw_rss_cos_lb_ctx[BNGE_MAX_CTX_PER_VNIC]; - u16 mru; - /* index 0 always dev_addr */ - struct bnge_l2_filter *l2_filters[BNGE_MAX_UC_ADDRS]; - u16 uc_filter_count; - u8 *uc_list; - dma_addr_t rss_table_dma_addr; - __le16 *rss_table; - dma_addr_t rss_hash_key_dma_addr; - u64 *rss_hash_key; - int rss_table_size; -#define BNGE_RSS_TABLE_ENTRIES 64 -#define BNGE_RSS_TABLE_SIZE (BNGE_RSS_TABLE_ENTRIES * 4) -#define BNGE_RSS_TABLE_MAX_TBL 8 -#define BNGE_MAX_RSS_TABLE_SIZE \ - (BNGE_RSS_TABLE_SIZE * BNGE_RSS_TABLE_MAX_TBL) - u32 rx_mask; - - u8 *mc_list; - int mc_list_size; - int mc_list_count; - dma_addr_t mc_list_mapping; -#define BNGE_MAX_MC_ADDRS 16 - - u32 flags; -#define BNGE_VNIC_RSS_FLAG 1 -#define BNGE_VNIC_MCAST_FLAG 4 -#define BNGE_VNIC_UCAST_FLAG 8 - u32 vnic_id; -}; - -struct bnge_filter_base { - struct hlist_node hash; - struct list_head list; - __le64 filter_id; - u8 type; -#define BNGE_FLTR_TYPE_L2 2 - u8 flags; - u16 rxq; - u16 fw_vnic_id; - u16 vf_idx; - unsigned long state; -#define BNGE_FLTR_VALID 0 -#define BNGE_FLTR_FW_DELETED 2 - - struct rcu_head rcu; -}; - -struct bnge_l2_key { - union { - struct { - u8 dst_mac_addr[ETH_ALEN]; - u16 vlan; - }; - u32 filter_key; - }; -}; - -#define BNGE_L2_KEY_SIZE (sizeof(struct bnge_l2_key) / 4) -struct bnge_l2_filter { - /* base filter must be the first member */ - struct bnge_filter_base base; - struct bnge_l2_key l2_key; - refcount_t refcnt; -}; - u32 bnge_cp_ring_for_rx(struct bnge_rx_ring_info *rxr); u32 bnge_cp_ring_for_tx(struct bnge_tx_ring_info *txr); -void bnge_fill_hw_rss_tbl(struct bnge_net *bn, struct bnge_vnic_info *vnic= ); int bnge_alloc_rx_data(struct bnge_net *bn, struct bnge_rx_ring_info *rxr, u16 prod, gfp_t gfp); u16 bnge_find_next_agg_idx(struct bnge_rx_ring_info *rxr, u16 idx); diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c b/drivers/net/e= thernet/broadcom/bnge/bnge_resc.c index 4711dd4945ff..69a894b52485 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_resc.c @@ -11,6 +11,7 @@ #include "bnge_hwrm.h" #include "bnge_hwrm_lib.h" #include "bnge_resc.h" +#include "bnge_vnic.h" =20 static u16 bnge_num_tx_to_cp(struct bnge_dev *bd, u16 tx) { @@ -186,13 +187,13 @@ int bnge_cal_nr_rss_ctxs(u16 rx_rings) BNGE_RSS_TABLE_ENTRIES); } =20 -static u16 bnge_rss_ctxs_in_use(struct bnge_dev *bd, - struct bnge_hw_rings *hwr) +static u16 bnge_get_total_rss_ctxs(struct bnge_dev *bd, + struct bnge_hw_rings *hwr) { return bnge_cal_nr_rss_ctxs(hwr->grp); } =20 -static u16 bnge_get_total_vnics(struct bnge_dev *bd, u16 rx_rings) +static u16 bnge_get_total_vnics(struct bnge_dev *bd) { return 1; } @@ -203,24 +204,6 @@ u32 bnge_get_rxfh_indir_size(struct bnge_dev *bd) BNGE_RSS_TABLE_ENTRIES; } =20 -static void bnge_set_dflt_rss_indir_tbl(struct bnge_dev *bd) -{ - u16 max_entries, pad; - u32 *rss_indir_tbl; - int i; - - max_entries =3D bnge_get_rxfh_indir_size(bd); - rss_indir_tbl =3D &bd->rss_indir_tbl[0]; - - for (i =3D 0; i < max_entries; i++) - rss_indir_tbl[i] =3D ethtool_rxfh_indir_default(i, - bd->rx_nr_rings); - - pad =3D bd->rss_indir_tbl_entries - max_entries; - if (pad) - memset(&rss_indir_tbl[i], 0, pad * sizeof(*rss_indir_tbl)); -} - static void bnge_copy_reserved_rings(struct bnge_dev *bd, struct bnge_hw_rings *hwr) { @@ -253,7 +236,7 @@ static bool bnge_need_reserve_rings(struct bnge_dev *bd) if (hw_resc->resv_tx_rings !=3D bd->tx_nr_rings) return true; =20 - vnic =3D bnge_get_total_vnics(bd, rx); + vnic =3D bnge_get_total_vnics(bd); =20 if (bnge_is_agg_reqd(bd)) rx <<=3D 1; @@ -299,12 +282,12 @@ int bnge_reserve_rings(struct bnge_dev *bd) sh =3D true; hwr.cmpl =3D hwr.rx + hwr.tx; =20 - hwr.vnic =3D bnge_get_total_vnics(bd, hwr.rx); + hwr.vnic =3D bnge_get_total_vnics(bd); =20 if (bnge_is_agg_reqd(bd)) hwr.rx <<=3D 1; hwr.grp =3D bd->rx_nr_rings; - hwr.rss_ctx =3D bnge_rss_ctxs_in_use(bd, &hwr); + hwr.rss_ctx =3D bnge_get_total_rss_ctxs(bd, &hwr); hwr.stat =3D bnge_func_stat_ctxs_demand(bd); old_rx_rings =3D bd->hw_resc.resv_rx_rings; =20 diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c b/drivers/net/e= thernet/broadcom/bnge/bnge_vnic.c new file mode 100644 index 000000000000..80b4ad77c659 --- /dev/null +++ b/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2026 Broadcom. + +#include +#include +#include + +#include "bnge.h" +#include "bnge_netdev.h" +#include "bnge_vnic.h" +#include "bnge_hwrm_lib.h" +#include "bnge_filter.h" +#include "bnge_ethtool.h" + +void bnge_set_dflt_rss_indir_tbl(struct bnge_dev *bd) +{ + u16 max_entries, pad; + u32 *rss_indir_tbl; + u16 i; + + max_entries =3D bnge_get_rxfh_indir_size(bd); + rss_indir_tbl =3D &bd->rss_indir_tbl[0]; + + for (i =3D 0; i < max_entries; i++) + rss_indir_tbl[i] =3D ethtool_rxfh_indir_default(i, + bd->rx_nr_rings); + + pad =3D bd->rss_indir_tbl_entries - max_entries; + if (pad) + memset(&rss_indir_tbl[i], 0, pad * sizeof(*rss_indir_tbl)); +} + +void bnge_fill_hw_rss_tbl(struct bnge_net *bn, struct bnge_vnic_info *vnic) +{ + __le16 *ring_tbl =3D vnic->rss_table; + struct bnge_rx_ring_info *rxr; + struct bnge_dev *bd =3D bn->bd; + u16 tbl_size, i; + + tbl_size =3D bnge_get_rxfh_indir_size(bd); + + for (i =3D 0; i < tbl_size; i++) { + u16 ring_id, j; + + j =3D bd->rss_indir_tbl[i]; + rxr =3D &bn->rx_ring[j]; + + ring_id =3D rxr->rx_ring_struct.fw_ring_id; + *ring_tbl++ =3D cpu_to_le16(ring_id); + ring_id =3D bnge_cp_ring_for_rx(rxr); + *ring_tbl++ =3D cpu_to_le16(ring_id); + } +} + +int bnge_hwrm_vnic_rss_cfg(struct bnge_net *bn, + struct bnge_vnic_info *vnic) +{ + int rc; + + rc =3D bnge_hwrm_vnic_set_rss(bn, vnic, true); + if (rc) { + netdev_err(bn->netdev, "hwrm vnic %d set rss failure rc: %d\n", + vnic->vnic_id, rc); + return rc; + } + rc =3D bnge_hwrm_vnic_cfg(bn, vnic); + if (rc) + netdev_err(bn->netdev, "hwrm vnic %d cfg failure rc: %d\n", + vnic->vnic_id, rc); + return rc; +} + +int bnge_setup_vnic(struct bnge_net *bn, struct bnge_vnic_info *vnic) +{ + struct bnge_dev *bd =3D bn->bd; + int rc, i, nr_ctxs; + + nr_ctxs =3D bnge_cal_nr_rss_ctxs(bd->rx_nr_rings); + for (i =3D 0; i < nr_ctxs; i++) { + rc =3D bnge_hwrm_vnic_ctx_alloc(bd, vnic, i); + if (rc) { + netdev_err(bn->netdev, "hwrm vnic %d ctx %d alloc failure rc: %d\n", + vnic->vnic_id, i, rc); + return -ENOMEM; + } + bn->rsscos_nr_ctxs++; + } + + rc =3D bnge_hwrm_vnic_rss_cfg(bn, vnic); + if (rc) + return rc; + + if (bnge_is_agg_reqd(bd)) { + rc =3D bnge_hwrm_vnic_set_hds(bn, vnic); + if (rc) + netdev_err(bn->netdev, "hwrm vnic %d set hds failure rc: %d\n", + vnic->vnic_id, rc); + } + return rc; +} diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h b/drivers/net/e= thernet/broadcom/bnge/bnge_vnic.h new file mode 100644 index 000000000000..30281e26f39f --- /dev/null +++ b/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2026 Broadcom */ + +#ifndef _BNGE_VNIC_H_ +#define _BNGE_VNIC_H_ + +struct bnge_net; +struct bnge_l2_filter; + +#define BNGE_RSS_TABLE_ENTRIES 64 +#define BNGE_RSS_TABLE_SIZE (BNGE_RSS_TABLE_ENTRIES * 4) +#define BNGE_RSS_TABLE_MAX_TBL 8 +#define BNGE_MAX_RSS_TABLE_SIZE \ + (BNGE_RSS_TABLE_SIZE * BNGE_RSS_TABLE_MAX_TBL) +#define BNGE_MAX_RSS_TABLE_ENTRIES \ + (BNGE_RSS_TABLE_ENTRIES * BNGE_RSS_TABLE_MAX_TBL) + +#define BNGE_MAX_CTX_PER_VNIC 8 + +#define BNGE_MAX_MC_ADDRS 16 +#define BNGE_MAX_UC_ADDRS 4 + +enum { + BNGE_VNIC_DEFAULT =3D 0 +}; + +enum { + BNGE_VNIC_RSS_FLAG =3D BIT(0), + BNGE_VNIC_MCAST_FLAG =3D BIT(1), + BNGE_VNIC_UCAST_FLAG =3D BIT(2) +}; + +struct bnge_vnic_info { + u16 fw_vnic_id; + u16 fw_rss_cos_lb_ctx[BNGE_MAX_CTX_PER_VNIC]; + u16 mru; + /* index 0 always dev_addr */ + struct bnge_l2_filter *l2_filters[BNGE_MAX_UC_ADDRS]; + u16 uc_filter_count; + u8 *uc_list; + dma_addr_t rss_table_dma_addr; + __le16 *rss_table; + dma_addr_t rss_hash_key_dma_addr; + u64 *rss_hash_key; + int rss_table_size; + u32 rx_mask; + + u8 *mc_list; + int mc_list_size; + int mc_list_count; + dma_addr_t mc_list_mapping; + + u32 flags; + u32 vnic_id; +}; + +void bnge_fill_hw_rss_tbl(struct bnge_net *bn, struct bnge_vnic_info *vnic= ); +int bnge_hwrm_vnic_rss_cfg(struct bnge_net *bn, + struct bnge_vnic_info *vnic); +int bnge_setup_vnic(struct bnge_net *bn, struct bnge_vnic_info *vnic); +void bnge_set_dflt_rss_indir_tbl(struct bnge_dev *bd); +#endif /* _BNGE_VNIC_H_ */ --=20 2.52.0 From nobody Fri Sep 25 03:16:18 2026 Received: from mail-qk1-f227.google.com (mail-qk1-f227.google.com [209.85.222.227]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B0C544684C for ; Thu, 17 Sep 2026 06:46:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.227 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627581; cv=none; b=o2VlSJ6SXQEXk5drW3B9V9UN6sYWeBTYfk4k1ia8rGMOune9qoRCZj73Lxd1DDEU4d50pl6+2IAz0hE02xQBzOY9rH9sY3Zl5TovEUqamjbeLRJHkx0vvMt5qQjTW92iF/D9FwWs+MIVYEmtfTeyjfgFgAK/ieVLe0SulBw+eLA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627581; c=relaxed/simple; bh=tPVIJyBE0kdA0MLXZj/BFpPN6SlwlnuloPoD0XlP9No=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZkH3k9Kaaf4fAio4lo24pCzw1z7ETI8yXstuvmFfGxTD3JUNVpxkdkqJo34WC5kJZj7BaoxtTrIysSEl8dUHQJ6JCOW13a3vuPdHQGvyqDFwa4rqwobRwRHyVCi5IzTbu6DGwN4y6d6iRo2/YUOkFDZiiNp8sSfWTVLsUN9wnak= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=PWP1hbtE; arc=none smtp.client-ip=209.85.222.227 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="PWP1hbtE" Received: by mail-qk1-f227.google.com with SMTP id af79cd13be357-939f5f82829so43634285a.1 for ; Wed, 16 Sep 2026 23:46:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789627578; x=1790232378; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=utj+LXach7A0wRbI7r1l5SQcV1AWLnk8cM4PUvzl2h8=; b=RiAJXSUQIpa+YVE4FTBRmJQIHPunGjHhutlOYoJAwi5Yj3d3MoVLSuqUh2nBIzyg42 VPnTLIFos5WPpZKgqcJPQJaSF4vJKQYEBCI6r5NY/YgVogrtj6dpVduBBc34KcAaR4Pa hA+u8ELqVSvINYRTDOejnryrkmOCJ6ikGOjOLIRLv4yDfzU8Pm/YW3Alki9gDhF9TccX IT+91tVS3vUwJbaoQr28vOlPYllW7Mivs9oZMojOz2VKiikiHA72bwMCLM04ZPrheiXh YpQppuiKFb3P6e9edP24vVDJnywVdtej+jVZjT2nJqpG1dYFnjUPkT5ufm9pJd4SkqjP gl4g== X-Forwarded-Encrypted: i=1; AKwUvBy9ML6L6YHvMw9vJHWwSb1Km2bHPfb7zHvtFV2b3CWsrMzk+R6zAF+rkHveUMvhxqxMq0n0bCoIGMzqkEI=@vger.kernel.org X-Gm-Message-State: AFuF++lFvCg+0+jp2iQ/pf/nl/wFGoZNsyuxXt7sfGLpYL1mojvWTTvT I4UI2M0iG5Wxd/2AfrnmPiXgLz6if44JFBqcVmDvVAJyTB0e/snSZ0v1ZlNhOXwHLgEXymXlLOT jHWtZ7c8q/l0Nt3uRmLShht3Xk9IQMg6kaO0YI3Iz9ItFsLBJYLTLqs+u9C9CfbylZJMh0xM1RN lFZEo4fBK7HsMcDJW7+9mbNIT26Qv3n7Wk1aNLGEfn+tCn266QARHoELitvvA8QOioP+yrqNqD4 mePGHOjH6qyGKoiFg== X-Gm-Gg: AYBFou31RuhVNGVdBEs/p474m5kvg4ZDqtMhehidMTjQfOkr2ZfelOHjcpF7eUkTqPx Y1JX3K1SNfCFMah26wAMmdezx/caw1Vxem7oZfNMfa3nRrYLRy/CPirdHdDj/rlksZQUfm71Eg7 Ua2AU4SGqvpcmvZy2+Rp5BTauhyCRRDC9pjoBsb26s6Gu1Ijhm795t15RJNKWHHPk/oTcG0S9ST mctgyqmtUC4sb0kGDc5/yNMjMQ4ucsCu5ZcrYJKm8yWP3xvUbj8coWZRNwVm+x6/EPawkzBV7iV YRavxq/k4ZZnYjDn21mPQzdIsrTrEuNN2mrw1ODgPr3tz6IW1W/xX/IlG8Ps58LeydIXTpHZRZR cnx9DjpX2QtHUpJ9RYQdo0j18iz2cVd6+GLGlxgNNNBnIm8nJ2MZ1iU+4JhJyeW3WqkAWV4noHG hkicNFt+xJavGQRq8VJ9L/putlelYbtjPN/+J3 X-Received: by 2002:a05:620a:600c:b0:939:f188:6d98 with SMTP id af79cd13be357-93bc62f5d25mr338422285a.10.1789627578230; Wed, 16 Sep 2026 23:46:18 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-125.dlp.protect.broadcom.com. [144.49.247.125]) by smtp-relay.gmail.com with ESMTPS id af79cd13be357-93b781bfc1asm51006085a.7.2026.09.16.23.46.17 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2026 23:46:18 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-cc1cade6b71so484541a12.0 for ; Wed, 16 Sep 2026 23:46:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1789627577; x=1790232377; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=utj+LXach7A0wRbI7r1l5SQcV1AWLnk8cM4PUvzl2h8=; b=PWP1hbtEXPjmVdpZcBfEycbTpRYzWsxAqblE9lUwpi7fTS3c3UYZQfCP/3Q0FX7hoo 2vtMpGQMbY6I9i9ZFAcfn8jg3UHwb5ssxcvum5Y9jzikxG6ZdT35V92XaWr7DE0n5FVn byzp8mzx5YDqCyVsoS6kUPqQJjqQrcCblJYj4= X-Forwarded-Encrypted: i=1; AKwUvBwh30HoyHgQJJLJrLoSiVbfXKgIF9x6gyDo7Zw4aFci6Fw2z8s2haZyBKNHW8EqpWiV6h6mfDXt/KffIxM=@vger.kernel.org X-Received: by 2002:a05:6a20:2d2c:b0:3db:10ef:b389 with SMTP id adf61e73a8af0-3dd7255a694mr3868814637.6.1789627576887; Wed, 16 Sep 2026 23:46:16 -0700 (PDT) X-Received: by 2002:a05:6a20:2d2c:b0:3db:10ef:b389 with SMTP id adf61e73a8af0-3dd7255a694mr3868776637.6.1789627576321; Wed, 16 Sep 2026 23:46:16 -0700 (PDT) Received: from H5S1 ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc50ab960edsm2754293a12.20.2026.09.16.23.46.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 23:46:16 -0700 (PDT) From: Vikas Gupta To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com, vsrama-krishna.nemani@broadcom.com, rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com, ajit.khaparde@broadcom.com, Vikas Gupta Subject: [net-next, v3 03/11] bnge: add NTUPLE/ARFS VNIC Date: Thu, 17 Sep 2026 12:15:40 +0530 Message-ID: <20260917064548.773334-4-vikas.gupta@broadcom.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260917064548.773334-1-vikas.gupta@broadcom.com> References: <20260917064548.773334-1-vikas.gupta@broadcom.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-DetectorID-Processed: b00c1d49-9d2e-4205-b15f-d015386d3d5e Content-Type: text/plain; charset="utf-8" Initialize the second VNIC, which is specifically used for the NTUPLE/ARFS feature. This VNIC helps support the aRFS/NTUPLE functionality. With this change, the total number of VNICs becomes 2. Add bnge_set_dflt_rfs() to configure the default NTUPLE feature state at netdev allocation time. Also, allocate and configure the ARFS VNIC. Signed-off-by: Vikas Gupta Reviewed-by: Dharmender Garg --- drivers/net/ethernet/broadcom/bnge/bnge.h | 11 ++- .../ethernet/broadcom/bnge/bnge_hwrm_lib.h | 1 + .../net/ethernet/broadcom/bnge/bnge_netdev.c | 66 +++++++++++++++-- .../net/ethernet/broadcom/bnge/bnge_netdev.h | 1 + .../net/ethernet/broadcom/bnge/bnge_resc.c | 73 ++++++++++++++++++- .../net/ethernet/broadcom/bnge/bnge_resc.h | 1 + .../net/ethernet/broadcom/bnge/bnge_vnic.c | 33 ++++++++- .../net/ethernet/broadcom/bnge/bnge_vnic.h | 7 +- 8 files changed, 181 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge.h b/drivers/net/ethern= et/broadcom/bnge/bnge.h index bde54ba5d50f..fc2f45fa7712 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge.h @@ -63,9 +63,8 @@ enum { BNGE_FW_CAP_THRESHOLD_TEMP_SUPPORTED =3D BIT_ULL(21), BNGE_FW_CAP_DFLT_VLAN_TPID_PCP =3D BIT_ULL(22), BNGE_FW_CAP_VNIC_TUNNEL_TPA =3D BIT_ULL(23), - BNGE_FW_CAP_CFA_NTUPLE_RX_EXT_IP_PROTO =3D BIT_ULL(24), - BNGE_FW_CAP_CFA_RFS_RING_TBL_IDX_V3 =3D BIT_ULL(25), - BNGE_FW_CAP_VNIC_RE_FLUSH =3D BIT_ULL(26), + BNGE_FW_CAP_CFA_RFS_RING_TBL_IDX_V3 =3D BIT_ULL(24), + BNGE_FW_CAP_VNIC_RE_FLUSH =3D BIT_ULL(25), }; =20 enum { @@ -74,6 +73,7 @@ enum { BNGE_EN_STRIP_VLAN =3D BIT_ULL(2), BNGE_EN_SHARED_CHNL =3D BIT_ULL(3), BNGE_EN_UDP_GSO_SUPP =3D BIT_ULL(4), + BNGE_EN_ARFS_CAP =3D BIT_ULL(5), }; =20 #define BNGE_EN_ROCE (BNGE_EN_ROCE_V1 | BNGE_EN_ROCE_V2) @@ -218,6 +218,11 @@ static inline bool bnge_is_roce_en(struct bnge_dev *bd) return bd->flags & BNGE_EN_ROCE; } =20 +static inline bool bnge_is_arfs_cap(struct bnge_dev *bd) +{ + return bd->flags & BNGE_EN_ARFS_CAP; +} + static inline bool bnge_is_agg_reqd(struct bnge_dev *bd) { if (bd->netdev) { diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h b/drivers/n= et/ethernet/broadcom/bnge/bnge_hwrm_lib.h index ae03041c36ac..2ae8ec9f33d3 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h @@ -67,4 +67,5 @@ int bnge_hwrm_shutdown_link(struct bnge_dev *bd); int bnge_hwrm_port_qstats(struct bnge_dev *bd, u8 flags); int bnge_hwrm_port_qstats_ext(struct bnge_dev *bd, u8 flags); int bnge_hwrm_func_qstat_ext(struct bnge_dev *bd, struct bnge_stats_mem *s= tats); +int bnge_hwrm_cfa_adv_flow_mgnt_qcaps(struct bnge_dev *bd); #endif /* _BNGE_HWRM_LIB_H_ */ diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.c index 9e64b1933c02..bab706cb969f 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -1149,12 +1149,10 @@ static int bnge_alloc_vnic_attributes(struct bnge_n= et *bn) =20 static int bnge_alloc_vnics(struct bnge_net *bn) { - int num_vnics; + int num_vnics =3D 1; =20 - /* Allocate only 1 VNIC for now - * Additional VNICs will be added based on RFS/NTUPLE in future patches - */ - num_vnics =3D 1; + if (bn->priv_flags & BNGE_NET_EN_NTUPLE) + num_vnics++; =20 bn->vnic_info =3D kzalloc_objs(struct bnge_vnic_info, num_vnics); if (!bn->vnic_info) @@ -1320,6 +1318,10 @@ static int bnge_alloc_core(struct bnge_net *bn) bn->vnic_info[BNGE_VNIC_DEFAULT].flags |=3D BNGE_VNIC_RSS_FLAG | BNGE_VNIC_MCAST_FLAG | BNGE_VNIC_UCAST_FLAG; + if (bn->priv_flags & BNGE_NET_EN_NTUPLE) + bn->vnic_info[BNGE_VNIC_NTUPLE].flags |=3D BNGE_VNIC_RSS_FLAG | + BNGE_VNIC_NTUPLE_FLAG; + rc =3D bnge_alloc_vnic_attributes(bn); if (rc) goto err_free_core; @@ -2546,6 +2548,12 @@ static int bnge_init_chip(struct bnge_net *bn) if (rc) goto err_out; =20 + if (bn->priv_flags & BNGE_NET_EN_NTUPLE) { + rc =3D bnge_alloc_rfs_vnic(bn); + if (rc) + goto err_out; + } + if (bd->rss_cap & BNGE_RSS_CAP_RSS_HASH_TYPE_DELTA) bnge_hwrm_update_rss_hash_cfg(bn); =20 @@ -3019,6 +3027,8 @@ static int bnge_close(struct net_device *dev) bnge_hwrm_if_change(bn->bd, false); bn->sp_event =3D 0; =20 + netdev_update_features(dev); + return 0; } =20 @@ -3101,6 +3111,36 @@ static const struct netdev_stat_ops bnge_stat_ops = =3D { .get_base_stats =3D bnge_get_base_stats, }; =20 +static netdev_features_t bnge_fix_features(struct net_device *dev, + netdev_features_t features) +{ + /* NTUPLE can only be changed while the interface is down. */ + if (netif_running(dev)) { + if (dev->features & NETIF_F_NTUPLE) + features |=3D NETIF_F_NTUPLE; + else + features &=3D ~NETIF_F_NTUPLE; + } + return features; +} + +static int bnge_set_features(struct net_device *dev, netdev_features_t fea= tures) +{ + struct bnge_net *bn =3D netdev_priv(dev); + u32 flags =3D bn->priv_flags; + + flags &=3D ~BNGE_NET_EN_NTUPLE; + if (features & NETIF_F_NTUPLE) + flags |=3D BNGE_NET_EN_NTUPLE; + + if (flags =3D=3D bn->priv_flags) + return 0; + + bn->priv_flags =3D flags; + + return 0; +} + static const struct net_device_ops bnge_netdev_ops =3D { .ndo_open =3D bnge_open, .ndo_stop =3D bnge_close, @@ -3108,6 +3148,8 @@ static const struct net_device_ops bnge_netdev_ops = =3D { .ndo_get_stats64 =3D bnge_get_stats64, .ndo_set_rx_mode_async =3D bnge_set_rx_mode, .ndo_features_check =3D bnge_features_check, + .ndo_fix_features =3D bnge_fix_features, + .ndo_set_features =3D bnge_set_features, }; =20 static void bnge_init_mac_addr(struct bnge_dev *bd) @@ -3233,6 +3275,18 @@ static void bnge_init_ring_params(struct bnge_net *b= n) bn->netdev->cfg->hds_thresh =3D max(BNGE_DEFAULT_RX_COPYBREAK, rx_size); } =20 +static void bnge_set_dflt_rfs(struct bnge_net *bn) +{ + bn->netdev->hw_features &=3D ~NETIF_F_NTUPLE; + bn->netdev->features &=3D ~NETIF_F_NTUPLE; + bn->priv_flags &=3D ~BNGE_NET_EN_NTUPLE; + if (bnge_is_arfs_cap(bn->bd)) { + bn->netdev->hw_features |=3D NETIF_F_NTUPLE; + bn->netdev->features |=3D NETIF_F_NTUPLE; + bn->priv_flags |=3D BNGE_NET_EN_NTUPLE; + } +} + int bnge_netdev_alloc(struct bnge_dev *bd, int max_irqs) { struct net_device *netdev; @@ -3339,6 +3393,8 @@ int bnge_netdev_alloc(struct bnge_dev *bd, int max_ir= qs) bnge_set_ring_params(bd); =20 bnge_init_l2_fltr_tbl(bn); + bnge_set_dflt_rfs(bn); + bnge_init_mac_addr(bd); =20 rc =3D bnge_probe_phy(bn, true); diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.h index ee649cc644db..c47a874df4ba 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h @@ -152,6 +152,7 @@ enum { BNGE_NET_EN_GRO =3D BIT(0), BNGE_NET_EN_LRO =3D BIT(1), BNGE_NET_EN_JUMBO =3D BIT(2), + BNGE_NET_EN_NTUPLE =3D BIT(3), }; =20 #define BNGE_NET_EN_TPA (BNGE_NET_EN_GRO | BNGE_NET_EN_LRO) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c b/drivers/net/e= thernet/broadcom/bnge/bnge_resc.c index 69a894b52485..4c0cde30992c 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_resc.c @@ -178,6 +178,16 @@ static int bnge_adjust_rings(struct bnge_dev *bd, u16 = *rx, return bnge_fix_rings_count(rx, tx, max_nq, sh); } =20 +static unsigned int bnge_get_max_func_rss_ctxs(struct bnge_dev *bd) +{ + return bd->hw_resc.max_rsscos_ctxs; +} + +static unsigned int bnge_get_max_func_vnics(struct bnge_dev *bd) +{ + return bd->hw_resc.max_vnics; +} + int bnge_cal_nr_rss_ctxs(u16 rx_rings) { if (!rx_rings) @@ -190,11 +200,24 @@ int bnge_cal_nr_rss_ctxs(u16 rx_rings) static u16 bnge_get_total_rss_ctxs(struct bnge_dev *bd, struct bnge_hw_rings *hwr) { - return bnge_cal_nr_rss_ctxs(hwr->grp); + u16 rss_ctx =3D bnge_cal_nr_rss_ctxs(hwr->grp); + + rss_ctx *=3D hwr->vnic; + + return rss_ctx; } =20 static u16 bnge_get_total_vnics(struct bnge_dev *bd) { + if (bd->netdev) { + struct bnge_net *bn =3D netdev_priv(bd->netdev); + + if (bn->priv_flags & BNGE_NET_EN_NTUPLE) + return 2; + } else if (bnge_is_arfs_cap(bd)) { + return 2; + } + return 1; } =20 @@ -563,6 +586,51 @@ static int bnge_alloc_rss_indir_tbl(struct bnge_dev *b= d) return 0; } =20 +/* If runtime conditions support RFS */ +bool bnge_arfs_capable(struct bnge_dev *bd, bool new_rss_ctx) +{ + struct bnge_hw_rings hwr =3D {}; + int max_vnics, max_rss_ctxs; + + hwr.grp =3D bd->rx_nr_rings; + hwr.vnic =3D bnge_get_total_vnics(bd); + + if (!bnge_is_arfs_cap(bd)) + hwr.vnic++; + + if (new_rss_ctx) + hwr.vnic++; + hwr.rss_ctx =3D bnge_get_total_rss_ctxs(bd, &hwr); + max_vnics =3D bnge_get_max_func_vnics(bd); + max_rss_ctxs =3D bnge_get_max_func_rss_ctxs(bd); + + if (hwr.vnic > max_vnics || hwr.rss_ctx > max_rss_ctxs) { + if (bd->rx_nr_rings > 1) + dev_warn(bd->dev, + "Not enough resources to support NTUPLE filters\n"); + return false; + } + + /* Do not reduce VNIC and RSS ctx reservations. There is a FW + * issue that will mess up the default VNIC if we reduce the + * reservations. + */ + if (hwr.vnic <=3D bd->hw_resc.resv_vnics && + hwr.rss_ctx <=3D bd->hw_resc.resv_rsscos_ctxs) + return true; + + bnge_hwrm_reserve_rings(bd, &hwr); + if (hwr.vnic <=3D bd->hw_resc.resv_vnics && + hwr.rss_ctx <=3D bd->hw_resc.resv_rsscos_ctxs) + return true; + + dev_warn(bd->dev, "Unable to reserve resources to support NTUPLE filters\= n"); + hwr.vnic =3D 1; + hwr.rss_ctx =3D 0; + bnge_hwrm_reserve_rings(bd, &hwr); + return false; +} + int bnge_net_init_dflt_config(struct bnge_dev *bd) { struct bnge_hw_resc *hw_resc; @@ -576,6 +644,9 @@ int bnge_net_init_dflt_config(struct bnge_dev *bd) if (rc) goto err_free_tbl; =20 + if (bnge_arfs_capable(bd, false)) + bd->flags |=3D BNGE_EN_ARFS_CAP; + hw_resc =3D &bd->hw_resc; bd->max_fltr =3D hw_resc->max_rx_em_flows + hw_resc->max_rx_wm_flows + BNGE_L2_FLTR_MAX_FLTR; diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_resc.h b/drivers/net/e= thernet/broadcom/bnge/bnge_resc.h index b62a634669f6..1e55fbe6985b 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_resc.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_resc.h @@ -75,6 +75,7 @@ void bnge_aux_init_dflt_config(struct bnge_dev *bd); u32 bnge_get_rxfh_indir_size(struct bnge_dev *bd); int bnge_cal_nr_rss_ctxs(u16 rx_rings); bool bnge_aux_has_enough_resources(struct bnge_dev *bd); +bool bnge_arfs_capable(struct bnge_dev *bd, bool new_rss_ctx); =20 static inline u32 bnge_adjust_pow_two(u32 total_ent, u16 ent_per_blk) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c b/drivers/net/e= thernet/broadcom/bnge/bnge_vnic.c index 80b4ad77c659..779780ab53d2 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c @@ -42,7 +42,11 @@ void bnge_fill_hw_rss_tbl(struct bnge_net *bn, struct bn= ge_vnic_info *vnic) for (i =3D 0; i < tbl_size; i++) { u16 ring_id, j; =20 - j =3D bd->rss_indir_tbl[i]; + if (vnic->flags & BNGE_VNIC_NTUPLE_FLAG) + j =3D ethtool_rxfh_indir_default(i, bd->rx_nr_rings); + else + j =3D bd->rss_indir_tbl[i]; + rxr =3D &bn->rx_ring[j]; =20 ring_id =3D rxr->rx_ring_struct.fw_ring_id; @@ -98,3 +102,30 @@ int bnge_setup_vnic(struct bnge_net *bn, struct bnge_vn= ic_info *vnic) } return rc; } + +static int bnge_alloc_and_setup_vnic(struct bnge_net *bn, + struct bnge_vnic_info *vnic, + u16 rx_rings) +{ + int rc; + + rc =3D bnge_hwrm_vnic_alloc(bn->bd, vnic, rx_rings); + if (rc) { + netdev_err(bn->netdev, "hwrm vnic %u alloc failure rc: %d\n", + vnic->vnic_id, rc); + return rc; + } + + /* If bnge_setup_vnic() fails, the VNIC allocated above is not freed + * here; the caller (bnge_open_core) unwinds via its err_out path, + */ + return bnge_setup_vnic(bn, vnic); +} + +int bnge_alloc_rfs_vnic(struct bnge_net *bn) +{ + struct bnge_vnic_info *vnic; + + vnic =3D &bn->vnic_info[BNGE_VNIC_NTUPLE]; + return bnge_alloc_and_setup_vnic(bn, vnic, bn->bd->rx_nr_rings); +} diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h b/drivers/net/e= thernet/broadcom/bnge/bnge_vnic.h index 30281e26f39f..93c6d736cbeb 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h @@ -21,13 +21,15 @@ struct bnge_l2_filter; #define BNGE_MAX_UC_ADDRS 4 =20 enum { - BNGE_VNIC_DEFAULT =3D 0 + BNGE_VNIC_DEFAULT =3D 0, + BNGE_VNIC_NTUPLE =3D 1 }; =20 enum { BNGE_VNIC_RSS_FLAG =3D BIT(0), BNGE_VNIC_MCAST_FLAG =3D BIT(1), - BNGE_VNIC_UCAST_FLAG =3D BIT(2) + BNGE_VNIC_UCAST_FLAG =3D BIT(2), + BNGE_VNIC_NTUPLE_FLAG =3D BIT(3) }; =20 struct bnge_vnic_info { @@ -59,4 +61,5 @@ int bnge_hwrm_vnic_rss_cfg(struct bnge_net *bn, struct bnge_vnic_info *vnic); int bnge_setup_vnic(struct bnge_net *bn, struct bnge_vnic_info *vnic); void bnge_set_dflt_rss_indir_tbl(struct bnge_dev *bd); +int bnge_alloc_rfs_vnic(struct bnge_net *bn); #endif /* _BNGE_VNIC_H_ */ --=20 2.52.0 From nobody Fri Sep 25 03:16:18 2026 Received: from mail-ot1-f99.google.com (mail-ot1-f99.google.com [209.85.210.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 57ED14457DF for ; Thu, 17 Sep 2026 06:46:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.99 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627586; cv=none; b=etCjLeCfu002rpLF3nNCq5WcpPONb0LQuHwbLPSRbEePQPTPwWezWq3cfMRBjHIUuhmPYnWuAZrjMebgEGSlu2MAB9v1gPICkjF0OHH0Rc7O6T0f2pdriCS0bkx+j8hI+7spt0xaBJZjlz1ACiqEnzHdXzbMudYXBmdWFxAof94= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627586; c=relaxed/simple; bh=Zpvdl/8Lw7viZFIGKdFkk6s8/B9GzaAAHMKKHgA/5AY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tCkeFM/jjBirzYQjKV7MeauAFqI48d789TBLPwy2ZUys6P8occqURwFnuMwVZVvvVIhSS51gn3V7lIJLDnkmSIAwraEQqYOa267V2z51klZ+koOdWbQwGTdIL1YCpzU3tF42hCLx4i9q0aLwX6h1q7zJGeV23ZD4j7+QcCcPulw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=KKvF6Skl; arc=none smtp.client-ip=209.85.210.99 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="KKvF6Skl" Received: by mail-ot1-f99.google.com with SMTP id 46e09a7af769-7f4b94d72acso149880a34.1 for ; Wed, 16 Sep 2026 23:46:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789627584; x=1790232384; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=JajMxo/krUHGWRtmYnpxnz/0vjg4QSBAOJSLqB1Atx8=; b=o/QeqCfTnp1PzB59CTbu5AulG6AF+j25LZrGNgVyFjRKLEbRgwqCiF6Sp3UaN3Eo0i vnzyKsrP86CKKVgmtxhD9eLYTRf4USxig4PaQufFkGB/MOvjd2QlgvTSSy3Ryn0oVpST BRjg2PnTzRKGle/bRnFc1DmMZrabwTvA2aji6zOkUD56uA3btkzHyi/Qy8opmqVGuxdX 8yCGsa91NF8Zs/k1Q/1PPhq0wL8KjYzOKVS0KNZu/Q8wRNuyi6C7ADYdNiA2D5e0umSL 3nuhH3CWKLQPyRnbpgJEt2BYS1YWWbWuJIoFfX1kNi52udFKKhj9CIuDeukVgsooQnyA 80yg== X-Forwarded-Encrypted: i=1; AKwUvBze1w2YFuDBVA6r/9GQp6TTxGLfO7lqs/4caPNt3KhhmMdjNfl4HUe+RVxHzNhboNfsF23xFOSSPyhtbJI=@vger.kernel.org X-Gm-Message-State: AFuF++lrt1g4C5wdJDKyL+D0EaY8B0slAHBjPgSY3HbgD2A6DnvDaKgx 5CVTZyE8E1QK4jDo6Dtv3fcPD2BEG2+CqRqfcqKmEGpfmFJYVKYdFxm+8wMRueR9t2Y1SsvlyVZ Wy5ue/j0pjZPkpZlQGTDd05MlFWKc6EIBRiAQvVSShPKKCFjO00Hi+jHpR+aq+2ewhZbnxqpj1J iwgXIC5RTF9Shkc34nYBB1oy0cTE4dmcKkIsA1mxB4EPWqVKDFrISih81qOith/RNbHKGXUF7lp y64lEghheMcT4MLJg== X-Gm-Gg: AYBFou0kHb1VTy+26qYmhHWrA6S7XcuCUMhS36AwOMTz+Vzsn43HAe5hDyeP41vsUph TkKqrJpfYjn0x+Nz/gNiMXy4yUzWnEJ20Gn27Q1I3ploCov5oYPsK9zE1z25qGPLh9CqyPTUgCk hxMENH3Dr/s91aSKdF9PXppoh/gmJJCBPSVEuxHLYtGaD7bnTV7cTcfR4gAncUF0qb+idJP6UpE 7NuE228NGHe+JV+tw+sraMof3vOnrU+oApoLAh95iKDmvHmUnTio0ZYmxxx9C6gXSkvLbK0NYDb 3qDnCbB3HyBgRc0QH5oDN3scJaXXE+eng9eqlJJcrioOE6Kp8JKaRTXZYzLQlN81wvosaZ55X4i Bx9WgVs5FvfNPnzUWcQ/7+XoE6kuWmLSdhW3vGmK7w3ljESIQacNcL+foxTvXDvTwTycYO4KmcY 6aOhlQhlnYoXXgM7esfL0NbPazvc4/aaRt+g== X-Received: by 2002:a05:6830:83b9:b0:7e9:dd7f:7a83 with SMTP id 46e09a7af769-80b2906b58bmr5947678a34.0.1789627584031; Wed, 16 Sep 2026 23:46:24 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-98.dlp.protect.broadcom.com. [144.49.247.98]) by smtp-relay.gmail.com with ESMTPS id 46e09a7af769-80c43e5d5e1sm1089394a34.1.2026.09.16.23.46.23 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2026 23:46:24 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pg1-f198.google.com with SMTP id 41be03b00d2f7-cbee6bb8408so666562a12.3 for ; Wed, 16 Sep 2026 23:46:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1789627582; x=1790232382; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=JajMxo/krUHGWRtmYnpxnz/0vjg4QSBAOJSLqB1Atx8=; b=KKvF6SklIxYNsxvVDHVlWYy8vpbprnCMKyxk9EQc5UlqMWGVbYxQzrx6h+wmRxWShs gUvvhGCO9HLFiVBmx61qpGtNmE7RemwV6QGDdEEIZK/ZkSyUKbkZzikuxeiiGEmvIsia Ib7Evxxnq16L6k1BRKGhhd6eqhhfceLzzSqyY= X-Forwarded-Encrypted: i=1; AKwUvByZEFdOilbDnnDfheLH8tHCBMlaMotvhQar0B1PsuIogcx41hcCSAAheZIx1wP/A0zx+bjhdvq9JNKiuuU=@vger.kernel.org X-Received: by 2002:a05:6a20:4327:b0:3d3:ae40:51e6 with SMTP id adf61e73a8af0-3dd5f78606dmr13217850637.26.1789627582414; Wed, 16 Sep 2026 23:46:22 -0700 (PDT) X-Received: by 2002:a05:6a20:4327:b0:3d3:ae40:51e6 with SMTP id adf61e73a8af0-3dd5f78606dmr13217813637.26.1789627581979; Wed, 16 Sep 2026 23:46:21 -0700 (PDT) Received: from H5S1 ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc50ab960edsm2754293a12.20.2026.09.16.23.46.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 23:46:21 -0700 (PDT) From: Vikas Gupta To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com, vsrama-krishna.nemani@broadcom.com, rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com, ajit.khaparde@broadcom.com, Vikas Gupta Subject: [net-next, v3 04/11] bnge: add helper functions for multi RSS contexts Date: Thu, 17 Sep 2026 12:15:41 +0530 Message-ID: <20260917064548.773334-5-vikas.gupta@broadcom.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260917064548.773334-1-vikas.gupta@broadcom.com> References: <20260917064548.773334-1-vikas.gupta@broadcom.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-DetectorID-Processed: b00c1d49-9d2e-4205-b15f-d015386d3d5e Content-Type: text/plain; charset="utf-8" Add infrastructure for creating, modifying, and deleting user-defined RSS contexts. This helps the next patch implement commands for ethtool. For each user RSS context, a VNIC is allocated. Signed-off-by: Vikas Gupta Reviewed-by: Bhargava Chenna Marreddy Reviewed-by: Dharmender Garg --- .../net/ethernet/broadcom/bnge/bnge_netdev.h | 2 + .../net/ethernet/broadcom/bnge/bnge_resc.c | 2 +- .../net/ethernet/broadcom/bnge/bnge_vnic.c | 113 ++++++++++++++++++ .../net/ethernet/broadcom/bnge/bnge_vnic.h | 15 +++ 4 files changed, 131 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.h index c47a874df4ba..3c0fea0a7608 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h @@ -371,6 +371,8 @@ struct bnge_net { =20 u8 pri2cos_idx[8]; bool pri2cos_valid; + + u16 num_rss_ctx; }; =20 #define BNGE_DEFAULT_RX_RING_SIZE 511 diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c b/drivers/net/e= thernet/broadcom/bnge/bnge_resc.c index 4c0cde30992c..b7a01cf885f2 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_resc.c @@ -213,7 +213,7 @@ static u16 bnge_get_total_vnics(struct bnge_dev *bd) struct bnge_net *bn =3D netdev_priv(bd->netdev); =20 if (bn->priv_flags & BNGE_NET_EN_NTUPLE) - return 2; + return 2 + bn->num_rss_ctx; } else if (bnge_is_arfs_cap(bd)) { return 2; } diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c b/drivers/net/e= thernet/broadcom/bnge/bnge_vnic.c index 779780ab53d2..7857421cd672 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c @@ -129,3 +129,116 @@ int bnge_alloc_rfs_vnic(struct bnge_net *bn) vnic =3D &bn->vnic_info[BNGE_VNIC_NTUPLE]; return bnge_alloc_and_setup_vnic(bn, vnic, bn->bd->rx_nr_rings); } + +void bnge_modify_rss(struct bnge_net *bn, struct ethtool_rxfh_context *ctx, + struct bnge_rss_ctx *rss_ctx, + const struct ethtool_rxfh_param *rxfh) +{ + struct bnge_dev *bd =3D bn->bd; + + if (rxfh->key) { + if (rss_ctx) { + memcpy(rss_ctx->vnic.rss_hash_key, rxfh->key, + HW_HASH_KEY_SIZE); + } else { + memcpy(bn->rss_hash_key, rxfh->key, HW_HASH_KEY_SIZE); + bn->rss_hash_key_updated =3D true; + } + } + + if (rxfh->indir) { + u32 i, pad, tbl_size =3D bnge_get_rxfh_indir_size(bd); + u32 *indir_tbl =3D bd->rss_indir_tbl; + + if (rss_ctx) + indir_tbl =3D ethtool_rxfh_context_indir(ctx); + for (i =3D 0; i < tbl_size; i++) + indir_tbl[i] =3D rxfh->indir[i]; + pad =3D bd->rss_indir_tbl_entries - tbl_size; + if (pad) + memset(&indir_tbl[i], 0, pad * sizeof(*indir_tbl)); + } +} + +void bnge_del_one_rss_ctx(struct bnge_net *bn, struct bnge_rss_ctx *rss_ct= x, + bool all) +{ + struct bnge_vnic_info *vnic =3D &rss_ctx->vnic; + int i; + + bnge_hwrm_vnic_free_one(bn->bd, &rss_ctx->vnic); + for (i =3D 0; i < BNGE_MAX_CTX_PER_VNIC; i++) { + if (vnic->fw_rss_cos_lb_ctx[i] !=3D INVALID_HW_RING_ID) + bnge_hwrm_vnic_ctx_free_one(bn->bd, vnic, i); + } + + if (!all) + return; + + if (vnic->rss_table) + dma_free_coherent(bn->bd->dev, vnic->rss_table_size, + vnic->rss_table, + vnic->rss_table_dma_addr); + bn->num_rss_ctx--; +} + +void bnge_hwrm_realloc_rss_ctx_vnic(struct bnge_net *bn) +{ + bool set_tpa =3D !!(bn->priv_flags & BNGE_NET_EN_TPA); + struct ethtool_rxfh_context *ctx; + unsigned long context; + + xa_for_each(&bn->netdev->ethtool->rss_ctx, context, ctx) { + struct bnge_rss_ctx *rss_ctx =3D ethtool_rxfh_context_priv(ctx); + struct bnge_vnic_info *vnic =3D &rss_ctx->vnic; + + if (bnge_hwrm_vnic_alloc(bn->bd, vnic, bn->bd->rx_nr_rings) || + bnge_hwrm_vnic_set_tpa(bn->bd, vnic, set_tpa) || + bnge_setup_vnic(bn, vnic)) { + netdev_err(bn->netdev, "Failed to restore RSS ctx %d\n", + rss_ctx->index); + bnge_del_one_rss_ctx(bn, rss_ctx, true); + ethtool_rxfh_context_lost(bn->netdev, rss_ctx->index); + } + } +} + +void bnge_clear_rss_ctxs(struct bnge_net *bn) +{ + struct ethtool_rxfh_context *ctx; + unsigned long context; + + xa_for_each(&bn->netdev->ethtool->rss_ctx, context, ctx) { + struct bnge_rss_ctx *rss_ctx =3D ethtool_rxfh_context_priv(ctx); + + bnge_del_one_rss_ctx(bn, rss_ctx, false); + } +} + +struct bnge_rss_ctx *bnge_get_rss_ctx_from_index(struct bnge_net *bn, u32 = idx) +{ + struct ethtool_rxfh_context *ctx; + + ctx =3D xa_load(&bn->netdev->ethtool->rss_ctx, idx); + if (!ctx) + return NULL; + return ethtool_rxfh_context_priv(ctx); +} + +int bnge_alloc_vnic_rss_table(struct bnge_net *bn, + struct bnge_vnic_info *vnic) +{ + unsigned int size =3D L1_CACHE_ALIGN(BNGE_MAX_RSS_TABLE_SIZE); + + vnic->rss_table_size =3D size + HW_HASH_KEY_SIZE; + vnic->rss_table =3D dma_alloc_coherent(bn->bd->dev, + vnic->rss_table_size, + &vnic->rss_table_dma_addr, + GFP_KERNEL); + if (!vnic->rss_table) + return -ENOMEM; + + vnic->rss_hash_key =3D ((void *)vnic->rss_table) + size; + vnic->rss_hash_key_dma_addr =3D vnic->rss_table_dma_addr + size; + return 0; +} diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h b/drivers/net/e= thernet/broadcom/bnge/bnge_vnic.h index 93c6d736cbeb..af066d8ff156 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h @@ -56,10 +56,25 @@ struct bnge_vnic_info { u32 vnic_id; }; =20 +struct bnge_rss_ctx { + struct bnge_vnic_info vnic; + u32 index; +}; + void bnge_fill_hw_rss_tbl(struct bnge_net *bn, struct bnge_vnic_info *vnic= ); int bnge_hwrm_vnic_rss_cfg(struct bnge_net *bn, struct bnge_vnic_info *vnic); int bnge_setup_vnic(struct bnge_net *bn, struct bnge_vnic_info *vnic); void bnge_set_dflt_rss_indir_tbl(struct bnge_dev *bd); int bnge_alloc_rfs_vnic(struct bnge_net *bn); +int bnge_alloc_vnic_rss_table(struct bnge_net *bn, + struct bnge_vnic_info *vnic); +struct bnge_rss_ctx *bnge_get_rss_ctx_from_index(struct bnge_net *bn, u32 = idx); +void bnge_modify_rss(struct bnge_net *bn, struct ethtool_rxfh_context *ctx, + struct bnge_rss_ctx *rss_ctx, + const struct ethtool_rxfh_param *rxfh); +void bnge_del_one_rss_ctx(struct bnge_net *bn, struct bnge_rss_ctx *rss_ct= x, + bool all); +void bnge_hwrm_realloc_rss_ctx_vnic(struct bnge_net *bn); +void bnge_clear_rss_ctxs(struct bnge_net *bn); #endif /* _BNGE_VNIC_H_ */ --=20 2.52.0 From nobody Fri Sep 25 03:16:18 2026 Received: from mail-pl1-f226.google.com (mail-pl1-f226.google.com [209.85.214.226]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5CA9A44607E for ; Thu, 17 Sep 2026 06:46:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.226 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627593; cv=none; b=CvU0YgRDdWDtc+gmJCQMna79U44SWGK7kNFAGVDoOTNC4xvRqL1O6jhY9HYwHoVejP/YXfU6KGMwIZFHUMzZwq9zrjuU7EKAsG0lktU4GItmzj4+48wOSk9RLGEwLy79Axa8qJgTZfVKfd1XxfMN3NASwiLaTiTmuLWnqSejJUE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627593; c=relaxed/simple; bh=hvAm2xCTSAU5DU9VIVyYXjPzrlTtE6P9ry4vlMuSLoA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UC2iRCURgToPdZxfsDme9i5dQOOTGGNY4tjh6iOtMIjDdx1GTXwsSXssrzYZNanoCdGXed9toYd8tDBAFWrF30y2jBHJ+fYgZxQ0c6TRnKsQHCFdheKcKf+F24QtGqNCv6D0+zAwvZiG30GmI3ubPSSwAm9wfLv8McQA6ul6SFA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=GkX49k0k; arc=none smtp.client-ip=209.85.214.226 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="GkX49k0k" Received: by mail-pl1-f226.google.com with SMTP id d9443c01a7336-2d9004f39d3so2962675ad.2 for ; Wed, 16 Sep 2026 23:46:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789627591; x=1790232391; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=xFer9Ol8ZjeYgrAICccHcidcUPB9Yevz5/PbPEQUt3k=; b=U+SUnraiFF+umcNBVLZFCLpTgCS1woTZ0Hyh1YgbfxTlP4RLW42oVKPzuuPkZ972ln +ytjRSHD53bZzdaqNvN9tvjBHeVCJHJ85/Ql6Z5XosVyUcX7vFzlHUDpGglP56WT3waK 2Xhf3t4kIK1Tq2F5pIhgULQyrlLdUDloJz8kASMU0H6CJ2v2iEfjmDfdQIxjrucS+ZBk 1zucOnkmV5FKbgddlvkOsGluImVlSJQh0dOajdet1MqBUWtjeQN/GcN1bb+szOadJv0o fCg/fiHUnl3v39gO2adlMgdty6eiNQciC+JIGcr4FtX9MBMLX1+rt60xC7qogpLBVGnQ tZ0g== X-Forwarded-Encrypted: i=1; AKwUvBxaa3jpRk2kEqZXQA4Un2JiVu2zYO3wAhJwMrrH+gbg9TVJBY3INtgVH+mm36syW/qOV8MIy7cAQ2Iwre0=@vger.kernel.org X-Gm-Message-State: AFuF++m7wDynADPvL+eLSi3HziiJWFzNNX3e3yCKu709XwtkIOKDtVln +w7af1yQgGUnamAOakI6hMvJAsI0hoKwTfsIZF5VYlZzGM25KZ3ymsbfLhHrXWcjfWWvbqpk9dd pMKqlxeXwloeu68U/prhdM5aLkc06qaU2z3JRp7OvOszL2JultepIMU5NjuPCqmjBFJH3nCjbdj UX1JQg+FLBsM2cnjSAOHIMYfP5qK8tmsAIo/Nnl/LhNKB6E9P+hP+Bl1B6UDOYD7uNSGvV4t1/8 jVzgLcEhM1jcn5vVQ== X-Gm-Gg: AYBFou3xOu/2qdFiTbIOn8hhT8hnMS5KA/LHFhVTHpZlCNf1l+PWyogHkt7gbRowsSu 6Xqst6JgooTBrFMr43S5KrPPqK/SBOVPG9BHnHfoLlenz3DpHwbfgDVz0vAhQ7Wd8OdjAvYl6zi mHHkesA8Dmu+dmOTdtJklFXE7CRonB9WXGcIJj/eGNA2hJT22XNiPHMcFaRIUf2WM8McAzCCoFb jzPV4ZEYFi+HSj6CkUOmN00FudSH8/OuRTQ/o8tUXxgvoTwm47CjRchIna3HXGANFT73uFnzFVr ciDoFJAE8fayZ8xIjP6eYtTXHn7uJ/RzUwjhqMrgJZr3myRlbqA+YDnP9WHDG8XXcmAsI3IIbIA Tm0KZZs4aWKtLrt5fftaopvTB/+AyIHHS1fSEVAe+Yz+Ps66x/UZm69guw28JJt0N+MD+1MMApT qhF0m0D4TYeHACyZABAhW0TbCkWQhnhN35zG+t X-Received: by 2002:a05:6a21:32a9:b0:3dd:53e0:aabf with SMTP id adf61e73a8af0-3dd5f7a9b95mr12969770637.26.1789627590517; Wed, 16 Sep 2026 23:46:30 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-125.dlp.protect.broadcom.com. [144.49.247.125]) by smtp-relay.gmail.com with ESMTPS id 41be03b00d2f7-cc50ad1e189sm2268894a12.10.2026.09.16.23.46.29 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2026 23:46:30 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-c89704da8c7so759221a12.0 for ; Wed, 16 Sep 2026 23:46:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1789627588; x=1790232388; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=xFer9Ol8ZjeYgrAICccHcidcUPB9Yevz5/PbPEQUt3k=; b=GkX49k0kl0nFDntvn4oChrTUO7TMxb8JKET5T8+bE9H0PUIpnsdgsBZmIUvyL3kN/5 O1skNy2ihVMq4QsiMyDSY6WBGtB0ixp77B1gDu4BX2pV2mYMnXeBbo5K0Jd7vP7eHsSu gOzlcDgEB+OeZUyBcJ43I6yEGQnlnyZmPLcZQ= X-Forwarded-Encrypted: i=1; AKwUvBz+Oa5oc3MX5hmvd125QFwKk/9rVTiA0+7LIYY84KJlZA8sCmlcgAM3EJU40W24Tjnp96Ko4+9EvPNOwBc=@vger.kernel.org X-Received: by 2002:a05:6a20:cf83:b0:3db:3e1c:8585 with SMTP id adf61e73a8af0-3dd5f7ac3f9mr15507052637.27.1789627587994; Wed, 16 Sep 2026 23:46:27 -0700 (PDT) X-Received: by 2002:a05:6a20:cf83:b0:3db:3e1c:8585 with SMTP id adf61e73a8af0-3dd5f7ac3f9mr15506968637.27.1789627587398; Wed, 16 Sep 2026 23:46:27 -0700 (PDT) Received: from H5S1 ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc50ab960edsm2754293a12.20.2026.09.16.23.46.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 23:46:27 -0700 (PDT) From: Vikas Gupta To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com, vsrama-krishna.nemani@broadcom.com, rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com, ajit.khaparde@broadcom.com, Vikas Gupta Subject: [net-next, v3 05/11] bnge: add RXFH ethtool support Date: Thu, 17 Sep 2026 12:15:42 +0530 Message-ID: <20260917064548.773334-6-vikas.gupta@broadcom.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260917064548.773334-1-vikas.gupta@broadcom.com> References: <20260917064548.773334-1-vikas.gupta@broadcom.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-DetectorID-Processed: b00c1d49-9d2e-4205-b15f-d015386d3d5e Content-Type: text/plain; charset="utf-8" Introduce ethtool RXFH operations including get/set_rxfh for reading and programming the RSS hash key and indirection table. Currently set_rxfh and set_rxfh_fields are supported only while the device is down. A future patch series will rework bnge_close_core()/bnge_open_core() so they can be driven safely from the ethtool path, adding full functionality by applying the configuration on a live device. Signed-off-by: Vikas Gupta Reviewed-by: Bhargava Chenna Marreddy Reviewed-by: Dharmender Garg --- drivers/net/ethernet/broadcom/bnge/bnge.h | 1 + .../net/ethernet/broadcom/bnge/bnge_ethtool.c | 276 ++++++++++++++++++ .../ethernet/broadcom/bnge/bnge_hwrm_lib.c | 2 + .../net/ethernet/broadcom/bnge/bnge_netdev.c | 17 +- .../net/ethernet/broadcom/bnge/bnge_netdev.h | 2 + .../net/ethernet/broadcom/bnge/bnge_vnic.h | 1 + 6 files changed, 297 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge.h b/drivers/net/ethern= et/broadcom/bnge/bnge.h index fc2f45fa7712..f0b152e6a43a 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge.h @@ -87,6 +87,7 @@ enum { BNGE_RSS_CAP_AH_V6_RSS_CAP =3D BIT(5), BNGE_RSS_CAP_ESP_V4_RSS_CAP =3D BIT(6), BNGE_RSS_CAP_ESP_V6_RSS_CAP =3D BIT(7), + BNGE_RSS_CAP_IPV6_FLOW_LABEL_RSS_CAP =3D BIT(8), }; =20 #define BNGE_MAX_QUEUE 8 diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c b/drivers/ne= t/ethernet/broadcom/bnge/bnge_ethtool.c index 2467e44de291..f1969de08534 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c @@ -10,6 +10,9 @@ #include =20 #include "bnge.h" +#include "bnge_netdev.h" +#include "bnge_vnic.h" +#include "bnge_resc.h" #include "bnge_ethtool.h" #include "bnge_hwrm_lib.h" =20 @@ -740,6 +743,267 @@ static int bnge_set_pauseparam(struct net_device *dev, return rc; } =20 +static u64 bnge_get_ethtool_ipv4_rss(struct bnge_dev *bd) +{ + if (bd->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4) + return RXH_IP_SRC | RXH_IP_DST; + return 0; +} + +static u64 bnge_get_ethtool_ipv6_rss(struct bnge_dev *bd) +{ + if (bd->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6) + return RXH_IP_SRC | RXH_IP_DST; + if (bd->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6_FLOW_LABEL) + return RXH_IP_SRC | RXH_IP_DST | RXH_IP6_FL; + return 0; +} + +static int bnge_get_rxfh_fields(struct net_device *dev, + struct ethtool_rxfh_fields *cmd) +{ + struct bnge_net *bn =3D netdev_priv(dev); + struct bnge_dev *bd =3D bn->bd; + + cmd->data =3D 0; + switch (cmd->flow_type) { + case TCP_V4_FLOW: + if (bd->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4) + cmd->data |=3D RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + cmd->data |=3D bnge_get_ethtool_ipv4_rss(bd); + break; + case UDP_V4_FLOW: + if (bd->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4) + cmd->data |=3D RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + cmd->data |=3D bnge_get_ethtool_ipv4_rss(bd); + break; + case AH_ESP_V4_FLOW: + if (bd->rss_hash_cfg & + (VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV4 | + VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV4)) + cmd->data |=3D RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + cmd->data |=3D bnge_get_ethtool_ipv4_rss(bd); + break; + case SCTP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + case IPV4_FLOW: + cmd->data |=3D bnge_get_ethtool_ipv4_rss(bd); + break; + case TCP_V6_FLOW: + if (bd->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6) + cmd->data |=3D RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + cmd->data |=3D bnge_get_ethtool_ipv6_rss(bd); + break; + case UDP_V6_FLOW: + if (bd->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6) + cmd->data |=3D RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + cmd->data |=3D bnge_get_ethtool_ipv6_rss(bd); + break; + case AH_ESP_V6_FLOW: + if (bd->rss_hash_cfg & + (VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV6 | + VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV6)) + cmd->data |=3D RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + cmd->data |=3D bnge_get_ethtool_ipv6_rss(bd); + break; + case SCTP_V6_FLOW: + case AH_V6_FLOW: + case ESP_V6_FLOW: + case IPV6_FLOW: + cmd->data |=3D bnge_get_ethtool_ipv6_rss(bd); + break; + } + return 0; +} + +#define RXH_4TUPLE (RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3) +#define RXH_2TUPLE (RXH_IP_SRC | RXH_IP_DST) + +static int bnge_set_rxfh_fields(struct net_device *dev, + const struct ethtool_rxfh_fields *cmd, + struct netlink_ext_ack *extack) +{ + struct bnge_net *bn =3D netdev_priv(dev); + struct bnge_dev *bd =3D bn->bd; + u32 rss_hash_cfg; + int tuple; + + rss_hash_cfg =3D bd->rss_hash_cfg; + + if (cmd->data =3D=3D RXH_4TUPLE || + cmd->data =3D=3D (RXH_4TUPLE | RXH_IP6_FL)) + tuple =3D 4; + else if (cmd->data =3D=3D RXH_2TUPLE || + cmd->data =3D=3D (RXH_2TUPLE | RXH_IP6_FL)) + tuple =3D 2; + else if (!cmd->data) + tuple =3D 0; + else + return -EINVAL; + + if (cmd->data & RXH_IP6_FL && + !(bd->rss_cap & BNGE_RSS_CAP_IPV6_FLOW_LABEL_RSS_CAP)) + return -EINVAL; + + if (cmd->flow_type =3D=3D TCP_V4_FLOW) { + rss_hash_cfg &=3D ~VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4; + if (tuple =3D=3D 4) + rss_hash_cfg |=3D VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4; + } else if (cmd->flow_type =3D=3D UDP_V4_FLOW) { + rss_hash_cfg &=3D ~VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4; + if (tuple =3D=3D 4) + rss_hash_cfg |=3D VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4; + } else if (cmd->flow_type =3D=3D TCP_V6_FLOW) { + rss_hash_cfg &=3D ~VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6; + if (tuple =3D=3D 4) + rss_hash_cfg |=3D VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6; + } else if (cmd->flow_type =3D=3D UDP_V6_FLOW) { + rss_hash_cfg &=3D ~VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6; + if (tuple =3D=3D 4) + rss_hash_cfg |=3D VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6; + } else if (cmd->flow_type =3D=3D AH_ESP_V4_FLOW) { + if (tuple =3D=3D 4 && + (!(bd->rss_cap & BNGE_RSS_CAP_AH_V4_RSS_CAP) || + !(bd->rss_cap & BNGE_RSS_CAP_ESP_V4_RSS_CAP))) + return -EINVAL; + rss_hash_cfg &=3D ~(VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV4 | + VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV4); + if (tuple =3D=3D 4) + rss_hash_cfg |=3D VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV4 | + VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV4; + } else if (cmd->flow_type =3D=3D AH_ESP_V6_FLOW) { + if (tuple =3D=3D 4 && + (!(bd->rss_cap & BNGE_RSS_CAP_AH_V6_RSS_CAP) || + !(bd->rss_cap & BNGE_RSS_CAP_ESP_V6_RSS_CAP))) + return -EINVAL; + rss_hash_cfg &=3D ~(VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV6 | + VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV6); + if (tuple =3D=3D 4) + rss_hash_cfg |=3D VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV6 | + VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV6; + } else if (tuple =3D=3D 4) { + return -EINVAL; + } + + switch (cmd->flow_type) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + case SCTP_V4_FLOW: + case AH_ESP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + case IPV4_FLOW: + if (tuple =3D=3D 2) + rss_hash_cfg |=3D VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4; + else if (!tuple) + rss_hash_cfg &=3D ~VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4; + break; + + case TCP_V6_FLOW: + case UDP_V6_FLOW: + case SCTP_V6_FLOW: + case AH_ESP_V6_FLOW: + case AH_V6_FLOW: + case ESP_V6_FLOW: + case IPV6_FLOW: + if (cmd->data & RXH_IP6_FL) { + rss_hash_cfg |=3D VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6_FLOW_LABEL; + rss_hash_cfg &=3D ~VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6; + } else if (tuple =3D=3D 2) { + rss_hash_cfg |=3D VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6; + rss_hash_cfg &=3D ~VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6_FLOW_LABEL; + } else if (!tuple) { + rss_hash_cfg &=3D ~(VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6 | + VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6_FLOW_LABEL); + } + break; + } + + if (bd->rss_hash_cfg =3D=3D rss_hash_cfg) + return 0; + + if (netif_running(dev)) { + NL_SET_ERR_MSG_MOD(extack, + "RSS configuration can only be changed while the interface is down"= ); + return -EBUSY; + } + + bd->rss_hash_cfg =3D rss_hash_cfg; + + return 0; +} + +static u32 bnge_get_rxfh_indir_size_eth(struct net_device *dev) +{ + struct bnge_net *bn =3D netdev_priv(dev); + struct bnge_dev *bd =3D bn->bd; + + return bnge_get_rxfh_indir_size(bd); +} + +static u32 bnge_get_rxfh_key_size(struct net_device *dev) +{ + return HW_HASH_KEY_SIZE; +} + +static int bnge_get_rxfh(struct net_device *dev, + struct ethtool_rxfh_param *rxfh) +{ + struct bnge_net *bn =3D netdev_priv(dev); + struct bnge_dev *bd =3D bn->bd; + u32 i, tbl_size; + u32 *indir_tbl; + + indir_tbl =3D bd->rss_indir_tbl; + rxfh->hfunc =3D ETH_RSS_HASH_TOP; + + if (rxfh->indir && indir_tbl) { + tbl_size =3D bnge_get_rxfh_indir_size(bd); + for (i =3D 0; i < tbl_size; i++) + rxfh->indir[i] =3D indir_tbl[i]; + } + + if (rxfh->key) + memcpy(rxfh->key, bn->rss_hash_key, HW_HASH_KEY_SIZE); + + return 0; +} + +static int bnge_set_rxfh(struct net_device *dev, + struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack) +{ + struct bnge_net *bn =3D netdev_priv(dev); + + if (rxfh->hfunc && rxfh->hfunc !=3D ETH_RSS_HASH_TOP) + return -EOPNOTSUPP; + + if (netif_running(dev)) { + NL_SET_ERR_MSG_MOD(extack, + "RSS configuration can only be changed while the interface is down"= ); + return -EBUSY; + } + + bnge_modify_rss(bn, NULL, NULL, rxfh); + + return 0; +} + +static u32 bnge_get_rx_ring_count(struct net_device *dev) +{ + struct bnge_net *bn =3D netdev_priv(dev); + struct bnge_dev *bd =3D bn->bd; + + return bd->rx_nr_rings; +} + static const struct ethtool_ops bnge_ethtool_ops =3D { .cap_link_lanes_supported =3D 1, .get_link_ksettings =3D bnge_get_link_ksettings, @@ -757,6 +1021,18 @@ static const struct ethtool_ops bnge_ethtool_ops =3D { .get_eth_ctrl_stats =3D bnge_get_eth_ctrl_stats, .get_pause_stats =3D bnge_get_pause_stats, .get_rmon_stats =3D bnge_get_rmon_stats, + /* RXFH */ + .rxfh_per_ctx_key =3D 1, + .rxfh_max_num_contexts =3D BNGE_MAX_ETH_RSS_CTX + 1, + .rxfh_indir_space =3D BNGE_MAX_RSS_TABLE_ENTRIES, + .rxfh_priv_size =3D sizeof(struct bnge_rss_ctx), + .get_rx_ring_count =3D bnge_get_rx_ring_count, + .get_rxfh_indir_size =3D bnge_get_rxfh_indir_size_eth, + .get_rxfh_key_size =3D bnge_get_rxfh_key_size, + .get_rxfh =3D bnge_get_rxfh, + .set_rxfh =3D bnge_set_rxfh, + .get_rxfh_fields =3D bnge_get_rxfh_fields, + .set_rxfh_fields =3D bnge_set_rxfh_fields, }; =20 void bnge_set_ethtool_ops(struct net_device *dev) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/n= et/ethernet/broadcom/bnge/bnge_hwrm_lib.c index 91d246c8dcf2..86edb70d323e 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c @@ -676,6 +676,8 @@ int bnge_hwrm_vnic_qcaps(struct bnge_dev *bd) bd->rss_cap |=3D BNGE_RSS_CAP_ESP_V4_RSS_CAP; if (flags & VNIC_QCAPS_RESP_FLAGS_RSS_IPSEC_ESP_SPI_IPV6_CAP) bd->rss_cap |=3D BNGE_RSS_CAP_ESP_V6_RSS_CAP; + if (flags & VNIC_QCAPS_RESP_FLAGS_RSS_IPV6_FLOW_LABEL_CAP) + bd->rss_cap |=3D BNGE_RSS_CAP_IPV6_FLOW_LABEL_RSS_CAP; } bnge_hwrm_req_drop(bd, req); =20 diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.c index bab706cb969f..c75c0a7f5c80 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -772,6 +772,9 @@ static void bnge_free_tx_skbs(struct bnge_net *bn) u16 max_idx; int i; =20 + if (!bn->tx_ring) + return; + max_idx =3D bn->tx_nr_pages * TX_DESC_CNT; for (i =3D 0; i < bd->tx_nr_rings; i++) { struct bnge_tx_ring_info *txr =3D &bn->tx_ring[i]; @@ -883,6 +886,9 @@ static void bnge_free_rx_rings(struct bnge_net *bn) struct bnge_dev *bd =3D bn->bd; int i; =20 + if (!bn->rx_ring) + return; + bnge_free_tpa_info(bn); for (i =3D 0; i < bd->rx_nr_rings; i++) { struct bnge_rx_ring_info *rxr =3D &bn->rx_ring[i]; @@ -1026,6 +1032,9 @@ static void bnge_free_tx_rings(struct bnge_net *bn) struct bnge_dev *bd =3D bn->bd; int i; =20 + if (!bn->tx_ring) + return; + for (i =3D 0; i < bd->tx_nr_rings; i++) { struct bnge_tx_ring_info *txr =3D &bn->tx_ring[i]; struct bnge_ring_struct *ring; @@ -2723,7 +2732,7 @@ static int bnge_hwrm_if_change(struct bnge_dev *bd, b= ool up) return bnge_hwrm_req_send(bd, req); } =20 -static int bnge_open_core(struct bnge_net *bn) +int bnge_open_core(struct bnge_net *bn) { struct bnge_dev *bd =3D bn->bd; int rc; @@ -2993,10 +3002,14 @@ static void bnge_save_ring_stats(struct bnge_net *b= n) } } =20 -static void bnge_close_core(struct bnge_net *bn) +void bnge_close_core(struct bnge_net *bn) { struct bnge_dev *bd =3D bn->bd; =20 + /* Already torn down (e.g. after a failed open/reconfiguration) */ + if (!bn->bnapi) + return; + bnge_tx_disable(bn); =20 clear_bit(BNGE_STATE_OPEN, &bd->state); diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.h index 3c0fea0a7608..d68eaa78d4e0 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h @@ -579,4 +579,6 @@ int bnge_alloc_rx_netmem(struct bnge_net *bn, struct bn= ge_rx_ring_info *rxr, u16 prod, gfp_t gfp); void __bnge_queue_sp_work(struct bnge_net *bn); void bnge_copy_hw_masks(u64 *mask_arr, __le64 *hw_mask_arr, int count); +int bnge_open_core(struct bnge_net *bn); +void bnge_close_core(struct bnge_net *bn); #endif /* _BNGE_NETDEV_H_ */ diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h b/drivers/net/e= thernet/broadcom/bnge/bnge_vnic.h index af066d8ff156..b2a1d8332a5f 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h @@ -15,6 +15,7 @@ struct bnge_l2_filter; #define BNGE_MAX_RSS_TABLE_ENTRIES \ (BNGE_RSS_TABLE_ENTRIES * BNGE_RSS_TABLE_MAX_TBL) =20 +#define BNGE_MAX_ETH_RSS_CTX 32 #define BNGE_MAX_CTX_PER_VNIC 8 =20 #define BNGE_MAX_MC_ADDRS 16 --=20 2.52.0 From nobody Fri Sep 25 03:16:18 2026 Received: from mail-pg1-f227.google.com (mail-pg1-f227.google.com [209.85.215.227]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 53C45448B9D for ; Thu, 17 Sep 2026 06:46:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.227 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627598; cv=none; b=SVUdsnd8IgxwycJD4qlgju/7EBA8O5LEJyDkDqjZdY0h//zLpboKp7M0EiFoMYymcJjTYzdLSbfBk4cKAnOTayZvxSnNVP+X9O144H8dDWFO4RBeRR7YmwSPf5kGbjRePqn6ekLr62LfY28sqi5s0WR2aYARgkIH6RknxAtwb34= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627598; c=relaxed/simple; bh=VUyUgX9gI54uFRlYe86ZoSCrxkp9Zm/UKKydohdqeNc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=t5hka+kKb09dViAiYWffF2FkzjLsrNOE/AFcC0WB6h6Wy/T0Zi7kNp4NQxdJYMYWbndhMfsXRpMjFDOivH2vMxvbnogaZIKpkLfBNk9+FIW3Othplt3JQ75Vbs7GwODfKL/52UyDN+R4iqY2VT1Jl64b7VRpvFK8hPVksvE+z4g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=BWmEyfxh; arc=none smtp.client-ip=209.85.215.227 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="BWmEyfxh" Received: by mail-pg1-f227.google.com with SMTP id 41be03b00d2f7-cc4d192643dso160145a12.1 for ; Wed, 16 Sep 2026 23:46:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789627596; x=1790232396; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=b8YyMvujqHd3wteUfLkNVe9en1vIb7NBkl9jwt2Wzes=; b=j9nYQRz5W1omoQPvy0LuVN1T768nyYKC9qTl/A9qhiXFMnHYcYXmzMt10mPXhY4ivt /a2iiqitOVCAHl9q3M771LSNzfmDY7+6iByRof1s9XeNrwS2IMTmsdAliuxG4WI36AOv XmxGj0gVeDF+WRJL4fAteipiGfWWHXZ4FkXJslP7yBZsKpd1efvFdwCxo70Q3MG6DITL gINauGtv8QxCymcUR0c/fBoggh2MV1ktMhBWz2ZMc7rKH3ea4FNxwmRNt1jlfNQFtCmd b81fBxDaBb/iwsrj6+LRCegQeOvZY5YKREDBn0AUTDe+x8PsZhjff/1V0H1xEuaKm7sR wI7w== X-Forwarded-Encrypted: i=1; AKwUvBzKsfHkD+p480HP5/Rqs99NitZJTf3XIsv23mGSVKUx9nzTxm2dLyekSAVuBJgwU6aB/9W0CTljNMsRtjc=@vger.kernel.org X-Gm-Message-State: AFuF++mDQMeCkiF0cPpYID+tWJpEtesq/17CsJ7FkR4kB3ej5ax4bOs8 8RDgVVjp4pNouJMPn/xfhPwztOflvorlIsutyY25HPw2DHGSV5DAv7ia3R/59MUxqaXBlWQz8JB Gq3Au16Bo/SEdRXeiY5G1N8N1fbqx+nyFO1H/k5WVNF1sekGys3xd4uekrRFarLuwbBbnCHj15P xcvBKvQSHxmulM2XG1ey1agZkbpWvR12XnzeJm9cxBUAam6sR7O5peqNw+jjmvXzWq5hdxFYHQI fp66B6Vnqgf9UqTag== X-Gm-Gg: AYBFou22OP5OAWAmCG4qTA0wqONVkMWjRItzmPzQLhcXVWzVRRpOdNDyl4LgjTzRhXp ObZkR9XVE0mwi0BgAsdzxmLYtAaFyCDEicIeLDzjIpIzHXmwNMRPLGsmHYylEKBuH/lOkLyaPbt LFO8UV/npsaFsLINcGk08vHMUwE5nRbSMYF88my3Hr04rCQFvpmwr1PoQ55llWmxMLyhovDmuOQ AGb2mKKEOm+/o9KJ0s82t9umjLuVStfk29DOUPvZQMOThz+OwBadeakuwyCNo0CfCy6CyxChmq6 aL3n1GPkcN82QllwwLLdOVGpw6ew3nlPpHssK7AujiWDRHFXeDijTodlrJ1n5h4TPM4kuAxqYNA fmb0JqhmBOg4EYhZAXtk1KmCHuHQN1j1Mq5rmkeYRXZn5pg34U4WRXA+Typ1ii9OFuwTQDiUSRN oXNmpzSbO1u/sYWruN2rj8BbN02+K/SSU0SyBK X-Received: by 2002:a05:6a20:4393:b0:3d3:afa7:8101 with SMTP id adf61e73a8af0-3dd5f7db6d1mr15399235637.28.1789627595544; Wed, 16 Sep 2026 23:46:35 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-125.dlp.protect.broadcom.com. [144.49.247.125]) by smtp-relay.gmail.com with ESMTPS id 41be03b00d2f7-cc50acd74a6sm2192063a12.6.2026.09.16.23.46.35 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2026 23:46:35 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-cc4ac5feaa4so734909a12.1 for ; Wed, 16 Sep 2026 23:46:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1789627594; x=1790232394; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=b8YyMvujqHd3wteUfLkNVe9en1vIb7NBkl9jwt2Wzes=; b=BWmEyfxhZfeyGUPhMF/sNY5SQs4/r4P2kHvme7K4UtHGOb9QxoECspi+vrwGc7asf4 hnhtIQ/C7lCW6MaWLVfhGa52pl7KDC3IkL530sINwSMqBsLZYpzZh9L4BwvGrO4wgSgz P+Pt6lAya6+/boL30+oLYmwpJOSakUNLRj7R8= X-Forwarded-Encrypted: i=1; AKwUvBztgUcTcwnGoyydse6iaP2es94js4NCKUZvJFkD6qLO6j4I8E7EvGP3fexCxWtf1V8OOGr2BadNq/z5wnc=@vger.kernel.org X-Received: by 2002:a05:6a20:7faa:b0:3d8:f78a:9349 with SMTP id adf61e73a8af0-3dd5f5c9013mr12096175637.13.1789627593666; Wed, 16 Sep 2026 23:46:33 -0700 (PDT) X-Received: by 2002:a05:6a20:7faa:b0:3d8:f78a:9349 with SMTP id adf61e73a8af0-3dd5f5c9013mr12096112637.13.1789627592995; Wed, 16 Sep 2026 23:46:32 -0700 (PDT) Received: from H5S1 ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc50ab960edsm2754293a12.20.2026.09.16.23.46.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 23:46:32 -0700 (PDT) From: Vikas Gupta To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com, vsrama-krishna.nemani@broadcom.com, rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com, ajit.khaparde@broadcom.com, Vikas Gupta Subject: [net-next, v3 06/11] bnge: add ethtool support to manage RSS contexts Date: Thu, 17 Sep 2026 12:15:43 +0530 Message-ID: <20260917064548.773334-7-vikas.gupta@broadcom.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260917064548.773334-1-vikas.gupta@broadcom.com> References: <20260917064548.773334-1-vikas.gupta@broadcom.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-DetectorID-Processed: b00c1d49-9d2e-4205-b15f-d015386d3d5e Content-Type: text/plain; charset="utf-8" Introduce ethtool callbacks to manage RSS contexts. Each context allocates a dedicated VNIC with its own RSS indirection table and hash key, configured with TPA settings matching those of the default VNIC. Signed-off-by: Vikas Gupta Reviewed-by: Bhargava Chenna Marreddy Reviewed-by: Dharmender Garg --- .../net/ethernet/broadcom/bnge/bnge_ethtool.c | 163 ++++++++++++++++++ .../net/ethernet/broadcom/bnge/bnge_netdev.c | 9 + .../net/ethernet/broadcom/bnge/bnge_resc.c | 5 +- .../net/ethernet/broadcom/bnge/bnge_vnic.c | 31 +++- .../net/ethernet/broadcom/bnge/bnge_vnic.h | 14 +- 5 files changed, 214 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c b/drivers/ne= t/ethernet/broadcom/bnge/bnge_ethtool.c index f1969de08534..d4e2968988e2 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c @@ -1004,6 +1004,166 @@ static u32 bnge_get_rx_ring_count(struct net_device= *dev) return bd->rx_nr_rings; } =20 +static int bnge_rxfh_context_check(struct bnge_net *bn, + const struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack) +{ + if (rxfh->hfunc && rxfh->hfunc !=3D ETH_RSS_HASH_TOP) { + NL_SET_ERR_MSG_MOD(extack, "RSS hash function not supported"); + return -EOPNOTSUPP; + } + + if (!(bn->priv_flags & BNGE_NET_EN_NTUPLE)) { + NL_SET_ERR_MSG_MOD(extack, + "Enable ntuple filtering before adding RSS contexts"); + return -EOPNOTSUPP; + } + + if (!netif_running(bn->netdev)) { + NL_SET_ERR_MSG_MOD(extack, "Unable to set RSS contexts when interface is= down"); + return -EAGAIN; + } + + return 0; +} + +static int bnge_create_rxfh_context(struct net_device *dev, + struct ethtool_rxfh_context *ctx, + const struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack) +{ + struct bnge_net *bn =3D netdev_priv(dev); + struct bnge_rss_ctx *rss_ctx; + struct bnge_vnic_info *vnic; + int rc; + + rc =3D bnge_rxfh_context_check(bn, rxfh, extack); + if (rc) + return rc; + + if (bn->num_rss_ctx >=3D BNGE_MAX_ETH_RSS_CTX) { + NL_SET_ERR_MSG_FMT_MOD(extack, "Out of RSS contexts, maximum %u", + BNGE_MAX_ETH_RSS_CTX); + return -EINVAL; + } + + if (!bnge_arfs_capable(bn->bd, true)) { + NL_SET_ERR_MSG_MOD(extack, "Out of hardware resources"); + return -ENOMEM; + } + + rss_ctx =3D ethtool_rxfh_context_priv(ctx); + + bn->num_rss_ctx++; + + vnic =3D &rss_ctx->vnic; + + bnge_init_vnic_mem(vnic); + + vnic->rss_ctx =3D ctx; + vnic->flags |=3D BNGE_VNIC_RSSCTX_FLAG; + rc =3D bnge_alloc_vnic_rss_table(bn, vnic); + if (rc) + goto err_del_rss_ctx; + + /* Populate defaults in the context */ + bnge_set_dflt_rss_indir_tbl(bn->bd, ctx); + ctx->hfunc =3D ETH_RSS_HASH_TOP; + memcpy(vnic->rss_hash_key, bn->rss_hash_key, HW_HASH_KEY_SIZE); + memcpy(ethtool_rxfh_context_key(ctx), + bn->rss_hash_key, HW_HASH_KEY_SIZE); + + rc =3D bnge_hwrm_vnic_alloc(bn->bd, vnic, bn->bd->rx_nr_rings); + if (rc) { + NL_SET_ERR_MSG_MOD(extack, "Unable to allocate VNIC"); + goto err_del_rss_ctx; + } + + rc =3D bnge_hwrm_vnic_set_tpa(bn->bd, vnic, + bn->priv_flags & BNGE_NET_EN_TPA); + if (rc) { + NL_SET_ERR_MSG_MOD(extack, + "Unable to set TPA settings to vnic"); + goto err_del_rss_ctx; + } + bnge_modify_rss(bn, ctx, rss_ctx, rxfh); + + rc =3D bnge_setup_vnic(bn, vnic); + if (rc) { + NL_SET_ERR_MSG_MOD(extack, "Unable to setup vnic"); + goto err_del_rss_ctx; + } + + rss_ctx->index =3D rxfh->rss_context; + return 0; + +err_del_rss_ctx: + bnge_del_one_rss_ctx(bn, rss_ctx, true); + return rc; +} + +static int bnge_modify_rxfh_context(struct net_device *dev, + struct ethtool_rxfh_context *ctx, + const struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack) +{ + struct bnge_net *bn =3D netdev_priv(dev); + u8 old_key[HW_HASH_KEY_SIZE]; + struct bnge_rss_ctx *rss_ctx; + u32 *old_indir =3D NULL; + u32 tbl_size; + int rc; + + rc =3D bnge_rxfh_context_check(bn, rxfh, extack); + if (rc) + return rc; + + rss_ctx =3D ethtool_rxfh_context_priv(ctx); + tbl_size =3D bnge_get_rxfh_indir_size(bn->bd); + + /* Snapshot the software state so it can be restored if the hardware + * update fails, keeping the reported config consistent with the + * hardware. + */ + if (rxfh->key) + memcpy(old_key, rss_ctx->vnic.rss_hash_key, HW_HASH_KEY_SIZE); + if (rxfh->indir) { + old_indir =3D kmemdup(ethtool_rxfh_context_indir(ctx), + tbl_size * sizeof(*old_indir), GFP_KERNEL); + if (!old_indir) + return -ENOMEM; + } + + bnge_modify_rss(bn, ctx, rss_ctx, rxfh); + + rc =3D bnge_hwrm_vnic_rss_cfg(bn, &rss_ctx->vnic); + if (rc) { + if (rxfh->key) + memcpy(rss_ctx->vnic.rss_hash_key, old_key, + HW_HASH_KEY_SIZE); + if (rxfh->indir) + memcpy(ethtool_rxfh_context_indir(ctx), old_indir, + tbl_size * sizeof(*old_indir)); + } + + kfree(old_indir); + return rc; +} + +static int bnge_remove_rxfh_context(struct net_device *dev, + struct ethtool_rxfh_context *ctx, + u32 rss_context, + struct netlink_ext_ack *extack) +{ + struct bnge_net *bn =3D netdev_priv(dev); + struct bnge_rss_ctx *rss_ctx; + + rss_ctx =3D ethtool_rxfh_context_priv(ctx); + + bnge_del_one_rss_ctx(bn, rss_ctx, true); + return 0; +} + static const struct ethtool_ops bnge_ethtool_ops =3D { .cap_link_lanes_supported =3D 1, .get_link_ksettings =3D bnge_get_link_ksettings, @@ -1033,6 +1193,9 @@ static const struct ethtool_ops bnge_ethtool_ops =3D { .set_rxfh =3D bnge_set_rxfh, .get_rxfh_fields =3D bnge_get_rxfh_fields, .set_rxfh_fields =3D bnge_set_rxfh_fields, + .create_rxfh_context =3D bnge_create_rxfh_context, + .modify_rxfh_context =3D bnge_modify_rxfh_context, + .remove_rxfh_context =3D bnge_remove_rxfh_context, }; =20 void bnge_set_ethtool_ops(struct net_device *dev) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.c index c75c0a7f5c80..3dcab0370bdf 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -2794,6 +2794,8 @@ int bnge_open_core(struct bnge_net *bn) /* Poll link status and check for SFP+ module status */ bnge_get_port_module_status(bn); =20 + bnge_hwrm_realloc_rss_ctx_vnic(bn); + return 0; =20 err_free_irq: @@ -3015,7 +3017,10 @@ void bnge_close_core(struct bnge_net *bn) clear_bit(BNGE_STATE_OPEN, &bd->state); =20 timer_delete_sync(&bn->timer); + + bnge_clear_rss_ctxs(bn); bnge_shutdown_nic(bn); + bnge_disable_napi(bn); =20 /* Save ring stats before shutdown */ @@ -3149,6 +3154,10 @@ static int bnge_set_features(struct net_device *dev,= netdev_features_t features) if (flags =3D=3D bn->priv_flags) return 0; =20 + if ((bn->priv_flags & BNGE_NET_EN_NTUPLE) && + !(flags & BNGE_NET_EN_NTUPLE) && bn->num_rss_ctx) + return -EBUSY; + bn->priv_flags =3D flags; =20 return 0; diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c b/drivers/net/e= thernet/broadcom/bnge/bnge_resc.c index b7a01cf885f2..0a4c4cf5eabf 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_resc.c @@ -352,8 +352,9 @@ int bnge_reserve_rings(struct bnge_dev *bd) if (!bnge_rings_ok(&hwr)) return -ENOMEM; =20 - if (old_rx_rings !=3D bd->hw_resc.resv_rx_rings) - bnge_set_dflt_rss_indir_tbl(bd); + if (old_rx_rings !=3D bd->hw_resc.resv_rx_rings && + (!bd->netdev || !netif_is_rxfh_configured(bd->netdev))) + bnge_set_dflt_rss_indir_tbl(bd, NULL); =20 if (!bnge_aux_registered(bd)) { u16 resv_msix, resv_ctx, aux_ctxs; diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c b/drivers/net/e= thernet/broadcom/bnge/bnge_vnic.c index 7857421cd672..3aa89bcd96b9 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c @@ -12,21 +12,26 @@ #include "bnge_filter.h" #include "bnge_ethtool.h" =20 -void bnge_set_dflt_rss_indir_tbl(struct bnge_dev *bd) +void bnge_set_dflt_rss_indir_tbl(struct bnge_dev *bd, + struct ethtool_rxfh_context *rss_ctx) { u16 max_entries, pad; u32 *rss_indir_tbl; u16 i; =20 max_entries =3D bnge_get_rxfh_indir_size(bd); - rss_indir_tbl =3D &bd->rss_indir_tbl[0]; + + if (rss_ctx) + rss_indir_tbl =3D ethtool_rxfh_context_indir(rss_ctx); + else + rss_indir_tbl =3D &bd->rss_indir_tbl[0]; =20 for (i =3D 0; i < max_entries; i++) rss_indir_tbl[i] =3D ethtool_rxfh_indir_default(i, bd->rx_nr_rings); =20 pad =3D bd->rss_indir_tbl_entries - max_entries; - if (pad) + if (pad && !rss_ctx) memset(&rss_indir_tbl[i], 0, pad * sizeof(*rss_indir_tbl)); } =20 @@ -44,6 +49,8 @@ void bnge_fill_hw_rss_tbl(struct bnge_net *bn, struct bng= e_vnic_info *vnic) =20 if (vnic->flags & BNGE_VNIC_NTUPLE_FLAG) j =3D ethtool_rxfh_indir_default(i, bd->rx_nr_rings); + else if (vnic->flags & BNGE_VNIC_RSSCTX_FLAG) + j =3D ethtool_rxfh_context_indir(vnic->rss_ctx)[i]; else j =3D bd->rss_indir_tbl[i]; =20 @@ -155,7 +162,7 @@ void bnge_modify_rss(struct bnge_net *bn, struct ethtoo= l_rxfh_context *ctx, for (i =3D 0; i < tbl_size; i++) indir_tbl[i] =3D rxfh->indir[i]; pad =3D bd->rss_indir_tbl_entries - tbl_size; - if (pad) + if (pad && !rss_ctx) memset(&indir_tbl[i], 0, pad * sizeof(*indir_tbl)); } } @@ -188,6 +195,10 @@ void bnge_hwrm_realloc_rss_ctx_vnic(struct bnge_net *b= n) struct ethtool_rxfh_context *ctx; unsigned long context; =20 + /* Erasing lost contexts touches netdev->ethtool->rss_ctx and calls + * ethtool_rxfh_context_lost(), which requires the ethtool rss_lock. + */ + mutex_lock(&bn->netdev->ethtool->rss_lock); xa_for_each(&bn->netdev->ethtool->rss_ctx, context, ctx) { struct bnge_rss_ctx *rss_ctx =3D ethtool_rxfh_context_priv(ctx); struct bnge_vnic_info *vnic =3D &rss_ctx->vnic; @@ -201,6 +212,7 @@ void bnge_hwrm_realloc_rss_ctx_vnic(struct bnge_net *bn) ethtool_rxfh_context_lost(bn->netdev, rss_ctx->index); } } + mutex_unlock(&bn->netdev->ethtool->rss_lock); } =20 void bnge_clear_rss_ctxs(struct bnge_net *bn) @@ -242,3 +254,14 @@ int bnge_alloc_vnic_rss_table(struct bnge_net *bn, vnic->rss_hash_key_dma_addr =3D vnic->rss_table_dma_addr + size; return 0; } + +void bnge_init_vnic_mem(struct bnge_vnic_info *vnic) +{ + int i; + + vnic->fw_vnic_id =3D INVALID_HW_RING_ID; + vnic->vnic_id =3D BNGE_VNIC_ID_INVALID; + + for (i =3D 0; i < BNGE_MAX_CTX_PER_VNIC; i++) + vnic->fw_rss_cos_lb_ctx[i] =3D INVALID_HW_RING_ID; +} diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h b/drivers/net/e= thernet/broadcom/bnge/bnge_vnic.h index b2a1d8332a5f..3954c450315d 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_vnic.h @@ -21,6 +21,11 @@ struct bnge_l2_filter; #define BNGE_MAX_MC_ADDRS 16 #define BNGE_MAX_UC_ADDRS 4 =20 +#define BNGE_VNIC_ID_INVALID 0xffffffff + +struct ethtool_rxfh_context; +struct ethtool_rxfh_param; + enum { BNGE_VNIC_DEFAULT =3D 0, BNGE_VNIC_NTUPLE =3D 1 @@ -30,7 +35,8 @@ enum { BNGE_VNIC_RSS_FLAG =3D BIT(0), BNGE_VNIC_MCAST_FLAG =3D BIT(1), BNGE_VNIC_UCAST_FLAG =3D BIT(2), - BNGE_VNIC_NTUPLE_FLAG =3D BIT(3) + BNGE_VNIC_NTUPLE_FLAG =3D BIT(3), + BNGE_VNIC_RSSCTX_FLAG =3D BIT(4) }; =20 struct bnge_vnic_info { @@ -55,6 +61,8 @@ struct bnge_vnic_info { =20 u32 flags; u32 vnic_id; + + struct ethtool_rxfh_context *rss_ctx; }; =20 struct bnge_rss_ctx { @@ -66,7 +74,8 @@ void bnge_fill_hw_rss_tbl(struct bnge_net *bn, struct bng= e_vnic_info *vnic); int bnge_hwrm_vnic_rss_cfg(struct bnge_net *bn, struct bnge_vnic_info *vnic); int bnge_setup_vnic(struct bnge_net *bn, struct bnge_vnic_info *vnic); -void bnge_set_dflt_rss_indir_tbl(struct bnge_dev *bd); +void bnge_set_dflt_rss_indir_tbl(struct bnge_dev *bd, + struct ethtool_rxfh_context *ctx); int bnge_alloc_rfs_vnic(struct bnge_net *bn); int bnge_alloc_vnic_rss_table(struct bnge_net *bn, struct bnge_vnic_info *vnic); @@ -78,4 +87,5 @@ void bnge_del_one_rss_ctx(struct bnge_net *bn, struct bng= e_rss_ctx *rss_ctx, bool all); void bnge_hwrm_realloc_rss_ctx_vnic(struct bnge_net *bn); void bnge_clear_rss_ctxs(struct bnge_net *bn); +void bnge_init_vnic_mem(struct bnge_vnic_info *vnic); #endif /* _BNGE_VNIC_H_ */ --=20 2.52.0 From nobody Fri Sep 25 03:16:18 2026 Received: from mail-pg1-f226.google.com (mail-pg1-f226.google.com [209.85.215.226]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D9414449B34 for ; Thu, 17 Sep 2026 06:46:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.226 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627603; cv=none; b=AaQcQFMJcnfvBCxaCVxPW6fmqNWkO5dwnVH9jOQGVA5qelM2yCX3sP4lUa3HtxWB2+wqiD6VXpQnsalmgT1kcdGPRSelcGCfsTCpC//0CMM/g4HFO9bULLZ8DmO6XqmeJTjyR39pD0EVD0UIq076OlzMH3mCcWNLb3qHynUKWfs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627603; c=relaxed/simple; bh=FJzSCfR4ZaCg30MFvONEMoFWjabSAHjeo4uJ9KGpewI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PQfYNjc2LPk/pjwbaNSUPowqxL73JgJnKii5LgFBX6739+U+3oxZJXjbbufqm0abGTnXG4Z77fB7jCz9vWL69E0KVsoG56tL5rrDC1cGz9Ui03yfpVZ1sd0Ut6nIQhnBQGHwIo1c7hDrUmCNHAot7rBJ1JMFK2NUfoIBgJmuq8g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=b7Yt6167; arc=none smtp.client-ip=209.85.215.226 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="b7Yt6167" Received: by mail-pg1-f226.google.com with SMTP id 41be03b00d2f7-cc1cb472b76so170074a12.0 for ; Wed, 16 Sep 2026 23:46:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789627601; x=1790232401; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=K1uINDFjo2ML6R3SHyow6jDUjhiv3et72Nqn9GZ5YjY=; b=zgSLyi/8r3aYkK6mxYH4j6a2cLFAWXRlc1/Ge0OKs/OE2BnkJu0N8MOZ8U6NsACkwx eYAeWZ2+ha/wJtYf3kMBVD6hYvg2/StnKSi4CkMbd5A9yF7bwFLIQnYHOboSoG82hHDR pw0DKs8+oLmweqiytdJSPFPq63pva0SmCMmucBGyB6sPB7H181x7VApwIWrF82E//Dw4 XW7G+XYsyN2mANrGWBaWRX+V1U9tkRKpDF3doZ+xTxAkhs86mA5leX6WUqLXOzP47aPc /Q+jst7A7BslEDCXVmgzM2fkiD6CdWTiePR0yKOJ7SyQ4sx167H+y79hGvMN0SMio6Fx 6Lqw== X-Forwarded-Encrypted: i=1; AKwUvBxYrl6ITC+zISh2wTQsIeA4fHzyofMvmyzGwh2l6JkAiL8RbwqIK4c5g5VC62iSHsyHMS2znrAP0ILn3A4=@vger.kernel.org X-Gm-Message-State: AFuF++kN1MQRSQdzJbxmd1pAutKg+ALKHoKheaKSOzYLNbRd4wN0yi9e 5JHJ+HMEJQC4MGmqbWDTnaD3OcqLc+YbyrcfZ+oxavav3LIPbOWAkmlSJC1leV/9AVJ/G2Bn2BR KiwmVLW7hVgjrlCJO9UcqAfSEYklCffs2fYBJzui+vU+nWn7AXvRWs0ImiiuH4HHp46NuLcLzWx ezzIXDRpicRx559v3f8y0li6trrsXSkMCWWo8jVw8fdxf0RyuE/rKIF4o0vpxiumWA4Y5GQX0DE +5PyFZZ7QxjH44HpA== X-Gm-Gg: AYBFou1+BTTUYOMxvXx/uNOLw6wQL7HHzNBGblRM7ZpEVr59li2OtAC2yiO5CjvODmx oYP9e9KdDCdVMhUSbWRTgh3n/lolrhxVYUkv6yg51FvpTcQQj//P91SF+kbklfEelcjr3mrThq6 +IGG5qa9AMw0Vy2L9B3DLPVd6KmsdQu9zzimR69t7XvZ08jXnbT+Ghdbr4sER+wyCpy8WVolE95 qRf8e7TYaQSfFDSTt+f+OVMuPZ5+bXSOrYI3qBN/5FuAwl5JbNMco42D7MkkW8km/DSvlwzqeid ztsmwDWerwF1YGaOTh1WAqLKDgm8awJnvpUl1Vkcn7WzPjnv9hBcJX7qj8N+Yuax1PaCI+doTXM IzOApyIShVZtdzUaFMfY1glleP2F6ZS6e0ID+vDTF0utyiRd8sCcDQGpldjnyR2k/praujmOEck bJKdlYBtiMEXnExHGiwYDl6PFJqUPyyFoR+Q== X-Received: by 2002:a05:6a00:408e:b0:869:2b72:525d with SMTP id d2e1a72fcca58-87238d832eamr13526051b3a.7.1789627601108; Wed, 16 Sep 2026 23:46:41 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-98.dlp.protect.broadcom.com. [144.49.247.98]) by smtp-relay.gmail.com with ESMTPS id d2e1a72fcca58-871fc14237fsm1427920b3a.0.2026.09.16.23.46.40 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2026 23:46:41 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pg1-f200.google.com with SMTP id 41be03b00d2f7-cbee6bb8408so666802a12.3 for ; Wed, 16 Sep 2026 23:46:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1789627599; x=1790232399; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=K1uINDFjo2ML6R3SHyow6jDUjhiv3et72Nqn9GZ5YjY=; b=b7Yt6167rAOEENqILy5prH6WZedz7a0rcn3T2NXc8VLASv6syKF7FsXymxt73c77OU EREuevfAu7ZOGZykau2RZkhRvJRnXlhL8jwsu8EelE2j3VRfmwkuvr39PugKU+wz4wC5 AYftQ/WYrsaebAsIGzLHcEvTu4pECtoHDsOi8= X-Forwarded-Encrypted: i=1; AKwUvBwAMbQoAthT2KEokl5opJp7cwB6pOMElwhPHQY5dJGwS+E/Ub4oz+aMCaKuXXGBfieTQESTGViqrKTBrBY=@vger.kernel.org X-Received: by 2002:a05:6a20:9150:b0:3cd:9bb1:c6f5 with SMTP id adf61e73a8af0-3dd5f451226mr13814450637.10.1789627599188; Wed, 16 Sep 2026 23:46:39 -0700 (PDT) X-Received: by 2002:a05:6a20:9150:b0:3cd:9bb1:c6f5 with SMTP id adf61e73a8af0-3dd5f451226mr13814398637.10.1789627598733; Wed, 16 Sep 2026 23:46:38 -0700 (PDT) Received: from H5S1 ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc50ab960edsm2754293a12.20.2026.09.16.23.46.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 23:46:38 -0700 (PDT) From: Vikas Gupta To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com, vsrama-krishna.nemani@broadcom.com, rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com, ajit.khaparde@broadcom.com, Vikas Gupta Subject: [net-next, v3 07/11] bnge: remove refcount from L2 filter Date: Thu, 17 Sep 2026 12:15:44 +0530 Message-ID: <20260917064548.773334-8-vikas.gupta@broadcom.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260917064548.773334-1-vikas.gupta@broadcom.com> References: <20260917064548.773334-1-vikas.gupta@broadcom.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-DetectorID-Processed: b00c1d49-9d2e-4205-b15f-d015386d3d5e Content-Type: text/plain; charset="utf-8" A reference count was previously used under the assumption that any context holding the last reference could delete the L2 filter. However, going forward, the filter will only be removed by the same context that created it, making refcount unnecessary. The primary and secondary MAC addresses passed by the kernel are guaranteed to be distinct, so each results in a filter being created exactly once. Signed-off-by: Vikas Gupta Reviewed-by: Dharmender Garg --- .../net/ethernet/broadcom/bnge/bnge_filter.c | 28 ++++--------------- .../net/ethernet/broadcom/bnge/bnge_filter.h | 1 - 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.c b/drivers/net= /ethernet/broadcom/bnge/bnge_filter.c index d1279a4babcd..e10a774c3033 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_filter.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.c @@ -13,8 +13,6 @@ =20 void bnge_del_l2_filter(struct bnge_net *bn, struct bnge_l2_filter *fltr) { - if (!refcount_dec_and_test(&fltr->refcnt)) - return; hlist_del_rcu(&fltr->base.hlist); kfree_rcu(fltr, base.rcu); } @@ -31,18 +29,17 @@ static void bnge_init_l2_filter(struct bnge_net *bn, =20 head =3D &bn->l2_fltr_hash_tbl[idx]; hlist_add_head_rcu(&fltr->base.hlist, head); - refcount_set(&fltr->refcnt, 1); } =20 -static struct bnge_l2_filter *__bnge_lookup_l2_filter(struct bnge_net *bn, - struct bnge_l2_key *key, - u32 idx) +struct bnge_l2_filter *bnge_lookup_l2_filter(struct bnge_net *bn, + struct bnge_l2_key *key, + u32 idx) { struct bnge_l2_filter *fltr; struct hlist_head *head; =20 head =3D &bn->l2_fltr_hash_tbl[idx]; - hlist_for_each_entry_rcu(fltr, head, base.hlist) { + hlist_for_each_entry(fltr, head, base.hlist) { struct bnge_l2_key *l2_key =3D &fltr->l2_key; =20 if (ether_addr_equal(l2_key->dst_mac_addr, key->dst_mac_addr) && @@ -52,20 +49,6 @@ static struct bnge_l2_filter *__bnge_lookup_l2_filter(st= ruct bnge_net *bn, return NULL; } =20 -struct bnge_l2_filter *bnge_lookup_l2_filter(struct bnge_net *bn, - struct bnge_l2_key *key, - u32 idx) -{ - struct bnge_l2_filter *fltr; - - rcu_read_lock(); - fltr =3D __bnge_lookup_l2_filter(bn, key, idx); - if (fltr) - refcount_inc(&fltr->refcnt); - rcu_read_unlock(); - return fltr; -} - static struct bnge_l2_filter *bnge_alloc_l2_filter(struct bnge_net *bn, struct bnge_l2_key *key, gfp_t gfp) @@ -75,9 +58,10 @@ static struct bnge_l2_filter *bnge_alloc_l2_filter(struc= t bnge_net *bn, =20 idx =3D jhash2(&key->filter_key, BNGE_L2_KEY_SIZE, bn->hash_seed) & BNGE_L2_FLTR_HASH_MASK; + fltr =3D bnge_lookup_l2_filter(bn, key, idx); if (fltr) - return fltr; + return ERR_PTR(-EEXIST); =20 fltr =3D kzalloc_obj(*fltr, gfp); if (!fltr) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.h b/drivers/net= /ethernet/broadcom/bnge/bnge_filter.h index 44ee1357a0ff..16a5d91517c9 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_filter.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.h @@ -42,7 +42,6 @@ struct bnge_l2_filter { /* base filter must be the first member */ struct bnge_filter_base base; struct bnge_l2_key l2_key; - refcount_t refcnt; }; =20 void bnge_del_l2_filter(struct bnge_net *bn, struct bnge_l2_filter *fltr); --=20 2.52.0 From nobody Fri Sep 25 03:16:18 2026 Received: from mail-pl1-f225.google.com (mail-pl1-f225.google.com [209.85.214.225]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 74ABF43FD0B for ; Thu, 17 Sep 2026 06:46:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.225 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627611; cv=none; b=dj+opP9jrQqtpHXf5xYXEht8ApBOiz34cNCqN0Yfx+ZVHjOChCaeF78nF3e9/90vXKWl0RjLf989otn8bfX414+3MtpRmS1zP/0DVFBY1wCXlbisepHgjOHw5M7JRJcgk+fTM+Q5Wqmn7R4lJHlUQhAQzBCyxEWmsH/S+9IumUU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627611; c=relaxed/simple; bh=3W4A1WGZzmmZnJxZlLxKrhwBYDySMqG32fM22CFYFh0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XJFIM0aMpXz818W0lcqzvL9M96Swg3yqfhkhVEPHN3h+qa1BSnkdEQpoc9N1uMpfLhVi7vojljlzbHGdzpKdf7CMrGaJHJOCfB/Yu/B9Q4tqGFMr8M0lar/sIYZfiHsUMOW5KALXf0EhWceSTs9IsRKtV04gVPrilrdhmNLAeJY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=SOqASV5+; arc=none smtp.client-ip=209.85.214.225 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="SOqASV5+" Received: by mail-pl1-f225.google.com with SMTP id d9443c01a7336-2dd664da0f5so2146975ad.0 for ; Wed, 16 Sep 2026 23:46:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789627609; x=1790232409; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=n8P48uP3wBqQG/cmhh+LqVY7vEt5BbPlgj0d2GBHfbo=; b=I/y4hcLRz0Knw8QpbKRQAy0+KPhTTlF5JH32qJoxK2PWrr+GvOyCClE6ELDfQgXDMz xm/fSG1lOP0PMo5p/DgwKyHH2tzS4sIw91a/9wmwQtqaYNi18GIGdHfE6LVkZ4mVYsIZ AdCmOB+sm7ffwjEjQuKF5eQepX6Escmw3ZDuYfZts1LHoHtcFeihGtrDrcG69zSyw7Gs sa+/ika5g+FilJiAlL2/ATW6UeGceLfNslK42lm2L0+a4Wk2l1b0mjGV9PK+9tpvbYYy XDAWDVmrgqAFLmGsCP/9l9+VCfSgW4ZYWtW2nxYld7g+gCdhDqqnUEU+wM5wk0krDRIT FDPQ== X-Forwarded-Encrypted: i=1; AKwUvBzzfZrkrZCjeRfb2p4dRCtZg6R5dW9cmB+vnxnOZRqAgrQdJlO29ebWmIXE/JSRaNGGWIigLSXjC0hZTpQ=@vger.kernel.org X-Gm-Message-State: AFuF++l7pofIT1kp5crj6Zb/v2rn7lOD2x+BUTqamIthVgZ4Yo4hJsEe peWlHkuJVhlpwtm6M/D4MmGp9hFq4VGyPt1VflyQ2iquDR9jKfAnqAPUWMTdwD/rp98+qglUBZg E3Ld103s0RYNH15mKTpnYP0MeWvfpBbf2L/zbzw4H2eYkJHOks/8KbQ0OSredWDI/aVxYanvS4I /EDYPW13iskxG//aUsG+nn1dH7STcT6znmr14en+IPXddh7wlxzJoCMFjp1MqvyEPaAwbFA1Qap eqeWrXyFzA7sXgEPw== X-Gm-Gg: AYBFou3Toz7AB2JZ0p401IrsVlMUtVfDPz7mEshlwhKS0WPl4r5W8AUZc1TOOE4Ongh txoWiL8zJnjG2spo26Pxacfws6CVnaIDfr6airdm9rRWLSOyIoD2+7GJLnTbizV2MQlHtDQlMCg dHHWsUroQ9Jf5Mrg3ngqUyabC2IFdeetaAc4qJc+6obRQmpxzC9y1qL0eWYfBm1tUCiuPyxz0uV U69KFCCDegzoY7peWJHwrCG1IsT2F0g3A8dN0eG/UGUKFPVm7KMomwpC7qAANaFSR0n61pWdPPI yHUH4d7OHtdYRLHZxqWyoNAQ8sR1cMgMaH6BC2VUYp5KTuX9HDosOjeQuYJqTv8kips86Y85FaK DxRcHaI3s6FAP0bltXAd9FO705fkR4xq+7EqAa3Vb1ZU22reik8xI1WPhxQrcQGA48IlfHNArF+ F14rms4K35mGiiaMKnINxFon8c+naCycMQLg== X-Received: by 2002:a17:90a:1189:b0:39e:21a7:5df5 with SMTP id 98e67ed59e1d1-39e21a761b4mr8350252a91.24.1789627608429; Wed, 16 Sep 2026 23:46:48 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-29.dlp.protect.broadcom.com. [144.49.247.29]) by smtp-relay.gmail.com with ESMTPS id 98e67ed59e1d1-39e35dd6cdbsm1114202a91.3.2026.09.16.23.46.47 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2026 23:46:48 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pg1-f199.google.com with SMTP id 41be03b00d2f7-cc4fc935a11so444130a12.0 for ; Wed, 16 Sep 2026 23:46:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1789627607; x=1790232407; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=n8P48uP3wBqQG/cmhh+LqVY7vEt5BbPlgj0d2GBHfbo=; b=SOqASV5+Jj+lX3SumlRrus0ZzhwLOQDDw88i35UFx74lSeu7EQ3sq4bX0+3NWkmkth +bJYwPNzARtv65ZNcFEL58B3Pw0wN4PFQmMK8GommNaG27c7fs2YbnPHGh+0k+K3oNuR fnrVAyxSfglYuCKEOBNc1+vOeWBDmpmwABs7w= X-Forwarded-Encrypted: i=1; AKwUvBwEhz41lpRrK06MKrslQ4dQWURU4mXrM96BN/+7/bQS0qq6gEqNc/0SP/z4awffDFoFb0pkk0CCKrSNOhQ=@vger.kernel.org X-Received: by 2002:a05:6a20:3d02:b0:3da:15a9:a18e with SMTP id adf61e73a8af0-3dd5f74d9bfmr15642964637.23.1789627606410; Wed, 16 Sep 2026 23:46:46 -0700 (PDT) X-Received: by 2002:a05:6a20:3d02:b0:3da:15a9:a18e with SMTP id adf61e73a8af0-3dd5f74d9bfmr15642878637.23.1789627605760; Wed, 16 Sep 2026 23:46:45 -0700 (PDT) Received: from H5S1 ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc50ab960edsm2754293a12.20.2026.09.16.23.46.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 23:46:45 -0700 (PDT) From: Vikas Gupta To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com, vsrama-krishna.nemani@broadcom.com, rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com, ajit.khaparde@broadcom.com, Vikas Gupta Subject: [net-next, v3 08/11] bnge: add NTUPLE filter infrastructure Date: Thu, 17 Sep 2026 12:15:45 +0530 Message-ID: <20260917064548.773334-9-vikas.gupta@broadcom.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260917064548.773334-1-vikas.gupta@broadcom.com> References: <20260917064548.773334-1-vikas.gupta@broadcom.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-DetectorID-Processed: b00c1d49-9d2e-4205-b15f-d015386d3d5e Content-Type: text/plain; charset="utf-8" Add the core NTUPLE filter data structures and firmware command wrappers needed for flow rule management. This helps further patches implement user-created NTUPLE rules as well as rules via kernel flow steering. Signed-off-by: Vikas Gupta Reviewed-by: Dharmender Garg --- drivers/net/ethernet/broadcom/bnge/bnge.h | 1 - .../net/ethernet/broadcom/bnge/bnge_filter.c | 494 +++++++++++++++++- .../net/ethernet/broadcom/bnge/bnge_filter.h | 69 ++- .../ethernet/broadcom/bnge/bnge_hwrm_lib.c | 143 ++++- .../ethernet/broadcom/bnge/bnge_hwrm_lib.h | 7 + .../net/ethernet/broadcom/bnge/bnge_netdev.c | 14 + .../net/ethernet/broadcom/bnge/bnge_netdev.h | 13 + .../net/ethernet/broadcom/bnge/bnge_resc.c | 6 +- .../net/ethernet/broadcom/bnge/bnge_vnic.c | 17 + 9 files changed, 751 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge.h b/drivers/net/ethern= et/broadcom/bnge/bnge.h index f0b152e6a43a..b7aef5c39b28 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge.h @@ -161,7 +161,6 @@ struct bnge_dev { u16 tso_max_segs; =20 int max_fltr; -#define BNGE_L2_FLTR_MAX_FLTR 1024 =20 u32 *rss_indir_tbl; u16 rss_indir_tbl_entries; diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.c b/drivers/net= /ethernet/broadcom/bnge/bnge_filter.c index e10a774c3033..698bd3967c27 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_filter.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include =20 #include "bnge.h" #include "bnge_netdev.h" @@ -11,24 +13,150 @@ #include "bnge_hwrm_lib.h" #include "bnge_filter.h" =20 -void bnge_del_l2_filter(struct bnge_net *bn, struct bnge_l2_filter *fltr) +#define BNGE_IPV6_MASK_ALL {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0= xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}} +#define BNGE_IPV6_MASK_NONE {{{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, = 0, 0 }}} + +const struct bnge_flow_masks BNGE_FLOW_MASK_NONE =3D { + .ports =3D { + .src =3D 0, + .dst =3D 0, + }, + .addrs =3D { + .v6addrs =3D { + .src =3D BNGE_IPV6_MASK_NONE, + .dst =3D BNGE_IPV6_MASK_NONE, + }, + }, +}; + +const struct bnge_flow_masks BNGE_FLOW_IPV6_MASK_ALL =3D { + .ports =3D { + .src =3D cpu_to_be16(0xffff), + .dst =3D cpu_to_be16(0xffff), + }, + .addrs =3D { + .v6addrs =3D { + .src =3D BNGE_IPV6_MASK_ALL, + .dst =3D BNGE_IPV6_MASK_ALL, + }, + }, +}; + +const struct bnge_flow_masks BNGE_FLOW_IPV4_MASK_ALL =3D { + .ports =3D { + .src =3D cpu_to_be16(0xffff), + .dst =3D cpu_to_be16(0xffff), + }, + .addrs =3D { + .v4addrs =3D { + .src =3D cpu_to_be32(0xffffffff), + .dst =3D cpu_to_be32(0xffffffff), + }, + }, +}; + +static bool bnge_is_usr_fltr(struct bnge_filter_base *fltr) +{ + return (fltr->type =3D=3D BNGE_FLTR_TYPE_L2 && + fltr->flags & BNGE_ACT_RING_DST) || + (fltr->type =3D=3D BNGE_FLTR_TYPE_NTUPLE && + fltr->flags & BNGE_ACT_NO_AGING); +} + +static void bnge_insert_usr_fltr(struct bnge_net *bn, + struct bnge_filter_base *fltr) +{ + if (!bnge_is_usr_fltr(fltr)) + return; + + INIT_LIST_HEAD(&fltr->list_node); + list_add_tail(&fltr->list_node, &bn->usr_fltr_list); + bn->user_fltr_count++; +} + +static void bnge_del_usr_fltr_node(struct bnge_net *bn, + struct bnge_filter_base *fltr) { + if (!bnge_is_usr_fltr(fltr)) + return; + + if (!list_empty(&fltr->list_node)) { + list_del_init(&fltr->list_node); + bn->user_fltr_count--; + } +} + +void bnge_del_l2_filter_rcu(struct bnge_net *bn, struct bnge_l2_filter *lf= ltr) +{ + struct bnge_filter_base *fltr =3D &lfltr->base; + + hlist_del_rcu(&fltr->hlist); + bnge_del_usr_fltr_node(bn, fltr); + clear_bit(fltr->sw_id, bn->l2_fltr_bmap); + bn->l2_fltr_count--; + kfree_rcu(lfltr, base.rcu); +} + +void bnge_del_l2_filter(struct bnge_net *bn, struct bnge_l2_filter *lfltr) +{ + struct bnge_filter_base *fltr =3D &lfltr->base; + + hlist_del(&fltr->hlist); + bnge_del_usr_fltr_node(bn, fltr); + clear_bit(fltr->sw_id, bn->l2_fltr_bmap); + bn->l2_fltr_count--; + kfree(fltr); +} + +void bnge_del_ntp_filter(struct bnge_net *bn, struct bnge_ntuple_filter *n= fltr) +{ + struct bnge_filter_base *fltr =3D &nfltr->base; + + hlist_del(&fltr->hlist); + bnge_del_usr_fltr_node(bn, fltr); + clear_bit(fltr->sw_id, bn->ntp_fltr_bmap); + bn->ntp_fltr_count--; + kfree(fltr); +} + +void bnge_del_ntp_filter_rcu(struct bnge_net *bn, + struct bnge_ntuple_filter *fltr) +{ + spin_lock_bh(&bn->ntp_fltr_lock); hlist_del_rcu(&fltr->base.hlist); + bnge_del_usr_fltr_node(bn, &fltr->base); + clear_bit(fltr->base.sw_id, bn->ntp_fltr_bmap); + bn->ntp_fltr_count--; + spin_unlock_bh(&bn->ntp_fltr_lock); + kfree_rcu(fltr, base.rcu); } =20 -static void bnge_init_l2_filter(struct bnge_net *bn, - struct bnge_l2_filter *fltr, - struct bnge_l2_key *key, u32 idx) +static int bnge_init_l2_filter(struct bnge_net *bn, + struct bnge_l2_filter *fltr, + struct bnge_l2_key *key, u32 idx) { struct hlist_head *head; + int bit_id; =20 ether_addr_copy(fltr->l2_key.dst_mac_addr, key->dst_mac_addr); fltr->l2_key.vlan =3D key->vlan; fltr->base.type =3D BNGE_FLTR_TYPE_L2; + fltr->base.filter_id =3D BNGE_FLTR_ID_INVALID; + + bit_id =3D bitmap_find_free_region(bn->l2_fltr_bmap, + BNGE_MAX_L2_FLTRS, 0); + if (bit_id < 0) + return -ENOMEM; + fltr->base.sw_id =3D (u16)bit_id; + + bn->l2_fltr_count++; =20 head =3D &bn->l2_fltr_hash_tbl[idx]; hlist_add_head_rcu(&fltr->base.hlist, head); + bnge_insert_usr_fltr(bn, &fltr->base); + return 0; } =20 struct bnge_l2_filter *bnge_lookup_l2_filter(struct bnge_net *bn, @@ -49,12 +177,38 @@ struct bnge_l2_filter *bnge_lookup_l2_filter(struct bn= ge_net *bn, return NULL; } =20 +__le64 bnge_lookup_l2_filter_rcu(struct bnge_net *bn, + struct bnge_l2_key *key, + u32 idx) +{ + __le64 id =3D BNGE_FLTR_ID_INVALID; + struct bnge_l2_filter *fltr; + struct hlist_head *head; + + rcu_read_lock(); + + head =3D &bn->l2_fltr_hash_tbl[idx]; + hlist_for_each_entry_rcu(fltr, head, base.hlist) { + struct bnge_l2_key *l2_key =3D &fltr->l2_key; + + if (ether_addr_equal(l2_key->dst_mac_addr, key->dst_mac_addr) && + l2_key->vlan =3D=3D key->vlan) { + id =3D fltr->base.filter_id; + break; + } + } + + rcu_read_unlock(); + return id; +} + static struct bnge_l2_filter *bnge_alloc_l2_filter(struct bnge_net *bn, struct bnge_l2_key *key, gfp_t gfp) { struct bnge_l2_filter *fltr; u32 idx; + int rc; =20 idx =3D jhash2(&key->filter_key, BNGE_L2_KEY_SIZE, bn->hash_seed) & BNGE_L2_FLTR_HASH_MASK; @@ -67,10 +221,338 @@ static struct bnge_l2_filter *bnge_alloc_l2_filter(st= ruct bnge_net *bn, if (!fltr) return ERR_PTR(-ENOMEM); =20 - bnge_init_l2_filter(bn, fltr, key, idx); + rc =3D bnge_init_l2_filter(bn, fltr, key, idx); + if (rc) { + kfree(fltr); + fltr =3D ERR_PTR(rc); + } + + return fltr; +} + +struct bnge_l2_filter *bnge_alloc_user_l2_filter(struct bnge_net *bn, + struct bnge_l2_key *key, + u8 flags) +{ + struct bnge_l2_filter *fltr; + u32 idx; + int rc; + + idx =3D jhash2(&key->filter_key, BNGE_L2_KEY_SIZE, bn->hash_seed) & + BNGE_L2_FLTR_HASH_MASK; + fltr =3D bnge_lookup_l2_filter(bn, key, idx); + if (fltr) { + fltr =3D ERR_PTR(-EEXIST); + goto l2_filter_exit; + } + fltr =3D kzalloc_obj(*fltr, GFP_ATOMIC); + if (!fltr) { + fltr =3D ERR_PTR(-ENOMEM); + goto l2_filter_exit; + } + fltr->base.flags =3D flags; + rc =3D bnge_init_l2_filter(bn, fltr, key, idx); + if (rc) { + kfree(fltr); + return ERR_PTR(rc); + } + +l2_filter_exit: return fltr; } =20 +void bnge_free_l2_filters(struct bnge_net *bn) +{ + int i; + + netdev_assert_locked_or_invisible(bn->netdev); + + for (i =3D 0; i < BNGE_L2_FLTR_HASH_SIZE; i++) { + struct bnge_l2_filter *fltr; + struct hlist_head *head; + struct hlist_node *tmp; + + head =3D &bn->l2_fltr_hash_tbl[i]; + hlist_for_each_entry_safe(fltr, tmp, head, base.hlist) + bnge_del_l2_filter(bn, fltr); + } + + bitmap_free(bn->l2_fltr_bmap); + bn->l2_fltr_bmap =3D NULL; + bn->l2_fltr_count =3D 0; +} + +void bnge_free_ntp_fltrs(struct bnge_net *bn, bool skip_user) +{ + int i; + + netdev_assert_locked_or_invisible(bn->netdev); + + /* Under netdev instance lock and all our NAPIs have been disabled. + * It's safe to delete the hash table. + */ + for (i =3D 0; i < BNGE_NTP_FLTR_HASH_SIZE; i++) { + struct bnge_ntuple_filter *fltr; + struct hlist_head *head; + struct hlist_node *tmp; + + head =3D &bn->ntp_fltr_hash_tbl[i]; + hlist_for_each_entry_safe(fltr, tmp, head, base.hlist) { + if (skip_user && bnge_is_usr_fltr(&fltr->base)) + continue; + bnge_del_ntp_filter(bn, fltr); + } + } + + if (skip_user) + return; + + bitmap_free(bn->ntp_fltr_bmap); + bn->ntp_fltr_bmap =3D NULL; + bn->ntp_fltr_count =3D 0; +} + +static int bnge_alloc_l2_fltrs_mem(struct bnge_net *bn) +{ + int i, rc =3D 0; + + if (bn->l2_fltr_bmap) + return 0; + + for (i =3D 0; i < BNGE_L2_FLTR_HASH_SIZE; i++) + INIT_HLIST_HEAD(&bn->l2_fltr_hash_tbl[i]); + + bn->l2_fltr_count =3D 0; + bn->l2_fltr_bmap =3D bitmap_zalloc(BNGE_MAX_L2_FLTRS, GFP_KERNEL); + + if (!bn->l2_fltr_bmap) + rc =3D -ENOMEM; + + return rc; +} + +static int bnge_alloc_ntp_fltrs_mem(struct bnge_net *bn) +{ + struct bnge_dev *bd =3D bn->bd; + int i, rc =3D 0; + + if (!(bn->priv_flags & BNGE_NET_EN_NTUPLE) || bn->ntp_fltr_bmap) + return 0; + + for (i =3D 0; i < BNGE_NTP_FLTR_HASH_SIZE; i++) + INIT_HLIST_HEAD(&bn->ntp_fltr_hash_tbl[i]); + + bn->ntp_fltr_count =3D 0; + bn->ntp_fltr_bmap =3D bitmap_zalloc(bd->max_fltr, GFP_KERNEL); + + if (!bn->ntp_fltr_bmap) + rc =3D -ENOMEM; + + return rc; +} + +int bnge_fltrs_mem(struct bnge_net *bn) +{ + bool ntp_alloced =3D !bn->ntp_fltr_bmap; + int rc; + + rc =3D bnge_alloc_ntp_fltrs_mem(bn); + if (rc) + return rc; + + rc =3D bnge_alloc_l2_fltrs_mem(bn); + if (rc) + goto err_free_ntp_mem; + + return 0; + +err_free_ntp_mem: + if (ntp_alloced) { + bitmap_free(bn->ntp_fltr_bmap); + bn->ntp_fltr_bmap =3D NULL; + } + return rc; +} + +#define BNGE_IPV4_4TUPLE(bd, fkeys) \ + (((fkeys)->basic.ip_proto =3D=3D IPPROTO_TCP && \ + (bd)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4) || \ + ((fkeys)->basic.ip_proto =3D=3D IPPROTO_UDP && \ + (bd)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4)) + +#define BNGE_IPV6_4TUPLE(bd, fkeys) \ + (((fkeys)->basic.ip_proto =3D=3D IPPROTO_TCP && \ + (bd)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6) || \ + ((fkeys)->basic.ip_proto =3D=3D IPPROTO_UDP && \ + (bd)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6)) + +static u32 bnge_get_rss_flow_tuple_len(struct bnge_dev *bd, + struct flow_keys *fkeys) +{ + if (fkeys->basic.n_proto =3D=3D htons(ETH_P_IP)) { + if (BNGE_IPV4_4TUPLE(bd, fkeys)) + return sizeof(fkeys->addrs.v4addrs) + + sizeof(fkeys->ports); + + if (bd->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4) + return sizeof(fkeys->addrs.v4addrs); + } + + if (fkeys->basic.n_proto =3D=3D htons(ETH_P_IPV6)) { + if (BNGE_IPV6_4TUPLE(bd, fkeys)) + return sizeof(fkeys->addrs.v6addrs) + + sizeof(fkeys->ports); + + if (bd->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6) + return sizeof(fkeys->addrs.v6addrs); + } + + return 0; +} + +static u32 bnge_toeplitz(struct bnge_net *bn, struct flow_keys *fkeys, + const unsigned char *key) +{ + u64 prefix =3D bn->toeplitz_prefix, hash =3D 0; + struct bnge_ipv4_tuple tuple4; + struct bnge_ipv6_tuple tuple6; + struct bnge_dev *bd =3D bn->bd; + u8 *four_tuple; + int i, j, len; + + len =3D bnge_get_rss_flow_tuple_len(bd, fkeys); + if (!len) + return 0; + + if (fkeys->basic.n_proto =3D=3D htons(ETH_P_IP)) { + tuple4.v4addrs =3D fkeys->addrs.v4addrs; + tuple4.ports =3D fkeys->ports; + four_tuple =3D (u8 *)&tuple4; + } else { + tuple6.v6addrs =3D fkeys->addrs.v6addrs; + tuple6.ports =3D fkeys->ports; + four_tuple =3D (u8 *)&tuple6; + } + + for (i =3D 0, j =3D 8; i < len; i++, j++) { + u8 byte =3D four_tuple[i]; + int bit; + + for (bit =3D 0; bit < 8; bit++, prefix <<=3D 1, byte <<=3D 1) { + if (byte & 0x80) + hash ^=3D prefix; + } + prefix |=3D (j < HW_HASH_KEY_SIZE) ? key[j] : 0; + } + + /* The valid part of the hash is in the upper 32 bits. */ + return (hash >> 32) & BNGE_NTP_FLTR_HASH_MASK; +} + +u32 bnge_get_ntp_filter_idx(struct bnge_net *bn, struct flow_keys *fkeys, + const struct sk_buff *skb) +{ + struct bnge_vnic_info *vnic; + + if (skb) + return skb_get_hash_raw(skb) & BNGE_NTP_FLTR_HASH_MASK; + + vnic =3D &bn->vnic_info[BNGE_VNIC_DEFAULT]; + return bnge_toeplitz(bn, fkeys, (void *)vnic->rss_hash_key); +} + +static bool bnge_fltr_match(struct bnge_ntuple_filter *f1, + struct bnge_ntuple_filter *f2) +{ + struct bnge_flow_masks *masks1 =3D &f1->fmasks; + struct bnge_flow_masks *masks2 =3D &f2->fmasks; + struct flow_keys *keys1 =3D &f1->fkeys; + struct flow_keys *keys2 =3D &f2->fkeys; + + if (keys1->basic.n_proto !=3D keys2->basic.n_proto || + keys1->basic.ip_proto !=3D keys2->basic.ip_proto) + return false; + + if (keys1->basic.n_proto =3D=3D htons(ETH_P_IP)) { + if (keys1->addrs.v4addrs.src !=3D keys2->addrs.v4addrs.src || + masks1->addrs.v4addrs.src !=3D masks2->addrs.v4addrs.src || + keys1->addrs.v4addrs.dst !=3D keys2->addrs.v4addrs.dst || + masks1->addrs.v4addrs.dst !=3D masks2->addrs.v4addrs.dst) + return false; + } else { + if (!ipv6_addr_equal(&keys1->addrs.v6addrs.src, + &keys2->addrs.v6addrs.src) || + !ipv6_addr_equal(&masks1->addrs.v6addrs.src, + &masks2->addrs.v6addrs.src) || + !ipv6_addr_equal(&keys1->addrs.v6addrs.dst, + &keys2->addrs.v6addrs.dst) || + !ipv6_addr_equal(&masks1->addrs.v6addrs.dst, + &masks2->addrs.v6addrs.dst)) + return false; + } + + return keys1->ports.src =3D=3D keys2->ports.src && + masks1->ports.src =3D=3D masks2->ports.src && + keys1->ports.dst =3D=3D keys2->ports.dst && + masks1->ports.dst =3D=3D masks2->ports.dst && + keys1->control.flags =3D=3D keys2->control.flags && + f1->l2_filter_id =3D=3D f2->l2_filter_id; +} + +int bnge_insert_ntp_filter(struct bnge_net *bn, struct bnge_ntuple_filter = *fltr, + u32 idx) +{ + struct bnge_ntuple_filter *f; + struct hlist_head *head; + int bit_id; + + spin_lock_bh(&bn->ntp_fltr_lock); + + head =3D &bn->ntp_fltr_hash_tbl[idx]; + hlist_for_each_entry(f, head, base.hlist) { + if (bnge_fltr_match(f, fltr)) { + spin_unlock_bh(&bn->ntp_fltr_lock); + return -EEXIST; + } + } + + bit_id =3D bitmap_find_free_region(bn->ntp_fltr_bmap, + bn->bd->max_fltr, 0); + if (bit_id < 0) { + spin_unlock_bh(&bn->ntp_fltr_lock); + return -ENOMEM; + } + + fltr->base.sw_id =3D (u16)bit_id; + fltr->base.type =3D BNGE_FLTR_TYPE_NTUPLE; + fltr->base.flags |=3D BNGE_ACT_RING_DST; + + head =3D &bn->ntp_fltr_hash_tbl[idx]; + hlist_add_head_rcu(&fltr->base.hlist, head); + + bnge_insert_usr_fltr(bn, &fltr->base); + bn->ntp_fltr_count++; + + spin_unlock_bh(&bn->ntp_fltr_lock); + + return 0; +} + +struct bnge_ntuple_filter * +bnge_lookup_ntp_filter_from_idx(struct bnge_net *bn, + struct bnge_ntuple_filter *fltr, u32 idx) +{ + struct bnge_ntuple_filter *f; + struct hlist_head *head; + + head =3D &bn->ntp_fltr_hash_tbl[idx]; + hlist_for_each_entry_rcu(f, head, base.hlist) { + if (bnge_fltr_match(f, fltr)) + return f; + } + return NULL; +} + int bnge_hwrm_set_vnic_filter(struct bnge_net *bn, u16 vnic_id, u16 idx, const u8 *mac_addr) { @@ -92,6 +574,6 @@ int bnge_hwrm_set_vnic_filter(struct bnge_net *bn, u16 v= nic_id, u16 idx, return rc; =20 err_del_l2_filter: - bnge_del_l2_filter(bn, fltr); + bnge_del_l2_filter_rcu(bn, fltr); return rc; } diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.h b/drivers/net= /ethernet/broadcom/bnge/bnge_filter.h index 16a5d91517c9..2ffd68ed32b7 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_filter.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.h @@ -4,8 +4,11 @@ #ifndef _BNGE_FILTER_H_ #define _BNGE_FILTER_H_ =20 +#include + enum { - BNGE_FLTR_TYPE_L2 =3D 1 + BNGE_FLTR_TYPE_L2 =3D 1, + BNGE_FLTR_TYPE_NTUPLE =3D 2 }; =20 enum { @@ -13,12 +16,23 @@ enum { BNGE_FLTR_FW_DELETED }; =20 +enum { + BNGE_ACT_DROP =3D 0x1, + BNGE_ACT_RING_DST =3D 0x2, + BNGE_ACT_NO_AGING =3D 0x4, + BNGE_ACT_RSS_CTX =3D 0x8 +}; + +#define BNGE_MAX_L2_FLTRS 128 +#define BNGE_MAX_NTUPLE_FLTRS (8 << 10) + struct bnge_filter_base { struct hlist_node hlist; struct list_head list_node; __le64 filter_id; u8 type; u8 flags; + u16 sw_id; u16 rxq; u16 fw_vnic_id; u16 vf_idx; @@ -44,10 +58,63 @@ struct bnge_l2_filter { struct bnge_l2_key l2_key; }; =20 +struct bnge_ipv4_tuple { + struct flow_dissector_key_ipv4_addrs v4addrs; + struct flow_dissector_key_ports ports; +}; + +struct bnge_ipv6_tuple { + struct flow_dissector_key_ipv6_addrs v6addrs; + struct flow_dissector_key_ports ports; +}; + +struct bnge_flow_masks { + struct flow_dissector_key_ports ports; + struct flow_dissector_key_addrs addrs; +}; + +extern const struct bnge_flow_masks BNGE_FLOW_MASK_NONE; +extern const struct bnge_flow_masks BNGE_FLOW_IPV6_MASK_ALL; +extern const struct bnge_flow_masks BNGE_FLOW_IPV4_MASK_ALL; + +struct bnge_ntuple_filter { + /* base filter must be the first member */ + struct bnge_filter_base base; + struct flow_keys fkeys; + struct bnge_flow_masks fmasks; + __le64 l2_filter_id; + u32 flow_id; +}; + +#define BNGE_L2_FLTR_IS_NTP_MAC(fltr) ((fltr)->base.flags) + +#define BNGE_FLTR_ID_INVALID cpu_to_le64(0xffffffffffffffffULL) + +void bnge_free_ntp_fltrs(struct bnge_net *bn, bool skip_user_filters); +u32 bnge_get_ntp_filter_idx(struct bnge_net *bn, struct flow_keys *fkeys, + const struct sk_buff *skb); +int bnge_insert_ntp_filter(struct bnge_net *bn, struct bnge_ntuple_filter = *fltr, + u32 idx); +struct bnge_ntuple_filter * +bnge_lookup_ntp_filter_from_idx(struct bnge_net *bn, + struct bnge_ntuple_filter *fltr, u32 idx); void bnge_del_l2_filter(struct bnge_net *bn, struct bnge_l2_filter *fltr); +void bnge_del_l2_filter_rcu(struct bnge_net *bn, struct bnge_l2_filter *fl= tr); struct bnge_l2_filter *bnge_lookup_l2_filter(struct bnge_net *bn, struct bnge_l2_key *key, u32 idx); +__le64 bnge_lookup_l2_filter_rcu(struct bnge_net *bn, + struct bnge_l2_key *key, + u32 idx); +void bnge_free_l2_filters(struct bnge_net *bn); int bnge_hwrm_set_vnic_filter(struct bnge_net *bn, u16 vnic_id, u16 idx, const u8 *mac_addr); +struct bnge_l2_filter *bnge_alloc_user_l2_filter(struct bnge_net *bn, + struct bnge_l2_key *key, + u8 flags); +int bnge_fltrs_mem(struct bnge_net *bn); +void bnge_del_ntp_filter(struct bnge_net *bn, + struct bnge_ntuple_filter *nfltr); +void bnge_del_ntp_filter_rcu(struct bnge_net *bn, + struct bnge_ntuple_filter *fltr); #endif /* _BNGE_FILTER_H_ */ diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/n= et/ethernet/broadcom/bnge/bnge_hwrm_lib.c index 86edb70d323e..e611d365db4f 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c @@ -8,6 +8,7 @@ #include #include #include +#include =20 #include "bnge.h" #include "bnge_hwrm.h" @@ -932,11 +933,151 @@ int bnge_hwrm_l2_filter_alloc(struct bnge_dev *bd, s= truct bnge_l2_filter *fltr) req->l2_ivlan_mask =3D cpu_to_le16(0xfff); } =20 + if (BNGE_L2_FLTR_IS_NTP_MAC(fltr)) { + req->enables |=3D cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_ENABLES_RFS_RING_T= BL_IDX); + req->rfs_ring_tbl_idx =3D cpu_to_le16(fltr->base.rxq); + } + resp =3D bnge_hwrm_req_hold(bd, req); rc =3D bnge_hwrm_req_send(bd, req); - if (!rc) + if (!rc) { fltr->base.filter_id =3D resp->l2_filter_id; + set_bit(BNGE_FLTR_VALID, &fltr->base.state); + } + + bnge_hwrm_req_drop(bd, req); + return rc; +} + +int bnge_hwrm_cfa_ntuple_filter_free(struct bnge_dev *bd, + struct bnge_ntuple_filter *fltr) +{ + struct hwrm_cfa_ntuple_filter_free_input *req; + int rc; + + set_bit(BNGE_FLTR_FW_DELETED, &fltr->base.state); + if (!test_bit(BNGE_STATE_OPEN, &bd->state)) + return 0; + + rc =3D bnge_hwrm_req_init(bd, req, HWRM_CFA_NTUPLE_FILTER_FREE); + if (rc) + return rc; + + req->ntuple_filter_id =3D fltr->base.filter_id; + return bnge_hwrm_req_send(bd, req); +} + +#define BNGE_NTP_FLTR_FLAGS \ + (CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_L2_FILTER_ID | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_ETHERTYPE | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_IPADDR_TYPE | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR_MASK | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_IPADDR | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_IPADDR_MASK | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_IP_PROTOCOL | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_PORT | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_PORT_MASK | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_PORT | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_PORT_MASK | \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_ID) + +#define BNGE_NTP_TUNNEL_FLTR_FLAG \ + CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_TUNNEL_TYPE + +static void +bnge_cfg_rfs_ring_tbl_idx(struct bnge_dev *bd, + struct hwrm_cfa_ntuple_filter_alloc_input *req, + struct bnge_ntuple_filter *fltr) +{ + struct bnge_net *bn =3D netdev_priv(bd->netdev); + struct bnge_vnic_info *def_vnic; + u32 rxq =3D fltr->base.rxq; + u32 enables; + + if (fltr->base.flags & BNGE_ACT_RSS_CTX) { + struct ethtool_rxfh_context *ctx; + struct bnge_rss_ctx *rss_ctx; + struct bnge_vnic_info *vnic; + + ctx =3D xa_load(&bd->netdev->ethtool->rss_ctx, + fltr->base.fw_vnic_id); + if (ctx) { + rss_ctx =3D ethtool_rxfh_context_priv(ctx); + vnic =3D &rss_ctx->vnic; + + req->dst_id =3D cpu_to_le16(vnic->fw_vnic_id); + } + return; + } + + def_vnic =3D &bn->vnic_info[BNGE_VNIC_NTUPLE]; + req->dst_id =3D cpu_to_le16(def_vnic->fw_vnic_id); + enables =3D CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_RFS_RING_TBL_IDX; + req->enables |=3D cpu_to_le32(enables); + req->rfs_ring_tbl_idx =3D cpu_to_le16(rxq); +} + +int bnge_hwrm_cfa_ntuple_filter_alloc(struct bnge_dev *bd, + struct bnge_ntuple_filter *fltr) +{ + struct hwrm_cfa_ntuple_filter_alloc_output *resp; + struct hwrm_cfa_ntuple_filter_alloc_input *req; + struct bnge_flow_masks *masks =3D &fltr->fmasks; + struct flow_keys *keys =3D &fltr->fkeys; + int rc; =20 + rc =3D bnge_hwrm_req_init(bd, req, HWRM_CFA_NTUPLE_FILTER_ALLOC); + if (rc) + return rc; + + req->l2_filter_id =3D fltr->l2_filter_id; + + if (fltr->base.flags & BNGE_ACT_DROP) + req->flags =3D + cpu_to_le32(CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DROP); + else + bnge_cfg_rfs_ring_tbl_idx(bd, req, fltr); + + req->enables |=3D cpu_to_le32(BNGE_NTP_FLTR_FLAGS); + + req->ethertype =3D htons(ETH_P_IP); + req->ip_addr_type =3D CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV4; + req->ip_protocol =3D keys->basic.ip_proto; + + if (keys->basic.n_proto =3D=3D htons(ETH_P_IPV6)) { + req->ethertype =3D htons(ETH_P_IPV6); + req->ip_addr_type =3D + CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV6; + memcpy(&req->src_ipaddr, &keys->addrs.v6addrs.src, + sizeof(struct in6_addr)); + memcpy(&req->src_ipaddr_mask, &masks->addrs.v6addrs.src, + sizeof(struct in6_addr)); + memcpy(&req->dst_ipaddr, &keys->addrs.v6addrs.dst, + sizeof(struct in6_addr)); + memcpy(&req->dst_ipaddr_mask, &masks->addrs.v6addrs.dst, + sizeof(struct in6_addr)); + } else { + req->src_ipaddr[0] =3D keys->addrs.v4addrs.src; + req->src_ipaddr_mask[0] =3D masks->addrs.v4addrs.src; + req->dst_ipaddr[0] =3D keys->addrs.v4addrs.dst; + req->dst_ipaddr_mask[0] =3D masks->addrs.v4addrs.dst; + } + if (keys->control.flags & FLOW_DIS_ENCAPSULATION) { + req->enables |=3D cpu_to_le32(BNGE_NTP_TUNNEL_FLTR_FLAG); + req->tunnel_type =3D + CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL; + } + + req->src_port =3D keys->ports.src; + req->src_port_mask =3D masks->ports.src; + req->dst_port =3D keys->ports.dst; + req->dst_port_mask =3D masks->ports.dst; + + resp =3D bnge_hwrm_req_hold(bd, req); + rc =3D bnge_hwrm_req_send(bd, req); + if (!rc) + fltr->base.filter_id =3D resp->ntuple_filter_id; bnge_hwrm_req_drop(bd, req); return rc; } diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h b/drivers/n= et/ethernet/broadcom/bnge/bnge_hwrm_lib.h index 2ae8ec9f33d3..5c5bb864fc4d 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h @@ -13,6 +13,8 @@ struct bnge_l2_filter; #define BNGE_VNIC_CFG_ROCE_DUAL_MODE \ VNIC_CFG_REQ_FLAGS_ROCE_DUAL_VNIC_MODE =20 +struct bnge_ntuple_filter; + int bnge_hwrm_ver_get(struct bnge_dev *bd); int bnge_hwrm_func_reset(struct bnge_dev *bd); int bnge_hwrm_fw_set_time(struct bnge_dev *bd); @@ -68,4 +70,9 @@ int bnge_hwrm_port_qstats(struct bnge_dev *bd, u8 flags); int bnge_hwrm_port_qstats_ext(struct bnge_dev *bd, u8 flags); int bnge_hwrm_func_qstat_ext(struct bnge_dev *bd, struct bnge_stats_mem *s= tats); int bnge_hwrm_cfa_adv_flow_mgnt_qcaps(struct bnge_dev *bd); + +int bnge_hwrm_cfa_ntuple_filter_alloc(struct bnge_dev *bd, + struct bnge_ntuple_filter *fltr); +int bnge_hwrm_cfa_ntuple_filter_free(struct bnge_dev *bd, + struct bnge_ntuple_filter *fltr); #endif /* _BNGE_HWRM_LIB_H_ */ diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.c index 3dcab0370bdf..6d0e6f587396 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -1214,6 +1214,10 @@ static void bnge_free_core(struct bnge_net *bn) bnge_free_ring_stats(bn); bnge_free_ring_grps(bn); bnge_free_vnics(bn); + + /* Free non-user filters only */ + bnge_free_ntp_fltrs(bn, true); + kfree(bn->tx_ring_map); bn->tx_ring_map =3D NULL; kfree(bn->tx_ring); @@ -1302,6 +1306,10 @@ static int bnge_alloc_core(struct bnge_net *bn) =20 bnge_init_stats(bn); =20 + rc =3D bnge_fltrs_mem(bn); + if (rc) + goto err_free_core; + rc =3D bnge_alloc_vnics(bn); if (rc) goto err_free_core; @@ -3428,6 +3436,9 @@ int bnge_netdev_alloc(struct bnge_dev *bd, int max_ir= qs) goto err_free_workq; spin_lock_init(&bn->stats_lock); =20 + spin_lock_init(&bn->ntp_fltr_lock); + INIT_LIST_HEAD(&bn->usr_fltr_list); + netdev->request_ops_lock =3D true; rc =3D register_netdev(netdev); if (rc) { @@ -3455,6 +3466,9 @@ void bnge_netdev_free(struct bnge_dev *bd) =20 unregister_netdev(netdev); =20 + bnge_free_ntp_fltrs(bn, false); + bnge_free_l2_filters(bn); + timer_shutdown_sync(&bn->timer); cancel_work_sync(&bn->sp_task); bn->sp_event =3D 0; diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.h index d68eaa78d4e0..bfd0d9cb871f 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h @@ -284,6 +284,9 @@ enum bnge_sp_event { BNGE_PERIODIC_STATS_SP_EVENT, }; =20 +#define BNGE_NTP_FLTR_HASH_SIZE 512 +#define BNGE_NTP_FLTR_HASH_MASK (BNGE_NTP_FLTR_HASH_SIZE - 1) + struct bnge_net { struct bnge_dev *bd; struct net_device *netdev; @@ -373,6 +376,16 @@ struct bnge_net { bool pri2cos_valid; =20 u16 num_rss_ctx; + + struct list_head usr_fltr_list; + unsigned long *ntp_fltr_bmap; + unsigned long *l2_fltr_bmap; + int ntp_fltr_count; + int l2_fltr_count; + int user_fltr_count; + + struct hlist_head ntp_fltr_hash_tbl[BNGE_NTP_FLTR_HASH_SIZE]; + spinlock_t ntp_fltr_lock; /* for hash table add, del */ }; =20 #define BNGE_DEFAULT_RX_RING_SIZE 511 diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c b/drivers/net/e= thernet/broadcom/bnge/bnge_resc.c index 0a4c4cf5eabf..89c16fdb08a4 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_resc.c @@ -12,6 +12,7 @@ #include "bnge_hwrm_lib.h" #include "bnge_resc.h" #include "bnge_vnic.h" +#include "bnge_filter.h" =20 static u16 bnge_num_tx_to_cp(struct bnge_dev *bd, u16 tx) { @@ -634,7 +635,6 @@ bool bnge_arfs_capable(struct bnge_dev *bd, bool new_rs= s_ctx) =20 int bnge_net_init_dflt_config(struct bnge_dev *bd) { - struct bnge_hw_resc *hw_resc; int rc; =20 rc =3D bnge_alloc_rss_indir_tbl(bd); @@ -648,9 +648,7 @@ int bnge_net_init_dflt_config(struct bnge_dev *bd) if (bnge_arfs_capable(bd, false)) bd->flags |=3D BNGE_EN_ARFS_CAP; =20 - hw_resc =3D &bd->hw_resc; - bd->max_fltr =3D hw_resc->max_rx_em_flows + hw_resc->max_rx_wm_flows + - BNGE_L2_FLTR_MAX_FLTR; + bd->max_fltr =3D BNGE_MAX_NTUPLE_FLTRS; =20 return 0; =20 diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c b/drivers/net/e= thernet/broadcom/bnge/bnge_vnic.c index 3aa89bcd96b9..bbcd5d0126ca 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_vnic.c @@ -171,8 +171,13 @@ void bnge_del_one_rss_ctx(struct bnge_net *bn, struct = bnge_rss_ctx *rss_ctx, bool all) { struct bnge_vnic_info *vnic =3D &rss_ctx->vnic; + struct bnge_filter_base *usr_fltr, *tmp; + struct bnge_ntuple_filter *ntp_fltr; int i; =20 + /* freeing the VNIC first is fine, the other HW resources + * can be freed independently. + */ bnge_hwrm_vnic_free_one(bn->bd, &rss_ctx->vnic); for (i =3D 0; i < BNGE_MAX_CTX_PER_VNIC; i++) { if (vnic->fw_rss_cos_lb_ctx[i] !=3D INVALID_HW_RING_ID) @@ -182,6 +187,18 @@ void bnge_del_one_rss_ctx(struct bnge_net *bn, struct = bnge_rss_ctx *rss_ctx, if (!all) return; =20 + /* Delete all filters associated with this user RSS context */ + list_for_each_entry_safe(usr_fltr, tmp, &bn->usr_fltr_list, list_node) { + if ((usr_fltr->flags & BNGE_ACT_RSS_CTX) && + usr_fltr->fw_vnic_id =3D=3D rss_ctx->index) { + ntp_fltr =3D container_of(usr_fltr, + struct bnge_ntuple_filter, + base); + bnge_hwrm_cfa_ntuple_filter_free(bn->bd, ntp_fltr); + bnge_del_ntp_filter_rcu(bn, ntp_fltr); + } + } + if (vnic->rss_table) dma_free_coherent(bn->bd->dev, vnic->rss_table_size, vnic->rss_table, --=20 2.52.0 From nobody Fri Sep 25 03:16:18 2026 Received: from mail-qt1-f228.google.com (mail-qt1-f228.google.com [209.85.160.228]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4A1F0446BF5 for ; Thu, 17 Sep 2026 06:46:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.228 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627617; cv=none; b=NLlqn6a6k1dBJtcYqZYxCffDay5kuRjEBHdLIXBrL3fAXQEB8k3+QYUAqHFzpXkm8mthriiK1xMjntcIMp/fltFUjq+GE5wOX2ZhfTaOFx+XeoX7+K8dtaV97ObIgnXvuETcfZLiGatHno/ipF9fx4J1HV6bkiUAnbAR7wEOnxY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627617; c=relaxed/simple; bh=P29Lr4K5jCdOFBuPlO41HSH43HB7hqrTHWOmKt3BHsk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FN8W8z0IK3BDEaguw2yBcfcjTrCgZNuVgK8DdK3lZHJL8jQhWCBWOzNUYclMP2zxSklKB/0MyssaIWd4GXr3p5NbbsmaUF7ZsCJhuoW2Hz5Ga+p4v4eq052FK+natISR8bxx/U2mcooPHxnWQCNaq4ldTJYTPHCOkxmpqD0KQvQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=RWaeuEl3; arc=none smtp.client-ip=209.85.160.228 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="RWaeuEl3" Received: by mail-qt1-f228.google.com with SMTP id d75a77b69052e-52fa9c055b5so5407651cf.1 for ; Wed, 16 Sep 2026 23:46:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789627614; x=1790232414; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=0NQ5HIl538K86q7BbSIiSFGsPyHQjoNLSBD1SNwW9A8=; b=LuDebhWWFoyLRM92MIkzSffMa/PfGSiCn9hZr4JFtFwUNc7LK3ReVos29+u20omENG Bwg1xHw/Em/atqvHbBHRhwlto2SPtsL3miISq7Ofya5lYbo8ozxjU7z+xhe7uOrkj8iU DDO4EavCd2LAiyaUMu0EDNkhg84/jK5InN7+ciptbRBjpgP5Z0TWZOWSMGj+nqlVJA9V LibJgsbeC3D93zNNQYJwfRYV8kS6TRWyOqywoGf+Z5wJrmJGABZy1ma1w6u2cxuQFahb JagPLUdNdXU8UKDd3I5Ym0fEjuq6Ho9LTlVEeyyGPrUJjOWR2nETGkKJg8bwvnpgcDxw tidA== X-Forwarded-Encrypted: i=1; AKwUvBwCFUgn+ThF+VLikMG4eH0BTKxd9gDUqwIMn86ILuP39Ikv2oyjBhdiGzGce9oUHjOjdCDvesigUavAtcE=@vger.kernel.org X-Gm-Message-State: AFuF++ncb+azikbyYXn2HRuf2QbfLP7ovnckF+YbzLCdquD+LAa49DIB DXznvIitBEYrNJEeE70YkarRTpe0rQ6Pna1Gcx0h6qz16fv0Yk7UlwSbOQGiJGIY+1Qj7nW4Yly IhMpiohWZu8f9ttwFbq/IhmsvwasDx5JhyC/aY7s4I2udQtwvmLQutTEneLUxEYJuVAdJl7zIvY jZf3F2t3aZTj8raWPwHigwIr5cStQOraymGMZBqFhlDyq+axdsSQt9Y8tsdGwMFSsimGO0j53fp 3EVy1cjVqIit+dYeg== X-Gm-Gg: AYBFou3bqITArT3N5GHJ/JrDbFnxAPC57nVCFHNftmMOJxm+OUE2QpAsVoCfbOcWFlA yNsISa9WJN67GrJh6FhEfo2A0J2Fy9A7Lrv+8NR+5Lcbr7icUSiZzu3NBQ3MfWHxBEVErt+6BIr 1lkrz9255KCExwbSdkAgaYRz2ZjSbEsxt9ABk0HfOqEJwv7L/LBdvQvohuEf7MCvDSzQNHNiA3c en7DhlqQLKQAYfLTSX/qNIqCuPtJ3bd8pF12Ls2JbfflWOQIWpT4F8u8uo5W6600q3P+1ZBOXek s8uG1hiAJ8flkHdi0ZDeU+ClIlrIS2QsicLWrpuAp6ma5esaMmpC/MYn8ohvRB9E49My/7N6UmT JZDBzJaBVB89Ls0D9BGeXbRWNynwVz448UGwWp+nQAsba0OwD8OGU7kQnFfwxYVd95+tereQQt+ ZXz3HxH2SabEbX3lEHkKT3ljfwhgxEsDw70w== X-Received: by 2002:ac8:7f92:0:b0:531:233f:7651 with SMTP id d75a77b69052e-5328d0062ecmr35101771cf.36.1789627614041; Wed, 16 Sep 2026 23:46:54 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-29.dlp.protect.broadcom.com. [144.49.247.29]) by smtp-relay.gmail.com with ESMTPS id d75a77b69052e-532620b5d0dsm591181cf.25.2026.09.16.23.46.53 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2026 23:46:54 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pg1-f198.google.com with SMTP id 41be03b00d2f7-cc1cade6b71so485049a12.0 for ; Wed, 16 Sep 2026 23:46:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1789627613; x=1790232413; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=0NQ5HIl538K86q7BbSIiSFGsPyHQjoNLSBD1SNwW9A8=; b=RWaeuEl3RcUNug+07OVv2DR9t8J1yFko1ZgE5y1EQyHPJx5RAbT5sgD+wxS7gjP3F+ I0tmAhLu39xSlK3EGV9QDd7Y6nG5rS96VmFXcO02GtPsL55Ow6KF9wUgiZQ7Z1sr2rm1 GMTjuBSE+PR2W6839tHTsltM7YyfDxZwlbE34= X-Forwarded-Encrypted: i=1; AKwUvBxdeJNdKySxgNgn6G1E2YKf/BrEQosFilZQik5KoF8YucvFNjz6SRRAUbh7y2kmsifJ6cnCL0hW9qn3reY=@vger.kernel.org X-Received: by 2002:a05:6300:68ce:10b0:3d3:ad6e:9cdd with SMTP id adf61e73a8af0-3dd725e6bf2mr2431117637.11.1789627612437; Wed, 16 Sep 2026 23:46:52 -0700 (PDT) X-Received: by 2002:a05:6300:68ce:10b0:3d3:ad6e:9cdd with SMTP id adf61e73a8af0-3dd725e6bf2mr2431092637.11.1789627611850; Wed, 16 Sep 2026 23:46:51 -0700 (PDT) Received: from H5S1 ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc50ab960edsm2754293a12.20.2026.09.16.23.46.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 23:46:51 -0700 (PDT) From: Vikas Gupta To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com, vsrama-krishna.nemani@broadcom.com, rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com, ajit.khaparde@broadcom.com, Vikas Gupta Subject: [net-next, v3 09/11] bnge: add NTUPLE filter support in ethtool Date: Thu, 17 Sep 2026 12:15:46 +0530 Message-ID: <20260917064548.773334-10-vikas.gupta@broadcom.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260917064548.773334-1-vikas.gupta@broadcom.com> References: <20260917064548.773334-1-vikas.gupta@broadcom.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-DetectorID-Processed: b00c1d49-9d2e-4205-b15f-d015386d3d5e Content-Type: text/plain; charset="utf-8" Introduce ethtool rx flow classification (rxnfc) operations for NTUPLE filter management. Since with ethtool support user filters creation is supported, when interface is down clearing of filters which are in software remains intact. Signed-off-by: Vikas Gupta Reviewed-by: Bhargava Chenna Marreddy Reviewed-by: Dharmender Garg --- .../net/ethernet/broadcom/bnge/bnge_ethtool.c | 591 ++++++++++++++++++ .../net/ethernet/broadcom/bnge/bnge_filter.c | 60 ++ .../net/ethernet/broadcom/bnge/bnge_filter.h | 2 + .../ethernet/broadcom/bnge/bnge_hwrm_lib.c | 8 +- .../net/ethernet/broadcom/bnge/bnge_netdev.c | 4 + 5 files changed, 662 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c b/drivers/ne= t/ethernet/broadcom/bnge/bnge_ethtool.c index d4e2968988e2..7759e99e0ef5 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c @@ -15,6 +15,7 @@ #include "bnge_resc.h" #include "bnge_ethtool.h" #include "bnge_hwrm_lib.h" +#include "bnge_filter.h" =20 static int bnge_nway_reset(struct net_device *dev) { @@ -1164,6 +1165,594 @@ static int bnge_remove_rxfh_context(struct net_devi= ce *dev, return 0; } =20 +#define BNGE_IP_PROTO_FULL_MASK 0xFF +#define BNGE_IP_PROTO_WILDCARD 0x0 + +static u32 bnge_get_all_fltr_ids_rcu(struct bnge_net *bn, + struct hlist_head tbl[], + u32 tbl_size, u32 *ids, u32 start, + u32 id_cnt, u32 offset) +{ + u32 i, j =3D start; + + if (j >=3D id_cnt) + return j; + + for (i =3D 0; i < tbl_size; i++) { + struct bnge_filter_base *fltr; + struct hlist_head *head; + + head =3D &tbl[i]; + hlist_for_each_entry_rcu(fltr, head, hlist) { + if (!fltr->flags || + test_bit(BNGE_FLTR_FW_DELETED, &fltr->state)) + continue; + ids[j++] =3D fltr->sw_id + offset; + if (j =3D=3D id_cnt) + return j; + } + } + return j; +} + +static struct bnge_filter_base *bnge_get_one_fltr_rcu(struct bnge_net *bn, + struct hlist_head tbl[], + u32 tbl_size, u32 id, + u32 offset) +{ + u32 i; + + for (i =3D 0; i < tbl_size; i++) { + struct bnge_filter_base *fltr; + struct hlist_head *head; + + head =3D &tbl[i]; + hlist_for_each_entry_rcu(fltr, head, hlist) { + if (fltr->flags && fltr->sw_id + offset =3D=3D id) + return fltr; + } + } + return NULL; +} + +static int bnge_grxclsrlall(struct bnge_net *bn, struct ethtool_rxnfc *cmd, + u32 *rule_locs) +{ + u32 count; + + cmd->data =3D bn->user_fltr_count; + rcu_read_lock(); + count =3D bnge_get_all_fltr_ids_rcu(bn, bn->l2_fltr_hash_tbl, + BNGE_L2_FLTR_HASH_SIZE, rule_locs, 0, + cmd->rule_cnt, 0); + cmd->rule_cnt =3D bnge_get_all_fltr_ids_rcu(bn, bn->ntp_fltr_hash_tbl, + BNGE_NTP_FLTR_HASH_SIZE, + rule_locs, count, + cmd->rule_cnt, + BNGE_MAX_L2_FLTRS); + rcu_read_unlock(); + + return 0; +} + +static int bnge_grxclsrule(struct bnge_net *bn, struct ethtool_rxnfc *cmd) +{ + struct ethtool_rx_flow_spec *fs =3D + (struct ethtool_rx_flow_spec *)&cmd->fs; + struct bnge_filter_base *fltr_base; + struct bnge_ntuple_filter *fltr; + struct bnge_flow_masks *fmasks; + struct bnge_dev *bd =3D bn->bd; + struct flow_keys *fkeys; + int rc =3D -EINVAL; + + if (fs->location >=3D BNGE_MAX_L2_FLTRS + bd->max_fltr) + return rc; + + rcu_read_lock(); + fltr_base =3D bnge_get_one_fltr_rcu(bn, bn->l2_fltr_hash_tbl, + BNGE_L2_FLTR_HASH_SIZE, + fs->location, 0); + if (fltr_base) { + struct ethhdr *h_ether =3D &fs->h_u.ether_spec; + struct ethhdr *m_ether =3D &fs->m_u.ether_spec; + struct bnge_l2_filter *l2_fltr; + struct bnge_l2_key *l2_key; + + l2_fltr =3D container_of(fltr_base, struct bnge_l2_filter, base); + l2_key =3D &l2_fltr->l2_key; + fs->flow_type =3D ETHER_FLOW; + ether_addr_copy(h_ether->h_dest, l2_key->dst_mac_addr); + eth_broadcast_addr(m_ether->h_dest); + if (l2_key->vlan) { + struct ethtool_flow_ext *m_ext =3D &fs->m_ext; + struct ethtool_flow_ext *h_ext =3D &fs->h_ext; + + fs->flow_type |=3D FLOW_EXT; + m_ext->vlan_tci =3D htons(0xfff); + h_ext->vlan_tci =3D htons(l2_key->vlan); + } + if (fltr_base->flags & BNGE_ACT_RING_DST) + fs->ring_cookie =3D fltr_base->rxq; + rcu_read_unlock(); + return 0; + } + fltr_base =3D bnge_get_one_fltr_rcu(bn, bn->ntp_fltr_hash_tbl, + BNGE_NTP_FLTR_HASH_SIZE, + fs->location, BNGE_MAX_L2_FLTRS); + if (!fltr_base) { + rcu_read_unlock(); + return rc; + } + fltr =3D container_of(fltr_base, struct bnge_ntuple_filter, base); + + fkeys =3D &fltr->fkeys; + fmasks =3D &fltr->fmasks; + if (fkeys->basic.n_proto =3D=3D htons(ETH_P_IP)) { + if (fkeys->basic.ip_proto =3D=3D BNGE_IP_PROTO_WILDCARD) { + fs->flow_type =3D IP_USER_FLOW; + fs->h_u.usr_ip4_spec.ip_ver =3D ETH_RX_NFC_IP4; + fs->h_u.usr_ip4_spec.proto =3D BNGE_IP_PROTO_WILDCARD; + fs->m_u.usr_ip4_spec.proto =3D 0; + } else if (fkeys->basic.ip_proto =3D=3D IPPROTO_ICMP) { + fs->flow_type =3D IP_USER_FLOW; + fs->h_u.usr_ip4_spec.ip_ver =3D ETH_RX_NFC_IP4; + fs->h_u.usr_ip4_spec.proto =3D IPPROTO_ICMP; + fs->m_u.usr_ip4_spec.proto =3D BNGE_IP_PROTO_FULL_MASK; + } else if (fkeys->basic.ip_proto =3D=3D IPPROTO_TCP) { + fs->flow_type =3D TCP_V4_FLOW; + } else if (fkeys->basic.ip_proto =3D=3D IPPROTO_UDP) { + fs->flow_type =3D UDP_V4_FLOW; + } else { + goto fltr_err; + } + + fs->h_u.tcp_ip4_spec.ip4src =3D fkeys->addrs.v4addrs.src; + fs->m_u.tcp_ip4_spec.ip4src =3D fmasks->addrs.v4addrs.src; + fs->h_u.tcp_ip4_spec.ip4dst =3D fkeys->addrs.v4addrs.dst; + fs->m_u.tcp_ip4_spec.ip4dst =3D fmasks->addrs.v4addrs.dst; + if (fs->flow_type =3D=3D TCP_V4_FLOW || + fs->flow_type =3D=3D UDP_V4_FLOW) { + fs->h_u.tcp_ip4_spec.psrc =3D fkeys->ports.src; + fs->m_u.tcp_ip4_spec.psrc =3D fmasks->ports.src; + fs->h_u.tcp_ip4_spec.pdst =3D fkeys->ports.dst; + fs->m_u.tcp_ip4_spec.pdst =3D fmasks->ports.dst; + } + } else { + if (fkeys->basic.ip_proto =3D=3D BNGE_IP_PROTO_WILDCARD) { + fs->flow_type =3D IPV6_USER_FLOW; + fs->h_u.usr_ip6_spec.l4_proto =3D + BNGE_IP_PROTO_WILDCARD; + fs->m_u.usr_ip6_spec.l4_proto =3D 0; + } else if (fkeys->basic.ip_proto =3D=3D IPPROTO_ICMPV6) { + fs->flow_type =3D IPV6_USER_FLOW; + fs->h_u.usr_ip6_spec.l4_proto =3D IPPROTO_ICMPV6; + fs->m_u.usr_ip6_spec.l4_proto =3D + BNGE_IP_PROTO_FULL_MASK; + } else if (fkeys->basic.ip_proto =3D=3D IPPROTO_TCP) { + fs->flow_type =3D TCP_V6_FLOW; + } else if (fkeys->basic.ip_proto =3D=3D IPPROTO_UDP) { + fs->flow_type =3D UDP_V6_FLOW; + } else { + goto fltr_err; + } + + memcpy(fs->h_u.tcp_ip6_spec.ip6src, + &fkeys->addrs.v6addrs.src, + sizeof(struct in6_addr)); + memcpy(fs->m_u.tcp_ip6_spec.ip6src, + &fmasks->addrs.v6addrs.src, + sizeof(struct in6_addr)); + memcpy(fs->h_u.tcp_ip6_spec.ip6dst, + &fkeys->addrs.v6addrs.dst, + sizeof(struct in6_addr)); + memcpy(fs->m_u.tcp_ip6_spec.ip6dst, + &fmasks->addrs.v6addrs.dst, + sizeof(struct in6_addr)); + + if (fs->flow_type =3D=3D TCP_V6_FLOW || + fs->flow_type =3D=3D UDP_V6_FLOW) { + fs->h_u.tcp_ip6_spec.psrc =3D fkeys->ports.src; + fs->m_u.tcp_ip6_spec.psrc =3D fmasks->ports.src; + fs->h_u.tcp_ip6_spec.pdst =3D fkeys->ports.dst; + fs->m_u.tcp_ip6_spec.pdst =3D fmasks->ports.dst; + } + } + + if (fltr->base.flags & BNGE_ACT_DROP) { + fs->ring_cookie =3D RX_CLS_FLOW_DISC; + } else if (fltr->base.flags & BNGE_ACT_RSS_CTX) { + fs->flow_type |=3D FLOW_RSS; + cmd->rss_context =3D fltr->base.fw_vnic_id; + } else { + fs->ring_cookie =3D fltr->base.rxq; + } + rc =3D 0; + +fltr_err: + rcu_read_unlock(); + + return rc; +} + +static bool bnge_verify_ntuple_ip4_flow(struct ethtool_usrip4_spec *ip_spe= c, + struct ethtool_usrip4_spec *ip_mask) +{ + u8 mproto =3D ip_mask->proto; + u8 sproto =3D ip_spec->proto; + + if (ip_mask->l4_4_bytes || ip_mask->tos || + ip_spec->ip_ver !=3D ETH_RX_NFC_IP4 || + (mproto && (mproto !=3D BNGE_IP_PROTO_FULL_MASK || + sproto !=3D IPPROTO_ICMP))) + return false; + return true; +} + +static bool bnge_verify_ntuple_ip6_flow(struct ethtool_usrip6_spec *ip_spe= c, + struct ethtool_usrip6_spec *ip_mask) +{ + u8 mproto =3D ip_mask->l4_proto; + u8 sproto =3D ip_spec->l4_proto; + + if (ip_mask->l4_4_bytes || ip_mask->tclass || + (mproto && (mproto !=3D BNGE_IP_PROTO_FULL_MASK || + sproto !=3D IPPROTO_ICMPV6))) + return false; + return true; +} + +static int bnge_add_ntuple_cls_rule(struct bnge_net *bn, + struct ethtool_rxnfc *cmd) +{ + struct ethtool_rx_flow_spec *fs =3D &cmd->fs; + struct bnge_ntuple_filter *new_fltr, *fltr; + u32 flow_type =3D fs->flow_type & 0xff; + struct bnge_l2_filter *l2_fltr; + struct bnge_flow_masks *fmasks; + struct flow_keys *fkeys; + u32 idx; + int rc; + + if (!bn->vnic_info) + return -EAGAIN; + + if (fs->flow_type & (FLOW_MAC_EXT | FLOW_EXT)) + return -EOPNOTSUPP; + + if (fs->ring_cookie !=3D RX_CLS_FLOW_DISC && + ethtool_get_flow_spec_ring_vf(fs->ring_cookie)) + return -EOPNOTSUPP; + + if (flow_type =3D=3D IP_USER_FLOW) { + if (!bnge_verify_ntuple_ip4_flow(&fs->h_u.usr_ip4_spec, + &fs->m_u.usr_ip4_spec)) + return -EOPNOTSUPP; + } + + if (flow_type =3D=3D IPV6_USER_FLOW) { + if (!bnge_verify_ntuple_ip6_flow(&fs->h_u.usr_ip6_spec, + &fs->m_u.usr_ip6_spec)) + return -EOPNOTSUPP; + } + + new_fltr =3D kzalloc_obj(*new_fltr, GFP_KERNEL); + if (!new_fltr) + return -ENOMEM; + + l2_fltr =3D bn->vnic_info[BNGE_VNIC_DEFAULT].l2_filters[0]; + new_fltr->l2_filter_id =3D l2_fltr->base.filter_id; + fmasks =3D &new_fltr->fmasks; + fkeys =3D &new_fltr->fkeys; + + rc =3D -EOPNOTSUPP; + switch (flow_type) { + case IP_USER_FLOW: { + struct ethtool_usrip4_spec *ip_spec =3D &fs->h_u.usr_ip4_spec; + struct ethtool_usrip4_spec *ip_mask =3D &fs->m_u.usr_ip4_spec; + + fkeys->basic.ip_proto =3D ip_mask->proto ? ip_spec->proto + : BNGE_IP_PROTO_WILDCARD; + fkeys->basic.n_proto =3D htons(ETH_P_IP); + fkeys->addrs.v4addrs.src =3D ip_spec->ip4src; + fmasks->addrs.v4addrs.src =3D ip_mask->ip4src; + fkeys->addrs.v4addrs.dst =3D ip_spec->ip4dst; + fmasks->addrs.v4addrs.dst =3D ip_mask->ip4dst; + break; + } + case TCP_V4_FLOW: + case UDP_V4_FLOW: { + struct ethtool_tcpip4_spec *ip_spec =3D &fs->h_u.tcp_ip4_spec; + struct ethtool_tcpip4_spec *ip_mask =3D &fs->m_u.tcp_ip4_spec; + + if (ip_mask->tos) + goto err_free_fltr; + + fkeys->basic.ip_proto =3D IPPROTO_TCP; + if (flow_type =3D=3D UDP_V4_FLOW) + fkeys->basic.ip_proto =3D IPPROTO_UDP; + fkeys->basic.n_proto =3D htons(ETH_P_IP); + fkeys->addrs.v4addrs.src =3D ip_spec->ip4src; + fmasks->addrs.v4addrs.src =3D ip_mask->ip4src; + fkeys->addrs.v4addrs.dst =3D ip_spec->ip4dst; + fmasks->addrs.v4addrs.dst =3D ip_mask->ip4dst; + fkeys->ports.src =3D ip_spec->psrc; + fmasks->ports.src =3D ip_mask->psrc; + fkeys->ports.dst =3D ip_spec->pdst; + fmasks->ports.dst =3D ip_mask->pdst; + break; + } + case IPV6_USER_FLOW: { + struct ethtool_usrip6_spec *ip_spec =3D &fs->h_u.usr_ip6_spec; + struct ethtool_usrip6_spec *ip_mask =3D &fs->m_u.usr_ip6_spec; + + fkeys->basic.ip_proto =3D ip_mask->l4_proto ? ip_spec->l4_proto + : BNGE_IP_PROTO_WILDCARD; + fkeys->basic.n_proto =3D htons(ETH_P_IPV6); + + memcpy(&fkeys->addrs.v6addrs.src, ip_spec->ip6src, + sizeof(struct in6_addr)); + memcpy(&fmasks->addrs.v6addrs.src, ip_mask->ip6src, + sizeof(struct in6_addr)); + memcpy(&fkeys->addrs.v6addrs.dst, ip_spec->ip6dst, + sizeof(struct in6_addr)); + memcpy(&fmasks->addrs.v6addrs.dst, ip_mask->ip6dst, + sizeof(struct in6_addr)); + break; + } + case TCP_V6_FLOW: + case UDP_V6_FLOW: { + struct ethtool_tcpip6_spec *ip_spec =3D &fs->h_u.tcp_ip6_spec; + struct ethtool_tcpip6_spec *ip_mask =3D &fs->m_u.tcp_ip6_spec; + + if (ip_mask->tclass) + goto err_free_fltr; + + fkeys->basic.ip_proto =3D IPPROTO_TCP; + if (flow_type =3D=3D UDP_V6_FLOW) + fkeys->basic.ip_proto =3D IPPROTO_UDP; + fkeys->basic.n_proto =3D htons(ETH_P_IPV6); + + memcpy(&fkeys->addrs.v6addrs.src, ip_spec->ip6src, + sizeof(struct in6_addr)); + memcpy(&fmasks->addrs.v6addrs.src, ip_mask->ip6src, + sizeof(struct in6_addr)); + memcpy(&fkeys->addrs.v6addrs.dst, ip_spec->ip6dst, + sizeof(struct in6_addr)); + memcpy(&fmasks->addrs.v6addrs.dst, ip_mask->ip6dst, + sizeof(struct in6_addr)); + + fkeys->ports.src =3D ip_spec->psrc; + fmasks->ports.src =3D ip_mask->psrc; + fkeys->ports.dst =3D ip_spec->pdst; + fmasks->ports.dst =3D ip_mask->pdst; + break; + } + default: + rc =3D -EOPNOTSUPP; + goto err_free_fltr; + } + if (!memcmp(&BNGE_FLOW_MASK_NONE, fmasks, sizeof(*fmasks))) + goto err_free_fltr; + + idx =3D bnge_get_ntp_filter_idx(bn, fkeys, NULL); + rcu_read_lock(); + fltr =3D bnge_lookup_ntp_filter_from_idx(bn, new_fltr, idx); + if (fltr) { + rcu_read_unlock(); + rc =3D -EEXIST; + goto err_free_fltr; + } + rcu_read_unlock(); + + new_fltr->base.flags =3D BNGE_ACT_NO_AGING; + if (fs->flow_type & FLOW_RSS) { + struct bnge_rss_ctx *rss_ctx; + + new_fltr->base.fw_vnic_id =3D 0; + new_fltr->base.flags |=3D BNGE_ACT_RSS_CTX; + rss_ctx =3D bnge_get_rss_ctx_from_index(bn, cmd->rss_context); + if (rss_ctx) { + new_fltr->base.fw_vnic_id =3D rss_ctx->index; + } else { + rc =3D -EINVAL; + goto err_free_fltr; + } + } + if (fs->ring_cookie =3D=3D RX_CLS_FLOW_DISC) + new_fltr->base.flags |=3D BNGE_ACT_DROP; + else + new_fltr->base.rxq =3D ethtool_get_flow_spec_ring(fs->ring_cookie); + __set_bit(BNGE_FLTR_VALID, &new_fltr->base.state); + rc =3D bnge_insert_ntp_filter(bn, new_fltr, idx); + if (!rc) { + rc =3D bnge_hwrm_cfa_ntuple_filter_alloc(bn->bd, new_fltr); + if (rc) { + bnge_del_ntp_filter_rcu(bn, new_fltr); + return rc; + } + fs->location =3D BNGE_MAX_L2_FLTRS + new_fltr->base.sw_id; + return 0; + } + +err_free_fltr: + kfree(new_fltr); + return rc; +} + +static int bnge_add_l2_cls_rule(struct bnge_net *bn, + struct ethtool_rx_flow_spec *fs) +{ + u32 ring =3D ethtool_get_flow_spec_ring(fs->ring_cookie); + struct ethhdr *h_ether =3D &fs->h_u.ether_spec; + struct ethhdr *m_ether =3D &fs->m_u.ether_spec; + struct bnge_l2_filter *fltr; + struct bnge_l2_key key; + u16 vnic_id; + u8 flags; + int rc; + + if (ethtool_get_flow_spec_ring_vf(fs->ring_cookie)) + return -EOPNOTSUPP; + + if (!is_broadcast_ether_addr(m_ether->h_dest)) + return -EINVAL; + + if (is_broadcast_ether_addr(h_ether->h_dest) || + is_multicast_ether_addr(h_ether->h_dest)) + return -EINVAL; + + ether_addr_copy(key.dst_mac_addr, h_ether->h_dest); + key.vlan =3D 0; + if (fs->flow_type & FLOW_EXT) { + struct ethtool_flow_ext *m_ext =3D &fs->m_ext; + struct ethtool_flow_ext *h_ext =3D &fs->h_ext; + + if (m_ext->vlan_tci !=3D htons(0xfff) || !h_ext->vlan_tci) + return -EINVAL; + key.vlan =3D ntohs(h_ext->vlan_tci); + } + + flags =3D BNGE_ACT_RING_DST; + vnic_id =3D bn->vnic_info[BNGE_VNIC_DEFAULT].fw_vnic_id; + + fltr =3D bnge_alloc_user_l2_filter(bn, &key, flags); + if (IS_ERR(fltr)) + return PTR_ERR(fltr); + + fltr->base.fw_vnic_id =3D vnic_id; + fltr->base.rxq =3D ring; + rc =3D bnge_hwrm_l2_filter_alloc(bn->bd, fltr); + if (rc) + bnge_del_l2_filter_rcu(bn, fltr); + else + fs->location =3D fltr->base.sw_id; + return rc; +} + +static int bnge_srxclsrlins(struct bnge_net *bn, struct ethtool_rxnfc *cmd) +{ + struct ethtool_rx_flow_spec *fs =3D &cmd->fs; + struct bnge_dev *bd =3D bn->bd; + u32 ring, flow_type; + int rc; + + if (!netif_running(bn->netdev)) + return -EAGAIN; + if (!(bn->priv_flags & BNGE_NET_EN_NTUPLE)) + return -EPERM; + if (fs->location !=3D RX_CLS_LOC_ANY) + return -EINVAL; + + flow_type =3D fs->flow_type; + + if (flow_type & FLOW_MAC_EXT) + return -EINVAL; + + flow_type &=3D ~FLOW_EXT; + + if (fs->ring_cookie =3D=3D RX_CLS_FLOW_DISC && flow_type !=3D ETHER_FLOW) + return bnge_add_ntuple_cls_rule(bn, cmd); + + ring =3D ethtool_get_flow_spec_ring(fs->ring_cookie); + if (ring >=3D bd->rx_nr_rings) + return -EINVAL; + + if (flow_type =3D=3D ETHER_FLOW) + rc =3D bnge_add_l2_cls_rule(bn, fs); + else + rc =3D bnge_add_ntuple_cls_rule(bn, cmd); + return rc; +} + +static int bnge_srxclsrldel(struct bnge_net *bn, struct ethtool_rxnfc *cmd) +{ + struct ethtool_rx_flow_spec *fs =3D &cmd->fs; + struct bnge_filter_base *fltr_base; + struct bnge_ntuple_filter *fltr; + u32 id =3D fs->location; + + rcu_read_lock(); + fltr_base =3D bnge_get_one_fltr_rcu(bn, bn->l2_fltr_hash_tbl, + BNGE_L2_FLTR_HASH_SIZE, id, 0); + if (fltr_base) { + struct bnge_l2_filter *l2_fltr; + + l2_fltr =3D container_of(fltr_base, struct bnge_l2_filter, base); + rcu_read_unlock(); + bnge_hwrm_l2_filter_free(bn->bd, l2_fltr); + bnge_del_l2_filter_rcu(bn, l2_fltr); + return 0; + } + fltr_base =3D bnge_get_one_fltr_rcu(bn, bn->ntp_fltr_hash_tbl, + BNGE_NTP_FLTR_HASH_SIZE, id, + BNGE_MAX_L2_FLTRS); + if (!fltr_base) { + rcu_read_unlock(); + return -ENOENT; + } + + fltr =3D container_of(fltr_base, struct bnge_ntuple_filter, base); + if (!(fltr->base.flags & BNGE_ACT_NO_AGING)) { + rcu_read_unlock(); + return -EINVAL; + } + rcu_read_unlock(); + bnge_hwrm_cfa_ntuple_filter_free(bn->bd, fltr); + bnge_del_ntp_filter_rcu(bn, fltr); + return 0; +} + +static int bnge_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cm= d, + u32 *rule_locs) +{ + struct bnge_net *bn =3D netdev_priv(dev); + struct bnge_dev *bd =3D bn->bd; + int rc =3D 0; + + switch (cmd->cmd) { + case ETHTOOL_GRXCLSRLCNT: + cmd->rule_cnt =3D bn->user_fltr_count; + cmd->data =3D bd->max_fltr | RX_CLS_LOC_SPECIAL; + break; + + case ETHTOOL_GRXCLSRLALL: + rc =3D bnge_grxclsrlall(bn, cmd, (u32 *)rule_locs); + break; + + case ETHTOOL_GRXCLSRULE: + rc =3D bnge_grxclsrule(bn, cmd); + break; + + default: + rc =3D -EOPNOTSUPP; + break; + } + + return rc; +} + +static int bnge_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cm= d) +{ + struct bnge_net *bn =3D netdev_priv(dev); + int rc; + + switch (cmd->cmd) { + case ETHTOOL_SRXCLSRLINS: + rc =3D bnge_srxclsrlins(bn, cmd); + break; + + case ETHTOOL_SRXCLSRLDEL: + rc =3D bnge_srxclsrldel(bn, cmd); + break; + + default: + rc =3D -EOPNOTSUPP; + break; + } + return rc; +} + static const struct ethtool_ops bnge_ethtool_ops =3D { .cap_link_lanes_supported =3D 1, .get_link_ksettings =3D bnge_get_link_ksettings, @@ -1196,6 +1785,8 @@ static const struct ethtool_ops bnge_ethtool_ops =3D { .create_rxfh_context =3D bnge_create_rxfh_context, .modify_rxfh_context =3D bnge_modify_rxfh_context, .remove_rxfh_context =3D bnge_remove_rxfh_context, + .get_rxnfc =3D bnge_get_rxnfc, + .set_rxnfc =3D bnge_set_rxnfc, }; =20 void bnge_set_ethtool_ops(struct net_device *dev) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.c b/drivers/net= /ethernet/broadcom/bnge/bnge_filter.c index 698bd3967c27..8d905252fe5e 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_filter.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.c @@ -577,3 +577,63 @@ int bnge_hwrm_set_vnic_filter(struct bnge_net *bn, u16= vnic_id, u16 idx, bnge_del_l2_filter_rcu(bn, fltr); return rc; } + +static void bnge_cfg_one_usr_fltr(struct bnge_net *bn, + struct bnge_filter_base *fltr) +{ + struct bnge_ntuple_filter *ntp_fltr; + struct bnge_l2_filter *l2_fltr; + + if (list_empty(&fltr->list_node)) + return; + + if (fltr->type =3D=3D BNGE_FLTR_TYPE_NTUPLE) { + ntp_fltr =3D container_of(fltr, struct bnge_ntuple_filter, base); + l2_fltr =3D bn->vnic_info[BNGE_VNIC_DEFAULT].l2_filters[0]; + ntp_fltr->l2_filter_id =3D l2_fltr->base.filter_id; + if (bnge_hwrm_cfa_ntuple_filter_alloc(bn->bd, ntp_fltr)) { + netdev_err(bn->netdev, + "restoring previously configured ntuple filter id %d failed\n", + fltr->sw_id); + bnge_del_ntp_filter_rcu(bn, ntp_fltr); + } + } else if (fltr->type =3D=3D BNGE_FLTR_TYPE_L2) { + l2_fltr =3D container_of(fltr, struct bnge_l2_filter, base); + if (bnge_hwrm_l2_filter_alloc(bn->bd, l2_fltr)) { + netdev_err(bn->netdev, + "restoring previously configured l2 filter id %d failed\n", + fltr->sw_id); + bnge_del_l2_filter_rcu(bn, l2_fltr); + } + } +} + +void bnge_cfg_usr_fltrs(struct bnge_net *bn) +{ + struct bnge_filter_base *usr_fltr, *tmp; + + list_for_each_entry_safe(usr_fltr, tmp, &bn->usr_fltr_list, list_node) + bnge_cfg_one_usr_fltr(bn, usr_fltr); +} + +void bnge_clear_usr_fltrs(struct bnge_net *bn) +{ + struct bnge_filter_base *usr_fltr, *tmp; + struct bnge_ntuple_filter *ntp_fltr; + struct bnge_l2_filter *l2_fltr; + + netdev_assert_locked(bn->netdev); + + list_for_each_entry_safe(usr_fltr, tmp, &bn->usr_fltr_list, list_node) { + if (usr_fltr->type =3D=3D BNGE_FLTR_TYPE_NTUPLE) { + ntp_fltr =3D container_of(usr_fltr, + struct bnge_ntuple_filter, + base); + bnge_del_ntp_filter(bn, ntp_fltr); + } else if (usr_fltr->type =3D=3D BNGE_FLTR_TYPE_L2) { + l2_fltr =3D container_of(usr_fltr, struct bnge_l2_filter, + base); + bnge_del_l2_filter(bn, l2_fltr); + } + } +} diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.h b/drivers/net= /ethernet/broadcom/bnge/bnge_filter.h index 2ffd68ed32b7..f1f43537ab97 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_filter.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.h @@ -117,4 +117,6 @@ void bnge_del_ntp_filter(struct bnge_net *bn, struct bnge_ntuple_filter *nfltr); void bnge_del_ntp_filter_rcu(struct bnge_net *bn, struct bnge_ntuple_filter *fltr); +void bnge_cfg_usr_fltrs(struct bnge_net *bn); +void bnge_clear_usr_fltrs(struct bnge_net *bn); #endif /* _BNGE_FILTER_H_ */ diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/n= et/ethernet/broadcom/bnge/bnge_hwrm_lib.c index e611d365db4f..79ae4bd86647 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c @@ -906,15 +906,17 @@ int bnge_hwrm_l2_filter_alloc(struct bnge_dev *bd, st= ruct bnge_l2_filter *fltr) { struct hwrm_cfa_l2_filter_alloc_output *resp; struct hwrm_cfa_l2_filter_alloc_input *req; + u32 flags; int rc; =20 rc =3D bnge_hwrm_req_init(bd, req, HWRM_CFA_L2_FILTER_ALLOC); if (rc) return rc; =20 - req->flags =3D cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_PATH_RX); - - req->flags |=3D cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_OUTERMOST); + flags =3D CFA_L2_FILTER_ALLOC_REQ_FLAGS_PATH_RX | + CFA_L2_FILTER_ALLOC_REQ_FLAGS_TRAFFIC_L2 | + CFA_L2_FILTER_ALLOC_REQ_FLAGS_OUTERMOST; + req->flags =3D cpu_to_le32(flags); req->dst_id =3D cpu_to_le16(fltr->base.fw_vnic_id); req->enables =3D cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR | diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.c index 6d0e6f587396..091de9624db4 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -2803,6 +2803,7 @@ int bnge_open_core(struct bnge_net *bn) bnge_get_port_module_status(bn); =20 bnge_hwrm_realloc_rss_ctx_vnic(bn); + bnge_cfg_usr_fltrs(bn); =20 return 0; =20 @@ -3166,6 +3167,9 @@ static int bnge_set_features(struct net_device *dev, = netdev_features_t features) !(flags & BNGE_NET_EN_NTUPLE) && bn->num_rss_ctx) return -EBUSY; =20 + if (!(flags & BNGE_NET_EN_NTUPLE)) + bnge_clear_usr_fltrs(bn); + bn->priv_flags =3D flags; =20 return 0; --=20 2.52.0 From nobody Fri Sep 25 03:16:18 2026 Received: from mail-pl1-f227.google.com (mail-pl1-f227.google.com [209.85.214.227]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5DC6D448CE0 for ; Thu, 17 Sep 2026 06:47:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.227 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627623; cv=none; b=jYriYgHFj1IWI8SwpJ6aJfygxSonf6ZPuKIAKDg/sLBtl+Xh+36itq6DBjXBiywqmCyXa696ZVJtoCgh581cpLLaFZZVNyoCqc8/qb+FV6SUC5Mph57WiV8Tk6/9X0Ka/qDswDp1blSjm/MYYduLihkxW3rVj2kEBeCW7gx964Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627623; c=relaxed/simple; bh=xWKtKjAimhawaEJZEncG7oDfMZ8jrMbCnP5wiXIdfnY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=emk1qdCP31v0V1IrzPjn0FxWg1J28vk86qlxFuXIc0y3PNeHitA+yUJzfrkoJeFzxM9VDltTp60eR7sjBtG/nNlSYacpPF/nR5oYCP+AIcXmyJJzYkrjBwU9EA7PVYxVulqTskuIjAuxqJhV+2icqma2IDHSB5xuBg/gaJwKNbE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=T85Pjcbk; arc=none smtp.client-ip=209.85.214.227 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="T85Pjcbk" Received: by mail-pl1-f227.google.com with SMTP id d9443c01a7336-2d560775ca2so1519715ad.1 for ; Wed, 16 Sep 2026 23:47:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789627620; x=1790232420; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=WnFkKlS5WARQKCpGuZojTqxptSVM2xGpYdtnYIiPoQU=; b=gEqfFuLkYMYJcDtxBDIrAaIfQtoSt9WYEboGT9xgfeVp6x7YSzejHRQZMTGaF2830E pdDRzxXK5k8JitxIcKevNYyIVnWGeTs/rrAnfCD/z9RWSUFl9V3BIi6ELJh+fZ+BYluW /tInwdgqC9Dic75WZoEsAIPVYoBNzvSrn0mocQ9w6LKgfLFLQLIr5AQGaUarxwMSdYHC MUqJKPtmMh/Wv3EKgJdL5WTVQeSPe2VuWCA3JpUDsTub2CObxfk1BVHVo8fE29a7z5YJ +wl2shjFk/0Ezk8Rr2sKT4UXYNU6tDQ+NxyyT6JngckF3KCZPMxdPDruaB+d4KN6MejQ cBEQ== X-Forwarded-Encrypted: i=1; AKwUvBx8khUQvtpQSxQuEXjoCl6xHgPxyNnNFxhA0VxZv1t59UcM5DeMPkaZhvBEJ17F8kl0N0NFmqEiF8xerRA=@vger.kernel.org X-Gm-Message-State: AFuF++lOawBPHWTWPqNgrzqLCX1iKF8AnlIrWKZbOiSoRHAChl5RZx7F RcLjUJc07DNUWZZFB36+8UNuJJBTCLTvCUSBJlAdX2ljyTzUXUkspyhB3et4ba12qalJhEhLjk+ lC8TrFE9R/glUuXWXVeqsUa8+zehBNXfaL8tGcBK0TK4lK1pBfxtqCl/9A5oG1D62AwJiV56k/q nQOeIK9TYyzYtMGzW+x+PcnX8H1IB52ir161bhgSzpYDmmvEY5U/eX4zknmer5OWlpYHQhjM+MZ NOb8qsEZ9hGUcmQtA== X-Gm-Gg: AYBFou0ARPgOQWRKDO2TbkAWOl0QeLzgcx2kRXzzwkKc2zDf0yTn7u4rxqQ5GLAFl9p b87+SZp/A3pHEcJtoYrD6PjOGQZkZv78EKrCMoFCmA/rLfHm0bKUx9ZEPnm0pv4sdQsN0UopSSI B0Ylk4NxCL5oA2aW8LfoG914/D9VS9wqiY5U20QKW9RT5KzglTp8vp5ICqPx/YhT+Z9/xc4yiyX 0l6A76jsD4UnmJ90C0OIXJE6bllq3p0uVJL9/qKw6V4IuY9jrrMSZkGXPZICjuDm83eAVzYIDuM s8DQNB+MrWguftj7pWqOwjMXAox3gpghWyl3bJmEvYQiHcFHcI2oJHf8AtK8KCtc/+6ulqcGKXF BSUC6UX7AQ7gJkVM7NMdNDQjwAIix5/4hMGR6LJxVrJRMEdBKu8XNaqi3iOi+wS/lBFRYmxL+e9 TBFwegGCnJbJsvNuAYMK2b5eGjLQ6uMWBqAszu X-Received: by 2002:a05:6a20:d70f:b0:3db:2c66:6638 with SMTP id adf61e73a8af0-3dd5f471e3emr15171146637.10.1789627620549; Wed, 16 Sep 2026 23:47:00 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-125.dlp.protect.broadcom.com. [144.49.247.125]) by smtp-relay.gmail.com with ESMTPS id a92af1059eb24-14395d60fc4sm203051c88.6.2026.09.16.23.47.00 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2026 23:47:00 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pg1-f199.google.com with SMTP id 41be03b00d2f7-cc1b6f65dacso490689a12.1 for ; Wed, 16 Sep 2026 23:46:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1789627618; x=1790232418; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=WnFkKlS5WARQKCpGuZojTqxptSVM2xGpYdtnYIiPoQU=; b=T85PjcbkdWofpRFkdvxsujTymSMlNHen/ro05W7/kRevGu3z48S3sg/LpBym3pGg68 586NWXC/X70jXyEeSuADitF0tEAKGtaISJUOu4YzWGOBXi7MksAJoZk+LS5HUAkCvyeC BLkifS71ShfCkYQwmUoqRH870Xh8WrE+h57Bc= X-Forwarded-Encrypted: i=1; AKwUvBx4BwBIUNbKSCM2RbegjxomNZFk0mGngLS7Qx82rG67wzumqrLhooR/Tz/CqHqUHOXUyIVmx3wEjh39ZFw=@vger.kernel.org X-Received: by 2002:a05:6a21:4a81:b0:3cd:8bba:824f with SMTP id adf61e73a8af0-3dd5f3f8a8fmr13321660637.4.1789627618533; Wed, 16 Sep 2026 23:46:58 -0700 (PDT) X-Received: by 2002:a05:6a21:4a81:b0:3cd:8bba:824f with SMTP id adf61e73a8af0-3dd5f3f8a8fmr13321597637.4.1789627617989; Wed, 16 Sep 2026 23:46:57 -0700 (PDT) Received: from H5S1 ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc50ab960edsm2754293a12.20.2026.09.16.23.46.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 23:46:57 -0700 (PDT) From: Vikas Gupta To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com, vsrama-krishna.nemani@broadcom.com, rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com, ajit.khaparde@broadcom.com, Vikas Gupta Subject: [net-next, v3 10/11] bnge: add aRFS flow steering ndo support Date: Thu, 17 Sep 2026 12:15:47 +0530 Message-ID: <20260917064548.773334-11-vikas.gupta@broadcom.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260917064548.773334-1-vikas.gupta@broadcom.com> References: <20260917064548.773334-1-vikas.gupta@broadcom.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-DetectorID-Processed: b00c1d49-9d2e-4205-b15f-d015386d3d5e Content-Type: text/plain; charset="utf-8" Introduce the ndo_rx_flow_steer callback (bnge_rx_flow_steer) to support aRFS. This callback creates an NTUPLE filter that steers matching packets to the appropriate RX queue. The implementation dissects flow keys from the SKB, creates an NTUPLE filter with the associated L2 filter, inserts it into the NTUPLE hash table, and schedules the sp_task workqueue via BNGE_RX_NTP_FLTR_SP_EVENT to program the filter in the firmware. Add bnge_cfg_ntp_filters() called from the periodic timer via sp_task to handle deferred filter programming and expiration via rps_may_expire_flow(). Signed-off-by: Vikas Gupta Reviewed-by: Dharmender Garg --- .../net/ethernet/broadcom/bnge/bnge_filter.c | 45 ++++++++ .../net/ethernet/broadcom/bnge/bnge_filter.h | 1 + .../net/ethernet/broadcom/bnge/bnge_netdev.c | 105 ++++++++++++++++++ .../net/ethernet/broadcom/bnge/bnge_netdev.h | 1 + 4 files changed, 152 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.c b/drivers/net= /ethernet/broadcom/bnge/bnge_filter.c index 8d905252fe5e..2f9754450fbf 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_filter.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.c @@ -637,3 +637,48 @@ void bnge_clear_usr_fltrs(struct bnge_net *bn) } } } + +void bnge_cfg_ntp_filters(struct bnge_net *bn) +{ +#ifdef CONFIG_RFS_ACCEL + struct bnge_ntuple_filter *fltr, *tmp; + LIST_HEAD(install_list); + LIST_HEAD(expire_list); + int i, rc; + + rcu_read_lock(); + for (i =3D 0; i < BNGE_NTP_FLTR_HASH_SIZE; i++) { + hlist_for_each_entry_rcu(fltr, &bn->ntp_fltr_hash_tbl[i], + base.hlist) { + if (test_bit(BNGE_FLTR_VALID, &fltr->base.state)) { + if (fltr->base.flags & BNGE_ACT_NO_AGING) + continue; + if (rps_may_expire_flow(bn->netdev, + fltr->base.rxq, + fltr->flow_id, + fltr->base.sw_id)) + list_add(&fltr->base.list_node, + &expire_list); + } else { + list_add(&fltr->base.list_node, &install_list); + } + } + } + rcu_read_unlock(); + + list_for_each_entry_safe(fltr, tmp, &install_list, base.list_node) { + list_del_init(&fltr->base.list_node); + rc =3D bnge_hwrm_cfa_ntuple_filter_alloc(bn->bd, fltr); + if (rc) + bnge_del_ntp_filter_rcu(bn, fltr); + else + set_bit(BNGE_FLTR_VALID, &fltr->base.state); + } + + list_for_each_entry_safe(fltr, tmp, &expire_list, base.list_node) { + list_del_init(&fltr->base.list_node); + bnge_hwrm_cfa_ntuple_filter_free(bn->bd, fltr); + bnge_del_ntp_filter_rcu(bn, fltr); + } +#endif +} diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.h b/drivers/net= /ethernet/broadcom/bnge/bnge_filter.h index f1f43537ab97..a7cd1fd01565 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_filter.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.h @@ -119,4 +119,5 @@ void bnge_del_ntp_filter_rcu(struct bnge_net *bn, struct bnge_ntuple_filter *fltr); void bnge_cfg_usr_fltrs(struct bnge_net *bn); void bnge_clear_usr_fltrs(struct bnge_net *bn); +void bnge_cfg_ntp_filters(struct bnge_net *bn); #endif /* _BNGE_FILTER_H_ */ diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.c index 091de9624db4..9021a73ae613 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -303,6 +303,11 @@ static void bnge_timer(struct timer_list *t) if (BNGE_LINK_IS_UP(bd) && bn->stats_coal_ticks) bnge_queue_sp_work(bn, BNGE_PERIODIC_STATS_SP_EVENT); =20 +#ifdef CONFIG_RFS_ACCEL + if ((bn->priv_flags & BNGE_NET_EN_NTUPLE) && bn->ntp_fltr_count) + bnge_queue_sp_work(bn, BNGE_RX_NTP_FLTR_SP_EVENT); +#endif + mod_timer(&bn->timer, jiffies + bn->current_interval); } =20 @@ -444,6 +449,9 @@ static void bnge_sp_task(struct work_struct *work) bnge_init_ethtool_link_settings(bn); } =20 + if (test_and_clear_bit(BNGE_RX_NTP_FLTR_SP_EVENT, &bn->sp_event)) + bnge_cfg_ntp_filters(bn); + netdev_unlock(bn->netdev); } =20 @@ -3175,6 +3183,100 @@ static int bnge_set_features(struct net_device *dev= , netdev_features_t features) return 0; } =20 +#ifdef CONFIG_RFS_ACCEL +static __le64 bnge_lookup_l2_filter_from_key(struct bnge_net *bn, + struct bnge_l2_key *key) +{ + u32 idx; + + idx =3D jhash2(&key->filter_key, BNGE_L2_KEY_SIZE, bn->hash_seed) & + BNGE_L2_FLTR_HASH_MASK; + return bnge_lookup_l2_filter_rcu(bn, key, idx); +} + +static int bnge_rx_flow_steer(struct net_device *dev, const struct sk_buff= *skb, + u16 rxq_index, u32 flow_id) +{ + struct ethhdr *eth =3D (struct ethhdr *)skb_mac_header(skb); + struct bnge_ntuple_filter *fltr, *new_fltr; + struct bnge_net *bn =3D netdev_priv(dev); + struct flow_keys *fkeys; + __le64 filter_id; + u32 flags, idx; + int rc =3D 0; + + if (ether_addr_equal(dev->dev_addr, eth->h_dest)) { + struct bnge_l2_filter *l2_filter; + + l2_filter =3D bn->vnic_info[BNGE_VNIC_DEFAULT].l2_filters[0]; + filter_id =3D l2_filter->base.filter_id; + + } else { + struct bnge_l2_key key; + + ether_addr_copy(key.dst_mac_addr, eth->h_dest); + key.vlan =3D 0; + + filter_id =3D bnge_lookup_l2_filter_from_key(bn, &key); + if (filter_id =3D=3D BNGE_FLTR_ID_INVALID) + return -EINVAL; + } + new_fltr =3D kzalloc_obj(*new_fltr, GFP_ATOMIC); + if (!new_fltr) + return -ENOMEM; + + fkeys =3D &new_fltr->fkeys; + if (!skb_flow_dissect_flow_keys(skb, fkeys, 0)) { + rc =3D -EPROTONOSUPPORT; + goto err_free; + } + + if ((fkeys->basic.n_proto !=3D htons(ETH_P_IP) && + fkeys->basic.n_proto !=3D htons(ETH_P_IPV6)) || + (fkeys->basic.ip_proto !=3D IPPROTO_TCP && + fkeys->basic.ip_proto !=3D IPPROTO_UDP)) { + rc =3D -EPROTONOSUPPORT; + goto err_free; + } + new_fltr->fmasks =3D BNGE_FLOW_IPV4_MASK_ALL; + if (fkeys->basic.n_proto =3D=3D htons(ETH_P_IPV6)) + new_fltr->fmasks =3D BNGE_FLOW_IPV6_MASK_ALL; + + flags =3D fkeys->control.flags; + if (flags & FLOW_DIS_IS_FRAGMENT) { + rc =3D -EPROTONOSUPPORT; + goto err_free; + } + + new_fltr->l2_filter_id =3D filter_id; + + idx =3D bnge_get_ntp_filter_idx(bn, fkeys, skb); + rcu_read_lock(); + fltr =3D bnge_lookup_ntp_filter_from_idx(bn, new_fltr, idx); + /* Filter already exists; return its id. A stale filter (queue + * changed) is freed later via rps_may_expire_flow() and recreated. + */ + if (fltr) { + rc =3D fltr->base.sw_id; + rcu_read_unlock(); + goto err_free; + } + rcu_read_unlock(); + + new_fltr->flow_id =3D flow_id; + new_fltr->base.rxq =3D rxq_index; + rc =3D bnge_insert_ntp_filter(bn, new_fltr, idx); + if (!rc) { + bnge_queue_sp_work(bn, BNGE_RX_NTP_FLTR_SP_EVENT); + return new_fltr->base.sw_id; + } + +err_free: + kfree(new_fltr); + return rc; +} +#endif + static const struct net_device_ops bnge_netdev_ops =3D { .ndo_open =3D bnge_open, .ndo_stop =3D bnge_close, @@ -3184,6 +3286,9 @@ static const struct net_device_ops bnge_netdev_ops = =3D { .ndo_features_check =3D bnge_features_check, .ndo_fix_features =3D bnge_fix_features, .ndo_set_features =3D bnge_set_features, +#ifdef CONFIG_RFS_ACCEL + .ndo_rx_flow_steer =3D bnge_rx_flow_steer, +#endif }; =20 static void bnge_init_mac_addr(struct bnge_dev *bd) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.h index bfd0d9cb871f..3146023621a6 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h @@ -282,6 +282,7 @@ enum bnge_sp_event { BNGE_LINK_CFG_CHANGE_SP_EVENT, BNGE_UPDATE_PHY_SP_EVENT, BNGE_PERIODIC_STATS_SP_EVENT, + BNGE_RX_NTP_FLTR_SP_EVENT, }; =20 #define BNGE_NTP_FLTR_HASH_SIZE 512 --=20 2.52.0 From nobody Fri Sep 25 03:16:18 2026 Received: from mail-pj1-f97.google.com (mail-pj1-f97.google.com [209.85.216.97]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E0C744E05B for ; Thu, 17 Sep 2026 06:47:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.97 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627629; cv=none; b=Qg4hnA9dbbw/AGeM27a6WjVhrcrDNWj0uagOz79zPs4rOkheRJjK1WwfZaI/kvtZ1Vgx9y2EeEMxLla4PI8bEcxt8a0/CIjZzw5DRCv6fA6blyIGBDLDskdJqBKjWkOVxhk4z4Gb+Th9GqgEAhKh8M5m+4lGCh3gzy5OXo+TMT4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789627629; c=relaxed/simple; bh=6s8I+G2QOuBgIACke0ae7iObsMaEdu7VrkAqPRa3J4A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Wx4o3p8kvBAT4RrjHh9jpwpLvwKaS/q3Kthu2QLrBRbkfvZqN96yE2BFtIwGDvLGaxnMm1Q3NM6w0TFGJfgiS+ouiUnboCqJHkcUjMqpgiTRkF8Y8Rik0UnnhupTHiUEfV+wBc5FRfbhR0CkVotGxJ/mGABI+Q47KtSPep5GTmM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=fpFi9SrD; arc=none smtp.client-ip=209.85.216.97 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="fpFi9SrD" Received: by mail-pj1-f97.google.com with SMTP id 98e67ed59e1d1-38759bcd877so177523a91.2 for ; Wed, 16 Sep 2026 23:47:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789627626; x=1790232426; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=dl0Y03iDyMlH0hydD0ToKowhkdZ6P1fZNzzLnbF2C34=; b=au6VEgGW6TMT5jzR2yRmOjY6w8eOiaPxrEbrXsn0+hvVStlOk8KjyFFGWXs+Vy0vQ1 bsBM21qR8T41dyghcolGjpTtwYhkY9vW6X/mYqwNUyXr2qfoSHzOiV6VPDgfBXjuqAFb hl0dmV6UDgX/ExMd1QdrClIJzgVlmMN5JrcjmUaoHRddK2dWIoSMfm+O70IeIxQ5oRGD BE9VQzbbj45KOJp7HGcko/PkXVuz81H+NRF7Wyc9JCkGpZoFejExMnsP3zCykKbDB6v6 GPhJztCKXzjXZRzMBDtiywzFKCjJdjuCxw9c7AYP/DxnYcVFz8/YbEDBXwUu6i4eNuCj H3pA== X-Forwarded-Encrypted: i=1; AKwUvBz2haIPZkS/tyVNTpYOHSCeDvdqCPzcK73lwzUEZxeYYkoWvrMg58OhpvLQWR+Ci4mACERiVE9VHsxsFI0=@vger.kernel.org X-Gm-Message-State: AFuF++ldRmIYIJDOZHhTJ/vvOt3pjU/h8OxAJf6zRC6w5zv5xOHCQuB7 /exvu2rMOlUszOizDQm8XilTQAGwQTixvEuI7415s4+5H/BDCTh/amqHtsxyjCeeQ/qIzpjtLJL GDIDZweka3fuskET3+8FdoVagMY0Ie6hOlVyiKuwNfDG8nKsr6uvbjw28aonvy8GGG9lFBlQiJ6 kmoVCq3PSJfMHWtFkILRqEKTJCpFjpaEfJLNoHEEDMuMBzU+KCTWllRW47i9tcerXnXF9GeC+9U 18IQffmhR4UrrwOVg== X-Gm-Gg: AYBFou2CioFQWAPGEt4fugVlptsGSGWuDdklitqWnZ804CfoYe36/GIDf6UHH1cd18E ysPlBXVuyxpTBpthl7OWNuMC49beJSPJh6/yZFxfbHFDkOOWOsR8+lM8gl8b+cqM71DPKrCina9 FEHITH5pNnBA1B3/PiOB90AJ/0x58jhvQqcsC54PNFkmJMPhw79wXsdq623uSyy4pIfJWHUEq+9 uqa+yBcyXdclRFffY5TJsI7dIICqyJMTZzBFywzxpT2prH7KamS7F3PfnhEoHLkemQj70cAEWJz soRVA5dtqvaGQl3OnflRs3V4E8BRO2JyLPBmep0YE5mxeS12QcCkTyimuL4vTbXJfJclCwcXpLr aKdtwSPbYhHofDtEx6LihaC0o+ihsH/DisGIzjDQioO52fCm1TrEFTmlt7SRYFw7YCVvsL3yhyj 9SQH6ugeSbfZytamYsIas4wuvBsSjq+BJD1Q== X-Received: by 2002:a17:90b:2f06:b0:39e:252:ae4d with SMTP id 98e67ed59e1d1-39e1e4d3fe8mr12734784a91.17.1789627626235; Wed, 16 Sep 2026 23:47:06 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-29.dlp.protect.broadcom.com. [144.49.247.29]) by smtp-relay.gmail.com with ESMTPS id 98e67ed59e1d1-39e3716843csm966329a91.5.2026.09.16.23.47.05 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2026 23:47:06 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-870ec29b035so341602b3a.2 for ; Wed, 16 Sep 2026 23:47:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1789627624; x=1790232424; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=dl0Y03iDyMlH0hydD0ToKowhkdZ6P1fZNzzLnbF2C34=; b=fpFi9SrD9v2U5Y9Ys60MRnUp24XGij9P85IwpwXXOe3zW0WaQYb8IQkWTAcLl1fWnE Pn6K7pc+04eR+a5MuUPdHrlOVEhsuOFYjZV6vMj+f9aMjzfxkS7Ty58slhzfFC4ZPpXu RKd5KDJjsjCTBHHOX+dd5Yk+fs0r/qO2xfD5o= X-Forwarded-Encrypted: i=1; AKwUvBwbjFRymNPoi8X1uEF6Mxa51f34uEuxyaprQryvq1bfVPSgFgIVuQBG/CZaIdVyhttOnyJUh7dZCRCzSSI=@vger.kernel.org X-Received: by 2002:a05:6a20:918e:b0:3d3:b00a:7082 with SMTP id adf61e73a8af0-3dd5f7b25d9mr14104562637.28.1789627624186; Wed, 16 Sep 2026 23:47:04 -0700 (PDT) X-Received: by 2002:a05:6a20:918e:b0:3d3:b00a:7082 with SMTP id adf61e73a8af0-3dd5f7b25d9mr14104523637.28.1789627623735; Wed, 16 Sep 2026 23:47:03 -0700 (PDT) Received: from H5S1 ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc50ab960edsm2754293a12.20.2026.09.16.23.46.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 23:47:03 -0700 (PDT) From: Vikas Gupta To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com, vsrama-krishna.nemani@broadcom.com, rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com, ajit.khaparde@broadcom.com, Vikas Gupta Subject: [net-next, v3 11/11] bnge: add cpu_rmap support for IRQ affinity Date: Thu, 17 Sep 2026 12:15:48 +0530 Message-ID: <20260917064548.773334-12-vikas.gupta@broadcom.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260917064548.773334-1-vikas.gupta@broadcom.com> References: <20260917064548.773334-1-vikas.gupta@broadcom.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-DetectorID-Processed: b00c1d49-9d2e-4205-b15f-d015386d3d5e Content-Type: text/plain; charset="utf-8" When CONFIG_RFS_ACCEL is enabled, allocate and populate a cpu_rmap for the RX IRQ vectors so that the kernel's aRFS infrastructure can correctly map flows to the RX queues serviced by the nearest CPU. This ensures that NTUPLE rules created by the kernel steer packets to the optimal queue based on CPU/IRQ affinity. Signed-off-by: Vikas Gupta Reviewed-by: Bhargava Chenna Marreddy Reviewed-by: Dharmender Garg --- .../net/ethernet/broadcom/bnge/bnge_netdev.c | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.c index 9021a73ae613..cc7c854864e2 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -18,6 +18,7 @@ #include #include #include +#include =20 #include "bnge.h" #include "bnge_hwrm.h" @@ -2441,10 +2442,23 @@ static int bnge_setup_interrupts(struct bnge_net *b= n) { struct net_device *dev =3D bn->netdev; struct bnge_dev *bd =3D bn->bd; + int rc; =20 bnge_setup_msix(bn); =20 - return netif_set_real_num_queues(dev, bd->tx_nr_rings, bd->rx_nr_rings); + rc =3D netif_set_real_num_queues(dev, bd->tx_nr_rings, bd->rx_nr_rings); + if (rc) + return rc; + +#ifdef CONFIG_RFS_ACCEL + if (bn->priv_flags & BNGE_NET_EN_NTUPLE) { + dev->rx_cpu_rmap =3D alloc_irq_cpu_rmap(bd->rx_nr_rings); + if (!dev->rx_cpu_rmap) + return -ENOMEM; + } +#endif + + return rc; } =20 static void bnge_hwrm_resource_free(struct bnge_net *bn, bool close_path) @@ -2460,6 +2474,11 @@ static void bnge_free_irq(struct bnge_net *bn) struct bnge_irq *irq; int i; =20 +#ifdef CONFIG_RFS_ACCEL + free_irq_cpu_rmap(bn->netdev->rx_cpu_rmap); + bn->netdev->rx_cpu_rmap =3D NULL; +#endif + for (i =3D 0; i < bd->nq_nr_rings; i++) { int map_idx =3D bnge_cp_num_to_irq_num(bn, i); =20 @@ -2479,6 +2498,7 @@ static void bnge_free_irq(struct bnge_net *bn) =20 static int bnge_request_irq(struct bnge_net *bn) { + struct cpu_rmap *rmap =3D NULL; struct bnge_dev *bd =3D bn->bd; int i, rc; =20 @@ -2487,10 +2507,23 @@ static int bnge_request_irq(struct bnge_net *bn) netdev_err(bn->netdev, "bnge_setup_interrupts err: %d\n", rc); return rc; } + +#ifdef CONFIG_RFS_ACCEL + rmap =3D bn->netdev->rx_cpu_rmap; +#endif + for (i =3D 0; i < bd->nq_nr_rings; i++) { int map_idx =3D bnge_cp_num_to_irq_num(bn, i); struct bnge_irq *irq =3D &bd->irq_tbl[map_idx]; =20 + if (IS_ENABLED(CONFIG_RFS_ACCEL) && + rmap && bn->bnapi[i]->rx_ring) { + rc =3D irq_cpu_rmap_add(rmap, irq->vector); + if (rc) + netdev_warn(bn->netdev, + "failed adding irq rmap for ring %d\n", i); + } + rc =3D request_irq(irq->vector, irq->handler, 0, irq->name, bn->bnapi[i]); if (rc) --=20 2.52.0