> On Oct 9, 2020, at 4:36 AM, Javed Hasan <jhasan@xxxxxxxxxxx> wrote: > > Added all the attributes for RHBA and RPA registration. > Fall back mechanism is added in between RBHA V2 and > RHBA V1 attributes. In case RHBA get failed > for RBHA V2 attributes, then we fall back to RHBA V1 > attributes registration. > > Signed-off-by: Javed Hasan <jhasan@xxxxxxxxxxx> > --- > drivers/scsi/libfc/fc_lport.c | 64 +++++++++++++++++++++++++++++++---- > 1 file changed, 58 insertions(+), 6 deletions(-) > > diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c > index b84dbc316df1..9b32930b5c67 100644 > --- a/drivers/scsi/libfc/fc_lport.c > +++ b/drivers/scsi/libfc/fc_lport.c > @@ -1185,7 +1185,7 @@ static void fc_lport_ms_resp(struct fc_seq *sp, struct fc_frame *fp, > struct fc_lport *lport = lp_arg; > struct fc_frame_header *fh; > struct fc_ct_hdr *ct; > - > + struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host); > FC_LPORT_DBG(lport, "Received a ms %s\n", fc_els_resp_type(fp)); > > if (fp == ERR_PTR(-FC_EX_CLOSED)) > @@ -1219,7 +1219,13 @@ static void fc_lport_ms_resp(struct fc_seq *sp, struct fc_frame *fp, > > switch (lport->state) { > case LPORT_ST_RHBA: > - if (ntohs(ct->ct_cmd) == FC_FS_ACC) > + if ((ntohs(ct->ct_cmd) == FC_FS_RJT) && fc_host->fdmi_version == FDMI_V2) { > + FC_LPORT_DBG(lport, "Error for FDMI-V2, fall back to FDMI-V1\n"); > + fc_host->fdmi_version = FDMI_V1; > + > + fc_lport_enter_ms(lport, LPORT_ST_RHBA); > + > + } else if (ntohs(ct->ct_cmd) == FC_FS_ACC) > fc_lport_enter_ms(lport, LPORT_ST_RPA); > else /* Error Skip RPA */ > fc_lport_enter_scr(lport); > @@ -1433,7 +1439,7 @@ static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state) > int size = sizeof(struct fc_ct_hdr); > size_t len; > int numattrs; > - > + struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host); > lockdep_assert_held(&lport->lp_mutex); > > FC_LPORT_DBG(lport, "Entered %s state from %s state\n", > @@ -1446,10 +1452,10 @@ static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state) > case LPORT_ST_RHBA: > cmd = FC_FDMI_RHBA; > /* Number of HBA Attributes */ > - numattrs = 10; > + numattrs = 11; > len = sizeof(struct fc_fdmi_rhba); > len -= sizeof(struct fc_fdmi_attr_entry); > - len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN); > + > len += FC_FDMI_HBA_ATTR_NODENAME_LEN; > len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN; > len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN; > @@ -1460,6 +1466,21 @@ static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state) > len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN; > len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN; > len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN; > + len += FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN; > + > + > + if (fc_host->fdmi_version == FDMI_V2) { > + numattrs += 7; > + len += FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN; > + len += FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN; > + len += FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN; > + len += FC_FDMI_HBA_ATTR_FABRICNAME_LEN; > + len += FC_FDMI_HBA_ATTR_BIOSVERSION_LEN; > + len += FC_FDMI_HBA_ATTR_BIOSSTATE_LEN; > + len += FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN; > + } > + > + len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN); > > size += len; > break; > @@ -1469,7 +1490,6 @@ static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state) > numattrs = 6; > len = sizeof(struct fc_fdmi_rpa); > len -= sizeof(struct fc_fdmi_attr_entry); > - len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN); > len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN; > len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN; > len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN; > @@ -1477,6 +1497,22 @@ static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state) > len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN; > len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN; > > + if (fc_host->fdmi_version == FDMI_V2) { > + numattrs += 10; > + len += FC_FDMI_PORT_ATTR_NODENAME_LEN; > + len += FC_FDMI_PORT_ATTR_PORTNAME_LEN; > + len += FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN; > + len += FC_FDMI_PORT_ATTR_PORTTYPE_LEN; > + len += FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN; > + len += FC_FDMI_PORT_ATTR_FABRICNAME_LEN; > + len += FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN; > + len += FC_FDMI_PORT_ATTR_PORTSTATE_LEN; > + len += FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN; > + len += FC_FDMI_PORT_ATTR_PORTID_LEN; > + } > + > + len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN); > + > size += len; > break; > case LPORT_ST_DPRT: > @@ -1546,6 +1582,7 @@ static void fc_lport_timeout(struct work_struct *work) > struct fc_lport *lport = > container_of(work, struct fc_lport, > retry_work.work); > + struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host); > > mutex_lock(&lport->lp_mutex); > > @@ -1573,6 +1610,13 @@ static void fc_lport_timeout(struct work_struct *work) > fc_lport_enter_fdmi(lport); > break; > case LPORT_ST_RHBA: > + if (fc_host->fdmi_version == FDMI_V2) { > + FC_LPORT_DBG(lport, "timeout for FDMI-V2 RHBA,fall back to FDMI-V1\n"); > + fc_host->fdmi_version = FDMI_V1; > + fc_lport_enter_ms(lport, LPORT_ST_RHBA); > + break; > + } > + fallthrough; > case LPORT_ST_RPA: > case LPORT_ST_DHBA: > case LPORT_ST_DPRT: > @@ -1839,6 +1883,13 @@ EXPORT_SYMBOL(fc_lport_config); > */ > int fc_lport_init(struct fc_lport *lport) > { > + struct fc_host_attrs *fc_host; > + > + fc_host = shost_to_fc_host(lport->host); > + > + /* Set FDMI version to FDMI-2 specification*/ > + fc_host->fdmi_version = FDMI_V2; > + > fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; > fc_host_node_name(lport->host) = lport->wwnn; > fc_host_port_name(lport->host) = lport->wwpn; > @@ -1847,6 +1898,7 @@ int fc_lport_init(struct fc_lport *lport) > sizeof(fc_host_supported_fc4s(lport->host))); > fc_host_supported_fc4s(lport->host)[2] = 1; > fc_host_supported_fc4s(lport->host)[7] = 1; > + fc_host_num_discovered_ports(lport->host) = 4; > > /* This value is also unchanging */ > memset(fc_host_active_fc4s(lport->host), 0, > -- > 2.18.2 > Looks Good. Reviewed-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx> -- Himanshu Madhani Oracle Linux Engineering