root/drivers/scsi/bfa/bfa_fcbuild.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fcbuild_init
  2. fc_gs_fchdr_build
  3. fc_gsresp_fchdr_build
  4. fc_els_req_build
  5. fc_els_rsp_build
  6. fc_bls_rsp_build
  7. fc_plogi_x_build
  8. fc_flogi_build
  9. fc_flogi_acc_build
  10. fc_fdisc_build
  11. fc_plogi_build
  12. fc_plogi_acc_build
  13. fc_plogi_rsp_parse
  14. fc_plogi_parse
  15. fc_prli_build
  16. fc_prli_acc_build
  17. fc_prli_rsp_parse
  18. fc_prli_parse
  19. fc_logo_build
  20. fc_adisc_x_build
  21. fc_adisc_build
  22. fc_adisc_acc_build
  23. fc_adisc_rsp_parse
  24. fc_adisc_parse
  25. fc_pdisc_parse
  26. fc_abts_build
  27. fc_abts_rsp_parse
  28. fc_rrq_build
  29. fc_logo_acc_build
  30. fc_ls_rjt_build
  31. fc_ba_acc_build
  32. fc_ls_acc_build
  33. fc_logout_params_pages
  34. fc_tprlo_acc_build
  35. fc_prlo_acc_build
  36. fc_rnid_build
  37. fc_rnid_acc_build
  38. fc_rpsc_build
  39. fc_rpsc2_build
  40. fc_rpsc_acc_build
  41. fc_pdisc_build
  42. fc_pdisc_rsp_parse
  43. fc_prlo_build
  44. fc_tprlo_build
  45. fc_ba_rjt_build
  46. fc_gs_cthdr_build
  47. fc_gs_fdmi_cthdr_build
  48. fc_gs_ms_cthdr_build
  49. fc_gidpn_build
  50. fc_gpnid_build
  51. fc_gnnid_build
  52. fc_ct_rsp_parse
  53. fc_gs_rjt_build
  54. fc_scr_build
  55. fc_rscn_build
  56. fc_rftid_build
  57. fc_rftid_build_sol
  58. fc_rffid_build
  59. fc_rspnid_build
  60. fc_rsnn_nn_build
  61. fc_gid_ft_build
  62. fc_rpnid_build
  63. fc_rnnid_build
  64. fc_rcsid_build
  65. fc_rptid_build
  66. fc_ganxt_build
  67. fc_fdmi_reqhdr_build
  68. fc_get_fc4type_bitmask
  69. fc_gmal_req_build
  70. fc_gfn_req_build

   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  */
  20 static void     fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
  21                                  __be16 ox_id);
  22 static void     fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
  23                                  __be16 ox_id);
  24 static struct fchs_s fc_els_req_tmpl;
  25 static struct fchs_s fc_els_rsp_tmpl;
  26 static struct fchs_s fc_bls_req_tmpl;
  27 static struct fchs_s fc_bls_rsp_tmpl;
  28 static struct fc_ba_acc_s ba_acc_tmpl;
  29 static struct fc_logi_s plogi_tmpl;
  30 static struct fc_prli_s prli_tmpl;
  31 static struct fc_rrq_s rrq_tmpl;
  32 static struct fchs_s fcp_fchs_tmpl;
  33 
  34 void
  35 fcbuild_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 
 129 static void
 130 fc_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 
 151 static void
 152 fc_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 
 167 void
 168 fc_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 
 176 static void
 177 fc_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 
 185 static void
 186 fc_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 
 194 static          u16
 195 fc_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 
 222 u16
 223 fc_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 
 260 u16
 261 fc_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 
 282 u16
 283 fc_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 
 300 u16
 301 fc_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 
 309 u16
 310 fc_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 
 318 enum fc_parse_status
 319 fc_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 
 352 enum fc_parse_status
 353 fc_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 
 368 u16
 369 fc_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 
 387 u16
 388 fc_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 
 405 enum fc_parse_status
 406 fc_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 
 424 enum fc_parse_status
 425 fc_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 
 439 u16
 440 fc_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 
 453 static u16
 454 fc_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 
 475 u16
 476 fc_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 
 483 u16
 484 fc_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 
 492 enum fc_parse_status
 493 fc_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 
 509 enum fc_parse_status
 510 fc_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 
 526 enum fc_parse_status
 527 fc_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 
 548 u16
 549 fc_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 
 560 enum fc_parse_status
 561 fc_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 
 570 u16
 571 fc_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 
 587 u16
 588 fc_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 
 601 u16
 602 fc_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 
 617 u16
 618 fc_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 
 633 u16
 634 fc_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 
 644 int
 645 fc_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 
 661 u16
 662 fc_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 
 685 u16
 686 fc_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 
 709 u16
 710 fc_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 
 723 u16
 724 fc_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 
 751 u16
 752 fc_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 
 763 u16
 764 fc_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 
 783 u16
 784 fc_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 
 804 u16
 805 fc_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 
 822 u16
 823 fc_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 
 845 u16
 846 fc_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 
 869 u16
 870 fc_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 
 899 u16
 900 fc_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 
 913 static void
 914 fc_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 
 923 static void
 924 fc_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 
 933 static void
 934 fc_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 
 944 u16
 945 fc_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 
 960 u16
 961 fc_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 
 976 u16
 977 fc_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 
 992 u16
 993 fc_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 
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 }

/* [<][>][^][v][top][bottom][index][help] */