diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 735 |
1 files changed, 501 insertions, 234 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 2445e399fd60..2359d0bfb734 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); |
| @@ -706,6 +708,8 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) | |||
| 706 | void | 708 | void |
| 707 | lpfc_port_link_failure(struct lpfc_vport *vport) | 709 | lpfc_port_link_failure(struct lpfc_vport *vport) |
| 708 | { | 710 | { |
| 711 | lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN); | ||
| 712 | |||
| 709 | /* Cleanup any outstanding received buffers */ | 713 | /* Cleanup any outstanding received buffers */ |
| 710 | lpfc_cleanup_rcv_buffers(vport); | 714 | lpfc_cleanup_rcv_buffers(vport); |
| 711 | 715 | ||
| @@ -752,12 +756,14 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
| 752 | lpfc_scsi_dev_block(phba); | 756 | lpfc_scsi_dev_block(phba); |
| 753 | 757 | ||
| 754 | spin_lock_irq(&phba->hbalock); | 758 | spin_lock_irq(&phba->hbalock); |
| 755 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); | 759 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_SCAN_DONE); |
| 760 | spin_unlock_irq(&phba->hbalock); | ||
| 756 | if (phba->link_state > LPFC_LINK_DOWN) { | 761 | if (phba->link_state > LPFC_LINK_DOWN) { |
| 757 | phba->link_state = LPFC_LINK_DOWN; | 762 | phba->link_state = LPFC_LINK_DOWN; |
| 763 | spin_lock_irq(shost->host_lock); | ||
| 758 | phba->pport->fc_flag &= ~FC_LBIT; | 764 | phba->pport->fc_flag &= ~FC_LBIT; |
| 765 | spin_unlock_irq(shost->host_lock); | ||
| 759 | } | 766 | } |
| 760 | spin_unlock_irq(&phba->hbalock); | ||
| 761 | vports = lpfc_create_vport_work_array(phba); | 767 | vports = lpfc_create_vport_work_array(phba); |
| 762 | if (vports != NULL) | 768 | if (vports != NULL) |
| 763 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | 769 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
| @@ -1023,7 +1029,7 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 1023 | return; | 1029 | return; |
| 1024 | } | 1030 | } |
| 1025 | spin_lock_irqsave(&phba->hbalock, flags); | 1031 | spin_lock_irqsave(&phba->hbalock, flags); |
| 1026 | phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); | 1032 | phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE); |
| 1027 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1033 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
| 1028 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1034 | spin_unlock_irqrestore(&phba->hbalock, flags); |
| 1029 | if (vport->port_state != LPFC_FLOGI) | 1035 | if (vport->port_state != LPFC_FLOGI) |
| @@ -1045,25 +1051,23 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 1045 | static uint32_t | 1051 | static uint32_t |
| 1046 | lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record) | 1052 | lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record) |
| 1047 | { | 1053 | { |
| 1048 | if ((fab_name[0] == | 1054 | if (fab_name[0] != bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record)) |
| 1049 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record)) && | 1055 | return 0; |
| 1050 | (fab_name[1] == | 1056 | if (fab_name[1] != bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record)) |
| 1051 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record)) && | 1057 | return 0; |
| 1052 | (fab_name[2] == | 1058 | if (fab_name[2] != bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record)) |
| 1053 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record)) && | ||
| 1054 | (fab_name[3] == | ||
| 1055 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record)) && | ||
| 1056 | (fab_name[4] == | ||
| 1057 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record)) && | ||
| 1058 | (fab_name[5] == | ||
| 1059 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record)) && | ||
| 1060 | (fab_name[6] == | ||
| 1061 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record)) && | ||
| 1062 | (fab_name[7] == | ||
| 1063 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record))) | ||
| 1064 | return 1; | ||
| 1065 | else | ||
| 1066 | return 0; | 1059 | return 0; |
| 1060 | if (fab_name[3] != bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record)) | ||
| 1061 | return 0; | ||
| 1062 | if (fab_name[4] != bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record)) | ||
| 1063 | return 0; | ||
| 1064 | if (fab_name[5] != bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record)) | ||
| 1065 | return 0; | ||
| 1066 | if (fab_name[6] != bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record)) | ||
| 1067 | return 0; | ||
| 1068 | if (fab_name[7] != bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record)) | ||
| 1069 | return 0; | ||
| 1070 | return 1; | ||
| 1067 | } | 1071 | } |
| 1068 | 1072 | ||
| 1069 | /** | 1073 | /** |
| @@ -1078,30 +1082,28 @@ lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record) | |||
| 1078 | static uint32_t | 1082 | static uint32_t |
| 1079 | lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record) | 1083 | lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record) |
| 1080 | { | 1084 | { |
| 1081 | if ((sw_name[0] == | 1085 | if (sw_name[0] != bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record)) |
| 1082 | bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record)) && | ||
| 1083 | (sw_name[1] == | ||
| 1084 | bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record)) && | ||
| 1085 | (sw_name[2] == | ||
| 1086 | bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record)) && | ||
| 1087 | (sw_name[3] == | ||
| 1088 | bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record)) && | ||
| 1089 | (sw_name[4] == | ||
| 1090 | bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record)) && | ||
| 1091 | (sw_name[5] == | ||
| 1092 | bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record)) && | ||
| 1093 | (sw_name[6] == | ||
| 1094 | bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record)) && | ||
| 1095 | (sw_name[7] == | ||
| 1096 | bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record))) | ||
| 1097 | return 1; | ||
| 1098 | else | ||
| 1099 | return 0; | 1086 | return 0; |
| 1087 | if (sw_name[1] != bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record)) | ||
| 1088 | return 0; | ||
| 1089 | if (sw_name[2] != bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record)) | ||
| 1090 | return 0; | ||
| 1091 | if (sw_name[3] != bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record)) | ||
| 1092 | return 0; | ||
| 1093 | if (sw_name[4] != bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record)) | ||
| 1094 | return 0; | ||
| 1095 | if (sw_name[5] != bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record)) | ||
| 1096 | return 0; | ||
| 1097 | if (sw_name[6] != bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record)) | ||
| 1098 | return 0; | ||
| 1099 | if (sw_name[7] != bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record)) | ||
| 1100 | return 0; | ||
| 1101 | return 1; | ||
| 1100 | } | 1102 | } |
| 1101 | 1103 | ||
| 1102 | /** | 1104 | /** |
| 1103 | * lpfc_mac_addr_match - Check if the fcf mac address match. | 1105 | * lpfc_mac_addr_match - Check if the fcf mac address match. |
| 1104 | * @phba: pointer to lpfc hba data structure. | 1106 | * @mac_addr: pointer to mac address. |
| 1105 | * @new_fcf_record: pointer to fcf record. | 1107 | * @new_fcf_record: pointer to fcf record. |
| 1106 | * | 1108 | * |
| 1107 | * This routine compare the fcf record's mac address with HBA's | 1109 | * This routine compare the fcf record's mac address with HBA's |
| @@ -1109,85 +1111,115 @@ lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record) | |||
| 1109 | * returns 1 else return 0. | 1111 | * returns 1 else return 0. |
| 1110 | **/ | 1112 | **/ |
| 1111 | static uint32_t | 1113 | static uint32_t |
| 1112 | lpfc_mac_addr_match(struct lpfc_hba *phba, struct fcf_record *new_fcf_record) | 1114 | lpfc_mac_addr_match(uint8_t *mac_addr, struct fcf_record *new_fcf_record) |
| 1113 | { | 1115 | { |
| 1114 | if ((phba->fcf.mac_addr[0] == | 1116 | if (mac_addr[0] != bf_get(lpfc_fcf_record_mac_0, new_fcf_record)) |
| 1115 | bf_get(lpfc_fcf_record_mac_0, new_fcf_record)) && | 1117 | return 0; |
| 1116 | (phba->fcf.mac_addr[1] == | 1118 | if (mac_addr[1] != bf_get(lpfc_fcf_record_mac_1, new_fcf_record)) |
| 1117 | bf_get(lpfc_fcf_record_mac_1, new_fcf_record)) && | 1119 | return 0; |
| 1118 | (phba->fcf.mac_addr[2] == | 1120 | if (mac_addr[2] != bf_get(lpfc_fcf_record_mac_2, new_fcf_record)) |
| 1119 | bf_get(lpfc_fcf_record_mac_2, new_fcf_record)) && | ||
| 1120 | (phba->fcf.mac_addr[3] == | ||
| 1121 | bf_get(lpfc_fcf_record_mac_3, new_fcf_record)) && | ||
| 1122 | (phba->fcf.mac_addr[4] == | ||
| 1123 | bf_get(lpfc_fcf_record_mac_4, new_fcf_record)) && | ||
| 1124 | (phba->fcf.mac_addr[5] == | ||
| 1125 | bf_get(lpfc_fcf_record_mac_5, new_fcf_record))) | ||
| 1126 | return 1; | ||
| 1127 | else | ||
| 1128 | return 0; | 1121 | return 0; |
| 1122 | if (mac_addr[3] != bf_get(lpfc_fcf_record_mac_3, new_fcf_record)) | ||
| 1123 | return 0; | ||
| 1124 | if (mac_addr[4] != bf_get(lpfc_fcf_record_mac_4, new_fcf_record)) | ||
| 1125 | return 0; | ||
| 1126 | if (mac_addr[5] != bf_get(lpfc_fcf_record_mac_5, new_fcf_record)) | ||
| 1127 | return 0; | ||
| 1128 | return 1; | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | static bool | ||
| 1132 | lpfc_vlan_id_match(uint16_t curr_vlan_id, uint16_t new_vlan_id) | ||
| 1133 | { | ||
| 1134 | return (curr_vlan_id == new_vlan_id); | ||
| 1129 | } | 1135 | } |
| 1130 | 1136 | ||
| 1131 | /** | 1137 | /** |
| 1132 | * lpfc_copy_fcf_record - Copy fcf information to lpfc_hba. | 1138 | * lpfc_copy_fcf_record - Copy fcf information to lpfc_hba. |
| 1133 | * @phba: pointer to lpfc hba data structure. | 1139 | * @fcf: pointer to driver fcf record. |
| 1134 | * @new_fcf_record: pointer to fcf record. | 1140 | * @new_fcf_record: pointer to fcf record. |
| 1135 | * | 1141 | * |
| 1136 | * This routine copies the FCF information from the FCF | 1142 | * This routine copies the FCF information from the FCF |
| 1137 | * record to lpfc_hba data structure. | 1143 | * record to lpfc_hba data structure. |
| 1138 | **/ | 1144 | **/ |
| 1139 | static void | 1145 | static void |
| 1140 | lpfc_copy_fcf_record(struct lpfc_hba *phba, struct fcf_record *new_fcf_record) | 1146 | lpfc_copy_fcf_record(struct lpfc_fcf_rec *fcf_rec, |
| 1147 | struct fcf_record *new_fcf_record) | ||
| 1141 | { | 1148 | { |
| 1142 | phba->fcf.fabric_name[0] = | 1149 | /* Fabric name */ |
| 1150 | fcf_rec->fabric_name[0] = | ||
| 1143 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record); | 1151 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record); |
| 1144 | phba->fcf.fabric_name[1] = | 1152 | fcf_rec->fabric_name[1] = |
| 1145 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record); | 1153 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record); |
| 1146 | phba->fcf.fabric_name[2] = | 1154 | fcf_rec->fabric_name[2] = |
| 1147 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record); | 1155 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record); |
| 1148 | phba->fcf.fabric_name[3] = | 1156 | fcf_rec->fabric_name[3] = |
| 1149 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record); | 1157 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record); |
| 1150 | phba->fcf.fabric_name[4] = | 1158 | fcf_rec->fabric_name[4] = |
| 1151 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record); | 1159 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record); |
| 1152 | phba->fcf.fabric_name[5] = | 1160 | fcf_rec->fabric_name[5] = |
| 1153 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record); | 1161 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record); |
| 1154 | phba->fcf.fabric_name[6] = | 1162 | fcf_rec->fabric_name[6] = |
| 1155 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record); | 1163 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record); |
| 1156 | phba->fcf.fabric_name[7] = | 1164 | fcf_rec->fabric_name[7] = |
| 1157 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record); | 1165 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record); |
| 1158 | phba->fcf.mac_addr[0] = | 1166 | /* Mac address */ |
| 1159 | bf_get(lpfc_fcf_record_mac_0, new_fcf_record); | 1167 | fcf_rec->mac_addr[0] = bf_get(lpfc_fcf_record_mac_0, new_fcf_record); |
| 1160 | phba->fcf.mac_addr[1] = | 1168 | fcf_rec->mac_addr[1] = bf_get(lpfc_fcf_record_mac_1, new_fcf_record); |
| 1161 | bf_get(lpfc_fcf_record_mac_1, new_fcf_record); | 1169 | fcf_rec->mac_addr[2] = bf_get(lpfc_fcf_record_mac_2, new_fcf_record); |
| 1162 | phba->fcf.mac_addr[2] = | 1170 | fcf_rec->mac_addr[3] = bf_get(lpfc_fcf_record_mac_3, new_fcf_record); |
| 1163 | bf_get(lpfc_fcf_record_mac_2, new_fcf_record); | 1171 | fcf_rec->mac_addr[4] = bf_get(lpfc_fcf_record_mac_4, new_fcf_record); |
| 1164 | phba->fcf.mac_addr[3] = | 1172 | fcf_rec->mac_addr[5] = bf_get(lpfc_fcf_record_mac_5, new_fcf_record); |
| 1165 | bf_get(lpfc_fcf_record_mac_3, new_fcf_record); | 1173 | /* FCF record index */ |
| 1166 | phba->fcf.mac_addr[4] = | 1174 | fcf_rec->fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); |
| 1167 | bf_get(lpfc_fcf_record_mac_4, new_fcf_record); | 1175 | /* FCF record priority */ |
| 1168 | phba->fcf.mac_addr[5] = | 1176 | fcf_rec->priority = new_fcf_record->fip_priority; |
| 1169 | bf_get(lpfc_fcf_record_mac_5, new_fcf_record); | 1177 | /* Switch name */ |
| 1170 | phba->fcf.fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); | 1178 | fcf_rec->switch_name[0] = |
| 1171 | phba->fcf.priority = new_fcf_record->fip_priority; | ||
| 1172 | phba->fcf.switch_name[0] = | ||
| 1173 | bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record); | 1179 | bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record); |
| 1174 | phba->fcf.switch_name[1] = | 1180 | fcf_rec->switch_name[1] = |
| 1175 | bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record); | 1181 | bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record); |
| 1176 | phba->fcf.switch_name[2] = | 1182 | fcf_rec->switch_name[2] = |
| 1177 | bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record); | 1183 | bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record); |
| 1178 | phba->fcf.switch_name[3] = | 1184 | fcf_rec->switch_name[3] = |
| 1179 | bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record); | 1185 | bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record); |
| 1180 | phba->fcf.switch_name[4] = | 1186 | fcf_rec->switch_name[4] = |
| 1181 | bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record); | 1187 | bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record); |
| 1182 | phba->fcf.switch_name[5] = | 1188 | fcf_rec->switch_name[5] = |
| 1183 | bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record); | 1189 | bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record); |
| 1184 | phba->fcf.switch_name[6] = | 1190 | fcf_rec->switch_name[6] = |
| 1185 | bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record); | 1191 | bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record); |
| 1186 | phba->fcf.switch_name[7] = | 1192 | fcf_rec->switch_name[7] = |
| 1187 | bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record); | 1193 | bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record); |
| 1188 | } | 1194 | } |
| 1189 | 1195 | ||
| 1190 | /** | 1196 | /** |
| 1197 | * lpfc_update_fcf_record - Update driver fcf record | ||
| 1198 | * @phba: pointer to lpfc hba data structure. | ||
| 1199 | * @fcf_rec: pointer to driver fcf record. | ||
| 1200 | * @new_fcf_record: pointer to hba fcf record. | ||
| 1201 | * @addr_mode: address mode to be set to the driver fcf record. | ||
| 1202 | * @vlan_id: vlan tag to be set to the driver fcf record. | ||
| 1203 | * @flag: flag bits to be set to the driver fcf record. | ||
| 1204 | * | ||
| 1205 | * This routine updates the driver FCF record from the new HBA FCF record | ||
| 1206 | * together with the address mode, vlan_id, and other informations. This | ||
| 1207 | * routine is called with the host lock held. | ||
| 1208 | **/ | ||
| 1209 | static void | ||
| 1210 | __lpfc_update_fcf_record(struct lpfc_hba *phba, struct lpfc_fcf_rec *fcf_rec, | ||
| 1211 | struct fcf_record *new_fcf_record, uint32_t addr_mode, | ||
| 1212 | uint16_t vlan_id, uint32_t flag) | ||
| 1213 | { | ||
| 1214 | /* Copy the fields from the HBA's FCF record */ | ||
| 1215 | lpfc_copy_fcf_record(fcf_rec, new_fcf_record); | ||
| 1216 | /* Update other fields of driver FCF record */ | ||
| 1217 | fcf_rec->addr_mode = addr_mode; | ||
| 1218 | fcf_rec->vlan_id = vlan_id; | ||
| 1219 | fcf_rec->flag |= (flag | RECORD_VALID); | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | /** | ||
| 1191 | * lpfc_register_fcf - Register the FCF with hba. | 1223 | * lpfc_register_fcf - Register the FCF with hba. |
| 1192 | * @phba: pointer to lpfc hba data structure. | 1224 | * @phba: pointer to lpfc hba data structure. |
| 1193 | * | 1225 | * |
| @@ -1212,7 +1244,7 @@ lpfc_register_fcf(struct lpfc_hba *phba) | |||
| 1212 | 1244 | ||
| 1213 | /* The FCF is already registered, start discovery */ | 1245 | /* The FCF is already registered, start discovery */ |
| 1214 | if (phba->fcf.fcf_flag & FCF_REGISTERED) { | 1246 | if (phba->fcf.fcf_flag & FCF_REGISTERED) { |
| 1215 | phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); | 1247 | phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE); |
| 1216 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1248 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
| 1217 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1249 | spin_unlock_irqrestore(&phba->hbalock, flags); |
| 1218 | if (phba->pport->port_state != LPFC_FLOGI) | 1250 | if (phba->pport->port_state != LPFC_FLOGI) |
| @@ -1250,6 +1282,7 @@ lpfc_register_fcf(struct lpfc_hba *phba) | |||
| 1250 | * @new_fcf_record: pointer to fcf record. | 1282 | * @new_fcf_record: pointer to fcf record. |
| 1251 | * @boot_flag: Indicates if this record used by boot bios. | 1283 | * @boot_flag: Indicates if this record used by boot bios. |
| 1252 | * @addr_mode: The address mode to be used by this FCF | 1284 | * @addr_mode: The address mode to be used by this FCF |
| 1285 | * @vlan_id: The vlan id to be used as vlan tagging by this FCF. | ||
| 1253 | * | 1286 | * |
| 1254 | * This routine compare the fcf record with connect list obtained from the | 1287 | * This routine compare the fcf record with connect list obtained from the |
| 1255 | * config region to decide if this FCF can be used for SAN discovery. It returns | 1288 | * config region to decide if this FCF can be used for SAN discovery. It returns |
| @@ -1323,7 +1356,8 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba, | |||
| 1323 | return 1; | 1356 | return 1; |
| 1324 | } | 1357 | } |
| 1325 | 1358 | ||
| 1326 | list_for_each_entry(conn_entry, &phba->fcf_conn_rec_list, list) { | 1359 | list_for_each_entry(conn_entry, |
| 1360 | &phba->fcf_conn_rec_list, list) { | ||
| 1327 | if (!(conn_entry->conn_rec.flags & FCFCNCT_VALID)) | 1361 | if (!(conn_entry->conn_rec.flags & FCFCNCT_VALID)) |
| 1328 | continue; | 1362 | continue; |
| 1329 | 1363 | ||
| @@ -1470,6 +1504,7 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) | |||
| 1470 | */ | 1504 | */ |
| 1471 | spin_lock_irq(&phba->hbalock); | 1505 | spin_lock_irq(&phba->hbalock); |
| 1472 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1506 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
| 1507 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | ||
| 1473 | spin_unlock_irq(&phba->hbalock); | 1508 | spin_unlock_irq(&phba->hbalock); |
| 1474 | } | 1509 | } |
| 1475 | 1510 | ||
| @@ -1524,11 +1559,12 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 1524 | uint32_t shdr_status, shdr_add_status; | 1559 | uint32_t shdr_status, shdr_add_status; |
| 1525 | union lpfc_sli4_cfg_shdr *shdr; | 1560 | union lpfc_sli4_cfg_shdr *shdr; |
| 1526 | struct fcf_record *new_fcf_record; | 1561 | struct fcf_record *new_fcf_record; |
| 1527 | int rc; | ||
| 1528 | uint32_t boot_flag, addr_mode; | 1562 | uint32_t boot_flag, addr_mode; |
| 1529 | uint32_t next_fcf_index; | 1563 | uint32_t next_fcf_index; |
| 1530 | unsigned long flags; | 1564 | struct lpfc_fcf_rec *fcf_rec = NULL; |
| 1565 | unsigned long iflags; | ||
| 1531 | uint16_t vlan_id; | 1566 | uint16_t vlan_id; |
| 1567 | int rc; | ||
| 1532 | 1568 | ||
| 1533 | /* If there is pending FCoE event restart FCF table scan */ | 1569 | /* If there is pending FCoE event restart FCF table scan */ |
| 1534 | if (lpfc_check_pending_fcoe_event(phba, 0)) { | 1570 | if (lpfc_check_pending_fcoe_event(phba, 0)) { |
| @@ -1583,9 +1619,8 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 1583 | sizeof(struct fcf_record)); | 1619 | sizeof(struct fcf_record)); |
| 1584 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | 1620 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); |
| 1585 | 1621 | ||
| 1586 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, | 1622 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, |
| 1587 | &boot_flag, &addr_mode, | 1623 | &addr_mode, &vlan_id); |
| 1588 | &vlan_id); | ||
| 1589 | /* | 1624 | /* |
| 1590 | * If the fcf record does not match with connect list entries | 1625 | * If the fcf record does not match with connect list entries |
| 1591 | * read the next entry. | 1626 | * read the next entry. |
| @@ -1594,90 +1629,159 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 1594 | goto read_next_fcf; | 1629 | goto read_next_fcf; |
| 1595 | /* | 1630 | /* |
| 1596 | * If this is not the first FCF discovery of the HBA, use last | 1631 | * If this is not the first FCF discovery of the HBA, use last |
| 1597 | * FCF record for the discovery. | 1632 | * FCF record for the discovery. The condition that a rescan |
| 1633 | * matches the in-use FCF record: fabric name, switch name, mac | ||
| 1634 | * address, and vlan_id. | ||
| 1598 | */ | 1635 | */ |
| 1599 | spin_lock_irqsave(&phba->hbalock, flags); | 1636 | spin_lock_irqsave(&phba->hbalock, iflags); |
| 1600 | if (phba->fcf.fcf_flag & FCF_IN_USE) { | 1637 | if (phba->fcf.fcf_flag & FCF_IN_USE) { |
| 1601 | if (lpfc_fab_name_match(phba->fcf.fabric_name, | 1638 | if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, |
| 1602 | new_fcf_record) && | 1639 | new_fcf_record) && |
| 1603 | lpfc_sw_name_match(phba->fcf.switch_name, | 1640 | lpfc_sw_name_match(phba->fcf.current_rec.switch_name, |
| 1604 | new_fcf_record) && | 1641 | new_fcf_record) && |
| 1605 | lpfc_mac_addr_match(phba, new_fcf_record)) { | 1642 | lpfc_mac_addr_match(phba->fcf.current_rec.mac_addr, |
| 1643 | new_fcf_record) && | ||
| 1644 | lpfc_vlan_id_match(phba->fcf.current_rec.vlan_id, | ||
| 1645 | vlan_id)) { | ||
| 1606 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | 1646 | phba->fcf.fcf_flag |= FCF_AVAILABLE; |
| 1607 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1647 | if (phba->fcf.fcf_flag & FCF_REDISC_PEND) |
| 1648 | /* Stop FCF redisc wait timer if pending */ | ||
| 1649 | __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); | ||
| 1650 | else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) | ||
| 1651 | /* If in fast failover, mark it's completed */ | ||
| 1652 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | ||
| 1653 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
| 1608 | goto out; | 1654 | goto out; |
| 1609 | } | 1655 | } |
| 1610 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1656 | /* |
| 1611 | goto read_next_fcf; | 1657 | * Read next FCF record from HBA searching for the matching |
| 1658 | * with in-use record only if not during the fast failover | ||
| 1659 | * period. In case of fast failover period, it shall try to | ||
| 1660 | * determine whether the FCF record just read should be the | ||
| 1661 | * next candidate. | ||
| 1662 | */ | ||
| 1663 | if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { | ||
| 1664 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
| 1665 | goto read_next_fcf; | ||
| 1666 | } | ||
| 1612 | } | 1667 | } |
| 1668 | /* | ||
| 1669 | * Update on failover FCF record only if it's in FCF fast-failover | ||
| 1670 | * period; otherwise, update on current FCF record. | ||
| 1671 | */ | ||
| 1672 | if (phba->fcf.fcf_flag & FCF_REDISC_FOV) { | ||
| 1673 | /* Fast FCF failover only to the same fabric name */ | ||
| 1674 | if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, | ||
| 1675 | new_fcf_record)) | ||
| 1676 | fcf_rec = &phba->fcf.failover_rec; | ||
| 1677 | else | ||
| 1678 | goto read_next_fcf; | ||
| 1679 | } else | ||
| 1680 | fcf_rec = &phba->fcf.current_rec; | ||
| 1681 | |||
| 1613 | if (phba->fcf.fcf_flag & FCF_AVAILABLE) { | 1682 | if (phba->fcf.fcf_flag & FCF_AVAILABLE) { |
| 1614 | /* | 1683 | /* |
| 1615 | * If the current FCF record does not have boot flag | 1684 | * If the driver FCF record does not have boot flag |
| 1616 | * set and new fcf record has boot flag set, use the | 1685 | * set and new hba fcf record has boot flag set, use |
| 1617 | * new fcf record. | 1686 | * the new hba fcf record. |
| 1618 | */ | 1687 | */ |
| 1619 | if (boot_flag && !(phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | 1688 | if (boot_flag && !(fcf_rec->flag & BOOT_ENABLE)) { |
| 1620 | /* Use this FCF record */ | 1689 | /* Choose this FCF record */ |
| 1621 | lpfc_copy_fcf_record(phba, new_fcf_record); | 1690 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
| 1622 | phba->fcf.addr_mode = addr_mode; | 1691 | addr_mode, vlan_id, BOOT_ENABLE); |
| 1623 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | 1692 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
| 1624 | if (vlan_id != 0xFFFF) { | ||
| 1625 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
| 1626 | phba->fcf.vlan_id = vlan_id; | ||
| 1627 | } | ||
| 1628 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
| 1629 | goto read_next_fcf; | 1693 | goto read_next_fcf; |
| 1630 | } | 1694 | } |
| 1631 | /* | 1695 | /* |
| 1632 | * If the current FCF record has boot flag set and the | 1696 | * If the driver FCF record has boot flag set and the |
| 1633 | * new FCF record does not have boot flag, read the next | 1697 | * new hba FCF record does not have boot flag, read |
| 1634 | * FCF record. | 1698 | * the next FCF record. |
| 1635 | */ | 1699 | */ |
| 1636 | if (!boot_flag && (phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | 1700 | if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) { |
| 1637 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1701 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
| 1638 | goto read_next_fcf; | 1702 | goto read_next_fcf; |
| 1639 | } | 1703 | } |
| 1640 | /* | 1704 | /* |
| 1641 | * If there is a record with lower priority value for | 1705 | * If the new hba FCF record has lower priority value |
| 1642 | * the current FCF, use that record. | 1706 | * than the driver FCF record, use the new record. |
| 1643 | */ | 1707 | */ |
| 1644 | if (lpfc_fab_name_match(phba->fcf.fabric_name, | 1708 | if (lpfc_fab_name_match(fcf_rec->fabric_name, new_fcf_record) && |
| 1645 | new_fcf_record) && | 1709 | (new_fcf_record->fip_priority < fcf_rec->priority)) { |
| 1646 | (new_fcf_record->fip_priority < phba->fcf.priority)) { | 1710 | /* Choose this FCF record */ |
| 1647 | /* Use this FCF record */ | 1711 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
| 1648 | lpfc_copy_fcf_record(phba, new_fcf_record); | 1712 | addr_mode, vlan_id, 0); |
| 1649 | phba->fcf.addr_mode = addr_mode; | ||
| 1650 | if (vlan_id != 0xFFFF) { | ||
| 1651 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
| 1652 | phba->fcf.vlan_id = vlan_id; | ||
| 1653 | } | ||
| 1654 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
| 1655 | goto read_next_fcf; | ||
| 1656 | } | 1713 | } |
| 1657 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1714 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
| 1658 | goto read_next_fcf; | 1715 | goto read_next_fcf; |
| 1659 | } | 1716 | } |
| 1660 | /* | 1717 | /* |
| 1661 | * This is the first available FCF record, use this | 1718 | * This is the first suitable FCF record, choose this record for |
| 1662 | * record. | 1719 | * initial best-fit FCF. |
| 1663 | */ | 1720 | */ |
| 1664 | lpfc_copy_fcf_record(phba, new_fcf_record); | 1721 | if (fcf_rec) { |
| 1665 | phba->fcf.addr_mode = addr_mode; | 1722 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
| 1666 | if (boot_flag) | 1723 | addr_mode, vlan_id, (boot_flag ? |
| 1667 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | 1724 | BOOT_ENABLE : 0)); |
| 1668 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | 1725 | phba->fcf.fcf_flag |= FCF_AVAILABLE; |
| 1669 | if (vlan_id != 0xFFFF) { | ||
| 1670 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
| 1671 | phba->fcf.vlan_id = vlan_id; | ||
| 1672 | } | 1726 | } |
| 1673 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1727 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
| 1674 | goto read_next_fcf; | 1728 | goto read_next_fcf; |
| 1675 | 1729 | ||
| 1676 | read_next_fcf: | 1730 | read_next_fcf: |
| 1677 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | 1731 | lpfc_sli4_mbox_cmd_free(phba, mboxq); |
| 1678 | if (next_fcf_index == LPFC_FCOE_FCF_NEXT_NONE || next_fcf_index == 0) | 1732 | if (next_fcf_index == LPFC_FCOE_FCF_NEXT_NONE || next_fcf_index == 0) { |
| 1679 | lpfc_register_fcf(phba); | 1733 | if (phba->fcf.fcf_flag & FCF_REDISC_FOV) { |
| 1680 | else | 1734 | /* |
| 1735 | * Case of FCF fast failover scan | ||
| 1736 | */ | ||
| 1737 | |||
| 1738 | /* | ||
| 1739 | * It has not found any suitable FCF record, cancel | ||
| 1740 | * FCF scan inprogress, and do nothing | ||
| 1741 | */ | ||
| 1742 | if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) { | ||
| 1743 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
| 1744 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | ||
| 1745 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
| 1746 | return; | ||
| 1747 | } | ||
| 1748 | /* | ||
| 1749 | * It has found a suitable FCF record that is not | ||
| 1750 | * the same as in-use FCF record, unregister the | ||
| 1751 | * in-use FCF record, replace the in-use FCF record | ||
| 1752 | * with the new FCF record, mark FCF fast failover | ||
| 1753 | * completed, and then start register the new FCF | ||
| 1754 | * record. | ||
| 1755 | */ | ||
| 1756 | |||
| 1757 | /* unregister the current in-use FCF record */ | ||
| 1758 | lpfc_unregister_fcf(phba); | ||
| 1759 | /* replace in-use record with the new record */ | ||
| 1760 | memcpy(&phba->fcf.current_rec, | ||
| 1761 | &phba->fcf.failover_rec, | ||
| 1762 | sizeof(struct lpfc_fcf_rec)); | ||
| 1763 | /* mark the FCF fast failover completed */ | ||
| 1764 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
| 1765 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | ||
| 1766 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
| 1767 | /* Register to the new FCF record */ | ||
| 1768 | lpfc_register_fcf(phba); | ||
| 1769 | } else { | ||
| 1770 | /* | ||
| 1771 | * In case of transaction period to fast FCF failover, | ||
| 1772 | * do nothing when search to the end of the FCF table. | ||
| 1773 | */ | ||
| 1774 | if ((phba->fcf.fcf_flag & FCF_REDISC_EVT) || | ||
| 1775 | (phba->fcf.fcf_flag & FCF_REDISC_PEND)) | ||
| 1776 | return; | ||
| 1777 | /* | ||
| 1778 | * Otherwise, initial scan or post linkdown rescan, | ||
| 1779 | * register with the best fit FCF record found so | ||
| 1780 | * far through the scanning process. | ||
| 1781 | */ | ||
| 1782 | lpfc_register_fcf(phba); | ||
| 1783 | } | ||
| 1784 | } else | ||
| 1681 | lpfc_sli4_read_fcf_record(phba, next_fcf_index); | 1785 | lpfc_sli4_read_fcf_record(phba, next_fcf_index); |
| 1682 | return; | 1786 | return; |
| 1683 | 1787 | ||
| @@ -1695,10 +1799,13 @@ out: | |||
| 1695 | * | 1799 | * |
| 1696 | * This function handles completion of init vpi mailbox command. | 1800 | * This function handles completion of init vpi mailbox command. |
| 1697 | */ | 1801 | */ |
| 1698 | static void | 1802 | void |
| 1699 | lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | 1803 | lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) |
| 1700 | { | 1804 | { |
| 1701 | struct lpfc_vport *vport = mboxq->vport; | 1805 | struct lpfc_vport *vport = mboxq->vport; |
| 1806 | struct lpfc_nodelist *ndlp; | ||
| 1807 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
| 1808 | |||
| 1702 | if (mboxq->u.mb.mbxStatus) { | 1809 | if (mboxq->u.mb.mbxStatus) { |
| 1703 | lpfc_printf_vlog(vport, KERN_ERR, | 1810 | lpfc_printf_vlog(vport, KERN_ERR, |
| 1704 | LOG_MBOX, | 1811 | LOG_MBOX, |
| @@ -1708,9 +1815,23 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 1708 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 1815 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
| 1709 | return; | 1816 | return; |
| 1710 | } | 1817 | } |
| 1711 | spin_lock_irq(&phba->hbalock); | 1818 | spin_lock_irq(shost->host_lock); |
| 1712 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; | 1819 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; |
| 1713 | spin_unlock_irq(&phba->hbalock); | 1820 | spin_unlock_irq(shost->host_lock); |
| 1821 | |||
| 1822 | /* If this port is physical port or FDISC is done, do reg_vpi */ | ||
| 1823 | if ((phba->pport == vport) || (vport->port_state == LPFC_FDISC)) { | ||
| 1824 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | ||
| 1825 | if (!ndlp) | ||
| 1826 | lpfc_printf_vlog(vport, KERN_ERR, | ||
| 1827 | LOG_DISCOVERY, | ||
| 1828 | "2731 Cannot find fabric " | ||
| 1829 | "controller node\n"); | ||
| 1830 | else | ||
| 1831 | lpfc_register_new_vport(phba, vport, ndlp); | ||
| 1832 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
| 1833 | return; | ||
| 1834 | } | ||
| 1714 | 1835 | ||
| 1715 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1836 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
| 1716 | lpfc_initial_fdisc(vport); | 1837 | lpfc_initial_fdisc(vport); |
| @@ -1719,10 +1840,42 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 1719 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 1840 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
| 1720 | "2606 No NPIV Fabric support\n"); | 1841 | "2606 No NPIV Fabric support\n"); |
| 1721 | } | 1842 | } |
| 1843 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
| 1722 | return; | 1844 | return; |
| 1723 | } | 1845 | } |
| 1724 | 1846 | ||
| 1725 | /** | 1847 | /** |
| 1848 | * lpfc_issue_init_vpi - Issue init_vpi mailbox command. | ||
| 1849 | * @vport: pointer to lpfc_vport data structure. | ||
| 1850 | * | ||
| 1851 | * This function issue a init_vpi mailbox command to initialize | ||
| 1852 | * VPI for the vport. | ||
| 1853 | */ | ||
| 1854 | void | ||
| 1855 | lpfc_issue_init_vpi(struct lpfc_vport *vport) | ||
| 1856 | { | ||
| 1857 | LPFC_MBOXQ_t *mboxq; | ||
| 1858 | int rc; | ||
| 1859 | |||
| 1860 | mboxq = mempool_alloc(vport->phba->mbox_mem_pool, GFP_KERNEL); | ||
| 1861 | if (!mboxq) { | ||
| 1862 | lpfc_printf_vlog(vport, KERN_ERR, | ||
| 1863 | LOG_MBOX, "2607 Failed to allocate " | ||
| 1864 | "init_vpi mailbox\n"); | ||
| 1865 | return; | ||
| 1866 | } | ||
| 1867 | lpfc_init_vpi(vport->phba, mboxq, vport->vpi); | ||
| 1868 | mboxq->vport = vport; | ||
| 1869 | mboxq->mbox_cmpl = lpfc_init_vpi_cmpl; | ||
| 1870 | rc = lpfc_sli_issue_mbox(vport->phba, mboxq, MBX_NOWAIT); | ||
| 1871 | if (rc == MBX_NOT_FINISHED) { | ||
| 1872 | lpfc_printf_vlog(vport, KERN_ERR, | ||
| 1873 | LOG_MBOX, "2608 Failed to issue init_vpi mailbox\n"); | ||
| 1874 | mempool_free(mboxq, vport->phba->mbox_mem_pool); | ||
| 1875 | } | ||
| 1876 | } | ||
| 1877 | |||
| 1878 | /** | ||
| 1726 | * lpfc_start_fdiscs - send fdiscs for each vports on this port. | 1879 | * lpfc_start_fdiscs - send fdiscs for each vports on this port. |
| 1727 | * @phba: pointer to lpfc hba data structure. | 1880 | * @phba: pointer to lpfc hba data structure. |
| 1728 | * | 1881 | * |
| @@ -1734,8 +1887,6 @@ lpfc_start_fdiscs(struct lpfc_hba *phba) | |||
| 1734 | { | 1887 | { |
| 1735 | struct lpfc_vport **vports; | 1888 | struct lpfc_vport **vports; |
| 1736 | int i; | 1889 | int i; |
| 1737 | LPFC_MBOXQ_t *mboxq; | ||
| 1738 | int rc; | ||
| 1739 | 1890 | ||
| 1740 | vports = lpfc_create_vport_work_array(phba); | 1891 | vports = lpfc_create_vport_work_array(phba); |
| 1741 | if (vports != NULL) { | 1892 | if (vports != NULL) { |
| @@ -1754,26 +1905,7 @@ lpfc_start_fdiscs(struct lpfc_hba *phba) | |||
| 1754 | continue; | 1905 | continue; |
| 1755 | } | 1906 | } |
| 1756 | if (vports[i]->fc_flag & FC_VPORT_NEEDS_INIT_VPI) { | 1907 | if (vports[i]->fc_flag & FC_VPORT_NEEDS_INIT_VPI) { |
| 1757 | mboxq = mempool_alloc(phba->mbox_mem_pool, | 1908 | lpfc_issue_init_vpi(vports[i]); |
| 1758 | GFP_KERNEL); | ||
| 1759 | if (!mboxq) { | ||
| 1760 | lpfc_printf_vlog(vports[i], KERN_ERR, | ||
| 1761 | LOG_MBOX, "2607 Failed to allocate " | ||
| 1762 | "init_vpi mailbox\n"); | ||
| 1763 | continue; | ||
| 1764 | } | ||
| 1765 | lpfc_init_vpi(phba, mboxq, vports[i]->vpi); | ||
| 1766 | mboxq->vport = vports[i]; | ||
| 1767 | mboxq->mbox_cmpl = lpfc_init_vpi_cmpl; | ||
| 1768 | rc = lpfc_sli_issue_mbox(phba, mboxq, | ||
| 1769 | MBX_NOWAIT); | ||
| 1770 | if (rc == MBX_NOT_FINISHED) { | ||
| 1771 | lpfc_printf_vlog(vports[i], KERN_ERR, | ||
| 1772 | LOG_MBOX, "2608 Failed to issue " | ||
| 1773 | "init_vpi mailbox\n"); | ||
| 1774 | mempool_free(mboxq, | ||
| 1775 | phba->mbox_mem_pool); | ||
| 1776 | } | ||
| 1777 | continue; | 1909 | continue; |
| 1778 | } | 1910 | } |
| 1779 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1911 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
| @@ -1796,6 +1928,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 1796 | { | 1928 | { |
| 1797 | struct lpfc_dmabuf *dmabuf = mboxq->context1; | 1929 | struct lpfc_dmabuf *dmabuf = mboxq->context1; |
| 1798 | struct lpfc_vport *vport = mboxq->vport; | 1930 | struct lpfc_vport *vport = mboxq->vport; |
| 1931 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
| 1799 | 1932 | ||
| 1800 | if (mboxq->u.mb.mbxStatus) { | 1933 | if (mboxq->u.mb.mbxStatus) { |
| 1801 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 1934 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
| @@ -1813,7 +1946,11 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 1813 | goto fail_free_mem; | 1946 | goto fail_free_mem; |
| 1814 | } | 1947 | } |
| 1815 | /* The VPI is implicitly registered when the VFI is registered */ | 1948 | /* The VPI is implicitly registered when the VFI is registered */ |
| 1949 | spin_lock_irq(shost->host_lock); | ||
| 1816 | vport->vpi_state |= LPFC_VPI_REGISTERED; | 1950 | vport->vpi_state |= LPFC_VPI_REGISTERED; |
| 1951 | vport->fc_flag |= FC_VFI_REGISTERED; | ||
| 1952 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | ||
| 1953 | spin_unlock_irq(shost->host_lock); | ||
| 1817 | 1954 | ||
| 1818 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { | 1955 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { |
| 1819 | lpfc_start_fdiscs(phba); | 1956 | lpfc_start_fdiscs(phba); |
| @@ -2050,8 +2187,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
| 2050 | return; | 2187 | return; |
| 2051 | } | 2188 | } |
| 2052 | spin_unlock_irq(&phba->hbalock); | 2189 | spin_unlock_irq(&phba->hbalock); |
| 2053 | rc = lpfc_sli4_read_fcf_record(phba, | 2190 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); |
| 2054 | LPFC_FCOE_FCF_GET_FIRST); | ||
| 2055 | if (rc) | 2191 | if (rc) |
| 2056 | goto out; | 2192 | goto out; |
| 2057 | } | 2193 | } |
| @@ -2139,10 +2275,12 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
| 2139 | } | 2275 | } |
| 2140 | 2276 | ||
| 2141 | phba->fc_eventTag = la->eventTag; | 2277 | phba->fc_eventTag = la->eventTag; |
| 2278 | spin_lock_irq(&phba->hbalock); | ||
| 2142 | if (la->mm) | 2279 | if (la->mm) |
| 2143 | phba->sli.sli_flag |= LPFC_MENLO_MAINT; | 2280 | phba->sli.sli_flag |= LPFC_MENLO_MAINT; |
| 2144 | else | 2281 | else |
| 2145 | phba->sli.sli_flag &= ~LPFC_MENLO_MAINT; | 2282 | phba->sli.sli_flag &= ~LPFC_MENLO_MAINT; |
| 2283 | spin_unlock_irq(&phba->hbalock); | ||
| 2146 | 2284 | ||
| 2147 | phba->link_events++; | 2285 | phba->link_events++; |
| 2148 | if (la->attType == AT_LINK_UP && (!la->mm)) { | 2286 | if (la->attType == AT_LINK_UP && (!la->mm)) { |
| @@ -2271,10 +2409,10 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
| 2271 | mb->mbxStatus); | 2409 | mb->mbxStatus); |
| 2272 | break; | 2410 | break; |
| 2273 | } | 2411 | } |
| 2274 | spin_lock_irq(&phba->hbalock); | 2412 | spin_lock_irq(shost->host_lock); |
| 2275 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; | 2413 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; |
| 2276 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 2414 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
| 2277 | spin_unlock_irq(&phba->hbalock); | 2415 | spin_unlock_irq(shost->host_lock); |
| 2278 | vport->unreg_vpi_cmpl = VPORT_OK; | 2416 | vport->unreg_vpi_cmpl = VPORT_OK; |
| 2279 | mempool_free(pmb, phba->mbox_mem_pool); | 2417 | mempool_free(pmb, phba->mbox_mem_pool); |
| 2280 | /* | 2418 | /* |
| @@ -2332,7 +2470,10 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
| 2332 | goto out; | 2470 | goto out; |
| 2333 | } | 2471 | } |
| 2334 | 2472 | ||
| 2473 | spin_lock_irq(shost->host_lock); | ||
| 2335 | vport->vpi_state |= LPFC_VPI_REGISTERED; | 2474 | vport->vpi_state |= LPFC_VPI_REGISTERED; |
| 2475 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | ||
| 2476 | spin_unlock_irq(shost->host_lock); | ||
| 2336 | vport->num_disc_nodes = 0; | 2477 | vport->num_disc_nodes = 0; |
| 2337 | /* go thru NPR list and issue ELS PLOGIs */ | 2478 | /* go thru NPR list and issue ELS PLOGIs */ |
| 2338 | if (vport->fc_npr_cnt) | 2479 | if (vport->fc_npr_cnt) |
| @@ -3218,6 +3359,34 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
| 3218 | return 0; | 3359 | return 0; |
| 3219 | } | 3360 | } |
| 3220 | 3361 | ||
| 3362 | /** | ||
| 3363 | * lpfc_unreg_hba_rpis - Unregister rpis registered to the hba. | ||
| 3364 | * @phba: pointer to lpfc hba data structure. | ||
| 3365 | * | ||
| 3366 | * This routine is invoked to unregister all the currently registered RPIs | ||
| 3367 | * to the HBA. | ||
| 3368 | **/ | ||
| 3369 | void | ||
| 3370 | lpfc_unreg_hba_rpis(struct lpfc_hba *phba) | ||
| 3371 | { | ||
| 3372 | struct lpfc_vport **vports; | ||
| 3373 | struct lpfc_nodelist *ndlp; | ||
| 3374 | struct Scsi_Host *shost; | ||
| 3375 | int i; | ||
| 3376 | |||
| 3377 | vports = lpfc_create_vport_work_array(phba); | ||
| 3378 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
| 3379 | shost = lpfc_shost_from_vport(vports[i]); | ||
| 3380 | spin_lock_irq(shost->host_lock); | ||
| 3381 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { | ||
| 3382 | if (ndlp->nlp_flag & NLP_RPI_VALID) | ||
| 3383 | lpfc_unreg_rpi(vports[i], ndlp); | ||
| 3384 | } | ||
| 3385 | spin_unlock_irq(shost->host_lock); | ||
| 3386 | } | ||
| 3387 | lpfc_destroy_vport_work_array(phba, vports); | ||
| 3388 | } | ||
| 3389 | |||
| 3221 | void | 3390 | void |
| 3222 | lpfc_unreg_all_rpis(struct lpfc_vport *vport) | 3391 | lpfc_unreg_all_rpis(struct lpfc_vport *vport) |
| 3223 | { | 3392 | { |
| @@ -4448,63 +4617,56 @@ lpfc_unregister_fcfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 4448 | } | 4617 | } |
| 4449 | 4618 | ||
| 4450 | /** | 4619 | /** |
| 4451 | * lpfc_unregister_unused_fcf - Unregister FCF if all devices are disconnected. | 4620 | * lpfc_unregister_fcf_prep - Unregister fcf record preparation |
| 4452 | * @phba: Pointer to hba context object. | 4621 | * @phba: Pointer to hba context object. |
| 4453 | * | 4622 | * |
| 4454 | * This function check if there are any connected remote port for the FCF and | 4623 | * This function prepare the HBA for unregistering the currently registered |
| 4455 | * if all the devices are disconnected, this function unregister FCFI. | 4624 | * FCF from the HBA. It performs unregistering, in order, RPIs, VPIs, and |
| 4456 | * This function also tries to use another FCF for discovery. | 4625 | * VFIs. |
| 4457 | */ | 4626 | */ |
| 4458 | void | 4627 | int |
| 4459 | lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | 4628 | lpfc_unregister_fcf_prep(struct lpfc_hba *phba) |
| 4460 | { | 4629 | { |
| 4461 | LPFC_MBOXQ_t *mbox; | 4630 | LPFC_MBOXQ_t *mbox; |
| 4462 | int rc; | ||
| 4463 | struct lpfc_vport **vports; | 4631 | struct lpfc_vport **vports; |
| 4464 | int i; | 4632 | struct lpfc_nodelist *ndlp; |
| 4465 | 4633 | struct Scsi_Host *shost; | |
| 4466 | spin_lock_irq(&phba->hbalock); | 4634 | int i, rc; |
| 4467 | /* | ||
| 4468 | * If HBA is not running in FIP mode or | ||
| 4469 | * If HBA does not support FCoE or | ||
| 4470 | * If FCF is not registered. | ||
| 4471 | * do nothing. | ||
| 4472 | */ | ||
| 4473 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT) || | ||
| 4474 | !(phba->fcf.fcf_flag & FCF_REGISTERED) || | ||
| 4475 | (!(phba->hba_flag & HBA_FIP_SUPPORT))) { | ||
| 4476 | spin_unlock_irq(&phba->hbalock); | ||
| 4477 | return; | ||
| 4478 | } | ||
| 4479 | spin_unlock_irq(&phba->hbalock); | ||
| 4480 | 4635 | ||
| 4636 | /* Unregister RPIs */ | ||
| 4481 | if (lpfc_fcf_inuse(phba)) | 4637 | if (lpfc_fcf_inuse(phba)) |
| 4482 | return; | 4638 | lpfc_unreg_hba_rpis(phba); |
| 4483 | 4639 | ||
| 4484 | /* At this point, all discovery is aborted */ | 4640 | /* At this point, all discovery is aborted */ |
| 4485 | phba->pport->port_state = LPFC_VPORT_UNKNOWN; | 4641 | phba->pport->port_state = LPFC_VPORT_UNKNOWN; |
| 4486 | 4642 | ||
| 4487 | /* Unregister VPIs */ | 4643 | /* Unregister VPIs */ |
| 4488 | vports = lpfc_create_vport_work_array(phba); | 4644 | vports = lpfc_create_vport_work_array(phba); |
| 4489 | if (vports && | 4645 | if (vports && (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) |
| 4490 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) | ||
| 4491 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | 4646 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
| 4647 | /* Stop FLOGI/FDISC retries */ | ||
| 4648 | ndlp = lpfc_findnode_did(vports[i], Fabric_DID); | ||
| 4649 | if (ndlp) | ||
| 4650 | lpfc_cancel_retry_delay_tmo(vports[i], ndlp); | ||
| 4492 | lpfc_mbx_unreg_vpi(vports[i]); | 4651 | lpfc_mbx_unreg_vpi(vports[i]); |
| 4493 | spin_lock_irq(&phba->hbalock); | 4652 | shost = lpfc_shost_from_vport(vports[i]); |
| 4653 | spin_lock_irq(shost->host_lock); | ||
| 4494 | vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | 4654 | vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; |
| 4495 | vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; | 4655 | vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; |
| 4496 | spin_unlock_irq(&phba->hbalock); | 4656 | spin_unlock_irq(shost->host_lock); |
| 4497 | } | 4657 | } |
| 4498 | lpfc_destroy_vport_work_array(phba, vports); | 4658 | lpfc_destroy_vport_work_array(phba, vports); |
| 4499 | 4659 | ||
| 4660 | /* Cleanup any outstanding ELS commands */ | ||
| 4661 | lpfc_els_flush_all_cmd(phba); | ||
| 4662 | |||
| 4500 | /* Unregister VFI */ | 4663 | /* Unregister VFI */ |
| 4501 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4664 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
| 4502 | if (!mbox) { | 4665 | if (!mbox) { |
| 4503 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4666 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
| 4504 | "2556 UNREG_VFI mbox allocation failed" | 4667 | "2556 UNREG_VFI mbox allocation failed" |
| 4505 | "HBA state x%x\n", | 4668 | "HBA state x%x\n", phba->pport->port_state); |
| 4506 | phba->pport->port_state); | 4669 | return -ENOMEM; |
| 4507 | return; | ||
| 4508 | } | 4670 | } |
| 4509 | 4671 | ||
| 4510 | lpfc_unreg_vfi(mbox, phba->pport); | 4672 | lpfc_unreg_vfi(mbox, phba->pport); |
| @@ -4514,58 +4676,163 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | |||
| 4514 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 4676 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
| 4515 | if (rc == MBX_NOT_FINISHED) { | 4677 | if (rc == MBX_NOT_FINISHED) { |
| 4516 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4678 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
| 4517 | "2557 UNREG_VFI issue mbox failed rc x%x " | 4679 | "2557 UNREG_VFI issue mbox failed rc x%x " |
| 4518 | "HBA state x%x\n", | 4680 | "HBA state x%x\n", |
| 4519 | rc, phba->pport->port_state); | 4681 | rc, phba->pport->port_state); |
| 4520 | mempool_free(mbox, phba->mbox_mem_pool); | 4682 | mempool_free(mbox, phba->mbox_mem_pool); |
| 4521 | return; | 4683 | return -EIO; |
| 4522 | } | 4684 | } |
| 4523 | 4685 | ||
| 4524 | /* Unregister FCF */ | 4686 | shost = lpfc_shost_from_vport(phba->pport); |
| 4687 | spin_lock_irq(shost->host_lock); | ||
| 4688 | phba->pport->fc_flag &= ~FC_VFI_REGISTERED; | ||
| 4689 | spin_unlock_irq(shost->host_lock); | ||
| 4690 | |||
| 4691 | return 0; | ||
| 4692 | } | ||
| 4693 | |||
| 4694 | /** | ||
| 4695 | * lpfc_sli4_unregister_fcf - Unregister currently registered FCF record | ||
| 4696 | * @phba: Pointer to hba context object. | ||
| 4697 | * | ||
| 4698 | * This function issues synchronous unregister FCF mailbox command to HBA to | ||
| 4699 | * unregister the currently registered FCF record. The driver does not reset | ||
| 4700 | * the driver FCF usage state flags. | ||
| 4701 | * | ||
| 4702 | * Return 0 if successfully issued, none-zero otherwise. | ||
| 4703 | */ | ||
| 4704 | int | ||
| 4705 | lpfc_sli4_unregister_fcf(struct lpfc_hba *phba) | ||
| 4706 | { | ||
| 4707 | LPFC_MBOXQ_t *mbox; | ||
| 4708 | int rc; | ||
| 4709 | |||
| 4525 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4710 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
| 4526 | if (!mbox) { | 4711 | if (!mbox) { |
| 4527 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4712 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
| 4528 | "2551 UNREG_FCFI mbox allocation failed" | 4713 | "2551 UNREG_FCFI mbox allocation failed" |
| 4529 | "HBA state x%x\n", | 4714 | "HBA state x%x\n", phba->pport->port_state); |
| 4530 | phba->pport->port_state); | 4715 | return -ENOMEM; |
| 4531 | return; | ||
| 4532 | } | 4716 | } |
| 4533 | |||
| 4534 | lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); | 4717 | lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); |
| 4535 | mbox->vport = phba->pport; | 4718 | mbox->vport = phba->pport; |
| 4536 | mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; | 4719 | mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; |
| 4537 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 4720 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
| 4538 | 4721 | ||
| 4539 | if (rc == MBX_NOT_FINISHED) { | 4722 | if (rc == MBX_NOT_FINISHED) { |
| 4540 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4723 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
| 4541 | "2552 UNREG_FCFI issue mbox failed rc x%x " | 4724 | "2552 Unregister FCFI command failed rc x%x " |
| 4542 | "HBA state x%x\n", | 4725 | "HBA state x%x\n", |
| 4543 | rc, phba->pport->port_state); | 4726 | rc, phba->pport->port_state); |
| 4544 | mempool_free(mbox, phba->mbox_mem_pool); | 4727 | return -EINVAL; |
| 4728 | } | ||
| 4729 | return 0; | ||
| 4730 | } | ||
| 4731 | |||
| 4732 | /** | ||
| 4733 | * lpfc_unregister_fcf_rescan - Unregister currently registered fcf and rescan | ||
| 4734 | * @phba: Pointer to hba context object. | ||
| 4735 | * | ||
| 4736 | * This function unregisters the currently reigstered FCF. This function | ||
| 4737 | * also tries to find another FCF for discovery by rescan the HBA FCF table. | ||
| 4738 | */ | ||
| 4739 | void | ||
| 4740 | lpfc_unregister_fcf_rescan(struct lpfc_hba *phba) | ||
| 4741 | { | ||
| 4742 | int rc; | ||
| 4743 | |||
| 4744 | /* Preparation for unregistering fcf */ | ||
| 4745 | rc = lpfc_unregister_fcf_prep(phba); | ||
| 4746 | if (rc) { | ||
| 4747 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | ||
| 4748 | "2748 Failed to prepare for unregistering " | ||
| 4749 | "HBA's FCF record: rc=%d\n", rc); | ||
| 4545 | return; | 4750 | return; |
| 4546 | } | 4751 | } |
| 4547 | 4752 | ||
| 4548 | spin_lock_irq(&phba->hbalock); | 4753 | /* Now, unregister FCF record and reset HBA FCF state */ |
| 4549 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_REGISTERED | | 4754 | rc = lpfc_sli4_unregister_fcf(phba); |
| 4550 | FCF_DISCOVERED | FCF_BOOT_ENABLE | FCF_IN_USE | | 4755 | if (rc) |
| 4551 | FCF_VALID_VLAN); | 4756 | return; |
| 4552 | spin_unlock_irq(&phba->hbalock); | 4757 | /* Reset HBA FCF states after successful unregister FCF */ |
| 4758 | phba->fcf.fcf_flag = 0; | ||
| 4553 | 4759 | ||
| 4554 | /* | 4760 | /* |
| 4555 | * If driver is not unloading, check if there is any other | 4761 | * If driver is not unloading, check if there is any other |
| 4556 | * FCF record that can be used for discovery. | 4762 | * FCF record that can be used for discovery. |
| 4557 | */ | 4763 | */ |
| 4558 | if ((phba->pport->load_flag & FC_UNLOADING) || | 4764 | if ((phba->pport->load_flag & FC_UNLOADING) || |
| 4559 | (phba->link_state < LPFC_LINK_UP)) | 4765 | (phba->link_state < LPFC_LINK_UP)) |
| 4560 | return; | 4766 | return; |
| 4561 | 4767 | ||
| 4562 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | 4768 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); |
| 4563 | 4769 | ||
| 4564 | if (rc) | 4770 | if (rc) |
| 4565 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4771 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
| 4566 | "2553 lpfc_unregister_unused_fcf failed to read FCF" | 4772 | "2553 lpfc_unregister_unused_fcf failed " |
| 4567 | " record HBA state x%x\n", | 4773 | "to read FCF record HBA state x%x\n", |
| 4568 | phba->pport->port_state); | 4774 | phba->pport->port_state); |
| 4775 | } | ||
| 4776 | |||
| 4777 | /** | ||
| 4778 | * lpfc_unregister_fcf - Unregister the currently registered fcf record | ||
| 4779 | * @phba: Pointer to hba context object. | ||
| 4780 | * | ||
| 4781 | * This function just unregisters the currently reigstered FCF. It does not | ||
| 4782 | * try to find another FCF for discovery. | ||
| 4783 | */ | ||
| 4784 | void | ||
| 4785 | lpfc_unregister_fcf(struct lpfc_hba *phba) | ||
| 4786 | { | ||
| 4787 | int rc; | ||
| 4788 | |||
| 4789 | /* Preparation for unregistering fcf */ | ||
| 4790 | rc = lpfc_unregister_fcf_prep(phba); | ||
| 4791 | if (rc) { | ||
| 4792 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | ||
| 4793 | "2749 Failed to prepare for unregistering " | ||
| 4794 | "HBA's FCF record: rc=%d\n", rc); | ||
| 4795 | return; | ||
| 4796 | } | ||
| 4797 | |||
| 4798 | /* Now, unregister FCF record and reset HBA FCF state */ | ||
| 4799 | rc = lpfc_sli4_unregister_fcf(phba); | ||
| 4800 | if (rc) | ||
| 4801 | return; | ||
| 4802 | /* Set proper HBA FCF states after successful unregister FCF */ | ||
| 4803 | spin_lock_irq(&phba->hbalock); | ||
| 4804 | phba->fcf.fcf_flag &= ~FCF_REGISTERED; | ||
| 4805 | spin_unlock_irq(&phba->hbalock); | ||
| 4806 | } | ||
| 4807 | |||
| 4808 | /** | ||
| 4809 | * lpfc_unregister_unused_fcf - Unregister FCF if all devices are disconnected. | ||
| 4810 | * @phba: Pointer to hba context object. | ||
| 4811 | * | ||
| 4812 | * This function check if there are any connected remote port for the FCF and | ||
| 4813 | * if all the devices are disconnected, this function unregister FCFI. | ||
| 4814 | * This function also tries to use another FCF for discovery. | ||
| 4815 | */ | ||
| 4816 | void | ||
| 4817 | lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | ||
| 4818 | { | ||
| 4819 | /* | ||
| 4820 | * If HBA is not running in FIP mode or if HBA does not support | ||
| 4821 | * FCoE or if FCF is not registered, do nothing. | ||
| 4822 | */ | ||
| 4823 | spin_lock_irq(&phba->hbalock); | ||
| 4824 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT) || | ||
| 4825 | !(phba->fcf.fcf_flag & FCF_REGISTERED) || | ||
| 4826 | !(phba->hba_flag & HBA_FIP_SUPPORT)) { | ||
| 4827 | spin_unlock_irq(&phba->hbalock); | ||
| 4828 | return; | ||
| 4829 | } | ||
| 4830 | spin_unlock_irq(&phba->hbalock); | ||
| 4831 | |||
| 4832 | if (lpfc_fcf_inuse(phba)) | ||
| 4833 | return; | ||
| 4834 | |||
| 4835 | lpfc_unregister_fcf_rescan(phba); | ||
| 4569 | } | 4836 | } |
| 4570 | 4837 | ||
| 4571 | /** | 4838 | /** |
