lpfc 8.3.21: FC Discovery changes
Subsystems (2)
PATCH 3/6 lpfc 8.3.21: FC Discovery changes
FC Discovery changes
- Treat received PLOGI while logged in as a relogin (unregister and reregister).
- Added a timer to delay Nport discovery when clean bit is cleared and Fabric portname/nodename/FCID is changed.
- Invalidate Port's DID when receiving PLOGI from p2p port with CONFIG_PORT mailbox command.
Signed-off-by Alex Iannicelli <[email protected]>
Signed-off-by James Smart <[email protected]>
---
lpfc.h | 5 ++ lpfc_attr.c | 21 +++++++++ lpfc_crtn.h | 3 + lpfc_ct.c | 49 ++++++++++++++++++++++ lpfc_els.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- lpfc_hbadisc.c | 7 +++ lpfc_hw.h | 6 ++ lpfc_init.c | 6 ++ lpfc_nportdisc.c | 11 +++-- 9 files changed, 219 insertions(+), 7 deletions(-)
drivers/scsi/lpfc/lpfc_attr.c +20 -1
@@ -1,7 +1,7 @@/******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * -* Copyright (C) 2004-2009 Emulex. All rights reserved. * +* Copyright (C) 2004-2011 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -3365,6 +3365,25 @@ unsigned char lpfc_prot_guard = SHOST_DImodule_param (lpfc_prot_guard, byte,0 );MODULE_PARM_DESC (lpfc_prot_guard,"host protection guard type" ); +/* +* Delay initial NPort discovery when Clean Address bit is cleared in +* FLOGI/FDISC accept and FCID/Fabric name/Fabric portname is changed. +* This parameter can have value 0 or 1. +* When this parameter is set to 0, no delay is added to the initial +* discovery. +* When this parameter is set to non-zero value, initial Nport discovery is +* delayed by ra_tov seconds when Clean Address bit is cleared in FLOGI/FDISC +* accept and FCID/Fabric name/Fabric portname is changed. +* Driver always delay Nport discovery for subsequent FLOGI/FDISC completion +* when Clean Address bit is cleared in FLOGI/FDISC +* accept and FCID/Fabric name/Fabric portname is changed. +* Default value is 0. +*/ +int lpfc_delay_discovery; +module_param (lpfc_delay_discovery, int,0 ); +MODULE_PARM_DESC (lpfc_delay_discovery, +"Delay NPort discovery when Clean Address bit is cleared. " +"Allowed values: 0,1." );/* * lpfc_sg_seg_cnt - Initial Maximum DMA Segment Count
drivers/scsi/lpfc/lpfc_crtn.h +3 -0
@@ -167,6 +167,8 @@ int lpfc_ns_cmd(struct lpfc_vport *, intint lpfc_fdmi_cmd (struct lpfc_vport *,struct lpfc_nodelist *,int );void lpfc_fdmi_tmo (unsigned long );void lpfc_fdmi_timeout_handler (struct lpfc_vport *); +void lpfc_delayed_disc_tmo (unsigned long ); +void lpfc_delayed_disc_timeout_handler (struct lpfc_vport *);int lpfc_config_port_prep (struct lpfc_hba *);int lpfc_config_port_post (struct lpfc_hba *);
@@ -341,6 +343,7 @@ extern struct fc_function_template lpfc_extern struct fc_function_template lpfc_vport_transport_functions;extern int lpfc_sli_mode;extern int lpfc_enable_npiv; +extern int lpfc_delay_discovery;int lpfc_vport_symbolic_node_name (struct lpfc_vport *,char *,size_t );int lpfc_vport_symbolic_port_name (struct lpfc_vport *,char *,size_t );
drivers/scsi/lpfc/lpfc_ct.c +49 -0
55 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_els.c +115 -3
190 lines not on this page · raw message
drivers/scsi/lpfc/lpfc.h +5 -0
@@ -325,6 +325,7 @@ struct lpfc_vport {#define FC_VPORT_CVL_RCVD 0x400000/* VLink failed due to CVL */ #define FC_VFI_REGISTERED 0x800000/* VFI is registered */ #define FC_FDISC_COMPLETED 0x1000000/* FDISC completed */ +#define FC_DISC_DELAYED 0x2000000/* Delay NPort discovery */ uint32_t ct_flags;#define FC_CT_RFF_ID 0x1/* RFF_ID accepted by switch */
@@ -348,6 +349,8 @@ struct lpfc_vport {uint32_t fc_myDID;/* fibre channel S_ID */ uint32_t fc_prevDID;/* previous fibre channel S_ID */ +struct lpfc_name fabric_portname; +struct lpfc_name fabric_nodename;int32_t stopped;/* HBA has not been restarted since last ERATT */ uint8_t fc_linkspeed;/* Link speed after last READ_LA */
@@ -372,6 +375,7 @@ struct lpfc_vport {#define WORKER_DISC_TMO 0x1/* vport: Discovery timeout */ #define WORKER_ELS_TMO 0x2/* vport: ELS timeout */ #define WORKER_FDMI_TMO 0x4/* vport: FDMI timeout */ +#define WORKER_DELAYED_DISC_TMO 0x8/* vport: delayed discovery */ #define WORKER_MBOX_TMO 0x100/* hba: MBOX timeout */ #define WORKER_HB_TMO 0x200/* hba: Heart beat timeout */
@@ -382,6 +386,7 @@ struct lpfc_vport {struct timer_list fc_fdmitmo;struct timer_list els_tmofunc; +struct timer_list delayed_disc_tmo;int unreg_vpi_cmpl;
drivers/scsi/lpfc/lpfc_hbadisc.c +7 -0
@@ -658,6 +658,8 @@ lpfc_work_done(struct lpfc_hba *phba)lpfc_ramp_down_queue_handler (phba);if (work_port_events &WORKER_RAMP_UP_QUEUE )lpfc_ramp_up_queue_handler (phba); +if (work_port_events &WORKER_DELAYED_DISC_TMO ) +lpfc_delayed_disc_timeout_handler (vport); }lpfc_destroy_vport_work_array (phba, vports);
@@ -838,6 +840,11 @@ lpfc_linkdown_port(struct lpfc_vport *vplpfc_port_link_failure (vport); +/* Stop delayed Nport discovery */ +spin_lock_irq (shost->host_lock); + vport->fc_flag &= ~FC_DISC_DELAYED ; +spin_unlock_irq (shost->host_lock); +del_timer_sync (&vport->delayed_disc_tmo); }int
drivers/scsi/lpfc/lpfc_hw.h +6 -0
@@ -341,6 +341,12 @@ struct csp {uint8_t bbCreditMsb;uint8_t bbCreditlsb;/* FC Word 0, byte 3 */ +/* +* Word 1 Bit 31 in common service parameter is overloaded. +* Word 1 Bit 31 in FLOGI request is multiple NPort request +* Word 1 Bit 31 in FLOGI response is clean address bit +*/ +#define clean_address_bit request_multiple_Nport/* Word 1, bit 31 */ #ifdef __BIG_ENDIAN_BITFIELD uint16_t request_multiple_Nport:1; /* FC Word 1, bit 31 */ uint16_t randomOffset:1; /* FC Word 1, bit 30 */
drivers/scsi/lpfc/lpfc_init.c +6 -0
@@ -2292,6 +2292,7 @@ lpfc_stop_vport_timers(struct lpfc_vport {del_timer_sync (&vport->els_tmofunc);del_timer_sync (&vport->fc_fdmitmo); +del_timer_sync (&vport->delayed_disc_tmo);lpfc_can_disctmo (vport);return ; }
@@ -2733,6 +2734,11 @@ lpfc_create_port(struct lpfc_hba *phba,init_timer (&vport->els_tmofunc); vport->els_tmofunc.function = lpfc_els_timeout; vport->els_tmofunc.data = (unsigned long )vport; + +init_timer (&vport->delayed_disc_tmo); + vport->delayed_disc_tmo.function = lpfc_delayed_disc_tmo; + vport->delayed_disc_tmo.data = (unsigned long )vport; + error =scsi_add_host_with_dma (shost, dev, &phba->pcidev->dev);if (error) goto out_put_shost;
drivers/scsi/lpfc/lpfc_nportdisc.c +8 -3
@@ -350,7 +350,11 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb &0x0F ) <<8 ) | sp->cmn.bbRcvSizeLsb; -/* no need to reg_login if we are already in one of these states */ +/* +* Need to unreg_login if we are already in one of these states and +* change to NPR state. This will block the port until after the ACC +* completes and the reg_login is issued and completed. +*/ switch (ndlp->nlp_state) {case NLP_STE_NPR_NODE :if (!(ndlp->nlp_flag &NLP_NPR_ADISC ))
@@ -359,8 +363,9 @@ lpfc_rcv_plogi(struct lpfc_vport *vport,case NLP_STE_PRLI_ISSUE :case NLP_STE_UNMAPPED_NODE :case NLP_STE_MAPPED_NODE : -lpfc_els_rsp_acc (vport,ELS_CMD_PLOGI , cmdiocb, ndlp,NULL ); -return 1 ; +lpfc_unreg_rpi (vport, ndlp); + ndlp->nlp_prev_state = ndlp->nlp_state; +lpfc_nlp_set_state (vport, ndlp,NLP_STE_NPR_NODE ); } if ((vport->fc_flag & FC_PT2PT) &&