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