xref: /freebsd/sys/dev/ixgbe/ixgbe_mbx.c (revision 7937bfbc0ca53fe7cdd0d54414f9296e273a518e)
1 /******************************************************************************
2   SPDX-License-Identifier: BSD-3-Clause
3 
4   Copyright (c) 2001-2020, Intel Corporation
5   All rights reserved.
6 
7   Redistribution and use in source and binary forms, with or without
8   modification, are permitted provided that the following conditions are met:
9 
10    1. Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12 
13    2. Redistributions in binary form must reproduce the above copyright
14       notice, this list of conditions and the following disclaimer in the
15       documentation and/or other materials provided with the distribution.
16 
17    3. Neither the name of the Intel Corporation nor the names of its
18       contributors may be used to endorse or promote products derived from
19       this software without specific prior written permission.
20 
21   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31   POSSIBILITY OF SUCH DAMAGE.
32 
33 ******************************************************************************/
34 
35 #include "ixgbe_type.h"
36 #include "ixgbe_mbx.h"
37 
38 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id);
39 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id);
40 
41 /**
42  * ixgbe_read_mbx - Reads a message from the mailbox
43  * @hw: pointer to the HW structure
44  * @msg: The message buffer
45  * @size: Length of buffer
46  * @mbx_id: id of mailbox to read
47  *
48  * returns SUCCESS if it successfully read message from buffer
49  **/
50 s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
51 {
52 	struct ixgbe_mbx_info *mbx = &hw->mbx;
53 
54 	DEBUGFUNC("ixgbe_read_mbx");
55 
56 	/* limit read to size of mailbox */
57 	if (size > mbx->size) {
58 		ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
59 			      "Invalid mailbox message size %u, changing to %u",
60 			      size, mbx->size);
61 		size = mbx->size;
62 	}
63 
64 	if (mbx->ops[mbx_id].read)
65 		return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
66 
67 	return IXGBE_ERR_CONFIG;
68 }
69 
70 /**
71  * ixgbe_poll_mbx - Wait for message and read it from the mailbox
72  * @hw: pointer to the HW structure
73  * @msg: The message buffer
74  * @size: Length of buffer
75  * @mbx_id: id of mailbox to read
76  *
77  * returns SUCCESS if it successfully read message from buffer
78  **/
79 s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
80 {
81 	struct ixgbe_mbx_info *mbx = &hw->mbx;
82 	s32 ret_val;
83 
84 	DEBUGFUNC("ixgbe_poll_mbx");
85 
86 	if (!mbx->ops[mbx_id].read || !mbx->ops[mbx_id].check_for_msg ||
87 	    !mbx->timeout)
88 		return IXGBE_ERR_CONFIG;
89 
90 	/* limit read to size of mailbox */
91 	if (size > mbx->size) {
92 		ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
93 			      "Invalid mailbox message size %u, changing to %u",
94 			      size, mbx->size);
95 		size = mbx->size;
96 	}
97 
98 	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
99 	/* if ack received read message, otherwise we timed out */
100 	if (!ret_val)
101 		return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
102 
103 	return ret_val;
104 }
105 
106 /**
107  * ixgbe_write_mbx - Write a message to the mailbox and wait for ACK
108  * @hw: pointer to the HW structure
109  * @msg: The message buffer
110  * @size: Length of buffer
111  * @mbx_id: id of mailbox to write
112  *
113  * returns SUCCESS if it successfully copied message into the buffer and
114  * received an ACK to that message within specified period
115  **/
116 s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
117 {
118 	struct ixgbe_mbx_info *mbx = &hw->mbx;
119 	s32 ret_val = IXGBE_ERR_MBX;
120 
121 	DEBUGFUNC("ixgbe_write_mbx");
122 
123 	/*
124 	 * exit if either we can't write, release
125 	 * or there is no timeout defined
126 	 */
127 	if (!mbx->ops[mbx_id].write || !mbx->ops[mbx_id].check_for_ack ||
128 	    !mbx->ops[mbx_id].release || !mbx->timeout)
129 		return IXGBE_ERR_CONFIG;
130 
131 	if (size > mbx->size) {
132 		ret_val = IXGBE_ERR_PARAM;
133 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
134 			     "Invalid mailbox message size %u", size);
135 	} else {
136 		ret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id);
137 	}
138 
139 	return ret_val;
140 }
141 
142 /**
143  * ixgbe_check_for_msg - checks to see if someone sent us mail
144  * @hw: pointer to the HW structure
145  * @mbx_id: id of mailbox to check
146  *
147  * returns SUCCESS if the Status bit was found or else ERR_MBX
148  **/
149 s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
150 {
151 	struct ixgbe_mbx_info *mbx = &hw->mbx;
152 	s32 ret_val = IXGBE_ERR_CONFIG;
153 
154 	DEBUGFUNC("ixgbe_check_for_msg");
155 
156 	if (mbx->ops[mbx_id].check_for_msg)
157 		ret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id);
158 
159 	return ret_val;
160 }
161 
162 /**
163  * ixgbe_check_for_ack - checks to see if someone sent us ACK
164  * @hw: pointer to the HW structure
165  * @mbx_id: id of mailbox to check
166  *
167  * returns SUCCESS if the Status bit was found or else ERR_MBX
168  **/
169 s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
170 {
171 	struct ixgbe_mbx_info *mbx = &hw->mbx;
172 	s32 ret_val = IXGBE_ERR_CONFIG;
173 
174 	DEBUGFUNC("ixgbe_check_for_ack");
175 
176 	if (mbx->ops[mbx_id].check_for_ack)
177 		ret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id);
178 
179 	return ret_val;
180 }
181 
182 /**
183  * ixgbe_check_for_rst - checks to see if other side has reset
184  * @hw: pointer to the HW structure
185  * @mbx_id: id of mailbox to check
186  *
187  * returns SUCCESS if the Status bit was found or else ERR_MBX
188  **/
189 s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
190 {
191 	struct ixgbe_mbx_info *mbx = &hw->mbx;
192 	s32 ret_val = IXGBE_ERR_CONFIG;
193 
194 	DEBUGFUNC("ixgbe_check_for_rst");
195 
196 	if (mbx->ops[mbx_id].check_for_rst)
197 		ret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id);
198 
199 	return ret_val;
200 }
201 
202 /**
203  * ixgbe_clear_mbx - Clear Mailbox Memory
204  * @hw: pointer to the HW structure
205  * @mbx_id: id of mailbox to write
206  *
207  * Set VFMBMEM of given VF to 0x0.
208  **/
209 s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 mbx_id)
210 {
211 	struct ixgbe_mbx_info *mbx = &hw->mbx;
212 	s32 ret_val = IXGBE_ERR_CONFIG;
213 
214 	DEBUGFUNC("ixgbe_clear_mbx");
215 
216 	if (mbx->ops[mbx_id].clear)
217 		ret_val = mbx->ops[mbx_id].clear(hw, mbx_id);
218 
219 	return ret_val;
220 }
221 
222 /**
223  * ixgbe_poll_for_msg - Wait for message notification
224  * @hw: pointer to the HW structure
225  * @mbx_id: id of mailbox to write
226  *
227  * returns SUCCESS if it successfully received a message notification
228  **/
229 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
230 {
231 	struct ixgbe_mbx_info *mbx = &hw->mbx;
232 	int countdown = mbx->timeout;
233 
234 	DEBUGFUNC("ixgbe_poll_for_msg");
235 
236 	if (!countdown || !mbx->ops[mbx_id].check_for_msg)
237 		return IXGBE_ERR_CONFIG;
238 
239 	while (countdown && mbx->ops[mbx_id].check_for_msg(hw, mbx_id)) {
240 		countdown--;
241 		if (!countdown)
242 			break;
243 		usec_delay(mbx->usec_delay);
244 	}
245 
246 	if (countdown == 0) {
247 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
248 			   "Polling for VF%u mailbox message timedout", mbx_id);
249 		return IXGBE_ERR_TIMEOUT;
250 	}
251 
252 	return IXGBE_SUCCESS;
253 }
254 
255 /**
256  * ixgbe_poll_for_ack - Wait for message acknowledgment
257  * @hw: pointer to the HW structure
258  * @mbx_id: id of mailbox to write
259  *
260  * returns SUCCESS if it successfully received a message acknowledgment
261  **/
262 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
263 {
264 	struct ixgbe_mbx_info *mbx = &hw->mbx;
265 	int countdown = mbx->timeout;
266 
267 	DEBUGFUNC("ixgbe_poll_for_ack");
268 
269 	if (!countdown || !mbx->ops[mbx_id].check_for_ack)
270 		return IXGBE_ERR_CONFIG;
271 
272 	while (countdown && mbx->ops[mbx_id].check_for_ack(hw, mbx_id)) {
273 		countdown--;
274 		if (!countdown)
275 			break;
276 		usec_delay(mbx->usec_delay);
277 	}
278 
279 	if (countdown == 0) {
280 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
281 			     "Polling for VF%u mailbox ack timedout", mbx_id);
282 		return IXGBE_ERR_TIMEOUT;
283 	}
284 
285 	return IXGBE_SUCCESS;
286 }
287 
288 /**
289  * ixgbe_read_mailbox_vf - read VF's mailbox register
290  * @hw: pointer to the HW structure
291  *
292  * This function is used to read the mailbox register dedicated for VF without
293  * losing the read to clear status bits.
294  **/
295 static u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw)
296 {
297 	u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
298 
299 	vf_mailbox |= hw->mbx.vf_mailbox;
300 	hw->mbx.vf_mailbox |= vf_mailbox % IXGBE_VFMAILBOX_R2C_BITS;
301 
302 	return vf_mailbox;
303 }
304 
305 static void ixgbe_clear_msg_vf(struct ixgbe_hw *hw)
306 {
307 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
308 
309 	if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) {
310 		hw->mbx.stats.reqs++;
311 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS;
312 	}
313 }
314 
315 static void ixgbe_clear_ack_vf(struct ixgbe_hw *hw)
316 {
317 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
318 
319 	if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) {
320 		hw->mbx.stats.acks++;
321 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK;
322 	}
323 }
324 
325 static void ixgbe_clear_rst_vf(struct ixgbe_hw *hw)
326 {
327 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
328 
329 	if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) {
330 		hw->mbx.stats.rsts++;
331 		hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI |
332 					IXGBE_VFMAILBOX_RSTD);
333 	}
334 }
335 
336 /**
337  * ixgbe_check_for_bit_vf - Determine if a status bit was set
338  * @hw: pointer to the HW structure
339  * @mask: bitmask for bits to be tested and cleared
340  *
341  * This function is used to check for the read to clear bits within
342  * the V2P mailbox.
343  **/
344 static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
345 {
346 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
347 
348 	if (vf_mailbox & mask)
349 		return IXGBE_SUCCESS;
350 
351 	return IXGBE_ERR_MBX;
352 }
353 
354 /**
355  * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
356  * @hw: pointer to the HW structure
357  * @mbx_id: id of mailbox to check
358  *
359  * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
360  **/
361 static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
362 {
363 	UNREFERENCED_1PARAMETER(mbx_id);
364 	DEBUGFUNC("ixgbe_check_for_msg_vf");
365 
366 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS))
367 		return IXGBE_SUCCESS;
368 
369 	return IXGBE_ERR_MBX;
370 }
371 
372 /**
373  * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
374  * @hw: pointer to the HW structure
375  * @mbx_id: id of mailbox to check
376  *
377  * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
378  **/
379 static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
380 {
381 	UNREFERENCED_1PARAMETER(mbx_id);
382 	DEBUGFUNC("ixgbe_check_for_ack_vf");
383 
384 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
385 		/* TODO: should this be autocleared? */
386 		ixgbe_clear_ack_vf(hw);
387 		return IXGBE_SUCCESS;
388 	}
389 
390 	return IXGBE_ERR_MBX;
391 }
392 
393 /**
394  * ixgbe_check_for_rst_vf - checks to see if the PF has reset
395  * @hw: pointer to the HW structure
396  * @mbx_id: id of mailbox to check
397  *
398  * returns true if the PF has set the reset done bit or else false
399  **/
400 static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
401 {
402 	UNREFERENCED_1PARAMETER(mbx_id);
403 	DEBUGFUNC("ixgbe_check_for_rst_vf");
404 
405 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_RSTI |
406 					  IXGBE_VFMAILBOX_RSTD)) {
407 		/* TODO: should this be autocleared? */
408 		ixgbe_clear_rst_vf(hw);
409 		return IXGBE_SUCCESS;
410 	}
411 
412 	return IXGBE_ERR_MBX;
413 }
414 
415 /**
416  * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
417  * @hw: pointer to the HW structure
418  *
419  * return SUCCESS if we obtained the mailbox lock
420  **/
421 static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
422 {
423 	struct ixgbe_mbx_info *mbx = &hw->mbx;
424 	int countdown = mbx->timeout;
425 	s32 ret_val = IXGBE_ERR_MBX;
426 	u32 vf_mailbox;
427 
428 	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
429 
430 	if (!mbx->timeout)
431 		return IXGBE_ERR_CONFIG;
432 
433 	while (countdown--) {
434 		/* Reserve mailbox for VF use */
435 		vf_mailbox = ixgbe_read_mailbox_vf(hw);
436 		vf_mailbox |= IXGBE_VFMAILBOX_VFU;
437 		IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
438 
439 		/* Verify that VF is the owner of the lock */
440 		if (ixgbe_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) {
441 			ret_val = IXGBE_SUCCESS;
442 			break;
443 		}
444 
445 		/* Wait a bit before trying again */
446 		usec_delay(mbx->usec_delay);
447 	}
448 
449 	if (ret_val != IXGBE_SUCCESS) {
450 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
451 				"Failed to obtain mailbox lock");
452 		ret_val = IXGBE_ERR_TIMEOUT;
453 	}
454 
455 	return ret_val;
456 }
457 
458 /**
459  * ixgbe_release_mbx_lock_dummy - release mailbox lock
460  * @hw: pointer to the HW structure
461  * @mbx_id: id of mailbox to read
462  **/
463 static void ixgbe_release_mbx_lock_dummy(struct ixgbe_hw *hw, u16 mbx_id)
464 {
465 	UNREFERENCED_2PARAMETER(hw, mbx_id);
466 
467 	DEBUGFUNC("ixgbe_release_mbx_lock_dummy");
468 }
469 
470 /**
471  * ixgbe_release_mbx_lock_vf - release mailbox lock
472  * @hw: pointer to the HW structure
473  * @mbx_id: id of mailbox to read
474  **/
475 static void ixgbe_release_mbx_lock_vf(struct ixgbe_hw *hw, u16 mbx_id)
476 {
477 	u32 vf_mailbox;
478 
479 	UNREFERENCED_1PARAMETER(mbx_id);
480 
481 	DEBUGFUNC("ixgbe_release_mbx_lock_vf");
482 
483 	/* Return ownership of the buffer */
484 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
485 	vf_mailbox &= ~IXGBE_VFMAILBOX_VFU;
486 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
487 }
488 
489 /**
490  * ixgbe_write_mbx_vf_legacy - Write a message to the mailbox
491  * @hw: pointer to the HW structure
492  * @msg: The message buffer
493  * @size: Length of buffer
494  * @mbx_id: id of mailbox to write
495  *
496  * returns SUCCESS if it successfully copied message into the buffer
497  **/
498 static s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
499 				     u16 mbx_id)
500 {
501 	s32 ret_val;
502 	u16 i;
503 
504 	UNREFERENCED_1PARAMETER(mbx_id);
505 	DEBUGFUNC("ixgbe_write_mbx_vf_legacy");
506 
507 	/* lock the mailbox to prevent pf/vf race condition */
508 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
509 	if (ret_val)
510 		return ret_val;
511 
512 	/* flush msg and acks as we are overwriting the message buffer */
513 	ixgbe_check_for_msg_vf(hw, 0);
514 	ixgbe_clear_msg_vf(hw);
515 	ixgbe_check_for_ack_vf(hw, 0);
516 	ixgbe_clear_ack_vf(hw);
517 
518 	/* copy the caller specified message to the mailbox memory buffer */
519 	for (i = 0; i < size; i++)
520 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
521 
522 	/* update stats */
523 	hw->mbx.stats.msgs_tx++;
524 
525 	/* interrupt the PF to tell it a message has been sent */
526 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
527 
528 	return IXGBE_SUCCESS;
529 }
530 
531 /**
532  * ixgbe_write_mbx_vf - Write a message to the mailbox
533  * @hw: pointer to the HW structure
534  * @msg: The message buffer
535  * @size: Length of buffer
536  * @mbx_id: id of mailbox to write
537  *
538  * returns SUCCESS if it successfully copied message into the buffer
539  **/
540 static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
541 			      u16 mbx_id)
542 {
543 	u32 vf_mailbox;
544 	s32 ret_val;
545 	u16 i;
546 
547 	UNREFERENCED_1PARAMETER(mbx_id);
548 
549 	DEBUGFUNC("ixgbe_write_mbx_vf");
550 
551 	/* lock the mailbox to prevent pf/vf race condition */
552 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
553 	if (ret_val)
554 		goto out;
555 
556 	/* flush msg and acks as we are overwriting the message buffer */
557 	ixgbe_clear_msg_vf(hw);
558 	ixgbe_clear_ack_vf(hw);
559 
560 	/* copy the caller specified message to the mailbox memory buffer */
561 	for (i = 0; i < size; i++)
562 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
563 
564 	/* update stats */
565 	hw->mbx.stats.msgs_tx++;
566 
567 	/* interrupt the PF to tell it a message has been sent */
568 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
569 	vf_mailbox |= IXGBE_VFMAILBOX_REQ;
570 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
571 
572 	/* if msg sent wait until we receive an ack */
573 	ixgbe_poll_for_ack(hw, mbx_id);
574 
575 out:
576 	hw->mbx.ops[mbx_id].release(hw, mbx_id);
577 
578 	return ret_val;
579 }
580 
581 /**
582  * ixgbe_read_mbx_vf_legacy - Reads a message from the inbox intended for vf
583  * @hw: pointer to the HW structure
584  * @msg: The message buffer
585  * @size: Length of buffer
586  * @mbx_id: id of mailbox to read
587  *
588  * returns SUCCESS if it successfully read message from buffer
589  **/
590 static s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
591 				 u16 mbx_id)
592 {
593 	s32 ret_val;
594 	u16 i;
595 
596 	DEBUGFUNC("ixgbe_read_mbx_vf_legacy");
597 	UNREFERENCED_1PARAMETER(mbx_id);
598 
599 	/* lock the mailbox to prevent pf/vf race condition */
600 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
601 	if (ret_val)
602 		return ret_val;
603 
604 	/* copy the message from the mailbox memory buffer */
605 	for (i = 0; i < size; i++)
606 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
607 
608 	/* Acknowledge receipt and release mailbox, then we're done */
609 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
610 
611 	/* update stats */
612 	hw->mbx.stats.msgs_rx++;
613 
614 	return IXGBE_SUCCESS;
615 }
616 
617 /**
618  * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
619  * @hw: pointer to the HW structure
620  * @msg: The message buffer
621  * @size: Length of buffer
622  * @mbx_id: id of mailbox to read
623  *
624  * returns SUCCESS if it successfully read message from buffer
625  **/
626 static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
627 			     u16 mbx_id)
628 {
629 	u32 vf_mailbox;
630 	s32 ret_val;
631 	u16 i;
632 
633 	DEBUGFUNC("ixgbe_read_mbx_vf");
634 	UNREFERENCED_1PARAMETER(mbx_id);
635 
636 	/* check if there is a message from PF */
637 	ret_val = ixgbe_check_for_msg_vf(hw, 0);
638 	if (ret_val != IXGBE_SUCCESS)
639 		return IXGBE_ERR_MBX_NOMSG;
640 
641 	ixgbe_clear_msg_vf(hw);
642 
643 	/* copy the message from the mailbox memory buffer */
644 	for (i = 0; i < size; i++)
645 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
646 
647 	/* Acknowledge receipt */
648 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
649 	vf_mailbox |= IXGBE_VFMAILBOX_ACK;
650 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
651 
652 	/* update stats */
653 	hw->mbx.stats.msgs_rx++;
654 
655 	return IXGBE_SUCCESS;
656 }
657 
658 /**
659  * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
660  * @hw: pointer to the HW structure
661  *
662  * Initializes single set the hw->mbx struct to correct values for vf mailbox
663  * Set of legacy functions is being used here
664  */
665 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
666 {
667 	struct ixgbe_mbx_info *mbx = &hw->mbx;
668 
669 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
670 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
671 
672 	mbx->size = IXGBE_VFMAILBOX_SIZE;
673 
674 	/* VF has only one mailbox connection, no need for more IDs */
675 	mbx->ops[0].release = ixgbe_release_mbx_lock_dummy;
676 	mbx->ops[0].read = ixgbe_read_mbx_vf_legacy;
677 	mbx->ops[0].write = ixgbe_write_mbx_vf_legacy;
678 	mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
679 	mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
680 	mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
681 	mbx->ops[0].clear = NULL;
682 
683 	mbx->stats.msgs_tx = 0;
684 	mbx->stats.msgs_rx = 0;
685 	mbx->stats.reqs = 0;
686 	mbx->stats.acks = 0;
687 	mbx->stats.rsts = 0;
688 }
689 
690 /**
691  * ixgbe_upgrade_mbx_params_vf - set initial values for vf mailbox
692  * @hw: pointer to the HW structure
693  *
694  * Initializes the hw->mbx struct to correct values for vf mailbox
695  */
696 void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw)
697 {
698 	struct ixgbe_mbx_info *mbx = &hw->mbx;
699 
700 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
701 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
702 
703 	mbx->size = IXGBE_VFMAILBOX_SIZE;
704 
705 	/* VF has only one mailbox connection, no need for more IDs */
706 	mbx->ops[0].release = ixgbe_release_mbx_lock_vf;
707 	mbx->ops[0].read = ixgbe_read_mbx_vf;
708 	mbx->ops[0].write = ixgbe_write_mbx_vf;
709 	mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
710 	mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
711 	mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
712 	mbx->ops[0].clear = NULL;
713 
714 	mbx->stats.msgs_tx = 0;
715 	mbx->stats.msgs_rx = 0;
716 	mbx->stats.reqs = 0;
717 	mbx->stats.acks = 0;
718 	mbx->stats.rsts = 0;
719 }
720 
721 static void ixgbe_clear_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
722 {
723 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
724 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
725 	u32 pfmbicr;
726 
727 	pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
728 
729 	if (pfmbicr & (IXGBE_PFMBICR_VFREQ_VF1 << vf_shift))
730 		hw->mbx.stats.reqs++;
731 
732 	IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
733 			IXGBE_PFMBICR_VFREQ_VF1 << vf_shift);
734 }
735 
736 static void ixgbe_clear_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
737 {
738 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
739 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
740 	u32 pfmbicr;
741 
742 	pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
743 
744 	if (pfmbicr & (IXGBE_PFMBICR_VFACK_VF1 << vf_shift))
745 		hw->mbx.stats.acks++;
746 
747 	IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
748 			IXGBE_PFMBICR_VFACK_VF1 << vf_shift);
749 }
750 
751 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
752 {
753 	u32 pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
754 
755 	if (pfmbicr & mask) {
756 		return IXGBE_SUCCESS;
757 	}
758 
759 	return IXGBE_ERR_MBX;
760 }
761 
762 /**
763  * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
764  * @hw: pointer to the HW structure
765  * @vf_id: the VF index
766  *
767  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
768  **/
769 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
770 {
771 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
772 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
773 
774 	DEBUGFUNC("ixgbe_check_for_msg_pf");
775 
776 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift,
777 				    index))
778 		return IXGBE_SUCCESS;
779 
780 	return IXGBE_ERR_MBX;
781 }
782 
783 /**
784  * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
785  * @hw: pointer to the HW structure
786  * @vf_id: the VF index
787  *
788  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
789  **/
790 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
791 {
792 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
793 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
794 	s32 ret_val = IXGBE_ERR_MBX;
795 
796 	DEBUGFUNC("ixgbe_check_for_ack_pf");
797 
798 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift,
799 				    index)) {
800 		ret_val = IXGBE_SUCCESS;
801 		/* TODO: should this be autocleared? */
802 		ixgbe_clear_ack_pf(hw, vf_id);
803 	}
804 
805 	return ret_val;
806 }
807 
808 /**
809  * ixgbe_check_for_rst_pf - checks to see if the VF has reset
810  * @hw: pointer to the HW structure
811  * @vf_id: the VF index
812  *
813  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
814  **/
815 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id)
816 {
817 	u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id);
818 	u32 index = IXGBE_PFVFLRE_INDEX(vf_id);
819 	s32 ret_val = IXGBE_ERR_MBX;
820 	u32 vflre = 0;
821 
822 	DEBUGFUNC("ixgbe_check_for_rst_pf");
823 
824 	switch (hw->mac.type) {
825 	case ixgbe_mac_82599EB:
826 		vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLRE(index));
827 		break;
828 	case ixgbe_mac_X550:
829 	case ixgbe_mac_X550EM_x:
830 	case ixgbe_mac_X550EM_a:
831 	case ixgbe_mac_X540:
832 		vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLREC(index));
833 		break;
834 	default:
835 		break;
836 	}
837 
838 	if (vflre & (1 << vf_shift)) {
839 		ret_val = IXGBE_SUCCESS;
840 		IXGBE_WRITE_REG(hw, IXGBE_PFVFLREC(index), (1 << vf_shift));
841 		hw->mbx.stats.rsts++;
842 	}
843 
844 	return ret_val;
845 }
846 
847 /**
848  * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
849  * @hw: pointer to the HW structure
850  * @vf_id: the VF index
851  *
852  * return SUCCESS if we obtained the mailbox lock
853  **/
854 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
855 {
856 	struct ixgbe_mbx_info *mbx = &hw->mbx;
857 	int countdown = mbx->timeout;
858 	s32 ret_val = IXGBE_ERR_MBX;
859 	u32 pf_mailbox;
860 
861 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
862 
863 	if (!mbx->timeout)
864 		return IXGBE_ERR_CONFIG;
865 
866 	while (countdown--) {
867 		/* Reserve mailbox for PF use */
868 		pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
869 		pf_mailbox |= IXGBE_PFMAILBOX_PFU;
870 		IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
871 
872 		/* Verify that PF is the owner of the lock */
873 		pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
874 		if (pf_mailbox & IXGBE_PFMAILBOX_PFU) {
875 			ret_val = IXGBE_SUCCESS;
876 			break;
877 		}
878 
879 		/* Wait a bit before trying again */
880 		usec_delay(mbx->usec_delay);
881 	}
882 
883 	if (ret_val != IXGBE_SUCCESS) {
884 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
885 			      "Failed to obtain mailbox lock");
886 		ret_val = IXGBE_ERR_TIMEOUT;
887 	}
888 
889 	return ret_val;
890 }
891 
892 /**
893  * ixgbe_release_mbx_lock_pf - release mailbox lock
894  * @hw: pointer to the HW structure
895  * @vf_id: the VF index
896  **/
897 static void ixgbe_release_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
898 {
899 	u32 pf_mailbox;
900 
901 	DEBUGFUNC("ixgbe_release_mbx_lock_pf");
902 
903 	/* Return ownership of the buffer */
904 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
905 	pf_mailbox &= ~IXGBE_PFMAILBOX_PFU;
906 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
907 }
908 
909 /**
910  * ixgbe_write_mbx_pf_legacy - Places a message in the mailbox
911  * @hw: pointer to the HW structure
912  * @msg: The message buffer
913  * @size: Length of buffer
914  * @vf_id: the VF index
915  *
916  * returns SUCCESS if it successfully copied message into the buffer
917  **/
918 static s32 ixgbe_write_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
919 				     u16 vf_id)
920 {
921 	s32 ret_val;
922 	u16 i;
923 
924 	DEBUGFUNC("ixgbe_write_mbx_pf_legacy");
925 
926 	/* lock the mailbox to prevent pf/vf race condition */
927 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
928 	if (ret_val)
929 		return ret_val;
930 
931 	/* flush msg and acks as we are overwriting the message buffer */
932 	ixgbe_check_for_msg_pf(hw, vf_id);
933 	ixgbe_clear_msg_pf(hw, vf_id);
934 	ixgbe_check_for_ack_pf(hw, vf_id);
935 	ixgbe_clear_ack_pf(hw, vf_id);
936 
937 	/* copy the caller specified message to the mailbox memory buffer */
938 	for (i = 0; i < size; i++)
939 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
940 
941 	/* Interrupt VF to tell it a message has been sent and release buffer*/
942 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_STS);
943 
944 	/* update stats */
945 	hw->mbx.stats.msgs_tx++;
946 
947 	return IXGBE_SUCCESS;
948 }
949 
950 /**
951  * ixgbe_write_mbx_pf - Places a message in the mailbox
952  * @hw: pointer to the HW structure
953  * @msg: The message buffer
954  * @size: Length of buffer
955  * @vf_id: the VF index
956  *
957  * returns SUCCESS if it successfully copied message into the buffer
958  **/
959 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
960 			      u16 vf_id)
961 {
962 	u32 pf_mailbox;
963 	s32 ret_val;
964 	u16 i;
965 
966 	DEBUGFUNC("ixgbe_write_mbx_pf");
967 
968 	/* lock the mailbox to prevent pf/vf race condition */
969 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
970 	if (ret_val)
971 		goto out;
972 
973 	/* flush msg and acks as we are overwriting the message buffer */
974 	ixgbe_clear_msg_pf(hw, vf_id);
975 	ixgbe_clear_ack_pf(hw, vf_id);
976 
977 	/* copy the caller specified message to the mailbox memory buffer */
978 	for (i = 0; i < size; i++)
979 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
980 
981 	/* Interrupt VF to tell it a message has been sent */
982 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
983 	pf_mailbox |= IXGBE_PFMAILBOX_STS;
984 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
985 
986 	/* if msg sent wait until we receive an ack */
987 	ixgbe_poll_for_ack(hw, vf_id);
988 
989 	/* update stats */
990 	hw->mbx.stats.msgs_tx++;
991 
992 out:
993 	hw->mbx.ops[vf_id].release(hw, vf_id);
994 
995 	return ret_val;
996 
997 }
998 
999 /**
1000  * ixgbe_read_mbx_pf_legacy - Read a message from the mailbox
1001  * @hw: pointer to the HW structure
1002  * @msg: The message buffer
1003  * @size: Length of buffer
1004  * @vf_id: the VF index
1005  *
1006  * This function copies a message from the mailbox buffer to the caller's
1007  * memory buffer.  The presumption is that the caller knows that there was
1008  * a message due to a VF request so no polling for message is needed.
1009  **/
1010 static s32 ixgbe_read_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
1011 				    u16 vf_id)
1012 {
1013 	s32 ret_val;
1014 	u16 i;
1015 
1016 	DEBUGFUNC("ixgbe_read_mbx_pf_legacy");
1017 
1018 	/* lock the mailbox to prevent pf/vf race condition */
1019 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
1020 	if (ret_val != IXGBE_SUCCESS)
1021 		return ret_val;
1022 
1023 	/* copy the message to the mailbox memory buffer */
1024 	for (i = 0; i < size; i++)
1025 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
1026 
1027 	/* Acknowledge the message and release buffer */
1028 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_ACK);
1029 
1030 	/* update stats */
1031 	hw->mbx.stats.msgs_rx++;
1032 
1033 	return IXGBE_SUCCESS;
1034 }
1035 
1036 /**
1037  * ixgbe_read_mbx_pf - Read a message from the mailbox
1038  * @hw: pointer to the HW structure
1039  * @msg: The message buffer
1040  * @size: Length of buffer
1041  * @vf_id: the VF index
1042  *
1043  * This function copies a message from the mailbox buffer to the caller's
1044  * memory buffer.  The presumption is that the caller knows that there was
1045  * a message due to a VF request so no polling for message is needed.
1046  **/
1047 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
1048 			     u16 vf_id)
1049 {
1050 	u32 pf_mailbox;
1051 	s32 ret_val;
1052 	u16 i;
1053 
1054 	DEBUGFUNC("ixgbe_read_mbx_pf");
1055 
1056 	/* check if there is a message from VF */
1057 	ret_val = ixgbe_check_for_msg_pf(hw, vf_id);
1058 	if (ret_val != IXGBE_SUCCESS)
1059 		return IXGBE_ERR_MBX_NOMSG;
1060 
1061 	ixgbe_clear_msg_pf(hw, vf_id);
1062 
1063 	/* copy the message to the mailbox memory buffer */
1064 	for (i = 0; i < size; i++)
1065 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
1066 
1067 	/* Acknowledge the message and release buffer */
1068 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
1069 	pf_mailbox |= IXGBE_PFMAILBOX_ACK;
1070 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
1071 
1072 	/* update stats */
1073 	hw->mbx.stats.msgs_rx++;
1074 
1075 	return IXGBE_SUCCESS;
1076 }
1077 
1078 /**
1079  * ixgbe_clear_mbx_pf - Clear Mailbox Memory
1080  * @hw: pointer to the HW structure
1081  * @vf_id: the VF index
1082  *
1083  * Set VFMBMEM of given VF to 0x0.
1084  **/
1085 static s32 ixgbe_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_id)
1086 {
1087 	u16 mbx_size = hw->mbx.size;
1088 	u16 i;
1089 
1090 	if (vf_id > 63)
1091 		return IXGBE_ERR_PARAM;
1092 
1093 	for (i = 0; i < mbx_size; ++i)
1094 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, 0x0);
1095 
1096 	return IXGBE_SUCCESS;
1097 }
1098 
1099 /**
1100  * ixgbe_init_mbx_params_pf_id - set initial values for pf mailbox
1101  * @hw: pointer to the HW structure
1102  * @vf_id: the VF index
1103  *
1104  * Initializes single set of the hw->mbx struct to correct values for pf mailbox
1105  * Set of legacy functions is being used here
1106  */
1107 void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id)
1108 {
1109 	struct ixgbe_mbx_info *mbx = &hw->mbx;
1110 
1111 	mbx->ops[vf_id].release = ixgbe_release_mbx_lock_dummy;
1112 	mbx->ops[vf_id].read = ixgbe_read_mbx_pf_legacy;
1113 	mbx->ops[vf_id].write = ixgbe_write_mbx_pf_legacy;
1114 	mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
1115 	mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
1116 	mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
1117 	mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
1118 }
1119 
1120 /**
1121  * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
1122  * @hw: pointer to the HW structure
1123  *
1124  * Initializes all sets of the hw->mbx struct to correct values for pf
1125  * mailbox. One set corresponds to single VF. It also initializes counters
1126  * and general variables. A set of legacy functions is used by default.
1127  */
1128 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
1129 {
1130 	u16 i;
1131 	struct ixgbe_mbx_info *mbx = &hw->mbx;
1132 
1133 	/* Ensure we are not calling this function from VF */
1134 	if (hw->mac.type != ixgbe_mac_82599EB &&
1135 	    hw->mac.type != ixgbe_mac_X550 &&
1136 	    hw->mac.type != ixgbe_mac_X550EM_x &&
1137 	    hw->mac.type != ixgbe_mac_X550EM_a &&
1138 	    hw->mac.type != ixgbe_mac_X540)
1139 		return;
1140 
1141 	/* Initialize common mailbox settings */
1142 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
1143 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
1144 	mbx->size = IXGBE_VFMAILBOX_SIZE;
1145 
1146 	/* Initialize counters with zeroes */
1147 	mbx->stats.msgs_tx = 0;
1148 	mbx->stats.msgs_rx = 0;
1149 	mbx->stats.reqs = 0;
1150 	mbx->stats.acks = 0;
1151 	mbx->stats.rsts = 0;
1152 
1153 	/* No matter of VF number, we initialize params for all 64 VFs. */
1154 	/* TODO: 1. Add a define for max VF and refactor SHARED to get rid
1155 	 * of magic number for that (63 or 64 depending on use case.)
1156 	 * 2. rewrite the code to dynamically allocate mbx->ops[vf_id] for
1157 	 * certain number of VFs instead of default maximum value of 64 (0..63)
1158 	 */
1159 	for (i = 0; i < 64; i++)
1160 		ixgbe_init_mbx_params_pf_id(hw, i);
1161 }
1162 
1163 /**
1164  * ixgbe_upgrade_mbx_params_pf - Upgrade initial values for pf mailbox
1165  * @hw: pointer to the HW structure
1166  * @vf_id: the VF index
1167  *
1168  * Initializes the hw->mbx struct to new function set for improved
1169  * stability and handling of messages.
1170  */
1171 void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id)
1172 {
1173 	struct ixgbe_mbx_info *mbx = &hw->mbx;
1174 
1175 	/* Ensure we are not calling this function from VF */
1176 	if (hw->mac.type != ixgbe_mac_82599EB &&
1177 	    hw->mac.type != ixgbe_mac_X550 &&
1178 	    hw->mac.type != ixgbe_mac_X550EM_x &&
1179 	    hw->mac.type != ixgbe_mac_X550EM_a &&
1180 	    hw->mac.type != ixgbe_mac_X540)
1181 		return;
1182 
1183 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
1184 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
1185 	mbx->size = IXGBE_VFMAILBOX_SIZE;
1186 
1187 	mbx->ops[vf_id].release = ixgbe_release_mbx_lock_pf;
1188 	mbx->ops[vf_id].read = ixgbe_read_mbx_pf;
1189 	mbx->ops[vf_id].write = ixgbe_write_mbx_pf;
1190 	mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
1191 	mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
1192 	mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
1193 	mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
1194 
1195 	mbx->stats.msgs_tx = 0;
1196 	mbx->stats.msgs_rx = 0;
1197 	mbx->stats.reqs = 0;
1198 	mbx->stats.acks = 0;
1199 	mbx->stats.rsts = 0;
1200 }
1201