2026-01-21 18:59:54 +08:00

269 lines
9.0 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/* Huawei Hifc PCI Express Linux driver
* Copyright(c) 2017 Huawei Technologies Co., Ltd
*
*/
#ifndef HIFC_API_CMD_H_
#define HIFC_API_CMD_H_
#define HIFC_API_CMD_CELL_CTRL_CELL_LEN_SHIFT 0
#define HIFC_API_CMD_CELL_CTRL_RD_DMA_ATTR_OFF_SHIFT 16
#define HIFC_API_CMD_CELL_CTRL_WR_DMA_ATTR_OFF_SHIFT 24
#define HIFC_API_CMD_CELL_CTRL_XOR_CHKSUM_SHIFT 56
#define HIFC_API_CMD_CELL_CTRL_CELL_LEN_MASK 0x3FU
#define HIFC_API_CMD_CELL_CTRL_RD_DMA_ATTR_OFF_MASK 0x3FU
#define HIFC_API_CMD_CELL_CTRL_WR_DMA_ATTR_OFF_MASK 0x3FU
#define HIFC_API_CMD_CELL_CTRL_XOR_CHKSUM_MASK 0xFFU
#define HIFC_API_CMD_CELL_CTRL_SET(val, member) \
((((u64)val) & HIFC_API_CMD_CELL_CTRL_##member##_MASK) << \
HIFC_API_CMD_CELL_CTRL_##member##_SHIFT)
#define HIFC_API_CMD_DESC_API_TYPE_SHIFT 0
#define HIFC_API_CMD_DESC_RD_WR_SHIFT 1
#define HIFC_API_CMD_DESC_MGMT_BYPASS_SHIFT 2
#define HIFC_API_CMD_DESC_RESP_AEQE_EN_SHIFT 3
#define HIFC_API_CMD_DESC_PRIV_DATA_SHIFT 8
#define HIFC_API_CMD_DESC_DEST_SHIFT 32
#define HIFC_API_CMD_DESC_SIZE_SHIFT 40
#define HIFC_API_CMD_DESC_XOR_CHKSUM_SHIFT 56
#define HIFC_API_CMD_DESC_API_TYPE_MASK 0x1U
#define HIFC_API_CMD_DESC_RD_WR_MASK 0x1U
#define HIFC_API_CMD_DESC_MGMT_BYPASS_MASK 0x1U
#define HIFC_API_CMD_DESC_RESP_AEQE_EN_MASK 0x1U
#define HIFC_API_CMD_DESC_DEST_MASK 0x1FU
#define HIFC_API_CMD_DESC_SIZE_MASK 0x7FFU
#define HIFC_API_CMD_DESC_XOR_CHKSUM_MASK 0xFFU
#define HIFC_API_CMD_DESC_PRIV_DATA_MASK 0xFFFFFFU
#define HIFC_API_CMD_DESC_SET(val, member) \
((((u64)val) & HIFC_API_CMD_DESC_##member##_MASK) << \
HIFC_API_CMD_DESC_##member##_SHIFT)
#define HIFC_API_CMD_STATUS_HEADER_VALID_SHIFT 0
#define HIFC_API_CMD_STATUS_HEADER_CHAIN_ID_SHIFT 16
#define HIFC_API_CMD_STATUS_HEADER_VALID_MASK 0xFFU
#define HIFC_API_CMD_STATUS_HEADER_CHAIN_ID_MASK 0xFFU
#define HIFC_API_CMD_STATUS_HEADER_GET(val, member) \
(((val) >> HIFC_API_CMD_STATUS_HEADER_##member##_SHIFT) & \
HIFC_API_CMD_STATUS_HEADER_##member##_MASK)
#define HIFC_API_CMD_CHAIN_REQ_RESTART_SHIFT 1
#define HIFC_API_CMD_CHAIN_REQ_RESTART_MASK 0x1U
#define HIFC_API_CMD_CHAIN_REQ_WB_TRIGGER_MASK 0x1U
#define HIFC_API_CMD_CHAIN_REQ_SET(val, member) \
(((val) & HIFC_API_CMD_CHAIN_REQ_##member##_MASK) << \
HIFC_API_CMD_CHAIN_REQ_##member##_SHIFT)
#define HIFC_API_CMD_CHAIN_REQ_GET(val, member) \
(((val) >> HIFC_API_CMD_CHAIN_REQ_##member##_SHIFT) & \
HIFC_API_CMD_CHAIN_REQ_##member##_MASK)
#define HIFC_API_CMD_CHAIN_REQ_CLEAR(val, member) \
((val) & (~(HIFC_API_CMD_CHAIN_REQ_##member##_MASK \
<< HIFC_API_CMD_CHAIN_REQ_##member##_SHIFT)))
#define HIFC_API_CMD_CHAIN_CTRL_RESTART_EN_SHIFT 1
#define HIFC_API_CMD_CHAIN_CTRL_XOR_ERR_SHIFT 2
#define HIFC_API_CMD_CHAIN_CTRL_AEQE_EN_SHIFT 4
#define HIFC_API_CMD_CHAIN_CTRL_AEQ_ID_SHIFT 8
#define HIFC_API_CMD_CHAIN_CTRL_XOR_CHK_EN_SHIFT 28
#define HIFC_API_CMD_CHAIN_CTRL_CELL_SIZE_SHIFT 30
#define HIFC_API_CMD_CHAIN_CTRL_RESTART_EN_MASK 0x1U
#define HIFC_API_CMD_CHAIN_CTRL_XOR_ERR_MASK 0x1U
#define HIFC_API_CMD_CHAIN_CTRL_AEQE_EN_MASK 0x1U
#define HIFC_API_CMD_CHAIN_CTRL_AEQ_ID_MASK 0x3U
#define HIFC_API_CMD_CHAIN_CTRL_XOR_CHK_EN_MASK 0x3U
#define HIFC_API_CMD_CHAIN_CTRL_CELL_SIZE_MASK 0x3U
#define HIFC_API_CMD_CHAIN_CTRL_SET(val, member) \
(((val) & HIFC_API_CMD_CHAIN_CTRL_##member##_MASK) << \
HIFC_API_CMD_CHAIN_CTRL_##member##_SHIFT)
#define HIFC_API_CMD_CHAIN_CTRL_CLEAR(val, member) \
((val) & (~(HIFC_API_CMD_CHAIN_CTRL_##member##_MASK \
<< HIFC_API_CMD_CHAIN_CTRL_##member##_SHIFT)))
#define HIFC_API_CMD_RESP_HEAD_VALID_MASK 0xFF
#define HIFC_API_CMD_RESP_HEAD_VALID_CODE 0xFF
#define HIFC_API_CMD_RESP_HEADER_VALID(val) \
(((val) & HIFC_API_CMD_RESP_HEAD_VALID_MASK) == \
HIFC_API_CMD_RESP_HEAD_VALID_CODE)
#define HIFC_API_CMD_STATUS_CONS_IDX_MASK 0xFFFFFFU
#define HIFC_API_CMD_STATUS_CONS_IDX_SHIFT 0
#define HIFC_API_CMD_STATUS_FSM_MASK 0xFU
#define HIFC_API_CMD_STATUS_FSM_SHIFT 24
#define HIFC_API_CMD_STATUS_CHKSUM_ERR_MASK 0x3U
#define HIFC_API_CMD_STATUS_CHKSUM_ERR_SHIFT 28
#define HIFC_API_CMD_STATUS_CPLD_ERR_MASK 0x1U
#define HIFC_API_CMD_STATUS_CPLD_ERR_SHIFT 30
#define HIFC_API_CMD_STATUS_GET(val, member) \
(((val) >> HIFC_API_CMD_STATUS_##member##_SHIFT) & \
HIFC_API_CMD_STATUS_##member##_MASK)
/* API CMD registers */
#define HIFC_CSR_API_CMD_BASE 0xF000
#define HIFC_CSR_API_CMD_STRIDE 0x100
#define HIFC_CSR_API_CMD_CHAIN_HEAD_HI_ADDR(idx) \
(HIFC_CSR_API_CMD_BASE + 0x0 + (idx) * HIFC_CSR_API_CMD_STRIDE)
#define HIFC_CSR_API_CMD_CHAIN_HEAD_LO_ADDR(idx) \
(HIFC_CSR_API_CMD_BASE + 0x4 + (idx) * HIFC_CSR_API_CMD_STRIDE)
#define HIFC_CSR_API_CMD_STATUS_HI_ADDR(idx) \
(HIFC_CSR_API_CMD_BASE + 0x8 + (idx) * HIFC_CSR_API_CMD_STRIDE)
#define HIFC_CSR_API_CMD_STATUS_LO_ADDR(idx) \
(HIFC_CSR_API_CMD_BASE + 0xC + (idx) * HIFC_CSR_API_CMD_STRIDE)
#define HIFC_CSR_API_CMD_CHAIN_NUM_CELLS_ADDR(idx) \
(HIFC_CSR_API_CMD_BASE + 0x10 + (idx) * HIFC_CSR_API_CMD_STRIDE)
#define HIFC_CSR_API_CMD_CHAIN_CTRL_ADDR(idx) \
(HIFC_CSR_API_CMD_BASE + 0x14 + (idx) * HIFC_CSR_API_CMD_STRIDE)
#define HIFC_CSR_API_CMD_CHAIN_PI_ADDR(idx) \
(HIFC_CSR_API_CMD_BASE + 0x1C + (idx) * HIFC_CSR_API_CMD_STRIDE)
#define HIFC_CSR_API_CMD_CHAIN_REQ_ADDR(idx) \
(HIFC_CSR_API_CMD_BASE + 0x20 + (idx) * HIFC_CSR_API_CMD_STRIDE)
#define HIFC_CSR_API_CMD_STATUS_0_ADDR(idx) \
(HIFC_CSR_API_CMD_BASE + 0x30 + (idx) * HIFC_CSR_API_CMD_STRIDE)
enum hifc_api_cmd_chain_type {
/* write command with completion notification */
HIFC_API_CMD_WRITE = 0,
/* read command with completion notification */
HIFC_API_CMD_READ = 1,
/* write to mgmt cpu command with completion */
HIFC_API_CMD_WRITE_TO_MGMT_CPU = 2,
/* multi read command with completion notification - not used */
HIFC_API_CMD_MULTI_READ = 3,
/* write command without completion notification */
HIFC_API_CMD_POLL_WRITE = 4,
/* read command without completion notification */
HIFC_API_CMD_POLL_READ = 5,
/* read from mgmt cpu command with completion */
HIFC_API_CMD_WRITE_ASYNC_TO_MGMT_CPU = 6,
HIFC_API_CMD_MAX,
};
struct hifc_api_cmd_status {
u64 header;
u32 buf_desc;
u32 cell_addr_hi;
u32 cell_addr_lo;
u32 rsvd0;
u64 rsvd1;
};
/* HW struct */
struct hifc_api_cmd_cell {
u64 ctrl;
/* address is 64 bit in HW struct */
u64 next_cell_paddr;
u64 desc;
/* HW struct */
union {
struct {
u64 hw_cmd_paddr;
} write;
struct {
u64 hw_wb_resp_paddr;
u64 hw_cmd_paddr;
} read;
};
};
struct hifc_api_cmd_resp_fmt {
u64 header;
u64 rsvd[3];
u64 resp_data;
};
struct hifc_api_cmd_cell_ctxt {
struct hifc_api_cmd_cell *cell_vaddr;
void *api_cmd_vaddr;
struct hifc_api_cmd_resp_fmt *resp;
struct completion done;
int status;
u32 saved_prod_idx;
};
struct hifc_api_cmd_chain_attr {
struct hifc_hwdev *hwdev;
enum hifc_api_cmd_chain_type chain_type;
u32 num_cells;
u16 rsp_size;
u16 cell_size;
};
struct hifc_api_cmd_chain {
struct hifc_hwdev *hwdev;
enum hifc_api_cmd_chain_type chain_type;
u32 num_cells;
u16 cell_size;
u16 rsp_size;
/* HW members is 24 bit format */
u32 prod_idx;
u32 cons_idx;
struct semaphore sem;
/* Async cmd can not be scheduling */
spinlock_t async_lock;
dma_addr_t wb_status_paddr;
struct hifc_api_cmd_status *wb_status;
dma_addr_t head_cell_paddr;
struct hifc_api_cmd_cell *head_node;
struct hifc_api_cmd_cell_ctxt *cell_ctxt;
struct hifc_api_cmd_cell *curr_node;
struct hifc_dma_addr_align cells_addr;
u8 *cell_vaddr_base;
u64 cell_paddr_base;
u8 *rsp_vaddr_base;
u64 rsp_paddr_base;
u8 *buf_vaddr_base;
u64 buf_paddr_base;
u64 cell_size_align;
u64 rsp_size_align;
u64 buf_size_align;
};
int hifc_api_cmd_write(struct hifc_api_cmd_chain *chain,
enum hifc_node_id dest, void *cmd, u16 size);
int hifc_api_cmd_read(struct hifc_api_cmd_chain *chain,
enum hifc_node_id dest, void *cmd, u16 size,
void *ack, u16 ack_size);
int hifc_api_cmd_init(struct hifc_hwdev *hwdev,
struct hifc_api_cmd_chain **chain);
void hifc_api_cmd_free(struct hifc_api_cmd_chain **chain);
#endif