xref: /OK3568_Linux_fs/kernel/drivers/scsi/bfa/bfa_port.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
4*4882a593Smuzhiyun  * Copyright (c) 2014- QLogic Corporation.
5*4882a593Smuzhiyun  * All rights reserved
6*4882a593Smuzhiyun  * www.qlogic.com
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include "bfad_drv.h"
12*4882a593Smuzhiyun #include "bfa_defs_svc.h"
13*4882a593Smuzhiyun #include "bfa_port.h"
14*4882a593Smuzhiyun #include "bfi.h"
15*4882a593Smuzhiyun #include "bfa_ioc.h"
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun BFA_TRC_FILE(CNA, PORT);
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun static void
bfa_port_stats_swap(struct bfa_port_s * port,union bfa_port_stats_u * stats)21*4882a593Smuzhiyun bfa_port_stats_swap(struct bfa_port_s *port, union bfa_port_stats_u *stats)
22*4882a593Smuzhiyun {
23*4882a593Smuzhiyun 	u32    *dip = (u32 *) stats;
24*4882a593Smuzhiyun 	__be32    t0, t1;
25*4882a593Smuzhiyun 	int	    i;
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun 	for (i = 0; i < sizeof(union bfa_port_stats_u)/sizeof(u32);
28*4882a593Smuzhiyun 		i += 2) {
29*4882a593Smuzhiyun 		t0 = dip[i];
30*4882a593Smuzhiyun 		t1 = dip[i + 1];
31*4882a593Smuzhiyun #ifdef __BIG_ENDIAN
32*4882a593Smuzhiyun 		dip[i] = be32_to_cpu(t0);
33*4882a593Smuzhiyun 		dip[i + 1] = be32_to_cpu(t1);
34*4882a593Smuzhiyun #else
35*4882a593Smuzhiyun 		dip[i] = be32_to_cpu(t1);
36*4882a593Smuzhiyun 		dip[i + 1] = be32_to_cpu(t0);
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 	}
39*4882a593Smuzhiyun }
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /*
42*4882a593Smuzhiyun  * bfa_port_enable_isr()
43*4882a593Smuzhiyun  *
44*4882a593Smuzhiyun  *
45*4882a593Smuzhiyun  * @param[in] port - Pointer to the port module
46*4882a593Smuzhiyun  *            status - Return status from the f/w
47*4882a593Smuzhiyun  *
48*4882a593Smuzhiyun  * @return void
49*4882a593Smuzhiyun  */
50*4882a593Smuzhiyun static void
bfa_port_enable_isr(struct bfa_port_s * port,bfa_status_t status)51*4882a593Smuzhiyun bfa_port_enable_isr(struct bfa_port_s *port, bfa_status_t status)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun 	bfa_trc(port, status);
54*4882a593Smuzhiyun 	port->endis_pending = BFA_FALSE;
55*4882a593Smuzhiyun 	port->endis_cbfn(port->endis_cbarg, status);
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /*
59*4882a593Smuzhiyun  * bfa_port_disable_isr()
60*4882a593Smuzhiyun  *
61*4882a593Smuzhiyun  *
62*4882a593Smuzhiyun  * @param[in] port - Pointer to the port module
63*4882a593Smuzhiyun  *            status - Return status from the f/w
64*4882a593Smuzhiyun  *
65*4882a593Smuzhiyun  * @return void
66*4882a593Smuzhiyun  */
67*4882a593Smuzhiyun static void
bfa_port_disable_isr(struct bfa_port_s * port,bfa_status_t status)68*4882a593Smuzhiyun bfa_port_disable_isr(struct bfa_port_s *port, bfa_status_t status)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun 	bfa_trc(port, status);
71*4882a593Smuzhiyun 	port->endis_pending = BFA_FALSE;
72*4882a593Smuzhiyun 	port->endis_cbfn(port->endis_cbarg, status);
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun /*
76*4882a593Smuzhiyun  * bfa_port_get_stats_isr()
77*4882a593Smuzhiyun  *
78*4882a593Smuzhiyun  *
79*4882a593Smuzhiyun  * @param[in] port - Pointer to the Port module
80*4882a593Smuzhiyun  *            status - Return status from the f/w
81*4882a593Smuzhiyun  *
82*4882a593Smuzhiyun  * @return void
83*4882a593Smuzhiyun  */
84*4882a593Smuzhiyun static void
bfa_port_get_stats_isr(struct bfa_port_s * port,bfa_status_t status)85*4882a593Smuzhiyun bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	port->stats_status = status;
88*4882a593Smuzhiyun 	port->stats_busy = BFA_FALSE;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	if (status == BFA_STATUS_OK) {
91*4882a593Smuzhiyun 		memcpy(port->stats, port->stats_dma.kva,
92*4882a593Smuzhiyun 		       sizeof(union bfa_port_stats_u));
93*4882a593Smuzhiyun 		bfa_port_stats_swap(port, port->stats);
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 		port->stats->fc.secs_reset = ktime_get_seconds() - port->stats_reset_time;
96*4882a593Smuzhiyun 	}
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	if (port->stats_cbfn) {
99*4882a593Smuzhiyun 		port->stats_cbfn(port->stats_cbarg, status);
100*4882a593Smuzhiyun 		port->stats_cbfn = NULL;
101*4882a593Smuzhiyun 	}
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun /*
105*4882a593Smuzhiyun  * bfa_port_clear_stats_isr()
106*4882a593Smuzhiyun  *
107*4882a593Smuzhiyun  *
108*4882a593Smuzhiyun  * @param[in] port - Pointer to the Port module
109*4882a593Smuzhiyun  *            status - Return status from the f/w
110*4882a593Smuzhiyun  *
111*4882a593Smuzhiyun  * @return void
112*4882a593Smuzhiyun  */
113*4882a593Smuzhiyun static void
bfa_port_clear_stats_isr(struct bfa_port_s * port,bfa_status_t status)114*4882a593Smuzhiyun bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun 	port->stats_status = status;
117*4882a593Smuzhiyun 	port->stats_busy   = BFA_FALSE;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	/*
120*4882a593Smuzhiyun 	* re-initialize time stamp for stats reset
121*4882a593Smuzhiyun 	*/
122*4882a593Smuzhiyun 	port->stats_reset_time = ktime_get_seconds();
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	if (port->stats_cbfn) {
125*4882a593Smuzhiyun 		port->stats_cbfn(port->stats_cbarg, status);
126*4882a593Smuzhiyun 		port->stats_cbfn = NULL;
127*4882a593Smuzhiyun 	}
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun /*
131*4882a593Smuzhiyun  * bfa_port_isr()
132*4882a593Smuzhiyun  *
133*4882a593Smuzhiyun  *
134*4882a593Smuzhiyun  * @param[in] Pointer to the Port module data structure.
135*4882a593Smuzhiyun  *
136*4882a593Smuzhiyun  * @return void
137*4882a593Smuzhiyun  */
138*4882a593Smuzhiyun static void
bfa_port_isr(void * cbarg,struct bfi_mbmsg_s * m)139*4882a593Smuzhiyun bfa_port_isr(void *cbarg, struct bfi_mbmsg_s *m)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	struct bfa_port_s *port = (struct bfa_port_s *) cbarg;
142*4882a593Smuzhiyun 	union bfi_port_i2h_msg_u *i2hmsg;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	i2hmsg = (union bfi_port_i2h_msg_u *) m;
145*4882a593Smuzhiyun 	bfa_trc(port, m->mh.msg_id);
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	switch (m->mh.msg_id) {
148*4882a593Smuzhiyun 	case BFI_PORT_I2H_ENABLE_RSP:
149*4882a593Smuzhiyun 		if (port->endis_pending == BFA_FALSE)
150*4882a593Smuzhiyun 			break;
151*4882a593Smuzhiyun 		bfa_port_enable_isr(port, i2hmsg->enable_rsp.status);
152*4882a593Smuzhiyun 		break;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	case BFI_PORT_I2H_DISABLE_RSP:
155*4882a593Smuzhiyun 		if (port->endis_pending == BFA_FALSE)
156*4882a593Smuzhiyun 			break;
157*4882a593Smuzhiyun 		bfa_port_disable_isr(port, i2hmsg->disable_rsp.status);
158*4882a593Smuzhiyun 		break;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	case BFI_PORT_I2H_GET_STATS_RSP:
161*4882a593Smuzhiyun 		/* Stats busy flag is still set? (may be cmd timed out) */
162*4882a593Smuzhiyun 		if (port->stats_busy == BFA_FALSE)
163*4882a593Smuzhiyun 			break;
164*4882a593Smuzhiyun 		bfa_port_get_stats_isr(port, i2hmsg->getstats_rsp.status);
165*4882a593Smuzhiyun 		break;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	case BFI_PORT_I2H_CLEAR_STATS_RSP:
168*4882a593Smuzhiyun 		if (port->stats_busy == BFA_FALSE)
169*4882a593Smuzhiyun 			break;
170*4882a593Smuzhiyun 		bfa_port_clear_stats_isr(port, i2hmsg->clearstats_rsp.status);
171*4882a593Smuzhiyun 		break;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	default:
174*4882a593Smuzhiyun 		WARN_ON(1);
175*4882a593Smuzhiyun 	}
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun /*
179*4882a593Smuzhiyun  * bfa_port_meminfo()
180*4882a593Smuzhiyun  *
181*4882a593Smuzhiyun  *
182*4882a593Smuzhiyun  * @param[in] void
183*4882a593Smuzhiyun  *
184*4882a593Smuzhiyun  * @return Size of DMA region
185*4882a593Smuzhiyun  */
186*4882a593Smuzhiyun u32
bfa_port_meminfo(void)187*4882a593Smuzhiyun bfa_port_meminfo(void)
188*4882a593Smuzhiyun {
189*4882a593Smuzhiyun 	return BFA_ROUNDUP(sizeof(union bfa_port_stats_u), BFA_DMA_ALIGN_SZ);
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun /*
193*4882a593Smuzhiyun  * bfa_port_mem_claim()
194*4882a593Smuzhiyun  *
195*4882a593Smuzhiyun  *
196*4882a593Smuzhiyun  * @param[in] port Port module pointer
197*4882a593Smuzhiyun  *	      dma_kva Kernel Virtual Address of Port DMA Memory
198*4882a593Smuzhiyun  *	      dma_pa  Physical Address of Port DMA Memory
199*4882a593Smuzhiyun  *
200*4882a593Smuzhiyun  * @return void
201*4882a593Smuzhiyun  */
202*4882a593Smuzhiyun void
bfa_port_mem_claim(struct bfa_port_s * port,u8 * dma_kva,u64 dma_pa)203*4882a593Smuzhiyun bfa_port_mem_claim(struct bfa_port_s *port, u8 *dma_kva, u64 dma_pa)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun 	port->stats_dma.kva = dma_kva;
206*4882a593Smuzhiyun 	port->stats_dma.pa  = dma_pa;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun /*
210*4882a593Smuzhiyun  * bfa_port_enable()
211*4882a593Smuzhiyun  *
212*4882a593Smuzhiyun  *   Send the Port enable request to the f/w
213*4882a593Smuzhiyun  *
214*4882a593Smuzhiyun  * @param[in] Pointer to the Port module data structure.
215*4882a593Smuzhiyun  *
216*4882a593Smuzhiyun  * @return Status
217*4882a593Smuzhiyun  */
218*4882a593Smuzhiyun bfa_status_t
bfa_port_enable(struct bfa_port_s * port,bfa_port_endis_cbfn_t cbfn,void * cbarg)219*4882a593Smuzhiyun bfa_port_enable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
220*4882a593Smuzhiyun 		 void *cbarg)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	struct bfi_port_generic_req_s *m;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	/* If port is PBC disabled, return error */
225*4882a593Smuzhiyun 	if (port->pbc_disabled) {
226*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_PBC);
227*4882a593Smuzhiyun 		return BFA_STATUS_PBC;
228*4882a593Smuzhiyun 	}
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	if (bfa_ioc_is_disabled(port->ioc)) {
231*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_IOC_DISABLED);
232*4882a593Smuzhiyun 		return BFA_STATUS_IOC_DISABLED;
233*4882a593Smuzhiyun 	}
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	if (!bfa_ioc_is_operational(port->ioc)) {
236*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_IOC_FAILURE);
237*4882a593Smuzhiyun 		return BFA_STATUS_IOC_FAILURE;
238*4882a593Smuzhiyun 	}
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	/* if port is d-port enabled, return error */
241*4882a593Smuzhiyun 	if (port->dport_enabled) {
242*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_DPORT_ERR);
243*4882a593Smuzhiyun 		return BFA_STATUS_DPORT_ERR;
244*4882a593Smuzhiyun 	}
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	if (port->endis_pending) {
247*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_DEVBUSY);
248*4882a593Smuzhiyun 		return BFA_STATUS_DEVBUSY;
249*4882a593Smuzhiyun 	}
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	m = (struct bfi_port_generic_req_s *) port->endis_mb.msg;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	port->msgtag++;
254*4882a593Smuzhiyun 	port->endis_cbfn    = cbfn;
255*4882a593Smuzhiyun 	port->endis_cbarg   = cbarg;
256*4882a593Smuzhiyun 	port->endis_pending = BFA_TRUE;
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_ENABLE_REQ,
259*4882a593Smuzhiyun 		    bfa_ioc_portid(port->ioc));
260*4882a593Smuzhiyun 	bfa_ioc_mbox_queue(port->ioc, &port->endis_mb);
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	return BFA_STATUS_OK;
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun /*
266*4882a593Smuzhiyun  * bfa_port_disable()
267*4882a593Smuzhiyun  *
268*4882a593Smuzhiyun  *   Send the Port disable request to the f/w
269*4882a593Smuzhiyun  *
270*4882a593Smuzhiyun  * @param[in] Pointer to the Port module data structure.
271*4882a593Smuzhiyun  *
272*4882a593Smuzhiyun  * @return Status
273*4882a593Smuzhiyun  */
274*4882a593Smuzhiyun bfa_status_t
bfa_port_disable(struct bfa_port_s * port,bfa_port_endis_cbfn_t cbfn,void * cbarg)275*4882a593Smuzhiyun bfa_port_disable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
276*4882a593Smuzhiyun 		  void *cbarg)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun 	struct bfi_port_generic_req_s *m;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	/* If port is PBC disabled, return error */
281*4882a593Smuzhiyun 	if (port->pbc_disabled) {
282*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_PBC);
283*4882a593Smuzhiyun 		return BFA_STATUS_PBC;
284*4882a593Smuzhiyun 	}
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	if (bfa_ioc_is_disabled(port->ioc)) {
287*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_IOC_DISABLED);
288*4882a593Smuzhiyun 		return BFA_STATUS_IOC_DISABLED;
289*4882a593Smuzhiyun 	}
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	if (!bfa_ioc_is_operational(port->ioc)) {
292*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_IOC_FAILURE);
293*4882a593Smuzhiyun 		return BFA_STATUS_IOC_FAILURE;
294*4882a593Smuzhiyun 	}
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	/* if port is d-port enabled, return error */
297*4882a593Smuzhiyun 	if (port->dport_enabled) {
298*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_DPORT_ERR);
299*4882a593Smuzhiyun 		return BFA_STATUS_DPORT_ERR;
300*4882a593Smuzhiyun 	}
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	if (port->endis_pending) {
303*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_DEVBUSY);
304*4882a593Smuzhiyun 		return BFA_STATUS_DEVBUSY;
305*4882a593Smuzhiyun 	}
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	m = (struct bfi_port_generic_req_s *) port->endis_mb.msg;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	port->msgtag++;
310*4882a593Smuzhiyun 	port->endis_cbfn    = cbfn;
311*4882a593Smuzhiyun 	port->endis_cbarg   = cbarg;
312*4882a593Smuzhiyun 	port->endis_pending = BFA_TRUE;
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_DISABLE_REQ,
315*4882a593Smuzhiyun 		    bfa_ioc_portid(port->ioc));
316*4882a593Smuzhiyun 	bfa_ioc_mbox_queue(port->ioc, &port->endis_mb);
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	return BFA_STATUS_OK;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun /*
322*4882a593Smuzhiyun  * bfa_port_get_stats()
323*4882a593Smuzhiyun  *
324*4882a593Smuzhiyun  *   Send the request to the f/w to fetch Port statistics.
325*4882a593Smuzhiyun  *
326*4882a593Smuzhiyun  * @param[in] Pointer to the Port module data structure.
327*4882a593Smuzhiyun  *
328*4882a593Smuzhiyun  * @return Status
329*4882a593Smuzhiyun  */
330*4882a593Smuzhiyun bfa_status_t
bfa_port_get_stats(struct bfa_port_s * port,union bfa_port_stats_u * stats,bfa_port_stats_cbfn_t cbfn,void * cbarg)331*4882a593Smuzhiyun bfa_port_get_stats(struct bfa_port_s *port, union bfa_port_stats_u *stats,
332*4882a593Smuzhiyun 		    bfa_port_stats_cbfn_t cbfn, void *cbarg)
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun 	struct bfi_port_get_stats_req_s *m;
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	if (!bfa_ioc_is_operational(port->ioc)) {
337*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_IOC_FAILURE);
338*4882a593Smuzhiyun 		return BFA_STATUS_IOC_FAILURE;
339*4882a593Smuzhiyun 	}
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	if (port->stats_busy) {
342*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_DEVBUSY);
343*4882a593Smuzhiyun 		return BFA_STATUS_DEVBUSY;
344*4882a593Smuzhiyun 	}
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	m = (struct bfi_port_get_stats_req_s *) port->stats_mb.msg;
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	port->stats	  = stats;
349*4882a593Smuzhiyun 	port->stats_cbfn  = cbfn;
350*4882a593Smuzhiyun 	port->stats_cbarg = cbarg;
351*4882a593Smuzhiyun 	port->stats_busy  = BFA_TRUE;
352*4882a593Smuzhiyun 	bfa_dma_be_addr_set(m->dma_addr, port->stats_dma.pa);
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_GET_STATS_REQ,
355*4882a593Smuzhiyun 		    bfa_ioc_portid(port->ioc));
356*4882a593Smuzhiyun 	bfa_ioc_mbox_queue(port->ioc, &port->stats_mb);
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	return BFA_STATUS_OK;
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun /*
362*4882a593Smuzhiyun  * bfa_port_clear_stats()
363*4882a593Smuzhiyun  *
364*4882a593Smuzhiyun  *
365*4882a593Smuzhiyun  * @param[in] Pointer to the Port module data structure.
366*4882a593Smuzhiyun  *
367*4882a593Smuzhiyun  * @return Status
368*4882a593Smuzhiyun  */
369*4882a593Smuzhiyun bfa_status_t
bfa_port_clear_stats(struct bfa_port_s * port,bfa_port_stats_cbfn_t cbfn,void * cbarg)370*4882a593Smuzhiyun bfa_port_clear_stats(struct bfa_port_s *port, bfa_port_stats_cbfn_t cbfn,
371*4882a593Smuzhiyun 		      void *cbarg)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun 	struct bfi_port_generic_req_s *m;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	if (!bfa_ioc_is_operational(port->ioc)) {
376*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_IOC_FAILURE);
377*4882a593Smuzhiyun 		return BFA_STATUS_IOC_FAILURE;
378*4882a593Smuzhiyun 	}
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	if (port->stats_busy) {
381*4882a593Smuzhiyun 		bfa_trc(port, BFA_STATUS_DEVBUSY);
382*4882a593Smuzhiyun 		return BFA_STATUS_DEVBUSY;
383*4882a593Smuzhiyun 	}
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	m = (struct bfi_port_generic_req_s *) port->stats_mb.msg;
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	port->stats_cbfn  = cbfn;
388*4882a593Smuzhiyun 	port->stats_cbarg = cbarg;
389*4882a593Smuzhiyun 	port->stats_busy  = BFA_TRUE;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_CLEAR_STATS_REQ,
392*4882a593Smuzhiyun 		    bfa_ioc_portid(port->ioc));
393*4882a593Smuzhiyun 	bfa_ioc_mbox_queue(port->ioc, &port->stats_mb);
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	return BFA_STATUS_OK;
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun /*
399*4882a593Smuzhiyun  * bfa_port_notify()
400*4882a593Smuzhiyun  *
401*4882a593Smuzhiyun  * Port module IOC event handler
402*4882a593Smuzhiyun  *
403*4882a593Smuzhiyun  * @param[in] Pointer to the Port module data structure.
404*4882a593Smuzhiyun  * @param[in] IOC event structure
405*4882a593Smuzhiyun  *
406*4882a593Smuzhiyun  * @return void
407*4882a593Smuzhiyun  */
408*4882a593Smuzhiyun void
bfa_port_notify(void * arg,enum bfa_ioc_event_e event)409*4882a593Smuzhiyun bfa_port_notify(void *arg, enum bfa_ioc_event_e event)
410*4882a593Smuzhiyun {
411*4882a593Smuzhiyun 	struct bfa_port_s *port = (struct bfa_port_s *) arg;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	switch (event) {
414*4882a593Smuzhiyun 	case BFA_IOC_E_DISABLED:
415*4882a593Smuzhiyun 	case BFA_IOC_E_FAILED:
416*4882a593Smuzhiyun 		/* Fail any pending get_stats/clear_stats requests */
417*4882a593Smuzhiyun 		if (port->stats_busy) {
418*4882a593Smuzhiyun 			if (port->stats_cbfn)
419*4882a593Smuzhiyun 				port->stats_cbfn(port->stats_cbarg,
420*4882a593Smuzhiyun 						BFA_STATUS_FAILED);
421*4882a593Smuzhiyun 			port->stats_cbfn = NULL;
422*4882a593Smuzhiyun 			port->stats_busy = BFA_FALSE;
423*4882a593Smuzhiyun 		}
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 		/* Clear any enable/disable is pending */
426*4882a593Smuzhiyun 		if (port->endis_pending) {
427*4882a593Smuzhiyun 			if (port->endis_cbfn)
428*4882a593Smuzhiyun 				port->endis_cbfn(port->endis_cbarg,
429*4882a593Smuzhiyun 						BFA_STATUS_FAILED);
430*4882a593Smuzhiyun 			port->endis_cbfn = NULL;
431*4882a593Smuzhiyun 			port->endis_pending = BFA_FALSE;
432*4882a593Smuzhiyun 		}
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 		/* clear D-port mode */
435*4882a593Smuzhiyun 		if (port->dport_enabled)
436*4882a593Smuzhiyun 			bfa_port_set_dportenabled(port, BFA_FALSE);
437*4882a593Smuzhiyun 		break;
438*4882a593Smuzhiyun 	default:
439*4882a593Smuzhiyun 		break;
440*4882a593Smuzhiyun 	}
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun /*
444*4882a593Smuzhiyun  * bfa_port_attach()
445*4882a593Smuzhiyun  *
446*4882a593Smuzhiyun  *
447*4882a593Smuzhiyun  * @param[in] port - Pointer to the Port module data structure
448*4882a593Smuzhiyun  *            ioc  - Pointer to the ioc module data structure
449*4882a593Smuzhiyun  *            dev  - Pointer to the device driver module data structure
450*4882a593Smuzhiyun  *                   The device driver specific mbox ISR functions have
451*4882a593Smuzhiyun  *                   this pointer as one of the parameters.
452*4882a593Smuzhiyun  *            trcmod -
453*4882a593Smuzhiyun  *
454*4882a593Smuzhiyun  * @return void
455*4882a593Smuzhiyun  */
456*4882a593Smuzhiyun void
bfa_port_attach(struct bfa_port_s * port,struct bfa_ioc_s * ioc,void * dev,struct bfa_trc_mod_s * trcmod)457*4882a593Smuzhiyun bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
458*4882a593Smuzhiyun 		 void *dev, struct bfa_trc_mod_s *trcmod)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun 	WARN_ON(!port);
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	port->dev    = dev;
463*4882a593Smuzhiyun 	port->ioc    = ioc;
464*4882a593Smuzhiyun 	port->trcmod = trcmod;
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	port->stats_busy = BFA_FALSE;
467*4882a593Smuzhiyun 	port->endis_pending = BFA_FALSE;
468*4882a593Smuzhiyun 	port->stats_cbfn = NULL;
469*4882a593Smuzhiyun 	port->endis_cbfn = NULL;
470*4882a593Smuzhiyun 	port->pbc_disabled = BFA_FALSE;
471*4882a593Smuzhiyun 	port->dport_enabled = BFA_FALSE;
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port);
474*4882a593Smuzhiyun 	bfa_q_qe_init(&port->ioc_notify);
475*4882a593Smuzhiyun 	bfa_ioc_notify_init(&port->ioc_notify, bfa_port_notify, port);
476*4882a593Smuzhiyun 	list_add_tail(&port->ioc_notify.qe, &port->ioc->notify_q);
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 	/*
479*4882a593Smuzhiyun 	 * initialize time stamp for stats reset
480*4882a593Smuzhiyun 	 */
481*4882a593Smuzhiyun 	port->stats_reset_time = ktime_get_seconds();
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	bfa_trc(port, 0);
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun /*
487*4882a593Smuzhiyun  * bfa_port_set_dportenabled();
488*4882a593Smuzhiyun  *
489*4882a593Smuzhiyun  * Port module- set pbc disabled flag
490*4882a593Smuzhiyun  *
491*4882a593Smuzhiyun  * @param[in] port - Pointer to the Port module data structure
492*4882a593Smuzhiyun  *
493*4882a593Smuzhiyun  * @return void
494*4882a593Smuzhiyun  */
495*4882a593Smuzhiyun void
bfa_port_set_dportenabled(struct bfa_port_s * port,bfa_boolean_t enabled)496*4882a593Smuzhiyun bfa_port_set_dportenabled(struct bfa_port_s *port, bfa_boolean_t enabled)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun 	port->dport_enabled = enabled;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun /*
502*4882a593Smuzhiyun  *	CEE module specific definitions
503*4882a593Smuzhiyun  */
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun /*
506*4882a593Smuzhiyun  * bfa_cee_get_attr_isr()
507*4882a593Smuzhiyun  *
508*4882a593Smuzhiyun  * @brief CEE ISR for get-attributes responses from f/w
509*4882a593Smuzhiyun  *
510*4882a593Smuzhiyun  * @param[in] cee - Pointer to the CEE module
511*4882a593Smuzhiyun  *		    status - Return status from the f/w
512*4882a593Smuzhiyun  *
513*4882a593Smuzhiyun  * @return void
514*4882a593Smuzhiyun  */
515*4882a593Smuzhiyun static void
bfa_cee_get_attr_isr(struct bfa_cee_s * cee,bfa_status_t status)516*4882a593Smuzhiyun bfa_cee_get_attr_isr(struct bfa_cee_s *cee, bfa_status_t status)
517*4882a593Smuzhiyun {
518*4882a593Smuzhiyun 	struct bfa_cee_lldp_cfg_s *lldp_cfg = &cee->attr->lldp_remote;
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	cee->get_attr_status = status;
521*4882a593Smuzhiyun 	bfa_trc(cee, 0);
522*4882a593Smuzhiyun 	if (status == BFA_STATUS_OK) {
523*4882a593Smuzhiyun 		bfa_trc(cee, 0);
524*4882a593Smuzhiyun 		memcpy(cee->attr, cee->attr_dma.kva,
525*4882a593Smuzhiyun 			sizeof(struct bfa_cee_attr_s));
526*4882a593Smuzhiyun 		lldp_cfg->time_to_live = be16_to_cpu(lldp_cfg->time_to_live);
527*4882a593Smuzhiyun 		lldp_cfg->enabled_system_cap =
528*4882a593Smuzhiyun 				be16_to_cpu(lldp_cfg->enabled_system_cap);
529*4882a593Smuzhiyun 	}
530*4882a593Smuzhiyun 	cee->get_attr_pending = BFA_FALSE;
531*4882a593Smuzhiyun 	if (cee->cbfn.get_attr_cbfn) {
532*4882a593Smuzhiyun 		bfa_trc(cee, 0);
533*4882a593Smuzhiyun 		cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
534*4882a593Smuzhiyun 	}
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun /*
538*4882a593Smuzhiyun  * bfa_cee_get_stats_isr()
539*4882a593Smuzhiyun  *
540*4882a593Smuzhiyun  * @brief CEE ISR for get-stats responses from f/w
541*4882a593Smuzhiyun  *
542*4882a593Smuzhiyun  * @param[in] cee - Pointer to the CEE module
543*4882a593Smuzhiyun  *	      status - Return status from the f/w
544*4882a593Smuzhiyun  *
545*4882a593Smuzhiyun  * @return void
546*4882a593Smuzhiyun  */
547*4882a593Smuzhiyun static void
bfa_cee_get_stats_isr(struct bfa_cee_s * cee,bfa_status_t status)548*4882a593Smuzhiyun bfa_cee_get_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
549*4882a593Smuzhiyun {
550*4882a593Smuzhiyun 	u32 *buffer;
551*4882a593Smuzhiyun 	int i;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	cee->get_stats_status = status;
554*4882a593Smuzhiyun 	bfa_trc(cee, 0);
555*4882a593Smuzhiyun 	if (status == BFA_STATUS_OK) {
556*4882a593Smuzhiyun 		bfa_trc(cee, 0);
557*4882a593Smuzhiyun 		memcpy(cee->stats, cee->stats_dma.kva,
558*4882a593Smuzhiyun 			sizeof(struct bfa_cee_stats_s));
559*4882a593Smuzhiyun 		/* swap the cee stats */
560*4882a593Smuzhiyun 		buffer = (u32 *)cee->stats;
561*4882a593Smuzhiyun 		for (i = 0; i < (sizeof(struct bfa_cee_stats_s) /
562*4882a593Smuzhiyun 				 sizeof(u32)); i++)
563*4882a593Smuzhiyun 			buffer[i] = cpu_to_be32(buffer[i]);
564*4882a593Smuzhiyun 	}
565*4882a593Smuzhiyun 	cee->get_stats_pending = BFA_FALSE;
566*4882a593Smuzhiyun 	bfa_trc(cee, 0);
567*4882a593Smuzhiyun 	if (cee->cbfn.get_stats_cbfn) {
568*4882a593Smuzhiyun 		bfa_trc(cee, 0);
569*4882a593Smuzhiyun 		cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
570*4882a593Smuzhiyun 	}
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun /*
574*4882a593Smuzhiyun  * bfa_cee_reset_stats_isr()
575*4882a593Smuzhiyun  *
576*4882a593Smuzhiyun  * @brief CEE ISR for reset-stats responses from f/w
577*4882a593Smuzhiyun  *
578*4882a593Smuzhiyun  * @param[in] cee - Pointer to the CEE module
579*4882a593Smuzhiyun  *            status - Return status from the f/w
580*4882a593Smuzhiyun  *
581*4882a593Smuzhiyun  * @return void
582*4882a593Smuzhiyun  */
583*4882a593Smuzhiyun static void
bfa_cee_reset_stats_isr(struct bfa_cee_s * cee,bfa_status_t status)584*4882a593Smuzhiyun bfa_cee_reset_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
585*4882a593Smuzhiyun {
586*4882a593Smuzhiyun 	cee->reset_stats_status = status;
587*4882a593Smuzhiyun 	cee->reset_stats_pending = BFA_FALSE;
588*4882a593Smuzhiyun 	if (cee->cbfn.reset_stats_cbfn)
589*4882a593Smuzhiyun 		cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun /*
593*4882a593Smuzhiyun  * bfa_cee_meminfo()
594*4882a593Smuzhiyun  *
595*4882a593Smuzhiyun  * @brief Returns the size of the DMA memory needed by CEE module
596*4882a593Smuzhiyun  *
597*4882a593Smuzhiyun  * @param[in] void
598*4882a593Smuzhiyun  *
599*4882a593Smuzhiyun  * @return Size of DMA region
600*4882a593Smuzhiyun  */
601*4882a593Smuzhiyun u32
bfa_cee_meminfo(void)602*4882a593Smuzhiyun bfa_cee_meminfo(void)
603*4882a593Smuzhiyun {
604*4882a593Smuzhiyun 	return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ) +
605*4882a593Smuzhiyun 		BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s), BFA_DMA_ALIGN_SZ);
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun /*
609*4882a593Smuzhiyun  * bfa_cee_mem_claim()
610*4882a593Smuzhiyun  *
611*4882a593Smuzhiyun  * @brief Initialized CEE DMA Memory
612*4882a593Smuzhiyun  *
613*4882a593Smuzhiyun  * @param[in] cee CEE module pointer
614*4882a593Smuzhiyun  *            dma_kva Kernel Virtual Address of CEE DMA Memory
615*4882a593Smuzhiyun  *            dma_pa  Physical Address of CEE DMA Memory
616*4882a593Smuzhiyun  *
617*4882a593Smuzhiyun  * @return void
618*4882a593Smuzhiyun  */
619*4882a593Smuzhiyun void
bfa_cee_mem_claim(struct bfa_cee_s * cee,u8 * dma_kva,u64 dma_pa)620*4882a593Smuzhiyun bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa)
621*4882a593Smuzhiyun {
622*4882a593Smuzhiyun 	cee->attr_dma.kva = dma_kva;
623*4882a593Smuzhiyun 	cee->attr_dma.pa = dma_pa;
624*4882a593Smuzhiyun 	cee->stats_dma.kva = dma_kva + BFA_ROUNDUP(
625*4882a593Smuzhiyun 			     sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ);
626*4882a593Smuzhiyun 	cee->stats_dma.pa = dma_pa + BFA_ROUNDUP(
627*4882a593Smuzhiyun 			     sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ);
628*4882a593Smuzhiyun 	cee->attr = (struct bfa_cee_attr_s *) dma_kva;
629*4882a593Smuzhiyun 	cee->stats = (struct bfa_cee_stats_s *) (dma_kva + BFA_ROUNDUP(
630*4882a593Smuzhiyun 			sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ));
631*4882a593Smuzhiyun }
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun /*
634*4882a593Smuzhiyun  * bfa_cee_get_attr()
635*4882a593Smuzhiyun  *
636*4882a593Smuzhiyun  * @brief
637*4882a593Smuzhiyun  *   Send the request to the f/w to fetch CEE attributes.
638*4882a593Smuzhiyun  *
639*4882a593Smuzhiyun  * @param[in] Pointer to the CEE module data structure.
640*4882a593Smuzhiyun  *
641*4882a593Smuzhiyun  * @return Status
642*4882a593Smuzhiyun  */
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun bfa_status_t
bfa_cee_get_attr(struct bfa_cee_s * cee,struct bfa_cee_attr_s * attr,bfa_cee_get_attr_cbfn_t cbfn,void * cbarg)645*4882a593Smuzhiyun bfa_cee_get_attr(struct bfa_cee_s *cee, struct bfa_cee_attr_s *attr,
646*4882a593Smuzhiyun 		 bfa_cee_get_attr_cbfn_t cbfn, void *cbarg)
647*4882a593Smuzhiyun {
648*4882a593Smuzhiyun 	struct bfi_cee_get_req_s *cmd;
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun 	WARN_ON((cee == NULL) || (cee->ioc == NULL));
651*4882a593Smuzhiyun 	bfa_trc(cee, 0);
652*4882a593Smuzhiyun 	if (!bfa_ioc_is_operational(cee->ioc)) {
653*4882a593Smuzhiyun 		bfa_trc(cee, 0);
654*4882a593Smuzhiyun 		return BFA_STATUS_IOC_FAILURE;
655*4882a593Smuzhiyun 	}
656*4882a593Smuzhiyun 	if (cee->get_attr_pending == BFA_TRUE) {
657*4882a593Smuzhiyun 		bfa_trc(cee, 0);
658*4882a593Smuzhiyun 		return  BFA_STATUS_DEVBUSY;
659*4882a593Smuzhiyun 	}
660*4882a593Smuzhiyun 	cee->get_attr_pending = BFA_TRUE;
661*4882a593Smuzhiyun 	cmd = (struct bfi_cee_get_req_s *) cee->get_cfg_mb.msg;
662*4882a593Smuzhiyun 	cee->attr = attr;
663*4882a593Smuzhiyun 	cee->cbfn.get_attr_cbfn = cbfn;
664*4882a593Smuzhiyun 	cee->cbfn.get_attr_cbarg = cbarg;
665*4882a593Smuzhiyun 	bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ,
666*4882a593Smuzhiyun 		bfa_ioc_portid(cee->ioc));
667*4882a593Smuzhiyun 	bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa);
668*4882a593Smuzhiyun 	bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb);
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	return BFA_STATUS_OK;
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun /*
674*4882a593Smuzhiyun  * bfa_cee_get_stats()
675*4882a593Smuzhiyun  *
676*4882a593Smuzhiyun  * @brief
677*4882a593Smuzhiyun  *   Send the request to the f/w to fetch CEE statistics.
678*4882a593Smuzhiyun  *
679*4882a593Smuzhiyun  * @param[in] Pointer to the CEE module data structure.
680*4882a593Smuzhiyun  *
681*4882a593Smuzhiyun  * @return Status
682*4882a593Smuzhiyun  */
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun bfa_status_t
bfa_cee_get_stats(struct bfa_cee_s * cee,struct bfa_cee_stats_s * stats,bfa_cee_get_stats_cbfn_t cbfn,void * cbarg)685*4882a593Smuzhiyun bfa_cee_get_stats(struct bfa_cee_s *cee, struct bfa_cee_stats_s *stats,
686*4882a593Smuzhiyun 		  bfa_cee_get_stats_cbfn_t cbfn, void *cbarg)
687*4882a593Smuzhiyun {
688*4882a593Smuzhiyun 	struct bfi_cee_get_req_s *cmd;
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	WARN_ON((cee == NULL) || (cee->ioc == NULL));
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun 	if (!bfa_ioc_is_operational(cee->ioc)) {
693*4882a593Smuzhiyun 		bfa_trc(cee, 0);
694*4882a593Smuzhiyun 		return BFA_STATUS_IOC_FAILURE;
695*4882a593Smuzhiyun 	}
696*4882a593Smuzhiyun 	if (cee->get_stats_pending == BFA_TRUE) {
697*4882a593Smuzhiyun 		bfa_trc(cee, 0);
698*4882a593Smuzhiyun 		return  BFA_STATUS_DEVBUSY;
699*4882a593Smuzhiyun 	}
700*4882a593Smuzhiyun 	cee->get_stats_pending = BFA_TRUE;
701*4882a593Smuzhiyun 	cmd = (struct bfi_cee_get_req_s *) cee->get_stats_mb.msg;
702*4882a593Smuzhiyun 	cee->stats = stats;
703*4882a593Smuzhiyun 	cee->cbfn.get_stats_cbfn = cbfn;
704*4882a593Smuzhiyun 	cee->cbfn.get_stats_cbarg = cbarg;
705*4882a593Smuzhiyun 	bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ,
706*4882a593Smuzhiyun 		bfa_ioc_portid(cee->ioc));
707*4882a593Smuzhiyun 	bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa);
708*4882a593Smuzhiyun 	bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb);
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	return BFA_STATUS_OK;
711*4882a593Smuzhiyun }
712*4882a593Smuzhiyun 
713*4882a593Smuzhiyun /*
714*4882a593Smuzhiyun  * bfa_cee_reset_stats()
715*4882a593Smuzhiyun  *
716*4882a593Smuzhiyun  * @brief Clears CEE Stats in the f/w.
717*4882a593Smuzhiyun  *
718*4882a593Smuzhiyun  * @param[in] Pointer to the CEE module data structure.
719*4882a593Smuzhiyun  *
720*4882a593Smuzhiyun  * @return Status
721*4882a593Smuzhiyun  */
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun bfa_status_t
bfa_cee_reset_stats(struct bfa_cee_s * cee,bfa_cee_reset_stats_cbfn_t cbfn,void * cbarg)724*4882a593Smuzhiyun bfa_cee_reset_stats(struct bfa_cee_s *cee,
725*4882a593Smuzhiyun 		    bfa_cee_reset_stats_cbfn_t cbfn, void *cbarg)
726*4882a593Smuzhiyun {
727*4882a593Smuzhiyun 	struct bfi_cee_reset_stats_s *cmd;
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun 	WARN_ON((cee == NULL) || (cee->ioc == NULL));
730*4882a593Smuzhiyun 	if (!bfa_ioc_is_operational(cee->ioc)) {
731*4882a593Smuzhiyun 		bfa_trc(cee, 0);
732*4882a593Smuzhiyun 		return BFA_STATUS_IOC_FAILURE;
733*4882a593Smuzhiyun 	}
734*4882a593Smuzhiyun 	if (cee->reset_stats_pending == BFA_TRUE) {
735*4882a593Smuzhiyun 		bfa_trc(cee, 0);
736*4882a593Smuzhiyun 		return  BFA_STATUS_DEVBUSY;
737*4882a593Smuzhiyun 	}
738*4882a593Smuzhiyun 	cee->reset_stats_pending = BFA_TRUE;
739*4882a593Smuzhiyun 	cmd = (struct bfi_cee_reset_stats_s *) cee->reset_stats_mb.msg;
740*4882a593Smuzhiyun 	cee->cbfn.reset_stats_cbfn = cbfn;
741*4882a593Smuzhiyun 	cee->cbfn.reset_stats_cbarg = cbarg;
742*4882a593Smuzhiyun 	bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS,
743*4882a593Smuzhiyun 		bfa_ioc_portid(cee->ioc));
744*4882a593Smuzhiyun 	bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb);
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun 	return BFA_STATUS_OK;
747*4882a593Smuzhiyun }
748*4882a593Smuzhiyun 
749*4882a593Smuzhiyun /*
750*4882a593Smuzhiyun  * bfa_cee_isrs()
751*4882a593Smuzhiyun  *
752*4882a593Smuzhiyun  * @brief Handles Mail-box interrupts for CEE module.
753*4882a593Smuzhiyun  *
754*4882a593Smuzhiyun  * @param[in] Pointer to the CEE module data structure.
755*4882a593Smuzhiyun  *
756*4882a593Smuzhiyun  * @return void
757*4882a593Smuzhiyun  */
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun static void
bfa_cee_isr(void * cbarg,struct bfi_mbmsg_s * m)760*4882a593Smuzhiyun bfa_cee_isr(void *cbarg, struct bfi_mbmsg_s *m)
761*4882a593Smuzhiyun {
762*4882a593Smuzhiyun 	union bfi_cee_i2h_msg_u *msg;
763*4882a593Smuzhiyun 	struct bfi_cee_get_rsp_s *get_rsp;
764*4882a593Smuzhiyun 	struct bfa_cee_s *cee = (struct bfa_cee_s *) cbarg;
765*4882a593Smuzhiyun 	msg = (union bfi_cee_i2h_msg_u *) m;
766*4882a593Smuzhiyun 	get_rsp = (struct bfi_cee_get_rsp_s *) m;
767*4882a593Smuzhiyun 	bfa_trc(cee, msg->mh.msg_id);
768*4882a593Smuzhiyun 	switch (msg->mh.msg_id) {
769*4882a593Smuzhiyun 	case BFI_CEE_I2H_GET_CFG_RSP:
770*4882a593Smuzhiyun 		bfa_trc(cee, get_rsp->cmd_status);
771*4882a593Smuzhiyun 		bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
772*4882a593Smuzhiyun 		break;
773*4882a593Smuzhiyun 	case BFI_CEE_I2H_GET_STATS_RSP:
774*4882a593Smuzhiyun 		bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
775*4882a593Smuzhiyun 		break;
776*4882a593Smuzhiyun 	case BFI_CEE_I2H_RESET_STATS_RSP:
777*4882a593Smuzhiyun 		bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
778*4882a593Smuzhiyun 		break;
779*4882a593Smuzhiyun 	default:
780*4882a593Smuzhiyun 		WARN_ON(1);
781*4882a593Smuzhiyun 	}
782*4882a593Smuzhiyun }
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun /*
785*4882a593Smuzhiyun  * bfa_cee_notify()
786*4882a593Smuzhiyun  *
787*4882a593Smuzhiyun  * @brief CEE module IOC event handler.
788*4882a593Smuzhiyun  *
789*4882a593Smuzhiyun  * @param[in] Pointer to the CEE module data structure.
790*4882a593Smuzhiyun  * @param[in] IOC event type
791*4882a593Smuzhiyun  *
792*4882a593Smuzhiyun  * @return void
793*4882a593Smuzhiyun  */
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun static void
bfa_cee_notify(void * arg,enum bfa_ioc_event_e event)796*4882a593Smuzhiyun bfa_cee_notify(void *arg, enum bfa_ioc_event_e event)
797*4882a593Smuzhiyun {
798*4882a593Smuzhiyun 	struct bfa_cee_s *cee = (struct bfa_cee_s *) arg;
799*4882a593Smuzhiyun 
800*4882a593Smuzhiyun 	bfa_trc(cee, event);
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun 	switch (event) {
803*4882a593Smuzhiyun 	case BFA_IOC_E_DISABLED:
804*4882a593Smuzhiyun 	case BFA_IOC_E_FAILED:
805*4882a593Smuzhiyun 		if (cee->get_attr_pending == BFA_TRUE) {
806*4882a593Smuzhiyun 			cee->get_attr_status = BFA_STATUS_FAILED;
807*4882a593Smuzhiyun 			cee->get_attr_pending  = BFA_FALSE;
808*4882a593Smuzhiyun 			if (cee->cbfn.get_attr_cbfn) {
809*4882a593Smuzhiyun 				cee->cbfn.get_attr_cbfn(
810*4882a593Smuzhiyun 					cee->cbfn.get_attr_cbarg,
811*4882a593Smuzhiyun 					BFA_STATUS_FAILED);
812*4882a593Smuzhiyun 			}
813*4882a593Smuzhiyun 		}
814*4882a593Smuzhiyun 		if (cee->get_stats_pending == BFA_TRUE) {
815*4882a593Smuzhiyun 			cee->get_stats_status = BFA_STATUS_FAILED;
816*4882a593Smuzhiyun 			cee->get_stats_pending  = BFA_FALSE;
817*4882a593Smuzhiyun 			if (cee->cbfn.get_stats_cbfn) {
818*4882a593Smuzhiyun 				cee->cbfn.get_stats_cbfn(
819*4882a593Smuzhiyun 				cee->cbfn.get_stats_cbarg,
820*4882a593Smuzhiyun 				BFA_STATUS_FAILED);
821*4882a593Smuzhiyun 			}
822*4882a593Smuzhiyun 		}
823*4882a593Smuzhiyun 		if (cee->reset_stats_pending == BFA_TRUE) {
824*4882a593Smuzhiyun 			cee->reset_stats_status = BFA_STATUS_FAILED;
825*4882a593Smuzhiyun 			cee->reset_stats_pending  = BFA_FALSE;
826*4882a593Smuzhiyun 			if (cee->cbfn.reset_stats_cbfn) {
827*4882a593Smuzhiyun 				cee->cbfn.reset_stats_cbfn(
828*4882a593Smuzhiyun 				cee->cbfn.reset_stats_cbarg,
829*4882a593Smuzhiyun 				BFA_STATUS_FAILED);
830*4882a593Smuzhiyun 			}
831*4882a593Smuzhiyun 		}
832*4882a593Smuzhiyun 		break;
833*4882a593Smuzhiyun 
834*4882a593Smuzhiyun 	default:
835*4882a593Smuzhiyun 		break;
836*4882a593Smuzhiyun 	}
837*4882a593Smuzhiyun }
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun /*
840*4882a593Smuzhiyun  * bfa_cee_attach()
841*4882a593Smuzhiyun  *
842*4882a593Smuzhiyun  * @brief CEE module-attach API
843*4882a593Smuzhiyun  *
844*4882a593Smuzhiyun  * @param[in] cee - Pointer to the CEE module data structure
845*4882a593Smuzhiyun  *            ioc - Pointer to the ioc module data structure
846*4882a593Smuzhiyun  *            dev - Pointer to the device driver module data structure
847*4882a593Smuzhiyun  *                  The device driver specific mbox ISR functions have
848*4882a593Smuzhiyun  *                  this pointer as one of the parameters.
849*4882a593Smuzhiyun  *
850*4882a593Smuzhiyun  * @return void
851*4882a593Smuzhiyun  */
852*4882a593Smuzhiyun void
bfa_cee_attach(struct bfa_cee_s * cee,struct bfa_ioc_s * ioc,void * dev)853*4882a593Smuzhiyun bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc,
854*4882a593Smuzhiyun 		void *dev)
855*4882a593Smuzhiyun {
856*4882a593Smuzhiyun 	WARN_ON(cee == NULL);
857*4882a593Smuzhiyun 	cee->dev = dev;
858*4882a593Smuzhiyun 	cee->ioc = ioc;
859*4882a593Smuzhiyun 
860*4882a593Smuzhiyun 	bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
861*4882a593Smuzhiyun 	bfa_q_qe_init(&cee->ioc_notify);
862*4882a593Smuzhiyun 	bfa_ioc_notify_init(&cee->ioc_notify, bfa_cee_notify, cee);
863*4882a593Smuzhiyun 	list_add_tail(&cee->ioc_notify.qe, &cee->ioc->notify_q);
864*4882a593Smuzhiyun }
865