1 /*-
2  * Copyright (c) 2002-2007 Neterion, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: stable/9/sys/dev/nxge/xgehal/xgehal-stats.c 173139 2007-10-29 14:19:32Z rwatson $
27  */
28 
29 #include <dev/nxge/include/xgehal-stats.h>
30 #include <dev/nxge/include/xgehal-device.h>
31 
32 /*
33  * __hal_stats_initialize
34  * @stats: xge_hal_stats_t structure that contains, in particular,
35  *         Xframe hw stat counters.
36  * @devh: HAL device handle.
37  *
38  * Initialize per-device statistics object.
39  * See also: xge_hal_stats_getinfo(), xge_hal_status_e{}.
40  */
41 xge_hal_status_e
__hal_stats_initialize(xge_hal_stats_t * stats,xge_hal_device_h devh)42 __hal_stats_initialize (xge_hal_stats_t *stats, xge_hal_device_h devh)
43 {
44 	int dma_flags;
45 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
46 
47 	xge_assert(!stats->is_initialized);
48 
49 	dma_flags = XGE_OS_DMA_CACHELINE_ALIGNED;
50 #ifdef XGE_HAL_DMA_STATS_CONSISTENT
51 	dma_flags |= XGE_OS_DMA_CONSISTENT;
52 #else
53 	dma_flags |= XGE_OS_DMA_STREAMING;
54 #endif
55 	if (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN) {
56 	    stats->hw_info =
57 	        (xge_hal_stats_hw_info_t *) xge_os_dma_malloc(
58 	                hldev->pdev,
59 	                sizeof(xge_hal_stats_hw_info_t),
60 	                dma_flags,
61 	                &stats->hw_info_dmah,
62 	                &stats->hw_info_dma_acch);
63 
64 	    if (stats->hw_info == NULL) {
65 	        xge_debug_stats(XGE_ERR, "%s", "can not DMA alloc");
66 	        return XGE_HAL_ERR_OUT_OF_MEMORY;
67 	    }
68 	    xge_os_memzero(stats->hw_info,
69 	        sizeof(xge_hal_stats_hw_info_t));
70 	    xge_os_memzero(&stats->hw_info_saved,
71 	        sizeof(xge_hal_stats_hw_info_t));
72 	    xge_os_memzero(&stats->hw_info_latest,
73 	        sizeof(xge_hal_stats_hw_info_t));
74 
75 
76 
77 	    stats->dma_addr = xge_os_dma_map(hldev->pdev,
78 	                               stats->hw_info_dmah,
79 	                   stats->hw_info,
80 	                   sizeof(xge_hal_stats_hw_info_t),
81 	                   XGE_OS_DMA_DIR_FROMDEVICE,
82 	                   XGE_OS_DMA_CACHELINE_ALIGNED |
83 #ifdef XGE_HAL_DMA_STATS_CONSISTENT
84 	                   XGE_OS_DMA_CONSISTENT
85 #else
86 	                       XGE_OS_DMA_STREAMING
87 #endif
88 	                                   );
89 	    if (stats->dma_addr == XGE_OS_INVALID_DMA_ADDR) {
90 	        xge_debug_stats(XGE_ERR,
91 	            "can not map vaddr 0x"XGE_OS_LLXFMT" to DMA",
92 	            (unsigned long long)(ulong_t)stats->hw_info);
93 	        xge_os_dma_free(hldev->pdev,
94 	              stats->hw_info,
95 	              sizeof(xge_hal_stats_hw_info_t),
96 	              &stats->hw_info_dma_acch,
97 	              &stats->hw_info_dmah);
98 	        return XGE_HAL_ERR_OUT_OF_MAPPING;
99 	    }
100 	}
101 	else {
102 	    stats->pcim_info_saved =
103 	        (xge_hal_stats_pcim_info_t *)xge_os_malloc(
104 	        hldev->pdev, sizeof(xge_hal_stats_pcim_info_t));
105 	    if (stats->pcim_info_saved == NULL) {
106 	        xge_debug_stats(XGE_ERR, "%s", "can not alloc");
107 	        return XGE_HAL_ERR_OUT_OF_MEMORY;
108 	    }
109 
110 	    stats->pcim_info_latest =
111 	        (xge_hal_stats_pcim_info_t *)xge_os_malloc(
112 	        hldev->pdev, sizeof(xge_hal_stats_pcim_info_t));
113 	    if (stats->pcim_info_latest == NULL) {
114 	        xge_os_free(hldev->pdev, stats->pcim_info_saved,
115 	            sizeof(xge_hal_stats_pcim_info_t));
116 	        xge_debug_stats(XGE_ERR, "%s", "can not alloc");
117 	        return XGE_HAL_ERR_OUT_OF_MEMORY;
118 	    }
119 
120 	    stats->pcim_info =
121 	        (xge_hal_stats_pcim_info_t *) xge_os_dma_malloc(
122 	                hldev->pdev,
123 	                sizeof(xge_hal_stats_pcim_info_t),
124 	                dma_flags,
125 	                &stats->hw_info_dmah,
126 	                &stats->hw_info_dma_acch);
127 
128 	    if (stats->pcim_info == NULL) {
129 	        xge_os_free(hldev->pdev, stats->pcim_info_saved,
130 	            sizeof(xge_hal_stats_pcim_info_t));
131 	        xge_os_free(hldev->pdev, stats->pcim_info_latest,
132 	            sizeof(xge_hal_stats_pcim_info_t));
133 	        xge_debug_stats(XGE_ERR, "%s", "can not DMA alloc");
134 	        return XGE_HAL_ERR_OUT_OF_MEMORY;
135 	    }
136 
137 
138 	    xge_os_memzero(stats->pcim_info,
139 	        sizeof(xge_hal_stats_pcim_info_t));
140 	    xge_os_memzero(stats->pcim_info_saved,
141 	        sizeof(xge_hal_stats_pcim_info_t));
142 	    xge_os_memzero(stats->pcim_info_latest,
143 	        sizeof(xge_hal_stats_pcim_info_t));
144 
145 
146 
147 	    stats->dma_addr = xge_os_dma_map(hldev->pdev,
148 	                               stats->hw_info_dmah,
149 	                   stats->pcim_info,
150 	                   sizeof(xge_hal_stats_pcim_info_t),
151 	                   XGE_OS_DMA_DIR_FROMDEVICE,
152 	                   XGE_OS_DMA_CACHELINE_ALIGNED |
153 #ifdef XGE_HAL_DMA_STATS_CONSISTENT
154 	                   XGE_OS_DMA_CONSISTENT
155 #else
156 	                       XGE_OS_DMA_STREAMING
157 #endif
158 	                                   );
159 	    if (stats->dma_addr == XGE_OS_INVALID_DMA_ADDR) {
160 	        xge_debug_stats(XGE_ERR,
161 	            "can not map vaddr 0x"XGE_OS_LLXFMT" to DMA",
162 	            (unsigned long long)(ulong_t)stats->hw_info);
163 
164 	        xge_os_dma_free(hldev->pdev,
165 	              stats->pcim_info,
166 	              sizeof(xge_hal_stats_pcim_info_t),
167 	              &stats->hw_info_dma_acch,
168 	              &stats->hw_info_dmah);
169 
170 	        xge_os_free(hldev->pdev, stats->pcim_info_saved,
171 	            sizeof(xge_hal_stats_pcim_info_t));
172 
173 	        xge_os_free(hldev->pdev, stats->pcim_info_latest,
174 	            sizeof(xge_hal_stats_pcim_info_t));
175 
176 	        return XGE_HAL_ERR_OUT_OF_MAPPING;
177 	    }
178 	}
179 	stats->devh = devh;
180 	xge_os_memzero(&stats->sw_dev_info_stats,
181 	         sizeof(xge_hal_stats_device_info_t));
182 
183 	stats->is_initialized = 1;
184 
185 	return XGE_HAL_OK;
186 }
187 
188 static void
__hal_stats_save(xge_hal_stats_t * stats)189 __hal_stats_save (xge_hal_stats_t *stats)
190 {
191 	xge_hal_device_t *hldev = (xge_hal_device_t*)stats->devh;
192 
193 	if (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN) {
194 	    xge_hal_stats_hw_info_t *latest;
195 
196 	    (void) xge_hal_stats_hw(stats->devh, &latest);
197 
198 	    xge_os_memcpy(&stats->hw_info_saved, stats->hw_info,
199 	          sizeof(xge_hal_stats_hw_info_t));
200 	} else {
201 	    xge_hal_stats_pcim_info_t   *latest;
202 
203 	    (void) xge_hal_stats_pcim(stats->devh, &latest);
204 
205 	    xge_os_memcpy(stats->pcim_info_saved, stats->pcim_info,
206 	          sizeof(xge_hal_stats_pcim_info_t));
207 	}
208 }
209 
210 /*
211  * __hal_stats_disable
212  * @stats: xge_hal_stats_t structure that contains, in particular,
213  *         Xframe hw stat counters.
214  *
215  * Ask device to stop collecting stats.
216  * See also: xge_hal_stats_getinfo().
217  */
218 void
__hal_stats_disable(xge_hal_stats_t * stats)219 __hal_stats_disable (xge_hal_stats_t *stats)
220 {
221 	xge_hal_device_t *hldev;
222 	xge_hal_pci_bar0_t *bar0;
223 	u64 val64;
224 
225 	xge_assert(stats->hw_info);
226 
227 	hldev = (xge_hal_device_t*)stats->devh;
228 	xge_assert(hldev);
229 	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
230 
231 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
232 	    &bar0->stat_cfg);
233 	val64 &= ~XGE_HAL_STAT_CFG_STAT_EN;
234 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
235 	    &bar0->stat_cfg);
236 	/* flush the write */
237 	(void)xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
238 	    &bar0->stat_cfg);
239 
240 	xge_debug_stats(XGE_TRACE, "stats disabled at 0x"XGE_OS_LLXFMT,
241 	     (unsigned long long)stats->dma_addr);
242 
243 	stats->is_enabled = 0;
244 }
245 
246 /*
247  * __hal_stats_terminate
248  * @stats: xge_hal_stats_t structure that contains, in particular,
249  *         Xframe hw stat counters.
250  * Terminate per-device statistics object.
251  */
252 void
__hal_stats_terminate(xge_hal_stats_t * stats)253 __hal_stats_terminate (xge_hal_stats_t *stats)
254 {
255 	xge_hal_device_t *hldev;
256 
257 	xge_assert(stats->hw_info);
258 
259 	hldev = (xge_hal_device_t*)stats->devh;
260 	xge_assert(hldev);
261 	xge_assert(stats->is_initialized);
262 	if (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN) {
263 	    xge_os_dma_unmap(hldev->pdev,
264 	               stats->hw_info_dmah,
265 	           stats->dma_addr,
266 	           sizeof(xge_hal_stats_hw_info_t),
267 	           XGE_OS_DMA_DIR_FROMDEVICE);
268 
269 	    xge_os_dma_free(hldev->pdev,
270 	          stats->hw_info,
271 	          sizeof(xge_hal_stats_hw_info_t),
272 	          &stats->hw_info_dma_acch,
273 	          &stats->hw_info_dmah);
274 	} else {
275 	    xge_os_dma_unmap(hldev->pdev,
276 	               stats->hw_info_dmah,
277 	           stats->dma_addr,
278 	           sizeof(xge_hal_stats_pcim_info_t),
279 	           XGE_OS_DMA_DIR_FROMDEVICE);
280 
281 	    xge_os_dma_free(hldev->pdev,
282 	          stats->pcim_info,
283 	          sizeof(xge_hal_stats_pcim_info_t),
284 	          &stats->hw_info_dma_acch,
285 	          &stats->hw_info_dmah);
286 
287 	    xge_os_free(hldev->pdev, stats->pcim_info_saved,
288 	        sizeof(xge_hal_stats_pcim_info_t));
289 
290 	    xge_os_free(hldev->pdev, stats->pcim_info_latest,
291 	            sizeof(xge_hal_stats_pcim_info_t));
292 
293 	}
294 
295 	stats->is_initialized = 0;
296 	stats->is_enabled = 0;
297 }
298 
299 
300 
301 /*
302  * __hal_stats_enable
303  * @stats: xge_hal_stats_t structure that contains, in particular,
304  *         Xframe hw stat counters.
305  *
306  * Ask device to start collecting stats.
307  * See also: xge_hal_stats_getinfo().
308  */
309 void
__hal_stats_enable(xge_hal_stats_t * stats)310 __hal_stats_enable (xge_hal_stats_t *stats)
311 {
312 	xge_hal_device_t *hldev;
313 	xge_hal_pci_bar0_t *bar0;
314 	u64 val64;
315 	unsigned int refresh_time_pci_clocks;
316 
317 	xge_assert(stats->hw_info);
318 
319 	hldev = (xge_hal_device_t*)stats->devh;
320 	xge_assert(hldev);
321 
322 	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
323 
324 	/* enable statistics
325 	 * For Titan stat_addr offset == 0x09d8, and stat_cfg offset == 0x09d0
326 	*/
327 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
328 	    stats->dma_addr, &bar0->stat_addr);
329 
330 	refresh_time_pci_clocks = XGE_HAL_XENA_PER_SEC *
331 	    hldev->config.stats_refresh_time_sec;
332 	refresh_time_pci_clocks =
333 	    __hal_fix_time_ival_herc(hldev,
334 	        refresh_time_pci_clocks);
335 
336 #ifdef XGE_HAL_HERC_EMULATION
337 	/*
338 	 *  The clocks in the emulator are running ~1000 times slower
339 	 *  than real world, so the stats transfer will occur ~1000
340 	 *  times less frequent. STAT_CFG.STAT_TRSF_PERIOD should be
341 	 *  set to 0x20C for Hercules emulation (stats transferred
342 	 *  every 0.5 sec).
343 	*/
344 
345 	val64 = (0x20C | XGE_HAL_STAT_CFG_STAT_RO |
346 	    XGE_HAL_STAT_CFG_STAT_EN);
347 #else
348 	val64 = XGE_HAL_SET_UPDT_PERIOD(refresh_time_pci_clocks) |
349 	                    XGE_HAL_STAT_CFG_STAT_RO |
350 	            XGE_HAL_STAT_CFG_STAT_EN;
351 #endif
352 
353 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
354 	    val64, &bar0->stat_cfg);
355 
356 	xge_debug_stats(XGE_TRACE, "stats enabled at 0x"XGE_OS_LLXFMT,
357 	     (unsigned long long)stats->dma_addr);
358 
359 	stats->is_enabled = 1;
360 }
361 
362 /*
363  * __hal_stats_pcim_update_latest - Update hw ER stats counters, based on the
364  * real hardware maintained counters and the stored "reset" values.
365  */
366 static void
__hal_stats_pcim_update_latest(xge_hal_device_h devh)367 __hal_stats_pcim_update_latest(xge_hal_device_h devh)
368 {
369 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
370 	int i;
371 
372 #define set_latest_stat_link_cnt(_link, _p)                   \
373 	    hldev->stats.pcim_info_latest->link_info[_link]._p =              \
374 	((hldev->stats.pcim_info->link_info[_link]._p >=                  \
375 	    hldev->stats.pcim_info_saved->link_info[_link]._p) ?          \
376 	    hldev->stats.pcim_info->link_info[_link]._p -             \
377 	        hldev->stats.pcim_info_saved->link_info[_link]._p :   \
378 	    ((-1) - hldev->stats.pcim_info_saved->link_info[_link]._p) +  \
379 	        hldev->stats.pcim_info->link_info[_link]._p)
380 
381 
382 #define set_latest_stat_aggr_cnt(_aggr, _p)                   \
383 	    hldev->stats.pcim_info_latest->aggr_info[_aggr]._p =              \
384 	((hldev->stats.pcim_info->aggr_info[_aggr]._p >=              \
385 	    hldev->stats.pcim_info_saved->aggr_info[_aggr]._p) ?          \
386 	    hldev->stats.pcim_info->aggr_info[_aggr]._p -             \
387 	        hldev->stats.pcim_info_saved->aggr_info[_aggr]._p :   \
388 	    ((-1) - hldev->stats.pcim_info_saved->aggr_info[_aggr]._p) +  \
389 	        hldev->stats.pcim_info->aggr_info[_aggr]._p)
390 
391 
392 	for (i = 0; i < XGE_HAL_MAC_LINKS; i++) {
393 	    set_latest_stat_link_cnt(i, tx_frms);
394 	    set_latest_stat_link_cnt(i, tx_ttl_eth_octets);
395 	    set_latest_stat_link_cnt(i, tx_data_octets);
396 	    set_latest_stat_link_cnt(i, tx_mcst_frms);
397 	    set_latest_stat_link_cnt(i, tx_bcst_frms);
398 	    set_latest_stat_link_cnt(i, tx_ucst_frms);
399 	    set_latest_stat_link_cnt(i, tx_tagged_frms);
400 	    set_latest_stat_link_cnt(i, tx_vld_ip);
401 	    set_latest_stat_link_cnt(i, tx_vld_ip_octets);
402 	    set_latest_stat_link_cnt(i, tx_icmp);
403 	    set_latest_stat_link_cnt(i, tx_tcp);
404 	    set_latest_stat_link_cnt(i, tx_rst_tcp);
405 	    set_latest_stat_link_cnt(i, tx_udp);
406 	    set_latest_stat_link_cnt(i, tx_unknown_protocol);
407 	    set_latest_stat_link_cnt(i, tx_parse_error);
408 	    set_latest_stat_link_cnt(i, tx_pause_ctrl_frms);
409 	    set_latest_stat_link_cnt(i, tx_lacpdu_frms);
410 	    set_latest_stat_link_cnt(i, tx_marker_pdu_frms);
411 	    set_latest_stat_link_cnt(i, tx_marker_resp_pdu_frms);
412 	    set_latest_stat_link_cnt(i, tx_drop_ip);
413 	    set_latest_stat_link_cnt(i, tx_xgmii_char1_match);
414 	    set_latest_stat_link_cnt(i, tx_xgmii_char2_match);
415 	    set_latest_stat_link_cnt(i, tx_xgmii_column1_match);
416 	    set_latest_stat_link_cnt(i, tx_xgmii_column2_match);
417 	    set_latest_stat_link_cnt(i, tx_drop_frms);
418 	    set_latest_stat_link_cnt(i, tx_any_err_frms);
419 	    set_latest_stat_link_cnt(i, rx_ttl_frms);
420 	    set_latest_stat_link_cnt(i, rx_vld_frms);
421 	    set_latest_stat_link_cnt(i, rx_offld_frms);
422 	    set_latest_stat_link_cnt(i, rx_ttl_eth_octets);
423 	    set_latest_stat_link_cnt(i, rx_data_octets);
424 	    set_latest_stat_link_cnt(i, rx_offld_octets);
425 	    set_latest_stat_link_cnt(i, rx_vld_mcst_frms);
426 	    set_latest_stat_link_cnt(i, rx_vld_bcst_frms);
427 	    set_latest_stat_link_cnt(i, rx_accepted_ucst_frms);
428 	    set_latest_stat_link_cnt(i, rx_accepted_nucst_frms);
429 	    set_latest_stat_link_cnt(i, rx_tagged_frms);
430 	    set_latest_stat_link_cnt(i, rx_long_frms);
431 	    set_latest_stat_link_cnt(i, rx_usized_frms);
432 	    set_latest_stat_link_cnt(i, rx_osized_frms);
433 	    set_latest_stat_link_cnt(i, rx_frag_frms);
434 	    set_latest_stat_link_cnt(i, rx_jabber_frms);
435 	    set_latest_stat_link_cnt(i, rx_ttl_64_frms);
436 	    set_latest_stat_link_cnt(i, rx_ttl_65_127_frms);
437 	    set_latest_stat_link_cnt(i, rx_ttl_128_255_frms);
438 	    set_latest_stat_link_cnt(i, rx_ttl_256_511_frms);
439 	    set_latest_stat_link_cnt(i, rx_ttl_512_1023_frms);
440 	    set_latest_stat_link_cnt(i, rx_ttl_1024_1518_frms);
441 	    set_latest_stat_link_cnt(i, rx_ttl_1519_4095_frms);
442 	    set_latest_stat_link_cnt(i, rx_ttl_40956_8191_frms);
443 	    set_latest_stat_link_cnt(i, rx_ttl_8192_max_frms);
444 	    set_latest_stat_link_cnt(i, rx_ttl_gt_max_frms);
445 	    set_latest_stat_link_cnt(i, rx_ip);
446 	    set_latest_stat_link_cnt(i, rx_ip_octets);
447 	    set_latest_stat_link_cnt(i, rx_hdr_err_ip);
448 	    set_latest_stat_link_cnt(i, rx_icmp);
449 	    set_latest_stat_link_cnt(i, rx_tcp);
450 	    set_latest_stat_link_cnt(i, rx_udp);
451 	    set_latest_stat_link_cnt(i, rx_err_tcp);
452 	    set_latest_stat_link_cnt(i, rx_pause_cnt);
453 	    set_latest_stat_link_cnt(i, rx_pause_ctrl_frms);
454 	    set_latest_stat_link_cnt(i, rx_unsup_ctrl_frms);
455 	    set_latest_stat_link_cnt(i, rx_in_rng_len_err_frms);
456 	    set_latest_stat_link_cnt(i, rx_out_rng_len_err_frms);
457 	    set_latest_stat_link_cnt(i, rx_drop_frms);
458 	    set_latest_stat_link_cnt(i, rx_discarded_frms);
459 	    set_latest_stat_link_cnt(i, rx_drop_ip);
460 	    set_latest_stat_link_cnt(i, rx_err_drp_udp);
461 	    set_latest_stat_link_cnt(i, rx_lacpdu_frms);
462 	    set_latest_stat_link_cnt(i, rx_marker_pdu_frms);
463 	    set_latest_stat_link_cnt(i, rx_marker_resp_pdu_frms);
464 	    set_latest_stat_link_cnt(i, rx_unknown_pdu_frms);
465 	    set_latest_stat_link_cnt(i, rx_illegal_pdu_frms);
466 	    set_latest_stat_link_cnt(i, rx_fcs_discard);
467 	    set_latest_stat_link_cnt(i, rx_len_discard);
468 	    set_latest_stat_link_cnt(i, rx_pf_discard);
469 	    set_latest_stat_link_cnt(i, rx_trash_discard);
470 	    set_latest_stat_link_cnt(i, rx_rts_discard);
471 	    set_latest_stat_link_cnt(i, rx_wol_discard);
472 	    set_latest_stat_link_cnt(i, rx_red_discard);
473 	    set_latest_stat_link_cnt(i, rx_ingm_full_discard);
474 	    set_latest_stat_link_cnt(i, rx_xgmii_data_err_cnt);
475 	    set_latest_stat_link_cnt(i, rx_xgmii_ctrl_err_cnt);
476 	    set_latest_stat_link_cnt(i, rx_xgmii_err_sym);
477 	    set_latest_stat_link_cnt(i, rx_xgmii_char1_match);
478 	    set_latest_stat_link_cnt(i, rx_xgmii_char2_match);
479 	    set_latest_stat_link_cnt(i, rx_xgmii_column1_match);
480 	    set_latest_stat_link_cnt(i, rx_xgmii_column2_match);
481 	    set_latest_stat_link_cnt(i, rx_local_fault);
482 	    set_latest_stat_link_cnt(i, rx_remote_fault);
483 	    set_latest_stat_link_cnt(i, rx_queue_full);
484 	}
485 
486 	for (i = 0; i < XGE_HAL_MAC_AGGREGATORS; i++) {
487 	    set_latest_stat_aggr_cnt(i, tx_frms);
488 	    set_latest_stat_aggr_cnt(i, tx_mcst_frms);
489 	    set_latest_stat_aggr_cnt(i, tx_bcst_frms);
490 	    set_latest_stat_aggr_cnt(i, tx_discarded_frms);
491 	    set_latest_stat_aggr_cnt(i, tx_errored_frms);
492 	    set_latest_stat_aggr_cnt(i, rx_frms);
493 	    set_latest_stat_aggr_cnt(i, rx_data_octets);
494 	    set_latest_stat_aggr_cnt(i, rx_mcst_frms);
495 	    set_latest_stat_aggr_cnt(i, rx_bcst_frms);
496 	    set_latest_stat_aggr_cnt(i, rx_discarded_frms);
497 	    set_latest_stat_aggr_cnt(i, rx_errored_frms);
498 	    set_latest_stat_aggr_cnt(i, rx_unknown_protocol_frms);
499 	}
500 	return;
501 }
502 
503 /*
504  * __hal_stats_update_latest - Update hw stats counters, based on the real
505  * hardware maintained counters and the stored "reset" values.
506  */
507 static void
__hal_stats_update_latest(xge_hal_device_h devh)508 __hal_stats_update_latest(xge_hal_device_h devh)
509 {
510 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
511 
512 #define set_latest_stat_cnt(_dev, _p)                                   \
513 	    hldev->stats.hw_info_latest._p =                                \
514 	((hldev->stats.hw_info->_p >= hldev->stats.hw_info_saved._p) ?  \
515 	      hldev->stats.hw_info->_p - hldev->stats.hw_info_saved._p :    \
516 	  ((-1) - hldev->stats.hw_info_saved._p) + hldev->stats.hw_info->_p)
517 
518 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN) {
519 	    __hal_stats_pcim_update_latest(devh);
520 	    return;
521 	}
522 
523 	/* Tx MAC statistics counters. */
524 	set_latest_stat_cnt(hldev, tmac_frms);
525 	set_latest_stat_cnt(hldev, tmac_data_octets);
526 	set_latest_stat_cnt(hldev, tmac_drop_frms);
527 	set_latest_stat_cnt(hldev, tmac_mcst_frms);
528 	set_latest_stat_cnt(hldev, tmac_bcst_frms);
529 	set_latest_stat_cnt(hldev, tmac_pause_ctrl_frms);
530 	set_latest_stat_cnt(hldev, tmac_ttl_octets);
531 	set_latest_stat_cnt(hldev, tmac_ucst_frms);
532 	set_latest_stat_cnt(hldev, tmac_nucst_frms);
533 	set_latest_stat_cnt(hldev, tmac_any_err_frms);
534 	set_latest_stat_cnt(hldev, tmac_ttl_less_fb_octets);
535 	set_latest_stat_cnt(hldev, tmac_vld_ip_octets);
536 	set_latest_stat_cnt(hldev, tmac_vld_ip);
537 	set_latest_stat_cnt(hldev, tmac_drop_ip);
538 	set_latest_stat_cnt(hldev, tmac_icmp);
539 	set_latest_stat_cnt(hldev, tmac_rst_tcp);
540 	set_latest_stat_cnt(hldev, tmac_tcp);
541 	set_latest_stat_cnt(hldev, tmac_udp);
542 	set_latest_stat_cnt(hldev, reserved_0);
543 
544 	/* Rx MAC Statistics counters. */
545 	set_latest_stat_cnt(hldev, rmac_vld_frms);
546 	set_latest_stat_cnt(hldev, rmac_data_octets);
547 	set_latest_stat_cnt(hldev, rmac_fcs_err_frms);
548 	set_latest_stat_cnt(hldev, rmac_drop_frms);
549 	set_latest_stat_cnt(hldev, rmac_vld_mcst_frms);
550 	set_latest_stat_cnt(hldev, rmac_vld_bcst_frms);
551 	set_latest_stat_cnt(hldev, rmac_in_rng_len_err_frms);
552 	set_latest_stat_cnt(hldev, rmac_out_rng_len_err_frms);
553 	set_latest_stat_cnt(hldev, rmac_long_frms);
554 	set_latest_stat_cnt(hldev, rmac_pause_ctrl_frms);
555 	set_latest_stat_cnt(hldev, rmac_unsup_ctrl_frms);
556 	set_latest_stat_cnt(hldev, rmac_ttl_octets);
557 	set_latest_stat_cnt(hldev, rmac_accepted_ucst_frms);
558 	set_latest_stat_cnt(hldev, rmac_accepted_nucst_frms);
559 	set_latest_stat_cnt(hldev, rmac_discarded_frms);
560 	set_latest_stat_cnt(hldev, rmac_drop_events);
561 	set_latest_stat_cnt(hldev, reserved_1);
562 	set_latest_stat_cnt(hldev, rmac_ttl_less_fb_octets);
563 	set_latest_stat_cnt(hldev, rmac_ttl_frms);
564 	set_latest_stat_cnt(hldev, reserved_2);
565 	set_latest_stat_cnt(hldev, reserved_3);
566 	set_latest_stat_cnt(hldev, rmac_usized_frms);
567 	set_latest_stat_cnt(hldev, rmac_osized_frms);
568 	set_latest_stat_cnt(hldev, rmac_frag_frms);
569 	set_latest_stat_cnt(hldev, rmac_jabber_frms);
570 	set_latest_stat_cnt(hldev, reserved_4);
571 	set_latest_stat_cnt(hldev, rmac_ttl_64_frms);
572 	set_latest_stat_cnt(hldev, rmac_ttl_65_127_frms);
573 	set_latest_stat_cnt(hldev, reserved_5);
574 	set_latest_stat_cnt(hldev, rmac_ttl_128_255_frms);
575 	set_latest_stat_cnt(hldev, rmac_ttl_256_511_frms);
576 	set_latest_stat_cnt(hldev, reserved_6);
577 	set_latest_stat_cnt(hldev, rmac_ttl_512_1023_frms);
578 	set_latest_stat_cnt(hldev, rmac_ttl_1024_1518_frms);
579 	set_latest_stat_cnt(hldev, reserved_7);
580 	set_latest_stat_cnt(hldev, rmac_ip);
581 	set_latest_stat_cnt(hldev, rmac_ip_octets);
582 	set_latest_stat_cnt(hldev, rmac_hdr_err_ip);
583 	set_latest_stat_cnt(hldev, rmac_drop_ip);
584 	set_latest_stat_cnt(hldev, rmac_icmp);
585 	set_latest_stat_cnt(hldev, reserved_8);
586 	set_latest_stat_cnt(hldev, rmac_tcp);
587 	set_latest_stat_cnt(hldev, rmac_udp);
588 	set_latest_stat_cnt(hldev, rmac_err_drp_udp);
589 	set_latest_stat_cnt(hldev, rmac_xgmii_err_sym);
590 	set_latest_stat_cnt(hldev, rmac_frms_q0);
591 	set_latest_stat_cnt(hldev, rmac_frms_q1);
592 	set_latest_stat_cnt(hldev, rmac_frms_q2);
593 	set_latest_stat_cnt(hldev, rmac_frms_q3);
594 	set_latest_stat_cnt(hldev, rmac_frms_q4);
595 	set_latest_stat_cnt(hldev, rmac_frms_q5);
596 	set_latest_stat_cnt(hldev, rmac_frms_q6);
597 	set_latest_stat_cnt(hldev, rmac_frms_q7);
598 	set_latest_stat_cnt(hldev, rmac_full_q0);
599 	set_latest_stat_cnt(hldev, rmac_full_q1);
600 	set_latest_stat_cnt(hldev, rmac_full_q2);
601 	set_latest_stat_cnt(hldev, rmac_full_q3);
602 	set_latest_stat_cnt(hldev, rmac_full_q4);
603 	set_latest_stat_cnt(hldev, rmac_full_q5);
604 	set_latest_stat_cnt(hldev, rmac_full_q6);
605 	set_latest_stat_cnt(hldev, rmac_full_q7);
606 	set_latest_stat_cnt(hldev, rmac_pause_cnt);
607 	set_latest_stat_cnt(hldev, reserved_9);
608 	set_latest_stat_cnt(hldev, rmac_xgmii_data_err_cnt);
609 	set_latest_stat_cnt(hldev, rmac_xgmii_ctrl_err_cnt);
610 	set_latest_stat_cnt(hldev, rmac_accepted_ip);
611 	set_latest_stat_cnt(hldev, rmac_err_tcp);
612 
613 	/* PCI/PCI-X Read transaction statistics. */
614 	set_latest_stat_cnt(hldev, rd_req_cnt);
615 	set_latest_stat_cnt(hldev, new_rd_req_cnt);
616 	set_latest_stat_cnt(hldev, new_rd_req_rtry_cnt);
617 	set_latest_stat_cnt(hldev, rd_rtry_cnt);
618 	set_latest_stat_cnt(hldev, wr_rtry_rd_ack_cnt);
619 
620 	/* PCI/PCI-X write transaction statistics. */
621 	set_latest_stat_cnt(hldev, wr_req_cnt);
622 	set_latest_stat_cnt(hldev, new_wr_req_cnt);
623 	set_latest_stat_cnt(hldev, new_wr_req_rtry_cnt);
624 	set_latest_stat_cnt(hldev, wr_rtry_cnt);
625 	set_latest_stat_cnt(hldev, wr_disc_cnt);
626 	set_latest_stat_cnt(hldev, rd_rtry_wr_ack_cnt);
627 
628 	/* DMA Transaction statistics. */
629 	set_latest_stat_cnt(hldev, txp_wr_cnt);
630 	set_latest_stat_cnt(hldev, txd_rd_cnt);
631 	set_latest_stat_cnt(hldev, txd_wr_cnt);
632 	set_latest_stat_cnt(hldev, rxd_rd_cnt);
633 	set_latest_stat_cnt(hldev, rxd_wr_cnt);
634 	set_latest_stat_cnt(hldev, txf_rd_cnt);
635 	set_latest_stat_cnt(hldev, rxf_wr_cnt);
636 
637 	/* Enhanced Herc statistics */
638 	set_latest_stat_cnt(hldev, tmac_frms_oflow);
639 	set_latest_stat_cnt(hldev, tmac_data_octets_oflow);
640 	set_latest_stat_cnt(hldev, tmac_mcst_frms_oflow);
641 	set_latest_stat_cnt(hldev, tmac_bcst_frms_oflow);
642 	set_latest_stat_cnt(hldev, tmac_ttl_octets_oflow);
643 	set_latest_stat_cnt(hldev, tmac_ucst_frms_oflow);
644 	set_latest_stat_cnt(hldev, tmac_nucst_frms_oflow);
645 	set_latest_stat_cnt(hldev, tmac_any_err_frms_oflow);
646 	set_latest_stat_cnt(hldev, tmac_vlan_frms);
647 	set_latest_stat_cnt(hldev, tmac_vld_ip_oflow);
648 	set_latest_stat_cnt(hldev, tmac_drop_ip_oflow);
649 	set_latest_stat_cnt(hldev, tmac_icmp_oflow);
650 	set_latest_stat_cnt(hldev, tmac_rst_tcp_oflow);
651 	set_latest_stat_cnt(hldev, tmac_udp_oflow);
652 	set_latest_stat_cnt(hldev, tpa_unknown_protocol);
653 	set_latest_stat_cnt(hldev, tpa_parse_failure);
654 	set_latest_stat_cnt(hldev, rmac_vld_frms_oflow);
655 	set_latest_stat_cnt(hldev, rmac_data_octets_oflow);
656 	set_latest_stat_cnt(hldev, rmac_vld_mcst_frms_oflow);
657 	set_latest_stat_cnt(hldev, rmac_vld_bcst_frms_oflow);
658 	set_latest_stat_cnt(hldev, rmac_ttl_octets_oflow);
659 	set_latest_stat_cnt(hldev, rmac_accepted_ucst_frms_oflow);
660 	set_latest_stat_cnt(hldev, rmac_accepted_nucst_frms_oflow);
661 	set_latest_stat_cnt(hldev, rmac_discarded_frms_oflow);
662 	set_latest_stat_cnt(hldev, rmac_drop_events_oflow);
663 	set_latest_stat_cnt(hldev, rmac_usized_frms_oflow);
664 	set_latest_stat_cnt(hldev, rmac_osized_frms_oflow);
665 	set_latest_stat_cnt(hldev, rmac_frag_frms_oflow);
666 	set_latest_stat_cnt(hldev, rmac_jabber_frms_oflow);
667 	set_latest_stat_cnt(hldev, rmac_ip_oflow);
668 	set_latest_stat_cnt(hldev, rmac_drop_ip_oflow);
669 	set_latest_stat_cnt(hldev, rmac_icmp_oflow);
670 	set_latest_stat_cnt(hldev, rmac_udp_oflow);
671 	set_latest_stat_cnt(hldev, rmac_err_drp_udp_oflow);
672 	set_latest_stat_cnt(hldev, rmac_pause_cnt_oflow);
673 	set_latest_stat_cnt(hldev, rmac_ttl_1519_4095_frms);
674 	set_latest_stat_cnt(hldev, rmac_ttl_4096_8191_frms);
675 	set_latest_stat_cnt(hldev, rmac_ttl_8192_max_frms);
676 	set_latest_stat_cnt(hldev, rmac_ttl_gt_max_frms);
677 	set_latest_stat_cnt(hldev, rmac_osized_alt_frms);
678 	set_latest_stat_cnt(hldev, rmac_jabber_alt_frms);
679 	set_latest_stat_cnt(hldev, rmac_gt_max_alt_frms);
680 	set_latest_stat_cnt(hldev, rmac_vlan_frms);
681 	set_latest_stat_cnt(hldev, rmac_fcs_discard);
682 	set_latest_stat_cnt(hldev, rmac_len_discard);
683 	set_latest_stat_cnt(hldev, rmac_da_discard);
684 	set_latest_stat_cnt(hldev, rmac_pf_discard);
685 	set_latest_stat_cnt(hldev, rmac_rts_discard);
686 	set_latest_stat_cnt(hldev, rmac_red_discard);
687 	set_latest_stat_cnt(hldev, rmac_ingm_full_discard);
688 	set_latest_stat_cnt(hldev, rmac_accepted_ip_oflow);
689 	set_latest_stat_cnt(hldev, link_fault_cnt);
690 }
691 
692 /**
693  * xge_hal_stats_hw - Get HW device statistics.
694  * @devh: HAL device handle.
695  * @hw_info: Xframe statistic counters. See xge_hal_stats_hw_info_t.
696  *           Returned by HAL.
697  *
698  * Get device and HAL statistics. The latter is part of the in-host statistics
699  * that HAL maintains for _that_ device.
700  *
701  * Returns: XGE_HAL_OK - success.
702  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
703  * currently available.
704  *
705  * See also: xge_hal_status_e{}.
706  */
707 xge_hal_status_e
xge_hal_stats_hw(xge_hal_device_h devh,xge_hal_stats_hw_info_t ** hw_info)708 xge_hal_stats_hw(xge_hal_device_h devh, xge_hal_stats_hw_info_t **hw_info)
709 {
710 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
711 
712 	xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN)
713 
714 	if (!hldev->stats.is_initialized ||
715 	    !hldev->stats.is_enabled) {
716 	    *hw_info = NULL;
717 	    return XGE_HAL_INF_STATS_IS_NOT_READY;
718 	}
719 
720 #if defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_STATS_STREAMING)
721 	xge_os_dma_sync(hldev->pdev,
722 	              hldev->stats.hw_info_dmah,
723 	          hldev->stats.dma_addr,
724 	          0,
725 	          sizeof(xge_hal_stats_hw_info_t),
726 	          XGE_OS_DMA_DIR_FROMDEVICE);
727 #endif
728 
729 	    /*
730 	 * update hw counters, taking into account
731 	 * the "reset" or "saved"
732 	 * values
733 	 */
734 	__hal_stats_update_latest(devh);
735 
736 	/*
737 	 * statistics HW bug fixups for Xena and Herc
738 	 */
739 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA ||
740 	    xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
741 	    u64 mcst, bcst;
742 	    xge_hal_stats_hw_info_t *hwsta = &hldev->stats.hw_info_latest;
743 
744 	    mcst = ((u64)hwsta->rmac_vld_mcst_frms_oflow << 32) |
745 	        hwsta->rmac_vld_mcst_frms;
746 
747 	    bcst = ((u64)hwsta->rmac_vld_bcst_frms_oflow << 32) |
748 	        hwsta->rmac_vld_bcst_frms;
749 
750 	    mcst -= bcst;
751 
752 	    hwsta->rmac_vld_mcst_frms_oflow = (u32)(mcst >> 32);
753 	    hwsta->rmac_vld_mcst_frms = (u32)mcst;
754 	}
755 
756 	*hw_info = &hldev->stats.hw_info_latest;
757 
758 	return XGE_HAL_OK;
759 }
760 
761 /**
762  * xge_hal_stats_pcim - Get HW device statistics.
763  * @devh: HAL device handle.
764  * @hw_info: Xframe statistic counters. See xge_hal_stats_pcim_info_t.
765  *
766  * Returns: XGE_HAL_OK - success.
767  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
768  * currently available.
769  *
770  * See also: xge_hal_status_e{}.
771  */
772 xge_hal_status_e
xge_hal_stats_pcim(xge_hal_device_h devh,xge_hal_stats_pcim_info_t ** hw_info)773 xge_hal_stats_pcim(xge_hal_device_h devh, xge_hal_stats_pcim_info_t **hw_info)
774 {
775 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
776 
777 	xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN)
778 
779 	if (!hldev->stats.is_initialized ||
780 	    !hldev->stats.is_enabled) {
781 	    *hw_info = NULL;
782 	    return XGE_HAL_INF_STATS_IS_NOT_READY;
783 	}
784 
785 #if defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_STATS_STREAMING)
786 	xge_os_dma_sync(hldev->pdev,
787 	              hldev->stats.hw_info_dmah,
788 	          hldev->stats.dma_addr,
789 	          0,
790 	          sizeof(xge_hal_stats_pcim_info_t),
791 	          XGE_OS_DMA_DIR_FROMDEVICE);
792 #endif
793 
794 	    /*
795 	 * update hw counters, taking into account
796 	 * the "reset" or "saved"
797 	 * values
798 	 */
799 	__hal_stats_pcim_update_latest(devh);
800 
801 	*hw_info = hldev->stats.pcim_info_latest;
802 
803 	return XGE_HAL_OK;
804 }
805 
806 /**
807  * xge_hal_stats_device - Get HAL statistics.
808  * @devh: HAL device handle.
809  * @hw_info: Xframe statistic counters. See xge_hal_stats_hw_info_t.
810  *           Returned by HAL.
811  * @device_info: HAL statistics. See xge_hal_stats_device_info_t.
812  *               Returned by HAL.
813  *
814  * Get device and HAL statistics. The latter is part of the in-host statistics
815  * that HAL maintains for _that_ device.
816  *
817  * Returns: XGE_HAL_OK - success.
818  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
819  * currently available.
820  *
821  * See also: xge_hal_status_e{}.
822  */
823 xge_hal_status_e
xge_hal_stats_device(xge_hal_device_h devh,xge_hal_stats_device_info_t ** device_info)824 xge_hal_stats_device(xge_hal_device_h devh,
825 	    xge_hal_stats_device_info_t **device_info)
826 {
827 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
828 
829 	if (!hldev->stats.is_initialized ||
830 	    !hldev->stats.is_enabled) {
831 	    *device_info = NULL;
832 	    return XGE_HAL_INF_STATS_IS_NOT_READY;
833 	}
834 
835 	hldev->stats.sw_dev_info_stats.traffic_intr_cnt =
836 	    hldev->stats.sw_dev_info_stats.total_intr_cnt -
837 	        hldev->stats.sw_dev_info_stats.not_traffic_intr_cnt;
838 
839 	*device_info = &hldev->stats.sw_dev_info_stats;
840 
841 	return XGE_HAL_OK;
842 }
843 
844 /**
845  * xge_hal_stats_channel - Get channel statistics.
846  * @channelh: Channel handle.
847  * @channel_info: HAL channel statistic counters.
848  *                See xge_hal_stats_channel_info_t{}. Returned by HAL.
849  *
850  * Retrieve statistics of a particular HAL channel. This includes, for instance,
851  * number of completions per interrupt, number of traffic interrupts, etc.
852  *
853  * Returns: XGE_HAL_OK - success.
854  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
855  * currently available.
856  *
857  * See also: xge_hal_status_e{}.
858  */
859 xge_hal_status_e
xge_hal_stats_channel(xge_hal_channel_h channelh,xge_hal_stats_channel_info_t ** channel_info)860 xge_hal_stats_channel(xge_hal_channel_h channelh,
861 	    xge_hal_stats_channel_info_t **channel_info)
862 {
863 	xge_hal_stats_hw_info_t *latest;
864 	xge_hal_channel_t *channel;
865 	xge_hal_device_t *hldev;
866 
867 	channel = (xge_hal_channel_t *)channelh;
868 	if ((channel == NULL) || (channel->magic != XGE_HAL_MAGIC)) {
869 	    return XGE_HAL_ERR_INVALID_DEVICE;
870 	}
871 	hldev = (xge_hal_device_t *)channel->devh;
872 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
873 	    return XGE_HAL_ERR_INVALID_DEVICE;
874 	}
875 
876 	if (!hldev->stats.is_initialized ||
877 	    !hldev->stats.is_enabled ||
878 	    !channel->is_open) {
879 	    *channel_info = NULL;
880 	    return XGE_HAL_INF_STATS_IS_NOT_READY;
881 	}
882 
883 	hldev->stats.sw_dev_info_stats.traffic_intr_cnt =
884 	    hldev->stats.sw_dev_info_stats.total_intr_cnt -
885 	        hldev->stats.sw_dev_info_stats.not_traffic_intr_cnt;
886 
887 	if (hldev->stats.sw_dev_info_stats.traffic_intr_cnt) {
888 	    int rxcnt = hldev->stats.sw_dev_info_stats.rx_traffic_intr_cnt;
889 	    int txcnt = hldev->stats.sw_dev_info_stats.tx_traffic_intr_cnt;
890 	    if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) {
891 	        if (!txcnt)
892 	            txcnt = 1;
893 	        channel->stats.avg_compl_per_intr_cnt =
894 	            channel->stats.total_compl_cnt / txcnt;
895 	    } else if (channel->type == XGE_HAL_CHANNEL_TYPE_RING &&
896 	           !hldev->config.bimodal_interrupts) {
897 	        if (!rxcnt)
898 	            rxcnt = 1;
899 	        channel->stats.avg_compl_per_intr_cnt =
900 	            channel->stats.total_compl_cnt / rxcnt;
901 	    }
902 	    if (channel->stats.avg_compl_per_intr_cnt == 0) {
903 	        /* to not confuse user */
904 	        channel->stats.avg_compl_per_intr_cnt = 1;
905 	    }
906 	}
907 
908 	(void) xge_hal_stats_hw(hldev, &latest);
909 
910 	if (channel->stats.total_posts) {
911 	    channel->stats.avg_buffers_per_post =
912 	        channel->stats.total_buffers /
913 	            channel->stats.total_posts;
914 #ifdef XGE_OS_PLATFORM_64BIT
915 	        if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) {
916 	            channel->stats.avg_post_size =
917 	        (u32)(latest->tmac_ttl_less_fb_octets /
918 	            channel->stats.total_posts);
919 	        }
920 #endif
921 	}
922 
923 #ifdef XGE_OS_PLATFORM_64BIT
924 	if (channel->stats.total_buffers &&
925 	    channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) {
926 	    channel->stats.avg_buffer_size =
927 	        (u32)(latest->tmac_ttl_less_fb_octets /
928 	            channel->stats.total_buffers);
929 	}
930 #endif
931 
932 	*channel_info = &channel->stats;
933 	return XGE_HAL_OK;
934 }
935 
936 /**
937  * xge_hal_stats_reset - Reset (zero-out) device statistics
938  * @devh: HAL device handle.
939  *
940  * Reset all device statistics.
941  * Returns: XGE_HAL_OK - success.
942  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
943  * currently available.
944  *
945  * See also: xge_hal_status_e{}, xge_hal_stats_channel_info_t{},
946  * xge_hal_stats_sw_err_t{}, xge_hal_stats_device_info_t{}.
947  */
948 xge_hal_status_e
xge_hal_stats_reset(xge_hal_device_h devh)949 xge_hal_stats_reset(xge_hal_device_h devh)
950 {
951 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
952 
953 	if (!hldev->stats.is_initialized ||
954 	    !hldev->stats.is_enabled) {
955 	    return XGE_HAL_INF_STATS_IS_NOT_READY;
956 	}
957 
958 	/* save hw stats to calculate the after-reset values */
959 	__hal_stats_save(&hldev->stats);
960 
961 	/* zero-out driver-maintained stats, don't reset the saved */
962 	    __hal_stats_soft_reset(hldev, 0);
963 
964 	return XGE_HAL_OK;
965 }
966 
967 /*
968  * __hal_stats_soft_reset - Reset software-maintained statistics.
969  */
970 void
__hal_stats_soft_reset(xge_hal_device_h devh,int reset_all)971 __hal_stats_soft_reset (xge_hal_device_h devh, int reset_all)
972 {
973 	xge_list_t *item;
974 	xge_hal_channel_t *channel;
975 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
976 
977 	    if (reset_all)  {
978 	    if (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN) {
979 	        xge_os_memzero(&hldev->stats.hw_info_saved,
980 	                   sizeof(xge_hal_stats_hw_info_t));
981 	        xge_os_memzero(&hldev->stats.hw_info_latest,
982 	                   sizeof(xge_hal_stats_hw_info_t));
983 	    } else {
984 	        xge_os_memzero(&hldev->stats.pcim_info_saved,
985 	                   sizeof(xge_hal_stats_pcim_info_t));
986 	        xge_os_memzero(&hldev->stats.pcim_info_latest,
987 	                   sizeof(xge_hal_stats_pcim_info_t));
988 	    }
989 	    }
990 
991 	/* Reset the "soft" error and informational statistics */
992 	xge_os_memzero(&hldev->stats.sw_dev_err_stats,
993 	             sizeof(xge_hal_stats_sw_err_t));
994 	xge_os_memzero(&hldev->stats.sw_dev_info_stats,
995 	             sizeof(xge_hal_stats_device_info_t));
996 
997 	/* for each Rx channel */
998 	xge_list_for_each(item, &hldev->ring_channels) {
999 	    channel = xge_container_of(item, xge_hal_channel_t, item);
1000 	    xge_os_memzero(&channel->stats,
1001 	                 sizeof(xge_hal_stats_channel_info_t));
1002 	}
1003 
1004 	/* for each Tx channel */
1005 	xge_list_for_each(item, &hldev->fifo_channels) {
1006 	    channel = xge_container_of(item, xge_hal_channel_t, item);
1007 	    xge_os_memzero(&channel->stats,
1008 	                 sizeof(xge_hal_stats_channel_info_t));
1009 	}
1010 }
1011 
1012