18c2ecf20Sopenharmony_ci/* bnx2x_stats.c: QLogic Everest network driver.
28c2ecf20Sopenharmony_ci *
38c2ecf20Sopenharmony_ci * Copyright (c) 2007-2013 Broadcom Corporation
48c2ecf20Sopenharmony_ci * Copyright (c) 2014 QLogic Corporation
58c2ecf20Sopenharmony_ci * All rights reserved
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify
88c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License as published by
98c2ecf20Sopenharmony_ci * the Free Software Foundation.
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * Maintained by: Ariel Elior <ariel.elior@qlogic.com>
128c2ecf20Sopenharmony_ci * Written by: Eliezer Tamir
138c2ecf20Sopenharmony_ci * Based on code from Michael Chan's bnx2 driver
148c2ecf20Sopenharmony_ci * UDP CSUM errata workaround by Arik Gendelman
158c2ecf20Sopenharmony_ci * Slowpath and fastpath rework by Vladislav Zolotarov
168c2ecf20Sopenharmony_ci * Statistics and Link management by Yitchak Gertner
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#include "bnx2x_stats.h"
238c2ecf20Sopenharmony_ci#include "bnx2x_cmn.h"
248c2ecf20Sopenharmony_ci#include "bnx2x_sriov.h"
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ciextern const u32 dmae_reg_go_c[];
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/* Statistics */
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/*
318c2ecf20Sopenharmony_ci * General service functions
328c2ecf20Sopenharmony_ci */
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_cistatic inline long bnx2x_hilo(u32 *hiref)
358c2ecf20Sopenharmony_ci{
368c2ecf20Sopenharmony_ci	u32 lo = *(hiref + 1);
378c2ecf20Sopenharmony_ci#if (BITS_PER_LONG == 64)
388c2ecf20Sopenharmony_ci	u32 hi = *hiref;
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	return HILO_U64(hi, lo);
418c2ecf20Sopenharmony_ci#else
428c2ecf20Sopenharmony_ci	return lo;
438c2ecf20Sopenharmony_ci#endif
448c2ecf20Sopenharmony_ci}
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_cistatic inline u16 bnx2x_get_port_stats_dma_len(struct bnx2x *bp)
478c2ecf20Sopenharmony_ci{
488c2ecf20Sopenharmony_ci	u16 res = 0;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	/* 'newest' convention - shmem2 cotains the size of the port stats */
518c2ecf20Sopenharmony_ci	if (SHMEM2_HAS(bp, sizeof_port_stats)) {
528c2ecf20Sopenharmony_ci		u32 size = SHMEM2_RD(bp, sizeof_port_stats);
538c2ecf20Sopenharmony_ci		if (size)
548c2ecf20Sopenharmony_ci			res = size;
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci		/* prevent newer BC from causing buffer overflow */
578c2ecf20Sopenharmony_ci		if (res > sizeof(struct host_port_stats))
588c2ecf20Sopenharmony_ci			res = sizeof(struct host_port_stats);
598c2ecf20Sopenharmony_ci	}
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	/* Older convention - all BCs support the port stats' fields up until
628c2ecf20Sopenharmony_ci	 * the 'not_used' field
638c2ecf20Sopenharmony_ci	 */
648c2ecf20Sopenharmony_ci	if (!res) {
658c2ecf20Sopenharmony_ci		res = offsetof(struct host_port_stats, not_used) + 4;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci		/* if PFC stats are supported by the MFW, DMA them as well */
688c2ecf20Sopenharmony_ci		if (bp->flags & BC_SUPPORTS_PFC_STATS) {
698c2ecf20Sopenharmony_ci			res += offsetof(struct host_port_stats,
708c2ecf20Sopenharmony_ci					pfc_frames_rx_lo) -
718c2ecf20Sopenharmony_ci			       offsetof(struct host_port_stats,
728c2ecf20Sopenharmony_ci					pfc_frames_tx_hi) + 4 ;
738c2ecf20Sopenharmony_ci		}
748c2ecf20Sopenharmony_ci	}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	res >>= 2;
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	WARN_ON(res > 2 * DMAE_LEN32_RD_MAX);
798c2ecf20Sopenharmony_ci	return res;
808c2ecf20Sopenharmony_ci}
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci/*
838c2ecf20Sopenharmony_ci * Init service functions
848c2ecf20Sopenharmony_ci */
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_cistatic void bnx2x_dp_stats(struct bnx2x *bp)
878c2ecf20Sopenharmony_ci{
888c2ecf20Sopenharmony_ci	int i;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	DP(BNX2X_MSG_STATS, "dumping stats:\n"
918c2ecf20Sopenharmony_ci	   "fw_stats_req\n"
928c2ecf20Sopenharmony_ci	   "    hdr\n"
938c2ecf20Sopenharmony_ci	   "        cmd_num %d\n"
948c2ecf20Sopenharmony_ci	   "        reserved0 %d\n"
958c2ecf20Sopenharmony_ci	   "        drv_stats_counter %d\n"
968c2ecf20Sopenharmony_ci	   "        reserved1 %d\n"
978c2ecf20Sopenharmony_ci	   "        stats_counters_addrs %x %x\n",
988c2ecf20Sopenharmony_ci	   bp->fw_stats_req->hdr.cmd_num,
998c2ecf20Sopenharmony_ci	   bp->fw_stats_req->hdr.reserved0,
1008c2ecf20Sopenharmony_ci	   bp->fw_stats_req->hdr.drv_stats_counter,
1018c2ecf20Sopenharmony_ci	   bp->fw_stats_req->hdr.reserved1,
1028c2ecf20Sopenharmony_ci	   bp->fw_stats_req->hdr.stats_counters_addrs.hi,
1038c2ecf20Sopenharmony_ci	   bp->fw_stats_req->hdr.stats_counters_addrs.lo);
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	for (i = 0; i < bp->fw_stats_req->hdr.cmd_num; i++) {
1068c2ecf20Sopenharmony_ci		DP(BNX2X_MSG_STATS,
1078c2ecf20Sopenharmony_ci		   "query[%d]\n"
1088c2ecf20Sopenharmony_ci		   "              kind %d\n"
1098c2ecf20Sopenharmony_ci		   "              index %d\n"
1108c2ecf20Sopenharmony_ci		   "              funcID %d\n"
1118c2ecf20Sopenharmony_ci		   "              reserved %d\n"
1128c2ecf20Sopenharmony_ci		   "              address %x %x\n",
1138c2ecf20Sopenharmony_ci		   i, bp->fw_stats_req->query[i].kind,
1148c2ecf20Sopenharmony_ci		   bp->fw_stats_req->query[i].index,
1158c2ecf20Sopenharmony_ci		   bp->fw_stats_req->query[i].funcID,
1168c2ecf20Sopenharmony_ci		   bp->fw_stats_req->query[i].reserved,
1178c2ecf20Sopenharmony_ci		   bp->fw_stats_req->query[i].address.hi,
1188c2ecf20Sopenharmony_ci		   bp->fw_stats_req->query[i].address.lo);
1198c2ecf20Sopenharmony_ci	}
1208c2ecf20Sopenharmony_ci}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci/* Post the next statistics ramrod. Protect it with the spin in
1238c2ecf20Sopenharmony_ci * order to ensure the strict order between statistics ramrods
1248c2ecf20Sopenharmony_ci * (each ramrod has a sequence number passed in a
1258c2ecf20Sopenharmony_ci * bp->fw_stats_req->hdr.drv_stats_counter and ramrods must be
1268c2ecf20Sopenharmony_ci * sent in order).
1278c2ecf20Sopenharmony_ci */
1288c2ecf20Sopenharmony_cistatic void bnx2x_storm_stats_post(struct bnx2x *bp)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	int rc;
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci	if (bp->stats_pending)
1338c2ecf20Sopenharmony_ci		return;
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	bp->fw_stats_req->hdr.drv_stats_counter =
1368c2ecf20Sopenharmony_ci		cpu_to_le16(bp->stats_counter++);
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	DP(BNX2X_MSG_STATS, "Sending statistics ramrod %d\n",
1398c2ecf20Sopenharmony_ci	   le16_to_cpu(bp->fw_stats_req->hdr.drv_stats_counter));
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci	/* adjust the ramrod to include VF queues statistics */
1428c2ecf20Sopenharmony_ci	bnx2x_iov_adjust_stats_req(bp);
1438c2ecf20Sopenharmony_ci	bnx2x_dp_stats(bp);
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	/* send FW stats ramrod */
1468c2ecf20Sopenharmony_ci	rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0,
1478c2ecf20Sopenharmony_ci			   U64_HI(bp->fw_stats_req_mapping),
1488c2ecf20Sopenharmony_ci			   U64_LO(bp->fw_stats_req_mapping),
1498c2ecf20Sopenharmony_ci			   NONE_CONNECTION_TYPE);
1508c2ecf20Sopenharmony_ci	if (rc == 0)
1518c2ecf20Sopenharmony_ci		bp->stats_pending = 1;
1528c2ecf20Sopenharmony_ci}
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_cistatic void bnx2x_hw_stats_post(struct bnx2x *bp)
1558c2ecf20Sopenharmony_ci{
1568c2ecf20Sopenharmony_ci	struct dmae_command *dmae = &bp->stats_dmae;
1578c2ecf20Sopenharmony_ci	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	*stats_comp = DMAE_COMP_VAL;
1608c2ecf20Sopenharmony_ci	if (CHIP_REV_IS_SLOW(bp))
1618c2ecf20Sopenharmony_ci		return;
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	/* Update MCP's statistics if possible */
1648c2ecf20Sopenharmony_ci	if (bp->func_stx)
1658c2ecf20Sopenharmony_ci		memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats,
1668c2ecf20Sopenharmony_ci		       sizeof(bp->func_stats));
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci	/* loader */
1698c2ecf20Sopenharmony_ci	if (bp->executer_idx) {
1708c2ecf20Sopenharmony_ci		int loader_idx = PMF_DMAE_C(bp);
1718c2ecf20Sopenharmony_ci		u32 opcode =  bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC,
1728c2ecf20Sopenharmony_ci						 true, DMAE_COMP_GRC);
1738c2ecf20Sopenharmony_ci		opcode = bnx2x_dmae_opcode_clr_src_reset(opcode);
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci		memset(dmae, 0, sizeof(struct dmae_command));
1768c2ecf20Sopenharmony_ci		dmae->opcode = opcode;
1778c2ecf20Sopenharmony_ci		dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0]));
1788c2ecf20Sopenharmony_ci		dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0]));
1798c2ecf20Sopenharmony_ci		dmae->dst_addr_lo = (DMAE_REG_CMD_MEM +
1808c2ecf20Sopenharmony_ci				     sizeof(struct dmae_command) *
1818c2ecf20Sopenharmony_ci				     (loader_idx + 1)) >> 2;
1828c2ecf20Sopenharmony_ci		dmae->dst_addr_hi = 0;
1838c2ecf20Sopenharmony_ci		dmae->len = sizeof(struct dmae_command) >> 2;
1848c2ecf20Sopenharmony_ci		if (CHIP_IS_E1(bp))
1858c2ecf20Sopenharmony_ci			dmae->len--;
1868c2ecf20Sopenharmony_ci		dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2;
1878c2ecf20Sopenharmony_ci		dmae->comp_addr_hi = 0;
1888c2ecf20Sopenharmony_ci		dmae->comp_val = 1;
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci		*stats_comp = 0;
1918c2ecf20Sopenharmony_ci		bnx2x_post_dmae(bp, dmae, loader_idx);
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci	} else if (bp->func_stx) {
1948c2ecf20Sopenharmony_ci		*stats_comp = 0;
1958c2ecf20Sopenharmony_ci		bnx2x_issue_dmae_with_comp(bp, dmae, stats_comp);
1968c2ecf20Sopenharmony_ci	}
1978c2ecf20Sopenharmony_ci}
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_cistatic void bnx2x_stats_comp(struct bnx2x *bp)
2008c2ecf20Sopenharmony_ci{
2018c2ecf20Sopenharmony_ci	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
2028c2ecf20Sopenharmony_ci	int cnt = 10;
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci	might_sleep();
2058c2ecf20Sopenharmony_ci	while (*stats_comp != DMAE_COMP_VAL) {
2068c2ecf20Sopenharmony_ci		if (!cnt) {
2078c2ecf20Sopenharmony_ci			BNX2X_ERR("timeout waiting for stats finished\n");
2088c2ecf20Sopenharmony_ci			break;
2098c2ecf20Sopenharmony_ci		}
2108c2ecf20Sopenharmony_ci		cnt--;
2118c2ecf20Sopenharmony_ci		usleep_range(1000, 2000);
2128c2ecf20Sopenharmony_ci	}
2138c2ecf20Sopenharmony_ci}
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci/*
2168c2ecf20Sopenharmony_ci * Statistics service functions
2178c2ecf20Sopenharmony_ci */
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci/* should be called under stats_sema */
2208c2ecf20Sopenharmony_cistatic void bnx2x_stats_pmf_update(struct bnx2x *bp)
2218c2ecf20Sopenharmony_ci{
2228c2ecf20Sopenharmony_ci	struct dmae_command *dmae;
2238c2ecf20Sopenharmony_ci	u32 opcode;
2248c2ecf20Sopenharmony_ci	int loader_idx = PMF_DMAE_C(bp);
2258c2ecf20Sopenharmony_ci	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci	/* sanity */
2288c2ecf20Sopenharmony_ci	if (!bp->port.pmf || !bp->port.port_stx) {
2298c2ecf20Sopenharmony_ci		BNX2X_ERR("BUG!\n");
2308c2ecf20Sopenharmony_ci		return;
2318c2ecf20Sopenharmony_ci	}
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	bp->executer_idx = 0;
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci	opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, false, 0);
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci	dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
2388c2ecf20Sopenharmony_ci	dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_GRC);
2398c2ecf20Sopenharmony_ci	dmae->src_addr_lo = bp->port.port_stx >> 2;
2408c2ecf20Sopenharmony_ci	dmae->src_addr_hi = 0;
2418c2ecf20Sopenharmony_ci	dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
2428c2ecf20Sopenharmony_ci	dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
2438c2ecf20Sopenharmony_ci	dmae->len = DMAE_LEN32_RD_MAX;
2448c2ecf20Sopenharmony_ci	dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
2458c2ecf20Sopenharmony_ci	dmae->comp_addr_hi = 0;
2468c2ecf20Sopenharmony_ci	dmae->comp_val = 1;
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci	dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
2498c2ecf20Sopenharmony_ci	dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
2508c2ecf20Sopenharmony_ci	dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX;
2518c2ecf20Sopenharmony_ci	dmae->src_addr_hi = 0;
2528c2ecf20Sopenharmony_ci	dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) +
2538c2ecf20Sopenharmony_ci				   DMAE_LEN32_RD_MAX * 4);
2548c2ecf20Sopenharmony_ci	dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats) +
2558c2ecf20Sopenharmony_ci				   DMAE_LEN32_RD_MAX * 4);
2568c2ecf20Sopenharmony_ci	dmae->len = bnx2x_get_port_stats_dma_len(bp) - DMAE_LEN32_RD_MAX;
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
2598c2ecf20Sopenharmony_ci	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
2608c2ecf20Sopenharmony_ci	dmae->comp_val = DMAE_COMP_VAL;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	*stats_comp = 0;
2638c2ecf20Sopenharmony_ci	bnx2x_hw_stats_post(bp);
2648c2ecf20Sopenharmony_ci	bnx2x_stats_comp(bp);
2658c2ecf20Sopenharmony_ci}
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_cistatic void bnx2x_port_stats_init(struct bnx2x *bp)
2688c2ecf20Sopenharmony_ci{
2698c2ecf20Sopenharmony_ci	struct dmae_command *dmae;
2708c2ecf20Sopenharmony_ci	int port = BP_PORT(bp);
2718c2ecf20Sopenharmony_ci	u32 opcode;
2728c2ecf20Sopenharmony_ci	int loader_idx = PMF_DMAE_C(bp);
2738c2ecf20Sopenharmony_ci	u32 mac_addr;
2748c2ecf20Sopenharmony_ci	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	/* sanity */
2778c2ecf20Sopenharmony_ci	if (!bp->link_vars.link_up || !bp->port.pmf) {
2788c2ecf20Sopenharmony_ci		BNX2X_ERR("BUG!\n");
2798c2ecf20Sopenharmony_ci		return;
2808c2ecf20Sopenharmony_ci	}
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci	bp->executer_idx = 0;
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci	/* MCP */
2858c2ecf20Sopenharmony_ci	opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC,
2868c2ecf20Sopenharmony_ci				    true, DMAE_COMP_GRC);
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci	if (bp->port.port_stx) {
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci		dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
2918c2ecf20Sopenharmony_ci		dmae->opcode = opcode;
2928c2ecf20Sopenharmony_ci		dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
2938c2ecf20Sopenharmony_ci		dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
2948c2ecf20Sopenharmony_ci		dmae->dst_addr_lo = bp->port.port_stx >> 2;
2958c2ecf20Sopenharmony_ci		dmae->dst_addr_hi = 0;
2968c2ecf20Sopenharmony_ci		dmae->len = bnx2x_get_port_stats_dma_len(bp);
2978c2ecf20Sopenharmony_ci		dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
2988c2ecf20Sopenharmony_ci		dmae->comp_addr_hi = 0;
2998c2ecf20Sopenharmony_ci		dmae->comp_val = 1;
3008c2ecf20Sopenharmony_ci	}
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_ci	if (bp->func_stx) {
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci		dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
3058c2ecf20Sopenharmony_ci		dmae->opcode = opcode;
3068c2ecf20Sopenharmony_ci		dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
3078c2ecf20Sopenharmony_ci		dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
3088c2ecf20Sopenharmony_ci		dmae->dst_addr_lo = bp->func_stx >> 2;
3098c2ecf20Sopenharmony_ci		dmae->dst_addr_hi = 0;
3108c2ecf20Sopenharmony_ci		dmae->len = sizeof(struct host_func_stats) >> 2;
3118c2ecf20Sopenharmony_ci		dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
3128c2ecf20Sopenharmony_ci		dmae->comp_addr_hi = 0;
3138c2ecf20Sopenharmony_ci		dmae->comp_val = 1;
3148c2ecf20Sopenharmony_ci	}
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci	/* MAC */
3178c2ecf20Sopenharmony_ci	opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI,
3188c2ecf20Sopenharmony_ci				   true, DMAE_COMP_GRC);
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_ci	/* EMAC is special */
3218c2ecf20Sopenharmony_ci	if (bp->link_vars.mac_type == MAC_TYPE_EMAC) {
3228c2ecf20Sopenharmony_ci		mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0);
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci		/* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/
3258c2ecf20Sopenharmony_ci		dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
3268c2ecf20Sopenharmony_ci		dmae->opcode = opcode;
3278c2ecf20Sopenharmony_ci		dmae->src_addr_lo = (mac_addr +
3288c2ecf20Sopenharmony_ci				     EMAC_REG_EMAC_RX_STAT_AC) >> 2;
3298c2ecf20Sopenharmony_ci		dmae->src_addr_hi = 0;
3308c2ecf20Sopenharmony_ci		dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
3318c2ecf20Sopenharmony_ci		dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
3328c2ecf20Sopenharmony_ci		dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT;
3338c2ecf20Sopenharmony_ci		dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
3348c2ecf20Sopenharmony_ci		dmae->comp_addr_hi = 0;
3358c2ecf20Sopenharmony_ci		dmae->comp_val = 1;
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci		/* EMAC_REG_EMAC_RX_STAT_AC_28 */
3388c2ecf20Sopenharmony_ci		dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
3398c2ecf20Sopenharmony_ci		dmae->opcode = opcode;
3408c2ecf20Sopenharmony_ci		dmae->src_addr_lo = (mac_addr +
3418c2ecf20Sopenharmony_ci				     EMAC_REG_EMAC_RX_STAT_AC_28) >> 2;
3428c2ecf20Sopenharmony_ci		dmae->src_addr_hi = 0;
3438c2ecf20Sopenharmony_ci		dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
3448c2ecf20Sopenharmony_ci		     offsetof(struct emac_stats, rx_stat_falsecarriererrors));
3458c2ecf20Sopenharmony_ci		dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
3468c2ecf20Sopenharmony_ci		     offsetof(struct emac_stats, rx_stat_falsecarriererrors));
3478c2ecf20Sopenharmony_ci		dmae->len = 1;
3488c2ecf20Sopenharmony_ci		dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
3498c2ecf20Sopenharmony_ci		dmae->comp_addr_hi = 0;
3508c2ecf20Sopenharmony_ci		dmae->comp_val = 1;
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci		/* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/
3538c2ecf20Sopenharmony_ci		dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
3548c2ecf20Sopenharmony_ci		dmae->opcode = opcode;
3558c2ecf20Sopenharmony_ci		dmae->src_addr_lo = (mac_addr +
3568c2ecf20Sopenharmony_ci				     EMAC_REG_EMAC_TX_STAT_AC) >> 2;
3578c2ecf20Sopenharmony_ci		dmae->src_addr_hi = 0;
3588c2ecf20Sopenharmony_ci		dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
3598c2ecf20Sopenharmony_ci			offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
3608c2ecf20Sopenharmony_ci		dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
3618c2ecf20Sopenharmony_ci			offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
3628c2ecf20Sopenharmony_ci		dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT;
3638c2ecf20Sopenharmony_ci		dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
3648c2ecf20Sopenharmony_ci		dmae->comp_addr_hi = 0;
3658c2ecf20Sopenharmony_ci		dmae->comp_val = 1;
3668c2ecf20Sopenharmony_ci	} else {
3678c2ecf20Sopenharmony_ci		u32 tx_src_addr_lo, rx_src_addr_lo;
3688c2ecf20Sopenharmony_ci		u16 rx_len, tx_len;
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci		/* configure the params according to MAC type */
3718c2ecf20Sopenharmony_ci		switch (bp->link_vars.mac_type) {
3728c2ecf20Sopenharmony_ci		case MAC_TYPE_BMAC:
3738c2ecf20Sopenharmony_ci			mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM :
3748c2ecf20Sopenharmony_ci					   NIG_REG_INGRESS_BMAC0_MEM);
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci			/* BIGMAC_REGISTER_TX_STAT_GTPKT ..
3778c2ecf20Sopenharmony_ci			   BIGMAC_REGISTER_TX_STAT_GTBYT */
3788c2ecf20Sopenharmony_ci			if (CHIP_IS_E1x(bp)) {
3798c2ecf20Sopenharmony_ci				tx_src_addr_lo = (mac_addr +
3808c2ecf20Sopenharmony_ci					BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
3818c2ecf20Sopenharmony_ci				tx_len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT -
3828c2ecf20Sopenharmony_ci					  BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
3838c2ecf20Sopenharmony_ci				rx_src_addr_lo = (mac_addr +
3848c2ecf20Sopenharmony_ci					BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
3858c2ecf20Sopenharmony_ci				rx_len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
3868c2ecf20Sopenharmony_ci					  BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
3878c2ecf20Sopenharmony_ci			} else {
3888c2ecf20Sopenharmony_ci				tx_src_addr_lo = (mac_addr +
3898c2ecf20Sopenharmony_ci					BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2;
3908c2ecf20Sopenharmony_ci				tx_len = (8 + BIGMAC2_REGISTER_TX_STAT_GTBYT -
3918c2ecf20Sopenharmony_ci					  BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2;
3928c2ecf20Sopenharmony_ci				rx_src_addr_lo = (mac_addr +
3938c2ecf20Sopenharmony_ci					BIGMAC2_REGISTER_RX_STAT_GR64) >> 2;
3948c2ecf20Sopenharmony_ci				rx_len = (8 + BIGMAC2_REGISTER_RX_STAT_GRIPJ -
3958c2ecf20Sopenharmony_ci					  BIGMAC2_REGISTER_RX_STAT_GR64) >> 2;
3968c2ecf20Sopenharmony_ci			}
3978c2ecf20Sopenharmony_ci			break;
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci		case MAC_TYPE_UMAC: /* handled by MSTAT */
4008c2ecf20Sopenharmony_ci		case MAC_TYPE_XMAC: /* handled by MSTAT */
4018c2ecf20Sopenharmony_ci		default:
4028c2ecf20Sopenharmony_ci			mac_addr = port ? GRCBASE_MSTAT1 : GRCBASE_MSTAT0;
4038c2ecf20Sopenharmony_ci			tx_src_addr_lo = (mac_addr +
4048c2ecf20Sopenharmony_ci					  MSTAT_REG_TX_STAT_GTXPOK_LO) >> 2;
4058c2ecf20Sopenharmony_ci			rx_src_addr_lo = (mac_addr +
4068c2ecf20Sopenharmony_ci					  MSTAT_REG_RX_STAT_GR64_LO) >> 2;
4078c2ecf20Sopenharmony_ci			tx_len = sizeof(bp->slowpath->
4088c2ecf20Sopenharmony_ci					mac_stats.mstat_stats.stats_tx) >> 2;
4098c2ecf20Sopenharmony_ci			rx_len = sizeof(bp->slowpath->
4108c2ecf20Sopenharmony_ci					mac_stats.mstat_stats.stats_rx) >> 2;
4118c2ecf20Sopenharmony_ci			break;
4128c2ecf20Sopenharmony_ci		}
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_ci		/* TX stats */
4158c2ecf20Sopenharmony_ci		dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
4168c2ecf20Sopenharmony_ci		dmae->opcode = opcode;
4178c2ecf20Sopenharmony_ci		dmae->src_addr_lo = tx_src_addr_lo;
4188c2ecf20Sopenharmony_ci		dmae->src_addr_hi = 0;
4198c2ecf20Sopenharmony_ci		dmae->len = tx_len;
4208c2ecf20Sopenharmony_ci		dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
4218c2ecf20Sopenharmony_ci		dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
4228c2ecf20Sopenharmony_ci		dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
4238c2ecf20Sopenharmony_ci		dmae->comp_addr_hi = 0;
4248c2ecf20Sopenharmony_ci		dmae->comp_val = 1;
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci		/* RX stats */
4278c2ecf20Sopenharmony_ci		dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
4288c2ecf20Sopenharmony_ci		dmae->opcode = opcode;
4298c2ecf20Sopenharmony_ci		dmae->src_addr_hi = 0;
4308c2ecf20Sopenharmony_ci		dmae->src_addr_lo = rx_src_addr_lo;
4318c2ecf20Sopenharmony_ci		dmae->dst_addr_lo =
4328c2ecf20Sopenharmony_ci			U64_LO(bnx2x_sp_mapping(bp, mac_stats) + (tx_len << 2));
4338c2ecf20Sopenharmony_ci		dmae->dst_addr_hi =
4348c2ecf20Sopenharmony_ci			U64_HI(bnx2x_sp_mapping(bp, mac_stats) + (tx_len << 2));
4358c2ecf20Sopenharmony_ci		dmae->len = rx_len;
4368c2ecf20Sopenharmony_ci		dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
4378c2ecf20Sopenharmony_ci		dmae->comp_addr_hi = 0;
4388c2ecf20Sopenharmony_ci		dmae->comp_val = 1;
4398c2ecf20Sopenharmony_ci	}
4408c2ecf20Sopenharmony_ci
4418c2ecf20Sopenharmony_ci	/* NIG */
4428c2ecf20Sopenharmony_ci	if (!CHIP_IS_E3(bp)) {
4438c2ecf20Sopenharmony_ci		dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
4448c2ecf20Sopenharmony_ci		dmae->opcode = opcode;
4458c2ecf20Sopenharmony_ci		dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 :
4468c2ecf20Sopenharmony_ci					    NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2;
4478c2ecf20Sopenharmony_ci		dmae->src_addr_hi = 0;
4488c2ecf20Sopenharmony_ci		dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
4498c2ecf20Sopenharmony_ci				offsetof(struct nig_stats, egress_mac_pkt0_lo));
4508c2ecf20Sopenharmony_ci		dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
4518c2ecf20Sopenharmony_ci				offsetof(struct nig_stats, egress_mac_pkt0_lo));
4528c2ecf20Sopenharmony_ci		dmae->len = (2*sizeof(u32)) >> 2;
4538c2ecf20Sopenharmony_ci		dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
4548c2ecf20Sopenharmony_ci		dmae->comp_addr_hi = 0;
4558c2ecf20Sopenharmony_ci		dmae->comp_val = 1;
4568c2ecf20Sopenharmony_ci
4578c2ecf20Sopenharmony_ci		dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
4588c2ecf20Sopenharmony_ci		dmae->opcode = opcode;
4598c2ecf20Sopenharmony_ci		dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 :
4608c2ecf20Sopenharmony_ci					    NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2;
4618c2ecf20Sopenharmony_ci		dmae->src_addr_hi = 0;
4628c2ecf20Sopenharmony_ci		dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
4638c2ecf20Sopenharmony_ci				offsetof(struct nig_stats, egress_mac_pkt1_lo));
4648c2ecf20Sopenharmony_ci		dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
4658c2ecf20Sopenharmony_ci				offsetof(struct nig_stats, egress_mac_pkt1_lo));
4668c2ecf20Sopenharmony_ci		dmae->len = (2*sizeof(u32)) >> 2;
4678c2ecf20Sopenharmony_ci		dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
4688c2ecf20Sopenharmony_ci		dmae->comp_addr_hi = 0;
4698c2ecf20Sopenharmony_ci		dmae->comp_val = 1;
4708c2ecf20Sopenharmony_ci	}
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_ci	dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
4738c2ecf20Sopenharmony_ci	dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI,
4748c2ecf20Sopenharmony_ci						 true, DMAE_COMP_PCI);
4758c2ecf20Sopenharmony_ci	dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD :
4768c2ecf20Sopenharmony_ci				    NIG_REG_STAT0_BRB_DISCARD) >> 2;
4778c2ecf20Sopenharmony_ci	dmae->src_addr_hi = 0;
4788c2ecf20Sopenharmony_ci	dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats));
4798c2ecf20Sopenharmony_ci	dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats));
4808c2ecf20Sopenharmony_ci	dmae->len = (sizeof(struct nig_stats) - 4*sizeof(u32)) >> 2;
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_ci	dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
4838c2ecf20Sopenharmony_ci	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
4848c2ecf20Sopenharmony_ci	dmae->comp_val = DMAE_COMP_VAL;
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci	*stats_comp = 0;
4878c2ecf20Sopenharmony_ci}
4888c2ecf20Sopenharmony_ci
4898c2ecf20Sopenharmony_cistatic void bnx2x_func_stats_init(struct bnx2x *bp)
4908c2ecf20Sopenharmony_ci{
4918c2ecf20Sopenharmony_ci	struct dmae_command *dmae = &bp->stats_dmae;
4928c2ecf20Sopenharmony_ci	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci	/* sanity */
4958c2ecf20Sopenharmony_ci	if (!bp->func_stx) {
4968c2ecf20Sopenharmony_ci		BNX2X_ERR("BUG!\n");
4978c2ecf20Sopenharmony_ci		return;
4988c2ecf20Sopenharmony_ci	}
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_ci	bp->executer_idx = 0;
5018c2ecf20Sopenharmony_ci	memset(dmae, 0, sizeof(struct dmae_command));
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_ci	dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC,
5048c2ecf20Sopenharmony_ci					 true, DMAE_COMP_PCI);
5058c2ecf20Sopenharmony_ci	dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
5068c2ecf20Sopenharmony_ci	dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
5078c2ecf20Sopenharmony_ci	dmae->dst_addr_lo = bp->func_stx >> 2;
5088c2ecf20Sopenharmony_ci	dmae->dst_addr_hi = 0;
5098c2ecf20Sopenharmony_ci	dmae->len = sizeof(struct host_func_stats) >> 2;
5108c2ecf20Sopenharmony_ci	dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
5118c2ecf20Sopenharmony_ci	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
5128c2ecf20Sopenharmony_ci	dmae->comp_val = DMAE_COMP_VAL;
5138c2ecf20Sopenharmony_ci
5148c2ecf20Sopenharmony_ci	*stats_comp = 0;
5158c2ecf20Sopenharmony_ci}
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci/* should be called under stats_sema */
5188c2ecf20Sopenharmony_cistatic void bnx2x_stats_start(struct bnx2x *bp)
5198c2ecf20Sopenharmony_ci{
5208c2ecf20Sopenharmony_ci	if (IS_PF(bp)) {
5218c2ecf20Sopenharmony_ci		if (bp->port.pmf)
5228c2ecf20Sopenharmony_ci			bnx2x_port_stats_init(bp);
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_ci		else if (bp->func_stx)
5258c2ecf20Sopenharmony_ci			bnx2x_func_stats_init(bp);
5268c2ecf20Sopenharmony_ci
5278c2ecf20Sopenharmony_ci		bnx2x_hw_stats_post(bp);
5288c2ecf20Sopenharmony_ci		bnx2x_storm_stats_post(bp);
5298c2ecf20Sopenharmony_ci	}
5308c2ecf20Sopenharmony_ci}
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_cistatic void bnx2x_stats_pmf_start(struct bnx2x *bp)
5338c2ecf20Sopenharmony_ci{
5348c2ecf20Sopenharmony_ci	bnx2x_stats_comp(bp);
5358c2ecf20Sopenharmony_ci	bnx2x_stats_pmf_update(bp);
5368c2ecf20Sopenharmony_ci	bnx2x_stats_start(bp);
5378c2ecf20Sopenharmony_ci}
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_cistatic void bnx2x_stats_restart(struct bnx2x *bp)
5408c2ecf20Sopenharmony_ci{
5418c2ecf20Sopenharmony_ci	/* vfs travel through here as part of the statistics FSM, but no action
5428c2ecf20Sopenharmony_ci	 * is required
5438c2ecf20Sopenharmony_ci	 */
5448c2ecf20Sopenharmony_ci	if (IS_VF(bp))
5458c2ecf20Sopenharmony_ci		return;
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_ci	bnx2x_stats_comp(bp);
5488c2ecf20Sopenharmony_ci	bnx2x_stats_start(bp);
5498c2ecf20Sopenharmony_ci}
5508c2ecf20Sopenharmony_ci
5518c2ecf20Sopenharmony_cistatic void bnx2x_bmac_stats_update(struct bnx2x *bp)
5528c2ecf20Sopenharmony_ci{
5538c2ecf20Sopenharmony_ci	struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
5548c2ecf20Sopenharmony_ci	struct bnx2x_eth_stats *estats = &bp->eth_stats;
5558c2ecf20Sopenharmony_ci	struct {
5568c2ecf20Sopenharmony_ci		u32 lo;
5578c2ecf20Sopenharmony_ci		u32 hi;
5588c2ecf20Sopenharmony_ci	} diff;
5598c2ecf20Sopenharmony_ci
5608c2ecf20Sopenharmony_ci	if (CHIP_IS_E1x(bp)) {
5618c2ecf20Sopenharmony_ci		struct bmac1_stats *new = bnx2x_sp(bp, mac_stats.bmac1_stats);
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_ci		/* the macros below will use "bmac1_stats" type */
5648c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
5658c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
5668c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
5678c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
5688c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
5698c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
5708c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
5718c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
5728c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grxpf, rx_stat_mac_xpf);
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
5758c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
5768c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
5778c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt127,
5788c2ecf20Sopenharmony_ci				tx_stat_etherstatspkts65octetsto127octets);
5798c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt255,
5808c2ecf20Sopenharmony_ci				tx_stat_etherstatspkts128octetsto255octets);
5818c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt511,
5828c2ecf20Sopenharmony_ci				tx_stat_etherstatspkts256octetsto511octets);
5838c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt1023,
5848c2ecf20Sopenharmony_ci				tx_stat_etherstatspkts512octetsto1023octets);
5858c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt1518,
5868c2ecf20Sopenharmony_ci				tx_stat_etherstatspkts1024octetsto1522octets);
5878c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt2047, tx_stat_mac_2047);
5888c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt4095, tx_stat_mac_4095);
5898c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt9216, tx_stat_mac_9216);
5908c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt16383, tx_stat_mac_16383);
5918c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gterr,
5928c2ecf20Sopenharmony_ci				tx_stat_dot3statsinternalmactransmiterrors);
5938c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl);
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci	} else {
5968c2ecf20Sopenharmony_ci		struct bmac2_stats *new = bnx2x_sp(bp, mac_stats.bmac2_stats);
5978c2ecf20Sopenharmony_ci
5988c2ecf20Sopenharmony_ci		/* the macros below will use "bmac2_stats" type */
5998c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
6008c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
6018c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
6028c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
6038c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
6048c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
6058c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
6068c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
6078c2ecf20Sopenharmony_ci		UPDATE_STAT64(rx_stat_grxpf, rx_stat_mac_xpf);
6088c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
6098c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
6108c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
6118c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt127,
6128c2ecf20Sopenharmony_ci				tx_stat_etherstatspkts65octetsto127octets);
6138c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt255,
6148c2ecf20Sopenharmony_ci				tx_stat_etherstatspkts128octetsto255octets);
6158c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt511,
6168c2ecf20Sopenharmony_ci				tx_stat_etherstatspkts256octetsto511octets);
6178c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt1023,
6188c2ecf20Sopenharmony_ci				tx_stat_etherstatspkts512octetsto1023octets);
6198c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt1518,
6208c2ecf20Sopenharmony_ci				tx_stat_etherstatspkts1024octetsto1522octets);
6218c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt2047, tx_stat_mac_2047);
6228c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt4095, tx_stat_mac_4095);
6238c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt9216, tx_stat_mac_9216);
6248c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gt16383, tx_stat_mac_16383);
6258c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gterr,
6268c2ecf20Sopenharmony_ci				tx_stat_dot3statsinternalmactransmiterrors);
6278c2ecf20Sopenharmony_ci		UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl);
6288c2ecf20Sopenharmony_ci
6298c2ecf20Sopenharmony_ci		/* collect PFC stats */
6308c2ecf20Sopenharmony_ci		pstats->pfc_frames_tx_hi = new->tx_stat_gtpp_hi;
6318c2ecf20Sopenharmony_ci		pstats->pfc_frames_tx_lo = new->tx_stat_gtpp_lo;
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci		pstats->pfc_frames_rx_hi = new->rx_stat_grpp_hi;
6348c2ecf20Sopenharmony_ci		pstats->pfc_frames_rx_lo = new->rx_stat_grpp_lo;
6358c2ecf20Sopenharmony_ci	}
6368c2ecf20Sopenharmony_ci
6378c2ecf20Sopenharmony_ci	estats->pause_frames_received_hi =
6388c2ecf20Sopenharmony_ci				pstats->mac_stx[1].rx_stat_mac_xpf_hi;
6398c2ecf20Sopenharmony_ci	estats->pause_frames_received_lo =
6408c2ecf20Sopenharmony_ci				pstats->mac_stx[1].rx_stat_mac_xpf_lo;
6418c2ecf20Sopenharmony_ci
6428c2ecf20Sopenharmony_ci	estats->pause_frames_sent_hi =
6438c2ecf20Sopenharmony_ci				pstats->mac_stx[1].tx_stat_outxoffsent_hi;
6448c2ecf20Sopenharmony_ci	estats->pause_frames_sent_lo =
6458c2ecf20Sopenharmony_ci				pstats->mac_stx[1].tx_stat_outxoffsent_lo;
6468c2ecf20Sopenharmony_ci
6478c2ecf20Sopenharmony_ci	estats->pfc_frames_received_hi =
6488c2ecf20Sopenharmony_ci				pstats->pfc_frames_rx_hi;
6498c2ecf20Sopenharmony_ci	estats->pfc_frames_received_lo =
6508c2ecf20Sopenharmony_ci				pstats->pfc_frames_rx_lo;
6518c2ecf20Sopenharmony_ci	estats->pfc_frames_sent_hi =
6528c2ecf20Sopenharmony_ci				pstats->pfc_frames_tx_hi;
6538c2ecf20Sopenharmony_ci	estats->pfc_frames_sent_lo =
6548c2ecf20Sopenharmony_ci				pstats->pfc_frames_tx_lo;
6558c2ecf20Sopenharmony_ci}
6568c2ecf20Sopenharmony_ci
6578c2ecf20Sopenharmony_cistatic void bnx2x_mstat_stats_update(struct bnx2x *bp)
6588c2ecf20Sopenharmony_ci{
6598c2ecf20Sopenharmony_ci	struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
6608c2ecf20Sopenharmony_ci	struct bnx2x_eth_stats *estats = &bp->eth_stats;
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci	struct mstat_stats *new = bnx2x_sp(bp, mac_stats.mstat_stats);
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_ci	ADD_STAT64(stats_rx.rx_grerb, rx_stat_ifhcinbadoctets);
6658c2ecf20Sopenharmony_ci	ADD_STAT64(stats_rx.rx_grfcs, rx_stat_dot3statsfcserrors);
6668c2ecf20Sopenharmony_ci	ADD_STAT64(stats_rx.rx_grund, rx_stat_etherstatsundersizepkts);
6678c2ecf20Sopenharmony_ci	ADD_STAT64(stats_rx.rx_grovr, rx_stat_dot3statsframestoolong);
6688c2ecf20Sopenharmony_ci	ADD_STAT64(stats_rx.rx_grfrg, rx_stat_etherstatsfragments);
6698c2ecf20Sopenharmony_ci	ADD_STAT64(stats_rx.rx_grxcf, rx_stat_maccontrolframesreceived);
6708c2ecf20Sopenharmony_ci	ADD_STAT64(stats_rx.rx_grxpf, rx_stat_xoffstateentered);
6718c2ecf20Sopenharmony_ci	ADD_STAT64(stats_rx.rx_grxpf, rx_stat_mac_xpf);
6728c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gtxpf, tx_stat_outxoffsent);
6738c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gtxpf, tx_stat_flowcontroldone);
6748c2ecf20Sopenharmony_ci
6758c2ecf20Sopenharmony_ci	/* collect pfc stats */
6768c2ecf20Sopenharmony_ci	ADD_64(pstats->pfc_frames_tx_hi, new->stats_tx.tx_gtxpp_hi,
6778c2ecf20Sopenharmony_ci		pstats->pfc_frames_tx_lo, new->stats_tx.tx_gtxpp_lo);
6788c2ecf20Sopenharmony_ci	ADD_64(pstats->pfc_frames_rx_hi, new->stats_rx.rx_grxpp_hi,
6798c2ecf20Sopenharmony_ci		pstats->pfc_frames_rx_lo, new->stats_rx.rx_grxpp_lo);
6808c2ecf20Sopenharmony_ci
6818c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gt64, tx_stat_etherstatspkts64octets);
6828c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gt127,
6838c2ecf20Sopenharmony_ci			tx_stat_etherstatspkts65octetsto127octets);
6848c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gt255,
6858c2ecf20Sopenharmony_ci			tx_stat_etherstatspkts128octetsto255octets);
6868c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gt511,
6878c2ecf20Sopenharmony_ci			tx_stat_etherstatspkts256octetsto511octets);
6888c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gt1023,
6898c2ecf20Sopenharmony_ci			tx_stat_etherstatspkts512octetsto1023octets);
6908c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gt1518,
6918c2ecf20Sopenharmony_ci			tx_stat_etherstatspkts1024octetsto1522octets);
6928c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gt2047, tx_stat_mac_2047);
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gt4095, tx_stat_mac_4095);
6958c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gt9216, tx_stat_mac_9216);
6968c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gt16383, tx_stat_mac_16383);
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gterr,
6998c2ecf20Sopenharmony_ci			tx_stat_dot3statsinternalmactransmiterrors);
7008c2ecf20Sopenharmony_ci	ADD_STAT64(stats_tx.tx_gtufl, tx_stat_mac_ufl);
7018c2ecf20Sopenharmony_ci
7028c2ecf20Sopenharmony_ci	estats->etherstatspkts1024octetsto1522octets_hi =
7038c2ecf20Sopenharmony_ci	    pstats->mac_stx[1].tx_stat_etherstatspkts1024octetsto1522octets_hi;
7048c2ecf20Sopenharmony_ci	estats->etherstatspkts1024octetsto1522octets_lo =
7058c2ecf20Sopenharmony_ci	    pstats->mac_stx[1].tx_stat_etherstatspkts1024octetsto1522octets_lo;
7068c2ecf20Sopenharmony_ci
7078c2ecf20Sopenharmony_ci	estats->etherstatspktsover1522octets_hi =
7088c2ecf20Sopenharmony_ci	    pstats->mac_stx[1].tx_stat_mac_2047_hi;
7098c2ecf20Sopenharmony_ci	estats->etherstatspktsover1522octets_lo =
7108c2ecf20Sopenharmony_ci	    pstats->mac_stx[1].tx_stat_mac_2047_lo;
7118c2ecf20Sopenharmony_ci
7128c2ecf20Sopenharmony_ci	ADD_64(estats->etherstatspktsover1522octets_hi,
7138c2ecf20Sopenharmony_ci	       pstats->mac_stx[1].tx_stat_mac_4095_hi,
7148c2ecf20Sopenharmony_ci	       estats->etherstatspktsover1522octets_lo,
7158c2ecf20Sopenharmony_ci	       pstats->mac_stx[1].tx_stat_mac_4095_lo);
7168c2ecf20Sopenharmony_ci
7178c2ecf20Sopenharmony_ci	ADD_64(estats->etherstatspktsover1522octets_hi,
7188c2ecf20Sopenharmony_ci	       pstats->mac_stx[1].tx_stat_mac_9216_hi,
7198c2ecf20Sopenharmony_ci	       estats->etherstatspktsover1522octets_lo,
7208c2ecf20Sopenharmony_ci	       pstats->mac_stx[1].tx_stat_mac_9216_lo);
7218c2ecf20Sopenharmony_ci
7228c2ecf20Sopenharmony_ci	ADD_64(estats->etherstatspktsover1522octets_hi,
7238c2ecf20Sopenharmony_ci	       pstats->mac_stx[1].tx_stat_mac_16383_hi,
7248c2ecf20Sopenharmony_ci	       estats->etherstatspktsover1522octets_lo,
7258c2ecf20Sopenharmony_ci	       pstats->mac_stx[1].tx_stat_mac_16383_lo);
7268c2ecf20Sopenharmony_ci
7278c2ecf20Sopenharmony_ci	estats->pause_frames_received_hi =
7288c2ecf20Sopenharmony_ci				pstats->mac_stx[1].rx_stat_mac_xpf_hi;
7298c2ecf20Sopenharmony_ci	estats->pause_frames_received_lo =
7308c2ecf20Sopenharmony_ci				pstats->mac_stx[1].rx_stat_mac_xpf_lo;
7318c2ecf20Sopenharmony_ci
7328c2ecf20Sopenharmony_ci	estats->pause_frames_sent_hi =
7338c2ecf20Sopenharmony_ci				pstats->mac_stx[1].tx_stat_outxoffsent_hi;
7348c2ecf20Sopenharmony_ci	estats->pause_frames_sent_lo =
7358c2ecf20Sopenharmony_ci				pstats->mac_stx[1].tx_stat_outxoffsent_lo;
7368c2ecf20Sopenharmony_ci
7378c2ecf20Sopenharmony_ci	estats->pfc_frames_received_hi =
7388c2ecf20Sopenharmony_ci				pstats->pfc_frames_rx_hi;
7398c2ecf20Sopenharmony_ci	estats->pfc_frames_received_lo =
7408c2ecf20Sopenharmony_ci				pstats->pfc_frames_rx_lo;
7418c2ecf20Sopenharmony_ci	estats->pfc_frames_sent_hi =
7428c2ecf20Sopenharmony_ci				pstats->pfc_frames_tx_hi;
7438c2ecf20Sopenharmony_ci	estats->pfc_frames_sent_lo =
7448c2ecf20Sopenharmony_ci				pstats->pfc_frames_tx_lo;
7458c2ecf20Sopenharmony_ci}
7468c2ecf20Sopenharmony_ci
7478c2ecf20Sopenharmony_cistatic void bnx2x_emac_stats_update(struct bnx2x *bp)
7488c2ecf20Sopenharmony_ci{
7498c2ecf20Sopenharmony_ci	struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats);
7508c2ecf20Sopenharmony_ci	struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
7518c2ecf20Sopenharmony_ci	struct bnx2x_eth_stats *estats = &bp->eth_stats;
7528c2ecf20Sopenharmony_ci
7538c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets);
7548c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets);
7558c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors);
7568c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors);
7578c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors);
7588c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors);
7598c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts);
7608c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong);
7618c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments);
7628c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers);
7638c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived);
7648c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_xoffstateentered);
7658c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived);
7668c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived);
7678c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_outxonsent);
7688c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_outxoffsent);
7698c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_flowcontroldone);
7708c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions);
7718c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes);
7728c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes);
7738c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions);
7748c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions);
7758c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions);
7768c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets);
7778c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets);
7788c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets);
7798c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets);
7808c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets);
7818c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets);
7828c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets);
7838c2ecf20Sopenharmony_ci	UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors);
7848c2ecf20Sopenharmony_ci
7858c2ecf20Sopenharmony_ci	estats->pause_frames_received_hi =
7868c2ecf20Sopenharmony_ci			pstats->mac_stx[1].rx_stat_xonpauseframesreceived_hi;
7878c2ecf20Sopenharmony_ci	estats->pause_frames_received_lo =
7888c2ecf20Sopenharmony_ci			pstats->mac_stx[1].rx_stat_xonpauseframesreceived_lo;
7898c2ecf20Sopenharmony_ci	ADD_64(estats->pause_frames_received_hi,
7908c2ecf20Sopenharmony_ci	       pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_hi,
7918c2ecf20Sopenharmony_ci	       estats->pause_frames_received_lo,
7928c2ecf20Sopenharmony_ci	       pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_lo);
7938c2ecf20Sopenharmony_ci
7948c2ecf20Sopenharmony_ci	estats->pause_frames_sent_hi =
7958c2ecf20Sopenharmony_ci			pstats->mac_stx[1].tx_stat_outxonsent_hi;
7968c2ecf20Sopenharmony_ci	estats->pause_frames_sent_lo =
7978c2ecf20Sopenharmony_ci			pstats->mac_stx[1].tx_stat_outxonsent_lo;
7988c2ecf20Sopenharmony_ci	ADD_64(estats->pause_frames_sent_hi,
7998c2ecf20Sopenharmony_ci	       pstats->mac_stx[1].tx_stat_outxoffsent_hi,
8008c2ecf20Sopenharmony_ci	       estats->pause_frames_sent_lo,
8018c2ecf20Sopenharmony_ci	       pstats->mac_stx[1].tx_stat_outxoffsent_lo);
8028c2ecf20Sopenharmony_ci}
8038c2ecf20Sopenharmony_ci
8048c2ecf20Sopenharmony_cistatic int bnx2x_hw_stats_update(struct bnx2x *bp)
8058c2ecf20Sopenharmony_ci{
8068c2ecf20Sopenharmony_ci	struct nig_stats *new = bnx2x_sp(bp, nig_stats);
8078c2ecf20Sopenharmony_ci	struct nig_stats *old = &(bp->port.old_nig_stats);
8088c2ecf20Sopenharmony_ci	struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
8098c2ecf20Sopenharmony_ci	struct bnx2x_eth_stats *estats = &bp->eth_stats;
8108c2ecf20Sopenharmony_ci	struct {
8118c2ecf20Sopenharmony_ci		u32 lo;
8128c2ecf20Sopenharmony_ci		u32 hi;
8138c2ecf20Sopenharmony_ci	} diff;
8148c2ecf20Sopenharmony_ci
8158c2ecf20Sopenharmony_ci	switch (bp->link_vars.mac_type) {
8168c2ecf20Sopenharmony_ci	case MAC_TYPE_BMAC:
8178c2ecf20Sopenharmony_ci		bnx2x_bmac_stats_update(bp);
8188c2ecf20Sopenharmony_ci		break;
8198c2ecf20Sopenharmony_ci
8208c2ecf20Sopenharmony_ci	case MAC_TYPE_EMAC:
8218c2ecf20Sopenharmony_ci		bnx2x_emac_stats_update(bp);
8228c2ecf20Sopenharmony_ci		break;
8238c2ecf20Sopenharmony_ci
8248c2ecf20Sopenharmony_ci	case MAC_TYPE_UMAC:
8258c2ecf20Sopenharmony_ci	case MAC_TYPE_XMAC:
8268c2ecf20Sopenharmony_ci		bnx2x_mstat_stats_update(bp);
8278c2ecf20Sopenharmony_ci		break;
8288c2ecf20Sopenharmony_ci
8298c2ecf20Sopenharmony_ci	case MAC_TYPE_NONE: /* unreached */
8308c2ecf20Sopenharmony_ci		DP(BNX2X_MSG_STATS,
8318c2ecf20Sopenharmony_ci		   "stats updated by DMAE but no MAC active\n");
8328c2ecf20Sopenharmony_ci		return -1;
8338c2ecf20Sopenharmony_ci
8348c2ecf20Sopenharmony_ci	default: /* unreached */
8358c2ecf20Sopenharmony_ci		BNX2X_ERR("Unknown MAC type\n");
8368c2ecf20Sopenharmony_ci	}
8378c2ecf20Sopenharmony_ci
8388c2ecf20Sopenharmony_ci	ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo,
8398c2ecf20Sopenharmony_ci		      new->brb_discard - old->brb_discard);
8408c2ecf20Sopenharmony_ci	ADD_EXTEND_64(estats->brb_truncate_hi, estats->brb_truncate_lo,
8418c2ecf20Sopenharmony_ci		      new->brb_truncate - old->brb_truncate);
8428c2ecf20Sopenharmony_ci
8438c2ecf20Sopenharmony_ci	if (!CHIP_IS_E3(bp)) {
8448c2ecf20Sopenharmony_ci		UPDATE_STAT64_NIG(egress_mac_pkt0,
8458c2ecf20Sopenharmony_ci					etherstatspkts1024octetsto1522octets);
8468c2ecf20Sopenharmony_ci		UPDATE_STAT64_NIG(egress_mac_pkt1,
8478c2ecf20Sopenharmony_ci					etherstatspktsover1522octets);
8488c2ecf20Sopenharmony_ci	}
8498c2ecf20Sopenharmony_ci
8508c2ecf20Sopenharmony_ci	memcpy(old, new, sizeof(struct nig_stats));
8518c2ecf20Sopenharmony_ci
8528c2ecf20Sopenharmony_ci	memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]),
8538c2ecf20Sopenharmony_ci	       sizeof(struct mac_stx));
8548c2ecf20Sopenharmony_ci	estats->brb_drop_hi = pstats->brb_drop_hi;
8558c2ecf20Sopenharmony_ci	estats->brb_drop_lo = pstats->brb_drop_lo;
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_ci	pstats->host_port_stats_counter++;
8588c2ecf20Sopenharmony_ci
8598c2ecf20Sopenharmony_ci	if (CHIP_IS_E3(bp)) {
8608c2ecf20Sopenharmony_ci		u32 lpi_reg = BP_PORT(bp) ? MISC_REG_CPMU_LP_SM_ENT_CNT_P1
8618c2ecf20Sopenharmony_ci					  : MISC_REG_CPMU_LP_SM_ENT_CNT_P0;
8628c2ecf20Sopenharmony_ci		estats->eee_tx_lpi += REG_RD(bp, lpi_reg);
8638c2ecf20Sopenharmony_ci	}
8648c2ecf20Sopenharmony_ci
8658c2ecf20Sopenharmony_ci	if (!BP_NOMCP(bp)) {
8668c2ecf20Sopenharmony_ci		u32 nig_timer_max =
8678c2ecf20Sopenharmony_ci			SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer);
8688c2ecf20Sopenharmony_ci		if (nig_timer_max != estats->nig_timer_max) {
8698c2ecf20Sopenharmony_ci			estats->nig_timer_max = nig_timer_max;
8708c2ecf20Sopenharmony_ci			BNX2X_ERR("NIG timer max (%u)\n",
8718c2ecf20Sopenharmony_ci				  estats->nig_timer_max);
8728c2ecf20Sopenharmony_ci		}
8738c2ecf20Sopenharmony_ci	}
8748c2ecf20Sopenharmony_ci
8758c2ecf20Sopenharmony_ci	return 0;
8768c2ecf20Sopenharmony_ci}
8778c2ecf20Sopenharmony_ci
8788c2ecf20Sopenharmony_cistatic int bnx2x_storm_stats_validate_counters(struct bnx2x *bp)
8798c2ecf20Sopenharmony_ci{
8808c2ecf20Sopenharmony_ci	struct stats_counter *counters = &bp->fw_stats_data->storm_counters;
8818c2ecf20Sopenharmony_ci	u16 cur_stats_counter;
8828c2ecf20Sopenharmony_ci	/* Make sure we use the value of the counter
8838c2ecf20Sopenharmony_ci	 * used for sending the last stats ramrod.
8848c2ecf20Sopenharmony_ci	 */
8858c2ecf20Sopenharmony_ci	cur_stats_counter = bp->stats_counter - 1;
8868c2ecf20Sopenharmony_ci
8878c2ecf20Sopenharmony_ci	/* are storm stats valid? */
8888c2ecf20Sopenharmony_ci	if (le16_to_cpu(counters->xstats_counter) != cur_stats_counter) {
8898c2ecf20Sopenharmony_ci		DP(BNX2X_MSG_STATS,
8908c2ecf20Sopenharmony_ci		   "stats not updated by xstorm  xstorm counter (0x%x) != stats_counter (0x%x)\n",
8918c2ecf20Sopenharmony_ci		   le16_to_cpu(counters->xstats_counter), bp->stats_counter);
8928c2ecf20Sopenharmony_ci		return -EAGAIN;
8938c2ecf20Sopenharmony_ci	}
8948c2ecf20Sopenharmony_ci
8958c2ecf20Sopenharmony_ci	if (le16_to_cpu(counters->ustats_counter) != cur_stats_counter) {
8968c2ecf20Sopenharmony_ci		DP(BNX2X_MSG_STATS,
8978c2ecf20Sopenharmony_ci		   "stats not updated by ustorm  ustorm counter (0x%x) != stats_counter (0x%x)\n",
8988c2ecf20Sopenharmony_ci		   le16_to_cpu(counters->ustats_counter), bp->stats_counter);
8998c2ecf20Sopenharmony_ci		return -EAGAIN;
9008c2ecf20Sopenharmony_ci	}
9018c2ecf20Sopenharmony_ci
9028c2ecf20Sopenharmony_ci	if (le16_to_cpu(counters->cstats_counter) != cur_stats_counter) {
9038c2ecf20Sopenharmony_ci		DP(BNX2X_MSG_STATS,
9048c2ecf20Sopenharmony_ci		   "stats not updated by cstorm  cstorm counter (0x%x) != stats_counter (0x%x)\n",
9058c2ecf20Sopenharmony_ci		   le16_to_cpu(counters->cstats_counter), bp->stats_counter);
9068c2ecf20Sopenharmony_ci		return -EAGAIN;
9078c2ecf20Sopenharmony_ci	}
9088c2ecf20Sopenharmony_ci
9098c2ecf20Sopenharmony_ci	if (le16_to_cpu(counters->tstats_counter) != cur_stats_counter) {
9108c2ecf20Sopenharmony_ci		DP(BNX2X_MSG_STATS,
9118c2ecf20Sopenharmony_ci		   "stats not updated by tstorm  tstorm counter (0x%x) != stats_counter (0x%x)\n",
9128c2ecf20Sopenharmony_ci		   le16_to_cpu(counters->tstats_counter), bp->stats_counter);
9138c2ecf20Sopenharmony_ci		return -EAGAIN;
9148c2ecf20Sopenharmony_ci	}
9158c2ecf20Sopenharmony_ci	return 0;
9168c2ecf20Sopenharmony_ci}
9178c2ecf20Sopenharmony_ci
9188c2ecf20Sopenharmony_cistatic int bnx2x_storm_stats_update(struct bnx2x *bp)
9198c2ecf20Sopenharmony_ci{
9208c2ecf20Sopenharmony_ci	struct tstorm_per_port_stats *tport =
9218c2ecf20Sopenharmony_ci				&bp->fw_stats_data->port.tstorm_port_statistics;
9228c2ecf20Sopenharmony_ci	struct tstorm_per_pf_stats *tfunc =
9238c2ecf20Sopenharmony_ci				&bp->fw_stats_data->pf.tstorm_pf_statistics;
9248c2ecf20Sopenharmony_ci	struct host_func_stats *fstats = &bp->func_stats;
9258c2ecf20Sopenharmony_ci	struct bnx2x_eth_stats *estats = &bp->eth_stats;
9268c2ecf20Sopenharmony_ci	struct bnx2x_eth_stats_old *estats_old = &bp->eth_stats_old;
9278c2ecf20Sopenharmony_ci	int i;
9288c2ecf20Sopenharmony_ci
9298c2ecf20Sopenharmony_ci	/* vfs stat counter is managed by pf */
9308c2ecf20Sopenharmony_ci	if (IS_PF(bp) && bnx2x_storm_stats_validate_counters(bp))
9318c2ecf20Sopenharmony_ci		return -EAGAIN;
9328c2ecf20Sopenharmony_ci
9338c2ecf20Sopenharmony_ci	estats->error_bytes_received_hi = 0;
9348c2ecf20Sopenharmony_ci	estats->error_bytes_received_lo = 0;
9358c2ecf20Sopenharmony_ci
9368c2ecf20Sopenharmony_ci	for_each_eth_queue(bp, i) {
9378c2ecf20Sopenharmony_ci		struct bnx2x_fastpath *fp = &bp->fp[i];
9388c2ecf20Sopenharmony_ci		struct tstorm_per_queue_stats *tclient =
9398c2ecf20Sopenharmony_ci			&bp->fw_stats_data->queue_stats[i].
9408c2ecf20Sopenharmony_ci			tstorm_queue_statistics;
9418c2ecf20Sopenharmony_ci		struct tstorm_per_queue_stats *old_tclient =
9428c2ecf20Sopenharmony_ci			&bnx2x_fp_stats(bp, fp)->old_tclient;
9438c2ecf20Sopenharmony_ci		struct ustorm_per_queue_stats *uclient =
9448c2ecf20Sopenharmony_ci			&bp->fw_stats_data->queue_stats[i].
9458c2ecf20Sopenharmony_ci			ustorm_queue_statistics;
9468c2ecf20Sopenharmony_ci		struct ustorm_per_queue_stats *old_uclient =
9478c2ecf20Sopenharmony_ci			&bnx2x_fp_stats(bp, fp)->old_uclient;
9488c2ecf20Sopenharmony_ci		struct xstorm_per_queue_stats *xclient =
9498c2ecf20Sopenharmony_ci			&bp->fw_stats_data->queue_stats[i].
9508c2ecf20Sopenharmony_ci			xstorm_queue_statistics;
9518c2ecf20Sopenharmony_ci		struct xstorm_per_queue_stats *old_xclient =
9528c2ecf20Sopenharmony_ci			&bnx2x_fp_stats(bp, fp)->old_xclient;
9538c2ecf20Sopenharmony_ci		struct bnx2x_eth_q_stats *qstats =
9548c2ecf20Sopenharmony_ci			&bnx2x_fp_stats(bp, fp)->eth_q_stats;
9558c2ecf20Sopenharmony_ci		struct bnx2x_eth_q_stats_old *qstats_old =
9568c2ecf20Sopenharmony_ci			&bnx2x_fp_stats(bp, fp)->eth_q_stats_old;
9578c2ecf20Sopenharmony_ci
9588c2ecf20Sopenharmony_ci		u32 diff;
9598c2ecf20Sopenharmony_ci
9608c2ecf20Sopenharmony_ci		DP(BNX2X_MSG_STATS, "queue[%d]: ucast_sent 0x%x, bcast_sent 0x%x mcast_sent 0x%x\n",
9618c2ecf20Sopenharmony_ci		   i, xclient->ucast_pkts_sent,
9628c2ecf20Sopenharmony_ci		   xclient->bcast_pkts_sent, xclient->mcast_pkts_sent);
9638c2ecf20Sopenharmony_ci
9648c2ecf20Sopenharmony_ci		DP(BNX2X_MSG_STATS, "---------------\n");
9658c2ecf20Sopenharmony_ci
9668c2ecf20Sopenharmony_ci		UPDATE_QSTAT(tclient->rcv_bcast_bytes,
9678c2ecf20Sopenharmony_ci			     total_broadcast_bytes_received);
9688c2ecf20Sopenharmony_ci		UPDATE_QSTAT(tclient->rcv_mcast_bytes,
9698c2ecf20Sopenharmony_ci			     total_multicast_bytes_received);
9708c2ecf20Sopenharmony_ci		UPDATE_QSTAT(tclient->rcv_ucast_bytes,
9718c2ecf20Sopenharmony_ci			     total_unicast_bytes_received);
9728c2ecf20Sopenharmony_ci
9738c2ecf20Sopenharmony_ci		/*
9748c2ecf20Sopenharmony_ci		 * sum to total_bytes_received all
9758c2ecf20Sopenharmony_ci		 * unicast/multicast/broadcast
9768c2ecf20Sopenharmony_ci		 */
9778c2ecf20Sopenharmony_ci		qstats->total_bytes_received_hi =
9788c2ecf20Sopenharmony_ci			qstats->total_broadcast_bytes_received_hi;
9798c2ecf20Sopenharmony_ci		qstats->total_bytes_received_lo =
9808c2ecf20Sopenharmony_ci			qstats->total_broadcast_bytes_received_lo;
9818c2ecf20Sopenharmony_ci
9828c2ecf20Sopenharmony_ci		ADD_64(qstats->total_bytes_received_hi,
9838c2ecf20Sopenharmony_ci		       qstats->total_multicast_bytes_received_hi,
9848c2ecf20Sopenharmony_ci		       qstats->total_bytes_received_lo,
9858c2ecf20Sopenharmony_ci		       qstats->total_multicast_bytes_received_lo);
9868c2ecf20Sopenharmony_ci
9878c2ecf20Sopenharmony_ci		ADD_64(qstats->total_bytes_received_hi,
9888c2ecf20Sopenharmony_ci		       qstats->total_unicast_bytes_received_hi,
9898c2ecf20Sopenharmony_ci		       qstats->total_bytes_received_lo,
9908c2ecf20Sopenharmony_ci		       qstats->total_unicast_bytes_received_lo);
9918c2ecf20Sopenharmony_ci
9928c2ecf20Sopenharmony_ci		qstats->valid_bytes_received_hi =
9938c2ecf20Sopenharmony_ci					qstats->total_bytes_received_hi;
9948c2ecf20Sopenharmony_ci		qstats->valid_bytes_received_lo =
9958c2ecf20Sopenharmony_ci					qstats->total_bytes_received_lo;
9968c2ecf20Sopenharmony_ci
9978c2ecf20Sopenharmony_ci		UPDATE_EXTEND_TSTAT(rcv_ucast_pkts,
9988c2ecf20Sopenharmony_ci					total_unicast_packets_received);
9998c2ecf20Sopenharmony_ci		UPDATE_EXTEND_TSTAT(rcv_mcast_pkts,
10008c2ecf20Sopenharmony_ci					total_multicast_packets_received);
10018c2ecf20Sopenharmony_ci		UPDATE_EXTEND_TSTAT(rcv_bcast_pkts,
10028c2ecf20Sopenharmony_ci					total_broadcast_packets_received);
10038c2ecf20Sopenharmony_ci		UPDATE_EXTEND_E_TSTAT(pkts_too_big_discard,
10048c2ecf20Sopenharmony_ci				      etherstatsoverrsizepkts, 32);
10058c2ecf20Sopenharmony_ci		UPDATE_EXTEND_E_TSTAT(no_buff_discard, no_buff_discard, 16);
10068c2ecf20Sopenharmony_ci
10078c2ecf20Sopenharmony_ci		SUB_EXTEND_USTAT(ucast_no_buff_pkts,
10088c2ecf20Sopenharmony_ci					total_unicast_packets_received);
10098c2ecf20Sopenharmony_ci		SUB_EXTEND_USTAT(mcast_no_buff_pkts,
10108c2ecf20Sopenharmony_ci					total_multicast_packets_received);
10118c2ecf20Sopenharmony_ci		SUB_EXTEND_USTAT(bcast_no_buff_pkts,
10128c2ecf20Sopenharmony_ci					total_broadcast_packets_received);
10138c2ecf20Sopenharmony_ci		UPDATE_EXTEND_E_USTAT(ucast_no_buff_pkts, no_buff_discard);
10148c2ecf20Sopenharmony_ci		UPDATE_EXTEND_E_USTAT(mcast_no_buff_pkts, no_buff_discard);
10158c2ecf20Sopenharmony_ci		UPDATE_EXTEND_E_USTAT(bcast_no_buff_pkts, no_buff_discard);
10168c2ecf20Sopenharmony_ci
10178c2ecf20Sopenharmony_ci		UPDATE_QSTAT(xclient->bcast_bytes_sent,
10188c2ecf20Sopenharmony_ci			     total_broadcast_bytes_transmitted);
10198c2ecf20Sopenharmony_ci		UPDATE_QSTAT(xclient->mcast_bytes_sent,
10208c2ecf20Sopenharmony_ci			     total_multicast_bytes_transmitted);
10218c2ecf20Sopenharmony_ci		UPDATE_QSTAT(xclient->ucast_bytes_sent,
10228c2ecf20Sopenharmony_ci			     total_unicast_bytes_transmitted);
10238c2ecf20Sopenharmony_ci
10248c2ecf20Sopenharmony_ci		/*
10258c2ecf20Sopenharmony_ci		 * sum to total_bytes_transmitted all
10268c2ecf20Sopenharmony_ci		 * unicast/multicast/broadcast
10278c2ecf20Sopenharmony_ci		 */
10288c2ecf20Sopenharmony_ci		qstats->total_bytes_transmitted_hi =
10298c2ecf20Sopenharmony_ci				qstats->total_unicast_bytes_transmitted_hi;
10308c2ecf20Sopenharmony_ci		qstats->total_bytes_transmitted_lo =
10318c2ecf20Sopenharmony_ci				qstats->total_unicast_bytes_transmitted_lo;
10328c2ecf20Sopenharmony_ci
10338c2ecf20Sopenharmony_ci		ADD_64(qstats->total_bytes_transmitted_hi,
10348c2ecf20Sopenharmony_ci		       qstats->total_broadcast_bytes_transmitted_hi,
10358c2ecf20Sopenharmony_ci		       qstats->total_bytes_transmitted_lo,
10368c2ecf20Sopenharmony_ci		       qstats->total_broadcast_bytes_transmitted_lo);
10378c2ecf20Sopenharmony_ci
10388c2ecf20Sopenharmony_ci		ADD_64(qstats->total_bytes_transmitted_hi,
10398c2ecf20Sopenharmony_ci		       qstats->total_multicast_bytes_transmitted_hi,
10408c2ecf20Sopenharmony_ci		       qstats->total_bytes_transmitted_lo,
10418c2ecf20Sopenharmony_ci		       qstats->total_multicast_bytes_transmitted_lo);
10428c2ecf20Sopenharmony_ci
10438c2ecf20Sopenharmony_ci		UPDATE_EXTEND_XSTAT(ucast_pkts_sent,
10448c2ecf20Sopenharmony_ci					total_unicast_packets_transmitted);
10458c2ecf20Sopenharmony_ci		UPDATE_EXTEND_XSTAT(mcast_pkts_sent,
10468c2ecf20Sopenharmony_ci					total_multicast_packets_transmitted);
10478c2ecf20Sopenharmony_ci		UPDATE_EXTEND_XSTAT(bcast_pkts_sent,
10488c2ecf20Sopenharmony_ci					total_broadcast_packets_transmitted);
10498c2ecf20Sopenharmony_ci
10508c2ecf20Sopenharmony_ci		UPDATE_EXTEND_TSTAT(checksum_discard,
10518c2ecf20Sopenharmony_ci				    total_packets_received_checksum_discarded);
10528c2ecf20Sopenharmony_ci		UPDATE_EXTEND_TSTAT(ttl0_discard,
10538c2ecf20Sopenharmony_ci				    total_packets_received_ttl0_discarded);
10548c2ecf20Sopenharmony_ci
10558c2ecf20Sopenharmony_ci		UPDATE_EXTEND_XSTAT(error_drop_pkts,
10568c2ecf20Sopenharmony_ci				    total_transmitted_dropped_packets_error);
10578c2ecf20Sopenharmony_ci
10588c2ecf20Sopenharmony_ci		/* TPA aggregations completed */
10598c2ecf20Sopenharmony_ci		UPDATE_EXTEND_E_USTAT(coalesced_events, total_tpa_aggregations);
10608c2ecf20Sopenharmony_ci		/* Number of network frames aggregated by TPA */
10618c2ecf20Sopenharmony_ci		UPDATE_EXTEND_E_USTAT(coalesced_pkts,
10628c2ecf20Sopenharmony_ci				      total_tpa_aggregated_frames);
10638c2ecf20Sopenharmony_ci		/* Total number of bytes in completed TPA aggregations */
10648c2ecf20Sopenharmony_ci		UPDATE_QSTAT(uclient->coalesced_bytes, total_tpa_bytes);
10658c2ecf20Sopenharmony_ci
10668c2ecf20Sopenharmony_ci		UPDATE_ESTAT_QSTAT_64(total_tpa_bytes);
10678c2ecf20Sopenharmony_ci
10688c2ecf20Sopenharmony_ci		UPDATE_FSTAT_QSTAT(total_bytes_received);
10698c2ecf20Sopenharmony_ci		UPDATE_FSTAT_QSTAT(total_bytes_transmitted);
10708c2ecf20Sopenharmony_ci		UPDATE_FSTAT_QSTAT(total_unicast_packets_received);
10718c2ecf20Sopenharmony_ci		UPDATE_FSTAT_QSTAT(total_multicast_packets_received);
10728c2ecf20Sopenharmony_ci		UPDATE_FSTAT_QSTAT(total_broadcast_packets_received);
10738c2ecf20Sopenharmony_ci		UPDATE_FSTAT_QSTAT(total_unicast_packets_transmitted);
10748c2ecf20Sopenharmony_ci		UPDATE_FSTAT_QSTAT(total_multicast_packets_transmitted);
10758c2ecf20Sopenharmony_ci		UPDATE_FSTAT_QSTAT(total_broadcast_packets_transmitted);
10768c2ecf20Sopenharmony_ci		UPDATE_FSTAT_QSTAT(valid_bytes_received);
10778c2ecf20Sopenharmony_ci	}
10788c2ecf20Sopenharmony_ci
10798c2ecf20Sopenharmony_ci	ADD_64(estats->total_bytes_received_hi,
10808c2ecf20Sopenharmony_ci	       estats->rx_stat_ifhcinbadoctets_hi,
10818c2ecf20Sopenharmony_ci	       estats->total_bytes_received_lo,
10828c2ecf20Sopenharmony_ci	       estats->rx_stat_ifhcinbadoctets_lo);
10838c2ecf20Sopenharmony_ci
10848c2ecf20Sopenharmony_ci	ADD_64_LE(estats->total_bytes_received_hi,
10858c2ecf20Sopenharmony_ci		  tfunc->rcv_error_bytes.hi,
10868c2ecf20Sopenharmony_ci		  estats->total_bytes_received_lo,
10878c2ecf20Sopenharmony_ci		  tfunc->rcv_error_bytes.lo);
10888c2ecf20Sopenharmony_ci
10898c2ecf20Sopenharmony_ci	ADD_64_LE(estats->error_bytes_received_hi,
10908c2ecf20Sopenharmony_ci		  tfunc->rcv_error_bytes.hi,
10918c2ecf20Sopenharmony_ci		  estats->error_bytes_received_lo,
10928c2ecf20Sopenharmony_ci		  tfunc->rcv_error_bytes.lo);
10938c2ecf20Sopenharmony_ci
10948c2ecf20Sopenharmony_ci	UPDATE_ESTAT(etherstatsoverrsizepkts, rx_stat_dot3statsframestoolong);
10958c2ecf20Sopenharmony_ci
10968c2ecf20Sopenharmony_ci	ADD_64(estats->error_bytes_received_hi,
10978c2ecf20Sopenharmony_ci	       estats->rx_stat_ifhcinbadoctets_hi,
10988c2ecf20Sopenharmony_ci	       estats->error_bytes_received_lo,
10998c2ecf20Sopenharmony_ci	       estats->rx_stat_ifhcinbadoctets_lo);
11008c2ecf20Sopenharmony_ci
11018c2ecf20Sopenharmony_ci	if (bp->port.pmf) {
11028c2ecf20Sopenharmony_ci		struct bnx2x_fw_port_stats_old *fwstats = &bp->fw_stats_old;
11038c2ecf20Sopenharmony_ci		UPDATE_FW_STAT(mac_filter_discard);
11048c2ecf20Sopenharmony_ci		UPDATE_FW_STAT(mf_tag_discard);
11058c2ecf20Sopenharmony_ci		UPDATE_FW_STAT(brb_truncate_discard);
11068c2ecf20Sopenharmony_ci		UPDATE_FW_STAT(mac_discard);
11078c2ecf20Sopenharmony_ci	}
11088c2ecf20Sopenharmony_ci
11098c2ecf20Sopenharmony_ci	fstats->host_func_stats_start = ++fstats->host_func_stats_end;
11108c2ecf20Sopenharmony_ci
11118c2ecf20Sopenharmony_ci	bp->stats_pending = 0;
11128c2ecf20Sopenharmony_ci
11138c2ecf20Sopenharmony_ci	return 0;
11148c2ecf20Sopenharmony_ci}
11158c2ecf20Sopenharmony_ci
11168c2ecf20Sopenharmony_cistatic void bnx2x_net_stats_update(struct bnx2x *bp)
11178c2ecf20Sopenharmony_ci{
11188c2ecf20Sopenharmony_ci	struct bnx2x_eth_stats *estats = &bp->eth_stats;
11198c2ecf20Sopenharmony_ci	struct net_device_stats *nstats = &bp->dev->stats;
11208c2ecf20Sopenharmony_ci	unsigned long tmp;
11218c2ecf20Sopenharmony_ci	int i;
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_ci	nstats->rx_packets =
11248c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->total_unicast_packets_received_hi) +
11258c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->total_multicast_packets_received_hi) +
11268c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->total_broadcast_packets_received_hi);
11278c2ecf20Sopenharmony_ci
11288c2ecf20Sopenharmony_ci	nstats->tx_packets =
11298c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->total_unicast_packets_transmitted_hi) +
11308c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) +
11318c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi);
11328c2ecf20Sopenharmony_ci
11338c2ecf20Sopenharmony_ci	nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi);
11348c2ecf20Sopenharmony_ci
11358c2ecf20Sopenharmony_ci	nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
11368c2ecf20Sopenharmony_ci
11378c2ecf20Sopenharmony_ci	tmp = estats->mac_discard;
11388c2ecf20Sopenharmony_ci	for_each_rx_queue(bp, i) {
11398c2ecf20Sopenharmony_ci		struct tstorm_per_queue_stats *old_tclient =
11408c2ecf20Sopenharmony_ci			&bp->fp_stats[i].old_tclient;
11418c2ecf20Sopenharmony_ci		tmp += le32_to_cpu(old_tclient->checksum_discard);
11428c2ecf20Sopenharmony_ci	}
11438c2ecf20Sopenharmony_ci	nstats->rx_dropped = tmp + bp->net_stats_old.rx_dropped;
11448c2ecf20Sopenharmony_ci
11458c2ecf20Sopenharmony_ci	nstats->tx_dropped = 0;
11468c2ecf20Sopenharmony_ci
11478c2ecf20Sopenharmony_ci	nstats->multicast =
11488c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->total_multicast_packets_received_hi);
11498c2ecf20Sopenharmony_ci
11508c2ecf20Sopenharmony_ci	nstats->collisions =
11518c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->tx_stat_etherstatscollisions_hi);
11528c2ecf20Sopenharmony_ci
11538c2ecf20Sopenharmony_ci	nstats->rx_length_errors =
11548c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->rx_stat_etherstatsundersizepkts_hi) +
11558c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->etherstatsoverrsizepkts_hi);
11568c2ecf20Sopenharmony_ci	nstats->rx_over_errors = bnx2x_hilo(&estats->brb_drop_hi) +
11578c2ecf20Sopenharmony_ci				 bnx2x_hilo(&estats->brb_truncate_hi);
11588c2ecf20Sopenharmony_ci	nstats->rx_crc_errors =
11598c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->rx_stat_dot3statsfcserrors_hi);
11608c2ecf20Sopenharmony_ci	nstats->rx_frame_errors =
11618c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->rx_stat_dot3statsalignmenterrors_hi);
11628c2ecf20Sopenharmony_ci	nstats->rx_fifo_errors = bnx2x_hilo(&estats->no_buff_discard_hi);
11638c2ecf20Sopenharmony_ci	nstats->rx_missed_errors = 0;
11648c2ecf20Sopenharmony_ci
11658c2ecf20Sopenharmony_ci	nstats->rx_errors = nstats->rx_length_errors +
11668c2ecf20Sopenharmony_ci			    nstats->rx_over_errors +
11678c2ecf20Sopenharmony_ci			    nstats->rx_crc_errors +
11688c2ecf20Sopenharmony_ci			    nstats->rx_frame_errors +
11698c2ecf20Sopenharmony_ci			    nstats->rx_fifo_errors +
11708c2ecf20Sopenharmony_ci			    nstats->rx_missed_errors;
11718c2ecf20Sopenharmony_ci
11728c2ecf20Sopenharmony_ci	nstats->tx_aborted_errors =
11738c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->tx_stat_dot3statslatecollisions_hi) +
11748c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->tx_stat_dot3statsexcessivecollisions_hi);
11758c2ecf20Sopenharmony_ci	nstats->tx_carrier_errors =
11768c2ecf20Sopenharmony_ci		bnx2x_hilo(&estats->rx_stat_dot3statscarriersenseerrors_hi);
11778c2ecf20Sopenharmony_ci	nstats->tx_fifo_errors = 0;
11788c2ecf20Sopenharmony_ci	nstats->tx_heartbeat_errors = 0;
11798c2ecf20Sopenharmony_ci	nstats->tx_window_errors = 0;
11808c2ecf20Sopenharmony_ci
11818c2ecf20Sopenharmony_ci	nstats->tx_errors = nstats->tx_aborted_errors +
11828c2ecf20Sopenharmony_ci			    nstats->tx_carrier_errors +
11838c2ecf20Sopenharmony_ci	    bnx2x_hilo(&estats->tx_stat_dot3statsinternalmactransmiterrors_hi);
11848c2ecf20Sopenharmony_ci}
11858c2ecf20Sopenharmony_ci
11868c2ecf20Sopenharmony_cistatic void bnx2x_drv_stats_update(struct bnx2x *bp)
11878c2ecf20Sopenharmony_ci{
11888c2ecf20Sopenharmony_ci	struct bnx2x_eth_stats *estats = &bp->eth_stats;
11898c2ecf20Sopenharmony_ci	int i;
11908c2ecf20Sopenharmony_ci
11918c2ecf20Sopenharmony_ci	for_each_queue(bp, i) {
11928c2ecf20Sopenharmony_ci		struct bnx2x_eth_q_stats *qstats = &bp->fp_stats[i].eth_q_stats;
11938c2ecf20Sopenharmony_ci		struct bnx2x_eth_q_stats_old *qstats_old =
11948c2ecf20Sopenharmony_ci			&bp->fp_stats[i].eth_q_stats_old;
11958c2ecf20Sopenharmony_ci
11968c2ecf20Sopenharmony_ci		UPDATE_ESTAT_QSTAT(driver_xoff);
11978c2ecf20Sopenharmony_ci		UPDATE_ESTAT_QSTAT(rx_err_discard_pkt);
11988c2ecf20Sopenharmony_ci		UPDATE_ESTAT_QSTAT(rx_skb_alloc_failed);
11998c2ecf20Sopenharmony_ci		UPDATE_ESTAT_QSTAT(hw_csum_err);
12008c2ecf20Sopenharmony_ci		UPDATE_ESTAT_QSTAT(driver_filtered_tx_pkt);
12018c2ecf20Sopenharmony_ci	}
12028c2ecf20Sopenharmony_ci}
12038c2ecf20Sopenharmony_ci
12048c2ecf20Sopenharmony_cistatic bool bnx2x_edebug_stats_stopped(struct bnx2x *bp)
12058c2ecf20Sopenharmony_ci{
12068c2ecf20Sopenharmony_ci	u32 val;
12078c2ecf20Sopenharmony_ci
12088c2ecf20Sopenharmony_ci	if (SHMEM2_HAS(bp, edebug_driver_if[1])) {
12098c2ecf20Sopenharmony_ci		val = SHMEM2_RD(bp, edebug_driver_if[1]);
12108c2ecf20Sopenharmony_ci
12118c2ecf20Sopenharmony_ci		if (val == EDEBUG_DRIVER_IF_OP_CODE_DISABLE_STAT)
12128c2ecf20Sopenharmony_ci			return true;
12138c2ecf20Sopenharmony_ci	}
12148c2ecf20Sopenharmony_ci
12158c2ecf20Sopenharmony_ci	return false;
12168c2ecf20Sopenharmony_ci}
12178c2ecf20Sopenharmony_ci
12188c2ecf20Sopenharmony_cistatic void bnx2x_stats_update(struct bnx2x *bp)
12198c2ecf20Sopenharmony_ci{
12208c2ecf20Sopenharmony_ci	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
12218c2ecf20Sopenharmony_ci
12228c2ecf20Sopenharmony_ci	if (bnx2x_edebug_stats_stopped(bp))
12238c2ecf20Sopenharmony_ci		return;
12248c2ecf20Sopenharmony_ci
12258c2ecf20Sopenharmony_ci	if (IS_PF(bp)) {
12268c2ecf20Sopenharmony_ci		if (*stats_comp != DMAE_COMP_VAL)
12278c2ecf20Sopenharmony_ci			return;
12288c2ecf20Sopenharmony_ci
12298c2ecf20Sopenharmony_ci		if (bp->port.pmf)
12308c2ecf20Sopenharmony_ci			bnx2x_hw_stats_update(bp);
12318c2ecf20Sopenharmony_ci
12328c2ecf20Sopenharmony_ci		if (bnx2x_storm_stats_update(bp)) {
12338c2ecf20Sopenharmony_ci			if (bp->stats_pending++ == 3) {
12348c2ecf20Sopenharmony_ci				BNX2X_ERR("storm stats were not updated for 3 times\n");
12358c2ecf20Sopenharmony_ci				bnx2x_panic();
12368c2ecf20Sopenharmony_ci			}
12378c2ecf20Sopenharmony_ci			return;
12388c2ecf20Sopenharmony_ci		}
12398c2ecf20Sopenharmony_ci	} else {
12408c2ecf20Sopenharmony_ci		/* vf doesn't collect HW statistics, and doesn't get completions
12418c2ecf20Sopenharmony_ci		 * perform only update
12428c2ecf20Sopenharmony_ci		 */
12438c2ecf20Sopenharmony_ci		bnx2x_storm_stats_update(bp);
12448c2ecf20Sopenharmony_ci	}
12458c2ecf20Sopenharmony_ci
12468c2ecf20Sopenharmony_ci	bnx2x_net_stats_update(bp);
12478c2ecf20Sopenharmony_ci	bnx2x_drv_stats_update(bp);
12488c2ecf20Sopenharmony_ci
12498c2ecf20Sopenharmony_ci	/* vf is done */
12508c2ecf20Sopenharmony_ci	if (IS_VF(bp))
12518c2ecf20Sopenharmony_ci		return;
12528c2ecf20Sopenharmony_ci
12538c2ecf20Sopenharmony_ci	if (netif_msg_timer(bp)) {
12548c2ecf20Sopenharmony_ci		struct bnx2x_eth_stats *estats = &bp->eth_stats;
12558c2ecf20Sopenharmony_ci
12568c2ecf20Sopenharmony_ci		netdev_dbg(bp->dev, "brb drops %u  brb truncate %u\n",
12578c2ecf20Sopenharmony_ci		       estats->brb_drop_lo, estats->brb_truncate_lo);
12588c2ecf20Sopenharmony_ci	}
12598c2ecf20Sopenharmony_ci
12608c2ecf20Sopenharmony_ci	bnx2x_hw_stats_post(bp);
12618c2ecf20Sopenharmony_ci	bnx2x_storm_stats_post(bp);
12628c2ecf20Sopenharmony_ci}
12638c2ecf20Sopenharmony_ci
12648c2ecf20Sopenharmony_cistatic void bnx2x_port_stats_stop(struct bnx2x *bp)
12658c2ecf20Sopenharmony_ci{
12668c2ecf20Sopenharmony_ci	struct dmae_command *dmae;
12678c2ecf20Sopenharmony_ci	u32 opcode;
12688c2ecf20Sopenharmony_ci	int loader_idx = PMF_DMAE_C(bp);
12698c2ecf20Sopenharmony_ci	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
12708c2ecf20Sopenharmony_ci
12718c2ecf20Sopenharmony_ci	bp->executer_idx = 0;
12728c2ecf20Sopenharmony_ci
12738c2ecf20Sopenharmony_ci	opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, false, 0);
12748c2ecf20Sopenharmony_ci
12758c2ecf20Sopenharmony_ci	if (bp->port.port_stx) {
12768c2ecf20Sopenharmony_ci
12778c2ecf20Sopenharmony_ci		dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
12788c2ecf20Sopenharmony_ci		if (bp->func_stx)
12798c2ecf20Sopenharmony_ci			dmae->opcode = bnx2x_dmae_opcode_add_comp(
12808c2ecf20Sopenharmony_ci						opcode, DMAE_COMP_GRC);
12818c2ecf20Sopenharmony_ci		else
12828c2ecf20Sopenharmony_ci			dmae->opcode = bnx2x_dmae_opcode_add_comp(
12838c2ecf20Sopenharmony_ci						opcode, DMAE_COMP_PCI);
12848c2ecf20Sopenharmony_ci
12858c2ecf20Sopenharmony_ci		dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
12868c2ecf20Sopenharmony_ci		dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
12878c2ecf20Sopenharmony_ci		dmae->dst_addr_lo = bp->port.port_stx >> 2;
12888c2ecf20Sopenharmony_ci		dmae->dst_addr_hi = 0;
12898c2ecf20Sopenharmony_ci		dmae->len = bnx2x_get_port_stats_dma_len(bp);
12908c2ecf20Sopenharmony_ci		if (bp->func_stx) {
12918c2ecf20Sopenharmony_ci			dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
12928c2ecf20Sopenharmony_ci			dmae->comp_addr_hi = 0;
12938c2ecf20Sopenharmony_ci			dmae->comp_val = 1;
12948c2ecf20Sopenharmony_ci		} else {
12958c2ecf20Sopenharmony_ci			dmae->comp_addr_lo =
12968c2ecf20Sopenharmony_ci				U64_LO(bnx2x_sp_mapping(bp, stats_comp));
12978c2ecf20Sopenharmony_ci			dmae->comp_addr_hi =
12988c2ecf20Sopenharmony_ci				U64_HI(bnx2x_sp_mapping(bp, stats_comp));
12998c2ecf20Sopenharmony_ci			dmae->comp_val = DMAE_COMP_VAL;
13008c2ecf20Sopenharmony_ci
13018c2ecf20Sopenharmony_ci			*stats_comp = 0;
13028c2ecf20Sopenharmony_ci		}
13038c2ecf20Sopenharmony_ci	}
13048c2ecf20Sopenharmony_ci
13058c2ecf20Sopenharmony_ci	if (bp->func_stx) {
13068c2ecf20Sopenharmony_ci
13078c2ecf20Sopenharmony_ci		dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
13088c2ecf20Sopenharmony_ci		dmae->opcode =
13098c2ecf20Sopenharmony_ci			bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
13108c2ecf20Sopenharmony_ci		dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
13118c2ecf20Sopenharmony_ci		dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
13128c2ecf20Sopenharmony_ci		dmae->dst_addr_lo = bp->func_stx >> 2;
13138c2ecf20Sopenharmony_ci		dmae->dst_addr_hi = 0;
13148c2ecf20Sopenharmony_ci		dmae->len = sizeof(struct host_func_stats) >> 2;
13158c2ecf20Sopenharmony_ci		dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
13168c2ecf20Sopenharmony_ci		dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
13178c2ecf20Sopenharmony_ci		dmae->comp_val = DMAE_COMP_VAL;
13188c2ecf20Sopenharmony_ci
13198c2ecf20Sopenharmony_ci		*stats_comp = 0;
13208c2ecf20Sopenharmony_ci	}
13218c2ecf20Sopenharmony_ci}
13228c2ecf20Sopenharmony_ci
13238c2ecf20Sopenharmony_cistatic void bnx2x_stats_stop(struct bnx2x *bp)
13248c2ecf20Sopenharmony_ci{
13258c2ecf20Sopenharmony_ci	bool update = false;
13268c2ecf20Sopenharmony_ci
13278c2ecf20Sopenharmony_ci	bnx2x_stats_comp(bp);
13288c2ecf20Sopenharmony_ci
13298c2ecf20Sopenharmony_ci	if (bp->port.pmf)
13308c2ecf20Sopenharmony_ci		update = (bnx2x_hw_stats_update(bp) == 0);
13318c2ecf20Sopenharmony_ci
13328c2ecf20Sopenharmony_ci	update |= (bnx2x_storm_stats_update(bp) == 0);
13338c2ecf20Sopenharmony_ci
13348c2ecf20Sopenharmony_ci	if (update) {
13358c2ecf20Sopenharmony_ci		bnx2x_net_stats_update(bp);
13368c2ecf20Sopenharmony_ci
13378c2ecf20Sopenharmony_ci		if (bp->port.pmf)
13388c2ecf20Sopenharmony_ci			bnx2x_port_stats_stop(bp);
13398c2ecf20Sopenharmony_ci
13408c2ecf20Sopenharmony_ci		bnx2x_hw_stats_post(bp);
13418c2ecf20Sopenharmony_ci		bnx2x_stats_comp(bp);
13428c2ecf20Sopenharmony_ci	}
13438c2ecf20Sopenharmony_ci}
13448c2ecf20Sopenharmony_ci
13458c2ecf20Sopenharmony_cistatic void bnx2x_stats_do_nothing(struct bnx2x *bp)
13468c2ecf20Sopenharmony_ci{
13478c2ecf20Sopenharmony_ci}
13488c2ecf20Sopenharmony_ci
13498c2ecf20Sopenharmony_cistatic const struct {
13508c2ecf20Sopenharmony_ci	void (*action)(struct bnx2x *bp);
13518c2ecf20Sopenharmony_ci	enum bnx2x_stats_state next_state;
13528c2ecf20Sopenharmony_ci} bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = {
13538c2ecf20Sopenharmony_ci/* state	event	*/
13548c2ecf20Sopenharmony_ci{
13558c2ecf20Sopenharmony_ci/* DISABLED	PMF	*/ {bnx2x_stats_pmf_update, STATS_STATE_DISABLED},
13568c2ecf20Sopenharmony_ci/*		LINK_UP	*/ {bnx2x_stats_start,      STATS_STATE_ENABLED},
13578c2ecf20Sopenharmony_ci/*		UPDATE	*/ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED},
13588c2ecf20Sopenharmony_ci/*		STOP	*/ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED}
13598c2ecf20Sopenharmony_ci},
13608c2ecf20Sopenharmony_ci{
13618c2ecf20Sopenharmony_ci/* ENABLED	PMF	*/ {bnx2x_stats_pmf_start,  STATS_STATE_ENABLED},
13628c2ecf20Sopenharmony_ci/*		LINK_UP	*/ {bnx2x_stats_restart,    STATS_STATE_ENABLED},
13638c2ecf20Sopenharmony_ci/*		UPDATE	*/ {bnx2x_stats_update,     STATS_STATE_ENABLED},
13648c2ecf20Sopenharmony_ci/*		STOP	*/ {bnx2x_stats_stop,       STATS_STATE_DISABLED}
13658c2ecf20Sopenharmony_ci}
13668c2ecf20Sopenharmony_ci};
13678c2ecf20Sopenharmony_ci
13688c2ecf20Sopenharmony_civoid bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
13698c2ecf20Sopenharmony_ci{
13708c2ecf20Sopenharmony_ci	enum bnx2x_stats_state state = bp->stats_state;
13718c2ecf20Sopenharmony_ci
13728c2ecf20Sopenharmony_ci	if (unlikely(bp->panic))
13738c2ecf20Sopenharmony_ci		return;
13748c2ecf20Sopenharmony_ci
13758c2ecf20Sopenharmony_ci	/* Statistics update run from timer context, and we don't want to stop
13768c2ecf20Sopenharmony_ci	 * that context in case someone is in the middle of a transition.
13778c2ecf20Sopenharmony_ci	 * For other events, wait a bit until lock is taken.
13788c2ecf20Sopenharmony_ci	 */
13798c2ecf20Sopenharmony_ci	if (down_trylock(&bp->stats_lock)) {
13808c2ecf20Sopenharmony_ci		if (event == STATS_EVENT_UPDATE)
13818c2ecf20Sopenharmony_ci			return;
13828c2ecf20Sopenharmony_ci
13838c2ecf20Sopenharmony_ci		DP(BNX2X_MSG_STATS,
13848c2ecf20Sopenharmony_ci		   "Unlikely stats' lock contention [event %d]\n", event);
13858c2ecf20Sopenharmony_ci		if (unlikely(down_timeout(&bp->stats_lock, HZ / 10))) {
13868c2ecf20Sopenharmony_ci			BNX2X_ERR("Failed to take stats lock [event %d]\n",
13878c2ecf20Sopenharmony_ci				  event);
13888c2ecf20Sopenharmony_ci			return;
13898c2ecf20Sopenharmony_ci		}
13908c2ecf20Sopenharmony_ci	}
13918c2ecf20Sopenharmony_ci
13928c2ecf20Sopenharmony_ci	bnx2x_stats_stm[state][event].action(bp);
13938c2ecf20Sopenharmony_ci	bp->stats_state = bnx2x_stats_stm[state][event].next_state;
13948c2ecf20Sopenharmony_ci
13958c2ecf20Sopenharmony_ci	up(&bp->stats_lock);
13968c2ecf20Sopenharmony_ci
13978c2ecf20Sopenharmony_ci	if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp))
13988c2ecf20Sopenharmony_ci		DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
13998c2ecf20Sopenharmony_ci		   state, event, bp->stats_state);
14008c2ecf20Sopenharmony_ci}
14018c2ecf20Sopenharmony_ci
14028c2ecf20Sopenharmony_cistatic void bnx2x_port_stats_base_init(struct bnx2x *bp)
14038c2ecf20Sopenharmony_ci{
14048c2ecf20Sopenharmony_ci	struct dmae_command *dmae;
14058c2ecf20Sopenharmony_ci	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
14068c2ecf20Sopenharmony_ci
14078c2ecf20Sopenharmony_ci	/* sanity */
14088c2ecf20Sopenharmony_ci	if (!bp->port.pmf || !bp->port.port_stx) {
14098c2ecf20Sopenharmony_ci		BNX2X_ERR("BUG!\n");
14108c2ecf20Sopenharmony_ci		return;
14118c2ecf20Sopenharmony_ci	}
14128c2ecf20Sopenharmony_ci
14138c2ecf20Sopenharmony_ci	bp->executer_idx = 0;
14148c2ecf20Sopenharmony_ci
14158c2ecf20Sopenharmony_ci	dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
14168c2ecf20Sopenharmony_ci	dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC,
14178c2ecf20Sopenharmony_ci					 true, DMAE_COMP_PCI);
14188c2ecf20Sopenharmony_ci	dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
14198c2ecf20Sopenharmony_ci	dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
14208c2ecf20Sopenharmony_ci	dmae->dst_addr_lo = bp->port.port_stx >> 2;
14218c2ecf20Sopenharmony_ci	dmae->dst_addr_hi = 0;
14228c2ecf20Sopenharmony_ci	dmae->len = bnx2x_get_port_stats_dma_len(bp);
14238c2ecf20Sopenharmony_ci	dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
14248c2ecf20Sopenharmony_ci	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
14258c2ecf20Sopenharmony_ci	dmae->comp_val = DMAE_COMP_VAL;
14268c2ecf20Sopenharmony_ci
14278c2ecf20Sopenharmony_ci	*stats_comp = 0;
14288c2ecf20Sopenharmony_ci	bnx2x_hw_stats_post(bp);
14298c2ecf20Sopenharmony_ci	bnx2x_stats_comp(bp);
14308c2ecf20Sopenharmony_ci}
14318c2ecf20Sopenharmony_ci
14328c2ecf20Sopenharmony_ci/* This function will prepare the statistics ramrod data the way
14338c2ecf20Sopenharmony_ci * we will only have to increment the statistics counter and
14348c2ecf20Sopenharmony_ci * send the ramrod each time we have to.
14358c2ecf20Sopenharmony_ci */
14368c2ecf20Sopenharmony_cistatic void bnx2x_prep_fw_stats_req(struct bnx2x *bp)
14378c2ecf20Sopenharmony_ci{
14388c2ecf20Sopenharmony_ci	int i;
14398c2ecf20Sopenharmony_ci	int first_queue_query_index;
14408c2ecf20Sopenharmony_ci	struct stats_query_header *stats_hdr = &bp->fw_stats_req->hdr;
14418c2ecf20Sopenharmony_ci
14428c2ecf20Sopenharmony_ci	dma_addr_t cur_data_offset;
14438c2ecf20Sopenharmony_ci	struct stats_query_entry *cur_query_entry;
14448c2ecf20Sopenharmony_ci
14458c2ecf20Sopenharmony_ci	stats_hdr->cmd_num = bp->fw_stats_num;
14468c2ecf20Sopenharmony_ci	stats_hdr->drv_stats_counter = 0;
14478c2ecf20Sopenharmony_ci
14488c2ecf20Sopenharmony_ci	/* storm_counters struct contains the counters of completed
14498c2ecf20Sopenharmony_ci	 * statistics requests per storm which are incremented by FW
14508c2ecf20Sopenharmony_ci	 * each time it completes hadning a statistics ramrod. We will
14518c2ecf20Sopenharmony_ci	 * check these counters in the timer handler and discard a
14528c2ecf20Sopenharmony_ci	 * (statistics) ramrod completion.
14538c2ecf20Sopenharmony_ci	 */
14548c2ecf20Sopenharmony_ci	cur_data_offset = bp->fw_stats_data_mapping +
14558c2ecf20Sopenharmony_ci		offsetof(struct bnx2x_fw_stats_data, storm_counters);
14568c2ecf20Sopenharmony_ci
14578c2ecf20Sopenharmony_ci	stats_hdr->stats_counters_addrs.hi =
14588c2ecf20Sopenharmony_ci		cpu_to_le32(U64_HI(cur_data_offset));
14598c2ecf20Sopenharmony_ci	stats_hdr->stats_counters_addrs.lo =
14608c2ecf20Sopenharmony_ci		cpu_to_le32(U64_LO(cur_data_offset));
14618c2ecf20Sopenharmony_ci
14628c2ecf20Sopenharmony_ci	/* prepare to the first stats ramrod (will be completed with
14638c2ecf20Sopenharmony_ci	 * the counters equal to zero) - init counters to somethig different.
14648c2ecf20Sopenharmony_ci	 */
14658c2ecf20Sopenharmony_ci	memset(&bp->fw_stats_data->storm_counters, 0xff,
14668c2ecf20Sopenharmony_ci	       sizeof(struct stats_counter));
14678c2ecf20Sopenharmony_ci
14688c2ecf20Sopenharmony_ci	/**** Port FW statistics data ****/
14698c2ecf20Sopenharmony_ci	cur_data_offset = bp->fw_stats_data_mapping +
14708c2ecf20Sopenharmony_ci		offsetof(struct bnx2x_fw_stats_data, port);
14718c2ecf20Sopenharmony_ci
14728c2ecf20Sopenharmony_ci	cur_query_entry = &bp->fw_stats_req->query[BNX2X_PORT_QUERY_IDX];
14738c2ecf20Sopenharmony_ci
14748c2ecf20Sopenharmony_ci	cur_query_entry->kind = STATS_TYPE_PORT;
14758c2ecf20Sopenharmony_ci	/* For port query index is a DONT CARE */
14768c2ecf20Sopenharmony_ci	cur_query_entry->index = BP_PORT(bp);
14778c2ecf20Sopenharmony_ci	/* For port query funcID is a DONT CARE */
14788c2ecf20Sopenharmony_ci	cur_query_entry->funcID = cpu_to_le16(BP_FUNC(bp));
14798c2ecf20Sopenharmony_ci	cur_query_entry->address.hi = cpu_to_le32(U64_HI(cur_data_offset));
14808c2ecf20Sopenharmony_ci	cur_query_entry->address.lo = cpu_to_le32(U64_LO(cur_data_offset));
14818c2ecf20Sopenharmony_ci
14828c2ecf20Sopenharmony_ci	/**** PF FW statistics data ****/
14838c2ecf20Sopenharmony_ci	cur_data_offset = bp->fw_stats_data_mapping +
14848c2ecf20Sopenharmony_ci		offsetof(struct bnx2x_fw_stats_data, pf);
14858c2ecf20Sopenharmony_ci
14868c2ecf20Sopenharmony_ci	cur_query_entry = &bp->fw_stats_req->query[BNX2X_PF_QUERY_IDX];
14878c2ecf20Sopenharmony_ci
14888c2ecf20Sopenharmony_ci	cur_query_entry->kind = STATS_TYPE_PF;
14898c2ecf20Sopenharmony_ci	/* For PF query index is a DONT CARE */
14908c2ecf20Sopenharmony_ci	cur_query_entry->index = BP_PORT(bp);
14918c2ecf20Sopenharmony_ci	cur_query_entry->funcID = cpu_to_le16(BP_FUNC(bp));
14928c2ecf20Sopenharmony_ci	cur_query_entry->address.hi = cpu_to_le32(U64_HI(cur_data_offset));
14938c2ecf20Sopenharmony_ci	cur_query_entry->address.lo = cpu_to_le32(U64_LO(cur_data_offset));
14948c2ecf20Sopenharmony_ci
14958c2ecf20Sopenharmony_ci	/**** FCoE FW statistics data ****/
14968c2ecf20Sopenharmony_ci	if (!NO_FCOE(bp)) {
14978c2ecf20Sopenharmony_ci		cur_data_offset = bp->fw_stats_data_mapping +
14988c2ecf20Sopenharmony_ci			offsetof(struct bnx2x_fw_stats_data, fcoe);
14998c2ecf20Sopenharmony_ci
15008c2ecf20Sopenharmony_ci		cur_query_entry =
15018c2ecf20Sopenharmony_ci			&bp->fw_stats_req->query[BNX2X_FCOE_QUERY_IDX];
15028c2ecf20Sopenharmony_ci
15038c2ecf20Sopenharmony_ci		cur_query_entry->kind = STATS_TYPE_FCOE;
15048c2ecf20Sopenharmony_ci		/* For FCoE query index is a DONT CARE */
15058c2ecf20Sopenharmony_ci		cur_query_entry->index = BP_PORT(bp);
15068c2ecf20Sopenharmony_ci		cur_query_entry->funcID = cpu_to_le16(BP_FUNC(bp));
15078c2ecf20Sopenharmony_ci		cur_query_entry->address.hi =
15088c2ecf20Sopenharmony_ci			cpu_to_le32(U64_HI(cur_data_offset));
15098c2ecf20Sopenharmony_ci		cur_query_entry->address.lo =
15108c2ecf20Sopenharmony_ci			cpu_to_le32(U64_LO(cur_data_offset));
15118c2ecf20Sopenharmony_ci	}
15128c2ecf20Sopenharmony_ci
15138c2ecf20Sopenharmony_ci	/**** Clients' queries ****/
15148c2ecf20Sopenharmony_ci	cur_data_offset = bp->fw_stats_data_mapping +
15158c2ecf20Sopenharmony_ci		offsetof(struct bnx2x_fw_stats_data, queue_stats);
15168c2ecf20Sopenharmony_ci
15178c2ecf20Sopenharmony_ci	/* first queue query index depends whether FCoE offloaded request will
15188c2ecf20Sopenharmony_ci	 * be included in the ramrod
15198c2ecf20Sopenharmony_ci	 */
15208c2ecf20Sopenharmony_ci	if (!NO_FCOE(bp))
15218c2ecf20Sopenharmony_ci		first_queue_query_index = BNX2X_FIRST_QUEUE_QUERY_IDX;
15228c2ecf20Sopenharmony_ci	else
15238c2ecf20Sopenharmony_ci		first_queue_query_index = BNX2X_FIRST_QUEUE_QUERY_IDX - 1;
15248c2ecf20Sopenharmony_ci
15258c2ecf20Sopenharmony_ci	for_each_eth_queue(bp, i) {
15268c2ecf20Sopenharmony_ci		cur_query_entry =
15278c2ecf20Sopenharmony_ci			&bp->fw_stats_req->
15288c2ecf20Sopenharmony_ci					query[first_queue_query_index + i];
15298c2ecf20Sopenharmony_ci
15308c2ecf20Sopenharmony_ci		cur_query_entry->kind = STATS_TYPE_QUEUE;
15318c2ecf20Sopenharmony_ci		cur_query_entry->index = bnx2x_stats_id(&bp->fp[i]);
15328c2ecf20Sopenharmony_ci		cur_query_entry->funcID = cpu_to_le16(BP_FUNC(bp));
15338c2ecf20Sopenharmony_ci		cur_query_entry->address.hi =
15348c2ecf20Sopenharmony_ci			cpu_to_le32(U64_HI(cur_data_offset));
15358c2ecf20Sopenharmony_ci		cur_query_entry->address.lo =
15368c2ecf20Sopenharmony_ci			cpu_to_le32(U64_LO(cur_data_offset));
15378c2ecf20Sopenharmony_ci
15388c2ecf20Sopenharmony_ci		cur_data_offset += sizeof(struct per_queue_stats);
15398c2ecf20Sopenharmony_ci	}
15408c2ecf20Sopenharmony_ci
15418c2ecf20Sopenharmony_ci	/* add FCoE queue query if needed */
15428c2ecf20Sopenharmony_ci	if (!NO_FCOE(bp)) {
15438c2ecf20Sopenharmony_ci		cur_query_entry =
15448c2ecf20Sopenharmony_ci			&bp->fw_stats_req->
15458c2ecf20Sopenharmony_ci					query[first_queue_query_index + i];
15468c2ecf20Sopenharmony_ci
15478c2ecf20Sopenharmony_ci		cur_query_entry->kind = STATS_TYPE_QUEUE;
15488c2ecf20Sopenharmony_ci		cur_query_entry->index = bnx2x_stats_id(&bp->fp[FCOE_IDX(bp)]);
15498c2ecf20Sopenharmony_ci		cur_query_entry->funcID = cpu_to_le16(BP_FUNC(bp));
15508c2ecf20Sopenharmony_ci		cur_query_entry->address.hi =
15518c2ecf20Sopenharmony_ci			cpu_to_le32(U64_HI(cur_data_offset));
15528c2ecf20Sopenharmony_ci		cur_query_entry->address.lo =
15538c2ecf20Sopenharmony_ci			cpu_to_le32(U64_LO(cur_data_offset));
15548c2ecf20Sopenharmony_ci	}
15558c2ecf20Sopenharmony_ci}
15568c2ecf20Sopenharmony_ci
15578c2ecf20Sopenharmony_civoid bnx2x_memset_stats(struct bnx2x *bp)
15588c2ecf20Sopenharmony_ci{
15598c2ecf20Sopenharmony_ci	int i;
15608c2ecf20Sopenharmony_ci
15618c2ecf20Sopenharmony_ci	/* function stats */
15628c2ecf20Sopenharmony_ci	for_each_queue(bp, i) {
15638c2ecf20Sopenharmony_ci		struct bnx2x_fp_stats *fp_stats = &bp->fp_stats[i];
15648c2ecf20Sopenharmony_ci
15658c2ecf20Sopenharmony_ci		memset(&fp_stats->old_tclient, 0,
15668c2ecf20Sopenharmony_ci		       sizeof(fp_stats->old_tclient));
15678c2ecf20Sopenharmony_ci		memset(&fp_stats->old_uclient, 0,
15688c2ecf20Sopenharmony_ci		       sizeof(fp_stats->old_uclient));
15698c2ecf20Sopenharmony_ci		memset(&fp_stats->old_xclient, 0,
15708c2ecf20Sopenharmony_ci		       sizeof(fp_stats->old_xclient));
15718c2ecf20Sopenharmony_ci		if (bp->stats_init) {
15728c2ecf20Sopenharmony_ci			memset(&fp_stats->eth_q_stats, 0,
15738c2ecf20Sopenharmony_ci			       sizeof(fp_stats->eth_q_stats));
15748c2ecf20Sopenharmony_ci			memset(&fp_stats->eth_q_stats_old, 0,
15758c2ecf20Sopenharmony_ci			       sizeof(fp_stats->eth_q_stats_old));
15768c2ecf20Sopenharmony_ci		}
15778c2ecf20Sopenharmony_ci	}
15788c2ecf20Sopenharmony_ci
15798c2ecf20Sopenharmony_ci	memset(&bp->dev->stats, 0, sizeof(bp->dev->stats));
15808c2ecf20Sopenharmony_ci
15818c2ecf20Sopenharmony_ci	if (bp->stats_init) {
15828c2ecf20Sopenharmony_ci		memset(&bp->net_stats_old, 0, sizeof(bp->net_stats_old));
15838c2ecf20Sopenharmony_ci		memset(&bp->fw_stats_old, 0, sizeof(bp->fw_stats_old));
15848c2ecf20Sopenharmony_ci		memset(&bp->eth_stats_old, 0, sizeof(bp->eth_stats_old));
15858c2ecf20Sopenharmony_ci		memset(&bp->eth_stats, 0, sizeof(bp->eth_stats));
15868c2ecf20Sopenharmony_ci		memset(&bp->func_stats, 0, sizeof(bp->func_stats));
15878c2ecf20Sopenharmony_ci	}
15888c2ecf20Sopenharmony_ci
15898c2ecf20Sopenharmony_ci	bp->stats_state = STATS_STATE_DISABLED;
15908c2ecf20Sopenharmony_ci
15918c2ecf20Sopenharmony_ci	if (bp->port.pmf && bp->port.port_stx)
15928c2ecf20Sopenharmony_ci		bnx2x_port_stats_base_init(bp);
15938c2ecf20Sopenharmony_ci
15948c2ecf20Sopenharmony_ci	/* mark the end of statistics initialization */
15958c2ecf20Sopenharmony_ci	bp->stats_init = false;
15968c2ecf20Sopenharmony_ci}
15978c2ecf20Sopenharmony_ci
15988c2ecf20Sopenharmony_civoid bnx2x_stats_init(struct bnx2x *bp)
15998c2ecf20Sopenharmony_ci{
16008c2ecf20Sopenharmony_ci	int /*abs*/port = BP_PORT(bp);
16018c2ecf20Sopenharmony_ci	int mb_idx = BP_FW_MB_IDX(bp);
16028c2ecf20Sopenharmony_ci
16038c2ecf20Sopenharmony_ci	if (IS_VF(bp)) {
16048c2ecf20Sopenharmony_ci		bnx2x_memset_stats(bp);
16058c2ecf20Sopenharmony_ci		return;
16068c2ecf20Sopenharmony_ci	}
16078c2ecf20Sopenharmony_ci
16088c2ecf20Sopenharmony_ci	bp->stats_pending = 0;
16098c2ecf20Sopenharmony_ci	bp->executer_idx = 0;
16108c2ecf20Sopenharmony_ci	bp->stats_counter = 0;
16118c2ecf20Sopenharmony_ci
16128c2ecf20Sopenharmony_ci	/* port and func stats for management */
16138c2ecf20Sopenharmony_ci	if (!BP_NOMCP(bp)) {
16148c2ecf20Sopenharmony_ci		bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx);
16158c2ecf20Sopenharmony_ci		bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param);
16168c2ecf20Sopenharmony_ci
16178c2ecf20Sopenharmony_ci	} else {
16188c2ecf20Sopenharmony_ci		bp->port.port_stx = 0;
16198c2ecf20Sopenharmony_ci		bp->func_stx = 0;
16208c2ecf20Sopenharmony_ci	}
16218c2ecf20Sopenharmony_ci	DP(BNX2X_MSG_STATS, "port_stx 0x%x  func_stx 0x%x\n",
16228c2ecf20Sopenharmony_ci	   bp->port.port_stx, bp->func_stx);
16238c2ecf20Sopenharmony_ci
16248c2ecf20Sopenharmony_ci	/* pmf should retrieve port statistics from SP on a non-init*/
16258c2ecf20Sopenharmony_ci	if (!bp->stats_init && bp->port.pmf && bp->port.port_stx)
16268c2ecf20Sopenharmony_ci		bnx2x_stats_handle(bp, STATS_EVENT_PMF);
16278c2ecf20Sopenharmony_ci
16288c2ecf20Sopenharmony_ci	port = BP_PORT(bp);
16298c2ecf20Sopenharmony_ci	/* port stats */
16308c2ecf20Sopenharmony_ci	memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats));
16318c2ecf20Sopenharmony_ci	bp->port.old_nig_stats.brb_discard =
16328c2ecf20Sopenharmony_ci			REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
16338c2ecf20Sopenharmony_ci	bp->port.old_nig_stats.brb_truncate =
16348c2ecf20Sopenharmony_ci			REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38);
16358c2ecf20Sopenharmony_ci	if (!CHIP_IS_E3(bp)) {
16368c2ecf20Sopenharmony_ci		REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
16378c2ecf20Sopenharmony_ci			    &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2);
16388c2ecf20Sopenharmony_ci		REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
16398c2ecf20Sopenharmony_ci			    &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2);
16408c2ecf20Sopenharmony_ci	}
16418c2ecf20Sopenharmony_ci
16428c2ecf20Sopenharmony_ci	/* Prepare statistics ramrod data */
16438c2ecf20Sopenharmony_ci	bnx2x_prep_fw_stats_req(bp);
16448c2ecf20Sopenharmony_ci
16458c2ecf20Sopenharmony_ci	/* Clean SP from previous statistics */
16468c2ecf20Sopenharmony_ci	if (bp->stats_init) {
16478c2ecf20Sopenharmony_ci		if (bp->func_stx) {
16488c2ecf20Sopenharmony_ci			memset(bnx2x_sp(bp, func_stats), 0,
16498c2ecf20Sopenharmony_ci			       sizeof(struct host_func_stats));
16508c2ecf20Sopenharmony_ci			bnx2x_func_stats_init(bp);
16518c2ecf20Sopenharmony_ci			bnx2x_hw_stats_post(bp);
16528c2ecf20Sopenharmony_ci			bnx2x_stats_comp(bp);
16538c2ecf20Sopenharmony_ci		}
16548c2ecf20Sopenharmony_ci	}
16558c2ecf20Sopenharmony_ci
16568c2ecf20Sopenharmony_ci	bnx2x_memset_stats(bp);
16578c2ecf20Sopenharmony_ci}
16588c2ecf20Sopenharmony_ci
16598c2ecf20Sopenharmony_civoid bnx2x_save_statistics(struct bnx2x *bp)
16608c2ecf20Sopenharmony_ci{
16618c2ecf20Sopenharmony_ci	int i;
16628c2ecf20Sopenharmony_ci	struct net_device_stats *nstats = &bp->dev->stats;
16638c2ecf20Sopenharmony_ci
16648c2ecf20Sopenharmony_ci	/* save queue statistics */
16658c2ecf20Sopenharmony_ci	for_each_eth_queue(bp, i) {
16668c2ecf20Sopenharmony_ci		struct bnx2x_fastpath *fp = &bp->fp[i];
16678c2ecf20Sopenharmony_ci		struct bnx2x_eth_q_stats *qstats =
16688c2ecf20Sopenharmony_ci			&bnx2x_fp_stats(bp, fp)->eth_q_stats;
16698c2ecf20Sopenharmony_ci		struct bnx2x_eth_q_stats_old *qstats_old =
16708c2ecf20Sopenharmony_ci			&bnx2x_fp_stats(bp, fp)->eth_q_stats_old;
16718c2ecf20Sopenharmony_ci
16728c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_unicast_bytes_received_hi);
16738c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_unicast_bytes_received_lo);
16748c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_broadcast_bytes_received_hi);
16758c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_broadcast_bytes_received_lo);
16768c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_multicast_bytes_received_hi);
16778c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_multicast_bytes_received_lo);
16788c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_unicast_bytes_transmitted_hi);
16798c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_unicast_bytes_transmitted_lo);
16808c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_broadcast_bytes_transmitted_hi);
16818c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_broadcast_bytes_transmitted_lo);
16828c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_multicast_bytes_transmitted_hi);
16838c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_multicast_bytes_transmitted_lo);
16848c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_tpa_bytes_hi);
16858c2ecf20Sopenharmony_ci		UPDATE_QSTAT_OLD(total_tpa_bytes_lo);
16868c2ecf20Sopenharmony_ci	}
16878c2ecf20Sopenharmony_ci
16888c2ecf20Sopenharmony_ci	/* save net_device_stats statistics */
16898c2ecf20Sopenharmony_ci	bp->net_stats_old.rx_dropped = nstats->rx_dropped;
16908c2ecf20Sopenharmony_ci
16918c2ecf20Sopenharmony_ci	/* store port firmware statistics */
16928c2ecf20Sopenharmony_ci	if (bp->port.pmf && IS_MF(bp)) {
16938c2ecf20Sopenharmony_ci		struct bnx2x_eth_stats *estats = &bp->eth_stats;
16948c2ecf20Sopenharmony_ci		struct bnx2x_fw_port_stats_old *fwstats = &bp->fw_stats_old;
16958c2ecf20Sopenharmony_ci		UPDATE_FW_STAT_OLD(mac_filter_discard);
16968c2ecf20Sopenharmony_ci		UPDATE_FW_STAT_OLD(mf_tag_discard);
16978c2ecf20Sopenharmony_ci		UPDATE_FW_STAT_OLD(brb_truncate_discard);
16988c2ecf20Sopenharmony_ci		UPDATE_FW_STAT_OLD(mac_discard);
16998c2ecf20Sopenharmony_ci	}
17008c2ecf20Sopenharmony_ci}
17018c2ecf20Sopenharmony_ci
17028c2ecf20Sopenharmony_civoid bnx2x_afex_collect_stats(struct bnx2x *bp, void *void_afex_stats,
17038c2ecf20Sopenharmony_ci			      u32 stats_type)
17048c2ecf20Sopenharmony_ci{
17058c2ecf20Sopenharmony_ci	int i;
17068c2ecf20Sopenharmony_ci	struct afex_stats *afex_stats = (struct afex_stats *)void_afex_stats;
17078c2ecf20Sopenharmony_ci	struct bnx2x_eth_stats *estats = &bp->eth_stats;
17088c2ecf20Sopenharmony_ci	struct per_queue_stats *fcoe_q_stats =
17098c2ecf20Sopenharmony_ci		&bp->fw_stats_data->queue_stats[FCOE_IDX(bp)];
17108c2ecf20Sopenharmony_ci
17118c2ecf20Sopenharmony_ci	struct tstorm_per_queue_stats *fcoe_q_tstorm_stats =
17128c2ecf20Sopenharmony_ci		&fcoe_q_stats->tstorm_queue_statistics;
17138c2ecf20Sopenharmony_ci
17148c2ecf20Sopenharmony_ci	struct ustorm_per_queue_stats *fcoe_q_ustorm_stats =
17158c2ecf20Sopenharmony_ci		&fcoe_q_stats->ustorm_queue_statistics;
17168c2ecf20Sopenharmony_ci
17178c2ecf20Sopenharmony_ci	struct xstorm_per_queue_stats *fcoe_q_xstorm_stats =
17188c2ecf20Sopenharmony_ci		&fcoe_q_stats->xstorm_queue_statistics;
17198c2ecf20Sopenharmony_ci
17208c2ecf20Sopenharmony_ci	struct fcoe_statistics_params *fw_fcoe_stat =
17218c2ecf20Sopenharmony_ci		&bp->fw_stats_data->fcoe;
17228c2ecf20Sopenharmony_ci
17238c2ecf20Sopenharmony_ci	memset(afex_stats, 0, sizeof(struct afex_stats));
17248c2ecf20Sopenharmony_ci
17258c2ecf20Sopenharmony_ci	for_each_eth_queue(bp, i) {
17268c2ecf20Sopenharmony_ci		struct bnx2x_eth_q_stats *qstats = &bp->fp_stats[i].eth_q_stats;
17278c2ecf20Sopenharmony_ci
17288c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_unicast_bytes_hi,
17298c2ecf20Sopenharmony_ci		       qstats->total_unicast_bytes_received_hi,
17308c2ecf20Sopenharmony_ci		       afex_stats->rx_unicast_bytes_lo,
17318c2ecf20Sopenharmony_ci		       qstats->total_unicast_bytes_received_lo);
17328c2ecf20Sopenharmony_ci
17338c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_broadcast_bytes_hi,
17348c2ecf20Sopenharmony_ci		       qstats->total_broadcast_bytes_received_hi,
17358c2ecf20Sopenharmony_ci		       afex_stats->rx_broadcast_bytes_lo,
17368c2ecf20Sopenharmony_ci		       qstats->total_broadcast_bytes_received_lo);
17378c2ecf20Sopenharmony_ci
17388c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_multicast_bytes_hi,
17398c2ecf20Sopenharmony_ci		       qstats->total_multicast_bytes_received_hi,
17408c2ecf20Sopenharmony_ci		       afex_stats->rx_multicast_bytes_lo,
17418c2ecf20Sopenharmony_ci		       qstats->total_multicast_bytes_received_lo);
17428c2ecf20Sopenharmony_ci
17438c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_unicast_frames_hi,
17448c2ecf20Sopenharmony_ci		       qstats->total_unicast_packets_received_hi,
17458c2ecf20Sopenharmony_ci		       afex_stats->rx_unicast_frames_lo,
17468c2ecf20Sopenharmony_ci		       qstats->total_unicast_packets_received_lo);
17478c2ecf20Sopenharmony_ci
17488c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_broadcast_frames_hi,
17498c2ecf20Sopenharmony_ci		       qstats->total_broadcast_packets_received_hi,
17508c2ecf20Sopenharmony_ci		       afex_stats->rx_broadcast_frames_lo,
17518c2ecf20Sopenharmony_ci		       qstats->total_broadcast_packets_received_lo);
17528c2ecf20Sopenharmony_ci
17538c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_multicast_frames_hi,
17548c2ecf20Sopenharmony_ci		       qstats->total_multicast_packets_received_hi,
17558c2ecf20Sopenharmony_ci		       afex_stats->rx_multicast_frames_lo,
17568c2ecf20Sopenharmony_ci		       qstats->total_multicast_packets_received_lo);
17578c2ecf20Sopenharmony_ci
17588c2ecf20Sopenharmony_ci		/* sum to rx_frames_discarded all discraded
17598c2ecf20Sopenharmony_ci		 * packets due to size, ttl0 and checksum
17608c2ecf20Sopenharmony_ci		 */
17618c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_frames_discarded_hi,
17628c2ecf20Sopenharmony_ci		       qstats->total_packets_received_checksum_discarded_hi,
17638c2ecf20Sopenharmony_ci		       afex_stats->rx_frames_discarded_lo,
17648c2ecf20Sopenharmony_ci		       qstats->total_packets_received_checksum_discarded_lo);
17658c2ecf20Sopenharmony_ci
17668c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_frames_discarded_hi,
17678c2ecf20Sopenharmony_ci		       qstats->total_packets_received_ttl0_discarded_hi,
17688c2ecf20Sopenharmony_ci		       afex_stats->rx_frames_discarded_lo,
17698c2ecf20Sopenharmony_ci		       qstats->total_packets_received_ttl0_discarded_lo);
17708c2ecf20Sopenharmony_ci
17718c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_frames_discarded_hi,
17728c2ecf20Sopenharmony_ci		       qstats->etherstatsoverrsizepkts_hi,
17738c2ecf20Sopenharmony_ci		       afex_stats->rx_frames_discarded_lo,
17748c2ecf20Sopenharmony_ci		       qstats->etherstatsoverrsizepkts_lo);
17758c2ecf20Sopenharmony_ci
17768c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_frames_dropped_hi,
17778c2ecf20Sopenharmony_ci		       qstats->no_buff_discard_hi,
17788c2ecf20Sopenharmony_ci		       afex_stats->rx_frames_dropped_lo,
17798c2ecf20Sopenharmony_ci		       qstats->no_buff_discard_lo);
17808c2ecf20Sopenharmony_ci
17818c2ecf20Sopenharmony_ci		ADD_64(afex_stats->tx_unicast_bytes_hi,
17828c2ecf20Sopenharmony_ci		       qstats->total_unicast_bytes_transmitted_hi,
17838c2ecf20Sopenharmony_ci		       afex_stats->tx_unicast_bytes_lo,
17848c2ecf20Sopenharmony_ci		       qstats->total_unicast_bytes_transmitted_lo);
17858c2ecf20Sopenharmony_ci
17868c2ecf20Sopenharmony_ci		ADD_64(afex_stats->tx_broadcast_bytes_hi,
17878c2ecf20Sopenharmony_ci		       qstats->total_broadcast_bytes_transmitted_hi,
17888c2ecf20Sopenharmony_ci		       afex_stats->tx_broadcast_bytes_lo,
17898c2ecf20Sopenharmony_ci		       qstats->total_broadcast_bytes_transmitted_lo);
17908c2ecf20Sopenharmony_ci
17918c2ecf20Sopenharmony_ci		ADD_64(afex_stats->tx_multicast_bytes_hi,
17928c2ecf20Sopenharmony_ci		       qstats->total_multicast_bytes_transmitted_hi,
17938c2ecf20Sopenharmony_ci		       afex_stats->tx_multicast_bytes_lo,
17948c2ecf20Sopenharmony_ci		       qstats->total_multicast_bytes_transmitted_lo);
17958c2ecf20Sopenharmony_ci
17968c2ecf20Sopenharmony_ci		ADD_64(afex_stats->tx_unicast_frames_hi,
17978c2ecf20Sopenharmony_ci		       qstats->total_unicast_packets_transmitted_hi,
17988c2ecf20Sopenharmony_ci		       afex_stats->tx_unicast_frames_lo,
17998c2ecf20Sopenharmony_ci		       qstats->total_unicast_packets_transmitted_lo);
18008c2ecf20Sopenharmony_ci
18018c2ecf20Sopenharmony_ci		ADD_64(afex_stats->tx_broadcast_frames_hi,
18028c2ecf20Sopenharmony_ci		       qstats->total_broadcast_packets_transmitted_hi,
18038c2ecf20Sopenharmony_ci		       afex_stats->tx_broadcast_frames_lo,
18048c2ecf20Sopenharmony_ci		       qstats->total_broadcast_packets_transmitted_lo);
18058c2ecf20Sopenharmony_ci
18068c2ecf20Sopenharmony_ci		ADD_64(afex_stats->tx_multicast_frames_hi,
18078c2ecf20Sopenharmony_ci		       qstats->total_multicast_packets_transmitted_hi,
18088c2ecf20Sopenharmony_ci		       afex_stats->tx_multicast_frames_lo,
18098c2ecf20Sopenharmony_ci		       qstats->total_multicast_packets_transmitted_lo);
18108c2ecf20Sopenharmony_ci
18118c2ecf20Sopenharmony_ci		ADD_64(afex_stats->tx_frames_dropped_hi,
18128c2ecf20Sopenharmony_ci		       qstats->total_transmitted_dropped_packets_error_hi,
18138c2ecf20Sopenharmony_ci		       afex_stats->tx_frames_dropped_lo,
18148c2ecf20Sopenharmony_ci		       qstats->total_transmitted_dropped_packets_error_lo);
18158c2ecf20Sopenharmony_ci	}
18168c2ecf20Sopenharmony_ci
18178c2ecf20Sopenharmony_ci	/* now add FCoE statistics which are collected separately
18188c2ecf20Sopenharmony_ci	 * (both offloaded and non offloaded)
18198c2ecf20Sopenharmony_ci	 */
18208c2ecf20Sopenharmony_ci	if (!NO_FCOE(bp)) {
18218c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_unicast_bytes_hi,
18228c2ecf20Sopenharmony_ci			  LE32_0,
18238c2ecf20Sopenharmony_ci			  afex_stats->rx_unicast_bytes_lo,
18248c2ecf20Sopenharmony_ci			  fw_fcoe_stat->rx_stat0.fcoe_rx_byte_cnt);
18258c2ecf20Sopenharmony_ci
18268c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_unicast_bytes_hi,
18278c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->rcv_ucast_bytes.hi,
18288c2ecf20Sopenharmony_ci			  afex_stats->rx_unicast_bytes_lo,
18298c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->rcv_ucast_bytes.lo);
18308c2ecf20Sopenharmony_ci
18318c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_broadcast_bytes_hi,
18328c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->rcv_bcast_bytes.hi,
18338c2ecf20Sopenharmony_ci			  afex_stats->rx_broadcast_bytes_lo,
18348c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->rcv_bcast_bytes.lo);
18358c2ecf20Sopenharmony_ci
18368c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_multicast_bytes_hi,
18378c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->rcv_mcast_bytes.hi,
18388c2ecf20Sopenharmony_ci			  afex_stats->rx_multicast_bytes_lo,
18398c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->rcv_mcast_bytes.lo);
18408c2ecf20Sopenharmony_ci
18418c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_unicast_frames_hi,
18428c2ecf20Sopenharmony_ci			  LE32_0,
18438c2ecf20Sopenharmony_ci			  afex_stats->rx_unicast_frames_lo,
18448c2ecf20Sopenharmony_ci			  fw_fcoe_stat->rx_stat0.fcoe_rx_pkt_cnt);
18458c2ecf20Sopenharmony_ci
18468c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_unicast_frames_hi,
18478c2ecf20Sopenharmony_ci			  LE32_0,
18488c2ecf20Sopenharmony_ci			  afex_stats->rx_unicast_frames_lo,
18498c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->rcv_ucast_pkts);
18508c2ecf20Sopenharmony_ci
18518c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_broadcast_frames_hi,
18528c2ecf20Sopenharmony_ci			  LE32_0,
18538c2ecf20Sopenharmony_ci			  afex_stats->rx_broadcast_frames_lo,
18548c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->rcv_bcast_pkts);
18558c2ecf20Sopenharmony_ci
18568c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_multicast_frames_hi,
18578c2ecf20Sopenharmony_ci			  LE32_0,
18588c2ecf20Sopenharmony_ci			  afex_stats->rx_multicast_frames_lo,
18598c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->rcv_ucast_pkts);
18608c2ecf20Sopenharmony_ci
18618c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_frames_discarded_hi,
18628c2ecf20Sopenharmony_ci			  LE32_0,
18638c2ecf20Sopenharmony_ci			  afex_stats->rx_frames_discarded_lo,
18648c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->checksum_discard);
18658c2ecf20Sopenharmony_ci
18668c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_frames_discarded_hi,
18678c2ecf20Sopenharmony_ci			  LE32_0,
18688c2ecf20Sopenharmony_ci			  afex_stats->rx_frames_discarded_lo,
18698c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->pkts_too_big_discard);
18708c2ecf20Sopenharmony_ci
18718c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_frames_discarded_hi,
18728c2ecf20Sopenharmony_ci			  LE32_0,
18738c2ecf20Sopenharmony_ci			  afex_stats->rx_frames_discarded_lo,
18748c2ecf20Sopenharmony_ci			  fcoe_q_tstorm_stats->ttl0_discard);
18758c2ecf20Sopenharmony_ci
18768c2ecf20Sopenharmony_ci		ADD_64_LE16(afex_stats->rx_frames_dropped_hi,
18778c2ecf20Sopenharmony_ci			    LE16_0,
18788c2ecf20Sopenharmony_ci			    afex_stats->rx_frames_dropped_lo,
18798c2ecf20Sopenharmony_ci			    fcoe_q_tstorm_stats->no_buff_discard);
18808c2ecf20Sopenharmony_ci
18818c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_frames_dropped_hi,
18828c2ecf20Sopenharmony_ci			  LE32_0,
18838c2ecf20Sopenharmony_ci			  afex_stats->rx_frames_dropped_lo,
18848c2ecf20Sopenharmony_ci			  fcoe_q_ustorm_stats->ucast_no_buff_pkts);
18858c2ecf20Sopenharmony_ci
18868c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_frames_dropped_hi,
18878c2ecf20Sopenharmony_ci			  LE32_0,
18888c2ecf20Sopenharmony_ci			  afex_stats->rx_frames_dropped_lo,
18898c2ecf20Sopenharmony_ci			  fcoe_q_ustorm_stats->mcast_no_buff_pkts);
18908c2ecf20Sopenharmony_ci
18918c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_frames_dropped_hi,
18928c2ecf20Sopenharmony_ci			  LE32_0,
18938c2ecf20Sopenharmony_ci			  afex_stats->rx_frames_dropped_lo,
18948c2ecf20Sopenharmony_ci			  fcoe_q_ustorm_stats->bcast_no_buff_pkts);
18958c2ecf20Sopenharmony_ci
18968c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_frames_dropped_hi,
18978c2ecf20Sopenharmony_ci			  LE32_0,
18988c2ecf20Sopenharmony_ci			  afex_stats->rx_frames_dropped_lo,
18998c2ecf20Sopenharmony_ci			  fw_fcoe_stat->rx_stat1.fcoe_rx_drop_pkt_cnt);
19008c2ecf20Sopenharmony_ci
19018c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->rx_frames_dropped_hi,
19028c2ecf20Sopenharmony_ci			  LE32_0,
19038c2ecf20Sopenharmony_ci			  afex_stats->rx_frames_dropped_lo,
19048c2ecf20Sopenharmony_ci			  fw_fcoe_stat->rx_stat2.fcoe_rx_drop_pkt_cnt);
19058c2ecf20Sopenharmony_ci
19068c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->tx_unicast_bytes_hi,
19078c2ecf20Sopenharmony_ci			  LE32_0,
19088c2ecf20Sopenharmony_ci			  afex_stats->tx_unicast_bytes_lo,
19098c2ecf20Sopenharmony_ci			  fw_fcoe_stat->tx_stat.fcoe_tx_byte_cnt);
19108c2ecf20Sopenharmony_ci
19118c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->tx_unicast_bytes_hi,
19128c2ecf20Sopenharmony_ci			  fcoe_q_xstorm_stats->ucast_bytes_sent.hi,
19138c2ecf20Sopenharmony_ci			  afex_stats->tx_unicast_bytes_lo,
19148c2ecf20Sopenharmony_ci			  fcoe_q_xstorm_stats->ucast_bytes_sent.lo);
19158c2ecf20Sopenharmony_ci
19168c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->tx_broadcast_bytes_hi,
19178c2ecf20Sopenharmony_ci			  fcoe_q_xstorm_stats->bcast_bytes_sent.hi,
19188c2ecf20Sopenharmony_ci			  afex_stats->tx_broadcast_bytes_lo,
19198c2ecf20Sopenharmony_ci			  fcoe_q_xstorm_stats->bcast_bytes_sent.lo);
19208c2ecf20Sopenharmony_ci
19218c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->tx_multicast_bytes_hi,
19228c2ecf20Sopenharmony_ci			  fcoe_q_xstorm_stats->mcast_bytes_sent.hi,
19238c2ecf20Sopenharmony_ci			  afex_stats->tx_multicast_bytes_lo,
19248c2ecf20Sopenharmony_ci			  fcoe_q_xstorm_stats->mcast_bytes_sent.lo);
19258c2ecf20Sopenharmony_ci
19268c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->tx_unicast_frames_hi,
19278c2ecf20Sopenharmony_ci			  LE32_0,
19288c2ecf20Sopenharmony_ci			  afex_stats->tx_unicast_frames_lo,
19298c2ecf20Sopenharmony_ci			  fw_fcoe_stat->tx_stat.fcoe_tx_pkt_cnt);
19308c2ecf20Sopenharmony_ci
19318c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->tx_unicast_frames_hi,
19328c2ecf20Sopenharmony_ci			  LE32_0,
19338c2ecf20Sopenharmony_ci			  afex_stats->tx_unicast_frames_lo,
19348c2ecf20Sopenharmony_ci			  fcoe_q_xstorm_stats->ucast_pkts_sent);
19358c2ecf20Sopenharmony_ci
19368c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->tx_broadcast_frames_hi,
19378c2ecf20Sopenharmony_ci			  LE32_0,
19388c2ecf20Sopenharmony_ci			  afex_stats->tx_broadcast_frames_lo,
19398c2ecf20Sopenharmony_ci			  fcoe_q_xstorm_stats->bcast_pkts_sent);
19408c2ecf20Sopenharmony_ci
19418c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->tx_multicast_frames_hi,
19428c2ecf20Sopenharmony_ci			  LE32_0,
19438c2ecf20Sopenharmony_ci			  afex_stats->tx_multicast_frames_lo,
19448c2ecf20Sopenharmony_ci			  fcoe_q_xstorm_stats->mcast_pkts_sent);
19458c2ecf20Sopenharmony_ci
19468c2ecf20Sopenharmony_ci		ADD_64_LE(afex_stats->tx_frames_dropped_hi,
19478c2ecf20Sopenharmony_ci			  LE32_0,
19488c2ecf20Sopenharmony_ci			  afex_stats->tx_frames_dropped_lo,
19498c2ecf20Sopenharmony_ci			  fcoe_q_xstorm_stats->error_drop_pkts);
19508c2ecf20Sopenharmony_ci	}
19518c2ecf20Sopenharmony_ci
19528c2ecf20Sopenharmony_ci	/* if port stats are requested, add them to the PMF
19538c2ecf20Sopenharmony_ci	 * stats, as anyway they will be accumulated by the
19548c2ecf20Sopenharmony_ci	 * MCP before sent to the switch
19558c2ecf20Sopenharmony_ci	 */
19568c2ecf20Sopenharmony_ci	if ((bp->port.pmf) && (stats_type == VICSTATST_UIF_INDEX)) {
19578c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_frames_dropped_hi,
19588c2ecf20Sopenharmony_ci		       0,
19598c2ecf20Sopenharmony_ci		       afex_stats->rx_frames_dropped_lo,
19608c2ecf20Sopenharmony_ci		       estats->mac_filter_discard);
19618c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_frames_dropped_hi,
19628c2ecf20Sopenharmony_ci		       0,
19638c2ecf20Sopenharmony_ci		       afex_stats->rx_frames_dropped_lo,
19648c2ecf20Sopenharmony_ci		       estats->brb_truncate_discard);
19658c2ecf20Sopenharmony_ci		ADD_64(afex_stats->rx_frames_discarded_hi,
19668c2ecf20Sopenharmony_ci		       0,
19678c2ecf20Sopenharmony_ci		       afex_stats->rx_frames_discarded_lo,
19688c2ecf20Sopenharmony_ci		       estats->mac_discard);
19698c2ecf20Sopenharmony_ci	}
19708c2ecf20Sopenharmony_ci}
19718c2ecf20Sopenharmony_ci
19728c2ecf20Sopenharmony_ciint bnx2x_stats_safe_exec(struct bnx2x *bp,
19738c2ecf20Sopenharmony_ci			  void (func_to_exec)(void *cookie),
19748c2ecf20Sopenharmony_ci			  void *cookie)
19758c2ecf20Sopenharmony_ci{
19768c2ecf20Sopenharmony_ci	int cnt = 10, rc = 0;
19778c2ecf20Sopenharmony_ci
19788c2ecf20Sopenharmony_ci	/* Wait for statistics to end [while blocking further requests],
19798c2ecf20Sopenharmony_ci	 * then run supplied function 'safely'.
19808c2ecf20Sopenharmony_ci	 */
19818c2ecf20Sopenharmony_ci	rc = down_timeout(&bp->stats_lock, HZ / 10);
19828c2ecf20Sopenharmony_ci	if (unlikely(rc)) {
19838c2ecf20Sopenharmony_ci		BNX2X_ERR("Failed to take statistics lock for safe execution\n");
19848c2ecf20Sopenharmony_ci		goto out_no_lock;
19858c2ecf20Sopenharmony_ci	}
19868c2ecf20Sopenharmony_ci
19878c2ecf20Sopenharmony_ci	bnx2x_stats_comp(bp);
19888c2ecf20Sopenharmony_ci	while (bp->stats_pending && cnt--)
19898c2ecf20Sopenharmony_ci		if (bnx2x_storm_stats_update(bp))
19908c2ecf20Sopenharmony_ci			usleep_range(1000, 2000);
19918c2ecf20Sopenharmony_ci	if (bp->stats_pending) {
19928c2ecf20Sopenharmony_ci		BNX2X_ERR("Failed to wait for stats pending to clear [possibly FW is stuck]\n");
19938c2ecf20Sopenharmony_ci		rc = -EBUSY;
19948c2ecf20Sopenharmony_ci		goto out;
19958c2ecf20Sopenharmony_ci	}
19968c2ecf20Sopenharmony_ci
19978c2ecf20Sopenharmony_ci	func_to_exec(cookie);
19988c2ecf20Sopenharmony_ci
19998c2ecf20Sopenharmony_ciout:
20008c2ecf20Sopenharmony_ci	/* No need to restart statistics - if they're enabled, the timer
20018c2ecf20Sopenharmony_ci	 * will restart the statistics.
20028c2ecf20Sopenharmony_ci	 */
20038c2ecf20Sopenharmony_ci	up(&bp->stats_lock);
20048c2ecf20Sopenharmony_ciout_no_lock:
20058c2ecf20Sopenharmony_ci	return rc;
20068c2ecf20Sopenharmony_ci}
2007