457 lines
12 KiB
C
457 lines
12 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Huawei Hifc PCI Express Linux driver
|
|
* Copyright(c) 2017 Huawei Technologies Co., Ltd
|
|
*
|
|
*/
|
|
|
|
#ifndef HIFC_HWDEV_H_
|
|
#define HIFC_HWDEV_H_
|
|
|
|
/* to use 0-level CLA, page size must be: 64B(wqebb) * 4096(max_q_depth) */
|
|
#define HIFC_DEFAULT_WQ_PAGE_SIZE 0x40000
|
|
#define HIFC_HW_WQ_PAGE_SIZE 0x1000
|
|
|
|
#define HIFC_MSG_TO_MGMT_MAX_LEN 2016
|
|
|
|
#define HIFC_MGMT_STATUS_ERR_OK 0 /* Ok */
|
|
#define HIFC_MGMT_STATUS_ERR_PARAM 1 /* Invalid parameter */
|
|
#define HIFC_MGMT_STATUS_ERR_FAILED 2 /* Operation failed */
|
|
#define HIFC_MGMT_STATUS_ERR_PORT 3 /* Invalid port */
|
|
#define HIFC_MGMT_STATUS_ERR_TIMEOUT 4 /* Operation time out */
|
|
#define HIFC_MGMT_STATUS_ERR_NOMATCH 5 /* Version not match */
|
|
#define HIFC_MGMT_STATUS_ERR_EXIST 6 /* Entry exists */
|
|
#define HIFC_MGMT_STATUS_ERR_NOMEM 7 /* Out of memory */
|
|
#define HIFC_MGMT_STATUS_ERR_INIT 8 /* Feature not initialized */
|
|
#define HIFC_MGMT_STATUS_ERR_FAULT 9 /* Invalid address */
|
|
#define HIFC_MGMT_STATUS_ERR_PERM 10 /* Operation not permitted */
|
|
#define HIFC_MGMT_STATUS_ERR_EMPTY 11 /* Table empty */
|
|
#define HIFC_MGMT_STATUS_ERR_FULL 12 /* Table full */
|
|
#define HIFC_MGMT_STATUS_ERR_NOT_FOUND 13 /* Not found */
|
|
#define HIFC_MGMT_STATUS_ERR_BUSY 14 /* Device or resource busy */
|
|
#define HIFC_MGMT_STATUS_ERR_RESOURCE 15 /* No resources for operation */
|
|
#define HIFC_MGMT_STATUS_ERR_CONFIG 16 /* Invalid configuration */
|
|
#define HIFC_MGMT_STATUS_ERR_UNAVAIL 17 /* Feature unavailable */
|
|
#define HIFC_MGMT_STATUS_ERR_CRC 18 /* CRC check failed */
|
|
#define HIFC_MGMT_STATUS_ERR_NXIO 19 /* No such device or address */
|
|
#define HIFC_MGMT_STATUS_ERR_ROLLBACK 20 /* Chip rollback fail */
|
|
#define HIFC_MGMT_STATUS_ERR_LEN 32 /* Length too short or too long */
|
|
#define HIFC_MGMT_STATUS_ERR_UNSUPPORT 0xFF /* Feature not supported*/
|
|
/* Qe buffer relates define */
|
|
|
|
enum hifc_rx_buf_size {
|
|
HIFC_RX_BUF_SIZE_32B = 0x20,
|
|
HIFC_RX_BUF_SIZE_64B = 0x40,
|
|
HIFC_RX_BUF_SIZE_96B = 0x60,
|
|
HIFC_RX_BUF_SIZE_128B = 0x80,
|
|
HIFC_RX_BUF_SIZE_192B = 0xC0,
|
|
HIFC_RX_BUF_SIZE_256B = 0x100,
|
|
HIFC_RX_BUF_SIZE_384B = 0x180,
|
|
HIFC_RX_BUF_SIZE_512B = 0x200,
|
|
HIFC_RX_BUF_SIZE_768B = 0x300,
|
|
HIFC_RX_BUF_SIZE_1K = 0x400,
|
|
HIFC_RX_BUF_SIZE_1_5K = 0x600,
|
|
HIFC_RX_BUF_SIZE_2K = 0x800,
|
|
HIFC_RX_BUF_SIZE_3K = 0xC00,
|
|
HIFC_RX_BUF_SIZE_4K = 0x1000,
|
|
HIFC_RX_BUF_SIZE_8K = 0x2000,
|
|
HIFC_RX_BUF_SIZE_16K = 0x4000,
|
|
};
|
|
|
|
enum hifc_res_state {
|
|
HIFC_RES_CLEAN = 0,
|
|
HIFC_RES_ACTIVE = 1,
|
|
};
|
|
|
|
enum ppf_tmr_status {
|
|
HIFC_PPF_TMR_FLAG_STOP,
|
|
HIFC_PPF_TMR_FLAG_START,
|
|
};
|
|
|
|
struct cfg_mgmt_info;
|
|
struct hifc_hwif;
|
|
struct hifc_wqs;
|
|
struct hifc_aeqs;
|
|
struct hifc_ceqs;
|
|
struct hifc_msg_pf_to_mgmt;
|
|
struct hifc_cmdqs;
|
|
|
|
struct hifc_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 hifc_page_addr {
|
|
void *virt_addr;
|
|
u64 phys_addr;
|
|
};
|
|
|
|
#define HIFC_PCIE_LINK_DOWN 0xFFFFFFFF
|
|
|
|
#define HIFC_DEV_ACTIVE_FW_TIMEOUT (35 * 1000)
|
|
#define HIFC_DEV_BUSY_ACTIVE_FW 0xFE
|
|
|
|
#define HIFC_HW_WQ_NAME "hifc_hardware"
|
|
#define HIFC_HEARTBEAT_PERIOD 1000
|
|
#define HIFC_HEARTBEAT_START_EXPIRE 5000
|
|
|
|
#define HIFC_CHIP_ERROR_TYPE_MAX 1024
|
|
#define HIFC_CHIP_FAULT_SIZE \
|
|
(HIFC_NODE_ID_MAX * FAULT_LEVEL_MAX * HIFC_CHIP_ERROR_TYPE_MAX)
|
|
|
|
#define HIFC_CSR_DMA_ATTR_TBL_BASE 0xC80
|
|
#define HIFC_CSR_DMA_ATTR_TBL_STRIDE 0x4
|
|
#define HIFC_CSR_DMA_ATTR_TBL_ADDR(idx) \
|
|
(HIFC_CSR_DMA_ATTR_TBL_BASE \
|
|
+ (idx) * HIFC_CSR_DMA_ATTR_TBL_STRIDE)
|
|
|
|
/* MSI-X registers */
|
|
#define HIFC_CSR_MSIX_CNT_BASE 0x2004
|
|
#define HIFC_CSR_MSIX_STRIDE 0x8
|
|
|
|
#define HIFC_CSR_MSIX_CNT_ADDR(idx) \
|
|
(HIFC_CSR_MSIX_CNT_BASE + (idx) * HIFC_CSR_MSIX_STRIDE)
|
|
|
|
enum hifc_node_id {
|
|
HIFC_NODE_ID_IPSU = 4,
|
|
HIFC_NODE_ID_MGMT_HOST = 21, /*Host CPU send API to uP */
|
|
HIFC_NODE_ID_MAX = 22
|
|
};
|
|
|
|
#define HIFC_HWDEV_INIT_MODES_MASK ((1UL << HIFC_HWDEV_ALL_INITED) - 1)
|
|
|
|
enum hifc_hwdev_func_state {
|
|
HIFC_HWDEV_FUNC_INITED = HIFC_HWDEV_ALL_INITED,
|
|
HIFC_HWDEV_FUNC_DEINIT,
|
|
HIFC_HWDEV_STATE_BUSY = 31,
|
|
};
|
|
|
|
struct hifc_cqm_stats {
|
|
atomic_t cqm_cmd_alloc_cnt;
|
|
atomic_t cqm_cmd_free_cnt;
|
|
atomic_t cqm_send_cmd_box_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_qpc_mpt_create_cnt;
|
|
atomic_t cqm_nonrdma_queue_create_cnt;
|
|
atomic_t cqm_qpc_mpt_delete_cnt;
|
|
atomic_t cqm_nonrdma_queue_delete_cnt;
|
|
atomic_t cqm_aeq_callback_cnt[112];
|
|
};
|
|
|
|
struct hifc_link_event_stats {
|
|
atomic_t link_down_stats;
|
|
atomic_t link_up_stats;
|
|
};
|
|
|
|
struct hifc_fault_event_stats {
|
|
atomic_t chip_fault_stats[HIFC_NODE_ID_MAX][FAULT_LEVEL_MAX];
|
|
atomic_t fault_type_stat[FAULT_TYPE_MAX];
|
|
atomic_t pcie_fault_stats;
|
|
};
|
|
|
|
struct hifc_hw_stats {
|
|
atomic_t heart_lost_stats;
|
|
atomic_t nic_ucode_event_stats[HIFC_NIC_FATAL_ERROR_MAX];
|
|
struct hifc_cqm_stats cqm_stats;
|
|
struct hifc_link_event_stats link_event_stats;
|
|
struct hifc_fault_event_stats fault_event_stats;
|
|
};
|
|
|
|
struct hifc_fault_info_node {
|
|
struct list_head list;
|
|
struct hifc_hwdev *hwdev;
|
|
struct hifc_fault_recover_info info;
|
|
};
|
|
|
|
enum heartbeat_support_state {
|
|
HEARTBEAT_NOT_SUPPORT = 0,
|
|
HEARTBEAT_SUPPORT,
|
|
};
|
|
|
|
/* 25s for max 5 heartbeat event lost */
|
|
#define HIFC_HEARBEAT_ENHANCED_LOST 25000
|
|
struct hifc_heartbeat_enhanced {
|
|
bool en; /* enable enhanced heartbeat or not */
|
|
|
|
unsigned long last_update_jiffies;
|
|
u32 last_heartbeat;
|
|
|
|
unsigned long start_detect_jiffies;
|
|
};
|
|
|
|
#define HIFC_CMD_VER_FUNC_ID 2
|
|
#define HIFC_GLB_DMA_SO_RO_REPLACE_ADDR 0x488C
|
|
#define HIFC_ICPL_RESERVD_ADDR 0x9204
|
|
|
|
#define l2nic_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out, out_size)\
|
|
hifc_msg_to_mgmt_sync(hwdev, HIFC_MOD_L2NIC, cmd, \
|
|
buf_in, in_size, \
|
|
buf_out, out_size, 0)
|
|
|
|
struct hifc_hwdev {
|
|
void *adapter_hdl; /* pointer to hifc_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 hifc_hwif *hwif; /* include void __iomem *bar */
|
|
struct cfg_mgmt_info *cfg_mgmt;
|
|
struct hifc_wqs *wqs; /* for FC slq */
|
|
|
|
struct hifc_aeqs *aeqs;
|
|
struct hifc_ceqs *ceqs;
|
|
|
|
struct hifc_msg_pf_to_mgmt *pf_to_mgmt;
|
|
struct hifc_clp_pf_to_mgmt *clp_pf_to_mgmt;
|
|
|
|
struct hifc_cmdqs *cmdqs;
|
|
|
|
struct hifc_page_addr page_pa0;
|
|
struct hifc_page_addr page_pa1;
|
|
|
|
hifc_event_handler event_callback;
|
|
void *event_pri_handle;
|
|
bool history_fault_flag;
|
|
struct hifc_fault_recover_info history_fault;
|
|
struct semaphore fault_list_sem;
|
|
|
|
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 hifc_heartbeat_enhanced heartbeat_ehd;
|
|
struct hifc_hw_stats hw_stats;
|
|
u8 *chip_fault_stats;
|
|
|
|
u32 statufull_ref_cnt;
|
|
ulong func_state;
|
|
|
|
u64 feature_cap; /* enum hifc_func_cap */
|
|
|
|
/* In bmgw x86 host, driver can't send message to mgmt cpu directly,
|
|
* need to trasmit message ppf mbox to bmgw arm host.
|
|
*/
|
|
|
|
struct hifc_board_info board_info;
|
|
};
|
|
|
|
int hifc_init_comm_ch(struct hifc_hwdev *hwdev);
|
|
void hifc_uninit_comm_ch(struct hifc_hwdev *hwdev);
|
|
|
|
enum hifc_set_arm_type {
|
|
HIFC_SET_ARM_CMDQ,
|
|
HIFC_SET_ARM_SQ,
|
|
HIFC_SET_ARM_TYPE_NUM,
|
|
};
|
|
|
|
/* up to driver event */
|
|
#define HIFC_PORT_CMD_MGMT_RESET 0x0
|
|
struct hifc_vport_state {
|
|
u8 status;
|
|
u8 version;
|
|
u8 rsvd0[6];
|
|
|
|
u16 func_id;
|
|
u16 rsvd1;
|
|
u8 state;
|
|
u8 rsvd2[3];
|
|
};
|
|
|
|
struct hifc_l2nic_reset {
|
|
u8 status;
|
|
u8 version;
|
|
u8 rsvd0[6];
|
|
|
|
u16 func_id;
|
|
u16 reset_flag;
|
|
};
|
|
|
|
/* HILINK module interface */
|
|
|
|
/* cmd of mgmt CPU message for HILINK module */
|
|
enum hifc_hilink_cmd {
|
|
HIFC_HILINK_CMD_GET_LINK_INFO = 0x3,
|
|
HIFC_HILINK_CMD_SET_LINK_SETTINGS = 0x8,
|
|
};
|
|
|
|
enum hilink_info_print_event {
|
|
HILINK_EVENT_LINK_UP = 1,
|
|
HILINK_EVENT_LINK_DOWN,
|
|
HILINK_EVENT_CABLE_PLUGGED,
|
|
HILINK_EVENT_MAX_TYPE,
|
|
};
|
|
|
|
enum hifc_link_port_type {
|
|
LINK_PORT_FIBRE = 1,
|
|
LINK_PORT_ELECTRIC,
|
|
LINK_PORT_COPPER,
|
|
LINK_PORT_AOC,
|
|
LINK_PORT_BACKPLANE,
|
|
LINK_PORT_BASET,
|
|
LINK_PORT_MAX_TYPE,
|
|
};
|
|
|
|
enum hilink_fibre_subtype {
|
|
FIBRE_SUBTYPE_SR = 1,
|
|
FIBRE_SUBTYPE_LR,
|
|
FIBRE_SUBTYPE_MAX,
|
|
};
|
|
|
|
enum hilink_fec_type {
|
|
HILINK_FEC_RSFEC,
|
|
HILINK_FEC_BASEFEC,
|
|
HILINK_FEC_NOFEC,
|
|
HILINK_FEC_MAX_TYPE,
|
|
};
|
|
|
|
/* cmd of mgmt CPU message */
|
|
enum hifc_port_cmd {
|
|
HIFC_PORT_CMD_SET_MAC = 0x9,
|
|
HIFC_PORT_CMD_GET_AUTONEG_CAP = 0xf,
|
|
HIFC_PORT_CMD_SET_VPORT_ENABLE = 0x5d,
|
|
HIFC_PORT_CMD_UPDATE_MAC = 0xa4,
|
|
HIFC_PORT_CMD_GET_SFP_INFO = 0xad,
|
|
HIFC_PORT_CMD_GET_STD_SFP_INFO = 0xF0,
|
|
HIFC_PORT_CMD_GET_SFP_ABS = 0xFB,
|
|
};
|
|
|
|
struct hi30_ffe_data {
|
|
u8 PRE2;
|
|
u8 PRE1;
|
|
u8 POST1;
|
|
u8 POST2;
|
|
u8 MAIN;
|
|
};
|
|
|
|
struct hi30_ctle_data {
|
|
u8 ctlebst[3];
|
|
u8 ctlecmband[3];
|
|
u8 ctlermband[3];
|
|
u8 ctleza[3];
|
|
u8 ctlesqh[3];
|
|
u8 ctleactgn[3];
|
|
u8 ctlepassgn;
|
|
};
|
|
|
|
#define HILINK_MAX_LANE 4
|
|
|
|
struct hilink_lane {
|
|
u8 lane_used;
|
|
u8 hi30_ffe[5];
|
|
u8 hi30_ctle[19];
|
|
u8 hi30_dfe[14];
|
|
u8 rsvd4;
|
|
};
|
|
|
|
struct hifc_link_info {
|
|
u8 vendor_name[16];
|
|
/* port type:
|
|
* 1 - fiber; 2 - electric; 3 - copper; 4 - AOC; 5 - backplane;
|
|
* 6 - baseT; 0xffff - unknown
|
|
*
|
|
* port subtype:
|
|
* Only when port_type is fiber:
|
|
* 1 - SR; 2 - LR
|
|
*/
|
|
u32 port_type;
|
|
u32 port_sub_type;
|
|
u32 cable_length;
|
|
u8 cable_temp;
|
|
u8 cable_max_speed; /* 1(G)/10(G)/25(G)... */
|
|
u8 sfp_type; /* 0 - qsfp; 1 - sfp */
|
|
u8 rsvd0;
|
|
u32 power[4]; /* uW; if is sfp, only power[2] is valid */
|
|
|
|
u8 an_state; /* 0 - off; 1 - on */
|
|
u8 fec; /* 0 - RSFEC; 1 - BASEFEC; 2 - NOFEC */
|
|
u16 speed; /* 1(G)/10(G)/25(G)... */
|
|
|
|
u8 cable_absent; /* 0 - cable present; 1 - cable unpresent */
|
|
u8 alos; /* 0 - yes; 1 - no */
|
|
u8 rx_los; /* 0 - yes; 1 - no */
|
|
u8 pma_status;
|
|
u32 pma_dbg_info_reg; /* pma debug info: */
|
|
u32 pma_signal_ok_reg; /* signal ok: */
|
|
|
|
u32 pcs_err_blk_cnt_reg; /* error block counter: */
|
|
u32 rf_lf_status_reg; /* RF/LF status: */
|
|
u8 pcs_link_reg; /* pcs link: */
|
|
u8 mac_link_reg; /* mac link: */
|
|
u8 mac_tx_en;
|
|
u8 mac_rx_en;
|
|
u32 pcs_err_cnt;
|
|
|
|
/* struct hifc_hilink_lane: 40 bytes */
|
|
u8 lane1[40]; /* 25GE lane in old firmware */
|
|
|
|
u8 rsvd1[266]; /* hilink machine state */
|
|
|
|
u8 lane2[HILINK_MAX_LANE * 40]; /* max 4 lane for 40GE/100GE */
|
|
|
|
u8 rsvd2[2];
|
|
};
|
|
|
|
struct hifc_hilink_link_info {
|
|
u8 status;
|
|
u8 version;
|
|
u8 rsvd0[6];
|
|
|
|
u16 port_id;
|
|
u8 info_type; /* 1: link up 2: link down 3 cable plugged */
|
|
u8 rsvd1;
|
|
|
|
struct hifc_link_info info;
|
|
|
|
u8 rsvd2[352];
|
|
};
|
|
|
|
int hifc_set_arm_bit(void *hwdev, enum hifc_set_arm_type q_type, u16 q_id);
|
|
void hifc_set_chip_present(void *hwdev);
|
|
void hifc_force_complete_all(void *hwdev);
|
|
void hifc_init_heartbeat(struct hifc_hwdev *hwdev);
|
|
void hifc_destroy_heartbeat(struct hifc_hwdev *hwdev);
|
|
u8 hifc_nic_sw_aeqe_handler(void *handle, u8 event, u64 data);
|
|
int hifc_l2nic_reset_base(struct hifc_hwdev *hwdev, u16 reset_flag);
|
|
int hifc_pf_msg_to_mgmt_sync(void *hwdev, enum hifc_mod_type mod, u8 cmd,
|
|
void *buf_in, u16 in_size,
|
|
void *buf_out, u16 *out_size, u32 timeout);
|
|
void hifc_swe_fault_handler(struct hifc_hwdev *hwdev, u8 level,
|
|
u8 event, u64 val);
|
|
bool hifc_mgmt_event_ack_first(u8 mod, u8 cmd);
|
|
int hifc_phy_init_status_judge(void *hwdev);
|
|
int hifc_api_csr_rd32(void *hwdev, u8 dest, u32 addr, u32 *val);
|
|
int hifc_api_csr_wr32(void *hwdev, u8 dest, u32 addr, u32 val);
|
|
void mgmt_heartbeat_event_handler(void *hwdev, void *buf_in, u16 in_size,
|
|
void *buf_out, u16 *out_size);
|
|
struct hifc_sge {
|
|
u32 hi_addr;
|
|
u32 lo_addr;
|
|
u32 len;
|
|
};
|
|
|
|
void hifc_cpu_to_be32(void *data, int len);
|
|
void hifc_be32_to_cpu(void *data, int len);
|
|
void hifc_set_sge(struct hifc_sge *sge, dma_addr_t addr, u32 len);
|
|
#endif
|