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