diff options
Diffstat (limited to 'drivers/scsi/bfa/bfa_fcs.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs.c | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index eb42e74ed423..6c8a27e78974 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c | |||
@@ -196,6 +196,9 @@ static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg, | |||
196 | u32 rsp_len, | 196 | u32 rsp_len, |
197 | u32 resid_len, | 197 | u32 resid_len, |
198 | struct fchs_s *rspfchs); | 198 | struct fchs_s *rspfchs); |
199 | static u8 bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric); | ||
200 | static bfa_boolean_t bfa_fcs_fabric_is_bbscn_enabled( | ||
201 | struct bfa_fcs_fabric_s *fabric); | ||
199 | 202 | ||
200 | static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric, | 203 | static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric, |
201 | enum bfa_fcs_fabric_event event); | 204 | enum bfa_fcs_fabric_event event); |
@@ -322,7 +325,8 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric, | |||
322 | case BFA_FCS_FABRIC_SM_CONT_OP: | 325 | case BFA_FCS_FABRIC_SM_CONT_OP: |
323 | 326 | ||
324 | bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, | 327 | bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, |
325 | fabric->bb_credit); | 328 | fabric->bb_credit, |
329 | bfa_fcs_fabric_oper_bbscn(fabric)); | ||
326 | fabric->fab_type = BFA_FCS_FABRIC_SWITCHED; | 330 | fabric->fab_type = BFA_FCS_FABRIC_SWITCHED; |
327 | 331 | ||
328 | if (fabric->auth_reqd && fabric->is_auth) { | 332 | if (fabric->auth_reqd && fabric->is_auth) { |
@@ -350,7 +354,8 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric, | |||
350 | case BFA_FCS_FABRIC_SM_NO_FABRIC: | 354 | case BFA_FCS_FABRIC_SM_NO_FABRIC: |
351 | fabric->fab_type = BFA_FCS_FABRIC_N2N; | 355 | fabric->fab_type = BFA_FCS_FABRIC_N2N; |
352 | bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, | 356 | bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, |
353 | fabric->bb_credit); | 357 | fabric->bb_credit, |
358 | bfa_fcs_fabric_oper_bbscn(fabric)); | ||
354 | bfa_fcs_fabric_notify_online(fabric); | 359 | bfa_fcs_fabric_notify_online(fabric); |
355 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric); | 360 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric); |
356 | break; | 361 | break; |
@@ -518,7 +523,8 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric, | |||
518 | case BFA_FCS_FABRIC_SM_NO_FABRIC: | 523 | case BFA_FCS_FABRIC_SM_NO_FABRIC: |
519 | bfa_trc(fabric->fcs, fabric->bb_credit); | 524 | bfa_trc(fabric->fcs, fabric->bb_credit); |
520 | bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, | 525 | bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, |
521 | fabric->bb_credit); | 526 | fabric->bb_credit, |
527 | bfa_fcs_fabric_oper_bbscn(fabric)); | ||
522 | break; | 528 | break; |
523 | 529 | ||
524 | default: | 530 | default: |
@@ -764,6 +770,10 @@ bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status) | |||
764 | 770 | ||
765 | case BFA_STATUS_FABRIC_RJT: | 771 | case BFA_STATUS_FABRIC_RJT: |
766 | fabric->stats.flogi_rejects++; | 772 | fabric->stats.flogi_rejects++; |
773 | if (fabric->lps->lsrjt_rsn == FC_LS_RJT_RSN_LOGICAL_ERROR && | ||
774 | fabric->lps->lsrjt_expl == FC_LS_RJT_EXP_NO_ADDL_INFO) | ||
775 | fabric->fcs->bbscn_flogi_rjt = BFA_TRUE; | ||
776 | |||
767 | bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP); | 777 | bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP); |
768 | return; | 778 | return; |
769 | 779 | ||
@@ -808,13 +818,17 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric) | |||
808 | { | 818 | { |
809 | struct bfa_s *bfa = fabric->fcs->bfa; | 819 | struct bfa_s *bfa = fabric->fcs->bfa; |
810 | struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg; | 820 | struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg; |
811 | u8 alpa = 0; | 821 | u8 alpa = 0, bb_scn = 0; |
812 | 822 | ||
813 | if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) | 823 | if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) |
814 | alpa = bfa_fcport_get_myalpa(bfa); | 824 | alpa = bfa_fcport_get_myalpa(bfa); |
815 | 825 | ||
826 | if (bfa_fcs_fabric_is_bbscn_enabled(fabric) && | ||
827 | (!fabric->fcs->bbscn_flogi_rjt)) | ||
828 | bb_scn = BFA_FCS_PORT_DEF_BB_SCN; | ||
829 | |||
816 | bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa), | 830 | bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa), |
817 | pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd); | 831 | pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd, bb_scn); |
818 | 832 | ||
819 | fabric->stats.flogi_sent++; | 833 | fabric->stats.flogi_sent++; |
820 | } | 834 | } |
@@ -873,6 +887,37 @@ bfa_fcs_fabric_delay(void *cbarg) | |||
873 | } | 887 | } |
874 | 888 | ||
875 | /* | 889 | /* |
890 | * Computes operating BB_SCN value | ||
891 | */ | ||
892 | static u8 | ||
893 | bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric) | ||
894 | { | ||
895 | u8 pr_bbscn = fabric->lps->pr_bbscn; | ||
896 | |||
897 | if (!(fabric->fcs->bbscn_enabled && pr_bbscn)) | ||
898 | return 0; | ||
899 | |||
900 | /* return max of local/remote bb_scn values */ | ||
901 | return ((pr_bbscn > BFA_FCS_PORT_DEF_BB_SCN) ? | ||
902 | pr_bbscn : BFA_FCS_PORT_DEF_BB_SCN); | ||
903 | } | ||
904 | |||
905 | /* | ||
906 | * Check if BB_SCN can be enabled. | ||
907 | */ | ||
908 | static bfa_boolean_t | ||
909 | bfa_fcs_fabric_is_bbscn_enabled(struct bfa_fcs_fabric_s *fabric) | ||
910 | { | ||
911 | if (bfa_ioc_get_fcmode(&fabric->fcs->bfa->ioc) && | ||
912 | fabric->fcs->bbscn_enabled && | ||
913 | !bfa_fcport_is_qos_enabled(fabric->fcs->bfa) && | ||
914 | !bfa_fcport_is_trunk_enabled(fabric->fcs->bfa)) | ||
915 | return BFA_TRUE; | ||
916 | else | ||
917 | return BFA_FALSE; | ||
918 | } | ||
919 | |||
920 | /* | ||
876 | * Delete all vports and wait for vport delete completions. | 921 | * Delete all vports and wait for vport delete completions. |
877 | */ | 922 | */ |
878 | static void | 923 | static void |
@@ -989,6 +1034,7 @@ void | |||
989 | bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric) | 1034 | bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric) |
990 | { | 1035 | { |
991 | bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); | 1036 | bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); |
1037 | fabric->fcs->bbscn_flogi_rjt = BFA_FALSE; | ||
992 | bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN); | 1038 | bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN); |
993 | } | 1039 | } |
994 | 1040 | ||
@@ -1192,6 +1238,7 @@ bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric, | |||
1192 | } | 1238 | } |
1193 | 1239 | ||
1194 | fabric->bb_credit = be16_to_cpu(flogi->csp.bbcred); | 1240 | fabric->bb_credit = be16_to_cpu(flogi->csp.bbcred); |
1241 | fabric->lps->pr_bbscn = (be16_to_cpu(flogi->csp.rxsz) >> 12); | ||
1195 | bport->port_topo.pn2n.rem_port_wwn = flogi->port_name; | 1242 | bport->port_topo.pn2n.rem_port_wwn = flogi->port_name; |
1196 | bport->port_topo.pn2n.reply_oxid = fchs->ox_id; | 1243 | bport->port_topo.pn2n.reply_oxid = fchs->ox_id; |
1197 | 1244 | ||
@@ -1224,7 +1271,8 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric) | |||
1224 | n2n_port->reply_oxid, pcfg->pwwn, | 1271 | n2n_port->reply_oxid, pcfg->pwwn, |
1225 | pcfg->nwwn, | 1272 | pcfg->nwwn, |
1226 | bfa_fcport_get_maxfrsize(bfa), | 1273 | bfa_fcport_get_maxfrsize(bfa), |
1227 | bfa_fcport_get_rx_bbcredit(bfa)); | 1274 | bfa_fcport_get_rx_bbcredit(bfa), |
1275 | bfa_fcs_fabric_oper_bbscn(fabric)); | ||
1228 | 1276 | ||
1229 | bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->lp_tag, | 1277 | bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->lp_tag, |
1230 | BFA_FALSE, FC_CLASS_3, | 1278 | BFA_FALSE, FC_CLASS_3, |