aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/bfa/bfa_fcport.c232
-rw-r--r--drivers/scsi/bfa/bfa_port_priv.h13
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 @@
26BFA_TRC_FILE(HAL, PPORT); 26BFA_TRC_FILE(HAL, PPORT);
27BFA_MODULE(pport); 27BFA_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);
57static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete); 47static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete);
58static void bfa_port_stats_timeout(void *cbarg); 48static void bfa_port_stats_timeout(void *cbarg);
59static void bfa_port_stats_clr_timeout(void *cbarg); 49static void bfa_port_stats_clr_timeout(void *cbarg);
60 50static void bfa_pport_callback(struct bfa_pport_s *pport,
51 enum bfa_pport_linkstate event);
52static 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
77enum 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
80static void bfa_pport_sm_uninit(struct bfa_pport_s *pport, 83static void bfa_pport_sm_uninit(struct bfa_pport_s *pport,
81 enum bfa_pport_sm_event event); 84 enum bfa_pport_sm_event event);
82static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, 85static 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,
100static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport, 103static 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
106static void bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln,
107 enum bfa_pport_ln_sm_event event);
108static void bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln,
109 enum bfa_pport_ln_sm_event event);
110static void bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln,
111 enum bfa_pport_ln_sm_event event);
112static void bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln,
113 enum bfa_pport_ln_sm_event event);
114static void bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln,
115 enum bfa_pport_ln_sm_event event);
116static void bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln,
117 enum bfa_pport_ln_sm_event event);
118static void bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln,
119 enum bfa_pport_ln_sm_event event);
120
103static struct bfa_sm_table_s hal_pport_sm_table[] = { 121static 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 */
643static void
644bfa_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 */
663static void
664bfa_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 */
686static void
687bfa_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 */
710static void
711bfa_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 */
730static void
731bfa_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 */
753static void
754bfa_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 */
777static void
778bfa_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)
628static void 802static 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
1371static void 1550static void
1551bfa_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
1570static void
1571bfa_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
1577static 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 */
28struct 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 */
28struct bfa_pport_s { 38struct 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;