2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2014 QLogic Corporation
5 * See LICENSE.qla2xxx for copyright and licensing details.
8 #include "qla_target.h"
9 #include <linux/utsname.h>
11 static int qla2x00_sns_ga_nxt(scsi_qla_host_t
*, fc_port_t
*);
12 static int qla2x00_sns_gid_pt(scsi_qla_host_t
*, sw_info_t
*);
13 static int qla2x00_sns_gpn_id(scsi_qla_host_t
*, sw_info_t
*);
14 static int qla2x00_sns_gnn_id(scsi_qla_host_t
*, sw_info_t
*);
15 static int qla2x00_sns_rft_id(scsi_qla_host_t
*);
16 static int qla2x00_sns_rnn_id(scsi_qla_host_t
*);
19 * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
21 * @req_size: request size in bytes
22 * @rsp_size: response size in bytes
24 * Returns a pointer to the @ha's ms_iocb.
27 qla2x00_prep_ms_iocb(scsi_qla_host_t
*vha
, struct ct_arg
*arg
)
29 struct qla_hw_data
*ha
= vha
->hw
;
30 ms_iocb_entry_t
*ms_pkt
;
32 ms_pkt
= (ms_iocb_entry_t
*)arg
->iocb
;
33 memset(ms_pkt
, 0, sizeof(ms_iocb_entry_t
));
35 ms_pkt
->entry_type
= MS_IOCB_TYPE
;
36 ms_pkt
->entry_count
= 1;
37 SET_TARGET_ID(ha
, ms_pkt
->loop_id
, SIMPLE_NAME_SERVER
);
38 ms_pkt
->control_flags
= cpu_to_le16(CF_READ
| CF_HEAD_TAG
);
39 ms_pkt
->timeout
= cpu_to_le16(ha
->r_a_tov
/ 10 * 2);
40 ms_pkt
->cmd_dsd_count
= cpu_to_le16(1);
41 ms_pkt
->total_dsd_count
= cpu_to_le16(2);
42 ms_pkt
->rsp_bytecount
= cpu_to_le32(arg
->rsp_size
);
43 ms_pkt
->req_bytecount
= cpu_to_le32(arg
->req_size
);
45 ms_pkt
->dseg_req_address
[0] = cpu_to_le32(LSD(arg
->req_dma
));
46 ms_pkt
->dseg_req_address
[1] = cpu_to_le32(MSD(arg
->req_dma
));
47 ms_pkt
->dseg_req_length
= ms_pkt
->req_bytecount
;
49 ms_pkt
->dseg_rsp_address
[0] = cpu_to_le32(LSD(arg
->rsp_dma
));
50 ms_pkt
->dseg_rsp_address
[1] = cpu_to_le32(MSD(arg
->rsp_dma
));
51 ms_pkt
->dseg_rsp_length
= ms_pkt
->rsp_bytecount
;
53 vha
->qla_stats
.control_requests
++;
59 * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
61 * @req_size: request size in bytes
62 * @rsp_size: response size in bytes
64 * Returns a pointer to the @ha's ms_iocb.
67 qla24xx_prep_ms_iocb(scsi_qla_host_t
*vha
, struct ct_arg
*arg
)
69 struct qla_hw_data
*ha
= vha
->hw
;
70 struct ct_entry_24xx
*ct_pkt
;
72 ct_pkt
= (struct ct_entry_24xx
*)arg
->iocb
;
73 memset(ct_pkt
, 0, sizeof(struct ct_entry_24xx
));
75 ct_pkt
->entry_type
= CT_IOCB_TYPE
;
76 ct_pkt
->entry_count
= 1;
77 ct_pkt
->nport_handle
= cpu_to_le16(arg
->nport_handle
);
78 ct_pkt
->timeout
= cpu_to_le16(ha
->r_a_tov
/ 10 * 2);
79 ct_pkt
->cmd_dsd_count
= cpu_to_le16(1);
80 ct_pkt
->rsp_dsd_count
= cpu_to_le16(1);
81 ct_pkt
->rsp_byte_count
= cpu_to_le32(arg
->rsp_size
);
82 ct_pkt
->cmd_byte_count
= cpu_to_le32(arg
->req_size
);
84 ct_pkt
->dseg_0_address
[0] = cpu_to_le32(LSD(arg
->req_dma
));
85 ct_pkt
->dseg_0_address
[1] = cpu_to_le32(MSD(arg
->req_dma
));
86 ct_pkt
->dseg_0_len
= ct_pkt
->cmd_byte_count
;
88 ct_pkt
->dseg_1_address
[0] = cpu_to_le32(LSD(arg
->rsp_dma
));
89 ct_pkt
->dseg_1_address
[1] = cpu_to_le32(MSD(arg
->rsp_dma
));
90 ct_pkt
->dseg_1_len
= ct_pkt
->rsp_byte_count
;
91 ct_pkt
->vp_index
= vha
->vp_idx
;
93 vha
->qla_stats
.control_requests
++;
99 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
100 * @ct_req: CT request buffer
102 * @rsp_size: response size in bytes
104 * Returns a pointer to the intitialized @ct_req.
106 static inline struct ct_sns_req
*
107 qla2x00_prep_ct_req(struct ct_sns_pkt
*p
, uint16_t cmd
, uint16_t rsp_size
)
109 memset(p
, 0, sizeof(struct ct_sns_pkt
));
111 p
->p
.req
.header
.revision
= 0x01;
112 p
->p
.req
.header
.gs_type
= 0xFC;
113 p
->p
.req
.header
.gs_subtype
= 0x02;
114 p
->p
.req
.command
= cpu_to_be16(cmd
);
115 p
->p
.req
.max_rsp_size
= cpu_to_be16((rsp_size
- 16) / 4);
121 qla2x00_chk_ms_status(scsi_qla_host_t
*vha
, ms_iocb_entry_t
*ms_pkt
,
122 struct ct_sns_rsp
*ct_rsp
, const char *routine
)
125 uint16_t comp_status
;
126 struct qla_hw_data
*ha
= vha
->hw
;
127 bool lid_is_sns
= false;
129 rval
= QLA_FUNCTION_FAILED
;
130 if (ms_pkt
->entry_status
!= 0) {
131 ql_dbg(ql_dbg_disc
, vha
, 0x2031,
132 "%s failed, error status (%x) on port_id: %02x%02x%02x.\n",
133 routine
, ms_pkt
->entry_status
, vha
->d_id
.b
.domain
,
134 vha
->d_id
.b
.area
, vha
->d_id
.b
.al_pa
);
136 if (IS_FWI2_CAPABLE(ha
))
137 comp_status
= le16_to_cpu(
138 ((struct ct_entry_24xx
*)ms_pkt
)->comp_status
);
140 comp_status
= le16_to_cpu(ms_pkt
->status
);
141 switch (comp_status
) {
143 case CS_DATA_UNDERRUN
:
144 case CS_DATA_OVERRUN
: /* Overrun? */
145 if (ct_rsp
->header
.response
!=
146 cpu_to_be16(CT_ACCEPT_RESPONSE
)) {
147 ql_dbg(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x2077,
148 "%s failed rejected request on port_id: %02x%02x%02x Completion status 0x%x, response 0x%x\n",
149 routine
, vha
->d_id
.b
.domain
,
150 vha
->d_id
.b
.area
, vha
->d_id
.b
.al_pa
,
151 comp_status
, ct_rsp
->header
.response
);
152 ql_dump_buffer(ql_dbg_disc
+ ql_dbg_buffer
, vha
,
153 0x2078, (uint8_t *)&ct_rsp
->header
,
154 sizeof(struct ct_rsp_hdr
));
155 rval
= QLA_INVALID_COMMAND
;
159 case CS_PORT_LOGGED_OUT
:
160 if (IS_FWI2_CAPABLE(ha
)) {
161 if (le16_to_cpu(ms_pkt
->loop_id
.extended
) ==
165 if (le16_to_cpu(ms_pkt
->loop_id
.extended
) ==
170 ql_dbg(ql_dbg_async
, vha
, 0x502b,
171 "%s failed, Name server has logged out",
173 rval
= QLA_NOT_LOGGED_IN
;
174 set_bit(LOOP_RESYNC_NEEDED
, &vha
->dpc_flags
);
175 set_bit(LOCAL_LOOP_UPDATE
, &vha
->dpc_flags
);
179 ql_dbg(ql_dbg_disc
, vha
, 0x2033,
180 "%s failed, completion status (%x) on port_id: "
181 "%02x%02x%02x.\n", routine
, comp_status
,
182 vha
->d_id
.b
.domain
, vha
->d_id
.b
.area
,
191 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
193 * @fcport: fcport entry to updated
195 * Returns 0 on success.
198 qla2x00_ga_nxt(scsi_qla_host_t
*vha
, fc_port_t
*fcport
)
202 ms_iocb_entry_t
*ms_pkt
;
203 struct ct_sns_req
*ct_req
;
204 struct ct_sns_rsp
*ct_rsp
;
205 struct qla_hw_data
*ha
= vha
->hw
;
208 if (IS_QLA2100(ha
) || IS_QLA2200(ha
))
209 return qla2x00_sns_ga_nxt(vha
, fcport
);
211 arg
.iocb
= ha
->ms_iocb
;
212 arg
.req_dma
= ha
->ct_sns_dma
;
213 arg
.rsp_dma
= ha
->ct_sns_dma
;
214 arg
.req_size
= GA_NXT_REQ_SIZE
;
215 arg
.rsp_size
= GA_NXT_RSP_SIZE
;
216 arg
.nport_handle
= NPH_SNS
;
219 /* Prepare common MS IOCB */
220 ms_pkt
= ha
->isp_ops
->prep_ms_iocb(vha
, &arg
);
222 /* Prepare CT request */
223 ct_req
= qla2x00_prep_ct_req(ha
->ct_sns
, GA_NXT_CMD
,
225 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
227 /* Prepare CT arguments -- port_id */
228 ct_req
->req
.port_id
.port_id
[0] = fcport
->d_id
.b
.domain
;
229 ct_req
->req
.port_id
.port_id
[1] = fcport
->d_id
.b
.area
;
230 ct_req
->req
.port_id
.port_id
[2] = fcport
->d_id
.b
.al_pa
;
232 /* Execute MS IOCB */
233 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
234 sizeof(ms_iocb_entry_t
));
235 if (rval
!= QLA_SUCCESS
) {
237 ql_dbg(ql_dbg_disc
, vha
, 0x2062,
238 "GA_NXT issue IOCB failed (%d).\n", rval
);
239 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
, "GA_NXT") !=
241 rval
= QLA_FUNCTION_FAILED
;
243 /* Populate fc_port_t entry. */
244 fcport
->d_id
.b
.domain
= ct_rsp
->rsp
.ga_nxt
.port_id
[0];
245 fcport
->d_id
.b
.area
= ct_rsp
->rsp
.ga_nxt
.port_id
[1];
246 fcport
->d_id
.b
.al_pa
= ct_rsp
->rsp
.ga_nxt
.port_id
[2];
248 memcpy(fcport
->node_name
, ct_rsp
->rsp
.ga_nxt
.node_name
,
250 memcpy(fcport
->port_name
, ct_rsp
->rsp
.ga_nxt
.port_name
,
253 fcport
->fc4_type
= (ct_rsp
->rsp
.ga_nxt
.fc4_types
[2] & BIT_0
) ?
254 FC4_TYPE_FCP_SCSI
: FC4_TYPE_OTHER
;
256 if (ct_rsp
->rsp
.ga_nxt
.port_type
!= NS_N_PORT_TYPE
&&
257 ct_rsp
->rsp
.ga_nxt
.port_type
!= NS_NL_PORT_TYPE
)
258 fcport
->d_id
.b
.domain
= 0xf0;
260 ql_dbg(ql_dbg_disc
, vha
, 0x2063,
261 "GA_NXT entry - nn %8phN pn %8phN "
262 "port_id=%02x%02x%02x.\n",
263 fcport
->node_name
, fcport
->port_name
,
264 fcport
->d_id
.b
.domain
, fcport
->d_id
.b
.area
,
265 fcport
->d_id
.b
.al_pa
);
272 qla2x00_gid_pt_rsp_size(scsi_qla_host_t
*vha
)
274 return vha
->hw
->max_fibre_devices
* 4 + 16;
278 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
280 * @list: switch info entries to populate
282 * NOTE: Non-Nx_Ports are not requested.
284 * Returns 0 on success.
287 qla2x00_gid_pt(scsi_qla_host_t
*vha
, sw_info_t
*list
)
292 ms_iocb_entry_t
*ms_pkt
;
293 struct ct_sns_req
*ct_req
;
294 struct ct_sns_rsp
*ct_rsp
;
296 struct ct_sns_gid_pt_data
*gid_data
;
297 struct qla_hw_data
*ha
= vha
->hw
;
298 uint16_t gid_pt_rsp_size
;
301 if (IS_QLA2100(ha
) || IS_QLA2200(ha
))
302 return qla2x00_sns_gid_pt(vha
, list
);
305 gid_pt_rsp_size
= qla2x00_gid_pt_rsp_size(vha
);
307 arg
.iocb
= ha
->ms_iocb
;
308 arg
.req_dma
= ha
->ct_sns_dma
;
309 arg
.rsp_dma
= ha
->ct_sns_dma
;
310 arg
.req_size
= GID_PT_REQ_SIZE
;
311 arg
.rsp_size
= gid_pt_rsp_size
;
312 arg
.nport_handle
= NPH_SNS
;
315 /* Prepare common MS IOCB */
316 ms_pkt
= ha
->isp_ops
->prep_ms_iocb(vha
, &arg
);
318 /* Prepare CT request */
319 ct_req
= qla2x00_prep_ct_req(ha
->ct_sns
, GID_PT_CMD
, gid_pt_rsp_size
);
320 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
322 /* Prepare CT arguments -- port_type */
323 ct_req
->req
.gid_pt
.port_type
= NS_NX_PORT_TYPE
;
325 /* Execute MS IOCB */
326 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
327 sizeof(ms_iocb_entry_t
));
328 if (rval
!= QLA_SUCCESS
) {
330 ql_dbg(ql_dbg_disc
, vha
, 0x2055,
331 "GID_PT issue IOCB failed (%d).\n", rval
);
332 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
, "GID_PT") !=
334 rval
= QLA_FUNCTION_FAILED
;
336 /* Set port IDs in switch info list. */
337 for (i
= 0; i
< ha
->max_fibre_devices
; i
++) {
338 gid_data
= &ct_rsp
->rsp
.gid_pt
.entries
[i
];
339 list
[i
].d_id
.b
.domain
= gid_data
->port_id
[0];
340 list
[i
].d_id
.b
.area
= gid_data
->port_id
[1];
341 list
[i
].d_id
.b
.al_pa
= gid_data
->port_id
[2];
342 memset(list
[i
].fabric_port_name
, 0, WWN_SIZE
);
343 list
[i
].fp_speed
= PORT_SPEED_UNKNOWN
;
346 if (gid_data
->control_byte
& BIT_7
) {
347 list
[i
].d_id
.b
.rsvd_1
= gid_data
->control_byte
;
353 * If we've used all available slots, then the switch is
354 * reporting back more devices than we can handle with this
355 * single call. Return a failed status, and let GA_NXT handle
358 if (i
== ha
->max_fibre_devices
)
359 rval
= QLA_FUNCTION_FAILED
;
366 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
368 * @list: switch info entries to populate
370 * Returns 0 on success.
373 qla2x00_gpn_id(scsi_qla_host_t
*vha
, sw_info_t
*list
)
375 int rval
= QLA_SUCCESS
;
378 ms_iocb_entry_t
*ms_pkt
;
379 struct ct_sns_req
*ct_req
;
380 struct ct_sns_rsp
*ct_rsp
;
381 struct qla_hw_data
*ha
= vha
->hw
;
384 if (IS_QLA2100(ha
) || IS_QLA2200(ha
))
385 return qla2x00_sns_gpn_id(vha
, list
);
387 arg
.iocb
= ha
->ms_iocb
;
388 arg
.req_dma
= ha
->ct_sns_dma
;
389 arg
.rsp_dma
= ha
->ct_sns_dma
;
390 arg
.req_size
= GPN_ID_REQ_SIZE
;
391 arg
.rsp_size
= GPN_ID_RSP_SIZE
;
392 arg
.nport_handle
= NPH_SNS
;
394 for (i
= 0; i
< ha
->max_fibre_devices
; i
++) {
396 /* Prepare common MS IOCB */
397 ms_pkt
= ha
->isp_ops
->prep_ms_iocb(vha
, &arg
);
399 /* Prepare CT request */
400 ct_req
= qla2x00_prep_ct_req(ha
->ct_sns
, GPN_ID_CMD
,
402 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
404 /* Prepare CT arguments -- port_id */
405 ct_req
->req
.port_id
.port_id
[0] = list
[i
].d_id
.b
.domain
;
406 ct_req
->req
.port_id
.port_id
[1] = list
[i
].d_id
.b
.area
;
407 ct_req
->req
.port_id
.port_id
[2] = list
[i
].d_id
.b
.al_pa
;
409 /* Execute MS IOCB */
410 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
411 sizeof(ms_iocb_entry_t
));
412 if (rval
!= QLA_SUCCESS
) {
414 ql_dbg(ql_dbg_disc
, vha
, 0x2056,
415 "GPN_ID issue IOCB failed (%d).\n", rval
);
417 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
,
418 "GPN_ID") != QLA_SUCCESS
) {
419 rval
= QLA_FUNCTION_FAILED
;
423 memcpy(list
[i
].port_name
,
424 ct_rsp
->rsp
.gpn_id
.port_name
, WWN_SIZE
);
427 /* Last device exit. */
428 if (list
[i
].d_id
.b
.rsvd_1
!= 0)
436 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
438 * @list: switch info entries to populate
440 * Returns 0 on success.
443 qla2x00_gnn_id(scsi_qla_host_t
*vha
, sw_info_t
*list
)
445 int rval
= QLA_SUCCESS
;
447 struct qla_hw_data
*ha
= vha
->hw
;
448 ms_iocb_entry_t
*ms_pkt
;
449 struct ct_sns_req
*ct_req
;
450 struct ct_sns_rsp
*ct_rsp
;
453 if (IS_QLA2100(ha
) || IS_QLA2200(ha
))
454 return qla2x00_sns_gnn_id(vha
, list
);
456 arg
.iocb
= ha
->ms_iocb
;
457 arg
.req_dma
= ha
->ct_sns_dma
;
458 arg
.rsp_dma
= ha
->ct_sns_dma
;
459 arg
.req_size
= GNN_ID_REQ_SIZE
;
460 arg
.rsp_size
= GNN_ID_RSP_SIZE
;
461 arg
.nport_handle
= NPH_SNS
;
463 for (i
= 0; i
< ha
->max_fibre_devices
; i
++) {
465 /* Prepare common MS IOCB */
466 ms_pkt
= ha
->isp_ops
->prep_ms_iocb(vha
, &arg
);
468 /* Prepare CT request */
469 ct_req
= qla2x00_prep_ct_req(ha
->ct_sns
, GNN_ID_CMD
,
471 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
473 /* Prepare CT arguments -- port_id */
474 ct_req
->req
.port_id
.port_id
[0] = list
[i
].d_id
.b
.domain
;
475 ct_req
->req
.port_id
.port_id
[1] = list
[i
].d_id
.b
.area
;
476 ct_req
->req
.port_id
.port_id
[2] = list
[i
].d_id
.b
.al_pa
;
478 /* Execute MS IOCB */
479 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
480 sizeof(ms_iocb_entry_t
));
481 if (rval
!= QLA_SUCCESS
) {
483 ql_dbg(ql_dbg_disc
, vha
, 0x2057,
484 "GNN_ID issue IOCB failed (%d).\n", rval
);
486 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
,
487 "GNN_ID") != QLA_SUCCESS
) {
488 rval
= QLA_FUNCTION_FAILED
;
492 memcpy(list
[i
].node_name
,
493 ct_rsp
->rsp
.gnn_id
.node_name
, WWN_SIZE
);
495 ql_dbg(ql_dbg_disc
, vha
, 0x2058,
496 "GID_PT entry - nn %8phN pn %8phN "
497 "portid=%02x%02x%02x.\n",
498 list
[i
].node_name
, list
[i
].port_name
,
499 list
[i
].d_id
.b
.domain
, list
[i
].d_id
.b
.area
,
500 list
[i
].d_id
.b
.al_pa
);
503 /* Last device exit. */
504 if (list
[i
].d_id
.b
.rsvd_1
!= 0)
512 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
515 * Returns 0 on success.
518 qla2x00_rft_id(scsi_qla_host_t
*vha
)
521 struct qla_hw_data
*ha
= vha
->hw
;
522 ms_iocb_entry_t
*ms_pkt
;
523 struct ct_sns_req
*ct_req
;
524 struct ct_sns_rsp
*ct_rsp
;
527 if (IS_QLA2100(ha
) || IS_QLA2200(ha
))
528 return qla2x00_sns_rft_id(vha
);
530 arg
.iocb
= ha
->ms_iocb
;
531 arg
.req_dma
= ha
->ct_sns_dma
;
532 arg
.rsp_dma
= ha
->ct_sns_dma
;
533 arg
.req_size
= RFT_ID_REQ_SIZE
;
534 arg
.rsp_size
= RFT_ID_RSP_SIZE
;
535 arg
.nport_handle
= NPH_SNS
;
538 /* Prepare common MS IOCB */
539 ms_pkt
= ha
->isp_ops
->prep_ms_iocb(vha
, &arg
);
541 /* Prepare CT request */
542 ct_req
= qla2x00_prep_ct_req(ha
->ct_sns
, RFT_ID_CMD
,
544 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
546 /* Prepare CT arguments -- port_id, FC-4 types */
547 ct_req
->req
.rft_id
.port_id
[0] = vha
->d_id
.b
.domain
;
548 ct_req
->req
.rft_id
.port_id
[1] = vha
->d_id
.b
.area
;
549 ct_req
->req
.rft_id
.port_id
[2] = vha
->d_id
.b
.al_pa
;
551 ct_req
->req
.rft_id
.fc4_types
[2] = 0x01; /* FCP-3 */
553 if (vha
->flags
.nvme_enabled
)
554 ct_req
->req
.rft_id
.fc4_types
[6] = 1; /* NVMe type 28h */
555 /* Execute MS IOCB */
556 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
557 sizeof(ms_iocb_entry_t
));
558 if (rval
!= QLA_SUCCESS
) {
560 ql_dbg(ql_dbg_disc
, vha
, 0x2043,
561 "RFT_ID issue IOCB failed (%d).\n", rval
);
562 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
, "RFT_ID") !=
564 rval
= QLA_FUNCTION_FAILED
;
566 ql_dbg(ql_dbg_disc
, vha
, 0x2044,
567 "RFT_ID exiting normally.\n");
574 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
577 * Returns 0 on success.
580 qla2x00_rff_id(scsi_qla_host_t
*vha
, u8 type
)
583 struct qla_hw_data
*ha
= vha
->hw
;
584 ms_iocb_entry_t
*ms_pkt
;
585 struct ct_sns_req
*ct_req
;
586 struct ct_sns_rsp
*ct_rsp
;
589 if (IS_QLA2100(ha
) || IS_QLA2200(ha
)) {
590 ql_dbg(ql_dbg_disc
, vha
, 0x2046,
591 "RFF_ID call not supported on ISP2100/ISP2200.\n");
592 return (QLA_SUCCESS
);
595 arg
.iocb
= ha
->ms_iocb
;
596 arg
.req_dma
= ha
->ct_sns_dma
;
597 arg
.rsp_dma
= ha
->ct_sns_dma
;
598 arg
.req_size
= RFF_ID_REQ_SIZE
;
599 arg
.rsp_size
= RFF_ID_RSP_SIZE
;
600 arg
.nport_handle
= NPH_SNS
;
603 /* Prepare common MS IOCB */
604 ms_pkt
= ha
->isp_ops
->prep_ms_iocb(vha
, &arg
);
606 /* Prepare CT request */
607 ct_req
= qla2x00_prep_ct_req(ha
->ct_sns
, RFF_ID_CMD
,
609 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
611 /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
612 ct_req
->req
.rff_id
.port_id
[0] = vha
->d_id
.b
.domain
;
613 ct_req
->req
.rff_id
.port_id
[1] = vha
->d_id
.b
.area
;
614 ct_req
->req
.rff_id
.port_id
[2] = vha
->d_id
.b
.al_pa
;
616 qlt_rff_id(vha
, ct_req
);
618 ct_req
->req
.rff_id
.fc4_type
= type
; /* SCSI - FCP */
620 /* Execute MS IOCB */
621 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
622 sizeof(ms_iocb_entry_t
));
623 if (rval
!= QLA_SUCCESS
) {
625 ql_dbg(ql_dbg_disc
, vha
, 0x2047,
626 "RFF_ID issue IOCB failed (%d).\n", rval
);
627 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
, "RFF_ID") !=
629 rval
= QLA_FUNCTION_FAILED
;
631 ql_dbg(ql_dbg_disc
, vha
, 0x2048,
632 "RFF_ID exiting normally.\n");
639 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
642 * Returns 0 on success.
645 qla2x00_rnn_id(scsi_qla_host_t
*vha
)
648 struct qla_hw_data
*ha
= vha
->hw
;
649 ms_iocb_entry_t
*ms_pkt
;
650 struct ct_sns_req
*ct_req
;
651 struct ct_sns_rsp
*ct_rsp
;
654 if (IS_QLA2100(ha
) || IS_QLA2200(ha
))
655 return qla2x00_sns_rnn_id(vha
);
657 arg
.iocb
= ha
->ms_iocb
;
658 arg
.req_dma
= ha
->ct_sns_dma
;
659 arg
.rsp_dma
= ha
->ct_sns_dma
;
660 arg
.req_size
= RNN_ID_REQ_SIZE
;
661 arg
.rsp_size
= RNN_ID_RSP_SIZE
;
662 arg
.nport_handle
= NPH_SNS
;
665 /* Prepare common MS IOCB */
666 ms_pkt
= ha
->isp_ops
->prep_ms_iocb(vha
, &arg
);
668 /* Prepare CT request */
669 ct_req
= qla2x00_prep_ct_req(ha
->ct_sns
, RNN_ID_CMD
, RNN_ID_RSP_SIZE
);
670 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
672 /* Prepare CT arguments -- port_id, node_name */
673 ct_req
->req
.rnn_id
.port_id
[0] = vha
->d_id
.b
.domain
;
674 ct_req
->req
.rnn_id
.port_id
[1] = vha
->d_id
.b
.area
;
675 ct_req
->req
.rnn_id
.port_id
[2] = vha
->d_id
.b
.al_pa
;
677 memcpy(ct_req
->req
.rnn_id
.node_name
, vha
->node_name
, WWN_SIZE
);
679 /* Execute MS IOCB */
680 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
681 sizeof(ms_iocb_entry_t
));
682 if (rval
!= QLA_SUCCESS
) {
684 ql_dbg(ql_dbg_disc
, vha
, 0x204d,
685 "RNN_ID issue IOCB failed (%d).\n", rval
);
686 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
, "RNN_ID") !=
688 rval
= QLA_FUNCTION_FAILED
;
690 ql_dbg(ql_dbg_disc
, vha
, 0x204e,
691 "RNN_ID exiting normally.\n");
698 qla2x00_get_sym_node_name(scsi_qla_host_t
*vha
, uint8_t *snn
, size_t size
)
700 struct qla_hw_data
*ha
= vha
->hw
;
703 snprintf(snn
, size
, "%s FW:v%s DVR:v%s", ha
->model_number
,
704 ha
->mr
.fw_version
, qla2x00_version_str
);
707 "%s FW:v%d.%02d.%02d DVR:v%s", ha
->model_number
,
708 ha
->fw_major_version
, ha
->fw_minor_version
,
709 ha
->fw_subminor_version
, qla2x00_version_str
);
713 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
716 * Returns 0 on success.
719 qla2x00_rsnn_nn(scsi_qla_host_t
*vha
)
722 struct qla_hw_data
*ha
= vha
->hw
;
723 ms_iocb_entry_t
*ms_pkt
;
724 struct ct_sns_req
*ct_req
;
725 struct ct_sns_rsp
*ct_rsp
;
728 if (IS_QLA2100(ha
) || IS_QLA2200(ha
)) {
729 ql_dbg(ql_dbg_disc
, vha
, 0x2050,
730 "RSNN_ID call unsupported on ISP2100/ISP2200.\n");
731 return (QLA_SUCCESS
);
734 arg
.iocb
= ha
->ms_iocb
;
735 arg
.req_dma
= ha
->ct_sns_dma
;
736 arg
.rsp_dma
= ha
->ct_sns_dma
;
738 arg
.rsp_size
= RSNN_NN_RSP_SIZE
;
739 arg
.nport_handle
= NPH_SNS
;
742 /* Prepare common MS IOCB */
743 /* Request size adjusted after CT preparation */
744 ms_pkt
= ha
->isp_ops
->prep_ms_iocb(vha
, &arg
);
746 /* Prepare CT request */
747 ct_req
= qla2x00_prep_ct_req(ha
->ct_sns
, RSNN_NN_CMD
,
749 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
751 /* Prepare CT arguments -- node_name, symbolic node_name, size */
752 memcpy(ct_req
->req
.rsnn_nn
.node_name
, vha
->node_name
, WWN_SIZE
);
754 /* Prepare the Symbolic Node Name */
755 qla2x00_get_sym_node_name(vha
, ct_req
->req
.rsnn_nn
.sym_node_name
,
756 sizeof(ct_req
->req
.rsnn_nn
.sym_node_name
));
758 /* Calculate SNN length */
759 ct_req
->req
.rsnn_nn
.name_len
=
760 (uint8_t)strlen(ct_req
->req
.rsnn_nn
.sym_node_name
);
762 /* Update MS IOCB request */
763 ms_pkt
->req_bytecount
=
764 cpu_to_le32(24 + 1 + ct_req
->req
.rsnn_nn
.name_len
);
765 ms_pkt
->dseg_req_length
= ms_pkt
->req_bytecount
;
767 /* Execute MS IOCB */
768 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
769 sizeof(ms_iocb_entry_t
));
770 if (rval
!= QLA_SUCCESS
) {
772 ql_dbg(ql_dbg_disc
, vha
, 0x2051,
773 "RSNN_NN issue IOCB failed (%d).\n", rval
);
774 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
, "RSNN_NN") !=
776 rval
= QLA_FUNCTION_FAILED
;
778 ql_dbg(ql_dbg_disc
, vha
, 0x2052,
779 "RSNN_NN exiting normally.\n");
786 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
789 * @scmd_len: Subcommand length
790 * @data_size: response size in bytes
792 * Returns a pointer to the @ha's sns_cmd.
794 static inline struct sns_cmd_pkt
*
795 qla2x00_prep_sns_cmd(scsi_qla_host_t
*vha
, uint16_t cmd
, uint16_t scmd_len
,
799 struct sns_cmd_pkt
*sns_cmd
;
800 struct qla_hw_data
*ha
= vha
->hw
;
802 sns_cmd
= ha
->sns_cmd
;
803 memset(sns_cmd
, 0, sizeof(struct sns_cmd_pkt
));
804 wc
= data_size
/ 2; /* Size in 16bit words. */
805 sns_cmd
->p
.cmd
.buffer_length
= cpu_to_le16(wc
);
806 sns_cmd
->p
.cmd
.buffer_address
[0] = cpu_to_le32(LSD(ha
->sns_cmd_dma
));
807 sns_cmd
->p
.cmd
.buffer_address
[1] = cpu_to_le32(MSD(ha
->sns_cmd_dma
));
808 sns_cmd
->p
.cmd
.subcommand_length
= cpu_to_le16(scmd_len
);
809 sns_cmd
->p
.cmd
.subcommand
= cpu_to_le16(cmd
);
810 wc
= (data_size
- 16) / 4; /* Size in 32bit words. */
811 sns_cmd
->p
.cmd
.size
= cpu_to_le16(wc
);
813 vha
->qla_stats
.control_requests
++;
819 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
821 * @fcport: fcport entry to updated
823 * This command uses the old Exectute SNS Command mailbox routine.
825 * Returns 0 on success.
828 qla2x00_sns_ga_nxt(scsi_qla_host_t
*vha
, fc_port_t
*fcport
)
830 int rval
= QLA_SUCCESS
;
831 struct qla_hw_data
*ha
= vha
->hw
;
832 struct sns_cmd_pkt
*sns_cmd
;
835 /* Prepare SNS command request. */
836 sns_cmd
= qla2x00_prep_sns_cmd(vha
, GA_NXT_CMD
, GA_NXT_SNS_SCMD_LEN
,
837 GA_NXT_SNS_DATA_SIZE
);
839 /* Prepare SNS command arguments -- port_id. */
840 sns_cmd
->p
.cmd
.param
[0] = fcport
->d_id
.b
.al_pa
;
841 sns_cmd
->p
.cmd
.param
[1] = fcport
->d_id
.b
.area
;
842 sns_cmd
->p
.cmd
.param
[2] = fcport
->d_id
.b
.domain
;
844 /* Execute SNS command. */
845 rval
= qla2x00_send_sns(vha
, ha
->sns_cmd_dma
, GA_NXT_SNS_CMD_SIZE
/ 2,
846 sizeof(struct sns_cmd_pkt
));
847 if (rval
!= QLA_SUCCESS
) {
849 ql_dbg(ql_dbg_disc
, vha
, 0x205f,
850 "GA_NXT Send SNS failed (%d).\n", rval
);
851 } else if (sns_cmd
->p
.gan_data
[8] != 0x80 ||
852 sns_cmd
->p
.gan_data
[9] != 0x02) {
853 ql_dbg(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x2084,
854 "GA_NXT failed, rejected request ga_nxt_rsp:\n");
855 ql_dump_buffer(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x2074,
856 sns_cmd
->p
.gan_data
, 16);
857 rval
= QLA_FUNCTION_FAILED
;
859 /* Populate fc_port_t entry. */
860 fcport
->d_id
.b
.domain
= sns_cmd
->p
.gan_data
[17];
861 fcport
->d_id
.b
.area
= sns_cmd
->p
.gan_data
[18];
862 fcport
->d_id
.b
.al_pa
= sns_cmd
->p
.gan_data
[19];
864 memcpy(fcport
->node_name
, &sns_cmd
->p
.gan_data
[284], WWN_SIZE
);
865 memcpy(fcport
->port_name
, &sns_cmd
->p
.gan_data
[20], WWN_SIZE
);
867 if (sns_cmd
->p
.gan_data
[16] != NS_N_PORT_TYPE
&&
868 sns_cmd
->p
.gan_data
[16] != NS_NL_PORT_TYPE
)
869 fcport
->d_id
.b
.domain
= 0xf0;
871 ql_dbg(ql_dbg_disc
, vha
, 0x2061,
872 "GA_NXT entry - nn %8phN pn %8phN "
873 "port_id=%02x%02x%02x.\n",
874 fcport
->node_name
, fcport
->port_name
,
875 fcport
->d_id
.b
.domain
, fcport
->d_id
.b
.area
,
876 fcport
->d_id
.b
.al_pa
);
883 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
885 * @list: switch info entries to populate
887 * This command uses the old Exectute SNS Command mailbox routine.
889 * NOTE: Non-Nx_Ports are not requested.
891 * Returns 0 on success.
894 qla2x00_sns_gid_pt(scsi_qla_host_t
*vha
, sw_info_t
*list
)
897 struct qla_hw_data
*ha
= vha
->hw
;
900 struct sns_cmd_pkt
*sns_cmd
;
901 uint16_t gid_pt_sns_data_size
;
903 gid_pt_sns_data_size
= qla2x00_gid_pt_rsp_size(vha
);
906 /* Prepare SNS command request. */
907 sns_cmd
= qla2x00_prep_sns_cmd(vha
, GID_PT_CMD
, GID_PT_SNS_SCMD_LEN
,
908 gid_pt_sns_data_size
);
910 /* Prepare SNS command arguments -- port_type. */
911 sns_cmd
->p
.cmd
.param
[0] = NS_NX_PORT_TYPE
;
913 /* Execute SNS command. */
914 rval
= qla2x00_send_sns(vha
, ha
->sns_cmd_dma
, GID_PT_SNS_CMD_SIZE
/ 2,
915 sizeof(struct sns_cmd_pkt
));
916 if (rval
!= QLA_SUCCESS
) {
918 ql_dbg(ql_dbg_disc
, vha
, 0x206d,
919 "GID_PT Send SNS failed (%d).\n", rval
);
920 } else if (sns_cmd
->p
.gid_data
[8] != 0x80 ||
921 sns_cmd
->p
.gid_data
[9] != 0x02) {
922 ql_dbg(ql_dbg_disc
, vha
, 0x202f,
923 "GID_PT failed, rejected request, gid_rsp:\n");
924 ql_dump_buffer(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x2081,
925 sns_cmd
->p
.gid_data
, 16);
926 rval
= QLA_FUNCTION_FAILED
;
928 /* Set port IDs in switch info list. */
929 for (i
= 0; i
< ha
->max_fibre_devices
; i
++) {
930 entry
= &sns_cmd
->p
.gid_data
[(i
* 4) + 16];
931 list
[i
].d_id
.b
.domain
= entry
[1];
932 list
[i
].d_id
.b
.area
= entry
[2];
933 list
[i
].d_id
.b
.al_pa
= entry
[3];
936 if (entry
[0] & BIT_7
) {
937 list
[i
].d_id
.b
.rsvd_1
= entry
[0];
943 * If we've used all available slots, then the switch is
944 * reporting back more devices that we can handle with this
945 * single call. Return a failed status, and let GA_NXT handle
948 if (i
== ha
->max_fibre_devices
)
949 rval
= QLA_FUNCTION_FAILED
;
956 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
958 * @list: switch info entries to populate
960 * This command uses the old Exectute SNS Command mailbox routine.
962 * Returns 0 on success.
965 qla2x00_sns_gpn_id(scsi_qla_host_t
*vha
, sw_info_t
*list
)
967 int rval
= QLA_SUCCESS
;
968 struct qla_hw_data
*ha
= vha
->hw
;
970 struct sns_cmd_pkt
*sns_cmd
;
972 for (i
= 0; i
< ha
->max_fibre_devices
; i
++) {
974 /* Prepare SNS command request. */
975 sns_cmd
= qla2x00_prep_sns_cmd(vha
, GPN_ID_CMD
,
976 GPN_ID_SNS_SCMD_LEN
, GPN_ID_SNS_DATA_SIZE
);
978 /* Prepare SNS command arguments -- port_id. */
979 sns_cmd
->p
.cmd
.param
[0] = list
[i
].d_id
.b
.al_pa
;
980 sns_cmd
->p
.cmd
.param
[1] = list
[i
].d_id
.b
.area
;
981 sns_cmd
->p
.cmd
.param
[2] = list
[i
].d_id
.b
.domain
;
983 /* Execute SNS command. */
984 rval
= qla2x00_send_sns(vha
, ha
->sns_cmd_dma
,
985 GPN_ID_SNS_CMD_SIZE
/ 2, sizeof(struct sns_cmd_pkt
));
986 if (rval
!= QLA_SUCCESS
) {
988 ql_dbg(ql_dbg_disc
, vha
, 0x2032,
989 "GPN_ID Send SNS failed (%d).\n", rval
);
990 } else if (sns_cmd
->p
.gpn_data
[8] != 0x80 ||
991 sns_cmd
->p
.gpn_data
[9] != 0x02) {
992 ql_dbg(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x207e,
993 "GPN_ID failed, rejected request, gpn_rsp:\n");
994 ql_dump_buffer(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x207f,
995 sns_cmd
->p
.gpn_data
, 16);
996 rval
= QLA_FUNCTION_FAILED
;
999 memcpy(list
[i
].port_name
, &sns_cmd
->p
.gpn_data
[16],
1003 /* Last device exit. */
1004 if (list
[i
].d_id
.b
.rsvd_1
!= 0)
1012 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
1014 * @list: switch info entries to populate
1016 * This command uses the old Exectute SNS Command mailbox routine.
1018 * Returns 0 on success.
1021 qla2x00_sns_gnn_id(scsi_qla_host_t
*vha
, sw_info_t
*list
)
1023 int rval
= QLA_SUCCESS
;
1024 struct qla_hw_data
*ha
= vha
->hw
;
1026 struct sns_cmd_pkt
*sns_cmd
;
1028 for (i
= 0; i
< ha
->max_fibre_devices
; i
++) {
1030 /* Prepare SNS command request. */
1031 sns_cmd
= qla2x00_prep_sns_cmd(vha
, GNN_ID_CMD
,
1032 GNN_ID_SNS_SCMD_LEN
, GNN_ID_SNS_DATA_SIZE
);
1034 /* Prepare SNS command arguments -- port_id. */
1035 sns_cmd
->p
.cmd
.param
[0] = list
[i
].d_id
.b
.al_pa
;
1036 sns_cmd
->p
.cmd
.param
[1] = list
[i
].d_id
.b
.area
;
1037 sns_cmd
->p
.cmd
.param
[2] = list
[i
].d_id
.b
.domain
;
1039 /* Execute SNS command. */
1040 rval
= qla2x00_send_sns(vha
, ha
->sns_cmd_dma
,
1041 GNN_ID_SNS_CMD_SIZE
/ 2, sizeof(struct sns_cmd_pkt
));
1042 if (rval
!= QLA_SUCCESS
) {
1044 ql_dbg(ql_dbg_disc
, vha
, 0x203f,
1045 "GNN_ID Send SNS failed (%d).\n", rval
);
1046 } else if (sns_cmd
->p
.gnn_data
[8] != 0x80 ||
1047 sns_cmd
->p
.gnn_data
[9] != 0x02) {
1048 ql_dbg(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x2082,
1049 "GNN_ID failed, rejected request, gnn_rsp:\n");
1050 ql_dump_buffer(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x207a,
1051 sns_cmd
->p
.gnn_data
, 16);
1052 rval
= QLA_FUNCTION_FAILED
;
1055 memcpy(list
[i
].node_name
, &sns_cmd
->p
.gnn_data
[16],
1058 ql_dbg(ql_dbg_disc
, vha
, 0x206e,
1059 "GID_PT entry - nn %8phN pn %8phN "
1060 "port_id=%02x%02x%02x.\n",
1061 list
[i
].node_name
, list
[i
].port_name
,
1062 list
[i
].d_id
.b
.domain
, list
[i
].d_id
.b
.area
,
1063 list
[i
].d_id
.b
.al_pa
);
1066 /* Last device exit. */
1067 if (list
[i
].d_id
.b
.rsvd_1
!= 0)
1075 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
1078 * This command uses the old Exectute SNS Command mailbox routine.
1080 * Returns 0 on success.
1083 qla2x00_sns_rft_id(scsi_qla_host_t
*vha
)
1086 struct qla_hw_data
*ha
= vha
->hw
;
1087 struct sns_cmd_pkt
*sns_cmd
;
1090 /* Prepare SNS command request. */
1091 sns_cmd
= qla2x00_prep_sns_cmd(vha
, RFT_ID_CMD
, RFT_ID_SNS_SCMD_LEN
,
1092 RFT_ID_SNS_DATA_SIZE
);
1094 /* Prepare SNS command arguments -- port_id, FC-4 types */
1095 sns_cmd
->p
.cmd
.param
[0] = vha
->d_id
.b
.al_pa
;
1096 sns_cmd
->p
.cmd
.param
[1] = vha
->d_id
.b
.area
;
1097 sns_cmd
->p
.cmd
.param
[2] = vha
->d_id
.b
.domain
;
1099 sns_cmd
->p
.cmd
.param
[5] = 0x01; /* FCP-3 */
1101 /* Execute SNS command. */
1102 rval
= qla2x00_send_sns(vha
, ha
->sns_cmd_dma
, RFT_ID_SNS_CMD_SIZE
/ 2,
1103 sizeof(struct sns_cmd_pkt
));
1104 if (rval
!= QLA_SUCCESS
) {
1106 ql_dbg(ql_dbg_disc
, vha
, 0x2060,
1107 "RFT_ID Send SNS failed (%d).\n", rval
);
1108 } else if (sns_cmd
->p
.rft_data
[8] != 0x80 ||
1109 sns_cmd
->p
.rft_data
[9] != 0x02) {
1110 ql_dbg(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x2083,
1111 "RFT_ID failed, rejected request rft_rsp:\n");
1112 ql_dump_buffer(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x2080,
1113 sns_cmd
->p
.rft_data
, 16);
1114 rval
= QLA_FUNCTION_FAILED
;
1116 ql_dbg(ql_dbg_disc
, vha
, 0x2073,
1117 "RFT_ID exiting normally.\n");
1124 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
1128 * This command uses the old Exectute SNS Command mailbox routine.
1130 * Returns 0 on success.
1133 qla2x00_sns_rnn_id(scsi_qla_host_t
*vha
)
1136 struct qla_hw_data
*ha
= vha
->hw
;
1137 struct sns_cmd_pkt
*sns_cmd
;
1140 /* Prepare SNS command request. */
1141 sns_cmd
= qla2x00_prep_sns_cmd(vha
, RNN_ID_CMD
, RNN_ID_SNS_SCMD_LEN
,
1142 RNN_ID_SNS_DATA_SIZE
);
1144 /* Prepare SNS command arguments -- port_id, nodename. */
1145 sns_cmd
->p
.cmd
.param
[0] = vha
->d_id
.b
.al_pa
;
1146 sns_cmd
->p
.cmd
.param
[1] = vha
->d_id
.b
.area
;
1147 sns_cmd
->p
.cmd
.param
[2] = vha
->d_id
.b
.domain
;
1149 sns_cmd
->p
.cmd
.param
[4] = vha
->node_name
[7];
1150 sns_cmd
->p
.cmd
.param
[5] = vha
->node_name
[6];
1151 sns_cmd
->p
.cmd
.param
[6] = vha
->node_name
[5];
1152 sns_cmd
->p
.cmd
.param
[7] = vha
->node_name
[4];
1153 sns_cmd
->p
.cmd
.param
[8] = vha
->node_name
[3];
1154 sns_cmd
->p
.cmd
.param
[9] = vha
->node_name
[2];
1155 sns_cmd
->p
.cmd
.param
[10] = vha
->node_name
[1];
1156 sns_cmd
->p
.cmd
.param
[11] = vha
->node_name
[0];
1158 /* Execute SNS command. */
1159 rval
= qla2x00_send_sns(vha
, ha
->sns_cmd_dma
, RNN_ID_SNS_CMD_SIZE
/ 2,
1160 sizeof(struct sns_cmd_pkt
));
1161 if (rval
!= QLA_SUCCESS
) {
1163 ql_dbg(ql_dbg_disc
, vha
, 0x204a,
1164 "RNN_ID Send SNS failed (%d).\n", rval
);
1165 } else if (sns_cmd
->p
.rnn_data
[8] != 0x80 ||
1166 sns_cmd
->p
.rnn_data
[9] != 0x02) {
1167 ql_dbg(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x207b,
1168 "RNN_ID failed, rejected request, rnn_rsp:\n");
1169 ql_dump_buffer(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x207c,
1170 sns_cmd
->p
.rnn_data
, 16);
1171 rval
= QLA_FUNCTION_FAILED
;
1173 ql_dbg(ql_dbg_disc
, vha
, 0x204c,
1174 "RNN_ID exiting normally.\n");
1181 * qla2x00_mgmt_svr_login() - Login to fabric Management Service.
1184 * Returns 0 on success.
1187 qla2x00_mgmt_svr_login(scsi_qla_host_t
*vha
)
1190 uint16_t mb
[MAILBOX_REGISTER_COUNT
];
1191 struct qla_hw_data
*ha
= vha
->hw
;
1193 if (vha
->flags
.management_server_logged_in
)
1196 rval
= ha
->isp_ops
->fabric_login(vha
, vha
->mgmt_svr_loop_id
, 0xff, 0xff,
1198 if (rval
!= QLA_SUCCESS
|| mb
[0] != MBS_COMMAND_COMPLETE
) {
1199 if (rval
== QLA_MEMORY_ALLOC_FAILED
)
1200 ql_dbg(ql_dbg_disc
, vha
, 0x2085,
1201 "Failed management_server login: loopid=%x "
1202 "rval=%d\n", vha
->mgmt_svr_loop_id
, rval
);
1204 ql_dbg(ql_dbg_disc
, vha
, 0x2024,
1205 "Failed management_server login: loopid=%x "
1206 "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
1207 vha
->mgmt_svr_loop_id
, mb
[0], mb
[1], mb
[2], mb
[6],
1209 ret
= QLA_FUNCTION_FAILED
;
1211 vha
->flags
.management_server_logged_in
= 1;
1217 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1219 * @req_size: request size in bytes
1220 * @rsp_size: response size in bytes
1222 * Returns a pointer to the @ha's ms_iocb.
1225 qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t
*vha
, uint32_t req_size
,
1228 ms_iocb_entry_t
*ms_pkt
;
1229 struct qla_hw_data
*ha
= vha
->hw
;
1230 ms_pkt
= ha
->ms_iocb
;
1231 memset(ms_pkt
, 0, sizeof(ms_iocb_entry_t
));
1233 ms_pkt
->entry_type
= MS_IOCB_TYPE
;
1234 ms_pkt
->entry_count
= 1;
1235 SET_TARGET_ID(ha
, ms_pkt
->loop_id
, vha
->mgmt_svr_loop_id
);
1236 ms_pkt
->control_flags
= cpu_to_le16(CF_READ
| CF_HEAD_TAG
);
1237 ms_pkt
->timeout
= cpu_to_le16(ha
->r_a_tov
/ 10 * 2);
1238 ms_pkt
->cmd_dsd_count
= cpu_to_le16(1);
1239 ms_pkt
->total_dsd_count
= cpu_to_le16(2);
1240 ms_pkt
->rsp_bytecount
= cpu_to_le32(rsp_size
);
1241 ms_pkt
->req_bytecount
= cpu_to_le32(req_size
);
1243 ms_pkt
->dseg_req_address
[0] = cpu_to_le32(LSD(ha
->ct_sns_dma
));
1244 ms_pkt
->dseg_req_address
[1] = cpu_to_le32(MSD(ha
->ct_sns_dma
));
1245 ms_pkt
->dseg_req_length
= ms_pkt
->req_bytecount
;
1247 ms_pkt
->dseg_rsp_address
[0] = cpu_to_le32(LSD(ha
->ct_sns_dma
));
1248 ms_pkt
->dseg_rsp_address
[1] = cpu_to_le32(MSD(ha
->ct_sns_dma
));
1249 ms_pkt
->dseg_rsp_length
= ms_pkt
->rsp_bytecount
;
1255 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1257 * @req_size: request size in bytes
1258 * @rsp_size: response size in bytes
1260 * Returns a pointer to the @ha's ms_iocb.
1263 qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t
*vha
, uint32_t req_size
,
1266 struct ct_entry_24xx
*ct_pkt
;
1267 struct qla_hw_data
*ha
= vha
->hw
;
1269 ct_pkt
= (struct ct_entry_24xx
*)ha
->ms_iocb
;
1270 memset(ct_pkt
, 0, sizeof(struct ct_entry_24xx
));
1272 ct_pkt
->entry_type
= CT_IOCB_TYPE
;
1273 ct_pkt
->entry_count
= 1;
1274 ct_pkt
->nport_handle
= cpu_to_le16(vha
->mgmt_svr_loop_id
);
1275 ct_pkt
->timeout
= cpu_to_le16(ha
->r_a_tov
/ 10 * 2);
1276 ct_pkt
->cmd_dsd_count
= cpu_to_le16(1);
1277 ct_pkt
->rsp_dsd_count
= cpu_to_le16(1);
1278 ct_pkt
->rsp_byte_count
= cpu_to_le32(rsp_size
);
1279 ct_pkt
->cmd_byte_count
= cpu_to_le32(req_size
);
1281 ct_pkt
->dseg_0_address
[0] = cpu_to_le32(LSD(ha
->ct_sns_dma
));
1282 ct_pkt
->dseg_0_address
[1] = cpu_to_le32(MSD(ha
->ct_sns_dma
));
1283 ct_pkt
->dseg_0_len
= ct_pkt
->cmd_byte_count
;
1285 ct_pkt
->dseg_1_address
[0] = cpu_to_le32(LSD(ha
->ct_sns_dma
));
1286 ct_pkt
->dseg_1_address
[1] = cpu_to_le32(MSD(ha
->ct_sns_dma
));
1287 ct_pkt
->dseg_1_len
= ct_pkt
->rsp_byte_count
;
1288 ct_pkt
->vp_index
= vha
->vp_idx
;
1293 static inline ms_iocb_entry_t
*
1294 qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t
*vha
, uint32_t req_size
)
1296 struct qla_hw_data
*ha
= vha
->hw
;
1297 ms_iocb_entry_t
*ms_pkt
= ha
->ms_iocb
;
1298 struct ct_entry_24xx
*ct_pkt
= (struct ct_entry_24xx
*)ha
->ms_iocb
;
1300 if (IS_FWI2_CAPABLE(ha
)) {
1301 ct_pkt
->cmd_byte_count
= cpu_to_le32(req_size
);
1302 ct_pkt
->dseg_0_len
= ct_pkt
->cmd_byte_count
;
1304 ms_pkt
->req_bytecount
= cpu_to_le32(req_size
);
1305 ms_pkt
->dseg_req_length
= ms_pkt
->req_bytecount
;
1312 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
1313 * @ct_req: CT request buffer
1315 * @rsp_size: response size in bytes
1317 * Returns a pointer to the intitialized @ct_req.
1319 static inline struct ct_sns_req
*
1320 qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt
*p
, uint16_t cmd
,
1323 memset(p
, 0, sizeof(struct ct_sns_pkt
));
1325 p
->p
.req
.header
.revision
= 0x01;
1326 p
->p
.req
.header
.gs_type
= 0xFA;
1327 p
->p
.req
.header
.gs_subtype
= 0x10;
1328 p
->p
.req
.command
= cpu_to_be16(cmd
);
1329 p
->p
.req
.max_rsp_size
= cpu_to_be16((rsp_size
- 16) / 4);
1335 * qla2x00_fdmi_rhba() -
1338 * Returns 0 on success.
1341 qla2x00_fdmi_rhba(scsi_qla_host_t
*vha
)
1346 ms_iocb_entry_t
*ms_pkt
;
1347 struct ct_sns_req
*ct_req
;
1348 struct ct_sns_rsp
*ct_rsp
;
1350 struct ct_fdmi_hba_attr
*eiter
;
1351 struct qla_hw_data
*ha
= vha
->hw
;
1354 /* Prepare common MS IOCB */
1355 /* Request size adjusted after CT preparation */
1356 ms_pkt
= ha
->isp_ops
->prep_ms_fdmi_iocb(vha
, 0, RHBA_RSP_SIZE
);
1358 /* Prepare CT request */
1359 ct_req
= qla2x00_prep_ct_fdmi_req(ha
->ct_sns
, RHBA_CMD
, RHBA_RSP_SIZE
);
1360 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
1362 /* Prepare FDMI command arguments -- attribute block, attributes. */
1363 memcpy(ct_req
->req
.rhba
.hba_identifier
, vha
->port_name
, WWN_SIZE
);
1364 ct_req
->req
.rhba
.entry_count
= cpu_to_be32(1);
1365 memcpy(ct_req
->req
.rhba
.port_name
, vha
->port_name
, WWN_SIZE
);
1366 size
= 2 * WWN_SIZE
+ 4 + 4;
1369 ct_req
->req
.rhba
.attrs
.count
=
1370 cpu_to_be32(FDMI_HBA_ATTR_COUNT
);
1371 entries
= ct_req
->req
.rhba
.hba_identifier
;
1374 eiter
= entries
+ size
;
1375 eiter
->type
= cpu_to_be16(FDMI_HBA_NODE_NAME
);
1376 eiter
->len
= cpu_to_be16(4 + WWN_SIZE
);
1377 memcpy(eiter
->a
.node_name
, vha
->node_name
, WWN_SIZE
);
1378 size
+= 4 + WWN_SIZE
;
1380 ql_dbg(ql_dbg_disc
, vha
, 0x2025,
1381 "NodeName = %8phN.\n", eiter
->a
.node_name
);
1384 eiter
= entries
+ size
;
1385 eiter
->type
= cpu_to_be16(FDMI_HBA_MANUFACTURER
);
1386 alen
= strlen(QLA2XXX_MANUFACTURER
);
1387 snprintf(eiter
->a
.manufacturer
, sizeof(eiter
->a
.manufacturer
),
1388 "%s", "QLogic Corporation");
1389 alen
+= 4 - (alen
& 3);
1390 eiter
->len
= cpu_to_be16(4 + alen
);
1393 ql_dbg(ql_dbg_disc
, vha
, 0x2026,
1394 "Manufacturer = %s.\n", eiter
->a
.manufacturer
);
1396 /* Serial number. */
1397 eiter
= entries
+ size
;
1398 eiter
->type
= cpu_to_be16(FDMI_HBA_SERIAL_NUMBER
);
1399 if (IS_FWI2_CAPABLE(ha
))
1400 qla2xxx_get_vpd_field(vha
, "SN", eiter
->a
.serial_num
,
1401 sizeof(eiter
->a
.serial_num
));
1403 sn
= ((ha
->serial0
& 0x1f) << 16) |
1404 (ha
->serial2
<< 8) | ha
->serial1
;
1405 snprintf(eiter
->a
.serial_num
, sizeof(eiter
->a
.serial_num
),
1406 "%c%05d", 'A' + sn
/ 100000, sn
% 100000);
1408 alen
= strlen(eiter
->a
.serial_num
);
1409 alen
+= 4 - (alen
& 3);
1410 eiter
->len
= cpu_to_be16(4 + alen
);
1413 ql_dbg(ql_dbg_disc
, vha
, 0x2027,
1414 "Serial no. = %s.\n", eiter
->a
.serial_num
);
1417 eiter
= entries
+ size
;
1418 eiter
->type
= cpu_to_be16(FDMI_HBA_MODEL
);
1419 snprintf(eiter
->a
.model
, sizeof(eiter
->a
.model
),
1420 "%s", ha
->model_number
);
1421 alen
= strlen(eiter
->a
.model
);
1422 alen
+= 4 - (alen
& 3);
1423 eiter
->len
= cpu_to_be16(4 + alen
);
1426 ql_dbg(ql_dbg_disc
, vha
, 0x2028,
1427 "Model Name = %s.\n", eiter
->a
.model
);
1429 /* Model description. */
1430 eiter
= entries
+ size
;
1431 eiter
->type
= cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION
);
1432 snprintf(eiter
->a
.model_desc
, sizeof(eiter
->a
.model_desc
),
1433 "%s", ha
->model_desc
);
1434 alen
= strlen(eiter
->a
.model_desc
);
1435 alen
+= 4 - (alen
& 3);
1436 eiter
->len
= cpu_to_be16(4 + alen
);
1439 ql_dbg(ql_dbg_disc
, vha
, 0x2029,
1440 "Model Desc = %s.\n", eiter
->a
.model_desc
);
1442 /* Hardware version. */
1443 eiter
= entries
+ size
;
1444 eiter
->type
= cpu_to_be16(FDMI_HBA_HARDWARE_VERSION
);
1445 if (!IS_FWI2_CAPABLE(ha
)) {
1446 snprintf(eiter
->a
.hw_version
, sizeof(eiter
->a
.hw_version
),
1447 "HW:%s", ha
->adapter_id
);
1448 } else if (qla2xxx_get_vpd_field(vha
, "MN", eiter
->a
.hw_version
,
1449 sizeof(eiter
->a
.hw_version
))) {
1451 } else if (qla2xxx_get_vpd_field(vha
, "EC", eiter
->a
.hw_version
,
1452 sizeof(eiter
->a
.hw_version
))) {
1455 snprintf(eiter
->a
.hw_version
, sizeof(eiter
->a
.hw_version
),
1456 "HW:%s", ha
->adapter_id
);
1458 alen
= strlen(eiter
->a
.hw_version
);
1459 alen
+= 4 - (alen
& 3);
1460 eiter
->len
= cpu_to_be16(4 + alen
);
1463 ql_dbg(ql_dbg_disc
, vha
, 0x202a,
1464 "Hardware ver = %s.\n", eiter
->a
.hw_version
);
1466 /* Driver version. */
1467 eiter
= entries
+ size
;
1468 eiter
->type
= cpu_to_be16(FDMI_HBA_DRIVER_VERSION
);
1469 snprintf(eiter
->a
.driver_version
, sizeof(eiter
->a
.driver_version
),
1470 "%s", qla2x00_version_str
);
1471 alen
= strlen(eiter
->a
.driver_version
);
1472 alen
+= 4 - (alen
& 3);
1473 eiter
->len
= cpu_to_be16(4 + alen
);
1476 ql_dbg(ql_dbg_disc
, vha
, 0x202b,
1477 "Driver ver = %s.\n", eiter
->a
.driver_version
);
1479 /* Option ROM version. */
1480 eiter
= entries
+ size
;
1481 eiter
->type
= cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION
);
1482 snprintf(eiter
->a
.orom_version
, sizeof(eiter
->a
.orom_version
),
1483 "%d.%02d", ha
->bios_revision
[1], ha
->bios_revision
[0]);
1484 alen
= strlen(eiter
->a
.orom_version
);
1485 alen
+= 4 - (alen
& 3);
1486 eiter
->len
= cpu_to_be16(4 + alen
);
1489 ql_dbg(ql_dbg_disc
, vha
, 0x202c,
1490 "Optrom vers = %s.\n", eiter
->a
.orom_version
);
1492 /* Firmware version */
1493 eiter
= entries
+ size
;
1494 eiter
->type
= cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION
);
1495 ha
->isp_ops
->fw_version_str(vha
, eiter
->a
.fw_version
,
1496 sizeof(eiter
->a
.fw_version
));
1497 alen
= strlen(eiter
->a
.fw_version
);
1498 alen
+= 4 - (alen
& 3);
1499 eiter
->len
= cpu_to_be16(4 + alen
);
1502 ql_dbg(ql_dbg_disc
, vha
, 0x202d,
1503 "Firmware vers = %s.\n", eiter
->a
.fw_version
);
1505 /* Update MS request size. */
1506 qla2x00_update_ms_fdmi_iocb(vha
, size
+ 16);
1508 ql_dbg(ql_dbg_disc
, vha
, 0x202e,
1509 "RHBA identifier = %8phN size=%d.\n",
1510 ct_req
->req
.rhba
.hba_identifier
, size
);
1511 ql_dump_buffer(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x2076,
1514 /* Execute MS IOCB */
1515 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
1516 sizeof(ms_iocb_entry_t
));
1517 if (rval
!= QLA_SUCCESS
) {
1519 ql_dbg(ql_dbg_disc
, vha
, 0x2030,
1520 "RHBA issue IOCB failed (%d).\n", rval
);
1521 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
, "RHBA") !=
1523 rval
= QLA_FUNCTION_FAILED
;
1524 if (ct_rsp
->header
.reason_code
== CT_REASON_CANNOT_PERFORM
&&
1525 ct_rsp
->header
.explanation_code
==
1526 CT_EXPL_ALREADY_REGISTERED
) {
1527 ql_dbg(ql_dbg_disc
, vha
, 0x2034,
1528 "HBA already registered.\n");
1529 rval
= QLA_ALREADY_REGISTERED
;
1531 ql_dbg(ql_dbg_disc
, vha
, 0x20ad,
1532 "RHBA FDMI registration failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
1533 ct_rsp
->header
.reason_code
,
1534 ct_rsp
->header
.explanation_code
);
1537 ql_dbg(ql_dbg_disc
, vha
, 0x2035,
1538 "RHBA exiting normally.\n");
1545 * qla2x00_fdmi_rpa() -
1548 * Returns 0 on success.
1551 qla2x00_fdmi_rpa(scsi_qla_host_t
*vha
)
1555 struct qla_hw_data
*ha
= vha
->hw
;
1556 ms_iocb_entry_t
*ms_pkt
;
1557 struct ct_sns_req
*ct_req
;
1558 struct ct_sns_rsp
*ct_rsp
;
1560 struct ct_fdmi_port_attr
*eiter
;
1561 struct init_cb_24xx
*icb24
= (struct init_cb_24xx
*)ha
->init_cb
;
1562 struct new_utsname
*p_sysid
= NULL
;
1565 /* Prepare common MS IOCB */
1566 /* Request size adjusted after CT preparation */
1567 ms_pkt
= ha
->isp_ops
->prep_ms_fdmi_iocb(vha
, 0, RPA_RSP_SIZE
);
1569 /* Prepare CT request */
1570 ct_req
= qla2x00_prep_ct_fdmi_req(ha
->ct_sns
, RPA_CMD
,
1572 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
1574 /* Prepare FDMI command arguments -- attribute block, attributes. */
1575 memcpy(ct_req
->req
.rpa
.port_name
, vha
->port_name
, WWN_SIZE
);
1576 size
= WWN_SIZE
+ 4;
1579 ct_req
->req
.rpa
.attrs
.count
= cpu_to_be32(FDMI_PORT_ATTR_COUNT
);
1580 entries
= ct_req
->req
.rpa
.port_name
;
1583 eiter
= entries
+ size
;
1584 eiter
->type
= cpu_to_be16(FDMI_PORT_FC4_TYPES
);
1585 eiter
->len
= cpu_to_be16(4 + 32);
1586 eiter
->a
.fc4_types
[2] = 0x01;
1589 ql_dbg(ql_dbg_disc
, vha
, 0x2039,
1590 "FC4_TYPES=%02x %02x.\n",
1591 eiter
->a
.fc4_types
[2],
1592 eiter
->a
.fc4_types
[1]);
1594 /* Supported speed. */
1595 eiter
= entries
+ size
;
1596 eiter
->type
= cpu_to_be16(FDMI_PORT_SUPPORT_SPEED
);
1597 eiter
->len
= cpu_to_be16(4 + 4);
1598 if (IS_CNA_CAPABLE(ha
))
1599 eiter
->a
.sup_speed
= cpu_to_be32(
1600 FDMI_PORT_SPEED_10GB
);
1601 else if (IS_QLA27XX(ha
))
1602 eiter
->a
.sup_speed
= cpu_to_be32(
1603 FDMI_PORT_SPEED_32GB
|
1604 FDMI_PORT_SPEED_16GB
|
1605 FDMI_PORT_SPEED_8GB
);
1606 else if (IS_QLA2031(ha
))
1607 eiter
->a
.sup_speed
= cpu_to_be32(
1608 FDMI_PORT_SPEED_16GB
|
1609 FDMI_PORT_SPEED_8GB
|
1610 FDMI_PORT_SPEED_4GB
);
1611 else if (IS_QLA25XX(ha
))
1612 eiter
->a
.sup_speed
= cpu_to_be32(
1613 FDMI_PORT_SPEED_8GB
|
1614 FDMI_PORT_SPEED_4GB
|
1615 FDMI_PORT_SPEED_2GB
|
1616 FDMI_PORT_SPEED_1GB
);
1617 else if (IS_QLA24XX_TYPE(ha
))
1618 eiter
->a
.sup_speed
= cpu_to_be32(
1619 FDMI_PORT_SPEED_4GB
|
1620 FDMI_PORT_SPEED_2GB
|
1621 FDMI_PORT_SPEED_1GB
);
1622 else if (IS_QLA23XX(ha
))
1623 eiter
->a
.sup_speed
= cpu_to_be32(
1624 FDMI_PORT_SPEED_2GB
|
1625 FDMI_PORT_SPEED_1GB
);
1627 eiter
->a
.sup_speed
= cpu_to_be32(
1628 FDMI_PORT_SPEED_1GB
);
1631 ql_dbg(ql_dbg_disc
, vha
, 0x203a,
1632 "Supported_Speed=%x.\n", eiter
->a
.sup_speed
);
1634 /* Current speed. */
1635 eiter
= entries
+ size
;
1636 eiter
->type
= cpu_to_be16(FDMI_PORT_CURRENT_SPEED
);
1637 eiter
->len
= cpu_to_be16(4 + 4);
1638 switch (ha
->link_data_rate
) {
1639 case PORT_SPEED_1GB
:
1640 eiter
->a
.cur_speed
=
1641 cpu_to_be32(FDMI_PORT_SPEED_1GB
);
1643 case PORT_SPEED_2GB
:
1644 eiter
->a
.cur_speed
=
1645 cpu_to_be32(FDMI_PORT_SPEED_2GB
);
1647 case PORT_SPEED_4GB
:
1648 eiter
->a
.cur_speed
=
1649 cpu_to_be32(FDMI_PORT_SPEED_4GB
);
1651 case PORT_SPEED_8GB
:
1652 eiter
->a
.cur_speed
=
1653 cpu_to_be32(FDMI_PORT_SPEED_8GB
);
1655 case PORT_SPEED_10GB
:
1656 eiter
->a
.cur_speed
=
1657 cpu_to_be32(FDMI_PORT_SPEED_10GB
);
1659 case PORT_SPEED_16GB
:
1660 eiter
->a
.cur_speed
=
1661 cpu_to_be32(FDMI_PORT_SPEED_16GB
);
1663 case PORT_SPEED_32GB
:
1664 eiter
->a
.cur_speed
=
1665 cpu_to_be32(FDMI_PORT_SPEED_32GB
);
1668 eiter
->a
.cur_speed
=
1669 cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN
);
1674 ql_dbg(ql_dbg_disc
, vha
, 0x203b,
1675 "Current_Speed=%x.\n", eiter
->a
.cur_speed
);
1677 /* Max frame size. */
1678 eiter
= entries
+ size
;
1679 eiter
->type
= cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE
);
1680 eiter
->len
= cpu_to_be16(4 + 4);
1681 eiter
->a
.max_frame_size
= IS_FWI2_CAPABLE(ha
) ?
1682 le16_to_cpu(icb24
->frame_payload_size
) :
1683 le16_to_cpu(ha
->init_cb
->frame_payload_size
);
1684 eiter
->a
.max_frame_size
= cpu_to_be32(eiter
->a
.max_frame_size
);
1687 ql_dbg(ql_dbg_disc
, vha
, 0x203c,
1688 "Max_Frame_Size=%x.\n", eiter
->a
.max_frame_size
);
1690 /* OS device name. */
1691 eiter
= entries
+ size
;
1692 eiter
->type
= cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME
);
1693 snprintf(eiter
->a
.os_dev_name
, sizeof(eiter
->a
.os_dev_name
),
1694 "%s:host%lu", QLA2XXX_DRIVER_NAME
, vha
->host_no
);
1695 alen
= strlen(eiter
->a
.os_dev_name
);
1696 alen
+= 4 - (alen
& 3);
1697 eiter
->len
= cpu_to_be16(4 + alen
);
1700 ql_dbg(ql_dbg_disc
, vha
, 0x204b,
1701 "OS_Device_Name=%s.\n", eiter
->a
.os_dev_name
);
1704 eiter
= entries
+ size
;
1705 eiter
->type
= cpu_to_be16(FDMI_PORT_HOST_NAME
);
1706 p_sysid
= utsname();
1708 snprintf(eiter
->a
.host_name
, sizeof(eiter
->a
.host_name
),
1709 "%s", p_sysid
->nodename
);
1711 snprintf(eiter
->a
.host_name
, sizeof(eiter
->a
.host_name
),
1712 "%s", fc_host_system_hostname(vha
->host
));
1714 alen
= strlen(eiter
->a
.host_name
);
1715 alen
+= 4 - (alen
& 3);
1716 eiter
->len
= cpu_to_be16(4 + alen
);
1719 ql_dbg(ql_dbg_disc
, vha
, 0x203d, "HostName=%s.\n", eiter
->a
.host_name
);
1721 /* Update MS request size. */
1722 qla2x00_update_ms_fdmi_iocb(vha
, size
+ 16);
1724 ql_dbg(ql_dbg_disc
, vha
, 0x203e,
1725 "RPA portname %016llx, size = %d.\n",
1726 wwn_to_u64(ct_req
->req
.rpa
.port_name
), size
);
1727 ql_dump_buffer(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x2079,
1730 /* Execute MS IOCB */
1731 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
1732 sizeof(ms_iocb_entry_t
));
1733 if (rval
!= QLA_SUCCESS
) {
1735 ql_dbg(ql_dbg_disc
, vha
, 0x2040,
1736 "RPA issue IOCB failed (%d).\n", rval
);
1737 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
, "RPA") !=
1739 rval
= QLA_FUNCTION_FAILED
;
1740 if (ct_rsp
->header
.reason_code
== CT_REASON_CANNOT_PERFORM
&&
1741 ct_rsp
->header
.explanation_code
==
1742 CT_EXPL_ALREADY_REGISTERED
) {
1743 ql_dbg(ql_dbg_disc
, vha
, 0x20cd,
1744 "RPA already registered.\n");
1745 rval
= QLA_ALREADY_REGISTERED
;
1749 ql_dbg(ql_dbg_disc
, vha
, 0x2041,
1750 "RPA exiting normally.\n");
1757 * qla2x00_fdmiv2_rhba() -
1760 * Returns 0 on success.
1763 qla2x00_fdmiv2_rhba(scsi_qla_host_t
*vha
)
1767 ms_iocb_entry_t
*ms_pkt
;
1768 struct ct_sns_req
*ct_req
;
1769 struct ct_sns_rsp
*ct_rsp
;
1771 struct ct_fdmiv2_hba_attr
*eiter
;
1772 struct qla_hw_data
*ha
= vha
->hw
;
1773 struct init_cb_24xx
*icb24
= (struct init_cb_24xx
*)ha
->init_cb
;
1774 struct new_utsname
*p_sysid
= NULL
;
1777 /* Prepare common MS IOCB */
1778 /* Request size adjusted after CT preparation */
1779 ms_pkt
= ha
->isp_ops
->prep_ms_fdmi_iocb(vha
, 0, RHBA_RSP_SIZE
);
1781 /* Prepare CT request */
1782 ct_req
= qla2x00_prep_ct_fdmi_req(ha
->ct_sns
, RHBA_CMD
,
1784 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
1786 /* Prepare FDMI command arguments -- attribute block, attributes. */
1787 memcpy(ct_req
->req
.rhba2
.hba_identifier
, vha
->port_name
, WWN_SIZE
);
1788 ct_req
->req
.rhba2
.entry_count
= cpu_to_be32(1);
1789 memcpy(ct_req
->req
.rhba2
.port_name
, vha
->port_name
, WWN_SIZE
);
1790 size
= 2 * WWN_SIZE
+ 4 + 4;
1793 ct_req
->req
.rhba2
.attrs
.count
= cpu_to_be32(FDMIV2_HBA_ATTR_COUNT
);
1794 entries
= ct_req
->req
.rhba2
.hba_identifier
;
1797 eiter
= entries
+ size
;
1798 eiter
->type
= cpu_to_be16(FDMI_HBA_NODE_NAME
);
1799 eiter
->len
= cpu_to_be16(4 + WWN_SIZE
);
1800 memcpy(eiter
->a
.node_name
, vha
->node_name
, WWN_SIZE
);
1801 size
+= 4 + WWN_SIZE
;
1803 ql_dbg(ql_dbg_disc
, vha
, 0x207d,
1804 "NodeName = %016llx.\n", wwn_to_u64(eiter
->a
.node_name
));
1807 eiter
= entries
+ size
;
1808 eiter
->type
= cpu_to_be16(FDMI_HBA_MANUFACTURER
);
1809 snprintf(eiter
->a
.manufacturer
, sizeof(eiter
->a
.manufacturer
),
1810 "%s", "QLogic Corporation");
1811 eiter
->a
.manufacturer
[strlen("QLogic Corporation")] = '\0';
1812 alen
= strlen(eiter
->a
.manufacturer
);
1813 alen
+= 4 - (alen
& 3);
1814 eiter
->len
= cpu_to_be16(4 + alen
);
1817 ql_dbg(ql_dbg_disc
, vha
, 0x20a5,
1818 "Manufacturer = %s.\n", eiter
->a
.manufacturer
);
1820 /* Serial number. */
1821 eiter
= entries
+ size
;
1822 eiter
->type
= cpu_to_be16(FDMI_HBA_SERIAL_NUMBER
);
1823 if (IS_FWI2_CAPABLE(ha
))
1824 qla2xxx_get_vpd_field(vha
, "SN", eiter
->a
.serial_num
,
1825 sizeof(eiter
->a
.serial_num
));
1827 sn
= ((ha
->serial0
& 0x1f) << 16) |
1828 (ha
->serial2
<< 8) | ha
->serial1
;
1829 snprintf(eiter
->a
.serial_num
, sizeof(eiter
->a
.serial_num
),
1830 "%c%05d", 'A' + sn
/ 100000, sn
% 100000);
1832 alen
= strlen(eiter
->a
.serial_num
);
1833 alen
+= 4 - (alen
& 3);
1834 eiter
->len
= cpu_to_be16(4 + alen
);
1837 ql_dbg(ql_dbg_disc
, vha
, 0x20a6,
1838 "Serial no. = %s.\n", eiter
->a
.serial_num
);
1841 eiter
= entries
+ size
;
1842 eiter
->type
= cpu_to_be16(FDMI_HBA_MODEL
);
1843 snprintf(eiter
->a
.model
, sizeof(eiter
->a
.model
),
1844 "%s", ha
->model_number
);
1845 alen
= strlen(eiter
->a
.model
);
1846 alen
+= 4 - (alen
& 3);
1847 eiter
->len
= cpu_to_be16(4 + alen
);
1850 ql_dbg(ql_dbg_disc
, vha
, 0x20a7,
1851 "Model Name = %s.\n", eiter
->a
.model
);
1853 /* Model description. */
1854 eiter
= entries
+ size
;
1855 eiter
->type
= cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION
);
1856 snprintf(eiter
->a
.model_desc
, sizeof(eiter
->a
.model_desc
),
1857 "%s", ha
->model_desc
);
1858 alen
= strlen(eiter
->a
.model_desc
);
1859 alen
+= 4 - (alen
& 3);
1860 eiter
->len
= cpu_to_be16(4 + alen
);
1863 ql_dbg(ql_dbg_disc
, vha
, 0x20a8,
1864 "Model Desc = %s.\n", eiter
->a
.model_desc
);
1866 /* Hardware version. */
1867 eiter
= entries
+ size
;
1868 eiter
->type
= cpu_to_be16(FDMI_HBA_HARDWARE_VERSION
);
1869 if (!IS_FWI2_CAPABLE(ha
)) {
1870 snprintf(eiter
->a
.hw_version
, sizeof(eiter
->a
.hw_version
),
1871 "HW:%s", ha
->adapter_id
);
1872 } else if (qla2xxx_get_vpd_field(vha
, "MN", eiter
->a
.hw_version
,
1873 sizeof(eiter
->a
.hw_version
))) {
1875 } else if (qla2xxx_get_vpd_field(vha
, "EC", eiter
->a
.hw_version
,
1876 sizeof(eiter
->a
.hw_version
))) {
1879 snprintf(eiter
->a
.hw_version
, sizeof(eiter
->a
.hw_version
),
1880 "HW:%s", ha
->adapter_id
);
1882 alen
= strlen(eiter
->a
.hw_version
);
1883 alen
+= 4 - (alen
& 3);
1884 eiter
->len
= cpu_to_be16(4 + alen
);
1887 ql_dbg(ql_dbg_disc
, vha
, 0x20a9,
1888 "Hardware ver = %s.\n", eiter
->a
.hw_version
);
1890 /* Driver version. */
1891 eiter
= entries
+ size
;
1892 eiter
->type
= cpu_to_be16(FDMI_HBA_DRIVER_VERSION
);
1893 snprintf(eiter
->a
.driver_version
, sizeof(eiter
->a
.driver_version
),
1894 "%s", qla2x00_version_str
);
1895 alen
= strlen(eiter
->a
.driver_version
);
1896 alen
+= 4 - (alen
& 3);
1897 eiter
->len
= cpu_to_be16(4 + alen
);
1900 ql_dbg(ql_dbg_disc
, vha
, 0x20aa,
1901 "Driver ver = %s.\n", eiter
->a
.driver_version
);
1903 /* Option ROM version. */
1904 eiter
= entries
+ size
;
1905 eiter
->type
= cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION
);
1906 snprintf(eiter
->a
.orom_version
, sizeof(eiter
->a
.orom_version
),
1907 "%d.%02d", ha
->bios_revision
[1], ha
->bios_revision
[0]);
1908 alen
= strlen(eiter
->a
.orom_version
);
1909 alen
+= 4 - (alen
& 3);
1910 eiter
->len
= cpu_to_be16(4 + alen
);
1913 ql_dbg(ql_dbg_disc
, vha
, 0x20ab,
1914 "Optrom version = %d.%02d.\n", eiter
->a
.orom_version
[1],
1915 eiter
->a
.orom_version
[0]);
1917 /* Firmware version */
1918 eiter
= entries
+ size
;
1919 eiter
->type
= cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION
);
1920 ha
->isp_ops
->fw_version_str(vha
, eiter
->a
.fw_version
,
1921 sizeof(eiter
->a
.fw_version
));
1922 alen
= strlen(eiter
->a
.fw_version
);
1923 alen
+= 4 - (alen
& 3);
1924 eiter
->len
= cpu_to_be16(4 + alen
);
1927 ql_dbg(ql_dbg_disc
, vha
, 0x20ac,
1928 "Firmware vers = %s.\n", eiter
->a
.fw_version
);
1930 /* OS Name and Version */
1931 eiter
= entries
+ size
;
1932 eiter
->type
= cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION
);
1933 p_sysid
= utsname();
1935 snprintf(eiter
->a
.os_version
, sizeof(eiter
->a
.os_version
),
1937 p_sysid
->sysname
, p_sysid
->release
, p_sysid
->version
);
1939 snprintf(eiter
->a
.os_version
, sizeof(eiter
->a
.os_version
),
1940 "%s %s", "Linux", fc_host_system_hostname(vha
->host
));
1942 alen
= strlen(eiter
->a
.os_version
);
1943 alen
+= 4 - (alen
& 3);
1944 eiter
->len
= cpu_to_be16(4 + alen
);
1947 ql_dbg(ql_dbg_disc
, vha
, 0x20ae,
1948 "OS Name and Version = %s.\n", eiter
->a
.os_version
);
1950 /* MAX CT Payload Length */
1951 eiter
= entries
+ size
;
1952 eiter
->type
= cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH
);
1953 eiter
->a
.max_ct_len
= IS_FWI2_CAPABLE(ha
) ?
1954 le16_to_cpu(icb24
->frame_payload_size
) :
1955 le16_to_cpu(ha
->init_cb
->frame_payload_size
);
1956 eiter
->a
.max_ct_len
= cpu_to_be32(eiter
->a
.max_ct_len
);
1957 eiter
->len
= cpu_to_be16(4 + 4);
1960 ql_dbg(ql_dbg_disc
, vha
, 0x20af,
1961 "CT Payload Length = 0x%x.\n", eiter
->a
.max_ct_len
);
1963 /* Node Sybolic Name */
1964 eiter
= entries
+ size
;
1965 eiter
->type
= cpu_to_be16(FDMI_HBA_NODE_SYMBOLIC_NAME
);
1966 qla2x00_get_sym_node_name(vha
, eiter
->a
.sym_name
,
1967 sizeof(eiter
->a
.sym_name
));
1968 alen
= strlen(eiter
->a
.sym_name
);
1969 alen
+= 4 - (alen
& 3);
1970 eiter
->len
= cpu_to_be16(4 + alen
);
1973 ql_dbg(ql_dbg_disc
, vha
, 0x20b0,
1974 "Symbolic Name = %s.\n", eiter
->a
.sym_name
);
1977 eiter
= entries
+ size
;
1978 eiter
->type
= cpu_to_be16(FDMI_HBA_VENDOR_ID
);
1979 eiter
->a
.vendor_id
= cpu_to_be32(0x1077);
1980 eiter
->len
= cpu_to_be16(4 + 4);
1983 ql_dbg(ql_dbg_disc
, vha
, 0x20b1,
1984 "Vendor Id = %x.\n", eiter
->a
.vendor_id
);
1987 eiter
= entries
+ size
;
1988 eiter
->type
= cpu_to_be16(FDMI_HBA_NUM_PORTS
);
1989 eiter
->a
.num_ports
= cpu_to_be32(1);
1990 eiter
->len
= cpu_to_be16(4 + 4);
1993 ql_dbg(ql_dbg_disc
, vha
, 0x20b2,
1994 "Port Num = %x.\n", eiter
->a
.num_ports
);
1997 eiter
= entries
+ size
;
1998 eiter
->type
= cpu_to_be16(FDMI_HBA_FABRIC_NAME
);
1999 memcpy(eiter
->a
.fabric_name
, vha
->fabric_node_name
, WWN_SIZE
);
2000 eiter
->len
= cpu_to_be16(4 + WWN_SIZE
);
2001 size
+= 4 + WWN_SIZE
;
2003 ql_dbg(ql_dbg_disc
, vha
, 0x20b3,
2004 "Fabric Name = %016llx.\n", wwn_to_u64(eiter
->a
.fabric_name
));
2007 eiter
= entries
+ size
;
2008 eiter
->type
= cpu_to_be16(FDMI_HBA_BOOT_BIOS_NAME
);
2009 snprintf(eiter
->a
.bios_name
, sizeof(eiter
->a
.bios_name
),
2010 "BIOS %d.%02d", ha
->bios_revision
[1], ha
->bios_revision
[0]);
2011 alen
= strlen(eiter
->a
.bios_name
);
2012 alen
+= 4 - (alen
& 3);
2013 eiter
->len
= cpu_to_be16(4 + alen
);
2016 ql_dbg(ql_dbg_disc
, vha
, 0x20b4,
2017 "BIOS Name = %s\n", eiter
->a
.bios_name
);
2019 /* Vendor Identifier */
2020 eiter
= entries
+ size
;
2021 eiter
->type
= cpu_to_be16(FDMI_HBA_TYPE_VENDOR_IDENTIFIER
);
2022 snprintf(eiter
->a
.vendor_identifier
, sizeof(eiter
->a
.vendor_identifier
),
2024 alen
= strlen(eiter
->a
.vendor_identifier
);
2025 alen
+= 4 - (alen
& 3);
2026 eiter
->len
= cpu_to_be16(4 + alen
);
2029 ql_dbg(ql_dbg_disc
, vha
, 0x201b,
2030 "Vendor Identifier = %s.\n", eiter
->a
.vendor_identifier
);
2032 /* Update MS request size. */
2033 qla2x00_update_ms_fdmi_iocb(vha
, size
+ 16);
2035 ql_dbg(ql_dbg_disc
, vha
, 0x20b5,
2036 "RHBA identifier = %016llx.\n",
2037 wwn_to_u64(ct_req
->req
.rhba2
.hba_identifier
));
2038 ql_dump_buffer(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x20b6,
2041 /* Execute MS IOCB */
2042 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
2043 sizeof(ms_iocb_entry_t
));
2044 if (rval
!= QLA_SUCCESS
) {
2046 ql_dbg(ql_dbg_disc
, vha
, 0x20b7,
2047 "RHBA issue IOCB failed (%d).\n", rval
);
2048 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
, "RHBA") !=
2050 rval
= QLA_FUNCTION_FAILED
;
2052 if (ct_rsp
->header
.reason_code
== CT_REASON_CANNOT_PERFORM
&&
2053 ct_rsp
->header
.explanation_code
==
2054 CT_EXPL_ALREADY_REGISTERED
) {
2055 ql_dbg(ql_dbg_disc
, vha
, 0x20b8,
2056 "HBA already registered.\n");
2057 rval
= QLA_ALREADY_REGISTERED
;
2059 ql_dbg(ql_dbg_disc
, vha
, 0x2016,
2060 "RHBA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
2061 ct_rsp
->header
.reason_code
,
2062 ct_rsp
->header
.explanation_code
);
2065 ql_dbg(ql_dbg_disc
, vha
, 0x20b9,
2066 "RHBA FDMI V2 exiting normally.\n");
2073 * qla2x00_fdmi_dhba() -
2076 * Returns 0 on success.
2079 qla2x00_fdmi_dhba(scsi_qla_host_t
*vha
)
2082 struct qla_hw_data
*ha
= vha
->hw
;
2083 ms_iocb_entry_t
*ms_pkt
;
2084 struct ct_sns_req
*ct_req
;
2085 struct ct_sns_rsp
*ct_rsp
;
2088 /* Prepare common MS IOCB */
2089 ms_pkt
= ha
->isp_ops
->prep_ms_fdmi_iocb(vha
, DHBA_REQ_SIZE
,
2092 /* Prepare CT request */
2093 ct_req
= qla2x00_prep_ct_fdmi_req(ha
->ct_sns
, DHBA_CMD
, DHBA_RSP_SIZE
);
2094 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
2096 /* Prepare FDMI command arguments -- portname. */
2097 memcpy(ct_req
->req
.dhba
.port_name
, vha
->port_name
, WWN_SIZE
);
2099 ql_dbg(ql_dbg_disc
, vha
, 0x2036,
2100 "DHBA portname = %8phN.\n", ct_req
->req
.dhba
.port_name
);
2102 /* Execute MS IOCB */
2103 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
2104 sizeof(ms_iocb_entry_t
));
2105 if (rval
!= QLA_SUCCESS
) {
2107 ql_dbg(ql_dbg_disc
, vha
, 0x2037,
2108 "DHBA issue IOCB failed (%d).\n", rval
);
2109 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
, "DHBA") !=
2111 rval
= QLA_FUNCTION_FAILED
;
2113 ql_dbg(ql_dbg_disc
, vha
, 0x2038,
2114 "DHBA exiting normally.\n");
2121 * qla2x00_fdmiv2_rpa() -
2124 * Returns 0 on success.
2127 qla2x00_fdmiv2_rpa(scsi_qla_host_t
*vha
)
2131 struct qla_hw_data
*ha
= vha
->hw
;
2132 ms_iocb_entry_t
*ms_pkt
;
2133 struct ct_sns_req
*ct_req
;
2134 struct ct_sns_rsp
*ct_rsp
;
2136 struct ct_fdmiv2_port_attr
*eiter
;
2137 struct init_cb_24xx
*icb24
= (struct init_cb_24xx
*)ha
->init_cb
;
2138 struct new_utsname
*p_sysid
= NULL
;
2141 /* Prepare common MS IOCB */
2142 /* Request size adjusted after CT preparation */
2143 ms_pkt
= ha
->isp_ops
->prep_ms_fdmi_iocb(vha
, 0, RPA_RSP_SIZE
);
2145 /* Prepare CT request */
2146 ct_req
= qla2x00_prep_ct_fdmi_req(ha
->ct_sns
, RPA_CMD
, RPA_RSP_SIZE
);
2147 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
2149 /* Prepare FDMI command arguments -- attribute block, attributes. */
2150 memcpy(ct_req
->req
.rpa2
.port_name
, vha
->port_name
, WWN_SIZE
);
2151 size
= WWN_SIZE
+ 4;
2154 ct_req
->req
.rpa2
.attrs
.count
= cpu_to_be32(FDMIV2_PORT_ATTR_COUNT
);
2155 entries
= ct_req
->req
.rpa2
.port_name
;
2158 eiter
= entries
+ size
;
2159 eiter
->type
= cpu_to_be16(FDMI_PORT_FC4_TYPES
);
2160 eiter
->len
= cpu_to_be16(4 + 32);
2161 eiter
->a
.fc4_types
[2] = 0x01;
2164 ql_dbg(ql_dbg_disc
, vha
, 0x20ba,
2165 "FC4_TYPES=%02x %02x.\n",
2166 eiter
->a
.fc4_types
[2],
2167 eiter
->a
.fc4_types
[1]);
2169 if (vha
->flags
.nvme_enabled
) {
2170 eiter
->a
.fc4_types
[6] = 1; /* NVMe type 28h */
2171 ql_dbg(ql_dbg_disc
, vha
, 0x211f,
2172 "NVME FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n",
2173 eiter
->a
.fc4_types
[6]);
2176 /* Supported speed. */
2177 eiter
= entries
+ size
;
2178 eiter
->type
= cpu_to_be16(FDMI_PORT_SUPPORT_SPEED
);
2179 eiter
->len
= cpu_to_be16(4 + 4);
2180 if (IS_CNA_CAPABLE(ha
))
2181 eiter
->a
.sup_speed
= cpu_to_be32(
2182 FDMI_PORT_SPEED_10GB
);
2183 else if (IS_QLA27XX(ha
))
2184 eiter
->a
.sup_speed
= cpu_to_be32(
2185 FDMI_PORT_SPEED_32GB
|
2186 FDMI_PORT_SPEED_16GB
|
2187 FDMI_PORT_SPEED_8GB
);
2188 else if (IS_QLA2031(ha
))
2189 eiter
->a
.sup_speed
= cpu_to_be32(
2190 FDMI_PORT_SPEED_16GB
|
2191 FDMI_PORT_SPEED_8GB
|
2192 FDMI_PORT_SPEED_4GB
);
2193 else if (IS_QLA25XX(ha
))
2194 eiter
->a
.sup_speed
= cpu_to_be32(
2195 FDMI_PORT_SPEED_8GB
|
2196 FDMI_PORT_SPEED_4GB
|
2197 FDMI_PORT_SPEED_2GB
|
2198 FDMI_PORT_SPEED_1GB
);
2199 else if (IS_QLA24XX_TYPE(ha
))
2200 eiter
->a
.sup_speed
= cpu_to_be32(
2201 FDMI_PORT_SPEED_4GB
|
2202 FDMI_PORT_SPEED_2GB
|
2203 FDMI_PORT_SPEED_1GB
);
2204 else if (IS_QLA23XX(ha
))
2205 eiter
->a
.sup_speed
= cpu_to_be32(
2206 FDMI_PORT_SPEED_2GB
|
2207 FDMI_PORT_SPEED_1GB
);
2209 eiter
->a
.sup_speed
= cpu_to_be32(
2210 FDMI_PORT_SPEED_1GB
);
2213 ql_dbg(ql_dbg_disc
, vha
, 0x20bb,
2214 "Supported Port Speed = %x.\n", eiter
->a
.sup_speed
);
2216 /* Current speed. */
2217 eiter
= entries
+ size
;
2218 eiter
->type
= cpu_to_be16(FDMI_PORT_CURRENT_SPEED
);
2219 eiter
->len
= cpu_to_be16(4 + 4);
2220 switch (ha
->link_data_rate
) {
2221 case PORT_SPEED_1GB
:
2222 eiter
->a
.cur_speed
= cpu_to_be32(FDMI_PORT_SPEED_1GB
);
2224 case PORT_SPEED_2GB
:
2225 eiter
->a
.cur_speed
= cpu_to_be32(FDMI_PORT_SPEED_2GB
);
2227 case PORT_SPEED_4GB
:
2228 eiter
->a
.cur_speed
= cpu_to_be32(FDMI_PORT_SPEED_4GB
);
2230 case PORT_SPEED_8GB
:
2231 eiter
->a
.cur_speed
= cpu_to_be32(FDMI_PORT_SPEED_8GB
);
2233 case PORT_SPEED_10GB
:
2234 eiter
->a
.cur_speed
= cpu_to_be32(FDMI_PORT_SPEED_10GB
);
2236 case PORT_SPEED_16GB
:
2237 eiter
->a
.cur_speed
= cpu_to_be32(FDMI_PORT_SPEED_16GB
);
2239 case PORT_SPEED_32GB
:
2240 eiter
->a
.cur_speed
= cpu_to_be32(FDMI_PORT_SPEED_32GB
);
2243 eiter
->a
.cur_speed
= cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN
);
2248 ql_dbg(ql_dbg_disc
, vha
, 0x2017,
2249 "Current_Speed = %x.\n", eiter
->a
.cur_speed
);
2251 /* Max frame size. */
2252 eiter
= entries
+ size
;
2253 eiter
->type
= cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE
);
2254 eiter
->len
= cpu_to_be16(4 + 4);
2255 eiter
->a
.max_frame_size
= IS_FWI2_CAPABLE(ha
) ?
2256 le16_to_cpu(icb24
->frame_payload_size
):
2257 le16_to_cpu(ha
->init_cb
->frame_payload_size
);
2258 eiter
->a
.max_frame_size
= cpu_to_be32(eiter
->a
.max_frame_size
);
2261 ql_dbg(ql_dbg_disc
, vha
, 0x20bc,
2262 "Max_Frame_Size = %x.\n", eiter
->a
.max_frame_size
);
2264 /* OS device name. */
2265 eiter
= entries
+ size
;
2266 eiter
->type
= cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME
);
2267 alen
= strlen(QLA2XXX_DRIVER_NAME
);
2268 snprintf(eiter
->a
.os_dev_name
, sizeof(eiter
->a
.os_dev_name
),
2269 "%s:host%lu", QLA2XXX_DRIVER_NAME
, vha
->host_no
);
2270 alen
+= 4 - (alen
& 3);
2271 eiter
->len
= cpu_to_be16(4 + alen
);
2274 ql_dbg(ql_dbg_disc
, vha
, 0x20be,
2275 "OS_Device_Name = %s.\n", eiter
->a
.os_dev_name
);
2278 eiter
= entries
+ size
;
2279 eiter
->type
= cpu_to_be16(FDMI_PORT_HOST_NAME
);
2280 p_sysid
= utsname();
2282 snprintf(eiter
->a
.host_name
, sizeof(eiter
->a
.host_name
),
2283 "%s", p_sysid
->nodename
);
2285 snprintf(eiter
->a
.host_name
, sizeof(eiter
->a
.host_name
),
2286 "%s", fc_host_system_hostname(vha
->host
));
2288 alen
= strlen(eiter
->a
.host_name
);
2289 alen
+= 4 - (alen
& 3);
2290 eiter
->len
= cpu_to_be16(4 + alen
);
2293 ql_dbg(ql_dbg_disc
, vha
, 0x201a,
2294 "HostName=%s.\n", eiter
->a
.host_name
);
2297 eiter
= entries
+ size
;
2298 eiter
->type
= cpu_to_be16(FDMI_PORT_NODE_NAME
);
2299 memcpy(eiter
->a
.node_name
, vha
->node_name
, WWN_SIZE
);
2300 eiter
->len
= cpu_to_be16(4 + WWN_SIZE
);
2301 size
+= 4 + WWN_SIZE
;
2303 ql_dbg(ql_dbg_disc
, vha
, 0x20c0,
2304 "Node Name = %016llx.\n", wwn_to_u64(eiter
->a
.node_name
));
2307 eiter
= entries
+ size
;
2308 eiter
->type
= cpu_to_be16(FDMI_PORT_NAME
);
2309 memcpy(eiter
->a
.port_name
, vha
->port_name
, WWN_SIZE
);
2310 eiter
->len
= cpu_to_be16(4 + WWN_SIZE
);
2311 size
+= 4 + WWN_SIZE
;
2313 ql_dbg(ql_dbg_disc
, vha
, 0x20c1,
2314 "Port Name = %016llx.\n", wwn_to_u64(eiter
->a
.port_name
));
2316 /* Port Symbolic Name */
2317 eiter
= entries
+ size
;
2318 eiter
->type
= cpu_to_be16(FDMI_PORT_SYM_NAME
);
2319 qla2x00_get_sym_node_name(vha
, eiter
->a
.port_sym_name
,
2320 sizeof(eiter
->a
.port_sym_name
));
2321 alen
= strlen(eiter
->a
.port_sym_name
);
2322 alen
+= 4 - (alen
& 3);
2323 eiter
->len
= cpu_to_be16(4 + alen
);
2326 ql_dbg(ql_dbg_disc
, vha
, 0x20c2,
2327 "port symbolic name = %s\n", eiter
->a
.port_sym_name
);
2330 eiter
= entries
+ size
;
2331 eiter
->type
= cpu_to_be16(FDMI_PORT_TYPE
);
2332 eiter
->a
.port_type
= cpu_to_be32(NS_NX_PORT_TYPE
);
2333 eiter
->len
= cpu_to_be16(4 + 4);
2336 ql_dbg(ql_dbg_disc
, vha
, 0x20c3,
2337 "Port Type = %x.\n", eiter
->a
.port_type
);
2339 /* Class of Service */
2340 eiter
= entries
+ size
;
2341 eiter
->type
= cpu_to_be16(FDMI_PORT_SUPP_COS
);
2342 eiter
->a
.port_supported_cos
= cpu_to_be32(FC_CLASS_3
);
2343 eiter
->len
= cpu_to_be16(4 + 4);
2346 ql_dbg(ql_dbg_disc
, vha
, 0x20c4,
2347 "Supported COS = %08x\n", eiter
->a
.port_supported_cos
);
2349 /* Port Fabric Name */
2350 eiter
= entries
+ size
;
2351 eiter
->type
= cpu_to_be16(FDMI_PORT_FABRIC_NAME
);
2352 memcpy(eiter
->a
.fabric_name
, vha
->fabric_node_name
, WWN_SIZE
);
2353 eiter
->len
= cpu_to_be16(4 + WWN_SIZE
);
2354 size
+= 4 + WWN_SIZE
;
2356 ql_dbg(ql_dbg_disc
, vha
, 0x20c5,
2357 "Fabric Name = %016llx.\n", wwn_to_u64(eiter
->a
.fabric_name
));
2360 eiter
= entries
+ size
;
2361 eiter
->type
= cpu_to_be16(FDMI_PORT_FC4_TYPE
);
2362 eiter
->a
.port_fc4_type
[0] = 0;
2363 eiter
->a
.port_fc4_type
[1] = 0;
2364 eiter
->a
.port_fc4_type
[2] = 1;
2365 eiter
->a
.port_fc4_type
[3] = 0;
2366 eiter
->len
= cpu_to_be16(4 + 32);
2369 ql_dbg(ql_dbg_disc
, vha
, 0x20c6,
2370 "Port Active FC4 Type = %02x %02x.\n",
2371 eiter
->a
.port_fc4_type
[2], eiter
->a
.port_fc4_type
[1]);
2373 if (vha
->flags
.nvme_enabled
) {
2374 eiter
->a
.port_fc4_type
[4] = 0;
2375 eiter
->a
.port_fc4_type
[5] = 0;
2376 eiter
->a
.port_fc4_type
[6] = 1; /* NVMe type 28h */
2377 ql_dbg(ql_dbg_disc
, vha
, 0x2120,
2378 "NVME Port Active FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n",
2379 eiter
->a
.port_fc4_type
[6]);
2383 eiter
= entries
+ size
;
2384 eiter
->type
= cpu_to_be16(FDMI_PORT_STATE
);
2385 eiter
->a
.port_state
= cpu_to_be32(1);
2386 eiter
->len
= cpu_to_be16(4 + 4);
2389 ql_dbg(ql_dbg_disc
, vha
, 0x20c7,
2390 "Port State = %x.\n", eiter
->a
.port_state
);
2392 /* Number of Ports */
2393 eiter
= entries
+ size
;
2394 eiter
->type
= cpu_to_be16(FDMI_PORT_COUNT
);
2395 eiter
->a
.num_ports
= cpu_to_be32(1);
2396 eiter
->len
= cpu_to_be16(4 + 4);
2399 ql_dbg(ql_dbg_disc
, vha
, 0x20c8,
2400 "Number of ports = %x.\n", eiter
->a
.num_ports
);
2403 eiter
= entries
+ size
;
2404 eiter
->type
= cpu_to_be16(FDMI_PORT_ID
);
2405 eiter
->a
.port_id
= cpu_to_be32(vha
->d_id
.b24
);
2406 eiter
->len
= cpu_to_be16(4 + 4);
2409 ql_dbg(ql_dbg_disc
, vha
, 0x201c,
2410 "Port Id = %x.\n", eiter
->a
.port_id
);
2412 /* Update MS request size. */
2413 qla2x00_update_ms_fdmi_iocb(vha
, size
+ 16);
2415 ql_dbg(ql_dbg_disc
, vha
, 0x2018,
2416 "RPA portname= %8phN size=%d.\n", ct_req
->req
.rpa
.port_name
, size
);
2417 ql_dump_buffer(ql_dbg_disc
+ ql_dbg_buffer
, vha
, 0x20ca,
2420 /* Execute MS IOCB */
2421 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
2422 sizeof(ms_iocb_entry_t
));
2423 if (rval
!= QLA_SUCCESS
) {
2425 ql_dbg(ql_dbg_disc
, vha
, 0x20cb,
2426 "RPA FDMI v2 issue IOCB failed (%d).\n", rval
);
2427 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
, "RPA") !=
2429 rval
= QLA_FUNCTION_FAILED
;
2430 if (ct_rsp
->header
.reason_code
== CT_REASON_CANNOT_PERFORM
&&
2431 ct_rsp
->header
.explanation_code
==
2432 CT_EXPL_ALREADY_REGISTERED
) {
2433 ql_dbg(ql_dbg_disc
, vha
, 0x20ce,
2434 "RPA FDMI v2 already registered\n");
2435 rval
= QLA_ALREADY_REGISTERED
;
2437 ql_dbg(ql_dbg_disc
, vha
, 0x2020,
2438 "RPA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
2439 ct_rsp
->header
.reason_code
,
2440 ct_rsp
->header
.explanation_code
);
2443 ql_dbg(ql_dbg_disc
, vha
, 0x20cc,
2444 "RPA FDMI V2 exiting normally.\n");
2451 * qla2x00_fdmi_register() -
2454 * Returns 0 on success.
2457 qla2x00_fdmi_register(scsi_qla_host_t
*vha
)
2459 int rval
= QLA_FUNCTION_FAILED
;
2460 struct qla_hw_data
*ha
= vha
->hw
;
2462 if (IS_QLA2100(ha
) || IS_QLA2200(ha
) ||
2464 return QLA_FUNCTION_FAILED
;
2466 rval
= qla2x00_mgmt_svr_login(vha
);
2470 rval
= qla2x00_fdmiv2_rhba(vha
);
2472 if (rval
!= QLA_ALREADY_REGISTERED
)
2475 rval
= qla2x00_fdmi_dhba(vha
);
2479 rval
= qla2x00_fdmiv2_rhba(vha
);
2483 rval
= qla2x00_fdmiv2_rpa(vha
);
2490 rval
= qla2x00_fdmi_rhba(vha
);
2492 if (rval
!= QLA_ALREADY_REGISTERED
)
2495 rval
= qla2x00_fdmi_dhba(vha
);
2499 rval
= qla2x00_fdmi_rhba(vha
);
2503 rval
= qla2x00_fdmi_rpa(vha
);
2509 * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
2511 * @list: switch info entries to populate
2513 * Returns 0 on success.
2516 qla2x00_gfpn_id(scsi_qla_host_t
*vha
, sw_info_t
*list
)
2518 int rval
= QLA_SUCCESS
;
2520 struct qla_hw_data
*ha
= vha
->hw
;
2521 ms_iocb_entry_t
*ms_pkt
;
2522 struct ct_sns_req
*ct_req
;
2523 struct ct_sns_rsp
*ct_rsp
;
2526 if (!IS_IIDMA_CAPABLE(ha
))
2527 return QLA_FUNCTION_FAILED
;
2529 arg
.iocb
= ha
->ms_iocb
;
2530 arg
.req_dma
= ha
->ct_sns_dma
;
2531 arg
.rsp_dma
= ha
->ct_sns_dma
;
2532 arg
.req_size
= GFPN_ID_REQ_SIZE
;
2533 arg
.rsp_size
= GFPN_ID_RSP_SIZE
;
2534 arg
.nport_handle
= NPH_SNS
;
2536 for (i
= 0; i
< ha
->max_fibre_devices
; i
++) {
2538 /* Prepare common MS IOCB */
2539 ms_pkt
= ha
->isp_ops
->prep_ms_iocb(vha
, &arg
);
2541 /* Prepare CT request */
2542 ct_req
= qla2x00_prep_ct_req(ha
->ct_sns
, GFPN_ID_CMD
,
2544 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
2546 /* Prepare CT arguments -- port_id */
2547 ct_req
->req
.port_id
.port_id
[0] = list
[i
].d_id
.b
.domain
;
2548 ct_req
->req
.port_id
.port_id
[1] = list
[i
].d_id
.b
.area
;
2549 ct_req
->req
.port_id
.port_id
[2] = list
[i
].d_id
.b
.al_pa
;
2551 /* Execute MS IOCB */
2552 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
2553 sizeof(ms_iocb_entry_t
));
2554 if (rval
!= QLA_SUCCESS
) {
2556 ql_dbg(ql_dbg_disc
, vha
, 0x2023,
2557 "GFPN_ID issue IOCB failed (%d).\n", rval
);
2559 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
,
2560 "GFPN_ID") != QLA_SUCCESS
) {
2561 rval
= QLA_FUNCTION_FAILED
;
2564 /* Save fabric portname */
2565 memcpy(list
[i
].fabric_port_name
,
2566 ct_rsp
->rsp
.gfpn_id
.port_name
, WWN_SIZE
);
2569 /* Last device exit. */
2570 if (list
[i
].d_id
.b
.rsvd_1
!= 0)
2578 static inline struct ct_sns_req
*
2579 qla24xx_prep_ct_fm_req(struct ct_sns_pkt
*p
, uint16_t cmd
,
2582 memset(p
, 0, sizeof(struct ct_sns_pkt
));
2584 p
->p
.req
.header
.revision
= 0x01;
2585 p
->p
.req
.header
.gs_type
= 0xFA;
2586 p
->p
.req
.header
.gs_subtype
= 0x01;
2587 p
->p
.req
.command
= cpu_to_be16(cmd
);
2588 p
->p
.req
.max_rsp_size
= cpu_to_be16((rsp_size
- 16) / 4);
2594 * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
2596 * @list: switch info entries to populate
2598 * Returns 0 on success.
2601 qla2x00_gpsc(scsi_qla_host_t
*vha
, sw_info_t
*list
)
2605 struct qla_hw_data
*ha
= vha
->hw
;
2606 ms_iocb_entry_t
*ms_pkt
;
2607 struct ct_sns_req
*ct_req
;
2608 struct ct_sns_rsp
*ct_rsp
;
2611 if (!IS_IIDMA_CAPABLE(ha
))
2612 return QLA_FUNCTION_FAILED
;
2613 if (!ha
->flags
.gpsc_supported
)
2614 return QLA_FUNCTION_FAILED
;
2616 rval
= qla2x00_mgmt_svr_login(vha
);
2620 arg
.iocb
= ha
->ms_iocb
;
2621 arg
.req_dma
= ha
->ct_sns_dma
;
2622 arg
.rsp_dma
= ha
->ct_sns_dma
;
2623 arg
.req_size
= GPSC_REQ_SIZE
;
2624 arg
.rsp_size
= GPSC_RSP_SIZE
;
2625 arg
.nport_handle
= vha
->mgmt_svr_loop_id
;
2627 for (i
= 0; i
< ha
->max_fibre_devices
; i
++) {
2629 /* Prepare common MS IOCB */
2630 ms_pkt
= qla24xx_prep_ms_iocb(vha
, &arg
);
2632 /* Prepare CT request */
2633 ct_req
= qla24xx_prep_ct_fm_req(ha
->ct_sns
, GPSC_CMD
,
2635 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
2637 /* Prepare CT arguments -- port_name */
2638 memcpy(ct_req
->req
.gpsc
.port_name
, list
[i
].fabric_port_name
,
2641 /* Execute MS IOCB */
2642 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
2643 sizeof(ms_iocb_entry_t
));
2644 if (rval
!= QLA_SUCCESS
) {
2646 ql_dbg(ql_dbg_disc
, vha
, 0x2059,
2647 "GPSC issue IOCB failed (%d).\n", rval
);
2648 } else if ((rval
= qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
,
2649 "GPSC")) != QLA_SUCCESS
) {
2650 /* FM command unsupported? */
2651 if (rval
== QLA_INVALID_COMMAND
&&
2652 (ct_rsp
->header
.reason_code
==
2653 CT_REASON_INVALID_COMMAND_CODE
||
2654 ct_rsp
->header
.reason_code
==
2655 CT_REASON_COMMAND_UNSUPPORTED
)) {
2656 ql_dbg(ql_dbg_disc
, vha
, 0x205a,
2657 "GPSC command unsupported, disabling "
2659 ha
->flags
.gpsc_supported
= 0;
2660 rval
= QLA_FUNCTION_FAILED
;
2663 rval
= QLA_FUNCTION_FAILED
;
2665 /* Save port-speed */
2666 switch (be16_to_cpu(ct_rsp
->rsp
.gpsc
.speed
)) {
2668 list
[i
].fp_speed
= PORT_SPEED_1GB
;
2671 list
[i
].fp_speed
= PORT_SPEED_2GB
;
2674 list
[i
].fp_speed
= PORT_SPEED_4GB
;
2677 list
[i
].fp_speed
= PORT_SPEED_10GB
;
2680 list
[i
].fp_speed
= PORT_SPEED_8GB
;
2683 list
[i
].fp_speed
= PORT_SPEED_16GB
;
2686 list
[i
].fp_speed
= PORT_SPEED_32GB
;
2690 ql_dbg(ql_dbg_disc
, vha
, 0x205b,
2691 "GPSC ext entry - fpn "
2692 "%8phN speeds=%04x speed=%04x.\n",
2693 list
[i
].fabric_port_name
,
2694 be16_to_cpu(ct_rsp
->rsp
.gpsc
.speeds
),
2695 be16_to_cpu(ct_rsp
->rsp
.gpsc
.speed
));
2698 /* Last device exit. */
2699 if (list
[i
].d_id
.b
.rsvd_1
!= 0)
2707 * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
2710 * @list: switch info entries to populate
2714 qla2x00_gff_id(scsi_qla_host_t
*vha
, sw_info_t
*list
)
2719 ms_iocb_entry_t
*ms_pkt
;
2720 struct ct_sns_req
*ct_req
;
2721 struct ct_sns_rsp
*ct_rsp
;
2722 struct qla_hw_data
*ha
= vha
->hw
;
2723 uint8_t fcp_scsi_features
= 0;
2726 for (i
= 0; i
< ha
->max_fibre_devices
; i
++) {
2727 /* Set default FC4 Type as UNKNOWN so the default is to
2728 * Process this port */
2729 list
[i
].fc4_type
= FC4_TYPE_UNKNOWN
;
2731 /* Do not attempt GFF_ID if we are not FWI_2 capable */
2732 if (!IS_FWI2_CAPABLE(ha
))
2735 arg
.iocb
= ha
->ms_iocb
;
2736 arg
.req_dma
= ha
->ct_sns_dma
;
2737 arg
.rsp_dma
= ha
->ct_sns_dma
;
2738 arg
.req_size
= GFF_ID_REQ_SIZE
;
2739 arg
.rsp_size
= GFF_ID_RSP_SIZE
;
2740 arg
.nport_handle
= NPH_SNS
;
2742 /* Prepare common MS IOCB */
2743 ms_pkt
= ha
->isp_ops
->prep_ms_iocb(vha
, &arg
);
2745 /* Prepare CT request */
2746 ct_req
= qla2x00_prep_ct_req(ha
->ct_sns
, GFF_ID_CMD
,
2748 ct_rsp
= &ha
->ct_sns
->p
.rsp
;
2750 /* Prepare CT arguments -- port_id */
2751 ct_req
->req
.port_id
.port_id
[0] = list
[i
].d_id
.b
.domain
;
2752 ct_req
->req
.port_id
.port_id
[1] = list
[i
].d_id
.b
.area
;
2753 ct_req
->req
.port_id
.port_id
[2] = list
[i
].d_id
.b
.al_pa
;
2755 /* Execute MS IOCB */
2756 rval
= qla2x00_issue_iocb(vha
, ha
->ms_iocb
, ha
->ms_iocb_dma
,
2757 sizeof(ms_iocb_entry_t
));
2759 if (rval
!= QLA_SUCCESS
) {
2760 ql_dbg(ql_dbg_disc
, vha
, 0x205c,
2761 "GFF_ID issue IOCB failed (%d).\n", rval
);
2762 } else if (qla2x00_chk_ms_status(vha
, ms_pkt
, ct_rsp
,
2763 "GFF_ID") != QLA_SUCCESS
) {
2764 ql_dbg(ql_dbg_disc
, vha
, 0x205d,
2765 "GFF_ID IOCB status had a failure status code.\n");
2768 ct_rsp
->rsp
.gff_id
.fc4_features
[GFF_FCP_SCSI_OFFSET
];
2769 fcp_scsi_features
&= 0x0f;
2771 if (fcp_scsi_features
)
2772 list
[i
].fc4_type
= FC4_TYPE_FCP_SCSI
;
2774 list
[i
].fc4_type
= FC4_TYPE_OTHER
;
2777 ct_rsp
->rsp
.gff_id
.fc4_features
[GFF_NVME_OFFSET
];
2778 list
[i
].fc4f_nvme
&= 0xf;
2781 /* Last device exit. */
2782 if (list
[i
].d_id
.b
.rsvd_1
!= 0)
2787 /* GID_PN completion processing. */
2788 void qla24xx_handle_gidpn_event(scsi_qla_host_t
*vha
, struct event_arg
*ea
)
2790 fc_port_t
*fcport
= ea
->fcport
;
2792 ql_dbg(ql_dbg_disc
, vha
, 0x201d,
2793 "%s %8phC login state %d\n",
2794 __func__
, fcport
->port_name
, fcport
->fw_login_state
);
2796 if (ea
->sp
->gen2
!= fcport
->login_gen
) {
2797 /* PLOGI/PRLI/LOGO came in while cmd was out.*/
2798 ql_dbg(ql_dbg_disc
, vha
, 0x201e,
2799 "%s %8phC generation changed rscn %d|%d login %d|%d \n",
2800 __func__
, fcport
->port_name
, fcport
->last_rscn_gen
,
2801 fcport
->rscn_gen
, fcport
->last_login_gen
, fcport
->login_gen
);
2806 if (ea
->sp
->gen1
== fcport
->rscn_gen
) {
2807 fcport
->scan_state
= QLA_FCPORT_FOUND
;
2808 fcport
->flags
|= FCF_FABRIC_DEVICE
;
2810 if (fcport
->d_id
.b24
== ea
->id
.b24
) {
2811 /* cable plugged into the same place */
2812 switch (vha
->host
->active_mode
) {
2814 /* NOOP. let the other guy login to us.*/
2816 case MODE_INITIATOR
:
2819 if (atomic_read(&fcport
->state
) ==
2822 ql_dbg(ql_dbg_disc
, vha
, 0x201f,
2823 "%s %d %8phC post gnl\n",
2824 __func__
, __LINE__
, fcport
->port_name
);
2825 qla24xx_post_gnl_work(vha
, fcport
);
2828 } else { /* fcport->d_id.b24 != ea->id.b24 */
2829 fcport
->d_id
.b24
= ea
->id
.b24
;
2830 if (fcport
->deleted
== QLA_SESS_DELETED
) {
2831 ql_dbg(ql_dbg_disc
, vha
, 0x2021,
2832 "%s %d %8phC post del sess\n",
2833 __func__
, __LINE__
, fcport
->port_name
);
2834 qlt_schedule_sess_for_deletion_lock(fcport
);
2837 } else { /* ea->sp->gen1 != fcport->rscn_gen */
2838 ql_dbg(ql_dbg_disc
, vha
, 0x2022,
2839 "%s %d %8phC post gidpn\n",
2840 __func__
, __LINE__
, fcport
->port_name
);
2841 /* rscn came in while cmd was out */
2842 qla24xx_post_gidpn_work(vha
, fcport
);
2844 } else { /* ea->rc */
2846 if (ea
->sp
->gen1
== fcport
->rscn_gen
) {
2847 if (ea
->sp
->gen2
== fcport
->login_gen
) {
2848 ql_dbg(ql_dbg_disc
, vha
, 0x2042,
2849 "%s %d %8phC post del sess\n", __func__
,
2850 __LINE__
, fcport
->port_name
);
2851 qlt_schedule_sess_for_deletion_lock(fcport
);
2853 ql_dbg(ql_dbg_disc
, vha
, 0x2045,
2854 "%s %d %8phC login\n", __func__
, __LINE__
,
2856 qla24xx_fcport_handle_login(vha
, fcport
);
2859 ql_dbg(ql_dbg_disc
, vha
, 0x2049,
2860 "%s %d %8phC post gidpn\n", __func__
, __LINE__
,
2862 qla24xx_post_gidpn_work(vha
, fcport
);
2867 static void qla2x00_async_gidpn_sp_done(void *s
, int res
)
2870 struct scsi_qla_host
*vha
= sp
->vha
;
2871 fc_port_t
*fcport
= sp
->fcport
;
2872 u8
*id
= fcport
->ct_desc
.ct_sns
->p
.rsp
.rsp
.gid_pn
.port_id
;
2873 struct event_arg ea
;
2875 fcport
->flags
&= ~FCF_ASYNC_SENT
;
2877 memset(&ea
, 0, sizeof(ea
));
2879 ea
.id
.b
.domain
= id
[0];
2880 ea
.id
.b
.area
= id
[1];
2881 ea
.id
.b
.al_pa
= id
[2];
2884 ea
.event
= FCME_GIDPN_DONE
;
2886 ql_dbg(ql_dbg_disc
, vha
, 0x204f,
2887 "Async done-%s res %x, WWPN %8phC ID %3phC \n",
2888 sp
->name
, res
, fcport
->port_name
, id
);
2890 qla2x00_fcport_event_handler(vha
, &ea
);
2895 int qla24xx_async_gidpn(scsi_qla_host_t
*vha
, fc_port_t
*fcport
)
2897 int rval
= QLA_FUNCTION_FAILED
;
2898 struct ct_sns_req
*ct_req
;
2901 if (!vha
->flags
.online
)
2904 fcport
->flags
|= FCF_ASYNC_SENT
;
2905 fcport
->disc_state
= DSC_GID_PN
;
2906 fcport
->scan_state
= QLA_FCPORT_SCAN
;
2907 sp
= qla2x00_get_sp(vha
, fcport
, GFP_ATOMIC
);
2911 sp
->type
= SRB_CT_PTHRU_CMD
;
2913 sp
->gen1
= fcport
->rscn_gen
;
2914 sp
->gen2
= fcport
->login_gen
;
2916 qla2x00_init_timer(sp
, qla2x00_get_async_timeout(vha
) + 2);
2918 /* CT_IU preamble */
2919 ct_req
= qla2x00_prep_ct_req(fcport
->ct_desc
.ct_sns
, GID_PN_CMD
,
2923 memcpy(ct_req
->req
.gid_pn
.port_name
, fcport
->port_name
,
2926 /* req & rsp use the same buffer */
2927 sp
->u
.iocb_cmd
.u
.ctarg
.req
= fcport
->ct_desc
.ct_sns
;
2928 sp
->u
.iocb_cmd
.u
.ctarg
.req_dma
= fcport
->ct_desc
.ct_sns_dma
;
2929 sp
->u
.iocb_cmd
.u
.ctarg
.rsp
= fcport
->ct_desc
.ct_sns
;
2930 sp
->u
.iocb_cmd
.u
.ctarg
.rsp_dma
= fcport
->ct_desc
.ct_sns_dma
;
2931 sp
->u
.iocb_cmd
.u
.ctarg
.req_size
= GID_PN_REQ_SIZE
;
2932 sp
->u
.iocb_cmd
.u
.ctarg
.rsp_size
= GID_PN_RSP_SIZE
;
2933 sp
->u
.iocb_cmd
.u
.ctarg
.nport_handle
= NPH_SNS
;
2935 sp
->u
.iocb_cmd
.timeout
= qla2x00_async_iocb_timeout
;
2936 sp
->done
= qla2x00_async_gidpn_sp_done
;
2938 rval
= qla2x00_start_sp(sp
);
2939 if (rval
!= QLA_SUCCESS
)
2942 ql_dbg(ql_dbg_disc
, vha
, 0x20a4,
2943 "Async-%s - %8phC hdl=%x loopid=%x portid %02x%02x%02x.\n",
2944 sp
->name
, fcport
->port_name
,
2945 sp
->handle
, fcport
->loop_id
, fcport
->d_id
.b
.domain
,
2946 fcport
->d_id
.b
.area
, fcport
->d_id
.b
.al_pa
);
2952 fcport
->flags
&= ~FCF_ASYNC_SENT
;
2956 int qla24xx_post_gidpn_work(struct scsi_qla_host
*vha
, fc_port_t
*fcport
)
2958 struct qla_work_evt
*e
;
2961 ls
= atomic_read(&vha
->loop_state
);
2962 if (((ls
!= LOOP_READY
) && (ls
!= LOOP_UP
)) ||
2963 test_bit(UNLOADING
, &vha
->dpc_flags
))
2966 e
= qla2x00_alloc_work(vha
, QLA_EVT_GIDPN
);
2968 return QLA_FUNCTION_FAILED
;
2970 e
->u
.fcport
.fcport
= fcport
;
2971 return qla2x00_post_work(vha
, e
);
2974 int qla24xx_post_gpsc_work(struct scsi_qla_host
*vha
, fc_port_t
*fcport
)
2976 struct qla_work_evt
*e
;
2978 e
= qla2x00_alloc_work(vha
, QLA_EVT_GPSC
);
2980 return QLA_FUNCTION_FAILED
;
2982 e
->u
.fcport
.fcport
= fcport
;
2983 return qla2x00_post_work(vha
, e
);
2986 static void qla24xx_async_gpsc_sp_done(void *s
, int res
)
2989 struct scsi_qla_host
*vha
= sp
->vha
;
2990 struct qla_hw_data
*ha
= vha
->hw
;
2991 fc_port_t
*fcport
= sp
->fcport
;
2992 struct ct_sns_rsp
*ct_rsp
;
2993 struct event_arg ea
;
2995 ct_rsp
= &fcport
->ct_desc
.ct_sns
->p
.rsp
;
2997 ql_dbg(ql_dbg_disc
, vha
, 0x2053,
2998 "Async done-%s res %x, WWPN %8phC \n",
2999 sp
->name
, res
, fcport
->port_name
);
3001 fcport
->flags
&= ~FCF_ASYNC_SENT
;
3003 if (res
== (DID_ERROR
<< 16)) {
3004 /* entry status error */
3007 if ((ct_rsp
->header
.reason_code
==
3008 CT_REASON_INVALID_COMMAND_CODE
) ||
3009 (ct_rsp
->header
.reason_code
==
3010 CT_REASON_COMMAND_UNSUPPORTED
)) {
3011 ql_dbg(ql_dbg_disc
, vha
, 0x2019,
3012 "GPSC command unsupported, disabling query.\n");
3013 ha
->flags
.gpsc_supported
= 0;
3017 switch (be16_to_cpu(ct_rsp
->rsp
.gpsc
.speed
)) {
3019 fcport
->fp_speed
= PORT_SPEED_1GB
;
3022 fcport
->fp_speed
= PORT_SPEED_2GB
;
3025 fcport
->fp_speed
= PORT_SPEED_4GB
;
3028 fcport
->fp_speed
= PORT_SPEED_10GB
;
3031 fcport
->fp_speed
= PORT_SPEED_8GB
;
3034 fcport
->fp_speed
= PORT_SPEED_16GB
;
3037 fcport
->fp_speed
= PORT_SPEED_32GB
;
3041 ql_dbg(ql_dbg_disc
, vha
, 0x2054,
3042 "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n",
3043 sp
->name
, fcport
->fabric_port_name
,
3044 be16_to_cpu(ct_rsp
->rsp
.gpsc
.speeds
),
3045 be16_to_cpu(ct_rsp
->rsp
.gpsc
.speed
));
3048 memset(&ea
, 0, sizeof(ea
));
3049 ea
.event
= FCME_GPSC_DONE
;
3052 qla2x00_fcport_event_handler(vha
, &ea
);
3057 int qla24xx_async_gpsc(scsi_qla_host_t
*vha
, fc_port_t
*fcport
)
3059 int rval
= QLA_FUNCTION_FAILED
;
3060 struct ct_sns_req
*ct_req
;
3063 if (!vha
->flags
.online
)
3066 fcport
->flags
|= FCF_ASYNC_SENT
;
3067 sp
= qla2x00_get_sp(vha
, fcport
, GFP_KERNEL
);
3071 sp
->type
= SRB_CT_PTHRU_CMD
;
3073 sp
->gen1
= fcport
->rscn_gen
;
3074 sp
->gen2
= fcport
->login_gen
;
3076 qla2x00_init_timer(sp
, qla2x00_get_async_timeout(vha
) + 2);
3078 /* CT_IU preamble */
3079 ct_req
= qla24xx_prep_ct_fm_req(fcport
->ct_desc
.ct_sns
, GPSC_CMD
,
3083 memcpy(ct_req
->req
.gpsc
.port_name
, fcport
->port_name
,
3086 sp
->u
.iocb_cmd
.u
.ctarg
.req
= fcport
->ct_desc
.ct_sns
;
3087 sp
->u
.iocb_cmd
.u
.ctarg
.req_dma
= fcport
->ct_desc
.ct_sns_dma
;
3088 sp
->u
.iocb_cmd
.u
.ctarg
.rsp
= fcport
->ct_desc
.ct_sns
;
3089 sp
->u
.iocb_cmd
.u
.ctarg
.rsp_dma
= fcport
->ct_desc
.ct_sns_dma
;
3090 sp
->u
.iocb_cmd
.u
.ctarg
.req_size
= GPSC_REQ_SIZE
;
3091 sp
->u
.iocb_cmd
.u
.ctarg
.rsp_size
= GPSC_RSP_SIZE
;
3092 sp
->u
.iocb_cmd
.u
.ctarg
.nport_handle
= vha
->mgmt_svr_loop_id
;
3094 sp
->u
.iocb_cmd
.timeout
= qla2x00_async_iocb_timeout
;
3095 sp
->done
= qla24xx_async_gpsc_sp_done
;
3097 rval
= qla2x00_start_sp(sp
);
3098 if (rval
!= QLA_SUCCESS
)
3101 ql_dbg(ql_dbg_disc
, vha
, 0x205e,
3102 "Async-%s %8phC hdl=%x loopid=%x portid=%02x%02x%02x.\n",
3103 sp
->name
, fcport
->port_name
, sp
->handle
,
3104 fcport
->loop_id
, fcport
->d_id
.b
.domain
,
3105 fcport
->d_id
.b
.area
, fcport
->d_id
.b
.al_pa
);
3111 fcport
->flags
&= ~FCF_ASYNC_SENT
;
3115 int qla24xx_post_gpnid_work(struct scsi_qla_host
*vha
, port_id_t
*id
)
3117 struct qla_work_evt
*e
;
3119 if (test_bit(UNLOADING
, &vha
->dpc_flags
))
3122 e
= qla2x00_alloc_work(vha
, QLA_EVT_GPNID
);
3124 return QLA_FUNCTION_FAILED
;
3126 e
->u
.gpnid
.id
= *id
;
3127 return qla2x00_post_work(vha
, e
);
3130 void qla24xx_async_gpnid_done(scsi_qla_host_t
*vha
, srb_t
*sp
)
3132 if (sp
->u
.iocb_cmd
.u
.ctarg
.req
) {
3133 dma_free_coherent(&vha
->hw
->pdev
->dev
,
3134 sizeof(struct ct_sns_pkt
),
3135 sp
->u
.iocb_cmd
.u
.ctarg
.req
,
3136 sp
->u
.iocb_cmd
.u
.ctarg
.req_dma
);
3137 sp
->u
.iocb_cmd
.u
.ctarg
.req
= NULL
;
3139 if (sp
->u
.iocb_cmd
.u
.ctarg
.rsp
) {
3140 dma_free_coherent(&vha
->hw
->pdev
->dev
,
3141 sizeof(struct ct_sns_pkt
),
3142 sp
->u
.iocb_cmd
.u
.ctarg
.rsp
,
3143 sp
->u
.iocb_cmd
.u
.ctarg
.rsp_dma
);
3144 sp
->u
.iocb_cmd
.u
.ctarg
.rsp
= NULL
;
3150 void qla24xx_handle_gpnid_event(scsi_qla_host_t
*vha
, struct event_arg
*ea
)
3153 unsigned long flags
;
3155 spin_lock_irqsave(&vha
->hw
->tgt
.sess_lock
, flags
);
3156 fcport
= qla2x00_find_fcport_by_wwpn(vha
, ea
->port_name
, 1);
3157 spin_unlock_irqrestore(&vha
->hw
->tgt
.sess_lock
, flags
);
3160 /* cable moved. just plugged in */
3162 fcport
->d_id
= ea
->id
;
3163 fcport
->scan_state
= QLA_FCPORT_FOUND
;
3164 fcport
->flags
|= FCF_FABRIC_DEVICE
;
3166 switch (fcport
->disc_state
) {
3168 ql_dbg(ql_dbg_disc
, vha
, 0x210d,
3169 "%s %d %8phC login\n", __func__
, __LINE__
,
3171 qla24xx_fcport_handle_login(vha
, fcport
);
3173 case DSC_DELETE_PEND
:
3176 ql_dbg(ql_dbg_disc
, vha
, 0x2064,
3177 "%s %d %8phC post del sess\n",
3178 __func__
, __LINE__
, fcport
->port_name
);
3179 qlt_schedule_sess_for_deletion_lock(fcport
);
3183 /* create new fcport */
3184 ql_dbg(ql_dbg_disc
, vha
, 0x2065,
3185 "%s %d %8phC post new sess\n",
3186 __func__
, __LINE__
, ea
->port_name
);
3188 qla24xx_post_newsess_work(vha
, &ea
->id
, ea
->port_name
, NULL
);
3192 static void qla2x00_async_gpnid_sp_done(void *s
, int res
)
3195 struct scsi_qla_host
*vha
= sp
->vha
;
3196 struct ct_sns_req
*ct_req
=
3197 (struct ct_sns_req
*)sp
->u
.iocb_cmd
.u
.ctarg
.req
;
3198 struct ct_sns_rsp
*ct_rsp
=
3199 (struct ct_sns_rsp
*)sp
->u
.iocb_cmd
.u
.ctarg
.rsp
;
3200 struct event_arg ea
;
3201 struct qla_work_evt
*e
;
3203 ql_dbg(ql_dbg_disc
, vha
, 0x2066,
3204 "Async done-%s res %x ID %3phC. %8phC\n",
3205 sp
->name
, res
, ct_req
->req
.port_id
.port_id
,
3206 ct_rsp
->rsp
.gpn_id
.port_name
);
3208 memset(&ea
, 0, sizeof(ea
));
3209 memcpy(ea
.port_name
, ct_rsp
->rsp
.gpn_id
.port_name
, WWN_SIZE
);
3211 ea
.id
.b
.domain
= ct_req
->req
.port_id
.port_id
[0];
3212 ea
.id
.b
.area
= ct_req
->req
.port_id
.port_id
[1];
3213 ea
.id
.b
.al_pa
= ct_req
->req
.port_id
.port_id
[2];
3215 ea
.event
= FCME_GPNID_DONE
;
3217 qla2x00_fcport_event_handler(vha
, &ea
);
3219 e
= qla2x00_alloc_work(vha
, QLA_EVT_GPNID_DONE
);
3221 /* please ignore kernel warning. otherwise, we have mem leak. */
3222 if (sp
->u
.iocb_cmd
.u
.ctarg
.req
) {
3223 dma_free_coherent(&vha
->hw
->pdev
->dev
,
3224 sizeof(struct ct_sns_pkt
),
3225 sp
->u
.iocb_cmd
.u
.ctarg
.req
,
3226 sp
->u
.iocb_cmd
.u
.ctarg
.req_dma
);
3227 sp
->u
.iocb_cmd
.u
.ctarg
.req
= NULL
;
3229 if (sp
->u
.iocb_cmd
.u
.ctarg
.rsp
) {
3230 dma_free_coherent(&vha
->hw
->pdev
->dev
,
3231 sizeof(struct ct_sns_pkt
),
3232 sp
->u
.iocb_cmd
.u
.ctarg
.rsp
,
3233 sp
->u
.iocb_cmd
.u
.ctarg
.rsp_dma
);
3234 sp
->u
.iocb_cmd
.u
.ctarg
.rsp
= NULL
;
3242 qla2x00_post_work(vha
, e
);
3245 /* Get WWPN with Nport ID. */
3246 int qla24xx_async_gpnid(scsi_qla_host_t
*vha
, port_id_t
*id
)
3248 int rval
= QLA_FUNCTION_FAILED
;
3249 struct ct_sns_req
*ct_req
;
3251 struct ct_sns_pkt
*ct_sns
;
3253 if (!vha
->flags
.online
)
3256 sp
= qla2x00_get_sp(vha
, NULL
, GFP_KERNEL
);
3260 sp
->type
= SRB_CT_PTHRU_CMD
;
3262 qla2x00_init_timer(sp
, qla2x00_get_async_timeout(vha
) + 2);
3264 sp
->u
.iocb_cmd
.u
.ctarg
.req
= dma_alloc_coherent(&vha
->hw
->pdev
->dev
,
3265 sizeof(struct ct_sns_pkt
), &sp
->u
.iocb_cmd
.u
.ctarg
.req_dma
,
3267 if (!sp
->u
.iocb_cmd
.u
.ctarg
.req
) {
3268 ql_log(ql_log_warn
, vha
, 0xd041,
3269 "Failed to allocate ct_sns request.\n");
3273 sp
->u
.iocb_cmd
.u
.ctarg
.rsp
= dma_alloc_coherent(&vha
->hw
->pdev
->dev
,
3274 sizeof(struct ct_sns_pkt
), &sp
->u
.iocb_cmd
.u
.ctarg
.rsp_dma
,
3276 if (!sp
->u
.iocb_cmd
.u
.ctarg
.rsp
) {
3277 ql_log(ql_log_warn
, vha
, 0xd042,
3278 "Failed to allocate ct_sns request.\n");
3282 ct_sns
= (struct ct_sns_pkt
*)sp
->u
.iocb_cmd
.u
.ctarg
.rsp
;
3283 memset(ct_sns
, 0, sizeof(*ct_sns
));
3285 ct_sns
= (struct ct_sns_pkt
*)sp
->u
.iocb_cmd
.u
.ctarg
.req
;
3286 /* CT_IU preamble */
3287 ct_req
= qla2x00_prep_ct_req(ct_sns
, GPN_ID_CMD
, GPN_ID_RSP_SIZE
);
3290 ct_req
->req
.port_id
.port_id
[0] = id
->b
.domain
;
3291 ct_req
->req
.port_id
.port_id
[1] = id
->b
.area
;
3292 ct_req
->req
.port_id
.port_id
[2] = id
->b
.al_pa
;
3294 sp
->u
.iocb_cmd
.u
.ctarg
.req_size
= GPN_ID_REQ_SIZE
;
3295 sp
->u
.iocb_cmd
.u
.ctarg
.rsp_size
= GPN_ID_RSP_SIZE
;
3296 sp
->u
.iocb_cmd
.u
.ctarg
.nport_handle
= NPH_SNS
;
3298 sp
->u
.iocb_cmd
.timeout
= qla2x00_async_iocb_timeout
;
3299 sp
->done
= qla2x00_async_gpnid_sp_done
;
3301 rval
= qla2x00_start_sp(sp
);
3302 if (rval
!= QLA_SUCCESS
)
3305 ql_dbg(ql_dbg_disc
, vha
, 0x2067,
3306 "Async-%s hdl=%x ID %3phC.\n", sp
->name
,
3307 sp
->handle
, ct_req
->req
.port_id
.port_id
);
3311 if (sp
->u
.iocb_cmd
.u
.ctarg
.req
) {
3312 dma_free_coherent(&vha
->hw
->pdev
->dev
,
3313 sizeof(struct ct_sns_pkt
),
3314 sp
->u
.iocb_cmd
.u
.ctarg
.req
,
3315 sp
->u
.iocb_cmd
.u
.ctarg
.req_dma
);
3316 sp
->u
.iocb_cmd
.u
.ctarg
.req
= NULL
;
3318 if (sp
->u
.iocb_cmd
.u
.ctarg
.rsp
) {
3319 dma_free_coherent(&vha
->hw
->pdev
->dev
,
3320 sizeof(struct ct_sns_pkt
),
3321 sp
->u
.iocb_cmd
.u
.ctarg
.rsp
,
3322 sp
->u
.iocb_cmd
.u
.ctarg
.rsp_dma
);
3323 sp
->u
.iocb_cmd
.u
.ctarg
.rsp
= NULL
;
3331 void qla24xx_handle_gffid_event(scsi_qla_host_t
*vha
, struct event_arg
*ea
)
3333 fc_port_t
*fcport
= ea
->fcport
;
3335 qla24xx_post_gnl_work(vha
, fcport
);
3338 void qla24xx_async_gffid_sp_done(void *s
, int res
)
3341 struct scsi_qla_host
*vha
= sp
->vha
;
3342 fc_port_t
*fcport
= sp
->fcport
;
3343 struct ct_sns_rsp
*ct_rsp
;
3344 struct event_arg ea
;
3346 ql_dbg(ql_dbg_disc
, vha
, 0x2133,
3347 "Async done-%s res %x ID %x. %8phC\n",
3348 sp
->name
, res
, fcport
->d_id
.b24
, fcport
->port_name
);
3350 fcport
->flags
&= ~FCF_ASYNC_SENT
;
3351 ct_rsp
= &fcport
->ct_desc
.ct_sns
->p
.rsp
;
3353 * FC-GS-7, 5.2.3.12 FC-4 Features - format
3354 * The format of the FC-4 Features object, as defined by the FC-4,
3355 * Shall be an array of 4-bit values, one for each type code value
3358 if (ct_rsp
->rsp
.gff_id
.fc4_features
[GFF_FCP_SCSI_OFFSET
] & 0xf) {
3361 ct_rsp
->rsp
.gff_id
.fc4_features
[GFF_FCP_SCSI_OFFSET
];
3362 fcport
->fc4_type
&= 0xf;
3365 if (ct_rsp
->rsp
.gff_id
.fc4_features
[GFF_NVME_OFFSET
] & 0xf) {
3366 /* w5 [00:03]/28h */
3368 ct_rsp
->rsp
.gff_id
.fc4_features
[GFF_NVME_OFFSET
];
3369 fcport
->fc4f_nvme
&= 0xf;
3373 memset(&ea
, 0, sizeof(ea
));
3375 ea
.fcport
= sp
->fcport
;
3377 ea
.event
= FCME_GFFID_DONE
;
3379 qla2x00_fcport_event_handler(vha
, &ea
);
3383 /* Get FC4 Feature with Nport ID. */
3384 int qla24xx_async_gffid(scsi_qla_host_t
*vha
, fc_port_t
*fcport
)
3386 int rval
= QLA_FUNCTION_FAILED
;
3387 struct ct_sns_req
*ct_req
;
3390 if (!vha
->flags
.online
)
3393 sp
= qla2x00_get_sp(vha
, fcport
, GFP_KERNEL
);
3397 fcport
->flags
|= FCF_ASYNC_SENT
;
3398 sp
->type
= SRB_CT_PTHRU_CMD
;
3400 sp
->gen1
= fcport
->rscn_gen
;
3401 sp
->gen2
= fcport
->login_gen
;
3403 qla2x00_init_timer(sp
, qla2x00_get_async_timeout(vha
) + 2);
3405 /* CT_IU preamble */
3406 ct_req
= qla2x00_prep_ct_req(fcport
->ct_desc
.ct_sns
, GFF_ID_CMD
,
3409 ct_req
->req
.gff_id
.port_id
[0] = fcport
->d_id
.b
.domain
;
3410 ct_req
->req
.gff_id
.port_id
[1] = fcport
->d_id
.b
.area
;
3411 ct_req
->req
.gff_id
.port_id
[2] = fcport
->d_id
.b
.al_pa
;
3413 sp
->u
.iocb_cmd
.u
.ctarg
.req
= fcport
->ct_desc
.ct_sns
;
3414 sp
->u
.iocb_cmd
.u
.ctarg
.req_dma
= fcport
->ct_desc
.ct_sns_dma
;
3415 sp
->u
.iocb_cmd
.u
.ctarg
.rsp
= fcport
->ct_desc
.ct_sns
;
3416 sp
->u
.iocb_cmd
.u
.ctarg
.rsp_dma
= fcport
->ct_desc
.ct_sns_dma
;
3417 sp
->u
.iocb_cmd
.u
.ctarg
.req_size
= GFF_ID_REQ_SIZE
;
3418 sp
->u
.iocb_cmd
.u
.ctarg
.rsp_size
= GFF_ID_RSP_SIZE
;
3419 sp
->u
.iocb_cmd
.u
.ctarg
.nport_handle
= NPH_SNS
;
3421 sp
->u
.iocb_cmd
.timeout
= qla2x00_async_iocb_timeout
;
3422 sp
->done
= qla24xx_async_gffid_sp_done
;
3424 rval
= qla2x00_start_sp(sp
);
3425 if (rval
!= QLA_SUCCESS
)
3428 ql_dbg(ql_dbg_disc
, vha
, 0x2132,
3429 "Async-%s hdl=%x %8phC.\n", sp
->name
,
3430 sp
->handle
, fcport
->port_name
);
3435 fcport
->flags
&= ~FCF_ASYNC_SENT
;