From nobody Tue Dec 2 02:32:02 2025 Received: from canpmsgout01.his.huawei.com (canpmsgout01.his.huawei.com [113.46.200.216]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA8CA3559C9; Wed, 19 Nov 2025 12:44:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.216 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763556254; cv=none; b=hExhmSL9jbtpgECyOEisj7peD7daFKizj6f5sT3l+g6RfbSKVn/E2RodIrKhSnJn8DtOyRZR7WdpieNKlqIHVcUxt7+L0uwNsBR+RmRv3gjK6cRniMSLkkdksEudKk9YfBvs4flxojk63i8VhbFqasK4z5VmQob/b7uO2wptEbg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763556254; c=relaxed/simple; bh=N/pG+796n6dtmC+ReMP+O0qSXOzw1+BxCsjlLHlqP6c=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=HIArryfHz2PicQ1sypS8+J9NgpB/OQRoasGK1bgvjDwKwpoIbdJKM+Id5PI1myoW3YMW3Gi1sauBhcyb6ucVvK19UTRIgh4yu/YW78Zpzl3odqnSaFQoEcyiT+gtkqtbYnf0dWQTbI6r5QAU/JvphVqI6Wmj63+N4CR4iUsKiW4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=JyQux/uV; arc=none smtp.client-ip=113.46.200.216 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="JyQux/uV" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=0jf9RYMP/5laEAnMJdwviHAN2p67D+g6/gkP5rRQzps=; b=JyQux/uVOsOKf4wPwFmjPlXCkBrMFOu5uOXo1WL9HD3QVih5DwARSZ0sXj9vyqz51lJbtLJyO pCjbacRa0AuzRpu5K2DqSa2TWXpgJ8cxDLClXrAr+W1+1GqwwFeEDKSzT/ATAM4tXd/2lh3/vlh DUVKvqWXauKLlN4M0ji7xwU= Received: from mail.maildlp.com (unknown [172.19.163.174]) by canpmsgout01.his.huawei.com (SkyGuard) with ESMTPS id 4dBLjR1WdGz1T4Fc; Wed, 19 Nov 2025 20:42:35 +0800 (CST) Received: from kwepemf100013.china.huawei.com (unknown [7.202.181.12]) by mail.maildlp.com (Postfix) with ESMTPS id 6DB7F140135; Wed, 19 Nov 2025 20:44:08 +0800 (CST) Received: from DESKTOP-62GVMTR.china.huawei.com (10.174.188.120) by kwepemf100013.china.huawei.com (7.202.181.12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Wed, 19 Nov 2025 20:44:07 +0800 From: Fan Gong To: Fan Gong , Zhu Yikai , , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Andrew Lunn , Markus Elfring , Pavan Chebbi , ALOK TIWARI CC: , , luosifu , Xin Guo , Shen Chenyang , Zhou Shuai , Wu Like , Shi Jing , Luo Yang , Meny Yossefi , Gur Stavi Subject: [PATCH net-next v07 5/9] hinic3: Add .ndo_vlan_rx_add/kill_vid and .ndo_validate_addr Date: Wed, 19 Nov 2025 20:43:38 +0800 Message-ID: X-Mailer: git-send-email 2.51.0.windows.1 In-Reply-To: References: 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-ClientProxiedBy: kwepems200002.china.huawei.com (7.221.188.68) To kwepemf100013.china.huawei.com (7.202.181.12) Content-Type: text/plain; charset="utf-8" Implement following callback function: .ndo_vlan_rx_add_vid .ndo_vlan_rx_kill_vid .ndo_validate_addr Co-developed-by: Zhu Yikai Signed-off-by: Zhu Yikai Signed-off-by: Fan Gong --- .../net/ethernet/huawei/hinic3/hinic3_main.c | 7 +++ .../huawei/hinic3/hinic3_mgmt_interface.h | 10 +++ .../huawei/hinic3/hinic3_netdev_ops.c | 62 +++++++++++++++++++ .../ethernet/huawei/hinic3/hinic3_nic_cfg.c | 41 ++++++++++++ .../ethernet/huawei/hinic3/hinic3_nic_cfg.h | 2 + .../ethernet/huawei/hinic3/hinic3_nic_dev.h | 6 ++ 6 files changed, 128 insertions(+) diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net= /ethernet/huawei/hinic3/hinic3_main.c index 704afd3189ee..f0f347c6b6ba 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c @@ -137,11 +137,17 @@ static int hinic3_init_nic_dev(struct net_device *net= dev, =20 nic_dev->rx_buf_len =3D HINIC3_RX_BUF_LEN; nic_dev->lro_replenish_thld =3D HINIC3_LRO_REPLENISH_THLD; + nic_dev->vlan_bitmap =3D kzalloc(HINIC3_VLAN_BITMAP_SIZE(nic_dev), + GFP_KERNEL); + if (!nic_dev->vlan_bitmap) + return -ENOMEM; + nic_dev->nic_svc_cap =3D hwdev->cfg_mgmt->cap.nic_svc_cap; =20 nic_dev->workq =3D create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME); if (!nic_dev->workq) { dev_err(hwdev->dev, "Failed to initialize nic workqueue\n"); + kfree(nic_dev->vlan_bitmap); return -ENOMEM; } =20 @@ -335,6 +341,7 @@ static void hinic3_nic_event(struct auxiliary_device *a= dev, static void hinic3_free_nic_dev(struct hinic3_nic_dev *nic_dev) { destroy_workqueue(nic_dev->workq); + kfree(nic_dev->vlan_bitmap); } =20 static int hinic3_nic_probe(struct auxiliary_device *adev, diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h b/d= rivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h index 69405715e734..60f47152c01d 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h @@ -56,6 +56,15 @@ struct l2nic_cmd_update_mac { u8 new_mac[ETH_ALEN]; }; =20 +struct l2nic_cmd_vlan_config { + struct mgmt_msg_head msg_head; + u16 func_id; + u8 opcode; + u8 rsvd1; + u16 vlan_id; + u16 rsvd2; +}; + struct l2nic_cmd_vlan_offload { struct mgmt_msg_head msg_head; u16 func_id; @@ -205,6 +214,7 @@ enum l2nic_cmd { L2NIC_CMD_SET_MAC =3D 21, L2NIC_CMD_DEL_MAC =3D 22, L2NIC_CMD_UPDATE_MAC =3D 23, + L2NIC_CMD_CFG_FUNC_VLAN =3D 25, L2NIC_CMD_SET_VLAN_FILTER_EN =3D 26, L2NIC_CMD_SET_RX_VLAN_OFFLOAD =3D 27, L2NIC_CMD_CFG_RSS =3D 60, diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drive= rs/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c index f7e6fbdec40b..1e298be6e0d1 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c @@ -15,6 +15,12 @@ #define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32 #define HINIC3_LRO_DEFAULT_TIME_LIMIT 16 =20 +#define VLAN_BITMAP_BITS_SIZE(nic_dev) (sizeof(*(nic_dev)->vlan_bitmap)= * 8) +#define VID_LINE(nic_dev, vid) \ + ((vid) / VLAN_BITMAP_BITS_SIZE(nic_dev)) +#define VID_COL(nic_dev, vid) \ + ((vid) & (VLAN_BITMAP_BITS_SIZE(nic_dev) - 1)) + /* try to modify the number of irq to the target number, * and return the actual number of irq. */ @@ -676,6 +682,59 @@ static int hinic3_set_mac_addr(struct net_device *netd= ev, void *addr) return 0; } =20 +static int hinic3_vlan_rx_add_vid(struct net_device *netdev, + __be16 proto, u16 vid) +{ + struct hinic3_nic_dev *nic_dev =3D netdev_priv(netdev); + unsigned long *vlan_bitmap =3D nic_dev->vlan_bitmap; + u32 column, row; + u16 func_id; + int err; + + column =3D VID_COL(nic_dev, vid); + row =3D VID_LINE(nic_dev, vid); + + func_id =3D hinic3_global_func_id(nic_dev->hwdev); + + err =3D hinic3_add_vlan(nic_dev->hwdev, vid, func_id); + if (err) { + netdev_err(netdev, "Failed to add vlan %u\n", vid); + goto out; + } + + set_bit(column, &vlan_bitmap[row]); + netdev_dbg(netdev, "Add vlan %u\n", vid); + +out: + return err; +} + +static int hinic3_vlan_rx_kill_vid(struct net_device *netdev, + __be16 proto, u16 vid) +{ + struct hinic3_nic_dev *nic_dev =3D netdev_priv(netdev); + unsigned long *vlan_bitmap =3D nic_dev->vlan_bitmap; + u32 column, row; + u16 func_id; + int err; + + column =3D VID_COL(nic_dev, vid); + row =3D VID_LINE(nic_dev, vid); + + func_id =3D hinic3_global_func_id(nic_dev->hwdev); + err =3D hinic3_del_vlan(nic_dev->hwdev, vid, func_id); + if (err) { + netdev_err(netdev, "Failed to delete vlan %u\n", vid); + goto out; + } + + clear_bit(column, &vlan_bitmap[row]); + netdev_dbg(netdev, "Remove vlan %u\n", vid); + +out: + return err; +} + static void hinic3_tx_timeout(struct net_device *netdev, unsigned int txqu= eue) { struct hinic3_nic_dev *nic_dev =3D netdev_priv(netdev); @@ -758,6 +817,9 @@ static const struct net_device_ops hinic3_netdev_ops = =3D { .ndo_fix_features =3D hinic3_fix_features, .ndo_change_mtu =3D hinic3_change_mtu, .ndo_set_mac_address =3D hinic3_set_mac_addr, + .ndo_validate_addr =3D eth_validate_addr, + .ndo_vlan_rx_add_vid =3D hinic3_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid =3D hinic3_vlan_rx_kill_vid, .ndo_tx_timeout =3D hinic3_tx_timeout, .ndo_get_stats64 =3D hinic3_get_stats64, .ndo_start_xmit =3D hinic3_xmit_frame, diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/= net/ethernet/huawei/hinic3/hinic3_nic_cfg.c index c8944c51e6bf..4a5356cf51a5 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c @@ -10,6 +10,9 @@ #include "hinic3_nic_dev.h" #include "hinic3_nic_io.h" =20 +#define MGMT_MSG_CMD_OP_ADD 1 +#define MGMT_MSG_CMD_OP_DEL 0 + static int hinic3_feature_nego(struct hinic3_hwdev *hwdev, u8 opcode, u64 *s_feature, u16 size) { @@ -496,6 +499,44 @@ int hinic3_force_drop_tx_pkt(struct hinic3_hwdev *hwde= v) return pkt_drop.msg_head.status; } =20 +static int hinic3_config_vlan(struct hinic3_hwdev *hwdev, + u8 opcode, u16 vlan_id, u16 func_id) +{ + struct l2nic_cmd_vlan_config vlan_info =3D {}; + struct mgmt_msg_params msg_params =3D {}; + int err; + + vlan_info.opcode =3D opcode; + vlan_info.func_id =3D func_id; + vlan_info.vlan_id =3D vlan_id; + + mgmt_msg_params_init_default(&msg_params, &vlan_info, + sizeof(vlan_info)); + + err =3D hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_L2NIC, + L2NIC_CMD_CFG_FUNC_VLAN, &msg_params); + + if (err || vlan_info.msg_head.status) { + dev_err(hwdev->dev, + "Failed to %s vlan, err: %d, status: 0x%x\n", + opcode =3D=3D MGMT_MSG_CMD_OP_ADD ? "add" : "delete", + err, vlan_info.msg_head.status); + return -EFAULT; + } + + return 0; +} + +int hinic3_add_vlan(struct hinic3_hwdev *hwdev, u16 vlan_id, u16 func_id) +{ + return hinic3_config_vlan(hwdev, MGMT_MSG_CMD_OP_ADD, vlan_id, func_id); +} + +int hinic3_del_vlan(struct hinic3_hwdev *hwdev, u16 vlan_id, u16 func_id) +{ + return hinic3_config_vlan(hwdev, MGMT_MSG_CMD_OP_DEL, vlan_id, func_id); +} + int hinic3_set_port_enable(struct hinic3_hwdev *hwdev, bool enable) { struct mag_cmd_set_port_enable en_state =3D {}; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/= net/ethernet/huawei/hinic3/hinic3_nic_cfg.h index a17cd56bce71..84831c87507b 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h @@ -83,5 +83,7 @@ int hinic3_set_port_enable(struct hinic3_hwdev *hwdev, bo= ol enable); int hinic3_get_link_status(struct hinic3_hwdev *hwdev, bool *link_status_u= p); int hinic3_set_vport_enable(struct hinic3_hwdev *hwdev, u16 func_id, bool enable); +int hinic3_add_vlan(struct hinic3_hwdev *hwdev, u16 vlan_id, u16 func_id); +int hinic3_del_vlan(struct hinic3_hwdev *hwdev, u16 vlan_id, u16 func_id); =20 #endif diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/= net/ethernet/huawei/hinic3/hinic3_nic_dev.h index a8e92e070d9e..6e48c29566e1 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h @@ -4,12 +4,17 @@ #ifndef _HINIC3_NIC_DEV_H_ #define _HINIC3_NIC_DEV_H_ =20 +#include #include =20 #include "hinic3_hw_cfg.h" #include "hinic3_hwdev.h" #include "hinic3_mgmt_interface.h" =20 +#define HINIC3_VLAN_BITMAP_BYTE_SIZE(nic_dev) (sizeof(*(nic_dev)->vlan_bi= tmap)) +#define HINIC3_VLAN_BITMAP_SIZE(nic_dev) \ + (VLAN_N_VID / HINIC3_VLAN_BITMAP_BYTE_SIZE(nic_dev)) + enum hinic3_flags { HINIC3_RSS_ENABLE, }; @@ -71,6 +76,7 @@ struct hinic3_nic_dev { u16 max_qps; u16 rx_buf_len; u32 lro_replenish_thld; + unsigned long *vlan_bitmap; unsigned long flags; struct hinic3_nic_service_cap nic_svc_cap; =20 --=20 2.43.0