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