Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,136 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2016-2017 Hisilicon Limited. */
#ifndef __HCLGEVF_CMD_H
#define __HCLGEVF_CMD_H
#include <linux/io.h>
#include <linux/types.h>
#include "hnae3.h"
#include "hclge_comm_cmd.h"
#define HCLGEVF_CMDQ_RX_INVLD_B 0
#define HCLGEVF_CMDQ_RX_OUTVLD_B 1
struct hclgevf_hw;
struct hclgevf_dev;
#define HCLGEVF_SYNC_RX_RING_HEAD_EN_B 4
#define HCLGEVF_TQP_REG_OFFSET 0x80000
#define HCLGEVF_TQP_REG_SIZE 0x200
#define HCLGEVF_TQP_MAX_SIZE_DEV_V2 1024
#define HCLGEVF_TQP_EXT_REG_OFFSET 0x100
struct hclgevf_tqp_map {
__le16 tqp_id; /* Absolute tqp id for in this pf */
u8 tqp_vf; /* VF id */
#define HCLGEVF_TQP_MAP_TYPE_PF 0
#define HCLGEVF_TQP_MAP_TYPE_VF 1
#define HCLGEVF_TQP_MAP_TYPE_B 0
#define HCLGEVF_TQP_MAP_EN_B 1
u8 tqp_flag; /* Indicate it's pf or vf tqp */
__le16 tqp_vid; /* Virtual id in this pf/vf */
u8 rsv[18];
};
#define HCLGEVF_VECTOR_ELEMENTS_PER_CMD 10
enum hclgevf_int_type {
HCLGEVF_INT_TX = 0,
HCLGEVF_INT_RX,
HCLGEVF_INT_EVENT,
};
struct hclgevf_ctrl_vector_chain {
u8 int_vector_id;
u8 int_cause_num;
#define HCLGEVF_INT_TYPE_S 0
#define HCLGEVF_INT_TYPE_M 0x3
#define HCLGEVF_TQP_ID_S 2
#define HCLGEVF_TQP_ID_M (0x3fff << HCLGEVF_TQP_ID_S)
__le16 tqp_type_and_id[HCLGEVF_VECTOR_ELEMENTS_PER_CMD];
u8 vfid;
u8 resv;
};
#define HCLGEVF_MSIX_OFT_ROCEE_S 0
#define HCLGEVF_MSIX_OFT_ROCEE_M (0xffff << HCLGEVF_MSIX_OFT_ROCEE_S)
#define HCLGEVF_VEC_NUM_S 0
#define HCLGEVF_VEC_NUM_M (0xff << HCLGEVF_VEC_NUM_S)
struct hclgevf_query_res_cmd {
__le16 tqp_num;
__le16 reserved;
__le16 msixcap_localid_ba_nic;
__le16 msixcap_localid_ba_rocee;
__le16 vf_intr_vector_number;
__le16 rsv[7];
};
#define HCLGEVF_GRO_EN_B 0
struct hclgevf_cfg_gro_status_cmd {
u8 gro_en;
u8 rsv[23];
};
#define HCLGEVF_LINK_STS_B 0
#define HCLGEVF_LINK_STATUS BIT(HCLGEVF_LINK_STS_B)
struct hclgevf_link_status_cmd {
u8 status;
u8 rsv[23];
};
#define HCLGEVF_RING_ID_MASK 0x3ff
#define HCLGEVF_TQP_ENABLE_B 0
struct hclgevf_cfg_com_tqp_queue_cmd {
__le16 tqp_id;
__le16 stream_id;
u8 enable;
u8 rsv[19];
};
struct hclgevf_cfg_tx_queue_pointer_cmd {
__le16 tqp_id;
__le16 tx_tail;
__le16 tx_head;
__le16 fbd_num;
__le16 ring_offset;
u8 rsv[14];
};
/* this bit indicates that the driver is ready for hardware reset */
#define HCLGEVF_NIC_SW_RST_RDY_B 16
#define HCLGEVF_NIC_SW_RST_RDY BIT(HCLGEVF_NIC_SW_RST_RDY_B)
#define HCLGEVF_NIC_CMQ_DESC_NUM 1024
#define HCLGEVF_NIC_CMQ_DESC_NUM_S 3
#define HCLGEVF_QUERY_DEV_SPECS_BD_NUM 4
#define hclgevf_cmd_setup_basic_desc(desc, opcode, is_read) \
hclge_comm_cmd_setup_basic_desc(desc, opcode, is_read)
struct hclgevf_dev_specs_0_cmd {
__le32 rsv0;
__le32 mac_entry_num;
__le32 mng_entry_num;
__le16 rss_ind_tbl_size;
__le16 rss_key_size;
__le16 int_ql_max;
u8 max_non_tso_bd_num;
u8 rsv1[5];
};
#define HCLGEVF_DEF_MAX_INT_GL 0x1FE0U
struct hclgevf_dev_specs_1_cmd {
__le16 max_frm_size;
__le16 rsv0;
__le16 max_int_gl;
u8 rsv1[18];
};
int hclgevf_cmd_send(struct hclgevf_hw *hw, struct hclge_desc *desc, int num);
void hclgevf_arq_init(struct hclgevf_dev *hdev);
#endif
@@ -0,0 +1,130 @@
// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) 2021 Hisilicon Limited. */
#include <net/devlink.h>
#include "hclgevf_devlink.h"
static int hclgevf_devlink_info_get(struct devlink *devlink,
struct devlink_info_req *req,
struct netlink_ext_ack *extack)
{
#define HCLGEVF_DEVLINK_FW_STRING_LEN 32
struct hclgevf_devlink_priv *priv = devlink_priv(devlink);
char version_str[HCLGEVF_DEVLINK_FW_STRING_LEN];
struct hclgevf_dev *hdev = priv->hdev;
snprintf(version_str, sizeof(version_str), "%lu.%lu.%lu.%lu",
hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE3_MASK,
HNAE3_FW_VERSION_BYTE3_SHIFT),
hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE2_MASK,
HNAE3_FW_VERSION_BYTE2_SHIFT),
hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE1_MASK,
HNAE3_FW_VERSION_BYTE1_SHIFT),
hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK,
HNAE3_FW_VERSION_BYTE0_SHIFT));
return devlink_info_version_running_put(req,
DEVLINK_INFO_VERSION_GENERIC_FW,
version_str);
}
static int hclgevf_devlink_reload_down(struct devlink *devlink,
bool netns_change,
enum devlink_reload_action action,
enum devlink_reload_limit limit,
struct netlink_ext_ack *extack)
{
struct hclgevf_devlink_priv *priv = devlink_priv(devlink);
struct hclgevf_dev *hdev = priv->hdev;
struct hnae3_handle *h = &hdev->nic;
struct pci_dev *pdev = hdev->pdev;
int ret;
if (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) {
dev_err(&pdev->dev, "reset is handling\n");
return -EBUSY;
}
switch (action) {
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
rtnl_lock();
ret = hdev->nic_client->ops->reset_notify(h, HNAE3_DOWN_CLIENT);
if (ret) {
rtnl_unlock();
return ret;
}
ret = hdev->nic_client->ops->reset_notify(h,
HNAE3_UNINIT_CLIENT);
rtnl_unlock();
return ret;
default:
return -EOPNOTSUPP;
}
}
static int hclgevf_devlink_reload_up(struct devlink *devlink,
enum devlink_reload_action action,
enum devlink_reload_limit limit,
u32 *actions_performed,
struct netlink_ext_ack *extack)
{
struct hclgevf_devlink_priv *priv = devlink_priv(devlink);
struct hclgevf_dev *hdev = priv->hdev;
struct hnae3_handle *h = &hdev->nic;
int ret;
*actions_performed = BIT(action);
switch (action) {
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
rtnl_lock();
ret = hdev->nic_client->ops->reset_notify(h, HNAE3_INIT_CLIENT);
if (ret) {
rtnl_unlock();
return ret;
}
ret = hdev->nic_client->ops->reset_notify(h, HNAE3_UP_CLIENT);
rtnl_unlock();
return ret;
default:
return -EOPNOTSUPP;
}
}
static const struct devlink_ops hclgevf_devlink_ops = {
.info_get = hclgevf_devlink_info_get,
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
.reload_down = hclgevf_devlink_reload_down,
.reload_up = hclgevf_devlink_reload_up,
};
int hclgevf_devlink_init(struct hclgevf_dev *hdev)
{
struct pci_dev *pdev = hdev->pdev;
struct hclgevf_devlink_priv *priv;
struct devlink *devlink;
devlink =
devlink_alloc(&hclgevf_devlink_ops,
sizeof(struct hclgevf_devlink_priv), &pdev->dev);
if (!devlink)
return -ENOMEM;
priv = devlink_priv(devlink);
priv->hdev = hdev;
hdev->devlink = devlink;
devlink_register(devlink);
return 0;
}
void hclgevf_devlink_uninit(struct hclgevf_dev *hdev)
{
struct devlink *devlink = hdev->devlink;
devlink_unregister(devlink);
devlink_free(devlink);
}
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2021 Hisilicon Limited. */
#ifndef __HCLGEVF_DEVLINK_H
#define __HCLGEVF_DEVLINK_H
#include "hclgevf_main.h"
struct hclgevf_devlink_priv {
struct hclgevf_dev *hdev;
};
int hclgevf_devlink_init(struct hclgevf_dev *hdev);
void hclgevf_devlink_uninit(struct hclgevf_dev *hdev);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,300 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2016-2017 Hisilicon Limited. */
#ifndef __HCLGEVF_MAIN_H
#define __HCLGEVF_MAIN_H
#include <linux/fs.h>
#include <linux/if_vlan.h>
#include <linux/types.h>
#include <net/devlink.h>
#include "hclge_mbx.h"
#include "hclgevf_cmd.h"
#include "hnae3.h"
#include "hclge_comm_rss.h"
#include "hclge_comm_tqp_stats.h"
#define HCLGEVF_MOD_VERSION "1.0"
#define HCLGEVF_DRIVER_NAME "hclgevf"
#define HCLGEVF_MAX_VLAN_ID 4095
#define HCLGEVF_MISC_VECTOR_NUM 0
#define HCLGEVF_INVALID_VPORT 0xffff
#define HCLGEVF_GENERAL_TASK_INTERVAL 5
#define HCLGEVF_KEEP_ALIVE_TASK_INTERVAL 2
/* This number in actual depends upon the total number of VFs
* created by physical function. But the maximum number of
* possible vector-per-VF is {VFn(1-32), VECTn(32 + 1)}.
*/
#define HCLGEVF_MAX_VF_VECTOR_NUM (32 + 1)
#define HCLGEVF_VECTOR_REG_BASE 0x20000
#define HCLGEVF_MISC_VECTOR_REG_BASE 0x20400
#define HCLGEVF_VECTOR_REG_OFFSET 0x4
#define HCLGEVF_VECTOR_VF_OFFSET 0x100000
/* bar registers for common func */
#define HCLGEVF_GRO_EN_REG 0x28000
#define HCLGEVF_RXD_ADV_LAYOUT_EN_REG 0x28008
/* bar registers for rcb */
#define HCLGEVF_RING_RX_ADDR_L_REG 0x80000
#define HCLGEVF_RING_RX_ADDR_H_REG 0x80004
#define HCLGEVF_RING_RX_BD_NUM_REG 0x80008
#define HCLGEVF_RING_RX_BD_LENGTH_REG 0x8000C
#define HCLGEVF_RING_RX_MERGE_EN_REG 0x80014
#define HCLGEVF_RING_RX_TAIL_REG 0x80018
#define HCLGEVF_RING_RX_HEAD_REG 0x8001C
#define HCLGEVF_RING_RX_FBD_NUM_REG 0x80020
#define HCLGEVF_RING_RX_OFFSET_REG 0x80024
#define HCLGEVF_RING_RX_FBD_OFFSET_REG 0x80028
#define HCLGEVF_RING_RX_STASH_REG 0x80030
#define HCLGEVF_RING_RX_BD_ERR_REG 0x80034
#define HCLGEVF_RING_TX_ADDR_L_REG 0x80040
#define HCLGEVF_RING_TX_ADDR_H_REG 0x80044
#define HCLGEVF_RING_TX_BD_NUM_REG 0x80048
#define HCLGEVF_RING_TX_PRIORITY_REG 0x8004C
#define HCLGEVF_RING_TX_TC_REG 0x80050
#define HCLGEVF_RING_TX_MERGE_EN_REG 0x80054
#define HCLGEVF_RING_TX_TAIL_REG 0x80058
#define HCLGEVF_RING_TX_HEAD_REG 0x8005C
#define HCLGEVF_RING_TX_FBD_NUM_REG 0x80060
#define HCLGEVF_RING_TX_OFFSET_REG 0x80064
#define HCLGEVF_RING_TX_EBD_NUM_REG 0x80068
#define HCLGEVF_RING_TX_EBD_OFFSET_REG 0x80070
#define HCLGEVF_RING_TX_BD_ERR_REG 0x80074
#define HCLGEVF_RING_EN_REG 0x80090
/* bar registers for tqp interrupt */
#define HCLGEVF_TQP_INTR_CTRL_REG 0x20000
#define HCLGEVF_TQP_INTR_GL0_REG 0x20100
#define HCLGEVF_TQP_INTR_GL1_REG 0x20200
#define HCLGEVF_TQP_INTR_GL2_REG 0x20300
#define HCLGEVF_TQP_INTR_RL_REG 0x20900
/* CMDQ register bits for RX event(=MBX event) */
#define HCLGEVF_VECTOR0_RX_CMDQ_INT_B 1
/* RST register bits for RESET event */
#define HCLGEVF_VECTOR0_RST_INT_B 2
#define HCLGEVF_TQP_RESET_TRY_TIMES 10
/* Reset related Registers */
#define HCLGEVF_RST_ING 0x20C00
#define HCLGEVF_FUN_RST_ING_BIT BIT(0)
#define HCLGEVF_GLOBAL_RST_ING_BIT BIT(5)
#define HCLGEVF_CORE_RST_ING_BIT BIT(6)
#define HCLGEVF_IMP_RST_ING_BIT BIT(7)
#define HCLGEVF_RST_ING_BITS \
(HCLGEVF_FUN_RST_ING_BIT | HCLGEVF_GLOBAL_RST_ING_BIT | \
HCLGEVF_CORE_RST_ING_BIT | HCLGEVF_IMP_RST_ING_BIT)
#define HCLGEVF_VF_RST_ING 0x07008
#define HCLGEVF_VF_RST_ING_BIT BIT(16)
#define HCLGEVF_WAIT_RESET_DONE 100
#define HCLGEVF_RSS_IND_TBL_SIZE 512
#define HCLGEVF_TQP_MEM_SIZE 0x10000
#define HCLGEVF_MEM_BAR 4
/* in the bar4, the first half is for roce, and the second half is for nic */
#define HCLGEVF_NIC_MEM_OFFSET(hdev) \
(pci_resource_len((hdev)->pdev, HCLGEVF_MEM_BAR) >> 1)
#define HCLGEVF_TQP_MEM_OFFSET(hdev, i) \
(HCLGEVF_NIC_MEM_OFFSET(hdev) + HCLGEVF_TQP_MEM_SIZE * (i))
#define HCLGEVF_MAC_MAX_FRAME 9728
#define HCLGEVF_STATS_TIMER_INTERVAL 36U
#define hclgevf_read_dev(a, reg) \
hclge_comm_read_reg((a)->hw.io_base, reg)
#define hclgevf_write_dev(a, reg, value) \
hclge_comm_write_reg((a)->hw.io_base, reg, value)
enum hclgevf_evt_cause {
HCLGEVF_VECTOR0_EVENT_RST,
HCLGEVF_VECTOR0_EVENT_MBX,
HCLGEVF_VECTOR0_EVENT_OTHER,
};
/* states of hclgevf device & tasks */
enum hclgevf_states {
/* device states */
HCLGEVF_STATE_DOWN,
HCLGEVF_STATE_DISABLED,
HCLGEVF_STATE_IRQ_INITED,
HCLGEVF_STATE_REMOVING,
HCLGEVF_STATE_NIC_REGISTERED,
HCLGEVF_STATE_ROCE_REGISTERED,
HCLGEVF_STATE_SERVICE_INITED,
/* task states */
HCLGEVF_STATE_RST_SERVICE_SCHED,
HCLGEVF_STATE_RST_HANDLING,
HCLGEVF_STATE_MBX_SERVICE_SCHED,
HCLGEVF_STATE_MBX_HANDLING,
HCLGEVF_STATE_LINK_UPDATING,
HCLGEVF_STATE_PROMISC_CHANGED,
HCLGEVF_STATE_RST_FAIL,
HCLGEVF_STATE_PF_PUSH_LINK_STATUS,
};
struct hclgevf_mac {
u8 media_type;
u8 module_type;
u8 mac_addr[ETH_ALEN];
int link;
u8 duplex;
u32 speed;
u64 supported;
u64 advertising;
};
struct hclgevf_hw {
struct hclge_comm_hw hw;
int num_vec;
struct hclgevf_mac mac;
};
struct hclgevf_cfg {
u8 tc_num;
u16 tqp_desc_num;
u16 rx_buf_len;
u8 phy_addr;
u8 media_type;
u8 mac_addr[ETH_ALEN];
u32 numa_node_map;
};
struct hclgevf_misc_vector {
u8 __iomem *addr;
int vector_irq;
char name[HNAE3_INT_NAME_LEN];
};
struct hclgevf_rst_stats {
u32 rst_cnt; /* the number of reset */
u32 vf_func_rst_cnt; /* the number of VF function reset */
u32 flr_rst_cnt; /* the number of FLR */
u32 vf_rst_cnt; /* the number of VF reset */
u32 rst_done_cnt; /* the number of reset completed */
u32 hw_rst_done_cnt; /* the number of HW reset completed */
u32 rst_fail_cnt; /* the number of VF reset fail */
};
enum HCLGEVF_MAC_ADDR_TYPE {
HCLGEVF_MAC_ADDR_UC,
HCLGEVF_MAC_ADDR_MC
};
enum HCLGEVF_MAC_NODE_STATE {
HCLGEVF_MAC_TO_ADD,
HCLGEVF_MAC_TO_DEL,
HCLGEVF_MAC_ACTIVE
};
struct hclgevf_mac_addr_node {
struct list_head node;
enum HCLGEVF_MAC_NODE_STATE state;
u8 mac_addr[ETH_ALEN];
};
struct hclgevf_mac_table_cfg {
spinlock_t mac_list_lock; /* protect mac address need to add/detele */
struct list_head uc_mac_list;
struct list_head mc_mac_list;
};
struct hclgevf_dev {
struct pci_dev *pdev;
struct hnae3_ae_dev *ae_dev;
struct hclgevf_hw hw;
struct hclgevf_misc_vector misc_vector;
struct hclge_comm_rss_cfg rss_cfg;
unsigned long state;
unsigned long flr_state;
unsigned long default_reset_request;
unsigned long last_reset_time;
enum hnae3_reset_type reset_level;
unsigned long reset_pending;
enum hnae3_reset_type reset_type;
struct timer_list reset_timer;
#define HCLGEVF_RESET_REQUESTED 0
#define HCLGEVF_RESET_PENDING 1
unsigned long reset_state; /* requested, pending */
struct hclgevf_rst_stats rst_stats;
u32 reset_attempts;
struct semaphore reset_sem; /* protect reset process */
u32 fw_version;
u16 mbx_api_version;
u16 num_tqps; /* num task queue pairs of this VF */
u16 alloc_rss_size; /* allocated RSS task queue */
u16 rss_size_max; /* HW defined max RSS task queue */
u16 num_alloc_vport; /* num vports this driver supports */
nodemask_t numa_node_mask;
u16 rx_buf_len;
u16 num_tx_desc; /* desc num of per tx queue */
u16 num_rx_desc; /* desc num of per rx queue */
u8 hw_tc_map;
u8 has_pf_mac;
u16 num_msi;
u16 num_msi_left;
u16 num_msi_used;
u16 num_nic_msix; /* Num of nic vectors for this VF */
u16 num_roce_msix; /* Num of roce vectors for this VF */
u16 roce_base_msix_offset;
u16 *vector_status;
int *vector_irq;
bool gro_en;
bool rxvtag_strip_en;
unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)];
struct hclgevf_mac_table_cfg mac_table;
struct hclgevf_mbx_resp_status mbx_resp; /* mailbox response */
struct hclgevf_mbx_arq_ring arq; /* mailbox async rx queue */
struct delayed_work service_task;
struct hclge_comm_tqp *htqp;
struct hnae3_handle nic;
struct hnae3_handle roce;
struct hnae3_client *nic_client;
struct hnae3_client *roce_client;
u32 flag;
unsigned long serv_processed_cnt;
unsigned long last_serv_processed;
struct devlink *devlink;
};
static inline bool hclgevf_is_reset_pending(struct hclgevf_dev *hdev)
{
return !!hdev->reset_pending;
}
int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev,
struct hclge_vf_to_pf_msg *send_msg, bool need_resp,
u8 *resp_data, u16 resp_len);
void hclgevf_mbx_handler(struct hclgevf_dev *hdev);
void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev);
void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state);
void hclgevf_update_speed_duplex(struct hclgevf_dev *hdev, u32 speed,
u8 duplex);
void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev);
void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev);
void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,
struct hclge_mbx_port_base_vlan *port_base_vlan);
struct hclgevf_dev *hclgevf_ae_get_hdev(struct hnae3_handle *handle);
#endif
@@ -0,0 +1,388 @@
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2016-2017 Hisilicon Limited.
#include "hclge_mbx.h"
#include "hclgevf_main.h"
#include "hnae3.h"
#define CREATE_TRACE_POINTS
#include "hclgevf_trace.h"
static int hclgevf_resp_to_errno(u16 resp_code)
{
return resp_code ? -resp_code : 0;
}
#define HCLGEVF_MBX_MATCH_ID_START 1
static void hclgevf_reset_mbx_resp_status(struct hclgevf_dev *hdev)
{
/* this function should be called with mbx_resp.mbx_mutex held
* to protect the received_response from race condition
*/
hdev->mbx_resp.received_resp = false;
hdev->mbx_resp.origin_mbx_msg = 0;
hdev->mbx_resp.resp_status = 0;
hdev->mbx_resp.match_id++;
/* Update match_id and ensure the value of match_id is not zero */
if (hdev->mbx_resp.match_id == 0)
hdev->mbx_resp.match_id = HCLGEVF_MBX_MATCH_ID_START;
memset(hdev->mbx_resp.additional_info, 0, HCLGE_MBX_MAX_RESP_DATA_SIZE);
}
/* hclgevf_get_mbx_resp: used to get a response from PF after VF sends a mailbox
* message to PF.
* @hdev: pointer to struct hclgevf_dev
* @code0: the message opcode VF send to PF.
* @code1: the message sub-opcode VF send to PF.
* @resp_data: pointer to store response data from PF to VF.
* @resp_len: the length of resp_data from PF to VF.
*/
static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1,
u8 *resp_data, u16 resp_len)
{
#define HCLGEVF_MAX_TRY_TIMES 500
#define HCLGEVF_SLEEP_USECOND 1000
struct hclgevf_mbx_resp_status *mbx_resp;
u16 r_code0, r_code1;
int i = 0;
if (resp_len > HCLGE_MBX_MAX_RESP_DATA_SIZE) {
dev_err(&hdev->pdev->dev,
"VF mbx response len(=%u) exceeds maximum(=%u)\n",
resp_len,
HCLGE_MBX_MAX_RESP_DATA_SIZE);
return -EINVAL;
}
while ((!hdev->mbx_resp.received_resp) && (i < HCLGEVF_MAX_TRY_TIMES)) {
if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE,
&hdev->hw.hw.comm_state))
return -EIO;
usleep_range(HCLGEVF_SLEEP_USECOND, HCLGEVF_SLEEP_USECOND * 2);
i++;
}
/* ensure additional_info will be seen after received_resp */
smp_rmb();
if (i >= HCLGEVF_MAX_TRY_TIMES) {
dev_err(&hdev->pdev->dev,
"VF could not get mbx(%u,%u) resp(=%d) from PF in %d tries\n",
code0, code1, hdev->mbx_resp.received_resp, i);
return -EIO;
}
mbx_resp = &hdev->mbx_resp;
r_code0 = (u16)(mbx_resp->origin_mbx_msg >> 16);
r_code1 = (u16)(mbx_resp->origin_mbx_msg & 0xff);
if (mbx_resp->resp_status)
return mbx_resp->resp_status;
if (resp_data)
memcpy(resp_data, &mbx_resp->additional_info[0], resp_len);
hclgevf_reset_mbx_resp_status(hdev);
if (!(r_code0 == code0 && r_code1 == code1 && !mbx_resp->resp_status)) {
dev_err(&hdev->pdev->dev,
"VF could not match resp code(code0=%u,code1=%u), %d\n",
code0, code1, mbx_resp->resp_status);
dev_err(&hdev->pdev->dev,
"VF could not match resp r_code(r_code0=%u,r_code1=%u)\n",
r_code0, r_code1);
return -EIO;
}
return 0;
}
int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev,
struct hclge_vf_to_pf_msg *send_msg, bool need_resp,
u8 *resp_data, u16 resp_len)
{
struct hclge_mbx_vf_to_pf_cmd *req;
struct hclge_desc desc;
int status;
req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data;
if (!send_msg) {
dev_err(&hdev->pdev->dev,
"failed to send mbx, msg is NULL\n");
return -EINVAL;
}
hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false);
if (need_resp)
hnae3_set_bit(req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B, 1);
memcpy(&req->msg, send_msg, sizeof(struct hclge_vf_to_pf_msg));
if (test_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state))
trace_hclge_vf_mbx_send(hdev, req);
/* synchronous send */
if (need_resp) {
mutex_lock(&hdev->mbx_resp.mbx_mutex);
hclgevf_reset_mbx_resp_status(hdev);
req->match_id = cpu_to_le16(hdev->mbx_resp.match_id);
status = hclgevf_cmd_send(&hdev->hw, &desc, 1);
if (status) {
dev_err(&hdev->pdev->dev,
"VF failed(=%d) to send mbx message to PF\n",
status);
mutex_unlock(&hdev->mbx_resp.mbx_mutex);
return status;
}
status = hclgevf_get_mbx_resp(hdev, send_msg->code,
send_msg->subcode, resp_data,
resp_len);
mutex_unlock(&hdev->mbx_resp.mbx_mutex);
} else {
/* asynchronous send */
status = hclgevf_cmd_send(&hdev->hw, &desc, 1);
if (status) {
dev_err(&hdev->pdev->dev,
"VF failed(=%d) to send mbx message to PF\n",
status);
return status;
}
}
return status;
}
static bool hclgevf_cmd_crq_empty(struct hclgevf_hw *hw)
{
u32 tail = hclgevf_read_dev(hw, HCLGE_COMM_NIC_CRQ_TAIL_REG);
return tail == (u32)hw->hw.cmq.crq.next_to_use;
}
static void hclgevf_handle_mbx_response(struct hclgevf_dev *hdev,
struct hclge_mbx_pf_to_vf_cmd *req)
{
u16 vf_mbx_msg_subcode = le16_to_cpu(req->msg.vf_mbx_msg_subcode);
u16 vf_mbx_msg_code = le16_to_cpu(req->msg.vf_mbx_msg_code);
struct hclgevf_mbx_resp_status *resp = &hdev->mbx_resp;
u16 resp_status = le16_to_cpu(req->msg.resp_status);
u16 match_id = le16_to_cpu(req->match_id);
if (resp->received_resp)
dev_warn(&hdev->pdev->dev,
"VF mbx resp flag not clear(%u)\n",
vf_mbx_msg_code);
resp->origin_mbx_msg = (vf_mbx_msg_code << 16);
resp->origin_mbx_msg |= vf_mbx_msg_subcode;
resp->resp_status = hclgevf_resp_to_errno(resp_status);
memcpy(resp->additional_info, req->msg.resp_data,
HCLGE_MBX_MAX_RESP_DATA_SIZE * sizeof(u8));
/* ensure additional_info will be seen before setting received_resp */
smp_wmb();
if (match_id) {
/* If match_id is not zero, it means PF support match_id.
* if the match_id is right, VF get the right response, or
* ignore the response. and driver will clear hdev->mbx_resp
* when send next message which need response.
*/
if (match_id == resp->match_id)
resp->received_resp = true;
} else {
resp->received_resp = true;
}
}
static void hclgevf_handle_mbx_msg(struct hclgevf_dev *hdev,
struct hclge_mbx_pf_to_vf_cmd *req)
{
/* we will drop the async msg if we find ARQ as full
* and continue with next message
*/
if (atomic_read(&hdev->arq.count) >=
HCLGE_MBX_MAX_ARQ_MSG_NUM) {
dev_warn(&hdev->pdev->dev,
"Async Q full, dropping msg(%u)\n",
le16_to_cpu(req->msg.code));
return;
}
/* tail the async message in arq */
memcpy(hdev->arq.msg_q[hdev->arq.tail], &req->msg,
HCLGE_MBX_MAX_ARQ_MSG_SIZE * sizeof(u16));
hclge_mbx_tail_ptr_move_arq(hdev->arq);
atomic_inc(&hdev->arq.count);
hclgevf_mbx_task_schedule(hdev);
}
void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
{
struct hclge_mbx_pf_to_vf_cmd *req;
struct hclge_comm_cmq_ring *crq;
struct hclge_desc *desc;
u16 flag;
u16 code;
crq = &hdev->hw.hw.cmq.crq;
while (!hclgevf_cmd_crq_empty(&hdev->hw)) {
if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE,
&hdev->hw.hw.comm_state)) {
dev_info(&hdev->pdev->dev, "vf crq need init\n");
return;
}
desc = &crq->desc[crq->next_to_use];
req = (struct hclge_mbx_pf_to_vf_cmd *)desc->data;
flag = le16_to_cpu(crq->desc[crq->next_to_use].flag);
code = le16_to_cpu(req->msg.code);
if (unlikely(!hnae3_get_bit(flag, HCLGEVF_CMDQ_RX_OUTVLD_B))) {
dev_warn(&hdev->pdev->dev,
"dropped invalid mailbox message, code = %u\n",
code);
/* dropping/not processing this invalid message */
crq->desc[crq->next_to_use].flag = 0;
hclge_mbx_ring_ptr_move_crq(crq);
continue;
}
trace_hclge_vf_mbx_get(hdev, req);
/* synchronous messages are time critical and need preferential
* treatment. Therefore, we need to acknowledge all the sync
* responses as quickly as possible so that waiting tasks do not
* timeout and simultaneously queue the async messages for later
* prcessing in context of mailbox task i.e. the slow path.
*/
switch (code) {
case HCLGE_MBX_PF_VF_RESP:
hclgevf_handle_mbx_response(hdev, req);
break;
case HCLGE_MBX_LINK_STAT_CHANGE:
case HCLGE_MBX_ASSERTING_RESET:
case HCLGE_MBX_LINK_STAT_MODE:
case HCLGE_MBX_PUSH_VLAN_INFO:
case HCLGE_MBX_PUSH_PROMISC_INFO:
hclgevf_handle_mbx_msg(hdev, req);
break;
default:
dev_err(&hdev->pdev->dev,
"VF received unsupported(%u) mbx msg from PF\n",
code);
break;
}
crq->desc[crq->next_to_use].flag = 0;
hclge_mbx_ring_ptr_move_crq(crq);
}
/* Write back CMDQ_RQ header pointer, M7 need this pointer */
hclgevf_write_dev(&hdev->hw, HCLGE_COMM_NIC_CRQ_HEAD_REG,
crq->next_to_use);
}
static void hclgevf_parse_promisc_info(struct hclgevf_dev *hdev,
u16 promisc_info)
{
if (!promisc_info)
dev_info(&hdev->pdev->dev,
"Promisc mode is closed by host for being untrusted.\n");
}
void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
{
struct hclge_mbx_port_base_vlan *vlan_info;
struct hclge_mbx_link_status *link_info;
struct hclge_mbx_link_mode *link_mode;
enum hnae3_reset_type reset_type;
u16 link_status, state;
__le16 *msg_q;
u16 opcode;
u8 duplex;
u32 speed;
u32 tail;
u8 flag;
u16 idx;
tail = hdev->arq.tail;
/* process all the async queue messages */
while (tail != hdev->arq.head) {
if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE,
&hdev->hw.hw.comm_state)) {
dev_info(&hdev->pdev->dev,
"vf crq need init in async\n");
return;
}
msg_q = hdev->arq.msg_q[hdev->arq.head];
opcode = le16_to_cpu(msg_q[0]);
switch (opcode) {
case HCLGE_MBX_LINK_STAT_CHANGE:
link_info = (struct hclge_mbx_link_status *)(msg_q + 1);
link_status = le16_to_cpu(link_info->link_status);
speed = le32_to_cpu(link_info->speed);
duplex = (u8)le16_to_cpu(link_info->duplex);
flag = link_info->flag;
/* update upper layer with new link link status */
hclgevf_update_speed_duplex(hdev, speed, duplex);
hclgevf_update_link_status(hdev, link_status);
if (flag & HCLGE_MBX_PUSH_LINK_STATUS_EN)
set_bit(HCLGEVF_STATE_PF_PUSH_LINK_STATUS,
&hdev->state);
break;
case HCLGE_MBX_LINK_STAT_MODE:
link_mode = (struct hclge_mbx_link_mode *)(msg_q + 1);
idx = le16_to_cpu(link_mode->idx);
if (idx)
hdev->hw.mac.supported =
le64_to_cpu(link_mode->link_mode);
else
hdev->hw.mac.advertising =
le64_to_cpu(link_mode->link_mode);
break;
case HCLGE_MBX_ASSERTING_RESET:
/* PF has asserted reset hence VF should go in pending
* state and poll for the hardware reset status till it
* has been completely reset. After this stack should
* eventually be re-initialized.
*/
reset_type =
(enum hnae3_reset_type)le16_to_cpu(msg_q[1]);
set_bit(reset_type, &hdev->reset_pending);
set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
hclgevf_reset_task_schedule(hdev);
break;
case HCLGE_MBX_PUSH_VLAN_INFO:
vlan_info =
(struct hclge_mbx_port_base_vlan *)(msg_q + 1);
state = le16_to_cpu(vlan_info->state);
hclgevf_update_port_base_vlan_info(hdev, state,
vlan_info);
break;
case HCLGE_MBX_PUSH_PROMISC_INFO:
hclgevf_parse_promisc_info(hdev, le16_to_cpu(msg_q[1]));
break;
default:
dev_err(&hdev->pdev->dev,
"fetched unsupported(%u) message from arq\n",
opcode);
break;
}
hclge_mbx_head_ptr_move_arq(hdev->arq);
atomic_dec(&hdev->arq.count);
msg_q = hdev->arq.msg_q[hdev->arq.head];
}
}
@@ -0,0 +1,166 @@
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2023 Hisilicon Limited.
#include "hclgevf_main.h"
#include "hclgevf_regs.h"
#include "hnae3.h"
static const u32 cmdq_reg_addr_list[] = {HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG,
HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG,
HCLGE_COMM_NIC_CSQ_DEPTH_REG,
HCLGE_COMM_NIC_CSQ_TAIL_REG,
HCLGE_COMM_NIC_CSQ_HEAD_REG,
HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG,
HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG,
HCLGE_COMM_NIC_CRQ_DEPTH_REG,
HCLGE_COMM_NIC_CRQ_TAIL_REG,
HCLGE_COMM_NIC_CRQ_HEAD_REG,
HCLGE_COMM_VECTOR0_CMDQ_SRC_REG,
HCLGE_COMM_VECTOR0_CMDQ_STATE_REG,
HCLGE_COMM_CMDQ_INTR_EN_REG,
HCLGE_COMM_CMDQ_INTR_GEN_REG};
static const u32 common_reg_addr_list[] = {HCLGEVF_MISC_VECTOR_REG_BASE,
HCLGEVF_RST_ING,
HCLGEVF_GRO_EN_REG};
static const u32 ring_reg_addr_list[] = {HCLGEVF_RING_RX_ADDR_L_REG,
HCLGEVF_RING_RX_ADDR_H_REG,
HCLGEVF_RING_RX_BD_NUM_REG,
HCLGEVF_RING_RX_BD_LENGTH_REG,
HCLGEVF_RING_RX_MERGE_EN_REG,
HCLGEVF_RING_RX_TAIL_REG,
HCLGEVF_RING_RX_HEAD_REG,
HCLGEVF_RING_RX_FBD_NUM_REG,
HCLGEVF_RING_RX_OFFSET_REG,
HCLGEVF_RING_RX_FBD_OFFSET_REG,
HCLGEVF_RING_RX_STASH_REG,
HCLGEVF_RING_RX_BD_ERR_REG,
HCLGEVF_RING_TX_ADDR_L_REG,
HCLGEVF_RING_TX_ADDR_H_REG,
HCLGEVF_RING_TX_BD_NUM_REG,
HCLGEVF_RING_TX_PRIORITY_REG,
HCLGEVF_RING_TX_TC_REG,
HCLGEVF_RING_TX_MERGE_EN_REG,
HCLGEVF_RING_TX_TAIL_REG,
HCLGEVF_RING_TX_HEAD_REG,
HCLGEVF_RING_TX_FBD_NUM_REG,
HCLGEVF_RING_TX_OFFSET_REG,
HCLGEVF_RING_TX_EBD_NUM_REG,
HCLGEVF_RING_TX_EBD_OFFSET_REG,
HCLGEVF_RING_TX_BD_ERR_REG,
HCLGEVF_RING_EN_REG};
static const u32 tqp_intr_reg_addr_list[] = {HCLGEVF_TQP_INTR_CTRL_REG,
HCLGEVF_TQP_INTR_GL0_REG,
HCLGEVF_TQP_INTR_GL1_REG,
HCLGEVF_TQP_INTR_GL2_REG,
HCLGEVF_TQP_INTR_RL_REG};
enum hclgevf_reg_tag {
HCLGEVF_REG_TAG_CMDQ = 0,
HCLGEVF_REG_TAG_COMMON,
HCLGEVF_REG_TAG_RING,
HCLGEVF_REG_TAG_TQP_INTR,
};
#pragma pack(4)
struct hclgevf_reg_tlv {
u16 tag;
u16 len;
};
struct hclgevf_reg_header {
u64 magic_number;
u8 is_vf;
u8 rsv[7];
};
#pragma pack()
#define HCLGEVF_REG_TLV_SIZE sizeof(struct hclgevf_reg_tlv)
#define HCLGEVF_REG_HEADER_SIZE sizeof(struct hclgevf_reg_header)
#define HCLGEVF_REG_TLV_SPACE (sizeof(struct hclgevf_reg_tlv) / sizeof(u32))
#define HCLGEVF_REG_HEADER_SPACE (sizeof(struct hclgevf_reg_header) / sizeof(u32))
#define HCLGEVF_REG_MAGIC_NUMBER 0x686e733372656773 /* meaning is hns3regs */
static u32 hclgevf_reg_get_header(void *data)
{
struct hclgevf_reg_header *header = data;
header->magic_number = HCLGEVF_REG_MAGIC_NUMBER;
header->is_vf = 0x1;
return HCLGEVF_REG_HEADER_SPACE;
}
static u32 hclgevf_reg_get_tlv(u32 tag, u32 regs_num, void *data)
{
struct hclgevf_reg_tlv *tlv = data;
tlv->tag = tag;
tlv->len = regs_num * sizeof(u32) + HCLGEVF_REG_TLV_SIZE;
return HCLGEVF_REG_TLV_SPACE;
}
int hclgevf_get_regs_len(struct hnae3_handle *handle)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
int cmdq_len, common_len, ring_len, tqp_intr_len;
cmdq_len = HCLGEVF_REG_TLV_SIZE + sizeof(cmdq_reg_addr_list);
common_len = HCLGEVF_REG_TLV_SIZE + sizeof(common_reg_addr_list);
ring_len = HCLGEVF_REG_TLV_SIZE + sizeof(ring_reg_addr_list);
tqp_intr_len = HCLGEVF_REG_TLV_SIZE + sizeof(tqp_intr_reg_addr_list);
/* return the total length of all register values */
return HCLGEVF_REG_HEADER_SIZE + cmdq_len + common_len +
tqp_intr_len * (hdev->num_msi_used - 1) +
ring_len * hdev->num_tqps;
}
void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
void *data)
{
#define HCLGEVF_RING_INT_REG_OFFSET 0x4
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
struct hnae3_queue *tqp;
int i, j, reg_num;
u32 *reg = data;
*version = hdev->fw_version;
reg += hclgevf_reg_get_header(reg);
/* fetching per-VF registers values from VF PCIe register space */
reg_num = ARRAY_SIZE(cmdq_reg_addr_list);
reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ, reg_num, reg);
for (i = 0; i < reg_num; i++)
*reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]);
reg_num = ARRAY_SIZE(common_reg_addr_list);
reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON, reg_num, reg);
for (i = 0; i < reg_num; i++)
*reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]);
reg_num = ARRAY_SIZE(ring_reg_addr_list);
for (j = 0; j < hdev->num_tqps; j++) {
reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_num, reg);
tqp = &hdev->htqp[j].q;
for (i = 0; i < reg_num; i++)
*reg++ = readl_relaxed(tqp->io_base -
HCLGEVF_TQP_REG_OFFSET +
ring_reg_addr_list[i]);
}
reg_num = ARRAY_SIZE(tqp_intr_reg_addr_list);
for (j = 0; j < hdev->num_msi_used - 1; j++) {
reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR,
reg_num, reg);
for (i = 0; i < reg_num; i++)
*reg++ = hclgevf_read_dev(&hdev->hw,
tqp_intr_reg_addr_list[i] +
HCLGEVF_RING_INT_REG_OFFSET * j);
}
}
@@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2023 Hisilicon Limited. */
#ifndef __HCLGEVF_REGS_H
#define __HCLGEVF_REGS_H
#include <linux/types.h>
struct hnae3_handle;
int hclgevf_get_regs_len(struct hnae3_handle *handle);
void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
void *data);
#endif
@@ -0,0 +1,137 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2018-2019 Hisilicon Limited. */
/* This must be outside ifdef _HCLGEVF_TRACE_H */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM hns3
#if !defined(_HCLGEVF_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
#define _HCLGEVF_TRACE_H_
#include <linux/tracepoint.h>
#define VF_GET_MBX_LEN (sizeof(struct hclge_mbx_pf_to_vf_cmd) / sizeof(u32))
#define VF_SEND_MBX_LEN (sizeof(struct hclge_mbx_vf_to_pf_cmd) / sizeof(u32))
TRACE_EVENT(hclge_vf_mbx_get,
TP_PROTO(
struct hclgevf_dev *hdev,
struct hclge_mbx_pf_to_vf_cmd *req),
TP_ARGS(hdev, req),
TP_STRUCT__entry(
__field(u8, vfid)
__field(u16, code)
__string(pciname, pci_name(hdev->pdev))
__string(devname, hdev->nic.kinfo.netdev->name)
__array(u32, mbx_data, VF_GET_MBX_LEN)
),
TP_fast_assign(
__entry->vfid = req->dest_vfid;
__entry->code = le16_to_cpu(req->msg.code);
__assign_str(pciname);
__assign_str(devname);
memcpy(__entry->mbx_data, req,
sizeof(struct hclge_mbx_pf_to_vf_cmd));
),
TP_printk(
"%s %s vfid:%u code:%u data:%s",
__get_str(pciname), __get_str(devname), __entry->vfid,
__entry->code,
__print_array(__entry->mbx_data, VF_GET_MBX_LEN, sizeof(u32))
)
);
TRACE_EVENT(hclge_vf_mbx_send,
TP_PROTO(
struct hclgevf_dev *hdev,
struct hclge_mbx_vf_to_pf_cmd *req),
TP_ARGS(hdev, req),
TP_STRUCT__entry(
__field(u8, vfid)
__field(u8, code)
__field(u8, subcode)
__string(pciname, pci_name(hdev->pdev))
__string(devname, hdev->nic.kinfo.netdev->name)
__array(u32, mbx_data, VF_SEND_MBX_LEN)
),
TP_fast_assign(
__entry->vfid = req->mbx_src_vfid;
__entry->code = req->msg.code;
__entry->subcode = req->msg.subcode;
__assign_str(pciname);
__assign_str(devname);
memcpy(__entry->mbx_data, req,
sizeof(struct hclge_mbx_vf_to_pf_cmd));
),
TP_printk(
"%s %s vfid:%u code:%u subcode:%u data:%s",
__get_str(pciname), __get_str(devname), __entry->vfid,
__entry->code, __entry->subcode,
__print_array(__entry->mbx_data, VF_SEND_MBX_LEN, sizeof(u32))
)
);
DECLARE_EVENT_CLASS(hclge_vf_cmd_template,
TP_PROTO(struct hclge_comm_hw *hw,
struct hclge_desc *desc,
int index,
int num),
TP_ARGS(hw, desc, index, num),
TP_STRUCT__entry(__field(u16, opcode)
__field(u16, flag)
__field(u16, retval)
__field(u16, rsv)
__field(int, index)
__field(int, num)
__string(pciname, pci_name(hw->cmq.csq.pdev))
__array(u32, data, HCLGE_DESC_DATA_LEN)),
TP_fast_assign(int i;
__entry->opcode = le16_to_cpu(desc->opcode);
__entry->flag = le16_to_cpu(desc->flag);
__entry->retval = le16_to_cpu(desc->retval);
__entry->rsv = le16_to_cpu(desc->rsv);
__entry->index = index;
__entry->num = num;
__assign_str(pciname);
for (i = 0; i < HCLGE_DESC_DATA_LEN; i++)
__entry->data[i] = le32_to_cpu(desc->data[i]);),
TP_printk("%s opcode:0x%04x %d-%d flag:0x%04x retval:0x%04x rsv:0x%04x data:%s",
__get_str(pciname), __entry->opcode,
__entry->index, __entry->num,
__entry->flag, __entry->retval, __entry->rsv,
__print_array(__entry->data,
HCLGE_DESC_DATA_LEN, sizeof(u32)))
);
DEFINE_EVENT(hclge_vf_cmd_template, hclge_vf_cmd_send,
TP_PROTO(struct hclge_comm_hw *hw,
struct hclge_desc *desc,
int index,
int num),
TP_ARGS(hw, desc, index, num));
DEFINE_EVENT(hclge_vf_cmd_template, hclge_vf_cmd_get,
TP_PROTO(struct hclge_comm_hw *hw,
struct hclge_desc *desc,
int index,
int num),
TP_ARGS(hw, desc, index, num));
#endif /* _HCLGEVF_TRACE_H_ */
/* This must be outside ifdef _HCLGEVF_TRACE_H */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE hclgevf_trace
#include <trace/define_trace.h>