提交 d0203361 编写于 作者: W Weiwei 提交者: Xie XiuQi

net: hns3: add hns3 cae drivers to kernel

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

add hns3 cae drivers to kernel.
Signed-off-by: NWeiwei <dengweiwei@huawei.com>
Reviewed-by: Ngaoxun <gaoxun3@huawei.com>
Reviewed-by: NShengzui You <youshengzui@huawei.com>
Reviewed-by: NZhaohui Zhong <zhongzhaohui@huawei.com>
Reviewed-by: NYongxin Li <liyongxin1@huawei.com>
Tested-by: Junxin Chen <chenjunxin1@huawei.com>i
Reviewed-by: NYunsheng Lin <linyunsheng@huawei.com>
Acked-by: NHanjun Guo <guohanjun@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 b4535f93
......@@ -123,6 +123,16 @@ config HNS3_ENET
family of SoCs. This module depends upon HNAE3 driver to access the HNAE3
devices and their associated operations.
config HNS3_CAE
tristate "Hisilicon HNS3 configuration & analysis & enhancement Support"
default m
depends on HNS3_HCLGE && HNS3_ENET
help
This selects the Configuration, Analysis and Enhancement Support for HNS3 Driver
(e.g. SFP management, self-adaptive port speed and DFX). It is supposed to
support upcoming User Mode Tool (i.e. hiarmtool) developed by Huawei.
This module depends upon HNS3_HCLGE and HNS3 driver.
endif #HNS3
endif # NET_VENDOR_HISILICON
......@@ -2,14 +2,85 @@
#
# Makefile for the HISILICON network device drivers.
#
ccflags-y += -I$(srctree)/$(src)
obj-$(CONFIG_HNS3) += hns3pf/
obj-$(CONFIG_HNS3) += hns3vf/
# Add security options
ccflags-y += -fstack-protector-strong
ccflags-y += -Wl,-z,relro,-z,now
ccflags-y += -Wl,-z,noexecstack
ccflags-y += -D_FORTIFY_SOURCE=2 -O2
ccflags-y += -fvisibility=hidden
ccflags-y += -Wformat=2 -Wfloat-equal
ccflags-y += -fsigned-char
ccflags-y += -DCONFIG_IT_VALIDATION
ccflags-y += -DCONFIG_HNS3_TEST
ccflags-y += -DCONFIG_EXT_TEST
PWD = $(srctree)/drivers/net/ethernet/hisilicon/hns3
#add include path
ccflags-y += -I$(PWD) \
-I$(PWD)/hns3pf \
-I$(PWD)/hns-customer \
-I$(PWD)/hns-customer/hns3pf \
-I$(PWD)/hns3vf \
-I$(PWD)/hns3_cae
obj-$(CONFIG_HNS3_HCLGE) += hclge.o
hclge-objs = hns3pf/hclge_main.o \
hns3pf/hclge_cmd.o \
hns3pf/hclge_mdio.o \
hns3pf/hclge_debugfs.o \
hns3pf/hclge_tm.o \
hns3pf/hclge_mbx.o \
hns3pf/hclge_err.o
hclge-objs += hns-customer/hns3pf/hclge_main_it.o \
hns-customer/hns3pf/hclge_cmd_it.o \
hns-customer/hns3pf/hclge_ext.o \
hns-customer/hns3pf/hclge_test.o
hclge-$(CONFIG_HNS3_DCB) += hns3pf/hclge_dcb.o
#### compile hnae3.ko
obj-$(CONFIG_HNS3) += hnae3.o
obj-$(CONFIG_HNS3_ENET) += hns3.o
hns3-objs = hns3_enet.o hns3_ethtool.o hns3_debugfs.o
hns3-objs += hns-customer/hns3_enet_it.o hns-customer/hns3_ext.o
hns3-$(CONFIG_HNS3_DCB) += hns3_dcbnl.o
#### compile hclgevf.ko
obj-$(CONFIG_HNS3_HCLGEVF) += hclgevf.o
hclgevf-objs := hns3vf/hclgevf_main.o hns3vf/hclgevf_cmd.o hns3vf/hclgevf_mbx.o
#### compile hns3_cae.ko
#add rally code
HNS3_CAE_OBJS_PRIM = hns3_cae/hns3_cae_init.o \
hns3_cae/hns3_nictool.o \
hns3_cae/hns3_priv_common_test.o \
hns3_cae/hns3_priv_dcb.o \
hns3_cae/hns3_priv_lamp.o \
hns3_cae/hns3_priv_mactbl.o \
hns3_cae/hns3_priv_m7_cmd.o
#add test code
HNS3_CAE_OBJS_EXT = hns3_cae/hns3_priv_dfx.o \
hns3_cae/hns3_priv_ext.o \
hns3_cae/hns3_priv_fd.o \
hns3_cae/hns3_priv_hilink_param.o \
hns3_cae/hns3_priv_irq.o \
hns3_cae/hns3_priv_mac.o \
hns3_cae/hns3_priv_phy.o \
hns3_cae/hns3_priv_pkt.o \
hns3_cae/hns3_priv_port.o \
hns3_cae/hns3_priv_promisc.o \
hns3_cae/hns3_priv_qinfo.o \
hns3_cae/hns3_priv_qos.o \
hns3_cae/hns3_priv_qres.o \
hns3_cae/hns3_priv_rss.o \
hns3_cae/hns3_priv_stat.o \
hns3_cae/hns3_priv_tm.o \
hns3_cae/hns3_priv_vlan.o \
hns3_cae/hns3_priv_xsfp.o
obj-$(CONFIG_HNS3_CAE) += hns3_cae.o
hns3_cae-objs := $(HNS3_CAE_OBJS_PRIM) $(HNS3_CAE_OBJS_EXT)
......@@ -8,75 +8,22 @@
#include <linux/module.h>
#include <linux/pci.h>
#include "../hnae3.h"
#include "hnae3.h"
#include "hns3_enet_it.h"
#include "hns3pf/hclge_main_it.h"
#include "../hns3_enet.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
#define HNAE_DRIVER_VERSION "1.8.10.0"
#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)
{
......@@ -84,7 +31,6 @@ int hns3_nic_do_ioctl_it(struct net_device *netdev, struct ifreq *ifr, int 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;
......@@ -93,8 +39,7 @@ int hns3_nic_do_ioctl_it(struct net_device *netdev, struct ifreq *ifr, int cmd)
#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)
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,
......@@ -115,25 +60,15 @@ u16 hns3_nic_select_queue_it(struct net_device *ndev, struct sk_buff *skb,
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);
sizeof(HNAE_DRIVER_VERSION));
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);
......@@ -141,9 +76,6 @@ static int __init hns3_init_module_it(void)
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);
......@@ -153,7 +85,6 @@ static int __init hns3_init_module_it(void)
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;
......@@ -166,5 +97,6 @@ static int __init hns3_init_module_it(void)
hns3_dbg_unregister_debugfs();
return ret;
}
module_init(hns3_init_module_it);
#endif
......@@ -7,8 +7,6 @@
typedef int (*hns3_priv_func)(struct net_device *, void *);
hns3_priv_func hns3_ioctl;
#define VERSION_NUMBER "$FULL_VERSION"
#ifndef LINUX_VERSION_CODE
#include <linux/version.h>
#else
......
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2016-2017 Hisilicon Limited.
#include <linux/etherdevice.h>
#include <linux/string.h>
#include <linux/phy.h>
#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);
......@@ -38,21 +38,28 @@ int nic_netdev_match_check(struct net_device *netdev)
EXPORT_SYMBOL(nic_netdev_match_check);
void nic_chip_recover_handler(struct net_device *netdev,
enum hnae3_reset_type_custom event_t)
enum hnae3_event_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);
dev_info(&netdev->dev, "reset type is %d!!\n", event_t);
if (ae_dev->ops->reset_event)
ae_dev->ops->reset_event(h->pdev, NULL);
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(&netdev->dev, "reset type err!!\n");
return;
}
h = hns3_get_handle(netdev);
if (h->ae_algo->ops->priv_ops)
h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_RESET, &event_t, 0);
}
EXPORT_SYMBOL(nic_chip_recover_handler);
......@@ -70,7 +77,10 @@ int nic_clean_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats)
priv = netdev_priv(ndev);
h = hns3_get_handle(ndev);
kinfo = &h->kinfo;
hclge_clean_stats64(h);
if (h->ae_algo->ops->priv_ops)
h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_CLEAN_STATS64, stats,
0);
for (i = 0; i < kinfo->num_tqps; i++) {
ring = priv->ring_data[i].ring;
......@@ -95,66 +105,96 @@ int nic_get_chipid(struct net_device *ndev, u32 *chip_id)
return -EINVAL;
h = hns3_get_handle(ndev);
return hclge_get_chipid(h, chip_id);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_GET_CHIPID,
chip_id, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_get_chipid);
int nic_get_sfpinfo(struct net_device *ndev, u8 *buff, u16 size, u16 *outlen)
int nic_get_mac_id(struct net_device *ndev, u32 *mac_id)
{
struct hnae3_handle *h;
if (nic_netdev_match_check(ndev))
return -ENODEV;
if (!buff || !outlen)
if (!mac_id)
return -EINVAL;
h = hns3_get_handle(ndev);
return hclge_get_sfpinfo(h, buff, 0, size, outlen);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_GET_MAC_ID,
mac_id, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_get_sfpinfo);
EXPORT_SYMBOL(nic_get_mac_id);
int nic_get_sfp_present(struct net_device *ndev, u32 *present)
int nic_get_sfpinfo(struct net_device *ndev, u8 *buff, u16 size, u16 *outlen)
{
struct hns3_sfp_info_para para;
struct hnae3_handle *h;
if (nic_netdev_match_check(ndev))
return -ENODEV;
if (!present)
if (!buff || !outlen)
return -EINVAL;
para.buff = buff;
para.outlen = outlen;
para.offset = 0;
para.size = size;
h = hns3_get_handle(ndev);
return hclge_get_sfp_present(h, present);
if (h->ae_algo->ops->priv_ops) {
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_GET_SFPINFO,
&para, 0);
} else {
return -EOPNOTSUPP;
}
}
EXPORT_SYMBOL(nic_get_sfp_present);
EXPORT_SYMBOL(nic_get_sfpinfo);
int nic_set_sfp_state(struct net_device *ndev, bool en)
int nic_get_sfp_present(struct net_device *ndev, int *present)
{
struct hnae3_handle *h;
if (nic_netdev_match_check(ndev))
return -ENODEV;
if (!present)
return -EINVAL;
h = hns3_get_handle(ndev);
return hclge_set_sfp_state(h, en);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_GET_PRESENT,
present, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_set_sfp_state);
EXPORT_SYMBOL(nic_get_sfp_present);
int nic_get_sfp_speed(struct net_device *ndev, u32 *speed)
int nic_set_sfp_state(struct net_device *ndev, bool en)
{
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);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_SET_SFP_STATE,
&en, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_get_sfp_speed);
EXPORT_SYMBOL(nic_set_sfp_state);
int nic_get_chip_num(struct net_device *ndev, u32 *chip_num)
{
......@@ -167,7 +207,11 @@ int nic_get_chip_num(struct net_device *ndev, u32 *chip_num)
return -EINVAL;
h = hns3_get_handle(ndev);
return hclge_get_chip_num(h, chip_num);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_GET_CHIP_NUM,
chip_num, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_get_chip_num);
......@@ -182,19 +226,30 @@ int nic_get_port_num_per_chip(struct net_device *ndev, u32 *port_num)
return -EINVAL;
h = hns3_get_handle(ndev);
return hclge_get_port_num(h, port_num);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_GET_PORT_NUM,
port_num, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_get_port_num_per_chip);
int nic_set_led(struct net_device *ndev, int type, int status)
{
struct hns3_led_state_para para;
struct hnae3_handle *h;
if (nic_netdev_match_check(ndev))
return -ENODEV;
para.status = status;
para.type = type;
h = hns3_get_handle(ndev);
return hclge_set_led(h, type, status);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_SET_LED, &para,
0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_set_led);
......@@ -209,7 +264,11 @@ int nic_get_led_signal(struct net_device *ndev, struct hns3_lamp_signal *signal)
return -EINVAL;
h = hns3_get_handle(ndev);
return hclge_get_led_signal(h, signal);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_GET_LED_SIGNAL,
signal, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_get_led_signal);
......@@ -221,11 +280,15 @@ int nic_disable_net_lane(struct net_device *ndev)
return -ENODEV;
h = hns3_get_handle(ndev);
return hclge_disable_net_lane(h);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_DISABLE_LANE,
NULL, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_disable_net_lane);
int nic_get_net_lane_status(struct net_device *ndev, u32 *status)
int nic_get_net_lane_status(struct net_device *ndev, u32 *status)
{
struct hnae3_handle *h;
......@@ -236,11 +299,16 @@ int nic_get_net_lane_status(struct net_device *ndev, u32 *status)
return -EINVAL;
h = hns3_get_handle(ndev);
return hclge_get_net_lane_status(h, status);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h,
HNS3_EXT_OPC_GET_LANE_STATUS,
status, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_get_net_lane_status);
int nic_set_mac_state(struct net_device *ndev, int enable)
int nic_set_mac_state(struct net_device *ndev, int enable)
{
struct hnae3_handle *h;
bool en;
......@@ -250,7 +318,11 @@ int nic_set_mac_state(struct net_device *ndev, int enable)
h = hns3_get_handle(ndev);
en = !!enable;
return hclge_set_mac_state(h, en);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_SET_MAC_STATE,
&en, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_set_mac_state);
......@@ -271,7 +343,8 @@ int nic_set_cpu_affinity(struct net_device *netdev, cpumask_t *affinity_mask)
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");
dev_err(&netdev->dev,
"ethernet is down, not support cpu affinity set\n");
return -EOPNOTSUPP;
}
......@@ -284,16 +357,16 @@ int nic_set_cpu_affinity(struct net_device *netdev, cpumask_t *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);
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);
dev_err(&netdev->dev,
"set affinity hint fail, ret = %d\n", ret);
return ret;
}
}
......@@ -308,12 +381,151 @@ EXPORT_SYMBOL(nic_set_cpu_affinity);
int nic_disable_clock(struct net_device *ndev)
{
struct hnae3_handle *h;
u32 en;
if (nic_netdev_match_check(ndev))
return -ENODEV;
en = 0;
h = hns3_get_handle(ndev);
return hclge_config_nic_clock(h, 0);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_CONFIG_CLOCK,
&en, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_disable_clock);
int nic_set_pfc_storm_para(struct net_device *ndev, int dir, int enable,
int period_ms, int times, int recovery_period_ms)
{
struct hns3_pfc_storm_para para;
struct hnae3_handle *h;
if (nic_netdev_match_check(ndev))
return -ENODEV;
para.dir = dir;
para.enable = enable;
para.period_ms = period_ms;
para.times = times;
para.recovery_period_ms = recovery_period_ms;
h = hns3_get_handle(ndev);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h,
HNS3_EXT_OPC_SET_PFC_STORM_PARA,
&para, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_set_pfc_storm_para);
int nic_get_pfc_storm_para(struct net_device *ndev, int dir, int *enable,
int *period_ms, int *times, int *recovery_period_ms)
{
struct hns3_pfc_storm_para para;
struct hnae3_handle *h;
int ret;
if (nic_netdev_match_check(ndev))
return -ENODEV;
if (!enable || !period_ms || !times || !recovery_period_ms) {
pr_err("get pfc storm para failed because invalid input param.\n");
return -EINVAL;
}
h = hns3_get_handle(ndev);
if (h->ae_algo->ops->priv_ops) {
para.dir = dir;
ret = h->ae_algo->ops->priv_ops(h,
HNS3_EXT_OPC_GET_PFC_STORM_PARA,
&para, 0);
if (!ret) {
*enable = para.enable;
*period_ms = para.period_ms;
*times = para.times;
*recovery_period_ms = para.recovery_period_ms;
return 0;
} else {
return ret;
}
} else {
return -EOPNOTSUPP;
}
}
EXPORT_SYMBOL(nic_get_pfc_storm_para);
int nic_get_phy_reg(struct net_device *ndev, u32 page_select_addr,
u16 page, u32 reg_addr, u16 *data)
{
struct hns3_phy_para para;
struct hnae3_handle *h;
int ret;
if (nic_netdev_match_check(ndev))
return -ENODEV;
para.page_select_addr = page_select_addr;
para.page = page;
para.reg_addr = reg_addr;
h = hns3_get_handle(ndev);
if (h->ae_algo->ops->priv_ops) {
ret = h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_GET_PHY_REG,
&para, 0);
if (!ret) {
*data = para.data;
return 0;
} else {
return ret;
}
} else {
return -EOPNOTSUPP;
}
}
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 hns3_phy_para para;
struct hnae3_handle *h;
if (nic_netdev_match_check(ndev))
return -ENODEV;
para.page_select_addr = page_select_addr;
para.page = page;
para.reg_addr = reg_addr;
para.data = data;
h = hns3_get_handle(ndev);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h, HNS3_EXT_OPC_SET_PHY_REG,
&para, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_set_phy_reg);
int nic_get_hilink_ref_los(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);
if (h->ae_algo->ops->priv_ops)
return h->ae_algo->ops->priv_ops(h,
HNS3_EXT_OPC_GET_HILINK_REF_LOS,
status, 0);
else
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(nic_get_hilink_ref_los);
......@@ -4,32 +4,91 @@
#ifndef __HNS3_EXT_H
#define __HNS3_EXT_H
#include <linux/types.h>
#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);
#include "hns3_enet.h"
#include "hnae3.h"
#include "hclge_main_it.h"
enum hns3_ext_op_code {
HNS3_EXT_OPC_CLEAN_STATS64 = 0,
HNS3_EXT_OPC_GET_CHIPID,
HNS3_EXT_OPC_GET_SFPINFO,
HNS3_EXT_OPC_SET_SFP_STATE,
HNS3_EXT_OPC_GET_CHIP_NUM,
HNS3_EXT_OPC_GET_PORT_NUM,
HNS3_EXT_OPC_SET_LED,
HNS3_EXT_OPC_GET_PRESENT,
HNS3_EXT_OPC_DISABLE_LANE,
HNS3_EXT_OPC_GET_LANE_STATUS,
HNS3_EXT_OPC_GET_LED_SIGNAL,
HNS3_EXT_OPC_SET_MAC_STATE,
HNS3_EXT_OPC_CONFIG_CLOCK,
HNS3_EXT_OPC_GET_PFC_STORM_PARA,
HNS3_EXT_OPC_SET_PFC_STORM_PARA,
HNS3_EXT_OPC_GET_PHY_REG,
HNS3_EXT_OPC_SET_PHY_REG,
HNS3_EXT_OPC_GET_MAC_ID,
HNS3_EXT_OPC_OPT_MAC_TABLE,
HNS3_EXT_OPC_RESET,
HNS3_EXT_OPC_GET_HILINK_REF_LOS,
};
struct hns3_sfp_info_para {
u8 *buff;
u16 offset;
u16 size;
u16 *outlen;
};
struct hns3_led_state_para {
u32 type;
u32 status;
};
struct hns3_pfc_storm_para {
u32 dir;
u32 enable;
u32 period_ms;
u32 times;
u32 recovery_period_ms;
};
struct hns3_phy_para {
u32 page_select_addr;
u32 reg_addr;
u16 page;
u16 data;
};
struct hns3_lamp_signal {
u8 error;
u8 locate;
u8 activity;
};
int nic_get_chipid(struct net_device *ndev, u32 *chip_id);
int nic_netdev_match_check(struct net_device *netdev);
int nic_get_sfpinfo(struct net_device *ndev, u8 *buff, u16 size, u16 *outlen);
int nic_get_sfp_present(struct net_device *ndev, int *present);
int nic_set_sfp_state(struct net_device *ndev, bool en);
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_get_port_num_per_chip(struct net_device *ndev, u32 *port_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_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_set_mac_state(struct net_device *ndev, int enable);
int nic_disable_clock(struct net_device *ndev);
int nic_set_pfc_storm_para(struct net_device *ndev, int dir, int enable,
int period_ms, int times, int recovery_period_ms);
int nic_get_pfc_storm_para(struct net_device *ndev, int dir, int *enable,
int *period_ms, int *times, int *recovery_period_ms);
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);
int nic_get_mac_id(struct net_device *ndev, u32 *mac_id);
int nic_get_hilink_ref_los(struct net_device *ndev, u32 *status);
#endif
// 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"
#include "hclge_cmd.h"
#include "hnae3.h"
#include "hclge_main.h"
#ifdef CONFIG_HNS3_TEST
#include "hclge_test.h"
......@@ -12,4 +12,3 @@ EXPORT_SYMBOL(hclge_cmd_reuse_desc);
EXPORT_SYMBOL(hclge_cmd_setup_basic_desc);
EXPORT_SYMBOL(hclge_cmd_send);
#endif
......@@ -4,7 +4,7 @@
#ifndef __HCLGE_EXT_H
#define __HCLGE_EXT_H
#include <linux/types.h>
#include "../../hnae3.h"
#include "hnae3.h"
#define HCLGE_SFP_INFO_LEN 6
#define HCLGE_SFP_INFO_SIZE 140
......@@ -16,64 +16,111 @@ struct hclge_chip_id_cmd {
u32 rsv[5];
};
struct hclge_commit_id_cmd {
u8 commit_id[8];
u32 ncl_version;
u32 rsv[3];
struct hclge_sfp_info_para {
u8 *buff;
u16 offset;
u16 size;
u16 *outlen;
};
struct hclge_sfp_info {
u32 sfpinfo[6];
};
struct hclge_led_state {
u32 type;
u32 status;
};
struct hclge_pfc_storm_para {
u32 dir;
u32 enable;
u32 period_ms;
u32 times;
u32 recovery_period_ms;
};
struct hclge_phy_para {
u32 page_select_addr;
u32 reg_addr;
u16 page;
u16 data;
};
struct hclge_sfp_enable_cmd {
u32 set_sfp_enable_flag;
u32 rsv[5];
u32 set_sfp_enable_flag;
u32 rsv[5];
};
struct hclge_sfp_present_cmd {
u32 sfp_present;
u32 rsv[5];
u32 sfp_present;
u32 rsv[5];
};
struct hns3_lamp_signal {
struct hclge_lamp_signal {
u8 error;
u8 locate;
u8 activity;
};
struct hclge_mac_table_para {
u8 op_cmd;
u8 mac_addr[ETH_ALEN];
};
enum hclge_ext_op_code {
HCLGE_EXT_OPC_CLEAN_STATS64 = 0,
HCLGE_EXT_OPC_GET_CHIPID,
HCLGE_EXT_OPC_GET_SFPINFO,
HCLGE_EXT_OPC_SET_SFP_STATE,
HCLGE_EXT_OPC_GET_CHIP_NUM,
HCLGE_EXT_OPC_GET_PORT_NUM,
HCLGE_EXT_OPC_SET_LED,
HCLGE_EXT_OPC_GET_PRESENT,
HCLGE_EXT_OPC_DISABLE_LANE,
HCLGE_EXT_OPC_GET_LANE_STATUS,
HCLGE_EXT_OPC_GET_LED_SIGNAL,
HCLGE_EXT_OPC_SET_MAC_STATE,
HCLGE_EXT_OPC_CONFIG_CLOCK,
HCLGE_EXT_OPC_GET_PFC_STORM_PARA,
HCLGE_EXT_OPC_SET_PFC_STORM_PARA,
HCLGE_EXT_OPC_GET_PHY_REG,
HCLGE_EXT_OPC_SET_PHY_REG,
HCLGE_EXT_OPC_GET_MAC_ID,
HCLGE_EXT_OPC_OPT_MAC_TABLE,
HCLGE_EXT_OPC_RESET,
HCLGE_EXT_OPC_GET_HILINK_REF_LOS,
};
enum hclge_opt_table_code {
HCLGE_OPT_TABLE_LOOKUP,
HCLGE_OPT_TABLE_ADD,
HCLGE_OPT_TABLE_DEL,
};
struct hclge_ext_func {
int opcode;
int (*priv_ops)(struct hnae3_handle *handle, int opcode,
void *data, int length);
};
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,
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,
HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019,
HCLGE_OPC_CFG_GET_HILINK_REF_LOS = 0x701B,
/*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);
int hclge_ext_ops_handle(struct hnae3_handle *handle, int opcode,
void *data, int length);
void hclge_reset_task_schedule_it(struct hclge_dev *hdev);
#endif
......@@ -13,20 +13,17 @@
#include <linux/platform_device.h>
#include <linux/if_vlan.h>
#include <net/rtnetlink.h>
#include "../../kcompat.h"
#include "../../hns3pf/hclge_cmd.h"
#include "../../hns3pf/hclge_main.h"
#include "../../hnae3.h"
#include "kcompat.h"
#include "hclge_cmd.h"
#include "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;
......@@ -53,90 +50,125 @@ int nic_unregister_event(void)
EXPORT_SYMBOL(nic_unregister_event);
void nic_call_event(struct net_device *netdev,
enum hnae3_reset_type_custom event_t)
enum hnae3_event_type_custom event_t)
{
if (nic_event_call)
if (nic_event_call) {
nic_event_call(netdev, event_t);
netdev_info(netdev, "report reset event %d\n", event_t);
netdev_info(netdev, "report event %d\n", event_t);
}
}
EXPORT_SYMBOL(nic_call_event);
bool hclge_reset_done_it(struct hnae3_handle *handle, bool done)
void hclge_handle_imp_error_it(struct hnae3_handle *handle)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
struct net_device *netdev;
u32 reg_val;
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 (test_and_clear_bit(HCLGE_IMP_RD_POISON, &hdev->imp_err_state)) {
dev_err(&hdev->pdev->dev, "Detected IMP RD poison!\n");
if (nic_event_call)
nic_call_event(netdev, HNAE3_IMP_RD_POISON_CUSTOM);
reg_val = hclge_read_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG) &
~BIT(HCLGE_VECTOR0_IMP_RD_POISON_B);
hclge_write_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG, reg_val);
}
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);
if (test_and_clear_bit(HCLGE_IMP_CMDQ_ERROR, &hdev->imp_err_state)) {
dev_err(&hdev->pdev->dev, "Detected CMDQ ECC error!\n");
if (nic_event_call)
nic_call_event(netdev, HNAE3_IMP_RESET_CUSTOM);
reg_val = hclge_read_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG) &
~BIT(HCLGE_VECTOR0_IMP_CMDQ_ERR_B);
hclge_write_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG, reg_val);
}
return done;
}
pci_ers_result_t hclge_handle_hw_ras_error_it(struct hnae3_ae_dev *ae_dev)
void hclge_reset_event_it(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;
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);
/* We might end up getting called broadly because of 2 below cases:
* 1. Recoverable error was conveyed through APEI and only way to bring
* normalcy is to reset.
* 2. A new reset request from the stack due to timeout
*
* For the first case,error event might not have ae handle available.
* check if this is a new reset request and we are not here just because
* last reset attempt did not succeed and watchdog hit us again. We will
* know this if last reset request did not occur very recently (watchdog
* timer = 5*HZ, let us check after sufficiently large time, say 4*5*Hz)
* In case of new request we reset the "reset level" to PF reset.
* And if it is a repeat reset request of the most recent one then we
* want to make sure we throttle the reset request. Therefore, we will
* not allow it again before 12*HZ times.
*/
if (time_before(jiffies, (hdev->last_reset_time +
HCLGE_RESET_INTERVAL)))
return;
else if (hdev->default_reset_request)
hdev->reset_level =
hclge_get_reset_level(ae_dev, &hdev->default_reset_request);
else if (time_after(jiffies, (hdev->last_reset_time + 4 * 5 * HZ)))
hdev->reset_level = HNAE3_FUNC_RESET;
dev_info(&hdev->pdev->dev, "received reset event , reset type is %d",
hdev->reset_level);
if (hdev->ppu_poison_ras_err && nic_event_call) {
nic_call_event(netdev, HNAE3_PPU_POISON_CUSTOM);
hdev->ppu_poison_ras_err = false;
}
if (reset_type != HNAE3_NONE_RESET_CUSTOM)
nic_call_event(netdev, reset_type);
if (nic_event_call) {
nic_call_event(netdev, hdev->reset_level);
} 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;
}
/* request reset & schedule reset task */
set_bit(hdev->reset_level, &hdev->reset_request);
hclge_reset_task_schedule_it(hdev);
}
}
if (status & HCLGE_RAS_REG_ROCEE_ERR_MASK) {
dev_warn(dev, "ROCEE uncorrected RAS error identified\n");
hclge_handle_rocee_ras_error(ae_dev);
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");
if (nic_event_call)
nic_call_event(netdev, HNAE3_RESET_DONE_CUSTOM);
}
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;
if (hdev->reset_fail_cnt >= HCLGE_RESET_MAX_FAIL_CNT) {
dev_err(&hdev->pdev->dev, "Report Reset fail!\n");
if (nic_event_call) {
if (hdev->reset_type == HNAE3_FUNC_RESET)
nic_call_event(netdev,
HNAE3_FUNC_RESET_FAIL_CUSTOM);
else if (hdev->reset_type == HNAE3_GLOBAL_RESET)
nic_call_event(netdev,
HNAE3_GLOBAL_RESET_FAIL_CUSTOM);
else if (hdev->reset_type == HNAE3_IMP_RESET)
nic_call_event(netdev,
HNAE3_IMP_RESET_FAIL_CUSTOM);
}
}
ae_dev->override_pci_need_reset = 1;
return PCI_ERS_RESULT_RECOVERED;
return done;
}
#endif
#ifdef CONFIG_IT_VALIDATION
#define HCLGE_NAME_IT "hclge"
......@@ -145,39 +177,21 @@ 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;
hclge_ops.priv_ops = hclge_ext_ops_handle;
#endif
#ifdef CONFIG_EXT_TEST
hclge_ops.handle_hw_ras_error = hclge_handle_hw_ras_error_it;
hclge_ops.reset_event = hclge_reset_event_it;
hclge_ops.reset_done = hclge_reset_done_it;
#endif
ae_algo.pdev_id_table = ae_algo_pci_tbl_it;
hclge_ops.handle_imp_error = hclge_handle_imp_error_it;
hnae3_register_ae_algo(&ae_algo);
return 0;
}
module_init(hclge_init_it);
#endif
......@@ -7,7 +7,7 @@
extern struct hnae3_ae_algo ae_algo;
extern struct hnae3_ae_ops hclge_ops;
enum hnae3_reset_type_custom {
enum hnae3_event_type_custom {
HNAE3_VF_RESET_CUSTOM,
HNAE3_VF_FUNC_RESET_CUSTOM,
HNAE3_VF_PF_FUNC_RESET_CUSTOM,
......@@ -20,17 +20,20 @@ enum hnae3_reset_type_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,
};
#ifdef CONFIG_EXT_TEST
/**
* nic_event_fn_t - nic event handler prototype
* @netdev: net device
* @hnae3_reset_type_custom: nic device event type
* @hnae3_event_type_custom: nic device event type
*/
typedef void (*nic_event_fn_t) (struct net_device *netdev,
enum hnae3_reset_type_custom);
enum hnae3_event_type_custom);
/**
* nic_register_event - register for nic event listening
......@@ -46,7 +49,5 @@ int nic_register_event(nic_event_fn_t event_call);
int nic_unregister_event(void);
void nic_call_event(struct net_device *netdev,
enum hnae3_reset_type_custom event_t);
#endif
enum hnae3_event_type_custom event_t);
#endif
......@@ -4,8 +4,8 @@
#ifndef __HCLGE_TEST_H
#define __HCLGE_TEST_H
#include "../../hns3pf/hclge_cmd.h"
#include "../../hns3pf/hclge_main.h"
#include "hclge_cmd.h"
#include "hclge_main.h"
int hclge_send_cmdq(struct hnae3_handle *handle, void *data, int num);
......
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2016-2017 Hisilicon Limited.
#include <linux/module.h>
#include "hnae3.h"
#include "hns3_enet.h"
#include "hns3_enet_it.h"
#ifdef CONFIG_HNS3_TEST
#include "hns3_nictool.h"
#endif
static int __init hns3_cae_init(void)
{
#ifdef CONFIG_HNS3_TEST
int ret;
pr_err("%s enter!\n", __func__);
ret = nictool_k_init();
if (ret)
return ret;
#endif
return 0;
}
static void __exit hns3_cae_exit(void)
{
#ifdef CONFIG_HNS3_TEST
pr_err("%s exit!\n", __func__);
nictool_k_uninit();
#endif
}
module_init(hns3_cae_init);
module_exit(hns3_cae_exit);
MODULE_LICENSE("GPL");
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2016-2019 Hisilicon Limited. */
#ifndef HNS3_NICTOOL_H_
#define HNS3_NICTOOL_H_
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif
/* completion overtime in (unit of) jiffies */
#define UP_COMP_TIME_OUT_VAL 10000U
#define UCODE_COMP_TIME_OUT_VAL 0xFF00000
#define NIC_TOOL_MAGIC 'x'
enum module_name {
SEND_TO_DRIVER = 1,
};
enum driver_cmd_type {
FW_VER = 1,
DRIVER_VER,
CHECKSUM_CFG,
RX_CS_STATISTICS_INFO,
CLEAN_STASTICS,
MAX_TSO_SIZE,
FUNC_TYPE,
TM_QUEUE_CFG = 100,
TM_QSET_CFG,
TM_PRI_CFG,
TM_PG_CFG,
TM_PORT_CFG,
TM_ETS_CFG,
DCB_MODE_CFG = 150,
ETS_MODE_CFG,
PFC_MODE_CFG,
MAC_LOOP_CFG = 200,
DFX_INFO_CMD = 250,
DFX_READ_CMD = 251,
SEND_PKT = 300,
RECV_PKT,
RX_PRIV_BUFF_WL_CFG = 400,
RX_COMMON_THRD_CFG,
RX_COMMON_WL_CFG,
MAC_PAUSE_EN_CFG,
PFC_PAUSE_EN_CFG,
MAC_PAUSE_PARAM_CFG,
SHOW_PAUSE_CFG,
SHOW_PRI_MAP_CFG,
SHOW_RX_PRIV_WL,
SHOW_RX_COMM_THRES,
TX_BUFF_CFG,
RX_BUFF_CFG,
SHOW_TX_QUEUE_TO_TC,
L2_PFC_CFG,
QCN_EN_CFG,
RESET_CFG = 500,
RAS_RESET_CFG = 501,
TIMEOUT_CFG = 550,
CLEAN_STATS = 600,
PROMISC_MODE_CFG = 700,
QINFO_CFG = 800,
MACTABLE_CFG = 900,
PHY_REGISTER_CFG = 1000,
FD_CFG,
RSS_GENERIC_CFG,
REG_CFG,
COM_REG_CFG,
GRO_CFG,
LAMP_CFG,
M7_CMD_MODE_CFG, /* M7 cmd */
QRES_CFG = 1100,
STAT_CFG,
IRQ_CFG,
VLAN_UPMAPPING = 1200,
EXTERN_INTERFACE_CFG = 1300, /* extern interface test */
XSFP_CFG = 1400,
SHOW_PORT_INFO,
SHOW_HILINK_PARAM,
DCQCN_PARM_CFG = 1500,
DCQCN_GET_MSG_CNT_CMD = 1600
};
#define API_CMD (0x1)
#define API_CHAIN (0x2)
struct msg_module {
char device_name[IFNAMSIZ];
unsigned int module;
u32 msg_formate; /* cmd type for driver */
struct {
u32 in_buff_len;
u32 out_buff_len;
} len_info;
u32 res;
void *in_buff;
void *out_buf;
};
#define OUTER_L3_CHECK_EN 0x1
#define OUTER_UDP_CHECK_EN 0x1
#define INNER_L3_CHECK_EN 0x1
#define INNER_TCP_CHECK_EN 0x1
#define INNER_UDP_CHECK_EN 0x1
#define INNER_SCTP_CHECK_EN 0x1
enum {
DCQCN_MASK_AI = 0x0,
DCQCN_MASK_F,
DCQCN_MASK_TKP,
DCQCN_MASK_TMP,
DCQCN_MASK_ALP,
DCQCN_MASK_G,
DCQCN_MASK_AL,
DCQCN_MASK_MAX_SPEED,
DCQCN_MASK_CNP_TIME,
DCQCN_MASK_ALP_SHIFT,
};
#define HINICADM_DCQCN_READ_CFG_MODE 30
#define HINICADM_DCQCN_WRITE_CFG_MODE 31
enum {
CKS_OUTER_L3_EN = 0,
CKS_OUTER_UDP_EN,
CKS_INNER_L3_EN,
CKS_INNER_TCP_EN,
CKS_INNER_UDP_EN,
CKS_INNER_SCTP_EN,
CKS_MAX,
};
int nictool_k_init(void);
void nictool_k_uninit(void);
struct hns3_chs_param {
u8 is_set;
u8 type;
u8 is_enable;
};
struct hns3_test_commit_id_param {
u8 commit_id[8];
u32 ncl_version;
u32 rsv[3];
};
struct firmware_ver_param {
u32 imp_ver;
u8 commit_id[9];
u8 rsv[3];
u32 ncl_version;
};
#define HCLGE_OPC_GRO_AGE_CFG 0x0c11
struct hclge_gro_age_config_cmd {
u32 ppu_gro_age_cnt;
u8 rsv[20];
};
struct gro_param {
u8 is_read;
u32 age_cnt;
};
struct cfg_dcqcn_param {
u16 ai;
u8 f;
u8 tkp;
u16 tmp;
u16 alp;
u32 max_speed;
u8 g;
u8 al;
u8 cnp_time;
u8 alp_shift;
u16 dcqcn_parm_opcode;
u16 is_get;
u32 device_number;
};
struct dcqcn_statistic_param {
u32 dcqcn_rx_cnt;
u32 dcqcn_tx_cnt;
u32 dcqcn_db_cnt;
u32 dcqcn_statistic_enable;
};
enum DEVMEM_RW_TYPE {
DEVMEM_CFG_WRITE = 0,
DEVMEM_CFG_READ,
};
#endif
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2016-2017 Hisilicon Limited.
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/phy_fixed.h>
#include <linux/platform_device.h>
#include "hclge_cmd.h"
#include "hclge_main.h"
#include "hnae3.h"
#include "hns3_enet.h"
#include "hns3_priv_common_test.h"
static int hns3_test_write_reg_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct reg_param *in_buf = (struct reg_param *)buf_in;
enum hclge_cmd_status status;
struct hnae3_handle *handle;
struct hclge_vport *vport;
struct hclge_dev *hdev;
struct hclge_desc desc;
handle = net_priv->ae_handle;
vport = hclge_get_vport(handle);
hdev = vport->back;
if (in_buf->bits_width == 64) {
hclge_cmd_setup_basic_desc(&desc, CMDQ_64_COM_CMD_OPCODE,
false);
desc.data[0] = in_buf->addr;
desc.data[1] = in_buf->data[0];
} else {
hclge_cmd_setup_basic_desc(&desc, CMDQ_32_COM_CMD_OPCODE,
false);
desc.data[0] = in_buf->addr;
desc.data[2] = in_buf->data[0];
}
status = hclge_cmd_send(&hdev->hw, &desc, 1);
if (status) {
dev_err(&hdev->pdev->dev, "%s fail, status is %d.\n", __func__,
status);
return status;
}
return 0;
}
static int hns3_test_read_reg_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct reg_ret_param *out_buf = (struct reg_ret_param *)buf_out;
struct reg_param *in_buf = (struct reg_param *)buf_in;
struct hnae3_handle *handle = net_priv->ae_handle;
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
enum hclge_cmd_status status;
struct hclge_desc desc;
if (in_buf->bits_width == 64)
hclge_cmd_setup_basic_desc(&desc, CMDQ_64_COM_CMD_OPCODE, true);
else
hclge_cmd_setup_basic_desc(&desc, CMDQ_32_COM_CMD_OPCODE, true);
desc.data[0] = in_buf->addr;
status = hclge_cmd_send(&hdev->hw, &desc, 1);
if (status) {
dev_err(&hdev->pdev->dev, "%s fail, status is %d.\n", __func__,
status);
return status;
}
out_buf->value[0] = desc.data[0];
if (in_buf->bits_width == 64)
out_buf->value[1] = desc.data[1];
return 0;
}
int hns3_test_reg_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size, void *buf_out, u16 *out_size)
{
struct reg_param *mode_param = (struct reg_param *)buf_in;
int ret;
if (!mode_param) {
pr_err("%s error: mode_param NULL.\n", __func__);
return -EINVAL;
}
if (mode_param->is_read == 1)
ret = hns3_test_read_reg_cfg(net_priv, buf_in, in_size,
buf_out, out_size);
else
ret = hns3_test_write_reg_cfg(net_priv, buf_in, in_size,
buf_out, out_size);
return ret;
}
static int hns3_reg_read_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct com_reg_param *out_buf = (struct com_reg_param *)buf_out;
struct com_reg_param *in_buf = (struct com_reg_param *)buf_in;
struct hnae3_handle *handle = net_priv->ae_handle;
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
enum hclge_cmd_status status;
struct hclge_desc desc;
int i;
hclge_cmd_setup_basic_desc(&desc, in_buf->fw_dw_opcode,
in_buf->is_read);
for (i = 0; i < 6; i++)
desc.data[i] = in_buf->reg_desc.data[i];
status = hclge_cmd_send(&hdev->hw, &desc, 1);
if (status) {
dev_err(&hdev->pdev->dev, "%s, status is %d.\n", __func__,
status);
return status;
}
for (i = 0; i < 6; i++)
out_buf->reg_desc.data[i] = desc.data[i];
return 0;
}
static int hns3_reg_write_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct hnae3_handle *handle;
struct hclge_vport *vport;
struct hclge_dev *hdev;
struct hclge_desc desc;
enum hclge_cmd_status status;
struct com_reg_param *in_buf = (struct com_reg_param *)buf_in;
int i;
handle = net_priv->ae_handle;
vport = hclge_get_vport(handle);
hdev = vport->back;
hclge_cmd_setup_basic_desc(&desc, in_buf->fw_dw_opcode,
in_buf->is_read);
for (i = 0; i < 6; i++)
desc.data[i] = in_buf->reg_desc.data[i];
status = hclge_cmd_send(&hdev->hw, &desc, 1);
if (status) {
dev_err(&hdev->pdev->dev, "%s, status is %d.\n", __func__,
status);
return status;
}
return 0;
}
int hns3_reg_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size, void *buf_out, u16 *out_size)
{
int ret = 0;
struct com_reg_param *param;
param = (struct com_reg_param *)buf_in;
if (!param) {
pr_err("%s error: param NULL.\n", __func__);
return -EINVAL;
}
if (param->is_read == 1)
ret = hns3_reg_read_cfg(net_priv, buf_in, in_size, buf_out,
out_size);
else
ret = hns3_reg_write_cfg(net_priv, buf_in, in_size, buf_out,
out_size);
return ret;
}
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2016-2019 Hisilicon Limited. */
#ifndef __HNS3_PRIV_COMMON_TEST_H
#define __HNS3_PRIV_COMMON_TEST_H
#define REG_RDATA_NUM 2
#define CMDQ_32_COM_CMD_OPCODE 0xfffd
#define CMDQ_64_COM_CMD_OPCODE 0xffff
struct reg_param {
u32 addr;
u32 data[REG_RDATA_NUM];
u8 bits_width;
u8 is_read;
};
struct reg_ret_param {
u32 value[REG_RDATA_NUM];
};
struct cmd_desc {
u16 opcode;
u16 flag;
u16 retval;
u16 rsv;
u32 data[6];
};
struct com_reg_param {
struct cmd_desc reg_desc;
u32 fw_dw_opcode;
u32 is_read;
};
int hns3_test_reg_cfg(struct hns3_nic_priv *net_priv, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
int hns3_reg_cfg(struct hns3_nic_priv *net_priv, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
#endif
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2016-2017 Hisilicon Limited.
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/kthread.h>
#include "hnae3.h"
#include "hclge_main.h"
#include "hns3_enet.h"
#include "hclge_tm.h"
#include "hclge_cmd.h"
#include "hns3_priv_dcb.h"
struct nictool_dcb_info dcb_all_info[20];
u8 curr_dev_index;
u8 max_index;
static void check_and_set_curr_dev(struct hns3_nic_priv *net_priv)
{
int flag = false;
int i;
for (i = 0; i < max_index; i++) {
if (dcb_all_info[i].net_priv != net_priv)
continue;
flag = true;
curr_dev_index = i;
}
if (!flag) {
max_index++;
curr_dev_index = max_index - 1;
dcb_all_info[curr_dev_index].net_priv = net_priv;
}
}
int hns3_test_dcb_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size, void *buf_out, u16 *out_size)
{
struct nictool_dcb_cfg_param *in_info;
struct nictool_dcb_cfg_param *out_info;
in_info = (struct nictool_dcb_cfg_param *)buf_in;
out_info = (struct nictool_dcb_cfg_param *)buf_out;
check_and_set_curr_dev(net_priv);
if (!in_info) {
pr_err("in_info should not be NULL in %s funciton\n", __func__);
return -1;
}
if (in_info->is_read) {
out_info->dcb_en =
dcb_all_info[curr_dev_index].dcb_cfg_info.dcb_en;
} else {
if (in_info->cfg_flag & NICTOOL_DCB_DCB_CFG_FLAG)
dcb_all_info[curr_dev_index].dcb_cfg_info.dcb_en =
in_info->dcb_en;
}
return 0;
}
static int hns3_test_cfg_pfc_en(u8 is_read, struct hclge_dev *hdev,
struct nictool_pfc_cfg_param *info)
{
struct hclge_desc desc;
int ret;
hclge_cmd_setup_basic_desc(&desc, NICTOOL_OPC_CFG_PFC_PAUSE_EN, true);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
pr_err("read pfc enable status fail!ret = %d\n", ret);
return ret;
}
if (is_read) {
info->prien = ((desc.data[0] & 0xff00) >> 8);
info->pfc_en = ((desc.data[0] & 0x3) == 0x3);
} else {
hclge_cmd_reuse_desc(&desc, false);
if (info->cfg_flag & NICTOOL_PFC_EN_CFG_FLAG) {
desc.data[0] = (desc.data[0] & (~0x3)) |
(info->pfc_en << 0) |
(info->pfc_en << 1);
dcb_all_info[curr_dev_index].pfc_cfg_info.pfc_en =
info->pfc_en;
}
if (info->cfg_flag & NICTOOL_PFC_PRIEN_CFG_FLAG) {
desc.data[0] = (desc.data[0] & (~0xff00)) |
(info->prien << 8);
dcb_all_info[curr_dev_index].pfc_cfg_info.prien =
info->prien;
}
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
pr_err("set pfc cmd return fail!ret = %d\n", ret);
return ret;
}
}
return ret;
}
static int hns3_test_cfg_pause_param(struct hclge_dev *hdev,
struct nictool_pfc_cfg_param *info,
u8 is_read)
{
struct hclge_desc desc;
int ret;
hclge_cmd_setup_basic_desc(&desc, NICTOOL_OPC_CFG_PAUSE_PARAM, true);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
pr_err("pause param cfg cmd send fail\n");
return ret;
}
if (is_read) {
info->pause_time = desc.data[2] & 0xffff;
info->pause_gap = (desc.data[1] & 0xff0000) >> 16;
return 0;
}
if (info->cfg_flag & NICTOOL_PFC_TIME_CFG_FLAG)
desc.data[2] = (desc.data[2] & (~0xffff)) | info->pause_time;
if (info->cfg_flag & NICTOOL_PFC_GAP_CFG_FLAG)
desc.data[1] = (desc.data[1] & (~0xff0000)) |
(info->pause_gap << 16);
hclge_cmd_reuse_desc(&desc, false);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev,
"mac pause param cfg fail, ret = %d.\n", ret);
return ret;
}
return 0;
}
int hns3_test_dcb_pfc_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct nictool_pfc_cfg_param *out_info;
struct nictool_pfc_cfg_param *in_info;
struct net_device *ndev;
struct hclge_vport *vport;
struct hnae3_handle *h;
struct hclge_dev *hdev;
int ret;
check_and_set_curr_dev(net_priv);
h = net_priv->ae_handle;
vport = hclge_get_vport(h);
ndev = h->netdev;
hdev = vport->back;
in_info = (struct nictool_pfc_cfg_param *)buf_in;
out_info = (struct nictool_pfc_cfg_param *)buf_out;
if (!in_info) {
pr_err("in_info should not be NULL in %s function\n", __func__);
return -1;
}
if (!in_info->is_read &&
!dcb_all_info[curr_dev_index].dcb_cfg_info.dcb_en) {
pr_err("please enable dcb cfg first!\n");
return -1;
}
if (!hnae3_dev_dcb_supported(hdev) || vport->vport_id != 0) {
pr_err("this device doesn't support dcb!\n");
return -1;
}
if (in_info->is_read) {
ret = hns3_test_cfg_pfc_en(in_info->is_read, hdev, out_info);
if (ret)
return ret;
ret = hns3_test_cfg_pause_param(hdev, out_info, true);
if (ret)
return ret;
} else {
struct ieee_pfc pfc = {0};
if (in_info->cfg_flag & NICTOOL_PFC_PRIEN_CFG_FLAG) {
pfc.pfc_en = in_info->prien;
dcb_all_info[curr_dev_index].pfc_cfg_info.prien =
in_info->prien;
if (ndev->dcbnl_ops->ieee_setpfc) {
rtnl_lock();
ret = ndev->dcbnl_ops->ieee_setpfc(ndev, &pfc);
rtnl_unlock();
if (ret)
return ret;
}
}
if ((in_info->cfg_flag & NICTOOL_PFC_TIME_CFG_FLAG) ||
(in_info->cfg_flag & NICTOOL_PFC_GAP_CFG_FLAG)) {
ret = hns3_test_cfg_pause_param(hdev, in_info, false);
if (ret)
return ret;
}
}
return 0;
}
static void hns3_test_disable_ets_cfg(struct hclge_dev *hdev,
struct ieee_ets *ets)
{
u8 percent = 0;
int i;
for (i = 0; i < NICTOOL_ETS_MAC_TC_NUM; i++) {
ets->prio_tc[i] = hdev->tm_info.prio_tc[i];
ets->tc_tsa[i] = IEEE_8021QAZ_TSA_ETS;
dcb_all_info[curr_dev_index].ets_cfg_info.schedule[i] = 0;
}
for (i = 0; i < hdev->tm_info.num_tc; i++) {
ets->tc_tx_bw[i] = 100 / hdev->tm_info.num_tc;
dcb_all_info[curr_dev_index].ets_cfg_info.bw[i] =
ets->tc_tx_bw[i];
percent += ets->tc_tx_bw[i];
}
if (percent != 100) {
ets->tc_tx_bw[i - 1] += (100 - percent);
dcb_all_info[curr_dev_index].ets_cfg_info.bw[i - 1] =
ets->tc_tx_bw[i - 1];
}
}
static void hns3_test_enable_ets_cfg(struct hclge_dev *hdev,
struct ieee_ets *ets,
struct nictool_ets_cfg_param *info)
{
int i;
if (info->cfg_flag & NICTOOL_ETS_UP2TC_CFG_FLAG) {
for (i = 0; i < NICTOOL_ETS_MAC_TC_NUM; i++) {
ets->prio_tc[i] = info->up2tc[i];
dcb_all_info[curr_dev_index].ets_cfg_info.up2tc[i] =
info->up2tc[i];
}
} else {
for (i = 0; i < NICTOOL_ETS_MAC_TC_NUM; i++)
ets->prio_tc[i] = hdev->tm_info.prio_tc[i];
}
if (info->cfg_flag & NICTOOL_ETS_BANDWIDTH_CFG_FLAG) {
for (i = 0; i < NICTOOL_ETS_MAC_TC_NUM; i++) {
ets->tc_tx_bw[i] = info->bw[i];
dcb_all_info[curr_dev_index].ets_cfg_info.bw[i] =
info->bw[i];
}
} else {
for (i = 0; i < NICTOOL_ETS_MAC_TC_NUM; i++)
ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i];
}
if (info->cfg_flag & NICTOOL_ETS_SCHEDULE_CFG_FLAG) {
for (i = 0; i < NICTOOL_ETS_MAC_TC_NUM; i++) {
ets->tc_tsa[i] = info->schedule[i] ?
IEEE_8021QAZ_TSA_STRICT : IEEE_8021QAZ_TSA_ETS;
dcb_all_info[curr_dev_index].ets_cfg_info.schedule[i] =
info->schedule[i];
}
} else {
for (i = 0; i < NICTOOL_ETS_MAC_TC_NUM; i++)
ets->tc_tsa[i] = hdev->tm_info.tc_info[i].tc_sch_mode ?
IEEE_8021QAZ_TSA_ETS : IEEE_8021QAZ_TSA_STRICT;
}
}
int hns3_test_dcb_ets_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct nictool_ets_cfg_param *out_info;
struct nictool_ets_cfg_param *in_info;
struct hclge_vport *vport;
struct net_device *ndev;
struct hclge_dev *hdev;
struct hclge_desc desc;
struct hnae3_handle *h;
int ret;
int i;
check_and_set_curr_dev(net_priv);
h = net_priv->ae_handle;
vport = hclge_get_vport(h);
ndev = h->netdev;
hdev = vport->back;
in_info = (struct nictool_ets_cfg_param *)buf_in;
out_info = (struct nictool_ets_cfg_param *)buf_out;
if (!in_info) {
pr_err("in_info should not be NULL in %s function\n", __func__);
return -1;
}
if (!in_info->is_read &&
!dcb_all_info[curr_dev_index].dcb_cfg_info.dcb_en) {
pr_err("please enable dcb cfg first!\n");
return -1;
}
if (!hnae3_dev_dcb_supported(hdev) || vport->vport_id != 0) {
pr_err("this device doesn't support dcb!\n");
return -1;
}
if (in_info->is_read) {
hclge_cmd_setup_basic_desc(&desc,
NICTOOL_OPC_PRI_TO_TC_MAPPING, true);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
pr_err("read up2tc mapping fail!\n");
return ret;
}
out_info->ets_en =
dcb_all_info[curr_dev_index].ets_cfg_info.ets_en;
for (i = 0; i < NICTOOL_ETS_MAC_TC_NUM; i++) {
out_info->up2tc[i] =
(desc.data[0] & (0xf << (4 * i))) >> (4 * i);
dcb_all_info[curr_dev_index].ets_cfg_info.up2tc[i] =
out_info->up2tc[i];
out_info->bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i];
dcb_all_info[curr_dev_index].ets_cfg_info.bw[i] =
hdev->tm_info.pg_info[0].tc_dwrr[i];
out_info->schedule[i] =
!hdev->tm_info.tc_info[i].tc_sch_mode;
dcb_all_info[curr_dev_index].ets_cfg_info.schedule[i] =
!hdev->tm_info.tc_info[i].tc_sch_mode;
}
} else {
struct ieee_ets ets = {0};
if (in_info->cfg_flag & NICTOOL_ETS_EN_CFG_FLAG)
dcb_all_info[curr_dev_index].ets_cfg_info.ets_en =
in_info->ets_en;
if (!dcb_all_info[curr_dev_index].ets_cfg_info.ets_en)
hns3_test_disable_ets_cfg(hdev, &ets);
else
hns3_test_enable_ets_cfg(hdev, &ets, in_info);
if (ndev->dcbnl_ops->ieee_setets) {
rtnl_lock();
ret = ndev->dcbnl_ops->ieee_setets(ndev, &ets);
rtnl_unlock();
if (ret)
return ret;
}
out_info->cfg_flag = in_info->cfg_flag;
out_info->is_read = in_info->is_read;
out_info->ets_en =
dcb_all_info[curr_dev_index].ets_cfg_info.ets_en;
}
return 0;
}
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2016-2019 Hisilicon Limited. */
#ifndef __HNS3_PRIV_DCB_H__
#define __HNS3_PRIV_DCB_H__
struct nictool_pfc_cfg_param {
u8 is_read;
u8 cfg_flag;
u8 pfc_en;
u8 prien;
u16 pause_time;
u8 pause_gap;
};
struct nictool_dcb_cfg_param {
u8 is_read;
u8 cfg_flag;
u8 dcb_en;
};
struct nictool_ets_cfg_param {
u8 is_read;
u8 cfg_flag;
u8 ets_en;
u8 up2tc[8];
u8 bw[8];
u8 schedule[8];
};
struct nictool_dcb_info {
struct hns3_nic_priv *net_priv;
struct nictool_pfc_cfg_param pfc_cfg_info;
struct nictool_dcb_cfg_param dcb_cfg_info;
struct nictool_ets_cfg_param ets_cfg_info;
};
#define NICTOOL_OPC_CFG_MAC_PAUSE_EN 0x0701
#define NICTOOL_OPC_CFG_PFC_PAUSE_EN 0x0702
#define NICTOOL_OPC_CFG_PAUSE_PARAM 0x0703
#define NICTOOL_OPC_PRI_TO_TC_MAPPING 0x0709
#define NICTOOL_OPC_TM_PRI_WEIGHT 0x080b
#define NICTOOL_DCB_DCB_CFG_FLAG 0x1
#define NICTOOL_ETS_EN_CFG_FLAG 0x1
#define NICTOOL_ETS_UP2TC_CFG_FLAG 0x2
#define NICTOOL_ETS_BANDWIDTH_CFG_FLAG 0x4
#define NICTOOL_ETS_SCHEDULE_CFG_FLAG 0x8
#define NICTOOL_ETS_MAC_TC_NUM 8
#define NICTOOL_PFC_EN_CFG_FLAG 0x1
#define NICTOOL_PFC_PRIEN_CFG_FLAG 0x2
#define NICTOOL_PFC_TIME_CFG_FLAG 0x4
#define NICTOOL_PFC_GAP_CFG_FLAG 0x8
#define NICTOOL_PFC_MAC_PRI 8
int hns3_test_dcb_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size, void *buf_out, u16 *out_size);
int hns3_test_dcb_ets_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
int hns3_test_dcb_pfc_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
#endif
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2016-2017 Hisilicon Limited.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/phy_fixed.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include "hclge_cmd.h"
#include "hnae3.h"
#include "hclge_main.h"
#include "hns3_enet.h"
#include "hns3_priv_dfx.h"
static int hns3_test_operate_nic_regs(struct hclge_dev *hdev,
struct hns3_test_reg_param *info)
{
struct hclge_desc desc;
int ret;
if (info->is_read) {
hclge_cmd_setup_basic_desc(&desc, OPC_WRITE_READ_REG_CMD, true);
desc.data[0] = (u32)(info->addr & 0xffffffff);
desc.data[1] = (u32)(info->addr >> 32);
desc.data[4] = (u32)info->bit_width;
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev,
"read addr 0x%llx failed! ret = %d.\n",
info->addr, ret);
return ret;
}
info->value = (u64)desc.data[2] | ((u64)desc.data[3] << 32);
} else {
hclge_cmd_setup_basic_desc(&desc, OPC_WRITE_READ_REG_CMD,
false);
desc.data[0] = (u32)(info->addr & 0xffffffff);
desc.data[1] = (u32)(info->addr >> 32);
desc.data[2] = (u32)(info->value & 0xffffffff);
desc.data[3] = (u32)(info->value >> 32);
desc.data[4] = (u32)info->bit_width;
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev,
"write addr 0x%llx value 0x%llx failed! ret = %d.\n",
info->addr, info->value, ret);
return ret;
}
}
return 0;
}
static int hns3_test_get_chip_and_mac_id(struct hnae3_handle *handle,
u32 *chip_id, u32 *mac_id)
{
#define HNS3_TEST_GET_CHIP_MAC_ID_CMD 0x7003
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, HNS3_TEST_GET_CHIP_MAC_ID_CMD, true);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev, "get chip id and mac id failed %d\n",
ret);
return ret;
}
*chip_id = desc.data[0];
*mac_id = desc.data[1];
return 0;
}
int hns3_test_get_dfx_info(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
#define HNS3_TEST_MAC_MODE_ADDR 0x130000000U
#define HNS3_TEST_MAC_MAP_ADDR 0x130000008U
struct hns3_test_dfx_param *out_info;
struct hns3_test_reg_param reg_info;
struct hnae3_handle *handle;
struct hclge_vport *vport;
struct hclge_dev *hdev;
u32 chip_id;
u32 mac_id;
int ret;
int i;
handle = net_priv->ae_handle;
vport = hclge_get_vport(handle);
hdev = vport->back;
out_info = (struct hns3_test_dfx_param *)buf_out;
ret = hns3_test_get_chip_and_mac_id(handle, &chip_id, &mac_id);
if (ret)
return ret;
out_info->chip_id = (u8)chip_id;
out_info->mac_id = (u8)mac_id;
out_info->func_id = (u8)hdev->pdev->devfn;
out_info->is_cs_board =
(handle->pdev->revision > HNAE3_REVISION_ID_20) ? true : false;
reg_info.addr = HNS3_TEST_MAC_MODE_ADDR;
reg_info.bit_width = 32;
reg_info.is_read = true;
ret = hns3_test_operate_nic_regs(hdev, &reg_info);
if (ret) {
pr_err("read chip%d's work mode failed!\n", chip_id);
return ret;
}
out_info->work_mode = reg_info.value;
reg_info.addr = HNS3_TEST_MAC_MAP_ADDR;
reg_info.bit_width = 64;
reg_info.is_read = true;
ret = hns3_test_operate_nic_regs(hdev, &reg_info);
if (ret) {
pr_err("read mac's map info failed!\n");
return ret;
}
for (i = 0; i < HNS3_TEST_MAX_MAC_NUMBER; i++)
out_info->mac_used |= ((reg_info.value >> (i * 8)) & 0xff);
return 0;
}
int hns3_test_read_dfx_info(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct hns3_test_reg_param *out_info;
struct hns3_test_reg_param *in_info;
struct hnae3_handle *handle;
struct hclge_vport *vport;
struct hclge_dev *hdev;
int ret;
handle = net_priv->ae_handle;
vport = hclge_get_vport(handle);
hdev = vport->back;
in_info = (struct hns3_test_reg_param *)buf_in;
out_info = (struct hns3_test_reg_param *)buf_out;
if (in_info->is_read) {
out_info->addr = in_info->addr;
out_info->is_read = true;
out_info->bit_width = in_info->bit_width;
ret = hns3_test_operate_nic_regs(hdev, out_info);
if (ret)
return ret;
} else {
ret = hns3_test_operate_nic_regs(hdev, in_info);
if (ret)
return ret;
}
return 0;
}
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2016-2019 Hisilicon Limited. */
#ifndef __HNS3_PRIV_DFX_H
#define __HNS3_PRIV_DFX_H
#define OPC_WRITE_READ_REG_CMD 0x7014
struct hns3_test_reg_param {
u8 is_read;
u8 bit_width;
u64 value;
u64 addr;
};
struct hns3_test_dfx_param {
u8 is_cs_board;
u8 work_mode;
u8 mac_used;
u8 chip_id;
u8 mac_id;
u8 func_id;
};
#define HNS3_READ_INFO_FLAG 0x1
#define HNS3_READ_REGS_FLAG 0x2
#define HNS3_TEST_MAX_MAC_NUMBER 0x8
int hns3_test_get_dfx_info(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
int hns3_test_read_dfx_info(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
#endif
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2016-2017 Hisilicon Limited.
#include "hns3_priv_ext.h"
#include "hns3_ext.h"
static int hns3_ext_test_disable_netclk(struct hns3_nic_priv *net_priv)
{
struct net_device *netdev = net_priv->netdev;
return nic_disable_clock(netdev);
}
static int hns3_get_cpu_affinity(struct hns3_nic_priv *priv)
{
struct hns3_enet_tqp_vector *tqp_vector;
struct hnae3_handle *h;
int i;
if (!priv) {
pr_err("invalid input param when get cpu affinity\n");
return -EINVAL;
}
h = priv->ae_handle;
if (nic_netdev_match_check(priv->netdev))
return -ENODEV;
pr_info("%s : %d irq total.\n", h->pdev->driver->name,
priv->vector_num);
for (i = 0; i < priv->vector_num; i++) {
tqp_vector = &priv->tqp_vector[i];
if (tqp_vector->irq_init_flag != HNS3_VECTOR_INITED)
continue;
pr_err("irq %d ==> cpu affinity: %*pb\n",
tqp_vector->vector_irq,
cpumask_pr_args(&tqp_vector->affinity_mask));
}
return 0;
}
static int hns3_ext_test_affi(struct hns3_nic_priv *net_priv, void *in)
{
struct hns3_cpumask_param *cpumask_param;
cpumask_var_t cpumask_new;
int ret;
cpumask_param = (struct hns3_cpumask_param *)in;
if (cpumask_param->affi_exec_flag != HNS3_AFFI_GET_BIT) {
if (!alloc_cpumask_var(&cpumask_new, GFP_KERNEL))
return -ENOMEM;
ret = cpumask_parse(cpumask_param->mask, cpumask_new);
if (ret) {
pr_err("parse cpu affinity from user fail, ret = %d\n",
ret);
return ret;
}
ret = nic_set_cpu_affinity(net_priv->netdev, cpumask_new);
if (ret) {
pr_err("set cpu affinity fail, ret = %d\n", ret);
return ret;
}
} else {
ret = hns3_get_cpu_affinity(net_priv);
if (ret) {
pr_err("get cpu affinity fail, ret = %d\n", ret);
return ret;
}
}
return ret;
}
static int hns3_ext_test_get_chipid(struct hns3_nic_priv *net_priv,
void *out, u16 *out_size)
{
u32 chip_id;
int ret;
struct net_device *netdev = net_priv->netdev;
ret = nic_get_chipid(netdev, &chip_id);
if (!ret) {
*(u32 *)out = chip_id;
*out_size = sizeof(chip_id);
}
return ret;
}
static int hns3_ext_test_match_check(struct hns3_nic_priv *net_priv)
{
struct net_device *netdev = net_priv->netdev;
return nic_netdev_match_check(netdev);
}
static int hns3_ext_test_set_led(struct hns3_nic_priv *net_priv, void *in)
{
struct hns3_led_state_para *para = (struct hns3_led_state_para *)in;
struct net_device *netdev = net_priv->netdev;
return nic_set_led(netdev, para->type, para->status);
}
static int hns3_ext_test_get_sfp_info(struct hns3_nic_priv *net_priv, void *in,
void *out, u16 *out_size)
{
struct hns3_priv_sfp_info_para *para_in =
(struct hns3_priv_sfp_info_para *)in;
struct hns3_priv_sfp_info_para *para_out =
(struct hns3_priv_sfp_info_para *)out;
struct net_device *netdev = net_priv->netdev;
int ret;
ret = nic_get_sfpinfo(netdev, para_out->buff, para_in->size,
&para_out->outlen);
if (!ret)
*out_size = para_out->outlen;
return ret;
}
static int hns3_ext_test_get_sfp_present(struct hns3_nic_priv *net_priv,
void *out, u16 *out_size)
{
struct net_device *netdev = net_priv->netdev;
u32 present;
int ret;
ret = nic_get_sfp_present(netdev, &present);
if (!ret) {
*(u32 *)out = present;
*out_size = sizeof(present);
}
return ret;
}
static int hns3_ext_test_set_sfp_state(struct hns3_nic_priv *net_priv, void *in)
{
struct net_device *netdev = net_priv->netdev;
bool en = *(bool *)in;
return nic_set_sfp_state(netdev, en);
}
static int hns3_ext_test_clean_stats64(struct hns3_nic_priv *net_priv)
{
struct net_device *netdev = net_priv->netdev;
return nic_clean_stats64(netdev, NULL);
}
static int hns3_ext_test_get_chip_num(struct hns3_nic_priv *net_priv,
void *out, u16 *out_size)
{
struct net_device *netdev = net_priv->netdev;
u32 chip_num;
int ret;
ret = nic_get_chip_num(netdev, &chip_num);
if (!ret) {
*(u32 *)out = chip_num;
*out_size = sizeof(chip_num);
}
return ret;
}
static int hns3_ext_test_get_port_num(struct hns3_nic_priv *net_priv,
void *out, u16 *out_size)
{
struct net_device *netdev = net_priv->netdev;
u32 port_num;
int ret;
ret = nic_get_port_num_per_chip(netdev, &port_num);
if (!ret) {
*(u32 *)out = port_num;
*out_size = sizeof(port_num);
}
return ret;
}
static int hns3_ext_test_disable_net_lane(struct hns3_nic_priv *net_priv)
{
struct net_device *netdev = net_priv->netdev;
return nic_disable_net_lane(netdev);
}
static int hns3_ext_test_get_lane_status(struct hns3_nic_priv *net_priv,
void *out, u16 *out_size)
{
struct net_device *netdev = net_priv->netdev;
u32 lane_status;
int ret;
ret = nic_get_net_lane_status(netdev, &lane_status);
if (!ret) {
*(u32 *)out = lane_status;
*out_size = lane_status;
}
return ret;
}
static int hns3_ext_test_set_mac_state(struct hns3_nic_priv *net_priv, void *in)
{
struct net_device *netdev = net_priv->netdev;
int enable = *(int *)in;
return nic_set_mac_state(netdev, enable);
}
static int hns3_ext_test_set_pfc_storm_para(struct hns3_nic_priv *net_priv,
void *in)
{
struct hns3_pfc_storm_para *para = (struct hns3_pfc_storm_para *)in;
struct net_device *netdev = net_priv->netdev;
return nic_set_pfc_storm_para(netdev, para->dir, para->enable,
para->period_ms, para->times,
para->recovery_period_ms);
}
static int hns3_ext_test_get_pfc_storm_para(struct hns3_nic_priv *net_priv,
void *in, void *out, u16 *out_size)
{
struct hns3_pfc_storm_para *para_in = (struct hns3_pfc_storm_para *)in;
struct net_device *netdev = net_priv->netdev;
struct hns3_pfc_storm_para *para_out =
(struct hns3_pfc_storm_para *)out;
u32 recovery_period_ms;
u32 period_ms;
u32 enable;
u32 times;
u32 dir;
int ret;
dir = para_in->dir;
ret = nic_get_pfc_storm_para(netdev, dir, &enable, &period_ms,
&times, &recovery_period_ms);
if (!ret) {
para_out->dir = dir;
para_out->enable = enable;
para_out->period_ms = period_ms;
para_out->times = times;
para_out->recovery_period_ms = recovery_period_ms;
*out_size = sizeof(struct hns3_pfc_storm_para);
}
return ret;
}
static int hns3_ext_test_get_phy_reg(struct hns3_nic_priv *net_priv, void *in,
void *out, u16 *out_size)
{
struct hns3_phy_para *para_out = (struct hns3_phy_para *)out;
struct hns3_phy_para *para_in = (struct hns3_phy_para *)in;
u32 page_select_addr = para_in->page_select_addr;
struct net_device *netdev = net_priv->netdev;
u32 reg_addr = para_in->reg_addr;
u16 page = para_in->page;
u16 data;
int ret;
ret = nic_get_phy_reg(netdev, page_select_addr, page, reg_addr, &data);
if (!ret) {
para_out->page = page;
para_out->reg_addr = reg_addr;
para_out->data = data;
*out_size = sizeof(struct hns3_phy_para);
}
return ret;
}
static int hns3_ext_test_set_phy_reg(struct hns3_nic_priv *net_priv, void *in)
{
struct hns3_phy_para *para = (struct hns3_phy_para *)in;
struct net_device *netdev = net_priv->netdev;
return nic_set_phy_reg(netdev, para->page_select_addr,
para->page, para->reg_addr, para->data);
}
static int hns3_ext_test_get_macid(struct hns3_nic_priv *net_priv,
void *out, u16 *out_size)
{
struct net_device *netdev = net_priv->netdev;
u32 mac_id;
int ret;
ret = nic_get_mac_id(netdev, &mac_id);
if (!ret) {
*(u32 *)out = mac_id;
*out_size = sizeof(mac_id);
}
return ret;
}
static int hns3_ext_test_get_hilink_ref_los(struct hns3_nic_priv *net_priv,
void *out, u16 *out_size)
{
struct net_device *netdev = net_priv->netdev;
u32 status;
int ret;
ret = nic_get_hilink_ref_los(netdev, &status);
if (!ret) {
*(u32 *)out = status;
*out_size = sizeof(status);
}
return ret;
}
int hns3_ext_interface_test(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct cmd_ext_driver_param *ext_param_in;
struct cmd_ext_driver_param *ext_param_out;
void *in;
void *out;
int ret;
ext_param_in = (struct cmd_ext_driver_param *)buf_in;
ext_param_out = (struct cmd_ext_driver_param *)buf_out;
in = ext_param_in->buf;
out = ext_param_out->buf;
switch (ext_param_in->op_code) {
case EXT_AFFI_MASK:
ret = hns3_ext_test_affi(net_priv, in);
break;
case EXT_DISABLE_NET_CLK:
ret = hns3_ext_test_disable_netclk(net_priv);
break;
case EXT_GET_CHIP_ID:
ret = hns3_ext_test_get_chipid(net_priv, out, out_size);
break;
case EXT_NET_MATCH_CHECK:
ret = hns3_ext_test_match_check(net_priv);
break;
case EXT_SET_LED:
ret = hns3_ext_test_set_led(net_priv, in);
break;
case EXT_GET_SFP_INFO:
ret = hns3_ext_test_get_sfp_info(net_priv, in, out, out_size);
break;
case EXT_GET_SFP_PRESENT:
ret = hns3_ext_test_get_sfp_present(net_priv, out, out_size);
break;
case EXT_SET_SFP_STATE:
ret = hns3_ext_test_set_sfp_state(net_priv, in);
break;
case EXT_CLEAN_STATS64:
ret = hns3_ext_test_clean_stats64(net_priv);
break;
case EXT_GET_CHIP_NUM:
ret = hns3_ext_test_get_chip_num(net_priv, out, out_size);
break;
case EXT_GET_PORT_NUM:
ret = hns3_ext_test_get_port_num(net_priv, out, out_size);
break;
case EXT_DISABLE_NET_LANE:
ret = hns3_ext_test_disable_net_lane(net_priv);
break;
case EXT_GET_LANE_STATUS:
ret = hns3_ext_test_get_lane_status(net_priv, out, out_size);
break;
case EXT_SET_MAC_STATE:
ret = hns3_ext_test_set_mac_state(net_priv, in);
break;
case EXT_SET_PFC_STORM_PARA:
ret = hns3_ext_test_set_pfc_storm_para(net_priv, in);
break;
case EXT_GET_PFC_STORM_PARA:
ret = hns3_ext_test_get_pfc_storm_para(net_priv, in,
out, out_size);
break;
case EXT_GET_PHY_REG:
ret = hns3_ext_test_get_phy_reg(net_priv, in, out, out_size);
break;
case EXT_SET_PHY_REG:
ret = hns3_ext_test_set_phy_reg(net_priv, in);
break;
case EXT_GET_MAC_ID:
ret = hns3_ext_test_get_macid(net_priv, out, out_size);
break;
case EXT_GET_HILINK_REF_LOS:
ret = hns3_ext_test_get_hilink_ref_los(net_priv, out, out_size);
break;
default:
ret = -EFAULT;
}
return ret;
}
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2016-2019 Hisilicon Limited. */
#ifndef __HNS3_PRIV_EXT_H
#define __HNS3_PRIV_EXT_H
#include "hnae3.h"
#include "hns3_enet.h"
#define HNS3_AFFI_SET_BIT BIT(0)
#define HNS3_AFFI_GET_BIT BIT(1)
#define HNS3_AFFI_MAX_LEN 34
enum ext_op_code {
EXT_AFFI_MASK = 0,
EXT_DISABLE_NET_CLK,
EXT_GET_CHIP_ID,
EXT_NET_MATCH_CHECK,
EXT_SET_LED,
EXT_GET_SFP_INFO,
EXT_GET_SFP_PRESENT,
EXT_SET_SFP_STATE,
EXT_CLEAN_STATS64,
EXT_GET_CHIP_NUM,
EXT_GET_PORT_NUM,
EXT_DISABLE_NET_LANE,
EXT_GET_LANE_STATUS,
EXT_SET_MAC_STATE,
EXT_SET_PFC_STORM_PARA,
EXT_GET_PFC_STORM_PARA,
EXT_GET_PHY_REG,
EXT_SET_PHY_REG,
EXT_GET_MAC_ID,
EXT_GET_HILINK_REF_LOS,
};
struct hns3_cpumask_param {
u32 affi_exec_flag;
char mask[HNS3_AFFI_MAX_LEN];
};
struct hns3_priv_sfp_info_para {
u8 buff[768];
u16 offset;
u16 size;
u16 outlen;
};
struct cmd_ext_driver_param {
u32 op_code;
u32 judge_class;
u8 buf[1024];
};
int hns3_ext_interface_test(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
#endif
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2016-2019 Hisilicon Limited. */
#ifndef __HNS3_PRIV_FD_H__
#define __HNS3_PRIV_FD_H__
#define HCLGE_OPC_FD_CNT_OP 0x1205
struct fd_param {
u8 is_read;
u8 stage;
u16 op;
u8 xy_sel;
__le32 idx;
u8 entry_vld;
u8 data[128];
};
struct hclge_fd_cnt_op_cmd {
u8 stage;
u8 rsv1[3];
__le16 cnt_idx;
u8 rsv2[2];
__le64 cnt_value;
u8 rsv3[8];
};
struct hclge_fd_tcam_data {
u8 vld;
u8 tcam_data[52];
};
int hns3_test_fd_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size, void *buf_out, u16 *out_size);
#endif
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2016-2019 Hisilicon Limited. */
#ifndef __HNS3_PRIV_HILINK_PARAM_H__
#define __HNS3_PRIV_HILINK_PARAM_H__
#define HILINK_LANE_MAX_NUM 10
#define HCLGE_OPC_DUMP_CTLE_PARAM 0x0382
#define HCLGE_OPC_DUMP_DFE_PARAM 0x0383
#define HCLGE_OPC_DUMP_FFE_PARAM 0x0384
struct hns3_ctle_data {
u8 ctlebst[3];
u8 ctlecmband[3];
u8 ctlermband[3];
u8 ctleza[3];
u8 ctlesqh[3];
u8 ctleactgn[3];
u8 ctlepassgn;
u8 ctlerefsel;
u8 ctleibiastune;
u8 alos;
u8 lpbk;
};
struct hns3_dfe_data {
u8 dfefxtap[10]; /* DFE Fix Tap */
u8 floatingtap[6]; /* DFE Floating Taps */
};
struct hns3_ffe_data {
u8 pre2;
u8 pre1;
u8 main;
u8 post1;
u8 post2;
};
struct hns3_hilink_param {
u32 lane_start;
u32 lane_len;
struct hns3_ctle_data ctle_param[HILINK_LANE_MAX_NUM];
struct hns3_dfe_data dfe_param[HILINK_LANE_MAX_NUM];
struct hns3_ffe_data ffe_param[HILINK_LANE_MAX_NUM];
};
int hns3_get_hilink_param(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
#endif
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2016-2019 Hisilicon Limited. */
#ifndef __HNS3_PRIV_IRQ_H__
#define __HNS3_PRIV_IRQ_H__
int hns3_irq_lli_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size, void *buf_out, u16 *out_size);
#endif
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2016-2017 Hisilicon Limited.
#include "hclge_cmd.h"
#include "hnae3.h"
#include "hclge_main.h"
#include "hns3_enet.h"
#include "hns3_priv_lamp.h"
int hns3_lamp_cfg(struct hns3_nic_priv *net_priv,
void *buf_in, u16 in_size, void *buf_out, u16 *out_size)
{
struct net_device *netdev = net_priv->netdev;
struct hns3_lamp_signal *signal;
struct hns3_lamp_param *param;
int ret = -1;
if (!buf_in || !buf_out)
return -ENODEV;
param = (struct hns3_lamp_param *)buf_in;
signal = (struct hns3_lamp_signal *)buf_out;
if (param->op_type == LAMP_OP_GET_SGPIO)
ret = nic_get_led_signal(netdev, signal);
else if (param->op_type == LAMP_OP_SET_TYPE)
ret = nic_set_led(netdev, param->type, param->status);
return ret;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册