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