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