15779Sxy150489 /* 25779Sxy150489 * CDDL HEADER START 35779Sxy150489 * 4*8955SChenlu.Chen@Sun.COM * Copyright(c) 2007-2009 Intel Corporation. All rights reserved. 55779Sxy150489 * The contents of this file are subject to the terms of the 65779Sxy150489 * Common Development and Distribution License (the "License"). 75779Sxy150489 * You may not use this file except in compliance with the License. 85779Sxy150489 * 95779Sxy150489 * You can obtain a copy of the license at: 105779Sxy150489 * http://www.opensolaris.org/os/licensing. 115779Sxy150489 * See the License for the specific language governing permissions 125779Sxy150489 * and limitations under the License. 135779Sxy150489 * 145779Sxy150489 * When using or redistributing this file, you may do so under the 155779Sxy150489 * License only. No other modification of this header is permitted. 165779Sxy150489 * 175779Sxy150489 * If applicable, add the following below this CDDL HEADER, with the 185779Sxy150489 * fields enclosed by brackets "[]" replaced with your own identifying 195779Sxy150489 * information: Portions Copyright [yyyy] [name of copyright owner] 205779Sxy150489 * 215779Sxy150489 * CDDL HEADER END 225779Sxy150489 */ 235779Sxy150489 245779Sxy150489 /* 25*8955SChenlu.Chen@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 265779Sxy150489 * Use is subject to license terms of the CDDL. 275779Sxy150489 */ 285779Sxy150489 295779Sxy150489 #include "igb_sw.h" 305779Sxy150489 315779Sxy150489 /* 325779Sxy150489 * Update driver private statistics. 335779Sxy150489 */ 345779Sxy150489 static int 355779Sxy150489 igb_update_stats(kstat_t *ks, int rw) 365779Sxy150489 { 375779Sxy150489 igb_t *igb; 385779Sxy150489 struct e1000_hw *hw; 395779Sxy150489 igb_stat_t *igb_ks; 405779Sxy150489 uint32_t val_low, val_high; 415779Sxy150489 #ifdef IGB_DEBUG 425779Sxy150489 int i; 435779Sxy150489 #endif 445779Sxy150489 455779Sxy150489 if (rw == KSTAT_WRITE) 465779Sxy150489 return (EACCES); 475779Sxy150489 485779Sxy150489 igb = (igb_t *)ks->ks_private; 495779Sxy150489 igb_ks = (igb_stat_t *)ks->ks_data; 505779Sxy150489 hw = &igb->hw; 515779Sxy150489 525779Sxy150489 mutex_enter(&igb->gen_lock); 535779Sxy150489 545779Sxy150489 /* 555779Sxy150489 * Basic information. 565779Sxy150489 */ 575779Sxy150489 igb_ks->link_speed.value.ui64 = igb->link_speed; 58*8955SChenlu.Chen@Sun.COM igb_ks->reset_count.value.ui64 = igb->reset_count; 59*8955SChenlu.Chen@Sun.COM igb_ks->dout_sync.value.ui64 = igb->dout_sync; 605779Sxy150489 615779Sxy150489 #ifdef IGB_DEBUG 625779Sxy150489 igb_ks->rx_frame_error.value.ui64 = 0; 635779Sxy150489 igb_ks->rx_cksum_error.value.ui64 = 0; 645779Sxy150489 igb_ks->rx_exceed_pkt.value.ui64 = 0; 655779Sxy150489 for (i = 0; i < igb->num_rx_rings; i++) { 665779Sxy150489 igb_ks->rx_frame_error.value.ui64 += 675779Sxy150489 igb->rx_rings[i].stat_frame_error; 685779Sxy150489 igb_ks->rx_cksum_error.value.ui64 += 695779Sxy150489 igb->rx_rings[i].stat_cksum_error; 705779Sxy150489 igb_ks->rx_exceed_pkt.value.ui64 += 715779Sxy150489 igb->rx_rings[i].stat_exceed_pkt; 725779Sxy150489 } 735779Sxy150489 745779Sxy150489 igb_ks->tx_overload.value.ui64 = 0; 755779Sxy150489 igb_ks->tx_fail_no_tbd.value.ui64 = 0; 765779Sxy150489 igb_ks->tx_fail_no_tcb.value.ui64 = 0; 775779Sxy150489 igb_ks->tx_fail_dma_bind.value.ui64 = 0; 785779Sxy150489 igb_ks->tx_reschedule.value.ui64 = 0; 795779Sxy150489 for (i = 0; i < igb->num_tx_rings; i++) { 805779Sxy150489 igb_ks->tx_overload.value.ui64 += 815779Sxy150489 igb->tx_rings[i].stat_overload; 825779Sxy150489 igb_ks->tx_fail_no_tbd.value.ui64 += 835779Sxy150489 igb->tx_rings[i].stat_fail_no_tbd; 845779Sxy150489 igb_ks->tx_fail_no_tcb.value.ui64 += 855779Sxy150489 igb->tx_rings[i].stat_fail_no_tcb; 865779Sxy150489 igb_ks->tx_fail_dma_bind.value.ui64 += 875779Sxy150489 igb->tx_rings[i].stat_fail_dma_bind; 885779Sxy150489 igb_ks->tx_reschedule.value.ui64 += 895779Sxy150489 igb->tx_rings[i].stat_reschedule; 905779Sxy150489 } 915779Sxy150489 925779Sxy150489 /* 935779Sxy150489 * Hardware calculated statistics. 945779Sxy150489 */ 955779Sxy150489 igb_ks->gprc.value.ul += E1000_READ_REG(hw, E1000_GPRC); 965779Sxy150489 igb_ks->gptc.value.ul += E1000_READ_REG(hw, E1000_GPTC); 975779Sxy150489 igb_ks->prc64.value.ul += E1000_READ_REG(hw, E1000_PRC64); 985779Sxy150489 igb_ks->prc127.value.ul += E1000_READ_REG(hw, E1000_PRC127); 995779Sxy150489 igb_ks->prc255.value.ul += E1000_READ_REG(hw, E1000_PRC255); 1005779Sxy150489 igb_ks->prc511.value.ul += E1000_READ_REG(hw, E1000_PRC511); 1015779Sxy150489 igb_ks->prc1023.value.ul += E1000_READ_REG(hw, E1000_PRC1023); 1025779Sxy150489 igb_ks->prc1522.value.ul += E1000_READ_REG(hw, E1000_PRC1522); 1035779Sxy150489 igb_ks->ptc64.value.ul += E1000_READ_REG(hw, E1000_PTC64); 1045779Sxy150489 igb_ks->ptc127.value.ul += E1000_READ_REG(hw, E1000_PTC127); 1055779Sxy150489 igb_ks->ptc255.value.ul += E1000_READ_REG(hw, E1000_PTC255); 1065779Sxy150489 igb_ks->ptc511.value.ul += E1000_READ_REG(hw, E1000_PTC511); 1075779Sxy150489 igb_ks->ptc1023.value.ul += E1000_READ_REG(hw, E1000_PTC1023); 1085779Sxy150489 igb_ks->ptc1522.value.ul += E1000_READ_REG(hw, E1000_PTC1522); 1095779Sxy150489 1105779Sxy150489 /* 1115779Sxy150489 * The 64-bit register will reset whenever the upper 1125779Sxy150489 * 32 bits are read. So we need to read the lower 1135779Sxy150489 * 32 bits first, then read the upper 32 bits. 1145779Sxy150489 */ 1155779Sxy150489 val_low = E1000_READ_REG(hw, E1000_GORCL); 1165779Sxy150489 val_high = E1000_READ_REG(hw, E1000_GORCH); 1175779Sxy150489 igb_ks->gor.value.ui64 += (uint64_t)val_high << 32 | (uint64_t)val_low; 1185779Sxy150489 1195779Sxy150489 val_low = E1000_READ_REG(hw, E1000_GOTCL); 1205779Sxy150489 val_high = E1000_READ_REG(hw, E1000_GOTCH); 1215779Sxy150489 igb_ks->got.value.ui64 += (uint64_t)val_high << 32 | (uint64_t)val_low; 1225779Sxy150489 #endif 1235779Sxy150489 1245779Sxy150489 igb_ks->symerrs.value.ui64 += E1000_READ_REG(hw, E1000_SYMERRS); 1255779Sxy150489 igb_ks->mpc.value.ui64 += E1000_READ_REG(hw, E1000_MPC); 1265779Sxy150489 igb_ks->rlec.value.ui64 += E1000_READ_REG(hw, E1000_RLEC); 1275779Sxy150489 igb_ks->fcruc.value.ui64 += E1000_READ_REG(hw, E1000_FCRUC); 1285779Sxy150489 igb_ks->rfc.value.ul += E1000_READ_REG(hw, E1000_RFC); 1295779Sxy150489 igb_ks->tncrs.value.ul += E1000_READ_REG(hw, E1000_TNCRS); 1305779Sxy150489 igb_ks->tsctc.value.ul += E1000_READ_REG(hw, E1000_TSCTC); 1315779Sxy150489 igb_ks->tsctfc.value.ul += E1000_READ_REG(hw, E1000_TSCTFC); 1325779Sxy150489 igb_ks->xonrxc.value.ui64 += E1000_READ_REG(hw, E1000_XONRXC); 1335779Sxy150489 igb_ks->xontxc.value.ui64 += E1000_READ_REG(hw, E1000_XONTXC); 1345779Sxy150489 igb_ks->xoffrxc.value.ui64 += E1000_READ_REG(hw, E1000_XOFFRXC); 1355779Sxy150489 igb_ks->xofftxc.value.ui64 += E1000_READ_REG(hw, E1000_XOFFTXC); 1365779Sxy150489 1375779Sxy150489 mutex_exit(&igb->gen_lock); 1385779Sxy150489 1396624Sgl147354 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) 1406624Sgl147354 ddi_fm_service_impact(igb->dip, DDI_SERVICE_UNAFFECTED); 1416624Sgl147354 1425779Sxy150489 return (0); 1435779Sxy150489 } 1445779Sxy150489 1455779Sxy150489 /* 1465779Sxy150489 * Create and initialize the driver private statistics. 1475779Sxy150489 */ 1485779Sxy150489 int 1495779Sxy150489 igb_init_stats(igb_t *igb) 1505779Sxy150489 { 1515779Sxy150489 kstat_t *ks; 1525779Sxy150489 igb_stat_t *igb_ks; 1535779Sxy150489 1545779Sxy150489 /* 1555779Sxy150489 * Create and init kstat 1565779Sxy150489 */ 1575779Sxy150489 ks = kstat_create(MODULE_NAME, ddi_get_instance(igb->dip), 1585779Sxy150489 "statistics", "net", KSTAT_TYPE_NAMED, 1595779Sxy150489 sizeof (igb_stat_t) / sizeof (kstat_named_t), 0); 1605779Sxy150489 1615779Sxy150489 if (ks == NULL) { 1625779Sxy150489 igb_error(igb, 1635779Sxy150489 "Could not create kernel statistics"); 1645779Sxy150489 return (IGB_FAILURE); 1655779Sxy150489 } 1665779Sxy150489 1675779Sxy150489 igb->igb_ks = ks; 1685779Sxy150489 1695779Sxy150489 igb_ks = (igb_stat_t *)ks->ks_data; 1705779Sxy150489 1715779Sxy150489 /* 1725779Sxy150489 * Initialize all the statistics. 1735779Sxy150489 */ 1745779Sxy150489 kstat_named_init(&igb_ks->link_speed, "link_speed", 1755779Sxy150489 KSTAT_DATA_UINT64); 176*8955SChenlu.Chen@Sun.COM kstat_named_init(&igb_ks->reset_count, "reset_count", 177*8955SChenlu.Chen@Sun.COM KSTAT_DATA_UINT64); 178*8955SChenlu.Chen@Sun.COM kstat_named_init(&igb_ks->dout_sync, "DMA_out_sync", 179*8955SChenlu.Chen@Sun.COM KSTAT_DATA_UINT64); 1805779Sxy150489 1815779Sxy150489 #ifdef IGB_DEBUG 1825779Sxy150489 kstat_named_init(&igb_ks->rx_frame_error, "rx_frame_error", 1835779Sxy150489 KSTAT_DATA_UINT64); 1845779Sxy150489 kstat_named_init(&igb_ks->rx_cksum_error, "rx_cksum_error", 1855779Sxy150489 KSTAT_DATA_UINT64); 1865779Sxy150489 kstat_named_init(&igb_ks->rx_exceed_pkt, "rx_exceed_pkt", 1875779Sxy150489 KSTAT_DATA_UINT64); 1885779Sxy150489 kstat_named_init(&igb_ks->tx_overload, "tx_overload", 1895779Sxy150489 KSTAT_DATA_UINT64); 1905779Sxy150489 kstat_named_init(&igb_ks->tx_fail_no_tbd, "tx_fail_no_tbd", 1915779Sxy150489 KSTAT_DATA_UINT64); 1925779Sxy150489 kstat_named_init(&igb_ks->tx_fail_no_tcb, "tx_fail_no_tcb", 1935779Sxy150489 KSTAT_DATA_UINT64); 1945779Sxy150489 kstat_named_init(&igb_ks->tx_fail_dma_bind, "tx_fail_dma_bind", 1955779Sxy150489 KSTAT_DATA_UINT64); 1965779Sxy150489 kstat_named_init(&igb_ks->tx_reschedule, "tx_reschedule", 1975779Sxy150489 KSTAT_DATA_UINT64); 1985779Sxy150489 1995779Sxy150489 kstat_named_init(&igb_ks->gprc, "good_pkts_recvd", 2005779Sxy150489 KSTAT_DATA_UINT64); 2015779Sxy150489 kstat_named_init(&igb_ks->gptc, "good_pkts_xmitd", 2025779Sxy150489 KSTAT_DATA_UINT64); 2035779Sxy150489 kstat_named_init(&igb_ks->gor, "good_octets_recvd", 2045779Sxy150489 KSTAT_DATA_UINT64); 2055779Sxy150489 kstat_named_init(&igb_ks->got, "good_octets_xmitd", 2065779Sxy150489 KSTAT_DATA_UINT64); 2075779Sxy150489 kstat_named_init(&igb_ks->prc64, "pkts_recvd_( 64b)", 2085779Sxy150489 KSTAT_DATA_UINT64); 2095779Sxy150489 kstat_named_init(&igb_ks->prc127, "pkts_recvd_( 65- 127b)", 2105779Sxy150489 KSTAT_DATA_UINT64); 2115779Sxy150489 kstat_named_init(&igb_ks->prc255, "pkts_recvd_( 127- 255b)", 2125779Sxy150489 KSTAT_DATA_UINT64); 2135779Sxy150489 kstat_named_init(&igb_ks->prc511, "pkts_recvd_( 256- 511b)", 2145779Sxy150489 KSTAT_DATA_UINT64); 2155779Sxy150489 kstat_named_init(&igb_ks->prc1023, "pkts_recvd_( 511-1023b)", 2165779Sxy150489 KSTAT_DATA_UINT64); 2175779Sxy150489 kstat_named_init(&igb_ks->prc1522, "pkts_recvd_(1024-1522b)", 2185779Sxy150489 KSTAT_DATA_UINT64); 2195779Sxy150489 kstat_named_init(&igb_ks->ptc64, "pkts_xmitd_( 64b)", 2205779Sxy150489 KSTAT_DATA_UINT64); 2215779Sxy150489 kstat_named_init(&igb_ks->ptc127, "pkts_xmitd_( 65- 127b)", 2225779Sxy150489 KSTAT_DATA_UINT64); 2235779Sxy150489 kstat_named_init(&igb_ks->ptc255, "pkts_xmitd_( 128- 255b)", 2245779Sxy150489 KSTAT_DATA_UINT64); 2255779Sxy150489 kstat_named_init(&igb_ks->ptc511, "pkts_xmitd_( 255- 511b)", 2265779Sxy150489 KSTAT_DATA_UINT64); 2275779Sxy150489 kstat_named_init(&igb_ks->ptc1023, "pkts_xmitd_( 512-1023b)", 2285779Sxy150489 KSTAT_DATA_UINT64); 2295779Sxy150489 kstat_named_init(&igb_ks->ptc1522, "pkts_xmitd_(1024-1522b)", 2305779Sxy150489 KSTAT_DATA_UINT64); 2315779Sxy150489 #endif 2325779Sxy150489 2335779Sxy150489 kstat_named_init(&igb_ks->symerrs, "recv_symbol_errors", 2345779Sxy150489 KSTAT_DATA_UINT64); 2355779Sxy150489 kstat_named_init(&igb_ks->mpc, "recv_missed_packets", 2365779Sxy150489 KSTAT_DATA_UINT64); 2375779Sxy150489 kstat_named_init(&igb_ks->rlec, "recv_length_errors", 2385779Sxy150489 KSTAT_DATA_UINT64); 2395779Sxy150489 kstat_named_init(&igb_ks->fcruc, "recv_unsupport_FC_pkts", 2405779Sxy150489 KSTAT_DATA_UINT64); 2415779Sxy150489 kstat_named_init(&igb_ks->rfc, "recv_frag", 2425779Sxy150489 KSTAT_DATA_UINT64); 2435779Sxy150489 kstat_named_init(&igb_ks->tncrs, "xmit_with_no_CRS", 2445779Sxy150489 KSTAT_DATA_UINT64); 2455779Sxy150489 kstat_named_init(&igb_ks->tsctc, "xmit_TCP_seg_contexts", 2465779Sxy150489 KSTAT_DATA_UINT64); 2475779Sxy150489 kstat_named_init(&igb_ks->tsctfc, "xmit_TCP_seg_contexts_fail", 2485779Sxy150489 KSTAT_DATA_UINT64); 2495779Sxy150489 kstat_named_init(&igb_ks->xonrxc, "XONs_recvd", 2505779Sxy150489 KSTAT_DATA_UINT64); 2515779Sxy150489 kstat_named_init(&igb_ks->xontxc, "XONs_xmitd", 2525779Sxy150489 KSTAT_DATA_UINT64); 2535779Sxy150489 kstat_named_init(&igb_ks->xoffrxc, "XOFFs_recvd", 2545779Sxy150489 KSTAT_DATA_UINT64); 2555779Sxy150489 kstat_named_init(&igb_ks->xofftxc, "XOFFs_xmitd", 2565779Sxy150489 KSTAT_DATA_UINT64); 2575779Sxy150489 2585779Sxy150489 /* 2595779Sxy150489 * Function to provide kernel stat update on demand 2605779Sxy150489 */ 2615779Sxy150489 ks->ks_update = igb_update_stats; 2625779Sxy150489 2635779Sxy150489 ks->ks_private = (void *)igb; 2645779Sxy150489 2655779Sxy150489 /* 2665779Sxy150489 * Add kstat to systems kstat chain 2675779Sxy150489 */ 2685779Sxy150489 kstat_install(ks); 2695779Sxy150489 2705779Sxy150489 return (IGB_SUCCESS); 2715779Sxy150489 } 272