1171095Ssam/*- 2171095Ssam * Copyright (c) 2002-2007 Neterion, Inc. 3171095Ssam * All rights reserved. 4171095Ssam * 5171095Ssam * Redistribution and use in source and binary forms, with or without 6171095Ssam * modification, are permitted provided that the following conditions 7171095Ssam * are met: 8171095Ssam * 1. Redistributions of source code must retain the above copyright 9171095Ssam * notice, this list of conditions and the following disclaimer. 10171095Ssam * 2. Redistributions in binary form must reproduce the above copyright 11171095Ssam * notice, this list of conditions and the following disclaimer in the 12171095Ssam * documentation and/or other materials provided with the distribution. 13171095Ssam * 14171095Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15171095Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16171095Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17171095Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18171095Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19171095Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20171095Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21171095Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22171095Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23171095Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24171095Ssam * SUCH DAMAGE. 25171095Ssam * 26171095Ssam * $FreeBSD$ 27171095Ssam */ 28171095Ssam 29171095Ssam#include <dev/nxge/include/xgehal-stats.h> 30171095Ssam#include <dev/nxge/include/xgehal-device.h> 31171095Ssam 32171095Ssam/* 33171095Ssam * __hal_stats_initialize 34171095Ssam * @stats: xge_hal_stats_t structure that contains, in particular, 35171095Ssam * Xframe hw stat counters. 36171095Ssam * @devh: HAL device handle. 37171095Ssam * 38171095Ssam * Initialize per-device statistics object. 39171095Ssam * See also: xge_hal_stats_getinfo(), xge_hal_status_e{}. 40171095Ssam */ 41171095Ssamxge_hal_status_e 42171095Ssam__hal_stats_initialize (xge_hal_stats_t *stats, xge_hal_device_h devh) 43171095Ssam{ 44171095Ssam int dma_flags; 45171095Ssam xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 46171095Ssam 47171095Ssam xge_assert(!stats->is_initialized); 48171095Ssam 49171095Ssam dma_flags = XGE_OS_DMA_CACHELINE_ALIGNED; 50171095Ssam#ifdef XGE_HAL_DMA_STATS_CONSISTENT 51171095Ssam dma_flags |= XGE_OS_DMA_CONSISTENT; 52171095Ssam#else 53171095Ssam dma_flags |= XGE_OS_DMA_STREAMING; 54171095Ssam#endif 55171095Ssam if (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN) { 56173139Srwatson stats->hw_info = 57173139Srwatson (xge_hal_stats_hw_info_t *) xge_os_dma_malloc( 58173139Srwatson hldev->pdev, 59173139Srwatson sizeof(xge_hal_stats_hw_info_t), 60173139Srwatson dma_flags, 61173139Srwatson &stats->hw_info_dmah, 62173139Srwatson &stats->hw_info_dma_acch); 63171095Ssam 64173139Srwatson if (stats->hw_info == NULL) { 65173139Srwatson xge_debug_stats(XGE_ERR, "%s", "can not DMA alloc"); 66173139Srwatson return XGE_HAL_ERR_OUT_OF_MEMORY; 67173139Srwatson } 68173139Srwatson xge_os_memzero(stats->hw_info, 69173139Srwatson sizeof(xge_hal_stats_hw_info_t)); 70173139Srwatson xge_os_memzero(&stats->hw_info_saved, 71173139Srwatson sizeof(xge_hal_stats_hw_info_t)); 72173139Srwatson xge_os_memzero(&stats->hw_info_latest, 73173139Srwatson sizeof(xge_hal_stats_hw_info_t)); 74171095Ssam 75171095Ssam 76171095Ssam 77173139Srwatson stats->dma_addr = xge_os_dma_map(hldev->pdev, 78171095Ssam stats->hw_info_dmah, 79173139Srwatson stats->hw_info, 80173139Srwatson sizeof(xge_hal_stats_hw_info_t), 81173139Srwatson XGE_OS_DMA_DIR_FROMDEVICE, 82173139Srwatson XGE_OS_DMA_CACHELINE_ALIGNED | 83171095Ssam#ifdef XGE_HAL_DMA_STATS_CONSISTENT 84173139Srwatson XGE_OS_DMA_CONSISTENT 85171095Ssam#else 86173139Srwatson XGE_OS_DMA_STREAMING 87171095Ssam#endif 88173139Srwatson ); 89173139Srwatson if (stats->dma_addr == XGE_OS_INVALID_DMA_ADDR) { 90173139Srwatson xge_debug_stats(XGE_ERR, 91173139Srwatson "can not map vaddr 0x"XGE_OS_LLXFMT" to DMA", 92173139Srwatson (unsigned long long)(ulong_t)stats->hw_info); 93173139Srwatson xge_os_dma_free(hldev->pdev, 94173139Srwatson stats->hw_info, 95173139Srwatson sizeof(xge_hal_stats_hw_info_t), 96173139Srwatson &stats->hw_info_dma_acch, 97173139Srwatson &stats->hw_info_dmah); 98173139Srwatson return XGE_HAL_ERR_OUT_OF_MAPPING; 99173139Srwatson } 100171095Ssam } 101171095Ssam else { 102173139Srwatson stats->pcim_info_saved = 103173139Srwatson (xge_hal_stats_pcim_info_t *)xge_os_malloc( 104173139Srwatson hldev->pdev, sizeof(xge_hal_stats_pcim_info_t)); 105173139Srwatson if (stats->pcim_info_saved == NULL) { 106173139Srwatson xge_debug_stats(XGE_ERR, "%s", "can not alloc"); 107173139Srwatson return XGE_HAL_ERR_OUT_OF_MEMORY; 108173139Srwatson } 109171095Ssam 110173139Srwatson stats->pcim_info_latest = 111173139Srwatson (xge_hal_stats_pcim_info_t *)xge_os_malloc( 112173139Srwatson hldev->pdev, sizeof(xge_hal_stats_pcim_info_t)); 113173139Srwatson if (stats->pcim_info_latest == NULL) { 114173139Srwatson xge_os_free(hldev->pdev, stats->pcim_info_saved, 115173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 116173139Srwatson xge_debug_stats(XGE_ERR, "%s", "can not alloc"); 117173139Srwatson return XGE_HAL_ERR_OUT_OF_MEMORY; 118173139Srwatson } 119171095Ssam 120173139Srwatson stats->pcim_info = 121173139Srwatson (xge_hal_stats_pcim_info_t *) xge_os_dma_malloc( 122173139Srwatson hldev->pdev, 123173139Srwatson sizeof(xge_hal_stats_pcim_info_t), 124173139Srwatson dma_flags, 125173139Srwatson &stats->hw_info_dmah, 126173139Srwatson &stats->hw_info_dma_acch); 127171095Ssam 128173139Srwatson if (stats->pcim_info == NULL) { 129173139Srwatson xge_os_free(hldev->pdev, stats->pcim_info_saved, 130173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 131173139Srwatson xge_os_free(hldev->pdev, stats->pcim_info_latest, 132173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 133173139Srwatson xge_debug_stats(XGE_ERR, "%s", "can not DMA alloc"); 134173139Srwatson return XGE_HAL_ERR_OUT_OF_MEMORY; 135173139Srwatson } 136171095Ssam 137171095Ssam 138173139Srwatson xge_os_memzero(stats->pcim_info, 139173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 140173139Srwatson xge_os_memzero(stats->pcim_info_saved, 141173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 142173139Srwatson xge_os_memzero(stats->pcim_info_latest, 143173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 144171095Ssam 145171095Ssam 146171095Ssam 147173139Srwatson stats->dma_addr = xge_os_dma_map(hldev->pdev, 148171095Ssam stats->hw_info_dmah, 149173139Srwatson stats->pcim_info, 150173139Srwatson sizeof(xge_hal_stats_pcim_info_t), 151173139Srwatson XGE_OS_DMA_DIR_FROMDEVICE, 152173139Srwatson XGE_OS_DMA_CACHELINE_ALIGNED | 153171095Ssam#ifdef XGE_HAL_DMA_STATS_CONSISTENT 154173139Srwatson XGE_OS_DMA_CONSISTENT 155171095Ssam#else 156173139Srwatson XGE_OS_DMA_STREAMING 157171095Ssam#endif 158173139Srwatson ); 159173139Srwatson if (stats->dma_addr == XGE_OS_INVALID_DMA_ADDR) { 160173139Srwatson xge_debug_stats(XGE_ERR, 161173139Srwatson "can not map vaddr 0x"XGE_OS_LLXFMT" to DMA", 162173139Srwatson (unsigned long long)(ulong_t)stats->hw_info); 163171095Ssam 164173139Srwatson xge_os_dma_free(hldev->pdev, 165173139Srwatson stats->pcim_info, 166173139Srwatson sizeof(xge_hal_stats_pcim_info_t), 167173139Srwatson &stats->hw_info_dma_acch, 168173139Srwatson &stats->hw_info_dmah); 169171095Ssam 170173139Srwatson xge_os_free(hldev->pdev, stats->pcim_info_saved, 171173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 172171095Ssam 173173139Srwatson xge_os_free(hldev->pdev, stats->pcim_info_latest, 174173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 175171095Ssam 176173139Srwatson return XGE_HAL_ERR_OUT_OF_MAPPING; 177173139Srwatson } 178171095Ssam } 179171095Ssam stats->devh = devh; 180171095Ssam xge_os_memzero(&stats->sw_dev_info_stats, 181173139Srwatson sizeof(xge_hal_stats_device_info_t)); 182171095Ssam 183171095Ssam stats->is_initialized = 1; 184171095Ssam 185171095Ssam return XGE_HAL_OK; 186171095Ssam} 187171095Ssam 188171095Ssamstatic void 189171095Ssam__hal_stats_save (xge_hal_stats_t *stats) 190171095Ssam{ 191171095Ssam xge_hal_device_t *hldev = (xge_hal_device_t*)stats->devh; 192171095Ssam 193171095Ssam if (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN) { 194173139Srwatson xge_hal_stats_hw_info_t *latest; 195171095Ssam 196173139Srwatson (void) xge_hal_stats_hw(stats->devh, &latest); 197171095Ssam 198173139Srwatson xge_os_memcpy(&stats->hw_info_saved, stats->hw_info, 199173139Srwatson sizeof(xge_hal_stats_hw_info_t)); 200171095Ssam } else { 201173139Srwatson xge_hal_stats_pcim_info_t *latest; 202171095Ssam 203173139Srwatson (void) xge_hal_stats_pcim(stats->devh, &latest); 204171095Ssam 205173139Srwatson xge_os_memcpy(stats->pcim_info_saved, stats->pcim_info, 206173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 207171095Ssam } 208171095Ssam} 209171095Ssam 210171095Ssam/* 211171095Ssam * __hal_stats_disable 212171095Ssam * @stats: xge_hal_stats_t structure that contains, in particular, 213171095Ssam * Xframe hw stat counters. 214171095Ssam * 215171095Ssam * Ask device to stop collecting stats. 216171095Ssam * See also: xge_hal_stats_getinfo(). 217171095Ssam */ 218171095Ssamvoid 219171095Ssam__hal_stats_disable (xge_hal_stats_t *stats) 220171095Ssam{ 221171095Ssam xge_hal_device_t *hldev; 222171095Ssam xge_hal_pci_bar0_t *bar0; 223171095Ssam u64 val64; 224171095Ssam 225171095Ssam xge_assert(stats->hw_info); 226171095Ssam 227171095Ssam hldev = (xge_hal_device_t*)stats->devh; 228171095Ssam xge_assert(hldev); 229171095Ssam bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0; 230171095Ssam 231171095Ssam val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 232173139Srwatson &bar0->stat_cfg); 233171095Ssam val64 &= ~XGE_HAL_STAT_CFG_STAT_EN; 234171095Ssam xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 235173139Srwatson &bar0->stat_cfg); 236171095Ssam /* flush the write */ 237171095Ssam (void)xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 238173139Srwatson &bar0->stat_cfg); 239171095Ssam 240171095Ssam xge_debug_stats(XGE_TRACE, "stats disabled at 0x"XGE_OS_LLXFMT, 241173139Srwatson (unsigned long long)stats->dma_addr); 242171095Ssam 243171095Ssam stats->is_enabled = 0; 244171095Ssam} 245171095Ssam 246171095Ssam/* 247171095Ssam * __hal_stats_terminate 248171095Ssam * @stats: xge_hal_stats_t structure that contains, in particular, 249171095Ssam * Xframe hw stat counters. 250171095Ssam * Terminate per-device statistics object. 251171095Ssam */ 252171095Ssamvoid 253171095Ssam__hal_stats_terminate (xge_hal_stats_t *stats) 254171095Ssam{ 255171095Ssam xge_hal_device_t *hldev; 256171095Ssam 257171095Ssam xge_assert(stats->hw_info); 258171095Ssam 259171095Ssam hldev = (xge_hal_device_t*)stats->devh; 260171095Ssam xge_assert(hldev); 261171095Ssam xge_assert(stats->is_initialized); 262171095Ssam if (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN) { 263173139Srwatson xge_os_dma_unmap(hldev->pdev, 264171095Ssam stats->hw_info_dmah, 265173139Srwatson stats->dma_addr, 266173139Srwatson sizeof(xge_hal_stats_hw_info_t), 267173139Srwatson XGE_OS_DMA_DIR_FROMDEVICE); 268171095Ssam 269173139Srwatson xge_os_dma_free(hldev->pdev, 270173139Srwatson stats->hw_info, 271173139Srwatson sizeof(xge_hal_stats_hw_info_t), 272173139Srwatson &stats->hw_info_dma_acch, 273173139Srwatson &stats->hw_info_dmah); 274171095Ssam } else { 275173139Srwatson xge_os_dma_unmap(hldev->pdev, 276171095Ssam stats->hw_info_dmah, 277173139Srwatson stats->dma_addr, 278173139Srwatson sizeof(xge_hal_stats_pcim_info_t), 279173139Srwatson XGE_OS_DMA_DIR_FROMDEVICE); 280171095Ssam 281173139Srwatson xge_os_dma_free(hldev->pdev, 282173139Srwatson stats->pcim_info, 283173139Srwatson sizeof(xge_hal_stats_pcim_info_t), 284173139Srwatson &stats->hw_info_dma_acch, 285173139Srwatson &stats->hw_info_dmah); 286171095Ssam 287173139Srwatson xge_os_free(hldev->pdev, stats->pcim_info_saved, 288173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 289171095Ssam 290173139Srwatson xge_os_free(hldev->pdev, stats->pcim_info_latest, 291173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 292171095Ssam 293171095Ssam } 294171095Ssam 295171095Ssam stats->is_initialized = 0; 296171095Ssam stats->is_enabled = 0; 297171095Ssam} 298171095Ssam 299171095Ssam 300171095Ssam 301171095Ssam/* 302171095Ssam * __hal_stats_enable 303171095Ssam * @stats: xge_hal_stats_t structure that contains, in particular, 304171095Ssam * Xframe hw stat counters. 305171095Ssam * 306171095Ssam * Ask device to start collecting stats. 307171095Ssam * See also: xge_hal_stats_getinfo(). 308171095Ssam */ 309171095Ssamvoid 310171095Ssam__hal_stats_enable (xge_hal_stats_t *stats) 311171095Ssam{ 312171095Ssam xge_hal_device_t *hldev; 313171095Ssam xge_hal_pci_bar0_t *bar0; 314171095Ssam u64 val64; 315171095Ssam unsigned int refresh_time_pci_clocks; 316171095Ssam 317171095Ssam xge_assert(stats->hw_info); 318171095Ssam 319171095Ssam hldev = (xge_hal_device_t*)stats->devh; 320171095Ssam xge_assert(hldev); 321171095Ssam 322171095Ssam bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0; 323171095Ssam 324171095Ssam /* enable statistics 325171095Ssam * For Titan stat_addr offset == 0x09d8, and stat_cfg offset == 0x09d0 326171095Ssam */ 327171095Ssam xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 328173139Srwatson stats->dma_addr, &bar0->stat_addr); 329171095Ssam 330171095Ssam refresh_time_pci_clocks = XGE_HAL_XENA_PER_SEC * 331173139Srwatson hldev->config.stats_refresh_time_sec; 332171095Ssam refresh_time_pci_clocks = 333173139Srwatson __hal_fix_time_ival_herc(hldev, 334173139Srwatson refresh_time_pci_clocks); 335171095Ssam 336171095Ssam#ifdef XGE_HAL_HERC_EMULATION 337171095Ssam /* 338171095Ssam * The clocks in the emulator are running ~1000 times slower 339171095Ssam * than real world, so the stats transfer will occur ~1000 340171095Ssam * times less frequent. STAT_CFG.STAT_TRSF_PERIOD should be 341171095Ssam * set to 0x20C for Hercules emulation (stats transferred 342171095Ssam * every 0.5 sec). 343171095Ssam */ 344171095Ssam 345171095Ssam val64 = (0x20C | XGE_HAL_STAT_CFG_STAT_RO | 346173139Srwatson XGE_HAL_STAT_CFG_STAT_EN); 347171095Ssam#else 348171095Ssam val64 = XGE_HAL_SET_UPDT_PERIOD(refresh_time_pci_clocks) | 349173139Srwatson XGE_HAL_STAT_CFG_STAT_RO | 350173139Srwatson XGE_HAL_STAT_CFG_STAT_EN; 351171095Ssam#endif 352171095Ssam 353171095Ssam xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 354173139Srwatson val64, &bar0->stat_cfg); 355171095Ssam 356171095Ssam xge_debug_stats(XGE_TRACE, "stats enabled at 0x"XGE_OS_LLXFMT, 357173139Srwatson (unsigned long long)stats->dma_addr); 358171095Ssam 359171095Ssam stats->is_enabled = 1; 360171095Ssam} 361171095Ssam 362171095Ssam/* 363171095Ssam * __hal_stats_pcim_update_latest - Update hw ER stats counters, based on the 364171095Ssam * real hardware maintained counters and the stored "reset" values. 365171095Ssam */ 366171095Ssamstatic void 367171095Ssam__hal_stats_pcim_update_latest(xge_hal_device_h devh) 368171095Ssam{ 369171095Ssam xge_hal_device_t *hldev = (xge_hal_device_t *)devh; 370171095Ssam int i; 371171095Ssam 372173139Srwatson#define set_latest_stat_link_cnt(_link, _p) \ 373173139Srwatson hldev->stats.pcim_info_latest->link_info[_link]._p = \ 374173139Srwatson ((hldev->stats.pcim_info->link_info[_link]._p >= \ 375173139Srwatson hldev->stats.pcim_info_saved->link_info[_link]._p) ? \ 376173139Srwatson hldev->stats.pcim_info->link_info[_link]._p - \ 377173139Srwatson hldev->stats.pcim_info_saved->link_info[_link]._p : \ 378173139Srwatson ((-1) - hldev->stats.pcim_info_saved->link_info[_link]._p) + \ 379173139Srwatson hldev->stats.pcim_info->link_info[_link]._p) 380171095Ssam 381171095Ssam 382173139Srwatson#define set_latest_stat_aggr_cnt(_aggr, _p) \ 383173139Srwatson hldev->stats.pcim_info_latest->aggr_info[_aggr]._p = \ 384173139Srwatson ((hldev->stats.pcim_info->aggr_info[_aggr]._p >= \ 385173139Srwatson hldev->stats.pcim_info_saved->aggr_info[_aggr]._p) ? \ 386173139Srwatson hldev->stats.pcim_info->aggr_info[_aggr]._p - \ 387173139Srwatson hldev->stats.pcim_info_saved->aggr_info[_aggr]._p : \ 388173139Srwatson ((-1) - hldev->stats.pcim_info_saved->aggr_info[_aggr]._p) + \ 389173139Srwatson hldev->stats.pcim_info->aggr_info[_aggr]._p) 390171095Ssam 391171095Ssam 392171095Ssam for (i = 0; i < XGE_HAL_MAC_LINKS; i++) { 393173139Srwatson set_latest_stat_link_cnt(i, tx_frms); 394173139Srwatson set_latest_stat_link_cnt(i, tx_ttl_eth_octets); 395173139Srwatson set_latest_stat_link_cnt(i, tx_data_octets); 396173139Srwatson set_latest_stat_link_cnt(i, tx_mcst_frms); 397173139Srwatson set_latest_stat_link_cnt(i, tx_bcst_frms); 398173139Srwatson set_latest_stat_link_cnt(i, tx_ucst_frms); 399173139Srwatson set_latest_stat_link_cnt(i, tx_tagged_frms); 400173139Srwatson set_latest_stat_link_cnt(i, tx_vld_ip); 401173139Srwatson set_latest_stat_link_cnt(i, tx_vld_ip_octets); 402173139Srwatson set_latest_stat_link_cnt(i, tx_icmp); 403173139Srwatson set_latest_stat_link_cnt(i, tx_tcp); 404173139Srwatson set_latest_stat_link_cnt(i, tx_rst_tcp); 405173139Srwatson set_latest_stat_link_cnt(i, tx_udp); 406173139Srwatson set_latest_stat_link_cnt(i, tx_unknown_protocol); 407173139Srwatson set_latest_stat_link_cnt(i, tx_parse_error); 408173139Srwatson set_latest_stat_link_cnt(i, tx_pause_ctrl_frms); 409173139Srwatson set_latest_stat_link_cnt(i, tx_lacpdu_frms); 410173139Srwatson set_latest_stat_link_cnt(i, tx_marker_pdu_frms); 411173139Srwatson set_latest_stat_link_cnt(i, tx_marker_resp_pdu_frms); 412173139Srwatson set_latest_stat_link_cnt(i, tx_drop_ip); 413173139Srwatson set_latest_stat_link_cnt(i, tx_xgmii_char1_match); 414173139Srwatson set_latest_stat_link_cnt(i, tx_xgmii_char2_match); 415173139Srwatson set_latest_stat_link_cnt(i, tx_xgmii_column1_match); 416173139Srwatson set_latest_stat_link_cnt(i, tx_xgmii_column2_match); 417173139Srwatson set_latest_stat_link_cnt(i, tx_drop_frms); 418173139Srwatson set_latest_stat_link_cnt(i, tx_any_err_frms); 419173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_frms); 420173139Srwatson set_latest_stat_link_cnt(i, rx_vld_frms); 421173139Srwatson set_latest_stat_link_cnt(i, rx_offld_frms); 422173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_eth_octets); 423173139Srwatson set_latest_stat_link_cnt(i, rx_data_octets); 424173139Srwatson set_latest_stat_link_cnt(i, rx_offld_octets); 425173139Srwatson set_latest_stat_link_cnt(i, rx_vld_mcst_frms); 426173139Srwatson set_latest_stat_link_cnt(i, rx_vld_bcst_frms); 427173139Srwatson set_latest_stat_link_cnt(i, rx_accepted_ucst_frms); 428173139Srwatson set_latest_stat_link_cnt(i, rx_accepted_nucst_frms); 429173139Srwatson set_latest_stat_link_cnt(i, rx_tagged_frms); 430173139Srwatson set_latest_stat_link_cnt(i, rx_long_frms); 431173139Srwatson set_latest_stat_link_cnt(i, rx_usized_frms); 432173139Srwatson set_latest_stat_link_cnt(i, rx_osized_frms); 433173139Srwatson set_latest_stat_link_cnt(i, rx_frag_frms); 434173139Srwatson set_latest_stat_link_cnt(i, rx_jabber_frms); 435173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_64_frms); 436173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_65_127_frms); 437173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_128_255_frms); 438173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_256_511_frms); 439173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_512_1023_frms); 440173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_1024_1518_frms); 441173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_1519_4095_frms); 442173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_40956_8191_frms); 443173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_8192_max_frms); 444173139Srwatson set_latest_stat_link_cnt(i, rx_ttl_gt_max_frms); 445173139Srwatson set_latest_stat_link_cnt(i, rx_ip); 446173139Srwatson set_latest_stat_link_cnt(i, rx_ip_octets); 447173139Srwatson set_latest_stat_link_cnt(i, rx_hdr_err_ip); 448173139Srwatson set_latest_stat_link_cnt(i, rx_icmp); 449173139Srwatson set_latest_stat_link_cnt(i, rx_tcp); 450173139Srwatson set_latest_stat_link_cnt(i, rx_udp); 451173139Srwatson set_latest_stat_link_cnt(i, rx_err_tcp); 452173139Srwatson set_latest_stat_link_cnt(i, rx_pause_cnt); 453173139Srwatson set_latest_stat_link_cnt(i, rx_pause_ctrl_frms); 454173139Srwatson set_latest_stat_link_cnt(i, rx_unsup_ctrl_frms); 455173139Srwatson set_latest_stat_link_cnt(i, rx_in_rng_len_err_frms); 456173139Srwatson set_latest_stat_link_cnt(i, rx_out_rng_len_err_frms); 457173139Srwatson set_latest_stat_link_cnt(i, rx_drop_frms); 458173139Srwatson set_latest_stat_link_cnt(i, rx_discarded_frms); 459173139Srwatson set_latest_stat_link_cnt(i, rx_drop_ip); 460173139Srwatson set_latest_stat_link_cnt(i, rx_err_drp_udp); 461173139Srwatson set_latest_stat_link_cnt(i, rx_lacpdu_frms); 462173139Srwatson set_latest_stat_link_cnt(i, rx_marker_pdu_frms); 463173139Srwatson set_latest_stat_link_cnt(i, rx_marker_resp_pdu_frms); 464173139Srwatson set_latest_stat_link_cnt(i, rx_unknown_pdu_frms); 465173139Srwatson set_latest_stat_link_cnt(i, rx_illegal_pdu_frms); 466173139Srwatson set_latest_stat_link_cnt(i, rx_fcs_discard); 467173139Srwatson set_latest_stat_link_cnt(i, rx_len_discard); 468173139Srwatson set_latest_stat_link_cnt(i, rx_pf_discard); 469173139Srwatson set_latest_stat_link_cnt(i, rx_trash_discard); 470173139Srwatson set_latest_stat_link_cnt(i, rx_rts_discard); 471173139Srwatson set_latest_stat_link_cnt(i, rx_wol_discard); 472173139Srwatson set_latest_stat_link_cnt(i, rx_red_discard); 473173139Srwatson set_latest_stat_link_cnt(i, rx_ingm_full_discard); 474173139Srwatson set_latest_stat_link_cnt(i, rx_xgmii_data_err_cnt); 475173139Srwatson set_latest_stat_link_cnt(i, rx_xgmii_ctrl_err_cnt); 476173139Srwatson set_latest_stat_link_cnt(i, rx_xgmii_err_sym); 477173139Srwatson set_latest_stat_link_cnt(i, rx_xgmii_char1_match); 478173139Srwatson set_latest_stat_link_cnt(i, rx_xgmii_char2_match); 479173139Srwatson set_latest_stat_link_cnt(i, rx_xgmii_column1_match); 480173139Srwatson set_latest_stat_link_cnt(i, rx_xgmii_column2_match); 481173139Srwatson set_latest_stat_link_cnt(i, rx_local_fault); 482173139Srwatson set_latest_stat_link_cnt(i, rx_remote_fault); 483173139Srwatson set_latest_stat_link_cnt(i, rx_queue_full); 484171095Ssam } 485171095Ssam 486171095Ssam for (i = 0; i < XGE_HAL_MAC_AGGREGATORS; i++) { 487173139Srwatson set_latest_stat_aggr_cnt(i, tx_frms); 488173139Srwatson set_latest_stat_aggr_cnt(i, tx_mcst_frms); 489173139Srwatson set_latest_stat_aggr_cnt(i, tx_bcst_frms); 490173139Srwatson set_latest_stat_aggr_cnt(i, tx_discarded_frms); 491173139Srwatson set_latest_stat_aggr_cnt(i, tx_errored_frms); 492173139Srwatson set_latest_stat_aggr_cnt(i, rx_frms); 493173139Srwatson set_latest_stat_aggr_cnt(i, rx_data_octets); 494173139Srwatson set_latest_stat_aggr_cnt(i, rx_mcst_frms); 495173139Srwatson set_latest_stat_aggr_cnt(i, rx_bcst_frms); 496173139Srwatson set_latest_stat_aggr_cnt(i, rx_discarded_frms); 497173139Srwatson set_latest_stat_aggr_cnt(i, rx_errored_frms); 498173139Srwatson set_latest_stat_aggr_cnt(i, rx_unknown_protocol_frms); 499171095Ssam } 500171095Ssam return; 501171095Ssam} 502171095Ssam 503171095Ssam/* 504171095Ssam * __hal_stats_update_latest - Update hw stats counters, based on the real 505171095Ssam * hardware maintained counters and the stored "reset" values. 506171095Ssam */ 507171095Ssamstatic void 508171095Ssam__hal_stats_update_latest(xge_hal_device_h devh) 509171095Ssam{ 510171095Ssam xge_hal_device_t *hldev = (xge_hal_device_t *)devh; 511171095Ssam 512171095Ssam#define set_latest_stat_cnt(_dev, _p) \ 513173139Srwatson hldev->stats.hw_info_latest._p = \ 514171095Ssam ((hldev->stats.hw_info->_p >= hldev->stats.hw_info_saved._p) ? \ 515173139Srwatson hldev->stats.hw_info->_p - hldev->stats.hw_info_saved._p : \ 516171095Ssam ((-1) - hldev->stats.hw_info_saved._p) + hldev->stats.hw_info->_p) 517171095Ssam 518171095Ssam if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN) { 519173139Srwatson __hal_stats_pcim_update_latest(devh); 520173139Srwatson return; 521171095Ssam } 522171095Ssam 523171095Ssam /* Tx MAC statistics counters. */ 524171095Ssam set_latest_stat_cnt(hldev, tmac_frms); 525171095Ssam set_latest_stat_cnt(hldev, tmac_data_octets); 526171095Ssam set_latest_stat_cnt(hldev, tmac_drop_frms); 527171095Ssam set_latest_stat_cnt(hldev, tmac_mcst_frms); 528171095Ssam set_latest_stat_cnt(hldev, tmac_bcst_frms); 529171095Ssam set_latest_stat_cnt(hldev, tmac_pause_ctrl_frms); 530171095Ssam set_latest_stat_cnt(hldev, tmac_ttl_octets); 531171095Ssam set_latest_stat_cnt(hldev, tmac_ucst_frms); 532171095Ssam set_latest_stat_cnt(hldev, tmac_nucst_frms); 533171095Ssam set_latest_stat_cnt(hldev, tmac_any_err_frms); 534171095Ssam set_latest_stat_cnt(hldev, tmac_ttl_less_fb_octets); 535171095Ssam set_latest_stat_cnt(hldev, tmac_vld_ip_octets); 536171095Ssam set_latest_stat_cnt(hldev, tmac_vld_ip); 537171095Ssam set_latest_stat_cnt(hldev, tmac_drop_ip); 538171095Ssam set_latest_stat_cnt(hldev, tmac_icmp); 539171095Ssam set_latest_stat_cnt(hldev, tmac_rst_tcp); 540171095Ssam set_latest_stat_cnt(hldev, tmac_tcp); 541171095Ssam set_latest_stat_cnt(hldev, tmac_udp); 542171095Ssam set_latest_stat_cnt(hldev, reserved_0); 543171095Ssam 544171095Ssam /* Rx MAC Statistics counters. */ 545171095Ssam set_latest_stat_cnt(hldev, rmac_vld_frms); 546171095Ssam set_latest_stat_cnt(hldev, rmac_data_octets); 547171095Ssam set_latest_stat_cnt(hldev, rmac_fcs_err_frms); 548171095Ssam set_latest_stat_cnt(hldev, rmac_drop_frms); 549171095Ssam set_latest_stat_cnt(hldev, rmac_vld_mcst_frms); 550171095Ssam set_latest_stat_cnt(hldev, rmac_vld_bcst_frms); 551171095Ssam set_latest_stat_cnt(hldev, rmac_in_rng_len_err_frms); 552171095Ssam set_latest_stat_cnt(hldev, rmac_out_rng_len_err_frms); 553171095Ssam set_latest_stat_cnt(hldev, rmac_long_frms); 554171095Ssam set_latest_stat_cnt(hldev, rmac_pause_ctrl_frms); 555171095Ssam set_latest_stat_cnt(hldev, rmac_unsup_ctrl_frms); 556171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_octets); 557171095Ssam set_latest_stat_cnt(hldev, rmac_accepted_ucst_frms); 558171095Ssam set_latest_stat_cnt(hldev, rmac_accepted_nucst_frms); 559171095Ssam set_latest_stat_cnt(hldev, rmac_discarded_frms); 560171095Ssam set_latest_stat_cnt(hldev, rmac_drop_events); 561171095Ssam set_latest_stat_cnt(hldev, reserved_1); 562171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_less_fb_octets); 563171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_frms); 564171095Ssam set_latest_stat_cnt(hldev, reserved_2); 565171095Ssam set_latest_stat_cnt(hldev, reserved_3); 566171095Ssam set_latest_stat_cnt(hldev, rmac_usized_frms); 567171095Ssam set_latest_stat_cnt(hldev, rmac_osized_frms); 568171095Ssam set_latest_stat_cnt(hldev, rmac_frag_frms); 569171095Ssam set_latest_stat_cnt(hldev, rmac_jabber_frms); 570171095Ssam set_latest_stat_cnt(hldev, reserved_4); 571171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_64_frms); 572171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_65_127_frms); 573171095Ssam set_latest_stat_cnt(hldev, reserved_5); 574171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_128_255_frms); 575171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_256_511_frms); 576171095Ssam set_latest_stat_cnt(hldev, reserved_6); 577171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_512_1023_frms); 578171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_1024_1518_frms); 579171095Ssam set_latest_stat_cnt(hldev, reserved_7); 580171095Ssam set_latest_stat_cnt(hldev, rmac_ip); 581171095Ssam set_latest_stat_cnt(hldev, rmac_ip_octets); 582171095Ssam set_latest_stat_cnt(hldev, rmac_hdr_err_ip); 583171095Ssam set_latest_stat_cnt(hldev, rmac_drop_ip); 584171095Ssam set_latest_stat_cnt(hldev, rmac_icmp); 585171095Ssam set_latest_stat_cnt(hldev, reserved_8); 586171095Ssam set_latest_stat_cnt(hldev, rmac_tcp); 587171095Ssam set_latest_stat_cnt(hldev, rmac_udp); 588171095Ssam set_latest_stat_cnt(hldev, rmac_err_drp_udp); 589171095Ssam set_latest_stat_cnt(hldev, rmac_xgmii_err_sym); 590171095Ssam set_latest_stat_cnt(hldev, rmac_frms_q0); 591171095Ssam set_latest_stat_cnt(hldev, rmac_frms_q1); 592171095Ssam set_latest_stat_cnt(hldev, rmac_frms_q2); 593171095Ssam set_latest_stat_cnt(hldev, rmac_frms_q3); 594171095Ssam set_latest_stat_cnt(hldev, rmac_frms_q4); 595171095Ssam set_latest_stat_cnt(hldev, rmac_frms_q5); 596171095Ssam set_latest_stat_cnt(hldev, rmac_frms_q6); 597171095Ssam set_latest_stat_cnt(hldev, rmac_frms_q7); 598171095Ssam set_latest_stat_cnt(hldev, rmac_full_q0); 599171095Ssam set_latest_stat_cnt(hldev, rmac_full_q1); 600171095Ssam set_latest_stat_cnt(hldev, rmac_full_q2); 601171095Ssam set_latest_stat_cnt(hldev, rmac_full_q3); 602171095Ssam set_latest_stat_cnt(hldev, rmac_full_q4); 603171095Ssam set_latest_stat_cnt(hldev, rmac_full_q5); 604171095Ssam set_latest_stat_cnt(hldev, rmac_full_q6); 605171095Ssam set_latest_stat_cnt(hldev, rmac_full_q7); 606171095Ssam set_latest_stat_cnt(hldev, rmac_pause_cnt); 607171095Ssam set_latest_stat_cnt(hldev, reserved_9); 608171095Ssam set_latest_stat_cnt(hldev, rmac_xgmii_data_err_cnt); 609171095Ssam set_latest_stat_cnt(hldev, rmac_xgmii_ctrl_err_cnt); 610171095Ssam set_latest_stat_cnt(hldev, rmac_accepted_ip); 611171095Ssam set_latest_stat_cnt(hldev, rmac_err_tcp); 612171095Ssam 613171095Ssam /* PCI/PCI-X Read transaction statistics. */ 614171095Ssam set_latest_stat_cnt(hldev, rd_req_cnt); 615171095Ssam set_latest_stat_cnt(hldev, new_rd_req_cnt); 616171095Ssam set_latest_stat_cnt(hldev, new_rd_req_rtry_cnt); 617171095Ssam set_latest_stat_cnt(hldev, rd_rtry_cnt); 618171095Ssam set_latest_stat_cnt(hldev, wr_rtry_rd_ack_cnt); 619171095Ssam 620171095Ssam /* PCI/PCI-X write transaction statistics. */ 621171095Ssam set_latest_stat_cnt(hldev, wr_req_cnt); 622171095Ssam set_latest_stat_cnt(hldev, new_wr_req_cnt); 623171095Ssam set_latest_stat_cnt(hldev, new_wr_req_rtry_cnt); 624171095Ssam set_latest_stat_cnt(hldev, wr_rtry_cnt); 625171095Ssam set_latest_stat_cnt(hldev, wr_disc_cnt); 626171095Ssam set_latest_stat_cnt(hldev, rd_rtry_wr_ack_cnt); 627171095Ssam 628171095Ssam /* DMA Transaction statistics. */ 629171095Ssam set_latest_stat_cnt(hldev, txp_wr_cnt); 630171095Ssam set_latest_stat_cnt(hldev, txd_rd_cnt); 631171095Ssam set_latest_stat_cnt(hldev, txd_wr_cnt); 632171095Ssam set_latest_stat_cnt(hldev, rxd_rd_cnt); 633171095Ssam set_latest_stat_cnt(hldev, rxd_wr_cnt); 634171095Ssam set_latest_stat_cnt(hldev, txf_rd_cnt); 635171095Ssam set_latest_stat_cnt(hldev, rxf_wr_cnt); 636171095Ssam 637171095Ssam /* Enhanced Herc statistics */ 638171095Ssam set_latest_stat_cnt(hldev, tmac_frms_oflow); 639171095Ssam set_latest_stat_cnt(hldev, tmac_data_octets_oflow); 640171095Ssam set_latest_stat_cnt(hldev, tmac_mcst_frms_oflow); 641171095Ssam set_latest_stat_cnt(hldev, tmac_bcst_frms_oflow); 642171095Ssam set_latest_stat_cnt(hldev, tmac_ttl_octets_oflow); 643171095Ssam set_latest_stat_cnt(hldev, tmac_ucst_frms_oflow); 644171095Ssam set_latest_stat_cnt(hldev, tmac_nucst_frms_oflow); 645171095Ssam set_latest_stat_cnt(hldev, tmac_any_err_frms_oflow); 646171095Ssam set_latest_stat_cnt(hldev, tmac_vlan_frms); 647171095Ssam set_latest_stat_cnt(hldev, tmac_vld_ip_oflow); 648171095Ssam set_latest_stat_cnt(hldev, tmac_drop_ip_oflow); 649171095Ssam set_latest_stat_cnt(hldev, tmac_icmp_oflow); 650171095Ssam set_latest_stat_cnt(hldev, tmac_rst_tcp_oflow); 651171095Ssam set_latest_stat_cnt(hldev, tmac_udp_oflow); 652171095Ssam set_latest_stat_cnt(hldev, tpa_unknown_protocol); 653171095Ssam set_latest_stat_cnt(hldev, tpa_parse_failure); 654171095Ssam set_latest_stat_cnt(hldev, rmac_vld_frms_oflow); 655171095Ssam set_latest_stat_cnt(hldev, rmac_data_octets_oflow); 656171095Ssam set_latest_stat_cnt(hldev, rmac_vld_mcst_frms_oflow); 657171095Ssam set_latest_stat_cnt(hldev, rmac_vld_bcst_frms_oflow); 658171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_octets_oflow); 659171095Ssam set_latest_stat_cnt(hldev, rmac_accepted_ucst_frms_oflow); 660171095Ssam set_latest_stat_cnt(hldev, rmac_accepted_nucst_frms_oflow); 661171095Ssam set_latest_stat_cnt(hldev, rmac_discarded_frms_oflow); 662171095Ssam set_latest_stat_cnt(hldev, rmac_drop_events_oflow); 663171095Ssam set_latest_stat_cnt(hldev, rmac_usized_frms_oflow); 664171095Ssam set_latest_stat_cnt(hldev, rmac_osized_frms_oflow); 665171095Ssam set_latest_stat_cnt(hldev, rmac_frag_frms_oflow); 666171095Ssam set_latest_stat_cnt(hldev, rmac_jabber_frms_oflow); 667171095Ssam set_latest_stat_cnt(hldev, rmac_ip_oflow); 668171095Ssam set_latest_stat_cnt(hldev, rmac_drop_ip_oflow); 669171095Ssam set_latest_stat_cnt(hldev, rmac_icmp_oflow); 670171095Ssam set_latest_stat_cnt(hldev, rmac_udp_oflow); 671171095Ssam set_latest_stat_cnt(hldev, rmac_err_drp_udp_oflow); 672171095Ssam set_latest_stat_cnt(hldev, rmac_pause_cnt_oflow); 673171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_1519_4095_frms); 674171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_4096_8191_frms); 675171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_8192_max_frms); 676171095Ssam set_latest_stat_cnt(hldev, rmac_ttl_gt_max_frms); 677171095Ssam set_latest_stat_cnt(hldev, rmac_osized_alt_frms); 678171095Ssam set_latest_stat_cnt(hldev, rmac_jabber_alt_frms); 679171095Ssam set_latest_stat_cnt(hldev, rmac_gt_max_alt_frms); 680171095Ssam set_latest_stat_cnt(hldev, rmac_vlan_frms); 681171095Ssam set_latest_stat_cnt(hldev, rmac_fcs_discard); 682171095Ssam set_latest_stat_cnt(hldev, rmac_len_discard); 683171095Ssam set_latest_stat_cnt(hldev, rmac_da_discard); 684171095Ssam set_latest_stat_cnt(hldev, rmac_pf_discard); 685171095Ssam set_latest_stat_cnt(hldev, rmac_rts_discard); 686171095Ssam set_latest_stat_cnt(hldev, rmac_red_discard); 687171095Ssam set_latest_stat_cnt(hldev, rmac_ingm_full_discard); 688171095Ssam set_latest_stat_cnt(hldev, rmac_accepted_ip_oflow); 689171095Ssam set_latest_stat_cnt(hldev, link_fault_cnt); 690171095Ssam} 691171095Ssam 692171095Ssam/** 693171095Ssam * xge_hal_stats_hw - Get HW device statistics. 694171095Ssam * @devh: HAL device handle. 695171095Ssam * @hw_info: Xframe statistic counters. See xge_hal_stats_hw_info_t. 696171095Ssam * Returned by HAL. 697171095Ssam * 698171095Ssam * Get device and HAL statistics. The latter is part of the in-host statistics 699171095Ssam * that HAL maintains for _that_ device. 700171095Ssam * 701171095Ssam * Returns: XGE_HAL_OK - success. 702171095Ssam * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not 703171095Ssam * currently available. 704171095Ssam * 705171095Ssam * See also: xge_hal_status_e{}. 706171095Ssam */ 707171095Ssamxge_hal_status_e 708171095Ssamxge_hal_stats_hw(xge_hal_device_h devh, xge_hal_stats_hw_info_t **hw_info) 709171095Ssam{ 710171095Ssam xge_hal_device_t *hldev = (xge_hal_device_t *)devh; 711171095Ssam 712171095Ssam xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN) 713171095Ssam 714171095Ssam if (!hldev->stats.is_initialized || 715171095Ssam !hldev->stats.is_enabled) { 716173139Srwatson *hw_info = NULL; 717173139Srwatson return XGE_HAL_INF_STATS_IS_NOT_READY; 718171095Ssam } 719171095Ssam 720171095Ssam#if defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_STATS_STREAMING) 721171095Ssam xge_os_dma_sync(hldev->pdev, 722171095Ssam hldev->stats.hw_info_dmah, 723173139Srwatson hldev->stats.dma_addr, 724173139Srwatson 0, 725173139Srwatson sizeof(xge_hal_stats_hw_info_t), 726173139Srwatson XGE_OS_DMA_DIR_FROMDEVICE); 727171095Ssam#endif 728171095Ssam 729173139Srwatson /* 730171095Ssam * update hw counters, taking into account 731171095Ssam * the "reset" or "saved" 732171095Ssam * values 733171095Ssam */ 734171095Ssam __hal_stats_update_latest(devh); 735171095Ssam 736171095Ssam /* 737171095Ssam * statistics HW bug fixups for Xena and Herc 738171095Ssam */ 739171095Ssam if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA || 740171095Ssam xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) { 741173139Srwatson u64 mcst, bcst; 742173139Srwatson xge_hal_stats_hw_info_t *hwsta = &hldev->stats.hw_info_latest; 743171095Ssam 744173139Srwatson mcst = ((u64)hwsta->rmac_vld_mcst_frms_oflow << 32) | 745173139Srwatson hwsta->rmac_vld_mcst_frms; 746171095Ssam 747173139Srwatson bcst = ((u64)hwsta->rmac_vld_bcst_frms_oflow << 32) | 748173139Srwatson hwsta->rmac_vld_bcst_frms; 749171095Ssam 750173139Srwatson mcst -= bcst; 751171095Ssam 752173139Srwatson hwsta->rmac_vld_mcst_frms_oflow = (u32)(mcst >> 32); 753173139Srwatson hwsta->rmac_vld_mcst_frms = (u32)mcst; 754171095Ssam } 755171095Ssam 756171095Ssam *hw_info = &hldev->stats.hw_info_latest; 757171095Ssam 758171095Ssam return XGE_HAL_OK; 759171095Ssam} 760171095Ssam 761171095Ssam/** 762171095Ssam * xge_hal_stats_pcim - Get HW device statistics. 763171095Ssam * @devh: HAL device handle. 764171095Ssam * @hw_info: Xframe statistic counters. See xge_hal_stats_pcim_info_t. 765171095Ssam * 766171095Ssam * Returns: XGE_HAL_OK - success. 767171095Ssam * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not 768171095Ssam * currently available. 769171095Ssam * 770171095Ssam * See also: xge_hal_status_e{}. 771171095Ssam */ 772171095Ssamxge_hal_status_e 773171095Ssamxge_hal_stats_pcim(xge_hal_device_h devh, xge_hal_stats_pcim_info_t **hw_info) 774171095Ssam{ 775171095Ssam xge_hal_device_t *hldev = (xge_hal_device_t *)devh; 776171095Ssam 777171095Ssam xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN) 778171095Ssam 779171095Ssam if (!hldev->stats.is_initialized || 780171095Ssam !hldev->stats.is_enabled) { 781173139Srwatson *hw_info = NULL; 782173139Srwatson return XGE_HAL_INF_STATS_IS_NOT_READY; 783171095Ssam } 784171095Ssam 785171095Ssam#if defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_STATS_STREAMING) 786171095Ssam xge_os_dma_sync(hldev->pdev, 787171095Ssam hldev->stats.hw_info_dmah, 788173139Srwatson hldev->stats.dma_addr, 789173139Srwatson 0, 790173139Srwatson sizeof(xge_hal_stats_pcim_info_t), 791173139Srwatson XGE_OS_DMA_DIR_FROMDEVICE); 792171095Ssam#endif 793171095Ssam 794173139Srwatson /* 795171095Ssam * update hw counters, taking into account 796171095Ssam * the "reset" or "saved" 797171095Ssam * values 798171095Ssam */ 799171095Ssam __hal_stats_pcim_update_latest(devh); 800171095Ssam 801171095Ssam *hw_info = hldev->stats.pcim_info_latest; 802171095Ssam 803171095Ssam return XGE_HAL_OK; 804171095Ssam} 805171095Ssam 806171095Ssam/** 807171095Ssam * xge_hal_stats_device - Get HAL statistics. 808171095Ssam * @devh: HAL device handle. 809171095Ssam * @hw_info: Xframe statistic counters. See xge_hal_stats_hw_info_t. 810171095Ssam * Returned by HAL. 811171095Ssam * @device_info: HAL statistics. See xge_hal_stats_device_info_t. 812171095Ssam * Returned by HAL. 813171095Ssam * 814171095Ssam * Get device and HAL statistics. The latter is part of the in-host statistics 815171095Ssam * that HAL maintains for _that_ device. 816171095Ssam * 817171095Ssam * Returns: XGE_HAL_OK - success. 818171095Ssam * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not 819171095Ssam * currently available. 820171095Ssam * 821171095Ssam * See also: xge_hal_status_e{}. 822171095Ssam */ 823171095Ssamxge_hal_status_e 824171095Ssamxge_hal_stats_device(xge_hal_device_h devh, 825173139Srwatson xge_hal_stats_device_info_t **device_info) 826171095Ssam{ 827171095Ssam xge_hal_device_t *hldev = (xge_hal_device_t *)devh; 828171095Ssam 829171095Ssam if (!hldev->stats.is_initialized || 830171095Ssam !hldev->stats.is_enabled) { 831173139Srwatson *device_info = NULL; 832173139Srwatson return XGE_HAL_INF_STATS_IS_NOT_READY; 833171095Ssam } 834171095Ssam 835171095Ssam hldev->stats.sw_dev_info_stats.traffic_intr_cnt = 836173139Srwatson hldev->stats.sw_dev_info_stats.total_intr_cnt - 837173139Srwatson hldev->stats.sw_dev_info_stats.not_traffic_intr_cnt; 838171095Ssam 839171095Ssam *device_info = &hldev->stats.sw_dev_info_stats; 840171095Ssam 841171095Ssam return XGE_HAL_OK; 842171095Ssam} 843171095Ssam 844171095Ssam/** 845171095Ssam * xge_hal_stats_channel - Get channel statistics. 846171095Ssam * @channelh: Channel handle. 847171095Ssam * @channel_info: HAL channel statistic counters. 848171095Ssam * See xge_hal_stats_channel_info_t{}. Returned by HAL. 849171095Ssam * 850171095Ssam * Retrieve statistics of a particular HAL channel. This includes, for instance, 851171095Ssam * number of completions per interrupt, number of traffic interrupts, etc. 852171095Ssam * 853171095Ssam * Returns: XGE_HAL_OK - success. 854171095Ssam * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not 855171095Ssam * currently available. 856171095Ssam * 857171095Ssam * See also: xge_hal_status_e{}. 858171095Ssam */ 859171095Ssamxge_hal_status_e 860171095Ssamxge_hal_stats_channel(xge_hal_channel_h channelh, 861173139Srwatson xge_hal_stats_channel_info_t **channel_info) 862171095Ssam{ 863173139Srwatson xge_hal_stats_hw_info_t *latest; 864171095Ssam xge_hal_channel_t *channel; 865171095Ssam xge_hal_device_t *hldev; 866171095Ssam 867171095Ssam channel = (xge_hal_channel_t *)channelh; 868173139Srwatson if ((channel == NULL) || (channel->magic != XGE_HAL_MAGIC)) { 869173139Srwatson return XGE_HAL_ERR_INVALID_DEVICE; 870173139Srwatson } 871171095Ssam hldev = (xge_hal_device_t *)channel->devh; 872171095Ssam if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) { 873173139Srwatson return XGE_HAL_ERR_INVALID_DEVICE; 874171095Ssam } 875171095Ssam 876171095Ssam if (!hldev->stats.is_initialized || 877171095Ssam !hldev->stats.is_enabled || 878171095Ssam !channel->is_open) { 879173139Srwatson *channel_info = NULL; 880173139Srwatson return XGE_HAL_INF_STATS_IS_NOT_READY; 881171095Ssam } 882171095Ssam 883171095Ssam hldev->stats.sw_dev_info_stats.traffic_intr_cnt = 884173139Srwatson hldev->stats.sw_dev_info_stats.total_intr_cnt - 885173139Srwatson hldev->stats.sw_dev_info_stats.not_traffic_intr_cnt; 886171095Ssam 887171095Ssam if (hldev->stats.sw_dev_info_stats.traffic_intr_cnt) { 888173139Srwatson int rxcnt = hldev->stats.sw_dev_info_stats.rx_traffic_intr_cnt; 889173139Srwatson int txcnt = hldev->stats.sw_dev_info_stats.tx_traffic_intr_cnt; 890173139Srwatson if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) { 891173139Srwatson if (!txcnt) 892173139Srwatson txcnt = 1; 893173139Srwatson channel->stats.avg_compl_per_intr_cnt = 894173139Srwatson channel->stats.total_compl_cnt / txcnt; 895173139Srwatson } else if (channel->type == XGE_HAL_CHANNEL_TYPE_RING && 896173139Srwatson !hldev->config.bimodal_interrupts) { 897173139Srwatson if (!rxcnt) 898173139Srwatson rxcnt = 1; 899173139Srwatson channel->stats.avg_compl_per_intr_cnt = 900173139Srwatson channel->stats.total_compl_cnt / rxcnt; 901173139Srwatson } 902173139Srwatson if (channel->stats.avg_compl_per_intr_cnt == 0) { 903173139Srwatson /* to not confuse user */ 904173139Srwatson channel->stats.avg_compl_per_intr_cnt = 1; 905173139Srwatson } 906171095Ssam } 907171095Ssam 908171095Ssam (void) xge_hal_stats_hw(hldev, &latest); 909171095Ssam 910171095Ssam if (channel->stats.total_posts) { 911173139Srwatson channel->stats.avg_buffers_per_post = 912173139Srwatson channel->stats.total_buffers / 913173139Srwatson channel->stats.total_posts; 914171095Ssam#ifdef XGE_OS_PLATFORM_64BIT 915171095Ssam if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) { 916173139Srwatson channel->stats.avg_post_size = 917173139Srwatson (u32)(latest->tmac_ttl_less_fb_octets / 918173139Srwatson channel->stats.total_posts); 919171095Ssam } 920171095Ssam#endif 921171095Ssam } 922171095Ssam 923171095Ssam#ifdef XGE_OS_PLATFORM_64BIT 924171095Ssam if (channel->stats.total_buffers && 925171095Ssam channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) { 926173139Srwatson channel->stats.avg_buffer_size = 927173139Srwatson (u32)(latest->tmac_ttl_less_fb_octets / 928173139Srwatson channel->stats.total_buffers); 929171095Ssam } 930171095Ssam#endif 931171095Ssam 932171095Ssam *channel_info = &channel->stats; 933171095Ssam return XGE_HAL_OK; 934171095Ssam} 935171095Ssam 936171095Ssam/** 937171095Ssam * xge_hal_stats_reset - Reset (zero-out) device statistics 938171095Ssam * @devh: HAL device handle. 939171095Ssam * 940171095Ssam * Reset all device statistics. 941171095Ssam * Returns: XGE_HAL_OK - success. 942171095Ssam * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not 943171095Ssam * currently available. 944171095Ssam * 945171095Ssam * See also: xge_hal_status_e{}, xge_hal_stats_channel_info_t{}, 946171095Ssam * xge_hal_stats_sw_err_t{}, xge_hal_stats_device_info_t{}. 947171095Ssam */ 948171095Ssamxge_hal_status_e 949171095Ssamxge_hal_stats_reset(xge_hal_device_h devh) 950171095Ssam{ 951171095Ssam xge_hal_device_t *hldev = (xge_hal_device_t *)devh; 952171095Ssam 953171095Ssam if (!hldev->stats.is_initialized || 954171095Ssam !hldev->stats.is_enabled) { 955173139Srwatson return XGE_HAL_INF_STATS_IS_NOT_READY; 956171095Ssam } 957171095Ssam 958171095Ssam /* save hw stats to calculate the after-reset values */ 959171095Ssam __hal_stats_save(&hldev->stats); 960171095Ssam 961171095Ssam /* zero-out driver-maintained stats, don't reset the saved */ 962173139Srwatson __hal_stats_soft_reset(hldev, 0); 963171095Ssam 964171095Ssam return XGE_HAL_OK; 965171095Ssam} 966171095Ssam 967171095Ssam/* 968171095Ssam * __hal_stats_soft_reset - Reset software-maintained statistics. 969171095Ssam */ 970171095Ssamvoid 971171095Ssam__hal_stats_soft_reset (xge_hal_device_h devh, int reset_all) 972171095Ssam{ 973171095Ssam xge_list_t *item; 974171095Ssam xge_hal_channel_t *channel; 975171095Ssam xge_hal_device_t *hldev = (xge_hal_device_t *)devh; 976171095Ssam 977173139Srwatson if (reset_all) { 978173139Srwatson if (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN) { 979173139Srwatson xge_os_memzero(&hldev->stats.hw_info_saved, 980173139Srwatson sizeof(xge_hal_stats_hw_info_t)); 981173139Srwatson xge_os_memzero(&hldev->stats.hw_info_latest, 982173139Srwatson sizeof(xge_hal_stats_hw_info_t)); 983173139Srwatson } else { 984173139Srwatson xge_os_memzero(&hldev->stats.pcim_info_saved, 985173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 986173139Srwatson xge_os_memzero(&hldev->stats.pcim_info_latest, 987173139Srwatson sizeof(xge_hal_stats_pcim_info_t)); 988173139Srwatson } 989173139Srwatson } 990171095Ssam 991171095Ssam /* Reset the "soft" error and informational statistics */ 992171095Ssam xge_os_memzero(&hldev->stats.sw_dev_err_stats, 993171095Ssam sizeof(xge_hal_stats_sw_err_t)); 994171095Ssam xge_os_memzero(&hldev->stats.sw_dev_info_stats, 995171095Ssam sizeof(xge_hal_stats_device_info_t)); 996171095Ssam 997171095Ssam /* for each Rx channel */ 998171095Ssam xge_list_for_each(item, &hldev->ring_channels) { 999173139Srwatson channel = xge_container_of(item, xge_hal_channel_t, item); 1000173139Srwatson xge_os_memzero(&channel->stats, 1001173139Srwatson sizeof(xge_hal_stats_channel_info_t)); 1002171095Ssam } 1003171095Ssam 1004171095Ssam /* for each Tx channel */ 1005171095Ssam xge_list_for_each(item, &hldev->fifo_channels) { 1006173139Srwatson channel = xge_container_of(item, xge_hal_channel_t, item); 1007173139Srwatson xge_os_memzero(&channel->stats, 1008173139Srwatson sizeof(xge_hal_stats_channel_info_t)); 1009171095Ssam } 1010171095Ssam} 1011171095Ssam 1012