diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 1388 |
1 files changed, 1286 insertions, 102 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index e764ce0bf704..ed46b24a3380 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2009 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -29,10 +29,12 @@ | |||
29 | #include <scsi/scsi_host.h> | 29 | #include <scsi/scsi_host.h> |
30 | #include <scsi/scsi_transport_fc.h> | 30 | #include <scsi/scsi_transport_fc.h> |
31 | 31 | ||
32 | #include "lpfc_hw4.h" | ||
32 | #include "lpfc_hw.h" | 33 | #include "lpfc_hw.h" |
33 | #include "lpfc_nl.h" | 34 | #include "lpfc_nl.h" |
34 | #include "lpfc_disc.h" | 35 | #include "lpfc_disc.h" |
35 | #include "lpfc_sli.h" | 36 | #include "lpfc_sli.h" |
37 | #include "lpfc_sli4.h" | ||
36 | #include "lpfc_scsi.h" | 38 | #include "lpfc_scsi.h" |
37 | #include "lpfc.h" | 39 | #include "lpfc.h" |
38 | #include "lpfc_logmsg.h" | 40 | #include "lpfc_logmsg.h" |
@@ -273,6 +275,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
273 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && | 275 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
274 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) | 276 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) |
275 | 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); | ||
276 | } | 280 | } |
277 | 281 | ||
278 | /** | 282 | /** |
@@ -295,10 +299,11 @@ lpfc_alloc_fast_evt(struct lpfc_hba *phba) { | |||
295 | 299 | ||
296 | ret = kzalloc(sizeof(struct lpfc_fast_path_event), | 300 | ret = kzalloc(sizeof(struct lpfc_fast_path_event), |
297 | GFP_ATOMIC); | 301 | GFP_ATOMIC); |
298 | if (ret) | 302 | if (ret) { |
299 | atomic_inc(&phba->fast_event_count); | 303 | atomic_inc(&phba->fast_event_count); |
300 | INIT_LIST_HEAD(&ret->work_evt.evt_listp); | 304 | INIT_LIST_HEAD(&ret->work_evt.evt_listp); |
301 | ret->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT; | 305 | ret->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT; |
306 | } | ||
302 | return ret; | 307 | return ret; |
303 | } | 308 | } |
304 | 309 | ||
@@ -491,6 +496,10 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
491 | phba->work_ha = 0; | 496 | phba->work_ha = 0; |
492 | spin_unlock_irq(&phba->hbalock); | 497 | spin_unlock_irq(&phba->hbalock); |
493 | 498 | ||
499 | /* First, try to post the next mailbox command to SLI4 device */ | ||
500 | if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) | ||
501 | lpfc_sli4_post_async_mbox(phba); | ||
502 | |||
494 | if (ha_copy & HA_ERATT) | 503 | if (ha_copy & HA_ERATT) |
495 | /* Handle the error attention event */ | 504 | /* Handle the error attention event */ |
496 | lpfc_handle_eratt(phba); | 505 | lpfc_handle_eratt(phba); |
@@ -501,9 +510,27 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
501 | if (ha_copy & HA_LATT) | 510 | if (ha_copy & HA_LATT) |
502 | lpfc_handle_latt(phba); | 511 | lpfc_handle_latt(phba); |
503 | 512 | ||
513 | /* Process SLI4 events */ | ||
514 | if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) { | ||
515 | if (phba->hba_flag & FCP_XRI_ABORT_EVENT) | ||
516 | lpfc_sli4_fcp_xri_abort_event_proc(phba); | ||
517 | if (phba->hba_flag & ELS_XRI_ABORT_EVENT) | ||
518 | lpfc_sli4_els_xri_abort_event_proc(phba); | ||
519 | if (phba->hba_flag & ASYNC_EVENT) | ||
520 | lpfc_sli4_async_event_proc(phba); | ||
521 | if (phba->hba_flag & HBA_POST_RECEIVE_BUFFER) { | ||
522 | spin_lock_irq(&phba->hbalock); | ||
523 | phba->hba_flag &= ~HBA_POST_RECEIVE_BUFFER; | ||
524 | spin_unlock_irq(&phba->hbalock); | ||
525 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); | ||
526 | } | ||
527 | if (phba->hba_flag & HBA_RECEIVE_BUFFER) | ||
528 | lpfc_sli4_handle_received_buffer(phba); | ||
529 | } | ||
530 | |||
504 | vports = lpfc_create_vport_work_array(phba); | 531 | vports = lpfc_create_vport_work_array(phba); |
505 | if (vports != NULL) | 532 | if (vports != NULL) |
506 | for(i = 0; i <= phba->max_vpi; i++) { | 533 | for (i = 0; i <= phba->max_vports; i++) { |
507 | /* | 534 | /* |
508 | * We could have no vports in array if unloading, so if | 535 | * We could have no vports in array if unloading, so if |
509 | * this happens then just use the pport | 536 | * this happens then just use the pport |
@@ -555,23 +582,24 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
555 | /* | 582 | /* |
556 | * Turn on Ring interrupts | 583 | * Turn on Ring interrupts |
557 | */ | 584 | */ |
558 | spin_lock_irq(&phba->hbalock); | 585 | if (phba->sli_rev <= LPFC_SLI_REV3) { |
559 | control = readl(phba->HCregaddr); | 586 | spin_lock_irq(&phba->hbalock); |
560 | if (!(control & (HC_R0INT_ENA << LPFC_ELS_RING))) { | 587 | control = readl(phba->HCregaddr); |
561 | lpfc_debugfs_slow_ring_trc(phba, | 588 | if (!(control & (HC_R0INT_ENA << LPFC_ELS_RING))) { |
562 | "WRK Enable ring: cntl:x%x hacopy:x%x", | 589 | lpfc_debugfs_slow_ring_trc(phba, |
563 | control, ha_copy, 0); | 590 | "WRK Enable ring: cntl:x%x hacopy:x%x", |
564 | 591 | control, ha_copy, 0); | |
565 | control |= (HC_R0INT_ENA << LPFC_ELS_RING); | 592 | |
566 | writel(control, phba->HCregaddr); | 593 | control |= (HC_R0INT_ENA << LPFC_ELS_RING); |
567 | readl(phba->HCregaddr); /* flush */ | 594 | writel(control, phba->HCregaddr); |
568 | } | 595 | readl(phba->HCregaddr); /* flush */ |
569 | else { | 596 | } else { |
570 | lpfc_debugfs_slow_ring_trc(phba, | 597 | lpfc_debugfs_slow_ring_trc(phba, |
571 | "WRK Ring ok: cntl:x%x hacopy:x%x", | 598 | "WRK Ring ok: cntl:x%x hacopy:x%x", |
572 | control, ha_copy, 0); | 599 | control, ha_copy, 0); |
600 | } | ||
601 | spin_unlock_irq(&phba->hbalock); | ||
573 | } | 602 | } |
574 | spin_unlock_irq(&phba->hbalock); | ||
575 | } | 603 | } |
576 | lpfc_work_list_done(phba); | 604 | lpfc_work_list_done(phba); |
577 | } | 605 | } |
@@ -689,7 +717,7 @@ lpfc_port_link_failure(struct lpfc_vport *vport) | |||
689 | lpfc_can_disctmo(vport); | 717 | lpfc_can_disctmo(vport); |
690 | } | 718 | } |
691 | 719 | ||
692 | static void | 720 | void |
693 | lpfc_linkdown_port(struct lpfc_vport *vport) | 721 | lpfc_linkdown_port(struct lpfc_vport *vport) |
694 | { | 722 | { |
695 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 723 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
@@ -716,6 +744,7 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
716 | if (phba->link_state == LPFC_LINK_DOWN) | 744 | if (phba->link_state == LPFC_LINK_DOWN) |
717 | return 0; | 745 | return 0; |
718 | spin_lock_irq(&phba->hbalock); | 746 | spin_lock_irq(&phba->hbalock); |
747 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); | ||
719 | if (phba->link_state > LPFC_LINK_DOWN) { | 748 | if (phba->link_state > LPFC_LINK_DOWN) { |
720 | phba->link_state = LPFC_LINK_DOWN; | 749 | phba->link_state = LPFC_LINK_DOWN; |
721 | phba->pport->fc_flag &= ~FC_LBIT; | 750 | phba->pport->fc_flag &= ~FC_LBIT; |
@@ -723,7 +752,7 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
723 | spin_unlock_irq(&phba->hbalock); | 752 | spin_unlock_irq(&phba->hbalock); |
724 | vports = lpfc_create_vport_work_array(phba); | 753 | vports = lpfc_create_vport_work_array(phba); |
725 | if (vports != NULL) | 754 | if (vports != NULL) |
726 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | 755 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
727 | /* Issue a LINK DOWN event to all nodes */ | 756 | /* Issue a LINK DOWN event to all nodes */ |
728 | lpfc_linkdown_port(vports[i]); | 757 | lpfc_linkdown_port(vports[i]); |
729 | } | 758 | } |
@@ -833,10 +862,11 @@ lpfc_linkup(struct lpfc_hba *phba) | |||
833 | 862 | ||
834 | vports = lpfc_create_vport_work_array(phba); | 863 | vports = lpfc_create_vport_work_array(phba); |
835 | if (vports != NULL) | 864 | if (vports != NULL) |
836 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) | 865 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) |
837 | lpfc_linkup_port(vports[i]); | 866 | lpfc_linkup_port(vports[i]); |
838 | lpfc_destroy_vport_work_array(phba, vports); | 867 | lpfc_destroy_vport_work_array(phba, vports); |
839 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) | 868 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && |
869 | (phba->sli_rev < LPFC_SLI_REV4)) | ||
840 | lpfc_issue_clear_la(phba, phba->pport); | 870 | lpfc_issue_clear_la(phba, phba->pport); |
841 | 871 | ||
842 | return 0; | 872 | return 0; |
@@ -854,7 +884,7 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
854 | struct lpfc_vport *vport = pmb->vport; | 884 | struct lpfc_vport *vport = pmb->vport; |
855 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 885 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
856 | struct lpfc_sli *psli = &phba->sli; | 886 | struct lpfc_sli *psli = &phba->sli; |
857 | MAILBOX_t *mb = &pmb->mb; | 887 | MAILBOX_t *mb = &pmb->u.mb; |
858 | uint32_t control; | 888 | uint32_t control; |
859 | 889 | ||
860 | /* Since we don't do discovery right now, turn these off here */ | 890 | /* Since we don't do discovery right now, turn these off here */ |
@@ -917,7 +947,7 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
917 | { | 947 | { |
918 | struct lpfc_vport *vport = pmb->vport; | 948 | struct lpfc_vport *vport = pmb->vport; |
919 | 949 | ||
920 | if (pmb->mb.mbxStatus) | 950 | if (pmb->u.mb.mbxStatus) |
921 | goto out; | 951 | goto out; |
922 | 952 | ||
923 | mempool_free(pmb, phba->mbox_mem_pool); | 953 | mempool_free(pmb, phba->mbox_mem_pool); |
@@ -945,7 +975,7 @@ out: | |||
945 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 975 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
946 | "0306 CONFIG_LINK mbxStatus error x%x " | 976 | "0306 CONFIG_LINK mbxStatus error x%x " |
947 | "HBA state x%x\n", | 977 | "HBA state x%x\n", |
948 | pmb->mb.mbxStatus, vport->port_state); | 978 | pmb->u.mb.mbxStatus, vport->port_state); |
949 | mempool_free(pmb, phba->mbox_mem_pool); | 979 | mempool_free(pmb, phba->mbox_mem_pool); |
950 | 980 | ||
951 | lpfc_linkdown(phba); | 981 | lpfc_linkdown(phba); |
@@ -959,9 +989,612 @@ out: | |||
959 | } | 989 | } |
960 | 990 | ||
961 | 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 FCF not available return 0 */ | ||
1201 | if (!bf_get(lpfc_fcf_record_fcf_avail, new_fcf_record) || | ||
1202 | !bf_get(lpfc_fcf_record_fcf_valid, new_fcf_record)) | ||
1203 | return 0; | ||
1204 | |||
1205 | if (!phba->cfg_enable_fip) { | ||
1206 | *boot_flag = 0; | ||
1207 | *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1208 | new_fcf_record); | ||
1209 | if (phba->valid_vlan) | ||
1210 | *vlan_id = phba->vlan_id; | ||
1211 | else | ||
1212 | *vlan_id = 0xFFFF; | ||
1213 | return 1; | ||
1214 | } | ||
1215 | |||
1216 | /* | ||
1217 | * If there are no FCF connection table entry, driver connect to all | ||
1218 | * FCFs. | ||
1219 | */ | ||
1220 | if (list_empty(&phba->fcf_conn_rec_list)) { | ||
1221 | *boot_flag = 0; | ||
1222 | *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1223 | new_fcf_record); | ||
1224 | |||
1225 | /* | ||
1226 | * When there are no FCF connect entries, use driver's default | ||
1227 | * addressing mode - FPMA. | ||
1228 | */ | ||
1229 | if (*addr_mode & LPFC_FCF_FPMA) | ||
1230 | *addr_mode = LPFC_FCF_FPMA; | ||
1231 | |||
1232 | *vlan_id = 0xFFFF; | ||
1233 | return 1; | ||
1234 | } | ||
1235 | |||
1236 | list_for_each_entry(conn_entry, &phba->fcf_conn_rec_list, list) { | ||
1237 | if (!(conn_entry->conn_rec.flags & FCFCNCT_VALID)) | ||
1238 | continue; | ||
1239 | |||
1240 | if ((conn_entry->conn_rec.flags & FCFCNCT_FBNM_VALID) && | ||
1241 | !lpfc_fab_name_match(conn_entry->conn_rec.fabric_name, | ||
1242 | new_fcf_record)) | ||
1243 | continue; | ||
1244 | |||
1245 | if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID) { | ||
1246 | /* | ||
1247 | * If the vlan bit map does not have the bit set for the | ||
1248 | * vlan id to be used, then it is not a match. | ||
1249 | */ | ||
1250 | if (!(new_fcf_record->vlan_bitmap | ||
1251 | [conn_entry->conn_rec.vlan_tag / 8] & | ||
1252 | (1 << (conn_entry->conn_rec.vlan_tag % 8)))) | ||
1253 | continue; | ||
1254 | } | ||
1255 | |||
1256 | /* | ||
1257 | * If connection record does not support any addressing mode, | ||
1258 | * skip the FCF record. | ||
1259 | */ | ||
1260 | if (!(bf_get(lpfc_fcf_record_mac_addr_prov, new_fcf_record) | ||
1261 | & (LPFC_FCF_FPMA | LPFC_FCF_SPMA))) | ||
1262 | continue; | ||
1263 | |||
1264 | /* | ||
1265 | * Check if the connection record specifies a required | ||
1266 | * addressing mode. | ||
1267 | */ | ||
1268 | if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1269 | !(conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED)) { | ||
1270 | |||
1271 | /* | ||
1272 | * If SPMA required but FCF not support this continue. | ||
1273 | */ | ||
1274 | if ((conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1275 | !(bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1276 | new_fcf_record) & LPFC_FCF_SPMA)) | ||
1277 | continue; | ||
1278 | |||
1279 | /* | ||
1280 | * If FPMA required but FCF not support this continue. | ||
1281 | */ | ||
1282 | if (!(conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1283 | !(bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1284 | new_fcf_record) & LPFC_FCF_FPMA)) | ||
1285 | continue; | ||
1286 | } | ||
1287 | |||
1288 | /* | ||
1289 | * This fcf record matches filtering criteria. | ||
1290 | */ | ||
1291 | if (conn_entry->conn_rec.flags & FCFCNCT_BOOT) | ||
1292 | *boot_flag = 1; | ||
1293 | else | ||
1294 | *boot_flag = 0; | ||
1295 | |||
1296 | /* | ||
1297 | * If user did not specify any addressing mode, or if the | ||
1298 | * prefered addressing mode specified by user is not supported | ||
1299 | * by FCF, allow fabric to pick the addressing mode. | ||
1300 | */ | ||
1301 | *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1302 | new_fcf_record); | ||
1303 | /* | ||
1304 | * If the user specified a required address mode, assign that | ||
1305 | * address mode | ||
1306 | */ | ||
1307 | if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1308 | (!(conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED))) | ||
1309 | *addr_mode = (conn_entry->conn_rec.flags & | ||
1310 | FCFCNCT_AM_SPMA) ? | ||
1311 | LPFC_FCF_SPMA : LPFC_FCF_FPMA; | ||
1312 | /* | ||
1313 | * If the user specified a prefered address mode, use the | ||
1314 | * addr mode only if FCF support the addr_mode. | ||
1315 | */ | ||
1316 | else if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1317 | (conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED) && | ||
1318 | (conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1319 | (*addr_mode & LPFC_FCF_SPMA)) | ||
1320 | *addr_mode = LPFC_FCF_SPMA; | ||
1321 | else if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1322 | (conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED) && | ||
1323 | !(conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1324 | (*addr_mode & LPFC_FCF_FPMA)) | ||
1325 | *addr_mode = LPFC_FCF_FPMA; | ||
1326 | |||
1327 | if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID) | ||
1328 | *vlan_id = conn_entry->conn_rec.vlan_tag; | ||
1329 | else | ||
1330 | *vlan_id = 0xFFFF; | ||
1331 | |||
1332 | return 1; | ||
1333 | } | ||
1334 | |||
1335 | return 0; | ||
1336 | } | ||
1337 | |||
1338 | /** | ||
1339 | * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox. | ||
1340 | * @phba: pointer to lpfc hba data structure. | ||
1341 | * @mboxq: pointer to mailbox object. | ||
1342 | * | ||
1343 | * This function iterate through all the fcf records available in | ||
1344 | * HBA and choose the optimal FCF record for discovery. After finding | ||
1345 | * the FCF for discovery it register the FCF record and kick start | ||
1346 | * discovery. | ||
1347 | * If FCF_IN_USE flag is set in currently used FCF, the routine try to | ||
1348 | * use a FCF record which match fabric name and mac address of the | ||
1349 | * currently used FCF record. | ||
1350 | * If the driver support only one FCF, it will try to use the FCF record | ||
1351 | * used by BOOT_BIOS. | ||
1352 | */ | ||
1353 | void | ||
1354 | lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1355 | { | ||
1356 | void *virt_addr; | ||
1357 | dma_addr_t phys_addr; | ||
1358 | uint8_t *bytep; | ||
1359 | struct lpfc_mbx_sge sge; | ||
1360 | struct lpfc_mbx_read_fcf_tbl *read_fcf; | ||
1361 | uint32_t shdr_status, shdr_add_status; | ||
1362 | union lpfc_sli4_cfg_shdr *shdr; | ||
1363 | struct fcf_record *new_fcf_record; | ||
1364 | int rc; | ||
1365 | uint32_t boot_flag, addr_mode; | ||
1366 | uint32_t next_fcf_index; | ||
1367 | unsigned long flags; | ||
1368 | uint16_t vlan_id; | ||
1369 | |||
1370 | /* Get the first SGE entry from the non-embedded DMA memory. This | ||
1371 | * routine only uses a single SGE. | ||
1372 | */ | ||
1373 | lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); | ||
1374 | phys_addr = getPaddr(sge.pa_hi, sge.pa_lo); | ||
1375 | if (unlikely(!mboxq->sge_array)) { | ||
1376 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
1377 | "2524 Failed to get the non-embedded SGE " | ||
1378 | "virtual address\n"); | ||
1379 | goto out; | ||
1380 | } | ||
1381 | virt_addr = mboxq->sge_array->addr[0]; | ||
1382 | |||
1383 | shdr = (union lpfc_sli4_cfg_shdr *)virt_addr; | ||
1384 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
1385 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | ||
1386 | &shdr->response); | ||
1387 | /* | ||
1388 | * The FCF Record was read and there is no reason for the driver | ||
1389 | * to maintain the FCF record data or memory. Instead, just need | ||
1390 | * to book keeping the FCFIs can be used. | ||
1391 | */ | ||
1392 | if (shdr_status || shdr_add_status) { | ||
1393 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1394 | "2521 READ_FCF_RECORD mailbox failed " | ||
1395 | "with status x%x add_status x%x, mbx\n", | ||
1396 | shdr_status, shdr_add_status); | ||
1397 | goto out; | ||
1398 | } | ||
1399 | /* Interpreting the returned information of FCF records */ | ||
1400 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; | ||
1401 | lpfc_sli_pcimem_bcopy(read_fcf, read_fcf, | ||
1402 | sizeof(struct lpfc_mbx_read_fcf_tbl)); | ||
1403 | next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf); | ||
1404 | |||
1405 | new_fcf_record = (struct fcf_record *)(virt_addr + | ||
1406 | sizeof(struct lpfc_mbx_read_fcf_tbl)); | ||
1407 | lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record, | ||
1408 | sizeof(struct fcf_record)); | ||
1409 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | ||
1410 | |||
1411 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, | ||
1412 | &boot_flag, &addr_mode, | ||
1413 | &vlan_id); | ||
1414 | /* | ||
1415 | * If the fcf record does not match with connect list entries | ||
1416 | * read the next entry. | ||
1417 | */ | ||
1418 | if (!rc) | ||
1419 | goto read_next_fcf; | ||
1420 | /* | ||
1421 | * If this is not the first FCF discovery of the HBA, use last | ||
1422 | * FCF record for the discovery. | ||
1423 | */ | ||
1424 | spin_lock_irqsave(&phba->hbalock, flags); | ||
1425 | if (phba->fcf.fcf_flag & FCF_IN_USE) { | ||
1426 | if (lpfc_fab_name_match(phba->fcf.fabric_name, | ||
1427 | new_fcf_record) && | ||
1428 | lpfc_mac_addr_match(phba, new_fcf_record)) { | ||
1429 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | ||
1430 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1431 | goto out; | ||
1432 | } | ||
1433 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1434 | goto read_next_fcf; | ||
1435 | } | ||
1436 | if (phba->fcf.fcf_flag & FCF_AVAILABLE) { | ||
1437 | /* | ||
1438 | * If the current FCF record does not have boot flag | ||
1439 | * set and new fcf record has boot flag set, use the | ||
1440 | * new fcf record. | ||
1441 | */ | ||
1442 | if (boot_flag && !(phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | ||
1443 | /* Use this FCF record */ | ||
1444 | lpfc_copy_fcf_record(phba, new_fcf_record); | ||
1445 | phba->fcf.addr_mode = addr_mode; | ||
1446 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | ||
1447 | if (vlan_id != 0xFFFF) { | ||
1448 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1449 | phba->fcf.vlan_id = vlan_id; | ||
1450 | } | ||
1451 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1452 | goto read_next_fcf; | ||
1453 | } | ||
1454 | /* | ||
1455 | * If the current FCF record has boot flag set and the | ||
1456 | * new FCF record does not have boot flag, read the next | ||
1457 | * FCF record. | ||
1458 | */ | ||
1459 | if (!boot_flag && (phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | ||
1460 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1461 | goto read_next_fcf; | ||
1462 | } | ||
1463 | /* | ||
1464 | * If there is a record with lower priority value for | ||
1465 | * the current FCF, use that record. | ||
1466 | */ | ||
1467 | if (lpfc_fab_name_match(phba->fcf.fabric_name, new_fcf_record) | ||
1468 | && (new_fcf_record->fip_priority < | ||
1469 | phba->fcf.priority)) { | ||
1470 | /* Use this FCF record */ | ||
1471 | lpfc_copy_fcf_record(phba, new_fcf_record); | ||
1472 | phba->fcf.addr_mode = addr_mode; | ||
1473 | if (vlan_id != 0xFFFF) { | ||
1474 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1475 | phba->fcf.vlan_id = vlan_id; | ||
1476 | } | ||
1477 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1478 | goto read_next_fcf; | ||
1479 | } | ||
1480 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1481 | goto read_next_fcf; | ||
1482 | } | ||
1483 | /* | ||
1484 | * This is the first available FCF record, use this | ||
1485 | * record. | ||
1486 | */ | ||
1487 | lpfc_copy_fcf_record(phba, new_fcf_record); | ||
1488 | phba->fcf.addr_mode = addr_mode; | ||
1489 | if (boot_flag) | ||
1490 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | ||
1491 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | ||
1492 | if (vlan_id != 0xFFFF) { | ||
1493 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1494 | phba->fcf.vlan_id = vlan_id; | ||
1495 | } | ||
1496 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1497 | goto read_next_fcf; | ||
1498 | |||
1499 | read_next_fcf: | ||
1500 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1501 | if (next_fcf_index == LPFC_FCOE_FCF_NEXT_NONE || next_fcf_index == 0) | ||
1502 | lpfc_register_fcf(phba); | ||
1503 | else | ||
1504 | lpfc_sli4_read_fcf_record(phba, next_fcf_index); | ||
1505 | return; | ||
1506 | |||
1507 | out: | ||
1508 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1509 | lpfc_register_fcf(phba); | ||
1510 | |||
1511 | return; | ||
1512 | } | ||
1513 | |||
1514 | /** | ||
1515 | * lpfc_start_fdiscs - send fdiscs for each vports on this port. | ||
1516 | * @phba: pointer to lpfc hba data structure. | ||
1517 | * | ||
1518 | * This function loops through the list of vports on the @phba and issues an | ||
1519 | * FDISC if possible. | ||
1520 | */ | ||
1521 | void | ||
1522 | lpfc_start_fdiscs(struct lpfc_hba *phba) | ||
1523 | { | ||
1524 | struct lpfc_vport **vports; | ||
1525 | int i; | ||
1526 | |||
1527 | vports = lpfc_create_vport_work_array(phba); | ||
1528 | if (vports != NULL) { | ||
1529 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
1530 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | ||
1531 | continue; | ||
1532 | /* There are no vpi for this vport */ | ||
1533 | if (vports[i]->vpi > phba->max_vpi) { | ||
1534 | lpfc_vport_set_state(vports[i], | ||
1535 | FC_VPORT_FAILED); | ||
1536 | continue; | ||
1537 | } | ||
1538 | if (phba->fc_topology == TOPOLOGY_LOOP) { | ||
1539 | lpfc_vport_set_state(vports[i], | ||
1540 | FC_VPORT_LINKDOWN); | ||
1541 | continue; | ||
1542 | } | ||
1543 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | ||
1544 | lpfc_initial_fdisc(vports[i]); | ||
1545 | else { | ||
1546 | lpfc_vport_set_state(vports[i], | ||
1547 | FC_VPORT_NO_FABRIC_SUPP); | ||
1548 | lpfc_printf_vlog(vports[i], KERN_ERR, | ||
1549 | LOG_ELS, | ||
1550 | "0259 No NPIV " | ||
1551 | "Fabric support\n"); | ||
1552 | } | ||
1553 | } | ||
1554 | } | ||
1555 | lpfc_destroy_vport_work_array(phba, vports); | ||
1556 | } | ||
1557 | |||
1558 | void | ||
1559 | lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1560 | { | ||
1561 | struct lpfc_dmabuf *dmabuf = mboxq->context1; | ||
1562 | struct lpfc_vport *vport = mboxq->vport; | ||
1563 | |||
1564 | if (mboxq->u.mb.mbxStatus) { | ||
1565 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | ||
1566 | "2018 REG_VFI mbxStatus error x%x " | ||
1567 | "HBA state x%x\n", | ||
1568 | mboxq->u.mb.mbxStatus, vport->port_state); | ||
1569 | if (phba->fc_topology == TOPOLOGY_LOOP) { | ||
1570 | /* FLOGI failed, use loop map to make discovery list */ | ||
1571 | lpfc_disc_list_loopmap(vport); | ||
1572 | /* Start discovery */ | ||
1573 | lpfc_disc_start(vport); | ||
1574 | goto fail_free_mem; | ||
1575 | } | ||
1576 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
1577 | goto fail_free_mem; | ||
1578 | } | ||
1579 | /* Mark the vport has registered with its VFI */ | ||
1580 | vport->vfi_state |= LPFC_VFI_REGISTERED; | ||
1581 | |||
1582 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { | ||
1583 | lpfc_start_fdiscs(phba); | ||
1584 | lpfc_do_scr_ns_plogi(phba, vport); | ||
1585 | } | ||
1586 | |||
1587 | fail_free_mem: | ||
1588 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1589 | lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); | ||
1590 | kfree(dmabuf); | ||
1591 | return; | ||
1592 | } | ||
1593 | |||
1594 | static void | ||
962 | lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 1595 | lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
963 | { | 1596 | { |
964 | MAILBOX_t *mb = &pmb->mb; | 1597 | MAILBOX_t *mb = &pmb->u.mb; |
965 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; | 1598 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; |
966 | struct lpfc_vport *vport = pmb->vport; | 1599 | struct lpfc_vport *vport = pmb->vport; |
967 | 1600 | ||
@@ -1012,13 +1645,13 @@ static void | |||
1012 | lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | 1645 | lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) |
1013 | { | 1646 | { |
1014 | struct lpfc_vport *vport = phba->pport; | 1647 | struct lpfc_vport *vport = phba->pport; |
1015 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox; | 1648 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox = NULL; |
1016 | int i; | 1649 | int i; |
1017 | struct lpfc_dmabuf *mp; | 1650 | struct lpfc_dmabuf *mp; |
1018 | int rc; | 1651 | int rc; |
1652 | struct fcf_record *fcf_record; | ||
1019 | 1653 | ||
1020 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1654 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
1021 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
1022 | 1655 | ||
1023 | spin_lock_irq(&phba->hbalock); | 1656 | spin_lock_irq(&phba->hbalock); |
1024 | switch (la->UlnkSpeed) { | 1657 | switch (la->UlnkSpeed) { |
@@ -1034,6 +1667,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
1034 | case LA_8GHZ_LINK: | 1667 | case LA_8GHZ_LINK: |
1035 | phba->fc_linkspeed = LA_8GHZ_LINK; | 1668 | phba->fc_linkspeed = LA_8GHZ_LINK; |
1036 | break; | 1669 | break; |
1670 | case LA_10GHZ_LINK: | ||
1671 | phba->fc_linkspeed = LA_10GHZ_LINK; | ||
1672 | break; | ||
1037 | default: | 1673 | default: |
1038 | phba->fc_linkspeed = LA_UNKNW_LINK; | 1674 | phba->fc_linkspeed = LA_UNKNW_LINK; |
1039 | break; | 1675 | break; |
@@ -1115,22 +1751,66 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
1115 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1751 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1116 | kfree(mp); | 1752 | kfree(mp); |
1117 | mempool_free(sparam_mbox, phba->mbox_mem_pool); | 1753 | mempool_free(sparam_mbox, phba->mbox_mem_pool); |
1118 | if (cfglink_mbox) | ||
1119 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); | ||
1120 | goto out; | 1754 | goto out; |
1121 | } | 1755 | } |
1122 | } | 1756 | } |
1123 | 1757 | ||
1124 | if (cfglink_mbox) { | 1758 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) { |
1759 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
1760 | if (!cfglink_mbox) | ||
1761 | goto out; | ||
1125 | vport->port_state = LPFC_LOCAL_CFG_LINK; | 1762 | vport->port_state = LPFC_LOCAL_CFG_LINK; |
1126 | lpfc_config_link(phba, cfglink_mbox); | 1763 | lpfc_config_link(phba, cfglink_mbox); |
1127 | cfglink_mbox->vport = vport; | 1764 | cfglink_mbox->vport = vport; |
1128 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; | 1765 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; |
1129 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT); | 1766 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT); |
1130 | if (rc != MBX_NOT_FINISHED) | 1767 | if (rc == MBX_NOT_FINISHED) { |
1131 | return; | 1768 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); |
1132 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); | 1769 | goto out; |
1770 | } | ||
1771 | } else { | ||
1772 | /* | ||
1773 | * Add the driver's default FCF record at FCF index 0 now. This | ||
1774 | * is phase 1 implementation that support FCF index 0 and driver | ||
1775 | * defaults. | ||
1776 | */ | ||
1777 | if (phba->cfg_enable_fip == 0) { | ||
1778 | fcf_record = kzalloc(sizeof(struct fcf_record), | ||
1779 | GFP_KERNEL); | ||
1780 | if (unlikely(!fcf_record)) { | ||
1781 | lpfc_printf_log(phba, KERN_ERR, | ||
1782 | LOG_MBOX | LOG_SLI, | ||
1783 | "2554 Could not allocate memmory for " | ||
1784 | "fcf record\n"); | ||
1785 | rc = -ENODEV; | ||
1786 | goto out; | ||
1787 | } | ||
1788 | |||
1789 | lpfc_sli4_build_dflt_fcf_record(phba, fcf_record, | ||
1790 | LPFC_FCOE_FCF_DEF_INDEX); | ||
1791 | rc = lpfc_sli4_add_fcf_record(phba, fcf_record); | ||
1792 | if (unlikely(rc)) { | ||
1793 | lpfc_printf_log(phba, KERN_ERR, | ||
1794 | LOG_MBOX | LOG_SLI, | ||
1795 | "2013 Could not manually add FCF " | ||
1796 | "record 0, status %d\n", rc); | ||
1797 | rc = -ENODEV; | ||
1798 | kfree(fcf_record); | ||
1799 | goto out; | ||
1800 | } | ||
1801 | kfree(fcf_record); | ||
1802 | } | ||
1803 | /* | ||
1804 | * The driver is expected to do FIP/FCF. Call the port | ||
1805 | * and get the FCF Table. | ||
1806 | */ | ||
1807 | rc = lpfc_sli4_read_fcf_record(phba, | ||
1808 | LPFC_FCOE_FCF_GET_FIRST); | ||
1809 | if (rc) | ||
1810 | goto out; | ||
1133 | } | 1811 | } |
1812 | |||
1813 | return; | ||
1134 | out: | 1814 | out: |
1135 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 1815 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
1136 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 1816 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
@@ -1147,10 +1827,12 @@ lpfc_enable_la(struct lpfc_hba *phba) | |||
1147 | struct lpfc_sli *psli = &phba->sli; | 1827 | struct lpfc_sli *psli = &phba->sli; |
1148 | spin_lock_irq(&phba->hbalock); | 1828 | spin_lock_irq(&phba->hbalock); |
1149 | psli->sli_flag |= LPFC_PROCESS_LA; | 1829 | psli->sli_flag |= LPFC_PROCESS_LA; |
1150 | control = readl(phba->HCregaddr); | 1830 | if (phba->sli_rev <= LPFC_SLI_REV3) { |
1151 | control |= HC_LAINT_ENA; | 1831 | control = readl(phba->HCregaddr); |
1152 | writel(control, phba->HCregaddr); | 1832 | control |= HC_LAINT_ENA; |
1153 | readl(phba->HCregaddr); /* flush */ | 1833 | writel(control, phba->HCregaddr); |
1834 | readl(phba->HCregaddr); /* flush */ | ||
1835 | } | ||
1154 | spin_unlock_irq(&phba->hbalock); | 1836 | spin_unlock_irq(&phba->hbalock); |
1155 | } | 1837 | } |
1156 | 1838 | ||
@@ -1159,6 +1841,7 @@ lpfc_mbx_issue_link_down(struct lpfc_hba *phba) | |||
1159 | { | 1841 | { |
1160 | lpfc_linkdown(phba); | 1842 | lpfc_linkdown(phba); |
1161 | lpfc_enable_la(phba); | 1843 | lpfc_enable_la(phba); |
1844 | lpfc_unregister_unused_fcf(phba); | ||
1162 | /* turn on Link Attention interrupts - no CLEAR_LA needed */ | 1845 | /* turn on Link Attention interrupts - no CLEAR_LA needed */ |
1163 | } | 1846 | } |
1164 | 1847 | ||
@@ -1175,7 +1858,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1175 | struct lpfc_vport *vport = pmb->vport; | 1858 | struct lpfc_vport *vport = pmb->vport; |
1176 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 1859 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1177 | READ_LA_VAR *la; | 1860 | READ_LA_VAR *la; |
1178 | MAILBOX_t *mb = &pmb->mb; | 1861 | MAILBOX_t *mb = &pmb->u.mb; |
1179 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | 1862 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
1180 | 1863 | ||
1181 | /* Unblock ELS traffic */ | 1864 | /* Unblock ELS traffic */ |
@@ -1190,7 +1873,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1190 | goto lpfc_mbx_cmpl_read_la_free_mbuf; | 1873 | goto lpfc_mbx_cmpl_read_la_free_mbuf; |
1191 | } | 1874 | } |
1192 | 1875 | ||
1193 | la = (READ_LA_VAR *) & pmb->mb.un.varReadLA; | 1876 | la = (READ_LA_VAR *) &pmb->u.mb.un.varReadLA; |
1194 | 1877 | ||
1195 | memcpy(&phba->alpa_map[0], mp->virt, 128); | 1878 | memcpy(&phba->alpa_map[0], mp->virt, 128); |
1196 | 1879 | ||
@@ -1201,7 +1884,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1201 | vport->fc_flag &= ~FC_BYPASSED_MODE; | 1884 | vport->fc_flag &= ~FC_BYPASSED_MODE; |
1202 | spin_unlock_irq(shost->host_lock); | 1885 | spin_unlock_irq(shost->host_lock); |
1203 | 1886 | ||
1204 | if (((phba->fc_eventTag + 1) < la->eventTag) || | 1887 | if ((phba->fc_eventTag < la->eventTag) || |
1205 | (phba->fc_eventTag == la->eventTag)) { | 1888 | (phba->fc_eventTag == la->eventTag)) { |
1206 | phba->fc_stat.LinkMultiEvent++; | 1889 | phba->fc_stat.LinkMultiEvent++; |
1207 | if (la->attType == AT_LINK_UP) | 1890 | if (la->attType == AT_LINK_UP) |
@@ -1328,7 +2011,7 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1328 | static void | 2011 | static void |
1329 | lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 2012 | lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
1330 | { | 2013 | { |
1331 | MAILBOX_t *mb = &pmb->mb; | 2014 | MAILBOX_t *mb = &pmb->u.mb; |
1332 | struct lpfc_vport *vport = pmb->vport; | 2015 | struct lpfc_vport *vport = pmb->vport; |
1333 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 2016 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1334 | 2017 | ||
@@ -1381,7 +2064,7 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1381 | { | 2064 | { |
1382 | struct lpfc_vport *vport = pmb->vport; | 2065 | struct lpfc_vport *vport = pmb->vport; |
1383 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 2066 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1384 | MAILBOX_t *mb = &pmb->mb; | 2067 | MAILBOX_t *mb = &pmb->u.mb; |
1385 | 2068 | ||
1386 | switch (mb->mbxStatus) { | 2069 | switch (mb->mbxStatus) { |
1387 | case 0x0011: | 2070 | case 0x0011: |
@@ -1416,6 +2099,128 @@ out: | |||
1416 | return; | 2099 | return; |
1417 | } | 2100 | } |
1418 | 2101 | ||
2102 | /** | ||
2103 | * lpfc_create_static_vport - Read HBA config region to create static vports. | ||
2104 | * @phba: pointer to lpfc hba data structure. | ||
2105 | * | ||
2106 | * This routine issue a DUMP mailbox command for config region 22 to get | ||
2107 | * the list of static vports to be created. The function create vports | ||
2108 | * based on the information returned from the HBA. | ||
2109 | **/ | ||
2110 | void | ||
2111 | lpfc_create_static_vport(struct lpfc_hba *phba) | ||
2112 | { | ||
2113 | LPFC_MBOXQ_t *pmb = NULL; | ||
2114 | MAILBOX_t *mb; | ||
2115 | struct static_vport_info *vport_info; | ||
2116 | int rc, i; | ||
2117 | struct fc_vport_identifiers vport_id; | ||
2118 | struct fc_vport *new_fc_vport; | ||
2119 | struct Scsi_Host *shost; | ||
2120 | struct lpfc_vport *vport; | ||
2121 | uint16_t offset = 0; | ||
2122 | uint8_t *vport_buff; | ||
2123 | |||
2124 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
2125 | if (!pmb) { | ||
2126 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
2127 | "0542 lpfc_create_static_vport failed to" | ||
2128 | " allocate mailbox memory\n"); | ||
2129 | return; | ||
2130 | } | ||
2131 | |||
2132 | mb = &pmb->u.mb; | ||
2133 | |||
2134 | vport_info = kzalloc(sizeof(struct static_vport_info), GFP_KERNEL); | ||
2135 | if (!vport_info) { | ||
2136 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
2137 | "0543 lpfc_create_static_vport failed to" | ||
2138 | " allocate vport_info\n"); | ||
2139 | mempool_free(pmb, phba->mbox_mem_pool); | ||
2140 | return; | ||
2141 | } | ||
2142 | |||
2143 | vport_buff = (uint8_t *) vport_info; | ||
2144 | do { | ||
2145 | lpfc_dump_static_vport(phba, pmb, offset); | ||
2146 | pmb->vport = phba->pport; | ||
2147 | rc = lpfc_sli_issue_mbox_wait(phba, pmb, LPFC_MBOX_TMO); | ||
2148 | |||
2149 | if ((rc != MBX_SUCCESS) || mb->mbxStatus) { | ||
2150 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
2151 | "0544 lpfc_create_static_vport failed to" | ||
2152 | " issue dump mailbox command ret 0x%x " | ||
2153 | "status 0x%x\n", | ||
2154 | rc, mb->mbxStatus); | ||
2155 | goto out; | ||
2156 | } | ||
2157 | |||
2158 | if (mb->un.varDmp.word_cnt > | ||
2159 | sizeof(struct static_vport_info) - offset) | ||
2160 | mb->un.varDmp.word_cnt = | ||
2161 | sizeof(struct static_vport_info) - offset; | ||
2162 | |||
2163 | lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET, | ||
2164 | vport_buff + offset, | ||
2165 | mb->un.varDmp.word_cnt); | ||
2166 | offset += mb->un.varDmp.word_cnt; | ||
2167 | |||
2168 | } while (mb->un.varDmp.word_cnt && | ||
2169 | offset < sizeof(struct static_vport_info)); | ||
2170 | |||
2171 | |||
2172 | if ((le32_to_cpu(vport_info->signature) != VPORT_INFO_SIG) || | ||
2173 | ((le32_to_cpu(vport_info->rev) & VPORT_INFO_REV_MASK) | ||
2174 | != VPORT_INFO_REV)) { | ||
2175 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
2176 | "0545 lpfc_create_static_vport bad" | ||
2177 | " information header 0x%x 0x%x\n", | ||
2178 | le32_to_cpu(vport_info->signature), | ||
2179 | le32_to_cpu(vport_info->rev) & VPORT_INFO_REV_MASK); | ||
2180 | |||
2181 | goto out; | ||
2182 | } | ||
2183 | |||
2184 | shost = lpfc_shost_from_vport(phba->pport); | ||
2185 | |||
2186 | for (i = 0; i < MAX_STATIC_VPORT_COUNT; i++) { | ||
2187 | memset(&vport_id, 0, sizeof(vport_id)); | ||
2188 | vport_id.port_name = wwn_to_u64(vport_info->vport_list[i].wwpn); | ||
2189 | vport_id.node_name = wwn_to_u64(vport_info->vport_list[i].wwnn); | ||
2190 | if (!vport_id.port_name || !vport_id.node_name) | ||
2191 | continue; | ||
2192 | |||
2193 | vport_id.roles = FC_PORT_ROLE_FCP_INITIATOR; | ||
2194 | vport_id.vport_type = FC_PORTTYPE_NPIV; | ||
2195 | vport_id.disable = false; | ||
2196 | new_fc_vport = fc_vport_create(shost, 0, &vport_id); | ||
2197 | |||
2198 | if (!new_fc_vport) { | ||
2199 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
2200 | "0546 lpfc_create_static_vport failed to" | ||
2201 | " create vport \n"); | ||
2202 | continue; | ||
2203 | } | ||
2204 | |||
2205 | vport = *(struct lpfc_vport **)new_fc_vport->dd_data; | ||
2206 | vport->vport_flag |= STATIC_VPORT; | ||
2207 | } | ||
2208 | |||
2209 | out: | ||
2210 | /* | ||
2211 | * If this is timed out command, setting NULL to context2 tell SLI | ||
2212 | * layer not to use this buffer. | ||
2213 | */ | ||
2214 | spin_lock_irq(&phba->hbalock); | ||
2215 | pmb->context2 = NULL; | ||
2216 | spin_unlock_irq(&phba->hbalock); | ||
2217 | kfree(vport_info); | ||
2218 | if (rc != MBX_TIMEOUT) | ||
2219 | mempool_free(pmb, phba->mbox_mem_pool); | ||
2220 | |||
2221 | return; | ||
2222 | } | ||
2223 | |||
1419 | /* | 2224 | /* |
1420 | * This routine handles processing a Fabric REG_LOGIN mailbox | 2225 | * This routine handles processing a Fabric REG_LOGIN mailbox |
1421 | * command upon completion. It is setup in the LPFC_MBOXQ | 2226 | * command upon completion. It is setup in the LPFC_MBOXQ |
@@ -1426,16 +2231,17 @@ void | |||
1426 | lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 2231 | lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
1427 | { | 2232 | { |
1428 | struct lpfc_vport *vport = pmb->vport; | 2233 | struct lpfc_vport *vport = pmb->vport; |
1429 | MAILBOX_t *mb = &pmb->mb; | 2234 | MAILBOX_t *mb = &pmb->u.mb; |
1430 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | 2235 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
1431 | struct lpfc_nodelist *ndlp; | 2236 | struct lpfc_nodelist *ndlp; |
1432 | struct lpfc_vport **vports; | ||
1433 | int i; | ||
1434 | 2237 | ||
1435 | ndlp = (struct lpfc_nodelist *) pmb->context2; | 2238 | ndlp = (struct lpfc_nodelist *) pmb->context2; |
1436 | pmb->context1 = NULL; | 2239 | pmb->context1 = NULL; |
1437 | pmb->context2 = NULL; | 2240 | pmb->context2 = NULL; |
1438 | if (mb->mbxStatus) { | 2241 | if (mb->mbxStatus) { |
2242 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | ||
2243 | "0258 Register Fabric login error: 0x%x\n", | ||
2244 | mb->mbxStatus); | ||
1439 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 2245 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1440 | kfree(mp); | 2246 | kfree(mp); |
1441 | mempool_free(pmb, phba->mbox_mem_pool); | 2247 | mempool_free(pmb, phba->mbox_mem_pool); |
@@ -1454,9 +2260,6 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1454 | } | 2260 | } |
1455 | 2261 | ||
1456 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 2262 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
1457 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | ||
1458 | "0258 Register Fabric login error: 0x%x\n", | ||
1459 | mb->mbxStatus); | ||
1460 | /* Decrement the reference count to ndlp after the reference | 2263 | /* Decrement the reference count to ndlp after the reference |
1461 | * to the ndlp are done. | 2264 | * to the ndlp are done. |
1462 | */ | 2265 | */ |
@@ -1465,34 +2268,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1465 | } | 2268 | } |
1466 | 2269 | ||
1467 | ndlp->nlp_rpi = mb->un.varWords[0]; | 2270 | ndlp->nlp_rpi = mb->un.varWords[0]; |
2271 | ndlp->nlp_flag |= NLP_RPI_VALID; | ||
1468 | ndlp->nlp_type |= NLP_FABRIC; | 2272 | ndlp->nlp_type |= NLP_FABRIC; |
1469 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | 2273 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1470 | 2274 | ||
1471 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { | 2275 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { |
1472 | vports = lpfc_create_vport_work_array(phba); | 2276 | lpfc_start_fdiscs(phba); |
1473 | if (vports != NULL) | ||
1474 | for(i = 0; | ||
1475 | i <= phba->max_vpi && vports[i] != NULL; | ||
1476 | i++) { | ||
1477 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | ||
1478 | continue; | ||
1479 | if (phba->fc_topology == TOPOLOGY_LOOP) { | ||
1480 | lpfc_vport_set_state(vports[i], | ||
1481 | FC_VPORT_LINKDOWN); | ||
1482 | continue; | ||
1483 | } | ||
1484 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | ||
1485 | lpfc_initial_fdisc(vports[i]); | ||
1486 | else { | ||
1487 | lpfc_vport_set_state(vports[i], | ||
1488 | FC_VPORT_NO_FABRIC_SUPP); | ||
1489 | lpfc_printf_vlog(vport, KERN_ERR, | ||
1490 | LOG_ELS, | ||
1491 | "0259 No NPIV " | ||
1492 | "Fabric support\n"); | ||
1493 | } | ||
1494 | } | ||
1495 | lpfc_destroy_vport_work_array(phba, vports); | ||
1496 | lpfc_do_scr_ns_plogi(phba, vport); | 2277 | lpfc_do_scr_ns_plogi(phba, vport); |
1497 | } | 2278 | } |
1498 | 2279 | ||
@@ -1516,13 +2297,16 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1516 | void | 2297 | void |
1517 | lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 2298 | lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
1518 | { | 2299 | { |
1519 | MAILBOX_t *mb = &pmb->mb; | 2300 | MAILBOX_t *mb = &pmb->u.mb; |
1520 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | 2301 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
1521 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; | 2302 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
1522 | struct lpfc_vport *vport = pmb->vport; | 2303 | struct lpfc_vport *vport = pmb->vport; |
1523 | 2304 | ||
1524 | if (mb->mbxStatus) { | 2305 | if (mb->mbxStatus) { |
1525 | out: | 2306 | out: |
2307 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
2308 | "0260 Register NameServer error: 0x%x\n", | ||
2309 | mb->mbxStatus); | ||
1526 | /* decrement the node reference count held for this | 2310 | /* decrement the node reference count held for this |
1527 | * callback function. | 2311 | * callback function. |
1528 | */ | 2312 | */ |
@@ -1546,15 +2330,13 @@ out: | |||
1546 | return; | 2330 | return; |
1547 | } | 2331 | } |
1548 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 2332 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
1549 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
1550 | "0260 Register NameServer error: 0x%x\n", | ||
1551 | mb->mbxStatus); | ||
1552 | return; | 2333 | return; |
1553 | } | 2334 | } |
1554 | 2335 | ||
1555 | pmb->context1 = NULL; | 2336 | pmb->context1 = NULL; |
1556 | 2337 | ||
1557 | ndlp->nlp_rpi = mb->un.varWords[0]; | 2338 | ndlp->nlp_rpi = mb->un.varWords[0]; |
2339 | ndlp->nlp_flag |= NLP_RPI_VALID; | ||
1558 | ndlp->nlp_type |= NLP_FABRIC; | 2340 | ndlp->nlp_type |= NLP_FABRIC; |
1559 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | 2341 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1560 | 2342 | ||
@@ -2055,7 +2837,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba *phba, | |||
2055 | if (pring->ringno == LPFC_ELS_RING) { | 2837 | if (pring->ringno == LPFC_ELS_RING) { |
2056 | switch (icmd->ulpCommand) { | 2838 | switch (icmd->ulpCommand) { |
2057 | case CMD_GEN_REQUEST64_CR: | 2839 | case CMD_GEN_REQUEST64_CR: |
2058 | if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) | 2840 | if (iocb->context_un.ndlp == ndlp) |
2059 | return 1; | 2841 | return 1; |
2060 | case CMD_ELS_REQUEST64_CR: | 2842 | case CMD_ELS_REQUEST64_CR: |
2061 | if (icmd->un.elsreq64.remoteID == ndlp->nlp_DID) | 2843 | if (icmd->un.elsreq64.remoteID == ndlp->nlp_DID) |
@@ -2102,7 +2884,7 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
2102 | */ | 2884 | */ |
2103 | psli = &phba->sli; | 2885 | psli = &phba->sli; |
2104 | rpi = ndlp->nlp_rpi; | 2886 | rpi = ndlp->nlp_rpi; |
2105 | if (rpi) { | 2887 | if (ndlp->nlp_flag & NLP_RPI_VALID) { |
2106 | /* Now process each ring */ | 2888 | /* Now process each ring */ |
2107 | for (i = 0; i < psli->num_rings; i++) { | 2889 | for (i = 0; i < psli->num_rings; i++) { |
2108 | pring = &psli->ring[i]; | 2890 | pring = &psli->ring[i]; |
@@ -2150,7 +2932,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2150 | LPFC_MBOXQ_t *mbox; | 2932 | LPFC_MBOXQ_t *mbox; |
2151 | int rc; | 2933 | int rc; |
2152 | 2934 | ||
2153 | if (ndlp->nlp_rpi) { | 2935 | if (ndlp->nlp_flag & NLP_RPI_VALID) { |
2154 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 2936 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
2155 | if (mbox) { | 2937 | if (mbox) { |
2156 | lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox); | 2938 | lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox); |
@@ -2162,6 +2944,8 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2162 | } | 2944 | } |
2163 | lpfc_no_rpi(phba, ndlp); | 2945 | lpfc_no_rpi(phba, ndlp); |
2164 | ndlp->nlp_rpi = 0; | 2946 | ndlp->nlp_rpi = 0; |
2947 | ndlp->nlp_flag &= ~NLP_RPI_VALID; | ||
2948 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | ||
2165 | return 1; | 2949 | return 1; |
2166 | } | 2950 | } |
2167 | return 0; | 2951 | return 0; |
@@ -2252,7 +3036,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2252 | 3036 | ||
2253 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ | 3037 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ |
2254 | if ((mb = phba->sli.mbox_active)) { | 3038 | if ((mb = phba->sli.mbox_active)) { |
2255 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 3039 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && |
2256 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 3040 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
2257 | mb->context2 = NULL; | 3041 | mb->context2 = NULL; |
2258 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 3042 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
@@ -2261,7 +3045,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2261 | 3045 | ||
2262 | spin_lock_irq(&phba->hbalock); | 3046 | spin_lock_irq(&phba->hbalock); |
2263 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { | 3047 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { |
2264 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 3048 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && |
2265 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 3049 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
2266 | mp = (struct lpfc_dmabuf *) (mb->context1); | 3050 | mp = (struct lpfc_dmabuf *) (mb->context1); |
2267 | if (mp) { | 3051 | if (mp) { |
@@ -2309,13 +3093,14 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2309 | int rc; | 3093 | int rc; |
2310 | 3094 | ||
2311 | lpfc_cancel_retry_delay_tmo(vport, ndlp); | 3095 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
2312 | if (ndlp->nlp_flag & NLP_DEFER_RM && !ndlp->nlp_rpi) { | 3096 | if ((ndlp->nlp_flag & NLP_DEFER_RM) && |
3097 | !(ndlp->nlp_flag & NLP_RPI_VALID)) { | ||
2313 | /* For this case we need to cleanup the default rpi | 3098 | /* For this case we need to cleanup the default rpi |
2314 | * allocated by the firmware. | 3099 | * allocated by the firmware. |
2315 | */ | 3100 | */ |
2316 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) | 3101 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) |
2317 | != NULL) { | 3102 | != NULL) { |
2318 | rc = lpfc_reg_login(phba, vport->vpi, ndlp->nlp_DID, | 3103 | rc = lpfc_reg_rpi(phba, vport->vpi, ndlp->nlp_DID, |
2319 | (uint8_t *) &vport->fc_sparam, mbox, 0); | 3104 | (uint8_t *) &vport->fc_sparam, mbox, 0); |
2320 | if (rc) { | 3105 | if (rc) { |
2321 | mempool_free(mbox, phba->mbox_mem_pool); | 3106 | mempool_free(mbox, phba->mbox_mem_pool); |
@@ -2553,7 +3338,8 @@ lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
2553 | * clear_la then don't send it. | 3338 | * clear_la then don't send it. |
2554 | */ | 3339 | */ |
2555 | if ((phba->link_state >= LPFC_CLEAR_LA) || | 3340 | if ((phba->link_state >= LPFC_CLEAR_LA) || |
2556 | (vport->port_type != LPFC_PHYSICAL_PORT)) | 3341 | (vport->port_type != LPFC_PHYSICAL_PORT) || |
3342 | (phba->sli_rev == LPFC_SLI_REV4)) | ||
2557 | return; | 3343 | return; |
2558 | 3344 | ||
2559 | /* Link up discovery */ | 3345 | /* Link up discovery */ |
@@ -2582,7 +3368,7 @@ lpfc_issue_reg_vpi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
2582 | 3368 | ||
2583 | regvpimbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 3369 | regvpimbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
2584 | if (regvpimbox) { | 3370 | if (regvpimbox) { |
2585 | lpfc_reg_vpi(phba, vport->vpi, vport->fc_myDID, regvpimbox); | 3371 | lpfc_reg_vpi(vport, regvpimbox); |
2586 | regvpimbox->mbox_cmpl = lpfc_mbx_cmpl_reg_vpi; | 3372 | regvpimbox->mbox_cmpl = lpfc_mbx_cmpl_reg_vpi; |
2587 | regvpimbox->vport = vport; | 3373 | regvpimbox->vport = vport; |
2588 | if (lpfc_sli_issue_mbox(phba, regvpimbox, MBX_NOWAIT) | 3374 | if (lpfc_sli_issue_mbox(phba, regvpimbox, MBX_NOWAIT) |
@@ -2642,7 +3428,8 @@ lpfc_disc_start(struct lpfc_vport *vport) | |||
2642 | */ | 3428 | */ |
2643 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && | 3429 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && |
2644 | !(vport->fc_flag & FC_PT2PT) && | 3430 | !(vport->fc_flag & FC_PT2PT) && |
2645 | !(vport->fc_flag & FC_RSCN_MODE)) { | 3431 | !(vport->fc_flag & FC_RSCN_MODE) && |
3432 | (phba->sli_rev < LPFC_SLI_REV4)) { | ||
2646 | lpfc_issue_reg_vpi(phba, vport); | 3433 | lpfc_issue_reg_vpi(phba, vport); |
2647 | return; | 3434 | return; |
2648 | } | 3435 | } |
@@ -2919,11 +3706,13 @@ restart_disc: | |||
2919 | * set port_state to PORT_READY if SLI2. | 3706 | * set port_state to PORT_READY if SLI2. |
2920 | * cmpl_reg_vpi will set port_state to READY for SLI3. | 3707 | * cmpl_reg_vpi will set port_state to READY for SLI3. |
2921 | */ | 3708 | */ |
2922 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) | 3709 | if (phba->sli_rev < LPFC_SLI_REV4) { |
2923 | lpfc_issue_reg_vpi(phba, vport); | 3710 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) |
2924 | else { /* NPIV Not enabled */ | 3711 | lpfc_issue_reg_vpi(phba, vport); |
2925 | lpfc_issue_clear_la(phba, vport); | 3712 | else { /* NPIV Not enabled */ |
2926 | vport->port_state = LPFC_VPORT_READY; | 3713 | lpfc_issue_clear_la(phba, vport); |
3714 | vport->port_state = LPFC_VPORT_READY; | ||
3715 | } | ||
2927 | } | 3716 | } |
2928 | 3717 | ||
2929 | /* Setup and issue mailbox INITIALIZE LINK command */ | 3718 | /* Setup and issue mailbox INITIALIZE LINK command */ |
@@ -2939,7 +3728,7 @@ restart_disc: | |||
2939 | lpfc_linkdown(phba); | 3728 | lpfc_linkdown(phba); |
2940 | lpfc_init_link(phba, initlinkmbox, phba->cfg_topology, | 3729 | lpfc_init_link(phba, initlinkmbox, phba->cfg_topology, |
2941 | phba->cfg_link_speed); | 3730 | phba->cfg_link_speed); |
2942 | initlinkmbox->mb.un.varInitLnk.lipsr_AL_PA = 0; | 3731 | initlinkmbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0; |
2943 | initlinkmbox->vport = vport; | 3732 | initlinkmbox->vport = vport; |
2944 | initlinkmbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 3733 | initlinkmbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
2945 | rc = lpfc_sli_issue_mbox(phba, initlinkmbox, MBX_NOWAIT); | 3734 | rc = lpfc_sli_issue_mbox(phba, initlinkmbox, MBX_NOWAIT); |
@@ -2959,11 +3748,13 @@ restart_disc: | |||
2959 | * set port_state to PORT_READY if SLI2. | 3748 | * set port_state to PORT_READY if SLI2. |
2960 | * cmpl_reg_vpi will set port_state to READY for SLI3. | 3749 | * cmpl_reg_vpi will set port_state to READY for SLI3. |
2961 | */ | 3750 | */ |
2962 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) | 3751 | if (phba->sli_rev < LPFC_SLI_REV4) { |
2963 | lpfc_issue_reg_vpi(phba, vport); | 3752 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) |
2964 | else { /* NPIV Not enabled */ | 3753 | lpfc_issue_reg_vpi(phba, vport); |
2965 | lpfc_issue_clear_la(phba, vport); | 3754 | else { /* NPIV Not enabled */ |
2966 | vport->port_state = LPFC_VPORT_READY; | 3755 | lpfc_issue_clear_la(phba, vport); |
3756 | vport->port_state = LPFC_VPORT_READY; | ||
3757 | } | ||
2967 | } | 3758 | } |
2968 | break; | 3759 | break; |
2969 | 3760 | ||
@@ -3036,7 +3827,7 @@ restart_disc: | |||
3036 | void | 3827 | void |
3037 | lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 3828 | lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
3038 | { | 3829 | { |
3039 | MAILBOX_t *mb = &pmb->mb; | 3830 | MAILBOX_t *mb = &pmb->u.mb; |
3040 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | 3831 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
3041 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; | 3832 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
3042 | struct lpfc_vport *vport = pmb->vport; | 3833 | struct lpfc_vport *vport = pmb->vport; |
@@ -3044,6 +3835,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3044 | pmb->context1 = NULL; | 3835 | pmb->context1 = NULL; |
3045 | 3836 | ||
3046 | ndlp->nlp_rpi = mb->un.varWords[0]; | 3837 | ndlp->nlp_rpi = mb->un.varWords[0]; |
3838 | ndlp->nlp_flag |= NLP_RPI_VALID; | ||
3047 | ndlp->nlp_type |= NLP_FABRIC; | 3839 | ndlp->nlp_type |= NLP_FABRIC; |
3048 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | 3840 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
3049 | 3841 | ||
@@ -3297,3 +4089,395 @@ lpfc_nlp_not_used(struct lpfc_nodelist *ndlp) | |||
3297 | return 1; | 4089 | return 1; |
3298 | return 0; | 4090 | return 0; |
3299 | } | 4091 | } |
4092 | |||
4093 | /** | ||
4094 | * lpfc_fcf_inuse - Check if FCF can be unregistered. | ||
4095 | * @phba: Pointer to hba context object. | ||
4096 | * | ||
4097 | * This function iterate through all FC nodes associated | ||
4098 | * will all vports to check if there is any node with | ||
4099 | * fc_rports associated with it. If there is an fc_rport | ||
4100 | * associated with the node, then the node is either in | ||
4101 | * discovered state or its devloss_timer is pending. | ||
4102 | */ | ||
4103 | static int | ||
4104 | lpfc_fcf_inuse(struct lpfc_hba *phba) | ||
4105 | { | ||
4106 | struct lpfc_vport **vports; | ||
4107 | int i, ret = 0; | ||
4108 | struct lpfc_nodelist *ndlp; | ||
4109 | struct Scsi_Host *shost; | ||
4110 | |||
4111 | vports = lpfc_create_vport_work_array(phba); | ||
4112 | |||
4113 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
4114 | shost = lpfc_shost_from_vport(vports[i]); | ||
4115 | spin_lock_irq(shost->host_lock); | ||
4116 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { | ||
4117 | if (NLP_CHK_NODE_ACT(ndlp) && ndlp->rport && | ||
4118 | (ndlp->rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { | ||
4119 | ret = 1; | ||
4120 | spin_unlock_irq(shost->host_lock); | ||
4121 | goto out; | ||
4122 | } | ||
4123 | } | ||
4124 | spin_unlock_irq(shost->host_lock); | ||
4125 | } | ||
4126 | out: | ||
4127 | lpfc_destroy_vport_work_array(phba, vports); | ||
4128 | return ret; | ||
4129 | } | ||
4130 | |||
4131 | /** | ||
4132 | * lpfc_unregister_vfi_cmpl - Completion handler for unreg vfi. | ||
4133 | * @phba: Pointer to hba context object. | ||
4134 | * @mboxq: Pointer to mailbox object. | ||
4135 | * | ||
4136 | * This function frees memory associated with the mailbox command. | ||
4137 | */ | ||
4138 | static void | ||
4139 | lpfc_unregister_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
4140 | { | ||
4141 | struct lpfc_vport *vport = mboxq->vport; | ||
4142 | |||
4143 | if (mboxq->u.mb.mbxStatus) { | ||
4144 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4145 | "2555 UNREG_VFI mbxStatus error x%x " | ||
4146 | "HBA state x%x\n", | ||
4147 | mboxq->u.mb.mbxStatus, vport->port_state); | ||
4148 | } | ||
4149 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
4150 | return; | ||
4151 | } | ||
4152 | |||
4153 | /** | ||
4154 | * lpfc_unregister_fcfi_cmpl - Completion handler for unreg fcfi. | ||
4155 | * @phba: Pointer to hba context object. | ||
4156 | * @mboxq: Pointer to mailbox object. | ||
4157 | * | ||
4158 | * This function frees memory associated with the mailbox command. | ||
4159 | */ | ||
4160 | static void | ||
4161 | lpfc_unregister_fcfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
4162 | { | ||
4163 | struct lpfc_vport *vport = mboxq->vport; | ||
4164 | |||
4165 | if (mboxq->u.mb.mbxStatus) { | ||
4166 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4167 | "2550 UNREG_FCFI mbxStatus error x%x " | ||
4168 | "HBA state x%x\n", | ||
4169 | mboxq->u.mb.mbxStatus, vport->port_state); | ||
4170 | } | ||
4171 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
4172 | return; | ||
4173 | } | ||
4174 | |||
4175 | /** | ||
4176 | * lpfc_unregister_unused_fcf - Unregister FCF if all devices are disconnected. | ||
4177 | * @phba: Pointer to hba context object. | ||
4178 | * | ||
4179 | * This function check if there are any connected remote port for the FCF and | ||
4180 | * if all the devices are disconnected, this function unregister FCFI. | ||
4181 | * This function also tries to use another FCF for discovery. | ||
4182 | */ | ||
4183 | void | ||
4184 | lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | ||
4185 | { | ||
4186 | LPFC_MBOXQ_t *mbox; | ||
4187 | int rc; | ||
4188 | struct lpfc_vport **vports; | ||
4189 | int i; | ||
4190 | |||
4191 | spin_lock_irq(&phba->hbalock); | ||
4192 | /* | ||
4193 | * If HBA is not running in FIP mode or | ||
4194 | * If HBA does not support FCoE or | ||
4195 | * If FCF is not registered. | ||
4196 | * do nothing. | ||
4197 | */ | ||
4198 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT) || | ||
4199 | !(phba->fcf.fcf_flag & FCF_REGISTERED) || | ||
4200 | (phba->cfg_enable_fip == 0)) { | ||
4201 | spin_unlock_irq(&phba->hbalock); | ||
4202 | return; | ||
4203 | } | ||
4204 | spin_unlock_irq(&phba->hbalock); | ||
4205 | |||
4206 | if (lpfc_fcf_inuse(phba)) | ||
4207 | return; | ||
4208 | |||
4209 | |||
4210 | /* Unregister VPIs */ | ||
4211 | vports = lpfc_create_vport_work_array(phba); | ||
4212 | if (vports && | ||
4213 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) | ||
4214 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
4215 | lpfc_mbx_unreg_vpi(vports[i]); | ||
4216 | vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | ||
4217 | vports[i]->vfi_state &= ~LPFC_VFI_REGISTERED; | ||
4218 | } | ||
4219 | lpfc_destroy_vport_work_array(phba, vports); | ||
4220 | |||
4221 | /* Unregister VFI */ | ||
4222 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
4223 | if (!mbox) { | ||
4224 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4225 | "2556 UNREG_VFI mbox allocation failed" | ||
4226 | "HBA state x%x\n", | ||
4227 | phba->pport->port_state); | ||
4228 | return; | ||
4229 | } | ||
4230 | |||
4231 | lpfc_unreg_vfi(mbox, phba->pport->vfi); | ||
4232 | mbox->vport = phba->pport; | ||
4233 | mbox->mbox_cmpl = lpfc_unregister_vfi_cmpl; | ||
4234 | |||
4235 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
4236 | if (rc == MBX_NOT_FINISHED) { | ||
4237 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4238 | "2557 UNREG_VFI issue mbox failed rc x%x " | ||
4239 | "HBA state x%x\n", | ||
4240 | rc, phba->pport->port_state); | ||
4241 | mempool_free(mbox, phba->mbox_mem_pool); | ||
4242 | return; | ||
4243 | } | ||
4244 | |||
4245 | /* Unregister FCF */ | ||
4246 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
4247 | if (!mbox) { | ||
4248 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4249 | "2551 UNREG_FCFI mbox allocation failed" | ||
4250 | "HBA state x%x\n", | ||
4251 | phba->pport->port_state); | ||
4252 | return; | ||
4253 | } | ||
4254 | |||
4255 | lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); | ||
4256 | mbox->vport = phba->pport; | ||
4257 | mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; | ||
4258 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
4259 | |||
4260 | if (rc == MBX_NOT_FINISHED) { | ||
4261 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4262 | "2552 UNREG_FCFI issue mbox failed rc x%x " | ||
4263 | "HBA state x%x\n", | ||
4264 | rc, phba->pport->port_state); | ||
4265 | mempool_free(mbox, phba->mbox_mem_pool); | ||
4266 | return; | ||
4267 | } | ||
4268 | |||
4269 | spin_lock_irq(&phba->hbalock); | ||
4270 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_REGISTERED | | ||
4271 | FCF_DISCOVERED | FCF_BOOT_ENABLE | FCF_IN_USE | | ||
4272 | FCF_VALID_VLAN); | ||
4273 | spin_unlock_irq(&phba->hbalock); | ||
4274 | |||
4275 | /* | ||
4276 | * If driver is not unloading, check if there is any other | ||
4277 | * FCF record that can be used for discovery. | ||
4278 | */ | ||
4279 | if ((phba->pport->load_flag & FC_UNLOADING) || | ||
4280 | (phba->link_state < LPFC_LINK_UP)) | ||
4281 | return; | ||
4282 | |||
4283 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | ||
4284 | |||
4285 | if (rc) | ||
4286 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4287 | "2553 lpfc_unregister_unused_fcf failed to read FCF" | ||
4288 | " record HBA state x%x\n", | ||
4289 | phba->pport->port_state); | ||
4290 | } | ||
4291 | |||
4292 | /** | ||
4293 | * lpfc_read_fcf_conn_tbl - Create driver FCF connection table. | ||
4294 | * @phba: Pointer to hba context object. | ||
4295 | * @buff: Buffer containing the FCF connection table as in the config | ||
4296 | * region. | ||
4297 | * This function create driver data structure for the FCF connection | ||
4298 | * record table read from config region 23. | ||
4299 | */ | ||
4300 | static void | ||
4301 | lpfc_read_fcf_conn_tbl(struct lpfc_hba *phba, | ||
4302 | uint8_t *buff) | ||
4303 | { | ||
4304 | struct lpfc_fcf_conn_entry *conn_entry, *next_conn_entry; | ||
4305 | struct lpfc_fcf_conn_hdr *conn_hdr; | ||
4306 | struct lpfc_fcf_conn_rec *conn_rec; | ||
4307 | uint32_t record_count; | ||
4308 | int i; | ||
4309 | |||
4310 | /* Free the current connect table */ | ||
4311 | list_for_each_entry_safe(conn_entry, next_conn_entry, | ||
4312 | &phba->fcf_conn_rec_list, list) | ||
4313 | kfree(conn_entry); | ||
4314 | |||
4315 | conn_hdr = (struct lpfc_fcf_conn_hdr *) buff; | ||
4316 | record_count = conn_hdr->length * sizeof(uint32_t)/ | ||
4317 | sizeof(struct lpfc_fcf_conn_rec); | ||
4318 | |||
4319 | conn_rec = (struct lpfc_fcf_conn_rec *) | ||
4320 | (buff + sizeof(struct lpfc_fcf_conn_hdr)); | ||
4321 | |||
4322 | for (i = 0; i < record_count; i++) { | ||
4323 | if (!(conn_rec[i].flags & FCFCNCT_VALID)) | ||
4324 | continue; | ||
4325 | conn_entry = kzalloc(sizeof(struct lpfc_fcf_conn_entry), | ||
4326 | GFP_KERNEL); | ||
4327 | if (!conn_entry) { | ||
4328 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4329 | "2566 Failed to allocate connection" | ||
4330 | " table entry\n"); | ||
4331 | return; | ||
4332 | } | ||
4333 | |||
4334 | memcpy(&conn_entry->conn_rec, &conn_rec[i], | ||
4335 | sizeof(struct lpfc_fcf_conn_rec)); | ||
4336 | conn_entry->conn_rec.vlan_tag = | ||
4337 | le16_to_cpu(conn_entry->conn_rec.vlan_tag) & 0xFFF; | ||
4338 | conn_entry->conn_rec.flags = | ||
4339 | le16_to_cpu(conn_entry->conn_rec.flags); | ||
4340 | list_add_tail(&conn_entry->list, | ||
4341 | &phba->fcf_conn_rec_list); | ||
4342 | } | ||
4343 | } | ||
4344 | |||
4345 | /** | ||
4346 | * lpfc_read_fcoe_param - Read FCoe parameters from conf region.. | ||
4347 | * @phba: Pointer to hba context object. | ||
4348 | * @buff: Buffer containing the FCoE parameter data structure. | ||
4349 | * | ||
4350 | * This function update driver data structure with config | ||
4351 | * parameters read from config region 23. | ||
4352 | */ | ||
4353 | static void | ||
4354 | lpfc_read_fcoe_param(struct lpfc_hba *phba, | ||
4355 | uint8_t *buff) | ||
4356 | { | ||
4357 | struct lpfc_fip_param_hdr *fcoe_param_hdr; | ||
4358 | struct lpfc_fcoe_params *fcoe_param; | ||
4359 | |||
4360 | fcoe_param_hdr = (struct lpfc_fip_param_hdr *) | ||
4361 | buff; | ||
4362 | fcoe_param = (struct lpfc_fcoe_params *) | ||
4363 | buff + sizeof(struct lpfc_fip_param_hdr); | ||
4364 | |||
4365 | if ((fcoe_param_hdr->parm_version != FIPP_VERSION) || | ||
4366 | (fcoe_param_hdr->length != FCOE_PARAM_LENGTH)) | ||
4367 | return; | ||
4368 | |||
4369 | if (bf_get(lpfc_fip_param_hdr_fipp_mode, fcoe_param_hdr) == | ||
4370 | FIPP_MODE_ON) | ||
4371 | phba->cfg_enable_fip = 1; | ||
4372 | |||
4373 | if (bf_get(lpfc_fip_param_hdr_fipp_mode, fcoe_param_hdr) == | ||
4374 | FIPP_MODE_OFF) | ||
4375 | phba->cfg_enable_fip = 0; | ||
4376 | |||
4377 | if (fcoe_param_hdr->parm_flags & FIPP_VLAN_VALID) { | ||
4378 | phba->valid_vlan = 1; | ||
4379 | phba->vlan_id = le16_to_cpu(fcoe_param->vlan_tag) & | ||
4380 | 0xFFF; | ||
4381 | } | ||
4382 | |||
4383 | phba->fc_map[0] = fcoe_param->fc_map[0]; | ||
4384 | phba->fc_map[1] = fcoe_param->fc_map[1]; | ||
4385 | phba->fc_map[2] = fcoe_param->fc_map[2]; | ||
4386 | return; | ||
4387 | } | ||
4388 | |||
4389 | /** | ||
4390 | * lpfc_get_rec_conf23 - Get a record type in config region data. | ||
4391 | * @buff: Buffer containing config region 23 data. | ||
4392 | * @size: Size of the data buffer. | ||
4393 | * @rec_type: Record type to be searched. | ||
4394 | * | ||
4395 | * This function searches config region data to find the begining | ||
4396 | * of the record specified by record_type. If record found, this | ||
4397 | * function return pointer to the record else return NULL. | ||
4398 | */ | ||
4399 | static uint8_t * | ||
4400 | lpfc_get_rec_conf23(uint8_t *buff, uint32_t size, uint8_t rec_type) | ||
4401 | { | ||
4402 | uint32_t offset = 0, rec_length; | ||
4403 | |||
4404 | if ((buff[0] == LPFC_REGION23_LAST_REC) || | ||
4405 | (size < sizeof(uint32_t))) | ||
4406 | return NULL; | ||
4407 | |||
4408 | rec_length = buff[offset + 1]; | ||
4409 | |||
4410 | /* | ||
4411 | * One TLV record has one word header and number of data words | ||
4412 | * specified in the rec_length field of the record header. | ||
4413 | */ | ||
4414 | while ((offset + rec_length * sizeof(uint32_t) + sizeof(uint32_t)) | ||
4415 | <= size) { | ||
4416 | if (buff[offset] == rec_type) | ||
4417 | return &buff[offset]; | ||
4418 | |||
4419 | if (buff[offset] == LPFC_REGION23_LAST_REC) | ||
4420 | return NULL; | ||
4421 | |||
4422 | offset += rec_length * sizeof(uint32_t) + sizeof(uint32_t); | ||
4423 | rec_length = buff[offset + 1]; | ||
4424 | } | ||
4425 | return NULL; | ||
4426 | } | ||
4427 | |||
4428 | /** | ||
4429 | * lpfc_parse_fcoe_conf - Parse FCoE config data read from config region 23. | ||
4430 | * @phba: Pointer to lpfc_hba data structure. | ||
4431 | * @buff: Buffer containing config region 23 data. | ||
4432 | * @size: Size of the data buffer. | ||
4433 | * | ||
4434 | * This fuction parse the FCoE config parameters in config region 23 and | ||
4435 | * populate driver data structure with the parameters. | ||
4436 | */ | ||
4437 | void | ||
4438 | lpfc_parse_fcoe_conf(struct lpfc_hba *phba, | ||
4439 | uint8_t *buff, | ||
4440 | uint32_t size) | ||
4441 | { | ||
4442 | uint32_t offset = 0, rec_length; | ||
4443 | uint8_t *rec_ptr; | ||
4444 | |||
4445 | /* | ||
4446 | * If data size is less than 2 words signature and version cannot be | ||
4447 | * verified. | ||
4448 | */ | ||
4449 | if (size < 2*sizeof(uint32_t)) | ||
4450 | return; | ||
4451 | |||
4452 | /* Check the region signature first */ | ||
4453 | if (memcmp(buff, LPFC_REGION23_SIGNATURE, 4)) { | ||
4454 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4455 | "2567 Config region 23 has bad signature\n"); | ||
4456 | return; | ||
4457 | } | ||
4458 | |||
4459 | offset += 4; | ||
4460 | |||
4461 | /* Check the data structure version */ | ||
4462 | if (buff[offset] != LPFC_REGION23_VERSION) { | ||
4463 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4464 | "2568 Config region 23 has bad version\n"); | ||
4465 | return; | ||
4466 | } | ||
4467 | offset += 4; | ||
4468 | |||
4469 | rec_length = buff[offset + 1]; | ||
4470 | |||
4471 | /* Read FCoE param record */ | ||
4472 | rec_ptr = lpfc_get_rec_conf23(&buff[offset], | ||
4473 | size - offset, FCOE_PARAM_TYPE); | ||
4474 | if (rec_ptr) | ||
4475 | lpfc_read_fcoe_param(phba, rec_ptr); | ||
4476 | |||
4477 | /* Read FCF connection table */ | ||
4478 | rec_ptr = lpfc_get_rec_conf23(&buff[offset], | ||
4479 | size - offset, FCOE_CONN_TBL_TYPE); | ||
4480 | if (rec_ptr) | ||
4481 | lpfc_read_fcf_conn_tbl(phba, rec_ptr); | ||
4482 | |||
4483 | } | ||