提交 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 ...@@ -123,6 +123,16 @@ config HNS3_ENET
family of SoCs. This module depends upon HNAE3 driver to access the HNAE3 family of SoCs. This module depends upon HNAE3 driver to access the HNAE3
devices and their associated operations. 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 #HNS3
endif # NET_VENDOR_HISILICON endif # NET_VENDOR_HISILICON
...@@ -2,14 +2,85 @@ ...@@ -2,14 +2,85 @@
# #
# Makefile for the HISILICON network device drivers. # Makefile for the HISILICON network device drivers.
# #
ccflags-y += -I$(srctree)/$(src)
obj-$(CONFIG_HNS3) += hns3pf/ # Add security options
obj-$(CONFIG_HNS3) += hns3vf/ 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) += hnae3.o
obj-$(CONFIG_HNS3_ENET) += hns3.o obj-$(CONFIG_HNS3_ENET) += hns3.o
hns3-objs = hns3_enet.o hns3_ethtool.o hns3_debugfs.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 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 @@ ...@@ -8,75 +8,22 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
#include "../hnae3.h" #include "hnae3.h"
#include "hns3_enet_it.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_driver_string[];
extern const char hns3_copyright[]; extern const char hns3_copyright[];
#ifdef CONFIG_IT_VALIDATION #ifdef CONFIG_IT_VALIDATION
#define HNAE_DRIVER_VERSION "B075" #define HNAE_DRIVER_VERSION "1.8.10.0"
#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 struct net_device_ops hns3_nic_netdev_ops;
extern const struct hnae3_client_ops client_ops; extern const struct hnae3_client_ops client_ops;
extern struct hnae3_client client; extern struct hnae3_client client;
extern struct pci_driver hns3_driver; extern struct pci_driver hns3_driver;
extern const char hns3_driver_name[]; 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) 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) ...@@ -84,7 +31,6 @@ int hns3_nic_do_ioctl_it(struct net_device *netdev, struct ifreq *ifr, int cmd)
case (SIOCDEVPRIVATE + 4): case (SIOCDEVPRIVATE + 4):
if (hns3_ioctl) if (hns3_ioctl)
return hns3_ioctl(netdev, ifr->ifr_data); return hns3_ioctl(netdev, ifr->ifr_data);
pr_err("open nic_test failed");
return -EINVAL; return -EINVAL;
default: default:
return -EINVAL; return -EINVAL;
...@@ -93,8 +39,7 @@ int hns3_nic_do_ioctl_it(struct net_device *netdev, struct ifreq *ifr, int cmd) ...@@ -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) #if (KERNEL_VERSION(4, 19, 0) > LINUX_VERSION_CODE)
u16 hns3_nic_select_queue_it(struct net_device *ndev, struct sk_buff *skb, u16 hns3_nic_select_queue_it(struct net_device *ndev, struct sk_buff *skb,
void *accel_priv, void *accel_priv, select_queue_fallback_t fallback)
select_queue_fallback_t fallback)
#else #else
u16 hns3_nic_select_queue_it(struct net_device *ndev, struct sk_buff *skb, u16 hns3_nic_select_queue_it(struct net_device *ndev, struct sk_buff *skb,
struct net_device *accel_priv, struct net_device *accel_priv,
...@@ -115,25 +60,15 @@ u16 hns3_nic_select_queue_it(struct net_device *ndev, struct sk_buff *skb, ...@@ -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) static int __init hns3_init_module_it(void)
{ {
struct ethtool_ops *loc_ethtool_ops;
struct net_device_ops *ndev_ops; struct net_device_ops *ndev_ops;
int ret; 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 - version\n", hns3_driver_name, hns3_driver_string);
pr_info("%s: %s\n", hns3_driver_name, hns3_copyright); pr_info("%s: %s\n", hns3_driver_name, hns3_copyright);
strncpy(hns3_driver_version, HNAE_DRIVER_VERSION, 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; client.type = HNAE3_CLIENT_KNIC;
snprintf(client.name, HNAE3_CLIENT_NAME_LENGTH - 1, "%s", snprintf(client.name, HNAE3_CLIENT_NAME_LENGTH - 1, "%s",
hns3_driver_name); hns3_driver_name);
...@@ -141,9 +76,6 @@ static int __init hns3_init_module_it(void) ...@@ -141,9 +76,6 @@ static int __init hns3_init_module_it(void)
client.ops = &client_ops; client.ops = &client_ops;
ndev_ops = (struct net_device_ops *)&hns3_nic_netdev_ops; ndev_ops = (struct net_device_ops *)&hns3_nic_netdev_ops;
ndev_ops->ndo_do_ioctl = hns3_nic_do_ioctl_it; 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; ndev_ops->ndo_select_queue = hns3_nic_select_queue_it;
INIT_LIST_HEAD(&client.node); INIT_LIST_HEAD(&client.node);
...@@ -153,7 +85,6 @@ static int __init hns3_init_module_it(void) ...@@ -153,7 +85,6 @@ static int __init hns3_init_module_it(void)
if (ret) if (ret)
goto err_reg_client; goto err_reg_client;
hns3_driver.id_table = hns3_pci_tbl_it;
ret = pci_register_driver(&hns3_driver); ret = pci_register_driver(&hns3_driver);
if (ret) if (ret)
goto err_reg_driver; goto err_reg_driver;
...@@ -166,5 +97,6 @@ static int __init hns3_init_module_it(void) ...@@ -166,5 +97,6 @@ static int __init hns3_init_module_it(void)
hns3_dbg_unregister_debugfs(); hns3_dbg_unregister_debugfs();
return ret; return ret;
} }
module_init(hns3_init_module_it); module_init(hns3_init_module_it);
#endif #endif
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
typedef int (*hns3_priv_func)(struct net_device *, void *); typedef int (*hns3_priv_func)(struct net_device *, void *);
hns3_priv_func hns3_ioctl; hns3_priv_func hns3_ioctl;
#define VERSION_NUMBER "$FULL_VERSION"
#ifndef LINUX_VERSION_CODE #ifndef LINUX_VERSION_CODE
#include <linux/version.h> #include <linux/version.h>
#else #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) ...@@ -38,21 +38,28 @@ int nic_netdev_match_check(struct net_device *netdev)
EXPORT_SYMBOL(nic_netdev_match_check); EXPORT_SYMBOL(nic_netdev_match_check);
void nic_chip_recover_handler(struct net_device *netdev, 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; struct hnae3_handle *h;
if (nic_netdev_match_check(netdev)) if (nic_netdev_match_check(netdev))
return; return;
priv = netdev_priv(netdev); dev_info(&netdev->dev, "reset type is %d!!\n", event_t);
h = priv->ae_handle;
ae_dev = pci_get_drvdata(h->pdev);
if (ae_dev->ops->reset_event) if (event_t == HNAE3_PPU_POISON_CUSTOM)
ae_dev->ops->reset_event(h->pdev, NULL); 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); EXPORT_SYMBOL(nic_chip_recover_handler);
...@@ -70,7 +77,10 @@ int nic_clean_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats) ...@@ -70,7 +77,10 @@ int nic_clean_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats)
priv = netdev_priv(ndev); priv = netdev_priv(ndev);
h = hns3_get_handle(ndev); h = hns3_get_handle(ndev);
kinfo = &h->kinfo; 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++) { for (i = 0; i < kinfo->num_tqps; i++) {
ring = priv->ring_data[i].ring; ring = priv->ring_data[i].ring;
...@@ -95,66 +105,96 @@ int nic_get_chipid(struct net_device *ndev, u32 *chip_id) ...@@ -95,66 +105,96 @@ int nic_get_chipid(struct net_device *ndev, u32 *chip_id)
return -EINVAL; return -EINVAL;
h = hns3_get_handle(ndev); 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); 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; struct hnae3_handle *h;
if (nic_netdev_match_check(ndev)) if (nic_netdev_match_check(ndev))
return -ENODEV; return -ENODEV;
if (!buff || !outlen) if (!mac_id)
return -EINVAL; return -EINVAL;
h = hns3_get_handle(ndev); 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; struct hnae3_handle *h;
if (nic_netdev_match_check(ndev)) if (nic_netdev_match_check(ndev))
return -ENODEV; return -ENODEV;
if (!present) if (!buff || !outlen)
return -EINVAL; return -EINVAL;
para.buff = buff;
para.outlen = outlen;
para.offset = 0;
para.size = size;
h = hns3_get_handle(ndev); 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; struct hnae3_handle *h;
if (nic_netdev_match_check(ndev)) if (nic_netdev_match_check(ndev))
return -ENODEV; return -ENODEV;
if (!present)
return -EINVAL;
h = hns3_get_handle(ndev); 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; struct hnae3_handle *h;
if (nic_netdev_match_check(ndev)) if (nic_netdev_match_check(ndev))
return -ENODEV; return -ENODEV;
if (!speed)
return -EINVAL;
h = hns3_get_handle(ndev); 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) 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) ...@@ -167,7 +207,11 @@ int nic_get_chip_num(struct net_device *ndev, u32 *chip_num)
return -EINVAL; return -EINVAL;
h = hns3_get_handle(ndev); 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); EXPORT_SYMBOL(nic_get_chip_num);
...@@ -182,19 +226,30 @@ int nic_get_port_num_per_chip(struct net_device *ndev, u32 *port_num) ...@@ -182,19 +226,30 @@ int nic_get_port_num_per_chip(struct net_device *ndev, u32 *port_num)
return -EINVAL; return -EINVAL;
h = hns3_get_handle(ndev); 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); EXPORT_SYMBOL(nic_get_port_num_per_chip);
int nic_set_led(struct net_device *ndev, int type, int status) int nic_set_led(struct net_device *ndev, int type, int status)
{ {
struct hns3_led_state_para para;
struct hnae3_handle *h; struct hnae3_handle *h;
if (nic_netdev_match_check(ndev)) if (nic_netdev_match_check(ndev))
return -ENODEV; return -ENODEV;
para.status = status;
para.type = type;
h = hns3_get_handle(ndev); 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); EXPORT_SYMBOL(nic_set_led);
...@@ -209,7 +264,11 @@ int nic_get_led_signal(struct net_device *ndev, struct hns3_lamp_signal *signal) ...@@ -209,7 +264,11 @@ int nic_get_led_signal(struct net_device *ndev, struct hns3_lamp_signal *signal)
return -EINVAL; return -EINVAL;
h = hns3_get_handle(ndev); 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); EXPORT_SYMBOL(nic_get_led_signal);
...@@ -221,11 +280,15 @@ int nic_disable_net_lane(struct net_device *ndev) ...@@ -221,11 +280,15 @@ int nic_disable_net_lane(struct net_device *ndev)
return -ENODEV; return -ENODEV;
h = hns3_get_handle(ndev); 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); 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; struct hnae3_handle *h;
...@@ -236,11 +299,16 @@ int nic_get_net_lane_status(struct net_device *ndev, u32 *status) ...@@ -236,11 +299,16 @@ int nic_get_net_lane_status(struct net_device *ndev, u32 *status)
return -EINVAL; return -EINVAL;
h = hns3_get_handle(ndev); 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); 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; struct hnae3_handle *h;
bool en; bool en;
...@@ -250,7 +318,11 @@ int nic_set_mac_state(struct net_device *ndev, int enable) ...@@ -250,7 +318,11 @@ int nic_set_mac_state(struct net_device *ndev, int enable)
h = hns3_get_handle(ndev); h = hns3_get_handle(ndev);
en = !!enable; 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); EXPORT_SYMBOL(nic_set_mac_state);
...@@ -271,7 +343,8 @@ int nic_set_cpu_affinity(struct net_device *netdev, cpumask_t *affinity_mask) ...@@ -271,7 +343,8 @@ int nic_set_cpu_affinity(struct net_device *netdev, cpumask_t *affinity_mask)
priv = netdev_priv(netdev); priv = netdev_priv(netdev);
if (test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) { 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; return -EOPNOTSUPP;
} }
...@@ -284,16 +357,16 @@ int nic_set_cpu_affinity(struct net_device *netdev, cpumask_t *affinity_mask) ...@@ -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); ret = irq_set_affinity_hint(tqp_vector->vector_irq, NULL);
if (ret) { if (ret) {
dev_err(&netdev->dev, "reset affinity hint fail, ret = %d\n", dev_err(&netdev->dev,
ret); "reset affinity hint fail, ret = %d\n", ret);
return ret; return ret;
} }
ret = irq_set_affinity_hint(tqp_vector->vector_irq, ret = irq_set_affinity_hint(tqp_vector->vector_irq,
&tqp_vector->affinity_mask); &tqp_vector->affinity_mask);
if (ret) { if (ret) {
dev_err(&netdev->dev, "set affinity hint fail, ret = %d\n", dev_err(&netdev->dev,
ret); "set affinity hint fail, ret = %d\n", ret);
return ret; return ret;
} }
} }
...@@ -308,12 +381,151 @@ EXPORT_SYMBOL(nic_set_cpu_affinity); ...@@ -308,12 +381,151 @@ EXPORT_SYMBOL(nic_set_cpu_affinity);
int nic_disable_clock(struct net_device *ndev) int nic_disable_clock(struct net_device *ndev)
{ {
struct hnae3_handle *h; struct hnae3_handle *h;
u32 en;
if (nic_netdev_match_check(ndev)) if (nic_netdev_match_check(ndev))
return -ENODEV; return -ENODEV;
en = 0;
h = hns3_get_handle(ndev); 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); 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 @@ ...@@ -4,32 +4,91 @@
#ifndef __HNS3_EXT_H #ifndef __HNS3_EXT_H
#define __HNS3_EXT_H #define __HNS3_EXT_H
#include <linux/types.h> #include <linux/types.h>
#include "../hns3_enet.h" #include "hns3_enet.h"
#include "hns3pf/hclge_ext.h" #include "hnae3.h"
#include "hns3pf/hclge_main_it.h" #include "hclge_main_it.h"
/** enum hns3_ext_op_code {
* nic_chip_recover_handler - reset net device by port id HNS3_EXT_OPC_CLEAN_STATS64 = 0,
* @netdev: net device HNS3_EXT_OPC_GET_CHIPID,
* @hnae3_reset_type: nic device event type HNS3_EXT_OPC_GET_SFPINFO,
*/ HNS3_EXT_OPC_SET_SFP_STATE,
void nic_chip_recover_handler(struct net_device *netdev, HNS3_EXT_OPC_GET_CHIP_NUM,
enum hnae3_reset_type_custom event_t); 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_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, int nic_clean_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *stats); 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_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_set_led(struct net_device *ndev, int type, int status);
int nic_disable_net_lane(struct net_device *ndev); 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_set_cpu_affinity(struct net_device *netdev, cpumask_t *affinity_mask);
int nic_get_led_signal(struct net_device *ndev, int nic_set_mac_state(struct net_device *ndev, int enable);
struct hns3_lamp_signal *signal);
int nic_set_mac_state(struct net_device *ndev, int enable);
int nic_disable_clock(struct net_device *ndev); 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 #endif
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2016-2017 Hisilicon Limited. // Copyright (c) 2016-2017 Hisilicon Limited.
#include "../../hns3pf/hclge_cmd.h" #include "hclge_cmd.h"
#include "../../hnae3.h" #include "hnae3.h"
#include "../../hns3pf/hclge_main.h" #include "hclge_main.h"
#ifdef CONFIG_HNS3_TEST #ifdef CONFIG_HNS3_TEST
#include "hclge_test.h" #include "hclge_test.h"
...@@ -12,4 +12,3 @@ EXPORT_SYMBOL(hclge_cmd_reuse_desc); ...@@ -12,4 +12,3 @@ EXPORT_SYMBOL(hclge_cmd_reuse_desc);
EXPORT_SYMBOL(hclge_cmd_setup_basic_desc); EXPORT_SYMBOL(hclge_cmd_setup_basic_desc);
EXPORT_SYMBOL(hclge_cmd_send); EXPORT_SYMBOL(hclge_cmd_send);
#endif #endif
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#ifndef __HCLGE_EXT_H #ifndef __HCLGE_EXT_H
#define __HCLGE_EXT_H #define __HCLGE_EXT_H
#include <linux/types.h> #include <linux/types.h>
#include "../../hnae3.h" #include "hnae3.h"
#define HCLGE_SFP_INFO_LEN 6 #define HCLGE_SFP_INFO_LEN 6
#define HCLGE_SFP_INFO_SIZE 140 #define HCLGE_SFP_INFO_SIZE 140
...@@ -16,64 +16,111 @@ struct hclge_chip_id_cmd { ...@@ -16,64 +16,111 @@ struct hclge_chip_id_cmd {
u32 rsv[5]; u32 rsv[5];
}; };
struct hclge_commit_id_cmd { struct hclge_sfp_info_para {
u8 commit_id[8]; u8 *buff;
u32 ncl_version; u16 offset;
u32 rsv[3]; u16 size;
u16 *outlen;
}; };
struct hclge_sfp_info { struct hclge_sfp_info {
u32 sfpinfo[6]; 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 { struct hclge_sfp_enable_cmd {
u32 set_sfp_enable_flag; u32 set_sfp_enable_flag;
u32 rsv[5]; u32 rsv[5];
}; };
struct hclge_sfp_present_cmd { struct hclge_sfp_present_cmd {
u32 sfp_present; u32 sfp_present;
u32 rsv[5]; u32 rsv[5];
}; };
struct hns3_lamp_signal { struct hclge_lamp_signal {
u8 error; u8 error;
u8 locate; u8 locate;
u8 activity; 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 { enum hclge_ext_opcode_type {
/* misc command */ /* misc command */
HCLGE_OPC_CHIP_ID_GET = 0x7003, HCLGE_OPC_CHIP_ID_GET = 0x7003,
HCLGE_OPC_IMP_COMMIT_ID_GET = 0x7004, HCLGE_OPC_IMP_COMMIT_ID_GET = 0x7004,
HCLGE_OPC_GET_CHIP_NUM = 0x7005, HCLGE_OPC_GET_CHIP_NUM = 0x7005,
HCLGE_OPC_GET_PORT_NUM = 0x7006, HCLGE_OPC_GET_PORT_NUM = 0x7006,
HCLGE_OPC_SET_LED = 0x7007, HCLGE_OPC_SET_LED = 0x7007,
HCLGE_OPC_DISABLE_NET_LANE = 0x7008, HCLGE_OPC_DISABLE_NET_LANE = 0x7008,
/*SFP command*/ HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019,
HCLGE_OPC_SFP_GET_INFO = 0x7100, HCLGE_OPC_CFG_GET_HILINK_REF_LOS = 0x701B,
HCLGE_OPC_SFP_GET_PRESENT = 0x7101, /*SFP command */
HCLGE_OPC_SFP_SET_STATUS = 0x7102, 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_ext_ops_handle(struct hnae3_handle *handle, int opcode,
int hclge_get_chipid(struct hnae3_handle *handle, u32 *chip_id); void *data, int length);
int hclge_get_commit_id(struct hnae3_handle *handle, u8 *commit_id, void hclge_reset_task_schedule_it(struct hclge_dev *hdev);
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 #endif
...@@ -13,20 +13,17 @@ ...@@ -13,20 +13,17 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <net/rtnetlink.h> #include <net/rtnetlink.h>
#include "../../kcompat.h" #include "kcompat.h"
#include "../../hns3pf/hclge_cmd.h" #include "hclge_cmd.h"
#include "../../hns3pf/hclge_main.h" #include "hclge_main.h"
#include "../../hnae3.h" #include "hnae3.h"
#include "hclge_ext.h" #include "hclge_ext.h"
#include "hclge_main_it.h" #include "hclge_main_it.h"
#include "../../hns3pf/hclge_err.h"
#ifdef CONFIG_HNS3_TEST #ifdef CONFIG_HNS3_TEST
#include "hclge_test.h" #include "hclge_test.h"
#endif #endif
#ifdef CONFIG_EXT_TEST
#define HCLGE_RESET_MAX_FAIL_CNT 1 #define HCLGE_RESET_MAX_FAIL_CNT 1
static nic_event_fn_t nic_event_call; static nic_event_fn_t nic_event_call;
...@@ -53,90 +50,125 @@ int nic_unregister_event(void) ...@@ -53,90 +50,125 @@ int nic_unregister_event(void)
EXPORT_SYMBOL(nic_unregister_event); EXPORT_SYMBOL(nic_unregister_event);
void nic_call_event(struct net_device *netdev, 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); nic_event_call(netdev, event_t);
netdev_info(netdev, "report event %d\n", event_t);
netdev_info(netdev, "report reset event %d\n", event_t); }
} }
EXPORT_SYMBOL(nic_call_event); 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_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
struct net_device *netdev; struct net_device *netdev;
u32 reg_val;
netdev = hdev->vport[0].nic.netdev; netdev = hdev->vport[0].nic.netdev;
if (done) { if (test_and_clear_bit(HCLGE_IMP_RD_POISON, &hdev->imp_err_state)) {
dev_info(&hdev->pdev->dev, "Report Reset DONE!\n"); dev_err(&hdev->pdev->dev, "Detected IMP RD poison!\n");
nic_call_event(netdev, HNAE3_RESET_DONE_CUSTOM); 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) { if (test_and_clear_bit(HCLGE_IMP_CMDQ_ERROR, &hdev->imp_err_state)) {
dev_err(&hdev->pdev->dev, "Report Reset fail!\n"); dev_err(&hdev->pdev->dev, "Detected CMDQ ECC error!\n");
nic_call_event(netdev, HNAE3_PORT_FAULT); 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 hclge_dev *hdev = ae_dev->priv;
struct device *dev = &hdev->pdev->dev;
enum hnae3_reset_type_custom reset_type;
struct net_device *netdev; struct net_device *netdev;
u32 status;
netdev = hdev->vport[0].nic.netdev; netdev = hdev->vport[0].nic.netdev;
status = hclge_read_dev(&hdev->hw, HCLGE_RAS_PF_OTHER_INT_STS_REG); /* We might end up getting called broadly because of 2 below cases:
* 1. Recoverable error was conveyed through APEI and only way to bring
if (status & HCLGE_RAS_REG_NFE_MASK || * normalcy is to reset.
status & HCLGE_RAS_REG_ROCEE_ERR_MASK) * 2. A new reset request from the stack due to timeout
ae_dev->hw_err_reset_req = 0; *
* For the first case,error event might not have ae handle available.
/* Handling Non-fatal HNS RAS errors */ * check if this is a new reset request and we are not here just because
if (status & HCLGE_RAS_REG_NFE_MASK) { * last reset attempt did not succeed and watchdog hit us again. We will
dev_warn(dev, * know this if last reset request did not occur very recently (watchdog
"HNS Non-Fatal RAS error(status=0x%x) identified\n", * timer = 5*HZ, let us check after sufficiently large time, say 4*5*Hz)
status); * In case of new request we reset the "reset level" to PF reset.
hclge_handle_all_ras_errors(hdev); * 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
reset_type = ae_dev->ops->set_default_reset_request(ae_dev, * not allow it again before 12*HZ times.
&ae_dev->hw_err_reset_req); */
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) if (nic_event_call) {
nic_call_event(netdev, reset_type); nic_call_event(netdev, hdev->reset_level);
} else { } else {
if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) || /* request reset & schedule reset task */
hdev->pdev->revision < 0x21) { set_bit(hdev->reset_level, &hdev->reset_request);
ae_dev->override_pci_need_reset = 1; hclge_reset_task_schedule_it(hdev);
return PCI_ERS_RESULT_RECOVERED;
}
} }
}
if (status & HCLGE_RAS_REG_ROCEE_ERR_MASK) { bool hclge_reset_done_it(struct hnae3_handle *handle, bool done)
dev_warn(dev, "ROCEE uncorrected RAS error identified\n"); {
hclge_handle_rocee_ras_error(ae_dev); 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 || if (hdev->reset_fail_cnt >= HCLGE_RESET_MAX_FAIL_CNT) {
status & HCLGE_RAS_REG_ROCEE_ERR_MASK) && dev_err(&hdev->pdev->dev, "Report Reset fail!\n");
ae_dev->hw_err_reset_req) { if (nic_event_call) {
ae_dev->override_pci_need_reset = 0; if (hdev->reset_type == HNAE3_FUNC_RESET)
return PCI_ERS_RESULT_NEED_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 #ifdef CONFIG_IT_VALIDATION
#define HCLGE_NAME_IT "hclge" #define HCLGE_NAME_IT "hclge"
...@@ -145,39 +177,21 @@ EXPORT_SYMBOL(hclge_get_vport); ...@@ -145,39 +177,21 @@ EXPORT_SYMBOL(hclge_get_vport);
EXPORT_SYMBOL(hclge_cmd_set_promisc_mode); EXPORT_SYMBOL(hclge_cmd_set_promisc_mode);
EXPORT_SYMBOL(hclge_promisc_param_init); 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) int hclge_init_it(void)
{ {
pr_info("%s is initializing\n", HCLGE_NAME_IT); pr_info("%s is initializing\n", HCLGE_NAME_IT);
#ifdef CONFIG_HNS3_TEST #ifdef CONFIG_HNS3_TEST
hclge_ops.send_cmdq = hclge_send_cmdq; hclge_ops.send_cmdq = hclge_send_cmdq;
hclge_ops.priv_ops = hclge_ext_ops_handle;
#endif #endif
#ifdef CONFIG_EXT_TEST hclge_ops.reset_event = hclge_reset_event_it;
hclge_ops.handle_hw_ras_error = hclge_handle_hw_ras_error_it;
hclge_ops.reset_done = hclge_reset_done_it; hclge_ops.reset_done = hclge_reset_done_it;
#endif hclge_ops.handle_imp_error = hclge_handle_imp_error_it;
ae_algo.pdev_id_table = ae_algo_pci_tbl_it;
hnae3_register_ae_algo(&ae_algo); hnae3_register_ae_algo(&ae_algo);
return 0; return 0;
} }
module_init(hclge_init_it); module_init(hclge_init_it);
#endif #endif
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
extern struct hnae3_ae_algo ae_algo; extern struct hnae3_ae_algo ae_algo;
extern struct hnae3_ae_ops hclge_ops; extern struct hnae3_ae_ops hclge_ops;
enum hnae3_reset_type_custom { enum hnae3_event_type_custom {
HNAE3_VF_RESET_CUSTOM, HNAE3_VF_RESET_CUSTOM,
HNAE3_VF_FUNC_RESET_CUSTOM, HNAE3_VF_FUNC_RESET_CUSTOM,
HNAE3_VF_PF_FUNC_RESET_CUSTOM, HNAE3_VF_PF_FUNC_RESET_CUSTOM,
...@@ -20,17 +20,20 @@ enum hnae3_reset_type_custom { ...@@ -20,17 +20,20 @@ enum hnae3_reset_type_custom {
HNAE3_NONE_RESET_CUSTOM, HNAE3_NONE_RESET_CUSTOM,
HNAE3_PORT_FAULT, HNAE3_PORT_FAULT,
HNAE3_RESET_DONE_CUSTOM, 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 * nic_event_fn_t - nic event handler prototype
* @netdev: net device * @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, 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 * nic_register_event - register for nic event listening
...@@ -46,7 +49,5 @@ int nic_register_event(nic_event_fn_t event_call); ...@@ -46,7 +49,5 @@ int nic_register_event(nic_event_fn_t event_call);
int nic_unregister_event(void); int nic_unregister_event(void);
void nic_call_event(struct net_device *netdev, void nic_call_event(struct net_device *netdev,
enum hnae3_reset_type_custom event_t); enum hnae3_event_type_custom event_t);
#endif
#endif #endif
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
#ifndef __HCLGE_TEST_H #ifndef __HCLGE_TEST_H
#define __HCLGE_TEST_H #define __HCLGE_TEST_H
#include "../../hns3pf/hclge_cmd.h" #include "hclge_cmd.h"
#include "../../hns3pf/hclge_main.h" #include "hclge_main.h"
int hclge_send_cmdq(struct hnae3_handle *handle, void *data, int num); 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.
先完成此消息的编辑!
想要评论请 注册