ixgbe_mbx.c revision 1.1.30.2 1 /******************************************************************************
2
3 Copyright (c) 2001-2015, 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: head/sys/dev/ixgbe/ixgbe_mbx.c 282289 2015-04-30 22:53:27Z erj $*/
34 /*$NetBSD: ixgbe_mbx.c,v 1.1.30.2 2016/12/05 10:55:17 skrll 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 **/
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 acknowledgement
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 acknowledgement
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, u16 mbx_id)
226 {
227 struct ixgbe_mbx_info *mbx = &hw->mbx;
228 s32 ret_val = IXGBE_ERR_MBX;
229
230 DEBUGFUNC("ixgbe_read_posted_mbx");
231
232 if (!mbx->ops.read)
233 goto out;
234
235 ret_val = ixgbe_poll_for_msg(hw, mbx_id);
236
237 /* if ack received read message, otherwise we timed out */
238 if (!ret_val)
239 ret_val = mbx->ops.read(hw, msg, size, mbx_id);
240 out:
241 return ret_val;
242 }
243
244 /**
245 * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
246 * @hw: pointer to the HW structure
247 * @msg: The message buffer
248 * @size: Length of buffer
249 * @mbx_id: id of mailbox to write
250 *
251 * returns SUCCESS if it successfully copied message into the buffer and
252 * received an ack to that message within delay * timeout period
253 **/
254 s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
255 u16 mbx_id)
256 {
257 struct ixgbe_mbx_info *mbx = &hw->mbx;
258 s32 ret_val = IXGBE_ERR_MBX;
259
260 DEBUGFUNC("ixgbe_write_posted_mbx");
261
262 /* exit if either we can't write or there isn't a defined timeout */
263 if (!mbx->ops.write || !mbx->timeout)
264 goto out;
265
266 /* send msg */
267 ret_val = mbx->ops.write(hw, msg, size, mbx_id);
268
269 /* if msg sent wait until we receive an ack */
270 if (!ret_val)
271 ret_val = ixgbe_poll_for_ack(hw, mbx_id);
272 out:
273 return ret_val;
274 }
275
276 /**
277 * ixgbe_init_mbx_ops_generic - Initialize MB function pointers
278 * @hw: pointer to the HW structure
279 *
280 * Setups up the mailbox read and write message function pointers
281 **/
282 void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
283 {
284 struct ixgbe_mbx_info *mbx = &hw->mbx;
285
286 mbx->ops.read_posted = ixgbe_read_posted_mbx;
287 mbx->ops.write_posted = ixgbe_write_posted_mbx;
288 }
289
290 /**
291 * ixgbe_read_v2p_mailbox - read v2p mailbox
292 * @hw: pointer to the HW structure
293 *
294 * This function is used to read the v2p mailbox without losing the read to
295 * clear status bits.
296 **/
297 static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
298 {
299 u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
300
301 v2p_mailbox |= hw->mbx.v2p_mailbox;
302 hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
303
304 return v2p_mailbox;
305 }
306
307 /**
308 * ixgbe_check_for_bit_vf - Determine if a status bit was set
309 * @hw: pointer to the HW structure
310 * @mask: bitmask for bits to be tested and cleared
311 *
312 * This function is used to check for the read to clear bits within
313 * the V2P mailbox.
314 **/
315 static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
316 {
317 u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
318 s32 ret_val = IXGBE_ERR_MBX;
319
320 if (v2p_mailbox & mask)
321 ret_val = IXGBE_SUCCESS;
322
323 hw->mbx.v2p_mailbox &= ~mask;
324
325 return ret_val;
326 }
327
328 /**
329 * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
330 * @hw: pointer to the HW structure
331 * @mbx_id: id of mailbox to check
332 *
333 * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
334 **/
335 static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
336 {
337 s32 ret_val = IXGBE_ERR_MBX;
338
339 UNREFERENCED_1PARAMETER(mbx_id);
340 DEBUGFUNC("ixgbe_check_for_msg_vf");
341
342 if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
343 ret_val = IXGBE_SUCCESS;
344 hw->mbx.stats.reqs++;
345 }
346
347 return ret_val;
348 }
349
350 /**
351 * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
352 * @hw: pointer to the HW structure
353 * @mbx_id: id of mailbox to check
354 *
355 * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
356 **/
357 static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
358 {
359 s32 ret_val = IXGBE_ERR_MBX;
360
361 UNREFERENCED_1PARAMETER(mbx_id);
362 DEBUGFUNC("ixgbe_check_for_ack_vf");
363
364 if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
365 ret_val = IXGBE_SUCCESS;
366 hw->mbx.stats.acks++;
367 }
368
369 return ret_val;
370 }
371
372 /**
373 * ixgbe_check_for_rst_vf - checks to see if the PF has reset
374 * @hw: pointer to the HW structure
375 * @mbx_id: id of mailbox to check
376 *
377 * returns TRUE if the PF has set the reset done bit or else FALSE
378 **/
379 static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
380 {
381 s32 ret_val = IXGBE_ERR_MBX;
382
383 UNREFERENCED_1PARAMETER(mbx_id);
384 DEBUGFUNC("ixgbe_check_for_rst_vf");
385
386 if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
387 IXGBE_VFMAILBOX_RSTI))) {
388 ret_val = IXGBE_SUCCESS;
389 hw->mbx.stats.rsts++;
390 }
391
392 return ret_val;
393 }
394
395 /**
396 * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
397 * @hw: pointer to the HW structure
398 *
399 * return SUCCESS if we obtained the mailbox lock
400 **/
401 static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
402 {
403 s32 ret_val = IXGBE_ERR_MBX;
404
405 DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
406
407 /* Take ownership of the buffer */
408 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
409
410 /* reserve mailbox for vf use */
411 if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
412 ret_val = IXGBE_SUCCESS;
413
414 return ret_val;
415 }
416
417 /**
418 * ixgbe_write_mbx_vf - Write a message to the mailbox
419 * @hw: pointer to the HW structure
420 * @msg: The message buffer
421 * @size: Length of buffer
422 * @mbx_id: id of mailbox to write
423 *
424 * returns SUCCESS if it successfully copied message into the buffer
425 **/
426 static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
427 u16 mbx_id)
428 {
429 s32 ret_val;
430 u16 i;
431
432 UNREFERENCED_1PARAMETER(mbx_id);
433
434 DEBUGFUNC("ixgbe_write_mbx_vf");
435
436 /* lock the mailbox to prevent pf/vf race condition */
437 ret_val = ixgbe_obtain_mbx_lock_vf(hw);
438 if (ret_val)
439 goto out_no_write;
440
441 /* flush msg and acks as we are overwriting the message buffer */
442 ixgbe_check_for_msg_vf(hw, 0);
443 ixgbe_check_for_ack_vf(hw, 0);
444
445 /* copy the caller specified message to the mailbox memory buffer */
446 for (i = 0; i < size; i++)
447 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
448
449 /* update stats */
450 hw->mbx.stats.msgs_tx++;
451
452 /* Drop VFU and interrupt the PF to tell it a message has been sent */
453 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
454
455 out_no_write:
456 return ret_val;
457 }
458
459 /**
460 * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
461 * @hw: pointer to the HW structure
462 * @msg: The message buffer
463 * @size: Length of buffer
464 * @mbx_id: id of mailbox to read
465 *
466 * returns SUCCESS if it successfuly read message from buffer
467 **/
468 static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
469 u16 mbx_id)
470 {
471 s32 ret_val = IXGBE_SUCCESS;
472 u16 i;
473
474 DEBUGFUNC("ixgbe_read_mbx_vf");
475 UNREFERENCED_1PARAMETER(mbx_id);
476
477 /* lock the mailbox to prevent pf/vf race condition */
478 ret_val = ixgbe_obtain_mbx_lock_vf(hw);
479 if (ret_val)
480 goto out_no_read;
481
482 /* copy the message from the mailbox memory buffer */
483 for (i = 0; i < size; i++)
484 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
485
486 /* Acknowledge receipt and release mailbox, then we're done */
487 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
488
489 /* update stats */
490 hw->mbx.stats.msgs_rx++;
491
492 out_no_read:
493 return ret_val;
494 }
495
496 /**
497 * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
498 * @hw: pointer to the HW structure
499 *
500 * Initializes the hw->mbx struct to correct values for vf mailbox
501 */
502 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
503 {
504 struct ixgbe_mbx_info *mbx = &hw->mbx;
505
506 /* start mailbox as timed out and let the reset_hw call set the timeout
507 * value to begin communications */
508 mbx->timeout = 0;
509 mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
510
511 mbx->size = IXGBE_VFMAILBOX_SIZE;
512
513 mbx->ops.read = ixgbe_read_mbx_vf;
514 mbx->ops.write = ixgbe_write_mbx_vf;
515 mbx->ops.read_posted = ixgbe_read_posted_mbx;
516 mbx->ops.write_posted = ixgbe_write_posted_mbx;
517 mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
518 mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
519 mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
520
521 mbx->stats.msgs_tx = 0;
522 mbx->stats.msgs_rx = 0;
523 mbx->stats.reqs = 0;
524 mbx->stats.acks = 0;
525 mbx->stats.rsts = 0;
526 }
527
528 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
529 {
530 u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
531 s32 ret_val = IXGBE_ERR_MBX;
532
533 if (mbvficr & mask) {
534 ret_val = IXGBE_SUCCESS;
535 IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
536 }
537
538 return ret_val;
539 }
540
541 /**
542 * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
543 * @hw: pointer to the HW structure
544 * @vf_number: the VF index
545 *
546 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
547 **/
548 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
549 {
550 s32 ret_val = IXGBE_ERR_MBX;
551 s32 index = IXGBE_MBVFICR_INDEX(vf_number);
552 u32 vf_bit = vf_number % 16;
553
554 DEBUGFUNC("ixgbe_check_for_msg_pf");
555
556 if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
557 index)) {
558 ret_val = IXGBE_SUCCESS;
559 hw->mbx.stats.reqs++;
560 }
561
562 return ret_val;
563 }
564
565 /**
566 * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
567 * @hw: pointer to the HW structure
568 * @vf_number: the VF index
569 *
570 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
571 **/
572 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
573 {
574 s32 ret_val = IXGBE_ERR_MBX;
575 s32 index = IXGBE_MBVFICR_INDEX(vf_number);
576 u32 vf_bit = vf_number % 16;
577
578 DEBUGFUNC("ixgbe_check_for_ack_pf");
579
580 if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
581 index)) {
582 ret_val = IXGBE_SUCCESS;
583 hw->mbx.stats.acks++;
584 }
585
586 return ret_val;
587 }
588
589 /**
590 * ixgbe_check_for_rst_pf - checks to see if the VF has reset
591 * @hw: pointer to the HW structure
592 * @vf_number: the VF index
593 *
594 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
595 **/
596 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
597 {
598 u32 reg_offset = (vf_number < 32) ? 0 : 1;
599 u32 vf_shift = vf_number % 32;
600 u32 vflre = 0;
601 s32 ret_val = IXGBE_ERR_MBX;
602
603 DEBUGFUNC("ixgbe_check_for_rst_pf");
604
605 switch (hw->mac.type) {
606 case ixgbe_mac_82599EB:
607 vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
608 break;
609 case ixgbe_mac_X550:
610 case ixgbe_mac_X550EM_x:
611 case ixgbe_mac_X540:
612 vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
613 break;
614 default:
615 break;
616 }
617
618 if (vflre & (1 << vf_shift)) {
619 ret_val = IXGBE_SUCCESS;
620 IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
621 hw->mbx.stats.rsts++;
622 }
623
624 return ret_val;
625 }
626
627 /**
628 * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
629 * @hw: pointer to the HW structure
630 * @vf_number: the VF index
631 *
632 * return SUCCESS if we obtained the mailbox lock
633 **/
634 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
635 {
636 s32 ret_val = IXGBE_ERR_MBX;
637 u32 p2v_mailbox;
638
639 DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
640
641 /* Take ownership of the buffer */
642 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
643
644 /* reserve mailbox for vf use */
645 p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
646 if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
647 ret_val = IXGBE_SUCCESS;
648 else
649 ERROR_REPORT2(IXGBE_ERROR_POLLING,
650 "Failed to obtain mailbox lock for VF%d", vf_number);
651
652
653 return ret_val;
654 }
655
656 /**
657 * ixgbe_write_mbx_pf - Places a message in the mailbox
658 * @hw: pointer to the HW structure
659 * @msg: The message buffer
660 * @size: Length of buffer
661 * @vf_number: the VF index
662 *
663 * returns SUCCESS if it successfully copied message into the buffer
664 **/
665 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
666 u16 vf_number)
667 {
668 s32 ret_val;
669 u16 i;
670
671 DEBUGFUNC("ixgbe_write_mbx_pf");
672
673 /* lock the mailbox to prevent pf/vf race condition */
674 ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
675 if (ret_val)
676 goto out_no_write;
677
678 /* flush msg and acks as we are overwriting the message buffer */
679 ixgbe_check_for_msg_pf(hw, vf_number);
680 ixgbe_check_for_ack_pf(hw, vf_number);
681
682 /* copy the caller specified message to the mailbox memory buffer */
683 for (i = 0; i < size; i++)
684 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
685
686 /* Interrupt VF to tell it a message has been sent and release buffer*/
687 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
688
689 /* update stats */
690 hw->mbx.stats.msgs_tx++;
691
692 out_no_write:
693 return ret_val;
694
695 }
696
697 /**
698 * ixgbe_read_mbx_pf - Read a message from the mailbox
699 * @hw: pointer to the HW structure
700 * @msg: The message buffer
701 * @size: Length of buffer
702 * @vf_number: the VF index
703 *
704 * This function copies a message from the mailbox buffer to the caller's
705 * memory buffer. The presumption is that the caller knows that there was
706 * a message due to a VF request so no polling for message is needed.
707 **/
708 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
709 u16 vf_number)
710 {
711 s32 ret_val;
712 u16 i;
713
714 DEBUGFUNC("ixgbe_read_mbx_pf");
715
716 /* lock the mailbox to prevent pf/vf race condition */
717 ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
718 if (ret_val)
719 goto out_no_read;
720
721 /* copy the message to the mailbox memory buffer */
722 for (i = 0; i < size; i++)
723 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
724
725 /* Acknowledge the message and release buffer */
726 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
727
728 /* update stats */
729 hw->mbx.stats.msgs_rx++;
730
731 out_no_read:
732 return ret_val;
733 }
734
735 /**
736 * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
737 * @hw: pointer to the HW structure
738 *
739 * Initializes the hw->mbx struct to correct values for pf mailbox
740 */
741 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
742 {
743 struct ixgbe_mbx_info *mbx = &hw->mbx;
744
745 if (hw->mac.type != ixgbe_mac_82599EB &&
746 hw->mac.type != ixgbe_mac_X550 &&
747 hw->mac.type != ixgbe_mac_X550EM_x &&
748 hw->mac.type != ixgbe_mac_X540)
749 return;
750
751 mbx->timeout = 0;
752 mbx->usec_delay = 0;
753
754 mbx->size = IXGBE_VFMAILBOX_SIZE;
755
756 mbx->ops.read = ixgbe_read_mbx_pf;
757 mbx->ops.write = ixgbe_write_mbx_pf;
758 mbx->ops.read_posted = ixgbe_read_posted_mbx;
759 mbx->ops.write_posted = ixgbe_write_posted_mbx;
760 mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
761 mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
762 mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
763
764 mbx->stats.msgs_tx = 0;
765 mbx->stats.msgs_rx = 0;
766 mbx->stats.reqs = 0;
767 mbx->stats.acks = 0;
768 mbx->stats.rsts = 0;
769 }
770