xref: /illumos-gate/usr/src/uts/common/io/hxge/hxge_kstats.c (revision ffb5616e59d0fbdc1ee94070050f240a6a4ac8e2)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <hxge_impl.h>
27 #include <inet/mi.h>
28 #include <sys/cmn_err.h>
29 
30 #define	RDC_NAME_FORMAT1 "RDC_"
31 #define	TDC_NAME_FORMAT1 "TDC_"
32 #define	CH_NAME_FORMAT "%d"
33 
34 void
35 hxge_init_statsp(p_hxge_t hxgep)
36 {
37 	size_t stats_size;
38 
39 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_init_statsp"));
40 
41 	stats_size = sizeof (hxge_stats_t);
42 	hxgep->statsp = KMEM_ZALLOC(stats_size, KM_SLEEP);
43 	hxgep->statsp->stats_size = stats_size;
44 
45 	HXGE_DEBUG_MSG((hxgep, KST_CTL, " <== hxge_init_statsp"));
46 }
47 
48 typedef struct {
49 	uint8_t index;
50 	uint8_t type;
51 	char *name;
52 } hxge_kstat_index_t;
53 
54 typedef enum {
55 	RDC_STAT_PACKETS = 0,
56 	RDC_STAT_BYTES,
57 	RDC_STAT_ERRORS,
58 	RDC_STAT_JUMBO_PKTS,
59 	RDC_STAT_RCR_UNKNOWN_ERR,
60 	RDC_STAT_RCR_SHA_PAR_ERR,
61 	RDC_STAT_RBR_PRE_PAR_ERR,
62 	RDC_STAT_RBR_PRE_EMTY,
63 	RDC_STAT_RCR_SHADOW_FULL,
64 	RDC_STAT_RBR_TMOUT,
65 	RDC_STAT_PEU_RESP_ERR,
66 	RDC_STAT_CTRL_FIFO_ECC_ERR,
67 	RDC_STAT_DATA_FIFO_ECC_ERR,
68 	RDC_STAT_RCRFULL,
69 	RDC_STAT_RBR_EMPTY,
70 	RDC_STAT_RBR_EMPTY_FAIL,
71 	RDC_STAT_RBR_EMPTY_RESTORE,
72 	RDC_STAT_RBR_FULL,
73 	RDC_STAT_RCR_INVALIDS,
74 	RDC_STAT_RCRTO,
75 	RDC_STAT_RCRTHRES,
76 	RDC_STAT_PKT_DROP,
77 	RDC_STAT_END
78 } hxge_rdc_stat_index_t;
79 
80 hxge_kstat_index_t hxge_rdc_stats[] = {
81 	{RDC_STAT_PACKETS, KSTAT_DATA_UINT64, "rdc_packets"},
82 	{RDC_STAT_BYTES, KSTAT_DATA_UINT64, "rdc_bytes"},
83 	{RDC_STAT_ERRORS, KSTAT_DATA_ULONG, "rdc_errors"},
84 	{RDC_STAT_JUMBO_PKTS, KSTAT_DATA_ULONG, "rdc_jumbo_pkts"},
85 	{RDC_STAT_RCR_UNKNOWN_ERR, KSTAT_DATA_ULONG, "rdc_rcr_unknown_err"},
86 	{RDC_STAT_RCR_SHA_PAR_ERR, KSTAT_DATA_ULONG, "rdc_rcr_sha_par_err"},
87 	{RDC_STAT_RBR_PRE_PAR_ERR, KSTAT_DATA_ULONG, "rdc_rbr_pre_par_err"},
88 	{RDC_STAT_RBR_PRE_EMTY, KSTAT_DATA_ULONG, "rdc_rbr_pre_empty"},
89 	{RDC_STAT_RCR_SHADOW_FULL, KSTAT_DATA_ULONG, "rdc_rcr_shadow_full"},
90 	{RDC_STAT_RBR_TMOUT, KSTAT_DATA_ULONG, "rdc_rbr_tmout"},
91 	{RDC_STAT_PEU_RESP_ERR, KSTAT_DATA_ULONG, "peu_resp_err"},
92 	{RDC_STAT_CTRL_FIFO_ECC_ERR, KSTAT_DATA_ULONG, "ctrl_fifo_ecc_err"},
93 	{RDC_STAT_DATA_FIFO_ECC_ERR, KSTAT_DATA_ULONG, "data_fifo_ecc_err"},
94 	{RDC_STAT_RCRFULL, KSTAT_DATA_ULONG, "rdc_rcrfull"},
95 	{RDC_STAT_RBR_EMPTY, KSTAT_DATA_ULONG, "rdc_rbr_empty"},
96 	{RDC_STAT_RBR_EMPTY_FAIL, KSTAT_DATA_ULONG, "rdc_rbr_empty_fail"},
97 	{RDC_STAT_RBR_EMPTY_FAIL, KSTAT_DATA_ULONG, "rdc_rbr_empty_restore"},
98 	{RDC_STAT_RBR_FULL, KSTAT_DATA_ULONG, "rdc_rbrfull"},
99 	{RDC_STAT_RCR_INVALIDS, KSTAT_DATA_ULONG, "rdc_rcr_invalids"},
100 	{RDC_STAT_RCRTO, KSTAT_DATA_ULONG, "rdc_rcrto"},
101 	{RDC_STAT_RCRTHRES, KSTAT_DATA_ULONG, "rdc_rcrthres"},
102 	{RDC_STAT_PKT_DROP, KSTAT_DATA_ULONG, "rdc_pkt_drop"},
103 	{RDC_STAT_END, NULL, NULL}
104 };
105 
106 typedef enum {
107 	RDC_SYS_STAT_CTRL_FIFO_SEC = 0,
108 	RDC_SYS_STAT_CTRL_FIFO_DED,
109 	RDC_SYS_STAT_DATA_FIFO_SEC,
110 	RDC_SYS_STAT_DATA_FIFO_DED,
111 	RDC_SYS_STAT_END
112 } hxge_rdc_sys_stat_idx_t;
113 
114 hxge_kstat_index_t hxge_rdc_sys_stats[] = {
115 	{RDC_SYS_STAT_CTRL_FIFO_SEC, KSTAT_DATA_UINT64, "rdc_ctrl_fifo_sec"},
116 	{RDC_SYS_STAT_CTRL_FIFO_DED, KSTAT_DATA_UINT64, "rdc_ctrl_fifo_ded"},
117 	{RDC_SYS_STAT_DATA_FIFO_SEC, KSTAT_DATA_UINT64, "rdc_data_fifo_sec"},
118 	{RDC_SYS_STAT_DATA_FIFO_DED, KSTAT_DATA_UINT64, "tdc_data_fifo_ded"},
119 	{RDC_SYS_STAT_END, NULL, NULL}
120 };
121 
122 typedef enum {
123 	TDC_STAT_PACKETS = 0,
124 	TDC_STAT_BYTES,
125 	TDC_STAT_BYTES_WITH_PAD,
126 	TDC_STAT_ERRORS,
127 	TDC_STAT_TX_INITS,
128 	TDC_STAT_TX_NO_BUF,
129 	TDC_STAT_PEU_RESP_ERR,
130 	TDC_STAT_PKT_SIZE_ERR,
131 	TDC_STAT_TX_RNG_OFLOW,
132 	TDC_STAT_PKT_SIZE_HDR_ERR,
133 	TDC_STAT_RUNT_PKT_DROP_ERR,
134 	TDC_STAT_PREF_PAR_ERR,
135 	TDC_STAT_TDR_PREF_CPL_TO,
136 	TDC_STAT_PKT_CPL_TO,
137 	TDC_STAT_INVALID_SOP,
138 	TDC_STAT_UNEXPECTED_SOP,
139 	TDC_STAT_COUNT_HDR_SIZE_ERR,
140 	TDC_STAT_COUNT_RUNT,
141 	TDC_STAT_COUNT_ABORT,
142 	TDC_STAT_TX_STARTS,
143 	TDC_STAT_TX_NO_DESC,
144 	TDC_STAT_TX_DMA_BIND_FAIL,
145 	TDC_STAT_TX_HDR_PKTS,
146 	TDC_STAT_TX_DDI_PKTS,
147 	TDC_STAT_TX_JUMBO_PKTS,
148 	TDC_STAT_TX_MAX_PEND,
149 	TDC_STAT_TX_MARKS,
150 	TDC_STAT_END
151 } hxge_tdc_stats_index_t;
152 
153 hxge_kstat_index_t hxge_tdc_stats[] = {
154 	{TDC_STAT_PACKETS, KSTAT_DATA_UINT64, "tdc_packets"},
155 	{TDC_STAT_BYTES, KSTAT_DATA_UINT64, "tdc_bytes"},
156 	{TDC_STAT_BYTES_WITH_PAD, KSTAT_DATA_UINT64, "tdc_bytes_with_pad"},
157 	{TDC_STAT_ERRORS, KSTAT_DATA_UINT64, "tdc_errors"},
158 	{TDC_STAT_TX_INITS, KSTAT_DATA_ULONG, "tdc_tx_inits"},
159 	{TDC_STAT_TX_NO_BUF, KSTAT_DATA_ULONG, "tdc_tx_no_buf"},
160 
161 	{TDC_STAT_PEU_RESP_ERR, KSTAT_DATA_ULONG, "tdc_peu_resp_err"},
162 	{TDC_STAT_PKT_SIZE_ERR, KSTAT_DATA_ULONG, "tdc_pkt_size_err"},
163 	{TDC_STAT_TX_RNG_OFLOW, KSTAT_DATA_ULONG, "tdc_tx_rng_oflow"},
164 	{TDC_STAT_PKT_SIZE_HDR_ERR, KSTAT_DATA_ULONG, "tdc_pkt_size_hdr_err"},
165 	{TDC_STAT_RUNT_PKT_DROP_ERR, KSTAT_DATA_ULONG, "tdc_runt_pkt_drop_err"},
166 	{TDC_STAT_PREF_PAR_ERR, KSTAT_DATA_ULONG, "tdc_pref_par_err"},
167 	{TDC_STAT_TDR_PREF_CPL_TO, KSTAT_DATA_ULONG, "tdc_tdr_pref_cpl_to"},
168 	{TDC_STAT_PKT_CPL_TO, KSTAT_DATA_ULONG, "tdc_pkt_cpl_to"},
169 	{TDC_STAT_INVALID_SOP, KSTAT_DATA_ULONG, "tdc_invalid_sop"},
170 	{TDC_STAT_UNEXPECTED_SOP, KSTAT_DATA_ULONG, "tdc_unexpected_sop"},
171 
172 	{TDC_STAT_COUNT_HDR_SIZE_ERR, KSTAT_DATA_ULONG,
173 	    "tdc_count_hdr_size_err"},
174 	{TDC_STAT_COUNT_RUNT, KSTAT_DATA_ULONG, "tdc_count_runt"},
175 	{TDC_STAT_COUNT_ABORT, KSTAT_DATA_ULONG, "tdc_count_abort"},
176 
177 	{TDC_STAT_TX_STARTS, KSTAT_DATA_ULONG, "tdc_tx_starts"},
178 	{TDC_STAT_TX_NO_DESC, KSTAT_DATA_ULONG, "tdc_tx_no_desc"},
179 	{TDC_STAT_TX_DMA_BIND_FAIL, KSTAT_DATA_ULONG, "tdc_tx_dma_bind_fail"},
180 	{TDC_STAT_TX_HDR_PKTS, KSTAT_DATA_ULONG, "tdc_tx_hdr_pkts"},
181 	{TDC_STAT_TX_DDI_PKTS, KSTAT_DATA_ULONG, "tdc_tx_ddi_pkts"},
182 	{TDC_STAT_TX_JUMBO_PKTS, KSTAT_DATA_ULONG, "tdc_tx_jumbo_pkts"},
183 	{TDC_STAT_TX_MAX_PEND, KSTAT_DATA_ULONG, "tdc_tx_max_pend"},
184 	{TDC_STAT_TX_MARKS, KSTAT_DATA_ULONG, "tdc_tx_marks"},
185 	{TDC_STAT_END, NULL, NULL}
186 };
187 
188 typedef enum {
189 	REORD_TBL_PAR_ERR = 0,
190 	REORD_BUF_DED_ERR,
191 	REORD_BUF_SEC_ERR,
192 	TDC_SYS_STAT_END
193 } hxge_tdc_sys_stat_idx_t;
194 
195 hxge_kstat_index_t hxge_tdc_sys_stats[] = {
196 	{REORD_TBL_PAR_ERR, KSTAT_DATA_UINT64, "reord_tbl_par_err"},
197 	{REORD_BUF_DED_ERR, KSTAT_DATA_UINT64, "reord_buf_ded_err"},
198 	{REORD_BUF_SEC_ERR, KSTAT_DATA_UINT64, "reord_buf_sec_err"},
199 	{TDC_SYS_STAT_END, NULL, NULL}
200 };
201 
202 typedef enum {
203 	VMAC_STAT_TX_FRAME_CNT,		/* vmac_tx_frame_cnt_t */
204 	VMAC_STAT_TX_BYTE_CNT,		/* vmac_tx_byte_cnt_t */
205 
206 	VMAC_STAT_RX_FRAME_CNT,		/* vmac_rx_frame_cnt_t */
207 	VMAC_STAT_RX_BYTE_CNT,		/* vmac_rx_byte_cnt_t */
208 	VMAC_STAT_RX_DROP_FRAME_CNT,	/* vmac_rx_drop_fr_cnt_t */
209 	VMAC_STAT_RX_DROP_BYTE_CNT,	/* vmac_rx_drop_byte_cnt_t */
210 	VMAC_STAT_RX_CRC_CNT,		/* vmac_rx_crc_cnt_t */
211 	VMAC_STAT_RX_PAUSE_CNT,		/* vmac_rx_pause_cnt_t */
212 	VMAC_STAT_RX_BCAST_FR_CNT,	/* vmac_rx_bcast_fr_cnt_t */
213 	VMAC_STAT_RX_MCAST_FR_CNT,	/* vmac_rx_mcast_fr_cnt_t */
214 	VMAC_STAT_END
215 } hxge_vmac_stat_index_t;
216 
217 hxge_kstat_index_t hxge_vmac_stats[] = {
218 	{VMAC_STAT_TX_FRAME_CNT, KSTAT_DATA_UINT64, "vmac_tx_frame_cnt"},
219 	{VMAC_STAT_TX_BYTE_CNT, KSTAT_DATA_UINT64, "vmac_tx_byte_cnt"},
220 
221 	{VMAC_STAT_RX_FRAME_CNT, KSTAT_DATA_UINT64, "vmac_rx_frame_cnt"},
222 	{VMAC_STAT_RX_BYTE_CNT, KSTAT_DATA_UINT64, "vmac_rx_byte_cnt"},
223 	{VMAC_STAT_RX_DROP_FRAME_CNT, KSTAT_DATA_UINT64,
224 		"vmac_rx_drop_frame_cnt"},
225 	{VMAC_STAT_RX_DROP_BYTE_CNT, KSTAT_DATA_UINT64,
226 		"vmac_rx_drop_byte_cnt"},
227 	{VMAC_STAT_RX_CRC_CNT, KSTAT_DATA_UINT64, "vmac_rx_crc_cnt"},
228 	{VMAC_STAT_RX_PAUSE_CNT, KSTAT_DATA_UINT64, "vmac_rx_pause_cnt"},
229 	{VMAC_STAT_RX_BCAST_FR_CNT, KSTAT_DATA_UINT64, "vmac_rx_bcast_fr_cnt"},
230 	{VMAC_STAT_RX_MCAST_FR_CNT, KSTAT_DATA_UINT64, "vmac_rx_mcast_fr_cnt"},
231 	{VMAC_STAT_END, NULL, NULL}
232 };
233 
234 typedef enum {
235 	PFC_STAT_PKT_DROP,
236 	PFC_STAT_TCAM_PARITY_ERR,
237 	PFC_STAT_VLAN_PARITY_ERR,
238 	PFC_STAT_BAD_CS_COUNT,
239 	PFC_STAT_DROP_COUNT,
240 	PFC_STAT_TCP_CTRL_DROP,
241 	PFC_STAT_L2_ADDR_DROP,
242 	PFC_STAT_CLASS_CODE_DROP,
243 	PFC_STAT_TCAM_DROP,
244 	PFC_STAT_VLAN_DROP,
245 	PFC_STAT_END
246 } hxge_pfc_stat_index_t;
247 
248 hxge_kstat_index_t hxge_pfc_stats[] = {
249 	{PFC_STAT_PKT_DROP, KSTAT_DATA_ULONG, "pfc_pkt_drop"},
250 	{PFC_STAT_TCAM_PARITY_ERR, KSTAT_DATA_ULONG, "pfc_tcam_parity_err"},
251 	{PFC_STAT_VLAN_PARITY_ERR, KSTAT_DATA_ULONG, "pfc_vlan_parity_err"},
252 	{PFC_STAT_BAD_CS_COUNT, KSTAT_DATA_ULONG, "pfc_bad_cs_count"},
253 	{PFC_STAT_DROP_COUNT, KSTAT_DATA_ULONG, "pfc_drop_count"},
254 	{PFC_STAT_TCP_CTRL_DROP, KSTAT_DATA_ULONG, "  pfc_pkt_drop_tcp_ctrl"},
255 	{PFC_STAT_L2_ADDR_DROP, KSTAT_DATA_ULONG, "  pfc_pkt_drop_l2_addr"},
256 	{PFC_STAT_CLASS_CODE_DROP, KSTAT_DATA_ULONG,
257 	    "  pfc_pkt_drop_class_code"},
258 	{PFC_STAT_TCAM_DROP, KSTAT_DATA_ULONG, "  pfc_pkt_drop_tcam"},
259 	{PFC_STAT_VLAN_DROP, KSTAT_DATA_ULONG, "  pfc_pkt_drop_vlan"},
260 	{PFC_STAT_END, NULL, NULL}
261 };
262 
263 typedef enum {
264 	MMAC_MAX_ADDR,
265 	MMAC_AVAIL_ADDR,
266 	MMAC_ADDR_POOL1,
267 	MMAC_ADDR_POOL2,
268 	MMAC_ADDR_POOL3,
269 	MMAC_ADDR_POOL4,
270 	MMAC_ADDR_POOL5,
271 	MMAC_ADDR_POOL6,
272 	MMAC_ADDR_POOL7,
273 	MMAC_ADDR_POOL8,
274 	MMAC_ADDR_POOL9,
275 	MMAC_ADDR_POOL10,
276 	MMAC_ADDR_POOL11,
277 	MMAC_ADDR_POOL12,
278 	MMAC_ADDR_POOL13,
279 	MMAC_ADDR_POOL14,
280 	MMAC_ADDR_POOL15,
281 	MMAC_ADDR_POOL16,
282 	MMAC_STATS_END
283 } hxge_mmac_stat_index_t;
284 
285 hxge_kstat_index_t hxge_mmac_stats[] = {
286 	{MMAC_MAX_ADDR, KSTAT_DATA_UINT64, "max_mmac_addr"},
287 	{MMAC_AVAIL_ADDR, KSTAT_DATA_UINT64, "avail_mmac_addr"},
288 	{MMAC_ADDR_POOL1, KSTAT_DATA_UINT64, "mmac_addr_1"},
289 	{MMAC_ADDR_POOL2, KSTAT_DATA_UINT64, "mmac_addr_2"},
290 	{MMAC_ADDR_POOL3, KSTAT_DATA_UINT64, "mmac_addr_3"},
291 	{MMAC_ADDR_POOL4, KSTAT_DATA_UINT64, "mmac_addr_4"},
292 	{MMAC_ADDR_POOL5, KSTAT_DATA_UINT64, "mmac_addr_5"},
293 	{MMAC_ADDR_POOL6, KSTAT_DATA_UINT64, "mmac_addr_6"},
294 	{MMAC_ADDR_POOL7, KSTAT_DATA_UINT64, "mmac_addr_7"},
295 	{MMAC_ADDR_POOL8, KSTAT_DATA_UINT64, "mmac_addr_8"},
296 	{MMAC_ADDR_POOL9, KSTAT_DATA_UINT64, "mmac_addr_9"},
297 	{MMAC_ADDR_POOL10, KSTAT_DATA_UINT64, "mmac_addr_10"},
298 	{MMAC_ADDR_POOL11, KSTAT_DATA_UINT64, "mmac_addr_11"},
299 	{MMAC_ADDR_POOL12, KSTAT_DATA_UINT64, "mmac_addr_12"},
300 	{MMAC_ADDR_POOL13, KSTAT_DATA_UINT64, "mmac_addr_13"},
301 	{MMAC_ADDR_POOL14, KSTAT_DATA_UINT64, "mmac_addr_14"},
302 	{MMAC_ADDR_POOL15, KSTAT_DATA_UINT64, "mmac_addr_15"},
303 	{MMAC_ADDR_POOL16, KSTAT_DATA_UINT64, "mmac_addr_16"},
304 	{MMAC_STATS_END, NULL, NULL},
305 };
306 
307 typedef enum {
308 	SPC_ACC_ERR = 0,
309 	TDC_PIOACC_ERR,
310 	RDC_PIOACC_ERR,
311 	PFC_PIOACC_ERR,
312 	VMAC_PIOACC_ERR,
313 	CPL_HDRQ_PARERR,
314 	CPL_DATAQ_PARERR,
315 	RETRYRAM_XDLH_PARERR,
316 	RETRYSOTRAM_XDLH_PARERR,
317 	P_HDRQ_PARERR,
318 	P_DATAQ_PARERR,
319 	NP_HDRQ_PARERR,
320 	NP_DATAQ_PARERR,
321 	EIC_MSIX_PARERR,
322 	HCR_PARERR,
323 	PEU_SYS_STAT_END
324 } hxge_peu_sys_stat_idx_t;
325 
326 hxge_kstat_index_t hxge_peu_sys_stats[] = {
327 	{SPC_ACC_ERR, KSTAT_DATA_UINT64, "spc_acc_err"},
328 	{TDC_PIOACC_ERR, KSTAT_DATA_UINT64, "tdc_pioacc_err"},
329 	{RDC_PIOACC_ERR, KSTAT_DATA_UINT64, "rdc_pioacc_err"},
330 	{PFC_PIOACC_ERR, KSTAT_DATA_UINT64, "pfc_pioacc_err"},
331 	{VMAC_PIOACC_ERR, KSTAT_DATA_UINT64, "vmac_pioacc_err"},
332 	{CPL_HDRQ_PARERR, KSTAT_DATA_UINT64, "cpl_hdrq_parerr"},
333 	{CPL_DATAQ_PARERR, KSTAT_DATA_UINT64, "cpl_dataq_parerr"},
334 	{RETRYRAM_XDLH_PARERR, KSTAT_DATA_UINT64, "retryram_xdlh_parerr"},
335 	{RETRYSOTRAM_XDLH_PARERR, KSTAT_DATA_UINT64, "retrysotram_xdlh_parerr"},
336 	{P_HDRQ_PARERR, KSTAT_DATA_UINT64, "p_hdrq_parerr"},
337 	{P_DATAQ_PARERR, KSTAT_DATA_UINT64, "p_dataq_parerr"},
338 	{NP_HDRQ_PARERR, KSTAT_DATA_UINT64, "np_hdrq_parerr"},
339 	{NP_DATAQ_PARERR, KSTAT_DATA_UINT64, "np_dataq_parerr"},
340 	{EIC_MSIX_PARERR, KSTAT_DATA_UINT64, "eic_msix_parerr"},
341 	{HCR_PARERR, KSTAT_DATA_UINT64, "hcr_parerr"},
342 	{TDC_SYS_STAT_END, NULL, NULL}
343 };
344 
345 /* ARGSUSED */
346 int
347 hxge_tdc_stat_update(kstat_t *ksp, int rw)
348 {
349 	p_hxge_t		hxgep;
350 	p_hxge_tdc_kstat_t	tdc_kstatsp;
351 	p_hxge_tx_ring_stats_t	statsp;
352 	int			channel;
353 	char			*ch_name, *end;
354 
355 	hxgep = (p_hxge_t)ksp->ks_private;
356 	if (hxgep == NULL)
357 		return (-1);
358 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_rxstat_update"));
359 
360 	ch_name = ksp->ks_name;
361 	ch_name += strlen(TDC_NAME_FORMAT1);
362 	channel = mi_strtol(ch_name, &end, 10);
363 
364 	tdc_kstatsp = (p_hxge_tdc_kstat_t)ksp->ks_data;
365 	statsp = (p_hxge_tx_ring_stats_t)&hxgep->statsp->tdc_stats[channel];
366 
367 	HXGE_DEBUG_MSG((hxgep, KST_CTL,
368 	    "hxge_tdc_stat_update data $%p statsp $%p channel %d",
369 	    ksp->ks_data, statsp, channel));
370 
371 	tdc_kstatsp->opackets.value.ull = statsp->opackets;
372 	tdc_kstatsp->obytes.value.ull = statsp->obytes;
373 	tdc_kstatsp->obytes_with_pad.value.ull = statsp->obytes_with_pad;
374 	tdc_kstatsp->oerrors.value.ull = statsp->oerrors;
375 	tdc_kstatsp->tx_hdr_pkts.value.ull = statsp->tx_hdr_pkts;
376 	tdc_kstatsp->tx_ddi_pkts.value.ull = statsp->tx_ddi_pkts;
377 	tdc_kstatsp->tx_jumbo_pkts.value.ull = statsp->tx_jumbo_pkts;
378 	tdc_kstatsp->tx_max_pend.value.ull = statsp->tx_max_pend;
379 	tdc_kstatsp->peu_resp_err.value.ul = statsp->peu_resp_err;
380 	tdc_kstatsp->pkt_size_err.value.ul = statsp->pkt_size_err;
381 	tdc_kstatsp->tx_rng_oflow.value.ul = statsp->tx_rng_oflow;
382 	tdc_kstatsp->pkt_size_hdr_err.value.ul = statsp->pkt_size_hdr_err;
383 	tdc_kstatsp->runt_pkt_drop_err.value.ul = statsp->runt_pkt_drop_err;
384 	tdc_kstatsp->pref_par_err.value.ul = statsp->pref_par_err;
385 	tdc_kstatsp->tdr_pref_cpl_to.value.ul = statsp->tdr_pref_cpl_to;
386 	tdc_kstatsp->pkt_cpl_to.value.ul = statsp->pkt_cpl_to;
387 	tdc_kstatsp->invalid_sop.value.ul = statsp->invalid_sop;
388 	tdc_kstatsp->unexpected_sop.value.ul = statsp->unexpected_sop;
389 	tdc_kstatsp->tx_starts.value.ul = statsp->tx_starts;
390 	tdc_kstatsp->tx_no_desc.value.ul = statsp->tx_no_desc;
391 	tdc_kstatsp->tx_dma_bind_fail.value.ul = statsp->tx_dma_bind_fail;
392 
393 	tdc_kstatsp->count_hdr_size_err.value.ul =
394 	    statsp->count_hdr_size_err;
395 	tdc_kstatsp->count_runt.value.ul = statsp->count_runt;
396 	tdc_kstatsp->count_abort.value.ul = statsp->count_abort;
397 	tdc_kstatsp->tx_marks.value.ul = statsp->tx_marks;
398 
399 	HXGE_DEBUG_MSG((hxgep, KST_CTL, " <== hxge_tdc_stat_update"));
400 	return (0);
401 }
402 
403 /* ARGSUSED */
404 int
405 hxge_tdc_sys_stat_update(kstat_t *ksp, int rw)
406 {
407 	p_hxge_t		hxgep;
408 	p_hxge_tdc_sys_kstat_t	tdc_sys_kstatsp;
409 	p_hxge_tdc_sys_stats_t	statsp;
410 
411 	hxgep = (p_hxge_t)ksp->ks_private;
412 	if (hxgep == NULL)
413 		return (-1);
414 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_tdc_sys_stat_update"));
415 
416 	tdc_sys_kstatsp = (p_hxge_tdc_sys_kstat_t)ksp->ks_data;
417 	statsp = (p_hxge_tdc_sys_stats_t)&hxgep->statsp->tdc_sys_stats;
418 
419 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "hxge_tdc_sys_stat_update %llx",
420 	    ksp->ks_data));
421 
422 	tdc_sys_kstatsp->reord_tbl_par_err.value.ul =
423 	    statsp->reord_tbl_par_err;
424 	tdc_sys_kstatsp->reord_buf_ded_err.value.ul =
425 	    statsp->reord_buf_ded_err;
426 	tdc_sys_kstatsp->reord_buf_sec_err.value.ul =
427 	    statsp->reord_buf_sec_err;
428 
429 	HXGE_DEBUG_MSG((hxgep, KST_CTL, " <== hxge_tdc_sys_stat_update"));
430 	return (0);
431 }
432 
433 /* ARGSUSED */
434 int
435 hxge_rdc_stat_update(kstat_t *ksp, int rw)
436 {
437 	p_hxge_t		hxgep;
438 	p_hxge_rdc_kstat_t	rdc_kstatsp;
439 	p_hxge_rx_ring_stats_t	statsp;
440 	int			channel;
441 	char			*ch_name, *end;
442 
443 	hxgep = (p_hxge_t)ksp->ks_private;
444 	if (hxgep == NULL)
445 		return (-1);
446 
447 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_rdc_stat_update"));
448 
449 	ch_name = ksp->ks_name;
450 	ch_name += strlen(RDC_NAME_FORMAT1);
451 	channel = mi_strtol(ch_name, &end, 10);
452 
453 	rdc_kstatsp = (p_hxge_rdc_kstat_t)ksp->ks_data;
454 	statsp = (p_hxge_rx_ring_stats_t)&hxgep->statsp->rdc_stats[channel];
455 
456 	HXGE_DEBUG_MSG((hxgep, KST_CTL,
457 	    "hxge_rdc_stat_update $%p statsp $%p channel %d",
458 	    ksp->ks_data, statsp, channel));
459 
460 	rdc_kstatsp->ipackets.value.ull = statsp->ipackets;
461 	rdc_kstatsp->rbytes.value.ull = statsp->ibytes;
462 	rdc_kstatsp->jumbo_pkts.value.ul = statsp->jumbo_pkts;
463 	rdc_kstatsp->rcr_unknown_err.value.ul = statsp->rcr_unknown_err;
464 	rdc_kstatsp->errors.value.ul = statsp->ierrors;
465 	rdc_kstatsp->rcr_sha_par_err.value.ul = statsp->rcr_sha_par;
466 	rdc_kstatsp->rbr_pre_par_err.value.ul = statsp->rbr_pre_par;
467 	rdc_kstatsp->rbr_pre_emty.value.ul = statsp->rbr_pre_empty;
468 	rdc_kstatsp->rcr_shadow_full.value.ul = statsp->rcr_shadow_full;
469 	rdc_kstatsp->rbr_tmout.value.ul = statsp->rbr_tmout;
470 	rdc_kstatsp->peu_resp_err.value.ul = statsp->peu_resp_err;
471 	rdc_kstatsp->ctrl_fifo_ecc_err.value.ul = statsp->ctrl_fifo_ecc_err;
472 	rdc_kstatsp->data_fifo_ecc_err.value.ul = statsp->data_fifo_ecc_err;
473 	rdc_kstatsp->rcrfull.value.ul = statsp->rcrfull;
474 	rdc_kstatsp->rbr_empty.value.ul = statsp->rbr_empty;
475 	rdc_kstatsp->rbr_empty_fail.value.ul = statsp->rbr_empty_fail;
476 	rdc_kstatsp->rbr_empty_restore.value.ul = statsp->rbr_empty_restore;
477 	rdc_kstatsp->rbrfull.value.ul = statsp->rbrfull;
478 	rdc_kstatsp->rcr_invalids.value.ul = statsp->rcr_invalids;
479 	rdc_kstatsp->rcr_to.value.ul = statsp->rcr_to;
480 	rdc_kstatsp->rcr_thresh.value.ul = statsp->rcr_thres;
481 	rdc_kstatsp->pkt_drop.value.ul = statsp->pkt_drop;
482 
483 	HXGE_DEBUG_MSG((hxgep, KST_CTL, " <== hxge_rdc_stat_update"));
484 	return (0);
485 }
486 
487 /* ARGSUSED */
488 int
489 hxge_rdc_sys_stat_update(kstat_t *ksp, int rw)
490 {
491 	p_hxge_t		hxgep;
492 	p_hxge_rdc_sys_kstat_t	rdc_sys_kstatsp;
493 	p_hxge_rdc_sys_stats_t	statsp;
494 
495 	hxgep = (p_hxge_t)ksp->ks_private;
496 	if (hxgep == NULL)
497 		return (-1);
498 
499 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_rdc_sys_stat_update"));
500 
501 	rdc_sys_kstatsp = (p_hxge_rdc_sys_kstat_t)ksp->ks_data;
502 	statsp = (p_hxge_rdc_sys_stats_t)&hxgep->statsp->rdc_sys_stats;
503 
504 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "hxge_rdc_sys_stat_update %llx",
505 	    ksp->ks_data));
506 
507 	rdc_sys_kstatsp->ctrl_fifo_sec.value.ul = statsp->ctrl_fifo_sec;
508 	rdc_sys_kstatsp->ctrl_fifo_ded.value.ul = statsp->ctrl_fifo_ded;
509 	rdc_sys_kstatsp->data_fifo_sec.value.ul = statsp->data_fifo_sec;
510 	rdc_sys_kstatsp->data_fifo_ded.value.ul = statsp->data_fifo_ded;
511 
512 	HXGE_DEBUG_MSG((hxgep, KST_CTL, " <== hxge_rdc_sys_stat_update"));
513 	return (0);
514 }
515 
516 /* ARGSUSED */
517 int
518 hxge_vmac_stat_update(kstat_t *ksp, int rw)
519 {
520 	p_hxge_t		hxgep;
521 	p_hxge_vmac_kstat_t	vmac_kstatsp;
522 	p_hxge_vmac_stats_t	statsp;
523 
524 	hxgep = (p_hxge_t)ksp->ks_private;
525 	if (hxgep == NULL)
526 		return (-1);
527 
528 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_vmac_stat_update"));
529 
530 	hxge_save_cntrs(hxgep);
531 
532 	vmac_kstatsp = (p_hxge_vmac_kstat_t)ksp->ks_data;
533 	statsp = (p_hxge_vmac_stats_t)&hxgep->statsp->vmac_stats;
534 
535 	vmac_kstatsp->tx_frame_cnt.value.ul = statsp->tx_frame_cnt;
536 	vmac_kstatsp->tx_byte_cnt.value.ul = statsp->tx_byte_cnt;
537 
538 	vmac_kstatsp->rx_frame_cnt.value.ul = statsp->rx_frame_cnt;
539 	vmac_kstatsp->rx_byte_cnt.value.ul = statsp->rx_byte_cnt;
540 	vmac_kstatsp->rx_drop_frame_cnt.value.ul = statsp->rx_drop_frame_cnt;
541 	vmac_kstatsp->rx_drop_byte_cnt.value.ul = statsp->rx_drop_byte_cnt;
542 	vmac_kstatsp->rx_crc_cnt.value.ul = statsp->rx_crc_cnt;
543 	vmac_kstatsp->rx_pause_cnt.value.ul = statsp->rx_pause_cnt;
544 	vmac_kstatsp->rx_bcast_fr_cnt.value.ul = statsp->rx_bcast_fr_cnt;
545 	vmac_kstatsp->rx_mcast_fr_cnt.value.ul = statsp->rx_mcast_fr_cnt;
546 
547 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "<== hxge_vmac_stat_update"));
548 	return (0);
549 }
550 
551 /* ARGSUSED */
552 int
553 hxge_pfc_stat_update(kstat_t *ksp, int rw)
554 {
555 	p_hxge_t		hxgep;
556 	p_hxge_pfc_kstat_t	kstatsp;
557 	p_hxge_pfc_stats_t	statsp;
558 
559 	hxgep = (p_hxge_t)ksp->ks_private;
560 	if (hxgep == NULL)
561 		return (-1);
562 
563 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_pfc_stat_update"));
564 
565 	kstatsp = (p_hxge_pfc_kstat_t)ksp->ks_data;
566 	statsp = (p_hxge_pfc_stats_t)&hxgep->statsp->pfc_stats;
567 
568 	kstatsp->pfc_pkt_drop.value.ul = statsp->pkt_drop;
569 	kstatsp->pfc_tcam_parity_err.value.ul = statsp->tcam_parity_err;
570 	kstatsp->pfc_vlan_parity_err.value.ul = statsp->vlan_parity_err;
571 	kstatsp->pfc_bad_cs_count.value.ul = statsp->bad_cs_count;
572 	kstatsp->pfc_drop_count.value.ul = statsp->drop_count;
573 	kstatsp->pfc_tcp_ctrl_drop.value.ul = statsp->errlog.tcp_ctrl_drop;
574 	kstatsp->pfc_l2_addr_drop.value.ul = statsp->errlog.l2_addr_drop;
575 	kstatsp->pfc_class_code_drop.value.ul = statsp->errlog.class_code_drop;
576 	kstatsp->pfc_tcam_drop.value.ul = statsp->errlog.tcam_drop;
577 	kstatsp->pfc_vlan_drop.value.ul = statsp->errlog.vlan_drop;
578 
579 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "<== hxge_pfc_stat_update"));
580 	return (0);
581 }
582 
583 static uint64_t
584 hxge_mac_octet_to_u64(struct ether_addr addr)
585 {
586 	int		i;
587 	uint64_t	addr64 = 0;
588 
589 	for (i = ETHERADDRL - 1; i >= 0; i--) {
590 		addr64 <<= 8;
591 		addr64 |= addr.ether_addr_octet[i];
592 	}
593 	return (addr64);
594 }
595 
596 /* ARGSUSED */
597 int
598 hxge_mmac_stat_update(kstat_t *ksp, int rw)
599 {
600 	p_hxge_t		hxgep;
601 	p_hxge_mmac_kstat_t	mmac_kstatsp;
602 	p_hxge_mmac_stats_t	statsp;
603 
604 	hxgep = (p_hxge_t)ksp->ks_private;
605 	if (hxgep == NULL)
606 		return (-1);
607 
608 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_mmac_stat_update"));
609 
610 	mmac_kstatsp = (p_hxge_mmac_kstat_t)ksp->ks_data;
611 	statsp = (p_hxge_mmac_stats_t)&hxgep->statsp->mmac_stats;
612 
613 	mmac_kstatsp->mmac_max_addr_cnt.value.ul = statsp->mmac_max_cnt;
614 	mmac_kstatsp->mmac_avail_addr_cnt.value.ul = statsp->mmac_avail_cnt;
615 	mmac_kstatsp->mmac_addr1.value.ul =
616 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[0]);
617 	mmac_kstatsp->mmac_addr2.value.ul =
618 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[1]);
619 	mmac_kstatsp->mmac_addr3.value.ul =
620 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[2]);
621 	mmac_kstatsp->mmac_addr4.value.ul =
622 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[3]);
623 	mmac_kstatsp->mmac_addr5.value.ul =
624 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[4]);
625 	mmac_kstatsp->mmac_addr6.value.ul =
626 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[5]);
627 	mmac_kstatsp->mmac_addr7.value.ul =
628 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[6]);
629 	mmac_kstatsp->mmac_addr8.value.ul =
630 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[7]);
631 	mmac_kstatsp->mmac_addr9.value.ul =
632 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[8]);
633 	mmac_kstatsp->mmac_addr10.value.ul =
634 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[9]);
635 	mmac_kstatsp->mmac_addr11.value.ul =
636 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[10]);
637 	mmac_kstatsp->mmac_addr12.value.ul =
638 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[11]);
639 	mmac_kstatsp->mmac_addr13.value.ul =
640 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[12]);
641 	mmac_kstatsp->mmac_addr14.value.ul =
642 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[13]);
643 	mmac_kstatsp->mmac_addr15.value.ul =
644 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[14]);
645 	mmac_kstatsp->mmac_addr16.value.ul =
646 	    hxge_mac_octet_to_u64(statsp->mmac_avail_pool[15]);
647 
648 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "<== hxge_mmac_stat_update"));
649 	return (0);
650 }
651 
652 /* ARGSUSED */
653 int
654 hxge_peu_sys_stat_update(kstat_t *ksp, int rw)
655 {
656 	p_hxge_t		hxgep;
657 	p_hxge_peu_sys_kstat_t	peu_kstatsp;
658 	p_hxge_peu_sys_stats_t	statsp;
659 
660 	hxgep = (p_hxge_t)ksp->ks_private;
661 	if (hxgep == NULL)
662 		return (-1);
663 
664 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_peu_sys_stat_update"));
665 
666 	peu_kstatsp = (p_hxge_peu_sys_kstat_t)ksp->ks_data;
667 	statsp = (p_hxge_peu_sys_stats_t)&hxgep->statsp->peu_sys_stats;
668 
669 	peu_kstatsp->spc_acc_err.value.ul = statsp->spc_acc_err;
670 	peu_kstatsp->tdc_pioacc_err.value.ul = statsp->tdc_pioacc_err;
671 	peu_kstatsp->rdc_pioacc_err.value.ul = statsp->rdc_pioacc_err;
672 	peu_kstatsp->pfc_pioacc_err.value.ul = statsp->pfc_pioacc_err;
673 	peu_kstatsp->vmac_pioacc_err.value.ul = statsp->vmac_pioacc_err;
674 	peu_kstatsp->cpl_hdrq_parerr.value.ul = statsp->cpl_hdrq_parerr;
675 	peu_kstatsp->cpl_dataq_parerr.value.ul = statsp->cpl_dataq_parerr;
676 	peu_kstatsp->retryram_xdlh_parerr.value.ul =
677 	    statsp->retryram_xdlh_parerr;
678 	peu_kstatsp->retrysotram_xdlh_parerr.value.ul =
679 	    statsp->retrysotram_xdlh_parerr;
680 	peu_kstatsp->p_hdrq_parerr.value.ul = statsp->p_hdrq_parerr;
681 	peu_kstatsp->p_dataq_parerr.value.ul = statsp->p_dataq_parerr;
682 	peu_kstatsp->np_hdrq_parerr.value.ul = statsp->np_hdrq_parerr;
683 	peu_kstatsp->np_dataq_parerr.value.ul = statsp->np_dataq_parerr;
684 	peu_kstatsp->eic_msix_parerr.value.ul = statsp->eic_msix_parerr;
685 	peu_kstatsp->hcr_parerr.value.ul = statsp->hcr_parerr;
686 
687 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "<== hxge_peu_sys_stat_update"));
688 	return (0);
689 }
690 
691 static kstat_t *
692 hxge_setup_local_kstat(p_hxge_t hxgep, int instance, char *name,
693 	const hxge_kstat_index_t *ksip, size_t count,
694 	int (*update) (kstat_t *, int))
695 {
696 	kstat_t		*ksp;
697 	kstat_named_t	*knp;
698 	int		i;
699 
700 	ksp = kstat_create(HXGE_DRIVER_NAME, instance, name, "net",
701 	    KSTAT_TYPE_NAMED, count, 0);
702 	if (ksp == NULL)
703 		return (NULL);
704 
705 	ksp->ks_private = (void *) hxgep;
706 	ksp->ks_update = update;
707 	knp = ksp->ks_data;
708 
709 	for (i = 0; ksip[i].name != NULL; i++) {
710 		kstat_named_init(&knp[i], ksip[i].name, ksip[i].type);
711 	}
712 
713 	kstat_install(ksp);
714 
715 	return (ksp);
716 }
717 
718 void
719 hxge_setup_kstats(p_hxge_t hxgep)
720 {
721 	struct kstat		*ksp;
722 	p_hxge_port_kstat_t	hxgekp;
723 	size_t			hxge_kstat_sz;
724 	char			stat_name[64];
725 	char			mmac_name[64];
726 	int			i;
727 
728 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_setup_kstats"));
729 
730 	/* Setup RDC statistics */
731 	for (i = 0; i < hxgep->nrdc; i++) {
732 		(void) sprintf(stat_name, "%s"CH_NAME_FORMAT,
733 		    RDC_NAME_FORMAT1, i);
734 		hxgep->statsp->rdc_ksp[i] = hxge_setup_local_kstat(hxgep,
735 		    hxgep->instance, stat_name, &hxge_rdc_stats[0],
736 		    RDC_STAT_END, hxge_rdc_stat_update);
737 		if (hxgep->statsp->rdc_ksp[i] == NULL)
738 			cmn_err(CE_WARN,
739 			    "kstat_create failed for rdc channel %d", i);
740 	}
741 
742 	/* Setup RDC System statistics */
743 	hxgep->statsp->rdc_sys_ksp = hxge_setup_local_kstat(hxgep,
744 	    hxgep->instance, "RDC_system", &hxge_rdc_sys_stats[0],
745 	    RDC_SYS_STAT_END, hxge_rdc_sys_stat_update);
746 	if (hxgep->statsp->rdc_sys_ksp == NULL)
747 		cmn_err(CE_WARN, "kstat_create failed for rdc_sys_ksp");
748 
749 	/* Setup TDC statistics */
750 	for (i = 0; i < hxgep->ntdc; i++) {
751 		(void) sprintf(stat_name, "%s"CH_NAME_FORMAT,
752 		    TDC_NAME_FORMAT1, i);
753 		hxgep->statsp->tdc_ksp[i] = hxge_setup_local_kstat(hxgep,
754 		    hxgep->instance, stat_name, &hxge_tdc_stats[0],
755 		    TDC_STAT_END, hxge_tdc_stat_update);
756 		if (hxgep->statsp->tdc_ksp[i] == NULL)
757 			cmn_err(CE_WARN,
758 			    "kstat_create failed for tdc channel %d", i);
759 	}
760 
761 	/* Setup TDC System statistics */
762 	hxgep->statsp->tdc_sys_ksp = hxge_setup_local_kstat(hxgep,
763 	    hxgep->instance, "TDC_system", &hxge_tdc_sys_stats[0],
764 	    RDC_SYS_STAT_END, hxge_tdc_sys_stat_update);
765 	if (hxgep->statsp->tdc_sys_ksp == NULL)
766 		cmn_err(CE_WARN, "kstat_create failed for tdc_sys_ksp");
767 
768 	/* Setup PFC statistics */
769 	hxgep->statsp->pfc_ksp = hxge_setup_local_kstat(hxgep,
770 	    hxgep->instance, "PFC", &hxge_pfc_stats[0],
771 	    PFC_STAT_END, hxge_pfc_stat_update);
772 	if (hxgep->statsp->pfc_ksp == NULL)
773 		cmn_err(CE_WARN, "kstat_create failed for pfc");
774 
775 	/* Setup VMAC statistics */
776 	hxgep->statsp->vmac_ksp = hxge_setup_local_kstat(hxgep,
777 	    hxgep->instance, "VMAC", &hxge_vmac_stats[0],
778 	    VMAC_STAT_END, hxge_vmac_stat_update);
779 	if (hxgep->statsp->vmac_ksp == NULL)
780 		cmn_err(CE_WARN, "kstat_create failed for vmac");
781 
782 	/* Setup MMAC statistics */
783 	(void) sprintf(mmac_name, "MMAC Stats%d", hxgep->instance);
784 	hxgep->statsp->mmac_ksp = hxge_setup_local_kstat(hxgep,
785 	    hxgep->instance, "MMAC",
786 	    &hxge_mmac_stats[0], MMAC_STATS_END, hxge_mmac_stat_update);
787 	if (hxgep->statsp->mmac_ksp == NULL)
788 		cmn_err(CE_WARN, "kstat_create failed for mmac");
789 
790 	/* Setup PEU System statistics */
791 	hxgep->statsp->peu_sys_ksp = hxge_setup_local_kstat(hxgep,
792 	    hxgep->instance, "PEU", &hxge_peu_sys_stats[0],
793 	    PEU_SYS_STAT_END, hxge_peu_sys_stat_update);
794 	if (hxgep->statsp->peu_sys_ksp == NULL)
795 		cmn_err(CE_WARN, "kstat_create failed for peu sys");
796 
797 	/* Port stats */
798 	hxge_kstat_sz = sizeof (hxge_port_kstat_t);
799 
800 	if ((ksp = kstat_create(HXGE_DRIVER_NAME, hxgep->instance,
801 	    "Port", "net", KSTAT_TYPE_NAMED,
802 	    hxge_kstat_sz / sizeof (kstat_named_t), 0)) == NULL) {
803 		cmn_err(CE_WARN, "kstat_create failed for port stat");
804 		return;
805 	}
806 
807 	hxgekp = (p_hxge_port_kstat_t)ksp->ks_data;
808 
809 	kstat_named_init(&hxgekp->cap_10gfdx, "cap_10gfdx", KSTAT_DATA_ULONG);
810 
811 	/*
812 	 * Link partner capabilities.
813 	 */
814 	kstat_named_init(&hxgekp->lp_cap_10gfdx, "lp_cap_10gfdx",
815 	    KSTAT_DATA_ULONG);
816 
817 	/*
818 	 * Shared link setup.
819 	 */
820 	kstat_named_init(&hxgekp->link_speed, "link_speed", KSTAT_DATA_ULONG);
821 	kstat_named_init(&hxgekp->link_duplex, "link_duplex", KSTAT_DATA_CHAR);
822 	kstat_named_init(&hxgekp->link_up, "link_up", KSTAT_DATA_ULONG);
823 
824 	/*
825 	 * Loopback statistics.
826 	 */
827 	kstat_named_init(&hxgekp->lb_mode, "lb_mode", KSTAT_DATA_ULONG);
828 
829 	/* General MAC statistics */
830 
831 	kstat_named_init(&hxgekp->ifspeed, "ifspeed", KSTAT_DATA_UINT64);
832 	kstat_named_init(&hxgekp->promisc, "promisc", KSTAT_DATA_CHAR);
833 
834 	ksp->ks_update = hxge_port_kstat_update;
835 	ksp->ks_private = (void *) hxgep;
836 	kstat_install(ksp);
837 	hxgep->statsp->port_ksp = ksp;
838 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "<== hxge_setup_kstats"));
839 }
840 
841 void
842 hxge_destroy_kstats(p_hxge_t hxgep)
843 {
844 	int			channel;
845 	p_hxge_dma_pt_cfg_t	p_dma_cfgp;
846 	p_hxge_hw_pt_cfg_t	p_cfgp;
847 
848 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_destroy_kstats"));
849 	if (hxgep->statsp == NULL)
850 		return;
851 
852 	if (hxgep->statsp->ksp)
853 		kstat_delete(hxgep->statsp->ksp);
854 
855 	p_dma_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config;
856 	p_cfgp = (p_hxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
857 
858 	for (channel = 0; channel < p_cfgp->max_rdcs; channel++) {
859 		if (hxgep->statsp->rdc_ksp[channel]) {
860 			kstat_delete(hxgep->statsp->rdc_ksp[channel]);
861 		}
862 	}
863 
864 	for (channel = 0; channel < p_cfgp->max_tdcs; channel++) {
865 		if (hxgep->statsp->tdc_ksp[channel]) {
866 			kstat_delete(hxgep->statsp->tdc_ksp[channel]);
867 		}
868 	}
869 
870 	if (hxgep->statsp->rdc_sys_ksp)
871 		kstat_delete(hxgep->statsp->rdc_sys_ksp);
872 
873 	if (hxgep->statsp->tdc_sys_ksp)
874 		kstat_delete(hxgep->statsp->tdc_sys_ksp);
875 
876 	if (hxgep->statsp->peu_sys_ksp)
877 		kstat_delete(hxgep->statsp->peu_sys_ksp);
878 
879 	if (hxgep->statsp->mmac_ksp)
880 		kstat_delete(hxgep->statsp->mmac_ksp);
881 
882 	if (hxgep->statsp->pfc_ksp)
883 		kstat_delete(hxgep->statsp->pfc_ksp);
884 
885 	if (hxgep->statsp->vmac_ksp)
886 		kstat_delete(hxgep->statsp->vmac_ksp);
887 
888 	if (hxgep->statsp->port_ksp)
889 		kstat_delete(hxgep->statsp->port_ksp);
890 
891 	if (hxgep->statsp)
892 		KMEM_FREE(hxgep->statsp, hxgep->statsp->stats_size);
893 
894 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "<== hxge_destroy_kstats"));
895 }
896 
897 /* ARGSUSED */
898 int
899 hxge_port_kstat_update(kstat_t *ksp, int rw)
900 {
901 	p_hxge_t		hxgep;
902 	p_hxge_stats_t		statsp;
903 	p_hxge_port_kstat_t	hxgekp;
904 	p_hxge_port_stats_t	psp;
905 
906 	hxgep = (p_hxge_t)ksp->ks_private;
907 	if (hxgep == NULL)
908 		return (-1);
909 
910 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_port_kstat_update"));
911 	statsp = (p_hxge_stats_t)hxgep->statsp;
912 	hxgekp = (p_hxge_port_kstat_t)ksp->ks_data;
913 	psp = &statsp->port_stats;
914 
915 	if (hxgep->filter.all_phys_cnt)
916 		(void) strcpy(hxgekp->promisc.value.c, "phys");
917 	else if (hxgep->filter.all_multicast_cnt)
918 		(void) strcpy(hxgekp->promisc.value.c, "multi");
919 	else
920 		(void) strcpy(hxgekp->promisc.value.c, "off");
921 	hxgekp->ifspeed.value.ul = statsp->mac_stats.link_speed * 1000000ULL;
922 
923 	/*
924 	 * transceiver state informations.
925 	 */
926 	hxgekp->cap_10gfdx.value.ul = statsp->mac_stats.cap_10gfdx;
927 
928 	/*
929 	 * Link partner capabilities.
930 	 */
931 	hxgekp->lp_cap_10gfdx.value.ul = statsp->mac_stats.lp_cap_10gfdx;
932 
933 	/*
934 	 * Physical link statistics.
935 	 */
936 	hxgekp->link_speed.value.ul = statsp->mac_stats.link_speed;
937 	if (statsp->mac_stats.link_duplex == 2)
938 		(void) strcpy(hxgekp->link_duplex.value.c, "full");
939 	else
940 		(void) strcpy(hxgekp->link_duplex.value.c, "unknown");
941 	hxgekp->link_up.value.ul = statsp->mac_stats.link_up;
942 
943 	/*
944 	 * Loopback statistics.
945 	 */
946 	hxgekp->lb_mode.value.ul = psp->lb_mode;
947 
948 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "<== hxge_port_kstat_update"));
949 	return (0);
950 }
951 
952 int
953 hxge_m_stat(void *arg, uint_t stat, uint64_t *value)
954 {
955 	p_hxge_t		hxgep = (p_hxge_t)arg;
956 	p_hxge_stats_t		statsp;
957 	hxge_tx_ring_stats_t	*tx_stats;
958 	uint64_t		val = 0;
959 	int			channel;
960 
961 	HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_m_stat"));
962 	statsp = (p_hxge_stats_t)hxgep->statsp;
963 
964 	switch (stat) {
965 	case MAC_STAT_IFSPEED:
966 		val = statsp->mac_stats.link_speed * 1000000ull;
967 		break;
968 
969 	case MAC_STAT_MULTIRCV:
970 		val = 0;
971 		break;
972 
973 	case MAC_STAT_BRDCSTRCV:
974 		val = 0;
975 		break;
976 
977 	case MAC_STAT_MULTIXMT:
978 		val = 0;
979 		break;
980 
981 	case MAC_STAT_BRDCSTXMT:
982 		val = 0;
983 		break;
984 
985 	case MAC_STAT_NORCVBUF:
986 		val = 0;
987 		break;
988 
989 	case MAC_STAT_IERRORS:
990 	case ETHER_STAT_MACRCV_ERRORS:
991 		val = 0;
992 		for (channel = 0; channel < hxgep->nrdc; channel++) {
993 			val += statsp->rdc_stats[channel].ierrors;
994 		}
995 		break;
996 
997 	case MAC_STAT_NOXMTBUF:
998 		val = 0;
999 		break;
1000 
1001 	case MAC_STAT_OERRORS:
1002 		for (channel = 0; channel < hxgep->ntdc; channel++) {
1003 			val += statsp->tdc_stats[channel].oerrors;
1004 		}
1005 		break;
1006 
1007 	case MAC_STAT_COLLISIONS:
1008 		val = 0;
1009 		break;
1010 
1011 	case MAC_STAT_RBYTES:
1012 		for (channel = 0; channel < hxgep->nrdc; channel++) {
1013 			val += statsp->rdc_stats[channel].ibytes;
1014 		}
1015 		break;
1016 
1017 	case MAC_STAT_IPACKETS:
1018 		for (channel = 0; channel < hxgep->nrdc; channel++) {
1019 			val += statsp->rdc_stats[channel].ipackets;
1020 		}
1021 		break;
1022 
1023 	case MAC_STAT_OBYTES:
1024 		for (channel = 0; channel < hxgep->ntdc; channel++) {
1025 			val += statsp->tdc_stats[channel].obytes;
1026 		}
1027 		break;
1028 
1029 	case MAC_STAT_OPACKETS:
1030 		for (channel = 0; channel < hxgep->ntdc; channel++) {
1031 			val += statsp->tdc_stats[channel].opackets;
1032 		}
1033 		break;
1034 
1035 	case MAC_STAT_UNKNOWNS:
1036 		val = 0;
1037 		break;
1038 
1039 	case MAC_STAT_UNDERFLOWS:
1040 		val = 0;
1041 		break;
1042 
1043 	case MAC_STAT_OVERFLOWS:
1044 		val = 0;
1045 		break;
1046 
1047 	case MAC_STAT_LINK_STATE:
1048 		val = statsp->mac_stats.link_duplex;
1049 		break;
1050 	case MAC_STAT_LINK_UP:
1051 		val = statsp->mac_stats.link_up;
1052 		break;
1053 	case MAC_STAT_PROMISC:
1054 		val = statsp->mac_stats.promisc;
1055 		break;
1056 	case ETHER_STAT_SQE_ERRORS:
1057 		val = 0;
1058 		break;
1059 
1060 	case ETHER_STAT_ALIGN_ERRORS:
1061 		/*
1062 		 * No similar error in Hydra receive channels
1063 		 */
1064 		val = 0;
1065 		break;
1066 
1067 	case ETHER_STAT_FCS_ERRORS:
1068 		/*
1069 		 * No similar error in Hydra receive channels
1070 		 */
1071 		val = 0;
1072 		break;
1073 
1074 	case ETHER_STAT_FIRST_COLLISIONS:
1075 		val = 0;
1076 		break;
1077 
1078 	case ETHER_STAT_MULTI_COLLISIONS:
1079 		val = 0;
1080 		break;
1081 
1082 	case ETHER_STAT_TX_LATE_COLLISIONS:
1083 		val = 0;
1084 		break;
1085 
1086 	case ETHER_STAT_EX_COLLISIONS:
1087 		val = 0;
1088 		break;
1089 
1090 	case ETHER_STAT_DEFER_XMTS:
1091 		val = 0;
1092 		break;
1093 
1094 	case ETHER_STAT_MACXMT_ERRORS:
1095 		/*
1096 		 * A count of frames for which transmission on a
1097 		 * particular interface fails due to an internal
1098 		 * MAC sublayer transmit error
1099 		 */
1100 		for (channel = 0; channel < hxgep->ntdc; channel++) {
1101 			tx_stats = &statsp->tdc_stats[channel];
1102 			val += tx_stats->pkt_size_hdr_err +
1103 			    tx_stats->pkt_size_err +
1104 			    tx_stats->tx_rng_oflow +
1105 			    tx_stats->peu_resp_err +
1106 			    tx_stats->runt_pkt_drop_err +
1107 			    tx_stats->pref_par_err +
1108 			    tx_stats->tdr_pref_cpl_to +
1109 			    tx_stats->pkt_cpl_to +
1110 			    tx_stats->invalid_sop +
1111 			    tx_stats->unexpected_sop;
1112 		}
1113 		break;
1114 
1115 	case ETHER_STAT_CARRIER_ERRORS:
1116 		/*
1117 		 * The number of times that the carrier sense
1118 		 * condition was lost or never asserted when
1119 		 * attempting to transmit a frame on a particular interface
1120 		 */
1121 		for (channel = 0; channel < hxgep->ntdc; channel++) {
1122 			tx_stats = &statsp->tdc_stats[channel];
1123 			val += tx_stats->tdr_pref_cpl_to + tx_stats->pkt_cpl_to;
1124 		}
1125 		break;
1126 
1127 	case ETHER_STAT_TOOLONG_ERRORS:
1128 		/*
1129 		 * A count of frames received on a particular
1130 		 * interface that exceed the maximum permitted frame size
1131 		 */
1132 		for (channel = 0; channel < hxgep->ntdc; channel++) {
1133 			tx_stats = &statsp->tdc_stats[channel];
1134 			val += tx_stats->pkt_size_err;
1135 		}
1136 		break;
1137 
1138 	case ETHER_STAT_XCVR_ADDR:
1139 		val = 0;
1140 		break;
1141 	case ETHER_STAT_XCVR_ID:
1142 		val = 0;
1143 		break;
1144 
1145 	case ETHER_STAT_XCVR_INUSE:
1146 		val = 0;
1147 		break;
1148 
1149 	case ETHER_STAT_CAP_1000FDX:
1150 		val = 0;
1151 		break;
1152 
1153 	case ETHER_STAT_CAP_1000HDX:
1154 		val = 0;
1155 		break;
1156 
1157 	case ETHER_STAT_CAP_100FDX:
1158 		val = 0;
1159 		break;
1160 
1161 	case ETHER_STAT_CAP_100HDX:
1162 		val = 0;
1163 		break;
1164 
1165 	case ETHER_STAT_CAP_10FDX:
1166 		val = 0;
1167 		break;
1168 
1169 	case ETHER_STAT_CAP_10HDX:
1170 		val = 0;
1171 		break;
1172 
1173 	case ETHER_STAT_CAP_ASMPAUSE:
1174 		val = 0;
1175 		break;
1176 
1177 	case ETHER_STAT_CAP_PAUSE:
1178 		val = 0;
1179 		break;
1180 
1181 	case ETHER_STAT_CAP_AUTONEG:
1182 		val = 0;
1183 		break;
1184 
1185 	case ETHER_STAT_ADV_CAP_1000FDX:
1186 		val = 0;
1187 		break;
1188 
1189 	case ETHER_STAT_ADV_CAP_1000HDX:
1190 		val = 0;
1191 		break;
1192 
1193 	case ETHER_STAT_ADV_CAP_100FDX:
1194 		val = 0;
1195 		break;
1196 
1197 	case ETHER_STAT_ADV_CAP_100HDX:
1198 		val = 0;
1199 		break;
1200 
1201 	case ETHER_STAT_ADV_CAP_10FDX:
1202 		val = 0;
1203 		break;
1204 
1205 	case ETHER_STAT_ADV_CAP_10HDX:
1206 		val = 0;
1207 		break;
1208 
1209 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
1210 		val = 0;
1211 		break;
1212 
1213 	case ETHER_STAT_ADV_CAP_PAUSE:
1214 		val = 0;
1215 		break;
1216 
1217 	case ETHER_STAT_ADV_CAP_AUTONEG:
1218 		val = 0;
1219 		break;
1220 
1221 	case ETHER_STAT_LP_CAP_1000FDX:
1222 		val = 0;
1223 		break;
1224 
1225 	case ETHER_STAT_LP_CAP_1000HDX:
1226 		val = 0;
1227 		break;
1228 
1229 	case ETHER_STAT_LP_CAP_100FDX:
1230 		val = 0;
1231 		break;
1232 
1233 	case ETHER_STAT_LP_CAP_100HDX:
1234 		val = 0;
1235 		break;
1236 
1237 	case ETHER_STAT_LP_CAP_10FDX:
1238 		val = 0;
1239 		break;
1240 
1241 	case ETHER_STAT_LP_CAP_10HDX:
1242 		val = 0;
1243 		break;
1244 
1245 	case ETHER_STAT_LP_CAP_ASMPAUSE:
1246 		val = 0;
1247 		break;
1248 
1249 	case ETHER_STAT_LP_CAP_PAUSE:
1250 		val = 0;
1251 		break;
1252 
1253 	case ETHER_STAT_LP_CAP_AUTONEG:
1254 		val = 0;
1255 		break;
1256 
1257 	case ETHER_STAT_LINK_ASMPAUSE:
1258 		val = 0;
1259 		break;
1260 
1261 	case ETHER_STAT_LINK_PAUSE:
1262 		val = 0;
1263 		break;
1264 
1265 	case ETHER_STAT_LINK_AUTONEG:
1266 		val = 0;
1267 		break;
1268 
1269 	case ETHER_STAT_LINK_DUPLEX:
1270 		val = statsp->mac_stats.link_duplex;
1271 		break;
1272 
1273 	case ETHER_STAT_TOOSHORT_ERRORS:
1274 		val = 0;
1275 		break;
1276 
1277 	case ETHER_STAT_CAP_REMFAULT:
1278 		val = 0;
1279 		break;
1280 
1281 	case ETHER_STAT_ADV_REMFAULT:
1282 		val = 0;
1283 		break;
1284 
1285 	case ETHER_STAT_LP_REMFAULT:
1286 		val = 0;
1287 		break;
1288 
1289 	case ETHER_STAT_JABBER_ERRORS:
1290 		val = 0;
1291 		break;
1292 
1293 	case ETHER_STAT_CAP_100T4:
1294 		val = 0;
1295 		break;
1296 
1297 	case ETHER_STAT_ADV_CAP_100T4:
1298 		val = 0;
1299 		break;
1300 
1301 	case ETHER_STAT_LP_CAP_100T4:
1302 		val = 0;
1303 		break;
1304 
1305 	default:
1306 		/*
1307 		 * Shouldn't reach here...
1308 		 */
1309 		cmn_err(CE_WARN,
1310 		    "hxge_m_stat: unrecognized parameter value = 0x%x", stat);
1311 
1312 		return (ENOTSUP);
1313 	}
1314 	*value = val;
1315 	return (0);
1316 }
1317