49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Copyright (c) 2008-2016 Solarflare Communications Inc.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * All rights reserved.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Redistribution and use in source and binary forms, with or without
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * modification, are permitted provided that the following conditions are met:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * 1. Redistributions of source code must retain the above copyright notice,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * this list of conditions and the following disclaimer.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * 2. Redistributions in binary form must reproduce the above copyright notice,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * this list of conditions and the following disclaimer in the documentation
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * and/or other materials provided with the distribution.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * The views and conclusions contained in the software and documentation are
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * those of the authors and should not be interpreted as representing official
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * policies, either expressed or implied, of the FreeBSD Project.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/types.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/sysmacros.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/ddi.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/sunddi.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include "sfxge.h"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include "efx.h"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/* Monitor DMA attributes */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic ddi_device_acc_attr_t sfxge_mon_devacc = {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_DEVICE_ATTR_V0, /* devacc_attr_version */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_NEVERSWAP_ACC, /* devacc_attr_endian_flags */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_STRICTORDER_ACC /* devacc_attr_dataorder */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore};
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic ddi_dma_attr_t sfxge_mon_dma_attr = {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DMA_ATTR_V0, /* dma_attr_version */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0, /* dma_attr_addr_lo */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0xffffffffffffffffull, /* dma_attr_addr_hi */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0xffffffffffffffffull, /* dma_attr_count_max */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0x1000, /* dma_attr_align */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0xffffffff, /* dma_attr_burstsizes */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 1, /* dma_attr_minxfer */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0xffffffffffffffffull, /* dma_attr_maxxfer */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0xffffffffffffffffull, /* dma_attr_seg */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 1, /* dma_attr_sgllen */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 1, /* dma_attr_granular */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0 /* dma_attr_flags */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore};
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_mon_kstat_update(kstat_t *ksp, int rw)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_t *sp = ksp->ks_private;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_mon_t *smp = &(sp->s_mon);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efsys_mem_t *esmp = &(smp->sm_mem);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_nic_t *enp = sp->s_enp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kstat_named_t *knp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore const efx_nic_cfg_t *encp = efx_nic_cfg_get(sp->s_enp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc, sn;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (rw != KSTAT_READ) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = EACCES;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT(mutex_owned(&(smp->sm_lock)));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (smp->sm_state != SFXGE_MON_STARTED)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto done;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (smp->sm_polling) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = efx_mon_stats_update(enp, esmp, smp->sm_statbuf);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (rc != 0)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp = smp->sm_stat;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore for (sn = 0; sn < EFX_MON_NSTATS; sn++) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (encp->enc_mon_stat_mask[sn / EFX_MON_MASK_ELEMENT_SIZE] &
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (1 << (sn % EFX_MON_MASK_ELEMENT_SIZE))) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp->value.ui64 = smp->sm_statbuf[sn].emsv_value;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp++;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp->value.ui32 = sp->s_num_restarts;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp++;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp->value.ui32 = sp->s_num_restarts_hw_err;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp++;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp->value.ui32 = smp->sm_polling;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp++;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredone:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail2:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail2);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(fail1, int, rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_mon_kstat_init(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_mon_t *smp = &(sp->s_mon);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_info_t *dip = sp->s_dip;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_nic_t *enp = sp->s_enp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kstat_t *ksp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kstat_named_t *knp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore char name[MAXNAMELEN];
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore unsigned int id;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore const efx_nic_cfg_t *encp = efx_nic_cfg_get(sp->s_enp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int nstat;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((smp->sm_statbuf = kmem_zalloc(sizeof (uint32_t) * EFX_MON_NSTATS,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore KM_NOSLEEP)) == NULL) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENOMEM;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) snprintf(name, MAXNAMELEN - 1, "%s_%s", ddi_driver_name(dip),
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_mon_name(enp));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Create the set */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore for (id = 0, nstat = 0; id < EFX_MON_NSTATS; id++) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (encp->enc_mon_stat_mask[id / EFX_MON_MASK_ELEMENT_SIZE] &
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (1 << (id % EFX_MON_MASK_ELEMENT_SIZE))) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore nstat++;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((ksp = kstat_create((char *)ddi_driver_name(dip),
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ddi_get_instance(dip), name, "mon", KSTAT_TYPE_NAMED,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore nstat+3, 0)) == NULL) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENOMEM;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_ksp = ksp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ksp->ks_update = sfxge_mon_kstat_update;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ksp->ks_private = sp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ksp->ks_lock = &(smp->sm_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Initialise the named stats */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_stat = knp = ksp->ks_data;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore for (id = 0; id < EFX_MON_NSTATS; id++) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (encp->enc_mon_stat_mask[id / EFX_MON_MASK_ELEMENT_SIZE] &
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (1 << (id % EFX_MON_MASK_ELEMENT_SIZE))) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kstat_named_init(knp,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (char *)efx_mon_stat_name(enp, id),
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore KSTAT_DATA_UINT64);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp++;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kstat_named_init(knp, "num_restarts", KSTAT_DATA_UINT32);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp++;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kstat_named_init(knp, "num_restarts_hw_err", KSTAT_DATA_UINT32);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp++;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kstat_named_init(knp, "mon_polling", KSTAT_DATA_UINT32);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore knp++;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kstat_install(ksp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail2:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail2);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kmem_free(smp->sm_statbuf, sizeof (uint32_t) * EFX_MON_NSTATS);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(fail1, int, rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic void
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_mon_kstat_fini(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_mon_t *smp = &(sp->s_mon);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Destroy the set */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kstat_delete(smp->sm_ksp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_ksp = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_stat = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kmem_free(smp->sm_statbuf, sizeof (uint32_t) * EFX_MON_NSTATS);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_mon_init(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_mon_t *smp = &(sp->s_mon);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_nic_t *enp = sp->s_enp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efsys_mem_t *esmp = &(smp->sm_mem);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_dma_buffer_attr_t dma_attr;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore SFXGE_OBJ_CHECK(smp, sfxge_mon_t);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(smp->sm_state, ==, SFXGE_MON_UNINITIALIZED);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_sp = sp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_init(&(smp->sm_lock), NULL, MUTEX_DRIVER, NULL);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_dip = sp->s_dip;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_dattrp = &sfxge_mon_dma_attr;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_callback = DDI_DMA_SLEEP;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_length = encp->enc_mon_stat_dma_buf_size;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_memflags = DDI_DMA_CONSISTENT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_devaccp = &sfxge_mon_devacc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_bindflags = DDI_DMA_READ | DDI_DMA_CONSISTENT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_maxcookies = 1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_zeroinit = B_TRUE;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((rc = sfxge_dma_buffer_create(esmp, &dma_attr)) != 0)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_type = encp->enc_mon_type;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(mon, efx_mon_type_t, smp->sm_type);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_state = SFXGE_MON_INITIALIZED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Initialize the statistics */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((rc = sfxge_mon_kstat_init(sp)) != 0)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail2:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail2);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Tear down DMA setup */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_dma_buffer_destroy(esmp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(fail1, int, rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_destroy(&(smp->sm_lock));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_sp = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore SFXGE_OBJ_CHECK(smp, sfxge_mac_t);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_mon_start(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_mon_t *smp = &(sp->s_mon);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_enter(&(smp->sm_lock));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(smp->sm_state, ==, SFXGE_MON_INITIALIZED);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Initialize the MON module */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((rc = efx_mon_init(sp->s_enp)) != 0)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_state = SFXGE_MON_STARTED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_exit(&(smp->sm_lock));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(fail1, int, rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_exit(&(smp->sm_lock));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_mon_stop(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_mon_t *smp = &(sp->s_mon);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_enter(&(smp->sm_lock));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(smp->sm_state, ==, SFXGE_MON_STARTED);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_state = SFXGE_MON_INITIALIZED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Tear down the MON module */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_mon_fini(sp->s_enp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_exit(&(smp->sm_lock));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_mon_fini(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_mon_t *smp = &(sp->s_mon);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efsys_mem_t *esmp = &(smp->sm_mem);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(smp->sm_state, ==, SFXGE_MON_INITIALIZED);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Tear down the statistics */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_mon_kstat_fini(sp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_state = SFXGE_MON_UNINITIALIZED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_destroy(&(smp->sm_lock));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_sp = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore smp->sm_type = EFX_MON_INVALID;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Tear down DMA setup */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_dma_buffer_destroy(esmp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore SFXGE_OBJ_CHECK(smp, sfxge_mon_t);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}