1/* 2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. 3 * All rights reserved 4 * www.brocade.com 5 * 6 * Linux driver for Brocade Fibre Channel Host Bus Adapter. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License (GPL) Version 2 as 10 * published by the Free Software Foundation 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 */ 17/* 18 * fcbuild.c - FC link service frame building and parsing routines 19 */ 20 21#include <bfa_os_inc.h> 22#include "fcbuild.h" 23 24/* 25 * static build functions 26 */ 27static void fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, 28 u16 ox_id); 29static void fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, 30 u16 ox_id); 31static struct fchs_s fc_els_req_tmpl; 32static struct fchs_s fc_els_rsp_tmpl; 33static struct fchs_s fc_bls_req_tmpl; 34static struct fchs_s fc_bls_rsp_tmpl; 35static struct fc_ba_acc_s ba_acc_tmpl; 36static struct fc_logi_s plogi_tmpl; 37static struct fc_prli_s prli_tmpl; 38static struct fc_rrq_s rrq_tmpl; 39static struct fchs_s fcp_fchs_tmpl; 40 41void 42fcbuild_init(void) 43{ 44 /* 45 * fc_els_req_tmpl 46 */ 47 fc_els_req_tmpl.routing = FC_RTG_EXT_LINK; 48 fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST; 49 fc_els_req_tmpl.type = FC_TYPE_ELS; 50 fc_els_req_tmpl.f_ctl = 51 bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ | 52 FCTL_SI_XFER); 53 fc_els_req_tmpl.rx_id = FC_RXID_ANY; 54 55 /* 56 * fc_els_rsp_tmpl 57 */ 58 fc_els_rsp_tmpl.routing = FC_RTG_EXT_LINK; 59 fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY; 60 fc_els_rsp_tmpl.type = FC_TYPE_ELS; 61 fc_els_rsp_tmpl.f_ctl = 62 bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH | 63 FCTL_END_SEQ | FCTL_SI_XFER); 64 fc_els_rsp_tmpl.rx_id = FC_RXID_ANY; 65 66 /* 67 * fc_bls_req_tmpl 68 */ 69 fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK; 70 fc_bls_req_tmpl.type = FC_TYPE_BLS; 71 fc_bls_req_tmpl.f_ctl = bfa_os_hton3b(FCTL_END_SEQ | FCTL_SI_XFER); 72 fc_bls_req_tmpl.rx_id = FC_RXID_ANY; 73 74 /* 75 * fc_bls_rsp_tmpl 76 */ 77 fc_bls_rsp_tmpl.routing = FC_RTG_BASIC_LINK; 78 fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC; 79 fc_bls_rsp_tmpl.type = FC_TYPE_BLS; 80 fc_bls_rsp_tmpl.f_ctl = 81 bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH | 82 FCTL_END_SEQ | FCTL_SI_XFER); 83 fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY; 84 85 /* 86 * ba_acc_tmpl 87 */ 88 ba_acc_tmpl.seq_id_valid = 0; 89 ba_acc_tmpl.low_seq_cnt = 0; 90 ba_acc_tmpl.high_seq_cnt = 0xFFFF; 91 92 /* 93 * plogi_tmpl 94 */ 95 plogi_tmpl.csp.verhi = FC_PH_VER_PH_3; 96 plogi_tmpl.csp.verlo = FC_PH_VER_4_3; 97 plogi_tmpl.csp.bbcred = bfa_os_htons(0x0004); 98 plogi_tmpl.csp.ciro = 0x1; 99 plogi_tmpl.csp.cisc = 0x0; 100 plogi_tmpl.csp.altbbcred = 0x0; 101 plogi_tmpl.csp.conseq = bfa_os_htons(0x00FF); 102 plogi_tmpl.csp.ro_bitmap = bfa_os_htons(0x0002); 103 plogi_tmpl.csp.e_d_tov = bfa_os_htonl(2000); 104 105 plogi_tmpl.class3.class_valid = 1; 106 plogi_tmpl.class3.sequential = 1; 107 plogi_tmpl.class3.conseq = 0xFF; 108 plogi_tmpl.class3.ospx = 1; 109 110 /* 111 * prli_tmpl 112 */ 113 prli_tmpl.command = FC_ELS_PRLI; 114 prli_tmpl.pglen = 0x10; 115 prli_tmpl.pagebytes = bfa_os_htons(0x0014); 116 prli_tmpl.parampage.type = FC_TYPE_FCP; 117 prli_tmpl.parampage.imagepair = 1; 118 prli_tmpl.parampage.servparams.rxrdisab = 1; 119 120 /* 121 * rrq_tmpl 122 */ 123 rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ; 124 125 /* 126 * fcp_fchs_tmpl 127 */ 128 fcp_fchs_tmpl.routing = FC_RTG_FC4_DEV_DATA; 129 fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD; 130 fcp_fchs_tmpl.type = FC_TYPE_FCP; 131 fcp_fchs_tmpl.f_ctl = 132 bfa_os_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER); 133 fcp_fchs_tmpl.seq_id = 1; 134 fcp_fchs_tmpl.rx_id = FC_RXID_ANY; 135} 136 137static void 138fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, 139 u32 ox_id) 140{ 141 bfa_os_memset(fchs, 0, sizeof(struct fchs_s)); 142 143 fchs->routing = FC_RTG_FC4_DEV_DATA; 144 fchs->cat_info = FC_CAT_UNSOLICIT_CTRL; 145 fchs->type = FC_TYPE_SERVICES; 146 fchs->f_ctl = 147 bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ | 148 FCTL_SI_XFER); 149 fchs->rx_id = FC_RXID_ANY; 150 fchs->d_id = (d_id); 151 fchs->s_id = (s_id); 152 fchs->ox_id = bfa_os_htons(ox_id); 153 154 /** 155 * @todo no need to set ox_id for request 156 * no need to set rx_id for response 157 */ 158} 159 160void 161fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, 162 u16 ox_id) 163{ 164 bfa_os_memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s)); 165 fchs->d_id = (d_id); 166 fchs->s_id = (s_id); 167 fchs->ox_id = bfa_os_htons(ox_id); 168} 169 170static void 171fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, 172 u16 ox_id) 173{ 174 bfa_os_memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s)); 175 fchs->d_id = d_id; 176 fchs->s_id = s_id; 177 fchs->ox_id = ox_id; 178} 179 180enum fc_parse_status 181fc_els_rsp_parse(struct fchs_s *fchs, int len) 182{ 183 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 184 struct fc_ls_rjt_s *ls_rjt = (struct fc_ls_rjt_s *) els_cmd; 185 186 len = len; 187 188 switch (els_cmd->els_code) { 189 case FC_ELS_LS_RJT: 190 if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY) 191 return FC_PARSE_BUSY; 192 else 193 return FC_PARSE_FAILURE; 194 195 case FC_ELS_ACC: 196 return FC_PARSE_OK; 197 } 198 return FC_PARSE_OK; 199} 200 201static void 202fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, 203 u16 ox_id) 204{ 205 bfa_os_memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s)); 206 fchs->d_id = d_id; 207 fchs->s_id = s_id; 208 fchs->ox_id = ox_id; 209} 210 211static u16 212fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 213 u16 ox_id, wwn_t port_name, wwn_t node_name, 214 u16 pdu_size, u8 els_code) 215{ 216 struct fc_logi_s *plogi = (struct fc_logi_s *) (pld); 217 218 bfa_os_memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 219 220 plogi->els_cmd.els_code = els_code; 221 if (els_code == FC_ELS_PLOGI) 222 fc_els_req_build(fchs, d_id, s_id, ox_id); 223 else 224 fc_els_rsp_build(fchs, d_id, s_id, ox_id); 225 226 plogi->csp.rxsz = plogi->class3.rxsz = bfa_os_htons(pdu_size); 227 228 bfa_os_memcpy(&plogi->port_name, &port_name, sizeof(wwn_t)); 229 bfa_os_memcpy(&plogi->node_name, &node_name, sizeof(wwn_t)); 230 231 return sizeof(struct fc_logi_s); 232} 233 234u16 235fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, 236 u16 ox_id, wwn_t port_name, wwn_t node_name, 237 u16 pdu_size, u8 set_npiv, u8 set_auth, 238 u16 local_bb_credits) 239{ 240 u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT); 241 u32 *vvl_info; 242 243 bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 244 245 flogi->els_cmd.els_code = FC_ELS_FLOGI; 246 fc_els_req_build(fchs, d_id, s_id, ox_id); 247 248 flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size); 249 flogi->port_name = port_name; 250 flogi->node_name = node_name; 251 252 /* 253 * Set the NPIV Capability Bit ( word 1, bit 31) of Common 254 * Service Parameters. 255 */ 256 flogi->csp.ciro = set_npiv; 257 258 /* set AUTH capability */ 259 flogi->csp.security = set_auth; 260 261 flogi->csp.bbcred = bfa_os_htons(local_bb_credits); 262 263 /* Set brcd token in VVL */ 264 vvl_info = (u32 *)&flogi->vvl[0]; 265 266 /* set the flag to indicate the presence of VVL */ 267 flogi->csp.npiv_supp = 1; /* @todo. field name is not correct */ 268 vvl_info[0] = bfa_os_htonl(FLOGI_VVL_BRCD); 269 270 return sizeof(struct fc_logi_s); 271} 272 273u16 274fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, 275 u16 ox_id, wwn_t port_name, wwn_t node_name, 276 u16 pdu_size, u16 local_bb_credits) 277{ 278 u32 d_id = 0; 279 280 bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 281 fc_els_rsp_build(fchs, d_id, s_id, ox_id); 282 283 flogi->els_cmd.els_code = FC_ELS_ACC; 284 flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size); 285 flogi->port_name = port_name; 286 flogi->node_name = node_name; 287 288 flogi->csp.bbcred = bfa_os_htons(local_bb_credits); 289 290 return sizeof(struct fc_logi_s); 291} 292 293u16 294fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, 295 u16 ox_id, wwn_t port_name, wwn_t node_name, 296 u16 pdu_size) 297{ 298 u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT); 299 300 bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 301 302 flogi->els_cmd.els_code = FC_ELS_FDISC; 303 fc_els_req_build(fchs, d_id, s_id, ox_id); 304 305 flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size); 306 flogi->port_name = port_name; 307 flogi->node_name = node_name; 308 309 return sizeof(struct fc_logi_s); 310} 311 312u16 313fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 314 u16 ox_id, wwn_t port_name, wwn_t node_name, 315 u16 pdu_size) 316{ 317 return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name, 318 node_name, pdu_size, FC_ELS_PLOGI); 319} 320 321u16 322fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 323 u16 ox_id, wwn_t port_name, wwn_t node_name, 324 u16 pdu_size) 325{ 326 return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name, 327 node_name, pdu_size, FC_ELS_ACC); 328} 329 330enum fc_parse_status 331fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) 332{ 333 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 334 struct fc_logi_s *plogi; 335 struct fc_ls_rjt_s *ls_rjt; 336 337 switch (els_cmd->els_code) { 338 case FC_ELS_LS_RJT: 339 ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1); 340 if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY) 341 return FC_PARSE_BUSY; 342 else 343 return FC_PARSE_FAILURE; 344 case FC_ELS_ACC: 345 plogi = (struct fc_logi_s *) (fchs + 1); 346 if (len < sizeof(struct fc_logi_s)) 347 return FC_PARSE_FAILURE; 348 349 if (!wwn_is_equal(plogi->port_name, port_name)) 350 return FC_PARSE_FAILURE; 351 352 if (!plogi->class3.class_valid) 353 return FC_PARSE_FAILURE; 354 355 if (bfa_os_ntohs(plogi->class3.rxsz) < (FC_MIN_PDUSZ)) 356 return FC_PARSE_FAILURE; 357 358 return FC_PARSE_OK; 359 default: 360 return FC_PARSE_FAILURE; 361 } 362} 363 364enum fc_parse_status 365fc_plogi_parse(struct fchs_s *fchs) 366{ 367 struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1); 368 369 if (plogi->class3.class_valid != 1) 370 return FC_PARSE_FAILURE; 371 372 if ((bfa_os_ntohs(plogi->class3.rxsz) < FC_MIN_PDUSZ) 373 || (bfa_os_ntohs(plogi->class3.rxsz) > FC_MAX_PDUSZ) 374 || (plogi->class3.rxsz == 0)) 375 return FC_PARSE_FAILURE; 376 377 return FC_PARSE_OK; 378} 379 380u16 381fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 382 u16 ox_id) 383{ 384 struct fc_prli_s *prli = (struct fc_prli_s *) (pld); 385 386 fc_els_req_build(fchs, d_id, s_id, ox_id); 387 bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); 388 389 prli->command = FC_ELS_PRLI; 390 prli->parampage.servparams.initiator = 1; 391 prli->parampage.servparams.retry = 1; 392 prli->parampage.servparams.rec_support = 1; 393 prli->parampage.servparams.task_retry_id = 0; 394 prli->parampage.servparams.confirm = 1; 395 396 return sizeof(struct fc_prli_s); 397} 398 399u16 400fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 401 u16 ox_id, enum bfa_port_role role) 402{ 403 struct fc_prli_s *prli = (struct fc_prli_s *) (pld); 404 405 fc_els_rsp_build(fchs, d_id, s_id, ox_id); 406 bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); 407 408 prli->command = FC_ELS_ACC; 409 410 if ((role & BFA_PORT_ROLE_FCP_TM) == BFA_PORT_ROLE_FCP_TM) 411 prli->parampage.servparams.target = 1; 412 else 413 prli->parampage.servparams.initiator = 1; 414 415 prli->parampage.rspcode = FC_PRLI_ACC_XQTD; 416 417 return sizeof(struct fc_prli_s); 418} 419 420enum fc_parse_status 421fc_prli_rsp_parse(struct fc_prli_s *prli, int len) 422{ 423 if (len < sizeof(struct fc_prli_s)) 424 return FC_PARSE_FAILURE; 425 426 if (prli->command != FC_ELS_ACC) 427 return FC_PARSE_FAILURE; 428 429 if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD) 430 && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG)) 431 return FC_PARSE_FAILURE; 432 433 if (prli->parampage.servparams.target != 1) 434 return FC_PARSE_FAILURE; 435 436 return FC_PARSE_OK; 437} 438 439enum fc_parse_status 440fc_prli_parse(struct fc_prli_s *prli) 441{ 442 if (prli->parampage.type != FC_TYPE_FCP) 443 return FC_PARSE_FAILURE; 444 445 if (!prli->parampage.imagepair) 446 return FC_PARSE_FAILURE; 447 448 if (!prli->parampage.servparams.initiator) 449 return FC_PARSE_FAILURE; 450 451 return FC_PARSE_OK; 452} 453 454u16 455fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, 456 u32 s_id, u16 ox_id, wwn_t port_name) 457{ 458 fc_els_req_build(fchs, d_id, s_id, ox_id); 459 460 memset(logo, '\0', sizeof(struct fc_logo_s)); 461 logo->els_cmd.els_code = FC_ELS_LOGO; 462 logo->nport_id = (s_id); 463 logo->orig_port_name = port_name; 464 465 return sizeof(struct fc_logo_s); 466} 467 468static u16 469fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, 470 u32 s_id, u16 ox_id, wwn_t port_name, 471 wwn_t node_name, u8 els_code) 472{ 473 memset(adisc, '\0', sizeof(struct fc_adisc_s)); 474 475 adisc->els_cmd.els_code = els_code; 476 477 if (els_code == FC_ELS_ADISC) 478 fc_els_req_build(fchs, d_id, s_id, ox_id); 479 else 480 fc_els_rsp_build(fchs, d_id, s_id, ox_id); 481 482 adisc->orig_HA = 0; 483 adisc->orig_port_name = port_name; 484 adisc->orig_node_name = node_name; 485 adisc->nport_id = (s_id); 486 487 return sizeof(struct fc_adisc_s); 488} 489 490u16 491fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, 492 u32 s_id, u16 ox_id, wwn_t port_name, 493 wwn_t node_name) 494{ 495 return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name, 496 node_name, FC_ELS_ADISC); 497} 498 499u16 500fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, 501 u32 s_id, u16 ox_id, wwn_t port_name, 502 wwn_t node_name) 503{ 504 return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name, 505 node_name, FC_ELS_ACC); 506} 507 508enum fc_parse_status 509fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name, 510 wwn_t node_name) 511{ 512 513 if (len < sizeof(struct fc_adisc_s)) 514 return FC_PARSE_FAILURE; 515 516 if (adisc->els_cmd.els_code != FC_ELS_ACC) 517 return FC_PARSE_FAILURE; 518 519 if (!wwn_is_equal(adisc->orig_port_name, port_name)) 520 return FC_PARSE_FAILURE; 521 522 return FC_PARSE_OK; 523} 524 525enum fc_parse_status 526fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap, 527 wwn_t node_name, wwn_t port_name) 528{ 529 struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld; 530 531 if (adisc->els_cmd.els_code != FC_ELS_ACC) 532 return FC_PARSE_FAILURE; 533 534 if ((adisc->nport_id == (host_dap)) 535 && wwn_is_equal(adisc->orig_port_name, port_name) 536 && wwn_is_equal(adisc->orig_node_name, node_name)) 537 return FC_PARSE_OK; 538 539 return FC_PARSE_FAILURE; 540} 541 542enum fc_parse_status 543fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name) 544{ 545 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); 546 547 if (pdisc->class3.class_valid != 1) 548 return FC_PARSE_FAILURE; 549 550 if ((bfa_os_ntohs(pdisc->class3.rxsz) < 551 (FC_MIN_PDUSZ - sizeof(struct fchs_s))) 552 || (pdisc->class3.rxsz == 0)) 553 return FC_PARSE_FAILURE; 554 555 if (!wwn_is_equal(pdisc->port_name, port_name)) 556 return FC_PARSE_FAILURE; 557 558 if (!wwn_is_equal(pdisc->node_name, node_name)) 559 return FC_PARSE_FAILURE; 560 561 return FC_PARSE_OK; 562} 563 564u16 565fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id) 566{ 567 bfa_os_memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s)); 568 fchs->cat_info = FC_CAT_ABTS; 569 fchs->d_id = (d_id); 570 fchs->s_id = (s_id); 571 fchs->ox_id = bfa_os_htons(ox_id); 572 573 return sizeof(struct fchs_s); 574} 575 576enum fc_parse_status 577fc_abts_rsp_parse(struct fchs_s *fchs, int len) 578{ 579 if ((fchs->cat_info == FC_CAT_BA_ACC) 580 || (fchs->cat_info == FC_CAT_BA_RJT)) 581 return FC_PARSE_OK; 582 583 return FC_PARSE_FAILURE; 584} 585 586u16 587fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, 588 u32 s_id, u16 ox_id, u16 rrq_oxid) 589{ 590 fc_els_req_build(fchs, d_id, s_id, ox_id); 591 592 /* 593 * build rrq payload 594 */ 595 bfa_os_memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s)); 596 rrq->s_id = (s_id); 597 rrq->ox_id = bfa_os_htons(rrq_oxid); 598 rrq->rx_id = FC_RXID_ANY; 599 600 return sizeof(struct fc_rrq_s); 601} 602 603u16 604fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 605 u16 ox_id) 606{ 607 struct fc_els_cmd_s *acc = pld; 608 609 fc_els_rsp_build(fchs, d_id, s_id, ox_id); 610 611 memset(acc, 0, sizeof(struct fc_els_cmd_s)); 612 acc->els_code = FC_ELS_ACC; 613 614 return sizeof(struct fc_els_cmd_s); 615} 616 617u16 618fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id, 619 u32 s_id, u16 ox_id, u8 reason_code, 620 u8 reason_code_expl) 621{ 622 fc_els_rsp_build(fchs, d_id, s_id, ox_id); 623 memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s)); 624 625 ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT; 626 ls_rjt->reason_code = reason_code; 627 ls_rjt->reason_code_expl = reason_code_expl; 628 ls_rjt->vendor_unique = 0x00; 629 630 return sizeof(struct fc_ls_rjt_s); 631} 632 633u16 634fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id, 635 u32 s_id, u16 ox_id, u16 rx_id) 636{ 637 fc_bls_rsp_build(fchs, d_id, s_id, ox_id); 638 639 bfa_os_memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s)); 640 641 fchs->rx_id = rx_id; 642 643 ba_acc->ox_id = fchs->ox_id; 644 ba_acc->rx_id = fchs->rx_id; 645 646 return sizeof(struct fc_ba_acc_s); 647} 648 649u16 650fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, 651 u32 d_id, u32 s_id, u16 ox_id) 652{ 653 fc_els_rsp_build(fchs, d_id, s_id, ox_id); 654 memset(els_cmd, 0, sizeof(struct fc_els_cmd_s)); 655 els_cmd->els_code = FC_ELS_ACC; 656 657 return sizeof(struct fc_els_cmd_s); 658} 659 660int 661fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code) 662{ 663 int num_pages = 0; 664 struct fc_prlo_s *prlo; 665 struct fc_tprlo_s *tprlo; 666 667 if (els_code == FC_ELS_PRLO) { 668 prlo = (struct fc_prlo_s *) (fc_frame + 1); 669 num_pages = (bfa_os_ntohs(prlo->payload_len) - 4) / 16; 670 } else { 671 tprlo = (struct fc_tprlo_s *) (fc_frame + 1); 672 num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16; 673 } 674 return num_pages; 675} 676 677u16 678fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc, 679 u32 d_id, u32 s_id, u16 ox_id, 680 int num_pages) 681{ 682 int page; 683 684 fc_els_rsp_build(fchs, d_id, s_id, ox_id); 685 686 memset(tprlo_acc, 0, (num_pages * 16) + 4); 687 tprlo_acc->command = FC_ELS_ACC; 688 689 tprlo_acc->page_len = 0x10; 690 tprlo_acc->payload_len = bfa_os_htons((num_pages * 16) + 4); 691 692 for (page = 0; page < num_pages; page++) { 693 tprlo_acc->tprlo_acc_params[page].opa_valid = 0; 694 tprlo_acc->tprlo_acc_params[page].rpa_valid = 0; 695 tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP; 696 tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0; 697 tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0; 698 } 699 return bfa_os_ntohs(tprlo_acc->payload_len); 700} 701 702u16 703fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, 704 u32 d_id, u32 s_id, u16 ox_id, 705 int num_pages) 706{ 707 int page; 708 709 fc_els_rsp_build(fchs, d_id, s_id, ox_id); 710 711 memset(prlo_acc, 0, (num_pages * 16) + 4); 712 prlo_acc->command = FC_ELS_ACC; 713 prlo_acc->page_len = 0x10; 714 prlo_acc->payload_len = bfa_os_htons((num_pages * 16) + 4); 715 716 for (page = 0; page < num_pages; page++) { 717 prlo_acc->prlo_acc_params[page].opa_valid = 0; 718 prlo_acc->prlo_acc_params[page].rpa_valid = 0; 719 prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP; 720 prlo_acc->prlo_acc_params[page].orig_process_assc = 0; 721 prlo_acc->prlo_acc_params[page].resp_process_assc = 0; 722 } 723 724 return bfa_os_ntohs(prlo_acc->payload_len); 725} 726 727u16 728fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id, 729 u32 s_id, u16 ox_id, u32 data_format) 730{ 731 fc_els_req_build(fchs, d_id, s_id, ox_id); 732 733 memset(rnid, 0, sizeof(struct fc_rnid_cmd_s)); 734 735 rnid->els_cmd.els_code = FC_ELS_RNID; 736 rnid->node_id_data_format = data_format; 737 738 return sizeof(struct fc_rnid_cmd_s); 739} 740 741u16 742fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, 743 u32 d_id, u32 s_id, u16 ox_id, 744 u32 data_format, 745 struct fc_rnid_common_id_data_s *common_id_data, 746 struct fc_rnid_general_topology_data_s *gen_topo_data) 747{ 748 memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s)); 749 750 fc_els_rsp_build(fchs, d_id, s_id, ox_id); 751 752 rnid_acc->els_cmd.els_code = FC_ELS_ACC; 753 rnid_acc->node_id_data_format = data_format; 754 rnid_acc->common_id_data_length = 755 sizeof(struct fc_rnid_common_id_data_s); 756 rnid_acc->common_id_data = *common_id_data; 757 758 if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { 759 rnid_acc->specific_id_data_length = 760 sizeof(struct fc_rnid_general_topology_data_s); 761 bfa_os_assign(rnid_acc->gen_topology_data, *gen_topo_data); 762 return sizeof(struct fc_rnid_acc_s); 763 } else { 764 return sizeof(struct fc_rnid_acc_s) - 765 sizeof(struct fc_rnid_general_topology_data_s); 766 } 767 768} 769 770u16 771fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id, 772 u32 s_id, u16 ox_id) 773{ 774 fc_els_req_build(fchs, d_id, s_id, ox_id); 775 776 memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s)); 777 778 rpsc->els_cmd.els_code = FC_ELS_RPSC; 779 return sizeof(struct fc_rpsc_cmd_s); 780} 781 782u16 783fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, 784 u32 d_id, u32 s_id, u32 *pid_list, 785 u16 npids) 786{ 787 u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_os_hton3b(d_id)); 788 int i = 0; 789 790 fc_els_req_build(fchs, bfa_os_hton3b(dctlr_id), s_id, 0); 791 792 memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s)); 793 794 rpsc2->els_cmd.els_code = FC_ELS_RPSC; 795 rpsc2->token = bfa_os_htonl(FC_BRCD_TOKEN); 796 rpsc2->num_pids = bfa_os_htons(npids); 797 for (i = 0; i < npids; i++) 798 rpsc2->pid_list[i].pid = pid_list[i]; 799 800 return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) * 801 (sizeof(u32))); 802} 803 804u16 805fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc, 806 u32 d_id, u32 s_id, u16 ox_id, 807 struct fc_rpsc_speed_info_s *oper_speed) 808{ 809 memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s)); 810 811 fc_els_rsp_build(fchs, d_id, s_id, ox_id); 812 813 rpsc_acc->command = FC_ELS_ACC; 814 rpsc_acc->num_entries = bfa_os_htons(1); 815 816 rpsc_acc->speed_info[0].port_speed_cap = 817 bfa_os_htons(oper_speed->port_speed_cap); 818 819 rpsc_acc->speed_info[0].port_op_speed = 820 bfa_os_htons(oper_speed->port_op_speed); 821 822 return sizeof(struct fc_rpsc_acc_s); 823 824} 825 826/* 827 * TBD - 828 * . get rid of unnecessary memsets 829 */ 830 831u16 832fc_logo_rsp_parse(struct fchs_s *fchs, int len) 833{ 834 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 835 836 len = len; 837 if (els_cmd->els_code != FC_ELS_ACC) 838 return FC_PARSE_FAILURE; 839 840 return FC_PARSE_OK; 841} 842 843u16 844fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, 845 u16 ox_id, wwn_t port_name, wwn_t node_name, 846 u16 pdu_size) 847{ 848 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); 849 850 bfa_os_memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s)); 851 852 pdisc->els_cmd.els_code = FC_ELS_PDISC; 853 fc_els_req_build(fchs, d_id, s_id, ox_id); 854 855 pdisc->csp.rxsz = pdisc->class3.rxsz = bfa_os_htons(pdu_size); 856 pdisc->port_name = port_name; 857 pdisc->node_name = node_name; 858 859 return sizeof(struct fc_logi_s); 860} 861 862u16 863fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) 864{ 865 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); 866 867 if (len < sizeof(struct fc_logi_s)) 868 return FC_PARSE_LEN_INVAL; 869 870 if (pdisc->els_cmd.els_code != FC_ELS_ACC) 871 return FC_PARSE_ACC_INVAL; 872 873 if (!wwn_is_equal(pdisc->port_name, port_name)) 874 return FC_PARSE_PWWN_NOT_EQUAL; 875 876 if (!pdisc->class3.class_valid) 877 return FC_PARSE_NWWN_NOT_EQUAL; 878 879 if (bfa_os_ntohs(pdisc->class3.rxsz) < (FC_MIN_PDUSZ)) 880 return FC_PARSE_RXSZ_INVAL; 881 882 return FC_PARSE_OK; 883} 884 885u16 886fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, 887 int num_pages) 888{ 889 struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1); 890 int page; 891 892 fc_els_req_build(fchs, d_id, s_id, ox_id); 893 memset(prlo, 0, (num_pages * 16) + 4); 894 prlo->command = FC_ELS_PRLO; 895 prlo->page_len = 0x10; 896 prlo->payload_len = bfa_os_htons((num_pages * 16) + 4); 897 898 for (page = 0; page < num_pages; page++) { 899 prlo->prlo_params[page].type = FC_TYPE_FCP; 900 prlo->prlo_params[page].opa_valid = 0; 901 prlo->prlo_params[page].rpa_valid = 0; 902 prlo->prlo_params[page].orig_process_assc = 0; 903 prlo->prlo_params[page].resp_process_assc = 0; 904 } 905 906 return bfa_os_ntohs(prlo->payload_len); 907} 908 909u16 910fc_prlo_rsp_parse(struct fchs_s *fchs, int len) 911{ 912 struct fc_prlo_acc_s *prlo = (struct fc_prlo_acc_s *) (fchs + 1); 913 int num_pages = 0; 914 int page = 0; 915 916 len = len; 917 918 if (prlo->command != FC_ELS_ACC) 919 return FC_PARSE_FAILURE; 920 921 num_pages = ((bfa_os_ntohs(prlo->payload_len)) - 4) / 16; 922 923 for (page = 0; page < num_pages; page++) { 924 if (prlo->prlo_acc_params[page].type != FC_TYPE_FCP) 925 return FC_PARSE_FAILURE; 926 927 if (prlo->prlo_acc_params[page].opa_valid != 0) 928 return FC_PARSE_FAILURE; 929 930 if (prlo->prlo_acc_params[page].rpa_valid != 0) 931 return FC_PARSE_FAILURE; 932 933 if (prlo->prlo_acc_params[page].orig_process_assc != 0) 934 return FC_PARSE_FAILURE; 935 936 if (prlo->prlo_acc_params[page].resp_process_assc != 0) 937 return FC_PARSE_FAILURE; 938 } 939 return FC_PARSE_OK; 940 941} 942 943u16 944fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, 945 u16 ox_id, int num_pages, 946 enum fc_tprlo_type tprlo_type, u32 tpr_id) 947{ 948 struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1); 949 int page; 950 951 fc_els_req_build(fchs, d_id, s_id, ox_id); 952 memset(tprlo, 0, (num_pages * 16) + 4); 953 tprlo->command = FC_ELS_TPRLO; 954 tprlo->page_len = 0x10; 955 tprlo->payload_len = bfa_os_htons((num_pages * 16) + 4); 956 957 for (page = 0; page < num_pages; page++) { 958 tprlo->tprlo_params[page].type = FC_TYPE_FCP; 959 tprlo->tprlo_params[page].opa_valid = 0; 960 tprlo->tprlo_params[page].rpa_valid = 0; 961 tprlo->tprlo_params[page].orig_process_assc = 0; 962 tprlo->tprlo_params[page].resp_process_assc = 0; 963 if (tprlo_type == FC_GLOBAL_LOGO) { 964 tprlo->tprlo_params[page].global_process_logout = 1; 965 } else if (tprlo_type == FC_TPR_LOGO) { 966 tprlo->tprlo_params[page].tpo_nport_valid = 1; 967 tprlo->tprlo_params[page].tpo_nport_id = (tpr_id); 968 } 969 } 970 971 return bfa_os_ntohs(tprlo->payload_len); 972} 973 974u16 975fc_tprlo_rsp_parse(struct fchs_s *fchs, int len) 976{ 977 struct fc_tprlo_acc_s *tprlo = (struct fc_tprlo_acc_s *) (fchs + 1); 978 int num_pages = 0; 979 int page = 0; 980 981 len = len; 982 983 if (tprlo->command != FC_ELS_ACC) 984 return FC_PARSE_ACC_INVAL; 985 986 num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16; 987 988 for (page = 0; page < num_pages; page++) { 989 if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP) 990 return FC_PARSE_NOT_FCP; 991 if (tprlo->tprlo_acc_params[page].opa_valid != 0) 992 return FC_PARSE_OPAFLAG_INVAL; 993 if (tprlo->tprlo_acc_params[page].rpa_valid != 0) 994 return FC_PARSE_RPAFLAG_INVAL; 995 if (tprlo->tprlo_acc_params[page].orig_process_assc != 0) 996 return FC_PARSE_OPA_INVAL; 997 if (tprlo->tprlo_acc_params[page].resp_process_assc != 0) 998 return FC_PARSE_RPA_INVAL; 999 } 1000 return FC_PARSE_OK; 1001} 1002 1003enum fc_parse_status 1004fc_rrq_rsp_parse(struct fchs_s *fchs, int len) 1005{ 1006 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 1007 1008 len = len; 1009 if (els_cmd->els_code != FC_ELS_ACC) 1010 return FC_PARSE_FAILURE; 1011 1012 return FC_PARSE_OK; 1013} 1014 1015u16 1016fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, 1017 u16 ox_id, u32 reason_code, 1018 u32 reason_expl) 1019{ 1020 struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1); 1021 1022 fc_bls_rsp_build(fchs, d_id, s_id, ox_id); 1023 1024 fchs->cat_info = FC_CAT_BA_RJT; 1025 ba_rjt->reason_code = reason_code; 1026 ba_rjt->reason_expl = reason_expl; 1027 return sizeof(struct fc_ba_rjt_s); 1028} 1029 1030static void 1031fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code) 1032{ 1033 bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s)); 1034 cthdr->rev_id = CT_GS3_REVISION; 1035 cthdr->gs_type = CT_GSTYPE_DIRSERVICE; 1036 cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER; 1037 cthdr->cmd_rsp_code = bfa_os_htons(cmd_code); 1038} 1039 1040static void 1041fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code) 1042{ 1043 bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s)); 1044 cthdr->rev_id = CT_GS3_REVISION; 1045 cthdr->gs_type = CT_GSTYPE_MGMTSERVICE; 1046 cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER; 1047 cthdr->cmd_rsp_code = bfa_os_htons(cmd_code); 1048} 1049 1050static void 1051fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code, 1052 u8 sub_type) 1053{ 1054 bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s)); 1055 cthdr->rev_id = CT_GS3_REVISION; 1056 cthdr->gs_type = CT_GSTYPE_MGMTSERVICE; 1057 cthdr->gs_sub_type = sub_type; 1058 cthdr->cmd_rsp_code = bfa_os_htons(cmd_code); 1059} 1060 1061u16 1062fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1063 wwn_t port_name) 1064{ 1065 1066 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1067 struct fcgs_gidpn_req_s *gidpn = 1068 (struct fcgs_gidpn_req_s *) (cthdr + 1); 1069 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1070 1071 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1072 fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN); 1073 1074 bfa_os_memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s)); 1075 gidpn->port_name = port_name; 1076 return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s); 1077} 1078 1079u16 1080fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1081 u32 port_id) 1082{ 1083 1084 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1085 fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1); 1086 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1087 1088 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1089 fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID); 1090 1091 bfa_os_memset(gpnid, 0, sizeof(fcgs_gpnid_req_t)); 1092 gpnid->dap = port_id; 1093 return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s); 1094} 1095 1096u16 1097fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1098 u32 port_id) 1099{ 1100 1101 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1102 fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1); 1103 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1104 1105 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1106 fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID); 1107 1108 bfa_os_memset(gnnid, 0, sizeof(fcgs_gnnid_req_t)); 1109 gnnid->dap = port_id; 1110 return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s); 1111} 1112 1113u16 1114fc_ct_rsp_parse(struct ct_hdr_s *cthdr) 1115{ 1116 if (bfa_os_ntohs(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) { 1117 if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY) 1118 return FC_PARSE_BUSY; 1119 else 1120 return FC_PARSE_FAILURE; 1121 } 1122 1123 return FC_PARSE_OK; 1124} 1125 1126u16 1127fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr, u8 set_br_reg, 1128 u32 s_id, u16 ox_id) 1129{ 1130 u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER); 1131 1132 fc_els_req_build(fchs, d_id, s_id, ox_id); 1133 1134 bfa_os_memset(scr, 0, sizeof(struct fc_scr_s)); 1135 scr->command = FC_ELS_SCR; 1136 scr->reg_func = FC_SCR_REG_FUNC_FULL; 1137 if (set_br_reg) 1138 scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE; 1139 1140 return sizeof(struct fc_scr_s); 1141} 1142 1143u16 1144fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn, u32 s_id, 1145 u16 ox_id) 1146{ 1147 u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER); 1148 u16 payldlen; 1149 1150 fc_els_req_build(fchs, d_id, s_id, ox_id); 1151 rscn->command = FC_ELS_RSCN; 1152 rscn->pagelen = sizeof(rscn->event[0]); 1153 1154 payldlen = sizeof(u32) + rscn->pagelen; 1155 rscn->payldlen = bfa_os_htons(payldlen); 1156 1157 rscn->event[0].format = FC_RSCN_FORMAT_PORTID; 1158 rscn->event[0].portid = s_id; 1159 1160 return sizeof(struct fc_rscn_pl_s); 1161} 1162 1163u16 1164fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1165 enum bfa_port_role roles) 1166{ 1167 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1168 struct fcgs_rftid_req_s *rftid = 1169 (struct fcgs_rftid_req_s *) (cthdr + 1); 1170 u32 type_value, d_id = bfa_os_hton3b(FC_NAME_SERVER); 1171 u8 index; 1172 1173 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1174 fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID); 1175 1176 bfa_os_memset(rftid, 0, sizeof(struct fcgs_rftid_req_s)); 1177 1178 rftid->dap = s_id; 1179 1180 /* By default, FCP FC4 Type is registered */ 1181 index = FC_TYPE_FCP >> 5; 1182 type_value = 1 << (FC_TYPE_FCP % 32); 1183 rftid->fc4_type[index] = bfa_os_htonl(type_value); 1184 1185 if (roles & BFA_PORT_ROLE_FCP_IPFC) { 1186 index = FC_TYPE_IP >> 5; 1187 type_value = 1 << (FC_TYPE_IP % 32); 1188 rftid->fc4_type[index] |= bfa_os_htonl(type_value); 1189 } 1190 1191 return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s); 1192} 1193 1194u16 1195fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, 1196 u16 ox_id, u8 *fc4_bitmap, 1197 u32 bitmap_size) 1198{ 1199 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1200 struct fcgs_rftid_req_s *rftid = 1201 (struct fcgs_rftid_req_s *) (cthdr + 1); 1202 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1203 1204 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1205 fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID); 1206 1207 bfa_os_memset(rftid, 0, sizeof(struct fcgs_rftid_req_s)); 1208 1209 rftid->dap = s_id; 1210 bfa_os_memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap, 1211 (bitmap_size < 32 ? bitmap_size : 32)); 1212 1213 return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s); 1214} 1215 1216u16 1217fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1218 u8 fc4_type, u8 fc4_ftrs) 1219{ 1220 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1221 struct fcgs_rffid_req_s *rffid = 1222 (struct fcgs_rffid_req_s *) (cthdr + 1); 1223 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1224 1225 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1226 fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID); 1227 1228 bfa_os_memset(rffid, 0, sizeof(struct fcgs_rffid_req_s)); 1229 1230 rffid->dap = s_id; 1231 rffid->fc4ftr_bits = fc4_ftrs; 1232 rffid->fc4_type = fc4_type; 1233 1234 return sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s); 1235} 1236 1237u16 1238fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1239 u8 *name) 1240{ 1241 1242 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1243 struct fcgs_rspnid_req_s *rspnid = 1244 (struct fcgs_rspnid_req_s *) (cthdr + 1); 1245 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1246 1247 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1248 fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID); 1249 1250 bfa_os_memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s)); 1251 1252 rspnid->dap = s_id; 1253 rspnid->spn_len = (u8) strlen((char *)name); 1254 strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len); 1255 1256 return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s); 1257} 1258 1259u16 1260fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, 1261 u8 fc4_type) 1262{ 1263 1264 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1265 struct fcgs_gidft_req_s *gidft = 1266 (struct fcgs_gidft_req_s *) (cthdr + 1); 1267 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1268 1269 fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1270 1271 fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT); 1272 1273 bfa_os_memset(gidft, 0, sizeof(struct fcgs_gidft_req_s)); 1274 gidft->fc4_type = fc4_type; 1275 gidft->domain_id = 0; 1276 gidft->area_id = 0; 1277 1278 return sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s); 1279} 1280 1281u16 1282fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1283 wwn_t port_name) 1284{ 1285 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1286 struct fcgs_rpnid_req_s *rpnid = 1287 (struct fcgs_rpnid_req_s *) (cthdr + 1); 1288 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1289 1290 fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1291 fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID); 1292 1293 bfa_os_memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s)); 1294 rpnid->port_id = port_id; 1295 rpnid->port_name = port_name; 1296 1297 return sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s); 1298} 1299 1300u16 1301fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1302 wwn_t node_name) 1303{ 1304 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1305 struct fcgs_rnnid_req_s *rnnid = 1306 (struct fcgs_rnnid_req_s *) (cthdr + 1); 1307 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1308 1309 fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1310 fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID); 1311 1312 bfa_os_memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s)); 1313 rnnid->port_id = port_id; 1314 rnnid->node_name = node_name; 1315 1316 return sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s); 1317} 1318 1319u16 1320fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1321 u32 cos) 1322{ 1323 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1324 struct fcgs_rcsid_req_s *rcsid = 1325 (struct fcgs_rcsid_req_s *) (cthdr + 1); 1326 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1327 1328 fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1329 fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID); 1330 1331 bfa_os_memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s)); 1332 rcsid->port_id = port_id; 1333 rcsid->cos = cos; 1334 1335 return sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s); 1336} 1337 1338u16 1339fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1340 u8 port_type) 1341{ 1342 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1343 struct fcgs_rptid_req_s *rptid = 1344 (struct fcgs_rptid_req_s *) (cthdr + 1); 1345 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1346 1347 fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1348 fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID); 1349 1350 bfa_os_memset(rptid, 0, sizeof(struct fcgs_rptid_req_s)); 1351 rptid->port_id = port_id; 1352 rptid->port_type = port_type; 1353 1354 return sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s); 1355} 1356 1357u16 1358fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id) 1359{ 1360 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1361 struct fcgs_ganxt_req_s *ganxt = 1362 (struct fcgs_ganxt_req_s *) (cthdr + 1); 1363 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); 1364 1365 fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1366 fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT); 1367 1368 bfa_os_memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s)); 1369 ganxt->port_id = port_id; 1370 1371 return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s); 1372} 1373 1374/* 1375 * Builds fc hdr and ct hdr for FDMI requests. 1376 */ 1377u16 1378fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id, 1379 u16 cmd_code) 1380{ 1381 1382 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1383 u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER); 1384 1385 fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1386 fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code); 1387 1388 return sizeof(struct ct_hdr_s); 1389} 1390 1391/* 1392 * Given a FC4 Type, this function returns a fc4 type bitmask 1393 */ 1394void 1395fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask) 1396{ 1397 u8 index; 1398 u32 *ptr = (u32 *) bit_mask; 1399 u32 type_value; 1400 1401 /* 1402 * @todo : Check for bitmask size 1403 */ 1404 1405 index = fc4_type >> 5; 1406 type_value = 1 << (fc4_type % 32); 1407 ptr[index] = bfa_os_htonl(type_value); 1408 1409} 1410 1411/* 1412 * GMAL Request 1413 */ 1414u16 1415fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn) 1416{ 1417 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1418 fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1); 1419 u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER); 1420 1421 fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1422 fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD, 1423 CT_GSSUBTYPE_CFGSERVER); 1424 1425 bfa_os_memset(gmal, 0, sizeof(fcgs_gmal_req_t)); 1426 gmal->wwn = wwn; 1427 1428 return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t); 1429} 1430 1431/* 1432 * GFN (Get Fabric Name) Request 1433 */ 1434u16 1435fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn) 1436{ 1437 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1438 fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1); 1439 u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER); 1440 1441 fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1442 fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD, 1443 CT_GSSUBTYPE_CFGSERVER); 1444 1445 bfa_os_memset(gfn, 0, sizeof(fcgs_gfn_req_t)); 1446 gfn->wwn = wwn; 1447 1448 return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t); 1449} 1450