9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER START
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The contents of this file are subject to the terms of the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Common Development and Distribution License (the "License").
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You may not use this file except in compliance with the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * or http://www.opensolaris.org/os/licensing.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * See the License for the specific language governing permissions
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and limitations under the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * When distributing Covered Code, include this CDDL HEADER in each
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If applicable, add the following below this CDDL HEADER, with the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER END
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Use is subject to license terms.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_stats.c
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Hermon IB Performance Statistics routines
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Implements all the routines necessary for setting up, querying, and
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (later) tearing down all the kstats necessary for implementing to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the interfaces necessary to provide busstat(1M) access.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/types.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/conf.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/ddi.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/sunddi.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/modctl.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/ib/adapters/hermon/hermon.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic kstat_t *hermon_kstat_picN_create(hermon_state_t *state, int num_pic,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int num_evt, hermon_ks_mask_t *ev_array);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic kstat_t *hermon_kstat_cntr_create(hermon_state_t *state, int num_pic,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int (*update)(kstat_t *, int));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_kstat_cntr_update(kstat_t *ksp, int rw);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalavoid hermon_kstat_perfcntr64_create(hermon_state_t *state, uint_t port_num);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalastatic int hermon_kstat_perfcntr64_read(hermon_state_t *state, uint_t port,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala int reset);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalastatic void hermon_kstat_perfcntr64_thread_exit(hermon_ks_info_t *ksi);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalastatic int hermon_kstat_perfcntr64_update(kstat_t *ksp, int rw);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Hermon IB Performance Events structure
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This structure is read-only and is used to setup the individual kstats
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and to initialize the tki_ib_perfcnt[] array for each Hermon instance.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_ks_mask_t hermon_ib_perfcnt_list[HERMON_CNTR_NUMENTRIES] = {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"port_xmit_data", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"port_recv_data", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"port_xmit_pkts", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"port_recv_pkts", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"port_recv_err", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"port_xmit_discards", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"vl15_dropped", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"port_xmit_wait", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"port_recv_remote_phys_err", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"port_xmit_constraint_err", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"port_recv_constraint_err", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"symbol_err_counter", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"link_err_recovery_cnt", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"link_downed_cnt", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"excessive_buffer_overruns", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"local_link_integrity_err", 0, 0},
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor {"clear_pic", 0, 0}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor};
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala/*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Return the maximum of (x) and (y)
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala#define MAX(x, y) (((x) > (y)) ? (x) : (y))
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala/*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Set (x) to the maximum of (x) and (y)
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala#define SET_TO_MAX(x, y) \
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala{ \
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if ((x) < (y)) \
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala (x) = (y); \
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_kstat_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorint
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_kstat_init(hermon_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_ks_info_t *ksi;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t numports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Allocate a kstat info structure */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi = (hermon_ks_info_t *)kmem_zalloc(sizeof (hermon_ks_info_t),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor KM_SLEEP);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ksi == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->hs_ks_info = ksi;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Create as many "pic" and perfcntr64 kstats as we have IB ports.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Enable all of the events specified in the "hermon_ib_perfcnt_list"
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * structure.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor numports = state->hs_cfg_profile->cp_num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < numports; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi->hki_picN_ksp[i] = hermon_kstat_picN_create(state, i,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_CNTR_NUMENTRIES, hermon_ib_perfcnt_list);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ksi->hki_picN_ksp[i] == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto kstat_init_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_kstat_perfcntr64_create(state, i + 1);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (ksi->hki_perfcntr64[i].hki64_ksp == NULL) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala goto kstat_init_fail;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Create the "counters" kstat too */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi->hki_cntr_ksp = hermon_kstat_cntr_create(state, numports,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_kstat_cntr_update);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ksi->hki_cntr_ksp == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto kstat_init_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize the control register and initial counter values */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi->hki_pcr = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi->hki_pic0 = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi->hki_pic1 = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Initialize the Hermon hki_ib_perfcnt[] array values using the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * default values in hermon_ib_perfcnt_list[]
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < HERMON_CNTR_NUMENTRIES; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi->hki_ib_perfcnt[i] = hermon_ib_perfcnt_list[i];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala mutex_init(&ksi->hki_perfcntr64_lock, NULL, MUTEX_DRIVER, NULL);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala cv_init(&ksi->hki_perfcntr64_cv, NULL, CV_DRIVER, NULL);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorkstat_init_fail:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Delete all the previously created kstats */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ksi->hki_cntr_ksp != NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kstat_delete(ksi->hki_cntr_ksp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < numports; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ksi->hki_picN_ksp[i] != NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kstat_delete(ksi->hki_picN_ksp[i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (ksi->hki_perfcntr64[i].hki64_ksp != NULL) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala kstat_delete(ksi->hki_perfcntr64[i].hki64_ksp);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free the kstat info structure */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(ksi, sizeof (hermon_ks_info_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_kstat_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorvoid
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_kstat_fini(hermon_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_ks_info_t *ksi;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t numports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get pointer to kstat info */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi = state->hs_ks_info;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Signal the perfcntr64_update_thread to exit and wait until the
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * thread exits.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala mutex_enter(&ksi->hki_perfcntr64_lock);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_kstat_perfcntr64_thread_exit(ksi);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala mutex_exit(&ksi->hki_perfcntr64_lock);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /* Delete all the "pic" and perfcntr64 kstats (one per port) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor numports = state->hs_cfg_profile->cp_num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < numports; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ksi->hki_picN_ksp[i] != NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kstat_delete(ksi->hki_picN_ksp[i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (ksi->hki_perfcntr64[i].hki64_ksp != NULL) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala kstat_delete(ksi->hki_perfcntr64[i].hki64_ksp);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Delete the "counter" kstats (one per port) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kstat_delete(ksi->hki_cntr_ksp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala cv_destroy(&ksi->hki_perfcntr64_cv);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala mutex_destroy(&ksi->hki_perfcntr64_lock);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free the kstat info structure */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(ksi, sizeof (hermon_ks_info_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_kstat_picN_create()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic kstat_t *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_kstat_picN_create(hermon_state_t *state, int num_pic, int num_evt,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_ks_mask_t *ev_array)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kstat_t *picN_ksp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct kstat_named *pic_named_data;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int drv_instance, i;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor char *drv_name;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor char pic_name[16];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Create the "picN" kstat. In the steps, below we will attach
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * all of our named event types to it.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor drv_name = (char *)ddi_driver_name(state->hs_dip);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor drv_instance = ddi_get_instance(state->hs_dip);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) sprintf(pic_name, "pic%d", num_pic);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor picN_ksp = kstat_create(drv_name, drv_instance, pic_name, "bus",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor KSTAT_TYPE_NAMED, num_evt, NULL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (picN_ksp == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (NULL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pic_named_data = (struct kstat_named *)(picN_ksp->ks_data);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Write event names and their associated pcr masks. The last entry
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * in the array (clear_pic) is added separately below (as its pic
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * value must be inverted).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_evt - 1; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pic_named_data[i].value.ui64 =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((uint64_t)i << (num_pic * HERMON_CNTR_SIZE));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kstat_named_init(&pic_named_data[i], ev_array[i].ks_evt_name,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor KSTAT_DATA_UINT64);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Add the "clear_pic" entry */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pic_named_data[i].value.ui64 =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ~((uint64_t)HERMON_CNTR_MASK << (num_pic * HERMON_CNTR_SIZE));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kstat_named_init(&pic_named_data[i], ev_array[i].ks_evt_name,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor KSTAT_DATA_UINT64);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Install the kstat */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kstat_install(picN_ksp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (picN_ksp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_kstat_cntr_create()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic kstat_t *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_kstat_cntr_create(hermon_state_t *state, int num_pic,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int (*update)(kstat_t *, int))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct kstat *cntr_ksp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct kstat_named *cntr_named_data;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int drv_instance, i;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor char *drv_name;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor char pic_str[16];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Create the "counters" kstat. In the steps, below we will attach
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * all of our "pic" to it. Note: The size of this kstat is
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * num_pic + 1 because it also contains the "%pcr".
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor drv_name = (char *)ddi_driver_name(state->hs_dip);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor drv_instance = ddi_get_instance(state->hs_dip);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cntr_ksp = kstat_create(drv_name, drv_instance, "counters", "bus",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor KSTAT_TYPE_NAMED, num_pic + 1, KSTAT_FLAG_WRITABLE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (cntr_ksp == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (NULL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cntr_named_data = (struct kstat_named *)(cntr_ksp->ks_data);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Initialize the named kstats (for the "pcr" and for the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * individual "pic" kstats)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kstat_named_init(&cntr_named_data[0], "pcr", KSTAT_DATA_UINT64);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_pic; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) sprintf(pic_str, "pic%d", i);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kstat_named_init(&cntr_named_data[i+1], pic_str,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor KSTAT_DATA_UINT64);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Store the Hermon softstate pointer in the kstat's private field so
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that it is available to the update function.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cntr_ksp->ks_private = (void *)state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cntr_ksp->ks_update = update;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Install the kstat */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kstat_install(cntr_ksp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (cntr_ksp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_kstat_cntr_update()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Called from the kstat context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_kstat_cntr_update(kstat_t *ksp, int rw)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_state_t *state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_ks_mask_t *ib_perf;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_ks_info_t *ksi;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct kstat_named *data;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint64_t pcr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t tmp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t oldval;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t numports, indx;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_sm_perfcntr_t sm_perfcntr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Extract the Hermon softstate pointer, kstat data, pointer to the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * kstat info structure, and pointer to the hki_ib_perfcnt[] array
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * from the input parameters. Note: For warlock purposes, these
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * parameters are all accessed only in this routine and are,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * therefore, protected by the lock used by the kstat framework.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state = ksp->ks_private;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor data = (struct kstat_named *)(ksp->ks_data);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi = state->hs_ks_info;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ib_perf = &ksi->hki_ib_perfcnt[0];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ksi))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*data))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ib_perf))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Depending on whether we are reading the "pic" counters or
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * writing the "pcr" control register, we need to handle and
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fill in the kstat data appropriately.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If this is a write to the "pcr", then extract the value from
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the kstat data and store it in the kstat info structure.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Otherwise, if this is a read of the "pic" counter(s), then
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * extract the register offset, size, and mask values from the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * ib_perf[] array. Then read the corresponding register and store
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * it into the kstat data. Note: We only read/fill in pic1 if more
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * than one port is configured.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor numports = state->hs_cfg_profile->cp_num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (rw == KSTAT_WRITE) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Update the stored "pcr" value */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi->hki_pcr = data[0].value.ui64;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Get the current "pcr" value and extract the lower
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * portion (corresponding to the counters for "pic0")
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pcr = ksi->hki_pcr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor indx = pcr & HERMON_CNTR_MASK;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor data[0].value.ui64 = pcr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Fill in the "pic0" counter, corresponding to port 1.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This involves reading in the current value in the register
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and calculating how many events have happened since this
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * register was last polled. Then we save away the current
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * value for the counter and increment the "pic0" total by
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the number of new events.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor oldval = ib_perf[indx].ks_old_pic0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_getperfcntr_cmd_post(state, 1,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala HERMON_CMD_NOSLEEP_SPIN, &sm_perfcntr, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != HERMON_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor switch (indx) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 0: /* port_xmit_data */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portxmdata;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 1: /* port_recv_data */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portrcdata;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 2: /* port_xmit_pkts */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portxmpkts;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 3: /* port_recv_pkts */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portrcpkts;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 4: /* port_recv_err */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portrcv;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 5: /* port_xmit_discards */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portxmdiscard;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 6: /* vl15_dropped */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.vl15drop;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 7: /* port_xmit_wait */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portxmwait;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 8: /* port_recv_remote_phys_err */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portrcvrem;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 9: /* port_xmit_constraint_err */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portxmconstr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 10: /* port_recv_constraint_err */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portrcconstr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 11: /* symbol_err_counter */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.symerr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 12: /* link_err_recovery_cnt */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.linkerrrec;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 13: /* link_downed_cnt */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.linkdown;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 14: /* excessive_buffer_overruns */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.xsbuffovrun;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 15: /* local_link_integrity_err */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.locallinkint;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 16: /* clear_pic */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = 0; /* XXX */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor default:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "perf counter out of range\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ib_perf[indx].ks_old_pic0 = tmp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = tmp - oldval;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi->hki_pic0 += tmp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor data[1].value.ui64 = ksi->hki_pic0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If necessary, fill in the "pic1" counter for port 2.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This works the same as above except that we extract the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * upper bits (corresponding to the counters for "pic1")
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (numports == HERMON_MAX_PORTS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor indx = pcr >> HERMON_CNTR_SIZE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor oldval = ib_perf[indx].ks_old_pic1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_getperfcntr_cmd_post(state, 2,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala HERMON_CMD_NOSLEEP_SPIN, &sm_perfcntr, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != HERMON_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor switch (indx) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 0: /* port_xmit_data */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portxmdata;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 1: /* port_recv_data */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portrcdata;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 2: /* port_xmit_pkts */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portxmpkts;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 3: /* port_recv_pkts */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portrcpkts;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 4: /* port_recv_err */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portrcv;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 5: /* port_xmit_discards */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portxmdiscard;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 6: /* vl15_dropped */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.vl15drop;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 7: /* port_xmit_wait */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portxmwait;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 8: /* port_recv_remote_phys_err */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portrcvrem;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 9: /* port_xmit_constraint_err */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portxmconstr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 10: /* port_recv_constraint_err */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.portrcconstr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 11: /* symbol_err_counter */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.symerr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 12: /* link_err_recovery_cnt */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.linkerrrec;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 13: /* link_downed_cnt */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.linkdown;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 14: /* excessive_buffer_overruns */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.xsbuffovrun;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 15: /* local_link_integrity_err */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = sm_perfcntr.locallinkint;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 16: /* clear_pic */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = 0; /* XXX */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor default:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "perf counter out of range\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ib_perf[indx].ks_old_pic1 = tmp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp = tmp - oldval;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ksi->hki_pic1 += tmp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor data[2].value.ui64 = ksi->hki_pic1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala/*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * 64 bit kstats for performance counters:
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * Export 64 bit performance counters in kstats.
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala *
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * If the HCA hardware supports 64 bit extended port counters, we use the
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * hardware based counters. If the HCA hardware does not support extended port
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * counters, we maintain 64 bit performance counters in software using the
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * 32 bit hardware port counters.
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala *
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * The software based counters are maintained as follows:
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * We create a thread that, every one second, reads the values of 32 bit
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * hardware counters and adds them to the 64 bit software counters. Immediately
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * after reading, it resets the 32 bit hardware counters to zero (so that they
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * start counting from zero again). At any time the current value of a counter
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * is going to be the sum of the 64 bit software counter and the 32 bit
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * hardware counter.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Since this work need not be done if there is no consumer, by default
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * we do not maintain 64 bit software counters. To enable this the consumer
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * needs to write a non-zero value to the "enable" component of the of
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * perf_counters kstat. Writing zero to this component will disable this work.
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * NOTE: The enabling or disabling applies to software based counters only.
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * Hardware based counters counters are always enabled.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * If performance monitor is enabled in subnet manager, the SM could
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * periodically reset the hardware counters by sending perf-MADs. So only
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * one of either our software 64 bit counters or the SM performance monitor
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * could be enabled at the same time. However, if both of them are enabled at
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * the same time we still do our best by keeping track of the values of the
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * last read 32 bit hardware counters. If the current read of a 32 bit hardware
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * counter is less than the last read of the counter, we ignore the current
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * value and go with the last read value.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala/*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * hermon_kstat_perfcntr64_create()
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Context: Only called from attach() path context
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Create "port#/perf_counters" kstat for the specified port number.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalavoid
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalahermon_kstat_perfcntr64_create(hermon_state_t *state, uint_t port_num)
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala{
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_ks_info_t *ksi = state->hs_ks_info;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala struct kstat *cntr_ksp;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala struct kstat_named *cntr_named_data;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala int drv_instance;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala char *drv_name;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala char kname[32];
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala int status, ext_width_supported;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ASSERT(port_num != 0);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala status = hermon_is_ext_port_counters_supported(state, port_num,
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala HERMON_CMD_NOSLEEP_SPIN, &ext_width_supported);
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala if (status == HERMON_CMD_SUCCESS) {
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala ksi->hki_perfcntr64[port_num - 1].
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala hki64_ext_port_counters_supported = ext_width_supported;
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala }
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala drv_name = (char *)ddi_driver_name(state->hs_dip);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala drv_instance = ddi_get_instance(state->hs_dip);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala (void) snprintf(kname, sizeof (kname), "port%u/perf_counters",
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala port_num);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala cntr_ksp = kstat_create(drv_name, drv_instance, kname, "ib",
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala KSTAT_TYPE_NAMED, HERMON_PERFCNTR64_NUM_COUNTERS,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala KSTAT_FLAG_WRITABLE);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (cntr_ksp == NULL) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala return;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala cntr_named_data = (struct kstat_named *)(cntr_ksp->ks_data);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala kstat_named_init(&cntr_named_data[HERMON_PERFCNTR64_ENABLE_IDX],
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala "enable", KSTAT_DATA_UINT32);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala kstat_named_init(&cntr_named_data[HERMON_PERFCNTR64_XMIT_DATA_IDX],
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala "xmit_data", KSTAT_DATA_UINT64);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala kstat_named_init(&cntr_named_data[HERMON_PERFCNTR64_RECV_DATA_IDX],
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala "recv_data", KSTAT_DATA_UINT64);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala kstat_named_init(&cntr_named_data[HERMON_PERFCNTR64_XMIT_PKTS_IDX],
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala "xmit_pkts", KSTAT_DATA_UINT64);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala kstat_named_init(&cntr_named_data[HERMON_PERFCNTR64_RECV_PKTS_IDX],
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala "recv_pkts", KSTAT_DATA_UINT64);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi->hki_perfcntr64[port_num - 1].hki64_ksp = cntr_ksp;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi->hki_perfcntr64[port_num - 1].hki64_port_num = port_num;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi->hki_perfcntr64[port_num - 1].hki64_state = state;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala cntr_ksp->ks_private = &ksi->hki_perfcntr64[port_num - 1];
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala cntr_ksp->ks_update = hermon_kstat_perfcntr64_update;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /* Install the kstat */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala kstat_install(cntr_ksp);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala}
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala/*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * hermon_kstat_perfcntr64_read()
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Read the values of 32 bit hardware counters.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * If reset is true, reset the 32 bit hardware counters. Add the values of the
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * 32 bit hardware counters to the 64 bit software counters.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * If reset is false, just save the values read from the 32 bit hardware
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * counters in hki64_last_read[].
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * See the general comment on the 64 bit performance counters
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * regarding the use of last read 32 bit hardware counter values.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalastatic int
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalahermon_kstat_perfcntr64_read(hermon_state_t *state, uint_t port, int reset)
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala{
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_ks_info_t *ksi = state->hs_ks_info;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_perfcntr64_ks_info_t *ksi64 = &ksi->hki_perfcntr64[port - 1];
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala int status, i;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala uint32_t tmp;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_hw_sm_perfcntr_t sm_perfcntr;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ASSERT(MUTEX_HELD(&ksi->hki_perfcntr64_lock));
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ASSERT(port != 0);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /* read the 32 bit hardware counters */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala status = hermon_getperfcntr_cmd_post(state, port,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala HERMON_CMD_NOSLEEP_SPIN, &sm_perfcntr, 0);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (status != HERMON_CMD_SUCCESS) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala return (status);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (reset) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /* reset the hardware counters */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala status = hermon_getperfcntr_cmd_post(state, port,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala HERMON_CMD_NOSLEEP_SPIN, NULL, 1);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (status != HERMON_CMD_SUCCESS) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala return (status);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Update 64 bit software counters
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala tmp = MAX(sm_perfcntr.portxmdata,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_XMIT_DATA_IDX]);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_counters[HERMON_PERFCNTR64_XMIT_DATA_IDX] += tmp;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala tmp = MAX(sm_perfcntr.portrcdata,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_RECV_DATA_IDX]);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_counters[HERMON_PERFCNTR64_RECV_DATA_IDX] += tmp;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala tmp = MAX(sm_perfcntr.portxmpkts,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_XMIT_PKTS_IDX]);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_counters[HERMON_PERFCNTR64_XMIT_PKTS_IDX] += tmp;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala tmp = MAX(sm_perfcntr.portrcpkts,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_RECV_PKTS_IDX]);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_counters[HERMON_PERFCNTR64_RECV_PKTS_IDX] += tmp;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala for (i = 0; i < HERMON_PERFCNTR64_NUM_COUNTERS; i++)
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[i] = 0;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala } else {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Update ksi64->hki64_last_read[]
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala SET_TO_MAX(
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_XMIT_DATA_IDX],
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala sm_perfcntr.portxmdata);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala SET_TO_MAX(
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_RECV_DATA_IDX],
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala sm_perfcntr.portrcdata);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala SET_TO_MAX(
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_XMIT_PKTS_IDX],
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala sm_perfcntr.portxmpkts);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala SET_TO_MAX(
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_RECV_PKTS_IDX],
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala sm_perfcntr.portrcpkts);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala return (HERMON_CMD_SUCCESS);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala}
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala/*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * hermon_kstat_perfcntr64_update_thread()
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Context: Entry point for a kernel thread
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Maintain 64 bit performance counters in software using the 32 bit
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * hardware counters.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalastatic void
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalahermon_kstat_perfcntr64_update_thread(void *arg)
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala{
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_state_t *state = (hermon_state_t *)arg;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_ks_info_t *ksi = state->hs_ks_info;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala uint_t i;
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni clock_t delta = drv_usectohz(1000000);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala mutex_enter(&ksi->hki_perfcntr64_lock);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Every one second update the values 64 bit software counters
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * for all ports. Exit if HERMON_PERFCNTR64_THREAD_EXIT flag is set.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala while (!(ksi->hki_perfcntr64_flags & HERMON_PERFCNTR64_THREAD_EXIT)) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala for (i = 0; i < state->hs_cfg_profile->cp_num_ports; i++) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (ksi->hki_perfcntr64[i].hki64_enabled) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala (void) hermon_kstat_perfcntr64_read(state,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala i + 1, 1);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /* sleep for a second */
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni (void) cv_reltimedwait(&ksi->hki_perfcntr64_cv,
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni &ksi->hki_perfcntr64_lock, delta, TR_CLOCK_TICK);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi->hki_perfcntr64_flags = 0;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala mutex_exit(&ksi->hki_perfcntr64_lock);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala}
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala/*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * hermon_kstat_perfcntr64_thread_create()
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Context: Called from the kstat context
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Create a thread that maintains 64 bit performance counters in software.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalastatic void
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalahermon_kstat_perfcntr64_thread_create(hermon_state_t *state)
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala{
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_ks_info_t *ksi = state->hs_ks_info;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala kthread_t *thr;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ASSERT(MUTEX_HELD(&ksi->hki_perfcntr64_lock));
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * One thread per hermon instance. Don't create a thread if already
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * created.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (!(ksi->hki_perfcntr64_flags & HERMON_PERFCNTR64_THREAD_CREATED)) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala thr = thread_create(NULL, 0,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_kstat_perfcntr64_update_thread,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala state, 0, &p0, TS_RUN, minclsyspri);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi->hki_perfcntr64_thread_id = thr->t_did;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi->hki_perfcntr64_flags |= HERMON_PERFCNTR64_THREAD_CREATED;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala}
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala/*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * hermon_kstat_perfcntr64_thread_exit()
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Context: Called from attach, detach or kstat context
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalastatic void
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalahermon_kstat_perfcntr64_thread_exit(hermon_ks_info_t *ksi)
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala{
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala kt_did_t tid;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ASSERT(MUTEX_HELD(&ksi->hki_perfcntr64_lock));
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (ksi->hki_perfcntr64_flags & HERMON_PERFCNTR64_THREAD_CREATED) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Signal the thread to exit and wait until the thread exits.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi->hki_perfcntr64_flags |= HERMON_PERFCNTR64_THREAD_EXIT;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala tid = ksi->hki_perfcntr64_thread_id;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala cv_signal(&ksi->hki_perfcntr64_cv);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala mutex_exit(&ksi->hki_perfcntr64_lock);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala thread_join(tid);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala mutex_enter(&ksi->hki_perfcntr64_lock);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala}
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala/*
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * hermon_kstat_perfcntr64_update_ext()
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * Context: Called from the kstat context
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala *
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * Update perf_counters kstats with the values of the extended port counters
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * from the hardware.
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala */
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummalastatic int
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummalahermon_kstat_perfcntr64_update_ext(hermon_perfcntr64_ks_info_t *ksi64, int rw,
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala struct kstat_named *data)
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala{
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala hermon_hw_sm_extperfcntr_t sm_extperfcntr;
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala /*
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * The "enable" component of the kstat is the only writable kstat.
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * It is a no-op when the hardware supports extended port counters.
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala */
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala if (rw == KSTAT_WRITE)
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala return (0);
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala /*
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala * Read the counters and update kstats.
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala */
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala if (hermon_getextperfcntr_cmd_post(ksi64->hki64_state,
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala ksi64->hki64_port_num, HERMON_CMD_NOSLEEP_SPIN, &sm_extperfcntr) !=
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala HERMON_CMD_SUCCESS) {
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala return (EIO);
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala }
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala data[HERMON_PERFCNTR64_ENABLE_IDX].value.ui32 = 1;
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala data[HERMON_PERFCNTR64_XMIT_DATA_IDX].value.ui64 =
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala sm_extperfcntr.portxmdata;
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala data[HERMON_PERFCNTR64_RECV_DATA_IDX].value.ui64 =
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala sm_extperfcntr.portrcdata;
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala data[HERMON_PERFCNTR64_XMIT_PKTS_IDX].value.ui64 =
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala sm_extperfcntr.portxmpkts;
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala data[HERMON_PERFCNTR64_RECV_PKTS_IDX].value.ui64 =
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala sm_extperfcntr.portrcpkts;
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala return (0);
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala}
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala/*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * hermon_kstat_perfcntr64_update()
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Context: Called from the kstat context
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala *
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * See the general comment on 64 bit kstats for performance counters:
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalastatic int
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummalahermon_kstat_perfcntr64_update(kstat_t *ksp, int rw)
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala{
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_state_t *state;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala struct kstat_named *data;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_ks_info_t *ksi;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_perfcntr64_ks_info_t *ksi64;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala int i, thr_exit;
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala int rv;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64 = ksp->ks_private;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala state = ksi64->hki64_state;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi = state->hs_ks_info;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala data = (struct kstat_named *)(ksp->ks_data);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala mutex_enter(&ksi->hki_perfcntr64_lock);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala if (ksi64->hki64_ext_port_counters_supported) {
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala rv = hermon_kstat_perfcntr64_update_ext(ksi64, rw, data);
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala mutex_exit(&ksi->hki_perfcntr64_lock);
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala return (rv);
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala }
30e01c537fd78d139ff463ccb3ef064e7190f9a8Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * 64 bit performance counters maintained by the software is not
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * enabled by default. Enable them upon a writing a non-zero value
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * to "enable" kstat. Disable them upon a writing zero to the
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * "enable" kstat.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (rw == KSTAT_WRITE) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (data[HERMON_PERFCNTR64_ENABLE_IDX].value.ui32) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (ksi64->hki64_enabled == 0) {
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala /*
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala * Reset the hardware counters to ensure that
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala * the hardware counter doesn't max out
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala * (and hence stop counting) before we get
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala * a chance to reset the counter in
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala * hermon_kstat_perfcntr64_update_thread.
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala */
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala if (hermon_getperfcntr_cmd_post(state,
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala ksi64->hki64_port_num,
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala HERMON_CMD_NOSLEEP_SPIN, NULL, 1) !=
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala HERMON_CMD_SUCCESS) {
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala mutex_exit(&ksi->hki_perfcntr64_lock);
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala return (EIO);
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala }
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /* Enable 64 bit software counters */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_enabled = 1;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala for (i = 0;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala i < HERMON_PERFCNTR64_NUM_COUNTERS; i++) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_counters[i] = 0;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[i] = 0;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_kstat_perfcntr64_thread_create(state);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala } else if (ksi64->hki64_enabled) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /* Disable 64 bit software counters */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_enabled = 0;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala thr_exit = 1;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala for (i = 0; i < state->hs_cfg_profile->cp_num_ports;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala i++) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (ksi->hki_perfcntr64[i].hki64_enabled) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala thr_exit = 0;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala break;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (thr_exit)
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala hermon_kstat_perfcntr64_thread_exit(ksi);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala } else if (ksi64->hki64_enabled) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /*
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala * Read the counters and update kstats.
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala if (hermon_kstat_perfcntr64_read(state, ksi64->hki64_port_num,
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala 0) != HERMON_CMD_SUCCESS) {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala mutex_exit(&ksi->hki_perfcntr64_lock);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala return (EIO);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala data[HERMON_PERFCNTR64_ENABLE_IDX].value.ui32 = 1;
60c682e1f62d3c131ea9130c21e0ccd86044e039Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala data[HERMON_PERFCNTR64_XMIT_DATA_IDX].value.ui64 =
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_counters[HERMON_PERFCNTR64_XMIT_DATA_IDX] +
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_XMIT_DATA_IDX];
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala data[HERMON_PERFCNTR64_RECV_DATA_IDX].value.ui64 =
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_counters[HERMON_PERFCNTR64_RECV_DATA_IDX] +
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_RECV_DATA_IDX];
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala data[HERMON_PERFCNTR64_XMIT_PKTS_IDX].value.ui64 =
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_counters[HERMON_PERFCNTR64_XMIT_PKTS_IDX] +
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_XMIT_PKTS_IDX];
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala data[HERMON_PERFCNTR64_RECV_PKTS_IDX].value.ui64 =
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_counters[HERMON_PERFCNTR64_RECV_PKTS_IDX] +
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala ksi64->hki64_last_read[HERMON_PERFCNTR64_RECV_PKTS_IDX];
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala } else {
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala /* return 0 in kstats if not enabled */
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala data[HERMON_PERFCNTR64_ENABLE_IDX].value.ui32 = 0;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala for (i = 1; i < HERMON_PERFCNTR64_NUM_COUNTERS; i++)
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala data[i].value.ui64 = 0;
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala }
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala mutex_exit(&ksi->hki_perfcntr64_lock);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala return (0);
d1a5c8385583011b8adaf259d3460c22595b4a66Ramaswamy Tummala}