/* 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_MGMT_H_ #define HINIC_MGMT_H_ #define HINIC_MSG_HEADER_MSG_LEN_SHIFT 0 #define HINIC_MSG_HEADER_MODULE_SHIFT 11 #define HINIC_MSG_HEADER_SEG_LEN_SHIFT 16 #define HINIC_MSG_HEADER_NO_ACK_SHIFT 22 #define HINIC_MSG_HEADER_ASYNC_MGMT_TO_PF_SHIFT 23 #define HINIC_MSG_HEADER_SEQID_SHIFT 24 #define HINIC_MSG_HEADER_LAST_SHIFT 30 #define HINIC_MSG_HEADER_DIRECTION_SHIFT 31 #define HINIC_MSG_HEADER_CMD_SHIFT 32 #define HINIC_MSG_HEADER_PCI_INTF_IDX_SHIFT 48 #define HINIC_MSG_HEADER_P2P_IDX_SHIFT 50 #define HINIC_MSG_HEADER_MSG_ID_SHIFT 54 #define HINIC_MSG_HEADER_MSG_LEN_MASK 0x7FF #define HINIC_MSG_HEADER_MODULE_MASK 0x1F #define HINIC_MSG_HEADER_SEG_LEN_MASK 0x3F #define HINIC_MSG_HEADER_NO_ACK_MASK 0x1 #define HINIC_MSG_HEADER_ASYNC_MGMT_TO_PF_MASK 0x1 #define HINIC_MSG_HEADER_SEQID_MASK 0x3F #define HINIC_MSG_HEADER_LAST_MASK 0x1 #define HINIC_MSG_HEADER_DIRECTION_MASK 0x1 #define HINIC_MSG_HEADER_CMD_MASK 0xFF #define HINIC_MSG_HEADER_PCI_INTF_IDX_MASK 0x3 #define HINIC_MSG_HEADER_P2P_IDX_MASK 0xF #define HINIC_MSG_HEADER_MSG_ID_MASK 0x3FF #define HINIC_MSG_HEADER_GET(val, member) \ (((val) >> HINIC_MSG_HEADER_##member##_SHIFT) & \ HINIC_MSG_HEADER_##member##_MASK) #define HINIC_MSG_HEADER_SET(val, member) \ ((u64)((val) & HINIC_MSG_HEADER_##member##_MASK) << \ HINIC_MSG_HEADER_##member##_SHIFT) #define HINIC_MGMT_WQ_NAME "hinic_mgmt" enum clp_data_type { HINIC_CLP_REQ_HOST = 0, HINIC_CLP_RSP_HOST = 1 }; enum clp_reg_type { HINIC_CLP_BA_HOST = 0, HINIC_CLP_SIZE_HOST = 1, HINIC_CLP_LEN_HOST = 2, HINIC_CLP_START_REQ_HOST = 3, HINIC_CLP_READY_RSP_HOST = 4 }; #define HINIC_CLP_REG_GAP (0x20) #define HINIC_CLP_INPUT_BUFFER_LEN_HOST (4096UL) #define HINIC_CLP_DATA_UNIT_HOST (4UL) #define HINIC_BAR01_GLOABAL_CTL_OFFSET (0x4000) #define HINIC_BAR01_CLP_OFFSET (0x5000) #define HINIC_CLP_SRAM_SIZE_REG (HINIC_BAR01_GLOABAL_CTL_OFFSET + 0x220) #define HINIC_CLP_REQ_SRAM_BA_REG (HINIC_BAR01_GLOABAL_CTL_OFFSET + 0x224) #define HINIC_CLP_RSP_SRAM_BA_REG (HINIC_BAR01_GLOABAL_CTL_OFFSET + 0x228) #define HINIC_CLP_REQ_REG (HINIC_BAR01_GLOABAL_CTL_OFFSET + 0x22c) #define HINIC_CLP_RSP_REG (HINIC_BAR01_GLOABAL_CTL_OFFSET + 0x230) #define HINIC_CLP_REG(member) (HINIC_CLP_##member##_REG) #define HINIC_CLP_REQ_DATA (HINIC_BAR01_CLP_OFFSET) #define HINIC_CLP_RSP_DATA (HINIC_BAR01_CLP_OFFSET + 0x1000) #define HINIC_CLP_DATA(member) (HINIC_CLP_##member##_DATA) #define HINIC_CLP_SRAM_SIZE_OFFSET (16) #define HINIC_CLP_SRAM_BASE_OFFSET (0) #define HINIC_CLP_LEN_OFFSET (0) #define HINIC_CLP_START_OFFSET (31) #define HINIC_CLP_READY_OFFSET (31) #define HINIC_CLP_OFFSET(member) (HINIC_CLP_##member##_OFFSET) #define HINIC_CLP_SRAM_SIZE_BIT_LEN (0x7ffUL) #define HINIC_CLP_SRAM_BASE_BIT_LEN (0x7ffffffUL) #define HINIC_CLP_LEN_BIT_LEN (0x7ffUL) #define HINIC_CLP_START_BIT_LEN (0x1UL) #define HINIC_CLP_READY_BIT_LEN (0x1UL) #define HINIC_CLP_MASK(member) (HINIC_CLP_##member##_BIT_LEN) #define HINIC_CLP_DELAY_CNT_MAX (200UL) #define HINIC_CLP_SRAM_SIZE_REG_MAX (0x3ff) #define HINIC_CLP_SRAM_BASE_REG_MAX (0x7ffffff) #define HINIC_CLP_LEN_REG_MAX (0x3ff) #define HINIC_CLP_START_OR_READY_REG_MAX (0x1) enum hinic_msg_direction_type { HINIC_MSG_DIRECT_SEND = 0, HINIC_MSG_RESPONSE = 1 }; enum hinic_msg_segment_type { NOT_LAST_SEGMENT = 0, LAST_SEGMENT = 1, }; enum hinic_mgmt_msg_type { ASYNC_MGMT_MSG = 0, SYNC_MGMT_MSG = 1, }; enum hinic_msg_ack_type { HINIC_MSG_ACK = 0, HINIC_MSG_NO_ACK = 1, }; struct hinic_recv_msg { void *msg; struct completion recv_done; u16 msg_len; enum hinic_mod_type mod; u8 cmd; u8 seq_id; u16 msg_id; int async_mgmt_to_pf; }; #define HINIC_COMM_SELF_CMD_MAX 8 struct comm_up_self_msg_sub_info { u8 cmd; comm_up_self_msg_proc proc; }; struct comm_up_self_msg_info { u8 cmd_num; struct comm_up_self_msg_sub_info info[HINIC_COMM_SELF_CMD_MAX]; }; enum comm_pf_to_mgmt_event_state { SEND_EVENT_UNINIT = 0, SEND_EVENT_START, SEND_EVENT_FAIL, SEND_EVENT_TIMEOUT, SEND_EVENT_END, }; enum hinic_mgmt_msg_cb_state { HINIC_MGMT_MSG_CB_REG = 0, HINIC_MGMT_MSG_CB_RUNNING, }; struct hinic_clp_pf_to_mgmt { struct semaphore clp_msg_lock; void *clp_msg_buf; }; struct hinic_msg_pf_to_mgmt { struct hinic_hwdev *hwdev; /* Async cmd can not be scheduling */ spinlock_t async_msg_lock; struct semaphore sync_msg_lock; struct workqueue_struct *workq; void *async_msg_buf; void *sync_msg_buf; void *mgmt_ack_buf; struct hinic_recv_msg recv_msg_from_mgmt; struct hinic_recv_msg recv_resp_msg_from_mgmt; u16 async_msg_id; u16 sync_msg_id; struct hinic_api_cmd_chain *cmd_chain[HINIC_API_CMD_MAX]; hinic_mgmt_msg_cb recv_mgmt_msg_cb[HINIC_MOD_HW_MAX]; void *recv_mgmt_msg_data[HINIC_MOD_HW_MAX]; unsigned long mgmt_msg_cb_state[HINIC_MOD_HW_MAX]; void (*async_msg_cb[HINIC_MOD_HW_MAX])(void *handle, enum hinic_mgmt_cmd cmd, void *priv_data, u32 msg_id, void *buf_out, u32 out_size); void *async_msg_cb_data[HINIC_MOD_HW_MAX]; struct comm_up_self_msg_info proc; /* lock when sending msg */ spinlock_t sync_event_lock; enum comm_pf_to_mgmt_event_state event_flag; }; struct hinic_mgmt_msg_handle_work { struct work_struct work; struct hinic_msg_pf_to_mgmt *pf_to_mgmt; void *msg; u16 msg_len; enum hinic_mod_type mod; u8 cmd; u16 msg_id; int async_mgmt_to_pf; }; int hinic_pf_to_mgmt_no_ack(void *hwdev, enum hinic_mod_type mod, u8 cmd, void *buf_in, u16 in_size); void hinic_mgmt_msg_aeqe_handler(void *handle, u8 *header, u8 size); int hinic_pf_to_mgmt_init(struct hinic_hwdev *hwdev); void hinic_pf_to_mgmt_free(struct hinic_hwdev *hwdev); int hinic_pf_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_to_mgmt_async(void *hwdev, enum hinic_mod_type mod, u8 cmd, void *buf_in, u16 in_size); int hinic_pf_clp_to_mgmt(void *hwdev, enum hinic_mod_type mod, u8 cmd, const void *buf_in, u16 in_size, void *buf_out, u16 *out_size); int hinic_clp_pf_to_mgmt_init(struct hinic_hwdev *hwdev); void hinic_clp_pf_to_mgmt_free(struct hinic_hwdev *hwdev); #endif