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