diff options
author | James Smart <james.smart@emulex.com> | 2011-07-22 18:37:52 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-07-27 07:16:05 -0400 |
commit | 7d791df730844932feeac3bbf3ac08b510682174 (patch) | |
tree | 8a1dd1666dc7df7518368327b7eff45719adeae1 /drivers/scsi/lpfc | |
parent | b76f2dc91c0fff7a66616affdc039dc2e4b7ff98 (diff) |
[SCSI] lpfc 8.3.25: Add FCF priority failover functionality
This patch implements a new FCF failover policy for the lpfc driver. It
allows the driver to choose which FCF to failover to based on the FCF
priority. This patch also introduces a new sysfs parameter
(fcf_failover_policy) to allow the user to choose which FCF failover policy
to use.
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 3 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 220 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 7 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 131 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 27 |
8 files changed, 377 insertions, 20 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index b932067bf2d8..c088a36d1f33 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -680,6 +680,9 @@ struct lpfc_hba { | |||
680 | uint32_t cfg_enable_rrq; | 680 | uint32_t cfg_enable_rrq; |
681 | uint32_t cfg_topology; | 681 | uint32_t cfg_topology; |
682 | uint32_t cfg_link_speed; | 682 | uint32_t cfg_link_speed; |
683 | #define LPFC_FCF_FOV 1 /* Fast fcf failover */ | ||
684 | #define LPFC_FCF_PRIORITY 2 /* Priority fcf failover */ | ||
685 | uint32_t cfg_fcf_failover_policy; | ||
683 | uint32_t cfg_cr_delay; | 686 | uint32_t cfg_cr_delay; |
684 | uint32_t cfg_cr_count; | 687 | uint32_t cfg_cr_count; |
685 | uint32_t cfg_multi_ring_support; | 688 | uint32_t cfg_multi_ring_support; |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index fa5bc146d67b..2542f1f8bf86 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -2193,6 +2193,9 @@ lpfc_param_show(enable_npiv); | |||
2193 | lpfc_param_init(enable_npiv, 1, 0, 1); | 2193 | lpfc_param_init(enable_npiv, 1, 0, 1); |
2194 | static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, lpfc_enable_npiv_show, NULL); | 2194 | static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, lpfc_enable_npiv_show, NULL); |
2195 | 2195 | ||
2196 | LPFC_ATTR_R(fcf_failover_policy, 1, 1, 2, | ||
2197 | "FCF Fast failover=1 Priority failover=2"); | ||
2198 | |||
2196 | int lpfc_enable_rrq; | 2199 | int lpfc_enable_rrq; |
2197 | module_param(lpfc_enable_rrq, int, S_IRUGO); | 2200 | module_param(lpfc_enable_rrq, int, S_IRUGO); |
2198 | MODULE_PARM_DESC(lpfc_enable_rrq, "Enable RRQ functionality"); | 2201 | MODULE_PARM_DESC(lpfc_enable_rrq, "Enable RRQ functionality"); |
@@ -3775,6 +3778,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |||
3775 | &dev_attr_lpfc_fdmi_on, | 3778 | &dev_attr_lpfc_fdmi_on, |
3776 | &dev_attr_lpfc_max_luns, | 3779 | &dev_attr_lpfc_max_luns, |
3777 | &dev_attr_lpfc_enable_npiv, | 3780 | &dev_attr_lpfc_enable_npiv, |
3781 | &dev_attr_lpfc_fcf_failover_policy, | ||
3778 | &dev_attr_lpfc_enable_rrq, | 3782 | &dev_attr_lpfc_enable_rrq, |
3779 | &dev_attr_nport_evt_cnt, | 3783 | &dev_attr_nport_evt_cnt, |
3780 | &dev_attr_board_mode, | 3784 | &dev_attr_board_mode, |
@@ -4995,6 +4999,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
4995 | lpfc_link_speed_init(phba, lpfc_link_speed); | 4999 | lpfc_link_speed_init(phba, lpfc_link_speed); |
4996 | lpfc_poll_tmo_init(phba, lpfc_poll_tmo); | 5000 | lpfc_poll_tmo_init(phba, lpfc_poll_tmo); |
4997 | lpfc_enable_npiv_init(phba, lpfc_enable_npiv); | 5001 | lpfc_enable_npiv_init(phba, lpfc_enable_npiv); |
5002 | lpfc_fcf_failover_policy_init(phba, lpfc_fcf_failover_policy); | ||
4998 | lpfc_enable_rrq_init(phba, lpfc_enable_rrq); | 5003 | lpfc_enable_rrq_init(phba, lpfc_enable_rrq); |
4999 | lpfc_use_msi_init(phba, lpfc_use_msi); | 5004 | lpfc_use_msi_init(phba, lpfc_use_msi); |
5000 | lpfc_fcp_imax_init(phba, lpfc_fcp_imax); | 5005 | lpfc_fcp_imax_init(phba, lpfc_fcp_imax); |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 1f3cad0b1ce8..a6db6aef1331 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -235,9 +235,11 @@ int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *); | |||
235 | void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *); | 235 | void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *); |
236 | void lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *); | 236 | void lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *); |
237 | uint16_t lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *); | 237 | uint16_t lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *); |
238 | void lpfc_sli4_set_fcf_flogi_fail(struct lpfc_hba *, uint16_t); | ||
238 | int lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *, uint16_t); | 239 | int lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *, uint16_t); |
239 | void lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *, uint16_t); | 240 | void lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *, uint16_t); |
240 | int lpfc_sli4_fcf_rr_next_proc(struct lpfc_vport *, uint16_t); | 241 | int lpfc_sli4_fcf_rr_next_proc(struct lpfc_vport *, uint16_t); |
242 | void lpfc_sli4_clear_fcf_rr_bmask(struct lpfc_hba *); | ||
241 | 243 | ||
242 | int lpfc_mem_alloc(struct lpfc_hba *, int align); | 244 | int lpfc_mem_alloc(struct lpfc_hba *, int align); |
243 | void lpfc_mem_free(struct lpfc_hba *); | 245 | void lpfc_mem_free(struct lpfc_hba *); |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 1725b81770e9..023da0e00d38 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -874,6 +874,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
874 | phba->fcf.current_rec.fcf_indx, | 874 | phba->fcf.current_rec.fcf_indx, |
875 | irsp->ulpStatus, irsp->un.ulpWord[4], | 875 | irsp->ulpStatus, irsp->un.ulpWord[4], |
876 | irsp->ulpTimeout); | 876 | irsp->ulpTimeout); |
877 | lpfc_sli4_set_fcf_flogi_fail(phba, | ||
878 | phba->fcf.current_rec.fcf_indx); | ||
877 | fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba); | 879 | fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba); |
878 | rc = lpfc_sli4_fcf_rr_next_proc(vport, fcf_index); | 880 | rc = lpfc_sli4_fcf_rr_next_proc(vport, fcf_index); |
879 | if (rc) | 881 | if (rc) |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index bef17e3e419a..0b47adf9fee8 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1109,6 +1109,28 @@ out: | |||
1109 | return; | 1109 | return; |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | /** | ||
1113 | * lpfc_sli4_clear_fcf_rr_bmask | ||
1114 | * @phba pointer to the struct lpfc_hba for this port. | ||
1115 | * This fucnction resets the round robin bit mask and clears the | ||
1116 | * fcf priority list. The list deletions are done while holding the | ||
1117 | * hbalock. The ON_LIST flag and the FLOGI_FAILED flags are cleared | ||
1118 | * from the lpfc_fcf_pri record. | ||
1119 | **/ | ||
1120 | void | ||
1121 | lpfc_sli4_clear_fcf_rr_bmask(struct lpfc_hba *phba) | ||
1122 | { | ||
1123 | struct lpfc_fcf_pri *fcf_pri; | ||
1124 | struct lpfc_fcf_pri *next_fcf_pri; | ||
1125 | memset(phba->fcf.fcf_rr_bmask, 0, sizeof(*phba->fcf.fcf_rr_bmask)); | ||
1126 | spin_lock_irq(&phba->hbalock); | ||
1127 | list_for_each_entry_safe(fcf_pri, next_fcf_pri, | ||
1128 | &phba->fcf.fcf_pri_list, list) { | ||
1129 | list_del_init(&fcf_pri->list); | ||
1130 | fcf_pri->fcf_rec.flag = 0; | ||
1131 | } | ||
1132 | spin_unlock_irq(&phba->hbalock); | ||
1133 | } | ||
1112 | static void | 1134 | static void |
1113 | lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | 1135 | lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) |
1114 | { | 1136 | { |
@@ -1130,7 +1152,8 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1130 | spin_unlock_irq(&phba->hbalock); | 1152 | spin_unlock_irq(&phba->hbalock); |
1131 | 1153 | ||
1132 | /* If there is a pending FCoE event, restart FCF table scan. */ | 1154 | /* If there is a pending FCoE event, restart FCF table scan. */ |
1133 | if (lpfc_check_pending_fcoe_event(phba, LPFC_UNREG_FCF)) | 1155 | if ((!(phba->hba_flag & FCF_RR_INPROG)) && |
1156 | lpfc_check_pending_fcoe_event(phba, LPFC_UNREG_FCF)) | ||
1134 | goto fail_out; | 1157 | goto fail_out; |
1135 | 1158 | ||
1136 | /* Mark successful completion of FCF table scan */ | 1159 | /* Mark successful completion of FCF table scan */ |
@@ -1250,6 +1273,30 @@ lpfc_vlan_id_match(uint16_t curr_vlan_id, uint16_t new_vlan_id) | |||
1250 | } | 1273 | } |
1251 | 1274 | ||
1252 | /** | 1275 | /** |
1276 | * lpfc_update_fcf_record - Update driver fcf record | ||
1277 | * __lpfc_update_fcf_record_pri - update the lpfc_fcf_pri record. | ||
1278 | * @phba: pointer to lpfc hba data structure. | ||
1279 | * @fcf_index: Index for the lpfc_fcf_record. | ||
1280 | * @new_fcf_record: pointer to hba fcf record. | ||
1281 | * | ||
1282 | * This routine updates the driver FCF priority record from the new HBA FCF | ||
1283 | * record. This routine is called with the host lock held. | ||
1284 | **/ | ||
1285 | static void | ||
1286 | __lpfc_update_fcf_record_pri(struct lpfc_hba *phba, uint16_t fcf_index, | ||
1287 | struct fcf_record *new_fcf_record | ||
1288 | ) | ||
1289 | { | ||
1290 | struct lpfc_fcf_pri *fcf_pri; | ||
1291 | |||
1292 | fcf_pri = &phba->fcf.fcf_pri[fcf_index]; | ||
1293 | fcf_pri->fcf_rec.fcf_index = fcf_index; | ||
1294 | /* FCF record priority */ | ||
1295 | fcf_pri->fcf_rec.priority = new_fcf_record->fip_priority; | ||
1296 | |||
1297 | } | ||
1298 | |||
1299 | /** | ||
1253 | * lpfc_copy_fcf_record - Copy fcf information to lpfc_hba. | 1300 | * lpfc_copy_fcf_record - Copy fcf information to lpfc_hba. |
1254 | * @fcf: pointer to driver fcf record. | 1301 | * @fcf: pointer to driver fcf record. |
1255 | * @new_fcf_record: pointer to fcf record. | 1302 | * @new_fcf_record: pointer to fcf record. |
@@ -1332,6 +1379,9 @@ __lpfc_update_fcf_record(struct lpfc_hba *phba, struct lpfc_fcf_rec *fcf_rec, | |||
1332 | fcf_rec->addr_mode = addr_mode; | 1379 | fcf_rec->addr_mode = addr_mode; |
1333 | fcf_rec->vlan_id = vlan_id; | 1380 | fcf_rec->vlan_id = vlan_id; |
1334 | fcf_rec->flag |= (flag | RECORD_VALID); | 1381 | fcf_rec->flag |= (flag | RECORD_VALID); |
1382 | __lpfc_update_fcf_record_pri(phba, | ||
1383 | bf_get(lpfc_fcf_record_fcf_index, new_fcf_record), | ||
1384 | new_fcf_record); | ||
1335 | } | 1385 | } |
1336 | 1386 | ||
1337 | /** | 1387 | /** |
@@ -1834,6 +1884,8 @@ lpfc_sli4_fcf_record_match(struct lpfc_hba *phba, | |||
1834 | return false; | 1884 | return false; |
1835 | if (!lpfc_fab_name_match(fcf_rec->fabric_name, new_fcf_record)) | 1885 | if (!lpfc_fab_name_match(fcf_rec->fabric_name, new_fcf_record)) |
1836 | return false; | 1886 | return false; |
1887 | if (fcf_rec->priority != new_fcf_record->fip_priority) | ||
1888 | return false; | ||
1837 | return true; | 1889 | return true; |
1838 | } | 1890 | } |
1839 | 1891 | ||
@@ -1897,6 +1949,152 @@ stop_flogi_current_fcf: | |||
1897 | } | 1949 | } |
1898 | 1950 | ||
1899 | /** | 1951 | /** |
1952 | * lpfc_sli4_fcf_pri_list_del | ||
1953 | * @phba: pointer to lpfc hba data structure. | ||
1954 | * @fcf_index the index of the fcf record to delete | ||
1955 | * This routine checks the on list flag of the fcf_index to be deleted. | ||
1956 | * If it is one the list then it is removed from the list, and the flag | ||
1957 | * is cleared. This routine grab the hbalock before removing the fcf | ||
1958 | * record from the list. | ||
1959 | **/ | ||
1960 | static void lpfc_sli4_fcf_pri_list_del(struct lpfc_hba *phba, | ||
1961 | uint16_t fcf_index) | ||
1962 | { | ||
1963 | struct lpfc_fcf_pri *new_fcf_pri; | ||
1964 | |||
1965 | new_fcf_pri = &phba->fcf.fcf_pri[fcf_index]; | ||
1966 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
1967 | "3058 deleting idx x%x pri x%x flg x%x\n", | ||
1968 | fcf_index, new_fcf_pri->fcf_rec.priority, | ||
1969 | new_fcf_pri->fcf_rec.flag); | ||
1970 | spin_lock_irq(&phba->hbalock); | ||
1971 | if (new_fcf_pri->fcf_rec.flag & LPFC_FCF_ON_PRI_LIST) { | ||
1972 | if (phba->fcf.current_rec.priority == | ||
1973 | new_fcf_pri->fcf_rec.priority) | ||
1974 | phba->fcf.eligible_fcf_cnt--; | ||
1975 | list_del_init(&new_fcf_pri->list); | ||
1976 | new_fcf_pri->fcf_rec.flag &= ~LPFC_FCF_ON_PRI_LIST; | ||
1977 | } | ||
1978 | spin_unlock_irq(&phba->hbalock); | ||
1979 | } | ||
1980 | |||
1981 | /** | ||
1982 | * lpfc_sli4_set_fcf_flogi_fail | ||
1983 | * @phba: pointer to lpfc hba data structure. | ||
1984 | * @fcf_index the index of the fcf record to update | ||
1985 | * This routine acquires the hbalock and then set the LPFC_FCF_FLOGI_FAILED | ||
1986 | * flag so the the round robin slection for the particular priority level | ||
1987 | * will try a different fcf record that does not have this bit set. | ||
1988 | * If the fcf record is re-read for any reason this flag is cleared brfore | ||
1989 | * adding it to the priority list. | ||
1990 | **/ | ||
1991 | void | ||
1992 | lpfc_sli4_set_fcf_flogi_fail(struct lpfc_hba *phba, uint16_t fcf_index) | ||
1993 | { | ||
1994 | struct lpfc_fcf_pri *new_fcf_pri; | ||
1995 | new_fcf_pri = &phba->fcf.fcf_pri[fcf_index]; | ||
1996 | spin_lock_irq(&phba->hbalock); | ||
1997 | new_fcf_pri->fcf_rec.flag |= LPFC_FCF_FLOGI_FAILED; | ||
1998 | spin_unlock_irq(&phba->hbalock); | ||
1999 | } | ||
2000 | |||
2001 | /** | ||
2002 | * lpfc_sli4_fcf_pri_list_add | ||
2003 | * @phba: pointer to lpfc hba data structure. | ||
2004 | * @fcf_index the index of the fcf record to add | ||
2005 | * This routine checks the priority of the fcf_index to be added. | ||
2006 | * If it is a lower priority than the current head of the fcf_pri list | ||
2007 | * then it is added to the list in the right order. | ||
2008 | * If it is the same priority as the current head of the list then it | ||
2009 | * is added to the head of the list and its bit in the rr_bmask is set. | ||
2010 | * If the fcf_index to be added is of a higher priority than the current | ||
2011 | * head of the list then the rr_bmask is cleared, its bit is set in the | ||
2012 | * rr_bmask and it is added to the head of the list. | ||
2013 | * returns: | ||
2014 | * 0=success 1=failure | ||
2015 | **/ | ||
2016 | int lpfc_sli4_fcf_pri_list_add(struct lpfc_hba *phba, uint16_t fcf_index, | ||
2017 | struct fcf_record *new_fcf_record) | ||
2018 | { | ||
2019 | uint16_t current_fcf_pri; | ||
2020 | uint16_t last_index; | ||
2021 | struct lpfc_fcf_pri *fcf_pri; | ||
2022 | struct lpfc_fcf_pri *next_fcf_pri; | ||
2023 | struct lpfc_fcf_pri *new_fcf_pri; | ||
2024 | int ret; | ||
2025 | |||
2026 | new_fcf_pri = &phba->fcf.fcf_pri[fcf_index]; | ||
2027 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
2028 | "3059 adding idx x%x pri x%x flg x%x\n", | ||
2029 | fcf_index, new_fcf_record->fip_priority, | ||
2030 | new_fcf_pri->fcf_rec.flag); | ||
2031 | spin_lock_irq(&phba->hbalock); | ||
2032 | if (new_fcf_pri->fcf_rec.flag & LPFC_FCF_ON_PRI_LIST) | ||
2033 | list_del_init(&new_fcf_pri->list); | ||
2034 | new_fcf_pri->fcf_rec.fcf_index = fcf_index; | ||
2035 | new_fcf_pri->fcf_rec.priority = new_fcf_record->fip_priority; | ||
2036 | if (list_empty(&phba->fcf.fcf_pri_list)) { | ||
2037 | list_add(&new_fcf_pri->list, &phba->fcf.fcf_pri_list); | ||
2038 | ret = lpfc_sli4_fcf_rr_index_set(phba, | ||
2039 | new_fcf_pri->fcf_rec.fcf_index); | ||
2040 | goto out; | ||
2041 | } | ||
2042 | |||
2043 | last_index = find_first_bit(phba->fcf.fcf_rr_bmask, | ||
2044 | LPFC_SLI4_FCF_TBL_INDX_MAX); | ||
2045 | if (last_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) { | ||
2046 | ret = 0; /* Empty rr list */ | ||
2047 | goto out; | ||
2048 | } | ||
2049 | current_fcf_pri = phba->fcf.fcf_pri[last_index].fcf_rec.priority; | ||
2050 | if (new_fcf_pri->fcf_rec.priority <= current_fcf_pri) { | ||
2051 | list_add(&new_fcf_pri->list, &phba->fcf.fcf_pri_list); | ||
2052 | if (new_fcf_pri->fcf_rec.priority < current_fcf_pri) { | ||
2053 | memset(phba->fcf.fcf_rr_bmask, 0, | ||
2054 | sizeof(*phba->fcf.fcf_rr_bmask)); | ||
2055 | /* fcfs_at_this_priority_level = 1; */ | ||
2056 | phba->fcf.eligible_fcf_cnt = 1; | ||
2057 | } else | ||
2058 | /* fcfs_at_this_priority_level++; */ | ||
2059 | phba->fcf.eligible_fcf_cnt++; | ||
2060 | ret = lpfc_sli4_fcf_rr_index_set(phba, | ||
2061 | new_fcf_pri->fcf_rec.fcf_index); | ||
2062 | goto out; | ||
2063 | } | ||
2064 | |||
2065 | list_for_each_entry_safe(fcf_pri, next_fcf_pri, | ||
2066 | &phba->fcf.fcf_pri_list, list) { | ||
2067 | if (new_fcf_pri->fcf_rec.priority <= | ||
2068 | fcf_pri->fcf_rec.priority) { | ||
2069 | if (fcf_pri->list.prev == &phba->fcf.fcf_pri_list) | ||
2070 | list_add(&new_fcf_pri->list, | ||
2071 | &phba->fcf.fcf_pri_list); | ||
2072 | else | ||
2073 | list_add(&new_fcf_pri->list, | ||
2074 | &((struct lpfc_fcf_pri *) | ||
2075 | fcf_pri->list.prev)->list); | ||
2076 | ret = 0; | ||
2077 | goto out; | ||
2078 | } else if (fcf_pri->list.next == &phba->fcf.fcf_pri_list | ||
2079 | || new_fcf_pri->fcf_rec.priority < | ||
2080 | next_fcf_pri->fcf_rec.priority) { | ||
2081 | list_add(&new_fcf_pri->list, &fcf_pri->list); | ||
2082 | ret = 0; | ||
2083 | goto out; | ||
2084 | } | ||
2085 | if (new_fcf_pri->fcf_rec.priority > fcf_pri->fcf_rec.priority) | ||
2086 | continue; | ||
2087 | |||
2088 | } | ||
2089 | ret = 1; | ||
2090 | out: | ||
2091 | /* we use = instead of |= to clear the FLOGI_FAILED flag. */ | ||
2092 | new_fcf_pri->fcf_rec.flag = LPFC_FCF_ON_PRI_LIST; | ||
2093 | spin_unlock_irq(&phba->hbalock); | ||
2094 | return ret; | ||
2095 | } | ||
2096 | |||
2097 | /** | ||
1900 | * lpfc_mbx_cmpl_fcf_scan_read_fcf_rec - fcf scan read_fcf mbox cmpl handler. | 2098 | * lpfc_mbx_cmpl_fcf_scan_read_fcf_rec - fcf scan read_fcf mbox cmpl handler. |
1901 | * @phba: pointer to lpfc hba data structure. | 2099 | * @phba: pointer to lpfc hba data structure. |
1902 | * @mboxq: pointer to mailbox object. | 2100 | * @mboxq: pointer to mailbox object. |
@@ -1958,6 +2156,9 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1958 | * record for roundrobin FCF failover. | 2156 | * record for roundrobin FCF failover. |
1959 | */ | 2157 | */ |
1960 | if (!rc) { | 2158 | if (!rc) { |
2159 | lpfc_sli4_fcf_pri_list_del(phba, | ||
2160 | bf_get(lpfc_fcf_record_fcf_index, | ||
2161 | new_fcf_record)); | ||
1961 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, | 2162 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, |
1962 | "2781 FCF (x%x) failed connection " | 2163 | "2781 FCF (x%x) failed connection " |
1963 | "list check: (x%x/x%x)\n", | 2164 | "list check: (x%x/x%x)\n", |
@@ -2005,7 +2206,8 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
2005 | goto read_next_fcf; | 2206 | goto read_next_fcf; |
2006 | } else { | 2207 | } else { |
2007 | fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); | 2208 | fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); |
2008 | rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index); | 2209 | rc = lpfc_sli4_fcf_pri_list_add(phba, fcf_index, |
2210 | new_fcf_record); | ||
2009 | if (rc) | 2211 | if (rc) |
2010 | goto read_next_fcf; | 2212 | goto read_next_fcf; |
2011 | } | 2213 | } |
@@ -2018,7 +2220,8 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
2018 | */ | 2220 | */ |
2019 | spin_lock_irq(&phba->hbalock); | 2221 | spin_lock_irq(&phba->hbalock); |
2020 | if (phba->fcf.fcf_flag & FCF_IN_USE) { | 2222 | if (phba->fcf.fcf_flag & FCF_IN_USE) { |
2021 | if (lpfc_sli4_fcf_record_match(phba, &phba->fcf.current_rec, | 2223 | if (phba->cfg_fcf_failover_policy == LPFC_FCF_FOV && |
2224 | lpfc_sli4_fcf_record_match(phba, &phba->fcf.current_rec, | ||
2022 | new_fcf_record, vlan_id)) { | 2225 | new_fcf_record, vlan_id)) { |
2023 | if (bf_get(lpfc_fcf_record_fcf_index, new_fcf_record) == | 2226 | if (bf_get(lpfc_fcf_record_fcf_index, new_fcf_record) == |
2024 | phba->fcf.current_rec.fcf_indx) { | 2227 | phba->fcf.current_rec.fcf_indx) { |
@@ -2232,7 +2435,8 @@ read_next_fcf: | |||
2232 | (phba->fcf.fcf_flag & FCF_REDISC_PEND)) | 2435 | (phba->fcf.fcf_flag & FCF_REDISC_PEND)) |
2233 | return; | 2436 | return; |
2234 | 2437 | ||
2235 | if (phba->fcf.fcf_flag & FCF_IN_USE) { | 2438 | if (phba->cfg_fcf_failover_policy == LPFC_FCF_FOV && |
2439 | phba->fcf.fcf_flag & FCF_IN_USE) { | ||
2236 | /* | 2440 | /* |
2237 | * In case the current in-use FCF record no | 2441 | * In case the current in-use FCF record no |
2238 | * longer existed during FCF discovery that | 2442 | * longer existed during FCF discovery that |
@@ -2423,7 +2627,8 @@ lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
2423 | 2627 | ||
2424 | /* Update the eligible FCF record index bmask */ | 2628 | /* Update the eligible FCF record index bmask */ |
2425 | fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); | 2629 | fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); |
2426 | rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index); | 2630 | |
2631 | rc = lpfc_sli4_fcf_pri_list_add(phba, fcf_index, new_fcf_record); | ||
2427 | 2632 | ||
2428 | out: | 2633 | out: |
2429 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | 2634 | lpfc_sli4_mbox_cmd_free(phba, mboxq); |
@@ -2893,8 +3098,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) | |||
2893 | goto out; | 3098 | goto out; |
2894 | } | 3099 | } |
2895 | /* Reset FCF roundrobin bmask for new discovery */ | 3100 | /* Reset FCF roundrobin bmask for new discovery */ |
2896 | memset(phba->fcf.fcf_rr_bmask, 0, | 3101 | lpfc_sli4_clear_fcf_rr_bmask(phba); |
2897 | sizeof(*phba->fcf.fcf_rr_bmask)); | ||
2898 | } | 3102 | } |
2899 | 3103 | ||
2900 | return; | 3104 | return; |
@@ -5592,7 +5796,7 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba) | |||
5592 | spin_unlock_irq(&phba->hbalock); | 5796 | spin_unlock_irq(&phba->hbalock); |
5593 | 5797 | ||
5594 | /* Reset FCF roundrobin bmask for new discovery */ | 5798 | /* Reset FCF roundrobin bmask for new discovery */ |
5595 | memset(phba->fcf.fcf_rr_bmask, 0, sizeof(*phba->fcf.fcf_rr_bmask)); | 5799 | lpfc_sli4_clear_fcf_rr_bmask(phba); |
5596 | 5800 | ||
5597 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); | 5801 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); |
5598 | 5802 | ||
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 4c58402fa698..a3c820083c36 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -3634,8 +3634,7 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, | |||
3634 | lpfc_sli4_fcf_dead_failthrough(phba); | 3634 | lpfc_sli4_fcf_dead_failthrough(phba); |
3635 | } else { | 3635 | } else { |
3636 | /* Reset FCF roundrobin bmask for new discovery */ | 3636 | /* Reset FCF roundrobin bmask for new discovery */ |
3637 | memset(phba->fcf.fcf_rr_bmask, 0, | 3637 | lpfc_sli4_clear_fcf_rr_bmask(phba); |
3638 | sizeof(*phba->fcf.fcf_rr_bmask)); | ||
3639 | /* | 3638 | /* |
3640 | * Handling fast FCF failover to a DEAD FCF event is | 3639 | * Handling fast FCF failover to a DEAD FCF event is |
3641 | * considered equalivant to receiving CVL to all vports. | 3640 | * considered equalivant to receiving CVL to all vports. |
@@ -3721,8 +3720,7 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, | |||
3721 | * Reset FCF roundrobin bmask for new | 3720 | * Reset FCF roundrobin bmask for new |
3722 | * discovery. | 3721 | * discovery. |
3723 | */ | 3722 | */ |
3724 | memset(phba->fcf.fcf_rr_bmask, 0, | 3723 | lpfc_sli4_clear_fcf_rr_bmask(phba); |
3725 | sizeof(*phba->fcf.fcf_rr_bmask)); | ||
3726 | } | 3724 | } |
3727 | break; | 3725 | break; |
3728 | default: | 3726 | default: |
@@ -9046,6 +9044,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
9046 | } | 9044 | } |
9047 | 9045 | ||
9048 | INIT_LIST_HEAD(&phba->active_rrq_list); | 9046 | INIT_LIST_HEAD(&phba->active_rrq_list); |
9047 | INIT_LIST_HEAD(&phba->fcf.fcf_pri_list); | ||
9049 | 9048 | ||
9050 | /* Set up common device driver resources */ | 9049 | /* Set up common device driver resources */ |
9051 | error = lpfc_setup_driver_resource_phase2(phba); | 9050 | error = lpfc_setup_driver_resource_phase2(phba); |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 247c24f438f5..8b799f047a99 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -14635,6 +14635,92 @@ fail_fcf_read: | |||
14635 | } | 14635 | } |
14636 | 14636 | ||
14637 | /** | 14637 | /** |
14638 | * lpfc_check_next_fcf_pri | ||
14639 | * phba pointer to the lpfc_hba struct for this port. | ||
14640 | * This routine is called from the lpfc_sli4_fcf_rr_next_index_get | ||
14641 | * routine when the rr_bmask is empty. The FCF indecies are put into the | ||
14642 | * rr_bmask based on their priority level. Starting from the highest priority | ||
14643 | * to the lowest. The most likely FCF candidate will be in the highest | ||
14644 | * priority group. When this routine is called it searches the fcf_pri list for | ||
14645 | * next lowest priority group and repopulates the rr_bmask with only those | ||
14646 | * fcf_indexes. | ||
14647 | * returns: | ||
14648 | * 1=success 0=failure | ||
14649 | **/ | ||
14650 | int | ||
14651 | lpfc_check_next_fcf_pri_level(struct lpfc_hba *phba) | ||
14652 | { | ||
14653 | uint16_t next_fcf_pri; | ||
14654 | uint16_t last_index; | ||
14655 | struct lpfc_fcf_pri *fcf_pri; | ||
14656 | int rc; | ||
14657 | int ret = 0; | ||
14658 | |||
14659 | last_index = find_first_bit(phba->fcf.fcf_rr_bmask, | ||
14660 | LPFC_SLI4_FCF_TBL_INDX_MAX); | ||
14661 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
14662 | "3060 Last IDX %d\n", last_index); | ||
14663 | if (list_empty(&phba->fcf.fcf_pri_list)) { | ||
14664 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP, | ||
14665 | "3061 Last IDX %d\n", last_index); | ||
14666 | return 0; /* Empty rr list */ | ||
14667 | } | ||
14668 | next_fcf_pri = 0; | ||
14669 | /* | ||
14670 | * Clear the rr_bmask and set all of the bits that are at this | ||
14671 | * priority. | ||
14672 | */ | ||
14673 | memset(phba->fcf.fcf_rr_bmask, 0, | ||
14674 | sizeof(*phba->fcf.fcf_rr_bmask)); | ||
14675 | spin_lock_irq(&phba->hbalock); | ||
14676 | list_for_each_entry(fcf_pri, &phba->fcf.fcf_pri_list, list) { | ||
14677 | if (fcf_pri->fcf_rec.flag & LPFC_FCF_FLOGI_FAILED) | ||
14678 | continue; | ||
14679 | /* | ||
14680 | * the 1st priority that has not FLOGI failed | ||
14681 | * will be the highest. | ||
14682 | */ | ||
14683 | if (!next_fcf_pri) | ||
14684 | next_fcf_pri = fcf_pri->fcf_rec.priority; | ||
14685 | spin_unlock_irq(&phba->hbalock); | ||
14686 | if (fcf_pri->fcf_rec.priority == next_fcf_pri) { | ||
14687 | rc = lpfc_sli4_fcf_rr_index_set(phba, | ||
14688 | fcf_pri->fcf_rec.fcf_index); | ||
14689 | if (rc) | ||
14690 | return 0; | ||
14691 | } | ||
14692 | spin_lock_irq(&phba->hbalock); | ||
14693 | } | ||
14694 | /* | ||
14695 | * if next_fcf_pri was not set above and the list is not empty then | ||
14696 | * we have failed flogis on all of them. So reset flogi failed | ||
14697 | * and start at the begining. | ||
14698 | */ | ||
14699 | if (!next_fcf_pri && !list_empty(&phba->fcf.fcf_pri_list)) { | ||
14700 | list_for_each_entry(fcf_pri, &phba->fcf.fcf_pri_list, list) { | ||
14701 | fcf_pri->fcf_rec.flag &= ~LPFC_FCF_FLOGI_FAILED; | ||
14702 | /* | ||
14703 | * the 1st priority that has not FLOGI failed | ||
14704 | * will be the highest. | ||
14705 | */ | ||
14706 | if (!next_fcf_pri) | ||
14707 | next_fcf_pri = fcf_pri->fcf_rec.priority; | ||
14708 | spin_unlock_irq(&phba->hbalock); | ||
14709 | if (fcf_pri->fcf_rec.priority == next_fcf_pri) { | ||
14710 | rc = lpfc_sli4_fcf_rr_index_set(phba, | ||
14711 | fcf_pri->fcf_rec.fcf_index); | ||
14712 | if (rc) | ||
14713 | return 0; | ||
14714 | } | ||
14715 | spin_lock_irq(&phba->hbalock); | ||
14716 | } | ||
14717 | } else | ||
14718 | ret = 1; | ||
14719 | spin_unlock_irq(&phba->hbalock); | ||
14720 | |||
14721 | return ret; | ||
14722 | } | ||
14723 | /** | ||
14638 | * lpfc_sli4_fcf_rr_next_index_get - Get next eligible fcf record index | 14724 | * lpfc_sli4_fcf_rr_next_index_get - Get next eligible fcf record index |
14639 | * @phba: pointer to lpfc hba data structure. | 14725 | * @phba: pointer to lpfc hba data structure. |
14640 | * | 14726 | * |
@@ -14650,6 +14736,7 @@ lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba) | |||
14650 | uint16_t next_fcf_index; | 14736 | uint16_t next_fcf_index; |
14651 | 14737 | ||
14652 | /* Search start from next bit of currently registered FCF index */ | 14738 | /* Search start from next bit of currently registered FCF index */ |
14739 | next_priority: | ||
14653 | next_fcf_index = (phba->fcf.current_rec.fcf_indx + 1) % | 14740 | next_fcf_index = (phba->fcf.current_rec.fcf_indx + 1) % |
14654 | LPFC_SLI4_FCF_TBL_INDX_MAX; | 14741 | LPFC_SLI4_FCF_TBL_INDX_MAX; |
14655 | next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask, | 14742 | next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask, |
@@ -14657,17 +14744,46 @@ lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba) | |||
14657 | next_fcf_index); | 14744 | next_fcf_index); |
14658 | 14745 | ||
14659 | /* Wrap around condition on phba->fcf.fcf_rr_bmask */ | 14746 | /* Wrap around condition on phba->fcf.fcf_rr_bmask */ |
14660 | if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) | 14747 | if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) { |
14748 | /* | ||
14749 | * If we have wrapped then we need to clear the bits that | ||
14750 | * have been tested so that we can detect when we should | ||
14751 | * change the priority level. | ||
14752 | */ | ||
14661 | next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask, | 14753 | next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask, |
14662 | LPFC_SLI4_FCF_TBL_INDX_MAX, 0); | 14754 | LPFC_SLI4_FCF_TBL_INDX_MAX, 0); |
14755 | } | ||
14756 | |||
14663 | 14757 | ||
14664 | /* Check roundrobin failover list empty condition */ | 14758 | /* Check roundrobin failover list empty condition */ |
14665 | if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) { | 14759 | if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX || |
14760 | next_fcf_index == phba->fcf.current_rec.fcf_indx) { | ||
14761 | /* | ||
14762 | * If next fcf index is not found check if there are lower | ||
14763 | * Priority level fcf's in the fcf_priority list. | ||
14764 | * Set up the rr_bmask with all of the avaiable fcf bits | ||
14765 | * at that level and continue the selection process. | ||
14766 | */ | ||
14767 | if (lpfc_check_next_fcf_pri_level(phba)) | ||
14768 | goto next_priority; | ||
14666 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, | 14769 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, |
14667 | "2844 No roundrobin failover FCF available\n"); | 14770 | "2844 No roundrobin failover FCF available\n"); |
14668 | return LPFC_FCOE_FCF_NEXT_NONE; | 14771 | if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) |
14772 | return LPFC_FCOE_FCF_NEXT_NONE; | ||
14773 | else { | ||
14774 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, | ||
14775 | "3063 Only FCF available idx %d, flag %x\n", | ||
14776 | next_fcf_index, | ||
14777 | phba->fcf.fcf_pri[next_fcf_index].fcf_rec.flag); | ||
14778 | return next_fcf_index; | ||
14779 | } | ||
14669 | } | 14780 | } |
14670 | 14781 | ||
14782 | if (next_fcf_index < LPFC_SLI4_FCF_TBL_INDX_MAX && | ||
14783 | phba->fcf.fcf_pri[next_fcf_index].fcf_rec.flag & | ||
14784 | LPFC_FCF_FLOGI_FAILED) | ||
14785 | goto next_priority; | ||
14786 | |||
14671 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | 14787 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, |
14672 | "2845 Get next roundrobin failover FCF (x%x)\n", | 14788 | "2845 Get next roundrobin failover FCF (x%x)\n", |
14673 | next_fcf_index); | 14789 | next_fcf_index); |
@@ -14719,6 +14835,7 @@ lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index) | |||
14719 | void | 14835 | void |
14720 | lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index) | 14836 | lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index) |
14721 | { | 14837 | { |
14838 | struct lpfc_fcf_pri *fcf_pri; | ||
14722 | if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) { | 14839 | if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) { |
14723 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP, | 14840 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP, |
14724 | "2762 FCF (x%x) reached driver's book " | 14841 | "2762 FCF (x%x) reached driver's book " |
@@ -14727,6 +14844,14 @@ lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index) | |||
14727 | return; | 14844 | return; |
14728 | } | 14845 | } |
14729 | /* Clear the eligible FCF record index bmask */ | 14846 | /* Clear the eligible FCF record index bmask */ |
14847 | spin_lock_irq(&phba->hbalock); | ||
14848 | list_for_each_entry(fcf_pri, &phba->fcf.fcf_pri_list, list) { | ||
14849 | if (fcf_pri->fcf_rec.fcf_index == fcf_index) { | ||
14850 | list_del_init(&fcf_pri->list); | ||
14851 | break; | ||
14852 | } | ||
14853 | } | ||
14854 | spin_unlock_irq(&phba->hbalock); | ||
14730 | clear_bit(fcf_index, phba->fcf.fcf_rr_bmask); | 14855 | clear_bit(fcf_index, phba->fcf.fcf_rr_bmask); |
14731 | 14856 | ||
14732 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | 14857 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 88387c1c2dcc..19bb87ae8597 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -159,6 +159,25 @@ struct lpfc_fcf_rec { | |||
159 | #define RECORD_VALID 0x02 | 159 | #define RECORD_VALID 0x02 |
160 | }; | 160 | }; |
161 | 161 | ||
162 | struct lpfc_fcf_pri_rec { | ||
163 | uint16_t fcf_index; | ||
164 | #define LPFC_FCF_ON_PRI_LIST 0x0001 | ||
165 | #define LPFC_FCF_FLOGI_FAILED 0x0002 | ||
166 | uint16_t flag; | ||
167 | uint32_t priority; | ||
168 | }; | ||
169 | |||
170 | struct lpfc_fcf_pri { | ||
171 | struct list_head list; | ||
172 | struct lpfc_fcf_pri_rec fcf_rec; | ||
173 | }; | ||
174 | |||
175 | /* | ||
176 | * Maximum FCF table index, it is for driver internal book keeping, it | ||
177 | * just needs to be no less than the supported HBA's FCF table size. | ||
178 | */ | ||
179 | #define LPFC_SLI4_FCF_TBL_INDX_MAX 32 | ||
180 | |||
162 | struct lpfc_fcf { | 181 | struct lpfc_fcf { |
163 | uint16_t fcfi; | 182 | uint16_t fcfi; |
164 | uint32_t fcf_flag; | 183 | uint32_t fcf_flag; |
@@ -178,15 +197,13 @@ struct lpfc_fcf { | |||
178 | uint32_t eligible_fcf_cnt; | 197 | uint32_t eligible_fcf_cnt; |
179 | struct lpfc_fcf_rec current_rec; | 198 | struct lpfc_fcf_rec current_rec; |
180 | struct lpfc_fcf_rec failover_rec; | 199 | struct lpfc_fcf_rec failover_rec; |
200 | struct list_head fcf_pri_list; | ||
201 | struct lpfc_fcf_pri fcf_pri[LPFC_SLI4_FCF_TBL_INDX_MAX]; | ||
202 | uint32_t current_fcf_scan_pri; | ||
181 | struct timer_list redisc_wait; | 203 | struct timer_list redisc_wait; |
182 | unsigned long *fcf_rr_bmask; /* Eligible FCF indexes for RR failover */ | 204 | unsigned long *fcf_rr_bmask; /* Eligible FCF indexes for RR failover */ |
183 | }; | 205 | }; |
184 | 206 | ||
185 | /* | ||
186 | * Maximum FCF table index, it is for driver internal book keeping, it | ||
187 | * just needs to be no less than the supported HBA's FCF table size. | ||
188 | */ | ||
189 | #define LPFC_SLI4_FCF_TBL_INDX_MAX 32 | ||
190 | 207 | ||
191 | #define LPFC_REGION23_SIGNATURE "RG23" | 208 | #define LPFC_REGION23_SIGNATURE "RG23" |
192 | #define LPFC_REGION23_VERSION 1 | 209 | #define LPFC_REGION23_VERSION 1 |