diff options
author | James Smart <james.smart@emulex.com> | 2010-02-12 14:41:27 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-02-17 18:40:29 -0500 |
commit | ecfd03c6a99ad98fea5cb75ec83cd9945adff8d9 (patch) | |
tree | 9c480ef51f00384e616a68c6a6fc8a8f4b7c8795 | |
parent | 1dfb5a47bc76c700969e41cdc2df6d1bf0adeb62 (diff) |
[SCSI] lpfc 8.3.9: Discovery changes to the lpfc driver.
- Add init_vpi mailbox command before re-registering VPI.
- Add Fast FCF failover support.
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 8 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 16 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 672 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 16 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 164 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 70 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 128 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 36 |
8 files changed, 821 insertions, 289 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 107899dc3f3e..a717f0be7120 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -78,6 +78,7 @@ void lpfc_set_disctmo(struct lpfc_vport *); | |||
78 | int lpfc_can_disctmo(struct lpfc_vport *); | 78 | int lpfc_can_disctmo(struct lpfc_vport *); |
79 | int lpfc_unreg_rpi(struct lpfc_vport *, struct lpfc_nodelist *); | 79 | int lpfc_unreg_rpi(struct lpfc_vport *, struct lpfc_nodelist *); |
80 | void lpfc_unreg_all_rpis(struct lpfc_vport *); | 80 | void lpfc_unreg_all_rpis(struct lpfc_vport *); |
81 | void lpfc_unreg_hba_rpis(struct lpfc_hba *); | ||
81 | void lpfc_unreg_default_rpis(struct lpfc_vport *); | 82 | void lpfc_unreg_default_rpis(struct lpfc_vport *); |
82 | void lpfc_issue_reg_vpi(struct lpfc_hba *, struct lpfc_vport *); | 83 | void lpfc_issue_reg_vpi(struct lpfc_hba *, struct lpfc_vport *); |
83 | 84 | ||
@@ -202,6 +203,7 @@ void lpfc_reg_fcfi(struct lpfc_hba *, struct lpfcMboxq *); | |||
202 | void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t); | 203 | void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t); |
203 | void lpfc_resume_rpi(struct lpfcMboxq *, struct lpfc_nodelist *); | 204 | void lpfc_resume_rpi(struct lpfcMboxq *, struct lpfc_nodelist *); |
204 | int lpfc_check_pending_fcoe_event(struct lpfc_hba *, uint8_t); | 205 | int lpfc_check_pending_fcoe_event(struct lpfc_hba *, uint8_t); |
206 | void lpfc_issue_init_vpi(struct lpfc_vport *); | ||
205 | 207 | ||
206 | void lpfc_config_hbq(struct lpfc_hba *, uint32_t, struct lpfc_hbq_init *, | 208 | void lpfc_config_hbq(struct lpfc_hba *, uint32_t, struct lpfc_hbq_init *, |
207 | uint32_t , LPFC_MBOXQ_t *); | 209 | uint32_t , LPFC_MBOXQ_t *); |
@@ -211,7 +213,11 @@ struct hbq_dmabuf *lpfc_sli4_rb_alloc(struct lpfc_hba *); | |||
211 | void lpfc_sli4_rb_free(struct lpfc_hba *, struct hbq_dmabuf *); | 213 | void lpfc_sli4_rb_free(struct lpfc_hba *, struct hbq_dmabuf *); |
212 | void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *, | 214 | void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *, |
213 | uint16_t); | 215 | uint16_t); |
216 | void lpfc_unregister_fcf(struct lpfc_hba *); | ||
217 | void lpfc_unregister_fcf_rescan(struct lpfc_hba *); | ||
214 | void lpfc_unregister_unused_fcf(struct lpfc_hba *); | 218 | void lpfc_unregister_unused_fcf(struct lpfc_hba *); |
219 | int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *); | ||
220 | void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *); | ||
215 | 221 | ||
216 | int lpfc_mem_alloc(struct lpfc_hba *, int align); | 222 | int lpfc_mem_alloc(struct lpfc_hba *, int align); |
217 | void lpfc_mem_free(struct lpfc_hba *); | 223 | void lpfc_mem_free(struct lpfc_hba *); |
@@ -370,6 +376,8 @@ void lpfc_free_fast_evt(struct lpfc_hba *, struct lpfc_fast_path_event *); | |||
370 | void lpfc_create_static_vport(struct lpfc_hba *); | 376 | void lpfc_create_static_vport(struct lpfc_hba *); |
371 | void lpfc_stop_hba_timers(struct lpfc_hba *); | 377 | void lpfc_stop_hba_timers(struct lpfc_hba *); |
372 | void lpfc_stop_port(struct lpfc_hba *); | 378 | void lpfc_stop_port(struct lpfc_hba *); |
379 | void __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *); | ||
380 | void lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *); | ||
373 | void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t); | 381 | void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t); |
374 | int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); | 382 | int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); |
375 | void lpfc_start_fdiscs(struct lpfc_hba *phba); | 383 | void lpfc_start_fdiscs(struct lpfc_hba *phba); |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 2c62349a1041..08b6634cb994 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -589,6 +589,15 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
589 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 589 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
590 | spin_unlock_irq(shost->host_lock); | 590 | spin_unlock_irq(shost->host_lock); |
591 | } | 591 | } |
592 | /* | ||
593 | * If VPI is unreged, driver need to do INIT_VPI | ||
594 | * before re-registering | ||
595 | */ | ||
596 | if (phba->sli_rev == LPFC_SLI_REV4) { | ||
597 | spin_lock_irq(shost->host_lock); | ||
598 | vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | ||
599 | spin_unlock_irq(shost->host_lock); | ||
600 | } | ||
592 | } | 601 | } |
593 | 602 | ||
594 | if (phba->sli_rev < LPFC_SLI_REV4) { | 603 | if (phba->sli_rev < LPFC_SLI_REV4) { |
@@ -606,7 +615,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
606 | lpfc_start_fdiscs(phba); | 615 | lpfc_start_fdiscs(phba); |
607 | lpfc_do_scr_ns_plogi(phba, vport); | 616 | lpfc_do_scr_ns_plogi(phba, vport); |
608 | } else if (vport->fc_flag & FC_VFI_REGISTERED) | 617 | } else if (vport->fc_flag & FC_VFI_REGISTERED) |
609 | lpfc_register_new_vport(phba, vport, ndlp); | 618 | lpfc_issue_init_vpi(vport); |
610 | else | 619 | else |
611 | lpfc_issue_reg_vfi(vport); | 620 | lpfc_issue_reg_vfi(vport); |
612 | } | 621 | } |
@@ -6210,10 +6219,13 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
6210 | lpfc_mbx_unreg_vpi(vport); | 6219 | lpfc_mbx_unreg_vpi(vport); |
6211 | spin_lock_irq(shost->host_lock); | 6220 | spin_lock_irq(shost->host_lock); |
6212 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 6221 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
6222 | vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | ||
6213 | spin_unlock_irq(shost->host_lock); | 6223 | spin_unlock_irq(shost->host_lock); |
6214 | } | 6224 | } |
6215 | 6225 | ||
6216 | if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) | 6226 | if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI) |
6227 | lpfc_issue_init_vpi(vport); | ||
6228 | else if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) | ||
6217 | lpfc_register_new_vport(phba, vport, ndlp); | 6229 | lpfc_register_new_vport(phba, vport, ndlp); |
6218 | else | 6230 | else |
6219 | lpfc_do_scr_ns_plogi(phba, vport); | 6231 | lpfc_do_scr_ns_plogi(phba, vport); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 7143d71c501f..b890e2dc15db 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -525,6 +525,8 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
525 | spin_unlock_irq(&phba->hbalock); | 525 | spin_unlock_irq(&phba->hbalock); |
526 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); | 526 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); |
527 | } | 527 | } |
528 | if (phba->fcf.fcf_flag & FCF_REDISC_EVT) | ||
529 | lpfc_sli4_fcf_redisc_event_proc(phba); | ||
528 | } | 530 | } |
529 | 531 | ||
530 | vports = lpfc_create_vport_work_array(phba); | 532 | vports = lpfc_create_vport_work_array(phba); |
@@ -754,7 +756,7 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
754 | lpfc_scsi_dev_block(phba); | 756 | lpfc_scsi_dev_block(phba); |
755 | 757 | ||
756 | spin_lock_irq(&phba->hbalock); | 758 | spin_lock_irq(&phba->hbalock); |
757 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); | 759 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_SCAN_DONE); |
758 | if (phba->link_state > LPFC_LINK_DOWN) { | 760 | if (phba->link_state > LPFC_LINK_DOWN) { |
759 | phba->link_state = LPFC_LINK_DOWN; | 761 | phba->link_state = LPFC_LINK_DOWN; |
760 | phba->pport->fc_flag &= ~FC_LBIT; | 762 | phba->pport->fc_flag &= ~FC_LBIT; |
@@ -1025,7 +1027,7 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1025 | return; | 1027 | return; |
1026 | } | 1028 | } |
1027 | spin_lock_irqsave(&phba->hbalock, flags); | 1029 | spin_lock_irqsave(&phba->hbalock, flags); |
1028 | phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); | 1030 | phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE); |
1029 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1031 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
1030 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1032 | spin_unlock_irqrestore(&phba->hbalock, flags); |
1031 | if (vport->port_state != LPFC_FLOGI) | 1033 | if (vport->port_state != LPFC_FLOGI) |
@@ -1047,25 +1049,23 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1047 | static uint32_t | 1049 | static uint32_t |
1048 | lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record) | 1050 | lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record) |
1049 | { | 1051 | { |
1050 | if ((fab_name[0] == | 1052 | if (fab_name[0] != bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record)) |
1051 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record)) && | 1053 | return 0; |
1052 | (fab_name[1] == | 1054 | if (fab_name[1] != bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record)) |
1053 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record)) && | 1055 | return 0; |
1054 | (fab_name[2] == | 1056 | if (fab_name[2] != bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record)) |
1055 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record)) && | 1057 | return 0; |
1056 | (fab_name[3] == | 1058 | if (fab_name[3] != bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record)) |
1057 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record)) && | 1059 | return 0; |
1058 | (fab_name[4] == | 1060 | if (fab_name[4] != bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record)) |
1059 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record)) && | 1061 | return 0; |
1060 | (fab_name[5] == | 1062 | if (fab_name[5] != bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record)) |
1061 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record)) && | ||
1062 | (fab_name[6] == | ||
1063 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record)) && | ||
1064 | (fab_name[7] == | ||
1065 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record))) | ||
1066 | return 1; | ||
1067 | else | ||
1068 | return 0; | 1063 | return 0; |
1064 | if (fab_name[6] != bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record)) | ||
1065 | return 0; | ||
1066 | if (fab_name[7] != bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record)) | ||
1067 | return 0; | ||
1068 | return 1; | ||
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | /** | 1071 | /** |
@@ -1080,30 +1080,28 @@ lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record) | |||
1080 | static uint32_t | 1080 | static uint32_t |
1081 | lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record) | 1081 | lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record) |
1082 | { | 1082 | { |
1083 | if ((sw_name[0] == | 1083 | if (sw_name[0] != bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record)) |
1084 | bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record)) && | 1084 | return 0; |
1085 | (sw_name[1] == | 1085 | if (sw_name[1] != bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record)) |
1086 | bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record)) && | 1086 | return 0; |
1087 | (sw_name[2] == | 1087 | if (sw_name[2] != bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record)) |
1088 | bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record)) && | ||
1089 | (sw_name[3] == | ||
1090 | bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record)) && | ||
1091 | (sw_name[4] == | ||
1092 | bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record)) && | ||
1093 | (sw_name[5] == | ||
1094 | bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record)) && | ||
1095 | (sw_name[6] == | ||
1096 | bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record)) && | ||
1097 | (sw_name[7] == | ||
1098 | bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record))) | ||
1099 | return 1; | ||
1100 | else | ||
1101 | return 0; | 1088 | return 0; |
1089 | if (sw_name[3] != bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record)) | ||
1090 | return 0; | ||
1091 | if (sw_name[4] != bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record)) | ||
1092 | return 0; | ||
1093 | if (sw_name[5] != bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record)) | ||
1094 | return 0; | ||
1095 | if (sw_name[6] != bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record)) | ||
1096 | return 0; | ||
1097 | if (sw_name[7] != bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record)) | ||
1098 | return 0; | ||
1099 | return 1; | ||
1102 | } | 1100 | } |
1103 | 1101 | ||
1104 | /** | 1102 | /** |
1105 | * lpfc_mac_addr_match - Check if the fcf mac address match. | 1103 | * lpfc_mac_addr_match - Check if the fcf mac address match. |
1106 | * @phba: pointer to lpfc hba data structure. | 1104 | * @mac_addr: pointer to mac address. |
1107 | * @new_fcf_record: pointer to fcf record. | 1105 | * @new_fcf_record: pointer to fcf record. |
1108 | * | 1106 | * |
1109 | * This routine compare the fcf record's mac address with HBA's | 1107 | * This routine compare the fcf record's mac address with HBA's |
@@ -1111,85 +1109,115 @@ lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record) | |||
1111 | * returns 1 else return 0. | 1109 | * returns 1 else return 0. |
1112 | **/ | 1110 | **/ |
1113 | static uint32_t | 1111 | static uint32_t |
1114 | lpfc_mac_addr_match(struct lpfc_hba *phba, struct fcf_record *new_fcf_record) | 1112 | lpfc_mac_addr_match(uint8_t *mac_addr, struct fcf_record *new_fcf_record) |
1115 | { | 1113 | { |
1116 | if ((phba->fcf.mac_addr[0] == | 1114 | if (mac_addr[0] != bf_get(lpfc_fcf_record_mac_0, new_fcf_record)) |
1117 | bf_get(lpfc_fcf_record_mac_0, new_fcf_record)) && | 1115 | return 0; |
1118 | (phba->fcf.mac_addr[1] == | 1116 | if (mac_addr[1] != bf_get(lpfc_fcf_record_mac_1, new_fcf_record)) |
1119 | bf_get(lpfc_fcf_record_mac_1, new_fcf_record)) && | 1117 | return 0; |
1120 | (phba->fcf.mac_addr[2] == | 1118 | if (mac_addr[2] != bf_get(lpfc_fcf_record_mac_2, new_fcf_record)) |
1121 | bf_get(lpfc_fcf_record_mac_2, new_fcf_record)) && | 1119 | return 0; |
1122 | (phba->fcf.mac_addr[3] == | 1120 | if (mac_addr[3] != bf_get(lpfc_fcf_record_mac_3, new_fcf_record)) |
1123 | bf_get(lpfc_fcf_record_mac_3, new_fcf_record)) && | 1121 | return 0; |
1124 | (phba->fcf.mac_addr[4] == | 1122 | if (mac_addr[4] != bf_get(lpfc_fcf_record_mac_4, new_fcf_record)) |
1125 | bf_get(lpfc_fcf_record_mac_4, new_fcf_record)) && | 1123 | return 0; |
1126 | (phba->fcf.mac_addr[5] == | 1124 | if (mac_addr[5] != bf_get(lpfc_fcf_record_mac_5, new_fcf_record)) |
1127 | bf_get(lpfc_fcf_record_mac_5, new_fcf_record))) | ||
1128 | return 1; | ||
1129 | else | ||
1130 | return 0; | 1125 | return 0; |
1126 | return 1; | ||
1127 | } | ||
1128 | |||
1129 | static bool | ||
1130 | lpfc_vlan_id_match(uint16_t curr_vlan_id, uint16_t new_vlan_id) | ||
1131 | { | ||
1132 | return (curr_vlan_id == new_vlan_id); | ||
1131 | } | 1133 | } |
1132 | 1134 | ||
1133 | /** | 1135 | /** |
1134 | * lpfc_copy_fcf_record - Copy fcf information to lpfc_hba. | 1136 | * lpfc_copy_fcf_record - Copy fcf information to lpfc_hba. |
1135 | * @phba: pointer to lpfc hba data structure. | 1137 | * @fcf: pointer to driver fcf record. |
1136 | * @new_fcf_record: pointer to fcf record. | 1138 | * @new_fcf_record: pointer to fcf record. |
1137 | * | 1139 | * |
1138 | * This routine copies the FCF information from the FCF | 1140 | * This routine copies the FCF information from the FCF |
1139 | * record to lpfc_hba data structure. | 1141 | * record to lpfc_hba data structure. |
1140 | **/ | 1142 | **/ |
1141 | static void | 1143 | static void |
1142 | lpfc_copy_fcf_record(struct lpfc_hba *phba, struct fcf_record *new_fcf_record) | 1144 | lpfc_copy_fcf_record(struct lpfc_fcf_rec *fcf_rec, |
1145 | struct fcf_record *new_fcf_record) | ||
1143 | { | 1146 | { |
1144 | phba->fcf.fabric_name[0] = | 1147 | /* Fabric name */ |
1148 | fcf_rec->fabric_name[0] = | ||
1145 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record); | 1149 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record); |
1146 | phba->fcf.fabric_name[1] = | 1150 | fcf_rec->fabric_name[1] = |
1147 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record); | 1151 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record); |
1148 | phba->fcf.fabric_name[2] = | 1152 | fcf_rec->fabric_name[2] = |
1149 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record); | 1153 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record); |
1150 | phba->fcf.fabric_name[3] = | 1154 | fcf_rec->fabric_name[3] = |
1151 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record); | 1155 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record); |
1152 | phba->fcf.fabric_name[4] = | 1156 | fcf_rec->fabric_name[4] = |
1153 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record); | 1157 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record); |
1154 | phba->fcf.fabric_name[5] = | 1158 | fcf_rec->fabric_name[5] = |
1155 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record); | 1159 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record); |
1156 | phba->fcf.fabric_name[6] = | 1160 | fcf_rec->fabric_name[6] = |
1157 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record); | 1161 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record); |
1158 | phba->fcf.fabric_name[7] = | 1162 | fcf_rec->fabric_name[7] = |
1159 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record); | 1163 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record); |
1160 | phba->fcf.mac_addr[0] = | 1164 | /* Mac address */ |
1161 | bf_get(lpfc_fcf_record_mac_0, new_fcf_record); | 1165 | fcf_rec->mac_addr[0] = bf_get(lpfc_fcf_record_mac_0, new_fcf_record); |
1162 | phba->fcf.mac_addr[1] = | 1166 | fcf_rec->mac_addr[1] = bf_get(lpfc_fcf_record_mac_1, new_fcf_record); |
1163 | bf_get(lpfc_fcf_record_mac_1, new_fcf_record); | 1167 | fcf_rec->mac_addr[2] = bf_get(lpfc_fcf_record_mac_2, new_fcf_record); |
1164 | phba->fcf.mac_addr[2] = | 1168 | fcf_rec->mac_addr[3] = bf_get(lpfc_fcf_record_mac_3, new_fcf_record); |
1165 | bf_get(lpfc_fcf_record_mac_2, new_fcf_record); | 1169 | fcf_rec->mac_addr[4] = bf_get(lpfc_fcf_record_mac_4, new_fcf_record); |
1166 | phba->fcf.mac_addr[3] = | 1170 | fcf_rec->mac_addr[5] = bf_get(lpfc_fcf_record_mac_5, new_fcf_record); |
1167 | bf_get(lpfc_fcf_record_mac_3, new_fcf_record); | 1171 | /* FCF record index */ |
1168 | phba->fcf.mac_addr[4] = | 1172 | fcf_rec->fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); |
1169 | bf_get(lpfc_fcf_record_mac_4, new_fcf_record); | 1173 | /* FCF record priority */ |
1170 | phba->fcf.mac_addr[5] = | 1174 | fcf_rec->priority = new_fcf_record->fip_priority; |
1171 | bf_get(lpfc_fcf_record_mac_5, new_fcf_record); | 1175 | /* Switch name */ |
1172 | phba->fcf.fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); | 1176 | fcf_rec->switch_name[0] = |
1173 | phba->fcf.priority = new_fcf_record->fip_priority; | ||
1174 | phba->fcf.switch_name[0] = | ||
1175 | bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record); | 1177 | bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record); |
1176 | phba->fcf.switch_name[1] = | 1178 | fcf_rec->switch_name[1] = |
1177 | bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record); | 1179 | bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record); |
1178 | phba->fcf.switch_name[2] = | 1180 | fcf_rec->switch_name[2] = |
1179 | bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record); | 1181 | bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record); |
1180 | phba->fcf.switch_name[3] = | 1182 | fcf_rec->switch_name[3] = |
1181 | bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record); | 1183 | bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record); |
1182 | phba->fcf.switch_name[4] = | 1184 | fcf_rec->switch_name[4] = |
1183 | bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record); | 1185 | bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record); |
1184 | phba->fcf.switch_name[5] = | 1186 | fcf_rec->switch_name[5] = |
1185 | bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record); | 1187 | bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record); |
1186 | phba->fcf.switch_name[6] = | 1188 | fcf_rec->switch_name[6] = |
1187 | bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record); | 1189 | bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record); |
1188 | phba->fcf.switch_name[7] = | 1190 | fcf_rec->switch_name[7] = |
1189 | bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record); | 1191 | bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record); |
1190 | } | 1192 | } |
1191 | 1193 | ||
1192 | /** | 1194 | /** |
1195 | * lpfc_update_fcf_record - Update driver fcf record | ||
1196 | * @phba: pointer to lpfc hba data structure. | ||
1197 | * @fcf_rec: pointer to driver fcf record. | ||
1198 | * @new_fcf_record: pointer to hba fcf record. | ||
1199 | * @addr_mode: address mode to be set to the driver fcf record. | ||
1200 | * @vlan_id: vlan tag to be set to the driver fcf record. | ||
1201 | * @flag: flag bits to be set to the driver fcf record. | ||
1202 | * | ||
1203 | * This routine updates the driver FCF record from the new HBA FCF record | ||
1204 | * together with the address mode, vlan_id, and other informations. This | ||
1205 | * routine is called with the host lock held. | ||
1206 | **/ | ||
1207 | static void | ||
1208 | __lpfc_update_fcf_record(struct lpfc_hba *phba, struct lpfc_fcf_rec *fcf_rec, | ||
1209 | struct fcf_record *new_fcf_record, uint32_t addr_mode, | ||
1210 | uint16_t vlan_id, uint32_t flag) | ||
1211 | { | ||
1212 | /* Copy the fields from the HBA's FCF record */ | ||
1213 | lpfc_copy_fcf_record(fcf_rec, new_fcf_record); | ||
1214 | /* Update other fields of driver FCF record */ | ||
1215 | fcf_rec->addr_mode = addr_mode; | ||
1216 | fcf_rec->vlan_id = vlan_id; | ||
1217 | fcf_rec->flag |= (flag | RECORD_VALID); | ||
1218 | } | ||
1219 | |||
1220 | /** | ||
1193 | * lpfc_register_fcf - Register the FCF with hba. | 1221 | * lpfc_register_fcf - Register the FCF with hba. |
1194 | * @phba: pointer to lpfc hba data structure. | 1222 | * @phba: pointer to lpfc hba data structure. |
1195 | * | 1223 | * |
@@ -1214,7 +1242,7 @@ lpfc_register_fcf(struct lpfc_hba *phba) | |||
1214 | 1242 | ||
1215 | /* The FCF is already registered, start discovery */ | 1243 | /* The FCF is already registered, start discovery */ |
1216 | if (phba->fcf.fcf_flag & FCF_REGISTERED) { | 1244 | if (phba->fcf.fcf_flag & FCF_REGISTERED) { |
1217 | phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); | 1245 | phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE); |
1218 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1246 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
1219 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1247 | spin_unlock_irqrestore(&phba->hbalock, flags); |
1220 | if (phba->pport->port_state != LPFC_FLOGI) | 1248 | if (phba->pport->port_state != LPFC_FLOGI) |
@@ -1252,6 +1280,7 @@ lpfc_register_fcf(struct lpfc_hba *phba) | |||
1252 | * @new_fcf_record: pointer to fcf record. | 1280 | * @new_fcf_record: pointer to fcf record. |
1253 | * @boot_flag: Indicates if this record used by boot bios. | 1281 | * @boot_flag: Indicates if this record used by boot bios. |
1254 | * @addr_mode: The address mode to be used by this FCF | 1282 | * @addr_mode: The address mode to be used by this FCF |
1283 | * @vlan_id: The vlan id to be used as vlan tagging by this FCF. | ||
1255 | * | 1284 | * |
1256 | * This routine compare the fcf record with connect list obtained from the | 1285 | * This routine compare the fcf record with connect list obtained from the |
1257 | * config region to decide if this FCF can be used for SAN discovery. It returns | 1286 | * config region to decide if this FCF can be used for SAN discovery. It returns |
@@ -1325,7 +1354,8 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba, | |||
1325 | return 1; | 1354 | return 1; |
1326 | } | 1355 | } |
1327 | 1356 | ||
1328 | list_for_each_entry(conn_entry, &phba->fcf_conn_rec_list, list) { | 1357 | list_for_each_entry(conn_entry, |
1358 | &phba->fcf_conn_rec_list, list) { | ||
1329 | if (!(conn_entry->conn_rec.flags & FCFCNCT_VALID)) | 1359 | if (!(conn_entry->conn_rec.flags & FCFCNCT_VALID)) |
1330 | continue; | 1360 | continue; |
1331 | 1361 | ||
@@ -1472,6 +1502,7 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) | |||
1472 | */ | 1502 | */ |
1473 | spin_lock_irq(&phba->hbalock); | 1503 | spin_lock_irq(&phba->hbalock); |
1474 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1504 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
1505 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | ||
1475 | spin_unlock_irq(&phba->hbalock); | 1506 | spin_unlock_irq(&phba->hbalock); |
1476 | } | 1507 | } |
1477 | 1508 | ||
@@ -1526,11 +1557,12 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1526 | uint32_t shdr_status, shdr_add_status; | 1557 | uint32_t shdr_status, shdr_add_status; |
1527 | union lpfc_sli4_cfg_shdr *shdr; | 1558 | union lpfc_sli4_cfg_shdr *shdr; |
1528 | struct fcf_record *new_fcf_record; | 1559 | struct fcf_record *new_fcf_record; |
1529 | int rc; | ||
1530 | uint32_t boot_flag, addr_mode; | 1560 | uint32_t boot_flag, addr_mode; |
1531 | uint32_t next_fcf_index; | 1561 | uint32_t next_fcf_index; |
1532 | unsigned long flags; | 1562 | struct lpfc_fcf_rec *fcf_rec = NULL; |
1563 | unsigned long iflags; | ||
1533 | uint16_t vlan_id; | 1564 | uint16_t vlan_id; |
1565 | int rc; | ||
1534 | 1566 | ||
1535 | /* If there is pending FCoE event restart FCF table scan */ | 1567 | /* If there is pending FCoE event restart FCF table scan */ |
1536 | if (lpfc_check_pending_fcoe_event(phba, 0)) { | 1568 | if (lpfc_check_pending_fcoe_event(phba, 0)) { |
@@ -1585,9 +1617,8 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1585 | sizeof(struct fcf_record)); | 1617 | sizeof(struct fcf_record)); |
1586 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | 1618 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); |
1587 | 1619 | ||
1588 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, | 1620 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, |
1589 | &boot_flag, &addr_mode, | 1621 | &addr_mode, &vlan_id); |
1590 | &vlan_id); | ||
1591 | /* | 1622 | /* |
1592 | * If the fcf record does not match with connect list entries | 1623 | * If the fcf record does not match with connect list entries |
1593 | * read the next entry. | 1624 | * read the next entry. |
@@ -1596,90 +1627,159 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1596 | goto read_next_fcf; | 1627 | goto read_next_fcf; |
1597 | /* | 1628 | /* |
1598 | * If this is not the first FCF discovery of the HBA, use last | 1629 | * If this is not the first FCF discovery of the HBA, use last |
1599 | * FCF record for the discovery. | 1630 | * FCF record for the discovery. The condition that a rescan |
1631 | * matches the in-use FCF record: fabric name, switch name, mac | ||
1632 | * address, and vlan_id. | ||
1600 | */ | 1633 | */ |
1601 | spin_lock_irqsave(&phba->hbalock, flags); | 1634 | spin_lock_irqsave(&phba->hbalock, iflags); |
1602 | if (phba->fcf.fcf_flag & FCF_IN_USE) { | 1635 | if (phba->fcf.fcf_flag & FCF_IN_USE) { |
1603 | if (lpfc_fab_name_match(phba->fcf.fabric_name, | 1636 | if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, |
1604 | new_fcf_record) && | 1637 | new_fcf_record) && |
1605 | lpfc_sw_name_match(phba->fcf.switch_name, | 1638 | lpfc_sw_name_match(phba->fcf.current_rec.switch_name, |
1606 | new_fcf_record) && | 1639 | new_fcf_record) && |
1607 | lpfc_mac_addr_match(phba, new_fcf_record)) { | 1640 | lpfc_mac_addr_match(phba->fcf.current_rec.mac_addr, |
1641 | new_fcf_record) && | ||
1642 | lpfc_vlan_id_match(phba->fcf.current_rec.vlan_id, | ||
1643 | vlan_id)) { | ||
1608 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | 1644 | phba->fcf.fcf_flag |= FCF_AVAILABLE; |
1609 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1645 | if (phba->fcf.fcf_flag & FCF_REDISC_PEND) |
1646 | /* Stop FCF redisc wait timer if pending */ | ||
1647 | __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); | ||
1648 | else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) | ||
1649 | /* If in fast failover, mark it's completed */ | ||
1650 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | ||
1651 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1610 | goto out; | 1652 | goto out; |
1611 | } | 1653 | } |
1612 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1654 | /* |
1613 | goto read_next_fcf; | 1655 | * Read next FCF record from HBA searching for the matching |
1656 | * with in-use record only if not during the fast failover | ||
1657 | * period. In case of fast failover period, it shall try to | ||
1658 | * determine whether the FCF record just read should be the | ||
1659 | * next candidate. | ||
1660 | */ | ||
1661 | if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { | ||
1662 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1663 | goto read_next_fcf; | ||
1664 | } | ||
1614 | } | 1665 | } |
1666 | /* | ||
1667 | * Update on failover FCF record only if it's in FCF fast-failover | ||
1668 | * period; otherwise, update on current FCF record. | ||
1669 | */ | ||
1670 | if (phba->fcf.fcf_flag & FCF_REDISC_FOV) { | ||
1671 | /* Fast FCF failover only to the same fabric name */ | ||
1672 | if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, | ||
1673 | new_fcf_record)) | ||
1674 | fcf_rec = &phba->fcf.failover_rec; | ||
1675 | else | ||
1676 | goto read_next_fcf; | ||
1677 | } else | ||
1678 | fcf_rec = &phba->fcf.current_rec; | ||
1679 | |||
1615 | if (phba->fcf.fcf_flag & FCF_AVAILABLE) { | 1680 | if (phba->fcf.fcf_flag & FCF_AVAILABLE) { |
1616 | /* | 1681 | /* |
1617 | * If the current FCF record does not have boot flag | 1682 | * If the driver FCF record does not have boot flag |
1618 | * set and new fcf record has boot flag set, use the | 1683 | * set and new hba fcf record has boot flag set, use |
1619 | * new fcf record. | 1684 | * the new hba fcf record. |
1620 | */ | 1685 | */ |
1621 | if (boot_flag && !(phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | 1686 | if (boot_flag && !(fcf_rec->flag & BOOT_ENABLE)) { |
1622 | /* Use this FCF record */ | 1687 | /* Choose this FCF record */ |
1623 | lpfc_copy_fcf_record(phba, new_fcf_record); | 1688 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1624 | phba->fcf.addr_mode = addr_mode; | 1689 | addr_mode, vlan_id, BOOT_ENABLE); |
1625 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | 1690 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
1626 | if (vlan_id != 0xFFFF) { | ||
1627 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1628 | phba->fcf.vlan_id = vlan_id; | ||
1629 | } | ||
1630 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1631 | goto read_next_fcf; | 1691 | goto read_next_fcf; |
1632 | } | 1692 | } |
1633 | /* | 1693 | /* |
1634 | * If the current FCF record has boot flag set and the | 1694 | * If the driver FCF record has boot flag set and the |
1635 | * new FCF record does not have boot flag, read the next | 1695 | * new hba FCF record does not have boot flag, read |
1636 | * FCF record. | 1696 | * the next FCF record. |
1637 | */ | 1697 | */ |
1638 | if (!boot_flag && (phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | 1698 | if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) { |
1639 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1699 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
1640 | goto read_next_fcf; | 1700 | goto read_next_fcf; |
1641 | } | 1701 | } |
1642 | /* | 1702 | /* |
1643 | * If there is a record with lower priority value for | 1703 | * If the new hba FCF record has lower priority value |
1644 | * the current FCF, use that record. | 1704 | * than the driver FCF record, use the new record. |
1645 | */ | 1705 | */ |
1646 | if (lpfc_fab_name_match(phba->fcf.fabric_name, | 1706 | if (lpfc_fab_name_match(fcf_rec->fabric_name, new_fcf_record) && |
1647 | new_fcf_record) && | 1707 | (new_fcf_record->fip_priority < fcf_rec->priority)) { |
1648 | (new_fcf_record->fip_priority < phba->fcf.priority)) { | 1708 | /* Choose this FCF record */ |
1649 | /* Use this FCF record */ | 1709 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1650 | lpfc_copy_fcf_record(phba, new_fcf_record); | 1710 | addr_mode, vlan_id, 0); |
1651 | phba->fcf.addr_mode = addr_mode; | ||
1652 | if (vlan_id != 0xFFFF) { | ||
1653 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1654 | phba->fcf.vlan_id = vlan_id; | ||
1655 | } | ||
1656 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1657 | goto read_next_fcf; | ||
1658 | } | 1711 | } |
1659 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1712 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
1660 | goto read_next_fcf; | 1713 | goto read_next_fcf; |
1661 | } | 1714 | } |
1662 | /* | 1715 | /* |
1663 | * This is the first available FCF record, use this | 1716 | * This is the first suitable FCF record, choose this record for |
1664 | * record. | 1717 | * initial best-fit FCF. |
1665 | */ | 1718 | */ |
1666 | lpfc_copy_fcf_record(phba, new_fcf_record); | 1719 | if (fcf_rec) { |
1667 | phba->fcf.addr_mode = addr_mode; | 1720 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1668 | if (boot_flag) | 1721 | addr_mode, vlan_id, (boot_flag ? |
1669 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | 1722 | BOOT_ENABLE : 0)); |
1670 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | 1723 | phba->fcf.fcf_flag |= FCF_AVAILABLE; |
1671 | if (vlan_id != 0xFFFF) { | ||
1672 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1673 | phba->fcf.vlan_id = vlan_id; | ||
1674 | } | 1724 | } |
1675 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1725 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
1676 | goto read_next_fcf; | 1726 | goto read_next_fcf; |
1677 | 1727 | ||
1678 | read_next_fcf: | 1728 | read_next_fcf: |
1679 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | 1729 | lpfc_sli4_mbox_cmd_free(phba, mboxq); |
1680 | if (next_fcf_index == LPFC_FCOE_FCF_NEXT_NONE || next_fcf_index == 0) | 1730 | if (next_fcf_index == LPFC_FCOE_FCF_NEXT_NONE || next_fcf_index == 0) { |
1681 | lpfc_register_fcf(phba); | 1731 | if (phba->fcf.fcf_flag & FCF_REDISC_FOV) { |
1682 | else | 1732 | /* |
1733 | * Case of FCF fast failover scan | ||
1734 | */ | ||
1735 | |||
1736 | /* | ||
1737 | * It has not found any suitable FCF record, cancel | ||
1738 | * FCF scan inprogress, and do nothing | ||
1739 | */ | ||
1740 | if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) { | ||
1741 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
1742 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | ||
1743 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1744 | return; | ||
1745 | } | ||
1746 | /* | ||
1747 | * It has found a suitable FCF record that is not | ||
1748 | * the same as in-use FCF record, unregister the | ||
1749 | * in-use FCF record, replace the in-use FCF record | ||
1750 | * with the new FCF record, mark FCF fast failover | ||
1751 | * completed, and then start register the new FCF | ||
1752 | * record. | ||
1753 | */ | ||
1754 | |||
1755 | /* unregister the current in-use FCF record */ | ||
1756 | lpfc_unregister_fcf(phba); | ||
1757 | /* replace in-use record with the new record */ | ||
1758 | memcpy(&phba->fcf.current_rec, | ||
1759 | &phba->fcf.failover_rec, | ||
1760 | sizeof(struct lpfc_fcf_rec)); | ||
1761 | /* mark the FCF fast failover completed */ | ||
1762 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
1763 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | ||
1764 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1765 | /* Register to the new FCF record */ | ||
1766 | lpfc_register_fcf(phba); | ||
1767 | } else { | ||
1768 | /* | ||
1769 | * In case of transaction period to fast FCF failover, | ||
1770 | * do nothing when search to the end of the FCF table. | ||
1771 | */ | ||
1772 | if ((phba->fcf.fcf_flag & FCF_REDISC_EVT) || | ||
1773 | (phba->fcf.fcf_flag & FCF_REDISC_PEND)) | ||
1774 | return; | ||
1775 | /* | ||
1776 | * Otherwise, initial scan or post linkdown rescan, | ||
1777 | * register with the best fit FCF record found so | ||
1778 | * far through the scanning process. | ||
1779 | */ | ||
1780 | lpfc_register_fcf(phba); | ||
1781 | } | ||
1782 | } else | ||
1683 | lpfc_sli4_read_fcf_record(phba, next_fcf_index); | 1783 | lpfc_sli4_read_fcf_record(phba, next_fcf_index); |
1684 | return; | 1784 | return; |
1685 | 1785 | ||
@@ -1741,6 +1841,37 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1741 | } | 1841 | } |
1742 | 1842 | ||
1743 | /** | 1843 | /** |
1844 | * lpfc_issue_init_vpi - Issue init_vpi mailbox command. | ||
1845 | * @vport: pointer to lpfc_vport data structure. | ||
1846 | * | ||
1847 | * This function issue a init_vpi mailbox command to initialize | ||
1848 | * VPI for the vport. | ||
1849 | */ | ||
1850 | void | ||
1851 | lpfc_issue_init_vpi(struct lpfc_vport *vport) | ||
1852 | { | ||
1853 | LPFC_MBOXQ_t *mboxq; | ||
1854 | int rc; | ||
1855 | |||
1856 | mboxq = mempool_alloc(vport->phba->mbox_mem_pool, GFP_KERNEL); | ||
1857 | if (!mboxq) { | ||
1858 | lpfc_printf_vlog(vport, KERN_ERR, | ||
1859 | LOG_MBOX, "2607 Failed to allocate " | ||
1860 | "init_vpi mailbox\n"); | ||
1861 | return; | ||
1862 | } | ||
1863 | lpfc_init_vpi(vport->phba, mboxq, vport->vpi); | ||
1864 | mboxq->vport = vport; | ||
1865 | mboxq->mbox_cmpl = lpfc_init_vpi_cmpl; | ||
1866 | rc = lpfc_sli_issue_mbox(vport->phba, mboxq, MBX_NOWAIT); | ||
1867 | if (rc == MBX_NOT_FINISHED) { | ||
1868 | lpfc_printf_vlog(vport, KERN_ERR, | ||
1869 | LOG_MBOX, "2608 Failed to issue init_vpi mailbox\n"); | ||
1870 | mempool_free(mboxq, vport->phba->mbox_mem_pool); | ||
1871 | } | ||
1872 | } | ||
1873 | |||
1874 | /** | ||
1744 | * lpfc_start_fdiscs - send fdiscs for each vports on this port. | 1875 | * lpfc_start_fdiscs - send fdiscs for each vports on this port. |
1745 | * @phba: pointer to lpfc hba data structure. | 1876 | * @phba: pointer to lpfc hba data structure. |
1746 | * | 1877 | * |
@@ -1752,8 +1883,6 @@ lpfc_start_fdiscs(struct lpfc_hba *phba) | |||
1752 | { | 1883 | { |
1753 | struct lpfc_vport **vports; | 1884 | struct lpfc_vport **vports; |
1754 | int i; | 1885 | int i; |
1755 | LPFC_MBOXQ_t *mboxq; | ||
1756 | int rc; | ||
1757 | 1886 | ||
1758 | vports = lpfc_create_vport_work_array(phba); | 1887 | vports = lpfc_create_vport_work_array(phba); |
1759 | if (vports != NULL) { | 1888 | if (vports != NULL) { |
@@ -1772,26 +1901,7 @@ lpfc_start_fdiscs(struct lpfc_hba *phba) | |||
1772 | continue; | 1901 | continue; |
1773 | } | 1902 | } |
1774 | if (vports[i]->fc_flag & FC_VPORT_NEEDS_INIT_VPI) { | 1903 | if (vports[i]->fc_flag & FC_VPORT_NEEDS_INIT_VPI) { |
1775 | mboxq = mempool_alloc(phba->mbox_mem_pool, | 1904 | lpfc_issue_init_vpi(vports[i]); |
1776 | GFP_KERNEL); | ||
1777 | if (!mboxq) { | ||
1778 | lpfc_printf_vlog(vports[i], KERN_ERR, | ||
1779 | LOG_MBOX, "2607 Failed to allocate " | ||
1780 | "init_vpi mailbox\n"); | ||
1781 | continue; | ||
1782 | } | ||
1783 | lpfc_init_vpi(phba, mboxq, vports[i]->vpi); | ||
1784 | mboxq->vport = vports[i]; | ||
1785 | mboxq->mbox_cmpl = lpfc_init_vpi_cmpl; | ||
1786 | rc = lpfc_sli_issue_mbox(phba, mboxq, | ||
1787 | MBX_NOWAIT); | ||
1788 | if (rc == MBX_NOT_FINISHED) { | ||
1789 | lpfc_printf_vlog(vports[i], KERN_ERR, | ||
1790 | LOG_MBOX, "2608 Failed to issue " | ||
1791 | "init_vpi mailbox\n"); | ||
1792 | mempool_free(mboxq, | ||
1793 | phba->mbox_mem_pool); | ||
1794 | } | ||
1795 | continue; | 1905 | continue; |
1796 | } | 1906 | } |
1797 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1907 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
@@ -2071,8 +2181,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
2071 | return; | 2181 | return; |
2072 | } | 2182 | } |
2073 | spin_unlock_irq(&phba->hbalock); | 2183 | spin_unlock_irq(&phba->hbalock); |
2074 | rc = lpfc_sli4_read_fcf_record(phba, | 2184 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); |
2075 | LPFC_FCOE_FCF_GET_FIRST); | ||
2076 | if (rc) | 2185 | if (rc) |
2077 | goto out; | 2186 | goto out; |
2078 | } | 2187 | } |
@@ -3240,6 +3349,34 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
3240 | return 0; | 3349 | return 0; |
3241 | } | 3350 | } |
3242 | 3351 | ||
3352 | /** | ||
3353 | * lpfc_unreg_hba_rpis - Unregister rpis registered to the hba. | ||
3354 | * @phba: pointer to lpfc hba data structure. | ||
3355 | * | ||
3356 | * This routine is invoked to unregister all the currently registered RPIs | ||
3357 | * to the HBA. | ||
3358 | **/ | ||
3359 | void | ||
3360 | lpfc_unreg_hba_rpis(struct lpfc_hba *phba) | ||
3361 | { | ||
3362 | struct lpfc_vport **vports; | ||
3363 | struct lpfc_nodelist *ndlp; | ||
3364 | struct Scsi_Host *shost; | ||
3365 | int i; | ||
3366 | |||
3367 | vports = lpfc_create_vport_work_array(phba); | ||
3368 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
3369 | shost = lpfc_shost_from_vport(vports[i]); | ||
3370 | spin_lock_irq(shost->host_lock); | ||
3371 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { | ||
3372 | if (ndlp->nlp_flag & NLP_RPI_VALID) | ||
3373 | lpfc_unreg_rpi(vports[i], ndlp); | ||
3374 | } | ||
3375 | spin_unlock_irq(shost->host_lock); | ||
3376 | } | ||
3377 | lpfc_destroy_vport_work_array(phba, vports); | ||
3378 | } | ||
3379 | |||
3243 | void | 3380 | void |
3244 | lpfc_unreg_all_rpis(struct lpfc_vport *vport) | 3381 | lpfc_unreg_all_rpis(struct lpfc_vport *vport) |
3245 | { | 3382 | { |
@@ -4470,47 +4607,31 @@ lpfc_unregister_fcfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
4470 | } | 4607 | } |
4471 | 4608 | ||
4472 | /** | 4609 | /** |
4473 | * lpfc_unregister_unused_fcf - Unregister FCF if all devices are disconnected. | 4610 | * lpfc_unregister_fcf_prep - Unregister fcf record preparation |
4474 | * @phba: Pointer to hba context object. | 4611 | * @phba: Pointer to hba context object. |
4475 | * | 4612 | * |
4476 | * This function check if there are any connected remote port for the FCF and | 4613 | * This function prepare the HBA for unregistering the currently registered |
4477 | * if all the devices are disconnected, this function unregister FCFI. | 4614 | * FCF from the HBA. It performs unregistering, in order, RPIs, VPIs, and |
4478 | * This function also tries to use another FCF for discovery. | 4615 | * VFIs. |
4479 | */ | 4616 | */ |
4480 | void | 4617 | int |
4481 | lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | 4618 | lpfc_unregister_fcf_prep(struct lpfc_hba *phba) |
4482 | { | 4619 | { |
4483 | LPFC_MBOXQ_t *mbox; | 4620 | LPFC_MBOXQ_t *mbox; |
4484 | int rc; | ||
4485 | struct lpfc_vport **vports; | 4621 | struct lpfc_vport **vports; |
4486 | int i; | ||
4487 | struct lpfc_nodelist *ndlp; | 4622 | struct lpfc_nodelist *ndlp; |
4623 | int i, rc; | ||
4488 | 4624 | ||
4489 | spin_lock_irq(&phba->hbalock); | 4625 | /* Unregister RPIs */ |
4490 | /* | ||
4491 | * If HBA is not running in FIP mode or | ||
4492 | * If HBA does not support FCoE or | ||
4493 | * If FCF is not registered. | ||
4494 | * do nothing. | ||
4495 | */ | ||
4496 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT) || | ||
4497 | !(phba->fcf.fcf_flag & FCF_REGISTERED) || | ||
4498 | (!(phba->hba_flag & HBA_FIP_SUPPORT))) { | ||
4499 | spin_unlock_irq(&phba->hbalock); | ||
4500 | return; | ||
4501 | } | ||
4502 | spin_unlock_irq(&phba->hbalock); | ||
4503 | |||
4504 | if (lpfc_fcf_inuse(phba)) | 4626 | if (lpfc_fcf_inuse(phba)) |
4505 | return; | 4627 | lpfc_unreg_hba_rpis(phba); |
4506 | 4628 | ||
4507 | /* At this point, all discovery is aborted */ | 4629 | /* At this point, all discovery is aborted */ |
4508 | phba->pport->port_state = LPFC_VPORT_UNKNOWN; | 4630 | phba->pport->port_state = LPFC_VPORT_UNKNOWN; |
4509 | 4631 | ||
4510 | /* Unregister VPIs */ | 4632 | /* Unregister VPIs */ |
4511 | vports = lpfc_create_vport_work_array(phba); | 4633 | vports = lpfc_create_vport_work_array(phba); |
4512 | if (vports && | 4634 | if (vports && (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) |
4513 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) | ||
4514 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | 4635 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
4515 | /* Stop FLOGI/FDISC retries */ | 4636 | /* Stop FLOGI/FDISC retries */ |
4516 | ndlp = lpfc_findnode_did(vports[i], Fabric_DID); | 4637 | ndlp = lpfc_findnode_did(vports[i], Fabric_DID); |
@@ -4531,10 +4652,9 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | |||
4531 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4652 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
4532 | if (!mbox) { | 4653 | if (!mbox) { |
4533 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4654 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
4534 | "2556 UNREG_VFI mbox allocation failed" | 4655 | "2556 UNREG_VFI mbox allocation failed" |
4535 | "HBA state x%x\n", | 4656 | "HBA state x%x\n", phba->pport->port_state); |
4536 | phba->pport->port_state); | 4657 | return -ENOMEM; |
4537 | return; | ||
4538 | } | 4658 | } |
4539 | 4659 | ||
4540 | lpfc_unreg_vfi(mbox, phba->pport); | 4660 | lpfc_unreg_vfi(mbox, phba->pport); |
@@ -4544,62 +4664,162 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | |||
4544 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 4664 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
4545 | if (rc == MBX_NOT_FINISHED) { | 4665 | if (rc == MBX_NOT_FINISHED) { |
4546 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4666 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
4547 | "2557 UNREG_VFI issue mbox failed rc x%x " | 4667 | "2557 UNREG_VFI issue mbox failed rc x%x " |
4548 | "HBA state x%x\n", | 4668 | "HBA state x%x\n", |
4549 | rc, phba->pport->port_state); | 4669 | rc, phba->pport->port_state); |
4550 | mempool_free(mbox, phba->mbox_mem_pool); | 4670 | mempool_free(mbox, phba->mbox_mem_pool); |
4551 | return; | 4671 | return -EIO; |
4552 | } | 4672 | } |
4553 | 4673 | ||
4554 | spin_lock_irq(&phba->hbalock); | 4674 | spin_lock_irq(&phba->hbalock); |
4555 | phba->pport->fc_flag &= ~FC_VFI_REGISTERED; | 4675 | phba->pport->fc_flag &= ~FC_VFI_REGISTERED; |
4556 | spin_unlock_irq(&phba->hbalock); | 4676 | spin_unlock_irq(&phba->hbalock); |
4557 | 4677 | ||
4558 | /* Unregister FCF */ | 4678 | return 0; |
4679 | } | ||
4680 | |||
4681 | /** | ||
4682 | * lpfc_sli4_unregister_fcf - Unregister currently registered FCF record | ||
4683 | * @phba: Pointer to hba context object. | ||
4684 | * | ||
4685 | * This function issues synchronous unregister FCF mailbox command to HBA to | ||
4686 | * unregister the currently registered FCF record. The driver does not reset | ||
4687 | * the driver FCF usage state flags. | ||
4688 | * | ||
4689 | * Return 0 if successfully issued, none-zero otherwise. | ||
4690 | */ | ||
4691 | int | ||
4692 | lpfc_sli4_unregister_fcf(struct lpfc_hba *phba) | ||
4693 | { | ||
4694 | LPFC_MBOXQ_t *mbox; | ||
4695 | int rc; | ||
4696 | |||
4559 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4697 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
4560 | if (!mbox) { | 4698 | if (!mbox) { |
4561 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4699 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
4562 | "2551 UNREG_FCFI mbox allocation failed" | 4700 | "2551 UNREG_FCFI mbox allocation failed" |
4563 | "HBA state x%x\n", | 4701 | "HBA state x%x\n", phba->pport->port_state); |
4564 | phba->pport->port_state); | 4702 | return -ENOMEM; |
4565 | return; | ||
4566 | } | 4703 | } |
4567 | |||
4568 | lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); | 4704 | lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); |
4569 | mbox->vport = phba->pport; | 4705 | mbox->vport = phba->pport; |
4570 | mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; | 4706 | mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; |
4571 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 4707 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
4572 | 4708 | ||
4573 | if (rc == MBX_NOT_FINISHED) { | 4709 | if (rc == MBX_NOT_FINISHED) { |
4574 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4710 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
4575 | "2552 UNREG_FCFI issue mbox failed rc x%x " | 4711 | "2552 Unregister FCFI command failed rc x%x " |
4576 | "HBA state x%x\n", | 4712 | "HBA state x%x\n", |
4577 | rc, phba->pport->port_state); | 4713 | rc, phba->pport->port_state); |
4578 | mempool_free(mbox, phba->mbox_mem_pool); | 4714 | return -EINVAL; |
4715 | } | ||
4716 | return 0; | ||
4717 | } | ||
4718 | |||
4719 | /** | ||
4720 | * lpfc_unregister_fcf_rescan - Unregister currently registered fcf and rescan | ||
4721 | * @phba: Pointer to hba context object. | ||
4722 | * | ||
4723 | * This function unregisters the currently reigstered FCF. This function | ||
4724 | * also tries to find another FCF for discovery by rescan the HBA FCF table. | ||
4725 | */ | ||
4726 | void | ||
4727 | lpfc_unregister_fcf_rescan(struct lpfc_hba *phba) | ||
4728 | { | ||
4729 | int rc; | ||
4730 | |||
4731 | /* Preparation for unregistering fcf */ | ||
4732 | rc = lpfc_unregister_fcf_prep(phba); | ||
4733 | if (rc) { | ||
4734 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | ||
4735 | "2748 Failed to prepare for unregistering " | ||
4736 | "HBA's FCF record: rc=%d\n", rc); | ||
4579 | return; | 4737 | return; |
4580 | } | 4738 | } |
4581 | 4739 | ||
4582 | spin_lock_irq(&phba->hbalock); | 4740 | /* Now, unregister FCF record and reset HBA FCF state */ |
4583 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_REGISTERED | | 4741 | rc = lpfc_sli4_unregister_fcf(phba); |
4584 | FCF_DISCOVERED | FCF_BOOT_ENABLE | FCF_IN_USE | | 4742 | if (rc) |
4585 | FCF_VALID_VLAN); | 4743 | return; |
4586 | spin_unlock_irq(&phba->hbalock); | 4744 | /* Reset HBA FCF states after successful unregister FCF */ |
4745 | phba->fcf.fcf_flag = 0; | ||
4587 | 4746 | ||
4588 | /* | 4747 | /* |
4589 | * If driver is not unloading, check if there is any other | 4748 | * If driver is not unloading, check if there is any other |
4590 | * FCF record that can be used for discovery. | 4749 | * FCF record that can be used for discovery. |
4591 | */ | 4750 | */ |
4592 | if ((phba->pport->load_flag & FC_UNLOADING) || | 4751 | if ((phba->pport->load_flag & FC_UNLOADING) || |
4593 | (phba->link_state < LPFC_LINK_UP)) | 4752 | (phba->link_state < LPFC_LINK_UP)) |
4594 | return; | 4753 | return; |
4595 | 4754 | ||
4596 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | 4755 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); |
4597 | 4756 | ||
4598 | if (rc) | 4757 | if (rc) |
4599 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4758 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
4600 | "2553 lpfc_unregister_unused_fcf failed to read FCF" | 4759 | "2553 lpfc_unregister_unused_fcf failed " |
4601 | " record HBA state x%x\n", | 4760 | "to read FCF record HBA state x%x\n", |
4602 | phba->pport->port_state); | 4761 | phba->pport->port_state); |
4762 | } | ||
4763 | |||
4764 | /** | ||
4765 | * lpfc_unregister_fcf - Unregister the currently registered fcf record | ||
4766 | * @phba: Pointer to hba context object. | ||
4767 | * | ||
4768 | * This function just unregisters the currently reigstered FCF. It does not | ||
4769 | * try to find another FCF for discovery. | ||
4770 | */ | ||
4771 | void | ||
4772 | lpfc_unregister_fcf(struct lpfc_hba *phba) | ||
4773 | { | ||
4774 | int rc; | ||
4775 | |||
4776 | /* Preparation for unregistering fcf */ | ||
4777 | rc = lpfc_unregister_fcf_prep(phba); | ||
4778 | if (rc) { | ||
4779 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | ||
4780 | "2749 Failed to prepare for unregistering " | ||
4781 | "HBA's FCF record: rc=%d\n", rc); | ||
4782 | return; | ||
4783 | } | ||
4784 | |||
4785 | /* Now, unregister FCF record and reset HBA FCF state */ | ||
4786 | rc = lpfc_sli4_unregister_fcf(phba); | ||
4787 | if (rc) | ||
4788 | return; | ||
4789 | /* Set proper HBA FCF states after successful unregister FCF */ | ||
4790 | spin_lock_irq(&phba->hbalock); | ||
4791 | phba->fcf.fcf_flag &= ~FCF_REGISTERED; | ||
4792 | spin_unlock_irq(&phba->hbalock); | ||
4793 | } | ||
4794 | |||
4795 | /** | ||
4796 | * lpfc_unregister_unused_fcf - Unregister FCF if all devices are disconnected. | ||
4797 | * @phba: Pointer to hba context object. | ||
4798 | * | ||
4799 | * This function check if there are any connected remote port for the FCF and | ||
4800 | * if all the devices are disconnected, this function unregister FCFI. | ||
4801 | * This function also tries to use another FCF for discovery. | ||
4802 | */ | ||
4803 | void | ||
4804 | lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | ||
4805 | { | ||
4806 | /* | ||
4807 | * If HBA is not running in FIP mode or if HBA does not support | ||
4808 | * FCoE or if FCF is not registered, do nothing. | ||
4809 | */ | ||
4810 | spin_lock_irq(&phba->hbalock); | ||
4811 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT) || | ||
4812 | !(phba->fcf.fcf_flag & FCF_REGISTERED) || | ||
4813 | !(phba->hba_flag & HBA_FIP_SUPPORT)) { | ||
4814 | spin_unlock_irq(&phba->hbalock); | ||
4815 | return; | ||
4816 | } | ||
4817 | spin_unlock_irq(&phba->hbalock); | ||
4818 | |||
4819 | if (lpfc_fcf_inuse(phba)) | ||
4820 | return; | ||
4821 | |||
4822 | lpfc_unregister_fcf_rescan(phba); | ||
4603 | } | 4823 | } |
4604 | 4824 | ||
4605 | /** | 4825 | /** |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index ae0c53dba845..999e49f6071e 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -797,6 +797,7 @@ struct mbox_header { | |||
797 | #define LPFC_MBOX_OPCODE_FCOE_ADD_FCF 0x09 | 797 | #define LPFC_MBOX_OPCODE_FCOE_ADD_FCF 0x09 |
798 | #define LPFC_MBOX_OPCODE_FCOE_DELETE_FCF 0x0A | 798 | #define LPFC_MBOX_OPCODE_FCOE_DELETE_FCF 0x0A |
799 | #define LPFC_MBOX_OPCODE_FCOE_POST_HDR_TEMPLATE 0x0B | 799 | #define LPFC_MBOX_OPCODE_FCOE_POST_HDR_TEMPLATE 0x0B |
800 | #define LPFC_MBOX_OPCODE_FCOE_REDISCOVER_FCF 0x10 | ||
800 | 801 | ||
801 | /* Mailbox command structures */ | 802 | /* Mailbox command structures */ |
802 | struct eq_context { | 803 | struct eq_context { |
@@ -1297,6 +1298,19 @@ struct lpfc_mbx_del_fcf_tbl_entry { | |||
1297 | #define lpfc_mbx_del_fcf_tbl_index_WORD word10 | 1298 | #define lpfc_mbx_del_fcf_tbl_index_WORD word10 |
1298 | }; | 1299 | }; |
1299 | 1300 | ||
1301 | struct lpfc_mbx_redisc_fcf_tbl { | ||
1302 | struct mbox_header header; | ||
1303 | uint32_t word10; | ||
1304 | #define lpfc_mbx_redisc_fcf_count_SHIFT 0 | ||
1305 | #define lpfc_mbx_redisc_fcf_count_MASK 0x0000FFFF | ||
1306 | #define lpfc_mbx_redisc_fcf_count_WORD word10 | ||
1307 | uint32_t resvd; | ||
1308 | uint32_t word12; | ||
1309 | #define lpfc_mbx_redisc_fcf_index_SHIFT 0 | ||
1310 | #define lpfc_mbx_redisc_fcf_index_MASK 0x0000FFFF | ||
1311 | #define lpfc_mbx_redisc_fcf_index_WORD word12 | ||
1312 | }; | ||
1313 | |||
1300 | struct lpfc_mbx_query_fw_cfg { | 1314 | struct lpfc_mbx_query_fw_cfg { |
1301 | struct mbox_header header; | 1315 | struct mbox_header header; |
1302 | uint32_t config_number; | 1316 | uint32_t config_number; |
@@ -1859,6 +1873,7 @@ struct lpfc_mqe { | |||
1859 | struct lpfc_mbx_read_fcf_tbl read_fcf_tbl; | 1873 | struct lpfc_mbx_read_fcf_tbl read_fcf_tbl; |
1860 | struct lpfc_mbx_add_fcf_tbl_entry add_fcf_entry; | 1874 | struct lpfc_mbx_add_fcf_tbl_entry add_fcf_entry; |
1861 | struct lpfc_mbx_del_fcf_tbl_entry del_fcf_entry; | 1875 | struct lpfc_mbx_del_fcf_tbl_entry del_fcf_entry; |
1876 | struct lpfc_mbx_redisc_fcf_tbl redisc_fcf_tbl; | ||
1862 | struct lpfc_mbx_reg_fcfi reg_fcfi; | 1877 | struct lpfc_mbx_reg_fcfi reg_fcfi; |
1863 | struct lpfc_mbx_unreg_fcfi unreg_fcfi; | 1878 | struct lpfc_mbx_unreg_fcfi unreg_fcfi; |
1864 | struct lpfc_mbx_mq_create mq_create; | 1879 | struct lpfc_mbx_mq_create mq_create; |
@@ -1975,6 +1990,7 @@ struct lpfc_acqe_fcoe { | |||
1975 | #define LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL 0x2 | 1990 | #define LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL 0x2 |
1976 | #define LPFC_FCOE_EVENT_TYPE_FCF_DEAD 0x3 | 1991 | #define LPFC_FCOE_EVENT_TYPE_FCF_DEAD 0x3 |
1977 | #define LPFC_FCOE_EVENT_TYPE_CVL 0x4 | 1992 | #define LPFC_FCOE_EVENT_TYPE_CVL 0x4 |
1993 | #define LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD 0x5 | ||
1978 | uint32_t event_tag; | 1994 | uint32_t event_tag; |
1979 | uint32_t trailer; | 1995 | uint32_t trailer; |
1980 | }; | 1996 | }; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 25a97dfd4ea7..6e04679167e3 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -2073,6 +2073,44 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport) | |||
2073 | } | 2073 | } |
2074 | 2074 | ||
2075 | /** | 2075 | /** |
2076 | * __lpfc_sli4_stop_fcf_redisc_wait_timer - Stop FCF rediscovery wait timer | ||
2077 | * @phba: pointer to lpfc hba data structure. | ||
2078 | * | ||
2079 | * This routine stops the SLI4 FCF rediscover wait timer if it's on. The | ||
2080 | * caller of this routine should already hold the host lock. | ||
2081 | **/ | ||
2082 | void | ||
2083 | __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba) | ||
2084 | { | ||
2085 | /* Clear pending FCF rediscovery wait timer */ | ||
2086 | phba->fcf.fcf_flag &= ~FCF_REDISC_PEND; | ||
2087 | /* Now, try to stop the timer */ | ||
2088 | del_timer(&phba->fcf.redisc_wait); | ||
2089 | } | ||
2090 | |||
2091 | /** | ||
2092 | * lpfc_sli4_stop_fcf_redisc_wait_timer - Stop FCF rediscovery wait timer | ||
2093 | * @phba: pointer to lpfc hba data structure. | ||
2094 | * | ||
2095 | * This routine stops the SLI4 FCF rediscover wait timer if it's on. It | ||
2096 | * checks whether the FCF rediscovery wait timer is pending with the host | ||
2097 | * lock held before proceeding with disabling the timer and clearing the | ||
2098 | * wait timer pendig flag. | ||
2099 | **/ | ||
2100 | void | ||
2101 | lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba) | ||
2102 | { | ||
2103 | spin_lock_irq(&phba->hbalock); | ||
2104 | if (!(phba->fcf.fcf_flag & FCF_REDISC_PEND)) { | ||
2105 | /* FCF rediscovery timer already fired or stopped */ | ||
2106 | spin_unlock_irq(&phba->hbalock); | ||
2107 | return; | ||
2108 | } | ||
2109 | __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); | ||
2110 | spin_unlock_irq(&phba->hbalock); | ||
2111 | } | ||
2112 | |||
2113 | /** | ||
2076 | * lpfc_stop_hba_timers - Stop all the timers associated with an HBA | 2114 | * lpfc_stop_hba_timers - Stop all the timers associated with an HBA |
2077 | * @phba: pointer to lpfc hba data structure. | 2115 | * @phba: pointer to lpfc hba data structure. |
2078 | * | 2116 | * |
@@ -2096,6 +2134,7 @@ lpfc_stop_hba_timers(struct lpfc_hba *phba) | |||
2096 | break; | 2134 | break; |
2097 | case LPFC_PCI_DEV_OC: | 2135 | case LPFC_PCI_DEV_OC: |
2098 | /* Stop any OneConnect device sepcific driver timers */ | 2136 | /* Stop any OneConnect device sepcific driver timers */ |
2137 | lpfc_sli4_stop_fcf_redisc_wait_timer(phba); | ||
2099 | break; | 2138 | break; |
2100 | default: | 2139 | default: |
2101 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2140 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
@@ -2706,7 +2745,7 @@ lpfc_sli_remove_dflt_fcf(struct lpfc_hba *phba) | |||
2706 | del_fcf_record = &mboxq->u.mqe.un.del_fcf_entry; | 2745 | del_fcf_record = &mboxq->u.mqe.un.del_fcf_entry; |
2707 | bf_set(lpfc_mbx_del_fcf_tbl_count, del_fcf_record, 1); | 2746 | bf_set(lpfc_mbx_del_fcf_tbl_count, del_fcf_record, 1); |
2708 | bf_set(lpfc_mbx_del_fcf_tbl_index, del_fcf_record, | 2747 | bf_set(lpfc_mbx_del_fcf_tbl_index, del_fcf_record, |
2709 | phba->fcf.fcf_indx); | 2748 | phba->fcf.current_rec.fcf_indx); |
2710 | 2749 | ||
2711 | if (!phba->sli4_hba.intr_enable) | 2750 | if (!phba->sli4_hba.intr_enable) |
2712 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | 2751 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); |
@@ -2730,6 +2769,57 @@ lpfc_sli_remove_dflt_fcf(struct lpfc_hba *phba) | |||
2730 | } | 2769 | } |
2731 | 2770 | ||
2732 | /** | 2771 | /** |
2772 | * lpfc_fcf_redisc_wait_start_timer - Start fcf rediscover wait timer | ||
2773 | * @phba: Pointer to hba for which this call is being executed. | ||
2774 | * | ||
2775 | * This routine starts the timer waiting for the FCF rediscovery to complete. | ||
2776 | **/ | ||
2777 | void | ||
2778 | lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *phba) | ||
2779 | { | ||
2780 | unsigned long fcf_redisc_wait_tmo = | ||
2781 | (jiffies + msecs_to_jiffies(LPFC_FCF_REDISCOVER_WAIT_TMO)); | ||
2782 | /* Start fcf rediscovery wait period timer */ | ||
2783 | mod_timer(&phba->fcf.redisc_wait, fcf_redisc_wait_tmo); | ||
2784 | spin_lock_irq(&phba->hbalock); | ||
2785 | /* Allow action to new fcf asynchronous event */ | ||
2786 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_SCAN_DONE); | ||
2787 | /* Mark the FCF rediscovery pending state */ | ||
2788 | phba->fcf.fcf_flag |= FCF_REDISC_PEND; | ||
2789 | spin_unlock_irq(&phba->hbalock); | ||
2790 | } | ||
2791 | |||
2792 | /** | ||
2793 | * lpfc_sli4_fcf_redisc_wait_tmo - FCF table rediscover wait timeout | ||
2794 | * @ptr: Map to lpfc_hba data structure pointer. | ||
2795 | * | ||
2796 | * This routine is invoked when waiting for FCF table rediscover has been | ||
2797 | * timed out. If new FCF record(s) has (have) been discovered during the | ||
2798 | * wait period, a new FCF event shall be added to the FCOE async event | ||
2799 | * list, and then worker thread shall be waked up for processing from the | ||
2800 | * worker thread context. | ||
2801 | **/ | ||
2802 | void | ||
2803 | lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr) | ||
2804 | { | ||
2805 | struct lpfc_hba *phba = (struct lpfc_hba *)ptr; | ||
2806 | |||
2807 | /* Don't send FCF rediscovery event if timer cancelled */ | ||
2808 | spin_lock_irq(&phba->hbalock); | ||
2809 | if (!(phba->fcf.fcf_flag & FCF_REDISC_PEND)) { | ||
2810 | spin_unlock_irq(&phba->hbalock); | ||
2811 | return; | ||
2812 | } | ||
2813 | /* Clear FCF rediscovery timer pending flag */ | ||
2814 | phba->fcf.fcf_flag &= ~FCF_REDISC_PEND; | ||
2815 | /* FCF rediscovery event to worker thread */ | ||
2816 | phba->fcf.fcf_flag |= FCF_REDISC_EVT; | ||
2817 | spin_unlock_irq(&phba->hbalock); | ||
2818 | /* wake up worker thread */ | ||
2819 | lpfc_worker_wake_up(phba); | ||
2820 | } | ||
2821 | |||
2822 | /** | ||
2733 | * lpfc_sli4_fw_cfg_check - Read the firmware config and verify FCoE support | 2823 | * lpfc_sli4_fw_cfg_check - Read the firmware config and verify FCoE support |
2734 | * @phba: pointer to lpfc hba data structure. | 2824 | * @phba: pointer to lpfc hba data structure. |
2735 | * | 2825 | * |
@@ -3020,17 +3110,26 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3020 | phba->fcoe_eventtag = acqe_fcoe->event_tag; | 3110 | phba->fcoe_eventtag = acqe_fcoe->event_tag; |
3021 | switch (event_type) { | 3111 | switch (event_type) { |
3022 | case LPFC_FCOE_EVENT_TYPE_NEW_FCF: | 3112 | case LPFC_FCOE_EVENT_TYPE_NEW_FCF: |
3113 | case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD: | ||
3023 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 3114 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, |
3024 | "2546 New FCF found index 0x%x tag 0x%x\n", | 3115 | "2546 New FCF found index 0x%x tag 0x%x\n", |
3025 | acqe_fcoe->index, | 3116 | acqe_fcoe->index, |
3026 | acqe_fcoe->event_tag); | 3117 | acqe_fcoe->event_tag); |
3027 | /* | ||
3028 | * If the current FCF is in discovered state, or | ||
3029 | * FCF discovery is in progress do nothing. | ||
3030 | */ | ||
3031 | spin_lock_irq(&phba->hbalock); | 3118 | spin_lock_irq(&phba->hbalock); |
3032 | if ((phba->fcf.fcf_flag & FCF_DISCOVERED) || | 3119 | if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) || |
3033 | (phba->hba_flag & FCF_DISC_INPROGRESS)) { | 3120 | (phba->hba_flag & FCF_DISC_INPROGRESS)) { |
3121 | /* | ||
3122 | * If the current FCF is in discovered state or | ||
3123 | * FCF discovery is in progress, do nothing. | ||
3124 | */ | ||
3125 | spin_unlock_irq(&phba->hbalock); | ||
3126 | break; | ||
3127 | } | ||
3128 | if (phba->fcf.fcf_flag & FCF_REDISC_EVT) { | ||
3129 | /* | ||
3130 | * If fast FCF failover rescan event is pending, | ||
3131 | * do nothing. | ||
3132 | */ | ||
3034 | spin_unlock_irq(&phba->hbalock); | 3133 | spin_unlock_irq(&phba->hbalock); |
3035 | break; | 3134 | break; |
3036 | } | 3135 | } |
@@ -3057,7 +3156,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3057 | " tag 0x%x\n", acqe_fcoe->index, | 3156 | " tag 0x%x\n", acqe_fcoe->index, |
3058 | acqe_fcoe->event_tag); | 3157 | acqe_fcoe->event_tag); |
3059 | /* If the event is not for currently used fcf do nothing */ | 3158 | /* If the event is not for currently used fcf do nothing */ |
3060 | if (phba->fcf.fcf_indx != acqe_fcoe->index) | 3159 | if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index) |
3061 | break; | 3160 | break; |
3062 | /* | 3161 | /* |
3063 | * Currently, driver support only one FCF - so treat this as | 3162 | * Currently, driver support only one FCF - so treat this as |
@@ -3121,7 +3220,19 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3121 | ndlp->nlp_last_elscmd = ELS_CMD_FDISC; | 3220 | ndlp->nlp_last_elscmd = ELS_CMD_FDISC; |
3122 | vport->port_state = LPFC_FDISC; | 3221 | vport->port_state = LPFC_FDISC; |
3123 | } else { | 3222 | } else { |
3124 | lpfc_retry_pport_discovery(phba); | 3223 | /* |
3224 | * Otherwise, we request port to rediscover | ||
3225 | * the entire FCF table for a fast recovery | ||
3226 | * from possible case that the current FCF | ||
3227 | * is no longer valid. | ||
3228 | */ | ||
3229 | rc = lpfc_sli4_redisc_fcf_table(phba); | ||
3230 | if (rc) | ||
3231 | /* | ||
3232 | * Last resort will be re-try on the | ||
3233 | * the current registered FCF entry. | ||
3234 | */ | ||
3235 | lpfc_retry_pport_discovery(phba); | ||
3125 | } | 3236 | } |
3126 | break; | 3237 | break; |
3127 | default: | 3238 | default: |
@@ -3198,6 +3309,34 @@ void lpfc_sli4_async_event_proc(struct lpfc_hba *phba) | |||
3198 | } | 3309 | } |
3199 | 3310 | ||
3200 | /** | 3311 | /** |
3312 | * lpfc_sli4_fcf_redisc_event_proc - Process fcf table rediscovery event | ||
3313 | * @phba: pointer to lpfc hba data structure. | ||
3314 | * | ||
3315 | * This routine is invoked by the worker thread to process FCF table | ||
3316 | * rediscovery pending completion event. | ||
3317 | **/ | ||
3318 | void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba) | ||
3319 | { | ||
3320 | int rc; | ||
3321 | |||
3322 | spin_lock_irq(&phba->hbalock); | ||
3323 | /* Clear FCF rediscovery timeout event */ | ||
3324 | phba->fcf.fcf_flag &= ~FCF_REDISC_EVT; | ||
3325 | /* Clear driver fast failover FCF record flag */ | ||
3326 | phba->fcf.failover_rec.flag = 0; | ||
3327 | /* Set state for FCF fast failover */ | ||
3328 | phba->fcf.fcf_flag |= FCF_REDISC_FOV; | ||
3329 | spin_unlock_irq(&phba->hbalock); | ||
3330 | |||
3331 | /* Scan FCF table from the first entry to re-discover SAN */ | ||
3332 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | ||
3333 | if (rc) | ||
3334 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | ||
3335 | "2747 Post FCF rediscovery read FCF record " | ||
3336 | "failed 0x%x\n", rc); | ||
3337 | } | ||
3338 | |||
3339 | /** | ||
3201 | * lpfc_api_table_setup - Set up per hba pci-device group func api jump table | 3340 | * lpfc_api_table_setup - Set up per hba pci-device group func api jump table |
3202 | * @phba: pointer to lpfc hba data structure. | 3341 | * @phba: pointer to lpfc hba data structure. |
3203 | * @dev_grp: The HBA PCI-Device group number. | 3342 | * @dev_grp: The HBA PCI-Device group number. |
@@ -3512,6 +3651,11 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
3512 | init_timer(&phba->eratt_poll); | 3651 | init_timer(&phba->eratt_poll); |
3513 | phba->eratt_poll.function = lpfc_poll_eratt; | 3652 | phba->eratt_poll.function = lpfc_poll_eratt; |
3514 | phba->eratt_poll.data = (unsigned long) phba; | 3653 | phba->eratt_poll.data = (unsigned long) phba; |
3654 | /* FCF rediscover timer */ | ||
3655 | init_timer(&phba->fcf.redisc_wait); | ||
3656 | phba->fcf.redisc_wait.function = lpfc_sli4_fcf_redisc_wait_tmo; | ||
3657 | phba->fcf.redisc_wait.data = (unsigned long)phba; | ||
3658 | |||
3515 | /* | 3659 | /* |
3516 | * We need to do a READ_CONFIG mailbox command here before | 3660 | * We need to do a READ_CONFIG mailbox command here before |
3517 | * calling lpfc_get_cfgparam. For VFs this will report the | 3661 | * calling lpfc_get_cfgparam. For VFs this will report the |
@@ -6039,7 +6183,7 @@ lpfc_sli4_fcfi_unreg(struct lpfc_hba *phba, uint16_t fcfi) | |||
6039 | spin_lock_irqsave(&phba->hbalock, flags); | 6183 | spin_lock_irqsave(&phba->hbalock, flags); |
6040 | /* Mark the FCFI is no longer registered */ | 6184 | /* Mark the FCFI is no longer registered */ |
6041 | phba->fcf.fcf_flag &= | 6185 | phba->fcf.fcf_flag &= |
6042 | ~(FCF_AVAILABLE | FCF_REGISTERED | FCF_DISCOVERED); | 6186 | ~(FCF_AVAILABLE | FCF_REGISTERED | FCF_SCAN_DONE); |
6043 | spin_unlock_irqrestore(&phba->hbalock, flags); | 6187 | spin_unlock_irqrestore(&phba->hbalock, flags); |
6044 | } | 6188 | } |
6045 | } | 6189 | } |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index a9afd8b94b6a..c2cc29f70a4b 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -1747,6 +1747,65 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox) | |||
1747 | } | 1747 | } |
1748 | 1748 | ||
1749 | /** | 1749 | /** |
1750 | * lpfc_sli4_mbx_read_fcf_record - Allocate and construct read fcf mbox cmd | ||
1751 | * @phba: pointer to lpfc hba data structure. | ||
1752 | * @fcf_index: index to fcf table. | ||
1753 | * | ||
1754 | * This routine routine allocates and constructs non-embedded mailbox command | ||
1755 | * for reading a FCF table entry refered by @fcf_index. | ||
1756 | * | ||
1757 | * Return: pointer to the mailbox command constructed if successful, otherwise | ||
1758 | * NULL. | ||
1759 | **/ | ||
1760 | int | ||
1761 | lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *phba, | ||
1762 | struct lpfcMboxq *mboxq, | ||
1763 | uint16_t fcf_index) | ||
1764 | { | ||
1765 | void *virt_addr; | ||
1766 | dma_addr_t phys_addr; | ||
1767 | uint8_t *bytep; | ||
1768 | struct lpfc_mbx_sge sge; | ||
1769 | uint32_t alloc_len, req_len; | ||
1770 | struct lpfc_mbx_read_fcf_tbl *read_fcf; | ||
1771 | |||
1772 | if (!mboxq) | ||
1773 | return -ENOMEM; | ||
1774 | |||
1775 | req_len = sizeof(struct fcf_record) + | ||
1776 | sizeof(union lpfc_sli4_cfg_shdr) + 2 * sizeof(uint32_t); | ||
1777 | |||
1778 | /* Set up READ_FCF SLI4_CONFIG mailbox-ioctl command */ | ||
1779 | alloc_len = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
1780 | LPFC_MBOX_OPCODE_FCOE_READ_FCF_TABLE, req_len, | ||
1781 | LPFC_SLI4_MBX_NEMBED); | ||
1782 | |||
1783 | if (alloc_len < req_len) { | ||
1784 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
1785 | "0291 Allocated DMA memory size (x%x) is " | ||
1786 | "less than the requested DMA memory " | ||
1787 | "size (x%x)\n", alloc_len, req_len); | ||
1788 | return -ENOMEM; | ||
1789 | } | ||
1790 | |||
1791 | /* Get the first SGE entry from the non-embedded DMA memory. This | ||
1792 | * routine only uses a single SGE. | ||
1793 | */ | ||
1794 | lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); | ||
1795 | phys_addr = getPaddr(sge.pa_hi, sge.pa_lo); | ||
1796 | virt_addr = mboxq->sge_array->addr[0]; | ||
1797 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; | ||
1798 | |||
1799 | /* Set up command fields */ | ||
1800 | bf_set(lpfc_mbx_read_fcf_tbl_indx, &read_fcf->u.request, fcf_index); | ||
1801 | /* Perform necessary endian conversion */ | ||
1802 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | ||
1803 | lpfc_sli_pcimem_bcopy(bytep, bytep, sizeof(uint32_t)); | ||
1804 | |||
1805 | return 0; | ||
1806 | } | ||
1807 | |||
1808 | /** | ||
1750 | * lpfc_request_features: Configure SLI4 REQUEST_FEATURES mailbox | 1809 | * lpfc_request_features: Configure SLI4 REQUEST_FEATURES mailbox |
1751 | * @mboxq: pointer to lpfc mbox command. | 1810 | * @mboxq: pointer to lpfc mbox command. |
1752 | * | 1811 | * |
@@ -1946,13 +2005,14 @@ lpfc_reg_fcfi(struct lpfc_hba *phba, struct lpfcMboxq *mbox) | |||
1946 | bf_set(lpfc_reg_fcfi_rq_id1, reg_fcfi, REG_FCF_INVALID_QID); | 2005 | bf_set(lpfc_reg_fcfi_rq_id1, reg_fcfi, REG_FCF_INVALID_QID); |
1947 | bf_set(lpfc_reg_fcfi_rq_id2, reg_fcfi, REG_FCF_INVALID_QID); | 2006 | bf_set(lpfc_reg_fcfi_rq_id2, reg_fcfi, REG_FCF_INVALID_QID); |
1948 | bf_set(lpfc_reg_fcfi_rq_id3, reg_fcfi, REG_FCF_INVALID_QID); | 2007 | bf_set(lpfc_reg_fcfi_rq_id3, reg_fcfi, REG_FCF_INVALID_QID); |
1949 | bf_set(lpfc_reg_fcfi_info_index, reg_fcfi, phba->fcf.fcf_indx); | 2008 | bf_set(lpfc_reg_fcfi_info_index, reg_fcfi, |
2009 | phba->fcf.current_rec.fcf_indx); | ||
1950 | /* reg_fcf addr mode is bit wise inverted value of fcf addr_mode */ | 2010 | /* reg_fcf addr mode is bit wise inverted value of fcf addr_mode */ |
1951 | bf_set(lpfc_reg_fcfi_mam, reg_fcfi, | 2011 | bf_set(lpfc_reg_fcfi_mam, reg_fcfi, (~phba->fcf.addr_mode) & 0x3); |
1952 | (~phba->fcf.addr_mode) & 0x3); | 2012 | if (phba->fcf.current_rec.vlan_id != 0xFFFF) { |
1953 | if (phba->fcf.fcf_flag & FCF_VALID_VLAN) { | ||
1954 | bf_set(lpfc_reg_fcfi_vv, reg_fcfi, 1); | 2013 | bf_set(lpfc_reg_fcfi_vv, reg_fcfi, 1); |
1955 | bf_set(lpfc_reg_fcfi_vlan_tag, reg_fcfi, phba->fcf.vlan_id); | 2014 | bf_set(lpfc_reg_fcfi_vlan_tag, reg_fcfi, |
2015 | phba->fcf.current_rec.vlan_id); | ||
1956 | } | 2016 | } |
1957 | } | 2017 | } |
1958 | 2018 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 8d666d9fabb4..d2ddf7d9e1bb 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -11956,12 +11956,6 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) | |||
11956 | { | 11956 | { |
11957 | int rc = 0, error; | 11957 | int rc = 0, error; |
11958 | LPFC_MBOXQ_t *mboxq; | 11958 | LPFC_MBOXQ_t *mboxq; |
11959 | void *virt_addr; | ||
11960 | dma_addr_t phys_addr; | ||
11961 | uint8_t *bytep; | ||
11962 | struct lpfc_mbx_sge sge; | ||
11963 | uint32_t alloc_len, req_len; | ||
11964 | struct lpfc_mbx_read_fcf_tbl *read_fcf; | ||
11965 | 11959 | ||
11966 | phba->fcoe_eventtag_at_fcf_scan = phba->fcoe_eventtag; | 11960 | phba->fcoe_eventtag_at_fcf_scan = phba->fcoe_eventtag; |
11967 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 11961 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
@@ -11972,43 +11966,19 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) | |||
11972 | error = -ENOMEM; | 11966 | error = -ENOMEM; |
11973 | goto fail_fcfscan; | 11967 | goto fail_fcfscan; |
11974 | } | 11968 | } |
11975 | 11969 | /* Construct the read FCF record mailbox command */ | |
11976 | req_len = sizeof(struct fcf_record) + | 11970 | rc = lpfc_sli4_mbx_read_fcf_record(phba, mboxq, fcf_index); |
11977 | sizeof(union lpfc_sli4_cfg_shdr) + 2 * sizeof(uint32_t); | 11971 | if (rc) { |
11978 | 11972 | error = -EINVAL; | |
11979 | /* Set up READ_FCF SLI4_CONFIG mailbox-ioctl command */ | ||
11980 | alloc_len = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
11981 | LPFC_MBOX_OPCODE_FCOE_READ_FCF_TABLE, req_len, | ||
11982 | LPFC_SLI4_MBX_NEMBED); | ||
11983 | |||
11984 | if (alloc_len < req_len) { | ||
11985 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11986 | "0291 Allocated DMA memory size (x%x) is " | ||
11987 | "less than the requested DMA memory " | ||
11988 | "size (x%x)\n", alloc_len, req_len); | ||
11989 | error = -ENOMEM; | ||
11990 | goto fail_fcfscan; | 11973 | goto fail_fcfscan; |
11991 | } | 11974 | } |
11992 | 11975 | /* Issue the mailbox command asynchronously */ | |
11993 | /* Get the first SGE entry from the non-embedded DMA memory. This | ||
11994 | * routine only uses a single SGE. | ||
11995 | */ | ||
11996 | lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); | ||
11997 | phys_addr = getPaddr(sge.pa_hi, sge.pa_lo); | ||
11998 | virt_addr = mboxq->sge_array->addr[0]; | ||
11999 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; | ||
12000 | |||
12001 | /* Set up command fields */ | ||
12002 | bf_set(lpfc_mbx_read_fcf_tbl_indx, &read_fcf->u.request, fcf_index); | ||
12003 | /* Perform necessary endian conversion */ | ||
12004 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | ||
12005 | lpfc_sli_pcimem_bcopy(bytep, bytep, sizeof(uint32_t)); | ||
12006 | mboxq->vport = phba->pport; | 11976 | mboxq->vport = phba->pport; |
12007 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record; | 11977 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record; |
12008 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); | 11978 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); |
12009 | if (rc == MBX_NOT_FINISHED) { | 11979 | if (rc == MBX_NOT_FINISHED) |
12010 | error = -EIO; | 11980 | error = -EIO; |
12011 | } else { | 11981 | else { |
12012 | spin_lock_irq(&phba->hbalock); | 11982 | spin_lock_irq(&phba->hbalock); |
12013 | phba->hba_flag |= FCF_DISC_INPROGRESS; | 11983 | phba->hba_flag |= FCF_DISC_INPROGRESS; |
12014 | spin_unlock_irq(&phba->hbalock); | 11984 | spin_unlock_irq(&phba->hbalock); |
@@ -12027,6 +11997,90 @@ fail_fcfscan: | |||
12027 | } | 11997 | } |
12028 | 11998 | ||
12029 | /** | 11999 | /** |
12000 | * lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table | ||
12001 | * @phba: pointer to lpfc hba data structure. | ||
12002 | * | ||
12003 | * This routine is the completion routine for the rediscover FCF table mailbox | ||
12004 | * command. If the mailbox command returned failure, it will try to stop the | ||
12005 | * FCF rediscover wait timer. | ||
12006 | **/ | ||
12007 | void | ||
12008 | lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) | ||
12009 | { | ||
12010 | struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf; | ||
12011 | uint32_t shdr_status, shdr_add_status; | ||
12012 | |||
12013 | redisc_fcf = &mbox->u.mqe.un.redisc_fcf_tbl; | ||
12014 | |||
12015 | shdr_status = bf_get(lpfc_mbox_hdr_status, | ||
12016 | &redisc_fcf->header.cfg_shdr.response); | ||
12017 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | ||
12018 | &redisc_fcf->header.cfg_shdr.response); | ||
12019 | if (shdr_status || shdr_add_status) { | ||
12020 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
12021 | "2746 Requesting for FCF rediscovery failed " | ||
12022 | "status x%x add_status x%x\n", | ||
12023 | shdr_status, shdr_add_status); | ||
12024 | /* | ||
12025 | * Request failed, last resort to re-try current | ||
12026 | * registered FCF entry | ||
12027 | */ | ||
12028 | lpfc_retry_pport_discovery(phba); | ||
12029 | } else | ||
12030 | /* | ||
12031 | * Start FCF rediscovery wait timer for pending FCF | ||
12032 | * before rescan FCF record table. | ||
12033 | */ | ||
12034 | lpfc_fcf_redisc_wait_start_timer(phba); | ||
12035 | |||
12036 | mempool_free(mbox, phba->mbox_mem_pool); | ||
12037 | } | ||
12038 | |||
12039 | /** | ||
12040 | * lpfc_sli4_redisc_all_fcf - Request to rediscover entire FCF table by port. | ||
12041 | * @phba: pointer to lpfc hba data structure. | ||
12042 | * | ||
12043 | * This routine is invoked to request for rediscovery of the entire FCF table | ||
12044 | * by the port. | ||
12045 | **/ | ||
12046 | int | ||
12047 | lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba) | ||
12048 | { | ||
12049 | LPFC_MBOXQ_t *mbox; | ||
12050 | struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf; | ||
12051 | int rc, length; | ||
12052 | |||
12053 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
12054 | if (!mbox) { | ||
12055 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
12056 | "2745 Failed to allocate mbox for " | ||
12057 | "requesting FCF rediscover.\n"); | ||
12058 | return -ENOMEM; | ||
12059 | } | ||
12060 | |||
12061 | length = (sizeof(struct lpfc_mbx_redisc_fcf_tbl) - | ||
12062 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
12063 | lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
12064 | LPFC_MBOX_OPCODE_FCOE_REDISCOVER_FCF, | ||
12065 | length, LPFC_SLI4_MBX_EMBED); | ||
12066 | |||
12067 | redisc_fcf = &mbox->u.mqe.un.redisc_fcf_tbl; | ||
12068 | /* Set count to 0 for invalidating the entire FCF database */ | ||
12069 | bf_set(lpfc_mbx_redisc_fcf_count, redisc_fcf, 0); | ||
12070 | |||
12071 | /* Issue the mailbox command asynchronously */ | ||
12072 | mbox->vport = phba->pport; | ||
12073 | mbox->mbox_cmpl = lpfc_mbx_cmpl_redisc_fcf_table; | ||
12074 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
12075 | |||
12076 | if (rc == MBX_NOT_FINISHED) { | ||
12077 | mempool_free(mbox, phba->mbox_mem_pool); | ||
12078 | return -EIO; | ||
12079 | } | ||
12080 | return 0; | ||
12081 | } | ||
12082 | |||
12083 | /** | ||
12030 | * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled. | 12084 | * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled. |
12031 | * @phba: pointer to lpfc hba data structure. | 12085 | * @phba: pointer to lpfc hba data structure. |
12032 | * | 12086 | * |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 2e5e40576864..0a4f59ea21d0 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -22,6 +22,10 @@ | |||
22 | #define LPFC_RELEASE_NOTIFICATION_INTERVAL 32 | 22 | #define LPFC_RELEASE_NOTIFICATION_INTERVAL 32 |
23 | #define LPFC_GET_QE_REL_INT 32 | 23 | #define LPFC_GET_QE_REL_INT 32 |
24 | #define LPFC_RPI_LOW_WATER_MARK 10 | 24 | #define LPFC_RPI_LOW_WATER_MARK 10 |
25 | |||
26 | /* Amount of time in seconds for waiting FCF rediscovery to complete */ | ||
27 | #define LPFC_FCF_REDISCOVER_WAIT_TMO 2000 /* msec */ | ||
28 | |||
25 | /* Number of SGL entries can be posted in a 4KB nonembedded mbox command */ | 29 | /* Number of SGL entries can be posted in a 4KB nonembedded mbox command */ |
26 | #define LPFC_NEMBED_MBOX_SGL_CNT 254 | 30 | #define LPFC_NEMBED_MBOX_SGL_CNT 254 |
27 | 31 | ||
@@ -129,22 +133,33 @@ struct lpfc_sli4_link { | |||
129 | uint16_t logical_speed; | 133 | uint16_t logical_speed; |
130 | }; | 134 | }; |
131 | 135 | ||
132 | struct lpfc_fcf { | 136 | struct lpfc_fcf_rec { |
133 | uint8_t fabric_name[8]; | 137 | uint8_t fabric_name[8]; |
134 | uint8_t switch_name[8]; | 138 | uint8_t switch_name[8]; |
135 | uint8_t mac_addr[6]; | 139 | uint8_t mac_addr[6]; |
136 | uint16_t fcf_indx; | 140 | uint16_t fcf_indx; |
141 | uint32_t priority; | ||
142 | uint16_t vlan_id; | ||
143 | uint32_t addr_mode; | ||
144 | uint32_t flag; | ||
145 | #define BOOT_ENABLE 0x01 | ||
146 | #define RECORD_VALID 0x02 | ||
147 | }; | ||
148 | |||
149 | struct lpfc_fcf { | ||
137 | uint16_t fcfi; | 150 | uint16_t fcfi; |
138 | uint32_t fcf_flag; | 151 | uint32_t fcf_flag; |
139 | #define FCF_AVAILABLE 0x01 /* FCF available for discovery */ | 152 | #define FCF_AVAILABLE 0x01 /* FCF available for discovery */ |
140 | #define FCF_REGISTERED 0x02 /* FCF registered with FW */ | 153 | #define FCF_REGISTERED 0x02 /* FCF registered with FW */ |
141 | #define FCF_DISCOVERED 0x04 /* FCF discovery started */ | 154 | #define FCF_SCAN_DONE 0x04 /* FCF table scan done */ |
142 | #define FCF_BOOT_ENABLE 0x08 /* Boot bios use this FCF */ | 155 | #define FCF_IN_USE 0x08 /* Atleast one discovery completed */ |
143 | #define FCF_IN_USE 0x10 /* Atleast one discovery completed */ | 156 | #define FCF_REDISC_PEND 0x10 /* FCF rediscovery pending */ |
144 | #define FCF_VALID_VLAN 0x20 /* Use the vlan id specified */ | 157 | #define FCF_REDISC_EVT 0x20 /* FCF rediscovery event to worker thread */ |
145 | uint32_t priority; | 158 | #define FCF_REDISC_FOV 0x40 /* Post FCF rediscovery fast failover */ |
146 | uint32_t addr_mode; | 159 | uint32_t addr_mode; |
147 | uint16_t vlan_id; | 160 | struct lpfc_fcf_rec current_rec; |
161 | struct lpfc_fcf_rec failover_rec; | ||
162 | struct timer_list redisc_wait; | ||
148 | }; | 163 | }; |
149 | 164 | ||
150 | #define LPFC_REGION23_SIGNATURE "RG23" | 165 | #define LPFC_REGION23_SIGNATURE "RG23" |
@@ -407,6 +422,8 @@ void lpfc_sli4_mbox_cmd_free(struct lpfc_hba *, struct lpfcMboxq *); | |||
407 | void lpfc_sli4_mbx_sge_set(struct lpfcMboxq *, uint32_t, dma_addr_t, uint32_t); | 422 | void lpfc_sli4_mbx_sge_set(struct lpfcMboxq *, uint32_t, dma_addr_t, uint32_t); |
408 | void lpfc_sli4_mbx_sge_get(struct lpfcMboxq *, uint32_t, | 423 | void lpfc_sli4_mbx_sge_get(struct lpfcMboxq *, uint32_t, |
409 | struct lpfc_mbx_sge *); | 424 | struct lpfc_mbx_sge *); |
425 | int lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *, struct lpfcMboxq *, | ||
426 | uint16_t); | ||
410 | 427 | ||
411 | void lpfc_sli4_hba_reset(struct lpfc_hba *); | 428 | void lpfc_sli4_hba_reset(struct lpfc_hba *); |
412 | struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t, | 429 | struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t, |
@@ -449,6 +466,7 @@ int lpfc_sli4_alloc_rpi(struct lpfc_hba *); | |||
449 | void lpfc_sli4_free_rpi(struct lpfc_hba *, int); | 466 | void lpfc_sli4_free_rpi(struct lpfc_hba *, int); |
450 | void lpfc_sli4_remove_rpis(struct lpfc_hba *); | 467 | void lpfc_sli4_remove_rpis(struct lpfc_hba *); |
451 | void lpfc_sli4_async_event_proc(struct lpfc_hba *); | 468 | void lpfc_sli4_async_event_proc(struct lpfc_hba *); |
469 | void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *); | ||
452 | int lpfc_sli4_resume_rpi(struct lpfc_nodelist *); | 470 | int lpfc_sli4_resume_rpi(struct lpfc_nodelist *); |
453 | void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *); | 471 | void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *); |
454 | void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *); | 472 | void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *); |