xref: /f-stack/dpdk/drivers/net/ixgbe/base/ixgbe_mbx.c (revision 2d9fd380)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2001-2020 Intel Corporation
3  */
4 
5 #include "ixgbe_type.h"
6 #include "ixgbe_mbx.h"
7 
8 /**
9  * ixgbe_read_mbx - Reads a message from the mailbox
10  * @hw: pointer to the HW structure
11  * @msg: The message buffer
12  * @size: Length of buffer
13  * @mbx_id: id of mailbox to read
14  *
15  * returns SUCCESS if it successfully read message from buffer
16  **/
ixgbe_read_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)17 s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
18 {
19 	struct ixgbe_mbx_info *mbx = &hw->mbx;
20 	s32 ret_val = IXGBE_ERR_MBX;
21 
22 	DEBUGFUNC("ixgbe_read_mbx");
23 
24 	/* limit read to size of mailbox */
25 	if (size > mbx->size)
26 		size = mbx->size;
27 
28 	if (mbx->ops.read)
29 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
30 
31 	return ret_val;
32 }
33 
34 /**
35  * ixgbe_write_mbx - Write a message to the mailbox
36  * @hw: pointer to the HW structure
37  * @msg: The message buffer
38  * @size: Length of buffer
39  * @mbx_id: id of mailbox to write
40  *
41  * returns SUCCESS if it successfully copied message into the buffer
42  **/
ixgbe_write_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)43 s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
44 {
45 	struct ixgbe_mbx_info *mbx = &hw->mbx;
46 	s32 ret_val = IXGBE_SUCCESS;
47 
48 	DEBUGFUNC("ixgbe_write_mbx");
49 
50 	if (size > mbx->size) {
51 		ret_val = IXGBE_ERR_MBX;
52 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
53 			     "Invalid mailbox message size %d", size);
54 	} else if (mbx->ops.write)
55 		ret_val = mbx->ops.write(hw, msg, size, mbx_id);
56 
57 	return ret_val;
58 }
59 
60 /**
61  * ixgbe_check_for_msg - checks to see if someone sent us mail
62  * @hw: pointer to the HW structure
63  * @mbx_id: id of mailbox to check
64  *
65  * returns SUCCESS if the Status bit was found or else ERR_MBX
66  **/
ixgbe_check_for_msg(struct ixgbe_hw * hw,u16 mbx_id)67 s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
68 {
69 	struct ixgbe_mbx_info *mbx = &hw->mbx;
70 	s32 ret_val = IXGBE_ERR_MBX;
71 
72 	DEBUGFUNC("ixgbe_check_for_msg");
73 
74 	if (mbx->ops.check_for_msg)
75 		ret_val = mbx->ops.check_for_msg(hw, mbx_id);
76 
77 	return ret_val;
78 }
79 
80 /**
81  * ixgbe_check_for_ack - checks to see if someone sent us ACK
82  * @hw: pointer to the HW structure
83  * @mbx_id: id of mailbox to check
84  *
85  * returns SUCCESS if the Status bit was found or else ERR_MBX
86  **/
ixgbe_check_for_ack(struct ixgbe_hw * hw,u16 mbx_id)87 s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
88 {
89 	struct ixgbe_mbx_info *mbx = &hw->mbx;
90 	s32 ret_val = IXGBE_ERR_MBX;
91 
92 	DEBUGFUNC("ixgbe_check_for_ack");
93 
94 	if (mbx->ops.check_for_ack)
95 		ret_val = mbx->ops.check_for_ack(hw, mbx_id);
96 
97 	return ret_val;
98 }
99 
100 /**
101  * ixgbe_check_for_rst - checks to see if other side has reset
102  * @hw: pointer to the HW structure
103  * @mbx_id: id of mailbox to check
104  *
105  * returns SUCCESS if the Status bit was found or else ERR_MBX
106  **/
ixgbe_check_for_rst(struct ixgbe_hw * hw,u16 mbx_id)107 s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
108 {
109 	struct ixgbe_mbx_info *mbx = &hw->mbx;
110 	s32 ret_val = IXGBE_ERR_MBX;
111 
112 	DEBUGFUNC("ixgbe_check_for_rst");
113 
114 	if (mbx->ops.check_for_rst)
115 		ret_val = mbx->ops.check_for_rst(hw, mbx_id);
116 
117 	return ret_val;
118 }
119 
120 /**
121  * ixgbe_poll_for_msg - Wait for message notification
122  * @hw: pointer to the HW structure
123  * @mbx_id: id of mailbox to write
124  *
125  * returns SUCCESS if it successfully received a message notification
126  **/
ixgbe_poll_for_msg(struct ixgbe_hw * hw,u16 mbx_id)127 STATIC s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
128 {
129 	struct ixgbe_mbx_info *mbx = &hw->mbx;
130 	int countdown = mbx->timeout;
131 
132 	DEBUGFUNC("ixgbe_poll_for_msg");
133 
134 	if (!countdown || !mbx->ops.check_for_msg)
135 		goto out;
136 
137 	while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
138 		countdown--;
139 		if (!countdown)
140 			break;
141 		usec_delay(mbx->usec_delay);
142 	}
143 
144 	if (countdown == 0)
145 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
146 			   "Polling for VF%d mailbox message timedout", mbx_id);
147 
148 out:
149 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
150 }
151 
152 /**
153  * ixgbe_poll_for_ack - Wait for message acknowledgment
154  * @hw: pointer to the HW structure
155  * @mbx_id: id of mailbox to write
156  *
157  * returns SUCCESS if it successfully received a message acknowledgment
158  **/
ixgbe_poll_for_ack(struct ixgbe_hw * hw,u16 mbx_id)159 STATIC s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
160 {
161 	struct ixgbe_mbx_info *mbx = &hw->mbx;
162 	int countdown = mbx->timeout;
163 
164 	DEBUGFUNC("ixgbe_poll_for_ack");
165 
166 	if (!countdown || !mbx->ops.check_for_ack)
167 		goto out;
168 
169 	while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
170 		countdown--;
171 		if (!countdown)
172 			break;
173 		usec_delay(mbx->usec_delay);
174 	}
175 
176 	if (countdown == 0)
177 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
178 			     "Polling for VF%d mailbox ack timedout", mbx_id);
179 
180 out:
181 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
182 }
183 
184 /**
185  * ixgbe_read_posted_mbx - Wait for message notification and receive message
186  * @hw: pointer to the HW structure
187  * @msg: The message buffer
188  * @size: Length of buffer
189  * @mbx_id: id of mailbox to write
190  *
191  * returns SUCCESS if it successfully received a message notification and
192  * copied it into the receive buffer.
193  **/
ixgbe_read_posted_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)194 s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
195 {
196 	struct ixgbe_mbx_info *mbx = &hw->mbx;
197 	s32 ret_val = IXGBE_ERR_MBX;
198 
199 	DEBUGFUNC("ixgbe_read_posted_mbx");
200 
201 	if (!mbx->ops.read)
202 		goto out;
203 
204 	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
205 
206 	/* if ack received read message, otherwise we timed out */
207 	if (!ret_val)
208 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
209 out:
210 	return ret_val;
211 }
212 
213 /**
214  * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
215  * @hw: pointer to the HW structure
216  * @msg: The message buffer
217  * @size: Length of buffer
218  * @mbx_id: id of mailbox to write
219  *
220  * returns SUCCESS if it successfully copied message into the buffer and
221  * received an ack to that message within delay * timeout period
222  **/
ixgbe_write_posted_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)223 s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
224 			   u16 mbx_id)
225 {
226 	struct ixgbe_mbx_info *mbx = &hw->mbx;
227 	s32 ret_val = IXGBE_ERR_MBX;
228 
229 	DEBUGFUNC("ixgbe_write_posted_mbx");
230 
231 	/* exit if either we can't write or there isn't a defined timeout */
232 	if (!mbx->ops.write || !mbx->timeout)
233 		goto out;
234 
235 	/* send msg */
236 	ret_val = mbx->ops.write(hw, msg, size, mbx_id);
237 
238 	/* if msg sent wait until we receive an ack */
239 	if (!ret_val)
240 		ret_val = ixgbe_poll_for_ack(hw, mbx_id);
241 out:
242 	return ret_val;
243 }
244 
245 /**
246  * ixgbe_init_mbx_ops_generic - Initialize MB function pointers
247  * @hw: pointer to the HW structure
248  *
249  * Setups up the mailbox read and write message function pointers
250  **/
ixgbe_init_mbx_ops_generic(struct ixgbe_hw * hw)251 void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
252 {
253 	struct ixgbe_mbx_info *mbx = &hw->mbx;
254 
255 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
256 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
257 }
258 
259 /**
260  * ixgbe_read_v2p_mailbox - read v2p mailbox
261  * @hw: pointer to the HW structure
262  *
263  * This function is used to read the v2p mailbox without losing the read to
264  * clear status bits.
265  **/
ixgbe_read_v2p_mailbox(struct ixgbe_hw * hw)266 STATIC u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
267 {
268 	u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
269 
270 	v2p_mailbox |= hw->mbx.v2p_mailbox;
271 	hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
272 
273 	return v2p_mailbox;
274 }
275 
276 /**
277  * ixgbe_check_for_bit_vf - Determine if a status bit was set
278  * @hw: pointer to the HW structure
279  * @mask: bitmask for bits to be tested and cleared
280  *
281  * This function is used to check for the read to clear bits within
282  * the V2P mailbox.
283  **/
ixgbe_check_for_bit_vf(struct ixgbe_hw * hw,u32 mask)284 STATIC s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
285 {
286 	u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
287 	s32 ret_val = IXGBE_ERR_MBX;
288 
289 	if (v2p_mailbox & mask)
290 		ret_val = IXGBE_SUCCESS;
291 
292 	hw->mbx.v2p_mailbox &= ~mask;
293 
294 	return ret_val;
295 }
296 
297 /**
298  * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
299  * @hw: pointer to the HW structure
300  * @mbx_id: id of mailbox to check
301  *
302  * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
303  **/
ixgbe_check_for_msg_vf(struct ixgbe_hw * hw,u16 mbx_id)304 STATIC s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
305 {
306 	s32 ret_val = IXGBE_ERR_MBX;
307 
308 	UNREFERENCED_1PARAMETER(mbx_id);
309 	DEBUGFUNC("ixgbe_check_for_msg_vf");
310 
311 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
312 		ret_val = IXGBE_SUCCESS;
313 		hw->mbx.stats.reqs++;
314 	}
315 
316 	return ret_val;
317 }
318 
319 /**
320  * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
321  * @hw: pointer to the HW structure
322  * @mbx_id: id of mailbox to check
323  *
324  * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
325  **/
ixgbe_check_for_ack_vf(struct ixgbe_hw * hw,u16 mbx_id)326 STATIC s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
327 {
328 	s32 ret_val = IXGBE_ERR_MBX;
329 
330 	UNREFERENCED_1PARAMETER(mbx_id);
331 	DEBUGFUNC("ixgbe_check_for_ack_vf");
332 
333 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
334 		ret_val = IXGBE_SUCCESS;
335 		hw->mbx.stats.acks++;
336 	}
337 
338 	return ret_val;
339 }
340 
341 /**
342  * ixgbe_check_for_rst_vf - checks to see if the PF has reset
343  * @hw: pointer to the HW structure
344  * @mbx_id: id of mailbox to check
345  *
346  * returns true if the PF has set the reset done bit or else false
347  **/
ixgbe_check_for_rst_vf(struct ixgbe_hw * hw,u16 mbx_id)348 STATIC s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
349 {
350 	s32 ret_val = IXGBE_ERR_MBX;
351 
352 	UNREFERENCED_1PARAMETER(mbx_id);
353 	DEBUGFUNC("ixgbe_check_for_rst_vf");
354 
355 	if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
356 	    IXGBE_VFMAILBOX_RSTI))) {
357 		ret_val = IXGBE_SUCCESS;
358 		hw->mbx.stats.rsts++;
359 	}
360 
361 	return ret_val;
362 }
363 
364 /**
365  * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
366  * @hw: pointer to the HW structure
367  *
368  * return SUCCESS if we obtained the mailbox lock
369  **/
ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw * hw)370 STATIC s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
371 {
372 	s32 ret_val = IXGBE_ERR_MBX;
373 
374 	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
375 
376 	/* Take ownership of the buffer */
377 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
378 
379 	/* reserve mailbox for vf use */
380 	if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
381 		ret_val = IXGBE_SUCCESS;
382 
383 	return ret_val;
384 }
385 
386 /**
387  * ixgbe_write_mbx_vf - Write a message to the mailbox
388  * @hw: pointer to the HW structure
389  * @msg: The message buffer
390  * @size: Length of buffer
391  * @mbx_id: id of mailbox to write
392  *
393  * returns SUCCESS if it successfully copied message into the buffer
394  **/
ixgbe_write_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)395 STATIC s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
396 			      u16 mbx_id)
397 {
398 	s32 ret_val;
399 	u16 i;
400 
401 	UNREFERENCED_1PARAMETER(mbx_id);
402 
403 	DEBUGFUNC("ixgbe_write_mbx_vf");
404 
405 	/* lock the mailbox to prevent pf/vf race condition */
406 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
407 	if (ret_val)
408 		goto out_no_write;
409 
410 	/* flush msg and acks as we are overwriting the message buffer */
411 	ixgbe_check_for_msg_vf(hw, 0);
412 	ixgbe_check_for_ack_vf(hw, 0);
413 
414 	/* copy the caller specified message to the mailbox memory buffer */
415 	for (i = 0; i < size; i++)
416 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
417 
418 	/* update stats */
419 	hw->mbx.stats.msgs_tx++;
420 
421 	/* Drop VFU and interrupt the PF to tell it a message has been sent */
422 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
423 
424 out_no_write:
425 	return ret_val;
426 }
427 
428 /**
429  * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
430  * @hw: pointer to the HW structure
431  * @msg: The message buffer
432  * @size: Length of buffer
433  * @mbx_id: id of mailbox to read
434  *
435  * returns SUCCESS if it successfully read message from buffer
436  **/
ixgbe_read_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)437 STATIC s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
438 			     u16 mbx_id)
439 {
440 	s32 ret_val = IXGBE_SUCCESS;
441 	u16 i;
442 
443 	DEBUGFUNC("ixgbe_read_mbx_vf");
444 	UNREFERENCED_1PARAMETER(mbx_id);
445 
446 	/* lock the mailbox to prevent pf/vf race condition */
447 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
448 	if (ret_val)
449 		goto out_no_read;
450 
451 	/* copy the message from the mailbox memory buffer */
452 	for (i = 0; i < size; i++)
453 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
454 
455 	/* Acknowledge receipt and release mailbox, then we're done */
456 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
457 
458 	/* update stats */
459 	hw->mbx.stats.msgs_rx++;
460 
461 out_no_read:
462 	return ret_val;
463 }
464 
465 /**
466  * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
467  * @hw: pointer to the HW structure
468  *
469  * Initializes the hw->mbx struct to correct values for vf mailbox
470  */
ixgbe_init_mbx_params_vf(struct ixgbe_hw * hw)471 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
472 {
473 	struct ixgbe_mbx_info *mbx = &hw->mbx;
474 
475 	/* start mailbox as timed out and let the reset_hw call set the timeout
476 	 * value to begin communications */
477 	mbx->timeout = 0;
478 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
479 
480 	mbx->size = IXGBE_VFMAILBOX_SIZE;
481 
482 	mbx->ops.read = ixgbe_read_mbx_vf;
483 	mbx->ops.write = ixgbe_write_mbx_vf;
484 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
485 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
486 	mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
487 	mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
488 	mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
489 
490 	mbx->stats.msgs_tx = 0;
491 	mbx->stats.msgs_rx = 0;
492 	mbx->stats.reqs = 0;
493 	mbx->stats.acks = 0;
494 	mbx->stats.rsts = 0;
495 }
496 
ixgbe_check_for_bit_pf(struct ixgbe_hw * hw,u32 mask,s32 index)497 STATIC s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
498 {
499 	u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
500 	s32 ret_val = IXGBE_ERR_MBX;
501 
502 	if (mbvficr & mask) {
503 		ret_val = IXGBE_SUCCESS;
504 		IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
505 	}
506 
507 	return ret_val;
508 }
509 
510 /**
511  * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
512  * @hw: pointer to the HW structure
513  * @vf_number: the VF index
514  *
515  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
516  **/
ixgbe_check_for_msg_pf(struct ixgbe_hw * hw,u16 vf_number)517 STATIC s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
518 {
519 	s32 ret_val = IXGBE_ERR_MBX;
520 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
521 	u32 vf_bit = vf_number % 16;
522 
523 	DEBUGFUNC("ixgbe_check_for_msg_pf");
524 
525 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
526 				    index)) {
527 		ret_val = IXGBE_SUCCESS;
528 		hw->mbx.stats.reqs++;
529 	}
530 
531 	return ret_val;
532 }
533 
534 /**
535  * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
536  * @hw: pointer to the HW structure
537  * @vf_number: the VF index
538  *
539  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
540  **/
ixgbe_check_for_ack_pf(struct ixgbe_hw * hw,u16 vf_number)541 STATIC s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
542 {
543 	s32 ret_val = IXGBE_ERR_MBX;
544 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
545 	u32 vf_bit = vf_number % 16;
546 
547 	DEBUGFUNC("ixgbe_check_for_ack_pf");
548 
549 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
550 				    index)) {
551 		ret_val = IXGBE_SUCCESS;
552 		hw->mbx.stats.acks++;
553 	}
554 
555 	return ret_val;
556 }
557 
558 /**
559  * ixgbe_check_for_rst_pf - checks to see if the VF has reset
560  * @hw: pointer to the HW structure
561  * @vf_number: the VF index
562  *
563  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
564  **/
ixgbe_check_for_rst_pf(struct ixgbe_hw * hw,u16 vf_number)565 STATIC s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
566 {
567 	u32 reg_offset = (vf_number < 32) ? 0 : 1;
568 	u32 vf_shift = vf_number % 32;
569 	u32 vflre = 0;
570 	s32 ret_val = IXGBE_ERR_MBX;
571 
572 	DEBUGFUNC("ixgbe_check_for_rst_pf");
573 
574 	switch (hw->mac.type) {
575 	case ixgbe_mac_82599EB:
576 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
577 		break;
578 	case ixgbe_mac_X550:
579 	case ixgbe_mac_X550EM_x:
580 	case ixgbe_mac_X550EM_a:
581 	case ixgbe_mac_X540:
582 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
583 		break;
584 	default:
585 		break;
586 	}
587 
588 	if (vflre & (1 << vf_shift)) {
589 		ret_val = IXGBE_SUCCESS;
590 		IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
591 		hw->mbx.stats.rsts++;
592 	}
593 
594 	return ret_val;
595 }
596 
597 /**
598  * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
599  * @hw: pointer to the HW structure
600  * @vf_number: the VF index
601  *
602  * return SUCCESS if we obtained the mailbox lock
603  **/
ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw * hw,u16 vf_number)604 STATIC s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
605 {
606 	s32 ret_val = IXGBE_ERR_MBX;
607 	u32 p2v_mailbox;
608 
609 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
610 
611 	/* Take ownership of the buffer */
612 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
613 
614 	/* reserve mailbox for vf use */
615 	p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
616 	if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
617 		ret_val = IXGBE_SUCCESS;
618 	else
619 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
620 			   "Failed to obtain mailbox lock for VF%d", vf_number);
621 
622 
623 	return ret_val;
624 }
625 
626 /**
627  * ixgbe_write_mbx_pf - Places a message in the mailbox
628  * @hw: pointer to the HW structure
629  * @msg: The message buffer
630  * @size: Length of buffer
631  * @vf_number: the VF index
632  *
633  * returns SUCCESS if it successfully copied message into the buffer
634  **/
ixgbe_write_mbx_pf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_number)635 STATIC s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
636 			      u16 vf_number)
637 {
638 	s32 ret_val;
639 	u16 i;
640 
641 	DEBUGFUNC("ixgbe_write_mbx_pf");
642 
643 	/* lock the mailbox to prevent pf/vf race condition */
644 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
645 	if (ret_val)
646 		goto out_no_write;
647 
648 	/* flush msg and acks as we are overwriting the message buffer */
649 	ixgbe_check_for_msg_pf(hw, vf_number);
650 	ixgbe_check_for_ack_pf(hw, vf_number);
651 
652 	/* copy the caller specified message to the mailbox memory buffer */
653 	for (i = 0; i < size; i++)
654 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
655 
656 	/* Interrupt VF to tell it a message has been sent and release buffer*/
657 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
658 
659 	/* update stats */
660 	hw->mbx.stats.msgs_tx++;
661 
662 out_no_write:
663 	return ret_val;
664 
665 }
666 
667 /**
668  * ixgbe_read_mbx_pf - Read a message from the mailbox
669  * @hw: pointer to the HW structure
670  * @msg: The message buffer
671  * @size: Length of buffer
672  * @vf_number: the VF index
673  *
674  * This function copies a message from the mailbox buffer to the caller's
675  * memory buffer.  The presumption is that the caller knows that there was
676  * a message due to a VF request so no polling for message is needed.
677  **/
ixgbe_read_mbx_pf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_number)678 STATIC s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
679 			     u16 vf_number)
680 {
681 	s32 ret_val;
682 	u16 i;
683 
684 	DEBUGFUNC("ixgbe_read_mbx_pf");
685 
686 	/* lock the mailbox to prevent pf/vf race condition */
687 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
688 	if (ret_val)
689 		goto out_no_read;
690 
691 	/* copy the message to the mailbox memory buffer */
692 	for (i = 0; i < size; i++)
693 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
694 
695 	/* Acknowledge the message and release buffer */
696 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
697 
698 	/* update stats */
699 	hw->mbx.stats.msgs_rx++;
700 
701 out_no_read:
702 	return ret_val;
703 }
704 
705 /**
706  * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
707  * @hw: pointer to the HW structure
708  *
709  * Initializes the hw->mbx struct to correct values for pf mailbox
710  */
ixgbe_init_mbx_params_pf(struct ixgbe_hw * hw)711 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
712 {
713 	struct ixgbe_mbx_info *mbx = &hw->mbx;
714 
715 	if (hw->mac.type != ixgbe_mac_82599EB &&
716 	    hw->mac.type != ixgbe_mac_X550 &&
717 	    hw->mac.type != ixgbe_mac_X550EM_x &&
718 	    hw->mac.type != ixgbe_mac_X550EM_a &&
719 	    hw->mac.type != ixgbe_mac_X540)
720 		return;
721 
722 	mbx->timeout = 0;
723 	mbx->usec_delay = 0;
724 
725 	mbx->size = IXGBE_VFMAILBOX_SIZE;
726 
727 	mbx->ops.read = ixgbe_read_mbx_pf;
728 	mbx->ops.write = ixgbe_write_mbx_pf;
729 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
730 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
731 	mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
732 	mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
733 	mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
734 
735 	mbx->stats.msgs_tx = 0;
736 	mbx->stats.msgs_rx = 0;
737 	mbx->stats.reqs = 0;
738 	mbx->stats.acks = 0;
739 	mbx->stats.rsts = 0;
740 }
741