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