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