Home | History | Annotate | Download | only in hxge
      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