Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] bfa: Add support for FC Arbitrated Loop topology.

- Add private loop topology support at 2G/4G/8G speeds with following
limitations
1. No support for multiple initiators in the loop
2. No public loop support. If attached to a loop with an FL_Port,
device continues to work as a private NL_Port in the loop
3. No auto topology detection. User has to manually set the
configured topology to loop if attaching to loop.
- When loop topology is configured, enabling FC port features
QoS/Trunk/TRL are not allowed and vice versa.

Signed-off-by: Vijaya Mohan Guvva <vmohan@brocade.com>
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

authored by

Krishna Gudipati and committed by
James Bottomley
bc0e2c2a 56d92aa5

+714 -120
+5
drivers/scsi/bfa/bfa_defs.h
··· 159 159 BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */ 160 160 BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */ 161 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 164 BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */ 163 165 BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact support */ 164 166 BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */ ··· 186 184 BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */ 187 185 BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */ 188 186 BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */ 187 + BFA_STATUS_TOPOLOGY_LOOP = 230, /* Topology is set to Loop */ 188 + BFA_STATUS_LOOP_UNSUPP_MEZZ = 231, /* Loop topology is not supported 189 + * on mezz cards */ 189 190 BFA_STATUS_MAX_VAL /* Unknown error code */ 190 191 }; 191 192 #define bfa_status_t enum bfa_status
+69 -18
drivers/scsi/bfa/bfa_defs_svc.h
··· 324 324 struct bfa_fw_fip_stats_s fip_stats; 325 325 }; 326 326 327 + /** 328 + * @brief LPSM statistics 329 + */ 330 + struct 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 361 * IOC firmware FC uport stats 329 362 */ 330 363 struct bfa_fw_fc_uport_stats_s { 331 364 struct bfa_fw_port_snsm_stats_s snsm_stats; 332 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 /* ··· 389 355 struct bfa_fw_fcxchg_stats_s { 390 356 u32 ua_tag_inv; 391 357 u32 ua_state_inv; 392 - }; 393 - 394 - struct bfa_fw_lpsm_stats_s { 395 - u32 cls_rx; 396 - u32 cls_tx; 397 358 }; 398 359 399 360 /* ··· 483 454 struct bfa_fw_io_stats_s io_stats; 484 455 struct bfa_fw_port_stats_s port_stats; 485 456 struct bfa_fw_fcxchg_stats_s fcxchg_stats; 486 - struct bfa_fw_lpsm_stats_s lpsm_stats; 487 457 struct bfa_fw_lps_stats_s lps_stats; 488 458 struct bfa_fw_trunk_stats_s trunk_stats; 489 459 struct bfa_fw_advsm_stats_s advsm_stats; ··· 526 498 * QoS attribute returned in QoS Query 527 499 */ 528 500 struct bfa_qos_attr_s { 529 - u8 state; /* QoS current state */ 530 - u8 rsvd[3]; 531 - u32 total_bb_cr; /* Total BB Credits */ 501 + u8 state; /* QoS current state */ 502 + u8 rsvd1[3]; 503 + u32 total_bb_cr; /* Total BB Credits */ 504 + u32 rsvd2[2]; 532 505 }; 533 506 534 507 /* ··· 743 714 */ 744 715 enum bfa_port_topology { 745 716 BFA_PORT_TOPOLOGY_NONE = 0, /* No valid topology */ 746 - BFA_PORT_TOPOLOGY_P2P = 1, /* P2P only */ 747 - BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */ 748 - BFA_PORT_TOPOLOGY_AUTO = 3, /* auto topology selection */ 717 + BFA_PORT_TOPOLOGY_P2P_OLD_VER = 1, /* P2P def for older ver */ 718 + BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */ 719 + BFA_PORT_TOPOLOGY_AUTO_OLD_VER = 3, /* auto def for older ver */ 720 + BFA_PORT_TOPOLOGY_AUTO = 4, /* auto topology selection */ 721 + BFA_PORT_TOPOLOGY_P2P = 5, /* P2P only */ 749 722 }; 750 723 751 724 /* ··· 882 851 u8 bb_scn; /* BB_SCN value from FLOGI Exchg */ 883 852 u8 bb_scn_state; /* Config state of BB_SCN */ 884 853 u8 faa_state; /* FAA enabled/disabled */ 885 - u8 rsvd[1]; 854 + u8 rsvd1; 886 855 u16 path_tov; /* device path timeout */ 887 856 u16 q_depth; /* SCSI Queue depth */ 857 + u32 rsvd2; 888 858 }; 889 859 #pragma pack() 890 860 ··· 1003 971 u16 vc_credits[8]; 1004 972 }; 1005 973 974 + struct bfa_fcport_loop_info_s { 975 + u8 myalpa; /* alpa claimed */ 976 + u8 alpabm_val; /* alpa bitmap valid or not (1 or 0) */ 977 + u8 resvd[6]; 978 + struct fc_alpabm_s alpabm; /* alpa bitmap */ 979 + }; 980 + 1006 981 /* 1007 982 * Link state information 1008 983 */ ··· 1020 981 u8 speed; /* Link speed (1/2/4/8 G) */ 1021 982 u32 linkstate_opt; /* Linkstate optional data (debug) */ 1022 983 u8 trunked; /* Trunked or not (1 or 0) */ 1023 - u8 resvd[3]; 984 + u8 resvd[7]; 1024 985 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ 1025 986 union { 1026 - struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */ 1027 - struct bfa_trunk_vc_attr_s trunk_vc_attr; 1028 - struct bfa_fcport_fcf_s fcf; /* FCF information (for FCoE) */ 1029 - } vc_fcf; 987 + struct bfa_fcport_loop_info_s loop_info; 988 + union { 989 + struct bfa_qos_vc_attr_s qos_vc_attr; 990 + /* VC info from ELP */ 991 + struct bfa_trunk_vc_attr_s trunk_vc_attr; 992 + struct bfa_fcport_fcf_s fcf; 993 + /* FCF information (for FCoE) */ 994 + } vc_fcf; 995 + } attr; 1030 996 }; 1031 997 #pragma pack() 1032 998 ··· 1156 1112 u64 tx_frames; /* Tx frames */ 1157 1113 u64 tx_words; /* Tx words */ 1158 1114 u64 tx_lip; /* Tx LIP */ 1115 + u64 tx_lip_f7f7; /* Tx LIP_F7F7 */ 1116 + u64 tx_lip_f8f7; /* Tx LIP_F8F7 */ 1117 + u64 tx_arbf0; /* Tx ARB F0 */ 1159 1118 u64 tx_nos; /* Tx NOS */ 1160 1119 u64 tx_ols; /* Tx OLS */ 1161 1120 u64 tx_lr; /* Tx LR */ ··· 1166 1119 u64 rx_frames; /* Rx frames */ 1167 1120 u64 rx_words; /* Rx words */ 1168 1121 u64 lip_count; /* Rx LIP */ 1122 + u64 rx_lip_f7f7; /* Rx LIP_F7F7 */ 1123 + u64 rx_lip_f8f7; /* Rx LIP_F8F7 */ 1124 + u64 rx_arbf0; /* Rx ARB F0 */ 1169 1125 u64 nos_count; /* Rx NOS */ 1170 1126 u64 ols_count; /* Rx OLS */ 1171 1127 u64 lr_count; /* Rx LR */ ··· 1190 1140 u64 bbsc_frames_lost; /* Credit Recovery-Frames Lost */ 1191 1141 u64 bbsc_credits_lost; /* Credit Recovery-Credits Lost */ 1192 1142 u64 bbsc_link_resets; /* Credit Recovery-Link Resets */ 1143 + u64 loop_timeouts; /* Loop timeouts */ 1193 1144 }; 1194 1145 1195 1146 /*
+5
drivers/scsi/bfa/bfa_fc.h
··· 24 24 25 25 #define WWN_NULL (0) 26 26 #define FC_SYMNAME_MAX 256 /* max name server symbolic name size */ 27 + #define FC_ALPA_MAX 128 27 28 28 29 #pragma pack(1) 29 30 ··· 1014 1013 */ 1015 1014 struct fc_symname_s { 1016 1015 u8 symname[FC_SYMNAME_MAX]; 1016 + }; 1017 + 1018 + struct fc_alpabm_s { 1019 + u8 alpa_bm[FC_ALPA_MAX / 8]; 1017 1020 }; 1018 1021 1019 1022 /*
+4
drivers/scsi/bfa/bfa_fcbuild.c
··· 228 228 229 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 235 plogi->els_cmd.els_code = els_code; 232 236 if (els_code == FC_ELS_PLOGI) 233 237 fc_els_req_build(fchs, d_id, s_id, ox_id);
+51 -13
drivers/scsi/bfa/bfa_fcs.c
··· 303 303 bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric, 304 304 enum bfa_fcs_fabric_event event) 305 305 { 306 + struct bfa_s *bfa = fabric->fcs->bfa; 307 + 306 308 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); 307 309 bfa_trc(fabric->fcs, event); 308 310 309 311 switch (event) { 310 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 327 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); 313 328 bfa_fcs_fabric_login(fabric); 314 - } else 315 - bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); 329 + } 316 330 break; 317 331 318 332 case BFA_FCS_FABRIC_SM_LINK_UP: ··· 351 337 bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric, 352 338 enum bfa_fcs_fabric_event event) 353 339 { 340 + struct bfa_s *bfa = fabric->fcs->bfa; 341 + 354 342 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); 355 343 bfa_trc(fabric->fcs, event); 356 344 357 345 switch (event) { 358 346 case BFA_FCS_FABRIC_SM_LINK_UP: 359 - bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); 360 - bfa_fcs_fabric_login(fabric); 347 + if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) { 348 + bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); 349 + bfa_fcs_fabric_login(fabric); 350 + break; 351 + } 352 + fabric->fab_type = BFA_FCS_FABRIC_LOOP; 353 + fabric->bport.pid = bfa_fcport_get_myalpa(bfa); 354 + fabric->bport.pid = bfa_hton3b(fabric->bport.pid); 355 + bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online); 356 + bfa_fcs_fabric_set_opertype(fabric); 357 + bfa_fcs_lport_online(&fabric->bport); 361 358 break; 362 359 363 360 case BFA_FCS_FABRIC_SM_RETRY_OP: 361 + case BFA_FCS_FABRIC_SM_LOOPBACK: 364 362 break; 365 363 366 364 case BFA_FCS_FABRIC_SM_DELETE: ··· 621 595 bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric, 622 596 enum bfa_fcs_fabric_event event) 623 597 { 598 + struct bfa_s *bfa = fabric->fcs->bfa; 599 + 624 600 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); 625 601 bfa_trc(fabric->fcs, event); 626 602 627 603 switch (event) { 628 604 case BFA_FCS_FABRIC_SM_LINK_DOWN: 629 605 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); 630 - bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE); 631 - bfa_fcs_fabric_notify_offline(fabric); 606 + if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) { 607 + bfa_fcs_lport_offline(&fabric->bport); 608 + } else { 609 + bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE); 610 + bfa_fcs_fabric_notify_offline(fabric); 611 + } 632 612 break; 633 613 634 614 case BFA_FCS_FABRIC_SM_DELETE: ··· 751 719 bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric, 752 720 enum bfa_fcs_fabric_event event) 753 721 { 722 + struct bfa_s *bfa = fabric->fcs->bfa; 723 + 754 724 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); 755 725 bfa_trc(fabric->fcs, event); 756 726 757 727 switch (event) { 758 728 case BFA_FCS_FABRIC_SM_STOPCOMP: 759 - bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup); 760 - bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT); 729 + if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) { 730 + bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created); 731 + } else { 732 + bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup); 733 + bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT); 734 + } 761 735 break; 762 736 763 737 case BFA_FCS_FABRIC_SM_LINK_UP: 764 738 break; 765 739 766 740 case BFA_FCS_FABRIC_SM_LINK_DOWN: 767 - bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup); 741 + if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) 742 + bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created); 743 + else 744 + bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup); 768 745 break; 769 746 770 747 default: ··· 1015 974 struct bfa_s *bfa = fabric->fcs->bfa; 1016 975 struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg; 1017 976 u8 alpa = 0, bb_scn = 0; 1018 - 1019 - if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) 1020 - alpa = bfa_fcport_get_myalpa(bfa); 1021 977 1022 978 if (bfa_fcs_fabric_is_bbscn_enabled(fabric) && 1023 979 (!fabric->fcs->bbscn_flogi_rjt))
+12 -7
drivers/scsi/bfa/bfa_fcs.h
··· 118 118 #define MAX_ALPA_COUNT 127 119 119 120 120 struct bfa_fcs_lport_loop_s { 121 - u8 num_alpa; /* Num of ALPA entries in the map */ 122 - u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional 123 - *Map */ 121 + u8 num_alpa; /* Num of ALPA entries in the map */ 122 + u8 alpabm_valid; /* alpa bitmap valid or not (1 or 0) */ 123 + u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional Map */ 124 124 struct bfa_fcs_lport_s *port; /* parent port */ 125 125 }; 126 126 ··· 175 175 BFA_FCS_FABRIC_UNKNOWN = 0, 176 176 BFA_FCS_FABRIC_SWITCHED = 1, 177 177 BFA_FCS_FABRIC_N2N = 2, 178 + BFA_FCS_FABRIC_LOOP = 3, 178 179 }; 179 180 180 181 ··· 351 350 struct bfa_fcxp_s *fcxp_alloced); 352 351 void bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *vport); 353 352 void bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *vport); 354 - void bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *vport); 353 + void bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *vport); 355 354 void bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port, 356 355 struct fchs_s *rx_frame, u32 len); 356 + void bfa_fcs_lport_lip_scn_online(bfa_fcs_lport_t *port); 357 357 358 358 struct bfa_fcs_vport_s { 359 359 struct list_head qe; /* queue elem */ ··· 455 453 struct bfa_rport_stats_s stats; /* rport stats */ 456 454 enum bfa_rport_function scsi_function; /* Initiator/Target */ 457 455 struct bfa_fcs_rpf_s rpf; /* Rport features module */ 456 + bfa_boolean_t scn_online; /* SCN online flag */ 458 457 }; 459 458 460 459 static inline struct bfa_rport_s * ··· 736 733 RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */ 737 734 RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */ 738 735 RPSM_EVENT_DELETE = 7, /* RPORT delete request */ 739 - RPSM_EVENT_SCN = 8, /* state change notification */ 736 + RPSM_EVENT_FAB_SCN = 8, /* state change notification */ 740 737 RPSM_EVENT_ACCEPTED = 9, /* Good response from remote device */ 741 738 RPSM_EVENT_FAILED = 10, /* Request to rport failed. */ 742 739 RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */ ··· 747 744 RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */ 748 745 RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */ 749 746 RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continuously */ 750 - RPSM_EVENT_FC4_FCS_ONLINE = 19, /*!< FC-4 FCS online complete */ 747 + RPSM_EVENT_SCN_OFFLINE = 19, /* loop scn offline */ 748 + RPSM_EVENT_SCN_ONLINE = 20, /* loop scn online */ 749 + RPSM_EVENT_FC4_FCS_ONLINE = 21, /* FC-4 FCS online complete */ 751 750 }; 752 751 753 752 /* ··· 768 763 BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */ 769 764 BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */ 770 765 BFA_FCS_ITNIM_SM_RSP_NOT_SUPP = 12, /* cmd not supported rsp */ 771 - BFA_FCS_ITNIM_SM_HAL_ONLINE = 13, /*!< bfa rport online event */ 766 + BFA_FCS_ITNIM_SM_HAL_ONLINE = 13, /* bfa rport online event */ 772 767 }; 773 768 774 769 /*
+138 -3
drivers/scsi/bfa/bfa_fcs_lport.c
··· 23 23 24 24 BFA_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 + */ 32 + static 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 + 26 54 static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, 27 55 struct fchs_s *rx_fchs, u8 reason_code, 28 56 u8 reason_code_expl); ··· 79 51 static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port); 80 52 static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port); 81 53 54 + static void bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port); 55 + static void bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port); 56 + static void bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port); 57 + 82 58 static struct { 83 59 void (*init) (struct bfa_fcs_lport_s *port); 84 60 void (*online) (struct bfa_fcs_lport_s *port); ··· 94 62 bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online, 95 63 bfa_fcs_lport_fab_offline}, { 96 64 bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online, 97 - bfa_fcs_lport_n2n_offline}, 65 + bfa_fcs_lport_n2n_offline}, { 66 + bfa_fcs_lport_loop_init, bfa_fcs_lport_loop_online, 67 + bfa_fcs_lport_loop_offline}, 98 68 }; 99 69 100 70 /* ··· 1161 1127 bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port) 1162 1128 { 1163 1129 bfa_fcs_lport_ns_online(port); 1164 - bfa_fcs_lport_scn_online(port); 1130 + bfa_fcs_lport_fab_scn_online(port); 1165 1131 } 1166 1132 1167 1133 /* ··· 1253 1219 port->pid = 0; 1254 1220 n2n_port->rem_port_wwn = 0; 1255 1221 n2n_port->reply_oxid = 0; 1222 + } 1223 + 1224 + void 1225 + bfa_fcport_get_loop_attr(struct bfa_fcs_lport_s *port) 1226 + { 1227 + int i = 0, j = 0, bit = 0, alpa_bit = 0; 1228 + u8 k = 0; 1229 + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(port->fcs->bfa); 1230 + 1231 + port->port_topo.ploop.alpabm_valid = fcport->alpabm_valid; 1232 + port->pid = fcport->myalpa; 1233 + port->pid = bfa_hton3b(port->pid); 1234 + 1235 + for (i = 0; i < (FC_ALPA_MAX / 8); i++) { 1236 + for (j = 0, alpa_bit = 0; j < 8; j++, alpa_bit++) { 1237 + bfa_trc(port->fcs->bfa, fcport->alpabm.alpa_bm[i]); 1238 + bit = (fcport->alpabm.alpa_bm[i] & (1 << (7 - j))); 1239 + if (bit) { 1240 + port->port_topo.ploop.alpa_pos_map[k] = 1241 + loop_alpa_map[(i * 8) + alpa_bit]; 1242 + k++; 1243 + bfa_trc(port->fcs->bfa, k); 1244 + bfa_trc(port->fcs->bfa, 1245 + port->port_topo.ploop.alpa_pos_map[k]); 1246 + } 1247 + } 1248 + } 1249 + port->port_topo.ploop.num_alpa = k; 1250 + } 1251 + 1252 + /* 1253 + * Called by fcs/port to initialize Loop topology. 1254 + */ 1255 + static void 1256 + bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port) 1257 + { 1258 + } 1259 + 1260 + /* 1261 + * Called by fcs/port to notify transition to online state. 1262 + */ 1263 + static void 1264 + bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port) 1265 + { 1266 + u8 num_alpa = 0, alpabm_valid = 0; 1267 + struct bfa_fcs_rport_s *rport; 1268 + u8 *alpa_map = NULL; 1269 + int i = 0; 1270 + u32 pid; 1271 + 1272 + bfa_fcport_get_loop_attr(port); 1273 + 1274 + num_alpa = port->port_topo.ploop.num_alpa; 1275 + alpabm_valid = port->port_topo.ploop.alpabm_valid; 1276 + alpa_map = port->port_topo.ploop.alpa_pos_map; 1277 + 1278 + bfa_trc(port->fcs->bfa, port->pid); 1279 + bfa_trc(port->fcs->bfa, num_alpa); 1280 + if (alpabm_valid == 1) { 1281 + for (i = 0; i < num_alpa; i++) { 1282 + bfa_trc(port->fcs->bfa, alpa_map[i]); 1283 + if (alpa_map[i] != bfa_hton3b(port->pid)) { 1284 + pid = alpa_map[i]; 1285 + bfa_trc(port->fcs->bfa, pid); 1286 + rport = bfa_fcs_lport_get_rport_by_pid(port, 1287 + bfa_hton3b(pid)); 1288 + if (!rport) 1289 + rport = bfa_fcs_rport_create(port, 1290 + bfa_hton3b(pid)); 1291 + } 1292 + } 1293 + } else { 1294 + for (i = 0; i < MAX_ALPA_COUNT; i++) { 1295 + if (alpa_map[i] != port->pid) { 1296 + pid = loop_alpa_map[i]; 1297 + bfa_trc(port->fcs->bfa, pid); 1298 + rport = bfa_fcs_lport_get_rport_by_pid(port, 1299 + bfa_hton3b(pid)); 1300 + if (!rport) 1301 + rport = bfa_fcs_rport_create(port, 1302 + bfa_hton3b(pid)); 1303 + } 1304 + } 1305 + } 1306 + } 1307 + 1308 + /* 1309 + * Called by fcs/port to notify transition to offline state. 1310 + */ 1311 + static void 1312 + bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port) 1313 + { 1256 1314 } 1257 1315 1258 1316 #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 ··· 5325 5199 } 5326 5200 5327 5201 void 5328 - bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port) 5202 + bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *port) 5329 5203 { 5330 5204 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 5331 5205 ··· 5744 5618 bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port) 5745 5619 { 5746 5620 memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s)); 5621 + } 5622 + 5623 + /* 5624 + * Let new loop map create missing rports 5625 + */ 5626 + void 5627 + bfa_fcs_lport_lip_scn_online(struct bfa_fcs_lport_s *port) 5628 + { 5629 + bfa_fcs_lport_loop_online(port); 5747 5630 } 5748 5631 5749 5632 /*
+251 -33
drivers/scsi/bfa/bfa_fcs_rport.c
··· 106 106 enum rport_event event); 107 107 static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, 108 108 enum rport_event event); 109 - static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, 110 - enum rport_event event); 111 - static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, 109 + static void bfa_fcs_rport_sm_adisc_online_sending( 110 + struct bfa_fcs_rport_s *rport, enum rport_event event); 111 + static void bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport, 112 + enum rport_event event); 113 + static void bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s 114 + *rport, enum rport_event event); 115 + static void bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport, 112 116 enum rport_event event); 113 117 static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, 114 118 enum rport_event event); ··· 154 150 {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE}, 155 151 {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY}, 156 152 {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY}, 157 - {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC}, 158 - {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC}, 153 + {BFA_SM(bfa_fcs_rport_sm_adisc_online_sending), BFA_RPORT_ADISC}, 154 + {BFA_SM(bfa_fcs_rport_sm_adisc_online), BFA_RPORT_ADISC}, 155 + {BFA_SM(bfa_fcs_rport_sm_adisc_offline_sending), BFA_RPORT_ADISC}, 156 + {BFA_SM(bfa_fcs_rport_sm_adisc_offline), BFA_RPORT_ADISC}, 159 157 {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV}, 160 158 {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO}, 161 159 {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE}, ··· 237 231 bfa_fcs_rport_send_plogiacc(rport, NULL); 238 232 break; 239 233 234 + case RPSM_EVENT_SCN_OFFLINE: 235 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 236 + bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 237 + bfa_timer_start(rport->fcs->bfa, &rport->timer, 238 + bfa_fcs_rport_timeout, rport, 239 + bfa_fcs_rport_del_timeout); 240 + break; 240 241 case RPSM_EVENT_ADDRESS_CHANGE: 241 - case RPSM_EVENT_SCN: 242 + case RPSM_EVENT_FAB_SCN: 242 243 /* query the NS */ 243 244 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 245 + WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) != 246 + BFA_PORT_TOPOLOGY_LOOP)); 244 247 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 245 248 rport->ns_retries = 0; 246 249 bfa_fcs_rport_send_nsdisc(rport, NULL); ··· 295 280 296 281 case RPSM_EVENT_PLOGI_RCVD: 297 282 case RPSM_EVENT_PLOGI_COMP: 298 - case RPSM_EVENT_SCN: 283 + case RPSM_EVENT_FAB_SCN: 299 284 /* 300 285 * Ignore, SCN is possibly online notification. 301 286 */ 287 + break; 288 + 289 + case RPSM_EVENT_SCN_OFFLINE: 290 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 291 + bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 292 + bfa_timer_start(rport->fcs->bfa, &rport->timer, 293 + bfa_fcs_rport_timeout, rport, 294 + bfa_fcs_rport_del_timeout); 302 295 break; 303 296 304 297 case RPSM_EVENT_ADDRESS_CHANGE: ··· 369 346 bfa_fcs_rport_send_plogiacc(rport, NULL); 370 347 break; 371 348 372 - case RPSM_EVENT_ADDRESS_CHANGE: 373 - case RPSM_EVENT_SCN: 349 + case RPSM_EVENT_SCN_OFFLINE: 350 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 374 351 bfa_timer_stop(&rport->timer); 352 + bfa_timer_start(rport->fcs->bfa, &rport->timer, 353 + bfa_fcs_rport_timeout, rport, 354 + bfa_fcs_rport_del_timeout); 355 + break; 356 + 357 + case RPSM_EVENT_ADDRESS_CHANGE: 358 + case RPSM_EVENT_FAB_SCN: 359 + bfa_timer_stop(&rport->timer); 360 + WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) != 361 + BFA_PORT_TOPOLOGY_LOOP)); 375 362 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 376 363 rport->ns_retries = 0; 377 364 bfa_fcs_rport_send_nsdisc(rport, NULL); ··· 455 422 } 456 423 break; 457 424 458 - case RPSM_EVENT_PLOGI_RETRY: 425 + case RPSM_EVENT_SCN_ONLINE: 426 + break; 427 + 428 + case RPSM_EVENT_SCN_OFFLINE: 429 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 430 + bfa_fcxp_discard(rport->fcxp); 431 + bfa_timer_start(rport->fcs->bfa, &rport->timer, 432 + bfa_fcs_rport_timeout, rport, 433 + bfa_fcs_rport_del_timeout); 434 + break; 435 + 436 + case RPSM_EVENT_PLOGI_RETRY: 459 437 rport->plogi_retries = 0; 460 438 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry); 461 439 bfa_timer_start(rport->fcs->bfa, &rport->timer, ··· 484 440 break; 485 441 486 442 case RPSM_EVENT_ADDRESS_CHANGE: 487 - case RPSM_EVENT_SCN: 443 + case RPSM_EVENT_FAB_SCN: 488 444 bfa_fcxp_discard(rport->fcxp); 445 + WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) != 446 + BFA_PORT_TOPOLOGY_LOOP)); 489 447 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 490 448 rport->ns_retries = 0; 491 449 bfa_fcs_rport_send_nsdisc(rport, NULL); ··· 558 512 case RPSM_EVENT_PLOGI_COMP: 559 513 case RPSM_EVENT_LOGO_IMP: 560 514 case RPSM_EVENT_ADDRESS_CHANGE: 561 - case RPSM_EVENT_SCN: 515 + case RPSM_EVENT_FAB_SCN: 516 + case RPSM_EVENT_SCN_OFFLINE: 562 517 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 563 518 bfa_fcs_rport_fcs_offline_action(rport); 564 519 break; ··· 608 561 bfa_fcs_rport_fcs_offline_action(rport); 609 562 break; 610 563 611 - case RPSM_EVENT_SCN: 564 + case RPSM_EVENT_FAB_SCN: 612 565 case RPSM_EVENT_LOGO_IMP: 613 566 case RPSM_EVENT_ADDRESS_CHANGE: 567 + case RPSM_EVENT_SCN_OFFLINE: 614 568 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 615 569 bfa_fcs_rport_fcs_offline_action(rport); 616 570 break; ··· 643 595 bfa_trc(rport->fcs, event); 644 596 645 597 switch (event) { 646 - case RPSM_EVENT_SCN: 598 + case RPSM_EVENT_FAB_SCN: 647 599 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { 648 600 bfa_sm_set_state(rport, 649 601 bfa_fcs_rport_sm_nsquery_sending); 650 602 rport->ns_retries = 0; 651 603 bfa_fcs_rport_send_nsdisc(rport, NULL); 652 604 } else { 653 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); 605 + bfa_sm_set_state(rport, 606 + bfa_fcs_rport_sm_adisc_online_sending); 654 607 bfa_fcs_rport_send_adisc(rport, NULL); 655 608 } 656 609 break; ··· 659 610 case RPSM_EVENT_PLOGI_RCVD: 660 611 case RPSM_EVENT_LOGO_IMP: 661 612 case RPSM_EVENT_ADDRESS_CHANGE: 613 + case RPSM_EVENT_SCN_OFFLINE: 662 614 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 663 615 bfa_fcs_rport_hal_offline_action(rport); 664 616 break; ··· 675 625 bfa_fcs_rport_hal_offline_action(rport); 676 626 break; 677 627 628 + case RPSM_EVENT_SCN_ONLINE: 678 629 case RPSM_EVENT_PLOGI_COMP: 679 630 break; 680 631 ··· 707 656 bfa_fcs_rport_hal_offline_action(rport); 708 657 break; 709 658 710 - case RPSM_EVENT_SCN: 659 + case RPSM_EVENT_FAB_SCN: 711 660 /* 712 661 * ignore SCN, wait for response to query itself 713 662 */ ··· 747 696 748 697 switch (event) { 749 698 case RPSM_EVENT_ACCEPTED: 750 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); 699 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online_sending); 751 700 bfa_fcs_rport_send_adisc(rport, NULL); 752 701 break; 753 702 ··· 769 718 bfa_fcs_rport_hal_offline_action(rport); 770 719 break; 771 720 772 - case RPSM_EVENT_SCN: 721 + case RPSM_EVENT_FAB_SCN: 773 722 break; 774 723 775 724 case RPSM_EVENT_LOGO_RCVD: ··· 798 747 * authenticating with rport. FC-4s are paused. 799 748 */ 800 749 static void 801 - bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, 750 + bfa_fcs_rport_sm_adisc_online_sending(struct bfa_fcs_rport_s *rport, 802 751 enum rport_event event) 803 752 { 804 753 bfa_trc(rport->fcs, rport->pwwn); ··· 807 756 808 757 switch (event) { 809 758 case RPSM_EVENT_FCXP_SENT: 810 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc); 759 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online); 811 760 break; 812 761 813 762 case RPSM_EVENT_DELETE: ··· 830 779 bfa_fcs_rport_hal_offline_action(rport); 831 780 break; 832 781 833 - case RPSM_EVENT_SCN: 782 + case RPSM_EVENT_FAB_SCN: 834 783 break; 835 784 836 785 case RPSM_EVENT_PLOGI_RCVD: ··· 849 798 * FC-4s are paused. 850 799 */ 851 800 static void 852 - bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event) 801 + bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport, 802 + enum rport_event event) 853 803 { 854 804 bfa_trc(rport->fcs, rport->pwwn); 855 805 bfa_trc(rport->fcs, rport->pid); ··· 883 831 bfa_fcs_rport_hal_offline_action(rport); 884 832 break; 885 833 886 - case RPSM_EVENT_SCN: 834 + case RPSM_EVENT_FAB_SCN: 887 835 /* 888 836 * already processing RSCN 889 837 */ ··· 908 856 } 909 857 910 858 /* 911 - * Rport has sent LOGO. Awaiting FC-4 offline completion callback. 859 + * ADISC is being sent for authenticating with rport 860 + * Already did offline actions. 861 + */ 862 + static void 863 + bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s *rport, 864 + enum rport_event event) 865 + { 866 + bfa_trc(rport->fcs, rport->pwwn); 867 + bfa_trc(rport->fcs, rport->pid); 868 + bfa_trc(rport->fcs, event); 869 + 870 + switch (event) { 871 + case RPSM_EVENT_FCXP_SENT: 872 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_offline); 873 + break; 874 + 875 + case RPSM_EVENT_DELETE: 876 + case RPSM_EVENT_SCN_OFFLINE: 877 + case RPSM_EVENT_LOGO_IMP: 878 + case RPSM_EVENT_LOGO_RCVD: 879 + case RPSM_EVENT_PRLO_RCVD: 880 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 881 + bfa_fcxp_walloc_cancel(rport->fcs->bfa, 882 + &rport->fcxp_wqe); 883 + bfa_timer_start(rport->fcs->bfa, &rport->timer, 884 + bfa_fcs_rport_timeout, rport, 885 + bfa_fcs_rport_del_timeout); 886 + break; 887 + 888 + case RPSM_EVENT_PLOGI_RCVD: 889 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 890 + bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 891 + bfa_fcs_rport_send_plogiacc(rport, NULL); 892 + break; 893 + 894 + default: 895 + bfa_sm_fault(rport->fcs, event); 896 + } 897 + } 898 + 899 + /* 900 + * ADISC to rport 901 + * Already did offline actions 902 + */ 903 + static void 904 + bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport, 905 + enum rport_event event) 906 + { 907 + bfa_trc(rport->fcs, rport->pwwn); 908 + bfa_trc(rport->fcs, rport->pid); 909 + bfa_trc(rport->fcs, event); 910 + 911 + switch (event) { 912 + case RPSM_EVENT_ACCEPTED: 913 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 914 + bfa_fcs_rport_hal_online(rport); 915 + break; 916 + 917 + case RPSM_EVENT_PLOGI_RCVD: 918 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 919 + bfa_fcxp_discard(rport->fcxp); 920 + bfa_fcs_rport_send_plogiacc(rport, NULL); 921 + break; 922 + 923 + case RPSM_EVENT_FAILED: 924 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 925 + bfa_timer_start(rport->fcs->bfa, &rport->timer, 926 + bfa_fcs_rport_timeout, rport, 927 + bfa_fcs_rport_del_timeout); 928 + break; 929 + 930 + case RPSM_EVENT_DELETE: 931 + case RPSM_EVENT_SCN_OFFLINE: 932 + case RPSM_EVENT_LOGO_IMP: 933 + case RPSM_EVENT_LOGO_RCVD: 934 + case RPSM_EVENT_PRLO_RCVD: 935 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 936 + bfa_fcxp_discard(rport->fcxp); 937 + bfa_timer_start(rport->fcs->bfa, &rport->timer, 938 + bfa_fcs_rport_timeout, rport, 939 + bfa_fcs_rport_del_timeout); 940 + break; 941 + 942 + default: 943 + bfa_sm_fault(rport->fcs, event); 944 + } 945 + } 946 + 947 + /* 948 + * Rport has sent LOGO. Awaiting FC-4 offline completion callback. 912 949 */ 913 950 static void 914 951 bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, ··· 1022 881 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete); 1023 882 break; 1024 883 884 + case RPSM_EVENT_SCN_ONLINE: 885 + case RPSM_EVENT_SCN_OFFLINE: 1025 886 case RPSM_EVENT_HCB_ONLINE: 1026 887 case RPSM_EVENT_LOGO_RCVD: 1027 888 case RPSM_EVENT_PRLO_RCVD: ··· 1088 945 bfa_fcs_rport_hal_offline(rport); 1089 946 break; 1090 947 948 + case RPSM_EVENT_SCN_ONLINE: 949 + break; 1091 950 case RPSM_EVENT_LOGO_RCVD: 1092 951 /* 1093 952 * Rport is going offline. Just ack the logo ··· 1101 956 bfa_fcs_rport_send_prlo_acc(rport); 1102 957 break; 1103 958 959 + case RPSM_EVENT_SCN_OFFLINE: 1104 960 case RPSM_EVENT_HCB_ONLINE: 1105 - case RPSM_EVENT_SCN: 961 + case RPSM_EVENT_FAB_SCN: 1106 962 case RPSM_EVENT_LOGO_IMP: 1107 963 case RPSM_EVENT_ADDRESS_CHANGE: 1108 964 /* ··· 1161 1015 bfa_fcs_rport_sm_nsdisc_sending); 1162 1016 rport->ns_retries = 0; 1163 1017 bfa_fcs_rport_send_nsdisc(rport, NULL); 1018 + } else if (bfa_fcport_get_topology(rport->port->fcs->bfa) == 1019 + BFA_PORT_TOPOLOGY_LOOP) { 1020 + if (rport->scn_online) { 1021 + bfa_sm_set_state(rport, 1022 + bfa_fcs_rport_sm_adisc_offline_sending); 1023 + bfa_fcs_rport_send_adisc(rport, NULL); 1024 + } else { 1025 + bfa_sm_set_state(rport, 1026 + bfa_fcs_rport_sm_offline); 1027 + bfa_timer_start(rport->fcs->bfa, &rport->timer, 1028 + bfa_fcs_rport_timeout, rport, 1029 + bfa_fcs_rport_del_timeout); 1030 + } 1164 1031 } else { 1165 1032 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 1166 1033 rport->plogi_retries = 0; ··· 1186 1027 bfa_fcs_rport_free(rport); 1187 1028 break; 1188 1029 1189 - case RPSM_EVENT_SCN: 1030 + case RPSM_EVENT_SCN_ONLINE: 1031 + case RPSM_EVENT_SCN_OFFLINE: 1032 + case RPSM_EVENT_FAB_SCN: 1190 1033 case RPSM_EVENT_LOGO_RCVD: 1191 1034 case RPSM_EVENT_PRLO_RCVD: 1192 1035 case RPSM_EVENT_PLOGI_RCVD: ··· 1267 1106 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); 1268 1107 break; 1269 1108 1109 + case RPSM_EVENT_SCN_ONLINE: 1110 + case RPSM_EVENT_SCN_OFFLINE: 1270 1111 case RPSM_EVENT_LOGO_RCVD: 1271 1112 case RPSM_EVENT_PRLO_RCVD: 1272 1113 /* ··· 1309 1146 bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending); 1310 1147 break; 1311 1148 1149 + case RPSM_EVENT_SCN_ONLINE: 1150 + case RPSM_EVENT_SCN_OFFLINE: 1312 1151 case RPSM_EVENT_ADDRESS_CHANGE: 1313 1152 break; 1314 1153 ··· 1337 1172 bfa_fcs_rport_free(rport); 1338 1173 break; 1339 1174 1340 - case RPSM_EVENT_SCN: 1175 + case RPSM_EVENT_SCN_ONLINE: 1176 + case RPSM_EVENT_SCN_OFFLINE: 1177 + case RPSM_EVENT_FAB_SCN: 1341 1178 case RPSM_EVENT_ADDRESS_CHANGE: 1342 1179 break; 1343 1180 ··· 1376 1209 bfa_fcs_rport_free(rport); 1377 1210 break; 1378 1211 1379 - case RPSM_EVENT_SCN: 1212 + case RPSM_EVENT_FAB_SCN: 1380 1213 case RPSM_EVENT_ADDRESS_CHANGE: 1381 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 1382 1214 bfa_timer_stop(&rport->timer); 1215 + WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) != 1216 + BFA_PORT_TOPOLOGY_LOOP)); 1217 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 1383 1218 rport->ns_retries = 0; 1384 1219 bfa_fcs_rport_send_nsdisc(rport, NULL); 1385 1220 break; ··· 1401 1232 case RPSM_EVENT_LOGO_RCVD: 1402 1233 case RPSM_EVENT_PRLO_RCVD: 1403 1234 case RPSM_EVENT_LOGO_IMP: 1235 + case RPSM_EVENT_SCN_OFFLINE: 1404 1236 break; 1405 1237 1406 1238 case RPSM_EVENT_PLOGI_COMP: 1407 1239 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 1408 1240 bfa_timer_stop(&rport->timer); 1409 1241 bfa_fcs_rport_fcs_online_action(rport); 1242 + break; 1243 + 1244 + case RPSM_EVENT_SCN_ONLINE: 1245 + bfa_timer_stop(&rport->timer); 1246 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 1247 + bfa_fcs_rport_send_plogi(rport, NULL); 1410 1248 break; 1411 1249 1412 1250 case RPSM_EVENT_PLOGI_SEND: ··· 1456 1280 bfa_fcs_rport_send_plogiacc(rport, NULL); 1457 1281 break; 1458 1282 1459 - case RPSM_EVENT_SCN: 1283 + case RPSM_EVENT_FAB_SCN: 1460 1284 case RPSM_EVENT_LOGO_RCVD: 1461 1285 case RPSM_EVENT_PRLO_RCVD: 1462 1286 case RPSM_EVENT_PLOGI_SEND: ··· 1502 1326 bfa_fcs_rport_send_nsdisc(rport, NULL); 1503 1327 break; 1504 1328 1505 - case RPSM_EVENT_SCN: 1329 + case RPSM_EVENT_FAB_SCN: 1506 1330 case RPSM_EVENT_ADDRESS_CHANGE: 1507 1331 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 1508 1332 bfa_timer_stop(&rport->timer); ··· 1615 1439 case RPSM_EVENT_PRLO_RCVD: 1616 1440 bfa_fcs_rport_send_prlo_acc(rport); 1617 1441 break; 1618 - case RPSM_EVENT_SCN: 1442 + case RPSM_EVENT_FAB_SCN: 1619 1443 /* 1620 1444 * ignore, wait for NS query response 1621 1445 */ ··· 2722 2546 bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport) 2723 2547 { 2724 2548 rport->stats.rscns++; 2725 - bfa_sm_send_event(rport, RPSM_EVENT_SCN); 2549 + bfa_sm_send_event(rport, RPSM_EVENT_FAB_SCN); 2726 2550 } 2727 2551 2728 2552 /* ··· 2795 2619 bfa_trc(rport->fcs, rport->pwwn); 2796 2620 aen_data.priv.qos = new_qos_attr; 2797 2621 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data); 2622 + } 2623 + 2624 + void 2625 + bfa_cb_rport_scn_online(struct bfa_s *bfa) 2626 + { 2627 + struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs; 2628 + struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs); 2629 + struct bfa_fcs_rport_s *rp; 2630 + struct list_head *qe; 2631 + 2632 + list_for_each(qe, &port->rport_q) { 2633 + rp = (struct bfa_fcs_rport_s *) qe; 2634 + bfa_sm_send_event(rp, RPSM_EVENT_SCN_ONLINE); 2635 + rp->scn_online = BFA_TRUE; 2636 + } 2637 + 2638 + if (bfa_fcs_lport_is_online(port)) 2639 + bfa_fcs_lport_lip_scn_online(port); 2640 + } 2641 + 2642 + void 2643 + bfa_cb_rport_scn_no_dev(void *rport) 2644 + { 2645 + struct bfa_fcs_rport_s *rp = rport; 2646 + 2647 + bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE); 2648 + rp->scn_online = BFA_FALSE; 2649 + } 2650 + 2651 + void 2652 + bfa_cb_rport_scn_offline(struct bfa_s *bfa) 2653 + { 2654 + struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs; 2655 + struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs); 2656 + struct bfa_fcs_rport_s *rp; 2657 + struct list_head *qe; 2658 + 2659 + list_for_each(qe, &port->rport_q) { 2660 + rp = (struct bfa_fcs_rport_s *) qe; 2661 + bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE); 2662 + rp->scn_online = BFA_FALSE; 2663 + } 2798 2664 } 2799 2665 2800 2666 /*
+83 -10
drivers/scsi/bfa/bfa_svc.c
··· 1244 1244 * Just ignore 1245 1245 */ 1246 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 1254 default: 1249 1255 bfa_sm_fault(lps->bfa, event); ··· 1267 1261 1268 1262 switch (event) { 1269 1263 case BFA_LPS_SM_FWRSP: 1264 + case BFA_LPS_SM_OFFLINE: 1270 1265 if (lps->status == BFA_STATUS_OK) { 1271 1266 bfa_sm_set_state(lps, bfa_lps_sm_online); 1272 1267 if (lps->fdisc) ··· 1296 1289 bfa_lps_login_comp(lps); 1297 1290 break; 1298 1291 1299 - case BFA_LPS_SM_OFFLINE: 1300 1292 case BFA_LPS_SM_DELETE: 1301 1293 bfa_sm_set_state(lps, bfa_lps_sm_init); 1302 1294 break; ··· 2256 2250 if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { 2257 2251 2258 2252 bfa_trc(fcport->bfa, 2259 - pevent->link_state.vc_fcf.fcf.fipenabled); 2253 + pevent->link_state.attr.vc_fcf.fcf.fipenabled); 2260 2254 bfa_trc(fcport->bfa, 2261 - pevent->link_state.vc_fcf.fcf.fipfailed); 2255 + pevent->link_state.attr.vc_fcf.fcf.fipfailed); 2262 2256 2263 - if (pevent->link_state.vc_fcf.fcf.fipfailed) 2257 + if (pevent->link_state.attr.vc_fcf.fcf.fipfailed) 2264 2258 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2265 2259 BFA_PL_EID_FIP_FCF_DISC, 0, 2266 2260 "FIP FCF Discovery Failed"); ··· 3002 2996 bfa_trunk_iocdisable(bfa); 3003 2997 } 3004 2998 2999 + /* 3000 + * Update loop info in fcport for SCN online 3001 + */ 3002 + static void 3003 + bfa_fcport_update_loop_info(struct bfa_fcport_s *fcport, 3004 + struct bfa_fcport_loop_info_s *loop_info) 3005 + { 3006 + fcport->myalpa = loop_info->myalpa; 3007 + fcport->alpabm_valid = 3008 + loop_info->alpabm_val; 3009 + memcpy(fcport->alpabm.alpa_bm, 3010 + loop_info->alpabm.alpa_bm, 3011 + sizeof(struct fc_alpabm_s)); 3012 + } 3013 + 3005 3014 static void 3006 3015 bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) 3007 3016 { ··· 3026 3005 fcport->speed = pevent->link_state.speed; 3027 3006 fcport->topology = pevent->link_state.topology; 3028 3007 3029 - if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) 3030 - fcport->myalpa = 0; 3008 + if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) { 3009 + bfa_fcport_update_loop_info(fcport, 3010 + &pevent->link_state.attr.loop_info); 3011 + return; 3012 + } 3031 3013 3032 3014 /* QoS Details */ 3033 3015 fcport->qos_attr = pevent->link_state.qos_attr; 3034 - fcport->qos_vc_attr = pevent->link_state.vc_fcf.qos_vc_attr; 3016 + fcport->qos_vc_attr = pevent->link_state.attr.vc_fcf.qos_vc_attr; 3035 3017 3036 3018 /* 3037 3019 * update trunk state if applicable ··· 3043 3019 trunk->attr.state = BFA_TRUNK_DISABLED; 3044 3020 3045 3021 /* update FCoE specific */ 3046 - fcport->fcoe_vlan = be16_to_cpu(pevent->link_state.vc_fcf.fcf.vlan); 3022 + fcport->fcoe_vlan = 3023 + be16_to_cpu(pevent->link_state.attr.vc_fcf.fcf.vlan); 3047 3024 3048 3025 bfa_trc(fcport->bfa, fcport->speed); 3049 3026 bfa_trc(fcport->bfa, fcport->topology); ··· 3634 3609 3635 3610 if (fcport->cfg.trunked == BFA_TRUE) 3636 3611 return BFA_STATUS_TRUNK_ENABLED; 3612 + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 3613 + (speed == BFA_PORT_SPEED_16GBPS)) 3614 + return BFA_STATUS_UNSUPP_SPEED; 3637 3615 if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { 3638 3616 bfa_trc(bfa, fcport->speed_sup); 3639 3617 return BFA_STATUS_UNSUPP_SPEED; ··· 3691 3663 3692 3664 switch (topology) { 3693 3665 case BFA_PORT_TOPOLOGY_P2P: 3666 + break; 3667 + 3694 3668 case BFA_PORT_TOPOLOGY_LOOP: 3669 + if ((bfa_fcport_is_qos_enabled(bfa) != BFA_FALSE) || 3670 + (fcport->qos_attr.state != BFA_QOS_DISABLED)) 3671 + return BFA_STATUS_ERROR_QOS_ENABLED; 3672 + if (fcport->cfg.ratelimit != BFA_FALSE) 3673 + return BFA_STATUS_ERROR_TRL_ENABLED; 3674 + if ((bfa_fcport_is_trunk_enabled(bfa) != BFA_FALSE) || 3675 + (fcport->trunk.attr.state != BFA_TRUNK_DISABLED)) 3676 + return BFA_STATUS_ERROR_TRUNK_ENABLED; 3677 + if ((bfa_fcport_get_speed(bfa) == BFA_PORT_SPEED_16GBPS) || 3678 + (fcport->cfg.speed == BFA_PORT_SPEED_16GBPS)) 3679 + return BFA_STATUS_UNSUPP_SPEED; 3680 + if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) 3681 + return BFA_STATUS_LOOP_UNSUPP_MEZZ; 3682 + break; 3683 + 3695 3684 case BFA_PORT_TOPOLOGY_AUTO: 3696 3685 break; 3697 3686 ··· 3729 3684 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3730 3685 3731 3686 return fcport->topology; 3687 + } 3688 + 3689 + /** 3690 + * Get config topology. 3691 + */ 3692 + enum bfa_port_topology 3693 + bfa_fcport_get_cfg_topology(struct bfa_s *bfa) 3694 + { 3695 + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3696 + 3697 + return fcport->cfg.topology; 3732 3698 } 3733 3699 3734 3700 bfa_status_t ··· 3817 3761 u8 3818 3762 bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) 3819 3763 { 3820 - struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3764 + if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) 3765 + return (BFA_FCPORT_MOD(bfa))->cfg.rx_bbcredit; 3821 3766 3822 - return fcport->cfg.rx_bbcredit; 3767 + else 3768 + return 0; 3823 3769 } 3824 3770 3825 3771 void ··· 4763 4705 rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle); 4764 4706 rp->event_arg.fw_msg = msg.qos_scn_evt; 4765 4707 bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN); 4708 + break; 4709 + 4710 + case BFI_RPORT_I2H_LIP_SCN_ONLINE: 4711 + bfa_fcport_update_loop_info(BFA_FCPORT_MOD(bfa), 4712 + &msg.lip_scn->loop_info); 4713 + bfa_cb_rport_scn_online(bfa); 4714 + break; 4715 + 4716 + case BFI_RPORT_I2H_LIP_SCN_OFFLINE: 4717 + bfa_cb_rport_scn_offline(bfa); 4718 + break; 4719 + 4720 + case BFI_RPORT_I2H_NO_DEV: 4721 + rp = BFA_RPORT_FROM_TAG(bfa, msg.lip_scn->bfa_handle); 4722 + bfa_cb_rport_scn_no_dev(rp->rport_drv); 4766 4723 break; 4767 4724 4768 4725 default:
+7 -1
drivers/scsi/bfa/bfa_svc.h
··· 474 474 /* supported speeds */ 475 475 enum bfa_port_speed speed; /* current speed */ 476 476 enum bfa_port_topology topology; /* current topology */ 477 - u8 myalpa; /* my ALPA in LOOP topology */ 478 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 481 struct bfa_port_cfg_s cfg; /* current port configuration */ 480 482 bfa_boolean_t use_flash_cfg; /* get port cfg from flash */ 481 483 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ ··· 536 534 bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa, 537 535 enum bfa_port_topology topo); 538 536 enum bfa_port_topology bfa_fcport_get_topology(struct bfa_s *bfa); 537 + enum bfa_port_topology bfa_fcport_get_cfg_topology(struct bfa_s *bfa); 539 538 bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa); 540 539 bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa); 541 540 u8 bfa_fcport_get_myalpa(struct bfa_s *bfa); ··· 578 575 void bfa_cb_rport_qos_scn_flowid(void *rport, 579 576 struct bfa_rport_qos_attr_s old_qos_attr, 580 577 struct bfa_rport_qos_attr_s new_qos_attr); 578 + void bfa_cb_rport_scn_online(struct bfa_s *bfa); 579 + void bfa_cb_rport_scn_offline(struct bfa_s *bfa); 580 + void bfa_cb_rport_scn_no_dev(void *rp); 581 581 void bfa_cb_rport_qos_scn_prio(void *rport, 582 582 struct bfa_rport_qos_attr_s old_qos_attr, 583 583 struct bfa_rport_qos_attr_s new_qos_attr);
+77 -35
drivers/scsi/bfa/bfad_bsg.c
··· 888 888 889 889 spin_lock_irqsave(&bfad->bfad_lock, flags); 890 890 891 - if (cmd == IOCMD_RATELIM_ENABLE) 892 - fcport->cfg.ratelimit = BFA_TRUE; 893 - else if (cmd == IOCMD_RATELIM_DISABLE) 894 - fcport->cfg.ratelimit = BFA_FALSE; 891 + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 892 + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 893 + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 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) 897 - fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS; 900 + if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN) 901 + fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS; 902 + 903 + iocmd->status = BFA_STATUS_OK; 904 + } 898 905 899 906 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 900 - iocmd->status = BFA_STATUS_OK; 901 907 902 908 return 0; 903 909 } ··· 925 919 return 0; 926 920 } 927 921 928 - fcport->cfg.trl_def_speed = iocmd->speed; 929 - iocmd->status = BFA_STATUS_OK; 922 + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 923 + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 924 + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 925 + else { 926 + fcport->cfg.trl_def_speed = iocmd->speed; 927 + iocmd->status = BFA_STATUS_OK; 928 + } 930 929 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 931 930 932 931 return 0; ··· 2172 2161 2173 2162 spin_lock_irqsave(&bfad->bfad_lock, flags); 2174 2163 2175 - if (v_cmd == IOCMD_TRUNK_ENABLE) { 2176 - trunk->attr.state = BFA_TRUNK_OFFLINE; 2177 - bfa_fcport_disable(&bfad->bfa); 2178 - fcport->cfg.trunked = BFA_TRUE; 2179 - } else if (v_cmd == IOCMD_TRUNK_DISABLE) { 2180 - trunk->attr.state = BFA_TRUNK_DISABLED; 2181 - bfa_fcport_disable(&bfad->bfa); 2182 - fcport->cfg.trunked = BFA_FALSE; 2183 - } 2164 + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || 2165 + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2166 + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2167 + else { 2168 + if (v_cmd == IOCMD_TRUNK_ENABLE) { 2169 + trunk->attr.state = BFA_TRUNK_OFFLINE; 2170 + bfa_fcport_disable(&bfad->bfa); 2171 + fcport->cfg.trunked = BFA_TRUE; 2172 + } else if (v_cmd == IOCMD_TRUNK_DISABLE) { 2173 + trunk->attr.state = BFA_TRUNK_DISABLED; 2174 + bfa_fcport_disable(&bfad->bfa); 2175 + fcport->cfg.trunked = BFA_FALSE; 2176 + } 2184 2177 2185 - if (!bfa_fcport_is_disabled(&bfad->bfa)) 2186 - bfa_fcport_enable(&bfad->bfa); 2178 + if (!bfa_fcport_is_disabled(&bfad->bfa)) 2179 + bfa_fcport_enable(&bfad->bfa); 2180 + 2181 + iocmd->status = BFA_STATUS_OK; 2182 + } 2187 2183 2188 2184 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2189 2185 2190 - iocmd->status = BFA_STATUS_OK; 2191 2186 return 0; 2192 2187 } 2193 2188 ··· 2206 2189 unsigned long flags; 2207 2190 2208 2191 spin_lock_irqsave(&bfad->bfad_lock, flags); 2209 - memcpy((void *)&iocmd->attr, (void *)&trunk->attr, 2210 - sizeof(struct bfa_trunk_attr_s)); 2211 - iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa); 2192 + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || 2193 + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2194 + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2195 + else { 2196 + memcpy((void *)&iocmd->attr, (void *)&trunk->attr, 2197 + sizeof(struct bfa_trunk_attr_s)); 2198 + iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa); 2199 + iocmd->status = BFA_STATUS_OK; 2200 + } 2212 2201 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2213 2202 2214 - iocmd->status = BFA_STATUS_OK; 2215 2203 return 0; 2216 2204 } 2217 2205 ··· 2229 2207 2230 2208 spin_lock_irqsave(&bfad->bfad_lock, flags); 2231 2209 if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) { 2232 - if (v_cmd == IOCMD_QOS_ENABLE) 2233 - fcport->cfg.qos_enabled = BFA_TRUE; 2234 - else if (v_cmd == IOCMD_QOS_DISABLE) 2235 - fcport->cfg.qos_enabled = BFA_FALSE; 2210 + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2211 + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2212 + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2213 + else { 2214 + if (v_cmd == IOCMD_QOS_ENABLE) 2215 + fcport->cfg.qos_enabled = BFA_TRUE; 2216 + else if (v_cmd == IOCMD_QOS_DISABLE) 2217 + fcport->cfg.qos_enabled = BFA_FALSE; 2218 + } 2236 2219 } 2237 2220 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2238 2221 2239 - iocmd->status = BFA_STATUS_OK; 2240 2222 return 0; 2241 2223 } 2242 2224 ··· 2252 2226 unsigned long flags; 2253 2227 2254 2228 spin_lock_irqsave(&bfad->bfad_lock, flags); 2255 - iocmd->attr.state = fcport->qos_attr.state; 2256 - iocmd->attr.total_bb_cr = be32_to_cpu(fcport->qos_attr.total_bb_cr); 2229 + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2230 + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2231 + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2232 + else { 2233 + iocmd->attr.state = fcport->qos_attr.state; 2234 + iocmd->attr.total_bb_cr = 2235 + be32_to_cpu(fcport->qos_attr.total_bb_cr); 2236 + iocmd->status = BFA_STATUS_OK; 2237 + } 2257 2238 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2258 2239 2259 - iocmd->status = BFA_STATUS_OK; 2260 2240 return 0; 2261 2241 } 2262 2242 ··· 2306 2274 struct bfad_hal_comp fcomp; 2307 2275 unsigned long flags; 2308 2276 struct bfa_cb_pending_q_s cb_qe; 2277 + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2309 2278 2310 2279 init_completion(&fcomp.comp); 2311 2280 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, ··· 2314 2281 2315 2282 spin_lock_irqsave(&bfad->bfad_lock, flags); 2316 2283 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); 2317 - iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); 2284 + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2285 + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2286 + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2287 + else 2288 + iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); 2318 2289 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2319 2290 if (iocmd->status != BFA_STATUS_OK) { 2320 2291 bfa_trc(bfad, iocmd->status); ··· 2337 2300 struct bfad_hal_comp fcomp; 2338 2301 unsigned long flags; 2339 2302 struct bfa_cb_pending_q_s cb_qe; 2303 + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2340 2304 2341 2305 init_completion(&fcomp.comp); 2342 2306 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, ··· 2345 2307 2346 2308 spin_lock_irqsave(&bfad->bfad_lock, flags); 2347 2309 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); 2348 - iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); 2310 + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2311 + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2312 + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2313 + else 2314 + iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); 2349 2315 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2350 2316 if (iocmd->status != BFA_STATUS_OK) { 2351 2317 bfa_trc(bfad, iocmd->status);
+12
drivers/scsi/bfa/bfi_ms.h
··· 499 499 BFI_RPORT_I2H_CREATE_RSP = BFA_I2HM(1), 500 500 BFI_RPORT_I2H_DELETE_RSP = BFA_I2HM(2), 501 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 504 507 struct bfi_rport_create_req_s { ··· 554 551 struct bfa_rport_qos_attr_s new_qos_attr; /* New QoS Attributes */ 555 552 }; 556 553 554 + struct bfi_rport_lip_scn_s { 555 + struct bfi_mhdr_s mh; /*!< common msg header */ 556 + u16 bfa_handle; /*!< host rport handle */ 557 + u8 status; /*!< scn online status */ 558 + u8 rsvd; 559 + struct bfa_fcport_loop_info_s loop_info; 560 + }; 561 + 557 562 union bfi_rport_h2i_msg_u { 558 563 struct bfi_msg_s *msg; 559 564 struct bfi_rport_create_req_s *create_req; ··· 574 563 struct bfi_rport_create_rsp_s *create_rsp; 575 564 struct bfi_rport_delete_rsp_s *delete_rsp; 576 565 struct bfi_rport_qos_scn_s *qos_scn_evt; 566 + struct bfi_rport_lip_scn_s *lip_scn; 577 567 }; 578 568 579 569 /*