linux/drivers/scsi/qla2xxx/qla_gs.c
<<
>>
Prefs
   1/*
   2 * QLogic Fibre Channel HBA Driver
   3 * Copyright (c)  2003-2014 QLogic Corporation
   4 *
   5 * See LICENSE.qla2xxx for copyright and licensing details.
   6 */
   7#include "qla_def.h"
   8#include "qla_target.h"
   9#include <linux/utsname.h>
  10
  11static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
  12static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
  13static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
  14static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *);
  15static int qla2x00_sns_rft_id(scsi_qla_host_t *);
  16static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
  17static int qla_async_rftid(scsi_qla_host_t *, port_id_t *);
  18static int qla_async_rffid(scsi_qla_host_t *, port_id_t *, u8, u8);
  19static int qla_async_rnnid(scsi_qla_host_t *, port_id_t *, u8*);
  20static int qla_async_rsnn_nn(scsi_qla_host_t *);
  21
  22/**
  23 * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
  24 * @vha: HA context
  25 * @arg: CT arguments
  26 *
  27 * Returns a pointer to the @vha's ms_iocb.
  28 */
  29void *
  30qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
  31{
  32        struct qla_hw_data *ha = vha->hw;
  33        ms_iocb_entry_t *ms_pkt;
  34
  35        ms_pkt = (ms_iocb_entry_t *)arg->iocb;
  36        memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
  37
  38        ms_pkt->entry_type = MS_IOCB_TYPE;
  39        ms_pkt->entry_count = 1;
  40        SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
  41        ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
  42        ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
  43        ms_pkt->cmd_dsd_count = cpu_to_le16(1);
  44        ms_pkt->total_dsd_count = cpu_to_le16(2);
  45        ms_pkt->rsp_bytecount = cpu_to_le32(arg->rsp_size);
  46        ms_pkt->req_bytecount = cpu_to_le32(arg->req_size);
  47
  48        ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(arg->req_dma));
  49        ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(arg->req_dma));
  50        ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
  51
  52        ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(arg->rsp_dma));
  53        ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(arg->rsp_dma));
  54        ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
  55
  56        vha->qla_stats.control_requests++;
  57
  58        return (ms_pkt);
  59}
  60
  61/**
  62 * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
  63 * @vha: HA context
  64 * @arg: CT arguments
  65 *
  66 * Returns a pointer to the @ha's ms_iocb.
  67 */
  68void *
  69qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
  70{
  71        struct qla_hw_data *ha = vha->hw;
  72        struct ct_entry_24xx *ct_pkt;
  73
  74        ct_pkt = (struct ct_entry_24xx *)arg->iocb;
  75        memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
  76
  77        ct_pkt->entry_type = CT_IOCB_TYPE;
  78        ct_pkt->entry_count = 1;
  79        ct_pkt->nport_handle = cpu_to_le16(arg->nport_handle);
  80        ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
  81        ct_pkt->cmd_dsd_count = cpu_to_le16(1);
  82        ct_pkt->rsp_dsd_count = cpu_to_le16(1);
  83        ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size);
  84        ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size);
  85
  86        ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(arg->req_dma));
  87        ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(arg->req_dma));
  88        ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
  89
  90        ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(arg->rsp_dma));
  91        ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(arg->rsp_dma));
  92        ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
  93        ct_pkt->vp_index = vha->vp_idx;
  94
  95        vha->qla_stats.control_requests++;
  96
  97        return (ct_pkt);
  98}
  99
 100/**
 101 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
 102 * @p: CT request buffer
 103 * @cmd: GS command
 104 * @rsp_size: response size in bytes
 105 *
 106 * Returns a pointer to the intitialized @ct_req.
 107 */
 108static inline struct ct_sns_req *
 109qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size)
 110{
 111        memset(p, 0, sizeof(struct ct_sns_pkt));
 112
 113        p->p.req.header.revision = 0x01;
 114        p->p.req.header.gs_type = 0xFC;
 115        p->p.req.header.gs_subtype = 0x02;
 116        p->p.req.command = cpu_to_be16(cmd);
 117        p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
 118
 119        return &p->p.req;
 120}
 121
 122int
 123qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt,
 124    struct ct_sns_rsp *ct_rsp, const char *routine)
 125{
 126        int rval;
 127        uint16_t comp_status;
 128        struct qla_hw_data *ha = vha->hw;
 129        bool lid_is_sns = false;
 130
 131        rval = QLA_FUNCTION_FAILED;
 132        if (ms_pkt->entry_status != 0) {
 133                ql_dbg(ql_dbg_disc, vha, 0x2031,
 134                    "%s failed, error status (%x) on port_id: %02x%02x%02x.\n",
 135                    routine, ms_pkt->entry_status, vha->d_id.b.domain,
 136                    vha->d_id.b.area, vha->d_id.b.al_pa);
 137        } else {
 138                if (IS_FWI2_CAPABLE(ha))
 139                        comp_status = le16_to_cpu(
 140                            ((struct ct_entry_24xx *)ms_pkt)->comp_status);
 141                else
 142                        comp_status = le16_to_cpu(ms_pkt->status);
 143                switch (comp_status) {
 144                case CS_COMPLETE:
 145                case CS_DATA_UNDERRUN:
 146                case CS_DATA_OVERRUN:           /* Overrun? */
 147                        if (ct_rsp->header.response !=
 148                            cpu_to_be16(CT_ACCEPT_RESPONSE)) {
 149                                ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077,
 150                                    "%s failed rejected request on port_id: %02x%02x%02x Completion status 0x%x, response 0x%x\n",
 151                                    routine, vha->d_id.b.domain,
 152                                    vha->d_id.b.area, vha->d_id.b.al_pa,
 153                                    comp_status, ct_rsp->header.response);
 154                                ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha,
 155                                    0x2078, ct_rsp,
 156                                    offsetof(typeof(*ct_rsp), rsp));
 157                                rval = QLA_INVALID_COMMAND;
 158                        } else
 159                                rval = QLA_SUCCESS;
 160                        break;
 161                case CS_PORT_LOGGED_OUT:
 162                        if (IS_FWI2_CAPABLE(ha)) {
 163                                if (le16_to_cpu(ms_pkt->loop_id.extended) ==
 164                                    NPH_SNS)
 165                                        lid_is_sns = true;
 166                        } else {
 167                                if (le16_to_cpu(ms_pkt->loop_id.extended) ==
 168                                    SIMPLE_NAME_SERVER)
 169                                        lid_is_sns = true;
 170                        }
 171                        if (lid_is_sns) {
 172                                ql_dbg(ql_dbg_async, vha, 0x502b,
 173                                        "%s failed, Name server has logged out",
 174                                        routine);
 175                                rval = QLA_NOT_LOGGED_IN;
 176                                set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
 177                                set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
 178                        }
 179                        break;
 180                case CS_TIMEOUT:
 181                        rval = QLA_FUNCTION_TIMEOUT;
 182                        /* fall through */
 183                default:
 184                        ql_dbg(ql_dbg_disc, vha, 0x2033,
 185                            "%s failed, completion status (%x) on port_id: "
 186                            "%02x%02x%02x.\n", routine, comp_status,
 187                            vha->d_id.b.domain, vha->d_id.b.area,
 188                            vha->d_id.b.al_pa);
 189                        break;
 190                }
 191        }
 192        return rval;
 193}
 194
 195/**
 196 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
 197 * @vha: HA context
 198 * @fcport: fcport entry to updated
 199 *
 200 * Returns 0 on success.
 201 */
 202int
 203qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
 204{
 205        int             rval;
 206
 207        ms_iocb_entry_t *ms_pkt;
 208        struct ct_sns_req       *ct_req;
 209        struct ct_sns_rsp       *ct_rsp;
 210        struct qla_hw_data *ha = vha->hw;
 211        struct ct_arg arg;
 212
 213        if (IS_QLA2100(ha) || IS_QLA2200(ha))
 214                return qla2x00_sns_ga_nxt(vha, fcport);
 215
 216        arg.iocb = ha->ms_iocb;
 217        arg.req_dma = ha->ct_sns_dma;
 218        arg.rsp_dma = ha->ct_sns_dma;
 219        arg.req_size = GA_NXT_REQ_SIZE;
 220        arg.rsp_size = GA_NXT_RSP_SIZE;
 221        arg.nport_handle = NPH_SNS;
 222
 223        /* Issue GA_NXT */
 224        /* Prepare common MS IOCB */
 225        ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
 226
 227        /* Prepare CT request */
 228        ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD,
 229            GA_NXT_RSP_SIZE);
 230        ct_rsp = &ha->ct_sns->p.rsp;
 231
 232        /* Prepare CT arguments -- port_id */
 233        ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
 234        ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
 235        ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
 236
 237        /* Execute MS IOCB */
 238        rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
 239            sizeof(ms_iocb_entry_t));
 240        if (rval != QLA_SUCCESS) {
 241                /*EMPTY*/
 242                ql_dbg(ql_dbg_disc, vha, 0x2062,
 243                    "GA_NXT issue IOCB failed (%d).\n", rval);
 244        } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") !=
 245            QLA_SUCCESS) {
 246                rval = QLA_FUNCTION_FAILED;
 247        } else {
 248                /* Populate fc_port_t entry. */
 249                fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0];
 250                fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1];
 251                fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2];
 252
 253                memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name,
 254                    WWN_SIZE);
 255                memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name,
 256                    WWN_SIZE);
 257
 258                fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ?
 259                    FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER;
 260
 261                if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
 262                    ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
 263                        fcport->d_id.b.domain = 0xf0;
 264
 265                ql_dbg(ql_dbg_disc, vha, 0x2063,
 266                    "GA_NXT entry - nn %8phN pn %8phN "
 267                    "port_id=%02x%02x%02x.\n",
 268                    fcport->node_name, fcport->port_name,
 269                    fcport->d_id.b.domain, fcport->d_id.b.area,
 270                    fcport->d_id.b.al_pa);
 271        }
 272
 273        return (rval);
 274}
 275
 276static inline int
 277qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha)
 278{
 279        return vha->hw->max_fibre_devices * 4 + 16;
 280}
 281
 282/**
 283 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
 284 * @vha: HA context
 285 * @list: switch info entries to populate
 286 *
 287 * NOTE: Non-Nx_Ports are not requested.
 288 *
 289 * Returns 0 on success.
 290 */
 291int
 292qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
 293{
 294        int             rval;
 295        uint16_t        i;
 296
 297        ms_iocb_entry_t *ms_pkt;
 298        struct ct_sns_req       *ct_req;
 299        struct ct_sns_rsp       *ct_rsp;
 300
 301        struct ct_sns_gid_pt_data *gid_data;
 302        struct qla_hw_data *ha = vha->hw;
 303        uint16_t gid_pt_rsp_size;
 304        struct ct_arg arg;
 305
 306        if (IS_QLA2100(ha) || IS_QLA2200(ha))
 307                return qla2x00_sns_gid_pt(vha, list);
 308
 309        gid_data = NULL;
 310        gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha);
 311
 312        arg.iocb = ha->ms_iocb;
 313        arg.req_dma = ha->ct_sns_dma;
 314        arg.rsp_dma = ha->ct_sns_dma;
 315        arg.req_size = GID_PT_REQ_SIZE;
 316        arg.rsp_size = gid_pt_rsp_size;
 317        arg.nport_handle = NPH_SNS;
 318
 319        /* Issue GID_PT */
 320        /* Prepare common MS IOCB */
 321        ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
 322
 323        /* Prepare CT request */
 324        ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size);
 325        ct_rsp = &ha->ct_sns->p.rsp;
 326
 327        /* Prepare CT arguments -- port_type */
 328        ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE;
 329
 330        /* Execute MS IOCB */
 331        rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
 332            sizeof(ms_iocb_entry_t));
 333        if (rval != QLA_SUCCESS) {
 334                /*EMPTY*/
 335                ql_dbg(ql_dbg_disc, vha, 0x2055,
 336                    "GID_PT issue IOCB failed (%d).\n", rval);
 337        } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") !=
 338            QLA_SUCCESS) {
 339                rval = QLA_FUNCTION_FAILED;
 340        } else {
 341                /* Set port IDs in switch info list. */
 342                for (i = 0; i < ha->max_fibre_devices; i++) {
 343                        gid_data = &ct_rsp->rsp.gid_pt.entries[i];
 344                        list[i].d_id.b.domain = gid_data->port_id[0];
 345                        list[i].d_id.b.area = gid_data->port_id[1];
 346                        list[i].d_id.b.al_pa = gid_data->port_id[2];
 347                        memset(list[i].fabric_port_name, 0, WWN_SIZE);
 348                        list[i].fp_speed = PORT_SPEED_UNKNOWN;
 349
 350                        /* Last one exit. */
 351                        if (gid_data->control_byte & BIT_7) {
 352                                list[i].d_id.b.rsvd_1 = gid_data->control_byte;
 353                                break;
 354                        }
 355                }
 356
 357                /*
 358                 * If we've used all available slots, then the switch is
 359                 * reporting back more devices than we can handle with this
 360                 * single call.  Return a failed status, and let GA_NXT handle
 361                 * the overload.
 362                 */
 363                if (i == ha->max_fibre_devices)
 364                        rval = QLA_FUNCTION_FAILED;
 365        }
 366
 367        return (rval);
 368}
 369
 370/**
 371 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
 372 * @vha: HA context
 373 * @list: switch info entries to populate
 374 *
 375 * Returns 0 on success.
 376 */
 377int
 378qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 379{
 380        int             rval = QLA_SUCCESS;
 381        uint16_t        i;
 382
 383        ms_iocb_entry_t *ms_pkt;
 384        struct ct_sns_req       *ct_req;
 385        struct ct_sns_rsp       *ct_rsp;
 386        struct qla_hw_data *ha = vha->hw;
 387        struct ct_arg arg;
 388
 389        if (IS_QLA2100(ha) || IS_QLA2200(ha))
 390                return qla2x00_sns_gpn_id(vha, list);
 391
 392        arg.iocb = ha->ms_iocb;
 393        arg.req_dma = ha->ct_sns_dma;
 394        arg.rsp_dma = ha->ct_sns_dma;
 395        arg.req_size = GPN_ID_REQ_SIZE;
 396        arg.rsp_size = GPN_ID_RSP_SIZE;
 397        arg.nport_handle = NPH_SNS;
 398
 399        for (i = 0; i < ha->max_fibre_devices; i++) {
 400                /* Issue GPN_ID */
 401                /* Prepare common MS IOCB */
 402                ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
 403
 404                /* Prepare CT request */
 405                ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD,
 406                    GPN_ID_RSP_SIZE);
 407                ct_rsp = &ha->ct_sns->p.rsp;
 408
 409                /* Prepare CT arguments -- port_id */
 410                ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
 411                ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
 412                ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
 413
 414                /* Execute MS IOCB */
 415                rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
 416                    sizeof(ms_iocb_entry_t));
 417                if (rval != QLA_SUCCESS) {
 418                        /*EMPTY*/
 419                        ql_dbg(ql_dbg_disc, vha, 0x2056,
 420                            "GPN_ID issue IOCB failed (%d).\n", rval);
 421                        break;
 422                } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
 423                    "GPN_ID") != QLA_SUCCESS) {
 424                        rval = QLA_FUNCTION_FAILED;
 425                        break;
 426                } else {
 427                        /* Save portname */
 428                        memcpy(list[i].port_name,
 429                            ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
 430                }
 431
 432                /* Last device exit. */
 433                if (list[i].d_id.b.rsvd_1 != 0)
 434                        break;
 435        }
 436
 437        return (rval);
 438}
 439
 440/**
 441 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
 442 * @vha: HA context
 443 * @list: switch info entries to populate
 444 *
 445 * Returns 0 on success.
 446 */
 447int
 448qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
 449{
 450        int             rval = QLA_SUCCESS;
 451        uint16_t        i;
 452        struct qla_hw_data *ha = vha->hw;
 453        ms_iocb_entry_t *ms_pkt;
 454        struct ct_sns_req       *ct_req;
 455        struct ct_sns_rsp       *ct_rsp;
 456        struct ct_arg arg;
 457
 458        if (IS_QLA2100(ha) || IS_QLA2200(ha))
 459                return qla2x00_sns_gnn_id(vha, list);
 460
 461        arg.iocb = ha->ms_iocb;
 462        arg.req_dma = ha->ct_sns_dma;
 463        arg.rsp_dma = ha->ct_sns_dma;
 464        arg.req_size = GNN_ID_REQ_SIZE;
 465        arg.rsp_size = GNN_ID_RSP_SIZE;
 466        arg.nport_handle = NPH_SNS;
 467
 468        for (i = 0; i < ha->max_fibre_devices; i++) {
 469                /* Issue GNN_ID */
 470                /* Prepare common MS IOCB */
 471                ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
 472
 473                /* Prepare CT request */
 474                ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD,
 475                    GNN_ID_RSP_SIZE);
 476                ct_rsp = &ha->ct_sns->p.rsp;
 477
 478                /* Prepare CT arguments -- port_id */
 479                ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
 480                ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
 481                ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
 482
 483                /* Execute MS IOCB */
 484                rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
 485                    sizeof(ms_iocb_entry_t));
 486                if (rval != QLA_SUCCESS) {
 487                        /*EMPTY*/
 488                        ql_dbg(ql_dbg_disc, vha, 0x2057,
 489                            "GNN_ID issue IOCB failed (%d).\n", rval);
 490                        break;
 491                } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
 492                    "GNN_ID") != QLA_SUCCESS) {
 493                        rval = QLA_FUNCTION_FAILED;
 494                        break;
 495                } else {
 496                        /* Save nodename */
 497                        memcpy(list[i].node_name,
 498                            ct_rsp->rsp.gnn_id.node_name, WWN_SIZE);
 499
 500                        ql_dbg(ql_dbg_disc, vha, 0x2058,
 501                            "GID_PT entry - nn %8phN pn %8phN "
 502                            "portid=%02x%02x%02x.\n",
 503                            list[i].node_name, list[i].port_name,
 504                            list[i].d_id.b.domain, list[i].d_id.b.area,
 505                            list[i].d_id.b.al_pa);
 506                }
 507
 508                /* Last device exit. */
 509                if (list[i].d_id.b.rsvd_1 != 0)
 510                        break;
 511        }
 512
 513        return (rval);
 514}
 515
 516static void qla2x00_async_sns_sp_done(void *s, int rc)
 517{
 518        struct srb *sp = s;
 519        struct scsi_qla_host *vha = sp->vha;
 520        struct ct_sns_pkt *ct_sns;
 521        struct qla_work_evt *e;
 522
 523        sp->rc = rc;
 524        if (rc == QLA_SUCCESS) {
 525                ql_dbg(ql_dbg_disc, vha, 0x204f,
 526                    "Async done-%s exiting normally.\n",
 527                    sp->name);
 528        } else if (rc == QLA_FUNCTION_TIMEOUT) {
 529                ql_dbg(ql_dbg_disc, vha, 0x204f,
 530                    "Async done-%s timeout\n", sp->name);
 531        } else {
 532                ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
 533                memset(ct_sns, 0, sizeof(*ct_sns));
 534                sp->retry_count++;
 535                if (sp->retry_count > 3)
 536                        goto err;
 537
 538                ql_dbg(ql_dbg_disc, vha, 0x204f,
 539                    "Async done-%s fail rc %x.  Retry count %d\n",
 540                    sp->name, rc, sp->retry_count);
 541
 542                e = qla2x00_alloc_work(vha, QLA_EVT_SP_RETRY);
 543                if (!e)
 544                        goto err2;
 545
 546                del_timer(&sp->u.iocb_cmd.timer);
 547                e->u.iosb.sp = sp;
 548                qla2x00_post_work(vha, e);
 549                return;
 550        }
 551
 552err:
 553        e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
 554err2:
 555        if (!e) {
 556                /* please ignore kernel warning. otherwise, we have mem leak. */
 557                if (sp->u.iocb_cmd.u.ctarg.req) {
 558                        dma_free_coherent(&vha->hw->pdev->dev,
 559                            sp->u.iocb_cmd.u.ctarg.req_allocated_size,
 560                            sp->u.iocb_cmd.u.ctarg.req,
 561                            sp->u.iocb_cmd.u.ctarg.req_dma);
 562                        sp->u.iocb_cmd.u.ctarg.req = NULL;
 563                }
 564
 565                if (sp->u.iocb_cmd.u.ctarg.rsp) {
 566                        dma_free_coherent(&vha->hw->pdev->dev,
 567                            sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
 568                            sp->u.iocb_cmd.u.ctarg.rsp,
 569                            sp->u.iocb_cmd.u.ctarg.rsp_dma);
 570                        sp->u.iocb_cmd.u.ctarg.rsp = NULL;
 571                }
 572
 573                sp->free(sp);
 574
 575                return;
 576        }
 577
 578        e->u.iosb.sp = sp;
 579        qla2x00_post_work(vha, e);
 580}
 581
 582/**
 583 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
 584 * @vha: HA context
 585 *
 586 * Returns 0 on success.
 587 */
 588int
 589qla2x00_rft_id(scsi_qla_host_t *vha)
 590{
 591        struct qla_hw_data *ha = vha->hw;
 592
 593        if (IS_QLA2100(ha) || IS_QLA2200(ha))
 594                return qla2x00_sns_rft_id(vha);
 595
 596        return qla_async_rftid(vha, &vha->d_id);
 597}
 598
 599static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id)
 600{
 601        int rval = QLA_MEMORY_ALLOC_FAILED;
 602        struct ct_sns_req *ct_req;
 603        srb_t *sp;
 604        struct ct_sns_pkt *ct_sns;
 605
 606        if (!vha->flags.online)
 607                goto done;
 608
 609        sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
 610        if (!sp)
 611                goto done;
 612
 613        sp->type = SRB_CT_PTHRU_CMD;
 614        sp->name = "rft_id";
 615        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 616
 617        sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
 618            sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
 619            GFP_KERNEL);
 620        sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
 621        if (!sp->u.iocb_cmd.u.ctarg.req) {
 622                ql_log(ql_log_warn, vha, 0xd041,
 623                    "%s: Failed to allocate ct_sns request.\n",
 624                    __func__);
 625                goto done_free_sp;
 626        }
 627
 628        sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
 629            sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
 630            GFP_KERNEL);
 631        sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
 632        if (!sp->u.iocb_cmd.u.ctarg.rsp) {
 633                ql_log(ql_log_warn, vha, 0xd042,
 634                    "%s: Failed to allocate ct_sns request.\n",
 635                    __func__);
 636                goto done_free_sp;
 637        }
 638        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
 639        memset(ct_sns, 0, sizeof(*ct_sns));
 640        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
 641
 642        /* Prepare CT request */
 643        ct_req = qla2x00_prep_ct_req(ct_sns, RFT_ID_CMD, RFT_ID_RSP_SIZE);
 644
 645        /* Prepare CT arguments -- port_id, FC-4 types */
 646        ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain;
 647        ct_req->req.rft_id.port_id[1] = vha->d_id.b.area;
 648        ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa;
 649        ct_req->req.rft_id.fc4_types[2] = 0x01;         /* FCP-3 */
 650
 651        if (vha->flags.nvme_enabled)
 652                ct_req->req.rft_id.fc4_types[6] = 1;    /* NVMe type 28h */
 653
 654        sp->u.iocb_cmd.u.ctarg.req_size = RFT_ID_REQ_SIZE;
 655        sp->u.iocb_cmd.u.ctarg.rsp_size = RFT_ID_RSP_SIZE;
 656        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
 657        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
 658        sp->done = qla2x00_async_sns_sp_done;
 659
 660        ql_dbg(ql_dbg_disc, vha, 0xffff,
 661            "Async-%s - hdl=%x portid %06x.\n",
 662            sp->name, sp->handle, d_id->b24);
 663
 664        rval = qla2x00_start_sp(sp);
 665        if (rval != QLA_SUCCESS) {
 666                ql_dbg(ql_dbg_disc, vha, 0x2043,
 667                    "RFT_ID issue IOCB failed (%d).\n", rval);
 668                goto done_free_sp;
 669        }
 670        return rval;
 671done_free_sp:
 672        sp->free(sp);
 673done:
 674        return rval;
 675}
 676
 677/**
 678 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
 679 * @vha: HA context
 680 * @type: not used
 681 *
 682 * Returns 0 on success.
 683 */
 684int
 685qla2x00_rff_id(scsi_qla_host_t *vha, u8 type)
 686{
 687        struct qla_hw_data *ha = vha->hw;
 688
 689        if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
 690                ql_dbg(ql_dbg_disc, vha, 0x2046,
 691                    "RFF_ID call not supported on ISP2100/ISP2200.\n");
 692                return (QLA_SUCCESS);
 693        }
 694
 695        return qla_async_rffid(vha, &vha->d_id, qlt_rff_id(vha),
 696            FC4_TYPE_FCP_SCSI);
 697}
 698
 699static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id,
 700    u8 fc4feature, u8 fc4type)
 701{
 702        int rval = QLA_MEMORY_ALLOC_FAILED;
 703        struct ct_sns_req *ct_req;
 704        srb_t *sp;
 705        struct ct_sns_pkt *ct_sns;
 706
 707        sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
 708        if (!sp)
 709                goto done;
 710
 711        sp->type = SRB_CT_PTHRU_CMD;
 712        sp->name = "rff_id";
 713        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 714
 715        sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
 716            sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
 717            GFP_KERNEL);
 718        sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
 719        if (!sp->u.iocb_cmd.u.ctarg.req) {
 720                ql_log(ql_log_warn, vha, 0xd041,
 721                    "%s: Failed to allocate ct_sns request.\n",
 722                    __func__);
 723                goto done_free_sp;
 724        }
 725
 726        sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
 727            sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
 728            GFP_KERNEL);
 729        sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
 730        if (!sp->u.iocb_cmd.u.ctarg.rsp) {
 731                ql_log(ql_log_warn, vha, 0xd042,
 732                    "%s: Failed to allocate ct_sns request.\n",
 733                    __func__);
 734                goto done_free_sp;
 735        }
 736        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
 737        memset(ct_sns, 0, sizeof(*ct_sns));
 738        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
 739
 740        /* Prepare CT request */
 741        ct_req = qla2x00_prep_ct_req(ct_sns, RFF_ID_CMD, RFF_ID_RSP_SIZE);
 742
 743        /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
 744        ct_req->req.rff_id.port_id[0] = d_id->b.domain;
 745        ct_req->req.rff_id.port_id[1] = d_id->b.area;
 746        ct_req->req.rff_id.port_id[2] = d_id->b.al_pa;
 747        ct_req->req.rff_id.fc4_feature = fc4feature;
 748        ct_req->req.rff_id.fc4_type = fc4type;          /* SCSI - FCP */
 749
 750        sp->u.iocb_cmd.u.ctarg.req_size = RFF_ID_REQ_SIZE;
 751        sp->u.iocb_cmd.u.ctarg.rsp_size = RFF_ID_RSP_SIZE;
 752        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
 753        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
 754        sp->done = qla2x00_async_sns_sp_done;
 755
 756        ql_dbg(ql_dbg_disc, vha, 0xffff,
 757            "Async-%s - hdl=%x portid %06x feature %x type %x.\n",
 758            sp->name, sp->handle, d_id->b24, fc4feature, fc4type);
 759
 760        rval = qla2x00_start_sp(sp);
 761        if (rval != QLA_SUCCESS) {
 762                ql_dbg(ql_dbg_disc, vha, 0x2047,
 763                    "RFF_ID issue IOCB failed (%d).\n", rval);
 764                goto done_free_sp;
 765        }
 766
 767        return rval;
 768
 769done_free_sp:
 770        sp->free(sp);
 771done:
 772        return rval;
 773}
 774
 775/**
 776 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
 777 * @vha: HA context
 778 *
 779 * Returns 0 on success.
 780 */
 781int
 782qla2x00_rnn_id(scsi_qla_host_t *vha)
 783{
 784        struct qla_hw_data *ha = vha->hw;
 785
 786        if (IS_QLA2100(ha) || IS_QLA2200(ha))
 787                return qla2x00_sns_rnn_id(vha);
 788
 789        return  qla_async_rnnid(vha, &vha->d_id, vha->node_name);
 790}
 791
 792static int qla_async_rnnid(scsi_qla_host_t *vha, port_id_t *d_id,
 793        u8 *node_name)
 794{
 795        int rval = QLA_MEMORY_ALLOC_FAILED;
 796        struct ct_sns_req *ct_req;
 797        srb_t *sp;
 798        struct ct_sns_pkt *ct_sns;
 799
 800        sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
 801        if (!sp)
 802                goto done;
 803
 804        sp->type = SRB_CT_PTHRU_CMD;
 805        sp->name = "rnid";
 806        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 807
 808        sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
 809            sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
 810            GFP_KERNEL);
 811        sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
 812        if (!sp->u.iocb_cmd.u.ctarg.req) {
 813                ql_log(ql_log_warn, vha, 0xd041,
 814                    "%s: Failed to allocate ct_sns request.\n",
 815                    __func__);
 816                goto done_free_sp;
 817        }
 818
 819        sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
 820            sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
 821            GFP_KERNEL);
 822        sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
 823        if (!sp->u.iocb_cmd.u.ctarg.rsp) {
 824                ql_log(ql_log_warn, vha, 0xd042,
 825                    "%s: Failed to allocate ct_sns request.\n",
 826                    __func__);
 827                goto done_free_sp;
 828        }
 829        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
 830        memset(ct_sns, 0, sizeof(*ct_sns));
 831        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
 832
 833        /* Prepare CT request */
 834        ct_req = qla2x00_prep_ct_req(ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE);
 835
 836        /* Prepare CT arguments -- port_id, node_name */
 837        ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain;
 838        ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area;
 839        ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa;
 840        memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE);
 841
 842        sp->u.iocb_cmd.u.ctarg.req_size = RNN_ID_REQ_SIZE;
 843        sp->u.iocb_cmd.u.ctarg.rsp_size = RNN_ID_RSP_SIZE;
 844        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
 845
 846        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
 847        sp->done = qla2x00_async_sns_sp_done;
 848
 849        ql_dbg(ql_dbg_disc, vha, 0xffff,
 850            "Async-%s - hdl=%x portid %06x\n",
 851            sp->name, sp->handle, d_id->b24);
 852
 853        rval = qla2x00_start_sp(sp);
 854        if (rval != QLA_SUCCESS) {
 855                ql_dbg(ql_dbg_disc, vha, 0x204d,
 856                    "RNN_ID issue IOCB failed (%d).\n", rval);
 857                goto done_free_sp;
 858        }
 859
 860        return rval;
 861
 862done_free_sp:
 863        sp->free(sp);
 864done:
 865        return rval;
 866}
 867
 868void
 869qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn, size_t size)
 870{
 871        struct qla_hw_data *ha = vha->hw;
 872
 873        if (IS_QLAFX00(ha))
 874                snprintf(snn, size, "%s FW:v%s DVR:v%s", ha->model_number,
 875                    ha->mr.fw_version, qla2x00_version_str);
 876        else
 877                snprintf(snn, size,
 878                    "%s FW:v%d.%02d.%02d DVR:v%s", ha->model_number,
 879                    ha->fw_major_version, ha->fw_minor_version,
 880                    ha->fw_subminor_version, qla2x00_version_str);
 881}
 882
 883/**
 884 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
 885 * @vha: HA context
 886 *
 887 * Returns 0 on success.
 888 */
 889int
 890qla2x00_rsnn_nn(scsi_qla_host_t *vha)
 891{
 892        struct qla_hw_data *ha = vha->hw;
 893
 894        if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
 895                ql_dbg(ql_dbg_disc, vha, 0x2050,
 896                    "RSNN_ID call unsupported on ISP2100/ISP2200.\n");
 897                return (QLA_SUCCESS);
 898        }
 899
 900        return qla_async_rsnn_nn(vha);
 901}
 902
 903static int qla_async_rsnn_nn(scsi_qla_host_t *vha)
 904{
 905        int rval = QLA_MEMORY_ALLOC_FAILED;
 906        struct ct_sns_req *ct_req;
 907        srb_t *sp;
 908        struct ct_sns_pkt *ct_sns;
 909
 910        sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
 911        if (!sp)
 912                goto done;
 913
 914        sp->type = SRB_CT_PTHRU_CMD;
 915        sp->name = "rsnn_nn";
 916        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 917
 918        sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
 919            sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
 920            GFP_KERNEL);
 921        sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
 922        if (!sp->u.iocb_cmd.u.ctarg.req) {
 923                ql_log(ql_log_warn, vha, 0xd041,
 924                    "%s: Failed to allocate ct_sns request.\n",
 925                    __func__);
 926                goto done_free_sp;
 927        }
 928
 929        sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
 930            sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
 931            GFP_KERNEL);
 932        sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
 933        if (!sp->u.iocb_cmd.u.ctarg.rsp) {
 934                ql_log(ql_log_warn, vha, 0xd042,
 935                    "%s: Failed to allocate ct_sns request.\n",
 936                    __func__);
 937                goto done_free_sp;
 938        }
 939        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
 940        memset(ct_sns, 0, sizeof(*ct_sns));
 941        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
 942
 943        /* Prepare CT request */
 944        ct_req = qla2x00_prep_ct_req(ct_sns, RSNN_NN_CMD, RSNN_NN_RSP_SIZE);
 945
 946        /* Prepare CT arguments -- node_name, symbolic node_name, size */
 947        memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE);
 948
 949        /* Prepare the Symbolic Node Name */
 950        qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name,
 951            sizeof(ct_req->req.rsnn_nn.sym_node_name));
 952        ct_req->req.rsnn_nn.name_len =
 953            (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
 954
 955
 956        sp->u.iocb_cmd.u.ctarg.req_size = 24 + 1 + ct_req->req.rsnn_nn.name_len;
 957        sp->u.iocb_cmd.u.ctarg.rsp_size = RSNN_NN_RSP_SIZE;
 958        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
 959
 960        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
 961        sp->done = qla2x00_async_sns_sp_done;
 962
 963        ql_dbg(ql_dbg_disc, vha, 0xffff,
 964            "Async-%s - hdl=%x.\n",
 965            sp->name, sp->handle);
 966
 967        rval = qla2x00_start_sp(sp);
 968        if (rval != QLA_SUCCESS) {
 969                ql_dbg(ql_dbg_disc, vha, 0x2043,
 970                    "RFT_ID issue IOCB failed (%d).\n", rval);
 971                goto done_free_sp;
 972        }
 973
 974        return rval;
 975
 976done_free_sp:
 977        sp->free(sp);
 978done:
 979        return rval;
 980}
 981
 982/**
 983 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
 984 * @vha: HA context
 985 * @cmd: GS command
 986 * @scmd_len: Subcommand length
 987 * @data_size: response size in bytes
 988 *
 989 * Returns a pointer to the @ha's sns_cmd.
 990 */
 991static inline struct sns_cmd_pkt *
 992qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
 993    uint16_t data_size)
 994{
 995        uint16_t                wc;
 996        struct sns_cmd_pkt      *sns_cmd;
 997        struct qla_hw_data *ha = vha->hw;
 998
 999        sns_cmd = ha->sns_cmd;
1000        memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt));
1001        wc = data_size / 2;                     /* Size in 16bit words. */
1002        sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc);
1003        sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma));
1004        sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma));
1005        sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len);
1006        sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd);
1007        wc = (data_size - 16) / 4;              /* Size in 32bit words. */
1008        sns_cmd->p.cmd.size = cpu_to_le16(wc);
1009
1010        vha->qla_stats.control_requests++;
1011
1012        return (sns_cmd);
1013}
1014
1015/**
1016 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
1017 * @vha: HA context
1018 * @fcport: fcport entry to updated
1019 *
1020 * This command uses the old Exectute SNS Command mailbox routine.
1021 *
1022 * Returns 0 on success.
1023 */
1024static int
1025qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
1026{
1027        int             rval = QLA_SUCCESS;
1028        struct qla_hw_data *ha = vha->hw;
1029        struct sns_cmd_pkt      *sns_cmd;
1030
1031        /* Issue GA_NXT. */
1032        /* Prepare SNS command request. */
1033        sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN,
1034            GA_NXT_SNS_DATA_SIZE);
1035
1036        /* Prepare SNS command arguments -- port_id. */
1037        sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa;
1038        sns_cmd->p.cmd.param[1] = fcport->d_id.b.area;
1039        sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain;
1040
1041        /* Execute SNS command. */
1042        rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2,
1043            sizeof(struct sns_cmd_pkt));
1044        if (rval != QLA_SUCCESS) {
1045                /*EMPTY*/
1046                ql_dbg(ql_dbg_disc, vha, 0x205f,
1047                    "GA_NXT Send SNS failed (%d).\n", rval);
1048        } else if (sns_cmd->p.gan_data[8] != 0x80 ||
1049            sns_cmd->p.gan_data[9] != 0x02) {
1050                ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084,
1051                    "GA_NXT failed, rejected request ga_nxt_rsp:\n");
1052                ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074,
1053                    sns_cmd->p.gan_data, 16);
1054                rval = QLA_FUNCTION_FAILED;
1055        } else {
1056                /* Populate fc_port_t entry. */
1057                fcport->d_id.b.domain = sns_cmd->p.gan_data[17];
1058                fcport->d_id.b.area = sns_cmd->p.gan_data[18];
1059                fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19];
1060
1061                memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE);
1062                memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE);
1063
1064                if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE &&
1065                    sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE)
1066                        fcport->d_id.b.domain = 0xf0;
1067
1068                ql_dbg(ql_dbg_disc, vha, 0x2061,
1069                    "GA_NXT entry - nn %8phN pn %8phN "
1070                    "port_id=%02x%02x%02x.\n",
1071                    fcport->node_name, fcport->port_name,
1072                    fcport->d_id.b.domain, fcport->d_id.b.area,
1073                    fcport->d_id.b.al_pa);
1074        }
1075
1076        return (rval);
1077}
1078
1079/**
1080 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
1081 * @vha: HA context
1082 * @list: switch info entries to populate
1083 *
1084 * This command uses the old Exectute SNS Command mailbox routine.
1085 *
1086 * NOTE: Non-Nx_Ports are not requested.
1087 *
1088 * Returns 0 on success.
1089 */
1090static int
1091qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
1092{
1093        int             rval;
1094        struct qla_hw_data *ha = vha->hw;
1095        uint16_t        i;
1096        uint8_t         *entry;
1097        struct sns_cmd_pkt      *sns_cmd;
1098        uint16_t gid_pt_sns_data_size;
1099
1100        gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha);
1101
1102        /* Issue GID_PT. */
1103        /* Prepare SNS command request. */
1104        sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN,
1105            gid_pt_sns_data_size);
1106
1107        /* Prepare SNS command arguments -- port_type. */
1108        sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE;
1109
1110        /* Execute SNS command. */
1111        rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2,
1112            sizeof(struct sns_cmd_pkt));
1113        if (rval != QLA_SUCCESS) {
1114                /*EMPTY*/
1115                ql_dbg(ql_dbg_disc, vha, 0x206d,
1116                    "GID_PT Send SNS failed (%d).\n", rval);
1117        } else if (sns_cmd->p.gid_data[8] != 0x80 ||
1118            sns_cmd->p.gid_data[9] != 0x02) {
1119                ql_dbg(ql_dbg_disc, vha, 0x202f,
1120                    "GID_PT failed, rejected request, gid_rsp:\n");
1121                ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081,
1122                    sns_cmd->p.gid_data, 16);
1123                rval = QLA_FUNCTION_FAILED;
1124        } else {
1125                /* Set port IDs in switch info list. */
1126                for (i = 0; i < ha->max_fibre_devices; i++) {
1127                        entry = &sns_cmd->p.gid_data[(i * 4) + 16];
1128                        list[i].d_id.b.domain = entry[1];
1129                        list[i].d_id.b.area = entry[2];
1130                        list[i].d_id.b.al_pa = entry[3];
1131
1132                        /* Last one exit. */
1133                        if (entry[0] & BIT_7) {
1134                                list[i].d_id.b.rsvd_1 = entry[0];
1135                                break;
1136                        }
1137                }
1138
1139                /*
1140                 * If we've used all available slots, then the switch is
1141                 * reporting back more devices that we can handle with this
1142                 * single call.  Return a failed status, and let GA_NXT handle
1143                 * the overload.
1144                 */
1145                if (i == ha->max_fibre_devices)
1146                        rval = QLA_FUNCTION_FAILED;
1147        }
1148
1149        return (rval);
1150}
1151
1152/**
1153 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
1154 * @vha: HA context
1155 * @list: switch info entries to populate
1156 *
1157 * This command uses the old Exectute SNS Command mailbox routine.
1158 *
1159 * Returns 0 on success.
1160 */
1161static int
1162qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
1163{
1164        int             rval = QLA_SUCCESS;
1165        struct qla_hw_data *ha = vha->hw;
1166        uint16_t        i;
1167        struct sns_cmd_pkt      *sns_cmd;
1168
1169        for (i = 0; i < ha->max_fibre_devices; i++) {
1170                /* Issue GPN_ID */
1171                /* Prepare SNS command request. */
1172                sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD,
1173                    GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE);
1174
1175                /* Prepare SNS command arguments -- port_id. */
1176                sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
1177                sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
1178                sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
1179
1180                /* Execute SNS command. */
1181                rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
1182                    GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
1183                if (rval != QLA_SUCCESS) {
1184                        /*EMPTY*/
1185                        ql_dbg(ql_dbg_disc, vha, 0x2032,
1186                            "GPN_ID Send SNS failed (%d).\n", rval);
1187                } else if (sns_cmd->p.gpn_data[8] != 0x80 ||
1188                    sns_cmd->p.gpn_data[9] != 0x02) {
1189                        ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e,
1190                            "GPN_ID failed, rejected request, gpn_rsp:\n");
1191                        ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207f,
1192                            sns_cmd->p.gpn_data, 16);
1193                        rval = QLA_FUNCTION_FAILED;
1194                } else {
1195                        /* Save portname */
1196                        memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16],
1197                            WWN_SIZE);
1198                }
1199
1200                /* Last device exit. */
1201                if (list[i].d_id.b.rsvd_1 != 0)
1202                        break;
1203        }
1204
1205        return (rval);
1206}
1207
1208/**
1209 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
1210 * @vha: HA context
1211 * @list: switch info entries to populate
1212 *
1213 * This command uses the old Exectute SNS Command mailbox routine.
1214 *
1215 * Returns 0 on success.
1216 */
1217static int
1218qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
1219{
1220        int             rval = QLA_SUCCESS;
1221        struct qla_hw_data *ha = vha->hw;
1222        uint16_t        i;
1223        struct sns_cmd_pkt      *sns_cmd;
1224
1225        for (i = 0; i < ha->max_fibre_devices; i++) {
1226                /* Issue GNN_ID */
1227                /* Prepare SNS command request. */
1228                sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD,
1229                    GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE);
1230
1231                /* Prepare SNS command arguments -- port_id. */
1232                sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
1233                sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
1234                sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
1235
1236                /* Execute SNS command. */
1237                rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
1238                    GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
1239                if (rval != QLA_SUCCESS) {
1240                        /*EMPTY*/
1241                        ql_dbg(ql_dbg_disc, vha, 0x203f,
1242                            "GNN_ID Send SNS failed (%d).\n", rval);
1243                } else if (sns_cmd->p.gnn_data[8] != 0x80 ||
1244                    sns_cmd->p.gnn_data[9] != 0x02) {
1245                        ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082,
1246                            "GNN_ID failed, rejected request, gnn_rsp:\n");
1247                        ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a,
1248                            sns_cmd->p.gnn_data, 16);
1249                        rval = QLA_FUNCTION_FAILED;
1250                } else {
1251                        /* Save nodename */
1252                        memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16],
1253                            WWN_SIZE);
1254
1255                        ql_dbg(ql_dbg_disc, vha, 0x206e,
1256                            "GID_PT entry - nn %8phN pn %8phN "
1257                            "port_id=%02x%02x%02x.\n",
1258                            list[i].node_name, list[i].port_name,
1259                            list[i].d_id.b.domain, list[i].d_id.b.area,
1260                            list[i].d_id.b.al_pa);
1261                }
1262
1263                /* Last device exit. */
1264                if (list[i].d_id.b.rsvd_1 != 0)
1265                        break;
1266        }
1267
1268        return (rval);
1269}
1270
1271/**
1272 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
1273 * @vha: HA context
1274 *
1275 * This command uses the old Exectute SNS Command mailbox routine.
1276 *
1277 * Returns 0 on success.
1278 */
1279static int
1280qla2x00_sns_rft_id(scsi_qla_host_t *vha)
1281{
1282        int             rval;
1283        struct qla_hw_data *ha = vha->hw;
1284        struct sns_cmd_pkt      *sns_cmd;
1285
1286        /* Issue RFT_ID. */
1287        /* Prepare SNS command request. */
1288        sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN,
1289            RFT_ID_SNS_DATA_SIZE);
1290
1291        /* Prepare SNS command arguments -- port_id, FC-4 types */
1292        sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1293        sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1294        sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
1295
1296        sns_cmd->p.cmd.param[5] = 0x01;                 /* FCP-3 */
1297
1298        /* Execute SNS command. */
1299        rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2,
1300            sizeof(struct sns_cmd_pkt));
1301        if (rval != QLA_SUCCESS) {
1302                /*EMPTY*/
1303                ql_dbg(ql_dbg_disc, vha, 0x2060,
1304                    "RFT_ID Send SNS failed (%d).\n", rval);
1305        } else if (sns_cmd->p.rft_data[8] != 0x80 ||
1306            sns_cmd->p.rft_data[9] != 0x02) {
1307                ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083,
1308                    "RFT_ID failed, rejected request rft_rsp:\n");
1309                ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080,
1310                    sns_cmd->p.rft_data, 16);
1311                rval = QLA_FUNCTION_FAILED;
1312        } else {
1313                ql_dbg(ql_dbg_disc, vha, 0x2073,
1314                    "RFT_ID exiting normally.\n");
1315        }
1316
1317        return (rval);
1318}
1319
1320/**
1321 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
1322 * @vha: HA context
1323 *
1324 * This command uses the old Exectute SNS Command mailbox routine.
1325 *
1326 * Returns 0 on success.
1327 */
1328static int
1329qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
1330{
1331        int             rval;
1332        struct qla_hw_data *ha = vha->hw;
1333        struct sns_cmd_pkt      *sns_cmd;
1334
1335        /* Issue RNN_ID. */
1336        /* Prepare SNS command request. */
1337        sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN,
1338            RNN_ID_SNS_DATA_SIZE);
1339
1340        /* Prepare SNS command arguments -- port_id, nodename. */
1341        sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1342        sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1343        sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
1344
1345        sns_cmd->p.cmd.param[4] = vha->node_name[7];
1346        sns_cmd->p.cmd.param[5] = vha->node_name[6];
1347        sns_cmd->p.cmd.param[6] = vha->node_name[5];
1348        sns_cmd->p.cmd.param[7] = vha->node_name[4];
1349        sns_cmd->p.cmd.param[8] = vha->node_name[3];
1350        sns_cmd->p.cmd.param[9] = vha->node_name[2];
1351        sns_cmd->p.cmd.param[10] = vha->node_name[1];
1352        sns_cmd->p.cmd.param[11] = vha->node_name[0];
1353
1354        /* Execute SNS command. */
1355        rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2,
1356            sizeof(struct sns_cmd_pkt));
1357        if (rval != QLA_SUCCESS) {
1358                /*EMPTY*/
1359                ql_dbg(ql_dbg_disc, vha, 0x204a,
1360                    "RNN_ID Send SNS failed (%d).\n", rval);
1361        } else if (sns_cmd->p.rnn_data[8] != 0x80 ||
1362            sns_cmd->p.rnn_data[9] != 0x02) {
1363                ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b,
1364                    "RNN_ID failed, rejected request, rnn_rsp:\n");
1365                ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c,
1366                    sns_cmd->p.rnn_data, 16);
1367                rval = QLA_FUNCTION_FAILED;
1368        } else {
1369                ql_dbg(ql_dbg_disc, vha, 0x204c,
1370                    "RNN_ID exiting normally.\n");
1371        }
1372
1373        return (rval);
1374}
1375
1376/**
1377 * qla2x00_mgmt_svr_login() - Login to fabric Management Service.
1378 * @vha: HA context
1379 *
1380 * Returns 0 on success.
1381 */
1382int
1383qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
1384{
1385        int ret, rval;
1386        uint16_t mb[MAILBOX_REGISTER_COUNT];
1387        struct qla_hw_data *ha = vha->hw;
1388        ret = QLA_SUCCESS;
1389        if (vha->flags.management_server_logged_in)
1390                return ret;
1391
1392        rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff,
1393            0xfa, mb, BIT_1);
1394        if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
1395                if (rval == QLA_MEMORY_ALLOC_FAILED)
1396                        ql_dbg(ql_dbg_disc, vha, 0x2085,
1397                            "Failed management_server login: loopid=%x "
1398                            "rval=%d\n", vha->mgmt_svr_loop_id, rval);
1399                else
1400                        ql_dbg(ql_dbg_disc, vha, 0x2024,
1401                            "Failed management_server login: loopid=%x "
1402                            "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
1403                            vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6],
1404                            mb[7]);
1405                ret = QLA_FUNCTION_FAILED;
1406        } else
1407                vha->flags.management_server_logged_in = 1;
1408
1409        return ret;
1410}
1411
1412/**
1413 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1414 * @vha: HA context
1415 * @req_size: request size in bytes
1416 * @rsp_size: response size in bytes
1417 *
1418 * Returns a pointer to the @ha's ms_iocb.
1419 */
1420void *
1421qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1422    uint32_t rsp_size)
1423{
1424        ms_iocb_entry_t *ms_pkt;
1425        struct qla_hw_data *ha = vha->hw;
1426        ms_pkt = ha->ms_iocb;
1427        memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
1428
1429        ms_pkt->entry_type = MS_IOCB_TYPE;
1430        ms_pkt->entry_count = 1;
1431        SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id);
1432        ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
1433        ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1434        ms_pkt->cmd_dsd_count = cpu_to_le16(1);
1435        ms_pkt->total_dsd_count = cpu_to_le16(2);
1436        ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
1437        ms_pkt->req_bytecount = cpu_to_le32(req_size);
1438
1439        ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1440        ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1441        ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1442
1443        ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1444        ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1445        ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
1446
1447        return ms_pkt;
1448}
1449
1450/**
1451 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1452 * @vha: HA context
1453 * @req_size: request size in bytes
1454 * @rsp_size: response size in bytes
1455 *
1456 * Returns a pointer to the @ha's ms_iocb.
1457 */
1458void *
1459qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1460    uint32_t rsp_size)
1461{
1462        struct ct_entry_24xx *ct_pkt;
1463        struct qla_hw_data *ha = vha->hw;
1464
1465        ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1466        memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1467
1468        ct_pkt->entry_type = CT_IOCB_TYPE;
1469        ct_pkt->entry_count = 1;
1470        ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
1471        ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1472        ct_pkt->cmd_dsd_count = cpu_to_le16(1);
1473        ct_pkt->rsp_dsd_count = cpu_to_le16(1);
1474        ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1475        ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1476
1477        ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1478        ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1479        ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1480
1481        ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1482        ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1483        ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
1484        ct_pkt->vp_index = vha->vp_idx;
1485
1486        return ct_pkt;
1487}
1488
1489static inline ms_iocb_entry_t *
1490qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
1491{
1492        struct qla_hw_data *ha = vha->hw;
1493        ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
1494        struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1495
1496        if (IS_FWI2_CAPABLE(ha)) {
1497                ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1498                ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1499        } else {
1500                ms_pkt->req_bytecount = cpu_to_le32(req_size);
1501                ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1502        }
1503
1504        return ms_pkt;
1505}
1506
1507/**
1508 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
1509 * @p: CT request buffer
1510 * @cmd: GS command
1511 * @rsp_size: response size in bytes
1512 *
1513 * Returns a pointer to the intitialized @ct_req.
1514 */
1515static inline struct ct_sns_req *
1516qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
1517    uint16_t rsp_size)
1518{
1519        memset(p, 0, sizeof(struct ct_sns_pkt));
1520
1521        p->p.req.header.revision = 0x01;
1522        p->p.req.header.gs_type = 0xFA;
1523        p->p.req.header.gs_subtype = 0x10;
1524        p->p.req.command = cpu_to_be16(cmd);
1525        p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
1526
1527        return &p->p.req;
1528}
1529
1530/**
1531 * qla2x00_fdmi_rhba() - perform RHBA FDMI registration
1532 * @vha: HA context
1533 *
1534 * Returns 0 on success.
1535 */
1536static int
1537qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
1538{
1539        int rval, alen;
1540        uint32_t size, sn;
1541
1542        ms_iocb_entry_t *ms_pkt;
1543        struct ct_sns_req *ct_req;
1544        struct ct_sns_rsp *ct_rsp;
1545        void *entries;
1546        struct ct_fdmi_hba_attr *eiter;
1547        struct qla_hw_data *ha = vha->hw;
1548
1549        /* Issue RHBA */
1550        /* Prepare common MS IOCB */
1551        /*   Request size adjusted after CT preparation */
1552        ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
1553
1554        /* Prepare CT request */
1555        ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, RHBA_RSP_SIZE);
1556        ct_rsp = &ha->ct_sns->p.rsp;
1557
1558        /* Prepare FDMI command arguments -- attribute block, attributes. */
1559        memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE);
1560        ct_req->req.rhba.entry_count = cpu_to_be32(1);
1561        memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE);
1562        size = 2 * WWN_SIZE + 4 + 4;
1563
1564        /* Attributes */
1565        ct_req->req.rhba.attrs.count =
1566            cpu_to_be32(FDMI_HBA_ATTR_COUNT);
1567        entries = ct_req->req.rhba.hba_identifier;
1568
1569        /* Nodename. */
1570        eiter = entries + size;
1571        eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME);
1572        eiter->len = cpu_to_be16(4 + WWN_SIZE);
1573        memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
1574        size += 4 + WWN_SIZE;
1575
1576        ql_dbg(ql_dbg_disc, vha, 0x2025,
1577            "NodeName = %8phN.\n", eiter->a.node_name);
1578
1579        /* Manufacturer. */
1580        eiter = entries + size;
1581        eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER);
1582        alen = strlen(QLA2XXX_MANUFACTURER);
1583        snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer),
1584            "%s", "QLogic Corporation");
1585        alen += 4 - (alen & 3);
1586        eiter->len = cpu_to_be16(4 + alen);
1587        size += 4 + alen;
1588
1589        ql_dbg(ql_dbg_disc, vha, 0x2026,
1590            "Manufacturer = %s.\n", eiter->a.manufacturer);
1591
1592        /* Serial number. */
1593        eiter = entries + size;
1594        eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
1595        if (IS_FWI2_CAPABLE(ha))
1596                qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num,
1597                    sizeof(eiter->a.serial_num));
1598        else {
1599                sn = ((ha->serial0 & 0x1f) << 16) |
1600                        (ha->serial2 << 8) | ha->serial1;
1601                snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num),
1602                    "%c%05d", 'A' + sn / 100000, sn % 100000);
1603        }
1604        alen = strlen(eiter->a.serial_num);
1605        alen += 4 - (alen & 3);
1606        eiter->len = cpu_to_be16(4 + alen);
1607        size += 4 + alen;
1608
1609        ql_dbg(ql_dbg_disc, vha, 0x2027,
1610            "Serial no. = %s.\n", eiter->a.serial_num);
1611
1612        /* Model name. */
1613        eiter = entries + size;
1614        eiter->type = cpu_to_be16(FDMI_HBA_MODEL);
1615        snprintf(eiter->a.model, sizeof(eiter->a.model),
1616            "%s", ha->model_number);
1617        alen = strlen(eiter->a.model);
1618        alen += 4 - (alen & 3);
1619        eiter->len = cpu_to_be16(4 + alen);
1620        size += 4 + alen;
1621
1622        ql_dbg(ql_dbg_disc, vha, 0x2028,
1623            "Model Name = %s.\n", eiter->a.model);
1624
1625        /* Model description. */
1626        eiter = entries + size;
1627        eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
1628        snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc),
1629            "%s", ha->model_desc);
1630        alen = strlen(eiter->a.model_desc);
1631        alen += 4 - (alen & 3);
1632        eiter->len = cpu_to_be16(4 + alen);
1633        size += 4 + alen;
1634
1635        ql_dbg(ql_dbg_disc, vha, 0x2029,
1636            "Model Desc = %s.\n", eiter->a.model_desc);
1637
1638        /* Hardware version. */
1639        eiter = entries + size;
1640        eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
1641        if (!IS_FWI2_CAPABLE(ha)) {
1642                snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1643                    "HW:%s", ha->adapter_id);
1644        } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version,
1645                    sizeof(eiter->a.hw_version))) {
1646                ;
1647        } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version,
1648                    sizeof(eiter->a.hw_version))) {
1649                ;
1650        } else {
1651                snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1652                    "HW:%s", ha->adapter_id);
1653        }
1654        alen = strlen(eiter->a.hw_version);
1655        alen += 4 - (alen & 3);
1656        eiter->len = cpu_to_be16(4 + alen);
1657        size += 4 + alen;
1658
1659        ql_dbg(ql_dbg_disc, vha, 0x202a,
1660            "Hardware ver = %s.\n", eiter->a.hw_version);
1661
1662        /* Driver version. */
1663        eiter = entries + size;
1664        eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
1665        snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version),
1666            "%s", qla2x00_version_str);
1667        alen = strlen(eiter->a.driver_version);
1668        alen += 4 - (alen & 3);
1669        eiter->len = cpu_to_be16(4 + alen);
1670        size += 4 + alen;
1671
1672        ql_dbg(ql_dbg_disc, vha, 0x202b,
1673            "Driver ver = %s.\n", eiter->a.driver_version);
1674
1675        /* Option ROM version. */
1676        eiter = entries + size;
1677        eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
1678        snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version),
1679            "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
1680        alen = strlen(eiter->a.orom_version);
1681        alen += 4 - (alen & 3);
1682        eiter->len = cpu_to_be16(4 + alen);
1683        size += 4 + alen;
1684
1685        ql_dbg(ql_dbg_disc, vha , 0x202c,
1686            "Optrom vers = %s.\n", eiter->a.orom_version);
1687
1688        /* Firmware version */
1689        eiter = entries + size;
1690        eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
1691        ha->isp_ops->fw_version_str(vha, eiter->a.fw_version,
1692            sizeof(eiter->a.fw_version));
1693        alen = strlen(eiter->a.fw_version);
1694        alen += 4 - (alen & 3);
1695        eiter->len = cpu_to_be16(4 + alen);
1696        size += 4 + alen;
1697
1698        ql_dbg(ql_dbg_disc, vha, 0x202d,
1699            "Firmware vers = %s.\n", eiter->a.fw_version);
1700
1701        /* Update MS request size. */
1702        qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1703
1704        ql_dbg(ql_dbg_disc, vha, 0x202e,
1705            "RHBA identifier = %8phN size=%d.\n",
1706            ct_req->req.rhba.hba_identifier, size);
1707        ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076,
1708            entries, size);
1709
1710        /* Execute MS IOCB */
1711        rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1712            sizeof(ms_iocb_entry_t));
1713        if (rval != QLA_SUCCESS) {
1714                /*EMPTY*/
1715                ql_dbg(ql_dbg_disc, vha, 0x2030,
1716                    "RHBA issue IOCB failed (%d).\n", rval);
1717        } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") !=
1718            QLA_SUCCESS) {
1719                rval = QLA_FUNCTION_FAILED;
1720                if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1721                    ct_rsp->header.explanation_code ==
1722                    CT_EXPL_ALREADY_REGISTERED) {
1723                        ql_dbg(ql_dbg_disc, vha, 0x2034,
1724                            "HBA already registered.\n");
1725                        rval = QLA_ALREADY_REGISTERED;
1726                } else {
1727                        ql_dbg(ql_dbg_disc, vha, 0x20ad,
1728                            "RHBA FDMI registration failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
1729                            ct_rsp->header.reason_code,
1730                            ct_rsp->header.explanation_code);
1731                }
1732        } else {
1733                ql_dbg(ql_dbg_disc, vha, 0x2035,
1734                    "RHBA exiting normally.\n");
1735        }
1736
1737        return rval;
1738}
1739
1740/**
1741 * qla2x00_fdmi_rpa() - perform RPA registration
1742 * @vha: HA context
1743 *
1744 * Returns 0 on success.
1745 */
1746static int
1747qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
1748{
1749        int rval, alen;
1750        uint32_t size;
1751        struct qla_hw_data *ha = vha->hw;
1752        ms_iocb_entry_t *ms_pkt;
1753        struct ct_sns_req *ct_req;
1754        struct ct_sns_rsp *ct_rsp;
1755        void *entries;
1756        struct ct_fdmi_port_attr *eiter;
1757        struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
1758        struct new_utsname *p_sysid = NULL;
1759
1760        /* Issue RPA */
1761        /* Prepare common MS IOCB */
1762        /*   Request size adjusted after CT preparation */
1763        ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
1764
1765        /* Prepare CT request */
1766        ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD,
1767            RPA_RSP_SIZE);
1768        ct_rsp = &ha->ct_sns->p.rsp;
1769
1770        /* Prepare FDMI command arguments -- attribute block, attributes. */
1771        memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE);
1772        size = WWN_SIZE + 4;
1773
1774        /* Attributes */
1775        ct_req->req.rpa.attrs.count = cpu_to_be32(FDMI_PORT_ATTR_COUNT);
1776        entries = ct_req->req.rpa.port_name;
1777
1778        /* FC4 types. */
1779        eiter = entries + size;
1780        eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES);
1781        eiter->len = cpu_to_be16(4 + 32);
1782        eiter->a.fc4_types[2] = 0x01;
1783        size += 4 + 32;
1784
1785        ql_dbg(ql_dbg_disc, vha, 0x2039,
1786            "FC4_TYPES=%02x %02x.\n",
1787            eiter->a.fc4_types[2],
1788            eiter->a.fc4_types[1]);
1789
1790        /* Supported speed. */
1791        eiter = entries + size;
1792        eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
1793        eiter->len = cpu_to_be16(4 + 4);
1794        if (IS_CNA_CAPABLE(ha))
1795                eiter->a.sup_speed = cpu_to_be32(
1796                    FDMI_PORT_SPEED_10GB);
1797        else if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
1798                eiter->a.sup_speed = cpu_to_be32(
1799                    FDMI_PORT_SPEED_32GB|
1800                    FDMI_PORT_SPEED_16GB|
1801                    FDMI_PORT_SPEED_8GB);
1802        else if (IS_QLA2031(ha))
1803                eiter->a.sup_speed = cpu_to_be32(
1804                    FDMI_PORT_SPEED_16GB|
1805                    FDMI_PORT_SPEED_8GB|
1806                    FDMI_PORT_SPEED_4GB);
1807        else if (IS_QLA25XX(ha))
1808                eiter->a.sup_speed = cpu_to_be32(
1809                    FDMI_PORT_SPEED_8GB|
1810                    FDMI_PORT_SPEED_4GB|
1811                    FDMI_PORT_SPEED_2GB|
1812                    FDMI_PORT_SPEED_1GB);
1813        else if (IS_QLA24XX_TYPE(ha))
1814                eiter->a.sup_speed = cpu_to_be32(
1815                    FDMI_PORT_SPEED_4GB|
1816                    FDMI_PORT_SPEED_2GB|
1817                    FDMI_PORT_SPEED_1GB);
1818        else if (IS_QLA23XX(ha))
1819                eiter->a.sup_speed = cpu_to_be32(
1820                    FDMI_PORT_SPEED_2GB|
1821                    FDMI_PORT_SPEED_1GB);
1822        else
1823                eiter->a.sup_speed = cpu_to_be32(
1824                    FDMI_PORT_SPEED_1GB);
1825        size += 4 + 4;
1826
1827        ql_dbg(ql_dbg_disc, vha, 0x203a,
1828            "Supported_Speed=%x.\n", eiter->a.sup_speed);
1829
1830        /* Current speed. */
1831        eiter = entries + size;
1832        eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
1833        eiter->len = cpu_to_be16(4 + 4);
1834        switch (ha->link_data_rate) {
1835        case PORT_SPEED_1GB:
1836                eiter->a.cur_speed =
1837                    cpu_to_be32(FDMI_PORT_SPEED_1GB);
1838                break;
1839        case PORT_SPEED_2GB:
1840                eiter->a.cur_speed =
1841                    cpu_to_be32(FDMI_PORT_SPEED_2GB);
1842                break;
1843        case PORT_SPEED_4GB:
1844                eiter->a.cur_speed =
1845                    cpu_to_be32(FDMI_PORT_SPEED_4GB);
1846                break;
1847        case PORT_SPEED_8GB:
1848                eiter->a.cur_speed =
1849                    cpu_to_be32(FDMI_PORT_SPEED_8GB);
1850                break;
1851        case PORT_SPEED_10GB:
1852                eiter->a.cur_speed =
1853                    cpu_to_be32(FDMI_PORT_SPEED_10GB);
1854                break;
1855        case PORT_SPEED_16GB:
1856                eiter->a.cur_speed =
1857                    cpu_to_be32(FDMI_PORT_SPEED_16GB);
1858                break;
1859        case PORT_SPEED_32GB:
1860                eiter->a.cur_speed =
1861                    cpu_to_be32(FDMI_PORT_SPEED_32GB);
1862                break;
1863        default:
1864                eiter->a.cur_speed =
1865                    cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
1866                break;
1867        }
1868        size += 4 + 4;
1869
1870        ql_dbg(ql_dbg_disc, vha, 0x203b,
1871            "Current_Speed=%x.\n", eiter->a.cur_speed);
1872
1873        /* Max frame size. */
1874        eiter = entries + size;
1875        eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
1876        eiter->len = cpu_to_be16(4 + 4);
1877        eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ?
1878            le16_to_cpu(icb24->frame_payload_size) :
1879            le16_to_cpu(ha->init_cb->frame_payload_size);
1880        eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size);
1881        size += 4 + 4;
1882
1883        ql_dbg(ql_dbg_disc, vha, 0x203c,
1884            "Max_Frame_Size=%x.\n", eiter->a.max_frame_size);
1885
1886        /* OS device name. */
1887        eiter = entries + size;
1888        eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
1889        snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name),
1890            "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
1891        alen = strlen(eiter->a.os_dev_name);
1892        alen += 4 - (alen & 3);
1893        eiter->len = cpu_to_be16(4 + alen);
1894        size += 4 + alen;
1895
1896        ql_dbg(ql_dbg_disc, vha, 0x204b,
1897            "OS_Device_Name=%s.\n", eiter->a.os_dev_name);
1898
1899        /* Hostname. */
1900        eiter = entries + size;
1901        eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME);
1902        p_sysid = utsname();
1903        if (p_sysid) {
1904                snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
1905                    "%s", p_sysid->nodename);
1906        } else {
1907                snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
1908                    "%s", fc_host_system_hostname(vha->host));
1909        }
1910        alen = strlen(eiter->a.host_name);
1911        alen += 4 - (alen & 3);
1912        eiter->len = cpu_to_be16(4 + alen);
1913        size += 4 + alen;
1914
1915        ql_dbg(ql_dbg_disc, vha, 0x203d, "HostName=%s.\n", eiter->a.host_name);
1916
1917        /* Update MS request size. */
1918        qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1919
1920        ql_dbg(ql_dbg_disc, vha, 0x203e,
1921            "RPA portname  %016llx, size = %d.\n",
1922            wwn_to_u64(ct_req->req.rpa.port_name), size);
1923        ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079,
1924            entries, size);
1925
1926        /* Execute MS IOCB */
1927        rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1928            sizeof(ms_iocb_entry_t));
1929        if (rval != QLA_SUCCESS) {
1930                /*EMPTY*/
1931                ql_dbg(ql_dbg_disc, vha, 0x2040,
1932                    "RPA issue IOCB failed (%d).\n", rval);
1933        } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") !=
1934            QLA_SUCCESS) {
1935                rval = QLA_FUNCTION_FAILED;
1936                if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1937                    ct_rsp->header.explanation_code ==
1938                    CT_EXPL_ALREADY_REGISTERED) {
1939                        ql_dbg(ql_dbg_disc, vha, 0x20cd,
1940                            "RPA already registered.\n");
1941                        rval = QLA_ALREADY_REGISTERED;
1942                }
1943
1944        } else {
1945                ql_dbg(ql_dbg_disc, vha, 0x2041,
1946                    "RPA exiting normally.\n");
1947        }
1948
1949        return rval;
1950}
1951
1952/**
1953 * qla2x00_fdmiv2_rhba() - perform RHBA FDMI v2 registration
1954 * @vha: HA context
1955 *
1956 * Returns 0 on success.
1957 */
1958static int
1959qla2x00_fdmiv2_rhba(scsi_qla_host_t *vha)
1960{
1961        int rval, alen;
1962        uint32_t size, sn;
1963        ms_iocb_entry_t *ms_pkt;
1964        struct ct_sns_req *ct_req;
1965        struct ct_sns_rsp *ct_rsp;
1966        void *entries;
1967        struct ct_fdmiv2_hba_attr *eiter;
1968        struct qla_hw_data *ha = vha->hw;
1969        struct new_utsname *p_sysid = NULL;
1970
1971        /* Issue RHBA */
1972        /* Prepare common MS IOCB */
1973        /*   Request size adjusted after CT preparation */
1974        ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
1975
1976        /* Prepare CT request */
1977        ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD,
1978            RHBA_RSP_SIZE);
1979        ct_rsp = &ha->ct_sns->p.rsp;
1980
1981        /* Prepare FDMI command arguments -- attribute block, attributes. */
1982        memcpy(ct_req->req.rhba2.hba_identifier, vha->port_name, WWN_SIZE);
1983        ct_req->req.rhba2.entry_count = cpu_to_be32(1);
1984        memcpy(ct_req->req.rhba2.port_name, vha->port_name, WWN_SIZE);
1985        size = 2 * WWN_SIZE + 4 + 4;
1986
1987        /* Attributes */
1988        ct_req->req.rhba2.attrs.count = cpu_to_be32(FDMIV2_HBA_ATTR_COUNT);
1989        entries = ct_req->req.rhba2.hba_identifier;
1990
1991        /* Nodename. */
1992        eiter = entries + size;
1993        eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME);
1994        eiter->len = cpu_to_be16(4 + WWN_SIZE);
1995        memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
1996        size += 4 + WWN_SIZE;
1997
1998        ql_dbg(ql_dbg_disc, vha, 0x207d,
1999            "NodeName = %016llx.\n", wwn_to_u64(eiter->a.node_name));
2000
2001        /* Manufacturer. */
2002        eiter = entries + size;
2003        eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER);
2004        snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer),
2005            "%s", "QLogic Corporation");
2006        eiter->a.manufacturer[strlen("QLogic Corporation")] = '\0';
2007        alen = strlen(eiter->a.manufacturer);
2008        alen += 4 - (alen & 3);
2009        eiter->len = cpu_to_be16(4 + alen);
2010        size += 4 + alen;
2011
2012        ql_dbg(ql_dbg_disc, vha, 0x20a5,
2013            "Manufacturer = %s.\n", eiter->a.manufacturer);
2014
2015        /* Serial number. */
2016        eiter = entries + size;
2017        eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
2018        if (IS_FWI2_CAPABLE(ha))
2019                qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num,
2020                    sizeof(eiter->a.serial_num));
2021        else {
2022                sn = ((ha->serial0 & 0x1f) << 16) |
2023                        (ha->serial2 << 8) | ha->serial1;
2024                snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num),
2025                    "%c%05d", 'A' + sn / 100000, sn % 100000);
2026        }
2027        alen = strlen(eiter->a.serial_num);
2028        alen += 4 - (alen & 3);
2029        eiter->len = cpu_to_be16(4 + alen);
2030        size += 4 + alen;
2031
2032        ql_dbg(ql_dbg_disc, vha, 0x20a6,
2033            "Serial no. = %s.\n", eiter->a.serial_num);
2034
2035        /* Model name. */
2036        eiter = entries + size;
2037        eiter->type = cpu_to_be16(FDMI_HBA_MODEL);
2038        snprintf(eiter->a.model, sizeof(eiter->a.model),
2039            "%s", ha->model_number);
2040        alen = strlen(eiter->a.model);
2041        alen += 4 - (alen & 3);
2042        eiter->len = cpu_to_be16(4 + alen);
2043        size += 4 + alen;
2044
2045        ql_dbg(ql_dbg_disc, vha, 0x20a7,
2046            "Model Name = %s.\n", eiter->a.model);
2047
2048        /* Model description. */
2049        eiter = entries + size;
2050        eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
2051        snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc),
2052            "%s", ha->model_desc);
2053        alen = strlen(eiter->a.model_desc);
2054        alen += 4 - (alen & 3);
2055        eiter->len = cpu_to_be16(4 + alen);
2056        size += 4 + alen;
2057
2058        ql_dbg(ql_dbg_disc, vha, 0x20a8,
2059            "Model Desc = %s.\n", eiter->a.model_desc);
2060
2061        /* Hardware version. */
2062        eiter = entries + size;
2063        eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
2064        if (!IS_FWI2_CAPABLE(ha)) {
2065                snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
2066                    "HW:%s", ha->adapter_id);
2067        } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version,
2068                    sizeof(eiter->a.hw_version))) {
2069                ;
2070        } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version,
2071                    sizeof(eiter->a.hw_version))) {
2072                ;
2073        } else {
2074                snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
2075                    "HW:%s", ha->adapter_id);
2076        }
2077        alen = strlen(eiter->a.hw_version);
2078        alen += 4 - (alen & 3);
2079        eiter->len = cpu_to_be16(4 + alen);
2080        size += 4 + alen;
2081
2082        ql_dbg(ql_dbg_disc, vha, 0x20a9,
2083            "Hardware ver = %s.\n", eiter->a.hw_version);
2084
2085        /* Driver version. */
2086        eiter = entries + size;
2087        eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
2088        snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version),
2089            "%s", qla2x00_version_str);
2090        alen = strlen(eiter->a.driver_version);
2091        alen += 4 - (alen & 3);
2092        eiter->len = cpu_to_be16(4 + alen);
2093        size += 4 + alen;
2094
2095        ql_dbg(ql_dbg_disc, vha, 0x20aa,
2096            "Driver ver = %s.\n", eiter->a.driver_version);
2097
2098        /* Option ROM version. */
2099        eiter = entries + size;
2100        eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
2101        snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version),
2102            "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
2103        alen = strlen(eiter->a.orom_version);
2104        alen += 4 - (alen & 3);
2105        eiter->len = cpu_to_be16(4 + alen);
2106        size += 4 + alen;
2107
2108        ql_dbg(ql_dbg_disc, vha , 0x20ab,
2109            "Optrom version = %d.%02d.\n", eiter->a.orom_version[1],
2110            eiter->a.orom_version[0]);
2111
2112        /* Firmware version */
2113        eiter = entries + size;
2114        eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
2115        ha->isp_ops->fw_version_str(vha, eiter->a.fw_version,
2116            sizeof(eiter->a.fw_version));
2117        alen = strlen(eiter->a.fw_version);
2118        alen += 4 - (alen & 3);
2119        eiter->len = cpu_to_be16(4 + alen);
2120        size += 4 + alen;
2121
2122        ql_dbg(ql_dbg_disc, vha, 0x20ac,
2123            "Firmware vers = %s.\n", eiter->a.fw_version);
2124
2125        /* OS Name and Version */
2126        eiter = entries + size;
2127        eiter->type = cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION);
2128        p_sysid = utsname();
2129        if (p_sysid) {
2130                snprintf(eiter->a.os_version, sizeof(eiter->a.os_version),
2131                    "%s %s %s",
2132                    p_sysid->sysname, p_sysid->release, p_sysid->version);
2133        } else {
2134                snprintf(eiter->a.os_version, sizeof(eiter->a.os_version),
2135                    "%s %s", "Linux", fc_host_system_hostname(vha->host));
2136        }
2137        alen = strlen(eiter->a.os_version);
2138        alen += 4 - (alen & 3);
2139        eiter->len = cpu_to_be16(4 + alen);
2140        size += 4 + alen;
2141
2142        ql_dbg(ql_dbg_disc, vha, 0x20ae,
2143            "OS Name and Version = %s.\n", eiter->a.os_version);
2144
2145        /* MAX CT Payload Length */
2146        eiter = entries + size;
2147        eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH);
2148        eiter->a.max_ct_len = cpu_to_be32(ha->frame_payload_size);
2149        eiter->a.max_ct_len = cpu_to_be32(eiter->a.max_ct_len);
2150        eiter->len = cpu_to_be16(4 + 4);
2151        size += 4 + 4;
2152
2153        ql_dbg(ql_dbg_disc, vha, 0x20af,
2154            "CT Payload Length = 0x%x.\n", eiter->a.max_ct_len);
2155
2156        /* Node Sybolic Name */
2157        eiter = entries + size;
2158        eiter->type = cpu_to_be16(FDMI_HBA_NODE_SYMBOLIC_NAME);
2159        qla2x00_get_sym_node_name(vha, eiter->a.sym_name,
2160            sizeof(eiter->a.sym_name));
2161        alen = strlen(eiter->a.sym_name);
2162        alen += 4 - (alen & 3);
2163        eiter->len = cpu_to_be16(4 + alen);
2164        size += 4 + alen;
2165
2166        ql_dbg(ql_dbg_disc, vha, 0x20b0,
2167            "Symbolic Name = %s.\n", eiter->a.sym_name);
2168
2169        /* Vendor Id */
2170        eiter = entries + size;
2171        eiter->type = cpu_to_be16(FDMI_HBA_VENDOR_ID);
2172        eiter->a.vendor_id = cpu_to_be32(0x1077);
2173        eiter->len = cpu_to_be16(4 + 4);
2174        size += 4 + 4;
2175
2176        ql_dbg(ql_dbg_disc, vha, 0x20b1,
2177            "Vendor Id = %x.\n", eiter->a.vendor_id);
2178
2179        /* Num Ports */
2180        eiter = entries + size;
2181        eiter->type = cpu_to_be16(FDMI_HBA_NUM_PORTS);
2182        eiter->a.num_ports = cpu_to_be32(1);
2183        eiter->len = cpu_to_be16(4 + 4);
2184        size += 4 + 4;
2185
2186        ql_dbg(ql_dbg_disc, vha, 0x20b2,
2187            "Port Num = %x.\n", eiter->a.num_ports);
2188
2189        /* Fabric Name */
2190        eiter = entries + size;
2191        eiter->type = cpu_to_be16(FDMI_HBA_FABRIC_NAME);
2192        memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE);
2193        eiter->len = cpu_to_be16(4 + WWN_SIZE);
2194        size += 4 + WWN_SIZE;
2195
2196        ql_dbg(ql_dbg_disc, vha, 0x20b3,
2197            "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
2198
2199        /* BIOS Version */
2200        eiter = entries + size;
2201        eiter->type = cpu_to_be16(FDMI_HBA_BOOT_BIOS_NAME);
2202        snprintf(eiter->a.bios_name, sizeof(eiter->a.bios_name),
2203            "BIOS %d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
2204        alen = strlen(eiter->a.bios_name);
2205        alen += 4 - (alen & 3);
2206        eiter->len = cpu_to_be16(4 + alen);
2207        size += 4 + alen;
2208
2209        ql_dbg(ql_dbg_disc, vha, 0x20b4,
2210            "BIOS Name = %s\n", eiter->a.bios_name);
2211
2212        /* Vendor Identifier */
2213        eiter = entries + size;
2214        eiter->type = cpu_to_be16(FDMI_HBA_TYPE_VENDOR_IDENTIFIER);
2215        snprintf(eiter->a.vendor_identifier, sizeof(eiter->a.vendor_identifier),
2216            "%s", "QLGC");
2217        alen = strlen(eiter->a.vendor_identifier);
2218        alen += 4 - (alen & 3);
2219        eiter->len = cpu_to_be16(4 + alen);
2220        size += 4 + alen;
2221
2222        ql_dbg(ql_dbg_disc, vha, 0x201b,
2223            "Vendor Identifier = %s.\n", eiter->a.vendor_identifier);
2224
2225        /* Update MS request size. */
2226        qla2x00_update_ms_fdmi_iocb(vha, size + 16);
2227
2228        ql_dbg(ql_dbg_disc, vha, 0x20b5,
2229            "RHBA identifier = %016llx.\n",
2230            wwn_to_u64(ct_req->req.rhba2.hba_identifier));
2231        ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20b6,
2232            entries, size);
2233
2234        /* Execute MS IOCB */
2235        rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2236            sizeof(ms_iocb_entry_t));
2237        if (rval != QLA_SUCCESS) {
2238                /*EMPTY*/
2239                ql_dbg(ql_dbg_disc, vha, 0x20b7,
2240                    "RHBA issue IOCB failed (%d).\n", rval);
2241        } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") !=
2242            QLA_SUCCESS) {
2243                rval = QLA_FUNCTION_FAILED;
2244
2245                if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
2246                    ct_rsp->header.explanation_code ==
2247                    CT_EXPL_ALREADY_REGISTERED) {
2248                        ql_dbg(ql_dbg_disc, vha, 0x20b8,
2249                            "HBA already registered.\n");
2250                        rval = QLA_ALREADY_REGISTERED;
2251                } else {
2252                        ql_dbg(ql_dbg_disc, vha, 0x2016,
2253                            "RHBA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
2254                            ct_rsp->header.reason_code,
2255                            ct_rsp->header.explanation_code);
2256                }
2257        } else {
2258                ql_dbg(ql_dbg_disc, vha, 0x20b9,
2259                    "RHBA FDMI V2 exiting normally.\n");
2260        }
2261
2262        return rval;
2263}
2264
2265/**
2266 * qla2x00_fdmi_dhba() -
2267 * @vha: HA context
2268 *
2269 * Returns 0 on success.
2270 */
2271static int
2272qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
2273{
2274        int rval;
2275        struct qla_hw_data *ha = vha->hw;
2276        ms_iocb_entry_t *ms_pkt;
2277        struct ct_sns_req *ct_req;
2278        struct ct_sns_rsp *ct_rsp;
2279
2280        /* Issue RPA */
2281        /* Prepare common MS IOCB */
2282        ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE,
2283            DHBA_RSP_SIZE);
2284
2285        /* Prepare CT request */
2286        ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE);
2287        ct_rsp = &ha->ct_sns->p.rsp;
2288
2289        /* Prepare FDMI command arguments -- portname. */
2290        memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE);
2291
2292        ql_dbg(ql_dbg_disc, vha, 0x2036,
2293            "DHBA portname = %8phN.\n", ct_req->req.dhba.port_name);
2294
2295        /* Execute MS IOCB */
2296        rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2297            sizeof(ms_iocb_entry_t));
2298        if (rval != QLA_SUCCESS) {
2299                /*EMPTY*/
2300                ql_dbg(ql_dbg_disc, vha, 0x2037,
2301                    "DHBA issue IOCB failed (%d).\n", rval);
2302        } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") !=
2303            QLA_SUCCESS) {
2304                rval = QLA_FUNCTION_FAILED;
2305        } else {
2306                ql_dbg(ql_dbg_disc, vha, 0x2038,
2307                    "DHBA exiting normally.\n");
2308        }
2309
2310        return rval;
2311}
2312
2313/**
2314 * qla2x00_fdmiv2_rpa() -
2315 * @vha: HA context
2316 *
2317 * Returns 0 on success.
2318 */
2319static int
2320qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha)
2321{
2322        int rval, alen;
2323        uint32_t size;
2324        struct qla_hw_data *ha = vha->hw;
2325        ms_iocb_entry_t *ms_pkt;
2326        struct ct_sns_req *ct_req;
2327        struct ct_sns_rsp *ct_rsp;
2328        void *entries;
2329        struct ct_fdmiv2_port_attr *eiter;
2330        struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
2331        struct new_utsname *p_sysid = NULL;
2332
2333        /* Issue RPA */
2334        /* Prepare common MS IOCB */
2335        /*   Request size adjusted after CT preparation */
2336        ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
2337
2338        /* Prepare CT request */
2339        ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, RPA_RSP_SIZE);
2340        ct_rsp = &ha->ct_sns->p.rsp;
2341
2342        /* Prepare FDMI command arguments -- attribute block, attributes. */
2343        memcpy(ct_req->req.rpa2.port_name, vha->port_name, WWN_SIZE);
2344        size = WWN_SIZE + 4;
2345
2346        /* Attributes */
2347        ct_req->req.rpa2.attrs.count = cpu_to_be32(FDMIV2_PORT_ATTR_COUNT);
2348        entries = ct_req->req.rpa2.port_name;
2349
2350        /* FC4 types. */
2351        eiter = entries + size;
2352        eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES);
2353        eiter->len = cpu_to_be16(4 + 32);
2354        eiter->a.fc4_types[2] = 0x01;
2355        size += 4 + 32;
2356
2357        ql_dbg(ql_dbg_disc, vha, 0x20ba,
2358            "FC4_TYPES=%02x %02x.\n",
2359            eiter->a.fc4_types[2],
2360            eiter->a.fc4_types[1]);
2361
2362        if (vha->flags.nvme_enabled) {
2363                eiter->a.fc4_types[6] = 1;      /* NVMe type 28h */
2364                ql_dbg(ql_dbg_disc, vha, 0x211f,
2365                    "NVME FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n",
2366                    eiter->a.fc4_types[6]);
2367        }
2368
2369        /* Supported speed. */
2370        eiter = entries + size;
2371        eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
2372        eiter->len = cpu_to_be16(4 + 4);
2373        if (IS_CNA_CAPABLE(ha))
2374                eiter->a.sup_speed = cpu_to_be32(
2375                    FDMI_PORT_SPEED_10GB);
2376        else if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
2377                eiter->a.sup_speed = cpu_to_be32(
2378                    FDMI_PORT_SPEED_32GB|
2379                    FDMI_PORT_SPEED_16GB|
2380                    FDMI_PORT_SPEED_8GB);
2381        else if (IS_QLA2031(ha))
2382                eiter->a.sup_speed = cpu_to_be32(
2383                    FDMI_PORT_SPEED_16GB|
2384                    FDMI_PORT_SPEED_8GB|
2385                    FDMI_PORT_SPEED_4GB);
2386        else if (IS_QLA25XX(ha))
2387                eiter->a.sup_speed = cpu_to_be32(
2388                    FDMI_PORT_SPEED_8GB|
2389                    FDMI_PORT_SPEED_4GB|
2390                    FDMI_PORT_SPEED_2GB|
2391                    FDMI_PORT_SPEED_1GB);
2392        else if (IS_QLA24XX_TYPE(ha))
2393                eiter->a.sup_speed = cpu_to_be32(
2394                    FDMI_PORT_SPEED_4GB|
2395                    FDMI_PORT_SPEED_2GB|
2396                    FDMI_PORT_SPEED_1GB);
2397        else if (IS_QLA23XX(ha))
2398                eiter->a.sup_speed = cpu_to_be32(
2399                    FDMI_PORT_SPEED_2GB|
2400                    FDMI_PORT_SPEED_1GB);
2401        else
2402                eiter->a.sup_speed = cpu_to_be32(
2403                    FDMI_PORT_SPEED_1GB);
2404        size += 4 + 4;
2405
2406        ql_dbg(ql_dbg_disc, vha, 0x20bb,
2407            "Supported Port Speed = %x.\n", eiter->a.sup_speed);
2408
2409        /* Current speed. */
2410        eiter = entries + size;
2411        eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
2412        eiter->len = cpu_to_be16(4 + 4);
2413        switch (ha->link_data_rate) {
2414        case PORT_SPEED_1GB:
2415                eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_1GB);
2416                break;
2417        case PORT_SPEED_2GB:
2418                eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_2GB);
2419                break;
2420        case PORT_SPEED_4GB:
2421                eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_4GB);
2422                break;
2423        case PORT_SPEED_8GB:
2424                eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_8GB);
2425                break;
2426        case PORT_SPEED_10GB:
2427                eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_10GB);
2428                break;
2429        case PORT_SPEED_16GB:
2430                eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_16GB);
2431                break;
2432        case PORT_SPEED_32GB:
2433                eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_32GB);
2434                break;
2435        default:
2436                eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
2437                break;
2438        }
2439        size += 4 + 4;
2440
2441        ql_dbg(ql_dbg_disc, vha, 0x2017,
2442            "Current_Speed = %x.\n", eiter->a.cur_speed);
2443
2444        /* Max frame size. */
2445        eiter = entries + size;
2446        eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
2447        eiter->len = cpu_to_be16(4 + 4);
2448        eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ?
2449            le16_to_cpu(icb24->frame_payload_size):
2450            le16_to_cpu(ha->init_cb->frame_payload_size);
2451        eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size);
2452        size += 4 + 4;
2453
2454        ql_dbg(ql_dbg_disc, vha, 0x20bc,
2455            "Max_Frame_Size = %x.\n", eiter->a.max_frame_size);
2456
2457        /* OS device name. */
2458        eiter = entries + size;
2459        eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
2460        alen = strlen(QLA2XXX_DRIVER_NAME);
2461        snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name),
2462            "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
2463        alen += 4 - (alen & 3);
2464        eiter->len = cpu_to_be16(4 + alen);
2465        size += 4 + alen;
2466
2467        ql_dbg(ql_dbg_disc, vha, 0x20be,
2468            "OS_Device_Name = %s.\n", eiter->a.os_dev_name);
2469
2470        /* Hostname. */
2471        eiter = entries + size;
2472        eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME);
2473        p_sysid = utsname();
2474        if (p_sysid) {
2475                snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
2476                    "%s", p_sysid->nodename);
2477        } else {
2478                snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
2479                    "%s", fc_host_system_hostname(vha->host));
2480        }
2481        alen = strlen(eiter->a.host_name);
2482        alen += 4 - (alen & 3);
2483        eiter->len = cpu_to_be16(4 + alen);
2484        size += 4 + alen;
2485
2486        ql_dbg(ql_dbg_disc, vha, 0x201a,
2487            "HostName=%s.\n", eiter->a.host_name);
2488
2489        /* Node Name */
2490        eiter = entries + size;
2491        eiter->type = cpu_to_be16(FDMI_PORT_NODE_NAME);
2492        memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
2493        eiter->len = cpu_to_be16(4 + WWN_SIZE);
2494        size += 4 + WWN_SIZE;
2495
2496        ql_dbg(ql_dbg_disc, vha, 0x20c0,
2497            "Node Name = %016llx.\n", wwn_to_u64(eiter->a.node_name));
2498
2499        /* Port Name */
2500        eiter = entries + size;
2501        eiter->type = cpu_to_be16(FDMI_PORT_NAME);
2502        memcpy(eiter->a.port_name, vha->port_name, WWN_SIZE);
2503        eiter->len = cpu_to_be16(4 + WWN_SIZE);
2504        size += 4 + WWN_SIZE;
2505
2506        ql_dbg(ql_dbg_disc, vha, 0x20c1,
2507            "Port Name = %016llx.\n", wwn_to_u64(eiter->a.port_name));
2508
2509        /* Port Symbolic Name */
2510        eiter = entries + size;
2511        eiter->type = cpu_to_be16(FDMI_PORT_SYM_NAME);
2512        qla2x00_get_sym_node_name(vha, eiter->a.port_sym_name,
2513            sizeof(eiter->a.port_sym_name));
2514        alen = strlen(eiter->a.port_sym_name);
2515        alen += 4 - (alen & 3);
2516        eiter->len = cpu_to_be16(4 + alen);
2517        size += 4 + alen;
2518
2519        ql_dbg(ql_dbg_disc, vha, 0x20c2,
2520            "port symbolic name = %s\n", eiter->a.port_sym_name);
2521
2522        /* Port Type */
2523        eiter = entries + size;
2524        eiter->type = cpu_to_be16(FDMI_PORT_TYPE);
2525        eiter->a.port_type = cpu_to_be32(NS_NX_PORT_TYPE);
2526        eiter->len = cpu_to_be16(4 + 4);
2527        size += 4 + 4;
2528
2529        ql_dbg(ql_dbg_disc, vha, 0x20c3,
2530            "Port Type = %x.\n", eiter->a.port_type);
2531
2532        /* Class of Service  */
2533        eiter = entries + size;
2534        eiter->type = cpu_to_be16(FDMI_PORT_SUPP_COS);
2535        eiter->a.port_supported_cos = cpu_to_be32(FC_CLASS_3);
2536        eiter->len = cpu_to_be16(4 + 4);
2537        size += 4 + 4;
2538
2539        ql_dbg(ql_dbg_disc, vha, 0x20c4,
2540            "Supported COS = %08x\n", eiter->a.port_supported_cos);
2541
2542        /* Port Fabric Name */
2543        eiter = entries + size;
2544        eiter->type = cpu_to_be16(FDMI_PORT_FABRIC_NAME);
2545        memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE);
2546        eiter->len = cpu_to_be16(4 + WWN_SIZE);
2547        size += 4 + WWN_SIZE;
2548
2549        ql_dbg(ql_dbg_disc, vha, 0x20c5,
2550            "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
2551
2552        /* FC4_type */
2553        eiter = entries + size;
2554        eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPE);
2555        eiter->a.port_fc4_type[0] = 0;
2556        eiter->a.port_fc4_type[1] = 0;
2557        eiter->a.port_fc4_type[2] = 1;
2558        eiter->a.port_fc4_type[3] = 0;
2559        eiter->len = cpu_to_be16(4 + 32);
2560        size += 4 + 32;
2561
2562        ql_dbg(ql_dbg_disc, vha, 0x20c6,
2563            "Port Active FC4 Type = %02x %02x.\n",
2564            eiter->a.port_fc4_type[2], eiter->a.port_fc4_type[1]);
2565
2566        if (vha->flags.nvme_enabled) {
2567                eiter->a.port_fc4_type[4] = 0;
2568                eiter->a.port_fc4_type[5] = 0;
2569                eiter->a.port_fc4_type[6] = 1;  /* NVMe type 28h */
2570                ql_dbg(ql_dbg_disc, vha, 0x2120,
2571                    "NVME Port Active FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n",
2572                    eiter->a.port_fc4_type[6]);
2573        }
2574
2575        /* Port State */
2576        eiter = entries + size;
2577        eiter->type = cpu_to_be16(FDMI_PORT_STATE);
2578        eiter->a.port_state = cpu_to_be32(1);
2579        eiter->len = cpu_to_be16(4 + 4);
2580        size += 4 + 4;
2581
2582        ql_dbg(ql_dbg_disc, vha, 0x20c7,
2583            "Port State = %x.\n", eiter->a.port_state);
2584
2585        /* Number of Ports */
2586        eiter = entries + size;
2587        eiter->type = cpu_to_be16(FDMI_PORT_COUNT);
2588        eiter->a.num_ports = cpu_to_be32(1);
2589        eiter->len = cpu_to_be16(4 + 4);
2590        size += 4 + 4;
2591
2592        ql_dbg(ql_dbg_disc, vha, 0x20c8,
2593            "Number of ports = %x.\n", eiter->a.num_ports);
2594
2595        /* Port Id */
2596        eiter = entries + size;
2597        eiter->type = cpu_to_be16(FDMI_PORT_ID);
2598        eiter->a.port_id = cpu_to_be32(vha->d_id.b24);
2599        eiter->len = cpu_to_be16(4 + 4);
2600        size += 4 + 4;
2601
2602        ql_dbg(ql_dbg_disc, vha, 0x201c,
2603            "Port Id = %x.\n", eiter->a.port_id);
2604
2605        /* Update MS request size. */
2606        qla2x00_update_ms_fdmi_iocb(vha, size + 16);
2607
2608        ql_dbg(ql_dbg_disc, vha, 0x2018,
2609            "RPA portname= %8phN size=%d.\n", ct_req->req.rpa.port_name, size);
2610        ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20ca,
2611            entries, size);
2612
2613        /* Execute MS IOCB */
2614        rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2615            sizeof(ms_iocb_entry_t));
2616        if (rval != QLA_SUCCESS) {
2617                /*EMPTY*/
2618                ql_dbg(ql_dbg_disc, vha, 0x20cb,
2619                    "RPA FDMI v2 issue IOCB failed (%d).\n", rval);
2620        } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") !=
2621            QLA_SUCCESS) {
2622                rval = QLA_FUNCTION_FAILED;
2623                if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
2624                    ct_rsp->header.explanation_code ==
2625                    CT_EXPL_ALREADY_REGISTERED) {
2626                        ql_dbg(ql_dbg_disc, vha, 0x20ce,
2627                            "RPA FDMI v2 already registered\n");
2628                        rval = QLA_ALREADY_REGISTERED;
2629                } else {
2630                        ql_dbg(ql_dbg_disc, vha, 0x2020,
2631                            "RPA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
2632                            ct_rsp->header.reason_code,
2633                            ct_rsp->header.explanation_code);
2634                }
2635        } else {
2636                ql_dbg(ql_dbg_disc, vha, 0x20cc,
2637                    "RPA FDMI V2 exiting normally.\n");
2638        }
2639
2640        return rval;
2641}
2642
2643/**
2644 * qla2x00_fdmi_register() -
2645 * @vha: HA context
2646 *
2647 * Returns 0 on success.
2648 */
2649int
2650qla2x00_fdmi_register(scsi_qla_host_t *vha)
2651{
2652        int rval = QLA_FUNCTION_FAILED;
2653        struct qla_hw_data *ha = vha->hw;
2654
2655        if (IS_QLA2100(ha) || IS_QLA2200(ha) ||
2656            IS_QLAFX00(ha))
2657                return QLA_FUNCTION_FAILED;
2658
2659        rval = qla2x00_mgmt_svr_login(vha);
2660        if (rval)
2661                return rval;
2662
2663        rval = qla2x00_fdmiv2_rhba(vha);
2664        if (rval) {
2665                if (rval != QLA_ALREADY_REGISTERED)
2666                        goto try_fdmi;
2667
2668                rval = qla2x00_fdmi_dhba(vha);
2669                if (rval)
2670                        goto try_fdmi;
2671
2672                rval = qla2x00_fdmiv2_rhba(vha);
2673                if (rval)
2674                        goto try_fdmi;
2675        }
2676        rval = qla2x00_fdmiv2_rpa(vha);
2677        if (rval)
2678                goto try_fdmi;
2679
2680        goto out;
2681
2682try_fdmi:
2683        rval = qla2x00_fdmi_rhba(vha);
2684        if (rval) {
2685                if (rval != QLA_ALREADY_REGISTERED)
2686                        return rval;
2687
2688                rval = qla2x00_fdmi_dhba(vha);
2689                if (rval)
2690                        return rval;
2691
2692                rval = qla2x00_fdmi_rhba(vha);
2693                if (rval)
2694                        return rval;
2695        }
2696        rval = qla2x00_fdmi_rpa(vha);
2697out:
2698        return rval;
2699}
2700
2701/**
2702 * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
2703 * @vha: HA context
2704 * @list: switch info entries to populate
2705 *
2706 * Returns 0 on success.
2707 */
2708int
2709qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
2710{
2711        int             rval = QLA_SUCCESS;
2712        uint16_t        i;
2713        struct qla_hw_data *ha = vha->hw;
2714        ms_iocb_entry_t *ms_pkt;
2715        struct ct_sns_req       *ct_req;
2716        struct ct_sns_rsp       *ct_rsp;
2717        struct ct_arg arg;
2718
2719        if (!IS_IIDMA_CAPABLE(ha))
2720                return QLA_FUNCTION_FAILED;
2721
2722        arg.iocb = ha->ms_iocb;
2723        arg.req_dma = ha->ct_sns_dma;
2724        arg.rsp_dma = ha->ct_sns_dma;
2725        arg.req_size = GFPN_ID_REQ_SIZE;
2726        arg.rsp_size = GFPN_ID_RSP_SIZE;
2727        arg.nport_handle = NPH_SNS;
2728
2729        for (i = 0; i < ha->max_fibre_devices; i++) {
2730                /* Issue GFPN_ID */
2731                /* Prepare common MS IOCB */
2732                ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
2733
2734                /* Prepare CT request */
2735                ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD,
2736                    GFPN_ID_RSP_SIZE);
2737                ct_rsp = &ha->ct_sns->p.rsp;
2738
2739                /* Prepare CT arguments -- port_id */
2740                ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
2741                ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
2742                ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
2743
2744                /* Execute MS IOCB */
2745                rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2746                    sizeof(ms_iocb_entry_t));
2747                if (rval != QLA_SUCCESS) {
2748                        /*EMPTY*/
2749                        ql_dbg(ql_dbg_disc, vha, 0x2023,
2750                            "GFPN_ID issue IOCB failed (%d).\n", rval);
2751                        break;
2752                } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
2753                    "GFPN_ID") != QLA_SUCCESS) {
2754                        rval = QLA_FUNCTION_FAILED;
2755                        break;
2756                } else {
2757                        /* Save fabric portname */
2758                        memcpy(list[i].fabric_port_name,
2759                            ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
2760                }
2761
2762                /* Last device exit. */
2763                if (list[i].d_id.b.rsvd_1 != 0)
2764                        break;
2765        }
2766
2767        return (rval);
2768}
2769
2770
2771static inline struct ct_sns_req *
2772qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
2773    uint16_t rsp_size)
2774{
2775        memset(p, 0, sizeof(struct ct_sns_pkt));
2776
2777        p->p.req.header.revision = 0x01;
2778        p->p.req.header.gs_type = 0xFA;
2779        p->p.req.header.gs_subtype = 0x01;
2780        p->p.req.command = cpu_to_be16(cmd);
2781        p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
2782
2783        return &p->p.req;
2784}
2785
2786static uint16_t
2787qla2x00_port_speed_capability(uint16_t speed)
2788{
2789        switch (speed) {
2790        case BIT_15:
2791                return PORT_SPEED_1GB;
2792        case BIT_14:
2793                return PORT_SPEED_2GB;
2794        case BIT_13:
2795                return PORT_SPEED_4GB;
2796        case BIT_12:
2797                return PORT_SPEED_10GB;
2798        case BIT_11:
2799                return PORT_SPEED_8GB;
2800        case BIT_10:
2801                return PORT_SPEED_16GB;
2802        case BIT_8:
2803                return PORT_SPEED_32GB;
2804        case BIT_7:
2805                return PORT_SPEED_64GB;
2806        default:
2807                return PORT_SPEED_UNKNOWN;
2808        }
2809}
2810
2811/**
2812 * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
2813 * @vha: HA context
2814 * @list: switch info entries to populate
2815 *
2816 * Returns 0 on success.
2817 */
2818int
2819qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
2820{
2821        int             rval;
2822        uint16_t        i;
2823        struct qla_hw_data *ha = vha->hw;
2824        ms_iocb_entry_t *ms_pkt;
2825        struct ct_sns_req       *ct_req;
2826        struct ct_sns_rsp       *ct_rsp;
2827        struct ct_arg arg;
2828
2829        if (!IS_IIDMA_CAPABLE(ha))
2830                return QLA_FUNCTION_FAILED;
2831        if (!ha->flags.gpsc_supported)
2832                return QLA_FUNCTION_FAILED;
2833
2834        rval = qla2x00_mgmt_svr_login(vha);
2835        if (rval)
2836                return rval;
2837
2838        arg.iocb = ha->ms_iocb;
2839        arg.req_dma = ha->ct_sns_dma;
2840        arg.rsp_dma = ha->ct_sns_dma;
2841        arg.req_size = GPSC_REQ_SIZE;
2842        arg.rsp_size = GPSC_RSP_SIZE;
2843        arg.nport_handle = vha->mgmt_svr_loop_id;
2844
2845        for (i = 0; i < ha->max_fibre_devices; i++) {
2846                /* Issue GFPN_ID */
2847                /* Prepare common MS IOCB */
2848                ms_pkt = qla24xx_prep_ms_iocb(vha, &arg);
2849
2850                /* Prepare CT request */
2851                ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD,
2852                    GPSC_RSP_SIZE);
2853                ct_rsp = &ha->ct_sns->p.rsp;
2854
2855                /* Prepare CT arguments -- port_name */
2856                memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
2857                    WWN_SIZE);
2858
2859                /* Execute MS IOCB */
2860                rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2861                    sizeof(ms_iocb_entry_t));
2862                if (rval != QLA_SUCCESS) {
2863                        /*EMPTY*/
2864                        ql_dbg(ql_dbg_disc, vha, 0x2059,
2865                            "GPSC issue IOCB failed (%d).\n", rval);
2866                } else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
2867                    "GPSC")) != QLA_SUCCESS) {
2868                        /* FM command unsupported? */
2869                        if (rval == QLA_INVALID_COMMAND &&
2870                            (ct_rsp->header.reason_code ==
2871                                CT_REASON_INVALID_COMMAND_CODE ||
2872                             ct_rsp->header.reason_code ==
2873                                CT_REASON_COMMAND_UNSUPPORTED)) {
2874                                ql_dbg(ql_dbg_disc, vha, 0x205a,
2875                                    "GPSC command unsupported, disabling "
2876                                    "query.\n");
2877                                ha->flags.gpsc_supported = 0;
2878                                rval = QLA_FUNCTION_FAILED;
2879                                break;
2880                        }
2881                        rval = QLA_FUNCTION_FAILED;
2882                } else {
2883                        list->fp_speed = qla2x00_port_speed_capability(
2884                            be16_to_cpu(ct_rsp->rsp.gpsc.speed));
2885                        ql_dbg(ql_dbg_disc, vha, 0x205b,
2886                            "GPSC ext entry - fpn "
2887                            "%8phN speeds=%04x speed=%04x.\n",
2888                            list[i].fabric_port_name,
2889                            be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
2890                            be16_to_cpu(ct_rsp->rsp.gpsc.speed));
2891                }
2892
2893                /* Last device exit. */
2894                if (list[i].d_id.b.rsvd_1 != 0)
2895                        break;
2896        }
2897
2898        return (rval);
2899}
2900
2901/**
2902 * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
2903 *
2904 * @vha: HA context
2905 * @list: switch info entries to populate
2906 *
2907 */
2908void
2909qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
2910{
2911        int             rval;
2912        uint16_t        i;
2913
2914        ms_iocb_entry_t *ms_pkt;
2915        struct ct_sns_req       *ct_req;
2916        struct ct_sns_rsp       *ct_rsp;
2917        struct qla_hw_data *ha = vha->hw;
2918        uint8_t fcp_scsi_features = 0;
2919        struct ct_arg arg;
2920
2921        for (i = 0; i < ha->max_fibre_devices; i++) {
2922                /* Set default FC4 Type as UNKNOWN so the default is to
2923                 * Process this port */
2924                list[i].fc4_type = FC4_TYPE_UNKNOWN;
2925
2926                /* Do not attempt GFF_ID if we are not FWI_2 capable */
2927                if (!IS_FWI2_CAPABLE(ha))
2928                        continue;
2929
2930                arg.iocb = ha->ms_iocb;
2931                arg.req_dma = ha->ct_sns_dma;
2932                arg.rsp_dma = ha->ct_sns_dma;
2933                arg.req_size = GFF_ID_REQ_SIZE;
2934                arg.rsp_size = GFF_ID_RSP_SIZE;
2935                arg.nport_handle = NPH_SNS;
2936
2937                /* Prepare common MS IOCB */
2938                ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
2939
2940                /* Prepare CT request */
2941                ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD,
2942                    GFF_ID_RSP_SIZE);
2943                ct_rsp = &ha->ct_sns->p.rsp;
2944
2945                /* Prepare CT arguments -- port_id */
2946                ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
2947                ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
2948                ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
2949
2950                /* Execute MS IOCB */
2951                rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2952                   sizeof(ms_iocb_entry_t));
2953
2954                if (rval != QLA_SUCCESS) {
2955                        ql_dbg(ql_dbg_disc, vha, 0x205c,
2956                            "GFF_ID issue IOCB failed (%d).\n", rval);
2957                } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
2958                               "GFF_ID") != QLA_SUCCESS) {
2959                        ql_dbg(ql_dbg_disc, vha, 0x205d,
2960                            "GFF_ID IOCB status had a failure status code.\n");
2961                } else {
2962                        fcp_scsi_features =
2963                           ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
2964                        fcp_scsi_features &= 0x0f;
2965
2966                        if (fcp_scsi_features)
2967                                list[i].fc4_type = FC4_TYPE_FCP_SCSI;
2968                        else
2969                                list[i].fc4_type = FC4_TYPE_OTHER;
2970
2971                        list[i].fc4f_nvme =
2972                            ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
2973                        list[i].fc4f_nvme &= 0xf;
2974                }
2975
2976                /* Last device exit. */
2977                if (list[i].d_id.b.rsvd_1 != 0)
2978                        break;
2979        }
2980}
2981
2982int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport)
2983{
2984        struct qla_work_evt *e;
2985
2986        e = qla2x00_alloc_work(vha, QLA_EVT_GPSC);
2987        if (!e)
2988                return QLA_FUNCTION_FAILED;
2989
2990        e->u.fcport.fcport = fcport;
2991        fcport->flags |= FCF_ASYNC_ACTIVE;
2992        return qla2x00_post_work(vha, e);
2993}
2994
2995void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea)
2996{
2997        struct fc_port *fcport = ea->fcport;
2998
2999        ql_dbg(ql_dbg_disc, vha, 0x20d8,
3000            "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
3001            __func__, fcport->port_name, fcport->disc_state,
3002            fcport->fw_login_state, ea->rc, ea->sp->gen2, fcport->login_gen,
3003            ea->sp->gen2, fcport->rscn_gen|ea->sp->gen1, fcport->loop_id);
3004
3005        if (fcport->disc_state == DSC_DELETE_PEND)
3006                return;
3007
3008        if (ea->sp->gen2 != fcport->login_gen) {
3009                /* target side must have changed it. */
3010                ql_dbg(ql_dbg_disc, vha, 0x20d3,
3011                    "%s %8phC generation changed\n",
3012                    __func__, fcport->port_name);
3013                return;
3014        } else if (ea->sp->gen1 != fcport->rscn_gen) {
3015                return;
3016        }
3017
3018        qla_post_iidma_work(vha, fcport);
3019}
3020
3021static void qla24xx_async_gpsc_sp_done(void *s, int res)
3022{
3023        struct srb *sp = s;
3024        struct scsi_qla_host *vha = sp->vha;
3025        struct qla_hw_data *ha = vha->hw;
3026        fc_port_t *fcport = sp->fcport;
3027        struct ct_sns_rsp       *ct_rsp;
3028        struct event_arg ea;
3029
3030        ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
3031
3032        ql_dbg(ql_dbg_disc, vha, 0x2053,
3033            "Async done-%s res %x, WWPN %8phC \n",
3034            sp->name, res, fcport->port_name);
3035
3036        if (res == QLA_FUNCTION_TIMEOUT)
3037                return;
3038
3039        if (res == (DID_ERROR << 16)) {
3040                /* entry status error */
3041                goto done;
3042        } else if (res) {
3043                if ((ct_rsp->header.reason_code ==
3044                         CT_REASON_INVALID_COMMAND_CODE) ||
3045                        (ct_rsp->header.reason_code ==
3046                        CT_REASON_COMMAND_UNSUPPORTED)) {
3047                        ql_dbg(ql_dbg_disc, vha, 0x2019,
3048                            "GPSC command unsupported, disabling query.\n");
3049                        ha->flags.gpsc_supported = 0;
3050                        goto done;
3051                }
3052        } else {
3053                fcport->fp_speed = qla2x00_port_speed_capability(
3054                    be16_to_cpu(ct_rsp->rsp.gpsc.speed));
3055
3056                ql_dbg(ql_dbg_disc, vha, 0x2054,
3057                    "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n",
3058                    sp->name, fcport->fabric_port_name,
3059                    be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
3060                    be16_to_cpu(ct_rsp->rsp.gpsc.speed));
3061        }
3062        memset(&ea, 0, sizeof(ea));
3063        ea.event = FCME_GPSC_DONE;
3064        ea.rc = res;
3065        ea.fcport = fcport;
3066        ea.sp = sp;
3067        qla2x00_fcport_event_handler(vha, &ea);
3068
3069done:
3070        sp->free(sp);
3071}
3072
3073int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport)
3074{
3075        int rval = QLA_FUNCTION_FAILED;
3076        struct ct_sns_req       *ct_req;
3077        srb_t *sp;
3078
3079        if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
3080                return rval;
3081
3082        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
3083        if (!sp)
3084                goto done;
3085
3086        sp->type = SRB_CT_PTHRU_CMD;
3087        sp->name = "gpsc";
3088        sp->gen1 = fcport->rscn_gen;
3089        sp->gen2 = fcport->login_gen;
3090
3091        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
3092
3093        /* CT_IU preamble  */
3094        ct_req = qla24xx_prep_ct_fm_req(fcport->ct_desc.ct_sns, GPSC_CMD,
3095                GPSC_RSP_SIZE);
3096
3097        /* GPSC req */
3098        memcpy(ct_req->req.gpsc.port_name, fcport->fabric_port_name,
3099                WWN_SIZE);
3100
3101        sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
3102        sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
3103        sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
3104        sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
3105        sp->u.iocb_cmd.u.ctarg.req_size = GPSC_REQ_SIZE;
3106        sp->u.iocb_cmd.u.ctarg.rsp_size = GPSC_RSP_SIZE;
3107        sp->u.iocb_cmd.u.ctarg.nport_handle = vha->mgmt_svr_loop_id;
3108
3109        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
3110        sp->done = qla24xx_async_gpsc_sp_done;
3111
3112        ql_dbg(ql_dbg_disc, vha, 0x205e,
3113            "Async-%s %8phC hdl=%x loopid=%x portid=%02x%02x%02x.\n",
3114            sp->name, fcport->port_name, sp->handle,
3115            fcport->loop_id, fcport->d_id.b.domain,
3116            fcport->d_id.b.area, fcport->d_id.b.al_pa);
3117
3118        rval = qla2x00_start_sp(sp);
3119        if (rval != QLA_SUCCESS)
3120                goto done_free_sp;
3121        return rval;
3122
3123done_free_sp:
3124        sp->free(sp);
3125        fcport->flags &= ~FCF_ASYNC_SENT;
3126done:
3127        fcport->flags &= ~FCF_ASYNC_ACTIVE;
3128        return rval;
3129}
3130
3131int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id)
3132{
3133        struct qla_work_evt *e;
3134
3135        if (test_bit(UNLOADING, &vha->dpc_flags))
3136                return 0;
3137
3138        e = qla2x00_alloc_work(vha, QLA_EVT_GPNID);
3139        if (!e)
3140                return QLA_FUNCTION_FAILED;
3141
3142        e->u.gpnid.id = *id;
3143        return qla2x00_post_work(vha, e);
3144}
3145
3146void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp)
3147{
3148        struct srb_iocb *c = &sp->u.iocb_cmd;
3149
3150        switch (sp->type) {
3151        case SRB_ELS_DCMD:
3152                if (c->u.els_plogi.els_plogi_pyld)
3153                        dma_free_coherent(&vha->hw->pdev->dev,
3154                            c->u.els_plogi.tx_size,
3155                            c->u.els_plogi.els_plogi_pyld,
3156                            c->u.els_plogi.els_plogi_pyld_dma);
3157
3158                if (c->u.els_plogi.els_resp_pyld)
3159                        dma_free_coherent(&vha->hw->pdev->dev,
3160                            c->u.els_plogi.rx_size,
3161                            c->u.els_plogi.els_resp_pyld,
3162                            c->u.els_plogi.els_resp_pyld_dma);
3163                break;
3164        case SRB_CT_PTHRU_CMD:
3165        default:
3166                if (sp->u.iocb_cmd.u.ctarg.req) {
3167                        dma_free_coherent(&vha->hw->pdev->dev,
3168                            sizeof(struct ct_sns_pkt),
3169                            sp->u.iocb_cmd.u.ctarg.req,
3170                            sp->u.iocb_cmd.u.ctarg.req_dma);
3171                        sp->u.iocb_cmd.u.ctarg.req = NULL;
3172                }
3173
3174                if (sp->u.iocb_cmd.u.ctarg.rsp) {
3175                        dma_free_coherent(&vha->hw->pdev->dev,
3176                            sizeof(struct ct_sns_pkt),
3177                            sp->u.iocb_cmd.u.ctarg.rsp,
3178                            sp->u.iocb_cmd.u.ctarg.rsp_dma);
3179                        sp->u.iocb_cmd.u.ctarg.rsp = NULL;
3180                }
3181                break;
3182        }
3183
3184        sp->free(sp);
3185}
3186
3187void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
3188{
3189        fc_port_t *fcport, *conflict, *t;
3190        u16 data[2];
3191
3192        ql_dbg(ql_dbg_disc, vha, 0xffff,
3193            "%s %d port_id: %06x\n",
3194            __func__, __LINE__, ea->id.b24);
3195
3196        if (ea->rc) {
3197                /* cable is disconnected */
3198                list_for_each_entry_safe(fcport, t, &vha->vp_fcports, list) {
3199                        if (fcport->d_id.b24 == ea->id.b24)
3200                                fcport->scan_state = QLA_FCPORT_SCAN;
3201
3202                        qlt_schedule_sess_for_deletion(fcport);
3203                }
3204        } else {
3205                /* cable is connected */
3206                fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1);
3207                if (fcport) {
3208                        list_for_each_entry_safe(conflict, t, &vha->vp_fcports,
3209                            list) {
3210                                if ((conflict->d_id.b24 == ea->id.b24) &&
3211                                    (fcport != conflict))
3212                                        /*
3213                                         * 2 fcports with conflict Nport ID or
3214                                         * an existing fcport is having nport ID
3215                                         * conflict with new fcport.
3216                                         */
3217
3218                                        conflict->scan_state = QLA_FCPORT_SCAN;
3219
3220                                qlt_schedule_sess_for_deletion(conflict);
3221                        }
3222
3223                        fcport->scan_needed = 0;
3224                        fcport->rscn_gen++;
3225                        fcport->scan_state = QLA_FCPORT_FOUND;
3226                        fcport->flags |= FCF_FABRIC_DEVICE;
3227                        if (fcport->login_retry == 0) {
3228                                fcport->login_retry =
3229                                        vha->hw->login_retry_count;
3230                                ql_dbg(ql_dbg_disc, vha, 0xffff,
3231                                    "Port login retry %8phN, lid 0x%04x cnt=%d.\n",
3232                                    fcport->port_name, fcport->loop_id,
3233                                    fcport->login_retry);
3234                        }
3235                        switch (fcport->disc_state) {
3236                        case DSC_LOGIN_COMPLETE:
3237                                /* recheck session is still intact. */
3238                                ql_dbg(ql_dbg_disc, vha, 0x210d,
3239                                    "%s %d %8phC revalidate session with ADISC\n",
3240                                    __func__, __LINE__, fcport->port_name);
3241                                data[0] = data[1] = 0;
3242                                qla2x00_post_async_adisc_work(vha, fcport,
3243                                    data);
3244                                break;
3245                        case DSC_DELETED:
3246                                ql_dbg(ql_dbg_disc, vha, 0x210d,
3247                                    "%s %d %8phC login\n", __func__, __LINE__,
3248                                    fcport->port_name);
3249                                fcport->d_id = ea->id;
3250                                qla24xx_fcport_handle_login(vha, fcport);
3251                                break;
3252                        case DSC_DELETE_PEND:
3253                                fcport->d_id = ea->id;
3254                                break;
3255                        default:
3256                                fcport->d_id = ea->id;
3257                                break;
3258                        }
3259                } else {
3260                        list_for_each_entry_safe(conflict, t, &vha->vp_fcports,
3261                            list) {
3262                                if (conflict->d_id.b24 == ea->id.b24) {
3263                                        /* 2 fcports with conflict Nport ID or
3264                                         * an existing fcport is having nport ID
3265                                         * conflict with new fcport.
3266                                         */
3267                                        ql_dbg(ql_dbg_disc, vha, 0xffff,
3268                                            "%s %d %8phC DS %d\n",
3269                                            __func__, __LINE__,
3270                                            conflict->port_name,
3271                                            conflict->disc_state);
3272
3273                                        conflict->scan_state = QLA_FCPORT_SCAN;
3274                                        qlt_schedule_sess_for_deletion(conflict);
3275                                }
3276                        }
3277
3278                        /* create new fcport */
3279                        ql_dbg(ql_dbg_disc, vha, 0x2065,
3280                            "%s %d %8phC post new sess\n",
3281                            __func__, __LINE__, ea->port_name);
3282                        qla24xx_post_newsess_work(vha, &ea->id,
3283                            ea->port_name, NULL, NULL, FC4_TYPE_UNKNOWN);
3284                }
3285        }
3286}
3287
3288static void qla2x00_async_gpnid_sp_done(void *s, int res)
3289{
3290        struct srb *sp = s;
3291        struct scsi_qla_host *vha = sp->vha;
3292        struct ct_sns_req *ct_req =
3293            (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
3294        struct ct_sns_rsp *ct_rsp =
3295            (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
3296        struct event_arg ea;
3297        struct qla_work_evt *e;
3298        unsigned long flags;
3299
3300        if (res)
3301                ql_dbg(ql_dbg_disc, vha, 0x2066,
3302                    "Async done-%s fail res %x rscn gen %d ID %3phC. %8phC\n",
3303                    sp->name, res, sp->gen1, ct_req->req.port_id.port_id,
3304                    ct_rsp->rsp.gpn_id.port_name);
3305        else
3306                ql_dbg(ql_dbg_disc, vha, 0x2066,
3307                    "Async done-%s good rscn gen %d ID %3phC. %8phC\n",
3308                    sp->name, sp->gen1, ct_req->req.port_id.port_id,
3309                    ct_rsp->rsp.gpn_id.port_name);
3310
3311        memset(&ea, 0, sizeof(ea));
3312        memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
3313        ea.sp = sp;
3314        ea.id.b.domain = ct_req->req.port_id.port_id[0];
3315        ea.id.b.area = ct_req->req.port_id.port_id[1];
3316        ea.id.b.al_pa = ct_req->req.port_id.port_id[2];
3317        ea.rc = res;
3318        ea.event = FCME_GPNID_DONE;
3319
3320        spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
3321        list_del(&sp->elem);
3322        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3323
3324        if (res) {
3325                if (res == QLA_FUNCTION_TIMEOUT) {
3326                        qla24xx_post_gpnid_work(sp->vha, &ea.id);
3327                        sp->free(sp);
3328                        return;
3329                }
3330        } else if (sp->gen1) {
3331                /* There was another RSCN for this Nport ID */
3332                qla24xx_post_gpnid_work(sp->vha, &ea.id);
3333                sp->free(sp);
3334                return;
3335        }
3336
3337        qla2x00_fcport_event_handler(vha, &ea);
3338
3339        e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
3340        if (!e) {
3341                /* please ignore kernel warning. otherwise, we have mem leak. */
3342                if (sp->u.iocb_cmd.u.ctarg.req) {
3343                        dma_free_coherent(&vha->hw->pdev->dev,
3344                                sp->u.iocb_cmd.u.ctarg.req_allocated_size,
3345                                sp->u.iocb_cmd.u.ctarg.req,
3346                                sp->u.iocb_cmd.u.ctarg.req_dma);
3347                        sp->u.iocb_cmd.u.ctarg.req = NULL;
3348                }
3349                if (sp->u.iocb_cmd.u.ctarg.rsp) {
3350                        dma_free_coherent(&vha->hw->pdev->dev,
3351                                sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
3352                                sp->u.iocb_cmd.u.ctarg.rsp,
3353                                sp->u.iocb_cmd.u.ctarg.rsp_dma);
3354                        sp->u.iocb_cmd.u.ctarg.rsp = NULL;
3355                }
3356
3357                sp->free(sp);
3358                return;
3359        }
3360
3361        e->u.iosb.sp = sp;
3362        qla2x00_post_work(vha, e);
3363}
3364
3365/* Get WWPN with Nport ID. */
3366int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
3367{
3368        int rval = QLA_FUNCTION_FAILED;
3369        struct ct_sns_req       *ct_req;
3370        srb_t *sp, *tsp;
3371        struct ct_sns_pkt *ct_sns;
3372        unsigned long flags;
3373
3374        if (!vha->flags.online)
3375                goto done;
3376
3377        sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
3378        if (!sp)
3379                goto done;
3380
3381        sp->type = SRB_CT_PTHRU_CMD;
3382        sp->name = "gpnid";
3383        sp->u.iocb_cmd.u.ctarg.id = *id;
3384        sp->gen1 = 0;
3385        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
3386
3387        spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
3388        list_for_each_entry(tsp, &vha->gpnid_list, elem) {
3389                if (tsp->u.iocb_cmd.u.ctarg.id.b24 == id->b24) {
3390                        tsp->gen1++;
3391                        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3392                        sp->free(sp);
3393                        goto done;
3394                }
3395        }
3396        list_add_tail(&sp->elem, &vha->gpnid_list);
3397        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3398
3399        sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
3400                sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
3401                GFP_KERNEL);
3402        sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
3403        if (!sp->u.iocb_cmd.u.ctarg.req) {
3404                ql_log(ql_log_warn, vha, 0xd041,
3405                    "Failed to allocate ct_sns request.\n");
3406                goto done_free_sp;
3407        }
3408
3409        sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
3410                sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
3411                GFP_KERNEL);
3412        sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
3413        if (!sp->u.iocb_cmd.u.ctarg.rsp) {
3414                ql_log(ql_log_warn, vha, 0xd042,
3415                    "Failed to allocate ct_sns request.\n");
3416                goto done_free_sp;
3417        }
3418
3419        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
3420        memset(ct_sns, 0, sizeof(*ct_sns));
3421
3422        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
3423        /* CT_IU preamble  */
3424        ct_req = qla2x00_prep_ct_req(ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE);
3425
3426        /* GPN_ID req */
3427        ct_req->req.port_id.port_id[0] = id->b.domain;
3428        ct_req->req.port_id.port_id[1] = id->b.area;
3429        ct_req->req.port_id.port_id[2] = id->b.al_pa;
3430
3431        sp->u.iocb_cmd.u.ctarg.req_size = GPN_ID_REQ_SIZE;
3432        sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_RSP_SIZE;
3433        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
3434
3435        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
3436        sp->done = qla2x00_async_gpnid_sp_done;
3437
3438        ql_dbg(ql_dbg_disc, vha, 0x2067,
3439            "Async-%s hdl=%x ID %3phC.\n", sp->name,
3440            sp->handle, ct_req->req.port_id.port_id);
3441
3442        rval = qla2x00_start_sp(sp);
3443        if (rval != QLA_SUCCESS)
3444                goto done_free_sp;
3445
3446        return rval;
3447
3448done_free_sp:
3449        spin_lock_irqsave(&vha->hw->vport_slock, flags);
3450        list_del(&sp->elem);
3451        spin_unlock_irqrestore(&vha->hw->vport_slock, flags);
3452
3453        if (sp->u.iocb_cmd.u.ctarg.req) {
3454                dma_free_coherent(&vha->hw->pdev->dev,
3455                        sizeof(struct ct_sns_pkt),
3456                        sp->u.iocb_cmd.u.ctarg.req,
3457                        sp->u.iocb_cmd.u.ctarg.req_dma);
3458                sp->u.iocb_cmd.u.ctarg.req = NULL;
3459        }
3460        if (sp->u.iocb_cmd.u.ctarg.rsp) {
3461                dma_free_coherent(&vha->hw->pdev->dev,
3462                        sizeof(struct ct_sns_pkt),
3463                        sp->u.iocb_cmd.u.ctarg.rsp,
3464                        sp->u.iocb_cmd.u.ctarg.rsp_dma);
3465                sp->u.iocb_cmd.u.ctarg.rsp = NULL;
3466        }
3467
3468        sp->free(sp);
3469done:
3470        return rval;
3471}
3472
3473void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
3474{
3475       fc_port_t *fcport = ea->fcport;
3476
3477       qla24xx_post_gnl_work(vha, fcport);
3478}
3479
3480void qla24xx_async_gffid_sp_done(void *s, int res)
3481{
3482       struct srb *sp = s;
3483       struct scsi_qla_host *vha = sp->vha;
3484       fc_port_t *fcport = sp->fcport;
3485       struct ct_sns_rsp *ct_rsp;
3486       struct event_arg ea;
3487
3488       ql_dbg(ql_dbg_disc, vha, 0x2133,
3489           "Async done-%s res %x ID %x. %8phC\n",
3490           sp->name, res, fcport->d_id.b24, fcport->port_name);
3491
3492       fcport->flags &= ~FCF_ASYNC_SENT;
3493       ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
3494       /*
3495        * FC-GS-7, 5.2.3.12 FC-4 Features - format
3496        * The format of the FC-4 Features object, as defined by the FC-4,
3497        * Shall be an array of 4-bit values, one for each type code value
3498        */
3499       if (!res) {
3500               if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) {
3501                       /* w1 b00:03 */
3502                       fcport->fc4_type =
3503                           ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
3504                       fcport->fc4_type &= 0xf;
3505               }
3506
3507               if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) {
3508                       /* w5 [00:03]/28h */
3509                       fcport->fc4f_nvme =
3510                           ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
3511                       fcport->fc4f_nvme &= 0xf;
3512               }
3513       }
3514
3515       memset(&ea, 0, sizeof(ea));
3516       ea.sp = sp;
3517       ea.fcport = sp->fcport;
3518       ea.rc = res;
3519       ea.event = FCME_GFFID_DONE;
3520
3521       qla2x00_fcport_event_handler(vha, &ea);
3522       sp->free(sp);
3523}
3524
3525/* Get FC4 Feature with Nport ID. */
3526int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
3527{
3528        int rval = QLA_FUNCTION_FAILED;
3529        struct ct_sns_req       *ct_req;
3530        srb_t *sp;
3531
3532        if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
3533                return rval;
3534
3535        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
3536        if (!sp)
3537                return rval;
3538
3539        fcport->flags |= FCF_ASYNC_SENT;
3540        sp->type = SRB_CT_PTHRU_CMD;
3541        sp->name = "gffid";
3542        sp->gen1 = fcport->rscn_gen;
3543        sp->gen2 = fcport->login_gen;
3544
3545        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
3546        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
3547
3548        /* CT_IU preamble  */
3549        ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD,
3550            GFF_ID_RSP_SIZE);
3551
3552        ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain;
3553        ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area;
3554        ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
3555
3556        sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
3557        sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
3558        sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
3559        sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
3560        sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE;
3561        sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
3562        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
3563
3564        sp->done = qla24xx_async_gffid_sp_done;
3565
3566        ql_dbg(ql_dbg_disc, vha, 0x2132,
3567            "Async-%s hdl=%x  %8phC.\n", sp->name,
3568            sp->handle, fcport->port_name);
3569
3570        rval = qla2x00_start_sp(sp);
3571        if (rval != QLA_SUCCESS)
3572                goto done_free_sp;
3573
3574        return rval;
3575done_free_sp:
3576        sp->free(sp);
3577        fcport->flags &= ~FCF_ASYNC_SENT;
3578        return rval;
3579}
3580
3581/* GPN_FT + GNN_FT*/
3582static int qla2x00_is_a_vp(scsi_qla_host_t *vha, u64 wwn)
3583{
3584        struct qla_hw_data *ha = vha->hw;
3585        scsi_qla_host_t *vp;
3586        unsigned long flags;
3587        u64 twwn;
3588        int rc = 0;
3589
3590        if (!ha->num_vhosts)
3591                return 0;
3592
3593        spin_lock_irqsave(&ha->vport_slock, flags);
3594        list_for_each_entry(vp, &ha->vp_list, list) {
3595                twwn = wwn_to_u64(vp->port_name);
3596                if (wwn == twwn) {
3597                        rc = 1;
3598                        break;
3599                }
3600        }
3601        spin_unlock_irqrestore(&ha->vport_slock, flags);
3602
3603        return rc;
3604}
3605
3606void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
3607{
3608        fc_port_t *fcport;
3609        u32 i, rc;
3610        bool found;
3611        struct fab_scan_rp *rp, *trp;
3612        unsigned long flags;
3613        u8 recheck = 0;
3614        u16 dup = 0, dup_cnt = 0;
3615
3616        ql_dbg(ql_dbg_disc, vha, 0xffff,
3617            "%s enter\n", __func__);
3618
3619        if (sp->gen1 != vha->hw->base_qpair->chip_reset) {
3620                ql_dbg(ql_dbg_disc, vha, 0xffff,
3621                    "%s scan stop due to chip reset %x/%x\n",
3622                    sp->name, sp->gen1, vha->hw->base_qpair->chip_reset);
3623                goto out;
3624        }
3625
3626        rc = sp->rc;
3627        if (rc) {
3628                vha->scan.scan_retry++;
3629                if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
3630                        set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
3631                        set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
3632                } else {
3633                        ql_dbg(ql_dbg_disc, vha, 0xffff,
3634                            "Fabric scan failed on all retries.\n");
3635                }
3636                goto out;
3637        }
3638        vha->scan.scan_retry = 0;
3639
3640        list_for_each_entry(fcport, &vha->vp_fcports, list)
3641                fcport->scan_state = QLA_FCPORT_SCAN;
3642
3643        for (i = 0; i < vha->hw->max_fibre_devices; i++) {
3644                u64 wwn;
3645                int k;
3646
3647                rp = &vha->scan.l[i];
3648                found = false;
3649
3650                wwn = wwn_to_u64(rp->port_name);
3651                if (wwn == 0)
3652                        continue;
3653
3654                /* Remove duplicate NPORT ID entries from switch data base */
3655                for (k = i + 1; k < vha->hw->max_fibre_devices; k++) {
3656                        trp = &vha->scan.l[k];
3657                        if (rp->id.b24 == trp->id.b24) {
3658                                dup = 1;
3659                                dup_cnt++;
3660                                ql_dbg(ql_dbg_disc + ql_dbg_verbose,
3661                                    vha, 0xffff,
3662                                    "Detected duplicate NPORT ID from switch data base: ID %06x WWN %8phN WWN %8phN\n",
3663                                    rp->id.b24, rp->port_name, trp->port_name);
3664                                memset(trp, 0, sizeof(*trp));
3665                        }
3666                }
3667
3668                if (!memcmp(rp->port_name, vha->port_name, WWN_SIZE))
3669                        continue;
3670
3671                /* Bypass reserved domain fields. */
3672                if ((rp->id.b.domain & 0xf0) == 0xf0)
3673                        continue;
3674
3675                /* Bypass virtual ports of the same host. */
3676                if (qla2x00_is_a_vp(vha, wwn))
3677                        continue;
3678
3679                list_for_each_entry(fcport, &vha->vp_fcports, list) {
3680                        if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE))
3681                                continue;
3682                        fcport->scan_needed = 0;
3683                        fcport->scan_state = QLA_FCPORT_FOUND;
3684                        found = true;
3685                        /*
3686                         * If device was not a fabric device before.
3687                         */
3688                        if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
3689                                qla2x00_clear_loop_id(fcport);
3690                                fcport->flags |= FCF_FABRIC_DEVICE;
3691                        } else if (fcport->d_id.b24 != rp->id.b24) {
3692                                qlt_schedule_sess_for_deletion(fcport);
3693                        }
3694                        fcport->d_id.b24 = rp->id.b24;
3695                        break;
3696                }
3697
3698                if (!found) {
3699                        ql_dbg(ql_dbg_disc, vha, 0xffff,
3700                            "%s %d %8phC post new sess\n",
3701                            __func__, __LINE__, rp->port_name);
3702                        qla24xx_post_newsess_work(vha, &rp->id, rp->port_name,
3703                            rp->node_name, NULL, rp->fc4type);
3704                }
3705        }
3706
3707        if (dup) {
3708                ql_log(ql_log_warn, vha, 0xffff,
3709                    "Detected %d duplicate NPORT ID(s) from switch data base\n",
3710                    dup_cnt);
3711        }
3712
3713        /*
3714         * Logout all previous fabric dev marked lost, except FCP2 devices.
3715         */
3716        list_for_each_entry(fcport, &vha->vp_fcports, list) {
3717                if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
3718                        fcport->scan_needed = 0;
3719                        continue;
3720                }
3721
3722                if (fcport->scan_state != QLA_FCPORT_FOUND) {
3723                        fcport->scan_needed = 0;
3724                        if ((qla_dual_mode_enabled(vha) ||
3725                                qla_ini_mode_enabled(vha)) &&
3726                            atomic_read(&fcport->state) == FCS_ONLINE) {
3727                                if (fcport->loop_id != FC_NO_LOOP_ID) {
3728                                        if (fcport->flags & FCF_FCP2_DEVICE)
3729                                                fcport->logout_on_delete = 0;
3730
3731                                        ql_dbg(ql_dbg_disc, vha, 0x20f0,
3732                                            "%s %d %8phC post del sess\n",
3733                                            __func__, __LINE__,
3734                                            fcport->port_name);
3735
3736                                        qlt_schedule_sess_for_deletion(fcport);
3737                                        continue;
3738                                }
3739                        }
3740                } else {
3741                        if (fcport->scan_needed ||
3742                            fcport->disc_state != DSC_LOGIN_COMPLETE) {
3743                                if (fcport->login_retry == 0) {
3744                                        fcport->login_retry =
3745                                                vha->hw->login_retry_count;
3746                                        ql_dbg(ql_dbg_disc, vha, 0x20a3,
3747                                            "Port login retry %8phN, lid 0x%04x retry cnt=%d.\n",
3748                                            fcport->port_name, fcport->loop_id,
3749                                            fcport->login_retry);
3750                                }
3751                                fcport->scan_needed = 0;
3752                                qla24xx_fcport_handle_login(vha, fcport);
3753                        }
3754                }
3755        }
3756
3757        recheck = 1;
3758out:
3759        qla24xx_sp_unmap(vha, sp);
3760        spin_lock_irqsave(&vha->work_lock, flags);
3761        vha->scan.scan_flags &= ~SF_SCANNING;
3762        spin_unlock_irqrestore(&vha->work_lock, flags);
3763
3764        if (recheck) {
3765                list_for_each_entry(fcport, &vha->vp_fcports, list) {
3766                        if (fcport->scan_needed) {
3767                                set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
3768                                set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
3769                                break;
3770                        }
3771                }
3772        }
3773}
3774
3775static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha,
3776    srb_t *sp, int cmd)
3777{
3778        struct qla_work_evt *e;
3779
3780        if (cmd != QLA_EVT_GPNFT_DONE && cmd != QLA_EVT_GNNFT_DONE)
3781                return QLA_PARAMETER_ERROR;
3782
3783        e = qla2x00_alloc_work(vha, cmd);
3784        if (!e)
3785                return QLA_FUNCTION_FAILED;
3786
3787        e->u.iosb.sp = sp;
3788
3789        return qla2x00_post_work(vha, e);
3790}
3791
3792static int qla2x00_post_nvme_gpnft_work(struct scsi_qla_host *vha,
3793    srb_t *sp, int cmd)
3794{
3795        struct qla_work_evt *e;
3796
3797        if (cmd != QLA_EVT_GPNFT)
3798                return QLA_PARAMETER_ERROR;
3799
3800        e = qla2x00_alloc_work(vha, cmd);
3801        if (!e)
3802                return QLA_FUNCTION_FAILED;
3803
3804        e->u.gpnft.fc4_type = FC4_TYPE_NVME;
3805        e->u.gpnft.sp = sp;
3806
3807        return qla2x00_post_work(vha, e);
3808}
3809
3810static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
3811        struct srb *sp)
3812{
3813        struct qla_hw_data *ha = vha->hw;
3814        int num_fibre_dev = ha->max_fibre_devices;
3815        struct ct_sns_req *ct_req =
3816                (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
3817        struct ct_sns_gpnft_rsp *ct_rsp =
3818                (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
3819        struct ct_sns_gpn_ft_data *d;
3820        struct fab_scan_rp *rp;
3821        u16 cmd = be16_to_cpu(ct_req->command);
3822        u8 fc4_type = sp->gen2;
3823        int i, j, k;
3824        port_id_t id;
3825        u8 found;
3826        u64 wwn;
3827
3828        j = 0;
3829        for (i = 0; i < num_fibre_dev; i++) {
3830                d  = &ct_rsp->entries[i];
3831
3832                id.b.rsvd_1 = 0;
3833                id.b.domain = d->port_id[0];
3834                id.b.area   = d->port_id[1];
3835                id.b.al_pa  = d->port_id[2];
3836                wwn = wwn_to_u64(d->port_name);
3837
3838                if (id.b24 == 0 || wwn == 0)
3839                        continue;
3840
3841                if (fc4_type == FC4_TYPE_FCP_SCSI) {
3842                        if (cmd == GPN_FT_CMD) {
3843                                rp = &vha->scan.l[j];
3844                                rp->id = id;
3845                                memcpy(rp->port_name, d->port_name, 8);
3846                                j++;
3847                                rp->fc4type = FS_FC4TYPE_FCP;
3848                        } else {
3849                                for (k = 0; k < num_fibre_dev; k++) {
3850                                        rp = &vha->scan.l[k];
3851                                        if (id.b24 == rp->id.b24) {
3852                                                memcpy(rp->node_name,
3853                                                    d->port_name, 8);
3854                                                break;
3855                                        }
3856                                }
3857                        }
3858                } else {
3859                        /* Search if the fibre device supports FC4_TYPE_NVME */
3860                        if (cmd == GPN_FT_CMD) {
3861                                found = 0;
3862
3863                                for (k = 0; k < num_fibre_dev; k++) {
3864                                        rp = &vha->scan.l[k];
3865                                        if (!memcmp(rp->port_name,
3866                                            d->port_name, 8)) {
3867                                                /*
3868                                                 * Supports FC-NVMe & FCP
3869                                                 */
3870                                                rp->fc4type |= FS_FC4TYPE_NVME;
3871                                                found = 1;
3872                                                break;
3873                                        }
3874                                }
3875
3876                                /* We found new FC-NVMe only port */
3877                                if (!found) {
3878                                        for (k = 0; k < num_fibre_dev; k++) {
3879                                                rp = &vha->scan.l[k];
3880                                                if (wwn_to_u64(rp->port_name)) {
3881                                                        continue;
3882                                                } else {
3883                                                        rp->id = id;
3884                                                        memcpy(rp->port_name,
3885                                                            d->port_name, 8);
3886                                                        rp->fc4type =
3887                                                            FS_FC4TYPE_NVME;
3888                                                        break;
3889                                                }
3890                                        }
3891                                }
3892                        } else {
3893                                for (k = 0; k < num_fibre_dev; k++) {
3894                                        rp = &vha->scan.l[k];
3895                                        if (id.b24 == rp->id.b24) {
3896                                                memcpy(rp->node_name,
3897                                                    d->port_name, 8);
3898                                                break;
3899                                        }
3900                                }
3901                        }
3902                }
3903        }
3904}
3905
3906static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
3907{
3908        struct srb *sp = s;
3909        struct scsi_qla_host *vha = sp->vha;
3910        struct ct_sns_req *ct_req =
3911                (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
3912        u16 cmd = be16_to_cpu(ct_req->command);
3913        u8 fc4_type = sp->gen2;
3914        unsigned long flags;
3915        int rc;
3916
3917        /* gen2 field is holding the fc4type */
3918        ql_dbg(ql_dbg_disc, vha, 0xffff,
3919            "Async done-%s res %x FC4Type %x\n",
3920            sp->name, res, sp->gen2);
3921
3922        del_timer(&sp->u.iocb_cmd.timer);
3923        sp->rc = res;
3924        if (res) {
3925                unsigned long flags;
3926                const char *name = sp->name;
3927
3928                /*
3929                 * We are in an Interrupt context, queue up this
3930                 * sp for GNNFT_DONE work. This will allow all
3931                 * the resource to get freed up.
3932                 */
3933                rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
3934                    QLA_EVT_GNNFT_DONE);
3935                if (rc) {
3936                        /* Cleanup here to prevent memory leak */
3937                        qla24xx_sp_unmap(vha, sp);
3938
3939                        spin_lock_irqsave(&vha->work_lock, flags);
3940                        vha->scan.scan_flags &= ~SF_SCANNING;
3941                        vha->scan.scan_retry++;
3942                        spin_unlock_irqrestore(&vha->work_lock, flags);
3943
3944                        if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
3945                                set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
3946                                set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
3947                                qla2xxx_wake_dpc(vha);
3948                        } else {
3949                                ql_dbg(ql_dbg_disc, vha, 0xffff,
3950                                    "Async done-%s rescan failed on all retries.\n",
3951                                    name);
3952                        }
3953                }
3954                return;
3955        }
3956
3957        qla2x00_find_free_fcp_nvme_slot(vha, sp);
3958
3959        if ((fc4_type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled &&
3960            cmd == GNN_FT_CMD) {
3961                spin_lock_irqsave(&vha->work_lock, flags);
3962                vha->scan.scan_flags &= ~SF_SCANNING;
3963                spin_unlock_irqrestore(&vha->work_lock, flags);
3964
3965                sp->rc = res;
3966                rc = qla2x00_post_nvme_gpnft_work(vha, sp, QLA_EVT_GPNFT);
3967                if (rc) {
3968                        qla24xx_sp_unmap(vha, sp);
3969                        set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
3970                        set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
3971                }
3972                return;
3973        }
3974
3975        if (cmd == GPN_FT_CMD) {
3976                rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
3977                    QLA_EVT_GPNFT_DONE);
3978        } else {
3979                rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
3980                    QLA_EVT_GNNFT_DONE);
3981        }
3982
3983        if (rc) {
3984                qla24xx_sp_unmap(vha, sp);
3985                set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
3986                set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
3987                return;
3988        }
3989}
3990
3991/*
3992 * Get WWNN list for fc4_type
3993 *
3994 * It is assumed the same SRB is re-used from GPNFT to avoid
3995 * mem free & re-alloc
3996 */
3997static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
3998    u8 fc4_type)
3999{
4000        int rval = QLA_FUNCTION_FAILED;
4001        struct ct_sns_req *ct_req;
4002        struct ct_sns_pkt *ct_sns;
4003        unsigned long flags;
4004
4005        if (!vha->flags.online) {
4006                spin_lock_irqsave(&vha->work_lock, flags);
4007                vha->scan.scan_flags &= ~SF_SCANNING;
4008                spin_unlock_irqrestore(&vha->work_lock, flags);
4009                goto done_free_sp;
4010        }
4011
4012        if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) {
4013                ql_log(ql_log_warn, vha, 0xffff,
4014                    "%s: req %p rsp %p are not setup\n",
4015                    __func__, sp->u.iocb_cmd.u.ctarg.req,
4016                    sp->u.iocb_cmd.u.ctarg.rsp);
4017                spin_lock_irqsave(&vha->work_lock, flags);
4018                vha->scan.scan_flags &= ~SF_SCANNING;
4019                spin_unlock_irqrestore(&vha->work_lock, flags);
4020                WARN_ON(1);
4021                set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
4022                set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
4023                goto done_free_sp;
4024        }
4025
4026        ql_dbg(ql_dbg_disc, vha, 0xfffff,
4027            "%s: FC4Type %x, CT-PASSTHRU %s command ctarg rsp size %d, ctarg req size %d\n",
4028            __func__, fc4_type, sp->name, sp->u.iocb_cmd.u.ctarg.rsp_size,
4029             sp->u.iocb_cmd.u.ctarg.req_size);
4030
4031        sp->type = SRB_CT_PTHRU_CMD;
4032        sp->name = "gnnft";
4033        sp->gen1 = vha->hw->base_qpair->chip_reset;
4034        sp->gen2 = fc4_type;
4035
4036        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
4037        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
4038
4039        memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
4040        memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
4041
4042        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
4043        /* CT_IU preamble  */
4044        ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD,
4045            sp->u.iocb_cmd.u.ctarg.rsp_size);
4046
4047        /* GPN_FT req */
4048        ct_req->req.gpn_ft.port_type = fc4_type;
4049
4050        sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE;
4051        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
4052
4053        sp->done = qla2x00_async_gpnft_gnnft_sp_done;
4054
4055        ql_dbg(ql_dbg_disc, vha, 0xffff,
4056            "Async-%s hdl=%x FC4Type %x.\n", sp->name,
4057            sp->handle, ct_req->req.gpn_ft.port_type);
4058
4059        rval = qla2x00_start_sp(sp);
4060        if (rval != QLA_SUCCESS) {
4061                spin_lock_irqsave(&vha->work_lock, flags);
4062                vha->scan.scan_flags &= ~SF_SCANNING;
4063                spin_unlock_irqrestore(&vha->work_lock, flags);
4064                goto done_free_sp;
4065        }
4066
4067        return rval;
4068
4069done_free_sp:
4070        if (sp->u.iocb_cmd.u.ctarg.req) {
4071                dma_free_coherent(&vha->hw->pdev->dev,
4072                    sp->u.iocb_cmd.u.ctarg.req_allocated_size,
4073                    sp->u.iocb_cmd.u.ctarg.req,
4074                    sp->u.iocb_cmd.u.ctarg.req_dma);
4075                sp->u.iocb_cmd.u.ctarg.req = NULL;
4076        }
4077        if (sp->u.iocb_cmd.u.ctarg.rsp) {
4078                dma_free_coherent(&vha->hw->pdev->dev,
4079                    sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
4080                    sp->u.iocb_cmd.u.ctarg.rsp,
4081                    sp->u.iocb_cmd.u.ctarg.rsp_dma);
4082                sp->u.iocb_cmd.u.ctarg.rsp = NULL;
4083        }
4084
4085        sp->free(sp);
4086
4087        return rval;
4088} /* GNNFT */
4089
4090void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp)
4091{
4092        ql_dbg(ql_dbg_disc, vha, 0xffff,
4093            "%s enter\n", __func__);
4094        qla24xx_async_gnnft(vha, sp, sp->gen2);
4095}
4096
4097/* Get WWPN list for certain fc4_type */
4098int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
4099{
4100        int rval = QLA_FUNCTION_FAILED;
4101        struct ct_sns_req       *ct_req;
4102        struct ct_sns_pkt *ct_sns;
4103        u32 rspsz;
4104        unsigned long flags;
4105
4106        ql_dbg(ql_dbg_disc, vha, 0xffff,
4107            "%s enter\n", __func__);
4108
4109        if (!vha->flags.online)
4110                return rval;
4111
4112        spin_lock_irqsave(&vha->work_lock, flags);
4113        if (vha->scan.scan_flags & SF_SCANNING) {
4114                spin_unlock_irqrestore(&vha->work_lock, flags);
4115                ql_dbg(ql_dbg_disc, vha, 0xffff, "scan active\n");
4116                return rval;
4117        }
4118        vha->scan.scan_flags |= SF_SCANNING;
4119        spin_unlock_irqrestore(&vha->work_lock, flags);
4120
4121        if (fc4_type == FC4_TYPE_FCP_SCSI) {
4122                ql_dbg(ql_dbg_disc, vha, 0xffff,
4123                    "%s: Performing FCP Scan\n", __func__);
4124
4125                if (sp)
4126                        sp->free(sp); /* should not happen */
4127
4128                sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
4129                if (!sp) {
4130                        spin_lock_irqsave(&vha->work_lock, flags);
4131                        vha->scan.scan_flags &= ~SF_SCANNING;
4132                        spin_unlock_irqrestore(&vha->work_lock, flags);
4133                        return rval;
4134                }
4135
4136                sp->u.iocb_cmd.u.ctarg.req = dma_zalloc_coherent(
4137                        &vha->hw->pdev->dev, sizeof(struct ct_sns_pkt),
4138                        &sp->u.iocb_cmd.u.ctarg.req_dma, GFP_KERNEL);
4139                sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
4140                if (!sp->u.iocb_cmd.u.ctarg.req) {
4141                        ql_log(ql_log_warn, vha, 0xffff,
4142                            "Failed to allocate ct_sns request.\n");
4143                        spin_lock_irqsave(&vha->work_lock, flags);
4144                        vha->scan.scan_flags &= ~SF_SCANNING;
4145                        spin_unlock_irqrestore(&vha->work_lock, flags);
4146                        qla2x00_rel_sp(sp);
4147                        return rval;
4148                }
4149                sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE;
4150
4151                rspsz = sizeof(struct ct_sns_gpnft_rsp) +
4152                        ((vha->hw->max_fibre_devices - 1) *
4153                            sizeof(struct ct_sns_gpn_ft_data));
4154
4155                sp->u.iocb_cmd.u.ctarg.rsp = dma_zalloc_coherent(
4156                        &vha->hw->pdev->dev, rspsz,
4157                        &sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL);
4158                sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
4159                if (!sp->u.iocb_cmd.u.ctarg.rsp) {
4160                        ql_log(ql_log_warn, vha, 0xffff,
4161                            "Failed to allocate ct_sns request.\n");
4162                        spin_lock_irqsave(&vha->work_lock, flags);
4163                        vha->scan.scan_flags &= ~SF_SCANNING;
4164                        spin_unlock_irqrestore(&vha->work_lock, flags);
4165                        dma_free_coherent(&vha->hw->pdev->dev,
4166                            sp->u.iocb_cmd.u.ctarg.req_allocated_size,
4167                            sp->u.iocb_cmd.u.ctarg.req,
4168                            sp->u.iocb_cmd.u.ctarg.req_dma);
4169                        sp->u.iocb_cmd.u.ctarg.req = NULL;
4170                        qla2x00_rel_sp(sp);
4171                        return rval;
4172                }
4173                sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz;
4174
4175                ql_dbg(ql_dbg_disc, vha, 0xffff,
4176                    "%s scan list size %d\n", __func__, vha->scan.size);
4177
4178                memset(vha->scan.l, 0, vha->scan.size);
4179        } else if (!sp) {
4180                ql_dbg(ql_dbg_disc, vha, 0xffff,
4181                    "NVME scan did not provide SP\n");
4182                return rval;
4183        }
4184
4185        sp->type = SRB_CT_PTHRU_CMD;
4186        sp->name = "gpnft";
4187        sp->gen1 = vha->hw->base_qpair->chip_reset;
4188        sp->gen2 = fc4_type;
4189
4190        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
4191        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
4192
4193        rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size;
4194        memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
4195        memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
4196
4197        ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
4198        /* CT_IU preamble  */
4199        ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz);
4200
4201        /* GPN_FT req */
4202        ct_req->req.gpn_ft.port_type = fc4_type;
4203
4204        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
4205
4206        sp->done = qla2x00_async_gpnft_gnnft_sp_done;
4207
4208        ql_dbg(ql_dbg_disc, vha, 0xffff,
4209            "Async-%s hdl=%x FC4Type %x.\n", sp->name,
4210            sp->handle, ct_req->req.gpn_ft.port_type);
4211
4212        rval = qla2x00_start_sp(sp);
4213        if (rval != QLA_SUCCESS) {
4214                spin_lock_irqsave(&vha->work_lock, flags);
4215                vha->scan.scan_flags &= ~SF_SCANNING;
4216                spin_unlock_irqrestore(&vha->work_lock, flags);
4217                goto done_free_sp;
4218        }
4219
4220        return rval;
4221
4222done_free_sp:
4223        if (sp->u.iocb_cmd.u.ctarg.req) {
4224                dma_free_coherent(&vha->hw->pdev->dev,
4225                    sp->u.iocb_cmd.u.ctarg.req_allocated_size,
4226                    sp->u.iocb_cmd.u.ctarg.req,
4227                    sp->u.iocb_cmd.u.ctarg.req_dma);
4228                sp->u.iocb_cmd.u.ctarg.req = NULL;
4229        }
4230        if (sp->u.iocb_cmd.u.ctarg.rsp) {
4231                dma_free_coherent(&vha->hw->pdev->dev,
4232                    sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
4233                    sp->u.iocb_cmd.u.ctarg.rsp,
4234                    sp->u.iocb_cmd.u.ctarg.rsp_dma);
4235                sp->u.iocb_cmd.u.ctarg.rsp = NULL;
4236        }
4237
4238        sp->free(sp);
4239
4240        return rval;
4241}
4242
4243void qla_scan_work_fn(struct work_struct *work)
4244{
4245        struct fab_scan *s = container_of(to_delayed_work(work),
4246            struct fab_scan, scan_work);
4247        struct scsi_qla_host *vha = container_of(s, struct scsi_qla_host,
4248            scan);
4249        unsigned long flags;
4250
4251        ql_dbg(ql_dbg_disc, vha, 0xffff,
4252            "%s: schedule loop resync\n", __func__);
4253        set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
4254        set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
4255        qla2xxx_wake_dpc(vha);
4256        spin_lock_irqsave(&vha->work_lock, flags);
4257        vha->scan.scan_flags &= ~SF_QUEUED;
4258        spin_unlock_irqrestore(&vha->work_lock, flags);
4259}
4260
4261/* GNN_ID */
4262void qla24xx_handle_gnnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
4263{
4264        qla24xx_post_gnl_work(vha, ea->fcport);
4265}
4266
4267static void qla2x00_async_gnnid_sp_done(void *s, int res)
4268{
4269        struct srb *sp = s;
4270        struct scsi_qla_host *vha = sp->vha;
4271        fc_port_t *fcport = sp->fcport;
4272        u8 *node_name = fcport->ct_desc.ct_sns->p.rsp.rsp.gnn_id.node_name;
4273        struct event_arg ea;
4274        u64 wwnn;
4275
4276        fcport->flags &= ~FCF_ASYNC_SENT;
4277        wwnn = wwn_to_u64(node_name);
4278        if (wwnn)
4279                memcpy(fcport->node_name, node_name, WWN_SIZE);
4280
4281        memset(&ea, 0, sizeof(ea));
4282        ea.fcport = fcport;
4283        ea.sp = sp;
4284        ea.rc = res;
4285        ea.event = FCME_GNNID_DONE;
4286
4287        ql_dbg(ql_dbg_disc, vha, 0x204f,
4288            "Async done-%s res %x, WWPN %8phC %8phC\n",
4289            sp->name, res, fcport->port_name, fcport->node_name);
4290
4291        qla2x00_fcport_event_handler(vha, &ea);
4292
4293        sp->free(sp);
4294}
4295
4296int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport)
4297{
4298        int rval = QLA_FUNCTION_FAILED;
4299        struct ct_sns_req       *ct_req;
4300        srb_t *sp;
4301
4302        if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
4303                return rval;
4304
4305        fcport->disc_state = DSC_GNN_ID;
4306        sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
4307        if (!sp)
4308                goto done;
4309
4310        fcport->flags |= FCF_ASYNC_SENT;
4311        sp->type = SRB_CT_PTHRU_CMD;
4312        sp->name = "gnnid";
4313        sp->gen1 = fcport->rscn_gen;
4314        sp->gen2 = fcport->login_gen;
4315
4316        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
4317        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
4318
4319        /* CT_IU preamble  */
4320        ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GNN_ID_CMD,
4321            GNN_ID_RSP_SIZE);
4322
4323        /* GNN_ID req */
4324        ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
4325        ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
4326        ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
4327
4328
4329        /* req & rsp use the same buffer */
4330        sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
4331        sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
4332        sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
4333        sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
4334        sp->u.iocb_cmd.u.ctarg.req_size = GNN_ID_REQ_SIZE;
4335        sp->u.iocb_cmd.u.ctarg.rsp_size = GNN_ID_RSP_SIZE;
4336        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
4337
4338        sp->done = qla2x00_async_gnnid_sp_done;
4339
4340        ql_dbg(ql_dbg_disc, vha, 0xffff,
4341            "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n",
4342            sp->name, fcport->port_name,
4343            sp->handle, fcport->loop_id, fcport->d_id.b24);
4344
4345        rval = qla2x00_start_sp(sp);
4346        if (rval != QLA_SUCCESS)
4347                goto done_free_sp;
4348        return rval;
4349
4350done_free_sp:
4351        sp->free(sp);
4352done:
4353        return rval;
4354}
4355
4356int qla24xx_post_gnnid_work(struct scsi_qla_host *vha, fc_port_t *fcport)
4357{
4358        struct qla_work_evt *e;
4359        int ls;
4360
4361        ls = atomic_read(&vha->loop_state);
4362        if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
4363                test_bit(UNLOADING, &vha->dpc_flags))
4364                return 0;
4365
4366        e = qla2x00_alloc_work(vha, QLA_EVT_GNNID);
4367        if (!e)
4368                return QLA_FUNCTION_FAILED;
4369
4370        e->u.fcport.fcport = fcport;
4371        return qla2x00_post_work(vha, e);
4372}
4373
4374/* GPFN_ID */
4375void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
4376{
4377        fc_port_t *fcport = ea->fcport;
4378
4379        ql_dbg(ql_dbg_disc, vha, 0xffff,
4380            "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d fcpcnt %d\n",
4381            __func__, fcport->port_name, fcport->disc_state,
4382            fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
4383            fcport->rscn_gen, ea->sp->gen1, vha->fcport_count);
4384
4385        if (fcport->disc_state == DSC_DELETE_PEND)
4386                return;
4387
4388        if (ea->sp->gen2 != fcport->login_gen) {
4389                /* target side must have changed it. */
4390                ql_dbg(ql_dbg_disc, vha, 0x20d3,
4391                    "%s %8phC generation changed\n",
4392                    __func__, fcport->port_name);
4393                return;
4394        } else if (ea->sp->gen1 != fcport->rscn_gen) {
4395                return;
4396        }
4397
4398        qla24xx_post_gpsc_work(vha, fcport);
4399}
4400
4401static void qla2x00_async_gfpnid_sp_done(void *s, int res)
4402{
4403        struct srb *sp = s;
4404        struct scsi_qla_host *vha = sp->vha;
4405        fc_port_t *fcport = sp->fcport;
4406        u8 *fpn = fcport->ct_desc.ct_sns->p.rsp.rsp.gfpn_id.port_name;
4407        struct event_arg ea;
4408        u64 wwn;
4409
4410        wwn = wwn_to_u64(fpn);
4411        if (wwn)
4412                memcpy(fcport->fabric_port_name, fpn, WWN_SIZE);
4413
4414        memset(&ea, 0, sizeof(ea));
4415        ea.fcport = fcport;
4416        ea.sp = sp;
4417        ea.rc = res;
4418        ea.event = FCME_GFPNID_DONE;
4419
4420        ql_dbg(ql_dbg_disc, vha, 0x204f,
4421            "Async done-%s res %x, WWPN %8phC %8phC\n",
4422            sp->name, res, fcport->port_name, fcport->fabric_port_name);
4423
4424        qla2x00_fcport_event_handler(vha, &ea);
4425
4426        sp->free(sp);
4427}
4428
4429int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport)
4430{
4431        int rval = QLA_FUNCTION_FAILED;
4432        struct ct_sns_req       *ct_req;
4433        srb_t *sp;
4434
4435        if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
4436                return rval;
4437
4438        sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
4439        if (!sp)
4440                goto done;
4441
4442        sp->type = SRB_CT_PTHRU_CMD;
4443        sp->name = "gfpnid";
4444        sp->gen1 = fcport->rscn_gen;
4445        sp->gen2 = fcport->login_gen;
4446
4447        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
4448        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
4449
4450        /* CT_IU preamble  */
4451        ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFPN_ID_CMD,
4452            GFPN_ID_RSP_SIZE);
4453
4454        /* GFPN_ID req */
4455        ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
4456        ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
4457        ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
4458
4459
4460        /* req & rsp use the same buffer */
4461        sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
4462        sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
4463        sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
4464        sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
4465        sp->u.iocb_cmd.u.ctarg.req_size = GFPN_ID_REQ_SIZE;
4466        sp->u.iocb_cmd.u.ctarg.rsp_size = GFPN_ID_RSP_SIZE;
4467        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
4468
4469        sp->done = qla2x00_async_gfpnid_sp_done;
4470
4471        ql_dbg(ql_dbg_disc, vha, 0xffff,
4472            "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n",
4473            sp->name, fcport->port_name,
4474            sp->handle, fcport->loop_id, fcport->d_id.b24);
4475
4476        rval = qla2x00_start_sp(sp);
4477        if (rval != QLA_SUCCESS)
4478                goto done_free_sp;
4479
4480        return rval;
4481
4482done_free_sp:
4483        sp->free(sp);
4484        fcport->flags &= ~FCF_ASYNC_SENT;
4485done:
4486        return rval;
4487}
4488
4489int qla24xx_post_gfpnid_work(struct scsi_qla_host *vha, fc_port_t *fcport)
4490{
4491        struct qla_work_evt *e;
4492        int ls;
4493
4494        ls = atomic_read(&vha->loop_state);
4495        if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
4496                test_bit(UNLOADING, &vha->dpc_flags))
4497                return 0;
4498
4499        e = qla2x00_alloc_work(vha, QLA_EVT_GFPNID);
4500        if (!e)
4501                return QLA_FUNCTION_FAILED;
4502
4503        e->u.fcport.fcport = fcport;
4504        return qla2x00_post_work(vha, e);
4505}
4506