From nobody Wed Sep 10 05:39:07 2025 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) (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 AFA74311594; Tue, 9 Sep 2025 07:34:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757403257; cv=none; b=Lw/wcEwANVvkYioo0M49ShFmKqOpa4Em6xhtGd8a1dcA0dJfOatdm2Gxrs2Wz3DGv09TOZScJ3v86SjZGtbe+uBMHe1PSOj0JJXZZ+EAoU3zo2KuyqZeq0aLtLrUpLlvNVYZHtkBAFPUXZQU8bAg8wOG6Rjzo0dmgk0Nz0CcgRw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757403257; c=relaxed/simple; bh=yF0bX13QiU9YmKsN+BFkUljpXOCWRF+Go0TMI2Xm9Dg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=cjG4MJbZetkvp/I3sFR/gEl7PLv0cziiXO4jhn8woyXP+G4rDYDYXgNSurC31MSLXNDmJKJ0GI2trdFe9wtgcbip9XSXTv2n7fc4fU7f0rlOIw9m2S31mNbP3tqYQ3ZuW2kdyGHbGRu6HMuM921b3InfFwJoyJqYLCs2dRhBKQg= 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; arc=none smtp.client-ip=45.249.212.188 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 Received: from mail.maildlp.com (unknown [172.19.163.174]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4cLb736hM0z5vM8; Tue, 9 Sep 2025 15:29:35 +0800 (CST) Received: from kwepemf100013.china.huawei.com (unknown [7.202.181.12]) by mail.maildlp.com (Postfix) with ESMTPS id B1C7014020C; Tue, 9 Sep 2025 15:34:12 +0800 (CST) Received: from DESKTOP-62GVMTR.china.huawei.com (10.174.189.55) 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; Tue, 9 Sep 2025 15:34:11 +0800 From: Fan Gong To: Fan Gong , Zhu Yikai CC: , , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Andrew Lunn , , Jonathan Corbet , Bjorn Helgaas , luosifu , Xin Guo , Shen Chenyang , Zhou Shuai , Wu Like , Shi Jing , Luo Yang , Meny Yossefi , Gur Stavi , Lee Trager , Michael Ellerman , Vadim Fedorenko , Suman Ghosh , Przemek Kitszel , Joe Damato , Christophe JAILLET Subject: [PATCH net-next v05 12/14] hinic3: Add port management Date: Tue, 9 Sep 2025 15:33:37 +0800 Message-ID: <9fa22ecd4b8dfe9ea613b0d81d2cabf7c233e7d2.1757401320.git.zhuyikai1@h-partners.com> 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: kwepems100002.china.huawei.com (7.221.188.206) To kwepemf100013.china.huawei.com (7.202.181.12) Content-Type: text/plain; charset="utf-8" Add port management of enable/disable/query/flush function. Co-developed-by: Zhu Yikai Signed-off-by: Zhu Yikai Signed-off-by: Fan Gong --- .../huawei/hinic3/hinic3_mgmt_interface.h | 29 ++++++++ .../huawei/hinic3/hinic3_netdev_ops.c | 60 ++++++++++++++++ .../ethernet/huawei/hinic3/hinic3_nic_cfg.c | 68 +++++++++++++++++++ .../ethernet/huawei/hinic3/hinic3_nic_cfg.h | 4 ++ 4 files changed, 161 insertions(+) diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h b/d= rivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h index 7012130bba1d..6cc0345c39e4 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h @@ -69,12 +69,27 @@ struct l2nic_cmd_set_ci_attr { u64 ci_addr; }; =20 +struct l2nic_cmd_clear_qp_resource { + struct mgmt_msg_head msg_head; + u16 func_id; + u16 rsvd1; +}; + struct l2nic_cmd_force_pkt_drop { struct mgmt_msg_head msg_head; u8 port; u8 rsvd1[3]; }; =20 +struct l2nic_cmd_set_vport_state { + struct mgmt_msg_head msg_head; + u16 func_id; + u16 rsvd1; + /* 0--disable, 1--enable */ + u8 state; + u8 rsvd2[3]; +}; + struct l2nic_cmd_set_dcb_state { struct mgmt_msg_head head; u16 func_id; @@ -172,6 +187,20 @@ enum l2nic_ucode_cmd { L2NIC_UCODE_CMD_SET_RSS_INDIR_TBL =3D 4, }; =20 +/* hilink mac group command */ +enum mag_cmd { + MAG_CMD_GET_LINK_STATUS =3D 7, +}; + +/* firmware also use this cmd report link event to driver */ +struct mag_cmd_get_link_status { + struct mgmt_msg_head head; + u8 port_id; + /* 0:link down 1:link up */ + u8 status; + u8 rsvd0[2]; +}; + enum hinic3_nic_feature_cap { HINIC3_NIC_F_CSUM =3D BIT(0), HINIC3_NIC_F_SCTP_CRC =3D BIT(1), diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drive= rs/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c index 3d17ca5e7ba5..a07fa4bd71e7 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c @@ -326,6 +326,59 @@ static void hinic3_close_channel(struct net_device *ne= tdev) hinic3_free_qp_ctxts(nic_dev); } =20 +static int hinic3_vport_up(struct net_device *netdev) +{ + struct hinic3_nic_dev *nic_dev =3D netdev_priv(netdev); + bool link_status_up; + u16 glb_func_id; + int err; + + glb_func_id =3D hinic3_global_func_id(nic_dev->hwdev); + err =3D hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, true); + if (err) { + netdev_err(netdev, "Failed to enable vport\n"); + goto err_flush_qps_res; + } + + err =3D netif_set_real_num_queues(netdev, nic_dev->q_params.num_qps, + nic_dev->q_params.num_qps); + if (err) { + netdev_err(netdev, "Failed to set real number of queues\n"); + goto err_flush_qps_res; + } + netif_tx_start_all_queues(netdev); + + err =3D hinic3_get_link_status(nic_dev->hwdev, &link_status_up); + if (!err && link_status_up) + netif_carrier_on(netdev); + + return 0; + +err_flush_qps_res: + hinic3_flush_qps_res(nic_dev->hwdev); + /* wait to guarantee that no packets will be sent to host */ + msleep(100); + + return err; +} + +static void hinic3_vport_down(struct net_device *netdev) +{ + struct hinic3_nic_dev *nic_dev =3D netdev_priv(netdev); + u16 glb_func_id; + + netif_carrier_off(netdev); + netif_tx_disable(netdev); + + glb_func_id =3D hinic3_global_func_id(nic_dev->hwdev); + hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false); + + hinic3_flush_txqs(netdev); + /* wait to guarantee that no packets will be sent to host */ + msleep(100); + hinic3_flush_qps_res(nic_dev->hwdev); +} + static int hinic3_open(struct net_device *netdev) { struct hinic3_nic_dev *nic_dev =3D netdev_priv(netdev); @@ -355,8 +408,14 @@ static int hinic3_open(struct net_device *netdev) if (err) goto err_uninit_qps; =20 + err =3D hinic3_vport_up(netdev); + if (err) + goto err_close_channel; + return 0; =20 +err_close_channel: + hinic3_close_channel(netdev); err_uninit_qps: hinic3_uninit_qps(nic_dev, &qp_params); hinic3_free_channel_resources(netdev, &qp_params, &nic_dev->q_params); @@ -373,6 +432,7 @@ static int hinic3_close(struct net_device *netdev) struct hinic3_nic_dev *nic_dev =3D netdev_priv(netdev); struct hinic3_dyna_qp_params qp_params; =20 + hinic3_vport_down(netdev); hinic3_close_channel(netdev); hinic3_uninit_qps(nic_dev, &qp_params); hinic3_free_channel_resources(netdev, &qp_params, &nic_dev->q_params); diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/= net/ethernet/huawei/hinic3/hinic3_nic_cfg.c index ed70750f5ae8..9349b8a314ae 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c @@ -267,6 +267,28 @@ int hinic3_set_ci_table(struct hinic3_hwdev *hwdev, st= ruct hinic3_sq_attr *attr) return 0; } =20 +int hinic3_flush_qps_res(struct hinic3_hwdev *hwdev) +{ + struct l2nic_cmd_clear_qp_resource sq_res =3D {}; + struct mgmt_msg_params msg_params =3D {}; + int err; + + sq_res.func_id =3D hinic3_global_func_id(hwdev); + + mgmt_msg_params_init_default(&msg_params, &sq_res, sizeof(sq_res)); + + err =3D hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_L2NIC, + L2NIC_CMD_CLEAR_QP_RESOURCE, + &msg_params); + if (err || sq_res.msg_head.status) { + dev_err(hwdev->dev, "Failed to clear sq resources, err: %d, status: 0x%x= \n", + err, sq_res.msg_head.status); + return -EINVAL; + } + + return 0; +} + int hinic3_force_drop_tx_pkt(struct hinic3_hwdev *hwdev) { struct l2nic_cmd_force_pkt_drop pkt_drop =3D {}; @@ -314,3 +336,49 @@ int hinic3_sync_dcb_state(struct hinic3_hwdev *hwdev, = u8 op_code, u8 state) =20 return 0; } + +int hinic3_get_link_status(struct hinic3_hwdev *hwdev, bool *link_status_u= p) +{ + struct mag_cmd_get_link_status get_link =3D {}; + struct mgmt_msg_params msg_params =3D {}; + int err; + + get_link.port_id =3D hinic3_physical_port_id(hwdev); + + mgmt_msg_params_init_default(&msg_params, &get_link, sizeof(get_link)); + + err =3D hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_HILINK, + MAG_CMD_GET_LINK_STATUS, &msg_params); + if (err || get_link.head.status) { + dev_err(hwdev->dev, "Failed to get link state, err: %d, status: 0x%x\n", + err, get_link.head.status); + return -EIO; + } + + *link_status_up =3D !!get_link.status; + + return 0; +} + +int hinic3_set_vport_enable(struct hinic3_hwdev *hwdev, u16 func_id, + bool enable) +{ + struct l2nic_cmd_set_vport_state en_state =3D {}; + struct mgmt_msg_params msg_params =3D {}; + int err; + + en_state.func_id =3D func_id; + en_state.state =3D enable ? 1 : 0; + + mgmt_msg_params_init_default(&msg_params, &en_state, sizeof(en_state)); + + err =3D hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_L2NIC, + L2NIC_CMD_SET_VPORT_ENABLE, &msg_params); + if (err || en_state.msg_head.status) { + dev_err(hwdev->dev, "Failed to set vport state, err: %d, status: 0x%x\n", + err, en_state.msg_head.status); + return -EINVAL; + } + + return 0; +} diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/= net/ethernet/huawei/hinic3/hinic3_nic_cfg.h index 719b81e2bc2a..b83b567fa542 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h @@ -50,8 +50,12 @@ int hinic3_update_mac(struct hinic3_hwdev *hwdev, const = u8 *old_mac, =20 int hinic3_set_ci_table(struct hinic3_hwdev *hwdev, struct hinic3_sq_attr *attr); +int hinic3_flush_qps_res(struct hinic3_hwdev *hwdev); int hinic3_force_drop_tx_pkt(struct hinic3_hwdev *hwdev); =20 int hinic3_sync_dcb_state(struct hinic3_hwdev *hwdev, u8 op_code, u8 state= ); +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); =20 #endif --=20 2.43.0