0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include "bfad_drv.h"
0015 #include "bfa_fcbuild.h"
0016
0017
0018
0019
0020 static void fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
0021 __be16 ox_id);
0022 static void fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
0023 __be16 ox_id);
0024 static struct fchs_s fc_els_req_tmpl;
0025 static struct fchs_s fc_els_rsp_tmpl;
0026 static struct fchs_s fc_bls_req_tmpl;
0027 static struct fchs_s fc_bls_rsp_tmpl;
0028 static struct fc_ba_acc_s ba_acc_tmpl;
0029 static struct fc_logi_s plogi_tmpl;
0030 static struct fc_prli_s prli_tmpl;
0031 static struct fc_rrq_s rrq_tmpl;
0032 static struct fchs_s fcp_fchs_tmpl;
0033
0034 void
0035 fcbuild_init(void)
0036 {
0037
0038
0039
0040 fc_els_req_tmpl.routing = FC_RTG_EXT_LINK;
0041 fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST;
0042 fc_els_req_tmpl.type = FC_TYPE_ELS;
0043 fc_els_req_tmpl.f_ctl =
0044 bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
0045 FCTL_SI_XFER);
0046 fc_els_req_tmpl.rx_id = FC_RXID_ANY;
0047
0048
0049
0050
0051 fc_els_rsp_tmpl.routing = FC_RTG_EXT_LINK;
0052 fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY;
0053 fc_els_rsp_tmpl.type = FC_TYPE_ELS;
0054 fc_els_rsp_tmpl.f_ctl =
0055 bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
0056 FCTL_END_SEQ | FCTL_SI_XFER);
0057 fc_els_rsp_tmpl.rx_id = FC_RXID_ANY;
0058
0059
0060
0061
0062 fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK;
0063 fc_bls_req_tmpl.type = FC_TYPE_BLS;
0064 fc_bls_req_tmpl.f_ctl = bfa_hton3b(FCTL_END_SEQ | FCTL_SI_XFER);
0065 fc_bls_req_tmpl.rx_id = FC_RXID_ANY;
0066
0067
0068
0069
0070 fc_bls_rsp_tmpl.routing = FC_RTG_BASIC_LINK;
0071 fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC;
0072 fc_bls_rsp_tmpl.type = FC_TYPE_BLS;
0073 fc_bls_rsp_tmpl.f_ctl =
0074 bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
0075 FCTL_END_SEQ | FCTL_SI_XFER);
0076 fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY;
0077
0078
0079
0080
0081 ba_acc_tmpl.seq_id_valid = 0;
0082 ba_acc_tmpl.low_seq_cnt = 0;
0083 ba_acc_tmpl.high_seq_cnt = 0xFFFF;
0084
0085
0086
0087
0088 plogi_tmpl.csp.verhi = FC_PH_VER_PH_3;
0089 plogi_tmpl.csp.verlo = FC_PH_VER_4_3;
0090 plogi_tmpl.csp.ciro = 0x1;
0091 plogi_tmpl.csp.cisc = 0x0;
0092 plogi_tmpl.csp.altbbcred = 0x0;
0093 plogi_tmpl.csp.conseq = cpu_to_be16(0x00FF);
0094 plogi_tmpl.csp.ro_bitmap = cpu_to_be16(0x0002);
0095 plogi_tmpl.csp.e_d_tov = cpu_to_be32(2000);
0096
0097 plogi_tmpl.class3.class_valid = 1;
0098 plogi_tmpl.class3.sequential = 1;
0099 plogi_tmpl.class3.conseq = 0xFF;
0100 plogi_tmpl.class3.ospx = 1;
0101
0102
0103
0104
0105 prli_tmpl.command = FC_ELS_PRLI;
0106 prli_tmpl.pglen = 0x10;
0107 prli_tmpl.pagebytes = cpu_to_be16(0x0014);
0108 prli_tmpl.parampage.type = FC_TYPE_FCP;
0109 prli_tmpl.parampage.imagepair = 1;
0110 prli_tmpl.parampage.servparams.rxrdisab = 1;
0111
0112
0113
0114
0115 rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ;
0116
0117
0118
0119
0120 fcp_fchs_tmpl.routing = FC_RTG_FC4_DEV_DATA;
0121 fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD;
0122 fcp_fchs_tmpl.type = FC_TYPE_FCP;
0123 fcp_fchs_tmpl.f_ctl =
0124 bfa_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER);
0125 fcp_fchs_tmpl.seq_id = 1;
0126 fcp_fchs_tmpl.rx_id = FC_RXID_ANY;
0127 }
0128
0129 static void
0130 fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
0131 {
0132 memset(fchs, 0, sizeof(struct fchs_s));
0133
0134 fchs->routing = FC_RTG_FC4_DEV_DATA;
0135 fchs->cat_info = FC_CAT_UNSOLICIT_CTRL;
0136 fchs->type = FC_TYPE_SERVICES;
0137 fchs->f_ctl =
0138 bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
0139 FCTL_SI_XFER);
0140 fchs->rx_id = FC_RXID_ANY;
0141 fchs->d_id = (d_id);
0142 fchs->s_id = (s_id);
0143 fchs->ox_id = cpu_to_be16(ox_id);
0144
0145
0146
0147
0148
0149 }
0150
0151 static void
0152 fc_gsresp_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
0153 {
0154 memset(fchs, 0, sizeof(struct fchs_s));
0155
0156 fchs->routing = FC_RTG_FC4_DEV_DATA;
0157 fchs->cat_info = FC_CAT_SOLICIT_CTRL;
0158 fchs->type = FC_TYPE_SERVICES;
0159 fchs->f_ctl =
0160 bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
0161 FCTL_END_SEQ | FCTL_SI_XFER);
0162 fchs->d_id = d_id;
0163 fchs->s_id = s_id;
0164 fchs->ox_id = ox_id;
0165 }
0166
0167 void
0168 fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
0169 {
0170 memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s));
0171 fchs->d_id = (d_id);
0172 fchs->s_id = (s_id);
0173 fchs->ox_id = cpu_to_be16(ox_id);
0174 }
0175
0176 static void
0177 fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
0178 {
0179 memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s));
0180 fchs->d_id = d_id;
0181 fchs->s_id = s_id;
0182 fchs->ox_id = ox_id;
0183 }
0184
0185 static void
0186 fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
0187 {
0188 memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s));
0189 fchs->d_id = d_id;
0190 fchs->s_id = s_id;
0191 fchs->ox_id = ox_id;
0192 }
0193
0194 static u16
0195 fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0196 __be16 ox_id, wwn_t port_name, wwn_t node_name,
0197 u16 pdu_size, u16 bb_cr, u8 els_code)
0198 {
0199 struct fc_logi_s *plogi = (struct fc_logi_s *) (pld);
0200
0201 memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
0202
0203
0204 if (!bb_cr)
0205 plogi->csp.altbbcred = 1;
0206
0207 plogi->els_cmd.els_code = els_code;
0208 if (els_code == FC_ELS_PLOGI)
0209 fc_els_req_build(fchs, d_id, s_id, ox_id);
0210 else
0211 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0212
0213 plogi->csp.rxsz = plogi->class3.rxsz = cpu_to_be16(pdu_size);
0214 plogi->csp.bbcred = cpu_to_be16(bb_cr);
0215
0216 memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
0217 memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
0218
0219 return sizeof(struct fc_logi_s);
0220 }
0221
0222 u16
0223 fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
0224 u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size,
0225 u8 set_npiv, u8 set_auth, u16 local_bb_credits)
0226 {
0227 u32 d_id = bfa_hton3b(FC_FABRIC_PORT);
0228 __be32 *vvl_info;
0229
0230 memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
0231
0232 flogi->els_cmd.els_code = FC_ELS_FLOGI;
0233 fc_els_req_build(fchs, d_id, s_id, ox_id);
0234
0235 flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
0236 flogi->port_name = port_name;
0237 flogi->node_name = node_name;
0238
0239
0240
0241
0242
0243 flogi->csp.ciro = set_npiv;
0244
0245
0246 flogi->csp.security = set_auth;
0247
0248 flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
0249
0250
0251 vvl_info = (u32 *)&flogi->vvl[0];
0252
0253
0254 flogi->csp.npiv_supp = 1;
0255 vvl_info[0] = cpu_to_be32(FLOGI_VVL_BRCD);
0256
0257 return sizeof(struct fc_logi_s);
0258 }
0259
0260 u16
0261 fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
0262 __be16 ox_id, wwn_t port_name, wwn_t node_name,
0263 u16 pdu_size, u16 local_bb_credits, u8 bb_scn)
0264 {
0265 u32 d_id = 0;
0266 u16 bbscn_rxsz = (bb_scn << 12) | pdu_size;
0267
0268 memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
0269 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0270
0271 flogi->els_cmd.els_code = FC_ELS_ACC;
0272 flogi->class3.rxsz = cpu_to_be16(pdu_size);
0273 flogi->csp.rxsz = cpu_to_be16(bbscn_rxsz);
0274 flogi->port_name = port_name;
0275 flogi->node_name = node_name;
0276
0277 flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
0278
0279 return sizeof(struct fc_logi_s);
0280 }
0281
0282 u16
0283 fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
0284 u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size)
0285 {
0286 u32 d_id = bfa_hton3b(FC_FABRIC_PORT);
0287
0288 memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
0289
0290 flogi->els_cmd.els_code = FC_ELS_FDISC;
0291 fc_els_req_build(fchs, d_id, s_id, ox_id);
0292
0293 flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
0294 flogi->port_name = port_name;
0295 flogi->node_name = node_name;
0296
0297 return sizeof(struct fc_logi_s);
0298 }
0299
0300 u16
0301 fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0302 u16 ox_id, wwn_t port_name, wwn_t node_name,
0303 u16 pdu_size, u16 bb_cr)
0304 {
0305 return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
0306 node_name, pdu_size, bb_cr, FC_ELS_PLOGI);
0307 }
0308
0309 u16
0310 fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0311 u16 ox_id, wwn_t port_name, wwn_t node_name,
0312 u16 pdu_size, u16 bb_cr)
0313 {
0314 return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
0315 node_name, pdu_size, bb_cr, FC_ELS_ACC);
0316 }
0317
0318 enum fc_parse_status
0319 fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
0320 {
0321 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
0322 struct fc_logi_s *plogi;
0323 struct fc_ls_rjt_s *ls_rjt;
0324
0325 switch (els_cmd->els_code) {
0326 case FC_ELS_LS_RJT:
0327 ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1);
0328 if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
0329 return FC_PARSE_BUSY;
0330 else
0331 return FC_PARSE_FAILURE;
0332 case FC_ELS_ACC:
0333 plogi = (struct fc_logi_s *) (fchs + 1);
0334 if (len < sizeof(struct fc_logi_s))
0335 return FC_PARSE_FAILURE;
0336
0337 if (!wwn_is_equal(plogi->port_name, port_name))
0338 return FC_PARSE_FAILURE;
0339
0340 if (!plogi->class3.class_valid)
0341 return FC_PARSE_FAILURE;
0342
0343 if (be16_to_cpu(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
0344 return FC_PARSE_FAILURE;
0345
0346 return FC_PARSE_OK;
0347 default:
0348 return FC_PARSE_FAILURE;
0349 }
0350 }
0351
0352 enum fc_parse_status
0353 fc_plogi_parse(struct fchs_s *fchs)
0354 {
0355 struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1);
0356
0357 if (plogi->class3.class_valid != 1)
0358 return FC_PARSE_FAILURE;
0359
0360 if ((be16_to_cpu(plogi->class3.rxsz) < FC_MIN_PDUSZ)
0361 || (be16_to_cpu(plogi->class3.rxsz) > FC_MAX_PDUSZ)
0362 || (plogi->class3.rxsz == 0))
0363 return FC_PARSE_FAILURE;
0364
0365 return FC_PARSE_OK;
0366 }
0367
0368 u16
0369 fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0370 u16 ox_id)
0371 {
0372 struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
0373
0374 fc_els_req_build(fchs, d_id, s_id, ox_id);
0375 memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
0376
0377 prli->command = FC_ELS_PRLI;
0378 prli->parampage.servparams.initiator = 1;
0379 prli->parampage.servparams.retry = 1;
0380 prli->parampage.servparams.rec_support = 1;
0381 prli->parampage.servparams.task_retry_id = 0;
0382 prli->parampage.servparams.confirm = 1;
0383
0384 return sizeof(struct fc_prli_s);
0385 }
0386
0387 u16
0388 fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0389 __be16 ox_id, enum bfa_lport_role role)
0390 {
0391 struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
0392
0393 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0394 memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
0395
0396 prli->command = FC_ELS_ACC;
0397
0398 prli->parampage.servparams.initiator = 1;
0399
0400 prli->parampage.rspcode = FC_PRLI_ACC_XQTD;
0401
0402 return sizeof(struct fc_prli_s);
0403 }
0404
0405 enum fc_parse_status
0406 fc_prli_rsp_parse(struct fc_prli_s *prli, int len)
0407 {
0408 if (len < sizeof(struct fc_prli_s))
0409 return FC_PARSE_FAILURE;
0410
0411 if (prli->command != FC_ELS_ACC)
0412 return FC_PARSE_FAILURE;
0413
0414 if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD)
0415 && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG))
0416 return FC_PARSE_FAILURE;
0417
0418 if (prli->parampage.servparams.target != 1)
0419 return FC_PARSE_FAILURE;
0420
0421 return FC_PARSE_OK;
0422 }
0423
0424 enum fc_parse_status
0425 fc_prli_parse(struct fc_prli_s *prli)
0426 {
0427 if (prli->parampage.type != FC_TYPE_FCP)
0428 return FC_PARSE_FAILURE;
0429
0430 if (!prli->parampage.imagepair)
0431 return FC_PARSE_FAILURE;
0432
0433 if (!prli->parampage.servparams.initiator)
0434 return FC_PARSE_FAILURE;
0435
0436 return FC_PARSE_OK;
0437 }
0438
0439 u16
0440 fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id,
0441 u16 ox_id, wwn_t port_name)
0442 {
0443 fc_els_req_build(fchs, d_id, s_id, ox_id);
0444
0445 memset(logo, '\0', sizeof(struct fc_logo_s));
0446 logo->els_cmd.els_code = FC_ELS_LOGO;
0447 logo->nport_id = (s_id);
0448 logo->orig_port_name = port_name;
0449
0450 return sizeof(struct fc_logo_s);
0451 }
0452
0453 static u16
0454 fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
0455 u32 s_id, __be16 ox_id, wwn_t port_name,
0456 wwn_t node_name, u8 els_code)
0457 {
0458 memset(adisc, '\0', sizeof(struct fc_adisc_s));
0459
0460 adisc->els_cmd.els_code = els_code;
0461
0462 if (els_code == FC_ELS_ADISC)
0463 fc_els_req_build(fchs, d_id, s_id, ox_id);
0464 else
0465 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0466
0467 adisc->orig_HA = 0;
0468 adisc->orig_port_name = port_name;
0469 adisc->orig_node_name = node_name;
0470 adisc->nport_id = (s_id);
0471
0472 return sizeof(struct fc_adisc_s);
0473 }
0474
0475 u16
0476 fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
0477 u32 s_id, __be16 ox_id, wwn_t port_name, wwn_t node_name)
0478 {
0479 return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
0480 node_name, FC_ELS_ADISC);
0481 }
0482
0483 u16
0484 fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
0485 u32 s_id, __be16 ox_id, wwn_t port_name,
0486 wwn_t node_name)
0487 {
0488 return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
0489 node_name, FC_ELS_ACC);
0490 }
0491
0492 enum fc_parse_status
0493 fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name,
0494 wwn_t node_name)
0495 {
0496
0497 if (len < sizeof(struct fc_adisc_s))
0498 return FC_PARSE_FAILURE;
0499
0500 if (adisc->els_cmd.els_code != FC_ELS_ACC)
0501 return FC_PARSE_FAILURE;
0502
0503 if (!wwn_is_equal(adisc->orig_port_name, port_name))
0504 return FC_PARSE_FAILURE;
0505
0506 return FC_PARSE_OK;
0507 }
0508
0509 enum fc_parse_status
0510 fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap, wwn_t node_name,
0511 wwn_t port_name)
0512 {
0513 struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld;
0514
0515 if (adisc->els_cmd.els_code != FC_ELS_ACC)
0516 return FC_PARSE_FAILURE;
0517
0518 if ((adisc->nport_id == (host_dap))
0519 && wwn_is_equal(adisc->orig_port_name, port_name)
0520 && wwn_is_equal(adisc->orig_node_name, node_name))
0521 return FC_PARSE_OK;
0522
0523 return FC_PARSE_FAILURE;
0524 }
0525
0526 enum fc_parse_status
0527 fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name)
0528 {
0529 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
0530
0531 if (pdisc->class3.class_valid != 1)
0532 return FC_PARSE_FAILURE;
0533
0534 if ((be16_to_cpu(pdisc->class3.rxsz) <
0535 (FC_MIN_PDUSZ - sizeof(struct fchs_s)))
0536 || (pdisc->class3.rxsz == 0))
0537 return FC_PARSE_FAILURE;
0538
0539 if (!wwn_is_equal(pdisc->port_name, port_name))
0540 return FC_PARSE_FAILURE;
0541
0542 if (!wwn_is_equal(pdisc->node_name, node_name))
0543 return FC_PARSE_FAILURE;
0544
0545 return FC_PARSE_OK;
0546 }
0547
0548 u16
0549 fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
0550 {
0551 memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s));
0552 fchs->cat_info = FC_CAT_ABTS;
0553 fchs->d_id = (d_id);
0554 fchs->s_id = (s_id);
0555 fchs->ox_id = cpu_to_be16(ox_id);
0556
0557 return sizeof(struct fchs_s);
0558 }
0559
0560 enum fc_parse_status
0561 fc_abts_rsp_parse(struct fchs_s *fchs, int len)
0562 {
0563 if ((fchs->cat_info == FC_CAT_BA_ACC)
0564 || (fchs->cat_info == FC_CAT_BA_RJT))
0565 return FC_PARSE_OK;
0566
0567 return FC_PARSE_FAILURE;
0568 }
0569
0570 u16
0571 fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id,
0572 u16 ox_id, u16 rrq_oxid)
0573 {
0574 fc_els_req_build(fchs, d_id, s_id, ox_id);
0575
0576
0577
0578
0579 memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s));
0580 rrq->s_id = (s_id);
0581 rrq->ox_id = cpu_to_be16(rrq_oxid);
0582 rrq->rx_id = FC_RXID_ANY;
0583
0584 return sizeof(struct fc_rrq_s);
0585 }
0586
0587 u16
0588 fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
0589 __be16 ox_id)
0590 {
0591 struct fc_els_cmd_s *acc = pld;
0592
0593 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0594
0595 memset(acc, 0, sizeof(struct fc_els_cmd_s));
0596 acc->els_code = FC_ELS_ACC;
0597
0598 return sizeof(struct fc_els_cmd_s);
0599 }
0600
0601 u16
0602 fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
0603 u32 s_id, __be16 ox_id, u8 reason_code,
0604 u8 reason_code_expl)
0605 {
0606 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0607 memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s));
0608
0609 ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT;
0610 ls_rjt->reason_code = reason_code;
0611 ls_rjt->reason_code_expl = reason_code_expl;
0612 ls_rjt->vendor_unique = 0x00;
0613
0614 return sizeof(struct fc_ls_rjt_s);
0615 }
0616
0617 u16
0618 fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
0619 u32 s_id, __be16 ox_id, u16 rx_id)
0620 {
0621 fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
0622
0623 memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s));
0624
0625 fchs->rx_id = rx_id;
0626
0627 ba_acc->ox_id = fchs->ox_id;
0628 ba_acc->rx_id = fchs->rx_id;
0629
0630 return sizeof(struct fc_ba_acc_s);
0631 }
0632
0633 u16
0634 fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id,
0635 u32 s_id, __be16 ox_id)
0636 {
0637 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0638 memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
0639 els_cmd->els_code = FC_ELS_ACC;
0640
0641 return sizeof(struct fc_els_cmd_s);
0642 }
0643
0644 int
0645 fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code)
0646 {
0647 int num_pages = 0;
0648 struct fc_prlo_s *prlo;
0649 struct fc_tprlo_s *tprlo;
0650
0651 if (els_code == FC_ELS_PRLO) {
0652 prlo = (struct fc_prlo_s *) (fc_frame + 1);
0653 num_pages = (be16_to_cpu(prlo->payload_len) - 4) / 16;
0654 } else {
0655 tprlo = (struct fc_tprlo_s *) (fc_frame + 1);
0656 num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16;
0657 }
0658 return num_pages;
0659 }
0660
0661 u16
0662 fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
0663 u32 d_id, u32 s_id, __be16 ox_id, int num_pages)
0664 {
0665 int page;
0666
0667 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0668
0669 memset(tprlo_acc, 0, (num_pages * 16) + 4);
0670 tprlo_acc->command = FC_ELS_ACC;
0671
0672 tprlo_acc->page_len = 0x10;
0673 tprlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
0674
0675 for (page = 0; page < num_pages; page++) {
0676 tprlo_acc->tprlo_acc_params[page].opa_valid = 0;
0677 tprlo_acc->tprlo_acc_params[page].rpa_valid = 0;
0678 tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
0679 tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0;
0680 tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0;
0681 }
0682 return be16_to_cpu(tprlo_acc->payload_len);
0683 }
0684
0685 u16
0686 fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id,
0687 u32 s_id, __be16 ox_id, int num_pages)
0688 {
0689 int page;
0690
0691 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0692
0693 memset(prlo_acc, 0, (num_pages * 16) + 4);
0694 prlo_acc->command = FC_ELS_ACC;
0695 prlo_acc->page_len = 0x10;
0696 prlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
0697
0698 for (page = 0; page < num_pages; page++) {
0699 prlo_acc->prlo_acc_params[page].opa_valid = 0;
0700 prlo_acc->prlo_acc_params[page].rpa_valid = 0;
0701 prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
0702 prlo_acc->prlo_acc_params[page].orig_process_assc = 0;
0703 prlo_acc->prlo_acc_params[page].resp_process_assc = 0;
0704 }
0705
0706 return be16_to_cpu(prlo_acc->payload_len);
0707 }
0708
0709 u16
0710 fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id,
0711 u32 s_id, u16 ox_id, u32 data_format)
0712 {
0713 fc_els_req_build(fchs, d_id, s_id, ox_id);
0714
0715 memset(rnid, 0, sizeof(struct fc_rnid_cmd_s));
0716
0717 rnid->els_cmd.els_code = FC_ELS_RNID;
0718 rnid->node_id_data_format = data_format;
0719
0720 return sizeof(struct fc_rnid_cmd_s);
0721 }
0722
0723 u16
0724 fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id,
0725 u32 s_id, __be16 ox_id, u32 data_format,
0726 struct fc_rnid_common_id_data_s *common_id_data,
0727 struct fc_rnid_general_topology_data_s *gen_topo_data)
0728 {
0729 memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s));
0730
0731 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0732
0733 rnid_acc->els_cmd.els_code = FC_ELS_ACC;
0734 rnid_acc->node_id_data_format = data_format;
0735 rnid_acc->common_id_data_length =
0736 sizeof(struct fc_rnid_common_id_data_s);
0737 rnid_acc->common_id_data = *common_id_data;
0738
0739 if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
0740 rnid_acc->specific_id_data_length =
0741 sizeof(struct fc_rnid_general_topology_data_s);
0742 rnid_acc->gen_topology_data = *gen_topo_data;
0743 return sizeof(struct fc_rnid_acc_s);
0744 } else {
0745 return sizeof(struct fc_rnid_acc_s) -
0746 sizeof(struct fc_rnid_general_topology_data_s);
0747 }
0748
0749 }
0750
0751 u16
0752 fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id,
0753 u32 s_id, u16 ox_id)
0754 {
0755 fc_els_req_build(fchs, d_id, s_id, ox_id);
0756
0757 memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
0758
0759 rpsc->els_cmd.els_code = FC_ELS_RPSC;
0760 return sizeof(struct fc_rpsc_cmd_s);
0761 }
0762
0763 u16
0764 fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id,
0765 u32 s_id, u32 *pid_list, u16 npids)
0766 {
0767 u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_hton3b(d_id));
0768 int i = 0;
0769
0770 fc_els_req_build(fchs, bfa_hton3b(dctlr_id), s_id, 0);
0771
0772 memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
0773
0774 rpsc2->els_cmd.els_code = FC_ELS_RPSC;
0775 rpsc2->token = cpu_to_be32(FC_BRCD_TOKEN);
0776 rpsc2->num_pids = cpu_to_be16(npids);
0777 for (i = 0; i < npids; i++)
0778 rpsc2->pid_list[i].pid = pid_list[i];
0779
0780 return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) * (sizeof(u32)));
0781 }
0782
0783 u16
0784 fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
0785 u32 d_id, u32 s_id, __be16 ox_id,
0786 struct fc_rpsc_speed_info_s *oper_speed)
0787 {
0788 memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
0789
0790 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
0791
0792 rpsc_acc->command = FC_ELS_ACC;
0793 rpsc_acc->num_entries = cpu_to_be16(1);
0794
0795 rpsc_acc->speed_info[0].port_speed_cap =
0796 cpu_to_be16(oper_speed->port_speed_cap);
0797
0798 rpsc_acc->speed_info[0].port_op_speed =
0799 cpu_to_be16(oper_speed->port_op_speed);
0800
0801 return sizeof(struct fc_rpsc_acc_s);
0802 }
0803
0804 u16
0805 fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
0806 wwn_t port_name, wwn_t node_name, u16 pdu_size)
0807 {
0808 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
0809
0810 memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s));
0811
0812 pdisc->els_cmd.els_code = FC_ELS_PDISC;
0813 fc_els_req_build(fchs, d_id, s_id, ox_id);
0814
0815 pdisc->csp.rxsz = pdisc->class3.rxsz = cpu_to_be16(pdu_size);
0816 pdisc->port_name = port_name;
0817 pdisc->node_name = node_name;
0818
0819 return sizeof(struct fc_logi_s);
0820 }
0821
0822 u16
0823 fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
0824 {
0825 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
0826
0827 if (len < sizeof(struct fc_logi_s))
0828 return FC_PARSE_LEN_INVAL;
0829
0830 if (pdisc->els_cmd.els_code != FC_ELS_ACC)
0831 return FC_PARSE_ACC_INVAL;
0832
0833 if (!wwn_is_equal(pdisc->port_name, port_name))
0834 return FC_PARSE_PWWN_NOT_EQUAL;
0835
0836 if (!pdisc->class3.class_valid)
0837 return FC_PARSE_NWWN_NOT_EQUAL;
0838
0839 if (be16_to_cpu(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
0840 return FC_PARSE_RXSZ_INVAL;
0841
0842 return FC_PARSE_OK;
0843 }
0844
0845 u16
0846 fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
0847 int num_pages)
0848 {
0849 struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1);
0850 int page;
0851
0852 fc_els_req_build(fchs, d_id, s_id, ox_id);
0853 memset(prlo, 0, (num_pages * 16) + 4);
0854 prlo->command = FC_ELS_PRLO;
0855 prlo->page_len = 0x10;
0856 prlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
0857
0858 for (page = 0; page < num_pages; page++) {
0859 prlo->prlo_params[page].type = FC_TYPE_FCP;
0860 prlo->prlo_params[page].opa_valid = 0;
0861 prlo->prlo_params[page].rpa_valid = 0;
0862 prlo->prlo_params[page].orig_process_assc = 0;
0863 prlo->prlo_params[page].resp_process_assc = 0;
0864 }
0865
0866 return be16_to_cpu(prlo->payload_len);
0867 }
0868
0869 u16
0870 fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
0871 int num_pages, enum fc_tprlo_type tprlo_type, u32 tpr_id)
0872 {
0873 struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1);
0874 int page;
0875
0876 fc_els_req_build(fchs, d_id, s_id, ox_id);
0877 memset(tprlo, 0, (num_pages * 16) + 4);
0878 tprlo->command = FC_ELS_TPRLO;
0879 tprlo->page_len = 0x10;
0880 tprlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
0881
0882 for (page = 0; page < num_pages; page++) {
0883 tprlo->tprlo_params[page].type = FC_TYPE_FCP;
0884 tprlo->tprlo_params[page].opa_valid = 0;
0885 tprlo->tprlo_params[page].rpa_valid = 0;
0886 tprlo->tprlo_params[page].orig_process_assc = 0;
0887 tprlo->tprlo_params[page].resp_process_assc = 0;
0888 if (tprlo_type == FC_GLOBAL_LOGO) {
0889 tprlo->tprlo_params[page].global_process_logout = 1;
0890 } else if (tprlo_type == FC_TPR_LOGO) {
0891 tprlo->tprlo_params[page].tpo_nport_valid = 1;
0892 tprlo->tprlo_params[page].tpo_nport_id = (tpr_id);
0893 }
0894 }
0895
0896 return be16_to_cpu(tprlo->payload_len);
0897 }
0898
0899 u16
0900 fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id,
0901 u32 reason_code, u32 reason_expl)
0902 {
0903 struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1);
0904
0905 fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
0906
0907 fchs->cat_info = FC_CAT_BA_RJT;
0908 ba_rjt->reason_code = reason_code;
0909 ba_rjt->reason_expl = reason_expl;
0910 return sizeof(struct fc_ba_rjt_s);
0911 }
0912
0913 static void
0914 fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
0915 {
0916 memset(cthdr, 0, sizeof(struct ct_hdr_s));
0917 cthdr->rev_id = CT_GS3_REVISION;
0918 cthdr->gs_type = CT_GSTYPE_DIRSERVICE;
0919 cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER;
0920 cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
0921 }
0922
0923 static void
0924 fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
0925 {
0926 memset(cthdr, 0, sizeof(struct ct_hdr_s));
0927 cthdr->rev_id = CT_GS3_REVISION;
0928 cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
0929 cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER;
0930 cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
0931 }
0932
0933 static void
0934 fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code,
0935 u8 sub_type)
0936 {
0937 memset(cthdr, 0, sizeof(struct ct_hdr_s));
0938 cthdr->rev_id = CT_GS3_REVISION;
0939 cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
0940 cthdr->gs_sub_type = sub_type;
0941 cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
0942 }
0943
0944 u16
0945 fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
0946 wwn_t port_name)
0947 {
0948 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
0949 struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1);
0950 u32 d_id = bfa_hton3b(FC_NAME_SERVER);
0951
0952 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
0953 fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
0954
0955 memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
0956 gidpn->port_name = port_name;
0957 return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s);
0958 }
0959
0960 u16
0961 fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
0962 u32 port_id)
0963 {
0964 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
0965 fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1);
0966 u32 d_id = bfa_hton3b(FC_NAME_SERVER);
0967
0968 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
0969 fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
0970
0971 memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
0972 gpnid->dap = port_id;
0973 return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s);
0974 }
0975
0976 u16
0977 fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
0978 u32 port_id)
0979 {
0980 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
0981 fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1);
0982 u32 d_id = bfa_hton3b(FC_NAME_SERVER);
0983
0984 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
0985 fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
0986
0987 memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
0988 gnnid->dap = port_id;
0989 return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s);
0990 }
0991
0992 u16
0993 fc_ct_rsp_parse(struct ct_hdr_s *cthdr)
0994 {
0995 if (be16_to_cpu(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) {
0996 if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY)
0997 return FC_PARSE_BUSY;
0998 else
0999 return FC_PARSE_FAILURE;
1000 }
1001
1002 return FC_PARSE_OK;
1003 }
1004
1005 u16
1006 fc_gs_rjt_build(struct fchs_s *fchs, struct ct_hdr_s *cthdr,
1007 u32 d_id, u32 s_id, u16 ox_id, u8 reason_code,
1008 u8 reason_code_expl)
1009 {
1010 fc_gsresp_fchdr_build(fchs, d_id, s_id, ox_id);
1011
1012 cthdr->cmd_rsp_code = cpu_to_be16(CT_RSP_REJECT);
1013 cthdr->rev_id = CT_GS3_REVISION;
1014
1015 cthdr->reason_code = reason_code;
1016 cthdr->exp_code = reason_code_expl;
1017 return sizeof(struct ct_hdr_s);
1018 }
1019
1020 u16
1021 fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
1022 u8 set_br_reg, u32 s_id, u16 ox_id)
1023 {
1024 u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
1025
1026 fc_els_req_build(fchs, d_id, s_id, ox_id);
1027
1028 memset(scr, 0, sizeof(struct fc_scr_s));
1029 scr->command = FC_ELS_SCR;
1030 scr->reg_func = FC_SCR_REG_FUNC_FULL;
1031 if (set_br_reg)
1032 scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE;
1033
1034 return sizeof(struct fc_scr_s);
1035 }
1036
1037 u16
1038 fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn,
1039 u32 s_id, u16 ox_id)
1040 {
1041 u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
1042 u16 payldlen;
1043
1044 fc_els_req_build(fchs, d_id, s_id, ox_id);
1045 rscn->command = FC_ELS_RSCN;
1046 rscn->pagelen = sizeof(rscn->event[0]);
1047
1048 payldlen = sizeof(u32) + rscn->pagelen;
1049 rscn->payldlen = cpu_to_be16(payldlen);
1050
1051 rscn->event[0].format = FC_RSCN_FORMAT_PORTID;
1052 rscn->event[0].portid = s_id;
1053
1054 return sizeof(struct fc_rscn_pl_s);
1055 }
1056
1057 u16
1058 fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1059 enum bfa_lport_role roles)
1060 {
1061 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1062 struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
1063 u32 type_value, d_id = bfa_hton3b(FC_NAME_SERVER);
1064 u8 index;
1065
1066 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1067 fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
1068
1069 memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
1070
1071 rftid->dap = s_id;
1072
1073
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
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
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
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
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
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 }