PageRenderTime 78ms CodeModel.GetById 16ms app.highlight 57ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/scsi/bfa/bfa_port.c

http://github.com/mirrors/linux
C | 864 lines | 499 code | 98 blank | 267 comment | 72 complexity | 90ba6e8572d40eaa960497578d2f66ff MD5 | raw file
  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
759void
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
795void
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}