Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.7-rc6 881 lines 20 kB view raw
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 26BFA_TRC_FILE(CNA, PORT); 27 28static void 29bfa_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 */ 58static void 59bfa_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 */ 75static void 76bfa_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 */ 92static void 93bfa_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 */ 124static void 125bfa_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 */ 152static void 153bfa_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 */ 200u32 201bfa_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 */ 216void 217bfa_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 */ 232bfa_status_t 233bfa_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 */ 288bfa_status_t 289bfa_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 */ 344bfa_status_t 345bfa_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 */ 383bfa_status_t 384bfa_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 */ 422void 423bfa_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 */ 470void 471bfa_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 */ 512void 513bfa_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 */ 532static void 533bfa_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 */ 564static void 565bfa_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 */ 600static void 601bfa_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 */ 618u32 619bfa_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 */ 636void 637bfa_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 661bfa_status_t 662bfa_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 701bfa_status_t 702bfa_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 740bfa_status_t 741bfa_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 776void 777bfa_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 812void 813bfa_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 */ 869void 870bfa_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}