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