1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
4 * Copyright (c) 2014- QLogic Corporation.
8 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
11 * fcbuild.c - FC link service frame building and parsing routines
15 #include "bfa_fcbuild.h"
18 * static build functions
20 static void fc_els_rsp_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
,
22 static void fc_bls_rsp_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
,
24 static struct fchs_s fc_els_req_tmpl
;
25 static struct fchs_s fc_els_rsp_tmpl
;
26 static struct fchs_s fc_bls_req_tmpl
;
27 static struct fchs_s fc_bls_rsp_tmpl
;
28 static struct fc_ba_acc_s ba_acc_tmpl
;
29 static struct fc_logi_s plogi_tmpl
;
30 static struct fc_prli_s prli_tmpl
;
31 static struct fc_rrq_s rrq_tmpl
;
32 static struct fchs_s fcp_fchs_tmpl
;
40 fc_els_req_tmpl
.routing
= FC_RTG_EXT_LINK
;
41 fc_els_req_tmpl
.cat_info
= FC_CAT_LD_REQUEST
;
42 fc_els_req_tmpl
.type
= FC_TYPE_ELS
;
43 fc_els_req_tmpl
.f_ctl
=
44 bfa_hton3b(FCTL_SEQ_INI
| FCTL_FS_EXCH
| FCTL_END_SEQ
|
46 fc_els_req_tmpl
.rx_id
= FC_RXID_ANY
;
51 fc_els_rsp_tmpl
.routing
= FC_RTG_EXT_LINK
;
52 fc_els_rsp_tmpl
.cat_info
= FC_CAT_LD_REPLY
;
53 fc_els_rsp_tmpl
.type
= FC_TYPE_ELS
;
54 fc_els_rsp_tmpl
.f_ctl
=
55 bfa_hton3b(FCTL_EC_RESP
| FCTL_SEQ_INI
| FCTL_LS_EXCH
|
56 FCTL_END_SEQ
| FCTL_SI_XFER
);
57 fc_els_rsp_tmpl
.rx_id
= FC_RXID_ANY
;
62 fc_bls_req_tmpl
.routing
= FC_RTG_BASIC_LINK
;
63 fc_bls_req_tmpl
.type
= FC_TYPE_BLS
;
64 fc_bls_req_tmpl
.f_ctl
= bfa_hton3b(FCTL_END_SEQ
| FCTL_SI_XFER
);
65 fc_bls_req_tmpl
.rx_id
= FC_RXID_ANY
;
70 fc_bls_rsp_tmpl
.routing
= FC_RTG_BASIC_LINK
;
71 fc_bls_rsp_tmpl
.cat_info
= FC_CAT_BA_ACC
;
72 fc_bls_rsp_tmpl
.type
= FC_TYPE_BLS
;
73 fc_bls_rsp_tmpl
.f_ctl
=
74 bfa_hton3b(FCTL_EC_RESP
| FCTL_SEQ_INI
| FCTL_LS_EXCH
|
75 FCTL_END_SEQ
| FCTL_SI_XFER
);
76 fc_bls_rsp_tmpl
.rx_id
= FC_RXID_ANY
;
81 ba_acc_tmpl
.seq_id_valid
= 0;
82 ba_acc_tmpl
.low_seq_cnt
= 0;
83 ba_acc_tmpl
.high_seq_cnt
= 0xFFFF;
88 plogi_tmpl
.csp
.verhi
= FC_PH_VER_PH_3
;
89 plogi_tmpl
.csp
.verlo
= FC_PH_VER_4_3
;
90 plogi_tmpl
.csp
.ciro
= 0x1;
91 plogi_tmpl
.csp
.cisc
= 0x0;
92 plogi_tmpl
.csp
.altbbcred
= 0x0;
93 plogi_tmpl
.csp
.conseq
= cpu_to_be16(0x00FF);
94 plogi_tmpl
.csp
.ro_bitmap
= cpu_to_be16(0x0002);
95 plogi_tmpl
.csp
.e_d_tov
= cpu_to_be32(2000);
97 plogi_tmpl
.class3
.class_valid
= 1;
98 plogi_tmpl
.class3
.sequential
= 1;
99 plogi_tmpl
.class3
.conseq
= 0xFF;
100 plogi_tmpl
.class3
.ospx
= 1;
105 prli_tmpl
.command
= FC_ELS_PRLI
;
106 prli_tmpl
.pglen
= 0x10;
107 prli_tmpl
.pagebytes
= cpu_to_be16(0x0014);
108 prli_tmpl
.parampage
.type
= FC_TYPE_FCP
;
109 prli_tmpl
.parampage
.imagepair
= 1;
110 prli_tmpl
.parampage
.servparams
.rxrdisab
= 1;
115 rrq_tmpl
.els_cmd
.els_code
= FC_ELS_RRQ
;
118 * fcp_struct fchs_s mpl
120 fcp_fchs_tmpl
.routing
= FC_RTG_FC4_DEV_DATA
;
121 fcp_fchs_tmpl
.cat_info
= FC_CAT_UNSOLICIT_CMD
;
122 fcp_fchs_tmpl
.type
= FC_TYPE_FCP
;
123 fcp_fchs_tmpl
.f_ctl
=
124 bfa_hton3b(FCTL_FS_EXCH
| FCTL_END_SEQ
| FCTL_SI_XFER
);
125 fcp_fchs_tmpl
.seq_id
= 1;
126 fcp_fchs_tmpl
.rx_id
= FC_RXID_ANY
;
130 fc_gs_fchdr_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
, u32 ox_id
)
132 memset(fchs
, 0, sizeof(struct fchs_s
));
134 fchs
->routing
= FC_RTG_FC4_DEV_DATA
;
135 fchs
->cat_info
= FC_CAT_UNSOLICIT_CTRL
;
136 fchs
->type
= FC_TYPE_SERVICES
;
138 bfa_hton3b(FCTL_SEQ_INI
| FCTL_FS_EXCH
| FCTL_END_SEQ
|
140 fchs
->rx_id
= FC_RXID_ANY
;
143 fchs
->ox_id
= cpu_to_be16(ox_id
);
146 * @todo no need to set ox_id for request
147 * no need to set rx_id for response
152 fc_gsresp_fchdr_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
, u16 ox_id
)
154 memset(fchs
, 0, sizeof(struct fchs_s
));
156 fchs
->routing
= FC_RTG_FC4_DEV_DATA
;
157 fchs
->cat_info
= FC_CAT_SOLICIT_CTRL
;
158 fchs
->type
= FC_TYPE_SERVICES
;
160 bfa_hton3b(FCTL_EC_RESP
| FCTL_SEQ_INI
| FCTL_LS_EXCH
|
161 FCTL_END_SEQ
| FCTL_SI_XFER
);
168 fc_els_req_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
, __be16 ox_id
)
170 memcpy(fchs
, &fc_els_req_tmpl
, sizeof(struct fchs_s
));
173 fchs
->ox_id
= cpu_to_be16(ox_id
);
177 fc_els_rsp_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
, __be16 ox_id
)
179 memcpy(fchs
, &fc_els_rsp_tmpl
, sizeof(struct fchs_s
));
186 fc_bls_rsp_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
, __be16 ox_id
)
188 memcpy(fchs
, &fc_bls_rsp_tmpl
, sizeof(struct fchs_s
));
195 fc_plogi_x_build(struct fchs_s
*fchs
, void *pld
, u32 d_id
, u32 s_id
,
196 __be16 ox_id
, wwn_t port_name
, wwn_t node_name
,
197 u16 pdu_size
, u16 bb_cr
, u8 els_code
)
199 struct fc_logi_s
*plogi
= (struct fc_logi_s
*) (pld
);
201 memcpy(plogi
, &plogi_tmpl
, sizeof(struct fc_logi_s
));
203 /* For FC AL bb_cr is 0 and altbbcred is 1 */
205 plogi
->csp
.altbbcred
= 1;
207 plogi
->els_cmd
.els_code
= els_code
;
208 if (els_code
== FC_ELS_PLOGI
)
209 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
211 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
213 plogi
->csp
.rxsz
= plogi
->class3
.rxsz
= cpu_to_be16(pdu_size
);
214 plogi
->csp
.bbcred
= cpu_to_be16(bb_cr
);
216 memcpy(&plogi
->port_name
, &port_name
, sizeof(wwn_t
));
217 memcpy(&plogi
->node_name
, &node_name
, sizeof(wwn_t
));
219 return sizeof(struct fc_logi_s
);
223 fc_flogi_acc_build(struct fchs_s
*fchs
, struct fc_logi_s
*flogi
, u32 s_id
,
224 __be16 ox_id
, wwn_t port_name
, wwn_t node_name
,
225 u16 pdu_size
, u16 local_bb_credits
, u8 bb_scn
)
228 u16 bbscn_rxsz
= (bb_scn
<< 12) | pdu_size
;
230 memcpy(flogi
, &plogi_tmpl
, sizeof(struct fc_logi_s
));
231 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
233 flogi
->els_cmd
.els_code
= FC_ELS_ACC
;
234 flogi
->class3
.rxsz
= cpu_to_be16(pdu_size
);
235 flogi
->csp
.rxsz
= cpu_to_be16(bbscn_rxsz
); /* bb_scn/rxsz */
236 flogi
->port_name
= port_name
;
237 flogi
->node_name
= node_name
;
239 flogi
->csp
.bbcred
= cpu_to_be16(local_bb_credits
);
241 return sizeof(struct fc_logi_s
);
245 fc_plogi_build(struct fchs_s
*fchs
, void *pld
, u32 d_id
, u32 s_id
,
246 u16 ox_id
, wwn_t port_name
, wwn_t node_name
,
247 u16 pdu_size
, u16 bb_cr
)
249 return fc_plogi_x_build(fchs
, pld
, d_id
, s_id
, ox_id
, port_name
,
250 node_name
, pdu_size
, bb_cr
, FC_ELS_PLOGI
);
254 fc_plogi_acc_build(struct fchs_s
*fchs
, void *pld
, u32 d_id
, u32 s_id
,
255 u16 ox_id
, wwn_t port_name
, wwn_t node_name
,
256 u16 pdu_size
, u16 bb_cr
)
258 return fc_plogi_x_build(fchs
, pld
, d_id
, s_id
, ox_id
, port_name
,
259 node_name
, pdu_size
, bb_cr
, FC_ELS_ACC
);
263 fc_plogi_parse(struct fchs_s
*fchs
)
265 struct fc_logi_s
*plogi
= (struct fc_logi_s
*) (fchs
+ 1);
267 if (plogi
->class3
.class_valid
!= 1)
268 return FC_PARSE_FAILURE
;
270 if ((be16_to_cpu(plogi
->class3
.rxsz
) < FC_MIN_PDUSZ
)
271 || (be16_to_cpu(plogi
->class3
.rxsz
) > FC_MAX_PDUSZ
)
272 || (plogi
->class3
.rxsz
== 0))
273 return FC_PARSE_FAILURE
;
279 fc_prli_build(struct fchs_s
*fchs
, void *pld
, u32 d_id
, u32 s_id
,
282 struct fc_prli_s
*prli
= (struct fc_prli_s
*) (pld
);
284 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
285 memcpy(prli
, &prli_tmpl
, sizeof(struct fc_prli_s
));
287 prli
->command
= FC_ELS_PRLI
;
288 prli
->parampage
.servparams
.initiator
= 1;
289 prli
->parampage
.servparams
.retry
= 1;
290 prli
->parampage
.servparams
.rec_support
= 1;
291 prli
->parampage
.servparams
.task_retry_id
= 0;
292 prli
->parampage
.servparams
.confirm
= 1;
294 return sizeof(struct fc_prli_s
);
298 fc_prli_acc_build(struct fchs_s
*fchs
, void *pld
, u32 d_id
, u32 s_id
,
299 __be16 ox_id
, enum bfa_lport_role role
)
301 struct fc_prli_s
*prli
= (struct fc_prli_s
*) (pld
);
303 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
304 memcpy(prli
, &prli_tmpl
, sizeof(struct fc_prli_s
));
306 prli
->command
= FC_ELS_ACC
;
308 prli
->parampage
.servparams
.initiator
= 1;
310 prli
->parampage
.rspcode
= FC_PRLI_ACC_XQTD
;
312 return sizeof(struct fc_prli_s
);
316 fc_prli_rsp_parse(struct fc_prli_s
*prli
, int len
)
318 if (len
< sizeof(struct fc_prli_s
))
319 return FC_PARSE_FAILURE
;
321 if (prli
->command
!= FC_ELS_ACC
)
322 return FC_PARSE_FAILURE
;
324 if ((prli
->parampage
.rspcode
!= FC_PRLI_ACC_XQTD
)
325 && (prli
->parampage
.rspcode
!= FC_PRLI_ACC_PREDEF_IMG
))
326 return FC_PARSE_FAILURE
;
328 if (prli
->parampage
.servparams
.target
!= 1)
329 return FC_PARSE_FAILURE
;
335 fc_logo_build(struct fchs_s
*fchs
, struct fc_logo_s
*logo
, u32 d_id
, u32 s_id
,
336 u16 ox_id
, wwn_t port_name
)
338 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
340 memset(logo
, '\0', sizeof(struct fc_logo_s
));
341 logo
->els_cmd
.els_code
= FC_ELS_LOGO
;
342 logo
->nport_id
= (s_id
);
343 logo
->orig_port_name
= port_name
;
345 return sizeof(struct fc_logo_s
);
349 fc_adisc_x_build(struct fchs_s
*fchs
, struct fc_adisc_s
*adisc
, u32 d_id
,
350 u32 s_id
, __be16 ox_id
, wwn_t port_name
,
351 wwn_t node_name
, u8 els_code
)
353 memset(adisc
, '\0', sizeof(struct fc_adisc_s
));
355 adisc
->els_cmd
.els_code
= els_code
;
357 if (els_code
== FC_ELS_ADISC
)
358 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
360 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
363 adisc
->orig_port_name
= port_name
;
364 adisc
->orig_node_name
= node_name
;
365 adisc
->nport_id
= (s_id
);
367 return sizeof(struct fc_adisc_s
);
371 fc_adisc_build(struct fchs_s
*fchs
, struct fc_adisc_s
*adisc
, u32 d_id
,
372 u32 s_id
, __be16 ox_id
, wwn_t port_name
, wwn_t node_name
)
374 return fc_adisc_x_build(fchs
, adisc
, d_id
, s_id
, ox_id
, port_name
,
375 node_name
, FC_ELS_ADISC
);
379 fc_adisc_acc_build(struct fchs_s
*fchs
, struct fc_adisc_s
*adisc
, u32 d_id
,
380 u32 s_id
, __be16 ox_id
, wwn_t port_name
,
383 return fc_adisc_x_build(fchs
, adisc
, d_id
, s_id
, ox_id
, port_name
,
384 node_name
, FC_ELS_ACC
);
388 fc_adisc_rsp_parse(struct fc_adisc_s
*adisc
, int len
, wwn_t port_name
,
392 if (len
< sizeof(struct fc_adisc_s
))
393 return FC_PARSE_FAILURE
;
395 if (adisc
->els_cmd
.els_code
!= FC_ELS_ACC
)
396 return FC_PARSE_FAILURE
;
398 if (!wwn_is_equal(adisc
->orig_port_name
, port_name
))
399 return FC_PARSE_FAILURE
;
405 fc_logo_acc_build(struct fchs_s
*fchs
, void *pld
, u32 d_id
, u32 s_id
,
408 struct fc_els_cmd_s
*acc
= pld
;
410 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
412 memset(acc
, 0, sizeof(struct fc_els_cmd_s
));
413 acc
->els_code
= FC_ELS_ACC
;
415 return sizeof(struct fc_els_cmd_s
);
419 fc_ls_rjt_build(struct fchs_s
*fchs
, struct fc_ls_rjt_s
*ls_rjt
, u32 d_id
,
420 u32 s_id
, __be16 ox_id
, u8 reason_code
,
423 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
424 memset(ls_rjt
, 0, sizeof(struct fc_ls_rjt_s
));
426 ls_rjt
->els_cmd
.els_code
= FC_ELS_LS_RJT
;
427 ls_rjt
->reason_code
= reason_code
;
428 ls_rjt
->reason_code_expl
= reason_code_expl
;
429 ls_rjt
->vendor_unique
= 0x00;
431 return sizeof(struct fc_ls_rjt_s
);
435 fc_ba_acc_build(struct fchs_s
*fchs
, struct fc_ba_acc_s
*ba_acc
, u32 d_id
,
436 u32 s_id
, __be16 ox_id
, u16 rx_id
)
438 fc_bls_rsp_build(fchs
, d_id
, s_id
, ox_id
);
440 memcpy(ba_acc
, &ba_acc_tmpl
, sizeof(struct fc_ba_acc_s
));
444 ba_acc
->ox_id
= fchs
->ox_id
;
445 ba_acc
->rx_id
= fchs
->rx_id
;
447 return sizeof(struct fc_ba_acc_s
);
451 fc_ls_acc_build(struct fchs_s
*fchs
, struct fc_els_cmd_s
*els_cmd
, u32 d_id
,
452 u32 s_id
, __be16 ox_id
)
454 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
455 memset(els_cmd
, 0, sizeof(struct fc_els_cmd_s
));
456 els_cmd
->els_code
= FC_ELS_ACC
;
458 return sizeof(struct fc_els_cmd_s
);
462 fc_logout_params_pages(struct fchs_s
*fc_frame
, u8 els_code
)
465 struct fc_prlo_s
*prlo
;
466 struct fc_tprlo_s
*tprlo
;
468 if (els_code
== FC_ELS_PRLO
) {
469 prlo
= (struct fc_prlo_s
*) (fc_frame
+ 1);
470 num_pages
= (be16_to_cpu(prlo
->payload_len
) - 4) / 16;
472 tprlo
= (struct fc_tprlo_s
*) (fc_frame
+ 1);
473 num_pages
= (be16_to_cpu(tprlo
->payload_len
) - 4) / 16;
479 fc_prlo_acc_build(struct fchs_s
*fchs
, struct fc_prlo_acc_s
*prlo_acc
, u32 d_id
,
480 u32 s_id
, __be16 ox_id
, int num_pages
)
484 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
486 memset(prlo_acc
, 0, (num_pages
* 16) + 4);
487 prlo_acc
->command
= FC_ELS_ACC
;
488 prlo_acc
->page_len
= 0x10;
489 prlo_acc
->payload_len
= cpu_to_be16((num_pages
* 16) + 4);
491 for (page
= 0; page
< num_pages
; page
++) {
492 prlo_acc
->prlo_acc_params
[page
].opa_valid
= 0;
493 prlo_acc
->prlo_acc_params
[page
].rpa_valid
= 0;
494 prlo_acc
->prlo_acc_params
[page
].fc4type_csp
= FC_TYPE_FCP
;
495 prlo_acc
->prlo_acc_params
[page
].orig_process_assc
= 0;
496 prlo_acc
->prlo_acc_params
[page
].resp_process_assc
= 0;
499 return be16_to_cpu(prlo_acc
->payload_len
);
503 fc_rnid_acc_build(struct fchs_s
*fchs
, struct fc_rnid_acc_s
*rnid_acc
, u32 d_id
,
504 u32 s_id
, __be16 ox_id
, u32 data_format
,
505 struct fc_rnid_common_id_data_s
*common_id_data
,
506 struct fc_rnid_general_topology_data_s
*gen_topo_data
)
508 memset(rnid_acc
, 0, sizeof(struct fc_rnid_acc_s
));
510 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
512 rnid_acc
->els_cmd
.els_code
= FC_ELS_ACC
;
513 rnid_acc
->node_id_data_format
= data_format
;
514 rnid_acc
->common_id_data_length
=
515 sizeof(struct fc_rnid_common_id_data_s
);
516 rnid_acc
->common_id_data
= *common_id_data
;
518 if (data_format
== RNID_NODEID_DATA_FORMAT_DISCOVERY
) {
519 rnid_acc
->specific_id_data_length
=
520 sizeof(struct fc_rnid_general_topology_data_s
);
521 rnid_acc
->gen_topology_data
= *gen_topo_data
;
522 return sizeof(struct fc_rnid_acc_s
);
524 return sizeof(struct fc_rnid_acc_s
) -
525 sizeof(struct fc_rnid_general_topology_data_s
);
531 fc_rpsc2_build(struct fchs_s
*fchs
, struct fc_rpsc2_cmd_s
*rpsc2
, u32 d_id
,
532 u32 s_id
, u32
*pid_list
, u16 npids
)
534 u32 dctlr_id
= FC_DOMAIN_CTRLR(bfa_hton3b(d_id
));
537 fc_els_req_build(fchs
, bfa_hton3b(dctlr_id
), s_id
, 0);
539 memset(rpsc2
, 0, sizeof(struct fc_rpsc2_cmd_s
));
541 rpsc2
->els_cmd
.els_code
= FC_ELS_RPSC
;
542 rpsc2
->token
= cpu_to_be32(FC_BRCD_TOKEN
);
543 rpsc2
->num_pids
= cpu_to_be16(npids
);
544 for (i
= 0; i
< npids
; i
++)
545 rpsc2
->pid_list
[i
].pid
= pid_list
[i
];
547 return sizeof(struct fc_rpsc2_cmd_s
) + ((npids
- 1) * (sizeof(u32
)));
551 fc_rpsc_acc_build(struct fchs_s
*fchs
, struct fc_rpsc_acc_s
*rpsc_acc
,
552 u32 d_id
, u32 s_id
, __be16 ox_id
,
553 struct fc_rpsc_speed_info_s
*oper_speed
)
555 memset(rpsc_acc
, 0, sizeof(struct fc_rpsc_acc_s
));
557 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
559 rpsc_acc
->command
= FC_ELS_ACC
;
560 rpsc_acc
->num_entries
= cpu_to_be16(1);
562 rpsc_acc
->speed_info
[0].port_speed_cap
=
563 cpu_to_be16(oper_speed
->port_speed_cap
);
565 rpsc_acc
->speed_info
[0].port_op_speed
=
566 cpu_to_be16(oper_speed
->port_op_speed
);
568 return sizeof(struct fc_rpsc_acc_s
);
572 fc_gs_cthdr_build(struct ct_hdr_s
*cthdr
, u32 s_id
, u16 cmd_code
)
574 memset(cthdr
, 0, sizeof(struct ct_hdr_s
));
575 cthdr
->rev_id
= CT_GS3_REVISION
;
576 cthdr
->gs_type
= CT_GSTYPE_DIRSERVICE
;
577 cthdr
->gs_sub_type
= CT_GSSUBTYPE_NAMESERVER
;
578 cthdr
->cmd_rsp_code
= cpu_to_be16(cmd_code
);
582 fc_gs_fdmi_cthdr_build(struct ct_hdr_s
*cthdr
, u32 s_id
, u16 cmd_code
)
584 memset(cthdr
, 0, sizeof(struct ct_hdr_s
));
585 cthdr
->rev_id
= CT_GS3_REVISION
;
586 cthdr
->gs_type
= CT_GSTYPE_MGMTSERVICE
;
587 cthdr
->gs_sub_type
= CT_GSSUBTYPE_HBA_MGMTSERVER
;
588 cthdr
->cmd_rsp_code
= cpu_to_be16(cmd_code
);
592 fc_gs_ms_cthdr_build(struct ct_hdr_s
*cthdr
, u32 s_id
, u16 cmd_code
,
595 memset(cthdr
, 0, sizeof(struct ct_hdr_s
));
596 cthdr
->rev_id
= CT_GS3_REVISION
;
597 cthdr
->gs_type
= CT_GSTYPE_MGMTSERVICE
;
598 cthdr
->gs_sub_type
= sub_type
;
599 cthdr
->cmd_rsp_code
= cpu_to_be16(cmd_code
);
603 fc_gidpn_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
606 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
607 struct fcgs_gidpn_req_s
*gidpn
= (struct fcgs_gidpn_req_s
*)(cthdr
+ 1);
608 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
610 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
611 fc_gs_cthdr_build(cthdr
, s_id
, GS_GID_PN
);
613 memset(gidpn
, 0, sizeof(struct fcgs_gidpn_req_s
));
614 gidpn
->port_name
= port_name
;
615 return sizeof(struct fcgs_gidpn_req_s
) + sizeof(struct ct_hdr_s
);
619 fc_gpnid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
622 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
623 fcgs_gpnid_req_t
*gpnid
= (fcgs_gpnid_req_t
*) (cthdr
+ 1);
624 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
626 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
627 fc_gs_cthdr_build(cthdr
, s_id
, GS_GPN_ID
);
629 memset(gpnid
, 0, sizeof(fcgs_gpnid_req_t
));
630 gpnid
->dap
= port_id
;
631 return sizeof(fcgs_gpnid_req_t
) + sizeof(struct ct_hdr_s
);
635 fc_gs_rjt_build(struct fchs_s
*fchs
, struct ct_hdr_s
*cthdr
,
636 u32 d_id
, u32 s_id
, u16 ox_id
, u8 reason_code
,
639 fc_gsresp_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
641 cthdr
->cmd_rsp_code
= cpu_to_be16(CT_RSP_REJECT
);
642 cthdr
->rev_id
= CT_GS3_REVISION
;
644 cthdr
->reason_code
= reason_code
;
645 cthdr
->exp_code
= reason_code_expl
;
646 return sizeof(struct ct_hdr_s
);
650 fc_scr_build(struct fchs_s
*fchs
, struct fc_scr_s
*scr
,
651 u8 set_br_reg
, u32 s_id
, u16 ox_id
)
653 u32 d_id
= bfa_hton3b(FC_FABRIC_CONTROLLER
);
655 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
657 memset(scr
, 0, sizeof(struct fc_scr_s
));
658 scr
->command
= FC_ELS_SCR
;
659 scr
->reg_func
= FC_SCR_REG_FUNC_FULL
;
661 scr
->vu_reg_func
= FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE
;
663 return sizeof(struct fc_scr_s
);
667 fc_rftid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
668 enum bfa_lport_role roles
)
670 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
671 struct fcgs_rftid_req_s
*rftid
= (struct fcgs_rftid_req_s
*)(cthdr
+ 1);
672 u32 type_value
, d_id
= bfa_hton3b(FC_NAME_SERVER
);
675 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
676 fc_gs_cthdr_build(cthdr
, s_id
, GS_RFT_ID
);
678 memset(rftid
, 0, sizeof(struct fcgs_rftid_req_s
));
682 /* By default, FCP FC4 Type is registered */
683 index
= FC_TYPE_FCP
>> 5;
684 type_value
= 1 << (FC_TYPE_FCP
% 32);
685 rftid
->fc4_type
[index
] = cpu_to_be32(type_value
);
687 return sizeof(struct fcgs_rftid_req_s
) + sizeof(struct ct_hdr_s
);
691 fc_rffid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
692 u8 fc4_type
, u8 fc4_ftrs
)
694 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
695 struct fcgs_rffid_req_s
*rffid
= (struct fcgs_rffid_req_s
*)(cthdr
+ 1);
696 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
698 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
699 fc_gs_cthdr_build(cthdr
, s_id
, GS_RFF_ID
);
701 memset(rffid
, 0, sizeof(struct fcgs_rffid_req_s
));
704 rffid
->fc4ftr_bits
= fc4_ftrs
;
705 rffid
->fc4_type
= fc4_type
;
707 return sizeof(struct fcgs_rffid_req_s
) + sizeof(struct ct_hdr_s
);
711 fc_rspnid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
715 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
716 struct fcgs_rspnid_req_s
*rspnid
=
717 (struct fcgs_rspnid_req_s
*)(cthdr
+ 1);
718 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
720 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
721 fc_gs_cthdr_build(cthdr
, s_id
, GS_RSPN_ID
);
723 memset(rspnid
, 0, sizeof(struct fcgs_rspnid_req_s
));
726 strscpy(rspnid
->spn
, name
, sizeof(rspnid
->spn
));
727 rspnid
->spn_len
= (u8
) strlen(rspnid
->spn
);
729 return sizeof(struct fcgs_rspnid_req_s
) + sizeof(struct ct_hdr_s
);
733 fc_rsnn_nn_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
,
734 wwn_t node_name
, u8
*name
)
736 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
737 struct fcgs_rsnn_nn_req_s
*rsnn_nn
=
738 (struct fcgs_rsnn_nn_req_s
*) (cthdr
+ 1);
739 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
741 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
742 fc_gs_cthdr_build(cthdr
, s_id
, GS_RSNN_NN
);
744 memset(rsnn_nn
, 0, sizeof(struct fcgs_rsnn_nn_req_s
));
746 rsnn_nn
->node_name
= node_name
;
747 strscpy(rsnn_nn
->snn
, name
, sizeof(rsnn_nn
->snn
));
748 rsnn_nn
->snn_len
= (u8
) strlen(rsnn_nn
->snn
);
750 return sizeof(struct fcgs_rsnn_nn_req_s
) + sizeof(struct ct_hdr_s
);
754 fc_gid_ft_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u8 fc4_type
)
757 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
758 struct fcgs_gidft_req_s
*gidft
= (struct fcgs_gidft_req_s
*)(cthdr
+ 1);
759 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
761 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
763 fc_gs_cthdr_build(cthdr
, s_id
, GS_GID_FT
);
765 memset(gidft
, 0, sizeof(struct fcgs_gidft_req_s
));
766 gidft
->fc4_type
= fc4_type
;
767 gidft
->domain_id
= 0;
770 return sizeof(struct fcgs_gidft_req_s
) + sizeof(struct ct_hdr_s
);
774 fc_rnnid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u32 port_id
,
777 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
778 struct fcgs_rnnid_req_s
*rnnid
= (struct fcgs_rnnid_req_s
*)(cthdr
+ 1);
779 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
781 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
782 fc_gs_cthdr_build(cthdr
, s_id
, GS_RNN_ID
);
784 memset(rnnid
, 0, sizeof(struct fcgs_rnnid_req_s
));
785 rnnid
->port_id
= port_id
;
786 rnnid
->node_name
= node_name
;
788 return sizeof(struct fcgs_rnnid_req_s
) + sizeof(struct ct_hdr_s
);
792 * Builds fc hdr and ct hdr for FDMI requests.
795 fc_fdmi_reqhdr_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
,
799 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
800 u32 d_id
= bfa_hton3b(FC_MGMT_SERVER
);
802 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
803 fc_gs_fdmi_cthdr_build(cthdr
, s_id
, cmd_code
);
805 return sizeof(struct ct_hdr_s
);
809 * Given a FC4 Type, this function returns a fc4 type bitmask
812 fc_get_fc4type_bitmask(u8 fc4_type
, u8
*bit_mask
)
815 __be32
*ptr
= (__be32
*) bit_mask
;
819 * @todo : Check for bitmask size
822 index
= fc4_type
>> 5;
823 type_value
= 1 << (fc4_type
% 32);
824 ptr
[index
] = cpu_to_be32(type_value
);
832 fc_gmal_req_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, wwn_t wwn
)
834 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
835 fcgs_gmal_req_t
*gmal
= (fcgs_gmal_req_t
*) (cthdr
+ 1);
836 u32 d_id
= bfa_hton3b(FC_MGMT_SERVER
);
838 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
839 fc_gs_ms_cthdr_build(cthdr
, s_id
, GS_FC_GMAL_CMD
,
840 CT_GSSUBTYPE_CFGSERVER
);
842 memset(gmal
, 0, sizeof(fcgs_gmal_req_t
));
845 return sizeof(struct ct_hdr_s
) + sizeof(fcgs_gmal_req_t
);
849 * GFN (Get Fabric Name) Request
852 fc_gfn_req_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, wwn_t wwn
)
854 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
855 fcgs_gfn_req_t
*gfn
= (fcgs_gfn_req_t
*) (cthdr
+ 1);
856 u32 d_id
= bfa_hton3b(FC_MGMT_SERVER
);
858 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
859 fc_gs_ms_cthdr_build(cthdr
, s_id
, GS_FC_GFN_CMD
,
860 CT_GSSUBTYPE_CFGSERVER
);
862 memset(gfn
, 0, sizeof(fcgs_gfn_req_t
));
865 return sizeof(struct ct_hdr_s
) + sizeof(fcgs_gfn_req_t
);