powerpc/perf/hv-24x7: Move cpumask file to top folder of hv-24x7 driver
[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                                     fcport->port_type != FCT_INITIATOR &&
3501                                     fcport->port_type != FCT_NVME_INITIATOR)) {
3502                                 qlt_schedule_sess_for_deletion(fcport);
3503                         }
3504                         fcport->d_id.b24 = rp->id.b24;
3505                         fcport->scan_needed = 0;
3506                         break;
3507                 }
3508
3509                 if (!found) {
3510                         ql_dbg(ql_dbg_disc, vha, 0xffff,
3511                             "%s %d %8phC post new sess\n",
3512                             __func__, __LINE__, rp->port_name);
3513                         qla24xx_post_newsess_work(vha, &rp->id, rp->port_name,
3514                             rp->node_name, NULL, rp->fc4type);
3515                 }
3516         }
3517
3518         if (dup) {
3519                 ql_log(ql_log_warn, vha, 0xffff,
3520                     "Detected %d duplicate NPORT ID(s) from switch data base\n",
3521                     dup_cnt);
3522         }
3523
3524 login_logout:
3525         /*
3526          * Logout all previous fabric dev marked lost, except FCP2 devices.
3527          */
3528         list_for_each_entry(fcport, &vha->vp_fcports, list) {
3529                 if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
3530                         fcport->scan_needed = 0;
3531                         continue;
3532                 }
3533
3534                 if (fcport->scan_state != QLA_FCPORT_FOUND) {
3535                         fcport->scan_needed = 0;
3536                         if ((qla_dual_mode_enabled(vha) ||
3537                                 qla_ini_mode_enabled(vha)) &&
3538                             atomic_read(&fcport->state) == FCS_ONLINE) {
3539                                 if (fcport->loop_id != FC_NO_LOOP_ID) {
3540                                         if (fcport->flags & FCF_FCP2_DEVICE)
3541                                                 fcport->logout_on_delete = 0;
3542
3543                                         ql_dbg(ql_dbg_disc, vha, 0x20f0,
3544                                             "%s %d %8phC post del sess\n",
3545                                             __func__, __LINE__,
3546                                             fcport->port_name);
3547
3548                                         qlt_schedule_sess_for_deletion(fcport);
3549                                         continue;
3550                                 }
3551                         }
3552                 } else {
3553                         if (fcport->scan_needed ||
3554                             fcport->disc_state != DSC_LOGIN_COMPLETE) {
3555                                 if (fcport->login_retry == 0) {
3556                                         fcport->login_retry =
3557                                                 vha->hw->login_retry_count;
3558                                         ql_dbg(ql_dbg_disc, vha, 0x20a3,
3559                                             "Port login retry %8phN, lid 0x%04x retry cnt=%d.\n",
3560                                             fcport->port_name, fcport->loop_id,
3561                                             fcport->login_retry);
3562                                 }
3563                                 fcport->scan_needed = 0;
3564                                 qla24xx_fcport_handle_login(vha, fcport);
3565                         }
3566                 }
3567         }
3568
3569         recheck = 1;
3570 out:
3571         qla24xx_sp_unmap(vha, sp);
3572         spin_lock_irqsave(&vha->work_lock, flags);
3573         vha->scan.scan_flags &= ~SF_SCANNING;
3574         spin_unlock_irqrestore(&vha->work_lock, flags);
3575
3576         if (recheck) {
3577                 list_for_each_entry(fcport, &vha->vp_fcports, list) {
3578                         if (fcport->scan_needed) {
3579                                 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
3580                                 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
3581                                 break;
3582                         }
3583                 }
3584         }
3585 }
3586
3587 static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha,
3588     srb_t *sp, int cmd)
3589 {
3590         struct qla_work_evt *e;
3591
3592         if (cmd != QLA_EVT_GPNFT_DONE && cmd != QLA_EVT_GNNFT_DONE)
3593                 return QLA_PARAMETER_ERROR;
3594
3595         e = qla2x00_alloc_work(vha, cmd);
3596         if (!e)
3597                 return QLA_FUNCTION_FAILED;
3598
3599         e->u.iosb.sp = sp;
3600
3601         return qla2x00_post_work(vha, e);
3602 }
3603
3604 static int qla2x00_post_nvme_gpnft_work(struct scsi_qla_host *vha,
3605     srb_t *sp, int cmd)
3606 {
3607         struct qla_work_evt *e;
3608
3609         if (cmd != QLA_EVT_GPNFT)
3610                 return QLA_PARAMETER_ERROR;
3611
3612         e = qla2x00_alloc_work(vha, cmd);
3613         if (!e)
3614                 return QLA_FUNCTION_FAILED;
3615
3616         e->u.gpnft.fc4_type = FC4_TYPE_NVME;
3617         e->u.gpnft.sp = sp;
3618
3619         return qla2x00_post_work(vha, e);
3620 }
3621
3622 static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
3623         struct srb *sp)
3624 {
3625         struct qla_hw_data *ha = vha->hw;
3626         int num_fibre_dev = ha->max_fibre_devices;
3627         struct ct_sns_req *ct_req =
3628                 (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
3629         struct ct_sns_gpnft_rsp *ct_rsp =
3630                 (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
3631         struct ct_sns_gpn_ft_data *d;
3632         struct fab_scan_rp *rp;
3633         u16 cmd = be16_to_cpu(ct_req->command);
3634         u8 fc4_type = sp->gen2;
3635         int i, j, k;
3636         port_id_t id;
3637         u8 found;
3638         u64 wwn;
3639
3640         j = 0;
3641         for (i = 0; i < num_fibre_dev; i++) {
3642                 d  = &ct_rsp->entries[i];
3643
3644                 id.b.rsvd_1 = 0;
3645                 id.b.domain = d->port_id[0];
3646                 id.b.area   = d->port_id[1];
3647                 id.b.al_pa  = d->port_id[2];
3648                 wwn = wwn_to_u64(d->port_name);
3649
3650                 if (id.b24 == 0 || wwn == 0)
3651                         continue;
3652
3653                 if (fc4_type == FC4_TYPE_FCP_SCSI) {
3654                         if (cmd == GPN_FT_CMD) {
3655                                 rp = &vha->scan.l[j];
3656                                 rp->id = id;
3657                                 memcpy(rp->port_name, d->port_name, 8);
3658                                 j++;
3659                                 rp->fc4type = FS_FC4TYPE_FCP;
3660                         } else {
3661                                 for (k = 0; k < num_fibre_dev; k++) {
3662                                         rp = &vha->scan.l[k];
3663                                         if (id.b24 == rp->id.b24) {
3664                                                 memcpy(rp->node_name,
3665                                                     d->port_name, 8);
3666                                                 break;
3667                                         }
3668                                 }
3669                         }
3670                 } else {
3671                         /* Search if the fibre device supports FC4_TYPE_NVME */
3672                         if (cmd == GPN_FT_CMD) {
3673                                 found = 0;
3674
3675                                 for (k = 0; k < num_fibre_dev; k++) {
3676                                         rp = &vha->scan.l[k];
3677                                         if (!memcmp(rp->port_name,
3678                                             d->port_name, 8)) {
3679                                                 /*
3680                                                  * Supports FC-NVMe & FCP
3681                                                  */
3682                                                 rp->fc4type |= FS_FC4TYPE_NVME;
3683                                                 found = 1;
3684                                                 break;
3685                                         }
3686                                 }
3687
3688                                 /* We found new FC-NVMe only port */
3689                                 if (!found) {
3690                                         for (k = 0; k < num_fibre_dev; k++) {
3691                                                 rp = &vha->scan.l[k];
3692                                                 if (wwn_to_u64(rp->port_name)) {
3693                                                         continue;
3694                                                 } else {
3695                                                         rp->id = id;
3696                                                         memcpy(rp->port_name,
3697                                                             d->port_name, 8);
3698                                                         rp->fc4type =
3699                                                             FS_FC4TYPE_NVME;
3700                                                         break;
3701                                                 }
3702                                         }
3703                                 }
3704                         } else {
3705                                 for (k = 0; k < num_fibre_dev; k++) {
3706                                         rp = &vha->scan.l[k];
3707                                         if (id.b24 == rp->id.b24) {
3708                                                 memcpy(rp->node_name,
3709                                                     d->port_name, 8);
3710                                                 break;
3711                                         }
3712                                 }
3713                         }
3714                 }
3715         }
3716 }
3717
3718 static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res)
3719 {
3720         struct scsi_qla_host *vha = sp->vha;
3721         struct ct_sns_req *ct_req =
3722                 (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
3723         u16 cmd = be16_to_cpu(ct_req->command);
3724         u8 fc4_type = sp->gen2;
3725         unsigned long flags;
3726         int rc;
3727
3728         /* gen2 field is holding the fc4type */
3729         ql_dbg(ql_dbg_disc, vha, 0xffff,
3730             "Async done-%s res %x FC4Type %x\n",
3731             sp->name, res, sp->gen2);
3732
3733         del_timer(&sp->u.iocb_cmd.timer);
3734         sp->rc = res;
3735         if (res) {
3736                 unsigned long flags;
3737                 const char *name = sp->name;
3738
3739                 /*
3740                  * We are in an Interrupt context, queue up this
3741                  * sp for GNNFT_DONE work. This will allow all
3742                  * the resource to get freed up.
3743                  */
3744                 rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
3745                     QLA_EVT_GNNFT_DONE);
3746                 if (rc) {
3747                         /* Cleanup here to prevent memory leak */
3748                         qla24xx_sp_unmap(vha, sp);
3749
3750                         spin_lock_irqsave(&vha->work_lock, flags);
3751                         vha->scan.scan_flags &= ~SF_SCANNING;
3752                         vha->scan.scan_retry++;
3753                         spin_unlock_irqrestore(&vha->work_lock, flags);
3754
3755                         if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
3756                                 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
3757                                 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
3758                                 qla2xxx_wake_dpc(vha);
3759                         } else {
3760                                 ql_dbg(ql_dbg_disc, vha, 0xffff,
3761                                     "Async done-%s rescan failed on all retries.\n",
3762                                     name);
3763                         }
3764                 }
3765                 return;
3766         }
3767
3768         qla2x00_find_free_fcp_nvme_slot(vha, sp);
3769
3770         if ((fc4_type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled &&
3771             cmd == GNN_FT_CMD) {
3772                 spin_lock_irqsave(&vha->work_lock, flags);
3773                 vha->scan.scan_flags &= ~SF_SCANNING;
3774                 spin_unlock_irqrestore(&vha->work_lock, flags);
3775
3776                 sp->rc = res;
3777                 rc = qla2x00_post_nvme_gpnft_work(vha, sp, QLA_EVT_GPNFT);
3778                 if (rc) {
3779                         qla24xx_sp_unmap(vha, sp);
3780                         set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
3781                         set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
3782                 }
3783                 return;
3784         }
3785
3786         if (cmd == GPN_FT_CMD) {
3787                 rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
3788                     QLA_EVT_GPNFT_DONE);
3789         } else {
3790                 rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
3791                     QLA_EVT_GNNFT_DONE);
3792         }
3793
3794         if (rc) {
3795                 qla24xx_sp_unmap(vha, sp);
3796                 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
3797                 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
3798                 return;
3799         }
3800 }
3801
3802 /*
3803  * Get WWNN list for fc4_type
3804  *
3805  * It is assumed the same SRB is re-used from GPNFT to avoid
3806  * mem free & re-alloc
3807  */
3808 static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
3809     u8 fc4_type)
3810 {
3811         int rval = QLA_FUNCTION_FAILED;
3812         struct ct_sns_req *ct_req;
3813         struct ct_sns_pkt *ct_sns;
3814         unsigned long flags;
3815
3816         if (!vha->flags.online) {
3817                 spin_lock_irqsave(&vha->work_lock, flags);
3818                 vha->scan.scan_flags &= ~SF_SCANNING;
3819                 spin_unlock_irqrestore(&vha->work_lock, flags);
3820                 goto done_free_sp;
3821         }
3822
3823         if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) {
3824                 ql_log(ql_log_warn, vha, 0xffff,
3825                     "%s: req %p rsp %p are not setup\n",
3826                     __func__, sp->u.iocb_cmd.u.ctarg.req,
3827                     sp->u.iocb_cmd.u.ctarg.rsp);
3828                 spin_lock_irqsave(&vha->work_lock, flags);
3829                 vha->scan.scan_flags &= ~SF_SCANNING;
3830                 spin_unlock_irqrestore(&vha->work_lock, flags);
3831                 WARN_ON(1);
3832                 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
3833                 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
3834                 goto done_free_sp;
3835         }
3836
3837         ql_dbg(ql_dbg_disc, vha, 0xfffff,
3838             "%s: FC4Type %x, CT-PASSTHRU %s command ctarg rsp size %d, ctarg req size %d\n",
3839             __func__, fc4_type, sp->name, sp->u.iocb_cmd.u.ctarg.rsp_size,
3840              sp->u.iocb_cmd.u.ctarg.req_size);
3841
3842         sp->type = SRB_CT_PTHRU_CMD;
3843         sp->name = "gnnft";
3844         sp->gen1 = vha->hw->base_qpair->chip_reset;
3845         sp->gen2 = fc4_type;
3846
3847         sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
3848         qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
3849
3850         memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
3851         memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
3852
3853         ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
3854         /* CT_IU preamble  */
3855         ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD,
3856             sp->u.iocb_cmd.u.ctarg.rsp_size);
3857
3858         /* GPN_FT req */
3859         ct_req->req.gpn_ft.port_type = fc4_type;
3860
3861         sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE;
3862         sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
3863
3864         sp->done = qla2x00_async_gpnft_gnnft_sp_done;
3865
3866         ql_dbg(ql_dbg_disc, vha, 0xffff,
3867             "Async-%s hdl=%x FC4Type %x.\n", sp->name,
3868             sp->handle, ct_req->req.gpn_ft.port_type);
3869
3870         rval = qla2x00_start_sp(sp);
3871         if (rval != QLA_SUCCESS) {
3872                 goto done_free_sp;
3873         }
3874
3875         return rval;
3876
3877 done_free_sp:
3878         if (sp->u.iocb_cmd.u.ctarg.req) {
3879                 dma_free_coherent(&vha->hw->pdev->dev,
3880                     sp->u.iocb_cmd.u.ctarg.req_allocated_size,
3881                     sp->u.iocb_cmd.u.ctarg.req,
3882                     sp->u.iocb_cmd.u.ctarg.req_dma);
3883                 sp->u.iocb_cmd.u.ctarg.req = NULL;
3884         }
3885         if (sp->u.iocb_cmd.u.ctarg.rsp) {
3886                 dma_free_coherent(&vha->hw->pdev->dev,
3887                     sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
3888                     sp->u.iocb_cmd.u.ctarg.rsp,
3889                     sp->u.iocb_cmd.u.ctarg.rsp_dma);
3890                 sp->u.iocb_cmd.u.ctarg.rsp = NULL;
3891         }
3892
3893         sp->free(sp);
3894
3895         spin_lock_irqsave(&vha->work_lock, flags);
3896         vha->scan.scan_flags &= ~SF_SCANNING;
3897         if (vha->scan.scan_flags == 0) {
3898                 ql_dbg(ql_dbg_disc, vha, 0xffff,
3899                     "%s: schedule\n", __func__);
3900                 vha->scan.scan_flags |= SF_QUEUED;
3901                 schedule_delayed_work(&vha->scan.scan_work, 5);
3902         }
3903         spin_unlock_irqrestore(&vha->work_lock, flags);
3904
3905
3906         return rval;
3907 } /* GNNFT */
3908
3909 void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp)
3910 {
3911         ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
3912             "%s enter\n", __func__);
3913         qla24xx_async_gnnft(vha, sp, sp->gen2);
3914 }
3915
3916 /* Get WWPN list for certain fc4_type */
3917 int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
3918 {
3919         int rval = QLA_FUNCTION_FAILED;
3920         struct ct_sns_req       *ct_req;
3921         struct ct_sns_pkt *ct_sns;
3922         u32 rspsz;
3923         unsigned long flags;
3924
3925         ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
3926             "%s enter\n", __func__);
3927
3928         if (!vha->flags.online)
3929                 return rval;
3930
3931         spin_lock_irqsave(&vha->work_lock, flags);
3932         if (vha->scan.scan_flags & SF_SCANNING) {
3933                 spin_unlock_irqrestore(&vha->work_lock, flags);
3934                 ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
3935                     "%s: scan active\n", __func__);
3936                 return rval;
3937         }
3938         vha->scan.scan_flags |= SF_SCANNING;
3939         spin_unlock_irqrestore(&vha->work_lock, flags);
3940
3941         if (fc4_type == FC4_TYPE_FCP_SCSI) {
3942                 ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
3943                     "%s: Performing FCP Scan\n", __func__);
3944
3945                 if (sp)
3946                         sp->free(sp); /* should not happen */
3947
3948                 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
3949                 if (!sp) {
3950                         spin_lock_irqsave(&vha->work_lock, flags);
3951                         vha->scan.scan_flags &= ~SF_SCANNING;
3952                         spin_unlock_irqrestore(&vha->work_lock, flags);
3953                         return rval;
3954                 }
3955
3956                 sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
3957                                                                 sizeof(struct ct_sns_pkt),
3958                                                                 &sp->u.iocb_cmd.u.ctarg.req_dma,
3959                                                                 GFP_KERNEL);
3960                 sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
3961                 if (!sp->u.iocb_cmd.u.ctarg.req) {
3962                         ql_log(ql_log_warn, vha, 0xffff,
3963                             "Failed to allocate ct_sns request.\n");
3964                         spin_lock_irqsave(&vha->work_lock, flags);
3965                         vha->scan.scan_flags &= ~SF_SCANNING;
3966                         spin_unlock_irqrestore(&vha->work_lock, flags);
3967                         qla2x00_rel_sp(sp);
3968                         return rval;
3969                 }
3970                 sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE;
3971
3972                 rspsz = sizeof(struct ct_sns_gpnft_rsp) +
3973                         ((vha->hw->max_fibre_devices - 1) *
3974                             sizeof(struct ct_sns_gpn_ft_data));
3975
3976                 sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
3977                                                                 rspsz,
3978                                                                 &sp->u.iocb_cmd.u.ctarg.rsp_dma,
3979                                                                 GFP_KERNEL);
3980                 sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz;
3981                 if (!sp->u.iocb_cmd.u.ctarg.rsp) {
3982                         ql_log(ql_log_warn, vha, 0xffff,
3983                             "Failed to allocate ct_sns request.\n");
3984                         spin_lock_irqsave(&vha->work_lock, flags);
3985                         vha->scan.scan_flags &= ~SF_SCANNING;
3986                         spin_unlock_irqrestore(&vha->work_lock, flags);
3987                         dma_free_coherent(&vha->hw->pdev->dev,
3988                             sp->u.iocb_cmd.u.ctarg.req_allocated_size,
3989                             sp->u.iocb_cmd.u.ctarg.req,
3990                             sp->u.iocb_cmd.u.ctarg.req_dma);
3991                         sp->u.iocb_cmd.u.ctarg.req = NULL;
3992                         qla2x00_rel_sp(sp);
3993                         return rval;
3994                 }
3995                 sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz;
3996
3997                 ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
3998                     "%s scan list size %d\n", __func__, vha->scan.size);
3999
4000                 memset(vha->scan.l, 0, vha->scan.size);
4001         } else if (!sp) {
4002                 ql_dbg(ql_dbg_disc, vha, 0xffff,
4003                     "NVME scan did not provide SP\n");
4004                 return rval;
4005         }
4006
4007         sp->type = SRB_CT_PTHRU_CMD;
4008         sp->name = "gpnft";
4009         sp->gen1 = vha->hw->base_qpair->chip_reset;
4010         sp->gen2 = fc4_type;
4011
4012         sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
4013         qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
4014
4015         rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size;
4016         memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
4017         memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
4018
4019         ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
4020         /* CT_IU preamble  */
4021         ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz);
4022
4023         /* GPN_FT req */
4024         ct_req->req.gpn_ft.port_type = fc4_type;
4025
4026         sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
4027
4028         sp->done = qla2x00_async_gpnft_gnnft_sp_done;
4029
4030         ql_dbg(ql_dbg_disc, vha, 0xffff,
4031             "Async-%s hdl=%x FC4Type %x.\n", sp->name,
4032             sp->handle, ct_req->req.gpn_ft.port_type);
4033
4034         rval = qla2x00_start_sp(sp);
4035         if (rval != QLA_SUCCESS) {
4036                 goto done_free_sp;
4037         }
4038
4039         return rval;
4040
4041 done_free_sp:
4042         if (sp->u.iocb_cmd.u.ctarg.req) {
4043                 dma_free_coherent(&vha->hw->pdev->dev,
4044                     sp->u.iocb_cmd.u.ctarg.req_allocated_size,
4045                     sp->u.iocb_cmd.u.ctarg.req,
4046                     sp->u.iocb_cmd.u.ctarg.req_dma);
4047                 sp->u.iocb_cmd.u.ctarg.req = NULL;
4048         }
4049         if (sp->u.iocb_cmd.u.ctarg.rsp) {
4050                 dma_free_coherent(&vha->hw->pdev->dev,
4051                     sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
4052                     sp->u.iocb_cmd.u.ctarg.rsp,
4053                     sp->u.iocb_cmd.u.ctarg.rsp_dma);
4054                 sp->u.iocb_cmd.u.ctarg.rsp = NULL;
4055         }
4056
4057         sp->free(sp);
4058
4059         spin_lock_irqsave(&vha->work_lock, flags);
4060         vha->scan.scan_flags &= ~SF_SCANNING;
4061         if (vha->scan.scan_flags == 0) {
4062                 ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
4063                     "%s: Scan scheduled.\n", __func__);
4064                 vha->scan.scan_flags |= SF_QUEUED;
4065                 schedule_delayed_work(&vha->scan.scan_work, 5);
4066         }
4067         spin_unlock_irqrestore(&vha->work_lock, flags);
4068
4069
4070         return rval;
4071 }
4072
4073 void qla_scan_work_fn(struct work_struct *work)
4074 {
4075         struct fab_scan *s = container_of(to_delayed_work(work),
4076             struct fab_scan, scan_work);
4077         struct scsi_qla_host *vha = container_of(s, struct scsi_qla_host,
4078             scan);
4079         unsigned long flags;
4080
4081         ql_dbg(ql_dbg_disc, vha, 0xffff,
4082             "%s: schedule loop resync\n", __func__);
4083         set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
4084         set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
4085         qla2xxx_wake_dpc(vha);
4086         spin_lock_irqsave(&vha->work_lock, flags);
4087         vha->scan.scan_flags &= ~SF_QUEUED;
4088         spin_unlock_irqrestore(&vha->work_lock, flags);
4089 }
4090
4091 /* GNN_ID */
4092 void qla24xx_handle_gnnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
4093 {
4094         qla24xx_post_gnl_work(vha, ea->fcport);
4095 }
4096
4097 static void qla2x00_async_gnnid_sp_done(srb_t *sp, int res)
4098 {
4099         struct scsi_qla_host *vha = sp->vha;
4100         fc_port_t *fcport = sp->fcport;
4101         u8 *node_name = fcport->ct_desc.ct_sns->p.rsp.rsp.gnn_id.node_name;
4102         struct event_arg ea;
4103         u64 wwnn;
4104
4105         fcport->flags &= ~FCF_ASYNC_SENT;
4106         wwnn = wwn_to_u64(node_name);
4107         if (wwnn)
4108                 memcpy(fcport->node_name, node_name, WWN_SIZE);
4109
4110         memset(&ea, 0, sizeof(ea));
4111         ea.fcport = fcport;
4112         ea.sp = sp;
4113         ea.rc = res;
4114
4115         ql_dbg(ql_dbg_disc, vha, 0x204f,
4116             "Async done-%s res %x, WWPN %8phC %8phC\n",
4117             sp->name, res, fcport->port_name, fcport->node_name);
4118
4119         qla24xx_handle_gnnid_event(vha, &ea);
4120
4121         sp->free(sp);
4122 }
4123
4124 int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport)
4125 {
4126         int rval = QLA_FUNCTION_FAILED;
4127         struct ct_sns_req       *ct_req;
4128         srb_t *sp;
4129
4130         if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
4131                 return rval;
4132
4133         qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID);
4134         sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
4135         if (!sp)
4136                 goto done;
4137
4138         fcport->flags |= FCF_ASYNC_SENT;
4139         sp->type = SRB_CT_PTHRU_CMD;
4140         sp->name = "gnnid";
4141         sp->gen1 = fcport->rscn_gen;
4142         sp->gen2 = fcport->login_gen;
4143
4144         sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
4145         qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
4146
4147         /* CT_IU preamble  */
4148         ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GNN_ID_CMD,
4149             GNN_ID_RSP_SIZE);
4150
4151         /* GNN_ID req */
4152         ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
4153
4154
4155         /* req & rsp use the same buffer */
4156         sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
4157         sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
4158         sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
4159         sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
4160         sp->u.iocb_cmd.u.ctarg.req_size = GNN_ID_REQ_SIZE;
4161         sp->u.iocb_cmd.u.ctarg.rsp_size = GNN_ID_RSP_SIZE;
4162         sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
4163
4164         sp->done = qla2x00_async_gnnid_sp_done;
4165
4166         ql_dbg(ql_dbg_disc, vha, 0xffff,
4167             "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n",
4168             sp->name, fcport->port_name,
4169             sp->handle, fcport->loop_id, fcport->d_id.b24);
4170
4171         rval = qla2x00_start_sp(sp);
4172         if (rval != QLA_SUCCESS)
4173                 goto done_free_sp;
4174         return rval;
4175
4176 done_free_sp:
4177         sp->free(sp);
4178         fcport->flags &= ~FCF_ASYNC_SENT;
4179 done:
4180         return rval;
4181 }
4182
4183 int qla24xx_post_gnnid_work(struct scsi_qla_host *vha, fc_port_t *fcport)
4184 {
4185         struct qla_work_evt *e;
4186         int ls;
4187
4188         ls = atomic_read(&vha->loop_state);
4189         if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
4190                 test_bit(UNLOADING, &vha->dpc_flags))
4191                 return 0;
4192
4193         e = qla2x00_alloc_work(vha, QLA_EVT_GNNID);
4194         if (!e)
4195                 return QLA_FUNCTION_FAILED;
4196
4197         e->u.fcport.fcport = fcport;
4198         return qla2x00_post_work(vha, e);
4199 }
4200
4201 /* GPFN_ID */
4202 void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
4203 {
4204         fc_port_t *fcport = ea->fcport;
4205
4206         ql_dbg(ql_dbg_disc, vha, 0xffff,
4207             "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d fcpcnt %d\n",
4208             __func__, fcport->port_name, fcport->disc_state,
4209             fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
4210             fcport->rscn_gen, ea->sp->gen1, vha->fcport_count);
4211
4212         if (fcport->disc_state == DSC_DELETE_PEND)
4213                 return;
4214
4215         if (ea->sp->gen2 != fcport->login_gen) {
4216                 /* target side must have changed it. */
4217                 ql_dbg(ql_dbg_disc, vha, 0x20d3,
4218                     "%s %8phC generation changed\n",
4219                     __func__, fcport->port_name);
4220                 return;
4221         } else if (ea->sp->gen1 != fcport->rscn_gen) {
4222                 return;
4223         }
4224
4225         qla24xx_post_gpsc_work(vha, fcport);
4226 }
4227
4228 static void qla2x00_async_gfpnid_sp_done(srb_t *sp, int res)
4229 {
4230         struct scsi_qla_host *vha = sp->vha;
4231         fc_port_t *fcport = sp->fcport;
4232         u8 *fpn = fcport->ct_desc.ct_sns->p.rsp.rsp.gfpn_id.port_name;
4233         struct event_arg ea;
4234         u64 wwn;
4235
4236         wwn = wwn_to_u64(fpn);
4237         if (wwn)
4238                 memcpy(fcport->fabric_port_name, fpn, WWN_SIZE);
4239
4240         memset(&ea, 0, sizeof(ea));
4241         ea.fcport = fcport;
4242         ea.sp = sp;
4243         ea.rc = res;
4244
4245         ql_dbg(ql_dbg_disc, vha, 0x204f,
4246             "Async done-%s res %x, WWPN %8phC %8phC\n",
4247             sp->name, res, fcport->port_name, fcport->fabric_port_name);
4248
4249         qla24xx_handle_gfpnid_event(vha, &ea);
4250
4251         sp->free(sp);
4252 }
4253
4254 int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport)
4255 {
4256         int rval = QLA_FUNCTION_FAILED;
4257         struct ct_sns_req       *ct_req;
4258         srb_t *sp;
4259
4260         if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
4261                 return rval;
4262
4263         sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
4264         if (!sp)
4265                 goto done;
4266
4267         sp->type = SRB_CT_PTHRU_CMD;
4268         sp->name = "gfpnid";
4269         sp->gen1 = fcport->rscn_gen;
4270         sp->gen2 = fcport->login_gen;
4271
4272         sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
4273         qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
4274
4275         /* CT_IU preamble  */
4276         ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFPN_ID_CMD,
4277             GFPN_ID_RSP_SIZE);
4278
4279         /* GFPN_ID req */
4280         ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
4281
4282
4283         /* req & rsp use the same buffer */
4284         sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
4285         sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
4286         sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
4287         sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
4288         sp->u.iocb_cmd.u.ctarg.req_size = GFPN_ID_REQ_SIZE;
4289         sp->u.iocb_cmd.u.ctarg.rsp_size = GFPN_ID_RSP_SIZE;
4290         sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
4291
4292         sp->done = qla2x00_async_gfpnid_sp_done;
4293
4294         ql_dbg(ql_dbg_disc, vha, 0xffff,
4295             "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n",
4296             sp->name, fcport->port_name,
4297             sp->handle, fcport->loop_id, fcport->d_id.b24);
4298
4299         rval = qla2x00_start_sp(sp);
4300         if (rval != QLA_SUCCESS)
4301                 goto done_free_sp;
4302
4303         return rval;
4304
4305 done_free_sp:
4306         sp->free(sp);
4307 done:
4308         return rval;
4309 }
4310
4311 int qla24xx_post_gfpnid_work(struct scsi_qla_host *vha, fc_port_t *fcport)
4312 {
4313         struct qla_work_evt *e;
4314         int ls;
4315
4316         ls = atomic_read(&vha->loop_state);
4317         if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
4318                 test_bit(UNLOADING, &vha->dpc_flags))
4319                 return 0;
4320
4321         e = qla2x00_alloc_work(vha, QLA_EVT_GFPNID);
4322         if (!e)
4323                 return QLA_FUNCTION_FAILED;
4324
4325         e->u.fcport.fcport = fcport;
4326         return qla2x00_post_work(vha, e);
4327 }