linux/drivers/scsi/bfa/bfa_port.c
<<
>>
Prefs
   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
  18BFA_TRC_FILE(CNA, PORT);
  19
  20static void
  21bfa_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 */
  50static void
  51bfa_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 */
  67static void
  68bfa_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 */
  84static void
  85bfa_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 */
 113static void
 114bfa_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 */
 138static void
 139bfa_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 */
 186u32
 187bfa_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 */
 202void
 203bfa_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 */
 218bfa_status_t
 219bfa_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 */
 274bfa_status_t
 275bfa_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 */
 330bfa_status_t
 331bfa_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 */
 369bfa_status_t
 370bfa_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 */
 408void
 409bfa_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 */
 456void
 457bfa_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 */
 495void
 496bfa_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 */
 515static void
 516bfa_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 */
 547static void
 548bfa_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 */
 583static void
 584bfa_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 */
 601u32
 602bfa_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 */
 619void
 620bfa_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
 644bfa_status_t
 645bfa_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
 684bfa_status_t
 685bfa_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
 723bfa_status_t
 724bfa_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
 759static void
 760bfa_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
 795static void
 796bfa_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 */
 852void
 853bfa_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