1/*
2 * Copyright 2014-2017 Cavium, Inc.
3 * The contents of this file are subject to the terms of the Common Development
4 * and Distribution License, v.1,  (the "License").
5 *
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the License at available
9 * at http://opensource.org/licenses/CDDL-1.0
10 *
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15/*
16 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
17 * Copyright (c) 2019, Joyent, Inc.
18 */
19
20#include "bnx.h"
21
22typedef struct {
23	kstat_named_t version;
24	kstat_named_t versionFW;
25	kstat_named_t chipName;
26	kstat_named_t intrAlloc;
27	kstat_named_t intrFired;
28	kstat_named_t intrInDisabled;
29	kstat_named_t intrNoChange;
30} bnx_kstat_t;
31
32#define	BNX_KSTAT_SIZE (sizeof (bnx_kstat_t) / sizeof (kstat_named_t))
33
34
35static int
36bnx_kstat_update(kstat_t *kstats, int rw)
37{
38	bnx_kstat_t *pStats = (bnx_kstat_t *)kstats->ks_data;
39	um_device_t *pUM = (um_device_t *)kstats->ks_private;
40
41	if (rw == KSTAT_WRITE) {
42		return (EACCES);
43	}
44
45	mutex_enter(&pUM->kstatMutex);
46
47	(void) strncpy(pStats->version.value.c, pUM->version,
48	    sizeof (pStats->version.value.c));
49	(void) strncpy(pStats->versionFW.value.c, pUM->versionFW,
50	    sizeof (pStats->versionFW.value.c));
51	(void) strncpy(pStats->chipName.value.c,  pUM->chipName,
52	    sizeof (pStats->chipName.value.c));
53	(void) strncpy(pStats->intrAlloc.value.c, pUM->intrAlloc,
54	    sizeof (pStats->intrAlloc.value.c));
55	pStats->intrFired.value.ui64 = pUM->intr_count;
56	pStats->intrInDisabled.value.ui64 = pUM->intr_in_disabled;
57	pStats->intrNoChange.value.ui64 = pUM->intr_no_change;
58
59	mutex_exit(&pUM->kstatMutex);
60
61	return (0);
62}
63
64#define	BNX_KSTAT(f, t)	kstat_named_init(&pStats->f, #f, t)
65
66boolean_t
67bnx_kstat_init(um_device_t *pUM)
68{
69	bnx_kstat_t *pStats;
70
71	if ((pUM->kstats = kstat_create("bnx", pUM->instance, "statistics",
72	    "net", KSTAT_TYPE_NAMED, BNX_KSTAT_SIZE, 0)) == NULL) {
73		cmn_err(CE_WARN, "%s: Failed to create kstat", pUM->dev_name);
74		return (B_FALSE);
75	}
76
77	pStats = (bnx_kstat_t *)pUM->kstats->ks_data;
78
79	BNX_KSTAT(version, KSTAT_DATA_CHAR);
80	BNX_KSTAT(versionFW, KSTAT_DATA_CHAR);
81	BNX_KSTAT(chipName, KSTAT_DATA_CHAR);
82	BNX_KSTAT(intrAlloc, KSTAT_DATA_CHAR);
83	BNX_KSTAT(intrFired, KSTAT_DATA_UINT64);
84	BNX_KSTAT(intrInDisabled, KSTAT_DATA_UINT64);
85	BNX_KSTAT(intrNoChange, KSTAT_DATA_UINT64);
86
87	pUM->kstats->ks_update  = bnx_kstat_update;
88	pUM->kstats->ks_private = (void *)pUM;
89
90	mutex_init(&pUM->kstatMutex, NULL,
91	    MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
92
93	kstat_install(pUM->kstats);
94
95	return (B_TRUE);
96}
97
98void
99bnx_kstat_fini(um_device_t *pUM)
100{
101	if (pUM->kstats) {
102		kstat_delete(pUM->kstats);
103		pUM->kstats = NULL;
104	}
105
106	mutex_destroy(&pUM->kstatMutex);
107}
108