1*49ef7e06SGarrett D'Amore /*
2*49ef7e06SGarrett D'Amore  * Copyright (c) 2008-2016 Solarflare Communications Inc.
3*49ef7e06SGarrett D'Amore  * All rights reserved.
4*49ef7e06SGarrett D'Amore  *
5*49ef7e06SGarrett D'Amore  * Redistribution and use in source and binary forms, with or without
6*49ef7e06SGarrett D'Amore  * modification, are permitted provided that the following conditions are met:
7*49ef7e06SGarrett D'Amore  *
8*49ef7e06SGarrett D'Amore  * 1. Redistributions of source code must retain the above copyright notice,
9*49ef7e06SGarrett D'Amore  *    this list of conditions and the following disclaimer.
10*49ef7e06SGarrett D'Amore  * 2. Redistributions in binary form must reproduce the above copyright notice,
11*49ef7e06SGarrett D'Amore  *    this list of conditions and the following disclaimer in the documentation
12*49ef7e06SGarrett D'Amore  *    and/or other materials provided with the distribution.
13*49ef7e06SGarrett D'Amore  *
14*49ef7e06SGarrett D'Amore  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15*49ef7e06SGarrett D'Amore  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16*49ef7e06SGarrett D'Amore  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17*49ef7e06SGarrett D'Amore  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18*49ef7e06SGarrett D'Amore  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19*49ef7e06SGarrett D'Amore  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20*49ef7e06SGarrett D'Amore  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21*49ef7e06SGarrett D'Amore  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22*49ef7e06SGarrett D'Amore  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23*49ef7e06SGarrett D'Amore  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24*49ef7e06SGarrett D'Amore  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*49ef7e06SGarrett D'Amore  *
26*49ef7e06SGarrett D'Amore  * The views and conclusions contained in the software and documentation are
27*49ef7e06SGarrett D'Amore  * those of the authors and should not be interpreted as representing official
28*49ef7e06SGarrett D'Amore  * policies, either expressed or implied, of the FreeBSD Project.
29*49ef7e06SGarrett D'Amore  */
30*49ef7e06SGarrett D'Amore 
31*49ef7e06SGarrett D'Amore #include <sys/types.h>
32*49ef7e06SGarrett D'Amore #include <sys/sysmacros.h>
33*49ef7e06SGarrett D'Amore #include <sys/ddi.h>
34*49ef7e06SGarrett D'Amore #include <sys/sunddi.h>
35*49ef7e06SGarrett D'Amore 
36*49ef7e06SGarrett D'Amore #include "sfxge.h"
37*49ef7e06SGarrett D'Amore 
38*49ef7e06SGarrett D'Amore #include "efx.h"
39*49ef7e06SGarrett D'Amore 
40*49ef7e06SGarrett D'Amore /* Monitor DMA attributes */
41*49ef7e06SGarrett D'Amore static ddi_device_acc_attr_t sfxge_mon_devacc = {
42*49ef7e06SGarrett D'Amore 
43*49ef7e06SGarrett D'Amore 	DDI_DEVICE_ATTR_V0,	/* devacc_attr_version */
44*49ef7e06SGarrett D'Amore 	DDI_NEVERSWAP_ACC,	/* devacc_attr_endian_flags */
45*49ef7e06SGarrett D'Amore 	DDI_STRICTORDER_ACC	/* devacc_attr_dataorder */
46*49ef7e06SGarrett D'Amore };
47*49ef7e06SGarrett D'Amore 
48*49ef7e06SGarrett D'Amore static ddi_dma_attr_t sfxge_mon_dma_attr = {
49*49ef7e06SGarrett D'Amore 	DMA_ATTR_V0,		/* dma_attr_version	*/
50*49ef7e06SGarrett D'Amore 	0,			/* dma_attr_addr_lo	*/
51*49ef7e06SGarrett D'Amore 	0xffffffffffffffffull,	/* dma_attr_addr_hi	*/
52*49ef7e06SGarrett D'Amore 	0xffffffffffffffffull,	/* dma_attr_count_max	*/
53*49ef7e06SGarrett D'Amore 	0x1000,			/* dma_attr_align	*/
54*49ef7e06SGarrett D'Amore 	0xffffffff,		/* dma_attr_burstsizes	*/
55*49ef7e06SGarrett D'Amore 	1,			/* dma_attr_minxfer	*/
56*49ef7e06SGarrett D'Amore 	0xffffffffffffffffull,	/* dma_attr_maxxfer	*/
57*49ef7e06SGarrett D'Amore 	0xffffffffffffffffull,	/* dma_attr_seg		*/
58*49ef7e06SGarrett D'Amore 	1,			/* dma_attr_sgllen	*/
59*49ef7e06SGarrett D'Amore 	1,			/* dma_attr_granular	*/
60*49ef7e06SGarrett D'Amore 	0			/* dma_attr_flags	*/
61*49ef7e06SGarrett D'Amore };
62*49ef7e06SGarrett D'Amore 
63*49ef7e06SGarrett D'Amore 
64*49ef7e06SGarrett D'Amore static int
sfxge_mon_kstat_update(kstat_t * ksp,int rw)65*49ef7e06SGarrett D'Amore sfxge_mon_kstat_update(kstat_t *ksp, int rw)
66*49ef7e06SGarrett D'Amore {
67*49ef7e06SGarrett D'Amore 	sfxge_t *sp = ksp->ks_private;
68*49ef7e06SGarrett D'Amore 	sfxge_mon_t *smp = &(sp->s_mon);
69*49ef7e06SGarrett D'Amore 	efsys_mem_t *esmp = &(smp->sm_mem);
70*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = sp->s_enp;
71*49ef7e06SGarrett D'Amore 	kstat_named_t *knp;
72*49ef7e06SGarrett D'Amore 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sp->s_enp);
73*49ef7e06SGarrett D'Amore 	int rc, sn;
74*49ef7e06SGarrett D'Amore 
75*49ef7e06SGarrett D'Amore 	if (rw != KSTAT_READ) {
76*49ef7e06SGarrett D'Amore 		rc = EACCES;
77*49ef7e06SGarrett D'Amore 		goto fail1;
78*49ef7e06SGarrett D'Amore 	}
79*49ef7e06SGarrett D'Amore 
80*49ef7e06SGarrett D'Amore 	ASSERT(mutex_owned(&(smp->sm_lock)));
81*49ef7e06SGarrett D'Amore 
82*49ef7e06SGarrett D'Amore 	if (smp->sm_state != SFXGE_MON_STARTED)
83*49ef7e06SGarrett D'Amore 		goto done;
84*49ef7e06SGarrett D'Amore 
85*49ef7e06SGarrett D'Amore 	if (smp->sm_polling) {
86*49ef7e06SGarrett D'Amore 		rc = efx_mon_stats_update(enp, esmp, smp->sm_statbuf);
87*49ef7e06SGarrett D'Amore 		if (rc != 0)
88*49ef7e06SGarrett D'Amore 			goto fail2;
89*49ef7e06SGarrett D'Amore 	}
90*49ef7e06SGarrett D'Amore 
91*49ef7e06SGarrett D'Amore 	knp = smp->sm_stat;
92*49ef7e06SGarrett D'Amore 	for (sn = 0; sn < EFX_MON_NSTATS; sn++) {
93*49ef7e06SGarrett D'Amore 		if (encp->enc_mon_stat_mask[sn / EFX_MON_MASK_ELEMENT_SIZE] &
94*49ef7e06SGarrett D'Amore 		    (1 << (sn % EFX_MON_MASK_ELEMENT_SIZE)))  {
95*49ef7e06SGarrett D'Amore 			knp->value.ui64 = smp->sm_statbuf[sn].emsv_value;
96*49ef7e06SGarrett D'Amore 			knp++;
97*49ef7e06SGarrett D'Amore 		}
98*49ef7e06SGarrett D'Amore 	}
99*49ef7e06SGarrett D'Amore 
100*49ef7e06SGarrett D'Amore 	knp->value.ui32 = sp->s_num_restarts;
101*49ef7e06SGarrett D'Amore 	knp++;
102*49ef7e06SGarrett D'Amore 	knp->value.ui32 = sp->s_num_restarts_hw_err;
103*49ef7e06SGarrett D'Amore 	knp++;
104*49ef7e06SGarrett D'Amore 	knp->value.ui32 = smp->sm_polling;
105*49ef7e06SGarrett D'Amore 	knp++;
106*49ef7e06SGarrett D'Amore 
107*49ef7e06SGarrett D'Amore done:
108*49ef7e06SGarrett D'Amore 	return (0);
109*49ef7e06SGarrett D'Amore 
110*49ef7e06SGarrett D'Amore fail2:
111*49ef7e06SGarrett D'Amore 	DTRACE_PROBE(fail2);
112*49ef7e06SGarrett D'Amore fail1:
113*49ef7e06SGarrett D'Amore 	DTRACE_PROBE1(fail1, int, rc);
114*49ef7e06SGarrett D'Amore 
115*49ef7e06SGarrett D'Amore 	return (rc);
116*49ef7e06SGarrett D'Amore }
117*49ef7e06SGarrett D'Amore 
118*49ef7e06SGarrett D'Amore static int
sfxge_mon_kstat_init(sfxge_t * sp)119*49ef7e06SGarrett D'Amore sfxge_mon_kstat_init(sfxge_t *sp)
120*49ef7e06SGarrett D'Amore {
121*49ef7e06SGarrett D'Amore 	sfxge_mon_t *smp = &(sp->s_mon);
122*49ef7e06SGarrett D'Amore 	dev_info_t *dip = sp->s_dip;
123*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = sp->s_enp;
124*49ef7e06SGarrett D'Amore 	kstat_t *ksp;
125*49ef7e06SGarrett D'Amore 	kstat_named_t *knp;
126*49ef7e06SGarrett D'Amore 	char name[MAXNAMELEN];
127*49ef7e06SGarrett D'Amore 	unsigned int id;
128*49ef7e06SGarrett D'Amore 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sp->s_enp);
129*49ef7e06SGarrett D'Amore 	int rc;
130*49ef7e06SGarrett D'Amore 	int nstat;
131*49ef7e06SGarrett D'Amore 
132*49ef7e06SGarrett D'Amore 	if ((smp->sm_statbuf = kmem_zalloc(sizeof (uint32_t) * EFX_MON_NSTATS,
133*49ef7e06SGarrett D'Amore 	    KM_NOSLEEP)) == NULL) {
134*49ef7e06SGarrett D'Amore 		rc = ENOMEM;
135*49ef7e06SGarrett D'Amore 		goto fail1;
136*49ef7e06SGarrett D'Amore 	}
137*49ef7e06SGarrett D'Amore 
138*49ef7e06SGarrett D'Amore 	(void) snprintf(name, MAXNAMELEN - 1, "%s_%s", ddi_driver_name(dip),
139*49ef7e06SGarrett D'Amore 	    efx_mon_name(enp));
140*49ef7e06SGarrett D'Amore 
141*49ef7e06SGarrett D'Amore 
142*49ef7e06SGarrett D'Amore 	/* Create the set */
143*49ef7e06SGarrett D'Amore 	for (id = 0, nstat = 0; id < EFX_MON_NSTATS; id++) {
144*49ef7e06SGarrett D'Amore 		if (encp->enc_mon_stat_mask[id / EFX_MON_MASK_ELEMENT_SIZE] &
145*49ef7e06SGarrett D'Amore 		    (1 << (id % EFX_MON_MASK_ELEMENT_SIZE)))  {
146*49ef7e06SGarrett D'Amore 			nstat++;
147*49ef7e06SGarrett D'Amore 		}
148*49ef7e06SGarrett D'Amore 	}
149*49ef7e06SGarrett D'Amore 
150*49ef7e06SGarrett D'Amore 	if ((ksp = kstat_create((char *)ddi_driver_name(dip),
151*49ef7e06SGarrett D'Amore 	    ddi_get_instance(dip), name, "mon", KSTAT_TYPE_NAMED,
152*49ef7e06SGarrett D'Amore 	    nstat+3, 0)) == NULL) {
153*49ef7e06SGarrett D'Amore 		rc = ENOMEM;
154*49ef7e06SGarrett D'Amore 		goto fail2;
155*49ef7e06SGarrett D'Amore 	}
156*49ef7e06SGarrett D'Amore 
157*49ef7e06SGarrett D'Amore 	smp->sm_ksp = ksp;
158*49ef7e06SGarrett D'Amore 
159*49ef7e06SGarrett D'Amore 	ksp->ks_update = sfxge_mon_kstat_update;
160*49ef7e06SGarrett D'Amore 	ksp->ks_private = sp;
161*49ef7e06SGarrett D'Amore 	ksp->ks_lock = &(smp->sm_lock);
162*49ef7e06SGarrett D'Amore 
163*49ef7e06SGarrett D'Amore 	/* Initialise the named stats */
164*49ef7e06SGarrett D'Amore 	smp->sm_stat = knp = ksp->ks_data;
165*49ef7e06SGarrett D'Amore 	for (id = 0; id < EFX_MON_NSTATS; id++) {
166*49ef7e06SGarrett D'Amore 		if (encp->enc_mon_stat_mask[id / EFX_MON_MASK_ELEMENT_SIZE] &
167*49ef7e06SGarrett D'Amore 		    (1 << (id % EFX_MON_MASK_ELEMENT_SIZE)))  {
168*49ef7e06SGarrett D'Amore 			kstat_named_init(knp,
169*49ef7e06SGarrett D'Amore 			    (char *)efx_mon_stat_name(enp, id),
170*49ef7e06SGarrett D'Amore 			    KSTAT_DATA_UINT64);
171*49ef7e06SGarrett D'Amore 			knp++;
172*49ef7e06SGarrett D'Amore 		}
173*49ef7e06SGarrett D'Amore 	}
174*49ef7e06SGarrett D'Amore 	kstat_named_init(knp, "num_restarts", KSTAT_DATA_UINT32);
175*49ef7e06SGarrett D'Amore 	knp++;
176*49ef7e06SGarrett D'Amore 	kstat_named_init(knp, "num_restarts_hw_err", KSTAT_DATA_UINT32);
177*49ef7e06SGarrett D'Amore 	knp++;
178*49ef7e06SGarrett D'Amore 	kstat_named_init(knp, "mon_polling", KSTAT_DATA_UINT32);
179*49ef7e06SGarrett D'Amore 	knp++;
180*49ef7e06SGarrett D'Amore 
181*49ef7e06SGarrett D'Amore 	kstat_install(ksp);
182*49ef7e06SGarrett D'Amore 
183*49ef7e06SGarrett D'Amore 	return (0);
184*49ef7e06SGarrett D'Amore 
185*49ef7e06SGarrett D'Amore fail2:
186*49ef7e06SGarrett D'Amore 	DTRACE_PROBE(fail2);
187*49ef7e06SGarrett D'Amore 	kmem_free(smp->sm_statbuf, sizeof (uint32_t) * EFX_MON_NSTATS);
188*49ef7e06SGarrett D'Amore fail1:
189*49ef7e06SGarrett D'Amore 	DTRACE_PROBE1(fail1, int, rc);
190*49ef7e06SGarrett D'Amore 
191*49ef7e06SGarrett D'Amore 	return (rc);
192*49ef7e06SGarrett D'Amore }
193*49ef7e06SGarrett D'Amore 
194*49ef7e06SGarrett D'Amore static void
sfxge_mon_kstat_fini(sfxge_t * sp)195*49ef7e06SGarrett D'Amore sfxge_mon_kstat_fini(sfxge_t *sp)
196*49ef7e06SGarrett D'Amore {
197*49ef7e06SGarrett D'Amore 	sfxge_mon_t *smp = &(sp->s_mon);
198*49ef7e06SGarrett D'Amore 
199*49ef7e06SGarrett D'Amore 	/* Destroy the set */
200*49ef7e06SGarrett D'Amore 	kstat_delete(smp->sm_ksp);
201*49ef7e06SGarrett D'Amore 	smp->sm_ksp = NULL;
202*49ef7e06SGarrett D'Amore 	smp->sm_stat = NULL;
203*49ef7e06SGarrett D'Amore 
204*49ef7e06SGarrett D'Amore 	kmem_free(smp->sm_statbuf, sizeof (uint32_t) * EFX_MON_NSTATS);
205*49ef7e06SGarrett D'Amore }
206*49ef7e06SGarrett D'Amore 
207*49ef7e06SGarrett D'Amore int
sfxge_mon_init(sfxge_t * sp)208*49ef7e06SGarrett D'Amore sfxge_mon_init(sfxge_t *sp)
209*49ef7e06SGarrett D'Amore {
210*49ef7e06SGarrett D'Amore 	sfxge_mon_t *smp = &(sp->s_mon);
211*49ef7e06SGarrett D'Amore 	efx_nic_t *enp = sp->s_enp;
212*49ef7e06SGarrett D'Amore 	efsys_mem_t *esmp = &(smp->sm_mem);
213*49ef7e06SGarrett D'Amore 	sfxge_dma_buffer_attr_t dma_attr;
214*49ef7e06SGarrett D'Amore 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
215*49ef7e06SGarrett D'Amore 	int rc;
216*49ef7e06SGarrett D'Amore 
217*49ef7e06SGarrett D'Amore 	SFXGE_OBJ_CHECK(smp, sfxge_mon_t);
218*49ef7e06SGarrett D'Amore 
219*49ef7e06SGarrett D'Amore 	ASSERT3U(smp->sm_state, ==, SFXGE_MON_UNINITIALIZED);
220*49ef7e06SGarrett D'Amore 
221*49ef7e06SGarrett D'Amore 	smp->sm_sp = sp;
222*49ef7e06SGarrett D'Amore 
223*49ef7e06SGarrett D'Amore 	mutex_init(&(smp->sm_lock), NULL, MUTEX_DRIVER, NULL);
224*49ef7e06SGarrett D'Amore 
225*49ef7e06SGarrett D'Amore 	dma_attr.sdba_dip	 = sp->s_dip;
226*49ef7e06SGarrett D'Amore 	dma_attr.sdba_dattrp	 = &sfxge_mon_dma_attr;
227*49ef7e06SGarrett D'Amore 	dma_attr.sdba_callback	 = DDI_DMA_SLEEP;
228*49ef7e06SGarrett D'Amore 	dma_attr.sdba_length	 = encp->enc_mon_stat_dma_buf_size;
229*49ef7e06SGarrett D'Amore 	dma_attr.sdba_memflags	 = DDI_DMA_CONSISTENT;
230*49ef7e06SGarrett D'Amore 	dma_attr.sdba_devaccp	 = &sfxge_mon_devacc;
231*49ef7e06SGarrett D'Amore 	dma_attr.sdba_bindflags	 = DDI_DMA_READ | DDI_DMA_CONSISTENT;
232*49ef7e06SGarrett D'Amore 	dma_attr.sdba_maxcookies = 1;
233*49ef7e06SGarrett D'Amore 	dma_attr.sdba_zeroinit	 = B_TRUE;
234*49ef7e06SGarrett D'Amore 
235*49ef7e06SGarrett D'Amore 	if ((rc = sfxge_dma_buffer_create(esmp, &dma_attr)) != 0)
236*49ef7e06SGarrett D'Amore 		goto fail1;
237*49ef7e06SGarrett D'Amore 
238*49ef7e06SGarrett D'Amore 	smp->sm_type = encp->enc_mon_type;
239*49ef7e06SGarrett D'Amore 
240*49ef7e06SGarrett D'Amore 	DTRACE_PROBE1(mon, efx_mon_type_t, smp->sm_type);
241*49ef7e06SGarrett D'Amore 
242*49ef7e06SGarrett D'Amore 	smp->sm_state = SFXGE_MON_INITIALIZED;
243*49ef7e06SGarrett D'Amore 
244*49ef7e06SGarrett D'Amore 	/* Initialize the statistics */
245*49ef7e06SGarrett D'Amore 	if ((rc = sfxge_mon_kstat_init(sp)) != 0)
246*49ef7e06SGarrett D'Amore 		goto fail2;
247*49ef7e06SGarrett D'Amore 
248*49ef7e06SGarrett D'Amore 	return (0);
249*49ef7e06SGarrett D'Amore 
250*49ef7e06SGarrett D'Amore fail2:
251*49ef7e06SGarrett D'Amore 	DTRACE_PROBE(fail2);
252*49ef7e06SGarrett D'Amore 
253*49ef7e06SGarrett D'Amore 	/* Tear down DMA setup */
254*49ef7e06SGarrett D'Amore 	sfxge_dma_buffer_destroy(esmp);
255*49ef7e06SGarrett D'Amore 
256*49ef7e06SGarrett D'Amore fail1:
257*49ef7e06SGarrett D'Amore 	DTRACE_PROBE1(fail1, int, rc);
258*49ef7e06SGarrett D'Amore 	mutex_destroy(&(smp->sm_lock));
259*49ef7e06SGarrett D'Amore 
260*49ef7e06SGarrett D'Amore 	smp->sm_sp = NULL;
261*49ef7e06SGarrett D'Amore 
262*49ef7e06SGarrett D'Amore 	SFXGE_OBJ_CHECK(smp, sfxge_mac_t);
263*49ef7e06SGarrett D'Amore 
264*49ef7e06SGarrett D'Amore 	return (rc);
265*49ef7e06SGarrett D'Amore }
266*49ef7e06SGarrett D'Amore 
267*49ef7e06SGarrett D'Amore int
sfxge_mon_start(sfxge_t * sp)268*49ef7e06SGarrett D'Amore sfxge_mon_start(sfxge_t *sp)
269*49ef7e06SGarrett D'Amore {
270*49ef7e06SGarrett D'Amore 	sfxge_mon_t *smp = &(sp->s_mon);
271*49ef7e06SGarrett D'Amore 	int rc;
272*49ef7e06SGarrett D'Amore 
273*49ef7e06SGarrett D'Amore 	mutex_enter(&(smp->sm_lock));
274*49ef7e06SGarrett D'Amore 	ASSERT3U(smp->sm_state, ==, SFXGE_MON_INITIALIZED);
275*49ef7e06SGarrett D'Amore 
276*49ef7e06SGarrett D'Amore 	/* Initialize the MON module */
277*49ef7e06SGarrett D'Amore 	if ((rc = efx_mon_init(sp->s_enp)) != 0)
278*49ef7e06SGarrett D'Amore 		goto fail1;
279*49ef7e06SGarrett D'Amore 
280*49ef7e06SGarrett D'Amore 	smp->sm_state = SFXGE_MON_STARTED;
281*49ef7e06SGarrett D'Amore 
282*49ef7e06SGarrett D'Amore 	mutex_exit(&(smp->sm_lock));
283*49ef7e06SGarrett D'Amore 
284*49ef7e06SGarrett D'Amore 	return (0);
285*49ef7e06SGarrett D'Amore 
286*49ef7e06SGarrett D'Amore fail1:
287*49ef7e06SGarrett D'Amore 	DTRACE_PROBE1(fail1, int, rc);
288*49ef7e06SGarrett D'Amore 
289*49ef7e06SGarrett D'Amore 	mutex_exit(&(smp->sm_lock));
290*49ef7e06SGarrett D'Amore 
291*49ef7e06SGarrett D'Amore 	return (rc);
292*49ef7e06SGarrett D'Amore }
293*49ef7e06SGarrett D'Amore 
294*49ef7e06SGarrett D'Amore void
sfxge_mon_stop(sfxge_t * sp)295*49ef7e06SGarrett D'Amore sfxge_mon_stop(sfxge_t *sp)
296*49ef7e06SGarrett D'Amore {
297*49ef7e06SGarrett D'Amore 	sfxge_mon_t *smp = &(sp->s_mon);
298*49ef7e06SGarrett D'Amore 
299*49ef7e06SGarrett D'Amore 	mutex_enter(&(smp->sm_lock));
300*49ef7e06SGarrett D'Amore 
301*49ef7e06SGarrett D'Amore 	ASSERT3U(smp->sm_state, ==, SFXGE_MON_STARTED);
302*49ef7e06SGarrett D'Amore 	smp->sm_state = SFXGE_MON_INITIALIZED;
303*49ef7e06SGarrett D'Amore 
304*49ef7e06SGarrett D'Amore 	/* Tear down the MON module */
305*49ef7e06SGarrett D'Amore 	efx_mon_fini(sp->s_enp);
306*49ef7e06SGarrett D'Amore 
307*49ef7e06SGarrett D'Amore 	mutex_exit(&(smp->sm_lock));
308*49ef7e06SGarrett D'Amore }
309*49ef7e06SGarrett D'Amore 
310*49ef7e06SGarrett D'Amore void
sfxge_mon_fini(sfxge_t * sp)311*49ef7e06SGarrett D'Amore sfxge_mon_fini(sfxge_t *sp)
312*49ef7e06SGarrett D'Amore {
313*49ef7e06SGarrett D'Amore 	sfxge_mon_t *smp = &(sp->s_mon);
314*49ef7e06SGarrett D'Amore 	efsys_mem_t *esmp = &(smp->sm_mem);
315*49ef7e06SGarrett D'Amore 
316*49ef7e06SGarrett D'Amore 	ASSERT3U(smp->sm_state, ==, SFXGE_MON_INITIALIZED);
317*49ef7e06SGarrett D'Amore 
318*49ef7e06SGarrett D'Amore 	/* Tear down the statistics */
319*49ef7e06SGarrett D'Amore 	sfxge_mon_kstat_fini(sp);
320*49ef7e06SGarrett D'Amore 
321*49ef7e06SGarrett D'Amore 	smp->sm_state = SFXGE_MON_UNINITIALIZED;
322*49ef7e06SGarrett D'Amore 	mutex_destroy(&(smp->sm_lock));
323*49ef7e06SGarrett D'Amore 
324*49ef7e06SGarrett D'Amore 	smp->sm_sp = NULL;
325*49ef7e06SGarrett D'Amore 	smp->sm_type = EFX_MON_INVALID;
326*49ef7e06SGarrett D'Amore 
327*49ef7e06SGarrett D'Amore 	/* Tear down DMA setup */
328*49ef7e06SGarrett D'Amore 	sfxge_dma_buffer_destroy(esmp);
329*49ef7e06SGarrett D'Amore 
330*49ef7e06SGarrett D'Amore 	SFXGE_OBJ_CHECK(smp, sfxge_mon_t);
331*49ef7e06SGarrett D'Amore }
332