From nobody Fri Oct 3 19:06:48 2025 Received: from mail-vk1-f227.google.com (mail-vk1-f227.google.com [209.85.221.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 F1814343202 for ; Tue, 26 Aug 2025 11:18:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.227 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756207091; cv=none; b=rCaijffchU2cohuQwwxVh9XUfQ8+mhN/Lk+mXhC9CV+ptbXxF/VL7d5Vd4AbQFIC9dAWaDZeWUxjXD8TdPXQwBvWwP24F9AJkAuT1Gllyy66lj7F2S07U5P5zr0c4PBC90ZXNSuDM4Ym0AJHy7xJiKYJCQHMDZEmnJtkdokqsfk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756207091; c=relaxed/simple; bh=oP428h/0jDdlOL0V1oJjHwxxZPJVaKReKCuGXUgA6Gs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uvpTiHTIaqY90JANWFOenwiYka8NM+I0qV9Y/bfsE6LFQgVHnKW9cpp+ra5zfUiEt8lrXSoH6Lj6UMHc7v3LH9HanfEzZ5VL6DbdYm2FeW3BmV05elVMPkP93oEKA2BpCq+7HWnltMa+M+6X6WFddc4ZtXB7YG6zkM/Y/vV62kA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=Z+NF+PrA; arc=none smtp.client-ip=209.85.221.227 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="Z+NF+PrA" Received: by mail-vk1-f227.google.com with SMTP id 71dfb90a1353d-5435d248876so340685e0c.0 for ; Tue, 26 Aug 2025 04:18:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1756207088; x=1756811888; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Tv4wP7UUY3Up6ECf8C5DmcvveA3lbi0N0eGZkDqeA0c=; b=mFFDwlhWtUDe8IX9tGYJ3FtH6RziZqWTnYHoPiofIXlJBTf4ehHxeD6X8ltcVdDFGf hU7357pV2hlyeZ/lyHwdp46uvZ032PQAY8syEBHEuF6HQP/kg1CO8p3Y+6gfyK2TB9E3 r1HAuknj/Eb8uCYLesORbxxoGEiKaWpHgeDi/0bnsZpdj9y0rVJgvkn1z+kr/7pUJAVo eGKUpcuUOSxVU0WCKeT3a+L2XR8sR4NgaIDlDNeP0t+r4e24AZgscIW57CrUItGcHbka YzE5nTm5uYTLbTgOWseeQCCyCsDLPvROIKBG5Ki4ExfOmZ345LVY4antdz4OLCiHhThO 8Hxw== X-Forwarded-Encrypted: i=1; AJvYcCXwwXc6pGuU1pOT6+o0p7/H1kCcNZ7WoOKJe6UE/3eEVqOv6GyLhiSkh88wjYyuHMnUymCW6OTVCCV1jhs=@vger.kernel.org X-Gm-Message-State: AOJu0Yxuchdmdx0B3/QjXTavM6bGyCWf3HOSxoeAJYM+s/BZPJpYZZMV t5b1sqkB1FDABsO5b7kZS306Y9+2EO5oJmufe2FL+VSFEFdQVFMu89aiZbyQxq+r4XO4YsPI3J1 4Hme5N5Y59rV7Lp93SJmOLjVsbb4WrdX4E314m0A3P+vPgdyP6kzw4GjMrrHq39zPFR5YWYO35J vIYjqaYZ39HOixE7blG161TKo1GtENdM1dFWseMz6+QOh2mSdJBIXVO7qmGM5ThkFI4P22NEvbT CHzaXcn4mdsnmQiTGr/S5LOtHzx X-Gm-Gg: ASbGnct2i3IbLdKHrsAEtS6Q0ZmXkO8rl31n5OltEKMG4YBkwQJwz7G8x2KbW2JhmkY +3QX9zmPs0fCeOmJN/Y3hM8hyg+oZNZgVPLxWZEPLJf5v/BEwp1Ztt2CqCcw8U+SxLyLvg4V9ic 6sj5QezQAB1aZHUhei3xVeKV6Lcle5AQozwockgAeVEJEGkHNtF2IIMxQqSQfvHSztd/JOf1ahG qlISvXFpfE7RuHAQrbSg7b19mXVSu/IlK8RhfWaiUffwaBGOEmw9i6cHqvO+YU2/1VC7LHdcAiA gP31wru8GOnjUwtjNT2cQT4qPVODFy/gSEEzwRndM4Lt+p1971paQEaL5Z2YfcQhZvvT0kNmawF Z4oUJ9j5dxkhPdudUhywJhewnGvBhBErDT1h8TNtapoPLHEypX0fgwNq+lYXZKYixBOQytdpJ3u LfO/Gylw== X-Google-Smtp-Source: AGHT+IEN6jp2u8nq5RD2ASV3QkI00D2v5pE9V0MRV+p11sOq2WYfBYpiowsCKSrauO+gpPBT8O6B3z/G7CGn X-Received: by 2002:a05:6122:2528:b0:539:4097:794a with SMTP id 71dfb90a1353d-53c8a3cad8emr4709766e0c.12.1756207087891; Tue, 26 Aug 2025 04:18:07 -0700 (PDT) Received: from smtp-us-east1-p01-i01-si01.dlp.protect.broadcom.com (address-144-49-247-11.dlp.protect.broadcom.com. [144.49.247.11]) by smtp-relay.gmail.com with ESMTPS id 71dfb90a1353d-542724daef8sm267948e0c.2.2025.08.26.04.18.07 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Aug 2025 04:18:07 -0700 (PDT) X-Relaying-Domain: broadcom.com X-CFilter-Loop: Reflected Received: by mail-pf1-f197.google.com with SMTP id d2e1a72fcca58-771f28ed113so1209541b3a.0 for ; Tue, 26 Aug 2025 04:18:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1756207086; x=1756811886; 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; bh=Tv4wP7UUY3Up6ECf8C5DmcvveA3lbi0N0eGZkDqeA0c=; b=Z+NF+PrAgJ0ME1KLS63tGQD8klmN7GZdlKou9ky97F6pQYQdyoyiT7nFqnRtv0rKQp +on3KeUTMRa5Ip4iAKi9mqursiMnQ+yBFv83cpB8TPst7pBfg457EDou0Szvjp+rDdMf hFk0rOd+DGfP35+10TILpfH1B0iO50zIdWFro= X-Forwarded-Encrypted: i=1; AJvYcCWryFu1RmSNuQJdUOImWVDWBwyPqOAWihXQdU92qFWhwadLb74mN4CFRTGVWfUihQfh4HylqPluZsp1Vkc=@vger.kernel.org X-Received: by 2002:a05:6a00:99e:b0:76c:503:180d with SMTP id d2e1a72fcca58-7702f9e8eb1mr20381549b3a.8.1756207086042; Tue, 26 Aug 2025 04:18:06 -0700 (PDT) X-Received: by 2002:a05:6a00:99e:b0:76c:503:180d with SMTP id d2e1a72fcca58-7702f9e8eb1mr20381510b3a.8.1756207085473; Tue, 26 Aug 2025 04:18:05 -0700 (PDT) Received: from hyd-csg-thor2-h1-server2.dhcp.broadcom.net ([192.19.203.250]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-77054bb0c46sm7280339b3a.41.2025.08.26.04.18.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Aug 2025 04:18:04 -0700 (PDT) From: Bhargava Marreddy 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, michael.chan@broadcom.com, pavan.chebbi@broadcom.com, vsrama-krishna.nemani@broadcom.com, Bhargava Marreddy , Vikas Gupta , Rajashekar Hudumula Subject: [v4, net-next 9/9] bng_en: Configure default VNIC Date: Tue, 26 Aug 2025 16:44:12 +0000 Message-ID: <20250826164412.220565-10-bhargava.marreddy@broadcom.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20250826164412.220565-1-bhargava.marreddy@broadcom.com> References: <20250826164412.220565-1-bhargava.marreddy@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 functions to add a filter to the VNIC to configure unicast addresses. Also, add multicast, broadcast, and promiscuous settings to the default VNIC. Signed-off-by: Bhargava Marreddy Reviewed-by: Vikas Gupta Reviewed-by: Rajashekar Hudumula --- .../ethernet/broadcom/bnge/bnge_hwrm_lib.c | 72 +++++ .../ethernet/broadcom/bnge/bnge_hwrm_lib.h | 4 + .../net/ethernet/broadcom/bnge/bnge_netdev.c | 271 ++++++++++++++++++ .../net/ethernet/broadcom/bnge/bnge_netdev.h | 41 +++ 4 files changed, 388 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/n= et/ethernet/broadcom/bnge/bnge_hwrm_lib.c index fd54c72b0ad0..f4ef27c307ab 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c @@ -854,6 +854,78 @@ void bnge_hwrm_update_rss_hash_cfg(struct bnge_net *bn) bnge_hwrm_req_drop(bd, req); } =20 +int bnge_hwrm_l2_filter_free(struct bnge_dev *bd, struct bnge_l2_filter *f= ltr) +{ + struct hwrm_cfa_l2_filter_free_input *req; + int rc; + + rc =3D bnge_hwrm_req_init(bd, req, HWRM_CFA_L2_FILTER_FREE); + if (rc) + return rc; + + req->l2_filter_id =3D fltr->base.filter_id; + return bnge_hwrm_req_send(bd, req); +} + +int bnge_hwrm_l2_filter_alloc(struct bnge_dev *bd, struct bnge_l2_filter *= fltr) +{ + struct hwrm_cfa_l2_filter_alloc_output *resp; + struct hwrm_cfa_l2_filter_alloc_input *req; + int rc; + + rc =3D bnge_hwrm_req_init(bd, req, HWRM_CFA_L2_FILTER_ALLOC); + if (rc) + return rc; + + 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); + 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 | + CFA_L2_FILTER_ALLOC_REQ_ENABLES_DST_ID | + CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR_MASK); + ether_addr_copy(req->l2_addr, fltr->l2_key.dst_mac_addr); + eth_broadcast_addr(req->l2_addr_mask); + + if (fltr->l2_key.vlan) { + req->enables |=3D + cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_IVLAN | + CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_IVLAN_MASK | + CFA_L2_FILTER_ALLOC_REQ_ENABLES_NUM_VLANS); + req->num_vlans =3D 1; + req->l2_ivlan =3D cpu_to_le16(fltr->l2_key.vlan); + req->l2_ivlan_mask =3D cpu_to_le16(0xfff); + } + + resp =3D bnge_hwrm_req_hold(bd, req); + rc =3D bnge_hwrm_req_send(bd, req); + if (!rc) + fltr->base.filter_id =3D resp->l2_filter_id; + + bnge_hwrm_req_drop(bd, req); + return rc; +} + +int bnge_hwrm_cfa_l2_set_rx_mask(struct bnge_dev *bd, + struct bnge_vnic_info *vnic) +{ + struct hwrm_cfa_l2_set_rx_mask_input *req; + int rc; + + rc =3D bnge_hwrm_req_init(bd, req, HWRM_CFA_L2_SET_RX_MASK); + if (rc) + return rc; + + req->vnic_id =3D cpu_to_le32(vnic->fw_vnic_id); + if (vnic->rx_mask & CFA_L2_SET_RX_MASK_REQ_MASK_MCAST) { + req->num_mc_entries =3D cpu_to_le32(vnic->mc_list_count); + req->mc_tbl_addr =3D cpu_to_le64(vnic->mc_list_mapping); + } + req->mask =3D cpu_to_le32(vnic->rx_mask); + return bnge_hwrm_req_send_silent(bd, req); +} + int bnge_hwrm_vnic_alloc(struct bnge_dev *bd, struct bnge_vnic_info *vnic, unsigned int nr_rings) { diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h b/drivers/n= et/ethernet/broadcom/bnge/bnge_hwrm_lib.h index 09517ffb1a21..042f28e84a05 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.h @@ -43,6 +43,10 @@ int bnge_hwrm_vnic_alloc(struct bnge_dev *bd, struct bng= e_vnic_info *vnic, void bnge_hwrm_vnic_free_one(struct bnge_dev *bd, struct bnge_vnic_info *v= nic); void bnge_hwrm_vnic_ctx_free_one(struct bnge_dev *bd, struct bnge_vnic_info *vnic, u16 ctx_idx); +int bnge_hwrm_l2_filter_free(struct bnge_dev *bd, struct bnge_l2_filter *f= ltr); +int bnge_hwrm_l2_filter_alloc(struct bnge_dev *bd, struct bnge_l2_filter *= fltr); +int bnge_hwrm_cfa_l2_set_rx_mask(struct bnge_dev *bd, + struct bnge_vnic_info *vnic); void bnge_hwrm_stat_ctx_free(struct bnge_net *bn); int bnge_hwrm_stat_ctx_alloc(struct bnge_net *bn); int hwrm_ring_free_send_msg(struct bnge_net *bn, struct bnge_ring_struct *= ring, diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.c index 30381d9a0734..c0971e243fbe 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -1512,6 +1512,231 @@ static int bnge_setup_vnic(struct bnge_net *bn, str= uct bnge_vnic_info *vnic) return rc; } =20 +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 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; + + 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); + return 0; +} + +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; + 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) + return fltr; + + fltr =3D kzalloc(sizeof(*fltr), gfp); + if (!fltr) + return ERR_PTR(-ENOMEM); + rc =3D bnge_init_l2_filter(bn, fltr, key, idx); + if (rc) { + bnge_del_l2_filter(bn, fltr); + fltr =3D ERR_PTR(rc); + } + 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) + bnge_del_l2_filter(bn, fltr); + else + bn->vnic_info[vnic_id].l2_filters[idx] =3D fltr; + return rc; +} + +static bool bnge_mc_list_updated(struct bnge_net *bn, u32 *rx_mask) +{ + struct bnge_vnic_info *vnic =3D &bn->vnic_info[BNGE_VNIC_DEFAULT]; + struct net_device *dev =3D bn->netdev; + struct netdev_hw_addr *ha; + int mc_count =3D 0, off =3D 0; + bool update =3D false; + u8 *haddr; + + netdev_for_each_mc_addr(ha, dev) { + if (mc_count >=3D BNGE_MAX_MC_ADDRS) { + *rx_mask |=3D CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST; + vnic->mc_list_count =3D 0; + return false; + } + haddr =3D ha->addr; + if (!ether_addr_equal(haddr, vnic->mc_list + off)) { + memcpy(vnic->mc_list + off, haddr, ETH_ALEN); + update =3D true; + } + off +=3D ETH_ALEN; + mc_count++; + } + if (mc_count) + *rx_mask |=3D CFA_L2_SET_RX_MASK_REQ_MASK_MCAST; + + if (mc_count !=3D vnic->mc_list_count) { + vnic->mc_list_count =3D mc_count; + update =3D true; + } + return update; +} + +static bool bnge_uc_list_updated(struct bnge_net *bn) +{ + struct bnge_vnic_info *vnic =3D &bn->vnic_info[BNGE_VNIC_DEFAULT]; + struct net_device *dev =3D bn->netdev; + struct netdev_hw_addr *ha; + int off =3D 0; + + if (netdev_uc_count(dev) !=3D (vnic->uc_filter_count - 1)) + return true; + + netdev_for_each_uc_addr(ha, dev) { + if (!ether_addr_equal(ha->addr, vnic->uc_list + off)) + return true; + + off +=3D ETH_ALEN; + } + return false; +} + +static bool bnge_promisc_ok(struct bnge_net *bn) +{ + return true; +} + +static int bnge_cfg_def_vnic(struct bnge_net *bn) +{ + struct bnge_vnic_info *vnic =3D &bn->vnic_info[BNGE_VNIC_DEFAULT]; + struct net_device *dev =3D bn->netdev; + struct bnge_dev *bd =3D bn->bd; + struct netdev_hw_addr *ha; + int i, off =3D 0, rc; + bool uc_update; + + netif_addr_lock_bh(dev); + uc_update =3D bnge_uc_list_updated(bn); + netif_addr_unlock_bh(dev); + + if (!uc_update) + goto skip_uc; + + for (i =3D 1; i < vnic->uc_filter_count; i++) { + struct bnge_l2_filter *fltr =3D vnic->l2_filters[i]; + + bnge_hwrm_l2_filter_free(bd, fltr); + bnge_del_l2_filter(bn, fltr); + } + + vnic->uc_filter_count =3D 1; + + netif_addr_lock_bh(dev); + if (netdev_uc_count(dev) > (BNGE_MAX_UC_ADDRS - 1)) { + vnic->rx_mask |=3D CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS; + } else { + netdev_for_each_uc_addr(ha, dev) { + memcpy(vnic->uc_list + off, ha->addr, ETH_ALEN); + off +=3D ETH_ALEN; + vnic->uc_filter_count++; + } + } + netif_addr_unlock_bh(dev); + + for (i =3D 1, off =3D 0; i < vnic->uc_filter_count; i++, off +=3D ETH_ALE= N) { + rc =3D bnge_hwrm_set_vnic_filter(bn, 0, i, vnic->uc_list + off); + if (rc) { + netdev_err(dev, "HWRM vnic filter failure rc: %d\n", rc); + vnic->uc_filter_count =3D i; + return rc; + } + } + +skip_uc: + if ((vnic->rx_mask & CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS) && + !bnge_promisc_ok(bn)) + vnic->rx_mask &=3D ~CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS; + rc =3D bnge_hwrm_cfa_l2_set_rx_mask(bd, vnic); + if (rc && (vnic->rx_mask & CFA_L2_SET_RX_MASK_REQ_MASK_MCAST)) { + netdev_info(dev, "Failed setting MC filters rc: %d, turning on ALL_MCAST= mode\n", + rc); + vnic->rx_mask &=3D ~CFA_L2_SET_RX_MASK_REQ_MASK_MCAST; + vnic->rx_mask |=3D CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST; + vnic->mc_list_count =3D 0; + rc =3D bnge_hwrm_cfa_l2_set_rx_mask(bd, vnic); + } + if (rc) + netdev_err(dev, "HWRM cfa l2 rx mask failure rc: %d\n", + rc); + + return rc; +} + static void bnge_hwrm_vnic_free(struct bnge_net *bn) { int i; @@ -1535,11 +1760,27 @@ static void bnge_hwrm_vnic_ctx_free(struct bnge_net= *bn) bn->rsscos_nr_ctxs =3D 0; } =20 +static void bnge_hwrm_clear_vnic_filter(struct bnge_net *bn) +{ + struct bnge_vnic_info *vnic =3D &bn->vnic_info[BNGE_VNIC_DEFAULT]; + int i; + + for (i =3D 0; i < vnic->uc_filter_count; i++) { + struct bnge_l2_filter *fltr =3D vnic->l2_filters[i]; + + bnge_hwrm_l2_filter_free(bn->bd, fltr); + bnge_del_l2_filter(bn, fltr); + } + + vnic->uc_filter_count =3D 0; +} + static void bnge_clear_vnic(struct bnge_net *bn) { if (!bn->vnic_info) return; =20 + bnge_hwrm_clear_vnic_filter(bn); bnge_hwrm_vnic_free(bn); bnge_hwrm_vnic_ctx_free(bn); } @@ -1784,6 +2025,36 @@ static int bnge_init_chip(struct bnge_net *bn) if (bd->rss_cap & BNGE_RSS_CAP_RSS_HASH_TYPE_DELTA) bnge_hwrm_update_rss_hash_cfg(bn); =20 + /* Filter for default vnic 0 */ + rc =3D bnge_hwrm_set_vnic_filter(bn, 0, 0, bn->netdev->dev_addr); + if (rc) { + netdev_err(bn->netdev, "HWRM vnic filter failure rc: %d\n", rc); + goto err_out; + } + vnic->uc_filter_count =3D 1; + + vnic->rx_mask =3D 0; + + if (bn->netdev->flags & IFF_BROADCAST) + vnic->rx_mask |=3D CFA_L2_SET_RX_MASK_REQ_MASK_BCAST; + + if (bn->netdev->flags & IFF_PROMISC) + vnic->rx_mask |=3D CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS; + + if (bn->netdev->flags & IFF_ALLMULTI) { + vnic->rx_mask |=3D CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST; + vnic->mc_list_count =3D 0; + } else if (bn->netdev->flags & IFF_MULTICAST) { + u32 mask =3D 0; + + bnge_mc_list_updated(bn, &mask); + vnic->rx_mask |=3D mask; + } + + rc =3D bnge_cfg_def_vnic(bn); + if (rc) + goto err_out; + return 0; err_out: bnge_hwrm_resource_free(bn, 0); diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h b/drivers/net= /ethernet/broadcom/bnge/bnge_netdev.h index f5b1a6360f50..8f1e7080d770 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h @@ -6,6 +6,7 @@ =20 #include #include +#include #include "bnge_db.h" =20 struct tx_bd { @@ -383,6 +384,10 @@ struct bnge_vnic_info { #define BNGE_MAX_CTX_PER_VNIC 8 u16 fw_rss_cos_lb_ctx[BNGE_MAX_CTX_PER_VNIC]; u16 mru; +#define BNGE_MAX_UC_ADDRS 4 + /* 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; @@ -394,6 +399,7 @@ struct bnge_vnic_info { #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; =20 u8 *mc_list; int mc_list_size; @@ -408,6 +414,41 @@ struct bnge_vnic_info { u32 vnic_id; }; =20 +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; +}; + u16 bnge_cp_ring_for_rx(struct bnge_rx_ring_info *rxr); u16 bnge_cp_ring_for_tx(struct bnge_tx_ring_info *txr); int bnge_get_nr_rss_ctxs(int rx_rings); --=20 2.47.3