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