2026-01-29 22:25:33 +08:00

371 lines
11 KiB
C

/* SPDX-License-Identifier: GPL-2.0*/
/* Huawei HiNIC PCI Express Linux driver
* Copyright(c) 2017 Huawei Technologies Co., Ltd
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
*/
#ifndef HINIC_HWDEV_H_
#define HINIC_HWDEV_H_
#include "hinic_port_cmd.h"
/* to use 0-level CLA, page size must be: 64B(wqebb) * 4096(max_q_depth) */
#define HINIC_DEFAULT_WQ_PAGE_SIZE 0x40000
#define HINIC_HW_WQ_PAGE_SIZE 0x1000
#define HINIC_MSG_TO_MGMT_MAX_LEN 2016
#define HINIC_MGMT_STATUS_ERR_OK 0 /* Ok */
#define HINIC_MGMT_STATUS_ERR_PARAM 1 /* Invalid parameter */
#define HINIC_MGMT_STATUS_ERR_FAILED 2 /* Operation failed */
#define HINIC_MGMT_STATUS_ERR_PORT 3 /* Invalid port */
#define HINIC_MGMT_STATUS_ERR_TIMEOUT 4 /* Operation time out */
#define HINIC_MGMT_STATUS_ERR_NOMATCH 5 /* Version not match */
#define HINIC_MGMT_STATUS_ERR_EXIST 6 /* Entry exists */
#define HINIC_MGMT_STATUS_ERR_NOMEM 7 /* Out of memory */
#define HINIC_MGMT_STATUS_ERR_INIT 8 /* Feature not initialized */
#define HINIC_MGMT_STATUS_ERR_FAULT 9 /* Invalid address */
#define HINIC_MGMT_STATUS_ERR_PERM 10 /* Operation not permitted */
#define HINIC_MGMT_STATUS_ERR_EMPTY 11 /* Table empty */
#define HINIC_MGMT_STATUS_ERR_FULL 12 /* Table full */
#define HINIC_MGMT_STATUS_ERR_NOT_FOUND 13 /* Not found */
#define HINIC_MGMT_STATUS_ERR_BUSY 14 /* Device or resource busy */
#define HINIC_MGMT_STATUS_ERR_RESOURCE 15 /* No resources for operation */
#define HINIC_MGMT_STATUS_ERR_CONFIG 16 /* Invalid configuration */
#define HINIC_MGMT_STATUS_ERR_UNAVAIL 17 /* Feature unavailable */
#define HINIC_MGMT_STATUS_ERR_CRC 18 /* CRC check failed */
#define HINIC_MGMT_STATUS_ERR_NXIO 19 /* No such device or address */
#define HINIC_MGMT_STATUS_ERR_ROLLBACK 20 /* Chip rollback fail */
#define HINIC_MGMT_STATUS_ERR_LEN 32 /* Length too short or too long */
#define HINIC_MGMT_STATUS_ERR_UNSUPPORT 0xFF /* Feature not supported */
#define HINIC_CHIP_PRESENT 1
#define HINIC_CHIP_ABSENT 0
struct cfg_mgmt_info;
struct rdma_comp_resource;
struct hinic_hwif;
struct hinic_nic_io;
struct hinic_wqs;
struct hinic_aeqs;
struct hinic_ceqs;
struct hinic_mbox_func_to_func;
struct hinic_msg_pf_to_mgmt;
struct hinic_cmdqs;
struct hinic_multi_host_mgmt;
struct hinic_root_ctxt {
u8 status;
u8 version;
u8 rsvd0[6];
u16 func_idx;
u16 rsvd1;
u8 set_cmdq_depth;
u8 cmdq_depth;
u8 lro_en;
u8 rsvd2;
u8 ppf_idx;
u8 rsvd3;
u16 rq_depth;
u16 rx_buf_sz;
u16 sq_depth;
};
struct hinic_page_addr {
void *virt_addr;
u64 phys_addr;
};
struct mqm_addr_trans_tbl_info {
u32 chunk_num;
u32 search_gpa_num;
u32 page_size;
u32 page_num;
struct hinic_page_addr *brm_srch_page_addr;
};
#define HINIC_PCIE_LINK_DOWN 0xFFFFFFFF
#define HINIC_DEV_ACTIVE_FW_TIMEOUT (35 * 1000)
#define HINIC_DEV_BUSY_ACTIVE_FW 0xFE
#define HINIC_HW_WQ_NAME "hinic_hardware"
#define HINIC_HEARTBEAT_PERIOD 1000
#define HINIC_HEARTBEAT_START_EXPIRE 5000
#define HINIC_CHIP_ERROR_TYPE_MAX 1024
#define HINIC_CHIP_FAULT_SIZE \
(HINIC_NODE_ID_MAX * FAULT_LEVEL_MAX * HINIC_CHIP_ERROR_TYPE_MAX)
enum hinic_node_id {
HINIC_NODE_ID_CPI = 0,
HINIC_NODE_ID_IPSU = 4,
HINIC_NODE_ID_MGMT_HOST = 21, /* Host CPU send API to uP */
HINIC_NODE_ID_MAX = 22
};
#define HINIC_HWDEV_INIT_MODES_MASK ((1UL << HINIC_HWDEV_ALL_INITED) - 1)
enum hinic_hwdev_func_state {
HINIC_HWDEV_FUNC_INITED = HINIC_HWDEV_ALL_INITED,
HINIC_HWDEV_FUNC_DEINIT,
HINIC_HWDEV_STATE_BUSY = 31,
};
struct hinic_cqm_stats {
atomic_t cqm_cmd_alloc_cnt;
atomic_t cqm_cmd_free_cnt;
atomic_t cqm_send_cmd_box_cnt;
atomic_t cqm_send_cmd_imm_cnt;
atomic_t cqm_db_addr_alloc_cnt;
atomic_t cqm_db_addr_free_cnt;
atomic_t cqm_fc_srq_create_cnt;
atomic_t cqm_srq_create_cnt;
atomic_t cqm_rq_create_cnt;
atomic_t cqm_qpc_mpt_create_cnt;
atomic_t cqm_nonrdma_queue_create_cnt;
atomic_t cqm_rdma_queue_create_cnt;
atomic_t cqm_rdma_table_create_cnt;
atomic_t cqm_qpc_mpt_delete_cnt;
atomic_t cqm_nonrdma_queue_delete_cnt;
atomic_t cqm_rdma_queue_delete_cnt;
atomic_t cqm_rdma_table_delete_cnt;
atomic_t cqm_func_timer_clear_cnt;
atomic_t cqm_func_hash_buf_clear_cnt;
atomic_t cqm_scq_callback_cnt;
atomic_t cqm_ecq_callback_cnt;
atomic_t cqm_nocq_callback_cnt;
atomic_t cqm_aeq_callback_cnt[112];
};
struct hinic_link_event_stats {
atomic_t link_down_stats;
atomic_t link_up_stats;
};
struct hinic_fault_event_stats {
atomic_t chip_fault_stats[HINIC_NODE_ID_MAX][FAULT_LEVEL_MAX];
atomic_t fault_type_stat[FAULT_TYPE_MAX];
atomic_t pcie_fault_stats;
};
struct hinic_hw_stats {
atomic_t heart_lost_stats;
atomic_t nic_ucode_event_stats[HINIC_NIC_FATAL_ERROR_MAX];
struct hinic_cqm_stats cqm_stats;
struct hinic_link_event_stats link_event_stats;
struct hinic_fault_event_stats fault_event_stats;
};
#define HINIC_NORMAL_HOST_CAP (HINIC_FUNC_MGMT | HINIC_FUNC_PORT | \
HINIC_FUNC_SUPP_RATE_LIMIT | \
HINIC_FUNC_SUPP_DFX_REG | \
HINIC_FUNC_SUPP_RX_MODE | \
HINIC_FUNC_SUPP_SET_VF_MAC_VLAN | \
HINIC_FUNC_SUPP_CHANGE_MAC | \
HINIC_FUNC_SUPP_ENCAP_TSO_CSUM)
#define HINIC_MULTI_BM_MASTER (HINIC_FUNC_MGMT | HINIC_FUNC_PORT | \
HINIC_FUNC_SUPP_DFX_REG | \
HINIC_FUNC_SUPP_RX_MODE | \
HINIC_FUNC_SUPP_SET_VF_MAC_VLAN | \
HINIC_FUNC_SUPP_CHANGE_MAC)
#define HINIC_MULTI_BM_SLAVE (HINIC_FUNC_SRIOV_EN_DFLT | \
HINIC_FUNC_SRIOV_NUM_FIX | \
HINIC_FUNC_FORCE_LINK_UP | \
HINIC_FUNC_OFFLOAD_OVS_UNSUPP)
#define HINIC_MULTI_VM_MASTER (HINIC_FUNC_MGMT | HINIC_FUNC_PORT | \
HINIC_FUNC_SUPP_DFX_REG | \
HINIC_FUNC_SUPP_RX_MODE | \
HINIC_FUNC_SUPP_SET_VF_MAC_VLAN | \
HINIC_FUNC_SUPP_CHANGE_MAC)
#define HINIC_MULTI_VM_SLAVE (HINIC_FUNC_MGMT | \
HINIC_FUNC_SUPP_DFX_REG | \
HINIC_FUNC_SRIOV_EN_DFLT | \
HINIC_FUNC_SUPP_RX_MODE | \
HINIC_FUNC_SUPP_CHANGE_MAC | \
HINIC_FUNC_OFFLOAD_OVS_UNSUPP)
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 0x4
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
#define MULTI_HOST_CHIP_MODE_MASK 0xF
#define MULTI_HOST_MASTER_MBX_STS_MASK 0xF
#define MULTI_HOST_PRIV_DATA_MASK 0xFFFF
#define MULTI_HOST_REG_SET(val, member) \
(((val) & MULTI_HOST_##member##_MASK) \
<< MULTI_HOST_##member##_SHIFT)
#define MULTI_HOST_REG_GET(val, member) \
(((val) >> MULTI_HOST_##member##_SHIFT) \
& MULTI_HOST_##member##_MASK)
#define MULTI_HOST_REG_CLEAR(val, member) \
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
#define HINIC_BOARD_TYPE_MULTI_HOST_ETH_25GE 12
/* new version of roce qp not limited by power of 2 */
#define HINIC_CMD_VER_ROCE_QP 1
/* new version for add function id in multi-host */
#define HINIC_CMD_VER_FUNC_ID 2
struct hinic_hwdev {
void *adapter_hdl; /* pointer to hinic_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
void *dev_hdl; /* pointer to pcidev->dev or Handler, for
* sdk_err() or dma_alloc()
*/
u32 wq_page_size;
void *cqm_hdl;
void *chip_node;
struct hinic_hwif *hwif; /* include void __iomem *bar */
struct hinic_nic_io *nic_io;
struct cfg_mgmt_info *cfg_mgmt;
struct rdma_comp_resource *rdma_comp_res;
struct hinic_wqs *wqs; /* for FC slq */
struct mqm_addr_trans_tbl_info mqm_att;
struct hinic_aeqs *aeqs;
struct hinic_ceqs *ceqs;
struct hinic_mbox_func_to_func *func_to_func;
struct hinic_msg_pf_to_mgmt *pf_to_mgmt;
struct hinic_clp_pf_to_mgmt *clp_pf_to_mgmt;
struct hinic_cmdqs *cmdqs;
struct hinic_page_addr page_pa0;
struct hinic_page_addr page_pa1;
hinic_event_handler event_callback;
void *event_pri_handle;
struct work_struct timer_work;
struct workqueue_struct *workq;
struct timer_list heartbeat_timer;
/* true represent heartbeat lost, false represent heartbeat restore */
u32 heartbeat_lost;
int chip_present_flag;
struct hinic_hw_stats hw_stats;
u8 *chip_fault_stats;
u32 statufull_ref_cnt;
ulong func_state;
u64 feature_cap; /* enum hinic_func_cap */
enum hinic_func_mode func_mode;
struct hinic_multi_host_mgmt *mhost_mgmt;
/* In bmgw x86 host, driver can't send message to mgmt cpu directly,
* need to trasmit message ppf mbox to bmgw arm host.
*/
struct semaphore ppf_sem;
void *ppf_hwdev;
struct semaphore func_sem;
int func_ref;
struct hinic_board_info board_info;
#define MGMT_VERSION_MAX_LEN 32
u8 mgmt_ver[MGMT_VERSION_MAX_LEN];
u64 fw_support_func_flag;
};
int hinic_init_comm_ch(struct hinic_hwdev *hwdev);
void hinic_uninit_comm_ch(struct hinic_hwdev *hwdev);
int hinic_ppf_ext_db_init(void *dev);
int hinic_ppf_ext_db_deinit(void *dev);
enum hinic_set_arm_type {
HINIC_SET_ARM_CMDQ,
HINIC_SET_ARM_SQ,
HINIC_SET_ARM_TYPE_NUM,
};
int hinic_set_arm_bit(void *hwdev, enum hinic_set_arm_type q_type, u16 q_id);
void hinic_set_chip_present(void *hwdev);
void hinic_force_complete_all(void *hwdev);
void hinic_init_heartbeat(struct hinic_hwdev *hwdev);
void hinic_destroy_heartbeat(struct hinic_hwdev *hwdev);
u8 hinic_nic_sw_aeqe_handler(void *handle, u8 event, u64 data);
int hinic_enable_fast_recycle(void *hwdev, bool enable);
int hinic_l2nic_reset_base(struct hinic_hwdev *hwdev, u16 reset_flag);
enum l2nic_resource_type {
RES_TYPE_NIC_FUNC = 0,
RES_TYPE_FLUSH_BIT,
RES_TYPE_PF_BW_CFG,
RES_TYPE_MQM,
RES_TYPE_SMF,
RES_TYPE_CMDQ_ROOTCTX,
RES_TYPE_SQ_CI_TABLE,
RES_TYPE_CEQ,
RES_TYPE_MBOX,
RES_TYPE_AEQ,
};
void hinic_notify_dcb_state_event(struct hinic_hwdev *hwdev,
struct hinic_dcb_state *dcb_state);
int hinic_pf_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size, u32 timeout);
int hinic_pf_send_clp_cmd(void *hwdev, enum hinic_mod_type mod, u8 cmd,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
int hinic_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit);
bool hinic_mgmt_event_ack_first(u8 mod, u8 cmd);
int hinic_set_wq_page_size(struct hinic_hwdev *hwdev, u16 func_idx,
u32 page_size);
int hinic_phy_init_status_judge(void *hwdev);
int hinic_hilink_info_show(struct hinic_hwdev *hwdev);
int hinic_api_csr_rd32(void *hwdev, u8 dest, u32 addr, u32 *val);
int hinic_api_csr_wr32(void *hwdev, u8 dest, u32 addr, u32 val);
int hinic_ppf_process_mbox_msg(struct hinic_hwdev *hwdev, u16 pf_idx, u16 vf_id,
enum hinic_mod_type mod, u8 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size);
#define HINIC_SDI_MODE_UNKNOWN 0
#define HINIC_SDI_MODE_BM 1
#define HINIC_SDI_MODE_VM 2
#define HINIC_SDI_MODE_MAX 3
int hinic_get_sdi_mode(struct hinic_hwdev *hwdev, u16 *cur_mode);
#endif