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