xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcbuild.c (revision e657c18a)
1 /*
2  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
3  * Copyright (c) 2014- QLogic Corporation.
4  * All rights reserved
5  * www.qlogic.com
6  *
7  * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License (GPL) Version 2 as
11  * published by the Free Software Foundation
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  */
18 /*
19  * fcbuild.c - FC link service frame building and parsing routines
20  */
21 
22 #include "bfad_drv.h"
23 #include "bfa_fcbuild.h"
24 
25 /*
26  * static build functions
27  */
28 static void     fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
29 				 __be16 ox_id);
30 static void     fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
31 				 __be16 ox_id);
32 static struct fchs_s fc_els_req_tmpl;
33 static struct fchs_s fc_els_rsp_tmpl;
34 static struct fchs_s fc_bls_req_tmpl;
35 static struct fchs_s fc_bls_rsp_tmpl;
36 static struct fc_ba_acc_s ba_acc_tmpl;
37 static struct fc_logi_s plogi_tmpl;
38 static struct fc_prli_s prli_tmpl;
39 static struct fc_rrq_s rrq_tmpl;
40 static struct fchs_s fcp_fchs_tmpl;
41 
42 void
43 fcbuild_init(void)
44 {
45 	/*
46 	 * fc_els_req_tmpl
47 	 */
48 	fc_els_req_tmpl.routing = FC_RTG_EXT_LINK;
49 	fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST;
50 	fc_els_req_tmpl.type = FC_TYPE_ELS;
51 	fc_els_req_tmpl.f_ctl =
52 		bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
53 			      FCTL_SI_XFER);
54 	fc_els_req_tmpl.rx_id = FC_RXID_ANY;
55 
56 	/*
57 	 * fc_els_rsp_tmpl
58 	 */
59 	fc_els_rsp_tmpl.routing = FC_RTG_EXT_LINK;
60 	fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY;
61 	fc_els_rsp_tmpl.type = FC_TYPE_ELS;
62 	fc_els_rsp_tmpl.f_ctl =
63 		bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
64 			      FCTL_END_SEQ | FCTL_SI_XFER);
65 	fc_els_rsp_tmpl.rx_id = FC_RXID_ANY;
66 
67 	/*
68 	 * fc_bls_req_tmpl
69 	 */
70 	fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK;
71 	fc_bls_req_tmpl.type = FC_TYPE_BLS;
72 	fc_bls_req_tmpl.f_ctl = bfa_hton3b(FCTL_END_SEQ | FCTL_SI_XFER);
73 	fc_bls_req_tmpl.rx_id = FC_RXID_ANY;
74 
75 	/*
76 	 * fc_bls_rsp_tmpl
77 	 */
78 	fc_bls_rsp_tmpl.routing = FC_RTG_BASIC_LINK;
79 	fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC;
80 	fc_bls_rsp_tmpl.type = FC_TYPE_BLS;
81 	fc_bls_rsp_tmpl.f_ctl =
82 		bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
83 			      FCTL_END_SEQ | FCTL_SI_XFER);
84 	fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY;
85 
86 	/*
87 	 * ba_acc_tmpl
88 	 */
89 	ba_acc_tmpl.seq_id_valid = 0;
90 	ba_acc_tmpl.low_seq_cnt = 0;
91 	ba_acc_tmpl.high_seq_cnt = 0xFFFF;
92 
93 	/*
94 	 * plogi_tmpl
95 	 */
96 	plogi_tmpl.csp.verhi = FC_PH_VER_PH_3;
97 	plogi_tmpl.csp.verlo = FC_PH_VER_4_3;
98 	plogi_tmpl.csp.ciro = 0x1;
99 	plogi_tmpl.csp.cisc = 0x0;
100 	plogi_tmpl.csp.altbbcred = 0x0;
101 	plogi_tmpl.csp.conseq = cpu_to_be16(0x00FF);
102 	plogi_tmpl.csp.ro_bitmap = cpu_to_be16(0x0002);
103 	plogi_tmpl.csp.e_d_tov = cpu_to_be32(2000);
104 
105 	plogi_tmpl.class3.class_valid = 1;
106 	plogi_tmpl.class3.sequential = 1;
107 	plogi_tmpl.class3.conseq = 0xFF;
108 	plogi_tmpl.class3.ospx = 1;
109 
110 	/*
111 	 * prli_tmpl
112 	 */
113 	prli_tmpl.command = FC_ELS_PRLI;
114 	prli_tmpl.pglen = 0x10;
115 	prli_tmpl.pagebytes = cpu_to_be16(0x0014);
116 	prli_tmpl.parampage.type = FC_TYPE_FCP;
117 	prli_tmpl.parampage.imagepair = 1;
118 	prli_tmpl.parampage.servparams.rxrdisab = 1;
119 
120 	/*
121 	 * rrq_tmpl
122 	 */
123 	rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ;
124 
125 	/*
126 	 * fcp_struct fchs_s mpl
127 	 */
128 	fcp_fchs_tmpl.routing = FC_RTG_FC4_DEV_DATA;
129 	fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD;
130 	fcp_fchs_tmpl.type = FC_TYPE_FCP;
131 	fcp_fchs_tmpl.f_ctl =
132 		bfa_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER);
133 	fcp_fchs_tmpl.seq_id = 1;
134 	fcp_fchs_tmpl.rx_id = FC_RXID_ANY;
135 }
136 
137 static void
138 fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
139 {
140 	memset(fchs, 0, sizeof(struct fchs_s));
141 
142 	fchs->routing = FC_RTG_FC4_DEV_DATA;
143 	fchs->cat_info = FC_CAT_UNSOLICIT_CTRL;
144 	fchs->type = FC_TYPE_SERVICES;
145 	fchs->f_ctl =
146 		bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
147 			      FCTL_SI_XFER);
148 	fchs->rx_id = FC_RXID_ANY;
149 	fchs->d_id = (d_id);
150 	fchs->s_id = (s_id);
151 	fchs->ox_id = cpu_to_be16(ox_id);
152 
153 	/*
154 	 * @todo no need to set ox_id for request
155 	 *       no need to set rx_id for response
156 	 */
157 }
158 
159 static void
160 fc_gsresp_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
161 {
162 	memset(fchs, 0, sizeof(struct fchs_s));
163 
164 	fchs->routing = FC_RTG_FC4_DEV_DATA;
165 	fchs->cat_info = FC_CAT_SOLICIT_CTRL;
166 	fchs->type = FC_TYPE_SERVICES;
167 	fchs->f_ctl =
168 		bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
169 			   FCTL_END_SEQ | FCTL_SI_XFER);
170 	fchs->d_id = d_id;
171 	fchs->s_id = s_id;
172 	fchs->ox_id = ox_id;
173 }
174 
175 void
176 fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
177 {
178 	memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s));
179 	fchs->d_id = (d_id);
180 	fchs->s_id = (s_id);
181 	fchs->ox_id = cpu_to_be16(ox_id);
182 }
183 
184 static void
185 fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
186 {
187 	memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s));
188 	fchs->d_id = d_id;
189 	fchs->s_id = s_id;
190 	fchs->ox_id = ox_id;
191 }
192 
193 static void
194 fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
195 {
196 	memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s));
197 	fchs->d_id = d_id;
198 	fchs->s_id = s_id;
199 	fchs->ox_id = ox_id;
200 }
201 
202 static          u16
203 fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
204 		 __be16 ox_id, wwn_t port_name, wwn_t node_name,
205 		 u16 pdu_size, u16 bb_cr, u8 els_code)
206 {
207 	struct fc_logi_s *plogi = (struct fc_logi_s *) (pld);
208 
209 	memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
210 
211 	/* For FC AL bb_cr is 0 and altbbcred is 1 */
212 	if (!bb_cr)
213 		plogi->csp.altbbcred = 1;
214 
215 	plogi->els_cmd.els_code = els_code;
216 	if (els_code == FC_ELS_PLOGI)
217 		fc_els_req_build(fchs, d_id, s_id, ox_id);
218 	else
219 		fc_els_rsp_build(fchs, d_id, s_id, ox_id);
220 
221 	plogi->csp.rxsz = plogi->class3.rxsz = cpu_to_be16(pdu_size);
222 	plogi->csp.bbcred  = cpu_to_be16(bb_cr);
223 
224 	memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
225 	memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
226 
227 	return sizeof(struct fc_logi_s);
228 }
229 
230 u16
231 fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
232 		u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size,
233 	       u8 set_npiv, u8 set_auth, u16 local_bb_credits)
234 {
235 	u32        d_id = bfa_hton3b(FC_FABRIC_PORT);
236 	__be32	*vvl_info;
237 
238 	memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
239 
240 	flogi->els_cmd.els_code = FC_ELS_FLOGI;
241 	fc_els_req_build(fchs, d_id, s_id, ox_id);
242 
243 	flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
244 	flogi->port_name = port_name;
245 	flogi->node_name = node_name;
246 
247 	/*
248 	 * Set the NPIV Capability Bit ( word 1, bit 31) of Common
249 	 * Service Parameters.
250 	 */
251 	flogi->csp.ciro = set_npiv;
252 
253 	/* set AUTH capability */
254 	flogi->csp.security = set_auth;
255 
256 	flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
257 
258 	/* Set brcd token in VVL */
259 	vvl_info = (u32 *)&flogi->vvl[0];
260 
261 	/* set the flag to indicate the presence of VVL */
262 	flogi->csp.npiv_supp    = 1; /* @todo. field name is not correct */
263 	vvl_info[0]	= cpu_to_be32(FLOGI_VVL_BRCD);
264 
265 	return sizeof(struct fc_logi_s);
266 }
267 
268 u16
269 fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
270 		   __be16 ox_id, wwn_t port_name, wwn_t node_name,
271 		   u16 pdu_size, u16 local_bb_credits, u8 bb_scn)
272 {
273 	u32        d_id = 0;
274 	u16	   bbscn_rxsz = (bb_scn << 12) | pdu_size;
275 
276 	memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
277 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
278 
279 	flogi->els_cmd.els_code = FC_ELS_ACC;
280 	flogi->class3.rxsz = cpu_to_be16(pdu_size);
281 	flogi->csp.rxsz  = cpu_to_be16(bbscn_rxsz);	/* bb_scn/rxsz */
282 	flogi->port_name = port_name;
283 	flogi->node_name = node_name;
284 
285 	flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
286 
287 	return sizeof(struct fc_logi_s);
288 }
289 
290 u16
291 fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
292 		u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size)
293 {
294 	u32        d_id = bfa_hton3b(FC_FABRIC_PORT);
295 
296 	memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
297 
298 	flogi->els_cmd.els_code = FC_ELS_FDISC;
299 	fc_els_req_build(fchs, d_id, s_id, ox_id);
300 
301 	flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
302 	flogi->port_name = port_name;
303 	flogi->node_name = node_name;
304 
305 	return sizeof(struct fc_logi_s);
306 }
307 
308 u16
309 fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
310 	       u16 ox_id, wwn_t port_name, wwn_t node_name,
311 	       u16 pdu_size, u16 bb_cr)
312 {
313 	return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
314 				node_name, pdu_size, bb_cr, FC_ELS_PLOGI);
315 }
316 
317 u16
318 fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
319 		   u16 ox_id, wwn_t port_name, wwn_t node_name,
320 		   u16 pdu_size, u16 bb_cr)
321 {
322 	return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
323 				node_name, pdu_size, bb_cr, FC_ELS_ACC);
324 }
325 
326 enum fc_parse_status
327 fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
328 {
329 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
330 	struct fc_logi_s *plogi;
331 	struct fc_ls_rjt_s *ls_rjt;
332 
333 	switch (els_cmd->els_code) {
334 	case FC_ELS_LS_RJT:
335 		ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1);
336 		if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
337 			return FC_PARSE_BUSY;
338 		else
339 			return FC_PARSE_FAILURE;
340 	case FC_ELS_ACC:
341 		plogi = (struct fc_logi_s *) (fchs + 1);
342 		if (len < sizeof(struct fc_logi_s))
343 			return FC_PARSE_FAILURE;
344 
345 		if (!wwn_is_equal(plogi->port_name, port_name))
346 			return FC_PARSE_FAILURE;
347 
348 		if (!plogi->class3.class_valid)
349 			return FC_PARSE_FAILURE;
350 
351 		if (be16_to_cpu(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
352 			return FC_PARSE_FAILURE;
353 
354 		return FC_PARSE_OK;
355 	default:
356 		return FC_PARSE_FAILURE;
357 	}
358 }
359 
360 enum fc_parse_status
361 fc_plogi_parse(struct fchs_s *fchs)
362 {
363 	struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1);
364 
365 	if (plogi->class3.class_valid != 1)
366 		return FC_PARSE_FAILURE;
367 
368 	if ((be16_to_cpu(plogi->class3.rxsz) < FC_MIN_PDUSZ)
369 	    || (be16_to_cpu(plogi->class3.rxsz) > FC_MAX_PDUSZ)
370 	    || (plogi->class3.rxsz == 0))
371 		return FC_PARSE_FAILURE;
372 
373 	return FC_PARSE_OK;
374 }
375 
376 u16
377 fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
378 	      u16 ox_id)
379 {
380 	struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
381 
382 	fc_els_req_build(fchs, d_id, s_id, ox_id);
383 	memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
384 
385 	prli->command = FC_ELS_PRLI;
386 	prli->parampage.servparams.initiator     = 1;
387 	prli->parampage.servparams.retry         = 1;
388 	prli->parampage.servparams.rec_support   = 1;
389 	prli->parampage.servparams.task_retry_id = 0;
390 	prli->parampage.servparams.confirm       = 1;
391 
392 	return sizeof(struct fc_prli_s);
393 }
394 
395 u16
396 fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
397 		  __be16 ox_id, enum bfa_lport_role role)
398 {
399 	struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
400 
401 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
402 	memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
403 
404 	prli->command = FC_ELS_ACC;
405 
406 	prli->parampage.servparams.initiator = 1;
407 
408 	prli->parampage.rspcode = FC_PRLI_ACC_XQTD;
409 
410 	return sizeof(struct fc_prli_s);
411 }
412 
413 enum fc_parse_status
414 fc_prli_rsp_parse(struct fc_prli_s *prli, int len)
415 {
416 	if (len < sizeof(struct fc_prli_s))
417 		return FC_PARSE_FAILURE;
418 
419 	if (prli->command != FC_ELS_ACC)
420 		return FC_PARSE_FAILURE;
421 
422 	if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD)
423 	    && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG))
424 		return FC_PARSE_FAILURE;
425 
426 	if (prli->parampage.servparams.target != 1)
427 		return FC_PARSE_FAILURE;
428 
429 	return FC_PARSE_OK;
430 }
431 
432 enum fc_parse_status
433 fc_prli_parse(struct fc_prli_s *prli)
434 {
435 	if (prli->parampage.type != FC_TYPE_FCP)
436 		return FC_PARSE_FAILURE;
437 
438 	if (!prli->parampage.imagepair)
439 		return FC_PARSE_FAILURE;
440 
441 	if (!prli->parampage.servparams.initiator)
442 		return FC_PARSE_FAILURE;
443 
444 	return FC_PARSE_OK;
445 }
446 
447 u16
448 fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id,
449 	      u16 ox_id, wwn_t port_name)
450 {
451 	fc_els_req_build(fchs, d_id, s_id, ox_id);
452 
453 	memset(logo, '\0', sizeof(struct fc_logo_s));
454 	logo->els_cmd.els_code = FC_ELS_LOGO;
455 	logo->nport_id = (s_id);
456 	logo->orig_port_name = port_name;
457 
458 	return sizeof(struct fc_logo_s);
459 }
460 
461 static u16
462 fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
463 		 u32 s_id, __be16 ox_id, wwn_t port_name,
464 		 wwn_t node_name, u8 els_code)
465 {
466 	memset(adisc, '\0', sizeof(struct fc_adisc_s));
467 
468 	adisc->els_cmd.els_code = els_code;
469 
470 	if (els_code == FC_ELS_ADISC)
471 		fc_els_req_build(fchs, d_id, s_id, ox_id);
472 	else
473 		fc_els_rsp_build(fchs, d_id, s_id, ox_id);
474 
475 	adisc->orig_HA = 0;
476 	adisc->orig_port_name = port_name;
477 	adisc->orig_node_name = node_name;
478 	adisc->nport_id = (s_id);
479 
480 	return sizeof(struct fc_adisc_s);
481 }
482 
483 u16
484 fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
485 		u32 s_id, __be16 ox_id, wwn_t port_name, wwn_t node_name)
486 {
487 	return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
488 				node_name, FC_ELS_ADISC);
489 }
490 
491 u16
492 fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
493 		   u32 s_id, __be16 ox_id, wwn_t port_name,
494 		   wwn_t node_name)
495 {
496 	return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
497 				node_name, FC_ELS_ACC);
498 }
499 
500 enum fc_parse_status
501 fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name,
502 				 wwn_t node_name)
503 {
504 
505 	if (len < sizeof(struct fc_adisc_s))
506 		return FC_PARSE_FAILURE;
507 
508 	if (adisc->els_cmd.els_code != FC_ELS_ACC)
509 		return FC_PARSE_FAILURE;
510 
511 	if (!wwn_is_equal(adisc->orig_port_name, port_name))
512 		return FC_PARSE_FAILURE;
513 
514 	return FC_PARSE_OK;
515 }
516 
517 enum fc_parse_status
518 fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap, wwn_t node_name,
519 	       wwn_t port_name)
520 {
521 	struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld;
522 
523 	if (adisc->els_cmd.els_code != FC_ELS_ACC)
524 		return FC_PARSE_FAILURE;
525 
526 	if ((adisc->nport_id == (host_dap))
527 	    && wwn_is_equal(adisc->orig_port_name, port_name)
528 	    && wwn_is_equal(adisc->orig_node_name, node_name))
529 		return FC_PARSE_OK;
530 
531 	return FC_PARSE_FAILURE;
532 }
533 
534 enum fc_parse_status
535 fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name)
536 {
537 	struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
538 
539 	if (pdisc->class3.class_valid != 1)
540 		return FC_PARSE_FAILURE;
541 
542 	if ((be16_to_cpu(pdisc->class3.rxsz) <
543 		(FC_MIN_PDUSZ - sizeof(struct fchs_s)))
544 	    || (pdisc->class3.rxsz == 0))
545 		return FC_PARSE_FAILURE;
546 
547 	if (!wwn_is_equal(pdisc->port_name, port_name))
548 		return FC_PARSE_FAILURE;
549 
550 	if (!wwn_is_equal(pdisc->node_name, node_name))
551 		return FC_PARSE_FAILURE;
552 
553 	return FC_PARSE_OK;
554 }
555 
556 u16
557 fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
558 {
559 	memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s));
560 	fchs->cat_info = FC_CAT_ABTS;
561 	fchs->d_id = (d_id);
562 	fchs->s_id = (s_id);
563 	fchs->ox_id = cpu_to_be16(ox_id);
564 
565 	return sizeof(struct fchs_s);
566 }
567 
568 enum fc_parse_status
569 fc_abts_rsp_parse(struct fchs_s *fchs, int len)
570 {
571 	if ((fchs->cat_info == FC_CAT_BA_ACC)
572 	    || (fchs->cat_info == FC_CAT_BA_RJT))
573 		return FC_PARSE_OK;
574 
575 	return FC_PARSE_FAILURE;
576 }
577 
578 u16
579 fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id,
580 	     u16 ox_id, u16 rrq_oxid)
581 {
582 	fc_els_req_build(fchs, d_id, s_id, ox_id);
583 
584 	/*
585 	 * build rrq payload
586 	 */
587 	memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s));
588 	rrq->s_id = (s_id);
589 	rrq->ox_id = cpu_to_be16(rrq_oxid);
590 	rrq->rx_id = FC_RXID_ANY;
591 
592 	return sizeof(struct fc_rrq_s);
593 }
594 
595 u16
596 fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
597 		  __be16 ox_id)
598 {
599 	struct fc_els_cmd_s *acc = pld;
600 
601 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
602 
603 	memset(acc, 0, sizeof(struct fc_els_cmd_s));
604 	acc->els_code = FC_ELS_ACC;
605 
606 	return sizeof(struct fc_els_cmd_s);
607 }
608 
609 u16
610 fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
611 		u32 s_id, __be16 ox_id, u8 reason_code,
612 		u8 reason_code_expl)
613 {
614 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
615 	memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s));
616 
617 	ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT;
618 	ls_rjt->reason_code = reason_code;
619 	ls_rjt->reason_code_expl = reason_code_expl;
620 	ls_rjt->vendor_unique = 0x00;
621 
622 	return sizeof(struct fc_ls_rjt_s);
623 }
624 
625 u16
626 fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
627 		u32 s_id, __be16 ox_id, u16 rx_id)
628 {
629 	fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
630 
631 	memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s));
632 
633 	fchs->rx_id = rx_id;
634 
635 	ba_acc->ox_id = fchs->ox_id;
636 	ba_acc->rx_id = fchs->rx_id;
637 
638 	return sizeof(struct fc_ba_acc_s);
639 }
640 
641 u16
642 fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id,
643 		u32 s_id, __be16 ox_id)
644 {
645 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
646 	memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
647 	els_cmd->els_code = FC_ELS_ACC;
648 
649 	return sizeof(struct fc_els_cmd_s);
650 }
651 
652 int
653 fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code)
654 {
655 	int             num_pages = 0;
656 	struct fc_prlo_s *prlo;
657 	struct fc_tprlo_s *tprlo;
658 
659 	if (els_code == FC_ELS_PRLO) {
660 		prlo = (struct fc_prlo_s *) (fc_frame + 1);
661 		num_pages = (be16_to_cpu(prlo->payload_len) - 4) / 16;
662 	} else {
663 		tprlo = (struct fc_tprlo_s *) (fc_frame + 1);
664 		num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16;
665 	}
666 	return num_pages;
667 }
668 
669 u16
670 fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
671 		u32 d_id, u32 s_id, __be16 ox_id, int num_pages)
672 {
673 	int             page;
674 
675 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
676 
677 	memset(tprlo_acc, 0, (num_pages * 16) + 4);
678 	tprlo_acc->command = FC_ELS_ACC;
679 
680 	tprlo_acc->page_len = 0x10;
681 	tprlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
682 
683 	for (page = 0; page < num_pages; page++) {
684 		tprlo_acc->tprlo_acc_params[page].opa_valid = 0;
685 		tprlo_acc->tprlo_acc_params[page].rpa_valid = 0;
686 		tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
687 		tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0;
688 		tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0;
689 	}
690 	return be16_to_cpu(tprlo_acc->payload_len);
691 }
692 
693 u16
694 fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id,
695 		  u32 s_id, __be16 ox_id, int num_pages)
696 {
697 	int             page;
698 
699 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
700 
701 	memset(prlo_acc, 0, (num_pages * 16) + 4);
702 	prlo_acc->command = FC_ELS_ACC;
703 	prlo_acc->page_len = 0x10;
704 	prlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
705 
706 	for (page = 0; page < num_pages; page++) {
707 		prlo_acc->prlo_acc_params[page].opa_valid = 0;
708 		prlo_acc->prlo_acc_params[page].rpa_valid = 0;
709 		prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
710 		prlo_acc->prlo_acc_params[page].orig_process_assc = 0;
711 		prlo_acc->prlo_acc_params[page].resp_process_assc = 0;
712 	}
713 
714 	return be16_to_cpu(prlo_acc->payload_len);
715 }
716 
717 u16
718 fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id,
719 		u32 s_id, u16 ox_id, u32 data_format)
720 {
721 	fc_els_req_build(fchs, d_id, s_id, ox_id);
722 
723 	memset(rnid, 0, sizeof(struct fc_rnid_cmd_s));
724 
725 	rnid->els_cmd.els_code = FC_ELS_RNID;
726 	rnid->node_id_data_format = data_format;
727 
728 	return sizeof(struct fc_rnid_cmd_s);
729 }
730 
731 u16
732 fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id,
733 		  u32 s_id, __be16 ox_id, u32 data_format,
734 		  struct fc_rnid_common_id_data_s *common_id_data,
735 		  struct fc_rnid_general_topology_data_s *gen_topo_data)
736 {
737 	memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s));
738 
739 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
740 
741 	rnid_acc->els_cmd.els_code = FC_ELS_ACC;
742 	rnid_acc->node_id_data_format = data_format;
743 	rnid_acc->common_id_data_length =
744 			sizeof(struct fc_rnid_common_id_data_s);
745 	rnid_acc->common_id_data = *common_id_data;
746 
747 	if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
748 		rnid_acc->specific_id_data_length =
749 			sizeof(struct fc_rnid_general_topology_data_s);
750 		rnid_acc->gen_topology_data = *gen_topo_data;
751 		return sizeof(struct fc_rnid_acc_s);
752 	} else {
753 		return sizeof(struct fc_rnid_acc_s) -
754 			sizeof(struct fc_rnid_general_topology_data_s);
755 	}
756 
757 }
758 
759 u16
760 fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id,
761 		u32 s_id, u16 ox_id)
762 {
763 	fc_els_req_build(fchs, d_id, s_id, ox_id);
764 
765 	memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
766 
767 	rpsc->els_cmd.els_code = FC_ELS_RPSC;
768 	return sizeof(struct fc_rpsc_cmd_s);
769 }
770 
771 u16
772 fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id,
773 		u32 s_id, u32 *pid_list, u16 npids)
774 {
775 	u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_hton3b(d_id));
776 	int i = 0;
777 
778 	fc_els_req_build(fchs, bfa_hton3b(dctlr_id), s_id, 0);
779 
780 	memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
781 
782 	rpsc2->els_cmd.els_code = FC_ELS_RPSC;
783 	rpsc2->token = cpu_to_be32(FC_BRCD_TOKEN);
784 	rpsc2->num_pids  = cpu_to_be16(npids);
785 	for (i = 0; i < npids; i++)
786 		rpsc2->pid_list[i].pid = pid_list[i];
787 
788 	return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) * (sizeof(u32)));
789 }
790 
791 u16
792 fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
793 		u32 d_id, u32 s_id, __be16 ox_id,
794 		  struct fc_rpsc_speed_info_s *oper_speed)
795 {
796 	memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
797 
798 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
799 
800 	rpsc_acc->command = FC_ELS_ACC;
801 	rpsc_acc->num_entries = cpu_to_be16(1);
802 
803 	rpsc_acc->speed_info[0].port_speed_cap =
804 		cpu_to_be16(oper_speed->port_speed_cap);
805 
806 	rpsc_acc->speed_info[0].port_op_speed =
807 		cpu_to_be16(oper_speed->port_op_speed);
808 
809 	return sizeof(struct fc_rpsc_acc_s);
810 }
811 
812 u16
813 fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
814 	       wwn_t port_name, wwn_t node_name, u16 pdu_size)
815 {
816 	struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
817 
818 	memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s));
819 
820 	pdisc->els_cmd.els_code = FC_ELS_PDISC;
821 	fc_els_req_build(fchs, d_id, s_id, ox_id);
822 
823 	pdisc->csp.rxsz = pdisc->class3.rxsz = cpu_to_be16(pdu_size);
824 	pdisc->port_name = port_name;
825 	pdisc->node_name = node_name;
826 
827 	return sizeof(struct fc_logi_s);
828 }
829 
830 u16
831 fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
832 {
833 	struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
834 
835 	if (len < sizeof(struct fc_logi_s))
836 		return FC_PARSE_LEN_INVAL;
837 
838 	if (pdisc->els_cmd.els_code != FC_ELS_ACC)
839 		return FC_PARSE_ACC_INVAL;
840 
841 	if (!wwn_is_equal(pdisc->port_name, port_name))
842 		return FC_PARSE_PWWN_NOT_EQUAL;
843 
844 	if (!pdisc->class3.class_valid)
845 		return FC_PARSE_NWWN_NOT_EQUAL;
846 
847 	if (be16_to_cpu(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
848 		return FC_PARSE_RXSZ_INVAL;
849 
850 	return FC_PARSE_OK;
851 }
852 
853 u16
854 fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
855 	      int num_pages)
856 {
857 	struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1);
858 	int             page;
859 
860 	fc_els_req_build(fchs, d_id, s_id, ox_id);
861 	memset(prlo, 0, (num_pages * 16) + 4);
862 	prlo->command = FC_ELS_PRLO;
863 	prlo->page_len = 0x10;
864 	prlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
865 
866 	for (page = 0; page < num_pages; page++) {
867 		prlo->prlo_params[page].type = FC_TYPE_FCP;
868 		prlo->prlo_params[page].opa_valid = 0;
869 		prlo->prlo_params[page].rpa_valid = 0;
870 		prlo->prlo_params[page].orig_process_assc = 0;
871 		prlo->prlo_params[page].resp_process_assc = 0;
872 	}
873 
874 	return be16_to_cpu(prlo->payload_len);
875 }
876 
877 u16
878 fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
879 	       int num_pages, enum fc_tprlo_type tprlo_type, u32 tpr_id)
880 {
881 	struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1);
882 	int             page;
883 
884 	fc_els_req_build(fchs, d_id, s_id, ox_id);
885 	memset(tprlo, 0, (num_pages * 16) + 4);
886 	tprlo->command = FC_ELS_TPRLO;
887 	tprlo->page_len = 0x10;
888 	tprlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
889 
890 	for (page = 0; page < num_pages; page++) {
891 		tprlo->tprlo_params[page].type = FC_TYPE_FCP;
892 		tprlo->tprlo_params[page].opa_valid = 0;
893 		tprlo->tprlo_params[page].rpa_valid = 0;
894 		tprlo->tprlo_params[page].orig_process_assc = 0;
895 		tprlo->tprlo_params[page].resp_process_assc = 0;
896 		if (tprlo_type == FC_GLOBAL_LOGO) {
897 			tprlo->tprlo_params[page].global_process_logout = 1;
898 		} else if (tprlo_type == FC_TPR_LOGO) {
899 			tprlo->tprlo_params[page].tpo_nport_valid = 1;
900 			tprlo->tprlo_params[page].tpo_nport_id = (tpr_id);
901 		}
902 	}
903 
904 	return be16_to_cpu(tprlo->payload_len);
905 }
906 
907 u16
908 fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id,
909 		u32 reason_code, u32 reason_expl)
910 {
911 	struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1);
912 
913 	fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
914 
915 	fchs->cat_info = FC_CAT_BA_RJT;
916 	ba_rjt->reason_code = reason_code;
917 	ba_rjt->reason_expl = reason_expl;
918 	return sizeof(struct fc_ba_rjt_s);
919 }
920 
921 static void
922 fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
923 {
924 	memset(cthdr, 0, sizeof(struct ct_hdr_s));
925 	cthdr->rev_id = CT_GS3_REVISION;
926 	cthdr->gs_type = CT_GSTYPE_DIRSERVICE;
927 	cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER;
928 	cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
929 }
930 
931 static void
932 fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
933 {
934 	memset(cthdr, 0, sizeof(struct ct_hdr_s));
935 	cthdr->rev_id = CT_GS3_REVISION;
936 	cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
937 	cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER;
938 	cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
939 }
940 
941 static void
942 fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code,
943 					 u8 sub_type)
944 {
945 	memset(cthdr, 0, sizeof(struct ct_hdr_s));
946 	cthdr->rev_id = CT_GS3_REVISION;
947 	cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
948 	cthdr->gs_sub_type = sub_type;
949 	cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
950 }
951 
952 u16
953 fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
954 	       wwn_t port_name)
955 {
956 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
957 	struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1);
958 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
959 
960 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
961 	fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
962 
963 	memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
964 	gidpn->port_name = port_name;
965 	return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s);
966 }
967 
968 u16
969 fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
970 	       u32 port_id)
971 {
972 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
973 	fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1);
974 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
975 
976 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
977 	fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
978 
979 	memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
980 	gpnid->dap = port_id;
981 	return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s);
982 }
983 
984 u16
985 fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
986 	       u32 port_id)
987 {
988 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
989 	fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1);
990 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
991 
992 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
993 	fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
994 
995 	memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
996 	gnnid->dap = port_id;
997 	return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s);
998 }
999 
1000 u16
1001 fc_ct_rsp_parse(struct ct_hdr_s *cthdr)
1002 {
1003 	if (be16_to_cpu(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) {
1004 		if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY)
1005 			return FC_PARSE_BUSY;
1006 		else
1007 			return FC_PARSE_FAILURE;
1008 	}
1009 
1010 	return FC_PARSE_OK;
1011 }
1012 
1013 u16
1014 fc_gs_rjt_build(struct fchs_s *fchs,  struct ct_hdr_s *cthdr,
1015 		u32 d_id, u32 s_id, u16 ox_id, u8 reason_code,
1016 		u8 reason_code_expl)
1017 {
1018 	fc_gsresp_fchdr_build(fchs, d_id, s_id, ox_id);
1019 
1020 	cthdr->cmd_rsp_code = cpu_to_be16(CT_RSP_REJECT);
1021 	cthdr->rev_id = CT_GS3_REVISION;
1022 
1023 	cthdr->reason_code = reason_code;
1024 	cthdr->exp_code    = reason_code_expl;
1025 	return sizeof(struct ct_hdr_s);
1026 }
1027 
1028 u16
1029 fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
1030 		u8 set_br_reg, u32 s_id, u16 ox_id)
1031 {
1032 	u32        d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
1033 
1034 	fc_els_req_build(fchs, d_id, s_id, ox_id);
1035 
1036 	memset(scr, 0, sizeof(struct fc_scr_s));
1037 	scr->command = FC_ELS_SCR;
1038 	scr->reg_func = FC_SCR_REG_FUNC_FULL;
1039 	if (set_br_reg)
1040 		scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE;
1041 
1042 	return sizeof(struct fc_scr_s);
1043 }
1044 
1045 u16
1046 fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn,
1047 		u32 s_id, u16 ox_id)
1048 {
1049 	u32        d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
1050 	u16        payldlen;
1051 
1052 	fc_els_req_build(fchs, d_id, s_id, ox_id);
1053 	rscn->command = FC_ELS_RSCN;
1054 	rscn->pagelen = sizeof(rscn->event[0]);
1055 
1056 	payldlen = sizeof(u32) + rscn->pagelen;
1057 	rscn->payldlen = cpu_to_be16(payldlen);
1058 
1059 	rscn->event[0].format = FC_RSCN_FORMAT_PORTID;
1060 	rscn->event[0].portid = s_id;
1061 
1062 	return sizeof(struct fc_rscn_pl_s);
1063 }
1064 
1065 u16
1066 fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1067 	       enum bfa_lport_role roles)
1068 {
1069 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1070 	struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
1071 	u32        type_value, d_id = bfa_hton3b(FC_NAME_SERVER);
1072 	u8         index;
1073 
1074 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1075 	fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
1076 
1077 	memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
1078 
1079 	rftid->dap = s_id;
1080 
1081 	/* By default, FCP FC4 Type is registered */
1082 	index = FC_TYPE_FCP >> 5;
1083 	type_value = 1 << (FC_TYPE_FCP % 32);
1084 	rftid->fc4_type[index] = cpu_to_be32(type_value);
1085 
1086 	return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
1087 }
1088 
1089 u16
1090 fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1091 		   u8 *fc4_bitmap, u32 bitmap_size)
1092 {
1093 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1094 	struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
1095 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1096 
1097 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1098 	fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
1099 
1100 	memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
1101 
1102 	rftid->dap = s_id;
1103 	memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap,
1104 		(bitmap_size < 32 ? bitmap_size : 32));
1105 
1106 	return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
1107 }
1108 
1109 u16
1110 fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1111 	       u8 fc4_type, u8 fc4_ftrs)
1112 {
1113 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1114 	struct fcgs_rffid_req_s *rffid = (struct fcgs_rffid_req_s *)(cthdr + 1);
1115 	u32         d_id = bfa_hton3b(FC_NAME_SERVER);
1116 
1117 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1118 	fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID);
1119 
1120 	memset(rffid, 0, sizeof(struct fcgs_rffid_req_s));
1121 
1122 	rffid->dap	    = s_id;
1123 	rffid->fc4ftr_bits  = fc4_ftrs;
1124 	rffid->fc4_type	    = fc4_type;
1125 
1126 	return sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s);
1127 }
1128 
1129 u16
1130 fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1131 		u8 *name)
1132 {
1133 
1134 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1135 	struct fcgs_rspnid_req_s *rspnid =
1136 			(struct fcgs_rspnid_req_s *)(cthdr + 1);
1137 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1138 
1139 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1140 	fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID);
1141 
1142 	memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s));
1143 
1144 	rspnid->dap = s_id;
1145 	strlcpy(rspnid->spn, name, sizeof(rspnid->spn));
1146 	rspnid->spn_len = (u8) strlen(rspnid->spn);
1147 
1148 	return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s);
1149 }
1150 
1151 u16
1152 fc_rsnn_nn_build(struct fchs_s *fchs, void *pyld, u32 s_id,
1153 			wwn_t node_name, u8 *name)
1154 {
1155 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1156 	struct fcgs_rsnn_nn_req_s *rsnn_nn =
1157 		(struct fcgs_rsnn_nn_req_s *) (cthdr + 1);
1158 	u32	d_id = bfa_hton3b(FC_NAME_SERVER);
1159 
1160 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1161 	fc_gs_cthdr_build(cthdr, s_id, GS_RSNN_NN);
1162 
1163 	memset(rsnn_nn, 0, sizeof(struct fcgs_rsnn_nn_req_s));
1164 
1165 	rsnn_nn->node_name = node_name;
1166 	strlcpy(rsnn_nn->snn, name, sizeof(rsnn_nn->snn));
1167 	rsnn_nn->snn_len = (u8) strlen(rsnn_nn->snn);
1168 
1169 	return sizeof(struct fcgs_rsnn_nn_req_s) + sizeof(struct ct_hdr_s);
1170 }
1171 
1172 u16
1173 fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type)
1174 {
1175 
1176 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1177 	struct fcgs_gidft_req_s *gidft = (struct fcgs_gidft_req_s *)(cthdr + 1);
1178 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1179 
1180 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1181 
1182 	fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT);
1183 
1184 	memset(gidft, 0, sizeof(struct fcgs_gidft_req_s));
1185 	gidft->fc4_type = fc4_type;
1186 	gidft->domain_id = 0;
1187 	gidft->area_id = 0;
1188 
1189 	return sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s);
1190 }
1191 
1192 u16
1193 fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1194 	       wwn_t port_name)
1195 {
1196 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1197 	struct fcgs_rpnid_req_s *rpnid = (struct fcgs_rpnid_req_s *)(cthdr + 1);
1198 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1199 
1200 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1201 	fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID);
1202 
1203 	memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s));
1204 	rpnid->port_id = port_id;
1205 	rpnid->port_name = port_name;
1206 
1207 	return sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s);
1208 }
1209 
1210 u16
1211 fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1212 	       wwn_t node_name)
1213 {
1214 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1215 	struct fcgs_rnnid_req_s *rnnid = (struct fcgs_rnnid_req_s *)(cthdr + 1);
1216 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1217 
1218 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1219 	fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID);
1220 
1221 	memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s));
1222 	rnnid->port_id = port_id;
1223 	rnnid->node_name = node_name;
1224 
1225 	return sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s);
1226 }
1227 
1228 u16
1229 fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1230 	       u32 cos)
1231 {
1232 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1233 	struct fcgs_rcsid_req_s *rcsid =
1234 			(struct fcgs_rcsid_req_s *) (cthdr + 1);
1235 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1236 
1237 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1238 	fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID);
1239 
1240 	memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s));
1241 	rcsid->port_id = port_id;
1242 	rcsid->cos = cos;
1243 
1244 	return sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s);
1245 }
1246 
1247 u16
1248 fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1249 	       u8 port_type)
1250 {
1251 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1252 	struct fcgs_rptid_req_s *rptid = (struct fcgs_rptid_req_s *)(cthdr + 1);
1253 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1254 
1255 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1256 	fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID);
1257 
1258 	memset(rptid, 0, sizeof(struct fcgs_rptid_req_s));
1259 	rptid->port_id = port_id;
1260 	rptid->port_type = port_type;
1261 
1262 	return sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s);
1263 }
1264 
1265 u16
1266 fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id)
1267 {
1268 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1269 	struct fcgs_ganxt_req_s *ganxt = (struct fcgs_ganxt_req_s *)(cthdr + 1);
1270 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1271 
1272 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1273 	fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT);
1274 
1275 	memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s));
1276 	ganxt->port_id = port_id;
1277 
1278 	return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s);
1279 }
1280 
1281 /*
1282  * Builds fc hdr and ct hdr for FDMI requests.
1283  */
1284 u16
1285 fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
1286 		     u16 cmd_code)
1287 {
1288 
1289 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1290 	u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
1291 
1292 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1293 	fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code);
1294 
1295 	return sizeof(struct ct_hdr_s);
1296 }
1297 
1298 /*
1299  * Given a FC4 Type, this function returns a fc4 type bitmask
1300  */
1301 void
1302 fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask)
1303 {
1304 	u8         index;
1305 	__be32       *ptr = (__be32 *) bit_mask;
1306 	u32        type_value;
1307 
1308 	/*
1309 	 * @todo : Check for bitmask size
1310 	 */
1311 
1312 	index = fc4_type >> 5;
1313 	type_value = 1 << (fc4_type % 32);
1314 	ptr[index] = cpu_to_be32(type_value);
1315 
1316 }
1317 
1318 /*
1319  *	GMAL Request
1320  */
1321 u16
1322 fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
1323 {
1324 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1325 	fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1);
1326 	u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
1327 
1328 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1329 	fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD,
1330 			CT_GSSUBTYPE_CFGSERVER);
1331 
1332 	memset(gmal, 0, sizeof(fcgs_gmal_req_t));
1333 	gmal->wwn = wwn;
1334 
1335 	return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t);
1336 }
1337 
1338 /*
1339  * GFN (Get Fabric Name) Request
1340  */
1341 u16
1342 fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
1343 {
1344 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1345 	fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1);
1346 	u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
1347 
1348 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1349 	fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD,
1350 			CT_GSSUBTYPE_CFGSERVER);
1351 
1352 	memset(gfn, 0, sizeof(fcgs_gfn_req_t));
1353 	gfn->wwn = wwn;
1354 
1355 	return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t);
1356 }
1357