1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* Huawei HiNIC PCI Express Linux driver |
3 | * Copyright(c) 2017 Huawei Technologies Co., Ltd |
4 | */ |
5 | |
6 | #ifndef HINIC_MBOX_H_ |
7 | #define HINIC_MBOX_H_ |
8 | |
9 | #define HINIC_MBOX_PF_SEND_ERR 0x1 |
10 | #define HINIC_MBOX_PF_BUSY_ACTIVE_FW 0x2 |
11 | #define HINIC_MBOX_VF_CMD_ERROR 0x3 |
12 | |
13 | #define HINIC_MAX_FUNCTIONS 512 |
14 | |
15 | #define HINIC_MAX_PF_FUNCS 16 |
16 | |
17 | #define HINIC_MBOX_WQ_NAME "hinic_mbox" |
18 | |
19 | #define HINIC_FUNC_CSR_MAILBOX_DATA_OFF 0x80 |
20 | #define HINIC_FUNC_CSR_MAILBOX_CONTROL_OFF 0x0100 |
21 | #define HINIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF 0x0104 |
22 | #define HINIC_FUNC_CSR_MAILBOX_RESULT_H_OFF 0x0108 |
23 | #define HINIC_FUNC_CSR_MAILBOX_RESULT_L_OFF 0x010C |
24 | |
25 | #define MAX_FUNCTION_NUM 512 |
26 | |
27 | struct vf_cmd_check_handle { |
28 | u8 cmd; |
29 | bool (*check_cmd)(struct hinic_hwdev *hwdev, u16 src_func_idx, |
30 | void *buf_in, u16 in_size); |
31 | }; |
32 | |
33 | enum hinic_mbox_ack_type { |
34 | MBOX_ACK, |
35 | MBOX_NO_ACK, |
36 | }; |
37 | |
38 | struct mbox_msg_info { |
39 | u8 msg_id; |
40 | u8 status; |
41 | }; |
42 | |
43 | struct hinic_recv_mbox { |
44 | struct completion recv_done; |
45 | void *mbox; |
46 | u8 cmd; |
47 | enum hinic_mod_type mod; |
48 | u16 mbox_len; |
49 | void *buf_out; |
50 | enum hinic_mbox_ack_type ack_type; |
51 | struct mbox_msg_info msg_info; |
52 | u8 seq_id; |
53 | atomic_t msg_cnt; |
54 | }; |
55 | |
56 | struct hinic_send_mbox { |
57 | struct completion send_done; |
58 | u8 *data; |
59 | |
60 | u64 *wb_status; |
61 | void *wb_vaddr; |
62 | dma_addr_t wb_paddr; |
63 | }; |
64 | |
65 | typedef void (*hinic_vf_mbox_cb)(void *handle, u8 cmd, void *buf_in, |
66 | u16 in_size, void *buf_out, u16 *out_size); |
67 | typedef int (*hinic_pf_mbox_cb)(void *handle, u16 vf_id, u8 cmd, void *buf_in, |
68 | u16 in_size, void *buf_out, u16 *out_size); |
69 | |
70 | enum mbox_event_state { |
71 | EVENT_START = 0, |
72 | EVENT_FAIL, |
73 | EVENT_TIMEOUT, |
74 | EVENT_END, |
75 | }; |
76 | |
77 | enum hinic_mbox_cb_state { |
78 | HINIC_VF_MBOX_CB_REG = 0, |
79 | HINIC_VF_MBOX_CB_RUNNING, |
80 | HINIC_PF_MBOX_CB_REG, |
81 | HINIC_PF_MBOX_CB_RUNNING, |
82 | HINIC_PPF_MBOX_CB_REG, |
83 | HINIC_PPF_MBOX_CB_RUNNING, |
84 | HINIC_PPF_TO_PF_MBOX_CB_REG, |
85 | HINIC_PPF_TO_PF_MBOX_CB_RUNNIG, |
86 | }; |
87 | |
88 | struct hinic_mbox_func_to_func { |
89 | struct hinic_hwdev *hwdev; |
90 | struct hinic_hwif *hwif; |
91 | |
92 | struct semaphore mbox_send_sem; |
93 | struct semaphore msg_send_sem; |
94 | struct hinic_send_mbox send_mbox; |
95 | |
96 | struct workqueue_struct *workq; |
97 | |
98 | struct hinic_recv_mbox mbox_resp[HINIC_MAX_FUNCTIONS]; |
99 | struct hinic_recv_mbox mbox_send[HINIC_MAX_FUNCTIONS]; |
100 | |
101 | hinic_vf_mbox_cb vf_mbox_cb[HINIC_MOD_MAX]; |
102 | hinic_pf_mbox_cb pf_mbox_cb[HINIC_MOD_MAX]; |
103 | unsigned long pf_mbox_cb_state[HINIC_MOD_MAX]; |
104 | unsigned long vf_mbox_cb_state[HINIC_MOD_MAX]; |
105 | |
106 | u8 send_msg_id; |
107 | enum mbox_event_state event_flag; |
108 | |
109 | /* lock for mbox event flag */ |
110 | spinlock_t mbox_lock; |
111 | |
112 | u32 vf_mbx_old_rand_id[MAX_FUNCTION_NUM]; |
113 | u32 vf_mbx_rand_id[MAX_FUNCTION_NUM]; |
114 | bool support_vf_random; |
115 | }; |
116 | |
117 | struct hinic_mbox_work { |
118 | struct work_struct work; |
119 | u16 src_func_idx; |
120 | struct hinic_mbox_func_to_func *func_to_func; |
121 | struct hinic_recv_mbox *recv_mbox; |
122 | }; |
123 | |
124 | struct vf_cmd_msg_handle { |
125 | u8 cmd; |
126 | int (*cmd_msg_handler)(void *hwdev, u16 vf_id, |
127 | void *buf_in, u16 in_size, |
128 | void *buf_out, u16 *out_size); |
129 | }; |
130 | |
131 | bool hinic_mbox_check_func_id_8B(struct hinic_hwdev *hwdev, u16 func_idx, |
132 | void *buf_in, u16 in_size); |
133 | |
134 | bool hinic_mbox_check_cmd_valid(struct hinic_hwdev *hwdev, |
135 | struct vf_cmd_check_handle *cmd_handle, |
136 | u16 vf_id, u8 cmd, void *buf_in, |
137 | u16 in_size, u8 size); |
138 | |
139 | int hinic_register_pf_mbox_cb(struct hinic_hwdev *hwdev, |
140 | enum hinic_mod_type mod, |
141 | hinic_pf_mbox_cb callback); |
142 | |
143 | int hinic_register_vf_mbox_cb(struct hinic_hwdev *hwdev, |
144 | enum hinic_mod_type mod, |
145 | hinic_vf_mbox_cb callback); |
146 | |
147 | void hinic_unregister_pf_mbox_cb(struct hinic_hwdev *hwdev, |
148 | enum hinic_mod_type mod); |
149 | |
150 | void hinic_unregister_vf_mbox_cb(struct hinic_hwdev *hwdev, |
151 | enum hinic_mod_type mod); |
152 | |
153 | int hinic_func_to_func_init(struct hinic_hwdev *hwdev); |
154 | |
155 | void hinic_func_to_func_free(struct hinic_hwdev *hwdev); |
156 | |
157 | int hinic_mbox_to_pf(struct hinic_hwdev *hwdev, enum hinic_mod_type mod, |
158 | u8 cmd, void *buf_in, u16 in_size, void *buf_out, |
159 | u16 *out_size, u32 timeout); |
160 | |
161 | int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, |
162 | enum hinic_mod_type mod, u16 cmd, u16 dst_func, |
163 | void *buf_in, u16 in_size, void *buf_out, |
164 | u16 *out_size, u32 timeout); |
165 | |
166 | int hinic_mbox_to_vf(struct hinic_hwdev *hwdev, |
167 | enum hinic_mod_type mod, u16 vf_id, u8 cmd, void *buf_in, |
168 | u16 in_size, void *buf_out, u16 *out_size, u32 timeout); |
169 | |
170 | int hinic_vf_mbox_random_id_init(struct hinic_hwdev *hwdev); |
171 | |
172 | #endif |
173 | |