root/drivers/scsi/qla2xxx/qla_gs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qla2x00_prep_ms_iocb
  2. qla24xx_prep_ms_iocb
  3. qla2x00_prep_ct_req
  4. qla2x00_chk_ms_status
  5. qla2x00_ga_nxt
  6. qla2x00_gid_pt_rsp_size
  7. qla2x00_gid_pt
  8. qla2x00_gpn_id
  9. qla2x00_gnn_id
  10. qla2x00_async_sns_sp_done
  11. qla2x00_rft_id
  12. qla_async_rftid
  13. qla2x00_rff_id
  14. qla_async_rffid
  15. qla2x00_rnn_id
  16. qla_async_rnnid
  17. qla2x00_get_sym_node_name
  18. qla2x00_rsnn_nn
  19. qla_async_rsnn_nn
  20. qla2x00_prep_sns_cmd
  21. qla2x00_sns_ga_nxt
  22. qla2x00_sns_gid_pt
  23. qla2x00_sns_gpn_id
  24. qla2x00_sns_gnn_id
  25. qla2x00_sns_rft_id
  26. qla2x00_sns_rnn_id
  27. qla2x00_mgmt_svr_login
  28. qla2x00_prep_ms_fdmi_iocb
  29. qla24xx_prep_ms_fdmi_iocb
  30. qla2x00_update_ms_fdmi_iocb
  31. qla2x00_prep_ct_fdmi_req
  32. qla2x00_fdmi_rhba
  33. qla2x00_fdmi_rpa
  34. qla2x00_fdmiv2_rhba
  35. qla2x00_fdmi_dhba
  36. qla2x00_fdmiv2_rpa
  37. qla2x00_fdmi_register
  38. qla2x00_gfpn_id
  39. qla24xx_prep_ct_fm_req
  40. qla2x00_port_speed_capability
  41. qla2x00_gpsc
  42. qla2x00_gff_id
  43. qla24xx_post_gpsc_work
  44. qla24xx_handle_gpsc_event
  45. qla24xx_async_gpsc_sp_done
  46. qla24xx_async_gpsc
  47. qla24xx_post_gpnid_work
  48. qla24xx_sp_unmap
  49. qla24xx_handle_gpnid_event
  50. qla2x00_async_gpnid_sp_done
  51. qla24xx_async_gpnid
  52. qla24xx_handle_gffid_event
  53. qla24xx_async_gffid_sp_done
  54. qla24xx_async_gffid
  55. qla2x00_is_a_vp
  56. qla24xx_async_gnnft_done
  57. qla2x00_post_gnnft_gpnft_done_work
  58. qla2x00_post_nvme_gpnft_work
  59. qla2x00_find_free_fcp_nvme_slot
  60. qla2x00_async_gpnft_gnnft_sp_done
  61. qla24xx_async_gnnft
  62. qla24xx_async_gpnft_done
  63. qla24xx_async_gpnft
  64. qla_scan_work_fn
  65. qla24xx_handle_gnnid_event
  66. qla2x00_async_gnnid_sp_done
  67. qla24xx_async_gnnid
  68. qla24xx_post_gnnid_work
  69. qla24xx_handle_gfpnid_event
  70. qla2x00_async_gfpnid_sp_done
  71. qla24xx_async_gfpnid
  72. qla24xx_post_gfpnid_work

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

/* [<][>][^][v][top][bottom][index][help] */