1*c869993eSxy /* 2*c869993eSxy * CDDL HEADER START 3*c869993eSxy * 4*c869993eSxy * Copyright(c) 2007-2008 Intel Corporation. All rights reserved. 5*c869993eSxy * The contents of this file are subject to the terms of the 6*c869993eSxy * Common Development and Distribution License (the "License"). 7*c869993eSxy * You may not use this file except in compliance with the License. 8*c869993eSxy * 9*c869993eSxy * You can obtain a copy of the license at: 10*c869993eSxy * http://www.opensolaris.org/os/licensing. 11*c869993eSxy * See the License for the specific language governing permissions 12*c869993eSxy * and limitations under the License. 13*c869993eSxy * 14*c869993eSxy * When using or redistributing this file, you may do so under the 15*c869993eSxy * License only. No other modification of this header is permitted. 16*c869993eSxy * 17*c869993eSxy * If applicable, add the following below this CDDL HEADER, with the 18*c869993eSxy * fields enclosed by brackets "[]" replaced with your own identifying 19*c869993eSxy * information: Portions Copyright [yyyy] [name of copyright owner] 20*c869993eSxy * 21*c869993eSxy * CDDL HEADER END 22*c869993eSxy */ 23*c869993eSxy 24*c869993eSxy /* 25*c869993eSxy * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 26*c869993eSxy * Use is subject to license terms of the CDDL. 27*c869993eSxy */ 28*c869993eSxy 29*c869993eSxy #pragma ident "%Z%%M% %I% %E% SMI" 30*c869993eSxy 31*c869993eSxy #include "igb_sw.h" 32*c869993eSxy 33*c869993eSxy /* 34*c869993eSxy * Update driver private statistics. 35*c869993eSxy */ 36*c869993eSxy static int 37*c869993eSxy igb_update_stats(kstat_t *ks, int rw) 38*c869993eSxy { 39*c869993eSxy igb_t *igb; 40*c869993eSxy struct e1000_hw *hw; 41*c869993eSxy igb_stat_t *igb_ks; 42*c869993eSxy uint32_t val_low, val_high; 43*c869993eSxy #ifdef IGB_DEBUG 44*c869993eSxy int i; 45*c869993eSxy #endif 46*c869993eSxy 47*c869993eSxy if (rw == KSTAT_WRITE) 48*c869993eSxy return (EACCES); 49*c869993eSxy 50*c869993eSxy igb = (igb_t *)ks->ks_private; 51*c869993eSxy igb_ks = (igb_stat_t *)ks->ks_data; 52*c869993eSxy hw = &igb->hw; 53*c869993eSxy 54*c869993eSxy mutex_enter(&igb->gen_lock); 55*c869993eSxy 56*c869993eSxy /* 57*c869993eSxy * Basic information. 58*c869993eSxy */ 59*c869993eSxy igb_ks->link_speed.value.ui64 = igb->link_speed; 60*c869993eSxy 61*c869993eSxy #ifdef IGB_DEBUG 62*c869993eSxy igb_ks->reset_count.value.ui64 = igb->reset_count; 63*c869993eSxy 64*c869993eSxy igb_ks->rx_frame_error.value.ui64 = 0; 65*c869993eSxy igb_ks->rx_cksum_error.value.ui64 = 0; 66*c869993eSxy igb_ks->rx_exceed_pkt.value.ui64 = 0; 67*c869993eSxy for (i = 0; i < igb->num_rx_rings; i++) { 68*c869993eSxy igb_ks->rx_frame_error.value.ui64 += 69*c869993eSxy igb->rx_rings[i].stat_frame_error; 70*c869993eSxy igb_ks->rx_cksum_error.value.ui64 += 71*c869993eSxy igb->rx_rings[i].stat_cksum_error; 72*c869993eSxy igb_ks->rx_exceed_pkt.value.ui64 += 73*c869993eSxy igb->rx_rings[i].stat_exceed_pkt; 74*c869993eSxy } 75*c869993eSxy 76*c869993eSxy igb_ks->tx_overload.value.ui64 = 0; 77*c869993eSxy igb_ks->tx_fail_no_tbd.value.ui64 = 0; 78*c869993eSxy igb_ks->tx_fail_no_tcb.value.ui64 = 0; 79*c869993eSxy igb_ks->tx_fail_dma_bind.value.ui64 = 0; 80*c869993eSxy igb_ks->tx_reschedule.value.ui64 = 0; 81*c869993eSxy for (i = 0; i < igb->num_tx_rings; i++) { 82*c869993eSxy igb_ks->tx_overload.value.ui64 += 83*c869993eSxy igb->tx_rings[i].stat_overload; 84*c869993eSxy igb_ks->tx_fail_no_tbd.value.ui64 += 85*c869993eSxy igb->tx_rings[i].stat_fail_no_tbd; 86*c869993eSxy igb_ks->tx_fail_no_tcb.value.ui64 += 87*c869993eSxy igb->tx_rings[i].stat_fail_no_tcb; 88*c869993eSxy igb_ks->tx_fail_dma_bind.value.ui64 += 89*c869993eSxy igb->tx_rings[i].stat_fail_dma_bind; 90*c869993eSxy igb_ks->tx_reschedule.value.ui64 += 91*c869993eSxy igb->tx_rings[i].stat_reschedule; 92*c869993eSxy } 93*c869993eSxy 94*c869993eSxy /* 95*c869993eSxy * Hardware calculated statistics. 96*c869993eSxy */ 97*c869993eSxy igb_ks->gprc.value.ul += E1000_READ_REG(hw, E1000_GPRC); 98*c869993eSxy igb_ks->gptc.value.ul += E1000_READ_REG(hw, E1000_GPTC); 99*c869993eSxy igb_ks->prc64.value.ul += E1000_READ_REG(hw, E1000_PRC64); 100*c869993eSxy igb_ks->prc127.value.ul += E1000_READ_REG(hw, E1000_PRC127); 101*c869993eSxy igb_ks->prc255.value.ul += E1000_READ_REG(hw, E1000_PRC255); 102*c869993eSxy igb_ks->prc511.value.ul += E1000_READ_REG(hw, E1000_PRC511); 103*c869993eSxy igb_ks->prc1023.value.ul += E1000_READ_REG(hw, E1000_PRC1023); 104*c869993eSxy igb_ks->prc1522.value.ul += E1000_READ_REG(hw, E1000_PRC1522); 105*c869993eSxy igb_ks->ptc64.value.ul += E1000_READ_REG(hw, E1000_PTC64); 106*c869993eSxy igb_ks->ptc127.value.ul += E1000_READ_REG(hw, E1000_PTC127); 107*c869993eSxy igb_ks->ptc255.value.ul += E1000_READ_REG(hw, E1000_PTC255); 108*c869993eSxy igb_ks->ptc511.value.ul += E1000_READ_REG(hw, E1000_PTC511); 109*c869993eSxy igb_ks->ptc1023.value.ul += E1000_READ_REG(hw, E1000_PTC1023); 110*c869993eSxy igb_ks->ptc1522.value.ul += E1000_READ_REG(hw, E1000_PTC1522); 111*c869993eSxy 112*c869993eSxy /* 113*c869993eSxy * The 64-bit register will reset whenever the upper 114*c869993eSxy * 32 bits are read. So we need to read the lower 115*c869993eSxy * 32 bits first, then read the upper 32 bits. 116*c869993eSxy */ 117*c869993eSxy val_low = E1000_READ_REG(hw, E1000_GORCL); 118*c869993eSxy val_high = E1000_READ_REG(hw, E1000_GORCH); 119*c869993eSxy igb_ks->gor.value.ui64 += (uint64_t)val_high << 32 | (uint64_t)val_low; 120*c869993eSxy 121*c869993eSxy val_low = E1000_READ_REG(hw, E1000_GOTCL); 122*c869993eSxy val_high = E1000_READ_REG(hw, E1000_GOTCH); 123*c869993eSxy igb_ks->got.value.ui64 += (uint64_t)val_high << 32 | (uint64_t)val_low; 124*c869993eSxy #endif 125*c869993eSxy 126*c869993eSxy igb_ks->symerrs.value.ui64 += E1000_READ_REG(hw, E1000_SYMERRS); 127*c869993eSxy igb_ks->mpc.value.ui64 += E1000_READ_REG(hw, E1000_MPC); 128*c869993eSxy igb_ks->rlec.value.ui64 += E1000_READ_REG(hw, E1000_RLEC); 129*c869993eSxy igb_ks->fcruc.value.ui64 += E1000_READ_REG(hw, E1000_FCRUC); 130*c869993eSxy igb_ks->rfc.value.ul += E1000_READ_REG(hw, E1000_RFC); 131*c869993eSxy igb_ks->tncrs.value.ul += E1000_READ_REG(hw, E1000_TNCRS); 132*c869993eSxy igb_ks->tsctc.value.ul += E1000_READ_REG(hw, E1000_TSCTC); 133*c869993eSxy igb_ks->tsctfc.value.ul += E1000_READ_REG(hw, E1000_TSCTFC); 134*c869993eSxy igb_ks->xonrxc.value.ui64 += E1000_READ_REG(hw, E1000_XONRXC); 135*c869993eSxy igb_ks->xontxc.value.ui64 += E1000_READ_REG(hw, E1000_XONTXC); 136*c869993eSxy igb_ks->xoffrxc.value.ui64 += E1000_READ_REG(hw, E1000_XOFFRXC); 137*c869993eSxy igb_ks->xofftxc.value.ui64 += E1000_READ_REG(hw, E1000_XOFFTXC); 138*c869993eSxy 139*c869993eSxy mutex_exit(&igb->gen_lock); 140*c869993eSxy 141*c869993eSxy return (0); 142*c869993eSxy } 143*c869993eSxy 144*c869993eSxy /* 145*c869993eSxy * Create and initialize the driver private statistics. 146*c869993eSxy */ 147*c869993eSxy int 148*c869993eSxy igb_init_stats(igb_t *igb) 149*c869993eSxy { 150*c869993eSxy kstat_t *ks; 151*c869993eSxy igb_stat_t *igb_ks; 152*c869993eSxy 153*c869993eSxy /* 154*c869993eSxy * Create and init kstat 155*c869993eSxy */ 156*c869993eSxy ks = kstat_create(MODULE_NAME, ddi_get_instance(igb->dip), 157*c869993eSxy "statistics", "net", KSTAT_TYPE_NAMED, 158*c869993eSxy sizeof (igb_stat_t) / sizeof (kstat_named_t), 0); 159*c869993eSxy 160*c869993eSxy if (ks == NULL) { 161*c869993eSxy igb_error(igb, 162*c869993eSxy "Could not create kernel statistics"); 163*c869993eSxy return (IGB_FAILURE); 164*c869993eSxy } 165*c869993eSxy 166*c869993eSxy igb->igb_ks = ks; 167*c869993eSxy 168*c869993eSxy igb_ks = (igb_stat_t *)ks->ks_data; 169*c869993eSxy 170*c869993eSxy /* 171*c869993eSxy * Initialize all the statistics. 172*c869993eSxy */ 173*c869993eSxy kstat_named_init(&igb_ks->link_speed, "link_speed", 174*c869993eSxy KSTAT_DATA_UINT64); 175*c869993eSxy 176*c869993eSxy #ifdef IGB_DEBUG 177*c869993eSxy kstat_named_init(&igb_ks->reset_count, "reset_count", 178*c869993eSxy KSTAT_DATA_UINT64); 179*c869993eSxy kstat_named_init(&igb_ks->rx_frame_error, "rx_frame_error", 180*c869993eSxy KSTAT_DATA_UINT64); 181*c869993eSxy kstat_named_init(&igb_ks->rx_cksum_error, "rx_cksum_error", 182*c869993eSxy KSTAT_DATA_UINT64); 183*c869993eSxy kstat_named_init(&igb_ks->rx_exceed_pkt, "rx_exceed_pkt", 184*c869993eSxy KSTAT_DATA_UINT64); 185*c869993eSxy kstat_named_init(&igb_ks->tx_overload, "tx_overload", 186*c869993eSxy KSTAT_DATA_UINT64); 187*c869993eSxy kstat_named_init(&igb_ks->tx_fail_no_tbd, "tx_fail_no_tbd", 188*c869993eSxy KSTAT_DATA_UINT64); 189*c869993eSxy kstat_named_init(&igb_ks->tx_fail_no_tcb, "tx_fail_no_tcb", 190*c869993eSxy KSTAT_DATA_UINT64); 191*c869993eSxy kstat_named_init(&igb_ks->tx_fail_dma_bind, "tx_fail_dma_bind", 192*c869993eSxy KSTAT_DATA_UINT64); 193*c869993eSxy kstat_named_init(&igb_ks->tx_reschedule, "tx_reschedule", 194*c869993eSxy KSTAT_DATA_UINT64); 195*c869993eSxy 196*c869993eSxy kstat_named_init(&igb_ks->gprc, "good_pkts_recvd", 197*c869993eSxy KSTAT_DATA_UINT64); 198*c869993eSxy kstat_named_init(&igb_ks->gptc, "good_pkts_xmitd", 199*c869993eSxy KSTAT_DATA_UINT64); 200*c869993eSxy kstat_named_init(&igb_ks->gor, "good_octets_recvd", 201*c869993eSxy KSTAT_DATA_UINT64); 202*c869993eSxy kstat_named_init(&igb_ks->got, "good_octets_xmitd", 203*c869993eSxy KSTAT_DATA_UINT64); 204*c869993eSxy kstat_named_init(&igb_ks->prc64, "pkts_recvd_( 64b)", 205*c869993eSxy KSTAT_DATA_UINT64); 206*c869993eSxy kstat_named_init(&igb_ks->prc127, "pkts_recvd_( 65- 127b)", 207*c869993eSxy KSTAT_DATA_UINT64); 208*c869993eSxy kstat_named_init(&igb_ks->prc255, "pkts_recvd_( 127- 255b)", 209*c869993eSxy KSTAT_DATA_UINT64); 210*c869993eSxy kstat_named_init(&igb_ks->prc511, "pkts_recvd_( 256- 511b)", 211*c869993eSxy KSTAT_DATA_UINT64); 212*c869993eSxy kstat_named_init(&igb_ks->prc1023, "pkts_recvd_( 511-1023b)", 213*c869993eSxy KSTAT_DATA_UINT64); 214*c869993eSxy kstat_named_init(&igb_ks->prc1522, "pkts_recvd_(1024-1522b)", 215*c869993eSxy KSTAT_DATA_UINT64); 216*c869993eSxy kstat_named_init(&igb_ks->ptc64, "pkts_xmitd_( 64b)", 217*c869993eSxy KSTAT_DATA_UINT64); 218*c869993eSxy kstat_named_init(&igb_ks->ptc127, "pkts_xmitd_( 65- 127b)", 219*c869993eSxy KSTAT_DATA_UINT64); 220*c869993eSxy kstat_named_init(&igb_ks->ptc255, "pkts_xmitd_( 128- 255b)", 221*c869993eSxy KSTAT_DATA_UINT64); 222*c869993eSxy kstat_named_init(&igb_ks->ptc511, "pkts_xmitd_( 255- 511b)", 223*c869993eSxy KSTAT_DATA_UINT64); 224*c869993eSxy kstat_named_init(&igb_ks->ptc1023, "pkts_xmitd_( 512-1023b)", 225*c869993eSxy KSTAT_DATA_UINT64); 226*c869993eSxy kstat_named_init(&igb_ks->ptc1522, "pkts_xmitd_(1024-1522b)", 227*c869993eSxy KSTAT_DATA_UINT64); 228*c869993eSxy #endif 229*c869993eSxy 230*c869993eSxy kstat_named_init(&igb_ks->symerrs, "recv_symbol_errors", 231*c869993eSxy KSTAT_DATA_UINT64); 232*c869993eSxy kstat_named_init(&igb_ks->mpc, "recv_missed_packets", 233*c869993eSxy KSTAT_DATA_UINT64); 234*c869993eSxy kstat_named_init(&igb_ks->rlec, "recv_length_errors", 235*c869993eSxy KSTAT_DATA_UINT64); 236*c869993eSxy kstat_named_init(&igb_ks->fcruc, "recv_unsupport_FC_pkts", 237*c869993eSxy KSTAT_DATA_UINT64); 238*c869993eSxy kstat_named_init(&igb_ks->rfc, "recv_frag", 239*c869993eSxy KSTAT_DATA_UINT64); 240*c869993eSxy kstat_named_init(&igb_ks->tncrs, "xmit_with_no_CRS", 241*c869993eSxy KSTAT_DATA_UINT64); 242*c869993eSxy kstat_named_init(&igb_ks->tsctc, "xmit_TCP_seg_contexts", 243*c869993eSxy KSTAT_DATA_UINT64); 244*c869993eSxy kstat_named_init(&igb_ks->tsctfc, "xmit_TCP_seg_contexts_fail", 245*c869993eSxy KSTAT_DATA_UINT64); 246*c869993eSxy kstat_named_init(&igb_ks->xonrxc, "XONs_recvd", 247*c869993eSxy KSTAT_DATA_UINT64); 248*c869993eSxy kstat_named_init(&igb_ks->xontxc, "XONs_xmitd", 249*c869993eSxy KSTAT_DATA_UINT64); 250*c869993eSxy kstat_named_init(&igb_ks->xoffrxc, "XOFFs_recvd", 251*c869993eSxy KSTAT_DATA_UINT64); 252*c869993eSxy kstat_named_init(&igb_ks->xofftxc, "XOFFs_xmitd", 253*c869993eSxy KSTAT_DATA_UINT64); 254*c869993eSxy 255*c869993eSxy /* 256*c869993eSxy * Function to provide kernel stat update on demand 257*c869993eSxy */ 258*c869993eSxy ks->ks_update = igb_update_stats; 259*c869993eSxy 260*c869993eSxy ks->ks_private = (void *)igb; 261*c869993eSxy 262*c869993eSxy /* 263*c869993eSxy * Add kstat to systems kstat chain 264*c869993eSxy */ 265*c869993eSxy kstat_install(ks); 266*c869993eSxy 267*c869993eSxy return (IGB_SUCCESS); 268*c869993eSxy } 269