1349 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.4 * Copyright (c) 2014- QLogic Corporation.5 * All rights reserved6 * www.qlogic.com7 *8 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.9 */10/*11 * fcbuild.c - FC link service frame building and parsing routines12 */13 14#include "bfad_drv.h"15#include "bfa_fcbuild.h"16 17/*18 * static build functions19 */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 34void35fcbuild_init(void)36{37 /*38 * fc_els_req_tmpl39 */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_tmpl50 */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_tmpl61 */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_tmpl69 */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_tmpl80 */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_tmpl87 */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_tmpl104 */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_tmpl114 */115 rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ;116 117 /*118 * fcp_struct fchs_s mpl119 */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 void130fc_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 request147 * no need to set rx_id for response148 */149}150 151static void152fc_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 167void168fc_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 void177fc_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 void186fc_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 u16195fc_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 else211 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 222u16223fc_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 Common241 * 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 260u16261fc_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 282u16283fc_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 300u16301fc_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 309u16310fc_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_status319fc_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 else331 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_status353fc_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 368u16369fc_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 387u16388fc_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_status406fc_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_status425fc_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 439u16440fc_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 u16454fc_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 else465 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 475u16476fc_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 483u16484fc_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_status493fc_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_status510fc_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_status527fc_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 548u16549fc_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_status561fc_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 570u16571fc_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 payload578 */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 587u16588fc_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 601u16602fc_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 617u16618fc_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 633u16634fc_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 644int645fc_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 661u16662fc_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 685u16686fc_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 709u16710fc_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 723u16724fc_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 751u16752fc_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 763u16764fc_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 783u16784fc_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 804u16805fc_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 822u16823fc_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 845u16846fc_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 869u16870fc_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 899u16900fc_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 void914fc_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 void924fc_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 void934fc_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 944u16945fc_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 960u16961fc_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 976u16977fc_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 992u16993fc_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 else999 return FC_PARSE_FAILURE;1000 }1001 1002 return FC_PARSE_OK;1003}1004 1005u161006fc_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 1020u161021fc_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 1037u161038fc_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 struct_size(rscn, event, 1);1055}1056 1057u161058fc_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 1081u161082fc_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 1101u161102fc_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 1121u161122fc_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 strscpy(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 1143u161144fc_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 strscpy(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 1164u161165fc_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 1184u161185fc_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 1202u161203fc_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 1220u161221fc_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 1239u161240fc_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 1257u161258fc_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 */1276u161277fc_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 bitmask1292 */1293void1294fc_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 size1302 */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 Request1312 */1313u161314fc_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) Request1332 */1333u161334fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)1335{1336 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;1337 fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1);1338 u32 d_id = bfa_hton3b(FC_MGMT_SERVER);1339 1340 fc_gs_fchdr_build(fchs, d_id, s_id, 0);1341 fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD,1342 CT_GSSUBTYPE_CFGSERVER);1343 1344 memset(gfn, 0, sizeof(fcgs_gfn_req_t));1345 gfn->wwn = wwn;1346 1347 return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t);1348}1349