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