[qca-nss-drv] Break up statistics implementation
Break up the centralized statistics implementation to be subsystem based
statistics implementation.
Change-Id: Ibc14d88f391e816d3d6284a57ea6676f2842ac70
Signed-off-by: Yu Huang <yuhuang@codeaurora.org>
diff --git a/Makefile b/Makefile
index 33b5dbd..5d7afdf 100644
--- a/Makefile
+++ b/Makefile
@@ -10,59 +10,85 @@
qca-nss-drv-objs := \
nss_bridge.o \
nss_capwap.o \
+ nss_capwap_stats.o \
nss_cmn.o \
nss_core.o \
nss_coredump.o \
nss_dtls.o \
+ nss_dtls_stats.o \
nss_dynamic_interface.o \
nss_edma.o \
+ nss_edma_stats.o \
nss_eth_rx.o \
+ nss_eth_rx_stats.o \
nss_gre.o \
+ nss_gre_stats.o \
nss_gre_redir.o \
+ nss_gre_redir_stats.o \
nss_gre_tunnel.o \
+ nss_gre_tunnel_stats.o \
nss_if.o \
nss_init.o \
nss_ipsec.o \
nss_ipv4.o \
+ nss_ipv4_stats.o \
nss_ipv4_log.o \
nss_ipv4_reasm.o \
+ nss_ipv4_reasm_stats.o \
nss_ipv6.o \
+ nss_ipv6_stats.o \
nss_ipv6_log.o \
nss_ipv6_reasm.o \
+ nss_ipv6_reasm_stats.o \
nss_l2tpv2.o \
+ nss_l2tpv2_stats.o \
nss_lag.o \
nss_log.o \
nss_lso_rx.o \
+ nss_lso_rx_stats.o \
nss_map_t.o \
+ nss_map_t_stats.o \
nss_n2h.o \
+ nss_n2h_stats.o \
nss_oam.o \
nss_phys_if.o \
nss_pm.o \
nss_profiler.o \
nss_project.o \
nss_portid.o \
+ nss_portid_stats.o \
nss_ppe.o \
+ nss_ppe_stats.o \
nss_pppoe.o \
+ nss_pppoe_stats.o \
nss_pptp.o \
+ nss_pptp_stats.o \
nss_shaper.o \
nss_sjack.o \
+ nss_sjack_stats.o \
nss_stats.o \
nss_tstamp.o \
nss_tun6rd.o \
nss_trustsec_tx.o \
+ nss_trustsec_tx_stats.o \
nss_tunipip6.o \
nss_virt_if.o \
+ nss_virt_if_stats.o \
nss_vlan.o \
nss_tstamp.o \
nss_wifi.o \
+ nss_wifi_stats.o \
nss_wifi_vdev.o \
nss_wifi_if.o \
- nss_wifili.o
+ nss_wifi_if_stats.o \
+ nss_wifili.o \
+ nss_wifili_stats.o
#
# TODO: Deprecated files should be removed before merge
#
-qca-nss-drv-objs += nss_tx_rx_virt_if.o
+qca-nss-drv-objs += nss_tx_rx_virt_if.o \
+ nss_tx_rx_virt_if_stats.o
# Base NSS data plane/HAL support
qca-nss-drv-objs += nss_data_plane/nss_data_plane.o
diff --git a/Makefile.fsm b/Makefile.fsm
index 241fa7d..61f4f1e 100644
--- a/Makefile.fsm
+++ b/Makefile.fsm
@@ -9,57 +9,82 @@
qca-nss-drv-objs := \
nss_bridge.o \
nss_capwap.o \
+ nss_capwap_stats.o \
nss_cmn.o \
nss_core.o \
nss_coredump.o \
nss_crypto.o \
nss_dtls.o \
+ nss_dtls_stats.o \
nss_dynamic_interface.o \
nss_edma.o \
+ nss_edma_stats.o \
nss_eth_rx.o \
+ nss_eth_rx_stats.o \
nss_gre.o \
+ nss_gre_stats.o \
nss_gre_redir.o \
+ nss_gre_redir_stats.o \
nss_gre_tunnel.o \
+ nss_gre_tunnel_stats.o \
nss_if.o \
nss_init.o \
nss_ipsec.o \
nss_ipv4.o \
+ nss_ipv4_stats.o \
nss_ipv4_log.o \
nss_ipv4_reasm.o \
+ nss_ipv4_reasm_stats.o \
nss_ipv6.o \
+ nss_ipv6_stats.o \
nss_ipv6_log.o \
nss_ipv6_reasm.o \
+ nss_ipv6_reasm_stats.o \
nss_l2tpv2.o \
+ nss_l2tpv2_stats.o \
nss_lag.o \
nss_log.o \
nss_lso_rx.o \
+ nss_lso_rx_stats.o \
nss_map_t.o \
+ nss_map_t_stats.o \
nss_n2h.o \
+ nss_n2h_stats.o \
nss_oam.o \
nss_phys_if.o \
nss_pm.o \
nss_profiler.o \
nss_portid.o \
+ nss_portid_stats.o \
nss_ppe.o \
+ nss_ppe_stats.o \
nss_pppoe.o \
+ nss_pppoe_stats.o \
nss_pptp.o \
+ nss_pptp_stats.o \
nss_shaper.o \
nss_sjack.o \
+ nss_sjack_stats.o \
nss_stats.o \
nss_tstamp.o \
nss_tun6rd.o \
nss_trustsec_tx.o \
+ nss_trustsec_tx_stats.o \
nss_tunipip6.o \
nss_virt_if.o \
+ nss_virt_if_stats.o \
nss_vlan.o \
nss_wifi.o \
+ nss_wifi_stats.o \
nss_wifi_if.o \
+ nss_wifi_if_stats.o \
nss_wifi_vdev.o
#
# TODO: Deprecated files should be removed before merge
#
-qca-nss-drv-objs += nss_tx_rx_virt_if.o
+qca-nss-drv-objs += nss_tx_rx_virt_if.o \
+ nss_tx_rx_virt_if_stats.o
qca-nss-drv-objs += nss_hal/nss_hal.o
qca-nss-drv-objs += nss_hal/fsm9010/nss_hal_pvt.o
diff --git a/exports/nss_gre.h b/exports/nss_gre.h
index d2a2d19..93fbf81 100644
--- a/exports/nss_gre.h
+++ b/exports/nss_gre.h
@@ -297,32 +297,6 @@
typedef void (*nss_gre_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi);
/**
- * nss_gre_base_debug_stats_get
- * Gets NSS GRE base debug statistics.
- *
- * @param[in] stats_mem Pointer to memory to which stats should be copied.
- * @param[in] size Stats memory size.
- * @param[out] stats_mem Pointer to the memory address, which must be large
- * enough to hold all the statistics.
- * @return
- * None.
- */
-extern void nss_gre_base_debug_stats_get(void *stats_mem, int size);
-
-/**
- * nss_gre_session_debug_stats_get
- * Gets NSS GRE session debug statistics.
- *
- * @param[in] stats_mem Pointer to memory to which stats should be copied.
- * @param[in] size Stats memory size.
- * @param[out] stats_mem Pointer to the memory address, which must be large
- * enough to hold all the statistics.
- * @return
- * None.
- */
-extern void nss_gre_session_debug_stats_get(void *stats_mem, int size);
-
-/**
* nss_gre_register_if
* Registers the GRE interface with the NSS for sending and
* receiving messages.
diff --git a/exports/nss_ipv4.h b/exports/nss_ipv4.h
index 10880fa..d79e3de 100644
--- a/exports/nss_ipv4.h
+++ b/exports/nss_ipv4.h
@@ -560,89 +560,89 @@
};
/**
- * exception_events_ipv4
+ * nss_ipv4_exception_events
* Exception events from the bridge or route handler.
*/
-enum exception_events_ipv4 {
- NSS_EXCEPTION_EVENT_IPV4_ICMP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_ICMP_UNHANDLED_TYPE,
- NSS_EXCEPTION_EVENT_IPV4_ICMP_IPV4_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_ICMP_IPV4_UDP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_ICMP_IPV4_TCP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_ICMP_IPV4_UNKNOWN_PROTOCOL,
- NSS_EXCEPTION_EVENT_IPV4_ICMP_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV4_ICMP_FLUSH_TO_HOST,
- NSS_EXCEPTION_EVENT_IPV4_TCP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_TCP_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV4_TCP_IP_OPTION,
- NSS_EXCEPTION_EVENT_IPV4_TCP_IP_FRAGMENT,
- NSS_EXCEPTION_EVENT_IPV4_TCP_SMALL_TTL,
- NSS_EXCEPTION_EVENT_IPV4_TCP_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV4_TCP_FLAGS,
- NSS_EXCEPTION_EVENT_IPV4_TCP_SEQ_EXCEEDS_RIGHT_EDGE,
- NSS_EXCEPTION_EVENT_IPV4_TCP_SMALL_DATA_OFFS,
- NSS_EXCEPTION_EVENT_IPV4_TCP_BAD_SACK,
- NSS_EXCEPTION_EVENT_IPV4_TCP_BIG_DATA_OFFS,
- NSS_EXCEPTION_EVENT_IPV4_TCP_SEQ_BEFORE_LEFT_EDGE,
- NSS_EXCEPTION_EVENT_IPV4_TCP_ACK_EXCEEDS_RIGHT_EDGE,
- NSS_EXCEPTION_EVENT_IPV4_TCP_ACK_BEFORE_LEFT_EDGE,
- NSS_EXCEPTION_EVENT_IPV4_UDP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_UDP_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV4_UDP_IP_OPTION,
- NSS_EXCEPTION_EVENT_IPV4_UDP_IP_FRAGMENT,
- NSS_EXCEPTION_EVENT_IPV4_UDP_SMALL_TTL,
- NSS_EXCEPTION_EVENT_IPV4_UDP_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV4_WRONG_TARGET_MAC,
- NSS_EXCEPTION_EVENT_IPV4_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_BAD_TOTAL_LENGTH,
- NSS_EXCEPTION_EVENT_IPV4_BAD_CHECKSUM,
- NSS_EXCEPTION_EVENT_IPV4_NON_INITIAL_FRAGMENT,
- NSS_EXCEPTION_EVENT_IPV4_DATAGRAM_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_OPTIONS_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_UNKNOWN_PROTOCOL,
- NSS_EXCEPTION_EVENT_IPV4_ESP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_ESP_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV4_ESP_IP_OPTION,
- NSS_EXCEPTION_EVENT_IPV4_ESP_IP_FRAGMENT,
- NSS_EXCEPTION_EVENT_IPV4_ESP_SMALL_TTL,
- NSS_EXCEPTION_EVENT_IPV4_ESP_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV4_IVID_MISMATCH,
- NSS_EXCEPTION_EVENT_IPV4_IVID_MISSING,
- NSS_EXCEPTION_EVENT_IPV4_6RD_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV4_6RD_IP_OPTION,
- NSS_EXCEPTION_EVENT_IPV4_6RD_IP_FRAGMENT,
- NSS_EXCEPTION_EVENT_IPV4_6RD_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV4_DSCP_MARKING_MISMATCH,
- NSS_EXCEPTION_EVENT_IPV4_VLAN_MARKING_MISMATCH,
- NSS_EXCEPTION_EVENT_IPV4_DEPRECATED,
- NSS_EXCEPTION_EVENT_GRE_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_GRE_NO_ICME,
- NSS_EXCEPTION_EVENT_GRE_IP_OPTION,
- NSS_EXCEPTION_EVENT_GRE_IP_FRAGMENT,
- NSS_EXCEPTION_EVENT_GRE_SMALL_TTL,
- NSS_EXCEPTION_EVENT_GRE_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV4_PPTP_GRE_SESSION_MATCH_FAIL,
- NSS_EXCEPTION_EVENT_IPV4_PPTP_GRE_INVALID_PROTO,
- NSS_EXCEPTION_EVENT_IPV4_PPTP_GRE_NO_CME,
- NSS_EXCEPTION_EVENT_IPV4_PPTP_GRE_IP_OPTION,
- NSS_EXCEPTION_EVENT_IPV4_PPTP_GRE_IP_FRAGMENT,
- NSS_EXCEPTION_EVENT_IPV4_PPTP_GRE_SMALL_TTL,
- NSS_EXCEPTION_EVENT_IPV4_PPTP_GRE_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV4_DESTROY,
- NSS_EXCEPTION_EVENT_IPV4_FRAG_DF_SET,
- NSS_EXCEPTION_EVENT_IPV4_FRAG_FAIL,
- NSS_EXCEPTION_EVENT_IPV4_ICMP_IPV4_UDPLITE_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_UDPLITE_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV4_UDPLITE_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV4_UDPLITE_IP_OPTION,
- NSS_EXCEPTION_EVENT_IPV4_UDPLITE_IP_FRAGMENT,
- NSS_EXCEPTION_EVENT_IPV4_UDPLITE_SMALL_TTL,
- NSS_EXCEPTION_EVENT_IPV4_UDPLITE_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV4_MC_UDP_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV4_MC_MEM_ALLOC_FAILURE,
- NSS_EXCEPTION_EVENT_IPV4_MC_UPDATE_FAILURE,
- NSS_EXCEPTION_EVENT_IPV4_MC_PBUF_ALLOC_FAILURE,
- NSS_EXCEPTION_EVENT_IPV4_MAX
+enum nss_ipv4_exception_events {
+ NSS_IPV4_EXCEPTION_EVENT_ICMP_HEADER_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_ICMP_UNHANDLED_TYPE,
+ NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_HEADER_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_UDP_HEADER_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_TCP_HEADER_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_UNKNOWN_PROTOCOL,
+ NSS_IPV4_EXCEPTION_EVENT_ICMP_NO_ICME,
+ NSS_IPV4_EXCEPTION_EVENT_ICMP_FLUSH_TO_HOST,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_HEADER_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_NO_ICME,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_IP_OPTION,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_IP_FRAGMENT,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_SMALL_TTL,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_NEEDS_FRAGMENTATION,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_FLAGS,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_SEQ_EXCEEDS_RIGHT_EDGE,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_SMALL_DATA_OFFS,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_BAD_SACK,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_BIG_DATA_OFFS,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_SEQ_BEFORE_LEFT_EDGE,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_ACK_EXCEEDS_RIGHT_EDGE,
+ NSS_IPV4_EXCEPTION_EVENT_TCP_ACK_BEFORE_LEFT_EDGE,
+ NSS_IPV4_EXCEPTION_EVENT_UDP_HEADER_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_UDP_NO_ICME,
+ NSS_IPV4_EXCEPTION_EVENT_UDP_IP_OPTION,
+ NSS_IPV4_EXCEPTION_EVENT_UDP_IP_FRAGMENT,
+ NSS_IPV4_EXCEPTION_EVENT_UDP_SMALL_TTL,
+ NSS_IPV4_EXCEPTION_EVENT_UDP_NEEDS_FRAGMENTATION,
+ NSS_IPV4_EXCEPTION_EVENT_WRONG_TARGET_MAC,
+ NSS_IPV4_EXCEPTION_EVENT_HEADER_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_BAD_TOTAL_LENGTH,
+ NSS_IPV4_EXCEPTION_EVENT_BAD_CHECKSUM,
+ NSS_IPV4_EXCEPTION_EVENT_NON_INITIAL_FRAGMENT,
+ NSS_IPV4_EXCEPTION_EVENT_DATAGRAM_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_OPTIONS_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_UNKNOWN_PROTOCOL,
+ NSS_IPV4_EXCEPTION_EVENT_ESP_HEADER_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_ESP_NO_ICME,
+ NSS_IPV4_EXCEPTION_EVENT_ESP_IP_OPTION,
+ NSS_IPV4_EXCEPTION_EVENT_ESP_IP_FRAGMENT,
+ NSS_IPV4_EXCEPTION_EVENT_ESP_SMALL_TTL,
+ NSS_IPV4_EXCEPTION_EVENT_ESP_NEEDS_FRAGMENTATION,
+ NSS_IPV4_EXCEPTION_EVENT_IVID_MISMATCH,
+ NSS_IPV4_EXCEPTION_EVENT_IVID_MISSING,
+ NSS_IPV4_EXCEPTION_EVENT_6RD_NO_ICME,
+ NSS_IPV4_EXCEPTION_EVENT_6RD_IP_OPTION,
+ NSS_IPV4_EXCEPTION_EVENT_6RD_IP_FRAGMENT,
+ NSS_IPV4_EXCEPTION_EVENT_6RD_NEEDS_FRAGMENTATION,
+ NSS_IPV4_EXCEPTION_EVENT_DSCP_MARKING_MISMATCH,
+ NSS_IPV4_EXCEPTION_EVENT_VLAN_MARKING_MISMATCH,
+ NSS_IPV4_EXCEPTION_EVENT_DEPRECATED,
+ NSS_IPV4_EXCEPTION_EVENT_GRE_HEADER_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_GRE_NO_ICME,
+ NSS_IPV4_EXCEPTION_EVENT_GRE_IP_OPTION,
+ NSS_IPV4_EXCEPTION_EVENT_GRE_IP_FRAGMENT,
+ NSS_IPV4_EXCEPTION_EVENT_GRE_SMALL_TTL,
+ NSS_IPV4_EXCEPTION_EVENT_GRE_NEEDS_FRAGMENTATION,
+ NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_SESSION_MATCH_FAIL,
+ NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_INVALID_PROTO,
+ NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_NO_CME,
+ NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_IP_OPTION,
+ NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_IP_FRAGMENT,
+ NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_SMALL_TTL,
+ NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_NEEDS_FRAGMENTATION,
+ NSS_IPV4_EXCEPTION_EVENT_DESTROY,
+ NSS_IPV4_EXCEPTION_EVENT_FRAG_DF_SET,
+ NSS_IPV4_EXCEPTION_EVENT_FRAG_FAIL,
+ NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_UDPLITE_HEADER_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_UDPLITE_HEADER_INCOMPLETE,
+ NSS_IPV4_EXCEPTION_EVENT_UDPLITE_NO_ICME,
+ NSS_IPV4_EXCEPTION_EVENT_UDPLITE_IP_OPTION,
+ NSS_IPV4_EXCEPTION_EVENT_UDPLITE_IP_FRAGMENT,
+ NSS_IPV4_EXCEPTION_EVENT_UDPLITE_SMALL_TTL,
+ NSS_IPV4_EXCEPTION_EVENT_UDPLITE_NEEDS_FRAGMENTATION,
+ NSS_IPV4_EXCEPTION_EVENT_MC_UDP_NO_ICME,
+ NSS_IPV4_EXCEPTION_EVENT_MC_MEM_ALLOC_FAILURE,
+ NSS_IPV4_EXCEPTION_EVENT_MC_UPDATE_FAILURE,
+ NSS_IPV4_EXCEPTION_EVENT_MC_PBUF_ALLOC_FAILURE,
+ NSS_IPV4_EXCEPTION_EVENT_MAX
};
/**
@@ -696,7 +696,7 @@
uint32_t ipv4_mc_connection_flushes;
/**< Number of multicast connection flushes. */
- uint32_t exception_events[NSS_EXCEPTION_EVENT_IPV4_MAX];
+ uint32_t exception_events[NSS_IPV4_EXCEPTION_EVENT_MAX];
/**< Number of exception events. */
};
diff --git a/exports/nss_ipv6.h b/exports/nss_ipv6.h
index 70ae39a..dd35df1 100644
--- a/exports/nss_ipv6.h
+++ b/exports/nss_ipv6.h
@@ -149,61 +149,61 @@
/**< MAC address for the return interface is valid. */
/**
- * exception_events_ipv6
+ * nss_ipv6_exception_events
* Exception events from an IPv6 bridge or route handler.
*/
-enum exception_events_ipv6 {
- NSS_EXCEPTION_EVENT_IPV6_ICMP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV6_ICMP_UNHANDLED_TYPE,
- NSS_EXCEPTION_EVENT_IPV6_ICMP_IPV6_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV6_ICMP_IPV6_UDP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV6_ICMP_IPV6_TCP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV6_ICMP_IPV6_UNKNOWN_PROTOCOL,
- NSS_EXCEPTION_EVENT_IPV6_ICMP_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV6_ICMP_FLUSH_TO_HOST,
- NSS_EXCEPTION_EVENT_IPV6_TCP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV6_TCP_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV6_TCP_SMALL_HOP_LIMIT,
- NSS_EXCEPTION_EVENT_IPV6_TCP_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV6_TCP_FLAGS,
- NSS_EXCEPTION_EVENT_IPV6_TCP_SEQ_EXCEEDS_RIGHT_EDGE,
- NSS_EXCEPTION_EVENT_IPV6_TCP_SMALL_DATA_OFFS,
- NSS_EXCEPTION_EVENT_IPV6_TCP_BAD_SACK,
- NSS_EXCEPTION_EVENT_IPV6_TCP_BIG_DATA_OFFS,
- NSS_EXCEPTION_EVENT_IPV6_TCP_SEQ_BEFORE_LEFT_EDGE,
- NSS_EXCEPTION_EVENT_IPV6_TCP_ACK_EXCEEDS_RIGHT_EDGE,
- NSS_EXCEPTION_EVENT_IPV6_TCP_ACK_BEFORE_LEFT_EDGE,
- NSS_EXCEPTION_EVENT_IPV6_UDP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV6_UDP_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV6_UDP_SMALL_HOP_LIMIT,
- NSS_EXCEPTION_EVENT_IPV6_UDP_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV6_WRONG_TARGET_MAC,
- NSS_EXCEPTION_EVENT_IPV6_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV6_UNKNOWN_PROTOCOL,
- NSS_EXCEPTION_EVENT_IPV6_IVID_MISMATCH,
- NSS_EXCEPTION_EVENT_IPV6_IVID_MISSING,
- NSS_EXCEPTION_EVENT_IPV6_DSCP_MARKING_MISMATCH,
- NSS_EXCEPTION_EVENT_IPV6_VLAN_MARKING_MISMATCH,
- NSS_EXCEPTION_EVENT_IPV6_DEPRECATED,
- NSS_EXCEPTION_EVENT_IPV6_GRE_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV6_GRE_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV6_GRE_SMALL_HOP_LIMIT,
- NSS_EXCEPTION_EVENT_IPV6_DESTROY,
- NSS_EXCEPTION_EVENT_IPV6_ICMP_IPV6_UDPLITE_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV6_UDPLITE_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV6_UDPLITE_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV6_UDPLITE_SMALL_HOP_LIMIT,
- NSS_EXCEPTION_EVENT_IPV6_UDPLITE_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV6_MC_UDP_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV6_MC_MEM_ALLOC_FAILURE,
- NSS_EXCEPTION_EVENT_IPV6_MC_UPDATE_FAILURE,
- NSS_EXCEPTION_EVENT_IPV6_MC_PBUF_ALLOC_FAILURE,
- NSS_EXCEPTION_EVENT_IPV6_ESP_HEADER_INCOMPLETE,
- NSS_EXCEPTION_EVENT_IPV6_ESP_NO_ICME,
- NSS_EXCEPTION_EVENT_IPV6_ESP_IP_FRAGMENT,
- NSS_EXCEPTION_EVENT_IPV6_ESP_SMALL_HOP_LIMIT,
- NSS_EXCEPTION_EVENT_IPV6_ESP_NEEDS_FRAGMENTATION,
- NSS_EXCEPTION_EVENT_IPV6_MAX
+enum nss_ipv6_exception_events {
+ NSS_IPV6_EXCEPTION_EVENT_ICMP_HEADER_INCOMPLETE,
+ NSS_IPV6_EXCEPTION_EVENT_ICMP_UNHANDLED_TYPE,
+ NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_HEADER_INCOMPLETE,
+ NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_UDP_HEADER_INCOMPLETE,
+ NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_TCP_HEADER_INCOMPLETE,
+ NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_UNKNOWN_PROTOCOL,
+ NSS_IPV6_EXCEPTION_EVENT_ICMP_NO_ICME,
+ NSS_IPV6_EXCEPTION_EVENT_ICMP_FLUSH_TO_HOST,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_HEADER_INCOMPLETE,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_NO_ICME,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_SMALL_HOP_LIMIT,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_NEEDS_FRAGMENTATION,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_FLAGS,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_SEQ_EXCEEDS_RIGHT_EDGE,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_SMALL_DATA_OFFS,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_BAD_SACK,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_BIG_DATA_OFFS,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_SEQ_BEFORE_LEFT_EDGE,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_ACK_EXCEEDS_RIGHT_EDGE,
+ NSS_IPV6_EXCEPTION_EVENT_TCP_ACK_BEFORE_LEFT_EDGE,
+ NSS_IPV6_EXCEPTION_EVENT_UDP_HEADER_INCOMPLETE,
+ NSS_IPV6_EXCEPTION_EVENT_UDP_NO_ICME,
+ NSS_IPV6_EXCEPTION_EVENT_UDP_SMALL_HOP_LIMIT,
+ NSS_IPV6_EXCEPTION_EVENT_UDP_NEEDS_FRAGMENTATION,
+ NSS_IPV6_EXCEPTION_EVENT_WRONG_TARGET_MAC,
+ NSS_IPV6_EXCEPTION_EVENT_HEADER_INCOMPLETE,
+ NSS_IPV6_EXCEPTION_EVENT_UNKNOWN_PROTOCOL,
+ NSS_IPV6_EXCEPTION_EVENT_IVID_MISMATCH,
+ NSS_IPV6_EXCEPTION_EVENT_IVID_MISSING,
+ NSS_IPV6_EXCEPTION_EVENT_DSCP_MARKING_MISMATCH,
+ NSS_IPV6_EXCEPTION_EVENT_VLAN_MARKING_MISMATCH,
+ NSS_IPV6_EXCEPTION_EVENT_DEPRECATED,
+ NSS_IPV6_EXCEPTION_EVENT_GRE_NO_ICME,
+ NSS_IPV6_EXCEPTION_EVENT_GRE_NEEDS_FRAGMENTATION,
+ NSS_IPV6_EXCEPTION_EVENT_GRE_SMALL_HOP_LIMIT,
+ NSS_IPV6_EXCEPTION_EVENT_DESTROY,
+ NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_UDPLITE_HEADER_INCOMPLETE,
+ NSS_IPV6_EXCEPTION_EVENT_UDPLITE_HEADER_INCOMPLETE,
+ NSS_IPV6_EXCEPTION_EVENT_UDPLITE_NO_ICME,
+ NSS_IPV6_EXCEPTION_EVENT_UDPLITE_SMALL_HOP_LIMIT,
+ NSS_IPV6_EXCEPTION_EVENT_UDPLITE_NEEDS_FRAGMENTATION,
+ NSS_IPV6_EXCEPTION_EVENT_MC_UDP_NO_ICME,
+ NSS_IPV6_EXCEPTION_EVENT_MC_MEM_ALLOC_FAILURE,
+ NSS_IPV6_EXCEPTION_EVENT_MC_UPDATE_FAILURE,
+ NSS_IPV6_EXCEPTION_EVENT_MC_PBUF_ALLOC_FAILURE,
+ NSS_IPV6_EXCEPTION_EVENT_ESP_HEADER_INCOMPLETE,
+ NSS_IPV6_EXCEPTION_EVENT_ESP_NO_ICME,
+ NSS_IPV6_EXCEPTION_EVENT_ESP_IP_FRAGMENT,
+ NSS_IPV6_EXCEPTION_EVENT_ESP_SMALL_HOP_LIMIT,
+ NSS_IPV6_EXCEPTION_EVENT_ESP_NEEDS_FRAGMENTATION,
+ NSS_IPV6_EXCEPTION_EVENT_MAX
};
/**
@@ -660,7 +660,7 @@
uint32_t ipv6_mc_connection_flushes;
/**< Number of multicast connection flushes. */
- uint32_t exception_events[NSS_EXCEPTION_EVENT_IPV6_MAX];
+ uint32_t exception_events[NSS_IPV6_EXCEPTION_EVENT_MAX];
/**< Number of exception events. */
};
diff --git a/exports/nss_virt_if.h b/exports/nss_virt_if.h
index a4b8bd7..c7eeb53 100644
--- a/exports/nss_virt_if.h
+++ b/exports/nss_virt_if.h
@@ -312,19 +312,6 @@
extern void nss_virt_if_unregister(struct nss_virt_if_handle *handle);
/**
- * nss_virt_if_copy_stats
- * Gets statistics for the virtual interface from the NSS driver.
- *
- * @param[in] if_num NSS interface number (provided during dynamic interface allocation).
- * @param[in] i Index of statistics.
- * @param[out] line Buffer into which the statistics are copied.
- *
- * @return
- * Returns 0 if if_num is not in range, or the number of bytes copied.
- */
-extern int32_t nss_virt_if_copy_stats(int32_t if_num, int i, char *line);
-
-/**
* nss_virt_if_get_interface_num
* Returns the virtual interface number associated with the handle.
*
diff --git a/exports/nss_wifili_if.h b/exports/nss_wifili_if.h
index 4bbd7d0..8591855 100644
--- a/exports/nss_wifili_if.h
+++ b/exports/nss_wifili_if.h
@@ -911,4 +911,5 @@
* void
*/
void nss_unregister_wifili_radio_if(uint32_t if_num);
+
#endif /* __NSS_WIFILI_H */
diff --git a/nss_capwap.c b/nss_capwap.c
index 0366da9..f14bfaf 100644
--- a/nss_capwap.c
+++ b/nss_capwap.c
@@ -15,13 +15,14 @@
*/
/*
- * nss_capwap.h
+ * nss_capwap.c
* NSS CAPWAP driver interface APIs
*/
#include "nss_core.h"
#include "nss_capwap.h"
#include "nss_cmn.h"
#include "nss_tx_rx_common.h"
+#include "nss_capwap_stats.h"
/*
* Spinlock for protecting tunnel operations colliding with a tunnel destroy
@@ -596,6 +597,7 @@
void nss_capwap_init()
{
memset(&nss_capwap_hdl, 0, sizeof(nss_capwap_hdl));
+ nss_capwap_stats_dentry_create();
}
/*
diff --git a/nss_capwap_stats.c b/nss_capwap_stats.c
new file mode 100644
index 0000000..4b00536
--- /dev/null
+++ b/nss_capwap_stats.c
@@ -0,0 +1,290 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_capwap.h"
+#include "nss_capwap_stats.h"
+
+/*
+ * nss_capwap_stats_encap_str
+ * CAPWAP encap statistics string
+ */
+static int8_t *nss_capwap_stats_encap_str[NSS_CAPWAP_STATS_ENCAP_MAX] = {
+ "packets",
+ "bytes",
+ "fragments",
+ "drop_ref",
+ "drop_ver",
+ "drop_unalign",
+ "drop_hroom",
+ "drop_dtls",
+ "drop_nwireless"
+ "drop_qfull",
+ "drop_memfail"
+};
+
+/*
+ * nss_capwap_stats_decap_str
+ * CAPWAP decap statistics string
+ */
+static int8_t *nss_capwap_stats_decap_str[NSS_CAPWAP_STATS_DECAP_MAX] = {
+ "packets",
+ "bytes",
+ "DTLS_pkts",
+ "fragments",
+ "rx_dropped",
+ "drop_oversize",
+ "drop_frag_timeout",
+ "drop_frag_dup",
+ "drop_frag_gap",
+ "drop_qfull",
+ "drop_memfail",
+ "drop_csum",
+ "drop_malformed"
+};
+
+/*
+ * nss_capwap_stats_encap()
+ * Make a row for CAPWAP encap stats.
+ */
+static ssize_t nss_capwap_stats_encap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s)
+{
+ uint64_t tcnt = 0;
+
+ switch (i) {
+ case 0:
+ tcnt = s->pnode_stats.tx_packets;
+ break;
+ case 1:
+ tcnt = s->pnode_stats.tx_bytes;
+ break;
+ case 2:
+ tcnt = s->tx_segments;
+ break;
+ case 3:
+ tcnt = s->tx_dropped_sg_ref;
+ break;
+ case 4:
+ tcnt = s->tx_dropped_ver_mis;
+ break;
+ case 5:
+ tcnt = s->tx_dropped_unalign;
+ break;
+ case 6:
+ tcnt = s->tx_dropped_hroom;
+ break;
+ case 7:
+ tcnt = s->tx_dropped_dtls;
+ break;
+ case 8:
+ tcnt = s->tx_dropped_nwireless;
+ break;
+ case 9:
+ tcnt = s->tx_queue_full_drops;
+ break;
+ case 10:
+ tcnt = s->tx_mem_failure_drops;
+ break;
+ default:
+ return 0;
+ }
+
+ return snprintf(line, len, "%s = %llu\n", nss_capwap_stats_encap_str[i], tcnt);
+}
+
+/*
+ * nss_capwap_stats_decap()
+ * Make a row for CAPWAP decap stats.
+ */
+static ssize_t nss_capwap_stats_decap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s)
+{
+ uint64_t tcnt = 0;
+
+ switch (i) {
+ case 0:
+ tcnt = s->pnode_stats.rx_packets;
+ break;
+ case 1:
+ tcnt = s->pnode_stats.rx_bytes;
+ break;
+ case 2:
+ tcnt = s->dtls_pkts;
+ break;
+ case 3:
+ tcnt = s->rx_segments;
+ break;
+ case 4:
+ tcnt = s->pnode_stats.rx_dropped;
+ break;
+ case 5:
+ tcnt = s->rx_oversize_drops;
+ break;
+ case 6:
+ tcnt = s->rx_frag_timeout_drops;
+ break;
+ case 7:
+ tcnt = s->rx_dup_frag;
+ break;
+ case 8:
+ tcnt = s->rx_frag_gap_drops;
+ break;
+ case 9:
+ tcnt = s->rx_queue_full_drops;
+ return snprintf(line, len, "%s = %llu (n2h = %llu)\n", nss_capwap_stats_decap_str[i], tcnt, s->rx_n2h_queue_full_drops);
+ case 10:
+ tcnt = s->rx_mem_failure_drops;
+ break;
+ case 11:
+ tcnt = s->rx_csum_drops;
+ break;
+ case 12:
+ tcnt = s->rx_malformed;
+ break;
+ default:
+ return 0;
+ }
+
+ return snprintf(line, len, "%s = %llu\n", nss_capwap_stats_decap_str[i], tcnt);
+}
+
+/*
+ * nss_capwap_stats_read()
+ * Read CAPWAP stats
+ */
+static ssize_t nss_capwap_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos, uint16_t type)
+{
+ struct nss_stats_data *data = fp->private_data;
+ ssize_t bytes_read = 0;
+ struct nss_capwap_tunnel_stats stats;
+ size_t bytes;
+ char line[80];
+ int start;
+ uint32_t if_num = NSS_DYNAMIC_IF_START;
+ uint32_t max_if_num = NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES;
+
+ if (data) {
+ if_num = data->if_num;
+ }
+
+ /*
+ * If we are done accomodating all the CAPWAP tunnels.
+ */
+ if (if_num > max_if_num) {
+ return 0;
+ }
+
+ for (; if_num <= max_if_num; if_num++) {
+ bool isthere;
+
+ if (nss_is_dynamic_interface(if_num) == false) {
+ continue;
+ }
+
+ if (nss_dynamic_interface_get_type(nss_capwap_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
+ continue;
+ }
+
+ /*
+ * If CAPWAP tunnel does not exists, then isthere will be false.
+ */
+ isthere = nss_capwap_get_stats(if_num, &stats);
+ if (!isthere) {
+ continue;
+ }
+
+ bytes = snprintf(line, sizeof(line), "----if_num : %2d----\n", if_num);
+ if ((bytes_read + bytes) > sz) {
+ break;
+ }
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto fail;
+ }
+ bytes_read += bytes;
+ start = 0;
+ while (bytes_read < sz) {
+ if (type == 1) {
+ bytes = nss_capwap_stats_encap(line, sizeof(line), start, &stats);
+ } else {
+ bytes = nss_capwap_stats_decap(line, sizeof(line), start, &stats);
+ }
+
+ /*
+ * If we don't have any more lines in decap/encap.
+ */
+ if (bytes == 0) {
+ break;
+ }
+
+ if ((bytes_read + bytes) > sz)
+ break;
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto fail;
+ }
+
+ bytes_read += bytes;
+ start++;
+ }
+ }
+
+ if (bytes_read > 0) {
+ *ppos = bytes_read;
+ }
+
+ if (data) {
+ data->if_num = if_num;
+ }
+fail:
+ return bytes_read;
+}
+
+/*
+ * nss_capwap_decap_stats_read()
+ * Read CAPWAP decap stats
+ */
+static ssize_t nss_capwap_decap_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ return nss_capwap_stats_read(fp, ubuf, sz, ppos, 0);
+}
+
+/*
+ * nss_capwap_encap_stats_read()
+ * Read CAPWAP encap stats
+ */
+static ssize_t nss_capwap_encap_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ return nss_capwap_stats_read(fp, ubuf, sz, ppos, 1);
+}
+
+/*
+ * nss_capwap_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_encap)
+NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_decap)
+
+/*
+ * nss_capwap_stats_dentry_create()
+ * Create CAPWAP statistics debug entry
+ */
+void nss_capwap_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("capwap_encap", &nss_capwap_encap_stats_ops);
+ nss_stats_create_dentry("capwap_decap", &nss_capwap_decap_stats_ops);
+}
diff --git a/nss_capwap_stats.h b/nss_capwap_stats.h
new file mode 100644
index 0000000..0a64189
--- /dev/null
+++ b/nss_capwap_stats.h
@@ -0,0 +1,63 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_CAPWAP_STATS_H__
+#define __NSS_CAPWAP_STATS_H__
+
+/*
+ * CAPWAP encap statistics
+ */
+enum nss_capwap_stats_encap_types {
+ NSS_CAPWAP_STATS_ENCAP_TX_PKTS,
+ NSS_CAPWAP_STATS_ENCAP_TX_BYTES,
+ NSS_CAPWAP_STATS_ENCAP_TX_SEGMENTS,
+ NSS_CAPWAP_STATS_ENCAP_TX_DROP_SG_REF,
+ NSS_CAPWAP_STATS_ENCAP_TX_DROP_VER_MISMATCH,
+ NSS_CAPWAP_STATS_ENCAP_TX_DROP_UNALIGN,
+ NSS_CAPWAP_STATS_ENCAP_TX_DROP_HEADER_ROOM,
+ NSS_CAPWAP_STATS_ENCAP_TX_DROP_DTLS,
+ NSS_CAPWAP_STATS_ENCAP_TX_DROP_NWIRELESS,
+ NSS_CAPWAP_STATS_ENCAP_TX_DROP_QUEUE_FULL,
+ NSS_CAPWAP_STATS_ENCAP_TX_DROP_MEM_FAIL,
+ NSS_CAPWAP_STATS_ENCAP_MAX
+};
+
+/*
+ * CAPWAP decap statistics
+ */
+enum nss_capwap_stats_decap_types {
+ NSS_CAPWAP_STATS_DECAP_RX_PKTS,
+ NSS_CAPWAP_STATS_DECAP_RX_BYTES,
+ NSS_CAPWAP_STATS_DECAP_RX_DTLS_PKTS,
+ NSS_CAPWAP_STATS_DECAP_RX_SEGMENTS,
+ NSS_CAPWAP_STATS_DECAP_RX_DROP,
+ NSS_CAPWAP_STATS_DECAP_RX_DROP_OVERSIZE,
+ NSS_CAPWAP_STATS_DECAP_RX_DROP_FRAG_TIMEOUT,
+ NSS_CAPWAP_STATS_DECAP_RX_DROP_DUP_FRAG,
+ NSS_CAPWAP_STATS_DECAP_RX_DROP_FRAG_GAP,
+ NSS_CAPWAP_STATS_DECAP_RX_DROP_QUEUE_FULL,
+ NSS_CAPWAP_STATS_DECAP_RX_DROP_MEM_FAIL,
+ NSS_CAPWAP_STATS_DECAP_RX_DROP_CHECKSUM,
+ NSS_CAPWAP_STATS_DECAP_RX_MALFORMED,
+ NSS_CAPWAP_STATS_DECAP_MAX
+};
+
+/*
+ * CAPWAP statistics APIs
+ */
+extern void nss_capwap_stats_dentry_create(void);
+
+#endif /* __NSS_CAPWAP_STATS_H__ */
diff --git a/nss_core.h b/nss_core.h
index 4f2aa1d..dd98d27 100644
--- a/nss_core.h
+++ b/nss_core.h
@@ -38,6 +38,7 @@
#include "nss_hlos_if.h"
#include "nss_oam.h"
#include "nss_data_plane.h"
+#include "nss_stats.h"
/*
* XXX:can't add this to api_if.h till the deprecated
@@ -263,144 +264,6 @@
extern struct nss_top_instance nss_top_main;
/*
- * IPV4 node statistics
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_ipv4 {
- NSS_STATS_IPV4_ACCELERATED_RX_PKTS = 0,
- /* Accelerated IPv4 RX packets */
- NSS_STATS_IPV4_ACCELERATED_RX_BYTES,
- /* Accelerated IPv4 RX bytes */
- NSS_STATS_IPV4_ACCELERATED_TX_PKTS,
- /* Accelerated IPv4 TX packets */
- NSS_STATS_IPV4_ACCELERATED_TX_BYTES,
- /* Accelerated IPv4 TX bytes */
- NSS_STATS_IPV4_CONNECTION_CREATE_REQUESTS,
- /* Number of IPv4 connection create requests */
- NSS_STATS_IPV4_CONNECTION_CREATE_COLLISIONS,
- /* Number of IPv4 connection create requests that collided with existing entries */
- NSS_STATS_IPV4_CONNECTION_CREATE_INVALID_INTERFACE,
- /* Number of IPv4 connection create requests that had invalid interface */
- NSS_STATS_IPV4_CONNECTION_DESTROY_REQUESTS,
- /* Number of IPv4 connection destroy requests */
- NSS_STATS_IPV4_CONNECTION_DESTROY_MISSES,
- /* Number of IPv4 connection destroy requests that missed the cache */
- NSS_STATS_IPV4_CONNECTION_HASH_HITS,
- /* Number of IPv4 connection hash hits */
- NSS_STATS_IPV4_CONNECTION_HASH_REORDERS,
- /* Number of IPv4 connection hash reorders */
- NSS_STATS_IPV4_CONNECTION_FLUSHES,
- /* Number of IPv4 connection flushes */
- NSS_STATS_IPV4_CONNECTION_EVICTIONS,
- /* Number of IPv4 connection evictions */
- NSS_STATS_IPV4_FRAGMENTATIONS,
- /* Number of successful IPv4 fragmentations performed */
- NSS_STATS_IPV4_DROPPED_BY_RULE,
- /* Number of IPv4 packets dropped because of a drop rule. */
- NSS_STATS_IPV4_MC_CONNECTION_CREATE_REQUESTS,
- /* Number of successful IPv4 Multicast create requests */
- NSS_STATS_IPV4_MC_CONNECTION_UPDATE_REQUESTS,
- /* Number of successful IPv4 Multicast update requests */
- NSS_STATS_IPV4_MC_CONNECTION_CREATE_INVALID_INTERFACE,
- /* Number of IPv4 Multicast connection create requests that had invalid interface */
- NSS_STATS_IPV4_MC_CONNECTION_DESTROY_REQUESTS,
- /* Number of IPv4 Multicast connection destroy requests */
- NSS_STATS_IPV4_MC_CONNECTION_DESTROY_MISSES,
- /* Number of IPv4 Multicast connection destroy requests that missed the cache */
- NSS_STATS_IPV4_MC_CONNECTION_FLUSHES,
- /* Number of IPv4 Multicast connection flushes */
- NSS_STATS_IPV4_MAX,
-};
-
-/*
- * IPV4 reasm node statistics
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_ipv4_reasm {
- NSS_STATS_IPV4_REASM_EVICTIONS = 0,
- /* Number of evicted fragment queues due to set memory threshold */
- NSS_STATS_IPV4_REASM_ALLOC_FAILS,
- /* Number of fragment queue allocation failures */
- NSS_STATS_IPV4_REASM_TIMEOUTS,
- /* Number of expired fragment queues */
- NSS_STATS_IPV4_REASM_MAX,
-};
-
-/*
- * IPV6 node statistics
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_ipv6 {
- NSS_STATS_IPV6_ACCELERATED_RX_PKTS = 0,
- /* Accelerated IPv6 RX packets */
- NSS_STATS_IPV6_ACCELERATED_RX_BYTES,
- /* Accelerated IPv6 RX bytes */
- NSS_STATS_IPV6_ACCELERATED_TX_PKTS,
- /* Accelerated IPv6 TX packets */
- NSS_STATS_IPV6_ACCELERATED_TX_BYTES,
- /* Accelerated IPv6 TX bytes */
- NSS_STATS_IPV6_CONNECTION_CREATE_REQUESTS,
- /* Number of IPv6 connection create requests */
- NSS_STATS_IPV6_CONNECTION_CREATE_COLLISIONS,
- /* Number of IPv6 connection create requests that collided with existing entries */
- NSS_STATS_IPV6_CONNECTION_CREATE_INVALID_INTERFACE,
- /* Number of IPv6 connection create requests that had invalid interface */
- NSS_STATS_IPV6_CONNECTION_DESTROY_REQUESTS,
- /* Number of IPv6 connection destroy requests */
- NSS_STATS_IPV6_CONNECTION_DESTROY_MISSES,
- /* Number of IPv6 connection destroy requests that missed the cache */
- NSS_STATS_IPV6_CONNECTION_HASH_HITS,
- /* Number of IPv6 connection hash hits */
- NSS_STATS_IPV6_CONNECTION_HASH_REORDERS,
- /* Number of IPv6 connection hash reorders */
- NSS_STATS_IPV6_CONNECTION_FLUSHES,
- /* Number of IPv6 connection flushes */
- NSS_STATS_IPV6_CONNECTION_EVICTIONS,
- /* Number of IPv6 connection evictions */
- NSS_STATS_IPV6_FRAGMENTATIONS,
- /* Number of successful IPv6 fragmentations performed */
- NSS_STATS_IPV6_FRAG_FAILS,
- /* Number of IPv6 fragmentation fails */
- NSS_STATS_IPV6_DROPPED_BY_RULE,
- /* Number of IPv6 packets dropped by a drop rule. */
- NSS_STATS_IPV6_MC_CONNECTION_CREATE_REQUESTS,
- /* Number of successful IPv6 Multicast create requests */
- NSS_STATS_IPV6_MC_CONNECTION_UPDATE_REQUESTS,
- /* Number of successful IPv6 Multicast update requests */
- NSS_STATS_IPV6_MC_CONNECTION_CREATE_INVALID_INTERFACE,
- /* Number of IPv6 Multicast connection create requests that had invalid interface */
- NSS_STATS_IPV6_MC_CONNECTION_DESTROY_REQUESTS,
- /* Number of IPv6 Multicast connection destroy requests */
- NSS_STATS_IPV6_MC_CONNECTION_DESTROY_MISSES,
- /* Number of IPv6 Multicast connection destroy requests that missed the cache */
- NSS_STATS_IPV6_MC_CONNECTION_FLUSHES,
- /* Number of IPv6 Multicast connection flushes */
- NSS_STATS_IPV6_MAX,
-};
-
-/*
- * IPv6 reasm node statistics
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_ipv6_reasm {
- NSS_STATS_IPV6_REASM_ALLOC_FAILS = 0,
- /* Number of fragment queue allocation failures */
- NSS_STATS_IPV6_REASM_TIMEOUTS,
- /* Number of expired fragment queues */
- NSS_STATS_IPV6_REASM_DISCARDS,
- /* Number of fragment queues discarded due to malformed fragments*/
- NSS_STATS_IPV6_REASM_MAX,
-};
-
-/*
* HLOS driver statistics
*
* WARNING: There is a 1:1 mapping between values below and corresponding
@@ -437,24 +300,6 @@
};
/*
- * PPPoE statistics
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_pppoe {
- NSS_STATS_PPPOE_SESSION_CREATE_REQUESTS = 0,
- /* Number of PPPoE session create requests */
- NSS_STATS_PPPOE_SESSION_CREATE_FAILURES,
- /* Number of PPPoE session create failures */
- NSS_STATS_PPPOE_SESSION_DESTROY_REQUESTS,
- /* Number of PPPoE session destroy requests */
- NSS_STATS_PPPOE_SESSION_DESTROY_MISSES,
- /* Number of PPPoE session destroy requests that missed the cache */
- NSS_STATS_PPPOE_MAX,
-};
-
-/*
* GMAC node statistics
*
* WARNING: There is a 1:1 mapping between values below and corresponding
@@ -470,896 +315,6 @@
};
/*
- * ETH_RX node statistics
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_eth_rx {
- NSS_STATS_ETH_RX_TOTAL_TICKS = 0,
- /* Total clock ticks spend inside the eth_rx package */
- NSS_STATS_ETH_RX_WORST_CASE_TICKS,
- /* Worst case iteration of the eth_rx in ticks */
- NSS_STATS_ETH_RX_ITERATIONS, /* Number of iterations around the eth_rx */
- NSS_STATS_ETH_RX_MAX,
-};
-
-/*
- * Node statistics
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_node {
- NSS_STATS_NODE_RX_PKTS,
- /* Accelerated node RX packets */
- NSS_STATS_NODE_RX_BYTES,
- /* Accelerated node RX bytes */
- NSS_STATS_NODE_TX_PKTS,
- /* Accelerated node TX packets */
- NSS_STATS_NODE_TX_BYTES,
- /* Accelerated node TX bytes */
- NSS_STATS_NODE_RX_QUEUE_0_DROPPED,
- /* Accelerated node RX Queue 0 dropped */
- NSS_STATS_NODE_RX_QUEUE_1_DROPPED,
- /* Accelerated node RX Queue 1 dropped */
- NSS_STATS_NODE_RX_QUEUE_2_DROPPED,
- /* Accelerated node RX Queue 2 dropped */
- NSS_STATS_NODE_RX_QUEUE_3_DROPPED,
- /* Accelerated node RX Queue 3 dropped */
- NSS_STATS_NODE_MAX,
-};
-
-/*
- * N2H node statistics
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_n2h {
- NSS_STATS_N2H_QUEUE_DROPPED = NSS_STATS_NODE_MAX,
- /* Number of packets dropped because the exception queue is too full */
- NSS_STATS_N2H_TOTAL_TICKS, /* Total clock ticks spend inside the N2H */
- NSS_STATS_N2H_WORST_CASE_TICKS, /* Worst case iteration of the exception path in ticks */
- NSS_STATS_N2H_ITERATIONS, /* Number of iterations around the N2H */
-
- NSS_STATS_N2H_PBUF_OCM_ALLOC_FAILS, /* Number of pbuf ocm allocations that have failed */
- NSS_STATS_N2H_PBUF_OCM_FREE_COUNT, /* Number of pbuf ocm free count */
- NSS_STATS_N2H_PBUF_OCM_TOTAL_COUNT, /* Number of pbuf ocm total count */
-
- NSS_STATS_N2H_PBUF_DEFAULT_ALLOC_FAILS, /* Number of pbuf default allocations that have failed */
- NSS_STATS_N2H_PBUF_DEFAULT_FREE_COUNT, /* Number of pbuf default free count */
- NSS_STATS_N2H_PBUF_DEFAULT_TOTAL_COUNT, /* Number of pbuf default total count */
-
- NSS_STATS_N2H_PAYLOAD_ALLOC_FAILS, /* Number of pbuf allocations that have failed because there were no free payloads */
- NSS_STATS_N2H_PAYLOAD_FREE_COUNT, /* Number of free payloads that exist */
-
- NSS_STATS_N2H_H2N_CONTROL_PACKETS, /* Control packets received from HLOS */
- NSS_STATS_N2H_H2N_CONTROL_BYTES, /* Control bytes received from HLOS */
- NSS_STATS_N2H_N2H_CONTROL_PACKETS, /* Control packets sent to HLOS */
- NSS_STATS_N2H_N2H_CONTROL_BYTES, /* Control bytes sent to HLOS */
-
- NSS_STATS_N2H_H2N_DATA_PACKETS, /* Data packets received from HLOS */
- NSS_STATS_N2H_H2N_DATA_BYTES, /* Data bytes received from HLOS */
- NSS_STATS_N2H_N2H_DATA_PACKETS, /* Data packets sent to HLOS */
- NSS_STATS_N2H_N2H_DATA_BYTES, /* Data bytes sent to HLOS */
- NSS_STATS_N2H_N2H_TOT_PAYLOADS, /* No. of payloads in NSS */
- NSS_STATS_N2H_N2H_INTERFACE_INVALID, /* No. of bad interface access */
-
- NSS_STATS_N2H_MAX,
-};
-
-/*
- * LSO_RX driver statistics
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_lso_rx {
- NSS_STATS_LSO_RX_TX_DROPPED, /* Number of packets dropped cause transmit queue is full */
- NSS_STATS_LSO_RX_DROPPED, /* Number of packets dropped because of node internal errors */
- NSS_STATS_LSO_RX_PBUF_ALLOC_FAIL, /* Number of pbuf alloc failures */
- NSS_STATS_LSO_RX_PBUF_REFERENCE_FAIL, /* Number of pbuf reference failures */
- NSS_STATS_LSO_RX_MAX,
-};
-
-/*
- * wifi statistics
- */
-enum nss_stats_wifi {
- NSS_STATS_WIFI_RX_PKTS, /* Number of packets enqueud to wifi */
- NSS_STATS_WIFI_RX_QUEUE_0_DROPPED, /* Number of packet dropped during enqueue to wifi queue 0 */
- NSS_STATS_WIFI_RX_QUEUE_1_DROPPED, /* Number of packet dropped during enqueue to wifi queue 1 */
- NSS_STATS_WIFI_RX_QUEUE_2_DROPPED, /* Number of packet dropped during enqueue to wifi queue 2 */
- NSS_STATS_WIFI_RX_QUEUE_3_DROPPED, /* Number of packet dropped during enqueue to wifi queue 3 */
- NSS_STATS_WIFI_TX_PKTS, /* Number of packets transmited out to wifi */
- NSS_STATS_WIFI_TX_DROPPED, /* Number of packets dropped during transmission */
- NSS_STATS_WIFI_TX_COMPLETED, /* Number of packets for which transmission completion received */
- NSS_STATS_WIFI_MGMT_RCV_CNT, /* Number of management packets received from host for transmission */
- NSS_STATS_WIFI_MGMT_TX_PKTS, /* Number of management packets transmitted over wifi */
- NSS_STATS_WIFI_MGMT_TX_DROPPED, /* Number of management packets dropped because of transmission failure */
- NSS_STATS_WIFI_MGMT_TX_COMPLETIONS, /* Number of management packets for which tx completions are received */
- NSS_STATS_WIFI_TX_INV_PEER_ENQUEUE_CNT, /* Number of packets for which tx enqueue failed because of invalid peer */
- NSS_STATS_WIFI_RX_INV_PEER_RCV_CNT, /* Number of packets received from wifi with invalid peer id */
- NSS_STATS_WIFI_RX_PN_CHECK_FAILED, /* Number of rx packets which failed packet number check */
- NSS_STATS_WIFI_RX_DELIVERED, /* Number of rx packets that NSS wifi offload path could successfully process */
- NSS_STATS_WIFI_RX_BYTES_DELIVERED, /* Number of rx bytes that NSS wifi offload path could successfully process */
- NSS_STATS_WIFI_TX_BYTES_COMPLETED, /* Number of bytes for which transmission completion received */
- NSS_STATS_WIFI_RX_DELIVER_UNALIGNED_DROP_CNT, /* Number of rx packets that dropped beacause of alignment mismatch*/
- NSS_STATS_WIFI_TIDQ_ENQUEUE_CNT, /* Number of packets enqueued to TIDQ */
- NSS_STATS_WIFI_TIDQ_DEQUEUE_CNT = NSS_STATS_WIFI_TIDQ_ENQUEUE_CNT + 8, /* Number of packets dequeued from TIDQ */
- NSS_STATS_WIFI_TIDQ_ENQUEUE_FAIL_CNT = NSS_STATS_WIFI_TIDQ_DEQUEUE_CNT + 8, /* Enqueue fail count */
- NSS_STATS_WIFI_TIDQ_TTL_EXPIRE_CNT = NSS_STATS_WIFI_TIDQ_ENQUEUE_FAIL_CNT + 8, /* Number of packets expired from TIDQ */
- NSS_STATS_WIFI_TIDQ_DEQUEUE_REQ_CNT = NSS_STATS_WIFI_TIDQ_TTL_EXPIRE_CNT + 8, /* Dequeue reuest count from wifi fw */
- NSS_STATS_WIFI_TOTAL_TIDQ_DEPTH = NSS_STATS_WIFI_TIDQ_DEQUEUE_REQ_CNT + 8, /* Tidq depth */
- NSS_STATS_WIFI_RX_HTT_FETCH_CNT, /* Total number of HTT Fetch Messages received from wifi fw */
- NSS_STATS_WIFI_TOTAL_TIDQ_BYPASS_CNT, /* Total number of packets which have bypassed tidq and sent to wifi fw */
- NSS_STATS_WIFI_GLOBAL_Q_FULL_CNT, /* Total number of packets dropped due to global queue full condition */
- NSS_STATS_WIFI_TIDQ_FULL_CNT, /* Total number of packets dropped due to TID queue full condition */
- NSS_STATS_WIFI_MAX,
-};
-
-/*
- * wifili txrx statistics
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_wifili_txrx {
- NSS_STATS_WIFILI_RX_MSDU_ERROR, /* Number of rx packets received from ring with msdu error */
- NSS_STATS_WIFILI_RX_INV_PEER_RCV, /* Number of rx packets with invalid peer id */
- NSS_STATS_WIFILI_RX_WDS_SRCPORT_EXCEPTION, /* Number of rx packets exceptioned to host because of src port learn fail */
- NSS_STATS_WIFILI_RX_WDS_SRCPORT_EXCEPTION_FAIL, /* Number of rx src port learn fail packets failed to get enqueued to host */
- NSS_STATS_WIFILI_RX_DELIVERD, /* Number of packets wifili has given to next node */
- NSS_STATS_WIFILI_RX_DELIVER_DROPPED, /* Number of packets which wifili failed to enqueue to next node */
- NSS_STATS_WIFILI_RX_INTRA_BSS_UCAST, /* Number of packets which wifili send for intra bss ucast packet */
- NSS_STATS_WIFILI_RX_INTRA_BSS_UCAST_FAIL, /* Number of packets which wifili send for intra bss ucast packet failed */
- NSS_STATS_WIFILI_RX_INTRA_BSS_MCAST, /* Number of packets which wifili send for intra bss mcast packet */
- NSS_STATS_WIFILI_RX_INTRA_BSS_MCAST_FAIL, /* Number of packets which wifili send for intra bss mcast packet failed */
- NSS_STATS_WIFILI_RX_SG_RCV_SEND, /* Number of packets sg send */
- NSS_STATS_WIFILI_RX_SG_RCV_FAIL, /* Number of packets sg received failure */
- NSS_STATS_WIFILI_RX_MCAST_ECHO, /* Number of multicast echo packets received */
- NSS_STATS_WIFILI_TX_ENQUEUE, /* Number of packets that got enqueued to wifili */
- NSS_STATS_WIFILI_TX_ENQUEUE_DROP, /* Number of packets that dropped during enqueue to wifili */
- NSS_STATS_WIFILI_TX_DEQUEUE, /* Number of packets that are dequeued by wifili */
- NSS_STATS_WIFILI_TX_HW_ENQUEUE_FAIL, /* Number of rx packets that NSS wifi offload path could successfully process */
- NSS_STATS_WIFILI_TX_SENT_COUNT, /* Number of Tx packets sent to hw */
- NSS_STATS_WIFILI_TXRX_MAX, /* Number of max txrx stats*/
-};
-
-/*
- * wifili tcl stats
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_wifili_tcl {
- NSS_STATS_WIFILI_TCL_NO_HW_DESC, /* Number of tcl hw desc*/
- NSS_STATS_WIFILI_TCL_RING_FULL, /* Number of times tcl ring full*/
- NSS_STATS_WIFILI_TCL_RING_SENT, /* Number of times tcl desc sent*/
- NSS_STATS_WIFILI_TCL_MAX, /* Number of max tcl stats*/
-};
-
-/*
- * wifili tx comp stats
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_wifili_tx_comp {
- NSS_STATS_WIFILI_TX_DESC_FREE_INV_BUFSRC, /* Number of invalid bufsrc packets */
- NSS_STATS_WIFILI_TX_DESC_FREE_INV_COOKIE, /* Number of invalid cookie packets */
- NSS_STATS_WIFILI_TX_DESC_FREE_HW_RING_EMPTY, /* Number of time times hw ring empty found*/
- NSS_STATS_WIFILI_TX_DESC_FREE_REAPED, /* Number of tx packets that are reaped out of tx completion ring */
- NSS_STATS_WIFILI_TX_DESC_FREE_MAX, /* Number of tx comp stats */
-};
-
-/*
- * wifili tx reo stats
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_wifili_reo {
- NSS_STATS_WIFILI_REO_ERROR, /* Number of reo error*/
- NSS_STATS_WIFILI_REO_REAPED, /* Number of reo reaped*/
- NSS_STATS_WIFILI_REO_INV_COOKIE, /* Number of invalid cookie*/
- NSS_STATS_WIFILI_REO_MAX, /* Number of reo stats*/
-};
-
-/*
- * wifili tx desc stats
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_wifili_txsw_pool {
- NSS_STATS_WIFILI_TX_DESC_IN_USE, /* Number of tx packets that are currently in flight */
- NSS_STATS_WIFILI_TX_DESC_ALLOC_FAIL, /* Number of tx sw desc alloc failures */
- NSS_STATS_WIFILI_TX_DESC_ALREADY_ALLOCATED, /* Number of tx sw desc already allocated*/
- NSS_STATS_WIFILI_TX_DESC_INVALID_FREE, /* Number of tx sw desc invalid free*/
- NSS_STATS_WIFILI_TX_DESC_FREE_SRC_FW, /* Number of tx desc for which release src is fw */
- NSS_STATS_WIFILI_TX_DESC_FREE_COMPLETION, /* Number of tx desc completion*/
- NSS_STATS_WIFILI_TX_DESC_NO_PB, /* Number of tx desc pb is null*/
- NSS_STATS_WIFILI_TX_DESC_MAX, /* Number of tx desc stats*/
-};
-
-/*
- * wifili tx ext desc stats
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_wifili_ext_txsw_pool {
- NSS_STATS_WIFILI_EXT_TX_DESC_IN_USE, /* Number of ext tx packets that are currently in flight */
- NSS_STATS_WIFILI_EXT_TX_DESC_ALLOC_FAIL, /* Number of ext tx sw desc alloc failures */
- NSS_STATS_WIFILI_EXT_TX_DESC_ALREADY_ALLOCATED, /* Number of ext tx sw desc already allocated*/
- NSS_STATS_WIFILI_EXT_TX_DESC_INVALID_FREE, /* Number of ext tx sw desc invalid free*/
- NSS_STATS_WIFILI_EXT_TX_DESC_MAX, /* Number of ext tx desc stats*/
-};
-
-/*
- * wifili rx desc stats
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_wifili_rxdma_pool {
- NSS_STATS_WIFILI_RX_DESC_NO_PB, /* Number of rx desc no pb*/
- NSS_STATS_WIFILI_RX_DESC_ALLOC_FAIL, /* Number of rx desc alloc failures */
- NSS_STATS_WIFILI_RX_DESC_IN_USE, /* Number of rx desc alloc in use*/
- NSS_STATS_WIFILI_RX_DESC_MAX, /* Number of rx desc stats*/
-};
-
-/*
- * wifili rx dma ring stats
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_wifili_rxdma_ring {
- NSS_STATS_WIFILI_RXDMA_DESC_UNAVAILABLE, /* Number of rx dma desc unavailable */
- NSS_STATS_WIFILI_RXDMA_BUF_REPLENISHED, /* Number of rx dma buf replished */
- NSS_STATS_WIFILI_RXDMA_DESC_MAX, /* Number of rx dma desc stast */
-};
-
-/*
- * wifili wbm ring stats
- *
- * WARNING: There is a 1:1 mapping between values below and corresponding
- * stats string array in nss_stats.c
- */
-enum nss_stats_wifili_wbm {
- NSS_STATS_WIFILI_WBM_SRC_DMA, /* Number of rx invalid src dma */
- NSS_STATS_WIFILI_WBM_SRC_DMA_CODE_INV, /* Number of rx invalid src dma */
- NSS_STATS_WIFILI_WBM_SRC_REO, /* Number of rx invalid src reo */
- NSS_STATS_WIFILI_WBM_SRC_REO_CODE_NULLQ, /* Number of rx invalid reo error with null q */
- NSS_STATS_WIFILI_WBM_SRC_REO_CODE_INV, /* Number of rx invalid reo error with null q */
- NSS_STATS_WIFILI_WBM_SRC_INV, /* Number of rx invalid reo code invalid */
- NSS_STATS_WIFILI_WBM_MAX, /* Number of rx wbm stats */
-};
-
-/*
- * NSS core state -- for H2N/N2H
- * l2tpv2 debug stats
- */
-enum nss_stats_l2tpv2_session {
- NSS_STATS_L2TPV2_SESSION_RX_PPP_LCP_PKTS, /* Number of ppp lcp packets received */
- NSS_STATS_L2TPV2_SESSION_RX_EXP_DATA_PKTS, /* Number of RX exceptioned packets */
- NSS_STATS_L2TPV2_SESSION_ENCAP_PBUF_ALLOC_FAIL_PKTS, /* Number of times packet buffer allocation failed during encap */
- NSS_STATS_L2TPV2_SESSION_DECAP_PBUF_ALLOC_FAIL_PKTS, /* Number of times packet buffer allocation failed during decap */
- NSS_STATS_L2TPV2_SESSION_MAX
-};
-
-/*
- * PortID statistics
- */
-enum nss_stats_portid {
- NSS_STATS_PORTID_RX_INVALID_HEADER,
- NSS_STATS_PORTID_MAX,
-};
-
-struct nss_stats_l2tpv2_session_debug {
- uint64_t stats[NSS_STATS_L2TPV2_SESSION_MAX];
- int32_t if_index;
- uint32_t if_num; /* nss interface number */
- bool valid;
-};
-
-/*
- * PPTP debug stats
- */
-enum nss_stats_pptp_session {
- NSS_STATS_PPTP_ENCAP_RX_PACKETS,
- NSS_STATS_PPTP_ENCAP_RX_BYTES,
- NSS_STATS_PPTP_ENCAP_TX_PACKETS,
- NSS_STATS_PPTP_ENCAP_TX_BYTES,
- NSS_STATS_PPTP_ENCAP_RX_QUEUE_0_DROP,
- NSS_STATS_PPTP_ENCAP_RX_QUEUE_1_DROP,
- NSS_STATS_PPTP_ENCAP_RX_QUEUE_2_DROP,
- NSS_STATS_PPTP_ENCAP_RX_QUEUE_3_DROP,
- NSS_STATS_PPTP_DECAP_RX_PACKETS,
- NSS_STATS_PPTP_DECAP_RX_BYTES,
- NSS_STATS_PPTP_DECAP_TX_PACKETS,
- NSS_STATS_PPTP_DECAP_TX_BYTES,
- NSS_STATS_PPTP_DECAP_RX_QUEUE_0_DROP,
- NSS_STATS_PPTP_DECAP_RX_QUEUE_1_DROP,
- NSS_STATS_PPTP_DECAP_RX_QUEUE_2_DROP,
- NSS_STATS_PPTP_DECAP_RX_QUEUE_3_DROP,
- NSS_STATS_PPTP_SESSION_ENCAP_HEADROOM_ERR,
- NSS_STATS_PPTP_SESSION_ENCAP_SMALL_SIZE,
- NSS_STATS_PPTP_SESSION_ENCAP_PNODE_ENQUEUE_FAIL,
- NSS_STATS_PPTP_SESSION_DECAP_NO_SEQ_NOR_ACK,
- NSS_STATS_PPTP_SESSION_DECAP_INVAL_GRE_FLAGS,
- NSS_STATS_PPTP_SESSION_DECAP_INVAL_GRE_PROTO,
- NSS_STATS_PPTP_SESSION_DECAP_WRONG_SEQ,
- NSS_STATS_PPTP_SESSION_DECAP_INVAL_PPP_HDR,
- NSS_STATS_PPTP_SESSION_DECAP_PPP_LCP,
- NSS_STATS_PPTP_SESSION_DECAP_UNSUPPORTED_PPP_PROTO,
- NSS_STATS_PPTP_SESSION_DECAP_PNODE_ENQUEUE_FAIL,
- NSS_STATS_PPTP_SESSION_MAX
-};
-
-struct nss_stats_pptp_session_debug {
- uint64_t stats[NSS_STATS_PPTP_SESSION_MAX];
- int32_t if_index;
- uint32_t if_num; /* nss interface number */
- bool valid;
-};
-
-/*
- * PPE stats
- */
-enum nss_stats_ppe_conn {
- NSS_STATS_PPE_V4_L3_FLOWS, /* No of v4 routed flows */
- NSS_STATS_PPE_V4_L2_FLOWS, /* No of v4 bridge flows */
- NSS_STATS_PPE_V4_CREATE_REQ, /* No of v4 create requests */
- NSS_STATS_PPE_V4_CREATE_FAIL, /* No of v4 create failure */
- NSS_STATS_PPE_V4_DESTROY_REQ, /* No of v4 delete requests */
- NSS_STATS_PPE_V4_DESTROY_FAIL, /* No of v4 delete failure */
- NSS_STATS_PPE_V4_MC_CREATE_REQ, /* No of v4 MC create requests */
- NSS_STATS_PPE_V4_MC_CREATE_FAIL, /* No of v4 MC create failure */
- NSS_STATS_PPE_V4_MC_UPDATE_REQ, /* No of v4 MC update requests */
- NSS_STATS_PPE_V4_MC_UPDATE_FAIL, /* No of v4 MC update failure */
- NSS_STATS_PPE_V4_MC_DESTROY_REQ, /* No of v4 MC delete requests */
- NSS_STATS_PPE_V4_MC_DESTROY_FAIL, /* No of v4 MC delete failure */
-
- NSS_STATS_PPE_V6_L3_FLOWS, /* No of v6 routed flows */
- NSS_STATS_PPE_V6_L2_FLOWS, /* No of v6 bridge flows */
- NSS_STATS_PPE_V6_CREATE_REQ, /* No of v6 create requests */
- NSS_STATS_PPE_V6_CREATE_FAIL, /* No of v6 create failure */
- NSS_STATS_PPE_V6_DESTROY_REQ, /* No of v6 delete requests */
- NSS_STATS_PPE_V6_DESTROY_FAIL, /* No of v6 delete failure */
- NSS_STATS_PPE_V6_MC_CREATE_REQ, /* No of v6 MC create requests */
- NSS_STATS_PPE_V6_MC_CREATE_FAIL, /* No of v6 MC create failure */
- NSS_STATS_PPE_V6_MC_UPDATE_REQ, /* No of v6 MC update requests */
- NSS_STATS_PPE_V6_MC_UPDATE_FAIL, /* No of v6 MC update failure */
- NSS_STATS_PPE_V6_MC_DESTROY_REQ, /* No of v6 MC delete requests */
- NSS_STATS_PPE_V6_MC_DESTROY_FAIL, /* No of v6 MC delete failure */
-
- NSS_STATS_PPE_FAIL_VP_FULL, /* Create req fail due to VP table full */
- NSS_STATS_PPE_FAIL_NH_FULL, /* Create req fail due to nexthop table full */
- NSS_STATS_PPE_FAIL_FLOW_FULL, /* Create req fail due to flow table full */
- NSS_STATS_PPE_FAIL_HOST_FULL, /* Create req fail due to host table full */
- NSS_STATS_PPE_FAIL_PUBIP_FULL, /* Create req fail due to pub-ip table full */
- NSS_STATS_PPE_FAIL_PORT_SETUP, /* Create req fail due to PPE port not setup */
- NSS_STATS_PPE_FAIL_RW_FIFO_FULL, /* Create req fail due to rw fifo full */
- NSS_STATS_PPE_FAIL_FLOW_COMMAND, /* Create req fail due to PPE flow command failure */
- NSS_STATS_PPE_FAIL_UNKNOWN_PROTO, /* Create req fail due to unknown protocol */
- NSS_STATS_PPE_FAIL_PPE_UNRESPONSIVE, /* Create req fail due to PPE not responding */
- NSS_STATS_PPE_CE_OPAQUE_INVALID, /* Create req fail due to invalid opaque in CE */
- NSS_STATS_PPE_FAIL_FQG_FULL, /* Create req fail due to flow qos group full */
- NSS_STATS_PPE_CONN_MAX
-};
-
-enum nss_stats_ppe_l3 {
- NSS_STATS_PPE_L3_DBG_0, /* PPE L3 debug register 0 */
- NSS_STATS_PPE_L3_DBG_1, /* PPE L3 debug register 1 */
- NSS_STATS_PPE_L3_DBG_2, /* PPE L3 debug register 2 */
- NSS_STATS_PPE_L3_DBG_3, /* PPE L3 debug register 3 */
- NSS_STATS_PPE_L3_DBG_4, /* PPE L3 debug register 4 */
- NSS_STATS_PPE_L3_DBG_PORT, /* PPE L3 debug register Port */
- NSS_STATS_PPE_L3_MAX
-};
-
-enum nss_stats_ppe_code {
- NSS_STATS_PPE_CODE_CPU, /* PPE CPU code for last packet processed */
- NSS_STATS_PPE_CODE_DROP, /* PPE DROP code for last packet processed */
- NSS_STATS_PPE_CODE_MAX
-};
-
-/*
- * PPE drop codes
- */
-enum nss_stats_ppe_dc {
- NSS_STATS_PPE_DROP_CODE_UNKNOWN, /* PPE drop code unknown */
- NSS_STATS_PPE_DROP_CODE_EXP_UNKNOWN_L2_PROT, /* PPE drop code exp unknown l2 prot */
- NSS_STATS_PPE_DROP_CODE_EXP_PPPOE_WRONG_VER_TYPE, /* PPE drop code exp pppoe wrong ver type */
- NSS_STATS_PPE_DROP_CODE_EXP_PPPOE_WRONG_CODE, /* PPE drop code exp pppoe wrong code */
- NSS_STATS_PPE_DROP_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT, /* PPE drop code exp pppoe unsupported ppp prot */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_WRONG_VER, /* PPE drop code exp ipv4 wrong ver */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_SMALL_IHL, /* PPE drop code exp ipv4 small ihl */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_WITH_OPTION, /* PPE drop code exp ipv4 with option */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_HDR_INCOMPLETE, /* PPE drop code exp ipv4 hdr incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_BAD_TOTAL_LEN, /* PPE drop code exp ipv4 bad total len */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_DATA_INCOMPLETE, /* PPE drop code exp ipv4 data incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_FRAG, /* PPE drop code exp ipv4 frag */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_PING_OF_DEATH, /* PPE drop code exp ipv4 ping of death */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_SNALL_TTL, /* PPE drop code exp ipv4 snall ttl */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_UNK_IP_PROT, /* PPE drop code exp ipv4 unk ip prot */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_CHECKSUM_ERR, /* PPE drop code exp ipv4 checksum err */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_INV_SIP, /* PPE drop code exp ipv4 inv sip */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_INV_DIP, /* PPE drop code exp ipv4 inv dip */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_LAND_ATTACK, /* PPE drop code exp ipv4 land attack */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_AH_HDR_INCOMPLETE, /* PPE drop code exp ipv4 ah hdr incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_AH_HDR_CROSS_BORDER, /* PPE drop code exp ipv4 ah hdr cross border */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE, /* PPE drop code exp ipv4 esp hdr incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_WRONG_VER, /* PPE drop code exp ipv6 wrong ver */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_HDR_INCOMPLETE, /* PPE drop code exp ipv6 hdr incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_BAD_PAYLOAD_LEN, /* PPE drop code exp ipv6 bad payload len */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_DATA_INCOMPLETE, /* PPE drop code exp ipv6 data incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_WITH_EXT_HDR, /* PPE drop code exp ipv6 with ext hdr */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_SMALL_HOP_LIMIT, /* PPE drop code exp ipv6 small hop limit */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_INV_SIP, /* PPE drop code exp ipv6 inv sip */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_INV_DIP, /* PPE drop code exp ipv6 inv dip */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_LAND_ATTACK, /* PPE drop code exp ipv6 land attack */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_FRAG, /* PPE drop code exp ipv6 frag */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_PING_OF_DEATH, /* PPE drop code exp ipv6 ping of death */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_WITH_MORE_EXT_HDR, /* PPE drop code exp ipv6 with more ext hdr */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_UNK_LAST_NEXT_HDR, /* PPE drop code exp ipv6 unk last next hdr */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE, /* PPE drop code exp ipv6 mobility hdr incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_MOBILITY_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 mobility hdr cross border */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_AH_HDR_INCOMPLETE, /* PPE drop code exp ipv6 ah hdr incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_AH_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 ah hdr cross border */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE, /* PPE drop code exp ipv6 esp hdr incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_ESP_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 esp hdr cross border */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_INCOMPLETE, /* PPE drop code exp ipv6 other ext hdr incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 other ext hdr cross border */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_HDR_INCOMPLETE, /* PPE drop code exp tcp hdr incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_HDR_CROSS_BORDER, /* PPE drop code exp tcp hdr cross border */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_SMAE_SP_DP, /* PPE drop code exp tcp smae sp dp */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_SMALL_DATA_OFFSET, /* PPE drop code exp tcp small data offset */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_FLAGS_0, /* PPE drop code exp tcp flags 0 */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_FLAGS_1, /* PPE drop code exp tcp flags 1 */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_FLAGS_2, /* PPE drop code exp tcp flags 2 */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_FLAGS_3, /* PPE drop code exp tcp flags 3 */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_FLAGS_4, /* PPE drop code exp tcp flags 4 */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_FLAGS_5, /* PPE drop code exp tcp flags 5 */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_FLAGS_6, /* PPE drop code exp tcp flags 6 */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_FLAGS_7, /* PPE drop code exp tcp flags 7 */
- NSS_STATS_PPE_DROP_CODE_EXP_TCP_CHECKSUM_ERR, /* PPE drop code exp tcp checksum err */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_HDR_INCOMPLETE, /* PPE drop code exp udp hdr incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_HDR_CROSS_BORDER, /* PPE drop code exp udp hdr cross border */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_SMAE_SP_DP, /* PPE drop code exp udp smae sp dp */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_BAD_LEN, /* PPE drop code exp udp bad len */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_DATA_INCOMPLETE, /* PPE drop code exp udp data incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_CHECKSUM_ERR, /* PPE drop code exp udp checksum err */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_LITE_HDR_INCOMPLETE, /* PPE drop code exp udp lite hdr incomplete */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_LITE_HDR_CROSS_BORDER, /* PPE drop code exp udp lite hdr cross border */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_LITE_SMAE_SP_DP, /* PPE drop code exp udp lite smae sp dp */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_1_TO_7, /* PPE drop code exp udp lite csm cov 1 to 7 */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_TOO_LONG, /* PPE drop code exp udp lite csm cov too long */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_CROSS_BORDER, /* PPE drop code exp udp lite csm cov cross border */
- NSS_STATS_PPE_DROP_CODE_EXP_UDP_LITE_CHECKSUM_ERR, /* PPE drop code exp udp lite checksum err */
- NSS_STATS_PPE_DROP_CODE_L3_MC_BRIDGE_ACTION, /* PPE drop code l3 mc bridge action */
- NSS_STATS_PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION, /* PPE drop code l3 no route prehead nat action */
- NSS_STATS_PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR, /* PPE drop code l3 no route prehead nat error */
- NSS_STATS_PPE_DROP_CODE_L3_ROUTE_ACTION, /* PPE drop code l3 route action */
- NSS_STATS_PPE_DROP_CODE_L3_NO_ROUTE_ACTION, /* PPE drop code l3 no route action */
- NSS_STATS_PPE_DROP_CODE_L3_NO_ROUTE_NH_INVALID_ACTION, /* PPE drop code l3 no route nh invalid action */
- NSS_STATS_PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_ACTION, /* PPE drop code l3 no route prehead action */
- NSS_STATS_PPE_DROP_CODE_L3_BRIDGE_ACTION, /* PPE drop code l3 bridge action */
- NSS_STATS_PPE_DROP_CODE_L3_FLOW_ACTION, /* PPE drop code l3 flow action */
- NSS_STATS_PPE_DROP_CODE_L3_FLOW_MISS_ACTION, /* PPE drop code l3 flow miss action */
- NSS_STATS_PPE_DROP_CODE_L2_EXP_MRU_FAIL, /* PPE drop code l2 exp mru fail */
- NSS_STATS_PPE_DROP_CODE_L2_EXP_MTU_FAIL, /* PPE drop code l2 exp mtu fail */
- NSS_STATS_PPE_DROP_CODE_L3_EXP_IP_PREFIX_BC, /* PPE drop code l3 exp ip prefix bc */
- NSS_STATS_PPE_DROP_CODE_L3_EXP_MTU_FAIL, /* PPE drop code l3 exp mtu fail */
- NSS_STATS_PPE_DROP_CODE_L3_EXP_MRU_FAIL, /* PPE drop code l3 exp mru fail */
- NSS_STATS_PPE_DROP_CODE_L3_EXP_ICMP_RDT, /* PPE drop code l3 exp icmp rdt */
- NSS_STATS_PPE_DROP_CODE_FAKE_MAC_HEADER_ERR, /* PPE drop code fake mac header err */
- NSS_STATS_PPE_DROP_CODE_L3_EXP_IP_RT_TTL_ZERO, /* PPE drop code l3 exp ip rt ttl zero */
- NSS_STATS_PPE_DROP_CODE_L3_FLOW_SERVICE_CODE_LOOP, /* PPE drop code l3 flow service code loop */
- NSS_STATS_PPE_DROP_CODE_L3_FLOW_DE_ACCELEARTE, /* PPE drop code l3 flow de accelearte */
- NSS_STATS_PPE_DROP_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL, /* PPE drop code l3 exp flow src if chk fail */
- NSS_STATS_PPE_DROP_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH, /* PPE drop code l3 flow sync toggle mismatch */
- NSS_STATS_PPE_DROP_CODE_L3_EXP_MTU_DF_FAIL, /* PPE drop code l3 exp mtu df fail */
- NSS_STATS_PPE_DROP_CODE_L3_EXP_PPPOE_MULTICAST, /* PPE drop code l3 exp pppoe multicast */
- NSS_STATS_PPE_DROP_CODE_IPV4_SG_UNKNOWN, /* PPE drop code ipv4 sg unknown */
- NSS_STATS_PPE_DROP_CODE_IPV6_SG_UNKNOWN, /* PPE drop code ipv6 sg unknown */
- NSS_STATS_PPE_DROP_CODE_ARP_SG_UNKNOWN, /* PPE drop code arp sg unknown */
- NSS_STATS_PPE_DROP_CODE_ND_SG_UNKNOWN, /* PPE drop code nd sg unknown */
- NSS_STATS_PPE_DROP_CODE_IPV4_SG_VIO, /* PPE drop code ipv4 sg vio */
- NSS_STATS_PPE_DROP_CODE_IPV6_SG_VIO, /* PPE drop code ipv6 sg vio */
- NSS_STATS_PPE_DROP_CODE_ARP_SG_VIO, /* PPE drop code arp sg vio */
- NSS_STATS_PPE_DROP_CODE_ND_SG_VIO, /* PPE drop code nd sg vio */
- NSS_STATS_PPE_DROP_CODE_L2_NEW_MAC_ADDRESS, /* PPE drop code l2 new mac address */
- NSS_STATS_PPE_DROP_CODE_L2_HASH_COLLISION, /* PPE drop code l2 hash collision */
- NSS_STATS_PPE_DROP_CODE_L2_STATION_MOVE, /* PPE drop code l2 station move */
- NSS_STATS_PPE_DROP_CODE_L2_LEARN_LIMIT, /* PPE drop code l2 learn limit */
- NSS_STATS_PPE_DROP_CODE_L2_SA_LOOKUP_ACTION, /* PPE drop code l2 sa lookup action */
- NSS_STATS_PPE_DROP_CODE_L2_DA_LOOKUP_ACTION, /* PPE drop code l2 da lookup action */
- NSS_STATS_PPE_DROP_CODE_APP_CTRL_ACTION, /* PPE drop code app ctrl action */
- NSS_STATS_PPE_DROP_CODE_IN_VLAN_FILTER_ACTION, /* PPE drop code in vlan filter action */
- NSS_STATS_PPE_DROP_CODE_IN_VLAN_XLT_MISS, /* PPE drop code in vlan xlt miss */
- NSS_STATS_PPE_DROP_CODE_EG_VLAN_FILTER_DROP, /* PPE drop code eg vlan filter drop */
- NSS_STATS_PPE_DROP_CODE_ACL_PRE_ACTION, /* PPE drop code acl pre action */
- NSS_STATS_PPE_DROP_CODE_ACL_POST_ACTION, /* PPE drop code acl post action */
- NSS_STATS_PPE_DROP_CODE_MC_BC_SA, /* PPE drop code mc bc sa */
- NSS_STATS_PPE_DROP_CODE_NO_DESTINATION, /* PPE drop code no destination */
- NSS_STATS_PPE_DROP_CODE_STG_IN_FILTER, /* PPE drop code stg in filter */
- NSS_STATS_PPE_DROP_CODE_STG_EG_FILTER, /* PPE drop code stg eg filter */
- NSS_STATS_PPE_DROP_CODE_SOURCE_FILTER_FAIL, /* PPE drop code source filter fail */
- NSS_STATS_PPE_DROP_CODE_TRUNK_SEL_FAIL, /* PPE drop code trunk sel fail */
- NSS_STATS_PPE_DROP_CODE_TX_EN_FAIL, /* PPE drop code tx en fail */
- NSS_STATS_PPE_DROP_CODE_VLAN_TAG_FMT, /* PPE drop code vlan tag fmt */
- NSS_STATS_PPE_DROP_CODE_CRC_ERR, /* PPE drop code crc err */
- NSS_STATS_PPE_DROP_CODE_PAUSE_FRAME, /* PPE drop code pause frame */
- NSS_STATS_PPE_DROP_CODE_PROMISC, /* PPE drop code promisc */
- NSS_STATS_PPE_DROP_CODE_ISOLATION, /* PPE drop code isolation */
- NSS_STATS_PPE_DROP_CODE_MGMT_APP, /* PPE drop code mgmt app */
- NSS_STATS_PPE_DROP_CODE_FAKE_L2_PROT_ERR, /* PPE drop code fake l2 prot err */
- NSS_STATS_PPE_DROP_CODE_POLICER, /* PPE drop code policer */
- NSS_STATS_PPE_DROP_CODE_MAX /* PPE drop code max */
-};
-
-/*
- * PPE CPU codes
- */
-#define NSS_STATS_PPE_CPU_CODE_MAX 150
-#define NSS_STATS_PPE_CPU_CODE_EXCEPTION_MAX 69
-#define NSS_STATS_PPE_CPU_CODE_NONEXCEPTION_START 69
-#define NSS_STATS_PPE_CPU_CODE_NONEXCEPTION_MAX (NSS_STATS_PPE_CPU_CODE_MAX - NSS_STATS_PPE_CPU_CODE_NONEXCEPTION_START)
-enum nss_stats_ppe_cc {
- NSS_STATS_PPE_CPU_CODE_FORWARDING = 0, /* PPE cpu code forwarding */
- NSS_STATS_PPE_CPU_CODE_EXP_UNKNOWN_L2_PROT = 1, /* PPE cpu code exp unknown l2 prot */
- NSS_STATS_PPE_CPU_CODE_EXP_PPPOE_WRONG_VER_TYPE = 2, /* PPE cpu code exp pppoe wrong ver type */
- NSS_STATS_PPE_CPU_CODE_EXP_PPPOE_WRONG_CODE = 3, /* PPE cpu code exp pppoe wrong code */
- NSS_STATS_PPE_CPU_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT = 4, /* PPE cpu code exp pppoe unsupported ppp prot */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_WRONG_VER = 5, /* PPE cpu code exp ipv4 wrong ver */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_SMALL_IHL = 6, /* PPE cpu code exp ipv4 small ihl */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_WITH_OPTION = 7, /* PPE cpu code exp ipv4 with option */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_HDR_INCOMPLETE = 8, /* PPE cpu code exp ipv4 hdr incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_BAD_TOTAL_LEN = 9, /* PPE cpu code exp ipv4 bad total len */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_DATA_INCOMPLETE = 10, /* PPE cpu code exp ipv4 data incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_FRAG = 11, /* PPE cpu code exp ipv4 frag */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_PING_OF_DEATH = 12, /* PPE cpu code exp ipv4 ping of death */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_SNALL_TTL = 13, /* PPE cpu code exp ipv4 snall ttl */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_UNK_IP_PROT = 14, /* PPE cpu code exp ipv4 unk ip prot */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_CHECKSUM_ERR = 15, /* PPE cpu code exp ipv4 checksum err */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_INV_SIP = 16, /* PPE cpu code exp ipv4 inv sip */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_INV_DIP = 17, /* PPE cpu code exp ipv4 inv dip */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_LAND_ATTACK = 18, /* PPE cpu code exp ipv4 land attack */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_AH_HDR_INCOMPLETE = 19, /* PPE cpu code exp ipv4 ah hdr incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_AH_HDR_CROSS_BORDER = 20, /* PPE cpu code exp ipv4 ah hdr cross border */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE = 21, /* PPE cpu code exp ipv4 esp hdr incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_WRONG_VER = 22, /* PPE cpu code exp ipv6 wrong ver */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_HDR_INCOMPLETE = 23, /* PPE cpu code exp ipv6 hdr incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_BAD_PAYLOAD_LEN = 24, /* PPE cpu code exp ipv6 bad payload len */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_DATA_INCOMPLETE = 25, /* PPE cpu code exp ipv6 data incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_WITH_EXT_HDR = 26, /* PPE cpu code exp ipv6 with ext hdr */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_SMALL_HOP_LIMIT = 27, /* PPE cpu code exp ipv6 small hop limit */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_INV_SIP = 28, /* PPE cpu code exp ipv6 inv sip */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_INV_DIP = 29, /* PPE cpu code exp ipv6 inv dip */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_LAND_ATTACK = 30, /* PPE cpu code exp ipv6 land attack */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_FRAG = 31, /* PPE cpu code exp ipv6 frag */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_PING_OF_DEATH = 32, /* PPE cpu code exp ipv6 ping of death */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_WITH_MORE_EXT_HDR = 33, /* PPE cpu code exp ipv6 with more ext hdr */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_UNK_LAST_NEXT_HDR = 34, /* PPE cpu code exp ipv6 unk last next hdr */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE = 35, /* PPE cpu code exp ipv6 mobility hdr incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_MOBILITY_HDR_CROSS_BORDER = 36, /* PPE cpu code exp ipv6 mobility hdr cross border */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_AH_HDR_INCOMPLETE = 37, /* PPE cpu code exp ipv6 ah hdr incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_AH_HDR_CROSS_BORDER = 38, /* PPE cpu code exp ipv6 ah hdr cross border */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE = 39, /* PPE cpu code exp ipv6 esp hdr incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_ESP_HDR_CROSS_BORDER = 40, /* PPE cpu code exp ipv6 esp hdr cross border */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_OTHER_EXT_HDR_INCOMPLETE = 41, /* PPE cpu code exp ipv6 other ext hdr incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_IPV6_OTHER_EXT_HDR_CROSS_BORDER = 42, /* PPE cpu code exp ipv6 other ext hdr cross border */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_HDR_INCOMPLETE = 43, /* PPE cpu code exp tcp hdr incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_HDR_CROSS_BORDER = 44, /* PPE cpu code exp tcp hdr cross border */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_SMAE_SP_DP = 45, /* PPE cpu code exp tcp smae sp dp */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_SMALL_DATA_OFFSET = 46, /* PPE cpu code exp tcp small data offset */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_FLAGS_0 = 47, /* PPE cpu code exp tcp flags 0 */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_FLAGS_1 = 48, /* PPE cpu code exp tcp flags 1 */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_FLAGS_2 = 49, /* PPE cpu code exp tcp flags 2 */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_FLAGS_3 = 50, /* PPE cpu code exp tcp flags 3 */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_FLAGS_4 = 51, /* PPE cpu code exp tcp flags 4 */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_FLAGS_5 = 52, /* PPE cpu code exp tcp flags 5 */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_FLAGS_6 = 53, /* PPE cpu code exp tcp flags 6 */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_FLAGS_7 = 54, /* PPE cpu code exp tcp flags 7 */
- NSS_STATS_PPE_CPU_CODE_EXP_TCP_CHECKSUM_ERR = 55, /* PPE cpu code exp tcp checksum err */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_HDR_INCOMPLETE = 56, /* PPE cpu code exp udp hdr incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_HDR_CROSS_BORDER = 57, /* PPE cpu code exp udp hdr cross border */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_SMAE_SP_DP = 58, /* PPE cpu code exp udp smae sp dp */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_BAD_LEN = 59, /* PPE cpu code exp udp bad len */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_DATA_INCOMPLETE = 60, /* PPE cpu code exp udp data incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_CHECKSUM_ERR = 61, /* PPE cpu code exp udp checksum err */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_LITE_HDR_INCOMPLETE = 62, /* PPE cpu code exp udp lite hdr incomplete */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_LITE_HDR_CROSS_BORDER = 63, /* PPE cpu code exp udp lite hdr cross border */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_LITE_SMAE_SP_DP = 64, /* PPE cpu code exp udp lite smae sp dp */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_LITE_CSM_COV_1_TO_7 = 65, /* PPE cpu code exp udp lite csm cov 1 to 7 */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_LITE_CSM_COV_TOO_LONG = 66, /* PPE cpu code exp udp lite csm cov too long */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_LITE_CSM_COV_CROSS_BORDER = 67, /* PPE cpu code exp udp lite csm cov cross border */
- NSS_STATS_PPE_CPU_CODE_EXP_UDP_LITE_CHECKSUM_ERR = 68, /* PPE cpu code exp udp lite checksum err */
- NSS_STATS_PPE_CPU_CODE_EXP_FAKE_L2_PROT_ERR = 69, /* PPE cpu code exp fake l2 prot err */
- NSS_STATS_PPE_CPU_CODE_EXP_FAKE_MAC_HEADER_ERR = 70, /* PPE cpu code exp fake mac header err */
- NSS_STATS_PPE_CPU_CODE_EXP_BITMAP_MAX = 78, /* PPE cpu code exp bitmap max */
- NSS_STATS_PPE_CPU_CODE_L2_EXP_MRU_FAIL = 79, /* PPE cpu code l2 exp mru fail */
- NSS_STATS_PPE_CPU_CODE_L2_EXP_MTU_FAIL = 80, /* PPE cpu code l2 exp mtu fail */
- NSS_STATS_PPE_CPU_CODE_L3_EXP_IP_PREFIX_BC = 81, /* PPE cpu code l3 exp ip prefix bc */
- NSS_STATS_PPE_CPU_CODE_L3_EXP_MTU_FAIL = 82, /* PPE cpu code l3 exp mtu fail */
- NSS_STATS_PPE_CPU_CODE_L3_EXP_MRU_FAIL = 83, /* PPE cpu code l3 exp mru fail */
- NSS_STATS_PPE_CPU_CODE_L3_EXP_ICMP_RDT = 84, /* PPE cpu code l3 exp icmp rdt */
- NSS_STATS_PPE_CPU_CODE_L3_EXP_IP_RT_TTL1_TO_ME = 85, /* PPE cpu code l3 exp ip rt ttl1 to me */
- NSS_STATS_PPE_CPU_CODE_L3_EXP_IP_RT_TTL_ZERO = 86, /* PPE cpu code l3 exp ip rt ttl zero */
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_SERVICE_CODE_LOOP = 87, /* PPE cpu code l3 flow service code loop */
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_DE_ACCELERATE = 88, /* PPE cpu code l3 flow de accelerate */
- NSS_STATS_PPE_CPU_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL = 89, /* PPE cpu code l3 exp flow src if chk fail */
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH = 90, /* PPE cpu code l3 flow sync toggle mismatch */
- NSS_STATS_PPE_CPU_CODE_L3_EXP_MTU_DF_FAIL = 91, /* PPE cpu code l3 exp mtu df fail */
- NSS_STATS_PPE_CPU_CODE_L3_EXP_PPPOE_MULTICAST = 92, /* PPE cpu code l3 exp pppoe multicast */
- NSS_STATS_PPE_CPU_CODE_MGMT_OFFSET = 96, /* PPE cpu code mgmt offset */
- NSS_STATS_PPE_CPU_CODE_MGMT_EAPOL = 97, /* PPE cpu code mgmt eapol */
- NSS_STATS_PPE_CPU_CODE_MGMT_PPPOE_DIS = 98, /* PPE cpu code mgmt pppoe dis */
- NSS_STATS_PPE_CPU_CODE_MGMT_IGMP = 99, /* PPE cpu code mgmt igmp */
- NSS_STATS_PPE_CPU_CODE_MGMT_ARP_REQ = 100, /* PPE cpu code mgmt arp req */
- NSS_STATS_PPE_CPU_CODE_MGMT_ARP_REP = 101, /* PPE cpu code mgmt arp rep */
- NSS_STATS_PPE_CPU_CODE_MGMT_DHCPv4 = 102, /* PPE cpu code mgmt dhcpv4 */
- NSS_STATS_PPE_CPU_CODE_MGMT_MLD = 107, /* PPE cpu code mgmt mld */
- NSS_STATS_PPE_CPU_CODE_MGMT_NS = 108, /* PPE cpu code mgmt ns */
- NSS_STATS_PPE_CPU_CODE_MGMT_NA = 109, /* PPE cpu code mgmt na */
- NSS_STATS_PPE_CPU_CODE_MGMT_DHCPv6 = 110, /* PPE cpu code mgmt dhcpv6 */
- NSS_STATS_PPE_CPU_CODE_PTP_OFFSET = 112, /* PPE cpu code ptp offset */
- NSS_STATS_PPE_CPU_CODE_PTP_SYNC = 113, /* PPE cpu code ptp sync */
- NSS_STATS_PPE_CPU_CODE_PTP_FOLLOW_UP = 114, /* PPE cpu code ptp follow up */
- NSS_STATS_PPE_CPU_CODE_PTP_DELAY_REQ = 115, /* PPE cpu code ptp delay req */
- NSS_STATS_PPE_CPU_CODE_PTP_DELAY_RESP = 116, /* PPE cpu code ptp delay resp */
- NSS_STATS_PPE_CPU_CODE_PTP_PDELAY_REQ = 117, /* PPE cpu code ptp pdelay req */
- NSS_STATS_PPE_CPU_CODE_PTP_PDELAY_RESP = 118, /* PPE cpu code ptp pdelay resp */
- NSS_STATS_PPE_CPU_CODE_PTP_PDELAY_RESP_FOLLOW_UP = 119, /* PPE cpu code ptp pdelay resp follow up */
- NSS_STATS_PPE_CPU_CODE_PTP_ANNOUNCE = 120, /* PPE cpu code ptp announce */
- NSS_STATS_PPE_CPU_CODE_PTP_MANAGEMENT = 121, /* PPE cpu code ptp management */
- NSS_STATS_PPE_CPU_CODE_PTP_SIGNALING = 122, /* PPE cpu code ptp signaling */
- NSS_STATS_PPE_CPU_CODE_PTP_PKT_RSV_MSG = 127, /* PPE cpu code ptp pkt rsv msg */
- NSS_STATS_PPE_CPU_CODE_IPV4_SG_UNKNOWN = 136, /* PPE cpu code ipv4 sg unknown */
- NSS_STATS_PPE_CPU_CODE_IPV6_SG_UNKNOWN = 137, /* PPE cpu code ipv6 sg unknown */
- NSS_STATS_PPE_CPU_CODE_ARP_SG_UNKNOWN = 138, /* PPE cpu code arp sg unknown */
- NSS_STATS_PPE_CPU_CODE_ND_SG_UNKNOWN = 139, /* PPE cpu code nd sg unknown */
- NSS_STATS_PPE_CPU_CODE_IPV4_SG_VIO = 140, /* PPE cpu code ipv4 sg vio */
- NSS_STATS_PPE_CPU_CODE_IPV6_SG_VIO = 141, /* PPE cpu code ipv6 sg vio */
- NSS_STATS_PPE_CPU_CODE_ARP_SG_VIO = 142, /* PPE cpu code arp sg vio */
- NSS_STATS_PPE_CPU_CODE_ND_SG_VIO = 143, /* PPE cpu code nd sg vio */
- NSS_STATS_PPE_CPU_CODE_L3_ROUTING_IP_TO_ME = 148, /* PPE cpu code l3 routing ip to me */
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_SNAT_ACTION = 149, /* PPE cpu code l3 flow snat action */
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_DNAT_ACTION = 150, /* PPE cpu code l3 flow dnat action */
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_RT_ACTION = 151, /* PPE cpu code l3 flow rt action */
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_BR_ACTION = 152, /* PPE cpu code l3 flow br action */
- NSS_STATS_PPE_CPU_CODE_L3_MC_BRIDGE_ACTION = 153, /* PPE cpu code l3 mc bridge action */
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_RT_ACTION = 154, /* PPE cpu code l3 route prehead rt action */
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAPT_ACTION = 155, /* PPE cpu code l3 route prehead snapt action */
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAPT_ACTION = 156, /* PPE cpu code l3 route prehead dnapt action */
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAT_ACTION = 157, /* PPE cpu code l3 route prehead snat action */
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAT_ACTION = 158, /* PPE cpu code l3 route prehead dnat action */
- NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION = 159, /* PPE cpu code l3 no route prehead nat action */
- NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR = 160, /* PPE cpu code l3 no route prehead nat error */
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_ACTION = 161, /* PPE cpu code l3 route action */
- NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_ACTION = 162, /* PPE cpu code l3 no route action */
- NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_NH_INVALID_ACTION = 163, /* PPE cpu code l3 no route nh invalid action */
- NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_ACTION = 164, /* PPE cpu code l3 no route prehead action */
- NSS_STATS_PPE_CPU_CODE_L3_BRIDGE_ACTION = 165, /* PPE cpu code l3 bridge action */
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_ACTION = 166, /* PPE cpu code l3 flow action */
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_MISS_ACTION = 167, /* PPE cpu code l3 flow miss action */
- NSS_STATS_PPE_CPU_CODE_L2_NEW_MAC_ADDRESS = 168, /* PPE cpu code l2 new mac address */
- NSS_STATS_PPE_CPU_CODE_L2_HASH_COLLISION = 169, /* PPE cpu code l2 hash collision */
- NSS_STATS_PPE_CPU_CODE_L2_STATION_MOVE = 170, /* PPE cpu code l2 station move */
- NSS_STATS_PPE_CPU_CODE_L2_LEARN_LIMIT = 171, /* PPE cpu code l2 learn limit */
- NSS_STATS_PPE_CPU_CODE_L2_SA_LOOKUP_ACTION = 172, /* PPE cpu code l2 sa lookup action */
- NSS_STATS_PPE_CPU_CODE_L2_DA_LOOKUP_ACTION = 173, /* PPE cpu code l2 da lookup action */
- NSS_STATS_PPE_CPU_CODE_APP_CTRL_ACTION = 174, /* PPE cpu code app ctrl action */
- NSS_STATS_PPE_CPU_CODE_IN_VLAN_FILTER_ACTION = 175, /* PPE cpu code in vlan filter action */
- NSS_STATS_PPE_CPU_CODE_IN_VLAN_XLT_MISS = 176, /* PPE cpu code in vlan xlt miss */
- NSS_STATS_PPE_CPU_CODE_EG_VLAN_FILTER_DROP = 177, /* PPE cpu code eg vlan filter drop */
- NSS_STATS_PPE_CPU_CODE_ACL_PRE_ACTION = 178, /* PPE cpu code acl pre action */
- NSS_STATS_PPE_CPU_CODE_ACL_POST_ACTION = 179, /* PPE cpu code acl post action */
- NSS_STATS_PPE_CPU_CODE_SERVICE_CODE_ACTION = 180, /* PPE cpu code service code action */
-};
-
-struct nss_stats_ppe_debug {
- uint32_t conn_stats[NSS_STATS_PPE_CONN_MAX];
- uint32_t l3_stats[NSS_STATS_PPE_L3_MAX];
- uint32_t code_stats[NSS_STATS_PPE_CODE_MAX];
- int32_t if_index;
- uint32_t if_num; /* nss interface number */
- bool valid;
-};
-
-/*
- * GRE base debug statistics types
- */
-enum nss_stats_gre_base_debug_types {
- NSS_STATS_GRE_BASE_RX_PACKETS, /**< Rx packet count. */
- NSS_STATS_GRE_BASE_RX_DROPPED, /**< Rx dropped count. */
- NSS_STATS_GRE_BASE_EXP_ETH_HDR_MISSING, /**< Ethernet header missing. */
- NSS_STATS_GRE_BASE_EXP_ETH_TYPE_NON_IP, /**< Not IPV4 or IPV6 packet. */
- NSS_STATS_GRE_BASE_EXP_IP_UNKNOWN_PROTOCOL, /**< Unknown protocol. */
- NSS_STATS_GRE_BASE_EXP_IP_HEADER_INCOMPLETE, /**< Bad IP header. */
- NSS_STATS_GRE_BASE_EXP_IP_BAD_TOTAL_LENGTH, /**< Invalid IP packet length. */
- NSS_STATS_GRE_BASE_EXP_IP_BAD_CHECKSUM, /**< Bad packet checksum. */
- NSS_STATS_GRE_BASE_EXP_IP_DATAGRAM_INCOMPLETE, /**< Bad packet. */
- NSS_STATS_GRE_BASE_EXP_IP_FRAGMENT, /**< IP fragment. */
- NSS_STATS_GRE_BASE_EXP_IP_OPTIONS_INCOMPLETE, /**< Invalid IP options. */
- NSS_STATS_GRE_BASE_EXP_IP_WITH_OPTIONS, /**< IP packet with options. */
- NSS_STATS_GRE_BASE_EXP_IPV6_UNKNOWN_PROTOCOL, /**< Unknown protocol. */
- NSS_STATS_GRE_BASE_EXP_IPV6_HEADER_INCOMPLETE, /**< Incomplete IPV6 header. */
- NSS_STATS_GRE_BASE_EXP_GRE_UNKNOWN_SESSION, /**< Unknown GRE session. */
- NSS_STATS_GRE_BASE_EXP_GRE_NODE_INACTIVE, /**< GRE node inactive. */
- NSS_STATS_GRE_BASE_DEBUG_MAX, /**< GRE base error max. */
-};
-
-/*
- * GRE base debug statistics
- */
-struct nss_stats_gre_base_debug {
- uint64_t stats[NSS_STATS_GRE_BASE_DEBUG_MAX]; /**< GRE debug statistics. */
-};
-
-/*
- * GRE session debug statistics types
- */
-enum nss_stats_gre_session_debug_types {
- NSS_STATS_GRE_SESSION_PBUF_ALLOC_FAIL, /**< Pbuf alloc failure. */
- NSS_STATS_GRE_SESSION_DECAP_FORWARD_ENQUEUE_FAIL, /**< Rx forward enqueue failure. */
- NSS_STATS_GRE_SESSION_ENCAP_FORWARD_ENQUEUE_FAIL, /**< Tx forward enqueue failure. */
- NSS_STATS_GRE_SESSION_DECAP_TX_FORWARDED, /**< Packets forwarded after decap. */
- NSS_STATS_GRE_SESSION_ENCAP_RX_RECEIVED, /**< Packets received for encap. */
- NSS_STATS_GRE_SESSION_ENCAP_RX_DROPPED, /**< Packets dropped while enqueue for encap. */
- NSS_STATS_GRE_SESSION_ENCAP_RX_LINEAR_FAIL, /**< Packets dropped during encap linearization. */
- NSS_STATS_GRE_SESSION_EXP_RX_KEY_ERROR, /**< Rx KEY error. */
- NSS_STATS_GRE_SESSION_EXP_RX_SEQ_ERROR, /**< Rx sequence number error. */
- NSS_STATS_GRE_SESSION_EXP_RX_CS_ERROR, /**< Rx checksum error. */
- NSS_STATS_GRE_SESSION_EXP_RX_FLAG_MISMATCH, /**< Rx flag mismatch. */
- NSS_STATS_GRE_SESSION_EXP_RX_MALFORMED, /**< Rx malformed packet. */
- NSS_STATS_GRE_SESSION_EXP_RX_INVALID_PROTOCOL, /**< Rx invalid protocol. */
- NSS_STATS_GRE_SESSION_EXP_RX_NO_HEADROOM, /**< Rx no headroom. */
- NSS_STATS_GRE_SESSION_DEBUG_MAX, /**< Session debug max. */
-};
-
-/*
- * GRE session debug statistics
- */
-struct nss_stats_gre_session_debug {
- uint64_t stats[NSS_STATS_GRE_SESSION_DEBUG_MAX]; /**< Session debug statistics. */
- int32_t if_index; /**< Netdevice's ifindex. */
- uint32_t if_num; /**< NSS interface number. */
- bool valid; /**< Is node valid ? */
-};
-
-/*
- * MAP-T debug error types
- */
-enum nss_stats_map_t_instance {
- NSS_STATS_MAP_T_V4_TO_V6_PBUF_EXCEPTION,
- NSS_STATS_MAP_T_V4_TO_V6_PBUF_NO_MATCHING_RULE,
- NSS_STATS_MAP_T_V4_TO_V6_PBUF_NOT_TCP_OR_UDP,
- NSS_STATS_MAP_T_V4_TO_V6_RULE_ERR_LOCAL_PSID,
- NSS_STATS_MAP_T_V4_TO_V6_RULE_ERR_LOCAL_IPV6,
- NSS_STATS_MAP_T_V4_TO_V6_RULE_ERR_REMOTE_PSID,
- NSS_STATS_MAP_T_V4_TO_V6_RULE_ERR_REMOTE_EA_BITS,
- NSS_STATS_MAP_T_V4_TO_V6_RULE_ERR_REMOTE_IPV6,
- NSS_STATS_MAP_T_V6_TO_V4_PBUF_EXCEPTION,
- NSS_STATS_MAP_T_V6_TO_V4_PBUF_NO_MATCHING_RULE,
- NSS_STATS_MAP_T_V6_TO_V4_PBUF_NOT_TCP_OR_UDP,
- NSS_STATS_MAP_T_V6_TO_V4_RULE_ERR_LOCAL_IPV4,
- NSS_STATS_MAP_T_V6_TO_V4_RULE_ERR_REMOTE_IPV4,
- NSS_STATS_MAP_T_MAX
-};
-
-/*
- * Trustsec TX statistics
- */
-enum nss_stats_trustsec_tx {
- NSS_STATS_TRUSTSEC_TX_INVALID_SRC,
- /* Number of packets with invalid src if */
- NSS_STATS_TRUSTSEC_TX_UNCONFIGURED_SRC,
- /* Number of packets with unconfigured src if */
- NSS_STATS_IRUSTSEC_TX_HEADROOM_NOT_ENOUGH,
- /* Number of packets with not enough headroom */
- NSS_STATS_TRUSTSEC_TX_MAX
-};
-
-/*
- * NSS core stats -- for H2N/N2H map_t debug stats
- */
-struct nss_stats_map_t_instance_debug {
- uint64_t stats[NSS_STATS_MAP_T_MAX];
- int32_t if_index;
- uint32_t if_num; /* nss interface number */
- bool valid;
-};
-
-/*
- * Types of EDMA Tx ring stats
- */
-enum nss_stats_edma_tx_t {
- NSS_STATS_EDMA_TX_ERR,
- NSS_STATS_EDMA_TX_DROPPED,
- NSS_STATS_EDMA_TX_DESC,
- NSS_STATS_EDMA_TX_MAX
-};
-
-/*
- * Types of EDMA Rx ring stats
- */
-enum nss_stats_edma_rx_t {
- NSS_STATS_EDMA_RX_CSUM_ERR,
- NSS_STATS_EDMA_RX_DESC,
- NSS_STATS_EDMA_RX_QOS_ERR,
- NSS_STATS_EDMA_RX_MAX
-};
-
-/*
- * Types of EDMA Tx complete stats
- */
-enum nss_stats_edma_txcmpl_t {
- NSS_STATS_EDMA_TXCMPL_DESC,
- NSS_STATS_EDMA_TXCMPL_MAX
-};
-
-/*
- * Types of EDMA Rx fill stats
- */
-enum nss_stats_edma_rxfill_t {
- NSS_STATS_EDMA_RXFILL_DESC,
- NSS_STATS_EDMA_RXFILL_MAX
-};
-
-/*
- * Port to EDMA ring map
- */
-enum nss_edma_port_ring_map_t {
- NSS_EDMA_PORT_RX_RING,
- NSS_EDMA_PORT_TX_RING,
- NSS_EDMA_PORT_RING_MAP_MAX
-};
-
-/*
- * Types of EDMA ERROR STATS
- */
-enum nss_edma_err_t {
- NSS_EDMA_AXI_RD_ERR,
- NSS_EDMA_AXI_WR_ERR,
- NSS_EDMA_RX_DESC_FIFO_FULL_ERR,
- NSS_EDMA_RX_BUF_SIZE_ERR,
- NSS_EDMA_TX_SRAM_FULL_ERR,
- NSS_EDMA_TX_CMPL_BUF_FULL_ERR,
- NSS_EDMA_PKT_LEN_LA64K_ERR,
- NSS_EDMA_PKT_LEN_LE33_ERR,
- NSS_EDMA_DATA_LEN_ERR,
- NSS_EDMA_ALLOC_FAIL_CNT,
- NSS_EDMA_ERR_STATS_MAX
-};
-
-/*
- * NSS EDMA port stats
- */
-struct nss_edma_port_info {
- uint64_t port_stats[NSS_STATS_NODE_MAX];
- uint64_t port_type;
- uint64_t port_ring_map[NSS_EDMA_PORT_RING_MAP_MAX];
-};
-
-/*
- * NSS EDMA node statistics
- */
-struct nss_edma_stats {
- struct nss_edma_port_info port[NSS_EDMA_NUM_PORTS_MAX];
- uint64_t tx_stats[NSS_EDMA_NUM_TX_RING_MAX][NSS_STATS_EDMA_TX_MAX];
- uint64_t rx_stats[NSS_EDMA_NUM_RX_RING_MAX][NSS_STATS_EDMA_RX_MAX];
- uint64_t txcmpl_stats[NSS_EDMA_NUM_TXCMPL_RING_MAX][NSS_STATS_EDMA_TXCMPL_MAX];
- uint64_t rxfill_stats[NSS_EDMA_NUM_RXFILL_RING_MAX][NSS_STATS_EDMA_RXFILL_MAX];
- uint64_t misc_err[NSS_EDMA_ERR_STATS_MAX];
-};
-
-/*
* NSS core state
*/
enum nss_core_state {
@@ -1509,8 +464,6 @@
spinlock_t decongest_cb_lock; /* Lock to protect queue decongestion cb table */
uint16_t phys_if_mtu[NSS_MAX_PHYSICAL_INTERFACES];
/* Current MTU value of physical interface */
- uint64_t stats_n2h[NSS_STATS_N2H_MAX];
- /* N2H node stats: includes node, n2h, pbuf in this order */
uint32_t worker_thread_count; /* Number of NSS core worker threads for statistics */
uint32_t irq_count; /* Number of NSS core IRQs for statistics */
struct nss_worker_thread_stats *wt_stats;
@@ -1524,30 +477,6 @@
};
/*
- * NSS wifili stats
- */
-struct nss_wifili_stats {
- uint64_t stats_txrx[NSS_WIFILI_MAX_PDEV_NUM_MSG][NSS_STATS_WIFILI_TXRX_MAX];
- /* Number of txrx stats*/
- uint64_t stats_tcl_ring[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG][NSS_STATS_WIFILI_TCL_MAX];
- /* Tcl stats for each ring*/
- uint64_t stats_tx_comp[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG][NSS_STATS_WIFILI_TX_DESC_FREE_MAX];
- /* Tx comp ring stats*/
- uint64_t stats_tx_desc[NSS_WIFILI_MAX_TXDESC_POOLS_MSG][NSS_STATS_WIFILI_TX_DESC_MAX];
- /* Tx desc pool stats*/
- uint64_t stats_ext_tx_desc[NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG][NSS_STATS_WIFILI_EXT_TX_DESC_MAX];
- /* Tx ext desc pool stats*/
- uint64_t stats_reo[NSS_WIFILI_MAX_REO_DATA_RINGS_MSG][NSS_STATS_WIFILI_REO_MAX];
- /* Rx reo ring stats*/
- uint64_t stats_rx_desc[NSS_WIFILI_MAX_PDEV_NUM_MSG][NSS_STATS_WIFILI_RX_DESC_MAX];
- /* Rx rx sw pool stats*/
- uint64_t stats_rxdma[NSS_WIFILI_MAX_PDEV_NUM_MSG][NSS_STATS_WIFILI_RXDMA_DESC_MAX];
- /* Rx dma ring stats*/
- uint64_t stats_wbm[NSS_STATS_WIFILI_WBM_MAX];
- /* Wbm error ring stats*/
-};
-
-/*
* Main NSS context structure (singleton)
*/
struct nss_top_instance {
@@ -1559,43 +488,7 @@
struct mutex wq_lock; /* Mutex for NSS Work queue function */
struct dentry *top_dentry; /* Top dentry for nss */
struct dentry *stats_dentry; /* Top dentry for nss stats */
- struct dentry *ipv4_dentry; /* IPv4 stats dentry */
- struct dentry *ipv4_reasm_dentry;
- /* IPv4 reassembly stats dentry */
- struct dentry *ipv6_dentry; /* IPv6 stats dentry */
- struct dentry *ipv6_reasm_dentry;
- /* IPv6 reassembly stats dentry */
- struct dentry *eth_rx_dentry; /* ETH_RX stats dentry */
- struct dentry *n2h_dentry; /* N2H stats dentry */
- struct dentry *lso_rx_dentry; /* LSO_RX stats dentry */
- struct dentry *drv_dentry; /* HLOS driver stats dentry */
- struct dentry *pppoe_dentry; /* PPPOE stats dentry */
- struct dentry *pptp_dentry; /* PPTP stats dentry */
- struct dentry *l2tpv2_dentry; /* L2TPV2 stats dentry */
- struct dentry *dtls_dentry; /* DTLS stats dentry */
- struct dentry *gre_dentry; /* GRE stats dentry */
- struct dentry *gre_tunnel_dentry; /* GRE Tunnel stats dentry */
- struct dentry *map_t_dentry; /* MAP-T stats dentry */
- struct dentry *gmac_dentry; /* GMAC ethnode stats dentry */
- struct dentry *capwap_decap_dentry; /* CAPWAP decap ethnode stats dentry */
- struct dentry *capwap_encap_dentry; /* CAPWAP encap ethnode stats dentry */
- struct dentry *ppe_dentry; /* PPE root dentry */
- struct dentry *ppe_conn_dentry; /* PPE connection stats dentry */
- struct dentry *ppe_l3_dentry; /* PPE L3 debug stats dentry */
- struct dentry *ppe_code_dentry; /* PPE code stats dentry */
- struct dentry *gre_redir_dentry; /* gre_redir ethnode stats dentry */
- struct dentry *sjack_dentry; /* sjack stats dentry */
- struct dentry *trustsec_tx_dentry; /* trustsec tx stats dentry */
- struct dentry *portid_dentry; /* portid stats dentry */
- struct dentry *wifi_dentry; /* wifi stats dentry */
- struct dentry *logs_dentry; /* NSS FW logs directory */
- struct dentry *core_log_dentry; /* NSS Core's FW log file */
- struct dentry *wifi_if_dentry; /* wifi_if stats dentry */
- struct dentry *virt_if_dentry; /* virt_if stats dentry */
- struct dentry *tx_rx_virt_if_dentry; /* tx_rx_virt_if stats dentry. Will be deprecated soon */
- struct dentry *wifili_dentry; /* wifili stats dentry */
struct dentry *project_dentry; /* per-project stats dentry */
-
struct nss_ctx_instance nss[NSS_MAX_CORES];
/* NSS contexts */
/*
@@ -1714,44 +607,12 @@
/*
* Statistics for various interfaces
*/
- uint64_t stats_ipv4[NSS_STATS_IPV4_MAX];
- /* IPv4 statistics */
- uint64_t stats_ipv4_reasm[NSS_STATS_IPV4_REASM_MAX];
- /* IPv4 reasm statistics */
- uint64_t stats_ipv6[NSS_STATS_IPV6_MAX];
- /* IPv6 statistics */
- uint64_t stats_ipv6_reasm[NSS_STATS_IPV6_REASM_MAX];
- /* IPv6 reasm statistics */
- uint64_t stats_lso_rx[NSS_STATS_LSO_RX_MAX];
- /* LSO_RX statistics */
atomic64_t stats_drv[NSS_STATS_DRV_MAX];
/* Hlos driver statistics */
- uint64_t stats_pppoe[NSS_STATS_PPPOE_MAX];
- /* PPPoE statistics */
uint64_t stats_gmac[NSS_MAX_PHYSICAL_INTERFACES][NSS_STATS_GMAC_MAX];
/* GMAC statistics */
- uint64_t stats_wifi[NSS_MAX_WIFI_RADIO_INTERFACES][NSS_STATS_WIFI_MAX];
- /* WIFI statistics */
- uint64_t stats_eth_rx[NSS_STATS_ETH_RX_MAX];
- /* ETH_RX statistics */
uint64_t stats_node[NSS_MAX_NET_INTERFACES][NSS_STATS_NODE_MAX];
/* IPv4 statistics per interface */
- uint64_t stats_if_exception_eth_rx[NSS_EXCEPTION_EVENT_ETH_RX_MAX];
- /* Unknown protocol exception events per interface */
- uint64_t stats_if_exception_ipv4[NSS_EXCEPTION_EVENT_IPV4_MAX];
- /* IPv4 protocol exception events per interface */
- uint64_t stats_if_exception_ipv6[NSS_EXCEPTION_EVENT_IPV6_MAX];
- /* IPv6 protocol exception events per interface */
- uint64_t stats_if_exception_pppoe[NSS_MAX_PHYSICAL_INTERFACES + 1][NSS_PPPOE_NUM_SESSION_PER_INTERFACE + 1][NSS_PPPOE_EXCEPTION_EVENT_MAX];
- /* PPPoE exception events for per session on per interface. Interface and session indexes start with 1. */
- uint64_t stats_portid[NSS_STATS_PORTID_MAX];
- /* PortID statistics */
- struct nss_edma_stats stats_edma;
- /* EDMA node stats */
- uint64_t stats_trustsec_tx[NSS_STATS_TRUSTSEC_TX_MAX];
- /* Trustsec TX stats */
-
- struct nss_wifili_stats stats_wifili; /* Wifili stats*/
bool nss_hal_common_init_done;
uint16_t prev_mtu_sz; /* mtu sz needed as of now */
diff --git a/nss_dtls.c b/nss_dtls.c
index 6fcd88b..f6ec614 100644
--- a/nss_dtls.c
+++ b/nss_dtls.c
@@ -22,8 +22,8 @@
/*
* Data structures to store DTLS nss debug stats
*/
-static DEFINE_SPINLOCK(nss_dtls_session_debug_stats_lock);
-static struct nss_stats_dtls_session_debug nss_dtls_session_debug_stats[NSS_MAX_DTLS_SESSIONS];
+static DEFINE_SPINLOCK(nss_dtls_session_stats_lock);
+static struct nss_dtls_stats_session session_stats[NSS_MAX_DTLS_SESSIONS];
/*
* Private data structure
@@ -61,68 +61,68 @@
uint16_t if_num)
{
int i;
- struct nss_stats_dtls_session_debug *s = NULL;
+ struct nss_dtls_stats_session *s = NULL;
NSS_VERIFY_CTX_MAGIC(nss_ctx);
- spin_lock_bh(&nss_dtls_session_debug_stats_lock);
+ spin_lock_bh(&nss_dtls_session_stats_lock);
for (i = 0; i < NSS_MAX_DTLS_SESSIONS; i++) {
- if (nss_dtls_session_debug_stats[i].if_num != if_num) {
+ if (session_stats[i].if_num != if_num) {
continue;
}
- s = &nss_dtls_session_debug_stats[i];
+ s = &session_stats[i];
break;
}
if (!s) {
- spin_unlock_bh(&nss_dtls_session_debug_stats_lock);
+ spin_unlock_bh(&nss_dtls_session_stats_lock);
return;
}
- s->stats[NSS_STATS_DTLS_SESSION_RX_PKTS] += stats_msg->node_stats.rx_packets;
- s->stats[NSS_STATS_DTLS_SESSION_TX_PKTS] += stats_msg->node_stats.tx_packets;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_PKTS] += stats_msg->node_stats.rx_packets;
+ s->stats[NSS_DTLS_STATS_SESSION_TX_PKTS] += stats_msg->node_stats.tx_packets;
for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
- s->stats[NSS_STATS_DTLS_SESSION_RX_QUEUE_0_DROPPED + i] += stats_msg->node_stats.rx_dropped[i];
+ s->stats[NSS_DTLS_STATS_SESSION_RX_QUEUE_0_DROPPED + i] += stats_msg->node_stats.rx_dropped[i];
}
- s->stats[NSS_STATS_DTLS_SESSION_RX_AUTH_DONE] += stats_msg->rx_auth_done;
- s->stats[NSS_STATS_DTLS_SESSION_TX_AUTH_DONE] += stats_msg->tx_auth_done;
- s->stats[NSS_STATS_DTLS_SESSION_RX_CIPHER_DONE] += stats_msg->rx_cipher_done;
- s->stats[NSS_STATS_DTLS_SESSION_TX_CIPHER_DONE] += stats_msg->tx_cipher_done;
- s->stats[NSS_STATS_DTLS_SESSION_RX_CBUF_ALLOC_FAIL] += stats_msg->rx_cbuf_alloc_fail;
- s->stats[NSS_STATS_DTLS_SESSION_TX_CBUF_ALLOC_FAIL] += stats_msg->tx_cbuf_alloc_fail;
- s->stats[NSS_STATS_DTLS_SESSION_TX_CENQUEUE_FAIL] += stats_msg->tx_cenqueue_fail;
- s->stats[NSS_STATS_DTLS_SESSION_RX_CENQUEUE_FAIL] += stats_msg->rx_cenqueue_fail;
- s->stats[NSS_STATS_DTLS_SESSION_TX_DROPPED_HROOM] += stats_msg->tx_dropped_hroom;
- s->stats[NSS_STATS_DTLS_SESSION_TX_DROPPED_TROOM] += stats_msg->tx_dropped_troom;
- s->stats[NSS_STATS_DTLS_SESSION_TX_FORWARD_ENQUEUE_FAIL] += stats_msg->tx_forward_enqueue_fail;
- s->stats[NSS_STATS_DTLS_SESSION_RX_FORWARD_ENQUEUE_FAIL] += stats_msg->rx_forward_enqueue_fail;
- s->stats[NSS_STATS_DTLS_SESSION_RX_INVALID_VERSION] += stats_msg->rx_invalid_version;
- s->stats[NSS_STATS_DTLS_SESSION_RX_INVALID_EPOCH] += stats_msg->rx_invalid_epoch;
- s->stats[NSS_STATS_DTLS_SESSION_RX_MALFORMED] += stats_msg->rx_malformed;
- s->stats[NSS_STATS_DTLS_SESSION_RX_CIPHER_FAIL] += stats_msg->rx_cipher_fail;
- s->stats[NSS_STATS_DTLS_SESSION_RX_AUTH_FAIL] += stats_msg->rx_auth_fail;
- s->stats[NSS_STATS_DTLS_SESSION_RX_CAPWAP_CLASSIFY_FAIL] += stats_msg->rx_capwap_classify_fail;
- s->stats[NSS_STATS_DTLS_SESSION_RX_SINGLE_REC_DGRAM] += stats_msg->rx_single_rec_dgram;
- s->stats[NSS_STATS_DTLS_SESSION_RX_MULTI_REC_DGRAM] += stats_msg->rx_multi_rec_dgram;
- s->stats[NSS_STATS_DTLS_SESSION_RX_REPLAY_FAIL] += stats_msg->rx_replay_fail;
- s->stats[NSS_STATS_DTLS_SESSION_RX_REPLAY_DUPLICATE] += stats_msg->rx_replay_duplicate;
- s->stats[NSS_STATS_DTLS_SESSION_RX_REPLAY_OUT_OF_WINDOW] += stats_msg->rx_replay_out_of_window;
- s->stats[NSS_STATS_DTLS_SESSION_OUTFLOW_QUEUE_FULL] += stats_msg->outflow_queue_full;
- s->stats[NSS_STATS_DTLS_SESSION_DECAP_QUEUE_FULL] += stats_msg->decap_queue_full;
- s->stats[NSS_STATS_DTLS_SESSION_PBUF_ALLOC_FAIL] += stats_msg->pbuf_alloc_fail;
- s->stats[NSS_STATS_DTLS_SESSION_PBUF_COPY_FAIL] += stats_msg->pbuf_copy_fail;
- s->stats[NSS_STATS_DTLS_SESSION_EPOCH] = stats_msg->epoch;
- s->stats[NSS_STATS_DTLS_SESSION_TX_SEQ_HIGH] = stats_msg->tx_seq_high;
- s->stats[NSS_STATS_DTLS_SESSION_TX_SEQ_LOW] = stats_msg->tx_seq_low;
- spin_unlock_bh(&nss_dtls_session_debug_stats_lock);
+ s->stats[NSS_DTLS_STATS_SESSION_RX_AUTH_DONE] += stats_msg->rx_auth_done;
+ s->stats[NSS_DTLS_STATS_SESSION_TX_AUTH_DONE] += stats_msg->tx_auth_done;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_CIPHER_DONE] += stats_msg->rx_cipher_done;
+ s->stats[NSS_DTLS_STATS_SESSION_TX_CIPHER_DONE] += stats_msg->tx_cipher_done;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_CBUF_ALLOC_FAIL] += stats_msg->rx_cbuf_alloc_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_TX_CBUF_ALLOC_FAIL] += stats_msg->tx_cbuf_alloc_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_TX_CENQUEUE_FAIL] += stats_msg->tx_cenqueue_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_CENQUEUE_FAIL] += stats_msg->rx_cenqueue_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_TX_DROPPED_HROOM] += stats_msg->tx_dropped_hroom;
+ s->stats[NSS_DTLS_STATS_SESSION_TX_DROPPED_TROOM] += stats_msg->tx_dropped_troom;
+ s->stats[NSS_DTLS_STATS_SESSION_TX_FORWARD_ENQUEUE_FAIL] += stats_msg->tx_forward_enqueue_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_FORWARD_ENQUEUE_FAIL] += stats_msg->rx_forward_enqueue_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_INVALID_VERSION] += stats_msg->rx_invalid_version;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_INVALID_EPOCH] += stats_msg->rx_invalid_epoch;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_MALFORMED] += stats_msg->rx_malformed;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_CIPHER_FAIL] += stats_msg->rx_cipher_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_AUTH_FAIL] += stats_msg->rx_auth_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_CAPWAP_CLASSIFY_FAIL] += stats_msg->rx_capwap_classify_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_SINGLE_REC_DGRAM] += stats_msg->rx_single_rec_dgram;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_MULTI_REC_DGRAM] += stats_msg->rx_multi_rec_dgram;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_REPLAY_FAIL] += stats_msg->rx_replay_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_REPLAY_DUPLICATE] += stats_msg->rx_replay_duplicate;
+ s->stats[NSS_DTLS_STATS_SESSION_RX_REPLAY_OUT_OF_WINDOW] += stats_msg->rx_replay_out_of_window;
+ s->stats[NSS_DTLS_STATS_SESSION_OUTFLOW_QUEUE_FULL] += stats_msg->outflow_queue_full;
+ s->stats[NSS_DTLS_STATS_SESSION_DECAP_QUEUE_FULL] += stats_msg->decap_queue_full;
+ s->stats[NSS_DTLS_STATS_SESSION_PBUF_ALLOC_FAIL] += stats_msg->pbuf_alloc_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_PBUF_COPY_FAIL] += stats_msg->pbuf_copy_fail;
+ s->stats[NSS_DTLS_STATS_SESSION_EPOCH] = stats_msg->epoch;
+ s->stats[NSS_DTLS_STATS_SESSION_TX_SEQ_HIGH] = stats_msg->tx_seq_high;
+ s->stats[NSS_DTLS_STATS_SESSION_TX_SEQ_LOW] = stats_msg->tx_seq_low;
+ spin_unlock_bh(&nss_dtls_session_stats_lock);
}
/*
- * nss_dtls_session_debug_stats_get()
+ * nss_dtls_session_stats_get()
* Get session DTLS statitics.
*/
-void nss_dtls_session_debug_stats_get(struct nss_stats_dtls_session_debug *stats)
+void nss_dtls_session_stats_get(struct nss_dtls_stats_session *stats)
{
int i;
@@ -131,15 +131,15 @@
return;
}
- spin_lock_bh(&nss_dtls_session_debug_stats_lock);
+ spin_lock_bh(&nss_dtls_session_stats_lock);
for (i = 0; i < NSS_MAX_DTLS_SESSIONS; i++) {
- if (nss_dtls_session_debug_stats[i].valid) {
- memcpy(stats, &nss_dtls_session_debug_stats[i],
- sizeof(struct nss_stats_dtls_session_debug));
+ if (session_stats[i].valid) {
+ memcpy(stats, &session_stats[i],
+ sizeof(struct nss_dtls_stats_session));
stats++;
}
}
- spin_unlock_bh(&nss_dtls_session_debug_stats_lock);
+ spin_unlock_bh(&nss_dtls_session_stats_lock);
}
/*
@@ -410,16 +410,16 @@
BUG_ON(!nss_dtls_verify_if_num(if_num));
- spin_lock_bh(&nss_dtls_session_debug_stats_lock);
+ spin_lock_bh(&nss_dtls_session_stats_lock);
for (i = 0; i < NSS_MAX_DTLS_SESSIONS; i++) {
- if (!nss_dtls_session_debug_stats[i].valid) {
- nss_dtls_session_debug_stats[i].valid = true;
- nss_dtls_session_debug_stats[i].if_num = if_num;
- nss_dtls_session_debug_stats[i].if_index = netdev->ifindex;
+ if (!session_stats[i].valid) {
+ session_stats[i].valid = true;
+ session_stats[i].if_num = if_num;
+ session_stats[i].if_index = netdev->ifindex;
break;
}
}
- spin_unlock_bh(&nss_dtls_session_debug_stats_lock);
+ spin_unlock_bh(&nss_dtls_session_stats_lock);
if (i == NSS_MAX_DTLS_SESSIONS) {
nss_warning("%p: Cannot find free slot for "
@@ -453,15 +453,15 @@
BUG_ON(!nss_dtls_verify_if_num(if_num));
- spin_lock_bh(&nss_dtls_session_debug_stats_lock);
+ spin_lock_bh(&nss_dtls_session_stats_lock);
for (i = 0; i < NSS_MAX_DTLS_SESSIONS; i++) {
- if (nss_dtls_session_debug_stats[i].if_num == if_num) {
- memset(&nss_dtls_session_debug_stats[i], 0,
- sizeof(struct nss_stats_dtls_session_debug));
+ if (session_stats[i].if_num == if_num) {
+ memset(&session_stats[i], 0,
+ sizeof(struct nss_dtls_stats_session));
break;
}
}
- spin_unlock_bh(&nss_dtls_session_debug_stats_lock);
+ spin_unlock_bh(&nss_dtls_session_stats_lock);
if (i == NSS_MAX_DTLS_SESSIONS) {
nss_warning("%p: Cannot find debug stats for DTLS session %d\n", nss_ctx, if_num);
@@ -520,4 +520,6 @@
{
sema_init(&dtls_pvt.sem, 1);
init_completion(&dtls_pvt.complete);
+
+ nss_dtls_stats_dentry_create();
}
diff --git a/nss_dtls_stats.c b/nss_dtls_stats.c
new file mode 100644
index 0000000..a15e716
--- /dev/null
+++ b/nss_dtls_stats.c
@@ -0,0 +1,150 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_dtls_stats.h"
+
+/*
+ * nss_dtls_stats_session_str
+ * DTLS statistics strings for nss session stats
+ */
+static int8_t *nss_dtls_stats_session_str[NSS_DTLS_STATS_SESSION_MAX] = {
+ "RX_PKTS",
+ "TX_PKTS",
+ "RX_DROPPED",
+ "RX_AUTH_DONE",
+ "TX_AUTH_DONE",
+ "RX_CIPHER_DONE",
+ "TX_CIPHER_DONE",
+ "RX_CBUF_ALLOC_FAIL",
+ "TX_CBUF_ALLOC_FAIL",
+ "TX_CENQUEUE_FAIL",
+ "RX_CENQUEUE_FAIL",
+ "TX_DROPPED_HROOM",
+ "TX_DROPPED_TROOM",
+ "TX_FORWARD_ENQUEUE_FAIL",
+ "RX_FORWARD_ENQUEUE_FAIL",
+ "RX_INVALID_VERSION",
+ "RX_INVALID_EPOCH",
+ "RX_MALFORMED",
+ "RX_CIPHER_FAIL",
+ "RX_AUTH_FAIL",
+ "RX_CAPWAP_CLASSIFY_FAIL",
+ "RX_SINGLE_REC_DGRAM",
+ "RX_MULTI_REC_DGRAM",
+ "RX_REPLAY_FAIL",
+ "RX_REPLAY_DUPLICATE",
+ "RX_REPLAY_OUT_OF_WINDOW",
+ "OUTFLOW_QUEUE_FULL",
+ "DECAP_QUEUE_FULL",
+ "PBUF_ALLOC_FAIL",
+ "PBUF_COPY_FAIL",
+ "EPOCH",
+ "TX_SEQ_HIGH",
+ "TX_SEQ_LOW",
+};
+
+/*
+ * nss_dtls_stats_read()
+ * Read DTLS session statistics
+ */
+static ssize_t nss_dtls_stats_read(struct file *fp, char __user *ubuf,
+ size_t sz, loff_t *ppos)
+{
+ uint32_t max_output_lines = 2 + (NSS_MAX_DTLS_SESSIONS
+ * (NSS_DTLS_STATS_SESSION_MAX + 2)) + 2;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ struct net_device *dev;
+ int id, i;
+ struct nss_dtls_stats_session *dtls_session_stats = NULL;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ dtls_session_stats = kzalloc((sizeof(struct nss_dtls_stats_session)
+ * NSS_MAX_DTLS_SESSIONS), GFP_KERNEL);
+ if (unlikely(dtls_session_stats == NULL)) {
+ nss_warning("Could not allocate memory for populating DTLS stats");
+ kfree(lbuf);
+ return 0;
+ }
+
+ /*
+ * Get all stats
+ */
+ nss_dtls_session_stats_get(dtls_session_stats);
+
+ /*
+ * Session stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\nDTLS session stats start:\n\n");
+
+ for (id = 0; id < NSS_MAX_DTLS_SESSIONS; id++) {
+ if (!dtls_session_stats[id].valid)
+ break;
+
+ dev = dev_get_by_index(&init_net, dtls_session_stats[id].if_index);
+ if (likely(dev)) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%d. nss interface id=%d, netdevice=%s\n",
+ id, dtls_session_stats[id].if_num,
+ dev->name);
+ dev_put(dev);
+ } else {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%d. nss interface id=%d\n", id,
+ dtls_session_stats[id].if_num);
+ }
+
+ for (i = 0; i < NSS_DTLS_STATS_SESSION_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %llu\n",
+ nss_dtls_stats_session_str[i],
+ dtls_session_stats[id].stats[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\nDTLS session stats end\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
+
+ kfree(dtls_session_stats);
+ kfree(lbuf);
+ return bytes_read;
+}
+
+/*
+ * nss_dtls_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(dtls)
+
+/*
+ * nss_dtls_stats_dentry_create()
+ * Create DTLS statistics debug entry.
+ */
+void nss_dtls_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("dtls", &nss_dtls_stats_ops);
+}
diff --git a/nss_dtls_stats.h b/nss_dtls_stats.h
index e8da83a..bf6a148 100644
--- a/nss_dtls_stats.h
+++ b/nss_dtls_stats.h
@@ -1,6 +1,6 @@
/*
******************************************************************************
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -14,87 +14,89 @@
* ****************************************************************************
*/
+#ifndef __NSS_DTLS_STATS_H
+#define __NSS_DTLS_STATS_H
+
/*
* DTLS session debug statistic counters
*/
-enum nss_stats_dtls_session {
- NSS_STATS_DTLS_SESSION_RX_PKTS,
+enum nss_dtls_stats_session_types {
+ NSS_DTLS_STATS_SESSION_RX_PKTS,
/* Rx packets */
- NSS_STATS_DTLS_SESSION_TX_PKTS,
+ NSS_DTLS_STATS_SESSION_TX_PKTS,
/* Tx packets */
- NSS_STATS_DTLS_SESSION_RX_QUEUE_0_DROPPED,
- NSS_STATS_DTLS_SESSION_RX_QUEUE_1_DROPPED,
- NSS_STATS_DTLS_SESSION_RX_QUEUE_2_DROPPED,
- NSS_STATS_DTLS_SESSION_RX_QUEUE_3_DROPPED,
- /* Rx dropped */
- NSS_STATS_DTLS_SESSION_RX_AUTH_DONE,
+ NSS_DTLS_STATS_SESSION_RX_QUEUE_0_DROPPED,
+ NSS_DTLS_STATS_SESSION_RX_QUEUE_1_DROPPED,
+ NSS_DTLS_STATS_SESSION_RX_QUEUE_2_DROPPED,
+ NSS_DTLS_STATS_SESSION_RX_QUEUE_3_DROPPED,
+ NSS_DTLS_STATS_SESSION_RX_AUTH_DONE,
/* Rx successful authentication */
- NSS_STATS_DTLS_SESSION_TX_AUTH_DONE,
+ NSS_DTLS_STATS_SESSION_TX_AUTH_DONE,
/* Tx authentication done */
- NSS_STATS_DTLS_SESSION_RX_CIPHER_DONE,
+ NSS_DTLS_STATS_SESSION_RX_CIPHER_DONE,
/* Rx cipher done */
- NSS_STATS_DTLS_SESSION_TX_CIPHER_DONE,
+ NSS_DTLS_STATS_SESSION_TX_CIPHER_DONE,
/* Tx cipher done */
- NSS_STATS_DTLS_SESSION_RX_CBUF_ALLOC_FAIL,
+ NSS_DTLS_STATS_SESSION_RX_CBUF_ALLOC_FAIL,
/* Rx crypto buffer alloc fail */
- NSS_STATS_DTLS_SESSION_TX_CBUF_ALLOC_FAIL,
+ NSS_DTLS_STATS_SESSION_TX_CBUF_ALLOC_FAIL,
/* Tx crypto buffer alloc fail */
- NSS_STATS_DTLS_SESSION_TX_CENQUEUE_FAIL,
+ NSS_DTLS_STATS_SESSION_TX_CENQUEUE_FAIL,
/* Tx enqueue to crypto fail */
- NSS_STATS_DTLS_SESSION_RX_CENQUEUE_FAIL,
+ NSS_DTLS_STATS_SESSION_RX_CENQUEUE_FAIL,
/* Rx enqueue to crypto fail */
- NSS_STATS_DTLS_SESSION_TX_DROPPED_HROOM,
+ NSS_DTLS_STATS_SESSION_TX_DROPPED_HROOM,
/* Tx drop due to insufficient headroom */
- NSS_STATS_DTLS_SESSION_TX_DROPPED_TROOM,
+ NSS_DTLS_STATS_SESSION_TX_DROPPED_TROOM,
/* Tx drop due to insufficient tailroom */
- NSS_STATS_DTLS_SESSION_TX_FORWARD_ENQUEUE_FAIL,
+ NSS_DTLS_STATS_SESSION_TX_FORWARD_ENQUEUE_FAIL,
/* Enqueue failed to Tx node after encap */
- NSS_STATS_DTLS_SESSION_RX_FORWARD_ENQUEUE_FAIL,
+ NSS_DTLS_STATS_SESSION_RX_FORWARD_ENQUEUE_FAIL,
/* Enqueue failed to Rx node after decap */
- NSS_STATS_DTLS_SESSION_RX_INVALID_VERSION,
+ NSS_DTLS_STATS_SESSION_RX_INVALID_VERSION,
/* Rx invalid DTLS version */
- NSS_STATS_DTLS_SESSION_RX_INVALID_EPOCH,
+ NSS_DTLS_STATS_SESSION_RX_INVALID_EPOCH,
/* Rx invalid DTLS epoch */
- NSS_STATS_DTLS_SESSION_RX_MALFORMED,
+ NSS_DTLS_STATS_SESSION_RX_MALFORMED,
/* Rx malformed DTLS record */
- NSS_STATS_DTLS_SESSION_RX_CIPHER_FAIL,
+ NSS_DTLS_STATS_SESSION_RX_CIPHER_FAIL,
/* Rx cipher fail */
- NSS_STATS_DTLS_SESSION_RX_AUTH_FAIL,
+ NSS_DTLS_STATS_SESSION_RX_AUTH_FAIL,
/* Rx authentication fail */
- NSS_STATS_DTLS_SESSION_RX_CAPWAP_CLASSIFY_FAIL,
+ NSS_DTLS_STATS_SESSION_RX_CAPWAP_CLASSIFY_FAIL,
/* Rx CAPWAP classification fail */
- NSS_STATS_DTLS_SESSION_RX_SINGLE_REC_DGRAM,
+ NSS_DTLS_STATS_SESSION_RX_SINGLE_REC_DGRAM,
/* Rx single record datagrams processed */
- NSS_STATS_DTLS_SESSION_RX_MULTI_REC_DGRAM,
+ NSS_DTLS_STATS_SESSION_RX_MULTI_REC_DGRAM,
/* Rx multi record datagrams processed */
- NSS_STATS_DTLS_SESSION_RX_REPLAY_FAIL,
+ NSS_DTLS_STATS_SESSION_RX_REPLAY_FAIL,
/* Rx anti-replay failures */
- NSS_STATS_DTLS_SESSION_RX_REPLAY_DUPLICATE,
+ NSS_DTLS_STATS_SESSION_RX_REPLAY_DUPLICATE,
/* Rx anti-replay fail due to duplicate record */
- NSS_STATS_DTLS_SESSION_RX_REPLAY_OUT_OF_WINDOW,
+ NSS_DTLS_STATS_SESSION_RX_REPLAY_OUT_OF_WINDOW,
/* Rx anti-replay fail due to out of window record */
- NSS_STATS_DTLS_SESSION_OUTFLOW_QUEUE_FULL,
+ NSS_DTLS_STATS_SESSION_OUTFLOW_QUEUE_FULL,
/* Tx drop due to encap queue full */
- NSS_STATS_DTLS_SESSION_DECAP_QUEUE_FULL,
+ NSS_DTLS_STATS_SESSION_DECAP_QUEUE_FULL,
/* Rx drop due to decap queue full */
- NSS_STATS_DTLS_SESSION_PBUF_ALLOC_FAIL,
+ NSS_DTLS_STATS_SESSION_PBUF_ALLOC_FAIL,
/* Drops due to buffer allocation failure */
- NSS_STATS_DTLS_SESSION_PBUF_COPY_FAIL,
+ NSS_DTLS_STATS_SESSION_PBUF_COPY_FAIL,
/* Drops due to buffer copy failure */
- NSS_STATS_DTLS_SESSION_EPOCH,
+ NSS_DTLS_STATS_SESSION_EPOCH,
/* Current Epoch */
- NSS_STATS_DTLS_SESSION_TX_SEQ_HIGH,
+ NSS_DTLS_STATS_SESSION_TX_SEQ_HIGH,
/* Upper 16-bits of current sequence number */
- NSS_STATS_DTLS_SESSION_TX_SEQ_LOW,
+ NSS_DTLS_STATS_SESSION_TX_SEQ_LOW,
/* Lower 32-bits of current sequence number */
- NSS_STATS_DTLS_SESSION_MAX,
+ NSS_DTLS_STATS_SESSION_MAX,
};
/*
- * DTLS session debug statistics
+ * DTLS session statistics
*/
-struct nss_stats_dtls_session_debug {
- uint64_t stats[NSS_STATS_DTLS_SESSION_MAX];
+struct nss_dtls_stats_session {
+ uint64_t stats[NSS_DTLS_STATS_SESSION_MAX];
int32_t if_index;
uint32_t if_num; /* nss interface number */
bool valid;
@@ -103,4 +105,11 @@
/*
* Stats APIs provided by nss_dtls.c
*/
-extern void nss_dtls_session_debug_stats_get(struct nss_stats_dtls_session_debug *s);
+extern void nss_dtls_session_stats_get(struct nss_dtls_stats_session *s);
+
+/*
+ * DTLS statistics APIs
+ */
+extern void nss_dtls_stats_dentry_create(void);
+
+#endif /* __NSS_DTLS_STATS_H */
diff --git a/nss_edma.c b/nss_edma.c
index bfcca62..0abb48e 100644
--- a/nss_edma.c
+++ b/nss_edma.c
@@ -20,6 +20,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_edma_stats.h"
/*
**********************************
@@ -28,110 +29,6 @@
*/
/*
- * nss_edma_metadata_port_stats_sync()
- * Handle the syncing of EDMA port statistics.
- */
-static void nss_edma_metadata_port_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_port_stats_sync *nepss)
-{
- int i;
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
-
- spin_lock_bh(&nss_top->stats_lock);
-
- /*
- * edma port stats
- * We process a subset of port stats since msg payload is not enough to hold all ports at once.
- */
- for (i = nepss->start_port; i < nepss->end_port; i++) {
- int k;
-
- nss_top->stats_edma.port[i].port_stats[NSS_STATS_NODE_RX_PKTS] += nepss->port_stats[i].node_stats.rx_packets;
- nss_top->stats_edma.port[i].port_stats[NSS_STATS_NODE_RX_BYTES] += nepss->port_stats[i].node_stats.rx_bytes;
- nss_top->stats_edma.port[i].port_stats[NSS_STATS_NODE_TX_PKTS] += nepss->port_stats[i].node_stats.tx_packets;
- nss_top->stats_edma.port[i].port_stats[NSS_STATS_NODE_TX_BYTES] += nepss->port_stats[i].node_stats.tx_bytes;
-
- for (k = 0; k < NSS_MAX_NUM_PRI; k++) {
- nss_top->stats_edma.port[i].port_stats[NSS_STATS_NODE_RX_QUEUE_0_DROPPED + k] += nepss->port_stats[i].node_stats.rx_dropped[k];
- }
-
- nss_top->stats_edma.port[i].port_type = nepss->port_stats[i].port_type;
- nss_top->stats_edma.port[i].port_ring_map[NSS_EDMA_PORT_RX_RING] = nepss->port_stats[i].edma_rx_ring;
- nss_top->stats_edma.port[i].port_ring_map[NSS_EDMA_PORT_TX_RING] = nepss->port_stats[i].edma_tx_ring;
- }
-
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
- * nss_edma_metadata_ring_stats_sync()
- * Handle the syncing of EDMA ring statistics.
- */
-static void nss_edma_metadata_ring_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_ring_stats_sync *nerss)
-{
- int i;
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
-
- spin_lock_bh(&nss_top->stats_lock);
-
- /*
- * edma tx ring stats
- */
- for (i = 0; i < NSS_EDMA_NUM_TX_RING_MAX; i++) {
- nss_top->stats_edma.tx_stats[i][NSS_STATS_EDMA_TX_ERR] += nerss->tx_ring[i].tx_err;
- nss_top->stats_edma.tx_stats[i][NSS_STATS_EDMA_TX_DROPPED] += nerss->tx_ring[i].tx_dropped;
- nss_top->stats_edma.tx_stats[i][NSS_STATS_EDMA_TX_DESC] += nerss->tx_ring[i].desc_cnt;
- }
-
- /*
- * edma rx ring stats
- */
- for (i = 0; i < NSS_EDMA_NUM_RX_RING_MAX; i++) {
- nss_top->stats_edma.rx_stats[i][NSS_STATS_EDMA_RX_CSUM_ERR] += nerss->rx_ring[i].rx_csum_err;
- nss_top->stats_edma.rx_stats[i][NSS_STATS_EDMA_RX_DESC] += nerss->rx_ring[i].desc_cnt;
- nss_top->stats_edma.rx_stats[i][NSS_STATS_EDMA_RX_QOS_ERR] += nerss->rx_ring[i].qos_err;
- }
-
- /*
- * edma tx cmpl ring stats
- */
- for (i = 0; i < NSS_EDMA_NUM_TXCMPL_RING_MAX; i++) {
- nss_top->stats_edma.txcmpl_stats[i][NSS_STATS_EDMA_TXCMPL_DESC] += nerss->txcmpl_ring[i].desc_cnt;
- }
-
- /*
- * edma rx fill ring stats
- */
- for (i = 0; i < NSS_EDMA_NUM_RXFILL_RING_MAX; i++) {
- nss_top->stats_edma.rxfill_stats[i][NSS_STATS_EDMA_RXFILL_DESC] += nerss->rxfill_ring[i].desc_cnt;
- }
-
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
- * nss_edma_metadata_err_stats_sync()
- * Handle the syncing of EDMA error statistics.
- */
-static void nss_edma_metadata_err_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_err_stats_sync *nerss)
-{
-
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
-
- spin_lock_bh(&nss_top->stats_lock);
- nss_top->stats_edma.misc_err[NSS_EDMA_AXI_RD_ERR] += nerss->msg_err_stats.axi_rd_err;
- nss_top->stats_edma.misc_err[NSS_EDMA_AXI_WR_ERR] += nerss->msg_err_stats.axi_wr_err;
- nss_top->stats_edma.misc_err[NSS_EDMA_RX_DESC_FIFO_FULL_ERR] += nerss->msg_err_stats.rx_desc_fifo_full_err;
- nss_top->stats_edma.misc_err[NSS_EDMA_RX_BUF_SIZE_ERR] += nerss->msg_err_stats.rx_buf_size_err;
- nss_top->stats_edma.misc_err[NSS_EDMA_TX_SRAM_FULL_ERR] += nerss->msg_err_stats.tx_sram_full_err;
- nss_top->stats_edma.misc_err[NSS_EDMA_TX_CMPL_BUF_FULL_ERR] += nerss->msg_err_stats.tx_cmpl_buf_full_err;
- nss_top->stats_edma.misc_err[NSS_EDMA_PKT_LEN_LA64K_ERR] += nerss->msg_err_stats.pkt_len_la64k_err;
- nss_top->stats_edma.misc_err[NSS_EDMA_PKT_LEN_LE33_ERR] += nerss->msg_err_stats.pkt_len_le33_err;
- nss_top->stats_edma.misc_err[NSS_EDMA_DATA_LEN_ERR] += nerss->msg_err_stats.data_len_err;
- nss_top->stats_edma.misc_err[NSS_EDMA_ALLOC_FAIL_CNT] += nerss->msg_err_stats.alloc_fail_cnt;
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
* nss_edma_interface_handler()
* Handle NSS -> HLOS messages for EDMA node
*/
@@ -233,4 +130,6 @@
struct nss_ctx_instance *nss_ctx = nss_edma_get_context();
nss_core_register_handler(nss_ctx, NSS_EDMA_INTERFACE, nss_edma_interface_handler, NULL);
+
+ nss_edma_stats_dentry_create();
}
diff --git a/nss_edma_stats.c b/nss_edma_stats.c
new file mode 100644
index 0000000..23cca5b
--- /dev/null
+++ b/nss_edma_stats.c
@@ -0,0 +1,882 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_edma_stats.c
+ * NSS EDMA statistics APIs
+ */
+
+#include "nss_stats.h"
+#include "nss_tx_rx_common.h"
+#include "nss_edma_stats.h"
+
+struct nss_edma_stats edma_stats;
+
+/*
+ * nss_edma_stats_str_node
+ */
+static int8_t *nss_edma_stats_str_node[NSS_STATS_NODE_MAX] = {
+ "rx_packets",
+ "rx_bytes",
+ "tx_packets",
+ "tx_bytes",
+ "rx_queue_0_dropped",
+ "rx_queue_1_dropped",
+ "rx_queue_2_dropped",
+ "rx_queue_3_dropped",
+};
+
+/*
+ * nss_edma_stats_str_tx
+ */
+static int8_t *nss_edma_stats_str_tx[NSS_EDMA_STATS_TX_MAX] = {
+ "tx_err",
+ "tx_dropped",
+ "desc_cnt"
+};
+
+/*
+ * nss_edma_stats_str_rx
+ */
+static int8_t *nss_edma_stats_str_rx[NSS_EDMA_STATS_RX_MAX] = {
+ "rx_csum_err",
+ "desc_cnt",
+ "qos_err"
+};
+
+/*
+ * nss_edma_stats_str_txcmpl
+ */
+static int8_t *nss_edma_stats_str_txcmpl[NSS_EDMA_STATS_TXCMPL_MAX] = {
+ "desc_cnt"
+};
+
+/*
+ * nss_edma_stats_str_rxfill
+ */
+static int8_t *nss_edma_stats_str_rxfill[NSS_EDMA_STATS_RXFILL_MAX] = {
+ "desc_cnt"
+};
+
+/*
+ * nss_edma_stats_str_port_type
+ */
+static int8_t *nss_edma_stats_str_port_type[NSS_EDMA_PORT_TYPE_MAX] = {
+ "physical_port",
+ "virtual_port"
+};
+
+/*
+ * nss_edma_stats_str_port_ring_map
+ */
+static int8_t *nss_edma_stats_str_port_ring_map[NSS_EDMA_PORT_RING_MAP_MAX] = {
+ "rx_ring",
+ "tx_ring"
+};
+
+/*
+ * nss_edma_stats_str_err_map
+ */
+static int8_t *nss_edma_stats_str_err_map[NSS_EDMA_ERR_STATS_MAX] = {
+ "axi_rd_err",
+ "axi_wr_err",
+ "rx_desc_fifo_full_err",
+ "rx_buf_size_err",
+ "tx_sram_full_err",
+ "tx_cmpl_buf_full_err",
+ "pkt_len_la64k_err",
+ "pkt_len_le33_err",
+ "data_len_err",
+ "alloc_fail_cnt"
+};
+
+/*
+ **********************************
+ EDMA statistics APIs
+ **********************************
+ */
+
+/*
+ * nss_edma_port_stats_read()
+ * Read EDMA port statistics
+ */
+static ssize_t nss_edma_port_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + 3;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+ struct nss_stats_data *data = fp->private_data;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ /*
+ * Note: The assumption here is that we do not have more than 64 stats
+ */
+ stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "edma stats start:\n\n");
+
+ /*
+ * Common node stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "edma port %d stats:\n\n", data->edma_id);
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
+ stats_shadow[i] = edma_stats.port[data->edma_id].port_stats[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_edma_stats_str_node[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_edma_port_type_stats_read()
+ * Read EDMA port type
+ */
+static ssize_t nss_edma_port_type_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (1 + 2) + 3;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t port_type;
+ struct nss_stats_data *data = fp->private_data;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "edma port type start:\n\n");
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "edma port %d type:\n\n", data->edma_id);
+
+ /*
+ * Port type
+ */
+ spin_lock_bh(&nss_top_main.stats_lock);
+ port_type = edma_stats.port[data->edma_id].port_type;
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "port_type = %s\n", nss_edma_stats_str_port_type[port_type]);
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma stats end\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+
+ return bytes_read;
+}
+
+/*
+ * nss_edma_port_ring_map_stats_read()
+ * Read EDMA port ring map
+ */
+static ssize_t nss_edma_port_ring_map_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (4 + 2) + 3;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+ struct nss_stats_data *data = fp->private_data;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ /*
+ * Note: The assumption here is that we do not have more than 64 stats
+ */
+ stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "edma port ring map start:\n\n");
+
+ /*
+ * Port ring map
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "edma port %d ring map:\n\n", data->edma_id);
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; i < NSS_EDMA_PORT_RING_MAP_MAX; i++) {
+ stats_shadow[i] = edma_stats.port[data->edma_id].port_ring_map[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; i < NSS_EDMA_PORT_RING_MAP_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_edma_stats_str_port_ring_map[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_edma_txring_stats_read()
+ * Read EDMA Tx ring stats
+ */
+static ssize_t nss_edma_txring_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_EDMA_STATS_TX_MAX + 2) + 3;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+ struct nss_stats_data *data = fp->private_data;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ /*
+ * Note: The assumption here is that we do not have more than 64 stats
+ */
+ stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "edma Tx ring stats start:\n\n");
+
+ /*
+ * Tx ring stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Tx ring %d stats:\n\n", data->edma_id);
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; i < NSS_EDMA_STATS_TX_MAX; i++) {
+ stats_shadow[i] = edma_stats.tx_stats[data->edma_id][i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; i < NSS_EDMA_STATS_TX_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_edma_stats_str_tx[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma Tx ring stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_edma_rxring_stats_read()
+ * Read EDMA rxring stats
+ */
+static ssize_t nss_edma_rxring_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_EDMA_STATS_RX_MAX + 2) + 3;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+ struct nss_stats_data *data = fp->private_data;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ /*
+ * Note: The assumption here is that we do not have more than 64 stats
+ */
+ stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "edma Rx ring stats start:\n\n");
+
+ /*
+ * RX ring stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Rx ring %d stats:\n\n", data->edma_id);
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; i < NSS_EDMA_STATS_RX_MAX; i++) {
+ stats_shadow[i] = edma_stats.rx_stats[data->edma_id][i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; i < NSS_EDMA_STATS_RX_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_edma_stats_str_rx[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma Rx ring stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_edma_txcmplring_stats_read()
+ * Read EDMA txcmplring stats
+ */
+static ssize_t nss_edma_txcmplring_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_EDMA_STATS_TXCMPL_MAX + 2) + 3;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+ struct nss_stats_data *data = fp->private_data;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ /*
+ * Note: The assumption here is that we do not have more than 64 stats
+ */
+ stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "edma Tx cmpl ring stats start:\n\n");
+
+ /*
+ * Tx cmpl ring stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Tx cmpl ring %d stats:\n\n", data->edma_id);
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; i < NSS_EDMA_STATS_TXCMPL_MAX; i++) {
+ stats_shadow[i] = edma_stats.txcmpl_stats[data->edma_id][i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; i < NSS_EDMA_STATS_TXCMPL_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_edma_stats_str_txcmpl[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma Tx cmpl ring stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_edma_rxfillring_stats_read()
+ * Read EDMA rxfillring stats
+ */
+static ssize_t nss_edma_rxfillring_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_EDMA_STATS_RXFILL_MAX + 2) + 3;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+ struct nss_stats_data *data = fp->private_data;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ /*
+ * Note: The assumption here is that we do not have more than 64 stats
+ */
+ stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "edma Rx fill ring stats start:\n\n");
+
+ /*
+ * Rx fill ring stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Rx fill ring %d stats:\n\n", data->edma_id);
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; i < NSS_EDMA_STATS_RXFILL_MAX; i++) {
+ stats_shadow[i] = edma_stats.rxfill_stats[data->edma_id][i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; i < NSS_EDMA_STATS_RXFILL_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_edma_stats_str_rxfill[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma Rx fill ring stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_edma_err_stats_read()
+ * Read EDMA err stats
+ */
+static ssize_t nss_edma_err_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_EDMA_ERR_STATS_MAX + 2) + 3;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ /*
+ * Note: The assumption here is that we do not have more than 64 stats
+ */
+ stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "edma error stats start:\n\n");
+
+ /*
+ * Common node stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "edma error stats:\n\n");
+ spin_lock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_EDMA_ERR_STATS_MAX); i++)
+ stats_shadow[i] = edma_stats.misc_err[i];
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_EDMA_ERR_STATS_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_edma_stats_str_err_map[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma error stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * edma_port_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(edma_port)
+
+/*
+ * edma_port_type_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(edma_port_type)
+
+/*
+ * edma_port_ring_map_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(edma_port_ring_map)
+
+/*
+ * edma_txring_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(edma_txring)
+
+/*
+ * edma_rxring_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(edma_rxring)
+
+/*
+ * edma_txcmplring_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(edma_txcmplring)
+
+/*
+ * edma_rxfillring_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(edma_rxfillring)
+
+/*
+ * edma_err_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(edma_err)
+
+/*
+ * nss_edma_stats_dentry_create()
+ * Create edma statistics debug entry.
+ */
+void nss_edma_stats_dentry_create(void)
+{
+ int i;
+ struct dentry *edma_d = NULL;
+ struct dentry *edma_port_dir_d = NULL;
+ struct dentry *edma_port_d = NULL;
+ struct dentry *edma_port_type_d = NULL;
+ struct dentry *edma_port_stats_d = NULL;
+ struct dentry *edma_port_ring_map_d = NULL;
+ struct dentry *edma_rings_dir_d = NULL;
+ struct dentry *edma_tx_dir_d = NULL;
+ struct dentry *edma_tx_d = NULL;
+ struct dentry *edma_rx_dir_d = NULL;
+ struct dentry *edma_rx_d = NULL;
+ struct dentry *edma_txcmpl_dir_d = NULL;
+ struct dentry *edma_txcmpl_d = NULL;
+ struct dentry *edma_rxfill_dir_d = NULL;
+ struct dentry *edma_rxfill_d = NULL;
+ struct dentry *edma_err_stats_d = NULL;
+ char file_name[10];
+
+ edma_d = debugfs_create_dir("edma", nss_top_main.stats_dentry);
+ if (unlikely(edma_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma directory");
+ return;
+ }
+
+ /*
+ * edma port stats
+ */
+ edma_port_dir_d = debugfs_create_dir("ports", edma_d);
+ if (unlikely(edma_port_dir_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/ports directory");
+ return;
+ }
+
+ for (i = 0; i < NSS_EDMA_NUM_PORTS_MAX; i++) {
+ memset(file_name, 0, sizeof(file_name));
+ snprintf(file_name, sizeof(file_name), "%d", i);
+
+ edma_port_d = debugfs_create_dir(file_name, edma_port_dir_d);
+ if (unlikely(edma_port_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d directory", i);
+ return;
+ }
+
+ edma_port_stats_d = debugfs_create_file("stats", 0400, edma_port_d, (void *)(nss_ptr_t)i, &nss_edma_port_stats_ops);
+ if (unlikely(edma_port_stats_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d/stats file", i);
+ return;
+ }
+
+ edma_port_type_d = debugfs_create_file("type", 0400, edma_port_d, (void *)(nss_ptr_t)i, &nss_edma_port_type_stats_ops);
+ if (unlikely(edma_port_type_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d/type file", i);
+ return;
+ }
+
+ edma_port_ring_map_d = debugfs_create_file("ring_map", 0400, edma_port_d, (void *)(nss_ptr_t)i, &nss_edma_port_ring_map_stats_ops);
+ if (unlikely(edma_port_ring_map_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d/ring_map file", i);
+ return;
+ }
+ }
+
+ /*
+ * edma error stats
+ */
+ edma_err_stats_d = NULL;
+ edma_err_stats_d = debugfs_create_file("err_stats", 0400, edma_d, &nss_top_main, &nss_edma_err_stats_ops);
+ if (unlikely(edma_port_stats_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/%d/err_stats file", 0);
+ return;
+ }
+
+ /*
+ * edma ring stats
+ */
+ edma_rings_dir_d = debugfs_create_dir("rings", edma_d);
+ if (unlikely(edma_rings_dir_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/rings directory");
+ return;
+ }
+
+ /*
+ * edma tx ring stats
+ */
+ edma_tx_dir_d = debugfs_create_dir("tx", edma_rings_dir_d);
+ if (unlikely(edma_tx_dir_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/rings/tx directory");
+ return;
+ }
+
+ for (i = 0; i < NSS_EDMA_NUM_TX_RING_MAX; i++) {
+ memset(file_name, 0, sizeof(file_name));
+ scnprintf(file_name, sizeof(file_name), "%d", i);
+ edma_tx_d = debugfs_create_file(file_name, 0400, edma_tx_dir_d, (void *)(nss_ptr_t)i, &nss_edma_txring_stats_ops);
+ if (unlikely(edma_tx_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/rings/tx/%d file", i);
+ return;
+ }
+ }
+
+ /*
+ * edma rx ring stats
+ */
+ edma_rx_dir_d = debugfs_create_dir("rx", edma_rings_dir_d);
+ if (unlikely(edma_rx_dir_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rx directory");
+ return;
+ }
+
+ for (i = 0; i < NSS_EDMA_NUM_RX_RING_MAX; i++) {
+ memset(file_name, 0, sizeof(file_name));
+ scnprintf(file_name, sizeof(file_name), "%d", i);
+ edma_rx_d = debugfs_create_file(file_name, 0400, edma_rx_dir_d, (void *)(nss_ptr_t)i, &nss_edma_rxring_stats_ops);
+ if (unlikely(edma_rx_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rx/%d file", i);
+ return;
+ }
+ }
+
+ /*
+ * edma tx cmpl ring stats
+ */
+ edma_txcmpl_dir_d = debugfs_create_dir("txcmpl", edma_rings_dir_d);
+ if (unlikely(edma_txcmpl_dir_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/rings/txcmpl directory");
+ return;
+ }
+
+ for (i = 0; i < NSS_EDMA_NUM_TXCMPL_RING_MAX; i++) {
+ memset(file_name, 0, sizeof(file_name));
+ scnprintf(file_name, sizeof(file_name), "%d", i);
+ edma_txcmpl_d = debugfs_create_file(file_name, 0400, edma_txcmpl_dir_d, (void *)(nss_ptr_t)i, &nss_edma_txcmplring_stats_ops);
+ if (unlikely(edma_txcmpl_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/rings/txcmpl/%d file", i);
+ return;
+ }
+ }
+
+ /*
+ * edma rx fill ring stats
+ */
+ edma_rxfill_dir_d = debugfs_create_dir("rxfill", edma_rings_dir_d);
+ if (unlikely(edma_rxfill_dir_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rxfill directory");
+ return;
+ }
+
+ for (i = 0; i < NSS_EDMA_NUM_RXFILL_RING_MAX; i++) {
+ memset(file_name, 0, sizeof(file_name));
+ scnprintf(file_name, sizeof(file_name), "%d", i);
+ edma_rxfill_d = debugfs_create_file(file_name, 0400, edma_rxfill_dir_d, (void *)(nss_ptr_t)i, &nss_edma_rxfillring_stats_ops);
+ if (unlikely(edma_rxfill_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rxfill/%d file", i);
+ return;
+ }
+ }
+}
+
+/*
+ * nss_edma_metadata_port_stats_sync()
+ * Handle the syncing of EDMA port statistics.
+ */
+void nss_edma_metadata_port_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_port_stats_sync *nepss)
+{
+ uint16_t i, j = 0;
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ /*
+ * edma port stats
+ * We process a subset of port stats since msg payload is not enough to hold all ports at once.
+ */
+ for (i = nepss->start_port; i < nepss->end_port; i++) {
+ int k;
+
+ edma_stats.port[i].port_stats[NSS_STATS_NODE_RX_PKTS] += nepss->port_stats[j].node_stats.rx_packets;
+ edma_stats.port[i].port_stats[NSS_STATS_NODE_RX_BYTES] += nepss->port_stats[j].node_stats.rx_bytes;
+ edma_stats.port[i].port_stats[NSS_STATS_NODE_TX_PKTS] += nepss->port_stats[j].node_stats.tx_packets;
+ edma_stats.port[i].port_stats[NSS_STATS_NODE_TX_BYTES] += nepss->port_stats[j].node_stats.tx_bytes;
+
+ for (k = 0; k < NSS_MAX_NUM_PRI; k++) {
+ edma_stats.port[i].port_stats[NSS_STATS_NODE_RX_QUEUE_0_DROPPED + k] += nepss->port_stats[i].node_stats.rx_dropped[k];
+ }
+
+ edma_stats.port[i].port_type = nepss->port_stats[j].port_type;
+ edma_stats.port[i].port_ring_map[NSS_EDMA_PORT_RX_RING] = nepss->port_stats[j].edma_rx_ring;
+ edma_stats.port[i].port_ring_map[NSS_EDMA_PORT_TX_RING] = nepss->port_stats[j].edma_tx_ring;
+ j++;
+ }
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
+
+/*
+ * nss_edma_metadata_ring_stats_sync()
+ * Handle the syncing of EDMA ring statistics.
+ */
+void nss_edma_metadata_ring_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_ring_stats_sync *nerss)
+{
+ int32_t i;
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ /*
+ * edma tx ring stats
+ */
+ for (i = 0; i < NSS_EDMA_NUM_TX_RING_MAX; i++) {
+ edma_stats.tx_stats[i][NSS_EDMA_STATS_TX_ERR] += nerss->tx_ring[i].tx_err;
+ edma_stats.tx_stats[i][NSS_EDMA_STATS_TX_DROPPED] += nerss->tx_ring[i].tx_dropped;
+ edma_stats.tx_stats[i][NSS_EDMA_STATS_TX_DESC] += nerss->tx_ring[i].desc_cnt;
+ }
+
+ /*
+ * edma rx ring stats
+ */
+ for (i = 0; i < NSS_EDMA_NUM_RX_RING_MAX; i++) {
+ edma_stats.rx_stats[i][NSS_EDMA_STATS_RX_CSUM_ERR] += nerss->rx_ring[i].rx_csum_err;
+ edma_stats.rx_stats[i][NSS_EDMA_STATS_RX_DESC] += nerss->rx_ring[i].desc_cnt;
+ }
+
+ /*
+ * edma tx cmpl ring stats
+ */
+ for (i = 0; i < NSS_EDMA_NUM_TXCMPL_RING_MAX; i++) {
+ edma_stats.txcmpl_stats[i][NSS_EDMA_STATS_TXCMPL_DESC] += nerss->txcmpl_ring[i].desc_cnt;
+ }
+
+ /*
+ * edma rx fill ring stats
+ */
+ for (i = 0; i < NSS_EDMA_NUM_RXFILL_RING_MAX; i++) {
+ edma_stats.rxfill_stats[i][NSS_EDMA_STATS_RXFILL_DESC] += nerss->rxfill_ring[i].desc_cnt;
+ }
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
+
+/*
+ * nss_edma_metadata_err_stats_sync()
+ * Handle the syncing of EDMA error statistics.
+ */
+void nss_edma_metadata_err_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_err_stats_sync *nerss)
+{
+
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ edma_stats.misc_err[NSS_EDMA_AXI_RD_ERR] += nerss->msg_err_stats.axi_rd_err;
+ edma_stats.misc_err[NSS_EDMA_AXI_WR_ERR] += nerss->msg_err_stats.axi_wr_err;
+ edma_stats.misc_err[NSS_EDMA_RX_DESC_FIFO_FULL_ERR] += nerss->msg_err_stats.rx_desc_fifo_full_err;
+ edma_stats.misc_err[NSS_EDMA_RX_BUF_SIZE_ERR] += nerss->msg_err_stats.rx_buf_size_err;
+ edma_stats.misc_err[NSS_EDMA_TX_SRAM_FULL_ERR] += nerss->msg_err_stats.tx_sram_full_err;
+ edma_stats.misc_err[NSS_EDMA_TX_CMPL_BUF_FULL_ERR] += nerss->msg_err_stats.tx_cmpl_buf_full_err;
+ edma_stats.misc_err[NSS_EDMA_PKT_LEN_LA64K_ERR] += nerss->msg_err_stats.pkt_len_la64k_err;
+ edma_stats.misc_err[NSS_EDMA_PKT_LEN_LE33_ERR] += nerss->msg_err_stats.pkt_len_le33_err;
+ edma_stats.misc_err[NSS_EDMA_DATA_LEN_ERR] += nerss->msg_err_stats.data_len_err;
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
diff --git a/nss_edma_stats.h b/nss_edma_stats.h
new file mode 100644
index 0000000..1c61075
--- /dev/null
+++ b/nss_edma_stats.h
@@ -0,0 +1,118 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+/*
+ * nss_edma_stats.h
+ * NSS EDMA statistics header file.
+ */
+
+#ifndef __NSS_EDMA_STATS_H
+#define __NSS_EDMA_STATS_H
+
+#include "nss_core.h"
+
+/*
+ * Types of EDMA Tx ring stats
+ */
+enum nss_edma_stats_tx_t {
+ NSS_EDMA_STATS_TX_ERR,
+ NSS_EDMA_STATS_TX_DROPPED,
+ NSS_EDMA_STATS_TX_DESC,
+ NSS_EDMA_STATS_TX_MAX
+};
+
+/*
+ * Types of EDMA Rx ring stats
+ */
+enum nss_edma_stats_rx_t {
+ NSS_EDMA_STATS_RX_CSUM_ERR,
+ NSS_EDMA_STATS_RX_DESC,
+ NSS_EDMA_STATS_RX_QOS_ERR,
+ NSS_EDMA_STATS_RX_MAX
+};
+
+/*
+ * Types of EDMA Tx complete stats
+ */
+enum nss_edma_stats_txcmpl_t {
+ NSS_EDMA_STATS_TXCMPL_DESC,
+ NSS_EDMA_STATS_TXCMPL_MAX
+};
+
+/*
+ * Types of EDMA Rx fill stats
+ */
+enum nss_edma_stats_rxfill_t {
+ NSS_EDMA_STATS_RXFILL_DESC,
+ NSS_EDMA_STATS_RXFILL_MAX
+};
+
+/*
+ * Port to EDMA ring map
+ */
+enum nss_edma_port_ring_map_t {
+ NSS_EDMA_PORT_RX_RING,
+ NSS_EDMA_PORT_TX_RING,
+ NSS_EDMA_PORT_RING_MAP_MAX
+};
+
+/*
+ * Types of EDMA ERROR STATS
+ */
+enum nss_edma_err_t {
+ NSS_EDMA_AXI_RD_ERR,
+ NSS_EDMA_AXI_WR_ERR,
+ NSS_EDMA_RX_DESC_FIFO_FULL_ERR,
+ NSS_EDMA_RX_BUF_SIZE_ERR,
+ NSS_EDMA_TX_SRAM_FULL_ERR,
+ NSS_EDMA_TX_CMPL_BUF_FULL_ERR,
+ NSS_EDMA_PKT_LEN_LA64K_ERR,
+ NSS_EDMA_PKT_LEN_LE33_ERR,
+ NSS_EDMA_DATA_LEN_ERR,
+ NSS_EDMA_ALLOC_FAIL_CNT,
+ NSS_EDMA_ERR_STATS_MAX
+};
+
+/*
+ * NSS EDMA port stats
+ */
+struct nss_edma_port_info {
+ uint64_t port_stats[NSS_STATS_NODE_MAX];
+ uint64_t port_type;
+ uint64_t port_ring_map[NSS_EDMA_PORT_RING_MAP_MAX];
+};
+
+/*
+ * NSS EDMA node statistics
+ */
+struct nss_edma_stats {
+ struct nss_edma_port_info port[NSS_EDMA_NUM_PORTS_MAX];
+ uint64_t tx_stats[NSS_EDMA_NUM_TX_RING_MAX][NSS_EDMA_STATS_TX_MAX];
+ uint64_t rx_stats[NSS_EDMA_NUM_RX_RING_MAX][NSS_EDMA_STATS_RX_MAX];
+ uint64_t txcmpl_stats[NSS_EDMA_NUM_TXCMPL_RING_MAX][NSS_EDMA_STATS_TXCMPL_MAX];
+ uint64_t rxfill_stats[NSS_EDMA_NUM_RXFILL_RING_MAX][NSS_EDMA_STATS_RXFILL_MAX];
+ uint64_t misc_err[NSS_EDMA_ERR_STATS_MAX];
+};
+
+/*
+ * NSS EDMA statistics APIs
+ */
+extern void nss_edma_metadata_port_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_port_stats_sync *nepss);
+extern void nss_edma_metadata_ring_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_ring_stats_sync *nerss);
+extern void nss_edma_metadata_err_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_err_stats_sync *nerss);
+extern void nss_edma_stats_dentry_create(void);
+
+#endif /* __NSS_EDMA_STATS_H */
diff --git a/nss_eth_rx.c b/nss_eth_rx.c
index 2ac5687..6d1fb4a 100644
--- a/nss_eth_rx.c
+++ b/nss_eth_rx.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -20,6 +20,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_eth_rx_stats.h"
/*
**********************************
@@ -28,37 +29,6 @@
*/
/*
- * nss_eth_rx_metadata_stats_sync()
- * Handle the syncing of PPPoE node statistics.
- */
-static void nss_eth_rx_metadata_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_eth_rx_node_sync *nens)
-{
- int i;
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
-
- spin_lock_bh(&nss_top->stats_lock);
-
- nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nens->node_stats.rx_packets;
- nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nens->node_stats.rx_bytes;
- nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nens->node_stats.tx_packets;
- nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nens->node_stats.tx_bytes;
-
- for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
- nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nens->node_stats.rx_dropped[i];
- }
-
- nss_top->stats_eth_rx[NSS_STATS_ETH_RX_TOTAL_TICKS] += nens->total_ticks;
- nss_top->stats_eth_rx[NSS_STATS_ETH_RX_WORST_CASE_TICKS] += nens->worst_case_ticks;
- nss_top->stats_eth_rx[NSS_STATS_ETH_RX_ITERATIONS] += nens->iterations;
-
- for (i = 0; i < NSS_EXCEPTION_EVENT_ETH_RX_MAX; i++) {
- nss_top->stats_if_exception_eth_rx[i] += nens->exception_events[i];
- }
-
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
* nss_eth_rx_interface_handler()
* Handle NSS -> HLOS messages for ETH_RX node
*/
@@ -96,4 +66,6 @@
void nss_eth_rx_register_handler(struct nss_ctx_instance *nss_ctx)
{
nss_core_register_handler(nss_ctx, NSS_ETH_RX_INTERFACE, nss_eth_rx_interface_handler, NULL);
+
+ nss_eth_rx_stats_dentry_create();
}
diff --git a/nss_eth_rx_stats.c b/nss_eth_rx_stats.c
new file mode 100644
index 0000000..617e846
--- /dev/null
+++ b/nss_eth_rx_stats.c
@@ -0,0 +1,166 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_eth_rx_stats.h"
+
+/*
+ * nss_eth_rx_stats_str
+ * eth_rx stats strings
+ */
+static int8_t *nss_eth_rx_stats_str[NSS_ETH_RX_STATS_MAX] = {
+ "ticks",
+ "worst_ticks",
+ "iterations"
+};
+
+/*
+ * nss_eth_rx_exception_stats_str
+ * Interface stats strings for unknown exceptions
+ */
+static int8_t *nss_eth_rx_exception_stats_str[NSS_ETH_RX_EXCEPTION_EVENT_MAX] = {
+ "UNKNOWN_L3_PROTOCOL",
+ "ETH_HDR_MISSING",
+ "VLAN_MISSING",
+ "TRUSTSEC_HDR_MISSING"
+};
+
+uint64_t nss_eth_rx_stats[NSS_ETH_RX_STATS_MAX]; /* ETH_RX statistics */
+uint64_t nss_eth_rx_exception_stats[NSS_ETH_RX_EXCEPTION_EVENT_MAX]; /* Unknown protocol exception events per interface */
+
+/*
+ * nss_eth_rx_stats_read()
+ * Read ETH_RX stats
+ */
+static ssize_t nss_eth_rx_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_ETH_RX_STATS_MAX + 3) + (NSS_ETH_RX_EXCEPTION_EVENT_MAX + 3) + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ /*
+ * Note: The assumption here is that we do not have more than 64 stats
+ */
+ stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "eth_rx stats start:\n\n");
+
+ size_wr = nss_stats_fill_common_stats(NSS_ETH_RX_INTERFACE, lbuf, size_wr, size_al);
+
+ /*
+ * eth_rx node stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx node stats:\n\n");
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_ETH_RX_STATS_MAX); i++) {
+ stats_shadow[i] = nss_eth_rx_stats[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_ETH_RX_STATS_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_eth_rx_stats_str[i], stats_shadow[i]);
+ }
+
+ /*
+ * Exception stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx exception stats:\n\n");
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_ETH_RX_EXCEPTION_EVENT_MAX); i++) {
+ stats_shadow[i] = nss_eth_rx_exception_stats[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_ETH_RX_EXCEPTION_EVENT_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_eth_rx_exception_stats_str[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_eth_rx_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(eth_rx)
+
+/*
+ * nss_eth_rx_stats_dentry_create()
+ * Create eth_rx statistics debug entry.
+ */
+void nss_eth_rx_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("eth_rx", &nss_eth_rx_stats_ops);
+}
+
+/*
+ * nss_eth_rx_metadata_stats_sync()
+ * Handle the syncing of ETH_RX node statistics.
+ */
+void nss_eth_rx_metadata_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_eth_rx_node_sync *nens)
+{
+ int32_t i;
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nens->node_stats.rx_packets;
+ nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nens->node_stats.rx_bytes;
+ nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nens->node_stats.tx_packets;
+ nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nens->node_stats.tx_bytes;
+
+ for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
+ nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nens->node_stats.rx_dropped[i];
+ }
+
+ nss_eth_rx_stats[NSS_ETH_RX_STATS_TOTAL_TICKS] += nens->total_ticks;
+ nss_eth_rx_stats[NSS_ETH_RX_STATS_WORST_CASE_TICKS] += nens->worst_case_ticks;
+ nss_eth_rx_stats[NSS_ETH_RX_STATS_ITERATIONS] += nens->iterations;
+
+ for (i = 0; i < NSS_ETH_RX_EXCEPTION_EVENT_MAX; i++) {
+ nss_eth_rx_exception_stats[i] += nens->exception_events[i];
+ }
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
diff --git a/nss_eth_rx_stats.h b/nss_eth_rx_stats.h
new file mode 100644
index 0000000..bc60da2
--- /dev/null
+++ b/nss_eth_rx_stats.h
@@ -0,0 +1,82 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#ifndef __NSS_ETH_RX_STATS_H
+#define __NSS_ETH_RX_STATS_H
+
+#include <nss_cmn.h>
+
+/*
+ * nss_eth_rx_stats.h
+ * NSS driver ETH_RX statistics header file.
+ */
+
+/*
+ * ETH_RX node statistics
+ */
+enum nss_eth_rx_stats {
+ NSS_ETH_RX_STATS_TOTAL_TICKS = 0, /* Total clock ticks spend inside the eth_rx package */
+ NSS_ETH_RX_STATS_WORST_CASE_TICKS, /* Worst case iteration of the eth_rx in ticks */
+ NSS_ETH_RX_STATS_ITERATIONS, /* Number of iterations around the eth_rx */
+ NSS_ETH_RX_STATS_MAX,
+};
+
+/*
+ * Exception events from bridge/route handler
+ */
+enum nss_eth_rx_exception_events {
+ NSS_ETH_RX_EXCEPTION_EVENT_UNKNOWN_L3_PROTOCOL,
+ NSS_ETH_RX_EXCEPTION_EVENT_ETH_HDR_MISSING,
+ NSS_ETH_RX_EXCEPTION_EVENT_VLAN_MISSING,
+ NSS_ETH_RX_EXCEPTION_EVENT_TRUSTSEC_HDR_MISSING,
+ NSS_ETH_RX_EXCEPTION_EVENT_MAX,
+};
+
+/*
+ * Request/Response types
+ */
+enum nss_eth_rx_metadata_types {
+ NSS_RX_METADATA_TYPE_ETH_RX_STATS_SYNC,
+ NSS_METADATA_TYPE_ETH_RX_MAX,
+};
+
+/*
+ * The NSS eth_rx node stats structure.
+ */
+struct nss_eth_rx_node_sync {
+ struct nss_cmn_node_stats node_stats;
+ /* Common node stats for ETH_RX */
+ uint32_t total_ticks; /* Total clock ticks spend inside the eth_rx */
+ uint32_t worst_case_ticks; /* Worst case iteration of the eth_rx in ticks */
+ uint32_t iterations; /* Number of iterations around the eth_rx */
+ uint32_t exception_events[NSS_ETH_RX_EXCEPTION_EVENT_MAX];
+ /* Number of ETH_RX exception events */
+};
+
+/*
+ * Message structure to send/receive eth_rx commands
+ */
+struct nss_eth_rx_msg {
+ struct nss_cmn_msg cm; /* Message Header */
+ union {
+ struct nss_eth_rx_node_sync node_sync; /* Message: node statistics sync */
+ } msg;
+};
+
+extern void nss_eth_rx_metadata_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_eth_rx_node_sync *nens);
+extern void nss_eth_rx_stats_dentry_create(void);
+
+#endif /* __NSS_ETH_RX_STATS_H */
diff --git a/nss_gre.c b/nss_gre.c
index 902e9d4..4c426e8 100644
--- a/nss_gre.c
+++ b/nss_gre.c
@@ -15,6 +15,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_gre_stats.h"
#define NSS_GRE_TX_TIMEOUT 3000 /* 3 Seconds */
@@ -29,13 +30,6 @@
void *app_data;
} nss_gre_pvt;
-/*
- * Data structures to store GRE nss debug stats
- */
-static DEFINE_SPINLOCK(nss_gre_stats_lock);
-static struct nss_stats_gre_session_debug session_debug_stats[NSS_GRE_MAX_DEBUG_SESSION_STATS];
-static struct nss_stats_gre_base_debug base_debug_stats;
-
static atomic64_t pkt_cb_addr = ATOMIC64_INIT(0);
/*
@@ -60,39 +54,6 @@
}
/*
- * nss_gre_session_debug_stats_sync()
- * debug statistics sync for GRE session.
- */
-static void nss_gre_session_debug_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_session_stats_msg *sstats, uint16_t if_num)
-{
- int i, j;
- spin_lock_bh(&nss_gre_stats_lock);
- for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) {
- if (session_debug_stats[i].if_num == if_num) {
- for (j = 0; j < NSS_STATS_GRE_SESSION_DEBUG_MAX; j++) {
- session_debug_stats[i].stats[j] += sstats->stats[j];
- }
- break;
- }
- }
- spin_unlock_bh(&nss_gre_stats_lock);
-}
-
-/*
- * nss_gre_base_debug_stats_sync()
- * Debug statistics sync for GRE base node.
- */
-static void nss_gre_base_debug_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_base_stats_msg *bstats)
-{
- int i;
- spin_lock_bh(&nss_gre_stats_lock);
- for (i = 0; i < NSS_STATS_GRE_BASE_DEBUG_MAX; i++) {
- base_debug_stats.stats[i] += bstats->stats[i];
- }
- spin_unlock_bh(&nss_gre_stats_lock);
-}
-
-/*
* nss_gre_msg_handler()
* Handle NSS -> HLOS messages for GRE
*/
@@ -124,11 +85,11 @@
/*
* debug stats embedded in stats msg
*/
- nss_gre_session_debug_stats_sync(nss_ctx, &ntm->msg.sstats, ncm->interface);
+ nss_gre_stats_session_debug_sync(nss_ctx, &ntm->msg.sstats, ncm->interface);
break;
case NSS_GRE_MSG_BASE_STATS:
- nss_gre_base_debug_stats_sync(nss_ctx, &ntm->msg.bstats);
+ nss_gre_stats_base_debug_sync(nss_ctx, &ntm->msg.bstats);
break;
default:
@@ -195,53 +156,6 @@
}
/*
- * nss_gre_session_debug_stats_get()
- * Get GRE session debug statistics.
- */
-void nss_gre_session_debug_stats_get(void *stats_mem, int size)
-{
- struct nss_stats_gre_session_debug *stats = (struct nss_stats_gre_session_debug *)stats_mem;
- int i;
-
- if (!stats || (size < (sizeof(struct nss_stats_gre_session_debug) * NSS_STATS_GRE_SESSION_DEBUG_MAX))) {
- nss_warning("No memory to copy gre stats");
- return;
- }
-
- spin_lock_bh(&nss_gre_stats_lock);
- for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) {
- if (session_debug_stats[i].valid) {
- memcpy(stats, &session_debug_stats[i], sizeof(struct nss_stats_gre_session_debug));
- stats++;
- }
- }
- spin_unlock_bh(&nss_gre_stats_lock);
-}
-
-/*
- * nss_gre_base_debug_stats_get()
- * Get GRE debug base statistics.
- */
-void nss_gre_base_debug_stats_get(void *stats_mem, int size)
-{
- struct nss_stats_gre_base_debug *stats = (struct nss_stats_gre_base_debug *)stats_mem;
-
- if (!stats) {
- nss_warning("No memory to copy GRE base stats\n");
- return;
- }
-
- if (size < sizeof(struct nss_stats_gre_base_debug)) {
- nss_warning("Not enough memory to copy GRE base stats\n");
- return;
- }
-
- spin_lock_bh(&nss_gre_stats_lock);
- memcpy(stats, &base_debug_stats, sizeof(struct nss_stats_gre_base_debug));
- spin_unlock_bh(&nss_gre_stats_lock);
-}
-
-/*
* nss_gre_register_pkt_callback()
* Register for data callback.
*/
@@ -406,7 +320,6 @@
nss_gre_msg_callback_t event_callback, struct net_device *netdev, uint32_t features)
{
struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_handler_id];
- int i = 0;
nss_assert(nss_ctx);
nss_assert(nss_is_dynamic_interface(if_num));
@@ -418,16 +331,7 @@
nss_core_register_handler(nss_ctx, if_num, nss_gre_msg_handler, NULL);
- spin_lock_bh(&nss_gre_stats_lock);
- for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) {
- if (!session_debug_stats[i].valid) {
- session_debug_stats[i].valid = true;
- session_debug_stats[i].if_num = if_num;
- session_debug_stats[i].if_index = netdev->ifindex;
- break;
- }
- }
- spin_unlock_bh(&nss_gre_stats_lock);
+ nss_gre_stats_session_register(if_num, netdev);
return nss_ctx;
}
@@ -440,7 +344,6 @@
void nss_gre_unregister_if(uint32_t if_num)
{
struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_handler_id];
- int i;
nss_assert(nss_ctx);
nss_assert(nss_is_dynamic_interface(if_num));
@@ -451,14 +354,7 @@
nss_core_unregister_handler(nss_ctx, if_num);
- spin_lock_bh(&nss_gre_stats_lock);
- for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) {
- if (session_debug_stats[i].if_num == if_num) {
- memset(&session_debug_stats[i], 0, sizeof(struct nss_stats_gre_session_debug));
- break;
- }
- }
- spin_unlock_bh(&nss_gre_stats_lock);
+ nss_gre_stats_session_unregister(if_num);
}
EXPORT_SYMBOL(nss_gre_unregister_if);
@@ -493,4 +389,5 @@
sema_init(&nss_gre_pvt.sem, 1);
init_completion(&nss_gre_pvt.complete);
nss_core_register_handler(nss_ctx, NSS_GRE_INTERFACE, nss_gre_msg_handler, NULL);
+ nss_gre_stats_dentry_create();
}
diff --git a/nss_gre_redir.c b/nss_gre_redir.c
index 1ff3106..55ce3b7 100644
--- a/nss_gre_redir.c
+++ b/nss_gre_redir.c
@@ -15,6 +15,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_gre_redir_stats.h"
/*
* Spinlock to update tunnel stats
@@ -354,6 +355,8 @@
nss_warning("Not able to register handler for gre_redir base interface with NSS core\n");
return;
}
+
+ nss_gre_redir_stats_dentry_create();
}
EXPORT_SYMBOL(nss_gre_redir_tx_msg);
diff --git a/nss_gre_redir_stats.c b/nss_gre_redir_stats.c
new file mode 100644
index 0000000..e350f5e
--- /dev/null
+++ b/nss_gre_redir_stats.c
@@ -0,0 +1,159 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_core.h"
+#include "nss_stats.h"
+#include "nss_gre_redir.h"
+#include "nss_gre_redir_stats.h"
+
+/*
+ * nss_gre_redir_stats_str
+ * GRE REDIR statistics string
+ */
+static int8_t *nss_gre_redir_stats_str[NSS_GRE_REDIR_STATS_MAX] = {
+ "TX Packets",
+ "TX Bytes",
+ "TX Drops",
+ "RX Packets",
+ "RX Bytes",
+ "Rx Drops"
+};
+
+/*
+ * nss_gre_redir_stats()
+ * Make a row for GRE_REDIR stats.
+ */
+static ssize_t nss_gre_redir_stats(char *line, int len, int i, struct nss_gre_redir_tunnel_stats *s)
+{
+ char name[20];
+ uint64_t tcnt = 0;
+ int j = 0;
+
+ switch (i) {
+ case 0:
+ tcnt = s->node_stats.tx_packets;
+ return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt);
+ case 1:
+ tcnt = s->node_stats.tx_bytes;
+ return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt);
+ case 2:
+ tcnt = s->tx_dropped;
+ return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt);
+ case 3:
+ tcnt = s->node_stats.rx_packets;
+ return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt);
+ case 4:
+ tcnt = s->node_stats.rx_bytes;
+ return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt);
+ case 5:
+ for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
+ scnprintf(name, 20, "Rx Queue %d Drops", j);
+ tcnt += snprintf(line, len, "%s = %u\n", name, s->node_stats.rx_dropped[j]);
+ }
+ return tcnt;
+
+ default:
+ return 0;
+ }
+
+ return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt);
+}
+
+/*
+ * nss_gre_redir_stats_read()
+ * READ gre_redir tunnel stats.
+ */
+static ssize_t nss_gre_redir_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ struct nss_stats_data *data = fp->private_data;
+ ssize_t bytes_read = 0;
+ struct nss_gre_redir_tunnel_stats stats;
+ size_t bytes;
+ char line[80];
+ int start, end;
+ int index = 0;
+
+ if (data) {
+ index = data->index;
+ }
+
+ /*
+ * If we are done accomodating all the GRE_REDIR tunnels.
+ */
+ if (index >= NSS_GRE_REDIR_MAX_INTERFACES) {
+ return 0;
+ }
+
+ for (; index < NSS_GRE_REDIR_MAX_INTERFACES; index++) {
+ bool isthere;
+
+ /*
+ * If gre_redir tunnel does not exists, then isthere will be false.
+ */
+ isthere = nss_gre_redir_get_stats(index, &stats);
+ if (!isthere) {
+ continue;
+ }
+
+ bytes = snprintf(line, sizeof(line), "\nTunnel if_num: %2d\n", stats.if_num);
+ if ((bytes_read + bytes) > sz) {
+ break;
+ }
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto fail;
+ }
+ bytes_read += bytes;
+ start = 0;
+ end = 6;
+ while (bytes_read < sz && start < end) {
+ bytes = nss_gre_redir_stats(line, sizeof(line), start, &stats);
+
+ if ((bytes_read + bytes) > sz)
+ break;
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto fail;
+ }
+
+ bytes_read += bytes;
+ start++;
+ }
+ }
+
+ if (bytes_read > 0) {
+ *ppos = bytes_read;
+ }
+
+ if (data) {
+ data->index = index;
+ }
+
+fail:
+ return bytes_read;
+}
+
+/*
+ * nss_gre_redir_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(gre_redir)
+
+void nss_gre_redir_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("gre_redir", &nss_gre_redir_stats_ops);
+}
diff --git a/nss_gre_redir_stats.h b/nss_gre_redir_stats.h
new file mode 100644
index 0000000..a551931
--- /dev/null
+++ b/nss_gre_redir_stats.h
@@ -0,0 +1,38 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_GRE_REDIR_STATS_H__
+#define __NSS_GRE_REDIR_STATS_H__
+
+/*
+ * GRE REDIR statistics
+ */
+enum nss_gre_redir_stats_types {
+ NSS_GRE_REDIR_STATS_TX_PKTS,
+ NSS_GRE_REDIR_STATS_TX_BYTES,
+ NSS_GRE_REDIR_STATS_TX_DROPS,
+ NSS_GRE_REDIR_STATS_RX_PKTS,
+ NSS_GRE_REDIR_STATS_RX_BYTES,
+ NSS_GRE_REDIR_STATS_RX_DROPS,
+ NSS_GRE_REDIR_STATS_MAX
+};
+
+/*
+ * NSS GRE REDIR statistics APIs
+ */
+extern void nss_gre_redir_stats_dentry_create(void);
+
+#endif /* __NSS_GRE_REDIR_STATS_H__ */
diff --git a/nss_gre_stats.c b/nss_gre_stats.c
new file mode 100644
index 0000000..7bead7b
--- /dev/null
+++ b/nss_gre_stats.c
@@ -0,0 +1,308 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_gre_stats.c
+ * NSS GRE statistics APIs
+ *
+ */
+
+#include "nss_tx_rx_common.h"
+#include "nss_stats.h"
+#include "nss_gre_stats.h"
+
+/*
+ * Data structures to store GRE nss debug stats
+ */
+static DEFINE_SPINLOCK(nss_gre_stats_lock);
+static struct nss_gre_stats_session_debug session_debug_stats[NSS_GRE_MAX_DEBUG_SESSION_STATS];
+static struct nss_gre_stats_base_debug base_debug_stats;
+
+/*
+ * nss_gre_stats_base_debug_str
+ * GRE debug statistics strings for base types
+ */
+static int8_t *nss_gre_stats_base_debug_str[NSS_GRE_STATS_BASE_DEBUG_MAX] = {
+ "GRE_BASE_RX_PACKETS",
+ "GRE_BASE_RX_DROPPED",
+ "GRE_BASE_EXP_ETH_HDR_MISSING",
+ "GRE_BASE_EXP_ETH_TYPE_NON_IP",
+ "GRE_BASE_EXP_IP_UNKNOWN_PROTOCOL",
+ "GRE_BASE_EXP_IP_HEADER_INCOMPLETE",
+ "GRE_BASE_EXP_IP_BAD_TOTAL_LENGTH",
+ "GRE_BASE_EXP_IP_BAD_CHECKSUM",
+ "GRE_BASE_EXP_IP_DATAGRAM_INCOMPLETE",
+ "GRE_BASE_EXP_IP_FRAGMENT",
+ "GRE_BASE_EXP_IP_OPTIONS_INCOMPLETE",
+ "GRE_BASE_EXP_IP_WITH_OPTIONS",
+ "GRE_BASE_EXP_IPV6_UNKNOWN_PROTOCOL",
+ "GRE_BASE_EXP_IPV6_HEADER_INCOMPLETE",
+ "GRE_BASE_EXP_GRE_UNKNOWN_SESSION",
+ "GRE_BASE_EXP_GRE_NODE_INACTIVE",
+};
+
+/*
+ * nss_gre_stats_session_debug_str
+ * GRE debug statistics strings for sessions
+ */
+static int8_t *nss_gre_stats_session_debug_str[NSS_GRE_STATS_SESSION_DEBUG_MAX] = {
+ "GRE_SESSION_PBUF_ALLOC_FAIL",
+ "GRE_SESSION_DECAP_FORWARD_ENQUEUE_FAIL",
+ "GRE_SESSION_ENCAP_FORWARD_ENQUEUE_FAIL",
+ "GRE_SESSION_DECAP_TX_FORWARDED",
+ "GRE_SESSION_ENCAP_RX_RECEIVED",
+ "GRE_SESSION_ENCAP_RX_DROPPED",
+ "GRE_SESSION_ENCAP_RX_LINEAR_FAIL",
+ "GRE_SESSION_EXP_RX_KEY_ERROR",
+ "GRE_SESSION_EXP_RX_SEQ_ERROR",
+ "GRE_SESSION_EXP_RX_CS_ERROR",
+ "GRE_SESSION_EXP_RX_FLAG_MISMATCH",
+ "GRE_SESSION_EXP_RX_MALFORMED",
+ "GRE_SESSION_EXP_RX_INVALID_PROTOCOL",
+ "GRE_SESSION_EXP_RX_NO_HEADROOM",
+};
+
+/*
+ * GRE statistics APIs
+ */
+
+/*
+ * nss_gre_stats_session_register()
+ * Register debug statistic for GRE session.
+ */
+void nss_gre_stats_session_register(uint32_t if_num, struct net_device *netdev)
+{
+ int i;
+
+ spin_lock_bh(&nss_gre_stats_lock);
+ for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) {
+ if (!session_debug_stats[i].valid) {
+ session_debug_stats[i].valid = true;
+ session_debug_stats[i].if_num = if_num;
+ session_debug_stats[i].if_index = netdev->ifindex;
+ break;
+ }
+ }
+ spin_unlock_bh(&nss_gre_stats_lock);
+}
+
+/*
+ * nss_gre_stats_session_unregister()
+ * Unregister debug statistic for GRE session.
+ */
+void nss_gre_stats_session_unregister(uint32_t if_num)
+{
+ int i;
+
+ spin_lock_bh(&nss_gre_stats_lock);
+ for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) {
+ if (session_debug_stats[i].if_num == if_num) {
+ memset(&session_debug_stats[i], 0, sizeof(struct nss_gre_stats_session_debug));
+ break;
+ }
+ }
+ spin_unlock_bh(&nss_gre_stats_lock);
+}
+
+/*
+ * nss_gre_stats_session_debug_sync()
+ * debug statistics sync for GRE session.
+ */
+void nss_gre_stats_session_debug_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_session_stats_msg *sstats, uint16_t if_num)
+{
+ int i, j;
+
+ spin_lock_bh(&nss_gre_stats_lock);
+ for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) {
+ if (session_debug_stats[i].if_num == if_num) {
+ for (j = 0; j < NSS_GRE_STATS_SESSION_DEBUG_MAX; j++) {
+ session_debug_stats[i].stats[j] += sstats->stats[j];
+ }
+ break;
+ }
+ }
+ spin_unlock_bh(&nss_gre_stats_lock);
+}
+
+/*
+ * nss_gre_stats_base_debug_sync()
+ * Debug statistics sync for GRE base node.
+ */
+void nss_gre_stats_base_debug_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_base_stats_msg *bstats)
+{
+ int i;
+
+ spin_lock_bh(&nss_gre_stats_lock);
+ for (i = 0; i < NSS_GRE_STATS_BASE_DEBUG_MAX; i++) {
+ base_debug_stats.stats[i] += bstats->stats[i];
+ }
+ spin_unlock_bh(&nss_gre_stats_lock);
+}
+
+/*
+ * nss_gre_stats_session_debug_get()
+ * Get GRE session debug statistics.
+ */
+static void nss_gre_stats_session_debug_get(void *stats_mem, int size)
+{
+ struct nss_gre_stats_session_debug *stats = (struct nss_gre_stats_session_debug *)stats_mem;
+ int i;
+
+ if (!stats || (size < (sizeof(struct nss_gre_stats_session_debug) * NSS_GRE_MAX_DEBUG_SESSION_STATS))) {
+ nss_warning("No memory to copy gre stats");
+ return;
+ }
+
+ spin_lock_bh(&nss_gre_stats_lock);
+ for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) {
+ if (session_debug_stats[i].valid) {
+ memcpy(stats, &session_debug_stats[i], sizeof(struct nss_gre_stats_session_debug));
+ stats++;
+ }
+ }
+ spin_unlock_bh(&nss_gre_stats_lock);
+}
+
+/*
+ * nss_gre_stats_base_debug_get()
+ * Get GRE debug base statistics.
+ */
+static void nss_gre_stats_base_debug_get(void *stats_mem, int size)
+{
+ struct nss_gre_stats_base_debug *stats = (struct nss_gre_stats_base_debug *)stats_mem;
+
+ if (!stats) {
+ nss_warning("No memory to copy GRE base stats\n");
+ return;
+ }
+
+ if (size < sizeof(struct nss_gre_stats_base_debug)) {
+ nss_warning("Not enough memory to copy GRE base stats\n");
+ return;
+ }
+
+ spin_lock_bh(&nss_gre_stats_lock);
+ memcpy(stats, &base_debug_stats, sizeof(struct nss_gre_stats_base_debug));
+ spin_unlock_bh(&nss_gre_stats_lock);
+}
+
+/*
+ * nss_gre_stats_read()
+ * Read GRE statistics
+ */
+static ssize_t nss_gre_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ uint32_t max_output_lines = 2 /* header & footer for base debug stats */
+ + 2 /* header & footer for session debug stats */
+ + NSS_GRE_STATS_BASE_DEBUG_MAX /* Base debug */
+ + NSS_GRE_MAX_DEBUG_SESSION_STATS * (NSS_GRE_STATS_SESSION_DEBUG_MAX + 2) /*session stats */
+ + 2;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ struct net_device *dev;
+ struct nss_gre_stats_session_debug *sstats;
+ struct nss_gre_stats_base_debug *bstats;
+ int id, i;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(!lbuf)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ bstats = kzalloc(sizeof(struct nss_gre_stats_base_debug), GFP_KERNEL);
+ if (unlikely(!bstats)) {
+ nss_warning("Could not allocate memory for base debug statistics buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ sstats = kzalloc(sizeof(struct nss_gre_stats_session_debug) * NSS_GRE_MAX_DEBUG_SESSION_STATS, GFP_KERNEL);
+ if (unlikely(!sstats)) {
+ nss_warning("Could not allocate memory for base debug statistics buffer");
+ kfree(lbuf);
+ kfree(bstats);
+ return 0;
+ }
+
+ /*
+ * Get all base stats
+ */
+ nss_gre_stats_base_debug_get((void *)bstats, sizeof(struct nss_gre_stats_base_debug));
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngre Base stats start:\n\n");
+ for (i = 0; i < NSS_GRE_STATS_BASE_DEBUG_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %llu\n", nss_gre_stats_base_debug_str[i],
+ bstats->stats[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngre Base stats End\n\n");
+
+ /*
+ * Get all session stats
+ */
+ nss_gre_stats_session_debug_get(sstats, sizeof(struct nss_gre_stats_session_debug) * NSS_GRE_MAX_DEBUG_SESSION_STATS);
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngre Session stats start:\n\n");
+
+ for (id = 0; id < NSS_GRE_MAX_DEBUG_SESSION_STATS; id++) {
+
+ if (!((sstats + id)->valid)) {
+ continue;
+ }
+
+ dev = dev_get_by_index(&init_net, (sstats + id)->if_index);
+ if (likely(dev)) {
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id,
+ (sstats + id)->if_num, dev->name);
+ dev_put(dev);
+ } else {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id,
+ (sstats + id)->if_num);
+ }
+
+ for (i = 0; i < NSS_GRE_STATS_SESSION_DEBUG_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %llu\n", nss_gre_stats_session_debug_str[i],
+ (sstats + id)->stats[i]);
+ }
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngre Session stats end\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
+
+ kfree(sstats);
+ kfree(bstats);
+ kfree(lbuf);
+ return bytes_read;
+}
+
+/*
+ * nss_gre_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(gre)
+
+/*
+ * nss_gre_stats_dentry_create()
+ * Create gre statistics debug entry.
+ */
+void nss_gre_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("gre", &nss_gre_stats_ops);
+}
+
diff --git a/nss_gre_stats.h b/nss_gre_stats.h
new file mode 100644
index 0000000..a16bd34
--- /dev/null
+++ b/nss_gre_stats.h
@@ -0,0 +1,95 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_gre_stats.h
+ * NSS GRE statistics header file.
+ */
+
+#ifndef __NSS_GRE_STATS_H
+#define __NSS_GRE_STATS_H
+
+/*
+ * GRE base debug statistics types
+ */
+enum nss_gre_stats_base_debug_types {
+ NSS_GRE_STATS_BASE_RX_PACKETS, /**< Rx packet count. */
+ NSS_GRE_STATS_BASE_RX_DROPPED, /**< Rx dropped count. */
+ NSS_GRE_STATS_BASE_EXP_ETH_HDR_MISSING, /**< Ethernet header missing. */
+ NSS_GRE_STATS_BASE_EXP_ETH_TYPE_NON_IP, /**< Not IPV4 or IPV6 packet. */
+ NSS_GRE_STATS_BASE_EXP_IP_UNKNOWN_PROTOCOL, /**< Unknown protocol. */
+ NSS_GRE_STATS_BASE_EXP_IP_HEADER_INCOMPLETE, /**< Bad IP header. */
+ NSS_GRE_STATS_BASE_EXP_IP_BAD_TOTAL_LENGTH, /**< Invalid IP packet length. */
+ NSS_GRE_STATS_BASE_EXP_IP_BAD_CHECKSUM, /**< Bad packet checksum. */
+ NSS_GRE_STATS_BASE_EXP_IP_DATAGRAM_INCOMPLETE, /**< Bad packet. */
+ NSS_GRE_STATS_BASE_EXP_IP_FRAGMENT, /**< IP fragment. */
+ NSS_GRE_STATS_BASE_EXP_IP_OPTIONS_INCOMPLETE, /**< Invalid IP options. */
+ NSS_GRE_STATS_BASE_EXP_IP_WITH_OPTIONS, /**< IP packet with options. */
+ NSS_GRE_STATS_BASE_EXP_IPV6_UNKNOWN_PROTOCOL, /**< Unknown protocol. */
+ NSS_GRE_STATS_BASE_EXP_IPV6_HEADER_INCOMPLETE, /**< Incomplete IPV6 header. */
+ NSS_GRE_STATS_BASE_EXP_GRE_UNKNOWN_SESSION, /**< Unknown GRE session. */
+ NSS_GRE_STATS_BASE_EXP_GRE_NODE_INACTIVE, /**< GRE node inactive. */
+ NSS_GRE_STATS_BASE_DEBUG_MAX, /**< GRE base error max. */
+};
+
+/*
+ * GRE base debug statistics
+ */
+struct nss_gre_stats_base_debug {
+ uint64_t stats[NSS_GRE_STATS_BASE_DEBUG_MAX]; /**< GRE debug statistics. */
+};
+
+/*
+ * GRE session debug statistics types
+ */
+enum nss_gre_stats_session_debug_types {
+ NSS_GRE_STATS_SESSION_PBUF_ALLOC_FAIL, /**< Pbuf alloc failure. */
+ NSS_GRE_STATS_SESSION_DECAP_FORWARD_ENQUEUE_FAIL, /**< Rx forward enqueue failure. */
+ NSS_GRE_STATS_SESSION_ENCAP_FORWARD_ENQUEUE_FAIL, /**< Tx forward enqueue failure. */
+ NSS_GRE_STATS_SESSION_DECAP_TX_FORWARDED, /**< Packets forwarded after decap. */
+ NSS_GRE_STATS_SESSION_ENCAP_RX_RECEIVED, /**< Packets received for encap. */
+ NSS_GRE_STATS_SESSION_ENCAP_RX_DROPPED, /**< Packets dropped while enqueue for encap. */
+ NSS_GRE_STATS_SESSION_ENCAP_RX_LINEAR_FAIL, /**< Packets dropped during encap linearization. */
+ NSS_GRE_STATS_SESSION_EXP_RX_KEY_ERROR, /**< Rx KEY error. */
+ NSS_GRE_STATS_SESSION_EXP_RX_SEQ_ERROR, /**< Rx sequence number error. */
+ NSS_GRE_STATS_SESSION_EXP_RX_CS_ERROR, /**< Rx checksum error. */
+ NSS_GRE_STATS_SESSION_EXP_RX_FLAG_MISMATCH, /**< Rx flag mismatch. */
+ NSS_GRE_STATS_SESSION_EXP_RX_MALFORMED, /**< Rx malformed packet. */
+ NSS_GRE_STATS_SESSION_EXP_RX_INVALID_PROTOCOL, /**< Rx invalid protocol. */
+ NSS_GRE_STATS_SESSION_EXP_RX_NO_HEADROOM, /**< Rx no headroom. */
+ NSS_GRE_STATS_SESSION_DEBUG_MAX, /**< Session debug max. */
+};
+
+/*
+ * GRE session debug statistics
+ */
+struct nss_gre_stats_session_debug {
+ uint64_t stats[NSS_GRE_STATS_SESSION_DEBUG_MAX]; /**< Session debug statistics. */
+ int32_t if_index; /**< Netdevice's ifindex. */
+ uint32_t if_num; /**< NSS interface number. */
+ bool valid; /**< Is node valid ? */
+};
+
+/*
+ * GRE statistics APIs
+ */
+extern void nss_gre_stats_session_debug_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_session_stats_msg *sstats, uint16_t if_num);
+extern void nss_gre_stats_base_debug_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_base_stats_msg *bstats);
+extern void nss_gre_stats_session_register(uint32_t if_num, struct net_device *netdev);
+extern void nss_gre_stats_session_unregister(uint32_t if_num);
+extern void nss_gre_stats_dentry_create(void);
+
+#endif /* __NSS_GRE_STATS_H */
diff --git a/nss_gre_tunnel.c b/nss_gre_tunnel.c
index e515fcc..05605f3 100644
--- a/nss_gre_tunnel.c
+++ b/nss_gre_tunnel.c
@@ -20,12 +20,6 @@
#define NSS_GRE_TUNNEL_TX_TIMEOUT 3000 /* 3 Seconds */
/*
- * Data structures to store GRE Tunnel nss debug stats
- */
-static DEFINE_SPINLOCK(nss_gre_tunnel_session_debug_stats_lock);
-static struct nss_stats_gre_tunnel_session_debug nss_gre_tunnel_session_debug_stats[NSS_MAX_GRE_TUNNEL_SESSIONS];
-
-/*
* Private data structure
*/
static struct nss_gre_tunnel_pvt {
@@ -52,84 +46,6 @@
}
/*
- * nss_gre_tunnel_session_stats_sync()
- * Sync function for statistics
- */
-static void nss_gre_tunnel_session_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_tunnel_stats *stats_msg,
- uint16_t if_num)
-{
- int i;
- struct nss_stats_gre_tunnel_session_debug *s = NULL;
-
- NSS_VERIFY_CTX_MAGIC(nss_ctx);
-
- spin_lock_bh(&nss_gre_tunnel_session_debug_stats_lock);
- for (i = 0; i < NSS_MAX_GRE_TUNNEL_SESSIONS; i++) {
- if (nss_gre_tunnel_session_debug_stats[i].if_num == if_num) {
- s = &nss_gre_tunnel_session_debug_stats[i];
- break;
- }
- }
-
- if (!s) {
- spin_unlock_bh(&nss_gre_tunnel_session_debug_stats_lock);
- nss_warning("%p: Session not found: %u", nss_ctx, if_num);
- return;
- }
-
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_PKTS] += stats_msg->node_stats.rx_packets;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_TX_PKTS] += stats_msg->node_stats.tx_packets;
- for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_QUEUE_0_DROPPED + i] += stats_msg->node_stats.rx_dropped[i];
- }
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_MALFORMED] += stats_msg->rx_malformed;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_INVALID_PROT] += stats_msg->rx_invalid_prot;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_DECAP_QUEUE_FULL] += stats_msg->decap_queue_full;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_SINGLE_REC_DGRAM] += stats_msg->rx_single_rec_dgram;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_INVALID_REC_DGRAM] += stats_msg->rx_invalid_rec_dgram;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_BUFFER_ALLOC_FAIL] += stats_msg->buffer_alloc_fail;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_BUFFER_COPY_FAIL] += stats_msg->buffer_copy_fail;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_OUTFLOW_QUEUE_FULL] += stats_msg->outflow_queue_full;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_DROPPED_HROOM] += stats_msg->rx_dropped_hroom;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_CBUFFER_ALLOC_FAIL] += stats_msg->rx_cbuf_alloc_fail;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_CENQUEUE_FAIL] += stats_msg->rx_cenqueue_fail;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_DECRYPT_DONE] += stats_msg->rx_decrypt_done;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_FORWARD_ENQUEUE_FAIL] += stats_msg->rx_forward_enqueue_fail;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_TX_CBUFFER_ALLOC_FAIL] += stats_msg->tx_cbuf_alloc_fail;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_TX_CENQUEUE_FAIL] += stats_msg->tx_cenqueue_fail;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_DROPPED_TROOM] += stats_msg->rx_dropped_troom;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_TX_FORWARD_ENQUEUE_FAIL] += stats_msg->tx_forward_enqueue_fail;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_TX_CIPHER_DONE] += stats_msg->tx_cipher_done;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_CRYPTO_NOSUPP] += stats_msg->crypto_nosupp;
- s->stats[NSS_STATS_GRE_TUNNEL_SESSION_RX_DROPPED_MH_VERSION] += stats_msg->rx_dropped_mh_ver;
- spin_unlock_bh(&nss_gre_tunnel_session_debug_stats_lock);
-}
-
-/*
- * nss_gre_tunnel_session_debug_stats_get()
- * Get session GRE Tunnel statitics.
- */
-void nss_gre_tunnel_session_debug_stats_get(struct nss_stats_gre_tunnel_session_debug *stats)
-{
- int i;
-
- if (!stats) {
- nss_warning("No memory to copy gre_tunnel session stats");
- return;
- }
-
- spin_lock_bh(&nss_gre_tunnel_session_debug_stats_lock);
- for (i = 0; i < NSS_MAX_GRE_TUNNEL_SESSIONS; i++) {
- if (nss_gre_tunnel_session_debug_stats[i].valid) {
- memcpy(stats, &nss_gre_tunnel_session_debug_stats[i],
- sizeof(struct nss_stats_gre_tunnel_session_debug));
- stats++;
- }
- }
- spin_unlock_bh(&nss_gre_tunnel_session_debug_stats_lock);
-}
-
-/*
* nss_gre_tunnel_handler()
* Handle NSS to HLOS messages for gre_tunnel
*/
@@ -161,7 +77,7 @@
*/
switch (ngtm->cm.type) {
case NSS_GRE_TUNNEL_MSG_STATS:
- nss_gre_tunnel_session_stats_sync(nss_ctx, &ngtm->msg.stats, ncm->interface);
+ nss_gre_tunnel_stats_session_sync(nss_ctx, &ngtm->msg.stats, ncm->interface);
break;
}
@@ -405,7 +321,7 @@
BUG_ON(!nss_gre_tunnel_verify_if_num(if_num));
- spin_lock_bh(&nss_gre_tunnel_session_debug_stats_lock);
+ spin_lock_bh(&nss_gre_tunnel_stats_session_debug_lock);
for (i = 0; i < NSS_MAX_GRE_TUNNEL_SESSIONS; i++) {
if (!nss_gre_tunnel_session_debug_stats[i].valid) {
nss_gre_tunnel_session_debug_stats[i].valid = true;
@@ -414,7 +330,7 @@
break;
}
}
- spin_unlock_bh(&nss_gre_tunnel_session_debug_stats_lock);
+ spin_unlock_bh(&nss_gre_tunnel_stats_session_debug_lock);
if (i == NSS_MAX_GRE_TUNNEL_SESSIONS) {
nss_warning("%p: Cannot find free slot for GRE Tunnel session stats, I/F:%u\n", nss_ctx, if_num);
@@ -433,6 +349,7 @@
nss_top_main.gre_tunnel_msg_callback = ev_cb;
nss_core_register_handler(nss_ctx, if_num, nss_gre_tunnel_handler, app_ctx);
+ nss_gre_tunnel_stats_dentry_create();
return nss_ctx;
}
@@ -449,15 +366,15 @@
BUG_ON(!nss_gre_tunnel_verify_if_num(if_num));
- spin_lock_bh(&nss_gre_tunnel_session_debug_stats_lock);
+ spin_lock_bh(&nss_gre_tunnel_stats_session_debug_lock);
for (i = 0; i < NSS_MAX_GRE_TUNNEL_SESSIONS; i++) {
if (nss_gre_tunnel_session_debug_stats[i].if_num == if_num) {
memset(&nss_gre_tunnel_session_debug_stats[i], 0,
- sizeof(struct nss_stats_gre_tunnel_session_debug));
+ sizeof(struct nss_gre_tunnel_stats_session_debug));
break;
}
}
- spin_unlock_bh(&nss_gre_tunnel_session_debug_stats_lock);
+ spin_unlock_bh(&nss_gre_tunnel_stats_session_debug_lock);
if (i == NSS_MAX_GRE_TUNNEL_SESSIONS) {
nss_warning("%p: Cannot find debug stats for GRE Tunnel session: %d\n", nss_ctx, if_num);
diff --git a/nss_gre_tunnel_stats.c b/nss_gre_tunnel_stats.c
new file mode 100644
index 0000000..a4fd60e
--- /dev/null
+++ b/nss_gre_tunnel_stats.c
@@ -0,0 +1,220 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_tx_rx_common.h"
+#include "nss_gre_tunnel_stats.h"
+
+/*
+ * nss_gre_tunnel_stats_session_debug_str
+ * GRE Tunnel statistics strings for nss session stats
+ */
+static int8_t *nss_gre_tunnel_stats_session_debug_str[NSS_GRE_TUNNEL_STATS_SESSION_MAX] = {
+ "RX_PKTS",
+ "TX_PKTS",
+ "RX_QUEUE_0_DROPPED",
+ "RX_QUEUE_1_DROPPED",
+ "RX_QUEUE_2_DROPPED",
+ "RX_QUEUE_3_DROPPED",
+ "RX_MALFORMED",
+ "RX_INVALID_PROT",
+ "DECAP_QUEUE_FULL",
+ "RX_SINGLE_REC_DGRAM",
+ "RX_INVALID_REC_DGRAM",
+ "BUFFER_ALLOC_FAIL",
+ "BUFFER_COPY_FAIL",
+ "OUTFLOW_QUEUE_FULL",
+ "TX_DROPPED_HROOM",
+ "RX_CBUFFER_ALLOC_FAIL",
+ "RX_CENQUEUE_FAIL",
+ "RX_DECRYPT_DONE",
+ "RX_FORWARD_ENQUEUE_FAIL",
+ "TX_CBUFFER_ALLOC_FAIL",
+ "TX_CENQUEUE_FAIL",
+ "TX_DROPPED_TROOM",
+ "TX_FORWARD_ENQUEUE_FAIL",
+ "TX_CIPHER_DONE",
+ "CRYPTO_NOSUPP",
+ "RX_DROPPED_MH_VERSION",
+};
+
+/*
+ * nss_gre_tunnel_stats_session_sync()
+ * Sync function for GRE Tunnel statistics
+ */
+void nss_gre_tunnel_stats_session_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_tunnel_stats *stats_msg,
+ uint16_t if_num)
+{
+ int i;
+ struct nss_gre_tunnel_stats_session_debug *s = NULL;
+
+ NSS_VERIFY_CTX_MAGIC(nss_ctx);
+
+ spin_lock_bh(&nss_gre_tunnel_stats_session_debug_lock);
+ for (i = 0; i < NSS_MAX_GRE_TUNNEL_SESSIONS; i++) {
+ if (nss_gre_tunnel_session_debug_stats[i].if_num == if_num) {
+ s = &nss_gre_tunnel_session_debug_stats[i];
+ break;
+ }
+ }
+
+ if (!s) {
+ spin_unlock_bh(&nss_gre_tunnel_stats_session_debug_lock);
+ nss_warning("%p: Session not found: %u", nss_ctx, if_num);
+ return;
+ }
+
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_PKTS] += stats_msg->node_stats.rx_packets;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_TX_PKTS] += stats_msg->node_stats.tx_packets;
+ for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_QUEUE_0_DROPPED + i] += stats_msg->node_stats.rx_dropped[i];
+ }
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_MALFORMED] += stats_msg->rx_malformed;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_INVALID_PROT] += stats_msg->rx_invalid_prot;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_DECAP_QUEUE_FULL] += stats_msg->decap_queue_full;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_SINGLE_REC_DGRAM] += stats_msg->rx_single_rec_dgram;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_INVALID_REC_DGRAM] += stats_msg->rx_invalid_rec_dgram;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_BUFFER_ALLOC_FAIL] += stats_msg->buffer_alloc_fail;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_BUFFER_COPY_FAIL] += stats_msg->buffer_copy_fail;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_OUTFLOW_QUEUE_FULL] += stats_msg->outflow_queue_full;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_DROPPED_HROOM] += stats_msg->rx_dropped_hroom;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_CBUFFER_ALLOC_FAIL] += stats_msg->rx_cbuf_alloc_fail;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_CENQUEUE_FAIL] += stats_msg->rx_cenqueue_fail;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_DECRYPT_DONE] += stats_msg->rx_decrypt_done;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_FORWARD_ENQUEUE_FAIL] += stats_msg->rx_forward_enqueue_fail;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_TX_CBUFFER_ALLOC_FAIL] += stats_msg->tx_cbuf_alloc_fail;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_TX_CENQUEUE_FAIL] += stats_msg->tx_cenqueue_fail;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_DROPPED_TROOM] += stats_msg->rx_dropped_troom;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_TX_FORWARD_ENQUEUE_FAIL] += stats_msg->tx_forward_enqueue_fail;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_TX_CIPHER_DONE] += stats_msg->tx_cipher_done;
+ s->stats[NSS_GRE_TUNNEL_STATS_SESSION_CRYPTO_NOSUPP] += stats_msg->crypto_nosupp;
+ spin_unlock_bh(&nss_gre_tunnel_stats_session_debug_lock);
+}
+
+/*
+ * nss_gre_tunnel_stats_session_debug_get()
+ * Get session GRE Tunnel statitics.
+ */
+static void nss_gre_tunnel_stats_session_debug_get(struct nss_gre_tunnel_stats_session_debug *stats)
+{
+ int i;
+
+ if (!stats) {
+ nss_warning("No memory to copy gre_tunnel session stats");
+ return;
+ }
+
+ spin_lock_bh(&nss_gre_tunnel_stats_session_debug_lock);
+ for (i = 0; i < NSS_MAX_GRE_TUNNEL_SESSIONS; i++) {
+ if (nss_gre_tunnel_session_debug_stats[i].valid) {
+ memcpy(stats, &nss_gre_tunnel_session_debug_stats[i],
+ sizeof(struct nss_gre_tunnel_stats_session_debug));
+ stats++;
+ }
+ }
+ spin_unlock_bh(&nss_gre_tunnel_stats_session_debug_lock);
+}
+
+/*
+ * nss_gre_tunnel_stats_read()
+ * Read GRE Tunnel session statistics
+ */
+static ssize_t nss_gre_tunnel_stats_read(struct file *fp, char __user *ubuf,
+ size_t sz, loff_t *ppos)
+{
+ uint32_t max_output_lines = 2 + (NSS_MAX_GRE_TUNNEL_SESSIONS
+ * (NSS_GRE_TUNNEL_STATS_SESSION_MAX + 2)) + 2;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ struct net_device *dev;
+ int id, i;
+ struct nss_gre_tunnel_stats_session_debug *gre_tunnel_session_stats = NULL;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ gre_tunnel_session_stats = kzalloc((sizeof(struct nss_gre_tunnel_stats_session_debug)
+ * NSS_MAX_GRE_TUNNEL_SESSIONS), GFP_KERNEL);
+ if (unlikely(gre_tunnel_session_stats == NULL)) {
+ nss_warning("Could not allocate memory for populating GRE Tunnel stats");
+ kfree(lbuf);
+ return 0;
+ }
+
+ /*
+ * Get all stats
+ */
+ nss_gre_tunnel_stats_session_debug_get(gre_tunnel_session_stats);
+
+ /*
+ * Session stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\nGRE Tunnel session stats start:\n\n");
+
+ for (id = 0; id < NSS_MAX_GRE_TUNNEL_SESSIONS; id++) {
+ if (!gre_tunnel_session_stats[id].valid)
+ break;
+
+ dev = dev_get_by_index(&init_net, gre_tunnel_session_stats[id].if_index);
+ if (likely(dev)) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%d. nss interface id=%d, netdevice=%s\n",
+ id, gre_tunnel_session_stats[id].if_num,
+ dev->name);
+ dev_put(dev);
+ } else {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%d. nss interface id=%d\n", id,
+ gre_tunnel_session_stats[id].if_num);
+ }
+
+ for (i = 0; i < NSS_GRE_TUNNEL_STATS_SESSION_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %llu\n",
+ nss_gre_tunnel_stats_session_debug_str[i],
+ gre_tunnel_session_stats[id].stats[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\nGRE Tunnel session stats end\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
+
+ kfree(gre_tunnel_session_stats);
+ kfree(lbuf);
+ return bytes_read;
+}
+
+/*
+ * nss_gre_tunnel_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(gre_tunnel)
+
+/*
+ * nss_gre_tunnel_stats_dentry_create()
+ * Create gre tunnel statistics debug entry.
+ */
+void nss_gre_tunnel_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("gre_tunnel", &nss_gre_tunnel_stats_ops);
+}
+
diff --git a/nss_gre_tunnel_stats.h b/nss_gre_tunnel_stats.h
index 623f11d..f53eb38 100644
--- a/nss_gre_tunnel_stats.h
+++ b/nss_gre_tunnel_stats.h
@@ -1,6 +1,6 @@
/*
******************************************************************************
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -14,50 +14,62 @@
* ****************************************************************************
*/
+#ifndef __NSS_GRE_TUNNEL_STATS_H
+#define __NSS_GRE_TUNNEL_STATS_H
+
/*
* GRE Tunnel session debug statistic counters
*/
-enum nss_stats_gre_tunnel_session {
- NSS_STATS_GRE_TUNNEL_SESSION_RX_PKTS,
- NSS_STATS_GRE_TUNNEL_SESSION_TX_PKTS,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_QUEUE_0_DROPPED,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_QUEUE_1_DROPPED,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_QUEUE_2_DROPPED,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_QUEUE_3_DROPPED,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_MALFORMED,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_INVALID_PROT,
- NSS_STATS_GRE_TUNNEL_SESSION_DECAP_QUEUE_FULL,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_SINGLE_REC_DGRAM,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_INVALID_REC_DGRAM,
- NSS_STATS_GRE_TUNNEL_SESSION_BUFFER_ALLOC_FAIL,
- NSS_STATS_GRE_TUNNEL_SESSION_BUFFER_COPY_FAIL,
- NSS_STATS_GRE_TUNNEL_SESSION_OUTFLOW_QUEUE_FULL,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_DROPPED_HROOM,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_CBUFFER_ALLOC_FAIL,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_CENQUEUE_FAIL,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_DECRYPT_DONE,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_FORWARD_ENQUEUE_FAIL,
- NSS_STATS_GRE_TUNNEL_SESSION_TX_CBUFFER_ALLOC_FAIL,
- NSS_STATS_GRE_TUNNEL_SESSION_TX_CENQUEUE_FAIL,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_DROPPED_TROOM,
- NSS_STATS_GRE_TUNNEL_SESSION_TX_FORWARD_ENQUEUE_FAIL,
- NSS_STATS_GRE_TUNNEL_SESSION_TX_CIPHER_DONE,
- NSS_STATS_GRE_TUNNEL_SESSION_CRYPTO_NOSUPP,
- NSS_STATS_GRE_TUNNEL_SESSION_RX_DROPPED_MH_VERSION,
- NSS_STATS_GRE_TUNNEL_SESSION_MAX,
+enum nss_gre_tunnel_stats_session {
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_PKTS,
+ NSS_GRE_TUNNEL_STATS_SESSION_TX_PKTS,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_QUEUE_0_DROPPED,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_QUEUE_1_DROPPED,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_QUEUE_2_DROPPED,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_QUEUE_3_DROPPED,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_MALFORMED,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_INVALID_PROT,
+ NSS_GRE_TUNNEL_STATS_SESSION_DECAP_QUEUE_FULL,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_SINGLE_REC_DGRAM,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_INVALID_REC_DGRAM,
+ NSS_GRE_TUNNEL_STATS_SESSION_BUFFER_ALLOC_FAIL,
+ NSS_GRE_TUNNEL_STATS_SESSION_BUFFER_COPY_FAIL,
+ NSS_GRE_TUNNEL_STATS_SESSION_OUTFLOW_QUEUE_FULL,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_DROPPED_HROOM,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_CBUFFER_ALLOC_FAIL,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_CENQUEUE_FAIL,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_DECRYPT_DONE,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_FORWARD_ENQUEUE_FAIL,
+ NSS_GRE_TUNNEL_STATS_SESSION_TX_CBUFFER_ALLOC_FAIL,
+ NSS_GRE_TUNNEL_STATS_SESSION_TX_CENQUEUE_FAIL,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_DROPPED_TROOM,
+ NSS_GRE_TUNNEL_STATS_SESSION_TX_FORWARD_ENQUEUE_FAIL,
+ NSS_GRE_TUNNEL_STATS_SESSION_TX_CIPHER_DONE,
+ NSS_GRE_TUNNEL_STATS_SESSION_CRYPTO_NOSUPP,
+ NSS_GRE_TUNNEL_STATS_SESSION_RX_DROPPED_MH_VERSION,
+ NSS_GRE_TUNNEL_STATS_SESSION_MAX,
};
/*
* GRE Tunnel session debug statistics
*/
-struct nss_stats_gre_tunnel_session_debug {
- uint64_t stats[NSS_STATS_GRE_TUNNEL_SESSION_MAX];
+struct nss_gre_tunnel_stats_session_debug {
+ uint64_t stats[NSS_GRE_TUNNEL_STATS_SESSION_MAX];
int32_t if_index;
uint32_t if_num; /* nss interface number */
bool valid;
};
/*
- * Stats APIs provided by nss_gre_tunnel.c
+ * Data structures to store GRE Tunnel nss debug stats
*/
-extern void nss_gre_tunnel_session_debug_stats_get(struct nss_stats_gre_tunnel_session_debug *s);
+static DEFINE_SPINLOCK(nss_gre_tunnel_stats_session_debug_lock);
+static struct nss_gre_tunnel_stats_session_debug nss_gre_tunnel_session_debug_stats[NSS_MAX_GRE_TUNNEL_SESSIONS];
+
+/*
+ * GRE Tunnel statistics APIs
+ */
+extern void nss_gre_tunnel_stats_session_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_tunnel_stats *stats_msg, uint16_t if_num);
+extern void nss_gre_tunnel_stats_dentry_create(void);
+
+#endif /* __NSS_GRE_TUNNEL_STATS_H */
diff --git a/nss_hlos_if.h b/nss_hlos_if.h
index 401f12e..72a9896 100644
--- a/nss_hlos_if.h
+++ b/nss_hlos_if.h
@@ -48,52 +48,6 @@
};
/*
- * ETH_RX
-*/
-
-/*
- * Request/Response types
- */
-enum nss_eth_rx_metadata_types {
- NSS_RX_METADATA_TYPE_ETH_RX_STATS_SYNC,
- NSS_METADATA_TYPE_ETH_RX_MAX,
-};
-
-/*
- * Exception events from bridge/route handler
- */
-enum exception_events_eth_rx {
- NSS_EXCEPTION_EVENT_ETH_RX_UNKNOWN_L3_PROTOCOL,
- NSS_EXCEPTION_EVENT_ETH_RX_ETH_HDR_MISSING,
- NSS_EXCEPTION_EVENT_ETH_RX_VLAN_MISSING,
- NSS_EXCEPTION_EVENT_ETH_RX_TRUSTSEC_HDR_MISSING,
- NSS_EXCEPTION_EVENT_ETH_RX_MAX,
-};
-
-/*
- * The NSS eth_rx node stats structure.
- */
-struct nss_eth_rx_node_sync {
- struct nss_cmn_node_stats node_stats;
- /* Common node stats for ETH_RX */
- uint32_t total_ticks; /* Total clock ticks spend inside the eth_rx */
- uint32_t worst_case_ticks; /* Worst case iteration of the eth_rx in ticks */
- uint32_t iterations; /* Number of iterations around the eth_rx */
- uint32_t exception_events[NSS_EXCEPTION_EVENT_ETH_RX_MAX];
- /* Number of ETH_RX exception events */
-};
-
-/*
- * Message structure to send/receive eth_rx commands
- */
-struct nss_eth_rx_msg {
- struct nss_cmn_msg cm; /* Message Header */
- union {
- struct nss_eth_rx_node_sync node_sync; /* Message: node statistics sync */
- } msg;
-};
-
-/*
* C2C message structures
*/
@@ -261,44 +215,6 @@
};
/*
- * lso_rx_node statistics.
- */
-struct nss_lso_rx_stats_sync {
- struct nss_cmn_node_stats node_stats;
-
- uint32_t tx_dropped; /* Number of packets dropped because lso_rx transmit queue is full */
- uint32_t dropped; /* Total of packets dropped by the node internally */
- uint32_t pbuf_alloc_fail; /* Count number of pbuf alloc fails */
- uint32_t pbuf_reference_fail; /* Count number of pbuf ref fails */
-
- /*
- * If we're generating per-packet statistics then we count total lso_rx processing ticks
- * worst-case ticks and the number of iterations around the lso_rx handler that we take.
- */
- uint32_t total_ticks; /* Total clock ticks spend inside the lso_rx handler */
- uint32_t worst_case_ticks;
- /* Worst case iteration of the lso_rx handler in ticks */
- uint32_t iterations; /* Number of iterations around the lso_rx handler */
-};
-
-/*
- * Message types for lso_rx
- */
-enum nss_lso_rx_metadata_types {
- NSS_LSO_RX_STATS_SYNC_MSG, /* Message type - stats sync message */
-};
-
-/*
- * Message structure to send receive LSO_RX commands
- */
-struct nss_lso_rx_msg {
- struct nss_cmn_msg cm; /* Message header */
- union {
- struct nss_lso_rx_stats_sync stats_sync; /* Stats sub-message */
- } msg;
-};
-
-/*
* H2N Buffer Types
*/
#define H2N_BUFFER_EMPTY 0
diff --git a/nss_ipv4.c b/nss_ipv4.c
index e6dfe1a..6126dcb 100644
--- a/nss_ipv4.c
+++ b/nss_ipv4.c
@@ -21,6 +21,7 @@
#include <linux/sysctl.h>
#include "nss_tx_rx_common.h"
#include "nss_dscp_map.h"
+#include "nss_ipv4_stats.h"
#define NSS_IPV4_TX_MSG_TIMEOUT 1000 /* 1 sec timeout for IPv4 messages */
@@ -69,92 +70,6 @@
}
/*
- * nss_ipv4_driver_conn_sync_update()
- * Update driver specific information from the messsage.
- */
-static void nss_ipv4_driver_conn_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync *nirs)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
-
- /*
- * Update statistics maintained by NSS driver
- */
- spin_lock_bh(&nss_top->stats_lock);
- nss_top->stats_ipv4[NSS_STATS_IPV4_ACCELERATED_RX_PKTS] += nirs->flow_rx_packet_count + nirs->return_rx_packet_count;
- nss_top->stats_ipv4[NSS_STATS_IPV4_ACCELERATED_RX_BYTES] += nirs->flow_rx_byte_count + nirs->return_rx_byte_count;
- nss_top->stats_ipv4[NSS_STATS_IPV4_ACCELERATED_TX_PKTS] += nirs->flow_tx_packet_count + nirs->return_tx_packet_count;
- nss_top->stats_ipv4[NSS_STATS_IPV4_ACCELERATED_TX_BYTES] += nirs->flow_tx_byte_count + nirs->return_tx_byte_count;
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
- * nss_ipv4_driver_conn_sync_many_update()
- * Update driver specific information from the conn_sync_many messsage.
- */
-static void nss_ipv4_driver_conn_sync_many_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync_many_msg *nicsm)
-{
- int i;
-
- /*
- * Sanity check for the stats count
- */
- if (nicsm->count * sizeof(struct nss_ipv4_conn_sync) >= nicsm->size) {
- nss_warning("%p: stats sync count %u exceeds the size of this msg %u", nss_ctx, nicsm->count, nicsm->size);
- return;
- }
-
- for (i = 0; i < nicsm->count; i++) {
- nss_ipv4_driver_conn_sync_update(nss_ctx, &nicsm->conn_sync[i]);
- }
-}
-
-/*
- * nss_ipv4_driver_node_sync_update)
- * Update driver specific information from the messsage.
- */
-static void nss_ipv4_driver_node_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_node_sync *nins)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- int i;
-
- /*
- * Update statistics maintained by NSS driver
- */
- spin_lock_bh(&nss_top->stats_lock);
- nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nins->node_stats.rx_packets;
- nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nins->node_stats.rx_bytes;
- nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nins->node_stats.tx_packets;
- nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nins->node_stats.tx_bytes;
-
- for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
- nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nins->node_stats.rx_dropped[i];
- }
-
- nss_top->stats_ipv4[NSS_STATS_IPV4_CONNECTION_CREATE_REQUESTS] += nins->ipv4_connection_create_requests;
- nss_top->stats_ipv4[NSS_STATS_IPV4_CONNECTION_CREATE_COLLISIONS] += nins->ipv4_connection_create_collisions;
- nss_top->stats_ipv4[NSS_STATS_IPV4_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv4_connection_create_invalid_interface;
- nss_top->stats_ipv4[NSS_STATS_IPV4_CONNECTION_DESTROY_REQUESTS] += nins->ipv4_connection_destroy_requests;
- nss_top->stats_ipv4[NSS_STATS_IPV4_CONNECTION_DESTROY_MISSES] += nins->ipv4_connection_destroy_misses;
- nss_top->stats_ipv4[NSS_STATS_IPV4_CONNECTION_HASH_HITS] += nins->ipv4_connection_hash_hits;
- nss_top->stats_ipv4[NSS_STATS_IPV4_CONNECTION_HASH_REORDERS] += nins->ipv4_connection_hash_reorders;
- nss_top->stats_ipv4[NSS_STATS_IPV4_CONNECTION_FLUSHES] += nins->ipv4_connection_flushes;
- nss_top->stats_ipv4[NSS_STATS_IPV4_CONNECTION_EVICTIONS] += nins->ipv4_connection_evictions;
- nss_top->stats_ipv4[NSS_STATS_IPV4_FRAGMENTATIONS] += nins->ipv4_fragmentations;
- nss_top->stats_ipv4[NSS_STATS_IPV4_MC_CONNECTION_CREATE_REQUESTS] += nins->ipv4_mc_connection_create_requests;
- nss_top->stats_ipv4[NSS_STATS_IPV4_MC_CONNECTION_UPDATE_REQUESTS] += nins->ipv4_mc_connection_update_requests;
- nss_top->stats_ipv4[NSS_STATS_IPV4_MC_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv4_mc_connection_create_invalid_interface;
- nss_top->stats_ipv4[NSS_STATS_IPV4_MC_CONNECTION_DESTROY_REQUESTS] += nins->ipv4_mc_connection_destroy_requests;
- nss_top->stats_ipv4[NSS_STATS_IPV4_MC_CONNECTION_DESTROY_MISSES] += nins->ipv4_mc_connection_destroy_misses;
- nss_top->stats_ipv4[NSS_STATS_IPV4_MC_CONNECTION_FLUSHES] += nins->ipv4_mc_connection_flushes;
- nss_top->stats_ipv4[NSS_STATS_IPV4_DROPPED_BY_RULE] += nins->ipv4_dropped_by_rule;
-
- for (i = 0; i < NSS_EXCEPTION_EVENT_IPV4_MAX; i++) {
- nss_top->stats_if_exception_ipv4[i] += nins->exception_events[i];
- }
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
* nss_ipv4_rx_msg_handler()
* Handle NSS -> HLOS messages for IPv4 bridge/route
*/
@@ -188,21 +103,21 @@
/*
* Update driver statistics on node sync.
*/
- nss_ipv4_driver_node_sync_update(nss_ctx, &nim->msg.node_stats);
+ nss_ipv4_stats_node_sync(nss_ctx, &nim->msg.node_stats);
break;
case NSS_IPV4_RX_CONN_STATS_SYNC_MSG:
/*
* Update driver statistics on connection sync.
*/
- nss_ipv4_driver_conn_sync_update(nss_ctx, &nim->msg.conn_stats);
+ nss_ipv4_stats_conn_sync(nss_ctx, &nim->msg.conn_stats);
break;
case NSS_IPV4_TX_CONN_STATS_SYNC_MANY_MSG:
/*
* Update driver statistics on connection sync many.
*/
- nss_ipv4_driver_conn_sync_many_update(nss_ctx, &nim->msg.conn_stats_many);
+ nss_ipv4_stats_conn_sync_many(nss_ctx, &nim->msg.conn_stats_many);
ncm->cb = (nss_ptr_t)nss_ipv4_conn_sync_many_msg_cb;
break;
}
@@ -507,6 +422,8 @@
if (nss_core_register_handler(nss_ctx, NSS_IPV4_RX_INTERFACE, nss_ipv4_rx_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) {
nss_warning("IPv4 handler failed to register");
}
+
+ nss_ipv4_stats_dentry_create();
}
/*
diff --git a/nss_ipv4_reasm.c b/nss_ipv4_reasm.c
index 80a230f..6837544 100644
--- a/nss_ipv4_reasm.c
+++ b/nss_ipv4_reasm.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -19,39 +19,8 @@
* NSS IPv4 Reassembly APIs
*/
#include "nss_tx_rx_common.h"
-
-/*
- * nss_ipv4_reasm_stats_sync()
- * Update driver specific information from the messsage.
- */
-static void nss_ipv4_reasm_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_reasm_stats_sync *nirs)
-{
- int i;
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
-
- spin_lock_bh(&nss_top->stats_lock);
-
- /*
- * Common node stats
- */
- nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nirs->node_stats.rx_packets;
- nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nirs->node_stats.rx_bytes;
- nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nirs->node_stats.tx_packets;
- nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nirs->node_stats.tx_bytes;
-
- for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
- nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nirs->node_stats.rx_dropped[0];
- }
-
- /*
- * IPv4 reasm node stats
- */
- nss_top->stats_ipv4_reasm[NSS_STATS_IPV4_REASM_EVICTIONS] += nirs->ipv4_reasm_evictions;
- nss_top->stats_ipv4_reasm[NSS_STATS_IPV4_REASM_ALLOC_FAILS] += nirs->ipv4_reasm_alloc_fails;
- nss_top->stats_ipv4_reasm[NSS_STATS_IPV4_REASM_TIMEOUTS] += nirs->ipv4_reasm_timeouts;
-
- spin_unlock_bh(&nss_top->stats_lock);
-}
+#include "nss_stats.h"
+#include "nss_ipv4_reasm_stats.h"
/*
* nss_ipv4_reasm_msg_handler()
@@ -99,4 +68,6 @@
if (nss_core_register_handler(nss_ctx, NSS_IPV4_REASM_INTERFACE, nss_ipv4_reasm_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) {
nss_warning("IPv4 reasm handler failed to register");
}
+
+ nss_ipv4_reasm_stats_dentry_create();
}
diff --git a/nss_ipv4_reasm_stats.c b/nss_ipv4_reasm_stats.c
new file mode 100644
index 0000000..7d2791f
--- /dev/null
+++ b/nss_ipv4_reasm_stats.c
@@ -0,0 +1,135 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_ipv4_reasm_stats.h"
+
+/*
+ * IPv4 reassembly stats strings
+ */
+static int8_t *nss_ipv4_reasm_stats_str[NSS_IPV4_REASM_STATS_MAX] = {
+ "evictions",
+ "alloc_fails",
+ "timeouts",
+};
+
+uint64_t nss_ipv4_reasm_stats[NSS_IPV4_REASM_STATS_MAX]; /* IPv4 reasm statistics */
+
+/*
+ * nss_ipv4_reasm_stats_read()
+ * Read IPV4 reassembly stats
+ */
+static ssize_t nss_ipv4_reasm_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_IPV4_REASM_STATS_MAX + 3) + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ stats_shadow = kzalloc(NSS_IPV4_REASM_STATS_MAX * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "ipv4 reasm stats start:\n\n");
+
+ size_wr = nss_stats_fill_common_stats(NSS_IPV4_REASM_INTERFACE, lbuf, size_wr, size_al);
+
+ /*
+ * IPv4 reasm node stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 reasm node stats:\n\n");
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_IPV4_REASM_STATS_MAX); i++) {
+ stats_shadow[i] = nss_ipv4_reasm_stats[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_IPV4_REASM_STATS_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_ipv4_reasm_stats_str[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 reasm stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_ipv4_reasm_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4_reasm)
+
+/*
+ * nss_ipv4_reasm_stats_dentry_create()
+ * Create the IPv4 reasm statistics debug entry
+ */
+void nss_ipv4_reasm_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("ipv4_reasm", &nss_ipv4_reasm_stats_ops);
+}
+
+/*
+ * nss_ipv4_reasm_stats_sync()
+ * Update driver specific information from the messsage.
+ */
+void nss_ipv4_reasm_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_reasm_stats_sync *nirs)
+{
+ int i;
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ /*
+ * Common node stats
+ */
+ nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nirs->node_stats.rx_packets;
+ nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nirs->node_stats.rx_bytes;
+ nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nirs->node_stats.tx_packets;
+ nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nirs->node_stats.tx_bytes;
+
+ for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
+ nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nirs->node_stats.rx_dropped[i];
+ }
+
+ /*
+ * IPv4 reasm node stats
+ */
+ nss_ipv4_reasm_stats[NSS_IPV4_REASM_STATS_EVICTIONS] += nirs->ipv4_reasm_evictions;
+ nss_ipv4_reasm_stats[NSS_IPV4_REASM_STATS_ALLOC_FAILS] += nirs->ipv4_reasm_alloc_fails;
+ nss_ipv4_reasm_stats[NSS_IPV4_REASM_STATS_TIMEOUTS] += nirs->ipv4_reasm_timeouts;
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
diff --git a/nss_ipv4_reasm_stats.h b/nss_ipv4_reasm_stats.h
new file mode 100644
index 0000000..73bb031
--- /dev/null
+++ b/nss_ipv4_reasm_stats.h
@@ -0,0 +1,39 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#ifndef __NSS_IPV4_REASM_STATS_H
+#define __NSS_IPV4_REASM_STATS_H
+
+/*
+ * IPV4 reasm node statistics
+ */
+enum nss_ipv4_reasm_stats_types {
+ NSS_IPV4_REASM_STATS_EVICTIONS = 0,
+ /* Number of evicted fragment queues due to set memory threshold */
+ NSS_IPV4_REASM_STATS_ALLOC_FAILS,
+ /* Number of fragment queue allocation failures */
+ NSS_IPV4_REASM_STATS_TIMEOUTS,
+ /* Number of expired fragment queues */
+ NSS_IPV4_REASM_STATS_MAX,
+};
+
+/*
+ * IPV4 reasm statistics APIs
+ */
+extern void nss_ipv4_reasm_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_reasm_stats_sync *nirs);
+extern void nss_ipv4_reasm_stats_dentry_create(void);
+
+#endif /* __NSS_IPV4_REASM_STATS_H */
diff --git a/nss_ipv4_stats.c b/nss_ipv4_stats.c
new file mode 100644
index 0000000..7317f6a
--- /dev/null
+++ b/nss_ipv4_stats.c
@@ -0,0 +1,313 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include <nss_ipv4.h>
+#include "nss_ipv4_stats.h"
+
+/*
+ * nss_ipv4_exception_stats_str
+ * Interface stats strings for ipv4 exceptions
+ */
+static int8_t *nss_ipv4_exception_stats_str[NSS_IPV4_EXCEPTION_EVENT_MAX] = {
+ "IPV4_ICMP_HEADER_INCOMPLETE",
+ "IPV4_ICMP_UNHANDLED_TYPE",
+ "IPV4_ICMP_IPV4_HEADER_INCOMPLETE",
+ "IPV4_ICMP_IPV4_UDP_HEADER_INCOMPLETE",
+ "IPV4_ICMP_IPV4_TCP_HEADER_INCOMPLETE",
+ "IPV4_ICMP_SIPV4_UNKNOWN_PROTOCOL",
+ "IPV4_ICMP_NO_ICME",
+ "IPV4_ICMP_FLUSH_TO_HOST",
+ "IPV4_TCP_HEADER_INCOMPLETE",
+ "IPV4_TCP_NO_ICME",
+ "IPV4_TCP_IP_OPTION",
+ "IPV4_TCP_IP_FRAGMENT",
+ "IPV4_TCP_SMALL_TTL",
+ "IPV4_TCP_NEEDS_FRAGMENTATION",
+ "IPV4_TCP_FLAGS",
+ "IPV4_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
+ "IPV4_TCP_SMALL_DATA_OFFS",
+ "IPV4_TCP_BAD_SACK",
+ "IPV4_TCP_BIG_DATA_OFFS",
+ "IPV4_TCP_SEQ_BEFORE_LEFT_EDGE",
+ "IPV4_TCP_ACK_EXCEEDS_RIGHT_EDGE",
+ "IPV4_TCP_ACK_BEFORE_LEFT_EDGE",
+ "IPV4_UDP_HEADER_INCOMPLETE",
+ "IPV4_UDP_NO_ICME",
+ "IPV4_UDP_IP_OPTION",
+ "IPV4_UDP_IP_FRAGMENT",
+ "IPV4_UDP_SMALL_TTL",
+ "IPV4_UDP_NEEDS_FRAGMENTATION",
+ "IPV4_WRONG_TARGET_MAC",
+ "IPV4_HEADER_INCOMPLETE",
+ "IPV4_BAD_TOTAL_LENGTH",
+ "IPV4_BAD_CHECKSUM",
+ "IPV4_NON_INITIAL_FRAGMENT",
+ "IPV4_DATAGRAM_INCOMPLETE",
+ "IPV4_OPTIONS_INCOMPLETE",
+ "IPV4_UNKNOWN_PROTOCOL",
+ "IPV4_ESP_HEADER_INCOMPLETE",
+ "IPV4_ESP_NO_ICME",
+ "IPV4_ESP_IP_OPTION",
+ "IPV4_ESP_IP_FRAGMENT",
+ "IPV4_ESP_SMALL_TTL",
+ "IPV4_ESP_NEEDS_FRAGMENTATION",
+ "IPV4_INGRESS_VID_MISMATCH",
+ "IPV4_INGRESS_VID_MISSING",
+ "IPV4_6RD_NO_ICME",
+ "IPV4_6RD_IP_OPTION",
+ "IPV4_6RD_IP_FRAGMENT",
+ "IPV4_6RD_NEEDS_FRAGMENTATION",
+ "IPV4_DSCP_MARKING_MISMATCH",
+ "IPV4_VLAN_MARKING_MISMATCH",
+ "IPV4_DEPRECATED",
+ "IPV4_GRE_HEADER_INCOMPLETE",
+ "IPV4_GRE_NO_ICME",
+ "IPV4_GRE_IP_OPTION",
+ "IPV4_GRE_IP_FRAGMENT",
+ "IPV4_GRE_SMALL_TTL",
+ "IPV4_GRE_NEEDS_FRAGMENTATION",
+ "IPV4_PPTP_GRE_SESSION_MATCH_FAIL",
+ "IPV4_PPTP_GRE_INVALID_PROTO",
+ "IPV4_PPTP_GRE_NO_CME",
+ "IPV4_PPTP_GRE_IP_OPTION",
+ "IPV4_PPTP_GRE_IP_FRAGMENT",
+ "IPV4_PPTP_GRE_SMALL_TTL",
+ "IPV4_PPTP_GRE_NEEDS_FRAGMENTATION",
+ "IPV4_DESTROY",
+ "IPV4_FRAG_DF_SET",
+ "IPV4_FRAG_FAIL",
+ "IPV4_ICMP_IPV4_UDPLITE_HEADER_INCOMPLETE",
+ "IPV4_UDPLITE_HEADER_INCOMPLETE",
+ "IPV4_UDPLITE_NO_ICME",
+ "IPV4_UDPLITE_IP_OPTION",
+ "IPV4_UDPLITE_IP_FRAGMENT",
+ "IPV4_UDPLITE_SMALL_TTL",
+ "IPV4_UDPLITE_NEEDS_FRAGMENTATION",
+ "IPV4_MC_UDP_NO_ICME",
+ "IPV4_MC_MEM_ALLOC_FAILURE",
+ "IPV4_MC_UPDATE_FAILURE",
+ "IPV4_MC_PBUF_ALLOC_FAILURE"
+};
+
+uint64_t nss_ipv4_stats[NSS_IPV4_STATS_MAX];
+uint64_t nss_ipv4_exception_stats[NSS_IPV4_EXCEPTION_EVENT_MAX];
+
+/*
+ * nss_ipv4_stats_str
+ * IPv4 stats strings
+ */
+static int8_t *nss_ipv4_stats_str[NSS_IPV4_STATS_MAX] = {
+ "rx_pkts",
+ "rx_bytes",
+ "tx_pkts",
+ "tx_bytes",
+ "create_requests",
+ "create_collisions",
+ "create_invalid_interface",
+ "destroy_requests",
+ "destroy_misses",
+ "hash_hits",
+ "hash_reorders",
+ "flushes",
+ "evictions",
+ "fragmentations",
+ "by_rule_drops",
+ "mc_create_requests",
+ "mc_update_requests",
+ "mc_create_invalid_interface",
+ "mc_destroy_requests",
+ "mc_destroy_misses",
+ "mc_flushes",
+};
+
+/*
+ * nss_ipv4_stats_read()
+ * Read IPV4 stats
+ */
+static ssize_t nss_ipv4_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_IPV4_STATS_MAX + 3) + (NSS_IPV4_EXCEPTION_EVENT_MAX + 3) + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ /*
+ * Note: The assumption here is that exception event count is larger than other statistics count for IPv4
+ */
+ stats_shadow = kzalloc(NSS_IPV4_EXCEPTION_EVENT_MAX * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "ipv4 stats start:\n\n");
+
+ size_wr = nss_stats_fill_common_stats(NSS_IPV4_RX_INTERFACE, lbuf, size_wr, size_al);
+
+ /*
+ * IPv4 node stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 node stats:\n\n");
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_IPV4_STATS_MAX); i++) {
+ stats_shadow[i] = nss_ipv4_stats[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_IPV4_STATS_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_ipv4_stats_str[i], stats_shadow[i]);
+ }
+
+ /*
+ * Exception stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 exception stats:\n\n");
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_IPV4_EXCEPTION_EVENT_MAX); i++) {
+ stats_shadow[i] = nss_ipv4_exception_stats[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_IPV4_EXCEPTION_EVENT_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_ipv4_exception_stats_str[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_ipv4_stats_conn_sync()
+ * Update driver specific information from the messsage.
+ */
+void nss_ipv4_stats_conn_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync *nirs)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+
+ /*
+ * Update statistics maintained by NSS driver
+ */
+ spin_lock_bh(&nss_top->stats_lock);
+ nss_ipv4_stats[NSS_IPV4_STATS_ACCELERATED_RX_PKTS] += nirs->flow_rx_packet_count + nirs->return_rx_packet_count;
+ nss_ipv4_stats[NSS_IPV4_STATS_ACCELERATED_RX_BYTES] += nirs->flow_rx_byte_count + nirs->return_rx_byte_count;
+ nss_ipv4_stats[NSS_IPV4_STATS_ACCELERATED_TX_PKTS] += nirs->flow_tx_packet_count + nirs->return_tx_packet_count;
+ nss_ipv4_stats[NSS_IPV4_STATS_ACCELERATED_TX_BYTES] += nirs->flow_tx_byte_count + nirs->return_tx_byte_count;
+ spin_unlock_bh(&nss_top->stats_lock);
+}
+
+/*
+ * nss_ipv4_stats_conn_sync_many()
+ * Update driver specific information from the conn_sync_many messsage.
+ */
+void nss_ipv4_stats_conn_sync_many(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync_many_msg *nicsm)
+{
+ int i;
+
+ /*
+ * Sanity check for the stats count
+ */
+ if (nicsm->count * sizeof(struct nss_ipv4_conn_sync) >= nicsm->size) {
+ nss_warning("%p: stats sync count %u exceeds the size of this msg %u", nss_ctx, nicsm->count, nicsm->size);
+ return;
+ }
+
+ for (i = 0; i < nicsm->count; i++) {
+ nss_ipv4_stats_conn_sync(nss_ctx, &nicsm->conn_sync[i]);
+ }
+}
+
+/*
+ * nss_ipv4_stats_node_sync()
+ * Update driver specific information from the messsage.
+ */
+void nss_ipv4_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_node_sync *nins)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ uint32_t i;
+
+ /*
+ * Update statistics maintained by NSS driver
+ */
+ spin_lock_bh(&nss_top->stats_lock);
+ nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nins->node_stats.rx_packets;
+ nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nins->node_stats.rx_bytes;
+ nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nins->node_stats.tx_packets;
+ nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nins->node_stats.tx_bytes;
+
+ for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
+ nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nins->node_stats.rx_dropped[i];
+ }
+
+ nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_CREATE_REQUESTS] += nins->ipv4_connection_create_requests;
+ nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_CREATE_COLLISIONS] += nins->ipv4_connection_create_collisions;
+ nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv4_connection_create_invalid_interface;
+ nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_DESTROY_REQUESTS] += nins->ipv4_connection_destroy_requests;
+ nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_DESTROY_MISSES] += nins->ipv4_connection_destroy_misses;
+ nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_HASH_HITS] += nins->ipv4_connection_hash_hits;
+ nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_HASH_REORDERS] += nins->ipv4_connection_hash_reorders;
+ nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_FLUSHES] += nins->ipv4_connection_flushes;
+ nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_EVICTIONS] += nins->ipv4_connection_evictions;
+ nss_ipv4_stats[NSS_IPV4_STATS_FRAGMENTATIONS] += nins->ipv4_fragmentations;
+ nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_CREATE_REQUESTS] += nins->ipv4_mc_connection_create_requests;
+ nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_UPDATE_REQUESTS] += nins->ipv4_mc_connection_update_requests;
+ nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv4_mc_connection_create_invalid_interface;
+ nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_DESTROY_REQUESTS] += nins->ipv4_mc_connection_destroy_requests;
+ nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_DESTROY_MISSES] += nins->ipv4_mc_connection_destroy_misses;
+ nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_FLUSHES] += nins->ipv4_mc_connection_flushes;
+
+ for (i = 0; i < NSS_IPV4_EXCEPTION_EVENT_MAX; i++) {
+ nss_ipv4_exception_stats[i] += nins->exception_events[i];
+ }
+ spin_unlock_bh(&nss_top->stats_lock);
+}
+
+/*
+ * nss_ipv4_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4)
+
+/*
+ * nss_ipv4_stats_dentry_create()
+ * Create IPv4 statistics debug entry.
+ */
+void nss_ipv4_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("ipv4", &nss_ipv4_stats_ops);
+}
diff --git a/nss_ipv4_stats.h b/nss_ipv4_stats.h
new file mode 100644
index 0000000..d28cdc0
--- /dev/null
+++ b/nss_ipv4_stats.h
@@ -0,0 +1,77 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#ifndef __NSS_IPV4_STATS_H
+#define __NSS_IPV4_STATS_H
+
+/*
+ * IPV4 node statistics
+ */
+enum nss_ipv4_stats_types {
+ NSS_IPV4_STATS_ACCELERATED_RX_PKTS = 0,
+ /* Accelerated IPv4 RX packets */
+ NSS_IPV4_STATS_ACCELERATED_RX_BYTES,
+ /* Accelerated IPv4 RX bytes */
+ NSS_IPV4_STATS_ACCELERATED_TX_PKTS,
+ /* Accelerated IPv4 TX packets */
+ NSS_IPV4_STATS_ACCELERATED_TX_BYTES,
+ /* Accelerated IPv4 TX bytes */
+ NSS_IPV4_STATS_CONNECTION_CREATE_REQUESTS,
+ /* Number of IPv4 connection create requests */
+ NSS_IPV4_STATS_CONNECTION_CREATE_COLLISIONS,
+ /* Number of IPv4 connection create requests that collided with existing entries */
+ NSS_IPV4_STATS_CONNECTION_CREATE_INVALID_INTERFACE,
+ /* Number of IPv4 connection create requests that had invalid interface */
+ NSS_IPV4_STATS_CONNECTION_DESTROY_REQUESTS,
+ /* Number of IPv4 connection destroy requests */
+ NSS_IPV4_STATS_CONNECTION_DESTROY_MISSES,
+ /* Number of IPv4 connection destroy requests that missed the cache */
+ NSS_IPV4_STATS_CONNECTION_HASH_HITS,
+ /* Number of IPv4 connection hash hits */
+ NSS_IPV4_STATS_CONNECTION_HASH_REORDERS,
+ /* Number of IPv4 connection hash reorders */
+ NSS_IPV4_STATS_CONNECTION_FLUSHES,
+ /* Number of IPv4 connection flushes */
+ NSS_IPV4_STATS_CONNECTION_EVICTIONS,
+ /* Number of IPv4 connection evictions */
+ NSS_IPV4_STATS_FRAGMENTATIONS,
+ /* Number of successful IPv4 fragmentations performed */
+ NSS_IPV4_STATS_DROPPED_BY_RULE,
+ /* Number of IPv4 packets dropped because of a drop rule.*/
+ NSS_IPV4_STATS_MC_CONNECTION_CREATE_REQUESTS,
+ /* Number of successful IPv4 Multicast create requests */
+ NSS_IPV4_STATS_MC_CONNECTION_UPDATE_REQUESTS,
+ /* Number of successful IPv4 Multicast update requests */
+ NSS_IPV4_STATS_MC_CONNECTION_CREATE_INVALID_INTERFACE,
+ /* Number of IPv4 Multicast connection create requests that had invalid interface */
+ NSS_IPV4_STATS_MC_CONNECTION_DESTROY_REQUESTS,
+ /* Number of IPv4 Multicast connection destroy requests */
+ NSS_IPV4_STATS_MC_CONNECTION_DESTROY_MISSES,
+ /* Number of IPv4 Multicast connection destroy requests that missed the cache */
+ NSS_IPV4_STATS_MC_CONNECTION_FLUSHES,
+ /* Number of IPv4 Multicast connection flushes */
+ NSS_IPV4_STATS_MAX,
+};
+
+/*
+ * NSS IPV4 statistics APIs
+ */
+extern void nss_ipv4_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_node_sync *nins);
+extern void nss_ipv4_stats_conn_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync *nirs);
+extern void nss_ipv4_stats_conn_sync_many(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync_many_msg *nicsm);
+extern void nss_ipv4_stats_dentry_create(void);
+
+#endif /* __NSS_IPV4_STATS_H */
diff --git a/nss_ipv6.c b/nss_ipv6.c
index ae83ea2..b840504 100644
--- a/nss_ipv6.c
+++ b/nss_ipv6.c
@@ -20,6 +20,7 @@
*/
#include "nss_tx_rx_common.h"
#include "nss_dscp_map.h"
+#include "nss_ipv6_stats.h"
#define NSS_IPV6_TX_MSG_TIMEOUT 1000 /* 1 sec timeout for IPv6 messages */
@@ -68,93 +69,6 @@
}
/*
- * nss_ipv6_driver_conn_sync_update()
- * Update driver specific information from the messsage.
- */
-static void nss_ipv6_driver_conn_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync *nics)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
-
- /*
- * Update statistics maintained by NSS driver
- */
- spin_lock_bh(&nss_top->stats_lock);
- nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_RX_PKTS] += nics->flow_rx_packet_count + nics->return_rx_packet_count;
- nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_RX_BYTES] += nics->flow_rx_byte_count + nics->return_rx_byte_count;
- nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_TX_PKTS] += nics->flow_tx_packet_count + nics->return_tx_packet_count;
- nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_TX_BYTES] += nics->flow_tx_byte_count + nics->return_tx_byte_count;
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
- * nss_ipv6_driver_conn_sync_many_update()
- * Update driver specific information from the conn_sync_many messsage.
- */
-static void nss_ipv6_driver_conn_sync_many_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync_many_msg *nicsm)
-{
- uint32_t i;
-
- /*
- * Sanity check for the stats count
- */
- if (nicsm->count * sizeof(struct nss_ipv6_conn_sync) >= nicsm->size) {
- nss_warning("%p: stats sync count %u exceeds the size of this msg %u", nss_ctx, nicsm->count, nicsm->size);
- return;
- }
-
- for (i = 0; i < nicsm->count; i++) {
- nss_ipv6_driver_conn_sync_update(nss_ctx, &nicsm->conn_sync[i]);
- }
-}
-
-/*
- * nss_ipv6_driver_node_sync_update)
- * Update driver specific information from the messsage.
- */
-static void nss_ipv6_driver_node_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_node_sync *nins)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- int i;
-
- /*
- * Update statistics maintained by NSS driver
- */
- spin_lock_bh(&nss_top->stats_lock);
- nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nins->node_stats.rx_packets;
- nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nins->node_stats.rx_bytes;
- nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nins->node_stats.tx_packets;
- nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nins->node_stats.tx_bytes;
-
- for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
- nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nins->node_stats.rx_dropped[i];
- }
-
- nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_REQUESTS] += nins->ipv6_connection_create_requests;
- nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_COLLISIONS] += nins->ipv6_connection_create_collisions;
- nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_connection_create_invalid_interface;
- nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_connection_destroy_requests;
- nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_DESTROY_MISSES] += nins->ipv6_connection_destroy_misses;
- nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_HASH_HITS] += nins->ipv6_connection_hash_hits;
- nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_HASH_REORDERS] += nins->ipv6_connection_hash_reorders;
- nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_FLUSHES] += nins->ipv6_connection_flushes;
- nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_EVICTIONS] += nins->ipv6_connection_evictions;
- nss_top->stats_ipv6[NSS_STATS_IPV6_FRAGMENTATIONS] += nins->ipv6_fragmentations;
- nss_top->stats_ipv6[NSS_STATS_IPV6_FRAG_FAILS] += nins->ipv6_frag_fails;
- nss_top->stats_ipv6[NSS_STATS_IPV6_DROPPED_BY_RULE] += nins->ipv6_dropped_by_rule;
- nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_CREATE_REQUESTS] += nins->ipv6_mc_connection_create_requests;
- nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_UPDATE_REQUESTS] += nins->ipv6_mc_connection_update_requests;
- nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_mc_connection_create_invalid_interface;
- nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_mc_connection_destroy_requests;
- nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_DESTROY_MISSES] += nins->ipv6_mc_connection_destroy_misses;
- nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_FLUSHES] += nins->ipv6_mc_connection_flushes;
-
- for (i = 0; i < NSS_EXCEPTION_EVENT_IPV6_MAX; i++) {
- nss_top->stats_if_exception_ipv6[i] += nins->exception_events[i];
- }
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
* nss_ipv6_rx_msg_handler()
* Handle NSS -> HLOS messages for IPv6 bridge/route
*/
@@ -191,21 +105,21 @@
/*
* Update driver statistics on node sync.
*/
- nss_ipv6_driver_node_sync_update(nss_ctx, &nim->msg.node_stats);
+ nss_ipv6_stats_node_sync(nss_ctx, &nim->msg.node_stats);
break;
case NSS_IPV6_RX_CONN_STATS_SYNC_MSG:
/*
* Update driver statistics on connection sync.
*/
- nss_ipv6_driver_conn_sync_update(nss_ctx, &nim->msg.conn_stats);
+ nss_ipv6_stats_conn_sync(nss_ctx, &nim->msg.conn_stats);
break;
case NSS_IPV6_TX_CONN_STATS_SYNC_MANY_MSG:
/*
* Update driver statistics on connection sync many.
*/
- nss_ipv6_driver_conn_sync_many_update(nss_ctx, &nim->msg.conn_stats_many);
+ nss_ipv6_stats_conn_sync_many(nss_ctx, &nim->msg.conn_stats_many);
ncm->cb = (nss_ptr_t)nss_ipv6_conn_sync_many_msg_cb;
break;
}
@@ -510,6 +424,8 @@
if (nss_core_register_handler(nss_ctx, NSS_IPV6_RX_INTERFACE, nss_ipv6_rx_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) {
nss_warning("IPv6 handler failed to register");
}
+
+ nss_ipv6_stats_dentry_create();
}
/*
diff --git a/nss_ipv6_reasm.c b/nss_ipv6_reasm.c
index b818be3..4870a95 100644
--- a/nss_ipv6_reasm.c
+++ b/nss_ipv6_reasm.c
@@ -19,39 +19,7 @@
* NSS IPv6 Reassembly APIs
*/
#include "nss_tx_rx_common.h"
-
-/*
- * nss_ipv6_reasm_stats_sync()
- * Update driver specific information from the messsage.
- */
-static void nss_ipv6_reasm_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_reasm_stats_sync *nirs)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- int j;
-
- spin_lock_bh(&nss_top->stats_lock);
-
- /*
- * Common node stats
- */
- nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nirs->node_stats.rx_packets;
- nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nirs->node_stats.rx_bytes;
- nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nirs->node_stats.tx_packets;
- nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nirs->node_stats.tx_bytes;
-
- for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
- nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nirs->node_stats.rx_dropped[j];
- }
-
- /*
- * IPv6 reasm node stats
- */
- nss_top->stats_ipv6_reasm[NSS_STATS_IPV6_REASM_ALLOC_FAILS] += nirs->ipv6_reasm_alloc_fails;
- nss_top->stats_ipv6_reasm[NSS_STATS_IPV6_REASM_TIMEOUTS] += nirs->ipv6_reasm_timeouts;
- nss_top->stats_ipv6_reasm[NSS_STATS_IPV6_REASM_DISCARDS] += nirs->ipv6_reasm_discards;
-
- spin_unlock_bh(&nss_top->stats_lock);
-}
+#include "nss_ipv6_reasm_stats.h"
/*
* nss_ipv6_reasm_msg_handler()
@@ -96,4 +64,6 @@
if (nss_core_register_handler(nss_ctx, NSS_IPV6_REASM_INTERFACE, nss_ipv6_reasm_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) {
nss_warning("IPv6 reasm handler failed to register");
}
+
+ nss_ipv6_reasm_stats_dentry_create();
}
diff --git a/nss_ipv6_reasm_stats.c b/nss_ipv6_reasm_stats.c
new file mode 100644
index 0000000..f896406
--- /dev/null
+++ b/nss_ipv6_reasm_stats.c
@@ -0,0 +1,136 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_ipv6_reasm_stats.h"
+
+/*
+ * nss_ipv6_reasm_stats_str
+ * IPv6 reassembly stats strings
+ */
+static int8_t *nss_ipv6_reasm_stats_str[NSS_IPV6_REASM_STATS_MAX] = {
+ "alloc_fails",
+ "timeouts",
+ "discards",
+};
+
+uint64_t nss_ipv6_reasm_stats[NSS_IPV6_REASM_STATS_MAX]; /* IPv6 reasm statistics */
+
+/*
+ * nss_ipv6_stats_reasm_read()
+ * Read IPV6 reassembly stats
+ */
+static ssize_t nss_ipv6_reasm_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_IPV6_REASM_STATS_MAX + 3) + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ stats_shadow = kzalloc(NSS_IPV6_REASM_STATS_MAX * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "ipv6 reasm stats start:\n\n");
+
+ size_wr = nss_stats_fill_common_stats(NSS_IPV6_REASM_INTERFACE, lbuf, size_wr, size_al);
+
+ /*
+ * Ipv6 reasm node stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 reasm node stats:\n\n");
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_IPV6_REASM_STATS_MAX); i++) {
+ stats_shadow[i] = nss_ipv6_reasm_stats[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_IPV6_REASM_STATS_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_ipv6_reasm_stats_str[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 reasm stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_ipv6_reasm_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6_reasm)
+
+/*
+ * nss_ipv6_reasm_stats_dentry_create()
+ * Create IPv6 reasm statistics debug entry.
+ */
+void nss_ipv6_reasm_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("ipv6_reasm", &nss_ipv6_reasm_stats_ops);
+}
+
+/*
+ * nss_ipv6_reasm_stats_sync()
+ * Update driver specific information from the messsage.
+ */
+void nss_ipv6_reasm_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_reasm_stats_sync *nirs)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ int j;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ /*
+ * Common node stats
+ */
+ nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nirs->node_stats.rx_packets;
+ nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nirs->node_stats.rx_bytes;
+ nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nirs->node_stats.tx_packets;
+ nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nirs->node_stats.tx_bytes;
+
+ for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
+ nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nirs->node_stats.rx_dropped[j];
+ }
+
+ /*
+ * IPv6 reasm node stats
+ */
+ nss_ipv6_reasm_stats[NSS_IPV6_REASM_STATS_ALLOC_FAILS] += nirs->ipv6_reasm_alloc_fails;
+ nss_ipv6_reasm_stats[NSS_IPV6_REASM_STATS_TIMEOUTS] += nirs->ipv6_reasm_timeouts;
+ nss_ipv6_reasm_stats[NSS_IPV6_REASM_STATS_DISCARDS] += nirs->ipv6_reasm_discards;
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
diff --git a/nss_ipv6_reasm_stats.h b/nss_ipv6_reasm_stats.h
new file mode 100644
index 0000000..45eff95
--- /dev/null
+++ b/nss_ipv6_reasm_stats.h
@@ -0,0 +1,39 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#ifndef __NSS_IPV6_REASM_STATS_H
+#define __NSS_IPV6_REASM_STATS_H
+
+/*
+ * IPv6 reasm node statistics
+ */
+enum nss_ipv6_reasm_stats {
+ NSS_IPV6_REASM_STATS_ALLOC_FAILS = 0,
+ /* Number of fragment queue allocation failures */
+ NSS_IPV6_REASM_STATS_TIMEOUTS,
+ /* Number of expired fragment queues */
+ NSS_IPV6_REASM_STATS_DISCARDS,
+ /* Number of fragment queues discarded due to malformed fragments*/
+ NSS_IPV6_REASM_STATS_MAX,
+};
+
+/*
+ * NSS IPv6 reasm statistics APIs
+ */
+extern void nss_ipv6_reasm_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_reasm_stats_sync *nirs);
+extern void nss_ipv6_reasm_stats_dentry_create(void);
+
+#endif /* __NSS_IPV6_REASM_STATS_H */
diff --git a/nss_ipv6_stats.c b/nss_ipv6_stats.c
new file mode 100644
index 0000000..24b1e77
--- /dev/null
+++ b/nss_ipv6_stats.c
@@ -0,0 +1,287 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include <nss_ipv6.h>
+#include "nss_ipv6_stats.h"
+
+/*
+ * nss_ipv6_exception_stats_str
+ * Interface stats strings for ipv6 exceptions
+ */
+static int8_t *nss_ipv6_exception_stats_str[NSS_IPV6_EXCEPTION_EVENT_MAX] = {
+ "IPV6_ICMP_HEADER_INCOMPLETE",
+ "IPV6_ICMP_UNHANDLED_TYPE",
+ "IPV6_ICMP_IPV6_HEADER_INCOMPLETE",
+ "IPV6_ICMP_IPV6_UDP_HEADER_INCOMPLETE",
+ "IPV6_ICMP_IPV6_TCP_HEADER_INCOMPLETE",
+ "IPV6_ICMP_IPV6_UNKNOWN_PROTOCOL",
+ "IPV6_ICMP_NO_ICME",
+ "IPV6_ICMP_FLUSH_TO_HOST",
+ "IPV6_TCP_HEADER_INCOMPLETE",
+ "IPV6_TCP_NO_ICME",
+ "IPV6_TCP_SMALL_HOP_LIMIT",
+ "IPV6_TCP_NEEDS_FRAGMENTATION",
+ "IPV6_TCP_FLAGS",
+ "IPV6_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
+ "IPV6_TCP_SMALL_DATA_OFFS",
+ "IPV6_TCP_BAD_SACK",
+ "IPV6_TCP_BIG_DATA_OFFS",
+ "IPV6_TCP_SEQ_BEFORE_LEFT_EDGE",
+ "IPV6_TCP_ACK_EXCEEDS_RIGHT_EDGE",
+ "IPV6_TCP_ACK_BEFORE_LEFT_EDGE",
+ "IPV6_UDP_HEADER_INCOMPLETE",
+ "IPV6_UDP_NO_ICME",
+ "IPV6_UDP_SMALL_HOP_LIMIT",
+ "IPV6_UDP_NEEDS_FRAGMENTATION",
+ "IPV6_WRONG_TARGET_MAC",
+ "IPV6_HEADER_INCOMPLETE",
+ "IPV6_UNKNOWN_PROTOCOL",
+ "IPV6_INGRESS_VID_MISMATCH",
+ "IPV6_INGRESS_VID_MISSING",
+ "IPV6_DSCP_MARKING_MISMATCH",
+ "IPV6_VLAN_MARKING_MISMATCH",
+ "IPV6_DEPRECATED",
+ "IPV6_GRE_NO_ICME",
+ "IPV6_GRE_NEEDS_FRAGMENTATION",
+ "IPV6_GRE_SMALL_HOP_LIMIT",
+ "IPV6_DESTROY",
+ "IPV6_ICMP_IPV6_UDPLITE_HEADER_INCOMPLETE",
+ "IPV6_UDPLITE_HEADER_INCOMPLETE",
+ "IPV6_UDPLITE_NO_ICME",
+ "IPV6_UDPLITE_SMALL_HOP_LIMIT",
+ "IPV6_UDPLITE_NEEDS_FRAGMENTATION",
+ "IPV6_MC_UDP_NO_ICME",
+ "IPV6_MC_MEM_ALLOC_FAILURE",
+ "IPV6_MC_UPDATE_FAILURE",
+ "IPV6_MC_PBUF_ALLOC_FAILURE",
+ "IPV6_ESP_HEADER_INCOMPLETE",
+ "IPV6_ESP_NO_ICME",
+ "IPV6_ESP_IP_FRAGMENT",
+ "IPV6_ESP_SMALL_HOP_LIMIT",
+ "IPV6_ESP_NEEDS_FRAGMENTATION"
+};
+
+uint64_t nss_ipv6_stats[NSS_IPV6_STATS_MAX];
+uint64_t nss_ipv6_exception_stats[NSS_IPV6_EXCEPTION_EVENT_MAX];
+
+/*
+ * nss_ipv6_stats_str
+ * IPv6 stats strings
+ */
+static int8_t *nss_ipv6_stats_str[NSS_IPV6_STATS_MAX] = {
+ "rx_pkts",
+ "rx_bytes",
+ "tx_pkts",
+ "tx_bytes",
+ "create_requests",
+ "create_collisions",
+ "create_invalid_interface",
+ "destroy_requests",
+ "destroy_misses",
+ "hash_hits",
+ "hash_reorders",
+ "flushes",
+ "evictions",
+ "fragmentations",
+ "frag_fails",
+ "by_rule_drops",
+ "mc_create_requests",
+ "mc_update_requests",
+ "mc_create_invalid_interface",
+ "mc_destroy_requests",
+ "mc_destroy_misses",
+ "mc_flushes",
+};
+
+/*
+ * nss_ipv6_stats_read()
+ * Read IPV6 stats
+ */
+static ssize_t nss_ipv6_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_IPV6_STATS_MAX + 3) + (NSS_IPV6_EXCEPTION_EVENT_MAX + 3) + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ /*
+ * Note: The assumption here is that exception event count is larger than other statistics count for IPv6
+ */
+ stats_shadow = kzalloc(NSS_IPV6_EXCEPTION_EVENT_MAX * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "ipv6 stats start:\n\n");
+
+ size_wr = nss_stats_fill_common_stats(NSS_IPV6_RX_INTERFACE, lbuf, size_wr, size_al);
+
+ /*
+ * IPv6 node stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 node stats:\n\n");
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_IPV6_STATS_MAX); i++) {
+ stats_shadow[i] = nss_ipv6_stats[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_IPV6_STATS_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_ipv6_stats_str[i], stats_shadow[i]);
+ }
+
+ /*
+ * Exception stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 exception stats:\n\n");
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_IPV6_EXCEPTION_EVENT_MAX); i++) {
+ stats_shadow[i] = nss_ipv6_exception_stats[i];
+ }
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_IPV6_EXCEPTION_EVENT_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_ipv6_exception_stats_str[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_ipv6_stats_conn_sync()
+ * Update driver specific information from the messsage.
+ */
+void nss_ipv6_stats_conn_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync *nics)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+
+ /*
+ * Update statistics maintained by NSS driver
+ */
+ spin_lock_bh(&nss_top->stats_lock);
+ nss_ipv6_stats[NSS_IPV6_STATS_ACCELERATED_RX_PKTS] += nics->flow_rx_packet_count + nics->return_rx_packet_count;
+ nss_ipv6_stats[NSS_IPV6_STATS_ACCELERATED_RX_BYTES] += nics->flow_rx_byte_count + nics->return_rx_byte_count;
+ nss_ipv6_stats[NSS_IPV6_STATS_ACCELERATED_TX_PKTS] += nics->flow_tx_packet_count + nics->return_tx_packet_count;
+ nss_ipv6_stats[NSS_IPV6_STATS_ACCELERATED_TX_BYTES] += nics->flow_tx_byte_count + nics->return_tx_byte_count;
+ spin_unlock_bh(&nss_top->stats_lock);
+}
+
+/*
+ * nss_ipv6_stats_conn_sync_many()
+ * Update driver specific information from the conn_sync_many messsage.
+ */
+void nss_ipv6_stats_conn_sync_many(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync_many_msg *nicsm)
+{
+ uint32_t i;
+
+ /*
+ * Sanity check for the stats count
+ */
+ if (nicsm->count * sizeof(struct nss_ipv6_conn_sync) >= nicsm->size) {
+ nss_warning("%p: stats sync count %u exceeds the size of this msg %u", nss_ctx, nicsm->count, nicsm->size);
+ return;
+ }
+
+ for (i = 0; i < nicsm->count; i++) {
+ nss_ipv6_stats_conn_sync(nss_ctx, &nicsm->conn_sync[i]);
+ }
+}
+
+/*
+ * nss_ipv6_stats_node_sync()
+ * Update driver specific information from the messsage.
+ */
+void nss_ipv6_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_node_sync *nins)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ uint32_t i;
+
+ /*
+ * Update statistics maintained by NSS driver
+ */
+ spin_lock_bh(&nss_top->stats_lock);
+ nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nins->node_stats.rx_packets;
+ nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nins->node_stats.rx_bytes;
+ nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nins->node_stats.tx_packets;
+ nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nins->node_stats.tx_bytes;
+
+ for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
+ nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nins->node_stats.rx_dropped[i];
+ }
+
+ nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_CREATE_REQUESTS] += nins->ipv6_connection_create_requests;
+ nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_CREATE_COLLISIONS] += nins->ipv6_connection_create_collisions;
+ nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_connection_create_invalid_interface;
+ nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_connection_destroy_requests;
+ nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_DESTROY_MISSES] += nins->ipv6_connection_destroy_misses;
+ nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_HASH_HITS] += nins->ipv6_connection_hash_hits;
+ nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_HASH_REORDERS] += nins->ipv6_connection_hash_reorders;
+ nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_FLUSHES] += nins->ipv6_connection_flushes;
+ nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_EVICTIONS] += nins->ipv6_connection_evictions;
+ nss_ipv6_stats[NSS_IPV6_STATS_FRAGMENTATIONS] += nins->ipv6_fragmentations;
+ nss_ipv6_stats[NSS_IPV6_STATS_FRAG_FAILS] += nins->ipv6_frag_fails;
+ nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_CREATE_REQUESTS] += nins->ipv6_mc_connection_create_requests;
+ nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_UPDATE_REQUESTS] += nins->ipv6_mc_connection_update_requests;
+ nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_mc_connection_create_invalid_interface;
+ nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_mc_connection_destroy_requests;
+ nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_DESTROY_MISSES] += nins->ipv6_mc_connection_destroy_misses;
+ nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_FLUSHES] += nins->ipv6_mc_connection_flushes;
+
+ for (i = 0; i < NSS_IPV6_EXCEPTION_EVENT_MAX; i++) {
+ nss_ipv6_exception_stats[i] += nins->exception_events[i];
+ }
+ spin_unlock_bh(&nss_top->stats_lock);
+}
+
+/*
+ * nss_ipv6_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6)
+
+/*
+ * nss_ipv6_stats_dentry_create()
+ * Create IPv6 statistics debug entry.
+ */
+void nss_ipv6_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("ipv6", &nss_ipv6_stats_ops);
+}
diff --git a/nss_ipv6_stats.h b/nss_ipv6_stats.h
new file mode 100644
index 0000000..536e49f
--- /dev/null
+++ b/nss_ipv6_stats.h
@@ -0,0 +1,79 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#ifndef __NSS_IPV6_STATS_H
+#define __NSS_IPV6_STATS_H
+
+/*
+ * IPV6 node statistics
+ */
+enum nss_ipv6_stats_types {
+ NSS_IPV6_STATS_ACCELERATED_RX_PKTS = 0,
+ /* Accelerated IPv6 RX packets */
+ NSS_IPV6_STATS_ACCELERATED_RX_BYTES,
+ /* Accelerated IPv6 RX bytes */
+ NSS_IPV6_STATS_ACCELERATED_TX_PKTS,
+ /* Accelerated IPv6 TX packets */
+ NSS_IPV6_STATS_ACCELERATED_TX_BYTES,
+ /* Accelerated IPv6 TX bytes */
+ NSS_IPV6_STATS_CONNECTION_CREATE_REQUESTS,
+ /* Number of IPv6 connection create requests */
+ NSS_IPV6_STATS_CONNECTION_CREATE_COLLISIONS,
+ /* Number of IPv6 connection create requests that collided with existing entries */
+ NSS_IPV6_STATS_CONNECTION_CREATE_INVALID_INTERFACE,
+ /* Number of IPv6 connection create requests that had invalid interface */
+ NSS_IPV6_STATS_CONNECTION_DESTROY_REQUESTS,
+ /* Number of IPv6 connection destroy requests */
+ NSS_IPV6_STATS_CONNECTION_DESTROY_MISSES,
+ /* Number of IPv6 connection destroy requests that missed the cache */
+ NSS_IPV6_STATS_CONNECTION_HASH_HITS,
+ /* Number of IPv6 connection hash hits */
+ NSS_IPV6_STATS_CONNECTION_HASH_REORDERS,
+ /* Number of IPv6 connection hash reorders */
+ NSS_IPV6_STATS_CONNECTION_FLUSHES,
+ /* Number of IPv6 connection flushes */
+ NSS_IPV6_STATS_CONNECTION_EVICTIONS,
+ /* Number of IPv6 connection evictions */
+ NSS_IPV6_STATS_FRAGMENTATIONS,
+ /* Number of successful IPv6 fragmentations performed */
+ NSS_IPV6_STATS_FRAG_FAILS,
+ /* Number of IPv6 fragmentation fails */
+ NSS_IPV6_STATS_DROPPED_BY_RULE,
+ /* Number of IPv6 packets dropped by a drop rule. */
+ NSS_IPV6_STATS_MC_CONNECTION_CREATE_REQUESTS,
+ /* Number of successful IPv6 Multicast create requests */
+ NSS_IPV6_STATS_MC_CONNECTION_UPDATE_REQUESTS,
+ /* Number of successful IPv6 Multicast update requests */
+ NSS_IPV6_STATS_MC_CONNECTION_CREATE_INVALID_INTERFACE,
+ /* Number of IPv6 Multicast connection create requests that had invalid interface */
+ NSS_IPV6_STATS_MC_CONNECTION_DESTROY_REQUESTS,
+ /* Number of IPv6 Multicast connection destroy requests */
+ NSS_IPV6_STATS_MC_CONNECTION_DESTROY_MISSES,
+ /* Number of IPv6 Multicast connection destroy requests that missed the cache */
+ NSS_IPV6_STATS_MC_CONNECTION_FLUSHES,
+ /* Number of IPv6 Multicast connection flushes */
+ NSS_IPV6_STATS_MAX,
+};
+
+/*
+ * IPV6 statistics APIs
+ */
+extern void nss_ipv6_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_node_sync *nins);
+extern void nss_ipv6_stats_conn_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync *nics);
+extern void nss_ipv6_stats_conn_sync_many(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync_many_msg *nicsm);
+extern void nss_ipv6_stats_dentry_create(void);
+
+#endif /* __NSS_IPV6_STATS_H */
diff --git a/nss_l2tpv2.c b/nss_l2tpv2.c
index ef05e20..af39b9d 100644
--- a/nss_l2tpv2.c
+++ b/nss_l2tpv2.c
@@ -17,12 +17,13 @@
#include <linux/l2tp.h>
#include <net/sock.h>
#include "nss_tx_rx_common.h"
+#include "nss_l2tpv2_stats.h"
/*
* Data structures to store l2tpv2 nss debug stats
*/
static DEFINE_SPINLOCK(nss_l2tpv2_session_debug_stats_lock);
-static struct nss_stats_l2tpv2_session_debug nss_l2tpv2_session_debug_stats[NSS_MAX_L2TPV2_DYNAMIC_INTERFACES];
+static struct nss_l2tpv2_stats_session_debug nss_l2tpv2_session_debug_stats[NSS_MAX_L2TPV2_DYNAMIC_INTERFACES];
/*
* nss_l2tpv2_session_debug_stats_sync
@@ -34,10 +35,10 @@
spin_lock_bh(&nss_l2tpv2_session_debug_stats_lock);
for (i = 0; i < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; i++) {
if (nss_l2tpv2_session_debug_stats[i].if_num == if_num) {
- nss_l2tpv2_session_debug_stats[i].stats[NSS_STATS_L2TPV2_SESSION_RX_PPP_LCP_PKTS] += stats_msg->debug_stats.rx_ppp_lcp_pkts;
- nss_l2tpv2_session_debug_stats[i].stats[NSS_STATS_L2TPV2_SESSION_RX_EXP_DATA_PKTS] += stats_msg->debug_stats.rx_exception_data_pkts;
- nss_l2tpv2_session_debug_stats[i].stats[NSS_STATS_L2TPV2_SESSION_ENCAP_PBUF_ALLOC_FAIL_PKTS] += stats_msg->debug_stats.encap_pbuf_alloc_fail;
- nss_l2tpv2_session_debug_stats[i].stats[NSS_STATS_L2TPV2_SESSION_DECAP_PBUF_ALLOC_FAIL_PKTS] += stats_msg->debug_stats.decap_pbuf_alloc_fail;
+ nss_l2tpv2_session_debug_stats[i].stats[NSS_L2TPV2_STATS_SESSION_RX_PPP_LCP_PKTS] += stats_msg->debug_stats.rx_ppp_lcp_pkts;
+ nss_l2tpv2_session_debug_stats[i].stats[NSS_L2TPV2_STATS_SESSION_RX_EXP_DATA_PKTS] += stats_msg->debug_stats.rx_exception_data_pkts;
+ nss_l2tpv2_session_debug_stats[i].stats[NSS_L2TPV2_STATS_SESSION_ENCAP_PBUF_ALLOC_FAIL_PKTS] += stats_msg->debug_stats.encap_pbuf_alloc_fail;
+ nss_l2tpv2_session_debug_stats[i].stats[NSS_L2TPV2_STATS_SESSION_DECAP_PBUF_ALLOC_FAIL_PKTS] += stats_msg->debug_stats.decap_pbuf_alloc_fail;
break;
}
}
@@ -50,7 +51,7 @@
*/
void nss_l2tpv2_session_debug_stats_get(void *stats_mem)
{
- struct nss_stats_l2tpv2_session_debug *stats = (struct nss_stats_l2tpv2_session_debug *)stats_mem;
+ struct nss_l2tpv2_stats_session_debug *stats = (struct nss_l2tpv2_stats_session_debug *)stats_mem;
int i;
if (!stats) {
@@ -61,7 +62,7 @@
spin_lock_bh(&nss_l2tpv2_session_debug_stats_lock);
for (i = 0; i < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; i++) {
if (nss_l2tpv2_session_debug_stats[i].valid) {
- memcpy(stats, &nss_l2tpv2_session_debug_stats[i], sizeof(struct nss_stats_l2tpv2_session_debug));
+ memcpy(stats, &nss_l2tpv2_session_debug_stats[i], sizeof(struct nss_l2tpv2_stats_session_debug));
stats++;
}
}
@@ -264,7 +265,7 @@
spin_lock_bh(&nss_l2tpv2_session_debug_stats_lock);
for (i = 0; i < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; i++) {
if (nss_l2tpv2_session_debug_stats[i].if_num == if_num) {
- memset(&nss_l2tpv2_session_debug_stats[i], 0, sizeof(struct nss_stats_l2tpv2_session_debug));
+ memset(&nss_l2tpv2_session_debug_stats[i], 0, sizeof(struct nss_l2tpv2_stats_session_debug));
break;
}
}
@@ -281,7 +282,7 @@
/*
* nss_l2tpv2_msg_init()
- * Initialize nss_l2tpv2 msg.
+ * Initialize nss_l2tpv2 msg.
*/
void nss_l2tpv2_msg_init(struct nss_l2tpv2_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data)
{
@@ -297,6 +298,8 @@
nss_info("nss_l2tpv2_register_handler");
nss_core_register_handler(nss_ctx, NSS_L2TPV2_INTERFACE, nss_l2tpv2_handler, NULL);
+
+ nss_l2tpv2_stats_dentry_create();
}
EXPORT_SYMBOL(nss_l2tpv2_get_context);
diff --git a/nss_l2tpv2_stats.c b/nss_l2tpv2_stats.c
new file mode 100644
index 0000000..00e35da
--- /dev/null
+++ b/nss_l2tpv2_stats.c
@@ -0,0 +1,110 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_l2tpv2_stats.h"
+
+/*
+ * nss_l2tpv2_stats_session_str
+ * l2tpv2 statistics strings for nss session stats
+ */
+static int8_t *nss_l2tpv2_stats_session_str[NSS_L2TPV2_STATS_SESSION_MAX] = {
+ "RX_PPP_LCP_PKTS",
+ "RX_EXP_PKTS",
+ "ENCAP_PBUF_ALLOC_FAIL",
+ "DECAP_PBUF_ALLOC_FAIL"
+};
+
+/*
+ * nss_l2tpv2_stats_read()
+ * Read l2tpv2 statistics
+ */
+static ssize_t nss_l2tpv2_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+
+ uint32_t max_output_lines = 2 /* header & footer for session stats */
+ + NSS_MAX_L2TPV2_DYNAMIC_INTERFACES * (NSS_L2TPV2_STATS_SESSION_MAX + 2) /*session stats */
+ + 2;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines ;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ struct net_device *dev;
+ struct nss_l2tpv2_stats_session_debug l2tpv2_session_stats[NSS_MAX_L2TPV2_DYNAMIC_INTERFACES];
+ int id, i;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ memset(&l2tpv2_session_stats, 0, sizeof(struct nss_l2tpv2_stats_session_debug) * NSS_MAX_L2TPV2_DYNAMIC_INTERFACES);
+
+ /*
+ * Get all stats
+ */
+ nss_l2tpv2_session_debug_stats_get((void *)&l2tpv2_session_stats);
+
+ /*
+ * Session stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nl2tp v2 session stats start:\n\n");
+ for (id = 0; id < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; id++) {
+
+ if (!l2tpv2_session_stats[id].valid) {
+ break;
+ }
+
+ dev = dev_get_by_index(&init_net, l2tpv2_session_stats[id].if_index);
+ if (likely(dev)) {
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id,
+ l2tpv2_session_stats[id].if_num, dev->name);
+ dev_put(dev);
+ } else {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id,
+ l2tpv2_session_stats[id].if_num);
+ }
+
+ for (i = 0; i < NSS_L2TPV2_STATS_SESSION_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %llu\n", nss_l2tpv2_stats_session_str[i],
+ l2tpv2_session_stats[id].stats[i]);
+ }
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nl2tp v2 session stats end\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
+
+ kfree(lbuf);
+ return bytes_read;
+}
+
+/*
+ * nss_l2tpv2_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(l2tpv2)
+
+/*
+ * nss_l2tpv2_stats_dentry_create()
+ * Create l2tpv2 statistics debug entry.
+ */
+void nss_l2tpv2_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("l2tpv2", &nss_l2tpv2_stats_ops);
+}
diff --git a/nss_l2tpv2_stats.h b/nss_l2tpv2_stats.h
new file mode 100644
index 0000000..c199afa
--- /dev/null
+++ b/nss_l2tpv2_stats.h
@@ -0,0 +1,43 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_L2TPV2_STATS_H
+#define __NSS_L2TPV2_STATS_H
+
+/*
+ * l2tpv2 debug stats
+ */
+enum nss_l2tpv2_stats_session {
+ NSS_L2TPV2_STATS_SESSION_RX_PPP_LCP_PKTS, /* Number of ppp lcp packets received */
+ NSS_L2TPV2_STATS_SESSION_RX_EXP_DATA_PKTS, /* Number of RX exceptioned packets */
+ NSS_L2TPV2_STATS_SESSION_ENCAP_PBUF_ALLOC_FAIL_PKTS, /* Number of times packet buffer allocation failed during encap */
+ NSS_L2TPV2_STATS_SESSION_DECAP_PBUF_ALLOC_FAIL_PKTS, /* Number of times packet buffer allocation failed during decap */
+ NSS_L2TPV2_STATS_SESSION_MAX
+};
+
+struct nss_l2tpv2_stats_session_debug {
+ uint64_t stats[NSS_L2TPV2_STATS_SESSION_MAX];
+ int32_t if_index;
+ uint32_t if_num; /* nss interface number */
+ bool valid;
+};
+
+/*
+ * l2tpv2 statistics APIs
+ */
+extern void nss_l2tpv2_stats_dentry_create(void);
+
+#endif /* __NSS_L2TPV2_STATS_H */
diff --git a/nss_log.c b/nss_log.c
index 0480ad0..a538264 100644
--- a/nss_log.c
+++ b/nss_log.c
@@ -655,6 +655,8 @@
void nss_log_init(void)
{
int i;
+ struct dentry *logs_dentry;
+ struct dentry *core_log_dentry;
memset(nss_rbe, 0, sizeof(nss_rbe));
init_waitqueue_head(&nss_log_wq);
@@ -663,8 +665,8 @@
/*
* Create directory for obtaining NSS FW logs from each core
*/
- nss_top_main.logs_dentry = debugfs_create_dir("logs", nss_top_main.top_dentry);
- if (unlikely(!nss_top_main.logs_dentry)) {
+ logs_dentry = debugfs_create_dir("logs", nss_top_main.top_dentry);
+ if (unlikely(!logs_dentry)) {
nss_warning("Failed to create qca-nss-drv/logs directory in debugfs");
return;
}
@@ -674,9 +676,9 @@
extern struct file_operations nss_logs_core_ops;
snprintf(file, sizeof(file), "core%d", i);
- nss_top_main.core_log_dentry = debugfs_create_file(file, 0400,
- nss_top_main.logs_dentry, (void *)(nss_ptr_t)i, &nss_logs_core_ops);
- if (unlikely(!nss_top_main.core_log_dentry)) {
+ core_log_dentry = debugfs_create_file(file, 0400,
+ logs_dentry, (void *)(nss_ptr_t)i, &nss_logs_core_ops);
+ if (unlikely(!core_log_dentry)) {
nss_warning("Failed to create qca-nss-drv/logs/%s file in debugfs", file);
return;
}
diff --git a/nss_lso_rx.c b/nss_lso_rx.c
index fb961ae..378818d 100644
--- a/nss_lso_rx.c
+++ b/nss_lso_rx.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -20,44 +20,7 @@
*/
#include "nss_tx_rx_common.h"
-
-/*
- * nss_rx_lso_rx_stats_sync()
- * Handle the syncing of lso_rx node statistics.
- */
-static void nss_rx_lso_rx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_lso_rx_stats_sync *nlrss)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- int j;
-
- spin_lock_bh(&nss_top->stats_lock);
-
- /*
- * common node stats
- */
- nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nlrss->node_stats.rx_packets;
- nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nlrss->node_stats.rx_bytes;
- nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nlrss->node_stats.tx_packets;
- nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nlrss->node_stats.tx_bytes;
-
- for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
- nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nlrss->node_stats.rx_dropped[j];
- }
-
- /*
- * General LSO_RX stats
- */
- nss_top->stats_lso_rx[NSS_STATS_LSO_RX_TX_DROPPED] += nlrss->tx_dropped;
- nss_top->stats_lso_rx[NSS_STATS_LSO_RX_DROPPED] += nlrss->dropped;
-
- /*
- * pbuf
- */
- nss_top->stats_lso_rx[NSS_STATS_LSO_RX_PBUF_ALLOC_FAIL] += nlrss->pbuf_alloc_fail;
- nss_top->stats_lso_rx[NSS_STATS_LSO_RX_PBUF_REFERENCE_FAIL] += nlrss->pbuf_reference_fail;
-
- spin_unlock_bh(&nss_top->stats_lock);
-}
+#include "nss_lso_rx.h"
/*
* nss_rx_lso_rx_interface_handler()
@@ -69,7 +32,7 @@
switch (nlrm->cm.type) {
case NSS_LSO_RX_STATS_SYNC_MSG:
- nss_rx_lso_rx_stats_sync(nss_ctx, &nlrm->msg.stats_sync);
+ nss_lso_rx_stats_sync(nss_ctx, &nlrm->msg.stats_sync);
break;
default:
@@ -89,4 +52,5 @@
void nss_lso_rx_register_handler(struct nss_ctx_instance *nss_ctx)
{
nss_core_register_handler(nss_ctx, NSS_LSO_RX_INTERFACE, nss_rx_lso_rx_interface_handler, NULL);
+ nss_lso_rx_stats_dentry_create();
}
diff --git a/nss_lso_rx.h b/nss_lso_rx.h
new file mode 100644
index 0000000..62aa9dd
--- /dev/null
+++ b/nss_lso_rx.h
@@ -0,0 +1,82 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#ifndef __NSS_LSO_RX_H
+#define __NSS_LSO_RX_H
+
+#include <nss_cmn.h>
+
+/*
+ * nss_lso_rx.h
+ * NSS driver lso_RX header file.
+ */
+
+/*
+ * LSO_RX driver statistics
+ */
+enum nss_lso_rx_stats_types {
+ NSS_LSO_RX_STATS_TX_DROPPED, /* Number of packets dropped cause transmit queue is full */
+ NSS_LSO_RX_STATS_DROPPED, /* Number of packets dropped because of node internal errors */
+ NSS_LSO_RX_STATS_PBUF_ALLOC_FAIL, /* Number of pbuf alloc failures */
+ NSS_LSO_RX_STATS_PBUF_REFERENCE_FAIL, /* Number of pbuf reference failures */
+ NSS_LSO_RX_STATS_MAX,
+};
+
+/*
+ * lso_rx_node statistics.
+ */
+struct nss_lso_rx_stats_sync {
+ struct nss_cmn_node_stats node_stats;
+
+ uint32_t tx_dropped; /* Number of packets dropped because lso_rx transmit queue is full */
+ uint32_t dropped; /* Total of packets dropped by the node internally */
+ uint32_t pbuf_alloc_fail; /* Count number of pbuf alloc fails */
+ uint32_t pbuf_reference_fail; /* Count number of pbuf ref fails */
+
+ /*
+ * If we're generating per-packet statistics then we count total lso_rx processing ticks
+ * worst-case ticks and the number of iterations around the lso_rx handler that we take.
+ */
+ uint32_t total_ticks; /* Total clock ticks spend inside the lso_rx handler */
+ uint32_t worst_case_ticks;
+ /* Worst case iteration of the lso_rx handler in ticks */
+ uint32_t iterations; /* Number of iterations around the lso_rx handler */
+};
+
+/*
+ * Message types for lso_rx
+ */
+enum nss_lso_rx_metadata_types {
+ NSS_LSO_RX_STATS_SYNC_MSG, /* Message type - stats sync message */
+};
+
+/*
+ * Message structure to send receive LSO_RX commands
+ */
+struct nss_lso_rx_msg {
+ struct nss_cmn_msg cm; /* Message header */
+ union {
+ struct nss_lso_rx_stats_sync stats_sync; /* Stats sub-message */
+ } msg;
+};
+
+/*
+ * lso_rx statistics APIs
+ */
+extern void nss_lso_rx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_lso_rx_stats_sync *nlrss);
+extern void nss_lso_rx_stats_dentry_create(void);
+
+#endif /* __NSS_LSO_RX_H */
diff --git a/nss_lso_rx_stats.c b/nss_lso_rx_stats.c
new file mode 100644
index 0000000..92aa6ea
--- /dev/null
+++ b/nss_lso_rx_stats.c
@@ -0,0 +1,142 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_lso_rx.h"
+
+/*
+ * nss_lso_rx_stats_str
+ * LSO_RX stats strings
+ */
+static int8_t *nss_lso_rx_stats_str[NSS_LSO_RX_STATS_MAX] = {
+ "tx_dropped",
+ "dropped",
+ "pbuf_alloc_fail",
+ "pbuf_reference_fail"
+};
+
+uint64_t nss_lso_rx_stats[NSS_LSO_RX_STATS_MAX]; /* LSO_RX statistics */
+
+/*
+ * nss_lso_rx_stats_read()
+ * Read LSO_RX stats
+ */
+static ssize_t nss_lso_rx_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_LSO_RX_STATS_MAX + 3) + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ stats_shadow = kzalloc(NSS_LSO_RX_STATS_MAX * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "lso_rx stats start:\n\n");
+
+ size_wr = nss_stats_fill_common_stats(NSS_LSO_RX_INTERFACE, lbuf, size_wr, size_al);
+
+ /*
+ * lso_rx node stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nlso_rx node stats:\n\n");
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_LSO_RX_STATS_MAX); i++) {
+ stats_shadow[i] = nss_lso_rx_stats[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; i < NSS_LSO_RX_STATS_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_lso_rx_stats_str[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nlso_rx stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_lso_rx_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(lso_rx)
+
+/*
+ * nss_lso_rx_stats_dentry_create()
+ * Create lso_rx statistics debug entry.
+ */
+void nss_lso_rx_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("lso_rx", &nss_lso_rx_stats_ops);
+}
+
+/*
+ * nss_lso_rx_stats_sync()
+ * Handle the syncing of lso_rx node statistics.
+ */
+void nss_lso_rx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_lso_rx_stats_sync *nlrss)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ int j;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ /*
+ * common node stats
+ */
+ nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nlrss->node_stats.rx_packets;
+ nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nlrss->node_stats.rx_bytes;
+ nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nlrss->node_stats.tx_packets;
+ nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nlrss->node_stats.tx_bytes;
+
+ for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
+ nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nlrss->node_stats.rx_dropped[j];
+ }
+
+ /*
+ * General LSO_RX stats
+ */
+ nss_lso_rx_stats[NSS_LSO_RX_STATS_TX_DROPPED] += nlrss->tx_dropped;
+ nss_lso_rx_stats[NSS_LSO_RX_STATS_DROPPED] += nlrss->dropped;
+
+ /*
+ * pbuf
+ */
+ nss_lso_rx_stats[NSS_LSO_RX_STATS_PBUF_ALLOC_FAIL] += nlrss->pbuf_alloc_fail;
+ nss_lso_rx_stats[NSS_LSO_RX_STATS_PBUF_REFERENCE_FAIL] += nlrss->pbuf_reference_fail;
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
diff --git a/nss_map_t.c b/nss_map_t.c
index 0369fd9..f23dcec 100644
--- a/nss_map_t.c
+++ b/nss_map_t.c
@@ -15,6 +15,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_map_t_stats.h"
#define NSS_MAP_T_TX_TIMEOUT 3000 /* 3 Seconds */
@@ -33,7 +34,7 @@
* Data structures to store map_t nss debug stats
*/
static DEFINE_SPINLOCK(nss_map_t_debug_stats_lock);
-static struct nss_stats_map_t_instance_debug nss_map_t_debug_stats[NSS_MAX_MAP_T_DYNAMIC_INTERFACES];
+static struct nss_map_t_stats_instance_debug nss_map_t_debug_stats[NSS_MAX_MAP_T_DYNAMIC_INTERFACES];
/*
* nss_map_t_verify_if_num()
@@ -63,20 +64,20 @@
spin_lock_bh(&nss_map_t_debug_stats_lock);
for (i = 0; i < NSS_MAX_MAP_T_DYNAMIC_INTERFACES; i++) {
if (nss_map_t_debug_stats[i].if_num == if_num) {
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V4_TO_V6_PBUF_EXCEPTION] += stats_msg->debug_stats.v4_to_v6.exception_pkts;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V4_TO_V6_PBUF_NO_MATCHING_RULE] += stats_msg->debug_stats.v4_to_v6.no_matching_rule;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V4_TO_V6_PBUF_NOT_TCP_OR_UDP] += stats_msg->debug_stats.v4_to_v6.not_tcp_or_udp;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V4_TO_V6_RULE_ERR_LOCAL_PSID] += stats_msg->debug_stats.v4_to_v6.rule_err_local_psid;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V4_TO_V6_RULE_ERR_LOCAL_IPV6] += stats_msg->debug_stats.v4_to_v6.rule_err_local_ipv6;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V4_TO_V6_RULE_ERR_REMOTE_PSID] += stats_msg->debug_stats.v4_to_v6.rule_err_remote_psid;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V4_TO_V6_RULE_ERR_REMOTE_EA_BITS] += stats_msg->debug_stats.v4_to_v6.rule_err_remote_ea_bits;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V4_TO_V6_RULE_ERR_REMOTE_IPV6] += stats_msg->debug_stats.v4_to_v6.rule_err_remote_ipv6;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_PBUF_EXCEPTION] += stats_msg->debug_stats.v4_to_v6.exception_pkts;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_PBUF_NO_MATCHING_RULE] += stats_msg->debug_stats.v4_to_v6.no_matching_rule;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_PBUF_NOT_TCP_OR_UDP] += stats_msg->debug_stats.v4_to_v6.not_tcp_or_udp;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_LOCAL_PSID] += stats_msg->debug_stats.v4_to_v6.rule_err_local_psid;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_LOCAL_IPV6] += stats_msg->debug_stats.v4_to_v6.rule_err_local_ipv6;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_PSID] += stats_msg->debug_stats.v4_to_v6.rule_err_remote_psid;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_EA_BITS] += stats_msg->debug_stats.v4_to_v6.rule_err_remote_ea_bits;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_IPV6] += stats_msg->debug_stats.v4_to_v6.rule_err_remote_ipv6;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V6_TO_V4_PBUF_EXCEPTION] += stats_msg->debug_stats.v6_to_v4.exception_pkts;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V6_TO_V4_PBUF_NO_MATCHING_RULE] += stats_msg->debug_stats.v6_to_v4.no_matching_rule;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V6_TO_V4_PBUF_NOT_TCP_OR_UDP] += stats_msg->debug_stats.v6_to_v4.not_tcp_or_udp;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V6_TO_V4_RULE_ERR_LOCAL_IPV4] += stats_msg->debug_stats.v6_to_v4.rule_err_local_ipv4;
- nss_map_t_debug_stats[i].stats[NSS_STATS_MAP_T_V6_TO_V4_RULE_ERR_REMOTE_IPV4] += stats_msg->debug_stats.v6_to_v4.rule_err_remote_ipv4;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V6_TO_V4_PBUF_EXCEPTION] += stats_msg->debug_stats.v6_to_v4.exception_pkts;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V6_TO_V4_PBUF_NO_MATCHING_RULE] += stats_msg->debug_stats.v6_to_v4.no_matching_rule;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V6_TO_V4_PBUF_NOT_TCP_OR_UDP] += stats_msg->debug_stats.v6_to_v4.not_tcp_or_udp;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V6_TO_V4_RULE_ERR_LOCAL_IPV4] += stats_msg->debug_stats.v6_to_v4.rule_err_local_ipv4;
+ nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V6_TO_V4_RULE_ERR_REMOTE_IPV4] += stats_msg->debug_stats.v6_to_v4.rule_err_remote_ipv4;
break;
}
}
@@ -84,12 +85,12 @@
}
/*
- * nss_map_t_instance_stats_get()
+ * nss_map_t_instance_debug_stats_get()
* Get map_t statitics.
*/
void nss_map_t_instance_debug_stats_get(void *stats_mem)
{
- struct nss_stats_map_t_instance_debug *stats = (struct nss_stats_map_t_instance_debug *)stats_mem;
+ struct nss_map_t_stats_instance_debug *stats = (struct nss_map_t_stats_instance_debug *)stats_mem;
int i;
if (!stats) {
@@ -100,7 +101,7 @@
spin_lock_bh(&nss_map_t_debug_stats_lock);
for (i = 0; i < NSS_MAX_MAP_T_DYNAMIC_INTERFACES; i++) {
if (nss_map_t_debug_stats[i].valid) {
- memcpy(stats, &nss_map_t_debug_stats[i], sizeof(struct nss_stats_map_t_instance_debug));
+ memcpy(stats, &nss_map_t_debug_stats[i], sizeof(struct nss_map_t_stats_instance_debug));
stats++;
}
}
@@ -360,7 +361,7 @@
spin_lock_bh(&nss_map_t_debug_stats_lock);
for (i = 0; i < NSS_MAX_MAP_T_DYNAMIC_INTERFACES; i++) {
if (nss_map_t_debug_stats[i].if_num == if_num) {
- memset(&nss_map_t_debug_stats[i], 0, sizeof(struct nss_stats_map_t_instance_debug));
+ memset(&nss_map_t_debug_stats[i], 0, sizeof(struct nss_map_t_stats_instance_debug));
break;
}
}
@@ -399,4 +400,6 @@
sema_init(&nss_map_t_pvt.sem, 1);
init_completion(&nss_map_t_pvt.complete);
nss_core_register_handler(nss_ctx, NSS_MAP_T_INTERFACE, nss_map_t_handler, NULL);
+
+ nss_map_t_stats_dentry_create();
}
diff --git a/nss_map_t_stats.c b/nss_map_t_stats.c
new file mode 100644
index 0000000..8406d2e
--- /dev/null
+++ b/nss_map_t_stats.c
@@ -0,0 +1,119 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_map_t_stats.h"
+
+/*
+ * nss_map_t_stats_instance_str
+ * map_t statistics strings for nss session stats
+ */
+static int8_t *nss_map_t_stats_instance_str[NSS_MAP_T_STATS_MAX] = {
+ "MAP_T_V4_TO_V6_PBUF_EXCEPTION_PKTS",
+ "MAP_T_V4_TO_V6_PBUF_NO_MATCHING_RULE",
+ "MAP_T_V4_TO_V6_PBUF_NOT_TCP_OR_UDP",
+ "MAP_T_V4_TO_V6_RULE_ERR_LOCAL_PSID",
+ "MAP_T_V4_TO_V6_RULE_ERR_LOCAL_IPV6",
+ "MAP_T_V4_TO_V6_RULE_ERR_REMOTE_PSID",
+ "MAP_T_V4_TO_V6_RULE_ERR_REMOTE_EA_BITS",
+ "MAP_T_V4_TO_V6_RULE_ERR_REMOTE_IPV6",
+ "MAP_T_V6_TO_V4_PBUF_EXCEPTION_PKTS",
+ "MAP_T_V6_TO_V4_PBUF_NO_MATCHING_RULE",
+ "MAP_T_V6_TO_V4_PBUF_NOT_TCP_OR_UDP",
+ "MAP_T_V6_TO_V4_RULE_ERR_LOCAL_IPV4",
+ "MAP_T_V6_TO_V4_RULE_ERR_REMOTE_IPV4"
+};
+
+/*
+ * nss_map_t_stats_read()
+ * Read map_t statistics
+ */
+static ssize_t nss_map_t_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+
+ uint32_t max_output_lines = 2 /* header & footer for instance stats */
+ + NSS_MAX_MAP_T_DYNAMIC_INTERFACES * (NSS_MAP_T_STATS_MAX + 2) /*instance stats */
+ + 2;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ struct net_device *dev;
+ struct nss_map_t_stats_instance_debug map_t_instance_stats[NSS_MAX_MAP_T_DYNAMIC_INTERFACES];
+ int id, i;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(!lbuf)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ memset(&map_t_instance_stats, 0, sizeof(struct nss_map_t_stats_instance_debug) * NSS_MAX_MAP_T_DYNAMIC_INTERFACES);
+
+ /*
+ * Get all stats
+ */
+ nss_map_t_instance_debug_stats_get((void *)&map_t_instance_stats);
+
+ /*
+ * Session stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nmap_t instance stats start:\n\n");
+ for (id = 0; id < NSS_MAX_MAP_T_DYNAMIC_INTERFACES; id++) {
+
+ if (!map_t_instance_stats[id].valid) {
+ break;
+ }
+
+ dev = dev_get_by_index(&init_net, map_t_instance_stats[id].if_index);
+ if (likely(dev)) {
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id,
+ map_t_instance_stats[id].if_num, dev->name);
+ dev_put(dev);
+ } else {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id,
+ map_t_instance_stats[id].if_num);
+ }
+
+ for (i = 0; i < NSS_MAP_T_STATS_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %llu\n", nss_map_t_stats_instance_str[i],
+ map_t_instance_stats[id].stats[i]);
+ }
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nmap_t instance stats end\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
+
+ kfree(lbuf);
+ return bytes_read;
+}
+
+/*
+ * nss_map_t_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(map_t)
+
+/*
+ * nss_map_t_stats_dentry_create()
+ * Create map_t statistics debug entry.
+ */
+void nss_map_t_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("map_t", &nss_map_t_stats_ops);
+}
diff --git a/nss_map_t_stats.h b/nss_map_t_stats.h
new file mode 100644
index 0000000..c0704df
--- /dev/null
+++ b/nss_map_t_stats.h
@@ -0,0 +1,55 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_MAP_T_STATS_H
+#define __NSS_MAP_T_STATS_H
+
+/*
+ * MAP-T debug error types
+ */
+enum nss_map_t_stats_instance {
+ NSS_MAP_T_STATS_V4_TO_V6_PBUF_EXCEPTION,
+ NSS_MAP_T_STATS_V4_TO_V6_PBUF_NO_MATCHING_RULE,
+ NSS_MAP_T_STATS_V4_TO_V6_PBUF_NOT_TCP_OR_UDP,
+ NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_LOCAL_PSID,
+ NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_LOCAL_IPV6,
+ NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_PSID,
+ NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_EA_BITS,
+ NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_IPV6,
+ NSS_MAP_T_STATS_V6_TO_V4_PBUF_EXCEPTION,
+ NSS_MAP_T_STATS_V6_TO_V4_PBUF_NO_MATCHING_RULE,
+ NSS_MAP_T_STATS_V6_TO_V4_PBUF_NOT_TCP_OR_UDP,
+ NSS_MAP_T_STATS_V6_TO_V4_RULE_ERR_LOCAL_IPV4,
+ NSS_MAP_T_STATS_V6_TO_V4_RULE_ERR_REMOTE_IPV4,
+ NSS_MAP_T_STATS_MAX
+};
+
+/*
+ * NSS core stats -- for H2N/N2H map_t debug stats
+ */
+struct nss_map_t_stats_instance_debug {
+ uint64_t stats[NSS_MAP_T_STATS_MAX];
+ int32_t if_index;
+ uint32_t if_num; /* nss interface number */
+ bool valid;
+};
+
+/*
+ * MAP-T statistics APIs
+ */
+extern void nss_map_t_stats_dentry_create(void);
+
+#endif /* __NSS_MAP_T_STATS_H */
diff --git a/nss_n2h.c b/nss_n2h.c
index 3d6d303..e09834a 100644
--- a/nss_n2h.c
+++ b/nss_n2h.c
@@ -20,6 +20,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_n2h_stats.h"
#define NSS_N2H_MAX_BUF_POOL_SIZE (1024 * 1024 * 8) /* 8MB */
#define NSS_N2H_MIN_EMPTY_POOL_BUF_SZ 32
@@ -52,80 +53,6 @@
static struct nss_n2h_cfg_pvt nss_n2h_q_cfg_pvt;
/*
- * nss_n2h_stats_sync()
- * Handle the syncing of NSS statistics.
- */
-static void nss_n2h_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_n2h_stats_sync *nnss)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- int j;
-
- spin_lock_bh(&nss_top->stats_lock);
-
- /*
- * common node stats
- */
- nss_ctx->stats_n2h[NSS_STATS_NODE_RX_PKTS] += nnss->node_stats.rx_packets;
- nss_ctx->stats_n2h[NSS_STATS_NODE_RX_BYTES] += nnss->node_stats.rx_bytes;
- nss_ctx->stats_n2h[NSS_STATS_NODE_TX_PKTS] += nnss->node_stats.tx_packets;
- nss_ctx->stats_n2h[NSS_STATS_NODE_TX_BYTES] += nnss->node_stats.tx_bytes;
-
- for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
- nss_ctx->stats_n2h[NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nnss->node_stats.rx_dropped[j];
- }
-
- /*
- * General N2H stats
- */
- nss_ctx->stats_n2h[NSS_STATS_N2H_QUEUE_DROPPED] += nnss->queue_dropped;
- nss_ctx->stats_n2h[NSS_STATS_N2H_TOTAL_TICKS] += nnss->total_ticks;
- nss_ctx->stats_n2h[NSS_STATS_N2H_WORST_CASE_TICKS] += nnss->worst_case_ticks;
- nss_ctx->stats_n2h[NSS_STATS_N2H_ITERATIONS] += nnss->iterations;
-
- /*
- * pbuf manager ocm and default pool stats
- */
- nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_ALLOC_FAILS] += nnss->pbuf_ocm_stats.pbuf_alloc_fails;
- nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_FREE_COUNT] = nnss->pbuf_ocm_stats.pbuf_free_count;
- nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_TOTAL_COUNT] = nnss->pbuf_ocm_stats.pbuf_total_count;
-
- nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_ALLOC_FAILS] += nnss->pbuf_default_stats.pbuf_alloc_fails;
- nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_FREE_COUNT] = nnss->pbuf_default_stats.pbuf_free_count;
- nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_TOTAL_COUNT] = nnss->pbuf_default_stats.pbuf_total_count;
-
- /*
- * payload mgr stats
- */
- nss_ctx->stats_n2h[NSS_STATS_N2H_PAYLOAD_ALLOC_FAILS] += nnss->payload_alloc_fails;
- nss_ctx->stats_n2h[NSS_STATS_N2H_PAYLOAD_FREE_COUNT] = nnss->payload_free_count;
-
- /*
- * Host <=> NSS control traffic stats
- */
- nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_CONTROL_PACKETS] += nnss->h2n_ctrl_pkts;
- nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_CONTROL_BYTES] += nnss->h2n_ctrl_bytes;
- nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_CONTROL_PACKETS] += nnss->n2h_ctrl_pkts;
- nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_CONTROL_BYTES] += nnss->n2h_ctrl_bytes;
-
- /*
- * Host <=> NSS control data traffic stats
- */
- nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_DATA_PACKETS] += nnss->h2n_data_pkts;
- nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_DATA_BYTES] += nnss->h2n_data_bytes;
- nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_DATA_PACKETS] += nnss->n2h_data_pkts;
- nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_DATA_BYTES] += nnss->n2h_data_bytes;
-
- /*
- * Payloads related stats
- */
- nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_TOT_PAYLOADS] = nnss->tot_payloads;
-
- nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_INTERFACE_INVALID] += nnss->data_interface_invalid;
-
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
* nss_n2h_interface_handler()
* Handle NSS -> HLOS messages for N2H node
*/
@@ -1853,6 +1780,8 @@
init_completion(&nss_n2h_q_cfg_pvt.complete);
nss_core_register_handler(nss_ctx, NSS_N2H_INTERFACE, nss_n2h_interface_handler, NULL);
+
+ nss_n2h_stats_dentry_create();
}
/*
diff --git a/nss_n2h_stats.c b/nss_n2h_stats.c
new file mode 100644
index 0000000..b188c14
--- /dev/null
+++ b/nss_n2h_stats.c
@@ -0,0 +1,205 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_n2h_stats.h"
+
+/*
+ * nss_n2h_stats_str
+ * N2H stats strings
+ */
+static int8_t *nss_n2h_stats_str[NSS_N2H_STATS_MAX] = {
+ "rx_packets",
+ "rx_bytes",
+ "tx_packets",
+ "tx_bytes",
+ "rx_queue_0_dropped",
+ "rx_queue_1_dropped",
+ "rx_queue_2_dropped",
+ "rx_queue_3_dropped",
+ "queue_dropped",
+ "ticks",
+ "worst_ticks",
+ "iterations",
+ "pbuf_ocm_alloc_fails",
+ "pbuf_ocm_free_count",
+ "pbuf_ocm_total_count",
+ "pbuf_default_alloc_fails",
+ "pbuf_default_free_count",
+ "pbuf_default_total_count",
+ "payload_fails",
+ "payload_free_count",
+ "h2n_control_packets",
+ "h2n_control_bytes",
+ "n2h_control_packets",
+ "n2h_control_bytes",
+ "h2n_data_packets",
+ "h2n_data_bytes",
+ "n2h_data_packets",
+ "n2h_data_bytes",
+ "n2h_tot_payloads",
+ "n2h_data_interface_invalid",
+};
+
+uint64_t nss_n2h_stats[NSS_MAX_CORES][NSS_N2H_STATS_MAX];
+
+/*
+ * nss_n2h_stats_read()
+ * Read N2H stats
+ */
+static ssize_t nss_n2h_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i, core;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_N2H_STATS_MAX + 3) * 2 + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ stats_shadow = kzalloc(NSS_N2H_STATS_MAX * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "n2h stats start:\n\n");
+
+ /*
+ * N2H node stats
+ */
+ for (core = 0; core < NSS_MAX_CORES; core++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h core %d stats:\n\n", core);
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; i < NSS_N2H_STATS_MAX; i++) {
+ stats_shadow[i] = nss_n2h_stats[core][i];
+ }
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; i < NSS_N2H_STATS_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_n2h_stats_str[i], stats_shadow[i]);
+ }
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_n2h_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(n2h)
+
+/*
+ * nss_n2h_stats_dentry_create()
+ * Create N2H statistics debug entry.
+ */
+void nss_n2h_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("n2h", &nss_n2h_stats_ops);
+}
+
+/*
+ * nss_n2h_stats_sync()
+ * Handle the syncing of NSS statistics.
+ */
+void nss_n2h_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_n2h_stats_sync *nnss)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ int id = nss_ctx->id;
+ int j;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ /*
+ * common node stats
+ */
+ nss_n2h_stats[id][NSS_STATS_NODE_RX_PKTS] += nnss->node_stats.rx_packets;
+ nss_n2h_stats[id][NSS_STATS_NODE_RX_BYTES] += nnss->node_stats.rx_bytes;
+ nss_n2h_stats[id][NSS_STATS_NODE_TX_PKTS] += nnss->node_stats.tx_packets;
+ nss_n2h_stats[id][NSS_STATS_NODE_TX_BYTES] += nnss->node_stats.tx_bytes;
+
+ for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
+ nss_n2h_stats[id][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nnss->node_stats.rx_dropped[j];
+ }
+
+ /*
+ * General N2H stats
+ */
+ nss_n2h_stats[id][NSS_N2H_STATS_QUEUE_DROPPED] += nnss->queue_dropped;
+ nss_n2h_stats[id][NSS_N2H_STATS_TOTAL_TICKS] += nnss->total_ticks;
+ nss_n2h_stats[id][NSS_N2H_STATS_WORST_CASE_TICKS] += nnss->worst_case_ticks;
+ nss_n2h_stats[id][NSS_N2H_STATS_ITERATIONS] += nnss->iterations;
+
+ /*
+ * pbuf manager ocm and default pool stats
+ */
+ nss_n2h_stats[id][NSS_N2H_STATS_PBUF_OCM_ALLOC_FAILS] += nnss->pbuf_ocm_stats.pbuf_alloc_fails;
+ nss_n2h_stats[id][NSS_N2H_STATS_PBUF_OCM_FREE_COUNT] = nnss->pbuf_ocm_stats.pbuf_free_count;
+ nss_n2h_stats[id][NSS_N2H_STATS_PBUF_OCM_TOTAL_COUNT] = nnss->pbuf_ocm_stats.pbuf_total_count;
+
+ nss_n2h_stats[id][NSS_N2H_STATS_PBUF_DEFAULT_ALLOC_FAILS] += nnss->pbuf_default_stats.pbuf_alloc_fails;
+ nss_n2h_stats[id][NSS_N2H_STATS_PBUF_DEFAULT_FREE_COUNT] = nnss->pbuf_default_stats.pbuf_free_count;
+ nss_n2h_stats[id][NSS_N2H_STATS_PBUF_DEFAULT_TOTAL_COUNT] = nnss->pbuf_default_stats.pbuf_total_count;
+
+ /*
+ * payload mgr stats
+ */
+ nss_n2h_stats[id][NSS_N2H_STATS_PAYLOAD_ALLOC_FAILS] += nnss->payload_alloc_fails;
+ nss_n2h_stats[id][NSS_N2H_STATS_PAYLOAD_FREE_COUNT] = nnss->payload_free_count;
+
+ /*
+ * Host <=> NSS control traffic stats
+ */
+ nss_n2h_stats[id][NSS_N2H_STATS_H2N_CONTROL_PACKETS] += nnss->h2n_ctrl_pkts;
+ nss_n2h_stats[id][NSS_N2H_STATS_H2N_CONTROL_BYTES] += nnss->h2n_ctrl_bytes;
+ nss_n2h_stats[id][NSS_N2H_STATS_N2H_CONTROL_PACKETS] += nnss->n2h_ctrl_pkts;
+ nss_n2h_stats[id][NSS_N2H_STATS_N2H_CONTROL_BYTES] += nnss->n2h_ctrl_bytes;
+
+ /*
+ * Host <=> NSS control data traffic stats
+ */
+ nss_n2h_stats[id][NSS_N2H_STATS_H2N_DATA_PACKETS] += nnss->h2n_data_pkts;
+ nss_n2h_stats[id][NSS_N2H_STATS_H2N_DATA_BYTES] += nnss->h2n_data_bytes;
+ nss_n2h_stats[id][NSS_N2H_STATS_N2H_DATA_PACKETS] += nnss->n2h_data_pkts;
+ nss_n2h_stats[id][NSS_N2H_STATS_N2H_DATA_BYTES] += nnss->n2h_data_bytes;
+
+ /*
+ * Payloads related stats
+ */
+ nss_n2h_stats[id][NSS_N2H_STATS_N2H_TOT_PAYLOADS] = nnss->tot_payloads;
+
+ nss_n2h_stats[id][NSS_N2H_STATS_N2H_INTERFACE_INVALID] += nnss->data_interface_invalid;
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
+
diff --git a/nss_n2h_stats.h b/nss_n2h_stats.h
new file mode 100644
index 0000000..58d76d2
--- /dev/null
+++ b/nss_n2h_stats.h
@@ -0,0 +1,62 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_N2H_STATS_H
+#define __NSS_N2H_STATS_H
+
+/*
+ * N2H node statistics
+ */
+enum nss_n2h_stats_types {
+ NSS_N2H_STATS_QUEUE_DROPPED = NSS_STATS_NODE_MAX,
+ /* Number of packets dropped because the exception queue is too full */
+ NSS_N2H_STATS_TOTAL_TICKS, /* Total clock ticks spend inside the N2H */
+ NSS_N2H_STATS_WORST_CASE_TICKS, /* Worst case iteration of the exception path in ticks */
+ NSS_N2H_STATS_ITERATIONS, /* Number of iterations around the N2H */
+
+ NSS_N2H_STATS_PBUF_OCM_ALLOC_FAILS, /* Number of pbuf ocm allocations that have failed */
+ NSS_N2H_STATS_PBUF_OCM_FREE_COUNT, /* Number of pbuf ocm free count */
+ NSS_N2H_STATS_PBUF_OCM_TOTAL_COUNT, /* Number of pbuf ocm total count */
+
+ NSS_N2H_STATS_PBUF_DEFAULT_ALLOC_FAILS, /* Number of pbuf default allocations that have failed */
+ NSS_N2H_STATS_PBUF_DEFAULT_FREE_COUNT, /* Number of pbuf default free count */
+ NSS_N2H_STATS_PBUF_DEFAULT_TOTAL_COUNT, /* Number of pbuf default total count */
+
+ NSS_N2H_STATS_PAYLOAD_ALLOC_FAILS, /* Number of pbuf allocations that have failed because there were no free payloads */
+ NSS_N2H_STATS_PAYLOAD_FREE_COUNT, /* Number of free payloads that exist */
+
+ NSS_N2H_STATS_H2N_CONTROL_PACKETS, /* Control packets received from HLOS */
+ NSS_N2H_STATS_H2N_CONTROL_BYTES, /* Control bytes received from HLOS */
+ NSS_N2H_STATS_N2H_CONTROL_PACKETS, /* Control packets sent to HLOS */
+ NSS_N2H_STATS_N2H_CONTROL_BYTES, /* Control bytes sent to HLOS */
+
+ NSS_N2H_STATS_H2N_DATA_PACKETS, /* Data packets received from HLOS */
+ NSS_N2H_STATS_H2N_DATA_BYTES, /* Data bytes received from HLOS */
+ NSS_N2H_STATS_N2H_DATA_PACKETS, /* Data packets sent to HLOS */
+ NSS_N2H_STATS_N2H_DATA_BYTES, /* Data bytes sent to HLOS */
+ NSS_N2H_STATS_N2H_TOT_PAYLOADS, /* No. of payloads in NSS */
+ NSS_N2H_STATS_N2H_INTERFACE_INVALID, /* No. of bad interface access */
+
+ NSS_N2H_STATS_MAX,
+};
+
+/*
+ * N2H statistics APIs
+ */
+extern void nss_n2h_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_n2h_stats_sync *nnss);
+extern void nss_n2h_stats_dentry_create(void);
+
+#endif /* __NSS_N2H_STATS_H */
diff --git a/nss_portid.c b/nss_portid.c
index 3476a44..66e1e47 100644
--- a/nss_portid.c
+++ b/nss_portid.c
@@ -15,6 +15,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_portid_stats.h"
/*
* Spinlock to protect portid interface create/destroy/update
@@ -35,63 +36,7 @@
/*
* Array of portid interface handles. Indexing based on the physical port_id
*/
-struct nss_portid_handle {
- uint32_t if_num; /**< Interface number */
- struct rtnl_link_stats64 stats; /**< statistics counters */
-};
-static struct nss_portid_handle nss_portid_hdl[NSS_PORTID_MAX_SWITCH_PORT];
-
-/*
- * nss_portid_node_sync_update()
- * Update portid node stats.
- */
-static void nss_portid_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_portid_stats_sync_msg *npsm)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- struct nss_portid_handle *hdl;
- int j;
-
- if (npsm->port_id == NSS_PORTID_MAX_SWITCH_PORT) {
- /*
- * Update PORTID base node stats.
- */
- spin_lock_bh(&nss_top->stats_lock);
- nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_RX_PKTS] += npsm->node_stats.rx_packets;
- nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_RX_BYTES] += npsm->node_stats.rx_bytes;
- nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_TX_PKTS] += npsm->node_stats.tx_packets;
- nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_TX_BYTES] += npsm->node_stats.tx_bytes;
-
- for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
- nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += npsm->node_stats.rx_dropped[j];
- }
-
- nss_top->stats_portid[NSS_STATS_PORTID_RX_INVALID_HEADER] += npsm->rx_invalid_header;
- spin_unlock_bh(&nss_top->stats_lock);
- return;
- }
-
- if (npsm->port_id >= NSS_PORTID_MAX_SWITCH_PORT) {
- nss_warning("port_id %d exceeds NSS_PORTID_MAX_SWITCH_PORT\n", npsm->port_id);
- return;
- }
-
- /*
- * Update PORTID interface stats.
- */
- spin_lock_bh(&nss_portid_spinlock);
- hdl = &nss_portid_hdl[npsm->port_id];
- if (hdl->if_num == 0) {
- nss_warning("%p: nss_portid recv'd stats with unconfigured port %d", nss_ctx, npsm->port_id);
- spin_unlock_bh(&nss_portid_spinlock);
- return;
- }
- hdl->stats.rx_packets += npsm->node_stats.rx_packets;
- hdl->stats.rx_bytes += npsm->node_stats.rx_bytes;
- hdl->stats.rx_dropped += nss_cmn_rx_dropped_sum(&npsm->node_stats);
- hdl->stats.tx_packets += npsm->node_stats.tx_packets;
- hdl->stats.tx_bytes += npsm->node_stats.tx_bytes;
- spin_unlock_bh(&nss_portid_spinlock);
-}
+struct nss_portid_handle nss_portid_hdl[NSS_PORTID_MAX_SWITCH_PORT];
/*
* nss_portid_handler()
@@ -128,7 +73,7 @@
/*
* Update portid statistics.
*/
- nss_portid_sync_update(nss_ctx, &npm->msg.stats_sync);
+ nss_portid_stats_sync(nss_ctx, &npm->msg.stats_sync);
break;
}
@@ -497,6 +442,8 @@
nss_core_register_handler(nss_ctx, NSS_PORTID_INTERFACE, nss_portid_handler, NULL);
+ nss_portid_stats_dentry_create();
+
sema_init(&pid.sem, 1);
init_completion(&pid.complete);
}
diff --git a/nss_portid_stats.c b/nss_portid_stats.c
new file mode 100644
index 0000000..4400bfd
--- /dev/null
+++ b/nss_portid_stats.c
@@ -0,0 +1,157 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_portid_stats.h"
+
+extern spinlock_t nss_portid_spinlock;
+extern struct nss_portid_handle nss_portid_hdl[];
+
+/*
+ * nss_portid_stats_str
+ * PortID statistics strings
+ */
+static int8_t *nss_portid_stats_str[NSS_PORTID_STATS_MAX] = {
+ "RX_INVALID_HEADER",
+};
+
+uint64_t nss_portid_stats[NSS_PORTID_STATS_MAX];
+
+/*
+ * nss_portid_stats_read()
+ * Read PortID stats
+ */
+static ssize_t nss_portid_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = NSS_STATS_NODE_MAX + NSS_PORTID_STATS_MAX + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "portid stats start:\n\n");
+
+ size_wr = nss_stats_fill_common_stats(NSS_PORTID_INTERFACE, lbuf, size_wr, size_al);
+
+ /*
+ * PortID node stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nportid node stats:\n\n");
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_PORTID_STATS_MAX); i++) {
+ stats_shadow[i] = nss_portid_stats[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_PORTID_STATS_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_portid_stats_str[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nportid stats end\n\n");
+
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_portid_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(portid)
+
+/*
+ * nss_portid_stats_dentry_create()
+ * Create portid node statistics debug entry.
+ */
+void nss_portid_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("portid", &nss_portid_stats_ops);
+}
+
+/*
+ * nss_portid_stats_sync()
+ * Update portid node stats.
+ */
+void nss_portid_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_portid_stats_sync_msg *npsm)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ struct nss_portid_handle *hdl;
+ int j;
+
+ if (npsm->port_id == NSS_PORTID_MAX_SWITCH_PORT) {
+ /*
+ * Update PORTID base node stats.
+ */
+ spin_lock_bh(&nss_top->stats_lock);
+ nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_RX_PKTS] += npsm->node_stats.rx_packets;
+ nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_RX_BYTES] += npsm->node_stats.rx_bytes;
+ nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_TX_PKTS] += npsm->node_stats.tx_packets;
+ nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_TX_BYTES] += npsm->node_stats.tx_bytes;
+
+ for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
+ nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += npsm->node_stats.rx_dropped[j];
+ }
+
+ nss_portid_stats[NSS_PORTID_STATS_RX_INVALID_HEADER] += npsm->rx_invalid_header;
+ spin_unlock_bh(&nss_top->stats_lock);
+ return;
+ }
+
+ if (npsm->port_id >= NSS_PORTID_MAX_SWITCH_PORT) {
+ nss_warning("port_id %d exceeds NSS_PORTID_MAX_SWITCH_PORT\n", npsm->port_id);
+ return;
+ }
+
+ /*
+ * Update PORTID interface stats.
+ */
+ spin_lock_bh(&nss_portid_spinlock);
+ hdl = &nss_portid_hdl[npsm->port_id];
+ if (hdl->if_num == 0) {
+ nss_warning("%p: nss_portid recv'd stats with unconfigured port %d", nss_ctx, npsm->port_id);
+ spin_unlock_bh(&nss_portid_spinlock);
+ return;
+ }
+ hdl->stats.rx_packets += npsm->node_stats.rx_packets;
+ hdl->stats.rx_bytes += npsm->node_stats.rx_bytes;
+ hdl->stats.rx_dropped += nss_cmn_rx_dropped_sum(&npsm->node_stats);
+ hdl->stats.tx_packets += npsm->node_stats.tx_packets;
+ hdl->stats.tx_bytes += npsm->node_stats.tx_bytes;
+ spin_unlock_bh(&nss_portid_spinlock);
+}
diff --git a/nss_portid_stats.h b/nss_portid_stats.h
new file mode 100644
index 0000000..b1a1ee5
--- /dev/null
+++ b/nss_portid_stats.h
@@ -0,0 +1,39 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_PORTID_STATS_H
+#define __NSS_PORTID_STATS_H
+
+/*
+ * PortID statistics
+ */
+enum nss_portid_stats_types {
+ NSS_PORTID_STATS_RX_INVALID_HEADER,
+ NSS_PORTID_STATS_MAX,
+};
+
+struct nss_portid_handle {
+ uint32_t if_num; /**< Interface number */
+ struct rtnl_link_stats64 stats; /**< statistics counters */
+};
+
+/*
+ * PortID statistics APIs
+ */
+extern void nss_portid_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_portid_stats_sync_msg *npsm);
+extern void nss_portid_stats_dentry_create(void);
+
+#endif /* __NSS_PORTID_STATS_H */
diff --git a/nss_ppe.c b/nss_ppe.c
index c66327e..1a07cdb 100644
--- a/nss_ppe.c
+++ b/nss_ppe.c
@@ -15,90 +15,7 @@
*/
#include "nss_ppe.h"
-
-static uint8_t ppe_cc_nonexception[NSS_STATS_PPE_CPU_CODE_NONEXCEPTION_MAX] = {
- NSS_STATS_PPE_CPU_CODE_EXP_FAKE_L2_PROT_ERR,
- NSS_STATS_PPE_CPU_CODE_EXP_FAKE_MAC_HEADER_ERR,
- NSS_STATS_PPE_CPU_CODE_EXP_BITMAP_MAX,
- NSS_STATS_PPE_CPU_CODE_L2_EXP_MRU_FAIL,
- NSS_STATS_PPE_CPU_CODE_L2_EXP_MTU_FAIL,
- NSS_STATS_PPE_CPU_CODE_L3_EXP_IP_PREFIX_BC,
- NSS_STATS_PPE_CPU_CODE_L3_EXP_MTU_FAIL,
- NSS_STATS_PPE_CPU_CODE_L3_EXP_MRU_FAIL,
- NSS_STATS_PPE_CPU_CODE_L3_EXP_ICMP_RDT,
- NSS_STATS_PPE_CPU_CODE_L3_EXP_IP_RT_TTL1_TO_ME,
- NSS_STATS_PPE_CPU_CODE_L3_EXP_IP_RT_TTL_ZERO,
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_SERVICE_CODE_LOOP,
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_DE_ACCELERATE,
- NSS_STATS_PPE_CPU_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL,
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH,
- NSS_STATS_PPE_CPU_CODE_L3_EXP_MTU_DF_FAIL,
- NSS_STATS_PPE_CPU_CODE_L3_EXP_PPPOE_MULTICAST,
- NSS_STATS_PPE_CPU_CODE_MGMT_OFFSET,
- NSS_STATS_PPE_CPU_CODE_MGMT_EAPOL,
- NSS_STATS_PPE_CPU_CODE_MGMT_PPPOE_DIS,
- NSS_STATS_PPE_CPU_CODE_MGMT_IGMP,
- NSS_STATS_PPE_CPU_CODE_MGMT_ARP_REQ,
- NSS_STATS_PPE_CPU_CODE_MGMT_ARP_REP,
- NSS_STATS_PPE_CPU_CODE_MGMT_DHCPv4,
- NSS_STATS_PPE_CPU_CODE_MGMT_MLD,
- NSS_STATS_PPE_CPU_CODE_MGMT_NS,
- NSS_STATS_PPE_CPU_CODE_MGMT_NA,
- NSS_STATS_PPE_CPU_CODE_MGMT_DHCPv6,
- NSS_STATS_PPE_CPU_CODE_PTP_OFFSET,
- NSS_STATS_PPE_CPU_CODE_PTP_SYNC,
- NSS_STATS_PPE_CPU_CODE_PTP_FOLLOW_UP,
- NSS_STATS_PPE_CPU_CODE_PTP_DELAY_REQ,
- NSS_STATS_PPE_CPU_CODE_PTP_DELAY_RESP,
- NSS_STATS_PPE_CPU_CODE_PTP_PDELAY_REQ,
- NSS_STATS_PPE_CPU_CODE_PTP_PDELAY_RESP,
- NSS_STATS_PPE_CPU_CODE_PTP_PDELAY_RESP_FOLLOW_UP,
- NSS_STATS_PPE_CPU_CODE_PTP_ANNOUNCE,
- NSS_STATS_PPE_CPU_CODE_PTP_MANAGEMENT,
- NSS_STATS_PPE_CPU_CODE_PTP_SIGNALING,
- NSS_STATS_PPE_CPU_CODE_PTP_PKT_RSV_MSG,
- NSS_STATS_PPE_CPU_CODE_IPV4_SG_UNKNOWN,
- NSS_STATS_PPE_CPU_CODE_IPV6_SG_UNKNOWN,
- NSS_STATS_PPE_CPU_CODE_ARP_SG_UNKNOWN,
- NSS_STATS_PPE_CPU_CODE_ND_SG_UNKNOWN,
- NSS_STATS_PPE_CPU_CODE_IPV4_SG_VIO,
- NSS_STATS_PPE_CPU_CODE_IPV6_SG_VIO,
- NSS_STATS_PPE_CPU_CODE_ARP_SG_VIO,
- NSS_STATS_PPE_CPU_CODE_ND_SG_VIO,
- NSS_STATS_PPE_CPU_CODE_L3_ROUTING_IP_TO_ME,
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_SNAT_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_DNAT_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_RT_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_BR_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_MC_BRIDGE_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_RT_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAPT_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAPT_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAT_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAT_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR,
- NSS_STATS_PPE_CPU_CODE_L3_ROUTE_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_NH_INVALID_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_BRIDGE_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_ACTION,
- NSS_STATS_PPE_CPU_CODE_L3_FLOW_MISS_ACTION,
- NSS_STATS_PPE_CPU_CODE_L2_NEW_MAC_ADDRESS,
- NSS_STATS_PPE_CPU_CODE_L2_HASH_COLLISION,
- NSS_STATS_PPE_CPU_CODE_L2_STATION_MOVE,
- NSS_STATS_PPE_CPU_CODE_L2_LEARN_LIMIT,
- NSS_STATS_PPE_CPU_CODE_L2_SA_LOOKUP_ACTION,
- NSS_STATS_PPE_CPU_CODE_L2_DA_LOOKUP_ACTION,
- NSS_STATS_PPE_CPU_CODE_APP_CTRL_ACTION,
- NSS_STATS_PPE_CPU_CODE_IN_VLAN_FILTER_ACTION,
- NSS_STATS_PPE_CPU_CODE_IN_VLAN_XLT_MISS,
- NSS_STATS_PPE_CPU_CODE_EG_VLAN_FILTER_DROP,
- NSS_STATS_PPE_CPU_CODE_ACL_PRE_ACTION,
- NSS_STATS_PPE_CPU_CODE_ACL_POST_ACTION,
- NSS_STATS_PPE_CPU_CODE_SERVICE_CODE_ACTION,
-};
+#include "nss_ppe_stats.h"
/*
* nss_ppe_verify_ifnum()
@@ -110,54 +27,6 @@
}
/*
- * nss_ppe_stats_sync
- * PPE connection sync stats from NSS
- */
-static void nss_ppe_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_sync_stats_msg *stats_msg, uint16_t if_num)
-{
- spin_lock_bh(&nss_ppe_stats_lock);
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_L3_FLOWS] += stats_msg->nss_ppe_v4_l3_flows;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_L2_FLOWS] += stats_msg->nss_ppe_v4_l2_flows;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_CREATE_REQ] += stats_msg->nss_ppe_v4_create_req;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_CREATE_FAIL] += stats_msg->nss_ppe_v4_create_fail;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_DESTROY_REQ] += stats_msg->nss_ppe_v4_destroy_req;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_DESTROY_FAIL] += stats_msg->nss_ppe_v4_destroy_fail;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_CREATE_REQ] += stats_msg->nss_ppe_v4_mc_create_req;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_CREATE_FAIL] += stats_msg->nss_ppe_v4_mc_create_fail;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_UPDATE_REQ] += stats_msg->nss_ppe_v4_mc_update_req;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_UPDATE_FAIL] += stats_msg->nss_ppe_v4_mc_update_fail;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_DESTROY_REQ] += stats_msg->nss_ppe_v4_mc_destroy_req;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_DESTROY_FAIL] += stats_msg->nss_ppe_v4_mc_destroy_fail;
-
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_L3_FLOWS] += stats_msg->nss_ppe_v6_l3_flows;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_L2_FLOWS] += stats_msg->nss_ppe_v6_l2_flows;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_CREATE_REQ] += stats_msg->nss_ppe_v6_create_req;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_CREATE_FAIL] += stats_msg->nss_ppe_v6_create_fail;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_DESTROY_REQ] += stats_msg->nss_ppe_v6_destroy_req;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_DESTROY_FAIL] += stats_msg->nss_ppe_v6_destroy_fail;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_CREATE_REQ] += stats_msg->nss_ppe_v6_mc_create_req;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_CREATE_FAIL] += stats_msg->nss_ppe_v6_mc_create_fail;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_UPDATE_REQ] += stats_msg->nss_ppe_v6_mc_update_req;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_UPDATE_FAIL] += stats_msg->nss_ppe_v6_mc_update_fail;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_DESTROY_REQ] += stats_msg->nss_ppe_v6_mc_destroy_req;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_DESTROY_FAIL] += stats_msg->nss_ppe_v6_mc_destroy_fail;
-
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_VP_FULL] += stats_msg->nss_ppe_fail_vp_full;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_NH_FULL] += stats_msg->nss_ppe_fail_nh_full;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_FLOW_FULL] += stats_msg->nss_ppe_fail_flow_full;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_HOST_FULL] += stats_msg->nss_ppe_fail_host_full;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_PUBIP_FULL] += stats_msg->nss_ppe_fail_pubip_full;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_PORT_SETUP] += stats_msg->nss_ppe_fail_port_setup;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_RW_FIFO_FULL] += stats_msg->nss_ppe_fail_rw_fifo_full;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_FLOW_COMMAND] += stats_msg->nss_ppe_fail_flow_command;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_UNKNOWN_PROTO] += stats_msg->nss_ppe_fail_unknown_proto;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_PPE_UNRESPONSIVE] += stats_msg->nss_ppe_fail_ppe_unresponsive;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_CE_OPAQUE_INVALID] += stats_msg->nss_ppe_ce_opaque_invalid;
- nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_FQG_FULL] += stats_msg->nss_ppe_fail_fqg_full;
- spin_unlock_bh(&nss_ppe_stats_lock);
-}
-
-/*
* nss_ppe_callback()
* Callback to handle the completion of NSS->HLOS messages.
*/
@@ -322,195 +191,6 @@
EXPORT_SYMBOL(nss_ppe_tx_l2_exception_msg);
/*
- * nss_ppe_stats_conn_get()
- * Get ppe connection stats.
- */
-void nss_ppe_stats_conn_get(uint32_t *stats)
-{
- if (!stats) {
- nss_warning("No memory to copy ppe connection stats\n");
- return;
- }
-
- spin_lock_bh(&nss_ppe_stats_lock);
-
- if (!nss_ppe_debug_stats.valid) {
- spin_unlock_bh(&nss_ppe_stats_lock);
- nss_warning("PPE base address not initialized!\n");
- return;
- }
-
- /*
- * Get flow stats
- */
- memcpy(stats, nss_ppe_debug_stats.conn_stats, (sizeof(uint32_t) * NSS_STATS_PPE_CONN_MAX));
-
- spin_unlock_bh(&nss_ppe_stats_lock);
-}
-
-/*
- * nss_ppe_stats_l3_get()
- * Get ppe L3 debug stats.
- */
-void nss_ppe_stats_l3_get(uint32_t *stats)
-{
- if (!stats) {
- nss_warning("No memory to copy ppe l3 dbg stats\n");
- return;
- }
-
- spin_lock_bh(&nss_ppe_stats_lock);
-
- if (!nss_ppe_debug_stats.valid) {
- spin_unlock_bh(&nss_ppe_stats_lock);
- nss_warning("PPE base address not initialized!\n");
- return;
- }
-
- nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG0_OFFSET);
- nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_0]);
-
- nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG1_OFFSET);
- nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_1]);
-
- nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG2_OFFSET);
- nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_2]);
-
- nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG3_OFFSET);
- nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_3]);
-
- nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG4_OFFSET);
- nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_4]);
-
- nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG_PORT_OFFSET);
- nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_PORT]);
-
- spin_unlock_bh(&nss_ppe_stats_lock);
-}
-
-/*
- * nss_ppe_stats_code_get()
- * Get ppe CPU and DROP code for last packet processed.
- */
-void nss_ppe_stats_code_get(uint32_t *stats)
-{
- uint32_t drop_0, drop_1, cpu_code;
-
- nss_trace("%s(%d) Start\n", __func__, __LINE__);
- if (!stats) {
- nss_warning("No memory to copy ppe code\n");
- return;
- }
-
- if (!nss_ppe_debug_stats.valid) {
- nss_warning("PPE base address not initialized!\n");
- return;
- }
-
- spin_lock_bh(&nss_ppe_stats_lock);
- nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_DROP0_OFFSET);
- nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &drop_0);
-
- nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_DROP1_OFFSET);
- nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &drop_1);
-
- stats[NSS_STATS_PPE_CODE_DROP] = PPE_PKT_CODE_DROP_GET(drop_0, drop_1);
-
- nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_CPU_OFFSET);
- nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &cpu_code);
-
- stats[NSS_STATS_PPE_CODE_CPU] = PPE_PKT_CODE_CPU_GET(cpu_code);
-
- spin_unlock_bh(&nss_ppe_stats_lock);
-}
-
-/*
- * nss_ppe_port_drop_code_get()
- * Get ppe per port drop code.
- */
-void nss_ppe_port_drop_code_get(uint32_t *stats, uint8_t port_id)
-{
- uint8_t i;
- nss_trace("%s(%d) Start\n", __func__, __LINE__);
- if (!stats) {
- nss_warning("No memory to copy ppe code\n");
- return;
- }
-
- if (port_id > NSS_PPE_NUM_PHY_PORTS_MAX) {
- nss_warning("Port id is out of range\n");
- return;
- }
-
- if (!nss_ppe_debug_stats.valid) {
- nss_warning("PPE base address not initialized!\n");
- return;
- }
-
- spin_lock_bh(&nss_ppe_stats_lock);
-
- for (i = 0; i < NSS_STATS_PPE_DROP_CODE_MAX; i++) {
- nss_ppe_reg_read(PPE_DROP_CODE_OFFSET(i, port_id), &stats[i]);
- }
-
- spin_unlock_bh(&nss_ppe_stats_lock);
-}
-
-/*
- * nss_ppe_cpu_code_exception_get()
- * Get ppe cpu code specific for flow exceptions.
- */
-void nss_ppe_cpu_code_exception_get(uint32_t *stats)
-{
- uint8_t i;
- nss_trace("%s(%d) Start\n", __func__, __LINE__);
- if (!stats) {
- nss_warning("No memory to copy ppe code\n");
- return;
- }
-
- if (!nss_ppe_debug_stats.valid) {
- nss_warning("PPE base address not initialized!\n");
- return;
- }
-
- spin_lock_bh(&nss_ppe_stats_lock);
-
- for (i = 0; i < NSS_STATS_PPE_CPU_CODE_EXCEPTION_MAX ; i++) {
- nss_ppe_reg_read(PPE_CPU_CODE_OFFSET(i), &stats[i]);
- }
-
- spin_unlock_bh(&nss_ppe_stats_lock);
-}
-
-/*
- * nss_ppe_cpu_code_nonexception_get()
- * Get ppe cpu code specific for flow exceptions.
- */
-void nss_ppe_cpu_code_nonexception_get(uint32_t *stats)
-{
- uint8_t i;
- nss_trace("%s(%d) Start\n", __func__, __LINE__);
- if (!stats) {
- nss_warning("No memory to copy ppe code\n");
- return;
- }
-
- if (!nss_ppe_debug_stats.valid) {
- nss_warning("PPE base address not initialized!\n");
- return;
- }
-
- spin_lock_bh(&nss_ppe_stats_lock);
-
- for (i = 0; i < NSS_STATS_PPE_CPU_CODE_NONEXCEPTION_MAX; i++) {
- nss_ppe_reg_read(PPE_CPU_CODE_OFFSET(ppe_cc_nonexception[i]), &stats[i]);
- }
-
- spin_unlock_bh(&nss_ppe_stats_lock);
-}
-
-/*
* nss_ppe_handler()
* Handle NSS -> HLOS messages for ppe
*/
@@ -578,6 +258,8 @@
struct nss_ctx_instance *nss_ctx = nss_ppe_get_context();
nss_core_register_handler(nss_ctx, NSS_PPE_INTERFACE, nss_ppe_handler, NULL);
+
+ nss_ppe_stats_dentry_create();
}
/*
diff --git a/nss_ppe.h b/nss_ppe.h
index 7139819..5f4e90e 100644
--- a/nss_ppe.h
+++ b/nss_ppe.h
@@ -74,7 +74,6 @@
* Data structures to store ppe nss debug stats
*/
static DEFINE_SPINLOCK(nss_ppe_stats_lock);
-static struct nss_stats_ppe_debug nss_ppe_debug_stats;
/*
* Private data structure
diff --git a/nss_ppe_stats.c b/nss_ppe_stats.c
new file mode 100644
index 0000000..df4a9d2
--- /dev/null
+++ b/nss_ppe_stats.c
@@ -0,0 +1,1144 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_core.h"
+#include "nss_ppe.h"
+#include "nss_ppe_stats.h"
+
+static uint8_t ppe_cc_nonexception[NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX] = {
+ NSS_PPE_STATS_CPU_CODE_EXP_FAKE_L2_PROT_ERR,
+ NSS_PPE_STATS_CPU_CODE_EXP_FAKE_MAC_HEADER_ERR,
+ NSS_PPE_STATS_CPU_CODE_EXP_BITMAP_MAX,
+ NSS_PPE_STATS_CPU_CODE_L2_EXP_MRU_FAIL,
+ NSS_PPE_STATS_CPU_CODE_L2_EXP_MTU_FAIL,
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_PREFIX_BC,
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_MTU_FAIL,
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_MRU_FAIL,
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_ICMP_RDT,
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_RT_TTL1_TO_ME,
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_RT_TTL_ZERO,
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_SERVICE_CODE_LOOP,
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_DE_ACCELERATE,
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL,
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH,
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_MTU_DF_FAIL,
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_PPPOE_MULTICAST,
+ NSS_PPE_STATS_CPU_CODE_MGMT_OFFSET,
+ NSS_PPE_STATS_CPU_CODE_MGMT_EAPOL,
+ NSS_PPE_STATS_CPU_CODE_MGMT_PPPOE_DIS,
+ NSS_PPE_STATS_CPU_CODE_MGMT_IGMP,
+ NSS_PPE_STATS_CPU_CODE_MGMT_ARP_REQ,
+ NSS_PPE_STATS_CPU_CODE_MGMT_ARP_REP,
+ NSS_PPE_STATS_CPU_CODE_MGMT_DHCPv4,
+ NSS_PPE_STATS_CPU_CODE_MGMT_MLD,
+ NSS_PPE_STATS_CPU_CODE_MGMT_NS,
+ NSS_PPE_STATS_CPU_CODE_MGMT_NA,
+ NSS_PPE_STATS_CPU_CODE_MGMT_DHCPv6,
+ NSS_PPE_STATS_CPU_CODE_PTP_OFFSET,
+ NSS_PPE_STATS_CPU_CODE_PTP_SYNC,
+ NSS_PPE_STATS_CPU_CODE_PTP_FOLLOW_UP,
+ NSS_PPE_STATS_CPU_CODE_PTP_DELAY_REQ,
+ NSS_PPE_STATS_CPU_CODE_PTP_DELAY_RESP,
+ NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_REQ,
+ NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_RESP,
+ NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_RESP_FOLLOW_UP,
+ NSS_PPE_STATS_CPU_CODE_PTP_ANNOUNCE,
+ NSS_PPE_STATS_CPU_CODE_PTP_MANAGEMENT,
+ NSS_PPE_STATS_CPU_CODE_PTP_SIGNALING,
+ NSS_PPE_STATS_CPU_CODE_PTP_PKT_RSV_MSG,
+ NSS_PPE_STATS_CPU_CODE_IPV4_SG_UNKNOWN,
+ NSS_PPE_STATS_CPU_CODE_IPV6_SG_UNKNOWN,
+ NSS_PPE_STATS_CPU_CODE_ARP_SG_UNKNOWN,
+ NSS_PPE_STATS_CPU_CODE_ND_SG_UNKNOWN,
+ NSS_PPE_STATS_CPU_CODE_IPV4_SG_VIO,
+ NSS_PPE_STATS_CPU_CODE_IPV6_SG_VIO,
+ NSS_PPE_STATS_CPU_CODE_ARP_SG_VIO,
+ NSS_PPE_STATS_CPU_CODE_ND_SG_VIO,
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTING_IP_TO_ME,
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_SNAT_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_DNAT_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_RT_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_BR_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_MC_BRIDGE_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_RT_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_SNAPT_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_DNAPT_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_SNAT_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_DNAT_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR,
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_NH_INVALID_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_BRIDGE_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_MISS_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L2_NEW_MAC_ADDRESS,
+ NSS_PPE_STATS_CPU_CODE_L2_HASH_COLLISION,
+ NSS_PPE_STATS_CPU_CODE_L2_STATION_MOVE,
+ NSS_PPE_STATS_CPU_CODE_L2_LEARN_LIMIT,
+ NSS_PPE_STATS_CPU_CODE_L2_SA_LOOKUP_ACTION,
+ NSS_PPE_STATS_CPU_CODE_L2_DA_LOOKUP_ACTION,
+ NSS_PPE_STATS_CPU_CODE_APP_CTRL_ACTION,
+ NSS_PPE_STATS_CPU_CODE_IN_VLAN_FILTER_ACTION,
+ NSS_PPE_STATS_CPU_CODE_IN_VLAN_XLT_MISS,
+ NSS_PPE_STATS_CPU_CODE_EG_VLAN_FILTER_DROP,
+ NSS_PPE_STATS_CPU_CODE_ACL_PRE_ACTION,
+ NSS_PPE_STATS_CPU_CODE_ACL_POST_ACTION,
+ NSS_PPE_STATS_CPU_CODE_SERVICE_CODE_ACTION,
+};
+
+/*
+ * nss_ppe_stats_str_conn
+ * PPE statistics strings for nss flow stats
+ */
+static int8_t *nss_ppe_stats_str_conn[NSS_PPE_STATS_CONN_MAX] = {
+ "v4 routed flows",
+ "v4 bridge flows",
+ "v4 conn create req",
+ "v4 conn create fail",
+ "v4 conn destroy req",
+ "v4 conn destroy fail",
+ "v4 conn MC create req",
+ "v4 conn MC create fail",
+ "v4 conn MC update req",
+ "v4 conn MC update fail",
+ "v4 conn MC delete req",
+ "v4 conn MC delete fail",
+
+ "v6 routed flows",
+ "v6 bridge flows",
+ "v6 conn create req",
+ "v6 conn create fail",
+ "v6 conn destroy req",
+ "v6 conn destroy fail",
+ "v6 conn MC create req",
+ "v6 conn MC create fail",
+ "v6 conn MC update req",
+ "v6 conn MC update fail",
+ "v6 conn MC delete req",
+ "v6 conn MC delete fail",
+
+ "conn fail - vp full",
+ "conn fail - nexthop full",
+ "conn fail - flow full",
+ "conn fail - host full",
+ "conn fail - pub-ip full",
+ "conn fail - port not setup",
+ "conn fail - rw fifo full",
+ "conn fail - flow cmd failure",
+ "conn fail - unknown proto",
+ "conn fail - ppe not responding",
+ "conn fail - CE opaque invalid",
+ "conn fail - fqg full"
+};
+
+/*
+ * nss_ppe_stats_str_l3
+ * PPE statistics strings for nss debug stats
+ */
+static int8_t *nss_ppe_stats_str_l3[NSS_PPE_STATS_L3_MAX] = {
+ "PPE L3 dbg reg 0",
+ "PPE L3 dbg reg 1",
+ "PPE L3 dbg reg 2",
+ "PPE L3 dbg reg 3",
+ "PPE L3 dbg reg 4",
+ "PPE L3 dbg reg port",
+};
+
+/*
+ * nss_ppe_stats_str_code
+ * PPE statistics strings for nss debug stats
+ */
+static int8_t *nss_ppe_stats_str_code[NSS_PPE_STATS_CODE_MAX] = {
+ "PPE CPU_CODE",
+ "PPE DROP_CODE",
+};
+
+/*
+ * nss_ppe_stats_str_dc
+ * PPE statistics strings for drop code
+ */
+static int8_t *nss_ppe_stats_str_dc[NSS_PPE_STATS_DROP_CODE_MAX] = {
+ "PPE_DROP_CODE_NONE",
+ "PPE_DROP_CODE_EXP_UNKNOWN_L2_PORT",
+ "PPE_DROP_CODE_EXP_PPPOE_WRONG_VER_TYPE",
+ "PPE_DROP_CODE_EXP_PPPOE_WRONG_CODE",
+ "PPE_DROP_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT",
+ "PPE_DROP_CODE_EXP_IPV4_WRONG_VER",
+ "PPE_DROP_CODE_EXP_IPV4_SMALL_IHL",
+ "PPE_DROP_CODE_EXP_IPV4_WITH_OPTION",
+ "PPE_DROP_CODE_EXP_IPV4_HDR_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_IPV4_BAD_TOTAL_LEN",
+ "PPE_DROP_CODE_EXP_IPV4_DATA_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_IPV4_FRAG",
+ "PPE_DROP_CODE_EXP_IPV4_PING_OF_DEATH",
+ "PPE_DROP_CODE_EXP_IPV4_SNALL_TTL",
+ "PPE_DROP_CODE_EXP_IPV4_UNK_IP_PROT",
+ "PPE_DROP_CODE_EXP_IPV4_CHECKSUM_ERR",
+ "PPE_DROP_CODE_EXP_IPV4_INV_SIP",
+ "PPE_DROP_CODE_EXP_IPV4_INV_DIP",
+ "PPE_DROP_CODE_EXP_IPV4_LAND_ATTACK",
+ "PPE_DROP_CODE_EXP_IPV4_AH_HDR_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_IPV4_AH_HDR_CROSS_BORDER",
+ "PPE_DROP_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_IPV6_WRONG_VER",
+ "PPE_DROP_CODE_EXP_IPV6_HDR_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_IPV6_BAD_PAYLOAD_LEN",
+ "PPE_DROP_CODE_EXP_IPV6_DATA_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_IPV6_WITH_EXT_HDR",
+ "PPE_DROP_CODE_EXP_IPV6_SMALL_HOP_LIMIT",
+ "PPE_DROP_CODE_EXP_IPV6_INV_SIP",
+ "PPE_DROP_CODE_EXP_IPV6_INV_DIP",
+ "PPE_DROP_CODE_EXP_IPV6_LAND_ATTACK",
+ "PPE_DROP_CODE_EXP_IPV6_FRAG",
+ "PPE_DROP_CODE_EXP_IPV6_PING_OF_DEATH",
+ "PPE_DROP_CODE_EXP_IPV6_WITH_MORE_EXT_HDR",
+ "PPE_DROP_CODE_EXP_IPV6_UNK_LAST_NEXT_HDR",
+ "PPE_DROP_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_IPV6_MOBILITY_HDR_CROSS_BORDER",
+ "PPE_DROP_CODE_EXP_IPV6_AH_HDR_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_IPV6_AH_HDR_CROSS_BORDER",
+ "PPE_DROP_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_IPV6_ESP_HDR_CROSS_BORDER",
+ "PPE_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_CROSS_BORDER",
+ "PPE_DROP_CODE_EXP_TCP_HDR_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_TCP_HDR_CROSS_BORDER",
+ "PPE_DROP_CODE_EXP_TCP_SMAE_SP_DP",
+ "PPE_DROP_CODE_EXP_TCP_SMALL_DATA_OFFSET",
+ "PPE_DROP_CODE_EXP_TCP_FLAGS_0",
+ "PPE_DROP_CODE_EXP_TCP_FLAGS_1",
+ "PPE_DROP_CODE_EXP_TCP_FLAGS_2",
+ "PPE_DROP_CODE_EXP_TCP_FLAGS_3",
+ "PPE_DROP_CODE_EXP_TCP_FLAGS_4",
+ "PPE_DROP_CODE_EXP_TCP_FLAGS_5",
+ "PPE_DROP_CODE_EXP_TCP_FLAGS_6",
+ "PPE_DROP_CODE_EXP_TCP_FLAGS_7",
+ "PPE_DROP_CODE_EXP_TCP_CHECKSUM_ERR",
+ "PPE_DROP_CODE_EXP_UDP_HDR_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_UDP_HDR_CROSS_BORDER",
+ "PPE_DROP_CODE_EXP_UDP_SMAE_SP_DP",
+ "PPE_DROP_CODE_EXP_UDP_BAD_LEN",
+ "PPE_DROP_CODE_EXP_UDP_DATA_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_UDP_CHECKSUM_ERR",
+ "PPE_DROP_CODE_EXP_UDP_LITE_HDR_INCOMPLETE",
+ "PPE_DROP_CODE_EXP_UDP_LITE_HDR_CROSS_BORDER",
+ "PPE_DROP_CODE_EXP_UDP_LITE_SMAE_SP_DP",
+ "PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_1_TO_7",
+ "PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_TOO_LONG",
+ "PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_CROSS_BORDER",
+ "PPE_DROP_CODE_EXP_UDP_LITE_CHECKSUM_ERR",
+ "PPE_DROP_CODE_L3_MC_BRIDGE_ACTION",
+ "PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION",
+ "PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR",
+ "PPE_DROP_CODE_L3_ROUTE_ACTION",
+ "PPE_DROP_CODE_L3_NO_ROUTE_ACTION",
+ "PPE_DROP_CODE_L3_NO_ROUTE_NH_INVALID_ACTION",
+ "PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_ACTION",
+ "PPE_DROP_CODE_L3_BRIDGE_ACTION",
+ "PPE_DROP_CODE_L3_FLOW_ACTION",
+ "PPE_DROP_CODE_L3_FLOW_MISS_ACTION",
+ "PPE_DROP_CODE_L2_EXP_MRU_FAIL",
+ "PPE_DROP_CODE_L2_EXP_MTU_FAIL",
+ "PPE_DROP_CODE_L3_EXP_IP_PREFIX_BC",
+ "PPE_DROP_CODE_L3_EXP_MTU_FAIL",
+ "PPE_DROP_CODE_L3_EXP_MRU_FAIL",
+ "PPE_DROP_CODE_L3_EXP_ICMP_RDT",
+ "PPE_DROP_CODE_FAKE_MAC_HEADER_ERR",
+ "PPE_DROP_CODE_L3_EXP_IP_RT_TTL_ZERO",
+ "PPE_DROP_CODE_L3_FLOW_SERVICE_CODE_LOOP",
+ "PPE_DROP_CODE_L3_FLOW_DE_ACCELEARTE",
+ "PPE_DROP_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL",
+ "PPE_DROP_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH",
+ "PPE_DROP_CODE_L3_EXP_MTU_DF_FAIL",
+ "PPE_DROP_CODE_L3_EXP_PPPOE_MULTICAST",
+ "PPE_DROP_CODE_IPV4_SG_UNKNOWN",
+ "PPE_DROP_CODE_IPV6_SG_UNKNOWN",
+ "PPE_DROP_CODE_ARP_SG_UNKNOWN",
+ "PPE_DROP_CODE_ND_SG_UNKNOWN",
+ "PPE_DROP_CODE_IPV4_SG_VIO",
+ "PPE_DROP_CODE_IPV6_SG_VIO",
+ "PPE_DROP_CODE_ARP_SG_VIO",
+ "PPE_DROP_CODE_ND_SG_VIO",
+ "PPE_DROP_CODE_L2_NEW_MAC_ADDRESS",
+ "PPE_DROP_CODE_L2_HASH_COLLISION",
+ "PPE_DROP_CODE_L2_STATION_MOVE",
+ "PPE_DROP_CODE_L2_LEARN_LIMIT",
+ "PPE_DROP_CODE_L2_SA_LOOKUP_ACTION",
+ "PPE_DROP_CODE_L2_DA_LOOKUP_ACTION",
+ "PPE_DROP_CODE_APP_CTRL_ACTION",
+ "PPE_DROP_CODE_IN_VLAN_FILTER_ACTION",
+ "PPE_DROP_CODE_IN_VLAN_XLT_MISS",
+ "PPE_DROP_CODE_EG_VLAN_FILTER_DROP",
+ "PPE_DROP_CODE_ACL_PRE_ACTION",
+ "PPE_DROP_CODE_ACL_POST_ACTION",
+ "PPE_DROP_CODE_MC_BC_SA",
+ "PPE_DROP_CODE_NO_DESTINATION",
+ "PPE_DROP_CODE_STG_IN_FILTER",
+ "PPE_DROP_CODE_STG_EG_FILTER",
+ "PPE_DROP_CODE_SOURCE_FILTER_FAIL",
+ "PPE_DROP_CODE_TRUNK_SEL_FAIL",
+ "PPE_DROP_CODE_TX_EN_FAIL",
+ "PPE_DROP_CODE_VLAN_TAG_FMT",
+ "PPE_DROP_CODE_CRC_ERR",
+ "PPE_DROP_CODE_PAUSE_FRAME",
+ "PPE_DROP_CODE_PROMISC",
+ "PPE_DROP_CODE_ISOLATION",
+ "PPE_DROP_CODE_MGMT_APP",
+ "PPE_DROP_CODE_FAKE_L2_PROT_ERR",
+ "PPE_DROP_CODE_POLICER",
+};
+
+/*
+ * nss_ppe_stats_str_cc
+ * PPE statistics strings for cpu code
+ */
+static int8_t *nss_ppe_stats_str_cc[NSS_PPE_STATS_CPU_CODE_MAX] = {
+ "PPE_CPU_CODE_FORWARDING",
+ "PPE_CPU_CODE_EXP_UNKNOWN_L2_PROT",
+ "PPE_CPU_CODE_EXP_PPPOE_WRONG_VER_TYPE",
+ "PPE_CPU_CODE_EXP_WRONG_CODE",
+ "PPE_CPU_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT",
+ "PPE_CPU_CODE_EXP_WRONG_VER",
+ "PPE_CPU_CODE_EXP_SMALL_IHL",
+ "PPE_CPU_CODE_EXP_WITH_OPTION",
+ "PPE_CPU_CODE_EXP_HDR_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_IPV4_BAD_TOTAL_LEN",
+ "PPE_CPU_CODE_EXP_DATA_INCOMPLETE",
+ "PPE_CPU_CODE_IPV4_FRAG",
+ "PPE_CPU_CODE_EXP_IPV4_PING_OF_DEATH",
+ "PPE_CPU_CODE_EXP_SNALL_TTL",
+ "PPE_CPU_CODE_EXP_IPV4_UNK_IP_PROT",
+ "PPE_CPU_CODE_EXP_CHECKSUM_ERR",
+ "PPE_CPU_CODE_EXP_INV_SIP",
+ "PPE_CPU_CODE_EXP_INV_DIP",
+ "PPE_CPU_CODE_EXP_LAND_ATTACK",
+ "PPE_CPU_CODE_EXP_IPV4_AH_HDR_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_IPV4_AH_CROSS_BORDER",
+ "PPE_CPU_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_WRONG_VER",
+ "PPE_CPU_CODE_EXP_HDR_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_IPV6_BAD_PAYLOAD_LEN",
+ "PPE_CPU_CODE_EXP_DATA_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_IPV6_WITH_EXT_HDR",
+ "PPE_CPU_CODE_EXP_IPV6_SMALL_HOP_LIMIT",
+ "PPE_CPU_CODE_EXP_INV_SIP",
+ "PPE_CPU_CODE_EXP_INV_DIP",
+ "PPE_CPU_CODE_EXP_LAND_ATTACK",
+ "PPE_CPU_CODE_IPV6_FRAG",
+ "PPE_CPU_CODE_EXP_IPV6_PING_OF_DEATH",
+ "PPE_CPU_CODE_EXP_IPV6_WITH_EXT_HDR",
+ "PPE_CPU_CODE_EXP_IPV6_UNK_NEXT_HDR",
+ "PPE_CPU_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_IPV6_MOBILITY_CROSS_BORDER",
+ "PPE_CPU_CODE_EXP_IPV6_AH_HDR_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_IPV6_AH_CROSS_BORDER",
+ "PPE_CPU_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_IPV6_ESP_CROSS_BORDER",
+ "PPE_CPU_CODE_EXP_IPV6_OTHER_HDR_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_IPV6_OTHER_EXT_CROSS_BORDER",
+ "PPE_CPU_CODE_EXP_HDR_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_TCP_HDR_CROSS_BORDER",
+ "PPE_CPU_CODE_EXP_TCP_SMAE_SP_DP",
+ "PPE_CPU_CODE_EXP_TCP_SMALL_DATA_OFFSET",
+ "PPE_CPU_CODE_EXP_FLAGS_0",
+ "PPE_CPU_CODE_EXP_FLAGS_1",
+ "PPE_CPU_CODE_EXP_FLAGS_2",
+ "PPE_CPU_CODE_EXP_FLAGS_3",
+ "PPE_CPU_CODE_EXP_FLAGS_4",
+ "PPE_CPU_CODE_EXP_FLAGS_5",
+ "PPE_CPU_CODE_EXP_FLAGS_6",
+ "PPE_CPU_CODE_EXP_FLAGS_7",
+ "PPE_CPU_CODE_EXP_CHECKSUM_ERR",
+ "PPE_CPU_CODE_EXP_HDR_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_UDP_HDR_CROSS_BORDER",
+ "PPE_CPU_CODE_EXP_UDP_SMAE_SP_DP",
+ "PPE_CPU_CODE_EXP_BAD_LEN",
+ "PPE_CPU_CODE_EXP_DATA_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_CHECKSUM_ERR",
+ "PPE_CPU_CODE_EXP_UDP_LITE_HDR_INCOMPLETE",
+ "PPE_CPU_CODE_EXP_UDP_LITE_CROSS_BORDER",
+ "PPE_CPU_CODE_EXP_UDP_LITE_SP_DP",
+ "PPE_CPU_CODE_EXP_UDP_LITE_CSM_COV_TO_7",
+ "PPE_CPU_CODE_EXP_UDP_LITE_CSM_TOO_LONG",
+ "PPE_CPU_CODE_EXP_UDP_LITE_CSM_CROSS_BORDER",
+ "PPE_CPU_CODE_EXP_UDP_LITE_CHECKSUM_ERR",
+ "PPE_CPU_CODE_EXP_FAKE_L2_PROT_ERR",
+ "PPE_CPU_CODE_EXP_FAKE_MAC_HEADER_ERR",
+ "PPE_CPU_CODE_BITMAP_MAX",
+ "PPE_CPU_CODE_L2_MRU_FAIL",
+ "PPE_CPU_CODE_L2_MTU_FAIL",
+ "PPE_CPU_CODE_L3_EXP_IP_PREFIX_BC",
+ "PPE_CPU_CODE_L3_MTU_FAIL",
+ "PPE_CPU_CODE_L3_MRU_FAIL",
+ "PPE_CPU_CODE_L3_ICMP_RDT",
+ "PPE_CPU_CODE_L3_EXP_IP_RT_TO_ME",
+ "PPE_CPU_CODE_L3_EXP_IP_TTL_ZERO",
+ "PPE_CPU_CODE_L3_FLOW_SERVICE_CODE_LOOP",
+ "PPE_CPU_CODE_L3_DE_ACCELERATE",
+ "PPE_CPU_CODE_L3_EXP_FLOW_SRC_CHK_FAIL",
+ "PPE_CPU_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH",
+ "PPE_CPU_CODE_L3_EXP_MTU_DF_FAIL",
+ "PPE_CPU_CODE_L3_PPPOE_MULTICAST",
+ "PPE_CPU_CODE_MGMT_OFFSET",
+ "PPE_CPU_CODE_MGMT_EAPOL",
+ "PPE_CPU_CODE_PPPOE_DIS",
+ "PPE_CPU_CODE_MGMT_IGMP",
+ "PPE_CPU_CODE_ARP_REQ",
+ "PPE_CPU_CODE_ARP_REP",
+ "PPE_CPU_CODE_MGMT_DHCPv4",
+ "PPE_CPU_CODE_MGMT_MLD",
+ "PPE_CPU_CODE_MGMT_NS",
+ "PPE_CPU_CODE_MGMT_NA",
+ "PPE_CPU_CODE_MGMT_DHCPv6",
+ "PPE_CPU_CODE_PTP_OFFSET",
+ "PPE_CPU_CODE_PTP_SYNC",
+ "PPE_CPU_CODE_FOLLOW_UP",
+ "PPE_CPU_CODE_DELAY_REQ",
+ "PPE_CPU_CODE_DELAY_RESP",
+ "PPE_CPU_CODE_PDELAY_REQ",
+ "PPE_CPU_CODE_PDELAY_RESP",
+ "PPE_CPU_CODE_PTP_PDELAY_RESP_FOLLOW_UP",
+ "PPE_CPU_CODE_PTP_ANNOUNCE",
+ "PPE_CPU_CODE_PTP_MANAGEMENT",
+ "PPE_CPU_CODE_PTP_SIGNALING",
+ "PPE_CPU_CODE_PTP_RSV_MSG",
+ "PPE_CPU_CODE_SG_UNKNOWN",
+ "PPE_CPU_CODE_SG_UNKNOWN",
+ "PPE_CPU_CODE_SG_UNKNOWN",
+ "PPE_CPU_CODE_SG_UNKNOWN",
+ "PPE_CPU_CODE_SG_VIO",
+ "PPE_CPU_CODE_SG_VIO",
+ "PPE_CPU_CODE_SG_VIO",
+ "PPE_CPU_CODE_SG_VIO",
+ "PPE_CPU_CODE_L3_ROUTING_IP_TO_ME",
+ "PPE_CPU_CODE_L3_SNAT_ACTION",
+ "PPE_CPU_CODE_L3_DNAT_ACTION",
+ "PPE_CPU_CODE_L3_RT_ACTION",
+ "PPE_CPU_CODE_L3_BR_ACTION",
+ "PPE_CPU_CODE_L3_BRIDGE_ACTION",
+ "PPE_CPU_CODE_L3_ROUTE_PREHEAD_RT_ACTION",
+ "PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAPT_ACTION",
+ "PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAPT_ACTION",
+ "PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAT_ACTION",
+ "PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAT_ACTION",
+ "PPE_CPU_CODE_L3_NO_ROUTE_NAT_ACTION",
+ "PPE_CPU_CODE_L3_NO_ROUTE_NAT_ERROR",
+ "PPE_CPU_CODE_ROUTE_ACTION",
+ "PPE_CPU_CODE_L3_ROUTE_ACTION",
+ "PPE_CPU_CODE_L3_NO_ROUTE_INVALID_ACTION",
+ "PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_ACTION",
+ "PPE_CPU_CODE_BRIDGE_ACTION",
+ "PPE_CPU_CODE_FLOW_ACTION",
+ "PPE_CPU_CODE_L3_MISS_ACTION",
+ "PPE_CPU_CODE_L2_MAC_ADDRESS",
+ "PPE_CPU_CODE_HASH_COLLISION",
+ "PPE_CPU_CODE_STATION_MOVE",
+ "PPE_CPU_CODE_LEARN_LIMIT",
+ "PPE_CPU_CODE_L2_LOOKUP_ACTION",
+ "PPE_CPU_CODE_L2_LOOKUP_ACTION",
+ "PPE_CPU_CODE_CTRL_ACTION",
+ "PPE_CPU_CODE_IN_FILTER_ACTION",
+ "PPE_CPU_CODE_IN_XLT_MISS",
+ "PPE_CPU_CODE_EG_FILTER_DROP",
+ "PPE_CPU_CODE_PRE_ACTION",
+ "PPE_CPU_CODE_POST_ACTION",
+ "PPE_CPU_CODE_CODE_ACTION",
+};
+
+/*
+ * nss_ppe_stats_sync
+ * PPE connection sync statistics from NSS
+ */
+void nss_ppe_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_sync_stats_msg *stats_msg, uint16_t if_num)
+{
+ spin_lock_bh(&nss_ppe_stats_lock);
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_L3_FLOWS] += stats_msg->nss_ppe_v4_l3_flows;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_L2_FLOWS] += stats_msg->nss_ppe_v4_l2_flows;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_CREATE_REQ] += stats_msg->nss_ppe_v4_create_req;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_CREATE_FAIL] += stats_msg->nss_ppe_v4_create_fail;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_DESTROY_REQ] += stats_msg->nss_ppe_v4_destroy_req;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_DESTROY_FAIL] += stats_msg->nss_ppe_v4_destroy_fail;
+
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_L3_FLOWS] += stats_msg->nss_ppe_v6_l3_flows;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_L2_FLOWS] += stats_msg->nss_ppe_v6_l2_flows;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_CREATE_REQ] += stats_msg->nss_ppe_v6_create_req;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_CREATE_FAIL] += stats_msg->nss_ppe_v6_create_fail;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_DESTROY_REQ] += stats_msg->nss_ppe_v6_destroy_req;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_DESTROY_FAIL] += stats_msg->nss_ppe_v6_destroy_fail;
+
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_NH_FULL] += stats_msg->nss_ppe_fail_nh_full;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_FLOW_FULL] += stats_msg->nss_ppe_fail_flow_full;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_HOST_FULL] += stats_msg->nss_ppe_fail_host_full;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_PUBIP_FULL] += stats_msg->nss_ppe_fail_pubip_full;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_PORT_SETUP] += stats_msg->nss_ppe_fail_port_setup;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_RW_FIFO_FULL] += stats_msg->nss_ppe_fail_rw_fifo_full;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_FLOW_COMMAND] += stats_msg->nss_ppe_fail_flow_command;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_UNKNOWN_PROTO] += stats_msg->nss_ppe_fail_unknown_proto;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_PPE_UNRESPONSIVE] += stats_msg->nss_ppe_fail_ppe_unresponsive;
+ nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_FQG_FULL] += stats_msg->nss_ppe_fail_fqg_full;
+ spin_unlock_bh(&nss_ppe_stats_lock);
+}
+
+/*
+ * nss_ppe_stats_conn_get()
+ * Get PPE connection statistics.
+ */
+void nss_ppe_stats_conn_get(uint32_t *stats)
+{
+ if (!stats) {
+ nss_warning("No memory to copy ppe connection stats");
+ return;
+ }
+
+ spin_lock_bh(&nss_ppe_stats_lock);
+
+ if (!nss_ppe_debug_stats.valid) {
+ spin_unlock_bh(&nss_ppe_stats_lock);
+ nss_warning("PPE base address not initialized!\n");
+ return;
+ }
+
+ /*
+ * Get flow stats
+ */
+ memcpy(stats, nss_ppe_debug_stats.conn_stats, (sizeof(uint32_t) * NSS_PPE_STATS_CONN_MAX));
+
+ spin_unlock_bh(&nss_ppe_stats_lock);
+}
+
+/*
+ * nss_ppe_stats_l3_get()
+ * Get PPE L3 debug statistics.
+ */
+void nss_ppe_stats_l3_get(uint32_t *stats)
+{
+ if (!stats) {
+ nss_warning("No memory to copy ppe l3 dbg stats\n");
+ return;
+ }
+
+ spin_lock_bh(&nss_ppe_stats_lock);
+
+ if (!nss_ppe_debug_stats.valid) {
+ spin_unlock_bh(&nss_ppe_stats_lock);
+ nss_warning("PPE base address not initialized!\n");
+ return;
+ }
+
+ nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG0_OFFSET);
+ nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_0]);
+
+ nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG1_OFFSET);
+ nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_1]);
+
+ nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG2_OFFSET);
+ nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_2]);
+
+ nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG3_OFFSET);
+ nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_3]);
+
+ nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG4_OFFSET);
+ nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_4]);
+
+ nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG_PORT_OFFSET);
+ nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_PORT]);
+
+ spin_unlock_bh(&nss_ppe_stats_lock);
+}
+
+/*
+ * nss_ppe_stats_code_get()
+ * Get PPE CPU and DROP code for last packet processed.
+ */
+void nss_ppe_stats_code_get(uint32_t *stats)
+{
+ uint32_t drop_0, drop_1, cpu_code;
+
+ nss_trace("%s(%d) Start\n", __func__, __LINE__);
+ if (!stats) {
+ nss_warning("No memory to copy ppe code\n");
+ return;
+ }
+
+ if (!nss_ppe_debug_stats.valid) {
+ nss_warning("PPE base address not initialized!\n");
+ return;
+ }
+
+ spin_lock_bh(&nss_ppe_stats_lock);
+ nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_DROP0_OFFSET);
+ nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &drop_0);
+
+ nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_DROP1_OFFSET);
+ nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &drop_1);
+
+ stats[NSS_PPE_STATS_CODE_DROP] = PPE_PKT_CODE_DROP_GET(drop_0, drop_1);
+
+ nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_CPU_OFFSET);
+ nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &cpu_code);
+
+ stats[NSS_PPE_STATS_CODE_CPU] = PPE_PKT_CODE_CPU_GET(cpu_code);
+
+ spin_unlock_bh(&nss_ppe_stats_lock);
+}
+
+/*
+ * nss_ppe_port_drop_code_get()
+ * Get ppe per port drop code.
+ */
+void nss_ppe_port_drop_code_get(uint32_t *stats, uint8_t port_id)
+{
+ uint8_t i;
+ nss_trace("%s(%d) Start\n", __func__, __LINE__);
+ if (!stats) {
+ nss_warning("No memory to copy ppe code\n");
+ return;
+ }
+
+ if (port_id > NSS_PPE_NUM_PHY_PORTS_MAX) {
+ nss_warning("Port id is out of range\n");
+ return;
+ }
+
+ if (!nss_ppe_debug_stats.valid) {
+ nss_warning("PPE base address not initialized!\n");
+ return;
+ }
+
+ spin_lock_bh(&nss_ppe_stats_lock);
+
+ for (i = 0; i < NSS_PPE_STATS_DROP_CODE_MAX; i++) {
+ nss_ppe_reg_read(PPE_DROP_CODE_OFFSET(i, port_id), &stats[i]);
+ }
+
+ spin_unlock_bh(&nss_ppe_stats_lock);
+}
+
+/*
+ * nss_ppe_cpu_code_exception_get()
+ * Get ppe cpu code specific for flow exceptions.
+ */
+void nss_ppe_cpu_code_exception_get(uint32_t *stats)
+{
+ uint8_t i;
+ nss_trace("%s(%d) Start\n", __func__, __LINE__);
+ if (!stats) {
+ nss_warning("No memory to copy ppe code\n");
+ return;
+ }
+
+ if (!nss_ppe_debug_stats.valid) {
+ nss_warning("PPE base address not initialized!\n");
+ return;
+ }
+
+ spin_lock_bh(&nss_ppe_stats_lock);
+
+ for (i = 0; i < NSS_PPE_STATS_CPU_CODE_EXCEPTION_MAX ; i++) {
+ nss_ppe_reg_read(PPE_CPU_CODE_OFFSET(i), &stats[i]);
+ }
+
+ spin_unlock_bh(&nss_ppe_stats_lock);
+}
+
+/*
+ * nss_ppe_cpu_code_nonexception_get()
+ * Get ppe cpu code specific for flow exceptions.
+ */
+void nss_ppe_cpu_code_nonexception_get(uint32_t *stats)
+{
+ uint8_t i;
+ nss_trace("%s(%d) Start\n", __func__, __LINE__);
+ if (!stats) {
+ nss_warning("No memory to copy ppe code\n");
+ return;
+ }
+
+ if (!nss_ppe_debug_stats.valid) {
+ nss_warning("PPE base address not initialized!\n");
+ return;
+ }
+
+ spin_lock_bh(&nss_ppe_stats_lock);
+
+ for (i = 0; i < NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX; i++) {
+ nss_ppe_reg_read(PPE_CPU_CODE_OFFSET(ppe_cc_nonexception[i]), &stats[i]);
+ }
+
+ spin_unlock_bh(&nss_ppe_stats_lock);
+}
+
+/*
+ * nss_ppe_conn_stats_read()
+ * Read ppe connection statistics
+ */
+static ssize_t nss_ppe_conn_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int i;
+ char *lbuf = NULL;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint32_t ppe_stats[NSS_PPE_STATS_CONN_MAX];
+ uint32_t max_output_lines = 2 /* header & footer for session stats */
+ + NSS_PPE_STATS_CONN_MAX /* PPE flow counters */
+ + 2;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+
+ lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ memset(ppe_stats, 0, sizeof(uint32_t) * NSS_PPE_STATS_CONN_MAX);
+
+ /*
+ * Get all stats
+ */
+ nss_ppe_stats_conn_get(ppe_stats);
+
+ /*
+ * flow stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe flow counters start:\n\n");
+
+ for (i = 0; i < NSS_PPE_STATS_CONN_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %u\n", nss_ppe_stats_str_conn[i],
+ ppe_stats[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe flow counters end\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
+
+ kfree(lbuf);
+ return bytes_read;
+}
+
+/*
+ * nss_ppe_l3_stats_read()
+ * Read PPE L3 debug statistics
+ */
+static ssize_t nss_ppe_l3_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int i;
+ char *lbuf = NULL;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint32_t ppe_stats[NSS_PPE_STATS_L3_MAX];
+ uint32_t max_output_lines = 2 /* header & footer for session stats */
+ + NSS_PPE_STATS_L3_MAX /* PPE flow counters */
+ + 2;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+
+ lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(!lbuf)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ memset(ppe_stats, 0, sizeof(uint32_t) * NSS_PPE_STATS_L3_MAX);
+
+ /*
+ * Get all stats
+ */
+ nss_ppe_stats_l3_get(ppe_stats);
+
+ /*
+ * flow stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe l3 debug stats start:\n\n");
+
+ for (i = 0; i < NSS_PPE_STATS_L3_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = 0x%x\n", nss_ppe_stats_str_l3[i],
+ ppe_stats[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe l3 debug stats end\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
+
+ kfree(lbuf);
+ return bytes_read;
+}
+
+/*
+ * nss_ppe_code_stats_read()
+ * Read ppe CPU & DROP code
+ */
+static ssize_t nss_ppe_code_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int i;
+ char *lbuf = NULL;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint32_t ppe_stats[NSS_PPE_STATS_CODE_MAX];
+ uint32_t max_output_lines = 2 /* header & footer for session stats */
+ + NSS_PPE_STATS_CODE_MAX /* PPE flow counters */
+ + 2;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+
+ lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(!lbuf)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ memset(ppe_stats, 0, sizeof(uint32_t) * NSS_PPE_STATS_CODE_MAX);
+
+ /*
+ * Get all stats
+ */
+ nss_ppe_stats_code_get(ppe_stats);
+
+ /*
+ * flow stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe session stats start:\n\n");
+
+ for (i = 0; i < NSS_PPE_STATS_CODE_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %u\n", nss_ppe_stats_str_code[i],
+ ppe_stats[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe session stats end\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
+
+ kfree(lbuf);
+ return bytes_read;
+}
+
+/*
+ * nss_ppe_port_dc_stats_read()
+ * Read PPE per port drop code stats
+ */
+static ssize_t nss_ppe_port_dc_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + 2 start tag line + 2 end tag line + five blank lines
+ */
+ uint32_t max_output_lines = (NSS_PPE_STATS_DROP_CODE_MAX + 4) + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ struct nss_stats_data *data = fp->private_data;
+ uint32_t *ppe_stats;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ ppe_stats = kzalloc(sizeof(uint32_t) * NSS_PPE_STATS_DROP_CODE_MAX, GFP_KERNEL);
+ if (unlikely(ppe_stats == NULL)) {
+ kfree(lbuf);
+ nss_warning("Could not allocate memory for ppe stats buffer");
+ return 0;
+ }
+
+ /*
+ * Get drop code counters for specific port
+ */
+ nss_ppe_port_drop_code_get(ppe_stats, data->edma_id);
+ size_wr = scnprintf(lbuf, size_al, "ppe no drop code stats start:\n\n");
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %u\n", nss_ppe_stats_str_dc[0],
+ ppe_stats[0]);
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe no drop code stats end\n\n");
+
+ /*
+ * Drop code stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "ppe non-zero drop code stats start:\n\n");
+ for (i = 1; i < NSS_PPE_STATS_DROP_CODE_MAX; i++) {
+ /*
+ * Print only non-zero stats.
+ */
+ if (!ppe_stats[i]) {
+ continue;
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %u\n", nss_ppe_stats_str_dc[i],
+ ppe_stats[i]);
+ }
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe non-zero drop code stats end\n\n");
+
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(ppe_stats);
+ kfree(lbuf);
+
+ return bytes_read;
+}
+
+/*
+ * nss_ppe_exception_cc_stats_read()
+ * Read PPE CPU code stats specific to flow exceptions
+ */
+static ssize_t nss_ppe_exception_cc_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_PPE_STATS_CPU_CODE_EXCEPTION_MAX + 2) + 3;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint32_t *ppe_stats;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ ppe_stats = kzalloc(sizeof(uint32_t) * NSS_PPE_STATS_CPU_CODE_EXCEPTION_MAX, GFP_KERNEL);
+ if (unlikely(ppe_stats == NULL)) {
+ kfree(lbuf);
+ nss_warning("Could not allocate memory for ppe stats buffer");
+ return 0;
+ }
+
+ /*
+ * Get CPU code counters for flow specific exceptions
+ */
+ nss_ppe_cpu_code_exception_get(ppe_stats);
+
+ size_wr = scnprintf(lbuf, size_al, "ppe non-zero cpu code flow-exception stats start:\n\n");
+
+ /*
+ * CPU code stats
+ */
+ for (i = 0; i < NSS_PPE_STATS_CPU_CODE_EXCEPTION_MAX; i++) {
+ /*
+ * Print only non-zero stats.
+ */
+ if (!ppe_stats[i]) {
+ continue;
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %u\n", nss_ppe_stats_str_cc[i],
+ ppe_stats[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe non-zero cpu code flow-exception stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(ppe_stats);
+ kfree(lbuf);
+
+ return bytes_read;
+}
+
+/*
+ * nss_ppe_nonexception_cc_stats_read()
+ * Read PPE CPU code stats for other than flow exceptions
+ */
+static ssize_t nss_ppe_nonexception_cc_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX + 2) + 3;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint32_t *ppe_stats;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ ppe_stats = kzalloc(sizeof(uint32_t) * NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX, GFP_KERNEL);
+ if (unlikely(ppe_stats == NULL)) {
+ kfree(lbuf);
+ nss_warning("Could not allocate memory for ppe stats buffer");
+ return 0;
+ }
+
+ /*
+ * Get CPU code counters for non flow exceptions
+ */
+ nss_ppe_cpu_code_nonexception_get(ppe_stats);
+
+ /*
+ * CPU code stats
+ */
+ size_wr = scnprintf(lbuf, size_al, "ppe non-zero cpu code non-flow exception stats start:\n\n");
+ for (i = 0; i < NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX; i++) {
+ /*
+ * Print only non-zero stats.
+ */
+ if (!ppe_stats[i]) {
+ continue;
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %u\n", nss_ppe_stats_str_cc[i + NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_START],
+ ppe_stats[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe non-zero cpu code non-flow exception stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(ppe_stats);
+ kfree(lbuf);
+
+ return bytes_read;
+}
+
+/*
+ * nss_ppe_conn_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_conn)
+
+/*
+ * nss_ppe_l3_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_l3)
+
+/*
+ * nss_ppe_code_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_code)
+
+/*
+ * nss_ppe_port_dc_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_port_dc)
+/*
+ * nss_ppe_exception_cc_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_exception_cc)
+
+/*
+ * nss_ppe_nonexception_cc_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_nonexception_cc)
+
+/*
+ * nss_ppe_stats_dentry_create()
+ * Create PPE statistics debug entry.
+ */
+void nss_ppe_stats_dentry_create(void)
+{
+ int i;
+ struct dentry *ppe_dentry = NULL;
+ struct dentry *ppe_conn_d = NULL;
+ struct dentry *ppe_l3_d = NULL;
+ struct dentry *ppe_ppe_code_d = NULL;
+ struct dentry *ppe_code_d = NULL;
+ struct dentry *ppe_drop_d = NULL;
+ struct dentry *ppe_port_dc_d = NULL;
+ struct dentry *ppe_cpu_d = NULL;
+ struct dentry *ppe_exception_d = NULL;
+ struct dentry *ppe_nonexception_d = NULL;
+ char file_name[10];
+
+ ppe_dentry = debugfs_create_dir("ppe", nss_top_main.stats_dentry);
+ if (unlikely(ppe_dentry == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/ppe directory");
+ return;
+ }
+
+ ppe_conn_d = debugfs_create_file("connection", 0400, ppe_dentry,
+ &nss_top_main, &nss_ppe_conn_stats_ops);
+ if (unlikely(ppe_conn_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/ppe/connection file");
+ return;
+ }
+
+ ppe_l3_d = debugfs_create_file("l3", 0400, ppe_dentry,
+ &nss_top_main, &nss_ppe_l3_stats_ops);
+ if (unlikely(ppe_l3_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/ppe/l3 filed");
+ return;
+ }
+
+ ppe_ppe_code_d = debugfs_create_file("ppe_code", 0400, ppe_dentry,
+ &nss_top_main, &nss_ppe_code_stats_ops);
+ if (unlikely(ppe_ppe_code_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/ppe/ppe_code file");
+ return;
+ }
+
+ /*
+ * ppe exception and drop code stats
+ */
+ ppe_code_d = debugfs_create_dir("code", ppe_dentry);
+ if (unlikely(ppe_code_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/ppe/code directory");
+ return;
+ }
+
+ ppe_cpu_d = debugfs_create_dir("cpu", ppe_code_d);
+ if (unlikely(ppe_cpu_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/ppe/code/cpu directory");
+ return;
+ }
+
+ ppe_exception_d = debugfs_create_file("exception", 0400, ppe_cpu_d,
+ &nss_top_main, &nss_ppe_exception_cc_stats_ops);
+ if (unlikely(ppe_exception_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/ppe/code/exception file");
+ return;
+ }
+
+ ppe_nonexception_d = debugfs_create_file("non-exception", 0400, ppe_cpu_d,
+ &nss_top_main, &nss_ppe_nonexception_cc_stats_ops);
+ if (unlikely(ppe_nonexception_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/ppe/code/non-exception file");
+ return;
+ }
+
+ ppe_drop_d = debugfs_create_dir("drop", ppe_code_d);
+ if (unlikely(ppe_drop_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/ppe/code/drop directory");
+ return;
+ }
+
+ for (i = 0; i < NSS_PPE_NUM_PHY_PORTS_MAX; i++) {
+ if (i > 0) {
+ memset(file_name, 0, sizeof(file_name));
+ snprintf(file_name, sizeof(file_name), "%d", i);
+ }
+
+ ppe_port_dc_d = debugfs_create_file((i == 0) ? "cpu" : file_name, 0400, ppe_drop_d,
+ (void *)(nss_ptr_t)i, &nss_ppe_port_dc_stats_ops);
+ if (unlikely(ppe_port_dc_d == NULL)) {
+ nss_warning("Failed to create qca-nss-drv/stats/ppe/code/drop/%d file", i);
+ return;
+ }
+ }
+}
diff --git a/nss_ppe_stats.h b/nss_ppe_stats.h
new file mode 100644
index 0000000..9fb2c26
--- /dev/null
+++ b/nss_ppe_stats.h
@@ -0,0 +1,411 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_ppe_stats.h
+ * NSS PPE statistics header file.
+ */
+
+#ifndef __NSS_PPE_STATS_H
+#define __NSS_PPE_STATS_H
+
+/*
+ * NSS PPE connection statistics
+ */
+enum nss_ppe_stats_conn {
+ NSS_PPE_STATS_V4_L3_FLOWS, /* No of v4 routed flows */
+ NSS_PPE_STATS_V4_L2_FLOWS, /* No of v4 bridge flows */
+ NSS_PPE_STATS_V4_CREATE_REQ, /* No of v4 create requests */
+ NSS_PPE_STATS_V4_CREATE_FAIL, /* No of v4 create failure */
+ NSS_PPE_STATS_V4_DESTROY_REQ, /* No of v4 delete requests */
+ NSS_PPE_STATS_V4_DESTROY_FAIL, /* No of v4 delete failure */
+ NSS_PPE_STATS_V4_MC_CREATE_REQ, /* No of v4 MC create requests */
+ NSS_PPE_STATS_V4_MC_CREATE_FAIL, /* No of v4 MC create failure */
+ NSS_PPE_STATS_V4_MC_UPDATE_REQ, /* No of v4 MC update requests */
+ NSS_PPE_STATS_V4_MC_UPDATE_FAIL, /* No of v4 MC update failure */
+ NSS_PPE_STATS_V4_MC_DESTROY_REQ, /* No of v4 MC delete requests */
+ NSS_PPE_STATS_V4_MC_DESTROY_FAIL, /* No of v4 MC delete failure */
+
+ NSS_PPE_STATS_V6_L3_FLOWS, /* No of v6 routed flows */
+ NSS_PPE_STATS_V6_L2_FLOWS, /* No of v6 bridge flows */
+ NSS_PPE_STATS_V6_CREATE_REQ, /* No of v6 create requests */
+ NSS_PPE_STATS_V6_CREATE_FAIL, /* No of v6 create failure */
+ NSS_PPE_STATS_V6_DESTROY_REQ, /* No of v6 delete requests */
+ NSS_PPE_STATS_V6_DESTROY_FAIL, /* No of v6 delete failure */
+ NSS_PPE_STATS_V6_MC_CREATE_REQ, /* No of v6 MC create requests */
+ NSS_PPE_STATS_V6_MC_CREATE_FAIL, /* No of v6 MC create failure */
+ NSS_PPE_STATS_V6_MC_UPDATE_REQ, /* No of v6 MC update requests */
+ NSS_PPE_STATS_V6_MC_UPDATE_FAIL, /* No of v6 MC update failure */
+ NSS_PPE_STATS_V6_MC_DESTROY_REQ, /* No of v6 MC delete requests */
+ NSS_PPE_STATS_V6_MC_DESTROY_FAIL, /* No of v6 MC delete failure */
+
+ NSS_PPE_STATS_FAIL_VP_FULL, /* Create req fail due to VP table full */
+ NSS_PPE_STATS_FAIL_NH_FULL, /* Create req fail due to nexthop table full */
+ NSS_PPE_STATS_FAIL_FLOW_FULL, /* Create req fail due to flow table full */
+ NSS_PPE_STATS_FAIL_HOST_FULL, /* Create req fail due to host table full */
+ NSS_PPE_STATS_FAIL_PUBIP_FULL, /* Create req fail due to pub-ip table full */
+ NSS_PPE_STATS_FAIL_PORT_SETUP, /* Create req fail due to PPE port not setup */
+ NSS_PPE_STATS_FAIL_RW_FIFO_FULL, /* Create req fail due to rw fifo full */
+ NSS_PPE_STATS_FAIL_FLOW_COMMAND, /* Create req fail due to PPE flow command failure */
+ NSS_PPE_STATS_FAIL_UNKNOWN_PROTO, /* Create req fail due to unknown protocol */
+ NSS_PPE_STATS_FAIL_PPE_UNRESPONSIVE, /* Create req fail due to PPE not responding */
+ NSS_PPE_STATS_CE_OPAQUE_INVALID, /* Create req fail due to invalid opaque in CE */
+ NSS_PPE_STATS_FAIL_FQG_FULL, /* Create req fail due to flow qos group full */
+ NSS_PPE_STATS_CONN_MAX
+};
+
+/*
+ * NSS PPE L3 statistics
+ */
+enum nss_ppe_stats_l3 {
+ NSS_PPE_STATS_L3_DBG_0, /* PPE L3 debug register 0 */
+ NSS_PPE_STATS_L3_DBG_1, /* PPE L3 debug register 1 */
+ NSS_PPE_STATS_L3_DBG_2, /* PPE L3 debug register 2 */
+ NSS_PPE_STATS_L3_DBG_3, /* PPE L3 debug register 3 */
+ NSS_PPE_STATS_L3_DBG_4, /* PPE L3 debug register 4 */
+ NSS_PPE_STATS_L3_DBG_PORT, /* PPE L3 debug register Port */
+ NSS_PPE_STATS_L3_MAX
+};
+
+/*
+ * NSS PPE_code statistics
+ */
+enum nss_ppe_stats_code {
+ NSS_PPE_STATS_CODE_CPU, /* PPE CPU code for last packet processed */
+ NSS_PPE_STATS_CODE_DROP, /* PPE DROP code for last packet processed */
+ NSS_PPE_STATS_CODE_MAX
+};
+
+/*
+ * PPE drop codes
+ */
+enum nss_ppe_stats_dc {
+ NSS_PPE_STATS_DROP_CODE_UNKNOWN, /* PPE drop code unknown */
+ NSS_PPE_STATS_DROP_CODE_EXP_UNKNOWN_L2_PROT, /* PPE drop code exp unknown l2 prot */
+ NSS_PPE_STATS_DROP_CODE_EXP_PPPOE_WRONG_VER_TYPE, /* PPE drop code exp pppoe wrong ver type */
+ NSS_PPE_STATS_DROP_CODE_EXP_PPPOE_WRONG_CODE, /* PPE drop code exp pppoe wrong code */
+ NSS_PPE_STATS_DROP_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT, /* PPE drop code exp pppoe unsupported ppp prot */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_WRONG_VER, /* PPE drop code exp ipv4 wrong ver */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_SMALL_IHL, /* PPE drop code exp ipv4 small ihl */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_WITH_OPTION, /* PPE drop code exp ipv4 with option */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_HDR_INCOMPLETE, /* PPE drop code exp ipv4 hdr incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_BAD_TOTAL_LEN, /* PPE drop code exp ipv4 bad total len */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_DATA_INCOMPLETE, /* PPE drop code exp ipv4 data incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_FRAG, /* PPE drop code exp ipv4 frag */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_PING_OF_DEATH, /* PPE drop code exp ipv4 ping of death */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_SNALL_TTL, /* PPE drop code exp ipv4 snall ttl */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_UNK_IP_PROT, /* PPE drop code exp ipv4 unk ip prot */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_CHECKSUM_ERR, /* PPE drop code exp ipv4 checksum err */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_INV_SIP, /* PPE drop code exp ipv4 inv sip */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_INV_DIP, /* PPE drop code exp ipv4 inv dip */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_LAND_ATTACK, /* PPE drop code exp ipv4 land attack */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_AH_HDR_INCOMPLETE, /* PPE drop code exp ipv4 ah hdr incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_AH_HDR_CROSS_BORDER, /* PPE drop code exp ipv4 ah hdr cross border */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE, /* PPE drop code exp ipv4 esp hdr incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_WRONG_VER, /* PPE drop code exp ipv6 wrong ver */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_HDR_INCOMPLETE, /* PPE drop code exp ipv6 hdr incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_BAD_PAYLOAD_LEN, /* PPE drop code exp ipv6 bad payload len */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_DATA_INCOMPLETE, /* PPE drop code exp ipv6 data incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_WITH_EXT_HDR, /* PPE drop code exp ipv6 with ext hdr */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_SMALL_HOP_LIMIT, /* PPE drop code exp ipv6 small hop limit */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_INV_SIP, /* PPE drop code exp ipv6 inv sip */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_INV_DIP, /* PPE drop code exp ipv6 inv dip */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_LAND_ATTACK, /* PPE drop code exp ipv6 land attack */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_FRAG, /* PPE drop code exp ipv6 frag */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_PING_OF_DEATH, /* PPE drop code exp ipv6 ping of death */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_WITH_MORE_EXT_HDR, /* PPE drop code exp ipv6 with more ext hdr */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_UNK_LAST_NEXT_HDR, /* PPE drop code exp ipv6 unk last next hdr */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE, /* PPE drop code exp ipv6 mobility hdr incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_MOBILITY_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 mobility hdr cross border */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_AH_HDR_INCOMPLETE, /* PPE drop code exp ipv6 ah hdr incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_AH_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 ah hdr cross border */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE, /* PPE drop code exp ipv6 esp hdr incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_ESP_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 esp hdr cross border */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_INCOMPLETE, /* PPE drop code exp ipv6 other ext hdr incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 other ext hdr cross border */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_HDR_INCOMPLETE, /* PPE drop code exp tcp hdr incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_HDR_CROSS_BORDER, /* PPE drop code exp tcp hdr cross border */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_SMAE_SP_DP, /* PPE drop code exp tcp smae sp dp */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_SMALL_DATA_OFFSET, /* PPE drop code exp tcp small data offset */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_0, /* PPE drop code exp tcp flags 0 */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_1, /* PPE drop code exp tcp flags 1 */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_2, /* PPE drop code exp tcp flags 2 */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_3, /* PPE drop code exp tcp flags 3 */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_4, /* PPE drop code exp tcp flags 4 */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_5, /* PPE drop code exp tcp flags 5 */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_6, /* PPE drop code exp tcp flags 6 */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_7, /* PPE drop code exp tcp flags 7 */
+ NSS_PPE_STATS_DROP_CODE_EXP_TCP_CHECKSUM_ERR, /* PPE drop code exp tcp checksum err */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_HDR_INCOMPLETE, /* PPE drop code exp udp hdr incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_HDR_CROSS_BORDER, /* PPE drop code exp udp hdr cross border */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_SMAE_SP_DP, /* PPE drop code exp udp smae sp dp */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_BAD_LEN, /* PPE drop code exp udp bad len */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_DATA_INCOMPLETE, /* PPE drop code exp udp data incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_CHECKSUM_ERR, /* PPE drop code exp udp checksum err */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_HDR_INCOMPLETE, /* PPE drop code exp udp lite hdr incomplete */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_HDR_CROSS_BORDER, /* PPE drop code exp udp lite hdr cross border */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_SMAE_SP_DP, /* PPE drop code exp udp lite smae sp dp */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_CSM_COV_1_TO_7, /* PPE drop code exp udp lite csm cov 1 to 7 */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_CSM_COV_TOO_LONG, /* PPE drop code exp udp lite csm cov too long */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_CSM_COV_CROSS_BORDER, /* PPE drop code exp udp lite csm cov cross border */
+ NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_CHECKSUM_ERR, /* PPE drop code exp udp lite checksum err */
+ NSS_PPE_STATS_DROP_CODE_L3_MC_BRIDGE_ACTION, /* PPE drop code l3 mc bridge action */
+ NSS_PPE_STATS_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION, /* PPE drop code l3 no route prehead nat action */
+ NSS_PPE_STATS_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR, /* PPE drop code l3 no route prehead nat error */
+ NSS_PPE_STATS_DROP_CODE_L3_ROUTE_ACTION, /* PPE drop code l3 route action */
+ NSS_PPE_STATS_DROP_CODE_L3_NO_ROUTE_ACTION, /* PPE drop code l3 no route action */
+ NSS_PPE_STATS_DROP_CODE_L3_NO_ROUTE_NH_INVALID_ACTION, /* PPE drop code l3 no route nh invalid action */
+ NSS_PPE_STATS_DROP_CODE_L3_NO_ROUTE_PREHEAD_ACTION, /* PPE drop code l3 no route prehead action */
+ NSS_PPE_STATS_DROP_CODE_L3_BRIDGE_ACTION, /* PPE drop code l3 bridge action */
+ NSS_PPE_STATS_DROP_CODE_L3_FLOW_ACTION, /* PPE drop code l3 flow action */
+ NSS_PPE_STATS_DROP_CODE_L3_FLOW_MISS_ACTION, /* PPE drop code l3 flow miss action */
+ NSS_PPE_STATS_DROP_CODE_L2_EXP_MRU_FAIL, /* PPE drop code l2 exp mru fail */
+ NSS_PPE_STATS_DROP_CODE_L2_EXP_MTU_FAIL, /* PPE drop code l2 exp mtu fail */
+ NSS_PPE_STATS_DROP_CODE_L3_EXP_IP_PREFIX_BC, /* PPE drop code l3 exp ip prefix bc */
+ NSS_PPE_STATS_DROP_CODE_L3_EXP_MTU_FAIL, /* PPE drop code l3 exp mtu fail */
+ NSS_PPE_STATS_DROP_CODE_L3_EXP_MRU_FAIL, /* PPE drop code l3 exp mru fail */
+ NSS_PPE_STATS_DROP_CODE_L3_EXP_ICMP_RDT, /* PPE drop code l3 exp icmp rdt */
+ NSS_PPE_STATS_DROP_CODE_FAKE_MAC_HEADER_ERR, /* PPE drop code fake mac header err */
+ NSS_PPE_STATS_DROP_CODE_L3_EXP_IP_RT_TTL_ZERO, /* PPE drop code l3 exp ip rt ttl zero */
+ NSS_PPE_STATS_DROP_CODE_L3_FLOW_SERVICE_CODE_LOOP, /* PPE drop code l3 flow service code loop */
+ NSS_PPE_STATS_DROP_CODE_L3_FLOW_DE_ACCELEARTE, /* PPE drop code l3 flow de accelearte */
+ NSS_PPE_STATS_DROP_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL, /* PPE drop code l3 exp flow src if chk fail */
+ NSS_PPE_STATS_DROP_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH, /* PPE drop code l3 flow sync toggle mismatch */
+ NSS_PPE_STATS_DROP_CODE_L3_EXP_MTU_DF_FAIL, /* PPE drop code l3 exp mtu df fail */
+ NSS_PPE_STATS_DROP_CODE_L3_EXP_PPPOE_MULTICAST, /* PPE drop code l3 exp pppoe multicast */
+ NSS_PPE_STATS_DROP_CODE_IPV4_SG_UNKNOWN, /* PPE drop code ipv4 sg unknown */
+ NSS_PPE_STATS_DROP_CODE_IPV6_SG_UNKNOWN, /* PPE drop code ipv6 sg unknown */
+ NSS_PPE_STATS_DROP_CODE_ARP_SG_UNKNOWN, /* PPE drop code arp sg unknown */
+ NSS_PPE_STATS_DROP_CODE_ND_SG_UNKNOWN, /* PPE drop code nd sg unknown */
+ NSS_PPE_STATS_DROP_CODE_IPV4_SG_VIO, /* PPE drop code ipv4 sg vio */
+ NSS_PPE_STATS_DROP_CODE_IPV6_SG_VIO, /* PPE drop code ipv6 sg vio */
+ NSS_PPE_STATS_DROP_CODE_ARP_SG_VIO, /* PPE drop code arp sg vio */
+ NSS_PPE_STATS_DROP_CODE_ND_SG_VIO, /* PPE drop code nd sg vio */
+ NSS_PPE_STATS_DROP_CODE_L2_NEW_MAC_ADDRESS, /* PPE drop code l2 new mac address */
+ NSS_PPE_STATS_DROP_CODE_L2_HASH_COLLISION, /* PPE drop code l2 hash collision */
+ NSS_PPE_STATS_DROP_CODE_L2_STATION_MOVE, /* PPE drop code l2 station move */
+ NSS_PPE_STATS_DROP_CODE_L2_LEARN_LIMIT, /* PPE drop code l2 learn limit */
+ NSS_PPE_STATS_DROP_CODE_L2_SA_LOOKUP_ACTION, /* PPE drop code l2 sa lookup action */
+ NSS_PPE_STATS_DROP_CODE_L2_DA_LOOKUP_ACTION, /* PPE drop code l2 da lookup action */
+ NSS_PPE_STATS_DROP_CODE_APP_CTRL_ACTION, /* PPE drop code app ctrl action */
+ NSS_PPE_STATS_DROP_CODE_IN_VLAN_FILTER_ACTION, /* PPE drop code in vlan filter action */
+ NSS_PPE_STATS_DROP_CODE_IN_VLAN_XLT_MISS, /* PPE drop code in vlan xlt miss */
+ NSS_PPE_STATS_DROP_CODE_EG_VLAN_FILTER_DROP, /* PPE drop code eg vlan filter drop */
+ NSS_PPE_STATS_DROP_CODE_ACL_PRE_ACTION, /* PPE drop code acl pre action */
+ NSS_PPE_STATS_DROP_CODE_ACL_POST_ACTION, /* PPE drop code acl post action */
+ NSS_PPE_STATS_DROP_CODE_MC_BC_SA, /* PPE drop code mc bc sa */
+ NSS_PPE_STATS_DROP_CODE_NO_DESTINATION, /* PPE drop code no destination */
+ NSS_PPE_STATS_DROP_CODE_STG_IN_FILTER, /* PPE drop code stg in filter */
+ NSS_PPE_STATS_DROP_CODE_STG_EG_FILTER, /* PPE drop code stg eg filter */
+ NSS_PPE_STATS_DROP_CODE_SOURCE_FILTER_FAIL, /* PPE drop code source filter fail */
+ NSS_PPE_STATS_DROP_CODE_TRUNK_SEL_FAIL, /* PPE drop code trunk sel fail */
+ NSS_PPE_STATS_DROP_CODE_TX_EN_FAIL, /* PPE drop code tx en fail */
+ NSS_PPE_STATS_DROP_CODE_VLAN_TAG_FMT, /* PPE drop code vlan tag fmt */
+ NSS_PPE_STATS_DROP_CODE_CRC_ERR, /* PPE drop code crc err */
+ NSS_PPE_STATS_DROP_CODE_PAUSE_FRAME, /* PPE drop code pause frame */
+ NSS_PPE_STATS_DROP_CODE_PROMISC, /* PPE drop code promisc */
+ NSS_PPE_STATS_DROP_CODE_ISOLATION, /* PPE drop code isolation */
+ NSS_PPE_STATS_DROP_CODE_MGMT_APP, /* PPE drop code mgmt app */
+ NSS_PPE_STATS_DROP_CODE_FAKE_L2_PROT_ERR, /* PPE drop code fake l2 prot err */
+ NSS_PPE_STATS_DROP_CODE_POLICER, /* PPE drop code policer */
+ NSS_PPE_STATS_DROP_CODE_MAX /* PPE drop code max */
+};
+
+/*
+ * PPE CPU codes
+ */
+#define NSS_PPE_STATS_CPU_CODE_MAX 150
+#define NSS_PPE_STATS_CPU_CODE_EXCEPTION_MAX 69
+#define NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_START 69
+#define NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX (NSS_PPE_STATS_CPU_CODE_MAX - NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_START)
+
+enum nss_ppe_stats_cc {
+ NSS_PPE_STATS_CPU_CODE_FORWARDING = 0, /* PPE cpu code forwarding */
+ NSS_PPE_STATS_CPU_CODE_EXP_UNKNOWN_L2_PROT = 1, /* PPE cpu code exp unknown l2 prot */
+ NSS_PPE_STATS_CPU_CODE_EXP_PPPOE_WRONG_VER_TYPE = 2, /* PPE cpu code exp pppoe wrong ver type */
+ NSS_PPE_STATS_CPU_CODE_EXP_PPPOE_WRONG_CODE = 3, /* PPE cpu code exp pppoe wrong code */
+ NSS_PPE_STATS_CPU_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT = 4, /* PPE cpu code exp pppoe unsupported ppp prot */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_WRONG_VER = 5, /* PPE cpu code exp ipv4 wrong ver */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_SMALL_IHL = 6, /* PPE cpu code exp ipv4 small ihl */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_WITH_OPTION = 7, /* PPE cpu code exp ipv4 with option */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_HDR_INCOMPLETE = 8, /* PPE cpu code exp ipv4 hdr incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_BAD_TOTAL_LEN = 9, /* PPE cpu code exp ipv4 bad total len */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_DATA_INCOMPLETE = 10, /* PPE cpu code exp ipv4 data incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_FRAG = 11, /* PPE cpu code exp ipv4 frag */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_PING_OF_DEATH = 12, /* PPE cpu code exp ipv4 ping of death */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_SNALL_TTL = 13, /* PPE cpu code exp ipv4 snall ttl */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_UNK_IP_PROT = 14, /* PPE cpu code exp ipv4 unk ip prot */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_CHECKSUM_ERR = 15, /* PPE cpu code exp ipv4 checksum err */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_INV_SIP = 16, /* PPE cpu code exp ipv4 inv sip */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_INV_DIP = 17, /* PPE cpu code exp ipv4 inv dip */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_LAND_ATTACK = 18, /* PPE cpu code exp ipv4 land attack */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_AH_HDR_INCOMPLETE = 19, /* PPE cpu code exp ipv4 ah hdr incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_AH_HDR_CROSS_BORDER = 20, /* PPE cpu code exp ipv4 ah hdr cross border */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE = 21, /* PPE cpu code exp ipv4 esp hdr incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_WRONG_VER = 22, /* PPE cpu code exp ipv6 wrong ver */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_HDR_INCOMPLETE = 23, /* PPE cpu code exp ipv6 hdr incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_BAD_PAYLOAD_LEN = 24, /* PPE cpu code exp ipv6 bad payload len */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_DATA_INCOMPLETE = 25, /* PPE cpu code exp ipv6 data incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_WITH_EXT_HDR = 26, /* PPE cpu code exp ipv6 with ext hdr */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_SMALL_HOP_LIMIT = 27, /* PPE cpu code exp ipv6 small hop limit */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_INV_SIP = 28, /* PPE cpu code exp ipv6 inv sip */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_INV_DIP = 29, /* PPE cpu code exp ipv6 inv dip */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_LAND_ATTACK = 30, /* PPE cpu code exp ipv6 land attack */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_FRAG = 31, /* PPE cpu code exp ipv6 frag */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_PING_OF_DEATH = 32, /* PPE cpu code exp ipv6 ping of death */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_WITH_MORE_EXT_HDR = 33, /* PPE cpu code exp ipv6 with more ext hdr */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_UNK_LAST_NEXT_HDR = 34, /* PPE cpu code exp ipv6 unk last next hdr */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE = 35, /* PPE cpu code exp ipv6 mobility hdr incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_MOBILITY_HDR_CROSS_BORDER = 36, /* PPE cpu code exp ipv6 mobility hdr cross border */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_AH_HDR_INCOMPLETE = 37, /* PPE cpu code exp ipv6 ah hdr incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_AH_HDR_CROSS_BORDER = 38, /* PPE cpu code exp ipv6 ah hdr cross border */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE = 39, /* PPE cpu code exp ipv6 esp hdr incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_ESP_HDR_CROSS_BORDER = 40, /* PPE cpu code exp ipv6 esp hdr cross border */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_OTHER_EXT_HDR_INCOMPLETE = 41, /* PPE cpu code exp ipv6 other ext hdr incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_IPV6_OTHER_EXT_HDR_CROSS_BORDER = 42, /* PPE cpu code exp ipv6 other ext hdr cross border */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_HDR_INCOMPLETE = 43, /* PPE cpu code exp tcp hdr incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_HDR_CROSS_BORDER = 44, /* PPE cpu code exp tcp hdr cross border */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_SMAE_SP_DP = 45, /* PPE cpu code exp tcp smae sp dp */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_SMALL_DATA_OFFSET = 46, /* PPE cpu code exp tcp small data offset */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_0 = 47, /* PPE cpu code exp tcp flags 0 */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_1 = 48, /* PPE cpu code exp tcp flags 1 */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_2 = 49, /* PPE cpu code exp tcp flags 2 */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_3 = 50, /* PPE cpu code exp tcp flags 3 */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_4 = 51, /* PPE cpu code exp tcp flags 4 */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_5 = 52, /* PPE cpu code exp tcp flags 5 */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_6 = 53, /* PPE cpu code exp tcp flags 6 */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_7 = 54, /* PPE cpu code exp tcp flags 7 */
+ NSS_PPE_STATS_CPU_CODE_EXP_TCP_CHECKSUM_ERR = 55, /* PPE cpu code exp tcp checksum err */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_HDR_INCOMPLETE = 56, /* PPE cpu code exp udp hdr incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_HDR_CROSS_BORDER = 57, /* PPE cpu code exp udp hdr cross border */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_SMAE_SP_DP = 58, /* PPE cpu code exp udp smae sp dp */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_BAD_LEN = 59, /* PPE cpu code exp udp bad len */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_DATA_INCOMPLETE = 60, /* PPE cpu code exp udp data incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_CHECKSUM_ERR = 61, /* PPE cpu code exp udp checksum err */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_HDR_INCOMPLETE = 62, /* PPE cpu code exp udp lite hdr incomplete */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_HDR_CROSS_BORDER = 63, /* PPE cpu code exp udp lite hdr cross border */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_SMAE_SP_DP = 64, /* PPE cpu code exp udp lite smae sp dp */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_CSM_COV_1_TO_7 = 65, /* PPE cpu code exp udp lite csm cov 1 to 7 */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_CSM_COV_TOO_LONG = 66, /* PPE cpu code exp udp lite csm cov too long */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_CSM_COV_CROSS_BORDER = 67, /* PPE cpu code exp udp lite csm cov cross border */
+ NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_CHECKSUM_ERR = 68, /* PPE cpu code exp udp lite checksum err */
+ NSS_PPE_STATS_CPU_CODE_EXP_FAKE_L2_PROT_ERR = 69, /* PPE cpu code exp fake l2 prot err */
+ NSS_PPE_STATS_CPU_CODE_EXP_FAKE_MAC_HEADER_ERR = 70, /* PPE cpu code exp fake mac header err */
+ NSS_PPE_STATS_CPU_CODE_EXP_BITMAP_MAX = 78, /* PPE cpu code exp bitmap max */
+ NSS_PPE_STATS_CPU_CODE_L2_EXP_MRU_FAIL = 79, /* PPE cpu code l2 exp mru fail */
+ NSS_PPE_STATS_CPU_CODE_L2_EXP_MTU_FAIL = 80, /* PPE cpu code l2 exp mtu fail */
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_PREFIX_BC = 81, /* PPE cpu code l3 exp ip prefix bc */
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_MTU_FAIL = 82, /* PPE cpu code l3 exp mtu fail */
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_MRU_FAIL = 83, /* PPE cpu code l3 exp mru fail */
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_ICMP_RDT = 84, /* PPE cpu code l3 exp icmp rdt */
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_RT_TTL1_TO_ME = 85, /* PPE cpu code l3 exp ip rt ttl1 to me */
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_RT_TTL_ZERO = 86, /* PPE cpu code l3 exp ip rt ttl zero */
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_SERVICE_CODE_LOOP = 87, /* PPE cpu code l3 flow service code loop */
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_DE_ACCELERATE = 88, /* PPE cpu code l3 flow de accelerate */
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL = 89, /* PPE cpu code l3 exp flow src if chk fail */
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH = 90, /* PPE cpu code l3 flow sync toggle mismatch */
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_MTU_DF_FAIL = 91, /* PPE cpu code l3 exp mtu df fail */
+ NSS_PPE_STATS_CPU_CODE_L3_EXP_PPPOE_MULTICAST = 92, /* PPE cpu code l3 exp pppoe multicast */
+ NSS_PPE_STATS_CPU_CODE_MGMT_OFFSET = 96, /* PPE cpu code mgmt offset */
+ NSS_PPE_STATS_CPU_CODE_MGMT_EAPOL = 97, /* PPE cpu code mgmt eapol */
+ NSS_PPE_STATS_CPU_CODE_MGMT_PPPOE_DIS = 98, /* PPE cpu code mgmt pppoe dis */
+ NSS_PPE_STATS_CPU_CODE_MGMT_IGMP = 99, /* PPE cpu code mgmt igmp */
+ NSS_PPE_STATS_CPU_CODE_MGMT_ARP_REQ = 100, /* PPE cpu code mgmt arp req */
+ NSS_PPE_STATS_CPU_CODE_MGMT_ARP_REP = 101, /* PPE cpu code mgmt arp rep */
+ NSS_PPE_STATS_CPU_CODE_MGMT_DHCPv4 = 102, /* PPE cpu code mgmt dhcpv4 */
+ NSS_PPE_STATS_CPU_CODE_MGMT_MLD = 107, /* PPE cpu code mgmt mld */
+ NSS_PPE_STATS_CPU_CODE_MGMT_NS = 108, /* PPE cpu code mgmt ns */
+ NSS_PPE_STATS_CPU_CODE_MGMT_NA = 109, /* PPE cpu code mgmt na */
+ NSS_PPE_STATS_CPU_CODE_MGMT_DHCPv6 = 110, /* PPE cpu code mgmt dhcpv6 */
+ NSS_PPE_STATS_CPU_CODE_PTP_OFFSET = 112, /* PPE cpu code ptp offset */
+ NSS_PPE_STATS_CPU_CODE_PTP_SYNC = 113, /* PPE cpu code ptp sync */
+ NSS_PPE_STATS_CPU_CODE_PTP_FOLLOW_UP = 114, /* PPE cpu code ptp follow up */
+ NSS_PPE_STATS_CPU_CODE_PTP_DELAY_REQ = 115, /* PPE cpu code ptp delay req */
+ NSS_PPE_STATS_CPU_CODE_PTP_DELAY_RESP = 116, /* PPE cpu code ptp delay resp */
+ NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_REQ = 117, /* PPE cpu code ptp pdelay req */
+ NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_RESP = 118, /* PPE cpu code ptp pdelay resp */
+ NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_RESP_FOLLOW_UP = 119, /* PPE cpu code ptp pdelay resp follow up */
+ NSS_PPE_STATS_CPU_CODE_PTP_ANNOUNCE = 120, /* PPE cpu code ptp announce */
+ NSS_PPE_STATS_CPU_CODE_PTP_MANAGEMENT = 121, /* PPE cpu code ptp management */
+ NSS_PPE_STATS_CPU_CODE_PTP_SIGNALING = 122, /* PPE cpu code ptp signaling */
+ NSS_PPE_STATS_CPU_CODE_PTP_PKT_RSV_MSG = 127, /* PPE cpu code ptp pkt rsv msg */
+ NSS_PPE_STATS_CPU_CODE_IPV4_SG_UNKNOWN = 136, /* PPE cpu code ipv4 sg unknown */
+ NSS_PPE_STATS_CPU_CODE_IPV6_SG_UNKNOWN = 137, /* PPE cpu code ipv6 sg unknown */
+ NSS_PPE_STATS_CPU_CODE_ARP_SG_UNKNOWN = 138, /* PPE cpu code arp sg unknown */
+ NSS_PPE_STATS_CPU_CODE_ND_SG_UNKNOWN = 139, /* PPE cpu code nd sg unknown */
+ NSS_PPE_STATS_CPU_CODE_IPV4_SG_VIO = 140, /* PPE cpu code ipv4 sg vio */
+ NSS_PPE_STATS_CPU_CODE_IPV6_SG_VIO = 141, /* PPE cpu code ipv6 sg vio */
+ NSS_PPE_STATS_CPU_CODE_ARP_SG_VIO = 142, /* PPE cpu code arp sg vio */
+ NSS_PPE_STATS_CPU_CODE_ND_SG_VIO = 143, /* PPE cpu code nd sg vio */
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTING_IP_TO_ME = 148, /* PPE cpu code l3 routing ip to me */
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_SNAT_ACTION = 149, /* PPE cpu code l3 flow snat action */
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_DNAT_ACTION = 150, /* PPE cpu code l3 flow dnat action */
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_RT_ACTION = 151, /* PPE cpu code l3 flow rt action */
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_BR_ACTION = 152, /* PPE cpu code l3 flow br action */
+ NSS_PPE_STATS_CPU_CODE_L3_MC_BRIDGE_ACTION = 153, /* PPE cpu code l3 mc bridge action */
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_RT_ACTION = 154, /* PPE cpu code l3 route prehead rt action */
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_SNAPT_ACTION = 155, /* PPE cpu code l3 route prehead snapt action */
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_DNAPT_ACTION = 156, /* PPE cpu code l3 route prehead dnapt action */
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_SNAT_ACTION = 157, /* PPE cpu code l3 route prehead snat action */
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_DNAT_ACTION = 158, /* PPE cpu code l3 route prehead dnat action */
+ NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION = 159, /* PPE cpu code l3 no route prehead nat action */
+ NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR = 160, /* PPE cpu code l3 no route prehead nat error */
+ NSS_PPE_STATS_CPU_CODE_L3_ROUTE_ACTION = 161, /* PPE cpu code l3 route action */
+ NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_ACTION = 162, /* PPE cpu code l3 no route action */
+ NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_NH_INVALID_ACTION = 163, /* PPE cpu code l3 no route nh invalid action */
+ NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_ACTION = 164, /* PPE cpu code l3 no route prehead action */
+ NSS_PPE_STATS_CPU_CODE_L3_BRIDGE_ACTION = 165, /* PPE cpu code l3 bridge action */
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_ACTION = 166, /* PPE cpu code l3 flow action */
+ NSS_PPE_STATS_CPU_CODE_L3_FLOW_MISS_ACTION = 167, /* PPE cpu code l3 flow miss action */
+ NSS_PPE_STATS_CPU_CODE_L2_NEW_MAC_ADDRESS = 168, /* PPE cpu code l2 new mac address */
+ NSS_PPE_STATS_CPU_CODE_L2_HASH_COLLISION = 169, /* PPE cpu code l2 hash collision */
+ NSS_PPE_STATS_CPU_CODE_L2_STATION_MOVE = 170, /* PPE cpu code l2 station move */
+ NSS_PPE_STATS_CPU_CODE_L2_LEARN_LIMIT = 171, /* PPE cpu code l2 learn limit */
+ NSS_PPE_STATS_CPU_CODE_L2_SA_LOOKUP_ACTION = 172, /* PPE cpu code l2 sa lookup action */
+ NSS_PPE_STATS_CPU_CODE_L2_DA_LOOKUP_ACTION = 173, /* PPE cpu code l2 da lookup action */
+ NSS_PPE_STATS_CPU_CODE_APP_CTRL_ACTION = 174, /* PPE cpu code app ctrl action */
+ NSS_PPE_STATS_CPU_CODE_IN_VLAN_FILTER_ACTION = 175, /* PPE cpu code in vlan filter action */
+ NSS_PPE_STATS_CPU_CODE_IN_VLAN_XLT_MISS = 176, /* PPE cpu code in vlan xlt miss */
+ NSS_PPE_STATS_CPU_CODE_EG_VLAN_FILTER_DROP = 177, /* PPE cpu code eg vlan filter drop */
+ NSS_PPE_STATS_CPU_CODE_ACL_PRE_ACTION = 178, /* PPE cpu code acl pre action */
+ NSS_PPE_STATS_CPU_CODE_ACL_POST_ACTION = 179, /* PPE cpu code acl post action */
+ NSS_PPE_STATS_CPU_CODE_SERVICE_CODE_ACTION = 180, /* PPE cpu code service code action */
+};
+
+/*
+ * NSS PPE statistics
+ */
+struct nss_ppe_stats_debug {
+ uint32_t conn_stats[NSS_PPE_STATS_CONN_MAX];
+ uint32_t l3_stats[NSS_PPE_STATS_L3_MAX];
+ uint32_t code_stats[NSS_PPE_STATS_CODE_MAX];
+ int32_t if_index;
+ uint32_t if_num; /* nss interface number */
+ bool valid;
+};
+
+/*
+ * Data structures to store NSS PPE debug statistics
+ */
+static struct nss_ppe_stats_debug nss_ppe_debug_stats;
+
+/*
+ * NSS PPE statistics APIs
+ */
+extern void nss_ppe_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_sync_stats_msg *stats_msg, uint16_t if_num);
+extern void nss_ppe_stats_dentry_create(void);
+
+#endif /* __NSS_PPE_STATS_H */
diff --git a/nss_pppoe.c b/nss_pppoe.c
index 43a1946..18faea2 100644
--- a/nss_pppoe.c
+++ b/nss_pppoe.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -21,6 +21,7 @@
#include "nss_tx_rx_common.h"
#include <linux/if_pppox.h>
+#include "nss_pppoe_stats.h"
/*
* nss_pppoe_tx()
@@ -92,83 +93,6 @@
*/
/*
- * nss_pppoe_session_reset()
- * Reset PPPoE session when session is destroyed.
- */
-static void nss_pppoe_session_reset(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_session_reset_msg *npsr)
-{
- uint32_t i;
- uint32_t interface = npsr->interface;
- uint32_t session_index = npsr->session_index;
-
- /*
- * Reset the PPPoE statistics for this specific session.
- */
- spin_lock_bh(&nss_ctx->nss_top->stats_lock);
- for (i = 0; i < NSS_PPPOE_EXCEPTION_EVENT_MAX; i++) {
- nss_ctx->nss_top->stats_if_exception_pppoe[interface][session_index][i] = 0;
- }
- spin_unlock_bh(&nss_ctx->nss_top->stats_lock);
-}
-
-/*
- * nss_pppoe_exception_stats_sync()
- * Handle the syncing of PPPoE exception statistics.
- */
-static void nss_pppoe_exception_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_conn_stats_sync_msg *npess)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- uint32_t index = npess->index;
- uint32_t interface_num = npess->interface_num;
- uint32_t i;
-
- spin_lock_bh(&nss_top->stats_lock);
-
- if (interface_num >= NSS_MAX_PHYSICAL_INTERFACES) {
- spin_unlock_bh(&nss_top->stats_lock);
- nss_warning("%p: Incorrect interface number %d for PPPoE exception stats", nss_ctx, interface_num);
- return;
- }
-
- /*
- * pppoe exception stats
- */
- for (i = 0; i < NSS_PPPOE_EXCEPTION_EVENT_MAX; i++) {
- nss_top->stats_if_exception_pppoe[interface_num][index][i] += npess->exception_events_pppoe[i];
- }
-
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
- * nss_pppoe_node_stats_sync()
- * Handle the syncing of PPPoE node statistics.
- */
-static void nss_pppoe_node_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_node_stats_sync_msg *npess)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- int j;
-
- spin_lock_bh(&nss_top->stats_lock);
-
- nss_top->stats_node[NSS_PPPOE_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += npess->node_stats.rx_packets;
- nss_top->stats_node[NSS_PPPOE_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += npess->node_stats.rx_bytes;
- nss_top->stats_node[NSS_PPPOE_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += npess->node_stats.tx_packets;
- nss_top->stats_node[NSS_PPPOE_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += npess->node_stats.tx_bytes;
-
- for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
- nss_top->stats_node[NSS_PPPOE_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += npess->node_stats.rx_dropped[j];
- }
-
- nss_top->stats_pppoe[NSS_STATS_PPPOE_SESSION_CREATE_REQUESTS] += npess->pppoe_session_create_requests;
- nss_top->stats_pppoe[NSS_STATS_PPPOE_SESSION_CREATE_FAILURES] += npess->pppoe_session_create_failures;
- nss_top->stats_pppoe[NSS_STATS_PPPOE_SESSION_DESTROY_REQUESTS] += npess->pppoe_session_destroy_requests;
- nss_top->stats_pppoe[NSS_STATS_PPPOE_SESSION_DESTROY_REQUESTS] += npess->pppoe_session_destroy_requests;
-
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
* nss_pppoe_rx_msg_handler()
* Handle NSS -> HLOS messages for PPPoE
*/
@@ -201,13 +125,13 @@
*/
switch (nim->cm.type) {
case NSS_PPPOE_RX_NODE_STATS_SYNC:
- nss_pppoe_node_stats_sync(nss_ctx, &nim->msg.pppoe_node_stats_sync);
+ nss_pppoe_stats_node_sync(nss_ctx, &nim->msg.pppoe_node_stats_sync);
break;
case NSS_PPPOE_RX_CONN_STATS_SYNC:
- nss_pppoe_exception_stats_sync(nss_ctx, &nim->msg.pppoe_conn_stats_sync);
+ nss_pppoe_stats_exception_sync(nss_ctx, &nim->msg.pppoe_conn_stats_sync);
break;
case NSS_PPPOE_RX_SESSION_RESET:
- nss_pppoe_session_reset(nss_ctx, &nim->msg.pppoe_session_reset);
+ nss_pppoe_stats_session_reset(nss_ctx, &nim->msg.pppoe_session_reset);
break;
default:
nss_warning("%p: Received response %d for type %d, interface %d",
@@ -221,6 +145,8 @@
void nss_pppoe_register_handler(struct nss_ctx_instance *nss_ctx)
{
nss_core_register_handler(nss_ctx, NSS_PPPOE_RX_INTERFACE, nss_pppoe_rx_msg_handler, NULL);
+
+ nss_pppoe_stats_dentry_create();
}
/*
diff --git a/nss_pppoe_stats.c b/nss_pppoe_stats.c
new file mode 100644
index 0000000..e95582e
--- /dev/null
+++ b/nss_pppoe_stats.c
@@ -0,0 +1,222 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_pppoe_stats.h"
+
+uint64_t nss_pppoe_stats[NSS_PPPOE_STATS_MAX];
+uint64_t nss_pppoe_stats_exception[NSS_MAX_PHYSICAL_INTERFACES + 1][NSS_PPPOE_NUM_SESSION_PER_INTERFACE + 1][NSS_PPPOE_EXCEPTION_EVENT_MAX];
+
+/*
+ * nss_pppoe_stats_str
+ * PPPoE stats strings
+ */
+static int8_t *nss_pppoe_stats_str[NSS_PPPOE_STATS_MAX] = {
+ "create_requests",
+ "create_failures",
+ "destroy_requests",
+ "destroy_misses"
+};
+
+/*
+ * nss_pppoe_stats_exception_str
+ * Interface stats strings for PPPoE exceptions
+ */
+static int8_t *nss_pppoe_stats_exception_str[NSS_PPPOE_EXCEPTION_EVENT_MAX] = {
+ "PPPOE_WRONG_VERSION_OR_TYPE",
+ "PPPOE_WRONG_CODE",
+ "PPPOE_HEADER_INCOMPLETE",
+ "PPPOE_UNSUPPORTED_PPP_PROTOCOL",
+ "PPPOE_DEPRECATED"
+};
+
+/*
+ * nss_pppoe_stats_read()
+ * Read PPPoE stats
+ */
+static ssize_t nss_pppoe_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ uint64_t stats_shadow_pppoe_except[NSS_PPPOE_NUM_SESSION_PER_INTERFACE][NSS_PPPOE_EXCEPTION_EVENT_MAX];
+ int32_t i, j, k;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_PPPOE_STATS_MAX + 3) +
+ ((NSS_MAX_PHYSICAL_INTERFACES * NSS_PPPOE_NUM_SESSION_PER_INTERFACE * (NSS_PPPOE_EXCEPTION_EVENT_MAX + 5)) + 3) + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "pppoe stats start:\n\n");
+
+ size_wr = nss_stats_fill_common_stats(NSS_PPPOE_RX_INTERFACE, lbuf, size_wr, size_al);
+
+ /*
+ * PPPoE node stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npppoe node stats:\n\n");
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_PPPOE_STATS_MAX); i++) {
+ stats_shadow[i] = nss_pppoe_stats[i];
+ }
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_PPPOE_STATS_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_pppoe_stats_str[i], stats_shadow[i]);
+ }
+
+ /*
+ * Exception stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nException PPPoE:\n\n");
+
+ for (j = 1; j <= NSS_MAX_PHYSICAL_INTERFACES; j++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nInterface %d:\n\n", j);
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (k = 1; k <= NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
+ for (i = 0; (i < NSS_PPPOE_EXCEPTION_EVENT_MAX); i++) {
+ stats_shadow_pppoe_except[k - 1][i] = nss_pppoe_stats_exception[j][k][i];
+ }
+ }
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (k = 1; k <= NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. Session\n", k);
+ for (i = 0; (i < NSS_PPPOE_EXCEPTION_EVENT_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n",
+ nss_pppoe_stats_exception_str[i],
+ stats_shadow_pppoe_except[k - 1][i]);
+ }
+ }
+
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npppoe stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_pppoe_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(pppoe)
+
+/*
+ * nss_pppoe_stats_dentry_create()
+ * Create PPPoE node statistics debug entry.
+ */
+void nss_pppoe_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("pppoe", &nss_pppoe_stats_ops);
+}
+
+/*
+ * nss_pppoe_stats_node_sync()
+ * Handle the syncing of PPPoE node statistics.
+ */
+void nss_pppoe_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_node_stats_sync_msg *npess)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ int j;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ nss_top->stats_node[NSS_PPPOE_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += npess->node_stats.rx_packets;
+ nss_top->stats_node[NSS_PPPOE_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += npess->node_stats.rx_bytes;
+ nss_top->stats_node[NSS_PPPOE_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += npess->node_stats.tx_packets;
+ nss_top->stats_node[NSS_PPPOE_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += npess->node_stats.tx_bytes;
+
+ for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
+ nss_top->stats_node[NSS_PPPOE_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += npess->node_stats.rx_dropped[j];
+ }
+
+ nss_pppoe_stats[NSS_PPPOE_STATS_SESSION_CREATE_REQUESTS] += npess->pppoe_session_create_requests;
+ nss_pppoe_stats[NSS_PPPOE_STATS_SESSION_CREATE_FAILURES] += npess->pppoe_session_create_failures;
+ nss_pppoe_stats[NSS_PPPOE_STATS_SESSION_DESTROY_REQUESTS] += npess->pppoe_session_destroy_requests;
+ nss_pppoe_stats[NSS_PPPOE_STATS_SESSION_DESTROY_REQUESTS] += npess->pppoe_session_destroy_requests;
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
+
+/*
+ * nss_pppoe_stats_session_reset()
+ * Reset PPPoE session when session is destroyed.
+ */
+void nss_pppoe_stats_session_reset(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_session_reset_msg *npsr)
+{
+ uint32_t i;
+ uint32_t interface = npsr->interface;
+ uint32_t session_index = npsr->session_index;
+
+ /*
+ * Reset the PPPoE statistics for this specific session.
+ */
+ spin_lock_bh(&nss_ctx->nss_top->stats_lock);
+ for (i = 0; i < NSS_PPPOE_EXCEPTION_EVENT_MAX; i++) {
+ nss_pppoe_stats_exception[interface][session_index][i] = 0;
+ }
+ spin_unlock_bh(&nss_ctx->nss_top->stats_lock);
+}
+
+/*
+ * nss_pppoe_stats_exception_sync()
+ * Handle the syncing of PPPoE exception statistics.
+ */
+void nss_pppoe_stats_exception_sync(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_conn_stats_sync_msg *npess)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ uint32_t index = npess->index;
+ uint32_t interface_num = npess->interface_num;
+ uint32_t i;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ if (interface_num >= NSS_MAX_PHYSICAL_INTERFACES) {
+ spin_unlock_bh(&nss_top->stats_lock);
+ nss_warning("%p: Incorrect interface number %d for PPPoE exception stats", nss_ctx, interface_num);
+ return;
+ }
+
+ /*
+ * pppoe exception stats
+ */
+ for (i = 0; i < NSS_PPPOE_EXCEPTION_EVENT_MAX; i++) {
+ nss_pppoe_stats_exception[interface_num][index][i] += npess->exception_events_pppoe[i];
+ }
+ spin_unlock_bh(&nss_top->stats_lock);
+}
diff --git a/nss_pppoe_stats.h b/nss_pppoe_stats.h
new file mode 100644
index 0000000..dc33f7b
--- /dev/null
+++ b/nss_pppoe_stats.h
@@ -0,0 +1,43 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_PPPOE_STATS_H
+#define __NSS_PPPOE_STATS_H
+
+/*
+ * PPPoE statistics
+ */
+enum nss_pppoe_stats_types {
+ NSS_PPPOE_STATS_SESSION_CREATE_REQUESTS = 0,
+ /* Number of PPPoE session create requests */
+ NSS_PPPOE_STATS_SESSION_CREATE_FAILURES,
+ /* Number of PPPoE session create failures */
+ NSS_PPPOE_STATS_SESSION_DESTROY_REQUESTS,
+ /* Number of PPPoE session destroy requests */
+ NSS_PPPOE_STATS_SESSION_DESTROY_MISSES,
+ /* Number of PPPoE session destroy requests that missed the cache */
+ NSS_PPPOE_STATS_MAX,
+};
+
+/*
+ * PPPoE statistics APIs
+ */
+extern void nss_pppoe_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_node_stats_sync_msg *npess);
+extern void nss_pppoe_stats_session_reset(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_session_reset_msg *npsr);
+extern void nss_pppoe_stats_exception_sync(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_conn_stats_sync_msg *npess);
+extern void nss_pppoe_stats_dentry_create(void);
+
+#endif /* __NSS_PPPOE_STATS_H */
diff --git a/nss_pptp.c b/nss_pptp.c
index dc66b14..8af8ef2 100644
--- a/nss_pptp.c
+++ b/nss_pptp.c
@@ -16,6 +16,7 @@
#include <net/sock.h>
#include "nss_tx_rx_common.h"
+#include "nss_pptp_stats.h"
#define NSS_PPTP_TX_TIMEOUT 3000 /* 3 Seconds */
@@ -23,7 +24,7 @@
* Data structures to store pptp nss debug stats
*/
static DEFINE_SPINLOCK(nss_pptp_session_debug_stats_lock);
-static struct nss_stats_pptp_session_debug nss_pptp_session_debug_stats[NSS_MAX_PPTP_DYNAMIC_INTERFACES];
+static struct nss_pptp_stats_session_debug nss_pptp_session_debug_stats[NSS_MAX_PPTP_DYNAMIC_INTERFACES];
/*
* Private data structure
@@ -46,31 +47,31 @@
spin_lock_bh(&nss_pptp_session_debug_stats_lock);
for (i = 0; i < NSS_MAX_PPTP_DYNAMIC_INTERFACES; i++) {
if (nss_pptp_session_debug_stats[i].if_num == if_num) {
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_ENCAP_RX_PACKETS] += stats_msg->encap_stats.rx_packets;
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_ENCAP_RX_BYTES] += stats_msg->encap_stats.rx_bytes;
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_ENCAP_TX_PACKETS] += stats_msg->encap_stats.tx_packets;
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_ENCAP_TX_BYTES] += stats_msg->encap_stats.tx_bytes;
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_ENCAP_RX_PACKETS] += stats_msg->encap_stats.rx_packets;
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_ENCAP_RX_BYTES] += stats_msg->encap_stats.rx_bytes;
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_ENCAP_TX_PACKETS] += stats_msg->encap_stats.tx_packets;
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_ENCAP_TX_BYTES] += stats_msg->encap_stats.tx_bytes;
for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_ENCAP_RX_QUEUE_0_DROP + j] += stats_msg->encap_stats.rx_dropped[j];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_ENCAP_RX_QUEUE_0_DROP + j] += stats_msg->encap_stats.rx_dropped[j];
}
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_DECAP_RX_PACKETS] += stats_msg->decap_stats.rx_packets;
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_DECAP_RX_BYTES] += stats_msg->decap_stats.rx_bytes;
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_DECAP_TX_PACKETS] += stats_msg->decap_stats.tx_packets;
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_DECAP_TX_BYTES] += stats_msg->decap_stats.tx_bytes;
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_DECAP_RX_PACKETS] += stats_msg->decap_stats.rx_packets;
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_DECAP_RX_BYTES] += stats_msg->decap_stats.rx_bytes;
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_DECAP_TX_PACKETS] += stats_msg->decap_stats.tx_packets;
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_DECAP_TX_BYTES] += stats_msg->decap_stats.tx_bytes;
for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_DECAP_RX_QUEUE_0_DROP + j] += stats_msg->decap_stats.rx_dropped[j];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_DECAP_RX_QUEUE_0_DROP + j] += stats_msg->decap_stats.rx_dropped[j];
}
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_SESSION_ENCAP_HEADROOM_ERR] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_ENCAP_HEADROOM_ERR];
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_SESSION_ENCAP_SMALL_SIZE] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_ENCAP_SMALL_SIZE];
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_SESSION_ENCAP_PNODE_ENQUEUE_FAIL] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_ENCAP_PNODE_ENQUEUE_FAIL];
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_SESSION_DECAP_NO_SEQ_NOR_ACK] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_NO_SEQ_NOR_ACK];
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_SESSION_DECAP_INVAL_GRE_FLAGS] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_INVAL_GRE_FLAGS];
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_SESSION_DECAP_INVAL_GRE_PROTO] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_INVAL_GRE_PROTO];
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_SESSION_DECAP_WRONG_SEQ] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_WRONG_SEQ];
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_SESSION_DECAP_INVAL_PPP_HDR] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_INVAL_PPP_HDR];
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_SESSION_DECAP_PPP_LCP] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_PPP_LCP];
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_SESSION_DECAP_UNSUPPORTED_PPP_PROTO] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_UNSUPPORTED_PPP_PROTO];
- nss_pptp_session_debug_stats[i].stats[NSS_STATS_PPTP_SESSION_DECAP_PNODE_ENQUEUE_FAIL] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_PNODE_ENQUEUE_FAIL];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_ENCAP_HEADROOM_ERR] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_ENCAP_HEADROOM_ERR];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_ENCAP_SMALL_SIZE] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_ENCAP_SMALL_SIZE];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_ENCAP_PNODE_ENQUEUE_FAIL] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_ENCAP_PNODE_ENQUEUE_FAIL];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_NO_SEQ_NOR_ACK] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_NO_SEQ_NOR_ACK];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_INVAL_GRE_FLAGS] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_INVAL_GRE_FLAGS];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_INVAL_GRE_PROTO] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_INVAL_GRE_PROTO];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_WRONG_SEQ] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_WRONG_SEQ];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_INVAL_PPP_HDR] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_INVAL_PPP_HDR];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_PPP_LCP] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_PPP_LCP];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_UNSUPPORTED_PPP_PROTO] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_UNSUPPORTED_PPP_PROTO];
+ nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_PNODE_ENQUEUE_FAIL] += stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_PNODE_ENQUEUE_FAIL];
break;
}
}
@@ -83,7 +84,7 @@
*/
void nss_pptp_session_debug_stats_get(void *stats_mem)
{
- struct nss_stats_pptp_session_debug *stats = (struct nss_stats_pptp_session_debug *)stats_mem;
+ struct nss_pptp_stats_session_debug *stats = (struct nss_pptp_stats_session_debug *)stats_mem;
int i;
if (!stats) {
@@ -94,7 +95,7 @@
spin_lock_bh(&nss_pptp_session_debug_stats_lock);
for (i = 0; i < NSS_MAX_PPTP_DYNAMIC_INTERFACES; i++) {
if (nss_pptp_session_debug_stats[i].valid) {
- memcpy(stats, &nss_pptp_session_debug_stats[i], sizeof(struct nss_stats_pptp_session_debug));
+ memcpy(stats, &nss_pptp_session_debug_stats[i], sizeof(struct nss_pptp_stats_session_debug));
stats++;
}
}
@@ -437,6 +438,8 @@
sema_init(&pptp_pvt.sem, 1);
init_completion(&pptp_pvt.complete);
+
+ nss_pptp_stats_dentry_create();
}
EXPORT_SYMBOL(nss_pptp_get_context);
diff --git a/nss_pptp_stats.c b/nss_pptp_stats.c
new file mode 100644
index 0000000..1e578cd
--- /dev/null
+++ b/nss_pptp_stats.c
@@ -0,0 +1,133 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_pptp_stats.h"
+
+/*
+ * nss_pptp_stats_session_debug_str
+ * PPTP statistics strings for nss session stats
+ */
+static int8_t *nss_pptp_stats_session_debug_str[NSS_PPTP_STATS_SESSION_MAX] = {
+ "ENCAP_RX_PACKETS",
+ "ENCAP_RX_BYTES",
+ "ENCAP_TX_PACKETS",
+ "ENCAP_TX_BYTES",
+ "ENCAP_RX_QUEUE_0_DROP",
+ "ENCAP_RX_QUEUE_1_DROP",
+ "ENCAP_RX_QUEUE_2_DROP",
+ "ENCAP_RX_QUEUE_3_DROP",
+ "DECAP_RX_PACKETS",
+ "DECAP_RX_BYTES",
+ "DECAP_TX_PACKETS",
+ "DECAP_TX_BYTES",
+ "DECAP_RX_QUEUE_0_DROP",
+ "DECAP_RX_QUEUE_1_DROP",
+ "DECAP_RX_QUEUE_2_DROP",
+ "DECAP_RX_QUEUE_3_DROP",
+ "ENCAP_HEADROOM_ERR",
+ "ENCAP_SMALL_SIZE",
+ "ENCAP_PNODE_ENQUEUE_FAIL",
+ "DECAP_NO_SEQ_NOR_ACK",
+ "DECAP_INVAL_GRE_FLAGS",
+ "DECAP_INVAL_GRE_PROTO",
+ "DECAP_WRONG_SEQ",
+ "DECAP_INVAL_PPP_HDR",
+ "DECAP_PPP_LCP",
+ "DECAP_UNSUPPORTED_PPP_PROTO",
+ "DECAP_PNODE_ENQUEUE_FAIL",
+};
+
+/*
+ * nss_pptp_stats_read()
+ * Read pptp statistics
+ */
+static ssize_t nss_pptp_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+
+ uint32_t max_output_lines = 2 /* header & footer for session stats */
+ + NSS_MAX_PPTP_DYNAMIC_INTERFACES * (NSS_PPTP_STATS_SESSION_MAX + 2) /*session stats */
+ + 2;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines ;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ struct net_device *dev;
+ struct nss_pptp_stats_session_debug pptp_session_stats[NSS_MAX_PPTP_DYNAMIC_INTERFACES];
+ int id, i;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ memset(&pptp_session_stats, 0, sizeof(struct nss_pptp_stats_session_debug) * NSS_MAX_PPTP_DYNAMIC_INTERFACES);
+
+ /*
+ * Get all stats
+ */
+ nss_pptp_session_debug_stats_get((void *)&pptp_session_stats);
+
+ /*
+ * Session stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npptp session stats start:\n\n");
+ for (id = 0; id < NSS_MAX_PPTP_DYNAMIC_INTERFACES; id++) {
+
+ if (!pptp_session_stats[id].valid) {
+ break;
+ }
+
+ dev = dev_get_by_index(&init_net, pptp_session_stats[id].if_index);
+ if (likely(dev)) {
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id,
+ pptp_session_stats[id].if_num, dev->name);
+ dev_put(dev);
+ } else {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id,
+ pptp_session_stats[id].if_num);
+ }
+
+ for (i = 0; i < NSS_PPTP_STATS_SESSION_MAX; i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "\t%s = %llu\n", nss_pptp_stats_session_debug_str[i],
+ pptp_session_stats[id].stats[i]);
+ }
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npptp session stats end\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
+
+ kfree(lbuf);
+ return bytes_read;
+}
+
+/*
+ * nss_pptp_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(pptp)
+
+/*
+ * nss_pptp_stats_dentry_create()
+ * Create PPTP node statistics debug entry.
+ */
+void nss_pptp_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("pptp", &nss_pptp_stats_ops);
+}
diff --git a/nss_pptp_stats.h b/nss_pptp_stats.h
new file mode 100644
index 0000000..5860ae0
--- /dev/null
+++ b/nss_pptp_stats.h
@@ -0,0 +1,69 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_PPTP_STATS_H
+#define __NSS_PPTP_STATS_H
+
+/*
+ * PPTP debug stats
+ */
+enum nss_pptp_stats_session {
+ NSS_PPTP_STATS_ENCAP_RX_PACKETS,
+ NSS_PPTP_STATS_ENCAP_RX_BYTES,
+ NSS_PPTP_STATS_ENCAP_TX_PACKETS,
+ NSS_PPTP_STATS_ENCAP_TX_BYTES,
+ NSS_PPTP_STATS_ENCAP_RX_QUEUE_0_DROP,
+ NSS_PPTP_STATS_ENCAP_RX_QUEUE_1_DROP,
+ NSS_PPTP_STATS_ENCAP_RX_QUEUE_2_DROP,
+ NSS_PPTP_STATS_ENCAP_RX_QUEUE_3_DROP,
+ NSS_PPTP_STATS_DECAP_RX_PACKETS,
+ NSS_PPTP_STATS_DECAP_RX_BYTES,
+ NSS_PPTP_STATS_DECAP_TX_PACKETS,
+ NSS_PPTP_STATS_DECAP_TX_BYTES,
+ NSS_PPTP_STATS_DECAP_RX_QUEUE_0_DROP,
+ NSS_PPTP_STATS_DECAP_RX_QUEUE_1_DROP,
+ NSS_PPTP_STATS_DECAP_RX_QUEUE_2_DROP,
+ NSS_PPTP_STATS_DECAP_RX_QUEUE_3_DROP,
+ NSS_PPTP_STATS_SESSION_ENCAP_HEADROOM_ERR,
+ NSS_PPTP_STATS_SESSION_ENCAP_SMALL_SIZE,
+ NSS_PPTP_STATS_SESSION_ENCAP_PNODE_ENQUEUE_FAIL,
+ NSS_PPTP_STATS_SESSION_DECAP_NO_SEQ_NOR_ACK,
+ NSS_PPTP_STATS_SESSION_DECAP_INVAL_GRE_FLAGS,
+ NSS_PPTP_STATS_SESSION_DECAP_INVAL_GRE_PROTO,
+ NSS_PPTP_STATS_SESSION_DECAP_WRONG_SEQ,
+ NSS_PPTP_STATS_SESSION_DECAP_INVAL_PPP_HDR,
+ NSS_PPTP_STATS_SESSION_DECAP_PPP_LCP,
+ NSS_PPTP_STATS_SESSION_DECAP_UNSUPPORTED_PPP_PROTO,
+ NSS_PPTP_STATS_SESSION_DECAP_PNODE_ENQUEUE_FAIL,
+ NSS_PPTP_STATS_SESSION_MAX
+};
+
+/*
+ * NSS PPTP node statistics session
+ */
+struct nss_pptp_stats_session_debug {
+ uint64_t stats[NSS_PPTP_STATS_SESSION_MAX];
+ int32_t if_index;
+ uint32_t if_num; /* nss interface number */
+ bool valid;
+};
+
+/*
+ * NSS PPTP statistics APIs
+ */
+extern void nss_pptp_stats_dentry_create(void);
+
+#endif /* __NSS_PPTP_STATS_H */
diff --git a/nss_sjack.c b/nss_sjack.c
index 84b5f92..ab79f9b 100644
--- a/nss_sjack.c
+++ b/nss_sjack.c
@@ -15,31 +15,7 @@
*/
#include "nss_tx_rx_common.h"
-
-/*
- * nss_sjack_node_sync_update()
- * Update sjack node stats.
- */
-static void nss_sjack_node_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_sjack_stats_sync_msg *nins)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- int j;
-
- /*
- * Update SJACK node stats.
- */
- spin_lock_bh(&nss_top->stats_lock);
- nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nins->node_stats.rx_packets;
- nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nins->node_stats.rx_bytes;
- nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nins->node_stats.tx_packets;
- nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nins->node_stats.tx_bytes;
-
- for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
- nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nins->node_stats.rx_dropped[j];
- }
-
- spin_unlock_bh(&nss_top->stats_lock);
-}
+#include "nss_sjack_stats.h"
/*
* nss_sjack_handler()
@@ -85,7 +61,7 @@
/*
* Update sjack statistics on node sync.
*/
- nss_sjack_node_sync_update(nss_ctx, &nsm->msg.stats_sync);
+ nss_sjack_stats_node_sync(nss_ctx, &nsm->msg.stats_sync);
break;
}
@@ -219,6 +195,8 @@
struct nss_ctx_instance *nss_ctx = nss_sjack_get_context();
nss_core_register_handler(nss_ctx, NSS_SJACK_INTERFACE, nss_sjack_handler, NULL);
+
+ nss_sjack_stats_dentry_create();
}
EXPORT_SYMBOL(nss_sjack_register_if);
diff --git a/nss_sjack_stats.c b/nss_sjack_stats.c
new file mode 100644
index 0000000..ce3458e
--- /dev/null
+++ b/nss_sjack_stats.c
@@ -0,0 +1,99 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_sjack_stats.h"
+
+/*
+ * nss_sjack_stats_read()
+ * Read SJACK stats
+ */
+static ssize_t nss_sjack_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = NSS_STATS_NODE_MAX + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "sjack stats start:\n\n");
+
+ size_wr = nss_stats_fill_common_stats(NSS_SJACK_INTERFACE, lbuf, size_wr, size_al);
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nsjack stats end\n\n");
+
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_sjack_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(sjack)
+
+/*
+ * nss_sjack_stats_dentry_create()
+ * Create SJACK node statistics debug entry.
+ */
+void nss_sjack_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("sjack", &nss_sjack_stats_ops);
+}
+
+/*
+ * nss_sjack_stats_node_sync()
+ * Update sjack node stats.
+ */
+void nss_sjack_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_sjack_stats_sync_msg *nins)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ int j;
+
+ /*
+ * Update SJACK node stats.
+ */
+ spin_lock_bh(&nss_top->stats_lock);
+ nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_SJACK_STATS_RX_PKTS] += nins->node_stats.rx_packets;
+ nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_SJACK_STATS_RX_BYTES] += nins->node_stats.rx_bytes;
+ nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_SJACK_STATS_TX_PKTS] += nins->node_stats.tx_packets;
+ nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_SJACK_STATS_TX_BYTES] += nins->node_stats.tx_bytes;
+
+ for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
+ nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_SJACK_STATS_RX_QUEUE_0_DROPPED + j] += nins->node_stats.rx_dropped[j];
+ }
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
diff --git a/nss_sjack_stats.h b/nss_sjack_stats.h
new file mode 100644
index 0000000..cbcd604
--- /dev/null
+++ b/nss_sjack_stats.h
@@ -0,0 +1,45 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_SJACK_STATS_H
+#define __NSS_SJACK_STATS_H
+
+/*
+ * SJACK statistics
+ */
+enum nss_sjack_stats_types {
+ NSS_SJACK_STATS_RX_PKTS, /* sjack node RX packets */
+ NSS_SJACK_STATS_RX_BYTES, /* sjack node RX bytes */
+ NSS_SJACK_STATS_TX_PKTS, /* sjack node TX packets */
+ NSS_SJACK_STATS_TX_BYTES, /* sjack node TX bytes */
+ NSS_SJACK_STATS_RX_QUEUE_0_DROPPED,
+ /* sjack node RX Queue 0 dropped */
+ NSS_SJACK_STATS_RX_QUEUE_1_DROPPED,
+ /* sjack node RX Queue 1 dropped */
+ NSS_SJACK_STATS_RX_QUEUE_2_DROPPED,
+ /* sjack node RX Queue 2 dropped */
+ NSS_SJACK_STATS_RX_QUEUE_3_DROPPED,
+ /* sjack node RX Queue 3 dropped */
+ NSS_SJACK_STATS_MAX,
+};
+
+/*
+ * SJACK statistics APIs
+ */
+extern void nss_sjack_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_sjack_stats_sync_msg *nins);
+extern void nss_sjack_stats_dentry_create(void);
+
+#endif /* __NSS_SJACK_STATS_H */
diff --git a/nss_stats.c b/nss_stats.c
index 6d4ea03..5996b54 100644
--- a/nss_stats.c
+++ b/nss_stats.c
@@ -20,157 +20,9 @@
*
*/
-#include "nss_core.h"
-#include "nss_dtls_stats.h"
-#include "nss_gre_tunnel_stats.h"
#include "nss_tx_rx_common.h"
-
-/*
- * Maximum string length:
- * This should be equal to maximum string size of any stats
- * inclusive of stats value
- */
-#define NSS_STATS_MAX_STR_LENGTH 96
-#define NSS_STATS_WIFILI_MAX (NSS_STATS_WIFILI_TXRX_MAX + NSS_STATS_WIFILI_TCL_MAX + \
- NSS_STATS_WIFILI_TX_DESC_FREE_MAX + NSS_STATS_WIFILI_REO_MAX + \
- NSS_STATS_WIFILI_TX_DESC_MAX + NSS_STATS_WIFILI_EXT_TX_DESC_MAX + \
- NSS_STATS_WIFILI_RX_DESC_MAX + NSS_STATS_WIFILI_RXDMA_DESC_MAX)
-
-extern int32_t nss_tx_rx_virt_if_copy_stats(int32_t if_num, int i, char *line);
-
-uint64_t stats_shadow_pppoe_except[NSS_PPPOE_NUM_SESSION_PER_INTERFACE][NSS_PPPOE_EXCEPTION_EVENT_MAX];
-
-/*
- * Private data for every file descriptor
- */
-struct nss_stats_data {
- uint32_t if_num; /* Interface number for stats */
- uint32_t index; /* Index for GRE_REDIR stats */
- uint32_t edma_id; /* EDMA port ID or ring ID */
- struct nss_ctx_instance *nss_ctx;
- /* The core for project stats */
-};
-
-/*
- * Statistics structures
- */
-
-/*
- * nss_stats_str_ipv4
- * IPv4 stats strings
- */
-static int8_t *nss_stats_str_ipv4[NSS_STATS_IPV4_MAX] = {
- "rx_pkts",
- "rx_bytes",
- "tx_pkts",
- "tx_bytes",
- "create_requests",
- "create_collisions",
- "create_invalid_interface",
- "destroy_requests",
- "destroy_misses",
- "hash_hits",
- "hash_reorders",
- "flushes",
- "evictions",
- "fragmentations",
- "dropped_by_rule",
- "mc_create_requests",
- "mc_update_requests",
- "mc_create_invalid_interface",
- "mc_destroy_requests",
- "mc_destroy_misses",
- "mc_flushes",
-};
-
-/*
- * nss_stats_str_ipv4_reasm
- * IPv4 reassembly stats strings
- */
-static int8_t *nss_stats_str_ipv4_reasm[NSS_STATS_IPV4_REASM_MAX] = {
- "evictions",
- "alloc_fails",
- "timeouts",
-};
-
-/*
- * nss_stats_str_ipv6
- * IPv6 stats strings
- */
-static int8_t *nss_stats_str_ipv6[NSS_STATS_IPV6_MAX] = {
- "rx_pkts",
- "rx_bytes",
- "tx_pkts",
- "tx_bytes",
- "create_requests",
- "create_collisions",
- "create_invalid_interface",
- "destroy_requests",
- "destroy_misses",
- "hash_hits",
- "hash_reorders",
- "flushes",
- "evictions",
- "fragmentations",
- "frag_fails",
- "dropped_by_rule",
- "mc_create_requests",
- "mc_update_requests",
- "mc_create_invalid_interface",
- "mc_destroy_requests",
- "mc_destroy_misses",
- "mc_flushes",
-};
-
-/*
- * nss_stats_str_ipv6_reasm
- * IPv6 reassembly stats strings
- */
-static int8_t *nss_stats_str_ipv6_reasm[NSS_STATS_IPV6_REASM_MAX] = {
- "alloc_fails",
- "timeouts",
- "discards",
-};
-
-/*
- * nss_stats_str_n2h
- * N2H stats strings
- */
-static int8_t *nss_stats_str_n2h[NSS_STATS_N2H_MAX] = {
- "queue_dropped",
- "ticks",
- "worst_ticks",
- "iterations",
- "pbuf_ocm_alloc_fails",
- "pbuf_ocm_free_count",
- "pbuf_ocm_total_count",
- "pbuf_default_alloc_fails",
- "pbuf_default_free_count",
- "pbuf_default_total_count",
- "payload_fails",
- "payload_free_count",
- "h2n_control_packets",
- "h2n_control_bytes",
- "n2h_control_packets",
- "n2h_control_bytes",
- "h2n_data_packets",
- "h2n_data_bytes",
- "n2h_data_packets",
- "n2h_data_bytes",
- "n2h_tot_payloads",
- "n2h_data_interface_invalid",
-};
-
-/*
- * nss_stats_str_lso_rx
- * LSO_RX stats strings
- */
-static int8_t *nss_stats_str_lso_rx[NSS_STATS_LSO_RX_MAX] = {
- "tx_dropped",
- "dropped",
- "pbuf_alloc_fail",
- "pbuf_reference_fail"
-};
+#include "nss_core.h"
+#include "nss_stats.h"
/*
* nss_stats_str_drv
@@ -206,17 +58,6 @@
};
/*
- * nss_stats_str_pppoe
- * PPPoE stats strings
- */
-static int8_t *nss_stats_str_pppoe[NSS_STATS_PPPOE_MAX] = {
- "create_requests",
- "create_failures",
- "destroy_requests",
- "destroy_misses"
-};
-
-/*
* nss_stats_str_gmac
* GMAC stats strings
*/
@@ -227,70 +68,6 @@
};
/*
- * nss_stats_str_edma_tx
- */
-static int8_t *nss_stats_str_edma_tx[NSS_STATS_EDMA_TX_MAX] = {
- "tx_err",
- "tx_dropped",
- "desc_cnt"
-};
-
-/*
- * nss_stats_str_edma_rx
- */
-static int8_t *nss_stats_str_edma_rx[NSS_STATS_EDMA_RX_MAX] = {
- "rx_csum_err",
- "desc_cnt",
- "qos_err"
-};
-
-/*
- * nss_stats_str_edma_txcmpl
- */
-static int8_t *nss_stats_str_edma_txcmpl[NSS_STATS_EDMA_TXCMPL_MAX] = {
- "desc_cnt"
-};
-
-/*
- * nss_stats_str_edma_rxfill
- */
-static int8_t *nss_stats_str_edma_rxfill[NSS_STATS_EDMA_RXFILL_MAX] = {
- "desc_cnt"
-};
-
-/*
- * nss_stats_str_edma_port_type
- */
-static int8_t *nss_stats_str_edma_port_type[NSS_EDMA_PORT_TYPE_MAX] = {
- "physical_port",
- "virtual_port"
-};
-
-/*
- * nss_stats_str_edma_port_ring_map
- */
-static int8_t *nss_stats_str_edma_port_ring_map[NSS_EDMA_PORT_RING_MAP_MAX] = {
- "rx_ring",
- "tx_ring"
-};
-
-/*
- * nss_stats_str_edma_err_map
- */
-static int8_t *nss_stats_str_edma_err_map[NSS_EDMA_ERR_STATS_MAX] = {
- "axi_rd_err",
- "axi_wr_err",
- "rx_desc_fifo_full_err",
- "rx_buf_size_err",
- "tx_sram_full_err",
- "tx_cmpl_buf_full_err",
- "pkt_len_la64k_err",
- "pkt_len_le33_err",
- "data_len_err",
- "alloc_fail_cnt"
-};
-
-/*
* nss_stats_str_node
* Interface stats strings per node
*/
@@ -306,969 +83,30 @@
};
/*
- * nss_stats_str_eth_rx
- * eth_rx stats strings
+ * nss_stats_create_dentry()
+ * Create statistics debug entry for subsystem.
*/
-static int8_t *nss_stats_str_eth_rx[NSS_STATS_ETH_RX_MAX] = {
- "ticks",
- "worst_ticks",
- "iterations"
-};
-
-/*
- * nss_stats_str_if_exception_unknown
- * Interface stats strings for unknown exceptions
- */
-static int8_t *nss_stats_str_if_exception_eth_rx[NSS_EXCEPTION_EVENT_ETH_RX_MAX] = {
- "UNKNOWN_L3_PROTOCOL",
- "ETH_HDR_MISSING",
- "VLAN_MISSING",
- "TRUSTSEC_HDR_MISSING"
-};
-
-/*
- * nss_stats_str_if_exception_ipv4
- * Interface stats strings for ipv4 exceptions
- */
-static int8_t *nss_stats_str_if_exception_ipv4[NSS_EXCEPTION_EVENT_IPV4_MAX] = {
- "IPV4_ICMP_HEADER_INCOMPLETE",
- "IPV4_ICMP_UNHANDLED_TYPE",
- "IPV4_ICMP_IPV4_HEADER_INCOMPLETE",
- "IPV4_ICMP_IPV4_UDP_HEADER_INCOMPLETE",
- "IPV4_ICMP_IPV4_TCP_HEADER_INCOMPLETE",
- "IPV4_ICMP_IPV4_UNKNOWN_PROTOCOL",
- "IPV4_ICMP_NO_ICME",
- "IPV4_ICMP_FLUSH_TO_HOST",
- "IPV4_TCP_HEADER_INCOMPLETE",
- "IPV4_TCP_NO_ICME",
- "IPV4_TCP_IP_OPTION",
- "IPV4_TCP_IP_FRAGMENT",
- "IPV4_TCP_SMALL_TTL",
- "IPV4_TCP_NEEDS_FRAGMENTATION",
- "IPV4_TCP_FLAGS",
- "IPV4_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
- "IPV4_TCP_SMALL_DATA_OFFS",
- "IPV4_TCP_BAD_SACK",
- "IPV4_TCP_BIG_DATA_OFFS",
- "IPV4_TCP_SEQ_BEFORE_LEFT_EDGE",
- "IPV4_TCP_ACK_EXCEEDS_RIGHT_EDGE",
- "IPV4_TCP_ACK_BEFORE_LEFT_EDGE",
- "IPV4_UDP_HEADER_INCOMPLETE",
- "IPV4_UDP_NO_ICME",
- "IPV4_UDP_IP_OPTION",
- "IPV4_UDP_IP_FRAGMENT",
- "IPV4_UDP_SMALL_TTL",
- "IPV4_UDP_NEEDS_FRAGMENTATION",
- "IPV4_WRONG_TARGET_MAC",
- "IPV4_HEADER_INCOMPLETE",
- "IPV4_BAD_TOTAL_LENGTH",
- "IPV4_BAD_CHECKSUM",
- "IPV4_NON_INITIAL_FRAGMENT",
- "IPV4_DATAGRAM_INCOMPLETE",
- "IPV4_OPTIONS_INCOMPLETE",
- "IPV4_UNKNOWN_PROTOCOL",
- "IPV4_ESP_HEADER_INCOMPLETE",
- "IPV4_ESP_NO_ICME",
- "IPV4_ESP_IP_OPTION",
- "IPV4_ESP_IP_FRAGMENT",
- "IPV4_ESP_SMALL_TTL",
- "IPV4_ESP_NEEDS_FRAGMENTATION",
- "IPV4_INGRESS_VID_MISMATCH",
- "IPV4_INGRESS_VID_MISSING",
- "IPV4_6RD_NO_ICME",
- "IPV4_6RD_IP_OPTION",
- "IPV4_6RD_IP_FRAGMENT",
- "IPV4_6RD_NEEDS_FRAGMENTATION",
- "IPV4_DSCP_MARKING_MISMATCH",
- "IPV4_VLAN_MARKING_MISMATCH",
- "IPV4_DEPRECATED",
- "IPV4_GRE_HEADER_INCOMPLETE",
- "IPV4_GRE_NO_ICME",
- "IPV4_GRE_IP_OPTION",
- "IPV4_GRE_IP_FRAGMENT",
- "IPV4_GRE_SMALL_TTL",
- "IPV4_GRE_NEEDS_FRAGMENTATION",
- "IPV4_PPTP_GRE_SESSION_MATCH_FAIL",
- "IPV4_PPTP_GRE_INVALID_PROTO",
- "IPV4_PPTP_GRE_NO_CME",
- "IPV4_PPTP_GRE_IP_OPTION",
- "IPV4_PPTP_GRE_IP_FRAGMENT",
- "IPV4_PPTP_GRE_SMALL_TTL",
- "IPV4_PPTP_GRE_NEEDS_FRAGMENTATION",
- "IPV4_DESTROY",
- "IPV4_FRAG_DF_SET",
- "IPV4_FRAG_FAIL",
- "IPV4_ICMP_IPV4_UDPLITE_HEADER_INCOMPLETE",
- "IPV4_UDPLITE_HEADER_INCOMPLETE",
- "IPV4_UDPLITE_NO_ICME",
- "IPV4_UDPLITE_IP_OPTION",
- "IPV4_UDPLITE_IP_FRAGMENT",
- "IPV4_UDPLITE_SMALL_TTL",
- "IPV4_UDPLITE_NEEDS_FRAGMENTATION",
- "IPV4_MC_UDP_NO_ICME",
- "IPV4_MC_MEM_ALLOC_FAILURE",
- "IPV4_MC_UPDATE_FAILURE",
- "IPV4_MC_PBUF_ALLOC_FAILURE"
-};
-
-/*
- * nss_stats_str_if_exception_ipv6
- * Interface stats strings for ipv6 exceptions
- */
-static int8_t *nss_stats_str_if_exception_ipv6[NSS_EXCEPTION_EVENT_IPV6_MAX] = {
- "IPV6_ICMP_HEADER_INCOMPLETE",
- "IPV6_ICMP_UNHANDLED_TYPE",
- "IPV6_ICMP_IPV6_HEADER_INCOMPLETE",
- "IPV6_ICMP_IPV6_UDP_HEADER_INCOMPLETE",
- "IPV6_ICMP_IPV6_TCP_HEADER_INCOMPLETE",
- "IPV6_ICMP_IPV6_UNKNOWN_PROTOCOL",
- "IPV6_ICMP_NO_ICME",
- "IPV6_ICMP_FLUSH_TO_HOST",
- "IPV6_TCP_HEADER_INCOMPLETE",
- "IPV6_TCP_NO_ICME",
- "IPV6_TCP_SMALL_HOP_LIMIT",
- "IPV6_TCP_NEEDS_FRAGMENTATION",
- "IPV6_TCP_FLAGS",
- "IPV6_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
- "IPV6_TCP_SMALL_DATA_OFFS",
- "IPV6_TCP_BAD_SACK",
- "IPV6_TCP_BIG_DATA_OFFS",
- "IPV6_TCP_SEQ_BEFORE_LEFT_EDGE",
- "IPV6_TCP_ACK_EXCEEDS_RIGHT_EDGE",
- "IPV6_TCP_ACK_BEFORE_LEFT_EDGE",
- "IPV6_UDP_HEADER_INCOMPLETE",
- "IPV6_UDP_NO_ICME",
- "IPV6_UDP_SMALL_HOP_LIMIT",
- "IPV6_UDP_NEEDS_FRAGMENTATION",
- "IPV6_WRONG_TARGET_MAC",
- "IPV6_HEADER_INCOMPLETE",
- "IPV6_UNKNOWN_PROTOCOL",
- "IPV6_INGRESS_VID_MISMATCH",
- "IPV6_INGRESS_VID_MISSING",
- "IPV6_DSCP_MARKING_MISMATCH",
- "IPV6_VLAN_MARKING_MISMATCH",
- "IPV6_DEPRECATED",
- "IPV6_GRE_NO_ICME",
- "IPV6_GRE_NEEDS_FRAGMENTATION",
- "IPV6_GRE_SMALL_HOP_LIMIT",
- "IPV6_DESTROY",
- "IPV6_ICMP_IPV6_UDPLITE_HEADER_INCOMPLETE",
- "IPV6_UDPLITE_HEADER_INCOMPLETE",
- "IPV6_UDPLITE_NO_ICME",
- "IPV6_UDPLITE_SMALL_HOP_LIMIT",
- "IPV6_UDPLITE_NEEDS_FRAGMENTATION",
- "IPV6_MC_UDP_NO_ICME",
- "IPV6_MC_MEM_ALLOC_FAILURE",
- "IPV6_MC_UPDATE_FAILURE",
- "IPV6_MC_PBUF_ALLOC_FAILURE",
- "IPV6_ESP_HEADER_INCOMPLETE",
- "IPV6_ESP_NO_ICME",
- "IPV6_ESP_IP_FRAGMENT",
- "IPV6_ESP_SMALL_HOP_LIMIT",
- "IPV6_ESP_NEEDS_FRAGMENTATION"
-};
-
-/*
- * nss_stats_str_if_exception_pppoe
- * Interface stats strings for PPPoE exceptions
- */
-static int8_t *nss_stats_str_if_exception_pppoe[NSS_PPPOE_EXCEPTION_EVENT_MAX] = {
- "PPPOE_WRONG_VERSION_OR_TYPE",
- "PPPOE_WRONG_CODE",
- "PPPOE_HEADER_INCOMPLETE",
- "PPPOE_UNSUPPORTED_PPP_PROTOCOL",
- "PPPOE_DEPRECATED"
-};
-
-/*
- * nss_stats_str_wifi
- * Wifi statistics strings
- */
-static int8_t *nss_stats_str_wifi[NSS_STATS_WIFI_MAX] = {
- "RX_PACKETS",
- "RX_QUEUE_0_DROPPED",
- "RX_QUEUE_1_DROPPED",
- "RX_QUEUE_2_DROPPED",
- "RX_QUEUE_3_DROPPED",
- "TX_PACKETS",
- "TX_DROPPED",
- "TX_TRANSMIT_COMPLETED",
- "TX_MGMT_RECEIVED",
- "TX_MGMT_TRANSMITTED",
- "TX_MGMT_DROPPED",
- "TX_MGMT_COMPLETED",
- "TX_INV_PEER_ENQ_CNT",
- "RX_INV_PEER_RCV_CNT",
- "RX_PN_CHECK_FAILED",
- "RX_PKTS_DELIVERD",
- "RX_BYTES_DELIVERED",
- "TX_BYTES_COMPLETED",
- "RX_DELIVER_UNALIGNED_DROP_CNT",
- "TIDQ_ENQUEUE_CNT_0",
- "TIDQ_ENQUEUE_CNT_1",
- "TIDQ_ENQUEUE_CNT_2",
- "TIDQ_ENQUEUE_CNT_3",
- "TIDQ_ENQUEUE_CNT_4",
- "TIDQ_ENQUEUE_CNT_5",
- "TIDQ_ENQUEUE_CNT_6",
- "TIDQ_ENQUEUE_CNT_7",
- "TIDQ_DEQUEUE_CNT_0",
- "TIDQ_DEQUEUE_CNT_1",
- "TIDQ_DEQUEUE_CNT_2",
- "TIDQ_DEQUEUE_CNT_3",
- "TIDQ_DEQUEUE_CNT_4",
- "TIDQ_DEQUEUE_CNT_5",
- "TIDQ_DEQUEUE_CNT_6",
- "TIDQ_DEQUEUE_CNT_7",
- "TIDQ_ENQUEUE_FAIL_CNT_0",
- "TIDQ_ENQUEUE_FAIL_CNT_1",
- "TIDQ_ENQUEUE_FAIL_CNT_2",
- "TIDQ_ENQUEUE_FAIL_CNT_3",
- "TIDQ_ENQUEUE_FAIL_CNT_4",
- "TIDQ_ENQUEUE_FAIL_CNT_5",
- "TIDQ_ENQUEUE_FAIL_CNT_6",
- "TIDQ_ENQUEUE_FAIL_CNT_7",
- "TIDQ_TTL_EXPIRE_CNT_0",
- "TIDQ_TTL_EXPIRE_CNT_1",
- "TIDQ_TTL_EXPIRE_CNT_2",
- "TIDQ_TTL_EXPIRE_CNT_3",
- "TIDQ_TTL_EXPIRE_CNT_4",
- "TIDQ_TTL_EXPIRE_CNT_5",
- "TIDQ_TTL_EXPIRE_CNT_6",
- "TIDQ_TTL_EXPIRE_CNT_7",
- "TIDQ_DEQUEUE_REQ_CNT_0",
- "TIDQ_DEQUEUE_REQ_CNT_1",
- "TIDQ_DEQUEUE_REQ_CNT_2",
- "TIDQ_DEQUEUE_REQ_CNT_3",
- "TIDQ_DEQUEUE_REQ_CNT_4",
- "TIDQ_DEQUEUE_REQ_CNT_5",
- "TIDQ_DEQUEUE_REQ_CNT_6",
- "TIDQ_DEQUEUE_REQ_CNT_7",
- "TOTAL_TIDQ_DEPTH",
- "RX_HTT_FETCH_CNT",
- "TOTAL_TIDQ_BYPASS_CNT",
- "GLOBAL_Q_FULL_CNT",
- "TIDQ_FULL_CNT",
-};
-
-/*
- * nss_stats_str_wifili
- * wifili txrx statistics
- */
-static int8_t *nss_stats_str_wifili_txrx[NSS_STATS_WIFILI_TXRX_MAX] = {
- "WIFILI_RX_MSDU_ERROR",
- "WIFILI_RX_INV_PEER_RCV",
- "WIFILI_RX_WDS_SRCPORT_EXCEPTION",
- "WIFILI_RX_WDS_SRCPORT_EXCEPTION_FAIL",
- "WIFILI_RX_DELIVERD",
- "WIFILI_RX_DELIVER_DROPPED",
- "WIFILI_RX_INTRA_BSS_UCAST",
- "WIFILI_RX_INTRA_BSS_UCAST_FAIL",
- "WIFILI_RX_INTRA_BSS_MCAST",
- "WIFILI_RX_INTRA_BSS_MCAST_FAIL",
- "WIFILI_RX_SG_RCV_SEND",
- "WIFILI_RX_SG_RCV_FAIL",
- "WIFILI_RX_MCAST_ECHO",
- "WIFILI_TX_ENQUEUE",
- "WIFILI_TX_ENQUEUE_DROP",
- "WIFILI_TX_DEQUEUE",
- "WIFILI_TX_HW_ENQUEUE_FAIL",
- "WIFILI_TX_SENT_COUNT",
-};
-
-/*
- * nss_stats_str_wifili_tcl
- * wifili tcl stats
- */
-static int8_t *nss_stats_str_wifili_tcl[NSS_STATS_WIFILI_TCL_MAX] = {
- "WIFILI_TCL_NO_HW_DESC",
- "WIFILI_TCL_RING_FULL",
- "WIFILI_TCL_RING_SENT",
-};
-
-/*
- * nss_stats_str_wifili_tx_comp
- * wifili tx comp stats
- */
-static int8_t *nss_stats_str_wifili_tx_comp[NSS_STATS_WIFILI_TX_DESC_FREE_MAX] = {
- "WIFILI_TX_DESC_FREE_INV_BUFSRC",
- "WIFILI_TX_DESC_FREE_INV_COOKIE",
- "WIFILI_TX_DESC_FREE_HW_RING_EMPTY",
- "WIFILI_TX_DESC_FREE_REAPED",
-};
-
-/*
- * nss_stats_str_wifili_reo
- * wifili tx reo stats
- */
-static int8_t *nss_stats_str_wifili_reo[NSS_STATS_WIFILI_REO_MAX] = {
- "WIFILI_REO_ERROR",
- "WIFILI_REO_REAPED",
- "WIFILI_REO_INV_COOKIE",
-};
-
-/*
- * nss_stats_str_wifili_txsw_pool
- * wifili tx desc stats
- */
-static int8_t *nss_stats_str_wifili_txsw_pool[NSS_STATS_WIFILI_TX_DESC_MAX] = {
- "WIFILI_TX_DESC_IN_USE",
- "WIFILI_TX_DESC_ALLOC_FAIL",
- "WIFILI_TX_DESC_ALREADY_ALLOCATED",
- "WIFILI_TX_DESC_INVALID_FREE",
- "WIFILI_TX_DESC_FREE_SRC_FW",
- "WIFILI_TX_DESC_FREE_COMPLETION",
- "WIFILI_TX_DESC_NO_PB",
-};
-
-/*
- * nss_stats_str_wifili_ext_txsw_pool
- * wifili tx ext desc stats
- */
-static uint8_t *nss_stats_str_wifili_ext_txsw_pool[NSS_STATS_WIFILI_EXT_TX_DESC_MAX] = {
- "WIFILI_EXT_TX_DESC_IN_USE",
- "WIFILI_EXT_TX_DESC_ALLOC_FAIL",
- "WIFILI_EXT_TX_DESC_ALREADY_ALLOCATED",
- "WIFILI_EXT_TX_DESC_INVALID_FREE",
-};
-
-/*
- * nss_stats_str_wifili_rxdma_pool
- * wifili rx desc stats
- */
-static int8_t *nss_stats_str_wifili_rxdma_pool[NSS_STATS_WIFILI_RX_DESC_MAX] = {
- "WIFILI_RX_DESC_NO_PB",
- "WIFILI_RX_DESC_ALLOC_FAIL",
- "WIFILI_RX_DESC_IN_USE",
-};
-
-/*
- * nss_stats_str_wifili_rxdma_ring
- * wifili rx dma ring stats
- */
-static int8_t *nss_stats_str_wifili_rxdma_ring[NSS_STATS_WIFILI_RXDMA_DESC_MAX] = {
- "WIFILI_RXDMA_HW_DESC_UNAVAILABLE",
- "WIFILI_RXDMA_BUF_REPLENISHED",
-};
-
-/*
- * nss_stats_str_wifili_wbm
- * wifili wbm ring stats
- */
-static int8_t *nss_stats_str_wifili_wbm[NSS_STATS_WIFILI_WBM_MAX] = {
- "WIFILI_WBM_SRC_DMA",
- "WIFILI_WBM_SRC_DMA_CODE_INV",
- "WIFILI_WBM_SRC_REO",
- "WIFILI_WBM_SRC_REO_CODE_NULLQ",
- "WIFILI_WBM_SRC_REO_CODE_INV",
- "WIFILI_WBM_SRC_INV",
-};
-
-/*
- * nss_stats_str_portid
- * PortID statistics strings
- */
-static int8_t *nss_stats_str_portid[NSS_STATS_PORTID_MAX] = {
- "RX_INVALID_HEADER",
-};
-
-/*
- * nss_stats_str_dtls_session_stats
- * DTLS statistics strings for nss session stats
- */
-static int8_t *nss_stats_str_dtls_session_debug_stats[NSS_STATS_DTLS_SESSION_MAX] = {
- "RX_PKTS",
- "TX_PKTS",
- "RX_QUEUE_0_DROPPED",
- "RX_QUEUE_1_DROPPED",
- "RX_QUEUE_2_DROPPED",
- "RX_QUEUE_3_DROPPED",
- "RX_AUTH_DONE",
- "TX_AUTH_DONE",
- "RX_CIPHER_DONE",
- "TX_CIPHER_DONE",
- "RX_CBUF_ALLOC_FAIL",
- "TX_CBUF_ALLOC_FAIL",
- "TX_CENQUEUE_FAIL",
- "RX_CENQUEUE_FAIL",
- "TX_DROPPED_HROOM",
- "TX_DROPPED_TROOM",
- "TX_FORWARD_ENQUEUE_FAIL",
- "RX_FORWARD_ENQUEUE_FAIL",
- "RX_INVALID_VERSION",
- "RX_INVALID_EPOCH",
- "RX_MALFORMED",
- "RX_CIPHER_FAIL",
- "RX_AUTH_FAIL",
- "RX_CAPWAP_CLASSIFY_FAIL",
- "RX_SINGLE_REC_DGRAM",
- "RX_MULTI_REC_DGRAM",
- "RX_REPLAY_FAIL",
- "RX_REPLAY_DUPLICATE",
- "RX_REPLAY_OUT_OF_WINDOW",
- "OUTFLOW_QUEUE_FULL",
- "DECAP_QUEUE_FULL",
- "PBUF_ALLOC_FAIL",
- "PBUF_COPY_FAIL",
- "EPOCH",
- "TX_SEQ_HIGH",
- "TX_SEQ_LOW",
-};
-
-/*
- * nss_stats_str_gre_tunnel_session_stats
- * GRE Tunnel statistics strings for nss session stats
- */
-static int8_t *nss_stats_str_gre_tunnel_session_debug_stats[NSS_STATS_GRE_TUNNEL_SESSION_MAX] = {
- "RX_PKTS",
- "TX_PKTS",
- "RX_QUEUE_0_DROPPED",
- "RX_QUEUE_1_DROPPED",
- "RX_QUEUE_2_DROPPED",
- "RX_QUEUE_3_DROPPED",
- "RX_MALFORMED",
- "RX_INVALID_PROT",
- "DECAP_QUEUE_FULL",
- "RX_SINGLE_REC_DGRAM",
- "RX_INVALID_REC_DGRAM",
- "BUFFER_ALLOC_FAIL",
- "BUFFER_COPY_FAIL",
- "OUTFLOW_QUEUE_FULL",
- "TX_DROPPED_HROOM",
- "RX_CBUFFER_ALLOC_FAIL",
- "RX_CENQUEUE_FAIL",
- "RX_DECRYPT_DONE",
- "RX_FORWARD_ENQUEUE_FAIL",
- "TX_CBUFFER_ALLOC_FAIL",
- "TX_CENQUEUE_FAIL",
- "TX_DROPPED_TROOM",
- "TX_FORWARD_ENQUEUE_FAIL",
- "TX_CIPHER_DONE",
- "CRYPTO_NOSUPP",
- "RX_DROPPED_MH_VERSION",
-};
-
-/*
- * nss_stats_str_l2tpv2_session_stats
- * l2tpv2 statistics strings for nss session stats
- */
-static int8_t *nss_stats_str_l2tpv2_session_debug_stats[NSS_STATS_L2TPV2_SESSION_MAX] = {
- "RX_PPP_LCP_PKTS",
- "RX_EXP_PKTS",
- "ENCAP_PBUF_ALLOC_FAIL",
- "DECAP_PBUF_ALLOC_FAIL"
-};
-
-/*
- * nss_stats_str_map_t_instance_stats
- * map_t statistics strings for nss session stats
- */
-static int8_t *nss_stats_str_map_t_instance_debug_stats[NSS_STATS_MAP_T_MAX] = {
- "MAP_T_V4_TO_V6_PBUF_EXCEPTION_PKTS",
- "MAP_T_V4_TO_V6_PBUF_NO_MATCHING_RULE",
- "MAP_T_V4_TO_V6_PBUF_NOT_TCP_OR_UDP",
- "MAP_T_V4_TO_V6_RULE_ERR_LOCAL_PSID",
- "MAP_T_V4_TO_V6_RULE_ERR_LOCAL_IPV6",
- "MAP_T_V4_TO_V6_RULE_ERR_REMOTE_PSID",
- "MAP_T_V4_TO_V6_RULE_ERR_REMOTE_EA_BITS",
- "MAP_T_V4_TO_V6_RULE_ERR_REMOTE_IPV6",
- "MAP_T_V6_TO_V4_PBUF_EXCEPTION_PKTS",
- "MAP_T_V6_TO_V4_PBUF_NO_MATCHING_RULE",
- "MAP_T_V6_TO_V4_PBUF_NOT_TCP_OR_UDP",
- "MAP_T_V6_TO_V4_RULE_ERR_LOCAL_IPV4",
- "MAP_T_V6_TO_V4_RULE_ERR_REMOTE_IPV4"
-};
-
- /*
- * nss_stats_str_gre_base_stats
- * GRE debug statistics strings for base types
- */
-static int8_t *nss_stats_str_gre_base_debug_stats[NSS_STATS_GRE_BASE_DEBUG_MAX] = {
- "GRE_BASE_RX_PACKETS",
- "GRE_BASE_RX_DROPPED",
- "GRE_BASE_EXP_ETH_HDR_MISSING",
- "GRE_BASE_EXP_ETH_TYPE_NON_IP",
- "GRE_BASE_EXP_IP_UNKNOWN_PROTOCOL",
- "GRE_BASE_EXP_IP_HEADER_INCOMPLETE",
- "GRE_BASE_EXP_IP_BAD_TOTAL_LENGTH",
- "GRE_BASE_EXP_IP_BAD_CHECKSUM",
- "GRE_BASE_EXP_IP_DATAGRAM_INCOMPLETE",
- "GRE_BASE_EXP_IP_FRAGMENT",
- "GRE_BASE_EXP_IP_OPTIONS_INCOMPLETE",
- "GRE_BASE_EXP_IP_WITH_OPTIONS",
- "GRE_BASE_EXP_IPV6_UNKNOWN_PROTOCOL",
- "GRE_BASE_EXP_IPV6_HEADER_INCOMPLETE",
- "GRE_BASE_EXP_GRE_UNKNOWN_SESSION",
- "GRE_BASE_EXP_GRE_NODE_INACTIVE",
-};
-
-/*
- * nss_stats_str_gre_session_stats
- * GRE debug statistics strings for sessions
- */
-static int8_t *nss_stats_str_gre_session_debug_stats[NSS_STATS_GRE_SESSION_DEBUG_MAX] = {
- "GRE_SESSION_PBUF_ALLOC_FAIL",
- "GRE_SESSION_DECAP_FORWARD_ENQUEUE_FAIL",
- "GRE_SESSION_ENCAP_FORWARD_ENQUEUE_FAIL",
- "GRE_SESSION_DECAP_TX_FORWARDED",
- "GRE_SESSION_ENCAP_RX_RECEIVED",
- "GRE_SESSION_ENCAP_RX_DROPPED",
- "GRE_SESSION_ENCAP_RX_LINEAR_FAIL",
- "GRE_SESSION_EXP_RX_KEY_ERROR",
- "GRE_SESSION_EXP_RX_SEQ_ERROR",
- "GRE_SESSION_EXP_RX_CS_ERROR",
- "GRE_SESSION_EXP_RX_FLAG_MISMATCH",
- "GRE_SESSION_EXP_RX_MALFORMED",
- "GRE_SESSION_EXP_RX_INVALID_PROTOCOL",
- "GRE_SESSION_EXP_RX_NO_HEADROOM",
-};
-
-/*
- * nss_stats_str_ppe_conn
- * PPE statistics strings for nss flow stats
- */
-static int8_t *nss_stats_str_ppe_conn[NSS_STATS_PPE_CONN_MAX] = {
- "v4 routed flows",
- "v4 bridge flows",
- "v4 conn create req",
- "v4 conn create fail",
- "v4 conn destroy req",
- "v4 conn destroy fail",
- "v4 conn MC create req",
- "v4 conn MC create fail",
- "v4 conn MC update req",
- "v4 conn MC update fail",
- "v4 conn MC delete req",
- "v4 conn MC delete fail",
-
- "v6 routed flows",
- "v6 bridge flows",
- "v6 conn create req",
- "v6 conn create fail",
- "v6 conn destroy req",
- "v6 conn destroy fail",
- "v6 conn MC create req",
- "v6 conn MC create fail",
- "v6 conn MC update req",
- "v6 conn MC update fail",
- "v6 conn MC delete req",
- "v6 conn MC delete fail",
-
- "conn fail - vp full",
- "conn fail - nexthop full",
- "conn fail - flow full",
- "conn fail - host full",
- "conn fail - pub-ip full",
- "conn fail - port not setup",
- "conn fail - rw fifo full",
- "conn fail - flow cmd failure",
- "conn fail - unknown proto",
- "conn fail - ppe not responding",
- "conn fail - CE opaque invalid",
- "conn fail - fqg full"
-};
-
-/*
- * nss_stats_str_ppe_l3
- * PPE statistics strings for nss debug stats
- */
-static int8_t *nss_stats_str_ppe_l3[NSS_STATS_PPE_L3_MAX] = {
- "PPE L3 dbg reg 0",
- "PPE L3 dbg reg 1",
- "PPE L3 dbg reg 2",
- "PPE L3 dbg reg 3",
- "PPE L3 dbg reg 4",
- "PPE L3 dbg reg port",
-};
-
-/*
- * nss_stats_str_ppe_code
- * PPE statistics strings for nss debug stats
- */
-static int8_t *nss_stats_str_ppe_code[NSS_STATS_PPE_CODE_MAX] = {
- "PPE CPU_CODE",
- "PPE DROP_CODE",
-};
-
-/*
- * nss_stats_str_ppe_dc
- * PPE statistics strings for drop code
- */
-static int8_t *nss_stats_str_ppe_dc[NSS_STATS_PPE_DROP_CODE_MAX] = {
- "PPE_DROP_CODE_NONE",
- "PPE_DROP_CODE_EXP_UNKNOWN_L2_PORT",
- "PPE_DROP_CODE_EXP_PPPOE_WRONG_VER_TYPE",
- "PPE_DROP_CODE_EXP_PPPOE_WRONG_CODE",
- "PPE_DROP_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT",
- "PPE_DROP_CODE_EXP_IPV4_WRONG_VER",
- "PPE_DROP_CODE_EXP_IPV4_SMALL_IHL",
- "PPE_DROP_CODE_EXP_IPV4_WITH_OPTION",
- "PPE_DROP_CODE_EXP_IPV4_HDR_INCOMPLETE",
- "PPE_DROP_CODE_EXP_IPV4_BAD_TOTAL_LEN",
- "PPE_DROP_CODE_EXP_IPV4_DATA_INCOMPLETE",
- "PPE_DROP_CODE_EXP_IPV4_FRAG",
- "PPE_DROP_CODE_EXP_IPV4_PING_OF_DEATH",
- "PPE_DROP_CODE_EXP_IPV4_SNALL_TTL",
- "PPE_DROP_CODE_EXP_IPV4_UNK_IP_PROT",
- "PPE_DROP_CODE_EXP_IPV4_CHECKSUM_ERR",
- "PPE_DROP_CODE_EXP_IPV4_INV_SIP",
- "PPE_DROP_CODE_EXP_IPV4_INV_DIP",
- "PPE_DROP_CODE_EXP_IPV4_LAND_ATTACK",
- "PPE_DROP_CODE_EXP_IPV4_AH_HDR_INCOMPLETE",
- "PPE_DROP_CODE_EXP_IPV4_AH_HDR_CROSS_BORDER",
- "PPE_DROP_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE",
- "PPE_DROP_CODE_EXP_IPV6_WRONG_VER",
- "PPE_DROP_CODE_EXP_IPV6_HDR_INCOMPLETE",
- "PPE_DROP_CODE_EXP_IPV6_BAD_PAYLOAD_LEN",
- "PPE_DROP_CODE_EXP_IPV6_DATA_INCOMPLETE",
- "PPE_DROP_CODE_EXP_IPV6_WITH_EXT_HDR",
- "PPE_DROP_CODE_EXP_IPV6_SMALL_HOP_LIMIT",
- "PPE_DROP_CODE_EXP_IPV6_INV_SIP",
- "PPE_DROP_CODE_EXP_IPV6_INV_DIP",
- "PPE_DROP_CODE_EXP_IPV6_LAND_ATTACK",
- "PPE_DROP_CODE_EXP_IPV6_FRAG",
- "PPE_DROP_CODE_EXP_IPV6_PING_OF_DEATH",
- "PPE_DROP_CODE_EXP_IPV6_WITH_MORE_EXT_HDR",
- "PPE_DROP_CODE_EXP_IPV6_UNK_LAST_NEXT_HDR",
- "PPE_DROP_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE",
- "PPE_DROP_CODE_EXP_IPV6_MOBILITY_HDR_CROSS_BORDER",
- "PPE_DROP_CODE_EXP_IPV6_AH_HDR_INCOMPLETE",
- "PPE_DROP_CODE_EXP_IPV6_AH_HDR_CROSS_BORDER",
- "PPE_DROP_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE",
- "PPE_DROP_CODE_EXP_IPV6_ESP_HDR_CROSS_BORDER",
- "PPE_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_INCOMPLETE",
- "PPE_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_CROSS_BORDER",
- "PPE_DROP_CODE_EXP_TCP_HDR_INCOMPLETE",
- "PPE_DROP_CODE_EXP_TCP_HDR_CROSS_BORDER",
- "PPE_DROP_CODE_EXP_TCP_SMAE_SP_DP",
- "PPE_DROP_CODE_EXP_TCP_SMALL_DATA_OFFSET",
- "PPE_DROP_CODE_EXP_TCP_FLAGS_0",
- "PPE_DROP_CODE_EXP_TCP_FLAGS_1",
- "PPE_DROP_CODE_EXP_TCP_FLAGS_2",
- "PPE_DROP_CODE_EXP_TCP_FLAGS_3",
- "PPE_DROP_CODE_EXP_TCP_FLAGS_4",
- "PPE_DROP_CODE_EXP_TCP_FLAGS_5",
- "PPE_DROP_CODE_EXP_TCP_FLAGS_6",
- "PPE_DROP_CODE_EXP_TCP_FLAGS_7",
- "PPE_DROP_CODE_EXP_TCP_CHECKSUM_ERR",
- "PPE_DROP_CODE_EXP_UDP_HDR_INCOMPLETE",
- "PPE_DROP_CODE_EXP_UDP_HDR_CROSS_BORDER",
- "PPE_DROP_CODE_EXP_UDP_SMAE_SP_DP",
- "PPE_DROP_CODE_EXP_UDP_BAD_LEN",
- "PPE_DROP_CODE_EXP_UDP_DATA_INCOMPLETE",
- "PPE_DROP_CODE_EXP_UDP_CHECKSUM_ERR",
- "PPE_DROP_CODE_EXP_UDP_LITE_HDR_INCOMPLETE",
- "PPE_DROP_CODE_EXP_UDP_LITE_HDR_CROSS_BORDER",
- "PPE_DROP_CODE_EXP_UDP_LITE_SMAE_SP_DP",
- "PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_1_TO_7",
- "PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_TOO_LONG",
- "PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_CROSS_BORDER",
- "PPE_DROP_CODE_EXP_UDP_LITE_CHECKSUM_ERR",
- "PPE_DROP_CODE_L3_MC_BRIDGE_ACTION",
- "PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION",
- "PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR",
- "PPE_DROP_CODE_L3_ROUTE_ACTION",
- "PPE_DROP_CODE_L3_NO_ROUTE_ACTION",
- "PPE_DROP_CODE_L3_NO_ROUTE_NH_INVALID_ACTION",
- "PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_ACTION",
- "PPE_DROP_CODE_L3_BRIDGE_ACTION",
- "PPE_DROP_CODE_L3_FLOW_ACTION",
- "PPE_DROP_CODE_L3_FLOW_MISS_ACTION",
- "PPE_DROP_CODE_L2_EXP_MRU_FAIL",
- "PPE_DROP_CODE_L2_EXP_MTU_FAIL",
- "PPE_DROP_CODE_L3_EXP_IP_PREFIX_BC",
- "PPE_DROP_CODE_L3_EXP_MTU_FAIL",
- "PPE_DROP_CODE_L3_EXP_MRU_FAIL",
- "PPE_DROP_CODE_L3_EXP_ICMP_RDT",
- "PPE_DROP_CODE_FAKE_MAC_HEADER_ERR",
- "PPE_DROP_CODE_L3_EXP_IP_RT_TTL_ZERO",
- "PPE_DROP_CODE_L3_FLOW_SERVICE_CODE_LOOP",
- "PPE_DROP_CODE_L3_FLOW_DE_ACCELEARTE",
- "PPE_DROP_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL",
- "PPE_DROP_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH",
- "PPE_DROP_CODE_L3_EXP_MTU_DF_FAIL",
- "PPE_DROP_CODE_L3_EXP_PPPOE_MULTICAST",
- "PPE_DROP_CODE_IPV4_SG_UNKNOWN",
- "PPE_DROP_CODE_IPV6_SG_UNKNOWN",
- "PPE_DROP_CODE_ARP_SG_UNKNOWN",
- "PPE_DROP_CODE_ND_SG_UNKNOWN",
- "PPE_DROP_CODE_IPV4_SG_VIO",
- "PPE_DROP_CODE_IPV6_SG_VIO",
- "PPE_DROP_CODE_ARP_SG_VIO",
- "PPE_DROP_CODE_ND_SG_VIO",
- "PPE_DROP_CODE_L2_NEW_MAC_ADDRESS",
- "PPE_DROP_CODE_L2_HASH_COLLISION",
- "PPE_DROP_CODE_L2_STATION_MOVE",
- "PPE_DROP_CODE_L2_LEARN_LIMIT",
- "PPE_DROP_CODE_L2_SA_LOOKUP_ACTION",
- "PPE_DROP_CODE_L2_DA_LOOKUP_ACTION",
- "PPE_DROP_CODE_APP_CTRL_ACTION",
- "PPE_DROP_CODE_IN_VLAN_FILTER_ACTION",
- "PPE_DROP_CODE_IN_VLAN_XLT_MISS",
- "PPE_DROP_CODE_EG_VLAN_FILTER_DROP",
- "PPE_DROP_CODE_ACL_PRE_ACTION",
- "PPE_DROP_CODE_ACL_POST_ACTION",
- "PPE_DROP_CODE_MC_BC_SA",
- "PPE_DROP_CODE_NO_DESTINATION",
- "PPE_DROP_CODE_STG_IN_FILTER",
- "PPE_DROP_CODE_STG_EG_FILTER",
- "PPE_DROP_CODE_SOURCE_FILTER_FAIL",
- "PPE_DROP_CODE_TRUNK_SEL_FAIL",
- "PPE_DROP_CODE_TX_EN_FAIL",
- "PPE_DROP_CODE_VLAN_TAG_FMT",
- "PPE_DROP_CODE_CRC_ERR",
- "PPE_DROP_CODE_PAUSE_FRAME",
- "PPE_DROP_CODE_PROMISC",
- "PPE_DROP_CODE_ISOLATION",
- "PPE_DROP_CODE_MGMT_APP",
- "PPE_DROP_CODE_FAKE_L2_PROT_ERR",
- "PPE_DROP_CODE_POLICER",
-};
-
-/*
- * nss_stats_str_ppe_cc
- * PPE statistics strings for cpu code
- */
-static int8_t *nss_stats_str_ppe_cc[NSS_STATS_PPE_CPU_CODE_MAX] = {
- "PPE_CPU_CODE_FORWARDING",
- "PPE_CPU_CODE_EXP_UNKNOWN_L2_PROT",
- "PPE_CPU_CODE_EXP_PPPOE_WRONG_VER_TYPE",
- "PPE_CPU_CODE_EXP_WRONG_CODE",
- "PPE_CPU_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT",
- "PPE_CPU_CODE_EXP_WRONG_VER",
- "PPE_CPU_CODE_EXP_SMALL_IHL",
- "PPE_CPU_CODE_EXP_WITH_OPTION",
- "PPE_CPU_CODE_EXP_HDR_INCOMPLETE",
- "PPE_CPU_CODE_EXP_IPV4_BAD_TOTAL_LEN",
- "PPE_CPU_CODE_EXP_DATA_INCOMPLETE",
- "PPE_CPU_CODE_IPV4_FRAG",
- "PPE_CPU_CODE_EXP_IPV4_PING_OF_DEATH",
- "PPE_CPU_CODE_EXP_SNALL_TTL",
- "PPE_CPU_CODE_EXP_IPV4_UNK_IP_PROT",
- "PPE_CPU_CODE_EXP_CHECKSUM_ERR",
- "PPE_CPU_CODE_EXP_INV_SIP",
- "PPE_CPU_CODE_EXP_INV_DIP",
- "PPE_CPU_CODE_EXP_LAND_ATTACK",
- "PPE_CPU_CODE_EXP_IPV4_AH_HDR_INCOMPLETE",
- "PPE_CPU_CODE_EXP_IPV4_AH_CROSS_BORDER",
- "PPE_CPU_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE",
- "PPE_CPU_CODE_EXP_WRONG_VER",
- "PPE_CPU_CODE_EXP_HDR_INCOMPLETE",
- "PPE_CPU_CODE_EXP_IPV6_BAD_PAYLOAD_LEN",
- "PPE_CPU_CODE_EXP_DATA_INCOMPLETE",
- "PPE_CPU_CODE_EXP_IPV6_WITH_EXT_HDR",
- "PPE_CPU_CODE_EXP_IPV6_SMALL_HOP_LIMIT",
- "PPE_CPU_CODE_EXP_INV_SIP",
- "PPE_CPU_CODE_EXP_INV_DIP",
- "PPE_CPU_CODE_EXP_LAND_ATTACK",
- "PPE_CPU_CODE_IPV6_FRAG",
- "PPE_CPU_CODE_EXP_IPV6_PING_OF_DEATH",
- "PPE_CPU_CODE_EXP_IPV6_WITH_EXT_HDR",
- "PPE_CPU_CODE_EXP_IPV6_UNK_NEXT_HDR",
- "PPE_CPU_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE",
- "PPE_CPU_CODE_EXP_IPV6_MOBILITY_CROSS_BORDER",
- "PPE_CPU_CODE_EXP_IPV6_AH_HDR_INCOMPLETE",
- "PPE_CPU_CODE_EXP_IPV6_AH_CROSS_BORDER",
- "PPE_CPU_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE",
- "PPE_CPU_CODE_EXP_IPV6_ESP_CROSS_BORDER",
- "PPE_CPU_CODE_EXP_IPV6_OTHER_HDR_INCOMPLETE",
- "PPE_CPU_CODE_EXP_IPV6_OTHER_EXT_CROSS_BORDER",
- "PPE_CPU_CODE_EXP_HDR_INCOMPLETE",
- "PPE_CPU_CODE_EXP_TCP_HDR_CROSS_BORDER",
- "PPE_CPU_CODE_EXP_TCP_SMAE_SP_DP",
- "PPE_CPU_CODE_EXP_TCP_SMALL_DATA_OFFSET",
- "PPE_CPU_CODE_EXP_FLAGS_0",
- "PPE_CPU_CODE_EXP_FLAGS_1",
- "PPE_CPU_CODE_EXP_FLAGS_2",
- "PPE_CPU_CODE_EXP_FLAGS_3",
- "PPE_CPU_CODE_EXP_FLAGS_4",
- "PPE_CPU_CODE_EXP_FLAGS_5",
- "PPE_CPU_CODE_EXP_FLAGS_6",
- "PPE_CPU_CODE_EXP_FLAGS_7",
- "PPE_CPU_CODE_EXP_CHECKSUM_ERR",
- "PPE_CPU_CODE_EXP_HDR_INCOMPLETE",
- "PPE_CPU_CODE_EXP_UDP_HDR_CROSS_BORDER",
- "PPE_CPU_CODE_EXP_UDP_SMAE_SP_DP",
- "PPE_CPU_CODE_EXP_BAD_LEN",
- "PPE_CPU_CODE_EXP_DATA_INCOMPLETE",
- "PPE_CPU_CODE_EXP_CHECKSUM_ERR",
- "PPE_CPU_CODE_EXP_UDP_LITE_HDR_INCOMPLETE",
- "PPE_CPU_CODE_EXP_UDP_LITE_CROSS_BORDER",
- "PPE_CPU_CODE_EXP_UDP_LITE_SP_DP",
- "PPE_CPU_CODE_EXP_UDP_LITE_CSM_COV_TO_7",
- "PPE_CPU_CODE_EXP_UDP_LITE_CSM_TOO_LONG",
- "PPE_CPU_CODE_EXP_UDP_LITE_CSM_CROSS_BORDER",
- "PPE_CPU_CODE_EXP_UDP_LITE_CHECKSUM_ERR",
- "PPE_CPU_CODE_EXP_FAKE_L2_PROT_ERR",
- "PPE_CPU_CODE_EXP_FAKE_MAC_HEADER_ERR",
- "PPE_CPU_CODE_BITMAP_MAX",
- "PPE_CPU_CODE_L2_MRU_FAIL",
- "PPE_CPU_CODE_L2_MTU_FAIL",
- "PPE_CPU_CODE_L3_EXP_IP_PREFIX_BC",
- "PPE_CPU_CODE_L3_MTU_FAIL",
- "PPE_CPU_CODE_L3_MRU_FAIL",
- "PPE_CPU_CODE_L3_ICMP_RDT",
- "PPE_CPU_CODE_L3_EXP_IP_RT_TO_ME",
- "PPE_CPU_CODE_L3_EXP_IP_TTL_ZERO",
- "PPE_CPU_CODE_L3_FLOW_SERVICE_CODE_LOOP",
- "PPE_CPU_CODE_L3_DE_ACCELERATE",
- "PPE_CPU_CODE_L3_EXP_FLOW_SRC_CHK_FAIL",
- "PPE_CPU_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH",
- "PPE_CPU_CODE_L3_EXP_MTU_DF_FAIL",
- "PPE_CPU_CODE_L3_PPPOE_MULTICAST",
- "PPE_CPU_CODE_MGMT_OFFSET",
- "PPE_CPU_CODE_MGMT_EAPOL",
- "PPE_CPU_CODE_PPPOE_DIS",
- "PPE_CPU_CODE_MGMT_IGMP",
- "PPE_CPU_CODE_ARP_REQ",
- "PPE_CPU_CODE_ARP_REP",
- "PPE_CPU_CODE_MGMT_DHCPv4",
- "PPE_CPU_CODE_MGMT_MLD",
- "PPE_CPU_CODE_MGMT_NS",
- "PPE_CPU_CODE_MGMT_NA",
- "PPE_CPU_CODE_MGMT_DHCPv6",
- "PPE_CPU_CODE_PTP_OFFSET",
- "PPE_CPU_CODE_PTP_SYNC",
- "PPE_CPU_CODE_FOLLOW_UP",
- "PPE_CPU_CODE_DELAY_REQ",
- "PPE_CPU_CODE_DELAY_RESP",
- "PPE_CPU_CODE_PDELAY_REQ",
- "PPE_CPU_CODE_PDELAY_RESP",
- "PPE_CPU_CODE_PTP_PDELAY_RESP_FOLLOW_UP",
- "PPE_CPU_CODE_PTP_ANNOUNCE",
- "PPE_CPU_CODE_PTP_MANAGEMENT",
- "PPE_CPU_CODE_PTP_SIGNALING",
- "PPE_CPU_CODE_PTP_RSV_MSG",
- "PPE_CPU_CODE_SG_UNKNOWN",
- "PPE_CPU_CODE_SG_UNKNOWN",
- "PPE_CPU_CODE_SG_UNKNOWN",
- "PPE_CPU_CODE_SG_UNKNOWN",
- "PPE_CPU_CODE_SG_VIO",
- "PPE_CPU_CODE_SG_VIO",
- "PPE_CPU_CODE_SG_VIO",
- "PPE_CPU_CODE_SG_VIO",
- "PPE_CPU_CODE_L3_ROUTING_IP_TO_ME",
- "PPE_CPU_CODE_L3_SNAT_ACTION",
- "PPE_CPU_CODE_L3_DNAT_ACTION",
- "PPE_CPU_CODE_L3_RT_ACTION",
- "PPE_CPU_CODE_L3_BR_ACTION",
- "PPE_CPU_CODE_L3_BRIDGE_ACTION",
- "PPE_CPU_CODE_L3_ROUTE_PREHEAD_RT_ACTION",
- "PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAPT_ACTION",
- "PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAPT_ACTION",
- "PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAT_ACTION",
- "PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAT_ACTION",
- "PPE_CPU_CODE_L3_NO_ROUTE_NAT_ACTION",
- "PPE_CPU_CODE_L3_NO_ROUTE_NAT_ERROR",
- "PPE_CPU_CODE_ROUTE_ACTION",
- "PPE_CPU_CODE_L3_ROUTE_ACTION",
- "PPE_CPU_CODE_L3_NO_ROUTE_INVALID_ACTION",
- "PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_ACTION",
- "PPE_CPU_CODE_BRIDGE_ACTION",
- "PPE_CPU_CODE_FLOW_ACTION",
- "PPE_CPU_CODE_L3_MISS_ACTION",
- "PPE_CPU_CODE_L2_MAC_ADDRESS",
- "PPE_CPU_CODE_HASH_COLLISION",
- "PPE_CPU_CODE_STATION_MOVE",
- "PPE_CPU_CODE_LEARN_LIMIT",
- "PPE_CPU_CODE_L2_LOOKUP_ACTION",
- "PPE_CPU_CODE_L2_LOOKUP_ACTION",
- "PPE_CPU_CODE_CTRL_ACTION",
- "PPE_CPU_CODE_IN_FILTER_ACTION",
- "PPE_CPU_CODE_IN_XLT_MISS",
- "PPE_CPU_CODE_EG_FILTER_DROP",
- "PPE_CPU_CODE_PRE_ACTION",
- "PPE_CPU_CODE_POST_ACTION",
- "PPE_CPU_CODE_CODE_ACTION",
-};
-
-/*
- * nss_stats_str_ppt_session_stats
- * PPTP statistics strings for nss session stats
- */
-static int8_t *nss_stats_str_pptp_session_debug_stats[NSS_STATS_PPTP_SESSION_MAX] = {
- "ENCAP_RX_PACKETS",
- "ENCAP_RX_BYTES",
- "ENCAP_TX_PACKETS",
- "ENCAP_TX_BYTES",
- "ENCAP_RX_QUEUE_0_DROP",
- "ENCAP_RX_QUEUE_1_DROP",
- "ENCAP_RX_QUEUE_2_DROP",
- "ENCAP_RX_QUEUE_3_DROP",
- "DECAP_RX_PACKETS",
- "DECAP_RX_BYTES",
- "DECAP_TX_PACKETS",
- "DECAP_TX_BYTES",
- "DECAP_RX_QUEUE_0_DROP",
- "DECAP_RX_QUEUE_1_DROP",
- "DECAP_RX_QUEUE_2_DROP",
- "DECAP_RX_QUEUE_3_DROP",
- "ENCAP_HEADROOM_ERR",
- "ENCAP_SMALL_SIZE",
- "ENCAP_PNODE_ENQUEUE_FAIL",
- "DECAP_NO_SEQ_NOR_ACK",
- "DECAP_INVAL_GRE_FLAGS",
- "DECAP_INVAL_GRE_PROTO",
- "DECAP_WRONG_SEQ",
- "DECAP_INVAL_PPP_HDR",
- "DECAP_PPP_LCP",
- "DECAP_UNSUPPORTED_PPP_PROTO",
- "DECAP_PNODE_ENQUEUE_FAIL",
-};
-
-/*
- * nss_stats_str_trustsec_tx
- * Trustsec TX stats strings
- */
-static int8_t *nss_stats_str_trustsec_tx[NSS_STATS_TRUSTSEC_TX_MAX] = {
- "INVALID_SRC",
- "UNCONFIGURED_SRC",
- "HEADROOM_NOT_ENOUGH",
-};
-
-/*
- * nss_stats_ipv4_read()
- * Read IPV4 stats
- */
-static ssize_t nss_stats_ipv4_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+void nss_stats_create_dentry(char *name, const struct file_operations *ops)
{
- int32_t i;
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_IPV4_MAX + 3) + (NSS_EXCEPTION_EVENT_IPV4_MAX + 3) + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
+ if (!debugfs_create_file(name, 0400, nss_top_main.stats_dentry, &nss_top_main, ops)) {
+ nss_warning("Faied to create debug entry for subsystem %s\n", name);
}
+}
- /*
- * Note: The assumption here is that exception event count is larger than other statistics count for IPv4
- */
- stats_shadow = kzalloc(NSS_EXCEPTION_EVENT_IPV4_MAX * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
+/*
+ * nss_stats_fill_common_stats()
+ * Fill common node statistics.
+ */
+size_t nss_stats_fill_common_stats(uint32_t if_num, char *lbuf, size_t size_wr, size_t size_al)
+{
+ uint64_t stats_shadow[NSS_STATS_NODE_MAX];
+ int i;
- size_wr = scnprintf(lbuf, size_al, "ipv4 stats start:\n\n");
-
- /*
- * Common node stats
- */
size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
spin_lock_bh(&nss_top_main.stats_lock);
for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_node[NSS_IPV4_RX_INTERFACE][i];
+ stats_shadow[i] = nss_top_main.stats_node[if_num][i];
}
-
spin_unlock_bh(&nss_top_main.stats_lock);
for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
@@ -1276,988 +114,14 @@
"%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
}
- /*
- * IPv4 node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 node stats:\n\n");
-
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_IPV4_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_ipv4[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_IPV4_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_ipv4[i], stats_shadow[i]);
- }
-
- /*
- * Exception stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 exception stats:\n\n");
-
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV4_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_if_exception_ipv4[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV4_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_if_exception_ipv4[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
+ return size_wr;
}
/*
- * nss_stats_ipv4_reasm_read()
- * Read IPV4 reassembly stats
- */
-static ssize_t nss_stats_ipv4_reasm_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_IPV4_REASM_MAX + 3) + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- stats_shadow = kzalloc(NSS_STATS_IPV4_REASM_MAX * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "ipv4 reasm stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_node[NSS_IPV4_REASM_INTERFACE][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
- }
-
- /*
- * IPv4 reasm node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 reasm node stats:\n\n");
-
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_IPV4_REASM_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_ipv4_reasm[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_IPV4_REASM_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_ipv4_reasm[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 reasm stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_ipv6_read()
- * Read IPV6 stats
- */
-static ssize_t nss_stats_ipv6_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_IPV6_MAX + 3) + (NSS_EXCEPTION_EVENT_IPV6_MAX + 3) + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- /*
- * Note: The assumption here is that exception event count is larger than other statistics count for IPv4
- */
- stats_shadow = kzalloc(NSS_EXCEPTION_EVENT_IPV6_MAX * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "ipv6 stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_node[NSS_IPV6_RX_INTERFACE][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
- }
-
- /*
- * IPv6 node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 node stats:\n\n");
-
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_IPV6_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_ipv6[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_IPV6_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_ipv6[i], stats_shadow[i]);
- }
-
- /*
- * Exception stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 exception stats:\n\n");
-
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV6_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_if_exception_ipv6[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV6_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_if_exception_ipv6[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_ipv6_reasm_read()
- * Read IPV6 reassembly stats
- */
-static ssize_t nss_stats_ipv6_reasm_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_IPV6_REASM_MAX + 3) + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- stats_shadow = kzalloc(NSS_STATS_IPV6_REASM_MAX * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "ipv6 reasm stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_node[NSS_IPV6_REASM_INTERFACE][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
- }
-
- /*
- * Ipv6 reasm node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 reasm node stats:\n\n");
-
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_IPV6_REASM_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_ipv6_reasm[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_IPV6_REASM_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_ipv6_reasm[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 reasm stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_edma_port_stats_read()
- * Read EDMA port stats
- */
-static ssize_t nss_stats_edma_port_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + 3;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
- struct nss_stats_data *data = fp->private_data;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- /*
- * Note: The assumption here is that we do not have more than 64 stats
- */
- stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "edma stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "edma port %d stats:\n\n", data->edma_id);
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_edma.port[data->edma_id].port_stats[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_edma_err_stats_read()
- * Read EDMA err stats
- */
-static ssize_t nss_stats_edma_err_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_EDMA_ERR_STATS_MAX + 2) + 3;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- /*
- * Note: The assumption here is that we do not have more than 64 stats
- */
- stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "edma error stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "edma error stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_EDMA_ERR_STATS_MAX); i++)
- stats_shadow[i] = nss_top_main.stats_edma.misc_err[i];
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_EDMA_ERR_STATS_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_edma_err_map[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma error stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_edma_port_type_read()
- * Read EDMA port type
- */
-static ssize_t nss_stats_edma_port_type_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (1 + 2) + 3;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t port_type;
- struct nss_stats_data *data = fp->private_data;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "edma port type start:\n\n");
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "edma port %d type:\n\n", data->edma_id);
-
- /*
- * Port type
- */
- spin_lock_bh(&nss_top_main.stats_lock);
- port_type = nss_top_main.stats_edma.port[data->edma_id].port_type;
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "port_type = %s\n", nss_stats_str_edma_port_type[port_type]);
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma stats end\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_edma_port_ring_map_read()
- * Read EDMA port ring map
- */
-static ssize_t nss_stats_edma_port_ring_map_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (4 + 2) + 3;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
- struct nss_stats_data *data = fp->private_data;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- /*
- * Note: The assumption here is that we do not have more than 64 stats
- */
- stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "edma port ring map start:\n\n");
-
- /*
- * Port ring map
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "edma port %d ring map:\n\n", data->edma_id);
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; i < NSS_EDMA_PORT_RING_MAP_MAX; i++) {
- stats_shadow[i] = nss_top_main.stats_edma.port[data->edma_id].port_ring_map[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; i < NSS_EDMA_PORT_RING_MAP_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_edma_port_ring_map[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_edma_txring_read()
- * Read EDMA Tx ring stats
- */
-static ssize_t nss_stats_edma_txring_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_EDMA_TX_MAX + 2) + 3;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
- struct nss_stats_data *data = fp->private_data;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- /*
- * Note: The assumption here is that we do not have more than 64 stats
- */
- stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "edma Tx ring stats start:\n\n");
-
- /*
- * Tx ring stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Tx ring %d stats:\n\n", data->edma_id);
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; i < NSS_STATS_EDMA_TX_MAX; i++) {
- stats_shadow[i] = nss_top_main.stats_edma.tx_stats[data->edma_id][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; i < NSS_STATS_EDMA_TX_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_edma_tx[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma Tx ring stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_edma_rxring_read()
- * Read EDMA rxring stats
- */
-static ssize_t nss_stats_edma_rxring_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_EDMA_RX_MAX + 2) + 3;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
- struct nss_stats_data *data = fp->private_data;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- /*
- * Note: The assumption here is that we do not have more than 64 stats
- */
- stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "edma Rx ring stats start:\n\n");
-
- /*
- * RX ring stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Rx ring %d stats:\n\n", data->edma_id);
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; i < NSS_STATS_EDMA_RX_MAX; i++) {
- stats_shadow[i] = nss_top_main.stats_edma.rx_stats[data->edma_id][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; i < NSS_STATS_EDMA_RX_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_edma_rx[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma Rx ring stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_edma_txcmplring_read()
- * Read EDMA txcmplring stats
- */
-static ssize_t nss_stats_edma_txcmplring_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_EDMA_TXCMPL_MAX + 2) + 3;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
- struct nss_stats_data *data = fp->private_data;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- /*
- * Note: The assumption here is that we do not have more than 64 stats
- */
- stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "edma Tx cmpl ring stats start:\n\n");
-
- /*
- * Tx cmpl ring stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Tx cmpl ring %d stats:\n\n", data->edma_id);
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; i < NSS_STATS_EDMA_TXCMPL_MAX; i++) {
- stats_shadow[i] = nss_top_main.stats_edma.txcmpl_stats[data->edma_id][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; i < NSS_STATS_EDMA_TXCMPL_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_edma_txcmpl[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma Tx cmpl ring stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_edma_rxfillring_read()
- * Read EDMA rxfillring stats
- */
-static ssize_t nss_stats_edma_rxfillring_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_EDMA_RXFILL_MAX + 2) + 3;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
- struct nss_stats_data *data = fp->private_data;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- /*
- * Note: The assumption here is that we do not have more than 64 stats
- */
- stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "edma Rx fill ring stats start:\n\n");
-
- /*
- * Rx fill ring stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Rx fill ring %d stats:\n\n", data->edma_id);
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; i < NSS_STATS_EDMA_RXFILL_MAX; i++) {
- stats_shadow[i] = nss_top_main.stats_edma.rxfill_stats[data->edma_id][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; i < NSS_STATS_EDMA_RXFILL_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_edma_rxfill[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma Rx fill ring stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_eth_rx_read()
- * Read ETH_RX stats
- */
-static ssize_t nss_stats_eth_rx_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_ETH_RX_MAX + 3) + (NSS_EXCEPTION_EVENT_ETH_RX_MAX + 3) + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- /*
- * Note: The assumption here is that we do not have more than 64 stats
- */
- stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "eth_rx stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_node[NSS_ETH_RX_INTERFACE][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
- }
-
- /*
- * eth_rx node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_ETH_RX_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_eth_rx[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_ETH_RX_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_eth_rx[i], stats_shadow[i]);
- }
-
- /*
- * Exception stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx exception stats:\n\n");
-
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_EXCEPTION_EVENT_ETH_RX_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_if_exception_eth_rx[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_EXCEPTION_EVENT_ETH_RX_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_if_exception_eth_rx[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_n2h_read()
- * Read N2H stats
- */
-static ssize_t nss_stats_n2h_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_N2H_MAX + 3) + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
- int max = NSS_STATS_N2H_MAX - NSS_STATS_NODE_MAX;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- stats_shadow = kzalloc(NSS_STATS_N2H_MAX * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "n2h stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.nss[0].stats_n2h[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
- }
-
- /*
- * N2H node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = NSS_STATS_NODE_MAX; (i < NSS_STATS_N2H_MAX); i++) {
- stats_shadow[i] = nss_top_main.nss[0].stats_n2h[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; i < max; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_n2h[i], stats_shadow[i + NSS_STATS_NODE_MAX]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_lso_rx_read()
- * Read LSO_RX stats
- */
-static ssize_t nss_stats_lso_rx_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_LSO_RX_MAX + 3) + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- stats_shadow = kzalloc(NSS_STATS_LSO_RX_MAX * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "lso_rx stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_node[NSS_LSO_RX_INTERFACE][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
- }
-
- /*
- * lso_rx node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nlso_rx node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_LSO_RX_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_lso_rx[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; i < NSS_STATS_LSO_RX_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_lso_rx[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nlso_rx stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_drv_read()
+ * nss_drv_stats_read()
* Read HLOS driver stats
*/
-static ssize_t nss_stats_drv_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+static ssize_t nss_drv_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
{
int32_t i;
@@ -2302,112 +166,10 @@
}
/*
- * nss_stats_pppoe_read()
- * Read PPPoE stats
- */
-static ssize_t nss_stats_pppoe_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i, j, k;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_PPPOE_MAX + 3) +
- ((NSS_MAX_PHYSICAL_INTERFACES * NSS_PPPOE_NUM_SESSION_PER_INTERFACE * (NSS_PPPOE_EXCEPTION_EVENT_MAX + 5)) + 3) + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "pppoe stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_node[NSS_PPPOE_RX_INTERFACE][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
- }
-
- /*
- * PPPoE node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npppoe node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_pppoe[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_pppoe[i], stats_shadow[i]);
- }
-
- /*
- * Exception stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nException PPPoE:\n\n");
-
- for (j = 1; j <= NSS_MAX_PHYSICAL_INTERFACES; j++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nInterface %d:\n\n", j);
-
- spin_lock_bh(&nss_top_main.stats_lock);
- for (k = 1; k <= NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
- for (i = 0; (i < NSS_PPPOE_EXCEPTION_EVENT_MAX); i++) {
- stats_shadow_pppoe_except[k - 1][i] = nss_top_main.stats_if_exception_pppoe[j][k][i];
- }
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (k = 1; k <= NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. Session\n", k);
- for (i = 0; (i < NSS_PPPOE_EXCEPTION_EVENT_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n",
- nss_stats_str_if_exception_pppoe[i],
- stats_shadow_pppoe_except[k - 1][i]);
- }
- }
-
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npppoe stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_gmac_read()
+ * nss_gmac_stats_read()
* Read GMAC stats
*/
-static ssize_t nss_stats_gmac_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+static ssize_t nss_gmac_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
{
uint32_t i, id;
@@ -2460,1792 +222,10 @@
}
/*
- * nss_stats_wifi_read()
- * Read wifi statistics
- */
-static ssize_t nss_stats_wifi_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- uint32_t i, id;
-
- /*
- * max output lines = ((#stats + start tag + one blank) * #WIFI RADIOs) + start/end tag + 3 blank
- */
- uint32_t max_output_lines = ((NSS_STATS_WIFI_MAX + 2) * NSS_MAX_WIFI_RADIO_INTERFACES) + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- stats_shadow = kzalloc(NSS_STATS_WIFI_MAX * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "wifi stats start:\n\n");
-
- for (id = 0; id < NSS_MAX_WIFI_RADIO_INTERFACES; id++) {
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_WIFI_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_wifi[id][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "WIFI ID: %d\n", id);
- for (i = 0; (i < NSS_STATS_WIFI_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_wifi[i], stats_shadow[i]);
- }
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\n");
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nwifi stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_wifili_read()
- * Read wifili statistics
- */
-static ssize_t nss_stats_wifili_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- uint32_t i, j;
-
- /*
- * max output lines = ((#stats + eight blank lines) * #WIFILI #STATS) + start/end tag + 3 blank
- */
- uint32_t max_output_lines = (((NSS_STATS_WIFILI_MAX + 9) * NSS_WIFILI_MAX_PDEV_NUM_MSG)+
- NSS_STATS_WIFILI_WBM_MAX + 5);
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- /*
- * Take max of all wifili stats
- *
- * NOTE: txrx stats is bigger of all stats
- */
- stats_shadow = kzalloc(NSS_STATS_WIFILI_TXRX_MAX * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "wifili stats start:\n\n");
-
- for (i = 0; i < NSS_WIFILI_MAX_PDEV_NUM_MSG; i++) {
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "WIFILI ID: %d\n", i);
-
- spin_lock_bh(&nss_top_main.stats_lock);
- for (j = 0; (j < NSS_STATS_WIFILI_TXRX_MAX); j++) {
- stats_shadow[j] = nss_top_main.stats_wifili.stats_txrx[i][j];
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_wifili_txrx[j], stats_shadow[j]);
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
-
- /*
- * Fillinng TCL ring stats
- */
- spin_lock_bh(&nss_top_main.stats_lock);
- for (j = 0; (j < NSS_STATS_WIFILI_TCL_MAX); j++) {
- stats_shadow[j] = nss_top_main.stats_wifili.stats_tcl_ring[i][j];
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_wifili_tcl[j], stats_shadow[j]);
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
-
- /*
- * Fillinng TCL comp stats
- */
- spin_lock_bh(&nss_top_main.stats_lock);
- for (j = 0; (j < NSS_STATS_WIFILI_TX_DESC_FREE_MAX); j++) {
- stats_shadow[j] = nss_top_main.stats_wifili.stats_tx_comp[i][j];
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_wifili_tx_comp[j], stats_shadow[j]);
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
-
- /*
- * Fillinng reo ring stats
- */
- spin_lock_bh(&nss_top_main.stats_lock);
- for (j = 0; (j < NSS_STATS_WIFILI_REO_MAX); j++) {
- stats_shadow[j] = nss_top_main.stats_wifili.stats_reo[i][j];
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_wifili_reo[j], stats_shadow[j]);
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
-
- /*
- * Fillinng TX SW Pool
- */
- spin_lock_bh(&nss_top_main.stats_lock);
- for (j = 0; (j < NSS_STATS_WIFILI_TX_DESC_MAX); j++) {
- stats_shadow[j] = nss_top_main.stats_wifili.stats_tx_desc[i][j];
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_wifili_txsw_pool[j], stats_shadow[j]);
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
-
- /*
- * Fillinng TX EXt SW Pool
- */
- spin_lock_bh(&nss_top_main.stats_lock);
- for (j = 0; (j < NSS_STATS_WIFILI_EXT_TX_DESC_MAX); j++) {
- stats_shadow[j] = nss_top_main.stats_wifili.stats_ext_tx_desc[i][j];
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_wifili_ext_txsw_pool[j], stats_shadow[j]);
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
-
- /*
- * Fillinng rxdma pool stats
- */
- spin_lock_bh(&nss_top_main.stats_lock);
- for (j = 0; (j < NSS_STATS_WIFILI_RX_DESC_MAX); j++) {
- stats_shadow[j] = nss_top_main.stats_wifili.stats_rx_desc[i][j];
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_wifili_rxdma_pool[j], stats_shadow[j]);
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
-
- /*
- * Fillinng rxdma ring stats
- */
- spin_lock_bh(&nss_top_main.stats_lock);
- for (j = 0; (j < NSS_STATS_WIFILI_RXDMA_DESC_MAX); j++) {
- stats_shadow[j] = nss_top_main.stats_wifili.stats_rxdma[i][j];
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_wifili_rxdma_ring[j], stats_shadow[j]);
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
-
- }
-
- /*
- * Fillinng wbm ring stats
- */
- spin_lock_bh(&nss_top_main.stats_lock);
- for (j = 0; (j < NSS_STATS_WIFILI_WBM_MAX); j++) {
- stats_shadow[j] = nss_top_main.stats_wifili.stats_wbm[j];
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_wifili_wbm[j], stats_shadow[j]);
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nwifili stats end\n\n");
-
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_dtls_read()
- * Read DTLS session statistics
- */
-static ssize_t nss_stats_dtls_read(struct file *fp, char __user *ubuf,
- size_t sz, loff_t *ppos)
-{
- uint32_t max_output_lines = 2 + (NSS_MAX_DTLS_SESSIONS
- * (NSS_STATS_DTLS_SESSION_MAX + 2)) + 2;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- struct net_device *dev;
- int id, i;
- struct nss_stats_dtls_session_debug *dtls_session_stats = NULL;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- dtls_session_stats = kzalloc((sizeof(struct nss_stats_dtls_session_debug)
- * NSS_MAX_DTLS_SESSIONS), GFP_KERNEL);
- if (unlikely(dtls_session_stats == NULL)) {
- nss_warning("Could not allocate memory for populating DTLS stats");
- kfree(lbuf);
- return 0;
- }
-
- /*
- * Get all stats
- */
- nss_dtls_session_debug_stats_get(dtls_session_stats);
-
- /*
- * Session stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\nDTLS session stats start:\n\n");
-
- for (id = 0; id < NSS_MAX_DTLS_SESSIONS; id++) {
- if (!dtls_session_stats[id].valid)
- break;
-
- dev = dev_get_by_index(&init_net, dtls_session_stats[id].if_index);
- if (likely(dev)) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%d. nss interface id=%d, netdevice=%s\n",
- id, dtls_session_stats[id].if_num,
- dev->name);
- dev_put(dev);
- } else {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%d. nss interface id=%d\n", id,
- dtls_session_stats[id].if_num);
- }
-
- for (i = 0; i < NSS_STATS_DTLS_SESSION_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %llu\n",
- nss_stats_str_dtls_session_debug_stats[i],
- dtls_session_stats[id].stats[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\nDTLS session stats end\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
-
- kfree(dtls_session_stats);
- kfree(lbuf);
- return bytes_read;
-}
-
-/*
- * nss_stats_gre_tunnel_read()
- * Read GRE Tunnel session statistics
- */
-static ssize_t nss_stats_gre_tunnel_read(struct file *fp, char __user *ubuf,
- size_t sz, loff_t *ppos)
-{
- uint32_t max_output_lines = 2 + (NSS_MAX_GRE_TUNNEL_SESSIONS
- * (NSS_STATS_GRE_TUNNEL_SESSION_MAX + 2)) + 2;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- struct net_device *dev;
- int id, i;
- struct nss_stats_gre_tunnel_session_debug *gre_tunnel_session_stats = NULL;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- gre_tunnel_session_stats = kzalloc((sizeof(struct nss_stats_gre_tunnel_session_debug)
- * NSS_MAX_GRE_TUNNEL_SESSIONS), GFP_KERNEL);
- if (unlikely(gre_tunnel_session_stats == NULL)) {
- nss_warning("Could not allocate memory for populating GRE Tunnel stats");
- kfree(lbuf);
- return 0;
- }
-
- /*
- * Get all stats
- */
- nss_gre_tunnel_session_debug_stats_get(gre_tunnel_session_stats);
-
- /*
- * Session stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\nGRE Tunnel session stats start:\n\n");
-
- for (id = 0; id < NSS_MAX_GRE_TUNNEL_SESSIONS; id++) {
- if (!gre_tunnel_session_stats[id].valid)
- break;
-
- dev = dev_get_by_index(&init_net, gre_tunnel_session_stats[id].if_index);
- if (likely(dev)) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%d. nss interface id=%d, netdevice=%s\n",
- id, gre_tunnel_session_stats[id].if_num,
- dev->name);
- dev_put(dev);
- } else {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%d. nss interface id=%d\n", id,
- gre_tunnel_session_stats[id].if_num);
- }
-
- for (i = 0; i < NSS_STATS_GRE_TUNNEL_SESSION_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %llu\n",
- nss_stats_str_gre_tunnel_session_debug_stats[i],
- gre_tunnel_session_stats[id].stats[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\nGRE Tunnel session stats end\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
-
- kfree(gre_tunnel_session_stats);
- kfree(lbuf);
- return bytes_read;
-}
-
-/*
- * nss_stats_l2tpv2_read()
- * Read l2tpv2 statistics
- */
-static ssize_t nss_stats_l2tpv2_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
-
- uint32_t max_output_lines = 2 /* header & footer for session stats */
- + NSS_MAX_L2TPV2_DYNAMIC_INTERFACES * (NSS_STATS_L2TPV2_SESSION_MAX + 2) /*session stats */
- + 2;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines ;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- struct net_device *dev;
- struct nss_stats_l2tpv2_session_debug l2tpv2_session_stats[NSS_MAX_L2TPV2_DYNAMIC_INTERFACES];
- int id, i;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- memset(&l2tpv2_session_stats, 0, sizeof(struct nss_stats_l2tpv2_session_debug) * NSS_MAX_L2TPV2_DYNAMIC_INTERFACES);
-
- /*
- * Get all stats
- */
- nss_l2tpv2_session_debug_stats_get((void *)&l2tpv2_session_stats);
-
- /*
- * Session stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nl2tp v2 session stats start:\n\n");
- for (id = 0; id < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; id++) {
-
- if (!l2tpv2_session_stats[id].valid) {
- break;
- }
-
- dev = dev_get_by_index(&init_net, l2tpv2_session_stats[id].if_index);
- if (likely(dev)) {
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id,
- l2tpv2_session_stats[id].if_num, dev->name);
- dev_put(dev);
- } else {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id,
- l2tpv2_session_stats[id].if_num);
- }
-
- for (i = 0; i < NSS_STATS_L2TPV2_SESSION_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %llu\n", nss_stats_str_l2tpv2_session_debug_stats[i],
- l2tpv2_session_stats[id].stats[i]);
- }
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nl2tp v2 session stats end\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
-
- kfree(lbuf);
- return bytes_read;
-}
-
-/*
- * nss_stats_map_t_read()
- * Read map_t statistics
- */
-static ssize_t nss_stats_map_t_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
-
- uint32_t max_output_lines = 2 /* header & footer for instance stats */
- + NSS_MAX_MAP_T_DYNAMIC_INTERFACES * (NSS_STATS_MAP_T_MAX + 2) /*instance stats */
- + 2;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- struct net_device *dev;
- struct nss_stats_map_t_instance_debug map_t_instance_stats[NSS_MAX_MAP_T_DYNAMIC_INTERFACES];
- int id, i;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(!lbuf)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- memset(&map_t_instance_stats, 0, sizeof(struct nss_stats_map_t_instance_debug) * NSS_MAX_MAP_T_DYNAMIC_INTERFACES);
-
- /*
- * Get all stats
- */
- nss_map_t_instance_debug_stats_get((void *)&map_t_instance_stats);
-
- /*
- * Session stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nmap_t instance stats start:\n\n");
- for (id = 0; id < NSS_MAX_MAP_T_DYNAMIC_INTERFACES; id++) {
-
- if (!map_t_instance_stats[id].valid) {
- break;
- }
-
- dev = dev_get_by_index(&init_net, map_t_instance_stats[id].if_index);
- if (likely(dev)) {
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id,
- map_t_instance_stats[id].if_num, dev->name);
- dev_put(dev);
- } else {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id,
- map_t_instance_stats[id].if_num);
- }
-
- for (i = 0; i < NSS_STATS_MAP_T_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %llu\n", nss_stats_str_map_t_instance_debug_stats[i],
- map_t_instance_stats[id].stats[i]);
- }
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nmap_t instance stats end\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
-
- kfree(lbuf);
- return bytes_read;
-}
-
- /*
- * nss_stats_gre_read()
- * Read GRE statistics
- */
-static ssize_t nss_stats_gre_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- uint32_t max_output_lines = 2 /* header & footer for base debug stats */
- + 2 /* header & footer for session debug stats */
- + NSS_STATS_GRE_BASE_DEBUG_MAX /* Base debug */
- + NSS_GRE_MAX_DEBUG_SESSION_STATS * (NSS_STATS_GRE_SESSION_DEBUG_MAX + 2) /*session stats */
- + 2;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- struct net_device *dev;
- struct nss_stats_gre_session_debug *sstats;
- struct nss_stats_gre_base_debug *bstats;
- int id, i;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(!lbuf)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- bstats = kzalloc(sizeof(struct nss_stats_gre_base_debug), GFP_KERNEL);
- if (unlikely(!bstats)) {
- nss_warning("Could not allocate memory for base debug statistics buffer");
- kfree(lbuf);
- return 0;
- }
-
- sstats = kzalloc(sizeof(struct nss_stats_gre_session_debug) * NSS_GRE_MAX_DEBUG_SESSION_STATS, GFP_KERNEL);
- if (unlikely(!sstats)) {
- nss_warning("Could not allocate memory for base debug statistics buffer");
- kfree(lbuf);
- kfree(bstats);
- return 0;
- }
-
- /*
- * Get all base stats
- */
- nss_gre_base_debug_stats_get((void *)bstats, sizeof(struct nss_stats_gre_base_debug));
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngre Base stats start:\n\n");
- for (i = 0; i < NSS_STATS_GRE_BASE_DEBUG_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %llu\n", nss_stats_str_gre_base_debug_stats[i],
- bstats->stats[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngre Base stats End\n\n");
-
- /*
- * Get all session stats
- */
- nss_gre_session_debug_stats_get(sstats, sizeof(struct nss_stats_gre_session_debug) * NSS_GRE_MAX_DEBUG_SESSION_STATS);
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngre Session stats start:\n\n");
-
- for (id = 0; id < NSS_GRE_MAX_DEBUG_SESSION_STATS; id++) {
-
- if (!((sstats + id)->valid)) {
- continue;
- }
-
- dev = dev_get_by_index(&init_net, (sstats + id)->if_index);
- if (likely(dev)) {
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id,
- (sstats + id)->if_num, dev->name);
- dev_put(dev);
- } else {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id,
- (sstats + id)->if_num);
- }
-
- for (i = 0; i < NSS_STATS_GRE_SESSION_DEBUG_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %llu\n", nss_stats_str_gre_session_debug_stats[i],
- (sstats + id)->stats[i]);
- }
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngre Session stats end\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
-
- kfree(sstats);
- kfree(bstats);
- kfree(lbuf);
- return bytes_read;
-}
-
-/*
- * nss_stats_ppe_conn_read()
- * Read ppe connection stats
- */
-static ssize_t nss_stats_ppe_conn_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
-
- int i;
- char *lbuf = NULL;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint32_t ppe_stats[NSS_STATS_PPE_CONN_MAX];
- uint32_t max_output_lines = 2 /* header & footer for session stats */
- + NSS_STATS_PPE_CONN_MAX /* PPE flow counters */
- + 2;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
-
- lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- memset(&ppe_stats, 0, sizeof(uint32_t) * NSS_STATS_PPE_CONN_MAX);
-
- /*
- * Get all stats
- */
- nss_ppe_stats_conn_get(ppe_stats);
-
- /*
- * flow stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe flow counters start:\n\n");
-
- for (i = 0; i < NSS_STATS_PPE_CONN_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %u\n", nss_stats_str_ppe_conn[i],
- ppe_stats[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe flow counters end\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
-
- kfree(lbuf);
- return bytes_read;
-}
-
-/*
- * nss_stats_ppe_l3_read()
- * Read ppe L3 debug stats
- */
-static ssize_t nss_stats_ppe_l3_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
-
- int i;
- char *lbuf = NULL;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint32_t ppe_stats[NSS_STATS_PPE_L3_MAX];
- uint32_t max_output_lines = 2 /* header & footer for session stats */
- + NSS_STATS_PPE_L3_MAX /* PPE flow counters */
- + 2;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
-
- lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(!lbuf)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- memset(ppe_stats, 0, sizeof(uint32_t) * NSS_STATS_PPE_L3_MAX);
-
- /*
- * Get all stats
- */
- nss_ppe_stats_l3_get(ppe_stats);
-
- /*
- * flow stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe l3 debug stats start:\n\n");
-
- for (i = 0; i < NSS_STATS_PPE_L3_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = 0x%x\n", nss_stats_str_ppe_l3[i],
- ppe_stats[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe l3 debug stats end\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
-
- kfree(lbuf);
- return bytes_read;
-}
-
-/*
- * nss_stats_ppe_code_read()
- * Read ppe CPU & DROP code
- */
-static ssize_t nss_stats_ppe_code_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
-
- int i;
- char *lbuf = NULL;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint32_t ppe_stats[NSS_STATS_PPE_CODE_MAX];
- uint32_t max_output_lines = 2 /* header & footer for session stats */
- + NSS_STATS_PPE_CODE_MAX /* PPE flow counters */
- + 2;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
-
- lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(!lbuf)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- memset(ppe_stats, 0, sizeof(uint32_t) * NSS_STATS_PPE_CODE_MAX);
-
- /*
- * Get all stats
- */
- nss_ppe_stats_code_get(ppe_stats);
-
- /*
- * flow stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe session stats start:\n\n");
-
- for (i = 0; i < NSS_STATS_PPE_CODE_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %u\n", nss_stats_str_ppe_code[i],
- ppe_stats[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe session stats end\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
-
- kfree(lbuf);
- return bytes_read;
-}
-
-/*
- * nss_stats_ppe_port_dc_read()
- * Read PPE per port drop code stats
- */
-static ssize_t nss_stats_ppe_port_dc_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + 2 start tag line + 2 end tag line + five blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_PPE_DROP_CODE_MAX + 4) + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- struct nss_stats_data *data = fp->private_data;
- uint32_t *ppe_stats;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- ppe_stats = kzalloc(sizeof(uint32_t) * NSS_STATS_PPE_DROP_CODE_MAX, GFP_KERNEL);
- if (unlikely(ppe_stats == NULL)) {
- kfree(lbuf);
- nss_warning("Could not allocate memory for ppe stats buffer");
- return 0;
- }
-
- /*
- * Get drop code counters for specific port
- */
- nss_ppe_port_drop_code_get(ppe_stats, data->edma_id);
- size_wr = scnprintf(lbuf, size_al, "ppe no drop code stats start:\n\n");
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %u\n", nss_stats_str_ppe_dc[0],
- ppe_stats[0]);
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe no drop code stats end\n\n");
-
- /*
- * Drop code stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "ppe non-zero drop code stats start:\n\n");
- for (i = 1; i < NSS_STATS_PPE_DROP_CODE_MAX; i++) {
- /*
- * Print only non-zero stats.
- */
- if (!ppe_stats[i]) {
- continue;
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %u\n", nss_stats_str_ppe_dc[i],
- ppe_stats[i]);
- }
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe non-zero drop code stats end\n\n");
-
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(ppe_stats);
- kfree(lbuf);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_ppe_exception_cc_read()
- * Read PPE CPU code stats specific to flow exceptions
- */
-static ssize_t nss_stats_ppe_exception_cc_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_PPE_CPU_CODE_EXCEPTION_MAX + 2) + 3;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint32_t *ppe_stats;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- ppe_stats = kzalloc(sizeof(uint32_t) * NSS_STATS_PPE_CPU_CODE_EXCEPTION_MAX, GFP_KERNEL);
- if (unlikely(ppe_stats == NULL)) {
- kfree(lbuf);
- nss_warning("Could not allocate memory for ppe stats buffer");
- return 0;
- }
-
- /*
- * Get CPU code counters for flow specific exceptions
- */
- nss_ppe_cpu_code_exception_get(ppe_stats);
-
- size_wr = scnprintf(lbuf, size_al, "ppe non-zero cpu code flow-exception stats start:\n\n");
-
- /*
- * CPU code stats
- */
- for (i = 0; i < NSS_STATS_PPE_CPU_CODE_EXCEPTION_MAX; i++) {
- /*
- * Print only non-zero stats.
- */
- if (!ppe_stats[i]) {
- continue;
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %u\n", nss_stats_str_ppe_cc[i],
- ppe_stats[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe non-zero cpu code flow-exception stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(ppe_stats);
- kfree(lbuf);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_ppe_nonexception_cc_read()
- * Read PPE CPU code stats for other than flow exceptions
- */
-static ssize_t nss_stats_ppe_nonexception_cc_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_PPE_CPU_CODE_NONEXCEPTION_MAX + 2) + 3;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint32_t *ppe_stats;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- ppe_stats = kzalloc(sizeof(uint32_t) * NSS_STATS_PPE_CPU_CODE_NONEXCEPTION_MAX, GFP_KERNEL);
- if (unlikely(ppe_stats == NULL)) {
- kfree(lbuf);
- nss_warning("Could not allocate memory for ppe stats buffer");
- return 0;
- }
-
- /*
- * Get CPU code counters for non flow exceptions
- */
- nss_ppe_cpu_code_nonexception_get(ppe_stats);
-
- /*
- * CPU code stats
- */
- size_wr = scnprintf(lbuf, size_al, "ppe non-zero cpu code non-flow exception stats start:\n\n");
- for (i = 0; i < NSS_STATS_PPE_CPU_CODE_NONEXCEPTION_MAX; i++) {
- /*
- * Print only non-zero stats.
- */
- if (!ppe_stats[i]) {
- continue;
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %u\n", nss_stats_str_ppe_cc[i + NSS_STATS_PPE_CPU_CODE_NONEXCEPTION_START],
- ppe_stats[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe non-zero cpu code non-flow exception stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(ppe_stats);
- kfree(lbuf);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_pptp_read()
- * Read pptp statistics
- */
-static ssize_t nss_stats_pptp_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
-
- uint32_t max_output_lines = 2 /* header & footer for session stats */
- + NSS_MAX_PPTP_DYNAMIC_INTERFACES * (NSS_STATS_PPTP_SESSION_MAX + 2) /*session stats */
- + 2;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines ;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- struct net_device *dev;
- struct nss_stats_pptp_session_debug pptp_session_stats[NSS_MAX_PPTP_DYNAMIC_INTERFACES];
- int id, i;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- memset(&pptp_session_stats, 0, sizeof(struct nss_stats_pptp_session_debug) * NSS_MAX_PPTP_DYNAMIC_INTERFACES);
-
- /*
- * Get all stats
- */
- nss_pptp_session_debug_stats_get((void *)&pptp_session_stats);
-
- /*
- * Session stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npptp session stats start:\n\n");
- for (id = 0; id < NSS_MAX_PPTP_DYNAMIC_INTERFACES; id++) {
-
- if (!pptp_session_stats[id].valid) {
- break;
- }
-
- dev = dev_get_by_index(&init_net, pptp_session_stats[id].if_index);
- if (likely(dev)) {
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id,
- pptp_session_stats[id].if_num, dev->name);
- dev_put(dev);
- } else {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id,
- pptp_session_stats[id].if_num);
- }
-
- for (i = 0; i < NSS_STATS_PPTP_SESSION_MAX; i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "\t%s = %llu\n", nss_stats_str_pptp_session_debug_stats[i],
- pptp_session_stats[id].stats[i]);
- }
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npptp session stats end\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
-
- kfree(lbuf);
- return bytes_read;
-}
-
-/*
- * nss_stats_sjack_read()
- * Read SJACK stats
- */
-static ssize_t nss_stats_sjack_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = NSS_STATS_NODE_MAX + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "sjack stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_node[NSS_SJACK_INTERFACE][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nsjack stats end\n\n");
-
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_portid_read()
- * Read PortID stats
- */
-static ssize_t nss_stats_portid_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = NSS_STATS_NODE_MAX + NSS_STATS_PORTID_MAX + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "portid stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_node[NSS_PORTID_INTERFACE][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
- }
-
- /*
- * PortID node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nportid node stats:\n\n");
-
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_PORTID_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_portid[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_PORTID_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_portid[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nportid stats end\n\n");
-
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_capwap_encap()
- * Make a row for CAPWAP encap stats.
- */
-static ssize_t nss_stats_capwap_encap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s)
-{
- char *header[] = { "packets", "bytes", "fragments", "drop_ref", "drop_ver", "drop_unalign",
- "drop_hroom", "drop_dtls", "drop_nwireless", "drop_qfull", "drop_memfail", "unknown" };
- uint64_t tcnt = 0;
-
- switch (i) {
- case 0:
- tcnt = s->pnode_stats.tx_packets;
- break;
- case 1:
- tcnt = s->pnode_stats.tx_bytes;
- break;
- case 2:
- tcnt = s->tx_segments;
- break;
- case 3:
- tcnt = s->tx_dropped_sg_ref;
- break;
- case 4:
- tcnt = s->tx_dropped_ver_mis;
- break;
- case 5:
- tcnt = s->tx_dropped_unalign;
- break;
- case 6:
- tcnt = s->tx_dropped_hroom;
- break;
- case 7:
- tcnt = s->tx_dropped_dtls;
- break;
- case 8:
- tcnt = s->tx_dropped_nwireless;
- break;
- case 9:
- tcnt = s->tx_queue_full_drops;
- break;
- case 10:
- tcnt = s->tx_mem_failure_drops;
- break;
- default:
- return 0;
- }
-
- return (snprintf(line, len, "%s = %llu\n", header[i], tcnt));
-}
-
-/*
- * nss_stats_capwap_decap()
- * Make a row for CAPWAP decap stats.
- */
-static ssize_t nss_stats_capwap_decap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s)
-{
- char *header[] = { "packets", "bytes", "DTLS_pkts", "fragments", "rx_dropped", "drop_oversize",
- "drop_frag_timeout", "drop_frag_dup", "drop_frag_gap", "drop_qfull", "drop_memfail",
- "drop_csum", "drop_malformed", "unknown" };
- uint64_t tcnt = 0;
-
- switch (i) {
- case 0:
- tcnt = s->pnode_stats.rx_packets;
- break;
- case 1:
- tcnt = s->pnode_stats.rx_bytes;
- break;
- case 2:
- tcnt = s->dtls_pkts;
- break;
- case 3:
- tcnt = s->rx_segments;
- break;
- case 4:
- tcnt = s->pnode_stats.rx_dropped;
- break;
- case 5:
- tcnt = s->rx_oversize_drops;
- break;
- case 6:
- tcnt = s->rx_frag_timeout_drops;
- break;
- case 7:
- tcnt = s->rx_dup_frag;
- break;
- case 8:
- tcnt = s->rx_frag_gap_drops;
- break;
- case 9:
- tcnt = s->rx_queue_full_drops;
- return (snprintf(line, len, "%s = %llu (n2h = %llu)\n", header[i], tcnt, s->rx_n2h_queue_full_drops));
- case 10:
- tcnt = s->rx_mem_failure_drops;
- break;
- case 11:
- tcnt = s->rx_csum_drops;
- break;
- case 12:
- tcnt = s->rx_malformed;
- break;
- default:
- return 0;
- }
-
- return (snprintf(line, len, "%s = %llu\n", header[i], tcnt));
-}
-
-/*
- * nss_stats_capwap_read()
- * Read CAPWAP stats
- */
-static ssize_t nss_stats_capwap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos, uint16_t type)
-{
- struct nss_stats_data *data = fp->private_data;
- ssize_t bytes_read = 0;
- struct nss_capwap_tunnel_stats stats;
- size_t bytes;
- char line[80];
- int start;
- uint32_t if_num = NSS_DYNAMIC_IF_START;
- uint32_t max_if_num = NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES;
-
- if (data) {
- if_num = data->if_num;
- }
-
- /*
- * If we are done accomodating all the CAPWAP tunnels.
- */
- if (if_num > max_if_num) {
- return 0;
- }
-
- for (; if_num <= max_if_num; if_num++) {
- bool isthere;
-
- if (nss_is_dynamic_interface(if_num) == false) {
- continue;
- }
-
- if (nss_dynamic_interface_get_type(nss_capwap_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
- continue;
- }
-
- /*
- * If CAPWAP tunnel does not exists, then isthere will be false.
- */
- isthere = nss_capwap_get_stats(if_num, &stats);
- if (!isthere) {
- continue;
- }
-
- bytes = snprintf(line, sizeof(line), "----if_num : %2d----\n", if_num);
- if ((bytes_read + bytes) > sz) {
- break;
- }
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto fail;
- }
- bytes_read += bytes;
- start = 0;
- while (bytes_read < sz) {
- if (type == 1) {
- bytes = nss_stats_capwap_encap(line, sizeof(line), start, &stats);
- } else {
- bytes = nss_stats_capwap_decap(line, sizeof(line), start, &stats);
- }
-
- /*
- * If we don't have any more lines in decap/encap.
- */
- if (bytes == 0) {
- break;
- }
-
- if ((bytes_read + bytes) > sz)
- break;
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto fail;
- }
-
- bytes_read += bytes;
- start++;
- }
- }
-
- if (bytes_read > 0) {
- *ppos = bytes_read;
- }
-
- if (data) {
- data->if_num = if_num;
- }
-fail:
- return bytes_read;
-}
-
-/*
- * nss_stats_capwap_decap_read()
- * Read CAPWAP decap stats
- */
-static ssize_t nss_stats_capwap_decap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- return (nss_stats_capwap_read(fp, ubuf, sz, ppos, 0));
-}
-
-/*
- * nss_stats_capwap_encap_read()
- * Read CAPWAP encap stats
- */
-static ssize_t nss_stats_capwap_encap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- return (nss_stats_capwap_read(fp, ubuf, sz, ppos, 1));
-}
-
-/*
- * nss_stats_gre_redir()
- * Make a row for GRE_REDIR stats.
- */
-static ssize_t nss_stats_gre_redir(char *line, int len, int i, struct nss_gre_redir_tunnel_stats *s)
-{
- char *header[] = { "TX Packets", "TX Bytes", "TX Drops", "RX Packets", "RX Bytes" };
- char name[20];
- uint64_t tcnt = 0;
- int j = 0;
-
- switch (i) {
- case 0:
- return snprintf(line, len, "%s = %u\n", header[i], s->node_stats.tx_packets);
- case 1:
- return snprintf(line, len, "%s = %u\n", header[i], s->node_stats.tx_bytes);
- case 2:
- return snprintf(line, len, "%s = %u\n", header[i], s->tx_dropped);
- case 3:
- return snprintf(line, len, "%s = %u\n", header[i], s->node_stats.rx_packets);
- case 4:
- return snprintf(line, len, "%s = %u\n", header[i], s->node_stats.rx_bytes);
- case 5:
- for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
- scnprintf(name, 20, "Rx Queue %d Drops", j);
- tcnt += snprintf(line, len, "%s = %u\n", name, s->node_stats.rx_dropped[j]);
- }
- return tcnt;
-
- default:
- return 0;
- }
-
-}
-
-/*
- * nss_stats_gre_redir_read()
- * READ gre_redir tunnel stats.
- */
-static ssize_t nss_stats_gre_redir_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- struct nss_stats_data *data = fp->private_data;
- ssize_t bytes_read = 0;
- struct nss_gre_redir_tunnel_stats stats;
- size_t bytes;
- char line[80 * NSS_MAX_NUM_PRI];
- int start, end;
- int index = 0;
-
- if (data) {
- index = data->index;
- }
-
- /*
- * If we are done accomodating all the GRE_REDIR tunnels.
- */
- if (index >= NSS_GRE_REDIR_MAX_INTERFACES) {
- return 0;
- }
-
- for (; index < NSS_GRE_REDIR_MAX_INTERFACES; index++) {
- bool isthere;
-
- /*
- * If gre_redir tunnel does not exists, then isthere will be false.
- */
- isthere = nss_gre_redir_get_stats(index, &stats);
- if (!isthere) {
- continue;
- }
-
- bytes = snprintf(line, sizeof(line), "\nTunnel if_num: %2d\n", stats.if_num);
- if ((bytes_read + bytes) > sz) {
- break;
- }
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto fail;
- }
- bytes_read += bytes;
- start = 0;
- end = 6;
- while (bytes_read < sz && start < end) {
- bytes = nss_stats_gre_redir(line, sizeof(line), start, &stats);
-
- if ((bytes_read + bytes) > sz)
- break;
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto fail;
- }
-
- bytes_read += bytes;
- start++;
- }
- }
-
- if (bytes_read > 0) {
- *ppos = bytes_read;
- }
-
- if (data) {
- data->index = index;
- }
-
-fail:
- return bytes_read;
-}
-
-/*
- * nss_stats_wifi_if_read()
- * Read wifi_if statistics
- */
-static ssize_t nss_stats_wifi_if_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- struct nss_stats_data *data = fp->private_data;
- struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
- int32_t if_num = NSS_DYNAMIC_IF_START;
- int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
- size_t bytes = 0;
- ssize_t bytes_read = 0;
- char line[80];
- int start, end;
-
- if (data) {
- if_num = data->if_num;
- }
-
- if (if_num > max_if_num) {
- return 0;
- }
-
- for (; if_num < max_if_num; if_num++) {
- if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
- continue;
-
- bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
- if ((bytes_read + bytes) > sz)
- break;
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto end;
- }
-
- bytes_read += bytes;
-
- start = 0;
- end = 7;
- while (bytes_read < sz && start < end) {
- bytes = nss_wifi_if_copy_stats(if_num, start, line);
- if (!bytes)
- break;
-
- if ((bytes_read + bytes) > sz)
- break;
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto end;
- }
-
- bytes_read += bytes;
- start++;
- }
-
- bytes = scnprintf(line, sizeof(line), "if_num %d stats end:\n\n", if_num);
- if (bytes_read > (sz - bytes))
- break;
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto end;
- }
-
- bytes_read += bytes;
- }
-
- if (bytes_read > 0) {
- *ppos = bytes_read;
- }
-
- if (data) {
- data->if_num = if_num;
- }
-
-end:
- return bytes_read;
-}
-
-/*
- * nss_stats_virt_if_read()
- * Read virt_if statistics
- */
-static ssize_t nss_stats_virt_if_read(struct file *fp, char __user *ubuf,
- size_t sz, loff_t *ppos)
-{
- struct nss_stats_data *data = fp->private_data;
- struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
- int32_t if_num = NSS_DYNAMIC_IF_START;
- int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
- size_t bytes = 0;
- ssize_t bytes_read = 0;
- char line[80];
- int start, end;
-
- if (data) {
- if_num = data->if_num;
- }
-
- if (if_num > max_if_num) {
- return 0;
- }
-
- for (; if_num < max_if_num; if_num++) {
- if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
- continue;
-
- bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
- if ((bytes_read + bytes) > sz)
- break;
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto end;
- }
-
- bytes_read += bytes;
-
- start = 0;
- end = 7;
- while (bytes_read < sz && start < end) {
- bytes = nss_virt_if_copy_stats(if_num, start, line);
- if (!bytes)
- break;
-
- if ((bytes_read + bytes) > sz)
- break;
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto end;
- }
-
- bytes_read += bytes;
- start++;
- }
-
- bytes = scnprintf(line, sizeof(line), "if_num %d stats end:\n\n", if_num);
- if (bytes_read > (sz - bytes))
- break;
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto end;
- }
-
- bytes_read += bytes;
- }
-
- if (bytes_read > 0) {
- *ppos = bytes_read;
- }
-
- if (data) {
- data->if_num = if_num;
- }
-
-end:
- return bytes_read;
-}
-
-/*
- * nss_stats_tx_rx_virt_if_read()
- * Read tx_rx_virt_if statistics
- */
-static ssize_t nss_stats_tx_rx_virt_if_read(struct file *fp, char __user *ubuf,
- size_t sz, loff_t *ppos)
-{
- struct nss_stats_data *data = fp->private_data;
- struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
- int32_t if_num = NSS_DYNAMIC_IF_START;
- int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
- size_t bytes = 0;
- ssize_t bytes_read = 0;
- char line[80];
- int start, end;
-
- if (data) {
- if_num = data->if_num;
- }
-
- if (if_num > max_if_num) {
- return 0;
- }
-
- for (; if_num < max_if_num; if_num++) {
- if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED)
- continue;
-
- bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
- if ((bytes_read + bytes) > sz)
- break;
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto end;
- }
-
- bytes_read += bytes;
-
- start = 0;
- end = 7;
- while (bytes_read < sz && start < end) {
- bytes = nss_tx_rx_virt_if_copy_stats(if_num, start, line);
- if (!bytes)
- break;
-
- if ((bytes_read + bytes) > sz)
- break;
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto end;
- }
-
- bytes_read += bytes;
- start++;
- }
-
- bytes = scnprintf(line, sizeof(line), "if_num %d stats end:\n\n", if_num);
- if (bytes_read > (sz - bytes))
- break;
-
- if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
- bytes_read = -EFAULT;
- goto end;
- }
-
- bytes_read += bytes;
- }
-
- if (bytes_read > 0) {
- *ppos = bytes_read;
- }
-
- if (data) {
- data->if_num = if_num;
- }
-
-end:
- return bytes_read;
-}
-
-/*
- * nss_stats_trustsec_tx_read()
- * Read trustsec_tx stats
- */
-static ssize_t nss_stats_trustsec_tx_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
-{
- int32_t i;
-
- /*
- * max output lines = #stats + start tag line + end tag line + three blank lines
- */
- uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_TRUSTSEC_TX_MAX + 3) + 5;
- size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
- size_t size_wr = 0;
- ssize_t bytes_read = 0;
- uint64_t *stats_shadow;
-
- char *lbuf = kzalloc(size_al, GFP_KERNEL);
- if (unlikely(lbuf == NULL)) {
- nss_warning("Could not allocate memory for local statistics buffer");
- return 0;
- }
-
- stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL);
- if (unlikely(stats_shadow == NULL)) {
- nss_warning("Could not allocate memory for local shadow buffer");
- kfree(lbuf);
- return 0;
- }
-
- size_wr = scnprintf(lbuf, size_al, "trustsec_tx stats start:\n\n");
-
- /*
- * Common node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_node[NSS_TRUSTSEC_TX_INTERFACE][i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
- }
-
- /*
- * TrustSec TX node stats
- */
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ntrustsec tx node stats:\n\n");
-
- spin_lock_bh(&nss_top_main.stats_lock);
- for (i = 0; (i < NSS_STATS_TRUSTSEC_TX_MAX); i++) {
- stats_shadow[i] = nss_top_main.stats_trustsec_tx[i];
- }
-
- spin_unlock_bh(&nss_top_main.stats_lock);
-
- for (i = 0; (i < NSS_STATS_TRUSTSEC_TX_MAX); i++) {
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
- "%s = %llu\n", nss_stats_str_trustsec_tx[i], stats_shadow[i]);
- }
-
- size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ntrustsec tx stats end\n\n");
- bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
- kfree(lbuf);
- kfree(stats_shadow);
-
- return bytes_read;
-}
-
-/*
- * nss_stats_wt_read()
+ * nss_wt_stats_read()
* Reads and formats worker thread statistics and outputs them to ubuf
*/
-static ssize_t nss_stats_wt_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+static ssize_t nss_wt_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
{
struct nss_stats_data *data = fp->private_data;
struct nss_ctx_instance *nss_ctx = data->nss_ctx;
@@ -4290,7 +270,7 @@
/*
* The statistics shadow is an array with thread_count * irq_count
* items in it. Each item is located at the index:
- * (thread number) * (irq_count) + (irq number)
+ * (thread number) * (irq_count) + (irq number)
* thus simulating a two-dimensional array.
*/
for (j = 0; j < irq_count; ++j) {
@@ -4327,7 +307,7 @@
/*
* nss_stats_open()
*/
-static int nss_stats_open(struct inode *inode, struct file *filp)
+int nss_stats_open(struct inode *inode, struct file *filp)
{
struct nss_stats_data *data = NULL;
@@ -4348,7 +328,7 @@
/*
* nss_stats_release()
*/
-static int nss_stats_release(struct inode *inode, struct file *filp)
+int nss_stats_release(struct inode *inode, struct file *filp)
{
struct nss_stats_data *data = filp->private_data;
@@ -4359,224 +339,46 @@
return 0;
}
-#define NSS_STATS_DECLARE_FILE_OPERATIONS(name) \
-static const struct file_operations nss_stats_##name##_ops = { \
- .open = nss_stats_open, \
- .read = nss_stats_##name##_read, \
- .llseek = generic_file_llseek, \
- .release = nss_stats_release, \
-};
-
-/*
- * nss_ipv4_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4)
-
-/*
- * ipv4_reasm_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4_reasm)
-
-/*
- * ipv6_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6)
-
-/*
- * ipv6_reasm_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6_reasm)
-
-/*
- * n2h_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(n2h)
-
-/*
- * lso_rx_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(lso_rx)
-
/*
* drv_stats_ops
*/
NSS_STATS_DECLARE_FILE_OPERATIONS(drv)
/*
- * pppoe_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(pppoe)
-
-/*
- * l2tpv2_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(l2tpv2)
-
-/*
- * map_t_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(map_t)
-
-/*
- * gre_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(gre)
-
-/*
- * ppe_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_conn)
-NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_l3)
-NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_code)
-NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_port_dc)
-NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_exception_cc)
-NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_nonexception_cc)
-
-/*
- * pptp_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(pptp)
-
-/*
* gmac_stats_ops
*/
NSS_STATS_DECLARE_FILE_OPERATIONS(gmac)
/*
- * capwap_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_encap)
-NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_decap)
-
-/*
- * eth_rx_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(eth_rx)
-
-/*
- * edma_port_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(edma_port_stats)
-
-/*
- * edma_port_type_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(edma_port_type)
-
-/*
- * edma_port_ring_map_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(edma_port_ring_map)
-
-/*
- * edma_txring_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(edma_txring)
-
-/*
- * edma_rxring_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(edma_rxring)
-
-/*
- * edma_txcmplring_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(edma_txcmplring)
-
-/*
- * edma_rxfillring_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(edma_rxfillring)
-
-/*
- * edma_err_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(edma_err_stats)
-
-/*
- * gre_redir_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(gre_redir)
-
-/*
- * sjack_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(sjack)
-
-/*
- * portid_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(portid)
-
-NSS_STATS_DECLARE_FILE_OPERATIONS(wifi_if)
-
-NSS_STATS_DECLARE_FILE_OPERATIONS(virt_if)
-
-NSS_STATS_DECLARE_FILE_OPERATIONS(tx_rx_virt_if)
-
-/*
- * wifi_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(wifi)
-
-/*
- * dtls_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(dtls)
-
-/*
- * gre_tunnel_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(gre_tunnel)
-
-/*
- * trustsec_tx_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(trustsec_tx)
-
-/*
- * wifili_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(wifili)
-
-/*
* wt_stats_ops
*/
NSS_STATS_DECLARE_FILE_OPERATIONS(wt)
+
+/*
+ * nss_stats_clean()
+ * Cleanup NSS statistics files
+ */
+void nss_stats_clean(void)
+{
+ /*
+ * Remove debugfs tree
+ */
+ if (likely(nss_top_main.top_dentry != NULL)) {
+ debugfs_remove_recursive(nss_top_main.top_dentry);
+ nss_top_main.top_dentry = NULL;
+ }
+}
+
/*
* nss_stats_init()
* Enable NSS statistics
*/
void nss_stats_init(void)
{
- int i = 0;
- struct dentry *edma_d = NULL;
- struct dentry *edma_port_dir_d = NULL;
- struct dentry *edma_port_d = NULL;
- struct dentry *edma_port_type_d = NULL;
- struct dentry *edma_port_stats_d = NULL;
- struct dentry *edma_port_ring_map_d = NULL;
- struct dentry *edma_rings_dir_d = NULL;
- struct dentry *edma_tx_dir_d = NULL;
- struct dentry *edma_tx_d = NULL;
- struct dentry *edma_rx_dir_d = NULL;
- struct dentry *edma_rx_d = NULL;
- struct dentry *edma_txcmpl_dir_d = NULL;
- struct dentry *edma_txcmpl_d = NULL;
- struct dentry *edma_rxfill_dir_d = NULL;
- struct dentry *edma_rxfill_d = NULL;
- struct dentry *edma_err_stats_d = NULL;
-
- struct dentry *ppe_code_d = NULL;
- struct dentry *ppe_drop_d = NULL;
- struct dentry *ppe_port_dc_d = NULL;
- struct dentry *ppe_cpu_d = NULL;
- struct dentry *ppe_exception_d = NULL;
- struct dentry *ppe_nonexception_d = NULL;
struct dentry *core_dentry = NULL;
struct dentry *wt_dentry = NULL;
-
char file_name[10];
+ int i;
/*
* NSS driver entry
@@ -4608,498 +410,14 @@
*/
/*
- * ipv4_stats
- */
- nss_top_main.ipv4_dentry = debugfs_create_file("ipv4", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv4_ops);
- if (unlikely(nss_top_main.ipv4_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ipv4 file in debugfs");
- return;
- }
-
- /*
- * ipv4_reasm_stats
- */
- nss_top_main.ipv4_reasm_dentry = debugfs_create_file("ipv4_reasm", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv4_reasm_ops);
- if (unlikely(nss_top_main.ipv4_reasm_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ipv4_reasm file in debugfs");
- return;
- }
-
- /*
- * ipv6_stats
- */
- nss_top_main.ipv6_dentry = debugfs_create_file("ipv6", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv6_ops);
- if (unlikely(nss_top_main.ipv6_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ipv6 file in debugfs");
- return;
- }
-
- /*
- * ipv6_reasm_stats
- */
- nss_top_main.ipv6_reasm_dentry = debugfs_create_file("ipv6_reasm", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv6_reasm_ops);
- if (unlikely(nss_top_main.ipv6_reasm_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ipv6_reasm file in debugfs");
- return;
- }
-
- /*
- * eth_rx__stats
- */
- nss_top_main.eth_rx_dentry = debugfs_create_file("eth_rx", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_eth_rx_ops);
- if (unlikely(nss_top_main.eth_rx_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/eth_rx file in debugfs");
- return;
- }
-
- /*
- * edma stats
- */
- edma_d = debugfs_create_dir("edma", nss_top_main.stats_dentry);
- if (unlikely(edma_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma directory in debugfs");
- return;
- }
-
- /*
- * edma port stats
- */
- edma_port_dir_d = debugfs_create_dir("ports", edma_d);
- if (unlikely(edma_port_dir_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/ports directory in debugfs");
- return;
- }
-
- for (i = 0; i < NSS_EDMA_NUM_PORTS_MAX; i++) {
- memset(file_name, 0, sizeof(file_name));
- snprintf(file_name, sizeof(file_name), "%d", i);
- edma_port_d = NULL;
- edma_port_stats_d = NULL;
- edma_port_type_d = NULL;
- edma_port_ring_map_d = NULL;
-
- edma_port_d = debugfs_create_dir(file_name, edma_port_dir_d);
- if (unlikely(edma_port_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d dir in debugfs", i);
- return;
- }
-
- edma_port_stats_d = debugfs_create_file("stats", 0400, edma_port_d, (void *)(nss_ptr_t)i, &nss_stats_edma_port_stats_ops);
- if (unlikely(edma_port_stats_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d/stats file in debugfs", i);
- return;
- }
-
- edma_port_type_d = debugfs_create_file("type", 0400, edma_port_d, (void *)(nss_ptr_t)i, &nss_stats_edma_port_type_ops);
- if (unlikely(edma_port_type_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d/type file in debugfs", i);
- return;
- }
-
- edma_port_ring_map_d = debugfs_create_file("ring_map", 0400, edma_port_d, (void *)(nss_ptr_t)i, &nss_stats_edma_port_ring_map_ops);
- if (unlikely(edma_port_ring_map_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d/ring_map file in debugfs", i);
- return;
- }
- }
-
- /*
- * edma error stats
- */
- edma_err_stats_d = NULL;
- edma_err_stats_d = debugfs_create_file("err_stats", 0400, edma_d, &nss_top_main, &nss_stats_edma_err_stats_ops);
- if (unlikely(edma_port_stats_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/%d/err_stats file in debugfs", 0);
- return;
- }
-
- /*
- * edma ring stats
- */
- edma_rings_dir_d = debugfs_create_dir("rings", edma_d);
- if (unlikely(edma_rings_dir_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/rings directory in debugfs");
- return;
- }
-
- /*
- * edma tx ring stats
- */
- edma_tx_dir_d = debugfs_create_dir("tx", edma_rings_dir_d);
- if (unlikely(edma_tx_dir_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/rings/tx directory in debugfs");
- return;
- }
-
- for (i = 0; i < NSS_EDMA_NUM_TX_RING_MAX; i++) {
- memset(file_name, 0, sizeof(file_name));
- scnprintf(file_name, sizeof(file_name), "%d", i);
- edma_tx_d = NULL;
- edma_tx_d = debugfs_create_file(file_name, 0400, edma_tx_dir_d, (void *)(nss_ptr_t)i, &nss_stats_edma_txring_ops);
- if (unlikely(edma_tx_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/rings/tx/%d file in debugfs", i);
- return;
- }
- }
-
- /*
- * edma rx ring stats
- */
- edma_rx_dir_d = debugfs_create_dir("rx", edma_rings_dir_d);
- if (unlikely(edma_rx_dir_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rx directory in debugfs");
- return;
- }
-
- for (i = 0; i < NSS_EDMA_NUM_RX_RING_MAX; i++) {
- memset(file_name, 0, sizeof(file_name));
- scnprintf(file_name, sizeof(file_name), "%d", i);
- edma_rx_d = NULL;
- edma_rx_d = debugfs_create_file(file_name, 0400, edma_rx_dir_d, (void *)(nss_ptr_t)i, &nss_stats_edma_rxring_ops);
- if (unlikely(edma_rx_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rx/%d file in debugfs", i);
- return;
- }
- }
-
- /*
- * edma tx cmpl ring stats
- */
- edma_txcmpl_dir_d = debugfs_create_dir("txcmpl", edma_rings_dir_d);
- if (unlikely(edma_txcmpl_dir_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/rings/txcmpl directory in debugfs");
- return;
- }
-
- for (i = 0; i < NSS_EDMA_NUM_TXCMPL_RING_MAX; i++) {
- memset(file_name, 0, sizeof(file_name));
- scnprintf(file_name, sizeof(file_name), "%d", i);
- edma_txcmpl_d = NULL;
- edma_txcmpl_d = debugfs_create_file(file_name, 0400, edma_txcmpl_dir_d, (void *)(nss_ptr_t)i, &nss_stats_edma_txcmplring_ops);
- if (unlikely(edma_txcmpl_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/rings/txcmpl/%d file in debugfs", i);
- return;
- }
- }
-
- /*
- * edma rx fill ring stats
- */
- edma_rxfill_dir_d = debugfs_create_dir("rxfill", edma_rings_dir_d);
- if (unlikely(edma_rxfill_dir_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rxfill directory in debugfs");
- return;
- }
-
- for (i = 0; i < NSS_EDMA_NUM_RXFILL_RING_MAX; i++) {
- memset(file_name, 0, sizeof(file_name));
- scnprintf(file_name, sizeof(file_name), "%d", i);
- edma_rxfill_d = NULL;
- edma_rxfill_d = debugfs_create_file(file_name, 0400, edma_rxfill_dir_d, (void *)(nss_ptr_t)i, &nss_stats_edma_rxfillring_ops);
- if (unlikely(edma_rxfill_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rxfill/%d file in debugfs", i);
- return;
- }
- }
-
- /*
- * n2h_stats
- */
- nss_top_main.n2h_dentry = debugfs_create_file("n2h", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_n2h_ops);
- if (unlikely(nss_top_main.n2h_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/n2h directory in debugfs");
- return;
- }
-
- /*
- * lso_rx_stats
- */
- nss_top_main.lso_rx_dentry = debugfs_create_file("lso_rx", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_lso_rx_ops);
- if (unlikely(nss_top_main.lso_rx_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/lso_rx file in debugfs");
- return;
- }
-
- /*
* drv_stats
*/
- nss_top_main.drv_dentry = debugfs_create_file("drv", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_drv_ops);
- if (unlikely(nss_top_main.drv_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/drv directory in debugfs");
- return;
- }
-
- /*
- * pppoe_stats
- */
- nss_top_main.pppoe_dentry = debugfs_create_file("pppoe", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_pppoe_ops);
- if (unlikely(nss_top_main.pppoe_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/pppoe file in debugfs");
- return;
- }
+ nss_stats_create_dentry("drv", &nss_drv_stats_ops);
/*
* gmac_stats
*/
- nss_top_main.gmac_dentry = debugfs_create_file("gmac", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_gmac_ops);
- if (unlikely(nss_top_main.gmac_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/gmac file in debugfs");
- return;
- }
-
- /*
- * CAPWAP stats.
- */
- nss_top_main.capwap_encap_dentry = debugfs_create_file("capwap_encap", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_capwap_encap_ops);
- if (unlikely(nss_top_main.capwap_encap_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/capwap_encap file in debugfs");
- return;
- }
-
- nss_top_main.capwap_decap_dentry = debugfs_create_file("capwap_decap", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_capwap_decap_ops);
- if (unlikely(nss_top_main.capwap_decap_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/capwap_decap file in debugfs");
- return;
- }
-
- /*
- * GRE_REDIR stats
- */
- nss_top_main.gre_redir_dentry = debugfs_create_file("gre_redir", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_gre_redir_ops);
- if (unlikely(nss_top_main.gre_redir_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/gre_redir file in debugfs");
- return;
- }
-
- /*
- * SJACK stats
- */
- nss_top_main.sjack_dentry = debugfs_create_file("sjack", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_sjack_ops);
- if (unlikely(nss_top_main.sjack_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/sjack file in debugfs");
- return;
- }
-
- /*
- * PORTID stats
- */
- nss_top_main.portid_dentry = debugfs_create_file("portid", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_portid_ops);
- if (unlikely(nss_top_main.portid_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/portid file in debugfs");
- return;
- }
-
- /*
- * WIFI stats
- */
- nss_top_main.wifi_dentry = debugfs_create_file("wifi", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_wifi_ops);
- if (unlikely(nss_top_main.wifi_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/wifi file in debugfs");
- return;
- }
-
- /*
- * wifi_if stats
- */
- nss_top_main.wifi_if_dentry = debugfs_create_file("wifi_if", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_wifi_if_ops);
- if (unlikely(nss_top_main.wifi_if_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/wifi_if file in debugfs");
- return;
- }
-
- nss_top_main.virt_if_dentry = debugfs_create_file("virt_if", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_virt_if_ops);
- if (unlikely(nss_top_main.virt_if_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/virt_if file in debugfs");
- return;
- }
-
- nss_top_main.tx_rx_virt_if_dentry = debugfs_create_file("tx_rx_virt_if", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_tx_rx_virt_if_ops);
- if (unlikely(nss_top_main.virt_if_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/tx_rx_virt_if file in debugfs");
- return;
- }
-
- /*
- * L2TPV2 Stats
- */
- nss_top_main.l2tpv2_dentry = debugfs_create_file("l2tpv2", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_l2tpv2_ops);
- if (unlikely(nss_top_main.l2tpv2_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/l2tpv2 file in debugfs");
- return;
- }
-
- /*
- * Map-t Stats
- */
- nss_top_main.map_t_dentry = debugfs_create_file("map_t", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_map_t_ops);
- if (unlikely(nss_top_main.map_t_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/map_t file in debugfs");
- return;
- }
-
- /*
- * GRE statistics
- */
- nss_top_main.gre_dentry = debugfs_create_file("gre", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_gre_ops);
- if (unlikely(nss_top_main.gre_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/gre file in debugfs");
- return;
- }
-
- /*
- * PPE Stats
- */
- nss_top_main.ppe_dentry = debugfs_create_dir("ppe", nss_top_main.stats_dentry);
- if (unlikely(nss_top_main.ppe_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv directory in debugfs");
- return;
- }
-
- nss_top_main.ppe_conn_dentry = debugfs_create_file("connection", 0400,
- nss_top_main.ppe_dentry, &nss_top_main, &nss_stats_ppe_conn_ops);
- if (unlikely(nss_top_main.ppe_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ppe/connection file in debugfs");
- }
-
- nss_top_main.ppe_l3_dentry = debugfs_create_file("l3", 0400,
- nss_top_main.ppe_dentry, &nss_top_main, &nss_stats_ppe_l3_ops);
- if (unlikely(nss_top_main.ppe_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ppe/l3 file in debugfs");
- }
-
- nss_top_main.ppe_l3_dentry = debugfs_create_file("ppe_code", 0400,
- nss_top_main.ppe_dentry, &nss_top_main, &nss_stats_ppe_code_ops);
- if (unlikely(nss_top_main.ppe_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ppe/ppe_code file in debugfs");
- }
-
- /*
- * ppe exception and drop code stats
- */
- ppe_code_d = debugfs_create_dir("code", nss_top_main.ppe_dentry);
- if (unlikely(ppe_code_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ppe/code directory in debugfs");
- return;
- }
-
- ppe_cpu_d = debugfs_create_dir("cpu", ppe_code_d);
- if (unlikely(ppe_cpu_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ppe/code/cpu directory in debugfs");
- return;
- }
-
- ppe_exception_d = debugfs_create_file("exception", 0400, ppe_cpu_d,
- &nss_top_main, &nss_stats_ppe_exception_cc_ops);
- if (unlikely(ppe_exception_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ppe/code/exception file in debugfs");
- return;
- }
-
- ppe_nonexception_d = debugfs_create_file("non-exception", 0400, ppe_cpu_d,
- &nss_top_main, &nss_stats_ppe_nonexception_cc_ops);
- if (unlikely(ppe_nonexception_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ppe/code/non-exception file in debugfs");
- return;
- }
-
- ppe_drop_d = debugfs_create_dir("drop", ppe_code_d);
- if (unlikely(ppe_drop_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ppe/code/drop directory in debugfs");
- return;
- }
-
- for (i = 0; i < NSS_PPE_NUM_PHY_PORTS_MAX; i++) {
- if (i > 0) {
- memset(file_name, 0, sizeof(file_name));
- snprintf(file_name, sizeof(file_name), "%d", i);
- }
-
- ppe_port_dc_d = NULL;
- ppe_port_dc_d = debugfs_create_file((i == 0) ? "cpu" : file_name, 0400, ppe_drop_d,
- (void *)(nss_ptr_t)i, &nss_stats_ppe_port_dc_ops);
- if (unlikely(ppe_port_dc_d == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/ppe/code/drop/%d file in debugfs", i);
- return;
- }
- }
-
- /*
- * PPTP Stats
- */
- nss_top_main.pptp_dentry = debugfs_create_file("pptp", 0400,
- nss_top_main.stats_dentry, &nss_top_main, &nss_stats_pptp_ops);
- if (unlikely(nss_top_main.pptp_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/pptp file in debugfs");
- }
-
- /*
- * DTLS Stats
- */
- nss_top_main.dtls_dentry = debugfs_create_file("dtls", 0400,
- nss_top_main.stats_dentry,
- &nss_top_main,
- &nss_stats_dtls_ops);
- if (unlikely(nss_top_main.dtls_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/dtls file in debugfs");
- return;
- }
-
- /*
- * GRE Tunnel Stats
- */
- nss_top_main.gre_tunnel_dentry = debugfs_create_file("gre_tunnel", 0400,
- nss_top_main.stats_dentry,
- &nss_top_main,
- &nss_stats_gre_tunnel_ops);
- if (unlikely(nss_top_main.gre_tunnel_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/gre_tunnel file in debugfs");
- return;
- }
-
- /*
- * TrustSec TX Stats
- */
- nss_top_main.trustsec_tx_dentry = debugfs_create_file("trustsec_tx", 0400,
- nss_top_main.stats_dentry,
- &nss_top_main,
- &nss_stats_trustsec_tx_ops);
- if (unlikely(nss_top_main.trustsec_tx_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/trustsec_tx file in debugfs");
- return;
- }
-
- /*
- * WIFILI stats
- */
- nss_top_main.wifili_dentry = debugfs_create_file("wifili", 0400,
- nss_top_main.stats_dentry,
- &nss_top_main, &nss_stats_wifili_ops);
- if (unlikely(nss_top_main.wifili_dentry == NULL)) {
- nss_warning("Failed to create qca-nss-drv/stats/wifili file in debugfs");
- return;
- }
+ nss_stats_create_dentry("gmac", &nss_gmac_stats_ops);
/*
* Per-project stats
@@ -5125,7 +443,7 @@
0400,
core_dentry,
&(nss_top_main.nss[i]),
- &nss_stats_wt_ops);
+ &nss_wt_stats_ops);
if (unlikely(wt_dentry == NULL)) {
nss_warning("Failed to create qca-nss-drv/stats/project/core%d/worker_threads file in debugfs", i);
return;
@@ -5134,18 +452,3 @@
nss_log_init();
}
-
-/*
- * nss_stats_clean()
- * Cleanup NSS statistics files
- */
-void nss_stats_clean(void)
-{
- /*
- * Remove debugfs tree
- */
- if (likely(nss_top_main.top_dentry != NULL)) {
- debugfs_remove_recursive(nss_top_main.top_dentry);
- nss_top_main.top_dentry = NULL;
- }
-}
diff --git a/nss_stats.h b/nss_stats.h
new file mode 100644
index 0000000..b973bab
--- /dev/null
+++ b/nss_stats.h
@@ -0,0 +1,78 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_stats.h
+ * NSS driver stats header file.
+ */
+
+#ifndef __NSS_STATS_H
+#define __NSS_STATS_H
+
+#include <linux/debugfs.h>
+
+/*
+ * Maximum string length:
+ * This should be equal to maximum string size of any stats
+ * inclusive of stats value
+ */
+#define NSS_STATS_MAX_STR_LENGTH 96
+
+/*
+ * Node statistics
+ */
+enum nss_stats_node {
+ NSS_STATS_NODE_RX_PKTS, /* Accelerated node RX packets */
+ NSS_STATS_NODE_RX_BYTES, /* Accelerated node RX bytes */
+ NSS_STATS_NODE_TX_PKTS, /* Accelerated node TX packets */
+ NSS_STATS_NODE_TX_BYTES, /* Accelerated node TX bytes */
+ NSS_STATS_NODE_RX_QUEUE_0_DROPPED,
+ /* Accelerated node RX Queue 0 dropped */
+ NSS_STATS_NODE_RX_QUEUE_1_DROPPED,
+ /* Accelerated node RX Queue 1 dropped */
+ NSS_STATS_NODE_RX_QUEUE_2_DROPPED,
+ /* Accelerated node RX Queue 2 dropped */
+ NSS_STATS_NODE_RX_QUEUE_3_DROPPED,
+ /* Accelerated node RX Queue 3 dropped */
+
+ NSS_STATS_NODE_MAX,
+};
+
+#define NSS_STATS_DECLARE_FILE_OPERATIONS(name) \
+static const struct file_operations nss_##name##_stats_ops = { \
+ .open = nss_stats_open, \
+ .read = nss_##name##_stats_read, \
+ .llseek = generic_file_llseek, \
+ .release = nss_stats_release, \
+};
+
+/*
+ * Private data for every file descriptor
+ */
+struct nss_stats_data {
+ uint32_t if_num; /**< Interface number for stats */
+ uint32_t index; /**< Index for GRE_REDIR stats */
+ uint32_t edma_id; /**< EDMA port ID or ring ID */
+ struct nss_ctx_instance *nss_ctx;
+ /**< The core for project stats */
+};
+
+int nss_stats_release(struct inode *inode, struct file *filp);
+int nss_stats_open(struct inode *inode, struct file *filp);
+void nss_stats_create_dentry(char *name, const struct file_operations *ops);
+size_t nss_stats_fill_common_stats(uint32_t if_num, char *lbuf, size_t size_wr, size_t size_al);
+
+#endif /* __NSS_STATS_H */
diff --git a/nss_trustsec_tx.c b/nss_trustsec_tx.c
index f9f181b..1795f78 100644
--- a/nss_trustsec_tx.c
+++ b/nss_trustsec_tx.c
@@ -15,6 +15,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_trustsec_tx_stats.h"
#define NSS_TRUSTSEC_TX_TIMEOUT 3000 /* 3 Seconds */
@@ -28,37 +29,6 @@
} ttx;
/*
- * nss_trustsec_tx_node_sync_update()
- * Update trustsec_tx node stats.
- */
-static void nss_trustsec_tx_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_trustsec_tx_stats_sync_msg *ntsm)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- int j;
-
- /*
- * Update common node stats
- */
- spin_lock_bh(&nss_top->stats_lock);
- nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += ntsm->node_stats.rx_packets;
- nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += ntsm->node_stats.rx_bytes;
- nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += ntsm->node_stats.tx_packets;
- nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += ntsm->node_stats.tx_bytes;
-
- for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
- nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += ntsm->node_stats.rx_dropped[j];
- }
-
- /*
- * Update trustsec node stats
- */
- nss_top->stats_trustsec_tx[NSS_STATS_TRUSTSEC_TX_INVALID_SRC] += ntsm->invalid_src;
- nss_top->stats_trustsec_tx[NSS_STATS_TRUSTSEC_TX_UNCONFIGURED_SRC] += ntsm->unconfigured_src;
- nss_top->stats_trustsec_tx[NSS_STATS_IRUSTSEC_TX_HEADROOM_NOT_ENOUGH] += ntsm->headroom_not_enough;
- spin_unlock_bh(&nss_top->stats_lock);
-}
-
-/*
* nss_trustsec_tx_handler()
* Handle NSS -> HLOS messages for trustsec_tx
*/
@@ -93,7 +63,7 @@
/*
* Update trustsec_tx statistics.
*/
- nss_trustsec_tx_sync_update(nss_ctx, &npm->msg.stats_sync);
+ nss_trustsec_tx_stats_sync(nss_ctx, &npm->msg.stats_sync);
break;
}
@@ -322,6 +292,8 @@
nss_core_register_handler(nss_ctx, NSS_TRUSTSEC_TX_INTERFACE, nss_trustsec_tx_handler, NULL);
+ nss_trustsec_tx_stats_dentry_create();
+
sema_init(&ttx.sem, 1);
init_completion(&ttx.complete);
}
diff --git a/nss_trustsec_tx_stats.c b/nss_trustsec_tx_stats.c
new file mode 100644
index 0000000..5c624e9
--- /dev/null
+++ b/nss_trustsec_tx_stats.c
@@ -0,0 +1,148 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_tx_rx_common.h"
+#include "nss_stats.h"
+#include "nss_trustsec_tx_stats.h"
+
+/*
+ * nss_trustsec_tx_stats_str
+ * Trustsec TX statistics strings
+ */
+static int8_t *nss_trustsec_tx_stats_str[NSS_TRUSTSEC_TX_STATS_MAX] = {
+ "INVALID_SRC",
+ "UNCONFIGURED_SRC",
+ "HEADROOM_NOT_ENOUGH",
+};
+
+/*
+ * trustsec_tx_stats
+ * Trustsec TX statistics
+ */
+uint64_t trustsec_tx_stats[NSS_TRUSTSEC_TX_STATS_MAX];
+
+/*
+ * Trustsec TX statistics APIs
+ */
+
+/*
+ * nss_trustsec_tx_stats_sync()
+ * Update trustsec_tx node statistics.
+ */
+void nss_trustsec_tx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_trustsec_tx_stats_sync_msg *ntsm)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ int j;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ /*
+ * Update common node stats
+ */
+ nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += ntsm->node_stats.rx_packets;
+ nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += ntsm->node_stats.rx_bytes;
+ nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += ntsm->node_stats.tx_packets;
+ nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += ntsm->node_stats.tx_bytes;
+
+ for (j = 0; j < NSS_MAX_NUM_PRI; j++) {
+ nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += ntsm->node_stats.rx_dropped[j];
+ }
+
+ /*
+ * Update trustsec node stats
+ */
+ trustsec_tx_stats[NSS_TRUSTSEC_TX_STATS_INVALID_SRC] += ntsm->invalid_src;
+ trustsec_tx_stats[NSS_TRUSTSEC_TX_STATS_UNCONFIGURED_SRC] += ntsm->unconfigured_src;
+ trustsec_tx_stats[NSS_TRUSTSEC_TX_STATS_HEADROOM_NOT_ENOUGH] += ntsm->headroom_not_enough;
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
+
+/*
+ * nss_trustsec_tx_stats_read()
+ * Read trustsec_tx statiistics
+ */
+static ssize_t nss_trustsec_tx_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ int32_t i;
+
+ /*
+ * max output lines = #stats + start tag line + end tag line + three blank lines
+ */
+ uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_TRUSTSEC_TX_STATS_MAX + 3) + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "trustsec_tx stats start:\n\n");
+
+ /*
+ * Common node stats
+ */
+ size_wr = nss_stats_fill_common_stats(NSS_TRUSTSEC_TX_INTERFACE, lbuf, size_wr, size_al);
+
+ /*
+ * TrustSec TX node stats
+ */
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ntrustsec tx node stats:\n\n");
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_TRUSTSEC_TX_STATS_MAX); i++) {
+ stats_shadow[i] = trustsec_tx_stats[i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ for (i = 0; (i < NSS_TRUSTSEC_TX_STATS_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_trustsec_tx_stats_str[i], stats_shadow[i]);
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ntrustsec tx stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_trustsec_tx_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(trustsec_tx)
+
+/*
+ * nss_trustsec_tx_stats_dentry_create()
+ * Create trustsec_tx statistics debug entry.
+ */
+void nss_trustsec_tx_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("trustsec_tx", &nss_trustsec_tx_stats_ops);
+}
diff --git a/nss_trustsec_tx_stats.h b/nss_trustsec_tx_stats.h
new file mode 100644
index 0000000..11a4d8f
--- /dev/null
+++ b/nss_trustsec_tx_stats.h
@@ -0,0 +1,44 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_trustsec_tx_stats.h
+ * NSS TRUSTSEC TX statistics header file.
+ */
+
+#ifndef __NSS_TRUSTSEC_TX_STATS_H
+#define __NSS_TRUSTSEC_TX_STATS_H
+
+/*
+ * Trustsec TX statistics
+ */
+enum nss_trustsec_tx_stats {
+ NSS_TRUSTSEC_TX_STATS_INVALID_SRC,
+ /* Number of packets with invalid src if */
+ NSS_TRUSTSEC_TX_STATS_UNCONFIGURED_SRC,
+ /* Number of packets with unconfigured src if */
+ NSS_TRUSTSEC_TX_STATS_HEADROOM_NOT_ENOUGH,
+ /* Number of packets with not enough headroom */
+ NSS_TRUSTSEC_TX_STATS_MAX
+};
+
+/*
+ * Trustsec TX statistics APIs
+ */
+extern void nss_trustsec_tx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_trustsec_tx_stats_sync_msg *ntsm);
+extern void nss_trustsec_tx_stats_dentry_create(void);
+
+#endif /* __NSS_TRUSTSEC_TX_STATS_H */
diff --git a/nss_tx_rx_common.h b/nss_tx_rx_common.h
index e3b9232..5603bdc 100644
--- a/nss_tx_rx_common.h
+++ b/nss_tx_rx_common.h
@@ -53,6 +53,8 @@
#define NSS_VERIFY_INIT_DONE(x)
#endif
+#define NSS_TX_RX_VIRT_IF_GET_INDEX(if_num) (if_num - NSS_DYNAMIC_IF_START)
+
/*
* Deprecated Redirect
*/
@@ -162,16 +164,11 @@
void *app_data;
};
-/**
- * @brief Get stats for redir interface from NSS driver
- *
- * @param if_num Interface number (provided during dynamic_interface allocation)
- * @param i index of stats
- * @param line buffer into which the stats will be copied.
- *
- * @return int32_t Returns 0 if if_num is not in range or the number of bytes copied.
+/*
+ * NSS tx_rx_virt_if statistics APIs
*/
-extern int32_t nss_tx_rx_virt_if_copy_stats(int32_t if_num, int i, char *line);
+extern void nss_tx_rx_virt_if_stats_sync(struct nss_tx_rx_virt_if_handle *handle, struct nss_tx_rx_virt_if_stats *nwis);
+extern void nss_tx_rx_virt_if_stats_dentry_create(void);
/*
* CB handlers for variour interfaces
diff --git a/nss_tx_rx_virt_if.c b/nss_tx_rx_virt_if.c
index 9d3dc59..4429747 100644
--- a/nss_tx_rx_virt_if.c
+++ b/nss_tx_rx_virt_if.c
@@ -23,7 +23,6 @@
#include <net/arp.h>
#define NSS_TX_RX_VIRT_IF_TX_TIMEOUT 3000 /* 3 Seconds */
-#define NSS_TX_RX_VIRT_IF_GET_INDEX(if_num) (if_num-NSS_DYNAMIC_IF_START)
#define NSS_TX_RX_VIRT_IF_802_3_PKT 0x2
#define NSS_TX_RX_VIRT_IF_NATIVE_WIFI_PKT 0x3
@@ -32,7 +31,7 @@
/*
* Data structure that holds the virtual interface context.
*/
-static struct nss_tx_rx_virt_if_handle *nss_tx_rx_virt_if_handles[NSS_MAX_DYNAMIC_INTERFACES];
+struct nss_tx_rx_virt_if_handle *nss_tx_rx_virt_if_handles[NSS_MAX_DYNAMIC_INTERFACES];
/*
* Spinlock to protect the global data structure virt_handle.
@@ -40,24 +39,6 @@
DEFINE_SPINLOCK(nss_tx_rx_virt_if_lock);
/*
- * nss_tx_rx_virt_if_stats_sync()
- * Sync stats from the NSS FW
- */
-static void nss_tx_rx_virt_if_stats_sync(struct nss_tx_rx_virt_if_handle *handle,
- struct nss_tx_rx_virt_if_stats *nwis)
-{
- struct nss_tx_rx_virt_if_stats *stats = &handle->stats;
-
- stats->node_stats.rx_packets += nwis->node_stats.rx_packets;
- stats->node_stats.rx_bytes += nwis->node_stats.rx_bytes;
- stats->node_stats.rx_dropped += nwis->node_stats.rx_dropped;
- stats->node_stats.tx_packets += nwis->node_stats.tx_packets;
- stats->node_stats.tx_bytes += nwis->node_stats.tx_bytes;
- stats->tx_enqueue_failed += nwis->tx_enqueue_failed;
- stats->shaper_enqueue_failed += nwis->shaper_enqueue_failed;
-}
-
-/*
* nss_tx_rx_virt_if_msg_handler()
* Handle msg responses from the FW on virtual interfaces
*/
@@ -395,7 +376,7 @@
* nss_tx_rx_virt_if_register_handler_sync()
* register msg handler for redir interface and initialize semaphore and completion.
*/
-static uint32_t nss_tx_rx_virt_if_register_handler(struct nss_tx_rx_virt_if_handle *handle)
+uint32_t nss_tx_rx_virt_if_register_handler(struct nss_tx_rx_virt_if_handle *handle)
{
struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wlan_handler_id];
@@ -416,6 +397,7 @@
nrip->sem_init_done = 1;
}
+ nss_tx_rx_virt_if_stats_dentry_create();
return NSS_TX_RX_VIRT_IF_SUCCESS;
}
@@ -664,77 +646,6 @@
return status;
}
-/*
- * nss_tx_rx_virt_if_copy_stats()
- * Copy stats from the redir_if handle to buffer(line)
- */
-int32_t nss_tx_rx_virt_if_copy_stats(int32_t if_num, int i, char *line)
-{
- int32_t bytes = 0;
- struct nss_tx_rx_virt_if_stats *stats;
- int32_t ifnum;
- uint32_t len = 80;
- struct nss_tx_rx_virt_if_handle *handle = NULL;
-
- if (if_num < 0) {
- nss_warning("invalid if_num\n");
- return 0;
- }
-
- ifnum = NSS_TX_RX_VIRT_IF_GET_INDEX(if_num);
-
- spin_lock_bh(&nss_tx_rx_virt_if_lock);
- if (!nss_tx_rx_virt_if_handles[ifnum]) {
- spin_unlock_bh(&nss_tx_rx_virt_if_lock);
- goto end;
- }
-
- handle = nss_tx_rx_virt_if_handles[ifnum];
- spin_unlock_bh(&nss_tx_rx_virt_if_lock);
-
- stats = &handle->stats;
-
- switch (i) {
- case 0:
- bytes = scnprintf(line, len, "rx_packets=%d\n",
- stats->node_stats.rx_packets);
- break;
-
- case 1:
- bytes = scnprintf(line, len, "rx_bytes=%d\n",
- stats->node_stats.rx_bytes);
- break;
-
- case 2:
- bytes = scnprintf(line, len, "rx_dropped=%d\n",
- stats->node_stats.rx_dropped);
- break;
-
- case 3:
- bytes = scnprintf(line, len, "tx_packets=%d\n",
- stats->node_stats.tx_packets);
- break;
-
- case 4:
- bytes = scnprintf(line, len, "tx_bytes=%d\n",
- stats->node_stats.tx_bytes);
- break;
-
- case 5:
- bytes = scnprintf(line, len, "tx_enqueue_failed=%d\n",
- stats->tx_enqueue_failed);
- break;
-
- case 6:
- bytes = scnprintf(line, len, "shaper_enqueue_failed=%d\n",
- stats->shaper_enqueue_failed);
- break;
- }
-
-end:
- return bytes;
-}
-
EXPORT_SYMBOL(nss_tx_virt_if_rxbuf);
EXPORT_SYMBOL(nss_tx_virt_if_rx_nwifibuf);
EXPORT_SYMBOL(nss_create_virt_if);
diff --git a/nss_tx_rx_virt_if_stats.c b/nss_tx_rx_virt_if_stats.c
new file mode 100644
index 0000000..52bcfd2
--- /dev/null
+++ b/nss_tx_rx_virt_if_stats.c
@@ -0,0 +1,213 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_tx_rx_common.h"
+
+/*
+ * Data structure that holds the virtual interface context.
+ */
+extern struct nss_tx_rx_virt_if_handle *nss_tx_rx_virt_if_handles[NSS_MAX_DYNAMIC_INTERFACES];
+
+/*
+ * Spinlock to protect the global data structure virt_handle.
+ */
+extern spinlock_t nss_tx_rx_virt_if_lock;
+
+/*
+ * nss_tx_rx_virt_if_stats_get()
+ * Get stats from the redir_if handle to buffer(line)
+ */
+static int32_t nss_tx_rx_virt_if_stats_get(int32_t if_num, int i, char *line)
+{
+ int32_t bytes = 0;
+ struct nss_tx_rx_virt_if_stats *stats;
+ int32_t ifnum;
+ uint32_t len = 80;
+ struct nss_tx_rx_virt_if_handle *handle = NULL;
+
+ if (if_num < 0) {
+ nss_warning("invalid if_num\n");
+ return 0;
+ }
+
+ ifnum = NSS_TX_RX_VIRT_IF_GET_INDEX(if_num);
+
+ spin_lock_bh(&nss_tx_rx_virt_if_lock);
+ if (!nss_tx_rx_virt_if_handles[ifnum]) {
+ spin_unlock_bh(&nss_tx_rx_virt_if_lock);
+ goto end;
+ }
+
+ handle = nss_tx_rx_virt_if_handles[ifnum];
+ spin_unlock_bh(&nss_tx_rx_virt_if_lock);
+
+ stats = &handle->stats;
+
+ switch (i) {
+ case 0:
+ bytes = scnprintf(line, len, "rx_packets=%d\n",
+ stats->node_stats.rx_packets);
+ break;
+
+ case 1:
+ bytes = scnprintf(line, len, "rx_bytes=%d\n",
+ stats->node_stats.rx_bytes);
+ break;
+
+ case 2:
+ bytes = scnprintf(line, len, "rx_dropped=%d\n",
+ stats->node_stats.rx_dropped);
+ break;
+
+ case 3:
+ bytes = scnprintf(line, len, "tx_packets=%d\n",
+ stats->node_stats.tx_packets);
+ break;
+
+ case 4:
+ bytes = scnprintf(line, len, "tx_bytes=%d\n",
+ stats->node_stats.tx_bytes);
+ break;
+
+ case 5:
+ bytes = scnprintf(line, len, "tx_enqueue_failed=%d\n",
+ stats->tx_enqueue_failed);
+ break;
+
+ case 6:
+ bytes = scnprintf(line, len, "shaper_enqueue_failed=%d\n",
+ stats->shaper_enqueue_failed);
+ break;
+ }
+
+end:
+ return bytes;
+}
+
+/*
+ * nss_tx_rx_virt_if_stats_ops()
+ * Read tx_rx_virt_if statistics
+ */
+static ssize_t nss_tx_rx_virt_if_stats_read(struct file *fp, char __user *ubuf,
+ size_t sz, loff_t *ppos)
+{
+ struct nss_stats_data *data = fp->private_data;
+ struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
+ int32_t if_num = NSS_DYNAMIC_IF_START;
+ int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
+ size_t bytes = 0;
+ ssize_t bytes_read = 0;
+ char line[80];
+ int start, end;
+
+ if (data) {
+ if_num = data->if_num;
+ }
+
+ if (if_num > max_if_num) {
+ return 0;
+ }
+
+ for (; if_num < max_if_num; if_num++) {
+ if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED)
+ continue;
+
+ bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
+ if ((bytes_read + bytes) > sz)
+ break;
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto end;
+ }
+
+ bytes_read += bytes;
+
+ start = 0;
+ end = 7;
+ while (bytes_read < sz && start < end) {
+ bytes = nss_tx_rx_virt_if_stats_get(if_num, start, line);
+ if (!bytes)
+ break;
+
+ if ((bytes_read + bytes) > sz)
+ break;
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto end;
+ }
+
+ bytes_read += bytes;
+ start++;
+ }
+
+ bytes = scnprintf(line, sizeof(line), "if_num %d stats end:\n\n", if_num);
+ if (bytes_read > (sz - bytes))
+ break;
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto end;
+ }
+
+ bytes_read += bytes;
+ }
+
+ if (bytes_read > 0) {
+ *ppos = bytes_read;
+ }
+
+ if (data) {
+ data->if_num = if_num;
+ }
+
+end:
+ return bytes_read;
+}
+
+/*
+ * nss_tx_rx_virt_if_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(tx_rx_virt_if)
+
+/*
+ * nss_tx_rx_virt_if_stats_dentry_create()
+ * Create tx_rx_virt_if statistics debug entry.
+ */
+void nss_tx_rx_virt_if_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("tx_rx_virt_if", &nss_tx_rx_virt_if_stats_ops);
+}
+
+/*
+ * nss_tx_rx_virt_if_stats_sync()
+ * Sync stats from the NSS FW
+ */
+void nss_tx_rx_virt_if_stats_sync(struct nss_tx_rx_virt_if_handle *handle,
+ struct nss_tx_rx_virt_if_stats *nwis)
+{
+ struct nss_tx_rx_virt_if_stats *stats = &handle->stats;
+
+ stats->node_stats.rx_packets += nwis->node_stats.rx_packets;
+ stats->node_stats.rx_bytes += nwis->node_stats.rx_bytes;
+ stats->node_stats.rx_dropped += nwis->node_stats.rx_dropped;
+ stats->node_stats.tx_packets += nwis->node_stats.tx_packets;
+ stats->node_stats.tx_bytes += nwis->node_stats.tx_bytes;
+ stats->tx_enqueue_failed += nwis->tx_enqueue_failed;
+ stats->shaper_enqueue_failed += nwis->shaper_enqueue_failed;
+}
diff --git a/nss_virt_if.c b/nss_virt_if.c
index e21a0c7..ec3b48d 100644
--- a/nss_virt_if.c
+++ b/nss_virt_if.c
@@ -20,6 +20,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_virt_if_stats.h"
#include <net/arp.h>
#define NSS_VIRT_IF_TX_TIMEOUT 3000 /* 3 Seconds */
@@ -30,7 +31,7 @@
/*
* Data structure that holds the virtual interface context.
*/
-static struct nss_virt_if_handle *nss_virt_if_handle_t[NSS_MAX_DYNAMIC_INTERFACES];
+struct nss_virt_if_handle *nss_virt_if_handle_t[NSS_MAX_DYNAMIC_INTERFACES];
/*
* Spinlock to protect the global data structure virt_handle.
@@ -38,24 +39,6 @@
DEFINE_SPINLOCK(nss_virt_if_lock);
/*
- * nss_virt_if_stats_sync()
- * Sync stats from the NSS FW
- */
-static void nss_virt_if_stats_sync(struct nss_virt_if_handle *handle,
- struct nss_virt_if_stats *nwis)
-{
- struct nss_virt_if_stats *stats = &handle->stats;
-
- stats->node_stats.rx_packets += nwis->node_stats.rx_packets;
- stats->node_stats.rx_bytes += nwis->node_stats.rx_bytes;
- stats->node_stats.rx_dropped += nwis->node_stats.rx_dropped;
- stats->node_stats.tx_packets += nwis->node_stats.tx_packets;
- stats->node_stats.tx_bytes += nwis->node_stats.tx_bytes;
- stats->tx_enqueue_failed += nwis->tx_enqueue_failed;
- stats->shaper_enqueue_failed += nwis->shaper_enqueue_failed;
-}
-
-/*
* nss_virt_if_msg_handler()
* Handle msg responses from the FW on virtual interfaces
*/
@@ -505,6 +488,7 @@
nvip->sem_init_done = 1;
}
+ nss_virt_if_stats_dentry_create();
return NSS_VIRT_IF_SUCCESS;
}
@@ -909,77 +893,6 @@
EXPORT_SYMBOL(nss_virt_if_unregister);
/*
- * nss_virt_if_copy_stats()
- * Copy stats from the virt_if handle to buffer(line)
- */
-int32_t nss_virt_if_copy_stats(int32_t if_num, int i, char *line)
-{
- int32_t bytes = 0;
- struct nss_virt_if_stats *stats;
- int32_t ifnum;
- uint32_t len = 80;
- struct nss_virt_if_handle *handle = NULL;
-
- if (if_num < 0) {
- nss_warning("invalid if_num\n");
- return 0;
- }
-
- ifnum = NSS_VIRT_IF_GET_INDEX(if_num);
-
- spin_lock_bh(&nss_virt_if_lock);
- if (!nss_virt_if_handle_t[ifnum]) {
- spin_unlock_bh(&nss_virt_if_lock);
- goto end;
- }
-
- handle = nss_virt_if_handle_t[ifnum];
- spin_unlock_bh(&nss_virt_if_lock);
-
- stats = &handle->stats;
-
- switch (i) {
- case 0:
- bytes = scnprintf(line, len, "rx_packets=%d\n",
- stats->node_stats.rx_packets);
- break;
-
- case 1:
- bytes = scnprintf(line, len, "rx_bytes=%d\n",
- stats->node_stats.rx_bytes);
- break;
-
- case 2:
- bytes = scnprintf(line, len, "rx_dropped=%d\n",
- stats->node_stats.rx_dropped);
- break;
-
- case 3:
- bytes = scnprintf(line, len, "tx_packets=%d\n",
- stats->node_stats.tx_packets);
- break;
-
- case 4:
- bytes = scnprintf(line, len, "tx_bytes=%d\n",
- stats->node_stats.tx_bytes);
- break;
-
- case 5:
- bytes = scnprintf(line, len, "tx_enqueue_failed=%d\n",
- stats->tx_enqueue_failed);
- break;
-
- case 6:
- bytes = scnprintf(line, len, "shaper_enqueue_failed=%d\n",
- stats->shaper_enqueue_failed);
- break;
- }
-
-end:
- return bytes;
-}
-
-/*
* nss_virt_if_get_interface_num()
* Get interface number for a virtual interface
*/
diff --git a/nss_virt_if_stats.c b/nss_virt_if_stats.c
new file mode 100644
index 0000000..5c923dd
--- /dev/null
+++ b/nss_virt_if_stats.c
@@ -0,0 +1,213 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_tx_rx_common.h"
+
+/*
+ * Data structure that holds the virtual interface context.
+ */
+extern struct nss_virt_if_handle *nss_virt_if_handle_t[];
+
+/*
+ * Spinlock to protect the global data structure virt_handle.
+ */
+extern spinlock_t nss_virt_if_lock;
+
+/*
+ * nss_virt_if_stats_get()
+ * Get stats from the virt_if handle to buffer(line)
+ */
+static int32_t nss_virt_if_stats_get(int32_t if_num, int i, char *line)
+{
+ int32_t bytes = 0;
+ struct nss_virt_if_stats *stats;
+ int32_t ifnum;
+ uint32_t len = 80;
+ struct nss_virt_if_handle *handle = NULL;
+
+ if (if_num < 0) {
+ nss_warning("invalid if_num\n");
+ return 0;
+ }
+
+ ifnum = if_num - NSS_DYNAMIC_IF_START;
+
+ spin_lock_bh(&nss_virt_if_lock);
+ if (!nss_virt_if_handle_t[ifnum]) {
+ spin_unlock_bh(&nss_virt_if_lock);
+ goto end;
+ }
+
+ handle = nss_virt_if_handle_t[ifnum];
+ spin_unlock_bh(&nss_virt_if_lock);
+
+ stats = &handle->stats;
+
+ switch (i) {
+ case 0:
+ bytes = scnprintf(line, len, "rx_packets=%d\n",
+ stats->node_stats.rx_packets);
+ break;
+
+ case 1:
+ bytes = scnprintf(line, len, "rx_bytes=%d\n",
+ stats->node_stats.rx_bytes);
+ break;
+
+ case 2:
+ bytes = scnprintf(line, len, "rx_dropped=%d\n",
+ stats->node_stats.rx_dropped);
+ break;
+
+ case 3:
+ bytes = scnprintf(line, len, "tx_packets=%d\n",
+ stats->node_stats.tx_packets);
+ break;
+
+ case 4:
+ bytes = scnprintf(line, len, "tx_bytes=%d\n",
+ stats->node_stats.tx_bytes);
+ break;
+
+ case 5:
+ bytes = scnprintf(line, len, "tx_enqueue_failed=%d\n",
+ stats->tx_enqueue_failed);
+ break;
+
+ case 6:
+ bytes = scnprintf(line, len, "shaper_enqueue_failed=%d\n",
+ stats->shaper_enqueue_failed);
+ break;
+ }
+
+end:
+ return bytes;
+}
+
+/*
+ * nss_virt_if_stats_read()
+ * Read virt_if statistics
+ */
+static ssize_t nss_virt_if_stats_read(struct file *fp, char __user *ubuf,
+ size_t sz, loff_t *ppos)
+{
+ struct nss_stats_data *data = fp->private_data;
+ struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
+ int32_t if_num = NSS_DYNAMIC_IF_START;
+ int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
+ size_t bytes = 0;
+ ssize_t bytes_read = 0;
+ char line[80];
+ int start, end;
+
+ if (data) {
+ if_num = data->if_num;
+ }
+
+ if (if_num > max_if_num) {
+ return 0;
+ }
+
+ for (; if_num < max_if_num; if_num++) {
+ if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
+ continue;
+
+ bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
+ if ((bytes_read + bytes) > sz)
+ break;
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto end;
+ }
+
+ bytes_read += bytes;
+
+ start = 0;
+ end = 7;
+ while (bytes_read < sz && start < end) {
+ bytes = nss_virt_if_stats_get(if_num, start, line);
+ if (!bytes)
+ break;
+
+ if ((bytes_read + bytes) > sz)
+ break;
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto end;
+ }
+
+ bytes_read += bytes;
+ start++;
+ }
+
+ bytes = scnprintf(line, sizeof(line), "if_num %d stats end:\n\n", if_num);
+ if (bytes_read > (sz - bytes))
+ break;
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto end;
+ }
+
+ bytes_read += bytes;
+ }
+
+ if (bytes_read > 0) {
+ *ppos = bytes_read;
+ }
+
+ if (data) {
+ data->if_num = if_num;
+ }
+
+end:
+ return bytes_read;
+}
+
+/*
+ * nss_virt_if_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(virt_if)
+
+/*
+ * nss_virt_if_stats_dentry_create()
+ * Create virt_if statistics debug entry.
+ */
+void nss_virt_if_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("virt_if", &nss_virt_if_stats_ops);
+}
+
+/*
+ * nss_virt_if_stats_sync()
+ * Sync stats from the NSS FW
+ */
+void nss_virt_if_stats_sync(struct nss_virt_if_handle *handle,
+ struct nss_virt_if_stats *nwis)
+{
+ struct nss_virt_if_stats *stats = &handle->stats;
+
+ stats->node_stats.rx_packets += nwis->node_stats.rx_packets;
+ stats->node_stats.rx_bytes += nwis->node_stats.rx_bytes;
+ stats->node_stats.rx_dropped += nwis->node_stats.rx_dropped;
+ stats->node_stats.tx_packets += nwis->node_stats.tx_packets;
+ stats->node_stats.tx_bytes += nwis->node_stats.tx_bytes;
+ stats->tx_enqueue_failed += nwis->tx_enqueue_failed;
+ stats->shaper_enqueue_failed += nwis->shaper_enqueue_failed;
+}
diff --git a/nss_virt_if_stats.h b/nss_virt_if_stats.h
new file mode 100644
index 0000000..d6e4448
--- /dev/null
+++ b/nss_virt_if_stats.h
@@ -0,0 +1,26 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_VIRT_IF_STATS_H
+#define __NSS_VIRT_IF_STATS_H
+
+/*
+ * Virtual interface statistics APIs
+ */
+extern void nss_virt_if_stats_sync(struct nss_virt_if_handle *handle, struct nss_virt_if_stats *nwis);
+extern void nss_virt_if_stats_dentry_create(void);
+
+#endif /* __NSS_VIRT_IF_STATS_H */
diff --git a/nss_wifi.c b/nss_wifi.c
index fab4c7c..fb2ec65 100644
--- a/nss_wifi.c
+++ b/nss_wifi.c
@@ -15,63 +15,7 @@
*/
#include "nss_tx_rx_common.h"
-
-/*
- * nss_wifi_stats_sync()
- * Handle the syncing of WIFI stats.
- */
-void nss_wifi_stats_sync(struct nss_ctx_instance *nss_ctx,
- struct nss_wifi_stats_sync_msg *stats, uint16_t interface)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- uint32_t radio_id = interface - NSS_WIFI_INTERFACE0;
- int i = 0;
-
- if (radio_id >= NSS_MAX_WIFI_RADIO_INTERFACES) {
- nss_warning("%p: invalid interface: %d", nss_ctx, interface);
- return;
- }
-
- spin_lock_bh(&nss_top->stats_lock);
-
- /*
- * Tx/Rx stats
- */
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_RX_PKTS] += stats->node_stats.rx_packets;
- for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_RX_QUEUE_0_DROPPED + i] += stats->node_stats.rx_dropped[i];
- }
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TX_PKTS] += stats->node_stats.tx_packets;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TX_DROPPED] += stats->tx_transmit_dropped;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TX_COMPLETED] += stats->tx_transmit_completions;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_MGMT_RCV_CNT] += stats->tx_mgmt_rcv_cnt;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_MGMT_TX_PKTS] += stats->tx_mgmt_pkts;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_MGMT_TX_DROPPED] += stats->tx_mgmt_dropped;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_MGMT_TX_COMPLETIONS] += stats->tx_mgmt_completions;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TX_INV_PEER_ENQUEUE_CNT] += stats->tx_inv_peer_enq_cnt;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_RX_INV_PEER_RCV_CNT] += stats->rx_inv_peer_rcv_cnt;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_RX_PN_CHECK_FAILED] += stats->rx_pn_check_failed;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_RX_DELIVERED] += stats->rx_pkts_deliverd;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_RX_BYTES_DELIVERED] += stats->rx_bytes_deliverd;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TX_BYTES_COMPLETED] += stats->tx_bytes_transmit_completions;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_RX_DELIVER_UNALIGNED_DROP_CNT] += stats->rx_deliver_unaligned_drop_cnt;
-
- for (i = 0; i < NSS_WIFI_TX_NUM_TOS_TIDS; i++) {
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TIDQ_ENQUEUE_CNT + i] += stats->tidq_enqueue_cnt[i];
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TIDQ_DEQUEUE_CNT + i] += stats->tidq_dequeue_cnt[i];
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TIDQ_ENQUEUE_FAIL_CNT + i] += stats->tidq_enqueue_fail_cnt[i];
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TIDQ_TTL_EXPIRE_CNT + i] += stats->tidq_ttl_expire_cnt[i];
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TIDQ_DEQUEUE_REQ_CNT + i] += stats->tidq_dequeue_req_cnt[i];
- }
-
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_RX_HTT_FETCH_CNT] += stats->rx_htt_fetch_cnt;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TOTAL_TIDQ_DEPTH] = stats->total_tidq_depth;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TOTAL_TIDQ_BYPASS_CNT] += stats->total_tidq_bypass_cnt;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_GLOBAL_Q_FULL_CNT] += stats->global_q_full_cnt;
- nss_top->stats_wifi[radio_id][NSS_STATS_WIFI_TIDQ_FULL_CNT] += stats->tidq_full_cnt;
-
- spin_unlock_bh(&nss_top->stats_lock);
-}
+#include "nss_wifi_stats.h"
/*
* nss_wifi_get_context()
@@ -100,7 +44,7 @@
* Is this a valid request/response packet?
*/
if (ncm->type >= NSS_WIFI_MAX_MSG) {
- nss_warning("%p: received invalid message %d for wifi interface", nss_ctx, ncm->type);
+ nss_warning("%p: received invalid message %d for wifi interface", nss_ctx, ncm->type);
return;
}
@@ -273,6 +217,8 @@
nss_core_register_handler(nss_ctx, NSS_WIFI_INTERFACE0, nss_wifi_handler, NULL);
nss_core_register_handler(nss_ctx, NSS_WIFI_INTERFACE1, nss_wifi_handler, NULL);
nss_core_register_handler(nss_ctx, NSS_WIFI_INTERFACE2, nss_wifi_handler, NULL);
+
+ nss_wifi_stats_dentry_create();
}
EXPORT_SYMBOL(nss_wifi_get_context);
diff --git a/nss_wifi_if.c b/nss_wifi_if.c
index 2af86c3..451d457 100644
--- a/nss_wifi_if.c
+++ b/nss_wifi_if.c
@@ -20,6 +20,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_wifi_if_stats.h"
#include <net/arp.h>
#define NSS_WIFI_IF_TX_TIMEOUT 3000 /* 3 Seconds */
@@ -30,7 +31,7 @@
/*
* Data structure that holds the wifi interface context.
*/
-static struct nss_wifi_if_handle *wifi_handle[NSS_MAX_DYNAMIC_INTERFACES];
+struct nss_wifi_if_handle *wifi_handle[NSS_MAX_DYNAMIC_INTERFACES];
/*
* Spinlock to protect the global data structure wifi_handle.
@@ -38,24 +39,6 @@
DEFINE_SPINLOCK(wifi_if_lock);
/*
- * nss_wifi_if_stats_sync()
- * Sync stats from the NSS FW
- */
-static void nss_wifi_if_stats_sync(struct nss_wifi_if_handle *handle,
- struct nss_wifi_if_stats *nwis)
-{
- struct nss_wifi_if_stats *stats = &handle->stats;
-
- stats->node_stats.rx_packets += nwis->node_stats.rx_packets;
- stats->node_stats.rx_bytes += nwis->node_stats.rx_bytes;
- stats->node_stats.rx_dropped += nwis->node_stats.rx_dropped;
- stats->node_stats.tx_packets += nwis->node_stats.tx_packets;
- stats->node_stats.tx_bytes += nwis->node_stats.tx_bytes;
- stats->tx_enqueue_failed += nwis->tx_enqueue_failed;
- stats->shaper_enqueue_failed += nwis->shaper_enqueue_failed;
-}
-
-/*
* nss_wifi_if_msg_handler()
* Handle NSS -> HLOS messages for wifi interface
*/
@@ -159,6 +142,7 @@
nwip->sem_init_done = 1;
}
+ nss_wifi_if_stats_dentry_create();
return NSS_WIFI_IF_SUCCESS;
}
@@ -589,68 +573,3 @@
}
EXPORT_SYMBOL(nss_wifi_if_tx_buf);
-/*
- * nss_wifi_if_copy_stats()
- * Copy the stats from wifi handle to buffer(line) for if_num.
- */
-int32_t nss_wifi_if_copy_stats(int32_t if_num, int i, char *line)
-{
- int32_t bytes = 0;
- struct nss_wifi_if_stats *stats;
- int32_t ifnum;
- uint32_t len = 80;
- struct nss_wifi_if_handle *handle = NULL;
-
- ifnum = NSS_WIFI_IF_GET_INDEX(if_num);
-
- spin_lock_bh(&wifi_if_lock);
- if (!wifi_handle[ifnum]) {
- spin_unlock_bh(&wifi_if_lock);
- goto end;
- }
-
- handle = wifi_handle[ifnum];
- spin_unlock_bh(&wifi_if_lock);
-
- stats = &handle->stats;
-
- switch (i) {
- case 0:
- bytes = scnprintf(line, len, "rx_packets=%d\n",
- stats->node_stats.rx_packets);
- break;
-
- case 1:
- bytes = scnprintf(line, len, "rx_bytes=%d\n",
- stats->node_stats.rx_bytes);
- break;
-
- case 2:
- bytes = scnprintf(line, len, "rx_dropped=%d\n",
- stats->node_stats.rx_dropped);
- break;
-
- case 3:
- bytes = scnprintf(line, len, "tx_packets=%d\n",
- stats->node_stats.tx_packets);
- break;
-
- case 4:
- bytes = scnprintf(line, len, "tx_bytes=%d\n",
- stats->node_stats.tx_bytes);
- break;
-
- case 5:
- bytes = scnprintf(line, len, "tx_enqueue_failed=%d\n",
- stats->tx_enqueue_failed);
- break;
-
- case 6:
- bytes = scnprintf(line, len, "shaper_enqueue_failed=%d\n",
- stats->shaper_enqueue_failed);
- break;
- }
-
-end:
- return bytes;
-}
diff --git a/nss_wifi_if_stats.c b/nss_wifi_if_stats.c
new file mode 100644
index 0000000..aa0f758
--- /dev/null
+++ b/nss_wifi_if_stats.c
@@ -0,0 +1,207 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_wifi_if.h"
+
+/*
+ * Data structure that holds the wifi interface context.
+ */
+extern struct nss_wifi_if_handle *wifi_handle[];
+
+/*
+ * Spinlock to protect the global data structure wifi_handle.
+ */
+extern spinlock_t wifi_if_lock;
+
+/*
+ * nss_wifi_if_stats_get()
+ * Get the stats from wifi handle to buffer(line) for if_num.
+ */
+static int32_t nss_wifi_if_stats_get(int32_t if_num, int i, char *line)
+{
+ int32_t bytes = 0;
+ struct nss_wifi_if_stats *stats;
+ int32_t ifnum;
+ uint32_t len = 80;
+ struct nss_wifi_if_handle *handle = NULL;
+
+ ifnum = if_num - NSS_DYNAMIC_IF_START;
+
+ spin_lock_bh(&wifi_if_lock);
+ if (!wifi_handle[ifnum]) {
+ spin_unlock_bh(&wifi_if_lock);
+ goto end;
+ }
+
+ handle = wifi_handle[ifnum];
+ spin_unlock_bh(&wifi_if_lock);
+ stats = &handle->stats;
+
+ switch (i) {
+ case 0:
+ bytes = scnprintf(line, len, "rx_packets=%d\n",
+ stats->node_stats.rx_packets);
+ break;
+
+ case 1:
+ bytes = scnprintf(line, len, "rx_bytes=%d\n",
+ stats->node_stats.rx_bytes);
+ break;
+
+ case 2:
+ bytes = scnprintf(line, len, "rx_dropped=%d\n",
+ stats->node_stats.rx_dropped);
+ break;
+
+ case 3:
+ bytes = scnprintf(line, len, "tx_packets=%d\n",
+ stats->node_stats.tx_packets);
+ break;
+
+ case 4:
+ bytes = scnprintf(line, len, "tx_bytes=%d\n",
+ stats->node_stats.tx_bytes);
+ break;
+
+ case 5:
+ bytes = scnprintf(line, len, "tx_enqueue_failed=%d\n",
+ stats->tx_enqueue_failed);
+ break;
+
+ case 6:
+ bytes = scnprintf(line, len, "shaper_enqueue_failed=%d\n",
+ stats->shaper_enqueue_failed);
+ break;
+ }
+
+end:
+ return bytes;
+}
+
+/*
+ * nss_wifi_if_stats_read()
+ * Read wifi_if statistics
+ */
+static ssize_t nss_wifi_if_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ struct nss_stats_data *data = fp->private_data;
+ struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
+ int32_t if_num = NSS_DYNAMIC_IF_START;
+ int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
+ size_t bytes = 0;
+ ssize_t bytes_read = 0;
+ char line[80];
+ int start, end;
+
+ if (data) {
+ if_num = data->if_num;
+ }
+
+ if (if_num > max_if_num) {
+ return 0;
+ }
+
+ for (; if_num < max_if_num; if_num++) {
+ if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
+ continue;
+
+ bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
+ if ((bytes_read + bytes) > sz)
+ break;
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto end;
+ }
+
+ bytes_read += bytes;
+
+ start = 0;
+ end = 7;
+ while (bytes_read < sz && start < end) {
+ bytes = nss_wifi_if_stats_get(if_num, start, line);
+ if (!bytes)
+ break;
+
+ if ((bytes_read + bytes) > sz)
+ break;
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto end;
+ }
+
+ bytes_read += bytes;
+ start++;
+ }
+
+ bytes = scnprintf(line, sizeof(line), "if_num %d stats end:\n\n", if_num);
+ if (bytes_read > (sz - bytes))
+ break;
+
+ if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
+ bytes_read = -EFAULT;
+ goto end;
+ }
+
+ bytes_read += bytes;
+ }
+
+ if (bytes_read > 0) {
+ *ppos = bytes_read;
+ }
+
+ if (data) {
+ data->if_num = if_num;
+ }
+
+end:
+ return bytes_read;
+}
+
+/*
+ * nss_wifi_if_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(wifi_if)
+
+/*
+ * nss_wifi_if_stats_dentry_create()
+ * Create wifi_if statistics debug entry.
+ */
+void nss_wifi_if_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("wifi_if", &nss_wifi_if_stats_ops);
+}
+
+/*
+ * nss_wifi_if_stats_sync()
+ * Sync stats from the NSS FW
+ */
+void nss_wifi_if_stats_sync(struct nss_wifi_if_handle *handle,
+ struct nss_wifi_if_stats *nwis)
+{
+ struct nss_wifi_if_stats *stats = &handle->stats;
+
+ stats->node_stats.rx_packets += nwis->node_stats.rx_packets;
+ stats->node_stats.rx_bytes += nwis->node_stats.rx_bytes;
+ stats->node_stats.rx_dropped += nwis->node_stats.rx_dropped;
+ stats->node_stats.tx_packets += nwis->node_stats.tx_packets;
+ stats->node_stats.tx_bytes += nwis->node_stats.tx_bytes;
+ stats->tx_enqueue_failed += nwis->tx_enqueue_failed;
+ stats->shaper_enqueue_failed += nwis->shaper_enqueue_failed;
+}
diff --git a/nss_wifi_if_stats.h b/nss_wifi_if_stats.h
new file mode 100644
index 0000000..ffc1f83
--- /dev/null
+++ b/nss_wifi_if_stats.h
@@ -0,0 +1,26 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_WIFI_IF_STATS_H
+#define __NSS_WIFI_IF_STATS_H
+
+/*
+ * wifi interface statistics APIs
+ */
+extern void nss_wifi_if_stats_sync(struct nss_wifi_if_handle *handle, struct nss_wifi_if_stats *nwis);
+extern void nss_wifi_if_stats_dentry_create(void);
+
+#endif /* __NSS_WIFI_IF_STATS_H */
diff --git a/nss_wifi_stats.c b/nss_wifi_stats.c
new file mode 100644
index 0000000..c925f71
--- /dev/null
+++ b/nss_wifi_stats.c
@@ -0,0 +1,220 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_wifi.h"
+#include "nss_wifi_stats.h"
+
+/*
+ * nss_wifi_stats_str
+ * Wifi statistics strings
+ */
+static int8_t *nss_wifi_stats_str[NSS_WIFI_STATS_MAX] = {
+ "RX_PACKETS",
+ "RX_QUEUE_0_DROPPED",
+ "RX_QUEUE_1_DROPPED",
+ "RX_QUEUE_2_DROPPED",
+ "RX_QUEUE_3_DROPPED",
+ "TX_PACKETS",
+ "TX_DROPPED",
+ "TX_TRANSMIT_COMPLETED",
+ "TX_MGMT_RECEIVED",
+ "TX_MGMT_TRANSMITTED",
+ "TX_MGMT_DROPPED",
+ "TX_MGMT_COMPLETED",
+ "TX_INV_PEER_ENQ_CNT",
+ "RX_INV_PEER_RCV_CNT",
+ "RX_PN_CHECK_FAILED",
+ "RX_PKTS_DELIVERD",
+ "RX_BYTES_DELIVERED",
+ "TX_BYTES_COMPLETED",
+ "RX_DELIVER_UNALIGNED_DROP_CNT",
+ "TIDQ_ENQUEUE_CNT_0",
+ "TIDQ_ENQUEUE_CNT_1",
+ "TIDQ_ENQUEUE_CNT_2",
+ "TIDQ_ENQUEUE_CNT_3",
+ "TIDQ_ENQUEUE_CNT_4",
+ "TIDQ_ENQUEUE_CNT_5",
+ "TIDQ_ENQUEUE_CNT_6",
+ "TIDQ_ENQUEUE_CNT_7",
+ "TIDQ_DEQUEUE_CNT_0",
+ "TIDQ_DEQUEUE_CNT_1",
+ "TIDQ_DEQUEUE_CNT_2",
+ "TIDQ_DEQUEUE_CNT_3",
+ "TIDQ_DEQUEUE_CNT_4",
+ "TIDQ_DEQUEUE_CNT_5",
+ "TIDQ_DEQUEUE_CNT_6",
+ "TIDQ_DEQUEUE_CNT_7",
+ "TIDQ_ENQUEUE_FAIL_CNT_0",
+ "TIDQ_ENQUEUE_FAIL_CNT_1",
+ "TIDQ_ENQUEUE_FAIL_CNT_2",
+ "TIDQ_ENQUEUE_FAIL_CNT_3",
+ "TIDQ_ENQUEUE_FAIL_CNT_4",
+ "TIDQ_ENQUEUE_FAIL_CNT_5",
+ "TIDQ_ENQUEUE_FAIL_CNT_6",
+ "TIDQ_ENQUEUE_FAIL_CNT_7",
+ "TIDQ_TTL_EXPIRE_CNT_0",
+ "TIDQ_TTL_EXPIRE_CNT_1",
+ "TIDQ_TTL_EXPIRE_CNT_2",
+ "TIDQ_TTL_EXPIRE_CNT_3",
+ "TIDQ_TTL_EXPIRE_CNT_4",
+ "TIDQ_TTL_EXPIRE_CNT_5",
+ "TIDQ_TTL_EXPIRE_CNT_6",
+ "TIDQ_TTL_EXPIRE_CNT_7",
+ "TIDQ_DEQUEUE_REQ_CNT_0",
+ "TIDQ_DEQUEUE_REQ_CNT_1",
+ "TIDQ_DEQUEUE_REQ_CNT_2",
+ "TIDQ_DEQUEUE_REQ_CNT_3",
+ "TIDQ_DEQUEUE_REQ_CNT_4",
+ "TIDQ_DEQUEUE_REQ_CNT_5",
+ "TIDQ_DEQUEUE_REQ_CNT_6",
+ "TIDQ_DEQUEUE_REQ_CNT_7",
+ "TOTAL_TIDQ_DEPTH",
+ "RX_HTT_FETCH_CNT",
+ "TOTAL_TIDQ_BYPASS_CNT",
+ "GLOBAL_Q_FULL_CNT",
+ "TIDQ_FULL_CNT",
+};
+
+uint64_t nss_wifi_stats[NSS_MAX_WIFI_RADIO_INTERFACES][NSS_WIFI_STATS_MAX]; /* WIFI statistics */
+
+/*
+ * nss_wifi_stats_read()
+ * Read wifi statistics
+ */
+static ssize_t nss_wifi_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ uint32_t i, id;
+
+ /*
+ * max output lines = ((#stats + start tag + one blank) * #WIFI RADIOs) + start/end tag + 3 blank
+ */
+ uint32_t max_output_lines = ((NSS_WIFI_STATS_MAX + 2) * NSS_MAX_WIFI_RADIO_INTERFACES) + 5;
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ stats_shadow = kzalloc(NSS_WIFI_STATS_MAX * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "wifi stats start:\n\n");
+
+ for (id = 0; id < NSS_MAX_WIFI_RADIO_INTERFACES; id++) {
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (i = 0; (i < NSS_WIFI_STATS_MAX); i++) {
+ stats_shadow[i] = nss_wifi_stats[id][i];
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "WIFI ID: %d\n", id);
+ for (i = 0; (i < NSS_WIFI_STATS_MAX); i++) {
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_wifi_stats_str[i], stats_shadow[i]);
+ }
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+ }
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nwifi stats end\n\n");
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * nss_wifi_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(wifi)
+
+/*
+ * nss_wifi_stats_dentry_create()
+ * Create wifi statistics debug entry.
+ */
+void nss_wifi_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("wifi", &nss_wifi_stats_ops);
+}
+
+/*
+ * nss_wifi_stats_sync()
+ * Handle the syncing of WIFI stats.
+ */
+void nss_wifi_stats_sync(struct nss_ctx_instance *nss_ctx,
+ struct nss_wifi_stats_sync_msg *stats, uint16_t interface)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ uint32_t radio_id = interface - NSS_WIFI_INTERFACE0;
+ uint8_t i = 0;
+
+ if (radio_id >= NSS_MAX_WIFI_RADIO_INTERFACES) {
+ nss_warning("%p: invalid interface: %d", nss_ctx, interface);
+ return;
+ }
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ /*
+ * Tx/Rx stats
+ */
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_PKTS] += stats->node_stats.rx_packets;
+ for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_QUEUE_0_DROPPED + i] += stats->node_stats.rx_dropped[i];
+ }
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TX_PKTS] += stats->node_stats.tx_packets;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TX_DROPPED] += stats->tx_transmit_dropped;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TX_COMPLETED] += stats->tx_transmit_completions;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_MGMT_RCV_CNT] += stats->tx_mgmt_rcv_cnt;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_MGMT_TX_PKTS] += stats->tx_mgmt_pkts;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_MGMT_TX_DROPPED] += stats->tx_mgmt_dropped;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_MGMT_TX_COMPLETIONS] += stats->tx_mgmt_completions;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TX_INV_PEER_ENQUEUE_CNT] += stats->tx_inv_peer_enq_cnt;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_INV_PEER_RCV_CNT] += stats->rx_inv_peer_rcv_cnt;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_PN_CHECK_FAILED] += stats->rx_pn_check_failed;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_DELIVERED] += stats->rx_pkts_deliverd;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_BYTES_DELIVERED] += stats->rx_bytes_deliverd;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TX_BYTES_COMPLETED] += stats->tx_bytes_transmit_completions;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_DELIVER_UNALIGNED_DROP_CNT] += stats->rx_deliver_unaligned_drop_cnt;
+
+ for (i = 0; i < NSS_WIFI_TX_NUM_TOS_TIDS; i++) {
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_ENQUEUE_CNT + i] += stats->tidq_enqueue_cnt[i];
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_DEQUEUE_CNT + i] += stats->tidq_dequeue_cnt[i];
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_ENQUEUE_FAIL_CNT + i] += stats->tidq_enqueue_fail_cnt[i];
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_TTL_EXPIRE_CNT + i] += stats->tidq_ttl_expire_cnt[i];
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_DEQUEUE_REQ_CNT + i] += stats->tidq_dequeue_req_cnt[i];
+ }
+
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_HTT_FETCH_CNT] += stats->rx_htt_fetch_cnt;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TOTAL_TIDQ_DEPTH] = stats->total_tidq_depth;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TOTAL_TIDQ_BYPASS_CNT] += stats->total_tidq_bypass_cnt;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_GLOBAL_Q_FULL_CNT] += stats->global_q_full_cnt;
+ nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_FULL_CNT] += stats->tidq_full_cnt;
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
diff --git a/nss_wifi_stats.h b/nss_wifi_stats.h
new file mode 100644
index 0000000..7827777
--- /dev/null
+++ b/nss_wifi_stats.h
@@ -0,0 +1,62 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_WIFI_STATS_H
+#define __NSS_WIFI_STATS_H
+
+/*
+ * wifi statistics
+ */
+enum nss_wifi_stats_types {
+ NSS_WIFI_STATS_RX_PKTS,
+ NSS_WIFI_STATS_RX_QUEUE_0_DROPPED,
+ NSS_WIFI_STATS_RX_QUEUE_1_DROPPED,
+ NSS_WIFI_STATS_RX_QUEUE_2_DROPPED,
+ NSS_WIFI_STATS_RX_QUEUE_3_DROPPED,
+ NSS_WIFI_STATS_TX_PKTS,
+ NSS_WIFI_STATS_TX_DROPPED,
+ NSS_WIFI_STATS_TX_COMPLETED,
+ NSS_WIFI_STATS_MGMT_RCV_CNT,
+ NSS_WIFI_STATS_MGMT_TX_PKTS,
+ NSS_WIFI_STATS_MGMT_TX_DROPPED,
+ NSS_WIFI_STATS_MGMT_TX_COMPLETIONS,
+ NSS_WIFI_STATS_TX_INV_PEER_ENQUEUE_CNT,
+ NSS_WIFI_STATS_RX_INV_PEER_RCV_CNT,
+ NSS_WIFI_STATS_RX_PN_CHECK_FAILED,
+ NSS_WIFI_STATS_RX_DELIVERED,
+ NSS_WIFI_STATS_RX_BYTES_DELIVERED,
+ NSS_WIFI_STATS_TX_BYTES_COMPLETED,
+ NSS_WIFI_STATS_RX_DELIVER_UNALIGNED_DROP_CNT,
+ NSS_WIFI_STATS_TIDQ_ENQUEUE_CNT,
+ NSS_WIFI_STATS_TIDQ_DEQUEUE_CNT = NSS_WIFI_STATS_TIDQ_ENQUEUE_CNT + 8,
+ NSS_WIFI_STATS_TIDQ_ENQUEUE_FAIL_CNT = NSS_WIFI_STATS_TIDQ_DEQUEUE_CNT + 8,
+ NSS_WIFI_STATS_TIDQ_TTL_EXPIRE_CNT = NSS_WIFI_STATS_TIDQ_ENQUEUE_FAIL_CNT + 8,
+ NSS_WIFI_STATS_TIDQ_DEQUEUE_REQ_CNT = NSS_WIFI_STATS_TIDQ_TTL_EXPIRE_CNT + 8,
+ NSS_WIFI_STATS_TOTAL_TIDQ_DEPTH = NSS_WIFI_STATS_TIDQ_DEQUEUE_REQ_CNT + 8,
+ NSS_WIFI_STATS_RX_HTT_FETCH_CNT,
+ NSS_WIFI_STATS_TOTAL_TIDQ_BYPASS_CNT,
+ NSS_WIFI_STATS_GLOBAL_Q_FULL_CNT,
+ NSS_WIFI_STATS_TIDQ_FULL_CNT,
+ NSS_WIFI_STATS_MAX,
+};
+
+/*
+ * wifi statistics APIs
+ */
+extern void nss_wifi_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_wifi_stats_sync_msg *stats, uint16_t interface);
+extern void nss_wifi_stats_dentry_create(void);
+
+#endif /* __NSS_WIFI_STATS_H */
diff --git a/nss_wifili.c b/nss_wifili.c
index 3070e87..abb40a3 100644
--- a/nss_wifili.c
+++ b/nss_wifili.c
@@ -15,6 +15,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_wifili_stats.h"
#define NSS_WIFILI_TX_TIMEOUT 1000 /* Millisecond to jiffies*/
@@ -31,174 +32,6 @@
} wifili_pvt;
/*
- * nss_wifili_stats_sync()
- * Handle the syncing of WIFI stats.
- */
-static void nss_wifili_stats_sync(struct nss_ctx_instance *nss_ctx,
- struct nss_wifili_stats_sync_msg *wlsoc_stats, uint16_t interface)
-{
- struct nss_top_instance *nss_top = nss_ctx->nss_top;
- struct nss_wifili_stats *stats = &nss_top->stats_wifili;
- struct nss_wifili_device_stats *devstats = &wlsoc_stats->stats;
- uint32_t index;
-
- spin_lock_bh(&nss_top->stats_lock);
-
- for (index = 0; index < NSS_WIFILI_MAX_PDEV_NUM_MSG; index++) {
- /*
- * Rx stats
- */
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_MSDU_ERROR] +=
- devstats->rx_data_stats[index].rx_msdu_err;
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_INV_PEER_RCV] +=
- (devstats->rx_data_stats[index].rx_inv_peer +
- devstats->rx_data_stats[index].rx_scatter_inv_peer);
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_WDS_SRCPORT_EXCEPTION] +=
- devstats->rx_data_stats[index].rx_wds_learn_send;
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_WDS_SRCPORT_EXCEPTION_FAIL] +=
- devstats->rx_data_stats[index].rx_wds_learn_send_fail;
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_DELIVERD] +=
- devstats->rx_data_stats[index].rx_deliver_cnt;
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_DELIVER_DROPPED] +=
- devstats->rx_data_stats[index].rx_deliver_cnt_fail;
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_INTRA_BSS_UCAST] +=
- devstats->rx_data_stats[index].rx_intra_bss_ucast_send;
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_INTRA_BSS_UCAST_FAIL] +=
- devstats->rx_data_stats[index].rx_intra_bss_ucast_send_fail;
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_INTRA_BSS_MCAST] +=
- devstats->rx_data_stats[index].rx_intra_bss_mcast_send;
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_INTRA_BSS_MCAST_FAIL] +=
- devstats->rx_data_stats[index].rx_intra_bss_mcast_send_fail;
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_SG_RCV_SEND] +=
- devstats->rx_data_stats[index].rx_sg_recv_send;
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_SG_RCV_FAIL] +=
- devstats->rx_data_stats[index].rx_sg_recv_fail;
- stats->stats_txrx[index][NSS_STATS_WIFILI_RX_MCAST_ECHO] +=
- devstats->rx_data_stats[index].rx_me_pkts;
-
- /*
- * Tx stats
- */
- stats->stats_txrx[index][NSS_STATS_WIFILI_TX_ENQUEUE] +=
- devstats->tx_data_stats[index].tx_enqueue_cnt;
- stats->stats_txrx[index][NSS_STATS_WIFILI_TX_ENQUEUE_DROP] +=
- devstats->tx_data_stats[index].tx_enqueue_dropped;
- stats->stats_txrx[index][NSS_STATS_WIFILI_TX_DEQUEUE] +=
- devstats->tx_data_stats[index].tx_dequeue_cnt;
- stats->stats_txrx[index][NSS_STATS_WIFILI_TX_HW_ENQUEUE_FAIL] +=
- devstats->tx_data_stats[index].tx_send_fail_cnt;
- stats->stats_txrx[index][NSS_STATS_WIFILI_TX_SENT_COUNT] +=
- devstats->tx_data_stats[index].tx_processed_pkt;
- }
-
- /*
- * update the tcl ring stats
- */
- for (index = 0; index < NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG; index++) {
- stats->stats_tcl_ring[index][NSS_STATS_WIFILI_TCL_NO_HW_DESC] +=
- devstats->tcl_stats[index].tcl_no_hw_desc;
- stats->stats_tcl_ring[index][NSS_STATS_WIFILI_TCL_RING_FULL] +=
- devstats->tcl_stats[index].tcl_ring_full;
- stats->stats_tcl_ring[index][NSS_STATS_WIFILI_TCL_RING_SENT] +=
- devstats->tcl_stats[index].tcl_ring_sent;
- }
-
- /*
- * update the tcl comp stats
- */
- for (index = 0; index < NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG; index++) {
- stats->stats_tx_comp[index][NSS_STATS_WIFILI_TX_DESC_FREE_INV_BUFSRC] +=
- devstats->txcomp_stats[index].invalid_bufsrc;
- stats->stats_tx_comp[index][NSS_STATS_WIFILI_TX_DESC_FREE_INV_COOKIE] +=
- devstats->txcomp_stats[index].invalid_cookie;
- stats->stats_tx_comp[index][NSS_STATS_WIFILI_TX_DESC_FREE_HW_RING_EMPTY] +=
- devstats->txcomp_stats[index].hw_ring_empty;
- stats->stats_tx_comp[index][NSS_STATS_WIFILI_TX_DESC_FREE_REAPED] +=
- devstats->txcomp_stats[index].ring_reaped;
- }
-
- /*
- * update reo ring stats
- */
- for (index = 0; index < NSS_WIFILI_MAX_REO_DATA_RINGS_MSG; index++) {
- stats->stats_reo[index][NSS_STATS_WIFILI_REO_ERROR] +=
- devstats->rxreo_stats[index].ring_error;
- stats->stats_reo[index][NSS_STATS_WIFILI_REO_REAPED] +=
- devstats->rxreo_stats[index].ring_reaped;
- stats->stats_reo[index][NSS_STATS_WIFILI_REO_INV_COOKIE] +=
- devstats->rxreo_stats[index].invalid_cookie;
- }
-
- /*
- * update tx sw pool
- */
- for (index = 0; index < NSS_WIFILI_MAX_TXDESC_POOLS_MSG; index++) {
- stats->stats_tx_desc[index][NSS_STATS_WIFILI_TX_DESC_IN_USE] =
- devstats->tx_sw_pool_stats[index].desc_alloc;
- stats->stats_tx_desc[index][NSS_STATS_WIFILI_TX_DESC_ALLOC_FAIL] +=
- devstats->tx_sw_pool_stats[index].desc_alloc_fail;
- stats->stats_tx_desc[index][NSS_STATS_WIFILI_TX_DESC_ALREADY_ALLOCATED] +=
- devstats->tx_sw_pool_stats[index].desc_already_allocated;
- stats->stats_tx_desc[index][NSS_STATS_WIFILI_TX_DESC_INVALID_FREE] +=
- devstats->tx_sw_pool_stats[index].desc_invalid_free;
- stats->stats_tx_desc[index][NSS_STATS_WIFILI_TX_DESC_FREE_SRC_FW] +=
- devstats->tx_sw_pool_stats[index].tx_rel_src_fw;
- stats->stats_tx_desc[index][NSS_STATS_WIFILI_TX_DESC_FREE_COMPLETION] +=
- devstats->tx_sw_pool_stats[index].tx_rel_tx_desc;
- stats->stats_tx_desc[index][NSS_STATS_WIFILI_TX_DESC_NO_PB] +=
- devstats->tx_sw_pool_stats[index].tx_rel_no_pb;
- }
-
- /*
- * update ext tx desc pool stats
- */
- for (index = 0; index < NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG; index++) {
- stats->stats_ext_tx_desc[index][NSS_STATS_WIFILI_EXT_TX_DESC_IN_USE] =
- devstats->tx_ext_sw_pool_stats[index].desc_alloc;
- stats->stats_ext_tx_desc[index][NSS_STATS_WIFILI_EXT_TX_DESC_ALLOC_FAIL] +=
- devstats->tx_ext_sw_pool_stats[index].desc_alloc_fail;
- stats->stats_ext_tx_desc[index][NSS_STATS_WIFILI_EXT_TX_DESC_ALREADY_ALLOCATED] +=
- devstats->tx_ext_sw_pool_stats[index].desc_already_allocated;
- stats->stats_ext_tx_desc[index][NSS_STATS_WIFILI_EXT_TX_DESC_INVALID_FREE] +=
- devstats->tx_ext_sw_pool_stats[index].desc_invalid_free;
- }
-
- /*
- * update rx desc pool stats
- */
- for (index = 0; index < NSS_WIFILI_MAX_PDEV_NUM_MSG; index++) {
- stats->stats_rx_desc[index][NSS_STATS_WIFILI_RX_DESC_NO_PB] +=
- devstats->rx_sw_pool_stats[index].rx_no_pb;
- stats->stats_rx_desc[index][NSS_STATS_WIFILI_RX_DESC_ALLOC_FAIL] +=
- devstats->rx_sw_pool_stats[index].desc_alloc_fail;
- stats->stats_rx_desc[index][NSS_STATS_WIFILI_RX_DESC_IN_USE] =
- devstats->rx_sw_pool_stats[index].desc_alloc;
- }
-
- /*
- * update rx dma ring stats
- */
- for (index = 0; index < NSS_WIFILI_MAX_PDEV_NUM_MSG; index++) {
- stats->stats_rxdma[index][NSS_STATS_WIFILI_RXDMA_DESC_UNAVAILABLE] +=
- devstats->rxdma_stats[index].rx_hw_desc_unavailable;
- stats->stats_rxdma[index][NSS_STATS_WIFILI_RXDMA_BUF_REPLENISHED] +=
- devstats->rxdma_stats[index].rx_buf_replenished;
- }
-
- /*
- * update wbm ring stats
- */
- stats->stats_wbm[NSS_STATS_WIFILI_WBM_SRC_DMA] += devstats->rxwbm_stats.err_src_rxdma;
- stats->stats_wbm[NSS_STATS_WIFILI_WBM_SRC_DMA_CODE_INV] += devstats->rxwbm_stats.err_src_rxdma_code_inv;
- stats->stats_wbm[NSS_STATS_WIFILI_WBM_SRC_REO] += devstats->rxwbm_stats.err_src_reo;
- stats->stats_wbm[NSS_STATS_WIFILI_WBM_SRC_REO_CODE_NULLQ] += devstats->rxwbm_stats.err_src_reo_code_nullq;
- stats->stats_wbm[NSS_STATS_WIFILI_WBM_SRC_REO_CODE_INV] += devstats->rxwbm_stats.err_src_reo_code_inv;
- stats->stats_wbm[NSS_STATS_WIFILI_WBM_SRC_INV] += devstats->rxwbm_stats.err_src_invalid;
- spin_unlock_bh(&nss_top->stats_lock);
- return;
-}
-
-/*
* nss_wifili_handler()
* Handle NSS -> HLOS messages for wifi
*/
@@ -521,6 +354,8 @@
nss_info("nss_wifili_register_handler");
nss_core_register_handler(nss_ctx, NSS_WIFILI_INTERFACE, nss_wifili_handler, NULL);
+ nss_wifili_stats_dentry_create();
+
sema_init(&wifili_pvt.sem, 1);
init_completion(&wifili_pvt.complete);
}
diff --git a/nss_wifili_stats.c b/nss_wifili_stats.c
new file mode 100644
index 0000000..7d02d71
--- /dev/null
+++ b/nss_wifili_stats.c
@@ -0,0 +1,498 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_wifili_stats.c
+ * NSS wifili statistics APIs
+ */
+
+#include "nss_tx_rx_common.h"
+#include "nss_core.h"
+#include "nss_stats.h"
+#include "nss_wifili_if.h"
+#include "nss_wifili_stats.h"
+
+/*
+ * Maximum string length:
+ * This should be equal to maximum string size of any stats
+ * inclusive of stats value
+ */
+#define NSS_WIFILI_STATS_MAX (NSS_WIFILI_STATS_TXRX_MAX + NSS_WIFILI_STATS_TCL_MAX + \
+ NSS_WIFILI_STATS_TX_DESC_FREE_MAX + NSS_WIFILI_STATS_REO_MAX + \
+ NSS_WIFILI_STATS_TX_DESC_MAX + NSS_WIFILI_STATS_EXT_TX_DESC_MAX + \
+ NSS_WIFILI_STATS_RX_DESC_MAX + NSS_WIFILI_STATS_RXDMA_DESC_MAX)
+
+/*
+ * Statistics structures
+ */
+struct nss_wifili_stats stats_wifili;
+
+/*
+ * nss_wifili_stats_str_txrx
+ * wifili txrx statistics
+ */
+static int8_t *nss_wifili_stats_str_txrx[NSS_WIFILI_STATS_TXRX_MAX] = {
+ "WIFILI_RX_MSDU_ERROR",
+ "WIFILI_RX_INV_PEER_RCV",
+ "WIFILI_RX_WDS_SRCPORT_EXCEPTION",
+ "WIFILI_RX_WDS_SRCPORT_EXCEPTION_FAIL",
+ "WIFILI_RX_DELIVERD",
+ "WIFILI_RX_DELIVER_DROPPED",
+ "WIFILI_RX_INTRA_BSS_UCAST",
+ "WIFILI_RX_INTRA_BSS_UCAST_FAIL",
+ "WIFILI_RX_INTRA_BSS_MCAST",
+ "WIFILI_RX_INTRA_BSS_MCAST_FAIL",
+ "WIFILI_RX_SG_RCV_SEND",
+ "WIFILI_RX_SG_RCV_FAIL",
+ "WIFILI_RX_MCAST_ECHO",
+ "WIFILI_TX_ENQUEUE",
+ "WIFILI_TX_ENQUEUE_DROP",
+ "WIFILI_TX_DEQUEUE",
+ "WIFILI_TX_HW_ENQUEUE_FAIL",
+ "WIFILI_TX_SENT_COUNT",
+};
+
+/*
+ * nss_wifili_stats_str_tcl
+ * wifili tcl stats
+ */
+static int8_t *nss_wifili_stats_str_tcl[NSS_WIFILI_STATS_TCL_MAX] = {
+ "WIFILI_TCL_NO_HW_DESC",
+ "WIFILI_TCL_RING_FULL",
+ "WIFILI_TCL_RING_SENT",
+};
+
+/*
+ * nss_wifili_stats_str_tx_comp
+ * wifili tx comp stats
+ */
+static int8_t *nss_wifili_stats_str_tx_comp[NSS_WIFILI_STATS_TX_DESC_FREE_MAX] = {
+ "WIFILI_TX_DESC_FREE_INV_BUFSRC",
+ "WIFILI_TX_DESC_FREE_INV_COOKIE",
+ "WIFILI_TX_DESC_FREE_HW_RING_EMPTY",
+ "WIFILI_TX_DESC_FREE_REAPED",
+};
+
+/*
+ * nss_wifili_stats_str_reo
+ * wifili tx reo stats
+ */
+static int8_t *nss_wifili_stats_str_reo[NSS_WIFILI_STATS_REO_MAX] = {
+ "WIFILI_REO_ERROR",
+ "WIFILI_REO_REAPED",
+ "WIFILI_REO_INV_COOKIE",
+};
+
+/*
+ * nss_wifili_stats_str_txsw_pool
+ * wifili tx desc stats
+ */
+static int8_t *nss_wifili_stats_str_txsw_pool[NSS_WIFILI_STATS_TX_DESC_MAX] = {
+ "WIFILI_TX_DESC_IN_USE",
+ "WIFILI_TX_DESC_ALLOC_FAIL",
+ "WIFILI_TX_DESC_ALREADY_ALLOCATED",
+ "WIFILI_TX_DESC_INVALID_FREE",
+ "WIFILI_TX_DESC_FREE_SRC_FW",
+ "WIFILI_TX_DESC_FREE_COMPLETION",
+ "WIFILI_TX_DESC_NO_PB",
+};
+
+/*
+ * nss_wifili_stats_str_ext_txsw_pool
+ * wifili tx ext desc stats
+ */
+static uint8_t *nss_wifili_stats_str_ext_txsw_pool[NSS_WIFILI_STATS_EXT_TX_DESC_MAX] = {
+ "WIFILI_EXT_TX_DESC_IN_USE",
+ "WIFILI_EXT_TX_DESC_ALLOC_FAIL",
+ "WIFILI_EXT_TX_DESC_ALREADY_ALLOCATED",
+ "WIFILI_EXT_TX_DESC_INVALID_FREE",
+};
+
+/*
+ * nss_wifili_stats_str_rxdma_pool
+ * wifili rx desc stats
+ */
+static int8_t *nss_wifili_stats_str_rxdma_pool[NSS_WIFILI_STATS_RX_DESC_MAX] = {
+ "WIFILI_RX_DESC_NO_PB",
+ "WIFILI_RX_DESC_ALLOC_FAIL",
+ "WIFILI_RX_DESC_IN_USE",
+};
+
+/*
+ * nss_wifili_stats_str_rxdma_ring
+ * wifili rx dma ring stats
+ */
+static int8_t *nss_wifili_stats_str_rxdma_ring[NSS_WIFILI_STATS_RXDMA_DESC_MAX] = {
+ "WIFILI_RXDMA_HW_DESC_UNAVAILABLE",
+ "WIFILI_RXDMA_BUF_REPLENISHED",
+};
+
+/*
+ * nss_wifili_stats_str_wbm
+ * wifili wbm ring stats
+ */
+static int8_t *nss_wifili_stats_str_wbm[NSS_WIFILI_STATS_WBM_MAX] = {
+ "WIFILI_WBM_SRC_DMA",
+ "WIFILI_WBM_SRC_DMA_CODE_INV",
+ "WIFILI_WBM_SRC_REO",
+ "WIFILI_WBM_SRC_REO_CODE_NULLQ",
+ "WIFILI_WBM_SRC_REO_CODE_INV",
+ "WIFILI_WBM_SRC_INV",
+};
+
+/*
+ * nss_wifili_stats_read()
+ * Read wifili statistics
+ */
+static ssize_t nss_wifili_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ uint32_t i, j;
+
+ /*
+ * max output lines = ((#stats + eight blank lines) * #WIFILI #STATS) + start/end tag + 3 blank
+ */
+ uint32_t max_output_lines = (((NSS_WIFILI_STATS_MAX + 9) * NSS_WIFILI_MAX_PDEV_NUM_MSG)+
+ NSS_WIFILI_STATS_WBM_MAX + 5);
+ size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
+ size_t size_wr = 0;
+ ssize_t bytes_read = 0;
+ uint64_t *stats_shadow;
+
+ char *lbuf = kzalloc(size_al, GFP_KERNEL);
+ if (unlikely(lbuf == NULL)) {
+ nss_warning("Could not allocate memory for local statistics buffer");
+ return 0;
+ }
+
+ /*
+ * Take max of all wifili stats
+ *
+ * NOTE: txrx stats is bigger of all stats
+ */
+ stats_shadow = kzalloc(NSS_WIFILI_STATS_TXRX_MAX * 8, GFP_KERNEL);
+ if (unlikely(stats_shadow == NULL)) {
+ nss_warning("Could not allocate memory for local shadow buffer");
+ kfree(lbuf);
+ return 0;
+ }
+
+ size_wr = scnprintf(lbuf, size_al, "wifili stats start:\n\n");
+
+ for (i = 0; i < NSS_WIFILI_MAX_PDEV_NUM_MSG; i++) {
+
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "WIFILI ID: %d\n", i);
+
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (j = 0; (j < NSS_WIFILI_STATS_TXRX_MAX); j++) {
+ stats_shadow[j] = stats_wifili.stats_txrx[i][j];
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_wifili_stats_str_txrx[j], stats_shadow[j]);
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+
+ /*
+ * Fillinng TCL ring stats
+ */
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (j = 0; (j < NSS_WIFILI_STATS_TCL_MAX); j++) {
+ stats_shadow[j] = stats_wifili.stats_tcl_ring[i][j];
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_wifili_stats_str_tcl[j], stats_shadow[j]);
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+
+ /*
+ * Fillinng TCL comp stats
+ */
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (j = 0; (j < NSS_WIFILI_STATS_TX_DESC_FREE_MAX); j++) {
+ stats_shadow[j] = stats_wifili.stats_tx_comp[i][j];
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_wifili_stats_str_tx_comp[j], stats_shadow[j]);
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+
+ /*
+ * Fillinng reo ring stats
+ */
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (j = 0; (j < NSS_WIFILI_STATS_REO_MAX); j++) {
+ stats_shadow[j] = stats_wifili.stats_reo[i][j];
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_wifili_stats_str_reo[j], stats_shadow[j]);
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+
+ /*
+ * Fillinng TX SW Pool
+ */
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (j = 0; (j < NSS_WIFILI_STATS_TX_DESC_MAX); j++) {
+ stats_shadow[j] = stats_wifili.stats_tx_desc[i][j];
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_wifili_stats_str_txsw_pool[j], stats_shadow[j]);
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+
+ /*
+ * Fillinng TX EXt SW Pool
+ */
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (j = 0; (j < NSS_WIFILI_STATS_EXT_TX_DESC_MAX); j++) {
+ stats_shadow[j] = stats_wifili.stats_ext_tx_desc[i][j];
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_wifili_stats_str_ext_txsw_pool[j], stats_shadow[j]);
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+
+ /*
+ * Fillinng rxdma pool stats
+ */
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (j = 0; (j < NSS_WIFILI_STATS_RX_DESC_MAX); j++) {
+ stats_shadow[j] = stats_wifili.stats_rx_desc[i][j];
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_wifili_stats_str_rxdma_pool[j], stats_shadow[j]);
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+
+ /*
+ * Fillinng rxdma ring stats
+ */
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (j = 0; (j < NSS_WIFILI_STATS_RXDMA_DESC_MAX); j++) {
+ stats_shadow[j] = stats_wifili.stats_rxdma[i][j];
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_wifili_stats_str_rxdma_ring[j], stats_shadow[j]);
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
+
+ }
+
+ /*
+ * Fillinng wbm ring stats
+ */
+ spin_lock_bh(&nss_top_main.stats_lock);
+ for (j = 0; (j < NSS_WIFILI_STATS_WBM_MAX); j++) {
+ stats_shadow[j] = stats_wifili.stats_wbm[j];
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
+ "%s = %llu\n", nss_wifili_stats_str_wbm[j], stats_shadow[j]);
+ }
+
+ spin_unlock_bh(&nss_top_main.stats_lock);
+ size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nwifili stats end\n\n");
+
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
+ kfree(lbuf);
+ kfree(stats_shadow);
+
+ return bytes_read;
+}
+
+/*
+ * wifili_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(wifili)
+
+/*
+ * nss_wifili_stats_dentry_create()
+ * Create wifili statistics debug entry.
+ */
+void nss_wifili_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("wifili", &nss_wifili_stats_ops);
+}
+
+/*
+ * nss_wifili_stats_sync()
+ * Handle the syncing of WIFI stats.
+ */
+void nss_wifili_stats_sync(struct nss_ctx_instance *nss_ctx,
+ struct nss_wifili_stats_sync_msg *wlsoc_stats, uint16_t interface)
+{
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ struct nss_wifili_stats *stats = &stats_wifili;
+ struct nss_wifili_device_stats *devstats = &wlsoc_stats->stats;
+ uint32_t index;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ for (index = 0; index < NSS_WIFILI_MAX_PDEV_NUM_MSG; index++) {
+ /*
+ * Rx stats
+ */
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_MSDU_ERROR] +=
+ devstats->rx_data_stats[index].rx_msdu_err;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_INV_PEER_RCV] +=
+ (devstats->rx_data_stats[index].rx_inv_peer +
+ devstats->rx_data_stats[index].rx_scatter_inv_peer);
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_WDS_SRCPORT_EXCEPTION] +=
+ devstats->rx_data_stats[index].rx_wds_learn_send;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_WDS_SRCPORT_EXCEPTION_FAIL] +=
+ devstats->rx_data_stats[index].rx_wds_learn_send_fail;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_DELIVERD] +=
+ devstats->rx_data_stats[index].rx_deliver_cnt;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_DELIVER_DROPPED] +=
+ devstats->rx_data_stats[index].rx_deliver_cnt_fail;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_INTRA_BSS_UCAST] +=
+ devstats->rx_data_stats[index].rx_intra_bss_ucast_send;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_INTRA_BSS_UCAST_FAIL] +=
+ devstats->rx_data_stats[index].rx_intra_bss_ucast_send_fail;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_INTRA_BSS_MCAST] +=
+ devstats->rx_data_stats[index].rx_intra_bss_mcast_send;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_INTRA_BSS_MCAST_FAIL] +=
+ devstats->rx_data_stats[index].rx_intra_bss_mcast_send_fail;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_SG_RCV_SEND] +=
+ devstats->rx_data_stats[index].rx_sg_recv_send;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_RX_SG_RCV_FAIL] +=
+ devstats->rx_data_stats[index].rx_sg_recv_fail;
+
+ /*
+ * Tx stats
+ */
+ stats->stats_txrx[index][NSS_WIFILI_STATS_TX_ENQUEUE] +=
+ devstats->tx_data_stats[index].tx_enqueue_cnt;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_TX_ENQUEUE_DROP] +=
+ devstats->tx_data_stats[index].tx_enqueue_dropped;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_TX_DEQUEUE] +=
+ devstats->tx_data_stats[index].tx_dequeue_cnt;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_TX_HW_ENQUEUE_FAIL] +=
+ devstats->tx_data_stats[index].tx_send_fail_cnt;
+ stats->stats_txrx[index][NSS_WIFILI_STATS_TX_SENT_COUNT] +=
+ devstats->tx_data_stats[index].tx_processed_pkt;
+ }
+
+ /*
+ * update the tcl ring stats
+ */
+ for (index = 0; index < NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG; index++) {
+ stats->stats_tcl_ring[index][NSS_WIFILI_STATS_TCL_NO_HW_DESC] +=
+ devstats->tcl_stats[index].tcl_no_hw_desc;
+ stats->stats_tcl_ring[index][NSS_WIFILI_STATS_TCL_RING_FULL] +=
+ devstats->tcl_stats[index].tcl_ring_full;
+ stats->stats_tcl_ring[index][NSS_WIFILI_STATS_TCL_RING_SENT] +=
+ devstats->tcl_stats[index].tcl_ring_sent;
+ }
+
+ /*
+ * update the tcl comp stats
+ */
+ for (index = 0; index < NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG; index++) {
+ stats->stats_tx_comp[index][NSS_WIFILI_STATS_TX_DESC_FREE_INV_BUFSRC] +=
+ devstats->txcomp_stats[index].invalid_bufsrc;
+ stats->stats_tx_comp[index][NSS_WIFILI_STATS_TX_DESC_FREE_INV_COOKIE] +=
+ devstats->txcomp_stats[index].invalid_cookie;
+ stats->stats_tx_comp[index][NSS_WIFILI_STATS_TX_DESC_FREE_HW_RING_EMPTY] +=
+ devstats->txcomp_stats[index].hw_ring_empty;
+ stats->stats_tx_comp[index][NSS_WIFILI_STATS_TX_DESC_FREE_REAPED] +=
+ devstats->txcomp_stats[index].ring_reaped;
+ }
+
+ /*
+ * update reo ring stats
+ */
+ for (index = 0; index < NSS_WIFILI_MAX_REO_DATA_RINGS_MSG; index++) {
+ stats->stats_reo[index][NSS_WIFILI_STATS_REO_ERROR] +=
+ devstats->rxreo_stats[index].ring_error;
+ stats->stats_reo[index][NSS_WIFILI_STATS_REO_REAPED] +=
+ devstats->rxreo_stats[index].ring_reaped;
+ stats->stats_reo[index][NSS_WIFILI_STATS_REO_INV_COOKIE] +=
+ devstats->rxreo_stats[index].invalid_cookie;
+ }
+
+ /*
+ * update tx sw pool
+ */
+ for (index = 0; index < NSS_WIFILI_MAX_TXDESC_POOLS_MSG; index++) {
+ stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_IN_USE] =
+ devstats->tx_sw_pool_stats[index].desc_alloc;
+ stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_ALLOC_FAIL] +=
+ devstats->tx_sw_pool_stats[index].desc_alloc_fail;
+ stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_ALREADY_ALLOCATED] +=
+ devstats->tx_sw_pool_stats[index].desc_already_allocated;
+ stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_INVALID_FREE] +=
+ devstats->tx_sw_pool_stats[index].desc_invalid_free;
+ stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_FREE_SRC_FW] +=
+ devstats->tx_sw_pool_stats[index].tx_rel_src_fw;
+ stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_FREE_COMPLETION] +=
+ devstats->tx_sw_pool_stats[index].tx_rel_tx_desc;
+ stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_NO_PB] +=
+ devstats->tx_sw_pool_stats[index].tx_rel_no_pb;
+ }
+
+ /*
+ * update ext tx desc pool stats
+ */
+ for (index = 0; index < NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG; index++) {
+ stats->stats_ext_tx_desc[index][NSS_WIFILI_STATS_EXT_TX_DESC_IN_USE] =
+ devstats->tx_ext_sw_pool_stats[index].desc_alloc;
+ stats->stats_ext_tx_desc[index][NSS_WIFILI_STATS_EXT_TX_DESC_ALLOC_FAIL] +=
+ devstats->tx_ext_sw_pool_stats[index].desc_alloc_fail;
+ stats->stats_ext_tx_desc[index][NSS_WIFILI_STATS_EXT_TX_DESC_ALREADY_ALLOCATED] +=
+ devstats->tx_ext_sw_pool_stats[index].desc_already_allocated;
+ stats->stats_ext_tx_desc[index][NSS_WIFILI_STATS_EXT_TX_DESC_INVALID_FREE] +=
+ devstats->tx_ext_sw_pool_stats[index].desc_invalid_free;
+ }
+
+ /*
+ * update rx desc pool stats
+ */
+ for (index = 0; index < NSS_WIFILI_MAX_PDEV_NUM_MSG; index++) {
+ stats->stats_rx_desc[index][NSS_WIFILI_STATS_RX_DESC_NO_PB] +=
+ devstats->rx_sw_pool_stats[index].rx_no_pb;
+ stats->stats_rx_desc[index][NSS_WIFILI_STATS_RX_DESC_ALLOC_FAIL] +=
+ devstats->rx_sw_pool_stats[index].desc_alloc_fail;
+ stats->stats_rx_desc[index][NSS_WIFILI_STATS_RX_DESC_IN_USE] =
+ devstats->rx_sw_pool_stats[index].desc_alloc;
+ }
+
+ /*
+ * update rx dma ring stats
+ */
+ for (index = 0; index < NSS_WIFILI_MAX_PDEV_NUM_MSG; index++) {
+ stats->stats_rxdma[index][NSS_WIFILI_STATS_RXDMA_DESC_UNAVAILABLE] +=
+ devstats->rxdma_stats[index].rx_hw_desc_unavailable;
+ }
+
+ /*
+ * update wbm ring stats
+ */
+ stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_DMA] += devstats->rxwbm_stats.err_src_rxdma;
+ stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_DMA_CODE_INV] += devstats->rxwbm_stats.err_src_rxdma_code_inv;
+ stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_REO] += devstats->rxwbm_stats.err_src_reo;
+ stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_REO_CODE_NULLQ] += devstats->rxwbm_stats.err_src_reo_code_nullq;
+ stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_REO_CODE_INV] += devstats->rxwbm_stats.err_src_reo_code_inv;
+ stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_INV] += devstats->rxwbm_stats.err_src_invalid;
+ spin_unlock_bh(&nss_top->stats_lock);
+ return;
+}
+
diff --git a/nss_wifili_stats.h b/nss_wifili_stats.h
new file mode 100644
index 0000000..d12eafe
--- /dev/null
+++ b/nss_wifili_stats.h
@@ -0,0 +1,199 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_wifili_stats.h
+ * NSS wifili statistics header file.
+ */
+
+#ifndef __NSS_WIFILI_STATS_H
+#define __NSS_WIFILI_STATS_H
+
+#include "nss_core.h"
+#include "nss_stats.h"
+#include "nss_wifili_if.h"
+
+/*
+ * wifili txrx statistics
+ *
+ * WARNING: There is a 1:1 mapping between values below and corresponding
+ * stats string array in nss_stats.c
+ */
+enum nss_wifili_stats_txrx {
+ NSS_WIFILI_STATS_RX_MSDU_ERROR, /* Number of rx packets received from ring with msdu error */
+ NSS_WIFILI_STATS_RX_INV_PEER_RCV, /* Number of rx packets with invalid peer id */
+ NSS_WIFILI_STATS_RX_WDS_SRCPORT_EXCEPTION, /* Number of rx packets exceptioned to host because of src port learn fail */
+ NSS_WIFILI_STATS_RX_WDS_SRCPORT_EXCEPTION_FAIL, /* Number of rx src port learn fail packets failed to get enqueued to host */
+ NSS_WIFILI_STATS_RX_DELIVERD, /* Number of packets wifili has given to next node */
+ NSS_WIFILI_STATS_RX_DELIVER_DROPPED, /* Number of packets which wifili failed to enqueue to next node */
+ NSS_WIFILI_STATS_RX_INTRA_BSS_UCAST, /* Number of packets which wifili send for intra bss ucast packet */
+ NSS_WIFILI_STATS_RX_INTRA_BSS_UCAST_FAIL, /* Number of packets which wifili send for intra bss ucast packet failed */
+ NSS_WIFILI_STATS_RX_INTRA_BSS_MCAST, /* Number of packets which wifili send for intra bss mcast packet */
+ NSS_WIFILI_STATS_RX_INTRA_BSS_MCAST_FAIL, /* Number of packets which wifili send for intra bss mcast packet failed */
+ NSS_WIFILI_STATS_RX_SG_RCV_SEND, /* Number of packets sg send */
+ NSS_WIFILI_STATS_RX_SG_RCV_FAIL, /* Number of packets sg received failure*/
+ NSS_STATS_WIFILI_RX_MCAST_ECHO, /* Number of multicast echo packets received */
+ NSS_WIFILI_STATS_TX_ENQUEUE, /* Number of packets that got enqueued to wifili */
+ NSS_WIFILI_STATS_TX_ENQUEUE_DROP, /* Number of packets that dropped during enqueue to wifili */
+ NSS_WIFILI_STATS_TX_DEQUEUE, /* Number of packets that are dequeued by wifili */
+ NSS_WIFILI_STATS_TX_HW_ENQUEUE_FAIL, /* Number of rx packets that NSS wifi offload path could successfully process */
+ NSS_WIFILI_STATS_TX_SENT_COUNT, /* Number of Tx packets sent to hw */
+ NSS_WIFILI_STATS_TXRX_MAX, /* Number of max txrx stats*/
+};
+
+/*
+ * wifili tcl stats
+ *
+ * WARNING: There is a 1:1 mapping between values below and corresponding
+ * stats string array in nss_stats.c
+ */
+enum nss_wifili_stats_tcl {
+ NSS_WIFILI_STATS_TCL_NO_HW_DESC, /* Number of tcl hw desc*/
+ NSS_WIFILI_STATS_TCL_RING_FULL, /* Number of times tcl ring full*/
+ NSS_WIFILI_STATS_TCL_RING_SENT, /* Number of times tcl desc sent*/
+ NSS_WIFILI_STATS_TCL_MAX, /* Number of max tcl stats*/
+};
+
+/*
+ * wifili tx comp stats
+ *
+ * WARNING: There is a 1:1 mapping between values below and corresponding
+ * stats string array in nss_stats.c
+ */
+enum nss_wifili_stats_tx_comp {
+ NSS_WIFILI_STATS_TX_DESC_FREE_INV_BUFSRC, /* Number of invalid bufsrc packets */
+ NSS_WIFILI_STATS_TX_DESC_FREE_INV_COOKIE, /* Number of invalid cookie packets */
+ NSS_WIFILI_STATS_TX_DESC_FREE_HW_RING_EMPTY, /* Number of time times hw ring empty found*/
+ NSS_WIFILI_STATS_TX_DESC_FREE_REAPED, /* Number of tx packets that are reaped out of tx completion ring */
+ NSS_WIFILI_STATS_TX_DESC_FREE_MAX, /* Number of tx comp stats */
+};
+
+/*
+ * wifili tx reo stats
+ *
+ * WARNING: There is a 1:1 mapping between values below and corresponding
+ * stats string array in nss_stats.c
+ */
+enum nss_wifili_stats_reo {
+ NSS_WIFILI_STATS_REO_ERROR, /* Number of reo error*/
+ NSS_WIFILI_STATS_REO_REAPED, /* Number of reo reaped*/
+ NSS_WIFILI_STATS_REO_INV_COOKIE, /* Number of invalid cookie*/
+ NSS_WIFILI_STATS_REO_MAX, /* Number of reo stats*/
+};
+
+/*
+ * wifili tx desc stats
+ *
+ * WARNING: There is a 1:1 mapping between values below and corresponding
+ * stats string array in nss_stats.c
+ */
+enum nss_wifili_stats_txsw_pool {
+ NSS_WIFILI_STATS_TX_DESC_IN_USE, /* Number of tx packets that are currently in flight */
+ NSS_WIFILI_STATS_TX_DESC_ALLOC_FAIL, /* Number of tx sw desc alloc failures */
+ NSS_WIFILI_STATS_TX_DESC_ALREADY_ALLOCATED, /* Number of tx sw desc already allocated*/
+ NSS_WIFILI_STATS_TX_DESC_INVALID_FREE, /* Number of tx sw desc invalid free*/
+ NSS_WIFILI_STATS_TX_DESC_FREE_SRC_FW, /* Number of tx desc for which release src is fw */
+ NSS_WIFILI_STATS_TX_DESC_FREE_COMPLETION, /* Number of tx desc completion*/
+ NSS_WIFILI_STATS_TX_DESC_NO_PB, /* Number of tx desc pb is null*/
+ NSS_WIFILI_STATS_TX_DESC_MAX, /* Number of tx desc stats*/
+};
+
+/*
+ * wifili tx ext desc stats
+ *
+ * WARNING: There is a 1:1 mapping between values below and corresponding
+ * stats string array in nss_stats.c
+ */
+enum nss_wifili_stats_ext_txsw_pool {
+ NSS_WIFILI_STATS_EXT_TX_DESC_IN_USE, /* Number of ext tx packets that are currently in flight */
+ NSS_WIFILI_STATS_EXT_TX_DESC_ALLOC_FAIL, /* Number of ext tx sw desc alloc failures */
+ NSS_WIFILI_STATS_EXT_TX_DESC_ALREADY_ALLOCATED, /* Number of ext tx sw desc already allocated*/
+ NSS_WIFILI_STATS_EXT_TX_DESC_INVALID_FREE, /* Number of ext tx sw desc invalid free*/
+ NSS_WIFILI_STATS_EXT_TX_DESC_MAX, /* Number of ext tx desc stats*/
+};
+
+/*
+ * wifili rx desc stats
+ *
+ * WARNING: There is a 1:1 mapping between values below and corresponding
+ * stats string array in nss_stats.c
+ */
+enum nss_wifili_stats_rxdma_pool {
+ NSS_WIFILI_STATS_RX_DESC_NO_PB, /* Number of rx desc no pb*/
+ NSS_WIFILI_STATS_RX_DESC_ALLOC_FAIL, /* Number of rx desc alloc failures */
+ NSS_WIFILI_STATS_RX_DESC_IN_USE, /* Number of rx desc alloc in use*/
+ NSS_WIFILI_STATS_RX_DESC_MAX, /* Number of rx desc stats*/
+};
+
+/*
+ * wifili rx dma ring stats
+ *
+ * WARNING: There is a 1:1 mapping between values below and corresponding
+ * stats string array in nss_stats.c
+ */
+enum nss_wifili_stats_rxdma_ring {
+ NSS_WIFILI_STATS_RXDMA_DESC_UNAVAILABLE, /* Number of rx dma desc unavailable */
+ NSS_WIFILI_STATS_RXDMA_BUF_REPLENISHED, /* Number of rx dma buf replished */
+ NSS_WIFILI_STATS_RXDMA_DESC_MAX, /* Number of rx dma desc stast*/
+};
+
+/*
+ * wifili wbm ring stats
+ *
+ * WARNING: There is a 1:1 mapping between values below and corresponding
+ * stats string array in nss_stats.c
+ */
+enum nss_wifili_stats_wbm {
+ NSS_WIFILI_STATS_WBM_SRC_DMA, /* Number of rx invalid src dma*/
+ NSS_WIFILI_STATS_WBM_SRC_DMA_CODE_INV, /* Number of rx invalid src dma*/
+ NSS_WIFILI_STATS_WBM_SRC_REO, /* Number of rx invalid src reo*/
+ NSS_WIFILI_STATS_WBM_SRC_REO_CODE_NULLQ, /* Number of rx invalid reo error with null q*/
+ NSS_WIFILI_STATS_WBM_SRC_REO_CODE_INV, /* Number of rx invalid reo error with null q*/
+ NSS_WIFILI_STATS_WBM_SRC_INV, /* Number of rx invalid reo code invalid*/
+ NSS_WIFILI_STATS_WBM_MAX, /* Number of rx wbm stats*/
+};
+
+/*
+ * NSS wifili stats
+ */
+struct nss_wifili_stats {
+ uint64_t stats_txrx[NSS_WIFILI_MAX_PDEV_NUM_MSG][NSS_WIFILI_STATS_TXRX_MAX];
+ /* Number of txrx stats*/
+ uint64_t stats_tcl_ring[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG][NSS_WIFILI_STATS_TCL_MAX];
+ /* Tcl stats for each ring*/
+ uint64_t stats_tx_comp[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG][NSS_WIFILI_STATS_TX_DESC_FREE_MAX];
+ /* Tx comp ring stats*/
+ uint64_t stats_tx_desc[NSS_WIFILI_MAX_TXDESC_POOLS_MSG][NSS_WIFILI_STATS_TX_DESC_MAX];
+ /* Tx desc pool stats*/
+ uint64_t stats_ext_tx_desc[NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG][NSS_WIFILI_STATS_EXT_TX_DESC_MAX];
+ /* Tx ext desc pool stats*/
+ uint64_t stats_reo[NSS_WIFILI_MAX_REO_DATA_RINGS_MSG][NSS_WIFILI_STATS_REO_MAX];
+ /* Rx reo ring stats*/
+ uint64_t stats_rx_desc[NSS_WIFILI_MAX_PDEV_NUM_MSG][NSS_WIFILI_STATS_RX_DESC_MAX];
+ /* Rx rx sw pool stats*/
+ uint64_t stats_rxdma[NSS_WIFILI_MAX_PDEV_NUM_MSG][NSS_WIFILI_STATS_RXDMA_DESC_MAX];
+ /* Rx dma ring stats*/
+ uint64_t stats_wbm[NSS_WIFILI_STATS_WBM_MAX];
+ /* Wbm error ring stats*/
+};
+
+/*
+ * NSS wifili statistics APIs
+ */
+extern void nss_wifili_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_wifili_stats_sync_msg *wlsoc_stats, uint16_t interface);
+extern void nss_wifili_stats_dentry_create(void);
+
+#endif /* __NSS_WIFILI_STATS_H */