tavor_stats.c revision 9e39c5ba00a55fa05777cc94b148296af305e135
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Tavor IB Performance Statistics routines
*
* Implements all the routines necessary for setting up, querying, and
* (later) tearing down all the kstats necessary for implementing to
* the interfaces necessary to provide busstat(1M) access.
*/
/*
* Tavor IB Performance Events structure
* This structure is read-only and is used to setup the individual kstats
* and to initialize the tki_ib_perfcnt[] array for each Tavor instance.
*/
{"port_xmit_data", TAVOR_HW_PMEG_PORTXMITDATA_OFFSET,
0, 0xFFFFFFFF, 0, 0},
{"port_recv_data", TAVOR_HW_PMEG_PORTRECVDATA_OFFSET,
0, 0xFFFFFFFF, 0, 0},
{"port_xmit_pkts", TAVOR_HW_PMEG_PORTXMITPKTS_OFFSET,
0, 0xFFFFFFFF, 0, 0},
{"port_recv_pkts", TAVOR_HW_PMEG_PORTRECVPKTS_OFFSET,
0, 0xFFFFFFFF, 0, 0},
{"port_recv_err", TAVOR_HW_PMEG_PORTRECVERR_OFFSET,
0, 0xFFFF, 0, 0},
{"port_xmit_discards", TAVOR_HW_PMEG_PORTXMITDISCARD_OFFSET,
0, 0xFFFF, 0, 0},
{"vl15_dropped", TAVOR_HW_PMEG_VL15DROPPED_OFFSET,
0, 0xFFFF, 0, 0},
{"port_xmit_wait", TAVOR_HW_PMEG_PORTXMITWAIT_OFFSET,
0, 0xFFFFFFFF, 0, 0},
{"port_recv_remote_phys_err", TAVOR_HW_PMEG_PORTRECVREMPHYSERR_OFFSET,
0, 0xFFFF, 0, 0},
{"port_xmit_constraint_err", TAVOR_HW_PMEG_PORTXMITCONSTERR_OFFSET,
0, 0xFF, 0, 0},
{"port_recv_constraint_err", TAVOR_HW_PMEG_PORTRECVCONSTERR_OFFSET,
0, 0xFF, 0, 0},
{"symbol_err_counter", TAVOR_HW_PMEG_SYMBOLERRCNT_OFFSET,
0, 0xFFFF, 0, 0},
{"link_err_recovery_cnt", TAVOR_HW_PMEG_LINKERRRECOVERCNT_OFFSET,
0, 0xFFFF, 0, 0},
{"link_downed_cnt", TAVOR_HW_PMEG_LINKDOWNEDCNT_OFFSET,
16, 0xFFFF, 0, 0},
{"excessive_buffer_overruns", TAVOR_HW_PMEG_EXCESSBUFOVERRUN_OFFSET,
0, 0xF, 0, 0},
{"local_link_integrity_err", TAVOR_HW_PMEG_LOCALLINKINTERR_OFFSET,
8, 0xF, 0, 0},
{"clear_pic", 0, 0, 0, 0}
};
/*
* tavor_kstat_init()
* Context: Only called from attach() path context
*/
int
{
int i;
/* Allocate a kstat info structure */
KM_SLEEP);
return (DDI_FAILURE);
}
/*
* Create as many "pic" kstats as we have IB ports. Enable all
* of the events specified in the "tavor_ib_perfcnt_list" structure.
*/
for (i = 0; i < numports; i++) {
TAVOR_TNF_ERROR, "");
goto kstat_init_fail;
}
}
/* Create the "counters" kstat too */
goto kstat_init_fail;
}
/* Initialize the control register and initial counter values */
/*
* Initialize the Tavor tki_ib_perfcnt[] array values using the
* default values in tavor_ib_perfcnt_list[]
*/
for (i = 0; i < TAVOR_CNTR_NUMENTRIES; i++) {
}
return (DDI_SUCCESS);
/* Delete all the previously created kstats */
}
for (i = 0; i < numports; i++) {
}
}
/* Free the kstat info structure */
return (DDI_FAILURE);
}
/*
* tavor_kstat_init()
*/
void
{
int i;
/* Get pointer to kstat info */
/* Delete all the "pic" kstats (one per port) */
for (i = 0; i < numports; i++) {
}
}
/* Delete the "counter" kstats (one per port) */
/* Free the kstat info structure */
}
/*
* tavor_kstat_picN_create()
* Context: Only called from attach() path context
*/
static kstat_t *
{
struct kstat_named *pic_named_data;
int drv_instance, i;
char *drv_name;
char pic_name[16];
/*
* Create the "picN" kstat. In the steps, below we will attach
* all of our named event types to it.
*/
TAVOR_TNF_ERROR, "");
return (NULL);
}
/*
* Write event names and their associated pcr masks. The last entry
* in the array (clear_pic) is added separately below (as its pic
* value must be inverted).
*/
for (i = 0; i < num_evt - 1; i++) {
}
/* Add the "clear_pic" entry */
/* Install the kstat */
return (picN_ksp);
}
/*
* tavor_kstat_cntr_create()
* Context: Only called from attach() path context
*/
static kstat_t *
{
struct kstat_named *cntr_named_data;
int drv_instance, i;
char *drv_name;
char pic_str[16];
/*
* Create the "counters" kstat. In the steps, below we will attach
* all of our "pic" to it. Note: The size of this kstat is
* num_pic + 1 because it also contains the "%pcr".
*/
TAVOR_TNF_ERROR, "");
return (NULL);
}
/*
* Initialize the named kstats (for the "pcr" and for the
* individual "pic" kstats)
*/
for (i = 0; i < num_pic; i++) {
}
/*
* Store the Tavor softstate pointer in the kstat's private field so
* that it is available to the update function.
*/
/* Install the kstat */
return (cntr_ksp);
}
/*
* tavor_kstat_cntr_update()
* Context: Called from the kstat context
*/
static int
{
struct kstat_named *data;
/*
* Extract the Tavor softstate pointer, kstat data, pointer to the
* kstat info structure, and pointer to the tki_ib_perfcnt[] array
* from the input parameters. Note: For warlock purposes, these
* parameters are all accessed only in this routine and are,
* therefore, protected by the lock used by the kstat framework.
*/
/*
* Depending on whether we are reading the "pic" counters or
* writing the "pcr" control register, we need to handle and
* fill in the kstat data appropriately.
*
* If this is a write to the "pcr", then extract the value from
* the kstat data and store it in the kstat info structure.
*
* Otherwise, if this is a read of the "pic" counter(s), then
* extract the register offset, size, and mask values from the
* ib_perf[] array. Then read the corresponding register and store
* than one port is configured.
*/
if (rw == KSTAT_WRITE) {
/* Update the stored "pcr" value */
return (0);
} else {
/*
* Get the current "pcr" value and extract the lower
* portion (corresponding to the counters for "pic0")
*/
/*
* Fill in the "pic0" counter, corresponding to port 1.
* This involves reading in the current value in the register
* and calculating how many events have happened since this
* register was last polled. Then we save away the current
* value for the counter and increment the "pic0" total by
* the number of new events.
*/
offset));
/*
* If necessary, fill in the "pic1" counter for port 2.
* This works the same as above except that we extract the
* upper bits (corresponding to the counters for "pic1")
*/
if (numports == TAVOR_NUM_PORTS) {
offset + TAVOR_HW_PORT_SIZE));
}
return (0);
}
}