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