From 2cf8cdea03bf327fe0b8280f62c7a028835d6371 Mon Sep 17 00:00:00 2001 From: dengweiwei Date: Tue, 23 Apr 2019 18:36:24 +0800 Subject: [PATCH] net: hns3: update IT chip code of hns3 driver driver inclusion category: feature bugzilla: 13683 CVE: NA ------------------------------------------------- Update IT chip code of hns3 driver particularly for dfx. Tested-by: chenjunxin Signed-off-by: dengweiwei Reviewed-by: Hanjun Guo Signed-off-by: Yang Yingliang --- .../hns3/hns-customer/hns3_enet_it.c | 170 ++++++++ .../hns3/hns-customer/hns3_enet_it.h | 18 + .../hns3/hns-customer/hns3_ethtool_it.c | 94 ++++ .../hisilicon/hns3/hns-customer/hns3_ext.c | 319 ++++++++++++++ .../hisilicon/hns3/hns-customer/hns3_ext.h | 35 ++ .../hns3/hns-customer/hns3pf/hclge_cmd_it.c | 15 + .../hns3/hns-customer/hns3pf/hclge_ext.c | 405 ++++++++++++++++++ .../hns3/hns-customer/hns3pf/hclge_ext.h | 79 ++++ .../hns3/hns-customer/hns3pf/hclge_main_it.c | 183 ++++++++ .../hns3/hns-customer/hns3pf/hclge_main_it.h | 52 +++ .../hns3/hns-customer/hns3pf/hclge_test.c | 16 + .../hns3/hns-customer/hns3pf/hclge_test.h | 12 + 12 files changed, 1398 insertions(+) create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_enet_it.c create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_enet_it.h create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ethtool_it.c create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ext.c create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ext.h create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_cmd_it.c create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_ext.c create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_ext.h create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_main_it.c create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_main_it.h create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_test.c create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_test.h diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_enet_it.c b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_enet_it.c new file mode 100644 index 000000000000..0305fcb26588 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_enet_it.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2016-2017 Hisilicon Limited. + +#include +#include +#include +#include +#include +#include + +#include "../hnae3.h" +#include "hns3_enet_it.h" +#include "hns3pf/hclge_main_it.h" +#include "../hns3_enet.h" + +extern const char hns3_driver_string[]; +extern const char hns3_copyright[]; + +#ifdef CONFIG_IT_VALIDATION + +#define HNAE_DRIVER_VERSION "B075" +#define HNAE_DRIVER_VERSION_MAX_LEN 8 + +#ifdef CONFIG_HNS3_X86 +#define HNAE3_DEV_ID_X86_25_GE 0xA125 +#endif + +extern struct ethtool_ops hns3vf_ethtool_ops; +extern struct ethtool_ops hns3_ethtool_ops; +extern struct net_device_ops hns3_nic_netdev_ops; +extern const struct hnae3_client_ops client_ops; +extern struct hnae3_client client; +extern struct pci_driver hns3_driver; +extern const char hns3_driver_name[]; +extern struct pci_error_handlers hns3_err_handler; + +extern int hns3_set_link_ksettings_it(struct net_device *netdev, + const struct ethtool_link_ksettings *cmd); + +/* hns3_pci_tbl - PCI Device ID Table + * + * Last entry must be all 0s + * + * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, + * Class, Class Mask, private data (not used) } + */ +const struct pci_device_id hns3_pci_tbl_it[] = { + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_GE), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA), + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA_MACSEC), + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA), + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA_MACSEC), + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_VF), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_DCB_PFC_VF), + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, +#ifdef CONFIG_HNS3_X86 + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_X86_25_GE), 0}, +#endif + /* required last entry */ + {0, } +}; +MODULE_DEVICE_TABLE(pci, hns3_pci_tbl_it); + +#ifdef CONFIG_EXT_TEST +void hns3_nic_net_timeout_it(struct net_device *ndev) +{ + if (!hns3_get_tx_timeo_queue_info(ndev)) + return; + + nic_call_event(ndev, HNAE3_FUNC_RESET_CUSTOM); +} +#endif + +int hns3_nic_do_ioctl_it(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + switch (cmd) { + case (SIOCDEVPRIVATE + 4): + if (hns3_ioctl) + return hns3_ioctl(netdev, ifr->ifr_data); + pr_err("open nic_test failed"); + return -EINVAL; + default: + return -EINVAL; + } +} + +#if (KERNEL_VERSION(4, 19, 0) > LINUX_VERSION_CODE) +u16 hns3_nic_select_queue_it(struct net_device *ndev, struct sk_buff *skb, + void *accel_priv, + select_queue_fallback_t fallback) +#else +u16 hns3_nic_select_queue_it(struct net_device *ndev, struct sk_buff *skb, + struct net_device *accel_priv, + select_queue_fallback_t fallback) +#endif +{ +#define HNS3_VLAN_PRIO_SHIFT 13 + if (!accel_priv) + if (skb->vlan_tci && !skb->priority) + skb->priority = skb->vlan_tci >> HNS3_VLAN_PRIO_SHIFT; + +#if (KERNEL_VERSION(4, 19, 0) > LINUX_VERSION_CODE) + return fallback(ndev, skb); +#else + return fallback(ndev, skb, accel_priv); +#endif +} + +static int __init hns3_init_module_it(void) +{ + struct ethtool_ops *loc_ethtool_ops; + struct net_device_ops *ndev_ops; + int ret; + +#ifdef CONFIG_EXT_TEST + struct pci_error_handlers *err_handlers; + + err_handlers = (struct pci_error_handlers *)&hns3_err_handler; + err_handlers->slot_reset = NULL; +#endif + + pr_info("%s: %s - version\n", hns3_driver_name, hns3_driver_string); + pr_info("%s: %s\n", hns3_driver_name, hns3_copyright); + + strncpy(hns3_driver_version, HNAE_DRIVER_VERSION, + HNAE_DRIVER_VERSION_MAX_LEN); + + loc_ethtool_ops = (struct ethtool_ops *)&hns3_ethtool_ops; + loc_ethtool_ops->set_link_ksettings = hns3_set_link_ksettings_it; + client.type = HNAE3_CLIENT_KNIC; + snprintf(client.name, HNAE3_CLIENT_NAME_LENGTH - 1, "%s", + hns3_driver_name); + + client.ops = &client_ops; + ndev_ops = (struct net_device_ops *)&hns3_nic_netdev_ops; + ndev_ops->ndo_do_ioctl = hns3_nic_do_ioctl_it; +#ifdef CONFIG_EXT_TEST + ndev_ops->ndo_tx_timeout = hns3_nic_net_timeout_it; +#endif + ndev_ops->ndo_select_queue = hns3_nic_select_queue_it; + + INIT_LIST_HEAD(&client.node); + hns3_dbg_register_debugfs(hns3_driver_name); + + ret = hnae3_register_client(&client); + if (ret) + goto err_reg_client; + + hns3_driver.id_table = hns3_pci_tbl_it; + ret = pci_register_driver(&hns3_driver); + if (ret) + goto err_reg_driver; + + return ret; + +err_reg_driver: + hnae3_unregister_client(&client); +err_reg_client: + hns3_dbg_unregister_debugfs(); + return ret; +} +module_init(hns3_init_module_it); +#endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_enet_it.h b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_enet_it.h new file mode 100644 index 000000000000..9ba52155f1d5 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_enet_it.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2016-2017 Hisilicon Limited. */ + +#ifndef __HNS3_ENET_IT_H +#define __HNS3_ENET_IT_H + +typedef int (*hns3_priv_func)(struct net_device *, void *); +hns3_priv_func hns3_ioctl; + +#define VERSION_NUMBER "$FULL_VERSION" + +#ifndef LINUX_VERSION_CODE +#include +#else +#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) +#endif + +#endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ethtool_it.c b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ethtool_it.c new file mode 100644 index 000000000000..074aa38b47fc --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ethtool_it.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2016-2017 Hisilicon Limited. + +#include +#include +#include +#include "../hns3_enet.h" + +static int hns3_check_ksettings_para(struct net_device *netdev, + const struct ethtool_link_ksettings *cmd) +{ + struct hns3_nic_priv *priv = netdev_priv(netdev); + struct hnae3_handle *h = priv->ae_handle; + + u8 media_type = HNAE3_MEDIA_TYPE_UNKNOWN; + u8 module_type = HNAE3_MODULE_TYPE_UNKNOWN; + u8 autoneg = 0; + u32 speed = 0; + u8 duplex = 0; + u32 check_flag; + + /* Verify the settings we care about. */ + if (cmd->base.autoneg != AUTONEG_ENABLE && + cmd->base.autoneg != AUTONEG_DISABLE) + return -EINVAL; + + if (h->ae_algo->ops->get_media_type) + h->ae_algo->ops->get_media_type(h, &media_type, &module_type); + + if (h->ae_algo->ops->get_ksettings_an_result) + h->ae_algo->ops->get_ksettings_an_result(h, &autoneg, &speed, + &duplex); + + if (cmd->base.autoneg == autoneg && + cmd->base.speed == speed && + cmd->base.duplex == duplex) + return 0; + + if (media_type == HNAE3_MEDIA_TYPE_COPPER) { + check_flag = (cmd->base.speed != SPEED_10 && + cmd->base.speed != SPEED_100 && + cmd->base.speed != SPEED_1000); + if (check_flag) + return -EINVAL; + } else { + check_flag = (cmd->base.speed != SPEED_1000 && + cmd->base.speed != SPEED_10000 && + cmd->base.speed != SPEED_25000 && + cmd->base.speed != SPEED_40000 && + cmd->base.speed != SPEED_50000 && + cmd->base.speed != SPEED_100000); + if (check_flag) + return -EINVAL; + } + + check_flag = (cmd->base.duplex != DUPLEX_HALF && + cmd->base.duplex != DUPLEX_FULL); + + if (check_flag) + return -EINVAL; + + return 0; +} + +int hns3_set_link_ksettings_it(struct net_device *netdev, + const struct ethtool_link_ksettings *cmd) +{ + struct hns3_nic_priv *priv = netdev_priv(netdev); + struct hnae3_handle *h = priv->ae_handle; + int ret = 0; + + if (!h->ae_algo || !h->ae_algo->ops) + return -ESRCH; + + ret = hns3_check_ksettings_para(netdev, cmd); + if (ret) + return ret; + + netdev_info(netdev, "set link setting autoneg = %d, speed = %d, duplex = %d\n", + cmd->base.autoneg, cmd->base.speed, cmd->base.duplex); + + if (netdev->phydev) + return phy_ethtool_ksettings_set(netdev->phydev, cmd); + + if (h->ae_algo->ops->set_autoneg) + h->ae_algo->ops->set_autoneg(h, cmd->base.autoneg); + + if (h->ae_algo->ops->cfg_mac_speed_dup_h) + h->ae_algo->ops->cfg_mac_speed_dup_h(h, + cmd->base.speed, cmd->base.duplex); + + return 0; +} +EXPORT_SYMBOL(hns3_set_link_ksettings_it); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ext.c new file mode 100644 index 000000000000..76161f1672df --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ext.c @@ -0,0 +1,319 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2016-2017 Hisilicon Limited. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hns3_ext.h" + +extern const char hns3_driver_name[]; + +int nic_netdev_match_check(struct net_device *netdev) +{ + struct ethtool_drvinfo drv_info; + + if (!netdev) + return -EINVAL; + + if (netdev->ethtool_ops && netdev->ethtool_ops->get_drvinfo) + netdev->ethtool_ops->get_drvinfo(netdev, &drv_info); + + if (!strncmp(drv_info.driver, hns3_driver_name, + strlen(hns3_driver_name))) + return 0; + + return -EINVAL; +} +EXPORT_SYMBOL(nic_netdev_match_check); + +void nic_chip_recover_handler(struct net_device *netdev, + enum hnae3_reset_type_custom event_t) +{ + struct hnae3_ae_dev *ae_dev; + struct hns3_nic_priv *priv; + struct hnae3_handle *h; + + if (nic_netdev_match_check(netdev)) + return; + + priv = netdev_priv(netdev); + h = priv->ae_handle; + ae_dev = pci_get_drvdata(h->pdev); + + if (ae_dev->ops->reset_event) + ae_dev->ops->reset_event(h->pdev, NULL); +} +EXPORT_SYMBOL(nic_chip_recover_handler); + +int nic_clean_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats) +{ + struct hns3_nic_priv *priv; + struct hnae3_handle *h; + struct hnae3_knic_private_info *kinfo; + struct hns3_enet_ring *ring; + int i; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + priv = netdev_priv(ndev); + h = hns3_get_handle(ndev); + kinfo = &h->kinfo; + hclge_clean_stats64(h); + + for (i = 0; i < kinfo->num_tqps; i++) { + ring = priv->ring_data[i].ring; + memset(&ring->stats, 0, sizeof(struct ring_stats)); + ring = priv->ring_data[i + kinfo->num_tqps].ring; + memset(&ring->stats, 0, sizeof(struct ring_stats)); + } + + memset(&ndev->stats, 0, sizeof(struct net_device_stats)); + return 0; +} +EXPORT_SYMBOL(nic_clean_stats64); + +int nic_get_chipid(struct net_device *ndev, u32 *chip_id) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + if (!chip_id) + return -EINVAL; + + h = hns3_get_handle(ndev); + return hclge_get_chipid(h, chip_id); +} +EXPORT_SYMBOL(nic_get_chipid); + +int nic_get_sfpinfo(struct net_device *ndev, u8 *buff, u16 size, u16 *outlen) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + if (!buff || !outlen) + return -EINVAL; + + h = hns3_get_handle(ndev); + return hclge_get_sfpinfo(h, buff, 0, size, outlen); +} +EXPORT_SYMBOL(nic_get_sfpinfo); + +int nic_get_sfp_present(struct net_device *ndev, u32 *present) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + if (!present) + return -EINVAL; + + h = hns3_get_handle(ndev); + return hclge_get_sfp_present(h, present); +} +EXPORT_SYMBOL(nic_get_sfp_present); + +int nic_set_sfp_state(struct net_device *ndev, bool en) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + h = hns3_get_handle(ndev); + return hclge_set_sfp_state(h, en); +} +EXPORT_SYMBOL(nic_set_sfp_state); + +int nic_get_sfp_speed(struct net_device *ndev, u32 *speed) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + if (!speed) + return -EINVAL; + + h = hns3_get_handle(ndev); + return hclge_ext_get_sfp_speed(h, speed); +} +EXPORT_SYMBOL(nic_get_sfp_speed); + +int nic_get_chip_num(struct net_device *ndev, u32 *chip_num) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + if (!chip_num) + return -EINVAL; + + h = hns3_get_handle(ndev); + return hclge_get_chip_num(h, chip_num); +} +EXPORT_SYMBOL(nic_get_chip_num); + +int nic_get_port_num_per_chip(struct net_device *ndev, u32 *port_num) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + if (!port_num) + return -EINVAL; + + h = hns3_get_handle(ndev); + return hclge_get_port_num(h, port_num); +} +EXPORT_SYMBOL(nic_get_port_num_per_chip); + +int nic_set_led(struct net_device *ndev, int type, int status) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + h = hns3_get_handle(ndev); + return hclge_set_led(h, type, status); +} +EXPORT_SYMBOL(nic_set_led); + +int nic_get_led_signal(struct net_device *ndev, struct hns3_lamp_signal *signal) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + if (!signal) + return -EINVAL; + + h = hns3_get_handle(ndev); + return hclge_get_led_signal(h, signal); +} +EXPORT_SYMBOL(nic_get_led_signal); + +int nic_disable_net_lane(struct net_device *ndev) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + h = hns3_get_handle(ndev); + return hclge_disable_net_lane(h); +} +EXPORT_SYMBOL(nic_disable_net_lane); + +int nic_get_net_lane_status(struct net_device *ndev, u32 *status) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + if (!status) + return -EINVAL; + + h = hns3_get_handle(ndev); + return hclge_get_net_lane_status(h, status); +} +EXPORT_SYMBOL(nic_get_net_lane_status); + +int nic_set_mac_state(struct net_device *ndev, int enable) +{ + struct hnae3_handle *h; + bool en; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + h = hns3_get_handle(ndev); + en = !!enable; + return hclge_set_mac_state(h, en); +} +EXPORT_SYMBOL(nic_set_mac_state); + +int nic_set_cpu_affinity(struct net_device *netdev, cpumask_t *affinity_mask) +{ + struct hns3_enet_tqp_vector *tqp_vector; + struct hns3_nic_priv *priv; + int ret; + u16 i; + + if (!netdev || !affinity_mask) { + pr_err("Invalid input param when set ethernet cpu affinity\n"); + return -EINVAL; + } + + if (nic_netdev_match_check(netdev)) + return -ENODEV; + + priv = netdev_priv(netdev); + if (test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) { + dev_err(&netdev->dev, "ethernet is down, not support cpu affinity set\n"); + return -EOPNOTSUPP; + } + + 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) { + dev_err(&netdev->dev, "reset affinity hint fail, ret = %d\n", + ret); + return ret; + } + + ret = irq_set_affinity_hint(tqp_vector->vector_irq, + &tqp_vector->affinity_mask); + if (ret) { + dev_err(&netdev->dev, "set affinity hint fail, ret = %d\n", + ret); + return ret; + } + } + + dev_info(&netdev->dev, "set nic cpu affinity %*pb succeed\n", + cpumask_pr_args(affinity_mask)); + + return 0; +} +EXPORT_SYMBOL(nic_set_cpu_affinity); + +int nic_disable_clock(struct net_device *ndev) +{ + struct hnae3_handle *h; + + if (nic_netdev_match_check(ndev)) + return -ENODEV; + + h = hns3_get_handle(ndev); + return hclge_config_nic_clock(h, 0); +} +EXPORT_SYMBOL(nic_disable_clock); + diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ext.h new file mode 100644 index 000000000000..98ab12746273 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3_ext.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2016-2017 Hisilicon Limited. */ + +#ifndef __HNS3_EXT_H +#define __HNS3_EXT_H +#include +#include "../hns3_enet.h" +#include "hns3pf/hclge_ext.h" +#include "hns3pf/hclge_main_it.h" + +/** + * nic_chip_recover_handler - reset net device by port id + * @netdev: net device + * @hnae3_reset_type: nic device event type + */ +void nic_chip_recover_handler(struct net_device *netdev, + enum hnae3_reset_type_custom event_t); +int nic_netdev_match_check(struct net_device *netdev); +int nic_clean_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats); +int nic_get_sfpinfo(struct net_device *netdev, u8 *buff, u16 size, u16 *outlen); +int nic_set_sfp_state(struct net_device *netdev, bool en); +int nic_get_sfp_id(struct net_device *netdev, u32 *sfp_id); +int nic_get_port_num_per_chip(struct net_device *ndev, u32 *port_num); +int nic_get_chip_num(struct net_device *ndev, u32 *chip_num); +int nic_set_led(struct net_device *ndev, int type, int status); +int nic_disable_net_lane(struct net_device *ndev); +int nic_get_net_lane_status(struct net_device *ndev, u32 *status); +int nic_set_cpu_affinity(struct net_device *netdev, cpumask_t *affinity_mask); +int nic_get_led_signal(struct net_device *ndev, + struct hns3_lamp_signal *signal); +int nic_set_mac_state(struct net_device *ndev, int enable); +int nic_disable_clock(struct net_device *ndev); + +#endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_cmd_it.c b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_cmd_it.c new file mode 100644 index 000000000000..e31f6f1a42df --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_cmd_it.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2016-2017 Hisilicon Limited. + +#include "../../hns3pf/hclge_cmd.h" +#include "../../hnae3.h" +#include "../../hns3pf/hclge_main.h" + +#ifdef CONFIG_HNS3_TEST +#include "hclge_test.h" + +EXPORT_SYMBOL(hclge_cmd_reuse_desc); +EXPORT_SYMBOL(hclge_cmd_setup_basic_desc); +EXPORT_SYMBOL(hclge_cmd_send); +#endif + diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_ext.c new file mode 100644 index 000000000000..f4c790952268 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_ext.c @@ -0,0 +1,405 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2016-2017 Hisilicon Limited. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../hns3pf/hclge_main.h" +#include "../../hnae3.h" +#include "../../hns3pf/hclge_cmd.h" +#include "hclge_ext.h" + +void hclge_clean_stats64(struct hnae3_handle *handle) +{ + struct hnae3_knic_private_info *kinfo; + struct hclge_vport *vport; + struct hclge_dev *hdev; + struct hclge_tqp *tqp; + int i; + + kinfo = &handle->kinfo; + vport = hclge_get_vport(handle); + hdev = vport->back; + + for (i = 0; i < kinfo->num_tqps; i++) { + tqp = container_of(kinfo->tqp[i], struct hclge_tqp, q); + memset(&tqp->tqp_stats, 0, sizeof(struct hlcge_tqp_stats)); + } + memset(&hdev->hw_stats.mac_stats, 0, sizeof(struct hclge_mac_stats)); +} +EXPORT_SYMBOL(hclge_clean_stats64); + +int hclge_get_chipid(struct hnae3_handle *handle, u32 *chip_id) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_chip_id_cmd *resp = NULL; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CHIP_ID_GET, true); + resp = (struct hclge_chip_id_cmd *)(desc.data); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, "get chip id failed %d\n", ret); + return ret; + } + *chip_id = resp->chip_id; + return 0; +} +EXPORT_SYMBOL(hclge_get_chipid); + +int hclge_get_commit_id(struct hnae3_handle *handle, u8 *commit_id, + u32 *ncl_version) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_commit_id_cmd *resp = NULL; + struct hclge_desc desc; + int ret, i; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_IMP_COMMIT_ID_GET, true); + resp = (struct hclge_commit_id_cmd *)(desc.data); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, "get commit id failed %d\n", ret); + return ret; + } + + for (i = 0; i < 8; i++) + commit_id[i] = resp->commit_id[i]; + + commit_id[8] = '\0'; + *ncl_version = resp->ncl_version; + + return 0; +} +EXPORT_SYMBOL(hclge_get_commit_id); + +static int _hclge_get_sfpinfo(struct hnae3_handle *handle, u8 *buff, + u16 offset, u16 size, u16 *outlen) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_desc desc[HCLGE_SFP_INFO_LEN]; + struct hclge_dev *hdev = vport->back; + struct hclge_sfp_info *resp = NULL; + int ret; + int i; + int j; + + for (i = 0; i < HCLGE_SFP_INFO_LEN; i++) { + hclge_cmd_setup_basic_desc(&desc[i], + HCLGE_OPC_SFP_GET_INFO, true); + if (i == 0) + desc[0].data[0] = offset | (size << 16); + if (i < HCLGE_SFP_INFO_LEN - 1) + desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); + else + desc[i].flag &= ~(cpu_to_le16(HCLGE_CMD_FLAG_NEXT)); + } + + ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_SFP_INFO_LEN); + if (ret) { + dev_err(&hdev->pdev->dev, + "get spf information cmd failed %d\n", + ret); + return ret; + } + + for (i = 0; i < HCLGE_SFP_INFO_LEN; i++) { + resp = (struct hclge_sfp_info *)desc[i].data; + if (i == 0) { + *outlen = (resp[i].sfpinfo[0] >> 16) & 0xFFFF; + for (j = 1; j < 6; j++) { + *(u32 *)buff = resp->sfpinfo[j]; + buff = buff + sizeof(u32); + } + } else { + for (j = 0; j < 6; j++) { + *(u32 *)buff = resp->sfpinfo[j]; + buff = buff + sizeof(u32); + } + } + } + return 0; +} + +int hclge_get_sfpinfo(struct hnae3_handle *handle, u8 *buff, u16 offset, + u16 size, u16 *outlen) +{ + u16 tmp_size; + u8 *tmp_buff; + u16 tmp_outlen; + int ret; + + tmp_buff = buff; + while (size) { + WARN_ON_ONCE(!tmp_buff); + if (size > HCLGE_SFP_INFO_SIZE) + tmp_size = HCLGE_SFP_INFO_SIZE; + else + tmp_size = size; + ret = _hclge_get_sfpinfo(handle, tmp_buff, offset, tmp_size, + &tmp_outlen); + if (ret) + return ret; + offset += tmp_size; + size -= tmp_size; + tmp_buff += tmp_size; + *outlen += tmp_outlen; + if (tmp_size != tmp_outlen) + break; + } + return 0; +} +EXPORT_SYMBOL(hclge_get_sfpinfo); + +int hclge_set_sfp_state(struct hnae3_handle *handle, bool en) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_sfp_enable_cmd *req = NULL; + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SFP_SET_STATUS, false); + req = (struct hclge_sfp_enable_cmd *)desc.data; + req->set_sfp_enable_flag = en; + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "set spf on/off cmd failed %d\n", ret); + + return ret; +} +EXPORT_SYMBOL(hclge_set_sfp_state); + +int hclge_get_chip_num(struct hnae3_handle *handle, u32 *chip_num) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_GET_CHIP_NUM, true); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, "get chip number failed %d\n", ret); + return ret; + } + *chip_num = desc.data[0]; + return 0; +} +EXPORT_SYMBOL(hclge_get_chip_num); + +int hclge_ext_get_sfp_speed(struct hnae3_handle *handle, u32 *speed) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + int ret = 0; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_GET_SFP_INFO, true); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret == -EOPNOTSUPP) { + dev_warn(&hdev->pdev->dev, + "IMP do not support get SFP speed %d\n", ret); + return ret; + } else if (ret) { + dev_err(&hdev->pdev->dev, "get sfp speed failed %d\n", ret); + return ret; + } + + *speed = desc.data[0]; + + return 0; +} +EXPORT_SYMBOL(hclge_ext_get_sfp_speed); + +int hclge_get_port_num(struct hnae3_handle *handle, u32 *port_num) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_GET_PORT_NUM, true); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, "get port number failed %d\n", ret); + return ret; + } + *port_num = desc.data[0]; + return 0; +} +EXPORT_SYMBOL(hclge_get_port_num); + +int hclge_set_led(struct hnae3_handle *handle, u32 type, u32 status) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SET_LED, false); + desc.data[0] = type; + desc.data[1] = status; + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, "get set led failed %d\n", ret); + return ret; + } + + return 0; +} +EXPORT_SYMBOL(hclge_set_led); + +int hclge_get_led_signal(struct hnae3_handle *handle, + struct hns3_lamp_signal *signal) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SET_LED, true); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "hclge_get_sgpio_tx_reg failed %d\n", ret); + return ret; + } + + signal->error = desc.data[2] & 0xFF; + signal->locate = (desc.data[2] >> 8) & 0xFF; + signal->activity = (desc.data[2] >> 16) & 0xFF; + + return 0; +} +EXPORT_SYMBOL(hclge_get_led_signal); + +int hclge_get_sfp_present(struct hnae3_handle *handle, u32 *present) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_sfp_present_cmd *resp = NULL; + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + int ret = 0; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SFP_GET_PRESENT, true); + resp = (struct hclge_sfp_present_cmd *)desc.data; + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, "get spf present failed %d\n", ret); + return ret; + } + + *present = resp->sfp_present; + return 0; +} +EXPORT_SYMBOL(hclge_get_sfp_present); + +int hclge_disable_net_lane(struct hnae3_handle *handle) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + int ret = 0; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_DISABLE_NET_LANE, false); + desc.data[0] = 0; + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, "disable net lane failed %d\n", ret); + return ret; + } + return 0; +} +EXPORT_SYMBOL(hclge_disable_net_lane); + +int hclge_get_net_lane_status(struct hnae3_handle *handle, u32 *status) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + int ret = 0; + + desc.data[0] = 0; + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_DISABLE_NET_LANE, true); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, "disable net lane failed %d\n", ret); + return ret; + } + *status = desc.data[0]; + return 0; +} +EXPORT_SYMBOL(hclge_get_net_lane_status); + +int hclge_set_mac_state(struct hnae3_handle *handle, bool enable) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + struct hclge_config_mac_mode_cmd *req = + (struct hclge_config_mac_mode_cmd *)desc.data; + u32 loop_en = 0; + int ret = 0; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_MAC_MODE, false); + hnae3_set_bit(loop_en, HCLGE_MAC_TX_EN_B, enable); + hnae3_set_bit(loop_en, HCLGE_MAC_RX_EN_B, enable); + hnae3_set_bit(loop_en, HCLGE_MAC_PAD_TX_B, enable); + hnae3_set_bit(loop_en, HCLGE_MAC_PAD_RX_B, enable); + hnae3_set_bit(loop_en, HCLGE_MAC_1588_TX_B, 0); + hnae3_set_bit(loop_en, HCLGE_MAC_1588_RX_B, 0); + hnae3_set_bit(loop_en, HCLGE_MAC_APP_LP_B, 0); + hnae3_set_bit(loop_en, HCLGE_MAC_LINE_LP_B, 0); + hnae3_set_bit(loop_en, HCLGE_MAC_FCS_TX_B, enable); + hnae3_set_bit(loop_en, HCLGE_MAC_RX_FCS_B, enable); + hnae3_set_bit(loop_en, HCLGE_MAC_RX_FCS_STRIP_B, enable); + hnae3_set_bit(loop_en, HCLGE_MAC_TX_OVERSIZE_TRUNCATE_B, enable); + hnae3_set_bit(loop_en, HCLGE_MAC_RX_OVERSIZE_TRUNCATE_B, enable); + hnae3_set_bit(loop_en, HCLGE_MAC_TX_UNDER_MIN_ERR_B, enable); + req->txrx_pad_fcs_loop_en = cpu_to_le32(loop_en); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "set mac state %x fail, ret =%d.\n", enable, ret); + return ret; +} +EXPORT_SYMBOL(hclge_set_mac_state); + +int hclge_config_nic_clock(struct hnae3_handle *handle, bool enable) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + u32 nic_clock_en = enable; + struct hclge_desc desc; + int ret = 0; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_NIC_CLOCK, false); + desc.data[0] = nic_clock_en; + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "config_nic_clock %x fail, ret = %d.\n", + nic_clock_en, ret); + return ret; +} +EXPORT_SYMBOL(hclge_config_nic_clock); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_ext.h new file mode 100644 index 000000000000..2049903980fa --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_ext.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2016-2017 Hisilicon Limited. */ + +#ifndef __HCLGE_EXT_H +#define __HCLGE_EXT_H +#include +#include "../../hnae3.h" + +#define HCLGE_SFP_INFO_LEN 6 +#define HCLGE_SFP_INFO_SIZE 140 + +#define HCLGE_OPC_CONFIG_NIC_CLOCK 0x0060 + +struct hclge_chip_id_cmd { + u32 chip_id; + u32 rsv[5]; +}; + +struct hclge_commit_id_cmd { + u8 commit_id[8]; + u32 ncl_version; + u32 rsv[3]; +}; + +struct hclge_sfp_info { + u32 sfpinfo[6]; +}; + +struct hclge_sfp_enable_cmd { + u32 set_sfp_enable_flag; + u32 rsv[5]; +}; + +struct hclge_sfp_present_cmd { + u32 sfp_present; + u32 rsv[5]; +}; + +struct hns3_lamp_signal { + u8 error; + u8 locate; + u8 activity; +}; + +enum hclge_ext_opcode_type { + /* misc command */ + HCLGE_OPC_CHIP_ID_GET = 0x7003, + HCLGE_OPC_IMP_COMMIT_ID_GET = 0x7004, + HCLGE_OPC_GET_CHIP_NUM = 0x7005, + HCLGE_OPC_GET_PORT_NUM = 0x7006, + HCLGE_OPC_SET_LED = 0x7007, + HCLGE_OPC_DISABLE_NET_LANE = 0x7008, + /*SFP command*/ + HCLGE_OPC_SFP_GET_INFO = 0x7100, + HCLGE_OPC_SFP_GET_PRESENT = 0x7101, + HCLGE_OPC_SFP_SET_STATUS = 0x7102, +}; + +void hclge_clean_stats64(struct hnae3_handle *handle); +int hclge_get_chipid(struct hnae3_handle *handle, u32 *chip_id); +int hclge_get_commit_id(struct hnae3_handle *handle, u8 *commit_id, + u32 *ncl_version); +int hclge_get_sfpinfo(struct hnae3_handle *handle, u8 *buff, u16 offset, + u16 size, u16 *outlen); +int hclge_set_sfp_state(struct hnae3_handle *handle, bool en); +int hclge_get_chip_num(struct hnae3_handle *handle, u32 *chip_num); +int hclge_get_port_num(struct hnae3_handle *handle, u32 *port_num); +int hclge_set_led(struct hnae3_handle *handle, u32 type, u32 status); +int hclge_get_sfp_present(struct hnae3_handle *handle, u32 *present); +int hclge_disable_net_lane(struct hnae3_handle *handle); +int hclge_get_net_lane_status(struct hnae3_handle *handle, u32 *status); +int hclge_ext_get_sfp_speed(struct hnae3_handle *handle, u32 *speed); +int hclge_get_led_signal(struct hnae3_handle *handle, + struct hns3_lamp_signal *signal); +int hclge_set_mac_state(struct hnae3_handle *handle, bool enable); +int hclge_config_nic_clock(struct hnae3_handle *handle, bool enable); + +#endif + diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_main_it.c b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_main_it.c new file mode 100644 index 000000000000..46b95ac3cae0 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_main_it.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2016-2017 Hisilicon Limited. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../kcompat.h" +#include "../../hns3pf/hclge_cmd.h" +#include "../../hns3pf/hclge_main.h" +#include "../../hnae3.h" +#include "hclge_ext.h" +#include "hclge_main_it.h" +#include "../../hns3pf/hclge_err.h" + +#ifdef CONFIG_HNS3_TEST +#include "hclge_test.h" +#endif + +#ifdef CONFIG_EXT_TEST + +#define HCLGE_RESET_MAX_FAIL_CNT 1 + +static nic_event_fn_t nic_event_call; + +int nic_register_event(nic_event_fn_t event_call) +{ + if (!event_call) { + pr_err("register event handle is null.\n"); + return -EINVAL; + } + + nic_event_call = event_call; + + pr_info("netdev register success.\n"); + return 0; +} +EXPORT_SYMBOL(nic_register_event); + +int nic_unregister_event(void) +{ + nic_event_call = NULL; + return 0; +} +EXPORT_SYMBOL(nic_unregister_event); + +void nic_call_event(struct net_device *netdev, + enum hnae3_reset_type_custom event_t) +{ + if (nic_event_call) + nic_event_call(netdev, event_t); + + netdev_info(netdev, "report reset event %d\n", event_t); +} +EXPORT_SYMBOL(nic_call_event); + +bool hclge_reset_done_it(struct hnae3_handle *handle, bool done) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct net_device *netdev; + + netdev = hdev->vport[0].nic.netdev; + + if (done) { + dev_info(&hdev->pdev->dev, "Report Reset DONE!\n"); + nic_call_event(netdev, HNAE3_RESET_DONE_CUSTOM); + } + + if (hdev->reset_fail_cnt >= HCLGE_RESET_MAX_FAIL_CNT) { + dev_err(&hdev->pdev->dev, "Report Reset fail!\n"); + nic_call_event(netdev, HNAE3_PORT_FAULT); + } + + return done; +} + +pci_ers_result_t hclge_handle_hw_ras_error_it(struct hnae3_ae_dev *ae_dev) +{ + struct hclge_dev *hdev = ae_dev->priv; + struct device *dev = &hdev->pdev->dev; + enum hnae3_reset_type_custom reset_type; + struct net_device *netdev; + u32 status; + + netdev = hdev->vport[0].nic.netdev; + + status = hclge_read_dev(&hdev->hw, HCLGE_RAS_PF_OTHER_INT_STS_REG); + + if (status & HCLGE_RAS_REG_NFE_MASK || + status & HCLGE_RAS_REG_ROCEE_ERR_MASK) + ae_dev->hw_err_reset_req = 0; + + /* Handling Non-fatal HNS RAS errors */ + if (status & HCLGE_RAS_REG_NFE_MASK) { + dev_warn(dev, + "HNS Non-Fatal RAS error(status=0x%x) identified\n", + status); + hclge_handle_all_ras_errors(hdev); + + reset_type = ae_dev->ops->set_default_reset_request(ae_dev, + &ae_dev->hw_err_reset_req); + + if (reset_type != HNAE3_NONE_RESET_CUSTOM) + nic_call_event(netdev, reset_type); + } else { + if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) || + hdev->pdev->revision < 0x21) { + ae_dev->override_pci_need_reset = 1; + return PCI_ERS_RESULT_RECOVERED; + } + } + + if (status & HCLGE_RAS_REG_ROCEE_ERR_MASK) { + dev_warn(dev, "ROCEE uncorrected RAS error identified\n"); + hclge_handle_rocee_ras_error(ae_dev); + } + + if ((status & HCLGE_RAS_REG_NFE_MASK || + status & HCLGE_RAS_REG_ROCEE_ERR_MASK) && + ae_dev->hw_err_reset_req) { + ae_dev->override_pci_need_reset = 0; + return PCI_ERS_RESULT_NEED_RESET; + } + ae_dev->override_pci_need_reset = 1; + + return PCI_ERS_RESULT_RECOVERED; +} + +#endif + +#ifdef CONFIG_IT_VALIDATION + +#define HCLGE_NAME_IT "hclge" + +EXPORT_SYMBOL(hclge_get_vport); +EXPORT_SYMBOL(hclge_cmd_set_promisc_mode); +EXPORT_SYMBOL(hclge_promisc_param_init); + +struct pci_device_id ae_algo_pci_tbl_it[] = { + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_GE), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA_MACSEC), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA_MACSEC), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), 0}, + +#ifdef CONFIG_HNS3_X86 + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_X86_25_GE), 0}, +#endif + + /* required last entry */ + {0, } +}; + +int hclge_init_it(void) +{ + pr_info("%s is initializing\n", HCLGE_NAME_IT); +#ifdef CONFIG_HNS3_TEST + hclge_ops.send_cmdq = hclge_send_cmdq; +#endif + +#ifdef CONFIG_EXT_TEST + hclge_ops.handle_hw_ras_error = hclge_handle_hw_ras_error_it; + hclge_ops.reset_done = hclge_reset_done_it; +#endif + + ae_algo.pdev_id_table = ae_algo_pci_tbl_it; + hnae3_register_ae_algo(&ae_algo); + + return 0; +} +module_init(hclge_init_it); +#endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_main_it.h b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_main_it.h new file mode 100644 index 000000000000..48643ce615e2 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_main_it.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2016-2017 Hisilicon Limited. */ + +#ifndef __HCLGE_MAIN_IT_H +#define __HCLGE_MAIN_IT_H + +extern struct hnae3_ae_algo ae_algo; +extern struct hnae3_ae_ops hclge_ops; + +enum hnae3_reset_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, +}; + +#ifdef CONFIG_EXT_TEST + +/** + * nic_event_fn_t - nic event handler prototype + * @netdev: net device + * @hnae3_reset_type_custom: nic device event type + */ +typedef void (*nic_event_fn_t) (struct net_device *netdev, + enum hnae3_reset_type_custom); + +/** + * nic_register_event - register for nic event listening + * @event_call: nic event handler + * return 0 - success , negative - fail + */ +int nic_register_event(nic_event_fn_t event_call); + +/** + * nic_unregister_event - quit nic event listening + * return 0 - success , negative - fail + */ +int nic_unregister_event(void); + +void nic_call_event(struct net_device *netdev, + enum hnae3_reset_type_custom event_t); +#endif + +#endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_test.c b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_test.c new file mode 100644 index 000000000000..44bb6701bfe5 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_test.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2016-2017 Hisilicon Limited. + +#include +#include "hclge_test.h" + +int hclge_send_cmdq(struct hnae3_handle *handle, void *data, int num) +{ + struct hclge_vport *vport; + struct hclge_dev *hdev; + + vport = hclge_get_vport(handle); + hdev = vport->back; + + return (int)hclge_cmd_send(&hdev->hw, data, num); +} diff --git a/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_test.h b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_test.h new file mode 100644 index 000000000000..2b63a611f3fa --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns-customer/hns3pf/hclge_test.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2016-2017 Hisilicon Limited. */ + +#ifndef __HCLGE_TEST_H +#define __HCLGE_TEST_H + +#include "../../hns3pf/hclge_cmd.h" +#include "../../hns3pf/hclge_main.h" + +int hclge_send_cmdq(struct hnae3_handle *handle, void *data, int num); + +#endif -- GitLab