2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2011 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,
1134 0xfa, mb
, BIT_1
|BIT_0
);
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)