cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bfa_fcbuild.c (35888B)


      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}