From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
The patch supports the function of disabling and status query of lane channels on a port. The patch traverses all covered lanes on the port and powers off the serdes ds power.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 2 + .../net/ethernet/hisilicon/hns3/hns3_ext.c | 13 ++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 2 + .../hisilicon/hns3/hns3pf/hclge_ext.c | 45 +++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 1 + 5 files changed, 63 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 54aab1270953..d7ab4449c031 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -41,6 +41,8 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_GET_PORT_NUM, HNAE3_EXT_OPC_GET_PRESENT, HNAE3_EXT_OPC_SET_SFP_STATE, + HNAE3_EXT_OPC_DISABLE_LANE, + HNAE3_EXT_OPC_GET_LANE_STATUS, };
struct hnae3_pfc_storm_para { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index 77f359f2a205..7eeeabc79bc9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -419,3 +419,16 @@ int nic_set_sfp_state(struct net_device *ndev, bool en) &state, sizeof(state)); } EXPORT_SYMBOL(nic_set_sfp_state); + +int nic_disable_net_lane(struct net_device *ndev) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_DISABLE_LANE, NULL, 0); +} +EXPORT_SYMBOL(nic_disable_net_lane); + +int nic_get_net_lane_status(struct net_device *ndev, u32 *status) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_GET_LANE_STATUS, + status, sizeof(*status)); +} +EXPORT_SYMBOL(nic_get_net_lane_status); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index cbf993691c92..7254ff23558c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -39,4 +39,6 @@ int nic_get_port_num_per_chip(struct net_device *ndev, u32 *port_num); int nic_set_tx_timeout(struct net_device *ndev, int tx_timeout); int nic_get_sfp_present(struct net_device *ndev, int *present); int nic_set_sfp_state(struct net_device *ndev, bool en); +int nic_disable_net_lane(struct net_device *ndev); +int nic_get_net_lane_status(struct net_device *ndev, u32 *status); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index 5d58780f7c74..4bc6216d2d8c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -491,6 +491,49 @@ static int hclge_set_sfp_state(struct hclge_dev *hdev, void *data, return ret; }
+static int hclge_set_net_lane_status(struct hclge_dev *hdev, + u32 enable) +{ + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_DISABLE_NET_LANE, false); + desc.data[0] = cpu_to_le32(enable); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to set net lane status, ret = %d\n", ret); + + return ret; +} + +static int hclge_disable_net_lane(struct hclge_dev *hdev, void *data, + size_t length) +{ + return hclge_set_net_lane_status(hdev, 0); +} + +static int hclge_get_net_lane_status(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_desc desc; + int ret; + + if (length != sizeof(u32)) + return -EINVAL; + + ret = hclge_get_info_from_cmd(hdev, &desc, 1, HCLGE_OPC_DISABLE_NET_LANE); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get net lane status, ret = %d\n", ret); + return ret; + } + + *(u32 *)data = le32_to_cpu(desc.data[0]); + return 0; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -655,6 +698,8 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_GET_PORT_NUM] = hclge_get_port_num, [HNAE3_EXT_OPC_GET_PRESENT] = hclge_get_sfp_present, [HNAE3_EXT_OPC_SET_SFP_STATE] = hclge_set_sfp_state, + [HNAE3_EXT_OPC_DISABLE_LANE] = hclge_disable_net_lane, + [HNAE3_EXT_OPC_GET_LANE_STATUS] = hclge_get_net_lane_status, };
int hclge_ext_ops_handle(struct hnae3_handle *handle, int opcode, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h index 607bd1668cdc..06b3d9c494f4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -91,6 +91,7 @@ enum hclge_ext_opcode_type { HCLGE_OPC_CHIP_ID_GET = 0x7003, HCLGE_OPC_GET_CHIP_NUM = 0x7005, HCLGE_OPC_GET_PORT_NUM = 0x7006, + HCLGE_OPC_DISABLE_NET_LANE = 0x7008, HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019, HCLGE_OPC_SFP_GET_PRESENT = 0x7101, HCLGE_OPC_SFP_SET_STATUS = 0x7102,