aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/bfa/bfa_defs.h5
-rw-r--r--drivers/scsi/bfa/bfa_defs_svc.h87
-rw-r--r--drivers/scsi/bfa/bfa_fc.h5
-rw-r--r--drivers/scsi/bfa/bfa_fcbuild.c4
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c64
-rw-r--r--drivers/scsi/bfa/bfa_fcs.h19
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c141
-rw-r--r--drivers/scsi/bfa/bfa_fcs_rport.c282
-rw-r--r--drivers/scsi/bfa/bfa_svc.c93
-rw-r--r--drivers/scsi/bfa/bfa_svc.h8
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c112
-rw-r--r--drivers/scsi/bfa/bfi_ms.h12
12 files changed, 713 insertions, 119 deletions
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h
index b5a1595cc0a5..f1c9314e86a3 100644
--- a/drivers/scsi/bfa/bfa_defs.h
+++ b/drivers/scsi/bfa/bfa_defs.h
@@ -159,6 +159,8 @@ enum bfa_status {
159 BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */ 159 BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */
160 BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */ 160 BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */
161 BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */ 161 BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */
162 BFA_STATUS_ERROR_TRL_ENABLED = 87, /* TRL is enabled */
163 BFA_STATUS_ERROR_QOS_ENABLED = 88, /* QoS is enabled */
162 BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */ 164 BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */
163 BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact support */ 165 BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact support */
164 BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */ 166 BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */
@@ -184,6 +186,9 @@ enum bfa_status {
184 BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */ 186 BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */
185 BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */ 187 BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */
186 BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */ 188 BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */
189 BFA_STATUS_TOPOLOGY_LOOP = 230, /* Topology is set to Loop */
190 BFA_STATUS_LOOP_UNSUPP_MEZZ = 231, /* Loop topology is not supported
191 * on mezz cards */
187 BFA_STATUS_MAX_VAL /* Unknown error code */ 192 BFA_STATUS_MAX_VAL /* Unknown error code */
188}; 193};
189#define bfa_status_t enum bfa_status 194#define bfa_status_t enum bfa_status
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h
index 36756ce0e58f..20749f193381 100644
--- a/drivers/scsi/bfa/bfa_defs_svc.h
+++ b/drivers/scsi/bfa/bfa_defs_svc.h
@@ -324,12 +324,46 @@ struct bfa_fw_fcoe_port_stats_s {
324 struct bfa_fw_fip_stats_s fip_stats; 324 struct bfa_fw_fip_stats_s fip_stats;
325}; 325};
326 326
327/**
328 * @brief LPSM statistics
329 */
330struct bfa_fw_lpsm_stats_s {
331 u32 cls_rx; /* LPSM cls_rx */
332 u32 cls_tx; /* LPSM cls_tx */
333 u32 arbf0_rx; /* LPSM abrf0 rcvd */
334 u32 arbf0_tx; /* LPSM abrf0 xmit */
335 u32 init_rx; /* LPSM loop init start */
336 u32 unexp_hwst; /* LPSM unknown hw state */
337 u32 unexp_frame; /* LPSM unknown_frame */
338 u32 unexp_prim; /* LPSM unexpected primitive */
339 u32 prev_alpa_unavail; /* LPSM prev alpa unavailable */
340 u32 alpa_unavail; /* LPSM alpa not available */
341 u32 lip_rx; /* LPSM lip rcvd */
342 u32 lip_f7f7_rx; /* LPSM lip f7f7 rcvd */
343 u32 lip_f8_rx; /* LPSM lip f8 rcvd */
344 u32 lip_f8f7_rx; /* LPSM lip f8f7 rcvd */
345 u32 lip_other_rx; /* LPSM lip other rcvd */
346 u32 lip_tx; /* LPSM lip xmit */
347 u32 retry_tov; /* LPSM retry TOV */
348 u32 lip_tov; /* LPSM LIP wait TOV */
349 u32 idle_tov; /* LPSM idle wait TOV */
350 u32 arbf0_tov; /* LPSM arbfo wait TOV */
351 u32 stop_loop_tov; /* LPSM stop loop wait TOV */
352 u32 lixa_tov; /* LPSM lisa wait TOV */
353 u32 lixx_tov; /* LPSM lilp/lirp wait TOV */
354 u32 cls_tov; /* LPSM cls wait TOV */
355 u32 sler; /* LPSM SLER recvd */
356 u32 failed; /* LPSM failed */
357 u32 success; /* LPSM online */
358};
359
327/* 360/*
328 * IOC firmware FC uport stats 361 * IOC firmware FC uport stats
329 */ 362 */
330struct bfa_fw_fc_uport_stats_s { 363struct bfa_fw_fc_uport_stats_s {
331 struct bfa_fw_port_snsm_stats_s snsm_stats; 364 struct bfa_fw_port_snsm_stats_s snsm_stats;
332 struct bfa_fw_port_lksm_stats_s lksm_stats; 365 struct bfa_fw_port_lksm_stats_s lksm_stats;
366 struct bfa_fw_lpsm_stats_s lpsm_stats;
333}; 367};
334 368
335/* 369/*
@@ -357,11 +391,6 @@ struct bfa_fw_fcxchg_stats_s {
357 u32 ua_state_inv; 391 u32 ua_state_inv;
358}; 392};
359 393
360struct bfa_fw_lpsm_stats_s {
361 u32 cls_rx;
362 u32 cls_tx;
363};
364
365/* 394/*
366 * Trunk statistics 395 * Trunk statistics
367 */ 396 */
@@ -454,7 +483,6 @@ struct bfa_fw_stats_s {
454 struct bfa_fw_io_stats_s io_stats; 483 struct bfa_fw_io_stats_s io_stats;
455 struct bfa_fw_port_stats_s port_stats; 484 struct bfa_fw_port_stats_s port_stats;
456 struct bfa_fw_fcxchg_stats_s fcxchg_stats; 485 struct bfa_fw_fcxchg_stats_s fcxchg_stats;
457 struct bfa_fw_lpsm_stats_s lpsm_stats;
458 struct bfa_fw_lps_stats_s lps_stats; 486 struct bfa_fw_lps_stats_s lps_stats;
459 struct bfa_fw_trunk_stats_s trunk_stats; 487 struct bfa_fw_trunk_stats_s trunk_stats;
460 struct bfa_fw_advsm_stats_s advsm_stats; 488 struct bfa_fw_advsm_stats_s advsm_stats;
@@ -498,9 +526,10 @@ enum bfa_qos_bw_alloc {
498 * QoS attribute returned in QoS Query 526 * QoS attribute returned in QoS Query
499 */ 527 */
500struct bfa_qos_attr_s { 528struct bfa_qos_attr_s {
501 u8 state; /* QoS current state */ 529 u8 state; /* QoS current state */
502 u8 rsvd[3]; 530 u8 rsvd1[3];
503 u32 total_bb_cr; /* Total BB Credits */ 531 u32 total_bb_cr; /* Total BB Credits */
532 u32 rsvd2[2];
504}; 533};
505 534
506/* 535/*
@@ -714,9 +743,11 @@ enum bfa_port_type {
714 */ 743 */
715enum bfa_port_topology { 744enum bfa_port_topology {
716 BFA_PORT_TOPOLOGY_NONE = 0, /* No valid topology */ 745 BFA_PORT_TOPOLOGY_NONE = 0, /* No valid topology */
717 BFA_PORT_TOPOLOGY_P2P = 1, /* P2P only */ 746 BFA_PORT_TOPOLOGY_P2P_OLD_VER = 1, /* P2P def for older ver */
718 BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */ 747 BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */
719 BFA_PORT_TOPOLOGY_AUTO = 3, /* auto topology selection */ 748 BFA_PORT_TOPOLOGY_AUTO_OLD_VER = 3, /* auto def for older ver */
749 BFA_PORT_TOPOLOGY_AUTO = 4, /* auto topology selection */
750 BFA_PORT_TOPOLOGY_P2P = 5, /* P2P only */
720}; 751};
721 752
722/* 753/*
@@ -851,9 +882,10 @@ struct bfa_port_cfg_s {
851 u8 bb_scn; /* BB_SCN value from FLOGI Exchg */ 882 u8 bb_scn; /* BB_SCN value from FLOGI Exchg */
852 u8 bb_scn_state; /* Config state of BB_SCN */ 883 u8 bb_scn_state; /* Config state of BB_SCN */
853 u8 faa_state; /* FAA enabled/disabled */ 884 u8 faa_state; /* FAA enabled/disabled */
854 u8 rsvd[1]; 885 u8 rsvd1;
855 u16 path_tov; /* device path timeout */ 886 u16 path_tov; /* device path timeout */
856 u16 q_depth; /* SCSI Queue depth */ 887 u16 q_depth; /* SCSI Queue depth */
888 u32 rsvd2;
857}; 889};
858#pragma pack() 890#pragma pack()
859 891
@@ -971,6 +1003,13 @@ struct bfa_trunk_vc_attr_s {
971 u16 vc_credits[8]; 1003 u16 vc_credits[8];
972}; 1004};
973 1005
1006struct bfa_fcport_loop_info_s {
1007 u8 myalpa; /* alpa claimed */
1008 u8 alpabm_val; /* alpa bitmap valid or not (1 or 0) */
1009 u8 resvd[6];
1010 struct fc_alpabm_s alpabm; /* alpa bitmap */
1011};
1012
974/* 1013/*
975 * Link state information 1014 * Link state information
976 */ 1015 */
@@ -981,13 +1020,18 @@ struct bfa_port_link_s {
981 u8 speed; /* Link speed (1/2/4/8 G) */ 1020 u8 speed; /* Link speed (1/2/4/8 G) */
982 u32 linkstate_opt; /* Linkstate optional data (debug) */ 1021 u32 linkstate_opt; /* Linkstate optional data (debug) */
983 u8 trunked; /* Trunked or not (1 or 0) */ 1022 u8 trunked; /* Trunked or not (1 or 0) */
984 u8 resvd[3]; 1023 u8 resvd[7];
985 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ 1024 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
986 union { 1025 union {
987 struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */ 1026 struct bfa_fcport_loop_info_s loop_info;
988 struct bfa_trunk_vc_attr_s trunk_vc_attr; 1027 union {
989 struct bfa_fcport_fcf_s fcf; /* FCF information (for FCoE) */ 1028 struct bfa_qos_vc_attr_s qos_vc_attr;
990 } vc_fcf; 1029 /* VC info from ELP */
1030 struct bfa_trunk_vc_attr_s trunk_vc_attr;
1031 struct bfa_fcport_fcf_s fcf;
1032 /* FCF information (for FCoE) */
1033 } vc_fcf;
1034 } attr;
991}; 1035};
992#pragma pack() 1036#pragma pack()
993 1037
@@ -1112,6 +1156,9 @@ struct bfa_port_fc_stats_s {
1112 u64 tx_frames; /* Tx frames */ 1156 u64 tx_frames; /* Tx frames */
1113 u64 tx_words; /* Tx words */ 1157 u64 tx_words; /* Tx words */
1114 u64 tx_lip; /* Tx LIP */ 1158 u64 tx_lip; /* Tx LIP */
1159 u64 tx_lip_f7f7; /* Tx LIP_F7F7 */
1160 u64 tx_lip_f8f7; /* Tx LIP_F8F7 */
1161 u64 tx_arbf0; /* Tx ARB F0 */
1115 u64 tx_nos; /* Tx NOS */ 1162 u64 tx_nos; /* Tx NOS */
1116 u64 tx_ols; /* Tx OLS */ 1163 u64 tx_ols; /* Tx OLS */
1117 u64 tx_lr; /* Tx LR */ 1164 u64 tx_lr; /* Tx LR */
@@ -1119,6 +1166,9 @@ struct bfa_port_fc_stats_s {
1119 u64 rx_frames; /* Rx frames */ 1166 u64 rx_frames; /* Rx frames */
1120 u64 rx_words; /* Rx words */ 1167 u64 rx_words; /* Rx words */
1121 u64 lip_count; /* Rx LIP */ 1168 u64 lip_count; /* Rx LIP */
1169 u64 rx_lip_f7f7; /* Rx LIP_F7F7 */
1170 u64 rx_lip_f8f7; /* Rx LIP_F8F7 */
1171 u64 rx_arbf0; /* Rx ARB F0 */
1122 u64 nos_count; /* Rx NOS */ 1172 u64 nos_count; /* Rx NOS */
1123 u64 ols_count; /* Rx OLS */ 1173 u64 ols_count; /* Rx OLS */
1124 u64 lr_count; /* Rx LR */ 1174 u64 lr_count; /* Rx LR */
@@ -1140,6 +1190,7 @@ struct bfa_port_fc_stats_s {
1140 u64 bbsc_frames_lost; /* Credit Recovery-Frames Lost */ 1190 u64 bbsc_frames_lost; /* Credit Recovery-Frames Lost */
1141 u64 bbsc_credits_lost; /* Credit Recovery-Credits Lost */ 1191 u64 bbsc_credits_lost; /* Credit Recovery-Credits Lost */
1142 u64 bbsc_link_resets; /* Credit Recovery-Link Resets */ 1192 u64 bbsc_link_resets; /* Credit Recovery-Link Resets */
1193 u64 loop_timeouts; /* Loop timeouts */
1143}; 1194};
1144 1195
1145/* 1196/*
diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h
index e0beb4d7e264..bea821b98030 100644
--- a/drivers/scsi/bfa/bfa_fc.h
+++ b/drivers/scsi/bfa/bfa_fc.h
@@ -24,6 +24,7 @@ typedef u64 wwn_t;
24 24
25#define WWN_NULL (0) 25#define WWN_NULL (0)
26#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */ 26#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */
27#define FC_ALPA_MAX 128
27 28
28#pragma pack(1) 29#pragma pack(1)
29 30
@@ -1015,6 +1016,10 @@ struct fc_symname_s {
1015 u8 symname[FC_SYMNAME_MAX]; 1016 u8 symname[FC_SYMNAME_MAX];
1016}; 1017};
1017 1018
1019struct fc_alpabm_s {
1020 u8 alpa_bm[FC_ALPA_MAX / 8];
1021};
1022
1018/* 1023/*
1019 * protocol default timeout values 1024 * protocol default timeout values
1020 */ 1025 */
diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c
index 273cee90b3b4..dce787f6cca2 100644
--- a/drivers/scsi/bfa/bfa_fcbuild.c
+++ b/drivers/scsi/bfa/bfa_fcbuild.c
@@ -228,6 +228,10 @@ fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
228 228
229 memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 229 memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
230 230
231 /* For FC AL bb_cr is 0 and altbbcred is 1 */
232 if (!bb_cr)
233 plogi->csp.altbbcred = 1;
234
231 plogi->els_cmd.els_code = els_code; 235 plogi->els_cmd.els_code = els_code;
232 if (els_code == FC_ELS_PLOGI) 236 if (els_code == FC_ELS_PLOGI)
233 fc_els_req_build(fchs, d_id, s_id, ox_id); 237 fc_els_req_build(fchs, d_id, s_id, ox_id);
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index fd3e84d32bd2..d428808fb37e 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -303,16 +303,30 @@ static void
303bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric, 303bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
304 enum bfa_fcs_fabric_event event) 304 enum bfa_fcs_fabric_event event)
305{ 305{
306 struct bfa_s *bfa = fabric->fcs->bfa;
307
306 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); 308 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
307 bfa_trc(fabric->fcs, event); 309 bfa_trc(fabric->fcs, event);
308 310
309 switch (event) { 311 switch (event) {
310 case BFA_FCS_FABRIC_SM_START: 312 case BFA_FCS_FABRIC_SM_START:
311 if (bfa_fcport_is_linkup(fabric->fcs->bfa)) { 313 if (!bfa_fcport_is_linkup(fabric->fcs->bfa)) {
314 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
315 break;
316 }
317 if (bfa_fcport_get_topology(bfa) ==
318 BFA_PORT_TOPOLOGY_LOOP) {
319 fabric->fab_type = BFA_FCS_FABRIC_LOOP;
320 fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
321 fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
322 bfa_sm_set_state(fabric,
323 bfa_fcs_fabric_sm_online);
324 bfa_fcs_fabric_set_opertype(fabric);
325 bfa_fcs_lport_online(&fabric->bport);
326 } else {
312 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); 327 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
313 bfa_fcs_fabric_login(fabric); 328 bfa_fcs_fabric_login(fabric);
314 } else 329 }
315 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
316 break; 330 break;
317 331
318 case BFA_FCS_FABRIC_SM_LINK_UP: 332 case BFA_FCS_FABRIC_SM_LINK_UP:
@@ -337,16 +351,28 @@ static void
337bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric, 351bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
338 enum bfa_fcs_fabric_event event) 352 enum bfa_fcs_fabric_event event)
339{ 353{
354 struct bfa_s *bfa = fabric->fcs->bfa;
355
340 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); 356 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
341 bfa_trc(fabric->fcs, event); 357 bfa_trc(fabric->fcs, event);
342 358
343 switch (event) { 359 switch (event) {
344 case BFA_FCS_FABRIC_SM_LINK_UP: 360 case BFA_FCS_FABRIC_SM_LINK_UP:
345 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); 361 if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) {
346 bfa_fcs_fabric_login(fabric); 362 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
363 bfa_fcs_fabric_login(fabric);
364 break;
365 }
366 fabric->fab_type = BFA_FCS_FABRIC_LOOP;
367 fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
368 fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
369 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
370 bfa_fcs_fabric_set_opertype(fabric);
371 bfa_fcs_lport_online(&fabric->bport);
347 break; 372 break;
348 373
349 case BFA_FCS_FABRIC_SM_RETRY_OP: 374 case BFA_FCS_FABRIC_SM_RETRY_OP:
375 case BFA_FCS_FABRIC_SM_LOOPBACK:
350 break; 376 break;
351 377
352 case BFA_FCS_FABRIC_SM_DELETE: 378 case BFA_FCS_FABRIC_SM_DELETE:
@@ -595,14 +621,20 @@ void
595bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric, 621bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
596 enum bfa_fcs_fabric_event event) 622 enum bfa_fcs_fabric_event event)
597{ 623{
624 struct bfa_s *bfa = fabric->fcs->bfa;
625
598 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); 626 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
599 bfa_trc(fabric->fcs, event); 627 bfa_trc(fabric->fcs, event);
600 628
601 switch (event) { 629 switch (event) {
602 case BFA_FCS_FABRIC_SM_LINK_DOWN: 630 case BFA_FCS_FABRIC_SM_LINK_DOWN:
603 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); 631 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
604 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE); 632 if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
605 bfa_fcs_fabric_notify_offline(fabric); 633 bfa_fcs_lport_offline(&fabric->bport);
634 } else {
635 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
636 bfa_fcs_fabric_notify_offline(fabric);
637 }
606 break; 638 break;
607 639
608 case BFA_FCS_FABRIC_SM_DELETE: 640 case BFA_FCS_FABRIC_SM_DELETE:
@@ -719,20 +751,29 @@ static void
719bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric, 751bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric,
720 enum bfa_fcs_fabric_event event) 752 enum bfa_fcs_fabric_event event)
721{ 753{
754 struct bfa_s *bfa = fabric->fcs->bfa;
755
722 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); 756 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
723 bfa_trc(fabric->fcs, event); 757 bfa_trc(fabric->fcs, event);
724 758
725 switch (event) { 759 switch (event) {
726 case BFA_FCS_FABRIC_SM_STOPCOMP: 760 case BFA_FCS_FABRIC_SM_STOPCOMP:
727 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup); 761 if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
728 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT); 762 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
763 } else {
764 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
765 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT);
766 }
729 break; 767 break;
730 768
731 case BFA_FCS_FABRIC_SM_LINK_UP: 769 case BFA_FCS_FABRIC_SM_LINK_UP:
732 break; 770 break;
733 771
734 case BFA_FCS_FABRIC_SM_LINK_DOWN: 772 case BFA_FCS_FABRIC_SM_LINK_DOWN:
735 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup); 773 if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
774 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
775 else
776 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
736 break; 777 break;
737 778
738 default: 779 default:
@@ -975,9 +1016,6 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
975 struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg; 1016 struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
976 u8 alpa = 0, bb_scn = 0; 1017 u8 alpa = 0, bb_scn = 0;
977 1018
978 if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
979 alpa = bfa_fcport_get_myalpa(bfa);
980
981 if (bfa_fcs_fabric_is_bbscn_enabled(fabric) && 1019 if (bfa_fcs_fabric_is_bbscn_enabled(fabric) &&
982 (!fabric->fcs->bbscn_flogi_rjt)) 1020 (!fabric->fcs->bbscn_flogi_rjt))
983 bb_scn = BFA_FCS_PORT_DEF_BB_SCN; 1021 bb_scn = BFA_FCS_PORT_DEF_BB_SCN;
diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h
index 6c4377cb287f..f2a6a3c0e002 100644
--- a/drivers/scsi/bfa/bfa_fcs.h
+++ b/drivers/scsi/bfa/bfa_fcs.h
@@ -118,9 +118,9 @@ struct bfa_fcs_lport_fab_s {
118#define MAX_ALPA_COUNT 127 118#define MAX_ALPA_COUNT 127
119 119
120struct bfa_fcs_lport_loop_s { 120struct bfa_fcs_lport_loop_s {
121 u8 num_alpa; /* Num of ALPA entries in the map */ 121 u8 num_alpa; /* Num of ALPA entries in the map */
122 u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional 122 u8 alpabm_valid; /* alpa bitmap valid or not (1 or 0) */
123 *Map */ 123 u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional Map */
124 struct bfa_fcs_lport_s *port; /* parent port */ 124 struct bfa_fcs_lport_s *port; /* parent port */
125}; 125};
126 126
@@ -175,6 +175,7 @@ enum bfa_fcs_fabric_type {
175 BFA_FCS_FABRIC_UNKNOWN = 0, 175 BFA_FCS_FABRIC_UNKNOWN = 0,
176 BFA_FCS_FABRIC_SWITCHED = 1, 176 BFA_FCS_FABRIC_SWITCHED = 1,
177 BFA_FCS_FABRIC_N2N = 2, 177 BFA_FCS_FABRIC_N2N = 2,
178 BFA_FCS_FABRIC_LOOP = 3,
178}; 179};
179 180
180 181
@@ -350,9 +351,10 @@ void bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg,
350 struct bfa_fcxp_s *fcxp_alloced); 351 struct bfa_fcxp_s *fcxp_alloced);
351void bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *vport); 352void bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *vport);
352void bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *vport); 353void bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *vport);
353void bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *vport); 354void bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *vport);
354void bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port, 355void bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
355 struct fchs_s *rx_frame, u32 len); 356 struct fchs_s *rx_frame, u32 len);
357void bfa_fcs_lport_lip_scn_online(bfa_fcs_lport_t *port);
356 358
357struct bfa_fcs_vport_s { 359struct bfa_fcs_vport_s {
358 struct list_head qe; /* queue elem */ 360 struct list_head qe; /* queue elem */
@@ -453,6 +455,7 @@ struct bfa_fcs_rport_s {
453 struct bfa_rport_stats_s stats; /* rport stats */ 455 struct bfa_rport_stats_s stats; /* rport stats */
454 enum bfa_rport_function scsi_function; /* Initiator/Target */ 456 enum bfa_rport_function scsi_function; /* Initiator/Target */
455 struct bfa_fcs_rpf_s rpf; /* Rport features module */ 457 struct bfa_fcs_rpf_s rpf; /* Rport features module */
458 bfa_boolean_t scn_online; /* SCN online flag */
456}; 459};
457 460
458static inline struct bfa_rport_s * 461static inline struct bfa_rport_s *
@@ -733,7 +736,7 @@ enum rport_event {
733 RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */ 736 RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */
734 RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */ 737 RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */
735 RPSM_EVENT_DELETE = 7, /* RPORT delete request */ 738 RPSM_EVENT_DELETE = 7, /* RPORT delete request */
736 RPSM_EVENT_SCN = 8, /* state change notification */ 739 RPSM_EVENT_FAB_SCN = 8, /* state change notification */
737 RPSM_EVENT_ACCEPTED = 9, /* Good response from remote device */ 740 RPSM_EVENT_ACCEPTED = 9, /* Good response from remote device */
738 RPSM_EVENT_FAILED = 10, /* Request to rport failed. */ 741 RPSM_EVENT_FAILED = 10, /* Request to rport failed. */
739 RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */ 742 RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */
@@ -744,7 +747,9 @@ enum rport_event {
744 RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */ 747 RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */
745 RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */ 748 RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */
746 RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continuously */ 749 RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continuously */
747 RPSM_EVENT_FC4_FCS_ONLINE = 19, /*!< FC-4 FCS online complete */ 750 RPSM_EVENT_SCN_OFFLINE = 19, /* loop scn offline */
751 RPSM_EVENT_SCN_ONLINE = 20, /* loop scn online */
752 RPSM_EVENT_FC4_FCS_ONLINE = 21, /* FC-4 FCS online complete */
748}; 753};
749 754
750/* 755/*
@@ -763,7 +768,7 @@ enum bfa_fcs_itnim_event {
763 BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */ 768 BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */
764 BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */ 769 BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */
765 BFA_FCS_ITNIM_SM_RSP_NOT_SUPP = 12, /* cmd not supported rsp */ 770 BFA_FCS_ITNIM_SM_RSP_NOT_SUPP = 12, /* cmd not supported rsp */
766 BFA_FCS_ITNIM_SM_HAL_ONLINE = 13, /*!< bfa rport online event */ 771 BFA_FCS_ITNIM_SM_HAL_ONLINE = 13, /* bfa rport online event */
767}; 772};
768 773
769/* 774/*
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index 3b75f6fb2de1..c58a5e03d56f 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -23,6 +23,34 @@
23 23
24BFA_TRC_FILE(FCS, PORT); 24BFA_TRC_FILE(FCS, PORT);
25 25
26/*
27 * ALPA to LIXA bitmap mapping
28 *
29 * ALPA 0x00 (Word 0, Bit 30) is invalid for N_Ports. Also Word 0 Bit 31
30 * is for L_bit (login required) and is filled as ALPA 0x00 here.
31 */
32static const u8 loop_alpa_map[] = {
33 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, /* Word 0 Bits 31..24 */
34 0x17, 0x18, 0x1B, 0x1D, 0x1E, 0x1F, 0x23, 0x25, /* Word 0 Bits 23..16 */
35 0x26, 0x27, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, /* Word 0 Bits 15..08 */
36 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A, /* Word 0 Bits 07..00 */
37
38 0x3C, 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, /* Word 1 Bits 31..24 */
39 0x4C, 0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55, /* Word 1 Bits 23..16 */
40 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67, /* Word 1 Bits 15..08 */
41 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, /* Word 1 Bits 07..00 */
42
43 0x73, 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, /* Word 2 Bits 31..24 */
44 0x81, 0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, /* Word 2 Bits 23..16 */
45 0x9B, 0x9D, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, /* Word 2 Bits 15..08 */
46 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2, /* Word 2 Bits 07..00 */
47
48 0xB3, 0xB4, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0xC3, /* Word 3 Bits 31..24 */
49 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, /* Word 3 Bits 23..16 */
50 0xCE, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9, /* Word 3 Bits 15..08 */
51 0xDA, 0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF, /* Word 3 Bits 07..00 */
52};
53
26static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, 54static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port,
27 struct fchs_s *rx_fchs, u8 reason_code, 55 struct fchs_s *rx_fchs, u8 reason_code,
28 u8 reason_code_expl); 56 u8 reason_code_expl);
@@ -51,6 +79,10 @@ static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port);
51static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port); 79static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port);
52static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port); 80static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port);
53 81
82static void bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port);
83static void bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port);
84static void bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port);
85
54static struct { 86static struct {
55 void (*init) (struct bfa_fcs_lport_s *port); 87 void (*init) (struct bfa_fcs_lport_s *port);
56 void (*online) (struct bfa_fcs_lport_s *port); 88 void (*online) (struct bfa_fcs_lport_s *port);
@@ -62,7 +94,9 @@ static struct {
62 bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online, 94 bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online,
63 bfa_fcs_lport_fab_offline}, { 95 bfa_fcs_lport_fab_offline}, {
64 bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online, 96 bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online,
65 bfa_fcs_lport_n2n_offline}, 97 bfa_fcs_lport_n2n_offline}, {
98 bfa_fcs_lport_loop_init, bfa_fcs_lport_loop_online,
99 bfa_fcs_lport_loop_offline},
66 }; 100 };
67 101
68/* 102/*
@@ -1127,7 +1161,7 @@ static void
1127bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port) 1161bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port)
1128{ 1162{
1129 bfa_fcs_lport_ns_online(port); 1163 bfa_fcs_lport_ns_online(port);
1130 bfa_fcs_lport_scn_online(port); 1164 bfa_fcs_lport_fab_scn_online(port);
1131} 1165}
1132 1166
1133/* 1167/*
@@ -1221,6 +1255,98 @@ bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port)
1221 n2n_port->reply_oxid = 0; 1255 n2n_port->reply_oxid = 0;
1222} 1256}
1223 1257
1258void
1259bfa_fcport_get_loop_attr(struct bfa_fcs_lport_s *port)
1260{
1261 int i = 0, j = 0, bit = 0, alpa_bit = 0;
1262 u8 k = 0;
1263 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(port->fcs->bfa);
1264
1265 port->port_topo.ploop.alpabm_valid = fcport->alpabm_valid;
1266 port->pid = fcport->myalpa;
1267 port->pid = bfa_hton3b(port->pid);
1268
1269 for (i = 0; i < (FC_ALPA_MAX / 8); i++) {
1270 for (j = 0, alpa_bit = 0; j < 8; j++, alpa_bit++) {
1271 bfa_trc(port->fcs->bfa, fcport->alpabm.alpa_bm[i]);
1272 bit = (fcport->alpabm.alpa_bm[i] & (1 << (7 - j)));
1273 if (bit) {
1274 port->port_topo.ploop.alpa_pos_map[k] =
1275 loop_alpa_map[(i * 8) + alpa_bit];
1276 k++;
1277 bfa_trc(port->fcs->bfa, k);
1278 bfa_trc(port->fcs->bfa,
1279 port->port_topo.ploop.alpa_pos_map[k]);
1280 }
1281 }
1282 }
1283 port->port_topo.ploop.num_alpa = k;
1284}
1285
1286/*
1287 * Called by fcs/port to initialize Loop topology.
1288 */
1289static void
1290bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port)
1291{
1292}
1293
1294/*
1295 * Called by fcs/port to notify transition to online state.
1296 */
1297static void
1298bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port)
1299{
1300 u8 num_alpa = 0, alpabm_valid = 0;
1301 struct bfa_fcs_rport_s *rport;
1302 u8 *alpa_map = NULL;
1303 int i = 0;
1304 u32 pid;
1305
1306 bfa_fcport_get_loop_attr(port);
1307
1308 num_alpa = port->port_topo.ploop.num_alpa;
1309 alpabm_valid = port->port_topo.ploop.alpabm_valid;
1310 alpa_map = port->port_topo.ploop.alpa_pos_map;
1311
1312 bfa_trc(port->fcs->bfa, port->pid);
1313 bfa_trc(port->fcs->bfa, num_alpa);
1314 if (alpabm_valid == 1) {
1315 for (i = 0; i < num_alpa; i++) {
1316 bfa_trc(port->fcs->bfa, alpa_map[i]);
1317 if (alpa_map[i] != bfa_hton3b(port->pid)) {
1318 pid = alpa_map[i];
1319 bfa_trc(port->fcs->bfa, pid);
1320 rport = bfa_fcs_lport_get_rport_by_pid(port,
1321 bfa_hton3b(pid));
1322 if (!rport)
1323 rport = bfa_fcs_rport_create(port,
1324 bfa_hton3b(pid));
1325 }
1326 }
1327 } else {
1328 for (i = 0; i < MAX_ALPA_COUNT; i++) {
1329 if (alpa_map[i] != port->pid) {
1330 pid = loop_alpa_map[i];
1331 bfa_trc(port->fcs->bfa, pid);
1332 rport = bfa_fcs_lport_get_rport_by_pid(port,
1333 bfa_hton3b(pid));
1334 if (!rport)
1335 rport = bfa_fcs_rport_create(port,
1336 bfa_hton3b(pid));
1337 }
1338 }
1339 }
1340}
1341
1342/*
1343 * Called by fcs/port to notify transition to offline state.
1344 */
1345static void
1346bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port)
1347{
1348}
1349
1224#define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 1350#define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
1225 1351
1226/* 1352/*
@@ -5199,7 +5325,7 @@ bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port)
5199} 5325}
5200 5326
5201void 5327void
5202bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port) 5328bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *port)
5203{ 5329{
5204 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 5330 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
5205 5331
@@ -5621,6 +5747,15 @@ bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port)
5621} 5747}
5622 5748
5623/* 5749/*
5750 * Let new loop map create missing rports
5751 */
5752void
5753bfa_fcs_lport_lip_scn_online(struct bfa_fcs_lport_s *port)
5754{
5755 bfa_fcs_lport_loop_online(port);
5756}
5757
5758/*
5624 * FCS virtual port state machine 5759 * FCS virtual port state machine
5625 */ 5760 */
5626 5761
diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c
index cc43b2a58ce3..e90800d0557a 100644
--- a/drivers/scsi/bfa/bfa_fcs_rport.c
+++ b/drivers/scsi/bfa/bfa_fcs_rport.c
@@ -106,9 +106,13 @@ static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
106 enum rport_event event); 106 enum rport_event event);
107static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, 107static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
108 enum rport_event event); 108 enum rport_event event);
109static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, 109static void bfa_fcs_rport_sm_adisc_online_sending(
110 enum rport_event event); 110 struct bfa_fcs_rport_s *rport, enum rport_event event);
111static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, 111static void bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
112 enum rport_event event);
113static void bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s
114 *rport, enum rport_event event);
115static void bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
112 enum rport_event event); 116 enum rport_event event);
113static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, 117static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
114 enum rport_event event); 118 enum rport_event event);
@@ -150,8 +154,10 @@ static struct bfa_sm_table_s rport_sm_table[] = {
150 {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE}, 154 {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
151 {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY}, 155 {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
152 {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY}, 156 {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
153 {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC}, 157 {BFA_SM(bfa_fcs_rport_sm_adisc_online_sending), BFA_RPORT_ADISC},
154 {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC}, 158 {BFA_SM(bfa_fcs_rport_sm_adisc_online), BFA_RPORT_ADISC},
159 {BFA_SM(bfa_fcs_rport_sm_adisc_offline_sending), BFA_RPORT_ADISC},
160 {BFA_SM(bfa_fcs_rport_sm_adisc_offline), BFA_RPORT_ADISC},
155 {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV}, 161 {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
156 {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO}, 162 {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
157 {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE}, 163 {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
@@ -231,10 +237,19 @@ bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
231 bfa_fcs_rport_send_plogiacc(rport, NULL); 237 bfa_fcs_rport_send_plogiacc(rport, NULL);
232 break; 238 break;
233 239
240 case RPSM_EVENT_SCN_OFFLINE:
241 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
242 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
243 bfa_timer_start(rport->fcs->bfa, &rport->timer,
244 bfa_fcs_rport_timeout, rport,
245 bfa_fcs_rport_del_timeout);
246 break;
234 case RPSM_EVENT_ADDRESS_CHANGE: 247 case RPSM_EVENT_ADDRESS_CHANGE:
235 case RPSM_EVENT_SCN: 248 case RPSM_EVENT_FAB_SCN:
236 /* query the NS */ 249 /* query the NS */
237 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 250 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
251 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
252 BFA_PORT_TOPOLOGY_LOOP));
238 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 253 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
239 rport->ns_retries = 0; 254 rport->ns_retries = 0;
240 bfa_fcs_rport_send_nsdisc(rport, NULL); 255 bfa_fcs_rport_send_nsdisc(rport, NULL);
@@ -280,12 +295,20 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
280 295
281 case RPSM_EVENT_PLOGI_RCVD: 296 case RPSM_EVENT_PLOGI_RCVD:
282 case RPSM_EVENT_PLOGI_COMP: 297 case RPSM_EVENT_PLOGI_COMP:
283 case RPSM_EVENT_SCN: 298 case RPSM_EVENT_FAB_SCN:
284 /* 299 /*
285 * Ignore, SCN is possibly online notification. 300 * Ignore, SCN is possibly online notification.
286 */ 301 */
287 break; 302 break;
288 303
304 case RPSM_EVENT_SCN_OFFLINE:
305 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
306 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
307 bfa_timer_start(rport->fcs->bfa, &rport->timer,
308 bfa_fcs_rport_timeout, rport,
309 bfa_fcs_rport_del_timeout);
310 break;
311
289 case RPSM_EVENT_ADDRESS_CHANGE: 312 case RPSM_EVENT_ADDRESS_CHANGE:
290 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 313 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
291 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 314 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
@@ -346,9 +369,19 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
346 bfa_fcs_rport_send_plogiacc(rport, NULL); 369 bfa_fcs_rport_send_plogiacc(rport, NULL);
347 break; 370 break;
348 371
372 case RPSM_EVENT_SCN_OFFLINE:
373 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
374 bfa_timer_stop(&rport->timer);
375 bfa_timer_start(rport->fcs->bfa, &rport->timer,
376 bfa_fcs_rport_timeout, rport,
377 bfa_fcs_rport_del_timeout);
378 break;
379
349 case RPSM_EVENT_ADDRESS_CHANGE: 380 case RPSM_EVENT_ADDRESS_CHANGE:
350 case RPSM_EVENT_SCN: 381 case RPSM_EVENT_FAB_SCN:
351 bfa_timer_stop(&rport->timer); 382 bfa_timer_stop(&rport->timer);
383 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
384 BFA_PORT_TOPOLOGY_LOOP));
352 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 385 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
353 rport->ns_retries = 0; 386 rport->ns_retries = 0;
354 bfa_fcs_rport_send_nsdisc(rport, NULL); 387 bfa_fcs_rport_send_nsdisc(rport, NULL);
@@ -422,7 +455,18 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
422 } 455 }
423 break; 456 break;
424 457
425 case RPSM_EVENT_PLOGI_RETRY: 458 case RPSM_EVENT_SCN_ONLINE:
459 break;
460
461 case RPSM_EVENT_SCN_OFFLINE:
462 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
463 bfa_fcxp_discard(rport->fcxp);
464 bfa_timer_start(rport->fcs->bfa, &rport->timer,
465 bfa_fcs_rport_timeout, rport,
466 bfa_fcs_rport_del_timeout);
467 break;
468
469 case RPSM_EVENT_PLOGI_RETRY:
426 rport->plogi_retries = 0; 470 rport->plogi_retries = 0;
427 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry); 471 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
428 bfa_timer_start(rport->fcs->bfa, &rport->timer, 472 bfa_timer_start(rport->fcs->bfa, &rport->timer,
@@ -440,8 +484,10 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
440 break; 484 break;
441 485
442 case RPSM_EVENT_ADDRESS_CHANGE: 486 case RPSM_EVENT_ADDRESS_CHANGE:
443 case RPSM_EVENT_SCN: 487 case RPSM_EVENT_FAB_SCN:
444 bfa_fcxp_discard(rport->fcxp); 488 bfa_fcxp_discard(rport->fcxp);
489 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
490 BFA_PORT_TOPOLOGY_LOOP));
445 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 491 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
446 rport->ns_retries = 0; 492 rport->ns_retries = 0;
447 bfa_fcs_rport_send_nsdisc(rport, NULL); 493 bfa_fcs_rport_send_nsdisc(rport, NULL);
@@ -512,7 +558,8 @@ bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
512 case RPSM_EVENT_PLOGI_COMP: 558 case RPSM_EVENT_PLOGI_COMP:
513 case RPSM_EVENT_LOGO_IMP: 559 case RPSM_EVENT_LOGO_IMP:
514 case RPSM_EVENT_ADDRESS_CHANGE: 560 case RPSM_EVENT_ADDRESS_CHANGE:
515 case RPSM_EVENT_SCN: 561 case RPSM_EVENT_FAB_SCN:
562 case RPSM_EVENT_SCN_OFFLINE:
516 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 563 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
517 bfa_fcs_rport_fcs_offline_action(rport); 564 bfa_fcs_rport_fcs_offline_action(rport);
518 break; 565 break;
@@ -561,9 +608,10 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
561 bfa_fcs_rport_fcs_offline_action(rport); 608 bfa_fcs_rport_fcs_offline_action(rport);
562 break; 609 break;
563 610
564 case RPSM_EVENT_SCN: 611 case RPSM_EVENT_FAB_SCN:
565 case RPSM_EVENT_LOGO_IMP: 612 case RPSM_EVENT_LOGO_IMP:
566 case RPSM_EVENT_ADDRESS_CHANGE: 613 case RPSM_EVENT_ADDRESS_CHANGE:
614 case RPSM_EVENT_SCN_OFFLINE:
567 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 615 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
568 bfa_fcs_rport_fcs_offline_action(rport); 616 bfa_fcs_rport_fcs_offline_action(rport);
569 break; 617 break;
@@ -595,14 +643,15 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
595 bfa_trc(rport->fcs, event); 643 bfa_trc(rport->fcs, event);
596 644
597 switch (event) { 645 switch (event) {
598 case RPSM_EVENT_SCN: 646 case RPSM_EVENT_FAB_SCN:
599 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { 647 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
600 bfa_sm_set_state(rport, 648 bfa_sm_set_state(rport,
601 bfa_fcs_rport_sm_nsquery_sending); 649 bfa_fcs_rport_sm_nsquery_sending);
602 rport->ns_retries = 0; 650 rport->ns_retries = 0;
603 bfa_fcs_rport_send_nsdisc(rport, NULL); 651 bfa_fcs_rport_send_nsdisc(rport, NULL);
604 } else { 652 } else {
605 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); 653 bfa_sm_set_state(rport,
654 bfa_fcs_rport_sm_adisc_online_sending);
606 bfa_fcs_rport_send_adisc(rport, NULL); 655 bfa_fcs_rport_send_adisc(rport, NULL);
607 } 656 }
608 break; 657 break;
@@ -610,6 +659,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
610 case RPSM_EVENT_PLOGI_RCVD: 659 case RPSM_EVENT_PLOGI_RCVD:
611 case RPSM_EVENT_LOGO_IMP: 660 case RPSM_EVENT_LOGO_IMP:
612 case RPSM_EVENT_ADDRESS_CHANGE: 661 case RPSM_EVENT_ADDRESS_CHANGE:
662 case RPSM_EVENT_SCN_OFFLINE:
613 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 663 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
614 bfa_fcs_rport_hal_offline_action(rport); 664 bfa_fcs_rport_hal_offline_action(rport);
615 break; 665 break;
@@ -625,6 +675,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
625 bfa_fcs_rport_hal_offline_action(rport); 675 bfa_fcs_rport_hal_offline_action(rport);
626 break; 676 break;
627 677
678 case RPSM_EVENT_SCN_ONLINE:
628 case RPSM_EVENT_PLOGI_COMP: 679 case RPSM_EVENT_PLOGI_COMP:
629 break; 680 break;
630 681
@@ -656,7 +707,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
656 bfa_fcs_rport_hal_offline_action(rport); 707 bfa_fcs_rport_hal_offline_action(rport);
657 break; 708 break;
658 709
659 case RPSM_EVENT_SCN: 710 case RPSM_EVENT_FAB_SCN:
660 /* 711 /*
661 * ignore SCN, wait for response to query itself 712 * ignore SCN, wait for response to query itself
662 */ 713 */
@@ -696,7 +747,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
696 747
697 switch (event) { 748 switch (event) {
698 case RPSM_EVENT_ACCEPTED: 749 case RPSM_EVENT_ACCEPTED:
699 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); 750 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online_sending);
700 bfa_fcs_rport_send_adisc(rport, NULL); 751 bfa_fcs_rport_send_adisc(rport, NULL);
701 break; 752 break;
702 753
@@ -718,7 +769,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
718 bfa_fcs_rport_hal_offline_action(rport); 769 bfa_fcs_rport_hal_offline_action(rport);
719 break; 770 break;
720 771
721 case RPSM_EVENT_SCN: 772 case RPSM_EVENT_FAB_SCN:
722 break; 773 break;
723 774
724 case RPSM_EVENT_LOGO_RCVD: 775 case RPSM_EVENT_LOGO_RCVD:
@@ -747,7 +798,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
747 * authenticating with rport. FC-4s are paused. 798 * authenticating with rport. FC-4s are paused.
748 */ 799 */
749static void 800static void
750bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, 801bfa_fcs_rport_sm_adisc_online_sending(struct bfa_fcs_rport_s *rport,
751 enum rport_event event) 802 enum rport_event event)
752{ 803{
753 bfa_trc(rport->fcs, rport->pwwn); 804 bfa_trc(rport->fcs, rport->pwwn);
@@ -756,7 +807,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
756 807
757 switch (event) { 808 switch (event) {
758 case RPSM_EVENT_FCXP_SENT: 809 case RPSM_EVENT_FCXP_SENT:
759 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc); 810 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online);
760 break; 811 break;
761 812
762 case RPSM_EVENT_DELETE: 813 case RPSM_EVENT_DELETE:
@@ -779,7 +830,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
779 bfa_fcs_rport_hal_offline_action(rport); 830 bfa_fcs_rport_hal_offline_action(rport);
780 break; 831 break;
781 832
782 case RPSM_EVENT_SCN: 833 case RPSM_EVENT_FAB_SCN:
783 break; 834 break;
784 835
785 case RPSM_EVENT_PLOGI_RCVD: 836 case RPSM_EVENT_PLOGI_RCVD:
@@ -798,7 +849,8 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
798 * FC-4s are paused. 849 * FC-4s are paused.
799 */ 850 */
800static void 851static void
801bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event) 852bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
853 enum rport_event event)
802{ 854{
803 bfa_trc(rport->fcs, rport->pwwn); 855 bfa_trc(rport->fcs, rport->pwwn);
804 bfa_trc(rport->fcs, rport->pid); 856 bfa_trc(rport->fcs, rport->pid);
@@ -831,7 +883,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
831 bfa_fcs_rport_hal_offline_action(rport); 883 bfa_fcs_rport_hal_offline_action(rport);
832 break; 884 break;
833 885
834 case RPSM_EVENT_SCN: 886 case RPSM_EVENT_FAB_SCN:
835 /* 887 /*
836 * already processing RSCN 888 * already processing RSCN
837 */ 889 */
@@ -856,7 +908,96 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
856} 908}
857 909
858/* 910/*
859 * Rport has sent LOGO. Awaiting FC-4 offline completion callback. 911 * ADISC is being sent for authenticating with rport
912 * Already did offline actions.
913 */
914static void
915bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s *rport,
916 enum rport_event event)
917{
918 bfa_trc(rport->fcs, rport->pwwn);
919 bfa_trc(rport->fcs, rport->pid);
920 bfa_trc(rport->fcs, event);
921
922 switch (event) {
923 case RPSM_EVENT_FCXP_SENT:
924 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_offline);
925 break;
926
927 case RPSM_EVENT_DELETE:
928 case RPSM_EVENT_SCN_OFFLINE:
929 case RPSM_EVENT_LOGO_IMP:
930 case RPSM_EVENT_LOGO_RCVD:
931 case RPSM_EVENT_PRLO_RCVD:
932 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
933 bfa_fcxp_walloc_cancel(rport->fcs->bfa,
934 &rport->fcxp_wqe);
935 bfa_timer_start(rport->fcs->bfa, &rport->timer,
936 bfa_fcs_rport_timeout, rport,
937 bfa_fcs_rport_del_timeout);
938 break;
939
940 case RPSM_EVENT_PLOGI_RCVD:
941 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
942 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
943 bfa_fcs_rport_send_plogiacc(rport, NULL);
944 break;
945
946 default:
947 bfa_sm_fault(rport->fcs, event);
948 }
949}
950
951/*
952 * ADISC to rport
953 * Already did offline actions
954 */
955static void
956bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
957 enum rport_event event)
958{
959 bfa_trc(rport->fcs, rport->pwwn);
960 bfa_trc(rport->fcs, rport->pid);
961 bfa_trc(rport->fcs, event);
962
963 switch (event) {
964 case RPSM_EVENT_ACCEPTED:
965 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
966 bfa_fcs_rport_hal_online(rport);
967 break;
968
969 case RPSM_EVENT_PLOGI_RCVD:
970 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
971 bfa_fcxp_discard(rport->fcxp);
972 bfa_fcs_rport_send_plogiacc(rport, NULL);
973 break;
974
975 case RPSM_EVENT_FAILED:
976 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
977 bfa_timer_start(rport->fcs->bfa, &rport->timer,
978 bfa_fcs_rport_timeout, rport,
979 bfa_fcs_rport_del_timeout);
980 break;
981
982 case RPSM_EVENT_DELETE:
983 case RPSM_EVENT_SCN_OFFLINE:
984 case RPSM_EVENT_LOGO_IMP:
985 case RPSM_EVENT_LOGO_RCVD:
986 case RPSM_EVENT_PRLO_RCVD:
987 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
988 bfa_fcxp_discard(rport->fcxp);
989 bfa_timer_start(rport->fcs->bfa, &rport->timer,
990 bfa_fcs_rport_timeout, rport,
991 bfa_fcs_rport_del_timeout);
992 break;
993
994 default:
995 bfa_sm_fault(rport->fcs, event);
996 }
997}
998
999/*
1000 * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
860 */ 1001 */
861static void 1002static void
862bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, 1003bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
@@ -881,6 +1022,8 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
881 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete); 1022 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
882 break; 1023 break;
883 1024
1025 case RPSM_EVENT_SCN_ONLINE:
1026 case RPSM_EVENT_SCN_OFFLINE:
884 case RPSM_EVENT_HCB_ONLINE: 1027 case RPSM_EVENT_HCB_ONLINE:
885 case RPSM_EVENT_LOGO_RCVD: 1028 case RPSM_EVENT_LOGO_RCVD:
886 case RPSM_EVENT_PRLO_RCVD: 1029 case RPSM_EVENT_PRLO_RCVD:
@@ -945,6 +1088,8 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
945 bfa_fcs_rport_hal_offline(rport); 1088 bfa_fcs_rport_hal_offline(rport);
946 break; 1089 break;
947 1090
1091 case RPSM_EVENT_SCN_ONLINE:
1092 break;
948 case RPSM_EVENT_LOGO_RCVD: 1093 case RPSM_EVENT_LOGO_RCVD:
949 /* 1094 /*
950 * Rport is going offline. Just ack the logo 1095 * Rport is going offline. Just ack the logo
@@ -956,8 +1101,9 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
956 bfa_fcs_rport_send_prlo_acc(rport); 1101 bfa_fcs_rport_send_prlo_acc(rport);
957 break; 1102 break;
958 1103
1104 case RPSM_EVENT_SCN_OFFLINE:
959 case RPSM_EVENT_HCB_ONLINE: 1105 case RPSM_EVENT_HCB_ONLINE:
960 case RPSM_EVENT_SCN: 1106 case RPSM_EVENT_FAB_SCN:
961 case RPSM_EVENT_LOGO_IMP: 1107 case RPSM_EVENT_LOGO_IMP:
962 case RPSM_EVENT_ADDRESS_CHANGE: 1108 case RPSM_EVENT_ADDRESS_CHANGE:
963 /* 1109 /*
@@ -1015,6 +1161,19 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
1015 bfa_fcs_rport_sm_nsdisc_sending); 1161 bfa_fcs_rport_sm_nsdisc_sending);
1016 rport->ns_retries = 0; 1162 rport->ns_retries = 0;
1017 bfa_fcs_rport_send_nsdisc(rport, NULL); 1163 bfa_fcs_rport_send_nsdisc(rport, NULL);
1164 } else if (bfa_fcport_get_topology(rport->port->fcs->bfa) ==
1165 BFA_PORT_TOPOLOGY_LOOP) {
1166 if (rport->scn_online) {
1167 bfa_sm_set_state(rport,
1168 bfa_fcs_rport_sm_adisc_offline_sending);
1169 bfa_fcs_rport_send_adisc(rport, NULL);
1170 } else {
1171 bfa_sm_set_state(rport,
1172 bfa_fcs_rport_sm_offline);
1173 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1174 bfa_fcs_rport_timeout, rport,
1175 bfa_fcs_rport_del_timeout);
1176 }
1018 } else { 1177 } else {
1019 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 1178 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1020 rport->plogi_retries = 0; 1179 rport->plogi_retries = 0;
@@ -1027,7 +1186,9 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
1027 bfa_fcs_rport_free(rport); 1186 bfa_fcs_rport_free(rport);
1028 break; 1187 break;
1029 1188
1030 case RPSM_EVENT_SCN: 1189 case RPSM_EVENT_SCN_ONLINE:
1190 case RPSM_EVENT_SCN_OFFLINE:
1191 case RPSM_EVENT_FAB_SCN:
1031 case RPSM_EVENT_LOGO_RCVD: 1192 case RPSM_EVENT_LOGO_RCVD:
1032 case RPSM_EVENT_PRLO_RCVD: 1193 case RPSM_EVENT_PRLO_RCVD:
1033 case RPSM_EVENT_PLOGI_RCVD: 1194 case RPSM_EVENT_PLOGI_RCVD:
@@ -1106,6 +1267,8 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
1106 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); 1267 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1107 break; 1268 break;
1108 1269
1270 case RPSM_EVENT_SCN_ONLINE:
1271 case RPSM_EVENT_SCN_OFFLINE:
1109 case RPSM_EVENT_LOGO_RCVD: 1272 case RPSM_EVENT_LOGO_RCVD:
1110 case RPSM_EVENT_PRLO_RCVD: 1273 case RPSM_EVENT_PRLO_RCVD:
1111 /* 1274 /*
@@ -1146,6 +1309,8 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
1146 bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending); 1309 bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
1147 break; 1310 break;
1148 1311
1312 case RPSM_EVENT_SCN_ONLINE:
1313 case RPSM_EVENT_SCN_OFFLINE:
1149 case RPSM_EVENT_ADDRESS_CHANGE: 1314 case RPSM_EVENT_ADDRESS_CHANGE:
1150 break; 1315 break;
1151 1316
@@ -1172,7 +1337,9 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
1172 bfa_fcs_rport_free(rport); 1337 bfa_fcs_rport_free(rport);
1173 break; 1338 break;
1174 1339
1175 case RPSM_EVENT_SCN: 1340 case RPSM_EVENT_SCN_ONLINE:
1341 case RPSM_EVENT_SCN_OFFLINE:
1342 case RPSM_EVENT_FAB_SCN:
1176 case RPSM_EVENT_ADDRESS_CHANGE: 1343 case RPSM_EVENT_ADDRESS_CHANGE:
1177 break; 1344 break;
1178 1345
@@ -1209,10 +1376,12 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1209 bfa_fcs_rport_free(rport); 1376 bfa_fcs_rport_free(rport);
1210 break; 1377 break;
1211 1378
1212 case RPSM_EVENT_SCN: 1379 case RPSM_EVENT_FAB_SCN:
1213 case RPSM_EVENT_ADDRESS_CHANGE: 1380 case RPSM_EVENT_ADDRESS_CHANGE:
1214 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1215 bfa_timer_stop(&rport->timer); 1381 bfa_timer_stop(&rport->timer);
1382 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
1383 BFA_PORT_TOPOLOGY_LOOP));
1384 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1216 rport->ns_retries = 0; 1385 rport->ns_retries = 0;
1217 bfa_fcs_rport_send_nsdisc(rport, NULL); 1386 bfa_fcs_rport_send_nsdisc(rport, NULL);
1218 break; 1387 break;
@@ -1232,6 +1401,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1232 case RPSM_EVENT_LOGO_RCVD: 1401 case RPSM_EVENT_LOGO_RCVD:
1233 case RPSM_EVENT_PRLO_RCVD: 1402 case RPSM_EVENT_PRLO_RCVD:
1234 case RPSM_EVENT_LOGO_IMP: 1403 case RPSM_EVENT_LOGO_IMP:
1404 case RPSM_EVENT_SCN_OFFLINE:
1235 break; 1405 break;
1236 1406
1237 case RPSM_EVENT_PLOGI_COMP: 1407 case RPSM_EVENT_PLOGI_COMP:
@@ -1240,6 +1410,12 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1240 bfa_fcs_rport_fcs_online_action(rport); 1410 bfa_fcs_rport_fcs_online_action(rport);
1241 break; 1411 break;
1242 1412
1413 case RPSM_EVENT_SCN_ONLINE:
1414 bfa_timer_stop(&rport->timer);
1415 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1416 bfa_fcs_rport_send_plogi(rport, NULL);
1417 break;
1418
1243 case RPSM_EVENT_PLOGI_SEND: 1419 case RPSM_EVENT_PLOGI_SEND:
1244 bfa_timer_stop(&rport->timer); 1420 bfa_timer_stop(&rport->timer);
1245 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 1421 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
@@ -1280,7 +1456,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
1280 bfa_fcs_rport_send_plogiacc(rport, NULL); 1456 bfa_fcs_rport_send_plogiacc(rport, NULL);
1281 break; 1457 break;
1282 1458
1283 case RPSM_EVENT_SCN: 1459 case RPSM_EVENT_FAB_SCN:
1284 case RPSM_EVENT_LOGO_RCVD: 1460 case RPSM_EVENT_LOGO_RCVD:
1285 case RPSM_EVENT_PRLO_RCVD: 1461 case RPSM_EVENT_PRLO_RCVD:
1286 case RPSM_EVENT_PLOGI_SEND: 1462 case RPSM_EVENT_PLOGI_SEND:
@@ -1326,7 +1502,7 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
1326 bfa_fcs_rport_send_nsdisc(rport, NULL); 1502 bfa_fcs_rport_send_nsdisc(rport, NULL);
1327 break; 1503 break;
1328 1504
1329 case RPSM_EVENT_SCN: 1505 case RPSM_EVENT_FAB_SCN:
1330 case RPSM_EVENT_ADDRESS_CHANGE: 1506 case RPSM_EVENT_ADDRESS_CHANGE:
1331 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 1507 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1332 bfa_timer_stop(&rport->timer); 1508 bfa_timer_stop(&rport->timer);
@@ -1439,7 +1615,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1439 case RPSM_EVENT_PRLO_RCVD: 1615 case RPSM_EVENT_PRLO_RCVD:
1440 bfa_fcs_rport_send_prlo_acc(rport); 1616 bfa_fcs_rport_send_prlo_acc(rport);
1441 break; 1617 break;
1442 case RPSM_EVENT_SCN: 1618 case RPSM_EVENT_FAB_SCN:
1443 /* 1619 /*
1444 * ignore, wait for NS query response 1620 * ignore, wait for NS query response
1445 */ 1621 */
@@ -2546,7 +2722,7 @@ void
2546bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport) 2722bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
2547{ 2723{
2548 rport->stats.rscns++; 2724 rport->stats.rscns++;
2549 bfa_sm_send_event(rport, RPSM_EVENT_SCN); 2725 bfa_sm_send_event(rport, RPSM_EVENT_FAB_SCN);
2550} 2726}
2551 2727
2552/* 2728/*
@@ -2621,6 +2797,48 @@ bfa_cb_rport_qos_scn_flowid(void *cbarg,
2621 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data); 2797 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
2622} 2798}
2623 2799
2800void
2801bfa_cb_rport_scn_online(struct bfa_s *bfa)
2802{
2803 struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
2804 struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
2805 struct bfa_fcs_rport_s *rp;
2806 struct list_head *qe;
2807
2808 list_for_each(qe, &port->rport_q) {
2809 rp = (struct bfa_fcs_rport_s *) qe;
2810 bfa_sm_send_event(rp, RPSM_EVENT_SCN_ONLINE);
2811 rp->scn_online = BFA_TRUE;
2812 }
2813
2814 if (bfa_fcs_lport_is_online(port))
2815 bfa_fcs_lport_lip_scn_online(port);
2816}
2817
2818void
2819bfa_cb_rport_scn_no_dev(void *rport)
2820{
2821 struct bfa_fcs_rport_s *rp = rport;
2822
2823 bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
2824 rp->scn_online = BFA_FALSE;
2825}
2826
2827void
2828bfa_cb_rport_scn_offline(struct bfa_s *bfa)
2829{
2830 struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
2831 struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
2832 struct bfa_fcs_rport_s *rp;
2833 struct list_head *qe;
2834
2835 list_for_each(qe, &port->rport_q) {
2836 rp = (struct bfa_fcs_rport_s *) qe;
2837 bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
2838 rp->scn_online = BFA_FALSE;
2839 }
2840}
2841
2624/* 2842/*
2625 * brief 2843 * brief
2626 * This routine is a static BFA callback when there is a QoS priority 2844 * This routine is a static BFA callback when there is a QoS priority
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index b2538d60db34..fcad11629f10 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -1244,6 +1244,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
1244 * Just ignore 1244 * Just ignore
1245 */ 1245 */
1246 break; 1246 break;
1247 case BFA_LPS_SM_SET_N2N_PID:
1248 /*
1249 * When topology is set to loop, bfa_lps_set_n2n_pid() sends
1250 * this event. Ignore this event.
1251 */
1252 break;
1247 1253
1248 default: 1254 default:
1249 bfa_sm_fault(lps->bfa, event); 1255 bfa_sm_fault(lps->bfa, event);
@@ -1261,6 +1267,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
1261 1267
1262 switch (event) { 1268 switch (event) {
1263 case BFA_LPS_SM_FWRSP: 1269 case BFA_LPS_SM_FWRSP:
1270 case BFA_LPS_SM_OFFLINE:
1264 if (lps->status == BFA_STATUS_OK) { 1271 if (lps->status == BFA_STATUS_OK) {
1265 bfa_sm_set_state(lps, bfa_lps_sm_online); 1272 bfa_sm_set_state(lps, bfa_lps_sm_online);
1266 if (lps->fdisc) 1273 if (lps->fdisc)
@@ -1289,7 +1296,6 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
1289 bfa_lps_login_comp(lps); 1296 bfa_lps_login_comp(lps);
1290 break; 1297 break;
1291 1298
1292 case BFA_LPS_SM_OFFLINE:
1293 case BFA_LPS_SM_DELETE: 1299 case BFA_LPS_SM_DELETE:
1294 bfa_sm_set_state(lps, bfa_lps_sm_init); 1300 bfa_sm_set_state(lps, bfa_lps_sm_init);
1295 break; 1301 break;
@@ -2250,11 +2256,11 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
2250 if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { 2256 if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
2251 2257
2252 bfa_trc(fcport->bfa, 2258 bfa_trc(fcport->bfa,
2253 pevent->link_state.vc_fcf.fcf.fipenabled); 2259 pevent->link_state.attr.vc_fcf.fcf.fipenabled);
2254 bfa_trc(fcport->bfa, 2260 bfa_trc(fcport->bfa,
2255 pevent->link_state.vc_fcf.fcf.fipfailed); 2261 pevent->link_state.attr.vc_fcf.fcf.fipfailed);
2256 2262
2257 if (pevent->link_state.vc_fcf.fcf.fipfailed) 2263 if (pevent->link_state.attr.vc_fcf.fcf.fipfailed)
2258 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2264 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2259 BFA_PL_EID_FIP_FCF_DISC, 0, 2265 BFA_PL_EID_FIP_FCF_DISC, 0,
2260 "FIP FCF Discovery Failed"); 2266 "FIP FCF Discovery Failed");
@@ -2996,6 +3002,21 @@ bfa_fcport_iocdisable(struct bfa_s *bfa)
2996 bfa_trunk_iocdisable(bfa); 3002 bfa_trunk_iocdisable(bfa);
2997} 3003}
2998 3004
3005/*
3006 * Update loop info in fcport for SCN online
3007 */
3008static void
3009bfa_fcport_update_loop_info(struct bfa_fcport_s *fcport,
3010 struct bfa_fcport_loop_info_s *loop_info)
3011{
3012 fcport->myalpa = loop_info->myalpa;
3013 fcport->alpabm_valid =
3014 loop_info->alpabm_val;
3015 memcpy(fcport->alpabm.alpa_bm,
3016 loop_info->alpabm.alpa_bm,
3017 sizeof(struct fc_alpabm_s));
3018}
3019
2999static void 3020static void
3000bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) 3021bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
3001{ 3022{
@@ -3005,12 +3026,15 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
3005 fcport->speed = pevent->link_state.speed; 3026 fcport->speed = pevent->link_state.speed;
3006 fcport->topology = pevent->link_state.topology; 3027 fcport->topology = pevent->link_state.topology;
3007 3028
3008 if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) 3029 if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) {
3009 fcport->myalpa = 0; 3030 bfa_fcport_update_loop_info(fcport,
3031 &pevent->link_state.attr.loop_info);
3032 return;
3033 }
3010 3034
3011 /* QoS Details */ 3035 /* QoS Details */
3012 fcport->qos_attr = pevent->link_state.qos_attr; 3036 fcport->qos_attr = pevent->link_state.qos_attr;
3013 fcport->qos_vc_attr = pevent->link_state.vc_fcf.qos_vc_attr; 3037 fcport->qos_vc_attr = pevent->link_state.attr.vc_fcf.qos_vc_attr;
3014 3038
3015 /* 3039 /*
3016 * update trunk state if applicable 3040 * update trunk state if applicable
@@ -3019,7 +3043,8 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
3019 trunk->attr.state = BFA_TRUNK_DISABLED; 3043 trunk->attr.state = BFA_TRUNK_DISABLED;
3020 3044
3021 /* update FCoE specific */ 3045 /* update FCoE specific */
3022 fcport->fcoe_vlan = be16_to_cpu(pevent->link_state.vc_fcf.fcf.vlan); 3046 fcport->fcoe_vlan =
3047 be16_to_cpu(pevent->link_state.attr.vc_fcf.fcf.vlan);
3023 3048
3024 bfa_trc(fcport->bfa, fcport->speed); 3049 bfa_trc(fcport->bfa, fcport->speed);
3025 bfa_trc(fcport->bfa, fcport->topology); 3050 bfa_trc(fcport->bfa, fcport->topology);
@@ -3609,6 +3634,9 @@ bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed)
3609 3634
3610 if (fcport->cfg.trunked == BFA_TRUE) 3635 if (fcport->cfg.trunked == BFA_TRUE)
3611 return BFA_STATUS_TRUNK_ENABLED; 3636 return BFA_STATUS_TRUNK_ENABLED;
3637 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
3638 (speed == BFA_PORT_SPEED_16GBPS))
3639 return BFA_STATUS_UNSUPP_SPEED;
3612 if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { 3640 if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
3613 bfa_trc(bfa, fcport->speed_sup); 3641 bfa_trc(bfa, fcport->speed_sup);
3614 return BFA_STATUS_UNSUPP_SPEED; 3642 return BFA_STATUS_UNSUPP_SPEED;
@@ -3663,7 +3691,24 @@ bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology)
3663 3691
3664 switch (topology) { 3692 switch (topology) {
3665 case BFA_PORT_TOPOLOGY_P2P: 3693 case BFA_PORT_TOPOLOGY_P2P:
3694 break;
3695
3666 case BFA_PORT_TOPOLOGY_LOOP: 3696 case BFA_PORT_TOPOLOGY_LOOP:
3697 if ((bfa_fcport_is_qos_enabled(bfa) != BFA_FALSE) ||
3698 (fcport->qos_attr.state != BFA_QOS_DISABLED))
3699 return BFA_STATUS_ERROR_QOS_ENABLED;
3700 if (fcport->cfg.ratelimit != BFA_FALSE)
3701 return BFA_STATUS_ERROR_TRL_ENABLED;
3702 if ((bfa_fcport_is_trunk_enabled(bfa) != BFA_FALSE) ||
3703 (fcport->trunk.attr.state != BFA_TRUNK_DISABLED))
3704 return BFA_STATUS_ERROR_TRUNK_ENABLED;
3705 if ((bfa_fcport_get_speed(bfa) == BFA_PORT_SPEED_16GBPS) ||
3706 (fcport->cfg.speed == BFA_PORT_SPEED_16GBPS))
3707 return BFA_STATUS_UNSUPP_SPEED;
3708 if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type))
3709 return BFA_STATUS_LOOP_UNSUPP_MEZZ;
3710 break;
3711
3667 case BFA_PORT_TOPOLOGY_AUTO: 3712 case BFA_PORT_TOPOLOGY_AUTO:
3668 break; 3713 break;
3669 3714
@@ -3686,6 +3731,17 @@ bfa_fcport_get_topology(struct bfa_s *bfa)
3686 return fcport->topology; 3731 return fcport->topology;
3687} 3732}
3688 3733
3734/**
3735 * Get config topology.
3736 */
3737enum bfa_port_topology
3738bfa_fcport_get_cfg_topology(struct bfa_s *bfa)
3739{
3740 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3741
3742 return fcport->cfg.topology;
3743}
3744
3689bfa_status_t 3745bfa_status_t
3690bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) 3746bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
3691{ 3747{
@@ -3761,9 +3817,11 @@ bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
3761u8 3817u8
3762bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) 3818bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
3763{ 3819{
3764 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3820 if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP)
3821 return (BFA_FCPORT_MOD(bfa))->cfg.rx_bbcredit;
3765 3822
3766 return fcport->cfg.rx_bbcredit; 3823 else
3824 return 0;
3767} 3825}
3768 3826
3769void 3827void
@@ -4707,6 +4765,21 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
4707 bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN); 4765 bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN);
4708 break; 4766 break;
4709 4767
4768 case BFI_RPORT_I2H_LIP_SCN_ONLINE:
4769 bfa_fcport_update_loop_info(BFA_FCPORT_MOD(bfa),
4770 &msg.lip_scn->loop_info);
4771 bfa_cb_rport_scn_online(bfa);
4772 break;
4773
4774 case BFI_RPORT_I2H_LIP_SCN_OFFLINE:
4775 bfa_cb_rport_scn_offline(bfa);
4776 break;
4777
4778 case BFI_RPORT_I2H_NO_DEV:
4779 rp = BFA_RPORT_FROM_TAG(bfa, msg.lip_scn->bfa_handle);
4780 bfa_cb_rport_scn_no_dev(rp->rport_drv);
4781 break;
4782
4710 default: 4783 default:
4711 bfa_trc(bfa, m->mhdr.msg_id); 4784 bfa_trc(bfa, m->mhdr.msg_id);
4712 WARN_ON(1); 4785 WARN_ON(1);
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h
index 1abcf7c51661..2d1cd4349bcd 100644
--- a/drivers/scsi/bfa/bfa_svc.h
+++ b/drivers/scsi/bfa/bfa_svc.h
@@ -474,8 +474,10 @@ struct bfa_fcport_s {
474 /* supported speeds */ 474 /* supported speeds */
475 enum bfa_port_speed speed; /* current speed */ 475 enum bfa_port_speed speed; /* current speed */
476 enum bfa_port_topology topology; /* current topology */ 476 enum bfa_port_topology topology; /* current topology */
477 u8 myalpa; /* my ALPA in LOOP topology */
478 u8 rsvd[3]; 477 u8 rsvd[3];
478 u8 myalpa; /* my ALPA in LOOP topology */
479 u8 alpabm_valid; /* alpa bitmap valid or not */
480 struct fc_alpabm_s alpabm; /* alpa bitmap */
479 struct bfa_port_cfg_s cfg; /* current port configuration */ 481 struct bfa_port_cfg_s cfg; /* current port configuration */
480 bfa_boolean_t use_flash_cfg; /* get port cfg from flash */ 482 bfa_boolean_t use_flash_cfg; /* get port cfg from flash */
481 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ 483 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
@@ -534,6 +536,7 @@ enum bfa_port_speed bfa_fcport_get_speed(struct bfa_s *bfa);
534bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa, 536bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa,
535 enum bfa_port_topology topo); 537 enum bfa_port_topology topo);
536enum bfa_port_topology bfa_fcport_get_topology(struct bfa_s *bfa); 538enum bfa_port_topology bfa_fcport_get_topology(struct bfa_s *bfa);
539enum bfa_port_topology bfa_fcport_get_cfg_topology(struct bfa_s *bfa);
537bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa); 540bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
538bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa); 541bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
539u8 bfa_fcport_get_myalpa(struct bfa_s *bfa); 542u8 bfa_fcport_get_myalpa(struct bfa_s *bfa);
@@ -575,6 +578,9 @@ void bfa_cb_rport_offline(void *rport);
575void bfa_cb_rport_qos_scn_flowid(void *rport, 578void bfa_cb_rport_qos_scn_flowid(void *rport,
576 struct bfa_rport_qos_attr_s old_qos_attr, 579 struct bfa_rport_qos_attr_s old_qos_attr,
577 struct bfa_rport_qos_attr_s new_qos_attr); 580 struct bfa_rport_qos_attr_s new_qos_attr);
581void bfa_cb_rport_scn_online(struct bfa_s *bfa);
582void bfa_cb_rport_scn_offline(struct bfa_s *bfa);
583void bfa_cb_rport_scn_no_dev(void *rp);
578void bfa_cb_rport_qos_scn_prio(void *rport, 584void bfa_cb_rport_qos_scn_prio(void *rport,
579 struct bfa_rport_qos_attr_s old_qos_attr, 585 struct bfa_rport_qos_attr_s old_qos_attr,
580 struct bfa_rport_qos_attr_s new_qos_attr); 586 struct bfa_rport_qos_attr_s new_qos_attr);
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 0afa39076cef..8ddd7e8be977 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -888,16 +888,22 @@ bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
888 888
889 spin_lock_irqsave(&bfad->bfad_lock, flags); 889 spin_lock_irqsave(&bfad->bfad_lock, flags);
890 890
891 if (cmd == IOCMD_RATELIM_ENABLE) 891 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
892 fcport->cfg.ratelimit = BFA_TRUE; 892 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
893 else if (cmd == IOCMD_RATELIM_DISABLE) 893 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
894 fcport->cfg.ratelimit = BFA_FALSE; 894 else {
895 if (cmd == IOCMD_RATELIM_ENABLE)
896 fcport->cfg.ratelimit = BFA_TRUE;
897 else if (cmd == IOCMD_RATELIM_DISABLE)
898 fcport->cfg.ratelimit = BFA_FALSE;
895 899
896 if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN) 900 if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN)
897 fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS; 901 fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS;
902
903 iocmd->status = BFA_STATUS_OK;
904 }
898 905
899 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 906 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
900 iocmd->status = BFA_STATUS_OK;
901 907
902 return 0; 908 return 0;
903} 909}
@@ -919,8 +925,13 @@ bfad_iocmd_ratelim_speed(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
919 return 0; 925 return 0;
920 } 926 }
921 927
922 fcport->cfg.trl_def_speed = iocmd->speed; 928 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
923 iocmd->status = BFA_STATUS_OK; 929 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
930 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
931 else {
932 fcport->cfg.trl_def_speed = iocmd->speed;
933 iocmd->status = BFA_STATUS_OK;
934 }
924 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 935 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
925 936
926 return 0; 937 return 0;
@@ -2161,22 +2172,28 @@ bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
2161 2172
2162 spin_lock_irqsave(&bfad->bfad_lock, flags); 2173 spin_lock_irqsave(&bfad->bfad_lock, flags);
2163 2174
2164 if (v_cmd == IOCMD_TRUNK_ENABLE) { 2175 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) ||
2165 trunk->attr.state = BFA_TRUNK_OFFLINE; 2176 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
2166 bfa_fcport_disable(&bfad->bfa); 2177 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
2167 fcport->cfg.trunked = BFA_TRUE; 2178 else {
2168 } else if (v_cmd == IOCMD_TRUNK_DISABLE) { 2179 if (v_cmd == IOCMD_TRUNK_ENABLE) {
2169 trunk->attr.state = BFA_TRUNK_DISABLED; 2180 trunk->attr.state = BFA_TRUNK_OFFLINE;
2170 bfa_fcport_disable(&bfad->bfa); 2181 bfa_fcport_disable(&bfad->bfa);
2171 fcport->cfg.trunked = BFA_FALSE; 2182 fcport->cfg.trunked = BFA_TRUE;
2172 } 2183 } else if (v_cmd == IOCMD_TRUNK_DISABLE) {
2184 trunk->attr.state = BFA_TRUNK_DISABLED;
2185 bfa_fcport_disable(&bfad->bfa);
2186 fcport->cfg.trunked = BFA_FALSE;
2187 }
2188
2189 if (!bfa_fcport_is_disabled(&bfad->bfa))
2190 bfa_fcport_enable(&bfad->bfa);
2173 2191
2174 if (!bfa_fcport_is_disabled(&bfad->bfa)) 2192 iocmd->status = BFA_STATUS_OK;
2175 bfa_fcport_enable(&bfad->bfa); 2193 }
2176 2194
2177 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2195 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2178 2196
2179 iocmd->status = BFA_STATUS_OK;
2180 return 0; 2197 return 0;
2181} 2198}
2182 2199
@@ -2189,12 +2206,17 @@ bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd)
2189 unsigned long flags; 2206 unsigned long flags;
2190 2207
2191 spin_lock_irqsave(&bfad->bfad_lock, flags); 2208 spin_lock_irqsave(&bfad->bfad_lock, flags);
2192 memcpy((void *)&iocmd->attr, (void *)&trunk->attr, 2209 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) ||
2193 sizeof(struct bfa_trunk_attr_s)); 2210 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
2194 iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa); 2211 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
2212 else {
2213 memcpy((void *)&iocmd->attr, (void *)&trunk->attr,
2214 sizeof(struct bfa_trunk_attr_s));
2215 iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa);
2216 iocmd->status = BFA_STATUS_OK;
2217 }
2195 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2218 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2196 2219
2197 iocmd->status = BFA_STATUS_OK;
2198 return 0; 2220 return 0;
2199} 2221}
2200 2222
@@ -2207,14 +2229,18 @@ bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
2207 2229
2208 spin_lock_irqsave(&bfad->bfad_lock, flags); 2230 spin_lock_irqsave(&bfad->bfad_lock, flags);
2209 if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) { 2231 if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) {
2210 if (v_cmd == IOCMD_QOS_ENABLE) 2232 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
2211 fcport->cfg.qos_enabled = BFA_TRUE; 2233 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
2212 else if (v_cmd == IOCMD_QOS_DISABLE) 2234 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
2213 fcport->cfg.qos_enabled = BFA_FALSE; 2235 else {
2236 if (v_cmd == IOCMD_QOS_ENABLE)
2237 fcport->cfg.qos_enabled = BFA_TRUE;
2238 else if (v_cmd == IOCMD_QOS_DISABLE)
2239 fcport->cfg.qos_enabled = BFA_FALSE;
2240 }
2214 } 2241 }
2215 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2242 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2216 2243
2217 iocmd->status = BFA_STATUS_OK;
2218 return 0; 2244 return 0;
2219} 2245}
2220 2246
@@ -2226,11 +2252,17 @@ bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd)
2226 unsigned long flags; 2252 unsigned long flags;
2227 2253
2228 spin_lock_irqsave(&bfad->bfad_lock, flags); 2254 spin_lock_irqsave(&bfad->bfad_lock, flags);
2229 iocmd->attr.state = fcport->qos_attr.state; 2255 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
2230 iocmd->attr.total_bb_cr = be32_to_cpu(fcport->qos_attr.total_bb_cr); 2256 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
2257 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
2258 else {
2259 iocmd->attr.state = fcport->qos_attr.state;
2260 iocmd->attr.total_bb_cr =
2261 be32_to_cpu(fcport->qos_attr.total_bb_cr);
2262 iocmd->status = BFA_STATUS_OK;
2263 }
2231 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2264 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2232 2265
2233 iocmd->status = BFA_STATUS_OK;
2234 return 0; 2266 return 0;
2235} 2267}
2236 2268
@@ -2274,6 +2306,7 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd)
2274 struct bfad_hal_comp fcomp; 2306 struct bfad_hal_comp fcomp;
2275 unsigned long flags; 2307 unsigned long flags;
2276 struct bfa_cb_pending_q_s cb_qe; 2308 struct bfa_cb_pending_q_s cb_qe;
2309 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
2277 2310
2278 init_completion(&fcomp.comp); 2311 init_completion(&fcomp.comp);
2279 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, 2312 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
@@ -2281,7 +2314,11 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd)
2281 2314
2282 spin_lock_irqsave(&bfad->bfad_lock, flags); 2315 spin_lock_irqsave(&bfad->bfad_lock, flags);
2283 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); 2316 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
2284 iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); 2317 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
2318 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
2319 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
2320 else
2321 iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe);
2285 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2322 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2286 if (iocmd->status != BFA_STATUS_OK) { 2323 if (iocmd->status != BFA_STATUS_OK) {
2287 bfa_trc(bfad, iocmd->status); 2324 bfa_trc(bfad, iocmd->status);
@@ -2300,6 +2337,7 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd)
2300 struct bfad_hal_comp fcomp; 2337 struct bfad_hal_comp fcomp;
2301 unsigned long flags; 2338 unsigned long flags;
2302 struct bfa_cb_pending_q_s cb_qe; 2339 struct bfa_cb_pending_q_s cb_qe;
2340 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
2303 2341
2304 init_completion(&fcomp.comp); 2342 init_completion(&fcomp.comp);
2305 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, 2343 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
@@ -2307,7 +2345,11 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd)
2307 2345
2308 spin_lock_irqsave(&bfad->bfad_lock, flags); 2346 spin_lock_irqsave(&bfad->bfad_lock, flags);
2309 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); 2347 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
2310 iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); 2348 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
2349 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
2350 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
2351 else
2352 iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe);
2311 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2353 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2312 if (iocmd->status != BFA_STATUS_OK) { 2354 if (iocmd->status != BFA_STATUS_OK) {
2313 bfa_trc(bfad, iocmd->status); 2355 bfa_trc(bfad, iocmd->status);
diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h
index d4220e13cafa..1f73db97fe24 100644
--- a/drivers/scsi/bfa/bfi_ms.h
+++ b/drivers/scsi/bfa/bfi_ms.h
@@ -499,6 +499,9 @@ enum bfi_rport_i2h_msgs {
499 BFI_RPORT_I2H_CREATE_RSP = BFA_I2HM(1), 499 BFI_RPORT_I2H_CREATE_RSP = BFA_I2HM(1),
500 BFI_RPORT_I2H_DELETE_RSP = BFA_I2HM(2), 500 BFI_RPORT_I2H_DELETE_RSP = BFA_I2HM(2),
501 BFI_RPORT_I2H_QOS_SCN = BFA_I2HM(3), 501 BFI_RPORT_I2H_QOS_SCN = BFA_I2HM(3),
502 BFI_RPORT_I2H_LIP_SCN_ONLINE = BFA_I2HM(4),
503 BFI_RPORT_I2H_LIP_SCN_OFFLINE = BFA_I2HM(5),
504 BFI_RPORT_I2H_NO_DEV = BFA_I2HM(6),
502}; 505};
503 506
504struct bfi_rport_create_req_s { 507struct bfi_rport_create_req_s {
@@ -551,6 +554,14 @@ struct bfi_rport_qos_scn_s {
551 struct bfa_rport_qos_attr_s new_qos_attr; /* New QoS Attributes */ 554 struct bfa_rport_qos_attr_s new_qos_attr; /* New QoS Attributes */
552}; 555};
553 556
557struct bfi_rport_lip_scn_s {
558 struct bfi_mhdr_s mh; /*!< common msg header */
559 u16 bfa_handle; /*!< host rport handle */
560 u8 status; /*!< scn online status */
561 u8 rsvd;
562 struct bfa_fcport_loop_info_s loop_info;
563};
564
554union bfi_rport_h2i_msg_u { 565union bfi_rport_h2i_msg_u {
555 struct bfi_msg_s *msg; 566 struct bfi_msg_s *msg;
556 struct bfi_rport_create_req_s *create_req; 567 struct bfi_rport_create_req_s *create_req;
@@ -563,6 +574,7 @@ union bfi_rport_i2h_msg_u {
563 struct bfi_rport_create_rsp_s *create_rsp; 574 struct bfi_rport_create_rsp_s *create_rsp;
564 struct bfi_rport_delete_rsp_s *delete_rsp; 575 struct bfi_rport_delete_rsp_s *delete_rsp;
565 struct bfi_rport_qos_scn_s *qos_scn_evt; 576 struct bfi_rport_qos_scn_s *qos_scn_evt;
577 struct bfi_rport_lip_scn_s *lip_scn;
566}; 578};
567 579
568/* 580/*