cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bfa_port.c (19857B)


      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}