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