]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/scsi/qla2xxx/qla_gs.c
546011b1a7659b5a26882c9b7f2a0d8a01421c9f
[linux.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_lock(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_lock(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         return rval;
3183 }
3184
3185 int qla24xx_post_gidpn_work(struct scsi_qla_host *vha, fc_port_t *fcport)
3186 {
3187         struct qla_work_evt *e;
3188         int ls;
3189
3190         ls = atomic_read(&vha->loop_state);
3191         if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
3192                 test_bit(UNLOADING, &vha->dpc_flags))
3193                 return 0;
3194
3195         e = qla2x00_alloc_work(vha, QLA_EVT_GIDPN);
3196         if (!e)
3197                 return QLA_FUNCTION_FAILED;
3198
3199         e->u.fcport.fcport = fcport;
3200         fcport->flags |= FCF_ASYNC_ACTIVE;
3201         return qla2x00_post_work(vha, e);
3202 }
3203
3204 int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport)
3205 {
3206         struct qla_work_evt *e;
3207
3208         e = qla2x00_alloc_work(vha, QLA_EVT_GPSC);
3209         if (!e)
3210                 return QLA_FUNCTION_FAILED;
3211
3212         e->u.fcport.fcport = fcport;
3213         fcport->flags |= FCF_ASYNC_ACTIVE;
3214         return qla2x00_post_work(vha, e);
3215 }
3216
3217 void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea)
3218 {
3219         struct fc_port *fcport = ea->fcport;
3220
3221         ql_dbg(ql_dbg_disc, vha, 0x20d8,
3222             "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
3223             __func__, fcport->port_name, fcport->disc_state,
3224             fcport->fw_login_state, ea->rc, ea->sp->gen2, fcport->login_gen,
3225             ea->sp->gen2, fcport->rscn_gen|ea->sp->gen1, fcport->loop_id);
3226
3227         if (fcport->disc_state == DSC_DELETE_PEND)
3228                 return;
3229
3230         if (ea->sp->gen2 != fcport->login_gen) {
3231                 /* target side must have changed it. */
3232                 ql_dbg(ql_dbg_disc, vha, 0x20d3,
3233                     "%s %8phC generation changed\n",
3234                     __func__, fcport->port_name);
3235                 return;
3236         } else if (ea->sp->gen1 != fcport->rscn_gen) {
3237                 ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
3238                     __func__, __LINE__, fcport->port_name);
3239                 qla24xx_post_gidpn_work(vha, fcport);
3240                 return;
3241         }
3242
3243         qla24xx_post_upd_fcport_work(vha, ea->fcport);
3244 }
3245
3246 static void qla24xx_async_gpsc_sp_done(void *s, int res)
3247 {
3248         struct srb *sp = s;
3249         struct scsi_qla_host *vha = sp->vha;
3250         struct qla_hw_data *ha = vha->hw;
3251         fc_port_t *fcport = sp->fcport;
3252         struct ct_sns_rsp       *ct_rsp;
3253         struct event_arg ea;
3254
3255         ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
3256
3257         ql_dbg(ql_dbg_disc, vha, 0x2053,
3258             "Async done-%s res %x, WWPN %8phC \n",
3259             sp->name, res, fcport->port_name);
3260
3261         fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
3262
3263         if (res == (DID_ERROR << 16)) {
3264                 /* entry status error */
3265                 goto done;
3266         } else if (res) {
3267                 if ((ct_rsp->header.reason_code ==
3268                          CT_REASON_INVALID_COMMAND_CODE) ||
3269                         (ct_rsp->header.reason_code ==
3270                         CT_REASON_COMMAND_UNSUPPORTED)) {
3271                         ql_dbg(ql_dbg_disc, vha, 0x2019,
3272                             "GPSC command unsupported, disabling query.\n");
3273                         ha->flags.gpsc_supported = 0;
3274                         res = QLA_SUCCESS;
3275                 }
3276         } else {
3277                 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
3278                 case BIT_15:
3279                         fcport->fp_speed = PORT_SPEED_1GB;
3280                         break;
3281                 case BIT_14:
3282                         fcport->fp_speed = PORT_SPEED_2GB;
3283                         break;
3284                 case BIT_13:
3285                         fcport->fp_speed = PORT_SPEED_4GB;
3286                         break;
3287                 case BIT_12:
3288                         fcport->fp_speed = PORT_SPEED_10GB;
3289                         break;
3290                 case BIT_11:
3291                         fcport->fp_speed = PORT_SPEED_8GB;
3292                         break;
3293                 case BIT_10:
3294                         fcport->fp_speed = PORT_SPEED_16GB;
3295                         break;
3296                 case BIT_8:
3297                         fcport->fp_speed = PORT_SPEED_32GB;
3298                         break;
3299                 }
3300
3301                 ql_dbg(ql_dbg_disc, vha, 0x2054,
3302                     "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n",
3303                     sp->name, fcport->fabric_port_name,
3304                     be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
3305                     be16_to_cpu(ct_rsp->rsp.gpsc.speed));
3306         }
3307 done:
3308         memset(&ea, 0, sizeof(ea));
3309         ea.event = FCME_GPSC_DONE;
3310         ea.rc = res;
3311         ea.fcport = fcport;
3312         ea.sp = sp;
3313         qla2x00_fcport_event_handler(vha, &ea);
3314
3315         sp->free(sp);
3316 }
3317
3318 int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport)
3319 {
3320         int rval = QLA_FUNCTION_FAILED;
3321         struct ct_sns_req       *ct_req;
3322         srb_t *sp;
3323
3324         if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
3325                 return rval;
3326
3327         sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
3328         if (!sp)
3329                 goto done;
3330
3331         fcport->flags |= FCF_ASYNC_SENT;
3332         sp->type = SRB_CT_PTHRU_CMD;
3333         sp->name = "gpsc";
3334         sp->gen1 = fcport->rscn_gen;
3335         sp->gen2 = fcport->login_gen;
3336
3337         qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
3338
3339         /* CT_IU preamble  */
3340         ct_req = qla24xx_prep_ct_fm_req(fcport->ct_desc.ct_sns, GPSC_CMD,
3341                 GPSC_RSP_SIZE);
3342
3343         /* GPSC req */
3344         memcpy(ct_req->req.gpsc.port_name, fcport->fabric_port_name,
3345                 WWN_SIZE);
3346
3347         sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
3348         sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
3349         sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
3350         sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
3351         sp->u.iocb_cmd.u.ctarg.req_size = GPSC_REQ_SIZE;
3352         sp->u.iocb_cmd.u.ctarg.rsp_size = GPSC_RSP_SIZE;
3353         sp->u.iocb_cmd.u.ctarg.nport_handle = vha->mgmt_svr_loop_id;
3354
3355         sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
3356         sp->done = qla24xx_async_gpsc_sp_done;
3357
3358         rval = qla2x00_start_sp(sp);
3359         if (rval != QLA_SUCCESS)
3360                 goto done_free_sp;
3361
3362         ql_dbg(ql_dbg_disc, vha, 0x205e,
3363             "Async-%s %8phC hdl=%x loopid=%x portid=%02x%02x%02x.\n",
3364             sp->name, fcport->port_name, sp->handle,
3365             fcport->loop_id, fcport->d_id.b.domain,
3366             fcport->d_id.b.area, fcport->d_id.b.al_pa);
3367         return rval;
3368
3369 done_free_sp:
3370         sp->free(sp);
3371         fcport->flags &= ~FCF_ASYNC_SENT;
3372 done:
3373         return rval;
3374 }
3375
3376 int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id)
3377 {
3378         struct qla_work_evt *e;
3379
3380         if (test_bit(UNLOADING, &vha->dpc_flags))
3381                 return 0;
3382
3383         e = qla2x00_alloc_work(vha, QLA_EVT_GPNID);
3384         if (!e)
3385                 return QLA_FUNCTION_FAILED;
3386
3387         e->u.gpnid.id = *id;
3388         return qla2x00_post_work(vha, e);
3389 }
3390
3391 void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp)
3392 {
3393         if (sp->u.iocb_cmd.u.ctarg.req) {
3394                 dma_free_coherent(&vha->hw->pdev->dev,
3395                         sizeof(struct ct_sns_pkt),
3396                         sp->u.iocb_cmd.u.ctarg.req,
3397                         sp->u.iocb_cmd.u.ctarg.req_dma);
3398                 sp->u.iocb_cmd.u.ctarg.req = NULL;
3399         }
3400         if (sp->u.iocb_cmd.u.ctarg.rsp) {
3401                 dma_free_coherent(&vha->hw->pdev->dev,
3402                         sizeof(struct ct_sns_pkt),
3403                         sp->u.iocb_cmd.u.ctarg.rsp,
3404                         sp->u.iocb_cmd.u.ctarg.rsp_dma);
3405                 sp->u.iocb_cmd.u.ctarg.rsp = NULL;
3406         }
3407
3408         sp->free(sp);
3409 }
3410
3411 void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
3412 {
3413         fc_port_t *fcport, *conflict, *t;
3414         u16 data[2];
3415
3416         ql_dbg(ql_dbg_disc, vha, 0xffff,
3417             "%s %d port_id: %06x\n",
3418             __func__, __LINE__, ea->id.b24);
3419
3420         if (ea->rc) {
3421                 /* cable is disconnected */
3422                 list_for_each_entry_safe(fcport, t, &vha->vp_fcports, list) {
3423                         if (fcport->d_id.b24 == ea->id.b24) {
3424                                 ql_dbg(ql_dbg_disc, vha, 0xffff,
3425                                     "%s %d %8phC DS %d\n",
3426                                     __func__, __LINE__,
3427                                     fcport->port_name,
3428                                     fcport->disc_state);
3429                                 fcport->scan_state = QLA_FCPORT_SCAN;
3430                                 switch (fcport->disc_state) {
3431                                 case DSC_DELETED:
3432                                 case DSC_DELETE_PEND:
3433                                         break;
3434                                 default:
3435                                         ql_dbg(ql_dbg_disc, vha, 0xffff,
3436                                             "%s %d %8phC post del sess\n",
3437                                             __func__, __LINE__,
3438                                             fcport->port_name);
3439                                         qlt_schedule_sess_for_deletion_lock
3440                                                 (fcport);
3441                                         break;
3442                                 }
3443                         }
3444                 }
3445         } else {
3446                 /* cable is connected */
3447                 fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1);
3448                 if (fcport) {
3449                         list_for_each_entry_safe(conflict, t, &vha->vp_fcports,
3450                             list) {
3451                                 if ((conflict->d_id.b24 == ea->id.b24) &&
3452                                     (fcport != conflict)) {
3453                                         /* 2 fcports with conflict Nport ID or
3454                                          * an existing fcport is having nport ID
3455                                          * conflict with new fcport.
3456                                          */
3457
3458                                         ql_dbg(ql_dbg_disc, vha, 0xffff,
3459                                             "%s %d %8phC DS %d\n",
3460                                             __func__, __LINE__,
3461                                             conflict->port_name,
3462                                             conflict->disc_state);
3463                                         conflict->scan_state = QLA_FCPORT_SCAN;
3464                                         switch (conflict->disc_state) {
3465                                         case DSC_DELETED:
3466                                         case DSC_DELETE_PEND:
3467                                                 break;
3468                                         default:
3469                                                 ql_dbg(ql_dbg_disc, vha, 0xffff,
3470                                                     "%s %d %8phC post del sess\n",
3471                                                     __func__, __LINE__,
3472                                                     conflict->port_name);
3473                                                 qlt_schedule_sess_for_deletion_lock
3474                                                         (conflict);
3475                                                 break;
3476                                         }
3477                                 }
3478                         }
3479
3480                         fcport->rscn_gen++;
3481                         fcport->scan_state = QLA_FCPORT_FOUND;
3482                         fcport->flags |= FCF_FABRIC_DEVICE;
3483                         switch (fcport->disc_state) {
3484                         case DSC_LOGIN_COMPLETE:
3485                                 /* recheck session is still intact. */
3486                                 ql_dbg(ql_dbg_disc, vha, 0x210d,
3487                                     "%s %d %8phC revalidate session with ADISC\n",
3488                                     __func__, __LINE__, fcport->port_name);
3489                                 data[0] = data[1] = 0;
3490                                 qla2x00_post_async_adisc_work(vha, fcport,
3491                                     data);
3492                                 break;
3493                         case DSC_DELETED:
3494                                 ql_dbg(ql_dbg_disc, vha, 0x210d,
3495                                     "%s %d %8phC login\n", __func__, __LINE__,
3496                                     fcport->port_name);
3497                                 fcport->d_id = ea->id;
3498                                 qla24xx_fcport_handle_login(vha, fcport);
3499                                 break;
3500                         case DSC_DELETE_PEND:
3501                                 fcport->d_id = ea->id;
3502                                 break;
3503                         default:
3504                                 fcport->d_id = ea->id;
3505                                 break;
3506                         }
3507                 } else {
3508                         list_for_each_entry_safe(conflict, t, &vha->vp_fcports,
3509                             list) {
3510                                 if (conflict->d_id.b24 == ea->id.b24) {
3511                                         /* 2 fcports with conflict Nport ID or
3512                                          * an existing fcport is having nport ID
3513                                          * conflict with new fcport.
3514                                          */
3515                                         ql_dbg(ql_dbg_disc, vha, 0xffff,
3516                                             "%s %d %8phC DS %d\n",
3517                                             __func__, __LINE__,
3518                                             conflict->port_name,
3519                                             conflict->disc_state);
3520
3521                                         conflict->scan_state = QLA_FCPORT_SCAN;
3522                                         switch (conflict->disc_state) {
3523                                         case DSC_DELETED:
3524                                         case DSC_DELETE_PEND:
3525                                                 break;
3526                                         default:
3527                                                 ql_dbg(ql_dbg_disc, vha, 0xffff,
3528                                                     "%s %d %8phC post del sess\n",
3529                                                     __func__, __LINE__,
3530                                                     conflict->port_name);
3531                                                 qlt_schedule_sess_for_deletion_lock
3532                                                         (conflict);
3533                                                 break;
3534                                         }
3535                                 }
3536                         }
3537
3538                         /* create new fcport */
3539                         ql_dbg(ql_dbg_disc, vha, 0x2065,
3540                             "%s %d %8phC post new sess\n",
3541                             __func__, __LINE__, ea->port_name);
3542                         qla24xx_post_newsess_work(vha, &ea->id,
3543                             ea->port_name, NULL, NULL, FC4_TYPE_UNKNOWN);
3544                 }
3545         }
3546 }
3547
3548 static void qla2x00_async_gpnid_sp_done(void *s, int res)
3549 {
3550         struct srb *sp = s;
3551         struct scsi_qla_host *vha = sp->vha;
3552         struct ct_sns_req *ct_req =
3553             (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
3554         struct ct_sns_rsp *ct_rsp =
3555             (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
3556         struct event_arg ea;
3557         struct qla_work_evt *e;
3558         unsigned long flags;
3559
3560         if (res)
3561                 ql_dbg(ql_dbg_disc, vha, 0x2066,
3562                     "Async done-%s fail res %x rscn gen %d ID %3phC. %8phC\n",
3563                     sp->name, res, sp->gen1, ct_req->req.port_id.port_id,
3564                     ct_rsp->rsp.gpn_id.port_name);
3565         else
3566                 ql_dbg(ql_dbg_disc, vha, 0x2066,
3567                     "Async done-%s good rscn gen %d ID %3phC. %8phC\n",
3568                     sp->name, sp->gen1, ct_req->req.port_id.port_id,
3569                     ct_rsp->rsp.gpn_id.port_name);
3570
3571         memset(&ea, 0, sizeof(ea));
3572         memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
3573         ea.sp = sp;
3574         ea.id.b.domain = ct_req->req.port_id.port_id[0];
3575         ea.id.b.area = ct_req->req.port_id.port_id[1];
3576         ea.id.b.al_pa = ct_req->req.port_id.port_id[2];
3577         ea.rc = res;
3578         ea.event = FCME_GPNID_DONE;
3579
3580         spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
3581         list_del(&sp->elem);
3582         spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3583
3584         if (res) {
3585                 if (res == QLA_FUNCTION_TIMEOUT) {
3586                         qla24xx_post_gpnid_work(sp->vha, &ea.id);
3587                         sp->free(sp);
3588                         return;
3589                 }
3590         } else if (sp->gen1) {
3591                 /* There was another RSCN for this Nport ID */
3592                 qla24xx_post_gpnid_work(sp->vha, &ea.id);
3593                 sp->free(sp);
3594                 return;
3595         }
3596
3597         qla2x00_fcport_event_handler(vha, &ea);
3598
3599         e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
3600         if (!e) {
3601                 /* please ignore kernel warning. otherwise, we have mem leak. */
3602                 if (sp->u.iocb_cmd.u.ctarg.req) {
3603                         dma_free_coherent(&vha->hw->pdev->dev,
3604                                 sizeof(struct ct_sns_pkt),
3605                                 sp->u.iocb_cmd.u.ctarg.req,
3606                                 sp->u.iocb_cmd.u.ctarg.req_dma);
3607                         sp->u.iocb_cmd.u.ctarg.req = NULL;
3608                 }
3609                 if (sp->u.iocb_cmd.u.ctarg.rsp) {
3610                         dma_free_coherent(&vha->hw->pdev->dev,
3611                                 sizeof(struct ct_sns_pkt),
3612                                 sp->u.iocb_cmd.u.ctarg.rsp,
3613                                 sp->u.iocb_cmd.u.ctarg.rsp_dma);
3614                         sp->u.iocb_cmd.u.ctarg.rsp = NULL;
3615                 }
3616
3617                 sp->free(sp);
3618                 return;
3619         }
3620
3621         e->u.iosb.sp = sp;
3622         qla2x00_post_work(vha, e);
3623 }
3624
3625 /* Get WWPN with Nport ID. */
3626 int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
3627 {
3628         int rval = QLA_FUNCTION_FAILED;
3629         struct ct_sns_req       *ct_req;
3630         srb_t *sp, *tsp;
3631         struct ct_sns_pkt *ct_sns;
3632         unsigned long flags;
3633
3634         if (!vha->flags.online)
3635                 goto done;
3636
3637         sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
3638         if (!sp)
3639                 goto done;
3640
3641         sp->type = SRB_CT_PTHRU_CMD;
3642         sp->name = "gpnid";
3643         sp->u.iocb_cmd.u.ctarg.id = *id;
3644         sp->gen1 = 0;
3645         qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
3646
3647         spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
3648         list_for_each_entry(tsp, &vha->gpnid_list, elem) {
3649                 if (tsp->u.iocb_cmd.u.ctarg.id.b24 == id->b24) {
3650                         tsp->gen1++;
3651                         spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3652                         sp->free(sp);
3653                         goto done;
3654                 }
3655         }
3656         list_add_tail(&sp->elem, &vha->gpnid_list);
3657         spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3658
3659         sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
3660                 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
3661                 GFP_KERNEL);
3662         if (!sp->u.iocb_cmd.u.ctarg.req) {
3663                 ql_log(ql_log_warn, vha, 0xd041,
3664                     "Failed to allocate ct_sns request.\n");
3665                 goto done_free_sp;
3666         }
3667
3668         sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
3669                 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
3670                 GFP_KERNEL);
3671         if (!sp->u.iocb_cmd.u.ctarg.rsp) {
3672                 ql_log(ql_log_warn, vha, 0xd042,
3673                     "Failed to allocate ct_sns request.\n");
3674                 goto done_free_sp;
3675         }
3676
3677         ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
3678         memset(ct_sns, 0, sizeof(*ct_sns));
3679
3680         ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
3681         /* CT_IU preamble  */
3682         ct_req = qla2x00_prep_ct_req(ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE);
3683
3684         /* GPN_ID req */
3685         ct_req->req.port_id.port_id[0] = id->b.domain;
3686         ct_req->req.port_id.port_id[1] = id->b.area;
3687         ct_req->req.port_id.port_id[2] = id->b.al_pa;
3688
3689         sp->u.iocb_cmd.u.ctarg.req_size = GPN_ID_REQ_SIZE;
3690         sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_RSP_SIZE;
3691         sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
3692
3693         sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
3694         sp->done = qla2x00_async_gpnid_sp_done;
3695
3696         rval = qla2x00_start_sp(sp);
3697         if (rval != QLA_SUCCESS)
3698                 goto done_free_sp;
3699
3700         ql_dbg(ql_dbg_disc, vha, 0x2067,
3701             "Async-%s hdl=%x ID %3phC.\n", sp->name,
3702             sp->handle, ct_req->req.port_id.port_id);
3703         return rval;
3704
3705 done_free_sp:
3706         if (sp->u.iocb_cmd.u.ctarg.req) {
3707                 dma_free_coherent(&vha->hw->pdev->dev,
3708                         sizeof(struct ct_sns_pkt),
3709                         sp->u.iocb_cmd.u.ctarg.req,
3710                         sp->u.iocb_cmd.u.ctarg.req_dma);
3711                 sp->u.iocb_cmd.u.ctarg.req = NULL;
3712         }
3713         if (sp->u.iocb_cmd.u.ctarg.rsp) {
3714                 dma_free_coherent(&vha->hw->pdev->dev,
3715                         sizeof(struct ct_sns_pkt),
3716                         sp->u.iocb_cmd.u.ctarg.rsp,
3717                         sp->u.iocb_cmd.u.ctarg.rsp_dma);
3718                 sp->u.iocb_cmd.u.ctarg.rsp = NULL;
3719         }
3720
3721         sp->free(sp);
3722 done:
3723         return rval;
3724 }
3725
3726 void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
3727 {
3728        fc_port_t *fcport = ea->fcport;
3729
3730        qla24xx_post_gnl_work(vha, fcport);
3731 }
3732
3733 void qla24xx_async_gffid_sp_done(void *s, int res)
3734 {
3735        struct srb *sp = s;
3736        struct scsi_qla_host *vha = sp->vha;
3737        fc_port_t *fcport = sp->fcport;
3738        struct ct_sns_rsp *ct_rsp;
3739        struct event_arg ea;
3740
3741        ql_dbg(ql_dbg_disc, vha, 0x2133,
3742            "Async done-%s res %x ID %x. %8phC\n",
3743            sp->name, res, fcport->d_id.b24, fcport->port_name);
3744
3745        fcport->flags &= ~FCF_ASYNC_SENT;
3746        ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
3747        /*
3748         * FC-GS-7, 5.2.3.12 FC-4 Features - format
3749         * The format of the FC-4 Features object, as defined by the FC-4,
3750         * Shall be an array of 4-bit values, one for each type code value
3751         */
3752        if (!res) {
3753                if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) {
3754                        /* w1 b00:03 */
3755                        fcport->fc4_type =
3756                            ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
3757                        fcport->fc4_type &= 0xf;
3758                }
3759
3760                if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) {
3761                        /* w5 [00:03]/28h */
3762                        fcport->fc4f_nvme =
3763                            ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
3764                        fcport->fc4f_nvme &= 0xf;
3765                }
3766        }
3767
3768        memset(&ea, 0, sizeof(ea));
3769        ea.sp = sp;
3770        ea.fcport = sp->fcport;
3771        ea.rc = res;
3772        ea.event = FCME_GFFID_DONE;
3773
3774        qla2x00_fcport_event_handler(vha, &ea);
3775        sp->free(sp);
3776 }
3777
3778 /* Get FC4 Feature with Nport ID. */
3779 int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
3780 {
3781         int rval = QLA_FUNCTION_FAILED;
3782         struct ct_sns_req       *ct_req;
3783         srb_t *sp;
3784
3785         if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
3786                 return rval;
3787
3788         sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
3789         if (!sp)
3790                 return rval;
3791
3792         fcport->flags |= FCF_ASYNC_SENT;
3793         sp->type = SRB_CT_PTHRU_CMD;
3794         sp->name = "gffid";
3795         sp->gen1 = fcport->rscn_gen;
3796         sp->gen2 = fcport->login_gen;
3797
3798         qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
3799
3800         /* CT_IU preamble  */
3801         ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD,
3802             GFF_ID_RSP_SIZE);
3803
3804         ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain;
3805         ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area;
3806         ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
3807
3808         sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
3809         sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
3810         sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
3811         sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
3812         sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE;
3813         sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
3814         sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
3815
3816         sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
3817         sp->done = qla24xx_async_gffid_sp_done;
3818
3819         rval = qla2x00_start_sp(sp);
3820         if (rval != QLA_SUCCESS)
3821                 goto done_free_sp;
3822
3823         ql_dbg(ql_dbg_disc, vha, 0x2132,
3824             "Async-%s hdl=%x  %8phC.\n", sp->name,
3825             sp->handle, fcport->port_name);
3826
3827         return rval;
3828 done_free_sp:
3829         sp->free(sp);
3830         fcport->flags &= ~FCF_ASYNC_SENT;
3831         return rval;
3832 }
3833
3834 /* GPN_FT + GNN_FT*/
3835 static int qla2x00_is_a_vp(scsi_qla_host_t *vha, u64 wwn)
3836 {
3837         struct qla_hw_data *ha = vha->hw;
3838         scsi_qla_host_t *vp;
3839         unsigned long flags;
3840         u64 twwn;
3841         int rc = 0;
3842
3843         if (!ha->num_vhosts)
3844                 return 0;
3845
3846         spin_lock_irqsave(&ha->vport_slock, flags);
3847         list_for_each_entry(vp, &ha->vp_list, list) {
3848                 twwn = wwn_to_u64(vp->port_name);
3849                 if (wwn == twwn) {
3850                         rc = 1;
3851                         break;
3852                 }
3853         }
3854         spin_unlock_irqrestore(&ha->vport_slock, flags);
3855
3856         return rc;
3857 }
3858
3859 void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
3860 {
3861         fc_port_t *fcport;
3862         u32 i, rc;
3863         bool found;
3864         u8 fc4type = sp->gen2;
3865         struct fab_scan_rp *rp;
3866         unsigned long flags;
3867
3868         ql_dbg(ql_dbg_disc, vha, 0xffff,
3869             "%s enter\n", __func__);
3870
3871         if (sp->gen1 != vha->hw->base_qpair->chip_reset) {
3872                 ql_dbg(ql_dbg_disc, vha, 0xffff,
3873                     "%s scan stop due to chip reset %x/%x\n",
3874                     sp->name, sp->gen1, vha->hw->base_qpair->chip_reset);
3875                 goto out;
3876         }
3877
3878         rc = sp->rc;
3879         if (rc) {
3880                 vha->scan.scan_retry++;
3881                 if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
3882                         set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
3883                         set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
3884                 } else {
3885                         ql_dbg(ql_dbg_disc, vha, 0xffff,
3886                             "Fabric scan failed on all retries.\n");
3887                 }
3888                 goto out;
3889         }
3890         vha->scan.scan_retry = 0;
3891
3892         list_for_each_entry(fcport, &vha->vp_fcports, list)
3893                 fcport->scan_state = QLA_FCPORT_SCAN;
3894
3895         for (i = 0; i < vha->hw->max_fibre_devices; i++) {
3896                 u64 wwn;
3897
3898                 rp = &vha->scan.l[i];
3899                 found = false;
3900
3901                 wwn = wwn_to_u64(rp->port_name);
3902                 if (wwn == 0)
3903                         continue;
3904
3905                 if (!memcmp(rp->port_name, vha->port_name, WWN_SIZE))
3906                         continue;
3907
3908                 /* Bypass reserved domain fields. */
3909                 if ((rp->id.b.domain & 0xf0) == 0xf0)
3910                         continue;
3911
3912                 /* Bypass virtual ports of the same host. */
3913                 if (qla2x00_is_a_vp(vha, wwn))
3914                         continue;
3915
3916                 list_for_each_entry(fcport, &vha->vp_fcports, list) {
3917                         if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE))
3918                                 continue;
3919                         fcport->scan_state = QLA_FCPORT_FOUND;
3920                         fcport->d_id.b24 = rp->id.b24;
3921                         found = true;
3922                         /*
3923                          * If device was not a fabric device before.
3924                          */
3925                         if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
3926                                 qla2x00_clear_loop_id(fcport);
3927                                 fcport->flags |= FCF_FABRIC_DEVICE;
3928                         }
3929                         break;
3930                 }
3931
3932                 if (!found) {
3933                         ql_dbg(ql_dbg_disc, vha, 0xffff,
3934                             "%s %d %8phC post new sess\n",
3935                             __func__, __LINE__, rp->port_name);
3936                         qla24xx_post_newsess_work(vha, &rp->id, rp->port_name,
3937                             rp->node_name, NULL, fc4type);
3938                 }
3939         }
3940
3941         /*
3942          * Logout all previous fabric dev marked lost, except FCP2 devices.
3943          */
3944         list_for_each_entry(fcport, &vha->vp_fcports, list) {
3945                 if ((fcport->flags & FCF_FABRIC_DEVICE) == 0)
3946                         continue;
3947
3948                 if (fcport->scan_state != QLA_FCPORT_FOUND) {
3949                         if ((qla_dual_mode_enabled(vha) ||
3950                                 qla_ini_mode_enabled(vha)) &&
3951                             atomic_read(&fcport->state) == FCS_ONLINE) {
3952                                 qla2x00_mark_device_lost(vha, fcport,
3953                                     ql2xplogiabsentdevice, 0);
3954
3955                                 if (fcport->loop_id != FC_NO_LOOP_ID &&
3956                                     (fcport->flags & FCF_FCP2_DEVICE) == 0) {
3957                                         ql_dbg(ql_dbg_disc, vha, 0x20f0,
3958                                             "%s %d %8phC post del sess\n",
3959                                             __func__, __LINE__,
3960                                             fcport->port_name);
3961
3962                                         qlt_schedule_sess_for_deletion_lock
3963                                                 (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
3978 static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
3979 {
3980         struct srb *sp = s;
3981         struct scsi_qla_host *vha = sp->vha;
3982         struct qla_work_evt *e;
3983         struct ct_sns_req *ct_req =
3984                 (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
3985         struct ct_sns_gpnft_rsp *ct_rsp =
3986                 (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
3987         struct ct_sns_gpn_ft_data *d = &ct_rsp->entries[0];
3988         struct fab_scan_rp *rp;
3989         int i, j, k;
3990         u16 cmd = be16_to_cpu(ct_req->command);
3991
3992         /* gen2 field is holding the fc4type */
3993         ql_dbg(ql_dbg_disc, vha, 0xffff,
3994             "Async done-%s res %x FC4Type %x\n",
3995             sp->name, res, sp->gen2);
3996
3997         if (res) {
3998                 unsigned long flags;
3999
4000                 sp->free(sp);
4001                 spin_lock_irqsave(&vha->work_lock, flags);
4002                 vha->scan.scan_flags &= ~SF_SCANNING;
4003                 vha->scan.scan_retry++;
4004                 spin_unlock_irqrestore(&vha->work_lock, flags);
4005
4006                 if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
4007                         set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
4008                         set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
4009                         qla2xxx_wake_dpc(vha);
4010                 } else {
4011                         ql_dbg(ql_dbg_disc, sp->vha, 0xffff,
4012                             "Async done-%s rescan failed on all retries\n",
4013                             sp->name);
4014                 }
4015                 return;
4016         }
4017
4018         if (!res) {
4019                 port_id_t id;
4020                 u64 wwn;
4021
4022                 j = 0;
4023                 for (i = 0; i < vha->hw->max_fibre_devices; i++) {
4024                         d  = &ct_rsp->entries[i];
4025
4026                         id.b.rsvd_1 = 0;
4027                         id.b.domain = d->port_id[0];
4028                         id.b.area   = d->port_id[1];
4029                         id.b.al_pa  = d->port_id[2];
4030                         wwn = wwn_to_u64(d->port_name);
4031
4032                         if (id.b24 == 0 || wwn == 0)
4033                                 continue;
4034
4035                         if (cmd == GPN_FT_CMD) {
4036                                 rp = &vha->scan.l[j];
4037                                 rp->id = id;
4038                                 memcpy(rp->port_name, d->port_name, 8);
4039                                 j++;
4040                         } else {/* GNN_FT_CMD */
4041                                 for (k = 0; k < vha->hw->max_fibre_devices;
4042                                     k++) {
4043                                         rp = &vha->scan.l[k];
4044                                         if (id.b24 == rp->id.b24) {
4045                                                 memcpy(rp->node_name,
4046                                                     d->port_name, 8);
4047                                                 break;
4048                                         }
4049                                 }
4050                         }
4051                 }
4052         }
4053
4054         if (cmd == GPN_FT_CMD)
4055                 e = qla2x00_alloc_work(vha, QLA_EVT_GPNFT_DONE);
4056         else
4057                 e = qla2x00_alloc_work(vha, QLA_EVT_GNNFT_DONE);
4058         if (!e) {
4059                 /* please ignore kernel warning. Otherwise, we have mem leak. */
4060                 if (sp->u.iocb_cmd.u.ctarg.req) {
4061                         dma_free_coherent(&vha->hw->pdev->dev,
4062                             sizeof(struct ct_sns_pkt),
4063                             sp->u.iocb_cmd.u.ctarg.req,
4064                             sp->u.iocb_cmd.u.ctarg.req_dma);
4065                         sp->u.iocb_cmd.u.ctarg.req = NULL;
4066                 }
4067                 if (sp->u.iocb_cmd.u.ctarg.rsp) {
4068                         dma_free_coherent(&vha->hw->pdev->dev,
4069                             sizeof(struct ct_sns_pkt),
4070                             sp->u.iocb_cmd.u.ctarg.rsp,
4071                             sp->u.iocb_cmd.u.ctarg.rsp_dma);
4072                         sp->u.iocb_cmd.u.ctarg.rsp = NULL;
4073                 }
4074
4075                 ql_dbg(ql_dbg_disc, vha, 0xffff,
4076                     "Async done-%s unable to alloc work element\n",
4077                     sp->name);
4078                 sp->free(sp);
4079                 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
4080                 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
4081                 return;
4082         }
4083
4084         sp->rc = res;
4085         e->u.iosb.sp = sp;
4086
4087         qla2x00_post_work(vha, e);
4088 }
4089
4090 /*
4091  * Get WWNN list for fc4_type
4092  *
4093  * It is assumed the same SRB is re-used from GPNFT to avoid
4094  * mem free & re-alloc
4095  */
4096 static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
4097     u8 fc4_type)
4098 {
4099         int rval = QLA_FUNCTION_FAILED;
4100         struct ct_sns_req *ct_req;
4101         struct ct_sns_pkt *ct_sns;
4102
4103         if (!vha->flags.online) {
4104                 vha->scan.scan_flags &= ~SF_SCANNING;
4105                 goto done_free_sp;
4106         }
4107
4108         if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) {
4109                 ql_log(ql_log_warn, vha, 0xffff,
4110                     "%s: req %p rsp %p are not setup\n",
4111                     __func__, sp->u.iocb_cmd.u.ctarg.req,
4112                     sp->u.iocb_cmd.u.ctarg.rsp);
4113                 vha->scan.scan_flags &= ~SF_SCANNING;
4114                 WARN_ON(1);
4115                 goto done_free_sp;
4116         }
4117         sp->type = SRB_CT_PTHRU_CMD;
4118         sp->name = "gnnft";
4119         sp->gen1 = vha->hw->base_qpair->chip_reset;
4120         sp->gen2 = fc4_type;
4121         qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
4122
4123         memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
4124         memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
4125
4126         ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
4127         /* CT_IU preamble  */
4128         ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD,
4129             sp->u.iocb_cmd.u.ctarg.rsp_size);
4130
4131         /* GPN_FT req */
4132         ct_req->req.gpn_ft.port_type = fc4_type;
4133
4134         sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE;
4135         sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
4136
4137         sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
4138         sp->done = qla2x00_async_gpnft_gnnft_sp_done;
4139
4140         rval = qla2x00_start_sp(sp);
4141         if (rval != QLA_SUCCESS)
4142                 goto done_free_sp;
4143
4144         ql_dbg(ql_dbg_disc, vha, 0xffff,
4145             "Async-%s hdl=%x FC4Type %x.\n", sp->name,
4146             sp->handle, ct_req->req.gpn_ft.port_type);
4147         return rval;
4148
4149 done_free_sp:
4150         if (sp->u.iocb_cmd.u.ctarg.req) {
4151                 dma_free_coherent(&vha->hw->pdev->dev,
4152                     sizeof(struct ct_sns_pkt),
4153                     sp->u.iocb_cmd.u.ctarg.req,
4154                     sp->u.iocb_cmd.u.ctarg.req_dma);
4155                 sp->u.iocb_cmd.u.ctarg.req = NULL;
4156         }
4157         if (sp->u.iocb_cmd.u.ctarg.rsp) {
4158                 dma_free_coherent(&vha->hw->pdev->dev,
4159                     sizeof(struct ct_sns_pkt),
4160                     sp->u.iocb_cmd.u.ctarg.rsp,
4161                     sp->u.iocb_cmd.u.ctarg.rsp_dma);
4162                 sp->u.iocb_cmd.u.ctarg.rsp = NULL;
4163         }
4164
4165         sp->free(sp);
4166
4167         return rval;
4168 } /* GNNFT */
4169
4170 void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp)
4171 {
4172         ql_dbg(ql_dbg_disc, vha, 0xffff,
4173             "%s enter\n", __func__);
4174         del_timer(&sp->u.iocb_cmd.timer);
4175         qla24xx_async_gnnft(vha, sp, sp->gen2);
4176 }
4177
4178 /* Get WWPN list for certain fc4_type */
4179 int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type)
4180 {
4181         int rval = QLA_FUNCTION_FAILED;
4182         struct ct_sns_req       *ct_req;
4183         srb_t *sp;
4184         struct ct_sns_pkt *ct_sns;
4185         u32 rspsz;
4186         unsigned long flags;
4187
4188         if (!vha->flags.online)
4189                 return rval;
4190
4191         spin_lock_irqsave(&vha->work_lock, flags);
4192         if (vha->scan.scan_flags & SF_SCANNING) {
4193                 spin_unlock_irqrestore(&vha->work_lock, flags);
4194                 ql_dbg(ql_dbg_disc, vha, 0xffff, "scan active\n");
4195                 return rval;
4196         }
4197         vha->scan.scan_flags |= SF_SCANNING;
4198         spin_unlock_irqrestore(&vha->work_lock, flags);
4199
4200         sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
4201         if (!sp) {
4202                 vha->scan.scan_flags &= ~SF_SCANNING;
4203                 return rval;
4204         }
4205
4206         sp->type = SRB_CT_PTHRU_CMD;
4207         sp->name = "gpnft";
4208         sp->gen1 = vha->hw->base_qpair->chip_reset;
4209         sp->gen2 = fc4_type;
4210         qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
4211
4212         sp->u.iocb_cmd.u.ctarg.req = dma_zalloc_coherent(&vha->hw->pdev->dev,
4213             sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
4214             GFP_KERNEL);
4215         if (!sp->u.iocb_cmd.u.ctarg.req) {
4216                 ql_log(ql_log_warn, vha, 0xffff,
4217                     "Failed to allocate ct_sns request.\n");
4218                 vha->scan.scan_flags &= ~SF_SCANNING;
4219                 goto done_free_sp;
4220         }
4221
4222         rspsz = sizeof(struct ct_sns_gpnft_rsp) +
4223                 ((vha->hw->max_fibre_devices - 1) *
4224                     sizeof(struct ct_sns_gpn_ft_data));
4225
4226         sp->u.iocb_cmd.u.ctarg.rsp = dma_zalloc_coherent(&vha->hw->pdev->dev,
4227             rspsz, &sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL);
4228         if (!sp->u.iocb_cmd.u.ctarg.rsp) {
4229                 ql_log(ql_log_warn, vha, 0xffff,
4230                     "Failed to allocate ct_sns request.\n");
4231                 vha->scan.scan_flags &= ~SF_SCANNING;
4232                 goto done_free_sp;
4233         }
4234
4235         memset(vha->scan.l, 0, vha->scan.size);
4236
4237         ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
4238         /* CT_IU preamble  */
4239         ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz);
4240
4241         /* GPN_FT req */
4242         ct_req->req.gpn_ft.port_type = fc4_type;
4243
4244         sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE;
4245         sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz;
4246         sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
4247
4248         sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
4249         sp->done = qla2x00_async_gpnft_gnnft_sp_done;
4250
4251         rval = qla2x00_start_sp(sp);
4252         if (rval != QLA_SUCCESS) {
4253                 vha->scan.scan_flags &= ~SF_SCANNING;
4254                 goto done_free_sp;
4255         }
4256
4257         ql_dbg(ql_dbg_disc, vha, 0xffff,
4258             "Async-%s hdl=%x FC4Type %x.\n", sp->name,
4259             sp->handle, ct_req->req.gpn_ft.port_type);
4260         return rval;
4261
4262 done_free_sp:
4263         if (sp->u.iocb_cmd.u.ctarg.req) {
4264                 dma_free_coherent(&vha->hw->pdev->dev,
4265                     sizeof(struct ct_sns_pkt),
4266                     sp->u.iocb_cmd.u.ctarg.req,
4267                     sp->u.iocb_cmd.u.ctarg.req_dma);
4268                 sp->u.iocb_cmd.u.ctarg.req = NULL;
4269         }
4270         if (sp->u.iocb_cmd.u.ctarg.rsp) {
4271                 dma_free_coherent(&vha->hw->pdev->dev,
4272                     sizeof(struct ct_sns_pkt),
4273                     sp->u.iocb_cmd.u.ctarg.rsp,
4274                     sp->u.iocb_cmd.u.ctarg.rsp_dma);
4275                 sp->u.iocb_cmd.u.ctarg.rsp = NULL;
4276         }
4277
4278         sp->free(sp);
4279
4280         return rval;
4281 }
4282
4283 void qla_scan_work_fn(struct work_struct *work)
4284 {
4285         struct fab_scan *s = container_of(to_delayed_work(work),
4286             struct fab_scan, scan_work);
4287         struct scsi_qla_host *vha = container_of(s, struct scsi_qla_host,
4288             scan);
4289         unsigned long flags;
4290
4291         ql_dbg(ql_dbg_disc, vha, 0xffff,
4292             "%s: schedule loop resync\n", __func__);
4293         set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
4294         set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
4295         qla2xxx_wake_dpc(vha);
4296         spin_lock_irqsave(&vha->work_lock, flags);
4297         vha->scan.scan_flags &= ~SF_QUEUED;
4298         spin_unlock_irqrestore(&vha->work_lock, flags);
4299 }
4300
4301 /* GNN_ID */
4302 void qla24xx_handle_gnnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
4303 {
4304         qla24xx_post_gnl_work(vha, ea->fcport);
4305 }
4306
4307 static void qla2x00_async_gnnid_sp_done(void *s, int res)
4308 {
4309         struct srb *sp = s;
4310         struct scsi_qla_host *vha = sp->vha;
4311         fc_port_t *fcport = sp->fcport;
4312         u8 *node_name = fcport->ct_desc.ct_sns->p.rsp.rsp.gnn_id.node_name;
4313         struct event_arg ea;
4314         u64 wwnn;
4315
4316         fcport->flags &= ~FCF_ASYNC_SENT;
4317         wwnn = wwn_to_u64(node_name);
4318         if (wwnn)
4319                 memcpy(fcport->node_name, node_name, WWN_SIZE);
4320
4321         memset(&ea, 0, sizeof(ea));
4322         ea.fcport = fcport;
4323         ea.sp = sp;
4324         ea.rc = res;
4325         ea.event = FCME_GNNID_DONE;
4326
4327         ql_dbg(ql_dbg_disc, vha, 0x204f,
4328             "Async done-%s res %x, WWPN %8phC %8phC\n",
4329             sp->name, res, fcport->port_name, fcport->node_name);
4330
4331         qla2x00_fcport_event_handler(vha, &ea);
4332
4333         sp->free(sp);
4334 }
4335
4336 int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport)
4337 {
4338         int rval = QLA_FUNCTION_FAILED;
4339         struct ct_sns_req       *ct_req;
4340         srb_t *sp;
4341
4342         if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
4343                 return rval;
4344
4345         fcport->disc_state = DSC_GNN_ID;
4346         sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
4347         if (!sp)
4348                 goto done;
4349
4350         fcport->flags |= FCF_ASYNC_SENT;
4351         sp->type = SRB_CT_PTHRU_CMD;
4352         sp->name = "gnnid";
4353         sp->gen1 = fcport->rscn_gen;
4354         sp->gen2 = fcport->login_gen;
4355
4356         qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
4357
4358         /* CT_IU preamble  */
4359         ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GNN_ID_CMD,
4360             GNN_ID_RSP_SIZE);
4361
4362         /* GNN_ID req */
4363         ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
4364         ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
4365         ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
4366
4367
4368         /* req & rsp use the same buffer */
4369         sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
4370         sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
4371         sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
4372         sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
4373         sp->u.iocb_cmd.u.ctarg.req_size = GNN_ID_REQ_SIZE;
4374         sp->u.iocb_cmd.u.ctarg.rsp_size = GNN_ID_RSP_SIZE;
4375         sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
4376
4377         sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
4378         sp->done = qla2x00_async_gnnid_sp_done;
4379
4380         rval = qla2x00_start_sp(sp);
4381         if (rval != QLA_SUCCESS)
4382                 goto done_free_sp;
4383         ql_dbg(ql_dbg_disc, vha, 0xffff,
4384             "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n",
4385             sp->name, fcport->port_name,
4386             sp->handle, fcport->loop_id, fcport->d_id.b24);
4387         return rval;
4388
4389 done_free_sp:
4390         sp->free(sp);
4391         fcport->flags &= ~FCF_ASYNC_SENT;
4392 done:
4393         return rval;
4394 }
4395
4396 int qla24xx_post_gnnid_work(struct scsi_qla_host *vha, fc_port_t *fcport)
4397 {
4398         struct qla_work_evt *e;
4399         int ls;
4400
4401         ls = atomic_read(&vha->loop_state);
4402         if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
4403                 test_bit(UNLOADING, &vha->dpc_flags))
4404                 return 0;
4405
4406         e = qla2x00_alloc_work(vha, QLA_EVT_GNNID);
4407         if (!e)
4408                 return QLA_FUNCTION_FAILED;
4409
4410         e->u.fcport.fcport = fcport;
4411         return qla2x00_post_work(vha, e);
4412 }
4413
4414 /* GPFN_ID */
4415 void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
4416 {
4417         fc_port_t *fcport = ea->fcport;
4418
4419         ql_dbg(ql_dbg_disc, vha, 0xffff,
4420             "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d fcpcnt %d\n",
4421             __func__, fcport->port_name, fcport->disc_state,
4422             fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
4423             fcport->rscn_gen, ea->sp->gen1, vha->fcport_count);
4424
4425         if (fcport->disc_state == DSC_DELETE_PEND)
4426                 return;
4427
4428         if (ea->sp->gen2 != fcport->login_gen) {
4429                 /* target side must have changed it. */
4430                 ql_dbg(ql_dbg_disc, vha, 0x20d3,
4431                     "%s %8phC generation changed\n",
4432                     __func__, fcport->port_name);
4433                 return;
4434         } else if (ea->sp->gen1 != fcport->rscn_gen) {
4435                 ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
4436                     __func__, __LINE__, fcport->port_name);
4437                 qla24xx_post_gidpn_work(vha, fcport);
4438                 return;
4439         }
4440
4441         qla24xx_post_gpsc_work(vha, fcport);
4442 }
4443
4444 static void qla2x00_async_gfpnid_sp_done(void *s, int res)
4445 {
4446         struct srb *sp = s;
4447         struct scsi_qla_host *vha = sp->vha;
4448         fc_port_t *fcport = sp->fcport;
4449         u8 *fpn = fcport->ct_desc.ct_sns->p.rsp.rsp.gfpn_id.port_name;
4450         struct event_arg ea;
4451         u64 wwn;
4452
4453         fcport->flags &= ~FCF_ASYNC_SENT;
4454         wwn = wwn_to_u64(fpn);
4455         if (wwn)
4456                 memcpy(fcport->fabric_port_name, fpn, WWN_SIZE);
4457
4458         memset(&ea, 0, sizeof(ea));
4459         ea.fcport = fcport;
4460         ea.sp = sp;
4461         ea.rc = res;
4462         ea.event = FCME_GFPNID_DONE;
4463
4464         ql_dbg(ql_dbg_disc, vha, 0x204f,
4465             "Async done-%s res %x, WWPN %8phC %8phC\n",
4466             sp->name, res, fcport->port_name, fcport->fabric_port_name);
4467
4468         qla2x00_fcport_event_handler(vha, &ea);
4469
4470         sp->free(sp);
4471 }
4472
4473 int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport)
4474 {
4475         int rval = QLA_FUNCTION_FAILED;
4476         struct ct_sns_req       *ct_req;
4477         srb_t *sp;
4478
4479         if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
4480                 return rval;
4481
4482         fcport->disc_state = DSC_GFPN_ID;
4483         sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
4484         if (!sp)
4485                 goto done;
4486
4487         fcport->flags |= FCF_ASYNC_SENT;
4488         sp->type = SRB_CT_PTHRU_CMD;
4489         sp->name = "gfpnid";
4490         sp->gen1 = fcport->rscn_gen;
4491         sp->gen2 = fcport->login_gen;
4492
4493         qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
4494
4495         /* CT_IU preamble  */
4496         ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFPN_ID_CMD,
4497             GFPN_ID_RSP_SIZE);
4498
4499         /* GFPN_ID req */
4500         ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
4501         ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
4502         ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
4503
4504
4505         /* req & rsp use the same buffer */
4506         sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
4507         sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
4508         sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
4509         sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
4510         sp->u.iocb_cmd.u.ctarg.req_size = GFPN_ID_REQ_SIZE;
4511         sp->u.iocb_cmd.u.ctarg.rsp_size = GFPN_ID_RSP_SIZE;
4512         sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
4513
4514         sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
4515         sp->done = qla2x00_async_gfpnid_sp_done;
4516
4517         rval = qla2x00_start_sp(sp);
4518         if (rval != QLA_SUCCESS)
4519                 goto done_free_sp;
4520
4521         ql_dbg(ql_dbg_disc, vha, 0xffff,
4522             "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n",
4523             sp->name, fcport->port_name,
4524             sp->handle, fcport->loop_id, fcport->d_id.b24);
4525         return rval;
4526
4527 done_free_sp:
4528         sp->free(sp);
4529         fcport->flags &= ~FCF_ASYNC_SENT;
4530 done:
4531         return rval;
4532 }
4533
4534 int qla24xx_post_gfpnid_work(struct scsi_qla_host *vha, fc_port_t *fcport)
4535 {
4536         struct qla_work_evt *e;
4537         int ls;
4538
4539         ls = atomic_read(&vha->loop_state);
4540         if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
4541                 test_bit(UNLOADING, &vha->dpc_flags))
4542                 return 0;
4543
4544         e = qla2x00_alloc_work(vha, QLA_EVT_GFPNID);
4545         if (!e)
4546                 return QLA_FUNCTION_FAILED;
4547
4548         e->u.fcport.fcport = fcport;
4549         return qla2x00_post_work(vha, e);
4550 }