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