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