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 2010 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 /*
 885  * Retrieve a value for one of the statistics for a particular rx ring
 886  */
 887 int
 888 hxge_rx_ring_stat(mac_ring_driver_t rdriver, uint_t stat, uint64_t *val)
 889 {
 890         p_hxge_ring_handle_t    rhp = (p_hxge_ring_handle_t)rdriver;
 891         p_hxge_t                hxgep = rhp->hxgep;
 892 
 893         ASSERT(rhp != NULL);
 894         ASSERT(hxgep != NULL);
 895         ASSERT(hxgep->statsp != NULL);
 896         ASSERT((rhp->index >= 0) && (rhp->index < HXGE_MAX_RDCS));
 897 
 898         switch (stat) {
 899         case MAC_STAT_IERRORS:
 900                 *val = hxgep->statsp->rdc_stats[rhp->index].ierrors;
 901                 break;
 902         case MAC_STAT_RBYTES:
 903                 *val = hxgep->statsp->rdc_stats[rhp->index].ibytes;
 904                 break;
 905         case MAC_STAT_IPACKETS:
 906                 *val = hxgep->statsp->rdc_stats[rhp->index].ipackets;
 907                 break;
 908         default:
 909                 *val = 0;
 910                 return (ENOTSUP);
 911         }
 912 
 913         return (0);
 914 }
 915 
 916 /*
 917  * Retrieve a value for one of the statistics for a particular tx ring
 918  */
 919 int
 920 hxge_tx_ring_stat(mac_ring_driver_t rdriver, uint_t stat, uint64_t *val)
 921 {
 922         p_hxge_ring_handle_t    rhp = (p_hxge_ring_handle_t)rdriver;
 923         p_hxge_t                hxgep = rhp->hxgep;
 924 
 925         ASSERT(rhp != NULL);
 926         ASSERT(hxgep != NULL);
 927         ASSERT(hxgep->statsp != NULL);
 928         ASSERT((rhp->index >= 0) && (rhp->index < HXGE_MAX_TDCS));
 929 
 930         switch (stat) {
 931         case MAC_STAT_OERRORS:
 932                 *val = hxgep->statsp->tdc_stats[rhp->index].oerrors;
 933                 break;
 934         case MAC_STAT_OBYTES:
 935                 *val = hxgep->statsp->tdc_stats[rhp->index].obytes;
 936                 break;
 937         case MAC_STAT_OPACKETS:
 938                 *val = hxgep->statsp->tdc_stats[rhp->index].opackets;
 939                 break;
 940         default:
 941                 *val = 0;
 942                 return (ENOTSUP);
 943         }
 944 
 945         return (0);
 946 }
 947 
 948 int
 949 hxge_m_stat(void *arg, uint_t stat, uint64_t *value)
 950 {
 951         p_hxge_t                hxgep = (p_hxge_t)arg;
 952         p_hxge_stats_t          statsp;
 953         hxge_tx_ring_stats_t    *tx_stats;
 954         uint64_t                val = 0;
 955         int                     channel;
 956 
 957         HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_m_stat"));
 958         statsp = (p_hxge_stats_t)hxgep->statsp;
 959 
 960         switch (stat) {
 961         case MAC_STAT_IFSPEED:
 962                 val = statsp->mac_stats.link_speed * 1000000ull;
 963                 break;
 964 
 965         case MAC_STAT_MULTIRCV:
 966                 val = 0;
 967                 break;
 968 
 969         case MAC_STAT_BRDCSTRCV:
 970                 val = 0;
 971                 break;
 972 
 973         case MAC_STAT_MULTIXMT:
 974                 val = 0;
 975                 break;
 976 
 977         case MAC_STAT_BRDCSTXMT:
 978                 val = 0;
 979                 break;
 980 
 981         case MAC_STAT_NORCVBUF:
 982                 val = 0;
 983                 break;
 984 
 985         case MAC_STAT_IERRORS:
 986         case ETHER_STAT_MACRCV_ERRORS:
 987                 val = 0;
 988                 for (channel = 0; channel < hxgep->nrdc; channel++) {
 989                         val += statsp->rdc_stats[channel].ierrors;
 990                 }
 991                 break;
 992 
 993         case MAC_STAT_NOXMTBUF:
 994                 val = 0;
 995                 break;
 996 
 997         case MAC_STAT_OERRORS:
 998                 for (channel = 0; channel < hxgep->ntdc; channel++) {
 999                         val += statsp->tdc_stats[channel].oerrors;
1000                 }
1001                 break;
1002 
1003         case MAC_STAT_COLLISIONS:
1004                 val = 0;
1005                 break;
1006 
1007         case MAC_STAT_RBYTES:
1008                 for (channel = 0; channel < hxgep->nrdc; channel++) {
1009                         val += statsp->rdc_stats[channel].ibytes;
1010                 }
1011                 break;
1012 
1013         case MAC_STAT_IPACKETS:
1014                 for (channel = 0; channel < hxgep->nrdc; channel++) {
1015                         val += statsp->rdc_stats[channel].ipackets;
1016                 }
1017                 break;
1018 
1019         case MAC_STAT_OBYTES:
1020                 for (channel = 0; channel < hxgep->ntdc; channel++) {
1021                         val += statsp->tdc_stats[channel].obytes;
1022                 }
1023                 break;
1024 
1025         case MAC_STAT_OPACKETS:
1026                 for (channel = 0; channel < hxgep->ntdc; channel++) {
1027                         val += statsp->tdc_stats[channel].opackets;
1028                 }
1029                 break;
1030 
1031         case MAC_STAT_UNKNOWNS:
1032                 val = 0;
1033                 break;
1034 
1035         case MAC_STAT_UNDERFLOWS:
1036                 val = 0;
1037                 break;
1038 
1039         case MAC_STAT_OVERFLOWS:
1040                 val = 0;
1041                 break;
1042 
1043         case MAC_STAT_LINK_STATE:
1044                 val = statsp->mac_stats.link_duplex;
1045                 break;
1046         case MAC_STAT_LINK_UP:
1047                 val = statsp->mac_stats.link_up;
1048                 break;
1049         case MAC_STAT_PROMISC:
1050                 val = statsp->mac_stats.promisc;
1051                 break;
1052         case ETHER_STAT_SQE_ERRORS:
1053                 val = 0;
1054                 break;
1055 
1056         case ETHER_STAT_ALIGN_ERRORS:
1057                 /*
1058                  * No similar error in Hydra receive channels
1059                  */
1060                 val = 0;
1061                 break;
1062 
1063         case ETHER_STAT_FCS_ERRORS:
1064                 /*
1065                  * No similar error in Hydra receive channels
1066                  */
1067                 val = 0;
1068                 break;
1069 
1070         case ETHER_STAT_FIRST_COLLISIONS:
1071                 val = 0;
1072                 break;
1073 
1074         case ETHER_STAT_MULTI_COLLISIONS:
1075                 val = 0;
1076                 break;
1077 
1078         case ETHER_STAT_TX_LATE_COLLISIONS:
1079                 val = 0;
1080                 break;
1081 
1082         case ETHER_STAT_EX_COLLISIONS:
1083                 val = 0;
1084                 break;
1085 
1086         case ETHER_STAT_DEFER_XMTS:
1087                 val = 0;
1088                 break;
1089 
1090         case ETHER_STAT_MACXMT_ERRORS:
1091                 /*
1092                  * A count of frames for which transmission on a
1093                  * particular interface fails due to an internal
1094                  * MAC sublayer transmit error
1095                  */
1096                 for (channel = 0; channel < hxgep->ntdc; channel++) {
1097                         tx_stats = &statsp->tdc_stats[channel];
1098                         val += tx_stats->pkt_size_hdr_err +
1099                             tx_stats->pkt_size_err +
1100                             tx_stats->tx_rng_oflow +
1101                             tx_stats->peu_resp_err +
1102                             tx_stats->runt_pkt_drop_err +
1103                             tx_stats->pref_par_err +
1104                             tx_stats->tdr_pref_cpl_to +
1105                             tx_stats->pkt_cpl_to +
1106                             tx_stats->invalid_sop +
1107                             tx_stats->unexpected_sop;
1108                 }
1109                 break;
1110 
1111         case ETHER_STAT_CARRIER_ERRORS:
1112                 /*
1113                  * The number of times that the carrier sense
1114                  * condition was lost or never asserted when
1115                  * attempting to transmit a frame on a particular interface
1116                  */
1117                 for (channel = 0; channel < hxgep->ntdc; channel++) {
1118                         tx_stats = &statsp->tdc_stats[channel];
1119                         val += tx_stats->tdr_pref_cpl_to + tx_stats->pkt_cpl_to;
1120                 }
1121                 break;
1122 
1123         case ETHER_STAT_TOOLONG_ERRORS:
1124                 /*
1125                  * A count of frames received on a particular
1126                  * interface that exceed the maximum permitted frame size
1127                  */
1128                 for (channel = 0; channel < hxgep->ntdc; channel++) {
1129                         tx_stats = &statsp->tdc_stats[channel];
1130                         val += tx_stats->pkt_size_err;
1131                 }
1132                 break;
1133 
1134         case ETHER_STAT_XCVR_ADDR:
1135                 val = 0;
1136                 break;
1137         case ETHER_STAT_XCVR_ID:
1138                 val = 0;
1139                 break;
1140 
1141         case ETHER_STAT_XCVR_INUSE:
1142                 val = 0;
1143                 break;
1144 
1145         case ETHER_STAT_CAP_1000FDX:
1146                 val = 0;
1147                 break;
1148 
1149         case ETHER_STAT_CAP_1000HDX:
1150                 val = 0;
1151                 break;
1152 
1153         case ETHER_STAT_CAP_100FDX:
1154                 val = 0;
1155                 break;
1156 
1157         case ETHER_STAT_CAP_100HDX:
1158                 val = 0;
1159                 break;
1160 
1161         case ETHER_STAT_CAP_10FDX:
1162                 val = 0;
1163                 break;
1164 
1165         case ETHER_STAT_CAP_10HDX:
1166                 val = 0;
1167                 break;
1168 
1169         case ETHER_STAT_CAP_ASMPAUSE:
1170                 val = 0;
1171                 break;
1172 
1173         case ETHER_STAT_CAP_PAUSE:
1174                 val = 0;
1175                 break;
1176 
1177         case ETHER_STAT_CAP_AUTONEG:
1178                 val = 0;
1179                 break;
1180 
1181         case ETHER_STAT_ADV_CAP_1000FDX:
1182                 val = 0;
1183                 break;
1184 
1185         case ETHER_STAT_ADV_CAP_1000HDX:
1186                 val = 0;
1187                 break;
1188 
1189         case ETHER_STAT_ADV_CAP_100FDX:
1190                 val = 0;
1191                 break;
1192 
1193         case ETHER_STAT_ADV_CAP_100HDX:
1194                 val = 0;
1195                 break;
1196 
1197         case ETHER_STAT_ADV_CAP_10FDX:
1198                 val = 0;
1199                 break;
1200 
1201         case ETHER_STAT_ADV_CAP_10HDX:
1202                 val = 0;
1203                 break;
1204 
1205         case ETHER_STAT_ADV_CAP_ASMPAUSE:
1206                 val = 0;
1207                 break;
1208 
1209         case ETHER_STAT_ADV_CAP_PAUSE:
1210                 val = 0;
1211                 break;
1212 
1213         case ETHER_STAT_ADV_CAP_AUTONEG:
1214                 val = 0;
1215                 break;
1216 
1217         case ETHER_STAT_LP_CAP_1000FDX:
1218                 val = 0;
1219                 break;
1220 
1221         case ETHER_STAT_LP_CAP_1000HDX:
1222                 val = 0;
1223                 break;
1224 
1225         case ETHER_STAT_LP_CAP_100FDX:
1226                 val = 0;
1227                 break;
1228 
1229         case ETHER_STAT_LP_CAP_100HDX:
1230                 val = 0;
1231                 break;
1232 
1233         case ETHER_STAT_LP_CAP_10FDX:
1234                 val = 0;
1235                 break;
1236 
1237         case ETHER_STAT_LP_CAP_10HDX:
1238                 val = 0;
1239                 break;
1240 
1241         case ETHER_STAT_LP_CAP_ASMPAUSE:
1242                 val = 0;
1243                 break;
1244 
1245         case ETHER_STAT_LP_CAP_PAUSE:
1246                 val = 0;
1247                 break;
1248 
1249         case ETHER_STAT_LP_CAP_AUTONEG:
1250                 val = 0;
1251                 break;
1252 
1253         case ETHER_STAT_LINK_ASMPAUSE:
1254                 val = 0;
1255                 break;
1256 
1257         case ETHER_STAT_LINK_PAUSE:
1258                 val = 0;
1259                 break;
1260 
1261         case ETHER_STAT_LINK_AUTONEG:
1262                 val = 0;
1263                 break;
1264 
1265         case ETHER_STAT_LINK_DUPLEX:
1266                 val = statsp->mac_stats.link_duplex;
1267                 break;
1268 
1269         case ETHER_STAT_TOOSHORT_ERRORS:
1270                 val = 0;
1271                 break;
1272 
1273         case ETHER_STAT_CAP_REMFAULT:
1274                 val = 0;
1275                 break;
1276 
1277         case ETHER_STAT_ADV_REMFAULT:
1278                 val = 0;
1279                 break;
1280 
1281         case ETHER_STAT_LP_REMFAULT:
1282                 val = 0;
1283                 break;
1284 
1285         case ETHER_STAT_JABBER_ERRORS:
1286                 val = 0;
1287                 break;
1288 
1289         case ETHER_STAT_CAP_100T4:
1290                 val = 0;
1291                 break;
1292 
1293         case ETHER_STAT_ADV_CAP_100T4:
1294                 val = 0;
1295                 break;
1296 
1297         case ETHER_STAT_LP_CAP_100T4:
1298                 val = 0;
1299                 break;
1300 
1301         case ETHER_STAT_ADV_CAP_10GFDX:
1302         case ETHER_STAT_CAP_10GFDX:
1303         case ETHER_STAT_LP_CAP_10GFDX:
1304                 val = 0;
1305                 break;
1306 
1307         default:
1308                 /*
1309                  * Shouldn't reach here...
1310                  */
1311                 cmn_err(CE_WARN,
1312                     "hxge_m_stat: unrecognized parameter value = 0x%x", stat);
1313                 return (ENOTSUP);
1314         }
1315         *value = val;
1316         return (0);
1317 }
1318 
1319 static uint64_t
1320 hxge_mac_octet_to_u64(uint8_t *addr)
1321 {
1322         int             i;
1323         uint64_t        addr64 = 0;
1324 
1325         for (i = ETHERADDRL - 1; i >= 0; i--) {
1326                 addr64 <<= 8;
1327                 addr64 |= addr[i];
1328         }
1329         return (addr64);
1330 }
1331 
1332 /*ARGSUSED*/
1333 static int
1334 hxge_mmac_stat_update(kstat_t *ksp, int rw)
1335 {
1336         p_hxge_t                hxgep;
1337         p_hxge_mmac_kstat_t     mmac_kstatsp;
1338 
1339         hxgep = (p_hxge_t)ksp->ks_private;
1340         if (hxgep == NULL)
1341                 return (-1);
1342 
1343         HXGE_DEBUG_MSG((hxgep, KST_CTL, "==> hxge_mmac_stat_update"));
1344 
1345         if (rw == KSTAT_WRITE) {
1346                 cmn_err(CE_WARN, "Can not write mmac stats");
1347         } else {
1348                 MUTEX_ENTER(hxgep->genlock);
1349                 mmac_kstatsp = (p_hxge_mmac_kstat_t)ksp->ks_data;
1350                 mmac_kstatsp->mmac_max_addr_cnt.value.ul = hxgep->mmac.total;
1351                 mmac_kstatsp->mmac_avail_addr_cnt.value.ul =
1352                     hxgep->mmac.available;
1353                 mmac_kstatsp->mmac_addr1.value.ul =
1354                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[0].addr);
1355                 mmac_kstatsp->mmac_addr2.value.ul =
1356                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[1].addr);
1357                 mmac_kstatsp->mmac_addr3.value.ul =
1358                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[2].addr);
1359                 mmac_kstatsp->mmac_addr4.value.ul =
1360                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[3].addr);
1361                 mmac_kstatsp->mmac_addr5.value.ul =
1362                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[4].addr);
1363                 mmac_kstatsp->mmac_addr6.value.ul =
1364                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[5].addr);
1365                 mmac_kstatsp->mmac_addr7.value.ul =
1366                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[6].addr);
1367                 mmac_kstatsp->mmac_addr8.value.ul =
1368                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[7].addr);
1369                 mmac_kstatsp->mmac_addr9.value.ul =
1370                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[8].addr);
1371                 mmac_kstatsp->mmac_addr10.value.ul =
1372                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[9].addr);
1373                 mmac_kstatsp->mmac_addr11.value.ul =
1374                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[10].addr);
1375                 mmac_kstatsp->mmac_addr12.value.ul =
1376                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[11].addr);
1377                 mmac_kstatsp->mmac_addr13.value.ul =
1378                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[12].addr);
1379                 mmac_kstatsp->mmac_addr14.value.ul =
1380                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[13].addr);
1381                 mmac_kstatsp->mmac_addr15.value.ul =
1382                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[14].addr);
1383                 mmac_kstatsp->mmac_addr16.value.ul =
1384                     hxge_mac_octet_to_u64(hxgep->mmac.addrs[15].addr);
1385                 MUTEX_EXIT(hxgep->genlock);
1386         }
1387 
1388         HXGE_DEBUG_MSG((hxgep, KST_CTL, "<== hxge_mmac_stat_update"));
1389         return (0);
1390 }