/* 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 
 |