| /* SPDX-License-Identifier: GPL-2.0+ */ |
| /* Copyright (c) 2023 Hisilicon Limited. */ |
| |
| #ifndef __KUNPENG_HCCS_H__ |
| #define __KUNPENG_HCCS_H__ |
| |
| /* |
| * |--------------- Chip0 ---------------|---------------- ChipN -------------| |
| * |--------Die0-------|--------DieN-------|--------Die0-------|-------DieN-------| |
| * | P0 | P1 | P2 | P3 | P0 | P1 | P2 | P3 | P0 | P1 | P2 | P3 |P0 | P1 | P2 | P3 | |
| */ |
| |
| /* |
| * This value cannot be 255, otherwise the loop of the multi-BD communication |
| * case cannot end. |
| */ |
| #define HCCS_DIE_MAX_PORT_ID 254 |
| |
| struct hccs_port_info { |
| u8 port_id; |
| u8 port_type; |
| u8 lane_mode; |
| bool enable; /* if the port is enabled */ |
| struct kobject kobj; |
| bool dir_created; |
| struct hccs_die_info *die; /* point to the die the port is located */ |
| }; |
| |
| struct hccs_die_info { |
| u8 die_id; |
| u8 port_num; |
| u8 min_port_id; |
| u8 max_port_id; |
| struct hccs_port_info *ports; |
| struct kobject kobj; |
| bool dir_created; |
| struct hccs_chip_info *chip; /* point to the chip the die is located */ |
| }; |
| |
| struct hccs_chip_info { |
| u8 chip_id; |
| u8 die_num; |
| struct hccs_die_info *dies; |
| struct kobject kobj; |
| struct hccs_dev *hdev; |
| }; |
| |
| struct hccs_mbox_client_info { |
| struct mbox_client client; |
| struct mbox_chan *mbox_chan; |
| struct pcc_mbox_chan *pcc_chan; |
| u64 deadline_us; |
| void __iomem *pcc_comm_addr; |
| struct completion done; |
| }; |
| |
| struct hccs_desc; |
| |
| struct hccs_verspecific_data { |
| void (*rx_callback)(struct mbox_client *cl, void *mssg); |
| int (*wait_cmd_complete)(struct hccs_dev *hdev); |
| void (*fill_pcc_shared_mem)(struct hccs_dev *hdev, |
| u8 cmd, struct hccs_desc *desc, |
| void __iomem *comm_space, |
| u16 space_size); |
| u16 shared_mem_size; |
| bool has_txdone_irq; |
| }; |
| |
| struct hccs_dev { |
| struct device *dev; |
| struct acpi_device *acpi_dev; |
| const struct hccs_verspecific_data *verspec_data; |
| u64 caps; |
| u8 chip_num; |
| struct hccs_chip_info *chips; |
| u8 chan_id; |
| struct mutex lock; |
| struct hccs_mbox_client_info cl_info; |
| }; |
| |
| #define HCCS_SERDES_MODULE_CODE 0x32 |
| enum hccs_subcmd_type { |
| HCCS_GET_CHIP_NUM = 0x1, |
| HCCS_GET_DIE_NUM, |
| HCCS_GET_DIE_INFO, |
| HCCS_GET_DIE_PORT_INFO, |
| HCCS_GET_DEV_CAP, |
| HCCS_GET_PORT_LINK_STATUS, |
| HCCS_GET_PORT_CRC_ERR_CNT, |
| HCCS_GET_DIE_PORTS_LANE_STA, |
| HCCS_GET_DIE_PORTS_LINK_STA, |
| HCCS_GET_DIE_PORTS_CRC_ERR_CNT, |
| HCCS_SUB_CMD_MAX = 255, |
| }; |
| |
| struct hccs_die_num_req_param { |
| u8 chip_id; |
| }; |
| |
| struct hccs_die_info_req_param { |
| u8 chip_id; |
| u8 die_idx; |
| }; |
| |
| struct hccs_die_info_rsp_data { |
| u8 die_id; |
| u8 port_num; |
| u8 min_port_id; |
| u8 max_port_id; |
| }; |
| |
| struct hccs_port_attr { |
| u8 port_id; |
| u8 port_type; |
| u8 lane_mode; |
| u8 enable : 1; /* if the port is enabled */ |
| u16 rsv[2]; |
| }; |
| |
| /* |
| * The common command request for getting the information of all HCCS port on |
| * specified DIE. |
| */ |
| struct hccs_die_comm_req_param { |
| u8 chip_id; |
| u8 die_id; /* id in hardware */ |
| }; |
| |
| /* The common command request for getting the information of a specific port */ |
| struct hccs_port_comm_req_param { |
| u8 chip_id; |
| u8 die_id; |
| u8 port_id; |
| }; |
| |
| #define HCCS_PORT_RESET 1 |
| #define HCCS_PORT_SETUP 2 |
| #define HCCS_PORT_CONFIG 3 |
| #define HCCS_PORT_READY 4 |
| struct hccs_link_status { |
| u8 lane_mask; /* indicate which lanes are used. */ |
| u8 link_fsm : 3; /* link fsm, 1: reset 2: setup 3: config 4: link-up */ |
| u8 lane_num : 5; /* current lane number */ |
| }; |
| |
| struct hccs_req_head { |
| u8 module_code; /* set to 0x32 for serdes */ |
| u8 start_id; |
| u8 rsv[2]; |
| }; |
| |
| struct hccs_rsp_head { |
| u8 data_len; |
| u8 next_id; |
| u8 rsv[2]; |
| }; |
| |
| struct hccs_fw_inner_head { |
| u8 retStatus; /* 0: success, other: failure */ |
| u8 rsv[7]; |
| }; |
| |
| #define HCCS_PCC_SHARE_MEM_BYTES 64 |
| #define HCCS_FW_INNER_HEAD_BYTES 8 |
| #define HCCS_RSP_HEAD_BYTES 4 |
| |
| #define HCCS_MAX_RSP_DATA_BYTES (HCCS_PCC_SHARE_MEM_BYTES - \ |
| HCCS_FW_INNER_HEAD_BYTES - \ |
| HCCS_RSP_HEAD_BYTES) |
| #define HCCS_MAX_RSP_DATA_SIZE_MAX (HCCS_MAX_RSP_DATA_BYTES / 4) |
| |
| /* |
| * Note: Actual available size of data field also depands on the PCC header |
| * bytes of the specific type. Driver needs to copy the response data in the |
| * communication space based on the real length. |
| */ |
| struct hccs_rsp_desc { |
| struct hccs_fw_inner_head fw_inner_head; /* 8 Bytes */ |
| struct hccs_rsp_head rsp_head; /* 4 Bytes */ |
| u32 data[HCCS_MAX_RSP_DATA_SIZE_MAX]; |
| }; |
| |
| #define HCCS_REQ_HEAD_BYTES 4 |
| #define HCCS_MAX_REQ_DATA_BYTES (HCCS_PCC_SHARE_MEM_BYTES - \ |
| HCCS_REQ_HEAD_BYTES) |
| #define HCCS_MAX_REQ_DATA_SIZE_MAX (HCCS_MAX_REQ_DATA_BYTES / 4) |
| |
| /* |
| * Note: Actual available size of data field also depands on the PCC header |
| * bytes of the specific type. Driver needs to copy the request data to the |
| * communication space based on the real length. |
| */ |
| struct hccs_req_desc { |
| struct hccs_req_head req_head; /* 4 Bytes */ |
| u32 data[HCCS_MAX_REQ_DATA_SIZE_MAX]; |
| }; |
| |
| struct hccs_desc { |
| union { |
| struct hccs_req_desc req; |
| struct hccs_rsp_desc rsp; |
| }; |
| }; |
| |
| #endif /* __KUNPENG_HCCS_H__ */ |