ixgbe_mbx.c revision 1.9 1 /* $NetBSD: ixgbe_mbx.c,v 1.9 2017/12/06 04:08:50 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 320688 2017-07-05 17:27:03Z erj $*/
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