diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 672 |
1 files changed, 446 insertions, 226 deletions
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 | /** |