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