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