aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa/rport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bfa/rport.c')
-rw-r--r--drivers/scsi/bfa/rport.c76
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);
94static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport, 94static 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);
96static 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
119static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, 121static 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 */
2593static void
2594bfa_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
2668void
2669bfa_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}