2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2014 QLogic Corporation
5 * See LICENSE.qla2xxx for copyright and licensing details.
8 #include "qla_target.h"
9 #include <linux/utsname.h>
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 *);
19 * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
21 * @req_size: request size in bytes
22 * @rsp_size: response size in bytes
24 * Returns a pointer to the @ha's ms_iocb.
27 qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
29 struct qla_hw_data *ha = vha->hw;
30 ms_iocb_entry_t *ms_pkt;
32 ms_pkt = (ms_iocb_entry_t *)arg->iocb;
33 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
35 ms_pkt->entry_type = MS_IOCB_TYPE;
36 ms_pkt->entry_count = 1;
37 SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
38 ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
39 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
40 ms_pkt->cmd_dsd_count = cpu_to_le16(1);
41 ms_pkt->total_dsd_count = cpu_to_le16(2);
42 ms_pkt->rsp_bytecount = cpu_to_le32(arg->rsp_size);
43 ms_pkt->req_bytecount = cpu_to_le32(arg->req_size);
45 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(arg->req_dma));
46 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(arg->req_dma));
47 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
49 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(arg->rsp_dma));
50 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(arg->rsp_dma));
51 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
53 vha->qla_stats.control_requests++;
59 * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
61 * @req_size: request size in bytes
62 * @rsp_size: response size in bytes
64 * Returns a pointer to the @ha's ms_iocb.
67 qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
69 struct qla_hw_data *ha = vha->hw;
70 struct ct_entry_24xx *ct_pkt;
72 ct_pkt = (struct ct_entry_24xx *)arg->iocb;
73 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
75 ct_pkt->entry_type = CT_IOCB_TYPE;
76 ct_pkt->entry_count = 1;
77 ct_pkt->nport_handle = cpu_to_le16(arg->nport_handle);
78 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
79 ct_pkt->cmd_dsd_count = cpu_to_le16(1);
80 ct_pkt->rsp_dsd_count = cpu_to_le16(1);
81 ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size);
82 ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size);
84 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(arg->req_dma));
85 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(arg->req_dma));
86 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
88 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(arg->rsp_dma));
89 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(arg->rsp_dma));
90 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
91 ct_pkt->vp_index = vha->vp_idx;
93 vha->qla_stats.control_requests++;
99 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
100 * @ct_req: CT request buffer
102 * @rsp_size: response size in bytes
104 * Returns a pointer to the intitialized @ct_req.
106 static inline struct ct_sns_req *
107 qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size)
109 memset(p, 0, sizeof(struct ct_sns_pkt));
111 p->p.req.header.revision = 0x01;
112 p->p.req.header.gs_type = 0xFC;
113 p->p.req.header.gs_subtype = 0x02;
114 p->p.req.command = cpu_to_be16(cmd);
115 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
121 qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt,
122 struct ct_sns_rsp *ct_rsp, const char *routine)
125 uint16_t comp_status;
126 struct qla_hw_data *ha = vha->hw;
127 bool lid_is_sns = false;
129 rval = QLA_FUNCTION_FAILED;
130 if (ms_pkt->entry_status != 0) {
131 ql_dbg(ql_dbg_disc, vha, 0x2031,
132 "%s failed, error status (%x) on port_id: %02x%02x%02x.\n",
133 routine, ms_pkt->entry_status, vha->d_id.b.domain,
134 vha->d_id.b.area, vha->d_id.b.al_pa);
136 if (IS_FWI2_CAPABLE(ha))
137 comp_status = le16_to_cpu(
138 ((struct ct_entry_24xx *)ms_pkt)->comp_status);
140 comp_status = le16_to_cpu(ms_pkt->status);
141 switch (comp_status) {
143 case CS_DATA_UNDERRUN:
144 case CS_DATA_OVERRUN: /* Overrun? */
145 if (ct_rsp->header.response !=
146 cpu_to_be16(CT_ACCEPT_RESPONSE)) {
147 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077,
148 "%s failed rejected request on port_id: %02x%02x%02x Completion status 0x%x, response 0x%x\n",
149 routine, vha->d_id.b.domain,
150 vha->d_id.b.area, vha->d_id.b.al_pa,
151 comp_status, ct_rsp->header.response);
152 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha,
153 0x2078, (uint8_t *)&ct_rsp->header,
154 sizeof(struct ct_rsp_hdr));
155 rval = QLA_INVALID_COMMAND;
159 case CS_PORT_LOGGED_OUT:
160 if (IS_FWI2_CAPABLE(ha)) {
161 if (le16_to_cpu(ms_pkt->loop_id.extended) ==
165 if (le16_to_cpu(ms_pkt->loop_id.extended) ==
170 ql_dbg(ql_dbg_async, vha, 0x502b,
171 "%s failed, Name server has logged out",
173 rval = QLA_NOT_LOGGED_IN;
174 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
175 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
179 rval = QLA_FUNCTION_TIMEOUT;
182 ql_dbg(ql_dbg_disc, vha, 0x2033,
183 "%s failed, completion status (%x) on port_id: "
184 "%02x%02x%02x.\n", routine, comp_status,
185 vha->d_id.b.domain, vha->d_id.b.area,
194 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
196 * @fcport: fcport entry to updated
198 * Returns 0 on success.
201 qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
205 ms_iocb_entry_t *ms_pkt;
206 struct ct_sns_req *ct_req;
207 struct ct_sns_rsp *ct_rsp;
208 struct qla_hw_data *ha = vha->hw;
211 if (IS_QLA2100(ha) || IS_QLA2200(ha))
212 return qla2x00_sns_ga_nxt(vha, fcport);
214 arg.iocb = ha->ms_iocb;
215 arg.req_dma = ha->ct_sns_dma;
216 arg.rsp_dma = ha->ct_sns_dma;
217 arg.req_size = GA_NXT_REQ_SIZE;
218 arg.rsp_size = GA_NXT_RSP_SIZE;
219 arg.nport_handle = NPH_SNS;
222 /* Prepare common MS IOCB */
223 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
225 /* Prepare CT request */
226 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD,
228 ct_rsp = &ha->ct_sns->p.rsp;
230 /* Prepare CT arguments -- port_id */
231 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
232 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
233 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
235 /* Execute MS IOCB */
236 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
237 sizeof(ms_iocb_entry_t));
238 if (rval != QLA_SUCCESS) {
240 ql_dbg(ql_dbg_disc, vha, 0x2062,
241 "GA_NXT issue IOCB failed (%d).\n", rval);
242 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") !=
244 rval = QLA_FUNCTION_FAILED;
246 /* Populate fc_port_t entry. */
247 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0];
248 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1];
249 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2];
251 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name,
253 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name,
256 fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ?
257 FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER;
259 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
260 ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
261 fcport->d_id.b.domain = 0xf0;
263 ql_dbg(ql_dbg_disc, vha, 0x2063,
264 "GA_NXT entry - nn %8phN pn %8phN "
265 "port_id=%02x%02x%02x.\n",
266 fcport->node_name, fcport->port_name,
267 fcport->d_id.b.domain, fcport->d_id.b.area,
268 fcport->d_id.b.al_pa);
275 qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha)
277 return vha->hw->max_fibre_devices * 4 + 16;
281 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
283 * @list: switch info entries to populate
285 * NOTE: Non-Nx_Ports are not requested.
287 * Returns 0 on success.
290 qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
295 ms_iocb_entry_t *ms_pkt;
296 struct ct_sns_req *ct_req;
297 struct ct_sns_rsp *ct_rsp;
299 struct ct_sns_gid_pt_data *gid_data;
300 struct qla_hw_data *ha = vha->hw;
301 uint16_t gid_pt_rsp_size;
304 if (IS_QLA2100(ha) || IS_QLA2200(ha))
305 return qla2x00_sns_gid_pt(vha, list);
308 gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha);
310 arg.iocb = ha->ms_iocb;
311 arg.req_dma = ha->ct_sns_dma;
312 arg.rsp_dma = ha->ct_sns_dma;
313 arg.req_size = GID_PT_REQ_SIZE;
314 arg.rsp_size = gid_pt_rsp_size;
315 arg.nport_handle = NPH_SNS;
318 /* Prepare common MS IOCB */
319 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
321 /* Prepare CT request */
322 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size);
323 ct_rsp = &ha->ct_sns->p.rsp;
325 /* Prepare CT arguments -- port_type */
326 ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE;
328 /* Execute MS IOCB */
329 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
330 sizeof(ms_iocb_entry_t));
331 if (rval != QLA_SUCCESS) {
333 ql_dbg(ql_dbg_disc, vha, 0x2055,
334 "GID_PT issue IOCB failed (%d).\n", rval);
335 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") !=
337 rval = QLA_FUNCTION_FAILED;
339 /* Set port IDs in switch info list. */
340 for (i = 0; i < ha->max_fibre_devices; i++) {
341 gid_data = &ct_rsp->rsp.gid_pt.entries[i];
342 list[i].d_id.b.domain = gid_data->port_id[0];
343 list[i].d_id.b.area = gid_data->port_id[1];
344 list[i].d_id.b.al_pa = gid_data->port_id[2];
345 memset(list[i].fabric_port_name, 0, WWN_SIZE);
346 list[i].fp_speed = PORT_SPEED_UNKNOWN;
349 if (gid_data->control_byte & BIT_7) {
350 list[i].d_id.b.rsvd_1 = gid_data->control_byte;
356 * If we've used all available slots, then the switch is
357 * reporting back more devices than we can handle with this
358 * single call. Return a failed status, and let GA_NXT handle
361 if (i == ha->max_fibre_devices)
362 rval = QLA_FUNCTION_FAILED;
369 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
371 * @list: switch info entries to populate
373 * Returns 0 on success.
376 qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
378 int rval = QLA_SUCCESS;
381 ms_iocb_entry_t *ms_pkt;
382 struct ct_sns_req *ct_req;
383 struct ct_sns_rsp *ct_rsp;
384 struct qla_hw_data *ha = vha->hw;
387 if (IS_QLA2100(ha) || IS_QLA2200(ha))
388 return qla2x00_sns_gpn_id(vha, list);
390 arg.iocb = ha->ms_iocb;
391 arg.req_dma = ha->ct_sns_dma;
392 arg.rsp_dma = ha->ct_sns_dma;
393 arg.req_size = GPN_ID_REQ_SIZE;
394 arg.rsp_size = GPN_ID_RSP_SIZE;
395 arg.nport_handle = NPH_SNS;
397 for (i = 0; i < ha->max_fibre_devices; i++) {
399 /* Prepare common MS IOCB */
400 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
402 /* Prepare CT request */
403 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD,
405 ct_rsp = &ha->ct_sns->p.rsp;
407 /* Prepare CT arguments -- port_id */
408 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
409 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
410 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
412 /* Execute MS IOCB */
413 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
414 sizeof(ms_iocb_entry_t));
415 if (rval != QLA_SUCCESS) {
417 ql_dbg(ql_dbg_disc, vha, 0x2056,
418 "GPN_ID issue IOCB failed (%d).\n", rval);
420 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
421 "GPN_ID") != QLA_SUCCESS) {
422 rval = QLA_FUNCTION_FAILED;
426 memcpy(list[i].port_name,
427 ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
430 /* Last device exit. */
431 if (list[i].d_id.b.rsvd_1 != 0)
439 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
441 * @list: switch info entries to populate
443 * Returns 0 on success.
446 qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
448 int rval = QLA_SUCCESS;
450 struct qla_hw_data *ha = vha->hw;
451 ms_iocb_entry_t *ms_pkt;
452 struct ct_sns_req *ct_req;
453 struct ct_sns_rsp *ct_rsp;
456 if (IS_QLA2100(ha) || IS_QLA2200(ha))
457 return qla2x00_sns_gnn_id(vha, list);
459 arg.iocb = ha->ms_iocb;
460 arg.req_dma = ha->ct_sns_dma;
461 arg.rsp_dma = ha->ct_sns_dma;
462 arg.req_size = GNN_ID_REQ_SIZE;
463 arg.rsp_size = GNN_ID_RSP_SIZE;
464 arg.nport_handle = NPH_SNS;
466 for (i = 0; i < ha->max_fibre_devices; i++) {
468 /* Prepare common MS IOCB */
469 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
471 /* Prepare CT request */
472 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD,
474 ct_rsp = &ha->ct_sns->p.rsp;
476 /* Prepare CT arguments -- port_id */
477 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
478 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
479 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
481 /* Execute MS IOCB */
482 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
483 sizeof(ms_iocb_entry_t));
484 if (rval != QLA_SUCCESS) {
486 ql_dbg(ql_dbg_disc, vha, 0x2057,
487 "GNN_ID issue IOCB failed (%d).\n", rval);
489 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
490 "GNN_ID") != QLA_SUCCESS) {
491 rval = QLA_FUNCTION_FAILED;
495 memcpy(list[i].node_name,
496 ct_rsp->rsp.gnn_id.node_name, WWN_SIZE);
498 ql_dbg(ql_dbg_disc, vha, 0x2058,
499 "GID_PT entry - nn %8phN pn %8phN "
500 "portid=%02x%02x%02x.\n",
501 list[i].node_name, list[i].port_name,
502 list[i].d_id.b.domain, list[i].d_id.b.area,
503 list[i].d_id.b.al_pa);
506 /* Last device exit. */
507 if (list[i].d_id.b.rsvd_1 != 0)
515 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
518 * Returns 0 on success.
521 qla2x00_rft_id(scsi_qla_host_t *vha)
524 struct qla_hw_data *ha = vha->hw;
525 ms_iocb_entry_t *ms_pkt;
526 struct ct_sns_req *ct_req;
527 struct ct_sns_rsp *ct_rsp;
530 if (IS_QLA2100(ha) || IS_QLA2200(ha))
531 return qla2x00_sns_rft_id(vha);
533 arg.iocb = ha->ms_iocb;
534 arg.req_dma = ha->ct_sns_dma;
535 arg.rsp_dma = ha->ct_sns_dma;
536 arg.req_size = RFT_ID_REQ_SIZE;
537 arg.rsp_size = RFT_ID_RSP_SIZE;
538 arg.nport_handle = NPH_SNS;
541 /* Prepare common MS IOCB */
542 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
544 /* Prepare CT request */
545 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFT_ID_CMD,
547 ct_rsp = &ha->ct_sns->p.rsp;
549 /* Prepare CT arguments -- port_id, FC-4 types */
550 ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain;
551 ct_req->req.rft_id.port_id[1] = vha->d_id.b.area;
552 ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa;
554 ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */
556 if (vha->flags.nvme_enabled)
557 ct_req->req.rft_id.fc4_types[6] = 1; /* NVMe type 28h */
558 /* Execute MS IOCB */
559 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
560 sizeof(ms_iocb_entry_t));
561 if (rval != QLA_SUCCESS) {
563 ql_dbg(ql_dbg_disc, vha, 0x2043,
564 "RFT_ID issue IOCB failed (%d).\n", rval);
565 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFT_ID") !=
567 rval = QLA_FUNCTION_FAILED;
569 ql_dbg(ql_dbg_disc, vha, 0x2044,
570 "RFT_ID exiting normally.\n");
577 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
580 * Returns 0 on success.
583 qla2x00_rff_id(scsi_qla_host_t *vha, u8 type)
586 struct qla_hw_data *ha = vha->hw;
587 ms_iocb_entry_t *ms_pkt;
588 struct ct_sns_req *ct_req;
589 struct ct_sns_rsp *ct_rsp;
592 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
593 ql_dbg(ql_dbg_disc, vha, 0x2046,
594 "RFF_ID call not supported on ISP2100/ISP2200.\n");
595 return (QLA_SUCCESS);
598 arg.iocb = ha->ms_iocb;
599 arg.req_dma = ha->ct_sns_dma;
600 arg.rsp_dma = ha->ct_sns_dma;
601 arg.req_size = RFF_ID_REQ_SIZE;
602 arg.rsp_size = RFF_ID_RSP_SIZE;
603 arg.nport_handle = NPH_SNS;
606 /* Prepare common MS IOCB */
607 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
609 /* Prepare CT request */
610 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFF_ID_CMD,
612 ct_rsp = &ha->ct_sns->p.rsp;
614 /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
615 ct_req->req.rff_id.port_id[0] = vha->d_id.b.domain;
616 ct_req->req.rff_id.port_id[1] = vha->d_id.b.area;
617 ct_req->req.rff_id.port_id[2] = vha->d_id.b.al_pa;
619 qlt_rff_id(vha, ct_req);
621 ct_req->req.rff_id.fc4_type = type; /* SCSI - FCP */
623 /* Execute MS IOCB */
624 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
625 sizeof(ms_iocb_entry_t));
626 if (rval != QLA_SUCCESS) {
628 ql_dbg(ql_dbg_disc, vha, 0x2047,
629 "RFF_ID issue IOCB failed (%d).\n", rval);
630 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFF_ID") !=
632 rval = QLA_FUNCTION_FAILED;
634 ql_dbg(ql_dbg_disc, vha, 0x2048,
635 "RFF_ID exiting normally.\n");
642 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
645 * Returns 0 on success.
648 qla2x00_rnn_id(scsi_qla_host_t *vha)
651 struct qla_hw_data *ha = vha->hw;
652 ms_iocb_entry_t *ms_pkt;
653 struct ct_sns_req *ct_req;
654 struct ct_sns_rsp *ct_rsp;
657 if (IS_QLA2100(ha) || IS_QLA2200(ha))
658 return qla2x00_sns_rnn_id(vha);
660 arg.iocb = ha->ms_iocb;
661 arg.req_dma = ha->ct_sns_dma;
662 arg.rsp_dma = ha->ct_sns_dma;
663 arg.req_size = RNN_ID_REQ_SIZE;
664 arg.rsp_size = RNN_ID_RSP_SIZE;
665 arg.nport_handle = NPH_SNS;
668 /* Prepare common MS IOCB */
669 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
671 /* Prepare CT request */
672 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE);
673 ct_rsp = &ha->ct_sns->p.rsp;
675 /* Prepare CT arguments -- port_id, node_name */
676 ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain;
677 ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area;
678 ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa;
680 memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE);
682 /* Execute MS IOCB */
683 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
684 sizeof(ms_iocb_entry_t));
685 if (rval != QLA_SUCCESS) {
687 ql_dbg(ql_dbg_disc, vha, 0x204d,
688 "RNN_ID issue IOCB failed (%d).\n", rval);
689 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RNN_ID") !=
691 rval = QLA_FUNCTION_FAILED;
693 ql_dbg(ql_dbg_disc, vha, 0x204e,
694 "RNN_ID exiting normally.\n");
701 qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn, size_t size)
703 struct qla_hw_data *ha = vha->hw;
706 snprintf(snn, size, "%s FW:v%s DVR:v%s", ha->model_number,
707 ha->mr.fw_version, qla2x00_version_str);
710 "%s FW:v%d.%02d.%02d DVR:v%s", ha->model_number,
711 ha->fw_major_version, ha->fw_minor_version,
712 ha->fw_subminor_version, qla2x00_version_str);
716 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
719 * Returns 0 on success.
722 qla2x00_rsnn_nn(scsi_qla_host_t *vha)
725 struct qla_hw_data *ha = vha->hw;
726 ms_iocb_entry_t *ms_pkt;
727 struct ct_sns_req *ct_req;
728 struct ct_sns_rsp *ct_rsp;
731 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
732 ql_dbg(ql_dbg_disc, vha, 0x2050,
733 "RSNN_ID call unsupported on ISP2100/ISP2200.\n");
734 return (QLA_SUCCESS);
737 arg.iocb = ha->ms_iocb;
738 arg.req_dma = ha->ct_sns_dma;
739 arg.rsp_dma = ha->ct_sns_dma;
741 arg.rsp_size = RSNN_NN_RSP_SIZE;
742 arg.nport_handle = NPH_SNS;
745 /* Prepare common MS IOCB */
746 /* Request size adjusted after CT preparation */
747 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
749 /* Prepare CT request */
750 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RSNN_NN_CMD,
752 ct_rsp = &ha->ct_sns->p.rsp;
754 /* Prepare CT arguments -- node_name, symbolic node_name, size */
755 memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE);
757 /* Prepare the Symbolic Node Name */
758 qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name,
759 sizeof(ct_req->req.rsnn_nn.sym_node_name));
761 /* Calculate SNN length */
762 ct_req->req.rsnn_nn.name_len =
763 (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
765 /* Update MS IOCB request */
766 ms_pkt->req_bytecount =
767 cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len);
768 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
770 /* Execute MS IOCB */
771 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
772 sizeof(ms_iocb_entry_t));
773 if (rval != QLA_SUCCESS) {
775 ql_dbg(ql_dbg_disc, vha, 0x2051,
776 "RSNN_NN issue IOCB failed (%d).\n", rval);
777 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RSNN_NN") !=
779 rval = QLA_FUNCTION_FAILED;
781 ql_dbg(ql_dbg_disc, vha, 0x2052,
782 "RSNN_NN exiting normally.\n");
789 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
792 * @scmd_len: Subcommand length
793 * @data_size: response size in bytes
795 * Returns a pointer to the @ha's sns_cmd.
797 static inline struct sns_cmd_pkt *
798 qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
802 struct sns_cmd_pkt *sns_cmd;
803 struct qla_hw_data *ha = vha->hw;
805 sns_cmd = ha->sns_cmd;
806 memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt));
807 wc = data_size / 2; /* Size in 16bit words. */
808 sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc);
809 sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma));
810 sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma));
811 sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len);
812 sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd);
813 wc = (data_size - 16) / 4; /* Size in 32bit words. */
814 sns_cmd->p.cmd.size = cpu_to_le16(wc);
816 vha->qla_stats.control_requests++;
822 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
824 * @fcport: fcport entry to updated
826 * This command uses the old Exectute SNS Command mailbox routine.
828 * Returns 0 on success.
831 qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
833 int rval = QLA_SUCCESS;
834 struct qla_hw_data *ha = vha->hw;
835 struct sns_cmd_pkt *sns_cmd;
838 /* Prepare SNS command request. */
839 sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN,
840 GA_NXT_SNS_DATA_SIZE);
842 /* Prepare SNS command arguments -- port_id. */
843 sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa;
844 sns_cmd->p.cmd.param[1] = fcport->d_id.b.area;
845 sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain;
847 /* Execute SNS command. */
848 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2,
849 sizeof(struct sns_cmd_pkt));
850 if (rval != QLA_SUCCESS) {
852 ql_dbg(ql_dbg_disc, vha, 0x205f,
853 "GA_NXT Send SNS failed (%d).\n", rval);
854 } else if (sns_cmd->p.gan_data[8] != 0x80 ||
855 sns_cmd->p.gan_data[9] != 0x02) {
856 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084,
857 "GA_NXT failed, rejected request ga_nxt_rsp:\n");
858 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074,
859 sns_cmd->p.gan_data, 16);
860 rval = QLA_FUNCTION_FAILED;
862 /* Populate fc_port_t entry. */
863 fcport->d_id.b.domain = sns_cmd->p.gan_data[17];
864 fcport->d_id.b.area = sns_cmd->p.gan_data[18];
865 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19];
867 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE);
868 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE);
870 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE &&
871 sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE)
872 fcport->d_id.b.domain = 0xf0;
874 ql_dbg(ql_dbg_disc, vha, 0x2061,
875 "GA_NXT entry - nn %8phN pn %8phN "
876 "port_id=%02x%02x%02x.\n",
877 fcport->node_name, fcport->port_name,
878 fcport->d_id.b.domain, fcport->d_id.b.area,
879 fcport->d_id.b.al_pa);
886 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
888 * @list: switch info entries to populate
890 * This command uses the old Exectute SNS Command mailbox routine.
892 * NOTE: Non-Nx_Ports are not requested.
894 * Returns 0 on success.
897 qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
900 struct qla_hw_data *ha = vha->hw;
903 struct sns_cmd_pkt *sns_cmd;
904 uint16_t gid_pt_sns_data_size;
906 gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha);
909 /* Prepare SNS command request. */
910 sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN,
911 gid_pt_sns_data_size);
913 /* Prepare SNS command arguments -- port_type. */
914 sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE;
916 /* Execute SNS command. */
917 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2,
918 sizeof(struct sns_cmd_pkt));
919 if (rval != QLA_SUCCESS) {
921 ql_dbg(ql_dbg_disc, vha, 0x206d,
922 "GID_PT Send SNS failed (%d).\n", rval);
923 } else if (sns_cmd->p.gid_data[8] != 0x80 ||
924 sns_cmd->p.gid_data[9] != 0x02) {
925 ql_dbg(ql_dbg_disc, vha, 0x202f,
926 "GID_PT failed, rejected request, gid_rsp:\n");
927 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081,
928 sns_cmd->p.gid_data, 16);
929 rval = QLA_FUNCTION_FAILED;
931 /* Set port IDs in switch info list. */
932 for (i = 0; i < ha->max_fibre_devices; i++) {
933 entry = &sns_cmd->p.gid_data[(i * 4) + 16];
934 list[i].d_id.b.domain = entry[1];
935 list[i].d_id.b.area = entry[2];
936 list[i].d_id.b.al_pa = entry[3];
939 if (entry[0] & BIT_7) {
940 list[i].d_id.b.rsvd_1 = entry[0];
946 * If we've used all available slots, then the switch is
947 * reporting back more devices that we can handle with this
948 * single call. Return a failed status, and let GA_NXT handle
951 if (i == ha->max_fibre_devices)
952 rval = QLA_FUNCTION_FAILED;
959 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
961 * @list: switch info entries to populate
963 * This command uses the old Exectute SNS Command mailbox routine.
965 * Returns 0 on success.
968 qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
970 int rval = QLA_SUCCESS;
971 struct qla_hw_data *ha = vha->hw;
973 struct sns_cmd_pkt *sns_cmd;
975 for (i = 0; i < ha->max_fibre_devices; i++) {
977 /* Prepare SNS command request. */
978 sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD,
979 GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE);
981 /* Prepare SNS command arguments -- port_id. */
982 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
983 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
984 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
986 /* Execute SNS command. */
987 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
988 GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
989 if (rval != QLA_SUCCESS) {
991 ql_dbg(ql_dbg_disc, vha, 0x2032,
992 "GPN_ID Send SNS failed (%d).\n", rval);
993 } else if (sns_cmd->p.gpn_data[8] != 0x80 ||
994 sns_cmd->p.gpn_data[9] != 0x02) {
995 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e,
996 "GPN_ID failed, rejected request, gpn_rsp:\n");
997 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207f,
998 sns_cmd->p.gpn_data, 16);
999 rval = QLA_FUNCTION_FAILED;
1002 memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16],
1006 /* Last device exit. */
1007 if (list[i].d_id.b.rsvd_1 != 0)
1015 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
1017 * @list: switch info entries to populate
1019 * This command uses the old Exectute SNS Command mailbox routine.
1021 * Returns 0 on success.
1024 qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
1026 int rval = QLA_SUCCESS;
1027 struct qla_hw_data *ha = vha->hw;
1029 struct sns_cmd_pkt *sns_cmd;
1031 for (i = 0; i < ha->max_fibre_devices; i++) {
1033 /* Prepare SNS command request. */
1034 sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD,
1035 GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE);
1037 /* Prepare SNS command arguments -- port_id. */
1038 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
1039 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
1040 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
1042 /* Execute SNS command. */
1043 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
1044 GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
1045 if (rval != QLA_SUCCESS) {
1047 ql_dbg(ql_dbg_disc, vha, 0x203f,
1048 "GNN_ID Send SNS failed (%d).\n", rval);
1049 } else if (sns_cmd->p.gnn_data[8] != 0x80 ||
1050 sns_cmd->p.gnn_data[9] != 0x02) {
1051 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082,
1052 "GNN_ID failed, rejected request, gnn_rsp:\n");
1053 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a,
1054 sns_cmd->p.gnn_data, 16);
1055 rval = QLA_FUNCTION_FAILED;
1058 memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16],
1061 ql_dbg(ql_dbg_disc, vha, 0x206e,
1062 "GID_PT entry - nn %8phN pn %8phN "
1063 "port_id=%02x%02x%02x.\n",
1064 list[i].node_name, list[i].port_name,
1065 list[i].d_id.b.domain, list[i].d_id.b.area,
1066 list[i].d_id.b.al_pa);
1069 /* Last device exit. */
1070 if (list[i].d_id.b.rsvd_1 != 0)
1078 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
1081 * This command uses the old Exectute SNS Command mailbox routine.
1083 * Returns 0 on success.
1086 qla2x00_sns_rft_id(scsi_qla_host_t *vha)
1089 struct qla_hw_data *ha = vha->hw;
1090 struct sns_cmd_pkt *sns_cmd;
1093 /* Prepare SNS command request. */
1094 sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN,
1095 RFT_ID_SNS_DATA_SIZE);
1097 /* Prepare SNS command arguments -- port_id, FC-4 types */
1098 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1099 sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1100 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
1102 sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */
1104 /* Execute SNS command. */
1105 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2,
1106 sizeof(struct sns_cmd_pkt));
1107 if (rval != QLA_SUCCESS) {
1109 ql_dbg(ql_dbg_disc, vha, 0x2060,
1110 "RFT_ID Send SNS failed (%d).\n", rval);
1111 } else if (sns_cmd->p.rft_data[8] != 0x80 ||
1112 sns_cmd->p.rft_data[9] != 0x02) {
1113 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083,
1114 "RFT_ID failed, rejected request rft_rsp:\n");
1115 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080,
1116 sns_cmd->p.rft_data, 16);
1117 rval = QLA_FUNCTION_FAILED;
1119 ql_dbg(ql_dbg_disc, vha, 0x2073,
1120 "RFT_ID exiting normally.\n");
1127 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
1131 * This command uses the old Exectute SNS Command mailbox routine.
1133 * Returns 0 on success.
1136 qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
1139 struct qla_hw_data *ha = vha->hw;
1140 struct sns_cmd_pkt *sns_cmd;
1143 /* Prepare SNS command request. */
1144 sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN,
1145 RNN_ID_SNS_DATA_SIZE);
1147 /* Prepare SNS command arguments -- port_id, nodename. */
1148 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1149 sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1150 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
1152 sns_cmd->p.cmd.param[4] = vha->node_name[7];
1153 sns_cmd->p.cmd.param[5] = vha->node_name[6];
1154 sns_cmd->p.cmd.param[6] = vha->node_name[5];
1155 sns_cmd->p.cmd.param[7] = vha->node_name[4];
1156 sns_cmd->p.cmd.param[8] = vha->node_name[3];
1157 sns_cmd->p.cmd.param[9] = vha->node_name[2];
1158 sns_cmd->p.cmd.param[10] = vha->node_name[1];
1159 sns_cmd->p.cmd.param[11] = vha->node_name[0];
1161 /* Execute SNS command. */
1162 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2,
1163 sizeof(struct sns_cmd_pkt));
1164 if (rval != QLA_SUCCESS) {
1166 ql_dbg(ql_dbg_disc, vha, 0x204a,
1167 "RNN_ID Send SNS failed (%d).\n", rval);
1168 } else if (sns_cmd->p.rnn_data[8] != 0x80 ||
1169 sns_cmd->p.rnn_data[9] != 0x02) {
1170 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b,
1171 "RNN_ID failed, rejected request, rnn_rsp:\n");
1172 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c,
1173 sns_cmd->p.rnn_data, 16);
1174 rval = QLA_FUNCTION_FAILED;
1176 ql_dbg(ql_dbg_disc, vha, 0x204c,
1177 "RNN_ID exiting normally.\n");
1184 * qla2x00_mgmt_svr_login() - Login to fabric Management Service.
1187 * Returns 0 on success.
1190 qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
1193 uint16_t mb[MAILBOX_REGISTER_COUNT];
1194 struct qla_hw_data *ha = vha->hw;
1196 if (vha->flags.management_server_logged_in)
1199 rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff,
1201 if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
1202 if (rval == QLA_MEMORY_ALLOC_FAILED)
1203 ql_dbg(ql_dbg_disc, vha, 0x2085,
1204 "Failed management_server login: loopid=%x "
1205 "rval=%d\n", vha->mgmt_svr_loop_id, rval);
1207 ql_dbg(ql_dbg_disc, vha, 0x2024,
1208 "Failed management_server login: loopid=%x "
1209 "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
1210 vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6],
1212 ret = QLA_FUNCTION_FAILED;
1214 vha->flags.management_server_logged_in = 1;
1220 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1222 * @req_size: request size in bytes
1223 * @rsp_size: response size in bytes
1225 * Returns a pointer to the @ha's ms_iocb.
1228 qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1231 ms_iocb_entry_t *ms_pkt;
1232 struct qla_hw_data *ha = vha->hw;
1233 ms_pkt = ha->ms_iocb;
1234 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
1236 ms_pkt->entry_type = MS_IOCB_TYPE;
1237 ms_pkt->entry_count = 1;
1238 SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id);
1239 ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
1240 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1241 ms_pkt->cmd_dsd_count = cpu_to_le16(1);
1242 ms_pkt->total_dsd_count = cpu_to_le16(2);
1243 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
1244 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1246 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1247 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1248 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1250 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1251 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1252 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
1258 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1260 * @req_size: request size in bytes
1261 * @rsp_size: response size in bytes
1263 * Returns a pointer to the @ha's ms_iocb.
1266 qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1269 struct ct_entry_24xx *ct_pkt;
1270 struct qla_hw_data *ha = vha->hw;
1272 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1273 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1275 ct_pkt->entry_type = CT_IOCB_TYPE;
1276 ct_pkt->entry_count = 1;
1277 ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
1278 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1279 ct_pkt->cmd_dsd_count = cpu_to_le16(1);
1280 ct_pkt->rsp_dsd_count = cpu_to_le16(1);
1281 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1282 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1284 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1285 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1286 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1288 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1289 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1290 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
1291 ct_pkt->vp_index = vha->vp_idx;
1296 static inline ms_iocb_entry_t *
1297 qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
1299 struct qla_hw_data *ha = vha->hw;
1300 ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
1301 struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1303 if (IS_FWI2_CAPABLE(ha)) {
1304 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1305 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1307 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1308 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1315 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
1316 * @ct_req: CT request buffer
1318 * @rsp_size: response size in bytes
1320 * Returns a pointer to the intitialized @ct_req.
1322 static inline struct ct_sns_req *
1323 qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
1326 memset(p, 0, sizeof(struct ct_sns_pkt));
1328 p->p.req.header.revision = 0x01;
1329 p->p.req.header.gs_type = 0xFA;
1330 p->p.req.header.gs_subtype = 0x10;
1331 p->p.req.command = cpu_to_be16(cmd);
1332 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
1338 * qla2x00_fdmi_rhba() -
1341 * Returns 0 on success.
1344 qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
1349 ms_iocb_entry_t *ms_pkt;
1350 struct ct_sns_req *ct_req;
1351 struct ct_sns_rsp *ct_rsp;
1353 struct ct_fdmi_hba_attr *eiter;
1354 struct qla_hw_data *ha = vha->hw;
1357 /* Prepare common MS IOCB */
1358 /* Request size adjusted after CT preparation */
1359 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
1361 /* Prepare CT request */
1362 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, RHBA_RSP_SIZE);
1363 ct_rsp = &ha->ct_sns->p.rsp;
1365 /* Prepare FDMI command arguments -- attribute block, attributes. */
1366 memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE);
1367 ct_req->req.rhba.entry_count = cpu_to_be32(1);
1368 memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE);
1369 size = 2 * WWN_SIZE + 4 + 4;
1372 ct_req->req.rhba.attrs.count =
1373 cpu_to_be32(FDMI_HBA_ATTR_COUNT);
1374 entries = ct_req->req.rhba.hba_identifier;
1377 eiter = entries + size;
1378 eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME);
1379 eiter->len = cpu_to_be16(4 + WWN_SIZE);
1380 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
1381 size += 4 + WWN_SIZE;
1383 ql_dbg(ql_dbg_disc, vha, 0x2025,
1384 "NodeName = %8phN.\n", eiter->a.node_name);
1387 eiter = entries + size;
1388 eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER);
1389 alen = strlen(QLA2XXX_MANUFACTURER);
1390 snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer),
1391 "%s", "QLogic Corporation");
1392 alen += 4 - (alen & 3);
1393 eiter->len = cpu_to_be16(4 + alen);
1396 ql_dbg(ql_dbg_disc, vha, 0x2026,
1397 "Manufacturer = %s.\n", eiter->a.manufacturer);
1399 /* Serial number. */
1400 eiter = entries + size;
1401 eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
1402 if (IS_FWI2_CAPABLE(ha))
1403 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num,
1404 sizeof(eiter->a.serial_num));
1406 sn = ((ha->serial0 & 0x1f) << 16) |
1407 (ha->serial2 << 8) | ha->serial1;
1408 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num),
1409 "%c%05d", 'A' + sn / 100000, sn % 100000);
1411 alen = strlen(eiter->a.serial_num);
1412 alen += 4 - (alen & 3);
1413 eiter->len = cpu_to_be16(4 + alen);
1416 ql_dbg(ql_dbg_disc, vha, 0x2027,
1417 "Serial no. = %s.\n", eiter->a.serial_num);
1420 eiter = entries + size;
1421 eiter->type = cpu_to_be16(FDMI_HBA_MODEL);
1422 snprintf(eiter->a.model, sizeof(eiter->a.model),
1423 "%s", ha->model_number);
1424 alen = strlen(eiter->a.model);
1425 alen += 4 - (alen & 3);
1426 eiter->len = cpu_to_be16(4 + alen);
1429 ql_dbg(ql_dbg_disc, vha, 0x2028,
1430 "Model Name = %s.\n", eiter->a.model);
1432 /* Model description. */
1433 eiter = entries + size;
1434 eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
1435 snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc),
1436 "%s", ha->model_desc);
1437 alen = strlen(eiter->a.model_desc);
1438 alen += 4 - (alen & 3);
1439 eiter->len = cpu_to_be16(4 + alen);
1442 ql_dbg(ql_dbg_disc, vha, 0x2029,
1443 "Model Desc = %s.\n", eiter->a.model_desc);
1445 /* Hardware version. */
1446 eiter = entries + size;
1447 eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
1448 if (!IS_FWI2_CAPABLE(ha)) {
1449 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1450 "HW:%s", ha->adapter_id);
1451 } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version,
1452 sizeof(eiter->a.hw_version))) {
1454 } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version,
1455 sizeof(eiter->a.hw_version))) {
1458 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1459 "HW:%s", ha->adapter_id);
1461 alen = strlen(eiter->a.hw_version);
1462 alen += 4 - (alen & 3);
1463 eiter->len = cpu_to_be16(4 + alen);
1466 ql_dbg(ql_dbg_disc, vha, 0x202a,
1467 "Hardware ver = %s.\n", eiter->a.hw_version);
1469 /* Driver version. */
1470 eiter = entries + size;
1471 eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
1472 snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version),
1473 "%s", qla2x00_version_str);
1474 alen = strlen(eiter->a.driver_version);
1475 alen += 4 - (alen & 3);
1476 eiter->len = cpu_to_be16(4 + alen);
1479 ql_dbg(ql_dbg_disc, vha, 0x202b,
1480 "Driver ver = %s.\n", eiter->a.driver_version);
1482 /* Option ROM version. */
1483 eiter = entries + size;
1484 eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
1485 snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version),
1486 "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
1487 alen = strlen(eiter->a.orom_version);
1488 alen += 4 - (alen & 3);
1489 eiter->len = cpu_to_be16(4 + alen);
1492 ql_dbg(ql_dbg_disc, vha , 0x202c,
1493 "Optrom vers = %s.\n", eiter->a.orom_version);
1495 /* Firmware version */
1496 eiter = entries + size;
1497 eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
1498 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version,
1499 sizeof(eiter->a.fw_version));
1500 alen = strlen(eiter->a.fw_version);
1501 alen += 4 - (alen & 3);
1502 eiter->len = cpu_to_be16(4 + alen);
1505 ql_dbg(ql_dbg_disc, vha, 0x202d,
1506 "Firmware vers = %s.\n", eiter->a.fw_version);
1508 /* Update MS request size. */
1509 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1511 ql_dbg(ql_dbg_disc, vha, 0x202e,
1512 "RHBA identifier = %8phN size=%d.\n",
1513 ct_req->req.rhba.hba_identifier, size);
1514 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076,
1517 /* Execute MS IOCB */
1518 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1519 sizeof(ms_iocb_entry_t));
1520 if (rval != QLA_SUCCESS) {
1522 ql_dbg(ql_dbg_disc, vha, 0x2030,
1523 "RHBA issue IOCB failed (%d).\n", rval);
1524 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") !=
1526 rval = QLA_FUNCTION_FAILED;
1527 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1528 ct_rsp->header.explanation_code ==
1529 CT_EXPL_ALREADY_REGISTERED) {
1530 ql_dbg(ql_dbg_disc, vha, 0x2034,
1531 "HBA already registered.\n");
1532 rval = QLA_ALREADY_REGISTERED;
1534 ql_dbg(ql_dbg_disc, vha, 0x20ad,
1535 "RHBA FDMI registration failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
1536 ct_rsp->header.reason_code,
1537 ct_rsp->header.explanation_code);
1540 ql_dbg(ql_dbg_disc, vha, 0x2035,
1541 "RHBA exiting normally.\n");
1548 * qla2x00_fdmi_rpa() -
1551 * Returns 0 on success.
1554 qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
1558 struct qla_hw_data *ha = vha->hw;
1559 ms_iocb_entry_t *ms_pkt;
1560 struct ct_sns_req *ct_req;
1561 struct ct_sns_rsp *ct_rsp;
1563 struct ct_fdmi_port_attr *eiter;
1564 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
1565 struct new_utsname *p_sysid = NULL;
1568 /* Prepare common MS IOCB */
1569 /* Request size adjusted after CT preparation */
1570 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
1572 /* Prepare CT request */
1573 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD,
1575 ct_rsp = &ha->ct_sns->p.rsp;
1577 /* Prepare FDMI command arguments -- attribute block, attributes. */
1578 memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE);
1579 size = WWN_SIZE + 4;
1582 ct_req->req.rpa.attrs.count = cpu_to_be32(FDMI_PORT_ATTR_COUNT);
1583 entries = ct_req->req.rpa.port_name;
1586 eiter = entries + size;
1587 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES);
1588 eiter->len = cpu_to_be16(4 + 32);
1589 eiter->a.fc4_types[2] = 0x01;
1592 ql_dbg(ql_dbg_disc, vha, 0x2039,
1593 "FC4_TYPES=%02x %02x.\n",
1594 eiter->a.fc4_types[2],
1595 eiter->a.fc4_types[1]);
1597 /* Supported speed. */
1598 eiter = entries + size;
1599 eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
1600 eiter->len = cpu_to_be16(4 + 4);
1601 if (IS_CNA_CAPABLE(ha))
1602 eiter->a.sup_speed = cpu_to_be32(
1603 FDMI_PORT_SPEED_10GB);
1604 else if (IS_QLA27XX(ha))
1605 eiter->a.sup_speed = cpu_to_be32(
1606 FDMI_PORT_SPEED_32GB|
1607 FDMI_PORT_SPEED_16GB|
1608 FDMI_PORT_SPEED_8GB);
1609 else if (IS_QLA2031(ha))
1610 eiter->a.sup_speed = cpu_to_be32(
1611 FDMI_PORT_SPEED_16GB|
1612 FDMI_PORT_SPEED_8GB|
1613 FDMI_PORT_SPEED_4GB);
1614 else if (IS_QLA25XX(ha))
1615 eiter->a.sup_speed = cpu_to_be32(
1616 FDMI_PORT_SPEED_8GB|
1617 FDMI_PORT_SPEED_4GB|
1618 FDMI_PORT_SPEED_2GB|
1619 FDMI_PORT_SPEED_1GB);
1620 else if (IS_QLA24XX_TYPE(ha))
1621 eiter->a.sup_speed = cpu_to_be32(
1622 FDMI_PORT_SPEED_4GB|
1623 FDMI_PORT_SPEED_2GB|
1624 FDMI_PORT_SPEED_1GB);
1625 else if (IS_QLA23XX(ha))
1626 eiter->a.sup_speed = cpu_to_be32(
1627 FDMI_PORT_SPEED_2GB|
1628 FDMI_PORT_SPEED_1GB);
1630 eiter->a.sup_speed = cpu_to_be32(
1631 FDMI_PORT_SPEED_1GB);
1634 ql_dbg(ql_dbg_disc, vha, 0x203a,
1635 "Supported_Speed=%x.\n", eiter->a.sup_speed);
1637 /* Current speed. */
1638 eiter = entries + size;
1639 eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
1640 eiter->len = cpu_to_be16(4 + 4);
1641 switch (ha->link_data_rate) {
1642 case PORT_SPEED_1GB:
1643 eiter->a.cur_speed =
1644 cpu_to_be32(FDMI_PORT_SPEED_1GB);
1646 case PORT_SPEED_2GB:
1647 eiter->a.cur_speed =
1648 cpu_to_be32(FDMI_PORT_SPEED_2GB);
1650 case PORT_SPEED_4GB:
1651 eiter->a.cur_speed =
1652 cpu_to_be32(FDMI_PORT_SPEED_4GB);
1654 case PORT_SPEED_8GB:
1655 eiter->a.cur_speed =
1656 cpu_to_be32(FDMI_PORT_SPEED_8GB);
1658 case PORT_SPEED_10GB:
1659 eiter->a.cur_speed =
1660 cpu_to_be32(FDMI_PORT_SPEED_10GB);
1662 case PORT_SPEED_16GB:
1663 eiter->a.cur_speed =
1664 cpu_to_be32(FDMI_PORT_SPEED_16GB);
1666 case PORT_SPEED_32GB:
1667 eiter->a.cur_speed =
1668 cpu_to_be32(FDMI_PORT_SPEED_32GB);
1671 eiter->a.cur_speed =
1672 cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
1677 ql_dbg(ql_dbg_disc, vha, 0x203b,
1678 "Current_Speed=%x.\n", eiter->a.cur_speed);
1680 /* Max frame size. */
1681 eiter = entries + size;
1682 eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
1683 eiter->len = cpu_to_be16(4 + 4);
1684 eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ?
1685 le16_to_cpu(icb24->frame_payload_size) :
1686 le16_to_cpu(ha->init_cb->frame_payload_size);
1687 eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size);
1690 ql_dbg(ql_dbg_disc, vha, 0x203c,
1691 "Max_Frame_Size=%x.\n", eiter->a.max_frame_size);
1693 /* OS device name. */
1694 eiter = entries + size;
1695 eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
1696 snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name),
1697 "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
1698 alen = strlen(eiter->a.os_dev_name);
1699 alen += 4 - (alen & 3);
1700 eiter->len = cpu_to_be16(4 + alen);
1703 ql_dbg(ql_dbg_disc, vha, 0x204b,
1704 "OS_Device_Name=%s.\n", eiter->a.os_dev_name);
1707 eiter = entries + size;
1708 eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME);
1709 p_sysid = utsname();
1711 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
1712 "%s", p_sysid->nodename);
1714 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
1715 "%s", fc_host_system_hostname(vha->host));
1717 alen = strlen(eiter->a.host_name);
1718 alen += 4 - (alen & 3);
1719 eiter->len = cpu_to_be16(4 + alen);
1722 ql_dbg(ql_dbg_disc, vha, 0x203d, "HostName=%s.\n", eiter->a.host_name);
1724 /* Update MS request size. */
1725 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1727 ql_dbg(ql_dbg_disc, vha, 0x203e,
1728 "RPA portname %016llx, size = %d.\n",
1729 wwn_to_u64(ct_req->req.rpa.port_name), size);
1730 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079,
1733 /* Execute MS IOCB */
1734 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1735 sizeof(ms_iocb_entry_t));
1736 if (rval != QLA_SUCCESS) {
1738 ql_dbg(ql_dbg_disc, vha, 0x2040,
1739 "RPA issue IOCB failed (%d).\n", rval);
1740 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") !=
1742 rval = QLA_FUNCTION_FAILED;
1743 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1744 ct_rsp->header.explanation_code ==
1745 CT_EXPL_ALREADY_REGISTERED) {
1746 ql_dbg(ql_dbg_disc, vha, 0x20cd,
1747 "RPA already registered.\n");
1748 rval = QLA_ALREADY_REGISTERED;
1752 ql_dbg(ql_dbg_disc, vha, 0x2041,
1753 "RPA exiting normally.\n");
1760 * qla2x00_fdmiv2_rhba() -
1763 * Returns 0 on success.
1766 qla2x00_fdmiv2_rhba(scsi_qla_host_t *vha)
1770 ms_iocb_entry_t *ms_pkt;
1771 struct ct_sns_req *ct_req;
1772 struct ct_sns_rsp *ct_rsp;
1774 struct ct_fdmiv2_hba_attr *eiter;
1775 struct qla_hw_data *ha = vha->hw;
1776 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
1777 struct new_utsname *p_sysid = NULL;
1780 /* Prepare common MS IOCB */
1781 /* Request size adjusted after CT preparation */
1782 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
1784 /* Prepare CT request */
1785 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD,
1787 ct_rsp = &ha->ct_sns->p.rsp;
1789 /* Prepare FDMI command arguments -- attribute block, attributes. */
1790 memcpy(ct_req->req.rhba2.hba_identifier, vha->port_name, WWN_SIZE);
1791 ct_req->req.rhba2.entry_count = cpu_to_be32(1);
1792 memcpy(ct_req->req.rhba2.port_name, vha->port_name, WWN_SIZE);
1793 size = 2 * WWN_SIZE + 4 + 4;
1796 ct_req->req.rhba2.attrs.count = cpu_to_be32(FDMIV2_HBA_ATTR_COUNT);
1797 entries = ct_req->req.rhba2.hba_identifier;
1800 eiter = entries + size;
1801 eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME);
1802 eiter->len = cpu_to_be16(4 + WWN_SIZE);
1803 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
1804 size += 4 + WWN_SIZE;
1806 ql_dbg(ql_dbg_disc, vha, 0x207d,
1807 "NodeName = %016llx.\n", wwn_to_u64(eiter->a.node_name));
1810 eiter = entries + size;
1811 eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER);
1812 snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer),
1813 "%s", "QLogic Corporation");
1814 eiter->a.manufacturer[strlen("QLogic Corporation")] = '\0';
1815 alen = strlen(eiter->a.manufacturer);
1816 alen += 4 - (alen & 3);
1817 eiter->len = cpu_to_be16(4 + alen);
1820 ql_dbg(ql_dbg_disc, vha, 0x20a5,
1821 "Manufacturer = %s.\n", eiter->a.manufacturer);
1823 /* Serial number. */
1824 eiter = entries + size;
1825 eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
1826 if (IS_FWI2_CAPABLE(ha))
1827 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num,
1828 sizeof(eiter->a.serial_num));
1830 sn = ((ha->serial0 & 0x1f) << 16) |
1831 (ha->serial2 << 8) | ha->serial1;
1832 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num),
1833 "%c%05d", 'A' + sn / 100000, sn % 100000);
1835 alen = strlen(eiter->a.serial_num);
1836 alen += 4 - (alen & 3);
1837 eiter->len = cpu_to_be16(4 + alen);
1840 ql_dbg(ql_dbg_disc, vha, 0x20a6,
1841 "Serial no. = %s.\n", eiter->a.serial_num);
1844 eiter = entries + size;
1845 eiter->type = cpu_to_be16(FDMI_HBA_MODEL);
1846 snprintf(eiter->a.model, sizeof(eiter->a.model),
1847 "%s", ha->model_number);
1848 alen = strlen(eiter->a.model);
1849 alen += 4 - (alen & 3);
1850 eiter->len = cpu_to_be16(4 + alen);
1853 ql_dbg(ql_dbg_disc, vha, 0x20a7,
1854 "Model Name = %s.\n", eiter->a.model);
1856 /* Model description. */
1857 eiter = entries + size;
1858 eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
1859 snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc),
1860 "%s", ha->model_desc);
1861 alen = strlen(eiter->a.model_desc);
1862 alen += 4 - (alen & 3);
1863 eiter->len = cpu_to_be16(4 + alen);
1866 ql_dbg(ql_dbg_disc, vha, 0x20a8,
1867 "Model Desc = %s.\n", eiter->a.model_desc);
1869 /* Hardware version. */
1870 eiter = entries + size;
1871 eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
1872 if (!IS_FWI2_CAPABLE(ha)) {
1873 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1874 "HW:%s", ha->adapter_id);
1875 } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version,
1876 sizeof(eiter->a.hw_version))) {
1878 } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version,
1879 sizeof(eiter->a.hw_version))) {
1882 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1883 "HW:%s", ha->adapter_id);
1885 alen = strlen(eiter->a.hw_version);
1886 alen += 4 - (alen & 3);
1887 eiter->len = cpu_to_be16(4 + alen);
1890 ql_dbg(ql_dbg_disc, vha, 0x20a9,
1891 "Hardware ver = %s.\n", eiter->a.hw_version);
1893 /* Driver version. */
1894 eiter = entries + size;
1895 eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
1896 snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version),
1897 "%s", qla2x00_version_str);
1898 alen = strlen(eiter->a.driver_version);
1899 alen += 4 - (alen & 3);
1900 eiter->len = cpu_to_be16(4 + alen);
1903 ql_dbg(ql_dbg_disc, vha, 0x20aa,
1904 "Driver ver = %s.\n", eiter->a.driver_version);
1906 /* Option ROM version. */
1907 eiter = entries + size;
1908 eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
1909 snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version),
1910 "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
1911 alen = strlen(eiter->a.orom_version);
1912 alen += 4 - (alen & 3);
1913 eiter->len = cpu_to_be16(4 + alen);
1916 ql_dbg(ql_dbg_disc, vha , 0x20ab,
1917 "Optrom version = %d.%02d.\n", eiter->a.orom_version[1],
1918 eiter->a.orom_version[0]);
1920 /* Firmware version */
1921 eiter = entries + size;
1922 eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
1923 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version,
1924 sizeof(eiter->a.fw_version));
1925 alen = strlen(eiter->a.fw_version);
1926 alen += 4 - (alen & 3);
1927 eiter->len = cpu_to_be16(4 + alen);
1930 ql_dbg(ql_dbg_disc, vha, 0x20ac,
1931 "Firmware vers = %s.\n", eiter->a.fw_version);
1933 /* OS Name and Version */
1934 eiter = entries + size;
1935 eiter->type = cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION);
1936 p_sysid = utsname();
1938 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version),
1940 p_sysid->sysname, p_sysid->release, p_sysid->version);
1942 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version),
1943 "%s %s", "Linux", fc_host_system_hostname(vha->host));
1945 alen = strlen(eiter->a.os_version);
1946 alen += 4 - (alen & 3);
1947 eiter->len = cpu_to_be16(4 + alen);
1950 ql_dbg(ql_dbg_disc, vha, 0x20ae,
1951 "OS Name and Version = %s.\n", eiter->a.os_version);
1953 /* MAX CT Payload Length */
1954 eiter = entries + size;
1955 eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH);
1956 eiter->a.max_ct_len = IS_FWI2_CAPABLE(ha) ?
1957 le16_to_cpu(icb24->frame_payload_size) :
1958 le16_to_cpu(ha->init_cb->frame_payload_size);
1959 eiter->a.max_ct_len = cpu_to_be32(eiter->a.max_ct_len);
1960 eiter->len = cpu_to_be16(4 + 4);
1963 ql_dbg(ql_dbg_disc, vha, 0x20af,
1964 "CT Payload Length = 0x%x.\n", eiter->a.max_ct_len);
1966 /* Node Sybolic Name */
1967 eiter = entries + size;
1968 eiter->type = cpu_to_be16(FDMI_HBA_NODE_SYMBOLIC_NAME);
1969 qla2x00_get_sym_node_name(vha, eiter->a.sym_name,
1970 sizeof(eiter->a.sym_name));
1971 alen = strlen(eiter->a.sym_name);
1972 alen += 4 - (alen & 3);
1973 eiter->len = cpu_to_be16(4 + alen);
1976 ql_dbg(ql_dbg_disc, vha, 0x20b0,
1977 "Symbolic Name = %s.\n", eiter->a.sym_name);
1980 eiter = entries + size;
1981 eiter->type = cpu_to_be16(FDMI_HBA_VENDOR_ID);
1982 eiter->a.vendor_id = cpu_to_be32(0x1077);
1983 eiter->len = cpu_to_be16(4 + 4);
1986 ql_dbg(ql_dbg_disc, vha, 0x20b1,
1987 "Vendor Id = %x.\n", eiter->a.vendor_id);
1990 eiter = entries + size;
1991 eiter->type = cpu_to_be16(FDMI_HBA_NUM_PORTS);
1992 eiter->a.num_ports = cpu_to_be32(1);
1993 eiter->len = cpu_to_be16(4 + 4);
1996 ql_dbg(ql_dbg_disc, vha, 0x20b2,
1997 "Port Num = %x.\n", eiter->a.num_ports);
2000 eiter = entries + size;
2001 eiter->type = cpu_to_be16(FDMI_HBA_FABRIC_NAME);
2002 memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE);
2003 eiter->len = cpu_to_be16(4 + WWN_SIZE);
2004 size += 4 + WWN_SIZE;
2006 ql_dbg(ql_dbg_disc, vha, 0x20b3,
2007 "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
2010 eiter = entries + size;
2011 eiter->type = cpu_to_be16(FDMI_HBA_BOOT_BIOS_NAME);
2012 snprintf(eiter->a.bios_name, sizeof(eiter->a.bios_name),
2013 "BIOS %d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
2014 alen = strlen(eiter->a.bios_name);
2015 alen += 4 - (alen & 3);
2016 eiter->len = cpu_to_be16(4 + alen);
2019 ql_dbg(ql_dbg_disc, vha, 0x20b4,
2020 "BIOS Name = %s\n", eiter->a.bios_name);
2022 /* Vendor Identifier */
2023 eiter = entries + size;
2024 eiter->type = cpu_to_be16(FDMI_HBA_TYPE_VENDOR_IDENTIFIER);
2025 snprintf(eiter->a.vendor_identifier, sizeof(eiter->a.vendor_identifier),
2027 alen = strlen(eiter->a.vendor_identifier);
2028 alen += 4 - (alen & 3);
2029 eiter->len = cpu_to_be16(4 + alen);
2032 ql_dbg(ql_dbg_disc, vha, 0x201b,
2033 "Vendor Identifier = %s.\n", eiter->a.vendor_identifier);
2035 /* Update MS request size. */
2036 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
2038 ql_dbg(ql_dbg_disc, vha, 0x20b5,
2039 "RHBA identifier = %016llx.\n",
2040 wwn_to_u64(ct_req->req.rhba2.hba_identifier));
2041 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20b6,
2044 /* Execute MS IOCB */
2045 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2046 sizeof(ms_iocb_entry_t));
2047 if (rval != QLA_SUCCESS) {
2049 ql_dbg(ql_dbg_disc, vha, 0x20b7,
2050 "RHBA issue IOCB failed (%d).\n", rval);
2051 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") !=
2053 rval = QLA_FUNCTION_FAILED;
2055 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
2056 ct_rsp->header.explanation_code ==
2057 CT_EXPL_ALREADY_REGISTERED) {
2058 ql_dbg(ql_dbg_disc, vha, 0x20b8,
2059 "HBA already registered.\n");
2060 rval = QLA_ALREADY_REGISTERED;
2062 ql_dbg(ql_dbg_disc, vha, 0x2016,
2063 "RHBA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
2064 ct_rsp->header.reason_code,
2065 ct_rsp->header.explanation_code);
2068 ql_dbg(ql_dbg_disc, vha, 0x20b9,
2069 "RHBA FDMI V2 exiting normally.\n");
2076 * qla2x00_fdmi_dhba() -
2079 * Returns 0 on success.
2082 qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
2085 struct qla_hw_data *ha = vha->hw;
2086 ms_iocb_entry_t *ms_pkt;
2087 struct ct_sns_req *ct_req;
2088 struct ct_sns_rsp *ct_rsp;
2091 /* Prepare common MS IOCB */
2092 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE,
2095 /* Prepare CT request */
2096 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE);
2097 ct_rsp = &ha->ct_sns->p.rsp;
2099 /* Prepare FDMI command arguments -- portname. */
2100 memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE);
2102 ql_dbg(ql_dbg_disc, vha, 0x2036,
2103 "DHBA portname = %8phN.\n", ct_req->req.dhba.port_name);
2105 /* Execute MS IOCB */
2106 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2107 sizeof(ms_iocb_entry_t));
2108 if (rval != QLA_SUCCESS) {
2110 ql_dbg(ql_dbg_disc, vha, 0x2037,
2111 "DHBA issue IOCB failed (%d).\n", rval);
2112 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") !=
2114 rval = QLA_FUNCTION_FAILED;
2116 ql_dbg(ql_dbg_disc, vha, 0x2038,
2117 "DHBA exiting normally.\n");
2124 * qla2x00_fdmiv2_rpa() -
2127 * Returns 0 on success.
2130 qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha)
2134 struct qla_hw_data *ha = vha->hw;
2135 ms_iocb_entry_t *ms_pkt;
2136 struct ct_sns_req *ct_req;
2137 struct ct_sns_rsp *ct_rsp;
2139 struct ct_fdmiv2_port_attr *eiter;
2140 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
2141 struct new_utsname *p_sysid = NULL;
2144 /* Prepare common MS IOCB */
2145 /* Request size adjusted after CT preparation */
2146 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
2148 /* Prepare CT request */
2149 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, RPA_RSP_SIZE);
2150 ct_rsp = &ha->ct_sns->p.rsp;
2152 /* Prepare FDMI command arguments -- attribute block, attributes. */
2153 memcpy(ct_req->req.rpa2.port_name, vha->port_name, WWN_SIZE);
2154 size = WWN_SIZE + 4;
2157 ct_req->req.rpa2.attrs.count = cpu_to_be32(FDMIV2_PORT_ATTR_COUNT);
2158 entries = ct_req->req.rpa2.port_name;
2161 eiter = entries + size;
2162 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES);
2163 eiter->len = cpu_to_be16(4 + 32);
2164 eiter->a.fc4_types[2] = 0x01;
2167 ql_dbg(ql_dbg_disc, vha, 0x20ba,
2168 "FC4_TYPES=%02x %02x.\n",
2169 eiter->a.fc4_types[2],
2170 eiter->a.fc4_types[1]);
2172 if (vha->flags.nvme_enabled) {
2173 eiter->a.fc4_types[6] = 1; /* NVMe type 28h */
2174 ql_dbg(ql_dbg_disc, vha, 0x211f,
2175 "NVME FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n",
2176 eiter->a.fc4_types[6]);
2179 /* Supported speed. */
2180 eiter = entries + size;
2181 eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
2182 eiter->len = cpu_to_be16(4 + 4);
2183 if (IS_CNA_CAPABLE(ha))
2184 eiter->a.sup_speed = cpu_to_be32(
2185 FDMI_PORT_SPEED_10GB);
2186 else if (IS_QLA27XX(ha))
2187 eiter->a.sup_speed = cpu_to_be32(
2188 FDMI_PORT_SPEED_32GB|
2189 FDMI_PORT_SPEED_16GB|
2190 FDMI_PORT_SPEED_8GB);
2191 else if (IS_QLA2031(ha))
2192 eiter->a.sup_speed = cpu_to_be32(
2193 FDMI_PORT_SPEED_16GB|
2194 FDMI_PORT_SPEED_8GB|
2195 FDMI_PORT_SPEED_4GB);
2196 else if (IS_QLA25XX(ha))
2197 eiter->a.sup_speed = cpu_to_be32(
2198 FDMI_PORT_SPEED_8GB|
2199 FDMI_PORT_SPEED_4GB|
2200 FDMI_PORT_SPEED_2GB|
2201 FDMI_PORT_SPEED_1GB);
2202 else if (IS_QLA24XX_TYPE(ha))
2203 eiter->a.sup_speed = cpu_to_be32(
2204 FDMI_PORT_SPEED_4GB|
2205 FDMI_PORT_SPEED_2GB|
2206 FDMI_PORT_SPEED_1GB);
2207 else if (IS_QLA23XX(ha))
2208 eiter->a.sup_speed = cpu_to_be32(
2209 FDMI_PORT_SPEED_2GB|
2210 FDMI_PORT_SPEED_1GB);
2212 eiter->a.sup_speed = cpu_to_be32(
2213 FDMI_PORT_SPEED_1GB);
2216 ql_dbg(ql_dbg_disc, vha, 0x20bb,
2217 "Supported Port Speed = %x.\n", eiter->a.sup_speed);
2219 /* Current speed. */
2220 eiter = entries + size;
2221 eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
2222 eiter->len = cpu_to_be16(4 + 4);
2223 switch (ha->link_data_rate) {
2224 case PORT_SPEED_1GB:
2225 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_1GB);
2227 case PORT_SPEED_2GB:
2228 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_2GB);
2230 case PORT_SPEED_4GB:
2231 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_4GB);
2233 case PORT_SPEED_8GB:
2234 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_8GB);
2236 case PORT_SPEED_10GB:
2237 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_10GB);
2239 case PORT_SPEED_16GB:
2240 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_16GB);
2242 case PORT_SPEED_32GB:
2243 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_32GB);
2246 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
2251 ql_dbg(ql_dbg_disc, vha, 0x2017,
2252 "Current_Speed = %x.\n", eiter->a.cur_speed);
2254 /* Max frame size. */
2255 eiter = entries + size;
2256 eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
2257 eiter->len = cpu_to_be16(4 + 4);
2258 eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ?
2259 le16_to_cpu(icb24->frame_payload_size):
2260 le16_to_cpu(ha->init_cb->frame_payload_size);
2261 eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size);
2264 ql_dbg(ql_dbg_disc, vha, 0x20bc,
2265 "Max_Frame_Size = %x.\n", eiter->a.max_frame_size);
2267 /* OS device name. */
2268 eiter = entries + size;
2269 eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
2270 alen = strlen(QLA2XXX_DRIVER_NAME);
2271 snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name),
2272 "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
2273 alen += 4 - (alen & 3);
2274 eiter->len = cpu_to_be16(4 + alen);
2277 ql_dbg(ql_dbg_disc, vha, 0x20be,
2278 "OS_Device_Name = %s.\n", eiter->a.os_dev_name);
2281 eiter = entries + size;
2282 eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME);
2283 p_sysid = utsname();
2285 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
2286 "%s", p_sysid->nodename);
2288 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
2289 "%s", fc_host_system_hostname(vha->host));
2291 alen = strlen(eiter->a.host_name);
2292 alen += 4 - (alen & 3);
2293 eiter->len = cpu_to_be16(4 + alen);
2296 ql_dbg(ql_dbg_disc, vha, 0x201a,
2297 "HostName=%s.\n", eiter->a.host_name);
2300 eiter = entries + size;
2301 eiter->type = cpu_to_be16(FDMI_PORT_NODE_NAME);
2302 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
2303 eiter->len = cpu_to_be16(4 + WWN_SIZE);
2304 size += 4 + WWN_SIZE;
2306 ql_dbg(ql_dbg_disc, vha, 0x20c0,
2307 "Node Name = %016llx.\n", wwn_to_u64(eiter->a.node_name));
2310 eiter = entries + size;
2311 eiter->type = cpu_to_be16(FDMI_PORT_NAME);
2312 memcpy(eiter->a.port_name, vha->port_name, WWN_SIZE);
2313 eiter->len = cpu_to_be16(4 + WWN_SIZE);
2314 size += 4 + WWN_SIZE;
2316 ql_dbg(ql_dbg_disc, vha, 0x20c1,
2317 "Port Name = %016llx.\n", wwn_to_u64(eiter->a.port_name));
2319 /* Port Symbolic Name */
2320 eiter = entries + size;
2321 eiter->type = cpu_to_be16(FDMI_PORT_SYM_NAME);
2322 qla2x00_get_sym_node_name(vha, eiter->a.port_sym_name,
2323 sizeof(eiter->a.port_sym_name));
2324 alen = strlen(eiter->a.port_sym_name);
2325 alen += 4 - (alen & 3);
2326 eiter->len = cpu_to_be16(4 + alen);
2329 ql_dbg(ql_dbg_disc, vha, 0x20c2,
2330 "port symbolic name = %s\n", eiter->a.port_sym_name);
2333 eiter = entries + size;
2334 eiter->type = cpu_to_be16(FDMI_PORT_TYPE);
2335 eiter->a.port_type = cpu_to_be32(NS_NX_PORT_TYPE);
2336 eiter->len = cpu_to_be16(4 + 4);
2339 ql_dbg(ql_dbg_disc, vha, 0x20c3,
2340 "Port Type = %x.\n", eiter->a.port_type);
2342 /* Class of Service */
2343 eiter = entries + size;
2344 eiter->type = cpu_to_be16(FDMI_PORT_SUPP_COS);
2345 eiter->a.port_supported_cos = cpu_to_be32(FC_CLASS_3);
2346 eiter->len = cpu_to_be16(4 + 4);
2349 ql_dbg(ql_dbg_disc, vha, 0x20c4,
2350 "Supported COS = %08x\n", eiter->a.port_supported_cos);
2352 /* Port Fabric Name */
2353 eiter = entries + size;
2354 eiter->type = cpu_to_be16(FDMI_PORT_FABRIC_NAME);
2355 memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE);
2356 eiter->len = cpu_to_be16(4 + WWN_SIZE);
2357 size += 4 + WWN_SIZE;
2359 ql_dbg(ql_dbg_disc, vha, 0x20c5,
2360 "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
2363 eiter = entries + size;
2364 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPE);
2365 eiter->a.port_fc4_type[0] = 0;
2366 eiter->a.port_fc4_type[1] = 0;
2367 eiter->a.port_fc4_type[2] = 1;
2368 eiter->a.port_fc4_type[3] = 0;
2369 eiter->len = cpu_to_be16(4 + 32);
2372 ql_dbg(ql_dbg_disc, vha, 0x20c6,
2373 "Port Active FC4 Type = %02x %02x.\n",
2374 eiter->a.port_fc4_type[2], eiter->a.port_fc4_type[1]);
2376 if (vha->flags.nvme_enabled) {
2377 eiter->a.port_fc4_type[4] = 0;
2378 eiter->a.port_fc4_type[5] = 0;
2379 eiter->a.port_fc4_type[6] = 1; /* NVMe type 28h */
2380 ql_dbg(ql_dbg_disc, vha, 0x2120,
2381 "NVME Port Active FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n",
2382 eiter->a.port_fc4_type[6]);
2386 eiter = entries + size;
2387 eiter->type = cpu_to_be16(FDMI_PORT_STATE);
2388 eiter->a.port_state = cpu_to_be32(1);
2389 eiter->len = cpu_to_be16(4 + 4);
2392 ql_dbg(ql_dbg_disc, vha, 0x20c7,
2393 "Port State = %x.\n", eiter->a.port_state);
2395 /* Number of Ports */
2396 eiter = entries + size;
2397 eiter->type = cpu_to_be16(FDMI_PORT_COUNT);
2398 eiter->a.num_ports = cpu_to_be32(1);
2399 eiter->len = cpu_to_be16(4 + 4);
2402 ql_dbg(ql_dbg_disc, vha, 0x20c8,
2403 "Number of ports = %x.\n", eiter->a.num_ports);
2406 eiter = entries + size;
2407 eiter->type = cpu_to_be16(FDMI_PORT_ID);
2408 eiter->a.port_id = cpu_to_be32(vha->d_id.b24);
2409 eiter->len = cpu_to_be16(4 + 4);
2412 ql_dbg(ql_dbg_disc, vha, 0x201c,
2413 "Port Id = %x.\n", eiter->a.port_id);
2415 /* Update MS request size. */
2416 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
2418 ql_dbg(ql_dbg_disc, vha, 0x2018,
2419 "RPA portname= %8phN size=%d.\n", ct_req->req.rpa.port_name, size);
2420 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20ca,
2423 /* Execute MS IOCB */
2424 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2425 sizeof(ms_iocb_entry_t));
2426 if (rval != QLA_SUCCESS) {
2428 ql_dbg(ql_dbg_disc, vha, 0x20cb,
2429 "RPA FDMI v2 issue IOCB failed (%d).\n", rval);
2430 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") !=
2432 rval = QLA_FUNCTION_FAILED;
2433 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
2434 ct_rsp->header.explanation_code ==
2435 CT_EXPL_ALREADY_REGISTERED) {
2436 ql_dbg(ql_dbg_disc, vha, 0x20ce,
2437 "RPA FDMI v2 already registered\n");
2438 rval = QLA_ALREADY_REGISTERED;
2440 ql_dbg(ql_dbg_disc, vha, 0x2020,
2441 "RPA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
2442 ct_rsp->header.reason_code,
2443 ct_rsp->header.explanation_code);
2446 ql_dbg(ql_dbg_disc, vha, 0x20cc,
2447 "RPA FDMI V2 exiting normally.\n");
2454 * qla2x00_fdmi_register() -
2457 * Returns 0 on success.
2460 qla2x00_fdmi_register(scsi_qla_host_t *vha)
2462 int rval = QLA_FUNCTION_FAILED;
2463 struct qla_hw_data *ha = vha->hw;
2465 if (IS_QLA2100(ha) || IS_QLA2200(ha) ||
2467 return QLA_FUNCTION_FAILED;
2469 rval = qla2x00_mgmt_svr_login(vha);
2473 rval = qla2x00_fdmiv2_rhba(vha);
2475 if (rval != QLA_ALREADY_REGISTERED)
2478 rval = qla2x00_fdmi_dhba(vha);
2482 rval = qla2x00_fdmiv2_rhba(vha);
2486 rval = qla2x00_fdmiv2_rpa(vha);
2493 rval = qla2x00_fdmi_rhba(vha);
2495 if (rval != QLA_ALREADY_REGISTERED)
2498 rval = qla2x00_fdmi_dhba(vha);
2502 rval = qla2x00_fdmi_rhba(vha);
2506 rval = qla2x00_fdmi_rpa(vha);
2512 * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
2514 * @list: switch info entries to populate
2516 * Returns 0 on success.
2519 qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
2521 int rval = QLA_SUCCESS;
2523 struct qla_hw_data *ha = vha->hw;
2524 ms_iocb_entry_t *ms_pkt;
2525 struct ct_sns_req *ct_req;
2526 struct ct_sns_rsp *ct_rsp;
2529 if (!IS_IIDMA_CAPABLE(ha))
2530 return QLA_FUNCTION_FAILED;
2532 arg.iocb = ha->ms_iocb;
2533 arg.req_dma = ha->ct_sns_dma;
2534 arg.rsp_dma = ha->ct_sns_dma;
2535 arg.req_size = GFPN_ID_REQ_SIZE;
2536 arg.rsp_size = GFPN_ID_RSP_SIZE;
2537 arg.nport_handle = NPH_SNS;
2539 for (i = 0; i < ha->max_fibre_devices; i++) {
2541 /* Prepare common MS IOCB */
2542 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
2544 /* Prepare CT request */
2545 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD,
2547 ct_rsp = &ha->ct_sns->p.rsp;
2549 /* Prepare CT arguments -- port_id */
2550 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
2551 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
2552 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
2554 /* Execute MS IOCB */
2555 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2556 sizeof(ms_iocb_entry_t));
2557 if (rval != QLA_SUCCESS) {
2559 ql_dbg(ql_dbg_disc, vha, 0x2023,
2560 "GFPN_ID issue IOCB failed (%d).\n", rval);
2562 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
2563 "GFPN_ID") != QLA_SUCCESS) {
2564 rval = QLA_FUNCTION_FAILED;
2567 /* Save fabric portname */
2568 memcpy(list[i].fabric_port_name,
2569 ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
2572 /* Last device exit. */
2573 if (list[i].d_id.b.rsvd_1 != 0)
2581 static inline struct ct_sns_req *
2582 qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
2585 memset(p, 0, sizeof(struct ct_sns_pkt));
2587 p->p.req.header.revision = 0x01;
2588 p->p.req.header.gs_type = 0xFA;
2589 p->p.req.header.gs_subtype = 0x01;
2590 p->p.req.command = cpu_to_be16(cmd);
2591 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
2597 * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
2599 * @list: switch info entries to populate
2601 * Returns 0 on success.
2604 qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
2608 struct qla_hw_data *ha = vha->hw;
2609 ms_iocb_entry_t *ms_pkt;
2610 struct ct_sns_req *ct_req;
2611 struct ct_sns_rsp *ct_rsp;
2614 if (!IS_IIDMA_CAPABLE(ha))
2615 return QLA_FUNCTION_FAILED;
2616 if (!ha->flags.gpsc_supported)
2617 return QLA_FUNCTION_FAILED;
2619 rval = qla2x00_mgmt_svr_login(vha);
2623 arg.iocb = ha->ms_iocb;
2624 arg.req_dma = ha->ct_sns_dma;
2625 arg.rsp_dma = ha->ct_sns_dma;
2626 arg.req_size = GPSC_REQ_SIZE;
2627 arg.rsp_size = GPSC_RSP_SIZE;
2628 arg.nport_handle = vha->mgmt_svr_loop_id;
2630 for (i = 0; i < ha->max_fibre_devices; i++) {
2632 /* Prepare common MS IOCB */
2633 ms_pkt = qla24xx_prep_ms_iocb(vha, &arg);
2635 /* Prepare CT request */
2636 ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD,
2638 ct_rsp = &ha->ct_sns->p.rsp;
2640 /* Prepare CT arguments -- port_name */
2641 memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
2644 /* Execute MS IOCB */
2645 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2646 sizeof(ms_iocb_entry_t));
2647 if (rval != QLA_SUCCESS) {
2649 ql_dbg(ql_dbg_disc, vha, 0x2059,
2650 "GPSC issue IOCB failed (%d).\n", rval);
2651 } else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
2652 "GPSC")) != QLA_SUCCESS) {
2653 /* FM command unsupported? */
2654 if (rval == QLA_INVALID_COMMAND &&
2655 (ct_rsp->header.reason_code ==
2656 CT_REASON_INVALID_COMMAND_CODE ||
2657 ct_rsp->header.reason_code ==
2658 CT_REASON_COMMAND_UNSUPPORTED)) {
2659 ql_dbg(ql_dbg_disc, vha, 0x205a,
2660 "GPSC command unsupported, disabling "
2662 ha->flags.gpsc_supported = 0;
2663 rval = QLA_FUNCTION_FAILED;
2666 rval = QLA_FUNCTION_FAILED;
2668 /* Save port-speed */
2669 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
2671 list[i].fp_speed = PORT_SPEED_1GB;
2674 list[i].fp_speed = PORT_SPEED_2GB;
2677 list[i].fp_speed = PORT_SPEED_4GB;
2680 list[i].fp_speed = PORT_SPEED_10GB;
2683 list[i].fp_speed = PORT_SPEED_8GB;
2686 list[i].fp_speed = PORT_SPEED_16GB;
2689 list[i].fp_speed = PORT_SPEED_32GB;
2693 ql_dbg(ql_dbg_disc, vha, 0x205b,
2694 "GPSC ext entry - fpn "
2695 "%8phN speeds=%04x speed=%04x.\n",
2696 list[i].fabric_port_name,
2697 be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
2698 be16_to_cpu(ct_rsp->rsp.gpsc.speed));
2701 /* Last device exit. */
2702 if (list[i].d_id.b.rsvd_1 != 0)
2710 * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
2713 * @list: switch info entries to populate
2717 qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
2722 ms_iocb_entry_t *ms_pkt;
2723 struct ct_sns_req *ct_req;
2724 struct ct_sns_rsp *ct_rsp;
2725 struct qla_hw_data *ha = vha->hw;
2726 uint8_t fcp_scsi_features = 0;
2729 for (i = 0; i < ha->max_fibre_devices; i++) {
2730 /* Set default FC4 Type as UNKNOWN so the default is to
2731 * Process this port */
2732 list[i].fc4_type = FC4_TYPE_UNKNOWN;
2734 /* Do not attempt GFF_ID if we are not FWI_2 capable */
2735 if (!IS_FWI2_CAPABLE(ha))
2738 arg.iocb = ha->ms_iocb;
2739 arg.req_dma = ha->ct_sns_dma;
2740 arg.rsp_dma = ha->ct_sns_dma;
2741 arg.req_size = GFF_ID_REQ_SIZE;
2742 arg.rsp_size = GFF_ID_RSP_SIZE;
2743 arg.nport_handle = NPH_SNS;
2745 /* Prepare common MS IOCB */
2746 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
2748 /* Prepare CT request */
2749 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD,
2751 ct_rsp = &ha->ct_sns->p.rsp;
2753 /* Prepare CT arguments -- port_id */
2754 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
2755 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
2756 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
2758 /* Execute MS IOCB */
2759 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2760 sizeof(ms_iocb_entry_t));
2762 if (rval != QLA_SUCCESS) {
2763 ql_dbg(ql_dbg_disc, vha, 0x205c,
2764 "GFF_ID issue IOCB failed (%d).\n", rval);
2765 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
2766 "GFF_ID") != QLA_SUCCESS) {
2767 ql_dbg(ql_dbg_disc, vha, 0x205d,
2768 "GFF_ID IOCB status had a failure status code.\n");
2771 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
2772 fcp_scsi_features &= 0x0f;
2774 if (fcp_scsi_features)
2775 list[i].fc4_type = FC4_TYPE_FCP_SCSI;
2777 list[i].fc4_type = FC4_TYPE_OTHER;
2780 ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
2781 list[i].fc4f_nvme &= 0xf;
2784 /* Last device exit. */
2785 if (list[i].d_id.b.rsvd_1 != 0)
2790 /* GID_PN completion processing. */
2791 void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea)
2793 fc_port_t *fcport = ea->fcport;
2795 ql_dbg(ql_dbg_disc, vha, 0x201d,
2796 "%s %8phC login state %d\n",
2797 __func__, fcport->port_name, fcport->fw_login_state);
2799 if (ea->sp->gen2 != fcport->login_gen) {
2800 /* PLOGI/PRLI/LOGO came in while cmd was out.*/
2801 ql_dbg(ql_dbg_disc, vha, 0x201e,
2802 "%s %8phC generation changed rscn %d|%d login %d|%d \n",
2803 __func__, fcport->port_name, fcport->last_rscn_gen,
2804 fcport->rscn_gen, fcport->last_login_gen, fcport->login_gen);
2809 if (ea->sp->gen1 == fcport->rscn_gen) {
2810 fcport->scan_state = QLA_FCPORT_FOUND;
2811 fcport->flags |= FCF_FABRIC_DEVICE;
2813 if (fcport->d_id.b24 == ea->id.b24) {
2814 /* cable plugged into the same place */
2815 switch (vha->host->active_mode) {
2817 /* NOOP. let the other guy login to us.*/
2819 case MODE_INITIATOR:
2822 ql_dbg(ql_dbg_disc, vha, 0x201f,
2823 "%s %d %8phC post %s\n", __func__,
2824 __LINE__, fcport->port_name,
2825 (atomic_read(&fcport->state) ==
2826 FCS_ONLINE) ? "gpdb" : "gnl");
2828 if (atomic_read(&fcport->state) ==
2830 qla24xx_post_gpdb_work(vha,
2831 fcport, PDO_FORCE_ADISC);
2833 qla24xx_post_gnl_work(vha,
2837 } else { /* fcport->d_id.b24 != ea->id.b24 */
2838 fcport->d_id.b24 = ea->id.b24;
2839 if (fcport->deleted != QLA_SESS_DELETED) {
2840 ql_dbg(ql_dbg_disc, vha, 0x2021,
2841 "%s %d %8phC post del sess\n",
2842 __func__, __LINE__, fcport->port_name);
2843 qlt_schedule_sess_for_deletion_lock(fcport);
2846 } else { /* ea->sp->gen1 != fcport->rscn_gen */
2847 ql_dbg(ql_dbg_disc, vha, 0x2022,
2848 "%s %d %8phC post gidpn\n",
2849 __func__, __LINE__, fcport->port_name);
2850 /* rscn came in while cmd was out */
2851 qla24xx_post_gidpn_work(vha, fcport);
2853 } else { /* ea->rc */
2855 if (ea->sp->gen1 == fcport->rscn_gen) {
2856 if (ea->sp->gen2 == fcport->login_gen) {
2857 ql_dbg(ql_dbg_disc, vha, 0x2042,
2858 "%s %d %8phC post del sess\n", __func__,
2859 __LINE__, fcport->port_name);
2860 qlt_schedule_sess_for_deletion_lock(fcport);
2862 ql_dbg(ql_dbg_disc, vha, 0x2045,
2863 "%s %d %8phC login\n", __func__, __LINE__,
2865 qla24xx_fcport_handle_login(vha, fcport);
2868 ql_dbg(ql_dbg_disc, vha, 0x2049,
2869 "%s %d %8phC post gidpn\n", __func__, __LINE__,
2871 qla24xx_post_gidpn_work(vha, fcport);
2876 static void qla2x00_async_gidpn_sp_done(void *s, int res)
2879 struct scsi_qla_host *vha = sp->vha;
2880 fc_port_t *fcport = sp->fcport;
2881 u8 *id = fcport->ct_desc.ct_sns->p.rsp.rsp.gid_pn.port_id;
2882 struct event_arg ea;
2884 fcport->flags &= ~FCF_ASYNC_SENT;
2886 memset(&ea, 0, sizeof(ea));
2888 ea.id.b.domain = id[0];
2889 ea.id.b.area = id[1];
2890 ea.id.b.al_pa = id[2];
2893 ea.event = FCME_GIDPN_DONE;
2895 if (res == QLA_FUNCTION_TIMEOUT) {
2896 ql_dbg(ql_dbg_disc, sp->vha, 0xffff,
2897 "Async done-%s WWPN %8phC timed out.\n",
2898 sp->name, fcport->port_name);
2899 qla24xx_post_gidpn_work(sp->vha, fcport);
2903 ql_dbg(ql_dbg_disc, sp->vha, 0xffff,
2904 "Async done-%s fail res %x, WWPN %8phC\n",
2905 sp->name, res, fcport->port_name);
2907 ql_dbg(ql_dbg_disc, vha, 0x204f,
2908 "Async done-%s good WWPN %8phC ID %3phC\n",
2909 sp->name, fcport->port_name, id);
2912 qla2x00_fcport_event_handler(vha, &ea);
2917 int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t *fcport)
2919 int rval = QLA_FUNCTION_FAILED;
2920 struct ct_sns_req *ct_req;
2923 if (!vha->flags.online)
2926 fcport->flags |= FCF_ASYNC_SENT;
2927 fcport->disc_state = DSC_GID_PN;
2928 fcport->scan_state = QLA_FCPORT_SCAN;
2929 sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
2933 sp->type = SRB_CT_PTHRU_CMD;
2935 sp->gen1 = fcport->rscn_gen;
2936 sp->gen2 = fcport->login_gen;
2938 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
2940 /* CT_IU preamble */
2941 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GID_PN_CMD,
2945 memcpy(ct_req->req.gid_pn.port_name, fcport->port_name,
2948 /* req & rsp use the same buffer */
2949 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
2950 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
2951 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
2952 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
2953 sp->u.iocb_cmd.u.ctarg.req_size = GID_PN_REQ_SIZE;
2954 sp->u.iocb_cmd.u.ctarg.rsp_size = GID_PN_RSP_SIZE;
2955 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
2957 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
2958 sp->done = qla2x00_async_gidpn_sp_done;
2960 rval = qla2x00_start_sp(sp);
2961 if (rval != QLA_SUCCESS)
2964 ql_dbg(ql_dbg_disc, vha, 0x20a4,
2965 "Async-%s - %8phC hdl=%x loopid=%x portid %02x%02x%02x.\n",
2966 sp->name, fcport->port_name,
2967 sp->handle, fcport->loop_id, fcport->d_id.b.domain,
2968 fcport->d_id.b.area, fcport->d_id.b.al_pa);
2974 fcport->flags &= ~FCF_ASYNC_SENT;
2978 int qla24xx_post_gidpn_work(struct scsi_qla_host *vha, fc_port_t *fcport)
2980 struct qla_work_evt *e;
2983 ls = atomic_read(&vha->loop_state);
2984 if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
2985 test_bit(UNLOADING, &vha->dpc_flags))
2988 e = qla2x00_alloc_work(vha, QLA_EVT_GIDPN);
2990 return QLA_FUNCTION_FAILED;
2992 e->u.fcport.fcport = fcport;
2993 return qla2x00_post_work(vha, e);
2996 int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport)
2998 struct qla_work_evt *e;
3000 e = qla2x00_alloc_work(vha, QLA_EVT_GPSC);
3002 return QLA_FUNCTION_FAILED;
3004 e->u.fcport.fcport = fcport;
3005 return qla2x00_post_work(vha, e);
3008 static void qla24xx_async_gpsc_sp_done(void *s, int res)
3011 struct scsi_qla_host *vha = sp->vha;
3012 struct qla_hw_data *ha = vha->hw;
3013 fc_port_t *fcport = sp->fcport;
3014 struct ct_sns_rsp *ct_rsp;
3015 struct event_arg ea;
3017 ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
3019 ql_dbg(ql_dbg_disc, vha, 0x2053,
3020 "Async done-%s res %x, WWPN %8phC \n",
3021 sp->name, res, fcport->port_name);
3023 fcport->flags &= ~FCF_ASYNC_SENT;
3025 if (res == (DID_ERROR << 16)) {
3026 /* entry status error */
3029 if ((ct_rsp->header.reason_code ==
3030 CT_REASON_INVALID_COMMAND_CODE) ||
3031 (ct_rsp->header.reason_code ==
3032 CT_REASON_COMMAND_UNSUPPORTED)) {
3033 ql_dbg(ql_dbg_disc, vha, 0x2019,
3034 "GPSC command unsupported, disabling query.\n");
3035 ha->flags.gpsc_supported = 0;
3039 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
3041 fcport->fp_speed = PORT_SPEED_1GB;
3044 fcport->fp_speed = PORT_SPEED_2GB;
3047 fcport->fp_speed = PORT_SPEED_4GB;
3050 fcport->fp_speed = PORT_SPEED_10GB;
3053 fcport->fp_speed = PORT_SPEED_8GB;
3056 fcport->fp_speed = PORT_SPEED_16GB;
3059 fcport->fp_speed = PORT_SPEED_32GB;
3063 ql_dbg(ql_dbg_disc, vha, 0x2054,
3064 "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n",
3065 sp->name, fcport->fabric_port_name,
3066 be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
3067 be16_to_cpu(ct_rsp->rsp.gpsc.speed));
3069 memset(&ea, 0, sizeof(ea));
3070 ea.event = FCME_GPSC_DONE;
3073 qla2x00_fcport_event_handler(vha, &ea);
3079 int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport)
3081 int rval = QLA_FUNCTION_FAILED;
3082 struct ct_sns_req *ct_req;
3085 if (!vha->flags.online)
3088 fcport->flags |= FCF_ASYNC_SENT;
3089 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
3093 sp->type = SRB_CT_PTHRU_CMD;
3095 sp->gen1 = fcport->rscn_gen;
3096 sp->gen2 = fcport->login_gen;
3098 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
3100 /* CT_IU preamble */
3101 ct_req = qla24xx_prep_ct_fm_req(fcport->ct_desc.ct_sns, GPSC_CMD,
3105 memcpy(ct_req->req.gpsc.port_name, fcport->fabric_port_name,
3108 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
3109 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
3110 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
3111 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
3112 sp->u.iocb_cmd.u.ctarg.req_size = GPSC_REQ_SIZE;
3113 sp->u.iocb_cmd.u.ctarg.rsp_size = GPSC_RSP_SIZE;
3114 sp->u.iocb_cmd.u.ctarg.nport_handle = vha->mgmt_svr_loop_id;
3116 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
3117 sp->done = qla24xx_async_gpsc_sp_done;
3119 rval = qla2x00_start_sp(sp);
3120 if (rval != QLA_SUCCESS)
3123 ql_dbg(ql_dbg_disc, vha, 0x205e,
3124 "Async-%s %8phC hdl=%x loopid=%x portid=%02x%02x%02x.\n",
3125 sp->name, fcport->port_name, sp->handle,
3126 fcport->loop_id, fcport->d_id.b.domain,
3127 fcport->d_id.b.area, fcport->d_id.b.al_pa);
3133 fcport->flags &= ~FCF_ASYNC_SENT;
3137 int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id)
3139 struct qla_work_evt *e;
3141 if (test_bit(UNLOADING, &vha->dpc_flags))
3144 e = qla2x00_alloc_work(vha, QLA_EVT_GPNID);
3146 return QLA_FUNCTION_FAILED;
3148 e->u.gpnid.id = *id;
3149 return qla2x00_post_work(vha, e);
3152 void qla24xx_async_gpnid_done(scsi_qla_host_t *vha, srb_t *sp)
3154 if (sp->u.iocb_cmd.u.ctarg.req) {
3155 dma_free_coherent(&vha->hw->pdev->dev,
3156 sizeof(struct ct_sns_pkt),
3157 sp->u.iocb_cmd.u.ctarg.req,
3158 sp->u.iocb_cmd.u.ctarg.req_dma);
3159 sp->u.iocb_cmd.u.ctarg.req = NULL;
3161 if (sp->u.iocb_cmd.u.ctarg.rsp) {
3162 dma_free_coherent(&vha->hw->pdev->dev,
3163 sizeof(struct ct_sns_pkt),
3164 sp->u.iocb_cmd.u.ctarg.rsp,
3165 sp->u.iocb_cmd.u.ctarg.rsp_dma);
3166 sp->u.iocb_cmd.u.ctarg.rsp = NULL;
3172 void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
3175 unsigned long flags;
3177 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
3178 fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1);
3179 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3182 /* cable moved. just plugged in */
3184 fcport->d_id = ea->id;
3185 fcport->scan_state = QLA_FCPORT_FOUND;
3186 fcport->flags |= FCF_FABRIC_DEVICE;
3188 switch (fcport->disc_state) {
3190 ql_dbg(ql_dbg_disc, vha, 0x210d,
3191 "%s %d %8phC login\n", __func__, __LINE__,
3193 qla24xx_fcport_handle_login(vha, fcport);
3195 case DSC_DELETE_PEND:
3198 ql_dbg(ql_dbg_disc, vha, 0x2064,
3199 "%s %d %8phC post del sess\n",
3200 __func__, __LINE__, fcport->port_name);
3201 qlt_schedule_sess_for_deletion_lock(fcport);
3205 /* create new fcport */
3206 ql_dbg(ql_dbg_disc, vha, 0x2065,
3207 "%s %d %8phC post new sess\n",
3208 __func__, __LINE__, ea->port_name);
3210 qla24xx_post_newsess_work(vha, &ea->id, ea->port_name, NULL);
3214 static void qla2x00_async_gpnid_sp_done(void *s, int res)
3217 struct scsi_qla_host *vha = sp->vha;
3218 struct ct_sns_req *ct_req =
3219 (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
3220 struct ct_sns_rsp *ct_rsp =
3221 (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
3222 struct event_arg ea;
3223 struct qla_work_evt *e;
3224 unsigned long flags;
3227 ql_dbg(ql_dbg_disc, vha, 0x2066,
3228 "Async done-%s fail res %x rscn gen %d ID %3phC. %8phC\n",
3229 sp->name, res, sp->gen1, ct_req->req.port_id.port_id,
3230 ct_rsp->rsp.gpn_id.port_name);
3232 ql_dbg(ql_dbg_disc, vha, 0x2066,
3233 "Async done-%s good rscn gen %d ID %3phC. %8phC\n",
3234 sp->name, sp->gen1, ct_req->req.port_id.port_id,
3235 ct_rsp->rsp.gpn_id.port_name);
3237 memset(&ea, 0, sizeof(ea));
3238 memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
3240 ea.id.b.domain = ct_req->req.port_id.port_id[0];
3241 ea.id.b.area = ct_req->req.port_id.port_id[1];
3242 ea.id.b.al_pa = ct_req->req.port_id.port_id[2];
3244 ea.event = FCME_GPNID_DONE;
3246 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
3247 list_del(&sp->elem);
3248 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3251 if (res == QLA_FUNCTION_TIMEOUT)
3252 qla24xx_post_gpnid_work(sp->vha, &ea.id);
3255 } else if (sp->gen1) {
3256 /* There was anoter RSNC for this Nport ID */
3257 qla24xx_post_gpnid_work(sp->vha, &ea.id);
3262 qla2x00_fcport_event_handler(vha, &ea);
3264 e = qla2x00_alloc_work(vha, QLA_EVT_GPNID_DONE);
3266 /* please ignore kernel warning. otherwise, we have mem leak. */
3267 if (sp->u.iocb_cmd.u.ctarg.req) {
3268 dma_free_coherent(&vha->hw->pdev->dev,
3269 sizeof(struct ct_sns_pkt),
3270 sp->u.iocb_cmd.u.ctarg.req,
3271 sp->u.iocb_cmd.u.ctarg.req_dma);
3272 sp->u.iocb_cmd.u.ctarg.req = NULL;
3274 if (sp->u.iocb_cmd.u.ctarg.rsp) {
3275 dma_free_coherent(&vha->hw->pdev->dev,
3276 sizeof(struct ct_sns_pkt),
3277 sp->u.iocb_cmd.u.ctarg.rsp,
3278 sp->u.iocb_cmd.u.ctarg.rsp_dma);
3279 sp->u.iocb_cmd.u.ctarg.rsp = NULL;
3287 qla2x00_post_work(vha, e);
3290 /* Get WWPN with Nport ID. */
3291 int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
3293 int rval = QLA_FUNCTION_FAILED;
3294 struct ct_sns_req *ct_req;
3296 struct ct_sns_pkt *ct_sns;
3297 unsigned long flags;
3299 if (!vha->flags.online)
3302 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
3306 sp->type = SRB_CT_PTHRU_CMD;
3308 sp->u.iocb_cmd.u.ctarg.id = *id;
3310 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
3312 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
3313 list_for_each_entry(tsp, &vha->gpnid_list, elem) {
3314 if (tsp->u.iocb_cmd.u.ctarg.id.b24 == id->b24) {
3316 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3321 list_add_tail(&sp->elem, &vha->gpnid_list);
3322 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3324 sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
3325 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
3327 if (!sp->u.iocb_cmd.u.ctarg.req) {
3328 ql_log(ql_log_warn, vha, 0xd041,
3329 "Failed to allocate ct_sns request.\n");
3333 sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
3334 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
3336 if (!sp->u.iocb_cmd.u.ctarg.rsp) {
3337 ql_log(ql_log_warn, vha, 0xd042,
3338 "Failed to allocate ct_sns request.\n");
3342 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
3343 memset(ct_sns, 0, sizeof(*ct_sns));
3345 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
3346 /* CT_IU preamble */
3347 ct_req = qla2x00_prep_ct_req(ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE);
3350 ct_req->req.port_id.port_id[0] = id->b.domain;
3351 ct_req->req.port_id.port_id[1] = id->b.area;
3352 ct_req->req.port_id.port_id[2] = id->b.al_pa;
3354 sp->u.iocb_cmd.u.ctarg.req_size = GPN_ID_REQ_SIZE;
3355 sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_RSP_SIZE;
3356 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
3358 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
3359 sp->done = qla2x00_async_gpnid_sp_done;
3361 rval = qla2x00_start_sp(sp);
3362 if (rval != QLA_SUCCESS)
3365 ql_dbg(ql_dbg_disc, vha, 0x2067,
3366 "Async-%s hdl=%x ID %3phC.\n", sp->name,
3367 sp->handle, ct_req->req.port_id.port_id);
3371 spin_lock_irqsave(&vha->hw->vport_slock, flags);
3372 list_del(&sp->elem);
3373 spin_unlock_irqrestore(&vha->hw->vport_slock, flags);
3375 if (sp->u.iocb_cmd.u.ctarg.req) {
3376 dma_free_coherent(&vha->hw->pdev->dev,
3377 sizeof(struct ct_sns_pkt),
3378 sp->u.iocb_cmd.u.ctarg.req,
3379 sp->u.iocb_cmd.u.ctarg.req_dma);
3380 sp->u.iocb_cmd.u.ctarg.req = NULL;
3382 if (sp->u.iocb_cmd.u.ctarg.rsp) {
3383 dma_free_coherent(&vha->hw->pdev->dev,
3384 sizeof(struct ct_sns_pkt),
3385 sp->u.iocb_cmd.u.ctarg.rsp,
3386 sp->u.iocb_cmd.u.ctarg.rsp_dma);
3387 sp->u.iocb_cmd.u.ctarg.rsp = NULL;
3395 void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
3397 fc_port_t *fcport = ea->fcport;
3399 qla24xx_post_gnl_work(vha, fcport);
3402 void qla24xx_async_gffid_sp_done(void *s, int res)
3405 struct scsi_qla_host *vha = sp->vha;
3406 fc_port_t *fcport = sp->fcport;
3407 struct ct_sns_rsp *ct_rsp;
3408 struct event_arg ea;
3410 ql_dbg(ql_dbg_disc, vha, 0x2133,
3411 "Async done-%s res %x ID %x. %8phC\n",
3412 sp->name, res, fcport->d_id.b24, fcport->port_name);
3414 fcport->flags &= ~FCF_ASYNC_SENT;
3415 ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
3417 * FC-GS-7, 5.2.3.12 FC-4 Features - format
3418 * The format of the FC-4 Features object, as defined by the FC-4,
3419 * Shall be an array of 4-bit values, one for each type code value
3422 if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) {
3425 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
3426 fcport->fc4_type &= 0xf;
3429 if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) {
3430 /* w5 [00:03]/28h */
3432 ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
3433 fcport->fc4f_nvme &= 0xf;
3437 memset(&ea, 0, sizeof(ea));
3439 ea.fcport = sp->fcport;
3441 ea.event = FCME_GFFID_DONE;
3443 qla2x00_fcport_event_handler(vha, &ea);
3447 /* Get FC4 Feature with Nport ID. */
3448 int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
3450 int rval = QLA_FUNCTION_FAILED;
3451 struct ct_sns_req *ct_req;
3454 if (!vha->flags.online)
3457 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
3461 fcport->flags |= FCF_ASYNC_SENT;
3462 sp->type = SRB_CT_PTHRU_CMD;
3464 sp->gen1 = fcport->rscn_gen;
3465 sp->gen2 = fcport->login_gen;
3467 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
3469 /* CT_IU preamble */
3470 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD,
3473 ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain;
3474 ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area;
3475 ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
3477 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
3478 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
3479 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
3480 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
3481 sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE;
3482 sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
3483 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
3485 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
3486 sp->done = qla24xx_async_gffid_sp_done;
3488 rval = qla2x00_start_sp(sp);
3489 if (rval != QLA_SUCCESS)
3492 ql_dbg(ql_dbg_disc, vha, 0x2132,
3493 "Async-%s hdl=%x %8phC.\n", sp->name,
3494 sp->handle, fcport->port_name);
3499 fcport->flags &= ~FCF_ASYNC_SENT;