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