linux/drivers/scsi/bfa/bfa_fcbuild.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
   4 * Copyright (c) 2014- QLogic Corporation.
   5 * All rights reserved
   6 * www.qlogic.com
   7 *
   8 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
   9 */
  10/*
  11 * fcbuild.c - FC link service frame building and parsing routines
  12 */
  13
  14#include "bfad_drv.h"
  15#include "bfa_fcbuild.h"
  16
  17/*
  18 * static build functions
  19 */
  20static void     fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
  21                                 __be16 ox_id);
  22static void     fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
  23                                 __be16 ox_id);
  24static struct fchs_s fc_els_req_tmpl;
  25static struct fchs_s fc_els_rsp_tmpl;
  26static struct fchs_s fc_bls_req_tmpl;
  27static struct fchs_s fc_bls_rsp_tmpl;
  28static struct fc_ba_acc_s ba_acc_tmpl;
  29static struct fc_logi_s plogi_tmpl;
  30static struct fc_prli_s prli_tmpl;
  31static struct fc_rrq_s rrq_tmpl;
  32static struct fchs_s fcp_fchs_tmpl;
  33
  34void
  35fcbuild_init(void)
  36{
  37        /*
  38         * fc_els_req_tmpl
  39         */
  40        fc_els_req_tmpl.routing = FC_RTG_EXT_LINK;
  41        fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST;
  42        fc_els_req_tmpl.type = FC_TYPE_ELS;
  43        fc_els_req_tmpl.f_ctl =
  44                bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
  45                              FCTL_SI_XFER);
  46        fc_els_req_tmpl.rx_id = FC_RXID_ANY;
  47
  48        /*
  49         * fc_els_rsp_tmpl
  50         */
  51        fc_els_rsp_tmpl.routing = FC_RTG_EXT_LINK;
  52        fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY;
  53        fc_els_rsp_tmpl.type = FC_TYPE_ELS;
  54        fc_els_rsp_tmpl.f_ctl =
  55                bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
  56                              FCTL_END_SEQ | FCTL_SI_XFER);
  57        fc_els_rsp_tmpl.rx_id = FC_RXID_ANY;
  58
  59        /*
  60         * fc_bls_req_tmpl
  61         */
  62        fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK;
  63        fc_bls_req_tmpl.type = FC_TYPE_BLS;
  64        fc_bls_req_tmpl.f_ctl = bfa_hton3b(FCTL_END_SEQ | FCTL_SI_XFER);
  65        fc_bls_req_tmpl.rx_id = FC_RXID_ANY;
  66
  67        /*
  68         * fc_bls_rsp_tmpl
  69         */
  70        fc_bls_rsp_tmpl.routing = FC_RTG_BASIC_LINK;
  71        fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC;
  72        fc_bls_rsp_tmpl.type = FC_TYPE_BLS;
  73        fc_bls_rsp_tmpl.f_ctl =
  74                bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
  75                              FCTL_END_SEQ | FCTL_SI_XFER);
  76        fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY;
  77
  78        /*
  79         * ba_acc_tmpl
  80         */
  81        ba_acc_tmpl.seq_id_valid = 0;
  82        ba_acc_tmpl.low_seq_cnt = 0;
  83        ba_acc_tmpl.high_seq_cnt = 0xFFFF;
  84
  85        /*
  86         * plogi_tmpl
  87         */
  88        plogi_tmpl.csp.verhi = FC_PH_VER_PH_3;
  89        plogi_tmpl.csp.verlo = FC_PH_VER_4_3;
  90        plogi_tmpl.csp.ciro = 0x1;
  91        plogi_tmpl.csp.cisc = 0x0;
  92        plogi_tmpl.csp.altbbcred = 0x0;
  93        plogi_tmpl.csp.conseq = cpu_to_be16(0x00FF);
  94        plogi_tmpl.csp.ro_bitmap = cpu_to_be16(0x0002);
  95        plogi_tmpl.csp.e_d_tov = cpu_to_be32(2000);
  96
  97        plogi_tmpl.class3.class_valid = 1;
  98        plogi_tmpl.class3.sequential = 1;
  99        plogi_tmpl.class3.conseq = 0xFF;
 100        plogi_tmpl.class3.ospx = 1;
 101
 102        /*
 103         * prli_tmpl
 104         */
 105        prli_tmpl.command = FC_ELS_PRLI;
 106        prli_tmpl.pglen = 0x10;
 107        prli_tmpl.pagebytes = cpu_to_be16(0x0014);
 108        prli_tmpl.parampage.type = FC_TYPE_FCP;
 109        prli_tmpl.parampage.imagepair = 1;
 110        prli_tmpl.parampage.servparams.rxrdisab = 1;
 111
 112        /*
 113         * rrq_tmpl
 114         */
 115        rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ;
 116
 117        /*
 118         * fcp_struct fchs_s mpl
 119         */
 120        fcp_fchs_tmpl.routing = FC_RTG_FC4_DEV_DATA;
 121        fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD;
 122        fcp_fchs_tmpl.type = FC_TYPE_FCP;
 123        fcp_fchs_tmpl.f_ctl =
 124                bfa_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER);
 125        fcp_fchs_tmpl.seq_id = 1;
 126        fcp_fchs_tmpl.rx_id = FC_RXID_ANY;
 127}
 128
 129static void
 130fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
 131{
 132        memset(fchs, 0, sizeof(struct fchs_s));
 133
 134        fchs->routing = FC_RTG_FC4_DEV_DATA;
 135        fchs->cat_info = FC_CAT_UNSOLICIT_CTRL;
 136        fchs->type = FC_TYPE_SERVICES;
 137        fchs->f_ctl =
 138                bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
 139                              FCTL_SI_XFER);
 140        fchs->rx_id = FC_RXID_ANY;
 141        fchs->d_id = (d_id);
 142        fchs->s_id = (s_id);
 143        fchs->ox_id = cpu_to_be16(ox_id);
 144
 145        /*
 146         * @todo no need to set ox_id for request
 147         *       no need to set rx_id for response
 148         */
 149}
 150
 151static void
 152fc_gsresp_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
 153{
 154        memset(fchs, 0, sizeof(struct fchs_s));
 155
 156        fchs->routing = FC_RTG_FC4_DEV_DATA;
 157        fchs->cat_info = FC_CAT_SOLICIT_CTRL;
 158        fchs->type = FC_TYPE_SERVICES;
 159        fchs->f_ctl =
 160                bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
 161                           FCTL_END_SEQ | FCTL_SI_XFER);
 162        fchs->d_id = d_id;
 163        fchs->s_id = s_id;
 164        fchs->ox_id = ox_id;
 165}
 166
 167void
 168fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
 169{
 170        memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s));
 171        fchs->d_id = (d_id);
 172        fchs->s_id = (s_id);
 173        fchs->ox_id = cpu_to_be16(ox_id);
 174}
 175
 176static void
 177fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
 178{
 179        memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s));
 180        fchs->d_id = d_id;
 181        fchs->s_id = s_id;
 182        fchs->ox_id = ox_id;
 183}
 184
 185static void
 186fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
 187{
 188        memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s));
 189        fchs->d_id = d_id;
 190        fchs->s_id = s_id;
 191        fchs->ox_id = ox_id;
 192}
 193
 194static          u16
 195fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 196                 __be16 ox_id, wwn_t port_name, wwn_t node_name,
 197                 u16 pdu_size, u16 bb_cr, u8 els_code)
 198{
 199        struct fc_logi_s *plogi = (struct fc_logi_s *) (pld);
 200
 201        memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
 202
 203        /* For FC AL bb_cr is 0 and altbbcred is 1 */
 204        if (!bb_cr)
 205                plogi->csp.altbbcred = 1;
 206
 207        plogi->els_cmd.els_code = els_code;
 208        if (els_code == FC_ELS_PLOGI)
 209                fc_els_req_build(fchs, d_id, s_id, ox_id);
 210        else
 211                fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 212
 213        plogi->csp.rxsz = plogi->class3.rxsz = cpu_to_be16(pdu_size);
 214        plogi->csp.bbcred  = cpu_to_be16(bb_cr);
 215
 216        memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
 217        memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
 218
 219        return sizeof(struct fc_logi_s);
 220}
 221
 222u16
 223fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
 224                u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size,
 225               u8 set_npiv, u8 set_auth, u16 local_bb_credits)
 226{
 227        u32        d_id = bfa_hton3b(FC_FABRIC_PORT);
 228        __be32  *vvl_info;
 229
 230        memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
 231
 232        flogi->els_cmd.els_code = FC_ELS_FLOGI;
 233        fc_els_req_build(fchs, d_id, s_id, ox_id);
 234
 235        flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
 236        flogi->port_name = port_name;
 237        flogi->node_name = node_name;
 238
 239        /*
 240         * Set the NPIV Capability Bit ( word 1, bit 31) of Common
 241         * Service Parameters.
 242         */
 243        flogi->csp.ciro = set_npiv;
 244
 245        /* set AUTH capability */
 246        flogi->csp.security = set_auth;
 247
 248        flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
 249
 250        /* Set brcd token in VVL */
 251        vvl_info = (u32 *)&flogi->vvl[0];
 252
 253        /* set the flag to indicate the presence of VVL */
 254        flogi->csp.npiv_supp    = 1; /* @todo. field name is not correct */
 255        vvl_info[0]     = cpu_to_be32(FLOGI_VVL_BRCD);
 256
 257        return sizeof(struct fc_logi_s);
 258}
 259
 260u16
 261fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
 262                   __be16 ox_id, wwn_t port_name, wwn_t node_name,
 263                   u16 pdu_size, u16 local_bb_credits, u8 bb_scn)
 264{
 265        u32        d_id = 0;
 266        u16        bbscn_rxsz = (bb_scn << 12) | pdu_size;
 267
 268        memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
 269        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 270
 271        flogi->els_cmd.els_code = FC_ELS_ACC;
 272        flogi->class3.rxsz = cpu_to_be16(pdu_size);
 273        flogi->csp.rxsz  = cpu_to_be16(bbscn_rxsz);     /* bb_scn/rxsz */
 274        flogi->port_name = port_name;
 275        flogi->node_name = node_name;
 276
 277        flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
 278
 279        return sizeof(struct fc_logi_s);
 280}
 281
 282u16
 283fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
 284                u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size)
 285{
 286        u32        d_id = bfa_hton3b(FC_FABRIC_PORT);
 287
 288        memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
 289
 290        flogi->els_cmd.els_code = FC_ELS_FDISC;
 291        fc_els_req_build(fchs, d_id, s_id, ox_id);
 292
 293        flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
 294        flogi->port_name = port_name;
 295        flogi->node_name = node_name;
 296
 297        return sizeof(struct fc_logi_s);
 298}
 299
 300u16
 301fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 302               u16 ox_id, wwn_t port_name, wwn_t node_name,
 303               u16 pdu_size, u16 bb_cr)
 304{
 305        return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
 306                                node_name, pdu_size, bb_cr, FC_ELS_PLOGI);
 307}
 308
 309u16
 310fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 311                   u16 ox_id, wwn_t port_name, wwn_t node_name,
 312                   u16 pdu_size, u16 bb_cr)
 313{
 314        return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
 315                                node_name, pdu_size, bb_cr, FC_ELS_ACC);
 316}
 317
 318enum fc_parse_status
 319fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
 320{
 321        struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
 322        struct fc_logi_s *plogi;
 323        struct fc_ls_rjt_s *ls_rjt;
 324
 325        switch (els_cmd->els_code) {
 326        case FC_ELS_LS_RJT:
 327                ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1);
 328                if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
 329                        return FC_PARSE_BUSY;
 330                else
 331                        return FC_PARSE_FAILURE;
 332        case FC_ELS_ACC:
 333                plogi = (struct fc_logi_s *) (fchs + 1);
 334                if (len < sizeof(struct fc_logi_s))
 335                        return FC_PARSE_FAILURE;
 336
 337                if (!wwn_is_equal(plogi->port_name, port_name))
 338                        return FC_PARSE_FAILURE;
 339
 340                if (!plogi->class3.class_valid)
 341                        return FC_PARSE_FAILURE;
 342
 343                if (be16_to_cpu(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
 344                        return FC_PARSE_FAILURE;
 345
 346                return FC_PARSE_OK;
 347        default:
 348                return FC_PARSE_FAILURE;
 349        }
 350}
 351
 352enum fc_parse_status
 353fc_plogi_parse(struct fchs_s *fchs)
 354{
 355        struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1);
 356
 357        if (plogi->class3.class_valid != 1)
 358                return FC_PARSE_FAILURE;
 359
 360        if ((be16_to_cpu(plogi->class3.rxsz) < FC_MIN_PDUSZ)
 361            || (be16_to_cpu(plogi->class3.rxsz) > FC_MAX_PDUSZ)
 362            || (plogi->class3.rxsz == 0))
 363                return FC_PARSE_FAILURE;
 364
 365        return FC_PARSE_OK;
 366}
 367
 368u16
 369fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 370              u16 ox_id)
 371{
 372        struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
 373
 374        fc_els_req_build(fchs, d_id, s_id, ox_id);
 375        memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
 376
 377        prli->command = FC_ELS_PRLI;
 378        prli->parampage.servparams.initiator     = 1;
 379        prli->parampage.servparams.retry         = 1;
 380        prli->parampage.servparams.rec_support   = 1;
 381        prli->parampage.servparams.task_retry_id = 0;
 382        prli->parampage.servparams.confirm       = 1;
 383
 384        return sizeof(struct fc_prli_s);
 385}
 386
 387u16
 388fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 389                  __be16 ox_id, enum bfa_lport_role role)
 390{
 391        struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
 392
 393        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 394        memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
 395
 396        prli->command = FC_ELS_ACC;
 397
 398        prli->parampage.servparams.initiator = 1;
 399
 400        prli->parampage.rspcode = FC_PRLI_ACC_XQTD;
 401
 402        return sizeof(struct fc_prli_s);
 403}
 404
 405enum fc_parse_status
 406fc_prli_rsp_parse(struct fc_prli_s *prli, int len)
 407{
 408        if (len < sizeof(struct fc_prli_s))
 409                return FC_PARSE_FAILURE;
 410
 411        if (prli->command != FC_ELS_ACC)
 412                return FC_PARSE_FAILURE;
 413
 414        if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD)
 415            && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG))
 416                return FC_PARSE_FAILURE;
 417
 418        if (prli->parampage.servparams.target != 1)
 419                return FC_PARSE_FAILURE;
 420
 421        return FC_PARSE_OK;
 422}
 423
 424enum fc_parse_status
 425fc_prli_parse(struct fc_prli_s *prli)
 426{
 427        if (prli->parampage.type != FC_TYPE_FCP)
 428                return FC_PARSE_FAILURE;
 429
 430        if (!prli->parampage.imagepair)
 431                return FC_PARSE_FAILURE;
 432
 433        if (!prli->parampage.servparams.initiator)
 434                return FC_PARSE_FAILURE;
 435
 436        return FC_PARSE_OK;
 437}
 438
 439u16
 440fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id,
 441              u16 ox_id, wwn_t port_name)
 442{
 443        fc_els_req_build(fchs, d_id, s_id, ox_id);
 444
 445        memset(logo, '\0', sizeof(struct fc_logo_s));
 446        logo->els_cmd.els_code = FC_ELS_LOGO;
 447        logo->nport_id = (s_id);
 448        logo->orig_port_name = port_name;
 449
 450        return sizeof(struct fc_logo_s);
 451}
 452
 453static u16
 454fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
 455                 u32 s_id, __be16 ox_id, wwn_t port_name,
 456                 wwn_t node_name, u8 els_code)
 457{
 458        memset(adisc, '\0', sizeof(struct fc_adisc_s));
 459
 460        adisc->els_cmd.els_code = els_code;
 461
 462        if (els_code == FC_ELS_ADISC)
 463                fc_els_req_build(fchs, d_id, s_id, ox_id);
 464        else
 465                fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 466
 467        adisc->orig_HA = 0;
 468        adisc->orig_port_name = port_name;
 469        adisc->orig_node_name = node_name;
 470        adisc->nport_id = (s_id);
 471
 472        return sizeof(struct fc_adisc_s);
 473}
 474
 475u16
 476fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
 477                u32 s_id, __be16 ox_id, wwn_t port_name, wwn_t node_name)
 478{
 479        return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
 480                                node_name, FC_ELS_ADISC);
 481}
 482
 483u16
 484fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
 485                   u32 s_id, __be16 ox_id, wwn_t port_name,
 486                   wwn_t node_name)
 487{
 488        return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
 489                                node_name, FC_ELS_ACC);
 490}
 491
 492enum fc_parse_status
 493fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name,
 494                                 wwn_t node_name)
 495{
 496
 497        if (len < sizeof(struct fc_adisc_s))
 498                return FC_PARSE_FAILURE;
 499
 500        if (adisc->els_cmd.els_code != FC_ELS_ACC)
 501                return FC_PARSE_FAILURE;
 502
 503        if (!wwn_is_equal(adisc->orig_port_name, port_name))
 504                return FC_PARSE_FAILURE;
 505
 506        return FC_PARSE_OK;
 507}
 508
 509enum fc_parse_status
 510fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap, wwn_t node_name,
 511               wwn_t port_name)
 512{
 513        struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld;
 514
 515        if (adisc->els_cmd.els_code != FC_ELS_ACC)
 516                return FC_PARSE_FAILURE;
 517
 518        if ((adisc->nport_id == (host_dap))
 519            && wwn_is_equal(adisc->orig_port_name, port_name)
 520            && wwn_is_equal(adisc->orig_node_name, node_name))
 521                return FC_PARSE_OK;
 522
 523        return FC_PARSE_FAILURE;
 524}
 525
 526enum fc_parse_status
 527fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name)
 528{
 529        struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
 530
 531        if (pdisc->class3.class_valid != 1)
 532                return FC_PARSE_FAILURE;
 533
 534        if ((be16_to_cpu(pdisc->class3.rxsz) <
 535                (FC_MIN_PDUSZ - sizeof(struct fchs_s)))
 536            || (pdisc->class3.rxsz == 0))
 537                return FC_PARSE_FAILURE;
 538
 539        if (!wwn_is_equal(pdisc->port_name, port_name))
 540                return FC_PARSE_FAILURE;
 541
 542        if (!wwn_is_equal(pdisc->node_name, node_name))
 543                return FC_PARSE_FAILURE;
 544
 545        return FC_PARSE_OK;
 546}
 547
 548u16
 549fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
 550{
 551        memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s));
 552        fchs->cat_info = FC_CAT_ABTS;
 553        fchs->d_id = (d_id);
 554        fchs->s_id = (s_id);
 555        fchs->ox_id = cpu_to_be16(ox_id);
 556
 557        return sizeof(struct fchs_s);
 558}
 559
 560enum fc_parse_status
 561fc_abts_rsp_parse(struct fchs_s *fchs, int len)
 562{
 563        if ((fchs->cat_info == FC_CAT_BA_ACC)
 564            || (fchs->cat_info == FC_CAT_BA_RJT))
 565                return FC_PARSE_OK;
 566
 567        return FC_PARSE_FAILURE;
 568}
 569
 570u16
 571fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id,
 572             u16 ox_id, u16 rrq_oxid)
 573{
 574        fc_els_req_build(fchs, d_id, s_id, ox_id);
 575
 576        /*
 577         * build rrq payload
 578         */
 579        memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s));
 580        rrq->s_id = (s_id);
 581        rrq->ox_id = cpu_to_be16(rrq_oxid);
 582        rrq->rx_id = FC_RXID_ANY;
 583
 584        return sizeof(struct fc_rrq_s);
 585}
 586
 587u16
 588fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 589                  __be16 ox_id)
 590{
 591        struct fc_els_cmd_s *acc = pld;
 592
 593        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 594
 595        memset(acc, 0, sizeof(struct fc_els_cmd_s));
 596        acc->els_code = FC_ELS_ACC;
 597
 598        return sizeof(struct fc_els_cmd_s);
 599}
 600
 601u16
 602fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
 603                u32 s_id, __be16 ox_id, u8 reason_code,
 604                u8 reason_code_expl)
 605{
 606        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 607        memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s));
 608
 609        ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT;
 610        ls_rjt->reason_code = reason_code;
 611        ls_rjt->reason_code_expl = reason_code_expl;
 612        ls_rjt->vendor_unique = 0x00;
 613
 614        return sizeof(struct fc_ls_rjt_s);
 615}
 616
 617u16
 618fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
 619                u32 s_id, __be16 ox_id, u16 rx_id)
 620{
 621        fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
 622
 623        memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s));
 624
 625        fchs->rx_id = rx_id;
 626
 627        ba_acc->ox_id = fchs->ox_id;
 628        ba_acc->rx_id = fchs->rx_id;
 629
 630        return sizeof(struct fc_ba_acc_s);
 631}
 632
 633u16
 634fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id,
 635                u32 s_id, __be16 ox_id)
 636{
 637        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 638        memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
 639        els_cmd->els_code = FC_ELS_ACC;
 640
 641        return sizeof(struct fc_els_cmd_s);
 642}
 643
 644int
 645fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code)
 646{
 647        int             num_pages = 0;
 648        struct fc_prlo_s *prlo;
 649        struct fc_tprlo_s *tprlo;
 650
 651        if (els_code == FC_ELS_PRLO) {
 652                prlo = (struct fc_prlo_s *) (fc_frame + 1);
 653                num_pages = (be16_to_cpu(prlo->payload_len) - 4) / 16;
 654        } else {
 655                tprlo = (struct fc_tprlo_s *) (fc_frame + 1);
 656                num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16;
 657        }
 658        return num_pages;
 659}
 660
 661u16
 662fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
 663                u32 d_id, u32 s_id, __be16 ox_id, int num_pages)
 664{
 665        int             page;
 666
 667        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 668
 669        memset(tprlo_acc, 0, (num_pages * 16) + 4);
 670        tprlo_acc->command = FC_ELS_ACC;
 671
 672        tprlo_acc->page_len = 0x10;
 673        tprlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
 674
 675        for (page = 0; page < num_pages; page++) {
 676                tprlo_acc->tprlo_acc_params[page].opa_valid = 0;
 677                tprlo_acc->tprlo_acc_params[page].rpa_valid = 0;
 678                tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
 679                tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0;
 680                tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0;
 681        }
 682        return be16_to_cpu(tprlo_acc->payload_len);
 683}
 684
 685u16
 686fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id,
 687                  u32 s_id, __be16 ox_id, int num_pages)
 688{
 689        int             page;
 690
 691        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 692
 693        memset(prlo_acc, 0, (num_pages * 16) + 4);
 694        prlo_acc->command = FC_ELS_ACC;
 695        prlo_acc->page_len = 0x10;
 696        prlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
 697
 698        for (page = 0; page < num_pages; page++) {
 699                prlo_acc->prlo_acc_params[page].opa_valid = 0;
 700                prlo_acc->prlo_acc_params[page].rpa_valid = 0;
 701                prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
 702                prlo_acc->prlo_acc_params[page].orig_process_assc = 0;
 703                prlo_acc->prlo_acc_params[page].resp_process_assc = 0;
 704        }
 705
 706        return be16_to_cpu(prlo_acc->payload_len);
 707}
 708
 709u16
 710fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id,
 711                u32 s_id, u16 ox_id, u32 data_format)
 712{
 713        fc_els_req_build(fchs, d_id, s_id, ox_id);
 714
 715        memset(rnid, 0, sizeof(struct fc_rnid_cmd_s));
 716
 717        rnid->els_cmd.els_code = FC_ELS_RNID;
 718        rnid->node_id_data_format = data_format;
 719
 720        return sizeof(struct fc_rnid_cmd_s);
 721}
 722
 723u16
 724fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id,
 725                  u32 s_id, __be16 ox_id, u32 data_format,
 726                  struct fc_rnid_common_id_data_s *common_id_data,
 727                  struct fc_rnid_general_topology_data_s *gen_topo_data)
 728{
 729        memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s));
 730
 731        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 732
 733        rnid_acc->els_cmd.els_code = FC_ELS_ACC;
 734        rnid_acc->node_id_data_format = data_format;
 735        rnid_acc->common_id_data_length =
 736                        sizeof(struct fc_rnid_common_id_data_s);
 737        rnid_acc->common_id_data = *common_id_data;
 738
 739        if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
 740                rnid_acc->specific_id_data_length =
 741                        sizeof(struct fc_rnid_general_topology_data_s);
 742                rnid_acc->gen_topology_data = *gen_topo_data;
 743                return sizeof(struct fc_rnid_acc_s);
 744        } else {
 745                return sizeof(struct fc_rnid_acc_s) -
 746                        sizeof(struct fc_rnid_general_topology_data_s);
 747        }
 748
 749}
 750
 751u16
 752fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id,
 753                u32 s_id, u16 ox_id)
 754{
 755        fc_els_req_build(fchs, d_id, s_id, ox_id);
 756
 757        memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
 758
 759        rpsc->els_cmd.els_code = FC_ELS_RPSC;
 760        return sizeof(struct fc_rpsc_cmd_s);
 761}
 762
 763u16
 764fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id,
 765                u32 s_id, u32 *pid_list, u16 npids)
 766{
 767        u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_hton3b(d_id));
 768        int i = 0;
 769
 770        fc_els_req_build(fchs, bfa_hton3b(dctlr_id), s_id, 0);
 771
 772        memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
 773
 774        rpsc2->els_cmd.els_code = FC_ELS_RPSC;
 775        rpsc2->token = cpu_to_be32(FC_BRCD_TOKEN);
 776        rpsc2->num_pids  = cpu_to_be16(npids);
 777        for (i = 0; i < npids; i++)
 778                rpsc2->pid_list[i].pid = pid_list[i];
 779
 780        return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) * (sizeof(u32)));
 781}
 782
 783u16
 784fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
 785                u32 d_id, u32 s_id, __be16 ox_id,
 786                  struct fc_rpsc_speed_info_s *oper_speed)
 787{
 788        memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
 789
 790        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 791
 792        rpsc_acc->command = FC_ELS_ACC;
 793        rpsc_acc->num_entries = cpu_to_be16(1);
 794
 795        rpsc_acc->speed_info[0].port_speed_cap =
 796                cpu_to_be16(oper_speed->port_speed_cap);
 797
 798        rpsc_acc->speed_info[0].port_op_speed =
 799                cpu_to_be16(oper_speed->port_op_speed);
 800
 801        return sizeof(struct fc_rpsc_acc_s);
 802}
 803
 804u16
 805fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
 806               wwn_t port_name, wwn_t node_name, u16 pdu_size)
 807{
 808        struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
 809
 810        memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s));
 811
 812        pdisc->els_cmd.els_code = FC_ELS_PDISC;
 813        fc_els_req_build(fchs, d_id, s_id, ox_id);
 814
 815        pdisc->csp.rxsz = pdisc->class3.rxsz = cpu_to_be16(pdu_size);
 816        pdisc->port_name = port_name;
 817        pdisc->node_name = node_name;
 818
 819        return sizeof(struct fc_logi_s);
 820}
 821
 822u16
 823fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
 824{
 825        struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
 826
 827        if (len < sizeof(struct fc_logi_s))
 828                return FC_PARSE_LEN_INVAL;
 829
 830        if (pdisc->els_cmd.els_code != FC_ELS_ACC)
 831                return FC_PARSE_ACC_INVAL;
 832
 833        if (!wwn_is_equal(pdisc->port_name, port_name))
 834                return FC_PARSE_PWWN_NOT_EQUAL;
 835
 836        if (!pdisc->class3.class_valid)
 837                return FC_PARSE_NWWN_NOT_EQUAL;
 838
 839        if (be16_to_cpu(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
 840                return FC_PARSE_RXSZ_INVAL;
 841
 842        return FC_PARSE_OK;
 843}
 844
 845u16
 846fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
 847              int num_pages)
 848{
 849        struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1);
 850        int             page;
 851
 852        fc_els_req_build(fchs, d_id, s_id, ox_id);
 853        memset(prlo, 0, (num_pages * 16) + 4);
 854        prlo->command = FC_ELS_PRLO;
 855        prlo->page_len = 0x10;
 856        prlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
 857
 858        for (page = 0; page < num_pages; page++) {
 859                prlo->prlo_params[page].type = FC_TYPE_FCP;
 860                prlo->prlo_params[page].opa_valid = 0;
 861                prlo->prlo_params[page].rpa_valid = 0;
 862                prlo->prlo_params[page].orig_process_assc = 0;
 863                prlo->prlo_params[page].resp_process_assc = 0;
 864        }
 865
 866        return be16_to_cpu(prlo->payload_len);
 867}
 868
 869u16
 870fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
 871               int num_pages, enum fc_tprlo_type tprlo_type, u32 tpr_id)
 872{
 873        struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1);
 874        int             page;
 875
 876        fc_els_req_build(fchs, d_id, s_id, ox_id);
 877        memset(tprlo, 0, (num_pages * 16) + 4);
 878        tprlo->command = FC_ELS_TPRLO;
 879        tprlo->page_len = 0x10;
 880        tprlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
 881
 882        for (page = 0; page < num_pages; page++) {
 883                tprlo->tprlo_params[page].type = FC_TYPE_FCP;
 884                tprlo->tprlo_params[page].opa_valid = 0;
 885                tprlo->tprlo_params[page].rpa_valid = 0;
 886                tprlo->tprlo_params[page].orig_process_assc = 0;
 887                tprlo->tprlo_params[page].resp_process_assc = 0;
 888                if (tprlo_type == FC_GLOBAL_LOGO) {
 889                        tprlo->tprlo_params[page].global_process_logout = 1;
 890                } else if (tprlo_type == FC_TPR_LOGO) {
 891                        tprlo->tprlo_params[page].tpo_nport_valid = 1;
 892                        tprlo->tprlo_params[page].tpo_nport_id = (tpr_id);
 893                }
 894        }
 895
 896        return be16_to_cpu(tprlo->payload_len);
 897}
 898
 899u16
 900fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id,
 901                u32 reason_code, u32 reason_expl)
 902{
 903        struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1);
 904
 905        fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
 906
 907        fchs->cat_info = FC_CAT_BA_RJT;
 908        ba_rjt->reason_code = reason_code;
 909        ba_rjt->reason_expl = reason_expl;
 910        return sizeof(struct fc_ba_rjt_s);
 911}
 912
 913static void
 914fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
 915{
 916        memset(cthdr, 0, sizeof(struct ct_hdr_s));
 917        cthdr->rev_id = CT_GS3_REVISION;
 918        cthdr->gs_type = CT_GSTYPE_DIRSERVICE;
 919        cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER;
 920        cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
 921}
 922
 923static void
 924fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
 925{
 926        memset(cthdr, 0, sizeof(struct ct_hdr_s));
 927        cthdr->rev_id = CT_GS3_REVISION;
 928        cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
 929        cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER;
 930        cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
 931}
 932
 933static void
 934fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code,
 935                                         u8 sub_type)
 936{
 937        memset(cthdr, 0, sizeof(struct ct_hdr_s));
 938        cthdr->rev_id = CT_GS3_REVISION;
 939        cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
 940        cthdr->gs_sub_type = sub_type;
 941        cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
 942}
 943
 944u16
 945fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
 946               wwn_t port_name)
 947{
 948        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
 949        struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1);
 950        u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 951
 952        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
 953        fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
 954
 955        memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
 956        gidpn->port_name = port_name;
 957        return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s);
 958}
 959
 960u16
 961fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
 962               u32 port_id)
 963{
 964        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
 965        fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1);
 966        u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 967
 968        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
 969        fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
 970
 971        memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
 972        gpnid->dap = port_id;
 973        return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s);
 974}
 975
 976u16
 977fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
 978               u32 port_id)
 979{
 980        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
 981        fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1);
 982        u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 983
 984        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
 985        fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
 986
 987        memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
 988        gnnid->dap = port_id;
 989        return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s);
 990}
 991
 992u16
 993fc_ct_rsp_parse(struct ct_hdr_s *cthdr)
 994{
 995        if (be16_to_cpu(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) {
 996                if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY)
 997                        return FC_PARSE_BUSY;
 998                else
 999                        return FC_PARSE_FAILURE;
1000        }
1001
1002        return FC_PARSE_OK;
1003}
1004
1005u16
1006fc_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
1020u16
1021fc_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
1037u16
1038fc_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
1057u16
1058fc_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
1081u16
1082fc_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
1101u16
1102fc_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
1121u16
1122fc_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
1143u16
1144fc_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
1164u16
1165fc_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
1184u16
1185fc_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
1202u16
1203fc_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
1220u16
1221fc_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
1239u16
1240fc_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
1257u16
1258fc_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 */
1276u16
1277fc_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 */
1293void
1294fc_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 */
1313u16
1314fc_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 */
1333u16
1334fc_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}
1349