xref: /netbsd-src/sys/dev/pci/ixgbe/ixgbe_mbx.c (revision c38e7cc395b1472a774ff828e46123de44c628e9)
1 /* $NetBSD: ixgbe_mbx.c,v 1.10 2018/04/04 08:13:07 msaitoh Exp $ */
2 
3 /******************************************************************************
4   SPDX-License-Identifier: BSD-3-Clause
5 
6   Copyright (c) 2001-2017, Intel Corporation
7   All rights reserved.
8 
9   Redistribution and use in source and binary forms, with or without
10   modification, are permitted provided that the following conditions are met:
11 
12    1. Redistributions of source code must retain the above copyright notice,
13       this list of conditions and the following disclaimer.
14 
15    2. Redistributions in binary form must reproduce the above copyright
16       notice, this list of conditions and the following disclaimer in the
17       documentation and/or other materials provided with the distribution.
18 
19    3. Neither the name of the Intel Corporation nor the names of its
20       contributors may be used to endorse or promote products derived from
21       this software without specific prior written permission.
22 
23   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33   POSSIBILITY OF SUCH DAMAGE.
34 
35 ******************************************************************************/
36 /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_mbx.c 326022 2017-11-20 19:36:21Z pfg $*/
37 
38 #include "ixgbe_type.h"
39 #include "ixgbe_mbx.h"
40 
41 /**
42  *  ixgbe_poll_for_msg - Wait for message notification
43  *  @hw: pointer to the HW structure
44  *  @mbx_id: id of mailbox to write
45  *
46  *  returns SUCCESS if it successfully received a message notification
47  **/
48 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
49 {
50 	struct ixgbe_mbx_info *mbx = &hw->mbx;
51 	int countdown = mbx->timeout;
52 
53 	DEBUGFUNC("ixgbe_poll_for_msg");
54 
55 	if (!countdown || !mbx->ops.check_for_msg)
56 		goto out;
57 
58 	while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
59 		countdown--;
60 		if (!countdown)
61 			break;
62 		usec_delay(mbx->usec_delay);
63 	}
64 
65 	if (countdown == 0)
66 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
67 			   "Polling for VF%d mailbox message timedout", mbx_id);
68 
69 out:
70 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
71 }
72 
73 /**
74  *  ixgbe_poll_for_ack - Wait for message acknowledgement
75  *  @hw: pointer to the HW structure
76  *  @mbx_id: id of mailbox to write
77  *
78  *  returns SUCCESS if it successfully received a message acknowledgement
79  **/
80 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
81 {
82 	struct ixgbe_mbx_info *mbx = &hw->mbx;
83 	int countdown = mbx->timeout;
84 
85 	DEBUGFUNC("ixgbe_poll_for_ack");
86 
87 	if (!countdown || !mbx->ops.check_for_ack)
88 		goto out;
89 
90 	while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
91 		countdown--;
92 		if (!countdown)
93 			break;
94 		usec_delay(mbx->usec_delay);
95 	}
96 
97 	if (countdown == 0)
98 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
99 			     "Polling for VF%d mailbox ack timedout", mbx_id);
100 
101 out:
102 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
103 }
104 
105 /**
106  *  ixgbe_read_posted_mbx - Wait for message notification and receive message
107  *  @hw: pointer to the HW structure
108  *  @msg: The message buffer
109  *  @size: Length of buffer
110  *  @mbx_id: id of mailbox to write
111  *
112  *  returns SUCCESS if it successfully received a message notification and
113  *  copied it into the receive buffer.
114  **/
115 static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
116 				 u16 mbx_id)
117 {
118 	struct ixgbe_mbx_info *mbx = &hw->mbx;
119 	s32 ret_val = IXGBE_ERR_MBX;
120 
121 	DEBUGFUNC("ixgbe_read_posted_mbx");
122 
123 	if (!mbx->ops.read)
124 		goto out;
125 
126 	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
127 
128 	/* if ack received read message, otherwise we timed out */
129 	if (!ret_val)
130 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
131 out:
132 	return ret_val;
133 }
134 
135 /**
136  *  ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
137  *  @hw: pointer to the HW structure
138  *  @msg: The message buffer
139  *  @size: Length of buffer
140  *  @mbx_id: id of mailbox to write
141  *
142  *  returns SUCCESS if it successfully copied message into the buffer and
143  *  received an ack to that message within delay * timeout period
144  **/
145 static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
146 				  u16 mbx_id)
147 {
148 	struct ixgbe_mbx_info *mbx = &hw->mbx;
149 	s32 ret_val = IXGBE_ERR_MBX;
150 
151 	DEBUGFUNC("ixgbe_write_posted_mbx");
152 
153 	/* exit if either we can't write or there isn't a defined timeout */
154 	if (!mbx->ops.write || !mbx->timeout)
155 		goto out;
156 
157 	/* send msg */
158 	ret_val = mbx->ops.write(hw, msg, size, mbx_id);
159 
160 	/* if msg sent wait until we receive an ack */
161 	if (!ret_val)
162 		ret_val = ixgbe_poll_for_ack(hw, mbx_id);
163 out:
164 	return ret_val;
165 }
166 
167 /**
168  *  ixgbe_init_mbx_ops_generic - Initialize MB function pointers
169  *  @hw: pointer to the HW structure
170  *
171  *  Setups up the mailbox read and write message function pointers
172  **/
173 void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
174 {
175 	struct ixgbe_mbx_info *mbx = &hw->mbx;
176 
177 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
178 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
179 }
180 
181 /**
182  *  ixgbe_read_v2p_mailbox - read v2p mailbox
183  *  @hw: pointer to the HW structure
184  *
185  *  This function is used to read the v2p mailbox without losing the read to
186  *  clear status bits.
187  **/
188 static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
189 {
190 	u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
191 
192 	v2p_mailbox |= hw->mbx.v2p_mailbox;
193 	hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
194 
195 	return v2p_mailbox;
196 }
197 
198 /**
199  *  ixgbe_check_for_bit_vf - Determine if a status bit was set
200  *  @hw: pointer to the HW structure
201  *  @mask: bitmask for bits to be tested and cleared
202  *
203  *  This function is used to check for the read to clear bits within
204  *  the V2P mailbox.
205  **/
206 static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
207 {
208 	u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
209 	s32 ret_val = IXGBE_ERR_MBX;
210 
211 	if (v2p_mailbox & mask)
212 		ret_val = IXGBE_SUCCESS;
213 
214 	hw->mbx.v2p_mailbox &= ~mask;
215 
216 	return ret_val;
217 }
218 
219 /**
220  *  ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
221  *  @hw: pointer to the HW structure
222  *  @mbx_id: id of mailbox to check
223  *
224  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
225  **/
226 static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
227 {
228 	s32 ret_val = IXGBE_ERR_MBX;
229 
230 	UNREFERENCED_1PARAMETER(mbx_id);
231 	DEBUGFUNC("ixgbe_check_for_msg_vf");
232 
233 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
234 		ret_val = IXGBE_SUCCESS;
235 		hw->mbx.stats.reqs.ev_count++;
236 	}
237 
238 	return ret_val;
239 }
240 
241 /**
242  *  ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
243  *  @hw: pointer to the HW structure
244  *  @mbx_id: id of mailbox to check
245  *
246  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
247  **/
248 static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
249 {
250 	s32 ret_val = IXGBE_ERR_MBX;
251 
252 	UNREFERENCED_1PARAMETER(mbx_id);
253 	DEBUGFUNC("ixgbe_check_for_ack_vf");
254 
255 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
256 		ret_val = IXGBE_SUCCESS;
257 		hw->mbx.stats.acks.ev_count++;
258 	}
259 
260 	return ret_val;
261 }
262 
263 /**
264  *  ixgbe_check_for_rst_vf - checks to see if the PF has reset
265  *  @hw: pointer to the HW structure
266  *  @mbx_id: id of mailbox to check
267  *
268  *  returns TRUE if the PF has set the reset done bit or else FALSE
269  **/
270 static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
271 {
272 	s32 ret_val = IXGBE_ERR_MBX;
273 
274 	UNREFERENCED_1PARAMETER(mbx_id);
275 	DEBUGFUNC("ixgbe_check_for_rst_vf");
276 
277 	if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
278 	    IXGBE_VFMAILBOX_RSTI))) {
279 		ret_val = IXGBE_SUCCESS;
280 		hw->mbx.stats.rsts.ev_count++;
281 	}
282 
283 	return ret_val;
284 }
285 
286 /**
287  *  ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
288  *  @hw: pointer to the HW structure
289  *
290  *  return SUCCESS if we obtained the mailbox lock
291  **/
292 static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
293 {
294 	s32 ret_val = IXGBE_ERR_MBX;
295 
296 	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
297 
298 	/* Take ownership of the buffer */
299 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
300 
301 	/* reserve mailbox for vf use */
302 	if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
303 		ret_val = IXGBE_SUCCESS;
304 
305 	return ret_val;
306 }
307 
308 /**
309  *  ixgbe_write_mbx_vf - Write a message to the mailbox
310  *  @hw: pointer to the HW structure
311  *  @msg: The message buffer
312  *  @size: Length of buffer
313  *  @mbx_id: id of mailbox to write
314  *
315  *  returns SUCCESS if it successfully copied message into the buffer
316  **/
317 static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
318 			      u16 mbx_id)
319 {
320 	s32 ret_val;
321 	u16 i;
322 
323 	UNREFERENCED_1PARAMETER(mbx_id);
324 
325 	DEBUGFUNC("ixgbe_write_mbx_vf");
326 
327 	/* lock the mailbox to prevent pf/vf race condition */
328 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
329 	if (ret_val)
330 		goto out_no_write;
331 
332 	/* flush msg and acks as we are overwriting the message buffer */
333 	ixgbe_check_for_msg_vf(hw, 0);
334 	ixgbe_check_for_ack_vf(hw, 0);
335 
336 	/* copy the caller specified message to the mailbox memory buffer */
337 	for (i = 0; i < size; i++)
338 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
339 
340 	/* update stats */
341 	hw->mbx.stats.msgs_tx.ev_count++;
342 
343 	/* Drop VFU and interrupt the PF to tell it a message has been sent */
344 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
345 
346 out_no_write:
347 	return ret_val;
348 }
349 
350 /**
351  *  ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
352  *  @hw: pointer to the HW structure
353  *  @msg: The message buffer
354  *  @size: Length of buffer
355  *  @mbx_id: id of mailbox to read
356  *
357  *  returns SUCCESS if it successfully read message from buffer
358  **/
359 static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
360 			     u16 mbx_id)
361 {
362 	s32 ret_val = IXGBE_SUCCESS;
363 	u16 i;
364 
365 	DEBUGFUNC("ixgbe_read_mbx_vf");
366 	UNREFERENCED_1PARAMETER(mbx_id);
367 
368 	/* lock the mailbox to prevent pf/vf race condition */
369 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
370 	if (ret_val)
371 		goto out_no_read;
372 
373 	/* copy the message from the mailbox memory buffer */
374 	for (i = 0; i < size; i++)
375 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
376 
377 	/* Acknowledge receipt and release mailbox, then we're done */
378 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
379 
380 	/* update stats */
381 	hw->mbx.stats.msgs_rx.ev_count++;
382 
383 out_no_read:
384 	return ret_val;
385 }
386 
387 /**
388  *  ixgbe_init_mbx_params_vf - set initial values for vf mailbox
389  *  @hw: pointer to the HW structure
390  *
391  *  Initializes the hw->mbx struct to correct values for vf mailbox
392  */
393 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
394 {
395 	struct ixgbe_mbx_info *mbx = &hw->mbx;
396 
397 	/* start mailbox as timed out and let the reset_hw call set the timeout
398 	 * value to begin communications */
399 	mbx->timeout = 0;
400 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
401 
402 	mbx->size = IXGBE_VFMAILBOX_SIZE;
403 
404 	mbx->ops.read = ixgbe_read_mbx_vf;
405 	mbx->ops.write = ixgbe_write_mbx_vf;
406 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
407 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
408 	mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
409 	mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
410 	mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
411 
412 	mbx->stats.msgs_tx.ev_count = 0;
413 	mbx->stats.msgs_rx.ev_count = 0;
414 	mbx->stats.reqs.ev_count = 0;
415 	mbx->stats.acks.ev_count = 0;
416 	mbx->stats.rsts.ev_count = 0;
417 }
418 
419 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
420 {
421 	u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
422 	s32 ret_val = IXGBE_ERR_MBX;
423 
424 	if (mbvficr & mask) {
425 		ret_val = IXGBE_SUCCESS;
426 		IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
427 	}
428 
429 	return ret_val;
430 }
431 
432 /**
433  *  ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
434  *  @hw: pointer to the HW structure
435  *  @vf_number: the VF index
436  *
437  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
438  **/
439 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
440 {
441 	s32 ret_val = IXGBE_ERR_MBX;
442 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
443 	u32 vf_bit = vf_number % 16;
444 
445 	DEBUGFUNC("ixgbe_check_for_msg_pf");
446 
447 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
448 				    index)) {
449 		ret_val = IXGBE_SUCCESS;
450 		hw->mbx.stats.reqs.ev_count++;
451 	}
452 
453 	return ret_val;
454 }
455 
456 /**
457  *  ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
458  *  @hw: pointer to the HW structure
459  *  @vf_number: the VF index
460  *
461  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
462  **/
463 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
464 {
465 	s32 ret_val = IXGBE_ERR_MBX;
466 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
467 	u32 vf_bit = vf_number % 16;
468 
469 	DEBUGFUNC("ixgbe_check_for_ack_pf");
470 
471 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
472 				    index)) {
473 		ret_val = IXGBE_SUCCESS;
474 		hw->mbx.stats.acks.ev_count++;
475 	}
476 
477 	return ret_val;
478 }
479 
480 /**
481  *  ixgbe_check_for_rst_pf - checks to see if the VF has reset
482  *  @hw: pointer to the HW structure
483  *  @vf_number: the VF index
484  *
485  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
486  **/
487 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
488 {
489 	u32 reg_offset = (vf_number < 32) ? 0 : 1;
490 	u32 vf_shift = vf_number % 32;
491 	u32 vflre = 0;
492 	s32 ret_val = IXGBE_ERR_MBX;
493 
494 	DEBUGFUNC("ixgbe_check_for_rst_pf");
495 
496 	switch (hw->mac.type) {
497 	case ixgbe_mac_82599EB:
498 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
499 		break;
500 	case ixgbe_mac_X550:
501 	case ixgbe_mac_X550EM_x:
502 	case ixgbe_mac_X550EM_a:
503 	case ixgbe_mac_X540:
504 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
505 		break;
506 	default:
507 		break;
508 	}
509 
510 	if (vflre & (1 << vf_shift)) {
511 		ret_val = IXGBE_SUCCESS;
512 		IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
513 		hw->mbx.stats.rsts.ev_count++;
514 	}
515 
516 	return ret_val;
517 }
518 
519 /**
520  *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
521  *  @hw: pointer to the HW structure
522  *  @vf_number: the VF index
523  *
524  *  return SUCCESS if we obtained the mailbox lock
525  **/
526 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
527 {
528 	s32 ret_val = IXGBE_ERR_MBX;
529 	u32 p2v_mailbox;
530 
531 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
532 
533 	/* Take ownership of the buffer */
534 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
535 
536 	/* reserve mailbox for vf use */
537 	p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
538 	if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
539 		ret_val = IXGBE_SUCCESS;
540 	else
541 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
542 			   "Failed to obtain mailbox lock for VF%d", vf_number);
543 
544 
545 	return ret_val;
546 }
547 
548 /**
549  *  ixgbe_write_mbx_pf - Places a message in the mailbox
550  *  @hw: pointer to the HW structure
551  *  @msg: The message buffer
552  *  @size: Length of buffer
553  *  @vf_number: the VF index
554  *
555  *  returns SUCCESS if it successfully copied message into the buffer
556  **/
557 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
558 			      u16 vf_number)
559 {
560 	s32 ret_val;
561 	u16 i;
562 
563 	DEBUGFUNC("ixgbe_write_mbx_pf");
564 
565 	/* lock the mailbox to prevent pf/vf race condition */
566 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
567 	if (ret_val)
568 		goto out_no_write;
569 
570 	/* flush msg and acks as we are overwriting the message buffer */
571 	ixgbe_check_for_msg_pf(hw, vf_number);
572 	ixgbe_check_for_ack_pf(hw, vf_number);
573 
574 	/* copy the caller specified message to the mailbox memory buffer */
575 	for (i = 0; i < size; i++)
576 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
577 
578 	/* Interrupt VF to tell it a message has been sent and release buffer*/
579 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
580 
581 	/* update stats */
582 	hw->mbx.stats.msgs_tx.ev_count++;
583 
584 out_no_write:
585 	return ret_val;
586 
587 }
588 
589 /**
590  *  ixgbe_read_mbx_pf - Read a message from the mailbox
591  *  @hw: pointer to the HW structure
592  *  @msg: The message buffer
593  *  @size: Length of buffer
594  *  @vf_number: the VF index
595  *
596  *  This function copies a message from the mailbox buffer to the caller's
597  *  memory buffer.  The presumption is that the caller knows that there was
598  *  a message due to a VF request so no polling for message is needed.
599  **/
600 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
601 			     u16 vf_number)
602 {
603 	s32 ret_val;
604 	u16 i;
605 
606 	DEBUGFUNC("ixgbe_read_mbx_pf");
607 
608 	/* lock the mailbox to prevent pf/vf race condition */
609 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
610 	if (ret_val)
611 		goto out_no_read;
612 
613 	/* copy the message to the mailbox memory buffer */
614 	for (i = 0; i < size; i++)
615 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
616 
617 	/* Acknowledge the message and release buffer */
618 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
619 
620 	/* update stats */
621 	hw->mbx.stats.msgs_rx.ev_count++;
622 
623 out_no_read:
624 	return ret_val;
625 }
626 
627 /**
628  *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox
629  *  @hw: pointer to the HW structure
630  *
631  *  Initializes the hw->mbx struct to correct values for pf mailbox
632  */
633 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
634 {
635 	struct ixgbe_mbx_info *mbx = &hw->mbx;
636 
637 	if (hw->mac.type != ixgbe_mac_82599EB &&
638 	    hw->mac.type != ixgbe_mac_X550 &&
639 	    hw->mac.type != ixgbe_mac_X550EM_x &&
640 	    hw->mac.type != ixgbe_mac_X550EM_a &&
641 	    hw->mac.type != ixgbe_mac_X540)
642 		return;
643 
644 	mbx->timeout = 0;
645 	mbx->usec_delay = 0;
646 
647 	mbx->size = IXGBE_VFMAILBOX_SIZE;
648 
649 	mbx->ops.read = ixgbe_read_mbx_pf;
650 	mbx->ops.write = ixgbe_write_mbx_pf;
651 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
652 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
653 	mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
654 	mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
655 	mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
656 
657 	mbx->stats.msgs_tx.ev_count = 0;
658 	mbx->stats.msgs_rx.ev_count = 0;
659 	mbx->stats.reqs.ev_count = 0;
660 	mbx->stats.acks.ev_count = 0;
661 	mbx->stats.rsts.ev_count = 0;
662 }
663