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