diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-05-22 14:52:59 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-06-08 12:25:24 -0400 |
commit | 6fb120a7ed882aae9636545142a51cf3182a3ace (patch) | |
tree | 7e830b09907286288f20f60c0f104d5fbec9998d /drivers/scsi/lpfc/lpfc_hbadisc.c | |
parent | 04c684968487eb4f98728363a97b8da48f3bb958 (diff) |
[SCSI] lpfc 8.3.2 : Addition of SLI4 Interface - FCOE Discovery support
SLI4 supports both FC and FCOE, with some extended topology objects.
This patch adss support for the objects, and updates the disovery
engines for their use.
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 1055 |
1 files changed, 1040 insertions, 15 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 2270d9a7c8e3..9bd7a8927a34 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -275,6 +275,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
275 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && | 275 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
276 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) | 276 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) |
277 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); | 277 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); |
278 | |||
279 | lpfc_unregister_unused_fcf(phba); | ||
278 | } | 280 | } |
279 | 281 | ||
280 | /** | 282 | /** |
@@ -297,10 +299,11 @@ lpfc_alloc_fast_evt(struct lpfc_hba *phba) { | |||
297 | 299 | ||
298 | ret = kzalloc(sizeof(struct lpfc_fast_path_event), | 300 | ret = kzalloc(sizeof(struct lpfc_fast_path_event), |
299 | GFP_ATOMIC); | 301 | GFP_ATOMIC); |
300 | if (ret) | 302 | if (ret) { |
301 | atomic_inc(&phba->fast_event_count); | 303 | atomic_inc(&phba->fast_event_count); |
302 | INIT_LIST_HEAD(&ret->work_evt.evt_listp); | 304 | INIT_LIST_HEAD(&ret->work_evt.evt_listp); |
303 | ret->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT; | 305 | ret->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT; |
306 | } | ||
304 | return ret; | 307 | return ret; |
305 | } | 308 | } |
306 | 309 | ||
@@ -741,6 +744,7 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
741 | if (phba->link_state == LPFC_LINK_DOWN) | 744 | if (phba->link_state == LPFC_LINK_DOWN) |
742 | return 0; | 745 | return 0; |
743 | spin_lock_irq(&phba->hbalock); | 746 | spin_lock_irq(&phba->hbalock); |
747 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); | ||
744 | if (phba->link_state > LPFC_LINK_DOWN) { | 748 | if (phba->link_state > LPFC_LINK_DOWN) { |
745 | phba->link_state = LPFC_LINK_DOWN; | 749 | phba->link_state = LPFC_LINK_DOWN; |
746 | phba->pport->fc_flag &= ~FC_LBIT; | 750 | phba->pport->fc_flag &= ~FC_LBIT; |
@@ -748,7 +752,7 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
748 | spin_unlock_irq(&phba->hbalock); | 752 | spin_unlock_irq(&phba->hbalock); |
749 | vports = lpfc_create_vport_work_array(phba); | 753 | vports = lpfc_create_vport_work_array(phba); |
750 | if (vports != NULL) | 754 | if (vports != NULL) |
751 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | 755 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
752 | /* Issue a LINK DOWN event to all nodes */ | 756 | /* Issue a LINK DOWN event to all nodes */ |
753 | lpfc_linkdown_port(vports[i]); | 757 | lpfc_linkdown_port(vports[i]); |
754 | } | 758 | } |
@@ -858,10 +862,11 @@ lpfc_linkup(struct lpfc_hba *phba) | |||
858 | 862 | ||
859 | vports = lpfc_create_vport_work_array(phba); | 863 | vports = lpfc_create_vport_work_array(phba); |
860 | if (vports != NULL) | 864 | if (vports != NULL) |
861 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) | 865 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) |
862 | lpfc_linkup_port(vports[i]); | 866 | lpfc_linkup_port(vports[i]); |
863 | lpfc_destroy_vport_work_array(phba, vports); | 867 | lpfc_destroy_vport_work_array(phba, vports); |
864 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) | 868 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && |
869 | (phba->sli_rev < LPFC_SLI_REV4)) | ||
865 | lpfc_issue_clear_la(phba, phba->pport); | 870 | lpfc_issue_clear_la(phba, phba->pport); |
866 | 871 | ||
867 | return 0; | 872 | return 0; |
@@ -984,9 +989,592 @@ out: | |||
984 | } | 989 | } |
985 | 990 | ||
986 | static void | 991 | static void |
992 | lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
993 | { | ||
994 | struct lpfc_vport *vport = mboxq->vport; | ||
995 | unsigned long flags; | ||
996 | |||
997 | if (mboxq->u.mb.mbxStatus) { | ||
998 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | ||
999 | "2017 REG_FCFI mbxStatus error x%x " | ||
1000 | "HBA state x%x\n", | ||
1001 | mboxq->u.mb.mbxStatus, vport->port_state); | ||
1002 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1003 | return; | ||
1004 | } | ||
1005 | |||
1006 | /* Start FCoE discovery by sending a FLOGI. */ | ||
1007 | phba->fcf.fcfi = bf_get(lpfc_reg_fcfi_fcfi, &mboxq->u.mqe.un.reg_fcfi); | ||
1008 | /* Set the FCFI registered flag */ | ||
1009 | spin_lock_irqsave(&phba->hbalock, flags); | ||
1010 | phba->fcf.fcf_flag |= FCF_REGISTERED; | ||
1011 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1012 | if (vport->port_state != LPFC_FLOGI) { | ||
1013 | spin_lock_irqsave(&phba->hbalock, flags); | ||
1014 | phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); | ||
1015 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1016 | lpfc_initial_flogi(vport); | ||
1017 | } | ||
1018 | |||
1019 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1020 | return; | ||
1021 | } | ||
1022 | |||
1023 | /** | ||
1024 | * lpfc_fab_name_match - Check if the fcf fabric name match. | ||
1025 | * @fab_name: pointer to fabric name. | ||
1026 | * @new_fcf_record: pointer to fcf record. | ||
1027 | * | ||
1028 | * This routine compare the fcf record's fabric name with provided | ||
1029 | * fabric name. If the fabric name are identical this function | ||
1030 | * returns 1 else return 0. | ||
1031 | **/ | ||
1032 | static uint32_t | ||
1033 | lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record) | ||
1034 | { | ||
1035 | if ((fab_name[0] == | ||
1036 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record)) && | ||
1037 | (fab_name[1] == | ||
1038 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record)) && | ||
1039 | (fab_name[2] == | ||
1040 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record)) && | ||
1041 | (fab_name[3] == | ||
1042 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record)) && | ||
1043 | (fab_name[4] == | ||
1044 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record)) && | ||
1045 | (fab_name[5] == | ||
1046 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record)) && | ||
1047 | (fab_name[6] == | ||
1048 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record)) && | ||
1049 | (fab_name[7] == | ||
1050 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record))) | ||
1051 | return 1; | ||
1052 | else | ||
1053 | return 0; | ||
1054 | } | ||
1055 | |||
1056 | /** | ||
1057 | * lpfc_mac_addr_match - Check if the fcf mac address match. | ||
1058 | * @phba: pointer to lpfc hba data structure. | ||
1059 | * @new_fcf_record: pointer to fcf record. | ||
1060 | * | ||
1061 | * This routine compare the fcf record's mac address with HBA's | ||
1062 | * FCF mac address. If the mac addresses are identical this function | ||
1063 | * returns 1 else return 0. | ||
1064 | **/ | ||
1065 | static uint32_t | ||
1066 | lpfc_mac_addr_match(struct lpfc_hba *phba, struct fcf_record *new_fcf_record) | ||
1067 | { | ||
1068 | if ((phba->fcf.mac_addr[0] == | ||
1069 | bf_get(lpfc_fcf_record_mac_0, new_fcf_record)) && | ||
1070 | (phba->fcf.mac_addr[1] == | ||
1071 | bf_get(lpfc_fcf_record_mac_1, new_fcf_record)) && | ||
1072 | (phba->fcf.mac_addr[2] == | ||
1073 | bf_get(lpfc_fcf_record_mac_2, new_fcf_record)) && | ||
1074 | (phba->fcf.mac_addr[3] == | ||
1075 | bf_get(lpfc_fcf_record_mac_3, new_fcf_record)) && | ||
1076 | (phba->fcf.mac_addr[4] == | ||
1077 | bf_get(lpfc_fcf_record_mac_4, new_fcf_record)) && | ||
1078 | (phba->fcf.mac_addr[5] == | ||
1079 | bf_get(lpfc_fcf_record_mac_5, new_fcf_record))) | ||
1080 | return 1; | ||
1081 | else | ||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | /** | ||
1086 | * lpfc_copy_fcf_record - Copy fcf information to lpfc_hba. | ||
1087 | * @phba: pointer to lpfc hba data structure. | ||
1088 | * @new_fcf_record: pointer to fcf record. | ||
1089 | * | ||
1090 | * This routine copies the FCF information from the FCF | ||
1091 | * record to lpfc_hba data structure. | ||
1092 | **/ | ||
1093 | static void | ||
1094 | lpfc_copy_fcf_record(struct lpfc_hba *phba, struct fcf_record *new_fcf_record) | ||
1095 | { | ||
1096 | phba->fcf.fabric_name[0] = | ||
1097 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record); | ||
1098 | phba->fcf.fabric_name[1] = | ||
1099 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record); | ||
1100 | phba->fcf.fabric_name[2] = | ||
1101 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record); | ||
1102 | phba->fcf.fabric_name[3] = | ||
1103 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record); | ||
1104 | phba->fcf.fabric_name[4] = | ||
1105 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record); | ||
1106 | phba->fcf.fabric_name[5] = | ||
1107 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record); | ||
1108 | phba->fcf.fabric_name[6] = | ||
1109 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record); | ||
1110 | phba->fcf.fabric_name[7] = | ||
1111 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record); | ||
1112 | phba->fcf.mac_addr[0] = | ||
1113 | bf_get(lpfc_fcf_record_mac_0, new_fcf_record); | ||
1114 | phba->fcf.mac_addr[1] = | ||
1115 | bf_get(lpfc_fcf_record_mac_1, new_fcf_record); | ||
1116 | phba->fcf.mac_addr[2] = | ||
1117 | bf_get(lpfc_fcf_record_mac_2, new_fcf_record); | ||
1118 | phba->fcf.mac_addr[3] = | ||
1119 | bf_get(lpfc_fcf_record_mac_3, new_fcf_record); | ||
1120 | phba->fcf.mac_addr[4] = | ||
1121 | bf_get(lpfc_fcf_record_mac_4, new_fcf_record); | ||
1122 | phba->fcf.mac_addr[5] = | ||
1123 | bf_get(lpfc_fcf_record_mac_5, new_fcf_record); | ||
1124 | phba->fcf.fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); | ||
1125 | phba->fcf.priority = new_fcf_record->fip_priority; | ||
1126 | } | ||
1127 | |||
1128 | /** | ||
1129 | * lpfc_register_fcf - Register the FCF with hba. | ||
1130 | * @phba: pointer to lpfc hba data structure. | ||
1131 | * | ||
1132 | * This routine issues a register fcfi mailbox command to register | ||
1133 | * the fcf with HBA. | ||
1134 | **/ | ||
1135 | static void | ||
1136 | lpfc_register_fcf(struct lpfc_hba *phba) | ||
1137 | { | ||
1138 | LPFC_MBOXQ_t *fcf_mbxq; | ||
1139 | int rc; | ||
1140 | unsigned long flags; | ||
1141 | |||
1142 | spin_lock_irqsave(&phba->hbalock, flags); | ||
1143 | |||
1144 | /* If the FCF is not availabe do nothing. */ | ||
1145 | if (!(phba->fcf.fcf_flag & FCF_AVAILABLE)) { | ||
1146 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1147 | return; | ||
1148 | } | ||
1149 | |||
1150 | /* The FCF is already registered, start discovery */ | ||
1151 | if (phba->fcf.fcf_flag & FCF_REGISTERED) { | ||
1152 | phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); | ||
1153 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1154 | if (phba->pport->port_state != LPFC_FLOGI) | ||
1155 | lpfc_initial_flogi(phba->pport); | ||
1156 | return; | ||
1157 | } | ||
1158 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1159 | |||
1160 | fcf_mbxq = mempool_alloc(phba->mbox_mem_pool, | ||
1161 | GFP_KERNEL); | ||
1162 | if (!fcf_mbxq) | ||
1163 | return; | ||
1164 | |||
1165 | lpfc_reg_fcfi(phba, fcf_mbxq); | ||
1166 | fcf_mbxq->vport = phba->pport; | ||
1167 | fcf_mbxq->mbox_cmpl = lpfc_mbx_cmpl_reg_fcfi; | ||
1168 | rc = lpfc_sli_issue_mbox(phba, fcf_mbxq, MBX_NOWAIT); | ||
1169 | if (rc == MBX_NOT_FINISHED) | ||
1170 | mempool_free(fcf_mbxq, phba->mbox_mem_pool); | ||
1171 | |||
1172 | return; | ||
1173 | } | ||
1174 | |||
1175 | /** | ||
1176 | * lpfc_match_fcf_conn_list - Check if the FCF record can be used for discovery. | ||
1177 | * @phba: pointer to lpfc hba data structure. | ||
1178 | * @new_fcf_record: pointer to fcf record. | ||
1179 | * @boot_flag: Indicates if this record used by boot bios. | ||
1180 | * @addr_mode: The address mode to be used by this FCF | ||
1181 | * | ||
1182 | * This routine compare the fcf record with connect list obtained from the | ||
1183 | * config region to decide if this FCF can be used for SAN discovery. It returns | ||
1184 | * 1 if this record can be used for SAN discovery else return zero. If this FCF | ||
1185 | * record can be used for SAN discovery, the boot_flag will indicate if this FCF | ||
1186 | * is used by boot bios and addr_mode will indicate the addressing mode to be | ||
1187 | * used for this FCF when the function returns. | ||
1188 | * If the FCF record need to be used with a particular vlan id, the vlan is | ||
1189 | * set in the vlan_id on return of the function. If not VLAN tagging need to | ||
1190 | * be used with the FCF vlan_id will be set to 0xFFFF; | ||
1191 | **/ | ||
1192 | static int | ||
1193 | lpfc_match_fcf_conn_list(struct lpfc_hba *phba, | ||
1194 | struct fcf_record *new_fcf_record, | ||
1195 | uint32_t *boot_flag, uint32_t *addr_mode, | ||
1196 | uint16_t *vlan_id) | ||
1197 | { | ||
1198 | struct lpfc_fcf_conn_entry *conn_entry; | ||
1199 | |||
1200 | if (!phba->cfg_enable_fip) { | ||
1201 | *boot_flag = 0; | ||
1202 | *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1203 | new_fcf_record); | ||
1204 | if (phba->valid_vlan) | ||
1205 | *vlan_id = phba->vlan_id; | ||
1206 | else | ||
1207 | *vlan_id = 0xFFFF; | ||
1208 | return 1; | ||
1209 | } | ||
1210 | |||
1211 | /* | ||
1212 | * If there are no FCF connection table entry, driver connect to all | ||
1213 | * FCFs. | ||
1214 | */ | ||
1215 | if (list_empty(&phba->fcf_conn_rec_list)) { | ||
1216 | *boot_flag = 0; | ||
1217 | *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1218 | new_fcf_record); | ||
1219 | *vlan_id = 0xFFFF; | ||
1220 | return 1; | ||
1221 | } | ||
1222 | |||
1223 | list_for_each_entry(conn_entry, &phba->fcf_conn_rec_list, list) { | ||
1224 | if (!(conn_entry->conn_rec.flags & FCFCNCT_VALID)) | ||
1225 | continue; | ||
1226 | |||
1227 | if ((conn_entry->conn_rec.flags & FCFCNCT_FBNM_VALID) && | ||
1228 | !lpfc_fab_name_match(conn_entry->conn_rec.fabric_name, | ||
1229 | new_fcf_record)) | ||
1230 | continue; | ||
1231 | |||
1232 | if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID) { | ||
1233 | /* | ||
1234 | * If the vlan bit map does not have the bit set for the | ||
1235 | * vlan id to be used, then it is not a match. | ||
1236 | */ | ||
1237 | if (!(new_fcf_record->vlan_bitmap | ||
1238 | [conn_entry->conn_rec.vlan_tag / 8] & | ||
1239 | (1 << (conn_entry->conn_rec.vlan_tag % 8)))) | ||
1240 | continue; | ||
1241 | } | ||
1242 | |||
1243 | /* | ||
1244 | * Check if the connection record specifies a required | ||
1245 | * addressing mode. | ||
1246 | */ | ||
1247 | if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1248 | !(conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED)) { | ||
1249 | |||
1250 | /* | ||
1251 | * If SPMA required but FCF not support this continue. | ||
1252 | */ | ||
1253 | if ((conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1254 | !(bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1255 | new_fcf_record) & LPFC_FCF_SPMA)) | ||
1256 | continue; | ||
1257 | |||
1258 | /* | ||
1259 | * If FPMA required but FCF not support this continue. | ||
1260 | */ | ||
1261 | if (!(conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1262 | !(bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1263 | new_fcf_record) & LPFC_FCF_FPMA)) | ||
1264 | continue; | ||
1265 | } | ||
1266 | |||
1267 | /* | ||
1268 | * This fcf record matches filtering criteria. | ||
1269 | */ | ||
1270 | if (conn_entry->conn_rec.flags & FCFCNCT_BOOT) | ||
1271 | *boot_flag = 1; | ||
1272 | else | ||
1273 | *boot_flag = 0; | ||
1274 | |||
1275 | *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1276 | new_fcf_record); | ||
1277 | /* | ||
1278 | * If the user specified a required address mode, assign that | ||
1279 | * address mode | ||
1280 | */ | ||
1281 | if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1282 | (!(conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED))) | ||
1283 | *addr_mode = (conn_entry->conn_rec.flags & | ||
1284 | FCFCNCT_AM_SPMA) ? | ||
1285 | LPFC_FCF_SPMA : LPFC_FCF_FPMA; | ||
1286 | /* | ||
1287 | * If the user specified a prefered address mode, use the | ||
1288 | * addr mode only if FCF support the addr_mode. | ||
1289 | */ | ||
1290 | else if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1291 | (conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED) && | ||
1292 | (conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1293 | (*addr_mode & LPFC_FCF_SPMA)) | ||
1294 | *addr_mode = LPFC_FCF_SPMA; | ||
1295 | else if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1296 | (conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED) && | ||
1297 | !(conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1298 | (*addr_mode & LPFC_FCF_FPMA)) | ||
1299 | *addr_mode = LPFC_FCF_FPMA; | ||
1300 | /* | ||
1301 | * If user did not specify any addressing mode, use FPMA if | ||
1302 | * possible else use SPMA. | ||
1303 | */ | ||
1304 | else if (*addr_mode & LPFC_FCF_FPMA) | ||
1305 | *addr_mode = LPFC_FCF_FPMA; | ||
1306 | |||
1307 | if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID) | ||
1308 | *vlan_id = conn_entry->conn_rec.vlan_tag; | ||
1309 | else | ||
1310 | *vlan_id = 0xFFFF; | ||
1311 | |||
1312 | return 1; | ||
1313 | } | ||
1314 | |||
1315 | return 0; | ||
1316 | } | ||
1317 | |||
1318 | /** | ||
1319 | * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox. | ||
1320 | * @phba: pointer to lpfc hba data structure. | ||
1321 | * @mboxq: pointer to mailbox object. | ||
1322 | * | ||
1323 | * This function iterate through all the fcf records available in | ||
1324 | * HBA and choose the optimal FCF record for discovery. After finding | ||
1325 | * the FCF for discovery it register the FCF record and kick start | ||
1326 | * discovery. | ||
1327 | * If FCF_IN_USE flag is set in currently used FCF, the routine try to | ||
1328 | * use a FCF record which match fabric name and mac address of the | ||
1329 | * currently used FCF record. | ||
1330 | * If the driver support only one FCF, it will try to use the FCF record | ||
1331 | * used by BOOT_BIOS. | ||
1332 | */ | ||
1333 | void | ||
1334 | lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1335 | { | ||
1336 | void *virt_addr; | ||
1337 | dma_addr_t phys_addr; | ||
1338 | uint8_t *bytep; | ||
1339 | struct lpfc_mbx_sge sge; | ||
1340 | struct lpfc_mbx_read_fcf_tbl *read_fcf; | ||
1341 | uint32_t shdr_status, shdr_add_status; | ||
1342 | union lpfc_sli4_cfg_shdr *shdr; | ||
1343 | struct fcf_record *new_fcf_record; | ||
1344 | int rc; | ||
1345 | uint32_t boot_flag, addr_mode; | ||
1346 | uint32_t next_fcf_index; | ||
1347 | unsigned long flags; | ||
1348 | uint16_t vlan_id; | ||
1349 | |||
1350 | /* Get the first SGE entry from the non-embedded DMA memory. This | ||
1351 | * routine only uses a single SGE. | ||
1352 | */ | ||
1353 | lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); | ||
1354 | phys_addr = getPaddr(sge.pa_hi, sge.pa_lo); | ||
1355 | if (unlikely(!mboxq->sge_array)) { | ||
1356 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
1357 | "2524 Failed to get the non-embedded SGE " | ||
1358 | "virtual address\n"); | ||
1359 | goto out; | ||
1360 | } | ||
1361 | virt_addr = mboxq->sge_array->addr[0]; | ||
1362 | |||
1363 | shdr = (union lpfc_sli4_cfg_shdr *)virt_addr; | ||
1364 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
1365 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | ||
1366 | &shdr->response); | ||
1367 | /* | ||
1368 | * The FCF Record was read and there is no reason for the driver | ||
1369 | * to maintain the FCF record data or memory. Instead, just need | ||
1370 | * to book keeping the FCFIs can be used. | ||
1371 | */ | ||
1372 | if (shdr_status || shdr_add_status) { | ||
1373 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1374 | "2521 READ_FCF_RECORD mailbox failed " | ||
1375 | "with status x%x add_status x%x, mbx\n", | ||
1376 | shdr_status, shdr_add_status); | ||
1377 | goto out; | ||
1378 | } | ||
1379 | /* Interpreting the returned information of FCF records */ | ||
1380 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; | ||
1381 | lpfc_sli_pcimem_bcopy(read_fcf, read_fcf, | ||
1382 | sizeof(struct lpfc_mbx_read_fcf_tbl)); | ||
1383 | next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf); | ||
1384 | |||
1385 | new_fcf_record = (struct fcf_record *)(virt_addr + | ||
1386 | sizeof(struct lpfc_mbx_read_fcf_tbl)); | ||
1387 | lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record, | ||
1388 | sizeof(struct fcf_record)); | ||
1389 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | ||
1390 | |||
1391 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, | ||
1392 | &boot_flag, &addr_mode, | ||
1393 | &vlan_id); | ||
1394 | /* | ||
1395 | * If the fcf record does not match with connect list entries | ||
1396 | * read the next entry. | ||
1397 | */ | ||
1398 | if (!rc) | ||
1399 | goto read_next_fcf; | ||
1400 | /* | ||
1401 | * If this is not the first FCF discovery of the HBA, use last | ||
1402 | * FCF record for the discovery. | ||
1403 | */ | ||
1404 | spin_lock_irqsave(&phba->hbalock, flags); | ||
1405 | if (phba->fcf.fcf_flag & FCF_IN_USE) { | ||
1406 | if (lpfc_fab_name_match(phba->fcf.fabric_name, | ||
1407 | new_fcf_record) && | ||
1408 | lpfc_mac_addr_match(phba, new_fcf_record)) { | ||
1409 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | ||
1410 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1411 | goto out; | ||
1412 | } | ||
1413 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1414 | goto read_next_fcf; | ||
1415 | } | ||
1416 | if (phba->fcf.fcf_flag & FCF_AVAILABLE) { | ||
1417 | /* | ||
1418 | * If the current FCF record does not have boot flag | ||
1419 | * set and new fcf record has boot flag set, use the | ||
1420 | * new fcf record. | ||
1421 | */ | ||
1422 | if (boot_flag && !(phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | ||
1423 | /* Use this FCF record */ | ||
1424 | lpfc_copy_fcf_record(phba, new_fcf_record); | ||
1425 | phba->fcf.addr_mode = addr_mode; | ||
1426 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | ||
1427 | if (vlan_id != 0xFFFF) { | ||
1428 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1429 | phba->fcf.vlan_id = vlan_id; | ||
1430 | } | ||
1431 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1432 | goto read_next_fcf; | ||
1433 | } | ||
1434 | /* | ||
1435 | * If the current FCF record has boot flag set and the | ||
1436 | * new FCF record does not have boot flag, read the next | ||
1437 | * FCF record. | ||
1438 | */ | ||
1439 | if (!boot_flag && (phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | ||
1440 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1441 | goto read_next_fcf; | ||
1442 | } | ||
1443 | /* | ||
1444 | * If there is a record with lower priority value for | ||
1445 | * the current FCF, use that record. | ||
1446 | */ | ||
1447 | if (lpfc_fab_name_match(phba->fcf.fabric_name, new_fcf_record) | ||
1448 | && (new_fcf_record->fip_priority < | ||
1449 | phba->fcf.priority)) { | ||
1450 | /* Use this FCF record */ | ||
1451 | lpfc_copy_fcf_record(phba, new_fcf_record); | ||
1452 | phba->fcf.addr_mode = addr_mode; | ||
1453 | if (vlan_id != 0xFFFF) { | ||
1454 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1455 | phba->fcf.vlan_id = vlan_id; | ||
1456 | } | ||
1457 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1458 | goto read_next_fcf; | ||
1459 | } | ||
1460 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1461 | goto read_next_fcf; | ||
1462 | } | ||
1463 | /* | ||
1464 | * This is the first available FCF record, use this | ||
1465 | * record. | ||
1466 | */ | ||
1467 | lpfc_copy_fcf_record(phba, new_fcf_record); | ||
1468 | phba->fcf.addr_mode = addr_mode; | ||
1469 | if (boot_flag) | ||
1470 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | ||
1471 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | ||
1472 | if (vlan_id != 0xFFFF) { | ||
1473 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1474 | phba->fcf.vlan_id = vlan_id; | ||
1475 | } | ||
1476 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1477 | goto read_next_fcf; | ||
1478 | |||
1479 | read_next_fcf: | ||
1480 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1481 | if (next_fcf_index == LPFC_FCOE_FCF_NEXT_NONE || next_fcf_index == 0) | ||
1482 | lpfc_register_fcf(phba); | ||
1483 | else | ||
1484 | lpfc_sli4_read_fcf_record(phba, next_fcf_index); | ||
1485 | return; | ||
1486 | |||
1487 | out: | ||
1488 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1489 | lpfc_register_fcf(phba); | ||
1490 | |||
1491 | return; | ||
1492 | } | ||
1493 | |||
1494 | /** | ||
1495 | * lpfc_start_fdiscs - send fdiscs for each vports on this port. | ||
1496 | * @phba: pointer to lpfc hba data structure. | ||
1497 | * | ||
1498 | * This function loops through the list of vports on the @phba and issues an | ||
1499 | * FDISC if possible. | ||
1500 | */ | ||
1501 | void | ||
1502 | lpfc_start_fdiscs(struct lpfc_hba *phba) | ||
1503 | { | ||
1504 | struct lpfc_vport **vports; | ||
1505 | int i; | ||
1506 | |||
1507 | vports = lpfc_create_vport_work_array(phba); | ||
1508 | if (vports != NULL) { | ||
1509 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
1510 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | ||
1511 | continue; | ||
1512 | /* There are no vpi for this vport */ | ||
1513 | if (vports[i]->vpi > phba->max_vpi) { | ||
1514 | lpfc_vport_set_state(vports[i], | ||
1515 | FC_VPORT_FAILED); | ||
1516 | continue; | ||
1517 | } | ||
1518 | if (phba->fc_topology == TOPOLOGY_LOOP) { | ||
1519 | lpfc_vport_set_state(vports[i], | ||
1520 | FC_VPORT_LINKDOWN); | ||
1521 | continue; | ||
1522 | } | ||
1523 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | ||
1524 | lpfc_initial_fdisc(vports[i]); | ||
1525 | else { | ||
1526 | lpfc_vport_set_state(vports[i], | ||
1527 | FC_VPORT_NO_FABRIC_SUPP); | ||
1528 | lpfc_printf_vlog(vports[i], KERN_ERR, | ||
1529 | LOG_ELS, | ||
1530 | "0259 No NPIV " | ||
1531 | "Fabric support\n"); | ||
1532 | } | ||
1533 | } | ||
1534 | } | ||
1535 | lpfc_destroy_vport_work_array(phba, vports); | ||
1536 | } | ||
1537 | |||
1538 | void | ||
1539 | lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1540 | { | ||
1541 | struct lpfc_dmabuf *dmabuf = mboxq->context1; | ||
1542 | struct lpfc_vport *vport = mboxq->vport; | ||
1543 | |||
1544 | if (mboxq->u.mb.mbxStatus) { | ||
1545 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | ||
1546 | "2018 REG_VFI mbxStatus error x%x " | ||
1547 | "HBA state x%x\n", | ||
1548 | mboxq->u.mb.mbxStatus, vport->port_state); | ||
1549 | if (phba->fc_topology == TOPOLOGY_LOOP) { | ||
1550 | /* FLOGI failed, use loop map to make discovery list */ | ||
1551 | lpfc_disc_list_loopmap(vport); | ||
1552 | /* Start discovery */ | ||
1553 | lpfc_disc_start(vport); | ||
1554 | goto fail_free_mem; | ||
1555 | } | ||
1556 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
1557 | goto fail_free_mem; | ||
1558 | } | ||
1559 | /* Mark the vport has registered with its VFI */ | ||
1560 | vport->vfi_state |= LPFC_VFI_REGISTERED; | ||
1561 | |||
1562 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { | ||
1563 | lpfc_start_fdiscs(phba); | ||
1564 | lpfc_do_scr_ns_plogi(phba, vport); | ||
1565 | } | ||
1566 | |||
1567 | fail_free_mem: | ||
1568 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1569 | lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); | ||
1570 | kfree(dmabuf); | ||
1571 | return; | ||
1572 | } | ||
1573 | |||
1574 | static void | ||
987 | lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 1575 | lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
988 | { | 1576 | { |
989 | MAILBOX_t *mb = &pmb->mb; | 1577 | MAILBOX_t *mb = &pmb->u.mb; |
990 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; | 1578 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; |
991 | struct lpfc_vport *vport = pmb->vport; | 1579 | struct lpfc_vport *vport = pmb->vport; |
992 | 1580 | ||
@@ -1037,13 +1625,13 @@ static void | |||
1037 | lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | 1625 | lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) |
1038 | { | 1626 | { |
1039 | struct lpfc_vport *vport = phba->pport; | 1627 | struct lpfc_vport *vport = phba->pport; |
1040 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox; | 1628 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox = NULL; |
1041 | int i; | 1629 | int i; |
1042 | struct lpfc_dmabuf *mp; | 1630 | struct lpfc_dmabuf *mp; |
1043 | int rc; | 1631 | int rc; |
1632 | struct fcf_record *fcf_record; | ||
1044 | 1633 | ||
1045 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1634 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
1046 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
1047 | 1635 | ||
1048 | spin_lock_irq(&phba->hbalock); | 1636 | spin_lock_irq(&phba->hbalock); |
1049 | switch (la->UlnkSpeed) { | 1637 | switch (la->UlnkSpeed) { |
@@ -1140,22 +1728,66 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
1140 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1728 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1141 | kfree(mp); | 1729 | kfree(mp); |
1142 | mempool_free(sparam_mbox, phba->mbox_mem_pool); | 1730 | mempool_free(sparam_mbox, phba->mbox_mem_pool); |
1143 | if (cfglink_mbox) | ||
1144 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); | ||
1145 | goto out; | 1731 | goto out; |
1146 | } | 1732 | } |
1147 | } | 1733 | } |
1148 | 1734 | ||
1149 | if (cfglink_mbox) { | 1735 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) { |
1736 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
1737 | if (!cfglink_mbox) | ||
1738 | goto out; | ||
1150 | vport->port_state = LPFC_LOCAL_CFG_LINK; | 1739 | vport->port_state = LPFC_LOCAL_CFG_LINK; |
1151 | lpfc_config_link(phba, cfglink_mbox); | 1740 | lpfc_config_link(phba, cfglink_mbox); |
1152 | cfglink_mbox->vport = vport; | 1741 | cfglink_mbox->vport = vport; |
1153 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; | 1742 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; |
1154 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT); | 1743 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT); |
1155 | if (rc != MBX_NOT_FINISHED) | 1744 | if (rc == MBX_NOT_FINISHED) { |
1156 | return; | 1745 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); |
1157 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); | 1746 | goto out; |
1747 | } | ||
1748 | } else { | ||
1749 | /* | ||
1750 | * Add the driver's default FCF record at FCF index 0 now. This | ||
1751 | * is phase 1 implementation that support FCF index 0 and driver | ||
1752 | * defaults. | ||
1753 | */ | ||
1754 | if (phba->cfg_enable_fip == 0) { | ||
1755 | fcf_record = kzalloc(sizeof(struct fcf_record), | ||
1756 | GFP_KERNEL); | ||
1757 | if (unlikely(!fcf_record)) { | ||
1758 | lpfc_printf_log(phba, KERN_ERR, | ||
1759 | LOG_MBOX | LOG_SLI, | ||
1760 | "2554 Could not allocate memmory for " | ||
1761 | "fcf record\n"); | ||
1762 | rc = -ENODEV; | ||
1763 | goto out; | ||
1764 | } | ||
1765 | |||
1766 | lpfc_sli4_build_dflt_fcf_record(phba, fcf_record, | ||
1767 | LPFC_FCOE_FCF_DEF_INDEX); | ||
1768 | rc = lpfc_sli4_add_fcf_record(phba, fcf_record); | ||
1769 | if (unlikely(rc)) { | ||
1770 | lpfc_printf_log(phba, KERN_ERR, | ||
1771 | LOG_MBOX | LOG_SLI, | ||
1772 | "2013 Could not manually add FCF " | ||
1773 | "record 0, status %d\n", rc); | ||
1774 | rc = -ENODEV; | ||
1775 | kfree(fcf_record); | ||
1776 | goto out; | ||
1777 | } | ||
1778 | kfree(fcf_record); | ||
1779 | } | ||
1780 | /* | ||
1781 | * The driver is expected to do FIP/FCF. Call the port | ||
1782 | * and get the FCF Table. | ||
1783 | */ | ||
1784 | rc = lpfc_sli4_read_fcf_record(phba, | ||
1785 | LPFC_FCOE_FCF_GET_FIRST); | ||
1786 | if (rc) | ||
1787 | goto out; | ||
1158 | } | 1788 | } |
1789 | |||
1790 | return; | ||
1159 | out: | 1791 | out: |
1160 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 1792 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
1161 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 1793 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
@@ -1186,6 +1818,7 @@ lpfc_mbx_issue_link_down(struct lpfc_hba *phba) | |||
1186 | { | 1818 | { |
1187 | lpfc_linkdown(phba); | 1819 | lpfc_linkdown(phba); |
1188 | lpfc_enable_la(phba); | 1820 | lpfc_enable_la(phba); |
1821 | lpfc_unregister_unused_fcf(phba); | ||
1189 | /* turn on Link Attention interrupts - no CLEAR_LA needed */ | 1822 | /* turn on Link Attention interrupts - no CLEAR_LA needed */ |
1190 | } | 1823 | } |
1191 | 1824 | ||
@@ -3330,3 +3963,395 @@ lpfc_nlp_not_used(struct lpfc_nodelist *ndlp) | |||
3330 | return 1; | 3963 | return 1; |
3331 | return 0; | 3964 | return 0; |
3332 | } | 3965 | } |
3966 | |||
3967 | /** | ||
3968 | * lpfc_fcf_inuse - Check if FCF can be unregistered. | ||
3969 | * @phba: Pointer to hba context object. | ||
3970 | * | ||
3971 | * This function iterate through all FC nodes associated | ||
3972 | * will all vports to check if there is any node with | ||
3973 | * fc_rports associated with it. If there is an fc_rport | ||
3974 | * associated with the node, then the node is either in | ||
3975 | * discovered state or its devloss_timer is pending. | ||
3976 | */ | ||
3977 | static int | ||
3978 | lpfc_fcf_inuse(struct lpfc_hba *phba) | ||
3979 | { | ||
3980 | struct lpfc_vport **vports; | ||
3981 | int i, ret = 0; | ||
3982 | struct lpfc_nodelist *ndlp; | ||
3983 | struct Scsi_Host *shost; | ||
3984 | |||
3985 | vports = lpfc_create_vport_work_array(phba); | ||
3986 | |||
3987 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
3988 | shost = lpfc_shost_from_vport(vports[i]); | ||
3989 | spin_lock_irq(shost->host_lock); | ||
3990 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { | ||
3991 | if (NLP_CHK_NODE_ACT(ndlp) && ndlp->rport && | ||
3992 | (ndlp->rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { | ||
3993 | ret = 1; | ||
3994 | spin_unlock_irq(shost->host_lock); | ||
3995 | goto out; | ||
3996 | } | ||
3997 | } | ||
3998 | spin_unlock_irq(shost->host_lock); | ||
3999 | } | ||
4000 | out: | ||
4001 | lpfc_destroy_vport_work_array(phba, vports); | ||
4002 | return ret; | ||
4003 | } | ||
4004 | |||
4005 | /** | ||
4006 | * lpfc_unregister_vfi_cmpl - Completion handler for unreg vfi. | ||
4007 | * @phba: Pointer to hba context object. | ||
4008 | * @mboxq: Pointer to mailbox object. | ||
4009 | * | ||
4010 | * This function frees memory associated with the mailbox command. | ||
4011 | */ | ||
4012 | static void | ||
4013 | lpfc_unregister_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
4014 | { | ||
4015 | struct lpfc_vport *vport = mboxq->vport; | ||
4016 | |||
4017 | if (mboxq->u.mb.mbxStatus) { | ||
4018 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4019 | "2555 UNREG_VFI mbxStatus error x%x " | ||
4020 | "HBA state x%x\n", | ||
4021 | mboxq->u.mb.mbxStatus, vport->port_state); | ||
4022 | } | ||
4023 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
4024 | return; | ||
4025 | } | ||
4026 | |||
4027 | /** | ||
4028 | * lpfc_unregister_fcfi_cmpl - Completion handler for unreg fcfi. | ||
4029 | * @phba: Pointer to hba context object. | ||
4030 | * @mboxq: Pointer to mailbox object. | ||
4031 | * | ||
4032 | * This function frees memory associated with the mailbox command. | ||
4033 | */ | ||
4034 | static void | ||
4035 | lpfc_unregister_fcfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
4036 | { | ||
4037 | struct lpfc_vport *vport = mboxq->vport; | ||
4038 | |||
4039 | if (mboxq->u.mb.mbxStatus) { | ||
4040 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4041 | "2550 UNREG_FCFI mbxStatus error x%x " | ||
4042 | "HBA state x%x\n", | ||
4043 | mboxq->u.mb.mbxStatus, vport->port_state); | ||
4044 | } | ||
4045 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
4046 | return; | ||
4047 | } | ||
4048 | |||
4049 | /** | ||
4050 | * lpfc_unregister_unused_fcf - Unregister FCF if all devices are disconnected. | ||
4051 | * @phba: Pointer to hba context object. | ||
4052 | * | ||
4053 | * This function check if there are any connected remote port for the FCF and | ||
4054 | * if all the devices are disconnected, this function unregister FCFI. | ||
4055 | * This function also tries to use another FCF for discovery. | ||
4056 | */ | ||
4057 | void | ||
4058 | lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | ||
4059 | { | ||
4060 | LPFC_MBOXQ_t *mbox; | ||
4061 | int rc; | ||
4062 | struct lpfc_vport **vports; | ||
4063 | int i; | ||
4064 | |||
4065 | spin_lock_irq(&phba->hbalock); | ||
4066 | /* | ||
4067 | * If HBA is not running in FIP mode or | ||
4068 | * If HBA does not support FCoE or | ||
4069 | * If FCF is not registered. | ||
4070 | * do nothing. | ||
4071 | */ | ||
4072 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT) || | ||
4073 | !(phba->fcf.fcf_flag & FCF_REGISTERED) || | ||
4074 | (phba->cfg_enable_fip == 0)) { | ||
4075 | spin_unlock_irq(&phba->hbalock); | ||
4076 | return; | ||
4077 | } | ||
4078 | spin_unlock_irq(&phba->hbalock); | ||
4079 | |||
4080 | if (lpfc_fcf_inuse(phba)) | ||
4081 | return; | ||
4082 | |||
4083 | |||
4084 | /* Unregister VPIs */ | ||
4085 | vports = lpfc_create_vport_work_array(phba); | ||
4086 | if (vports && | ||
4087 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) | ||
4088 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
4089 | lpfc_mbx_unreg_vpi(vports[i]); | ||
4090 | vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | ||
4091 | vports[i]->vfi_state &= ~LPFC_VFI_REGISTERED; | ||
4092 | } | ||
4093 | lpfc_destroy_vport_work_array(phba, vports); | ||
4094 | |||
4095 | /* Unregister VFI */ | ||
4096 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
4097 | if (!mbox) { | ||
4098 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4099 | "2556 UNREG_VFI mbox allocation failed" | ||
4100 | "HBA state x%x\n", | ||
4101 | phba->pport->port_state); | ||
4102 | return; | ||
4103 | } | ||
4104 | |||
4105 | lpfc_unreg_vfi(mbox, phba->pport->vfi); | ||
4106 | mbox->vport = phba->pport; | ||
4107 | mbox->mbox_cmpl = lpfc_unregister_vfi_cmpl; | ||
4108 | |||
4109 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
4110 | if (rc == MBX_NOT_FINISHED) { | ||
4111 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4112 | "2557 UNREG_VFI issue mbox failed rc x%x " | ||
4113 | "HBA state x%x\n", | ||
4114 | rc, phba->pport->port_state); | ||
4115 | mempool_free(mbox, phba->mbox_mem_pool); | ||
4116 | return; | ||
4117 | } | ||
4118 | |||
4119 | /* Unregister FCF */ | ||
4120 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
4121 | if (!mbox) { | ||
4122 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4123 | "2551 UNREG_FCFI mbox allocation failed" | ||
4124 | "HBA state x%x\n", | ||
4125 | phba->pport->port_state); | ||
4126 | return; | ||
4127 | } | ||
4128 | |||
4129 | lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); | ||
4130 | mbox->vport = phba->pport; | ||
4131 | mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; | ||
4132 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
4133 | |||
4134 | if (rc == MBX_NOT_FINISHED) { | ||
4135 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4136 | "2552 UNREG_FCFI issue mbox failed rc x%x " | ||
4137 | "HBA state x%x\n", | ||
4138 | rc, phba->pport->port_state); | ||
4139 | mempool_free(mbox, phba->mbox_mem_pool); | ||
4140 | return; | ||
4141 | } | ||
4142 | |||
4143 | spin_lock_irq(&phba->hbalock); | ||
4144 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_REGISTERED | | ||
4145 | FCF_DISCOVERED | FCF_BOOT_ENABLE | FCF_IN_USE | | ||
4146 | FCF_VALID_VLAN); | ||
4147 | spin_unlock_irq(&phba->hbalock); | ||
4148 | |||
4149 | /* | ||
4150 | * If driver is not unloading, check if there is any other | ||
4151 | * FCF record that can be used for discovery. | ||
4152 | */ | ||
4153 | if ((phba->pport->load_flag & FC_UNLOADING) || | ||
4154 | (phba->link_state < LPFC_LINK_UP)) | ||
4155 | return; | ||
4156 | |||
4157 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | ||
4158 | |||
4159 | if (rc) | ||
4160 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4161 | "2553 lpfc_unregister_unused_fcf failed to read FCF" | ||
4162 | " record HBA state x%x\n", | ||
4163 | phba->pport->port_state); | ||
4164 | } | ||
4165 | |||
4166 | /** | ||
4167 | * lpfc_read_fcf_conn_tbl - Create driver FCF connection table. | ||
4168 | * @phba: Pointer to hba context object. | ||
4169 | * @buff: Buffer containing the FCF connection table as in the config | ||
4170 | * region. | ||
4171 | * This function create driver data structure for the FCF connection | ||
4172 | * record table read from config region 23. | ||
4173 | */ | ||
4174 | static void | ||
4175 | lpfc_read_fcf_conn_tbl(struct lpfc_hba *phba, | ||
4176 | uint8_t *buff) | ||
4177 | { | ||
4178 | struct lpfc_fcf_conn_entry *conn_entry, *next_conn_entry; | ||
4179 | struct lpfc_fcf_conn_hdr *conn_hdr; | ||
4180 | struct lpfc_fcf_conn_rec *conn_rec; | ||
4181 | uint32_t record_count; | ||
4182 | int i; | ||
4183 | |||
4184 | /* Free the current connect table */ | ||
4185 | list_for_each_entry_safe(conn_entry, next_conn_entry, | ||
4186 | &phba->fcf_conn_rec_list, list) | ||
4187 | kfree(conn_entry); | ||
4188 | |||
4189 | conn_hdr = (struct lpfc_fcf_conn_hdr *) buff; | ||
4190 | record_count = conn_hdr->length * sizeof(uint32_t)/ | ||
4191 | sizeof(struct lpfc_fcf_conn_rec); | ||
4192 | |||
4193 | conn_rec = (struct lpfc_fcf_conn_rec *) | ||
4194 | (buff + sizeof(struct lpfc_fcf_conn_hdr)); | ||
4195 | |||
4196 | for (i = 0; i < record_count; i++) { | ||
4197 | if (!(conn_rec[i].flags & FCFCNCT_VALID)) | ||
4198 | continue; | ||
4199 | conn_entry = kzalloc(sizeof(struct lpfc_fcf_conn_entry), | ||
4200 | GFP_KERNEL); | ||
4201 | if (!conn_entry) { | ||
4202 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4203 | "2566 Failed to allocate connection" | ||
4204 | " table entry\n"); | ||
4205 | return; | ||
4206 | } | ||
4207 | |||
4208 | memcpy(&conn_entry->conn_rec, &conn_rec[i], | ||
4209 | sizeof(struct lpfc_fcf_conn_rec)); | ||
4210 | conn_entry->conn_rec.vlan_tag = | ||
4211 | le16_to_cpu(conn_entry->conn_rec.vlan_tag) & 0xFFF; | ||
4212 | conn_entry->conn_rec.flags = | ||
4213 | le16_to_cpu(conn_entry->conn_rec.flags); | ||
4214 | list_add_tail(&conn_entry->list, | ||
4215 | &phba->fcf_conn_rec_list); | ||
4216 | } | ||
4217 | } | ||
4218 | |||
4219 | /** | ||
4220 | * lpfc_read_fcoe_param - Read FCoe parameters from conf region.. | ||
4221 | * @phba: Pointer to hba context object. | ||
4222 | * @buff: Buffer containing the FCoE parameter data structure. | ||
4223 | * | ||
4224 | * This function update driver data structure with config | ||
4225 | * parameters read from config region 23. | ||
4226 | */ | ||
4227 | static void | ||
4228 | lpfc_read_fcoe_param(struct lpfc_hba *phba, | ||
4229 | uint8_t *buff) | ||
4230 | { | ||
4231 | struct lpfc_fip_param_hdr *fcoe_param_hdr; | ||
4232 | struct lpfc_fcoe_params *fcoe_param; | ||
4233 | |||
4234 | fcoe_param_hdr = (struct lpfc_fip_param_hdr *) | ||
4235 | buff; | ||
4236 | fcoe_param = (struct lpfc_fcoe_params *) | ||
4237 | buff + sizeof(struct lpfc_fip_param_hdr); | ||
4238 | |||
4239 | if ((fcoe_param_hdr->parm_version != FIPP_VERSION) || | ||
4240 | (fcoe_param_hdr->length != FCOE_PARAM_LENGTH)) | ||
4241 | return; | ||
4242 | |||
4243 | if (bf_get(lpfc_fip_param_hdr_fipp_mode, fcoe_param_hdr) == | ||
4244 | FIPP_MODE_ON) | ||
4245 | phba->cfg_enable_fip = 1; | ||
4246 | |||
4247 | if (bf_get(lpfc_fip_param_hdr_fipp_mode, fcoe_param_hdr) == | ||
4248 | FIPP_MODE_OFF) | ||
4249 | phba->cfg_enable_fip = 0; | ||
4250 | |||
4251 | if (fcoe_param_hdr->parm_flags & FIPP_VLAN_VALID) { | ||
4252 | phba->valid_vlan = 1; | ||
4253 | phba->vlan_id = le16_to_cpu(fcoe_param->vlan_tag) & | ||
4254 | 0xFFF; | ||
4255 | } | ||
4256 | |||
4257 | phba->fc_map[0] = fcoe_param->fc_map[0]; | ||
4258 | phba->fc_map[1] = fcoe_param->fc_map[1]; | ||
4259 | phba->fc_map[2] = fcoe_param->fc_map[2]; | ||
4260 | return; | ||
4261 | } | ||
4262 | |||
4263 | /** | ||
4264 | * lpfc_get_rec_conf23 - Get a record type in config region data. | ||
4265 | * @buff: Buffer containing config region 23 data. | ||
4266 | * @size: Size of the data buffer. | ||
4267 | * @rec_type: Record type to be searched. | ||
4268 | * | ||
4269 | * This function searches config region data to find the begining | ||
4270 | * of the record specified by record_type. If record found, this | ||
4271 | * function return pointer to the record else return NULL. | ||
4272 | */ | ||
4273 | static uint8_t * | ||
4274 | lpfc_get_rec_conf23(uint8_t *buff, uint32_t size, uint8_t rec_type) | ||
4275 | { | ||
4276 | uint32_t offset = 0, rec_length; | ||
4277 | |||
4278 | if ((buff[0] == LPFC_REGION23_LAST_REC) || | ||
4279 | (size < sizeof(uint32_t))) | ||
4280 | return NULL; | ||
4281 | |||
4282 | rec_length = buff[offset + 1]; | ||
4283 | |||
4284 | /* | ||
4285 | * One TLV record has one word header and number of data words | ||
4286 | * specified in the rec_length field of the record header. | ||
4287 | */ | ||
4288 | while ((offset + rec_length * sizeof(uint32_t) + sizeof(uint32_t)) | ||
4289 | <= size) { | ||
4290 | if (buff[offset] == rec_type) | ||
4291 | return &buff[offset]; | ||
4292 | |||
4293 | if (buff[offset] == LPFC_REGION23_LAST_REC) | ||
4294 | return NULL; | ||
4295 | |||
4296 | offset += rec_length * sizeof(uint32_t) + sizeof(uint32_t); | ||
4297 | rec_length = buff[offset + 1]; | ||
4298 | } | ||
4299 | return NULL; | ||
4300 | } | ||
4301 | |||
4302 | /** | ||
4303 | * lpfc_parse_fcoe_conf - Parse FCoE config data read from config region 23. | ||
4304 | * @phba: Pointer to lpfc_hba data structure. | ||
4305 | * @buff: Buffer containing config region 23 data. | ||
4306 | * @size: Size of the data buffer. | ||
4307 | * | ||
4308 | * This fuction parse the FCoE config parameters in config region 23 and | ||
4309 | * populate driver data structure with the parameters. | ||
4310 | */ | ||
4311 | void | ||
4312 | lpfc_parse_fcoe_conf(struct lpfc_hba *phba, | ||
4313 | uint8_t *buff, | ||
4314 | uint32_t size) | ||
4315 | { | ||
4316 | uint32_t offset = 0, rec_length; | ||
4317 | uint8_t *rec_ptr; | ||
4318 | |||
4319 | /* | ||
4320 | * If data size is less than 2 words signature and version cannot be | ||
4321 | * verified. | ||
4322 | */ | ||
4323 | if (size < 2*sizeof(uint32_t)) | ||
4324 | return; | ||
4325 | |||
4326 | /* Check the region signature first */ | ||
4327 | if (memcmp(buff, LPFC_REGION23_SIGNATURE, 4)) { | ||
4328 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4329 | "2567 Config region 23 has bad signature\n"); | ||
4330 | return; | ||
4331 | } | ||
4332 | |||
4333 | offset += 4; | ||
4334 | |||
4335 | /* Check the data structure version */ | ||
4336 | if (buff[offset] != LPFC_REGION23_VERSION) { | ||
4337 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4338 | "2568 Config region 23 has bad version\n"); | ||
4339 | return; | ||
4340 | } | ||
4341 | offset += 4; | ||
4342 | |||
4343 | rec_length = buff[offset + 1]; | ||
4344 | |||
4345 | /* Read FCoE param record */ | ||
4346 | rec_ptr = lpfc_get_rec_conf23(&buff[offset], | ||
4347 | size - offset, FCOE_PARAM_TYPE); | ||
4348 | if (rec_ptr) | ||
4349 | lpfc_read_fcoe_param(phba, rec_ptr); | ||
4350 | |||
4351 | /* Read FCF connection table */ | ||
4352 | rec_ptr = lpfc_get_rec_conf23(&buff[offset], | ||
4353 | size - offset, FCOE_CONN_TBL_TYPE); | ||
4354 | if (rec_ptr) | ||
4355 | lpfc_read_fcf_conn_tbl(phba, rec_ptr); | ||
4356 | |||
4357 | } | ||