aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2009-06-10 17:22:56 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-15 11:09:33 -0400
commit0c2875893ef27b93d5d3221f8f98ae944d6be5fa (patch)
tree01e201e3827611c9b5cfc35a5f00b6532fc948ef
parentf1126688805d77a4798b694439fa48bba6629388 (diff)
[SCSI] lpfc 8.3.3 : FC/FCOE discovery fixes
Contains the following changes: - Force vport to send LOGO to fabric controller when deleting vport - Fixed driver failing to register login when a PLOGI is received - Fixes for FIP discovery - Added stricter checks for FCF addressing mode - Added code to send only FLOGI, FDISC and LOGO to Fabric controller as FIP - Fixed handling of LOGO from Fabric port - Fixed consecutive link up events skipped link_down processing Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c13
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c35
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c6
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c24
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c2
8 files changed, 59 insertions, 26 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 2aabaf9c4053..f72fdf23bf1b 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -168,6 +168,19 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
168 if (elsiocb == NULL) 168 if (elsiocb == NULL)
169 return NULL; 169 return NULL;
170 170
171 /*
172 * If this command is for fabric controller and HBA running
173 * in FIP mode send FLOGI, FDISC and LOGO as FIP frames.
174 */
175 if ((did == Fabric_DID) &&
176 bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags) &&
177 ((elscmd == ELS_CMD_FLOGI) ||
178 (elscmd == ELS_CMD_FDISC) ||
179 (elscmd == ELS_CMD_LOGO)))
180 elsiocb->iocb_flag |= LPFC_FIP_ELS;
181 else
182 elsiocb->iocb_flag &= ~LPFC_FIP_ELS;
183
171 icmd = &elsiocb->iocb; 184 icmd = &elsiocb->iocb;
172 185
173 /* fill in BDEs for command */ 186 /* fill in BDEs for command */
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 35c41ae75be2..ed46b24a3380 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1197,6 +1197,11 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
1197{ 1197{
1198 struct lpfc_fcf_conn_entry *conn_entry; 1198 struct lpfc_fcf_conn_entry *conn_entry;
1199 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
1200 if (!phba->cfg_enable_fip) { 1205 if (!phba->cfg_enable_fip) {
1201 *boot_flag = 0; 1206 *boot_flag = 0;
1202 *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, 1207 *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov,
@@ -1216,6 +1221,14 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
1216 *boot_flag = 0; 1221 *boot_flag = 0;
1217 *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, 1222 *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov,
1218 new_fcf_record); 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
1219 *vlan_id = 0xFFFF; 1232 *vlan_id = 0xFFFF;
1220 return 1; 1233 return 1;
1221 } 1234 }
@@ -1241,6 +1254,14 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
1241 } 1254 }
1242 1255
1243 /* 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 /*
1244 * Check if the connection record specifies a required 1265 * Check if the connection record specifies a required
1245 * addressing mode. 1266 * addressing mode.
1246 */ 1267 */
@@ -1272,6 +1293,11 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
1272 else 1293 else
1273 *boot_flag = 0; 1294 *boot_flag = 0;
1274 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 */
1275 *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, 1301 *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov,
1276 new_fcf_record); 1302 new_fcf_record);
1277 /* 1303 /*
@@ -1297,12 +1323,6 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
1297 !(conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && 1323 !(conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) &&
1298 (*addr_mode & LPFC_FCF_FPMA)) 1324 (*addr_mode & LPFC_FCF_FPMA))
1299 *addr_mode = LPFC_FCF_FPMA; 1325 *addr_mode = LPFC_FCF_FPMA;
1300 /*
1301 * If user did not specify any addressing mode, use FPMA if
1302 * possible else use SPMA.
1303 */
1304 else if (*addr_mode & LPFC_FCF_FPMA)
1305 *addr_mode = LPFC_FCF_FPMA;
1306 1326
1307 if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID) 1327 if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID)
1308 *vlan_id = conn_entry->conn_rec.vlan_tag; 1328 *vlan_id = conn_entry->conn_rec.vlan_tag;
@@ -1864,7 +1884,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1864 vport->fc_flag &= ~FC_BYPASSED_MODE; 1884 vport->fc_flag &= ~FC_BYPASSED_MODE;
1865 spin_unlock_irq(shost->host_lock); 1885 spin_unlock_irq(shost->host_lock);
1866 1886
1867 if (((phba->fc_eventTag + 1) < la->eventTag) || 1887 if ((phba->fc_eventTag < la->eventTag) ||
1868 (phba->fc_eventTag == la->eventTag)) { 1888 (phba->fc_eventTag == la->eventTag)) {
1869 phba->fc_stat.LinkMultiEvent++; 1889 phba->fc_stat.LinkMultiEvent++;
1870 if (la->attType == AT_LINK_UP) 1890 if (la->attType == AT_LINK_UP)
@@ -2925,6 +2945,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
2925 lpfc_no_rpi(phba, ndlp); 2945 lpfc_no_rpi(phba, ndlp);
2926 ndlp->nlp_rpi = 0; 2946 ndlp->nlp_rpi = 0;
2927 ndlp->nlp_flag &= ~NLP_RPI_VALID; 2947 ndlp->nlp_flag &= ~NLP_RPI_VALID;
2948 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2928 return 1; 2949 return 1;
2929 } 2950 }
2930 return 0; 2951 return 0;
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 749811a1627b..2995d128f07f 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1128,7 +1128,7 @@ struct fcf_record {
1128#define lpfc_fcf_record_mac_5_WORD word4 1128#define lpfc_fcf_record_mac_5_WORD word4
1129#define lpfc_fcf_record_fcf_avail_SHIFT 16 1129#define lpfc_fcf_record_fcf_avail_SHIFT 16
1130#define lpfc_fcf_record_fcf_avail_MASK 0x000000FF 1130#define lpfc_fcf_record_fcf_avail_MASK 0x000000FF
1131#define lpfc_fcf_record_fc_avail_WORD word4 1131#define lpfc_fcf_record_fcf_avail_WORD word4
1132#define lpfc_fcf_record_mac_addr_prov_SHIFT 24 1132#define lpfc_fcf_record_mac_addr_prov_SHIFT 24
1133#define lpfc_fcf_record_mac_addr_prov_MASK 0x000000FF 1133#define lpfc_fcf_record_mac_addr_prov_MASK 0x000000FF
1134#define lpfc_fcf_record_mac_addr_prov_WORD word4 1134#define lpfc_fcf_record_mac_addr_prov_WORD word4
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index b9b451c09010..bb3dc1dcffe0 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -1715,8 +1715,10 @@ lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq)
1715 /* Set up host requested features. */ 1715 /* Set up host requested features. */
1716 bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1); 1716 bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1);
1717 1717
1718 /* Virtual fabrics and FIPs are not supported yet. */ 1718 if (phba->cfg_enable_fip)
1719 bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 0); 1719 bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 0);
1720 else
1721 bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 1);
1720 1722
1721 /* Enable DIF (block guard) only if configured to do so. */ 1723 /* Enable DIF (block guard) only if configured to do so. */
1722 if (phba->cfg_enable_bg) 1724 if (phba->cfg_enable_bg)
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 09f659f77bb3..3e74136f1ede 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -497,7 +497,7 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
497 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL); 497 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
498 else 498 else
499 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); 499 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
500 if ((ndlp->nlp_type & NLP_FABRIC) && 500 if ((ndlp->nlp_DID == Fabric_DID) &&
501 vport->port_type == LPFC_NPIV_PORT) { 501 vport->port_type == LPFC_NPIV_PORT) {
502 lpfc_linkdown_port(vport); 502 lpfc_linkdown_port(vport);
503 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); 503 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index b8cf0a1b1382..ba698d5f31af 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -4491,8 +4491,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
4491 rc = -ENODEV; 4491 rc = -ENODEV;
4492 goto out_free_vpd; 4492 goto out_free_vpd;
4493 } 4493 }
4494 /* Temporary initialization of lpfc_fip_flag to non-fip */ 4494 if (phba->cfg_enable_fip)
4495 bf_set(lpfc_fip_flag, &phba->sli4_hba.sli4_flags, 0); 4495 bf_set(lpfc_fip_flag, &phba->sli4_hba.sli4_flags, 1);
4496 else
4497 bf_set(lpfc_fip_flag, &phba->sli4_hba.sli4_flags, 0);
4496 4498
4497 /* Set up all the queues to the device */ 4499 /* Set up all the queues to the device */
4498 rc = lpfc_sli4_queue_setup(phba); 4500 rc = lpfc_sli4_queue_setup(phba);
@@ -5856,18 +5858,13 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
5856 5858
5857 fip = bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags); 5859 fip = bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags);
5858 /* The fcp commands will set command type */ 5860 /* The fcp commands will set command type */
5859 if ((!(iocbq->iocb_flag & LPFC_IO_FCP)) && (!fip)) 5861 if (iocbq->iocb_flag & LPFC_IO_FCP)
5860 command_type = ELS_COMMAND_NON_FIP;
5861 else if (!(iocbq->iocb_flag & LPFC_IO_FCP))
5862 command_type = ELS_COMMAND_FIP;
5863 else if (iocbq->iocb_flag & LPFC_IO_FCP)
5864 command_type = FCP_COMMAND; 5862 command_type = FCP_COMMAND;
5865 else { 5863 else if (fip && (iocbq->iocb_flag & LPFC_FIP_ELS))
5866 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 5864 command_type = ELS_COMMAND_FIP;
5867 "2019 Invalid cmd 0x%x\n", 5865 else
5868 iocbq->iocb.ulpCommand); 5866 command_type = ELS_COMMAND_NON_FIP;
5869 return IOCB_ERROR; 5867
5870 }
5871 /* Some of the fields are in the right position already */ 5868 /* Some of the fields are in the right position already */
5872 memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe)); 5869 memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe));
5873 abort_tag = (uint32_t) iocbq->iotag; 5870 abort_tag = (uint32_t) iocbq->iotag;
@@ -11467,6 +11464,7 @@ lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *phba,
11467 bf_set(lpfc_fcf_record_fc_map_1, fcf_record, phba->fc_map[1]); 11464 bf_set(lpfc_fcf_record_fc_map_1, fcf_record, phba->fc_map[1]);
11468 bf_set(lpfc_fcf_record_fc_map_2, fcf_record, phba->fc_map[2]); 11465 bf_set(lpfc_fcf_record_fc_map_2, fcf_record, phba->fc_map[2]);
11469 bf_set(lpfc_fcf_record_fcf_valid, fcf_record, 1); 11466 bf_set(lpfc_fcf_record_fcf_valid, fcf_record, 1);
11467 bf_set(lpfc_fcf_record_fcf_avail, fcf_record, 1);
11470 bf_set(lpfc_fcf_record_fcf_index, fcf_record, fcf_index); 11468 bf_set(lpfc_fcf_record_fcf_index, fcf_record, fcf_index);
11471 bf_set(lpfc_fcf_record_mac_addr_prov, fcf_record, 11469 bf_set(lpfc_fcf_record_mac_addr_prov, fcf_record,
11472 LPFC_FCF_FPMA | LPFC_FCF_SPMA); 11470 LPFC_FCF_FPMA | LPFC_FCF_SPMA);
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 7d37eb7459bf..3c53316cf6d0 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -56,6 +56,7 @@ struct lpfc_iocbq {
56#define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */ 56#define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */
57#define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */ 57#define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */
58#define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */ 58#define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */
59#define LPFC_FIP_ELS 0x40
59 60
60 uint8_t abort_count; 61 uint8_t abort_count;
61 uint8_t rsvd2; 62 uint8_t rsvd2;
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index a6313ee84ac5..e0b49922193e 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -695,8 +695,6 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
695 } 695 }
696 vport->unreg_vpi_cmpl = VPORT_INVAL; 696 vport->unreg_vpi_cmpl = VPORT_INVAL;
697 timeout = msecs_to_jiffies(phba->fc_ratov * 2000); 697 timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
698 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
699 goto skip_logo;
700 if (!lpfc_issue_els_npiv_logo(vport, ndlp)) 698 if (!lpfc_issue_els_npiv_logo(vport, ndlp))
701 while (vport->unreg_vpi_cmpl == VPORT_INVAL && timeout) 699 while (vport->unreg_vpi_cmpl == VPORT_INVAL && timeout)
702 timeout = schedule_timeout(timeout); 700 timeout = schedule_timeout(timeout);