diff options
-rw-r--r-- | drivers/scsi/bfa/bfa_fcport.c | 232 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_port_priv.h | 13 |
2 files changed, 230 insertions, 15 deletions
diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c index aef648b55dfc..4ed048bf45cb 100644 --- a/drivers/scsi/bfa/bfa_fcport.c +++ b/drivers/scsi/bfa/bfa_fcport.c | |||
@@ -26,16 +26,6 @@ | |||
26 | BFA_TRC_FILE(HAL, PPORT); | 26 | BFA_TRC_FILE(HAL, PPORT); |
27 | BFA_MODULE(pport); | 27 | BFA_MODULE(pport); |
28 | 28 | ||
29 | #define bfa_pport_callback(__pport, __event) do { \ | ||
30 | if ((__pport)->bfa->fcs) { \ | ||
31 | (__pport)->event_cbfn((__pport)->event_cbarg, (__event)); \ | ||
32 | } else { \ | ||
33 | (__pport)->hcb_event = (__event); \ | ||
34 | bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe, \ | ||
35 | __bfa_cb_port_event, (__pport)); \ | ||
36 | } \ | ||
37 | } while (0) | ||
38 | |||
39 | /* | 29 | /* |
40 | * The port is considered disabled if corresponding physical port or IOC are | 30 | * The port is considered disabled if corresponding physical port or IOC are |
41 | * disabled explicitly | 31 | * disabled explicitly |
@@ -57,7 +47,10 @@ static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete); | |||
57 | static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete); | 47 | static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete); |
58 | static void bfa_port_stats_timeout(void *cbarg); | 48 | static void bfa_port_stats_timeout(void *cbarg); |
59 | static void bfa_port_stats_clr_timeout(void *cbarg); | 49 | static void bfa_port_stats_clr_timeout(void *cbarg); |
60 | 50 | static void bfa_pport_callback(struct bfa_pport_s *pport, | |
51 | enum bfa_pport_linkstate event); | ||
52 | static void bfa_pport_queue_cb(struct bfa_pport_ln_s *ln, | ||
53 | enum bfa_pport_linkstate event); | ||
61 | /** | 54 | /** |
62 | * bfa_pport_private | 55 | * bfa_pport_private |
63 | */ | 56 | */ |
@@ -77,6 +70,16 @@ enum bfa_pport_sm_event { | |||
77 | BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */ | 70 | BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */ |
78 | }; | 71 | }; |
79 | 72 | ||
73 | /** | ||
74 | * BFA port link notification state machine events | ||
75 | */ | ||
76 | |||
77 | enum bfa_pport_ln_sm_event { | ||
78 | BFA_PPORT_LN_SM_LINKUP = 1, /* linkup event */ | ||
79 | BFA_PPORT_LN_SM_LINKDOWN = 2, /* linkdown event */ | ||
80 | BFA_PPORT_LN_SM_NOTIFICATION = 3 /* done notification */ | ||
81 | }; | ||
82 | |||
80 | static void bfa_pport_sm_uninit(struct bfa_pport_s *pport, | 83 | static void bfa_pport_sm_uninit(struct bfa_pport_s *pport, |
81 | enum bfa_pport_sm_event event); | 84 | enum bfa_pport_sm_event event); |
82 | static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, | 85 | static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, |
@@ -100,6 +103,21 @@ static void bfa_pport_sm_iocdown(struct bfa_pport_s *pport, | |||
100 | static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport, | 103 | static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport, |
101 | enum bfa_pport_sm_event event); | 104 | enum bfa_pport_sm_event event); |
102 | 105 | ||
106 | static void bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln, | ||
107 | enum bfa_pport_ln_sm_event event); | ||
108 | static void bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln, | ||
109 | enum bfa_pport_ln_sm_event event); | ||
110 | static void bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln, | ||
111 | enum bfa_pport_ln_sm_event event); | ||
112 | static void bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln, | ||
113 | enum bfa_pport_ln_sm_event event); | ||
114 | static void bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln, | ||
115 | enum bfa_pport_ln_sm_event event); | ||
116 | static void bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln, | ||
117 | enum bfa_pport_ln_sm_event event); | ||
118 | static void bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln, | ||
119 | enum bfa_pport_ln_sm_event event); | ||
120 | |||
103 | static struct bfa_sm_table_s hal_pport_sm_table[] = { | 121 | static struct bfa_sm_table_s hal_pport_sm_table[] = { |
104 | {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT}, | 122 | {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT}, |
105 | {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT}, | 123 | {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT}, |
@@ -619,7 +637,163 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | |||
619 | } | 637 | } |
620 | } | 638 | } |
621 | 639 | ||
640 | /** | ||
641 | * Link state is down | ||
642 | */ | ||
643 | static void | ||
644 | bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln, | ||
645 | enum bfa_pport_ln_sm_event event) | ||
646 | { | ||
647 | bfa_trc(ln->pport->bfa, event); | ||
648 | |||
649 | switch (event) { | ||
650 | case BFA_PPORT_LN_SM_LINKUP: | ||
651 | bfa_sm_set_state(ln, bfa_pport_ln_sm_up_nf); | ||
652 | bfa_pport_queue_cb(ln, BFA_PPORT_LINKUP); | ||
653 | break; | ||
654 | |||
655 | default: | ||
656 | bfa_sm_fault(ln->pport->bfa, event); | ||
657 | } | ||
658 | } | ||
659 | |||
660 | /** | ||
661 | * Link state is waiting for down notification | ||
662 | */ | ||
663 | static void | ||
664 | bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln, | ||
665 | enum bfa_pport_ln_sm_event event) | ||
666 | { | ||
667 | bfa_trc(ln->pport->bfa, event); | ||
668 | |||
669 | switch (event) { | ||
670 | case BFA_PPORT_LN_SM_LINKUP: | ||
671 | bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_up_nf); | ||
672 | break; | ||
673 | |||
674 | case BFA_PPORT_LN_SM_NOTIFICATION: | ||
675 | bfa_sm_set_state(ln, bfa_pport_ln_sm_dn); | ||
676 | break; | ||
677 | |||
678 | default: | ||
679 | bfa_sm_fault(ln->pport->bfa, event); | ||
680 | } | ||
681 | } | ||
682 | |||
683 | /** | ||
684 | * Link state is waiting for down notification and there is a pending up | ||
685 | */ | ||
686 | static void | ||
687 | bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln, | ||
688 | enum bfa_pport_ln_sm_event event) | ||
689 | { | ||
690 | bfa_trc(ln->pport->bfa, event); | ||
691 | |||
692 | switch (event) { | ||
693 | case BFA_PPORT_LN_SM_LINKDOWN: | ||
694 | bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf); | ||
695 | break; | ||
696 | |||
697 | case BFA_PPORT_LN_SM_NOTIFICATION: | ||
698 | bfa_sm_set_state(ln, bfa_pport_ln_sm_up_nf); | ||
699 | bfa_pport_queue_cb(ln, BFA_PPORT_LINKUP); | ||
700 | break; | ||
701 | |||
702 | default: | ||
703 | bfa_sm_fault(ln->pport->bfa, event); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | /** | ||
708 | * Link state is up | ||
709 | */ | ||
710 | static void | ||
711 | bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln, | ||
712 | enum bfa_pport_ln_sm_event event) | ||
713 | { | ||
714 | bfa_trc(ln->pport->bfa, event); | ||
715 | |||
716 | switch (event) { | ||
717 | case BFA_PPORT_LN_SM_LINKDOWN: | ||
718 | bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf); | ||
719 | bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN); | ||
720 | break; | ||
721 | |||
722 | default: | ||
723 | bfa_sm_fault(ln->pport->bfa, event); | ||
724 | } | ||
725 | } | ||
726 | |||
727 | /** | ||
728 | * Link state is waiting for up notification | ||
729 | */ | ||
730 | static void | ||
731 | bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln, | ||
732 | enum bfa_pport_ln_sm_event event) | ||
733 | { | ||
734 | bfa_trc(ln->pport->bfa, event); | ||
735 | |||
736 | switch (event) { | ||
737 | case BFA_PPORT_LN_SM_LINKDOWN: | ||
738 | bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_nf); | ||
739 | break; | ||
740 | |||
741 | case BFA_PPORT_LN_SM_NOTIFICATION: | ||
742 | bfa_sm_set_state(ln, bfa_pport_ln_sm_up); | ||
743 | break; | ||
744 | |||
745 | default: | ||
746 | bfa_sm_fault(ln->pport->bfa, event); | ||
747 | } | ||
748 | } | ||
749 | |||
750 | /** | ||
751 | * Link state is waiting for up notification and there is a pending down | ||
752 | */ | ||
753 | static void | ||
754 | bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln, | ||
755 | enum bfa_pport_ln_sm_event event) | ||
756 | { | ||
757 | bfa_trc(ln->pport->bfa, event); | ||
622 | 758 | ||
759 | switch (event) { | ||
760 | case BFA_PPORT_LN_SM_LINKUP: | ||
761 | bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_up_nf); | ||
762 | break; | ||
763 | |||
764 | case BFA_PPORT_LN_SM_NOTIFICATION: | ||
765 | bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf); | ||
766 | bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN); | ||
767 | break; | ||
768 | |||
769 | default: | ||
770 | bfa_sm_fault(ln->pport->bfa, event); | ||
771 | } | ||
772 | } | ||
773 | |||
774 | /** | ||
775 | * Link state is waiting for up notification and there are pending down and up | ||
776 | */ | ||
777 | static void | ||
778 | bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln, | ||
779 | enum bfa_pport_ln_sm_event event) | ||
780 | { | ||
781 | bfa_trc(ln->pport->bfa, event); | ||
782 | |||
783 | switch (event) { | ||
784 | case BFA_PPORT_LN_SM_LINKDOWN: | ||
785 | bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_nf); | ||
786 | break; | ||
787 | |||
788 | case BFA_PPORT_LN_SM_NOTIFICATION: | ||
789 | bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_up_nf); | ||
790 | bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN); | ||
791 | break; | ||
792 | |||
793 | default: | ||
794 | bfa_sm_fault(ln->pport->bfa, event); | ||
795 | } | ||
796 | } | ||
623 | 797 | ||
624 | /** | 798 | /** |
625 | * bfa_pport_private | 799 | * bfa_pport_private |
@@ -628,10 +802,12 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | |||
628 | static void | 802 | static void |
629 | __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete) | 803 | __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete) |
630 | { | 804 | { |
631 | struct bfa_pport_s *pport = cbarg; | 805 | struct bfa_pport_ln_s *ln = cbarg; |
632 | 806 | ||
633 | if (complete) | 807 | if (complete) |
634 | pport->event_cbfn(pport->event_cbarg, pport->hcb_event); | 808 | ln->pport->event_cbfn(ln->pport->event_cbarg, ln->ln_event); |
809 | else | ||
810 | bfa_sm_send_event(ln, BFA_PPORT_LN_SM_NOTIFICATION); | ||
635 | } | 811 | } |
636 | 812 | ||
637 | #define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \ | 813 | #define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \ |
@@ -681,13 +857,16 @@ bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
681 | { | 857 | { |
682 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 858 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); |
683 | struct bfa_pport_cfg_s *port_cfg = &pport->cfg; | 859 | struct bfa_pport_cfg_s *port_cfg = &pport->cfg; |
860 | struct bfa_pport_ln_s *ln = &pport->ln; | ||
684 | 861 | ||
685 | bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s)); | 862 | bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s)); |
686 | pport->bfa = bfa; | 863 | pport->bfa = bfa; |
864 | ln->pport = pport; | ||
687 | 865 | ||
688 | bfa_pport_mem_claim(pport, meminfo); | 866 | bfa_pport_mem_claim(pport, meminfo); |
689 | 867 | ||
690 | bfa_sm_set_state(pport, bfa_pport_sm_uninit); | 868 | bfa_sm_set_state(pport, bfa_pport_sm_uninit); |
869 | bfa_sm_set_state(ln, bfa_pport_ln_sm_dn); | ||
691 | 870 | ||
692 | /** | 871 | /** |
693 | * initialize and set default configuration | 872 | * initialize and set default configuration |
@@ -1369,6 +1548,33 @@ bfa_port_stats_clr_timeout(void *cbarg) | |||
1369 | } | 1548 | } |
1370 | 1549 | ||
1371 | static void | 1550 | static void |
1551 | bfa_pport_callback(struct bfa_pport_s *pport, enum bfa_pport_linkstate event) | ||
1552 | { | ||
1553 | if (pport->bfa->fcs) { | ||
1554 | pport->event_cbfn(pport->event_cbarg, event); | ||
1555 | return; | ||
1556 | } | ||
1557 | |||
1558 | switch (event) { | ||
1559 | case BFA_PPORT_LINKUP: | ||
1560 | bfa_sm_send_event(&pport->ln, BFA_PPORT_LN_SM_LINKUP); | ||
1561 | break; | ||
1562 | case BFA_PPORT_LINKDOWN: | ||
1563 | bfa_sm_send_event(&pport->ln, BFA_PPORT_LN_SM_LINKDOWN); | ||
1564 | break; | ||
1565 | default: | ||
1566 | bfa_assert(0); | ||
1567 | } | ||
1568 | } | ||
1569 | |||
1570 | static void | ||
1571 | bfa_pport_queue_cb(struct bfa_pport_ln_s *ln, enum bfa_pport_linkstate event) | ||
1572 | { | ||
1573 | ln->ln_event = event; | ||
1574 | bfa_cb_queue(ln->pport->bfa, &ln->ln_qe, __bfa_cb_port_event, ln); | ||
1575 | } | ||
1576 | |||
1577 | static void | ||
1372 | __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete) | 1578 | __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete) |
1373 | { | 1579 | { |
1374 | struct bfa_pport_s *port = cbarg; | 1580 | struct bfa_pport_s *port = cbarg; |
diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h index 51f698a06b6d..f29701bd2369 100644 --- a/drivers/scsi/bfa/bfa_port_priv.h +++ b/drivers/scsi/bfa/bfa_port_priv.h | |||
@@ -23,6 +23,16 @@ | |||
23 | #include "bfa_intr_priv.h" | 23 | #include "bfa_intr_priv.h" |
24 | 24 | ||
25 | /** | 25 | /** |
26 | * Link notification data structure | ||
27 | */ | ||
28 | struct bfa_pport_ln_s { | ||
29 | struct bfa_pport_s *pport; | ||
30 | bfa_sm_t sm; | ||
31 | struct bfa_cb_qe_s ln_qe; /* BFA callback queue elem for ln */ | ||
32 | enum bfa_pport_linkstate ln_event; /* ln event for callback */ | ||
33 | }; | ||
34 | |||
35 | /** | ||
26 | * BFA physical port data structure | 36 | * BFA physical port data structure |
27 | */ | 37 | */ |
28 | struct bfa_pport_s { | 38 | struct bfa_pport_s { |
@@ -52,9 +62,8 @@ struct bfa_pport_s { | |||
52 | union bfi_pport_i2h_msg_u i2hmsg; | 62 | union bfi_pport_i2h_msg_u i2hmsg; |
53 | } event_arg; | 63 | } event_arg; |
54 | void *bfad; /* BFA driver handle */ | 64 | void *bfad; /* BFA driver handle */ |
65 | struct bfa_pport_ln_s ln; /* Link Notification */ | ||
55 | struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */ | 66 | struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */ |
56 | enum bfa_pport_linkstate hcb_event; | ||
57 | /* link event for callback */ | ||
58 | u32 msgtag; /* fimrware msg tag for reply */ | 67 | u32 msgtag; /* fimrware msg tag for reply */ |
59 | u8 *stats_kva; | 68 | u8 *stats_kva; |
60 | u64 stats_pa; | 69 | u64 stats_pa; |