From 11b9f541cb03cc24ca091e62dd4f2ea36f3dda6a Mon Sep 17 00:00:00 2001 From: Rakesh Goyal Date: Wed, 8 May 2019 06:24:10 +0530 Subject: [PATCH] nvethernetrm: add HW and SW counters' support These stats are read from MAC HW RMON counters as well as from Core and DMA path. ethtool -S is used to get statistics. There are 3 stats captured currently 1) ether_mmc_counters: EQOS HW RMON counters 2) ether_xtra_stat_counters: SW counters from osi/core 3) ether_xtra_dma_stat_counters: SW counters from osi/dma Bug 200519211 Change-Id: I5bbeb340cf2ffccb6399687b254f79c67f480179 Signed-off-by: Rakesh Goyal Reviewed-on: https://git-master.nvidia.com/r/2114208 GVS: Gerrit_Virtual_Submit Reviewed-by: Narayan Reddy Reviewed-by: Srinivas Ramachandran Reviewed-by: mobile promotions Tested-by: mobile promotions --- include/mmc.h | 385 ++++++++++++++++++++++++++++++ include/osi_common.h | 34 +++ include/osi_core.h | 47 +++- include/osi_dma.h | 5 +- osi/{core => common}/osi_common.c | 18 ++ osi/core/Makefile.tmk | 5 +- osi/core/eqos_core.c | 55 +++++ osi/core/eqos_core.h | 8 + osi/core/eqos_mmc.c | 351 +++++++++++++++++++++++++++ osi/core/eqos_mmc.h | 109 +++++++++ osi/core/libnvethernetrm.export | 2 + osi/core/osi_core.c | 26 ++ osi/dma/Makefile.tmk | 3 +- osi/dma/eqos_dma.h | 1 - osi/dma/osi_dma_txrx.c | 44 ++-- 15 files changed, 1069 insertions(+), 24 deletions(-) create mode 100644 include/mmc.h rename osi/{core => common}/osi_common.c (94%) create mode 100644 osi/core/eqos_mmc.c create mode 100644 osi/core/eqos_mmc.h diff --git a/include/mmc.h b/include/mmc.h new file mode 100644 index 0000000..d75d096 --- /dev/null +++ b/include/mmc.h @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef MMC_H +#define MMC_H +/** + * osi_mmc_counters - The structure to hold RMON counter values + * + * mmc_tx_octetcount_gb: This counter provides the number of bytes + * transmitted, exclusive of preamble and retried bytes, in good and + * bad packets. + * mmc_tx_framecount_gb: This counter provides the number of good and + * bad packets transmitted, exclusive of retried packets. + * mmc_tx_broadcastframe_g: This counter provides the number of good + * broadcast packets transmitted + * mmc_tx_multicastframe_g: This counter provides the number of good + * multicast packets transmitted + * mmc_tx_64_octets_gb: This counter provides the number of good and bad + * packets transmitted with length 64 bytes, exclusive of preamble and + * retried packets + * mmc_tx_65_to_127_octets_gb: This counter provides the number of good + * and bad packets transmitted with length 65-127 bytes, exclusive of + * preamble and retried packets + * mmc_tx_128_to_255_octets_gb: This counter provides the number of good + * and bad packets transmitted with length 128-255 bytes, exclusive of + * preamble and retried packets + * mmc_tx_256_to_511_octets_gb: This counter provides the number of good + * and bad packets transmitted with length 256-511 bytes, exclusive of + * preamble and retried packets + * mmc_tx_512_to_1023_octets_gb: This counter provides the number of good + * and bad packets transmitted with length 512-1023 bytes, exclusive of + * preamble and retried packets + * mmc_tx_1024_to_max_octets_gb: This counter provides the number of good + * and bad packets transmitted with length 1024-max bytes, exclusive of + * preamble and retried packets + * mmc_tx_unicast_gb: This counter provides the number of good and bad + * unicast packets + * mmc_tx_multicast_gb: This counter provides the number of good and bad + * multicast packets + * mmc_tx_broadcast_gb: This counter provides the number of good and bad + * braodcast packets + * mmc_tx_underflow_error: This counter provides the number of abort + * packets due to underflow error + * mmc_tx_singlecol_g: This counter provides the number of successfully + * transmitted packets after a single collision in the half-duplex mode + * mmc_tx_multicol_g: This counter provides the number of successfully + * transmitted packets after a multiple collision in the half-duplex mode + * mmc_tx_deferred: This counter provides the number of successfully + * transmitted after a deferral in the half-duplex mode + * mmc_tx_latecol: This counter provides the number of packets aborted + * because of late collision error + * mmc_tx_exesscol: This counter provides the number of packets aborted + * because of excessive (16) collision errors + * mmc_tx_carrier_error: This counter provides the number of packets + * aborted because of carrier sense error (no carrier or loss of carrier) + * mmc_tx_octetcount_g: This counter provides the number of bytes + * transmitted, exclusive of preamble, only in good packets. + * mmc_tx_framecount_g: This counter provides the number of good packets + * transmitted . + * mmc_tx_excessdef: This counter provides the number of packets aborted + * because of excessive deferral error (deferred for more than two + * max-sized packet times). + * mmc_tx_pause_frame: This counter provides the number of good Pause + * packets transmitted. + * mmc_tx_vlan_frame_g: This counter provides the number of good + * VLAN packets transmitted + * mmc_tx_osize_frame_g: This counter provides the number of packets + * transmitted without errors and with length greater than the maxsize + * (1,518 or 1,522 bytes for VLAN tagged packets; 2000 bytes. + * mmc_rx_framecount_gb: This counter provides the number of good and bad + * packets received + * mmc_rx_octetcount_gb: This counter provides the number of bytes + * received by DWC_ther_qos, exclusive of preamble, in good and bad packets + * mmc_rx_octetcount_g: This counter provides the number of bytes + * received by DWC_ther_qos, exclusive of preamble, in good and bad packets + * mmc_rx_broadcastframe_g: This counter provides the number of good + * broadcast packets received + * mmc_rx_multicastframe_g: This counter provides the number of good + * multicast packets received + * mmc_rx_crc_error: This counter provides the number of packets received + * with CRC error + * mmc_rx_align_error: This counter provides the number of packets + * received with alignment (dribble) error. It is valid only in 10/100 + * mode. + * mmc_rx_runt_error: This counter provides the number of packets + * received with runt (length less than 64 bytes and CRC error) error + * mmc_rx_jabber_error: This counter provides the number of giant packets + * received with length (including CRC) greater than 1,518 bytes + * (1,522 bytes for VLAN tagged) and with CRC error. + * mmc_rx_undersize_g: This counter provides the number of packets + * received with length less than 64 bytes, without any errors + * mmc_rx_oversize_g: This counter provides the number of packets + * received without errors, with length greater than the maxsize + * mmc_rx_64_octets_gb: This counter provides the number of good and bad + * packets received with length 64 bytes, exclusive of the preamble. + * mmc_rx_65_to_127_octets_gb: This counter provides the number of good + * and bad packets received with length 65-127 bytes, exclusive of the + * preamble. + * mmc_rx_128_to_255_octets_gb: This counter provides the number of good + * and bad packets received with length 128-255 bytes, exclusive of the + * preamble. + * mmc_rx_256_to_511_octets_gb: This counter provides the number of good + * and bad packets received with length 256-511 bytes, exclusive of the + * preamble. + * mmc_rx_512_to_1023_octets_gb: This counter provides the number of good + * and bad packets received with length 512-1023 bytes, exclusive of the + * preamble. + * mmc_rx_1024_to_max_octets_gb: This counter provides the number of good + * and bad packets received with length 1024-max bytes, exclusive of the + * preamble. + * mmc_rx_unicast_g: This counter provides the number of good unicast + * packets received mmc_rx_length_error: This counter provides the + * number of packets received with length error (Length Type field + * not equal to packet size), for all packets with valid length field. + * mmc_rx_outofrangetype: This counter provides the number of packets + * received with length field not equal to the + * valid packet size (greater than 1,500 but less than 1,536). + * mmc_rx_pause_frames: This counter provides the number of good and + * valid Pause packets received + * mmc_rx_fifo_overflow: This counter provides the number of missed + * received packets because of FIFO overflow in DWC_ether_qos + * mmc_rx_vlan_frames_gb: This counter provides the number of good and + * bad VLAN packets received + * mmc_rx_watchdog_error: This counter provides the number of packets + * received with error because of watchdog timeout error + * mmc_rx_receive_error: This counter provides the number of packets + * received with Receive error or Packet Extension error on the GMII or + * MII interface + * mmc_rx_ctrl_frames_g: This counter provides the number of packets + * received with Receive error or Packet Extension error on the GMII + * or MII interface + * mmc_rx_ipv4_gd: This counter provides the number of good IPv4 + * datagrams received with the TCP, UDP, or ICMP payload + * mmc_rx_ipv4_hderr: RxIPv4 Header Error Packets + * mmc_rx_ipv4_nopay: This counter provides the number of IPv4 datagram + * packets received that did not have a TCP, UDP, or ICMP payload + * mmc_rx_ipv4_frag: This counter provides the number of good IPv4 + * datagrams received with fragmentation. + * mmc_rx_ipv4_udsbl: This counter provides the number of good IPv4 + * datagrams received that had a UDP payload with checksum disabled + * mmc_rx_ipv6_gd_octets: This counter provides the number of good IPv6 + * datagrams received with the TCP, UDP, or ICMP payload + * mmc_rx_ipv6_hderr_octets: This counter provides the number of IPv6 + * datagrams received with header (length or version mismatch) errors + * mmc_rx_ipv6_nopay_octets: This counter provides the number of IPv6 + * datagram packets received that did not have a TCP, UDP, or ICMP + * payload + * mmc_rx_udp_gd: This counter provides the number of good IP datagrams + * received by DWC_ether_qos with a good UDP payload. + * mmc_rx_udp_err: This counter provides the number of good IP datagrams + * received by DWC_ether_qos with a good UDP payload. This counter is not + * updated when the RxIPv4_UDP_Checksum_Disabled_Packets counter is + * incremented. + * mmc_rx_tcp_gd: This counter provides the number of good IP datagrams + * received with a good TCP payload + * mmc_rx_tcp_err: This counter provides the number of good IP datagrams + * received with a good TCP payload + * mmc_rx_icmp_gd: This counter provides the number of good IP datagrams + * received with a good ICMP payload + * mmc_rx_icmp_err: This counter provides the number of good IP + * datagrams received whose ICMP payload has a checksum error + * mmc_rx_ipv4_gd_octets: This counter provides the number of bytes + * received by DWC_ether_qos in good IPv4 datagrams encapsulating TCP, + * UDP, or ICMP data. (Ethernet header, FCS, pad, or IP pad bytes are + * not included in this counter + * mmc_rx_ipv4_hderr_octets: This counter provides the number of bytes + * received in IPv4 datagrams with header errors (checksum, length, + * version mismatch). The value in the Length field of IPv4 header is + * used to update this counter. (Ethernet header, FCS, pad, + * or IP pad bytes are not included in this counter + * mmc_rx_ipv4_nopay_octets: This counter provides the number of bytes + * received in IPv4 datagrams that did not have a TCP, UDP, or + * ICMP payload. The value in the Length field of IPv4 header is used + * to update this counter. (Ethernet header, FCS, pad, or IP pad bytes + * are not included in this counter. + * mmc_rx_ipv4_frag_octets: This counter provides the number of bytes + * received in fragmented IPv4 datagrams. The value in the Length + * field of IPv4 header is used to update this counter. (Ethernet header, + * FCS, pad, or IP pad bytes are not included in this counter + * mmc_rx_ipv4_udsbl_octets: This counter provides the number of bytes + * received in a UDP segment that had the UDP checksum disabled. This + * counter does not count IP Header bytes. (Ethernet header, FCS, pad, + * or IP pad bytes are not included in this counter. + * mmc_rx_ipv6_gd: This counter provides the number of bytes received + * in good IPv6 datagrams encapsulating TCP, UDP, or ICMP data. + * (Ethernet header, FCS, pad, or IP pad bytes are not included in + * this counter + * mmc_rx_ipv6_hderr: This counter provides the number of bytes received + * in IPv6 datagrams with header errors (length, version mismatch). The + * value in the Length field of IPv6 header is used to update this + * counter. (Ethernet header, FCS, pad, or IP pad bytes are not included + * in this counter. + * mmc_rx_ipv6_nopay: This counter provides the number of bytes received + * in IPv6 datagrams that did not have a TCP, UDP, or ICMP payload. The + * value in the Length field of IPv6 header is used to update this + * counter. (Ethernet header, FCS, pad, or IP pad bytes are not included + * in this counter + * mmc_rx_udp_gd_octets: This counter provides the number of bytes + * received in a good UDP segment. This counter does not count IP header + * bytes. + * mmc_rx_udp_err_octets: This counter provides the number of bytes + * received in a UDP segment that had checksum errors. This counter + * does not count IP header bytes + * mmc_rx_tcp_gd_octets: This counter provides the number of bytes + * received in a good TCP segment. This counter does not count IP + * header bytes + * mmc_rx_tcp_err_octets: This counter provides the number of bytes + * received in a TCP segment that had checksum errors. This counter + * does not count IP header bytes + * mmc_rx_icmp_gd_octets: This counter provides the number of bytes + * received in a good ICMP segment. This counter does not count + * IP header bytes + * mmc_rx_icmp_err_octets: This counter provides the number of bytes + * received in a ICMP segment that had checksum errors. + * This counter does not count IP header bytes + */ +struct osi_mmc_counters { + /* MMC TX counters */ + unsigned long mmc_tx_octetcount_gb; + unsigned long mmc_tx_framecount_gb; + unsigned long mmc_tx_broadcastframe_g; + unsigned long mmc_tx_multicastframe_g; + unsigned long mmc_tx_64_octets_gb; + unsigned long mmc_tx_65_to_127_octets_gb; + unsigned long mmc_tx_128_to_255_octets_gb; + unsigned long mmc_tx_256_to_511_octets_gb; + unsigned long mmc_tx_512_to_1023_octets_gb; + unsigned long mmc_tx_1024_to_max_octets_gb; + unsigned long mmc_tx_unicast_gb; + unsigned long mmc_tx_multicast_gb; + unsigned long mmc_tx_broadcast_gb; + unsigned long mmc_tx_underflow_error; + unsigned long mmc_tx_singlecol_g; + unsigned long mmc_tx_multicol_g; + unsigned long mmc_tx_deferred; + unsigned long mmc_tx_latecol; + unsigned long mmc_tx_exesscol; + unsigned long mmc_tx_carrier_error; + unsigned long mmc_tx_octetcount_g; + unsigned long mmc_tx_framecount_g; + unsigned long mmc_tx_excessdef; + unsigned long mmc_tx_pause_frame; + unsigned long mmc_tx_vlan_frame_g; + unsigned long mmc_tx_osize_frame_g; + + /* MMC RX counters */ + unsigned long mmc_rx_framecount_gb; + unsigned long mmc_rx_octetcount_gb; + unsigned long mmc_rx_octetcount_g; + unsigned long mmc_rx_broadcastframe_g; + unsigned long mmc_rx_multicastframe_g; + unsigned long mmc_rx_crc_error; + unsigned long mmc_rx_align_error; + unsigned long mmc_rx_runt_error; + unsigned long mmc_rx_jabber_error; + unsigned long mmc_rx_undersize_g; + unsigned long mmc_rx_oversize_g; + unsigned long mmc_rx_64_octets_gb; + unsigned long mmc_rx_65_to_127_octets_gb; + unsigned long mmc_rx_128_to_255_octets_gb; + unsigned long mmc_rx_256_to_511_octets_gb; + unsigned long mmc_rx_512_to_1023_octets_gb; + unsigned long mmc_rx_1024_to_max_octets_gb; + unsigned long mmc_rx_unicast_g; + unsigned long mmc_rx_length_error; + unsigned long mmc_rx_outofrangetype; + unsigned long mmc_rx_pause_frames; + unsigned long mmc_rx_fifo_overflow; + unsigned long mmc_rx_vlan_frames_gb; + unsigned long mmc_rx_watchdog_error; + unsigned long mmc_rx_receive_error; + unsigned long mmc_rx_ctrl_frames_g; + + /* IPv4 */ + unsigned long mmc_rx_ipv4_gd; + unsigned long mmc_rx_ipv4_hderr; + unsigned long mmc_rx_ipv4_nopay; + unsigned long mmc_rx_ipv4_frag; + unsigned long mmc_rx_ipv4_udsbl; + + /* IPV6 */ + unsigned long mmc_rx_ipv6_gd_octets; + unsigned long mmc_rx_ipv6_hderr_octets; + unsigned long mmc_rx_ipv6_nopay_octets; + + /* Protocols */ + unsigned long mmc_rx_udp_gd; + unsigned long mmc_rx_udp_err; + unsigned long mmc_rx_tcp_gd; + unsigned long mmc_rx_tcp_err; + unsigned long mmc_rx_icmp_gd; + unsigned long mmc_rx_icmp_err; + + /* IPv4 */ + unsigned long mmc_rx_ipv4_gd_octets; + unsigned long mmc_rx_ipv4_hderr_octets; + unsigned long mmc_rx_ipv4_nopay_octets; + unsigned long mmc_rx_ipv4_frag_octets; + unsigned long mmc_rx_ipv4_udsbl_octets; + + /* IPV6 */ + unsigned long mmc_rx_ipv6_gd; + unsigned long mmc_rx_ipv6_hderr; + unsigned long mmc_rx_ipv6_nopay; + + /* Protocols */ + unsigned long mmc_rx_udp_gd_octets; + unsigned long mmc_rx_udp_err_octets; + unsigned long mmc_rx_tcp_gd_octets; + unsigned long mmc_rx_tcp_err_octets; + unsigned long mmc_rx_icmp_gd_octets; + unsigned long mmc_rx_icmp_err_octets; +}; + +/** + * osi_xtra_stat_counters - OSI core extra stat counters + * + * rx_buf_unavail_irq_n: RX buffer unavailable irq count + * tx_proc_stopped_irq_n: Transmit Process Stopped irq count + * tx_buf_unavail_irq_n: Transmit Buffer Unavailable irq count + * rx_proc_stopped_irq_n: Receive Process Stopped irq count + * rx_watchdog_irq_n: Receive Watchdog Timeout irq count + * fatal_bus_error_irq_n: Fatal Bus Error irq count + * q_re_alloc_rx_buf_failed: rx sbk allocation failure count + * tx_normal_irq_n: TX per channel interrupt count + * rx_normal_irq_n: RX per cannel interrupt count + * link_connect_count: link disconnect count + * link_disconnect_count: link connect count + */ +struct osi_xtra_stat_counters { + unsigned long rx_buf_unavail_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long tx_proc_stopped_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long tx_buf_unavail_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long rx_proc_stopped_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long rx_watchdog_irq_n; + unsigned long fatal_bus_error_irq_n; + unsigned long re_alloc_rxbuf_failed[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long tx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long rx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long link_connect_count; + unsigned long link_disconnect_count; +}; + +/** + * osi_xtra_dma_stat_counters - OSI dma extra stats counters + * q_tx_pkt_n: Per Q TX packet count + * q_rx_pkt_n: Per Q RX packet count + * tx_clean_n: Per Q TX complete call count + * tx_pkt_n: Total number of tx packets count + * rx_pkt_n: Total number of rx packet count + * rx_vlan_pkt_n: Total number of VLAN RX packet count + * tx_vlan_pkt_n: Total number of VLAN TX packet count + * tx_tso_pkt_n: Total number of TSO packet count + */ +struct osi_xtra_dma_stat_counters { + unsigned long q_tx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long q_rx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long tx_clean_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long tx_pkt_n; + unsigned long rx_pkt_n; + unsigned long rx_vlan_pkt_n; + unsigned long tx_vlan_pkt_n; + unsigned long tx_tso_pkt_n; +}; + +#endif diff --git a/include/osi_common.h b/include/osi_common.h index a4b5a5c..7b30d89 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -65,6 +65,8 @@ #define OSI_MAC_TCR_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) #define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) +#define OSI_UCHAR_MAX 0xFFU + /* Default maximum Gaint Packet Size Limit */ #define OSI_MAX_MTU_SIZE 9000U #define OSI_DFLT_MTU_SIZE 1500U @@ -102,7 +104,9 @@ #define OSI_IP4_FILTER 0U #define OSI_IP6_FILTER 1U +/* FIXME add logic based on HW version */ #define OSI_EQOS_MAX_NUM_CHANS 4U +#define OSI_EQOS_MAX_NUM_QUEUES 4U #define OSI_BIT(nr) ((unsigned int)1 << (nr)) @@ -406,6 +410,35 @@ static inline int is_valid_mac_version(unsigned int mac_ver) return 0; } +/** + * osi_update_stats_counter - update value by increment passed as parameter + * @last_value: last value of stat counter + * @incr: increment value + * + * Algorithm: Check for boundary and return sum + * + * Dependencies: Input parameter should be only unsigned long type + * + * Protection: None + * + * Return: unsigned long value + */ +static inline unsigned long osi_update_stats_counter(unsigned long last_value, + unsigned long incr) +{ + unsigned long long temp; + + temp = (unsigned long long)last_value; + temp = temp + incr; + if (temp > ULONG_MAX) { + /* Do nothing */ + } else { + return (unsigned long)temp; + } + + return last_value; +} + /** * osi_get_mac_version - Reading MAC version * @addr: io-remap MAC base address. @@ -422,4 +455,5 @@ static inline int is_valid_mac_version(unsigned int mac_ver) int osi_get_mac_version(void *addr, unsigned int *mac_ver); void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); +void osi_memset(void *s, unsigned int c, unsigned long count); #endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h index d911b23..6066f13 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -24,6 +24,7 @@ #define OSI_CORE_H #include "osi_common.h" +#include "mmc.h" struct osi_core_priv_data; @@ -152,6 +153,8 @@ struct osi_core_avb_algorithm { * @get_systime_from_mac: Called to get the current time from MAC. * @config_tscr: Called to configure the TimeStampControl register. * @config_ssir: Called to configure the sub second increment register. + * @read_mmc: called to update MMC counter from HW register + * @reset_mmc: called to reset MMC HW counter and Structure */ struct osi_core_ops { /* initialize MAC/MTL/DMA Common registers */ @@ -224,6 +227,8 @@ struct osi_core_ops { unsigned long long (*get_systime_from_mac)(void *addr); void (*config_tscr)(void *addr, unsigned int ptp_filter); void (*config_ssir)(void *addr, unsigned int ptp_clock); + void (*read_mmc)(struct osi_core_priv_data *osi_core); + void (*reset_mmc)(struct osi_core_priv_data *osi_core); }; /** @@ -278,6 +283,8 @@ struct osi_ptp_config { * @flow_ctrl: Current flow control settings * @ptp_config: PTP configuration settings. * @default_addend: Default addend value. + * @mmc: mmc counter structure + * @xstats: xtra sw error counters */ struct osi_core_priv_data { void *base; @@ -296,6 +303,8 @@ struct osi_core_priv_data { unsigned int flow_ctrl; struct osi_ptp_config ptp_config; unsigned int default_addend; + struct osi_mmc_counters mmc; + struct osi_xtra_stat_counters xstats; }; /** @@ -849,6 +858,7 @@ int osi_config_l2_da_perfect_inverse_match(struct osi_core_priv_data *osi_core, */ int osi_update_vlan_id(struct osi_core_priv_data *osi_core, unsigned int vid); + /** * osi_write_phy_reg - Write to a PHY register through MAC over MDIO bus. * @osi_core: OSI private data structure. @@ -875,6 +885,41 @@ int osi_update_vlan_id(struct osi_core_priv_data *osi_core, int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); +/** + * osi_read_mmc - invoke function to read actual registers and update + * structure variable mmc + * + * @osi_core: OSI core private data structure. + * + * Algorithm: Read the registers, mask reserve bits if requied, update + * structure. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_read_mmc(struct osi_core_priv_data *osi_core); + +/** + * osi_reset_mmc - invoke function to rest MMC counter and data structure + * + * @osi_core: OSI core private data structure. + * + * Algorithm: Read the registers, mask reserve bits if requied, update + * structure. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_reset_mmc(struct osi_core_priv_data *osi_core); + /** * osi_read_phy_reg - Read from a PHY register through MAC over MDIO bus. * @osi_core: OSI private data structure. @@ -999,7 +1044,7 @@ void osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, * * Return: None */ - void osi_ptp_configuration(struct osi_core_priv_data *osi_core, unsigned int enable); + #endif /* OSI_CORE_H */ diff --git a/include/osi_dma.h b/include/osi_dma.h index d1eb05a..b3b4a4a 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -25,6 +25,7 @@ #include "osi_common.h" #include "osi_dma_txrx.h" +#include "mmc.h" #define OSI_PKT_CX_VLAN OSI_BIT(0) #define OSI_PKT_CX_VALID OSI_BIT(10) @@ -274,7 +275,8 @@ struct osi_dma_chan_ops { * @dma_chans[]: Array of supported DMA channels * @rx_buf_len: DMA Rx channel buffer length at HW level. * @mtu: MTU size - * @osi_pkt_err_stats: Packet error stats + * @pkt_err_stats: Packet error stats + * @dstats: Extra DMA stats */ struct osi_dma_priv_data { struct osi_tx_ring *tx_ring[OSI_EQOS_MAX_NUM_CHANS]; @@ -288,6 +290,7 @@ struct osi_dma_priv_data { unsigned int rx_buf_len; unsigned int mtu; struct osi_pkt_err_stats pkt_err_stats; + struct osi_xtra_dma_stat_counters dstats; }; /** diff --git a/osi/core/osi_common.c b/osi/common/osi_common.c similarity index 94% rename from osi/core/osi_common.c rename to osi/common/osi_common.c index ba8da0a..df137b4 100644 --- a/osi/core/osi_common.c +++ b/osi/common/osi_common.c @@ -133,3 +133,21 @@ int osi_get_mac_version(void *addr, unsigned int *mac_ver) *mac_ver = macver; return ret; } + +void osi_memset(void *s, unsigned int c, unsigned long count) +{ + unsigned char *xs = s; + int brk = 1; + + while (brk != 0) { + if (c < OSI_UCHAR_MAX) { + *xs++ = (unsigned char)c; + } + if (count > 0U) { + count--; + } + if (count == 0U) { + brk = 0; + } + } +} diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 516063b..f322e53 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -29,8 +29,9 @@ NV_COMPONENT_NAME := nvethernetrm NV_COMPONENT_OWN_INTERFACE_DIR := . NV_COMPONENT_SOURCES := \ eqos_core.c \ - osi_common.c \ - osi_core.c + eqos_mmc.c \ + osi_core.c \ + $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c NV_COMPONENT_NEEDED_INTERFACE_DIRS := \ $(NV_SOURCE)/qnx/src/libs/nvethernet/osi_dependencies diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 39b83f9..90d38d7 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -24,6 +24,7 @@ #include #include #include "eqos_core.h" +#include "eqos_mmc.h" struct osi_core_ops *eqos_get_hw_core_ops(void); @@ -1213,6 +1214,57 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *osi_core, } } +/** + * update_dma_sr_stats - stats for dma_status error + * @osi_core: OSI core private data structure. + * @dma_sr: Dma status register read value + * @qinx: Queue index + * + * Algorithm: increament error stats based on corresponding bit filed. + * + * Dependencies: None + * + * Protection: None. + * + * Return: None. + */ +static inline void update_dma_sr_stats(struct osi_core_priv_data *osi_core, + unsigned int dma_sr, unsigned int qinx) +{ + unsigned long val; + + if ((dma_sr & EQOS_DMA_CHX_STATUS_RBU) == EQOS_DMA_CHX_STATUS_RBU) { + val = osi_core->xstats.rx_buf_unavail_irq_n[qinx]; + osi_core->xstats.rx_buf_unavail_irq_n[qinx] = + osi_update_stats_counter(val, 1U); + } + if ((dma_sr & EQOS_DMA_CHX_STATUS_TPS) == EQOS_DMA_CHX_STATUS_TPS) { + val = osi_core->xstats.tx_proc_stopped_irq_n[qinx]; + osi_core->xstats.tx_proc_stopped_irq_n[qinx] = + osi_update_stats_counter(val, 1U); + } + if ((dma_sr & EQOS_DMA_CHX_STATUS_TBU) == EQOS_DMA_CHX_STATUS_TBU) { + val = osi_core->xstats.tx_buf_unavail_irq_n[qinx]; + osi_core->xstats.tx_buf_unavail_irq_n[qinx] = + osi_update_stats_counter(val, 1U); + } + if ((dma_sr & EQOS_DMA_CHX_STATUS_RPS) == EQOS_DMA_CHX_STATUS_RPS) { + val = osi_core->xstats.rx_proc_stopped_irq_n[qinx]; + osi_core->xstats.rx_proc_stopped_irq_n[qinx] = + osi_update_stats_counter(val, 1U); + } + if ((dma_sr & EQOS_DMA_CHX_STATUS_RWT) == EQOS_DMA_CHX_STATUS_RWT) { + val = osi_core->xstats.rx_watchdog_irq_n; + osi_core->xstats.rx_watchdog_irq_n = + osi_update_stats_counter(val, 1U); + } + if ((dma_sr & EQOS_DMA_CHX_STATUS_FBE) == EQOS_DMA_CHX_STATUS_FBE) { + val = osi_core->xstats.fatal_bus_error_irq_n; + osi_core->xstats.fatal_bus_error_irq_n = + osi_update_stats_counter(val, 1U); + } +} + /** * eqos_handle_common_intr - Handles common interrupt. * @osi_core: OSI core private data structure. @@ -1267,6 +1319,7 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *osi_core) /* ack non ti/ri ints */ osi_writel(dma_sr, (unsigned char *)base + EQOS_DMA_CHX_STATUS(qinx)); + update_dma_sr_stats(osi_core, dma_sr, qinx); } } @@ -2659,6 +2712,8 @@ static struct osi_core_ops eqos_core_ops = { .get_systime_from_mac = eqos_get_systime_from_mac, .config_tscr = eqos_config_tscr, .config_ssir = eqos_config_ssir, + .read_mmc = eqos_read_mmc, + .reset_mmc = eqos_reset_mmc, }; struct osi_core_ops *eqos_get_hw_core_ops(void) diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 1dec605..f5e9483 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -292,5 +292,13 @@ #define EQOS_MAC_TCR_TSCTRLSSR OSI_BIT(9) #define EQOS_MAC_SSIR_SSINC_SHIFT 16U #define EQOS_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU + +#define EQOS_DMA_CHX_STATUS_TPS OSI_BIT(1) +#define EQOS_DMA_CHX_STATUS_TBU OSI_BIT(2) +#define EQOS_DMA_CHX_STATUS_RBU OSI_BIT(7) +#define EQOS_DMA_CHX_STATUS_RPS OSI_BIT(8) +#define EQOS_DMA_CHX_STATUS_RWT OSI_BIT(9) +#define EQOS_DMA_CHX_STATUS_FBE OSI_BIT(10) + void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value); #endif diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c new file mode 100644 index 0000000..7dadf16 --- /dev/null +++ b/osi/core/eqos_mmc.c @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include "eqos_mmc.h" +#include "eqos_core.h" + +/** + * update_mmc_val - function to read resgister and return vlaue to callee + * + * @osi_core: OSI core private data structure. + * @last_vlaue: previous value of stats variable. + * @offset: HW register offset + * + * Algorithm: Read the registers, check for boundary, if more, reset + * counters else return same to caller. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: unsigned value + */ +static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, + unsigned long last_value, + unsigned long offset) +{ + unsigned long long temp; + unsigned int value = osi_readl((unsigned char *)osi_core->base + + offset); + + temp = (unsigned long long)last_value; + temp = temp + (unsigned long long)value; + if (temp > ULONG_MAX) { + osd_err(osi_core->osd, "Value overflow for offset = 0x%x resetting all counters\n", + offset); + eqos_reset_mmc(osi_core); + } else { + return (unsigned long)temp; + } + + return 0; +} + +/** + * eqos_reset_mmc - To reset MMC registers and ether_mmc_counter structure + * variable + * @osi_core: OSI core private data structure. + * + * Algorithm: reset HW counter and structure variable value. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements. + * + * Protection: None + * + * Return: None + */ +void eqos_reset_mmc(struct osi_core_priv_data *osi_core) +{ + unsigned int value; + + value = osi_readl((unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + /* self-clear bit in one clock cycle */ + value |= EQOS_MMC_CNTRL_CNTRST; + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + osi_memset(&osi_core->mmc, 0U, sizeof(struct osi_mmc_counters)); +} + +/** + * eqos_read_mmc - To read MMC registers and ether_mmc_counter structure + * variable + * @osi_core: OSI core private data structure. + * + * Algorithm: Pass register offset and old value to helper function and + * update structure. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: None + */ +void eqos_read_mmc(struct osi_core_priv_data *osi_core) +{ + struct osi_mmc_counters *mmc = &osi_core->mmc; + + mmc->mmc_tx_octetcount_gb = + update_mmc_val(osi_core, mmc->mmc_tx_octetcount_gb, + MMC_TXOCTETCOUNT_GB); + mmc->mmc_tx_framecount_gb = + update_mmc_val(osi_core, mmc->mmc_tx_framecount_gb, + MMC_TXPACKETCOUNT_GB); + mmc->mmc_tx_broadcastframe_g = + update_mmc_val(osi_core, mmc->mmc_tx_broadcastframe_g, + MMC_TXBROADCASTPACKETS_G); + mmc->mmc_tx_multicastframe_g = + update_mmc_val(osi_core, mmc->mmc_tx_multicastframe_g, + MMC_TXMULTICASTPACKETS_G); + mmc->mmc_tx_64_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_64_octets_gb, + MMC_TX64OCTETS_GB); + mmc->mmc_tx_65_to_127_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_65_to_127_octets_gb, + MMC_TX65TO127OCTETS_GB); + mmc->mmc_tx_128_to_255_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_128_to_255_octets_gb, + MMC_TX128TO255OCTETS_GB); + mmc->mmc_tx_256_to_511_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_256_to_511_octets_gb, + MMC_TX256TO511OCTETS_GB); + mmc->mmc_tx_512_to_1023_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_512_to_1023_octets_gb, + MMC_TX512TO1023OCTETS_GB); + mmc->mmc_tx_1024_to_max_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_1024_to_max_octets_gb, + MMC_TX1024TOMAXOCTETS_GB); + mmc->mmc_tx_unicast_gb = + update_mmc_val(osi_core, mmc->mmc_tx_unicast_gb, + MMC_TXUNICASTPACKETS_GB); + mmc->mmc_tx_multicast_gb = + update_mmc_val(osi_core, mmc->mmc_tx_multicast_gb, + MMC_TXMULTICASTPACKETS_GB); + mmc->mmc_tx_broadcast_gb = + update_mmc_val(osi_core, mmc->mmc_tx_broadcast_gb, + MMC_TXBROADCASTPACKETS_GB); + mmc->mmc_tx_underflow_error = + update_mmc_val(osi_core, mmc->mmc_tx_underflow_error, + MMC_TXUNDERFLOWERROR); + mmc->mmc_tx_singlecol_g = + update_mmc_val(osi_core, mmc->mmc_tx_singlecol_g, + MMC_TXSINGLECOL_G); + mmc->mmc_tx_multicol_g = + update_mmc_val(osi_core, mmc->mmc_tx_multicol_g, + MMC_TXMULTICOL_G); + mmc->mmc_tx_deferred = + update_mmc_val(osi_core, mmc->mmc_tx_deferred, + MMC_TXDEFERRED); + mmc->mmc_tx_latecol = + update_mmc_val(osi_core, mmc->mmc_tx_latecol, + MMC_TXLATECOL); + mmc->mmc_tx_exesscol = + update_mmc_val(osi_core, mmc->mmc_tx_exesscol, + MMC_TXEXESSCOL); + mmc->mmc_tx_carrier_error = + update_mmc_val(osi_core, mmc->mmc_tx_exesscol, + MMC_TXCARRIERERROR); + mmc->mmc_tx_octetcount_g = + update_mmc_val(osi_core, mmc->mmc_tx_octetcount_g, + MMC_TXOCTETCOUNT_G); + mmc->mmc_tx_framecount_g = + update_mmc_val(osi_core, mmc->mmc_tx_framecount_g, + MMC_TXPACKETSCOUNT_G); + mmc->mmc_tx_excessdef = + update_mmc_val(osi_core, mmc->mmc_tx_excessdef, + MMC_TXEXCESSDEF); + mmc->mmc_tx_pause_frame = + update_mmc_val(osi_core, mmc->mmc_tx_pause_frame, + MMC_TXPAUSEPACKETS); + mmc->mmc_tx_vlan_frame_g = + update_mmc_val(osi_core, mmc->mmc_tx_vlan_frame_g, + MMC_TXVLANPACKETS_G); + mmc->mmc_tx_osize_frame_g = + update_mmc_val(osi_core, mmc->mmc_tx_osize_frame_g, + MMC_TXOVERSIZE_G); + mmc->mmc_rx_framecount_gb = + update_mmc_val(osi_core, mmc->mmc_rx_framecount_gb, + MMC_RXPACKETCOUNT_GB); + mmc->mmc_rx_octetcount_gb = + update_mmc_val(osi_core, mmc->mmc_rx_octetcount_gb, + MMC_RXOCTETCOUNT_GB); + mmc->mmc_rx_octetcount_g = + update_mmc_val(osi_core, mmc->mmc_rx_octetcount_g, + MMC_RXOCTETCOUNT_G); + mmc->mmc_rx_broadcastframe_g = + update_mmc_val(osi_core, mmc->mmc_rx_broadcastframe_g, + MMC_RXBROADCASTPACKETS_G); + mmc->mmc_rx_multicastframe_g = + update_mmc_val(osi_core, mmc->mmc_rx_multicastframe_g, + MMC_RXMULTICASTPACKETS_G); + mmc->mmc_rx_crc_error = + update_mmc_val(osi_core, mmc->mmc_rx_crc_error, + MMC_RXCRCERROR); + mmc->mmc_rx_align_error = + update_mmc_val(osi_core, mmc->mmc_rx_align_error, + MMC_RXALIGNMENTERROR); + mmc->mmc_rx_runt_error = + update_mmc_val(osi_core, mmc->mmc_rx_runt_error, + MMC_RXRUNTERROR); + mmc->mmc_rx_jabber_error = + update_mmc_val(osi_core, mmc->mmc_rx_jabber_error, + MMC_RXJABBERERROR); + mmc->mmc_rx_undersize_g = + update_mmc_val(osi_core, mmc->mmc_rx_undersize_g, + MMC_RXUNDERSIZE_G); + mmc->mmc_rx_oversize_g = + update_mmc_val(osi_core, mmc->mmc_rx_oversize_g, + MMC_RXOVERSIZE_G); + mmc->mmc_rx_64_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_64_octets_gb, + MMC_RX64OCTETS_GB); + mmc->mmc_rx_65_to_127_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_65_to_127_octets_gb, + MMC_RX65TO127OCTETS_GB); + mmc->mmc_rx_128_to_255_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_128_to_255_octets_gb, + MMC_RX128TO255OCTETS_GB); + mmc->mmc_rx_256_to_511_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_256_to_511_octets_gb, + MMC_RX256TO511OCTETS_GB); + mmc->mmc_rx_512_to_1023_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_512_to_1023_octets_gb, + MMC_RX512TO1023OCTETS_GB); + mmc->mmc_rx_1024_to_max_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_1024_to_max_octets_gb, + MMC_RX1024TOMAXOCTETS_GB); + mmc->mmc_rx_unicast_g = + update_mmc_val(osi_core, mmc->mmc_rx_unicast_g, + MMC_RXUNICASTPACKETS_G); + mmc->mmc_rx_length_error = + update_mmc_val(osi_core, mmc->mmc_rx_length_error, + MMC_RXLENGTHERROR); + mmc->mmc_rx_outofrangetype = + update_mmc_val(osi_core, mmc->mmc_rx_outofrangetype, + MMC_RXOUTOFRANGETYPE); + mmc->mmc_rx_pause_frames = + update_mmc_val(osi_core, mmc->mmc_rx_pause_frames, + MMC_RXPAUSEPACKETS); + mmc->mmc_rx_fifo_overflow = + update_mmc_val(osi_core, mmc->mmc_rx_fifo_overflow, + MMC_RXFIFOOVERFLOW); + mmc->mmc_rx_vlan_frames_gb = + update_mmc_val(osi_core, mmc->mmc_rx_vlan_frames_gb, + MMC_RXVLANPACKETS_GB); + mmc->mmc_rx_watchdog_error = + update_mmc_val(osi_core, mmc->mmc_rx_watchdog_error, + MMC_RXWATCHDOGERROR); + mmc->mmc_rx_receive_error = + update_mmc_val(osi_core, mmc->mmc_rx_receive_error, + MMC_RXRCVERROR); + mmc->mmc_rx_ctrl_frames_g = + update_mmc_val(osi_core, mmc->mmc_rx_ctrl_frames_g, + MMC_RXCTRLPACKETS_G); + mmc->mmc_rx_ipv4_gd = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_gd, + MMC_RXIPV4_GD_PKTS); + mmc->mmc_rx_ipv4_hderr = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_hderr, + MMC_RXIPV4_HDRERR_PKTS); + mmc->mmc_rx_ipv4_nopay = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_nopay, + MMC_RXIPV4_NOPAY_PKTS); + mmc->mmc_rx_ipv4_frag = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_frag, + MMC_RXIPV4_FRAG_PKTS); + mmc->mmc_rx_ipv4_udsbl = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_udsbl, + MMC_RXIPV4_UBSBL_PKTS); + mmc->mmc_rx_ipv6_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_gd_octets, + MMC_RXIPV6_GD_PKTS); + mmc->mmc_rx_ipv6_hderr_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr_octets, + MMC_RXIPV6_HDRERR_PKTS); + mmc->mmc_rx_ipv6_nopay_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay_octets, + MMC_RXIPV6_NOPAY_PKTS); + mmc->mmc_rx_udp_gd = + update_mmc_val(osi_core, mmc->mmc_rx_udp_gd, + MMC_RXUDP_GD_PKTS); + mmc->mmc_rx_udp_err = + update_mmc_val(osi_core, mmc->mmc_rx_udp_err, + MMC_RXUDP_ERR_PKTS); + mmc->mmc_rx_tcp_gd = + update_mmc_val(osi_core, mmc->mmc_rx_tcp_gd, + MMC_RXTCP_GD_PKTS); + mmc->mmc_rx_tcp_err = + update_mmc_val(osi_core, mmc->mmc_rx_tcp_err, + MMC_RXTCP_ERR_PKTS); + mmc->mmc_rx_icmp_gd = + update_mmc_val(osi_core, mmc->mmc_rx_icmp_gd, + MMC_RXICMP_GD_PKTS); + mmc->mmc_rx_icmp_err = + update_mmc_val(osi_core, mmc->mmc_rx_icmp_err, + MMC_RXICMP_ERR_PKTS); + mmc->mmc_rx_ipv4_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_gd_octets, + MMC_RXIPV4_GD_OCTETS); + mmc->mmc_rx_ipv4_hderr_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_hderr_octets, + MMC_RXIPV4_HDRERR_OCTETS); + mmc->mmc_rx_ipv4_nopay_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_nopay_octets, + MMC_RXIPV4_NOPAY_OCTETS); + mmc->mmc_rx_ipv4_frag_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_frag_octets, + MMC_RXIPV4_FRAG_OCTETS); + mmc->mmc_rx_ipv4_udsbl_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_udsbl_octets, + MMC_RXIPV4_UDSBL_OCTETS); + mmc->mmc_rx_udp_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_udp_gd_octets, + MMC_RXIPV6_GD_OCTETS); + mmc->mmc_rx_ipv6_hderr = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr, + MMC_RXIPV6_HDRERR_OCTETS); + mmc->mmc_rx_ipv6_nopay = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay, + MMC_RXIPV6_NOPAY_OCTETS); + mmc->mmc_rx_udp_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_udp_gd_octets, + MMC_RXUDP_GD_OCTETS); + mmc->mmc_rx_udp_err_octets = + update_mmc_val(osi_core, mmc->mmc_rx_udp_err_octets, + MMC_RXUDP_ERR_OCTETS); + mmc->mmc_rx_tcp_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_tcp_gd_octets, + MMC_RXTCP_GD_OCTETS); + mmc->mmc_rx_tcp_err_octets = + update_mmc_val(osi_core, mmc->mmc_rx_tcp_err_octets, + MMC_RXTCP_ERR_OCTETS); + mmc->mmc_rx_icmp_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_icmp_gd_octets, + MMC_RXICMP_GD_OCTETS); + mmc->mmc_rx_icmp_err_octets = + update_mmc_val(osi_core, mmc->mmc_rx_icmp_err_octets, + MMC_RXICMP_ERR_OCTETS); +} diff --git a/osi/core/eqos_mmc.h b/osi/core/eqos_mmc.h new file mode 100644 index 0000000..d581792 --- /dev/null +++ b/osi/core/eqos_mmc.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef EQOS_MMC_H_ +#define EQOS_MMC_H_ + +#define MMC_TXOCTETCOUNT_GB 0x00714 +#define MMC_TXPACKETCOUNT_GB 0x00718 +#define MMC_TXBROADCASTPACKETS_G 0x0071c +#define MMC_TXMULTICASTPACKETS_G 0x00720 +#define MMC_TX64OCTETS_GB 0x00724 +#define MMC_TX65TO127OCTETS_GB 0x00728 +#define MMC_TX128TO255OCTETS_GB 0x0072c +#define MMC_TX256TO511OCTETS_GB 0x00730 +#define MMC_TX512TO1023OCTETS_GB 0x00734 +#define MMC_TX1024TOMAXOCTETS_GB 0x00738 +#define MMC_TXUNICASTPACKETS_GB 0x0073c +#define MMC_TXMULTICASTPACKETS_GB 0x00740 +#define MMC_TXBROADCASTPACKETS_GB 0x00744 +#define MMC_TXUNDERFLOWERROR 0x00748 +#define MMC_TXSINGLECOL_G 0x0074c +#define MMC_TXMULTICOL_G 0x00750 +#define MMC_TXDEFERRED 0x00754 +#define MMC_TXLATECOL 0x00758 +#define MMC_TXEXESSCOL 0x0075c +#define MMC_TXCARRIERERROR 0x00760 +#define MMC_TXOCTETCOUNT_G 0x00764 +#define MMC_TXPACKETSCOUNT_G 0x00768 +#define MMC_TXEXCESSDEF 0x0076c +#define MMC_TXPAUSEPACKETS 0x00770 +#define MMC_TXVLANPACKETS_G 0x00774 +#define MMC_TXOVERSIZE_G 0x00778 +#define MMC_RXPACKETCOUNT_GB 0x00780 +#define MMC_RXOCTETCOUNT_GB 0x00784 +#define MMC_RXOCTETCOUNT_G 0x00788 +#define MMC_RXBROADCASTPACKETS_G 0x0078c +#define MMC_RXMULTICASTPACKETS_G 0x00790 +#define MMC_RXCRCERROR 0x00794 +#define MMC_RXALIGNMENTERROR 0x00798 +#define MMC_RXRUNTERROR 0x0079c +#define MMC_RXJABBERERROR 0x007a0 +#define MMC_RXUNDERSIZE_G 0x007a4 +#define MMC_RXOVERSIZE_G 0x007a8 +#define MMC_RX64OCTETS_GB 0x007ac +#define MMC_RX65TO127OCTETS_GB 0x007b0 +#define MMC_RX128TO255OCTETS_GB 0x007b4 +#define MMC_RX256TO511OCTETS_GB 0x007b8 +#define MMC_RX512TO1023OCTETS_GB 0x007bc +#define MMC_RX1024TOMAXOCTETS_GB 0x007c0 +#define MMC_RXUNICASTPACKETS_G 0x007c4 +#define MMC_RXLENGTHERROR 0x007c8 +#define MMC_RXOUTOFRANGETYPE 0x007cc +#define MMC_RXPAUSEPACKETS 0x007d0 +#define MMC_RXFIFOOVERFLOW 0x007d4 +#define MMC_RXVLANPACKETS_GB 0x007d8 +#define MMC_RXWATCHDOGERROR 0x007dc +#define MMC_RXRCVERROR 0x007e0 +#define MMC_RXCTRLPACKETS_G 0x007e4 +#define MMC_RXIPV4_GD_PKTS 0x00810 +#define MMC_RXIPV4_HDRERR_PKTS 0x00814 +#define MMC_RXIPV4_NOPAY_PKTS 0x00818 +#define MMC_RXIPV4_FRAG_PKTS 0x0081c +#define MMC_RXIPV4_UBSBL_PKTS 0x00820 +#define MMC_RXIPV6_GD_PKTS 0x00824 +#define MMC_RXIPV6_HDRERR_PKTS 0x00828 +#define MMC_RXIPV6_NOPAY_PKTS 0x0082c +#define MMC_RXUDP_GD_PKTS 0x00830 +#define MMC_RXUDP_ERR_PKTS 0x00834 +#define MMC_RXTCP_GD_PKTS 0x00838 +#define MMC_RXTCP_ERR_PKTS 0x0083c +#define MMC_RXICMP_GD_PKTS 0x00840 +#define MMC_RXICMP_ERR_PKTS 0x00844 +#define MMC_RXIPV4_GD_OCTETS 0x00850 +#define MMC_RXIPV4_HDRERR_OCTETS 0x00854 +#define MMC_RXIPV4_NOPAY_OCTETS 0x00858 +#define MMC_RXIPV4_FRAG_OCTETS 0x0085c +#define MMC_RXIPV4_UDSBL_OCTETS 0x00860 +#define MMC_RXIPV6_GD_OCTETS 0x00864 +#define MMC_RXIPV6_HDRERR_OCTETS 0x00868 +#define MMC_RXIPV6_NOPAY_OCTETS 0x0086c +#define MMC_RXUDP_GD_OCTETS 0x00870 +#define MMC_RXUDP_ERR_OCTETS 0x00874 +#define MMC_RXTCP_GD_OCTETS 0x00878 +#define MMC_RXTCP_ERR_OCTETS 0x0087c +#define MMC_RXICMP_GD_OCTETS 0x00880 +#define MMC_RXICMP_ERR_OCTETS 0x00884 + +void eqos_read_mmc(struct osi_core_priv_data *osi_core); +void eqos_reset_mmc(struct osi_core_priv_data *osi_core); +#endif diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 74829fa..cc158d5 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -63,3 +63,5 @@ osi_get_systime_from_mac osi_adjust_time osi_adjust_freq osi_set_systime_to_mac +osi_read_mmc +osi_reset_mmc diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 8473c8e..b2b3065 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -824,3 +824,29 @@ void osi_ptp_configuration(struct osi_core_priv_data *osi_core, osi_core->ptp_config.nsec); } } + +int osi_read_mmc(struct osi_core_priv_data *osi_core) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->read_mmc != OSI_NULL)) { + osi_core->ops->read_mmc(osi_core); + ret = 0; + } + + return ret; +} + +int osi_reset_mmc(struct osi_core_priv_data *osi_core) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->reset_mmc != OSI_NULL)) { + osi_core->ops->reset_mmc(osi_core); + ret = 0; + } + + return ret; +} diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index e61be7b..da32328 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -30,7 +30,8 @@ NV_COMPONENT_OWN_INTERFACE_DIR := . NV_COMPONENT_SOURCES := \ eqos_dma.c \ osi_dma.c \ - osi_dma_txrx.c + osi_dma_txrx.c \ + $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c NV_COMPONENT_NEEDED_INTERFACE_DIRS := \ $(NV_SOURCE)/qnx/src/libs/nvethernet/osi_dependencies diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 322acc2..aab8ce8 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -68,5 +68,4 @@ #define EQOS_DMA_CHX_RBSZ_SHIFT 1U #define EQOS_DMA_CHX_TX_CTRL_TXPBL_RECOMMENDED 0x200000U #define EQOS_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED 0xC0000U - #endif diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 286f616..638626f 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -26,21 +26,6 @@ int dma_desc_init(struct osi_dma_priv_data *osi_dma); -static inline void osi_memset(void *s, int c, unsigned long count) -{ - char *xs = s; - int brk = 1; - - while (brk != 0) { - *xs++ = (char)c; - count--; - - if (count == 0U) { - brk = 0; - } - } -} - /** * get_rx_csum - Get the Rx checksum from descriptor if valid * @rx_desc: Rx descriptor @@ -236,7 +221,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, int ret = 0; while (received < budget) { - osi_memset(rx_pkt_cx, 0, sizeof(*rx_pkt_cx)); + osi_memset(rx_pkt_cx, 0U, sizeof(*rx_pkt_cx)); rx_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; rx_swcx = rx_ring->rx_swcx + rx_ring->cur_rx_idx; @@ -278,7 +263,11 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, osd_receive_packet(osi->osd, rx_ring, chan, osi->rx_buf_len, rx_pkt_cx, rx_swcx); } - + osi->dstats.q_rx_pkt_n[chan] = + osi_update_stats_counter(osi->dstats.q_rx_pkt_n[chan], + 1UL); + osi->dstats.rx_pkt_n = + osi_update_stats_counter(osi->dstats.rx_pkt_n, 1UL); received++; } @@ -454,8 +443,11 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, unsigned long long ns; int processed = 0; + osi->dstats.tx_clean_n[chan] = + osi_update_stats_counter(osi->dstats.tx_clean_n[chan], 1U); + while (entry != tx_ring->cur_tx_idx) { - osi_memset(txdone_pkt_cx, 0, sizeof(*txdone_pkt_cx)); + osi_memset(txdone_pkt_cx, 0U, sizeof(*txdone_pkt_cx)); tx_desc = tx_ring->tx_desc + entry; tx_swcx = tx_ring->tx_swcx + entry; @@ -516,6 +508,11 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * wake the corresponding transmit queue in OS layer. */ tx_ring->clean_idx = entry; + osi->dstats.q_tx_pkt_n[chan] = + osi_update_stats_counter(osi->dstats.q_tx_pkt_n[chan], + 1UL); + osi->dstats.tx_pkt_n = + osi_update_stats_counter(osi->dstats.tx_pkt_n, 1UL); } return processed; @@ -669,6 +666,17 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) int cntx_desc_consumed; /* Context decriptor for VLAN/TSO */ + if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { + osi->dstats.tx_vlan_pkt_n = + osi_update_stats_counter(osi->dstats.tx_vlan_pkt_n, + 1UL); + } + + if ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) { + osi->dstats.tx_tso_pkt_n = + osi_update_stats_counter(osi->dstats.tx_tso_pkt_n, 1UL); + } + cntx_desc_consumed = need_cntx_desc(tx_pkt_cx, tx_desc); if (cntx_desc_consumed == 1) { INCR_TX_DESC_INDEX(entry, 1U);