From: Jiantao Xiao xiaojiantao1@h-partners.com
Hao Chen (2): net: hns3: add support to get/set 1d torus param net: hns3: add support modified tx timeout
Jian Shen (2): net: hns3: add extend interface support for read and write phy register net: hns3: add input parameters checking
Jie Wang (1): net: hns3: add support PF provides customized interfaces to detect port faults.
shaojijie (13): net: hns3: add support customized exception handling interfaces. net: hns3: add supports pfc storm detection and suppression net: hns3: add supports fast reporting of faulty nodes net: hns3: add support clear mac statistics net: hns3: add support configuring function-level interrupt affinity net: hns3: add support query port ext information net: hns3: add support query the presence of optical module net: hns3: add supports configure optical module enable net: hns3: add support config and query serdes lane status net: hns3: add support disable nic clock net: hns3: support set pfc pause trans time net: hns3: add support detect port wire type net: hns3: add support set led
wangpeiyang (1): net: hns3: add support set mac state
drivers/net/ethernet/hisilicon/hns3/Makefile | 3 +- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 7 + .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 121 ++ .../hns3/hns3_common/hclge_comm_cmd.c | 1 + .../hns3/hns3_common/hclge_comm_cmd.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_enet.c | 7 +- .../net/ethernet/hisilicon/hns3/hns3_ext.c | 543 ++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 67 + .../hisilicon/hns3/hns3pf/hclge_cmd.h | 14 +- .../hisilicon/hns3/hns3pf/hclge_ext.c | 1490 +++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 180 ++ .../hisilicon/hns3/hns3pf/hclge_main.c | 58 +- .../hisilicon/hns3/hns3pf/hclge_main.h | 12 +- .../hisilicon/hns3/hns3pf/hclge_mbx.c | 2 +- .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 7 +- .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 2 + 16 files changed, 2488 insertions(+), 27 deletions(-) create mode 100644 drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3_ext.c create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3_ext.h create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
Establish a framework to support customization requirement. Provides interfaces to register special processing functions. When the system is reset due to an abnormal interrupt, the registered handler is called first.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- drivers/net/ethernet/hisilicon/hns3/Makefile | 3 +- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 2 + .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 33 ++++ .../net/ethernet/hisilicon/hns3/hns3_enet.c | 7 +- .../net/ethernet/hisilicon/hns3/hns3_ext.c | 75 ++++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 13 ++ .../hisilicon/hns3/hns3pf/hclge_ext.c | 177 ++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 43 +++++ .../hisilicon/hns3/hns3pf/hclge_main.c | 43 +++-- .../hisilicon/hns3/hns3pf/hclge_main.h | 6 +- .../hisilicon/hns3/hns3pf/hclge_mbx.c | 2 +- 11 files changed, 387 insertions(+), 17 deletions(-) create mode 100644 drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3_ext.c create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3_ext.h create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h
diff --git a/drivers/net/ethernet/hisilicon/hns3/Makefile b/drivers/net/ethernet/hisilicon/hns3/Makefile index e214bfaece1f..cc9158097e93 100644 --- a/drivers/net/ethernet/hisilicon/hns3/Makefile +++ b/drivers/net/ethernet/hisilicon/hns3/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_HNS3) += hnae3.o
obj-$(CONFIG_HNS3_ENET) += hns3.o hns3-objs = hns3_enet.o hns3_ethtool.o hns3_debugfs.o +hns3-objs += hns3_ext.o
hns3-$(CONFIG_HNS3_DCB) += hns3_dcbnl.o
@@ -24,6 +25,6 @@ obj-$(CONFIG_HNS3_HCLGE) += hclge.o hclge-objs = hns3pf/hclge_main.o hns3pf/hclge_mdio.o hns3pf/hclge_tm.o hns3pf/hclge_regs.o \ hns3pf/hclge_mbx.o hns3pf/hclge_err.o hns3pf/hclge_debugfs.o hns3pf/hclge_ptp.o hns3pf/hclge_devlink.o \ hns3_common/hclge_comm_cmd.o hns3_common/hclge_comm_rss.o hns3_common/hclge_comm_tqp_stats.o - +hclge-objs += hns3pf/hclge_ext.o
hclge-$(CONFIG_HNS3_DCB) += hns3pf/hclge_dcb.o diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index d7e175a9cb49..9b98dea8a590 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -782,6 +782,8 @@ struct hnae3_ae_ops { struct ethtool_wolinfo *wol); int (*set_wol)(struct hnae3_handle *handle, struct ethtool_wolinfo *wol); + int (*priv_ops)(struct hnae3_handle *handle, int opcode, + void *data, size_t length); };
struct hnae3_dcb_ops { diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h new file mode 100644 index 000000000000..f2ffc6f1b989 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +// Copyright (c) 2023 Hisilicon Limited. + +#ifndef __HNAE3_EXT_H +#define __HNAE3_EXT_H + +enum hnae3_event_type_custom { + HNAE3_VF_RESET_CUSTOM, + HNAE3_VF_FUNC_RESET_CUSTOM, + HNAE3_VF_PF_FUNC_RESET_CUSTOM, + HNAE3_VF_FULL_RESET_CUSTOM, + HNAE3_FLR_RESET_CUSTOM, + HNAE3_FUNC_RESET_CUSTOM, + HNAE3_GLOBAL_RESET_CUSTOM, + HNAE3_IMP_RESET_CUSTOM, + HNAE3_UNKNOWN_RESET_CUSTOM, + HNAE3_NONE_RESET_CUSTOM, + HNAE3_PORT_FAULT, + HNAE3_RESET_DONE_CUSTOM, + HNAE3_FUNC_RESET_FAIL_CUSTOM, + HNAE3_GLOBAL_RESET_FAIL_CUSTOM, + HNAE3_IMP_RESET_FAIL_CUSTOM, + HNAE3_PPU_POISON_CUSTOM, + HNAE3_IMP_RD_POISON_CUSTOM, + HNAE3_ROCEE_AXI_RESP_CUSTOM, + HNAE3_INVALID_EVENT_CUSTOM, +}; + +enum hnae3_ext_opcode { + HNAE3_EXT_OPC_RESET, + HNAE3_EXT_OPC_EVENT_CALLBACK, +}; +#endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 677cfaa5fe08..de509ae0b185 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -26,6 +26,7 @@ #include <net/geneve.h>
#include "hnae3.h" +#include "hnae3_ext.h" #include "hns3_enet.h" /* All hns3 tracepoints are defined by the include below, which * must be included exactly once across the whole kernel with @@ -5943,12 +5944,16 @@ static void hns3_process_hw_error(struct hnae3_handle *handle, if (hns3_hw_err[i].type == type) { dev_err(&handle->pdev->dev, "Detected %s!\n", hns3_hw_err[i].msg); + if (handle->ae_algo->ops->priv_ops) + handle->ae_algo->ops->priv_ops(handle, + HNAE3_EXT_OPC_EVENT_CALLBACK, &type, + sizeof(type)); break; } } }
-static const struct hnae3_client_ops client_ops = { +const struct hnae3_client_ops client_ops = { .init_instance = hns3_client_init, .uninit_instance = hns3_client_uninit, .link_status_change = hns3_link_status_change, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c new file mode 100644 index 000000000000..d8264b6e48b4 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2023 Hisilicon Limited. + +#include "hns3_ext.h" + +int nic_netdev_match_check(struct net_device *ndev) +{ +#define HNS3_DRIVER_NAME_LEN 5 + + struct ethtool_drvinfo drv_info; + struct hnae3_handle *h; + + if (!ndev || !ndev->ethtool_ops || + !ndev->ethtool_ops->get_drvinfo) + return -EINVAL; + + ndev->ethtool_ops->get_drvinfo(ndev, &drv_info); + + if (strncmp(drv_info.driver, "hns3", HNS3_DRIVER_NAME_LEN)) + return -EINVAL; + + h = hns3_get_handle(ndev); + if (h->flags & HNAE3_SUPPORT_VF) + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL(nic_netdev_match_check); + +static int nic_invoke_pri_ops(struct net_device *ndev, int opcode, + void *data, size_t length) + +{ + struct hnae3_handle *h; + int ret; + + if ((!data && length) || (data && !length)) { + netdev_err(ndev, "failed to check data and length"); + return -EINVAL; + } + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + h = hns3_get_handle(ndev); + if (!h->ae_algo->ops->priv_ops) + return -EOPNOTSUPP; + + ret = h->ae_algo->ops->priv_ops(h, opcode, data, length); + if (ret) + netdev_err(ndev, + "failed to invoke pri ops, opcode = %#x, ret = %d\n", + opcode, ret); + + return ret; +} + +void nic_chip_recover_handler(struct net_device *ndev, + enum hnae3_event_type_custom event_t) +{ + dev_info(&ndev->dev, "reset type is %d!!\n", event_t); + + if (event_t == HNAE3_PPU_POISON_CUSTOM) + event_t = HNAE3_FUNC_RESET_CUSTOM; + + if (event_t != HNAE3_FUNC_RESET_CUSTOM && + event_t != HNAE3_GLOBAL_RESET_CUSTOM && + event_t != HNAE3_IMP_RESET_CUSTOM) { + dev_err(&ndev->dev, "reset type err!!\n"); + return; + } + + nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_RESET, &event_t, sizeof(event_t)); +} +EXPORT_SYMBOL(nic_chip_recover_handler); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h new file mode 100644 index 000000000000..ce92a666db17 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2023 Hisilicon Limited. */ + +#ifndef __HNS3_EXT_H +#define __HNS3_EXT_H +#include <linux/types.h> +#include "hns3_enet.h" +#include "hnae3_ext.h" + +int nic_netdev_match_check(struct net_device *netdev); +void nic_chip_recover_handler(struct net_device *ndev, + enum hnae3_event_type_custom event_t); +#endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c new file mode 100644 index 000000000000..e6b8b6acb025 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2023 Hisilicon Limited. + +#include "hclge_main.h" +#include "hnae3.h" +#include "hnae3_ext.h" +#include "hclge_cmd.h" +#include "hclge_ext.h" + +static nic_event_fn_t nic_event_call; + +/* We use a lock to ensure that the address of the nic_event_call function + * is valid when it is called. Avoid null pointer exceptions caused by + * external unregister during invoking. + */ +static DEFINE_MUTEX(hclge_nic_event_lock); + +static int hclge_set_reset_task(struct hclge_dev *hdev, void *data, + size_t length) +{ + u32 *reset_level = (u32 *)data; + + if (length != sizeof(u32)) + return -EINVAL; + + dev_warn(&hdev->pdev->dev, "reset level is %u\n", *reset_level); + + /* request reset & schedule reset task */ + set_bit(*reset_level, &hdev->reset_request); + hclge_reset_task_schedule(hdev); + return 0; +} + +int hclge_ext_call_event(struct hclge_dev *hdev, + enum hnae3_event_type_custom event_t) +{ + if (event_t >= HNAE3_INVALID_EVENT_CUSTOM) + return -EINVAL; + + mutex_lock(&hclge_nic_event_lock); + if (!nic_event_call) { + mutex_unlock(&hclge_nic_event_lock); + return -EOPNOTSUPP; + } + + nic_event_call(hdev->vport[0].nic.netdev, event_t); + mutex_unlock(&hclge_nic_event_lock); + return 0; +} + +int nic_register_event(nic_event_fn_t event_call) +{ + if (!event_call) { + pr_err("hns3: register event handle is null\n"); + return -EINVAL; + } + + mutex_lock(&hclge_nic_event_lock); + if (nic_event_call) { + mutex_unlock(&hclge_nic_event_lock); + pr_err("hns3: event already register\n"); + return -EBUSY; + } + + nic_event_call = event_call; + + mutex_unlock(&hclge_nic_event_lock); + pr_info("hns3: event register success\n"); + return 0; +} +EXPORT_SYMBOL(nic_register_event); + +int nic_unregister_event(void) +{ + mutex_lock(&hclge_nic_event_lock); + nic_event_call = NULL; + + mutex_unlock(&hclge_nic_event_lock); + pr_info("hns3: event unregister success\n"); + return 0; +} +EXPORT_SYMBOL(nic_unregister_event); + +static int hclge_nic_call_event(struct hclge_dev *hdev, void *data, + size_t length) +{ +#define ERROR_EVENT_TYPE_NUM 4 + + u32 event_type[ERROR_EVENT_TYPE_NUM] = { + HNAE3_PPU_POISON_CUSTOM, + HNAE3_IMP_RESET_CUSTOM, + HNAE3_IMP_RD_POISON_CUSTOM, + HNAE3_ROCEE_AXI_RESP_CUSTOM, + }; + u32 *index = (u32 *)data; + + if (length != sizeof(u32)) + return -EINVAL; + + if ((*index) >= ERROR_EVENT_TYPE_NUM) + return 0; + + return hclge_ext_call_event(hdev, event_type[*index]); +} + +static enum hnae3_event_type_custom +hclge_get_reset_fail_type(enum hnae3_reset_type reset_type) +{ + const struct hclge_reset_fail_type_map fail_type_map[] = { + {HNAE3_FUNC_RESET, HNAE3_FUNC_RESET_FAIL_CUSTOM}, + {HNAE3_GLOBAL_RESET, HNAE3_GLOBAL_RESET_FAIL_CUSTOM}, + {HNAE3_IMP_RESET, HNAE3_IMP_RESET_FAIL_CUSTOM}, + }; + u32 i; + + for (i = 0; i < ARRAY_SIZE(fail_type_map); i++) + if (fail_type_map[i].reset_type == reset_type) + return fail_type_map[i].custom_type; + + return HNAE3_INVALID_EVENT_CUSTOM; +} + +static void hclge_report_reset_fail_custom(struct hclge_dev *hdev) +{ +#define HCLGE_RESET_MAX_FAIL_CNT_CUSTOM 1 + + u32 max_fail_custom_cnt = HCLGE_RESET_MAX_FAIL_CNT; + + mutex_lock(&hclge_nic_event_lock); + if (nic_event_call) + max_fail_custom_cnt = HCLGE_RESET_MAX_FAIL_CNT_CUSTOM; + mutex_unlock(&hclge_nic_event_lock); + + if (hdev->rst_stats.reset_fail_cnt < max_fail_custom_cnt) + return; + + dev_err(&hdev->pdev->dev, "failed to report reset!\n"); + hclge_ext_call_event(hdev, hclge_get_reset_fail_type(hdev->reset_type)); +} + +void hclge_ext_reset_end(struct hclge_dev *hdev, bool done) +{ + if (!done) { + hclge_report_reset_fail_custom(hdev); + return; + } + + hclge_ext_call_event(hdev, HNAE3_RESET_DONE_CUSTOM); + dev_info(&hdev->pdev->dev, "report reset done!\n"); +} + +static const hclge_priv_ops_fn hclge_ext_func_arr[] = { + [HNAE3_EXT_OPC_RESET] = hclge_set_reset_task, + [HNAE3_EXT_OPC_EVENT_CALLBACK] = hclge_nic_call_event, +}; + +int hclge_ext_ops_handle(struct hnae3_handle *handle, int opcode, + void *data, size_t length) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + int cmd_num = ARRAY_SIZE(hclge_ext_func_arr); + struct hclge_dev *hdev = vport->back; + hclge_priv_ops_fn ext_opcode_func; + + if (opcode >= cmd_num) { + dev_err(&hdev->pdev->dev, "invalid opcode %d\n", opcode); + return -EINVAL; + } + + ext_opcode_func = hclge_ext_func_arr[opcode]; + if (!ext_opcode_func) { + dev_err(&hdev->pdev->dev, "unsupported opcode %d\n", opcode); + return -EOPNOTSUPP; + } + + return ext_opcode_func(hdev, data, length); +} diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h new file mode 100644 index 000000000000..1c1b04765e7e --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2016-2017 Hisilicon Limited. */ + +#ifndef __HCLGE_EXT_H +#define __HCLGE_EXT_H +#include <linux/types.h> + +struct hclge_reset_fail_type_map { + enum hnae3_reset_type reset_type; + enum hnae3_event_type_custom custom_type; +}; + +typedef int (*hclge_priv_ops_fn)(struct hclge_dev *hdev, void *data, + size_t length); + +/** + * nic_event_fn_t - nic event handler prototype + * @netdev: net device + * @hnae3_event_type_custom: nic device event type + */ +typedef void (*nic_event_fn_t) (struct net_device *netdev, + enum hnae3_event_type_custom); + +/** + * nic_register_event - register for nic event handling + * @event_call: nic event handler + * return 0 - success , negative - fail + */ +int nic_register_event(nic_event_fn_t event_call); + +/** + * nic_unregister_event - unregister for nic event handling + * return 0 - success , negative - fail + */ +int nic_unregister_event(void); + +int hclge_ext_call_event(struct hclge_dev *hdev, + enum hnae3_event_type_custom event_t); +void hclge_ext_reset_end(struct hclge_dev *hdev, bool done); + +int hclge_ext_ops_handle(struct hnae3_handle *handle, int opcode, + void *data, size_t length); +#endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 5ea9e59569ef..5179aa769a4f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -17,6 +17,7 @@ #include <net/rtnetlink.h> #include "hclge_cmd.h" #include "hclge_dcb.h" +#include "hclge_ext.h" #include "hclge_main.h" #include "hclge_mbx.h" #include "hclge_mdio.h" @@ -36,7 +37,6 @@ #define BUF_MAX_PERCENT 100 #define BUF_RESERVE_PERCENT 90
-#define HCLGE_RESET_MAX_FAIL_CNT 5 #define HCLGE_RESET_SYNC_TIME 100 #define HCLGE_PF_RESET_SYNC_TIME 20 #define HCLGE_PF_RESET_SYNC_CNT 1500 @@ -62,6 +62,7 @@ static void hclge_update_fec_stats(struct hclge_dev *hdev); static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret, int wait_cnt); static int hclge_update_port_info(struct hclge_dev *hdev); +static void hclge_reset_end(struct hnae3_handle *handle, bool done);
static struct hnae3_ae_algo ae_algo;
@@ -2937,7 +2938,7 @@ static void hclge_mbx_task_schedule(struct hclge_dev *hdev) } }
-static void hclge_reset_task_schedule(struct hclge_dev *hdev) +void hclge_reset_task_schedule(struct hclge_dev *hdev) { if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) && test_bit(HCLGE_STATE_SERVICE_INITED, &hdev->state) && @@ -4140,7 +4141,7 @@ static void hclge_show_rst_info(struct hclge_dev *hdev)
static bool hclge_reset_err_handle(struct hclge_dev *hdev) { -#define MAX_RESET_FAIL_CNT 5 + struct hnae3_handle *handle = &hdev->vport[0].nic;
if (hdev->reset_pending) { dev_info(&hdev->pdev->dev, "Reset pending %lu\n", @@ -4152,7 +4153,7 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev) "reset failed because new reset interrupt\n"); hclge_clear_reset_cause(hdev); return false; - } else if (hdev->rst_stats.reset_fail_cnt < MAX_RESET_FAIL_CNT) { + } else if (hdev->rst_stats.reset_fail_cnt < HCLGE_RESET_MAX_FAIL_CNT) { hdev->rst_stats.reset_fail_cnt++; set_bit(hdev->reset_type, &hdev->reset_pending); dev_info(&hdev->pdev->dev, @@ -4166,7 +4167,7 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev) /* recover the handshake status when reset fail */ hclge_reset_handshake(hdev, true);
- dev_err(&hdev->pdev->dev, "Reset fail!\n"); + hclge_reset_end(handle, false);
hclge_show_rst_info(hdev);
@@ -4283,6 +4284,7 @@ static int hclge_reset_prepare(struct hclge_dev *hdev)
static int hclge_reset_rebuild(struct hclge_dev *hdev) { + struct hnae3_handle *handle = &hdev->vport[0].nic; int ret;
hdev->rst_stats.hw_reset_done_cnt++; @@ -4328,6 +4330,8 @@ static int hclge_reset_rebuild(struct hclge_dev *hdev)
hclge_update_reset_level(hdev);
+ hclge_reset_end(handle, true); + return 0; }
@@ -4349,10 +4353,11 @@ static void hclge_reset(struct hclge_dev *hdev) hclge_reset_task_schedule(hdev); }
-static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle) +void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle) { struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); struct hclge_dev *hdev = ae_dev->priv; + int ret;
/* We might end up getting called broadly because of 2 below cases: * 1. Recoverable error was conveyed through APEI and only way to bring @@ -4386,9 +4391,12 @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle) dev_info(&hdev->pdev->dev, "received reset event, reset type is %d\n", hdev->reset_level);
- /* request reset & schedule reset task */ - set_bit(hdev->reset_level, &hdev->reset_request); - hclge_reset_task_schedule(hdev); + ret = hclge_ext_call_event(hdev, hdev->reset_level); + if (ret) { + /* request reset & schedule reset task */ + set_bit(hdev->reset_level, &hdev->reset_request); + hclge_reset_task_schedule(hdev); + }
if (hdev->reset_level < HNAE3_GLOBAL_RESET) hdev->reset_level++; @@ -4414,7 +4422,15 @@ static void hclge_reset_timer(struct timer_list *t)
dev_info(&hdev->pdev->dev, "triggering reset in reset timer\n"); - hclge_reset_event(hdev->pdev, NULL); + hclge_reset_event(hdev->pdev, &hdev->vport[0].nic); +} + +static void hclge_reset_end(struct hnae3_handle *handle, bool done) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + + hclge_ext_reset_end(hdev, done); }
static void hclge_reset_subtask(struct hclge_dev *hdev) @@ -4454,8 +4470,8 @@ static void hclge_handle_err_reset_request(struct hclge_dev *hdev) hclge_set_def_reset_request(ae_dev, reset_type); }
- if (hdev->default_reset_request && ae_dev->ops->reset_event) - ae_dev->ops->reset_event(hdev->pdev, NULL); + if (hdev->default_reset_request) + hclge_reset_event(hdev->pdev, &hdev->vport[0].nic);
/* enable interrupt after error handling complete */ hclge_enable_vector(&hdev->misc_vector, true); @@ -12649,7 +12665,7 @@ static int hclge_get_dscp_prio(struct hnae3_handle *h, u8 dscp, u8 *tc_mode, return 0; }
-static const struct hnae3_ae_ops hclge_ops = { +struct hnae3_ae_ops hclge_ops = { .init_ae_dev = hclge_init_ae_dev, .uninit_ae_dev = hclge_uninit_ae_dev, .reset_prepare = hclge_reset_prepare_general, @@ -12755,6 +12771,7 @@ static const struct hnae3_ae_ops hclge_ops = { .get_dscp_prio = hclge_get_dscp_prio, .get_wol = hclge_get_wol, .set_wol = hclge_set_wol, + .priv_ops = hclge_ext_ops_handle, };
static struct hnae3_ae_algo ae_algo = { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 51979cf71262..e96f049df20f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -12,7 +12,7 @@
#include "hclge_cmd.h" #include "hclge_ptp.h" -#include "hnae3.h" +#include "hnae3_ext.h" #include "hclge_comm_rss.h" #include "hclge_comm_tqp_stats.h"
@@ -26,6 +26,8 @@ #define HCLGE_RD_FIRST_STATS_NUM 2 #define HCLGE_RD_OTHER_STATS_NUM 4
+#define HCLGE_RESET_MAX_FAIL_CNT 5 + #define HCLGE_INVALID_VPORT 0xffff
#define HCLGE_PF_CFG_BLOCK_SIZE 32 @@ -1160,4 +1162,6 @@ int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en); int hclge_mac_update_stats(struct hclge_dev *hdev); struct hclge_vport *hclge_get_vf_vport(struct hclge_dev *hdev, int vf); int hclge_inform_vf_reset(struct hclge_vport *vport, u16 reset_type); +void hclge_reset_task_schedule(struct hclge_dev *hdev); +void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index 4b0d07ca2505..c71e0123c3ad 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -811,7 +811,7 @@ static void hclge_handle_ncsi_error(struct hclge_dev *hdev)
ae_dev->ops->set_default_reset_request(ae_dev, HNAE3_GLOBAL_RESET); dev_warn(&hdev->pdev->dev, "requesting reset due to NCSI error\n"); - ae_dev->ops->reset_event(hdev->pdev, NULL); + hclge_reset_event(hdev->pdev, &hdev->vport[0].nic); }
static void hclge_handle_vf_tbl(struct hclge_vport *vport,
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
To solve the problem of abnormal transmission of pauses or PFC frames, the IMP periodically checks the transmission and reception status of packets. If a pause frame storm occurs, the pause storm response of the MAC address is disabled for a period of time.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 10 +++ .../net/ethernet/hisilicon/hns3/hns3_ext.c | 70 +++++++++++++++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 11 +++ .../hisilicon/hns3/hns3pf/hclge_ext.c | 60 ++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 13 ++++ 5 files changed, 164 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index f2ffc6f1b989..769b85e0d072 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -29,5 +29,15 @@ enum hnae3_event_type_custom { enum hnae3_ext_opcode { HNAE3_EXT_OPC_RESET, HNAE3_EXT_OPC_EVENT_CALLBACK, + HNAE3_EXT_OPC_GET_PFC_STORM_PARA, + HNAE3_EXT_OPC_SET_PFC_STORM_PARA, +}; + +struct hnae3_pfc_storm_para { + u32 dir; + u32 enable; + u32 period_ms; + u32 times; + u32 recovery_period_ms; }; #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index d8264b6e48b4..0369a6029d30 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -73,3 +73,73 @@ void nic_chip_recover_handler(struct net_device *ndev, nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_RESET, &event_t, sizeof(event_t)); } EXPORT_SYMBOL(nic_chip_recover_handler); + +static int nic_check_pfc_storm_para(u32 dir, u32 enable, u32 period_ms, + u32 times, u32 recovery_period_ms) +{ + if ((dir != HNS3_PFC_STORM_PARA_DIR_RX && + dir != HNS3_PFC_STORM_PARA_DIR_TX) || + (enable != HNS3_PFC_STORM_PARA_DISABLE && + enable != HNS3_PFC_STORM_PARA_ENABLE)) + return -EINVAL; + + if (period_ms < HNS3_PFC_STORM_PARA_PERIOD_MIN || + period_ms > HNS3_PFC_STORM_PARA_PERIOD_MAX || + recovery_period_ms < HNS3_PFC_STORM_PARA_PERIOD_MIN || + recovery_period_ms > HNS3_PFC_STORM_PARA_PERIOD_MAX || + times <= 0) + return -EINVAL; + + return 0; +} + +int nic_set_pfc_storm_para(struct net_device *ndev, u32 dir, u32 enable, + u32 period_ms, u32 times, u32 recovery_period_ms) +{ + struct hnae3_pfc_storm_para para; + + if (nic_check_pfc_storm_para(dir, enable, period_ms, times, + recovery_period_ms)) { + dev_err(&ndev->dev, + "set pfc storm para failed because invalid input param.\n"); + return -EINVAL; + } + + para.dir = dir; + para.enable = enable; + para.period_ms = period_ms; + para.times = times; + para.recovery_period_ms = recovery_period_ms; + + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_PFC_STORM_PARA, + ¶, sizeof(para)); +} +EXPORT_SYMBOL(nic_set_pfc_storm_para); + +int nic_get_pfc_storm_para(struct net_device *ndev, u32 dir, u32 *enable, + u32 *period_ms, u32 *times, u32 *recovery_period_ms) +{ + struct hnae3_pfc_storm_para para; + int ret; + + if (!enable || !period_ms || !times || !recovery_period_ms || + (dir != HNS3_PFC_STORM_PARA_DIR_RX && + dir != HNS3_PFC_STORM_PARA_DIR_TX)) { + dev_err(&ndev->dev, + "get pfc storm para failed because invalid input param.\n"); + return -EINVAL; + } + + para.dir = dir; + ret = nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_GET_PFC_STORM_PARA, + ¶, sizeof(para)); + if (ret) + return ret; + + *enable = para.enable; + *period_ms = para.period_ms; + *times = para.times; + *recovery_period_ms = para.recovery_period_ms; + return 0; +} +EXPORT_SYMBOL(nic_get_pfc_storm_para); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index ce92a666db17..a0feac3cfc13 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -7,7 +7,18 @@ #include "hns3_enet.h" #include "hnae3_ext.h"
+#define HNS3_PFC_STORM_PARA_DIR_RX 0 +#define HNS3_PFC_STORM_PARA_DIR_TX 1 +#define HNS3_PFC_STORM_PARA_DISABLE 0 +#define HNS3_PFC_STORM_PARA_ENABLE 1 +#define HNS3_PFC_STORM_PARA_PERIOD_MIN 5 +#define HNS3_PFC_STORM_PARA_PERIOD_MAX 2000 + int nic_netdev_match_check(struct net_device *netdev); void nic_chip_recover_handler(struct net_device *ndev, enum hnae3_event_type_custom event_t); +int nic_set_pfc_storm_para(struct net_device *ndev, u32 dir, u32 enable, + u32 period_ms, u32 times, u32 recovery_period_ms); +int nic_get_pfc_storm_para(struct net_device *ndev, u32 dir, u32 *enable, + u32 *period_ms, u32 *times, u32 *recovery_period_ms); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index e6b8b6acb025..8451b446f6d6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -15,6 +15,64 @@ static nic_event_fn_t nic_event_call; */ static DEFINE_MUTEX(hclge_nic_event_lock);
+static int hclge_set_pfc_storm_para(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_pfc_storm_para_cmd *para_cmd; + struct hnae3_pfc_storm_para *para; + struct hclge_desc desc; + int ret; + + if (length != sizeof(struct hnae3_pfc_storm_para)) + return -EINVAL; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PAUSE_STORM_PARA, + false); + para = (struct hnae3_pfc_storm_para *)data; + para_cmd = (struct hclge_pfc_storm_para_cmd *)desc.data; + para_cmd->dir = cpu_to_le32(para->dir); + para_cmd->enable = cpu_to_le32(para->enable); + para_cmd->period_ms = cpu_to_le32(para->period_ms); + para_cmd->times = cpu_to_le32(para->times); + para_cmd->recovery_period_ms = cpu_to_le32(para->recovery_period_ms); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to set pfc storm para, ret = %d\n", ret); + return ret; +} + +static int hclge_get_pfc_storm_para(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_pfc_storm_para_cmd *para_cmd; + struct hnae3_pfc_storm_para *para; + struct hclge_desc desc; + int ret; + + if (length != sizeof(struct hnae3_pfc_storm_para)) + return -EINVAL; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PAUSE_STORM_PARA, true); + para = (struct hnae3_pfc_storm_para *)data; + para_cmd = (struct hclge_pfc_storm_para_cmd *)desc.data; + para_cmd->dir = cpu_to_le32(para->dir); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get pfc storm para, ret = %d\n", ret); + return ret; + } + + para->enable = le32_to_cpu(para_cmd->enable); + para->period_ms = le32_to_cpu(para_cmd->period_ms); + para->times = le32_to_cpu(para_cmd->times); + para->recovery_period_ms = le32_to_cpu(para_cmd->recovery_period_ms); + + return 0; +} + static int hclge_set_reset_task(struct hclge_dev *hdev, void *data, size_t length) { @@ -152,6 +210,8 @@ void hclge_ext_reset_end(struct hclge_dev *hdev, bool done) static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_RESET] = hclge_set_reset_task, [HNAE3_EXT_OPC_EVENT_CALLBACK] = hclge_nic_call_event, + [HNAE3_EXT_OPC_GET_PFC_STORM_PARA] = hclge_get_pfc_storm_para, + [HNAE3_EXT_OPC_SET_PFC_STORM_PARA] = hclge_set_pfc_storm_para, };
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 1c1b04765e7e..d87d6bb0e4c5 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -5,6 +5,19 @@ #define __HCLGE_EXT_H #include <linux/types.h>
+struct hclge_pfc_storm_para_cmd { + __le32 dir; + __le32 enable; + __le32 period_ms; + __le32 times; + __le32 recovery_period_ms; + __le32 rsv; +}; + +enum hclge_ext_opcode_type { + HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019, +}; + struct hclge_reset_fail_type_map { enum hnae3_reset_type reset_type; enum hnae3_event_type_custom custom_type;
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
Services are switched only when no response is received within 10 seconds. As a result, services cannot be switched quickly. Therefore, if the chip is not suspended, the NIC sends a specific message to notify other nodes of the event. In this way, the service switchover is performed quickly.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 4 + .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 10 ++ .../hns3/hns3_common/hclge_comm_cmd.c | 1 + .../hns3/hns3_common/hclge_comm_cmd.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_ext.c | 14 +++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 3 + .../hisilicon/hns3/hns3pf/hclge_ext.c | 98 +++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 16 +++ .../hisilicon/hns3/hns3pf/hclge_main.h | 1 + 9 files changed, 148 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 9b98dea8a590..a9f675b64d18 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -104,6 +104,7 @@ enum HNAE3_DEV_CAP_BITS { HNAE3_DEV_SUPPORT_WOL_B, HNAE3_DEV_SUPPORT_TM_FLUSH_B, HNAE3_DEV_SUPPORT_VF_FAULT_B, + HNAE3_DEV_SUPPORT_NOTIFY_PKT_B, };
#define hnae3_ae_dev_fd_supported(ae_dev) \ @@ -181,6 +182,9 @@ enum HNAE3_DEV_CAP_BITS { #define hnae3_ae_dev_vf_fault_supported(ae_dev) \ test_bit(HNAE3_DEV_SUPPORT_VF_FAULT_B, (ae_dev)->caps)
+#define hnae3_ae_dev_notify_pkt_supported(ae_dev) \ + test_bit(HNAE3_DEV_SUPPORT_NOTIFY_PKT_B, (ae_dev)->caps) + enum HNAE3_PF_CAP_BITS { HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B = 0, }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 769b85e0d072..274a79414f47 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -31,6 +31,8 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_EVENT_CALLBACK, HNAE3_EXT_OPC_GET_PFC_STORM_PARA, HNAE3_EXT_OPC_SET_PFC_STORM_PARA, + HNAE3_EXT_OPC_SET_NOTIFY_PARAM, + HNAE3_EXT_OPC_SET_NOTIFY_START, };
struct hnae3_pfc_storm_para { @@ -40,4 +42,12 @@ struct hnae3_pfc_storm_para { u32 times; u32 recovery_period_ms; }; + +struct hnae3_notify_pkt_param { + u32 ipg; /* inter-packet gap of sending, the unit is one cycle of clock */ + u16 num; /* packet number of sending */ + u8 enable; /* send enable, 0=Disable, 1=Enable */ + u8 init; /* initialization flag, product does not need to set value */ + u8 data[64]; /* note packet data */ +}; #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c index d92ad6082d8e..e629b1483a42 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c @@ -158,6 +158,7 @@ static const struct hclge_comm_caps_bit_map hclge_pf_cmd_caps[] = { {HCLGE_COMM_CAP_WOL_B, HNAE3_DEV_SUPPORT_WOL_B}, {HCLGE_COMM_CAP_TM_FLUSH_B, HNAE3_DEV_SUPPORT_TM_FLUSH_B}, {HCLGE_COMM_CAP_VF_FAULT_B, HNAE3_DEV_SUPPORT_VF_FAULT_B}, + {HCLGE_COMM_CAP_NOTIFY_PKT_B, HNAE3_DEV_SUPPORT_NOTIFY_PKT_B}, };
static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h index 533c19d25e4f..cbc5f8fc8788 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h @@ -352,6 +352,7 @@ enum HCLGE_COMM_CAP_BITS { HCLGE_COMM_CAP_VF_FAULT_B = 26, HCLGE_COMM_CAP_LANE_NUM_B = 27, HCLGE_COMM_CAP_WOL_B = 28, + HCLGE_COMM_CAP_NOTIFY_PKT_B = 29, HCLGE_COMM_CAP_TM_FLUSH_B = 31, };
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index 0369a6029d30..5b7183daba4c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -143,3 +143,17 @@ int nic_get_pfc_storm_para(struct net_device *ndev, u32 dir, u32 *enable, return 0; } EXPORT_SYMBOL(nic_get_pfc_storm_para); + +int nic_set_notify_pkt_param(struct net_device *ndev, + struct hnae3_notify_pkt_param *param) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_NOTIFY_PARAM, + param, sizeof(*param)); +} +EXPORT_SYMBOL(nic_set_notify_pkt_param); + +int nic_set_notify_pkt_start(struct net_device *ndev) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_NOTIFY_START, NULL, 0); +} +EXPORT_SYMBOL(nic_set_notify_pkt_start); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index a0feac3cfc13..d75fd9fecef1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -21,4 +21,7 @@ int nic_set_pfc_storm_para(struct net_device *ndev, u32 dir, u32 enable, u32 period_ms, u32 times, u32 recovery_period_ms); int nic_get_pfc_storm_para(struct net_device *ndev, u32 dir, u32 *enable, u32 *period_ms, u32 *times, u32 *recovery_period_ms); +int nic_set_notify_pkt_param(struct net_device *ndev, + struct hnae3_notify_pkt_param *param); +int nic_set_notify_pkt_start(struct net_device *ndev); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index 8451b446f6d6..80f0bb0d738c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -73,6 +73,101 @@ static int hclge_get_pfc_storm_para(struct hclge_dev *hdev, void *data, return 0; }
+static int hclge_notify_packet_para_cmd_send(struct hclge_dev *hdev, + struct hclge_notify_pkt_param_cmd *param_cmd) +{ +#define HCLGE_NOTIFY_PKT_DESC_NUM 4 + + struct hclge_desc desc[HCLGE_NOTIFY_PKT_DESC_NUM]; + u32 i, desc_data_len; + + desc_data_len = ARRAY_SIZE(desc[0].data); + for (i = 0; i < HCLGE_NOTIFY_PKT_DESC_NUM; i++) { + hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_SET_NOTIFY_PKT, + false); + if (i != HCLGE_NOTIFY_PKT_DESC_NUM - 1) + desc[i].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT); + } + + for (i = 0; i < HCLGE_NOTIFY_PKT_DESC_NUM * desc_data_len; i++) + desc[i / desc_data_len].data[i % desc_data_len] = + *((__le32 *)param_cmd + i); + + return hclge_cmd_send(&hdev->hw, desc, HCLGE_NOTIFY_PKT_DESC_NUM); +} + +static int hclge_set_notify_packet_para(struct hclge_dev *hdev, + void *data, size_t length) +{ + struct hnae3_notify_pkt_param *param = (struct hnae3_notify_pkt_param *)data; + struct hclge_notify_pkt_param_cmd param_cmd; + u32 i, pkt_cfg = 0; + int ret; + + if (length != sizeof(struct hnae3_notify_pkt_param)) + return -EINVAL; + + if (!hnae3_ae_dev_notify_pkt_supported(hdev->ae_dev)) + return -EOPNOTSUPP; + + if (param->enable) + pkt_cfg = HCLGE_NOTIFY_PARA_CFG_PKT_EN; + hnae3_set_field(pkt_cfg, HCLGE_NOTIFY_PARA_CFG_PKT_NUM_M, + HCLGE_NOTIFY_PARA_CFG_PKT_NUM_S, param->num); + + param_cmd.cfg = cpu_to_le32(pkt_cfg); + param_cmd.ipg = cpu_to_le32(param->ipg); + for (i = 0; i < ARRAY_SIZE(param_cmd.data); i++) + param_cmd.data[i] = cpu_to_le32(*((u32 *)param->data + i)); + + hnae3_set_bit(param_cmd.vld_cfg, 0, 1); + hnae3_set_bit(param_cmd.vld_ipg, 0, 1); + hnae3_set_bit(param_cmd.vld_data, 0, 1); + + ret = hclge_notify_packet_para_cmd_send(hdev, ¶m_cmd); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to set notify packet content, ret = %d\n", ret); + return ret; + } + + param->init = 1; + memcpy(&hdev->notify_param, param, sizeof(*param)); + return 0; +} + +static int hclge_set_notify_packet_start(struct hclge_dev *hdev, + void *data, size_t length) +{ + u32 pkt_cfg = HCLGE_NOTIFY_PARA_CFG_START_EN; + struct hclge_notify_pkt_param_cmd param_cmd; + int ret; + + if (!hnae3_ae_dev_notify_pkt_supported(hdev->ae_dev)) + return -EOPNOTSUPP; + + memset(¶m_cmd, 0, sizeof(param_cmd)); + param_cmd.cfg = cpu_to_le32(pkt_cfg); + hnae3_set_bit(param_cmd.vld_cfg, 0, 1); + + ret = hclge_notify_packet_para_cmd_send(hdev, ¶m_cmd); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to send notify packet, ret = %d\n", ret); + return ret; +} + +static void hclge_ext_resotre_config(struct hclge_dev *hdev) +{ + if (hdev->reset_type != HNAE3_IMP_RESET && + hdev->reset_type != HNAE3_GLOBAL_RESET) + return; + + if (hdev->notify_param.init) + hclge_set_notify_packet_para(hdev, &hdev->notify_param, + sizeof(hdev->notify_param)); +} + static int hclge_set_reset_task(struct hclge_dev *hdev, void *data, size_t length) { @@ -203,6 +298,7 @@ void hclge_ext_reset_end(struct hclge_dev *hdev, bool done) return; }
+ hclge_ext_resotre_config(hdev); hclge_ext_call_event(hdev, HNAE3_RESET_DONE_CUSTOM); dev_info(&hdev->pdev->dev, "report reset done!\n"); } @@ -212,6 +308,8 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_EVENT_CALLBACK] = hclge_nic_call_event, [HNAE3_EXT_OPC_GET_PFC_STORM_PARA] = hclge_get_pfc_storm_para, [HNAE3_EXT_OPC_SET_PFC_STORM_PARA] = hclge_set_pfc_storm_para, + [HNAE3_EXT_OPC_SET_NOTIFY_PARAM] = hclge_set_notify_packet_para, + [HNAE3_EXT_OPC_SET_NOTIFY_START] = hclge_set_notify_packet_start, };
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 d87d6bb0e4c5..ce8fc17741fc 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -5,6 +5,11 @@ #define __HCLGE_EXT_H #include <linux/types.h>
+#define HCLGE_NOTIFY_PARA_CFG_PKT_EN BIT(0) +#define HCLGE_NOTIFY_PARA_CFG_START_EN BIT(1) +#define HCLGE_NOTIFY_PARA_CFG_PKT_NUM_M GENMASK(5, 2) +#define HCLGE_NOTIFY_PARA_CFG_PKT_NUM_S 2 + struct hclge_pfc_storm_para_cmd { __le32 dir; __le32 enable; @@ -14,7 +19,18 @@ struct hclge_pfc_storm_para_cmd { __le32 rsv; };
+struct hclge_notify_pkt_param_cmd { + __le32 cfg; + __le32 ipg; + __le32 data[16]; + u8 vld_cfg; + u8 vld_ipg; + u8 vld_data; + u8 rsv[21]; +}; + enum hclge_ext_opcode_type { + HCLGE_OPC_SET_NOTIFY_PKT = 0x180A, HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019, };
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index e96f049df20f..18c3c4ff9ba6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -974,6 +974,7 @@ struct hclge_dev { struct hclge_ptp *ptp; struct devlink *devlink; struct hclge_comm_rss_cfg rss_cfg; + struct hnae3_notify_pkt_param notify_param; };
/* VPort level vlan tag configuration for TX direction */
From: Hao Chen chenhao418@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
Two network ports on a single chip can be physically connected to form a 1d torus topology. TCP/UDP and RDMA communication between chip nodes can be implemented without switches.The patch provide interfaces for getting/setting 1d torus param.
Signed-off-by: Hao Chen chenhao418@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 1 + .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 8 + .../net/ethernet/hisilicon/hns3/hns3_ext.c | 17 ++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 2 + .../hisilicon/hns3/hns3pf/hclge_ext.c | 190 ++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 29 +++ .../hisilicon/hns3/hns3pf/hclge_main.h | 1 + 7 files changed, 248 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index a9f675b64d18..3dbdee2a9b92 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -43,6 +43,7 @@ #define HNAE3_DEVICE_VERSION_V1 0x00020 #define HNAE3_DEVICE_VERSION_V2 0x00021 #define HNAE3_DEVICE_VERSION_V3 0x00030 +#define HNAE3_DEVICE_VERSION_V4 0x00032
#define HNAE3_PCI_REVISION_BIT_SIZE 8
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 274a79414f47..40e93dd49a1c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -33,6 +33,8 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_SET_PFC_STORM_PARA, HNAE3_EXT_OPC_SET_NOTIFY_PARAM, HNAE3_EXT_OPC_SET_NOTIFY_START, + HNAE3_EXT_OPC_SET_TORUS_PARAM, + HNAE3_EXT_OPC_GET_TORUS_PARAM, };
struct hnae3_pfc_storm_para { @@ -50,4 +52,10 @@ struct hnae3_notify_pkt_param { u8 init; /* initialization flag, product does not need to set value */ u8 data[64]; /* note packet data */ }; + +struct hnae3_torus_param { + u32 enable; /* 1d torus mode enable */ + u32 mac_id; /* export mac id of port */ + u8 is_node0; /* if current node is node0 */ +}; #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index 5b7183daba4c..4b914f3187fd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -157,3 +157,20 @@ int nic_set_notify_pkt_start(struct net_device *ndev) return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_NOTIFY_START, NULL, 0); } EXPORT_SYMBOL(nic_set_notify_pkt_start); + +int nic_set_torus_param(struct net_device *ndev, struct hnae3_torus_param *param) +{ + if (!param || (param->enable != 0 && param->enable != 1)) + return -EINVAL; + + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_TORUS_PARAM, + param, sizeof(*param)); +} +EXPORT_SYMBOL(nic_set_torus_param); + +int nic_get_torus_param(struct net_device *ndev, struct hnae3_torus_param *param) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_GET_TORUS_PARAM, + param, sizeof(*param)); +} +EXPORT_SYMBOL(nic_get_torus_param); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index d75fd9fecef1..ef13661fb9c1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -24,4 +24,6 @@ int nic_get_pfc_storm_para(struct net_device *ndev, u32 dir, u32 *enable, int nic_set_notify_pkt_param(struct net_device *ndev, struct hnae3_notify_pkt_param *param); int nic_set_notify_pkt_start(struct net_device *ndev); +int nic_set_torus_param(struct net_device *ndev, struct hnae3_torus_param *param); +int nic_get_torus_param(struct net_device *ndev, struct hnae3_torus_param *param); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index 80f0bb0d738c..17eb80c59fcf 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -157,6 +157,191 @@ static int hclge_set_notify_packet_start(struct hclge_dev *hdev, return ret; }
+static int hclge_torus_cfg_switch(struct hclge_dev *hdev, bool is_rocee, + bool enabled) +{ + struct hclge_mac_vlan_switch_cmd *req; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_SWITCH_PARAM, true); + req = (struct hclge_mac_vlan_switch_cmd *)desc.data; + req->roce_sel = is_rocee ? 1 : 0; + /* set 0 to let firmware choose current function */ + req->func_id = 0; + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get switch param, ret = %d\n", ret); + return ret; + } + + hnae3_set_bit(req->switch_param, HCLGE_SWITCH_ALW_LPBK_B, 1); + hnae3_set_bit(req->switch_param, HCLGE_SWITCH_ALW_LCL_LPBK_B, 0); + hnae3_set_bit(req->switch_param, HCLGE_SWITCH_ANTI_SPOOF_B, enabled); + if (!is_rocee) + hnae3_set_bit(req->switch_param, HCLGE_SWITCH_ALW_DST_OVRD_B, + enabled); + + hclge_comm_cmd_reuse_desc(&desc, false); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to set switch param, ret = %d\n", ret); + + return ret; +} + +static int hclge_torus_cfg_vlan_filter(struct hclge_dev *hdev, + bool enabled) +{ + struct hclge_vlan_filter_ctrl_cmd *req; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_VLAN_FILTER, true); + req = (struct hclge_vlan_filter_ctrl_cmd *)desc.data; + req->vlan_type = HCLGE_FILTER_TYPE_PORT; + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get torus vlan filter, ret = %d\n", ret); + return ret; + } + + hnae3_set_bit(req->vlan_fe, HCLGE_VLAN_FE_NIC_INGRESS, !enabled); + hnae3_set_bit(req->vlan_fe, HCLGE_VLAN_FE_ROCEE_INGRESS, !enabled); + req->vlan_type = HCLGE_FILTER_TYPE_PORT; + + hclge_comm_cmd_reuse_desc(&desc, false); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to set torus vlan filter, ret = %d\n", ret); + + return ret; +} + +static int hclge_torus_cfg(struct hclge_dev *hdev, + struct hnae3_torus_param *param) +{ + struct hclge_torus_cfg_cmd *req; + struct hclge_desc desc; + u32 lan_fwd_tc_cfg = 0; + u32 lan_port_pair = 0; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_1D_TORUS, true); + req = (struct hclge_torus_cfg_cmd *)desc.data; + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get torus config, ret = %d\n", ret); + return ret; + } + + req->lan_port_pair = cpu_to_le32(param->mac_id & + HCLGE_TORUS_MAC_ID_MASK); + hnae3_set_bit(lan_port_pair, HCLGE_UC_LAN_PAIR_EN, 1); + hnae3_set_bit(lan_port_pair, HCLGE_MC_BC_LAN_PAIR_EN, 1); + hnae3_set_bit(lan_port_pair, HCLGE_LLDP_LAN_PAIR_EN, 1); + hnae3_set_bit(lan_port_pair, HCLGE_TC2VLANPRI_MAPPING_EN, 1); + hnae3_set_bit(lan_port_pair, HCLGE_TORUS_LPBK_DROP_EN, 1); + if (param->enable) + req->lan_port_pair |= cpu_to_le32(lan_port_pair); + + if (!param->is_node0) { + req->lan_fwd_tc_cfg &= cpu_to_le32(~HCLGE_TORUS_TC1_DROP_EN); + lan_fwd_tc_cfg &= ~HCLGE_TOURS_TCX_MAP_TCY_MASK; + lan_fwd_tc_cfg |= HCLGE_TOURS_TCX_MAP_TCY_INIT & + HCLGE_TOURS_TCX_MAP_TCY_MASK; + req->lan_fwd_tc_cfg |= cpu_to_le32(lan_fwd_tc_cfg); + } else { + req->lan_fwd_tc_cfg |= cpu_to_le32(HCLGE_TORUS_TC1_DROP_EN); + lan_fwd_tc_cfg &= ~HCLGE_TOURS_TCX_MAP_TCY_MASK; + lan_fwd_tc_cfg |= HCLGE_TOURS_TCX_MAP_TCY_NODE0_INIT & + HCLGE_TOURS_TCX_MAP_TCY_MASK; + req->lan_fwd_tc_cfg |= cpu_to_le32(lan_fwd_tc_cfg); + } + + req->torus_en = cpu_to_le32(param->enable); + hclge_comm_cmd_reuse_desc(&desc, false); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, "failed to set torus, ret = %d\n", + ret); + + return ret; +} + +static int hclge_set_torus_param(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hnae3_torus_param *param = (struct hnae3_torus_param *)data; + int ret; + + if (hdev->ae_dev->dev_version == HNAE3_DEVICE_VERSION_V4) + return -EOPNOTSUPP; + + if (length != sizeof(struct hnae3_torus_param)) + return -EINVAL; + + ret = hclge_torus_cfg_switch(hdev, false, !!param->enable); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to config nic switch param, ret = %d\n", ret); + return ret; + } + + ret = hclge_torus_cfg_switch(hdev, true, !!param->enable); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to config roce switch param, ret = %d\n", ret); + return ret; + } + + ret = hclge_torus_cfg_vlan_filter(hdev, !!param->enable); + if (ret) + return ret; + + ret = hclge_torus_cfg(hdev, param); + if (ret) + return ret; + + hdev->torus_param = *param; + return 0; +} + +static int hclge_get_torus_param(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hnae3_torus_param *param = (struct hnae3_torus_param *)data; + struct hclge_torus_cfg_cmd *req; + struct hclge_desc desc; + int ret; + + if (hdev->ae_dev->dev_version == HNAE3_DEVICE_VERSION_V4) + return -EOPNOTSUPP; + + if (length != sizeof(struct hnae3_torus_param)) + return -EINVAL; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_1D_TORUS, true); + req = (struct hclge_torus_cfg_cmd *)desc.data; + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get torus param, ret = %d\n", ret); + return ret; + } + + param->mac_id = + le32_to_cpu(req->lan_port_pair) & HCLGE_TORUS_MAC_ID_MASK; + param->enable = le32_to_cpu(req->torus_en); + + return 0; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -166,6 +351,9 @@ static void hclge_ext_resotre_config(struct hclge_dev *hdev) if (hdev->notify_param.init) hclge_set_notify_packet_para(hdev, &hdev->notify_param, sizeof(hdev->notify_param)); + + hclge_set_torus_param(hdev, &hdev->torus_param, + sizeof(hdev->torus_param)); }
static int hclge_set_reset_task(struct hclge_dev *hdev, void *data, @@ -310,6 +498,8 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_SET_PFC_STORM_PARA] = hclge_set_pfc_storm_para, [HNAE3_EXT_OPC_SET_NOTIFY_PARAM] = hclge_set_notify_packet_para, [HNAE3_EXT_OPC_SET_NOTIFY_START] = hclge_set_notify_packet_start, + [HNAE3_EXT_OPC_SET_TORUS_PARAM] = hclge_set_torus_param, + [HNAE3_EXT_OPC_GET_TORUS_PARAM] = hclge_get_torus_param, };
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 ce8fc17741fc..abdb00e78fc3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -10,6 +10,23 @@ #define HCLGE_NOTIFY_PARA_CFG_PKT_NUM_M GENMASK(5, 2) #define HCLGE_NOTIFY_PARA_CFG_PKT_NUM_S 2
+#define HCLGE_TORUS_MAC_ID_MASK 0x3 +#define HCLGE_TOURS_TCX_MAP_TCY_INIT 0x1c6144 +#define HCLGE_TOURS_TCX_MAP_TCY_NODE0_INIT 0x1c6141 + +#define HCLGE_VLAN_FE_NIC_INGRESS 0 +#define HCLGE_VLAN_FE_ROCEE_INGRESS 2 + +#define HCLGE_TORUS_LPBK_DROP_EN 20 +#define HCLGE_TC2VLANPRI_MAPPING_EN 19 +#define HCLGE_LLDP_LAN_PAIR_EN 18 +#define HCLGE_MC_BC_LAN_PAIR_EN 17 +#define HCLGE_UC_LAN_PAIR_EN 16 + +#define HCLGE_TORUS_TC1_DROP_EN BIT(26) + +#define HCLGE_TOURS_TCX_MAP_TCY_MASK 0x1c71c7 + struct hclge_pfc_storm_para_cmd { __le32 dir; __le32 enable; @@ -29,8 +46,20 @@ struct hclge_notify_pkt_param_cmd { u8 rsv[21]; };
+struct hclge_torus_cfg_cmd { + u8 rsv[4]; + __le32 lan_port_pair; + __le32 lan_fwd_tc_cfg; + __le32 pause_time_out; + __le32 pause_time_out_en; + __le32 torus_en; +}; + enum hclge_ext_opcode_type { + HCLGE_OPC_CONFIG_SWITCH_PARAM = 0x1033, + HCLGE_OPC_CONFIG_VLAN_FILTER = 0x1100, HCLGE_OPC_SET_NOTIFY_PKT = 0x180A, + HCLGE_OPC_CONFIG_1D_TORUS = 0x2300, HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019, };
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 18c3c4ff9ba6..6c2962cf5f5c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -975,6 +975,7 @@ struct hclge_dev { struct devlink *devlink; struct hclge_comm_rss_cfg rss_cfg; struct hnae3_notify_pkt_param notify_param; + struct hnae3_torus_param torus_param; };
/* VPort level vlan tag configuration for TX direction */
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
Some scenes use the standard tools ethtool and ifconfig to query traffic statistics in a specified period.To facilitate calculation, the driver needs to clear the original statistics first. The patch provides an customized interface for clearing MAC statistics.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_ext.c | 40 +++++++++++++++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 1 + .../hisilicon/hns3/hns3pf/hclge_ext.c | 17 ++++++++ 4 files changed, 59 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 40e93dd49a1c..53414001ba42 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -35,6 +35,7 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_SET_NOTIFY_START, HNAE3_EXT_OPC_SET_TORUS_PARAM, HNAE3_EXT_OPC_GET_TORUS_PARAM, + HNAE3_EXT_OPC_CLEAN_STATS64, };
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 4b914f3187fd..e10d1f192a5f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -174,3 +174,43 @@ int nic_get_torus_param(struct net_device *ndev, struct hnae3_torus_param *param param, sizeof(*param)); } EXPORT_SYMBOL(nic_get_torus_param); + +int nic_clean_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats) +{ + struct hnae3_knic_private_info *kinfo; + struct hns3_enet_ring *ring; + struct hns3_nic_priv *priv; + struct hnae3_handle *h; + int i, ret; + + priv = netdev_priv(ndev); + h = hns3_get_handle(ndev); + kinfo = &h->kinfo; + + rtnl_lock(); + if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || + test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) { + ret = -EBUSY; + goto end_unlock; + } + + ret = nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_CLEAN_STATS64, + NULL, 0); + if (ret) + goto end_unlock; + + for (i = 0; i < kinfo->num_tqps; i++) { + ring = &priv->ring[i]; + memset(&ring->stats, 0, sizeof(struct ring_stats)); + ring = &priv->ring[i + kinfo->num_tqps]; + memset(&ring->stats, 0, sizeof(struct ring_stats)); + } + + memset(&ndev->stats, 0, sizeof(struct net_device_stats)); + netdev_info(ndev, "clean stats succ\n"); + +end_unlock: + rtnl_unlock(); + return ret; +} +EXPORT_SYMBOL(nic_clean_stats64); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index ef13661fb9c1..3a4034f568fc 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -26,4 +26,5 @@ int nic_set_notify_pkt_param(struct net_device *ndev, int nic_set_notify_pkt_start(struct net_device *ndev); int nic_set_torus_param(struct net_device *ndev, struct hnae3_torus_param *param); int nic_get_torus_param(struct net_device *ndev, struct hnae3_torus_param *param); +int nic_clean_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index 17eb80c59fcf..b79d1cea4efc 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -342,6 +342,22 @@ static int hclge_get_torus_param(struct hclge_dev *hdev, void *data, return 0; }
+static int hclge_clean_stats64(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hnae3_knic_private_info *kinfo; + struct hclge_comm_tqp *tqp; + int i; + + kinfo = &hdev->vport[0].nic.kinfo; + for (i = 0; i < kinfo->num_tqps; i++) { + tqp = container_of(kinfo->tqp[i], struct hclge_comm_tqp, q); + memset(&tqp->tqp_stats, 0, sizeof(struct hclge_comm_tqp_stats)); + } + memset(&hdev->mac_stats, 0, sizeof(struct hclge_mac_stats)); + return 0; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -500,6 +516,7 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_SET_NOTIFY_START] = hclge_set_notify_packet_start, [HNAE3_EXT_OPC_SET_TORUS_PARAM] = hclge_set_torus_param, [HNAE3_EXT_OPC_GET_TORUS_PARAM] = hclge_get_torus_param, + [HNAE3_EXT_OPC_CLEAN_STATS64] = hclge_clean_stats64, };
int hclge_ext_ops_handle(struct hnae3_handle *handle, int opcode,
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
The patch provides a customized interface for configuring the interrupt affinity of the hns3 network port.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hns3_ext.c | 63 +++++++++++++++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 1 + 2 files changed, 64 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index e10d1f192a5f..d8dbd7d8763f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -214,3 +214,66 @@ int nic_clean_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats) return ret; } EXPORT_SYMBOL(nic_clean_stats64); + +int nic_set_cpu_affinity(struct net_device *ndev, cpumask_t *affinity_mask) +{ + struct hns3_enet_tqp_vector *tqp_vector; + struct hns3_nic_priv *priv; + int ret = 0; + u16 i; + + if (!ndev || !affinity_mask) { + netdev_err(ndev, + "Invalid input param when set ethernet cpu affinity\n"); + return -EINVAL; + } + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + priv = netdev_priv(ndev); + rtnl_lock(); + if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || + test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) { + ret = -EBUSY; + goto err_unlock; + } + + if (test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) { + netdev_err(ndev, + "ethernet is down, not support cpu affinity set\n"); + ret = -ENETDOWN; + goto err_unlock; + } + + for (i = 0; i < priv->vector_num; i++) { + tqp_vector = &priv->tqp_vector[i]; + if (tqp_vector->irq_init_flag != HNS3_VECTOR_INITED) + continue; + + tqp_vector->affinity_mask = *affinity_mask; + + ret = irq_set_affinity_hint(tqp_vector->vector_irq, NULL); + if (ret) { + netdev_err(ndev, + "failed to reset affinity hint, ret = %d\n", ret); + goto err_unlock; + } + + ret = irq_set_affinity_hint(tqp_vector->vector_irq, + &tqp_vector->affinity_mask); + if (ret) { + netdev_err(ndev, + "failed to set affinity hint, ret = %d\n", ret); + goto err_unlock; + } + } + + netdev_info(ndev, "set nic cpu affinity %*pb succeed\n", + cpumask_pr_args(affinity_mask)); + +err_unlock: + rtnl_unlock(); + return ret; +} +EXPORT_SYMBOL(nic_set_cpu_affinity); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index 3a4034f568fc..4520029d305d 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -27,4 +27,5 @@ int nic_set_notify_pkt_start(struct net_device *ndev); int nic_set_torus_param(struct net_device *ndev, struct hnae3_torus_param *param); int nic_get_torus_param(struct net_device *ndev, struct hnae3_torus_param *param); int nic_clean_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats); +int nic_set_cpu_affinity(struct net_device *ndev, cpumask_t *affinity_mask); #endif
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
The patch supports the query of port ext information.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 14 +++ .../net/ethernet/hisilicon/hns3/hns3_ext.c | 112 ++++++++++++++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 7 ++ .../hisilicon/hns3/hns3pf/hclge_ext.c | 91 ++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 21 ++++ 5 files changed, 245 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 53414001ba42..03b54b06c23b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -36,6 +36,9 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_SET_TORUS_PARAM, HNAE3_EXT_OPC_GET_TORUS_PARAM, HNAE3_EXT_OPC_CLEAN_STATS64, + HNAE3_EXT_OPC_GET_PORT_EXT_ID_INFO, + HNAE3_EXT_OPC_GET_PORT_EXT_NUM_INFO, + HNAE3_EXT_OPC_GET_PORT_NUM, };
struct hnae3_pfc_storm_para { @@ -59,4 +62,15 @@ struct hnae3_torus_param { u32 mac_id; /* export mac id of port */ u8 is_node0; /* if current node is node0 */ }; + +struct hane3_port_ext_id_info { + u32 chip_id; + u32 mac_id; + u32 io_die_id; +}; + +struct hane3_port_ext_num_info { + u32 chip_num; + u32 io_die_num; +}; #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index d8dbd7d8763f..60631b4a5dab 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -277,3 +277,115 @@ int nic_set_cpu_affinity(struct net_device *ndev, cpumask_t *affinity_mask) return ret; } EXPORT_SYMBOL(nic_set_cpu_affinity); + +static int nic_get_ext_id_info(struct net_device *ndev, + struct hane3_port_ext_id_info *id_info) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_GET_PORT_EXT_ID_INFO, + id_info, sizeof(*id_info)); +} + +int nic_get_chipid(struct net_device *ndev, u32 *chip_id) +{ + struct hane3_port_ext_id_info info; + int ret; + + if (!chip_id) + return -EINVAL; + + ret = nic_get_ext_id_info(ndev, &info); + if (ret) + return ret; + + *chip_id = info.chip_id; + return 0; +} +EXPORT_SYMBOL(nic_get_chipid); + +int nic_get_mac_id(struct net_device *ndev, u32 *mac_id) +{ + struct hane3_port_ext_id_info info; + int ret; + + if (!mac_id) + return -EINVAL; + + ret = nic_get_ext_id_info(ndev, &info); + if (ret) + return ret; + + *mac_id = info.mac_id; + return 0; +} +EXPORT_SYMBOL(nic_get_mac_id); + +int nic_get_io_die_id(struct net_device *ndev, u32 *io_die_id) +{ + struct hane3_port_ext_id_info info; + int ret; + + if (!io_die_id) + return -EINVAL; + + ret = nic_get_ext_id_info(ndev, &info); + if (ret) + return ret; + + *io_die_id = info.io_die_id; + return 0; +} +EXPORT_SYMBOL(nic_get_io_die_id); + +static int nic_get_ext_num_info(struct net_device *ndev, + struct hane3_port_ext_num_info *num_info) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_GET_PORT_EXT_NUM_INFO, + num_info, sizeof(*num_info)); +} + +int nic_get_chip_num(struct net_device *ndev, u32 *chip_num) +{ + struct hane3_port_ext_num_info info; + int ret; + + if (!chip_num) + return -EINVAL; + + ret = nic_get_ext_num_info(ndev, &info); + if (ret) + return ret; + + *chip_num = info.chip_num; + return 0; +} +EXPORT_SYMBOL(nic_get_chip_num); + +int nic_get_io_die_num(struct net_device *ndev, u32 *io_die_num) +{ + struct hane3_port_ext_num_info info; + int ret; + + if (!io_die_num) + return -EINVAL; + + ret = nic_get_ext_num_info(ndev, &info); + if (ret) + return ret; + + *io_die_num = info.io_die_num; + return 0; +} +EXPORT_SYMBOL(nic_get_io_die_num); + +int nic_get_port_num_of_die(struct net_device *ndev, u32 *port_num) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_GET_PORT_NUM, + port_num, sizeof(*port_num)); +} +EXPORT_SYMBOL(nic_get_port_num_of_die); + +int nic_get_port_num_per_chip(struct net_device *ndev, u32 *port_num) +{ + return nic_get_port_num_of_die(ndev, port_num); +} +EXPORT_SYMBOL(nic_get_port_num_per_chip); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index 4520029d305d..46ee0d2a735d 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -28,4 +28,11 @@ int nic_set_torus_param(struct net_device *ndev, struct hnae3_torus_param *param int nic_get_torus_param(struct net_device *ndev, struct hnae3_torus_param *param); int nic_clean_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats); int nic_set_cpu_affinity(struct net_device *ndev, cpumask_t *affinity_mask); +int nic_get_chipid(struct net_device *ndev, u32 *chip_id); +int nic_get_mac_id(struct net_device *ndev, u32 *mac_id); +int nic_get_io_die_id(struct net_device *ndev, u32 *io_die_id); +int nic_get_chip_num(struct net_device *ndev, u32 *chip_num); +int nic_get_io_die_num(struct net_device *ndev, u32 *io_die_num); +int nic_get_port_num_of_die(struct net_device *ndev, u32 *port_num); +int nic_get_port_num_per_chip(struct net_device *ndev, u32 *port_num); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index b79d1cea4efc..12867e7a7465 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -358,6 +358,94 @@ static int hclge_clean_stats64(struct hclge_dev *hdev, void *data, return 0; }
+static int hclge_get_info_from_cmd(struct hclge_dev *hdev, + struct hclge_desc *desc, u32 num, int opcode) +{ + u32 i; + + for (i = 0; i < num; i++) { + hclge_cmd_setup_basic_desc(desc + i, opcode, true); + if (i != num - 1) + desc[i].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT); + } + + return hclge_cmd_send(&hdev->hw, desc, num); +} + +static int hclge_get_extend_port_id_info(struct hclge_dev *hdev, + void *data, size_t length) +{ + struct hane3_port_ext_id_info *info; + struct hclge_id_info_cmd *info_cmd; + struct hclge_desc desc; + int ret; + + if (length != sizeof(struct hane3_port_ext_id_info)) + return -EINVAL; + + ret = hclge_get_info_from_cmd(hdev, &desc, 1, HCLGE_OPC_CHIP_ID_GET); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get extend port id info, ret = %d\n", + ret); + return ret; + } + + info_cmd = (struct hclge_id_info_cmd *)desc.data; + info = (struct hane3_port_ext_id_info *)data; + info->chip_id = le32_to_cpu(info_cmd->chip_id); + info->mac_id = le32_to_cpu(info_cmd->mac_id); + info->io_die_id = le32_to_cpu(info_cmd->io_die_id); + return 0; +} + +static int hclge_get_extend_port_num_info(struct hclge_dev *hdev, + void *data, size_t length) +{ + struct hane3_port_ext_num_info *num_info; + struct hclge_num_info_cmd *resp; + struct hclge_desc desc; + int ret; + + if (length != sizeof(struct hane3_port_ext_num_info)) + return -EINVAL; + + ret = hclge_get_info_from_cmd(hdev, &desc, 1, HCLGE_OPC_GET_CHIP_NUM); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get extend port number info, ret = %d\n", ret); + return ret; + } + + resp = (struct hclge_num_info_cmd *)(desc.data); + num_info = (struct hane3_port_ext_num_info *)data; + num_info->chip_num = le32_to_cpu(resp->chip_num); + num_info->io_die_num = le32_to_cpu(resp->io_die_num); + return 0; +} + +static int hclge_get_port_num(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_port_num_info_cmd *resp; + struct hclge_desc desc; + int ret; + + if (length != sizeof(u32)) + return -EINVAL; + + ret = hclge_get_info_from_cmd(hdev, &desc, 1, HCLGE_OPC_GET_PORT_NUM); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get port number, ret = %d\n", ret); + return ret; + } + + resp = (struct hclge_port_num_info_cmd *)(desc.data); + *(u32 *)data = le32_to_cpu(resp->port_num); + return 0; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -517,6 +605,9 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_SET_TORUS_PARAM] = hclge_set_torus_param, [HNAE3_EXT_OPC_GET_TORUS_PARAM] = hclge_get_torus_param, [HNAE3_EXT_OPC_CLEAN_STATS64] = hclge_clean_stats64, + [HNAE3_EXT_OPC_GET_PORT_EXT_ID_INFO] = hclge_get_extend_port_id_info, + [HNAE3_EXT_OPC_GET_PORT_EXT_NUM_INFO] = hclge_get_extend_port_num_info, + [HNAE3_EXT_OPC_GET_PORT_NUM] = hclge_get_port_num, };
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 abdb00e78fc3..f840129572c8 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -27,6 +27,24 @@
#define HCLGE_TOURS_TCX_MAP_TCY_MASK 0x1c71c7
+struct hclge_id_info_cmd { + __le32 chip_id; + __le32 mac_id; + __le32 io_die_id; + u8 rsv[12]; +}; + +struct hclge_num_info_cmd { + __le32 chip_num; + __le32 io_die_num; + u8 rsv[16]; +}; + +struct hclge_port_num_info_cmd { + __le32 port_num; + u8 rsv[20]; +}; + struct hclge_pfc_storm_para_cmd { __le32 dir; __le32 enable; @@ -60,6 +78,9 @@ enum hclge_ext_opcode_type { HCLGE_OPC_CONFIG_VLAN_FILTER = 0x1100, HCLGE_OPC_SET_NOTIFY_PKT = 0x180A, HCLGE_OPC_CONFIG_1D_TORUS = 0x2300, + HCLGE_OPC_CHIP_ID_GET = 0x7003, + HCLGE_OPC_GET_CHIP_NUM = 0x7005, + HCLGE_OPC_GET_PORT_NUM = 0x7006, HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019, };
From: Hao Chen chenhao418@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
The patch provides a customized interface to modify the tx timeout.
Signed-off-by: Hao Chen chenhao418@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- drivers/net/ethernet/hisilicon/hns3/hns3_ext.c | 14 ++++++++++++++ drivers/net/ethernet/hisilicon/hns3/hns3_ext.h | 2 ++ 2 files changed, 16 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index 60631b4a5dab..2f3cb8e90afc 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -389,3 +389,17 @@ int nic_get_port_num_per_chip(struct net_device *ndev, u32 *port_num) return nic_get_port_num_of_die(ndev, port_num); } EXPORT_SYMBOL(nic_get_port_num_per_chip); + +int nic_set_tx_timeout(struct net_device *ndev, int tx_timeout) +{ + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + if (tx_timeout <= 0 || tx_timeout > HNS3_MAX_TX_TIMEOUT) + return -EINVAL; + + ndev->watchdog_timeo = tx_timeout * HZ; + + return 0; +} +EXPORT_SYMBOL(nic_set_tx_timeout); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index 46ee0d2a735d..78080a7040b1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -13,6 +13,7 @@ #define HNS3_PFC_STORM_PARA_ENABLE 1 #define HNS3_PFC_STORM_PARA_PERIOD_MIN 5 #define HNS3_PFC_STORM_PARA_PERIOD_MAX 2000 +#define HNS3_MAX_TX_TIMEOUT 600
int nic_netdev_match_check(struct net_device *netdev); void nic_chip_recover_handler(struct net_device *ndev, @@ -35,4 +36,5 @@ int nic_get_chip_num(struct net_device *ndev, u32 *chip_num); int nic_get_io_die_num(struct net_device *ndev, u32 *io_die_num); int nic_get_port_num_of_die(struct net_device *ndev, u32 *port_num); 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); #endif
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
The patch provides an interface to check whether the optical module is inserted.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_ext.c | 7 ++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 1 + .../hisilicon/hns3/hns3pf/hclge_ext.c | 22 +++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 6 +++++ 5 files changed, 37 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 03b54b06c23b..3d9654883144 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -39,6 +39,7 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_GET_PORT_EXT_ID_INFO, HNAE3_EXT_OPC_GET_PORT_EXT_NUM_INFO, HNAE3_EXT_OPC_GET_PORT_NUM, + HNAE3_EXT_OPC_GET_PRESENT, };
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 2f3cb8e90afc..b6b0320753f6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -403,3 +403,10 @@ int nic_set_tx_timeout(struct net_device *ndev, int tx_timeout) return 0; } EXPORT_SYMBOL(nic_set_tx_timeout); + +int nic_get_sfp_present(struct net_device *ndev, int *present) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_GET_PRESENT, + present, sizeof(*present)); +} +EXPORT_SYMBOL(nic_get_sfp_present); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index 78080a7040b1..464f030da38a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -37,4 +37,5 @@ int nic_get_io_die_num(struct net_device *ndev, u32 *io_die_num); int nic_get_port_num_of_die(struct net_device *ndev, u32 *port_num); 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); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index 12867e7a7465..bf4e607245dd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -446,6 +446,27 @@ static int hclge_get_port_num(struct hclge_dev *hdev, void *data, return 0; }
+static int hclge_get_sfp_present(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_sfp_present_cmd *resp; + struct hclge_desc desc; + int ret; + + if (length != sizeof(u32)) + return -EINVAL; + + ret = hclge_get_info_from_cmd(hdev, &desc, 1, HCLGE_OPC_SFP_GET_PRESENT); + if (ret) { + dev_err(&hdev->pdev->dev, "failed to get sfp present, ret = %d\n", ret); + return ret; + } + + resp = (struct hclge_sfp_present_cmd *)desc.data; + *(u32 *)data = le32_to_cpu(resp->sfp_present); + return 0; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -608,6 +629,7 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_GET_PORT_EXT_ID_INFO] = hclge_get_extend_port_id_info, [HNAE3_EXT_OPC_GET_PORT_EXT_NUM_INFO] = hclge_get_extend_port_num_info, [HNAE3_EXT_OPC_GET_PORT_NUM] = hclge_get_port_num, + [HNAE3_EXT_OPC_GET_PRESENT] = hclge_get_sfp_present, };
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 f840129572c8..ae6f0afef1f1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -73,6 +73,11 @@ struct hclge_torus_cfg_cmd { __le32 torus_en; };
+struct hclge_sfp_present_cmd { + __le32 sfp_present; + __le32 rsv[5]; +}; + enum hclge_ext_opcode_type { HCLGE_OPC_CONFIG_SWITCH_PARAM = 0x1033, HCLGE_OPC_CONFIG_VLAN_FILTER = 0x1100, @@ -82,6 +87,7 @@ enum hclge_ext_opcode_type { HCLGE_OPC_GET_CHIP_NUM = 0x7005, HCLGE_OPC_GET_PORT_NUM = 0x7006, HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019, + HCLGE_OPC_SFP_GET_PRESENT = 0x7101, };
struct hclge_reset_fail_type_map {
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
The patch provides an interface for enabling or disabling the optical module.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_ext.c | 9 +++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 1 + .../hisilicon/hns3/hns3pf/hclge_ext.c | 25 +++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 6 +++++ 5 files changed, 42 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 3d9654883144..54aab1270953 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -40,6 +40,7 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_GET_PORT_EXT_NUM_INFO, HNAE3_EXT_OPC_GET_PORT_NUM, HNAE3_EXT_OPC_GET_PRESENT, + HNAE3_EXT_OPC_SET_SFP_STATE, };
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 b6b0320753f6..77f359f2a205 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -410,3 +410,12 @@ int nic_get_sfp_present(struct net_device *ndev, int *present) present, sizeof(*present)); } EXPORT_SYMBOL(nic_get_sfp_present); + +int nic_set_sfp_state(struct net_device *ndev, bool en) +{ + u32 state = en ? 1 : 0; + + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_SFP_STATE, + &state, sizeof(state)); +} +EXPORT_SYMBOL(nic_set_sfp_state); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index 464f030da38a..cbf993691c92 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -38,4 +38,5 @@ int nic_get_port_num_of_die(struct net_device *ndev, u32 *port_num); 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); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index bf4e607245dd..5d58780f7c74 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -467,6 +467,30 @@ static int hclge_get_sfp_present(struct hclge_dev *hdev, void *data, return 0; }
+static int hclge_set_sfp_state(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_sfp_enable_cmd *req; + struct hclge_desc desc; + u32 state; + int ret; + + if (length != sizeof(u32)) + return -EINVAL; + + state = *(u32 *)data; + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SFP_SET_STATUS, false); + req = (struct hclge_sfp_enable_cmd *)desc.data; + req->sfp_enable = cpu_to_le32(state); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to set sfp state, ret = %d\n", ret); + + return ret; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -630,6 +654,7 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_GET_PORT_EXT_NUM_INFO] = hclge_get_extend_port_num_info, [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, };
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 ae6f0afef1f1..607bd1668cdc 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -78,6 +78,11 @@ struct hclge_sfp_present_cmd { __le32 rsv[5]; };
+struct hclge_sfp_enable_cmd { + __le32 sfp_enable; + __le32 rsv[5]; +}; + enum hclge_ext_opcode_type { HCLGE_OPC_CONFIG_SWITCH_PARAM = 0x1033, HCLGE_OPC_CONFIG_VLAN_FILTER = 0x1100, @@ -88,6 +93,7 @@ enum hclge_ext_opcode_type { HCLGE_OPC_GET_PORT_NUM = 0x7006, HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019, HCLGE_OPC_SFP_GET_PRESENT = 0x7101, + HCLGE_OPC_SFP_SET_STATUS = 0x7102, };
struct hclge_reset_fail_type_map {
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,
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
The patch disables the clocks of the PPP, PPU, IGU_EGU, ROCE, and TM modules by configuring the network subctrl register.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h | 1 + drivers/net/ethernet/hisilicon/hns3/hns3_ext.c | 7 +++++++ drivers/net/ethernet/hisilicon/hns3/hns3_ext.h | 1 + .../ethernet/hisilicon/hns3/hns3pf/hclge_ext.c | 17 +++++++++++++++++ .../ethernet/hisilicon/hns3/hns3pf/hclge_ext.h | 1 + 5 files changed, 27 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index d7ab4449c031..208b1f67eb70 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -43,6 +43,7 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_SET_SFP_STATE, HNAE3_EXT_OPC_DISABLE_LANE, HNAE3_EXT_OPC_GET_LANE_STATUS, + HNAE3_EXT_OPC_DISABLE_CLOCK, };
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 7eeeabc79bc9..b4111cbeee70 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -432,3 +432,10 @@ int nic_get_net_lane_status(struct net_device *ndev, u32 *status) status, sizeof(*status)); } EXPORT_SYMBOL(nic_get_net_lane_status); + +int nic_disable_clock(struct net_device *ndev) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_DISABLE_CLOCK, + NULL, 0); +} +EXPORT_SYMBOL(nic_disable_clock); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index 7254ff23558c..6451b862ae39 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -41,4 +41,5 @@ 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); +int nic_disable_clock(struct net_device *ndev); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index 4bc6216d2d8c..1f2c351c5cbd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -534,6 +534,22 @@ static int hclge_get_net_lane_status(struct hclge_dev *hdev, void *data, return 0; }
+static int hclge_disable_nic_clock(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_NIC_CLOCK, false); + desc.data[0] = 0; + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to disable nic clock, ret = %d\n", ret); + return ret; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -700,6 +716,7 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [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, + [HNAE3_EXT_OPC_DISABLE_CLOCK] = hclge_disable_nic_clock, };
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 06b3d9c494f4..04f9ab5261e8 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -84,6 +84,7 @@ struct hclge_sfp_enable_cmd { };
enum hclge_ext_opcode_type { + HCLGE_OPC_CONFIG_NIC_CLOCK = 0x0060, HCLGE_OPC_CONFIG_SWITCH_PARAM = 0x1033, HCLGE_OPC_CONFIG_VLAN_FILTER = 0x1100, HCLGE_OPC_SET_NOTIFY_PKT = 0x180A,
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
The patch provides a customized interface to modify the pause trans time and retains the configured parameters.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_ext.c | 7 ++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 1 + .../hisilicon/hns3/hns3pf/hclge_ext.c | 38 +++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_main.h | 1 + .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 7 ++-- .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 2 + 7 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 208b1f67eb70..e1a176d78273 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -44,6 +44,7 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_DISABLE_LANE, HNAE3_EXT_OPC_GET_LANE_STATUS, HNAE3_EXT_OPC_DISABLE_CLOCK, + HNAE3_EXT_OPC_SET_PFC_TIME, };
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 b4111cbeee70..b0016da1a428 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -439,3 +439,10 @@ int nic_disable_clock(struct net_device *ndev) NULL, 0); } EXPORT_SYMBOL(nic_disable_clock); + +int nic_set_pfc_time_cfg(struct net_device *ndev, u16 time) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_PFC_TIME, + &time, sizeof(time)); +} +EXPORT_SYMBOL(nic_set_pfc_time_cfg); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index 6451b862ae39..b0a1e3f7dfec 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -42,4 +42,5 @@ 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); int nic_disable_clock(struct net_device *ndev); +int nic_set_pfc_time_cfg(struct net_device *ndev, u16 time); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index 1f2c351c5cbd..ceaaa257b2b3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -6,6 +6,7 @@ #include "hnae3_ext.h" #include "hclge_cmd.h" #include "hclge_ext.h" +#include "hclge_tm.h"
static nic_event_fn_t nic_event_call;
@@ -550,6 +551,42 @@ static int hclge_disable_nic_clock(struct hclge_dev *hdev, void *data, return ret; }
+static int hclge_set_pause_trans_time(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_cfg_pause_param_cmd *pause_param; + struct hclge_desc desc; + u16 pause_trans_time; + int ret; + + if (length != sizeof(u16)) + return -EINVAL; + + pause_param = (struct hclge_cfg_pause_param_cmd *)desc.data; + ret = hclge_get_info_from_cmd(hdev, &desc, 1, HCLGE_OPC_CFG_MAC_PARA); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get pause cfg info, ret = %d\n", ret); + return ret; + } + + pause_trans_time = *(u16 *)data; + if (pause_trans_time == le16_to_cpu(pause_param->pause_trans_time)) + return 0; + + ret = hclge_pause_param_cfg(hdev, pause_param->mac_addr, + pause_param->pause_trans_gap, + pause_trans_time); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to set pause trans time, ret = %d\n", ret); + return ret; + } + + hdev->tm_info.pause_time = pause_trans_time; + return 0; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -717,6 +754,7 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_DISABLE_LANE] = hclge_disable_net_lane, [HNAE3_EXT_OPC_GET_LANE_STATUS] = hclge_get_net_lane_status, [HNAE3_EXT_OPC_DISABLE_CLOCK] = hclge_disable_nic_clock, + [HNAE3_EXT_OPC_SET_PFC_TIME] = hclge_set_pause_trans_time, };
int hclge_ext_ops_handle(struct hnae3_handle *handle, int opcode, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 6c2962cf5f5c..993a9d682e06 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -378,6 +378,7 @@ struct hclge_tm_info { enum hclge_fc_mode fc_mode; u8 hw_pfc_map; /* Allow for packet drop or not on this TC */ u8 pfc_en; /* PFC enabled or not for user priority */ + u16 pause_time; };
/* max number of mac statistics on each version */ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c index c58c31221762..a68dcace90aa 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -185,8 +185,8 @@ int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap, return hclge_cmd_send(&hdev->hw, &desc, 1); }
-static int hclge_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr, - u8 pause_trans_gap, u16 pause_trans_time) +int hclge_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr, + u8 pause_trans_gap, u16 pause_trans_time) { struct hclge_cfg_pause_param_cmd *pause_param; struct hclge_desc desc; @@ -1498,7 +1498,7 @@ static int hclge_pause_param_setup_hw(struct hclge_dev *hdev)
return hclge_pause_param_cfg(hdev, mac->mac_addr, HCLGE_DEFAULT_PAUSE_TRANS_GAP, - HCLGE_DEFAULT_PAUSE_TRANS_TIME); + hdev->tm_info.pause_time); }
static int hclge_pfc_setup_hw(struct hclge_dev *hdev) @@ -1692,6 +1692,7 @@ int hclge_tm_schd_init(struct hclge_dev *hdev) /* fc_mode is HCLGE_FC_FULL on reset */ hdev->tm_info.fc_mode = HCLGE_FC_FULL; hdev->fc_mode_last_time = hdev->tm_info.fc_mode; + hdev->tm_info.pause_time = HCLGE_DEFAULT_PAUSE_TRANS_TIME;
if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE && hdev->tm_info.num_pg != 1) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h index 53eec6df5194..bfbd35d3bec3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h @@ -244,6 +244,8 @@ int hclge_tm_init_hw(struct hclge_dev *hdev, bool init); int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap, u8 pfc_bitmap); int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx); +int hclge_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr, + u8 pause_trans_gap, u16 pause_trans_time); int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr); int hclge_mac_pause_setup_hw(struct hclge_dev *hdev); void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats);
From: Jie Wang wangjie125@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
When the link status of the PF network port changes from up to down, the IMP can quickly report the link down fault cause based on the link status. If the hardware is faulty from the beginning and the link is not up, the IMP does not report the link down event because the status is not changed.
Therefore, an interface is provided to detect port faults.
Signed-off-by: Jie Wang wangjie125@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 15 ++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.c | 22 ++++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 6 +++ .../hisilicon/hns3/hns3pf/hclge_cmd.h | 6 +++ .../hisilicon/hns3/hns3pf/hclge_ext.c | 52 +++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 2 + 6 files changed, 103 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index e1a176d78273..6c38ed4b6e69 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -45,6 +45,8 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_GET_LANE_STATUS, HNAE3_EXT_OPC_DISABLE_CLOCK, HNAE3_EXT_OPC_SET_PFC_TIME, + HNAE3_EXT_OPC_GET_HILINK_REF_LOS, + HNAE3_EXT_OPC_GET_PORT_FAULT_STATUS, };
struct hnae3_pfc_storm_para { @@ -55,6 +57,19 @@ struct hnae3_pfc_storm_para { u32 recovery_period_ms; };
+enum hnae3_port_fault_type { + HNAE3_FAULT_TYPE_CDR_FLASH, + HNAE3_FAULT_TYPE_9545_ERR, + HNAE3_FAULT_TYPE_CDR_CORE, + HNAE3_FAULT_TYPE_HILINK_REF_LOS, + HNAE3_FAULT_TYPE_INVALID +}; + +struct hnae3_port_fault { + u32 fault_type; + u32 fault_status; +}; + struct hnae3_notify_pkt_param { u32 ipg; /* inter-packet gap of sending, the unit is one cycle of clock */ u16 num; /* packet number of sending */ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index b0016da1a428..50aa72d1f974 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -446,3 +446,25 @@ int nic_set_pfc_time_cfg(struct net_device *ndev, u16 time) &time, sizeof(time)); } EXPORT_SYMBOL(nic_set_pfc_time_cfg); + +int nic_get_port_fault_status(struct net_device *ndev, u32 fault_type, u32 *status) +{ + int opcode = HNAE3_EXT_OPC_GET_PORT_FAULT_STATUS; + struct hnae3_port_fault fault_para; + int ret; + + if (!status) + return -EINVAL; + + if (fault_type == HNAE3_FAULT_TYPE_HILINK_REF_LOS) + opcode = HNAE3_EXT_OPC_GET_HILINK_REF_LOS; + + fault_para.fault_type = fault_type; + ret = nic_invoke_pri_ops(ndev, opcode, &fault_para, sizeof(fault_para)); + if (ret) + return ret; + + *status = fault_para.fault_status; + return 0; +} +EXPORT_SYMBOL(nic_get_port_fault_status); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index b0a1e3f7dfec..499b690af747 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -15,6 +15,11 @@ #define HNS3_PFC_STORM_PARA_PERIOD_MAX 2000 #define HNS3_MAX_TX_TIMEOUT 600
+#define nic_get_cdr_flash_status(ndev, status) \ + nic_get_port_fault_status(ndev, HNAE3_FAULT_TYPE_CDR_FLASH, status) +#define nic_get_hilink_ref_los(ndev, status) \ + nic_get_port_fault_status(ndev, HNAE3_FAULT_TYPE_HILINK_REF_LOS, status) + int nic_netdev_match_check(struct net_device *netdev); void nic_chip_recover_handler(struct net_device *ndev, enum hnae3_event_type_custom event_t); @@ -43,4 +48,5 @@ int nic_disable_net_lane(struct net_device *ndev); int nic_get_net_lane_status(struct net_device *ndev, u32 *status); int nic_disable_clock(struct net_device *ndev); int nic_set_pfc_time_cfg(struct net_device *ndev, u16 time); +int nic_get_port_fault_status(struct net_device *ndev, u32 fault_type, u32 *status); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index 4d15eb73b972..da1efc921393 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -354,6 +354,12 @@ struct hclge_sfp_info_cmd { u8 rsv[6]; };
+struct hclge_port_fault_cmd { + __le32 fault_status; + __le32 port_type; + u8 rsv[16]; +}; + #define HCLGE_MAC_CFG_FEC_AUTO_EN_B 0 #define HCLGE_MAC_CFG_FEC_MODE_S 1 #define HCLGE_MAC_CFG_FEC_MODE_M GENMASK(3, 1) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index ceaaa257b2b3..8270e2e789ca 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -587,6 +587,56 @@ static int hclge_set_pause_trans_time(struct hclge_dev *hdev, void *data, return 0; }
+static int hclge_get_hilink_ref_los(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_port_fault_cmd *fault_cmd; + struct hclge_desc desc; + int ret; + + if (length != sizeof(struct hnae3_port_fault)) + return -EINVAL; + + fault_cmd = (struct hclge_port_fault_cmd *)desc.data; + ret = hclge_get_info_from_cmd(hdev, &desc, 1, HCLGE_OPC_CFG_GET_HILINK_REF_LOS); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get hilink ref los, ret = %d\n", ret); + return ret; + } + + *(u32 *)data = le32_to_cpu(fault_cmd->fault_status); + return 0; +} + +static int hclge_get_port_fault_status(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_port_fault_cmd *fault_cmd; + struct hnae3_port_fault *para; + struct hclge_desc desc; + int ret; + + if (length != sizeof(struct hnae3_port_fault)) + return -EINVAL; + + para = (struct hnae3_port_fault *)data; + fault_cmd = (struct hclge_port_fault_cmd *)desc.data; + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_GET_PORT_FAULT_STATUS, true); + fault_cmd->port_type = cpu_to_le32(para->fault_type); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get port fault status, type = %u, ret = %d\n", + para->fault_type, ret); + return ret; + } + + para->fault_status = le32_to_cpu(fault_cmd->fault_status); + + return 0; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -755,6 +805,8 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_GET_LANE_STATUS] = hclge_get_net_lane_status, [HNAE3_EXT_OPC_DISABLE_CLOCK] = hclge_disable_nic_clock, [HNAE3_EXT_OPC_SET_PFC_TIME] = hclge_set_pause_trans_time, + [HNAE3_EXT_OPC_GET_HILINK_REF_LOS] = hclge_get_hilink_ref_los, + [HNAE3_EXT_OPC_GET_PORT_FAULT_STATUS] = hclge_get_port_fault_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 04f9ab5261e8..c06b5164accd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -94,6 +94,8 @@ enum hclge_ext_opcode_type { HCLGE_OPC_GET_PORT_NUM = 0x7006, HCLGE_OPC_DISABLE_NET_LANE = 0x7008, HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019, + HCLGE_OPC_CFG_GET_HILINK_REF_LOS = 0x701B, + HCLGE_OPC_GET_PORT_FAULT_STATUS = 0x7023, HCLGE_OPC_SFP_GET_PRESENT = 0x7101, HCLGE_OPC_SFP_SET_STATUS = 0x7102, };
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
This patch add support to get port wire type.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h | 1 + drivers/net/ethernet/hisilicon/hns3/hns3_ext.c | 7 +++++++ drivers/net/ethernet/hisilicon/hns3/hns3_ext.h | 1 + .../net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c | 14 ++++++++++++++ .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 4 ++-- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 2 ++ 6 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 6c38ed4b6e69..608846538612 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -47,6 +47,7 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_SET_PFC_TIME, HNAE3_EXT_OPC_GET_HILINK_REF_LOS, HNAE3_EXT_OPC_GET_PORT_FAULT_STATUS, + HNAE3_EXT_OPC_GET_PORT_TYPE, };
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 50aa72d1f974..c3e16523bf33 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -468,3 +468,10 @@ int nic_get_port_fault_status(struct net_device *ndev, u32 fault_type, u32 *stat return 0; } EXPORT_SYMBOL(nic_get_port_fault_status); + +int nic_get_port_wire_type(struct net_device *ndev, u32 *wire_type) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_GET_PORT_TYPE, + wire_type, sizeof(*wire_type)); +} +EXPORT_SYMBOL(nic_get_port_wire_type); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index 499b690af747..4361b89c0521 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -49,4 +49,5 @@ int nic_get_net_lane_status(struct net_device *ndev, u32 *status); int nic_disable_clock(struct net_device *ndev); int nic_set_pfc_time_cfg(struct net_device *ndev, u16 time); int nic_get_port_fault_status(struct net_device *ndev, u32 fault_type, u32 *status); +int nic_get_port_wire_type(struct net_device *ndev, u32 *wire_type); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index 8270e2e789ca..67b41309c0fe 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -637,6 +637,19 @@ static int hclge_get_port_fault_status(struct hclge_dev *hdev, void *data, return 0; }
+static int hclge_get_port_wire_type(struct hclge_dev *hdev, void *data, + size_t length) +{ + u8 module_type; + + if (length != sizeof(u32)) + return -EINVAL; + + hclge_get_media_type(&hdev->vport[0].nic, NULL, &module_type); + *(u32 *)data = module_type; + return 0; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -807,6 +820,7 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_SET_PFC_TIME] = hclge_set_pause_trans_time, [HNAE3_EXT_OPC_GET_HILINK_REF_LOS] = hclge_get_hilink_ref_los, [HNAE3_EXT_OPC_GET_PORT_FAULT_STATUS] = hclge_get_port_fault_status, + [HNAE3_EXT_OPC_GET_PORT_TYPE] = hclge_get_port_wire_type, };
int hclge_ext_ops_handle(struct hnae3_handle *handle, int opcode, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 5179aa769a4f..a21a0a9b3345 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -10997,8 +10997,8 @@ static void hclge_get_ksettings_an_result(struct hnae3_handle *handle, *lane_num = hdev->hw.mac.lane_num; }
-static void hclge_get_media_type(struct hnae3_handle *handle, u8 *media_type, - u8 *module_type) +void hclge_get_media_type(struct hnae3_handle *handle, u8 *media_type, + u8 *module_type) { struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 993a9d682e06..7c16936af5a8 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -1167,4 +1167,6 @@ struct hclge_vport *hclge_get_vf_vport(struct hclge_dev *hdev, int vf); int hclge_inform_vf_reset(struct hclge_vport *vport, u16 reset_type); void hclge_reset_task_schedule(struct hclge_dev *hdev); void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle); +void hclge_get_media_type(struct hnae3_handle *handle, u8 *media_type, + u8 *module_type); #endif
From: wangpeiyang wangpeiyang1@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
The patch provides a customized interface to modify the MAC mode.
Signed-off-by: wangpeiyang wangpeiyang1@huawei.com Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_ext.c | 7 ++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 1 + .../hisilicon/hns3/hns3pf/hclge_ext.c | 33 +++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_main.c | 11 ++++--- .../hisilicon/hns3/hns3pf/hclge_main.h | 1 + 6 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 608846538612..ba707032f52e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -48,6 +48,7 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_GET_HILINK_REF_LOS, HNAE3_EXT_OPC_GET_PORT_FAULT_STATUS, HNAE3_EXT_OPC_GET_PORT_TYPE, + HNAE3_EXT_OPC_SET_MAC_STATE, };
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 c3e16523bf33..d4cdab636ff0 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -475,3 +475,10 @@ int nic_get_port_wire_type(struct net_device *ndev, u32 *wire_type) wire_type, sizeof(*wire_type)); } EXPORT_SYMBOL(nic_get_port_wire_type); + +int nic_set_mac_state(struct net_device *ndev, int enable) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_MAC_STATE, + &enable, sizeof(enable)); +} +EXPORT_SYMBOL(nic_set_mac_state); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index 4361b89c0521..907cbaf2a3f1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -50,4 +50,5 @@ int nic_disable_clock(struct net_device *ndev); int nic_set_pfc_time_cfg(struct net_device *ndev, u16 time); int nic_get_port_fault_status(struct net_device *ndev, u32 fault_type, u32 *status); int nic_get_port_wire_type(struct net_device *ndev, u32 *wire_type); +int nic_set_mac_state(struct net_device *ndev, int enable); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index 67b41309c0fe..8b6f75cad7f7 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -650,6 +650,38 @@ static int hclge_get_port_wire_type(struct hclge_dev *hdev, void *data, return 0; }
+static void hclge_set_phy_state(struct hclge_dev *hdev, bool enable) +{ + struct phy_device *phydev = hdev->hw.mac.phydev; + + if (!phydev) + return; + + if (enable && (phydev->state == PHY_READY || phydev->state == PHY_HALTED)) + phy_start(phydev); + else if (!enable && (phy_is_started(phydev) || phydev->state == PHY_DOWN || + phydev->state == PHY_ERROR)) + phy_stop(phydev); +} + +static int hclge_set_mac_state(struct hclge_dev *hdev, void *data, + size_t length) +{ + bool enable; + int ret; + + if (length != sizeof(int)) + return -EINVAL; + + enable = !!*(int *)data; + ret = hclge_cfg_mac_mode(hdev, enable); + + if (!ret && !hclge_comm_dev_phy_imp_supported(hdev->ae_dev)) + hclge_set_phy_state(hdev, enable); + + return ret; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -821,6 +853,7 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_GET_HILINK_REF_LOS] = hclge_get_hilink_ref_los, [HNAE3_EXT_OPC_GET_PORT_FAULT_STATUS] = hclge_get_port_fault_status, [HNAE3_EXT_OPC_GET_PORT_TYPE] = hclge_get_port_wire_type, + [HNAE3_EXT_OPC_SET_MAC_STATE] = hclge_set_mac_state, };
int hclge_ext_ops_handle(struct hnae3_handle *handle, int opcode, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index a21a0a9b3345..7be100810818 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -7491,7 +7491,7 @@ static void hclge_enable_fd(struct hnae3_handle *handle, bool enable) hclge_task_schedule(hdev, 0); }
-static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable) +int hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable) { #define HCLGE_LINK_STATUS_WAIT_CNT 3
@@ -7520,14 +7520,17 @@ static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable)
ret = hclge_cmd_send(&hdev->hw, &desc, 1); if (ret) { - dev_err(&hdev->pdev->dev, - "mac enable fail, ret =%d.\n", ret); - return; + dev_err(&hdev->pdev->dev, "failed to %s mac, ret = %d.\n", + enable ? "enable" : "disable", ret); + + return ret; }
if (!enable) hclge_mac_link_status_wait(hdev, HCLGE_LINK_STATUS_DOWN, HCLGE_LINK_STATUS_WAIT_CNT); + + return 0; }
static int hclge_config_switch_param(struct hclge_dev *hdev, int vfid, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 7c16936af5a8..4e692d5c8e7c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -1169,4 +1169,5 @@ void hclge_reset_task_schedule(struct hclge_dev *hdev); void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle); void hclge_get_media_type(struct hnae3_handle *handle, u8 *media_type, u8 *module_type); +int hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable); #endif
From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
The patch supports the configuration of the position indicator and error indicator modes.
Signed-off-by: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 13 +++++ .../net/ethernet/hisilicon/hns3/hns3_ext.c | 19 +++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 2 + .../hisilicon/hns3/hns3pf/hclge_ext.c | 52 +++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 10 ++++ 5 files changed, 96 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index ba707032f52e..37eee8743395 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -49,6 +49,19 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_GET_PORT_FAULT_STATUS, HNAE3_EXT_OPC_GET_PORT_TYPE, HNAE3_EXT_OPC_SET_MAC_STATE, + HNAE3_EXT_OPC_SET_LED, + HNAE3_EXT_OPC_GET_LED_SIGNAL, +}; + +struct hnae3_led_state_para { + u32 type; + u32 status; +}; + +struct hnae3_lamp_signal { + u8 error; + u8 locate; + u8 activity; };
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 d4cdab636ff0..1c03a4f5e457 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -482,3 +482,22 @@ int nic_set_mac_state(struct net_device *ndev, int enable) &enable, sizeof(enable)); } EXPORT_SYMBOL(nic_set_mac_state); + +int nic_set_led(struct net_device *ndev, u32 type, u32 status) +{ + struct hnae3_led_state_para para; + + para.status = status; + para.type = type; + + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_LED, + ¶, sizeof(para)); +} +EXPORT_SYMBOL(nic_set_led); + +int nic_get_led_signal(struct net_device *ndev, struct hnae3_lamp_signal *signal) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_GET_LED_SIGNAL, + signal, sizeof(*signal)); +} +EXPORT_SYMBOL(nic_get_led_signal); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index 907cbaf2a3f1..3e5f9ae37e85 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -51,4 +51,6 @@ int nic_set_pfc_time_cfg(struct net_device *ndev, u16 time); int nic_get_port_fault_status(struct net_device *ndev, u32 fault_type, u32 *status); int nic_get_port_wire_type(struct net_device *ndev, u32 *wire_type); int nic_set_mac_state(struct net_device *ndev, int enable); +int nic_set_led(struct net_device *ndev, u32 type, u32 status); +int nic_get_led_signal(struct net_device *ndev, struct hnae3_lamp_signal *signal); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index 8b6f75cad7f7..f299a486e5d2 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -682,6 +682,56 @@ static int hclge_set_mac_state(struct hclge_dev *hdev, void *data, return ret; }
+static int hclge_set_led(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_lamp_signal_cmd *para_cmd; + struct hnae3_led_state_para *para; + struct hclge_desc desc; + int ret; + + if (length != sizeof(struct hnae3_led_state_para)) + return -EINVAL; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SET_LED, false); + para = (struct hnae3_led_state_para *)data; + para_cmd = (struct hclge_lamp_signal_cmd *)desc.data; + para_cmd->type = cpu_to_le32(para->type); + para_cmd->status = cpu_to_le32(para->status); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, "failed to set led, ret = %d\n", ret); + + return ret; +} + +static int hclge_get_led_signal(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hclge_lamp_signal_cmd *signal_cmd; + struct hnae3_lamp_signal *signal; + struct hclge_desc desc; + int ret; + + if (length != sizeof(struct hnae3_lamp_signal)) + return -EINVAL; + + ret = hclge_get_info_from_cmd(hdev, &desc, 1, HCLGE_OPC_SET_LED); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get led signal, ret = %d\n", ret); + return ret; + } + + signal = (struct hnae3_lamp_signal *)data; + signal_cmd = (struct hclge_lamp_signal_cmd *)desc.data; + signal->error = signal_cmd->error; + signal->locate = signal_cmd->locate; + signal->activity = signal_cmd->activity; + return 0; +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -854,6 +904,8 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_GET_PORT_FAULT_STATUS] = hclge_get_port_fault_status, [HNAE3_EXT_OPC_GET_PORT_TYPE] = hclge_get_port_wire_type, [HNAE3_EXT_OPC_SET_MAC_STATE] = hclge_set_mac_state, + [HNAE3_EXT_OPC_SET_LED] = hclge_set_led, + [HNAE3_EXT_OPC_GET_LED_SIGNAL] = hclge_get_led_signal, };
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 c06b5164accd..dab62a588e53 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -83,6 +83,15 @@ struct hclge_sfp_enable_cmd { __le32 rsv[5]; };
+struct hclge_lamp_signal_cmd { + __le32 type; + __le32 status; + u8 error; + u8 locate; + u8 activity; + u8 rsv[13]; +}; + enum hclge_ext_opcode_type { HCLGE_OPC_CONFIG_NIC_CLOCK = 0x0060, HCLGE_OPC_CONFIG_SWITCH_PARAM = 0x1033, @@ -92,6 +101,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_SET_LED = 0x7007, HCLGE_OPC_DISABLE_NET_LANE = 0x7008, HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019, HCLGE_OPC_CFG_GET_HILINK_REF_LOS = 0x701B,
From: Jian Shen shenjian15@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
Add extend interface support for read and write phy register with page. Sofar it supports only Phy RTL8211 and YT8521.
Signed-off-by: Jian Shen shenjian15@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 9 + .../net/ethernet/hisilicon/hns3/hns3_ext.c | 36 ++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 11 + .../hisilicon/hns3/hns3pf/hclge_cmd.h | 8 +- .../hisilicon/hns3/hns3pf/hclge_ext.c | 559 ++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 32 + 6 files changed, 654 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 37eee8743395..7e0463c320bd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -51,6 +51,8 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_SET_MAC_STATE, HNAE3_EXT_OPC_SET_LED, HNAE3_EXT_OPC_GET_LED_SIGNAL, + HNAE3_EXT_OPC_GET_PHY_REG, + HNAE3_EXT_OPC_SET_PHY_REG, };
struct hnae3_led_state_para { @@ -58,6 +60,13 @@ struct hnae3_led_state_para { u32 status; };
+struct hnae3_phy_para { + u32 page_select_addr; + u32 reg_addr; + u16 page; + u16 data; +}; + struct hnae3_lamp_signal { u8 error; u8 locate; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index 1c03a4f5e457..7172831523a9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -501,3 +501,39 @@ int nic_get_led_signal(struct net_device *ndev, struct hnae3_lamp_signal *signal signal, sizeof(*signal)); } EXPORT_SYMBOL(nic_get_led_signal); + +int nic_get_phy_reg(struct net_device *ndev, u32 page_select_addr, + u16 page, u32 reg_addr, u16 *data) +{ + struct hnae3_phy_para para; + int ret; + + if (!data) + return -EINVAL; + + para.page_select_addr = page_select_addr; + para.page = page; + para.reg_addr = reg_addr; + ret = nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_GET_PHY_REG, + ¶, sizeof(para)); + if (ret) + return ret; + + *data = para.data; + return 0; +} +EXPORT_SYMBOL(nic_get_phy_reg); + +int nic_set_phy_reg(struct net_device *ndev, u32 page_select_addr, + u16 page, u32 reg_addr, u16 data) +{ + struct hnae3_phy_para para; + + para.page_select_addr = page_select_addr; + para.page = page; + para.reg_addr = reg_addr; + para.data = data; + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_PHY_REG, + ¶, sizeof(para)); +} +EXPORT_SYMBOL(nic_set_phy_reg); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index 3e5f9ae37e85..3f2e0d2f0149 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -15,6 +15,13 @@ #define HNS3_PFC_STORM_PARA_PERIOD_MAX 2000 #define HNS3_MAX_TX_TIMEOUT 600
+#define nic_set_8211_phy_reg nic_set_phy_reg +#define nic_get_8211_phy_reg nic_get_phy_reg +#define nic_set_8521_phy_reg(ndev, page, reg_addr, data) \ + nic_set_phy_reg(ndev, 0, page, reg_addr, data) +#define nic_get_8521_phy_reg(ndev, page, reg_addr, data) \ + nic_get_phy_reg(ndev, 0, page, reg_addr, data) + #define nic_get_cdr_flash_status(ndev, status) \ nic_get_port_fault_status(ndev, HNAE3_FAULT_TYPE_CDR_FLASH, status) #define nic_get_hilink_ref_los(ndev, status) \ @@ -53,4 +60,8 @@ int nic_get_port_wire_type(struct net_device *ndev, u32 *wire_type); int nic_set_mac_state(struct net_device *ndev, int enable); int nic_set_led(struct net_device *ndev, u32 type, u32 status); int nic_get_led_signal(struct net_device *ndev, struct hnae3_lamp_signal *signal); +int nic_get_phy_reg(struct net_device *ndev, u32 page_select_addr, + u16 page, u32 reg_addr, u16 *data); +int nic_set_phy_reg(struct net_device *ndev, u32 page_select_addr, + u16 page, u32 reg_addr, u16 data); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index da1efc921393..c18101f89442 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -873,11 +873,17 @@ struct hclge_phy_link_ksetting_1_cmd { u8 rsv[22]; };
+#define HCLGE_PHY_RW_DIRECTLY 0 +#define HCLGE_PHY_RW_WITH_PAGE 1 struct hclge_phy_reg_cmd { __le16 reg_addr; u8 rsv0[2]; __le16 reg_val; - u8 rsv1[18]; + u8 rsv1[2]; + u8 type; + u8 dev_addr; + __le16 page; + u8 rsv2[12]; };
struct hclge_wol_cfg_cmd { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index f299a486e5d2..a396e965bc5e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -732,6 +732,563 @@ static int hclge_get_led_signal(struct hclge_dev *hdev, void *data, return 0; }
+static int hclge_def_phy_opt(struct mii_bus *mdio_bus, u32 phy_addr, + u16 reg_addr, u16 *data, + enum hclge_phy_op_code opt_type) +{ + int ret; + + if (opt_type == PHY_OP_READ) { + ret = mdio_bus->read(mdio_bus, phy_addr, reg_addr); + if (ret >= 0) { + *data = (u16)ret; + ret = 0; + } + } else { + ret = mdio_bus->write(mdio_bus, phy_addr, reg_addr, *data); + } + return ret; +} + +static int hclge_phy_reg_opt(struct hclge_dev *hdev, + struct hnae3_phy_para *para, + enum hclge_phy_op_code opt_type) +{ + struct mii_bus *mdio_bus = hdev->hw.mac.mdio_bus; + u32 phy_addr = hdev->hw.mac.phy_addr; + bool need_page_select = false; + u16 cur_page; + int ret; + + /* operate flow: + * 1 record current page addr + * 2 jump to operated page + * 3 operate register(read or write) + * 4 come back to the page recorded in the first step. + */ + mutex_lock(&mdio_bus->mdio_lock); + + /* check if page select is needed and record current page addr. + * no need to change page when read page 0 + */ + if (opt_type != PHY_OP_READ || para->page != 0) { + ret = mdio_bus->read(mdio_bus, phy_addr, + para->page_select_addr); + if (ret < 0) { + dev_err(&hdev->pdev->dev, + "failed to read current phy %u reg page\n", + phy_addr); + mutex_unlock(&mdio_bus->mdio_lock); + return ret; + } + cur_page = (u16)ret; + need_page_select = cur_page != para->page; + } + + /* jump to operated page */ + if (need_page_select) { + ret = mdio_bus->write(mdio_bus, phy_addr, + para->page_select_addr, para->page); + if (ret < 0) { + mutex_unlock(&mdio_bus->mdio_lock); + dev_err(&hdev->pdev->dev, + "failed to change phy %u page %u to page %u\n", + phy_addr, cur_page, para->page); + return ret; + } + } + + /* operate register(read or write) */ + ret = hclge_def_phy_opt(mdio_bus, phy_addr, para->reg_addr, ¶->data, + opt_type); + if (ret < 0) + dev_err(&hdev->pdev->dev, + "failed to %s phy %u page %u reg %u\n, ret = %d", + opt_type == PHY_OP_READ ? "read" : "write", + phy_addr, para->page, para->reg_addr, ret); + + /* come back to the page recorded in the first step. */ + if (need_page_select) { + ret = mdio_bus->write(mdio_bus, phy_addr, + para->page_select_addr, cur_page); + if (ret < 0) + dev_err(&hdev->pdev->dev, + "failed to restore phy %u reg page %u\n", + phy_addr, cur_page); + } + + mutex_unlock(&mdio_bus->mdio_lock); + + return ret; +} + +static int hclge_8521_phy_ext_opt(struct mii_bus *mdio_bus, u32 phy_addr, + u16 reg_addr, u16 *data, + enum hclge_phy_op_code opt_type) +{ +#define EXT_REG_ADDR 0x1e +#define EXT_DATA_ADDR 0x1f + int ret; + + ret = mdio_bus->write(mdio_bus, phy_addr, EXT_REG_ADDR, reg_addr); + if (ret < 0) + return ret; + + return hclge_def_phy_opt(mdio_bus, phy_addr, EXT_DATA_ADDR, data, + opt_type); +} + +static int hclge_8521_phy_mmd_opt(struct mii_bus *mdio_bus, u32 phy_addr, + u32 reg_addr, u16 *data, + enum hclge_phy_op_code opt_type) +{ +#define MMD_REG_ADDR 0xd +#define MMD_DATA_ADDR 0xe + u16 mmd_index; + u16 mmd_reg; + int ret; + + mmd_index = reg_addr >> 16U; + mmd_reg = reg_addr & 0xFFFF; + + ret = mdio_bus->write(mdio_bus, phy_addr, MMD_REG_ADDR, mmd_index); + if (ret < 0) + return ret; + ret = mdio_bus->write(mdio_bus, phy_addr, MMD_DATA_ADDR, mmd_reg); + if (ret < 0) + return ret; + ret = mdio_bus->write(mdio_bus, phy_addr, MMD_REG_ADDR, + mmd_index | 0x4000); + if (ret < 0) + return ret; + + return hclge_def_phy_opt(mdio_bus, phy_addr, MMD_DATA_ADDR, data, + opt_type); +} + +static void hclge_8521_phy_restores_to_utp_mii(struct hclge_dev *hdev, + struct mii_bus *mdio_bus, + u32 phy_addr) +{ + u16 phy_mii_region_val = 0x6; + u16 utp_region_val = 0x0; + int ret; + + ret = hclge_8521_phy_ext_opt(mdio_bus, phy_addr, + HCLGE_8521_PHY_SMI_SDS_ADDR, + &utp_region_val, PHY_OP_WRITE); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to choose phy space, ret = %d\n", ret); + + ret = hclge_8521_phy_ext_opt(mdio_bus, phy_addr, + HCLGE_8521_PHY_LDS_MII_ADDR, + &phy_mii_region_val, PHY_OP_WRITE); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to choose phy MII, ret = %d\n", ret); +} + +static int hclge_8521_phy_utp_mii_opt(struct hnae3_phy_para *para, + struct mii_bus *mdio_bus, u32 phy_addr, + enum hclge_phy_op_code opt_type) +{ + u16 phy_mii_region_val = 0x6; + u16 utp_region_val = 0x0; + int ret; + + ret = hclge_8521_phy_ext_opt(mdio_bus, phy_addr, + HCLGE_8521_PHY_SMI_SDS_ADDR, + &utp_region_val, PHY_OP_WRITE); + if (ret) + return ret; + + ret = hclge_8521_phy_ext_opt(mdio_bus, phy_addr, + HCLGE_8521_PHY_LDS_MII_ADDR, + &phy_mii_region_val, PHY_OP_WRITE); + if (ret) + return ret; + + return hclge_def_phy_opt(mdio_bus, phy_addr, (u16)para->reg_addr, + ¶->data, opt_type); +} + +static int hclge_8521_phy_utp_mmd_opt(struct hnae3_phy_para *para, + struct mii_bus *mdio_bus, u32 phy_addr, + enum hclge_phy_op_code opt_type) +{ + u16 utp_region_val = 0x0; + int ret; + + ret = hclge_8521_phy_ext_opt(mdio_bus, phy_addr, + HCLGE_8521_PHY_SMI_SDS_ADDR, + &utp_region_val, PHY_OP_WRITE); + if (ret) + return ret; + + return hclge_8521_phy_mmd_opt(mdio_bus, phy_addr, para->reg_addr, + ¶->data, opt_type); +} + +static int hclge_8521_phy_utp_lds_opt(struct hnae3_phy_para *para, + struct mii_bus *mdio_bus, u32 phy_addr, + enum hclge_phy_op_code opt_type) +{ + u16 lds_mii_region_val = 0x4; + u16 utp_region_val = 0x0; + int ret; + + ret = hclge_8521_phy_ext_opt(mdio_bus, phy_addr, + HCLGE_8521_PHY_SMI_SDS_ADDR, + &utp_region_val, PHY_OP_WRITE); + if (ret) + return ret; + + ret = hclge_8521_phy_ext_opt(mdio_bus, phy_addr, + HCLGE_8521_PHY_LDS_MII_ADDR, + &lds_mii_region_val, PHY_OP_WRITE); + if (ret) + return ret; + + return hclge_def_phy_opt(mdio_bus, phy_addr, (u16)para->reg_addr, + ¶->data, opt_type); +} + +static int hclge_8521_phy_utp_ext_opt(struct hnae3_phy_para *para, + struct mii_bus *mdio_bus, u32 phy_addr, + enum hclge_phy_op_code opt_type) +{ + u16 utp_region_val = 0x0; + int ret; + + ret = hclge_8521_phy_ext_opt(mdio_bus, phy_addr, + HCLGE_8521_PHY_SMI_SDS_ADDR, + &utp_region_val, PHY_OP_WRITE); + if (ret) + return ret; + + return hclge_8521_phy_ext_opt(mdio_bus, phy_addr, (u16)para->reg_addr, + ¶->data, opt_type); +} + +static int hclge_8521_phy_sds_mii_opt(struct hnae3_phy_para *para, + struct mii_bus *mdio_bus, u32 phy_addr, + enum hclge_phy_op_code opt_type) +{ + u16 sds_region_val = 0x2; + int ret; + + ret = hclge_8521_phy_ext_opt(mdio_bus, phy_addr, + HCLGE_8521_PHY_SMI_SDS_ADDR, + &sds_region_val, PHY_OP_WRITE); + if (ret) + return ret; + + return hclge_def_phy_opt(mdio_bus, phy_addr, (u16)para->reg_addr, + ¶->data, opt_type); +} + +static int hclge_8521_phy_sds_ext_opt(struct hnae3_phy_para *para, + struct mii_bus *mdio_bus, u32 phy_addr, + enum hclge_phy_op_code opt_type) +{ + u16 sds_region_val = 0x2; + int ret; + + ret = hclge_8521_phy_ext_opt(mdio_bus, phy_addr, + HCLGE_8521_PHY_SMI_SDS_ADDR, + &sds_region_val, PHY_OP_WRITE); + if (ret) + return ret; + + return hclge_8521_phy_ext_opt(mdio_bus, phy_addr, (u16)para->reg_addr, + ¶->data, opt_type); +} + +static int hclge_8521_phy_opt(struct hclge_dev *hdev, + struct hnae3_phy_para *para, + enum hclge_phy_op_code opt_type) +{ + struct mii_bus *mdio_bus = hdev->hw.mac.mdio_bus; + u32 phy_addr = hdev->hw.mac.phy_addr; + int ret; + + mutex_lock(&mdio_bus->mdio_lock); + switch (para->page) { + case HCLGE_PHY_REGION_UTP_MII: + ret = hclge_8521_phy_utp_mii_opt(para, mdio_bus, + phy_addr, opt_type); + break; + case HCLGE_PHY_REGION_UTP_MMD: + ret = hclge_8521_phy_utp_mmd_opt(para, mdio_bus, + phy_addr, opt_type); + break; + case HCLGE_PHY_REGION_UTP_LDS: + ret = hclge_8521_phy_utp_lds_opt(para, mdio_bus, + phy_addr, opt_type); + break; + case HCLGE_PHY_REGION_UTP_EXT: + ret = hclge_8521_phy_utp_ext_opt(para, mdio_bus, + phy_addr, opt_type); + break; + case HCLGE_PHY_REGION_SDS_MII: + ret = hclge_8521_phy_sds_mii_opt(para, mdio_bus, + phy_addr, opt_type); + break; + case HCLGE_PHY_REGION_SDS_EXT: + ret = hclge_8521_phy_sds_ext_opt(para, mdio_bus, + phy_addr, opt_type); + break; + case HCLGE_PHY_REGION_COM_REG: + ret = hclge_8521_phy_ext_opt(mdio_bus, phy_addr, + (u16)para->reg_addr, + ¶->data, opt_type); + break; + default: + dev_err(&hdev->pdev->dev, "invalid reg region: %d\n", + para->page); + mutex_unlock(&mdio_bus->mdio_lock); + return -EINVAL; + } + + if (ret) + dev_err(&hdev->pdev->dev, + "phy operation failed %d, reg_region: %d, data: 0x%x\n", + ret, para->page, para->data); + + /* Set the region to UTP MII after operating the 8521 phy register */ + hclge_8521_phy_restores_to_utp_mii(hdev, mdio_bus, phy_addr); + mutex_unlock(&mdio_bus->mdio_lock); + return ret; +} + +static int hclge_check_phy_opt_param(struct hclge_dev *hdev, void *data, + size_t length) +{ + struct hnae3_phy_para *para = (struct hnae3_phy_para *)data; + struct hclge_mac *mac = &hdev->hw.mac; + + if (length != sizeof(*para)) + return -EINVAL; + + if (mac->media_type != HNAE3_MEDIA_TYPE_COPPER) { + dev_err(&hdev->pdev->dev, "this is not a copper port"); + return -EOPNOTSUPP; + } + + if (hnae3_dev_phy_imp_supported(hdev)) + return 0; + + if (!mac->phydev) { + dev_err(&hdev->pdev->dev, "this net device has no phy"); + return -EINVAL; + } + + if (!mac->mdio_bus) { + dev_err(&hdev->pdev->dev, "this net device has no mdio bus"); + return -EINVAL; + } + + return 0; +} + +static int hclge_8211_phy_indirect_opt(struct hclge_dev *hdev, + struct hnae3_phy_para *para, + struct mii_bus *mdio_bus, u32 phy_addr, + enum hclge_phy_op_code opt_type) +{ + u32 indirect_reg_data; + int ret; + + /* select indirect page 0xa43 */ + ret = mdio_bus->write(mdio_bus, phy_addr, para->page_select_addr, + HCLGE_8211_PHY_INDIRECT_PAGE); + if (ret < 0) { + dev_err(&hdev->pdev->dev, + "failed to change phy %u indirect page 0xa43\n", + phy_addr); + return ret; + } + /* indirect access addr = page_no*16 + 2*(reg_no%16) */ + indirect_reg_data = (para->page << 4) + ((para->reg_addr % 16) << 1); + ret = mdio_bus->write(mdio_bus, phy_addr, HCLGE_8211_PHY_INDIRECT_REG, + indirect_reg_data); + if (ret < 0) { + dev_err(&hdev->pdev->dev, + "failed to write phy %u indirect reg\n", phy_addr); + return ret; + } + + ret = hclge_def_phy_opt(mdio_bus, phy_addr, + HCLGE_8211_PHY_INDIRECT_DATA, ¶->data, + opt_type); + if (ret < 0) + dev_err(&hdev->pdev->dev, + "failed to %s phy %u indirect data\n, ret = %d", + opt_type == PHY_OP_READ ? "read" : "write", + phy_addr, ret); + + return ret; +} + +static int hclge_8211_phy_need_indirect_access(u16 page) +{ + if (page >= HCLGE_8211_PHY_INDIRECT_RANGE1_S && + page <= HCLGE_8211_PHY_INDIRECT_RANGE1_E) + return true; + else if (page >= HCLGE_8211_PHY_INDIRECT_RANGE2_S && + page <= HCLGE_8211_PHY_INDIRECT_RANGE2_E) + return true; + + return false; +} + +static int hclge_8211_phy_reg_opt(struct hclge_dev *hdev, + struct hnae3_phy_para *para, + enum hclge_phy_op_code opt_type) +{ + struct mii_bus *mdio_bus = hdev->hw.mac.mdio_bus; + u32 phy_addr = hdev->hw.mac.phy_addr; + u16 save_page; + int ret; + + mutex_lock(&mdio_bus->mdio_lock); + ret = mdio_bus->read(mdio_bus, phy_addr, para->page_select_addr); + if (ret < 0) { + dev_err(&hdev->pdev->dev, + "failed to record phy %u reg page\n", phy_addr); + mutex_unlock(&mdio_bus->mdio_lock); + return ret; + } + save_page = ret; + ret = hclge_8211_phy_indirect_opt(hdev, para, mdio_bus, phy_addr, + opt_type); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to indirect access 8211 phy %u\n", phy_addr); + ret = mdio_bus->write(mdio_bus, phy_addr, para->page_select_addr, + save_page); + if (ret < 0) + dev_err(&hdev->pdev->dev, + "failed to restore phy %u reg page %u\n", + phy_addr, save_page); + mutex_unlock(&mdio_bus->mdio_lock); + + return ret; +} + +static int hclge_rw_8211_phy_reg(struct hclge_dev *hdev, + struct hnae3_phy_para *para, + enum hclge_phy_op_code opt_type) +{ + if (hclge_8211_phy_need_indirect_access(para->page)) + return hclge_8211_phy_reg_opt(hdev, para, opt_type); + + return hclge_phy_reg_opt(hdev, para, opt_type); +} + +/* used when imp support phy drvier */ +static int hclge_read_phy_reg_with_page(struct hclge_dev *hdev, u16 page, + u16 reg_addr, u16 *val) +{ + struct hclge_phy_reg_cmd *req; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PHY_REG, true); + + req = (struct hclge_phy_reg_cmd *)desc.data; + req->reg_addr = cpu_to_le16(reg_addr); + req->type = HCLGE_PHY_RW_WITH_PAGE; + req->page = cpu_to_le16(page); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to read phy page %u reg %u, ret = %d\n", + page, reg_addr, ret); + return ret; + } + + *val = le16_to_cpu(req->reg_val); + return 0; +} + +/* used when imp support phy drvier */ +static int hclge_write_phy_reg_with_page(struct hclge_dev *hdev, u16 page, + u16 reg_addr, u16 val) +{ + struct hclge_phy_reg_cmd *req; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PHY_REG, false); + + req = (struct hclge_phy_reg_cmd *)desc.data; + req->reg_addr = cpu_to_le16(reg_addr); + req->type = HCLGE_PHY_RW_WITH_PAGE; + req->page = cpu_to_le16(page); + req->reg_val = cpu_to_le16(val); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to write phy page %u reg %u, ret = %d\n", + page, reg_addr, ret); + + return ret; +} + +static int hclge_rw_phy_reg_with_page(struct hclge_dev *hdev, + struct hnae3_phy_para *para, + enum hclge_phy_op_code opt_type) +{ + if (opt_type == PHY_OP_READ) + return hclge_read_phy_reg_with_page(hdev, para->page, + para->reg_addr, + ¶->data); + + return hclge_write_phy_reg_with_page(hdev, para->page, para->reg_addr, + para->data); +} + +static int hclge_rw_phy_reg(struct hclge_dev *hdev, void *data, + size_t length, enum hclge_phy_op_code opt_type) +{ + struct hnae3_phy_para *para = (struct hnae3_phy_para *)data; + struct hclge_mac *mac = &hdev->hw.mac; + u32 phy_id; + int ret; + + ret = hclge_check_phy_opt_param(hdev, data, length); + if (ret < 0) + return ret; + + if (hnae3_dev_phy_imp_supported(hdev)) + return hclge_rw_phy_reg_with_page(hdev, para, opt_type); + + phy_id = mac->phydev->phy_id & HCLGE_PHY_ID_MASK; + switch (phy_id) { + case HCLGE_PHY_ID_FOR_RTL8211: + return hclge_rw_8211_phy_reg(hdev, para, opt_type); + case HCLGE_PHY_ID_FOR_YT8521: + return hclge_8521_phy_opt(hdev, para, opt_type); + case HCLGE_PHY_ID_FOR_MVL1512: + default: + return hclge_phy_reg_opt(hdev, para, opt_type); + } +} + +static int hclge_get_phy_reg(struct hclge_dev *hdev, void *data, size_t length) +{ + return hclge_rw_phy_reg(hdev, data, length, PHY_OP_READ); +} + +static int hclge_set_phy_reg(struct hclge_dev *hdev, void *data, size_t length) +{ + return hclge_rw_phy_reg(hdev, data, length, PHY_OP_WRITE); +} + static void hclge_ext_resotre_config(struct hclge_dev *hdev) { if (hdev->reset_type != HNAE3_IMP_RESET && @@ -906,6 +1463,8 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_SET_MAC_STATE] = hclge_set_mac_state, [HNAE3_EXT_OPC_SET_LED] = hclge_set_led, [HNAE3_EXT_OPC_GET_LED_SIGNAL] = hclge_get_led_signal, + [HNAE3_EXT_OPC_GET_PHY_REG] = hclge_get_phy_reg, + [HNAE3_EXT_OPC_SET_PHY_REG] = hclge_set_phy_reg, };
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 dab62a588e53..090152a87c60 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -5,6 +5,38 @@ #define __HCLGE_EXT_H #include <linux/types.h>
+#define HCLGE_PHY_ID_FOR_RTL8211 0x001cc910 +#define HCLGE_PHY_ID_FOR_MVL1512 0x01410dd0 +#define HCLGE_PHY_ID_FOR_YT8521 0x00000110 +#define HCLGE_PHY_ID_MASK 0xFFFFFFF0U + +enum hclge_phy_page_region { + HCLGE_PHY_REGION_UTP_MII, + HCLGE_PHY_REGION_UTP_MMD, + HCLGE_PHY_REGION_UTP_LDS, + HCLGE_PHY_REGION_UTP_EXT, + HCLGE_PHY_REGION_SDS_MII, + HCLGE_PHY_REGION_SDS_EXT, + HCLGE_PHY_REGION_COM_REG, + HCLGE_PHY_REGION_MAX +}; + +enum hclge_phy_op_code { + PHY_OP_READ, + PHY_OP_WRITE +}; + +#define HCLGE_8211_PHY_INDIRECT_PAGE 0xa43 +#define HCLGE_8211_PHY_INDIRECT_REG 0x1b +#define HCLGE_8211_PHY_INDIRECT_DATA 0x1c +#define HCLGE_8211_PHY_INDIRECT_RANGE1_S 0xDC0 +#define HCLGE_8211_PHY_INDIRECT_RANGE1_E 0xDCF +#define HCLGE_8211_PHY_INDIRECT_RANGE2_S 0xDE0 +#define HCLGE_8211_PHY_INDIRECT_RANGE2_E 0xDF0 + +#define HCLGE_8521_PHY_SMI_SDS_ADDR 0xA000 +#define HCLGE_8521_PHY_LDS_MII_ADDR 0x100 + #define HCLGE_NOTIFY_PARA_CFG_PKT_EN BIT(0) #define HCLGE_NOTIFY_PARA_CFG_START_EN BIT(1) #define HCLGE_NOTIFY_PARA_CFG_PKT_NUM_M GENMASK(5, 2)
From: Jian Shen shenjian15@huawei.com
driver inclusion category: cleanup bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ CVE: NA
----------------------------------------------------------------------
There are several driver APIs missed to validate the input parameters, which may cause security risk. So fixes it.
Signed-off-by: Jian Shen shenjian15@huawei.com Signed-off-by: Jijie Shao shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hns3_ext.c | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index 7172831523a9..9220418e67b6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -34,14 +34,14 @@ static int nic_invoke_pri_ops(struct net_device *ndev, int opcode, struct hnae3_handle *h; int ret;
+ if (nic_netdev_match_check(ndev)) + return -ENODEV; + if ((!data && length) || (data && !length)) { netdev_err(ndev, "failed to check data and length"); return -EINVAL; }
- if (nic_netdev_match_check(ndev)) - return -ENODEV; - h = hns3_get_handle(ndev); if (!h->ae_algo->ops->priv_ops) return -EOPNOTSUPP; @@ -58,6 +58,9 @@ static int nic_invoke_pri_ops(struct net_device *ndev, int opcode, void nic_chip_recover_handler(struct net_device *ndev, enum hnae3_event_type_custom event_t) { + if (nic_netdev_match_check(ndev)) + return; + dev_info(&ndev->dev, "reset type is %d!!\n", event_t);
if (event_t == HNAE3_PPU_POISON_CUSTOM) @@ -100,8 +103,7 @@ int nic_set_pfc_storm_para(struct net_device *ndev, u32 dir, u32 enable,
if (nic_check_pfc_storm_para(dir, enable, period_ms, times, recovery_period_ms)) { - dev_err(&ndev->dev, - "set pfc storm para failed because invalid input param.\n"); + pr_err("set pfc storm para failed because invalid input param.\n"); return -EINVAL; }
@@ -125,8 +127,7 @@ int nic_get_pfc_storm_para(struct net_device *ndev, u32 dir, u32 *enable, if (!enable || !period_ms || !times || !recovery_period_ms || (dir != HNS3_PFC_STORM_PARA_DIR_RX && dir != HNS3_PFC_STORM_PARA_DIR_TX)) { - dev_err(&ndev->dev, - "get pfc storm para failed because invalid input param.\n"); + pr_err("get pfc storm para failed because invalid input param.\n"); return -EINVAL; }
@@ -183,6 +184,9 @@ int nic_clean_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats) struct hnae3_handle *h; int i, ret;
+ if (nic_netdev_match_check(ndev)) + return -ENODEV; + priv = netdev_priv(ndev); h = hns3_get_handle(ndev); kinfo = &h->kinfo; @@ -222,15 +226,15 @@ int nic_set_cpu_affinity(struct net_device *ndev, cpumask_t *affinity_mask) int ret = 0; u16 i;
- if (!ndev || !affinity_mask) { + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + if (!affinity_mask) { netdev_err(ndev, "Invalid input param when set ethernet cpu affinity\n"); return -EINVAL; }
- if (nic_netdev_match_check(ndev)) - return -ENODEV; - priv = netdev_priv(ndev); rtnl_lock(); if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,转换为PR失败! 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/5... 失败原因:应用补丁/补丁集失败,Patch failed at 0001 net: hns3: add support customized exception handling interfaces. 建议解决方法:请查看失败原因, 确认补丁是否可以应用在当前期望分支的最新代码上
FeedBack: The patch(es) which you have sent to kernel@openeuler.org has been converted to PR failed! Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/5... Failed Reason: apply patch(es) failed, Patch failed at 0001 net: hns3: add support customized exception handling interfaces. Suggest Solution: please checkout if the failed patch(es) can work on the newest codes in expected branch