1 /* 2 * Copyright (c) 2005-2010 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 #include "bfad_drv.h" 19 #include "bfa_defs_svc.h" 20 #include "bfa_port.h" 21 #include "bfi.h" 22 #include "bfa_ioc.h" 23 24 25 BFA_TRC_FILE(CNA, PORT); 26 27 static void 28 bfa_port_stats_swap(struct bfa_port_s *port, union bfa_port_stats_u *stats) 29 { 30 u32 *dip = (u32 *) stats; 31 __be32 t0, t1; 32 int i; 33 34 for (i = 0; i < sizeof(union bfa_port_stats_u)/sizeof(u32); 35 i += 2) { 36 t0 = dip[i]; 37 t1 = dip[i + 1]; 38 #ifdef __BIG_ENDIAN 39 dip[i] = be32_to_cpu(t0); 40 dip[i + 1] = be32_to_cpu(t1); 41 #else 42 dip[i] = be32_to_cpu(t1); 43 dip[i + 1] = be32_to_cpu(t0); 44 #endif 45 } 46 } 47 48 /* 49 * bfa_port_enable_isr() 50 * 51 * 52 * @param[in] port - Pointer to the port module 53 * status - Return status from the f/w 54 * 55 * @return void 56 */ 57 static void 58 bfa_port_enable_isr(struct bfa_port_s *port, bfa_status_t status) 59 { 60 bfa_trc(port, status); 61 port->endis_pending = BFA_FALSE; 62 port->endis_cbfn(port->endis_cbarg, status); 63 } 64 65 /* 66 * bfa_port_disable_isr() 67 * 68 * 69 * @param[in] port - Pointer to the port module 70 * status - Return status from the f/w 71 * 72 * @return void 73 */ 74 static void 75 bfa_port_disable_isr(struct bfa_port_s *port, bfa_status_t status) 76 { 77 bfa_trc(port, status); 78 port->endis_pending = BFA_FALSE; 79 port->endis_cbfn(port->endis_cbarg, status); 80 } 81 82 /* 83 * bfa_port_get_stats_isr() 84 * 85 * 86 * @param[in] port - Pointer to the Port module 87 * status - Return status from the f/w 88 * 89 * @return void 90 */ 91 static void 92 bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status) 93 { 94 port->stats_status = status; 95 port->stats_busy = BFA_FALSE; 96 97 if (status == BFA_STATUS_OK) { 98 struct timeval tv; 99 100 memcpy(port->stats, port->stats_dma.kva, 101 sizeof(union bfa_port_stats_u)); 102 bfa_port_stats_swap(port, port->stats); 103 104 do_gettimeofday(&tv); 105 port->stats->fc.secs_reset = tv.tv_sec - port->stats_reset_time; 106 } 107 108 if (port->stats_cbfn) { 109 port->stats_cbfn(port->stats_cbarg, status); 110 port->stats_cbfn = NULL; 111 } 112 } 113 114 /* 115 * bfa_port_clear_stats_isr() 116 * 117 * 118 * @param[in] port - Pointer to the Port module 119 * status - Return status from the f/w 120 * 121 * @return void 122 */ 123 static void 124 bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status) 125 { 126 struct timeval tv; 127 128 port->stats_status = status; 129 port->stats_busy = BFA_FALSE; 130 131 /* 132 * re-initialize time stamp for stats reset 133 */ 134 do_gettimeofday(&tv); 135 port->stats_reset_time = tv.tv_sec; 136 137 if (port->stats_cbfn) { 138 port->stats_cbfn(port->stats_cbarg, status); 139 port->stats_cbfn = NULL; 140 } 141 } 142 143 /* 144 * bfa_port_isr() 145 * 146 * 147 * @param[in] Pointer to the Port module data structure. 148 * 149 * @return void 150 */ 151 static void 152 bfa_port_isr(void *cbarg, struct bfi_mbmsg_s *m) 153 { 154 struct bfa_port_s *port = (struct bfa_port_s *) cbarg; 155 union bfi_port_i2h_msg_u *i2hmsg; 156 157 i2hmsg = (union bfi_port_i2h_msg_u *) m; 158 bfa_trc(port, m->mh.msg_id); 159 160 switch (m->mh.msg_id) { 161 case BFI_PORT_I2H_ENABLE_RSP: 162 if (port->endis_pending == BFA_FALSE) 163 break; 164 bfa_port_enable_isr(port, i2hmsg->enable_rsp.status); 165 break; 166 167 case BFI_PORT_I2H_DISABLE_RSP: 168 if (port->endis_pending == BFA_FALSE) 169 break; 170 bfa_port_disable_isr(port, i2hmsg->disable_rsp.status); 171 break; 172 173 case BFI_PORT_I2H_GET_STATS_RSP: 174 /* Stats busy flag is still set? (may be cmd timed out) */ 175 if (port->stats_busy == BFA_FALSE) 176 break; 177 bfa_port_get_stats_isr(port, i2hmsg->getstats_rsp.status); 178 break; 179 180 case BFI_PORT_I2H_CLEAR_STATS_RSP: 181 if (port->stats_busy == BFA_FALSE) 182 break; 183 bfa_port_clear_stats_isr(port, i2hmsg->clearstats_rsp.status); 184 break; 185 186 default: 187 WARN_ON(1); 188 } 189 } 190 191 /* 192 * bfa_port_meminfo() 193 * 194 * 195 * @param[in] void 196 * 197 * @return Size of DMA region 198 */ 199 u32 200 bfa_port_meminfo(void) 201 { 202 return BFA_ROUNDUP(sizeof(union bfa_port_stats_u), BFA_DMA_ALIGN_SZ); 203 } 204 205 /* 206 * bfa_port_mem_claim() 207 * 208 * 209 * @param[in] port Port module pointer 210 * dma_kva Kernel Virtual Address of Port DMA Memory 211 * dma_pa Physical Address of Port DMA Memory 212 * 213 * @return void 214 */ 215 void 216 bfa_port_mem_claim(struct bfa_port_s *port, u8 *dma_kva, u64 dma_pa) 217 { 218 port->stats_dma.kva = dma_kva; 219 port->stats_dma.pa = dma_pa; 220 } 221 222 /* 223 * bfa_port_enable() 224 * 225 * Send the Port enable request to the f/w 226 * 227 * @param[in] Pointer to the Port module data structure. 228 * 229 * @return Status 230 */ 231 bfa_status_t 232 bfa_port_enable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn, 233 void *cbarg) 234 { 235 struct bfi_port_generic_req_s *m; 236 237 /* If port is PBC disabled, return error */ 238 if (port->pbc_disabled) { 239 bfa_trc(port, BFA_STATUS_PBC); 240 return BFA_STATUS_PBC; 241 } 242 243 if (bfa_ioc_is_disabled(port->ioc)) { 244 bfa_trc(port, BFA_STATUS_IOC_DISABLED); 245 return BFA_STATUS_IOC_DISABLED; 246 } 247 248 if (!bfa_ioc_is_operational(port->ioc)) { 249 bfa_trc(port, BFA_STATUS_IOC_FAILURE); 250 return BFA_STATUS_IOC_FAILURE; 251 } 252 253 /* if port is d-port enabled, return error */ 254 if (port->dport_enabled) { 255 bfa_trc(port, BFA_STATUS_DPORT_ERR); 256 return BFA_STATUS_DPORT_ERR; 257 } 258 259 if (port->endis_pending) { 260 bfa_trc(port, BFA_STATUS_DEVBUSY); 261 return BFA_STATUS_DEVBUSY; 262 } 263 264 m = (struct bfi_port_generic_req_s *) port->endis_mb.msg; 265 266 port->msgtag++; 267 port->endis_cbfn = cbfn; 268 port->endis_cbarg = cbarg; 269 port->endis_pending = BFA_TRUE; 270 271 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_ENABLE_REQ, 272 bfa_ioc_portid(port->ioc)); 273 bfa_ioc_mbox_queue(port->ioc, &port->endis_mb); 274 275 return BFA_STATUS_OK; 276 } 277 278 /* 279 * bfa_port_disable() 280 * 281 * Send the Port disable request to the f/w 282 * 283 * @param[in] Pointer to the Port module data structure. 284 * 285 * @return Status 286 */ 287 bfa_status_t 288 bfa_port_disable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn, 289 void *cbarg) 290 { 291 struct bfi_port_generic_req_s *m; 292 293 /* If port is PBC disabled, return error */ 294 if (port->pbc_disabled) { 295 bfa_trc(port, BFA_STATUS_PBC); 296 return BFA_STATUS_PBC; 297 } 298 299 if (bfa_ioc_is_disabled(port->ioc)) { 300 bfa_trc(port, BFA_STATUS_IOC_DISABLED); 301 return BFA_STATUS_IOC_DISABLED; 302 } 303 304 if (!bfa_ioc_is_operational(port->ioc)) { 305 bfa_trc(port, BFA_STATUS_IOC_FAILURE); 306 return BFA_STATUS_IOC_FAILURE; 307 } 308 309 /* if port is d-port enabled, return error */ 310 if (port->dport_enabled) { 311 bfa_trc(port, BFA_STATUS_DPORT_ERR); 312 return BFA_STATUS_DPORT_ERR; 313 } 314 315 if (port->endis_pending) { 316 bfa_trc(port, BFA_STATUS_DEVBUSY); 317 return BFA_STATUS_DEVBUSY; 318 } 319 320 m = (struct bfi_port_generic_req_s *) port->endis_mb.msg; 321 322 port->msgtag++; 323 port->endis_cbfn = cbfn; 324 port->endis_cbarg = cbarg; 325 port->endis_pending = BFA_TRUE; 326 327 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_DISABLE_REQ, 328 bfa_ioc_portid(port->ioc)); 329 bfa_ioc_mbox_queue(port->ioc, &port->endis_mb); 330 331 return BFA_STATUS_OK; 332 } 333 334 /* 335 * bfa_port_get_stats() 336 * 337 * Send the request to the f/w to fetch Port statistics. 338 * 339 * @param[in] Pointer to the Port module data structure. 340 * 341 * @return Status 342 */ 343 bfa_status_t 344 bfa_port_get_stats(struct bfa_port_s *port, union bfa_port_stats_u *stats, 345 bfa_port_stats_cbfn_t cbfn, void *cbarg) 346 { 347 struct bfi_port_get_stats_req_s *m; 348 349 if (!bfa_ioc_is_operational(port->ioc)) { 350 bfa_trc(port, BFA_STATUS_IOC_FAILURE); 351 return BFA_STATUS_IOC_FAILURE; 352 } 353 354 if (port->stats_busy) { 355 bfa_trc(port, BFA_STATUS_DEVBUSY); 356 return BFA_STATUS_DEVBUSY; 357 } 358 359 m = (struct bfi_port_get_stats_req_s *) port->stats_mb.msg; 360 361 port->stats = stats; 362 port->stats_cbfn = cbfn; 363 port->stats_cbarg = cbarg; 364 port->stats_busy = BFA_TRUE; 365 bfa_dma_be_addr_set(m->dma_addr, port->stats_dma.pa); 366 367 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_GET_STATS_REQ, 368 bfa_ioc_portid(port->ioc)); 369 bfa_ioc_mbox_queue(port->ioc, &port->stats_mb); 370 371 return BFA_STATUS_OK; 372 } 373 374 /* 375 * bfa_port_clear_stats() 376 * 377 * 378 * @param[in] Pointer to the Port module data structure. 379 * 380 * @return Status 381 */ 382 bfa_status_t 383 bfa_port_clear_stats(struct bfa_port_s *port, bfa_port_stats_cbfn_t cbfn, 384 void *cbarg) 385 { 386 struct bfi_port_generic_req_s *m; 387 388 if (!bfa_ioc_is_operational(port->ioc)) { 389 bfa_trc(port, BFA_STATUS_IOC_FAILURE); 390 return BFA_STATUS_IOC_FAILURE; 391 } 392 393 if (port->stats_busy) { 394 bfa_trc(port, BFA_STATUS_DEVBUSY); 395 return BFA_STATUS_DEVBUSY; 396 } 397 398 m = (struct bfi_port_generic_req_s *) port->stats_mb.msg; 399 400 port->stats_cbfn = cbfn; 401 port->stats_cbarg = cbarg; 402 port->stats_busy = BFA_TRUE; 403 404 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_CLEAR_STATS_REQ, 405 bfa_ioc_portid(port->ioc)); 406 bfa_ioc_mbox_queue(port->ioc, &port->stats_mb); 407 408 return BFA_STATUS_OK; 409 } 410 411 /* 412 * bfa_port_notify() 413 * 414 * Port module IOC event handler 415 * 416 * @param[in] Pointer to the Port module data structure. 417 * @param[in] IOC event structure 418 * 419 * @return void 420 */ 421 void 422 bfa_port_notify(void *arg, enum bfa_ioc_event_e event) 423 { 424 struct bfa_port_s *port = (struct bfa_port_s *) arg; 425 426 switch (event) { 427 case BFA_IOC_E_DISABLED: 428 case BFA_IOC_E_FAILED: 429 /* Fail any pending get_stats/clear_stats requests */ 430 if (port->stats_busy) { 431 if (port->stats_cbfn) 432 port->stats_cbfn(port->stats_cbarg, 433 BFA_STATUS_FAILED); 434 port->stats_cbfn = NULL; 435 port->stats_busy = BFA_FALSE; 436 } 437 438 /* Clear any enable/disable is pending */ 439 if (port->endis_pending) { 440 if (port->endis_cbfn) 441 port->endis_cbfn(port->endis_cbarg, 442 BFA_STATUS_FAILED); 443 port->endis_cbfn = NULL; 444 port->endis_pending = BFA_FALSE; 445 } 446 447 /* clear D-port mode */ 448 if (port->dport_enabled) 449 bfa_port_set_dportenabled(port, BFA_FALSE); 450 break; 451 default: 452 break; 453 } 454 } 455 456 /* 457 * bfa_port_attach() 458 * 459 * 460 * @param[in] port - Pointer to the Port module data structure 461 * ioc - Pointer to the ioc module data structure 462 * dev - Pointer to the device driver module data structure 463 * The device driver specific mbox ISR functions have 464 * this pointer as one of the parameters. 465 * trcmod - 466 * 467 * @return void 468 */ 469 void 470 bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, 471 void *dev, struct bfa_trc_mod_s *trcmod) 472 { 473 struct timeval tv; 474 475 WARN_ON(!port); 476 477 port->dev = dev; 478 port->ioc = ioc; 479 port->trcmod = trcmod; 480 481 port->stats_busy = BFA_FALSE; 482 port->endis_pending = BFA_FALSE; 483 port->stats_cbfn = NULL; 484 port->endis_cbfn = NULL; 485 port->pbc_disabled = BFA_FALSE; 486 port->dport_enabled = BFA_FALSE; 487 488 bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port); 489 bfa_q_qe_init(&port->ioc_notify); 490 bfa_ioc_notify_init(&port->ioc_notify, bfa_port_notify, port); 491 list_add_tail(&port->ioc_notify.qe, &port->ioc->notify_q); 492 493 /* 494 * initialize time stamp for stats reset 495 */ 496 do_gettimeofday(&tv); 497 port->stats_reset_time = tv.tv_sec; 498 499 bfa_trc(port, 0); 500 } 501 502 /* 503 * bfa_port_set_dportenabled(); 504 * 505 * Port module- set pbc disabled flag 506 * 507 * @param[in] port - Pointer to the Port module data structure 508 * 509 * @return void 510 */ 511 void 512 bfa_port_set_dportenabled(struct bfa_port_s *port, bfa_boolean_t enabled) 513 { 514 port->dport_enabled = enabled; 515 } 516 517 /* 518 * CEE module specific definitions 519 */ 520 521 /* 522 * bfa_cee_get_attr_isr() 523 * 524 * @brief CEE ISR for get-attributes responses from f/w 525 * 526 * @param[in] cee - Pointer to the CEE module 527 * status - Return status from the f/w 528 * 529 * @return void 530 */ 531 static void 532 bfa_cee_get_attr_isr(struct bfa_cee_s *cee, bfa_status_t status) 533 { 534 struct bfa_cee_lldp_cfg_s *lldp_cfg = &cee->attr->lldp_remote; 535 536 cee->get_attr_status = status; 537 bfa_trc(cee, 0); 538 if (status == BFA_STATUS_OK) { 539 bfa_trc(cee, 0); 540 memcpy(cee->attr, cee->attr_dma.kva, 541 sizeof(struct bfa_cee_attr_s)); 542 lldp_cfg->time_to_live = be16_to_cpu(lldp_cfg->time_to_live); 543 lldp_cfg->enabled_system_cap = 544 be16_to_cpu(lldp_cfg->enabled_system_cap); 545 } 546 cee->get_attr_pending = BFA_FALSE; 547 if (cee->cbfn.get_attr_cbfn) { 548 bfa_trc(cee, 0); 549 cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status); 550 } 551 } 552 553 /* 554 * bfa_cee_get_stats_isr() 555 * 556 * @brief CEE ISR for get-stats responses from f/w 557 * 558 * @param[in] cee - Pointer to the CEE module 559 * status - Return status from the f/w 560 * 561 * @return void 562 */ 563 static void 564 bfa_cee_get_stats_isr(struct bfa_cee_s *cee, bfa_status_t status) 565 { 566 u32 *buffer; 567 int i; 568 569 cee->get_stats_status = status; 570 bfa_trc(cee, 0); 571 if (status == BFA_STATUS_OK) { 572 bfa_trc(cee, 0); 573 memcpy(cee->stats, cee->stats_dma.kva, 574 sizeof(struct bfa_cee_stats_s)); 575 /* swap the cee stats */ 576 buffer = (u32 *)cee->stats; 577 for (i = 0; i < (sizeof(struct bfa_cee_stats_s) / 578 sizeof(u32)); i++) 579 buffer[i] = cpu_to_be32(buffer[i]); 580 } 581 cee->get_stats_pending = BFA_FALSE; 582 bfa_trc(cee, 0); 583 if (cee->cbfn.get_stats_cbfn) { 584 bfa_trc(cee, 0); 585 cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status); 586 } 587 } 588 589 /* 590 * bfa_cee_reset_stats_isr() 591 * 592 * @brief CEE ISR for reset-stats responses from f/w 593 * 594 * @param[in] cee - Pointer to the CEE module 595 * status - Return status from the f/w 596 * 597 * @return void 598 */ 599 static void 600 bfa_cee_reset_stats_isr(struct bfa_cee_s *cee, bfa_status_t status) 601 { 602 cee->reset_stats_status = status; 603 cee->reset_stats_pending = BFA_FALSE; 604 if (cee->cbfn.reset_stats_cbfn) 605 cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status); 606 } 607 608 /* 609 * bfa_cee_meminfo() 610 * 611 * @brief Returns the size of the DMA memory needed by CEE module 612 * 613 * @param[in] void 614 * 615 * @return Size of DMA region 616 */ 617 u32 618 bfa_cee_meminfo(void) 619 { 620 return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ) + 621 BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s), BFA_DMA_ALIGN_SZ); 622 } 623 624 /* 625 * bfa_cee_mem_claim() 626 * 627 * @brief Initialized CEE DMA Memory 628 * 629 * @param[in] cee CEE module pointer 630 * dma_kva Kernel Virtual Address of CEE DMA Memory 631 * dma_pa Physical Address of CEE DMA Memory 632 * 633 * @return void 634 */ 635 void 636 bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa) 637 { 638 cee->attr_dma.kva = dma_kva; 639 cee->attr_dma.pa = dma_pa; 640 cee->stats_dma.kva = dma_kva + BFA_ROUNDUP( 641 sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ); 642 cee->stats_dma.pa = dma_pa + BFA_ROUNDUP( 643 sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ); 644 cee->attr = (struct bfa_cee_attr_s *) dma_kva; 645 cee->stats = (struct bfa_cee_stats_s *) (dma_kva + BFA_ROUNDUP( 646 sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ)); 647 } 648 649 /* 650 * bfa_cee_get_attr() 651 * 652 * @brief 653 * Send the request to the f/w to fetch CEE attributes. 654 * 655 * @param[in] Pointer to the CEE module data structure. 656 * 657 * @return Status 658 */ 659 660 bfa_status_t 661 bfa_cee_get_attr(struct bfa_cee_s *cee, struct bfa_cee_attr_s *attr, 662 bfa_cee_get_attr_cbfn_t cbfn, void *cbarg) 663 { 664 struct bfi_cee_get_req_s *cmd; 665 666 WARN_ON((cee == NULL) || (cee->ioc == NULL)); 667 bfa_trc(cee, 0); 668 if (!bfa_ioc_is_operational(cee->ioc)) { 669 bfa_trc(cee, 0); 670 return BFA_STATUS_IOC_FAILURE; 671 } 672 if (cee->get_attr_pending == BFA_TRUE) { 673 bfa_trc(cee, 0); 674 return BFA_STATUS_DEVBUSY; 675 } 676 cee->get_attr_pending = BFA_TRUE; 677 cmd = (struct bfi_cee_get_req_s *) cee->get_cfg_mb.msg; 678 cee->attr = attr; 679 cee->cbfn.get_attr_cbfn = cbfn; 680 cee->cbfn.get_attr_cbarg = cbarg; 681 bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ, 682 bfa_ioc_portid(cee->ioc)); 683 bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa); 684 bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb); 685 686 return BFA_STATUS_OK; 687 } 688 689 /* 690 * bfa_cee_get_stats() 691 * 692 * @brief 693 * Send the request to the f/w to fetch CEE statistics. 694 * 695 * @param[in] Pointer to the CEE module data structure. 696 * 697 * @return Status 698 */ 699 700 bfa_status_t 701 bfa_cee_get_stats(struct bfa_cee_s *cee, struct bfa_cee_stats_s *stats, 702 bfa_cee_get_stats_cbfn_t cbfn, void *cbarg) 703 { 704 struct bfi_cee_get_req_s *cmd; 705 706 WARN_ON((cee == NULL) || (cee->ioc == NULL)); 707 708 if (!bfa_ioc_is_operational(cee->ioc)) { 709 bfa_trc(cee, 0); 710 return BFA_STATUS_IOC_FAILURE; 711 } 712 if (cee->get_stats_pending == BFA_TRUE) { 713 bfa_trc(cee, 0); 714 return BFA_STATUS_DEVBUSY; 715 } 716 cee->get_stats_pending = BFA_TRUE; 717 cmd = (struct bfi_cee_get_req_s *) cee->get_stats_mb.msg; 718 cee->stats = stats; 719 cee->cbfn.get_stats_cbfn = cbfn; 720 cee->cbfn.get_stats_cbarg = cbarg; 721 bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ, 722 bfa_ioc_portid(cee->ioc)); 723 bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa); 724 bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb); 725 726 return BFA_STATUS_OK; 727 } 728 729 /* 730 * bfa_cee_reset_stats() 731 * 732 * @brief Clears CEE Stats in the f/w. 733 * 734 * @param[in] Pointer to the CEE module data structure. 735 * 736 * @return Status 737 */ 738 739 bfa_status_t 740 bfa_cee_reset_stats(struct bfa_cee_s *cee, 741 bfa_cee_reset_stats_cbfn_t cbfn, void *cbarg) 742 { 743 struct bfi_cee_reset_stats_s *cmd; 744 745 WARN_ON((cee == NULL) || (cee->ioc == NULL)); 746 if (!bfa_ioc_is_operational(cee->ioc)) { 747 bfa_trc(cee, 0); 748 return BFA_STATUS_IOC_FAILURE; 749 } 750 if (cee->reset_stats_pending == BFA_TRUE) { 751 bfa_trc(cee, 0); 752 return BFA_STATUS_DEVBUSY; 753 } 754 cee->reset_stats_pending = BFA_TRUE; 755 cmd = (struct bfi_cee_reset_stats_s *) cee->reset_stats_mb.msg; 756 cee->cbfn.reset_stats_cbfn = cbfn; 757 cee->cbfn.reset_stats_cbarg = cbarg; 758 bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS, 759 bfa_ioc_portid(cee->ioc)); 760 bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb); 761 762 return BFA_STATUS_OK; 763 } 764 765 /* 766 * bfa_cee_isrs() 767 * 768 * @brief Handles Mail-box interrupts for CEE module. 769 * 770 * @param[in] Pointer to the CEE module data structure. 771 * 772 * @return void 773 */ 774 775 void 776 bfa_cee_isr(void *cbarg, struct bfi_mbmsg_s *m) 777 { 778 union bfi_cee_i2h_msg_u *msg; 779 struct bfi_cee_get_rsp_s *get_rsp; 780 struct bfa_cee_s *cee = (struct bfa_cee_s *) cbarg; 781 msg = (union bfi_cee_i2h_msg_u *) m; 782 get_rsp = (struct bfi_cee_get_rsp_s *) m; 783 bfa_trc(cee, msg->mh.msg_id); 784 switch (msg->mh.msg_id) { 785 case BFI_CEE_I2H_GET_CFG_RSP: 786 bfa_trc(cee, get_rsp->cmd_status); 787 bfa_cee_get_attr_isr(cee, get_rsp->cmd_status); 788 break; 789 case BFI_CEE_I2H_GET_STATS_RSP: 790 bfa_cee_get_stats_isr(cee, get_rsp->cmd_status); 791 break; 792 case BFI_CEE_I2H_RESET_STATS_RSP: 793 bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status); 794 break; 795 default: 796 WARN_ON(1); 797 } 798 } 799 800 /* 801 * bfa_cee_notify() 802 * 803 * @brief CEE module IOC event handler. 804 * 805 * @param[in] Pointer to the CEE module data structure. 806 * @param[in] IOC event type 807 * 808 * @return void 809 */ 810 811 void 812 bfa_cee_notify(void *arg, enum bfa_ioc_event_e event) 813 { 814 struct bfa_cee_s *cee = (struct bfa_cee_s *) arg; 815 816 bfa_trc(cee, event); 817 818 switch (event) { 819 case BFA_IOC_E_DISABLED: 820 case BFA_IOC_E_FAILED: 821 if (cee->get_attr_pending == BFA_TRUE) { 822 cee->get_attr_status = BFA_STATUS_FAILED; 823 cee->get_attr_pending = BFA_FALSE; 824 if (cee->cbfn.get_attr_cbfn) { 825 cee->cbfn.get_attr_cbfn( 826 cee->cbfn.get_attr_cbarg, 827 BFA_STATUS_FAILED); 828 } 829 } 830 if (cee->get_stats_pending == BFA_TRUE) { 831 cee->get_stats_status = BFA_STATUS_FAILED; 832 cee->get_stats_pending = BFA_FALSE; 833 if (cee->cbfn.get_stats_cbfn) { 834 cee->cbfn.get_stats_cbfn( 835 cee->cbfn.get_stats_cbarg, 836 BFA_STATUS_FAILED); 837 } 838 } 839 if (cee->reset_stats_pending == BFA_TRUE) { 840 cee->reset_stats_status = BFA_STATUS_FAILED; 841 cee->reset_stats_pending = BFA_FALSE; 842 if (cee->cbfn.reset_stats_cbfn) { 843 cee->cbfn.reset_stats_cbfn( 844 cee->cbfn.reset_stats_cbarg, 845 BFA_STATUS_FAILED); 846 } 847 } 848 break; 849 850 default: 851 break; 852 } 853 } 854 855 /* 856 * bfa_cee_attach() 857 * 858 * @brief CEE module-attach API 859 * 860 * @param[in] cee - Pointer to the CEE module data structure 861 * ioc - Pointer to the ioc module data structure 862 * dev - Pointer to the device driver module data structure 863 * The device driver specific mbox ISR functions have 864 * this pointer as one of the parameters. 865 * 866 * @return void 867 */ 868 void 869 bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc, 870 void *dev) 871 { 872 WARN_ON(cee == NULL); 873 cee->dev = dev; 874 cee->ioc = ioc; 875 876 bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee); 877 bfa_q_qe_init(&cee->ioc_notify); 878 bfa_ioc_notify_init(&cee->ioc_notify, bfa_cee_notify, cee); 879 list_add_tail(&cee->ioc_notify.qe, &cee->ioc->notify_q); 880 } 881