108057504Sxy150489 /* 208057504Sxy150489 * This file is provided under a CDDLv1 license. When using or 308057504Sxy150489 * redistributing this file, you may do so under this license. 408057504Sxy150489 * In redistributing this file this license must be included 508057504Sxy150489 * and no other modification of this header file is permitted. 608057504Sxy150489 * 708057504Sxy150489 * CDDL LICENSE SUMMARY 808057504Sxy150489 * 9d5c3073dSchenlu chen - Sun Microsystems - Beijing China * Copyright(c) 1999 - 2009 Intel Corporation. All rights reserved. 1008057504Sxy150489 * 1108057504Sxy150489 * The contents of this file are subject to the terms of Version 1208057504Sxy150489 * 1.0 of the Common Development and Distribution License (the "License"). 1308057504Sxy150489 * 1408057504Sxy150489 * You should have received a copy of the License with this software. 1508057504Sxy150489 * You can obtain a copy of the License at 1608057504Sxy150489 * http://www.opensolaris.org/os/licensing. 1708057504Sxy150489 * See the License for the specific language governing permissions 1808057504Sxy150489 * and limitations under the License. 1908057504Sxy150489 */ 2008057504Sxy150489 2108057504Sxy150489 /* 220dc2366fSVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23*29fd2c16SDavid Höppner * Copyright 2012 David Höppner. All rights reserved. 24da14cebeSEric Cheng * Use is subject to license terms. 2508057504Sxy150489 */ 2608057504Sxy150489 2708057504Sxy150489 /* 2808057504Sxy150489 * ********************************************************************** 2908057504Sxy150489 * * 3008057504Sxy150489 * Module Name: e1000g_stat.c * 3108057504Sxy150489 * * 3225f2d433Sxy150489 * Abstract: Functions for processing statistics * 3308057504Sxy150489 * * 3408057504Sxy150489 * ********************************************************************** 3508057504Sxy150489 */ 3608057504Sxy150489 #include "e1000g_sw.h" 3708057504Sxy150489 #include "e1000g_debug.h" 3808057504Sxy150489 3925f2d433Sxy150489 static int e1000g_update_stats(kstat_t *ksp, int rw); 40caf05df5SMiles Xu, Sun Microsystems static uint32_t e1000g_read_phy_stat(struct e1000_hw *hw, int reg); 4108057504Sxy150489 4208057504Sxy150489 /* 4325f2d433Sxy150489 * e1000_tbi_adjust_stats 4425f2d433Sxy150489 * 4525f2d433Sxy150489 * Adjusts statistic counters when a frame is accepted 4625f2d433Sxy150489 * under the TBI workaround. This function has been 4725f2d433Sxy150489 * adapted for Solaris from shared code. 4808057504Sxy150489 */ 4908057504Sxy150489 void 5025f2d433Sxy150489 e1000_tbi_adjust_stats(struct e1000g *Adapter, 5125f2d433Sxy150489 uint32_t frame_len, uint8_t *mac_addr) 5208057504Sxy150489 { 5325f2d433Sxy150489 uint32_t carry_bit; 5425f2d433Sxy150489 p_e1000g_stat_t e1000g_ksp; 5508057504Sxy150489 5625f2d433Sxy150489 e1000g_ksp = (p_e1000g_stat_t)Adapter->e1000g_ksp->ks_data; 5708057504Sxy150489 5825f2d433Sxy150489 /* First adjust the frame length */ 5925f2d433Sxy150489 frame_len--; 6025f2d433Sxy150489 6108057504Sxy150489 /* 6208057504Sxy150489 * We need to adjust the statistics counters, since the hardware 6308057504Sxy150489 * counters overcount this packet as a CRC error and undercount 6408057504Sxy150489 * the packet as a good packet 6508057504Sxy150489 */ 6625f2d433Sxy150489 /* This packet should not be counted as a CRC error */ 67*29fd2c16SDavid Höppner Adapter->fcs_errors--; 6825f2d433Sxy150489 /* This packet does count as a Good Packet Received */ 6908057504Sxy150489 e1000g_ksp->Gprc.value.ul++; 7008057504Sxy150489 7108057504Sxy150489 /* 7208057504Sxy150489 * Adjust the Good Octets received counters 7308057504Sxy150489 */ 7425f2d433Sxy150489 carry_bit = 0x80000000 & e1000g_ksp->Gorl.value.ul; 7525f2d433Sxy150489 e1000g_ksp->Gorl.value.ul += frame_len; 7608057504Sxy150489 /* 7708057504Sxy150489 * If the high bit of Gorcl (the low 32 bits of the Good Octets 7808057504Sxy150489 * Received Count) was one before the addition, 7908057504Sxy150489 * AND it is zero after, then we lost the carry out, 8008057504Sxy150489 * need to add one to Gorch (Good Octets Received Count High). 8108057504Sxy150489 * This could be simplified if all environments supported 8208057504Sxy150489 * 64-bit integers. 8308057504Sxy150489 */ 8425f2d433Sxy150489 if (carry_bit && ((e1000g_ksp->Gorl.value.ul & 0x80000000) == 0)) { 8508057504Sxy150489 e1000g_ksp->Gorh.value.ul++; 8608057504Sxy150489 } 8708057504Sxy150489 /* 8808057504Sxy150489 * Is this a broadcast or multicast? Check broadcast first, 8908057504Sxy150489 * since the test for a multicast frame will test positive on 9008057504Sxy150489 * a broadcast frame. 9108057504Sxy150489 */ 9225f2d433Sxy150489 if ((mac_addr[0] == (uint8_t)0xff) && 9325f2d433Sxy150489 (mac_addr[1] == (uint8_t)0xff)) { 9408057504Sxy150489 /* 9508057504Sxy150489 * Broadcast packet 9608057504Sxy150489 */ 97*29fd2c16SDavid Höppner Adapter->brdcstrcv++; 9825f2d433Sxy150489 } else if (*mac_addr & 0x01) { 9908057504Sxy150489 /* 10008057504Sxy150489 * Multicast packet 10108057504Sxy150489 */ 102*29fd2c16SDavid Höppner Adapter->multircv++; 10308057504Sxy150489 } 10425f2d433Sxy150489 105592a4d85Scc210113 if (frame_len == Adapter->max_frame_size) { 10608057504Sxy150489 /* 10708057504Sxy150489 * In this case, the hardware has overcounted the number of 10808057504Sxy150489 * oversize frames. 10908057504Sxy150489 */ 110*29fd2c16SDavid Höppner if (Adapter->toolong_errors > 0) 111*29fd2c16SDavid Höppner Adapter->toolong_errors--; 11208057504Sxy150489 } 11308057504Sxy150489 11447b7744cSyy150190 #ifdef E1000G_DEBUG 11508057504Sxy150489 /* 11608057504Sxy150489 * Adjust the bin counters when the extra byte put the frame in the 11725f2d433Sxy150489 * wrong bin. Remember that the frame_len was adjusted above. 11808057504Sxy150489 */ 11925f2d433Sxy150489 if (frame_len == 64) { 12008057504Sxy150489 e1000g_ksp->Prc64.value.ul++; 12108057504Sxy150489 e1000g_ksp->Prc127.value.ul--; 12225f2d433Sxy150489 } else if (frame_len == 127) { 12308057504Sxy150489 e1000g_ksp->Prc127.value.ul++; 12408057504Sxy150489 e1000g_ksp->Prc255.value.ul--; 12525f2d433Sxy150489 } else if (frame_len == 255) { 12608057504Sxy150489 e1000g_ksp->Prc255.value.ul++; 12708057504Sxy150489 e1000g_ksp->Prc511.value.ul--; 12825f2d433Sxy150489 } else if (frame_len == 511) { 12908057504Sxy150489 e1000g_ksp->Prc511.value.ul++; 13008057504Sxy150489 e1000g_ksp->Prc1023.value.ul--; 13125f2d433Sxy150489 } else if (frame_len == 1023) { 13208057504Sxy150489 e1000g_ksp->Prc1023.value.ul++; 13308057504Sxy150489 e1000g_ksp->Prc1522.value.ul--; 13425f2d433Sxy150489 } else if (frame_len == 1522) { 13508057504Sxy150489 e1000g_ksp->Prc1522.value.ul++; 13608057504Sxy150489 } 13747b7744cSyy150190 #endif 13808057504Sxy150489 } 13908057504Sxy150489 14008057504Sxy150489 14108057504Sxy150489 /* 14225f2d433Sxy150489 * e1000g_update_stats - update driver private kstat counters 14325f2d433Sxy150489 * 14425f2d433Sxy150489 * This routine will dump and reset the e1000's internal 14525f2d433Sxy150489 * statistics counters. The current stats dump values will 14625f2d433Sxy150489 * be sent to the kernel status area. 14708057504Sxy150489 */ 14808057504Sxy150489 static int 14925f2d433Sxy150489 e1000g_update_stats(kstat_t *ksp, int rw) 15008057504Sxy150489 { 15108057504Sxy150489 struct e1000g *Adapter; 15225f2d433Sxy150489 struct e1000_hw *hw; 15325f2d433Sxy150489 p_e1000g_stat_t e1000g_ksp; 15425f2d433Sxy150489 e1000g_tx_ring_t *tx_ring; 15525f2d433Sxy150489 e1000g_rx_ring_t *rx_ring; 15657ef6f69Sguoqing zhu - Sun Microsystems - Beijing China #ifdef E1000G_DEBUG 15754e0d7a5SMiles Xu, Sun Microsystems e1000g_rx_data_t *rx_data; 15857ef6f69Sguoqing zhu - Sun Microsystems - Beijing China #endif 15908057504Sxy150489 uint64_t val; 16008057504Sxy150489 uint32_t low_val, high_val; 16108057504Sxy150489 16208057504Sxy150489 if (rw == KSTAT_WRITE) 16308057504Sxy150489 return (EACCES); 16408057504Sxy150489 16508057504Sxy150489 Adapter = (struct e1000g *)ksp->ks_private; 16608057504Sxy150489 ASSERT(Adapter != NULL); 16725f2d433Sxy150489 e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data; 16808057504Sxy150489 ASSERT(e1000g_ksp != NULL); 16925f2d433Sxy150489 hw = &Adapter->shared; 17025f2d433Sxy150489 17125f2d433Sxy150489 tx_ring = Adapter->tx_ring; 17225f2d433Sxy150489 rx_ring = Adapter->rx_ring; 17357ef6f69Sguoqing zhu - Sun Microsystems - Beijing China #ifdef E1000G_DEBUG 17454e0d7a5SMiles Xu, Sun Microsystems rx_data = rx_ring->rx_data; 17557ef6f69Sguoqing zhu - Sun Microsystems - Beijing China #endif 17625f2d433Sxy150489 17725f2d433Sxy150489 rw_enter(&Adapter->chip_lock, RW_WRITER); 17808057504Sxy150489 17908057504Sxy150489 e1000g_ksp->reset_count.value.ul = Adapter->reset_count; 18008057504Sxy150489 18125f2d433Sxy150489 e1000g_ksp->rx_error.value.ul = rx_ring->stat_error; 18225f2d433Sxy150489 e1000g_ksp->rx_allocb_fail.value.ul = rx_ring->stat_allocb_fail; 18346ebaa55SMiles Xu, Sun Microsystems e1000g_ksp->rx_size_error.value.ul = rx_ring->stat_size_error; 18425f2d433Sxy150489 18525f2d433Sxy150489 e1000g_ksp->tx_no_swpkt.value.ul = tx_ring->stat_no_swpkt; 18625f2d433Sxy150489 e1000g_ksp->tx_no_desc.value.ul = tx_ring->stat_no_desc; 18725f2d433Sxy150489 e1000g_ksp->tx_send_fail.value.ul = tx_ring->stat_send_fail; 18825f2d433Sxy150489 e1000g_ksp->tx_reschedule.value.ul = tx_ring->stat_reschedule; 18925f2d433Sxy150489 e1000g_ksp->tx_over_size.value.ul = tx_ring->stat_over_size; 19025f2d433Sxy150489 19125f2d433Sxy150489 #ifdef E1000G_DEBUG 19225f2d433Sxy150489 e1000g_ksp->rx_none.value.ul = rx_ring->stat_none; 19325f2d433Sxy150489 e1000g_ksp->rx_multi_desc.value.ul = rx_ring->stat_multi_desc; 19425f2d433Sxy150489 e1000g_ksp->rx_no_freepkt.value.ul = rx_ring->stat_no_freepkt; 19554e0d7a5SMiles Xu, Sun Microsystems if (rx_data != NULL) 19654e0d7a5SMiles Xu, Sun Microsystems e1000g_ksp->rx_avail_freepkt.value.ul = rx_data->avail_freepkt; 19725f2d433Sxy150489 19825f2d433Sxy150489 e1000g_ksp->tx_under_size.value.ul = tx_ring->stat_under_size; 19925f2d433Sxy150489 e1000g_ksp->tx_exceed_frags.value.ul = tx_ring->stat_exceed_frags; 20025f2d433Sxy150489 e1000g_ksp->tx_empty_frags.value.ul = tx_ring->stat_empty_frags; 20125f2d433Sxy150489 e1000g_ksp->tx_recycle.value.ul = tx_ring->stat_recycle; 20225f2d433Sxy150489 e1000g_ksp->tx_recycle_intr.value.ul = tx_ring->stat_recycle_intr; 20325f2d433Sxy150489 e1000g_ksp->tx_recycle_retry.value.ul = tx_ring->stat_recycle_retry; 20425f2d433Sxy150489 e1000g_ksp->tx_recycle_none.value.ul = tx_ring->stat_recycle_none; 20525f2d433Sxy150489 e1000g_ksp->tx_copy.value.ul = tx_ring->stat_copy; 20625f2d433Sxy150489 e1000g_ksp->tx_bind.value.ul = tx_ring->stat_bind; 20725f2d433Sxy150489 e1000g_ksp->tx_multi_copy.value.ul = tx_ring->stat_multi_copy; 20825f2d433Sxy150489 e1000g_ksp->tx_multi_cookie.value.ul = tx_ring->stat_multi_cookie; 20925f2d433Sxy150489 e1000g_ksp->tx_lack_desc.value.ul = tx_ring->stat_lack_desc; 21025f2d433Sxy150489 #endif 21108057504Sxy150489 21208057504Sxy150489 /* 21308057504Sxy150489 * Standard Stats 21408057504Sxy150489 */ 21525f2d433Sxy150489 e1000g_ksp->Mpc.value.ul += E1000_READ_REG(hw, E1000_MPC); 21625f2d433Sxy150489 e1000g_ksp->Rlec.value.ul += E1000_READ_REG(hw, E1000_RLEC); 21725f2d433Sxy150489 e1000g_ksp->Xonrxc.value.ul += E1000_READ_REG(hw, E1000_XONRXC); 21825f2d433Sxy150489 e1000g_ksp->Xontxc.value.ul += E1000_READ_REG(hw, E1000_XONTXC); 21925f2d433Sxy150489 e1000g_ksp->Xoffrxc.value.ul += E1000_READ_REG(hw, E1000_XOFFRXC); 22025f2d433Sxy150489 e1000g_ksp->Xofftxc.value.ul += E1000_READ_REG(hw, E1000_XOFFTXC); 22125f2d433Sxy150489 e1000g_ksp->Fcruc.value.ul += E1000_READ_REG(hw, E1000_FCRUC); 22208057504Sxy150489 22325f2d433Sxy150489 if ((hw->mac.type != e1000_ich8lan) && 2244d737963Sxiangtao you - Sun Microsystems - Beijing China (hw->mac.type != e1000_ich9lan) && 225caf05df5SMiles Xu, Sun Microsystems (hw->mac.type != e1000_ich10lan) && 226caf05df5SMiles Xu, Sun Microsystems (hw->mac.type != e1000_pchlan)) { 22708057504Sxy150489 e1000g_ksp->Symerrs.value.ul += 22825f2d433Sxy150489 E1000_READ_REG(hw, E1000_SYMERRS); 22947b7744cSyy150190 #ifdef E1000G_DEBUG 23008057504Sxy150489 e1000g_ksp->Prc64.value.ul += 23125f2d433Sxy150489 E1000_READ_REG(hw, E1000_PRC64); 23208057504Sxy150489 e1000g_ksp->Prc127.value.ul += 23325f2d433Sxy150489 E1000_READ_REG(hw, E1000_PRC127); 23408057504Sxy150489 e1000g_ksp->Prc255.value.ul += 23525f2d433Sxy150489 E1000_READ_REG(hw, E1000_PRC255); 23608057504Sxy150489 e1000g_ksp->Prc511.value.ul += 23725f2d433Sxy150489 E1000_READ_REG(hw, E1000_PRC511); 23808057504Sxy150489 e1000g_ksp->Prc1023.value.ul += 23925f2d433Sxy150489 E1000_READ_REG(hw, E1000_PRC1023); 24008057504Sxy150489 e1000g_ksp->Prc1522.value.ul += 24125f2d433Sxy150489 E1000_READ_REG(hw, E1000_PRC1522); 24208057504Sxy150489 24325f2d433Sxy150489 e1000g_ksp->Ptc64.value.ul += 24425f2d433Sxy150489 E1000_READ_REG(hw, E1000_PTC64); 24525f2d433Sxy150489 e1000g_ksp->Ptc127.value.ul += 24625f2d433Sxy150489 E1000_READ_REG(hw, E1000_PTC127); 24725f2d433Sxy150489 e1000g_ksp->Ptc255.value.ul += 24825f2d433Sxy150489 E1000_READ_REG(hw, E1000_PTC255); 24925f2d433Sxy150489 e1000g_ksp->Ptc511.value.ul += 25025f2d433Sxy150489 E1000_READ_REG(hw, E1000_PTC511); 25125f2d433Sxy150489 e1000g_ksp->Ptc1023.value.ul += 25225f2d433Sxy150489 E1000_READ_REG(hw, E1000_PTC1023); 25325f2d433Sxy150489 e1000g_ksp->Ptc1522.value.ul += 25425f2d433Sxy150489 E1000_READ_REG(hw, E1000_PTC1522); 25547b7744cSyy150190 #endif 25625f2d433Sxy150489 } 25708057504Sxy150489 25825f2d433Sxy150489 e1000g_ksp->Gprc.value.ul += E1000_READ_REG(hw, E1000_GPRC); 25925f2d433Sxy150489 e1000g_ksp->Gptc.value.ul += E1000_READ_REG(hw, E1000_GPTC); 26025f2d433Sxy150489 e1000g_ksp->Rfc.value.ul += E1000_READ_REG(hw, E1000_RFC); 261caf05df5SMiles Xu, Sun Microsystems e1000g_ksp->Tncrs.value.ul += e1000g_read_phy_stat(hw, E1000_TNCRS); 26225f2d433Sxy150489 e1000g_ksp->Tsctc.value.ul += E1000_READ_REG(hw, E1000_TSCTC); 26325f2d433Sxy150489 e1000g_ksp->Tsctfc.value.ul += E1000_READ_REG(hw, E1000_TSCTFC); 26425f2d433Sxy150489 26525f2d433Sxy150489 /* 26625f2d433Sxy150489 * Adaptive Calculations 26725f2d433Sxy150489 */ 26825f2d433Sxy150489 hw->mac.tx_packet_delta = E1000_READ_REG(hw, E1000_TPT); 269*29fd2c16SDavid Höppner Adapter->opackets += hw->mac.tx_packet_delta; 27008057504Sxy150489 27108057504Sxy150489 /* 27208057504Sxy150489 * The 64-bit register will reset whenever the upper 27308057504Sxy150489 * 32 bits are read. So we need to read the lower 27408057504Sxy150489 * 32 bits first, then read the upper 32 bits. 27508057504Sxy150489 */ 27625f2d433Sxy150489 low_val = E1000_READ_REG(hw, E1000_GORCL); 27725f2d433Sxy150489 high_val = E1000_READ_REG(hw, E1000_GORCH); 27808057504Sxy150489 val = (uint64_t)e1000g_ksp->Gorh.value.ul << 32 | 27908057504Sxy150489 (uint64_t)e1000g_ksp->Gorl.value.ul; 28008057504Sxy150489 val += (uint64_t)high_val << 32 | (uint64_t)low_val; 28108057504Sxy150489 e1000g_ksp->Gorl.value.ul = (uint32_t)val; 28208057504Sxy150489 e1000g_ksp->Gorh.value.ul = (uint32_t)(val >> 32); 28308057504Sxy150489 28425f2d433Sxy150489 low_val = E1000_READ_REG(hw, E1000_GOTCL); 28525f2d433Sxy150489 high_val = E1000_READ_REG(hw, E1000_GOTCH); 28608057504Sxy150489 val = (uint64_t)e1000g_ksp->Goth.value.ul << 32 | 28708057504Sxy150489 (uint64_t)e1000g_ksp->Gotl.value.ul; 28808057504Sxy150489 val += (uint64_t)high_val << 32 | (uint64_t)low_val; 28908057504Sxy150489 e1000g_ksp->Gotl.value.ul = (uint32_t)val; 29008057504Sxy150489 e1000g_ksp->Goth.value.ul = (uint32_t)(val >> 32); 29108057504Sxy150489 29225f2d433Sxy150489 low_val = E1000_READ_REG(hw, E1000_TORL); 29325f2d433Sxy150489 high_val = E1000_READ_REG(hw, E1000_TORH); 294*29fd2c16SDavid Höppner Adapter->rbytes += 295*29fd2c16SDavid Höppner (uint64_t)high_val << 32 | (uint64_t)low_val; 29608057504Sxy150489 29725f2d433Sxy150489 low_val = E1000_READ_REG(hw, E1000_TOTL); 29825f2d433Sxy150489 high_val = E1000_READ_REG(hw, E1000_TOTH); 299*29fd2c16SDavid Höppner Adapter->obytes += 300*29fd2c16SDavid Höppner (uint64_t)high_val << 32 | (uint64_t)low_val; 30108057504Sxy150489 30225f2d433Sxy150489 rw_exit(&Adapter->chip_lock); 30308057504Sxy150489 304ec39b9cfSchangqing li - Sun Microsystems - Beijing China if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK) { 3059b6541b3Sgl147354 ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED); 306ec39b9cfSchangqing li - Sun Microsystems - Beijing China return (EIO); 307ec39b9cfSchangqing li - Sun Microsystems - Beijing China } 3089b6541b3Sgl147354 30908057504Sxy150489 return (0); 31008057504Sxy150489 } 31108057504Sxy150489 31208057504Sxy150489 int 31308057504Sxy150489 e1000g_m_stat(void *arg, uint_t stat, uint64_t *val) 31408057504Sxy150489 { 31508057504Sxy150489 struct e1000g *Adapter = (struct e1000g *)arg; 31625f2d433Sxy150489 struct e1000_hw *hw = &Adapter->shared; 31725f2d433Sxy150489 p_e1000g_stat_t e1000g_ksp; 31808057504Sxy150489 uint32_t low_val, high_val; 31908057504Sxy150489 32025f2d433Sxy150489 e1000g_ksp = (p_e1000g_stat_t)Adapter->e1000g_ksp->ks_data; 32125f2d433Sxy150489 3224914a7d0Syy150190 rw_enter(&Adapter->chip_lock, RW_READER); 32308057504Sxy150489 324d5c3073dSchenlu chen - Sun Microsystems - Beijing China if (Adapter->e1000g_state & E1000G_SUSPENDED) { 325d5c3073dSchenlu chen - Sun Microsystems - Beijing China rw_exit(&Adapter->chip_lock); 326d5c3073dSchenlu chen - Sun Microsystems - Beijing China return (ECANCELED); 327d5c3073dSchenlu chen - Sun Microsystems - Beijing China } 328d5c3073dSchenlu chen - Sun Microsystems - Beijing China 32908057504Sxy150489 switch (stat) { 33008057504Sxy150489 case MAC_STAT_IFSPEED: 33108057504Sxy150489 *val = Adapter->link_speed * 1000000ull; 33208057504Sxy150489 break; 33308057504Sxy150489 33408057504Sxy150489 case MAC_STAT_MULTIRCV: 335*29fd2c16SDavid Höppner Adapter->multircv += 33625f2d433Sxy150489 E1000_READ_REG(hw, E1000_MPRC); 337*29fd2c16SDavid Höppner *val = Adapter->multircv; 33808057504Sxy150489 break; 33908057504Sxy150489 34008057504Sxy150489 case MAC_STAT_BRDCSTRCV: 341*29fd2c16SDavid Höppner Adapter->brdcstrcv += 34225f2d433Sxy150489 E1000_READ_REG(hw, E1000_BPRC); 343*29fd2c16SDavid Höppner *val = Adapter->brdcstrcv; 34408057504Sxy150489 break; 34508057504Sxy150489 34608057504Sxy150489 case MAC_STAT_MULTIXMT: 347*29fd2c16SDavid Höppner Adapter->multixmt += 34825f2d433Sxy150489 E1000_READ_REG(hw, E1000_MPTC); 349*29fd2c16SDavid Höppner *val = Adapter->multixmt; 35008057504Sxy150489 break; 35108057504Sxy150489 35208057504Sxy150489 case MAC_STAT_BRDCSTXMT: 353*29fd2c16SDavid Höppner Adapter->brdcstxmt += 35425f2d433Sxy150489 E1000_READ_REG(hw, E1000_BPTC); 355*29fd2c16SDavid Höppner *val = Adapter->brdcstxmt; 35608057504Sxy150489 break; 35708057504Sxy150489 35808057504Sxy150489 case MAC_STAT_NORCVBUF: 359*29fd2c16SDavid Höppner Adapter->norcvbuf += 36025f2d433Sxy150489 E1000_READ_REG(hw, E1000_RNBC); 361*29fd2c16SDavid Höppner *val = Adapter->norcvbuf; 36208057504Sxy150489 break; 36308057504Sxy150489 36408057504Sxy150489 case MAC_STAT_IERRORS: 365*29fd2c16SDavid Höppner Adapter->macrcv_errors += 36625f2d433Sxy150489 E1000_READ_REG(hw, E1000_RXERRC); 367*29fd2c16SDavid Höppner Adapter->align_errors += 36825f2d433Sxy150489 E1000_READ_REG(hw, E1000_ALGNERRC); 36908057504Sxy150489 e1000g_ksp->Rlec.value.ul += 37025f2d433Sxy150489 E1000_READ_REG(hw, E1000_RLEC); 371*29fd2c16SDavid Höppner Adapter->fcs_errors += 37225f2d433Sxy150489 E1000_READ_REG(hw, E1000_CRCERRS); 373*29fd2c16SDavid Höppner Adapter->carrier_errors += 37425f2d433Sxy150489 E1000_READ_REG(hw, E1000_CEXTERR); 375*29fd2c16SDavid Höppner *val = Adapter->macrcv_errors + 376*29fd2c16SDavid Höppner Adapter->align_errors + 37708057504Sxy150489 e1000g_ksp->Rlec.value.ul + 378*29fd2c16SDavid Höppner Adapter->fcs_errors + 379*29fd2c16SDavid Höppner Adapter->carrier_errors; 38008057504Sxy150489 break; 38108057504Sxy150489 38208057504Sxy150489 case MAC_STAT_NOXMTBUF: 38325f2d433Sxy150489 *val = Adapter->tx_ring->stat_no_desc; 38408057504Sxy150489 break; 38508057504Sxy150489 38608057504Sxy150489 case MAC_STAT_OERRORS: 387*29fd2c16SDavid Höppner Adapter->oerrors += 388caf05df5SMiles Xu, Sun Microsystems e1000g_read_phy_stat(hw, E1000_ECOL); 389*29fd2c16SDavid Höppner *val = Adapter->oerrors; 39008057504Sxy150489 break; 39108057504Sxy150489 39208057504Sxy150489 case MAC_STAT_COLLISIONS: 393*29fd2c16SDavid Höppner Adapter->collisions += 394caf05df5SMiles Xu, Sun Microsystems e1000g_read_phy_stat(hw, E1000_COLC); 395*29fd2c16SDavid Höppner *val = Adapter->collisions; 39608057504Sxy150489 break; 39708057504Sxy150489 39808057504Sxy150489 case MAC_STAT_RBYTES: 39908057504Sxy150489 /* 40008057504Sxy150489 * The 64-bit register will reset whenever the upper 40108057504Sxy150489 * 32 bits are read. So we need to read the lower 40208057504Sxy150489 * 32 bits first, then read the upper 32 bits. 40308057504Sxy150489 */ 40425f2d433Sxy150489 low_val = E1000_READ_REG(hw, E1000_TORL); 40525f2d433Sxy150489 high_val = E1000_READ_REG(hw, E1000_TORH); 406*29fd2c16SDavid Höppner Adapter->rbytes += 407*29fd2c16SDavid Höppner (uint64_t)high_val << 32 | (uint64_t)low_val; 408*29fd2c16SDavid Höppner *val = Adapter->rbytes; 40908057504Sxy150489 break; 41008057504Sxy150489 41108057504Sxy150489 case MAC_STAT_IPACKETS: 412*29fd2c16SDavid Höppner Adapter->ipackets += 41325f2d433Sxy150489 E1000_READ_REG(hw, E1000_TPR); 414*29fd2c16SDavid Höppner *val = Adapter->ipackets; 41508057504Sxy150489 break; 41608057504Sxy150489 41708057504Sxy150489 case MAC_STAT_OBYTES: 41808057504Sxy150489 /* 41908057504Sxy150489 * The 64-bit register will reset whenever the upper 42008057504Sxy150489 * 32 bits are read. So we need to read the lower 42108057504Sxy150489 * 32 bits first, then read the upper 32 bits. 42208057504Sxy150489 */ 42325f2d433Sxy150489 low_val = E1000_READ_REG(hw, E1000_TOTL); 42425f2d433Sxy150489 high_val = E1000_READ_REG(hw, E1000_TOTH); 425*29fd2c16SDavid Höppner Adapter->obytes += 426*29fd2c16SDavid Höppner (uint64_t)high_val << 32 | (uint64_t)low_val; 427*29fd2c16SDavid Höppner *val = Adapter->obytes; 42808057504Sxy150489 break; 42908057504Sxy150489 43008057504Sxy150489 case MAC_STAT_OPACKETS: 431*29fd2c16SDavid Höppner Adapter->opackets += 43225f2d433Sxy150489 E1000_READ_REG(hw, E1000_TPT); 433*29fd2c16SDavid Höppner *val = Adapter->opackets; 43408057504Sxy150489 break; 43508057504Sxy150489 43608057504Sxy150489 case ETHER_STAT_ALIGN_ERRORS: 437*29fd2c16SDavid Höppner Adapter->align_errors += 43825f2d433Sxy150489 E1000_READ_REG(hw, E1000_ALGNERRC); 439*29fd2c16SDavid Höppner *val = Adapter->align_errors; 44008057504Sxy150489 break; 44108057504Sxy150489 44208057504Sxy150489 case ETHER_STAT_FCS_ERRORS: 443*29fd2c16SDavid Höppner Adapter->fcs_errors += 44425f2d433Sxy150489 E1000_READ_REG(hw, E1000_CRCERRS); 445*29fd2c16SDavid Höppner *val = Adapter->fcs_errors; 44608057504Sxy150489 break; 44708057504Sxy150489 44808057504Sxy150489 case ETHER_STAT_SQE_ERRORS: 449*29fd2c16SDavid Höppner Adapter->sqe_errors += 45025f2d433Sxy150489 E1000_READ_REG(hw, E1000_SEC); 451*29fd2c16SDavid Höppner *val = Adapter->sqe_errors; 45208057504Sxy150489 break; 45308057504Sxy150489 45408057504Sxy150489 case ETHER_STAT_CARRIER_ERRORS: 455*29fd2c16SDavid Höppner Adapter->carrier_errors += 45625f2d433Sxy150489 E1000_READ_REG(hw, E1000_CEXTERR); 457*29fd2c16SDavid Höppner *val = Adapter->carrier_errors; 45808057504Sxy150489 break; 45908057504Sxy150489 46008057504Sxy150489 case ETHER_STAT_EX_COLLISIONS: 461*29fd2c16SDavid Höppner Adapter->ex_collisions += 462caf05df5SMiles Xu, Sun Microsystems e1000g_read_phy_stat(hw, E1000_ECOL); 463*29fd2c16SDavid Höppner *val = Adapter->ex_collisions; 46408057504Sxy150489 break; 46508057504Sxy150489 46608057504Sxy150489 case ETHER_STAT_TX_LATE_COLLISIONS: 467*29fd2c16SDavid Höppner Adapter->tx_late_collisions += 468caf05df5SMiles Xu, Sun Microsystems e1000g_read_phy_stat(hw, E1000_LATECOL); 469*29fd2c16SDavid Höppner *val = Adapter->tx_late_collisions; 47008057504Sxy150489 break; 47108057504Sxy150489 47208057504Sxy150489 case ETHER_STAT_DEFER_XMTS: 473*29fd2c16SDavid Höppner Adapter->defer_xmts += 474caf05df5SMiles Xu, Sun Microsystems e1000g_read_phy_stat(hw, E1000_DC); 475*29fd2c16SDavid Höppner *val = Adapter->defer_xmts; 47608057504Sxy150489 break; 47708057504Sxy150489 47808057504Sxy150489 case ETHER_STAT_FIRST_COLLISIONS: 479*29fd2c16SDavid Höppner Adapter->first_collisions += 480caf05df5SMiles Xu, Sun Microsystems e1000g_read_phy_stat(hw, E1000_SCC); 481*29fd2c16SDavid Höppner *val = Adapter->first_collisions; 48208057504Sxy150489 break; 48308057504Sxy150489 48408057504Sxy150489 case ETHER_STAT_MULTI_COLLISIONS: 485*29fd2c16SDavid Höppner Adapter->multi_collisions += 486caf05df5SMiles Xu, Sun Microsystems e1000g_read_phy_stat(hw, E1000_MCC); 487*29fd2c16SDavid Höppner *val = Adapter->multi_collisions; 48808057504Sxy150489 break; 48908057504Sxy150489 49008057504Sxy150489 case ETHER_STAT_MACRCV_ERRORS: 491*29fd2c16SDavid Höppner Adapter->macrcv_errors += 49225f2d433Sxy150489 E1000_READ_REG(hw, E1000_RXERRC); 493*29fd2c16SDavid Höppner *val = Adapter->macrcv_errors; 49408057504Sxy150489 break; 49508057504Sxy150489 49608057504Sxy150489 case ETHER_STAT_MACXMT_ERRORS: 497*29fd2c16SDavid Höppner Adapter->macxmt_errors += 498caf05df5SMiles Xu, Sun Microsystems e1000g_read_phy_stat(hw, E1000_ECOL); 499*29fd2c16SDavid Höppner *val = Adapter->macxmt_errors; 50008057504Sxy150489 break; 50108057504Sxy150489 50208057504Sxy150489 case ETHER_STAT_TOOLONG_ERRORS: 503*29fd2c16SDavid Höppner Adapter->toolong_errors += 50425f2d433Sxy150489 E1000_READ_REG(hw, E1000_ROC); 505*29fd2c16SDavid Höppner *val = Adapter->toolong_errors; 506*29fd2c16SDavid Höppner break; 507*29fd2c16SDavid Höppner 508*29fd2c16SDavid Höppner case ETHER_STAT_TOOSHORT_ERRORS: 509*29fd2c16SDavid Höppner Adapter->tooshort_errors += 510*29fd2c16SDavid Höppner E1000_READ_REG(hw, E1000_RUC); 511*29fd2c16SDavid Höppner *val = Adapter->tooshort_errors; 512*29fd2c16SDavid Höppner break; 513*29fd2c16SDavid Höppner 514*29fd2c16SDavid Höppner case ETHER_STAT_JABBER_ERRORS: 515*29fd2c16SDavid Höppner Adapter->jabber_errors += 516*29fd2c16SDavid Höppner E1000_READ_REG(hw, E1000_RJC); 517*29fd2c16SDavid Höppner *val = Adapter->jabber_errors; 51808057504Sxy150489 break; 51908057504Sxy150489 52008057504Sxy150489 case ETHER_STAT_XCVR_ADDR: 52108057504Sxy150489 /* The Internal PHY's MDI address for each MAC is 1 */ 52208057504Sxy150489 *val = 1; 52308057504Sxy150489 break; 52408057504Sxy150489 52508057504Sxy150489 case ETHER_STAT_XCVR_ID: 5264914a7d0Syy150190 *val = hw->phy.id | hw->phy.revision; 52708057504Sxy150489 break; 52808057504Sxy150489 52908057504Sxy150489 case ETHER_STAT_XCVR_INUSE: 53008057504Sxy150489 switch (Adapter->link_speed) { 53108057504Sxy150489 case SPEED_1000: 53208057504Sxy150489 *val = 533592a4d85Scc210113 (hw->phy.media_type == e1000_media_type_copper) ? 53425f2d433Sxy150489 XCVR_1000T : XCVR_1000X; 53508057504Sxy150489 break; 53608057504Sxy150489 case SPEED_100: 53708057504Sxy150489 *val = 538592a4d85Scc210113 (hw->phy.media_type == e1000_media_type_copper) ? 5394914a7d0Syy150190 (Adapter->phy_status & MII_SR_100T4_CAPS) ? 54025f2d433Sxy150489 XCVR_100T4 : XCVR_100T2 : XCVR_100X; 54108057504Sxy150489 break; 54208057504Sxy150489 case SPEED_10: 54308057504Sxy150489 *val = XCVR_10; 54408057504Sxy150489 break; 54508057504Sxy150489 default: 54608057504Sxy150489 *val = XCVR_NONE; 54708057504Sxy150489 break; 54808057504Sxy150489 } 54908057504Sxy150489 break; 55008057504Sxy150489 55108057504Sxy150489 case ETHER_STAT_CAP_1000FDX: 5529ce7e93cScc210113 *val = Adapter->param_1000fdx_cap; 55308057504Sxy150489 break; 55408057504Sxy150489 55508057504Sxy150489 case ETHER_STAT_CAP_1000HDX: 5569ce7e93cScc210113 *val = Adapter->param_1000hdx_cap; 55708057504Sxy150489 break; 55808057504Sxy150489 55908057504Sxy150489 case ETHER_STAT_CAP_100FDX: 5609ce7e93cScc210113 *val = Adapter->param_100fdx_cap; 56108057504Sxy150489 break; 56208057504Sxy150489 56308057504Sxy150489 case ETHER_STAT_CAP_100HDX: 5649ce7e93cScc210113 *val = Adapter->param_100hdx_cap; 56508057504Sxy150489 break; 56608057504Sxy150489 56708057504Sxy150489 case ETHER_STAT_CAP_10FDX: 5689ce7e93cScc210113 *val = Adapter->param_10fdx_cap; 56908057504Sxy150489 break; 57008057504Sxy150489 57108057504Sxy150489 case ETHER_STAT_CAP_10HDX: 5729ce7e93cScc210113 *val = Adapter->param_10hdx_cap; 57308057504Sxy150489 break; 57408057504Sxy150489 57508057504Sxy150489 case ETHER_STAT_CAP_ASMPAUSE: 5769ce7e93cScc210113 *val = Adapter->param_asym_pause_cap; 57708057504Sxy150489 break; 57808057504Sxy150489 57908057504Sxy150489 case ETHER_STAT_CAP_PAUSE: 5809ce7e93cScc210113 *val = Adapter->param_pause_cap; 58108057504Sxy150489 break; 58208057504Sxy150489 58308057504Sxy150489 case ETHER_STAT_CAP_AUTONEG: 5849ce7e93cScc210113 *val = Adapter->param_autoneg_cap; 58508057504Sxy150489 break; 58608057504Sxy150489 58708057504Sxy150489 case ETHER_STAT_ADV_CAP_1000FDX: 5889ce7e93cScc210113 *val = Adapter->param_adv_1000fdx; 58908057504Sxy150489 break; 59008057504Sxy150489 59108057504Sxy150489 case ETHER_STAT_ADV_CAP_1000HDX: 5929ce7e93cScc210113 *val = Adapter->param_adv_1000hdx; 59308057504Sxy150489 break; 59408057504Sxy150489 59508057504Sxy150489 case ETHER_STAT_ADV_CAP_100FDX: 5969ce7e93cScc210113 *val = Adapter->param_adv_100fdx; 59708057504Sxy150489 break; 59808057504Sxy150489 59908057504Sxy150489 case ETHER_STAT_ADV_CAP_100HDX: 6009ce7e93cScc210113 *val = Adapter->param_adv_100hdx; 60108057504Sxy150489 break; 60208057504Sxy150489 60308057504Sxy150489 case ETHER_STAT_ADV_CAP_10FDX: 6049ce7e93cScc210113 *val = Adapter->param_adv_10fdx; 60508057504Sxy150489 break; 60608057504Sxy150489 60708057504Sxy150489 case ETHER_STAT_ADV_CAP_10HDX: 6089ce7e93cScc210113 *val = Adapter->param_adv_10hdx; 60908057504Sxy150489 break; 61008057504Sxy150489 61108057504Sxy150489 case ETHER_STAT_ADV_CAP_ASMPAUSE: 6129ce7e93cScc210113 *val = Adapter->param_adv_asym_pause; 61308057504Sxy150489 break; 61408057504Sxy150489 61508057504Sxy150489 case ETHER_STAT_ADV_CAP_PAUSE: 6169ce7e93cScc210113 *val = Adapter->param_adv_pause; 61708057504Sxy150489 break; 61808057504Sxy150489 61908057504Sxy150489 case ETHER_STAT_ADV_CAP_AUTONEG: 62025f2d433Sxy150489 *val = hw->mac.autoneg; 62108057504Sxy150489 break; 62208057504Sxy150489 62308057504Sxy150489 case ETHER_STAT_LP_CAP_1000FDX: 6249ce7e93cScc210113 *val = Adapter->param_lp_1000fdx; 62508057504Sxy150489 break; 62608057504Sxy150489 62708057504Sxy150489 case ETHER_STAT_LP_CAP_1000HDX: 6289ce7e93cScc210113 *val = Adapter->param_lp_1000hdx; 62908057504Sxy150489 break; 63008057504Sxy150489 63108057504Sxy150489 case ETHER_STAT_LP_CAP_100FDX: 6329ce7e93cScc210113 *val = Adapter->param_lp_100fdx; 63308057504Sxy150489 break; 63408057504Sxy150489 63508057504Sxy150489 case ETHER_STAT_LP_CAP_100HDX: 6369ce7e93cScc210113 *val = Adapter->param_lp_100hdx; 63708057504Sxy150489 break; 63808057504Sxy150489 63908057504Sxy150489 case ETHER_STAT_LP_CAP_10FDX: 6409ce7e93cScc210113 *val = Adapter->param_lp_10fdx; 64108057504Sxy150489 break; 64208057504Sxy150489 64308057504Sxy150489 case ETHER_STAT_LP_CAP_10HDX: 6449ce7e93cScc210113 *val = Adapter->param_lp_10hdx; 64508057504Sxy150489 break; 64608057504Sxy150489 64708057504Sxy150489 case ETHER_STAT_LP_CAP_ASMPAUSE: 6489ce7e93cScc210113 *val = Adapter->param_lp_asym_pause; 64908057504Sxy150489 break; 65008057504Sxy150489 65108057504Sxy150489 case ETHER_STAT_LP_CAP_PAUSE: 6529ce7e93cScc210113 *val = Adapter->param_lp_pause; 65308057504Sxy150489 break; 65408057504Sxy150489 65508057504Sxy150489 case ETHER_STAT_LP_CAP_AUTONEG: 6569ce7e93cScc210113 *val = Adapter->param_lp_autoneg; 65708057504Sxy150489 break; 65808057504Sxy150489 65908057504Sxy150489 case ETHER_STAT_LINK_ASMPAUSE: 6609ce7e93cScc210113 *val = Adapter->param_asym_pause_cap; 66108057504Sxy150489 break; 66208057504Sxy150489 66308057504Sxy150489 case ETHER_STAT_LINK_PAUSE: 6649ce7e93cScc210113 *val = Adapter->param_pause_cap; 66508057504Sxy150489 break; 66608057504Sxy150489 66708057504Sxy150489 case ETHER_STAT_LINK_AUTONEG: 6689ce7e93cScc210113 *val = hw->mac.autoneg; 66908057504Sxy150489 break; 67008057504Sxy150489 67108057504Sxy150489 case ETHER_STAT_LINK_DUPLEX: 67208057504Sxy150489 *val = (Adapter->link_duplex == FULL_DUPLEX) ? 67308057504Sxy150489 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF; 67408057504Sxy150489 break; 67508057504Sxy150489 6769ce7e93cScc210113 case ETHER_STAT_CAP_100T4: 6779ce7e93cScc210113 *val = Adapter->param_100t4_cap; 6789ce7e93cScc210113 break; 6799ce7e93cScc210113 6809ce7e93cScc210113 case ETHER_STAT_ADV_CAP_100T4: 6819ce7e93cScc210113 *val = Adapter->param_adv_100t4; 6829ce7e93cScc210113 break; 6839ce7e93cScc210113 6849ce7e93cScc210113 case ETHER_STAT_LP_CAP_100T4: 6859ce7e93cScc210113 *val = Adapter->param_lp_100t4; 6869ce7e93cScc210113 break; 6879ce7e93cScc210113 68808057504Sxy150489 default: 68925f2d433Sxy150489 rw_exit(&Adapter->chip_lock); 69008057504Sxy150489 return (ENOTSUP); 69108057504Sxy150489 } 69208057504Sxy150489 69325f2d433Sxy150489 rw_exit(&Adapter->chip_lock); 69425f2d433Sxy150489 695ec39b9cfSchangqing li - Sun Microsystems - Beijing China if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK) { 6969b6541b3Sgl147354 ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED); 697ec39b9cfSchangqing li - Sun Microsystems - Beijing China return (EIO); 698ec39b9cfSchangqing li - Sun Microsystems - Beijing China } 6999b6541b3Sgl147354 70008057504Sxy150489 return (0); 70108057504Sxy150489 } 70208057504Sxy150489 70308057504Sxy150489 /* 70425f2d433Sxy150489 * e1000g_init_stats - initialize kstat data structures 70525f2d433Sxy150489 * 70625f2d433Sxy150489 * This routine will create and initialize the driver private 70725f2d433Sxy150489 * statistics counters. 70808057504Sxy150489 */ 70908057504Sxy150489 int 71025f2d433Sxy150489 e1000g_init_stats(struct e1000g *Adapter) 71108057504Sxy150489 { 71208057504Sxy150489 kstat_t *ksp; 71325f2d433Sxy150489 p_e1000g_stat_t e1000g_ksp; 71408057504Sxy150489 71508057504Sxy150489 /* 71608057504Sxy150489 * Create and init kstat 71708057504Sxy150489 */ 71808057504Sxy150489 ksp = kstat_create(WSNAME, ddi_get_instance(Adapter->dip), 71908057504Sxy150489 "statistics", "net", KSTAT_TYPE_NAMED, 72025f2d433Sxy150489 sizeof (e1000g_stat_t) / sizeof (kstat_named_t), 0); 72108057504Sxy150489 72208057504Sxy150489 if (ksp == NULL) { 72308057504Sxy150489 e1000g_log(Adapter, CE_WARN, 72408057504Sxy150489 "Could not create kernel statistics\n"); 72508057504Sxy150489 return (DDI_FAILURE); 72608057504Sxy150489 } 72708057504Sxy150489 72808057504Sxy150489 Adapter->e1000g_ksp = ksp; /* Fill in the Adapters ksp */ 72908057504Sxy150489 73025f2d433Sxy150489 e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data; 73108057504Sxy150489 73208057504Sxy150489 /* 73308057504Sxy150489 * Initialize all the statistics 73408057504Sxy150489 */ 73525f2d433Sxy150489 kstat_named_init(&e1000g_ksp->reset_count, "Reset Count", 73608057504Sxy150489 KSTAT_DATA_ULONG); 73708057504Sxy150489 73808057504Sxy150489 kstat_named_init(&e1000g_ksp->rx_error, "Rx Error", 73908057504Sxy150489 KSTAT_DATA_ULONG); 74008057504Sxy150489 kstat_named_init(&e1000g_ksp->rx_allocb_fail, "Rx Allocb Failure", 74108057504Sxy150489 KSTAT_DATA_ULONG); 74246ebaa55SMiles Xu, Sun Microsystems kstat_named_init(&e1000g_ksp->rx_size_error, "Rx Size Error", 74346ebaa55SMiles Xu, Sun Microsystems KSTAT_DATA_ULONG); 74408057504Sxy150489 74508057504Sxy150489 kstat_named_init(&e1000g_ksp->tx_no_desc, "Tx No Desc", 74608057504Sxy150489 KSTAT_DATA_ULONG); 74708057504Sxy150489 kstat_named_init(&e1000g_ksp->tx_no_swpkt, "Tx No Buffer", 74808057504Sxy150489 KSTAT_DATA_ULONG); 74925f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_send_fail, "Tx Send Failure", 75025f2d433Sxy150489 KSTAT_DATA_ULONG); 75125f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_over_size, "Tx Pkt Over Size", 75225f2d433Sxy150489 KSTAT_DATA_ULONG); 75325f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_reschedule, "Tx Reschedule", 75408057504Sxy150489 KSTAT_DATA_ULONG); 75508057504Sxy150489 75625f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Mpc, "Recv_Missed_Packets", 75725f2d433Sxy150489 KSTAT_DATA_ULONG); 75825f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Symerrs, "Recv_Symbol_Errors", 75925f2d433Sxy150489 KSTAT_DATA_ULONG); 76025f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Rlec, "Recv_Length_Errors", 76125f2d433Sxy150489 KSTAT_DATA_ULONG); 76225f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Xonrxc, "XONs_Recvd", 76325f2d433Sxy150489 KSTAT_DATA_ULONG); 76425f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Xontxc, "XONs_Xmitd", 76525f2d433Sxy150489 KSTAT_DATA_ULONG); 76625f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Xoffrxc, "XOFFs_Recvd", 76725f2d433Sxy150489 KSTAT_DATA_ULONG); 76825f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Xofftxc, "XOFFs_Xmitd", 76925f2d433Sxy150489 KSTAT_DATA_ULONG); 77025f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Fcruc, "Recv_Unsupport_FC_Pkts", 77125f2d433Sxy150489 KSTAT_DATA_ULONG); 77247b7744cSyy150190 #ifdef E1000G_DEBUG 77325f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Prc64, "Pkts_Recvd_( 64b)", 77425f2d433Sxy150489 KSTAT_DATA_ULONG); 77525f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Prc127, "Pkts_Recvd_( 65- 127b)", 77625f2d433Sxy150489 KSTAT_DATA_ULONG); 77725f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Prc255, "Pkts_Recvd_( 127- 255b)", 77825f2d433Sxy150489 KSTAT_DATA_ULONG); 77925f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Prc511, "Pkts_Recvd_( 256- 511b)", 78025f2d433Sxy150489 KSTAT_DATA_ULONG); 78125f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Prc1023, "Pkts_Recvd_( 511-1023b)", 78225f2d433Sxy150489 KSTAT_DATA_ULONG); 78325f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Prc1522, "Pkts_Recvd_(1024-1522b)", 78425f2d433Sxy150489 KSTAT_DATA_ULONG); 78547b7744cSyy150190 #endif 78625f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Gprc, "Good_Pkts_Recvd", 78725f2d433Sxy150489 KSTAT_DATA_ULONG); 78825f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Gptc, "Good_Pkts_Xmitd", 78925f2d433Sxy150489 KSTAT_DATA_ULONG); 79025f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Gorl, "Good_Octets_Recvd_Lo", 79125f2d433Sxy150489 KSTAT_DATA_ULONG); 79225f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Gorh, "Good_Octets_Recvd_Hi", 79325f2d433Sxy150489 KSTAT_DATA_ULONG); 79425f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Gotl, "Good_Octets_Xmitd_Lo", 79525f2d433Sxy150489 KSTAT_DATA_ULONG); 79625f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Goth, "Good_Octets_Xmitd_Hi", 79725f2d433Sxy150489 KSTAT_DATA_ULONG); 79825f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Rfc, "Recv_Frag", 79925f2d433Sxy150489 KSTAT_DATA_ULONG); 80047b7744cSyy150190 #ifdef E1000G_DEBUG 80125f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Ptc64, "Pkts_Xmitd_( 64b)", 80225f2d433Sxy150489 KSTAT_DATA_ULONG); 80325f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Ptc127, "Pkts_Xmitd_( 65- 127b)", 80425f2d433Sxy150489 KSTAT_DATA_ULONG); 80525f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Ptc255, "Pkts_Xmitd_( 128- 255b)", 80625f2d433Sxy150489 KSTAT_DATA_ULONG); 80725f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Ptc511, "Pkts_Xmitd_( 255- 511b)", 80825f2d433Sxy150489 KSTAT_DATA_ULONG); 80925f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Ptc1023, "Pkts_Xmitd_( 512-1023b)", 81025f2d433Sxy150489 KSTAT_DATA_ULONG); 81125f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Ptc1522, "Pkts_Xmitd_(1024-1522b)", 81225f2d433Sxy150489 KSTAT_DATA_ULONG); 81347b7744cSyy150190 #endif 81425f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Tncrs, "Xmit_with_No_CRS", 81525f2d433Sxy150489 KSTAT_DATA_ULONG); 81625f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Tsctc, "Xmit_TCP_Seg_Contexts", 81725f2d433Sxy150489 KSTAT_DATA_ULONG); 81825f2d433Sxy150489 kstat_named_init(&e1000g_ksp->Tsctfc, "Xmit_TCP_Seg_Contexts_Fail", 81925f2d433Sxy150489 KSTAT_DATA_ULONG); 82008057504Sxy150489 82125f2d433Sxy150489 #ifdef E1000G_DEBUG 82225f2d433Sxy150489 kstat_named_init(&e1000g_ksp->rx_none, "Rx No Data", 82325f2d433Sxy150489 KSTAT_DATA_ULONG); 82425f2d433Sxy150489 kstat_named_init(&e1000g_ksp->rx_multi_desc, "Rx Span Multi Desc", 82525f2d433Sxy150489 KSTAT_DATA_ULONG); 82625f2d433Sxy150489 kstat_named_init(&e1000g_ksp->rx_no_freepkt, "Rx Freelist Empty", 82725f2d433Sxy150489 KSTAT_DATA_ULONG); 82825f2d433Sxy150489 kstat_named_init(&e1000g_ksp->rx_avail_freepkt, "Rx Freelist Avail", 82908057504Sxy150489 KSTAT_DATA_ULONG); 83008057504Sxy150489 83108057504Sxy150489 kstat_named_init(&e1000g_ksp->tx_under_size, "Tx Pkt Under Size", 83208057504Sxy150489 KSTAT_DATA_ULONG); 83308057504Sxy150489 kstat_named_init(&e1000g_ksp->tx_exceed_frags, "Tx Exceed Max Frags", 83408057504Sxy150489 KSTAT_DATA_ULONG); 83525f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_empty_frags, "Tx Empty Frags", 83608057504Sxy150489 KSTAT_DATA_ULONG); 83725f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_recycle, "Tx Recycle", 83808057504Sxy150489 KSTAT_DATA_ULONG); 83925f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_recycle_intr, "Tx Recycle Intr", 84008057504Sxy150489 KSTAT_DATA_ULONG); 84125f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_recycle_retry, "Tx Recycle Retry", 84208057504Sxy150489 KSTAT_DATA_ULONG); 84325f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_recycle_none, "Tx Recycled None", 84408057504Sxy150489 KSTAT_DATA_ULONG); 84525f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_copy, "Tx Send Copy", 84608057504Sxy150489 KSTAT_DATA_ULONG); 84725f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_bind, "Tx Send Bind", 84808057504Sxy150489 KSTAT_DATA_ULONG); 84925f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_multi_copy, "Tx Copy Multi Frags", 85008057504Sxy150489 KSTAT_DATA_ULONG); 85125f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_multi_cookie, "Tx Bind Multi Cookies", 85208057504Sxy150489 KSTAT_DATA_ULONG); 85325f2d433Sxy150489 kstat_named_init(&e1000g_ksp->tx_lack_desc, "Tx Desc Insufficient", 85408057504Sxy150489 KSTAT_DATA_ULONG); 85525f2d433Sxy150489 #endif 85608057504Sxy150489 85708057504Sxy150489 /* 85808057504Sxy150489 * Function to provide kernel stat update on demand 85908057504Sxy150489 */ 86025f2d433Sxy150489 ksp->ks_update = e1000g_update_stats; 86108057504Sxy150489 86208057504Sxy150489 /* 86308057504Sxy150489 * Pointer into provider's raw statistics 86408057504Sxy150489 */ 86508057504Sxy150489 ksp->ks_private = (void *)Adapter; 86608057504Sxy150489 86708057504Sxy150489 /* 86808057504Sxy150489 * Add kstat to systems kstat chain 86908057504Sxy150489 */ 87008057504Sxy150489 kstat_install(ksp); 87108057504Sxy150489 87208057504Sxy150489 return (DDI_SUCCESS); 87308057504Sxy150489 } 874caf05df5SMiles Xu, Sun Microsystems 875caf05df5SMiles Xu, Sun Microsystems /* 876caf05df5SMiles Xu, Sun Microsystems * e1000g_read_phy_stat - read certain PHY statistics 877caf05df5SMiles Xu, Sun Microsystems * 878caf05df5SMiles Xu, Sun Microsystems * Certain statistics are read from MAC registers on some silicon types 879caf05df5SMiles Xu, Sun Microsystems * but are read from the PHY on other silicon types. This routine 880caf05df5SMiles Xu, Sun Microsystems * handles that difference as needed. 881caf05df5SMiles Xu, Sun Microsystems */ 882caf05df5SMiles Xu, Sun Microsystems static uint32_t 883caf05df5SMiles Xu, Sun Microsystems e1000g_read_phy_stat(struct e1000_hw *hw, int reg) 884caf05df5SMiles Xu, Sun Microsystems { 885caf05df5SMiles Xu, Sun Microsystems uint16_t phy_low, phy_high; 886caf05df5SMiles Xu, Sun Microsystems uint32_t val; 887caf05df5SMiles Xu, Sun Microsystems 888caf05df5SMiles Xu, Sun Microsystems /* get statistic from PHY in these cases */ 889caf05df5SMiles Xu, Sun Microsystems if ((hw->phy.type == e1000_phy_82578) || 890caf05df5SMiles Xu, Sun Microsystems (hw->phy.type == e1000_phy_82577)) { 891caf05df5SMiles Xu, Sun Microsystems 892caf05df5SMiles Xu, Sun Microsystems switch (reg) { 893caf05df5SMiles Xu, Sun Microsystems case E1000_SCC: 894caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_SCC_UPPER, &phy_high); 895caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_SCC_LOWER, &phy_low); 896caf05df5SMiles Xu, Sun Microsystems val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low; 897caf05df5SMiles Xu, Sun Microsystems break; 898caf05df5SMiles Xu, Sun Microsystems 899caf05df5SMiles Xu, Sun Microsystems case E1000_MCC: 900caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_MCC_UPPER, &phy_high); 901caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_MCC_LOWER, &phy_low); 902caf05df5SMiles Xu, Sun Microsystems val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low; 903caf05df5SMiles Xu, Sun Microsystems break; 904caf05df5SMiles Xu, Sun Microsystems 905caf05df5SMiles Xu, Sun Microsystems case E1000_ECOL: 906caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_ECOL_UPPER, &phy_high); 907caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_ECOL_LOWER, &phy_low); 908caf05df5SMiles Xu, Sun Microsystems val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low; 909caf05df5SMiles Xu, Sun Microsystems break; 910caf05df5SMiles Xu, Sun Microsystems 911caf05df5SMiles Xu, Sun Microsystems case E1000_COLC: 912caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_COLC_UPPER, &phy_high); 913caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_COLC_LOWER, &phy_low); 914caf05df5SMiles Xu, Sun Microsystems val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low; 915caf05df5SMiles Xu, Sun Microsystems break; 916caf05df5SMiles Xu, Sun Microsystems 917caf05df5SMiles Xu, Sun Microsystems case E1000_LATECOL: 918caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_LATECOL_UPPER, 919caf05df5SMiles Xu, Sun Microsystems &phy_high); 920caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_LATECOL_LOWER, 921caf05df5SMiles Xu, Sun Microsystems &phy_low); 922caf05df5SMiles Xu, Sun Microsystems val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low; 923caf05df5SMiles Xu, Sun Microsystems break; 924caf05df5SMiles Xu, Sun Microsystems 925caf05df5SMiles Xu, Sun Microsystems case E1000_DC: 926caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_DC_UPPER, &phy_high); 927caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_DC_LOWER, &phy_low); 928caf05df5SMiles Xu, Sun Microsystems val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low; 929caf05df5SMiles Xu, Sun Microsystems break; 930caf05df5SMiles Xu, Sun Microsystems 931caf05df5SMiles Xu, Sun Microsystems case E1000_TNCRS: 932caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_TNCRS_UPPER, 933caf05df5SMiles Xu, Sun Microsystems &phy_high); 934caf05df5SMiles Xu, Sun Microsystems (void) e1000_read_phy_reg(hw, HV_TNCRS_LOWER, 935caf05df5SMiles Xu, Sun Microsystems &phy_low); 936caf05df5SMiles Xu, Sun Microsystems val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low; 937caf05df5SMiles Xu, Sun Microsystems break; 938caf05df5SMiles Xu, Sun Microsystems 939caf05df5SMiles Xu, Sun Microsystems default: 940caf05df5SMiles Xu, Sun Microsystems break; 941caf05df5SMiles Xu, Sun Microsystems } 942caf05df5SMiles Xu, Sun Microsystems 943caf05df5SMiles Xu, Sun Microsystems /* get statistic from MAC otherwise */ 944caf05df5SMiles Xu, Sun Microsystems } else { 945caf05df5SMiles Xu, Sun Microsystems val = E1000_READ_REG(hw, reg); 946caf05df5SMiles Xu, Sun Microsystems } 947caf05df5SMiles Xu, Sun Microsystems 948caf05df5SMiles Xu, Sun Microsystems return (val); 949caf05df5SMiles Xu, Sun Microsystems } 9500dc2366fSVenugopal Iyer 9510dc2366fSVenugopal Iyer /* 9520dc2366fSVenugopal Iyer * Retrieve a value for one of the statistics for a particular rx ring 9530dc2366fSVenugopal Iyer */ 9540dc2366fSVenugopal Iyer int 9550dc2366fSVenugopal Iyer e1000g_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 9560dc2366fSVenugopal Iyer { 9570dc2366fSVenugopal Iyer e1000g_rx_ring_t *rx_ring = (e1000g_rx_ring_t *)rh; 9580dc2366fSVenugopal Iyer struct e1000g *Adapter = rx_ring->adapter; 9590dc2366fSVenugopal Iyer struct e1000_hw *hw = &Adapter->shared; 9600dc2366fSVenugopal Iyer uint32_t low_val, high_val; 9610dc2366fSVenugopal Iyer 9620dc2366fSVenugopal Iyer rw_enter(&Adapter->chip_lock, RW_READER); 9630dc2366fSVenugopal Iyer 9640dc2366fSVenugopal Iyer if (Adapter->e1000g_state & E1000G_SUSPENDED) { 9650dc2366fSVenugopal Iyer rw_exit(&Adapter->chip_lock); 9660dc2366fSVenugopal Iyer return (ECANCELED); 9670dc2366fSVenugopal Iyer } 9680dc2366fSVenugopal Iyer 9690dc2366fSVenugopal Iyer switch (stat) { 9700dc2366fSVenugopal Iyer case MAC_STAT_RBYTES: 9710dc2366fSVenugopal Iyer /* 9720dc2366fSVenugopal Iyer * The 64-bit register will reset whenever the upper 9730dc2366fSVenugopal Iyer * 32 bits are read. So we need to read the lower 9740dc2366fSVenugopal Iyer * 32 bits first, then read the upper 32 bits. 9750dc2366fSVenugopal Iyer */ 9760dc2366fSVenugopal Iyer low_val = E1000_READ_REG(hw, E1000_TORL); 9770dc2366fSVenugopal Iyer high_val = E1000_READ_REG(hw, E1000_TORH); 978*29fd2c16SDavid Höppner Adapter->rbytes += 979*29fd2c16SDavid Höppner (uint64_t)high_val << 32 | (uint64_t)low_val; 980*29fd2c16SDavid Höppner *val = Adapter->rbytes; 9810dc2366fSVenugopal Iyer break; 9820dc2366fSVenugopal Iyer 9830dc2366fSVenugopal Iyer case MAC_STAT_IPACKETS: 984*29fd2c16SDavid Höppner Adapter->ipackets += 9850dc2366fSVenugopal Iyer E1000_READ_REG(hw, E1000_TPR); 986*29fd2c16SDavid Höppner *val = Adapter->ipackets; 9870dc2366fSVenugopal Iyer break; 9880dc2366fSVenugopal Iyer 9890dc2366fSVenugopal Iyer default: 9900dc2366fSVenugopal Iyer *val = 0; 9910dc2366fSVenugopal Iyer rw_exit(&Adapter->chip_lock); 9920dc2366fSVenugopal Iyer return (ENOTSUP); 9930dc2366fSVenugopal Iyer } 9940dc2366fSVenugopal Iyer 9950dc2366fSVenugopal Iyer rw_exit(&Adapter->chip_lock); 9960dc2366fSVenugopal Iyer 9970dc2366fSVenugopal Iyer if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK) 9980dc2366fSVenugopal Iyer ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED); 9990dc2366fSVenugopal Iyer 10000dc2366fSVenugopal Iyer return (0); 10010dc2366fSVenugopal Iyer } 1002