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