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