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_build(struct fchs_s
*fchs
, struct fc_logi_s
*flogi
, u32 s_id
,
224 u16 ox_id
, wwn_t port_name
, wwn_t node_name
, u16 pdu_size
,
225 u8 set_npiv
, u8 set_auth
, u16 local_bb_credits
)
227 u32 d_id
= bfa_hton3b(FC_FABRIC_PORT
);
230 memcpy(flogi
, &plogi_tmpl
, sizeof(struct fc_logi_s
));
232 flogi
->els_cmd
.els_code
= FC_ELS_FLOGI
;
233 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
235 flogi
->csp
.rxsz
= flogi
->class3
.rxsz
= cpu_to_be16(pdu_size
);
236 flogi
->port_name
= port_name
;
237 flogi
->node_name
= node_name
;
240 * Set the NPIV Capability Bit ( word 1, bit 31) of Common
241 * Service Parameters.
243 flogi
->csp
.ciro
= set_npiv
;
245 /* set AUTH capability */
246 flogi
->csp
.security
= set_auth
;
248 flogi
->csp
.bbcred
= cpu_to_be16(local_bb_credits
);
250 /* Set brcd token in VVL */
251 vvl_info
= (u32
*)&flogi
->vvl
[0];
253 /* set the flag to indicate the presence of VVL */
254 flogi
->csp
.npiv_supp
= 1; /* @todo. field name is not correct */
255 vvl_info
[0] = cpu_to_be32(FLOGI_VVL_BRCD
);
257 return sizeof(struct fc_logi_s
);
261 fc_flogi_acc_build(struct fchs_s
*fchs
, struct fc_logi_s
*flogi
, u32 s_id
,
262 __be16 ox_id
, wwn_t port_name
, wwn_t node_name
,
263 u16 pdu_size
, u16 local_bb_credits
, u8 bb_scn
)
266 u16 bbscn_rxsz
= (bb_scn
<< 12) | pdu_size
;
268 memcpy(flogi
, &plogi_tmpl
, sizeof(struct fc_logi_s
));
269 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
271 flogi
->els_cmd
.els_code
= FC_ELS_ACC
;
272 flogi
->class3
.rxsz
= cpu_to_be16(pdu_size
);
273 flogi
->csp
.rxsz
= cpu_to_be16(bbscn_rxsz
); /* bb_scn/rxsz */
274 flogi
->port_name
= port_name
;
275 flogi
->node_name
= node_name
;
277 flogi
->csp
.bbcred
= cpu_to_be16(local_bb_credits
);
279 return sizeof(struct fc_logi_s
);
283 fc_fdisc_build(struct fchs_s
*fchs
, struct fc_logi_s
*flogi
, u32 s_id
,
284 u16 ox_id
, wwn_t port_name
, wwn_t node_name
, u16 pdu_size
)
286 u32 d_id
= bfa_hton3b(FC_FABRIC_PORT
);
288 memcpy(flogi
, &plogi_tmpl
, sizeof(struct fc_logi_s
));
290 flogi
->els_cmd
.els_code
= FC_ELS_FDISC
;
291 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
293 flogi
->csp
.rxsz
= flogi
->class3
.rxsz
= cpu_to_be16(pdu_size
);
294 flogi
->port_name
= port_name
;
295 flogi
->node_name
= node_name
;
297 return sizeof(struct fc_logi_s
);
301 fc_plogi_build(struct fchs_s
*fchs
, void *pld
, u32 d_id
, u32 s_id
,
302 u16 ox_id
, wwn_t port_name
, wwn_t node_name
,
303 u16 pdu_size
, u16 bb_cr
)
305 return fc_plogi_x_build(fchs
, pld
, d_id
, s_id
, ox_id
, port_name
,
306 node_name
, pdu_size
, bb_cr
, FC_ELS_PLOGI
);
310 fc_plogi_acc_build(struct fchs_s
*fchs
, void *pld
, u32 d_id
, u32 s_id
,
311 u16 ox_id
, wwn_t port_name
, wwn_t node_name
,
312 u16 pdu_size
, u16 bb_cr
)
314 return fc_plogi_x_build(fchs
, pld
, d_id
, s_id
, ox_id
, port_name
,
315 node_name
, pdu_size
, bb_cr
, FC_ELS_ACC
);
319 fc_plogi_rsp_parse(struct fchs_s
*fchs
, int len
, wwn_t port_name
)
321 struct fc_els_cmd_s
*els_cmd
= (struct fc_els_cmd_s
*) (fchs
+ 1);
322 struct fc_logi_s
*plogi
;
323 struct fc_ls_rjt_s
*ls_rjt
;
325 switch (els_cmd
->els_code
) {
327 ls_rjt
= (struct fc_ls_rjt_s
*) (fchs
+ 1);
328 if (ls_rjt
->reason_code
== FC_LS_RJT_RSN_LOGICAL_BUSY
)
329 return FC_PARSE_BUSY
;
331 return FC_PARSE_FAILURE
;
333 plogi
= (struct fc_logi_s
*) (fchs
+ 1);
334 if (len
< sizeof(struct fc_logi_s
))
335 return FC_PARSE_FAILURE
;
337 if (!wwn_is_equal(plogi
->port_name
, port_name
))
338 return FC_PARSE_FAILURE
;
340 if (!plogi
->class3
.class_valid
)
341 return FC_PARSE_FAILURE
;
343 if (be16_to_cpu(plogi
->class3
.rxsz
) < (FC_MIN_PDUSZ
))
344 return FC_PARSE_FAILURE
;
348 return FC_PARSE_FAILURE
;
353 fc_plogi_parse(struct fchs_s
*fchs
)
355 struct fc_logi_s
*plogi
= (struct fc_logi_s
*) (fchs
+ 1);
357 if (plogi
->class3
.class_valid
!= 1)
358 return FC_PARSE_FAILURE
;
360 if ((be16_to_cpu(plogi
->class3
.rxsz
) < FC_MIN_PDUSZ
)
361 || (be16_to_cpu(plogi
->class3
.rxsz
) > FC_MAX_PDUSZ
)
362 || (plogi
->class3
.rxsz
== 0))
363 return FC_PARSE_FAILURE
;
369 fc_prli_build(struct fchs_s
*fchs
, void *pld
, u32 d_id
, u32 s_id
,
372 struct fc_prli_s
*prli
= (struct fc_prli_s
*) (pld
);
374 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
375 memcpy(prli
, &prli_tmpl
, sizeof(struct fc_prli_s
));
377 prli
->command
= FC_ELS_PRLI
;
378 prli
->parampage
.servparams
.initiator
= 1;
379 prli
->parampage
.servparams
.retry
= 1;
380 prli
->parampage
.servparams
.rec_support
= 1;
381 prli
->parampage
.servparams
.task_retry_id
= 0;
382 prli
->parampage
.servparams
.confirm
= 1;
384 return sizeof(struct fc_prli_s
);
388 fc_prli_acc_build(struct fchs_s
*fchs
, void *pld
, u32 d_id
, u32 s_id
,
389 __be16 ox_id
, enum bfa_lport_role role
)
391 struct fc_prli_s
*prli
= (struct fc_prli_s
*) (pld
);
393 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
394 memcpy(prli
, &prli_tmpl
, sizeof(struct fc_prli_s
));
396 prli
->command
= FC_ELS_ACC
;
398 prli
->parampage
.servparams
.initiator
= 1;
400 prli
->parampage
.rspcode
= FC_PRLI_ACC_XQTD
;
402 return sizeof(struct fc_prli_s
);
406 fc_prli_rsp_parse(struct fc_prli_s
*prli
, int len
)
408 if (len
< sizeof(struct fc_prli_s
))
409 return FC_PARSE_FAILURE
;
411 if (prli
->command
!= FC_ELS_ACC
)
412 return FC_PARSE_FAILURE
;
414 if ((prli
->parampage
.rspcode
!= FC_PRLI_ACC_XQTD
)
415 && (prli
->parampage
.rspcode
!= FC_PRLI_ACC_PREDEF_IMG
))
416 return FC_PARSE_FAILURE
;
418 if (prli
->parampage
.servparams
.target
!= 1)
419 return FC_PARSE_FAILURE
;
425 fc_prli_parse(struct fc_prli_s
*prli
)
427 if (prli
->parampage
.type
!= FC_TYPE_FCP
)
428 return FC_PARSE_FAILURE
;
430 if (!prli
->parampage
.imagepair
)
431 return FC_PARSE_FAILURE
;
433 if (!prli
->parampage
.servparams
.initiator
)
434 return FC_PARSE_FAILURE
;
440 fc_logo_build(struct fchs_s
*fchs
, struct fc_logo_s
*logo
, u32 d_id
, u32 s_id
,
441 u16 ox_id
, wwn_t port_name
)
443 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
445 memset(logo
, '\0', sizeof(struct fc_logo_s
));
446 logo
->els_cmd
.els_code
= FC_ELS_LOGO
;
447 logo
->nport_id
= (s_id
);
448 logo
->orig_port_name
= port_name
;
450 return sizeof(struct fc_logo_s
);
454 fc_adisc_x_build(struct fchs_s
*fchs
, struct fc_adisc_s
*adisc
, u32 d_id
,
455 u32 s_id
, __be16 ox_id
, wwn_t port_name
,
456 wwn_t node_name
, u8 els_code
)
458 memset(adisc
, '\0', sizeof(struct fc_adisc_s
));
460 adisc
->els_cmd
.els_code
= els_code
;
462 if (els_code
== FC_ELS_ADISC
)
463 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
465 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
468 adisc
->orig_port_name
= port_name
;
469 adisc
->orig_node_name
= node_name
;
470 adisc
->nport_id
= (s_id
);
472 return sizeof(struct fc_adisc_s
);
476 fc_adisc_build(struct fchs_s
*fchs
, struct fc_adisc_s
*adisc
, u32 d_id
,
477 u32 s_id
, __be16 ox_id
, wwn_t port_name
, wwn_t node_name
)
479 return fc_adisc_x_build(fchs
, adisc
, d_id
, s_id
, ox_id
, port_name
,
480 node_name
, FC_ELS_ADISC
);
484 fc_adisc_acc_build(struct fchs_s
*fchs
, struct fc_adisc_s
*adisc
, u32 d_id
,
485 u32 s_id
, __be16 ox_id
, wwn_t port_name
,
488 return fc_adisc_x_build(fchs
, adisc
, d_id
, s_id
, ox_id
, port_name
,
489 node_name
, FC_ELS_ACC
);
493 fc_adisc_rsp_parse(struct fc_adisc_s
*adisc
, int len
, wwn_t port_name
,
497 if (len
< sizeof(struct fc_adisc_s
))
498 return FC_PARSE_FAILURE
;
500 if (adisc
->els_cmd
.els_code
!= FC_ELS_ACC
)
501 return FC_PARSE_FAILURE
;
503 if (!wwn_is_equal(adisc
->orig_port_name
, port_name
))
504 return FC_PARSE_FAILURE
;
510 fc_adisc_parse(struct fchs_s
*fchs
, void *pld
, u32 host_dap
, wwn_t node_name
,
513 struct fc_adisc_s
*adisc
= (struct fc_adisc_s
*) pld
;
515 if (adisc
->els_cmd
.els_code
!= FC_ELS_ACC
)
516 return FC_PARSE_FAILURE
;
518 if ((adisc
->nport_id
== (host_dap
))
519 && wwn_is_equal(adisc
->orig_port_name
, port_name
)
520 && wwn_is_equal(adisc
->orig_node_name
, node_name
))
523 return FC_PARSE_FAILURE
;
527 fc_pdisc_parse(struct fchs_s
*fchs
, wwn_t node_name
, wwn_t port_name
)
529 struct fc_logi_s
*pdisc
= (struct fc_logi_s
*) (fchs
+ 1);
531 if (pdisc
->class3
.class_valid
!= 1)
532 return FC_PARSE_FAILURE
;
534 if ((be16_to_cpu(pdisc
->class3
.rxsz
) <
535 (FC_MIN_PDUSZ
- sizeof(struct fchs_s
)))
536 || (pdisc
->class3
.rxsz
== 0))
537 return FC_PARSE_FAILURE
;
539 if (!wwn_is_equal(pdisc
->port_name
, port_name
))
540 return FC_PARSE_FAILURE
;
542 if (!wwn_is_equal(pdisc
->node_name
, node_name
))
543 return FC_PARSE_FAILURE
;
549 fc_abts_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
, u16 ox_id
)
551 memcpy(fchs
, &fc_bls_req_tmpl
, sizeof(struct fchs_s
));
552 fchs
->cat_info
= FC_CAT_ABTS
;
555 fchs
->ox_id
= cpu_to_be16(ox_id
);
557 return sizeof(struct fchs_s
);
561 fc_abts_rsp_parse(struct fchs_s
*fchs
, int len
)
563 if ((fchs
->cat_info
== FC_CAT_BA_ACC
)
564 || (fchs
->cat_info
== FC_CAT_BA_RJT
))
567 return FC_PARSE_FAILURE
;
571 fc_rrq_build(struct fchs_s
*fchs
, struct fc_rrq_s
*rrq
, u32 d_id
, u32 s_id
,
572 u16 ox_id
, u16 rrq_oxid
)
574 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
579 memcpy(rrq
, &rrq_tmpl
, sizeof(struct fc_rrq_s
));
581 rrq
->ox_id
= cpu_to_be16(rrq_oxid
);
582 rrq
->rx_id
= FC_RXID_ANY
;
584 return sizeof(struct fc_rrq_s
);
588 fc_logo_acc_build(struct fchs_s
*fchs
, void *pld
, u32 d_id
, u32 s_id
,
591 struct fc_els_cmd_s
*acc
= pld
;
593 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
595 memset(acc
, 0, sizeof(struct fc_els_cmd_s
));
596 acc
->els_code
= FC_ELS_ACC
;
598 return sizeof(struct fc_els_cmd_s
);
602 fc_ls_rjt_build(struct fchs_s
*fchs
, struct fc_ls_rjt_s
*ls_rjt
, u32 d_id
,
603 u32 s_id
, __be16 ox_id
, u8 reason_code
,
606 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
607 memset(ls_rjt
, 0, sizeof(struct fc_ls_rjt_s
));
609 ls_rjt
->els_cmd
.els_code
= FC_ELS_LS_RJT
;
610 ls_rjt
->reason_code
= reason_code
;
611 ls_rjt
->reason_code_expl
= reason_code_expl
;
612 ls_rjt
->vendor_unique
= 0x00;
614 return sizeof(struct fc_ls_rjt_s
);
618 fc_ba_acc_build(struct fchs_s
*fchs
, struct fc_ba_acc_s
*ba_acc
, u32 d_id
,
619 u32 s_id
, __be16 ox_id
, u16 rx_id
)
621 fc_bls_rsp_build(fchs
, d_id
, s_id
, ox_id
);
623 memcpy(ba_acc
, &ba_acc_tmpl
, sizeof(struct fc_ba_acc_s
));
627 ba_acc
->ox_id
= fchs
->ox_id
;
628 ba_acc
->rx_id
= fchs
->rx_id
;
630 return sizeof(struct fc_ba_acc_s
);
634 fc_ls_acc_build(struct fchs_s
*fchs
, struct fc_els_cmd_s
*els_cmd
, u32 d_id
,
635 u32 s_id
, __be16 ox_id
)
637 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
638 memset(els_cmd
, 0, sizeof(struct fc_els_cmd_s
));
639 els_cmd
->els_code
= FC_ELS_ACC
;
641 return sizeof(struct fc_els_cmd_s
);
645 fc_logout_params_pages(struct fchs_s
*fc_frame
, u8 els_code
)
648 struct fc_prlo_s
*prlo
;
649 struct fc_tprlo_s
*tprlo
;
651 if (els_code
== FC_ELS_PRLO
) {
652 prlo
= (struct fc_prlo_s
*) (fc_frame
+ 1);
653 num_pages
= (be16_to_cpu(prlo
->payload_len
) - 4) / 16;
655 tprlo
= (struct fc_tprlo_s
*) (fc_frame
+ 1);
656 num_pages
= (be16_to_cpu(tprlo
->payload_len
) - 4) / 16;
662 fc_tprlo_acc_build(struct fchs_s
*fchs
, struct fc_tprlo_acc_s
*tprlo_acc
,
663 u32 d_id
, u32 s_id
, __be16 ox_id
, int num_pages
)
667 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
669 memset(tprlo_acc
, 0, (num_pages
* 16) + 4);
670 tprlo_acc
->command
= FC_ELS_ACC
;
672 tprlo_acc
->page_len
= 0x10;
673 tprlo_acc
->payload_len
= cpu_to_be16((num_pages
* 16) + 4);
675 for (page
= 0; page
< num_pages
; page
++) {
676 tprlo_acc
->tprlo_acc_params
[page
].opa_valid
= 0;
677 tprlo_acc
->tprlo_acc_params
[page
].rpa_valid
= 0;
678 tprlo_acc
->tprlo_acc_params
[page
].fc4type_csp
= FC_TYPE_FCP
;
679 tprlo_acc
->tprlo_acc_params
[page
].orig_process_assc
= 0;
680 tprlo_acc
->tprlo_acc_params
[page
].resp_process_assc
= 0;
682 return be16_to_cpu(tprlo_acc
->payload_len
);
686 fc_prlo_acc_build(struct fchs_s
*fchs
, struct fc_prlo_acc_s
*prlo_acc
, u32 d_id
,
687 u32 s_id
, __be16 ox_id
, int num_pages
)
691 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
693 memset(prlo_acc
, 0, (num_pages
* 16) + 4);
694 prlo_acc
->command
= FC_ELS_ACC
;
695 prlo_acc
->page_len
= 0x10;
696 prlo_acc
->payload_len
= cpu_to_be16((num_pages
* 16) + 4);
698 for (page
= 0; page
< num_pages
; page
++) {
699 prlo_acc
->prlo_acc_params
[page
].opa_valid
= 0;
700 prlo_acc
->prlo_acc_params
[page
].rpa_valid
= 0;
701 prlo_acc
->prlo_acc_params
[page
].fc4type_csp
= FC_TYPE_FCP
;
702 prlo_acc
->prlo_acc_params
[page
].orig_process_assc
= 0;
703 prlo_acc
->prlo_acc_params
[page
].resp_process_assc
= 0;
706 return be16_to_cpu(prlo_acc
->payload_len
);
710 fc_rnid_build(struct fchs_s
*fchs
, struct fc_rnid_cmd_s
*rnid
, u32 d_id
,
711 u32 s_id
, u16 ox_id
, u32 data_format
)
713 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
715 memset(rnid
, 0, sizeof(struct fc_rnid_cmd_s
));
717 rnid
->els_cmd
.els_code
= FC_ELS_RNID
;
718 rnid
->node_id_data_format
= data_format
;
720 return sizeof(struct fc_rnid_cmd_s
);
724 fc_rnid_acc_build(struct fchs_s
*fchs
, struct fc_rnid_acc_s
*rnid_acc
, u32 d_id
,
725 u32 s_id
, __be16 ox_id
, u32 data_format
,
726 struct fc_rnid_common_id_data_s
*common_id_data
,
727 struct fc_rnid_general_topology_data_s
*gen_topo_data
)
729 memset(rnid_acc
, 0, sizeof(struct fc_rnid_acc_s
));
731 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
733 rnid_acc
->els_cmd
.els_code
= FC_ELS_ACC
;
734 rnid_acc
->node_id_data_format
= data_format
;
735 rnid_acc
->common_id_data_length
=
736 sizeof(struct fc_rnid_common_id_data_s
);
737 rnid_acc
->common_id_data
= *common_id_data
;
739 if (data_format
== RNID_NODEID_DATA_FORMAT_DISCOVERY
) {
740 rnid_acc
->specific_id_data_length
=
741 sizeof(struct fc_rnid_general_topology_data_s
);
742 rnid_acc
->gen_topology_data
= *gen_topo_data
;
743 return sizeof(struct fc_rnid_acc_s
);
745 return sizeof(struct fc_rnid_acc_s
) -
746 sizeof(struct fc_rnid_general_topology_data_s
);
752 fc_rpsc_build(struct fchs_s
*fchs
, struct fc_rpsc_cmd_s
*rpsc
, u32 d_id
,
755 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
757 memset(rpsc
, 0, sizeof(struct fc_rpsc_cmd_s
));
759 rpsc
->els_cmd
.els_code
= FC_ELS_RPSC
;
760 return sizeof(struct fc_rpsc_cmd_s
);
764 fc_rpsc2_build(struct fchs_s
*fchs
, struct fc_rpsc2_cmd_s
*rpsc2
, u32 d_id
,
765 u32 s_id
, u32
*pid_list
, u16 npids
)
767 u32 dctlr_id
= FC_DOMAIN_CTRLR(bfa_hton3b(d_id
));
770 fc_els_req_build(fchs
, bfa_hton3b(dctlr_id
), s_id
, 0);
772 memset(rpsc2
, 0, sizeof(struct fc_rpsc2_cmd_s
));
774 rpsc2
->els_cmd
.els_code
= FC_ELS_RPSC
;
775 rpsc2
->token
= cpu_to_be32(FC_BRCD_TOKEN
);
776 rpsc2
->num_pids
= cpu_to_be16(npids
);
777 for (i
= 0; i
< npids
; i
++)
778 rpsc2
->pid_list
[i
].pid
= pid_list
[i
];
780 return sizeof(struct fc_rpsc2_cmd_s
) + ((npids
- 1) * (sizeof(u32
)));
784 fc_rpsc_acc_build(struct fchs_s
*fchs
, struct fc_rpsc_acc_s
*rpsc_acc
,
785 u32 d_id
, u32 s_id
, __be16 ox_id
,
786 struct fc_rpsc_speed_info_s
*oper_speed
)
788 memset(rpsc_acc
, 0, sizeof(struct fc_rpsc_acc_s
));
790 fc_els_rsp_build(fchs
, d_id
, s_id
, ox_id
);
792 rpsc_acc
->command
= FC_ELS_ACC
;
793 rpsc_acc
->num_entries
= cpu_to_be16(1);
795 rpsc_acc
->speed_info
[0].port_speed_cap
=
796 cpu_to_be16(oper_speed
->port_speed_cap
);
798 rpsc_acc
->speed_info
[0].port_op_speed
=
799 cpu_to_be16(oper_speed
->port_op_speed
);
801 return sizeof(struct fc_rpsc_acc_s
);
805 fc_pdisc_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
, u16 ox_id
,
806 wwn_t port_name
, wwn_t node_name
, u16 pdu_size
)
808 struct fc_logi_s
*pdisc
= (struct fc_logi_s
*) (fchs
+ 1);
810 memcpy(pdisc
, &plogi_tmpl
, sizeof(struct fc_logi_s
));
812 pdisc
->els_cmd
.els_code
= FC_ELS_PDISC
;
813 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
815 pdisc
->csp
.rxsz
= pdisc
->class3
.rxsz
= cpu_to_be16(pdu_size
);
816 pdisc
->port_name
= port_name
;
817 pdisc
->node_name
= node_name
;
819 return sizeof(struct fc_logi_s
);
823 fc_pdisc_rsp_parse(struct fchs_s
*fchs
, int len
, wwn_t port_name
)
825 struct fc_logi_s
*pdisc
= (struct fc_logi_s
*) (fchs
+ 1);
827 if (len
< sizeof(struct fc_logi_s
))
828 return FC_PARSE_LEN_INVAL
;
830 if (pdisc
->els_cmd
.els_code
!= FC_ELS_ACC
)
831 return FC_PARSE_ACC_INVAL
;
833 if (!wwn_is_equal(pdisc
->port_name
, port_name
))
834 return FC_PARSE_PWWN_NOT_EQUAL
;
836 if (!pdisc
->class3
.class_valid
)
837 return FC_PARSE_NWWN_NOT_EQUAL
;
839 if (be16_to_cpu(pdisc
->class3
.rxsz
) < (FC_MIN_PDUSZ
))
840 return FC_PARSE_RXSZ_INVAL
;
846 fc_prlo_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
, u16 ox_id
,
849 struct fc_prlo_s
*prlo
= (struct fc_prlo_s
*) (fchs
+ 1);
852 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
853 memset(prlo
, 0, (num_pages
* 16) + 4);
854 prlo
->command
= FC_ELS_PRLO
;
855 prlo
->page_len
= 0x10;
856 prlo
->payload_len
= cpu_to_be16((num_pages
* 16) + 4);
858 for (page
= 0; page
< num_pages
; page
++) {
859 prlo
->prlo_params
[page
].type
= FC_TYPE_FCP
;
860 prlo
->prlo_params
[page
].opa_valid
= 0;
861 prlo
->prlo_params
[page
].rpa_valid
= 0;
862 prlo
->prlo_params
[page
].orig_process_assc
= 0;
863 prlo
->prlo_params
[page
].resp_process_assc
= 0;
866 return be16_to_cpu(prlo
->payload_len
);
870 fc_tprlo_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
, u16 ox_id
,
871 int num_pages
, enum fc_tprlo_type tprlo_type
, u32 tpr_id
)
873 struct fc_tprlo_s
*tprlo
= (struct fc_tprlo_s
*) (fchs
+ 1);
876 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
877 memset(tprlo
, 0, (num_pages
* 16) + 4);
878 tprlo
->command
= FC_ELS_TPRLO
;
879 tprlo
->page_len
= 0x10;
880 tprlo
->payload_len
= cpu_to_be16((num_pages
* 16) + 4);
882 for (page
= 0; page
< num_pages
; page
++) {
883 tprlo
->tprlo_params
[page
].type
= FC_TYPE_FCP
;
884 tprlo
->tprlo_params
[page
].opa_valid
= 0;
885 tprlo
->tprlo_params
[page
].rpa_valid
= 0;
886 tprlo
->tprlo_params
[page
].orig_process_assc
= 0;
887 tprlo
->tprlo_params
[page
].resp_process_assc
= 0;
888 if (tprlo_type
== FC_GLOBAL_LOGO
) {
889 tprlo
->tprlo_params
[page
].global_process_logout
= 1;
890 } else if (tprlo_type
== FC_TPR_LOGO
) {
891 tprlo
->tprlo_params
[page
].tpo_nport_valid
= 1;
892 tprlo
->tprlo_params
[page
].tpo_nport_id
= (tpr_id
);
896 return be16_to_cpu(tprlo
->payload_len
);
900 fc_ba_rjt_build(struct fchs_s
*fchs
, u32 d_id
, u32 s_id
, __be16 ox_id
,
901 u32 reason_code
, u32 reason_expl
)
903 struct fc_ba_rjt_s
*ba_rjt
= (struct fc_ba_rjt_s
*) (fchs
+ 1);
905 fc_bls_rsp_build(fchs
, d_id
, s_id
, ox_id
);
907 fchs
->cat_info
= FC_CAT_BA_RJT
;
908 ba_rjt
->reason_code
= reason_code
;
909 ba_rjt
->reason_expl
= reason_expl
;
910 return sizeof(struct fc_ba_rjt_s
);
914 fc_gs_cthdr_build(struct ct_hdr_s
*cthdr
, u32 s_id
, u16 cmd_code
)
916 memset(cthdr
, 0, sizeof(struct ct_hdr_s
));
917 cthdr
->rev_id
= CT_GS3_REVISION
;
918 cthdr
->gs_type
= CT_GSTYPE_DIRSERVICE
;
919 cthdr
->gs_sub_type
= CT_GSSUBTYPE_NAMESERVER
;
920 cthdr
->cmd_rsp_code
= cpu_to_be16(cmd_code
);
924 fc_gs_fdmi_cthdr_build(struct ct_hdr_s
*cthdr
, u32 s_id
, u16 cmd_code
)
926 memset(cthdr
, 0, sizeof(struct ct_hdr_s
));
927 cthdr
->rev_id
= CT_GS3_REVISION
;
928 cthdr
->gs_type
= CT_GSTYPE_MGMTSERVICE
;
929 cthdr
->gs_sub_type
= CT_GSSUBTYPE_HBA_MGMTSERVER
;
930 cthdr
->cmd_rsp_code
= cpu_to_be16(cmd_code
);
934 fc_gs_ms_cthdr_build(struct ct_hdr_s
*cthdr
, u32 s_id
, u16 cmd_code
,
937 memset(cthdr
, 0, sizeof(struct ct_hdr_s
));
938 cthdr
->rev_id
= CT_GS3_REVISION
;
939 cthdr
->gs_type
= CT_GSTYPE_MGMTSERVICE
;
940 cthdr
->gs_sub_type
= sub_type
;
941 cthdr
->cmd_rsp_code
= cpu_to_be16(cmd_code
);
945 fc_gidpn_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
948 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
949 struct fcgs_gidpn_req_s
*gidpn
= (struct fcgs_gidpn_req_s
*)(cthdr
+ 1);
950 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
952 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
953 fc_gs_cthdr_build(cthdr
, s_id
, GS_GID_PN
);
955 memset(gidpn
, 0, sizeof(struct fcgs_gidpn_req_s
));
956 gidpn
->port_name
= port_name
;
957 return sizeof(struct fcgs_gidpn_req_s
) + sizeof(struct ct_hdr_s
);
961 fc_gpnid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
964 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
965 fcgs_gpnid_req_t
*gpnid
= (fcgs_gpnid_req_t
*) (cthdr
+ 1);
966 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
968 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
969 fc_gs_cthdr_build(cthdr
, s_id
, GS_GPN_ID
);
971 memset(gpnid
, 0, sizeof(fcgs_gpnid_req_t
));
972 gpnid
->dap
= port_id
;
973 return sizeof(fcgs_gpnid_req_t
) + sizeof(struct ct_hdr_s
);
977 fc_gnnid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
980 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
981 fcgs_gnnid_req_t
*gnnid
= (fcgs_gnnid_req_t
*) (cthdr
+ 1);
982 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
984 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
985 fc_gs_cthdr_build(cthdr
, s_id
, GS_GNN_ID
);
987 memset(gnnid
, 0, sizeof(fcgs_gnnid_req_t
));
988 gnnid
->dap
= port_id
;
989 return sizeof(fcgs_gnnid_req_t
) + sizeof(struct ct_hdr_s
);
993 fc_ct_rsp_parse(struct ct_hdr_s
*cthdr
)
995 if (be16_to_cpu(cthdr
->cmd_rsp_code
) != CT_RSP_ACCEPT
) {
996 if (cthdr
->reason_code
== CT_RSN_LOGICAL_BUSY
)
997 return FC_PARSE_BUSY
;
999 return FC_PARSE_FAILURE
;
1006 fc_gs_rjt_build(struct fchs_s
*fchs
, struct ct_hdr_s
*cthdr
,
1007 u32 d_id
, u32 s_id
, u16 ox_id
, u8 reason_code
,
1008 u8 reason_code_expl
)
1010 fc_gsresp_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
1012 cthdr
->cmd_rsp_code
= cpu_to_be16(CT_RSP_REJECT
);
1013 cthdr
->rev_id
= CT_GS3_REVISION
;
1015 cthdr
->reason_code
= reason_code
;
1016 cthdr
->exp_code
= reason_code_expl
;
1017 return sizeof(struct ct_hdr_s
);
1021 fc_scr_build(struct fchs_s
*fchs
, struct fc_scr_s
*scr
,
1022 u8 set_br_reg
, u32 s_id
, u16 ox_id
)
1024 u32 d_id
= bfa_hton3b(FC_FABRIC_CONTROLLER
);
1026 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
1028 memset(scr
, 0, sizeof(struct fc_scr_s
));
1029 scr
->command
= FC_ELS_SCR
;
1030 scr
->reg_func
= FC_SCR_REG_FUNC_FULL
;
1032 scr
->vu_reg_func
= FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE
;
1034 return sizeof(struct fc_scr_s
);
1038 fc_rscn_build(struct fchs_s
*fchs
, struct fc_rscn_pl_s
*rscn
,
1039 u32 s_id
, u16 ox_id
)
1041 u32 d_id
= bfa_hton3b(FC_FABRIC_CONTROLLER
);
1044 fc_els_req_build(fchs
, d_id
, s_id
, ox_id
);
1045 rscn
->command
= FC_ELS_RSCN
;
1046 rscn
->pagelen
= sizeof(rscn
->event
[0]);
1048 payldlen
= sizeof(u32
) + rscn
->pagelen
;
1049 rscn
->payldlen
= cpu_to_be16(payldlen
);
1051 rscn
->event
[0].format
= FC_RSCN_FORMAT_PORTID
;
1052 rscn
->event
[0].portid
= s_id
;
1054 return sizeof(struct fc_rscn_pl_s
);
1058 fc_rftid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
1059 enum bfa_lport_role roles
)
1061 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1062 struct fcgs_rftid_req_s
*rftid
= (struct fcgs_rftid_req_s
*)(cthdr
+ 1);
1063 u32 type_value
, d_id
= bfa_hton3b(FC_NAME_SERVER
);
1066 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
1067 fc_gs_cthdr_build(cthdr
, s_id
, GS_RFT_ID
);
1069 memset(rftid
, 0, sizeof(struct fcgs_rftid_req_s
));
1073 /* By default, FCP FC4 Type is registered */
1074 index
= FC_TYPE_FCP
>> 5;
1075 type_value
= 1 << (FC_TYPE_FCP
% 32);
1076 rftid
->fc4_type
[index
] = cpu_to_be32(type_value
);
1078 return sizeof(struct fcgs_rftid_req_s
) + sizeof(struct ct_hdr_s
);
1082 fc_rftid_build_sol(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
1083 u8
*fc4_bitmap
, u32 bitmap_size
)
1085 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1086 struct fcgs_rftid_req_s
*rftid
= (struct fcgs_rftid_req_s
*)(cthdr
+ 1);
1087 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
1089 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
1090 fc_gs_cthdr_build(cthdr
, s_id
, GS_RFT_ID
);
1092 memset(rftid
, 0, sizeof(struct fcgs_rftid_req_s
));
1095 memcpy((void *)rftid
->fc4_type
, (void *)fc4_bitmap
,
1096 (bitmap_size
< 32 ? bitmap_size
: 32));
1098 return sizeof(struct fcgs_rftid_req_s
) + sizeof(struct ct_hdr_s
);
1102 fc_rffid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
1103 u8 fc4_type
, u8 fc4_ftrs
)
1105 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1106 struct fcgs_rffid_req_s
*rffid
= (struct fcgs_rffid_req_s
*)(cthdr
+ 1);
1107 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
1109 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
1110 fc_gs_cthdr_build(cthdr
, s_id
, GS_RFF_ID
);
1112 memset(rffid
, 0, sizeof(struct fcgs_rffid_req_s
));
1115 rffid
->fc4ftr_bits
= fc4_ftrs
;
1116 rffid
->fc4_type
= fc4_type
;
1118 return sizeof(struct fcgs_rffid_req_s
) + sizeof(struct ct_hdr_s
);
1122 fc_rspnid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u16 ox_id
,
1126 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1127 struct fcgs_rspnid_req_s
*rspnid
=
1128 (struct fcgs_rspnid_req_s
*)(cthdr
+ 1);
1129 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
1131 fc_gs_fchdr_build(fchs
, d_id
, s_id
, ox_id
);
1132 fc_gs_cthdr_build(cthdr
, s_id
, GS_RSPN_ID
);
1134 memset(rspnid
, 0, sizeof(struct fcgs_rspnid_req_s
));
1137 strlcpy(rspnid
->spn
, name
, sizeof(rspnid
->spn
));
1138 rspnid
->spn_len
= (u8
) strlen(rspnid
->spn
);
1140 return sizeof(struct fcgs_rspnid_req_s
) + sizeof(struct ct_hdr_s
);
1144 fc_rsnn_nn_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
,
1145 wwn_t node_name
, u8
*name
)
1147 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1148 struct fcgs_rsnn_nn_req_s
*rsnn_nn
=
1149 (struct fcgs_rsnn_nn_req_s
*) (cthdr
+ 1);
1150 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
1152 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
1153 fc_gs_cthdr_build(cthdr
, s_id
, GS_RSNN_NN
);
1155 memset(rsnn_nn
, 0, sizeof(struct fcgs_rsnn_nn_req_s
));
1157 rsnn_nn
->node_name
= node_name
;
1158 strlcpy(rsnn_nn
->snn
, name
, sizeof(rsnn_nn
->snn
));
1159 rsnn_nn
->snn_len
= (u8
) strlen(rsnn_nn
->snn
);
1161 return sizeof(struct fcgs_rsnn_nn_req_s
) + sizeof(struct ct_hdr_s
);
1165 fc_gid_ft_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u8 fc4_type
)
1168 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1169 struct fcgs_gidft_req_s
*gidft
= (struct fcgs_gidft_req_s
*)(cthdr
+ 1);
1170 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
1172 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
1174 fc_gs_cthdr_build(cthdr
, s_id
, GS_GID_FT
);
1176 memset(gidft
, 0, sizeof(struct fcgs_gidft_req_s
));
1177 gidft
->fc4_type
= fc4_type
;
1178 gidft
->domain_id
= 0;
1181 return sizeof(struct fcgs_gidft_req_s
) + sizeof(struct ct_hdr_s
);
1185 fc_rpnid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u32 port_id
,
1188 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1189 struct fcgs_rpnid_req_s
*rpnid
= (struct fcgs_rpnid_req_s
*)(cthdr
+ 1);
1190 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
1192 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
1193 fc_gs_cthdr_build(cthdr
, s_id
, GS_RPN_ID
);
1195 memset(rpnid
, 0, sizeof(struct fcgs_rpnid_req_s
));
1196 rpnid
->port_id
= port_id
;
1197 rpnid
->port_name
= port_name
;
1199 return sizeof(struct fcgs_rpnid_req_s
) + sizeof(struct ct_hdr_s
);
1203 fc_rnnid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u32 port_id
,
1206 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1207 struct fcgs_rnnid_req_s
*rnnid
= (struct fcgs_rnnid_req_s
*)(cthdr
+ 1);
1208 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
1210 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
1211 fc_gs_cthdr_build(cthdr
, s_id
, GS_RNN_ID
);
1213 memset(rnnid
, 0, sizeof(struct fcgs_rnnid_req_s
));
1214 rnnid
->port_id
= port_id
;
1215 rnnid
->node_name
= node_name
;
1217 return sizeof(struct fcgs_rnnid_req_s
) + sizeof(struct ct_hdr_s
);
1221 fc_rcsid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u32 port_id
,
1224 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1225 struct fcgs_rcsid_req_s
*rcsid
=
1226 (struct fcgs_rcsid_req_s
*) (cthdr
+ 1);
1227 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
1229 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
1230 fc_gs_cthdr_build(cthdr
, s_id
, GS_RCS_ID
);
1232 memset(rcsid
, 0, sizeof(struct fcgs_rcsid_req_s
));
1233 rcsid
->port_id
= port_id
;
1236 return sizeof(struct fcgs_rcsid_req_s
) + sizeof(struct ct_hdr_s
);
1240 fc_rptid_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u32 port_id
,
1243 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1244 struct fcgs_rptid_req_s
*rptid
= (struct fcgs_rptid_req_s
*)(cthdr
+ 1);
1245 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
1247 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
1248 fc_gs_cthdr_build(cthdr
, s_id
, GS_RPT_ID
);
1250 memset(rptid
, 0, sizeof(struct fcgs_rptid_req_s
));
1251 rptid
->port_id
= port_id
;
1252 rptid
->port_type
= port_type
;
1254 return sizeof(struct fcgs_rptid_req_s
) + sizeof(struct ct_hdr_s
);
1258 fc_ganxt_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, u32 port_id
)
1260 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1261 struct fcgs_ganxt_req_s
*ganxt
= (struct fcgs_ganxt_req_s
*)(cthdr
+ 1);
1262 u32 d_id
= bfa_hton3b(FC_NAME_SERVER
);
1264 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
1265 fc_gs_cthdr_build(cthdr
, s_id
, GS_GA_NXT
);
1267 memset(ganxt
, 0, sizeof(struct fcgs_ganxt_req_s
));
1268 ganxt
->port_id
= port_id
;
1270 return sizeof(struct ct_hdr_s
) + sizeof(struct fcgs_ganxt_req_s
);
1274 * Builds fc hdr and ct hdr for FDMI requests.
1277 fc_fdmi_reqhdr_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
,
1281 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1282 u32 d_id
= bfa_hton3b(FC_MGMT_SERVER
);
1284 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
1285 fc_gs_fdmi_cthdr_build(cthdr
, s_id
, cmd_code
);
1287 return sizeof(struct ct_hdr_s
);
1291 * Given a FC4 Type, this function returns a fc4 type bitmask
1294 fc_get_fc4type_bitmask(u8 fc4_type
, u8
*bit_mask
)
1297 __be32
*ptr
= (__be32
*) bit_mask
;
1301 * @todo : Check for bitmask size
1304 index
= fc4_type
>> 5;
1305 type_value
= 1 << (fc4_type
% 32);
1306 ptr
[index
] = cpu_to_be32(type_value
);
1314 fc_gmal_req_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, wwn_t wwn
)
1316 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1317 fcgs_gmal_req_t
*gmal
= (fcgs_gmal_req_t
*) (cthdr
+ 1);
1318 u32 d_id
= bfa_hton3b(FC_MGMT_SERVER
);
1320 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
1321 fc_gs_ms_cthdr_build(cthdr
, s_id
, GS_FC_GMAL_CMD
,
1322 CT_GSSUBTYPE_CFGSERVER
);
1324 memset(gmal
, 0, sizeof(fcgs_gmal_req_t
));
1327 return sizeof(struct ct_hdr_s
) + sizeof(fcgs_gmal_req_t
);
1331 * GFN (Get Fabric Name) Request
1334 fc_gfn_req_build(struct fchs_s
*fchs
, void *pyld
, u32 s_id
, wwn_t wwn
)
1336 struct ct_hdr_s
*cthdr
= (struct ct_hdr_s
*) pyld
;
1337 fcgs_gfn_req_t
*gfn
= (fcgs_gfn_req_t
*) (cthdr
+ 1);
1338 u32 d_id
= bfa_hton3b(FC_MGMT_SERVER
);
1340 fc_gs_fchdr_build(fchs
, d_id
, s_id
, 0);
1341 fc_gs_ms_cthdr_build(cthdr
, s_id
, GS_FC_GFN_CMD
,
1342 CT_GSSUBTYPE_CFGSERVER
);
1344 memset(gfn
, 0, sizeof(fcgs_gfn_req_t
));
1347 return sizeof(struct ct_hdr_s
) + sizeof(fcgs_gfn_req_t
);