1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2015 - 2025 Beijing WangXun Technology Co., Ltd. */
3
4 #include <linux/pci.h>
5 #include "wx_type.h"
6 #include "wx_mbx.h"
7
8 /**
9 * wx_obtain_mbx_lock_pf - obtain mailbox lock
10 * @wx: pointer to the HW structure
11 * @vf: the VF index
12 *
13 * Return: return 0 on success and -EBUSY on failure
14 **/
wx_obtain_mbx_lock_pf(struct wx * wx,u16 vf)15 static int wx_obtain_mbx_lock_pf(struct wx *wx, u16 vf)
16 {
17 int count = 5;
18 u32 mailbox;
19
20 while (count--) {
21 /* Take ownership of the buffer */
22 wr32(wx, WX_PXMAILBOX(vf), WX_PXMAILBOX_PFU);
23
24 /* reserve mailbox for vf use */
25 mailbox = rd32(wx, WX_PXMAILBOX(vf));
26 if (mailbox & WX_PXMAILBOX_PFU)
27 return 0;
28 else if (count)
29 udelay(10);
30 }
31 wx_err(wx, "Failed to obtain mailbox lock for PF%d", vf);
32
33 return -EBUSY;
34 }
35
wx_check_for_bit_pf(struct wx * wx,u32 mask,int index)36 static int wx_check_for_bit_pf(struct wx *wx, u32 mask, int index)
37 {
38 u32 mbvficr = rd32(wx, WX_MBVFICR(index));
39
40 if (!(mbvficr & mask))
41 return -EBUSY;
42 wr32(wx, WX_MBVFICR(index), mask);
43
44 return 0;
45 }
46
47 /**
48 * wx_check_for_ack_pf - checks to see if the VF has acked
49 * @wx: pointer to the HW structure
50 * @vf: the VF index
51 *
52 * Return: return 0 if the VF has set the status bit or else -EBUSY
53 **/
wx_check_for_ack_pf(struct wx * wx,u16 vf)54 int wx_check_for_ack_pf(struct wx *wx, u16 vf)
55 {
56 u32 index = vf / 16, vf_bit = vf % 16;
57
58 return wx_check_for_bit_pf(wx,
59 FIELD_PREP(WX_MBVFICR_VFACK_MASK,
60 BIT(vf_bit)),
61 index);
62 }
63
64 /**
65 * wx_check_for_msg_pf - checks to see if the VF has sent mail
66 * @wx: pointer to the HW structure
67 * @vf: the VF index
68 *
69 * Return: return 0 if the VF has got req bit or else -EBUSY
70 **/
wx_check_for_msg_pf(struct wx * wx,u16 vf)71 int wx_check_for_msg_pf(struct wx *wx, u16 vf)
72 {
73 u32 index = vf / 16, vf_bit = vf % 16;
74
75 return wx_check_for_bit_pf(wx,
76 FIELD_PREP(WX_MBVFICR_VFREQ_MASK,
77 BIT(vf_bit)),
78 index);
79 }
80
81 /**
82 * wx_write_mbx_pf - Places a message in the mailbox
83 * @wx: pointer to the HW structure
84 * @msg: The message buffer
85 * @size: Length of buffer
86 * @vf: the VF index
87 *
88 * Return: return 0 on success and -EINVAL/-EBUSY on failure
89 **/
wx_write_mbx_pf(struct wx * wx,u32 * msg,u16 size,u16 vf)90 int wx_write_mbx_pf(struct wx *wx, u32 *msg, u16 size, u16 vf)
91 {
92 struct wx_mbx_info *mbx = &wx->mbx;
93 int ret, i;
94
95 /* mbx->size is up to 15 */
96 if (size > mbx->size) {
97 wx_err(wx, "Invalid mailbox message size %d", size);
98 return -EINVAL;
99 }
100
101 /* lock the mailbox to prevent pf/vf race condition */
102 ret = wx_obtain_mbx_lock_pf(wx, vf);
103 if (ret)
104 return ret;
105
106 /* flush msg and acks as we are overwriting the message buffer */
107 wx_check_for_msg_pf(wx, vf);
108 wx_check_for_ack_pf(wx, vf);
109
110 /* copy the caller specified message to the mailbox memory buffer */
111 for (i = 0; i < size; i++)
112 wr32a(wx, WX_PXMBMEM(vf), i, msg[i]);
113
114 /* Interrupt VF to tell it a message has been sent and release buffer */
115 /* set mirrored mailbox flags */
116 wr32a(wx, WX_PXMBMEM(vf), WX_VXMAILBOX_SIZE, WX_PXMAILBOX_STS);
117 wr32(wx, WX_PXMAILBOX(vf), WX_PXMAILBOX_STS);
118
119 return 0;
120 }
121
122 /**
123 * wx_read_mbx_pf - Read a message from the mailbox
124 * @wx: pointer to the HW structure
125 * @msg: The message buffer
126 * @size: Length of buffer
127 * @vf: the VF index
128 *
129 * Return: return 0 on success and -EBUSY on failure
130 **/
wx_read_mbx_pf(struct wx * wx,u32 * msg,u16 size,u16 vf)131 int wx_read_mbx_pf(struct wx *wx, u32 *msg, u16 size, u16 vf)
132 {
133 struct wx_mbx_info *mbx = &wx->mbx;
134 int ret;
135 u16 i;
136
137 /* limit read to size of mailbox and mbx->size is up to 15 */
138 if (size > mbx->size)
139 size = mbx->size;
140
141 /* lock the mailbox to prevent pf/vf race condition */
142 ret = wx_obtain_mbx_lock_pf(wx, vf);
143 if (ret)
144 return ret;
145
146 for (i = 0; i < size; i++)
147 msg[i] = rd32a(wx, WX_PXMBMEM(vf), i);
148
149 /* Acknowledge the message and release buffer */
150 /* set mirrored mailbox flags */
151 wr32a(wx, WX_PXMBMEM(vf), WX_VXMAILBOX_SIZE, WX_PXMAILBOX_ACK);
152 wr32(wx, WX_PXMAILBOX(vf), WX_PXMAILBOX_ACK);
153
154 return 0;
155 }
156
157 /**
158 * wx_check_for_rst_pf - checks to see if the VF has reset
159 * @wx: pointer to the HW structure
160 * @vf: the VF index
161 *
162 * Return: return 0 on success and -EBUSY on failure
163 **/
wx_check_for_rst_pf(struct wx * wx,u16 vf)164 int wx_check_for_rst_pf(struct wx *wx, u16 vf)
165 {
166 u32 reg_offset = WX_VF_REG_OFFSET(vf);
167 u32 vf_shift = WX_VF_IND_SHIFT(vf);
168 u32 vflre = 0;
169
170 vflre = rd32(wx, WX_VFLRE(reg_offset));
171 if (!(vflre & BIT(vf_shift)))
172 return -EBUSY;
173 wr32(wx, WX_VFLREC(reg_offset), BIT(vf_shift));
174
175 return 0;
176 }
177
wx_read_v2p_mailbox(struct wx * wx)178 static u32 wx_read_v2p_mailbox(struct wx *wx)
179 {
180 u32 mailbox = rd32(wx, WX_VXMAILBOX);
181
182 mailbox |= wx->mbx.mailbox;
183 wx->mbx.mailbox |= mailbox & WX_VXMAILBOX_R2C_BITS;
184
185 return mailbox;
186 }
187
wx_mailbox_get_lock_vf(struct wx * wx)188 static u32 wx_mailbox_get_lock_vf(struct wx *wx)
189 {
190 wr32(wx, WX_VXMAILBOX, WX_VXMAILBOX_VFU);
191 return wx_read_v2p_mailbox(wx);
192 }
193
194 /**
195 * wx_obtain_mbx_lock_vf - obtain mailbox lock
196 * @wx: pointer to the HW structure
197 *
198 * Return: return 0 on success and -EBUSY on failure
199 **/
wx_obtain_mbx_lock_vf(struct wx * wx)200 static int wx_obtain_mbx_lock_vf(struct wx *wx)
201 {
202 int count = 5, ret;
203 u32 mailbox;
204
205 ret = readx_poll_timeout_atomic(wx_mailbox_get_lock_vf, wx, mailbox,
206 (mailbox & WX_VXMAILBOX_VFU),
207 1, count);
208 if (ret)
209 wx_err(wx, "Failed to obtain mailbox lock for VF.\n");
210
211 return ret;
212 }
213
wx_check_for_bit_vf(struct wx * wx,u32 mask)214 static int wx_check_for_bit_vf(struct wx *wx, u32 mask)
215 {
216 u32 mailbox = wx_read_v2p_mailbox(wx);
217
218 wx->mbx.mailbox &= ~mask;
219
220 return (mailbox & mask ? 0 : -EBUSY);
221 }
222
223 /**
224 * wx_check_for_ack_vf - checks to see if the PF has ACK'd
225 * @wx: pointer to the HW structure
226 *
227 * Return: return 0 if the PF has set the status bit or else -EBUSY
228 **/
wx_check_for_ack_vf(struct wx * wx)229 static int wx_check_for_ack_vf(struct wx *wx)
230 {
231 /* read clear the pf ack bit */
232 return wx_check_for_bit_vf(wx, WX_VXMAILBOX_PFACK);
233 }
234
235 /**
236 * wx_check_for_msg_vf - checks to see if the PF has sent mail
237 * @wx: pointer to the HW structure
238 *
239 * Return: return 0 if the PF has got req bit or else -EBUSY
240 **/
wx_check_for_msg_vf(struct wx * wx)241 int wx_check_for_msg_vf(struct wx *wx)
242 {
243 /* read clear the pf sts bit */
244 return wx_check_for_bit_vf(wx, WX_VXMAILBOX_PFSTS);
245 }
246
247 /**
248 * wx_check_for_rst_vf - checks to see if the PF has reset
249 * @wx: pointer to the HW structure
250 *
251 * Return: return 0 if the PF has set the reset done and -EBUSY on failure
252 **/
wx_check_for_rst_vf(struct wx * wx)253 int wx_check_for_rst_vf(struct wx *wx)
254 {
255 /* read clear the pf reset done bit */
256 return wx_check_for_bit_vf(wx,
257 WX_VXMAILBOX_RSTD |
258 WX_VXMAILBOX_RSTI);
259 }
260
261 /**
262 * wx_poll_for_msg - Wait for message notification
263 * @wx: pointer to the HW structure
264 *
265 * Return: return 0 if the VF has successfully received a message notification
266 **/
wx_poll_for_msg(struct wx * wx)267 static int wx_poll_for_msg(struct wx *wx)
268 {
269 struct wx_mbx_info *mbx = &wx->mbx;
270 u32 val;
271
272 return readx_poll_timeout_atomic(wx_check_for_msg_vf, wx, val,
273 (val == 0), mbx->udelay, mbx->timeout);
274 }
275
276 /**
277 * wx_poll_for_ack - Wait for message acknowledgment
278 * @wx: pointer to the HW structure
279 *
280 * Return: return 0 if the VF has successfully received a message ack
281 **/
wx_poll_for_ack(struct wx * wx)282 static int wx_poll_for_ack(struct wx *wx)
283 {
284 struct wx_mbx_info *mbx = &wx->mbx;
285 u32 val;
286
287 return readx_poll_timeout_atomic(wx_check_for_ack_vf, wx, val,
288 (val == 0), mbx->udelay, mbx->timeout);
289 }
290
291 /**
292 * wx_read_posted_mbx - Wait for message notification and receive message
293 * @wx: pointer to the HW structure
294 * @msg: The message buffer
295 * @size: Length of buffer
296 *
297 * Return: returns 0 if it successfully received a message notification and
298 * copied it into the receive buffer.
299 **/
wx_read_posted_mbx(struct wx * wx,u32 * msg,u16 size)300 int wx_read_posted_mbx(struct wx *wx, u32 *msg, u16 size)
301 {
302 int ret;
303
304 ret = wx_poll_for_msg(wx);
305 /* if ack received read message, otherwise we timed out */
306 if (ret)
307 return ret;
308
309 return wx_read_mbx_vf(wx, msg, size);
310 }
311
312 /**
313 * wx_write_posted_mbx - Write a message to the mailbox, wait for ack
314 * @wx: pointer to the HW structure
315 * @msg: The message buffer
316 * @size: Length of buffer
317 *
318 * Return: returns 0 if it successfully copied message into the buffer and
319 * received an ack to that message within delay * timeout period
320 **/
wx_write_posted_mbx(struct wx * wx,u32 * msg,u16 size)321 int wx_write_posted_mbx(struct wx *wx, u32 *msg, u16 size)
322 {
323 int ret;
324
325 /* send msg */
326 ret = wx_write_mbx_vf(wx, msg, size);
327 /* if msg sent wait until we receive an ack */
328 if (ret)
329 return ret;
330
331 return wx_poll_for_ack(wx);
332 }
333
334 /**
335 * wx_write_mbx_vf - Write a message to the mailbox
336 * @wx: pointer to the HW structure
337 * @msg: The message buffer
338 * @size: Length of buffer
339 *
340 * Return: returns 0 if it successfully copied message into the buffer
341 **/
wx_write_mbx_vf(struct wx * wx,u32 * msg,u16 size)342 int wx_write_mbx_vf(struct wx *wx, u32 *msg, u16 size)
343 {
344 struct wx_mbx_info *mbx = &wx->mbx;
345 int ret, i;
346
347 /* mbx->size is up to 15 */
348 if (size > mbx->size) {
349 wx_err(wx, "Invalid mailbox message size %d", size);
350 return -EINVAL;
351 }
352
353 /* lock the mailbox to prevent pf/vf race condition */
354 ret = wx_obtain_mbx_lock_vf(wx);
355 if (ret)
356 return ret;
357
358 /* flush msg and acks as we are overwriting the message buffer */
359 wx_check_for_msg_vf(wx);
360 wx_check_for_ack_vf(wx);
361
362 /* copy the caller specified message to the mailbox memory buffer */
363 for (i = 0; i < size; i++)
364 wr32a(wx, WX_VXMBMEM, i, msg[i]);
365
366 /* Drop VFU and interrupt the PF to tell it a message has been sent */
367 wr32(wx, WX_VXMAILBOX, WX_VXMAILBOX_REQ);
368
369 return 0;
370 }
371
372 /**
373 * wx_read_mbx_vf - Reads a message from the inbox intended for vf
374 * @wx: pointer to the HW structure
375 * @msg: The message buffer
376 * @size: Length of buffer
377 *
378 * Return: returns 0 if it successfully copied message into the buffer
379 **/
wx_read_mbx_vf(struct wx * wx,u32 * msg,u16 size)380 int wx_read_mbx_vf(struct wx *wx, u32 *msg, u16 size)
381 {
382 struct wx_mbx_info *mbx = &wx->mbx;
383 int ret, i;
384
385 /* limit read to size of mailbox and mbx->size is up to 15 */
386 if (size > mbx->size)
387 size = mbx->size;
388
389 /* lock the mailbox to prevent pf/vf race condition */
390 ret = wx_obtain_mbx_lock_vf(wx);
391 if (ret)
392 return ret;
393
394 /* copy the message from the mailbox memory buffer */
395 for (i = 0; i < size; i++)
396 msg[i] = rd32a(wx, WX_VXMBMEM, i);
397
398 /* Acknowledge receipt and release mailbox, then we're done */
399 wr32(wx, WX_VXMAILBOX, WX_VXMAILBOX_ACK);
400
401 return 0;
402 }
403
wx_init_mbx_params_vf(struct wx * wx)404 int wx_init_mbx_params_vf(struct wx *wx)
405 {
406 wx->vfinfo = kzalloc(sizeof(struct vf_data_storage),
407 GFP_KERNEL);
408 if (!wx->vfinfo)
409 return -ENOMEM;
410
411 /* Initialize mailbox parameters */
412 wx->mbx.size = WX_VXMAILBOX_SIZE;
413 wx->mbx.mailbox = WX_VXMAILBOX;
414 wx->mbx.udelay = 10;
415 wx->mbx.timeout = 1000;
416
417 return 0;
418 }
419 EXPORT_SYMBOL(wx_init_mbx_params_vf);
420