Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
0004  * Copyright (c) 2014- QLogic Corporation.
0005  * All rights reserved
0006  * www.qlogic.com
0007  *
0008  * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
0009  */
0010 /*
0011  * fcbuild.c - FC link service frame building and parsing routines
0012  */
0013 
0014 #include "bfad_drv.h"
0015 #include "bfa_fcbuild.h"
0016 
0017 /*
0018  * static build functions
0019  */
0020 static void     fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
0021                  __be16 ox_id);
0022 static void     fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
0023                  __be16 ox_id);
0024 static struct fchs_s fc_els_req_tmpl;
0025 static struct fchs_s fc_els_rsp_tmpl;
0026 static struct fchs_s fc_bls_req_tmpl;
0027 static struct fchs_s fc_bls_rsp_tmpl;
0028 static struct fc_ba_acc_s ba_acc_tmpl;
0029 static struct fc_logi_s plogi_tmpl;
0030 static struct fc_prli_s prli_tmpl;
0031 static struct fc_rrq_s rrq_tmpl;
0032 static struct fchs_s fcp_fchs_tmpl;
0033 
0034 void
0035 fcbuild_init(void)
0036 {
0037     /*
0038      * fc_els_req_tmpl
0039      */
0040     fc_els_req_tmpl.routing = FC_RTG_EXT_LINK;
0041     fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST;
0042     fc_els_req_tmpl.type = FC_TYPE_ELS;
0043     fc_els_req_tmpl.f_ctl =
0044         bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
0045                   FCTL_SI_XFER);
0046     fc_els_req_tmpl.rx_id = FC_RXID_ANY;
0047 
0048     /*
0049      * fc_els_rsp_tmpl
0050      */
0051     fc_els_rsp_tmpl.routing = FC_RTG_EXT_LINK;
0052     fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY;
0053     fc_els_rsp_tmpl.type = FC_TYPE_ELS;
0054     fc_els_rsp_tmpl.f_ctl =
0055         bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
0056                   FCTL_END_SEQ | FCTL_SI_XFER);
0057     fc_els_rsp_tmpl.rx_id = FC_RXID_ANY;
0058 
0059     /*
0060      * fc_bls_req_tmpl
0061      */
0062     fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK;
0063     fc_bls_req_tmpl.type = FC_TYPE_BLS;
0064     fc_bls_req_tmpl.f_ctl = bfa_hton3b(FCTL_END_SEQ | FCTL_SI_XFER);
0065     fc_bls_req_tmpl.rx_id = FC_RXID_ANY;
0066 
0067     /*
0068      * fc_bls_rsp_tmpl
0069      */
0070     fc_bls_rsp_tmpl.routing = FC_RTG_BASIC_LINK;
0071     fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC;
0072     fc_bls_rsp_tmpl.type = FC_TYPE_BLS;
0073     fc_bls_rsp_tmpl.f_ctl =
0074         bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
0075                   FCTL_END_SEQ | FCTL_SI_XFER);
0076     fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY;
0077 
0078     /*
0079      * ba_acc_tmpl
0080      */
0081     ba_acc_tmpl.seq_id_valid = 0;
0082     ba_acc_tmpl.low_seq_cnt = 0;
0083     ba_acc_tmpl.high_seq_cnt = 0xFFFF;
0084 
0085     /*
0086      * plogi_tmpl
0087      */
0088     plogi_tmpl.csp.verhi = FC_PH_VER_PH_3;
0089     plogi_tmpl.csp.verlo = FC_PH_VER_4_3;
0090     plogi_tmpl.csp.ciro = 0x1;
0091     plogi_tmpl.csp.cisc = 0x0;
0092     plogi_tmpl.csp.altbbcred = 0x0;
0093     plogi_tmpl.csp.conseq = cpu_to_be16(0x00FF);
0094     plogi_tmpl.csp.ro_bitmap = cpu_to_be16(0x0002);
0095     plogi_tmpl.csp.e_d_tov = cpu_to_be32(2000);
0096 
0097     plogi_tmpl.class3.class_valid = 1;
0098     plogi_tmpl.class3.sequential = 1;
0099     plogi_tmpl.class3.conseq = 0xFF;
0100     plogi_tmpl.class3.ospx = 1;
0101 
0102     /*
0103      * prli_tmpl
0104      */
0105     prli_tmpl.command = FC_ELS_PRLI;
0106     prli_tmpl.pglen = 0x10;
0107     prli_tmpl.pagebytes = cpu_to_be16(0x0014);
0108     prli_tmpl.parampage.type = FC_TYPE_FCP;
0109     prli_tmpl.parampage.imagepair = 1;
0110     prli_tmpl.parampage.servparams.rxrdisab = 1;
0111 
0112     /*
0113      * rrq_tmpl
0114      */
0115     rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ;
0116 
0117     /*
0118      * fcp_struct fchs_s mpl
0119      */
0120     fcp_fchs_tmpl.routing = FC_RTG_FC4_DEV_DATA;
0121     fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD;
0122     fcp_fchs_tmpl.type = FC_TYPE_FCP;
0123     fcp_fchs_tmpl.f_ctl =
0124         bfa_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER);
0125     fcp_fchs_tmpl.seq_id = 1;
0126     fcp_fchs_tmpl.rx_id = FC_RXID_ANY;
0127 }
0128 
0129 static void
0130 fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
0131 {
0132     memset(fchs, 0, sizeof(struct fchs_s));
0133 
0134     fchs->routing = FC_RTG_FC4_DEV_DATA;
0135     fchs->cat_info = FC_CAT_UNSOLICIT_CTRL;
0136     fchs->type = FC_TYPE_SERVICES;
0137     fchs->f_ctl =
0138         bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
0139                   FCTL_SI_XFER);
0140     fchs->rx_id = FC_RXID_ANY;
0141     fchs->d_id = (d_id);
0142     fchs->s_id = (s_id);
0143     fchs->ox_id = cpu_to_be16(ox_id);
0144 
0145     /*
0146      * @todo no need to set ox_id for request
0147      *       no need to set rx_id for response
0148      */
0149 }
0150 
0151 static void
0152 fc_gsresp_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
0153 {
0154     memset(fchs, 0, sizeof(struct fchs_s));
0155 
0156     fchs->routing = FC_RTG_FC4_DEV_DATA;
0157     fchs->cat_info = FC_CAT_SOLICIT_CTRL;
0158     fchs->type = FC_TYPE_SERVICES;
0159     fchs->f_ctl =
0160         bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
0161                FCTL_END_SEQ | FCTL_SI_XFER);
0162     fchs->d_id = d_id;
0163     fchs->s_id = s_id;
0164     fchs->ox_id = ox_id;
0165 }
0166 
0167 void
0168 fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
0169 {
0170     memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s));
0171     fchs->d_id = (d_id);
0172     fchs->s_id = (s_id);
0173     fchs->ox_id = cpu_to_be16(ox_id);
0174 }
0175 
0176 static void
0177 fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
0178 {
0179     memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s));
0180     fchs->d_id = d_id;
0181     fchs->s_id = s_id;
0182     fchs->ox_id = ox_id;
0183 }
0184 
0185 static void
0186 fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
0187 {
0188     memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s));
0189     fchs->d_id = d_id;
0190     fchs->s_id = s_id;
0191     fchs->ox_id = ox_id;
0192 }
0193 
0194 static          u16
0195 fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0196          __be16 ox_id, wwn_t port_name, wwn_t node_name,
0197          u16 pdu_size, u16 bb_cr, u8 els_code)
0198 {
0199     struct fc_logi_s *plogi = (struct fc_logi_s *) (pld);
0200 
0201     memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
0202 
0203     /* For FC AL bb_cr is 0 and altbbcred is 1 */
0204     if (!bb_cr)
0205         plogi->csp.altbbcred = 1;
0206 
0207     plogi->els_cmd.els_code = els_code;
0208     if (els_code == FC_ELS_PLOGI)
0209         fc_els_req_build(fchs, d_id, s_id, ox_id);
0210     else
0211         fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0212 
0213     plogi->csp.rxsz = plogi->class3.rxsz = cpu_to_be16(pdu_size);
0214     plogi->csp.bbcred  = cpu_to_be16(bb_cr);
0215 
0216     memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
0217     memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
0218 
0219     return sizeof(struct fc_logi_s);
0220 }
0221 
0222 u16
0223 fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
0224         u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size,
0225            u8 set_npiv, u8 set_auth, u16 local_bb_credits)
0226 {
0227     u32        d_id = bfa_hton3b(FC_FABRIC_PORT);
0228     __be32  *vvl_info;
0229 
0230     memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
0231 
0232     flogi->els_cmd.els_code = FC_ELS_FLOGI;
0233     fc_els_req_build(fchs, d_id, s_id, ox_id);
0234 
0235     flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
0236     flogi->port_name = port_name;
0237     flogi->node_name = node_name;
0238 
0239     /*
0240      * Set the NPIV Capability Bit ( word 1, bit 31) of Common
0241      * Service Parameters.
0242      */
0243     flogi->csp.ciro = set_npiv;
0244 
0245     /* set AUTH capability */
0246     flogi->csp.security = set_auth;
0247 
0248     flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
0249 
0250     /* Set brcd token in VVL */
0251     vvl_info = (u32 *)&flogi->vvl[0];
0252 
0253     /* set the flag to indicate the presence of VVL */
0254     flogi->csp.npiv_supp    = 1; /* @todo. field name is not correct */
0255     vvl_info[0] = cpu_to_be32(FLOGI_VVL_BRCD);
0256 
0257     return sizeof(struct fc_logi_s);
0258 }
0259 
0260 u16
0261 fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
0262            __be16 ox_id, wwn_t port_name, wwn_t node_name,
0263            u16 pdu_size, u16 local_bb_credits, u8 bb_scn)
0264 {
0265     u32        d_id = 0;
0266     u16    bbscn_rxsz = (bb_scn << 12) | pdu_size;
0267 
0268     memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
0269     fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0270 
0271     flogi->els_cmd.els_code = FC_ELS_ACC;
0272     flogi->class3.rxsz = cpu_to_be16(pdu_size);
0273     flogi->csp.rxsz  = cpu_to_be16(bbscn_rxsz); /* bb_scn/rxsz */
0274     flogi->port_name = port_name;
0275     flogi->node_name = node_name;
0276 
0277     flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
0278 
0279     return sizeof(struct fc_logi_s);
0280 }
0281 
0282 u16
0283 fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
0284         u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size)
0285 {
0286     u32        d_id = bfa_hton3b(FC_FABRIC_PORT);
0287 
0288     memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
0289 
0290     flogi->els_cmd.els_code = FC_ELS_FDISC;
0291     fc_els_req_build(fchs, d_id, s_id, ox_id);
0292 
0293     flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
0294     flogi->port_name = port_name;
0295     flogi->node_name = node_name;
0296 
0297     return sizeof(struct fc_logi_s);
0298 }
0299 
0300 u16
0301 fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0302            u16 ox_id, wwn_t port_name, wwn_t node_name,
0303            u16 pdu_size, u16 bb_cr)
0304 {
0305     return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
0306                 node_name, pdu_size, bb_cr, FC_ELS_PLOGI);
0307 }
0308 
0309 u16
0310 fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0311            u16 ox_id, wwn_t port_name, wwn_t node_name,
0312            u16 pdu_size, u16 bb_cr)
0313 {
0314     return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
0315                 node_name, pdu_size, bb_cr, FC_ELS_ACC);
0316 }
0317 
0318 enum fc_parse_status
0319 fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
0320 {
0321     struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
0322     struct fc_logi_s *plogi;
0323     struct fc_ls_rjt_s *ls_rjt;
0324 
0325     switch (els_cmd->els_code) {
0326     case FC_ELS_LS_RJT:
0327         ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1);
0328         if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
0329             return FC_PARSE_BUSY;
0330         else
0331             return FC_PARSE_FAILURE;
0332     case FC_ELS_ACC:
0333         plogi = (struct fc_logi_s *) (fchs + 1);
0334         if (len < sizeof(struct fc_logi_s))
0335             return FC_PARSE_FAILURE;
0336 
0337         if (!wwn_is_equal(plogi->port_name, port_name))
0338             return FC_PARSE_FAILURE;
0339 
0340         if (!plogi->class3.class_valid)
0341             return FC_PARSE_FAILURE;
0342 
0343         if (be16_to_cpu(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
0344             return FC_PARSE_FAILURE;
0345 
0346         return FC_PARSE_OK;
0347     default:
0348         return FC_PARSE_FAILURE;
0349     }
0350 }
0351 
0352 enum fc_parse_status
0353 fc_plogi_parse(struct fchs_s *fchs)
0354 {
0355     struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1);
0356 
0357     if (plogi->class3.class_valid != 1)
0358         return FC_PARSE_FAILURE;
0359 
0360     if ((be16_to_cpu(plogi->class3.rxsz) < FC_MIN_PDUSZ)
0361         || (be16_to_cpu(plogi->class3.rxsz) > FC_MAX_PDUSZ)
0362         || (plogi->class3.rxsz == 0))
0363         return FC_PARSE_FAILURE;
0364 
0365     return FC_PARSE_OK;
0366 }
0367 
0368 u16
0369 fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0370           u16 ox_id)
0371 {
0372     struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
0373 
0374     fc_els_req_build(fchs, d_id, s_id, ox_id);
0375     memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
0376 
0377     prli->command = FC_ELS_PRLI;
0378     prli->parampage.servparams.initiator     = 1;
0379     prli->parampage.servparams.retry         = 1;
0380     prli->parampage.servparams.rec_support   = 1;
0381     prli->parampage.servparams.task_retry_id = 0;
0382     prli->parampage.servparams.confirm       = 1;
0383 
0384     return sizeof(struct fc_prli_s);
0385 }
0386 
0387 u16
0388 fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0389           __be16 ox_id, enum bfa_lport_role role)
0390 {
0391     struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
0392 
0393     fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0394     memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
0395 
0396     prli->command = FC_ELS_ACC;
0397 
0398     prli->parampage.servparams.initiator = 1;
0399 
0400     prli->parampage.rspcode = FC_PRLI_ACC_XQTD;
0401 
0402     return sizeof(struct fc_prli_s);
0403 }
0404 
0405 enum fc_parse_status
0406 fc_prli_rsp_parse(struct fc_prli_s *prli, int len)
0407 {
0408     if (len < sizeof(struct fc_prli_s))
0409         return FC_PARSE_FAILURE;
0410 
0411     if (prli->command != FC_ELS_ACC)
0412         return FC_PARSE_FAILURE;
0413 
0414     if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD)
0415         && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG))
0416         return FC_PARSE_FAILURE;
0417 
0418     if (prli->parampage.servparams.target != 1)
0419         return FC_PARSE_FAILURE;
0420 
0421     return FC_PARSE_OK;
0422 }
0423 
0424 enum fc_parse_status
0425 fc_prli_parse(struct fc_prli_s *prli)
0426 {
0427     if (prli->parampage.type != FC_TYPE_FCP)
0428         return FC_PARSE_FAILURE;
0429 
0430     if (!prli->parampage.imagepair)
0431         return FC_PARSE_FAILURE;
0432 
0433     if (!prli->parampage.servparams.initiator)
0434         return FC_PARSE_FAILURE;
0435 
0436     return FC_PARSE_OK;
0437 }
0438 
0439 u16
0440 fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id,
0441           u16 ox_id, wwn_t port_name)
0442 {
0443     fc_els_req_build(fchs, d_id, s_id, ox_id);
0444 
0445     memset(logo, '\0', sizeof(struct fc_logo_s));
0446     logo->els_cmd.els_code = FC_ELS_LOGO;
0447     logo->nport_id = (s_id);
0448     logo->orig_port_name = port_name;
0449 
0450     return sizeof(struct fc_logo_s);
0451 }
0452 
0453 static u16
0454 fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
0455          u32 s_id, __be16 ox_id, wwn_t port_name,
0456          wwn_t node_name, u8 els_code)
0457 {
0458     memset(adisc, '\0', sizeof(struct fc_adisc_s));
0459 
0460     adisc->els_cmd.els_code = els_code;
0461 
0462     if (els_code == FC_ELS_ADISC)
0463         fc_els_req_build(fchs, d_id, s_id, ox_id);
0464     else
0465         fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0466 
0467     adisc->orig_HA = 0;
0468     adisc->orig_port_name = port_name;
0469     adisc->orig_node_name = node_name;
0470     adisc->nport_id = (s_id);
0471 
0472     return sizeof(struct fc_adisc_s);
0473 }
0474 
0475 u16
0476 fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
0477         u32 s_id, __be16 ox_id, wwn_t port_name, wwn_t node_name)
0478 {
0479     return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
0480                 node_name, FC_ELS_ADISC);
0481 }
0482 
0483 u16
0484 fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
0485            u32 s_id, __be16 ox_id, wwn_t port_name,
0486            wwn_t node_name)
0487 {
0488     return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
0489                 node_name, FC_ELS_ACC);
0490 }
0491 
0492 enum fc_parse_status
0493 fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name,
0494                  wwn_t node_name)
0495 {
0496 
0497     if (len < sizeof(struct fc_adisc_s))
0498         return FC_PARSE_FAILURE;
0499 
0500     if (adisc->els_cmd.els_code != FC_ELS_ACC)
0501         return FC_PARSE_FAILURE;
0502 
0503     if (!wwn_is_equal(adisc->orig_port_name, port_name))
0504         return FC_PARSE_FAILURE;
0505 
0506     return FC_PARSE_OK;
0507 }
0508 
0509 enum fc_parse_status
0510 fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap, wwn_t node_name,
0511            wwn_t port_name)
0512 {
0513     struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld;
0514 
0515     if (adisc->els_cmd.els_code != FC_ELS_ACC)
0516         return FC_PARSE_FAILURE;
0517 
0518     if ((adisc->nport_id == (host_dap))
0519         && wwn_is_equal(adisc->orig_port_name, port_name)
0520         && wwn_is_equal(adisc->orig_node_name, node_name))
0521         return FC_PARSE_OK;
0522 
0523     return FC_PARSE_FAILURE;
0524 }
0525 
0526 enum fc_parse_status
0527 fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name)
0528 {
0529     struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
0530 
0531     if (pdisc->class3.class_valid != 1)
0532         return FC_PARSE_FAILURE;
0533 
0534     if ((be16_to_cpu(pdisc->class3.rxsz) <
0535         (FC_MIN_PDUSZ - sizeof(struct fchs_s)))
0536         || (pdisc->class3.rxsz == 0))
0537         return FC_PARSE_FAILURE;
0538 
0539     if (!wwn_is_equal(pdisc->port_name, port_name))
0540         return FC_PARSE_FAILURE;
0541 
0542     if (!wwn_is_equal(pdisc->node_name, node_name))
0543         return FC_PARSE_FAILURE;
0544 
0545     return FC_PARSE_OK;
0546 }
0547 
0548 u16
0549 fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
0550 {
0551     memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s));
0552     fchs->cat_info = FC_CAT_ABTS;
0553     fchs->d_id = (d_id);
0554     fchs->s_id = (s_id);
0555     fchs->ox_id = cpu_to_be16(ox_id);
0556 
0557     return sizeof(struct fchs_s);
0558 }
0559 
0560 enum fc_parse_status
0561 fc_abts_rsp_parse(struct fchs_s *fchs, int len)
0562 {
0563     if ((fchs->cat_info == FC_CAT_BA_ACC)
0564         || (fchs->cat_info == FC_CAT_BA_RJT))
0565         return FC_PARSE_OK;
0566 
0567     return FC_PARSE_FAILURE;
0568 }
0569 
0570 u16
0571 fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id,
0572          u16 ox_id, u16 rrq_oxid)
0573 {
0574     fc_els_req_build(fchs, d_id, s_id, ox_id);
0575 
0576     /*
0577      * build rrq payload
0578      */
0579     memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s));
0580     rrq->s_id = (s_id);
0581     rrq->ox_id = cpu_to_be16(rrq_oxid);
0582     rrq->rx_id = FC_RXID_ANY;
0583 
0584     return sizeof(struct fc_rrq_s);
0585 }
0586 
0587 u16
0588 fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0589           __be16 ox_id)
0590 {
0591     struct fc_els_cmd_s *acc = pld;
0592 
0593     fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0594 
0595     memset(acc, 0, sizeof(struct fc_els_cmd_s));
0596     acc->els_code = FC_ELS_ACC;
0597 
0598     return sizeof(struct fc_els_cmd_s);
0599 }
0600 
0601 u16
0602 fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
0603         u32 s_id, __be16 ox_id, u8 reason_code,
0604         u8 reason_code_expl)
0605 {
0606     fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0607     memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s));
0608 
0609     ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT;
0610     ls_rjt->reason_code = reason_code;
0611     ls_rjt->reason_code_expl = reason_code_expl;
0612     ls_rjt->vendor_unique = 0x00;
0613 
0614     return sizeof(struct fc_ls_rjt_s);
0615 }
0616 
0617 u16
0618 fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
0619         u32 s_id, __be16 ox_id, u16 rx_id)
0620 {
0621     fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
0622 
0623     memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s));
0624 
0625     fchs->rx_id = rx_id;
0626 
0627     ba_acc->ox_id = fchs->ox_id;
0628     ba_acc->rx_id = fchs->rx_id;
0629 
0630     return sizeof(struct fc_ba_acc_s);
0631 }
0632 
0633 u16
0634 fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id,
0635         u32 s_id, __be16 ox_id)
0636 {
0637     fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0638     memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
0639     els_cmd->els_code = FC_ELS_ACC;
0640 
0641     return sizeof(struct fc_els_cmd_s);
0642 }
0643 
0644 int
0645 fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code)
0646 {
0647     int             num_pages = 0;
0648     struct fc_prlo_s *prlo;
0649     struct fc_tprlo_s *tprlo;
0650 
0651     if (els_code == FC_ELS_PRLO) {
0652         prlo = (struct fc_prlo_s *) (fc_frame + 1);
0653         num_pages = (be16_to_cpu(prlo->payload_len) - 4) / 16;
0654     } else {
0655         tprlo = (struct fc_tprlo_s *) (fc_frame + 1);
0656         num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16;
0657     }
0658     return num_pages;
0659 }
0660 
0661 u16
0662 fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
0663         u32 d_id, u32 s_id, __be16 ox_id, int num_pages)
0664 {
0665     int             page;
0666 
0667     fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0668 
0669     memset(tprlo_acc, 0, (num_pages * 16) + 4);
0670     tprlo_acc->command = FC_ELS_ACC;
0671 
0672     tprlo_acc->page_len = 0x10;
0673     tprlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
0674 
0675     for (page = 0; page < num_pages; page++) {
0676         tprlo_acc->tprlo_acc_params[page].opa_valid = 0;
0677         tprlo_acc->tprlo_acc_params[page].rpa_valid = 0;
0678         tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
0679         tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0;
0680         tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0;
0681     }
0682     return be16_to_cpu(tprlo_acc->payload_len);
0683 }
0684 
0685 u16
0686 fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id,
0687           u32 s_id, __be16 ox_id, int num_pages)
0688 {
0689     int             page;
0690 
0691     fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0692 
0693     memset(prlo_acc, 0, (num_pages * 16) + 4);
0694     prlo_acc->command = FC_ELS_ACC;
0695     prlo_acc->page_len = 0x10;
0696     prlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
0697 
0698     for (page = 0; page < num_pages; page++) {
0699         prlo_acc->prlo_acc_params[page].opa_valid = 0;
0700         prlo_acc->prlo_acc_params[page].rpa_valid = 0;
0701         prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
0702         prlo_acc->prlo_acc_params[page].orig_process_assc = 0;
0703         prlo_acc->prlo_acc_params[page].resp_process_assc = 0;
0704     }
0705 
0706     return be16_to_cpu(prlo_acc->payload_len);
0707 }
0708 
0709 u16
0710 fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id,
0711         u32 s_id, u16 ox_id, u32 data_format)
0712 {
0713     fc_els_req_build(fchs, d_id, s_id, ox_id);
0714 
0715     memset(rnid, 0, sizeof(struct fc_rnid_cmd_s));
0716 
0717     rnid->els_cmd.els_code = FC_ELS_RNID;
0718     rnid->node_id_data_format = data_format;
0719 
0720     return sizeof(struct fc_rnid_cmd_s);
0721 }
0722 
0723 u16
0724 fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id,
0725           u32 s_id, __be16 ox_id, u32 data_format,
0726           struct fc_rnid_common_id_data_s *common_id_data,
0727           struct fc_rnid_general_topology_data_s *gen_topo_data)
0728 {
0729     memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s));
0730 
0731     fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0732 
0733     rnid_acc->els_cmd.els_code = FC_ELS_ACC;
0734     rnid_acc->node_id_data_format = data_format;
0735     rnid_acc->common_id_data_length =
0736             sizeof(struct fc_rnid_common_id_data_s);
0737     rnid_acc->common_id_data = *common_id_data;
0738 
0739     if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
0740         rnid_acc->specific_id_data_length =
0741             sizeof(struct fc_rnid_general_topology_data_s);
0742         rnid_acc->gen_topology_data = *gen_topo_data;
0743         return sizeof(struct fc_rnid_acc_s);
0744     } else {
0745         return sizeof(struct fc_rnid_acc_s) -
0746             sizeof(struct fc_rnid_general_topology_data_s);
0747     }
0748 
0749 }
0750 
0751 u16
0752 fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id,
0753         u32 s_id, u16 ox_id)
0754 {
0755     fc_els_req_build(fchs, d_id, s_id, ox_id);
0756 
0757     memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
0758 
0759     rpsc->els_cmd.els_code = FC_ELS_RPSC;
0760     return sizeof(struct fc_rpsc_cmd_s);
0761 }
0762 
0763 u16
0764 fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id,
0765         u32 s_id, u32 *pid_list, u16 npids)
0766 {
0767     u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_hton3b(d_id));
0768     int i = 0;
0769 
0770     fc_els_req_build(fchs, bfa_hton3b(dctlr_id), s_id, 0);
0771 
0772     memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
0773 
0774     rpsc2->els_cmd.els_code = FC_ELS_RPSC;
0775     rpsc2->token = cpu_to_be32(FC_BRCD_TOKEN);
0776     rpsc2->num_pids  = cpu_to_be16(npids);
0777     for (i = 0; i < npids; i++)
0778         rpsc2->pid_list[i].pid = pid_list[i];
0779 
0780     return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) * (sizeof(u32)));
0781 }
0782 
0783 u16
0784 fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
0785         u32 d_id, u32 s_id, __be16 ox_id,
0786           struct fc_rpsc_speed_info_s *oper_speed)
0787 {
0788     memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
0789 
0790     fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0791 
0792     rpsc_acc->command = FC_ELS_ACC;
0793     rpsc_acc->num_entries = cpu_to_be16(1);
0794 
0795     rpsc_acc->speed_info[0].port_speed_cap =
0796         cpu_to_be16(oper_speed->port_speed_cap);
0797 
0798     rpsc_acc->speed_info[0].port_op_speed =
0799         cpu_to_be16(oper_speed->port_op_speed);
0800 
0801     return sizeof(struct fc_rpsc_acc_s);
0802 }
0803 
0804 u16
0805 fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
0806            wwn_t port_name, wwn_t node_name, u16 pdu_size)
0807 {
0808     struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
0809 
0810     memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s));
0811 
0812     pdisc->els_cmd.els_code = FC_ELS_PDISC;
0813     fc_els_req_build(fchs, d_id, s_id, ox_id);
0814 
0815     pdisc->csp.rxsz = pdisc->class3.rxsz = cpu_to_be16(pdu_size);
0816     pdisc->port_name = port_name;
0817     pdisc->node_name = node_name;
0818 
0819     return sizeof(struct fc_logi_s);
0820 }
0821 
0822 u16
0823 fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
0824 {
0825     struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
0826 
0827     if (len < sizeof(struct fc_logi_s))
0828         return FC_PARSE_LEN_INVAL;
0829 
0830     if (pdisc->els_cmd.els_code != FC_ELS_ACC)
0831         return FC_PARSE_ACC_INVAL;
0832 
0833     if (!wwn_is_equal(pdisc->port_name, port_name))
0834         return FC_PARSE_PWWN_NOT_EQUAL;
0835 
0836     if (!pdisc->class3.class_valid)
0837         return FC_PARSE_NWWN_NOT_EQUAL;
0838 
0839     if (be16_to_cpu(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
0840         return FC_PARSE_RXSZ_INVAL;
0841 
0842     return FC_PARSE_OK;
0843 }
0844 
0845 u16
0846 fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
0847           int num_pages)
0848 {
0849     struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1);
0850     int             page;
0851 
0852     fc_els_req_build(fchs, d_id, s_id, ox_id);
0853     memset(prlo, 0, (num_pages * 16) + 4);
0854     prlo->command = FC_ELS_PRLO;
0855     prlo->page_len = 0x10;
0856     prlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
0857 
0858     for (page = 0; page < num_pages; page++) {
0859         prlo->prlo_params[page].type = FC_TYPE_FCP;
0860         prlo->prlo_params[page].opa_valid = 0;
0861         prlo->prlo_params[page].rpa_valid = 0;
0862         prlo->prlo_params[page].orig_process_assc = 0;
0863         prlo->prlo_params[page].resp_process_assc = 0;
0864     }
0865 
0866     return be16_to_cpu(prlo->payload_len);
0867 }
0868 
0869 u16
0870 fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
0871            int num_pages, enum fc_tprlo_type tprlo_type, u32 tpr_id)
0872 {
0873     struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1);
0874     int             page;
0875 
0876     fc_els_req_build(fchs, d_id, s_id, ox_id);
0877     memset(tprlo, 0, (num_pages * 16) + 4);
0878     tprlo->command = FC_ELS_TPRLO;
0879     tprlo->page_len = 0x10;
0880     tprlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
0881 
0882     for (page = 0; page < num_pages; page++) {
0883         tprlo->tprlo_params[page].type = FC_TYPE_FCP;
0884         tprlo->tprlo_params[page].opa_valid = 0;
0885         tprlo->tprlo_params[page].rpa_valid = 0;
0886         tprlo->tprlo_params[page].orig_process_assc = 0;
0887         tprlo->tprlo_params[page].resp_process_assc = 0;
0888         if (tprlo_type == FC_GLOBAL_LOGO) {
0889             tprlo->tprlo_params[page].global_process_logout = 1;
0890         } else if (tprlo_type == FC_TPR_LOGO) {
0891             tprlo->tprlo_params[page].tpo_nport_valid = 1;
0892             tprlo->tprlo_params[page].tpo_nport_id = (tpr_id);
0893         }
0894     }
0895 
0896     return be16_to_cpu(tprlo->payload_len);
0897 }
0898 
0899 u16
0900 fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id,
0901         u32 reason_code, u32 reason_expl)
0902 {
0903     struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1);
0904 
0905     fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
0906 
0907     fchs->cat_info = FC_CAT_BA_RJT;
0908     ba_rjt->reason_code = reason_code;
0909     ba_rjt->reason_expl = reason_expl;
0910     return sizeof(struct fc_ba_rjt_s);
0911 }
0912 
0913 static void
0914 fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
0915 {
0916     memset(cthdr, 0, sizeof(struct ct_hdr_s));
0917     cthdr->rev_id = CT_GS3_REVISION;
0918     cthdr->gs_type = CT_GSTYPE_DIRSERVICE;
0919     cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER;
0920     cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
0921 }
0922 
0923 static void
0924 fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
0925 {
0926     memset(cthdr, 0, sizeof(struct ct_hdr_s));
0927     cthdr->rev_id = CT_GS3_REVISION;
0928     cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
0929     cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER;
0930     cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
0931 }
0932 
0933 static void
0934 fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code,
0935                      u8 sub_type)
0936 {
0937     memset(cthdr, 0, sizeof(struct ct_hdr_s));
0938     cthdr->rev_id = CT_GS3_REVISION;
0939     cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
0940     cthdr->gs_sub_type = sub_type;
0941     cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
0942 }
0943 
0944 u16
0945 fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
0946            wwn_t port_name)
0947 {
0948     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
0949     struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1);
0950     u32        d_id = bfa_hton3b(FC_NAME_SERVER);
0951 
0952     fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
0953     fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
0954 
0955     memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
0956     gidpn->port_name = port_name;
0957     return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s);
0958 }
0959 
0960 u16
0961 fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
0962            u32 port_id)
0963 {
0964     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
0965     fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1);
0966     u32        d_id = bfa_hton3b(FC_NAME_SERVER);
0967 
0968     fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
0969     fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
0970 
0971     memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
0972     gpnid->dap = port_id;
0973     return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s);
0974 }
0975 
0976 u16
0977 fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
0978            u32 port_id)
0979 {
0980     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
0981     fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1);
0982     u32        d_id = bfa_hton3b(FC_NAME_SERVER);
0983 
0984     fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
0985     fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
0986 
0987     memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
0988     gnnid->dap = port_id;
0989     return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s);
0990 }
0991 
0992 u16
0993 fc_ct_rsp_parse(struct ct_hdr_s *cthdr)
0994 {
0995     if (be16_to_cpu(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) {
0996         if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY)
0997             return FC_PARSE_BUSY;
0998         else
0999             return FC_PARSE_FAILURE;
1000     }
1001 
1002     return FC_PARSE_OK;
1003 }
1004 
1005 u16
1006 fc_gs_rjt_build(struct fchs_s *fchs,  struct ct_hdr_s *cthdr,
1007         u32 d_id, u32 s_id, u16 ox_id, u8 reason_code,
1008         u8 reason_code_expl)
1009 {
1010     fc_gsresp_fchdr_build(fchs, d_id, s_id, ox_id);
1011 
1012     cthdr->cmd_rsp_code = cpu_to_be16(CT_RSP_REJECT);
1013     cthdr->rev_id = CT_GS3_REVISION;
1014 
1015     cthdr->reason_code = reason_code;
1016     cthdr->exp_code    = reason_code_expl;
1017     return sizeof(struct ct_hdr_s);
1018 }
1019 
1020 u16
1021 fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
1022         u8 set_br_reg, u32 s_id, u16 ox_id)
1023 {
1024     u32        d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
1025 
1026     fc_els_req_build(fchs, d_id, s_id, ox_id);
1027 
1028     memset(scr, 0, sizeof(struct fc_scr_s));
1029     scr->command = FC_ELS_SCR;
1030     scr->reg_func = FC_SCR_REG_FUNC_FULL;
1031     if (set_br_reg)
1032         scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE;
1033 
1034     return sizeof(struct fc_scr_s);
1035 }
1036 
1037 u16
1038 fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn,
1039         u32 s_id, u16 ox_id)
1040 {
1041     u32        d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
1042     u16        payldlen;
1043 
1044     fc_els_req_build(fchs, d_id, s_id, ox_id);
1045     rscn->command = FC_ELS_RSCN;
1046     rscn->pagelen = sizeof(rscn->event[0]);
1047 
1048     payldlen = sizeof(u32) + rscn->pagelen;
1049     rscn->payldlen = cpu_to_be16(payldlen);
1050 
1051     rscn->event[0].format = FC_RSCN_FORMAT_PORTID;
1052     rscn->event[0].portid = s_id;
1053 
1054     return sizeof(struct fc_rscn_pl_s);
1055 }
1056 
1057 u16
1058 fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1059            enum bfa_lport_role roles)
1060 {
1061     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1062     struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
1063     u32        type_value, d_id = bfa_hton3b(FC_NAME_SERVER);
1064     u8         index;
1065 
1066     fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1067     fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
1068 
1069     memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
1070 
1071     rftid->dap = s_id;
1072 
1073     /* By default, FCP FC4 Type is registered */
1074     index = FC_TYPE_FCP >> 5;
1075     type_value = 1 << (FC_TYPE_FCP % 32);
1076     rftid->fc4_type[index] = cpu_to_be32(type_value);
1077 
1078     return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
1079 }
1080 
1081 u16
1082 fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1083            u8 *fc4_bitmap, u32 bitmap_size)
1084 {
1085     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1086     struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
1087     u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1088 
1089     fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1090     fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
1091 
1092     memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
1093 
1094     rftid->dap = s_id;
1095     memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap,
1096         (bitmap_size < 32 ? bitmap_size : 32));
1097 
1098     return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
1099 }
1100 
1101 u16
1102 fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1103            u8 fc4_type, u8 fc4_ftrs)
1104 {
1105     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1106     struct fcgs_rffid_req_s *rffid = (struct fcgs_rffid_req_s *)(cthdr + 1);
1107     u32         d_id = bfa_hton3b(FC_NAME_SERVER);
1108 
1109     fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1110     fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID);
1111 
1112     memset(rffid, 0, sizeof(struct fcgs_rffid_req_s));
1113 
1114     rffid->dap      = s_id;
1115     rffid->fc4ftr_bits  = fc4_ftrs;
1116     rffid->fc4_type     = fc4_type;
1117 
1118     return sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s);
1119 }
1120 
1121 u16
1122 fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1123         u8 *name)
1124 {
1125 
1126     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1127     struct fcgs_rspnid_req_s *rspnid =
1128             (struct fcgs_rspnid_req_s *)(cthdr + 1);
1129     u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1130 
1131     fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1132     fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID);
1133 
1134     memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s));
1135 
1136     rspnid->dap = s_id;
1137     strlcpy(rspnid->spn, name, sizeof(rspnid->spn));
1138     rspnid->spn_len = (u8) strlen(rspnid->spn);
1139 
1140     return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s);
1141 }
1142 
1143 u16
1144 fc_rsnn_nn_build(struct fchs_s *fchs, void *pyld, u32 s_id,
1145             wwn_t node_name, u8 *name)
1146 {
1147     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1148     struct fcgs_rsnn_nn_req_s *rsnn_nn =
1149         (struct fcgs_rsnn_nn_req_s *) (cthdr + 1);
1150     u32 d_id = bfa_hton3b(FC_NAME_SERVER);
1151 
1152     fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1153     fc_gs_cthdr_build(cthdr, s_id, GS_RSNN_NN);
1154 
1155     memset(rsnn_nn, 0, sizeof(struct fcgs_rsnn_nn_req_s));
1156 
1157     rsnn_nn->node_name = node_name;
1158     strlcpy(rsnn_nn->snn, name, sizeof(rsnn_nn->snn));
1159     rsnn_nn->snn_len = (u8) strlen(rsnn_nn->snn);
1160 
1161     return sizeof(struct fcgs_rsnn_nn_req_s) + sizeof(struct ct_hdr_s);
1162 }
1163 
1164 u16
1165 fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type)
1166 {
1167 
1168     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1169     struct fcgs_gidft_req_s *gidft = (struct fcgs_gidft_req_s *)(cthdr + 1);
1170     u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1171 
1172     fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1173 
1174     fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT);
1175 
1176     memset(gidft, 0, sizeof(struct fcgs_gidft_req_s));
1177     gidft->fc4_type = fc4_type;
1178     gidft->domain_id = 0;
1179     gidft->area_id = 0;
1180 
1181     return sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s);
1182 }
1183 
1184 u16
1185 fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1186            wwn_t port_name)
1187 {
1188     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1189     struct fcgs_rpnid_req_s *rpnid = (struct fcgs_rpnid_req_s *)(cthdr + 1);
1190     u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1191 
1192     fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1193     fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID);
1194 
1195     memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s));
1196     rpnid->port_id = port_id;
1197     rpnid->port_name = port_name;
1198 
1199     return sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s);
1200 }
1201 
1202 u16
1203 fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1204            wwn_t node_name)
1205 {
1206     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1207     struct fcgs_rnnid_req_s *rnnid = (struct fcgs_rnnid_req_s *)(cthdr + 1);
1208     u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1209 
1210     fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1211     fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID);
1212 
1213     memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s));
1214     rnnid->port_id = port_id;
1215     rnnid->node_name = node_name;
1216 
1217     return sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s);
1218 }
1219 
1220 u16
1221 fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1222            u32 cos)
1223 {
1224     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1225     struct fcgs_rcsid_req_s *rcsid =
1226             (struct fcgs_rcsid_req_s *) (cthdr + 1);
1227     u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1228 
1229     fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1230     fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID);
1231 
1232     memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s));
1233     rcsid->port_id = port_id;
1234     rcsid->cos = cos;
1235 
1236     return sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s);
1237 }
1238 
1239 u16
1240 fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1241            u8 port_type)
1242 {
1243     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1244     struct fcgs_rptid_req_s *rptid = (struct fcgs_rptid_req_s *)(cthdr + 1);
1245     u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1246 
1247     fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1248     fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID);
1249 
1250     memset(rptid, 0, sizeof(struct fcgs_rptid_req_s));
1251     rptid->port_id = port_id;
1252     rptid->port_type = port_type;
1253 
1254     return sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s);
1255 }
1256 
1257 u16
1258 fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id)
1259 {
1260     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1261     struct fcgs_ganxt_req_s *ganxt = (struct fcgs_ganxt_req_s *)(cthdr + 1);
1262     u32        d_id = bfa_hton3b(FC_NAME_SERVER);
1263 
1264     fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1265     fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT);
1266 
1267     memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s));
1268     ganxt->port_id = port_id;
1269 
1270     return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s);
1271 }
1272 
1273 /*
1274  * Builds fc hdr and ct hdr for FDMI requests.
1275  */
1276 u16
1277 fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
1278              u16 cmd_code)
1279 {
1280 
1281     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1282     u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
1283 
1284     fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1285     fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code);
1286 
1287     return sizeof(struct ct_hdr_s);
1288 }
1289 
1290 /*
1291  * Given a FC4 Type, this function returns a fc4 type bitmask
1292  */
1293 void
1294 fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask)
1295 {
1296     u8         index;
1297     __be32       *ptr = (__be32 *) bit_mask;
1298     u32        type_value;
1299 
1300     /*
1301      * @todo : Check for bitmask size
1302      */
1303 
1304     index = fc4_type >> 5;
1305     type_value = 1 << (fc4_type % 32);
1306     ptr[index] = cpu_to_be32(type_value);
1307 
1308 }
1309 
1310 /*
1311  *  GMAL Request
1312  */
1313 u16
1314 fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
1315 {
1316     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1317     fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1);
1318     u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
1319 
1320     fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1321     fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD,
1322             CT_GSSUBTYPE_CFGSERVER);
1323 
1324     memset(gmal, 0, sizeof(fcgs_gmal_req_t));
1325     gmal->wwn = wwn;
1326 
1327     return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t);
1328 }
1329 
1330 /*
1331  * GFN (Get Fabric Name) Request
1332  */
1333 u16
1334 fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
1335 {
1336     struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1337     fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1);
1338     u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
1339 
1340     fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1341     fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD,
1342             CT_GSSUBTYPE_CFGSERVER);
1343 
1344     memset(gfn, 0, sizeof(fcgs_gfn_req_t));
1345     gfn->wwn = wwn;
1346 
1347     return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t);
1348 }