aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2011-06-24 23:23:19 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-06-29 17:59:01 -0400
commita714134a857d3984250ee52fda7850b61bf8a94e (patch)
tree95a54d43ded235da2b61e15499151998ed9df3d8
parent5a0adaedffce91100d03fc1036dde024c8589295 (diff)
[SCSI] bfa: Added Fabric Assigned Address(FAA) support
- Updated/added data structures and definitions to support FAA protocol. - Modified the IOC state machine to support FAA. - Introduced FAA feature configuration - enable/disable/query. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/bfa/bfa.h26
-rw-r--r--drivers/scsi/bfa/bfa_core.c192
-rw-r--r--drivers/scsi/bfa/bfa_defs.h13
-rw-r--r--drivers/scsi/bfa/bfa_defs_svc.h4
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c67
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h1
-rw-r--r--drivers/scsi/bfa/bfa_svc.c36
-rw-r--r--drivers/scsi/bfa/bfa_svc.h9
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c76
-rw-r--r--drivers/scsi/bfa/bfad_bsg.h10
-rw-r--r--drivers/scsi/bfa/bfi.h1
-rw-r--r--drivers/scsi/bfa/bfi_ms.h37
12 files changed, 466 insertions, 6 deletions
diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h
index 8c73265f977d..42769bc07ff4 100644
--- a/drivers/scsi/bfa/bfa.h
+++ b/drivers/scsi/bfa/bfa.h
@@ -241,6 +241,31 @@ struct bfa_hwif_s {
241}; 241};
242typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status); 242typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status);
243 243
244struct bfa_faa_cbfn_s {
245 bfa_cb_iocfc_t faa_cbfn;
246 void *faa_cbarg;
247};
248
249#define BFA_FAA_ENABLED 1
250#define BFA_FAA_DISABLED 2
251
252/*
253 * FAA attributes
254 */
255struct bfa_faa_attr_s {
256 wwn_t faa;
257 u8 faa_state;
258 u8 pwwn_source;
259 u8 rsvd[6];
260};
261
262struct bfa_faa_args_s {
263 struct bfa_faa_attr_s *faa_attr;
264 struct bfa_faa_cbfn_s faa_cb;
265 u8 faa_state;
266 bfa_boolean_t busy;
267};
268
244struct bfa_iocfc_s { 269struct bfa_iocfc_s {
245 struct bfa_s *bfa; 270 struct bfa_s *bfa;
246 struct bfa_iocfc_cfg_s cfg; 271 struct bfa_iocfc_cfg_s cfg;
@@ -266,6 +291,7 @@ struct bfa_iocfc_s {
266 bfa_cb_iocfc_t updateq_cbfn; /* bios callback function */ 291 bfa_cb_iocfc_t updateq_cbfn; /* bios callback function */
267 void *updateq_cbarg; /* bios callback arg */ 292 void *updateq_cbarg; /* bios callback arg */
268 u32 intr_mask; 293 u32 intr_mask;
294 struct bfa_faa_args_s faa_args;
269}; 295};
270 296
271#define bfa_lpuid(__bfa) \ 297#define bfa_lpuid(__bfa) \
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index 2b497243baf4..4befbf9fd888 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -795,6 +795,181 @@ bfa_iocfc_reset_queues(struct bfa_s *bfa)
795 } 795 }
796} 796}
797 797
798/* Fabric Assigned Address specific functions */
799
800/*
801 * Check whether IOC is ready before sending command down
802 */
803static bfa_status_t
804bfa_faa_validate_request(struct bfa_s *bfa)
805{
806 enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);
807 u32 card_type = bfa->ioc.attr->card_type;
808
809 if (bfa_ioc_is_operational(&bfa->ioc)) {
810 if ((ioc_type != BFA_IOC_TYPE_FC) || bfa_mfg_is_mezz(card_type))
811 return BFA_STATUS_FEATURE_NOT_SUPPORTED;
812 } else {
813 if (!bfa_ioc_is_acq_addr(&bfa->ioc))
814 return BFA_STATUS_IOC_NON_OP;
815 }
816
817 return BFA_STATUS_OK;
818}
819
820bfa_status_t
821bfa_faa_enable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn, void *cbarg)
822{
823 struct bfi_faa_en_dis_s faa_enable_req;
824 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
825 bfa_status_t status;
826
827 iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
828 iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
829
830 status = bfa_faa_validate_request(bfa);
831 if (status != BFA_STATUS_OK)
832 return status;
833
834 if (iocfc->faa_args.busy == BFA_TRUE)
835 return BFA_STATUS_DEVBUSY;
836
837 if (iocfc->faa_args.faa_state == BFA_FAA_ENABLED)
838 return BFA_STATUS_FAA_ENABLED;
839
840 if (bfa_fcport_is_trunk_enabled(bfa))
841 return BFA_STATUS_ERROR_TRUNK_ENABLED;
842
843 bfa_fcport_cfg_faa(bfa, BFA_FAA_ENABLED);
844 iocfc->faa_args.busy = BFA_TRUE;
845
846 memset(&faa_enable_req, 0, sizeof(struct bfi_faa_en_dis_s));
847 bfi_h2i_set(faa_enable_req.mh, BFI_MC_IOCFC,
848 BFI_IOCFC_H2I_FAA_ENABLE_REQ, bfa_lpuid(bfa));
849
850 bfa_ioc_mbox_send(&bfa->ioc, &faa_enable_req,
851 sizeof(struct bfi_faa_en_dis_s));
852
853 return BFA_STATUS_OK;
854}
855
856bfa_status_t
857bfa_faa_disable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn,
858 void *cbarg)
859{
860 struct bfi_faa_en_dis_s faa_disable_req;
861 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
862 bfa_status_t status;
863
864 iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
865 iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
866
867 status = bfa_faa_validate_request(bfa);
868 if (status != BFA_STATUS_OK)
869 return status;
870
871 if (iocfc->faa_args.busy == BFA_TRUE)
872 return BFA_STATUS_DEVBUSY;
873
874 if (iocfc->faa_args.faa_state == BFA_FAA_DISABLED)
875 return BFA_STATUS_FAA_DISABLED;
876
877 bfa_fcport_cfg_faa(bfa, BFA_FAA_DISABLED);
878 iocfc->faa_args.busy = BFA_TRUE;
879
880 memset(&faa_disable_req, 0, sizeof(struct bfi_faa_en_dis_s));
881 bfi_h2i_set(faa_disable_req.mh, BFI_MC_IOCFC,
882 BFI_IOCFC_H2I_FAA_DISABLE_REQ, bfa_lpuid(bfa));
883
884 bfa_ioc_mbox_send(&bfa->ioc, &faa_disable_req,
885 sizeof(struct bfi_faa_en_dis_s));
886
887 return BFA_STATUS_OK;
888}
889
890bfa_status_t
891bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr,
892 bfa_cb_iocfc_t cbfn, void *cbarg)
893{
894 struct bfi_faa_query_s faa_attr_req;
895 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
896 bfa_status_t status;
897
898 iocfc->faa_args.faa_attr = attr;
899 iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
900 iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
901
902 status = bfa_faa_validate_request(bfa);
903 if (status != BFA_STATUS_OK)
904 return status;
905
906 if (iocfc->faa_args.busy == BFA_TRUE)
907 return BFA_STATUS_DEVBUSY;
908
909 iocfc->faa_args.busy = BFA_TRUE;
910 memset(&faa_attr_req, 0, sizeof(struct bfi_faa_query_s));
911 bfi_h2i_set(faa_attr_req.mh, BFI_MC_IOCFC,
912 BFI_IOCFC_H2I_FAA_QUERY_REQ, bfa_lpuid(bfa));
913
914 bfa_ioc_mbox_send(&bfa->ioc, &faa_attr_req,
915 sizeof(struct bfi_faa_query_s));
916
917 return BFA_STATUS_OK;
918}
919
920/*
921 * FAA enable response
922 */
923static void
924bfa_faa_enable_reply(struct bfa_iocfc_s *iocfc,
925 struct bfi_faa_en_dis_rsp_s *rsp)
926{
927 void *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
928 bfa_status_t status = rsp->status;
929
930 WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
931
932 iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
933 iocfc->faa_args.busy = BFA_FALSE;
934}
935
936/*
937 * FAA disable response
938 */
939static void
940bfa_faa_disable_reply(struct bfa_iocfc_s *iocfc,
941 struct bfi_faa_en_dis_rsp_s *rsp)
942{
943 void *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
944 bfa_status_t status = rsp->status;
945
946 WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
947
948 iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
949 iocfc->faa_args.busy = BFA_FALSE;
950}
951
952/*
953 * FAA query response
954 */
955static void
956bfa_faa_query_reply(struct bfa_iocfc_s *iocfc,
957 bfi_faa_query_rsp_t *rsp)
958{
959 void *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
960
961 if (iocfc->faa_args.faa_attr) {
962 iocfc->faa_args.faa_attr->faa = rsp->faa;
963 iocfc->faa_args.faa_attr->faa_state = rsp->faa_status;
964 iocfc->faa_args.faa_attr->pwwn_source = rsp->addr_source;
965 }
966
967 WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
968
969 iocfc->faa_args.faa_cb.faa_cbfn(cbarg, BFA_STATUS_OK);
970 iocfc->faa_args.busy = BFA_FALSE;
971}
972
798/* 973/*
799 * IOC enable request is complete 974 * IOC enable request is complete
800 */ 975 */
@@ -803,6 +978,12 @@ bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
803{ 978{
804 struct bfa_s *bfa = bfa_arg; 979 struct bfa_s *bfa = bfa_arg;
805 980
981 if (status == BFA_STATUS_FAA_ACQ_ADDR) {
982 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
983 bfa_iocfc_init_cb, bfa);
984 return;
985 }
986
806 if (status != BFA_STATUS_OK) { 987 if (status != BFA_STATUS_OK) {
807 bfa_isr_disable(bfa); 988 bfa_isr_disable(bfa);
808 if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT) 989 if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
@@ -968,6 +1149,17 @@ bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m)
968 case BFI_IOCFC_I2H_UPDATEQ_RSP: 1149 case BFI_IOCFC_I2H_UPDATEQ_RSP:
969 iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK); 1150 iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK);
970 break; 1151 break;
1152 case BFI_IOCFC_I2H_FAA_ENABLE_RSP:
1153 bfa_faa_enable_reply(iocfc,
1154 (struct bfi_faa_en_dis_rsp_s *)msg);
1155 break;
1156 case BFI_IOCFC_I2H_FAA_DISABLE_RSP:
1157 bfa_faa_disable_reply(iocfc,
1158 (struct bfi_faa_en_dis_rsp_s *)msg);
1159 break;
1160 case BFI_IOCFC_I2H_FAA_QUERY_RSP:
1161 bfa_faa_query_reply(iocfc, (bfi_faa_query_rsp_t *)msg);
1162 break;
971 default: 1163 default:
972 WARN_ON(1); 1164 WARN_ON(1);
973 } 1165 }
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h
index c675e65c77a4..bb382656c8c9 100644
--- a/drivers/scsi/bfa/bfa_defs.h
+++ b/drivers/scsi/bfa/bfa_defs.h
@@ -145,6 +145,7 @@ enum bfa_status {
145 BFA_STATUS_IOC_FAILURE = 56, /* IOC failure - Retry, if persists 145 BFA_STATUS_IOC_FAILURE = 56, /* IOC failure - Retry, if persists
146 * contact support */ 146 * contact support */
147 BFA_STATUS_INVALID_WWN = 57, /* Invalid WWN */ 147 BFA_STATUS_INVALID_WWN = 57, /* Invalid WWN */
148 BFA_STATUS_IOC_NON_OP = 61, /* IOC is not operational */
148 BFA_STATUS_VERSION_FAIL = 70, /* Application/Driver version mismatch */ 149 BFA_STATUS_VERSION_FAIL = 70, /* Application/Driver version mismatch */
149 BFA_STATUS_DIAG_BUSY = 71, /* diag busy */ 150 BFA_STATUS_DIAG_BUSY = 71, /* diag busy */
150 BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */ 151 BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */
@@ -157,6 +158,12 @@ enum bfa_status {
157 BFA_STATUS_TRUNK_DISABLED = 165, /* Trunking is disabled on 158 BFA_STATUS_TRUNK_DISABLED = 165, /* Trunking is disabled on
158 * the adapter */ 159 * the adapter */
159 BFA_STATUS_IOPROFILE_OFF = 175, /* IO profile OFF */ 160 BFA_STATUS_IOPROFILE_OFF = 175, /* IO profile OFF */
161 BFA_STATUS_FEATURE_NOT_SUPPORTED = 192, /* Feature not supported */
162 BFA_STATUS_FAA_ENABLED = 197, /* FAA is already enabled */
163 BFA_STATUS_FAA_DISABLED = 198, /* FAA is already disabled */
164 BFA_STATUS_FAA_ACQUIRED = 199, /* FAA is already acquired */
165 BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */
166 BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */
160 BFA_STATUS_MAX_VAL /* Unknown error code */ 167 BFA_STATUS_MAX_VAL /* Unknown error code */
161}; 168};
162#define bfa_status_t enum bfa_status 169#define bfa_status_t enum bfa_status
@@ -275,6 +282,7 @@ enum bfa_ioc_state {
275 BFA_IOC_FWMISMATCH = 11, /* IOC f/w different from drivers */ 282 BFA_IOC_FWMISMATCH = 11, /* IOC f/w different from drivers */
276 BFA_IOC_ENABLING = 12, /* IOC is being enabled */ 283 BFA_IOC_ENABLING = 12, /* IOC is being enabled */
277 BFA_IOC_HWFAIL = 13, /* PCI mapping doesn't exist */ 284 BFA_IOC_HWFAIL = 13, /* PCI mapping doesn't exist */
285 BFA_IOC_ACQ_ADDR = 14, /* Acquiring addr from fabric */
278}; 286};
279 287
280/* 288/*
@@ -455,10 +463,7 @@ enum bfa_port_speed {
455 BFA_PORT_SPEED_8GBPS = 8, 463 BFA_PORT_SPEED_8GBPS = 8,
456 BFA_PORT_SPEED_10GBPS = 10, 464 BFA_PORT_SPEED_10GBPS = 10,
457 BFA_PORT_SPEED_16GBPS = 16, 465 BFA_PORT_SPEED_16GBPS = 16,
458 BFA_PORT_SPEED_AUTO = 466 BFA_PORT_SPEED_AUTO = 0xf,
459 (BFA_PORT_SPEED_1GBPS | BFA_PORT_SPEED_2GBPS |
460 BFA_PORT_SPEED_4GBPS | BFA_PORT_SPEED_8GBPS |
461 BFA_PORT_SPEED_16GBPS),
462}; 467};
463#define bfa_port_speed_t enum bfa_port_speed 468#define bfa_port_speed_t enum bfa_port_speed
464 469
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h
index 0ee3f954dc85..d8861872ac70 100644
--- a/drivers/scsi/bfa/bfa_defs_svc.h
+++ b/drivers/scsi/bfa/bfa_defs_svc.h
@@ -635,6 +635,7 @@ enum bfa_port_states {
635 BFA_PORT_ST_FWMISMATCH = 12, 635 BFA_PORT_ST_FWMISMATCH = 12,
636 BFA_PORT_ST_PREBOOT_DISABLED = 13, 636 BFA_PORT_ST_PREBOOT_DISABLED = 13,
637 BFA_PORT_ST_TOGGLING_QWAIT = 14, 637 BFA_PORT_ST_TOGGLING_QWAIT = 14,
638 BFA_PORT_ST_ACQ_ADDR = 15,
638 BFA_PORT_ST_MAX_STATE, 639 BFA_PORT_ST_MAX_STATE,
639}; 640};
640 641
@@ -748,7 +749,8 @@ struct bfa_port_cfg_s {
748 u8 ratelimit; /* ratelimit enabled or not */ 749 u8 ratelimit; /* ratelimit enabled or not */
749 u8 trl_def_speed; /* ratelimit default speed */ 750 u8 trl_def_speed; /* ratelimit default speed */
750 u8 bb_scn; 751 u8 bb_scn;
751 u8 rsvd[3]; 752 u8 faa_state; /* FAA enabled/disabled */
753 u8 rsvd[2];
752 u16 path_tov; /* device path timeout */ 754 u16 path_tov; /* device path timeout */
753 u16 q_depth; /* SCSI Queue depth */ 755 u16 q_depth; /* SCSI Queue depth */
754}; 756};
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index 931bf9769ff2..7b4a567ca22a 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -113,6 +113,7 @@ enum ioc_event {
113 IOC_E_HWERROR = 10, /* hardware error interrupt */ 113 IOC_E_HWERROR = 10, /* hardware error interrupt */
114 IOC_E_TIMEOUT = 11, /* timeout */ 114 IOC_E_TIMEOUT = 11, /* timeout */
115 IOC_E_HWFAILED = 12, /* PCI mapping failure notice */ 115 IOC_E_HWFAILED = 12, /* PCI mapping failure notice */
116 IOC_E_FWRSP_ACQ_ADDR = 13, /* Acquiring address */
116}; 117};
117 118
118bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event); 119bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event);
@@ -125,6 +126,7 @@ bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event);
125bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event); 126bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
126bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event); 127bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
127bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc_s, enum ioc_event); 128bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc_s, enum ioc_event);
129bfa_fsm_state_decl(bfa_ioc, acq_addr, struct bfa_ioc_s, enum ioc_event);
128 130
129static struct bfa_sm_table_s ioc_sm_table[] = { 131static struct bfa_sm_table_s ioc_sm_table[] = {
130 {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT}, 132 {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
@@ -137,6 +139,7 @@ static struct bfa_sm_table_s ioc_sm_table[] = {
137 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, 139 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
138 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, 140 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
139 {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL}, 141 {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL},
142 {BFA_SM(bfa_ioc_sm_acq_addr), BFA_IOC_ACQ_ADDR},
140}; 143};
141 144
142/* 145/*
@@ -368,10 +371,16 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
368 case IOC_E_FWRSP_GETATTR: 371 case IOC_E_FWRSP_GETATTR:
369 bfa_ioc_timer_stop(ioc); 372 bfa_ioc_timer_stop(ioc);
370 bfa_ioc_check_attr_wwns(ioc); 373 bfa_ioc_check_attr_wwns(ioc);
374 bfa_ioc_hb_monitor(ioc);
371 bfa_fsm_set_state(ioc, bfa_ioc_sm_op); 375 bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
372 break; 376 break;
373 377
378 case IOC_E_FWRSP_ACQ_ADDR:
379 bfa_ioc_timer_stop(ioc);
380 bfa_ioc_hb_monitor(ioc);
381 bfa_fsm_set_state(ioc, bfa_ioc_sm_acq_addr);
374 break; 382 break;
383
375 case IOC_E_PFFAILED: 384 case IOC_E_PFFAILED:
376 case IOC_E_HWERROR: 385 case IOC_E_HWERROR:
377 bfa_ioc_timer_stop(ioc); 386 bfa_ioc_timer_stop(ioc);
@@ -396,6 +405,50 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
396 } 405 }
397} 406}
398 407
408/*
409 * Acquiring address from fabric (entry function)
410 */
411static void
412bfa_ioc_sm_acq_addr_entry(struct bfa_ioc_s *ioc)
413{
414}
415
416/*
417 * Acquiring address from the fabric
418 */
419static void
420bfa_ioc_sm_acq_addr(struct bfa_ioc_s *ioc, enum ioc_event event)
421{
422 bfa_trc(ioc, event);
423
424 switch (event) {
425 case IOC_E_FWRSP_GETATTR:
426 bfa_ioc_check_attr_wwns(ioc);
427 bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
428 break;
429
430 case IOC_E_PFFAILED:
431 case IOC_E_HWERROR:
432 bfa_hb_timer_stop(ioc);
433 case IOC_E_HBFAIL:
434 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
435 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
436 if (event != IOC_E_PFFAILED)
437 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
438 break;
439
440 case IOC_E_DISABLE:
441 bfa_hb_timer_stop(ioc);
442 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
443 break;
444
445 case IOC_E_ENABLE:
446 break;
447
448 default:
449 bfa_sm_fault(ioc, event);
450 }
451}
399 452
400static void 453static void
401bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc) 454bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
@@ -404,7 +457,6 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
404 457
405 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); 458 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
406 bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED); 459 bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
407 bfa_ioc_hb_monitor(ioc);
408 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n"); 460 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
409} 461}
410 462
@@ -2065,6 +2117,10 @@ bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
2065 bfa_ioc_getattr_reply(ioc); 2117 bfa_ioc_getattr_reply(ioc);
2066 break; 2118 break;
2067 2119
2120 case BFI_IOC_I2H_ACQ_ADDR_REPLY:
2121 bfa_fsm_send_event(ioc, IOC_E_FWRSP_ACQ_ADDR);
2122 break;
2123
2068 default: 2124 default:
2069 bfa_trc(ioc, msg->mh.msg_id); 2125 bfa_trc(ioc, msg->mh.msg_id);
2070 WARN_ON(1); 2126 WARN_ON(1);
@@ -2360,6 +2416,15 @@ bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
2360} 2416}
2361 2417
2362/* 2418/*
2419 * Return TRUE if IOC is in acquiring address state
2420 */
2421bfa_boolean_t
2422bfa_ioc_is_acq_addr(struct bfa_ioc_s *ioc)
2423{
2424 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_acq_addr);
2425}
2426
2427/*
2363 * return true if IOC firmware is different. 2428 * return true if IOC firmware is different.
2364 */ 2429 */
2365bfa_boolean_t 2430bfa_boolean_t
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index 337d0366845f..78e9606217ea 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -390,6 +390,7 @@ void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
390bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc); 390bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc);
391bfa_boolean_t bfa_ioc_is_initialized(struct bfa_ioc_s *ioc); 391bfa_boolean_t bfa_ioc_is_initialized(struct bfa_ioc_s *ioc);
392bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc); 392bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc);
393bfa_boolean_t bfa_ioc_is_acq_addr(struct bfa_ioc_s *ioc);
393bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc); 394bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc);
394bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc); 395bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc);
395void bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc); 396void bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc);
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index 5373e5ddd4ad..fe99ce20ec28 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -3502,6 +3502,28 @@ bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed)
3502 return BFA_STATUS_UNSUPP_SPEED; 3502 return BFA_STATUS_UNSUPP_SPEED;
3503 } 3503 }
3504 3504
3505 /* For Mezz card, port speed entered needs to be checked */
3506 if (bfa_mfg_is_mezz(fcport->bfa->ioc.attr->card_type)) {
3507 if (bfa_ioc_get_type(&fcport->bfa->ioc) == BFA_IOC_TYPE_FC) {
3508 /* For CT2, 1G is not supported */
3509 if ((speed == BFA_PORT_SPEED_1GBPS) &&
3510 (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)))
3511 return BFA_STATUS_UNSUPP_SPEED;
3512
3513 /* Already checked for Auto Speed and Max Speed supp */
3514 if (!(speed == BFA_PORT_SPEED_1GBPS ||
3515 speed == BFA_PORT_SPEED_2GBPS ||
3516 speed == BFA_PORT_SPEED_4GBPS ||
3517 speed == BFA_PORT_SPEED_8GBPS ||
3518 speed == BFA_PORT_SPEED_16GBPS ||
3519 speed == BFA_PORT_SPEED_AUTO))
3520 return BFA_STATUS_UNSUPP_SPEED;
3521 } else {
3522 if (speed != BFA_PORT_SPEED_10GBPS)
3523 return BFA_STATUS_UNSUPP_SPEED;
3524 }
3525 }
3526
3505 fcport->cfg.speed = speed; 3527 fcport->cfg.speed = speed;
3506 3528
3507 return BFA_STATUS_OK; 3529 return BFA_STATUS_OK;
@@ -3705,6 +3727,8 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
3705 attr->port_state = BFA_PORT_ST_IOCDIS; 3727 attr->port_state = BFA_PORT_ST_IOCDIS;
3706 else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc)) 3728 else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
3707 attr->port_state = BFA_PORT_ST_FWMISMATCH; 3729 attr->port_state = BFA_PORT_ST_FWMISMATCH;
3730 else if (bfa_ioc_is_acq_addr(&fcport->bfa->ioc))
3731 attr->port_state = BFA_PORT_ST_ACQ_ADDR;
3708 } 3732 }
3709 3733
3710 /* FCoE vlan */ 3734 /* FCoE vlan */
@@ -3787,6 +3811,18 @@ bfa_fcport_is_ratelim(struct bfa_s *bfa)
3787} 3811}
3788 3812
3789/* 3813/*
3814 * Enable/Disable FAA feature in port config
3815 */
3816void
3817bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state)
3818{
3819 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3820
3821 bfa_trc(bfa, state);
3822 fcport->cfg.faa_state = state;
3823}
3824
3825/*
3790 * Get default minimum ratelim speed 3826 * Get default minimum ratelim speed
3791 */ 3827 */
3792enum bfa_port_speed 3828enum bfa_port_speed
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h
index c81cf5cb856f..acb30efc953d 100644
--- a/drivers/scsi/bfa/bfa_svc.h
+++ b/drivers/scsi/bfa/bfa_svc.h
@@ -529,6 +529,7 @@ bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn,
529bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa); 529bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa);
530bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa); 530bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa);
531bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa); 531bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa);
532void bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state);
532 533
533/* 534/*
534 * bfa rport API functions 535 * bfa rport API functions
@@ -623,4 +624,12 @@ void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
623void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg); 624void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
624void bfa_cb_lps_cvl_event(void *bfad, void *uarg); 625void bfa_cb_lps_cvl_event(void *bfad, void *uarg);
625 626
627/* FAA specific APIs */
628bfa_status_t bfa_faa_enable(struct bfa_s *bfa,
629 bfa_cb_iocfc_t cbfn, void *cbarg);
630bfa_status_t bfa_faa_disable(struct bfa_s *bfa,
631 bfa_cb_iocfc_t cbfn, void *cbarg);
632bfa_status_t bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr,
633 bfa_cb_iocfc_t cbfn, void *cbarg);
634
626#endif /* __BFA_SVC_H__ */ 635#endif /* __BFA_SVC_H__ */
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 35c415c81dad..9ec8f04b16c0 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -437,6 +437,73 @@ out:
437 return 0; 437 return 0;
438} 438}
439 439
440int
441bfad_iocmd_faa_enable(struct bfad_s *bfad, void *cmd)
442{
443 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
444 unsigned long flags;
445 struct bfad_hal_comp fcomp;
446
447 init_completion(&fcomp.comp);
448 iocmd->status = BFA_STATUS_OK;
449 spin_lock_irqsave(&bfad->bfad_lock, flags);
450 iocmd->status = bfa_faa_enable(&bfad->bfa, bfad_hcb_comp, &fcomp);
451 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
452
453 if (iocmd->status != BFA_STATUS_OK)
454 goto out;
455
456 wait_for_completion(&fcomp.comp);
457 iocmd->status = fcomp.status;
458out:
459 return 0;
460}
461
462int
463bfad_iocmd_faa_disable(struct bfad_s *bfad, void *cmd)
464{
465 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
466 unsigned long flags;
467 struct bfad_hal_comp fcomp;
468
469 init_completion(&fcomp.comp);
470 iocmd->status = BFA_STATUS_OK;
471 spin_lock_irqsave(&bfad->bfad_lock, flags);
472 iocmd->status = bfa_faa_disable(&bfad->bfa, bfad_hcb_comp, &fcomp);
473 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
474
475 if (iocmd->status != BFA_STATUS_OK)
476 goto out;
477
478 wait_for_completion(&fcomp.comp);
479 iocmd->status = fcomp.status;
480out:
481 return 0;
482}
483
484int
485bfad_iocmd_faa_query(struct bfad_s *bfad, void *cmd)
486{
487 struct bfa_bsg_faa_attr_s *iocmd = (struct bfa_bsg_faa_attr_s *)cmd;
488 struct bfad_hal_comp fcomp;
489 unsigned long flags;
490
491 init_completion(&fcomp.comp);
492 iocmd->status = BFA_STATUS_OK;
493 spin_lock_irqsave(&bfad->bfad_lock, flags);
494 iocmd->status = bfa_faa_query(&bfad->bfa, &iocmd->faa_attr,
495 bfad_hcb_comp, &fcomp);
496 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
497
498 if (iocmd->status != BFA_STATUS_OK)
499 goto out;
500
501 wait_for_completion(&fcomp.comp);
502 iocmd->status = fcomp.status;
503out:
504 return 0;
505}
506
440static int 507static int
441bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, 508bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
442 unsigned int payload_len) 509 unsigned int payload_len)
@@ -487,6 +554,15 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
487 case IOCMD_FLASH_DISABLE_OPTROM: 554 case IOCMD_FLASH_DISABLE_OPTROM:
488 rc = bfad_iocmd_ablk_optrom(bfad, cmd, iocmd); 555 rc = bfad_iocmd_ablk_optrom(bfad, cmd, iocmd);
489 break; 556 break;
557 case IOCMD_FAA_ENABLE:
558 rc = bfad_iocmd_faa_enable(bfad, iocmd);
559 break;
560 case IOCMD_FAA_DISABLE:
561 rc = bfad_iocmd_faa_disable(bfad, iocmd);
562 break;
563 case IOCMD_FAA_QUERY:
564 rc = bfad_iocmd_faa_query(bfad, iocmd);
565 break;
490 default: 566 default:
491 rc = EINVAL; 567 rc = EINVAL;
492 break; 568 break;
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h
index a4dcb39883e7..49f558fc2375 100644
--- a/drivers/scsi/bfa/bfad_bsg.h
+++ b/drivers/scsi/bfa/bfad_bsg.h
@@ -39,6 +39,9 @@ enum {
39 IOCMD_PORT_CFG_MODE, 39 IOCMD_PORT_CFG_MODE,
40 IOCMD_FLASH_ENABLE_OPTROM, 40 IOCMD_FLASH_ENABLE_OPTROM,
41 IOCMD_FLASH_DISABLE_OPTROM, 41 IOCMD_FLASH_DISABLE_OPTROM,
42 IOCMD_FAA_ENABLE,
43 IOCMD_FAA_DISABLE,
44 IOCMD_FAA_QUERY,
42}; 45};
43 46
44struct bfa_bsg_gen_s { 47struct bfa_bsg_gen_s {
@@ -156,6 +159,13 @@ struct bfa_bsg_port_cfg_mode_s {
156 struct bfa_port_cfg_mode_s cfg; 159 struct bfa_port_cfg_mode_s cfg;
157}; 160};
158 161
162struct bfa_bsg_faa_attr_s {
163 bfa_status_t status;
164 u16 bfad_num;
165 u16 rsvd;
166 struct bfa_faa_attr_s faa_attr;
167};
168
159struct bfa_bsg_fcpt_s { 169struct bfa_bsg_fcpt_s {
160 bfa_status_t status; 170 bfa_status_t status;
161 u16 vf_id; 171 u16 vf_id;
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h
index 02e445612546..d8f1a7105139 100644
--- a/drivers/scsi/bfa/bfi.h
+++ b/drivers/scsi/bfa/bfi.h
@@ -222,6 +222,7 @@ enum bfi_ioc_i2h_msgs {
222 BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2), 222 BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2),
223 BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3), 223 BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3),
224 BFI_IOC_I2H_HBEAT = BFA_I2HM(4), 224 BFI_IOC_I2H_HBEAT = BFA_I2HM(4),
225 BFI_IOC_I2H_ACQ_ADDR_REPLY = BFA_I2HM(5),
225}; 226};
226 227
227/* 228/*
diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h
index 263631dcfa7c..c665a800c41d 100644
--- a/drivers/scsi/bfa/bfi_ms.h
+++ b/drivers/scsi/bfa/bfi_ms.h
@@ -28,11 +28,17 @@ enum bfi_iocfc_h2i_msgs {
28 BFI_IOCFC_H2I_CFG_REQ = 1, 28 BFI_IOCFC_H2I_CFG_REQ = 1,
29 BFI_IOCFC_H2I_SET_INTR_REQ = 2, 29 BFI_IOCFC_H2I_SET_INTR_REQ = 2,
30 BFI_IOCFC_H2I_UPDATEQ_REQ = 3, 30 BFI_IOCFC_H2I_UPDATEQ_REQ = 3,
31 BFI_IOCFC_H2I_FAA_ENABLE_REQ = 4,
32 BFI_IOCFC_H2I_FAA_DISABLE_REQ = 5,
33 BFI_IOCFC_H2I_FAA_QUERY_REQ = 6,
31}; 34};
32 35
33enum bfi_iocfc_i2h_msgs { 36enum bfi_iocfc_i2h_msgs {
34 BFI_IOCFC_I2H_CFG_REPLY = BFA_I2HM(1), 37 BFI_IOCFC_I2H_CFG_REPLY = BFA_I2HM(1),
35 BFI_IOCFC_I2H_UPDATEQ_RSP = BFA_I2HM(3), 38 BFI_IOCFC_I2H_UPDATEQ_RSP = BFA_I2HM(3),
39 BFI_IOCFC_I2H_FAA_ENABLE_RSP = BFA_I2HM(4),
40 BFI_IOCFC_I2H_FAA_DISABLE_RSP = BFA_I2HM(5),
41 BFI_IOCFC_I2H_FAA_QUERY_RSP = BFA_I2HM(6),
36}; 42};
37 43
38struct bfi_iocfc_cfg_s { 44struct bfi_iocfc_cfg_s {
@@ -166,6 +172,37 @@ union bfi_iocfc_i2h_msg_u {
166 u32 mboxmsg[BFI_IOC_MSGSZ]; 172 u32 mboxmsg[BFI_IOC_MSGSZ];
167}; 173};
168 174
175/*
176 * BFI_IOCFC_H2I_FAA_ENABLE_REQ BFI_IOCFC_H2I_FAA_DISABLE_REQ message
177 */
178struct bfi_faa_en_dis_s {
179 struct bfi_mhdr_s mh; /* common msg header */
180};
181
182/*
183 * BFI_IOCFC_H2I_FAA_QUERY_REQ message
184 */
185struct bfi_faa_query_s {
186 struct bfi_mhdr_s mh; /* common msg header */
187 u8 faa_status; /* FAA status */
188 u8 addr_source; /* PWWN source */
189 u8 rsvd[2];
190 wwn_t faa; /* Fabric acquired PWWN */
191};
192
193/*
194 * BFI_IOCFC_I2H_FAA_ENABLE_RSP, BFI_IOCFC_I2H_FAA_DISABLE_RSP message
195 */
196struct bfi_faa_en_dis_rsp_s {
197 struct bfi_mhdr_s mh; /* common msg header */
198 u8 status; /* updateq status */
199 u8 rsvd[3];
200};
201
202/*
203 * BFI_IOCFC_I2H_FAA_QUERY_RSP message
204 */
205#define bfi_faa_query_rsp_t struct bfi_faa_query_s
169 206
170enum bfi_fcport_h2i { 207enum bfi_fcport_h2i {
171 BFI_FCPORT_H2I_ENABLE_REQ = (1), 208 BFI_FCPORT_H2I_ENABLE_REQ = (1),