| /* SPDX-License-Identifier: GPL-2.0-only */ |
| /* Huawei HiNIC PCI Express Linux driver |
| * Copyright(c) 2017 Huawei Technologies Co., Ltd |
| */ |
| |
| #ifndef HINIC_MBOX_H_ |
| #define HINIC_MBOX_H_ |
| |
| #define HINIC_MBOX_PF_SEND_ERR 0x1 |
| #define HINIC_MBOX_PF_BUSY_ACTIVE_FW 0x2 |
| #define HINIC_MBOX_VF_CMD_ERROR 0x3 |
| |
| #define HINIC_MAX_FUNCTIONS 512 |
| |
| #define HINIC_MAX_PF_FUNCS 16 |
| |
| #define HINIC_MBOX_WQ_NAME "hinic_mbox" |
| |
| #define HINIC_FUNC_CSR_MAILBOX_DATA_OFF 0x80 |
| #define HINIC_FUNC_CSR_MAILBOX_CONTROL_OFF 0x0100 |
| #define HINIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF 0x0104 |
| #define HINIC_FUNC_CSR_MAILBOX_RESULT_H_OFF 0x0108 |
| #define HINIC_FUNC_CSR_MAILBOX_RESULT_L_OFF 0x010C |
| |
| #define MAX_FUNCTION_NUM 512 |
| |
| struct vf_cmd_check_handle { |
| u8 cmd; |
| bool (*check_cmd)(struct hinic_hwdev *hwdev, u16 src_func_idx, |
| void *buf_in, u16 in_size); |
| }; |
| |
| enum hinic_mbox_ack_type { |
| MBOX_ACK, |
| MBOX_NO_ACK, |
| }; |
| |
| struct mbox_msg_info { |
| u8 msg_id; |
| u8 status; |
| }; |
| |
| struct hinic_recv_mbox { |
| struct completion recv_done; |
| void *mbox; |
| u8 cmd; |
| enum hinic_mod_type mod; |
| u16 mbox_len; |
| void *buf_out; |
| enum hinic_mbox_ack_type ack_type; |
| struct mbox_msg_info msg_info; |
| u8 seq_id; |
| atomic_t msg_cnt; |
| }; |
| |
| struct hinic_send_mbox { |
| struct completion send_done; |
| u8 *data; |
| |
| u64 *wb_status; |
| void *wb_vaddr; |
| dma_addr_t wb_paddr; |
| }; |
| |
| typedef void (*hinic_vf_mbox_cb)(void *handle, u8 cmd, void *buf_in, |
| u16 in_size, void *buf_out, u16 *out_size); |
| typedef int (*hinic_pf_mbox_cb)(void *handle, u16 vf_id, u8 cmd, void *buf_in, |
| u16 in_size, void *buf_out, u16 *out_size); |
| |
| enum mbox_event_state { |
| EVENT_START = 0, |
| EVENT_FAIL, |
| EVENT_TIMEOUT, |
| EVENT_END, |
| }; |
| |
| enum hinic_mbox_cb_state { |
| HINIC_VF_MBOX_CB_REG = 0, |
| HINIC_VF_MBOX_CB_RUNNING, |
| HINIC_PF_MBOX_CB_REG, |
| HINIC_PF_MBOX_CB_RUNNING, |
| HINIC_PPF_MBOX_CB_REG, |
| HINIC_PPF_MBOX_CB_RUNNING, |
| HINIC_PPF_TO_PF_MBOX_CB_REG, |
| HINIC_PPF_TO_PF_MBOX_CB_RUNNIG, |
| }; |
| |
| struct hinic_mbox_func_to_func { |
| struct hinic_hwdev *hwdev; |
| struct hinic_hwif *hwif; |
| |
| struct semaphore mbox_send_sem; |
| struct semaphore msg_send_sem; |
| struct hinic_send_mbox send_mbox; |
| |
| struct workqueue_struct *workq; |
| |
| struct hinic_recv_mbox mbox_resp[HINIC_MAX_FUNCTIONS]; |
| struct hinic_recv_mbox mbox_send[HINIC_MAX_FUNCTIONS]; |
| |
| hinic_vf_mbox_cb vf_mbox_cb[HINIC_MOD_MAX]; |
| hinic_pf_mbox_cb pf_mbox_cb[HINIC_MOD_MAX]; |
| unsigned long pf_mbox_cb_state[HINIC_MOD_MAX]; |
| unsigned long vf_mbox_cb_state[HINIC_MOD_MAX]; |
| |
| u8 send_msg_id; |
| enum mbox_event_state event_flag; |
| |
| /* lock for mbox event flag */ |
| spinlock_t mbox_lock; |
| |
| u32 vf_mbx_old_rand_id[MAX_FUNCTION_NUM]; |
| u32 vf_mbx_rand_id[MAX_FUNCTION_NUM]; |
| bool support_vf_random; |
| }; |
| |
| struct hinic_mbox_work { |
| struct work_struct work; |
| u16 src_func_idx; |
| struct hinic_mbox_func_to_func *func_to_func; |
| struct hinic_recv_mbox *recv_mbox; |
| }; |
| |
| struct vf_cmd_msg_handle { |
| u8 cmd; |
| int (*cmd_msg_handler)(void *hwdev, u16 vf_id, |
| void *buf_in, u16 in_size, |
| void *buf_out, u16 *out_size); |
| }; |
| |
| bool hinic_mbox_check_func_id_8B(struct hinic_hwdev *hwdev, u16 func_idx, |
| void *buf_in, u16 in_size); |
| |
| bool hinic_mbox_check_cmd_valid(struct hinic_hwdev *hwdev, |
| struct vf_cmd_check_handle *cmd_handle, |
| u16 vf_id, u8 cmd, void *buf_in, |
| u16 in_size, u8 size); |
| |
| int hinic_register_pf_mbox_cb(struct hinic_hwdev *hwdev, |
| enum hinic_mod_type mod, |
| hinic_pf_mbox_cb callback); |
| |
| int hinic_register_vf_mbox_cb(struct hinic_hwdev *hwdev, |
| enum hinic_mod_type mod, |
| hinic_vf_mbox_cb callback); |
| |
| void hinic_unregister_pf_mbox_cb(struct hinic_hwdev *hwdev, |
| enum hinic_mod_type mod); |
| |
| void hinic_unregister_vf_mbox_cb(struct hinic_hwdev *hwdev, |
| enum hinic_mod_type mod); |
| |
| void hinic_mbox_func_aeqe_handler(void *handle, void *header, u8 size); |
| |
| void hinic_mbox_self_aeqe_handler(void *handle, void *header, u8 size); |
| |
| int hinic_func_to_func_init(struct hinic_hwdev *hwdev); |
| |
| void hinic_func_to_func_free(struct hinic_hwdev *hwdev); |
| |
| int hinic_mbox_to_pf(struct hinic_hwdev *hwdev, enum hinic_mod_type mod, |
| u8 cmd, void *buf_in, u16 in_size, void *buf_out, |
| u16 *out_size, u32 timeout); |
| |
| int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, |
| enum hinic_mod_type mod, u16 cmd, u16 dst_func, |
| void *buf_in, u16 in_size, void *buf_out, |
| u16 *out_size, u32 timeout); |
| |
| int hinic_mbox_to_vf(struct hinic_hwdev *hwdev, |
| enum hinic_mod_type mod, u16 vf_id, u8 cmd, void *buf_in, |
| u16 in_size, void *buf_out, u16 *out_size, u32 timeout); |
| |
| int hinic_vf_mbox_random_id_init(struct hinic_hwdev *hwdev); |
| |
| #endif |