xref: /linux/drivers/scsi/bfa/bfa_fcbuild.c (revision d7be54cc5c5f6f9cb9ac67462aadda57813698b8)
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 
158*d7be54ccSKrishna Gudipati static void
159*d7be54ccSKrishna Gudipati fc_gsresp_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
160*d7be54ccSKrishna Gudipati {
161*d7be54ccSKrishna Gudipati 	memset(fchs, 0, sizeof(struct fchs_s));
162*d7be54ccSKrishna Gudipati 
163*d7be54ccSKrishna Gudipati 	fchs->routing = FC_RTG_FC4_DEV_DATA;
164*d7be54ccSKrishna Gudipati 	fchs->cat_info = FC_CAT_SOLICIT_CTRL;
165*d7be54ccSKrishna Gudipati 	fchs->type = FC_TYPE_SERVICES;
166*d7be54ccSKrishna Gudipati 	fchs->f_ctl =
167*d7be54ccSKrishna Gudipati 		bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
168*d7be54ccSKrishna Gudipati 			   FCTL_END_SEQ | FCTL_SI_XFER);
169*d7be54ccSKrishna Gudipati 	fchs->d_id = d_id;
170*d7be54ccSKrishna Gudipati 	fchs->s_id = s_id;
171*d7be54ccSKrishna Gudipati 	fchs->ox_id = ox_id;
172*d7be54ccSKrishna Gudipati }
173*d7be54ccSKrishna 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 
231a36c61f9SKrishna Gudipati 	plogi->els_cmd.els_code = els_code;
232a36c61f9SKrishna Gudipati 	if (els_code == FC_ELS_PLOGI)
233a36c61f9SKrishna Gudipati 		fc_els_req_build(fchs, d_id, s_id, ox_id);
234a36c61f9SKrishna Gudipati 	else
235a36c61f9SKrishna Gudipati 		fc_els_rsp_build(fchs, d_id, s_id, ox_id);
236a36c61f9SKrishna Gudipati 
237ba816ea8SJing Huang 	plogi->csp.rxsz = plogi->class3.rxsz = cpu_to_be16(pdu_size);
238be540a99SKrishna Gudipati 	plogi->csp.bbcred  = cpu_to_be16(bb_cr);
239a36c61f9SKrishna Gudipati 
2406a18b167SJing Huang 	memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
2416a18b167SJing Huang 	memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
242a36c61f9SKrishna Gudipati 
243a36c61f9SKrishna Gudipati 	return sizeof(struct fc_logi_s);
244a36c61f9SKrishna Gudipati }
245a36c61f9SKrishna Gudipati 
246a36c61f9SKrishna Gudipati u16
247a36c61f9SKrishna Gudipati fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
248a36c61f9SKrishna Gudipati 		u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size,
249a36c61f9SKrishna Gudipati 	       u8 set_npiv, u8 set_auth, u16 local_bb_credits)
250a36c61f9SKrishna Gudipati {
251f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_FABRIC_PORT);
25250444a34SMaggie 	__be32	*vvl_info;
253a36c61f9SKrishna Gudipati 
2546a18b167SJing Huang 	memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
255a36c61f9SKrishna Gudipati 
256a36c61f9SKrishna Gudipati 	flogi->els_cmd.els_code = FC_ELS_FLOGI;
257a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
258a36c61f9SKrishna Gudipati 
259ba816ea8SJing Huang 	flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
260a36c61f9SKrishna Gudipati 	flogi->port_name = port_name;
261a36c61f9SKrishna Gudipati 	flogi->node_name = node_name;
262a36c61f9SKrishna Gudipati 
263a36c61f9SKrishna Gudipati 	/*
264a36c61f9SKrishna Gudipati 	 * Set the NPIV Capability Bit ( word 1, bit 31) of Common
265a36c61f9SKrishna Gudipati 	 * Service Parameters.
266a36c61f9SKrishna Gudipati 	 */
267a36c61f9SKrishna Gudipati 	flogi->csp.ciro = set_npiv;
268a36c61f9SKrishna Gudipati 
269a36c61f9SKrishna Gudipati 	/* set AUTH capability */
270a36c61f9SKrishna Gudipati 	flogi->csp.security = set_auth;
271a36c61f9SKrishna Gudipati 
272ba816ea8SJing Huang 	flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
273a36c61f9SKrishna Gudipati 
274a36c61f9SKrishna Gudipati 	/* Set brcd token in VVL */
275a36c61f9SKrishna Gudipati 	vvl_info = (u32 *)&flogi->vvl[0];
276a36c61f9SKrishna Gudipati 
277a36c61f9SKrishna Gudipati 	/* set the flag to indicate the presence of VVL */
278a36c61f9SKrishna Gudipati 	flogi->csp.npiv_supp    = 1; /* @todo. field name is not correct */
279ba816ea8SJing Huang 	vvl_info[0]	= cpu_to_be32(FLOGI_VVL_BRCD);
280a36c61f9SKrishna Gudipati 
281a36c61f9SKrishna Gudipati 	return sizeof(struct fc_logi_s);
282a36c61f9SKrishna Gudipati }
283a36c61f9SKrishna Gudipati 
284a36c61f9SKrishna Gudipati u16
285a36c61f9SKrishna Gudipati fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
28650444a34SMaggie 		   __be16 ox_id, wwn_t port_name, wwn_t node_name,
287be540a99SKrishna Gudipati 		   u16 pdu_size, u16 local_bb_credits, u8 bb_scn)
288a36c61f9SKrishna Gudipati {
289a36c61f9SKrishna Gudipati 	u32        d_id = 0;
290be540a99SKrishna Gudipati 	u16	   bbscn_rxsz = (bb_scn << 12) | pdu_size;
291a36c61f9SKrishna Gudipati 
2926a18b167SJing Huang 	memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
293a36c61f9SKrishna Gudipati 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
294a36c61f9SKrishna Gudipati 
295a36c61f9SKrishna Gudipati 	flogi->els_cmd.els_code = FC_ELS_ACC;
296be540a99SKrishna Gudipati 	flogi->class3.rxsz = cpu_to_be16(pdu_size);
297be540a99SKrishna Gudipati 	flogi->csp.rxsz  = cpu_to_be16(bbscn_rxsz);	/* bb_scn/rxsz */
298a36c61f9SKrishna Gudipati 	flogi->port_name = port_name;
299a36c61f9SKrishna Gudipati 	flogi->node_name = node_name;
300a36c61f9SKrishna Gudipati 
301ba816ea8SJing Huang 	flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
302a36c61f9SKrishna Gudipati 
303a36c61f9SKrishna Gudipati 	return sizeof(struct fc_logi_s);
304a36c61f9SKrishna Gudipati }
305a36c61f9SKrishna Gudipati 
306a36c61f9SKrishna Gudipati u16
307a36c61f9SKrishna Gudipati fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
308a36c61f9SKrishna Gudipati 		u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size)
309a36c61f9SKrishna Gudipati {
310f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_FABRIC_PORT);
311a36c61f9SKrishna Gudipati 
3126a18b167SJing Huang 	memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
313a36c61f9SKrishna Gudipati 
314a36c61f9SKrishna Gudipati 	flogi->els_cmd.els_code = FC_ELS_FDISC;
315a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
316a36c61f9SKrishna Gudipati 
317ba816ea8SJing Huang 	flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
318a36c61f9SKrishna Gudipati 	flogi->port_name = port_name;
319a36c61f9SKrishna Gudipati 	flogi->node_name = node_name;
320a36c61f9SKrishna Gudipati 
321a36c61f9SKrishna Gudipati 	return sizeof(struct fc_logi_s);
322a36c61f9SKrishna Gudipati }
323a36c61f9SKrishna Gudipati 
324a36c61f9SKrishna Gudipati u16
325a36c61f9SKrishna Gudipati fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
326a36c61f9SKrishna Gudipati 	       u16 ox_id, wwn_t port_name, wwn_t node_name,
327be540a99SKrishna Gudipati 	       u16 pdu_size, u16 bb_cr)
328a36c61f9SKrishna Gudipati {
329a36c61f9SKrishna Gudipati 	return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
330be540a99SKrishna Gudipati 				node_name, pdu_size, bb_cr, FC_ELS_PLOGI);
331a36c61f9SKrishna Gudipati }
332a36c61f9SKrishna Gudipati 
333a36c61f9SKrishna Gudipati u16
334a36c61f9SKrishna Gudipati fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
335a36c61f9SKrishna Gudipati 		   u16 ox_id, wwn_t port_name, wwn_t node_name,
336be540a99SKrishna Gudipati 		   u16 pdu_size, u16 bb_cr)
337a36c61f9SKrishna Gudipati {
338a36c61f9SKrishna Gudipati 	return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
339be540a99SKrishna Gudipati 				node_name, pdu_size, bb_cr, FC_ELS_ACC);
340a36c61f9SKrishna Gudipati }
341a36c61f9SKrishna Gudipati 
342a36c61f9SKrishna Gudipati enum fc_parse_status
343a36c61f9SKrishna Gudipati fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
344a36c61f9SKrishna Gudipati {
345a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
346a36c61f9SKrishna Gudipati 	struct fc_logi_s *plogi;
347a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
348a36c61f9SKrishna Gudipati 
349a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
350a36c61f9SKrishna Gudipati 	case FC_ELS_LS_RJT:
351a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1);
352a36c61f9SKrishna Gudipati 		if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
353a36c61f9SKrishna Gudipati 			return FC_PARSE_BUSY;
354a36c61f9SKrishna Gudipati 		else
355a36c61f9SKrishna Gudipati 			return FC_PARSE_FAILURE;
356a36c61f9SKrishna Gudipati 	case FC_ELS_ACC:
357a36c61f9SKrishna Gudipati 		plogi = (struct fc_logi_s *) (fchs + 1);
358a36c61f9SKrishna Gudipati 		if (len < sizeof(struct fc_logi_s))
359a36c61f9SKrishna Gudipati 			return FC_PARSE_FAILURE;
360a36c61f9SKrishna Gudipati 
361a36c61f9SKrishna Gudipati 		if (!wwn_is_equal(plogi->port_name, port_name))
362a36c61f9SKrishna Gudipati 			return FC_PARSE_FAILURE;
363a36c61f9SKrishna Gudipati 
364a36c61f9SKrishna Gudipati 		if (!plogi->class3.class_valid)
365a36c61f9SKrishna Gudipati 			return FC_PARSE_FAILURE;
366a36c61f9SKrishna Gudipati 
367ba816ea8SJing Huang 		if (be16_to_cpu(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
368a36c61f9SKrishna Gudipati 			return FC_PARSE_FAILURE;
369a36c61f9SKrishna Gudipati 
370a36c61f9SKrishna Gudipati 		return FC_PARSE_OK;
371a36c61f9SKrishna Gudipati 	default:
372a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
373a36c61f9SKrishna Gudipati 	}
374a36c61f9SKrishna Gudipati }
375a36c61f9SKrishna Gudipati 
376a36c61f9SKrishna Gudipati enum fc_parse_status
377a36c61f9SKrishna Gudipati fc_plogi_parse(struct fchs_s *fchs)
378a36c61f9SKrishna Gudipati {
379a36c61f9SKrishna Gudipati 	struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1);
380a36c61f9SKrishna Gudipati 
381a36c61f9SKrishna Gudipati 	if (plogi->class3.class_valid != 1)
382a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
383a36c61f9SKrishna Gudipati 
384ba816ea8SJing Huang 	if ((be16_to_cpu(plogi->class3.rxsz) < FC_MIN_PDUSZ)
385ba816ea8SJing Huang 	    || (be16_to_cpu(plogi->class3.rxsz) > FC_MAX_PDUSZ)
386a36c61f9SKrishna Gudipati 	    || (plogi->class3.rxsz == 0))
387a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
388a36c61f9SKrishna Gudipati 
389a36c61f9SKrishna Gudipati 	return FC_PARSE_OK;
390a36c61f9SKrishna Gudipati }
391a36c61f9SKrishna Gudipati 
392a36c61f9SKrishna Gudipati u16
393a36c61f9SKrishna Gudipati fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
394a36c61f9SKrishna Gudipati 	      u16 ox_id)
395a36c61f9SKrishna Gudipati {
396a36c61f9SKrishna Gudipati 	struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
397a36c61f9SKrishna Gudipati 
398a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
3996a18b167SJing Huang 	memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
400a36c61f9SKrishna Gudipati 
401a36c61f9SKrishna Gudipati 	prli->command = FC_ELS_PRLI;
402a36c61f9SKrishna Gudipati 	prli->parampage.servparams.initiator     = 1;
403a36c61f9SKrishna Gudipati 	prli->parampage.servparams.retry         = 1;
404a36c61f9SKrishna Gudipati 	prli->parampage.servparams.rec_support   = 1;
405a36c61f9SKrishna Gudipati 	prli->parampage.servparams.task_retry_id = 0;
406a36c61f9SKrishna Gudipati 	prli->parampage.servparams.confirm       = 1;
407a36c61f9SKrishna Gudipati 
408a36c61f9SKrishna Gudipati 	return sizeof(struct fc_prli_s);
409a36c61f9SKrishna Gudipati }
410a36c61f9SKrishna Gudipati 
411a36c61f9SKrishna Gudipati u16
412a36c61f9SKrishna Gudipati fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
41350444a34SMaggie 		  __be16 ox_id, enum bfa_lport_role role)
414a36c61f9SKrishna Gudipati {
415a36c61f9SKrishna Gudipati 	struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
416a36c61f9SKrishna Gudipati 
417a36c61f9SKrishna Gudipati 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
4186a18b167SJing Huang 	memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
419a36c61f9SKrishna Gudipati 
420a36c61f9SKrishna Gudipati 	prli->command = FC_ELS_ACC;
421a36c61f9SKrishna Gudipati 
422a36c61f9SKrishna Gudipati 	prli->parampage.servparams.initiator = 1;
423a36c61f9SKrishna Gudipati 
424a36c61f9SKrishna Gudipati 	prli->parampage.rspcode = FC_PRLI_ACC_XQTD;
425a36c61f9SKrishna Gudipati 
426a36c61f9SKrishna Gudipati 	return sizeof(struct fc_prli_s);
427a36c61f9SKrishna Gudipati }
428a36c61f9SKrishna Gudipati 
429a36c61f9SKrishna Gudipati enum fc_parse_status
430a36c61f9SKrishna Gudipati fc_prli_rsp_parse(struct fc_prli_s *prli, int len)
431a36c61f9SKrishna Gudipati {
432a36c61f9SKrishna Gudipati 	if (len < sizeof(struct fc_prli_s))
433a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
434a36c61f9SKrishna Gudipati 
435a36c61f9SKrishna Gudipati 	if (prli->command != FC_ELS_ACC)
436a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
437a36c61f9SKrishna Gudipati 
438a36c61f9SKrishna Gudipati 	if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD)
439a36c61f9SKrishna Gudipati 	    && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG))
440a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
441a36c61f9SKrishna Gudipati 
442a36c61f9SKrishna Gudipati 	if (prli->parampage.servparams.target != 1)
443a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
444a36c61f9SKrishna Gudipati 
445a36c61f9SKrishna Gudipati 	return FC_PARSE_OK;
446a36c61f9SKrishna Gudipati }
447a36c61f9SKrishna Gudipati 
448a36c61f9SKrishna Gudipati enum fc_parse_status
449a36c61f9SKrishna Gudipati fc_prli_parse(struct fc_prli_s *prli)
450a36c61f9SKrishna Gudipati {
451a36c61f9SKrishna Gudipati 	if (prli->parampage.type != FC_TYPE_FCP)
452a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
453a36c61f9SKrishna Gudipati 
454a36c61f9SKrishna Gudipati 	if (!prli->parampage.imagepair)
455a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
456a36c61f9SKrishna Gudipati 
457a36c61f9SKrishna Gudipati 	if (!prli->parampage.servparams.initiator)
458a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
459a36c61f9SKrishna Gudipati 
460a36c61f9SKrishna Gudipati 	return FC_PARSE_OK;
461a36c61f9SKrishna Gudipati }
462a36c61f9SKrishna Gudipati 
463a36c61f9SKrishna Gudipati u16
464a36c61f9SKrishna Gudipati fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id,
465a36c61f9SKrishna Gudipati 	      u16 ox_id, wwn_t port_name)
466a36c61f9SKrishna Gudipati {
467a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
468a36c61f9SKrishna Gudipati 
4696a18b167SJing Huang 	memset(logo, '\0', sizeof(struct fc_logo_s));
470a36c61f9SKrishna Gudipati 	logo->els_cmd.els_code = FC_ELS_LOGO;
471a36c61f9SKrishna Gudipati 	logo->nport_id = (s_id);
472a36c61f9SKrishna Gudipati 	logo->orig_port_name = port_name;
473a36c61f9SKrishna Gudipati 
474a36c61f9SKrishna Gudipati 	return sizeof(struct fc_logo_s);
475a36c61f9SKrishna Gudipati }
476a36c61f9SKrishna Gudipati 
477a36c61f9SKrishna Gudipati static u16
478a36c61f9SKrishna Gudipati fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
47950444a34SMaggie 		 u32 s_id, __be16 ox_id, wwn_t port_name,
480a36c61f9SKrishna Gudipati 		 wwn_t node_name, u8 els_code)
481a36c61f9SKrishna Gudipati {
4826a18b167SJing Huang 	memset(adisc, '\0', sizeof(struct fc_adisc_s));
483a36c61f9SKrishna Gudipati 
484a36c61f9SKrishna Gudipati 	adisc->els_cmd.els_code = els_code;
485a36c61f9SKrishna Gudipati 
486a36c61f9SKrishna Gudipati 	if (els_code == FC_ELS_ADISC)
487a36c61f9SKrishna Gudipati 		fc_els_req_build(fchs, d_id, s_id, ox_id);
488a36c61f9SKrishna Gudipati 	else
489a36c61f9SKrishna Gudipati 		fc_els_rsp_build(fchs, d_id, s_id, ox_id);
490a36c61f9SKrishna Gudipati 
491a36c61f9SKrishna Gudipati 	adisc->orig_HA = 0;
492a36c61f9SKrishna Gudipati 	adisc->orig_port_name = port_name;
493a36c61f9SKrishna Gudipati 	adisc->orig_node_name = node_name;
494a36c61f9SKrishna Gudipati 	adisc->nport_id = (s_id);
495a36c61f9SKrishna Gudipati 
496a36c61f9SKrishna Gudipati 	return sizeof(struct fc_adisc_s);
497a36c61f9SKrishna Gudipati }
498a36c61f9SKrishna Gudipati 
499a36c61f9SKrishna Gudipati u16
500a36c61f9SKrishna Gudipati fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
50150444a34SMaggie 		u32 s_id, __be16 ox_id, wwn_t port_name, wwn_t node_name)
502a36c61f9SKrishna Gudipati {
503a36c61f9SKrishna Gudipati 	return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
504a36c61f9SKrishna Gudipati 				node_name, FC_ELS_ADISC);
505a36c61f9SKrishna Gudipati }
506a36c61f9SKrishna Gudipati 
507a36c61f9SKrishna Gudipati u16
508a36c61f9SKrishna Gudipati fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
50950444a34SMaggie 		   u32 s_id, __be16 ox_id, wwn_t port_name,
510a36c61f9SKrishna Gudipati 		   wwn_t node_name)
511a36c61f9SKrishna Gudipati {
512a36c61f9SKrishna Gudipati 	return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
513a36c61f9SKrishna Gudipati 				node_name, FC_ELS_ACC);
514a36c61f9SKrishna Gudipati }
515a36c61f9SKrishna Gudipati 
516a36c61f9SKrishna Gudipati enum fc_parse_status
517a36c61f9SKrishna Gudipati fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name,
518a36c61f9SKrishna Gudipati 				 wwn_t node_name)
519a36c61f9SKrishna Gudipati {
520a36c61f9SKrishna Gudipati 
521a36c61f9SKrishna Gudipati 	if (len < sizeof(struct fc_adisc_s))
522a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
523a36c61f9SKrishna Gudipati 
524a36c61f9SKrishna Gudipati 	if (adisc->els_cmd.els_code != FC_ELS_ACC)
525a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
526a36c61f9SKrishna Gudipati 
527a36c61f9SKrishna Gudipati 	if (!wwn_is_equal(adisc->orig_port_name, port_name))
528a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
529a36c61f9SKrishna Gudipati 
530a36c61f9SKrishna Gudipati 	return FC_PARSE_OK;
531a36c61f9SKrishna Gudipati }
532a36c61f9SKrishna Gudipati 
533a36c61f9SKrishna Gudipati enum fc_parse_status
534a36c61f9SKrishna Gudipati fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap, wwn_t node_name,
535a36c61f9SKrishna Gudipati 	       wwn_t port_name)
536a36c61f9SKrishna Gudipati {
537a36c61f9SKrishna Gudipati 	struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld;
538a36c61f9SKrishna Gudipati 
539a36c61f9SKrishna Gudipati 	if (adisc->els_cmd.els_code != FC_ELS_ACC)
540a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
541a36c61f9SKrishna Gudipati 
542a36c61f9SKrishna Gudipati 	if ((adisc->nport_id == (host_dap))
543a36c61f9SKrishna Gudipati 	    && wwn_is_equal(adisc->orig_port_name, port_name)
544a36c61f9SKrishna Gudipati 	    && wwn_is_equal(adisc->orig_node_name, node_name))
545a36c61f9SKrishna Gudipati 		return FC_PARSE_OK;
546a36c61f9SKrishna Gudipati 
547a36c61f9SKrishna Gudipati 	return FC_PARSE_FAILURE;
548a36c61f9SKrishna Gudipati }
549a36c61f9SKrishna Gudipati 
550a36c61f9SKrishna Gudipati enum fc_parse_status
551a36c61f9SKrishna Gudipati fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name)
552a36c61f9SKrishna Gudipati {
553a36c61f9SKrishna Gudipati 	struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
554a36c61f9SKrishna Gudipati 
555a36c61f9SKrishna Gudipati 	if (pdisc->class3.class_valid != 1)
556a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
557a36c61f9SKrishna Gudipati 
558ba816ea8SJing Huang 	if ((be16_to_cpu(pdisc->class3.rxsz) <
559a36c61f9SKrishna Gudipati 		(FC_MIN_PDUSZ - sizeof(struct fchs_s)))
560a36c61f9SKrishna Gudipati 	    || (pdisc->class3.rxsz == 0))
561a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
562a36c61f9SKrishna Gudipati 
563a36c61f9SKrishna Gudipati 	if (!wwn_is_equal(pdisc->port_name, port_name))
564a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
565a36c61f9SKrishna Gudipati 
566a36c61f9SKrishna Gudipati 	if (!wwn_is_equal(pdisc->node_name, node_name))
567a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
568a36c61f9SKrishna Gudipati 
569a36c61f9SKrishna Gudipati 	return FC_PARSE_OK;
570a36c61f9SKrishna Gudipati }
571a36c61f9SKrishna Gudipati 
572a36c61f9SKrishna Gudipati u16
573a36c61f9SKrishna Gudipati fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
574a36c61f9SKrishna Gudipati {
5756a18b167SJing Huang 	memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s));
576a36c61f9SKrishna Gudipati 	fchs->cat_info = FC_CAT_ABTS;
577a36c61f9SKrishna Gudipati 	fchs->d_id = (d_id);
578a36c61f9SKrishna Gudipati 	fchs->s_id = (s_id);
579ba816ea8SJing Huang 	fchs->ox_id = cpu_to_be16(ox_id);
580a36c61f9SKrishna Gudipati 
581a36c61f9SKrishna Gudipati 	return sizeof(struct fchs_s);
582a36c61f9SKrishna Gudipati }
583a36c61f9SKrishna Gudipati 
584a36c61f9SKrishna Gudipati enum fc_parse_status
585a36c61f9SKrishna Gudipati fc_abts_rsp_parse(struct fchs_s *fchs, int len)
586a36c61f9SKrishna Gudipati {
587a36c61f9SKrishna Gudipati 	if ((fchs->cat_info == FC_CAT_BA_ACC)
588a36c61f9SKrishna Gudipati 	    || (fchs->cat_info == FC_CAT_BA_RJT))
589a36c61f9SKrishna Gudipati 		return FC_PARSE_OK;
590a36c61f9SKrishna Gudipati 
591a36c61f9SKrishna Gudipati 	return FC_PARSE_FAILURE;
592a36c61f9SKrishna Gudipati }
593a36c61f9SKrishna Gudipati 
594a36c61f9SKrishna Gudipati u16
595a36c61f9SKrishna Gudipati fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id,
596a36c61f9SKrishna Gudipati 	     u16 ox_id, u16 rrq_oxid)
597a36c61f9SKrishna Gudipati {
598a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
599a36c61f9SKrishna Gudipati 
600a36c61f9SKrishna Gudipati 	/*
601a36c61f9SKrishna Gudipati 	 * build rrq payload
602a36c61f9SKrishna Gudipati 	 */
6036a18b167SJing Huang 	memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s));
604a36c61f9SKrishna Gudipati 	rrq->s_id = (s_id);
605ba816ea8SJing Huang 	rrq->ox_id = cpu_to_be16(rrq_oxid);
606a36c61f9SKrishna Gudipati 	rrq->rx_id = FC_RXID_ANY;
607a36c61f9SKrishna Gudipati 
608a36c61f9SKrishna Gudipati 	return sizeof(struct fc_rrq_s);
609a36c61f9SKrishna Gudipati }
610a36c61f9SKrishna Gudipati 
611a36c61f9SKrishna Gudipati u16
612a36c61f9SKrishna Gudipati fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
61350444a34SMaggie 		  __be16 ox_id)
614a36c61f9SKrishna Gudipati {
615a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *acc = pld;
616a36c61f9SKrishna Gudipati 
617a36c61f9SKrishna Gudipati 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
618a36c61f9SKrishna Gudipati 
6196a18b167SJing Huang 	memset(acc, 0, sizeof(struct fc_els_cmd_s));
620a36c61f9SKrishna Gudipati 	acc->els_code = FC_ELS_ACC;
621a36c61f9SKrishna Gudipati 
622a36c61f9SKrishna Gudipati 	return sizeof(struct fc_els_cmd_s);
623a36c61f9SKrishna Gudipati }
624a36c61f9SKrishna Gudipati 
625a36c61f9SKrishna Gudipati u16
626a36c61f9SKrishna Gudipati fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
62750444a34SMaggie 		u32 s_id, __be16 ox_id, u8 reason_code,
628a36c61f9SKrishna Gudipati 		u8 reason_code_expl)
629a36c61f9SKrishna Gudipati {
630a36c61f9SKrishna Gudipati 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
6316a18b167SJing Huang 	memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s));
632a36c61f9SKrishna Gudipati 
633a36c61f9SKrishna Gudipati 	ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT;
634a36c61f9SKrishna Gudipati 	ls_rjt->reason_code = reason_code;
635a36c61f9SKrishna Gudipati 	ls_rjt->reason_code_expl = reason_code_expl;
636a36c61f9SKrishna Gudipati 	ls_rjt->vendor_unique = 0x00;
637a36c61f9SKrishna Gudipati 
638a36c61f9SKrishna Gudipati 	return sizeof(struct fc_ls_rjt_s);
639a36c61f9SKrishna Gudipati }
640a36c61f9SKrishna Gudipati 
641a36c61f9SKrishna Gudipati u16
642a36c61f9SKrishna Gudipati fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
64350444a34SMaggie 		u32 s_id, __be16 ox_id, u16 rx_id)
644a36c61f9SKrishna Gudipati {
645a36c61f9SKrishna Gudipati 	fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
646a36c61f9SKrishna Gudipati 
6476a18b167SJing Huang 	memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s));
648a36c61f9SKrishna Gudipati 
649a36c61f9SKrishna Gudipati 	fchs->rx_id = rx_id;
650a36c61f9SKrishna Gudipati 
651a36c61f9SKrishna Gudipati 	ba_acc->ox_id = fchs->ox_id;
652a36c61f9SKrishna Gudipati 	ba_acc->rx_id = fchs->rx_id;
653a36c61f9SKrishna Gudipati 
654a36c61f9SKrishna Gudipati 	return sizeof(struct fc_ba_acc_s);
655a36c61f9SKrishna Gudipati }
656a36c61f9SKrishna Gudipati 
657a36c61f9SKrishna Gudipati u16
658a36c61f9SKrishna Gudipati fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id,
65950444a34SMaggie 		u32 s_id, __be16 ox_id)
660a36c61f9SKrishna Gudipati {
661a36c61f9SKrishna Gudipati 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
6626a18b167SJing Huang 	memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
663a36c61f9SKrishna Gudipati 	els_cmd->els_code = FC_ELS_ACC;
664a36c61f9SKrishna Gudipati 
665a36c61f9SKrishna Gudipati 	return sizeof(struct fc_els_cmd_s);
666a36c61f9SKrishna Gudipati }
667a36c61f9SKrishna Gudipati 
668a36c61f9SKrishna Gudipati int
669a36c61f9SKrishna Gudipati fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code)
670a36c61f9SKrishna Gudipati {
671a36c61f9SKrishna Gudipati 	int             num_pages = 0;
672a36c61f9SKrishna Gudipati 	struct fc_prlo_s *prlo;
673a36c61f9SKrishna Gudipati 	struct fc_tprlo_s *tprlo;
674a36c61f9SKrishna Gudipati 
675a36c61f9SKrishna Gudipati 	if (els_code == FC_ELS_PRLO) {
676a36c61f9SKrishna Gudipati 		prlo = (struct fc_prlo_s *) (fc_frame + 1);
677ba816ea8SJing Huang 		num_pages = (be16_to_cpu(prlo->payload_len) - 4) / 16;
678a36c61f9SKrishna Gudipati 	} else {
679a36c61f9SKrishna Gudipati 		tprlo = (struct fc_tprlo_s *) (fc_frame + 1);
680ba816ea8SJing Huang 		num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16;
681a36c61f9SKrishna Gudipati 	}
682a36c61f9SKrishna Gudipati 	return num_pages;
683a36c61f9SKrishna Gudipati }
684a36c61f9SKrishna Gudipati 
685a36c61f9SKrishna Gudipati u16
686a36c61f9SKrishna Gudipati fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
68750444a34SMaggie 		u32 d_id, u32 s_id, __be16 ox_id, int num_pages)
688a36c61f9SKrishna Gudipati {
689a36c61f9SKrishna Gudipati 	int             page;
690a36c61f9SKrishna Gudipati 
691a36c61f9SKrishna Gudipati 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
692a36c61f9SKrishna Gudipati 
6936a18b167SJing Huang 	memset(tprlo_acc, 0, (num_pages * 16) + 4);
694a36c61f9SKrishna Gudipati 	tprlo_acc->command = FC_ELS_ACC;
695a36c61f9SKrishna Gudipati 
696a36c61f9SKrishna Gudipati 	tprlo_acc->page_len = 0x10;
697ba816ea8SJing Huang 	tprlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
698a36c61f9SKrishna Gudipati 
699a36c61f9SKrishna Gudipati 	for (page = 0; page < num_pages; page++) {
700a36c61f9SKrishna Gudipati 		tprlo_acc->tprlo_acc_params[page].opa_valid = 0;
701a36c61f9SKrishna Gudipati 		tprlo_acc->tprlo_acc_params[page].rpa_valid = 0;
702a36c61f9SKrishna Gudipati 		tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
703a36c61f9SKrishna Gudipati 		tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0;
704a36c61f9SKrishna Gudipati 		tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0;
705a36c61f9SKrishna Gudipati 	}
706ba816ea8SJing Huang 	return be16_to_cpu(tprlo_acc->payload_len);
707a36c61f9SKrishna Gudipati }
708a36c61f9SKrishna Gudipati 
709a36c61f9SKrishna Gudipati u16
710a36c61f9SKrishna Gudipati fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id,
71150444a34SMaggie 		  u32 s_id, __be16 ox_id, int num_pages)
712a36c61f9SKrishna Gudipati {
713a36c61f9SKrishna Gudipati 	int             page;
714a36c61f9SKrishna Gudipati 
715a36c61f9SKrishna Gudipati 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
716a36c61f9SKrishna Gudipati 
7176a18b167SJing Huang 	memset(prlo_acc, 0, (num_pages * 16) + 4);
718a36c61f9SKrishna Gudipati 	prlo_acc->command = FC_ELS_ACC;
719a36c61f9SKrishna Gudipati 	prlo_acc->page_len = 0x10;
720ba816ea8SJing Huang 	prlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
721a36c61f9SKrishna Gudipati 
722a36c61f9SKrishna Gudipati 	for (page = 0; page < num_pages; page++) {
723a36c61f9SKrishna Gudipati 		prlo_acc->prlo_acc_params[page].opa_valid = 0;
724a36c61f9SKrishna Gudipati 		prlo_acc->prlo_acc_params[page].rpa_valid = 0;
725a36c61f9SKrishna Gudipati 		prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
726a36c61f9SKrishna Gudipati 		prlo_acc->prlo_acc_params[page].orig_process_assc = 0;
727a36c61f9SKrishna Gudipati 		prlo_acc->prlo_acc_params[page].resp_process_assc = 0;
728a36c61f9SKrishna Gudipati 	}
729a36c61f9SKrishna Gudipati 
730ba816ea8SJing Huang 	return be16_to_cpu(prlo_acc->payload_len);
731a36c61f9SKrishna Gudipati }
732a36c61f9SKrishna Gudipati 
733a36c61f9SKrishna Gudipati u16
734a36c61f9SKrishna Gudipati fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id,
735a36c61f9SKrishna Gudipati 		u32 s_id, u16 ox_id, u32 data_format)
736a36c61f9SKrishna Gudipati {
737a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
738a36c61f9SKrishna Gudipati 
7396a18b167SJing Huang 	memset(rnid, 0, sizeof(struct fc_rnid_cmd_s));
740a36c61f9SKrishna Gudipati 
741a36c61f9SKrishna Gudipati 	rnid->els_cmd.els_code = FC_ELS_RNID;
742a36c61f9SKrishna Gudipati 	rnid->node_id_data_format = data_format;
743a36c61f9SKrishna Gudipati 
744a36c61f9SKrishna Gudipati 	return sizeof(struct fc_rnid_cmd_s);
745a36c61f9SKrishna Gudipati }
746a36c61f9SKrishna Gudipati 
747a36c61f9SKrishna Gudipati u16
748a36c61f9SKrishna Gudipati fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id,
74950444a34SMaggie 		  u32 s_id, __be16 ox_id, u32 data_format,
750a36c61f9SKrishna Gudipati 		  struct fc_rnid_common_id_data_s *common_id_data,
751a36c61f9SKrishna Gudipati 		  struct fc_rnid_general_topology_data_s *gen_topo_data)
752a36c61f9SKrishna Gudipati {
7536a18b167SJing Huang 	memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s));
754a36c61f9SKrishna Gudipati 
755a36c61f9SKrishna Gudipati 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
756a36c61f9SKrishna Gudipati 
757a36c61f9SKrishna Gudipati 	rnid_acc->els_cmd.els_code = FC_ELS_ACC;
758a36c61f9SKrishna Gudipati 	rnid_acc->node_id_data_format = data_format;
759a36c61f9SKrishna Gudipati 	rnid_acc->common_id_data_length =
760a36c61f9SKrishna Gudipati 			sizeof(struct fc_rnid_common_id_data_s);
761a36c61f9SKrishna Gudipati 	rnid_acc->common_id_data = *common_id_data;
762a36c61f9SKrishna Gudipati 
763a36c61f9SKrishna Gudipati 	if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
764a36c61f9SKrishna Gudipati 		rnid_acc->specific_id_data_length =
765a36c61f9SKrishna Gudipati 			sizeof(struct fc_rnid_general_topology_data_s);
7666a18b167SJing Huang 		rnid_acc->gen_topology_data = *gen_topo_data;
767a36c61f9SKrishna Gudipati 		return sizeof(struct fc_rnid_acc_s);
768a36c61f9SKrishna Gudipati 	} else {
769a36c61f9SKrishna Gudipati 		return sizeof(struct fc_rnid_acc_s) -
770a36c61f9SKrishna Gudipati 			sizeof(struct fc_rnid_general_topology_data_s);
771a36c61f9SKrishna Gudipati 	}
772a36c61f9SKrishna Gudipati 
773a36c61f9SKrishna Gudipati }
774a36c61f9SKrishna Gudipati 
775a36c61f9SKrishna Gudipati u16
776a36c61f9SKrishna Gudipati fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id,
777a36c61f9SKrishna Gudipati 		u32 s_id, u16 ox_id)
778a36c61f9SKrishna Gudipati {
779a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
780a36c61f9SKrishna Gudipati 
7816a18b167SJing Huang 	memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
782a36c61f9SKrishna Gudipati 
783a36c61f9SKrishna Gudipati 	rpsc->els_cmd.els_code = FC_ELS_RPSC;
784a36c61f9SKrishna Gudipati 	return sizeof(struct fc_rpsc_cmd_s);
785a36c61f9SKrishna Gudipati }
786a36c61f9SKrishna Gudipati 
787a36c61f9SKrishna Gudipati u16
788a36c61f9SKrishna Gudipati fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id,
789a36c61f9SKrishna Gudipati 		u32 s_id, u32 *pid_list, u16 npids)
790a36c61f9SKrishna Gudipati {
791f16a1750SMaggie Zhang 	u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_hton3b(d_id));
792a36c61f9SKrishna Gudipati 	int i = 0;
793a36c61f9SKrishna Gudipati 
794f16a1750SMaggie Zhang 	fc_els_req_build(fchs, bfa_hton3b(dctlr_id), s_id, 0);
795a36c61f9SKrishna Gudipati 
7966a18b167SJing Huang 	memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
797a36c61f9SKrishna Gudipati 
798a36c61f9SKrishna Gudipati 	rpsc2->els_cmd.els_code = FC_ELS_RPSC;
799ba816ea8SJing Huang 	rpsc2->token = cpu_to_be32(FC_BRCD_TOKEN);
800ba816ea8SJing Huang 	rpsc2->num_pids  = cpu_to_be16(npids);
801a36c61f9SKrishna Gudipati 	for (i = 0; i < npids; i++)
802a36c61f9SKrishna Gudipati 		rpsc2->pid_list[i].pid = pid_list[i];
803a36c61f9SKrishna Gudipati 
804a36c61f9SKrishna Gudipati 	return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) * (sizeof(u32)));
805a36c61f9SKrishna Gudipati }
806a36c61f9SKrishna Gudipati 
807a36c61f9SKrishna Gudipati u16
808a36c61f9SKrishna Gudipati fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
80950444a34SMaggie 		u32 d_id, u32 s_id, __be16 ox_id,
810a36c61f9SKrishna Gudipati 		  struct fc_rpsc_speed_info_s *oper_speed)
811a36c61f9SKrishna Gudipati {
8126a18b167SJing Huang 	memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
813a36c61f9SKrishna Gudipati 
814a36c61f9SKrishna Gudipati 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
815a36c61f9SKrishna Gudipati 
816a36c61f9SKrishna Gudipati 	rpsc_acc->command = FC_ELS_ACC;
817ba816ea8SJing Huang 	rpsc_acc->num_entries = cpu_to_be16(1);
818a36c61f9SKrishna Gudipati 
819a36c61f9SKrishna Gudipati 	rpsc_acc->speed_info[0].port_speed_cap =
820ba816ea8SJing Huang 		cpu_to_be16(oper_speed->port_speed_cap);
821a36c61f9SKrishna Gudipati 
822a36c61f9SKrishna Gudipati 	rpsc_acc->speed_info[0].port_op_speed =
823ba816ea8SJing Huang 		cpu_to_be16(oper_speed->port_op_speed);
824a36c61f9SKrishna Gudipati 
825a36c61f9SKrishna Gudipati 	return sizeof(struct fc_rpsc_acc_s);
826a36c61f9SKrishna Gudipati }
827a36c61f9SKrishna Gudipati 
828a36c61f9SKrishna Gudipati u16
829a36c61f9SKrishna Gudipati fc_logo_rsp_parse(struct fchs_s *fchs, int len)
830a36c61f9SKrishna Gudipati {
831a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
832a36c61f9SKrishna Gudipati 
833a36c61f9SKrishna Gudipati 	len = len;
834a36c61f9SKrishna Gudipati 	if (els_cmd->els_code != FC_ELS_ACC)
835a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
836a36c61f9SKrishna Gudipati 
837a36c61f9SKrishna Gudipati 	return FC_PARSE_OK;
838a36c61f9SKrishna Gudipati }
839a36c61f9SKrishna Gudipati 
840a36c61f9SKrishna Gudipati u16
841a36c61f9SKrishna Gudipati fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
842a36c61f9SKrishna Gudipati 	       wwn_t port_name, wwn_t node_name, u16 pdu_size)
843a36c61f9SKrishna Gudipati {
844a36c61f9SKrishna Gudipati 	struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
845a36c61f9SKrishna Gudipati 
8466a18b167SJing Huang 	memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s));
847a36c61f9SKrishna Gudipati 
848a36c61f9SKrishna Gudipati 	pdisc->els_cmd.els_code = FC_ELS_PDISC;
849a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
850a36c61f9SKrishna Gudipati 
851ba816ea8SJing Huang 	pdisc->csp.rxsz = pdisc->class3.rxsz = cpu_to_be16(pdu_size);
852a36c61f9SKrishna Gudipati 	pdisc->port_name = port_name;
853a36c61f9SKrishna Gudipati 	pdisc->node_name = node_name;
854a36c61f9SKrishna Gudipati 
855a36c61f9SKrishna Gudipati 	return sizeof(struct fc_logi_s);
856a36c61f9SKrishna Gudipati }
857a36c61f9SKrishna Gudipati 
858a36c61f9SKrishna Gudipati u16
859a36c61f9SKrishna Gudipati fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
860a36c61f9SKrishna Gudipati {
861a36c61f9SKrishna Gudipati 	struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
862a36c61f9SKrishna Gudipati 
863a36c61f9SKrishna Gudipati 	if (len < sizeof(struct fc_logi_s))
864a36c61f9SKrishna Gudipati 		return FC_PARSE_LEN_INVAL;
865a36c61f9SKrishna Gudipati 
866a36c61f9SKrishna Gudipati 	if (pdisc->els_cmd.els_code != FC_ELS_ACC)
867a36c61f9SKrishna Gudipati 		return FC_PARSE_ACC_INVAL;
868a36c61f9SKrishna Gudipati 
869a36c61f9SKrishna Gudipati 	if (!wwn_is_equal(pdisc->port_name, port_name))
870a36c61f9SKrishna Gudipati 		return FC_PARSE_PWWN_NOT_EQUAL;
871a36c61f9SKrishna Gudipati 
872a36c61f9SKrishna Gudipati 	if (!pdisc->class3.class_valid)
873a36c61f9SKrishna Gudipati 		return FC_PARSE_NWWN_NOT_EQUAL;
874a36c61f9SKrishna Gudipati 
875ba816ea8SJing Huang 	if (be16_to_cpu(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
876a36c61f9SKrishna Gudipati 		return FC_PARSE_RXSZ_INVAL;
877a36c61f9SKrishna Gudipati 
878a36c61f9SKrishna Gudipati 	return FC_PARSE_OK;
879a36c61f9SKrishna Gudipati }
880a36c61f9SKrishna Gudipati 
881a36c61f9SKrishna Gudipati u16
882a36c61f9SKrishna Gudipati fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
883a36c61f9SKrishna Gudipati 	      int num_pages)
884a36c61f9SKrishna Gudipati {
885a36c61f9SKrishna Gudipati 	struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1);
886a36c61f9SKrishna Gudipati 	int             page;
887a36c61f9SKrishna Gudipati 
888a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
8896a18b167SJing Huang 	memset(prlo, 0, (num_pages * 16) + 4);
890a36c61f9SKrishna Gudipati 	prlo->command = FC_ELS_PRLO;
891a36c61f9SKrishna Gudipati 	prlo->page_len = 0x10;
892ba816ea8SJing Huang 	prlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
893a36c61f9SKrishna Gudipati 
894a36c61f9SKrishna Gudipati 	for (page = 0; page < num_pages; page++) {
895a36c61f9SKrishna Gudipati 		prlo->prlo_params[page].type = FC_TYPE_FCP;
896a36c61f9SKrishna Gudipati 		prlo->prlo_params[page].opa_valid = 0;
897a36c61f9SKrishna Gudipati 		prlo->prlo_params[page].rpa_valid = 0;
898a36c61f9SKrishna Gudipati 		prlo->prlo_params[page].orig_process_assc = 0;
899a36c61f9SKrishna Gudipati 		prlo->prlo_params[page].resp_process_assc = 0;
900a36c61f9SKrishna Gudipati 	}
901a36c61f9SKrishna Gudipati 
902ba816ea8SJing Huang 	return be16_to_cpu(prlo->payload_len);
903a36c61f9SKrishna Gudipati }
904a36c61f9SKrishna Gudipati 
905a36c61f9SKrishna Gudipati u16
906a36c61f9SKrishna Gudipati fc_prlo_rsp_parse(struct fchs_s *fchs, int len)
907a36c61f9SKrishna Gudipati {
908a36c61f9SKrishna Gudipati 	struct fc_prlo_acc_s *prlo = (struct fc_prlo_acc_s *) (fchs + 1);
909a36c61f9SKrishna Gudipati 	int             num_pages = 0;
910a36c61f9SKrishna Gudipati 	int             page = 0;
911a36c61f9SKrishna Gudipati 
912a36c61f9SKrishna Gudipati 	len = len;
913a36c61f9SKrishna Gudipati 
914a36c61f9SKrishna Gudipati 	if (prlo->command != FC_ELS_ACC)
915a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
916a36c61f9SKrishna Gudipati 
917ba816ea8SJing Huang 	num_pages = ((be16_to_cpu(prlo->payload_len)) - 4) / 16;
918a36c61f9SKrishna Gudipati 
919a36c61f9SKrishna Gudipati 	for (page = 0; page < num_pages; page++) {
920a36c61f9SKrishna Gudipati 		if (prlo->prlo_acc_params[page].type != FC_TYPE_FCP)
921a36c61f9SKrishna Gudipati 			return FC_PARSE_FAILURE;
922a36c61f9SKrishna Gudipati 
923a36c61f9SKrishna Gudipati 		if (prlo->prlo_acc_params[page].opa_valid != 0)
924a36c61f9SKrishna Gudipati 			return FC_PARSE_FAILURE;
925a36c61f9SKrishna Gudipati 
926a36c61f9SKrishna Gudipati 		if (prlo->prlo_acc_params[page].rpa_valid != 0)
927a36c61f9SKrishna Gudipati 			return FC_PARSE_FAILURE;
928a36c61f9SKrishna Gudipati 
929a36c61f9SKrishna Gudipati 		if (prlo->prlo_acc_params[page].orig_process_assc != 0)
930a36c61f9SKrishna Gudipati 			return FC_PARSE_FAILURE;
931a36c61f9SKrishna Gudipati 
932a36c61f9SKrishna Gudipati 		if (prlo->prlo_acc_params[page].resp_process_assc != 0)
933a36c61f9SKrishna Gudipati 			return FC_PARSE_FAILURE;
934a36c61f9SKrishna Gudipati 	}
935a36c61f9SKrishna Gudipati 	return FC_PARSE_OK;
936a36c61f9SKrishna Gudipati 
937a36c61f9SKrishna Gudipati }
938a36c61f9SKrishna Gudipati 
939a36c61f9SKrishna Gudipati u16
940a36c61f9SKrishna Gudipati fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
941a36c61f9SKrishna Gudipati 	       int num_pages, enum fc_tprlo_type tprlo_type, u32 tpr_id)
942a36c61f9SKrishna Gudipati {
943a36c61f9SKrishna Gudipati 	struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1);
944a36c61f9SKrishna Gudipati 	int             page;
945a36c61f9SKrishna Gudipati 
946a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
9476a18b167SJing Huang 	memset(tprlo, 0, (num_pages * 16) + 4);
948a36c61f9SKrishna Gudipati 	tprlo->command = FC_ELS_TPRLO;
949a36c61f9SKrishna Gudipati 	tprlo->page_len = 0x10;
950ba816ea8SJing Huang 	tprlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
951a36c61f9SKrishna Gudipati 
952a36c61f9SKrishna Gudipati 	for (page = 0; page < num_pages; page++) {
953a36c61f9SKrishna Gudipati 		tprlo->tprlo_params[page].type = FC_TYPE_FCP;
954a36c61f9SKrishna Gudipati 		tprlo->tprlo_params[page].opa_valid = 0;
955a36c61f9SKrishna Gudipati 		tprlo->tprlo_params[page].rpa_valid = 0;
956a36c61f9SKrishna Gudipati 		tprlo->tprlo_params[page].orig_process_assc = 0;
957a36c61f9SKrishna Gudipati 		tprlo->tprlo_params[page].resp_process_assc = 0;
958a36c61f9SKrishna Gudipati 		if (tprlo_type == FC_GLOBAL_LOGO) {
959a36c61f9SKrishna Gudipati 			tprlo->tprlo_params[page].global_process_logout = 1;
960a36c61f9SKrishna Gudipati 		} else if (tprlo_type == FC_TPR_LOGO) {
961a36c61f9SKrishna Gudipati 			tprlo->tprlo_params[page].tpo_nport_valid = 1;
962a36c61f9SKrishna Gudipati 			tprlo->tprlo_params[page].tpo_nport_id = (tpr_id);
963a36c61f9SKrishna Gudipati 		}
964a36c61f9SKrishna Gudipati 	}
965a36c61f9SKrishna Gudipati 
966ba816ea8SJing Huang 	return be16_to_cpu(tprlo->payload_len);
967a36c61f9SKrishna Gudipati }
968a36c61f9SKrishna Gudipati 
969a36c61f9SKrishna Gudipati u16
970a36c61f9SKrishna Gudipati fc_tprlo_rsp_parse(struct fchs_s *fchs, int len)
971a36c61f9SKrishna Gudipati {
972a36c61f9SKrishna Gudipati 	struct fc_tprlo_acc_s *tprlo = (struct fc_tprlo_acc_s *) (fchs + 1);
973a36c61f9SKrishna Gudipati 	int             num_pages = 0;
974a36c61f9SKrishna Gudipati 	int             page = 0;
975a36c61f9SKrishna Gudipati 
976a36c61f9SKrishna Gudipati 	len = len;
977a36c61f9SKrishna Gudipati 
978a36c61f9SKrishna Gudipati 	if (tprlo->command != FC_ELS_ACC)
979a36c61f9SKrishna Gudipati 		return FC_PARSE_ACC_INVAL;
980a36c61f9SKrishna Gudipati 
981ba816ea8SJing Huang 	num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16;
982a36c61f9SKrishna Gudipati 
983a36c61f9SKrishna Gudipati 	for (page = 0; page < num_pages; page++) {
984a36c61f9SKrishna Gudipati 		if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP)
985a36c61f9SKrishna Gudipati 			return FC_PARSE_NOT_FCP;
986a36c61f9SKrishna Gudipati 		if (tprlo->tprlo_acc_params[page].opa_valid != 0)
987a36c61f9SKrishna Gudipati 			return FC_PARSE_OPAFLAG_INVAL;
988a36c61f9SKrishna Gudipati 		if (tprlo->tprlo_acc_params[page].rpa_valid != 0)
989a36c61f9SKrishna Gudipati 			return FC_PARSE_RPAFLAG_INVAL;
990a36c61f9SKrishna Gudipati 		if (tprlo->tprlo_acc_params[page].orig_process_assc != 0)
991a36c61f9SKrishna Gudipati 			return FC_PARSE_OPA_INVAL;
992a36c61f9SKrishna Gudipati 		if (tprlo->tprlo_acc_params[page].resp_process_assc != 0)
993a36c61f9SKrishna Gudipati 			return FC_PARSE_RPA_INVAL;
994a36c61f9SKrishna Gudipati 	}
995a36c61f9SKrishna Gudipati 	return FC_PARSE_OK;
996a36c61f9SKrishna Gudipati }
997a36c61f9SKrishna Gudipati 
998a36c61f9SKrishna Gudipati enum fc_parse_status
999a36c61f9SKrishna Gudipati fc_rrq_rsp_parse(struct fchs_s *fchs, int len)
1000a36c61f9SKrishna Gudipati {
1001a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1002a36c61f9SKrishna Gudipati 
1003a36c61f9SKrishna Gudipati 	len = len;
1004a36c61f9SKrishna Gudipati 	if (els_cmd->els_code != FC_ELS_ACC)
1005a36c61f9SKrishna Gudipati 		return FC_PARSE_FAILURE;
1006a36c61f9SKrishna Gudipati 
1007a36c61f9SKrishna Gudipati 	return FC_PARSE_OK;
1008a36c61f9SKrishna Gudipati }
1009a36c61f9SKrishna Gudipati 
1010a36c61f9SKrishna Gudipati u16
101150444a34SMaggie fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id,
1012a36c61f9SKrishna Gudipati 		u32 reason_code, u32 reason_expl)
1013a36c61f9SKrishna Gudipati {
1014a36c61f9SKrishna Gudipati 	struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1);
1015a36c61f9SKrishna Gudipati 
1016a36c61f9SKrishna Gudipati 	fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
1017a36c61f9SKrishna Gudipati 
1018a36c61f9SKrishna Gudipati 	fchs->cat_info = FC_CAT_BA_RJT;
1019a36c61f9SKrishna Gudipati 	ba_rjt->reason_code = reason_code;
1020a36c61f9SKrishna Gudipati 	ba_rjt->reason_expl = reason_expl;
1021a36c61f9SKrishna Gudipati 	return sizeof(struct fc_ba_rjt_s);
1022a36c61f9SKrishna Gudipati }
1023a36c61f9SKrishna Gudipati 
1024a36c61f9SKrishna Gudipati static void
1025a36c61f9SKrishna Gudipati fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
1026a36c61f9SKrishna Gudipati {
10276a18b167SJing Huang 	memset(cthdr, 0, sizeof(struct ct_hdr_s));
1028a36c61f9SKrishna Gudipati 	cthdr->rev_id = CT_GS3_REVISION;
1029a36c61f9SKrishna Gudipati 	cthdr->gs_type = CT_GSTYPE_DIRSERVICE;
1030a36c61f9SKrishna Gudipati 	cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER;
1031ba816ea8SJing Huang 	cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
1032a36c61f9SKrishna Gudipati }
1033a36c61f9SKrishna Gudipati 
1034a36c61f9SKrishna Gudipati static void
1035a36c61f9SKrishna Gudipati fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
1036a36c61f9SKrishna Gudipati {
10376a18b167SJing Huang 	memset(cthdr, 0, sizeof(struct ct_hdr_s));
1038a36c61f9SKrishna Gudipati 	cthdr->rev_id = CT_GS3_REVISION;
1039a36c61f9SKrishna Gudipati 	cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
1040a36c61f9SKrishna Gudipati 	cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER;
1041ba816ea8SJing Huang 	cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
1042a36c61f9SKrishna Gudipati }
1043a36c61f9SKrishna Gudipati 
1044a36c61f9SKrishna Gudipati static void
1045a36c61f9SKrishna Gudipati fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code,
1046a36c61f9SKrishna Gudipati 					 u8 sub_type)
1047a36c61f9SKrishna Gudipati {
10486a18b167SJing Huang 	memset(cthdr, 0, sizeof(struct ct_hdr_s));
1049a36c61f9SKrishna Gudipati 	cthdr->rev_id = CT_GS3_REVISION;
1050a36c61f9SKrishna Gudipati 	cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
1051a36c61f9SKrishna Gudipati 	cthdr->gs_sub_type = sub_type;
1052ba816ea8SJing Huang 	cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
1053a36c61f9SKrishna Gudipati }
1054a36c61f9SKrishna Gudipati 
1055a36c61f9SKrishna Gudipati u16
1056a36c61f9SKrishna Gudipati fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1057a36c61f9SKrishna Gudipati 	       wwn_t port_name)
1058a36c61f9SKrishna Gudipati {
1059a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1060a36c61f9SKrishna Gudipati 	struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1);
1061f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1062a36c61f9SKrishna Gudipati 
1063a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1064a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
1065a36c61f9SKrishna Gudipati 
10666a18b167SJing Huang 	memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
1067a36c61f9SKrishna Gudipati 	gidpn->port_name = port_name;
1068a36c61f9SKrishna Gudipati 	return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s);
1069a36c61f9SKrishna Gudipati }
1070a36c61f9SKrishna Gudipati 
1071a36c61f9SKrishna Gudipati u16
1072a36c61f9SKrishna Gudipati fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1073a36c61f9SKrishna Gudipati 	       u32 port_id)
1074a36c61f9SKrishna Gudipati {
1075a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1076a36c61f9SKrishna Gudipati 	fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1);
1077f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1078a36c61f9SKrishna Gudipati 
1079a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1080a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
1081a36c61f9SKrishna Gudipati 
10826a18b167SJing Huang 	memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
1083a36c61f9SKrishna Gudipati 	gpnid->dap = port_id;
1084a36c61f9SKrishna Gudipati 	return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s);
1085a36c61f9SKrishna Gudipati }
1086a36c61f9SKrishna Gudipati 
1087a36c61f9SKrishna Gudipati u16
1088a36c61f9SKrishna Gudipati fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1089a36c61f9SKrishna Gudipati 	       u32 port_id)
1090a36c61f9SKrishna Gudipati {
1091a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1092a36c61f9SKrishna Gudipati 	fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1);
1093f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1094a36c61f9SKrishna Gudipati 
1095a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1096a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
1097a36c61f9SKrishna Gudipati 
10986a18b167SJing Huang 	memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
1099a36c61f9SKrishna Gudipati 	gnnid->dap = port_id;
1100a36c61f9SKrishna Gudipati 	return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s);
1101a36c61f9SKrishna Gudipati }
1102a36c61f9SKrishna Gudipati 
1103a36c61f9SKrishna Gudipati u16
1104a36c61f9SKrishna Gudipati fc_ct_rsp_parse(struct ct_hdr_s *cthdr)
1105a36c61f9SKrishna Gudipati {
1106ba816ea8SJing Huang 	if (be16_to_cpu(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) {
1107a36c61f9SKrishna Gudipati 		if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY)
1108a36c61f9SKrishna Gudipati 			return FC_PARSE_BUSY;
1109a36c61f9SKrishna Gudipati 		else
1110a36c61f9SKrishna Gudipati 			return FC_PARSE_FAILURE;
1111a36c61f9SKrishna Gudipati 	}
1112a36c61f9SKrishna Gudipati 
1113a36c61f9SKrishna Gudipati 	return FC_PARSE_OK;
1114a36c61f9SKrishna Gudipati }
1115a36c61f9SKrishna Gudipati 
1116a36c61f9SKrishna Gudipati u16
1117*d7be54ccSKrishna Gudipati fc_gs_rjt_build(struct fchs_s *fchs,  struct ct_hdr_s *cthdr,
1118*d7be54ccSKrishna Gudipati 		u32 d_id, u32 s_id, u16 ox_id, u8 reason_code,
1119*d7be54ccSKrishna Gudipati 		u8 reason_code_expl)
1120*d7be54ccSKrishna Gudipati {
1121*d7be54ccSKrishna Gudipati 	fc_gsresp_fchdr_build(fchs, d_id, s_id, ox_id);
1122*d7be54ccSKrishna Gudipati 
1123*d7be54ccSKrishna Gudipati 	cthdr->cmd_rsp_code = cpu_to_be16(CT_RSP_REJECT);
1124*d7be54ccSKrishna Gudipati 	cthdr->rev_id = CT_GS3_REVISION;
1125*d7be54ccSKrishna Gudipati 
1126*d7be54ccSKrishna Gudipati 	cthdr->reason_code = reason_code;
1127*d7be54ccSKrishna Gudipati 	cthdr->exp_code    = reason_code_expl;
1128*d7be54ccSKrishna Gudipati 	return sizeof(struct ct_hdr_s);
1129*d7be54ccSKrishna Gudipati }
1130*d7be54ccSKrishna Gudipati 
1131*d7be54ccSKrishna Gudipati u16
1132a36c61f9SKrishna Gudipati fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
1133a36c61f9SKrishna Gudipati 		u8 set_br_reg, u32 s_id, u16 ox_id)
1134a36c61f9SKrishna Gudipati {
1135f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
1136a36c61f9SKrishna Gudipati 
1137a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
1138a36c61f9SKrishna Gudipati 
11396a18b167SJing Huang 	memset(scr, 0, sizeof(struct fc_scr_s));
1140a36c61f9SKrishna Gudipati 	scr->command = FC_ELS_SCR;
1141a36c61f9SKrishna Gudipati 	scr->reg_func = FC_SCR_REG_FUNC_FULL;
1142a36c61f9SKrishna Gudipati 	if (set_br_reg)
1143a36c61f9SKrishna Gudipati 		scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE;
1144a36c61f9SKrishna Gudipati 
1145a36c61f9SKrishna Gudipati 	return sizeof(struct fc_scr_s);
1146a36c61f9SKrishna Gudipati }
1147a36c61f9SKrishna Gudipati 
1148a36c61f9SKrishna Gudipati u16
1149a36c61f9SKrishna Gudipati fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn,
1150a36c61f9SKrishna Gudipati 		u32 s_id, u16 ox_id)
1151a36c61f9SKrishna Gudipati {
1152f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
1153a36c61f9SKrishna Gudipati 	u16        payldlen;
1154a36c61f9SKrishna Gudipati 
1155a36c61f9SKrishna Gudipati 	fc_els_req_build(fchs, d_id, s_id, ox_id);
1156a36c61f9SKrishna Gudipati 	rscn->command = FC_ELS_RSCN;
1157a36c61f9SKrishna Gudipati 	rscn->pagelen = sizeof(rscn->event[0]);
1158a36c61f9SKrishna Gudipati 
1159a36c61f9SKrishna Gudipati 	payldlen = sizeof(u32) + rscn->pagelen;
1160ba816ea8SJing Huang 	rscn->payldlen = cpu_to_be16(payldlen);
1161a36c61f9SKrishna Gudipati 
1162a36c61f9SKrishna Gudipati 	rscn->event[0].format = FC_RSCN_FORMAT_PORTID;
1163a36c61f9SKrishna Gudipati 	rscn->event[0].portid = s_id;
1164a36c61f9SKrishna Gudipati 
1165a36c61f9SKrishna Gudipati 	return sizeof(struct fc_rscn_pl_s);
1166a36c61f9SKrishna Gudipati }
1167a36c61f9SKrishna Gudipati 
1168a36c61f9SKrishna Gudipati u16
1169a36c61f9SKrishna Gudipati fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1170a36c61f9SKrishna Gudipati 	       enum bfa_lport_role roles)
1171a36c61f9SKrishna Gudipati {
1172a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1173a36c61f9SKrishna Gudipati 	struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
1174f16a1750SMaggie Zhang 	u32        type_value, d_id = bfa_hton3b(FC_NAME_SERVER);
1175a36c61f9SKrishna Gudipati 	u8         index;
1176a36c61f9SKrishna Gudipati 
1177a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1178a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
1179a36c61f9SKrishna Gudipati 
11806a18b167SJing Huang 	memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
1181a36c61f9SKrishna Gudipati 
1182a36c61f9SKrishna Gudipati 	rftid->dap = s_id;
1183a36c61f9SKrishna Gudipati 
1184a36c61f9SKrishna Gudipati 	/* By default, FCP FC4 Type is registered */
1185a36c61f9SKrishna Gudipati 	index = FC_TYPE_FCP >> 5;
1186a36c61f9SKrishna Gudipati 	type_value = 1 << (FC_TYPE_FCP % 32);
1187ba816ea8SJing Huang 	rftid->fc4_type[index] = cpu_to_be32(type_value);
1188a36c61f9SKrishna Gudipati 
1189a36c61f9SKrishna Gudipati 	return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
1190a36c61f9SKrishna Gudipati }
1191a36c61f9SKrishna Gudipati 
1192a36c61f9SKrishna Gudipati u16
1193a36c61f9SKrishna Gudipati fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1194a36c61f9SKrishna Gudipati 		   u8 *fc4_bitmap, u32 bitmap_size)
1195a36c61f9SKrishna Gudipati {
1196a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1197a36c61f9SKrishna Gudipati 	struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
1198f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1199a36c61f9SKrishna Gudipati 
1200a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1201a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
1202a36c61f9SKrishna Gudipati 
12036a18b167SJing Huang 	memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
1204a36c61f9SKrishna Gudipati 
1205a36c61f9SKrishna Gudipati 	rftid->dap = s_id;
12066a18b167SJing Huang 	memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap,
1207a36c61f9SKrishna Gudipati 		(bitmap_size < 32 ? bitmap_size : 32));
1208a36c61f9SKrishna Gudipati 
1209a36c61f9SKrishna Gudipati 	return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
1210a36c61f9SKrishna Gudipati }
1211a36c61f9SKrishna Gudipati 
1212a36c61f9SKrishna Gudipati u16
1213a36c61f9SKrishna Gudipati fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1214a36c61f9SKrishna Gudipati 	       u8 fc4_type, u8 fc4_ftrs)
1215a36c61f9SKrishna Gudipati {
1216a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1217a36c61f9SKrishna Gudipati 	struct fcgs_rffid_req_s *rffid = (struct fcgs_rffid_req_s *)(cthdr + 1);
1218f16a1750SMaggie Zhang 	u32         d_id = bfa_hton3b(FC_NAME_SERVER);
1219a36c61f9SKrishna Gudipati 
1220a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1221a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID);
1222a36c61f9SKrishna Gudipati 
12236a18b167SJing Huang 	memset(rffid, 0, sizeof(struct fcgs_rffid_req_s));
1224a36c61f9SKrishna Gudipati 
1225a36c61f9SKrishna Gudipati 	rffid->dap	    = s_id;
1226a36c61f9SKrishna Gudipati 	rffid->fc4ftr_bits  = fc4_ftrs;
1227a36c61f9SKrishna Gudipati 	rffid->fc4_type	    = fc4_type;
1228a36c61f9SKrishna Gudipati 
1229a36c61f9SKrishna Gudipati 	return sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s);
1230a36c61f9SKrishna Gudipati }
1231a36c61f9SKrishna Gudipati 
1232a36c61f9SKrishna Gudipati u16
1233a36c61f9SKrishna Gudipati fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1234a36c61f9SKrishna Gudipati 		u8 *name)
1235a36c61f9SKrishna Gudipati {
1236a36c61f9SKrishna Gudipati 
1237a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1238a36c61f9SKrishna Gudipati 	struct fcgs_rspnid_req_s *rspnid =
1239a36c61f9SKrishna Gudipati 			(struct fcgs_rspnid_req_s *)(cthdr + 1);
1240f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1241a36c61f9SKrishna Gudipati 
1242a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1243a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID);
1244a36c61f9SKrishna Gudipati 
12456a18b167SJing Huang 	memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s));
1246a36c61f9SKrishna Gudipati 
1247a36c61f9SKrishna Gudipati 	rspnid->dap = s_id;
1248a36c61f9SKrishna Gudipati 	rspnid->spn_len = (u8) strlen((char *)name);
1249a36c61f9SKrishna Gudipati 	strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len);
1250a36c61f9SKrishna Gudipati 
1251a36c61f9SKrishna Gudipati 	return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s);
1252a36c61f9SKrishna Gudipati }
1253a36c61f9SKrishna Gudipati 
1254a36c61f9SKrishna Gudipati u16
1255a36c61f9SKrishna Gudipati fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type)
1256a36c61f9SKrishna Gudipati {
1257a36c61f9SKrishna Gudipati 
1258a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1259a36c61f9SKrishna Gudipati 	struct fcgs_gidft_req_s *gidft = (struct fcgs_gidft_req_s *)(cthdr + 1);
1260f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1261a36c61f9SKrishna Gudipati 
1262a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1263a36c61f9SKrishna Gudipati 
1264a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT);
1265a36c61f9SKrishna Gudipati 
12666a18b167SJing Huang 	memset(gidft, 0, sizeof(struct fcgs_gidft_req_s));
1267a36c61f9SKrishna Gudipati 	gidft->fc4_type = fc4_type;
1268a36c61f9SKrishna Gudipati 	gidft->domain_id = 0;
1269a36c61f9SKrishna Gudipati 	gidft->area_id = 0;
1270a36c61f9SKrishna Gudipati 
1271a36c61f9SKrishna Gudipati 	return sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s);
1272a36c61f9SKrishna Gudipati }
1273a36c61f9SKrishna Gudipati 
1274a36c61f9SKrishna Gudipati u16
1275a36c61f9SKrishna Gudipati fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1276a36c61f9SKrishna Gudipati 	       wwn_t port_name)
1277a36c61f9SKrishna Gudipati {
1278a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1279a36c61f9SKrishna Gudipati 	struct fcgs_rpnid_req_s *rpnid = (struct fcgs_rpnid_req_s *)(cthdr + 1);
1280f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1281a36c61f9SKrishna Gudipati 
1282a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1283a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID);
1284a36c61f9SKrishna Gudipati 
12856a18b167SJing Huang 	memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s));
1286a36c61f9SKrishna Gudipati 	rpnid->port_id = port_id;
1287a36c61f9SKrishna Gudipati 	rpnid->port_name = port_name;
1288a36c61f9SKrishna Gudipati 
1289a36c61f9SKrishna Gudipati 	return sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s);
1290a36c61f9SKrishna Gudipati }
1291a36c61f9SKrishna Gudipati 
1292a36c61f9SKrishna Gudipati u16
1293a36c61f9SKrishna Gudipati fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1294a36c61f9SKrishna Gudipati 	       wwn_t node_name)
1295a36c61f9SKrishna Gudipati {
1296a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1297a36c61f9SKrishna Gudipati 	struct fcgs_rnnid_req_s *rnnid = (struct fcgs_rnnid_req_s *)(cthdr + 1);
1298f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1299a36c61f9SKrishna Gudipati 
1300a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1301a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID);
1302a36c61f9SKrishna Gudipati 
13036a18b167SJing Huang 	memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s));
1304a36c61f9SKrishna Gudipati 	rnnid->port_id = port_id;
1305a36c61f9SKrishna Gudipati 	rnnid->node_name = node_name;
1306a36c61f9SKrishna Gudipati 
1307a36c61f9SKrishna Gudipati 	return sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s);
1308a36c61f9SKrishna Gudipati }
1309a36c61f9SKrishna Gudipati 
1310a36c61f9SKrishna Gudipati u16
1311a36c61f9SKrishna Gudipati fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1312a36c61f9SKrishna Gudipati 	       u32 cos)
1313a36c61f9SKrishna Gudipati {
1314a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1315a36c61f9SKrishna Gudipati 	struct fcgs_rcsid_req_s *rcsid =
1316a36c61f9SKrishna Gudipati 			(struct fcgs_rcsid_req_s *) (cthdr + 1);
1317f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1318a36c61f9SKrishna Gudipati 
1319a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1320a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID);
1321a36c61f9SKrishna Gudipati 
13226a18b167SJing Huang 	memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s));
1323a36c61f9SKrishna Gudipati 	rcsid->port_id = port_id;
1324a36c61f9SKrishna Gudipati 	rcsid->cos = cos;
1325a36c61f9SKrishna Gudipati 
1326a36c61f9SKrishna Gudipati 	return sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s);
1327a36c61f9SKrishna Gudipati }
1328a36c61f9SKrishna Gudipati 
1329a36c61f9SKrishna Gudipati u16
1330a36c61f9SKrishna Gudipati fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1331a36c61f9SKrishna Gudipati 	       u8 port_type)
1332a36c61f9SKrishna Gudipati {
1333a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1334a36c61f9SKrishna Gudipati 	struct fcgs_rptid_req_s *rptid = (struct fcgs_rptid_req_s *)(cthdr + 1);
1335f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1336a36c61f9SKrishna Gudipati 
1337a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1338a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID);
1339a36c61f9SKrishna Gudipati 
13406a18b167SJing Huang 	memset(rptid, 0, sizeof(struct fcgs_rptid_req_s));
1341a36c61f9SKrishna Gudipati 	rptid->port_id = port_id;
1342a36c61f9SKrishna Gudipati 	rptid->port_type = port_type;
1343a36c61f9SKrishna Gudipati 
1344a36c61f9SKrishna Gudipati 	return sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s);
1345a36c61f9SKrishna Gudipati }
1346a36c61f9SKrishna Gudipati 
1347a36c61f9SKrishna Gudipati u16
1348a36c61f9SKrishna Gudipati fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id)
1349a36c61f9SKrishna Gudipati {
1350a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1351a36c61f9SKrishna Gudipati 	struct fcgs_ganxt_req_s *ganxt = (struct fcgs_ganxt_req_s *)(cthdr + 1);
1352f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1353a36c61f9SKrishna Gudipati 
1354a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1355a36c61f9SKrishna Gudipati 	fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT);
1356a36c61f9SKrishna Gudipati 
13576a18b167SJing Huang 	memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s));
1358a36c61f9SKrishna Gudipati 	ganxt->port_id = port_id;
1359a36c61f9SKrishna Gudipati 
1360a36c61f9SKrishna Gudipati 	return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s);
1361a36c61f9SKrishna Gudipati }
1362a36c61f9SKrishna Gudipati 
1363a36c61f9SKrishna Gudipati /*
1364a36c61f9SKrishna Gudipati  * Builds fc hdr and ct hdr for FDMI requests.
1365a36c61f9SKrishna Gudipati  */
1366a36c61f9SKrishna Gudipati u16
1367a36c61f9SKrishna Gudipati fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
1368a36c61f9SKrishna Gudipati 		     u16 cmd_code)
1369a36c61f9SKrishna Gudipati {
1370a36c61f9SKrishna Gudipati 
1371a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1372f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
1373a36c61f9SKrishna Gudipati 
1374a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1375a36c61f9SKrishna Gudipati 	fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code);
1376a36c61f9SKrishna Gudipati 
1377a36c61f9SKrishna Gudipati 	return sizeof(struct ct_hdr_s);
1378a36c61f9SKrishna Gudipati }
1379a36c61f9SKrishna Gudipati 
1380a36c61f9SKrishna Gudipati /*
1381a36c61f9SKrishna Gudipati  * Given a FC4 Type, this function returns a fc4 type bitmask
1382a36c61f9SKrishna Gudipati  */
1383a36c61f9SKrishna Gudipati void
1384a36c61f9SKrishna Gudipati fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask)
1385a36c61f9SKrishna Gudipati {
1386a36c61f9SKrishna Gudipati 	u8         index;
138750444a34SMaggie 	__be32       *ptr = (__be32 *) bit_mask;
1388a36c61f9SKrishna Gudipati 	u32        type_value;
1389a36c61f9SKrishna Gudipati 
1390a36c61f9SKrishna Gudipati 	/*
1391a36c61f9SKrishna Gudipati 	 * @todo : Check for bitmask size
1392a36c61f9SKrishna Gudipati 	 */
1393a36c61f9SKrishna Gudipati 
1394a36c61f9SKrishna Gudipati 	index = fc4_type >> 5;
1395a36c61f9SKrishna Gudipati 	type_value = 1 << (fc4_type % 32);
1396ba816ea8SJing Huang 	ptr[index] = cpu_to_be32(type_value);
1397a36c61f9SKrishna Gudipati 
1398a36c61f9SKrishna Gudipati }
1399a36c61f9SKrishna Gudipati 
1400a36c61f9SKrishna Gudipati /*
1401a36c61f9SKrishna Gudipati  *	GMAL Request
1402a36c61f9SKrishna Gudipati  */
1403a36c61f9SKrishna Gudipati u16
1404a36c61f9SKrishna Gudipati fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
1405a36c61f9SKrishna Gudipati {
1406a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1407a36c61f9SKrishna Gudipati 	fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1);
1408f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
1409a36c61f9SKrishna Gudipati 
1410a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1411a36c61f9SKrishna Gudipati 	fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD,
1412a36c61f9SKrishna Gudipati 			CT_GSSUBTYPE_CFGSERVER);
1413a36c61f9SKrishna Gudipati 
14146a18b167SJing Huang 	memset(gmal, 0, sizeof(fcgs_gmal_req_t));
1415a36c61f9SKrishna Gudipati 	gmal->wwn = wwn;
1416a36c61f9SKrishna Gudipati 
1417a36c61f9SKrishna Gudipati 	return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t);
1418a36c61f9SKrishna Gudipati }
1419a36c61f9SKrishna Gudipati 
1420a36c61f9SKrishna Gudipati /*
1421a36c61f9SKrishna Gudipati  * GFN (Get Fabric Name) Request
1422a36c61f9SKrishna Gudipati  */
1423a36c61f9SKrishna Gudipati u16
1424a36c61f9SKrishna Gudipati fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
1425a36c61f9SKrishna Gudipati {
1426a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1427a36c61f9SKrishna Gudipati 	fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1);
1428f16a1750SMaggie Zhang 	u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
1429a36c61f9SKrishna Gudipati 
1430a36c61f9SKrishna Gudipati 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1431a36c61f9SKrishna Gudipati 	fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD,
1432a36c61f9SKrishna Gudipati 			CT_GSSUBTYPE_CFGSERVER);
1433a36c61f9SKrishna Gudipati 
14346a18b167SJing Huang 	memset(gfn, 0, sizeof(fcgs_gfn_req_t));
1435a36c61f9SKrishna Gudipati 	gfn->wwn = wwn;
1436a36c61f9SKrishna Gudipati 
1437a36c61f9SKrishna Gudipati 	return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t);
1438a36c61f9SKrishna Gudipati }
1439