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/** 19 * port_api.c BFA FCS port 20 */ 21 22 23#include <bfa.h> 24#include <bfa_svc.h> 25#include "fcs_lport.h" 26#include "fcs_rport.h" 27#include "lport_priv.h" 28#include "fcs_trcmod.h" 29#include "fcs_fcxp.h" 30#include <fcs/bfa_fcs_fdmi.h> 31 32BFA_TRC_FILE(FCS, FDMI); 33 34#define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 35 36/* 37 * forward declarations 38 */ 39static void bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg, 40 struct bfa_fcxp_s *fcxp_alloced); 41static void bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg, 42 struct bfa_fcxp_s *fcxp_alloced); 43static void bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg, 44 struct bfa_fcxp_s *fcxp_alloced); 45static void bfa_fcs_port_fdmi_rhba_response(void *fcsarg, 46 struct bfa_fcxp_s *fcxp, 47 void *cbarg, 48 bfa_status_t req_status, 49 u32 rsp_len, 50 u32 resid_len, 51 struct fchs_s *rsp_fchs); 52static void bfa_fcs_port_fdmi_rprt_response(void *fcsarg, 53 struct bfa_fcxp_s *fcxp, 54 void *cbarg, 55 bfa_status_t req_status, 56 u32 rsp_len, 57 u32 resid_len, 58 struct fchs_s *rsp_fchs); 59static void bfa_fcs_port_fdmi_rpa_response(void *fcsarg, 60 struct bfa_fcxp_s *fcxp, 61 void *cbarg, 62 bfa_status_t req_status, 63 u32 rsp_len, 64 u32 resid_len, 65 struct fchs_s *rsp_fchs); 66static void bfa_fcs_port_fdmi_timeout(void *arg); 67static u16 bfa_fcs_port_fdmi_build_rhba_pyld( 68 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld); 69static u16 bfa_fcs_port_fdmi_build_rprt_pyld( 70 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld); 71static u16 bfa_fcs_port_fdmi_build_rpa_pyld( 72 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld); 73static u16 bfa_fcs_port_fdmi_build_portattr_block( 74 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld); 75static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi, 76 struct bfa_fcs_fdmi_hba_attr_s *hba_attr); 77static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi, 78 struct bfa_fcs_fdmi_port_attr_s *port_attr); 79/** 80 * fcs_fdmi_sm FCS FDMI state machine 81 */ 82 83/** 84 * FDMI State Machine events 85 */ 86enum port_fdmi_event { 87 FDMISM_EVENT_PORT_ONLINE = 1, 88 FDMISM_EVENT_PORT_OFFLINE = 2, 89 FDMISM_EVENT_RSP_OK = 4, 90 FDMISM_EVENT_RSP_ERROR = 5, 91 FDMISM_EVENT_TIMEOUT = 6, 92 FDMISM_EVENT_RHBA_SENT = 7, 93 FDMISM_EVENT_RPRT_SENT = 8, 94 FDMISM_EVENT_RPA_SENT = 9, 95}; 96 97static void bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi, 98 enum port_fdmi_event event); 99static void bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi, 100 enum port_fdmi_event event); 101static void bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi, 102 enum port_fdmi_event event); 103static void bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi, 104 enum port_fdmi_event event); 105static void bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi, 106 enum port_fdmi_event event); 107static void bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi, 108 enum port_fdmi_event event); 109static void bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi, 110 enum port_fdmi_event event); 111static void bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi, 112 enum port_fdmi_event event); 113static void bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi, 114 enum port_fdmi_event event); 115static void bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi, 116 enum port_fdmi_event event); 117static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi, 118 enum port_fdmi_event event); 119static void bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi, 120 enum port_fdmi_event event); 121 122/** 123 * Start in offline state - awaiting MS to send start. 124 */ 125static void 126bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi, 127 enum port_fdmi_event event) 128{ 129 struct bfa_fcs_port_s *port = fdmi->ms->port; 130 131 bfa_trc(port->fcs, port->port_cfg.pwwn); 132 bfa_trc(port->fcs, event); 133 134 fdmi->retry_cnt = 0; 135 136 switch (event) { 137 case FDMISM_EVENT_PORT_ONLINE: 138 if (port->vport) { 139 /* 140 * For Vports, register a new port. 141 */ 142 bfa_sm_set_state(fdmi, 143 bfa_fcs_port_fdmi_sm_sending_rprt); 144 bfa_fcs_port_fdmi_send_rprt(fdmi, NULL); 145 } else { 146 /* 147 * For a base port, we should first register the HBA 148 * atribute. The HBA attribute also contains the base 149 * port registration. 150 */ 151 bfa_sm_set_state(fdmi, 152 bfa_fcs_port_fdmi_sm_sending_rhba); 153 bfa_fcs_port_fdmi_send_rhba(fdmi, NULL); 154 } 155 break; 156 157 case FDMISM_EVENT_PORT_OFFLINE: 158 break; 159 160 default: 161 bfa_sm_fault(port->fcs, event); 162 } 163} 164 165static void 166bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi, 167 enum port_fdmi_event event) 168{ 169 struct bfa_fcs_port_s *port = fdmi->ms->port; 170 171 bfa_trc(port->fcs, port->port_cfg.pwwn); 172 bfa_trc(port->fcs, event); 173 174 switch (event) { 175 case FDMISM_EVENT_RHBA_SENT: 176 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba); 177 break; 178 179 case FDMISM_EVENT_PORT_OFFLINE: 180 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 181 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 182 &fdmi->fcxp_wqe); 183 break; 184 185 default: 186 bfa_sm_fault(port->fcs, event); 187 } 188} 189 190static void 191bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi, 192 enum port_fdmi_event event) 193{ 194 struct bfa_fcs_port_s *port = fdmi->ms->port; 195 196 bfa_trc(port->fcs, port->port_cfg.pwwn); 197 bfa_trc(port->fcs, event); 198 199 switch (event) { 200 case FDMISM_EVENT_RSP_ERROR: 201 /* 202 * if max retries have not been reached, start timer for a 203 * delayed retry 204 */ 205 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 206 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba_retry); 207 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 208 &fdmi->timer, bfa_fcs_port_fdmi_timeout, 209 fdmi, BFA_FCS_RETRY_TIMEOUT); 210 } else { 211 /* 212 * set state to offline 213 */ 214 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 215 } 216 break; 217 218 case FDMISM_EVENT_RSP_OK: 219 /* 220 * Initiate Register Port Attributes 221 */ 222 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa); 223 fdmi->retry_cnt = 0; 224 bfa_fcs_port_fdmi_send_rpa(fdmi, NULL); 225 break; 226 227 case FDMISM_EVENT_PORT_OFFLINE: 228 bfa_fcxp_discard(fdmi->fcxp); 229 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 230 break; 231 232 default: 233 bfa_sm_fault(port->fcs, event); 234 } 235} 236 237static void 238bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi, 239 enum port_fdmi_event event) 240{ 241 struct bfa_fcs_port_s *port = fdmi->ms->port; 242 243 bfa_trc(port->fcs, port->port_cfg.pwwn); 244 bfa_trc(port->fcs, event); 245 246 switch (event) { 247 case FDMISM_EVENT_TIMEOUT: 248 /* 249 * Retry Timer Expired. Re-send 250 */ 251 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rhba); 252 bfa_fcs_port_fdmi_send_rhba(fdmi, NULL); 253 break; 254 255 case FDMISM_EVENT_PORT_OFFLINE: 256 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 257 bfa_timer_stop(&fdmi->timer); 258 break; 259 260 default: 261 bfa_sm_fault(port->fcs, event); 262 } 263} 264 265/* 266* RPRT : Register Port 267 */ 268static void 269bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi, 270 enum port_fdmi_event event) 271{ 272 struct bfa_fcs_port_s *port = fdmi->ms->port; 273 274 bfa_trc(port->fcs, port->port_cfg.pwwn); 275 bfa_trc(port->fcs, event); 276 277 switch (event) { 278 case FDMISM_EVENT_RPRT_SENT: 279 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt); 280 break; 281 282 case FDMISM_EVENT_PORT_OFFLINE: 283 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 284 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 285 &fdmi->fcxp_wqe); 286 break; 287 288 default: 289 bfa_sm_fault(port->fcs, event); 290 } 291} 292 293static void 294bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi, 295 enum port_fdmi_event event) 296{ 297 struct bfa_fcs_port_s *port = fdmi->ms->port; 298 299 bfa_trc(port->fcs, port->port_cfg.pwwn); 300 bfa_trc(port->fcs, event); 301 302 switch (event) { 303 case FDMISM_EVENT_RSP_ERROR: 304 /* 305 * if max retries have not been reached, start timer for a 306 * delayed retry 307 */ 308 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 309 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt_retry); 310 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 311 &fdmi->timer, bfa_fcs_port_fdmi_timeout, 312 fdmi, BFA_FCS_RETRY_TIMEOUT); 313 314 } else { 315 /* 316 * set state to offline 317 */ 318 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 319 fdmi->retry_cnt = 0; 320 } 321 break; 322 323 case FDMISM_EVENT_RSP_OK: 324 fdmi->retry_cnt = 0; 325 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online); 326 break; 327 328 case FDMISM_EVENT_PORT_OFFLINE: 329 bfa_fcxp_discard(fdmi->fcxp); 330 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 331 break; 332 333 default: 334 bfa_sm_fault(port->fcs, event); 335 } 336} 337 338static void 339bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi, 340 enum port_fdmi_event event) 341{ 342 struct bfa_fcs_port_s *port = fdmi->ms->port; 343 344 bfa_trc(port->fcs, port->port_cfg.pwwn); 345 bfa_trc(port->fcs, event); 346 347 switch (event) { 348 case FDMISM_EVENT_TIMEOUT: 349 /* 350 * Retry Timer Expired. Re-send 351 */ 352 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rprt); 353 bfa_fcs_port_fdmi_send_rprt(fdmi, NULL); 354 break; 355 356 case FDMISM_EVENT_PORT_OFFLINE: 357 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 358 bfa_timer_stop(&fdmi->timer); 359 break; 360 361 default: 362 bfa_sm_fault(port->fcs, event); 363 } 364} 365 366/* 367 * Register Port Attributes 368 */ 369static void 370bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi, 371 enum port_fdmi_event event) 372{ 373 struct bfa_fcs_port_s *port = fdmi->ms->port; 374 375 bfa_trc(port->fcs, port->port_cfg.pwwn); 376 bfa_trc(port->fcs, event); 377 378 switch (event) { 379 case FDMISM_EVENT_RPA_SENT: 380 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa); 381 break; 382 383 case FDMISM_EVENT_PORT_OFFLINE: 384 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 385 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 386 &fdmi->fcxp_wqe); 387 break; 388 389 default: 390 bfa_sm_fault(port->fcs, event); 391 } 392} 393 394static void 395bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi, 396 enum port_fdmi_event event) 397{ 398 struct bfa_fcs_port_s *port = fdmi->ms->port; 399 400 bfa_trc(port->fcs, port->port_cfg.pwwn); 401 bfa_trc(port->fcs, event); 402 403 switch (event) { 404 case FDMISM_EVENT_RSP_ERROR: 405 /* 406 * if max retries have not been reached, start timer for a 407 * delayed retry 408 */ 409 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 410 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa_retry); 411 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 412 &fdmi->timer, bfa_fcs_port_fdmi_timeout, 413 fdmi, BFA_FCS_RETRY_TIMEOUT); 414 } else { 415 /* 416 * set state to offline 417 */ 418 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 419 fdmi->retry_cnt = 0; 420 } 421 break; 422 423 case FDMISM_EVENT_RSP_OK: 424 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online); 425 fdmi->retry_cnt = 0; 426 break; 427 428 case FDMISM_EVENT_PORT_OFFLINE: 429 bfa_fcxp_discard(fdmi->fcxp); 430 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 431 break; 432 433 default: 434 bfa_sm_fault(port->fcs, event); 435 } 436} 437 438static void 439bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi, 440 enum port_fdmi_event event) 441{ 442 struct bfa_fcs_port_s *port = fdmi->ms->port; 443 444 bfa_trc(port->fcs, port->port_cfg.pwwn); 445 bfa_trc(port->fcs, event); 446 447 switch (event) { 448 case FDMISM_EVENT_TIMEOUT: 449 /* 450 * Retry Timer Expired. Re-send 451 */ 452 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa); 453 bfa_fcs_port_fdmi_send_rpa(fdmi, NULL); 454 break; 455 456 case FDMISM_EVENT_PORT_OFFLINE: 457 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 458 bfa_timer_stop(&fdmi->timer); 459 break; 460 461 default: 462 bfa_sm_fault(port->fcs, event); 463 } 464} 465 466static void 467bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi, 468 enum port_fdmi_event event) 469{ 470 struct bfa_fcs_port_s *port = fdmi->ms->port; 471 472 bfa_trc(port->fcs, port->port_cfg.pwwn); 473 bfa_trc(port->fcs, event); 474 475 switch (event) { 476 case FDMISM_EVENT_PORT_OFFLINE: 477 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 478 break; 479 480 default: 481 bfa_sm_fault(port->fcs, event); 482 } 483} 484 485/** 486 * FDMI is disabled state. 487 */ 488static void 489bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi, 490 enum port_fdmi_event event) 491{ 492 struct bfa_fcs_port_s *port = fdmi->ms->port; 493 494 bfa_trc(port->fcs, port->port_cfg.pwwn); 495 bfa_trc(port->fcs, event); 496 497 /* No op State. It can only be enabled at Driver Init. */ 498} 499 500/** 501* RHBA : Register HBA Attributes. 502 */ 503static void 504bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 505{ 506 struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg; 507 struct bfa_fcs_port_s *port = fdmi->ms->port; 508 struct fchs_s fchs; 509 int len, attr_len; 510 struct bfa_fcxp_s *fcxp; 511 u8 *pyld; 512 513 bfa_trc(port->fcs, port->port_cfg.pwwn); 514 515 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 516 if (!fcxp) { 517 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 518 bfa_fcs_port_fdmi_send_rhba, fdmi); 519 return; 520 } 521 fdmi->fcxp = fcxp; 522 523 pyld = bfa_fcxp_get_reqbuf(fcxp); 524 bfa_os_memset(pyld, 0, FC_MAX_PDUSZ); 525 526 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port), 527 FDMI_RHBA); 528 529 attr_len = bfa_fcs_port_fdmi_build_rhba_pyld(fdmi, 530 (u8 *) ((struct ct_hdr_s *) pyld + 1)); 531 532 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 533 FC_CLASS_3, (len + attr_len), &fchs, 534 bfa_fcs_port_fdmi_rhba_response, (void *)fdmi, 535 FC_MAX_PDUSZ, FC_FCCT_TOV); 536 537 bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT); 538} 539 540static u16 541bfa_fcs_port_fdmi_build_rhba_pyld(struct bfa_fcs_port_fdmi_s *fdmi, 542 u8 *pyld) 543{ 544 struct bfa_fcs_port_s *port = fdmi->ms->port; 545 struct bfa_fcs_fdmi_hba_attr_s hba_attr; /* @todo */ 546 struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; /* @todo */ 547 struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld; 548 struct fdmi_attr_s *attr; 549 u8 *curr_ptr; 550 u16 len, count; 551 552 /* 553 * get hba attributes 554 */ 555 bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr); 556 557 rhba->hba_id = bfa_fcs_port_get_pwwn(port); 558 rhba->port_list.num_ports = bfa_os_htonl(1); 559 rhba->port_list.port_entry = bfa_fcs_port_get_pwwn(port); 560 561 len = sizeof(rhba->hba_id) + sizeof(rhba->port_list); 562 563 count = 0; 564 len += sizeof(rhba->hba_attr_blk.attr_count); 565 566 /* 567 * fill out the invididual entries of the HBA attrib Block 568 */ 569 curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr; 570 571 /* 572 * Node Name 573 */ 574 attr = (struct fdmi_attr_s *) curr_ptr; 575 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_NODENAME); 576 attr->len = sizeof(wwn_t); 577 memcpy(attr->value, &bfa_fcs_port_get_nwwn(port), attr->len); 578 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 579 len += attr->len; 580 count++; 581 attr->len = 582 bfa_os_htons(attr->len + sizeof(attr->type) + 583 sizeof(attr->len)); 584 585 /* 586 * Manufacturer 587 */ 588 attr = (struct fdmi_attr_s *) curr_ptr; 589 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MANUFACTURER); 590 attr->len = (u16) strlen(fcs_hba_attr->manufacturer); 591 memcpy(attr->value, fcs_hba_attr->manufacturer, attr->len); 592 /* variable fields need to be 4 byte aligned */ 593 attr->len = fc_roundup(attr->len, sizeof(u32)); 594 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 595 len += attr->len; 596 count++; 597 attr->len = 598 bfa_os_htons(attr->len + sizeof(attr->type) + 599 sizeof(attr->len)); 600 601 /* 602 * Serial Number 603 */ 604 attr = (struct fdmi_attr_s *) curr_ptr; 605 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_SERIALNUM); 606 attr->len = (u16) strlen(fcs_hba_attr->serial_num); 607 memcpy(attr->value, fcs_hba_attr->serial_num, attr->len); 608 /* variable fields need to be 4 byte aligned */ 609 attr->len = fc_roundup(attr->len, sizeof(u32)); 610 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 611 len += attr->len; 612 count++; 613 attr->len = 614 bfa_os_htons(attr->len + sizeof(attr->type) + 615 sizeof(attr->len)); 616 617 /* 618 * Model 619 */ 620 attr = (struct fdmi_attr_s *) curr_ptr; 621 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL); 622 attr->len = (u16) strlen(fcs_hba_attr->model); 623 memcpy(attr->value, fcs_hba_attr->model, attr->len); 624 /* variable fields need to be 4 byte aligned */ 625 attr->len = fc_roundup(attr->len, sizeof(u32)); 626 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 627 len += attr->len; 628 count++; 629 attr->len = 630 bfa_os_htons(attr->len + sizeof(attr->type) + 631 sizeof(attr->len)); 632 633 /* 634 * Model Desc 635 */ 636 attr = (struct fdmi_attr_s *) curr_ptr; 637 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL_DESC); 638 attr->len = (u16) strlen(fcs_hba_attr->model_desc); 639 memcpy(attr->value, fcs_hba_attr->model_desc, attr->len); 640 /* variable fields need to be 4 byte aligned */ 641 attr->len = fc_roundup(attr->len, sizeof(u32)); 642 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 643 len += attr->len; 644 count++; 645 attr->len = 646 bfa_os_htons(attr->len + sizeof(attr->type) + 647 sizeof(attr->len)); 648 649 /* 650 * H/W Version 651 */ 652 if (fcs_hba_attr->hw_version[0] != '\0') { 653 attr = (struct fdmi_attr_s *) curr_ptr; 654 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_HW_VERSION); 655 attr->len = (u16) strlen(fcs_hba_attr->hw_version); 656 memcpy(attr->value, fcs_hba_attr->hw_version, attr->len); 657 /* variable fields need to be 4 byte aligned */ 658 attr->len = fc_roundup(attr->len, sizeof(u32)); 659 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 660 len += attr->len; 661 count++; 662 attr->len = 663 bfa_os_htons(attr->len + sizeof(attr->type) + 664 sizeof(attr->len)); 665 } 666 667 /* 668 * Driver Version 669 */ 670 attr = (struct fdmi_attr_s *) curr_ptr; 671 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_DRIVER_VERSION); 672 attr->len = (u16) strlen(fcs_hba_attr->driver_version); 673 memcpy(attr->value, fcs_hba_attr->driver_version, attr->len); 674 /* variable fields need to be 4 byte aligned */ 675 attr->len = fc_roundup(attr->len, sizeof(u32)); 676 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 677 len += attr->len;; 678 count++; 679 attr->len = 680 bfa_os_htons(attr->len + sizeof(attr->type) + 681 sizeof(attr->len)); 682 683 /* 684 * Option Rom Version 685 */ 686 if (fcs_hba_attr->option_rom_ver[0] != '\0') { 687 attr = (struct fdmi_attr_s *) curr_ptr; 688 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_ROM_VERSION); 689 attr->len = (u16) strlen(fcs_hba_attr->option_rom_ver); 690 memcpy(attr->value, fcs_hba_attr->option_rom_ver, attr->len); 691 /* variable fields need to be 4 byte aligned */ 692 attr->len = fc_roundup(attr->len, sizeof(u32)); 693 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 694 len += attr->len; 695 count++; 696 attr->len = 697 bfa_os_htons(attr->len + sizeof(attr->type) + 698 sizeof(attr->len)); 699 } 700 701 /* 702 * f/w Version = driver version 703 */ 704 attr = (struct fdmi_attr_s *) curr_ptr; 705 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_FW_VERSION); 706 attr->len = (u16) strlen(fcs_hba_attr->driver_version); 707 memcpy(attr->value, fcs_hba_attr->driver_version, attr->len); 708 /* variable fields need to be 4 byte aligned */ 709 attr->len = fc_roundup(attr->len, sizeof(u32)); 710 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 711 len += attr->len; 712 count++; 713 attr->len = 714 bfa_os_htons(attr->len + sizeof(attr->type) + 715 sizeof(attr->len)); 716 717 /* 718 * OS Name 719 */ 720 if (fcs_hba_attr->os_name[0] != '\0') { 721 attr = (struct fdmi_attr_s *) curr_ptr; 722 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_OS_NAME); 723 attr->len = (u16) strlen(fcs_hba_attr->os_name); 724 memcpy(attr->value, fcs_hba_attr->os_name, attr->len); 725 /* variable fields need to be 4 byte aligned */ 726 attr->len = fc_roundup(attr->len, sizeof(u32)); 727 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 728 len += attr->len; 729 count++; 730 attr->len = 731 bfa_os_htons(attr->len + sizeof(attr->type) + 732 sizeof(attr->len)); 733 } 734 735 /* 736 * MAX_CT_PAYLOAD 737 */ 738 attr = (struct fdmi_attr_s *) curr_ptr; 739 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MAX_CT); 740 attr->len = sizeof(fcs_hba_attr->max_ct_pyld); 741 memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, attr->len); 742 len += attr->len; 743 count++; 744 attr->len = 745 bfa_os_htons(attr->len + sizeof(attr->type) + 746 sizeof(attr->len)); 747 748 /* 749 * Update size of payload 750 */ 751 len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 752 753 rhba->hba_attr_blk.attr_count = bfa_os_htonl(count); 754 return len; 755} 756 757static void 758bfa_fcs_port_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 759 void *cbarg, bfa_status_t req_status, 760 u32 rsp_len, u32 resid_len, 761 struct fchs_s *rsp_fchs) 762{ 763 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg; 764 struct bfa_fcs_port_s *port = fdmi->ms->port; 765 struct ct_hdr_s *cthdr = NULL; 766 767 bfa_trc(port->fcs, port->port_cfg.pwwn); 768 769 /* 770 * Sanity Checks 771 */ 772 if (req_status != BFA_STATUS_OK) { 773 bfa_trc(port->fcs, req_status); 774 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 775 return; 776 } 777 778 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 779 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); 780 781 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 782 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 783 return; 784 } 785 786 bfa_trc(port->fcs, cthdr->reason_code); 787 bfa_trc(port->fcs, cthdr->exp_code); 788 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 789} 790 791/** 792* RPRT : Register Port 793 */ 794static void 795bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 796{ 797 struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg; 798 struct bfa_fcs_port_s *port = fdmi->ms->port; 799 struct fchs_s fchs; 800 u16 len, attr_len; 801 struct bfa_fcxp_s *fcxp; 802 u8 *pyld; 803 804 bfa_trc(port->fcs, port->port_cfg.pwwn); 805 806 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 807 if (!fcxp) { 808 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 809 bfa_fcs_port_fdmi_send_rprt, fdmi); 810 return; 811 } 812 fdmi->fcxp = fcxp; 813 814 pyld = bfa_fcxp_get_reqbuf(fcxp); 815 bfa_os_memset(pyld, 0, FC_MAX_PDUSZ); 816 817 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port), 818 FDMI_RPRT); 819 820 attr_len = bfa_fcs_port_fdmi_build_rprt_pyld(fdmi, 821 (u8 *) ((struct ct_hdr_s *) pyld + 1)); 822 823 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 824 FC_CLASS_3, len + attr_len, &fchs, 825 bfa_fcs_port_fdmi_rprt_response, (void *)fdmi, 826 FC_MAX_PDUSZ, FC_FCCT_TOV); 827 828 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT); 829} 830 831/** 832 * This routine builds Port Attribute Block that used in RPA, RPRT commands. 833 */ 834static u16 835bfa_fcs_port_fdmi_build_portattr_block(struct bfa_fcs_port_fdmi_s *fdmi, 836 u8 *pyld) 837{ 838 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr; 839 struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld; 840 struct fdmi_attr_s *attr; 841 u8 *curr_ptr; 842 u16 len; 843 u8 count = 0; 844 845 /* 846 * get port attributes 847 */ 848 bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); 849 850 len = sizeof(port_attrib->attr_count); 851 852 /* 853 * fill out the invididual entries 854 */ 855 curr_ptr = (u8 *) &port_attrib->port_attr; 856 857 /* 858 * FC4 Types 859 */ 860 attr = (struct fdmi_attr_s *) curr_ptr; 861 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FC4_TYPES); 862 attr->len = sizeof(fcs_port_attr.supp_fc4_types); 863 memcpy(attr->value, fcs_port_attr.supp_fc4_types, attr->len); 864 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 865 len += attr->len; 866 ++count; 867 attr->len = 868 bfa_os_htons(attr->len + sizeof(attr->type) + 869 sizeof(attr->len)); 870 871 /* 872 * Supported Speed 873 */ 874 attr = (struct fdmi_attr_s *) curr_ptr; 875 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_SUPP_SPEED); 876 attr->len = sizeof(fcs_port_attr.supp_speed); 877 memcpy(attr->value, &fcs_port_attr.supp_speed, attr->len); 878 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 879 len += attr->len; 880 ++count; 881 attr->len = 882 bfa_os_htons(attr->len + sizeof(attr->type) + 883 sizeof(attr->len)); 884 885 /* 886 * current Port Speed 887 */ 888 attr = (struct fdmi_attr_s *) curr_ptr; 889 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_PORT_SPEED); 890 attr->len = sizeof(fcs_port_attr.curr_speed); 891 memcpy(attr->value, &fcs_port_attr.curr_speed, attr->len); 892 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 893 len += attr->len; 894 ++count; 895 attr->len = 896 bfa_os_htons(attr->len + sizeof(attr->type) + 897 sizeof(attr->len)); 898 899 /* 900 * max frame size 901 */ 902 attr = (struct fdmi_attr_s *) curr_ptr; 903 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FRAME_SIZE); 904 attr->len = sizeof(fcs_port_attr.max_frm_size); 905 memcpy(attr->value, &fcs_port_attr.max_frm_size, attr->len); 906 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 907 len += attr->len; 908 ++count; 909 attr->len = 910 bfa_os_htons(attr->len + sizeof(attr->type) + 911 sizeof(attr->len)); 912 913 /* 914 * OS Device Name 915 */ 916 if (fcs_port_attr.os_device_name[0] != '\0') { 917 attr = (struct fdmi_attr_s *) curr_ptr; 918 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_DEV_NAME); 919 attr->len = (u16) strlen(fcs_port_attr.os_device_name); 920 memcpy(attr->value, fcs_port_attr.os_device_name, attr->len); 921 /* variable fields need to be 4 byte aligned */ 922 attr->len = fc_roundup(attr->len, sizeof(u32)); 923 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 924 len += attr->len; 925 ++count; 926 attr->len = 927 bfa_os_htons(attr->len + sizeof(attr->type) + 928 sizeof(attr->len)); 929 930 } 931 /* 932 * Host Name 933 */ 934 if (fcs_port_attr.host_name[0] != '\0') { 935 attr = (struct fdmi_attr_s *) curr_ptr; 936 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_HOST_NAME); 937 attr->len = (u16) strlen(fcs_port_attr.host_name); 938 memcpy(attr->value, fcs_port_attr.host_name, attr->len); 939 /* variable fields need to be 4 byte aligned */ 940 attr->len = fc_roundup(attr->len, sizeof(u32)); 941 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 942 len += attr->len; 943 ++count; 944 attr->len = 945 bfa_os_htons(attr->len + sizeof(attr->type) + 946 sizeof(attr->len)); 947 948 } 949 950 /* 951 * Update size of payload 952 */ 953 port_attrib->attr_count = bfa_os_htonl(count); 954 len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 955 return len; 956} 957 958static u16 959bfa_fcs_port_fdmi_build_rprt_pyld(struct bfa_fcs_port_fdmi_s *fdmi, 960 u8 *pyld) 961{ 962 struct bfa_fcs_port_s *port = fdmi->ms->port; 963 struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld; 964 u16 len; 965 966 rprt->hba_id = bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs)); 967 rprt->port_name = bfa_fcs_port_get_pwwn(port); 968 969 len = bfa_fcs_port_fdmi_build_portattr_block(fdmi, 970 (u8 *) &rprt->port_attr_blk); 971 972 len += sizeof(rprt->hba_id) + sizeof(rprt->port_name); 973 974 return len; 975} 976 977static void 978bfa_fcs_port_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 979 void *cbarg, bfa_status_t req_status, 980 u32 rsp_len, u32 resid_len, 981 struct fchs_s *rsp_fchs) 982{ 983 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg; 984 struct bfa_fcs_port_s *port = fdmi->ms->port; 985 struct ct_hdr_s *cthdr = NULL; 986 987 bfa_trc(port->fcs, port->port_cfg.pwwn); 988 989 /* 990 * Sanity Checks 991 */ 992 if (req_status != BFA_STATUS_OK) { 993 bfa_trc(port->fcs, req_status); 994 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 995 return; 996 } 997 998 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 999 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); 1000 1001 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 1002 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 1003 return; 1004 } 1005 1006 bfa_trc(port->fcs, cthdr->reason_code); 1007 bfa_trc(port->fcs, cthdr->exp_code); 1008 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 1009} 1010 1011/** 1012* RPA : Register Port Attributes. 1013 */ 1014static void 1015bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1016{ 1017 struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg; 1018 struct bfa_fcs_port_s *port = fdmi->ms->port; 1019 struct fchs_s fchs; 1020 u16 len, attr_len; 1021 struct bfa_fcxp_s *fcxp; 1022 u8 *pyld; 1023 1024 bfa_trc(port->fcs, port->port_cfg.pwwn); 1025 1026 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1027 if (!fcxp) { 1028 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1029 bfa_fcs_port_fdmi_send_rpa, fdmi); 1030 return; 1031 } 1032 fdmi->fcxp = fcxp; 1033 1034 pyld = bfa_fcxp_get_reqbuf(fcxp); 1035 bfa_os_memset(pyld, 0, FC_MAX_PDUSZ); 1036 1037 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port), 1038 FDMI_RPA); 1039 1040 attr_len = bfa_fcs_port_fdmi_build_rpa_pyld(fdmi, 1041 (u8 *) ((struct ct_hdr_s *) pyld + 1)); 1042 1043 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1044 FC_CLASS_3, len + attr_len, &fchs, 1045 bfa_fcs_port_fdmi_rpa_response, (void *)fdmi, 1046 FC_MAX_PDUSZ, FC_FCCT_TOV); 1047 1048 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT); 1049} 1050 1051static u16 1052bfa_fcs_port_fdmi_build_rpa_pyld(struct bfa_fcs_port_fdmi_s *fdmi, 1053 u8 *pyld) 1054{ 1055 struct bfa_fcs_port_s *port = fdmi->ms->port; 1056 struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld; 1057 u16 len; 1058 1059 rpa->port_name = bfa_fcs_port_get_pwwn(port); 1060 1061 len = bfa_fcs_port_fdmi_build_portattr_block(fdmi, 1062 (u8 *) &rpa->port_attr_blk); 1063 1064 len += sizeof(rpa->port_name); 1065 1066 return len; 1067} 1068 1069static void 1070bfa_fcs_port_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 1071 void *cbarg, bfa_status_t req_status, 1072 u32 rsp_len, u32 resid_len, 1073 struct fchs_s *rsp_fchs) 1074{ 1075 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg; 1076 struct bfa_fcs_port_s *port = fdmi->ms->port; 1077 struct ct_hdr_s *cthdr = NULL; 1078 1079 bfa_trc(port->fcs, port->port_cfg.pwwn); 1080 1081 /* 1082 * Sanity Checks 1083 */ 1084 if (req_status != BFA_STATUS_OK) { 1085 bfa_trc(port->fcs, req_status); 1086 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 1087 return; 1088 } 1089 1090 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 1091 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); 1092 1093 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 1094 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 1095 return; 1096 } 1097 1098 bfa_trc(port->fcs, cthdr->reason_code); 1099 bfa_trc(port->fcs, cthdr->exp_code); 1100 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 1101} 1102 1103static void 1104bfa_fcs_port_fdmi_timeout(void *arg) 1105{ 1106 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)arg; 1107 1108 bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT); 1109} 1110 1111static void 1112bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi, 1113 struct bfa_fcs_fdmi_hba_attr_s *hba_attr) 1114{ 1115 struct bfa_fcs_port_s *port = fdmi->ms->port; 1116 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 1117 1118 bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); 1119 1120 bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc, 1121 hba_attr->manufacturer); 1122 bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc, 1123 hba_attr->serial_num); 1124 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model); 1125 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model_desc); 1126 bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, hba_attr->hw_version); 1127 bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc, 1128 hba_attr->option_rom_ver); 1129 bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, hba_attr->fw_version); 1130 1131 strncpy(hba_attr->driver_version, (char *)driver_info->version, 1132 sizeof(hba_attr->driver_version)); 1133 1134 strncpy(hba_attr->os_name, driver_info->host_os_name, 1135 sizeof(hba_attr->os_name)); 1136 1137 /* 1138 * If there is a patch level, append it to the os name along with a 1139 * separator 1140 */ 1141 if (driver_info->host_os_patch[0] != '\0') { 1142 strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, 1143 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); 1144 strncat(hba_attr->os_name, driver_info->host_os_patch, 1145 sizeof(driver_info->host_os_patch)); 1146 } 1147 1148 hba_attr->max_ct_pyld = bfa_os_htonl(FC_MAX_PDUSZ); 1149 1150} 1151 1152static void 1153bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi, 1154 struct bfa_fcs_fdmi_port_attr_s *port_attr) 1155{ 1156 struct bfa_fcs_port_s *port = fdmi->ms->port; 1157 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 1158 struct bfa_pport_attr_s pport_attr; 1159 1160 bfa_os_memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s)); 1161 1162 /* 1163 * get pport attributes from hal 1164 */ 1165 bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); 1166 1167 /* 1168 * get FC4 type Bitmask 1169 */ 1170 fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types); 1171 1172 /* 1173 * Supported Speeds 1174 */ 1175 port_attr->supp_speed = bfa_os_htonl(BFA_FCS_FDMI_SUPORTED_SPEEDS); 1176 1177 /* 1178 * Current Speed 1179 */ 1180 port_attr->curr_speed = bfa_os_htonl(pport_attr.speed); 1181 1182 /* 1183 * Max PDU Size. 1184 */ 1185 port_attr->max_frm_size = bfa_os_htonl(FC_MAX_PDUSZ); 1186 1187 /* 1188 * OS device Name 1189 */ 1190 strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name, 1191 sizeof(port_attr->os_device_name)); 1192 1193 /* 1194 * Host name 1195 */ 1196 strncpy(port_attr->host_name, (char *)driver_info->host_machine_name, 1197 sizeof(port_attr->host_name)); 1198 1199} 1200 1201 1202void 1203bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms) 1204{ 1205 struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi; 1206 1207 fdmi->ms = ms; 1208 if (ms->port->fcs->fdmi_enabled) 1209 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 1210 else 1211 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_disabled); 1212} 1213 1214void 1215bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s *ms) 1216{ 1217 struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi; 1218 1219 fdmi->ms = ms; 1220 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE); 1221} 1222 1223void 1224bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s *ms) 1225{ 1226 struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi; 1227 1228 fdmi->ms = ms; 1229 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE); 1230} 1231