diff options
Diffstat (limited to 'drivers/scsi/bfa/rport.c')
-rw-r--r-- | drivers/scsi/bfa/rport.c | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c index 4e1fff21a5bc..9b4c2c9a644b 100644 --- a/drivers/scsi/bfa/rport.c +++ b/drivers/scsi/bfa/rport.c | |||
@@ -93,6 +93,7 @@ static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, | |||
93 | u8 reason_code_expl); | 93 | u8 reason_code_expl); |
94 | static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport, | 94 | static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport, |
95 | struct fchs_s *rx_fchs, u16 len); | 95 | struct fchs_s *rx_fchs, u16 len); |
96 | static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport); | ||
96 | /** | 97 | /** |
97 | * fcs_rport_sm FCS rport state machine events | 98 | * fcs_rport_sm FCS rport state machine events |
98 | */ | 99 | */ |
@@ -113,7 +114,8 @@ enum rport_event { | |||
113 | RPSM_EVENT_HCB_OFFLINE = 13, /* BFA rport offline callback */ | 114 | RPSM_EVENT_HCB_OFFLINE = 13, /* BFA rport offline callback */ |
114 | RPSM_EVENT_FC4_OFFLINE = 14, /* FC-4 offline complete */ | 115 | RPSM_EVENT_FC4_OFFLINE = 14, /* FC-4 offline complete */ |
115 | RPSM_EVENT_ADDRESS_CHANGE = 15, /* Rport's PID has changed */ | 116 | RPSM_EVENT_ADDRESS_CHANGE = 15, /* Rport's PID has changed */ |
116 | RPSM_EVENT_ADDRESS_DISC = 16 /* Need to Discover rport's PID */ | 117 | RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */ |
118 | RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */ | ||
117 | }; | 119 | }; |
118 | 120 | ||
119 | static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, | 121 | static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, |
@@ -373,6 +375,7 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport, | |||
373 | bfa_fcs_rport_free(rport); | 375 | bfa_fcs_rport_free(rport); |
374 | break; | 376 | break; |
375 | 377 | ||
378 | case RPSM_EVENT_PRLO_RCVD: | ||
376 | case RPSM_EVENT_LOGO_RCVD: | 379 | case RPSM_EVENT_LOGO_RCVD: |
377 | break; | 380 | break; |
378 | 381 | ||
@@ -428,6 +431,13 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
428 | 431 | ||
429 | case RPSM_EVENT_LOGO_RCVD: | 432 | case RPSM_EVENT_LOGO_RCVD: |
430 | bfa_fcs_rport_send_logo_acc(rport); | 433 | bfa_fcs_rport_send_logo_acc(rport); |
434 | /* | ||
435 | * !! fall through !! | ||
436 | */ | ||
437 | case RPSM_EVENT_PRLO_RCVD: | ||
438 | if (rport->prlo == BFA_TRUE) | ||
439 | bfa_fcs_rport_send_prlo_acc(rport); | ||
440 | |||
431 | bfa_fcxp_discard(rport->fcxp); | 441 | bfa_fcxp_discard(rport->fcxp); |
432 | /* | 442 | /* |
433 | * !! fall through !! | 443 | * !! fall through !! |
@@ -502,6 +512,9 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, | |||
502 | bfa_fcs_rport_online_action(rport); | 512 | bfa_fcs_rport_online_action(rport); |
503 | break; | 513 | break; |
504 | 514 | ||
515 | case RPSM_EVENT_PRLO_RCVD: | ||
516 | break; | ||
517 | |||
505 | case RPSM_EVENT_LOGO_RCVD: | 518 | case RPSM_EVENT_LOGO_RCVD: |
506 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv); | 519 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv); |
507 | bfa_rport_offline(rport->bfa_rport); | 520 | bfa_rport_offline(rport->bfa_rport); |
@@ -580,6 +593,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
580 | break; | 593 | break; |
581 | 594 | ||
582 | case RPSM_EVENT_LOGO_RCVD: | 595 | case RPSM_EVENT_LOGO_RCVD: |
596 | case RPSM_EVENT_PRLO_RCVD: | ||
583 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); | 597 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); |
584 | bfa_fcs_rport_offline_action(rport); | 598 | bfa_fcs_rport_offline_action(rport); |
585 | break; | 599 | break; |
@@ -622,6 +636,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, | |||
622 | break; | 636 | break; |
623 | 637 | ||
624 | case RPSM_EVENT_LOGO_RCVD: | 638 | case RPSM_EVENT_LOGO_RCVD: |
639 | case RPSM_EVENT_PRLO_RCVD: | ||
625 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); | 640 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); |
626 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); | 641 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); |
627 | bfa_fcs_rport_offline_action(rport); | 642 | bfa_fcs_rport_offline_action(rport); |
@@ -688,6 +703,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
688 | break; | 703 | break; |
689 | 704 | ||
690 | case RPSM_EVENT_LOGO_RCVD: | 705 | case RPSM_EVENT_LOGO_RCVD: |
706 | case RPSM_EVENT_PRLO_RCVD: | ||
691 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); | 707 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); |
692 | bfa_fcxp_discard(rport->fcxp); | 708 | bfa_fcxp_discard(rport->fcxp); |
693 | bfa_fcs_rport_offline_action(rport); | 709 | bfa_fcs_rport_offline_action(rport); |
@@ -738,6 +754,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, | |||
738 | break; | 754 | break; |
739 | 755 | ||
740 | case RPSM_EVENT_LOGO_RCVD: | 756 | case RPSM_EVENT_LOGO_RCVD: |
757 | case RPSM_EVENT_PRLO_RCVD: | ||
741 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); | 758 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); |
742 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); | 759 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); |
743 | bfa_fcs_rport_offline_action(rport); | 760 | bfa_fcs_rport_offline_action(rport); |
@@ -809,6 +826,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
809 | break; | 826 | break; |
810 | 827 | ||
811 | case RPSM_EVENT_LOGO_RCVD: | 828 | case RPSM_EVENT_LOGO_RCVD: |
829 | case RPSM_EVENT_PRLO_RCVD: | ||
812 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); | 830 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); |
813 | bfa_fcxp_discard(rport->fcxp); | 831 | bfa_fcxp_discard(rport->fcxp); |
814 | bfa_fcs_rport_offline_action(rport); | 832 | bfa_fcs_rport_offline_action(rport); |
@@ -841,6 +859,7 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, | |||
841 | break; | 859 | break; |
842 | 860 | ||
843 | case RPSM_EVENT_LOGO_RCVD: | 861 | case RPSM_EVENT_LOGO_RCVD: |
862 | case RPSM_EVENT_PRLO_RCVD: | ||
844 | case RPSM_EVENT_ADDRESS_CHANGE: | 863 | case RPSM_EVENT_ADDRESS_CHANGE: |
845 | break; | 864 | break; |
846 | 865 | ||
@@ -892,6 +911,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport, | |||
892 | case RPSM_EVENT_SCN: | 911 | case RPSM_EVENT_SCN: |
893 | case RPSM_EVENT_LOGO_IMP: | 912 | case RPSM_EVENT_LOGO_IMP: |
894 | case RPSM_EVENT_LOGO_RCVD: | 913 | case RPSM_EVENT_LOGO_RCVD: |
914 | case RPSM_EVENT_PRLO_RCVD: | ||
895 | case RPSM_EVENT_ADDRESS_CHANGE: | 915 | case RPSM_EVENT_ADDRESS_CHANGE: |
896 | /** | 916 | /** |
897 | * rport is already going offline. | 917 | * rport is already going offline. |
@@ -951,6 +971,7 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, | |||
951 | 971 | ||
952 | case RPSM_EVENT_SCN: | 972 | case RPSM_EVENT_SCN: |
953 | case RPSM_EVENT_LOGO_RCVD: | 973 | case RPSM_EVENT_LOGO_RCVD: |
974 | case RPSM_EVENT_PRLO_RCVD: | ||
954 | /** | 975 | /** |
955 | * Ignore, already offline. | 976 | * Ignore, already offline. |
956 | */ | 977 | */ |
@@ -976,8 +997,11 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, | |||
976 | switch (event) { | 997 | switch (event) { |
977 | case RPSM_EVENT_HCB_OFFLINE: | 998 | case RPSM_EVENT_HCB_OFFLINE: |
978 | case RPSM_EVENT_ADDRESS_CHANGE: | 999 | case RPSM_EVENT_ADDRESS_CHANGE: |
979 | if (rport->pid) | 1000 | if (rport->pid && (rport->prlo == BFA_TRUE)) |
1001 | bfa_fcs_rport_send_prlo_acc(rport); | ||
1002 | if (rport->pid && (rport->prlo == BFA_FALSE)) | ||
980 | bfa_fcs_rport_send_logo_acc(rport); | 1003 | bfa_fcs_rport_send_logo_acc(rport); |
1004 | |||
981 | /* | 1005 | /* |
982 | * If the lport is online and if the rport is not a well known | 1006 | * If the lport is online and if the rport is not a well known |
983 | * address port, we try to re-discover the r-port. | 1007 | * address port, we try to re-discover the r-port. |
@@ -1011,6 +1035,7 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, | |||
1011 | break; | 1035 | break; |
1012 | 1036 | ||
1013 | case RPSM_EVENT_LOGO_RCVD: | 1037 | case RPSM_EVENT_LOGO_RCVD: |
1038 | case RPSM_EVENT_PRLO_RCVD: | ||
1014 | /** | 1039 | /** |
1015 | * Ignore - already processing a LOGO. | 1040 | * Ignore - already processing a LOGO. |
1016 | */ | 1041 | */ |
@@ -1040,6 +1065,7 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport, | |||
1040 | break; | 1065 | break; |
1041 | 1066 | ||
1042 | case RPSM_EVENT_LOGO_RCVD: | 1067 | case RPSM_EVENT_LOGO_RCVD: |
1068 | case RPSM_EVENT_PRLO_RCVD: | ||
1043 | case RPSM_EVENT_ADDRESS_CHANGE: | 1069 | case RPSM_EVENT_ADDRESS_CHANGE: |
1044 | break; | 1070 | break; |
1045 | 1071 | ||
@@ -1073,6 +1099,7 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport, | |||
1073 | break; | 1099 | break; |
1074 | 1100 | ||
1075 | case RPSM_EVENT_LOGO_RCVD: | 1101 | case RPSM_EVENT_LOGO_RCVD: |
1102 | case RPSM_EVENT_PRLO_RCVD: | ||
1076 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); | 1103 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); |
1077 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); | 1104 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); |
1078 | bfa_fcs_rport_free(rport); | 1105 | bfa_fcs_rport_free(rport); |
@@ -1121,6 +1148,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
1121 | break; | 1148 | break; |
1122 | 1149 | ||
1123 | case RPSM_EVENT_LOGO_RCVD: | 1150 | case RPSM_EVENT_LOGO_RCVD: |
1151 | case RPSM_EVENT_PRLO_RCVD: | ||
1124 | case RPSM_EVENT_LOGO_IMP: | 1152 | case RPSM_EVENT_LOGO_IMP: |
1125 | break; | 1153 | break; |
1126 | 1154 | ||
@@ -1172,6 +1200,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport, | |||
1172 | 1200 | ||
1173 | case RPSM_EVENT_SCN: | 1201 | case RPSM_EVENT_SCN: |
1174 | case RPSM_EVENT_LOGO_RCVD: | 1202 | case RPSM_EVENT_LOGO_RCVD: |
1203 | case RPSM_EVENT_PRLO_RCVD: | ||
1175 | case RPSM_EVENT_PLOGI_SEND: | 1204 | case RPSM_EVENT_PLOGI_SEND: |
1176 | break; | 1205 | break; |
1177 | 1206 | ||
@@ -1248,6 +1277,10 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport, | |||
1248 | bfa_fcs_rport_send_logo_acc(rport); | 1277 | bfa_fcs_rport_send_logo_acc(rport); |
1249 | break; | 1278 | break; |
1250 | 1279 | ||
1280 | case RPSM_EVENT_PRLO_RCVD: | ||
1281 | bfa_fcs_rport_send_prlo_acc(rport); | ||
1282 | break; | ||
1283 | |||
1251 | case RPSM_EVENT_PLOGI_COMP: | 1284 | case RPSM_EVENT_PLOGI_COMP: |
1252 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); | 1285 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); |
1253 | bfa_timer_stop(&rport->timer); | 1286 | bfa_timer_stop(&rport->timer); |
@@ -1320,6 +1353,10 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, | |||
1320 | bfa_fcs_rport_del_timeout); | 1353 | bfa_fcs_rport_del_timeout); |
1321 | break; | 1354 | break; |
1322 | 1355 | ||
1356 | case RPSM_EVENT_PRLO_RCVD: | ||
1357 | bfa_fcs_rport_send_prlo_acc(rport); | ||
1358 | break; | ||
1359 | |||
1323 | case RPSM_EVENT_SCN: | 1360 | case RPSM_EVENT_SCN: |
1324 | /** | 1361 | /** |
1325 | * ignore, wait for NS query response | 1362 | * ignore, wait for NS query response |
@@ -2182,6 +2219,7 @@ bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs) | |||
2182 | rport->reply_oxid = fchs->ox_id; | 2219 | rport->reply_oxid = fchs->ox_id; |
2183 | bfa_trc(rport->fcs, rport->reply_oxid); | 2220 | bfa_trc(rport->fcs, rport->reply_oxid); |
2184 | 2221 | ||
2222 | rport->prlo = BFA_FALSE; | ||
2185 | rport->stats.logo_rcvd++; | 2223 | rport->stats.logo_rcvd++; |
2186 | bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD); | 2224 | bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD); |
2187 | } | 2225 | } |
@@ -2551,6 +2589,30 @@ bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs, | |||
2551 | } | 2589 | } |
2552 | } | 2590 | } |
2553 | 2591 | ||
2592 | /* Send best case acc to prlo */ | ||
2593 | static void | ||
2594 | bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport) | ||
2595 | { | ||
2596 | struct bfa_fcs_port_s *port = rport->port; | ||
2597 | struct fchs_s fchs; | ||
2598 | struct bfa_fcxp_s *fcxp; | ||
2599 | int len; | ||
2600 | |||
2601 | bfa_trc(rport->fcs, rport->pid); | ||
2602 | |||
2603 | fcxp = bfa_fcs_fcxp_alloc(port->fcs); | ||
2604 | if (!fcxp) | ||
2605 | return; | ||
2606 | |||
2607 | len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), | ||
2608 | rport->pid, bfa_fcs_port_get_fcid(port), | ||
2609 | rport->reply_oxid, 0); | ||
2610 | |||
2611 | bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, | ||
2612 | port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, | ||
2613 | NULL, NULL, FC_MAX_PDUSZ, 0); | ||
2614 | } | ||
2615 | |||
2554 | /* | 2616 | /* |
2555 | * Send a LS reject | 2617 | * Send a LS reject |
2556 | */ | 2618 | */ |
@@ -2602,3 +2664,13 @@ bfa_fcs_rport_set_del_timeout(u8 rport_tmo) | |||
2602 | if (rport_tmo > 0) | 2664 | if (rport_tmo > 0) |
2603 | bfa_fcs_rport_del_timeout = rport_tmo * 1000; | 2665 | bfa_fcs_rport_del_timeout = rport_tmo * 1000; |
2604 | } | 2666 | } |
2667 | |||
2668 | void | ||
2669 | bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, uint16_t ox_id) | ||
2670 | { | ||
2671 | bfa_trc(rport->fcs, rport->pid); | ||
2672 | |||
2673 | rport->prlo = BFA_TRUE; | ||
2674 | rport->reply_oxid = ox_id; | ||
2675 | bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD); | ||
2676 | } | ||