--- zzzz-none-000/linux-3.10.107/drivers/scsi/bfa/bfa_fcs_lport.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/scsi/bfa/bfa_fcs_lport.c 2021-02-04 17:41:59.000000000 +0000 @@ -773,7 +773,20 @@ bfa_trc(lport->fcs, fchs->type); if (!bfa_fcs_lport_is_online(lport)) { - bfa_stats(lport, uf_recv_drops); + /* + * In direct attach topology, it is possible to get a PLOGI + * before the lport is online due to port feature + * (QoS/Trunk/FEC/CR), so send a rjt + */ + if ((fchs->type == FC_TYPE_ELS) && + (els_cmd->els_code == FC_ELS_PLOGI)) { + bfa_fcs_lport_send_ls_rjt(lport, fchs, + FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD, + FC_LS_RJT_EXP_NO_ADDL_INFO); + bfa_stats(lport, plogi_rcvd); + } else + bfa_stats(lport, uf_recv_drops); + return; } @@ -2059,10 +2072,71 @@ attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT); templen = sizeof(fcs_hba_attr->max_ct_pyld); memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; len += templen; count++; attr->len = cpu_to_be16(templen + sizeof(attr->type) + sizeof(templen)); + /* + * Send extended attributes ( FOS 7.1 support ) + */ + if (fdmi->retry_cnt == 0) { + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODE_SYM_NAME); + templen = sizeof(fcs_hba_attr->node_sym_name); + memcpy(attr->value, &fcs_hba_attr->node_sym_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + count++; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_VENDOR_ID); + templen = sizeof(fcs_hba_attr->vendor_info); + memcpy(attr->value, &fcs_hba_attr->vendor_info, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + count++; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NUM_PORTS); + templen = sizeof(fcs_hba_attr->num_ports); + memcpy(attr->value, &fcs_hba_attr->num_ports, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + count++; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FABRIC_NAME); + templen = sizeof(fcs_hba_attr->fabric_name); + memcpy(attr->value, &fcs_hba_attr->fabric_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + count++; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_BIOS_VER); + templen = sizeof(fcs_hba_attr->bios_ver); + memcpy(attr->value, &fcs_hba_attr->bios_ver, templen); + templen = fc_roundup(attr->len, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + count++; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + } /* * Update size of payload @@ -2263,6 +2337,113 @@ sizeof(templen)); } + if (fdmi->retry_cnt == 0) { + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_NODE_NAME); + templen = sizeof(fcs_port_attr.node_name); + memcpy(attr->value, &fcs_port_attr.node_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NAME); + templen = sizeof(fcs_port_attr.port_name); + memcpy(attr->value, &fcs_port_attr.port_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(attr->len) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + if (fcs_port_attr.port_sym_name.symname[0] != '\0') { + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = + cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SYM_NAME); + templen = sizeof(fcs_port_attr.port_sym_name); + memcpy(attr->value, + &fcs_port_attr.port_sym_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + + sizeof(attr->type) + sizeof(templen)); + } + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_TYPE); + templen = sizeof(fcs_port_attr.port_type); + memcpy(attr->value, &fcs_port_attr.port_type, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_COS); + templen = sizeof(fcs_port_attr.scos); + memcpy(attr->value, &fcs_port_attr.scos, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FAB_NAME); + templen = sizeof(fcs_port_attr.port_fabric_name); + memcpy(attr->value, &fcs_port_attr.port_fabric_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FC4_TYPE); + templen = sizeof(fcs_port_attr.port_act_fc4_type); + memcpy(attr->value, fcs_port_attr.port_act_fc4_type, + templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_STATE); + templen = sizeof(fcs_port_attr.port_state); + memcpy(attr->value, &fcs_port_attr.port_state, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NUM_RPRT); + templen = sizeof(fcs_port_attr.num_ports); + memcpy(attr->value, &fcs_port_attr.num_ports, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + } + /* * Update size of payload */ @@ -2469,6 +2650,15 @@ /* Retrieve the max frame size from the port attr */ bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size; + + strncpy(hba_attr->node_sym_name.symname, + port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN); + strcpy(hba_attr->vendor_info, "BROCADE"); + hba_attr->num_ports = + cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc)); + hba_attr->fabric_name = port->fabric->lps->pr_nwwn; + strncpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN); + } static void @@ -2478,6 +2668,7 @@ struct bfa_fcs_lport_s *port = fdmi->ms->port; struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; struct bfa_port_attr_s pport_attr; + struct bfa_lport_attr_s lport_attr; memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s)); @@ -2542,6 +2733,18 @@ strncpy(port_attr->host_name, (char *)driver_info->host_machine_name, sizeof(port_attr->host_name)); + port_attr->node_name = bfa_fcs_lport_get_nwwn(port); + port_attr->port_name = bfa_fcs_lport_get_pwwn(port); + + strncpy(port_attr->port_sym_name.symname, + (char *)&bfa_fcs_lport_get_psym_name(port), BFA_SYMNAME_MAXLEN); + bfa_fcs_lport_get_attr(port, &lport_attr); + port_attr->port_type = cpu_to_be32(lport_attr.port_type); + port_attr->scos = pport_attr.cos_supported; + port_attr->port_fabric_name = port->fabric->lps->pr_nwwn; + fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->port_act_fc4_type); + port_attr->port_state = cpu_to_be32(pport_attr.port_state); + port_attr->num_ports = cpu_to_be32(port->num_rports); } /* @@ -5806,6 +6009,7 @@ BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/ BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */ + BFA_FCS_VPORT_SM_FABRIC_MAX = 15, /* max vports on fabric */ }; static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, @@ -5991,6 +6195,7 @@ break; case BFA_FCS_VPORT_SM_RSP_FAILED: + case BFA_FCS_VPORT_SM_FABRIC_MAX: bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); break; @@ -6061,6 +6266,7 @@ case BFA_FCS_VPORT_SM_OFFLINE: case BFA_FCS_VPORT_SM_RSP_ERROR: case BFA_FCS_VPORT_SM_RSP_FAILED: + case BFA_FCS_VPORT_SM_FABRIC_MAX: case BFA_FCS_VPORT_SM_RSP_DUP_WWN: bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); @@ -6346,7 +6552,7 @@ else { bfa_fcs_vport_aen_post(&vport->lport, BFA_LPORT_AEN_NPIV_FABRIC_MAX); - bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_FABRIC_MAX); } break; @@ -6732,7 +6938,19 @@ break; } - bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); + if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); + else + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); + + break; + + case BFA_STATUS_ETIMER: + vport->vport_stats.fdisc_timeouts++; + if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); + else + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); break; case BFA_STATUS_FABRIC_RJT: