linux/drivers/scsi/bfa/bfa_port.c
<<
>>
Prefs
   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}
 882