Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
0004  * Copyright (c) 2014- QLogic Corporation.
0005  * All rights reserved
0006  * www.qlogic.com
0007  *
0008  * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
0009  */
0010 
0011 #include "bfad_drv.h"
0012 #include "bfa_defs_svc.h"
0013 #include "bfa_port.h"
0014 #include "bfi.h"
0015 #include "bfa_ioc.h"
0016 
0017 
0018 BFA_TRC_FILE(CNA, PORT);
0019 
0020 static void
0021 bfa_port_stats_swap(struct bfa_port_s *port, union bfa_port_stats_u *stats)
0022 {
0023     u32    *dip = (u32 *) stats;
0024     __be32    t0, t1;
0025     int     i;
0026 
0027     for (i = 0; i < sizeof(union bfa_port_stats_u)/sizeof(u32);
0028         i += 2) {
0029         t0 = dip[i];
0030         t1 = dip[i + 1];
0031 #ifdef __BIG_ENDIAN
0032         dip[i] = be32_to_cpu(t0);
0033         dip[i + 1] = be32_to_cpu(t1);
0034 #else
0035         dip[i] = be32_to_cpu(t1);
0036         dip[i + 1] = be32_to_cpu(t0);
0037 #endif
0038     }
0039 }
0040 
0041 /*
0042  * bfa_port_enable_isr()
0043  *
0044  *
0045  * @param[in] port - Pointer to the port module
0046  *            status - Return status from the f/w
0047  *
0048  * @return void
0049  */
0050 static void
0051 bfa_port_enable_isr(struct bfa_port_s *port, bfa_status_t status)
0052 {
0053     bfa_trc(port, status);
0054     port->endis_pending = BFA_FALSE;
0055     port->endis_cbfn(port->endis_cbarg, status);
0056 }
0057 
0058 /*
0059  * bfa_port_disable_isr()
0060  *
0061  *
0062  * @param[in] port - Pointer to the port module
0063  *            status - Return status from the f/w
0064  *
0065  * @return void
0066  */
0067 static void
0068 bfa_port_disable_isr(struct bfa_port_s *port, bfa_status_t status)
0069 {
0070     bfa_trc(port, status);
0071     port->endis_pending = BFA_FALSE;
0072     port->endis_cbfn(port->endis_cbarg, status);
0073 }
0074 
0075 /*
0076  * bfa_port_get_stats_isr()
0077  *
0078  *
0079  * @param[in] port - Pointer to the Port module
0080  *            status - Return status from the f/w
0081  *
0082  * @return void
0083  */
0084 static void
0085 bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
0086 {
0087     port->stats_status = status;
0088     port->stats_busy = BFA_FALSE;
0089 
0090     if (status == BFA_STATUS_OK) {
0091         memcpy(port->stats, port->stats_dma.kva,
0092                sizeof(union bfa_port_stats_u));
0093         bfa_port_stats_swap(port, port->stats);
0094 
0095         port->stats->fc.secs_reset = ktime_get_seconds() - port->stats_reset_time;
0096     }
0097 
0098     if (port->stats_cbfn) {
0099         port->stats_cbfn(port->stats_cbarg, status);
0100         port->stats_cbfn = NULL;
0101     }
0102 }
0103 
0104 /*
0105  * bfa_port_clear_stats_isr()
0106  *
0107  *
0108  * @param[in] port - Pointer to the Port module
0109  *            status - Return status from the f/w
0110  *
0111  * @return void
0112  */
0113 static void
0114 bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
0115 {
0116     port->stats_status = status;
0117     port->stats_busy   = BFA_FALSE;
0118 
0119     /*
0120     * re-initialize time stamp for stats reset
0121     */
0122     port->stats_reset_time = ktime_get_seconds();
0123 
0124     if (port->stats_cbfn) {
0125         port->stats_cbfn(port->stats_cbarg, status);
0126         port->stats_cbfn = NULL;
0127     }
0128 }
0129 
0130 /*
0131  * bfa_port_isr()
0132  *
0133  *
0134  * @param[in] Pointer to the Port module data structure.
0135  *
0136  * @return void
0137  */
0138 static void
0139 bfa_port_isr(void *cbarg, struct bfi_mbmsg_s *m)
0140 {
0141     struct bfa_port_s *port = (struct bfa_port_s *) cbarg;
0142     union bfi_port_i2h_msg_u *i2hmsg;
0143 
0144     i2hmsg = (union bfi_port_i2h_msg_u *) m;
0145     bfa_trc(port, m->mh.msg_id);
0146 
0147     switch (m->mh.msg_id) {
0148     case BFI_PORT_I2H_ENABLE_RSP:
0149         if (port->endis_pending == BFA_FALSE)
0150             break;
0151         bfa_port_enable_isr(port, i2hmsg->enable_rsp.status);
0152         break;
0153 
0154     case BFI_PORT_I2H_DISABLE_RSP:
0155         if (port->endis_pending == BFA_FALSE)
0156             break;
0157         bfa_port_disable_isr(port, i2hmsg->disable_rsp.status);
0158         break;
0159 
0160     case BFI_PORT_I2H_GET_STATS_RSP:
0161         /* Stats busy flag is still set? (may be cmd timed out) */
0162         if (port->stats_busy == BFA_FALSE)
0163             break;
0164         bfa_port_get_stats_isr(port, i2hmsg->getstats_rsp.status);
0165         break;
0166 
0167     case BFI_PORT_I2H_CLEAR_STATS_RSP:
0168         if (port->stats_busy == BFA_FALSE)
0169             break;
0170         bfa_port_clear_stats_isr(port, i2hmsg->clearstats_rsp.status);
0171         break;
0172 
0173     default:
0174         WARN_ON(1);
0175     }
0176 }
0177 
0178 /*
0179  * bfa_port_meminfo()
0180  *
0181  *
0182  * @param[in] void
0183  *
0184  * @return Size of DMA region
0185  */
0186 u32
0187 bfa_port_meminfo(void)
0188 {
0189     return BFA_ROUNDUP(sizeof(union bfa_port_stats_u), BFA_DMA_ALIGN_SZ);
0190 }
0191 
0192 /*
0193  * bfa_port_mem_claim()
0194  *
0195  *
0196  * @param[in] port Port module pointer
0197  *        dma_kva Kernel Virtual Address of Port DMA Memory
0198  *        dma_pa  Physical Address of Port DMA Memory
0199  *
0200  * @return void
0201  */
0202 void
0203 bfa_port_mem_claim(struct bfa_port_s *port, u8 *dma_kva, u64 dma_pa)
0204 {
0205     port->stats_dma.kva = dma_kva;
0206     port->stats_dma.pa  = dma_pa;
0207 }
0208 
0209 /*
0210  * bfa_port_enable()
0211  *
0212  *   Send the Port enable request to the f/w
0213  *
0214  * @param[in] Pointer to the Port module data structure.
0215  *
0216  * @return Status
0217  */
0218 bfa_status_t
0219 bfa_port_enable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
0220          void *cbarg)
0221 {
0222     struct bfi_port_generic_req_s *m;
0223 
0224     /* If port is PBC disabled, return error */
0225     if (port->pbc_disabled) {
0226         bfa_trc(port, BFA_STATUS_PBC);
0227         return BFA_STATUS_PBC;
0228     }
0229 
0230     if (bfa_ioc_is_disabled(port->ioc)) {
0231         bfa_trc(port, BFA_STATUS_IOC_DISABLED);
0232         return BFA_STATUS_IOC_DISABLED;
0233     }
0234 
0235     if (!bfa_ioc_is_operational(port->ioc)) {
0236         bfa_trc(port, BFA_STATUS_IOC_FAILURE);
0237         return BFA_STATUS_IOC_FAILURE;
0238     }
0239 
0240     /* if port is d-port enabled, return error */
0241     if (port->dport_enabled) {
0242         bfa_trc(port, BFA_STATUS_DPORT_ERR);
0243         return BFA_STATUS_DPORT_ERR;
0244     }
0245 
0246     if (port->endis_pending) {
0247         bfa_trc(port, BFA_STATUS_DEVBUSY);
0248         return BFA_STATUS_DEVBUSY;
0249     }
0250 
0251     m = (struct bfi_port_generic_req_s *) port->endis_mb.msg;
0252 
0253     port->msgtag++;
0254     port->endis_cbfn    = cbfn;
0255     port->endis_cbarg   = cbarg;
0256     port->endis_pending = BFA_TRUE;
0257 
0258     bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_ENABLE_REQ,
0259             bfa_ioc_portid(port->ioc));
0260     bfa_ioc_mbox_queue(port->ioc, &port->endis_mb);
0261 
0262     return BFA_STATUS_OK;
0263 }
0264 
0265 /*
0266  * bfa_port_disable()
0267  *
0268  *   Send the Port disable request to the f/w
0269  *
0270  * @param[in] Pointer to the Port module data structure.
0271  *
0272  * @return Status
0273  */
0274 bfa_status_t
0275 bfa_port_disable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
0276           void *cbarg)
0277 {
0278     struct bfi_port_generic_req_s *m;
0279 
0280     /* If port is PBC disabled, return error */
0281     if (port->pbc_disabled) {
0282         bfa_trc(port, BFA_STATUS_PBC);
0283         return BFA_STATUS_PBC;
0284     }
0285 
0286     if (bfa_ioc_is_disabled(port->ioc)) {
0287         bfa_trc(port, BFA_STATUS_IOC_DISABLED);
0288         return BFA_STATUS_IOC_DISABLED;
0289     }
0290 
0291     if (!bfa_ioc_is_operational(port->ioc)) {
0292         bfa_trc(port, BFA_STATUS_IOC_FAILURE);
0293         return BFA_STATUS_IOC_FAILURE;
0294     }
0295 
0296     /* if port is d-port enabled, return error */
0297     if (port->dport_enabled) {
0298         bfa_trc(port, BFA_STATUS_DPORT_ERR);
0299         return BFA_STATUS_DPORT_ERR;
0300     }
0301 
0302     if (port->endis_pending) {
0303         bfa_trc(port, BFA_STATUS_DEVBUSY);
0304         return BFA_STATUS_DEVBUSY;
0305     }
0306 
0307     m = (struct bfi_port_generic_req_s *) port->endis_mb.msg;
0308 
0309     port->msgtag++;
0310     port->endis_cbfn    = cbfn;
0311     port->endis_cbarg   = cbarg;
0312     port->endis_pending = BFA_TRUE;
0313 
0314     bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_DISABLE_REQ,
0315             bfa_ioc_portid(port->ioc));
0316     bfa_ioc_mbox_queue(port->ioc, &port->endis_mb);
0317 
0318     return BFA_STATUS_OK;
0319 }
0320 
0321 /*
0322  * bfa_port_get_stats()
0323  *
0324  *   Send the request to the f/w to fetch Port statistics.
0325  *
0326  * @param[in] Pointer to the Port module data structure.
0327  *
0328  * @return Status
0329  */
0330 bfa_status_t
0331 bfa_port_get_stats(struct bfa_port_s *port, union bfa_port_stats_u *stats,
0332             bfa_port_stats_cbfn_t cbfn, void *cbarg)
0333 {
0334     struct bfi_port_get_stats_req_s *m;
0335 
0336     if (!bfa_ioc_is_operational(port->ioc)) {
0337         bfa_trc(port, BFA_STATUS_IOC_FAILURE);
0338         return BFA_STATUS_IOC_FAILURE;
0339     }
0340 
0341     if (port->stats_busy) {
0342         bfa_trc(port, BFA_STATUS_DEVBUSY);
0343         return BFA_STATUS_DEVBUSY;
0344     }
0345 
0346     m = (struct bfi_port_get_stats_req_s *) port->stats_mb.msg;
0347 
0348     port->stats   = stats;
0349     port->stats_cbfn  = cbfn;
0350     port->stats_cbarg = cbarg;
0351     port->stats_busy  = BFA_TRUE;
0352     bfa_dma_be_addr_set(m->dma_addr, port->stats_dma.pa);
0353 
0354     bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_GET_STATS_REQ,
0355             bfa_ioc_portid(port->ioc));
0356     bfa_ioc_mbox_queue(port->ioc, &port->stats_mb);
0357 
0358     return BFA_STATUS_OK;
0359 }
0360 
0361 /*
0362  * bfa_port_clear_stats()
0363  *
0364  *
0365  * @param[in] Pointer to the Port module data structure.
0366  *
0367  * @return Status
0368  */
0369 bfa_status_t
0370 bfa_port_clear_stats(struct bfa_port_s *port, bfa_port_stats_cbfn_t cbfn,
0371               void *cbarg)
0372 {
0373     struct bfi_port_generic_req_s *m;
0374 
0375     if (!bfa_ioc_is_operational(port->ioc)) {
0376         bfa_trc(port, BFA_STATUS_IOC_FAILURE);
0377         return BFA_STATUS_IOC_FAILURE;
0378     }
0379 
0380     if (port->stats_busy) {
0381         bfa_trc(port, BFA_STATUS_DEVBUSY);
0382         return BFA_STATUS_DEVBUSY;
0383     }
0384 
0385     m = (struct bfi_port_generic_req_s *) port->stats_mb.msg;
0386 
0387     port->stats_cbfn  = cbfn;
0388     port->stats_cbarg = cbarg;
0389     port->stats_busy  = BFA_TRUE;
0390 
0391     bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_CLEAR_STATS_REQ,
0392             bfa_ioc_portid(port->ioc));
0393     bfa_ioc_mbox_queue(port->ioc, &port->stats_mb);
0394 
0395     return BFA_STATUS_OK;
0396 }
0397 
0398 /*
0399  * bfa_port_notify()
0400  *
0401  * Port module IOC event handler
0402  *
0403  * @param[in] Pointer to the Port module data structure.
0404  * @param[in] IOC event structure
0405  *
0406  * @return void
0407  */
0408 void
0409 bfa_port_notify(void *arg, enum bfa_ioc_event_e event)
0410 {
0411     struct bfa_port_s *port = (struct bfa_port_s *) arg;
0412 
0413     switch (event) {
0414     case BFA_IOC_E_DISABLED:
0415     case BFA_IOC_E_FAILED:
0416         /* Fail any pending get_stats/clear_stats requests */
0417         if (port->stats_busy) {
0418             if (port->stats_cbfn)
0419                 port->stats_cbfn(port->stats_cbarg,
0420                         BFA_STATUS_FAILED);
0421             port->stats_cbfn = NULL;
0422             port->stats_busy = BFA_FALSE;
0423         }
0424 
0425         /* Clear any enable/disable is pending */
0426         if (port->endis_pending) {
0427             if (port->endis_cbfn)
0428                 port->endis_cbfn(port->endis_cbarg,
0429                         BFA_STATUS_FAILED);
0430             port->endis_cbfn = NULL;
0431             port->endis_pending = BFA_FALSE;
0432         }
0433 
0434         /* clear D-port mode */
0435         if (port->dport_enabled)
0436             bfa_port_set_dportenabled(port, BFA_FALSE);
0437         break;
0438     default:
0439         break;
0440     }
0441 }
0442 
0443 /*
0444  * bfa_port_attach()
0445  *
0446  *
0447  * @param[in] port - Pointer to the Port module data structure
0448  *            ioc  - Pointer to the ioc module data structure
0449  *            dev  - Pointer to the device driver module data structure
0450  *                   The device driver specific mbox ISR functions have
0451  *                   this pointer as one of the parameters.
0452  *            trcmod -
0453  *
0454  * @return void
0455  */
0456 void
0457 bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
0458          void *dev, struct bfa_trc_mod_s *trcmod)
0459 {
0460     WARN_ON(!port);
0461 
0462     port->dev    = dev;
0463     port->ioc    = ioc;
0464     port->trcmod = trcmod;
0465 
0466     port->stats_busy = BFA_FALSE;
0467     port->endis_pending = BFA_FALSE;
0468     port->stats_cbfn = NULL;
0469     port->endis_cbfn = NULL;
0470     port->pbc_disabled = BFA_FALSE;
0471     port->dport_enabled = BFA_FALSE;
0472 
0473     bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port);
0474     bfa_q_qe_init(&port->ioc_notify);
0475     bfa_ioc_notify_init(&port->ioc_notify, bfa_port_notify, port);
0476     list_add_tail(&port->ioc_notify.qe, &port->ioc->notify_q);
0477 
0478     /*
0479      * initialize time stamp for stats reset
0480      */
0481     port->stats_reset_time = ktime_get_seconds();
0482 
0483     bfa_trc(port, 0);
0484 }
0485 
0486 /*
0487  * bfa_port_set_dportenabled();
0488  *
0489  * Port module- set pbc disabled flag
0490  *
0491  * @param[in] port - Pointer to the Port module data structure
0492  *
0493  * @return void
0494  */
0495 void
0496 bfa_port_set_dportenabled(struct bfa_port_s *port, bfa_boolean_t enabled)
0497 {
0498     port->dport_enabled = enabled;
0499 }
0500 
0501 /*
0502  *  CEE module specific definitions
0503  */
0504 
0505 /*
0506  * bfa_cee_get_attr_isr()
0507  *
0508  * @brief CEE ISR for get-attributes responses from f/w
0509  *
0510  * @param[in] cee - Pointer to the CEE module
0511  *          status - Return status from the f/w
0512  *
0513  * @return void
0514  */
0515 static void
0516 bfa_cee_get_attr_isr(struct bfa_cee_s *cee, bfa_status_t status)
0517 {
0518     struct bfa_cee_lldp_cfg_s *lldp_cfg = &cee->attr->lldp_remote;
0519 
0520     cee->get_attr_status = status;
0521     bfa_trc(cee, 0);
0522     if (status == BFA_STATUS_OK) {
0523         bfa_trc(cee, 0);
0524         memcpy(cee->attr, cee->attr_dma.kva,
0525             sizeof(struct bfa_cee_attr_s));
0526         lldp_cfg->time_to_live = be16_to_cpu(lldp_cfg->time_to_live);
0527         lldp_cfg->enabled_system_cap =
0528                 be16_to_cpu(lldp_cfg->enabled_system_cap);
0529     }
0530     cee->get_attr_pending = BFA_FALSE;
0531     if (cee->cbfn.get_attr_cbfn) {
0532         bfa_trc(cee, 0);
0533         cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
0534     }
0535 }
0536 
0537 /*
0538  * bfa_cee_get_stats_isr()
0539  *
0540  * @brief CEE ISR for get-stats responses from f/w
0541  *
0542  * @param[in] cee - Pointer to the CEE module
0543  *        status - Return status from the f/w
0544  *
0545  * @return void
0546  */
0547 static void
0548 bfa_cee_get_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
0549 {
0550     u32 *buffer;
0551     int i;
0552 
0553     cee->get_stats_status = status;
0554     bfa_trc(cee, 0);
0555     if (status == BFA_STATUS_OK) {
0556         bfa_trc(cee, 0);
0557         memcpy(cee->stats, cee->stats_dma.kva,
0558             sizeof(struct bfa_cee_stats_s));
0559         /* swap the cee stats */
0560         buffer = (u32 *)cee->stats;
0561         for (i = 0; i < (sizeof(struct bfa_cee_stats_s) /
0562                  sizeof(u32)); i++)
0563             buffer[i] = cpu_to_be32(buffer[i]);
0564     }
0565     cee->get_stats_pending = BFA_FALSE;
0566     bfa_trc(cee, 0);
0567     if (cee->cbfn.get_stats_cbfn) {
0568         bfa_trc(cee, 0);
0569         cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
0570     }
0571 }
0572 
0573 /*
0574  * bfa_cee_reset_stats_isr()
0575  *
0576  * @brief CEE ISR for reset-stats responses from f/w
0577  *
0578  * @param[in] cee - Pointer to the CEE module
0579  *            status - Return status from the f/w
0580  *
0581  * @return void
0582  */
0583 static void
0584 bfa_cee_reset_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
0585 {
0586     cee->reset_stats_status = status;
0587     cee->reset_stats_pending = BFA_FALSE;
0588     if (cee->cbfn.reset_stats_cbfn)
0589         cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
0590 }
0591 
0592 /*
0593  * bfa_cee_meminfo()
0594  *
0595  * @brief Returns the size of the DMA memory needed by CEE module
0596  *
0597  * @param[in] void
0598  *
0599  * @return Size of DMA region
0600  */
0601 u32
0602 bfa_cee_meminfo(void)
0603 {
0604     return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ) +
0605         BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s), BFA_DMA_ALIGN_SZ);
0606 }
0607 
0608 /*
0609  * bfa_cee_mem_claim()
0610  *
0611  * @brief Initialized CEE DMA Memory
0612  *
0613  * @param[in] cee CEE module pointer
0614  *            dma_kva Kernel Virtual Address of CEE DMA Memory
0615  *            dma_pa  Physical Address of CEE DMA Memory
0616  *
0617  * @return void
0618  */
0619 void
0620 bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa)
0621 {
0622     cee->attr_dma.kva = dma_kva;
0623     cee->attr_dma.pa = dma_pa;
0624     cee->stats_dma.kva = dma_kva + BFA_ROUNDUP(
0625                  sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ);
0626     cee->stats_dma.pa = dma_pa + BFA_ROUNDUP(
0627                  sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ);
0628     cee->attr = (struct bfa_cee_attr_s *) dma_kva;
0629     cee->stats = (struct bfa_cee_stats_s *) (dma_kva + BFA_ROUNDUP(
0630             sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ));
0631 }
0632 
0633 /*
0634  * bfa_cee_get_attr()
0635  *
0636  * @brief
0637  *   Send the request to the f/w to fetch CEE attributes.
0638  *
0639  * @param[in] Pointer to the CEE module data structure.
0640  *
0641  * @return Status
0642  */
0643 
0644 bfa_status_t
0645 bfa_cee_get_attr(struct bfa_cee_s *cee, struct bfa_cee_attr_s *attr,
0646          bfa_cee_get_attr_cbfn_t cbfn, void *cbarg)
0647 {
0648     struct bfi_cee_get_req_s *cmd;
0649 
0650     WARN_ON((cee == NULL) || (cee->ioc == NULL));
0651     bfa_trc(cee, 0);
0652     if (!bfa_ioc_is_operational(cee->ioc)) {
0653         bfa_trc(cee, 0);
0654         return BFA_STATUS_IOC_FAILURE;
0655     }
0656     if (cee->get_attr_pending == BFA_TRUE) {
0657         bfa_trc(cee, 0);
0658         return  BFA_STATUS_DEVBUSY;
0659     }
0660     cee->get_attr_pending = BFA_TRUE;
0661     cmd = (struct bfi_cee_get_req_s *) cee->get_cfg_mb.msg;
0662     cee->attr = attr;
0663     cee->cbfn.get_attr_cbfn = cbfn;
0664     cee->cbfn.get_attr_cbarg = cbarg;
0665     bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ,
0666         bfa_ioc_portid(cee->ioc));
0667     bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa);
0668     bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb);
0669 
0670     return BFA_STATUS_OK;
0671 }
0672 
0673 /*
0674  * bfa_cee_get_stats()
0675  *
0676  * @brief
0677  *   Send the request to the f/w to fetch CEE statistics.
0678  *
0679  * @param[in] Pointer to the CEE module data structure.
0680  *
0681  * @return Status
0682  */
0683 
0684 bfa_status_t
0685 bfa_cee_get_stats(struct bfa_cee_s *cee, struct bfa_cee_stats_s *stats,
0686           bfa_cee_get_stats_cbfn_t cbfn, void *cbarg)
0687 {
0688     struct bfi_cee_get_req_s *cmd;
0689 
0690     WARN_ON((cee == NULL) || (cee->ioc == NULL));
0691 
0692     if (!bfa_ioc_is_operational(cee->ioc)) {
0693         bfa_trc(cee, 0);
0694         return BFA_STATUS_IOC_FAILURE;
0695     }
0696     if (cee->get_stats_pending == BFA_TRUE) {
0697         bfa_trc(cee, 0);
0698         return  BFA_STATUS_DEVBUSY;
0699     }
0700     cee->get_stats_pending = BFA_TRUE;
0701     cmd = (struct bfi_cee_get_req_s *) cee->get_stats_mb.msg;
0702     cee->stats = stats;
0703     cee->cbfn.get_stats_cbfn = cbfn;
0704     cee->cbfn.get_stats_cbarg = cbarg;
0705     bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ,
0706         bfa_ioc_portid(cee->ioc));
0707     bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa);
0708     bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb);
0709 
0710     return BFA_STATUS_OK;
0711 }
0712 
0713 /*
0714  * bfa_cee_reset_stats()
0715  *
0716  * @brief Clears CEE Stats in the f/w.
0717  *
0718  * @param[in] Pointer to the CEE module data structure.
0719  *
0720  * @return Status
0721  */
0722 
0723 bfa_status_t
0724 bfa_cee_reset_stats(struct bfa_cee_s *cee,
0725             bfa_cee_reset_stats_cbfn_t cbfn, void *cbarg)
0726 {
0727     struct bfi_cee_reset_stats_s *cmd;
0728 
0729     WARN_ON((cee == NULL) || (cee->ioc == NULL));
0730     if (!bfa_ioc_is_operational(cee->ioc)) {
0731         bfa_trc(cee, 0);
0732         return BFA_STATUS_IOC_FAILURE;
0733     }
0734     if (cee->reset_stats_pending == BFA_TRUE) {
0735         bfa_trc(cee, 0);
0736         return  BFA_STATUS_DEVBUSY;
0737     }
0738     cee->reset_stats_pending = BFA_TRUE;
0739     cmd = (struct bfi_cee_reset_stats_s *) cee->reset_stats_mb.msg;
0740     cee->cbfn.reset_stats_cbfn = cbfn;
0741     cee->cbfn.reset_stats_cbarg = cbarg;
0742     bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS,
0743         bfa_ioc_portid(cee->ioc));
0744     bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb);
0745 
0746     return BFA_STATUS_OK;
0747 }
0748 
0749 /*
0750  * bfa_cee_isrs()
0751  *
0752  * @brief Handles Mail-box interrupts for CEE module.
0753  *
0754  * @param[in] Pointer to the CEE module data structure.
0755  *
0756  * @return void
0757  */
0758 
0759 static void
0760 bfa_cee_isr(void *cbarg, struct bfi_mbmsg_s *m)
0761 {
0762     union bfi_cee_i2h_msg_u *msg;
0763     struct bfi_cee_get_rsp_s *get_rsp;
0764     struct bfa_cee_s *cee = (struct bfa_cee_s *) cbarg;
0765     msg = (union bfi_cee_i2h_msg_u *) m;
0766     get_rsp = (struct bfi_cee_get_rsp_s *) m;
0767     bfa_trc(cee, msg->mh.msg_id);
0768     switch (msg->mh.msg_id) {
0769     case BFI_CEE_I2H_GET_CFG_RSP:
0770         bfa_trc(cee, get_rsp->cmd_status);
0771         bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
0772         break;
0773     case BFI_CEE_I2H_GET_STATS_RSP:
0774         bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
0775         break;
0776     case BFI_CEE_I2H_RESET_STATS_RSP:
0777         bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
0778         break;
0779     default:
0780         WARN_ON(1);
0781     }
0782 }
0783 
0784 /*
0785  * bfa_cee_notify()
0786  *
0787  * @brief CEE module IOC event handler.
0788  *
0789  * @param[in] Pointer to the CEE module data structure.
0790  * @param[in] IOC event type
0791  *
0792  * @return void
0793  */
0794 
0795 static void
0796 bfa_cee_notify(void *arg, enum bfa_ioc_event_e event)
0797 {
0798     struct bfa_cee_s *cee = (struct bfa_cee_s *) arg;
0799 
0800     bfa_trc(cee, event);
0801 
0802     switch (event) {
0803     case BFA_IOC_E_DISABLED:
0804     case BFA_IOC_E_FAILED:
0805         if (cee->get_attr_pending == BFA_TRUE) {
0806             cee->get_attr_status = BFA_STATUS_FAILED;
0807             cee->get_attr_pending  = BFA_FALSE;
0808             if (cee->cbfn.get_attr_cbfn) {
0809                 cee->cbfn.get_attr_cbfn(
0810                     cee->cbfn.get_attr_cbarg,
0811                     BFA_STATUS_FAILED);
0812             }
0813         }
0814         if (cee->get_stats_pending == BFA_TRUE) {
0815             cee->get_stats_status = BFA_STATUS_FAILED;
0816             cee->get_stats_pending  = BFA_FALSE;
0817             if (cee->cbfn.get_stats_cbfn) {
0818                 cee->cbfn.get_stats_cbfn(
0819                 cee->cbfn.get_stats_cbarg,
0820                 BFA_STATUS_FAILED);
0821             }
0822         }
0823         if (cee->reset_stats_pending == BFA_TRUE) {
0824             cee->reset_stats_status = BFA_STATUS_FAILED;
0825             cee->reset_stats_pending  = BFA_FALSE;
0826             if (cee->cbfn.reset_stats_cbfn) {
0827                 cee->cbfn.reset_stats_cbfn(
0828                 cee->cbfn.reset_stats_cbarg,
0829                 BFA_STATUS_FAILED);
0830             }
0831         }
0832         break;
0833 
0834     default:
0835         break;
0836     }
0837 }
0838 
0839 /*
0840  * bfa_cee_attach()
0841  *
0842  * @brief CEE module-attach API
0843  *
0844  * @param[in] cee - Pointer to the CEE module data structure
0845  *            ioc - Pointer to the ioc module data structure
0846  *            dev - Pointer to the device driver module data structure
0847  *                  The device driver specific mbox ISR functions have
0848  *                  this pointer as one of the parameters.
0849  *
0850  * @return void
0851  */
0852 void
0853 bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc,
0854         void *dev)
0855 {
0856     WARN_ON(cee == NULL);
0857     cee->dev = dev;
0858     cee->ioc = ioc;
0859 
0860     bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
0861     bfa_q_qe_init(&cee->ioc_notify);
0862     bfa_ioc_notify_init(&cee->ioc_notify, bfa_cee_notify, cee);
0863     list_add_tail(&cee->ioc_notify.qe, &cee->ioc->notify_q);
0864 }