2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2012 QLogic Corporation
5 * See LICENSE.qla2xxx for copyright and licensing details.
8 #include "qla_target.h"
10 static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
11 static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
12 static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
13 static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *);
14 static int qla2x00_sns_rft_id(scsi_qla_host_t *);
15 static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
18 * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
20 * @req_size: request size in bytes
21 * @rsp_size: response size in bytes
23 * Returns a pointer to the @ha's ms_iocb.
26 qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
28 struct qla_hw_data *ha = vha->hw;
29 ms_iocb_entry_t *ms_pkt;
32 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
34 ms_pkt->entry_type = MS_IOCB_TYPE;
35 ms_pkt->entry_count = 1;
36 SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
37 ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
38 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
39 ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
40 ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
41 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
42 ms_pkt->req_bytecount = cpu_to_le32(req_size);
44 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
45 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
46 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
48 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
49 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
50 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
56 * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
58 * @req_size: request size in bytes
59 * @rsp_size: response size in bytes
61 * Returns a pointer to the @ha's ms_iocb.
64 qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
66 struct qla_hw_data *ha = vha->hw;
67 struct ct_entry_24xx *ct_pkt;
69 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
70 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
72 ct_pkt->entry_type = CT_IOCB_TYPE;
73 ct_pkt->entry_count = 1;
74 ct_pkt->nport_handle = __constant_cpu_to_le16(NPH_SNS);
75 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
76 ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
77 ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
78 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
79 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
81 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
82 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
83 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
85 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
86 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
87 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
88 ct_pkt->vp_index = vha->vp_idx;
94 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
95 * @ct_req: CT request buffer
97 * @rsp_size: response size in bytes
99 * Returns a pointer to the intitialized @ct_req.
101 static inline struct ct_sns_req *
102 qla2x00_prep_ct_req(struct ct_sns_req *ct_req, uint16_t cmd, uint16_t rsp_size)
104 memset(ct_req, 0, sizeof(struct ct_sns_pkt));
106 ct_req->header.revision = 0x01;
107 ct_req->header.gs_type = 0xFC;
108 ct_req->header.gs_subtype = 0x02;
109 ct_req->command = cpu_to_be16(cmd);
110 ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
116 qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt,
117 struct ct_sns_rsp *ct_rsp, const char *routine)
120 uint16_t comp_status;
121 struct qla_hw_data *ha = vha->hw;
123 rval = QLA_FUNCTION_FAILED;
124 if (ms_pkt->entry_status != 0) {
125 ql_dbg(ql_dbg_disc, vha, 0x2031,
126 "%s failed, error status (%x) on port_id: %02x%02x%02x.\n",
127 routine, ms_pkt->entry_status, vha->d_id.b.domain,
128 vha->d_id.b.area, vha->d_id.b.al_pa);
130 if (IS_FWI2_CAPABLE(ha))
131 comp_status = le16_to_cpu(
132 ((struct ct_entry_24xx *)ms_pkt)->comp_status);
134 comp_status = le16_to_cpu(ms_pkt->status);
135 switch (comp_status) {
137 case CS_DATA_UNDERRUN:
138 case CS_DATA_OVERRUN: /* Overrun? */
139 if (ct_rsp->header.response !=
140 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
141 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077,
142 "%s failed rejected request on port_id: "
143 "%02x%02x%02x.\n", routine,
144 vha->d_id.b.domain, vha->d_id.b.area,
146 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha,
147 0x2078, (uint8_t *)&ct_rsp->header,
148 sizeof(struct ct_rsp_hdr));
149 rval = QLA_INVALID_COMMAND;
154 ql_dbg(ql_dbg_disc, vha, 0x2033,
155 "%s failed, completion status (%x) on port_id: "
156 "%02x%02x%02x.\n", routine, comp_status,
157 vha->d_id.b.domain, vha->d_id.b.area,
166 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
168 * @fcport: fcport entry to updated
170 * Returns 0 on success.
173 qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
177 ms_iocb_entry_t *ms_pkt;
178 struct ct_sns_req *ct_req;
179 struct ct_sns_rsp *ct_rsp;
180 struct qla_hw_data *ha = vha->hw;
182 if (IS_QLA2100(ha) || IS_QLA2200(ha))
183 return qla2x00_sns_ga_nxt(vha, fcport);
186 /* Prepare common MS IOCB */
187 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GA_NXT_REQ_SIZE,
190 /* Prepare CT request */
191 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD,
193 ct_rsp = &ha->ct_sns->p.rsp;
195 /* Prepare CT arguments -- port_id */
196 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
197 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
198 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
200 /* Execute MS IOCB */
201 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
202 sizeof(ms_iocb_entry_t));
203 if (rval != QLA_SUCCESS) {
205 ql_dbg(ql_dbg_disc, vha, 0x2062,
206 "GA_NXT issue IOCB failed (%d).\n", rval);
207 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") !=
209 rval = QLA_FUNCTION_FAILED;
211 /* Populate fc_port_t entry. */
212 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0];
213 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1];
214 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2];
216 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name,
218 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name,
221 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
222 ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
223 fcport->d_id.b.domain = 0xf0;
225 ql_dbg(ql_dbg_disc, vha, 0x2063,
226 "GA_NXT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x "
227 "pn %02x%02x%02x%02x%02x%02x%02x%02x "
228 "port_id=%02x%02x%02x.\n",
229 fcport->node_name[0], fcport->node_name[1],
230 fcport->node_name[2], fcport->node_name[3],
231 fcport->node_name[4], fcport->node_name[5],
232 fcport->node_name[6], fcport->node_name[7],
233 fcport->port_name[0], fcport->port_name[1],
234 fcport->port_name[2], fcport->port_name[3],
235 fcport->port_name[4], fcport->port_name[5],
236 fcport->port_name[6], fcport->port_name[7],
237 fcport->d_id.b.domain, fcport->d_id.b.area,
238 fcport->d_id.b.al_pa);
245 qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha)
247 return vha->hw->max_fibre_devices * 4 + 16;
251 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
253 * @list: switch info entries to populate
255 * NOTE: Non-Nx_Ports are not requested.
257 * Returns 0 on success.
260 qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
265 ms_iocb_entry_t *ms_pkt;
266 struct ct_sns_req *ct_req;
267 struct ct_sns_rsp *ct_rsp;
269 struct ct_sns_gid_pt_data *gid_data;
270 struct qla_hw_data *ha = vha->hw;
271 uint16_t gid_pt_rsp_size;
273 if (IS_QLA2100(ha) || IS_QLA2200(ha))
274 return qla2x00_sns_gid_pt(vha, list);
277 gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha);
279 /* Prepare common MS IOCB */
280 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GID_PT_REQ_SIZE,
283 /* Prepare CT request */
284 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD,
286 ct_rsp = &ha->ct_sns->p.rsp;
288 /* Prepare CT arguments -- port_type */
289 ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE;
291 /* Execute MS IOCB */
292 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
293 sizeof(ms_iocb_entry_t));
294 if (rval != QLA_SUCCESS) {
296 ql_dbg(ql_dbg_disc, vha, 0x2055,
297 "GID_PT issue IOCB failed (%d).\n", rval);
298 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") !=
300 rval = QLA_FUNCTION_FAILED;
302 /* Set port IDs in switch info list. */
303 for (i = 0; i < ha->max_fibre_devices; i++) {
304 gid_data = &ct_rsp->rsp.gid_pt.entries[i];
305 list[i].d_id.b.domain = gid_data->port_id[0];
306 list[i].d_id.b.area = gid_data->port_id[1];
307 list[i].d_id.b.al_pa = gid_data->port_id[2];
308 memset(list[i].fabric_port_name, 0, WWN_SIZE);
309 list[i].fp_speed = PORT_SPEED_UNKNOWN;
312 if (gid_data->control_byte & BIT_7) {
313 list[i].d_id.b.rsvd_1 = gid_data->control_byte;
319 * If we've used all available slots, then the switch is
320 * reporting back more devices than we can handle with this
321 * single call. Return a failed status, and let GA_NXT handle
324 if (i == ha->max_fibre_devices)
325 rval = QLA_FUNCTION_FAILED;
332 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
334 * @list: switch info entries to populate
336 * Returns 0 on success.
339 qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
341 int rval = QLA_SUCCESS;
344 ms_iocb_entry_t *ms_pkt;
345 struct ct_sns_req *ct_req;
346 struct ct_sns_rsp *ct_rsp;
347 struct qla_hw_data *ha = vha->hw;
349 if (IS_QLA2100(ha) || IS_QLA2200(ha))
350 return qla2x00_sns_gpn_id(vha, list);
352 for (i = 0; i < ha->max_fibre_devices; i++) {
354 /* Prepare common MS IOCB */
355 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GPN_ID_REQ_SIZE,
358 /* Prepare CT request */
359 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GPN_ID_CMD,
361 ct_rsp = &ha->ct_sns->p.rsp;
363 /* Prepare CT arguments -- port_id */
364 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
365 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
366 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
368 /* Execute MS IOCB */
369 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
370 sizeof(ms_iocb_entry_t));
371 if (rval != QLA_SUCCESS) {
373 ql_dbg(ql_dbg_disc, vha, 0x2056,
374 "GPN_ID issue IOCB failed (%d).\n", rval);
376 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
377 "GPN_ID") != QLA_SUCCESS) {
378 rval = QLA_FUNCTION_FAILED;
382 memcpy(list[i].port_name,
383 ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
386 /* Last device exit. */
387 if (list[i].d_id.b.rsvd_1 != 0)
395 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
397 * @list: switch info entries to populate
399 * Returns 0 on success.
402 qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
404 int rval = QLA_SUCCESS;
406 struct qla_hw_data *ha = vha->hw;
407 ms_iocb_entry_t *ms_pkt;
408 struct ct_sns_req *ct_req;
409 struct ct_sns_rsp *ct_rsp;
411 if (IS_QLA2100(ha) || IS_QLA2200(ha))
412 return qla2x00_sns_gnn_id(vha, list);
414 for (i = 0; i < ha->max_fibre_devices; i++) {
416 /* Prepare common MS IOCB */
417 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GNN_ID_REQ_SIZE,
420 /* Prepare CT request */
421 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GNN_ID_CMD,
423 ct_rsp = &ha->ct_sns->p.rsp;
425 /* Prepare CT arguments -- port_id */
426 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
427 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
428 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
430 /* Execute MS IOCB */
431 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
432 sizeof(ms_iocb_entry_t));
433 if (rval != QLA_SUCCESS) {
435 ql_dbg(ql_dbg_disc, vha, 0x2057,
436 "GNN_ID issue IOCB failed (%d).\n", rval);
438 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
439 "GNN_ID") != QLA_SUCCESS) {
440 rval = QLA_FUNCTION_FAILED;
444 memcpy(list[i].node_name,
445 ct_rsp->rsp.gnn_id.node_name, WWN_SIZE);
447 ql_dbg(ql_dbg_disc, vha, 0x2058,
448 "GID_PT entry - nn %02x%02x%02x%02x%02x%02x%02X%02x "
449 "pn %02x%02x%02x%02x%02x%02x%02X%02x "
450 "portid=%02x%02x%02x.\n",
451 list[i].node_name[0], list[i].node_name[1],
452 list[i].node_name[2], list[i].node_name[3],
453 list[i].node_name[4], list[i].node_name[5],
454 list[i].node_name[6], list[i].node_name[7],
455 list[i].port_name[0], list[i].port_name[1],
456 list[i].port_name[2], list[i].port_name[3],
457 list[i].port_name[4], list[i].port_name[5],
458 list[i].port_name[6], list[i].port_name[7],
459 list[i].d_id.b.domain, list[i].d_id.b.area,
460 list[i].d_id.b.al_pa);
463 /* Last device exit. */
464 if (list[i].d_id.b.rsvd_1 != 0)
472 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
475 * Returns 0 on success.
478 qla2x00_rft_id(scsi_qla_host_t *vha)
481 struct qla_hw_data *ha = vha->hw;
482 ms_iocb_entry_t *ms_pkt;
483 struct ct_sns_req *ct_req;
484 struct ct_sns_rsp *ct_rsp;
486 if (IS_QLA2100(ha) || IS_QLA2200(ha))
487 return qla2x00_sns_rft_id(vha);
490 /* Prepare common MS IOCB */
491 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFT_ID_REQ_SIZE,
494 /* Prepare CT request */
495 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD,
497 ct_rsp = &ha->ct_sns->p.rsp;
499 /* Prepare CT arguments -- port_id, FC-4 types */
500 ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain;
501 ct_req->req.rft_id.port_id[1] = vha->d_id.b.area;
502 ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa;
504 ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */
506 /* Execute MS IOCB */
507 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
508 sizeof(ms_iocb_entry_t));
509 if (rval != QLA_SUCCESS) {
511 ql_dbg(ql_dbg_disc, vha, 0x2043,
512 "RFT_ID issue IOCB failed (%d).\n", rval);
513 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFT_ID") !=
515 rval = QLA_FUNCTION_FAILED;
517 ql_dbg(ql_dbg_disc, vha, 0x2044,
518 "RFT_ID exiting normally.\n");
525 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
528 * Returns 0 on success.
531 qla2x00_rff_id(scsi_qla_host_t *vha)
534 struct qla_hw_data *ha = vha->hw;
535 ms_iocb_entry_t *ms_pkt;
536 struct ct_sns_req *ct_req;
537 struct ct_sns_rsp *ct_rsp;
539 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
540 ql_dbg(ql_dbg_disc, vha, 0x2046,
541 "RFF_ID call not supported on ISP2100/ISP2200.\n");
542 return (QLA_SUCCESS);
546 /* Prepare common MS IOCB */
547 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFF_ID_REQ_SIZE,
550 /* Prepare CT request */
551 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD,
553 ct_rsp = &ha->ct_sns->p.rsp;
555 /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
556 ct_req->req.rff_id.port_id[0] = vha->d_id.b.domain;
557 ct_req->req.rff_id.port_id[1] = vha->d_id.b.area;
558 ct_req->req.rff_id.port_id[2] = vha->d_id.b.al_pa;
560 qlt_rff_id(vha, ct_req);
562 ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */
564 /* Execute MS IOCB */
565 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
566 sizeof(ms_iocb_entry_t));
567 if (rval != QLA_SUCCESS) {
569 ql_dbg(ql_dbg_disc, vha, 0x2047,
570 "RFF_ID issue IOCB failed (%d).\n", rval);
571 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFF_ID") !=
573 rval = QLA_FUNCTION_FAILED;
575 ql_dbg(ql_dbg_disc, vha, 0x2048,
576 "RFF_ID exiting normally.\n");
583 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
586 * Returns 0 on success.
589 qla2x00_rnn_id(scsi_qla_host_t *vha)
592 struct qla_hw_data *ha = vha->hw;
593 ms_iocb_entry_t *ms_pkt;
594 struct ct_sns_req *ct_req;
595 struct ct_sns_rsp *ct_rsp;
597 if (IS_QLA2100(ha) || IS_QLA2200(ha))
598 return qla2x00_sns_rnn_id(vha);
601 /* Prepare common MS IOCB */
602 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RNN_ID_REQ_SIZE,
605 /* Prepare CT request */
606 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD,
608 ct_rsp = &ha->ct_sns->p.rsp;
610 /* Prepare CT arguments -- port_id, node_name */
611 ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain;
612 ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area;
613 ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa;
615 memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE);
617 /* Execute MS IOCB */
618 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
619 sizeof(ms_iocb_entry_t));
620 if (rval != QLA_SUCCESS) {
622 ql_dbg(ql_dbg_disc, vha, 0x204d,
623 "RNN_ID issue IOCB failed (%d).\n", rval);
624 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RNN_ID") !=
626 rval = QLA_FUNCTION_FAILED;
628 ql_dbg(ql_dbg_disc, vha, 0x204e,
629 "RNN_ID exiting normally.\n");
636 qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn)
638 struct qla_hw_data *ha = vha->hw;
639 sprintf(snn, "%s FW:v%d.%02d.%02d DVR:v%s",ha->model_number,
640 ha->fw_major_version, ha->fw_minor_version,
641 ha->fw_subminor_version, qla2x00_version_str);
645 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
648 * Returns 0 on success.
651 qla2x00_rsnn_nn(scsi_qla_host_t *vha)
654 struct qla_hw_data *ha = vha->hw;
655 ms_iocb_entry_t *ms_pkt;
656 struct ct_sns_req *ct_req;
657 struct ct_sns_rsp *ct_rsp;
659 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
660 ql_dbg(ql_dbg_disc, vha, 0x2050,
661 "RSNN_ID call unsupported on ISP2100/ISP2200.\n");
662 return (QLA_SUCCESS);
666 /* Prepare common MS IOCB */
667 /* Request size adjusted after CT preparation */
668 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, 0, RSNN_NN_RSP_SIZE);
670 /* Prepare CT request */
671 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD,
673 ct_rsp = &ha->ct_sns->p.rsp;
675 /* Prepare CT arguments -- node_name, symbolic node_name, size */
676 memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE);
678 /* Prepare the Symbolic Node Name */
679 qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name);
681 /* Calculate SNN length */
682 ct_req->req.rsnn_nn.name_len =
683 (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
685 /* Update MS IOCB request */
686 ms_pkt->req_bytecount =
687 cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len);
688 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
690 /* Execute MS IOCB */
691 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
692 sizeof(ms_iocb_entry_t));
693 if (rval != QLA_SUCCESS) {
695 ql_dbg(ql_dbg_disc, vha, 0x2051,
696 "RSNN_NN issue IOCB failed (%d).\n", rval);
697 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RSNN_NN") !=
699 rval = QLA_FUNCTION_FAILED;
701 ql_dbg(ql_dbg_disc, vha, 0x2052,
702 "RSNN_NN exiting normally.\n");
709 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
712 * @scmd_len: Subcommand length
713 * @data_size: response size in bytes
715 * Returns a pointer to the @ha's sns_cmd.
717 static inline struct sns_cmd_pkt *
718 qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
722 struct sns_cmd_pkt *sns_cmd;
723 struct qla_hw_data *ha = vha->hw;
725 sns_cmd = ha->sns_cmd;
726 memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt));
727 wc = data_size / 2; /* Size in 16bit words. */
728 sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc);
729 sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma));
730 sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma));
731 sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len);
732 sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd);
733 wc = (data_size - 16) / 4; /* Size in 32bit words. */
734 sns_cmd->p.cmd.size = cpu_to_le16(wc);
740 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
742 * @fcport: fcport entry to updated
744 * This command uses the old Exectute SNS Command mailbox routine.
746 * Returns 0 on success.
749 qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
751 int rval = QLA_SUCCESS;
752 struct qla_hw_data *ha = vha->hw;
753 struct sns_cmd_pkt *sns_cmd;
756 /* Prepare SNS command request. */
757 sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN,
758 GA_NXT_SNS_DATA_SIZE);
760 /* Prepare SNS command arguments -- port_id. */
761 sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa;
762 sns_cmd->p.cmd.param[1] = fcport->d_id.b.area;
763 sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain;
765 /* Execute SNS command. */
766 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2,
767 sizeof(struct sns_cmd_pkt));
768 if (rval != QLA_SUCCESS) {
770 ql_dbg(ql_dbg_disc, vha, 0x205f,
771 "GA_NXT Send SNS failed (%d).\n", rval);
772 } else if (sns_cmd->p.gan_data[8] != 0x80 ||
773 sns_cmd->p.gan_data[9] != 0x02) {
774 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084,
775 "GA_NXT failed, rejected request ga_nxt_rsp:\n");
776 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074,
777 sns_cmd->p.gan_data, 16);
778 rval = QLA_FUNCTION_FAILED;
780 /* Populate fc_port_t entry. */
781 fcport->d_id.b.domain = sns_cmd->p.gan_data[17];
782 fcport->d_id.b.area = sns_cmd->p.gan_data[18];
783 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19];
785 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE);
786 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE);
788 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE &&
789 sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE)
790 fcport->d_id.b.domain = 0xf0;
792 ql_dbg(ql_dbg_disc, vha, 0x2061,
793 "GA_NXT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x "
794 "pn %02x%02x%02x%02x%02x%02x%02x%02x "
795 "port_id=%02x%02x%02x.\n",
796 fcport->node_name[0], fcport->node_name[1],
797 fcport->node_name[2], fcport->node_name[3],
798 fcport->node_name[4], fcport->node_name[5],
799 fcport->node_name[6], fcport->node_name[7],
800 fcport->port_name[0], fcport->port_name[1],
801 fcport->port_name[2], fcport->port_name[3],
802 fcport->port_name[4], fcport->port_name[5],
803 fcport->port_name[6], fcport->port_name[7],
804 fcport->d_id.b.domain, fcport->d_id.b.area,
805 fcport->d_id.b.al_pa);
812 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
814 * @list: switch info entries to populate
816 * This command uses the old Exectute SNS Command mailbox routine.
818 * NOTE: Non-Nx_Ports are not requested.
820 * Returns 0 on success.
823 qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
826 struct qla_hw_data *ha = vha->hw;
829 struct sns_cmd_pkt *sns_cmd;
830 uint16_t gid_pt_sns_data_size;
832 gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha);
835 /* Prepare SNS command request. */
836 sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN,
837 gid_pt_sns_data_size);
839 /* Prepare SNS command arguments -- port_type. */
840 sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE;
842 /* Execute SNS command. */
843 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2,
844 sizeof(struct sns_cmd_pkt));
845 if (rval != QLA_SUCCESS) {
847 ql_dbg(ql_dbg_disc, vha, 0x206d,
848 "GID_PT Send SNS failed (%d).\n", rval);
849 } else if (sns_cmd->p.gid_data[8] != 0x80 ||
850 sns_cmd->p.gid_data[9] != 0x02) {
851 ql_dbg(ql_dbg_disc, vha, 0x202f,
852 "GID_PT failed, rejected request, gid_rsp:\n");
853 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081,
854 sns_cmd->p.gid_data, 16);
855 rval = QLA_FUNCTION_FAILED;
857 /* Set port IDs in switch info list. */
858 for (i = 0; i < ha->max_fibre_devices; i++) {
859 entry = &sns_cmd->p.gid_data[(i * 4) + 16];
860 list[i].d_id.b.domain = entry[1];
861 list[i].d_id.b.area = entry[2];
862 list[i].d_id.b.al_pa = entry[3];
865 if (entry[0] & BIT_7) {
866 list[i].d_id.b.rsvd_1 = entry[0];
872 * If we've used all available slots, then the switch is
873 * reporting back more devices that we can handle with this
874 * single call. Return a failed status, and let GA_NXT handle
877 if (i == ha->max_fibre_devices)
878 rval = QLA_FUNCTION_FAILED;
885 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
887 * @list: switch info entries to populate
889 * This command uses the old Exectute SNS Command mailbox routine.
891 * Returns 0 on success.
894 qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
896 int rval = QLA_SUCCESS;
897 struct qla_hw_data *ha = vha->hw;
899 struct sns_cmd_pkt *sns_cmd;
901 for (i = 0; i < ha->max_fibre_devices; i++) {
903 /* Prepare SNS command request. */
904 sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD,
905 GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE);
907 /* Prepare SNS command arguments -- port_id. */
908 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
909 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
910 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
912 /* Execute SNS command. */
913 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
914 GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
915 if (rval != QLA_SUCCESS) {
917 ql_dbg(ql_dbg_disc, vha, 0x2032,
918 "GPN_ID Send SNS failed (%d).\n", rval);
919 } else if (sns_cmd->p.gpn_data[8] != 0x80 ||
920 sns_cmd->p.gpn_data[9] != 0x02) {
921 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e,
922 "GPN_ID failed, rejected request, gpn_rsp:\n");
923 ql_dump_buffer(ql_dbg_disc, vha, 0x207f,
924 sns_cmd->p.gpn_data, 16);
925 rval = QLA_FUNCTION_FAILED;
928 memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16],
932 /* Last device exit. */
933 if (list[i].d_id.b.rsvd_1 != 0)
941 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
943 * @list: switch info entries to populate
945 * This command uses the old Exectute SNS Command mailbox routine.
947 * Returns 0 on success.
950 qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
952 int rval = QLA_SUCCESS;
953 struct qla_hw_data *ha = vha->hw;
955 struct sns_cmd_pkt *sns_cmd;
957 for (i = 0; i < ha->max_fibre_devices; i++) {
959 /* Prepare SNS command request. */
960 sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD,
961 GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE);
963 /* Prepare SNS command arguments -- port_id. */
964 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
965 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
966 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
968 /* Execute SNS command. */
969 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
970 GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
971 if (rval != QLA_SUCCESS) {
973 ql_dbg(ql_dbg_disc, vha, 0x203f,
974 "GNN_ID Send SNS failed (%d).\n", rval);
975 } else if (sns_cmd->p.gnn_data[8] != 0x80 ||
976 sns_cmd->p.gnn_data[9] != 0x02) {
977 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082,
978 "GNN_ID failed, rejected request, gnn_rsp:\n");
979 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a,
980 sns_cmd->p.gnn_data, 16);
981 rval = QLA_FUNCTION_FAILED;
984 memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16],
987 ql_dbg(ql_dbg_disc, vha, 0x206e,
988 "GID_PT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x "
989 "pn %02x%02x%02x%02x%02x%02x%02x%02x "
990 "port_id=%02x%02x%02x.\n",
991 list[i].node_name[0], list[i].node_name[1],
992 list[i].node_name[2], list[i].node_name[3],
993 list[i].node_name[4], list[i].node_name[5],
994 list[i].node_name[6], list[i].node_name[7],
995 list[i].port_name[0], list[i].port_name[1],
996 list[i].port_name[2], list[i].port_name[3],
997 list[i].port_name[4], list[i].port_name[5],
998 list[i].port_name[6], list[i].port_name[7],
999 list[i].d_id.b.domain, list[i].d_id.b.area,
1000 list[i].d_id.b.al_pa);
1003 /* Last device exit. */
1004 if (list[i].d_id.b.rsvd_1 != 0)
1012 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
1015 * This command uses the old Exectute SNS Command mailbox routine.
1017 * Returns 0 on success.
1020 qla2x00_sns_rft_id(scsi_qla_host_t *vha)
1023 struct qla_hw_data *ha = vha->hw;
1024 struct sns_cmd_pkt *sns_cmd;
1027 /* Prepare SNS command request. */
1028 sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN,
1029 RFT_ID_SNS_DATA_SIZE);
1031 /* Prepare SNS command arguments -- port_id, FC-4 types */
1032 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1033 sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1034 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
1036 sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */
1038 /* Execute SNS command. */
1039 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2,
1040 sizeof(struct sns_cmd_pkt));
1041 if (rval != QLA_SUCCESS) {
1043 ql_dbg(ql_dbg_disc, vha, 0x2060,
1044 "RFT_ID Send SNS failed (%d).\n", rval);
1045 } else if (sns_cmd->p.rft_data[8] != 0x80 ||
1046 sns_cmd->p.rft_data[9] != 0x02) {
1047 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083,
1048 "RFT_ID failed, rejected request rft_rsp:\n");
1049 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080,
1050 sns_cmd->p.rft_data, 16);
1051 rval = QLA_FUNCTION_FAILED;
1053 ql_dbg(ql_dbg_disc, vha, 0x2073,
1054 "RFT_ID exiting normally.\n");
1061 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
1065 * This command uses the old Exectute SNS Command mailbox routine.
1067 * Returns 0 on success.
1070 qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
1073 struct qla_hw_data *ha = vha->hw;
1074 struct sns_cmd_pkt *sns_cmd;
1077 /* Prepare SNS command request. */
1078 sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN,
1079 RNN_ID_SNS_DATA_SIZE);
1081 /* Prepare SNS command arguments -- port_id, nodename. */
1082 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1083 sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1084 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
1086 sns_cmd->p.cmd.param[4] = vha->node_name[7];
1087 sns_cmd->p.cmd.param[5] = vha->node_name[6];
1088 sns_cmd->p.cmd.param[6] = vha->node_name[5];
1089 sns_cmd->p.cmd.param[7] = vha->node_name[4];
1090 sns_cmd->p.cmd.param[8] = vha->node_name[3];
1091 sns_cmd->p.cmd.param[9] = vha->node_name[2];
1092 sns_cmd->p.cmd.param[10] = vha->node_name[1];
1093 sns_cmd->p.cmd.param[11] = vha->node_name[0];
1095 /* Execute SNS command. */
1096 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2,
1097 sizeof(struct sns_cmd_pkt));
1098 if (rval != QLA_SUCCESS) {
1100 ql_dbg(ql_dbg_disc, vha, 0x204a,
1101 "RNN_ID Send SNS failed (%d).\n", rval);
1102 } else if (sns_cmd->p.rnn_data[8] != 0x80 ||
1103 sns_cmd->p.rnn_data[9] != 0x02) {
1104 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b,
1105 "RNN_ID failed, rejected request, rnn_rsp:\n");
1106 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c,
1107 sns_cmd->p.rnn_data, 16);
1108 rval = QLA_FUNCTION_FAILED;
1110 ql_dbg(ql_dbg_disc, vha, 0x204c,
1111 "RNN_ID exiting normally.\n");
1118 * qla2x00_mgmt_svr_login() - Login to fabric Management Service.
1121 * Returns 0 on success.
1124 qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
1127 uint16_t mb[MAILBOX_REGISTER_COUNT];
1128 struct qla_hw_data *ha = vha->hw;
1130 if (vha->flags.management_server_logged_in)
1133 rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff,
1135 if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
1136 if (rval == QLA_MEMORY_ALLOC_FAILED)
1137 ql_dbg(ql_dbg_disc, vha, 0x2085,
1138 "Failed management_server login: loopid=%x "
1139 "rval=%d\n", vha->mgmt_svr_loop_id, rval);
1141 ql_dbg(ql_dbg_disc, vha, 0x2024,
1142 "Failed management_server login: loopid=%x "
1143 "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
1144 vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6],
1146 ret = QLA_FUNCTION_FAILED;
1148 vha->flags.management_server_logged_in = 1;
1154 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1156 * @req_size: request size in bytes
1157 * @rsp_size: response size in bytes
1159 * Returns a pointer to the @ha's ms_iocb.
1162 qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1165 ms_iocb_entry_t *ms_pkt;
1166 struct qla_hw_data *ha = vha->hw;
1167 ms_pkt = ha->ms_iocb;
1168 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
1170 ms_pkt->entry_type = MS_IOCB_TYPE;
1171 ms_pkt->entry_count = 1;
1172 SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id);
1173 ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
1174 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1175 ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1176 ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
1177 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
1178 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1180 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1181 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1182 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1184 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1185 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1186 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
1192 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1194 * @req_size: request size in bytes
1195 * @rsp_size: response size in bytes
1197 * Returns a pointer to the @ha's ms_iocb.
1200 qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1203 struct ct_entry_24xx *ct_pkt;
1204 struct qla_hw_data *ha = vha->hw;
1206 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1207 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1209 ct_pkt->entry_type = CT_IOCB_TYPE;
1210 ct_pkt->entry_count = 1;
1211 ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
1212 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1213 ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1214 ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
1215 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1216 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1218 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1219 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1220 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1222 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1223 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1224 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
1225 ct_pkt->vp_index = vha->vp_idx;
1230 static inline ms_iocb_entry_t *
1231 qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
1233 struct qla_hw_data *ha = vha->hw;
1234 ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
1235 struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1237 if (IS_FWI2_CAPABLE(ha)) {
1238 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1239 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1241 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1242 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1249 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
1250 * @ct_req: CT request buffer
1252 * @rsp_size: response size in bytes
1254 * Returns a pointer to the intitialized @ct_req.
1256 static inline struct ct_sns_req *
1257 qla2x00_prep_ct_fdmi_req(struct ct_sns_req *ct_req, uint16_t cmd,
1260 memset(ct_req, 0, sizeof(struct ct_sns_pkt));
1262 ct_req->header.revision = 0x01;
1263 ct_req->header.gs_type = 0xFA;
1264 ct_req->header.gs_subtype = 0x10;
1265 ct_req->command = cpu_to_be16(cmd);
1266 ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
1272 * qla2x00_fdmi_rhba() -
1275 * Returns 0 on success.
1278 qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
1283 ms_iocb_entry_t *ms_pkt;
1284 struct ct_sns_req *ct_req;
1285 struct ct_sns_rsp *ct_rsp;
1287 struct ct_fdmi_hba_attr *eiter;
1288 struct qla_hw_data *ha = vha->hw;
1291 /* Prepare common MS IOCB */
1292 /* Request size adjusted after CT preparation */
1293 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
1295 /* Prepare CT request */
1296 ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD,
1298 ct_rsp = &ha->ct_sns->p.rsp;
1300 /* Prepare FDMI command arguments -- attribute block, attributes. */
1301 memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE);
1302 ct_req->req.rhba.entry_count = __constant_cpu_to_be32(1);
1303 memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE);
1304 size = 2 * WWN_SIZE + 4 + 4;
1307 ct_req->req.rhba.attrs.count =
1308 __constant_cpu_to_be32(FDMI_HBA_ATTR_COUNT);
1309 entries = ct_req->req.rhba.hba_identifier;
1312 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1313 eiter->type = __constant_cpu_to_be16(FDMI_HBA_NODE_NAME);
1314 eiter->len = __constant_cpu_to_be16(4 + WWN_SIZE);
1315 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
1316 size += 4 + WWN_SIZE;
1318 ql_dbg(ql_dbg_disc, vha, 0x2025,
1319 "NodeName = %02x%02x%02x%02x%02x%02x%02x%02x.\n",
1320 eiter->a.node_name[0], eiter->a.node_name[1],
1321 eiter->a.node_name[2], eiter->a.node_name[3],
1322 eiter->a.node_name[4], eiter->a.node_name[5],
1323 eiter->a.node_name[6], eiter->a.node_name[7]);
1326 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1327 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MANUFACTURER);
1328 strcpy(eiter->a.manufacturer, "QLogic Corporation");
1329 alen = strlen(eiter->a.manufacturer);
1330 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1331 eiter->len = cpu_to_be16(4 + alen);
1334 ql_dbg(ql_dbg_disc, vha, 0x2026,
1335 "Manufacturer = %s.\n", eiter->a.manufacturer);
1337 /* Serial number. */
1338 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1339 eiter->type = __constant_cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
1340 sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;
1341 sprintf(eiter->a.serial_num, "%c%05d", 'A' + sn / 100000, sn % 100000);
1342 alen = strlen(eiter->a.serial_num);
1343 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1344 eiter->len = cpu_to_be16(4 + alen);
1347 ql_dbg(ql_dbg_disc, vha, 0x2027,
1348 "Serial no. = %s.\n", eiter->a.serial_num);
1351 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1352 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL);
1353 strcpy(eiter->a.model, ha->model_number);
1354 alen = strlen(eiter->a.model);
1355 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1356 eiter->len = cpu_to_be16(4 + alen);
1359 ql_dbg(ql_dbg_disc, vha, 0x2028,
1360 "Model Name = %s.\n", eiter->a.model);
1362 /* Model description. */
1363 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1364 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
1366 strncpy(eiter->a.model_desc, ha->model_desc, 80);
1367 alen = strlen(eiter->a.model_desc);
1368 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1369 eiter->len = cpu_to_be16(4 + alen);
1372 ql_dbg(ql_dbg_disc, vha, 0x2029,
1373 "Model Desc = %s.\n", eiter->a.model_desc);
1375 /* Hardware version. */
1376 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1377 eiter->type = __constant_cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
1378 strcpy(eiter->a.hw_version, ha->adapter_id);
1379 alen = strlen(eiter->a.hw_version);
1380 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1381 eiter->len = cpu_to_be16(4 + alen);
1384 ql_dbg(ql_dbg_disc, vha, 0x202a,
1385 "Hardware ver = %s.\n", eiter->a.hw_version);
1387 /* Driver version. */
1388 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1389 eiter->type = __constant_cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
1390 strcpy(eiter->a.driver_version, qla2x00_version_str);
1391 alen = strlen(eiter->a.driver_version);
1392 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1393 eiter->len = cpu_to_be16(4 + alen);
1396 ql_dbg(ql_dbg_disc, vha, 0x202b,
1397 "Driver ver = %s.\n", eiter->a.driver_version);
1399 /* Option ROM version. */
1400 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1401 eiter->type = __constant_cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
1402 strcpy(eiter->a.orom_version, "0.00");
1403 alen = strlen(eiter->a.orom_version);
1404 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1405 eiter->len = cpu_to_be16(4 + alen);
1408 ql_dbg(ql_dbg_disc, vha , 0x202c,
1409 "Optrom vers = %s.\n", eiter->a.orom_version);
1411 /* Firmware version */
1412 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1413 eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
1414 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version);
1415 alen = strlen(eiter->a.fw_version);
1416 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1417 eiter->len = cpu_to_be16(4 + alen);
1420 ql_dbg(ql_dbg_disc, vha, 0x202d,
1421 "Firmware vers = %s.\n", eiter->a.fw_version);
1423 /* Update MS request size. */
1424 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1426 ql_dbg(ql_dbg_disc, vha, 0x202e,
1427 "RHBA identifier = "
1428 "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n",
1429 ct_req->req.rhba.hba_identifier[0],
1430 ct_req->req.rhba.hba_identifier[1],
1431 ct_req->req.rhba.hba_identifier[2],
1432 ct_req->req.rhba.hba_identifier[3],
1433 ct_req->req.rhba.hba_identifier[4],
1434 ct_req->req.rhba.hba_identifier[5],
1435 ct_req->req.rhba.hba_identifier[6],
1436 ct_req->req.rhba.hba_identifier[7], size);
1437 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076,
1440 /* Execute MS IOCB */
1441 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1442 sizeof(ms_iocb_entry_t));
1443 if (rval != QLA_SUCCESS) {
1445 ql_dbg(ql_dbg_disc, vha, 0x2030,
1446 "RHBA issue IOCB failed (%d).\n", rval);
1447 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") !=
1449 rval = QLA_FUNCTION_FAILED;
1450 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1451 ct_rsp->header.explanation_code ==
1452 CT_EXPL_ALREADY_REGISTERED) {
1453 ql_dbg(ql_dbg_disc, vha, 0x2034,
1454 "HBA already registered.\n");
1455 rval = QLA_ALREADY_REGISTERED;
1458 ql_dbg(ql_dbg_disc, vha, 0x2035,
1459 "RHBA exiting normally.\n");
1466 * qla2x00_fdmi_dhba() -
1469 * Returns 0 on success.
1472 qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
1475 struct qla_hw_data *ha = vha->hw;
1476 ms_iocb_entry_t *ms_pkt;
1477 struct ct_sns_req *ct_req;
1478 struct ct_sns_rsp *ct_rsp;
1481 /* Prepare common MS IOCB */
1482 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE,
1485 /* Prepare CT request */
1486 ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, DHBA_CMD,
1488 ct_rsp = &ha->ct_sns->p.rsp;
1490 /* Prepare FDMI command arguments -- portname. */
1491 memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE);
1493 ql_dbg(ql_dbg_disc, vha, 0x2036,
1494 "DHBA portname = %02x%02x%02x%02x%02x%02x%02x%02x.\n",
1495 ct_req->req.dhba.port_name[0], ct_req->req.dhba.port_name[1],
1496 ct_req->req.dhba.port_name[2], ct_req->req.dhba.port_name[3],
1497 ct_req->req.dhba.port_name[4], ct_req->req.dhba.port_name[5],
1498 ct_req->req.dhba.port_name[6], ct_req->req.dhba.port_name[7]);
1500 /* Execute MS IOCB */
1501 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1502 sizeof(ms_iocb_entry_t));
1503 if (rval != QLA_SUCCESS) {
1505 ql_dbg(ql_dbg_disc, vha, 0x2037,
1506 "DHBA issue IOCB failed (%d).\n", rval);
1507 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") !=
1509 rval = QLA_FUNCTION_FAILED;
1511 ql_dbg(ql_dbg_disc, vha, 0x2038,
1512 "DHBA exiting normally.\n");
1519 * qla2x00_fdmi_rpa() -
1522 * Returns 0 on success.
1525 qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
1528 uint32_t size, max_frame_size;
1529 struct qla_hw_data *ha = vha->hw;
1530 ms_iocb_entry_t *ms_pkt;
1531 struct ct_sns_req *ct_req;
1532 struct ct_sns_rsp *ct_rsp;
1534 struct ct_fdmi_port_attr *eiter;
1535 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
1538 /* Prepare common MS IOCB */
1539 /* Request size adjusted after CT preparation */
1540 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
1542 /* Prepare CT request */
1543 ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD,
1545 ct_rsp = &ha->ct_sns->p.rsp;
1547 /* Prepare FDMI command arguments -- attribute block, attributes. */
1548 memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE);
1549 size = WWN_SIZE + 4;
1552 ct_req->req.rpa.attrs.count =
1553 __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT - 1);
1554 entries = ct_req->req.rpa.port_name;
1557 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1558 eiter->type = __constant_cpu_to_be16(FDMI_PORT_FC4_TYPES);
1559 eiter->len = __constant_cpu_to_be16(4 + 32);
1560 eiter->a.fc4_types[2] = 0x01;
1563 ql_dbg(ql_dbg_disc, vha, 0x2039,
1564 "FC4_TYPES=%02x %02x.\n",
1565 eiter->a.fc4_types[2],
1566 eiter->a.fc4_types[1]);
1568 /* Supported speed. */
1569 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1570 eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
1571 eiter->len = __constant_cpu_to_be16(4 + 4);
1572 if (IS_CNA_CAPABLE(ha))
1573 eiter->a.sup_speed = __constant_cpu_to_be32(
1574 FDMI_PORT_SPEED_10GB);
1575 else if (IS_QLA25XX(ha))
1576 eiter->a.sup_speed = __constant_cpu_to_be32(
1577 FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
1578 FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB);
1579 else if (IS_QLA24XX_TYPE(ha))
1580 eiter->a.sup_speed = __constant_cpu_to_be32(
1581 FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
1582 FDMI_PORT_SPEED_4GB);
1583 else if (IS_QLA23XX(ha))
1584 eiter->a.sup_speed =__constant_cpu_to_be32(
1585 FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB);
1587 eiter->a.sup_speed = __constant_cpu_to_be32(
1588 FDMI_PORT_SPEED_1GB);
1591 ql_dbg(ql_dbg_disc, vha, 0x203a,
1592 "Supported_Speed=%x.\n", eiter->a.sup_speed);
1594 /* Current speed. */
1595 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1596 eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
1597 eiter->len = __constant_cpu_to_be16(4 + 4);
1598 switch (ha->link_data_rate) {
1599 case PORT_SPEED_1GB:
1600 eiter->a.cur_speed =
1601 __constant_cpu_to_be32(FDMI_PORT_SPEED_1GB);
1603 case PORT_SPEED_2GB:
1604 eiter->a.cur_speed =
1605 __constant_cpu_to_be32(FDMI_PORT_SPEED_2GB);
1607 case PORT_SPEED_4GB:
1608 eiter->a.cur_speed =
1609 __constant_cpu_to_be32(FDMI_PORT_SPEED_4GB);
1611 case PORT_SPEED_8GB:
1612 eiter->a.cur_speed =
1613 __constant_cpu_to_be32(FDMI_PORT_SPEED_8GB);
1615 case PORT_SPEED_10GB:
1616 eiter->a.cur_speed =
1617 __constant_cpu_to_be32(FDMI_PORT_SPEED_10GB);
1619 case PORT_SPEED_16GB:
1620 eiter->a.cur_speed =
1621 __constant_cpu_to_be32(FDMI_PORT_SPEED_16GB);
1624 eiter->a.cur_speed =
1625 __constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
1630 ql_dbg(ql_dbg_disc, vha, 0x203b,
1631 "Current_Speed=%x.\n", eiter->a.cur_speed);
1633 /* Max frame size. */
1634 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1635 eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
1636 eiter->len = __constant_cpu_to_be16(4 + 4);
1637 max_frame_size = IS_FWI2_CAPABLE(ha) ?
1638 le16_to_cpu(icb24->frame_payload_size):
1639 le16_to_cpu(ha->init_cb->frame_payload_size);
1640 eiter->a.max_frame_size = cpu_to_be32(max_frame_size);
1643 ql_dbg(ql_dbg_disc, vha, 0x203c,
1644 "Max_Frame_Size=%x.\n", eiter->a.max_frame_size);
1646 /* OS device name. */
1647 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1648 eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
1649 strcpy(eiter->a.os_dev_name, QLA2XXX_DRIVER_NAME);
1650 alen = strlen(eiter->a.os_dev_name);
1651 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1652 eiter->len = cpu_to_be16(4 + alen);
1655 ql_dbg(ql_dbg_disc, vha, 0x204b,
1656 "OS_Device_Name=%s.\n", eiter->a.os_dev_name);
1659 if (strlen(fc_host_system_hostname(vha->host))) {
1660 ct_req->req.rpa.attrs.count =
1661 __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT);
1662 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1663 eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME);
1664 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
1665 "%s", fc_host_system_hostname(vha->host));
1666 alen = strlen(eiter->a.host_name);
1667 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1668 eiter->len = cpu_to_be16(4 + alen);
1671 ql_dbg(ql_dbg_disc, vha, 0x203d,
1672 "HostName=%s.\n", eiter->a.host_name);
1675 /* Update MS request size. */
1676 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1678 ql_dbg(ql_dbg_disc, vha, 0x203e,
1679 "RPA portname= %02x%02x%02x%02x%02X%02x%02x%02x size=%d.\n",
1680 ct_req->req.rpa.port_name[0], ct_req->req.rpa.port_name[1],
1681 ct_req->req.rpa.port_name[2], ct_req->req.rpa.port_name[3],
1682 ct_req->req.rpa.port_name[4], ct_req->req.rpa.port_name[5],
1683 ct_req->req.rpa.port_name[6], ct_req->req.rpa.port_name[7],
1685 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079,
1688 /* Execute MS IOCB */
1689 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1690 sizeof(ms_iocb_entry_t));
1691 if (rval != QLA_SUCCESS) {
1693 ql_dbg(ql_dbg_disc, vha, 0x2040,
1694 "RPA issue IOCB failed (%d).\n", rval);
1695 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") !=
1697 rval = QLA_FUNCTION_FAILED;
1699 ql_dbg(ql_dbg_disc, vha, 0x2041,
1700 "RPA exiting nornally.\n");
1707 * qla2x00_fdmi_register() -
1710 * Returns 0 on success.
1713 qla2x00_fdmi_register(scsi_qla_host_t *vha)
1716 struct qla_hw_data *ha = vha->hw;
1718 if (IS_QLA2100(ha) || IS_QLA2200(ha))
1719 return QLA_FUNCTION_FAILED;
1721 rval = qla2x00_mgmt_svr_login(vha);
1725 rval = qla2x00_fdmi_rhba(vha);
1727 if (rval != QLA_ALREADY_REGISTERED)
1730 rval = qla2x00_fdmi_dhba(vha);
1734 rval = qla2x00_fdmi_rhba(vha);
1738 rval = qla2x00_fdmi_rpa(vha);
1744 * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
1746 * @list: switch info entries to populate
1748 * Returns 0 on success.
1751 qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
1753 int rval = QLA_SUCCESS;
1755 struct qla_hw_data *ha = vha->hw;
1756 ms_iocb_entry_t *ms_pkt;
1757 struct ct_sns_req *ct_req;
1758 struct ct_sns_rsp *ct_rsp;
1760 if (!IS_IIDMA_CAPABLE(ha))
1761 return QLA_FUNCTION_FAILED;
1763 for (i = 0; i < ha->max_fibre_devices; i++) {
1765 /* Prepare common MS IOCB */
1766 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFPN_ID_REQ_SIZE,
1769 /* Prepare CT request */
1770 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD,
1772 ct_rsp = &ha->ct_sns->p.rsp;
1774 /* Prepare CT arguments -- port_id */
1775 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
1776 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
1777 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
1779 /* Execute MS IOCB */
1780 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1781 sizeof(ms_iocb_entry_t));
1782 if (rval != QLA_SUCCESS) {
1784 ql_dbg(ql_dbg_disc, vha, 0x2023,
1785 "GFPN_ID issue IOCB failed (%d).\n", rval);
1787 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
1788 "GFPN_ID") != QLA_SUCCESS) {
1789 rval = QLA_FUNCTION_FAILED;
1792 /* Save fabric portname */
1793 memcpy(list[i].fabric_port_name,
1794 ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
1797 /* Last device exit. */
1798 if (list[i].d_id.b.rsvd_1 != 0)
1805 static inline void *
1806 qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1809 struct ct_entry_24xx *ct_pkt;
1810 struct qla_hw_data *ha = vha->hw;
1811 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1812 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1814 ct_pkt->entry_type = CT_IOCB_TYPE;
1815 ct_pkt->entry_count = 1;
1816 ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
1817 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1818 ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1819 ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
1820 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1821 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1823 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1824 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1825 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1827 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1828 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1829 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
1830 ct_pkt->vp_index = vha->vp_idx;
1836 static inline struct ct_sns_req *
1837 qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd,
1840 memset(ct_req, 0, sizeof(struct ct_sns_pkt));
1842 ct_req->header.revision = 0x01;
1843 ct_req->header.gs_type = 0xFA;
1844 ct_req->header.gs_subtype = 0x01;
1845 ct_req->command = cpu_to_be16(cmd);
1846 ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
1852 * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
1854 * @list: switch info entries to populate
1856 * Returns 0 on success.
1859 qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
1863 struct qla_hw_data *ha = vha->hw;
1864 ms_iocb_entry_t *ms_pkt;
1865 struct ct_sns_req *ct_req;
1866 struct ct_sns_rsp *ct_rsp;
1868 if (!IS_IIDMA_CAPABLE(ha))
1869 return QLA_FUNCTION_FAILED;
1870 if (!ha->flags.gpsc_supported)
1871 return QLA_FUNCTION_FAILED;
1873 rval = qla2x00_mgmt_svr_login(vha);
1877 for (i = 0; i < ha->max_fibre_devices; i++) {
1879 /* Prepare common MS IOCB */
1880 ms_pkt = qla24xx_prep_ms_fm_iocb(vha, GPSC_REQ_SIZE,
1883 /* Prepare CT request */
1884 ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req,
1885 GPSC_CMD, GPSC_RSP_SIZE);
1886 ct_rsp = &ha->ct_sns->p.rsp;
1888 /* Prepare CT arguments -- port_name */
1889 memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
1892 /* Execute MS IOCB */
1893 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1894 sizeof(ms_iocb_entry_t));
1895 if (rval != QLA_SUCCESS) {
1897 ql_dbg(ql_dbg_disc, vha, 0x2059,
1898 "GPSC issue IOCB failed (%d).\n", rval);
1899 } else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
1900 "GPSC")) != QLA_SUCCESS) {
1901 /* FM command unsupported? */
1902 if (rval == QLA_INVALID_COMMAND &&
1903 (ct_rsp->header.reason_code ==
1904 CT_REASON_INVALID_COMMAND_CODE ||
1905 ct_rsp->header.reason_code ==
1906 CT_REASON_COMMAND_UNSUPPORTED)) {
1907 ql_dbg(ql_dbg_disc, vha, 0x205a,
1908 "GPSC command unsupported, disabling "
1910 ha->flags.gpsc_supported = 0;
1911 rval = QLA_FUNCTION_FAILED;
1914 rval = QLA_FUNCTION_FAILED;
1916 /* Save port-speed */
1917 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
1919 list[i].fp_speed = PORT_SPEED_1GB;
1922 list[i].fp_speed = PORT_SPEED_2GB;
1925 list[i].fp_speed = PORT_SPEED_4GB;
1928 list[i].fp_speed = PORT_SPEED_10GB;
1931 list[i].fp_speed = PORT_SPEED_8GB;
1935 ql_dbg(ql_dbg_disc, vha, 0x205b,
1936 "GPSC ext entry - fpn "
1937 "%02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x "
1939 list[i].fabric_port_name[0],
1940 list[i].fabric_port_name[1],
1941 list[i].fabric_port_name[2],
1942 list[i].fabric_port_name[3],
1943 list[i].fabric_port_name[4],
1944 list[i].fabric_port_name[5],
1945 list[i].fabric_port_name[6],
1946 list[i].fabric_port_name[7],
1947 be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
1948 be16_to_cpu(ct_rsp->rsp.gpsc.speed));
1951 /* Last device exit. */
1952 if (list[i].d_id.b.rsvd_1 != 0)
1960 * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
1963 * @list: switch info entries to populate
1967 qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
1972 ms_iocb_entry_t *ms_pkt;
1973 struct ct_sns_req *ct_req;
1974 struct ct_sns_rsp *ct_rsp;
1975 struct qla_hw_data *ha = vha->hw;
1976 uint8_t fcp_scsi_features = 0;
1978 for (i = 0; i < ha->max_fibre_devices; i++) {
1979 /* Set default FC4 Type as UNKNOWN so the default is to
1980 * Process this port */
1981 list[i].fc4_type = FC4_TYPE_UNKNOWN;
1983 /* Do not attempt GFF_ID if we are not FWI_2 capable */
1984 if (!IS_FWI2_CAPABLE(ha))
1987 /* Prepare common MS IOCB */
1988 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFF_ID_REQ_SIZE,
1991 /* Prepare CT request */
1992 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFF_ID_CMD,
1994 ct_rsp = &ha->ct_sns->p.rsp;
1996 /* Prepare CT arguments -- port_id */
1997 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
1998 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
1999 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
2001 /* Execute MS IOCB */
2002 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2003 sizeof(ms_iocb_entry_t));
2005 if (rval != QLA_SUCCESS) {
2006 ql_dbg(ql_dbg_disc, vha, 0x205c,
2007 "GFF_ID issue IOCB failed (%d).\n", rval);
2008 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
2009 "GFF_ID") != QLA_SUCCESS) {
2010 ql_dbg(ql_dbg_disc, vha, 0x205d,
2011 "GFF_ID IOCB status had a failure status code.\n");
2014 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
2015 fcp_scsi_features &= 0x0f;
2017 if (fcp_scsi_features)
2018 list[i].fc4_type = FC4_TYPE_FCP_SCSI;
2020 list[i].fc4_type = FC4_TYPE_OTHER;
2023 /* Last device exit. */
2024 if (list[i].d_id.b.rsvd_1 != 0)