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