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