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